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