Home | History | Annotate | Line # | Download | only in config
tc-nds32.c revision 1.1.1.6.2.1
      1 /* tc-nds32.c -- Assemble for the nds32
      2    Copyright (C) 2012-2024 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 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 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 (ISSPACE (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 () & ((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 = (valueT) 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, (valueT) 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 && !ISSPACE (*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 *nds_itoa (int n);
   4219 
   4220 static char *
   4221 nds_itoa (int n)
   4222 {
   4223   char *buf = xmalloc (MAX_BUFFER * sizeof (char));
   4224   snprintf (buf, MAX_BUFFER, "%d", n);
   4225   return buf;
   4226 }
   4227 
   4228 /* Insert a relax hint.  */
   4229 
   4230 static void
   4231 nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
   4232 {
   4233   char *name = NULL;
   4234   char saved_char;
   4235   struct nds32_relocs_pattern *relocs = NULL;
   4236   struct nds32_relocs_group *group, *new;
   4237   struct relax_hint_id *record_id;
   4238 
   4239   name = input_line_pointer;
   4240   while (*input_line_pointer && !ISSPACE (*input_line_pointer))
   4241     input_line_pointer++;
   4242   saved_char = *input_line_pointer;
   4243   *input_line_pointer = 0;
   4244   name = strdup (name);
   4245 
   4246   if (name && strcmp (name, "begin") == 0)
   4247     {
   4248       if (relax_hint_id_current == -1)
   4249 	reset_bias = 1;
   4250       relax_hint_bias++;
   4251       relax_hint_id_current++;
   4252       relax_hint_begin = 1;
   4253     }
   4254 
   4255   /* Original case ".relax_hint id".  It's id may need to be reordered. */
   4256   if (!relax_hint_begin)
   4257     {
   4258       int tmp = strtol (name, NULL, 10);
   4259       record_id = record_id_head;
   4260       while (record_id)
   4261 	{
   4262 	  if (record_id->old_id == tmp)
   4263 	    {
   4264 	      name = nds_itoa (record_id->new_id);
   4265 	      goto reordered_id;
   4266 	    }
   4267 	  record_id = record_id->next;
   4268 	}
   4269       if (reset_bias)
   4270 	{
   4271 	  relax_hint_bias = relax_hint_id_current - atoi (name) + 1;
   4272 	  reset_bias = 0;
   4273 	}
   4274       relax_hint_id_current = tmp + relax_hint_bias;
   4275 
   4276       /* Insert the element to the head of the link list.  */
   4277       struct relax_hint_id *tmp_id = malloc (sizeof (struct relax_hint_id));
   4278       tmp_id->old_id = tmp;
   4279       tmp_id->new_id = relax_hint_id_current;
   4280       tmp_id->next = record_id_head;
   4281       record_id_head = tmp_id;
   4282     }
   4283 
   4284   if (name && strcmp (name, "end") == 0)
   4285     relax_hint_begin = 0;
   4286   name = nds_itoa (relax_hint_id_current);
   4287 
   4288  reordered_id:
   4289 
   4290   /* Find relax hint entry for next instruction, and all member will be
   4291      initialized at that time.  */
   4292   relocs = str_hash_find (nds32_hint_hash, name);
   4293   if (relocs == NULL)
   4294     {
   4295       relocs = notes_calloc (1, sizeof (*relocs));
   4296       str_hash_insert (nds32_hint_hash, name, relocs, 0);
   4297     }
   4298   else
   4299     {
   4300       while (relocs->next)
   4301 	relocs = relocs->next;
   4302       relocs->next = notes_calloc (1, sizeof (*relocs));
   4303       relocs = relocs->next;
   4304     }
   4305 
   4306   *input_line_pointer = saved_char;
   4307   ignore_rest_of_line ();
   4308 
   4309   /* Get the final one of relax hint series.  */
   4310 
   4311   /* It has to build this list because there are maybe more than one
   4312      instructions relative to the same instruction.  It to connect to
   4313      next instruction after md_assemble.  */
   4314   new = XNEW (struct nds32_relocs_group);
   4315   memset (new, 0, sizeof (struct nds32_relocs_group));
   4316   new->pattern = relocs;
   4317   new->next = NULL;
   4318   group = nds32_relax_hint_current;
   4319   if (!group)
   4320     nds32_relax_hint_current = new;
   4321   else
   4322     {
   4323       while (group->next != NULL)
   4324 	group = group->next;
   4325       group->next = new;
   4326     }
   4327   relaxing = true;
   4328 }
   4329 
   4330 /* Decide the size of vector entries, only accepts 4 or 16 now.  */
   4331 
   4332 static void
   4333 nds32_vec_size (int ignore ATTRIBUTE_UNUSED)
   4334 {
   4335   expressionS exp;
   4336 
   4337   expression (&exp);
   4338 
   4339   if (exp.X_op == O_constant)
   4340     {
   4341       if (exp.X_add_number == 4 || exp.X_add_number == 16)
   4342 	{
   4343 	  if (vec_size == 0)
   4344 	    vec_size = exp.X_add_number;
   4345 	  else if (vec_size != exp.X_add_number)
   4346 	    as_warn (_("Different arguments of .vec_size are found, "
   4347 		       "previous %d, current %d"),
   4348 		     (int) vec_size, (int) exp.X_add_number);
   4349 	}
   4350       else
   4351 	as_warn (_("Argument of .vec_size is expected 4 or 16, actual: %d."),
   4352 		 (int) exp.X_add_number);
   4353     }
   4354   else
   4355     as_warn (_("Argument of .vec_size is not a constant."));
   4356 }
   4357 
   4358 /* The behavior of ".flag" directive varies depending on the target.
   4359    In nds32 target, we use it to recognize whether this assembly content is
   4360    generated by compiler.  Other features can also be added in this function
   4361    in the future.  */
   4362 
   4363 static void
   4364 nds32_flag (int ignore ATTRIBUTE_UNUSED)
   4365 {
   4366   char *name;
   4367   char saved_char;
   4368   int i;
   4369   const char *possible_flags[] = { "verbatim" };
   4370 
   4371   /* Skip whitespaces.  */
   4372   name = input_line_pointer;
   4373   while (*input_line_pointer && !ISSPACE (*input_line_pointer))
   4374     input_line_pointer++;
   4375   saved_char = *input_line_pointer;
   4376   *input_line_pointer = 0;
   4377 
   4378   for (i = 0; i < (int) ARRAY_SIZE (possible_flags); i++)
   4379     {
   4380       if (strcmp (name, possible_flags[i]) == 0)
   4381 	{
   4382 	  switch (i)
   4383 	    {
   4384 	    case 0:
   4385 	      /* flag: verbatim */
   4386 	      verbatim = 1;
   4387 	      break;
   4388 	    default:
   4389 	      break;
   4390 	    }
   4391 	  /* Already found the flag, no need to continue next loop.   */
   4392 	  break;
   4393 	}
   4394     }
   4395 
   4396   *input_line_pointer = saved_char;
   4397   ignore_rest_of_line ();
   4398 }
   4399 
   4400 static void
   4401 ict_model (int ignore ATTRIBUTE_UNUSED)
   4402 {
   4403   char *name;
   4404   char saved_char;
   4405   int i;
   4406   const char *possible_flags[] = { "small", "large" };
   4407 
   4408   /* Skip whitespaces.  */
   4409   name = input_line_pointer;
   4410   while (*input_line_pointer && !ISSPACE (*input_line_pointer))
   4411     input_line_pointer++;
   4412   saved_char = *input_line_pointer;
   4413   *input_line_pointer = 0;
   4414 
   4415   for (i = 0; i < (int) ARRAY_SIZE (possible_flags); i++)
   4416     {
   4417       if (strcmp (name, possible_flags[i]) == 0)
   4418 	{
   4419 	  switch (i)
   4420 	    {
   4421 	    case 0:
   4422 	      /* flag: verbatim  */
   4423 	      ict_flag = ICT_SMALL;
   4424 	      break;
   4425 	    case 1:
   4426 	      ict_flag = ICT_LARGE;
   4427 	      break;
   4428 	    default:
   4429 	      break;
   4430 	    }
   4431 	  /* Already found the flag, no need to continue next loop.   */
   4432 	  break;
   4433 	}
   4434     }
   4435 
   4436   *input_line_pointer = saved_char;
   4437   ignore_rest_of_line ();
   4438 }
   4439 
   4440 static void
   4441 nds32_n12hc (int ignore ATTRIBUTE_UNUSED)
   4442 {
   4443   /* N1213HC core is used.  */
   4444 }
   4445 
   4446 
   4447 /* The target specific pseudo-ops which we support.  */
   4448 const pseudo_typeS md_pseudo_table[] =
   4449 {
   4450   /* Forced alignment if declared these ways.  */
   4451   {"ascii", stringer, 8 + 0},
   4452   {"asciz", stringer, 8 + 1},
   4453   {"double", nds32_aligned_float_cons, 'd'},
   4454   {"dword", nds32_aligned_cons, 3},
   4455   {"float", nds32_aligned_float_cons, 'f'},
   4456   {"half", nds32_aligned_cons, 1},
   4457   {"hword", nds32_aligned_cons, 1},
   4458   {"int", nds32_aligned_cons, 2},
   4459   {"long", nds32_aligned_cons, 2},
   4460   {"octa", nds32_aligned_cons, 4},
   4461   {"quad", nds32_aligned_cons, 3},
   4462   {"qword", nds32_aligned_cons, 4},
   4463   {"short", nds32_aligned_cons, 1},
   4464   {"byte", nds32_aligned_cons, 0},
   4465   {"single", nds32_aligned_float_cons, 'f'},
   4466   {"string", stringer, 8 + 1},
   4467   {"word", nds32_aligned_cons, 2},
   4468 
   4469   {"little", set_endian_little, 1},
   4470   {"big", set_endian_little, 0},
   4471   {"16bit_on", trigger_16bit, 1},
   4472   {"16bit_off", trigger_16bit, 0},
   4473   {"restore_16bit", restore_16bit, 0},
   4474   {"off_16bit", off_16bit, 0},
   4475 
   4476   {"sdata_d", nds32_seg, SDATA_D_SECTION},
   4477   {"sdata_w", nds32_seg, SDATA_W_SECTION},
   4478   {"sdata_h", nds32_seg, SDATA_H_SECTION},
   4479   {"sdata_b", nds32_seg, SDATA_B_SECTION},
   4480   {"sdata_f", nds32_seg, SDATA_F_SECTION},
   4481 
   4482   {"sbss_d", nds32_seg, SBSS_D_SECTION},
   4483   {"sbss_w", nds32_seg, SBSS_W_SECTION},
   4484   {"sbss_h", nds32_seg, SBSS_H_SECTION},
   4485   {"sbss_b", nds32_seg, SBSS_B_SECTION},
   4486   {"sbss_f", nds32_seg, SBSS_F_SECTION},
   4487 
   4488   {"pic", nds32_enable_pic, 0},
   4489   {"n12_hc", nds32_n12hc, 0},
   4490   {"abi_1", nds32_set_abi, E_NDS_ABI_V1},
   4491   {"abi_2", nds32_set_abi, E_NDS_ABI_AABI},
   4492   /* Obsolete.  */
   4493   {"abi_2fp", nds32_set_abi, E_NDS_ABI_V2FP},
   4494   {"abi_2fp_plus", nds32_set_abi, E_NDS_ABI_V2FP_PLUS},
   4495   {"relax", nds32_relax_relocs, 1},
   4496   {"no_relax", nds32_relax_relocs, 0},
   4497   {"hint_func_args", nds32_set_hint_func_args, 0}, /* Abandon??  */
   4498   {"omit_fp_begin", nds32_omit_fp_begin, 1},
   4499   {"omit_fp_end", nds32_omit_fp_begin, 0},
   4500   {"vec_size", nds32_vec_size, 0},
   4501   {"flag", nds32_flag, 0},
   4502   {"innermost_loop_begin", nds32_loop_begin, 1},
   4503   {"innermost_loop_end", nds32_loop_begin, 0},
   4504   {"relax_hint", nds32_relax_hint, 0},
   4505   {"ict_model", ict_model, 0},
   4506   {NULL, NULL, 0}
   4507 };
   4508 
   4509 void
   4510 nds32_pre_do_align (int n, char *fill, int len, int max)
   4511 {
   4512   /* Only make a frag if we HAVE to...  */
   4513   fragS *fragP;
   4514   if (n != 0 && !need_pass_2)
   4515     {
   4516       if (fill == NULL)
   4517 	{
   4518 	  if (subseg_text_p (now_seg))
   4519 	    {
   4520 	      dwarf2_emit_insn (0);
   4521 	      fragP = frag_now;
   4522 	      add_mapping_symbol_for_align (n, frag_now_fix (), 0);
   4523 	      frag_align_code (n, max);
   4524 
   4525 	      /* Tag this alignment when there is a label before it.  */
   4526 	      if (label_exist)
   4527 		{
   4528 		  fragP->tc_frag_data.flag = NDS32_FRAG_LABEL;
   4529 		  label_exist = 0;
   4530 		}
   4531 	    }
   4532 	  else
   4533 	    frag_align (n, 0, max);
   4534 	}
   4535       else if (len <= 1)
   4536 	frag_align (n, *fill, max);
   4537       else
   4538 	frag_align_pattern (n, fill, len, max);
   4539     }
   4540 }
   4541 
   4542 void
   4543 nds32_do_align (int n)
   4544 {
   4545   /* Optimize for space and label exists.  */
   4546   expressionS exp;
   4547 
   4548   /* FIXME:I think this will break debug info sections and except_table.  */
   4549   if (!enable_relax_relocs || !subseg_text_p (now_seg))
   4550     return;
   4551 
   4552   /* Create and attach a BFD_RELOC_NDS32_LABEL fixup
   4553      the size of instruction may not be correct because
   4554      it could be relaxable.  */
   4555   exp.X_op = O_symbol;
   4556   exp.X_add_symbol = section_symbol (now_seg);
   4557   exp.X_add_number = n;
   4558   fix_new_exp (frag_now,
   4559 	       frag_now_fix (), 0, &exp, 0, BFD_RELOC_NDS32_LABEL);
   4560 }
   4561 
   4562 /* Supported Andes machines.  */
   4563 struct nds32_machs
   4564 {
   4565   enum bfd_architecture bfd_mach;
   4566   int mach_flags;
   4567 };
   4568 
   4569 /* This is the callback for nds32-asm.c to parse operands.  */
   4570 
   4571 int
   4572 nds32_asm_parse_operand (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
   4573 			 struct nds32_asm_insn *pinsn,
   4574 			 char **pstr, int64_t *value)
   4575 {
   4576   char *hold;
   4577   expressionS *pexp = pinsn->info;
   4578 
   4579   hold = input_line_pointer;
   4580   input_line_pointer = *pstr;
   4581   expression (pexp);
   4582   resolve_register (pexp);
   4583   *pstr = input_line_pointer;
   4584   input_line_pointer = hold;
   4585 
   4586   switch (pexp->X_op)
   4587     {
   4588     case O_symbol:
   4589       *value = 0;
   4590       return NASM_R_SYMBOL;
   4591     case O_constant:
   4592       *value = pexp->X_add_number;
   4593       return NASM_R_CONST;
   4594     case O_illegal:
   4595     case O_absent:
   4596     case O_register:
   4597     default:
   4598       return NASM_R_ILLEGAL;
   4599     }
   4600 }
   4601 
   4602 /* GAS will call this function at the start of the assembly, after the command
   4603    line arguments have been parsed and all the machine independent
   4604    initializations have been completed.  */
   4605 
   4606 void
   4607 md_begin (void)
   4608 {
   4609   const struct nds32_keyword *k;
   4610   relax_info_t *relax_info;
   4611   int flags = 0;
   4612 
   4613   bfd_set_arch_mach (stdoutput, TARGET_ARCH, nds32_baseline);
   4614 
   4615   nds32_init_nds32_pseudo_opcodes ();
   4616   asm_desc.parse_operand = nds32_asm_parse_operand;
   4617   if (nds32_gpr16)
   4618     flags |= NASM_OPEN_REDUCED_REG;
   4619   nds32_asm_init (&asm_desc, flags);
   4620 
   4621   /* Initial general purpose registers hash table.  */
   4622   nds32_gprs_hash = str_htab_create ();
   4623   for (k = nds32_keyword_gpr; k->name; k++)
   4624     str_hash_insert (nds32_gprs_hash, k->name, k, 0);
   4625 
   4626   /* Initial branch hash table.  */
   4627   nds32_relax_info_hash = str_htab_create ();
   4628   for (relax_info = relax_table; relax_info->opcode; relax_info++)
   4629     str_hash_insert (nds32_relax_info_hash, relax_info->opcode, relax_info, 0);
   4630 
   4631   /* Initial relax hint hash table.  */
   4632   nds32_hint_hash = str_htab_create ();
   4633   enable_16bit = nds32_16bit_ext;
   4634 }
   4635 
   4636 /* HANDLE_ALIGN in write.c.  */
   4637 
   4638 void
   4639 nds32_handle_align (fragS *fragp)
   4640 {
   4641   static const unsigned char nop16[] = { 0x92, 0x00 };
   4642   static const unsigned char nop32[] = { 0x40, 0x00, 0x00, 0x09 };
   4643   int bytes;
   4644   char *p;
   4645 
   4646   if (fragp->fr_type != rs_align_code)
   4647     return;
   4648 
   4649   bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
   4650   p = fragp->fr_literal + fragp->fr_fix;
   4651 
   4652   if (bytes & 1)
   4653     {
   4654       *p++ = 0;
   4655       bytes--;
   4656     }
   4657 
   4658   if (bytes & 2)
   4659     {
   4660       expressionS exp_t;
   4661       exp_t.X_op = O_symbol;
   4662       exp_t.X_add_symbol = abs_section_sym;
   4663       exp_t.X_add_number = R_NDS32_INSN16_CONVERT_FLAG;
   4664       fix_new_exp (fragp, fragp->fr_fix, 2, &exp_t, 0,
   4665 		   BFD_RELOC_NDS32_INSN16);
   4666       memcpy (p, nop16, 2);
   4667       p += 2;
   4668       bytes -= 2;
   4669     }
   4670 
   4671   while (bytes >= 4)
   4672     {
   4673       memcpy (p, nop32, 4);
   4674       p += 4;
   4675       bytes -= 4;
   4676     }
   4677 
   4678   bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
   4679   fragp->fr_fix += bytes;
   4680 }
   4681 
   4682 /* md_flush_pending_output  */
   4683 
   4684 void
   4685 nds32_flush_pending_output (void)
   4686 {
   4687   nds32_last_label = NULL;
   4688 }
   4689 
   4690 void
   4691 nds32_frob_label (symbolS *label)
   4692 {
   4693   dwarf2_emit_label (label);
   4694 }
   4695 
   4696 /* TC_START_LABEL  */
   4697 
   4698 int
   4699 nds32_start_label (int asmdone ATTRIBUTE_UNUSED, int secdone ATTRIBUTE_UNUSED)
   4700 {
   4701   if (optimize && subseg_text_p (now_seg))
   4702     label_exist = 1;
   4703   return 1;
   4704 }
   4705 
   4706 /* TARGET_FORMAT  */
   4707 
   4708 const char *
   4709 nds32_target_format (void)
   4710 {
   4711 #ifdef TE_LINUX
   4712   if (target_big_endian)
   4713     return "elf32-nds32be-linux";
   4714   else
   4715     return "elf32-nds32le-linux";
   4716 #else
   4717   if (target_big_endian)
   4718     return "elf32-nds32be";
   4719   else
   4720     return "elf32-nds32le";
   4721 #endif
   4722 }
   4723 
   4724 static enum nds32_br_range
   4725 get_range_type (const struct nds32_field *field)
   4726 {
   4727   gas_assert (field != NULL);
   4728 
   4729   if (field->bitpos != 0)
   4730     return BR_RANGE_U4G;
   4731 
   4732   if (field->bitsize == 24 && field->shift == 1)
   4733     return BR_RANGE_S16M;
   4734   else if (field->bitsize == 16 && field->shift == 1)
   4735     return BR_RANGE_S64K;
   4736   else if (field->bitsize == 14 && field->shift == 1)
   4737     return BR_RANGE_S16K;
   4738   else if (field->bitsize == 8 && field->shift == 1)
   4739     return BR_RANGE_S256;
   4740   else
   4741     return BR_RANGE_U4G;
   4742 }
   4743 
   4744 /* Save pseudo instruction relocation list.  */
   4745 
   4746 static struct nds32_relocs_pattern*
   4747 nds32_elf_save_pseudo_pattern (fixS* fixP, struct nds32_asm_insn *insn,
   4748 			       char *out, symbolS *sym,
   4749 			       struct nds32_relocs_pattern *reloc_ptr,
   4750 			       fragS *fragP)
   4751 {
   4752   struct nds32_opcode *opcode = insn->opcode;
   4753   if (!reloc_ptr)
   4754     reloc_ptr = XNEW (struct nds32_relocs_pattern);
   4755   reloc_ptr->seg = now_seg;
   4756   reloc_ptr->sym = sym;
   4757   reloc_ptr->frag = fragP;
   4758   reloc_ptr->frchain = frchain_now;
   4759   reloc_ptr->fixP = fixP;
   4760   reloc_ptr->opcode = opcode;
   4761   reloc_ptr->where = out;
   4762   reloc_ptr->insn = insn->insn;
   4763   reloc_ptr->next = NULL;
   4764   return reloc_ptr;
   4765 }
   4766 
   4767 /* Check X_md to transform relocation.  */
   4768 
   4769 static fixS*
   4770 nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
   4771 			    const struct nds32_field *fld,
   4772 			    expressionS *pexp, char* out,
   4773 			    struct nds32_asm_insn *insn)
   4774 {
   4775   int reloc = -1;
   4776   expressionS exp;
   4777   fixS *fixP = NULL;
   4778 
   4779   /* Handle instruction relocation.  */
   4780   if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_HI20))
   4781     {
   4782       /* Relocation for hi20 modifier.  */
   4783       switch (pexp->X_md)
   4784 	{
   4785 	case BFD_RELOC_NDS32_GOTOFF:	/* @GOTOFF */
   4786 	  reloc = BFD_RELOC_NDS32_GOTOFF_HI20;
   4787 	  break;
   4788 	case BFD_RELOC_NDS32_GOT20:	/* @GOT */
   4789 	  reloc = BFD_RELOC_NDS32_GOT_HI20;
   4790 	  break;
   4791 	case BFD_RELOC_NDS32_25_PLTREL:	/* @PLT */
   4792 	  if (!nds32_pic)
   4793 	    as_bad (_("Invalid PIC expression."));
   4794 	  else
   4795 	    reloc = BFD_RELOC_NDS32_PLT_GOTREL_HI20;
   4796 	  break;
   4797 	case BFD_RELOC_NDS32_GOTPC20:	/* _GLOBAL_OFFSET_TABLE_ */
   4798 	  reloc = BFD_RELOC_NDS32_GOTPC_HI20;
   4799 	  break;
   4800 	case BFD_RELOC_NDS32_TPOFF:	/* @TPOFF */
   4801 	  reloc = BFD_RELOC_NDS32_TLS_LE_HI20;
   4802 	  break;
   4803 	case BFD_RELOC_NDS32_GOTTPOFF:	/* @GOTTPOFF */
   4804 	  reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_HI20 : BFD_RELOC_NDS32_TLS_IE_HI20;
   4805 	  break;
   4806 	case BFD_RELOC_NDS32_TLS_DESC:	/* @TLSDESC */
   4807 	  reloc = BFD_RELOC_NDS32_TLS_DESC_HI20;
   4808 	  break;
   4809 	default:	/* No suffix */
   4810 	  if (nds32_pic)
   4811 	    /* When the file is pic, the address must be offset to gp.
   4812 	       It may define another relocation or use GOTOFF.  */
   4813 	    reloc = BFD_RELOC_NDS32_PLT_GOTREL_HI20;
   4814 	  else
   4815 	    reloc = BFD_RELOC_NDS32_HI20;
   4816 	  break;
   4817 	}
   4818       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
   4819 			  insn->info, 0 /* pcrel */, reloc);
   4820     }
   4821   else if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_LO12))
   4822     {
   4823       /* Relocation for lo12 modifier.  */
   4824       if (fld->bitsize == 15 && fld->shift == 0)
   4825 	{
   4826 	  /* [ls]bi || ori */
   4827 	  switch (pexp->X_md)
   4828 	    {
   4829 	    case BFD_RELOC_NDS32_GOTOFF:	/* @GOTOFF */
   4830 	      reloc = BFD_RELOC_NDS32_GOTOFF_LO12;
   4831 	      break;
   4832 	    case BFD_RELOC_NDS32_GOT20:		/* @GOT */
   4833 	      reloc = BFD_RELOC_NDS32_GOT_LO12;
   4834 	      break;
   4835 	    case BFD_RELOC_NDS32_25_PLTREL:	/* @PLT */
   4836 	      if (!nds32_pic)
   4837 		as_bad (_("Invalid PIC expression."));
   4838 	      else
   4839 		reloc = BFD_RELOC_NDS32_PLT_GOTREL_LO12;
   4840 	      break;
   4841 	    case BFD_RELOC_NDS32_GOTPC20:	/* _GLOBAL_OFFSET_TABLE_ */
   4842 	      reloc = BFD_RELOC_NDS32_GOTPC_LO12;
   4843 	      break;
   4844 	    case BFD_RELOC_NDS32_TPOFF:		/* @TPOFF */
   4845 	      reloc = BFD_RELOC_NDS32_TLS_LE_LO12;
   4846 	      break;
   4847 	    case BFD_RELOC_NDS32_GOTTPOFF:	/* @GOTTPOFF */
   4848 	      reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_LO12 : BFD_RELOC_NDS32_TLS_IE_LO12;
   4849 	      break;
   4850 	    case BFD_RELOC_NDS32_TLS_DESC:	/* @TLSDESC */
   4851 	      reloc = BFD_RELOC_NDS32_TLS_DESC_LO12;
   4852 	      break;
   4853 	    default:	/* No suffix */
   4854 	      if (nds32_pic)
   4855 		/* When the file is pic, the address must be offset to gp.
   4856 		   It may define another relocation or use GOTOFF.  */
   4857 		reloc = BFD_RELOC_NDS32_PLT_GOTREL_LO12;
   4858 	      else
   4859 		reloc = BFD_RELOC_NDS32_LO12S0;
   4860 	      break;
   4861 	    }
   4862 	}
   4863       else if (fld->bitsize == 15 && fld->shift == 1)
   4864 	reloc = BFD_RELOC_NDS32_LO12S1;		/* [ls]hi */
   4865       else if (fld->bitsize == 15 && fld->shift == 2)
   4866 	{
   4867 	  /* [ls]wi */
   4868 	  switch (pexp->X_md)
   4869 	    {
   4870 	    case BFD_RELOC_NDS32_GOTTPOFF:	/* @GOTTPOFF */
   4871 	      reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_LO12S2 : BFD_RELOC_NDS32_TLS_IE_LO12S2;
   4872 	      break;
   4873 	    default:	/* No suffix */
   4874 	      reloc = BFD_RELOC_NDS32_LO12S2;
   4875 	      break;
   4876 	    }
   4877 	}
   4878       else if (fld->bitsize == 15 && fld->shift == 3)
   4879 	reloc = BFD_RELOC_NDS32_LO12S3;		/* [ls]di */
   4880       else if (fld->bitsize == 12 && fld->shift == 2)
   4881 	reloc = BFD_RELOC_NDS32_LO12S2_SP;	/* f[ls][sd]i */
   4882 
   4883       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
   4884 			  insn->info, 0 /* pcrel */, reloc);
   4885     }
   4886   else if (fld && fld->bitpos == 0 && insn->opcode->isize == 4
   4887 	   && (insn->attr & NASM_ATTR_PCREL))
   4888     {
   4889       /* Relocation for 32-bit branch instructions.  */
   4890       if (fld->bitsize == 24 && fld->shift == 1)
   4891 	reloc = BFD_RELOC_NDS32_25_PCREL;
   4892       else if (fld->bitsize == 16 && fld->shift == 1)
   4893 	reloc = BFD_RELOC_NDS32_17_PCREL;
   4894       else if (fld->bitsize == 14 && fld->shift == 1)
   4895 	reloc = BFD_RELOC_NDS32_15_PCREL;
   4896       else if (fld->bitsize == 8 && fld->shift == 1)
   4897 	reloc = BFD_RELOC_NDS32_WORD_9_PCREL;
   4898       else
   4899 	abort ();
   4900 
   4901       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
   4902 		   insn->info, 1 /* pcrel */, reloc);
   4903     }
   4904   else if (fld && fld->bitpos == 0 && insn->opcode->isize == 4
   4905 	   && (insn->attr & NASM_ATTR_GPREL))
   4906     {
   4907       /* Relocation for 32-bit gp-relative instructions.  */
   4908       if (fld->bitsize == 19 && fld->shift == 0)
   4909 	reloc = BFD_RELOC_NDS32_SDA19S0;
   4910       else if (fld->bitsize == 18 && fld->shift == 1)
   4911 	reloc = BFD_RELOC_NDS32_SDA18S1;
   4912       else if (fld->bitsize == 17 && fld->shift == 2)
   4913 	reloc = BFD_RELOC_NDS32_SDA17S2;
   4914       else
   4915 	abort ();
   4916 
   4917       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
   4918 		   insn->info, 0 /* pcrel */, reloc);
   4919       /* Insert INSN16 for converting fp_as_gp.  */
   4920       exp.X_op = O_symbol;
   4921       exp.X_add_symbol = abs_section_sym;
   4922       exp.X_add_number = 0;
   4923       if (in_omit_fp && reloc == BFD_RELOC_NDS32_SDA17S2)
   4924 	fix_new_exp (fragP, out - fragP->fr_literal,
   4925 		     insn->opcode->isize, &exp, 0 /* pcrel */,
   4926 		     BFD_RELOC_NDS32_INSN16);
   4927     }
   4928   else if (fld && fld->bitpos == 0 && insn->opcode->isize == 2
   4929 	   && (insn->attr & NASM_ATTR_PCREL))
   4930     {
   4931       /* Relocation for 16-bit branch instructions.  */
   4932       if (fld->bitsize == 8 && fld->shift == 1)
   4933 	reloc = BFD_RELOC_NDS32_9_PCREL;
   4934       else
   4935 	abort ();
   4936 
   4937       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
   4938 		   insn->info, 1 /* pcrel */, reloc);
   4939     }
   4940   else if (fld)
   4941     as_bad (_("Don't know how to handle this field. %s"), str);
   4942 
   4943   return fixP;
   4944 }
   4945 
   4946 /* Build instruction pattern to relax.  There are two type group pattern
   4947    including pseudo instruction and relax hint.  */
   4948 
   4949 static void
   4950 nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out,
   4951 				struct nds32_asm_insn *insn, fragS *fragP,
   4952 				const struct nds32_field *fld,
   4953 				bool pseudo_hint)
   4954 {
   4955   struct nds32_relocs_pattern *reloc_ptr;
   4956   struct nds32_relocs_group *group;
   4957   symbolS *sym = NULL;
   4958 
   4959   /* The expression may be used uninitialized.  */
   4960   if (fld)
   4961     sym = pexp->X_add_symbol;
   4962 
   4963   if (pseudo_hint)
   4964     {
   4965       /* We cannot know how many instructions will be expanded for
   4966 	 the pseudo instruction here.  The first expanded instruction fills
   4967 	 the memory created by relax_hint.  The follower will created and link
   4968 	 here.  */
   4969       group = nds32_relax_hint_current;
   4970       while (group)
   4971 	{
   4972 	  if (group->pattern->opcode == NULL)
   4973 	    nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
   4974 					   group->pattern, fragP);
   4975 	  else
   4976 	    {
   4977 	      group->pattern->next =
   4978 		nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
   4979 					       NULL, fragP);
   4980 	      group->pattern = group->pattern->next;
   4981 	    }
   4982 	  group = group->next;
   4983 	}
   4984     }
   4985   else if (pseudo_opcode)
   4986     {
   4987       /* Save instruction relation for pseudo instruction expanding pattern.  */
   4988       reloc_ptr = nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
   4989 						 NULL, fragP);
   4990       if (!relocs_list)
   4991 	relocs_list = reloc_ptr;
   4992       else
   4993 	{
   4994 	  struct nds32_relocs_pattern *temp = relocs_list;
   4995 	  while (temp->next)
   4996 	    temp = temp->next;
   4997 	  temp->next = reloc_ptr;
   4998 	}
   4999     }
   5000   else if (nds32_relax_hint_current)
   5001     {
   5002       /* Save instruction relation by relax hint.  */
   5003       group = nds32_relax_hint_current;
   5004       while (group)
   5005 	{
   5006 	  nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
   5007 					 group->pattern, fragP);
   5008 	  group = group->next;
   5009 	  free (nds32_relax_hint_current);
   5010 	  nds32_relax_hint_current = group;
   5011 	}
   5012     }
   5013 
   5014   /* Set relaxing false only for relax_hint trigger it.  */
   5015   if (!pseudo_opcode)
   5016     relaxing = false;
   5017 }
   5018 
   5019 #define N32_MEM_EXT(insn) ((N32_OP6_MEM << 25) | insn)
   5020 
   5021 /* Relax pattern for link time relaxation.  */
   5022 /* Relaxation types only! relocation types are not necessary.  */
   5023 /* Refer to nds32_elf_record_fixup_exp ().  */
   5024 
   5025 static struct nds32_relax_hint_table relax_ls_table[] =
   5026 {
   5027   {
   5028     /* LA and Floating LSI.  */
   5029     .main_type = NDS32_RELAX_HINT_LA_FLSI,
   5030     .relax_code_size = 12,
   5031     .relax_code_seq =
   5032       {
   5033 	OP6 (SETHI),
   5034 	OP6 (ORI),
   5035 	OP6 (LBI),
   5036       },
   5037     .relax_fixup =
   5038       {
   5039 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
   5040 	{4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
   5041 	{4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
   5042 	{8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_LSI},
   5043 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
   5044 	{8, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
   5045 	{0, 0, 0, 0}
   5046       }
   5047   },
   5048   {
   5049     /* Load Address / Load-Store (LALS).  */
   5050     .main_type = NDS32_RELAX_HINT_LALS,
   5051     .relax_code_size = 12,
   5052     .relax_code_seq =
   5053       {
   5054 	OP6 (SETHI),
   5055 	OP6 (ORI),
   5056 	OP6 (LBI),
   5057       },
   5058     .relax_fixup =
   5059       {
   5060 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
   5061 	{4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
   5062 	{8, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
   5063 	{0, 0, 0, 0}
   5064       }
   5065   },
   5066   {
   5067     /* B(AL) symbol@PLT  */
   5068     .main_type = NDS32_RELAX_HINT_LA_PLT,
   5069     .relax_code_size = 16,
   5070     .relax_code_seq =
   5071       {
   5072 	OP6 (SETHI),
   5073 	OP6 (ORI),
   5074 	OP6 (ALU1),
   5075 	OP6 (JREG),
   5076       },
   5077     .relax_fixup =
   5078       {
   5079 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
   5080 	{4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
   5081 	{8, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
   5082 	{12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PLT_GOT_SUFF},
   5083 	{12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
   5084 	{12, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
   5085 	{0, 0, 0, 0}
   5086       }
   5087   },
   5088   {
   5089     /* LA (@GOT).  */
   5090     .main_type = NDS32_RELAX_HINT_LA_GOT,
   5091     .relax_code_size = 12,
   5092     .relax_code_seq =
   5093       {
   5094 	OP6 (SETHI),
   5095 	OP6 (ORI),
   5096 	OP6 (MEM),
   5097       },
   5098     .relax_fixup =
   5099       {
   5100 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
   5101 	{4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
   5102 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
   5103 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOT_SUFF},
   5104 	{0, 0, 0, 0}
   5105       }
   5106   },
   5107   {
   5108     /* LA (@GOTOFF).  */
   5109     .main_type = NDS32_RELAX_HINT_LA_GOTOFF,
   5110     .relax_code_size = 16,
   5111     .relax_code_seq =
   5112       {
   5113 	OP6 (SETHI),
   5114 	OP6 (ORI),
   5115 	OP6 (ALU1),
   5116 	OP6 (MEM),
   5117       },
   5118     .relax_fixup =
   5119       {
   5120 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
   5121 	{4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
   5122 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
   5123 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOTOFF_SUFF},
   5124 	{12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
   5125 	{12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOTOFF_SUFF},
   5126 	{0, 0, 0, 0}
   5127       }
   5128   },
   5129   {
   5130     /* TLS LE LS|LA */
   5131     .main_type = NDS32_RELAX_HINT_TLS_LE_LS,
   5132     .relax_code_size = 16,
   5133     .relax_code_seq =
   5134       {
   5135 	OP6(SETHI),
   5136 	OP6(ORI),
   5137 	OP6(MEM),
   5138 	OP6(ALU1),
   5139       },
   5140     .relax_fixup =
   5141       {
   5142 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
   5143 	{4, 4, NDS32_HINT | NDS32_PTR_MULTIPLE, BFD_RELOC_NDS32_PTR},
   5144 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
   5145 	{8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_LE_LS},
   5146 	{12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
   5147 	{12, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_LE_ADD},
   5148 	{0, 0, 0, 0}
   5149       }
   5150   },
   5151   {
   5152     /* TLS IE LA */
   5153     .main_type = NDS32_RELAX_HINT_TLS_IE_LA,
   5154     .relax_code_size = 8,
   5155     .relax_code_seq =
   5156       {
   5157 	OP6(SETHI),
   5158 	OP6(LBI),
   5159       },
   5160     .relax_fixup =
   5161       {
   5162 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
   5163 	{4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
   5164 	{0, 0, 0, 0}
   5165       }
   5166   },
   5167   {
   5168     /* TLS IEGP LA */
   5169     .main_type = NDS32_RELAX_HINT_TLS_IEGP_LA,
   5170     .relax_code_size = 12,
   5171     .relax_code_seq =
   5172       {
   5173 	OP6 (SETHI),
   5174 	OP6 (ORI),
   5175 	OP6 (MEM),
   5176       },
   5177     .relax_fixup =
   5178       {
   5179 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
   5180 	{4, 4, NDS32_HINT | NDS32_PTR_PATTERN, BFD_RELOC_NDS32_PTR},
   5181 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
   5182 	{8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_IEGP_LW},
   5183 	{0, 0, 0, 0}
   5184       }
   5185   },
   5186   {
   5187     /* TLS DESC LS:  */
   5188     .main_type = NDS32_RELAX_HINT_TLS_DESC_LS,
   5189     .relax_code_size = 24,
   5190     .relax_code_seq =
   5191       {
   5192 	OP6 (SETHI),
   5193 	OP6 (ORI),
   5194 	OP6 (ALU1),
   5195 	OP6 (LBI),	/* load argument */
   5196 	OP6 (JREG),
   5197 	OP6 (MEM),	/* load/store variable or load argument */
   5198       },
   5199     .relax_fixup =
   5200       {
   5201 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
   5202 	{4, 4, NDS32_HINT | NDS32_PTR_PATTERN, BFD_RELOC_NDS32_PTR},
   5203 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
   5204 	{8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_ADD},
   5205 	{12, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_FUNC},
   5206 	{16, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_CALL},
   5207 	{20, 4, NDS32_HINT | NDS32_SYM_DESC_MEM, BFD_RELOC_NDS32_TLS_DESC_MEM},
   5208 	{0, 0, 0, 0}
   5209       }
   5210   },
   5211   {
   5212     .main_type = 0,
   5213     .relax_code_seq = {0},
   5214     .relax_fixup = {{0, 0 , 0, 0}}
   5215   }
   5216 };
   5217 
   5218 /* Since sethi loadstore relocation has to using next instruction to determine
   5219    elimination itself or not, we have to return the next instruction range.  */
   5220 
   5221 static int
   5222 nds32_elf_sethi_range (struct nds32_relocs_pattern *pattern)
   5223 {
   5224   int range = 0;
   5225   while (pattern)
   5226     {
   5227       switch (pattern->opcode->value)
   5228 	{
   5229 	case INSN_LBI:
   5230 	case INSN_SBI:
   5231 	case INSN_LBSI:
   5232 	case N32_MEM_EXT (N32_MEM_LB):
   5233 	case N32_MEM_EXT (N32_MEM_LBS):
   5234 	case N32_MEM_EXT (N32_MEM_SB):
   5235 	  range = NDS32_LOADSTORE_BYTE;
   5236 	  break;
   5237 	case INSN_LHI:
   5238 	case INSN_SHI:
   5239 	case INSN_LHSI:
   5240 	case N32_MEM_EXT (N32_MEM_LH):
   5241 	case N32_MEM_EXT (N32_MEM_LHS):
   5242 	case N32_MEM_EXT (N32_MEM_SH):
   5243 	  range = NDS32_LOADSTORE_HALF;
   5244 	  break;
   5245 	case INSN_LWI:
   5246 	case INSN_SWI:
   5247 	case N32_MEM_EXT (N32_MEM_LW):
   5248 	case N32_MEM_EXT (N32_MEM_SW):
   5249 	  range = NDS32_LOADSTORE_WORD;
   5250 	  break;
   5251 	case INSN_FLSI:
   5252 	case INSN_FSSI:
   5253 	  range = NDS32_LOADSTORE_FLOAT_S;
   5254 	  break;
   5255 	case INSN_FLDI:
   5256 	case INSN_FSDI:
   5257 	  range = NDS32_LOADSTORE_FLOAT_D;
   5258 	  break;
   5259 	case INSN_ORI:
   5260 	  range = NDS32_LOADSTORE_IMM;
   5261 	  break;
   5262 	default:
   5263 	  range = NDS32_LOADSTORE_NONE;
   5264 	  break;
   5265 	}
   5266       if (range != NDS32_LOADSTORE_NONE)
   5267 	break;
   5268       pattern = pattern->next;
   5269     }
   5270   return range;
   5271 }
   5272 
   5273 /* The args means: instruction size, the 1st instruction is converted to 16 or
   5274    not, optimize option, 16 bit instruction is enable.  */
   5275 
   5276 #define SET_ADDEND(size, convertible, optimize, insn16_on) \
   5277   (((size) & 0xff) | ((convertible) ? 1u << 31 : 0) \
   5278    | ((optimize) ? 1 << 30 : 0) | (insn16_on ? 1 << 29 : 0))
   5279 #define MAC_COMBO (E_NDS32_HAS_FPU_MAC_INST|E_NDS32_HAS_MAC_DX_INST)
   5280 
   5281 static void
   5282 nds32_set_elf_flags_by_insn (struct nds32_asm_insn * insn)
   5283 {
   5284   static int skip_flags = NASM_ATTR_FPU_FMA
   5285     | NASM_ATTR_BRANCH | NASM_ATTR_SATURATION_EXT
   5286     | NASM_ATTR_GPREL | NASM_ATTR_DXREG
   5287     | NASM_ATTR_ISA_V1 | NASM_ATTR_ISA_V2
   5288     | NASM_ATTR_ISA_V3 | NASM_ATTR_ISA_V3M
   5289     | NASM_ATTR_PCREL;
   5290 
   5291   int new_flags = insn->opcode->attr & ~skip_flags;
   5292   while (new_flags)
   5293     {
   5294       int next = 1 << (ffs (new_flags) - 1);
   5295       new_flags &= ~next;
   5296       switch (next)
   5297 	{
   5298 	case NASM_ATTR_PERF_EXT:
   5299 	  {
   5300 	    if (nds32_perf_ext)
   5301 	      {
   5302 		nds32_elf_flags |= E_NDS32_HAS_EXT_INST;
   5303 		skip_flags |= NASM_ATTR_PERF_EXT;
   5304 	      }
   5305 	    else
   5306 	      as_bad (_("instruction %s requires enabling performance "
   5307 			"extension"), insn->opcode->opcode);
   5308 	  }
   5309 	  break;
   5310 	case NASM_ATTR_PERF2_EXT:
   5311 	  {
   5312 	    if (nds32_perf_ext2)
   5313 	      {
   5314 		nds32_elf_flags |= E_NDS32_HAS_EXT2_INST;
   5315 		skip_flags |= NASM_ATTR_PERF2_EXT;
   5316 	      }
   5317 	    else
   5318 	      as_bad (_("instruction %s requires enabling performance "
   5319 			"extension II"), insn->opcode->opcode);
   5320 	  }
   5321 	  break;
   5322 	case NASM_ATTR_AUDIO_ISAEXT:
   5323 	  {
   5324 	    if (nds32_audio_ext)
   5325 	      {
   5326 		nds32_elf_flags |= E_NDS32_HAS_AUDIO_INST;
   5327 		skip_flags |= NASM_ATTR_AUDIO_ISAEXT;
   5328 	      }
   5329 	    else
   5330 	      as_bad (_("instruction %s requires enabling AUDIO extension"),
   5331 		      insn->opcode->opcode);
   5332 	  }
   5333 	  break;
   5334 	case NASM_ATTR_STR_EXT:
   5335 	  {
   5336 	    if (nds32_string_ext)
   5337 	      {
   5338 		nds32_elf_flags |= E_NDS32_HAS_STRING_INST;
   5339 		skip_flags |= NASM_ATTR_STR_EXT;
   5340 	      }
   5341 	    else
   5342 	      as_bad (_("instruction %s requires enabling STRING extension"),
   5343 		      insn->opcode->opcode);
   5344 	  }
   5345 	  break;
   5346 	case NASM_ATTR_DIV:
   5347 	  {
   5348 	    if (insn->opcode->attr & NASM_ATTR_DXREG)
   5349 	      {
   5350 		if (nds32_div && nds32_dx_regs)
   5351 		  {
   5352 		    nds32_elf_flags |= E_NDS32_HAS_DIV_DX_INST;
   5353 		    skip_flags |= NASM_ATTR_DIV;
   5354 		  }
   5355 		else
   5356 		  as_bad (_("instruction %s requires enabling DIV & DX_REGS "
   5357 			    "extension"), insn->opcode->opcode);
   5358 	      }
   5359 	  }
   5360 	  break;
   5361 	case NASM_ATTR_FPU:
   5362 	  {
   5363 	    if (nds32_fpu_sp_ext || nds32_fpu_dp_ext)
   5364 	      {
   5365 		if (!(nds32_elf_flags
   5366 		      & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
   5367 		  nds32_fpu_com = 1;
   5368 		skip_flags |= NASM_ATTR_FPU;
   5369 	      }
   5370 	    else
   5371 	      as_bad (_("instruction %s requires enabling FPU extension"),
   5372 		      insn->opcode->opcode);
   5373 	  }
   5374 	  break;
   5375 	case NASM_ATTR_FPU_SP_EXT:
   5376 	  {
   5377 	    if (nds32_fpu_sp_ext)
   5378 	      {
   5379 		nds32_elf_flags |= E_NDS32_HAS_FPU_INST;
   5380 		skip_flags |= NASM_ATTR_FPU_SP_EXT;
   5381 	      }
   5382 	    else
   5383 	      as_bad (_("instruction %s requires enabling FPU_SP extension"),
   5384 		      insn->opcode->opcode);
   5385 	  }
   5386 	  break;
   5387 	case NASM_ATTR_FPU_DP_EXT:
   5388 	  {
   5389 	    if (nds32_fpu_dp_ext)
   5390 	      {
   5391 		nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST;
   5392 		skip_flags |= NASM_ATTR_FPU_DP_EXT;
   5393 	      }
   5394 	    else
   5395 	      as_bad (_("instruction %s requires enabling FPU_DP extension"),
   5396 		      insn->opcode->opcode);
   5397 	  }
   5398 	  break;
   5399 	case NASM_ATTR_MAC:
   5400 	  {
   5401 	    if (insn->opcode->attr & NASM_ATTR_FPU_SP_EXT)
   5402 	      {
   5403 		if (nds32_fpu_sp_ext && nds32_mac)
   5404 		  nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
   5405 		else
   5406 		  as_bad (_("instruction %s requires enabling FPU_MAC "
   5407 			    "extension"), insn->opcode->opcode);
   5408 	      }
   5409 	    else if (insn->opcode->attr & NASM_ATTR_FPU_DP_EXT)
   5410 	      {
   5411 		if (nds32_fpu_dp_ext && nds32_mac)
   5412 		  nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
   5413 		else
   5414 		  as_bad (_("instruction %s requires enabling FPU_MAC "
   5415 			    "extension"), insn->opcode->opcode);
   5416 	      }
   5417 	    else if (insn->opcode->attr & NASM_ATTR_DXREG)
   5418 	      {
   5419 		if (nds32_dx_regs && nds32_mac)
   5420 		  nds32_elf_flags |= E_NDS32_HAS_MAC_DX_INST;
   5421 		else
   5422 		  as_bad (_("instruction %s requires enabling DX_REGS "
   5423 			    "extension"), insn->opcode->opcode);
   5424 	      }
   5425 
   5426 	    if (MAC_COMBO == (MAC_COMBO & nds32_elf_flags))
   5427 	      skip_flags |= NASM_ATTR_MAC;
   5428 	  }
   5429 	  break;
   5430 	case NASM_ATTR_DSP_ISAEXT:
   5431 	  {
   5432 	    if (nds32_dsp_ext)
   5433 	      {
   5434 		nds32_elf_flags |= E_NDS32_HAS_DSP_INST;
   5435 		skip_flags |= NASM_ATTR_DSP_ISAEXT;
   5436 	      }
   5437 	    else
   5438 	      as_bad (_("instruction %s requires enabling dsp extension"),
   5439 		      insn->opcode->opcode);
   5440 	  }
   5441 	  break;
   5442 	case NASM_ATTR_ZOL:
   5443 	  {
   5444 	    if (nds32_zol_ext)
   5445 	      {
   5446 		nds32_elf_flags |= E_NDS32_HAS_ZOL;
   5447 		skip_flags |= NASM_ATTR_ZOL;
   5448 	      }
   5449 	    else
   5450 	      as_bad (_("instruction %s requires enabling zol extension"),
   5451 		      insn->opcode->opcode);
   5452 	  }
   5453 	  break;
   5454 	default:
   5455 	  as_bad (_("internal error: unknown instruction attribute: 0x%08x"),
   5456 		  next);
   5457 	}
   5458     }
   5459 }
   5460 
   5461 /* Flag for analysis relaxation type.  */
   5462 
   5463 enum nds32_insn_type
   5464 {
   5465   N32_RELAX_SETHI = 1,
   5466   N32_RELAX_BR = (1 << 1),
   5467   N32_RELAX_LSI = (1 << 2),
   5468   N32_RELAX_JUMP = (1 << 3),
   5469   N32_RELAX_CALL = (1 << 4),
   5470   N32_RELAX_ORI = (1 << 5),
   5471   N32_RELAX_MEM = (1 << 6),
   5472   N32_RELAX_MOVI = (1 << 7),
   5473   N32_RELAX_ALU1 = (1 << 8),
   5474   N32_RELAX_16BIT = (1 << 9),
   5475 };
   5476 
   5477 struct nds32_hint_map
   5478 {
   5479   /* the preamble relocation */
   5480   bfd_reloc_code_real_type hi_type;
   5481   /* mnemonic */
   5482   const char *opc;
   5483   /* relax pattern ID */
   5484   enum nds32_relax_hint_type hint_type;
   5485   /* range */
   5486   enum nds32_br_range range;
   5487   /* pattern character flags */
   5488   enum nds32_insn_type insn_list;
   5489   /* optional pattern character flags */
   5490   enum nds32_insn_type option_list;
   5491 };
   5492 
   5493 /* Table to match instructions with hint and relax pattern.  */
   5494 
   5495 static struct nds32_hint_map hint_map [] =
   5496 {
   5497   {
   5498     /* LONGCALL4.  */
   5499     BFD_RELOC_NDS32_HI20,
   5500     "jal",
   5501     NDS32_RELAX_HINT_NONE,
   5502     BR_RANGE_U4G,
   5503     N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL,
   5504     0,
   5505   },
   5506   {
   5507     /* LONGCALL5.  */
   5508     _dummy_first_bfd_reloc_code_real,
   5509     "bgezal",
   5510     NDS32_RELAX_HINT_NONE,
   5511     BR_RANGE_S16M,
   5512     N32_RELAX_BR | N32_RELAX_CALL,
   5513     0,
   5514   },
   5515   {
   5516     /* LONGCALL6.  */
   5517     BFD_RELOC_NDS32_HI20,
   5518     "bgezal",
   5519     NDS32_RELAX_HINT_NONE,
   5520     BR_RANGE_U4G,
   5521     N32_RELAX_BR | N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL,
   5522     0,
   5523   },
   5524   {
   5525     /* LONGJUMP4.  */
   5526     BFD_RELOC_NDS32_HI20,
   5527     "j",
   5528     NDS32_RELAX_HINT_NONE,
   5529     BR_RANGE_U4G,
   5530     N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_JUMP,
   5531     0,
   5532   },
   5533   {
   5534     /* LONGJUMP5.  */
   5535     /* There is two kinds of variation of LONGJUMP5.  One of them
   5536        generate EMPTY relocation for converted INSN16 if needed.
   5537        But we don't distinguish them here.  */
   5538     _dummy_first_bfd_reloc_code_real,
   5539     "beq",
   5540     NDS32_RELAX_HINT_NONE,
   5541     BR_RANGE_S16M,
   5542     N32_RELAX_BR | N32_RELAX_JUMP,
   5543     0,
   5544   },
   5545   {
   5546     /* LONGJUMP6.  */
   5547     BFD_RELOC_NDS32_HI20,
   5548     "beq",
   5549     NDS32_RELAX_HINT_NONE,
   5550     BR_RANGE_U4G,
   5551     N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_BR | N32_RELAX_JUMP,
   5552     0,
   5553   },
   5554   {
   5555     /* LONGJUMP7.  */
   5556     _dummy_first_bfd_reloc_code_real,
   5557     "beqc",
   5558     NDS32_RELAX_HINT_NONE,
   5559     BR_RANGE_S16K,
   5560     N32_RELAX_MOVI | N32_RELAX_BR,
   5561     0,
   5562   },
   5563   {
   5564     /* LONGCALL (BAL|JR|LA symbol@PLT).  */
   5565     BFD_RELOC_NDS32_PLT_GOTREL_HI20,
   5566     NULL,
   5567     NDS32_RELAX_HINT_LA_PLT,
   5568     BR_RANGE_U4G,
   5569     N32_RELAX_SETHI | N32_RELAX_ORI,
   5570     N32_RELAX_ALU1 | N32_RELAX_CALL | N32_RELAX_JUMP,
   5571   },
   5572   /* relative issue: #12566 */
   5573   {
   5574     /* LA and Floating LSI.  */
   5575     BFD_RELOC_NDS32_HI20,
   5576     NULL,
   5577     NDS32_RELAX_HINT_LA_FLSI,
   5578     BR_RANGE_U4G,
   5579     N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_LSI,
   5580     0,
   5581   },
   5582   /* relative issue: #11685 #11602 */
   5583   {
   5584     /* load address / load-store (LALS).  */
   5585     BFD_RELOC_NDS32_HI20,
   5586     NULL,
   5587     NDS32_RELAX_HINT_LALS,
   5588     BR_RANGE_U4G,
   5589     N32_RELAX_SETHI,
   5590     N32_RELAX_ORI | N32_RELAX_LSI,
   5591   },
   5592   {
   5593     /* setup $GP (_GLOBAL_OFFSET_TABLE_)  */
   5594     BFD_RELOC_NDS32_GOTPC_HI20,
   5595     NULL,
   5596     NDS32_RELAX_HINT_LALS,
   5597     BR_RANGE_U4G,
   5598     N32_RELAX_SETHI | N32_RELAX_ORI,
   5599     0,
   5600   },
   5601   {
   5602     /* GOT LA/LS (symbol@GOT)  */
   5603     BFD_RELOC_NDS32_GOT_HI20,
   5604     NULL,
   5605     NDS32_RELAX_HINT_LA_GOT,
   5606     BR_RANGE_U4G,
   5607     N32_RELAX_SETHI | N32_RELAX_ORI,
   5608     N32_RELAX_MEM,
   5609   },
   5610   {
   5611     /* GOTOFF LA/LS (symbol@GOTOFF)  */
   5612     BFD_RELOC_NDS32_GOTOFF_HI20,
   5613     NULL,
   5614     NDS32_RELAX_HINT_LA_GOTOFF,
   5615     BR_RANGE_U4G,
   5616     N32_RELAX_SETHI | N32_RELAX_ORI,
   5617     N32_RELAX_ALU1  | N32_RELAX_MEM, /* | N32_RELAX_LSI, */
   5618   },
   5619   {
   5620     /* TLS LE LA|LS (@TPOFF)  */
   5621     BFD_RELOC_NDS32_TLS_LE_HI20,
   5622     NULL,
   5623     NDS32_RELAX_HINT_TLS_LE_LS,
   5624     BR_RANGE_U4G,
   5625     N32_RELAX_SETHI | N32_RELAX_ORI,
   5626     N32_RELAX_ALU1 | N32_RELAX_MEM,
   5627   },
   5628   {
   5629     /* TLS IE LA */
   5630     BFD_RELOC_NDS32_TLS_IE_HI20,
   5631     NULL,
   5632     NDS32_RELAX_HINT_TLS_IE_LA,
   5633     BR_RANGE_U4G,
   5634     N32_RELAX_SETHI | N32_RELAX_LSI,
   5635     0,
   5636   },
   5637 {
   5638     /* TLS IE LS */
   5639     BFD_RELOC_NDS32_TLS_IE_HI20,
   5640     NULL,
   5641     NDS32_RELAX_HINT_TLS_IE_LS,
   5642     BR_RANGE_U4G,
   5643     N32_RELAX_SETHI | N32_RELAX_LSI | N32_RELAX_MEM,
   5644     0,
   5645   },
   5646   {
   5647     /* TLS IEGP LA */
   5648     BFD_RELOC_NDS32_TLS_IEGP_HI20,
   5649     NULL,
   5650     NDS32_RELAX_HINT_TLS_IEGP_LA,
   5651     BR_RANGE_U4G,
   5652     N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_MEM,
   5653     0,
   5654   },
   5655   {
   5656     /* TLS DESC LS */
   5657     BFD_RELOC_NDS32_TLS_DESC_HI20,
   5658     NULL,
   5659     NDS32_RELAX_HINT_TLS_DESC_LS,
   5660     BR_RANGE_U4G,
   5661     N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_ALU1 | N32_RELAX_CALL,
   5662     N32_RELAX_LSI | N32_RELAX_MEM,
   5663   },
   5664   /* last one */
   5665   {0, NULL, 0, 0 ,0, 0}
   5666 };
   5667 
   5668 /* Find the relaxation pattern according to instructions.  */
   5669 
   5670 static bool
   5671 nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern,
   5672 			struct nds32_relax_hint_table *hint_info)
   5673 {
   5674   unsigned int opcode, seq_size;
   5675   enum nds32_br_range range;
   5676   struct nds32_relocs_pattern *pattern, *hi_pattern = NULL;
   5677   const char *opc = NULL;
   5678   relax_info_t *relax_info = NULL;
   5679   nds32_relax_fixup_info_t *fixup_info, *hint_fixup;
   5680   enum nds32_relax_hint_type hint_type = NDS32_RELAX_HINT_NONE;
   5681   struct nds32_relax_hint_table *table_ptr;
   5682   uint32_t *code_seq, *hint_code;
   5683   enum nds32_insn_type relax_type = 0;
   5684   struct nds32_hint_map *map_ptr = hint_map;
   5685   unsigned int i;
   5686   const char *check_insn[] =
   5687     { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" };
   5688 
   5689   /* TODO: PLT GOT.  */
   5690   /* Traverse all pattern instruction and set flag.  */
   5691   pattern = relocs_pattern;
   5692   while (pattern)
   5693     {
   5694       if (pattern->opcode->isize == 4)
   5695 	{
   5696 	  /* 4 byte instruction.  */
   5697 	  opcode = N32_OP6 (pattern->opcode->value);
   5698 	  switch (opcode)
   5699 	    {
   5700 	    case N32_OP6_SETHI:
   5701 	      hi_pattern = pattern;
   5702 	      relax_type |= N32_RELAX_SETHI;
   5703 	      break;
   5704 	    case N32_OP6_MEM:
   5705 	      relax_type |= N32_RELAX_MEM;
   5706 	      break;
   5707 	    case N32_OP6_ALU1:
   5708 	      relax_type |= N32_RELAX_ALU1;
   5709 	      break;
   5710 	    case N32_OP6_ORI:
   5711 	      relax_type |= N32_RELAX_ORI;
   5712 	      break;
   5713 	    case N32_OP6_BR1:
   5714 	    case N32_OP6_BR2:
   5715 	    case N32_OP6_BR3:
   5716 	      relax_type |= N32_RELAX_BR;
   5717 	      break;
   5718 	    case N32_OP6_MOVI:
   5719 	      relax_type |= N32_RELAX_MOVI;
   5720 	      break;
   5721 	    case N32_OP6_LBI:
   5722 	    case N32_OP6_SBI:
   5723 	    case N32_OP6_LBSI:
   5724 	    case N32_OP6_LHI:
   5725 	    case N32_OP6_SHI:
   5726 	    case N32_OP6_LHSI:
   5727 	    case N32_OP6_LWI:
   5728 	    case N32_OP6_SWI:
   5729 	    case N32_OP6_LWC:
   5730 	    case N32_OP6_SWC:
   5731 	    case N32_OP6_LDC:
   5732 	    case N32_OP6_SDC:
   5733 	      relax_type |= N32_RELAX_LSI;
   5734 	      break;
   5735 	    case N32_OP6_JREG:
   5736 	      if (__GF (pattern->opcode->value, 0, 1) == 1)
   5737 		relax_type |= N32_RELAX_CALL;
   5738 	      else
   5739 		relax_type |= N32_RELAX_JUMP;
   5740 	      break;
   5741 	    case N32_OP6_JI:
   5742 	      if (__GF (pattern->opcode->value, 24, 1) == 1)
   5743 		relax_type |= N32_RELAX_CALL;
   5744 	      else
   5745 		relax_type |= N32_RELAX_JUMP;
   5746 	      break;
   5747 	    default:
   5748 	      as_warn (_("relax hint unrecognized instruction: line %d."),
   5749 		       pattern->frag->fr_line);
   5750 	      return false;
   5751 	    }
   5752 	}
   5753       else
   5754 	{
   5755 	  /* 2 byte instruction.  Compare by opcode name because
   5756 	     the opcode of 2byte instruction is not regular.  */
   5757 	  int is_matched = 0;
   5758 	  for (i = 0; i < ARRAY_SIZE (check_insn); i++)
   5759 	    {
   5760 	      if (strcmp (pattern->opcode->opcode, check_insn[i]) == 0)
   5761 		{
   5762 		  relax_type |= N32_RELAX_BR;
   5763 		  is_matched += 1;
   5764 		  break;
   5765 		}
   5766 	    }
   5767 	  if (!is_matched)
   5768 	    relax_type |= N32_RELAX_16BIT;
   5769 	}
   5770       pattern = pattern->next;
   5771     }
   5772 
   5773   /* Analysis instruction flag to choose relaxation table.  */
   5774   while (map_ptr->insn_list != 0)
   5775     {
   5776       struct nds32_hint_map *hint = map_ptr++;
   5777       enum nds32_insn_type must = hint->insn_list;
   5778       enum nds32_insn_type optional = hint->option_list;
   5779       enum nds32_insn_type extra;
   5780 
   5781       if (must != (must & relax_type))
   5782 	continue;
   5783 
   5784       extra = relax_type ^ must;
   5785       if (extra != (extra & optional))
   5786 	continue;
   5787 
   5788       if (!hi_pattern
   5789 	  || (hi_pattern->fixP
   5790 	      && hi_pattern->fixP->fx_r_type == hint->hi_type))
   5791 	{
   5792 	  opc = hint->opc;
   5793 	  hint_type = hint->hint_type;
   5794 	  range = hint->range;
   5795 	  map_ptr = hint;
   5796 	  break;
   5797 	}
   5798     }
   5799 
   5800   if (map_ptr->insn_list == 0)
   5801     {
   5802       if (!nds32_pic)
   5803 	as_warn (_("Can not find match relax hint.  Line: %d"),
   5804 		 relocs_pattern->frag->fr_line);
   5805       return false;
   5806     }
   5807 
   5808   /* Get the match table.  */
   5809   if (opc)
   5810     {
   5811       /* Branch relax pattern.  */
   5812       relax_info = str_hash_find (nds32_relax_info_hash, opc);
   5813       if (!relax_info)
   5814 	return false;
   5815       fixup_info = relax_info->relax_fixup[range];
   5816       code_seq = relax_info->relax_code_seq[range];
   5817       seq_size = relax_info->relax_code_size[range];
   5818     }
   5819   else if (hint_type)
   5820     {
   5821       /* Load-store relax pattern.  */
   5822       table_ptr = relax_ls_table;
   5823       while (table_ptr->main_type != 0)
   5824 	{
   5825 	  if (table_ptr->main_type == hint_type)
   5826 	    {
   5827 	      fixup_info = table_ptr->relax_fixup;
   5828 	      code_seq = table_ptr->relax_code_seq;
   5829 	      seq_size = table_ptr->relax_code_size;
   5830 	      break;
   5831 	    }
   5832 	  table_ptr++;
   5833 	}
   5834       if (table_ptr->main_type == 0)
   5835 	return false;
   5836     }
   5837   else
   5838     return false;
   5839 
   5840   hint_fixup = hint_info->relax_fixup;
   5841   hint_code = hint_info->relax_code_seq;
   5842   hint_info->relax_code_size = seq_size;
   5843 
   5844   while (fixup_info->size != 0)
   5845     {
   5846       if (fixup_info->ramp & NDS32_HINT)
   5847 	{
   5848 	  memcpy (hint_fixup, fixup_info, sizeof (nds32_relax_fixup_info_t));
   5849 	  hint_fixup++;
   5850 	}
   5851       fixup_info++;
   5852     }
   5853   /* Clear final relocation.  */
   5854   memset (hint_fixup, 0, sizeof (nds32_relax_fixup_info_t));
   5855   /* Copy code sequence.  */
   5856   memcpy (hint_code, code_seq, seq_size);
   5857   return true;
   5858 }
   5859 
   5860 /* Because there are a lot of variant of load-store, check
   5861    all these type here.  */
   5862 
   5863 #define CLEAN_REG(insn) ((insn) & 0xfe0003ff)
   5864 #define GET_OPCODE(insn) ((insn) & 0xfe000000)
   5865 
   5866 static bool
   5867 nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq)
   5868 {
   5869   const char *check_insn[] =
   5870     { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8", "jral5" };
   5871   uint32_t insn = opcode->value;
   5872   unsigned int i;
   5873 
   5874   insn = CLEAN_REG (opcode->value);
   5875   if (insn == seq)
   5876     return true;
   5877 
   5878   switch (seq)
   5879     {
   5880     case OP6 (LBI):
   5881       /* In relocation_table, it regards instruction LBI as representation
   5882 	 of all the NDS32_RELAX_HINT_LS pattern.  */
   5883       if (insn == OP6 (LBI) || insn == OP6 (SBI) || insn == OP6 (LBSI)
   5884 	  || insn == OP6 (LHI) || insn == OP6 (SHI) || insn == OP6 (LHSI)
   5885 	  || insn == OP6 (LWI) || insn == OP6 (SWI)
   5886 	  || insn == OP6 (LWC) || insn == OP6 (SWC)
   5887 	  || insn == OP6 (LDC) || insn == OP6 (SDC))
   5888 	return true;
   5889       break;
   5890     case OP6 (BR2):
   5891       /* This is for LONGCALL5 and LONGCALL6.  */
   5892       if (insn == OP6 (BR2))
   5893 	return true;
   5894       break;
   5895     case OP6 (BR1):
   5896       /* This is for LONGJUMP5 and LONGJUMP6.  */
   5897       if (opcode->isize == 4
   5898 	  && (insn == OP6 (BR1) || insn == OP6 (BR2) || insn == OP6 (BR3)))
   5899 	return true;
   5900       else if (opcode->isize == 2)
   5901 	{
   5902 	  for (i = 0; i < ARRAY_SIZE (check_insn); i++)
   5903 	    if (strcmp (opcode->opcode, check_insn[i]) == 0)
   5904 	      return true;
   5905 	}
   5906       break;
   5907     case OP6 (MOVI):
   5908       /* This is for LONGJUMP7.  */
   5909       if (opcode->isize == 2 && strcmp (opcode->opcode, "movi55") == 0)
   5910 	return true;
   5911       break;
   5912     case OP6 (MEM):
   5913       if (OP6 (MEM) == GET_OPCODE (insn))
   5914 	return true;
   5915       break;
   5916     case OP6 (JREG):
   5917       /* bit 24: N32_JI_JAL  */ /* feed me!  */
   5918       if ((insn & ~(N32_BIT (24))) == JREG (JRAL))
   5919 	return true;
   5920       break;
   5921     default:
   5922       if (opcode->isize == 2)
   5923 	{
   5924 	  for (i = 0; i < ARRAY_SIZE (check_insn); i++)
   5925 	    if (strcmp (opcode->opcode, check_insn[i]) == 0)
   5926 	      return true;
   5927 
   5928 	  if ((strcmp (opcode->opcode, "add5.pc") == 0) ||
   5929 	      (strcmp (opcode->opcode, "add45") == 0))
   5930 	    return true;
   5931 	}
   5932     }
   5933   return false;
   5934 }
   5935 
   5936 /* Append relax relocation for link time relaxing.  */
   5937 
   5938 static void
   5939 nds32_elf_append_relax_relocs (const char *key, const void *value)
   5940 {
   5941   struct nds32_relocs_pattern *relocs_pattern =
   5942     (struct nds32_relocs_pattern *) value;
   5943   struct nds32_relocs_pattern *pattern_temp, *pattern_now;
   5944   symbolS *sym, *hi_sym = NULL;
   5945   expressionS exp;
   5946   fragS *fragP;
   5947   segT seg_bak = now_seg;
   5948   frchainS *frchain_bak = frchain_now;
   5949   struct nds32_relax_hint_table hint_info;
   5950   nds32_relax_fixup_info_t *hint_fixup, *fixup_now;
   5951   size_t fixup_size;
   5952   offsetT branch_offset, hi_branch_offset = 0;
   5953   fixS *fixP;
   5954   int range, offset;
   5955   unsigned int ptr_offset, hint_count, relax_code_size, count = 0;
   5956   uint32_t *code_seq, code_insn;
   5957   char *where;
   5958   int pcrel;
   5959 
   5960   if (!relocs_pattern)
   5961     return;
   5962 
   5963   if (!nds32_find_reloc_table (relocs_pattern, &hint_info))
   5964     return;
   5965 
   5966   /* Save symbol for some EMPTY relocation using.  */
   5967   pattern_now = relocs_pattern;
   5968   while (pattern_now)
   5969     {
   5970       if (pattern_now->opcode->value == OP6 (SETHI))
   5971 	{
   5972 	  hi_sym = pattern_now->sym;
   5973 	  hi_branch_offset = pattern_now->fixP->fx_offset;
   5974 	  break;
   5975 	}
   5976       pattern_now = pattern_now->next;
   5977     }
   5978 
   5979   /* Inserting fix up must specify now_seg or frchain_now.  */
   5980   now_seg = relocs_pattern->seg;
   5981   frchain_now = relocs_pattern->frchain;
   5982   fragP = relocs_pattern->frag;
   5983   branch_offset = fragP->fr_offset;
   5984 
   5985   hint_fixup = hint_info.relax_fixup;
   5986   code_seq = hint_info.relax_code_seq;
   5987   relax_code_size = hint_info.relax_code_size;
   5988   pattern_now = relocs_pattern;
   5989 
   5990 #ifdef NDS32_LINUX_TOOLCHAIN
   5991   /* prepare group relocation ID (number).  */
   5992   long group_id = 0;
   5993   if (key)
   5994     {
   5995       /* convert .relax_hint key to number */
   5996       errno = 0;
   5997       group_id = strtol (key, NULL, 10);
   5998       if ((errno == ERANGE && (group_id == LONG_MAX || group_id == LONG_MIN))
   5999 	  || (errno != 0 && group_id == 0))
   6000 	{
   6001 	  as_bad (_("Internal error: .relax_hint KEY is not a number!"));
   6002 	  goto restore;
   6003 	}
   6004     }
   6005 #endif
   6006 
   6007   /* Insert relaxation.  */
   6008   exp.X_op = O_symbol;
   6009 
   6010   /* For each instruction in the hint group.  */
   6011   while (pattern_now)
   6012     {
   6013       if (count >= relax_code_size / 4)
   6014 	count = 0;
   6015 
   6016       /* Choose the match fixup by instruction.  */
   6017       code_insn = CLEAN_REG (*(code_seq + count));
   6018       if (!nds32_match_hint_insn (pattern_now->opcode, code_insn))
   6019 	{
   6020 	  /* Try search from head again */
   6021 	  count = 0;
   6022 	  code_insn = CLEAN_REG (*(code_seq + count));
   6023 
   6024 	  while (!nds32_match_hint_insn (pattern_now->opcode, code_insn))
   6025 	    {
   6026 	      count++;
   6027 	      if (count >= relax_code_size / 4)
   6028 		{
   6029 		  as_bad (_("Internal error: Relax hint (%s) error. %s: %s (%x)"),
   6030 			  key,
   6031 			  now_seg->name,
   6032 			  pattern_now->opcode->opcode,
   6033 			  pattern_now->opcode->value);
   6034 		  goto restore;
   6035 		}
   6036 	      code_insn = CLEAN_REG (*(code_seq + count));
   6037 	    }
   6038 	}
   6039       fragP = pattern_now->frag;
   6040       sym = pattern_now->sym;
   6041       branch_offset = fragP->fr_offset;
   6042       offset = count * 4;
   6043       where = pattern_now->where;
   6044       /* Find the instruction map fix.  */
   6045       fixup_now = hint_fixup;
   6046       while (fixup_now->offset != offset)
   6047 	{
   6048 	  fixup_now++;
   6049 	  if (fixup_now->size == 0)
   6050 	    break;
   6051 	}
   6052       /* This element is without relaxation relocation.  */
   6053       if (fixup_now->size == 0)
   6054 	{
   6055 	  pattern_now = pattern_now->next;
   6056 	  continue;
   6057 	}
   6058       fixup_size = fixup_now->size;
   6059 
   6060       /* Insert all fixup.  */
   6061       pcrel = 0;
   6062       while (fixup_size != 0 && fixup_now->offset == offset)
   6063 	{
   6064 	  /* Set the real instruction size in element.  */
   6065 	  fixup_size = pattern_now->opcode->isize;
   6066 	  pcrel = ((fixup_now->ramp & NDS32_PCREL) != 0) ? 1 : 0;
   6067 	  if (fixup_now->ramp & NDS32_FIX)
   6068 	    {
   6069 	      /* Convert original relocation.  */
   6070 	      pattern_now->fixP->fx_r_type = fixup_now->r_type ;
   6071 	      fixup_size = 0;
   6072 	    }
   6073 	  else if ((fixup_now->ramp & NDS32_PTR) != 0)
   6074 	    {
   6075 	      /* This relocation has to point to another instruction.  Make
   6076 		 sure each resolved relocation has to be pointed.  */
   6077 	      pattern_temp = relocs_pattern;
   6078 	      /* All instruction in relax_table should be 32-bit.  */
   6079 	      hint_count = hint_info.relax_code_size / 4;
   6080 	      code_insn = CLEAN_REG (*(code_seq + hint_count - 1));
   6081 	      while (pattern_temp)
   6082 		{
   6083 		  /* Point to every resolved relocation.  */
   6084 		  if (nds32_match_hint_insn (pattern_temp->opcode, code_insn))
   6085 		    {
   6086 		      ptr_offset =
   6087 			pattern_temp->where - pattern_temp->frag->fr_literal;
   6088 		      exp.X_add_symbol = symbol_temp_new (now_seg,
   6089 							  pattern_temp->frag,
   6090 							  ptr_offset);
   6091 		      exp.X_add_number = 0;
   6092 		      fixP =
   6093 			fix_new_exp (fragP, where - fragP->fr_literal,
   6094 				     fixup_size, &exp, 0, fixup_now->r_type);
   6095 		      fixP->fx_addnumber = fixP->fx_offset;
   6096 		    }
   6097 		  pattern_temp = pattern_temp->next;
   6098 		}
   6099 	      fixup_size = 0;
   6100 	    }
   6101 	  else if (fixup_now->ramp & NDS32_ADDEND)
   6102 	    {
   6103 	      range = nds32_elf_sethi_range (relocs_pattern);
   6104 	      if (range == NDS32_LOADSTORE_NONE)
   6105 		{
   6106 		  as_bad (_("Internal error: Range error. %s"), now_seg->name);
   6107 		  return;
   6108 		}
   6109 	      exp.X_add_symbol = abs_section_sym;
   6110 	      exp.X_add_number = SET_ADDEND (4, 0, optimize, enable_16bit);
   6111 	      exp.X_add_number |= ((range & 0x3f) << 8);
   6112 	    }
   6113 	  else if ((fixup_now->ramp & NDS32_ABS) != 0)
   6114 	    {
   6115 	      /* This is a tag relocation.  */
   6116 	      exp.X_add_symbol = abs_section_sym;
   6117 	      exp.X_add_number = 0;
   6118 	    }
   6119 	  else if ((fixup_now->ramp & NDS32_INSN16) != 0)
   6120 	    {
   6121 	      if (!enable_16bit)
   6122 		fixup_size = 0;
   6123 	      /* This is a tag relocation.  */
   6124 	      exp.X_add_symbol = abs_section_sym;
   6125 	      exp.X_add_number = 0;
   6126 	    }
   6127 	  else if ((fixup_now->ramp & NDS32_SYM) != 0)
   6128 	    {
   6129 	      /* For EMPTY relocation save the true symbol.  */
   6130 	      exp.X_add_symbol = hi_sym;
   6131 	      exp.X_add_number = hi_branch_offset;
   6132 	    }
   6133 	  else if (NDS32_SYM_DESC_MEM & fixup_now->ramp)
   6134 	    {
   6135 	      /* Do the same as NDS32_SYM.  */
   6136 	      exp.X_add_symbol = hi_sym;
   6137 	      exp.X_add_number = hi_branch_offset;
   6138 
   6139 	      /* Extra to NDS32_SYM.  */
   6140 	      /* Detect if DESC_FUNC relax type do apply.  */
   6141 	      if ((REG_GP == N32_RA5 (pattern_now->insn))
   6142 		  || (REG_GP == N32_RB5 (pattern_now->insn)))
   6143 		{
   6144 		  fixP = fix_new_exp (fragP, where - fragP->fr_literal,
   6145 				      fixup_size, &exp, pcrel,
   6146 				      BFD_RELOC_NDS32_TLS_DESC_FUNC);
   6147 		  fixP->fx_addnumber = fixP->fx_offset;
   6148 
   6149 		  fixup_size = 0;
   6150 		}
   6151 	      /* Else do as usual.  */
   6152 	    }
   6153 	  else if (fixup_now->ramp & NDS32_PTR_PATTERN)
   6154 	    {
   6155 	      /* Find out PTR_RESOLVED code pattern.  */
   6156 	      nds32_relax_fixup_info_t *next_fixup = fixup_now + 1;
   6157 	      uint32_t resolved_pattern = 0;
   6158 	      while (next_fixup->offset)
   6159 		{
   6160 		  if (next_fixup->r_type == BFD_RELOC_NDS32_PTR_RESOLVED)
   6161 		    {
   6162 		      uint32_t new_pattern = code_seq[next_fixup->offset >> 2];
   6163 		      if (!resolved_pattern)
   6164 			resolved_pattern = new_pattern;
   6165 		      else if (new_pattern != resolved_pattern)
   6166 			{
   6167 			  as_warn (_("Multiple BFD_RELOC_NDS32_PTR_RESOLVED "
   6168 				     "patterns are not supported yet!"));
   6169 			  break;
   6170 			}
   6171 		    }
   6172 		  ++next_fixup;
   6173 		}
   6174 
   6175 	      /* Find matched code and insert fix-ups.  */
   6176 	      struct nds32_relocs_pattern *next_pattern = pattern_now->next;
   6177 	      /* This relocation has to point to another instruction.
   6178 		 Make sure each resolved relocation has to be pointed.  */
   6179 	      /* All instruction in relax_table should be 32-bit.  */
   6180 	      while (next_pattern)
   6181 		{
   6182 		  uint32_t cur_pattern = GET_OPCODE (next_pattern->opcode->value);
   6183 		  if (cur_pattern == resolved_pattern)
   6184 		    {
   6185 		      ptr_offset = next_pattern->where
   6186 			- next_pattern->frag->fr_literal;
   6187 		      exp.X_add_symbol = symbol_temp_new (now_seg,
   6188 							  next_pattern->frag,
   6189 							  ptr_offset);
   6190 		      exp.X_add_number = 0;
   6191 		      fixP = fix_new_exp (fragP, where - fragP->fr_literal,
   6192 					  fixup_size, &exp, 0,
   6193 					  fixup_now->r_type);
   6194 		      fixP->fx_addnumber = fixP->fx_offset;
   6195 		    }
   6196 		  next_pattern = next_pattern->next;
   6197 		}
   6198 
   6199 	      fixup_size = 0;
   6200 	    }
   6201 	  else if (fixup_now->ramp & NDS32_PTR_MULTIPLE)
   6202 	    {
   6203 	      /* Find each PTR_RESOLVED pattern after PTR.  */
   6204 	      nds32_relax_fixup_info_t *next_fixup = fixup_now + 1;
   6205 	      while (next_fixup->offset)
   6206 		{
   6207 		  if (next_fixup->r_type == BFD_RELOC_NDS32_PTR_RESOLVED)
   6208 		    {
   6209 		      uint32_t pattern = code_seq[next_fixup->offset >> 2];
   6210 		      /* Find matched code to insert fix-ups.  */
   6211 		      struct nds32_relocs_pattern *next_insn = pattern_now->next;
   6212 		      while (next_insn)
   6213 			{
   6214 			  uint32_t insn_pattern = GET_OPCODE (next_insn->opcode->value);
   6215 			  if (insn_pattern == pattern)
   6216 			    {
   6217 			      ptr_offset = next_insn->where
   6218 				- next_insn->frag->fr_literal;
   6219 			      exp.X_add_symbol = symbol_temp_new (now_seg,
   6220 								  next_insn->frag,
   6221 								  ptr_offset);
   6222 			      exp.X_add_number = 0;
   6223 			      fixP = fix_new_exp (fragP,
   6224 						  where - fragP->fr_literal,
   6225 						  fixup_size, &exp, 0,
   6226 						  fixup_now->r_type);
   6227 			      fixP->fx_addnumber = fixP->fx_offset;
   6228 			    }
   6229 			  next_insn = next_insn->next;
   6230 			}
   6231 		    }
   6232 		  ++next_fixup;
   6233 		}
   6234 	      fixup_size = 0;
   6235 	    }
   6236 	  else
   6237 	    {
   6238 	      exp.X_add_symbol = sym;
   6239 	      exp.X_add_number = branch_offset;
   6240 	    }
   6241 
   6242 	  if (fixup_size != 0)
   6243 	    {
   6244 	      fixP = fix_new_exp (fragP, where - fragP->fr_literal, fixup_size,
   6245 				  &exp, pcrel, fixup_now->r_type);
   6246 	      fixP->fx_addnumber = fixP->fx_offset;
   6247 	    }
   6248 	  fixup_now++;
   6249 	  fixup_size = fixup_now->size;
   6250 	}
   6251 
   6252 #ifdef NDS32_LINUX_TOOLCHAIN
   6253       /* Insert group relocation for each relax hint.  */
   6254       if (key)
   6255 	{
   6256 	  exp.X_add_symbol = hi_sym; /* for eyes only */
   6257 	  exp.X_add_number = group_id;
   6258 	  fixP = fix_new_exp (fragP, where - fragP->fr_literal, fixup_size,
   6259 			      &exp, pcrel, BFD_RELOC_NDS32_GROUP);
   6260 	  fixP->fx_addnumber = fixP->fx_offset;
   6261 	}
   6262 #endif
   6263 
   6264       if (count < relax_code_size / 4)
   6265 	count++;
   6266       pattern_now = pattern_now->next;
   6267     }
   6268 
   6269  restore:
   6270   now_seg = seg_bak;
   6271   frchain_now = frchain_bak;
   6272 }
   6273 
   6274 static int
   6275 nds32_elf_append_relax_relocs_traverse (void **slot, void *arg ATTRIBUTE_UNUSED)
   6276 {
   6277   string_tuple_t *tuple = *((string_tuple_t **) slot);
   6278   nds32_elf_append_relax_relocs (tuple->key, tuple->value);
   6279   return 1;
   6280 }
   6281 
   6282 
   6283 static void
   6284 nds32_str_tolower (const char *src, char *dest)
   6285 {
   6286   unsigned int i, len;
   6287 
   6288   len = strlen (src);
   6289 
   6290   for (i = 0; i < len; i++)
   6291     *(dest + i) = TOLOWER (*(src + i));
   6292 
   6293   *(dest + i) = '\0';
   6294 }
   6295 
   6296 /* Check instruction if it can be used for the baseline.  */
   6297 
   6298 static bool
   6299 nds32_check_insn_available (struct nds32_asm_insn insn, const char *str)
   6300 {
   6301   int attr = insn.attr & ATTR_ALL;
   6302   static int baseline_isa = 0;
   6303   char *s;
   6304 
   6305   s = xmalloc (strlen (str) + 1);
   6306   nds32_str_tolower (str, s);
   6307   if (verbatim
   6308       && (((insn.opcode->value == ALU2 (MTUSR)
   6309 	    || insn.opcode->value == ALU2 (MFUSR))
   6310 	   && (strstr (s, "lc")
   6311 	       || strstr (s, "le")
   6312 	       || strstr (s, "lb")))
   6313 	  || (insn.attr & NASM_ATTR_ZOL)))
   6314     {
   6315       as_bad (_("Not support instruction %s in verbatim."), str);
   6316       return false;
   6317     }
   6318   free (s);
   6319 
   6320   if (!enable_16bit && insn.opcode->isize == 2)
   6321     {
   6322       as_bad (_("16-bit instruction is disabled: %s."), str);
   6323       return false;
   6324     }
   6325 
   6326   /* No isa setting or all isa can use.  */
   6327   if (attr == 0 || attr == ATTR_ALL)
   6328     return true;
   6329 
   6330   if (baseline_isa == 0)
   6331     {
   6332       /* Map option baseline and instruction attribute.  */
   6333       switch (nds32_baseline)
   6334 	{
   6335 	case ISA_V2:
   6336 	  baseline_isa = ATTR (ISA_V2);
   6337 	  break;
   6338 	case ISA_V3:
   6339 	  baseline_isa = ATTR (ISA_V3);
   6340 	  break;
   6341 	case ISA_V3M:
   6342 	  baseline_isa = ATTR (ISA_V3M);
   6343 	  break;
   6344 	}
   6345     }
   6346 
   6347   if  ((baseline_isa & attr) == 0)
   6348     {
   6349       as_bad (_("Instruction %s not supported in the baseline."), str);
   6350       return false;
   6351     }
   6352   return true;
   6353 }
   6354 
   6355 /* Stub of machine dependent.  */
   6356 
   6357 void
   6358 md_assemble (char *str)
   6359 {
   6360   struct nds32_asm_insn insn;
   6361   char *out;
   6362   struct nds32_pseudo_opcode *popcode;
   6363   const struct nds32_field *fld = NULL;
   6364   fixS *fixP;
   6365   uint16_t insn_16;
   6366   struct nds32_relocs_pattern *relocs_temp;
   6367   struct nds32_relocs_group *group_temp;
   6368   fragS *fragP;
   6369   int label = label_exist;
   6370   static bool pseudo_hint = false;
   6371 
   6372   popcode = nds32_lookup_pseudo_opcode (str);
   6373   /* Note that we need to check 'verbatim' and
   6374      'opcode->physical_op'.  If the assembly content is generated by
   6375      compiler and this opcode is a physical instruction, there is no
   6376      need to perform pseudo instruction expansion/transformation.  */
   6377   if (popcode && !(verbatim && popcode->physical_op))
   6378     {
   6379       /* Pseudo instruction is with relax_hint.  */
   6380       if (relaxing)
   6381 	pseudo_hint = true;
   6382       pseudo_opcode = true;
   6383       nds32_pseudo_opcode_wrapper (str, popcode);
   6384       pseudo_opcode = false;
   6385       pseudo_hint = false;
   6386       nds32_elf_append_relax_relocs (NULL, relocs_list);
   6387 
   6388       /* Free relax_hint group list.  */
   6389       while (nds32_relax_hint_current)
   6390 	{
   6391 	  group_temp = nds32_relax_hint_current->next;
   6392 	  free (nds32_relax_hint_current);
   6393 	  nds32_relax_hint_current = group_temp;
   6394 	}
   6395 
   6396       /* Free pseudo list.  */
   6397       relocs_temp = relocs_list;
   6398       while (relocs_temp)
   6399 	{
   6400 	  relocs_list = relocs_list->next;
   6401 	  free (relocs_temp);
   6402 	  relocs_temp = relocs_list;
   6403 	}
   6404 
   6405       return;
   6406     }
   6407 
   6408   label_exist = 0;
   6409   insn.info = XNEW (expressionS);
   6410   asm_desc.result = NASM_OK;
   6411   nds32_assemble (&asm_desc, &insn, str);
   6412 
   6413   switch (asm_desc.result)
   6414     {
   6415     case NASM_ERR_UNKNOWN_OP:
   6416       as_bad (_("Unrecognized opcode, %s."), str);
   6417       return;
   6418     case NASM_ERR_SYNTAX:
   6419       as_bad (_("Incorrect syntax, %s."), str);
   6420       return;
   6421     case NASM_ERR_OPERAND:
   6422       as_bad (_("Unrecognized operand/register, %s."), str);
   6423       return;
   6424     case NASM_ERR_OUT_OF_RANGE:
   6425       as_bad (_("Operand out of range, %s."), str);
   6426       return;
   6427     case NASM_ERR_REG_REDUCED:
   6428       as_bad (_("Prohibited register used for reduced-register, %s."), str);
   6429       return;
   6430     case NASM_ERR_JUNK_EOL:
   6431       as_bad (_("Junk at end of line, %s."), str);
   6432       return;
   6433     }
   6434 
   6435   gas_assert (insn.opcode);
   6436 
   6437   nds32_set_elf_flags_by_insn (&insn);
   6438 
   6439   gas_assert (insn.opcode->isize == 4 || insn.opcode->isize == 2);
   6440 
   6441   if (!nds32_check_insn_available (insn, str))
   6442     return;
   6443 
   6444   /* Make sure the beginning of text being 2-byte align.  */
   6445   nds32_adjust_label (1);
   6446   add_mapping_symbol (MAP_CODE, 0, 0);
   6447   fld = insn.field;
   6448   /* Try to allocate the max size to guarantee relaxable same branch
   6449      instructions in the same fragment.  */
   6450   frag_grow (NDS32_MAXCHAR);
   6451   fragP = frag_now;
   6452 
   6453   if (fld && (insn.attr & NASM_ATTR_BRANCH)
   6454       && (pseudo_opcode || (insn.opcode->value != INSN_JAL
   6455 			    && insn.opcode->value != INSN_J))
   6456       && (!verbatim || pseudo_opcode))
   6457     {
   6458       /* User assembly code branch relax for it.  */
   6459       /* If fld is not NULL, it is a symbol.  */
   6460       /* Branch must relax to proper pattern in user assembly code exclude
   6461 	 J and JAL.  Keep these two in original type for users which wants
   6462 	 to keep their size be fixed.  In general, assembler does not convert
   6463 	 instruction generated by compiler.  But jump instruction may be
   6464 	 truncated in text virtual model.  For workaround, compiler generate
   6465 	 pseudo jump to fix this issue currently.  */
   6466 
   6467       /* Get branch range type.  */
   6468       dwarf2_emit_insn (0);
   6469       enum nds32_br_range range_type;
   6470       expressionS *pexp = insn.info;
   6471 
   6472       range_type = get_range_type (fld);
   6473 
   6474       out = frag_var (rs_machine_dependent, NDS32_MAXCHAR,
   6475 		      0, /* VAR is un-used.  */
   6476 		      range_type, /* SUBTYPE is used as range type.  */
   6477 		      pexp->X_add_symbol, pexp->X_add_number, 0);
   6478 
   6479       fragP->fr_fix += insn.opcode->isize;
   6480       fragP->tc_frag_data.opcode = insn.opcode;
   6481       fragP->tc_frag_data.insn = insn.insn;
   6482       if (insn.opcode->isize == 4)
   6483 	bfd_putb32 (insn.insn, out);
   6484       else if (insn.opcode->isize == 2)
   6485 	bfd_putb16 (insn.insn, out);
   6486       fragP->tc_frag_data.flag |= NDS32_FRAG_BRANCH;
   6487 
   6488       free (insn.info);
   6489       return;
   6490       /* md_convert_frag will insert relocations.  */
   6491     }
   6492   else if (!relaxing && enable_16bit && (optimize || optimize_for_space)
   6493 	   && ((!fld && !verbatim && insn.opcode->isize == 4
   6494 		&& nds32_convert_32_to_16 (stdoutput, insn.insn, &insn_16, NULL))
   6495 	       || (insn.opcode->isize == 2
   6496 		   && nds32_convert_16_to_32 (stdoutput, insn.insn, NULL))))
   6497     {
   6498       /* Record this one is relaxable.  */
   6499       expressionS *pexp = insn.info;
   6500       dwarf2_emit_insn (0);
   6501       if (fld)
   6502 	{
   6503 	  out = frag_var (rs_machine_dependent,
   6504 			  4, /* Max size is 32-bit instruction.  */
   6505 			  0, /* VAR is un-used.  */
   6506 			  0, pexp->X_add_symbol, pexp->X_add_number, 0);
   6507 	  fragP->tc_frag_data.flag |= NDS32_FRAG_RELAXABLE_BRANCH;
   6508 	}
   6509       else
   6510 	out = frag_var (rs_machine_dependent,
   6511 			4, /* Max size is 32-bit instruction.  */
   6512 			0, /* VAR is un-used.  */
   6513 			0, NULL, 0, NULL);
   6514       fragP->tc_frag_data.flag |= NDS32_FRAG_RELAXABLE;
   6515       fragP->tc_frag_data.opcode = insn.opcode;
   6516       fragP->tc_frag_data.insn = insn.insn;
   6517       fragP->fr_fix += 2;
   6518 
   6519       /* In original, we don't relax the instruction with label on it,
   6520 	 but this may cause some redundant nop16.  Therefore, tag this
   6521 	 relaxable instruction and relax it carefully.  */
   6522       if (label)
   6523 	fragP->tc_frag_data.flag |= NDS32_FRAG_LABEL;
   6524 
   6525       if (insn.opcode->isize == 4)
   6526 	bfd_putb16 (insn_16, out);
   6527       else if (insn.opcode->isize == 2)
   6528 	bfd_putb16 (insn.insn, out);
   6529 
   6530       free (insn.info);
   6531       return;
   6532     }
   6533   else if ((verbatim || !relaxing) && optimize && label)
   6534     {
   6535       /* This instruction is with label.  */
   6536       expressionS exp;
   6537       out = frag_var (rs_machine_dependent, insn.opcode->isize,
   6538 		      0, 0, NULL, 0, NULL);
   6539       /* If this instruction is branch target, it is not relaxable.  */
   6540       fragP->tc_frag_data.flag = NDS32_FRAG_LABEL;
   6541       fragP->tc_frag_data.opcode = insn.opcode;
   6542       fragP->tc_frag_data.insn = insn.insn;
   6543       fragP->fr_fix += insn.opcode->isize;
   6544       if (insn.opcode->isize == 4)
   6545 	{
   6546 	  exp.X_op = O_symbol;
   6547 	  exp.X_add_symbol = abs_section_sym;
   6548 	  exp.X_add_number = 0;
   6549 	  fixP = fix_new_exp (fragP, fragP->fr_fix - 4, 0, &exp,
   6550 			      0, BFD_RELOC_NDS32_LABEL);
   6551 	  if (!verbatim)
   6552 	    fragP->tc_frag_data.flag = NDS32_FRAG_ALIGN;
   6553 	}
   6554     }
   6555   else
   6556     out = frag_more (insn.opcode->isize);
   6557 
   6558   if (insn.opcode->isize == 4)
   6559     bfd_putb32 (insn.insn, out);
   6560   else if (insn.opcode->isize == 2)
   6561     bfd_putb16 (insn.insn, out);
   6562 
   6563   dwarf2_emit_insn (insn.opcode->isize);
   6564 
   6565   /* Compiler generating code and user assembly pseudo load-store, insert
   6566      fixup here.  */
   6567   expressionS *pexp = insn.info;
   6568   fixP = nds32_elf_record_fixup_exp (fragP, str, fld, pexp, out, &insn);
   6569   /* Build relaxation pattern when relaxing is enable.  */
   6570   if (relaxing)
   6571     nds32_elf_build_relax_relation (fixP, pexp, out, &insn, fragP, fld,
   6572 				    pseudo_hint);
   6573 
   6574   free (insn.info);
   6575 }
   6576 
   6577 /* md_macro_start  */
   6578 
   6579 void
   6580 nds32_macro_start (void)
   6581 {
   6582 }
   6583 
   6584 /* md_macro_info  */
   6585 
   6586 void
   6587 nds32_macro_info (void *info ATTRIBUTE_UNUSED)
   6588 {
   6589 }
   6590 
   6591 /* md_macro_end  */
   6592 
   6593 void
   6594 nds32_macro_end (void)
   6595 {
   6596 }
   6597 
   6598 /* GAS will call this function with one argument, an expressionS pointer, for
   6599    any expression that can not be recognized.  When the function is called,
   6600    input_line_pointer will point to the start of the expression.  */
   6601 
   6602 void
   6603 md_operand (expressionS *expressionP)
   6604 {
   6605   if (*input_line_pointer == '#')
   6606     {
   6607       input_line_pointer++;
   6608       expression (expressionP);
   6609     }
   6610 }
   6611 
   6612 /* GAS will call this function for each section at the end of the assembly, to
   6613    permit the CPU back end to adjust the alignment of a section.  The function
   6614    must take two arguments, a segT for the section and a valueT for the size of
   6615    the section, and return a valueT for the rounded size.  */
   6616 
   6617 valueT
   6618 md_section_align (segT segment, valueT size)
   6619 {
   6620   int align = bfd_section_alignment (segment);
   6621 
   6622   return ((size + (1 << align) - 1) & ((valueT) -1 << align));
   6623 }
   6624 
   6625 /* GAS will call this function when a symbol table lookup fails, before it
   6626    creates a new symbol.  Typically this would be used to supply symbols whose
   6627    name or value changes dynamically, possibly in a context sensitive way.
   6628    Predefined symbols with fixed values, such as register names or condition
   6629    codes, are typically entered directly into the symbol table when md_begin
   6630    is called.  One argument is passed, a char * for the symbol.  */
   6631 
   6632 symbolS *
   6633 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
   6634 {
   6635   return NULL;
   6636 }
   6637 
   6638 static long
   6639 nds32_calc_branch_offset (segT segment, fragS *fragP,
   6640 			  long stretch ATTRIBUTE_UNUSED,
   6641 			  relax_info_t *relax_info,
   6642 			  enum nds32_br_range branch_range_type)
   6643 {
   6644   struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
   6645   symbolS *branch_symbol = fragP->fr_symbol;
   6646   offsetT branch_offset = fragP->fr_offset;
   6647   offsetT branch_target_address;
   6648   offsetT branch_insn_address;
   6649   long offset = 0;
   6650 
   6651   if ((S_GET_SEGMENT (branch_symbol) != segment)
   6652       || S_IS_WEAK (branch_symbol))
   6653     {
   6654       /* The symbol is not in the SEGMENT.  It could be far far away.  */
   6655       offset = 0x80000000;
   6656     }
   6657   else
   6658     {
   6659       /* Calculate symbol-to-instruction offset.  */
   6660       branch_target_address = S_GET_VALUE (branch_symbol) + branch_offset;
   6661       /* If the destination symbol is beyond current frag address,
   6662 	 STRETCH will take effect to symbol's position.  */
   6663       if (S_GET_VALUE (branch_symbol) > fragP->fr_address)
   6664 	branch_target_address += stretch;
   6665 
   6666       branch_insn_address = fragP->fr_address + fragP->fr_fix;
   6667       branch_insn_address -= opcode->isize;
   6668 
   6669       /* Update BRANCH_INSN_ADDRESS to relaxed position.  */
   6670       branch_insn_address += (relax_info->relax_code_size[branch_range_type]
   6671 			      - relax_info->relax_branch_isize[branch_range_type]);
   6672 
   6673       offset = branch_target_address - branch_insn_address;
   6674     }
   6675 
   6676   return offset;
   6677 }
   6678 
   6679 static enum nds32_br_range
   6680 nds32_convert_to_range_type (long offset)
   6681 {
   6682   enum nds32_br_range range_type;
   6683 
   6684   if (-(0x100) <= offset && offset < 0x100) /* 256 bytes */
   6685     range_type = BR_RANGE_S256;
   6686   else if (-(0x4000) <= offset && offset < 0x4000) /* 16K bytes */
   6687     range_type = BR_RANGE_S16K;
   6688   else if (-(0x10000) <= offset && offset < 0x10000) /* 64K bytes */
   6689     range_type = BR_RANGE_S64K;
   6690   else if (-(0x1000000) <= offset && offset < 0x1000000) /* 16M bytes */
   6691     range_type = BR_RANGE_S16M;
   6692   else /* 4G bytes */
   6693     range_type = BR_RANGE_U4G;
   6694 
   6695   return range_type;
   6696 }
   6697 
   6698 /* Set instruction register mask.  */
   6699 
   6700 static void
   6701 nds32_elf_get_set_cond (relax_info_t *relax_info, int offset, uint32_t *insn,
   6702 			uint32_t ori_insn, int range)
   6703 {
   6704   nds32_cond_field_t *cond_fields = relax_info->cond_field;
   6705   nds32_cond_field_t *code_seq_cond = relax_info->relax_code_condition[range];
   6706   uint32_t mask;
   6707   int i = 0;
   6708 
   6709   /* The instruction has conditions.  Collect condition values.  */
   6710   while (code_seq_cond[i].bitmask != 0)
   6711     {
   6712       if (offset == code_seq_cond[i].offset)
   6713 	{
   6714 	  mask = (ori_insn >> cond_fields[i].bitpos) & cond_fields[i].bitmask;
   6715 	  /* Sign extend.  */
   6716 	  if (cond_fields[i].signed_extend)
   6717 	    mask = (mask ^ ((cond_fields[i].bitmask + 1) >> 1)) -
   6718 	      ((cond_fields[i].bitmask + 1) >> 1);
   6719 	  *insn |= (mask & code_seq_cond[i].bitmask) << code_seq_cond[i].bitpos;
   6720 	}
   6721       i++;
   6722     }
   6723 }
   6724 
   6725 static int
   6726 nds32_relax_branch_instructions (segT segment, fragS *fragP,
   6727 				 long stretch ATTRIBUTE_UNUSED,
   6728 				 int init)
   6729 {
   6730   enum nds32_br_range branch_range_type;
   6731   struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
   6732   long offset = 0;
   6733   enum nds32_br_range real_range_type;
   6734   int adjust = 0;
   6735   relax_info_t *relax_info;
   6736   int diff = 0;
   6737   int i, j, k;
   6738   int code_seq_size;
   6739   uint32_t *code_seq;
   6740   uint32_t insn;
   6741   int insn_size;
   6742   int code_seq_offset;
   6743 
   6744   /* Replace with gas_assert (fragP->fr_symbol != NULL); */
   6745   if (fragP->fr_symbol == NULL)
   6746     return adjust;
   6747 
   6748   /* If frag_var is not enough room, the previous frag is fr_full and with
   6749      opcode.  The new one is rs_dependent but without opcode.  */
   6750   if (opcode == NULL)
   6751     return adjust;
   6752 
   6753   /* Use U4G mode for b and bal in verbatim mode because lto may combine
   6754      functions into a file.  And order the file in the last when linking.
   6755      Once there is multiple definition, the same function will be kicked.
   6756      This may cause relocation truncated error.  */
   6757   if (verbatim && !nds32_pic
   6758       && (strcmp (opcode->opcode, "j") == 0
   6759 	  || strcmp (opcode->opcode, "jal") == 0))
   6760     {
   6761       fragP->fr_subtype = BR_RANGE_U4G;
   6762       if (init)
   6763 	return 8;
   6764       else
   6765 	return 0;
   6766     }
   6767 
   6768   relax_info = str_hash_find (nds32_relax_info_hash, opcode->opcode);
   6769 
   6770   if (relax_info == NULL)
   6771     return adjust;
   6772 
   6773   if (init)
   6774     {
   6775       branch_range_type = relax_info->br_range;
   6776       i = BR_RANGE_S256;
   6777     }
   6778   else
   6779     {
   6780       branch_range_type = fragP->fr_subtype;
   6781       i = branch_range_type;
   6782     }
   6783 
   6784   offset = nds32_calc_branch_offset (segment, fragP, stretch,
   6785 				     relax_info, branch_range_type);
   6786 
   6787   real_range_type = nds32_convert_to_range_type (offset);
   6788 
   6789   /* If actual range is equal to instruction jump range, do nothing.  */
   6790   if (real_range_type == branch_range_type)
   6791     {
   6792       fragP->fr_subtype = real_range_type;
   6793       return adjust;
   6794     }
   6795 
   6796   /* Find out proper relaxation code sequence.  */
   6797   for (; i < BR_RANGE_NUM; i++)
   6798     {
   6799       if (real_range_type <= (unsigned int) i)
   6800 	{
   6801 	  if (init)
   6802 	    diff = relax_info->relax_code_size[i] - opcode->isize;
   6803 	  else if (real_range_type < (unsigned int) i)
   6804 	    diff = relax_info->relax_code_size[real_range_type]
   6805 	      - relax_info->relax_code_size[branch_range_type];
   6806 	  else
   6807 	    diff = relax_info->relax_code_size[i]
   6808 	      - relax_info->relax_code_size[branch_range_type];
   6809 
   6810 	  /* If the instruction could be converted to 16-bits,
   6811 	     minus the difference.  */
   6812 	  code_seq_offset = 0;
   6813 	  j = 0;
   6814 	  k = 0;
   6815 	  code_seq_size = relax_info->relax_code_size[i];
   6816 	  code_seq = relax_info->relax_code_seq[i];
   6817 	  while (code_seq_offset < code_seq_size)
   6818 	    {
   6819 	      insn = code_seq[j];
   6820 	      if (insn & 0x80000000) /* 16-bits instruction.  */
   6821 		{
   6822 		  insn_size = 2;
   6823 		}
   6824 	      else /* 32-bits instruction.  */
   6825 		{
   6826 		  insn_size = 4;
   6827 
   6828 		  while (relax_info->relax_fixup[i][k].size !=0
   6829 			 && relax_info->relax_fixup[i][k].offset < code_seq_offset)
   6830 		    k++;
   6831 		}
   6832 
   6833 	      code_seq_offset += insn_size;
   6834 	      j++;
   6835 	    }
   6836 
   6837 	  /* Update fr_subtype to new NDS32_BR_RANGE.  */
   6838 	  fragP->fr_subtype = real_range_type;
   6839 	  break;
   6840 	}
   6841     }
   6842 
   6843   return diff + adjust;
   6844 }
   6845 
   6846 /* Adjust relaxable frag till current frag.  */
   6847 
   6848 static int
   6849 nds32_adjust_relaxable_frag (fragS *startP, fragS *fragP)
   6850 {
   6851   int adj;
   6852   if (startP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
   6853     adj = -2;
   6854   else
   6855     adj = 2;
   6856 
   6857   startP->tc_frag_data.flag ^= NDS32_FRAG_RELAXED;
   6858 
   6859   while (startP)
   6860     {
   6861       startP = startP->fr_next;
   6862       if (startP)
   6863 	{
   6864 	  startP->fr_address += adj;
   6865 	  if (startP == fragP)
   6866 	    break;
   6867 	}
   6868     }
   6869   return adj;
   6870 }
   6871 
   6872 static addressT
   6873 nds32_get_align (addressT address, int align)
   6874 {
   6875   addressT mask, new_address;
   6876 
   6877   mask = ~((addressT) (~0) << align);
   6878   new_address = (address + mask) & (~mask);
   6879   return (new_address - address);
   6880 }
   6881 
   6882 /* Check the prev_frag is legal.  */
   6883 static void
   6884 invalid_prev_frag (fragS * fragP, fragS **prev_frag, bool relax)
   6885 {
   6886   addressT address;
   6887   fragS *frag_start = *prev_frag;
   6888 
   6889   if (!frag_start || !relax)
   6890     return;
   6891 
   6892   if (frag_start->last_fr_address >= fragP->last_fr_address)
   6893     {
   6894       *prev_frag = NULL;
   6895       return;
   6896     }
   6897 
   6898   fragS *frag_t = *prev_frag;
   6899   while (frag_t != fragP)
   6900     {
   6901       if (frag_t->fr_type == rs_align
   6902 	  || frag_t->fr_type == rs_align_code
   6903 	  || frag_t->fr_type == rs_align_test)
   6904 	{
   6905 	  /* Relax instruction can not walk across label.  */
   6906 	  if (frag_t->tc_frag_data.flag & NDS32_FRAG_LABEL)
   6907 	    {
   6908 	      prev_frag = NULL;
   6909 	      return;
   6910 	    }
   6911 	  /* Relax previous relaxable to align rs_align frag.  */
   6912 	  address = frag_t->fr_address + frag_t->fr_fix;
   6913 	  addressT offset = nds32_get_align (address, (int) frag_t->fr_offset);
   6914 	  if (offset & 0x2)
   6915 	    {
   6916 	      /* If there is label on the prev_frag, check if it is aligned.  */
   6917 	      if (!((*prev_frag)->tc_frag_data.flag & NDS32_FRAG_LABEL)
   6918 		  || (((*prev_frag)->fr_address + (*prev_frag)->fr_fix  - 2 )
   6919 		      & 0x2) == 0)
   6920 		nds32_adjust_relaxable_frag (*prev_frag, frag_t);
   6921 	    }
   6922 	  *prev_frag = NULL;
   6923 	  return;
   6924 	}
   6925       frag_t = frag_t->fr_next;
   6926     }
   6927 
   6928   if (fragP->tc_frag_data.flag & NDS32_FRAG_ALIGN)
   6929     {
   6930       address = fragP->fr_address;
   6931       addressT offset = nds32_get_align (address, 2);
   6932       if (offset & 0x2)
   6933 	{
   6934 	  /* If there is label on the prev_frag, check if it is aligned.  */
   6935 	  if (!((*prev_frag)->tc_frag_data.flag & NDS32_FRAG_LABEL)
   6936 	      || (((*prev_frag)->fr_address + (*prev_frag)->fr_fix  - 2 )
   6937 		  & 0x2) == 0)
   6938 	    nds32_adjust_relaxable_frag (*prev_frag, fragP);
   6939 	}
   6940       *prev_frag = NULL;
   6941       return;
   6942     }
   6943 }
   6944 
   6945 /* md_relax_frag  */
   6946 
   6947 int
   6948 nds32_relax_frag (segT segment, fragS *fragP, long stretch ATTRIBUTE_UNUSED)
   6949 {
   6950   /* Currently, there are two kinds of relaxation in nds32 assembler.
   6951      1. relax for branch
   6952      2. relax for 32-bits to 16-bits  */
   6953 
   6954   static fragS *prev_frag = NULL;
   6955   int adjust = 0;
   6956 
   6957   invalid_prev_frag (fragP, &prev_frag, true);
   6958 
   6959   if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
   6960     adjust = nds32_relax_branch_instructions (segment, fragP, stretch, 0);
   6961   if (fragP->tc_frag_data.flag & NDS32_FRAG_LABEL)
   6962     prev_frag = NULL;
   6963   if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE
   6964       && (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED) == 0)
   6965     /* Here is considered relaxed case originally.  But it may cause
   6966        an endless loop when relaxing.  Once the instruction is relaxed,
   6967        it can not be undone.  */
   6968     prev_frag = fragP;
   6969 
   6970   return adjust;
   6971 }
   6972 
   6973 /* This function returns an initial guess of the length by which a fragment
   6974    must grow to hold a branch to reach its destination.  Also updates
   6975    fr_type/fr_subtype as necessary.
   6976 
   6977    It is called just before doing relaxation.  Any symbol that is now undefined
   6978    will not become defined.  The guess for fr_var is ACTUALLY the growth beyond
   6979    fr_fix.  Whatever we do to grow fr_fix or fr_var contributes to our returned
   6980    value.  Although it may not be explicit in the frag, pretend fr_var starts
   6981    with a 0 value.  */
   6982 
   6983 int
   6984 md_estimate_size_before_relax (fragS *fragP, segT segment)
   6985 {
   6986   /* Currently, there are two kinds of relaxation in nds32 assembler.
   6987      1. relax for branch
   6988      2. relax for 32-bits to 16-bits  */
   6989 
   6990   /* Save previous relaxable frag.  */
   6991   static fragS *prev_frag = NULL;
   6992   int adjust = 0;
   6993 
   6994   invalid_prev_frag (fragP, &prev_frag, false);
   6995 
   6996   if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
   6997     adjust = nds32_relax_branch_instructions (segment, fragP, 0, 1);
   6998   if (fragP->tc_frag_data.flag & NDS32_FRAG_LABEL)
   6999     prev_frag = NULL;
   7000   if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
   7001     adjust = 2;
   7002   else if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE)
   7003     prev_frag = fragP;
   7004 
   7005   return adjust;
   7006 }
   7007 
   7008 /* GAS will call this for each rs_machine_dependent fragment.  The instruction
   7009    is completed using the data from the relaxation pass.  It may also create any
   7010    necessary relocations.
   7011 
   7012    *FRAGP has been relaxed to its final size, and now needs to have the bytes
   7013    inside it modified to conform to the new size.  It is called after relaxation
   7014    is finished.
   7015 
   7016    fragP->fr_type == rs_machine_dependent.
   7017    fragP->fr_subtype is the subtype of what the address relaxed to.  */
   7018 
   7019 void
   7020 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP)
   7021 {
   7022   /* Convert branch relaxation instructions.  */
   7023   symbolS *branch_symbol = fragP->fr_symbol;
   7024   offsetT branch_offset = fragP->fr_offset;
   7025   enum nds32_br_range branch_range_type = fragP->fr_subtype;
   7026   struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
   7027   uint32_t origin_insn = fragP->tc_frag_data.insn;
   7028   relax_info_t *relax_info;
   7029   char *fr_buffer;
   7030   int fr_where;
   7031   int addend ATTRIBUTE_UNUSED;
   7032   offsetT branch_target_address, branch_insn_address;
   7033   expressionS exp;
   7034   fixS *fixP;
   7035   uint32_t *code_seq;
   7036   uint32_t insn;
   7037   int code_size, insn_size, offset, fixup_size;
   7038   int buf_offset, pcrel;
   7039   int i, k;
   7040   uint16_t insn_16;
   7041   nds32_relax_fixup_info_t fixup_info[MAX_RELAX_FIX];
   7042   /* Save the 1st instruction is converted to 16 bit or not.  */
   7043   unsigned int branch_size;
   7044   enum bfd_reloc_code_real final_r_type;
   7045 
   7046   /* Replace with gas_assert (branch_symbol != NULL); */
   7047   if (branch_symbol == NULL && !(fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED))
   7048     return;
   7049 
   7050   /* If frag_var is not enough room, the previous frag is fr_full and with
   7051      opcode.  The new one is rs_dependent but without opcode.  */
   7052   if (opcode == NULL)
   7053     return;
   7054 
   7055   if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE_BRANCH)
   7056     {
   7057       relax_info = str_hash_find (nds32_relax_info_hash, opcode->opcode);
   7058 
   7059       if (relax_info == NULL)
   7060 	return;
   7061 
   7062       i = BR_RANGE_S256;
   7063       while (i < BR_RANGE_NUM
   7064 	     && relax_info->relax_code_size[i]
   7065 	     != (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED ? 4 : 2))
   7066 	i++;
   7067 
   7068       if (i >= BR_RANGE_NUM)
   7069 	as_bad ("Internal error: Cannot find relocation of"
   7070 		"relaxable branch.");
   7071 
   7072       exp.X_op = O_symbol;
   7073       exp.X_add_symbol = branch_symbol;
   7074       exp.X_add_number = branch_offset;
   7075       pcrel = ((relax_info->relax_fixup[i][0].ramp & NDS32_PCREL) != 0) ? 1 : 0;
   7076       fr_where = fragP->fr_fix - 2;
   7077       fixP = fix_new_exp (fragP, fr_where, relax_info->relax_fixup[i][0].size,
   7078 			  &exp, pcrel, relax_info->relax_fixup[i][0].r_type);
   7079       fixP->fx_addnumber = fixP->fx_offset;
   7080 
   7081       if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
   7082 	{
   7083 	  insn_16 = fragP->tc_frag_data.insn;
   7084 	  nds32_convert_16_to_32 (stdoutput, insn_16, &insn);
   7085 	  fr_buffer = fragP->fr_literal + fr_where;
   7086 	  fragP->fr_fix += 2;
   7087 	  exp.X_op = O_symbol;
   7088 	  exp.X_add_symbol = abs_section_sym;
   7089 	  exp.X_add_number = 0;
   7090 	  fix_new_exp (fragP, fr_where, 4,
   7091 		       &exp, 0, BFD_RELOC_NDS32_INSN16);
   7092 	  number_to_chars_bigendian (fr_buffer, insn, 4);
   7093 	}
   7094     }
   7095   else if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
   7096     {
   7097       if (fragP->tc_frag_data.opcode->isize == 2)
   7098 	{
   7099 	  insn_16 = fragP->tc_frag_data.insn;
   7100 	  nds32_convert_16_to_32 (stdoutput, insn_16, &insn);
   7101 	}
   7102       else
   7103 	insn = fragP->tc_frag_data.insn;
   7104       fragP->fr_fix += 2;
   7105       fr_where = fragP->fr_fix - 4;
   7106       fr_buffer = fragP->fr_literal + fr_where;
   7107       exp.X_op = O_symbol;
   7108       exp.X_add_symbol = abs_section_sym;
   7109       exp.X_add_number = 0;
   7110       fix_new_exp (fragP, fr_where, 4, &exp, 0,
   7111 		   BFD_RELOC_NDS32_INSN16);
   7112       number_to_chars_bigendian (fr_buffer, insn, 4);
   7113     }
   7114   else if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
   7115     {
   7116       /* Branch instruction adjust and append relocations.  */
   7117       relax_info = str_hash_find (nds32_relax_info_hash, opcode->opcode);
   7118 
   7119       if (relax_info == NULL)
   7120 	return;
   7121 
   7122       fr_where = fragP->fr_fix - opcode->isize;
   7123       fr_buffer = fragP->fr_literal + fr_where;
   7124 
   7125       if ((S_GET_SEGMENT (branch_symbol) != sec)
   7126 	  || S_IS_WEAK (branch_symbol))
   7127 	{
   7128 	  if (fragP->fr_offset & 3)
   7129 	    as_warn (_("Addend to unresolved symbol is not on word boundary."));
   7130 	  addend = 0;
   7131 	}
   7132       else
   7133 	{
   7134 	  /* Calculate symbol-to-instruction offset.  */
   7135 	  branch_target_address = S_GET_VALUE (branch_symbol) + branch_offset;
   7136 	  branch_insn_address = fragP->fr_address + fr_where;
   7137 	  addend = (branch_target_address - branch_insn_address) >> 1;
   7138 	}
   7139 
   7140       code_size = relax_info->relax_code_size[branch_range_type];
   7141       code_seq = relax_info->relax_code_seq[branch_range_type];
   7142 
   7143       memcpy (fixup_info, relax_info->relax_fixup[branch_range_type],
   7144 	      sizeof (fixup_info));
   7145 
   7146       /* Fill in frag.  */
   7147       i = 0;
   7148       k = 0;
   7149       offset = 0; /* code_seq offset */
   7150       buf_offset = 0; /* fr_buffer offset */
   7151       while (offset < code_size)
   7152 	{
   7153 	  insn = code_seq[i];
   7154 	  if (insn & 0x80000000) /* 16-bits instruction.  */
   7155 	    {
   7156 	      insn = (insn >> 16) & 0xFFFF;
   7157 	      insn_size = 2;
   7158 	    }
   7159 	  else /* 32-bits instruction.  */
   7160 	    {
   7161 	      insn_size = 4;
   7162 	    }
   7163 
   7164 	  nds32_elf_get_set_cond (relax_info, offset, &insn,
   7165 				  origin_insn, branch_range_type);
   7166 
   7167 	  /* Try to convert to 16-bits instruction.  Currently, only the first
   7168 	     instruction in pattern can be converted.  EX: bnez sethi ori jr,
   7169 	     only bnez can be converted to 16 bit and ori can't.  */
   7170 
   7171 	  while (fixup_info[k].size != 0
   7172 		 && relax_info->relax_fixup[branch_range_type][k].offset < offset)
   7173 	    k++;
   7174 
   7175 	  number_to_chars_bigendian (fr_buffer + buf_offset, insn, insn_size);
   7176 	  buf_offset += insn_size;
   7177 
   7178 	  offset += insn_size;
   7179 	  i++;
   7180 	}
   7181 
   7182       /* Set up fixup.  */
   7183       exp.X_op = O_symbol;
   7184 
   7185       for (i = 0; fixup_info[i].size != 0; i++)
   7186 	{
   7187 	  fixup_size = fixup_info[i].size;
   7188 	  pcrel = ((fixup_info[i].ramp & NDS32_PCREL) != 0) ? 1 : 0;
   7189 
   7190 	  if ((fixup_info[i].ramp & NDS32_CREATE_LABEL) != 0)
   7191 	    {
   7192 	      /* This is a reverse branch.  */
   7193 	      exp.X_add_symbol = symbol_temp_new (sec, fragP->fr_next, 0);
   7194 	      exp.X_add_number = 0;
   7195 	    }
   7196 	  else if ((fixup_info[i].ramp & NDS32_PTR) != 0)
   7197 	    {
   7198 	      /* This relocation has to point to another instruction.  */
   7199 	      branch_size = fr_where + code_size - 4;
   7200 	      exp.X_add_symbol = symbol_temp_new (sec, fragP, branch_size);
   7201 	      exp.X_add_number = 0;
   7202 	    }
   7203 	  else if ((fixup_info[i].ramp & NDS32_ABS) != 0)
   7204 	    {
   7205 	      /* This is a tag relocation.  */
   7206 	      exp.X_add_symbol = abs_section_sym;
   7207 	      exp.X_add_number = 0;
   7208 	    }
   7209 	  else if ((fixup_info[i].ramp & NDS32_INSN16) != 0)
   7210 	    {
   7211 	      if (!enable_16bit)
   7212 		continue;
   7213 	      /* This is a tag relocation.  */
   7214 	      exp.X_add_symbol = abs_section_sym;
   7215 	      exp.X_add_number = 0;
   7216 	    }
   7217 	  else
   7218 	    {
   7219 	      exp.X_add_symbol = branch_symbol;
   7220 	      exp.X_add_number = branch_offset;
   7221 	    }
   7222 
   7223 	  if (fixup_info[i].r_type != 0)
   7224 	    {
   7225 	      final_r_type = fixup_info[i].r_type;
   7226 	      fixP = fix_new_exp (fragP, fr_where + fixup_info[i].offset,
   7227 				  fixup_size, &exp, pcrel,
   7228 				  final_r_type);
   7229 	      fixP->fx_addnumber = fixP->fx_offset;
   7230 	    }
   7231 	}
   7232 
   7233       fragP->fr_fix = fr_where + buf_offset;
   7234     }
   7235 }
   7236 
   7237 /* tc_frob_file_before_fix  */
   7238 
   7239 void
   7240 nds32_frob_file_before_fix (void)
   7241 {
   7242 }
   7243 
   7244 static bool
   7245 nds32_relaxable_section (asection *sec)
   7246 {
   7247   return ((sec->flags & SEC_DEBUGGING) == 0
   7248 	  && strcmp (sec->name, ".eh_frame") != 0);
   7249 }
   7250 
   7251 /* TC_FORCE_RELOCATION */
   7252 int
   7253 nds32_force_relocation (fixS * fix)
   7254 {
   7255   switch (fix->fx_r_type)
   7256     {
   7257     case BFD_RELOC_NDS32_INSN16:
   7258     case BFD_RELOC_NDS32_LABEL:
   7259     case BFD_RELOC_NDS32_LONGCALL1:
   7260     case BFD_RELOC_NDS32_LONGCALL2:
   7261     case BFD_RELOC_NDS32_LONGCALL3:
   7262     case BFD_RELOC_NDS32_LONGJUMP1:
   7263     case BFD_RELOC_NDS32_LONGJUMP2:
   7264     case BFD_RELOC_NDS32_LONGJUMP3:
   7265     case BFD_RELOC_NDS32_LOADSTORE:
   7266     case BFD_RELOC_NDS32_9_FIXED:
   7267     case BFD_RELOC_NDS32_15_FIXED:
   7268     case BFD_RELOC_NDS32_17_FIXED:
   7269     case BFD_RELOC_NDS32_25_FIXED:
   7270     case BFD_RELOC_NDS32_9_PCREL:
   7271     case BFD_RELOC_NDS32_15_PCREL:
   7272     case BFD_RELOC_NDS32_17_PCREL:
   7273     case BFD_RELOC_NDS32_WORD_9_PCREL:
   7274     case BFD_RELOC_NDS32_10_UPCREL:
   7275     case BFD_RELOC_NDS32_25_PCREL:
   7276     case BFD_RELOC_NDS32_MINUEND:
   7277     case BFD_RELOC_NDS32_SUBTRAHEND:
   7278       return 1;
   7279 
   7280     case BFD_RELOC_8:
   7281     case BFD_RELOC_16:
   7282     case BFD_RELOC_32:
   7283     case BFD_RELOC_NDS32_DIFF_ULEB128:
   7284       /* Linker should handle difference between two symbol.  */
   7285       return fix->fx_subsy != NULL
   7286 	&& nds32_relaxable_section (S_GET_SEGMENT (fix->fx_addsy));
   7287     case BFD_RELOC_64:
   7288       if (fix->fx_subsy)
   7289 	as_bad ("Double word for difference between two symbols "
   7290 		"is not supported across relaxation.");
   7291     default:
   7292       ;
   7293     }
   7294 
   7295   if (generic_force_reloc (fix))
   7296     return 1;
   7297 
   7298   return fix->fx_pcrel;
   7299 }
   7300 
   7301 /* TC_VALIDATE_FIX_SUB  */
   7302 
   7303 int
   7304 nds32_validate_fix_sub (fixS *fix, segT add_symbol_segment)
   7305 {
   7306   segT sub_symbol_segment;
   7307 
   7308   /* This code is referred from Xtensa.  Check their implementation for
   7309      details.  */
   7310 
   7311   /* Make sure both symbols are in the same segment, and that segment is
   7312      "normal" and relaxable.  */
   7313   sub_symbol_segment = S_GET_SEGMENT (fix->fx_subsy);
   7314   return (sub_symbol_segment == add_symbol_segment
   7315 	  && add_symbol_segment != undefined_section);
   7316 }
   7317 
   7318 void
   7319 md_number_to_chars (char *buf, valueT val, int n)
   7320 {
   7321   if (target_big_endian)
   7322     number_to_chars_bigendian (buf, val, n);
   7323   else
   7324     number_to_chars_littleendian (buf, val, n);
   7325 }
   7326 
   7327 /* This function is called to convert an ASCII string into a floating point
   7328    value in format used by the CPU.  */
   7329 
   7330 const char *
   7331 md_atof (int type, char *litP, int *sizeP)
   7332 {
   7333   int i;
   7334   int prec;
   7335   LITTLENUM_TYPE words[MAX_LITTLENUMS];
   7336   char *t;
   7337 
   7338   switch (type)
   7339     {
   7340     case 'f':
   7341     case 'F':
   7342     case 's':
   7343     case 'S':
   7344       prec = 2;
   7345       break;
   7346     case 'd':
   7347     case 'D':
   7348     case 'r':
   7349     case 'R':
   7350       prec = 4;
   7351       break;
   7352     default:
   7353       *sizeP = 0;
   7354       return _("Bad call to md_atof()");
   7355     }
   7356 
   7357   t = atof_ieee (input_line_pointer, type, words);
   7358   if (t)
   7359     input_line_pointer = t;
   7360   *sizeP = prec * sizeof (LITTLENUM_TYPE);
   7361 
   7362   if (target_big_endian)
   7363     {
   7364       for (i = 0; i < prec; i++)
   7365 	{
   7366 	  md_number_to_chars (litP, (valueT) words[i],
   7367 			      sizeof (LITTLENUM_TYPE));
   7368 	  litP += sizeof (LITTLENUM_TYPE);
   7369 	}
   7370     }
   7371   else
   7372     {
   7373       for (i = prec - 1; i >= 0; i--)
   7374 	{
   7375 	  md_number_to_chars (litP, (valueT) words[i],
   7376 			      sizeof (LITTLENUM_TYPE));
   7377 	  litP += sizeof (LITTLENUM_TYPE);
   7378 	}
   7379     }
   7380 
   7381   return 0;
   7382 }
   7383 
   7384 /* md_elf_section_change_hook  */
   7385 
   7386 void
   7387 nds32_elf_section_change_hook (void)
   7388 {
   7389 }
   7390 
   7391 /* md_cleanup  */
   7392 
   7393 void
   7394 nds32_cleanup (void)
   7395 {
   7396 }
   7397 
   7398 /* This function is used to scan leb128 subtraction expressions,
   7399    and insert fixups for them.
   7400 
   7401       e.g., .leb128  .L1 - .L0
   7402 
   7403    These expressions are heavily used in debug information or
   7404    exception tables.  Because relaxation will change code size,
   7405    we must resolve them in link time.  */
   7406 
   7407 static void
   7408 nds32_insert_leb128_fixes (bfd *abfd ATTRIBUTE_UNUSED,
   7409 			   asection *sec, void *xxx ATTRIBUTE_UNUSED)
   7410 {
   7411   segment_info_type *seginfo = seg_info (sec);
   7412   struct frag *fragP;
   7413 
   7414   subseg_set (sec, 0);
   7415 
   7416   for (fragP = seginfo->frchainP->frch_root;
   7417        fragP; fragP = fragP->fr_next)
   7418     {
   7419       expressionS *exp;
   7420 
   7421       /* Only unsigned leb128 can be handle.  */
   7422       if (fragP->fr_type != rs_leb128 || fragP->fr_subtype != 0
   7423 	  || fragP->fr_symbol == NULL)
   7424 	continue;
   7425 
   7426       exp = symbol_get_value_expression (fragP->fr_symbol);
   7427 
   7428       if (exp->X_op != O_subtract)
   7429 	continue;
   7430 
   7431       fix_new_exp (fragP, fragP->fr_fix, 0,
   7432 		   exp, 0, BFD_RELOC_NDS32_DIFF_ULEB128);
   7433     }
   7434 }
   7435 
   7436 static void
   7437 nds32_insert_relax_entry (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
   7438 			  void *xxx ATTRIBUTE_UNUSED)
   7439 {
   7440   segment_info_type *seginfo;
   7441   fragS *fragP;
   7442   fixS *fixP;
   7443   expressionS exp;
   7444   fixS *fixp;
   7445 
   7446   seginfo = seg_info (sec);
   7447   if (!seginfo || !symbol_rootP || !subseg_text_p (sec) || sec->size == 0)
   7448     return;
   7449 
   7450   for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
   7451     if (!fixp->fx_done)
   7452       break;
   7453 
   7454   if (!fixp && !verbatim && ict_flag == ICT_NONE)
   7455     return;
   7456 
   7457   subseg_change (sec, 0);
   7458 
   7459   /* Set RELAX_ENTRY flags for linker.  */
   7460   fragP = seginfo->frchainP->frch_root;
   7461   exp.X_op = O_symbol;
   7462   exp.X_add_symbol = abs_section_sym;
   7463   exp.X_add_number = 0;
   7464   if (!enable_relax_relocs)
   7465     exp.X_add_number |= R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG;
   7466   else
   7467     {
   7468       /* These flags are only enabled when global relax is enabled.
   7469 	 Maybe we can check DISABLE_RELAX_FLAG at link-time,
   7470 	 so we set them anyway.  */
   7471       if (verbatim)
   7472 	exp.X_add_number |= R_NDS32_RELAX_ENTRY_VERBATIM_FLAG;
   7473       if (ict_flag == ICT_SMALL)
   7474 	exp.X_add_number |= R_NDS32_RELAX_ENTRY_ICT_SMALL;
   7475       else if (ict_flag == ICT_LARGE)
   7476 	exp.X_add_number |= R_NDS32_RELAX_ENTRY_ICT_LARGE;
   7477     }
   7478   if (optimize)
   7479     exp.X_add_number |= R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG;
   7480   if (optimize_for_space)
   7481     exp.X_add_number |= R_NDS32_RELAX_ENTRY_OPTIMIZE_FOR_SPACE_FLAG;
   7482 
   7483   fixP = fix_new_exp (fragP, 0, 0, &exp, 0, BFD_RELOC_NDS32_RELAX_ENTRY);
   7484   fixP->fx_no_overflow = 1;
   7485 }
   7486 
   7487 /* Analysis relax hint and insert suitable relocation pattern.  */
   7488 
   7489 static void
   7490 nds32_elf_analysis_relax_hint (void)
   7491 {
   7492   htab_traverse_noresize (nds32_hint_hash,
   7493 			  nds32_elf_append_relax_relocs_traverse, NULL);
   7494 }
   7495 
   7496 static void
   7497 nds32_elf_insert_final_frag (void)
   7498 {
   7499   struct frchain *frchainP;
   7500   asection *s;
   7501   fragS *fragP;
   7502 
   7503   if (!optimize)
   7504     return;
   7505 
   7506   for (s = stdoutput->sections; s; s = s->next)
   7507     {
   7508       segment_info_type *seginfo = seg_info (s);
   7509       if (!seginfo)
   7510 	continue;
   7511 
   7512       for (frchainP = seginfo->frchainP; frchainP != NULL;
   7513 	   frchainP = frchainP->frch_next)
   7514 	{
   7515 	  subseg_set (s, frchainP->frch_subseg);
   7516 
   7517 	  if (subseg_text_p (now_seg))
   7518 	    {
   7519 	      fragP = frag_now;
   7520 	      frag_var (rs_machine_dependent, 2, /* Max size.  */
   7521 			0, /* VAR is un-used.  */ 0, NULL, 0, NULL);
   7522 	      fragP->tc_frag_data.flag |= NDS32_FRAG_FINAL;
   7523 	    }
   7524 	}
   7525     }
   7526 }
   7527 
   7528 void
   7529 md_finish (void)
   7530 {
   7531   nds32_elf_insert_final_frag ();
   7532   nds32_elf_analysis_relax_hint ();
   7533   bfd_map_over_sections (stdoutput, nds32_insert_leb128_fixes, NULL);
   7534 }
   7535 
   7536 /* Implement md_allow_local_subtract.  */
   7537 
   7538 bool
   7539 nds32_allow_local_subtract (expressionS *expr_l ATTRIBUTE_UNUSED,
   7540 			    expressionS *expr_r ATTRIBUTE_UNUSED,
   7541 			    segT sec ATTRIBUTE_UNUSED)
   7542 {
   7543   /* Don't allow any subtraction, because relax may change the code.  */
   7544   return false;
   7545 }
   7546 
   7547 long
   7548 nds32_pcrel_from_section (fixS *fixP, segT sec ATTRIBUTE_UNUSED)
   7549 {
   7550   if (fixP->fx_addsy == NULL || !S_IS_DEFINED (fixP->fx_addsy)
   7551       || S_IS_EXTERNAL (fixP->fx_addsy) || S_IS_WEAK (fixP->fx_addsy))
   7552     {
   7553       /* Let linker resolve undefined symbols.  */
   7554       return 0;
   7555     }
   7556 
   7557   return fixP->fx_frag->fr_address + fixP->fx_where;
   7558 }
   7559 
   7560 /* md_post_relax_hook ()
   7561    Insert relax entry relocation into sections.  */
   7562 
   7563 void
   7564 nds32_post_relax_hook (void)
   7565 {
   7566   bfd_map_over_sections (stdoutput, nds32_insert_relax_entry, NULL);
   7567 }
   7568 
   7569 /* tc_fix_adjustable ()
   7570 
   7571    Return whether this symbol (fixup) can be replaced with
   7572    section symbols.  */
   7573 
   7574 bool
   7575 nds32_fix_adjustable (fixS *fixP)
   7576 {
   7577   switch (fixP->fx_r_type)
   7578     {
   7579     case BFD_RELOC_NDS32_WORD_9_PCREL:
   7580     case BFD_RELOC_NDS32_9_PCREL:
   7581     case BFD_RELOC_NDS32_15_PCREL:
   7582     case BFD_RELOC_NDS32_17_PCREL:
   7583     case BFD_RELOC_NDS32_25_PCREL:
   7584     case BFD_RELOC_NDS32_HI20:
   7585     case BFD_RELOC_NDS32_LO12S0:
   7586     case BFD_RELOC_8:
   7587     case BFD_RELOC_16:
   7588     case BFD_RELOC_32:
   7589     case BFD_RELOC_NDS32_PTR:
   7590     case BFD_RELOC_NDS32_LONGCALL4:
   7591     case BFD_RELOC_NDS32_LONGCALL5:
   7592     case BFD_RELOC_NDS32_LONGCALL6:
   7593     case BFD_RELOC_NDS32_LONGJUMP4:
   7594     case BFD_RELOC_NDS32_LONGJUMP5:
   7595     case BFD_RELOC_NDS32_LONGJUMP6:
   7596     case BFD_RELOC_NDS32_LONGJUMP7:
   7597       return 1;
   7598     default:
   7599       return 0;
   7600     }
   7601 }
   7602 
   7603 /* elf_tc_final_processing  */
   7604 
   7605 void
   7606 elf_nds32_final_processing (void)
   7607 {
   7608   /* An FPU_COM instruction is found without previous non-FPU_COM
   7609      instruction.  */
   7610   if (nds32_fpu_com
   7611       && !(nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
   7612     {
   7613       /* Since only FPU_COM instructions are used and no other FPU instructions
   7614 	 are used.  The nds32_elf_flags will be decided by the enabled options
   7615 	 by command line or default configuration.  */
   7616       if (nds32_fpu_dp_ext || nds32_fpu_sp_ext)
   7617 	{
   7618 	  nds32_elf_flags |= nds32_fpu_dp_ext ? E_NDS32_HAS_FPU_DP_INST : 0;
   7619 	  nds32_elf_flags |= nds32_fpu_sp_ext ? E_NDS32_HAS_FPU_INST : 0;
   7620 	}
   7621       else
   7622 	{
   7623 	  /* Should never here.  */
   7624 	  as_bad (_("Used FPU instructions requires enabling FPU extension"));
   7625 	}
   7626     }
   7627 
   7628   if (nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST))
   7629     {
   7630       /* Single/double FPU has been used, set FPU register config.  */
   7631       /* We did not check the actual number of register used.  We may
   7632 	 want to do it while assemble.  */
   7633       nds32_elf_flags &= ~E_NDS32_FPU_REG_CONF;
   7634       nds32_elf_flags |= (nds32_freg << E_NDS32_FPU_REG_CONF_SHIFT);
   7635     }
   7636 
   7637   if (nds32_pic)
   7638     nds32_elf_flags |= E_NDS32_HAS_PIC;
   7639 
   7640   if (nds32_gpr16)
   7641     nds32_elf_flags |= E_NDS32_HAS_REDUCED_REGS;
   7642 
   7643   nds32_elf_flags |= (E_NDS32_ELF_VER_1_4 | nds32_abi);
   7644   elf_elfheader (stdoutput)->e_flags |= nds32_elf_flags;
   7645 }
   7646 
   7647 /* Implement md_apply_fix.  Apply the fix-up or transform the fix-up for
   7648    later relocation generation.  */
   7649 
   7650 void
   7651 nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
   7652 {
   7653   char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
   7654   bfd_vma value = *valP;
   7655 
   7656   if (fixP->fx_r_type < BFD_RELOC_UNUSED
   7657       && fixP->fx_r_type > BFD_RELOC_NONE
   7658       && fixP->fx_r_type != BFD_RELOC_NDS32_DIFF_ULEB128)
   7659     {
   7660       /* In our old nds32 binutils, it must convert relocations which is
   7661 	 generated by CGEN.  However, it does not have to consider this anymore.
   7662 	 In current, it only deal with data relocations which enum
   7663 	 is smaller than BFD_RELOC_NONE and BFD_RELOC_NDS32_DIFF_ULEB128.
   7664 	 It is believed that we can construct a better mechanism to
   7665 	 deal with the whole relocation issue in nds32 target
   7666 	 without using CGEN.  */
   7667       fixP->fx_addnumber = value;
   7668       fixP->tc_fix_data = NULL;
   7669 
   7670       /* Transform specific relocations here for later relocation generation.
   7671 	 Tag tls data for linker.  */
   7672       switch (fixP->fx_r_type)
   7673 	{
   7674 	case BFD_RELOC_NDS32_DATA:
   7675 	  /* This reloc is obselete, we do not need it so far.  */
   7676 	  fixP->fx_done = 1;
   7677 	  break;
   7678 	case BFD_RELOC_NDS32_TPOFF:
   7679 	case BFD_RELOC_NDS32_TLS_LE_HI20:
   7680 	case BFD_RELOC_NDS32_TLS_LE_LO12:
   7681 	case BFD_RELOC_NDS32_TLS_LE_ADD:
   7682 	case BFD_RELOC_NDS32_TLS_LE_LS:
   7683 	case BFD_RELOC_NDS32_GOTTPOFF:
   7684 	case BFD_RELOC_NDS32_TLS_IE_HI20:
   7685 	case BFD_RELOC_NDS32_TLS_IE_LO12S2:
   7686 	case BFD_RELOC_NDS32_TLS_DESC_HI20:
   7687 	case BFD_RELOC_NDS32_TLS_DESC_LO12:
   7688 	case BFD_RELOC_NDS32_TLS_IE_LO12:
   7689 	case BFD_RELOC_NDS32_TLS_IEGP_HI20:
   7690 	case BFD_RELOC_NDS32_TLS_IEGP_LO12:
   7691 	case BFD_RELOC_NDS32_TLS_IEGP_LO12S2:
   7692 	  S_SET_THREAD_LOCAL (fixP->fx_addsy);
   7693 	  break;
   7694 	default:
   7695 	  break;
   7696 	}
   7697       return;
   7698     }
   7699 
   7700   if (fixP->fx_addsy == (symbolS *) NULL)
   7701     fixP->fx_done = 1;
   7702 
   7703   if (fixP->fx_subsy != (symbolS *) NULL)
   7704     {
   7705       /* HOW DIFF RELOCATION WORKS.
   7706 
   7707 	 First of all, this relocation is used to calculate the distance
   7708 	 between two symbols in the SAME section.  It is used for  jump-
   7709 	 table, debug information, exception table, et al.    Therefore,
   7710 	 it is a unsigned positive value.   It is NOT used for  general-
   7711 	 purpose arithmetic.
   7712 
   7713 	 Consider this example,  the distance between  .LEND and .LBEGIN
   7714 	 is stored at the address of foo.
   7715 
   7716 	 ---- >8 ---- >8 ---- >8 ---- >8 ----
   7717 	  .data
   7718 	  foo:
   7719 	    .word	.LBEGIN - .LEND
   7720 
   7721 	  .text
   7722 	     [before]
   7723 	  .LBEGIN
   7724 			 \
   7725 	     [between]    distance
   7726 			 /
   7727 	  .LEND
   7728 	     [after]
   7729 	 ---- 8< ---- 8< ---- 8< ---- 8< ----
   7730 
   7731 	 We use a single relocation entry for this expression.
   7732 	 * The initial distance value is stored directly in that location
   7733 	   specified by r_offset (i.e., foo in this example.)
   7734 	 * The begin of the region, i.e., .LBEGIN, is specified by
   7735 	   r_info/R_SYM and r_addend, e.g., .text + 0x32.
   7736 	 * The end of region, i.e., .LEND, is represented by
   7737 	   .LBEGIN + distance instead of .LEND, so we only need
   7738 	   a single relocation entry instead of two.
   7739 
   7740 	 When an instruction is relaxed, we adjust the relocation entry
   7741 	 depending on where the instruction locates.    There are three
   7742 	 cases, before, after and between the region.
   7743 	 * between: Distance value is read from r_offset,  adjusted and
   7744 	   written back into r_offset.
   7745 	 * before: Only r_addend is adjust.
   7746 	 * after: We don't care about it.
   7747 
   7748 	 Hereby, there are some limitation.
   7749 
   7750 	 `(.LEND - 1) - .LBEGIN' and `(.LEND - .LBEGIN) - 1'
   7751 	 are semantically different, and we cannot handle latter case
   7752 	 when relaxation.
   7753 
   7754 	 The latter expression means subtracting 1 from the distance
   7755 	 between .LEND and .LBEGIN.  And the former expression means
   7756 	 the distance between (.LEND - 1) and .LBEGIN.
   7757 
   7758 	 The nuance affects whether to adjust distance value when relax
   7759 	 an instruction.  In another words, whether the instruction
   7760 	 locates in the region.  Because we use a single relocation entry,
   7761 	 there is no field left for .LEND and the subtrahend.
   7762 
   7763 	 Since GCC-4.5, GCC may produce debug information in such expression
   7764 	     .long  .L1-1-.L0
   7765 	 in order to describe register clobbering during an function-call.
   7766 	     .L0:
   7767 		call foo
   7768 	     .L1:
   7769 
   7770 	 Check http://gcc.gnu.org/ml/gcc-patches/2009-06/msg01317.html
   7771 	 for details.  */
   7772 
   7773       value -= S_GET_VALUE (fixP->fx_subsy);
   7774       *valP = value;
   7775       fixP->fx_subsy = NULL;
   7776       fixP->fx_offset -= value;
   7777 
   7778       switch (fixP->fx_r_type)
   7779 	{
   7780 	case BFD_RELOC_8:
   7781 	  fixP->fx_r_type = BFD_RELOC_NDS32_DIFF8;
   7782 	  md_number_to_chars (where, value, 1);
   7783 	  break;
   7784 	case BFD_RELOC_16:
   7785 	  fixP->fx_r_type = BFD_RELOC_NDS32_DIFF16;
   7786 	  md_number_to_chars (where, value, 2);
   7787 	  break;
   7788 	case BFD_RELOC_32:
   7789 	  fixP->fx_r_type = BFD_RELOC_NDS32_DIFF32;
   7790 	  md_number_to_chars (where, value, 4);
   7791 	  break;
   7792 	case BFD_RELOC_NDS32_DIFF_ULEB128:
   7793 	  /* cvt_frag_to_fill () has called output_leb128 () for us.  */
   7794 	  break;
   7795 	default:
   7796 	  as_bad_subtract (fixP);
   7797 	  return;
   7798 	}
   7799     }
   7800   else if (fixP->fx_done)
   7801     {
   7802       /* We're finished with this fixup.  Install it because
   7803 	 bfd_install_relocation won't be called to do it.  */
   7804       switch (fixP->fx_r_type)
   7805 	{
   7806 	case BFD_RELOC_8:
   7807 	  md_number_to_chars (where, value, 1);
   7808 	  break;
   7809 	case BFD_RELOC_16:
   7810 	  md_number_to_chars (where, value, 2);
   7811 	  break;
   7812 	case BFD_RELOC_32:
   7813 	  md_number_to_chars (where, value, 4);
   7814 	  break;
   7815 	case BFD_RELOC_64:
   7816 	  md_number_to_chars (where, value, 8);
   7817 	  break;
   7818 	default:
   7819 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   7820 			_("Internal error: Unknown fixup type %d (`%s')"),
   7821 			fixP->fx_r_type,
   7822 			bfd_get_reloc_code_name (fixP->fx_r_type));
   7823 	  break;
   7824 	}
   7825     }
   7826 }
   7827 
   7828 /* Implement tc_gen_reloc.  Generate ELF relocation for a fix-up.  */
   7829 
   7830 arelent *
   7831 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
   7832 {
   7833   arelent *reloc;
   7834   bfd_reloc_code_real_type code;
   7835 
   7836   reloc = XNEW (arelent);
   7837 
   7838   reloc->sym_ptr_ptr = XNEW (asymbol *);
   7839   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
   7840   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
   7841 
   7842   code = fixP->fx_r_type;
   7843 
   7844   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
   7845   if (reloc->howto == (reloc_howto_type *) NULL)
   7846     {
   7847       as_bad_where (fixP->fx_file, fixP->fx_line,
   7848 		    _("internal error: can't export reloc type %d (`%s')"),
   7849 		    fixP->fx_r_type, bfd_get_reloc_code_name (code));
   7850       return NULL;
   7851     }
   7852 
   7853   /* Add relocation handling here.  */
   7854 
   7855   switch (fixP->fx_r_type)
   7856     {
   7857     default:
   7858       /* In general, addend of a relocation is the offset to the
   7859 	 associated symbol.  */
   7860       reloc->addend = fixP->fx_offset;
   7861       break;
   7862 
   7863     case BFD_RELOC_NDS32_DATA:
   7864       /* Prevent linker from optimizing data in text sections.
   7865 	 For example, jump table.  */
   7866       reloc->addend = fixP->fx_size;
   7867       break;
   7868     }
   7869 
   7870   return reloc;
   7871 }
   7872 
   7873 static struct suffix_name suffix_table[] =
   7874 {
   7875   {"GOTOFF",	BFD_RELOC_NDS32_GOTOFF},
   7876   {"GOT",	BFD_RELOC_NDS32_GOT20},
   7877   {"TPOFF",	BFD_RELOC_NDS32_TPOFF},
   7878   {"PLT",	BFD_RELOC_NDS32_25_PLTREL},
   7879   {"GOTTPOFF",	BFD_RELOC_NDS32_GOTTPOFF},
   7880   {"TLSDESC",  BFD_RELOC_NDS32_TLS_DESC},
   7881 };
   7882 
   7883 /* Implement md_parse_name.  */
   7884 
   7885 int
   7886 nds32_parse_name (char const *name, expressionS *exprP,
   7887 		  enum expr_mode mode ATTRIBUTE_UNUSED,
   7888 		  char *nextcharP ATTRIBUTE_UNUSED)
   7889 {
   7890   segT segment;
   7891 
   7892   exprP->X_op_symbol = NULL;
   7893   exprP->X_md = BFD_RELOC_UNUSED;
   7894 
   7895   exprP->X_add_symbol = symbol_find_or_make (name);
   7896   exprP->X_op = O_symbol;
   7897   exprP->X_add_number = 0;
   7898 
   7899   /* Check the special name if a symbol.  */
   7900   segment = S_GET_SEGMENT (exprP->X_add_symbol);
   7901   if ((segment != undefined_section) && (*nextcharP != '@'))
   7902     return 0;
   7903 
   7904   if (strcmp (name, GOT_NAME) == 0 && *nextcharP != '@')
   7905     {
   7906       /* Set for _GOT_OFFSET_TABLE_.  */
   7907       exprP->X_md = BFD_RELOC_NDS32_GOTPC20;
   7908     }
   7909   else if (*nextcharP == '@')
   7910     {
   7911       size_t i;
   7912       char *next;
   7913       for (i = 0; i < ARRAY_SIZE (suffix_table); i++)
   7914 	{
   7915 	  next = input_line_pointer + 1 + strlen (suffix_table[i].suffix);
   7916 	  if (strncasecmp (input_line_pointer + 1, suffix_table[i].suffix,
   7917 			   strlen (suffix_table[i].suffix)) == 0
   7918 	      && !is_part_of_name (*next))
   7919 	    {
   7920 	      exprP->X_md = suffix_table[i].reloc;
   7921 	      *input_line_pointer = *nextcharP;
   7922 	      input_line_pointer = next;
   7923 	      *nextcharP = *input_line_pointer;
   7924 	      *input_line_pointer = '\0';
   7925 	      break;
   7926 	    }
   7927 	}
   7928     }
   7929 
   7930   return 1;
   7931 }
   7932 
   7933 /* Implement tc_regname_to_dw2regnum.  */
   7934 
   7935 int
   7936 tc_nds32_regname_to_dw2regnum (char *regname)
   7937 {
   7938   struct nds32_keyword *sym = str_hash_find (nds32_gprs_hash, regname);
   7939 
   7940   if (!sym)
   7941     return -1;
   7942 
   7943   return sym->value;
   7944 }
   7945 
   7946 void
   7947 tc_nds32_frame_initial_instructions (void)
   7948 {
   7949   /* CIE */
   7950   /* Default cfa is register-31/sp.  */
   7951   cfi_add_CFA_def_cfa (31, 0);
   7952 }
   7953