Home | History | Annotate | Line # | Download | only in config
tc-nds32.c revision 1.1.1.1.2.1
      1 /* tc-nds32.c -- Assemble for the nds32
      2    Copyright (C) 2012-2016 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 perfomance.  */
     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[], int pv);
   2100 struct nds32_pseudo_opcode
   2101 {
   2102   const char *opcode;
   2103   int argc;
   2104   nds32_pseudo_opcode_func proc;
   2105   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[], int pv ATTRIBUTE_UNUSED)
   2193 {
   2194   char *arg_label = argv[0];
   2195   relaxing = TRUE;
   2196   /* b   label */
   2197   if (nds32_pic && strstr (arg_label, "@PLT"))
   2198     {
   2199       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
   2200       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
   2201       md_assemble  ((char *) "add $ta,$ta,$gp");
   2202       md_assemble  ((char *) "jr $ta");
   2203     }
   2204   else
   2205     {
   2206       md_assemblef ("j %s", arg_label);
   2207     }
   2208   relaxing = FALSE;
   2209 }
   2210 
   2211 static void
   2212 do_pseudo_bal (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2213 {
   2214   char *arg_label = argv[0];
   2215   relaxing = TRUE;
   2216   /* bal|call  label */
   2217   if (nds32_pic
   2218       && (strstr (arg_label, "@GOT") || strstr (arg_label, "@PLT")))
   2219     {
   2220       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
   2221       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
   2222       md_assemble  ((char *) "add $ta,$ta,$gp");
   2223       md_assemble ((char *) "jral $ta");
   2224     }
   2225   else
   2226     {
   2227       md_assemblef ("jal %s", arg_label);
   2228     }
   2229   relaxing = FALSE;
   2230 }
   2231 
   2232 static void
   2233 do_pseudo_bge (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2234 {
   2235   /* rt5, ra5, label */
   2236   md_assemblef ("slt $ta,%s,%s", argv[0], argv[1]);
   2237   md_assemblef ("beqz $ta,%s", argv[2]);
   2238 }
   2239 
   2240 static void
   2241 do_pseudo_bges (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2242 {
   2243   /* rt5, ra5, label */
   2244   md_assemblef ("slts $ta,%s,%s", argv[0], argv[1]);
   2245   md_assemblef ("beqz $ta,%s", argv[2]);
   2246 }
   2247 
   2248 static void
   2249 do_pseudo_bgt (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2250 {
   2251   /* bgt rt5, ra5, label */
   2252   md_assemblef ("slt $ta,%s,%s", argv[1], argv[0]);
   2253   md_assemblef ("bnez $ta,%s", argv[2]);
   2254 }
   2255 
   2256 static void
   2257 do_pseudo_bgts (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2258 {
   2259   /* bgt rt5, ra5, label */
   2260   md_assemblef ("slts $ta,%s,%s", argv[1], argv[0]);
   2261   md_assemblef ("bnez $ta,%s", argv[2]);
   2262 }
   2263 
   2264 static void
   2265 do_pseudo_ble (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2266 {
   2267   /* bgt rt5, ra5, label */
   2268   md_assemblef ("slt $ta,%s,%s", argv[1], argv[0]);
   2269   md_assemblef ("beqz $ta,%s", argv[2]);
   2270 }
   2271 
   2272 static void
   2273 do_pseudo_bles (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2274 {
   2275   /* bgt rt5, ra5, label */
   2276   md_assemblef ("slts $ta,%s,%s", argv[1], argv[0]);
   2277   md_assemblef ("beqz $ta,%s", argv[2]);
   2278 }
   2279 
   2280 static void
   2281 do_pseudo_blt (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2282 {
   2283   /* rt5, ra5, label */
   2284   md_assemblef ("slt $ta,%s,%s", argv[0], argv[1]);
   2285   md_assemblef ("bnez $ta,%s", argv[2]);
   2286 }
   2287 
   2288 static void
   2289 do_pseudo_blts (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2290 {
   2291   /* rt5, ra5, label */
   2292   md_assemblef ("slts $ta,%s,%s", argv[0], argv[1]);
   2293   md_assemblef ("bnez $ta,%s", argv[2]);
   2294 }
   2295 
   2296 static void
   2297 do_pseudo_br (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2298 {
   2299   md_assemblef ("jr %s", argv[0]);
   2300 }
   2301 
   2302 static void
   2303 do_pseudo_bral (int argc, char *argv[], int pv ATTRIBUTE_UNUSED)
   2304 {
   2305   if (argc == 1)
   2306     md_assemblef ("jral $lp,%s", argv[0]);
   2307   else
   2308     md_assemblef ("jral %s,%s", argv[0], argv[1]);
   2309 }
   2310 
   2311 static void
   2312 do_pseudo_la_internal (const char *arg_reg, char *arg_label,
   2313 		       const char *line)
   2314 {
   2315   expressionS exp;
   2316 
   2317   parse_expression (arg_label, &exp);
   2318   if (exp.X_op != O_symbol)
   2319     {
   2320       as_bad (_("la must use with symbol. '%s'"), line);
   2321       return;
   2322     }
   2323 
   2324   relaxing = TRUE;
   2325   /* rt, label */
   2326   if (!nds32_pic && !strstr(arg_label, "@"))
   2327     {
   2328       md_assemblef ("sethi %s,hi20(%s)", arg_reg, arg_label);
   2329       md_assemblef ("ori %s,%s,lo12(%s)", arg_reg, arg_reg, arg_label);
   2330     }
   2331   else if (strstr (arg_label, "@TPOFF"))
   2332     {
   2333       /* la $rt, sym@TPOFF  */
   2334       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
   2335       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
   2336       md_assemblef ("add %s,$ta,%s", arg_reg, TLS_REG);
   2337     }
   2338   else if (strstr(arg_label, "@GOTTPOFF"))
   2339     {
   2340       /* la $rt, sym@GOTTPOFF*/
   2341       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
   2342       md_assemblef ("lwi $ta,[$ta+lo12(%s)]", arg_label);
   2343       md_assemblef ("add %s,$ta,%s", arg_reg, TLS_REG);
   2344     }
   2345   else if (nds32_pic && ((strstr (arg_label, "@PLT")
   2346 			  || strstr (arg_label, "@GOTOFF"))))
   2347     {
   2348       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
   2349       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
   2350       md_assemblef ("add %s,$ta,$gp", arg_reg);
   2351     }
   2352   else if (nds32_pic && strstr (arg_label, "@GOT"))
   2353     {
   2354       long addend = builtin_addend (arg_label, NULL);
   2355 
   2356       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
   2357       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
   2358       md_assemblef ("lw %s,[$gp+$ta]", arg_reg);
   2359       if (addend != 0)
   2360 	{
   2361 	  if (addend < 0x4000 && addend >= -0x4000)
   2362 	    {
   2363 	      md_assemblef ("addi %s,%s,%d", arg_reg, arg_reg, addend);
   2364 	    }
   2365 	  else
   2366 	    {
   2367 	      do_pseudo_li_internal ("$ta", addend);
   2368 	      md_assemblef ("add %s,$ta,%s", arg_reg, arg_reg);
   2369 	    }
   2370 	}
   2371     }
   2372    else
   2373       as_bad (_("need PIC qualifier with symbol. '%s'"), line);
   2374   relaxing = FALSE;
   2375 }
   2376 
   2377 static void
   2378 do_pseudo_la (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2379 {
   2380   do_pseudo_la_internal (argv[0], argv[1], argv[argc]);
   2381 }
   2382 
   2383 static void
   2384 do_pseudo_li_internal (const char *rt, int imm32s)
   2385 {
   2386   if (enable_16bit && imm32s <= 0xf && imm32s >= -0x10)
   2387     md_assemblef ("movi55 %s,%d", rt, imm32s);
   2388   else if (imm32s <= 0x7ffff && imm32s >= -0x80000)
   2389     md_assemblef ("movi %s,%d", rt, imm32s);
   2390   else if ((imm32s & 0xfff) == 0)
   2391     md_assemblef ("sethi %s,hi20(%d)", rt, imm32s);
   2392   else
   2393     {
   2394       md_assemblef ("sethi %s,hi20(%d)", rt, imm32s);
   2395       md_assemblef ("ori %s,%s,lo12(%d)", rt, rt, imm32s);
   2396     }
   2397 }
   2398 
   2399 static void
   2400 do_pseudo_li (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2401 {
   2402   /* Validate argv[1] for constant expression.  */
   2403   expressionS exp;
   2404 
   2405   parse_expression (argv[1], &exp);
   2406   if (exp.X_op != O_constant)
   2407     {
   2408       as_bad (_("Operand is not a constant. `%s'"), argv[argc]);
   2409       return;
   2410     }
   2411 
   2412   do_pseudo_li_internal (argv[0], exp.X_add_number);
   2413 }
   2414 
   2415 static void
   2416 do_pseudo_ls_bhw (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
   2417 {
   2418   char ls = 'r';
   2419   char size = 'x';
   2420   const char *sign = "";
   2421 
   2422   /* Prepare arguments for various load/store.  */
   2423   sign = (pv & 0x10) ? "s" : "";
   2424   ls = (pv & 0x80000000) ? 's' : 'l';
   2425   switch (pv & 0x3)
   2426     {
   2427     case 0: size = 'b'; break;
   2428     case 1: size = 'h'; break;
   2429     case 2: size = 'w'; break;
   2430     }
   2431 
   2432   if (ls == 's' || size == 'w')
   2433     sign = "";
   2434 
   2435   if (builtin_isreg (argv[1], NULL))
   2436     {
   2437       /* lwi */
   2438       md_assemblef ("%c%ci %s,[%s]", ls, size, argv[0], argv[1]);
   2439     }
   2440   else if (!nds32_pic)
   2441     {
   2442       relaxing = TRUE;
   2443       if (strstr (argv[1], "@TPOFF"))
   2444 	{
   2445 	  /* ls.w $rt, sym@TPOFF  */
   2446 	  md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
   2447 	  md_assemblef ("ori $ta,$ta,lo12(%s)", argv[1]);
   2448 	  md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], TLS_REG);
   2449 	}
   2450       else if (strstr (argv[1], "@GOTTPOFF"))
   2451 	{
   2452 	  /* ls.w $rt, sym@GOTTPOFF  */
   2453 	  md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
   2454 	  md_assemblef ("lwi $ta,[$ta+lo12(%s)]", argv[1]);
   2455 	  md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], TLS_REG);
   2456 	}
   2457       else
   2458 	{
   2459 	  /* lwi */
   2460 	  md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
   2461 	  md_assemblef ("%c%c%si %s,[$ta+lo12(%s)]", ls, size, sign, argv[0], argv[1]);
   2462 	}
   2463       relaxing = FALSE;
   2464     }
   2465   else
   2466     {
   2467       relaxing = TRUE;
   2468       /* PIC code.  */
   2469       if (strstr (argv[1], "@GOTOFF"))
   2470 	{
   2471 	  /* lw */
   2472 	  md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
   2473 	  md_assemblef ("ori $ta,$ta,lo12(%s)", argv[1]);
   2474 	  md_assemblef ("%c%c%s %s,[$ta+$gp]", ls, size, sign, argv[0]);
   2475 	}
   2476       else if (strstr (argv[1], "@GOT"))
   2477 	{
   2478 	  long addend = builtin_addend (argv[1], NULL);
   2479 	  /* lw */
   2480 	  md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
   2481 	  md_assemblef ("ori $ta,$ta,lo12(%s)", argv[1]);
   2482 	  md_assemble ((char *) "lw $ta,[$gp+$ta]");	/* Load address word.  */
   2483 	  if (addend < 0x10000 && addend >= -0x10000)
   2484 	    {
   2485 	      md_assemblef ("%c%c%si %s,[$ta+(%d)]", ls, size, sign, argv[0], addend);
   2486 	    }
   2487 	  else
   2488 	    {
   2489 	      /* lw */
   2490 	      do_pseudo_li_internal (argv[0], addend);
   2491 	      md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], argv[0]);
   2492 	    }
   2493 	}
   2494       else
   2495 	{
   2496 	  as_bad (_("needs @GOT or @GOTOFF. %s"), argv[argc]);
   2497 	}
   2498       relaxing = FALSE;
   2499     }
   2500 }
   2501 
   2502 static void
   2503 do_pseudo_ls_bhwp (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
   2504 {
   2505   char *arg_rt = argv[0];
   2506   char *arg_label = argv[1];
   2507   char *arg_inc = argv[2];
   2508   char ls = 'r';
   2509   char size = 'x';
   2510   const char *sign = "";
   2511 
   2512   /* Prepare arguments for various load/store.  */
   2513   sign = (pv & 0x10) ? "s" : "";
   2514   ls = (pv & 0x80000000) ? 's' : 'l';
   2515   switch (pv & 0x3)
   2516     {
   2517     case 0: size = 'b'; break;
   2518     case 1: size = 'h'; break;
   2519     case 2: size = 'w'; break;
   2520     }
   2521 
   2522   if (ls == 's' || size == 'w')
   2523     sign = "";
   2524 
   2525   do_pseudo_la_internal ("$ta", arg_label, argv[argc]);
   2526   md_assemblef ("%c%c%si.bi %s,[$ta],%s", ls, size, sign, arg_rt, arg_inc);
   2527 }
   2528 
   2529 static void
   2530 do_pseudo_ls_bhwpc (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
   2531 {
   2532   char *arg_rt = argv[0];
   2533   char *arg_inc = argv[1];
   2534   char ls = 'r';
   2535   char size = 'x';
   2536   const char *sign = "";
   2537 
   2538   /* Prepare arguments for various load/store.  */
   2539   sign = (pv & 0x10) ? "s" : "";
   2540   ls = (pv & 0x80000000) ? 's' : 'l';
   2541   switch (pv & 0x3)
   2542     {
   2543     case 0: size = 'b'; break;
   2544     case 1: size = 'h'; break;
   2545     case 2: size = 'w'; break;
   2546     }
   2547 
   2548   if (ls == 's' || size == 'w')
   2549     sign = "";
   2550 
   2551   md_assemblef ("%c%c%si.bi %s,[$ta],%s", ls, size, sign, arg_rt, arg_inc);
   2552 }
   2553 
   2554 static void
   2555 do_pseudo_ls_bhwi (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
   2556 {
   2557   char ls = 'r';
   2558   char size = 'x';
   2559   const char *sign = "";
   2560 
   2561   /* Prepare arguments for various load/store.  */
   2562   sign = (pv & 0x10) ? "s" : "";
   2563   ls = (pv & 0x80000000) ? 's' : 'l';
   2564   switch (pv & 0x3)
   2565     {
   2566     case 0: size = 'b'; break;
   2567     case 1: size = 'h'; break;
   2568     case 2: size = 'w'; break;
   2569     }
   2570 
   2571   if (ls == 's' || size == 'w')
   2572     sign = "";
   2573 
   2574   md_assemblef ("%c%c%si.bi %s,%s,%s",
   2575 		ls, size, sign, argv[0], argv[1], argv[2]);
   2576 }
   2577 
   2578 static void
   2579 do_pseudo_move_reg_internal (char *dst, char *src)
   2580 {
   2581   if (enable_16bit)
   2582     md_assemblef ("mov55 %s,%s", dst, src);
   2583   else
   2584     md_assemblef ("ori %s,%s,0", dst, src);
   2585 }
   2586 
   2587 static void
   2588 do_pseudo_move (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2589 {
   2590   expressionS exp;
   2591 
   2592   if (builtin_isreg (argv[1], NULL))
   2593     do_pseudo_move_reg_internal (argv[0], argv[1]);
   2594   else
   2595     {
   2596       parse_expression (argv[1], &exp);
   2597       if (exp.X_op == O_constant)
   2598 	/* move $rt, imm  -> li $rt, imm  */
   2599 	do_pseudo_li_internal (argv[0], exp.X_add_number);
   2600       else
   2601 	/* l.w $rt, var  -> l.w $rt, var  */
   2602 	do_pseudo_ls_bhw (argc, argv, 2);
   2603     }
   2604 }
   2605 
   2606 static void
   2607 do_pseudo_neg (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2608 {
   2609   /* Instead of "subri".  */
   2610   md_assemblef ("subri %s,%s,0", argv[0], argv[1]);
   2611 }
   2612 
   2613 static void
   2614 do_pseudo_not (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2615 {
   2616   md_assemblef ("nor %s,%s,%s", argv[0], argv[1], argv[1]);
   2617 }
   2618 
   2619 static void
   2620 do_pseudo_pushpopm (int argc, char *argv[], int pv ATTRIBUTE_UNUSED)
   2621 {
   2622   /* posh/pop $ra, $rb */
   2623   /* SMW.{b | a}{i | d}{m?} Rb, [Ra], Re, Enable4 */
   2624   int rb, re, ra, en4;
   2625   int i;
   2626   const char *opc = "pushpopm";
   2627 
   2628   if (argc == 3)
   2629     as_bad ("'pushm/popm $ra5, $rb5, $label' is deprecated.  "
   2630 	    "Only 'pushm/popm $ra5' is supported now. %s", argv[argc]);
   2631   else if (argc == 1)
   2632     as_bad ("'pushm/popm $ra5, $rb5'. %s\n", argv[argc]);
   2633 
   2634   if (strstr (argv[argc], "pop") == argv[argc])
   2635     opc = "lmw.bim";
   2636   else if (strstr (argv[argc], "push") == argv[argc])
   2637     opc = "smw.adm";
   2638   else
   2639     as_fatal ("nds32-as internal error. %s", argv[argc]);
   2640 
   2641   rb = builtin_regnum (argv[0], NULL);
   2642   re = builtin_regnum (argv[1], NULL);
   2643 
   2644   if (re < rb)
   2645     {
   2646       as_warn ("$rb should not be smaller than $ra. %s", argv[argc]);
   2647       /* Swap to right order.  */
   2648       ra = re;
   2649       re = rb;
   2650       rb = ra;
   2651     }
   2652 
   2653   /* Build enable4 mask.  */
   2654   en4 = 0;
   2655   if (re >= 28 || rb >= 28)
   2656     {
   2657       for (i = (rb >= 28? rb: 28); i <= re; i++)
   2658 	en4 |= 1 << (3 - (i - 28));
   2659     }
   2660 
   2661   /* Adjust $re, $rb.  */
   2662   if (rb >= 28)
   2663     rb = re = 31;
   2664   else if (nds32_gpr16 != 1 && re >= 28)
   2665     re = 27;
   2666 
   2667   /* Reduce register.  */
   2668   if (nds32_gpr16 && re > 10 && !(rb == 31 && re == 31))
   2669     {
   2670       if (re >= 15 && strstr(opc, "smw") != NULL)
   2671 	md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
   2672       if (rb <= 10)
   2673 	md_assemblef ("%s $r%d,[$sp],$r10, 0x0", opc, rb);
   2674       if (re >= 15 && strstr(opc, "lmw") != NULL)
   2675 	md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
   2676     }
   2677   else
   2678     md_assemblef ("%s $r%d,[$sp],$r%d,%d", opc, rb, re, en4);
   2679 }
   2680 
   2681 static void
   2682 do_pseudo_pushpop (int argc, char *argv[], int pv ATTRIBUTE_UNUSED)
   2683 {
   2684   /* push/pop $ra5, $label=$sp */
   2685   char *argvm[3];
   2686 
   2687   if (argc == 2)
   2688     as_bad ("'push/pop $ra5, rb5' is deprecated.  "
   2689 	    "Only 'push/pop $ra5' is supported now. %s", argv[argc]);
   2690 
   2691   argvm[0] = argv[0];
   2692   argvm[1] = argv[0];
   2693   argvm[2] = argv[argc];
   2694   do_pseudo_pushpopm (2, argvm, PV_DONT_CARE);
   2695 }
   2696 
   2697 static void
   2698 do_pseudo_v3push (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2699 {
   2700   md_assemblef ("push25 %s,%s", argv[0], argv[1]);
   2701 }
   2702 
   2703 static void
   2704 do_pseudo_v3pop (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2705 {
   2706   md_assemblef ("pop25 %s,%s", argv[0], argv[1]);
   2707 }
   2708 
   2709 /* pv == 0, parsing "push.s" pseudo instruction operands.
   2710    pv != 0, parsing "pop.s" pseudo instruction operands.  */
   2711 
   2712 static void
   2713 do_pseudo_pushpop_stack (int argc, char *argv[], int pv)
   2714 {
   2715   /* push.s Rb,Re,{$fp $gp $lp $sp}  ==>  smw.adm Rb,[$sp],Re,Eable4  */
   2716   /* pop.s Rb,Re,{$fp $gp $lp $sp}   ==>  lmw.bim Rb,[$sp],Re,Eable4  */
   2717 
   2718   int rb, re;
   2719   int en4;
   2720   int last_arg_index;
   2721   const char *opc = (pv == 0) ? "smw.adm" : "lmw.bim";
   2722 
   2723   rb = re = 0;
   2724 
   2725   if (argc == 1)
   2726     {
   2727       /* argc=1, operands pattern: { $fp $gp $lp $sp }  */
   2728 
   2729       /* Set register number Rb = Re = $sp = $r31.  */
   2730       rb = re = 31;
   2731     }
   2732   else if (argc == 2 || argc == 3)
   2733     {
   2734       /* argc=2, operands pattern: Rb, Re  */
   2735       /* argc=3, operands pattern: Rb, Re, { $fp $gp $lp $sp }  */
   2736 
   2737       /* Get register number in integer.  */
   2738       rb = builtin_regnum (argv[0], NULL);
   2739       re = builtin_regnum (argv[1], NULL);
   2740 
   2741       /* Rb should be equal/less than Re.  */
   2742       if (rb > re)
   2743 	as_bad ("The first operand (%s) should be equal to or smaller than "
   2744 		"second operand (%s).", argv[0], argv[1]);
   2745 
   2746       /* forbid using $fp|$gp|$lp|$sp in Rb or Re
   2747 		      r28 r29 r30 r31  */
   2748       if (rb >= 28)
   2749 	as_bad ("Cannot use $fp, $gp, $lp, or $sp at first operand !!");
   2750       if (re >= 28)
   2751 	as_bad ("Cannot use $fp, $gp, $lp, or $sp at second operand !!");
   2752     }
   2753   else
   2754     {
   2755       as_bad ("Invalid operands pattern !!");
   2756     }
   2757 
   2758   /* Build Enable4 mask.  */
   2759   /* Using last_arg_index for argc=1|2|3 is safe, because $fp, $gp, $lp,
   2760      and $sp only appear in argc=1 or argc=3 if argc=2, en4 remains 0,
   2761      which is also valid for code generation.  */
   2762   en4 = 0;
   2763   last_arg_index = argc - 1;
   2764   if (strstr (argv[last_arg_index], "$fp"))
   2765     en4 |= 8;
   2766   if (strstr (argv[last_arg_index], "$gp"))
   2767     en4 |= 4;
   2768   if (strstr (argv[last_arg_index], "$lp"))
   2769     en4 |= 2;
   2770   if (strstr (argv[last_arg_index], "$sp"))
   2771     en4 |= 1;
   2772 
   2773   md_assemblef ("%s $r%d,[$sp],$r%d,%d", opc, rb, re, en4);
   2774 }
   2775 
   2776 static void
   2777 do_pseudo_push_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2778 {
   2779   char size = 'x';
   2780   /* If users omit push location, use $sp as default value.  */
   2781   char location[8] = "$sp";  /* 8 is enough for register name.  */
   2782 
   2783   switch (pv & 0x3)
   2784     {
   2785     case 0: size = 'b'; break;
   2786     case 1: size = 'h'; break;
   2787     case 2: size = 'w'; break;
   2788     case 3: size = 'w'; break;
   2789     }
   2790 
   2791   if (argc == 2)
   2792     {
   2793       strncpy (location, argv[1], 8);
   2794       location[7] = '\0';
   2795     }
   2796 
   2797   md_assemblef ("l.%c $ta,%s", size, argv[0]);
   2798   md_assemblef ("smw.adm $ta,[%s],$ta", location);
   2799 
   2800   if ((pv & 0x3) == 0x3) /* double-word */
   2801     {
   2802       md_assemblef ("l.w $ta,%s+4", argv[0]);
   2803       md_assemblef ("smw.adm $ta,[%s],$ta", location);
   2804     }
   2805 }
   2806 
   2807 static void
   2808 do_pseudo_pop_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2809 {
   2810   char size = 'x';
   2811   /* If users omit pop location, use $sp as default value.  */
   2812   char location[8] = "$sp";  /* 8 is enough for register name.  */
   2813 
   2814   switch (pv & 0x3)
   2815     {
   2816     case 0: size = 'b'; break;
   2817     case 1: size = 'h'; break;
   2818     case 2: size = 'w'; break;
   2819     case 3: size = 'w'; break;
   2820     }
   2821 
   2822   if (argc == 3)
   2823     {
   2824       strncpy (location, argv[2], 8);
   2825       location[7] = '\0';
   2826     }
   2827 
   2828   if ((pv & 0x3) == 0x3) /* double-word */
   2829     {
   2830       md_assemblef ("lmw.bim %s,[%s],%s", argv[1], location, argv[1]);
   2831       md_assemblef ("s.w %s,%s+4", argv[1], argv[0]);
   2832     }
   2833 
   2834   md_assemblef ("lmw.bim %s,[%s],%s", argv[1], location, argv[1]);
   2835   md_assemblef ("s.%c %s,%s", size, argv[1], argv[0]);
   2836 }
   2837 
   2838 static void
   2839 do_pseudo_pusha (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2840 {
   2841   /* If users omit push location, use $sp as default value.  */
   2842   char location[8] = "$sp";  /* 8 is enough for register name.  */
   2843 
   2844   if (argc == 2)
   2845     {
   2846       strncpy (location, argv[1], 8);
   2847       location[7] = '\0';
   2848     }
   2849 
   2850   md_assemblef ("la $ta,%s", argv[0]);
   2851   md_assemblef ("smw.adm $ta,[%s],$ta", location);
   2852 }
   2853 
   2854 static void
   2855 do_pseudo_pushi (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
   2856 {
   2857   /* If users omit push location, use $sp as default value.  */
   2858   char location[8] = "$sp";  /* 8 is enough for register name.  */
   2859 
   2860   if (argc == 2)
   2861     {
   2862       strncpy (location, argv[1], 8);
   2863       location[7] = '\0';
   2864     }
   2865 
   2866   md_assemblef ("li $ta,%s", argv[0]);
   2867   md_assemblef ("smw.adm $ta,[%s],$ta", location);
   2868 }
   2869 
   2870 struct nds32_pseudo_opcode nds32_pseudo_opcode_table[] =
   2871 {
   2872   {"b",      1, do_pseudo_b,      0, 0},
   2873   {"bal",    1, do_pseudo_bal,    0, 0},
   2874 
   2875   {"bge",    3, do_pseudo_bge,    0, 0},
   2876   {"bges",   3, do_pseudo_bges,   0, 0},
   2877 
   2878   {"bgt",    3, do_pseudo_bgt,    0, 0},
   2879   {"bgts",   3, do_pseudo_bgts,   0, 0},
   2880 
   2881   {"ble",    3, do_pseudo_ble,    0, 0},
   2882   {"bles",   3, do_pseudo_bles,   0, 0},
   2883 
   2884   {"blt",    3, do_pseudo_blt,    0, 0},
   2885   {"blts",   3, do_pseudo_blts,   0, 0},
   2886 
   2887   {"br",     1, do_pseudo_br,     0, 0},
   2888   {"bral",   1, do_pseudo_bral,   0, 0},
   2889 
   2890   {"call",   1, do_pseudo_bal,    0, 0},
   2891 
   2892   {"la",     2, do_pseudo_la, 0, 0},
   2893   {"li",     2, do_pseudo_li, 0, 0},
   2894 
   2895   {"l.b",    2, do_pseudo_ls_bhw, 0, 0},
   2896   {"l.h",    2, do_pseudo_ls_bhw, 1, 0},
   2897   {"l.w",    2, do_pseudo_ls_bhw, 2, 0},
   2898   {"l.bs",   2, do_pseudo_ls_bhw, 0 | 0x10, 0},
   2899   {"l.hs",   2, do_pseudo_ls_bhw, 1 | 0x10, 0},
   2900   {"s.b",    2, do_pseudo_ls_bhw, 0 | 0x80000000, 0},
   2901   {"s.h",    2, do_pseudo_ls_bhw, 1 | 0x80000000, 0},
   2902   {"s.w",    2, do_pseudo_ls_bhw, 2 | 0x80000000, 0},
   2903 
   2904   {"l.bp",   3, do_pseudo_ls_bhwp, 0, 0},
   2905   {"l.bpc",  3, do_pseudo_ls_bhwpc, 0, 0},
   2906   {"l.hp",   3, do_pseudo_ls_bhwp, 1, 0},
   2907   {"l.hpc",  3, do_pseudo_ls_bhwpc, 1, 0},
   2908   {"l.wp",   3, do_pseudo_ls_bhwp, 2, 0},
   2909   {"l.wpc",  3, do_pseudo_ls_bhwpc, 2, 0},
   2910   {"l.bsp",  3, do_pseudo_ls_bhwp, 0 | 0x10, 0},
   2911   {"l.bspc", 3, do_pseudo_ls_bhwpc, 0 | 0x10, 0},
   2912   {"l.hsp",  3, do_pseudo_ls_bhwp, 1 | 0x10, 0},
   2913   {"l.hspc", 3, do_pseudo_ls_bhwpc, 1 | 0x10, 0},
   2914   {"s.bp",   3, do_pseudo_ls_bhwp, 0 | 0x80000000, 0},
   2915   {"s.bpc",   3, do_pseudo_ls_bhwpc, 0 | 0x80000000, 0},
   2916   {"s.hp",   3, do_pseudo_ls_bhwp, 1 | 0x80000000, 0},
   2917   {"s.hpc",   3, do_pseudo_ls_bhwpc, 1 | 0x80000000, 0},
   2918   {"s.wp",   3, do_pseudo_ls_bhwp, 2 | 0x80000000, 0},
   2919   {"s.wpc",   3, do_pseudo_ls_bhwpc, 2 | 0x80000000, 0},
   2920   {"s.bsp",  3, do_pseudo_ls_bhwp, 0 | 0x80000000 | 0x10, 0},
   2921   {"s.hsp",  3, do_pseudo_ls_bhwp, 1 | 0x80000000 | 0x10, 0},
   2922 
   2923   {"lbi.p",  3, do_pseudo_ls_bhwi, 0, 0},
   2924   {"lhi.p",  3, do_pseudo_ls_bhwi, 1, 0},
   2925   {"lwi.p",  3, do_pseudo_ls_bhwi, 2, 0},
   2926   {"sbi.p",  3, do_pseudo_ls_bhwi, 0 | 0x80000000, 0},
   2927   {"shi.p",  3, do_pseudo_ls_bhwi, 1 | 0x80000000, 0},
   2928   {"swi.p",  3, do_pseudo_ls_bhwi, 2 | 0x80000000, 0},
   2929   {"lbsi.p", 3, do_pseudo_ls_bhwi, 0 | 0x10, 0},
   2930   {"lhsi.p", 3, do_pseudo_ls_bhwi, 1 | 0x10, 0},
   2931   {"lwsi.p", 3, do_pseudo_ls_bhwi, 2 | 0x10, 0},
   2932 
   2933   {"move",   2, do_pseudo_move, 0, 0},
   2934   {"neg",    2, do_pseudo_neg,  0, 0},
   2935   {"not",    2, do_pseudo_not,  0, 0},
   2936 
   2937   {"pop",    2, do_pseudo_pushpop,   0, 0},
   2938   {"push",   2, do_pseudo_pushpop,   0, 0},
   2939   {"popm",   2, do_pseudo_pushpopm,  0, 0},
   2940   {"pushm",   3, do_pseudo_pushpopm, 0, 0},
   2941 
   2942   {"v3push", 2, do_pseudo_v3push, 0, 0},
   2943   {"v3pop",  2, do_pseudo_v3pop,  0, 0},
   2944 
   2945   /* Support pseudo instructions of pushing/poping registers into/from stack
   2946        push.s  Rb, Re, { $fp $gp $lp $sp }  ==>  smw.adm  Rb,[$sp],Re,Enable4
   2947        pop.s   Rb, Re, { $fp $gp $lp $sp }  ==>  lmw.bim  Rb,[$sp],Re,Enable4 */
   2948   { "push.s", 3, do_pseudo_pushpop_stack, 0, 0 },
   2949   { "pop.s", 3, do_pseudo_pushpop_stack, 1, 0 },
   2950   { "push.b", 2, do_pseudo_push_bhwd, 0, 0 },
   2951   { "push.h", 2, do_pseudo_push_bhwd, 1, 0 },
   2952   { "push.w", 2, do_pseudo_push_bhwd, 2, 0 },
   2953   { "push.d", 2, do_pseudo_push_bhwd, 3, 0 },
   2954   { "pop.b", 3, do_pseudo_pop_bhwd, 0, 0 },
   2955   { "pop.h", 3, do_pseudo_pop_bhwd, 1, 0 },
   2956   { "pop.w", 3, do_pseudo_pop_bhwd, 2, 0 },
   2957   { "pop.d", 3, do_pseudo_pop_bhwd, 3, 0 },
   2958   { "pusha", 2, do_pseudo_pusha, 0, 0 },
   2959   { "pushi", 2, do_pseudo_pushi, 0, 0 },
   2960 
   2961   {NULL, 0, NULL, 0, 0}
   2962 };
   2963 
   2964 static void
   2965 nds32_init_nds32_pseudo_opcodes (void)
   2966 {
   2967   struct nds32_pseudo_opcode *opcode = nds32_pseudo_opcode_table;
   2968 
   2969   nds32_pseudo_opcode_hash = hash_new ();
   2970   for ( ; opcode->opcode; opcode++)
   2971     {
   2972       void *op;
   2973 
   2974       op = hash_find (nds32_pseudo_opcode_hash, opcode->opcode);
   2975       if (op != NULL)
   2976 	{
   2977 	  as_warn (_("Duplicated pseudo-opcode %s."), opcode->opcode);
   2978 	  continue;
   2979 	}
   2980       hash_insert (nds32_pseudo_opcode_hash, opcode->opcode, opcode);
   2981     }
   2982 }
   2983 
   2984 static struct nds32_pseudo_opcode *
   2985 nds32_lookup_pseudo_opcode (const char *str)
   2986 {
   2987   int i = 0;
   2988   /* Assume pseudo-opcode are less than 16-char in length.  */
   2989   char op[16] = {0};
   2990 
   2991   for (i = 0; i < (int)ARRAY_SIZE (op); i++)
   2992     {
   2993       if (ISSPACE (op[i] = str[i]))
   2994 	break;
   2995     }
   2996 
   2997   if (i >= (int)ARRAY_SIZE (op))
   2998     return NULL;
   2999 
   3000   op[i] = '\0';
   3001 
   3002   return hash_find (nds32_pseudo_opcode_hash, op);
   3003 }
   3004 
   3005 static void
   3006 nds32_pseudo_opcode_wrapper (char *line, struct nds32_pseudo_opcode *opcode)
   3007 {
   3008   int argc = 0;
   3009   char *argv[8] = {NULL};
   3010   char *s;
   3011   char *str = xstrdup (line);
   3012 
   3013   /* Parse arguments for opcode.  */
   3014   s = str + strlen (opcode->opcode);
   3015 
   3016   if (!s[0])
   3017     goto end;
   3018 
   3019   /* Dummy comma to ease separate arguments as below.  */
   3020   s[0] = ',';
   3021   do
   3022     {
   3023       if (s[0] == ',')
   3024 	{
   3025 	  if (argc >= opcode->argc
   3026 	      || (argc >= (int)ARRAY_SIZE (argv) - 1))
   3027 	    as_bad (_("Too many argument. `%s'"), line);
   3028 
   3029 	  argv[argc] = s + 1;
   3030 	  argc ++;
   3031 	  s[0] = '\0';
   3032 	}
   3033       ++s;
   3034     } while (s[0] != '\0');
   3035 end:
   3036   /* Put the origin line for debugging.  */
   3037   argv[argc] = line;
   3038   opcode->proc (argc, argv, opcode->pseudo_val);
   3039   free (str);
   3040 }
   3041 
   3042 /* This function will be invoked from function `nds32_after_parse_args'.
   3044    Thus, if the value of option has been set, keep the value the way it is.  */
   3045 
   3046 static int
   3047 nds32_parse_arch (const char *str)
   3048 {
   3049   static const struct nds32_arch
   3050   {
   3051     const char *name;
   3052     int baseline;
   3053     int reduced_reg;
   3054     int fpu_sp_ext;
   3055     int fpu_dp_ext;
   3056     int fpu_freg;
   3057     int abi;
   3058   } archs[] =
   3059   {
   3060     {"v3m", ISA_V3M, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
   3061     {"v3j", ISA_V3,  1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
   3062     {"v3s", ISA_V3,  0, 1, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
   3063     {"v3f", ISA_V3,  0, 1, 1, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
   3064     {"v3",  ISA_V3,  0, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
   3065     {"v2j", ISA_V2,  1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
   3066     {"v2s", ISA_V2,  0, 1, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
   3067     {"v2f", ISA_V2,  0, 1, 1, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
   3068     {"v2",  ISA_V2,  0, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
   3069   };
   3070   size_t i;
   3071 
   3072   for (i = 0; i < ARRAY_SIZE (archs); i++)
   3073     {
   3074       if (strcmp (str, archs[i].name) != 0)
   3075 	continue;
   3076 
   3077       /* The value `-1' represents this option has *NOT* been set.  */
   3078       nds32_baseline = (-1 != nds32_baseline) ? nds32_baseline : archs[i].baseline;
   3079       nds32_gpr16 = (-1 != nds32_gpr16) ? nds32_gpr16 : archs[i].reduced_reg;
   3080       nds32_fpu_sp_ext = (-1 != nds32_fpu_sp_ext) ? nds32_fpu_sp_ext : archs[i].fpu_sp_ext;
   3081       nds32_fpu_dp_ext = (-1 != nds32_fpu_dp_ext) ? nds32_fpu_dp_ext : archs[i].fpu_dp_ext;
   3082       nds32_freg = (-1 != nds32_freg) ? nds32_freg : archs[i].fpu_freg;
   3083       nds32_abi = (-1 != nds32_abi) ? nds32_abi : archs[i].abi;
   3084 
   3085       return 1;
   3086     }
   3087 
   3088   /* Logic here rejects the input arch name.  */
   3089   as_bad (_("unknown arch name `%s'\n"), str);
   3090 
   3091   return 1;
   3092 }
   3093 
   3094 /* This function parses "baseline" specified.  */
   3095 
   3096 static int
   3097 nds32_parse_baseline (const char *str)
   3098 {
   3099   if (strcmp (str, "v3") == 0)
   3100     nds32_baseline = ISA_V3;
   3101   else if (strcmp (str, "v3m") == 0)
   3102     nds32_baseline = ISA_V3M;
   3103   else if (strcmp (str, "v2") == 0)
   3104     nds32_baseline = ISA_V2;
   3105   else
   3106     {
   3107       /* Logic here rejects the input baseline.  */
   3108       as_bad (_("unknown baseline `%s'\n"), str);
   3109       return 0;
   3110     }
   3111 
   3112   return 1;
   3113 }
   3114 
   3115 /* This function parses "fpu-freg" specified.  */
   3116 
   3117 static int
   3118 nds32_parse_freg (const char *str)
   3119 {
   3120   if (strcmp (str, "2") == 0)
   3121     nds32_freg = E_NDS32_FPU_REG_32SP_16DP;
   3122   else if (strcmp (str, "3") == 0)
   3123     nds32_freg = E_NDS32_FPU_REG_32SP_32DP;
   3124   else if (strcmp (str, "1") == 0)
   3125     nds32_freg = E_NDS32_FPU_REG_16SP_8DP;
   3126   else if (strcmp (str, "0") == 0)
   3127     nds32_freg = E_NDS32_FPU_REG_8SP_4DP;
   3128   else
   3129     {
   3130       /* Logic here rejects the input FPU configuration.  */
   3131       as_bad (_("unknown FPU configuration `%s'\n"), str);
   3132       return 0;
   3133     }
   3134 
   3135   return 1;
   3136 }
   3137 
   3138 /* This function parse "abi=" specified.  */
   3139 
   3140 static int
   3141 nds32_parse_abi (const char *str)
   3142 {
   3143   if (strcmp (str, "v2") == 0)
   3144     nds32_abi = E_NDS_ABI_AABI;
   3145   /* Obsolete.  */
   3146   else if (strcmp (str, "v2fp") == 0)
   3147     nds32_abi = E_NDS_ABI_V2FP;
   3148   else if (strcmp (str, "v1") == 0)
   3149     nds32_abi = E_NDS_ABI_V1;
   3150   else if (strcmp (str,"v2fpp") == 0)
   3151     nds32_abi = E_NDS_ABI_V2FP_PLUS;
   3152   else
   3153     {
   3154       /* Logic here rejects the input abi version.  */
   3155       as_bad (_("unknown ABI version`%s'\n"), str);
   3156       return 0;
   3157     }
   3158 
   3159   return 1;
   3160 }
   3161 
   3162 /* This function turn on all extensions and instructions support.  */
   3163 
   3164 static int
   3165 nds32_all_ext (void)
   3166 {
   3167   nds32_mac = 1;
   3168   nds32_div = 1;
   3169   nds32_dx_regs = 1;
   3170   nds32_16bit_ext = 1;
   3171   nds32_perf_ext = 1;
   3172   nds32_perf_ext2 = 1;
   3173   nds32_string_ext = 1;
   3174   nds32_audio_ext = 1;
   3175   nds32_fpu_fma = 1;
   3176   nds32_fpu_sp_ext = 1;
   3177   nds32_fpu_dp_ext = 1;
   3178 
   3179   return 1;
   3180 }
   3181 
   3182 /* GAS will call md_parse_option whenever getopt returns an unrecognized code,
   3183    presumably indicating a special code value which appears in md_longopts.
   3184    This function should return non-zero if it handled the option and zero
   3185    otherwise.  There is no need to print a message about an option not being
   3186    recognized.  This will be handled by the generic code.  */
   3187 
   3188 int
   3189 nds32_parse_option (int c, const char *arg)
   3190 {
   3191   struct nds32_parse_option_table *coarse_tune;
   3192   struct nds32_set_option_table *fine_tune;
   3193   const char *ptr_arg = NULL;
   3194 
   3195   switch (c)
   3196     {
   3197     case OPTION_OPTIMIZE:
   3198       optimize = 1;
   3199       optimize_for_space = 0;
   3200       break;
   3201     case OPTION_OPTIMIZE_SPACE:
   3202       optimize = 0;
   3203       optimize_for_space = 1;
   3204       break;
   3205     case OPTION_BIG:
   3206       target_big_endian = 1;
   3207       break;
   3208     case OPTION_LITTLE:
   3209       target_big_endian = 0;
   3210       break;
   3211     case OPTION_TURBO:
   3212       nds32_all_ext ();
   3213       break;
   3214     case OPTION_PIC:
   3215       nds32_pic = 1;
   3216       break;
   3217     case OPTION_RELAX_FP_AS_GP_OFF:
   3218       nds32_relax_fp_as_gp = 0;
   3219       break;
   3220     case OPTION_RELAX_B2BB_ON:
   3221       nds32_relax_b2bb = 1;
   3222       break;
   3223     case OPTION_RELAX_ALL_OFF:
   3224       nds32_relax_all = 0;
   3225       break;
   3226     default:
   3227       /* Determination of which option table to search for to save time.  */
   3228       if (!arg)
   3229 	return 0;
   3230 
   3231       ptr_arg = strchr (arg, '=');
   3232 
   3233       if (ptr_arg)
   3234 	{
   3235 	  /* Find the value after '='.  */
   3236 	  if (ptr_arg != NULL)
   3237 	    ptr_arg++;
   3238 	  for (coarse_tune = parse_opts; coarse_tune->name != NULL; coarse_tune++)
   3239 	    {
   3240 	      if (strncmp (arg, coarse_tune->name, (ptr_arg - arg)) == 0)
   3241 		{
   3242 		  coarse_tune->func (ptr_arg);
   3243 		  return 1;
   3244 		}
   3245 	    }
   3246 	}
   3247       else
   3248 	{
   3249 	  int disable = 0;
   3250 
   3251 	  /* Filter out the Disable option first.  */
   3252 	  if (strncmp (arg, "no-", 3) == 0)
   3253 	    {
   3254 	      disable = 1;
   3255 	      arg += 3;
   3256 	    }
   3257 
   3258 	  for (fine_tune = toggle_opts; fine_tune->name != NULL; fine_tune++)
   3259 	    {
   3260 	      if (strcmp (arg, fine_tune->name) == 0)
   3261 		{
   3262 		  if (fine_tune->var != NULL)
   3263 		    *fine_tune->var = (disable) ? 0 : 1;
   3264 		  return 1;
   3265 		}
   3266 	    }
   3267 	}
   3268       /* Nothing match.  */
   3269       return 0;
   3270     }
   3271 
   3272   return 1;
   3273 }
   3274 
   3275 /* tc_check_label  */
   3276 
   3277 void
   3278 nds32_check_label (symbolS *label ATTRIBUTE_UNUSED)
   3279 {
   3280   /* The code used to create BB is move to frob_label.
   3281      They should go there.  */
   3282 }
   3283 
   3284 static void
   3285 set_endian_little (int on)
   3286 {
   3287   target_big_endian = !on;
   3288 }
   3289 
   3290 /* These functions toggles the generation of 16-bit.  First encounter signals
   3291    the beginning of not generating 16-bit instructions and next encounter
   3292    signals the restoring back to default behavior.  */
   3293 
   3294 static void
   3295 trigger_16bit (int trigger)
   3296 {
   3297   enable_16bit = trigger;
   3298 }
   3299 
   3300 static int backup_16bit_mode;
   3301 static void
   3302 restore_16bit (int no_use ATTRIBUTE_UNUSED)
   3303 {
   3304   enable_16bit = backup_16bit_mode;
   3305 }
   3306 
   3307 static void
   3308 off_16bit (int no_use ATTRIBUTE_UNUSED)
   3309 {
   3310   backup_16bit_mode = enable_16bit;
   3311   enable_16bit = 0;
   3312 }
   3313 
   3314 /* Built-in segments for small object.  */
   3315 typedef struct nds32_seg_entryT
   3316 {
   3317   segT s;
   3318   const char *name;
   3319   flagword flags;
   3320 } nds32_seg_entry;
   3321 
   3322 nds32_seg_entry nds32_seg_table[] =
   3323 {
   3324   {NULL, ".sdata_f", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
   3325 		     | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
   3326   {NULL, ".sdata_b", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
   3327 		     | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
   3328   {NULL, ".sdata_h", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
   3329 		     | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
   3330   {NULL, ".sdata_w", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
   3331 		     | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
   3332   {NULL, ".sdata_d", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
   3333 		     | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
   3334   {NULL, ".sbss_f", SEC_ALLOC | SEC_SMALL_DATA},
   3335   {NULL, ".sbss_b", SEC_ALLOC | SEC_SMALL_DATA},
   3336   {NULL, ".sbss_h", SEC_ALLOC | SEC_SMALL_DATA},
   3337   {NULL, ".sbss_w", SEC_ALLOC | SEC_SMALL_DATA},
   3338   {NULL, ".sbss_d", SEC_ALLOC | SEC_SMALL_DATA}
   3339 };
   3340 
   3341 /* Indexes to nds32_seg_table[].  */
   3342 enum NDS32_SECTIONS_ENUM
   3343 {
   3344   SDATA_F_SECTION = 0,
   3345   SDATA_B_SECTION = 1,
   3346   SDATA_H_SECTION = 2,
   3347   SDATA_W_SECTION = 3,
   3348   SDATA_D_SECTION = 4,
   3349   SBSS_F_SECTION = 5,
   3350   SBSS_B_SECTION = 6,
   3351   SBSS_H_SECTION = 7,
   3352   SBSS_W_SECTION = 8,
   3353   SBSS_D_SECTION = 9
   3354 };
   3355 
   3356 /* The following code is borrowed from v850_seg.  Revise this is needed.  */
   3357 
   3358 static void
   3359 do_nds32_seg (int i, subsegT sub)
   3360 {
   3361   nds32_seg_entry *seg = nds32_seg_table + i;
   3362 
   3363   obj_elf_section_change_hook ();
   3364 
   3365   if (seg->s != NULL)
   3366     subseg_set (seg->s, sub);
   3367   else
   3368     {
   3369       seg->s = subseg_new (seg->name, sub);
   3370       if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
   3371 	{
   3372 	  bfd_set_section_flags (stdoutput, seg->s, seg->flags);
   3373 	  if ((seg->flags & SEC_LOAD) == 0)
   3374 	    seg_info (seg->s)->bss = 1;
   3375 	}
   3376     }
   3377 }
   3378 
   3379 static void
   3380 nds32_seg (int i)
   3381 {
   3382   subsegT sub = get_absolute_expression ();
   3383 
   3384   do_nds32_seg (i, sub);
   3385   demand_empty_rest_of_line ();
   3386 }
   3387 
   3388 /* Set if label adjustment is needed.  I should not adjust .xbyte in dwarf.  */
   3389 static symbolS *nds32_last_label;	/* Last label for aligment.  */
   3390 
   3391 /* This code is referred from D30V for adjust label to be with pedning
   3392    aligment.  For example,
   3393      LBYTE: .byte	0x12
   3394      LHALF: .half	0x12
   3395      LWORD: .word	0x12
   3396    Without this, the above label will not attatch to incoming data.  */
   3397 
   3398 static void
   3399 nds32_adjust_label (int n)
   3400 {
   3401   /* FIXME: I think adjust lable and alignment is
   3402      the programmer's obligation.  Saddly, VLSI team doesn't
   3403      properly use .align for their test cases.
   3404      So I re-implement cons_align and auto adjust labels, again.
   3405 
   3406      I think d30v's implmentation is simple and good enough.  */
   3407 
   3408   symbolS *label = nds32_last_label;
   3409   nds32_last_label = NULL;
   3410 
   3411   /* SEC_ALLOC is used to eliminate .debug_ sections.
   3412      SEC_CODE is used to include section for ILM.  */
   3413   if (((now_seg->flags & SEC_ALLOC) == 0 && (now_seg->flags & SEC_CODE) == 0)
   3414       || strcmp (now_seg->name, ".eh_frame") == 0
   3415       || strcmp (now_seg->name, ".gcc_except_table") == 0)
   3416     return;
   3417 
   3418   /* Only frag by alignment when needed.
   3419      Otherwise, it will fail to optimize labels on 4-byte boundary.  (bug8454)
   3420      See md_convert_frag () and RELAX_SET_RELAXABLE (frag) for details.  */
   3421   if (frag_now_fix () & ((1 << n) -1 ))
   3422     {
   3423       if (subseg_text_p (now_seg))
   3424 	frag_align_code (n, 0);
   3425       else
   3426 	frag_align (n, 0, 0);
   3427 
   3428       /* Record the minimum alignment for this segment.  */
   3429       record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER);
   3430     }
   3431 
   3432   if (label != NULL)
   3433     {
   3434       symbolS *sym;
   3435       int label_seen = FALSE;
   3436       struct frag *old_frag;
   3437       valueT old_value, new_value;
   3438 
   3439       gas_assert (S_GET_SEGMENT (label) == now_seg);
   3440 
   3441       old_frag  = symbol_get_frag (label);
   3442       old_value = S_GET_VALUE (label);
   3443       new_value = (valueT) frag_now_fix ();
   3444 
   3445       /* Multiple labels may be on the same address.  And the last symbol
   3446 	 may not be a label at all, e.g., register name, external function names,
   3447 	 so I have to track the last label in tc_frob_label instead of
   3448 	 just using symbol_lastP.  */
   3449       for (sym = symbol_lastP; sym != NULL; sym = symbol_previous (sym))
   3450 	{
   3451 	  if (symbol_get_frag (sym) == old_frag
   3452 	      && S_GET_VALUE (sym) == old_value)
   3453 	    {
   3454 	      /* Warning HERE! */
   3455 	      label_seen = TRUE;
   3456 	      symbol_set_frag (sym, frag_now);
   3457 	      S_SET_VALUE (sym, new_value);
   3458 	    }
   3459 	  else if (label_seen && symbol_get_frag (sym) != old_frag)
   3460 	    break;
   3461 	}
   3462     }
   3463 }
   3464 
   3465 void
   3466 nds32_cons_align (int size ATTRIBUTE_UNUSED)
   3467 {
   3468   /* Do nothing here.
   3469      This is called before `md_flush_pending_output' is called by `cons'.
   3470 
   3471      There are two things should be done for auto-adjust-label.
   3472      1. Align data/instructions and adjust label to be attached to them.
   3473      2. Clear auto-adjust state, so incommng data/instructions will not
   3474 	adjust the label.
   3475 
   3476      For example,
   3477 	  .byte 0x1
   3478 	.L0:
   3479 	  .word 0x2
   3480 	  .word 0x3
   3481      in this case, '.word 0x2' will adjust the label, .L0, but '.word 0x3' should not.
   3482 
   3483      I think `md_flush_pending_output' is a good place to clear the auto-adjust state,
   3484      but it is also called by `cons' before this function.
   3485      To simplify the code, instead of overriding .zero, .fill, .space, etc,
   3486      I think we should just adjust label in `nds32_aligned_X_cons' instead of here.  */
   3487 }
   3488 
   3489 static void
   3490 nds32_aligned_cons (int idx)
   3491 {
   3492   nds32_adjust_label (idx);
   3493   /* Call default handler.  */
   3494   cons (1 << idx);
   3495   if (now_seg->flags & SEC_CODE
   3496       && now_seg->flags & SEC_ALLOC && now_seg->flags & SEC_RELOC)
   3497     {
   3498       /* Use BFD_RELOC_NDS32_DATA to avoid EX9 optimization replacing data.  */
   3499       expressionS exp;
   3500 
   3501       exp.X_add_number = 0;
   3502       exp.X_op = O_constant;
   3503       fix_new_exp (frag_now, frag_now_fix () - (1 << idx), 1 << idx,
   3504 		   &exp, 0, BFD_RELOC_NDS32_DATA);
   3505     }
   3506 }
   3507 
   3508 /* `.double' directive.  */
   3509 
   3510 static void
   3511 nds32_aligned_float_cons (int type)
   3512 {
   3513   switch (type)
   3514     {
   3515     case 'f':
   3516     case 'F':
   3517     case 's':
   3518     case 'S':
   3519       nds32_adjust_label (2);
   3520       break;
   3521     case 'd':
   3522     case 'D':
   3523     case 'r':
   3524     case 'R':
   3525       nds32_adjust_label (4);
   3526       break;
   3527     default:
   3528       as_bad ("Unrecognized float type, %c\n", (char)type);
   3529     }
   3530   /* Call default handler.  */
   3531   float_cons (type);
   3532 }
   3533 
   3534 static void
   3535 nds32_enable_pic (int ignore ATTRIBUTE_UNUSED)
   3536 {
   3537   /* Another way to do -mpic.
   3538      This is for GCC internal use and should always be first line
   3539      of code, otherwise, the effect is not determined.  */
   3540   nds32_pic = 1;
   3541 }
   3542 
   3543 static void
   3544 nds32_set_abi (int ver)
   3545 {
   3546   nds32_abi = ver;
   3547 }
   3548 
   3549 /* Relax directive to set relocation R_NDS32_RELAX_ENTRY value.  */
   3550 
   3551 static void
   3552 nds32_relax_relocs (int relax)
   3553 {
   3554   char saved_char;
   3555   char *name;
   3556   int i;
   3557   const char *subtype_relax[] =
   3558     {"", "", "ex9", "ifc"};
   3559 
   3560   name = input_line_pointer;
   3561   while (*input_line_pointer && !ISSPACE (*input_line_pointer))
   3562     input_line_pointer++;
   3563   saved_char = *input_line_pointer;
   3564   *input_line_pointer = 0;
   3565 
   3566   for (i = 0; i < (int) ARRAY_SIZE (subtype_relax); i++)
   3567     {
   3568       if (strcmp (name, subtype_relax[i]) == 0)
   3569 	{
   3570 	  switch (i)
   3571 	    {
   3572 	    case 0:
   3573 	    case 1:
   3574 	      enable_relax_relocs = relax & enable_relax_relocs;
   3575 	      enable_relax_ex9 = relax & enable_relax_ex9;
   3576 	      enable_relax_ifc = relax & enable_relax_ifc;
   3577 	      break;
   3578 	    case 2:
   3579 	      enable_relax_ex9 = relax;
   3580 	      break;
   3581 	    case 3:
   3582 	      enable_relax_ifc = relax;
   3583 	      break;
   3584 	    default:
   3585 	      break;
   3586 	    }
   3587 	  break;
   3588 	}
   3589     }
   3590   *input_line_pointer = saved_char;
   3591   ignore_rest_of_line ();
   3592 }
   3593 
   3594 /* Record which arguments register($r0 ~ $r5) is not used in callee.
   3595    bit[i] for $ri  */
   3596 
   3597 static void
   3598 nds32_set_hint_func_args (int ignore ATTRIBUTE_UNUSED)
   3599 {
   3600   ignore_rest_of_line ();
   3601 }
   3602 
   3603 /* Insert relocations to mark the begin and end of a fp-omitted function,
   3604    for further relaxation use.
   3605    bit[i] for $ri  */
   3606 
   3607 static void
   3608 nds32_omit_fp_begin (int mode)
   3609 {
   3610   expressionS exp;
   3611 
   3612   if (nds32_relax_fp_as_gp == 0)
   3613     return;
   3614   exp.X_op = O_symbol;
   3615   exp.X_add_symbol = abs_section_sym;
   3616   if (mode == 1)
   3617     {
   3618       in_omit_fp = 1;
   3619       exp.X_add_number = R_NDS32_RELAX_REGION_OMIT_FP_FLAG;
   3620       fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
   3621 		   BFD_RELOC_NDS32_RELAX_REGION_BEGIN);
   3622     }
   3623   else
   3624     {
   3625       in_omit_fp = 0;
   3626       exp.X_add_number = R_NDS32_RELAX_REGION_OMIT_FP_FLAG;
   3627       fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
   3628 		   BFD_RELOC_NDS32_RELAX_REGION_END);
   3629     }
   3630 }
   3631 
   3632 /* Insert relocations to mark the begin and end of ex9 region,
   3633    for further relaxation use.
   3634    bit[i] for $ri */
   3635 
   3636 static void
   3637 nds32_no_ex9_begin (int mode)
   3638 {
   3639   expressionS exp;
   3640 
   3641   exp.X_op = O_symbol;
   3642   exp.X_add_symbol = abs_section_sym;
   3643   if (mode == 1)
   3644     {
   3645       exp.X_add_number = R_NDS32_RELAX_REGION_NO_EX9_FLAG;
   3646       fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
   3647 		   BFD_RELOC_NDS32_RELAX_REGION_BEGIN);
   3648     }
   3649   else
   3650     {
   3651       exp.X_add_number = R_NDS32_RELAX_REGION_NO_EX9_FLAG;
   3652       fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
   3653 		   BFD_RELOC_NDS32_RELAX_REGION_END);
   3654     }
   3655 }
   3656 
   3657 static void
   3658 nds32_loop_begin (int mode)
   3659 {
   3660   /* Insert loop region relocation here.  */
   3661   expressionS exp;
   3662 
   3663   exp.X_op = O_symbol;
   3664   exp.X_add_symbol = abs_section_sym;
   3665   if (mode == 1)
   3666     {
   3667       exp.X_add_number = R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG;
   3668       fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
   3669 		   BFD_RELOC_NDS32_RELAX_REGION_BEGIN);
   3670     }
   3671   else
   3672     {
   3673       exp.X_add_number = R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG;
   3674       fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
   3675 		   BFD_RELOC_NDS32_RELAX_REGION_END);
   3676     }
   3677 }
   3678 
   3679 struct nds32_relocs_group
   3680 {
   3681   struct nds32_relocs_pattern *pattern;
   3682   struct nds32_relocs_group *next;
   3683 };
   3684 
   3685 static struct nds32_relocs_group *nds32_relax_hint_current = NULL;
   3686 
   3687 /* Insert a relax hint.  */
   3688 
   3689 static void
   3690 nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
   3691 {
   3692   char *name;
   3693   char saved_char;
   3694   struct nds32_relocs_pattern *relocs = NULL;
   3695   struct nds32_relocs_group *group, *new;
   3696 
   3697   name = input_line_pointer;
   3698   while (*input_line_pointer && !ISSPACE (*input_line_pointer))
   3699     input_line_pointer++;
   3700   saved_char = *input_line_pointer;
   3701   *input_line_pointer = 0;
   3702   name = strdup (name);
   3703 
   3704   /* Find relax hint entry for next instruction, and all member will be
   3705      initialized at that time.  */
   3706   relocs = hash_find (nds32_hint_hash, name);
   3707   if (relocs == NULL)
   3708     {
   3709       relocs = XNEW (struct nds32_relocs_pattern);
   3710       hash_insert (nds32_hint_hash, name, relocs);
   3711     }
   3712   else
   3713     {
   3714       while (relocs->next)
   3715 	relocs=relocs->next;
   3716       relocs->next = XNEW (struct nds32_relocs_pattern);
   3717       relocs = relocs->next;
   3718     }
   3719 
   3720   relocs->next = NULL;
   3721   *input_line_pointer = saved_char;
   3722   ignore_rest_of_line ();
   3723 
   3724   /* Get the final one of relax hint series.  */
   3725 
   3726   /* It has to build this list because there are maybe more than one
   3727      instructions relative to the same instruction.  It to connect to
   3728      next instruction after md_assemble.  */
   3729   new = XNEW (struct nds32_relocs_group);
   3730   new->pattern = relocs;
   3731   new->next = NULL;
   3732   group = nds32_relax_hint_current;
   3733   if (!group)
   3734     nds32_relax_hint_current = new;
   3735   else
   3736     {
   3737       while (group->next != NULL)
   3738 	group = group->next;
   3739       group->next = new;
   3740     }
   3741   relaxing = TRUE;
   3742 }
   3743 
   3744 /* Decide the size of vector entries, only accepts 4 or 16 now.  */
   3745 
   3746 static void
   3747 nds32_vec_size (int ignore ATTRIBUTE_UNUSED)
   3748 {
   3749   expressionS exp;
   3750 
   3751   expression (&exp);
   3752 
   3753   if (exp.X_op == O_constant)
   3754     {
   3755       if (exp.X_add_number == 4 || exp.X_add_number == 16)
   3756 	{
   3757 	  if (vec_size == 0)
   3758 	    vec_size = exp.X_add_number;
   3759 	  else if (vec_size != exp.X_add_number)
   3760 	    as_warn (_("Different arguments of .vec_size are found, "
   3761 		       "previous %d, current %d"),
   3762 		     (int) vec_size, (int) exp.X_add_number);
   3763 	}
   3764       else
   3765 	as_warn (_("Argument of .vec_size is expected 4 or 16, actual: %d."),
   3766 		 (int) exp.X_add_number);
   3767     }
   3768   else
   3769     as_warn (_("Argument of .vec_size is not a constant."));
   3770 }
   3771 
   3772 /* The behavior of ".flag" directive varies depending on the target.
   3773    In nds32 target, we use it to recognize whether this assembly content is
   3774    generated by compiler.  Other features can also be added in this function
   3775    in the future.  */
   3776 
   3777 static void
   3778 nds32_flag (int ignore ATTRIBUTE_UNUSED)
   3779 {
   3780   char *name;
   3781   char saved_char;
   3782   int i;
   3783   const char *possible_flags[] = { "verbatim" };
   3784 
   3785   /* Skip whitespaces.  */
   3786   name = input_line_pointer;
   3787   while (*input_line_pointer && !ISSPACE (*input_line_pointer))
   3788     input_line_pointer++;
   3789   saved_char = *input_line_pointer;
   3790   *input_line_pointer = 0;
   3791 
   3792   for (i = 0; i < (int) ARRAY_SIZE (possible_flags); i++)
   3793     {
   3794       if (strcmp (name, possible_flags[i]) == 0)
   3795 	{
   3796 	  switch (i)
   3797 	    {
   3798 	    case 0:
   3799 	      /* flag: verbatim */
   3800 	      verbatim = 1;
   3801 	      break;
   3802 	    default:
   3803 	      break;
   3804 	    }
   3805 	  /* Already found the flag, no need to continue next loop.   */
   3806 	  break;
   3807 	}
   3808     }
   3809 
   3810   *input_line_pointer = saved_char;
   3811   ignore_rest_of_line ();
   3812 }
   3813 
   3814 static void
   3815 nds32_n12hc (int ignore ATTRIBUTE_UNUSED)
   3816 {
   3817   /* N1213HC core is used.  */
   3818 }
   3819 
   3820 
   3821 /* The target specific pseudo-ops which we support.  */
   3822 const pseudo_typeS md_pseudo_table[] =
   3823 {
   3824   /* Forced alignment if declared these ways.  */
   3825   {"ascii", stringer, 8 + 0},
   3826   {"asciz", stringer, 8 + 1},
   3827   {"double", nds32_aligned_float_cons, 'd'},
   3828   {"dword", nds32_aligned_cons, 3},
   3829   {"float", nds32_aligned_float_cons, 'f'},
   3830   {"half", nds32_aligned_cons, 1},
   3831   {"hword", nds32_aligned_cons, 1},
   3832   {"int", nds32_aligned_cons, 2},
   3833   {"long", nds32_aligned_cons, 2},
   3834   {"octa", nds32_aligned_cons, 4},
   3835   {"quad", nds32_aligned_cons, 3},
   3836   {"qword", nds32_aligned_cons, 4},
   3837   {"short", nds32_aligned_cons, 1},
   3838   {"byte", nds32_aligned_cons, 0},
   3839   {"single", nds32_aligned_float_cons, 'f'},
   3840   {"string", stringer, 8 + 1},
   3841   {"word", nds32_aligned_cons, 2},
   3842 
   3843   {"little", set_endian_little, 1},
   3844   {"big", set_endian_little, 0},
   3845   {"16bit_on", trigger_16bit, 1},
   3846   {"16bit_off", trigger_16bit, 0},
   3847   {"restore_16bit", restore_16bit, 0},
   3848   {"off_16bit", off_16bit, 0},
   3849 
   3850   {"sdata_d", nds32_seg, SDATA_D_SECTION},
   3851   {"sdata_w", nds32_seg, SDATA_W_SECTION},
   3852   {"sdata_h", nds32_seg, SDATA_H_SECTION},
   3853   {"sdata_b", nds32_seg, SDATA_B_SECTION},
   3854   {"sdata_f", nds32_seg, SDATA_F_SECTION},
   3855 
   3856   {"sbss_d", nds32_seg, SBSS_D_SECTION},
   3857   {"sbss_w", nds32_seg, SBSS_W_SECTION},
   3858   {"sbss_h", nds32_seg, SBSS_H_SECTION},
   3859   {"sbss_b", nds32_seg, SBSS_B_SECTION},
   3860   {"sbss_f", nds32_seg, SBSS_F_SECTION},
   3861 
   3862   {"pic", nds32_enable_pic, 0},
   3863   {"n12_hc", nds32_n12hc, 0},
   3864   {"abi_1", nds32_set_abi, E_NDS_ABI_V1},
   3865   {"abi_2", nds32_set_abi, E_NDS_ABI_AABI},
   3866   /* Obsolete.  */
   3867   {"abi_2fp", nds32_set_abi, E_NDS_ABI_V2FP},
   3868   {"abi_2fp_plus", nds32_set_abi, E_NDS_ABI_V2FP_PLUS},
   3869   {"relax", nds32_relax_relocs, 1},
   3870   {"no_relax", nds32_relax_relocs, 0},
   3871   {"hint_func_args", nds32_set_hint_func_args, 0}, /* Abandon??  */
   3872   {"omit_fp_begin", nds32_omit_fp_begin, 1},
   3873   {"omit_fp_end", nds32_omit_fp_begin, 0},
   3874   {"no_ex9_begin", nds32_no_ex9_begin, 1},
   3875   {"no_ex9_end", nds32_no_ex9_begin, 0},
   3876   {"vec_size", nds32_vec_size, 0},
   3877   {"flag", nds32_flag, 0},
   3878   {"innermost_loop_begin", nds32_loop_begin, 1},
   3879   {"innermost_loop_end", nds32_loop_begin, 0},
   3880   {"relax_hint", nds32_relax_hint, 0},
   3881   {NULL, NULL, 0}
   3882 };
   3883 
   3884 void
   3885 nds32_pre_do_align (int n, char *fill, int len, int max)
   3886 {
   3887   /* Only make a frag if we HAVE to...  */
   3888   fragS *fragP;
   3889   if (n != 0 && !need_pass_2)
   3890     {
   3891       if (fill == NULL)
   3892 	{
   3893 	  if (subseg_text_p (now_seg))
   3894 	    {
   3895 	      dwarf2_emit_insn (0);
   3896 	      fragP = frag_now;
   3897 	      frag_align_code (n, max);
   3898 
   3899 	      /* Tag this alignment when there is a lable before it.  */
   3900 	      if (label_exist)
   3901 		{
   3902 		  fragP->tc_frag_data.flag = NDS32_FRAG_LABEL;
   3903 		  label_exist = 0;
   3904 		}
   3905 	    }
   3906 	  else
   3907 	    frag_align (n, 0, max);
   3908 	}
   3909       else if (len <= 1)
   3910 	frag_align (n, *fill, max);
   3911       else
   3912 	frag_align_pattern (n, fill, len, max);
   3913     }
   3914 }
   3915 
   3916 void
   3917 nds32_do_align (int n)
   3918 {
   3919   /* Optimize for space and label exists.  */
   3920   expressionS exp;
   3921 
   3922   /* FIXME:I think this will break debug info sections and except_table.  */
   3923   if (!enable_relax_relocs || !subseg_text_p (now_seg))
   3924     return;
   3925 
   3926   /* Create and attach a BFD_RELOC_NDS32_LABEL fixup
   3927      the size of instruction may not be correct because
   3928      it could be relaxable.  */
   3929   exp.X_op = O_symbol;
   3930   exp.X_add_symbol = section_symbol (now_seg);
   3931   exp.X_add_number = n;
   3932   fix_new_exp (frag_now,
   3933 	       frag_now_fix (), 0, &exp, 0, BFD_RELOC_NDS32_LABEL);
   3934 }
   3935 
   3936 /* Supported Andes machines.  */
   3937 struct nds32_machs
   3938 {
   3939   enum bfd_architecture bfd_mach;
   3940   int mach_flags;
   3941 };
   3942 
   3943 /* This is the callback for nds32-asm.c to parse operands.  */
   3944 
   3945 int
   3946 nds32_asm_parse_operand (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
   3947 			 struct nds32_asm_insn *pinsn,
   3948 			 char **pstr, int64_t *value)
   3949 {
   3950   char *hold;
   3951   expressionS *pexp = pinsn->info;
   3952 
   3953   hold = input_line_pointer;
   3954   input_line_pointer = *pstr;
   3955   expression (pexp);
   3956   *pstr = input_line_pointer;
   3957   input_line_pointer = hold;
   3958 
   3959   switch (pexp->X_op)
   3960     {
   3961     case O_symbol:
   3962       *value = 0;
   3963       return NASM_R_SYMBOL;
   3964     case O_constant:
   3965       *value = pexp->X_add_number;
   3966       return NASM_R_CONST;
   3967     case O_illegal:
   3968     case O_absent:
   3969     case O_register:
   3970     default:
   3971       return NASM_R_ILLEGAL;
   3972     }
   3973 }
   3974 
   3975 /* GAS will call this function at the start of the assembly, after the command
   3976    line arguments have been parsed and all the machine independent
   3977    initializations have been completed.  */
   3978 
   3979 void
   3980 md_begin (void)
   3981 {
   3982   struct nds32_keyword *k;
   3983   unsigned int i;
   3984 
   3985   bfd_set_arch_mach (stdoutput, TARGET_ARCH, nds32_baseline);
   3986 
   3987   nds32_init_nds32_pseudo_opcodes ();
   3988   asm_desc.parse_operand = nds32_asm_parse_operand;
   3989   nds32_asm_init (&asm_desc, 0);
   3990 
   3991   /* Initial general pupose registers hash table.  */
   3992   nds32_gprs_hash = hash_new ();
   3993   for (k = keyword_gpr; k->name; k++)
   3994     hash_insert (nds32_gprs_hash, k->name, k);
   3995 
   3996   /* Initial branch hash table.  */
   3997   nds32_relax_info_hash = hash_new ();
   3998   for (i = 0; i < ARRAY_SIZE (relax_table); i++)
   3999     hash_insert (nds32_relax_info_hash, relax_table[i].opcode,
   4000 		 &relax_table[i]);
   4001 
   4002   /* Initial relax hint hash table.  */
   4003   nds32_hint_hash = hash_new ();
   4004   enable_16bit = nds32_16bit_ext;
   4005 }
   4006 
   4007 /* HANDLE_ALIGN in write.c.  */
   4008 
   4009 void
   4010 nds32_handle_align (fragS *fragp)
   4011 {
   4012   static const unsigned char nop16[] = { 0x92, 0x00 };
   4013   static const unsigned char nop32[] = { 0x40, 0x00, 0x00, 0x09 };
   4014   int bytes;
   4015   char *p;
   4016 
   4017   if (fragp->fr_type != rs_align_code)
   4018     return;
   4019 
   4020   bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
   4021   p = fragp->fr_literal + fragp->fr_fix;
   4022 
   4023   if (bytes & 1)
   4024     {
   4025       *p++ = 0;
   4026       bytes--;
   4027     }
   4028 
   4029   if (bytes & 2)
   4030     {
   4031       expressionS exp_t;
   4032       exp_t.X_op = O_symbol;
   4033       exp_t.X_add_symbol = abs_section_sym;
   4034       exp_t.X_add_number = R_NDS32_INSN16_CONVERT_FLAG;
   4035       fix_new_exp (fragp, fragp->fr_fix, 2, &exp_t, 0,
   4036 		   BFD_RELOC_NDS32_INSN16);
   4037       memcpy (p, nop16, 2);
   4038       p += 2;
   4039       bytes -= 2;
   4040     }
   4041 
   4042   while (bytes >= 4)
   4043     {
   4044       memcpy (p, nop32, 4);
   4045       p += 4;
   4046       bytes -= 4;
   4047     }
   4048 
   4049   bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
   4050   fragp->fr_fix += bytes;
   4051 }
   4052 
   4053 /* md_flush_pending_output  */
   4054 
   4055 void
   4056 nds32_flush_pending_output (void)
   4057 {
   4058   nds32_last_label = NULL;
   4059 }
   4060 
   4061 void
   4062 nds32_frob_label (symbolS *label)
   4063 {
   4064   dwarf2_emit_label (label);
   4065 }
   4066 
   4067 /* TC_START_LABEL  */
   4068 
   4069 int
   4070 nds32_start_label (int asmdone ATTRIBUTE_UNUSED, int secdone ATTRIBUTE_UNUSED)
   4071 {
   4072   if (optimize && subseg_text_p (now_seg))
   4073     label_exist = 1;
   4074   return 1;
   4075 }
   4076 
   4077 /* TARGET_FORMAT  */
   4078 
   4079 const char *
   4080 nds32_target_format (void)
   4081 {
   4082 #ifdef TE_LINUX
   4083   if (target_big_endian)
   4084     return "elf32-nds32be-linux";
   4085   else
   4086     return "elf32-nds32le-linux";
   4087 #else
   4088   if (target_big_endian)
   4089     return "elf32-nds32be";
   4090   else
   4091     return "elf32-nds32le";
   4092 #endif
   4093 }
   4094 
   4095 static enum nds32_br_range
   4096 get_range_type (const struct nds32_field *field)
   4097 {
   4098   gas_assert (field != NULL);
   4099 
   4100   if (field->bitpos != 0)
   4101     return BR_RANGE_U4G;
   4102 
   4103   if (field->bitsize == 24 && field->shift == 1)
   4104     return BR_RANGE_S16M;
   4105   else if (field->bitsize == 16 && field->shift == 1)
   4106     return BR_RANGE_S64K;
   4107   else if (field->bitsize == 14 && field->shift == 1)
   4108     return BR_RANGE_S16K;
   4109   else if (field->bitsize == 8 && field->shift == 1)
   4110     return BR_RANGE_S256;
   4111   else
   4112     return BR_RANGE_U4G;
   4113 }
   4114 
   4115 /* Save pseudo instruction relocation list.  */
   4116 
   4117 static struct nds32_relocs_pattern*
   4118 nds32_elf_save_pseudo_pattern (fixS* fixP, struct nds32_opcode *opcode,
   4119 			       char *out, symbolS *sym,
   4120 			       struct nds32_relocs_pattern *reloc_ptr,
   4121 			       fragS *fragP)
   4122 {
   4123   if (!reloc_ptr)
   4124     reloc_ptr = XNEW (struct nds32_relocs_pattern);
   4125   reloc_ptr->seg = now_seg;
   4126   reloc_ptr->sym = sym;
   4127   reloc_ptr->frag = fragP;
   4128   reloc_ptr->frchain = frchain_now;
   4129   reloc_ptr->fixP = fixP;
   4130   reloc_ptr->opcode = opcode;
   4131   reloc_ptr->where = out;
   4132   reloc_ptr->next = NULL;
   4133   return reloc_ptr;
   4134 }
   4135 
   4136 /* Check X_md to transform relocation.  */
   4137 
   4138 static fixS*
   4139 nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
   4140 			    const struct nds32_field *fld,
   4141 			    expressionS *pexp, char* out,
   4142 			    struct nds32_asm_insn *insn)
   4143 {
   4144   int reloc = -1;
   4145   expressionS exp;
   4146   fixS *fixP = NULL;
   4147 
   4148   /* Handle instruction relocation.  */
   4149   if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_HI20))
   4150     {
   4151       /* Relocation for hi20 modifier.  */
   4152       switch (pexp->X_md)
   4153 	{
   4154 	case BFD_RELOC_NDS32_GOTOFF:	/* @GOTOFF */
   4155 	  reloc = BFD_RELOC_NDS32_GOTOFF_HI20;
   4156 	  break;
   4157 	case BFD_RELOC_NDS32_GOT20:	/* @GOT */
   4158 	  reloc = BFD_RELOC_NDS32_GOT_HI20;
   4159 	  break;
   4160 	case BFD_RELOC_NDS32_25_PLTREL:	/* @PLT */
   4161 	  if (!nds32_pic)
   4162 	    as_bad (_("Invalid PIC expression."));
   4163 	  else
   4164 	    reloc = BFD_RELOC_NDS32_PLT_GOTREL_HI20;
   4165 	  break;
   4166 	case BFD_RELOC_NDS32_GOTPC20:	/* _GLOBAL_OFFSET_TABLE_ */
   4167 	  reloc = BFD_RELOC_NDS32_GOTPC_HI20;
   4168 	  break;
   4169 	case BFD_RELOC_NDS32_TPOFF:	/* @TPOFF */
   4170 	  reloc = BFD_RELOC_NDS32_TLS_LE_HI20;
   4171 	  break;
   4172 	case BFD_RELOC_NDS32_GOTTPOFF:	/* @GOTTPOFF */
   4173 	  reloc = BFD_RELOC_NDS32_TLS_IE_HI20;
   4174 	  break;
   4175 	default:	/* No suffix.  */
   4176 	  reloc = BFD_RELOC_NDS32_HI20;
   4177 	  break;
   4178 	}
   4179       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
   4180 			  insn->info, 0 /* pcrel */, reloc);
   4181     }
   4182   else if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_LO12))
   4183     {
   4184       /* Relocation for lo12 modifier.  */
   4185       if (fld->bitsize == 15 && fld->shift == 0)
   4186 	{
   4187 	  /* [ls]bi || ori */
   4188 	  switch (pexp->X_md)
   4189 	    {
   4190 	    case BFD_RELOC_NDS32_GOTOFF:	/* @GOTOFF */
   4191 	      reloc = BFD_RELOC_NDS32_GOTOFF_LO12;
   4192 	      break;
   4193 	    case BFD_RELOC_NDS32_GOT20:		/* @GOT */
   4194 	      reloc = BFD_RELOC_NDS32_GOT_LO12;
   4195 	      break;
   4196 	    case BFD_RELOC_NDS32_25_PLTREL:	/* @PLT */
   4197 	      if (!nds32_pic)
   4198 		as_bad (_("Invalid PIC expression."));
   4199 	      else
   4200 		reloc = BFD_RELOC_NDS32_PLT_GOTREL_LO12;
   4201 	      break;
   4202 	    case BFD_RELOC_NDS32_GOTPC20:	/* _GLOBAL_OFFSET_TABLE_ */
   4203 	      reloc = BFD_RELOC_NDS32_GOTPC_LO12;
   4204 	      break;
   4205 	    case BFD_RELOC_NDS32_TPOFF:		/* @TPOFF */
   4206 	      reloc = BFD_RELOC_NDS32_TLS_LE_LO12;
   4207 	      break;
   4208 	    default:	/* No suffix.  */
   4209 	      reloc = BFD_RELOC_NDS32_LO12S0;
   4210 	      break;
   4211 	    }
   4212 	}
   4213       else if (fld->bitsize == 15 && fld->shift == 1)
   4214 	reloc = BFD_RELOC_NDS32_LO12S1;		/* [ls]hi */
   4215       else if (fld->bitsize == 15 && fld->shift == 2)
   4216 	{
   4217 	  /* [ls]wi */
   4218 	  switch (pexp->X_md)
   4219 	    {
   4220 	    case BFD_RELOC_NDS32_GOTTPOFF:	/* @GOTTPOFF */
   4221 	      reloc = BFD_RELOC_NDS32_TLS_IE_LO12S2;
   4222 	      break;
   4223 	    default:	/* No suffix.  */
   4224 	      reloc = BFD_RELOC_NDS32_LO12S2;
   4225 	      break;
   4226 	    }
   4227 	}
   4228       else if (fld->bitsize == 15 && fld->shift == 3)
   4229 	reloc = BFD_RELOC_NDS32_LO12S3;		/* [ls]di */
   4230       else if (fld->bitsize == 12 && fld->shift == 2)
   4231 	reloc = R_NDS32_LO12S2_SP_RELA;		/* f[ls][sd]i */
   4232 
   4233       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
   4234 			  insn->info, 0 /* pcrel */, reloc);
   4235     }
   4236   else if (fld && fld->bitpos == 0 && insn->opcode->isize == 4
   4237 	   && (insn->attr & NASM_ATTR_PCREL))
   4238     {
   4239       /* Relocation for 32-bit branch instructions.  */
   4240       if (fld->bitsize == 24 && fld->shift == 1)
   4241 	reloc = BFD_RELOC_NDS32_25_PCREL;
   4242       else if (fld->bitsize == 16 && fld->shift == 1)
   4243 	reloc = BFD_RELOC_NDS32_17_PCREL;
   4244       else if (fld->bitsize == 14 && fld->shift == 1)
   4245 	reloc = BFD_RELOC_NDS32_15_PCREL;
   4246       else if (fld->bitsize == 8 && fld->shift == 1)
   4247 	reloc = BFD_RELOC_NDS32_WORD_9_PCREL;
   4248       else
   4249 	abort ();
   4250 
   4251       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
   4252 		   insn->info, 1 /* pcrel */, reloc);
   4253     }
   4254   else if (fld && fld->bitpos == 0 && insn->opcode->isize == 4
   4255 	   && (insn->attr & NASM_ATTR_GPREL))
   4256     {
   4257       /* Relocation for 32-bit gp-relative instructions.  */
   4258       if (fld->bitsize == 19 && fld->shift == 0)
   4259 	reloc = BFD_RELOC_NDS32_SDA19S0;
   4260       else if (fld->bitsize == 18 && fld->shift == 1)
   4261 	reloc = BFD_RELOC_NDS32_SDA18S1;
   4262       else if (fld->bitsize == 17 && fld->shift == 2)
   4263 	reloc = BFD_RELOC_NDS32_SDA17S2;
   4264       else
   4265 	abort ();
   4266 
   4267       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
   4268 		   insn->info, 0 /* pcrel */, reloc);
   4269       /* Insert INSN16 for converting fp_as_gp.  */
   4270       exp.X_op = O_symbol;
   4271       exp.X_add_symbol = abs_section_sym;
   4272       exp.X_add_number = 0;
   4273       if (in_omit_fp && reloc == BFD_RELOC_NDS32_SDA17S2)
   4274 	fix_new_exp (fragP, out - fragP->fr_literal,
   4275 		     insn->opcode->isize, &exp, 0 /* pcrel */,
   4276 		     BFD_RELOC_NDS32_INSN16);
   4277     }
   4278   else if (fld && fld->bitpos == 0 && insn->opcode->isize == 2
   4279 	   && (insn->attr & NASM_ATTR_PCREL))
   4280     {
   4281       /* Relocation for 16-bit branch instructions.  */
   4282       if (fld->bitsize == 8 && fld->shift == 1)
   4283 	reloc = BFD_RELOC_NDS32_9_PCREL;
   4284       else
   4285 	abort ();
   4286 
   4287       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
   4288 		   insn->info, 1 /* pcrel */, reloc);
   4289     }
   4290   else if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_IFC_EXT))
   4291     {
   4292       /* Relocation for ifcall instruction.  */
   4293       if (insn->opcode->isize == 2 && fld->bitsize == 9 && fld->shift == 1)
   4294 	reloc = BFD_RELOC_NDS32_10IFCU_PCREL;
   4295       else if (insn->opcode->isize == 4 && fld->bitsize == 16
   4296 	       && fld->shift == 1)
   4297 	reloc = BFD_RELOC_NDS32_17IFC_PCREL;
   4298       else
   4299 	abort ();
   4300 
   4301       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
   4302 		   insn->info, 1 /* pcrel */, reloc);
   4303     }
   4304   else if (fld)
   4305     as_bad (_("Don't know how to handle this field. %s"), str);
   4306 
   4307   return fixP;
   4308 }
   4309 
   4310 /* Build instruction pattern to relax.  There are two type group pattern
   4311    including pseudo instruction and relax hint.  */
   4312 
   4313 static void
   4314 nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out,
   4315 				struct nds32_opcode *opcode, fragS *fragP,
   4316 				const struct nds32_field *fld)
   4317 {
   4318   struct nds32_relocs_pattern *reloc_ptr;
   4319   struct nds32_relocs_group *group;
   4320   symbolS *sym = NULL;
   4321 
   4322   /* The expression may be used uninitialized.  */
   4323   if (fld)
   4324     sym = pexp->X_add_symbol;
   4325 
   4326   if (pseudo_opcode)
   4327     {
   4328       /* Save instruction relation for pseudo instruction expanding pattern.  */
   4329       reloc_ptr = nds32_elf_save_pseudo_pattern (fixP, opcode, out, sym,
   4330 						 NULL, fragP);
   4331       if (!relocs_list)
   4332 	relocs_list = reloc_ptr;
   4333       else
   4334 	{
   4335 	  struct nds32_relocs_pattern *temp = relocs_list;
   4336 	  while (temp->next)
   4337 	    temp = temp->next;
   4338 	  temp->next = reloc_ptr;
   4339 	}
   4340     }
   4341   else if (nds32_relax_hint_current)
   4342     {
   4343       /* Save instruction relation by relax hint.  */
   4344       group = nds32_relax_hint_current;
   4345       while (group)
   4346 	{
   4347 	  nds32_elf_save_pseudo_pattern (fixP, opcode, out, sym,
   4348 					 group->pattern, fragP);
   4349 	  group = group->next;
   4350 	  free (nds32_relax_hint_current);
   4351 	  nds32_relax_hint_current = group;
   4352 	}
   4353     }
   4354 
   4355   /* Set relaxing false only for relax_hint trigger it.  */
   4356   if (!pseudo_opcode)
   4357     relaxing = FALSE;
   4358 }
   4359 
   4360 #define N32_MEM_EXT(insn) ((N32_OP6_MEM << 25) | insn)
   4361 
   4362 /* Relax pattern for link time relaxation.  */
   4363 
   4364 static struct nds32_relax_hint_table relax_ls_table[] =
   4365 {
   4366   {
   4367     /* Set address: la -> sethi ori.  */
   4368     NDS32_RELAX_HINT_LA,	/* main_type */
   4369     8,				/* relax_code_size */
   4370     {
   4371       OP6 (SETHI),
   4372       OP6 (ORI),
   4373     },				/* relax_code_seq */
   4374     {
   4375       {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
   4376       {4, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_INSN16}
   4377     }				/* relax_fixup */
   4378   },
   4379   {
   4380     /* Set address: l.w -> sethi ori.  */
   4381     NDS32_RELAX_HINT_LS,	/* main_type */
   4382     8,				/* relax_code_size */
   4383     {
   4384       OP6 (SETHI),
   4385       OP6 (LBI),
   4386     },				/* relax_code_seq */
   4387     {
   4388       {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
   4389       {4, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_INSN16}
   4390     }				/* relax_fixup */
   4391   },
   4392   {
   4393     0,
   4394     0,
   4395     {0},
   4396     {{0, 0 , 0, 0}}
   4397   }
   4398 };
   4399 
   4400 /* Since sethi loadstore relocation has to using next instruction to determine
   4401    elimination itself or not, we have to return the next instruction range.  */
   4402 
   4403 static int
   4404 nds32_elf_sethi_range (struct nds32_relocs_pattern *pattern)
   4405 {
   4406   int range = 0;
   4407   while (pattern)
   4408     {
   4409       switch (pattern->opcode->value)
   4410 	{
   4411 	case INSN_LBI:
   4412 	case INSN_SBI:
   4413 	case INSN_LBSI:
   4414 	case N32_MEM_EXT (N32_MEM_LB):
   4415 	case N32_MEM_EXT (N32_MEM_LBS):
   4416 	case N32_MEM_EXT (N32_MEM_SB):
   4417 	  range = NDS32_LOADSTORE_BYTE;
   4418 	  break;
   4419 	case INSN_LHI:
   4420 	case INSN_SHI:
   4421 	case INSN_LHSI:
   4422 	case N32_MEM_EXT (N32_MEM_LH):
   4423 	case N32_MEM_EXT (N32_MEM_LHS):
   4424 	case N32_MEM_EXT (N32_MEM_SH):
   4425 	  range = NDS32_LOADSTORE_HALF;
   4426 	  break;
   4427 	case INSN_LWI:
   4428 	case INSN_SWI:
   4429 	case N32_MEM_EXT (N32_MEM_LW):
   4430 	case N32_MEM_EXT (N32_MEM_SW):
   4431 	  range = NDS32_LOADSTORE_WORD;
   4432 	  break;
   4433 	case INSN_FLSI:
   4434 	case INSN_FSSI:
   4435 	  range = NDS32_LOADSTORE_FLOAT_S;
   4436 	  break;
   4437 	case INSN_FLDI:
   4438 	case INSN_FSDI:
   4439 	  range = NDS32_LOADSTORE_FLOAT_D;
   4440 	  break;
   4441 	case INSN_ORI:
   4442 	  range = NDS32_LOADSTORE_IMM;
   4443 	  break;
   4444 	default:
   4445 	  range = NDS32_LOADSTORE_NONE;
   4446 	  break;
   4447 	}
   4448       if (range != NDS32_LOADSTORE_NONE)
   4449 	break;
   4450       pattern = pattern->next;
   4451     }
   4452   return range;
   4453 }
   4454 
   4455 /* The args means: instruction size, the 1st instruction is converted to 16 or
   4456    not, optimize option, 16 bit instruction is enable.  */
   4457 #define SET_ADDEND(size, convertible, optimize, insn16_on) \
   4458   (((size) & 0xff) | ((convertible) ? 1 << 31 : 0) \
   4459    | ((optimize) ? 1<< 30 : 0) | (insn16_on ? 1 << 29 : 0))
   4460 
   4461 static void
   4462 nds32_set_elf_flags_by_insn (struct nds32_asm_insn * insn)
   4463 {
   4464   /* Set E_NDS32_HAS_EXT_INST.  */
   4465   if (insn->opcode->attr & NASM_ATTR_PERF_EXT)
   4466     {
   4467       if (nds32_perf_ext)
   4468 	nds32_elf_flags |= E_NDS32_HAS_EXT_INST;
   4469       else
   4470 	as_bad (_("instruction %s requires enabling performance extension"),
   4471 		insn->opcode->opcode);
   4472     }
   4473   else if (insn->opcode->attr & NASM_ATTR_PERF2_EXT)
   4474     {
   4475       if (nds32_perf_ext2)
   4476 	nds32_elf_flags |= E_NDS32_HAS_EXT2_INST;
   4477       else
   4478 	as_bad (_("instruction %s requires enabling performance extension II"),
   4479 		insn->opcode->opcode);
   4480     }
   4481   else if (insn->opcode->attr & NASM_ATTR_AUDIO_ISAEXT)
   4482     {
   4483       if (nds32_audio_ext)
   4484 	nds32_elf_flags |= E_NDS32_HAS_AUDIO_INST;
   4485       else
   4486 	as_bad (_("instruction %s requires enabling AUDIO extension"),
   4487 		insn->opcode->opcode);
   4488     }
   4489   else if (insn->opcode->attr & NASM_ATTR_STR_EXT)
   4490     {
   4491       if (nds32_string_ext)
   4492 	nds32_elf_flags |= E_NDS32_HAS_STRING_INST;
   4493       else
   4494 	as_bad (_("instruction %s requires enabling STRING extension"),
   4495 		insn->opcode->opcode);
   4496     }
   4497   else if ((insn->opcode->attr & NASM_ATTR_DIV)
   4498 	   && (insn->opcode->attr & NASM_ATTR_DXREG))
   4499     {
   4500       if (nds32_div && nds32_dx_regs)
   4501 	nds32_elf_flags |= E_NDS32_HAS_DIV_DX_INST;
   4502       else
   4503 	as_bad (_("instruction %s requires enabling DIV & DX_REGS extension"),
   4504 		insn->opcode->opcode);
   4505     }
   4506   else if (insn->opcode->attr & NASM_ATTR_FPU)
   4507     {
   4508       if (nds32_fpu_sp_ext || nds32_fpu_dp_ext)
   4509 	{
   4510 	  if (!(nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
   4511 	    nds32_fpu_com = 1;
   4512 	}
   4513       else
   4514 	as_bad (_("instruction %s requires enabling FPU extension"),
   4515 		insn->opcode->opcode);
   4516     }
   4517   else if (insn->opcode->attr & NASM_ATTR_FPU_SP_EXT)
   4518     {
   4519       if (nds32_fpu_sp_ext)
   4520 	nds32_elf_flags |= E_NDS32_HAS_FPU_INST;
   4521       else
   4522 	as_bad (_("instruction %s requires enabling FPU_SP extension"),
   4523 		insn->opcode->opcode);
   4524     }
   4525   else if ((insn->opcode->attr & NASM_ATTR_FPU_SP_EXT)
   4526 	   && (insn->opcode->attr & NASM_ATTR_MAC))
   4527     {
   4528       if (nds32_fpu_sp_ext && nds32_mac)
   4529 	{
   4530 	  nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
   4531 	  nds32_elf_flags |= E_NDS32_HAS_FPU_INST;
   4532 	}
   4533       else
   4534 	as_bad (_("instruction %s requires enabling FPU_MAC extension"),
   4535 		insn->opcode->opcode);
   4536     }
   4537   else if (insn->opcode->attr & NASM_ATTR_FPU_DP_EXT)
   4538     {
   4539       if (nds32_fpu_dp_ext)
   4540 	nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST;
   4541       else
   4542 	as_bad (_("instruction %s requires enabling FPU_DP extension"),
   4543 		insn->opcode->opcode);
   4544     }
   4545   else if ((insn->opcode->attr & NASM_ATTR_FPU_DP_EXT)
   4546 	   && (insn->opcode->attr & NASM_ATTR_MAC))
   4547     {
   4548       if (nds32_fpu_dp_ext && nds32_mac)
   4549 	{
   4550 	  nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
   4551 	  nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST;
   4552 	}
   4553       else
   4554 	as_bad (_("instruction %s requires enabling FPU_MAC extension"),
   4555 		insn->opcode->opcode);
   4556     }
   4557   /* TODO: FPU_BOTH */
   4558   else if ((insn->opcode->attr & NASM_ATTR_MAC)
   4559 	   && (insn->opcode->attr & NASM_ATTR_DXREG))
   4560     {
   4561       if (nds32_mac && nds32_dx_regs)
   4562 	nds32_elf_flags |= E_NDS32_HAS_MAC_DX_INST;
   4563       else
   4564 	as_bad (_("instruction %s requires enabling DX_REGS extension"),
   4565 		insn->opcode->opcode);
   4566     }
   4567   /* TODO: for DX_REG set but not for MAC, DIV, AUDIO */
   4568   else if (insn->opcode->attr & NASM_ATTR_IFC_EXT)
   4569     {
   4570       nds32_elf_flags |= E_NDS32_HAS_IFC_INST;
   4571     }
   4572   /* TODO: E_NDS32_HAS_SATURATION_INST */
   4573 }
   4574 
   4575 /* Flag for analysis relaxation type.  */
   4576 
   4577 enum nds32_insn_type
   4578 {
   4579   N32_RELAX_SETHI = 1,
   4580   N32_RELAX_BR = (1 << 1),
   4581   N32_RELAX_LSI = (1 << 2),
   4582   N32_RELAX_JUMP = (1 << 3),
   4583   N32_RELAX_CALL = (1 << 4),
   4584   N32_RELAX_ORI = (1 << 5),
   4585   N32_RELAX_MEM = (1 << 6),
   4586   N32_RELAX_MOVI = (1 << 7),
   4587 };
   4588 
   4589 struct nds32_hint_map
   4590 {
   4591   bfd_reloc_code_real_type hi_type;
   4592   const char *opc;
   4593   enum nds32_relax_hint_type hint_type;
   4594   enum nds32_br_range range;
   4595   enum nds32_insn_type insn_list;
   4596 };
   4597 
   4598 /* Table to match instructions with hint and relax pattern.  */
   4599 
   4600 static struct nds32_hint_map hint_map [] =
   4601 {
   4602     {
   4603       /* LONGCALL4.  */
   4604       BFD_RELOC_NDS32_HI20,
   4605       "jal",
   4606       NDS32_RELAX_HINT_NONE,
   4607       BR_RANGE_U4G,
   4608       N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL
   4609     },
   4610     {
   4611       /* LONGCALL5.  */
   4612       _dummy_first_bfd_reloc_code_real,
   4613       "bgezal",
   4614       NDS32_RELAX_HINT_NONE,
   4615       BR_RANGE_S16M,
   4616       N32_RELAX_BR | N32_RELAX_CALL
   4617     },
   4618     {
   4619       /* LONGCALL6.  */
   4620       BFD_RELOC_NDS32_HI20,
   4621       "bgezal",
   4622       NDS32_RELAX_HINT_NONE,
   4623       BR_RANGE_U4G,
   4624       N32_RELAX_BR | N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL
   4625     },
   4626     {
   4627       /* LONGJUMP4.  */
   4628       BFD_RELOC_NDS32_HI20,
   4629       "j",
   4630       NDS32_RELAX_HINT_NONE,
   4631       BR_RANGE_U4G,
   4632       N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_JUMP
   4633     },
   4634     {
   4635       /* LONGJUMP5.  */
   4636       /* There is two kinds of veriation of LONGJUMP5.  One of them
   4637 	 generate EMPTY relocation for converted INSN16 if needed.
   4638 	 But we don't distinguish them here.  */
   4639       _dummy_first_bfd_reloc_code_real,
   4640       "beq",
   4641       NDS32_RELAX_HINT_NONE,
   4642       BR_RANGE_S16M,
   4643       N32_RELAX_BR | N32_RELAX_JUMP
   4644     },
   4645     {
   4646       /* LONGJUMP6.  */
   4647       BFD_RELOC_NDS32_HI20,
   4648       "beq",
   4649       NDS32_RELAX_HINT_NONE,
   4650       BR_RANGE_U4G,
   4651       N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_BR | N32_RELAX_JUMP
   4652     },
   4653     {
   4654       /* LONGJUMP7.  */
   4655       _dummy_first_bfd_reloc_code_real,
   4656       "beqc",
   4657       NDS32_RELAX_HINT_NONE,
   4658       BR_RANGE_S16K,
   4659       N32_RELAX_MOVI | N32_RELAX_BR
   4660     },
   4661     {
   4662       /* LOADSTORE ADDRESS.  */
   4663       BFD_RELOC_NDS32_HI20,
   4664       NULL,
   4665       NDS32_RELAX_HINT_LA,
   4666       BR_RANGE_U4G,
   4667       N32_RELAX_SETHI | N32_RELAX_ORI
   4668     },
   4669     {
   4670       /* LOADSTORE ADDRESS.  */
   4671       BFD_RELOC_NDS32_HI20,
   4672       NULL,
   4673       NDS32_RELAX_HINT_LS,
   4674       BR_RANGE_U4G,
   4675       N32_RELAX_SETHI | N32_RELAX_LSI
   4676     },
   4677     {0, NULL, 0, 0 ,0}
   4678 };
   4679 
   4680 /* Find the relaxation pattern according to instructions.  */
   4681 
   4682 static bfd_boolean
   4683 nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern,
   4684 			struct nds32_relax_hint_table *hint_info)
   4685 {
   4686   unsigned int opcode, seq_size;
   4687   enum nds32_br_range range;
   4688   struct nds32_relocs_pattern *pattern, *hi_pattern = NULL;
   4689   const char *opc = NULL;
   4690   relax_info_t *relax_info = NULL;
   4691   nds32_relax_fixup_info_t *fixup_info, *hint_fixup;
   4692   enum nds32_relax_hint_type hint_type = NDS32_RELAX_HINT_NONE;
   4693   struct nds32_relax_hint_table *table_ptr;
   4694   uint32_t *code_seq, *hint_code;
   4695   enum nds32_insn_type relax_type = 0;
   4696   struct nds32_hint_map *map_ptr = hint_map;
   4697   unsigned int i;
   4698   const char *check_insn[] =
   4699     { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" };
   4700 
   4701   /* TODO: PLT GOT.  */
   4702   /* Traverse all pattern instruction and set flag.  */
   4703   pattern = relocs_pattern;
   4704   while (pattern)
   4705     {
   4706       if (pattern->opcode->isize == 4)
   4707 	{
   4708 	  /* 4 byte instruction.  */
   4709 	  opcode = N32_OP6 (pattern->opcode->value);
   4710 	  switch (opcode)
   4711 	    {
   4712 	    case N32_OP6_SETHI:
   4713 	      hi_pattern = pattern;
   4714 	      relax_type |= N32_RELAX_SETHI;
   4715 	      break;
   4716 	    case N32_OP6_MEM:
   4717 	      relax_type |= N32_RELAX_MEM;
   4718 	      break;
   4719 	    case N32_OP6_ORI:
   4720 	      relax_type |= N32_RELAX_ORI;
   4721 	      break;
   4722 	    case N32_OP6_BR1:
   4723 	    case N32_OP6_BR2:
   4724 	    case N32_OP6_BR3:
   4725 	      relax_type |= N32_RELAX_BR;
   4726 	      break;
   4727 	    case N32_OP6_MOVI:
   4728 	      relax_type |= N32_RELAX_MOVI;
   4729 	      break;
   4730 	    case N32_OP6_LBI:
   4731 	    case N32_OP6_SBI:
   4732 	    case N32_OP6_LBSI:
   4733 	    case N32_OP6_LHI:
   4734 	    case N32_OP6_SHI:
   4735 	    case N32_OP6_LHSI:
   4736 	    case N32_OP6_LWI:
   4737 	    case N32_OP6_SWI:
   4738 	    case N32_OP6_LWC:
   4739 	    case N32_OP6_SWC:
   4740 	      relax_type |= N32_RELAX_LSI;
   4741 	      break;
   4742 	    case N32_OP6_JREG:
   4743 	      if (__GF (pattern->opcode->value, 0, 1) == 1)
   4744 		relax_type |= N32_RELAX_CALL;
   4745 	      else
   4746 		relax_type |= N32_RELAX_JUMP;
   4747 	      break;
   4748 	    case N32_OP6_JI:
   4749 	      if (__GF (pattern->opcode->value, 24, 1) == 1)
   4750 		relax_type |= N32_RELAX_CALL;
   4751 	      else
   4752 		relax_type |= N32_RELAX_JUMP;
   4753 	      break;
   4754 	    default:
   4755 	      as_warn (_("relax hint unrecognized instruction: line %d."),
   4756 		       pattern->frag->fr_line);
   4757 	      return FALSE;
   4758 	    }
   4759 	}
   4760       else
   4761 	{
   4762 	  /* 2 byte instruction.  Compare by opcode name because the opcode of
   4763 	     2byte instruction is not regular.  */
   4764 	  for (i = 0; i < sizeof (check_insn) / sizeof (check_insn[0]); i++)
   4765 	    {
   4766 	      if (strcmp (pattern->opcode->opcode, check_insn[i]) == 0)
   4767 		{
   4768 		  relax_type |= N32_RELAX_BR;
   4769 		  break;
   4770 		}
   4771 	    }
   4772 	  if (strcmp (pattern->opcode->opcode, "movi55") == 0)
   4773 	    relax_type |= N32_RELAX_MOVI;
   4774 	}
   4775       pattern = pattern->next;
   4776     }
   4777 
   4778   /* Analysis instruction flag to choose relaxation table.  */
   4779   while (map_ptr->insn_list != 0)
   4780     {
   4781       if (map_ptr->insn_list == relax_type
   4782 	  && (!hi_pattern
   4783 	      || (hi_pattern->fixP
   4784 		  && hi_pattern->fixP->fx_r_type == map_ptr->hi_type)))
   4785 	{
   4786 	  opc = map_ptr->opc;
   4787 	  hint_type = map_ptr->hint_type;
   4788 	  range = map_ptr->range;
   4789 	  break;
   4790 	}
   4791       map_ptr++;
   4792     }
   4793 
   4794   if (map_ptr->insn_list == 0)
   4795     {
   4796       as_warn (_("Can not find match relax hint. line : %d"),
   4797 	       relocs_pattern->frag->fr_line);
   4798       return FALSE;
   4799     }
   4800 
   4801   /* Get the match table.  */
   4802   if (opc)
   4803     {
   4804       /* Branch relax pattern.  */
   4805       relax_info = hash_find (nds32_relax_info_hash, opc);
   4806       if (!relax_info)
   4807 	return FALSE;
   4808       fixup_info = relax_info->relax_fixup[range];
   4809       code_seq = relax_info->relax_code_seq[range];
   4810       seq_size = relax_info->relax_code_size[range];
   4811     }
   4812   else if (hint_type)
   4813     {
   4814       /* Load-store relax pattern.  */
   4815       table_ptr = relax_ls_table;
   4816       while (table_ptr->main_type != 0)
   4817 	{
   4818 	  if (table_ptr->main_type == hint_type)
   4819 	    {
   4820 	      fixup_info = table_ptr->relax_fixup;
   4821 	      code_seq = table_ptr->relax_code_seq;
   4822 	      seq_size = table_ptr->relax_code_size;
   4823 	      break;
   4824 	    }
   4825 	  table_ptr++;
   4826 	}
   4827       if (table_ptr->main_type == 0)
   4828 	return FALSE;
   4829     }
   4830   else
   4831     return FALSE;
   4832 
   4833   hint_fixup = hint_info->relax_fixup;
   4834   hint_code = hint_info->relax_code_seq;
   4835   hint_info->relax_code_size = seq_size;
   4836 
   4837   while (fixup_info->size != 0)
   4838     {
   4839       if (fixup_info->ramp & NDS32_HINT)
   4840 	{
   4841 	  memcpy (hint_fixup, fixup_info, sizeof (nds32_relax_fixup_info_t));
   4842 	  hint_fixup++;
   4843 	}
   4844       fixup_info++;
   4845     }
   4846   /* Clear final relocation.  */
   4847   memset (hint_fixup, 0, sizeof (nds32_relax_fixup_info_t));
   4848   /* Copy code sequance.  */
   4849   memcpy (hint_code, code_seq, seq_size);
   4850   return TRUE;
   4851 }
   4852 
   4853 /* Because there are a lot of variant of load-store, check
   4854    all these type here.  */
   4855 
   4856 #define CLEAN_REG(insn) ((insn) & 0xff0003ff)
   4857 static bfd_boolean
   4858 nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq)
   4859 {
   4860   const char *check_insn[] =
   4861     { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" };
   4862   uint32_t insn = opcode->value;
   4863   unsigned int i;
   4864 
   4865   insn = CLEAN_REG (opcode->value);
   4866   if (insn == seq)
   4867     return TRUE;
   4868 
   4869   switch (seq)
   4870     {
   4871     case OP6 (LBI):
   4872       /* In relocation_table, it regards instruction LBI as representation
   4873 	 of all the NDS32_RELAX_HINT_LS pattern.  */
   4874       if (insn == OP6 (LBI) || insn == OP6 (SBI) || insn == OP6 (LBSI)
   4875 	  || insn == OP6 (LHI) || insn == OP6 (SHI) || insn == OP6 (LHSI)
   4876 	  || insn == OP6 (LWI) || insn == OP6 (SWI)
   4877 	  || insn == OP6 (LWC) || insn == OP6 (SWC))
   4878 	 return TRUE;
   4879       break;
   4880     case OP6 (BR2):
   4881       /* This is for LONGCALL5 and LONGCALL6.  */
   4882       if (insn == OP6 (BR2))
   4883         return TRUE;
   4884       break;
   4885     case OP6 (BR1):
   4886       /* This is for LONGJUMP5 and LONGJUMP6.  */
   4887       if (opcode->isize == 4
   4888 	  && (insn == OP6 (BR1) || insn == OP6 (BR2) || insn == OP6 (BR3)))
   4889         return TRUE;
   4890       else if (opcode->isize == 2)
   4891 	{
   4892 	  for (i = 0; i < sizeof (check_insn) / sizeof (check_insn[0]); i++)
   4893 	    if (strcmp (opcode->opcode, check_insn[i]) == 0)
   4894 	      return TRUE;
   4895 	}
   4896       break;
   4897     case OP6 (MOVI):
   4898       /* This is for LONGJUMP7.  */
   4899       if (opcode->isize == 2 && strcmp (opcode->opcode, "movi55") == 0)
   4900         return TRUE;
   4901       break;
   4902     }
   4903   return FALSE;
   4904 }
   4905 
   4906 /* Append relax relocation for link time relaxing.  */
   4907 
   4908 static void
   4909 nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
   4910 {
   4911   struct nds32_relocs_pattern *relocs_pattern =
   4912     (struct nds32_relocs_pattern *) value;
   4913   struct nds32_relocs_pattern *pattern_temp, *pattern_now;
   4914   symbolS *sym, *hi_sym = NULL;
   4915   expressionS exp;
   4916   fragS *fragP;
   4917   segT seg_bak = now_seg;
   4918   frchainS *frchain_bak = frchain_now;
   4919   struct nds32_relax_hint_table hint_info;
   4920   nds32_relax_fixup_info_t *hint_fixup, *fixup_now;
   4921   size_t fixup_size;
   4922   offsetT branch_offset;
   4923   fixS *fixP;
   4924   int range, offset;
   4925   unsigned int ptr_offset, hint_count, relax_code_size, count = 0;
   4926   uint32_t *code_seq, code_insn;
   4927   char *where;
   4928   int pcrel;
   4929 
   4930   if (!relocs_pattern)
   4931     return;
   4932 
   4933   if (!nds32_find_reloc_table (relocs_pattern, &hint_info))
   4934     return;
   4935 
   4936   /* Save symbol for some EMPTY relocation using.  */
   4937   pattern_now = relocs_pattern;
   4938   while (pattern_now)
   4939     {
   4940       if (pattern_now->opcode->value == OP6 (SETHI))
   4941 	{
   4942 	  hi_sym = pattern_now->sym;
   4943 	  break;
   4944 	}
   4945       pattern_now = pattern_now->next;
   4946     }
   4947 
   4948   /* Inserting fix up must specify now_seg or frchain_now.  */
   4949   now_seg = relocs_pattern->seg;
   4950   frchain_now = relocs_pattern->frchain;
   4951   fragP = relocs_pattern->frag;
   4952   branch_offset = fragP->fr_offset;
   4953 
   4954   hint_fixup = hint_info.relax_fixup;
   4955   code_seq = hint_info.relax_code_seq;
   4956   relax_code_size = hint_info.relax_code_size;
   4957   pattern_now = relocs_pattern;
   4958 
   4959   /* Insert relaxation.  */
   4960   exp.X_op = O_symbol;
   4961 
   4962   while (pattern_now)
   4963     {
   4964       /* Choose the match fixup by instruction.  */
   4965       code_insn = CLEAN_REG (*(code_seq + count));
   4966       if (!nds32_match_hint_insn (pattern_now->opcode, code_insn))
   4967 	{
   4968 	  count = 0;
   4969 	  code_insn = CLEAN_REG (*(code_seq + count));
   4970 
   4971 	  while (!nds32_match_hint_insn (pattern_now->opcode, code_insn))
   4972 	    {
   4973 	      count++;
   4974 	      if (count >= relax_code_size / 4)
   4975 		{
   4976 		  as_bad (_("Internal error: Relax hint error. %s: %x"),
   4977 			  now_seg->name, pattern_now->opcode->value);
   4978 		  goto restore;
   4979 		}
   4980 	      code_insn = CLEAN_REG (*(code_seq + count));
   4981 	    }
   4982 	}
   4983       fragP = pattern_now->frag;
   4984       sym = pattern_now->sym;
   4985       branch_offset = fragP->fr_offset;
   4986       offset = count * 4;
   4987       where = pattern_now->where;
   4988       /* Find the instruction map fix.  */
   4989       fixup_now = hint_fixup;
   4990       while (fixup_now->offset != offset)
   4991 	{
   4992 	  fixup_now++;
   4993 	  if (fixup_now->size == 0)
   4994 	    break;
   4995 	}
   4996       /* This element is without relaxation relocation.  */
   4997       if (fixup_now->size == 0)
   4998 	{
   4999 	  pattern_now = pattern_now->next;
   5000 	  continue;
   5001 	}
   5002       fixup_size = fixup_now->size;
   5003 
   5004       /* Insert all fixup.  */
   5005       while (fixup_size != 0 && fixup_now->offset == offset)
   5006 	{
   5007 	  /* Set the real instruction size in element.  */
   5008 	  fixup_size = pattern_now->opcode->isize;
   5009 	  pcrel = ((fixup_now->ramp & NDS32_PCREL) != 0) ? 1 : 0;
   5010 	  if (fixup_now->ramp & NDS32_FIX)
   5011 	    {
   5012 	      /* Convert original relocation.  */
   5013 	      pattern_now->fixP->fx_r_type = fixup_now->r_type ;
   5014 	      fixup_size = 0;
   5015 	    }
   5016 	  else if ((fixup_now->ramp & NDS32_PTR) != 0)
   5017 	    {
   5018 	      /* This relocation has to point to another instruction.  Make
   5019 		 sure each resolved relocation has to be pointed.  */
   5020 	      pattern_temp = relocs_pattern;
   5021 	      /* All instruction in relax_table should be 32-bit.  */
   5022 	      hint_count = hint_info.relax_code_size / 4;
   5023 	      code_insn = CLEAN_REG (*(code_seq + hint_count - 1));
   5024 	      while (pattern_temp)
   5025 		{
   5026 		  /* Point to every resolved relocation.  */
   5027 		  if (nds32_match_hint_insn (pattern_temp->opcode, code_insn))
   5028 		    {
   5029 		      ptr_offset =
   5030 			pattern_temp->where - pattern_temp->frag->fr_literal;
   5031 		      exp.X_add_symbol = symbol_temp_new (now_seg, ptr_offset,
   5032 							  pattern_temp->frag);
   5033 		      exp.X_add_number = 0;
   5034 		      fixP =
   5035 			fix_new_exp (fragP, where - fragP->fr_literal,
   5036 				     fixup_size, &exp, 0, fixup_now->r_type);
   5037 		      fixP->fx_addnumber = fixP->fx_offset;
   5038 		    }
   5039 		  pattern_temp = pattern_temp->next;
   5040 		}
   5041 	      fixup_size = 0;
   5042 	    }
   5043 	  else if (fixup_now->ramp & NDS32_ADDEND)
   5044 	    {
   5045 	      range = nds32_elf_sethi_range (relocs_pattern);
   5046 	      if (range == NDS32_LOADSTORE_NONE)
   5047 		{
   5048 		  as_bad (_("Internal error: Range error. %s"), now_seg->name);
   5049 		  return;
   5050 		}
   5051 	      exp.X_add_symbol = abs_section_sym;
   5052 	      exp.X_add_number = SET_ADDEND (4, 0, optimize, enable_16bit);
   5053 	      exp.X_add_number |= ((range & 0x3f) << 8);
   5054 	    }
   5055 	  else if ((fixup_now->ramp & NDS32_ABS) != 0)
   5056 	    {
   5057 	      /* This is a tag relocation.  */
   5058 	      exp.X_add_symbol = abs_section_sym;
   5059 	      exp.X_add_number = 0;
   5060 	    }
   5061 	  else if ((fixup_now->ramp & NDS32_INSN16) != 0)
   5062 	    {
   5063 	      if (!enable_16bit)
   5064 		fixup_size = 0;
   5065 	      /* This is a tag relocation.  */
   5066 	      exp.X_add_symbol = abs_section_sym;
   5067 	      exp.X_add_number = 0;
   5068 	    }
   5069 	  else if ((fixup_now->ramp & NDS32_SYM) != 0)
   5070 	    {
   5071 	      /* For EMPTY relocation save the true symbol.  */
   5072 	      exp.X_add_symbol = hi_sym;
   5073 	      exp.X_add_number = branch_offset;
   5074 	    }
   5075 	  else
   5076 	    {
   5077 	      exp.X_add_symbol = sym;
   5078 	      exp.X_add_number = branch_offset;
   5079 	    }
   5080 
   5081 	  if (fixup_size != 0)
   5082 	    {
   5083 	      fixP = fix_new_exp (fragP, where - fragP->fr_literal, fixup_size,
   5084 				  &exp, pcrel, fixup_now->r_type);
   5085 	      fixP->fx_addnumber = fixP->fx_offset;
   5086 	    }
   5087 	  fixup_now++;
   5088 	  fixup_size = fixup_now->size;
   5089 	}
   5090       if (count < relax_code_size / 4)
   5091 	count++;
   5092       pattern_now = pattern_now->next;
   5093     }
   5094 
   5095 restore:
   5096   now_seg = seg_bak;
   5097   frchain_now = frchain_bak;
   5098 }
   5099 
   5100 /* Check instruction if it can be used for the baseline.  */
   5101 
   5102 static bfd_boolean
   5103 nds32_check_insn_available (struct nds32_asm_insn insn, const char *str)
   5104 {
   5105   int attr = insn.attr & ATTR_ALL;
   5106   static int baseline_isa = 0;
   5107   /* No isa setting or all isa can use.  */
   5108   if (attr == 0 || attr == ATTR_ALL)
   5109     return TRUE;
   5110 
   5111   if (baseline_isa == 0)
   5112     {
   5113       /* Map option baseline and instruction attribute.  */
   5114       switch (nds32_baseline)
   5115 	{
   5116 	case ISA_V2:
   5117 	  baseline_isa = ATTR (ISA_V2);
   5118 	  break;
   5119 	case ISA_V3:
   5120 	  baseline_isa = ATTR (ISA_V3);
   5121 	  break;
   5122 	case ISA_V3M:
   5123 	  baseline_isa = ATTR (ISA_V3M);
   5124 	  break;
   5125 	}
   5126     }
   5127 
   5128   if  ((baseline_isa & attr) == 0)
   5129     {
   5130       as_bad (_("Not support instrcution %s in the baseline."), str);
   5131       return FALSE;
   5132     }
   5133   return TRUE;
   5134 }
   5135 
   5136 /* Stub of machine dependent.  */
   5137 
   5138 void
   5139 md_assemble (char *str)
   5140 {
   5141   struct nds32_asm_insn insn;
   5142   expressionS expr;
   5143   char *out;
   5144   struct nds32_pseudo_opcode *popcode;
   5145   const struct nds32_field *fld = NULL;
   5146   fixS *fixP;
   5147   uint16_t insn_16;
   5148   struct nds32_relocs_pattern *relocs_temp;
   5149   expressionS *pexp;
   5150   fragS *fragP;
   5151   int label = label_exist;
   5152 
   5153   popcode = nds32_lookup_pseudo_opcode (str);
   5154   /* Note that we need to check 'verbatim' and
   5155      'opcode->physical_op'.  If the assembly content is generated by
   5156      compiler and this opcode is a physical instruction, there is no
   5157      need to perform pseudo instruction expansion/transformation.  */
   5158   if (popcode && !(verbatim && popcode->physical_op))
   5159     {
   5160       pseudo_opcode = TRUE;
   5161       nds32_pseudo_opcode_wrapper (str, popcode);
   5162       pseudo_opcode = FALSE;
   5163       nds32_elf_append_relax_relocs (NULL, relocs_list);
   5164 
   5165       /* Free pseudo list.  */
   5166       relocs_temp = relocs_list;
   5167       while (relocs_temp)
   5168 	{
   5169 	  relocs_list = relocs_list->next;
   5170 	  free (relocs_temp);
   5171 	  relocs_temp = relocs_list;
   5172 	}
   5173 
   5174       return;
   5175     }
   5176 
   5177   label_exist = 0;
   5178   insn.info = & expr;
   5179   asm_desc.result = NASM_OK;
   5180   nds32_assemble (&asm_desc, &insn, str);
   5181 
   5182   switch (asm_desc.result)
   5183     {
   5184     case NASM_ERR_UNKNOWN_OP:
   5185       as_bad (_("Unrecognized opcode, %s."), str);
   5186       return;
   5187     case NASM_ERR_SYNTAX:
   5188       as_bad (_("Incorrect syntax, %s."), str);
   5189       return;
   5190     case NASM_ERR_OPERAND:
   5191       as_bad (_("Unrecognized operand/register, %s."), str);
   5192       return;
   5193     case NASM_ERR_OUT_OF_RANGE:
   5194       as_bad (_("Operand out of range, %s."), str);
   5195       return;
   5196     case NASM_ERR_REG_REDUCED:
   5197       as_bad (_("Prohibited register used for reduced-register, %s."), str);
   5198       return;
   5199     case NASM_ERR_JUNK_EOL:
   5200       as_bad (_("Junk at end of line, %s."), str);
   5201       return;
   5202     }
   5203 
   5204   gas_assert (insn.opcode);
   5205 
   5206   nds32_set_elf_flags_by_insn (&insn);
   5207 
   5208   gas_assert (insn.opcode->isize == 4 || insn.opcode->isize == 2);
   5209 
   5210   if (!nds32_check_insn_available (insn, str))
   5211     return;
   5212 
   5213   /* Make sure the begining of text being 2-byte align.  */
   5214   nds32_adjust_label (1);
   5215   fld = insn.field;
   5216   /* Try to allocate the max size to guarantee relaxable same branch
   5217      instructions in the same fragment.  */
   5218   frag_grow (NDS32_MAXCHAR);
   5219   fragP = frag_now;
   5220   if (fld && (insn.attr & NASM_ATTR_BRANCH)
   5221       && (pseudo_opcode || (insn.opcode->value != INSN_JAL
   5222 			    && insn.opcode->value != INSN_J))
   5223       && (!verbatim || pseudo_opcode))
   5224     {
   5225       /* User assembly code branch relax for it.  */
   5226       /* If fld is not NULL, it is a symbol.  */
   5227       /* Branch msut relax to proper pattern in user assembly code exclude
   5228 	 J and JAL.  Keep these two in original type for users which wants
   5229 	 to keep their size be fixed.  In general, assembler does not convert
   5230 	 instruction generated by compiler.  But jump instruction may be
   5231 	 truncated in text virtual model.  For workaround, compiler generate
   5232 	 pseudo jump to fix this issue currently.  */
   5233 
   5234       /* Get branch range type.  */
   5235       dwarf2_emit_insn (0);
   5236       enum nds32_br_range range_type;
   5237 
   5238       pexp = insn.info;
   5239       range_type = get_range_type (fld);
   5240 
   5241       out = frag_var (rs_machine_dependent, NDS32_MAXCHAR,
   5242 		      0, /* VAR is un-used.  */
   5243 		      range_type, /* SUBTYPE is used as range type.  */
   5244 		      pexp->X_add_symbol, pexp->X_add_number, 0);
   5245 
   5246       fragP->fr_fix += insn.opcode->isize;
   5247       fragP->tc_frag_data.opcode = insn.opcode;
   5248       fragP->tc_frag_data.insn = insn.insn;
   5249       if (insn.opcode->isize == 4)
   5250 	bfd_putb32 (insn.insn, out);
   5251       else if (insn.opcode->isize == 2)
   5252 	bfd_putb16 (insn.insn, out);
   5253       fragP->tc_frag_data.flag |= NDS32_FRAG_BRANCH;
   5254       return;
   5255       /* md_convert_frag will insert relocations.  */
   5256     }
   5257   else if (!relaxing && enable_16bit && (optimize || optimize_for_space)
   5258 	   && ((!fld && !verbatim && insn.opcode->isize == 4
   5259 		&& nds32_convert_32_to_16 (stdoutput, insn.insn, &insn_16, NULL))
   5260 	       || (insn.opcode->isize == 2
   5261 		   && nds32_convert_16_to_32 (stdoutput, insn.insn, NULL))))
   5262     {
   5263       /* Record this one is relaxable.  */
   5264       pexp = insn.info;
   5265       dwarf2_emit_insn (0);
   5266       if (fld)
   5267 	{
   5268 	  out = frag_var (rs_machine_dependent,
   5269 			  4, /* Max size is 32-bit instruction.  */
   5270 			  0, /* VAR is un-used.  */
   5271 			  0, pexp->X_add_symbol, pexp->X_add_number, 0);
   5272 	  fragP->tc_frag_data.flag |= NDS32_FRAG_RELAXABLE_BRANCH;
   5273 	}
   5274       else
   5275 	out = frag_var (rs_machine_dependent,
   5276 			4, /* Max size is 32-bit instruction.  */
   5277 			0, /* VAR is un-used.  */
   5278 			0, NULL, 0, NULL);
   5279       fragP->tc_frag_data.flag |= NDS32_FRAG_RELAXABLE;
   5280       fragP->tc_frag_data.opcode = insn.opcode;
   5281       fragP->tc_frag_data.insn = insn.insn;
   5282       fragP->fr_fix += 2;
   5283 
   5284       /* In original, we don't relax the instrucion with label on it,
   5285 	 but this may cause some redundant nop16.  Therefore, tag this
   5286 	 relaxable instruction and relax it carefully.  */
   5287       if (label)
   5288 	fragP->tc_frag_data.flag |= NDS32_FRAG_LABEL;
   5289 
   5290       if (insn.opcode->isize == 4)
   5291 	bfd_putb16 (insn_16, out);
   5292       else if (insn.opcode->isize == 2)
   5293 	bfd_putb16 (insn.insn, out);
   5294       return;
   5295     }
   5296   else if ((verbatim || !relaxing) && optimize && label)
   5297     {
   5298       /* This instruction is with label.  */
   5299       expressionS exp;
   5300       out = frag_var (rs_machine_dependent, insn.opcode->isize,
   5301 		      0, 0, NULL, 0, NULL);
   5302       /* If this insturction is branch target, it is not relaxable.  */
   5303       fragP->tc_frag_data.flag = NDS32_FRAG_LABEL;
   5304       fragP->tc_frag_data.opcode = insn.opcode;
   5305       fragP->tc_frag_data.insn = insn.insn;
   5306       fragP->fr_fix += insn.opcode->isize;
   5307       if (insn.opcode->isize == 4)
   5308 	{
   5309 	  exp.X_op = O_symbol;
   5310 	  exp.X_add_symbol = abs_section_sym;
   5311 	  exp.X_add_number = 0;
   5312 	  fixP = fix_new_exp (fragP, fragP->fr_fix - 4, 0, &exp,
   5313 			      0, BFD_RELOC_NDS32_LABEL);
   5314 	  if (!verbatim)
   5315 	    fragP->tc_frag_data.flag = NDS32_FRAG_ALIGN;
   5316 	}
   5317     }
   5318   else
   5319     out = frag_more (insn.opcode->isize);
   5320 
   5321   if (insn.opcode->isize == 4)
   5322     bfd_putb32 (insn.insn, out);
   5323   if (insn.opcode->isize == 2)
   5324     bfd_putb16 (insn.insn, out);
   5325 
   5326   dwarf2_emit_insn (insn.opcode->isize);
   5327 
   5328   /* Compiler generating code and user assembly pseudo load-store, insert
   5329      fixup here.  */
   5330   pexp = insn.info;
   5331   fixP = nds32_elf_record_fixup_exp (fragP, str, fld, pexp, out, &insn);
   5332   /* Build relaxation pattern when relaxing is enable.  */
   5333   if (relaxing)
   5334     nds32_elf_build_relax_relation (fixP, pexp, out, insn.opcode, fragP, fld);
   5335 }
   5336 
   5337 /* md_macro_start  */
   5338 
   5339 void
   5340 nds32_macro_start (void)
   5341 {
   5342 }
   5343 
   5344 /* md_macro_info  */
   5345 
   5346 void
   5347 nds32_macro_info (void *info ATTRIBUTE_UNUSED)
   5348 {
   5349 }
   5350 
   5351 /* md_macro_end  */
   5352 
   5353 void
   5354 nds32_macro_end (void)
   5355 {
   5356 }
   5357 
   5358 /* GAS will call this function with one argument, an expressionS pointer, for
   5359    any expression that can not be recognized.  When the function is called,
   5360    input_line_pointer will point to the start of the expression.  */
   5361 
   5362 void
   5363 md_operand (expressionS *expressionP)
   5364 {
   5365   if (*input_line_pointer == '#')
   5366     {
   5367       input_line_pointer++;
   5368       expression (expressionP);
   5369     }
   5370 }
   5371 
   5372 /* GAS will call this function for each section at the end of the assembly, to
   5373    permit the CPU back end to adjust the alignment of a section.  The function
   5374    must take two arguments, a segT for the section and a valueT for the size of
   5375    the section, and return a valueT for the rounded size.  */
   5376 
   5377 valueT
   5378 md_section_align (segT segment, valueT size)
   5379 {
   5380   int align = bfd_get_section_alignment (stdoutput, segment);
   5381 
   5382   return ((size + (1 << align) - 1) & -(1 << align));
   5383 }
   5384 
   5385 /* GAS will call this function when a symbol table lookup fails, before it
   5386    creates a new symbol.  Typically this would be used to supply symbols whose
   5387    name or value changes dynamically, possibly in a context sensitive way.
   5388    Predefined symbols with fixed values, such as register names or condition
   5389    codes, are typically entered directly into the symbol table when md_begin
   5390    is called.  One argument is passed, a char * for the symbol.  */
   5391 
   5392 symbolS *
   5393 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
   5394 {
   5395   return NULL;
   5396 }
   5397 
   5398 static long
   5399 nds32_calc_branch_offset (segT segment, fragS *fragP,
   5400 			  long stretch ATTRIBUTE_UNUSED,
   5401 			  relax_info_t *relax_info,
   5402 			  enum nds32_br_range branch_range_type)
   5403 {
   5404   struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
   5405   symbolS *branch_symbol = fragP->fr_symbol;
   5406   offsetT branch_offset = fragP->fr_offset;
   5407   offsetT branch_target_address;
   5408   offsetT branch_insn_address;
   5409   long offset = 0;
   5410 
   5411   if ((S_GET_SEGMENT (branch_symbol) != segment)
   5412       || S_IS_WEAK (branch_symbol))
   5413     {
   5414       /* The symbol is not in the SEGMENT.  It could be far far away.  */
   5415       offset = 0x80000000;
   5416     }
   5417   else
   5418     {
   5419       /* Calculate symbol-to-instruction offset.  */
   5420       branch_target_address = S_GET_VALUE (branch_symbol) + branch_offset;
   5421       /* If the destination symbol is beyond current frag address,
   5422 	 STRETCH will take effect to symbol's position.  */
   5423       if (S_GET_VALUE (branch_symbol) > fragP->fr_address)
   5424 	branch_target_address += stretch;
   5425 
   5426       branch_insn_address = fragP->fr_address + fragP->fr_fix;
   5427       branch_insn_address -= opcode->isize;
   5428 
   5429       /* Update BRANCH_INSN_ADDRESS to relaxed position.  */
   5430       branch_insn_address += (relax_info->relax_code_size[branch_range_type]
   5431 			      - relax_info->relax_branch_isize[branch_range_type]);
   5432 
   5433       offset = branch_target_address - branch_insn_address;
   5434     }
   5435 
   5436   return offset;
   5437 }
   5438 
   5439 static enum nds32_br_range
   5440 nds32_convert_to_range_type (long offset)
   5441 {
   5442   enum nds32_br_range range_type;
   5443 
   5444   if (-(0x100) <= offset && offset < 0x100) /* 256 bytes */
   5445     range_type = BR_RANGE_S256;
   5446   else if (-(0x4000) <= offset && offset < 0x4000) /* 16K bytes */
   5447     range_type = BR_RANGE_S16K;
   5448   else if (-(0x10000) <= offset && offset < 0x10000) /* 64K bytes */
   5449     range_type = BR_RANGE_S64K;
   5450   else if (-(0x1000000) <= offset && offset < 0x1000000) /* 16M bytes */
   5451     range_type = BR_RANGE_S16M;
   5452   else /* 4G bytes */
   5453     range_type = BR_RANGE_U4G;
   5454 
   5455   return range_type;
   5456 }
   5457 
   5458 /* Set insntruction register mask.  */
   5459 
   5460 static void
   5461 nds32_elf_get_set_cond (relax_info_t *relax_info, int offset, uint32_t *insn,
   5462 			uint32_t ori_insn, int range)
   5463 {
   5464   nds32_cond_field_t *cond_fields = relax_info->cond_field;
   5465   nds32_cond_field_t *code_seq_cond = relax_info->relax_code_condition[range];
   5466   uint32_t mask;
   5467   int i = 0;
   5468 
   5469   /* The instruction has conditions.  Collect condition values.  */
   5470   while (code_seq_cond[i].bitmask != 0)
   5471     {
   5472       if (offset == code_seq_cond[i].offset)
   5473 	{
   5474 	  mask = (ori_insn >> cond_fields[i].bitpos) & cond_fields[i].bitmask;
   5475 	  /* Sign extend.  */
   5476 	  if (cond_fields[i].signed_extend)
   5477 	    mask = (mask ^ ((cond_fields[i].bitmask + 1) >> 1)) -
   5478 	      ((cond_fields[i].bitmask + 1) >> 1);
   5479 	  *insn |= (mask & code_seq_cond[i].bitmask) << code_seq_cond[i].bitpos;
   5480 	}
   5481       i++;
   5482     }
   5483 }
   5484 
   5485 
   5486 static int
   5487 nds32_relax_branch_instructions (segT segment, fragS *fragP,
   5488 				 long stretch ATTRIBUTE_UNUSED,
   5489 				 int init)
   5490 {
   5491   enum nds32_br_range branch_range_type;
   5492   struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
   5493   long offset = 0;
   5494   enum nds32_br_range real_range_type;
   5495   int adjust = 0;
   5496   relax_info_t *relax_info;
   5497   int diff = 0;
   5498   int i, j, k;
   5499   int code_seq_size;
   5500   uint32_t *code_seq;
   5501   uint32_t insn;
   5502   int insn_size;
   5503   int code_seq_offset;
   5504 
   5505   /* Replace with gas_assert (fragP->fr_symbol != NULL); */
   5506   if (fragP->fr_symbol == NULL)
   5507     return adjust;
   5508 
   5509   /* If frag_var is not enough room, the previos frag is fr_full and with
   5510      opcode.  The new one is rs_dependent but without opcode.  */
   5511   if (opcode == NULL)
   5512     return adjust;
   5513 
   5514   relax_info = hash_find (nds32_relax_info_hash, opcode->opcode);
   5515 
   5516   if (relax_info == NULL)
   5517     return adjust;
   5518 
   5519   if (init)
   5520     branch_range_type = relax_info->br_range;
   5521   else
   5522     branch_range_type = fragP->fr_subtype;
   5523 
   5524   offset = nds32_calc_branch_offset (segment, fragP, stretch,
   5525 				     relax_info, branch_range_type);
   5526 
   5527   real_range_type = nds32_convert_to_range_type (offset);
   5528 
   5529   /* If actual range is equal to instruction jump range, do nothing.  */
   5530   if (real_range_type == branch_range_type)
   5531     return adjust;
   5532 
   5533   /* Find out proper relaxation code sequence.  */
   5534   for (i = BR_RANGE_S256; i < BR_RANGE_NUM; i++)
   5535     {
   5536       if (real_range_type <= (unsigned int) i)
   5537 	{
   5538 	  if (init)
   5539 	    diff = relax_info->relax_code_size[i] - opcode->isize;
   5540 	  else
   5541 	    diff = relax_info->relax_code_size[i]
   5542 	      - relax_info->relax_code_size[branch_range_type];
   5543 
   5544 	  /* If the instruction could be converted to 16-bits,
   5545 	     minus the difference.  */
   5546 	  code_seq_offset = 0;
   5547 	  j = 0;
   5548 	  k = 0;
   5549 	  code_seq_size = relax_info->relax_code_size[i];
   5550 	  code_seq = relax_info->relax_code_seq[i];
   5551 	  while (code_seq_offset < code_seq_size)
   5552 	    {
   5553 	      insn = code_seq[j];
   5554 	      if (insn & 0x80000000) /* 16-bits instruction.  */
   5555 		{
   5556 		  insn_size = 2;
   5557 		}
   5558 	      else /* 32-bits instruction.  */
   5559 		{
   5560 		  insn_size = 4;
   5561 
   5562 		  while (relax_info->relax_fixup[i][k].size !=0
   5563 			 && relax_info->relax_fixup[i][k].offset < code_seq_offset)
   5564 		    k++;
   5565 		}
   5566 
   5567 	      code_seq_offset += insn_size;
   5568 	      j++;
   5569 	    }
   5570 
   5571 	  /* Update fr_subtype to new NDS32_BR_RANGE.  */
   5572 	  fragP->fr_subtype = i;
   5573 	  break;
   5574 	}
   5575     }
   5576 
   5577   return diff + adjust;
   5578 }
   5579 
   5580 /* Adjust relaxable frag till current frag.  */
   5581 
   5582 static int
   5583 nds32_adjust_relaxable_frag (fragS *startP, fragS *fragP)
   5584 {
   5585   int adj;
   5586   if (startP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
   5587     adj = -2;
   5588   else
   5589     adj = 2;
   5590 
   5591   startP->tc_frag_data.flag ^= NDS32_FRAG_RELAXED;
   5592 
   5593   while (startP)
   5594     {
   5595       startP = startP->fr_next;
   5596       if (startP)
   5597 	{
   5598 	  startP->fr_address += adj;
   5599 	  if (startP == fragP)
   5600 	    break;
   5601 	}
   5602     }
   5603   return adj;
   5604 }
   5605 
   5606 static addressT
   5607 nds32_get_align (addressT address, int align)
   5608 {
   5609   addressT mask, new_address;
   5610 
   5611   mask = ~((~0U) << align);
   5612   new_address = (address + mask) & (~mask);
   5613   return (new_address - address);
   5614 }
   5615 
   5616 /* Check the prev_frag is legal.  */
   5617 static void
   5618 invalid_prev_frag (fragS * fragP, fragS **prev_frag)
   5619 {
   5620   addressT address;
   5621   fragS *frag_start = *prev_frag;
   5622 
   5623   if (!frag_start)
   5624     return;
   5625 
   5626   if (frag_start->last_fr_address >= fragP->last_fr_address)
   5627     {
   5628       *prev_frag = NULL;
   5629       return;
   5630     }
   5631 
   5632   fragS *frag_t = *prev_frag;
   5633   while (frag_t != fragP)
   5634     {
   5635       if (frag_t->fr_type == rs_align
   5636 	  || frag_t->fr_type == rs_align_code
   5637 	  || frag_t->fr_type == rs_align_test)
   5638 	{
   5639 	  /* Relax instruction can not walk across lable.  */
   5640 	  if (frag_t->tc_frag_data.flag & NDS32_FRAG_LABEL)
   5641 	    {
   5642 	      prev_frag = NULL;
   5643 	      return;
   5644 	    }
   5645 	  /* Relax previos relaxable to align rs_align frag.  */
   5646 	  address = frag_t->fr_address + frag_t->fr_fix;
   5647 	  addressT offset = nds32_get_align (address, (int) frag_t->fr_offset);
   5648 	  if (offset & 0x2)
   5649 	    {
   5650 	      /* If there is label on the prev_frag, check if it is aligned.  */
   5651 	      if (!((*prev_frag)->tc_frag_data.flag & NDS32_FRAG_LABEL)
   5652 		  || (((*prev_frag)->fr_address + (*prev_frag)->fr_fix  - 2 )
   5653 		      & 0x2) == 0)
   5654 		nds32_adjust_relaxable_frag (*prev_frag, frag_t);
   5655 	    }
   5656 	  *prev_frag = NULL;
   5657 	  return;
   5658 	}
   5659       frag_t = frag_t->fr_next;
   5660     }
   5661 
   5662   if (fragP->tc_frag_data.flag & NDS32_FRAG_ALIGN)
   5663     {
   5664       address = fragP->fr_address;
   5665       addressT offset = nds32_get_align (address, 2);
   5666       if (offset & 0x2)
   5667 	{
   5668 	  /* If there is label on the prev_frag, check if it is aligned.  */
   5669 	  if (!((*prev_frag)->tc_frag_data.flag & NDS32_FRAG_LABEL)
   5670 	      || (((*prev_frag)->fr_address + (*prev_frag)->fr_fix  - 2 )
   5671 		  & 0x2) == 0)
   5672 	    nds32_adjust_relaxable_frag (*prev_frag, fragP);
   5673 	}
   5674       *prev_frag = NULL;
   5675       return;
   5676     }
   5677 }
   5678 
   5679 /* md_relax_frag  */
   5680 
   5681 int
   5682 nds32_relax_frag (segT segment, fragS *fragP, long stretch ATTRIBUTE_UNUSED)
   5683 {
   5684   /* Currently, there are two kinds of relaxation in nds32 assembler.
   5685      1. relax for branch
   5686      2. relax for 32-bits to 16-bits  */
   5687 
   5688   static fragS *prev_frag = NULL;
   5689   int adjust = 0;
   5690 
   5691   invalid_prev_frag (fragP, &prev_frag);
   5692 
   5693   if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
   5694     adjust = nds32_relax_branch_instructions (segment, fragP, stretch, 0);
   5695   if (fragP->tc_frag_data.flag & NDS32_FRAG_LABEL)
   5696     prev_frag = NULL;
   5697   if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE
   5698       && (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED) == 0)
   5699     /* Here is considered relaxed case originally.  But it may cause
   5700        unendless loop when relaxing.  Once the instruction is relaxed,
   5701        it can not be undo.  */
   5702     prev_frag = fragP;
   5703 
   5704   return adjust;
   5705 }
   5706 
   5707 /* This function returns an initial guess of the length by which a fragment
   5708    must grow to hold a branch to reach its destination.  Also updates
   5709    fr_type/fr_subtype as necessary.
   5710 
   5711    It is called just before doing relaxation.  Any symbol that is now undefined
   5712    will not become defined.  The guess for fr_var is ACTUALLY the growth beyond
   5713    fr_fix.  Whatever we do to grow fr_fix or fr_var contributes to our returned
   5714    value.  Although it may not be explicit in the frag, pretend fr_var starts
   5715    with a 0 value.  */
   5716 
   5717 int
   5718 md_estimate_size_before_relax (fragS *fragP, segT segment)
   5719 {
   5720   /* Currently, there are two kinds of relaxation in nds32 assembler.
   5721      1. relax for branch
   5722      2. relax for 32-bits to 16-bits  */
   5723 
   5724   /* Save previos relaxable frag.  */
   5725   static fragS *prev_frag = NULL;
   5726   int adjust = 0;
   5727 
   5728   invalid_prev_frag (fragP, &prev_frag);
   5729 
   5730   if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
   5731     adjust = nds32_relax_branch_instructions (segment, fragP, 0, 1);
   5732   if (fragP->tc_frag_data.flag & NDS32_FRAG_LABEL)
   5733     prev_frag = NULL;
   5734   if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
   5735     adjust = 2;
   5736   else if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE)
   5737     prev_frag = fragP;
   5738 
   5739   return adjust;
   5740 }
   5741 
   5742 /* GAS will call this for each rs_machine_dependent fragment.  The instruction
   5743    is completed using the data from the relaxation pass.  It may also create any
   5744    necessary relocations.
   5745 
   5746    *FRAGP has been relaxed to its final size, and now needs to have the bytes
   5747    inside it modified to conform to the new size.  It is called after relaxation
   5748    is finished.
   5749 
   5750    fragP->fr_type == rs_machine_dependent.
   5751    fragP->fr_subtype is the subtype of what the address relaxed to.  */
   5752 
   5753 void
   5754 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP)
   5755 {
   5756   /* Convert branch relaxation instructions.  */
   5757   symbolS *branch_symbol = fragP->fr_symbol;
   5758   offsetT branch_offset = fragP->fr_offset;
   5759   enum nds32_br_range branch_range_type = fragP->fr_subtype;
   5760   struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
   5761   uint32_t origin_insn = fragP->tc_frag_data.insn;
   5762   relax_info_t *relax_info;
   5763   char *fr_buffer;
   5764   int fr_where;
   5765   int addend ATTRIBUTE_UNUSED;
   5766   offsetT branch_target_address, branch_insn_address;
   5767   expressionS exp;
   5768   fixS *fixP;
   5769   uint32_t *code_seq;
   5770   uint32_t insn;
   5771   int code_size, insn_size, offset, fixup_size;
   5772   int buf_offset, pcrel;
   5773   int i, k;
   5774   uint16_t insn_16;
   5775   nds32_relax_fixup_info_t fixup_info[MAX_RELAX_FIX];
   5776   /* Save the 1st instruction is converted to 16 bit or not.  */
   5777   unsigned int branch_size;
   5778 
   5779   /* Replace with gas_assert (branch_symbol != NULL); */
   5780   if (branch_symbol == NULL && !(fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED))
   5781     return;
   5782 
   5783   /* If frag_var is not enough room, the previos frag is fr_full and with
   5784      opcode.  The new one is rs_dependent but without opcode.  */
   5785   if (opcode == NULL)
   5786     return;
   5787 
   5788   if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE_BRANCH)
   5789     {
   5790       relax_info = hash_find (nds32_relax_info_hash, opcode->opcode);
   5791 
   5792       if (relax_info == NULL)
   5793 	return;
   5794 
   5795       i = BR_RANGE_S256;
   5796       while (i < BR_RANGE_NUM
   5797 	     && relax_info->relax_code_size[i]
   5798 	     != (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED ? 4 : 2))
   5799 	i++;
   5800 
   5801       if (i >= BR_RANGE_NUM)
   5802 	as_bad ("Internal error: Cannot find relocation of"
   5803 		"relaxable branch.");
   5804 
   5805       exp.X_op = O_symbol;
   5806       exp.X_add_symbol = branch_symbol;
   5807       exp.X_add_number = branch_offset;
   5808       pcrel = ((relax_info->relax_fixup[i][0].ramp & NDS32_PCREL) != 0) ? 1 : 0;
   5809       fr_where = fragP->fr_fix - 2;
   5810       fixP = fix_new_exp (fragP, fr_where, relax_info->relax_fixup[i][0].size,
   5811 			  &exp, pcrel, relax_info->relax_fixup[i][0].r_type);
   5812       fixP->fx_addnumber = fixP->fx_offset;
   5813 
   5814       if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
   5815 	{
   5816 	  insn_16 = fragP->tc_frag_data.insn;
   5817 	  nds32_convert_16_to_32 (stdoutput, insn_16, &insn);
   5818 	  fr_buffer = fragP->fr_literal + fr_where;
   5819 	  fragP->fr_fix += 2;
   5820 	  exp.X_op = O_symbol;
   5821 	  exp.X_add_symbol = abs_section_sym;
   5822 	  exp.X_add_number = 0;
   5823 	  fix_new_exp (fragP, fr_where, 4,
   5824 		       &exp, 0, BFD_RELOC_NDS32_INSN16);
   5825 	  number_to_chars_bigendian (fr_buffer, insn, 4);
   5826 	}
   5827     }
   5828   else if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
   5829     {
   5830       if (fragP->tc_frag_data.opcode->isize == 2)
   5831 	{
   5832 	  insn_16 = fragP->tc_frag_data.insn;
   5833 	  nds32_convert_16_to_32 (stdoutput, insn_16, &insn);
   5834 	}
   5835       else
   5836 	insn = fragP->tc_frag_data.insn;
   5837       fragP->fr_fix += 2;
   5838       fr_where = fragP->fr_fix - 4;
   5839       fr_buffer = fragP->fr_literal + fr_where;
   5840       exp.X_op = O_symbol;
   5841       exp.X_add_symbol = abs_section_sym;
   5842       exp.X_add_number = 0;
   5843       fix_new_exp (fragP, fr_where, 4, &exp, 0,
   5844 		   BFD_RELOC_NDS32_INSN16);
   5845       number_to_chars_bigendian (fr_buffer, insn, 4);
   5846     }
   5847   else if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
   5848     {
   5849       /* Branch instruction adjust and append relocations.  */
   5850       relax_info = hash_find (nds32_relax_info_hash, opcode->opcode);
   5851 
   5852       if (relax_info == NULL)
   5853 	return;
   5854 
   5855       fr_where = fragP->fr_fix - opcode->isize;
   5856       fr_buffer = fragP->fr_literal + fr_where;
   5857 
   5858       if ((S_GET_SEGMENT (branch_symbol) != sec)
   5859 	  || S_IS_WEAK (branch_symbol))
   5860 	{
   5861 	  if (fragP->fr_offset & 3)
   5862 	    as_warn (_("Addend to unresolved symbol is not on word boundary."));
   5863 	  addend = 0;
   5864 	}
   5865       else
   5866 	{
   5867 	  /* Calculate symbol-to-instruction offset.  */
   5868 	  branch_target_address = S_GET_VALUE (branch_symbol) + branch_offset;
   5869 	  branch_insn_address = fragP->fr_address + fr_where;
   5870 	  addend = (branch_target_address - branch_insn_address) >> 1;
   5871 	}
   5872 
   5873       code_size = relax_info->relax_code_size[branch_range_type];
   5874       code_seq = relax_info->relax_code_seq[branch_range_type];
   5875 
   5876       memcpy (fixup_info, relax_info->relax_fixup[branch_range_type],
   5877 	      sizeof (fixup_info));
   5878 
   5879       /* Fill in frag.  */
   5880       i = 0;
   5881       k = 0;
   5882       offset = 0; /* code_seq offset */
   5883       buf_offset = 0; /* fr_buffer offset */
   5884       while (offset < code_size)
   5885 	{
   5886 	  insn = code_seq[i];
   5887 	  if (insn & 0x80000000) /* 16-bits instruction.  */
   5888 	    {
   5889 	      insn = (insn >> 16) & 0xFFFF;
   5890 	      insn_size = 2;
   5891 	    }
   5892 	  else /* 32-bits instruction.  */
   5893 	    {
   5894 	      insn_size = 4;
   5895 	    }
   5896 
   5897 	  nds32_elf_get_set_cond (relax_info, offset, &insn,
   5898 				  origin_insn, branch_range_type);
   5899 
   5900 	  /* Try to convert to 16-bits instruction.  Currently, only the first
   5901 	     insntruction in pattern can be converted.  EX: bnez sethi ori jr,
   5902 	     only bnez can be converted to 16 bit and ori can't.  */
   5903 
   5904 	  while (fixup_info[k].size != 0
   5905 		 && relax_info->relax_fixup[branch_range_type][k].offset < offset)
   5906 	    k++;
   5907 
   5908 	  number_to_chars_bigendian (fr_buffer + buf_offset, insn, insn_size);
   5909 	  buf_offset += insn_size;
   5910 
   5911 	  offset += insn_size;
   5912 	  i++;
   5913 	}
   5914 
   5915       /* Set up fixup.  */
   5916       exp.X_op = O_symbol;
   5917 
   5918       for (i = 0; fixup_info[i].size != 0; i++)
   5919 	{
   5920 	  fixup_size = fixup_info[i].size;
   5921 	  pcrel = ((fixup_info[i].ramp & NDS32_PCREL) != 0) ? 1 : 0;
   5922 
   5923 	  if ((fixup_info[i].ramp & NDS32_CREATE_LABEL) != 0)
   5924 	    {
   5925 	      /* This is a reverse branch.  */
   5926 	      exp.X_add_symbol = symbol_temp_new (sec, 0, fragP->fr_next);
   5927 	      exp.X_add_number = 0;
   5928 	    }
   5929 	  else if ((fixup_info[i].ramp & NDS32_PTR) != 0)
   5930 	    {
   5931 	      /* This relocation has to point to another instruction.  */
   5932 	      branch_size = fr_where + code_size - 4;
   5933 	      exp.X_add_symbol = symbol_temp_new (sec, branch_size, fragP);
   5934 	      exp.X_add_number = 0;
   5935 	    }
   5936 	  else if ((fixup_info[i].ramp & NDS32_ABS) != 0)
   5937 	    {
   5938 	      /* This is a tag relocation.  */
   5939 	      exp.X_add_symbol = abs_section_sym;
   5940 	      exp.X_add_number = 0;
   5941 	    }
   5942 	  else if ((fixup_info[i].ramp & NDS32_INSN16) != 0)
   5943 	    {
   5944 	      if (!enable_16bit)
   5945 		continue;
   5946 	      /* This is a tag relocation.  */
   5947 	      exp.X_add_symbol = abs_section_sym;
   5948 	      exp.X_add_number = 0;
   5949 	    }
   5950 	  else
   5951 	    {
   5952 	      exp.X_add_symbol = branch_symbol;
   5953 	      exp.X_add_number = branch_offset;
   5954 	    }
   5955 
   5956 	  if (fixup_info[i].r_type != 0)
   5957 	    {
   5958 	      fixP = fix_new_exp (fragP, fr_where + fixup_info[i].offset,
   5959 				  fixup_size, &exp, pcrel,
   5960 				  fixup_info[i].r_type);
   5961 	      fixP->fx_addnumber = fixP->fx_offset;
   5962 	    }
   5963 	}
   5964 
   5965       fragP->fr_fix = fr_where + buf_offset;
   5966     }
   5967 }
   5968 
   5969 /* tc_frob_file_before_fix  */
   5970 
   5971 void
   5972 nds32_frob_file_before_fix (void)
   5973 {
   5974 }
   5975 
   5976 static bfd_boolean
   5977 nds32_relaxable_section (asection *sec)
   5978 {
   5979   return ((sec->flags & SEC_DEBUGGING) == 0
   5980 	  && strcmp (sec->name, ".eh_frame") != 0);
   5981 }
   5982 
   5983 /* TC_FORCE_RELOCATION */
   5984 int
   5985 nds32_force_relocation (fixS * fix)
   5986 {
   5987   switch (fix->fx_r_type)
   5988     {
   5989     case BFD_RELOC_NDS32_INSN16:
   5990     case BFD_RELOC_NDS32_LABEL:
   5991     case BFD_RELOC_NDS32_LONGCALL1:
   5992     case BFD_RELOC_NDS32_LONGCALL2:
   5993     case BFD_RELOC_NDS32_LONGCALL3:
   5994     case BFD_RELOC_NDS32_LONGJUMP1:
   5995     case BFD_RELOC_NDS32_LONGJUMP2:
   5996     case BFD_RELOC_NDS32_LONGJUMP3:
   5997     case BFD_RELOC_NDS32_LOADSTORE:
   5998     case BFD_RELOC_NDS32_9_FIXED:
   5999     case BFD_RELOC_NDS32_15_FIXED:
   6000     case BFD_RELOC_NDS32_17_FIXED:
   6001     case BFD_RELOC_NDS32_25_FIXED:
   6002     case BFD_RELOC_NDS32_9_PCREL:
   6003     case BFD_RELOC_NDS32_15_PCREL:
   6004     case BFD_RELOC_NDS32_17_PCREL:
   6005     case BFD_RELOC_NDS32_WORD_9_PCREL:
   6006     case BFD_RELOC_NDS32_10_UPCREL:
   6007     case BFD_RELOC_NDS32_25_PCREL:
   6008     case BFD_RELOC_NDS32_MINUEND:
   6009     case BFD_RELOC_NDS32_SUBTRAHEND:
   6010       return 1;
   6011 
   6012     case BFD_RELOC_8:
   6013     case BFD_RELOC_16:
   6014     case BFD_RELOC_32:
   6015     case BFD_RELOC_NDS32_DIFF_ULEB128:
   6016       /* Linker should handle difference between two symbol.  */
   6017       return fix->fx_subsy != NULL
   6018 	&& nds32_relaxable_section (S_GET_SEGMENT (fix->fx_addsy));
   6019     case BFD_RELOC_64:
   6020       if (fix->fx_subsy)
   6021 	as_bad ("Double word for difference between two symbols "
   6022 		"is not supported across relaxation.");
   6023     default:
   6024       ;
   6025     }
   6026 
   6027   if (generic_force_reloc (fix))
   6028     return 1;
   6029 
   6030   return fix->fx_pcrel;
   6031 }
   6032 
   6033 /* TC_VALIDATE_FIX_SUB  */
   6034 
   6035 int
   6036 nds32_validate_fix_sub (fixS *fix, segT add_symbol_segment)
   6037 {
   6038   segT sub_symbol_segment;
   6039 
   6040   /* This code is referred from Xtensa.  Check their implementation for
   6041      details.  */
   6042 
   6043   /* Make sure both symbols are in the same segment, and that segment is
   6044      "normal" and relaxable.  */
   6045   sub_symbol_segment = S_GET_SEGMENT (fix->fx_subsy);
   6046   return (sub_symbol_segment == add_symbol_segment
   6047 	  && add_symbol_segment != undefined_section);
   6048 }
   6049 
   6050 void
   6051 md_number_to_chars (char *buf, valueT val, int n)
   6052 {
   6053   if (target_big_endian)
   6054     number_to_chars_bigendian (buf, val, n);
   6055   else
   6056     number_to_chars_littleendian (buf, val, n);
   6057 }
   6058 
   6059 /* Equal to MAX_PRECISION in atof-ieee.c.  */
   6060 #define MAX_LITTLENUMS 6
   6061 
   6062 /* This function is called to convert an ASCII string into a floating point
   6063    value in format used by the CPU.  */
   6064 
   6065 const char *
   6066 md_atof (int type, char *litP, int *sizeP)
   6067 {
   6068   int i;
   6069   int prec;
   6070   LITTLENUM_TYPE words[MAX_LITTLENUMS];
   6071   char *t;
   6072 
   6073   switch (type)
   6074     {
   6075     case 'f':
   6076     case 'F':
   6077     case 's':
   6078     case 'S':
   6079       prec = 2;
   6080       break;
   6081     case 'd':
   6082     case 'D':
   6083     case 'r':
   6084     case 'R':
   6085       prec = 4;
   6086       break;
   6087     default:
   6088       *sizeP = 0;
   6089       return _("Bad call to md_atof()");
   6090     }
   6091 
   6092   t = atof_ieee (input_line_pointer, type, words);
   6093   if (t)
   6094     input_line_pointer = t;
   6095   *sizeP = prec * sizeof (LITTLENUM_TYPE);
   6096 
   6097   if (target_big_endian)
   6098     {
   6099       for (i = 0; i < prec; i++)
   6100 	{
   6101 	  md_number_to_chars (litP, (valueT) words[i],
   6102 			      sizeof (LITTLENUM_TYPE));
   6103 	  litP += sizeof (LITTLENUM_TYPE);
   6104 	}
   6105     }
   6106   else
   6107     {
   6108       for (i = prec - 1; i >= 0; i--)
   6109 	{
   6110 	  md_number_to_chars (litP, (valueT) words[i],
   6111 			      sizeof (LITTLENUM_TYPE));
   6112 	  litP += sizeof (LITTLENUM_TYPE);
   6113 	}
   6114     }
   6115 
   6116   return 0;
   6117 }
   6118 
   6119 /* md_elf_section_change_hook  */
   6120 
   6121 void
   6122 nds32_elf_section_change_hook (void)
   6123 {
   6124 }
   6125 
   6126 /* md_cleanup  */
   6127 
   6128 void
   6129 nds32_cleanup (void)
   6130 {
   6131 }
   6132 
   6133 /* This function is used to scan leb128 subtraction expressions,
   6134    and insert fixups for them.
   6135 
   6136       e.g., .leb128  .L1 - .L0
   6137 
   6138    These expressions are heavily used in debug information or
   6139    exception tables.  Because relaxation will change code size,
   6140    we must resolve them in link time.  */
   6141 
   6142 static void
   6143 nds32_insert_leb128_fixes (bfd *abfd ATTRIBUTE_UNUSED,
   6144 			   asection *sec, void *xxx ATTRIBUTE_UNUSED)
   6145 {
   6146   segment_info_type *seginfo = seg_info (sec);
   6147   struct frag *fragP;
   6148 
   6149   subseg_set (sec, 0);
   6150 
   6151   for (fragP = seginfo->frchainP->frch_root;
   6152        fragP; fragP = fragP->fr_next)
   6153     {
   6154       expressionS *exp;
   6155 
   6156       /* Only unsigned leb128 can be handle.  */
   6157       if (fragP->fr_type != rs_leb128 || fragP->fr_subtype != 0
   6158 	  || fragP->fr_symbol == NULL)
   6159 	continue;
   6160 
   6161       exp = symbol_get_value_expression (fragP->fr_symbol);
   6162 
   6163       if (exp->X_op != O_subtract)
   6164 	continue;
   6165 
   6166       fix_new_exp (fragP, fragP->fr_fix, 0,
   6167 		   exp, 0, BFD_RELOC_NDS32_DIFF_ULEB128);
   6168     }
   6169 }
   6170 
   6171 static void
   6172 nds32_insert_relax_entry (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
   6173 			  void *xxx ATTRIBUTE_UNUSED)
   6174 {
   6175   segment_info_type *seginfo;
   6176   fragS *fragP;
   6177   fixS *fixP;
   6178   expressionS exp;
   6179   fixS *fixp;
   6180 
   6181   seginfo = seg_info (sec);
   6182   if (!seginfo || !symbol_rootP || !subseg_text_p (sec) || sec->size == 0)
   6183     return;
   6184   /* If there is no relocation and relax is disabled, it is not necessary to
   6185      insert R_NDS32_RELAX_ENTRY for linker do EX9 or IFC optimization.  */
   6186   for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
   6187     if (!fixp->fx_done)
   6188       break;
   6189   if (!fixp && !enable_relax_ex9 && !verbatim)
   6190     return;
   6191 
   6192   subseg_change (sec, 0);
   6193 
   6194   /* Set RELAX_ENTRY flags for linker.  */
   6195   fragP = seginfo->frchainP->frch_root;
   6196   exp.X_op = O_symbol;
   6197   exp.X_add_symbol = section_symbol (sec);
   6198   exp.X_add_number = 0;
   6199   if (!enable_relax_relocs)
   6200     exp.X_add_number |= R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG;
   6201   else
   6202     {
   6203       /* These flags are only enabled when global relax is enabled.
   6204 	 Maybe we can check DISABLE_RELAX_FLAG at linke-time,
   6205 	 so we set them anyway.  */
   6206       if (enable_relax_ex9)
   6207 	exp.X_add_number |= R_NDS32_RELAX_ENTRY_EX9_FLAG;
   6208       if (enable_relax_ifc)
   6209 	exp.X_add_number |= R_NDS32_RELAX_ENTRY_IFC_FLAG;
   6210       if (verbatim)
   6211 	exp.X_add_number |= R_NDS32_RELAX_ENTRY_VERBATIM_FLAG;
   6212     }
   6213   if (optimize)
   6214     exp.X_add_number |= R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG;
   6215   if (optimize_for_space)
   6216     exp.X_add_number |= R_NDS32_RELAX_ENTRY_OPTIMIZE_FOR_SPACE_FLAG;
   6217 
   6218   fixP = fix_new_exp (fragP, 0, 0, &exp, 0, BFD_RELOC_NDS32_RELAX_ENTRY);
   6219   fixP->fx_no_overflow = 1;
   6220 }
   6221 
   6222 /* Analysis relax hint and insert suitable relocation pattern.  */
   6223 
   6224 static void
   6225 nds32_elf_analysis_relax_hint (void)
   6226 {
   6227   hash_traverse (nds32_hint_hash, nds32_elf_append_relax_relocs);
   6228 }
   6229 
   6230 static void
   6231 nds32_elf_insert_final_frag (void)
   6232 {
   6233   struct frchain *frchainP;
   6234   asection *s;
   6235   fragS *fragP;
   6236 
   6237   if (!optimize)
   6238     return;
   6239 
   6240   for (s = stdoutput->sections; s; s = s->next)
   6241     {
   6242       segment_info_type *seginfo = seg_info (s);
   6243       if (!seginfo)
   6244 	continue;
   6245 
   6246       for (frchainP = seginfo->frchainP; frchainP != NULL;
   6247 	   frchainP = frchainP->frch_next)
   6248 	{
   6249 	  subseg_set (s, frchainP->frch_subseg);
   6250 
   6251 	  if (subseg_text_p (now_seg))
   6252 	    {
   6253 	      fragP = frag_now;
   6254 	      frag_var (rs_machine_dependent, 2, /* Max size.  */
   6255 			0, /* VAR is un-used.  */ 0, NULL, 0, NULL);
   6256 	      fragP->tc_frag_data.flag |= NDS32_FRAG_FINAL;
   6257 	    }
   6258 	}
   6259     }
   6260 }
   6261 
   6262 void
   6263 md_end (void)
   6264 {
   6265   nds32_elf_insert_final_frag ();
   6266   nds32_elf_analysis_relax_hint ();
   6267   bfd_map_over_sections (stdoutput, nds32_insert_leb128_fixes, NULL);
   6268 }
   6269 
   6270 /* Implement md_allow_local_subtract.  */
   6271 
   6272 bfd_boolean
   6273 nds32_allow_local_subtract (expressionS *expr_l ATTRIBUTE_UNUSED,
   6274 			    expressionS *expr_r ATTRIBUTE_UNUSED,
   6275 			    segT sec ATTRIBUTE_UNUSED)
   6276 {
   6277   /* Don't allow any subtraction, because relax may change the code.  */
   6278   return FALSE;
   6279 }
   6280 
   6281 /* Sort relocation by address.
   6282 
   6283    We didn't use qsort () in stdlib, because quick-sort is not a stable
   6284    sorting algorithm.  Relocations at the same address (r_offset) must keep
   6285    their relative order.  For example, RELAX_ENTRY must be the very first
   6286    relocation entry.
   6287 
   6288    Currently, this function implements insertion-sort.  */
   6289 
   6290 static int
   6291 compar_relent (const void *lhs, const void *rhs)
   6292 {
   6293   const arelent **l = (const arelent **) lhs;
   6294   const arelent **r = (const arelent **) rhs;
   6295 
   6296   if ((*l)->address > (*r)->address)
   6297     return 1;
   6298   else if ((*l)->address == (*r)->address)
   6299     return 0;
   6300   else
   6301     return -1;
   6302 }
   6303 
   6304 /* SET_SECTION_RELOCS ()
   6305 
   6306    Although this macro is originally used to set a relocation for each section,
   6307    we use it to sort relocations in the same section by the address of the
   6308    relocation.  */
   6309 
   6310 void
   6311 nds32_set_section_relocs (asection *sec, arelent ** relocs ATTRIBUTE_UNUSED,
   6312 			  unsigned int n ATTRIBUTE_UNUSED)
   6313 {
   6314   bfd *abfd ATTRIBUTE_UNUSED = sec->owner;
   6315   if (bfd_get_section_flags (abfd, sec) & (flagword) SEC_RELOC)
   6316     nds32_insertion_sort (sec->orelocation, sec->reloc_count,
   6317 			  sizeof (arelent**), compar_relent);
   6318 }
   6319 
   6320 long
   6321 nds32_pcrel_from_section (fixS *fixP, segT sec ATTRIBUTE_UNUSED)
   6322 {
   6323   if (fixP->fx_addsy == NULL || !S_IS_DEFINED (fixP->fx_addsy)
   6324       || S_IS_EXTERNAL (fixP->fx_addsy) || S_IS_WEAK (fixP->fx_addsy))
   6325     {
   6326       /* Let linker resolve undefined symbols.  */
   6327       return 0;
   6328     }
   6329 
   6330   return fixP->fx_frag->fr_address + fixP->fx_where;
   6331 }
   6332 
   6333 /* md_post_relax_hook ()
   6334    Insert relax entry relocation into sections.  */
   6335 
   6336 void
   6337 nds32_post_relax_hook (void)
   6338 {
   6339   bfd_map_over_sections (stdoutput, nds32_insert_relax_entry, NULL);
   6340 }
   6341 
   6342 /* tc_fix_adjustable ()
   6343 
   6344    Return whether this symbol (fixup) can be replaced with
   6345    section symbols.  */
   6346 
   6347 bfd_boolean
   6348 nds32_fix_adjustable (fixS *fixP)
   6349 {
   6350   switch (fixP->fx_r_type)
   6351     {
   6352     case BFD_RELOC_NDS32_WORD_9_PCREL:
   6353     case BFD_RELOC_NDS32_9_PCREL:
   6354     case BFD_RELOC_NDS32_15_PCREL:
   6355     case BFD_RELOC_NDS32_17_PCREL:
   6356     case BFD_RELOC_NDS32_25_PCREL:
   6357     case BFD_RELOC_NDS32_HI20:
   6358     case BFD_RELOC_NDS32_LO12S0:
   6359     case BFD_RELOC_8:
   6360     case BFD_RELOC_16:
   6361     case BFD_RELOC_32:
   6362     case BFD_RELOC_NDS32_PTR:
   6363     case BFD_RELOC_NDS32_LONGCALL4:
   6364     case BFD_RELOC_NDS32_LONGCALL5:
   6365     case BFD_RELOC_NDS32_LONGCALL6:
   6366     case BFD_RELOC_NDS32_LONGJUMP4:
   6367     case BFD_RELOC_NDS32_LONGJUMP5:
   6368     case BFD_RELOC_NDS32_LONGJUMP6:
   6369     case BFD_RELOC_NDS32_LONGJUMP7:
   6370       return 1;
   6371     default:
   6372       return 0;
   6373     }
   6374 }
   6375 
   6376 /* elf_tc_final_processing  */
   6377 
   6378 void
   6379 elf_nds32_final_processing (void)
   6380 {
   6381   /* An FPU_COM instruction is found without previous non-FPU_COM
   6382      instruction.  */
   6383   if (nds32_fpu_com
   6384       && !(nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
   6385     {
   6386       /* Since only FPU_COM instructions are used and no other FPU instructions
   6387 	 are used.  The nds32_elf_flags will be decided by the enabled options
   6388 	 by command line or default configuration.  */
   6389       if (nds32_fpu_dp_ext || nds32_fpu_sp_ext)
   6390 	{
   6391 	  nds32_elf_flags |= nds32_fpu_dp_ext ? E_NDS32_HAS_FPU_DP_INST : 0;
   6392 	  nds32_elf_flags |= nds32_fpu_sp_ext ? E_NDS32_HAS_FPU_INST : 0;
   6393 	}
   6394       else
   6395 	{
   6396 	  /* Should never here.  */
   6397 	  as_bad (_("Used FPU instructions requires enabling FPU extension"));
   6398 	}
   6399     }
   6400 
   6401   if (nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST))
   6402     {
   6403       /* Single/double FPU has been used, set FPU register config.  */
   6404       /* We did not check the actual number of register used.  We may
   6405 	 want to do it while assemble.  */
   6406       nds32_elf_flags &= ~E_NDS32_FPU_REG_CONF;
   6407       nds32_elf_flags |= (nds32_freg << E_NDS32_FPU_REG_CONF_SHIFT);
   6408     }
   6409 
   6410   if (nds32_pic)
   6411     nds32_elf_flags |= E_NDS32_HAS_PIC;
   6412 
   6413   if (nds32_gpr16)
   6414     nds32_elf_flags |= E_NDS32_HAS_REDUCED_REGS;
   6415 
   6416   nds32_elf_flags |= (E_NDS32_ELF_VER_1_4 | nds32_abi);
   6417   elf_elfheader (stdoutput)->e_flags |= nds32_elf_flags;
   6418 }
   6419 
   6420 /* Implement md_apply_fix.  Apply the fix-up or tranform the fix-up for
   6421    later relocation generation.  */
   6422 
   6423 void
   6424 nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
   6425 {
   6426   char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
   6427   bfd_vma value = *valP;
   6428 
   6429   if (fixP->fx_r_type < BFD_RELOC_UNUSED
   6430       && fixP->fx_r_type > BFD_RELOC_NONE
   6431       && fixP->fx_r_type != BFD_RELOC_NDS32_DIFF_ULEB128)
   6432     {
   6433       /* In our old nds32 binutils, it must convert relocations which is
   6434 	 generated by CGEN.  However, it does not have to consider this anymore.
   6435 	 In current, it only deal with data relocations which enum
   6436 	 is smaller than BFD_RELOC_NONE and BFD_RELOC_NDS32_DIFF_ULEB128.
   6437 	 It is believed that we can construct a better mechanism to
   6438 	 deal with the whole relocation issue in nds32 target
   6439 	 without using CGEN.  */
   6440       fixP->fx_addnumber = value;
   6441       fixP->tc_fix_data = NULL;
   6442 
   6443       /* Tranform specific relocations here for later relocation generation.
   6444 	 Tag data here for ex9 relaxtion and tag tls data for linker.  */
   6445       switch (fixP->fx_r_type)
   6446 	{
   6447 	case BFD_RELOC_NDS32_DATA:
   6448 	  if (!enable_relax_ex9)
   6449 	    fixP->fx_done = 1;
   6450 	  break;
   6451 	case BFD_RELOC_NDS32_TPOFF:
   6452 	case BFD_RELOC_NDS32_TLS_LE_HI20:
   6453 	case BFD_RELOC_NDS32_TLS_LE_LO12:
   6454 	case BFD_RELOC_NDS32_TLS_LE_ADD:
   6455 	case BFD_RELOC_NDS32_TLS_LE_LS:
   6456 	case BFD_RELOC_NDS32_GOTTPOFF:
   6457 	case BFD_RELOC_NDS32_TLS_IE_HI20:
   6458 	case BFD_RELOC_NDS32_TLS_IE_LO12S2:
   6459 	  S_SET_THREAD_LOCAL (fixP->fx_addsy);
   6460 	  break;
   6461 	default:
   6462 	  break;
   6463 	}
   6464       return;
   6465     }
   6466 
   6467   if (fixP->fx_addsy == (symbolS *) NULL)
   6468     fixP->fx_done = 1;
   6469 
   6470   if (fixP->fx_subsy != (symbolS *) NULL)
   6471     {
   6472       /* HOW DIFF RELOCATION WORKS.
   6473 
   6474 	 First of all, this relocation is used to calculate the distance
   6475 	 between two symbols in the SAME section.  It is used for  jump-
   6476 	 table, debug information, exception table, et al.    Therefore,
   6477 	 it is a unsigned positive value.   It is NOT used for  general-
   6478 	 purpose arithmetic.
   6479 
   6480 	 Consider this example,  the distance between  .LEND and .LBEGIN
   6481 	 is stored at the address of foo.
   6482 
   6483 	 ---- >8 ---- >8 ---- >8 ---- >8 ----
   6484 	  .data
   6485 	  foo:
   6486 	    .word	.LBEGIN - .LEND
   6487 
   6488 	  .text
   6489 	     [before]
   6490 	  .LBEGIN
   6491 			 \
   6492 	     [between]    distance
   6493 			 /
   6494 	  .LEND
   6495 	     [after]
   6496 	 ---- 8< ---- 8< ---- 8< ---- 8< ----
   6497 
   6498 	 We use a single relocation entry for this expression.
   6499 	 * The initial distance value is stored direcly in that location
   6500 	   specified by r_offset (i.e., foo in this example.)
   6501 	 * The begin of the region, i.e., .LBEGIN, is specified by
   6502 	   r_info/R_SYM and r_addend, e.g., .text + 0x32.
   6503 	 * The end of region, i.e., .LEND, is represented by
   6504 	   .LBEGIN + distance instead of .LEND, so we only need
   6505 	   a single relocation entry instead of two.
   6506 
   6507 	 When an instruction is relaxed, we adjust the relocation entry
   6508 	 depending on where the instruction locates.    There are three
   6509 	 cases, before, after and between the region.
   6510 	 * between: Distance value is read from r_offset,  adjusted and
   6511 	   written back into r_offset.
   6512 	 * before: Only r_addend is adjust.
   6513 	 * after: We don't care about it.
   6514 
   6515 	 Hereby, there are some limitation.
   6516 
   6517 	 `(.LEND - 1) - .LBEGIN' and `(.LEND - .LBEGIN) - 1'
   6518 	 are semantically different, and we cannot handle latter case
   6519 	 when relaxation.
   6520 
   6521 	 The latter expression means subtracting 1 from the distance
   6522 	 between .LEND and .LBEGIN.  And the former expression means
   6523 	 the distance between (.LEND - 1) and .LBEGIN.
   6524 
   6525 	 The nuance affects whether to adjust distance value when relax
   6526 	 an instruction.  In another words, whether the instruction
   6527 	 locates in the region.  Because we use a single relocation entry,
   6528 	 there is no field left for .LEND and the subtrahend.
   6529 
   6530 	 Since GCC-4.5, GCC may produce debug information in such expression
   6531 	     .long  .L1-1-.L0
   6532 	 in order to describe register clobbering during an function-call.
   6533 	     .L0:
   6534 		call foo
   6535 	     .L1:
   6536 
   6537 	 Check http://gcc.gnu.org/ml/gcc-patches/2009-06/msg01317.html
   6538 	 for details.  */
   6539 
   6540       value -= S_GET_VALUE (fixP->fx_subsy);
   6541       *valP = value;
   6542       fixP->fx_subsy = NULL;
   6543       fixP->fx_offset -= value;
   6544 
   6545       switch (fixP->fx_r_type)
   6546 	{
   6547 	case BFD_RELOC_8:
   6548 	  fixP->fx_r_type = BFD_RELOC_NDS32_DIFF8;
   6549 	  md_number_to_chars (where, value, 1);
   6550 	  break;
   6551 	case BFD_RELOC_16:
   6552 	  fixP->fx_r_type = BFD_RELOC_NDS32_DIFF16;
   6553 	  md_number_to_chars (where, value, 2);
   6554 	  break;
   6555 	case BFD_RELOC_32:
   6556 	  fixP->fx_r_type = BFD_RELOC_NDS32_DIFF32;
   6557 	  md_number_to_chars (where, value, 4);
   6558 	  break;
   6559 	case BFD_RELOC_NDS32_DIFF_ULEB128:
   6560 	  /* cvt_frag_to_fill () has called output_leb128 () for us.  */
   6561 	  break;
   6562 	default:
   6563 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   6564 			_("expression too complex"));
   6565 	  return;
   6566 	}
   6567     }
   6568   else if (fixP->fx_done)
   6569     {
   6570       /* We're finished with this fixup.  Install it because
   6571 	 bfd_install_relocation won't be called to do it.  */
   6572       switch (fixP->fx_r_type)
   6573 	{
   6574 	case BFD_RELOC_8:
   6575 	  md_number_to_chars (where, value, 1);
   6576 	  break;
   6577 	case BFD_RELOC_16:
   6578 	  md_number_to_chars (where, value, 2);
   6579 	  break;
   6580 	case BFD_RELOC_32:
   6581 	  md_number_to_chars (where, value, 4);
   6582 	  break;
   6583 	case BFD_RELOC_64:
   6584 	  md_number_to_chars (where, value, 8);
   6585 	default:
   6586 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   6587 			_("Internal error: Unknown fixup type %d (`%s')"),
   6588 			fixP->fx_r_type,
   6589 			bfd_get_reloc_code_name (fixP->fx_r_type));
   6590 	  break;
   6591 	}
   6592     }
   6593 }
   6594 
   6595 /* Implement tc_gen_reloc.  Generate ELF relocation for a fix-up.  */
   6596 
   6597 arelent *
   6598 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
   6599 {
   6600   arelent *reloc;
   6601   bfd_reloc_code_real_type code;
   6602 
   6603   reloc = XNEW (arelent);
   6604 
   6605   reloc->sym_ptr_ptr = XNEW (asymbol *);
   6606   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
   6607   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
   6608 
   6609   code = fixP->fx_r_type;
   6610 
   6611   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
   6612   if (reloc->howto == (reloc_howto_type *) NULL)
   6613     {
   6614       as_bad_where (fixP->fx_file, fixP->fx_line,
   6615 		    _("internal error: can't export reloc type %d (`%s')"),
   6616 		    fixP->fx_r_type, bfd_get_reloc_code_name (code));
   6617       return NULL;
   6618     }
   6619 
   6620   /* Add relocation handling here.  */
   6621 
   6622   switch (fixP->fx_r_type)
   6623     {
   6624     default:
   6625       /* In general, addend of a relocation is the offset to the
   6626 	 associated symbol.  */
   6627       reloc->addend = fixP->fx_offset;
   6628       break;
   6629 
   6630     case BFD_RELOC_NDS32_DATA:
   6631       /* Prevent linker from optimizing data in text sections.
   6632 	 For example, jump table.  */
   6633       reloc->addend = fixP->fx_size;
   6634       break;
   6635     }
   6636 
   6637   return reloc;
   6638 }
   6639 
   6640 struct suffix_name suffix_table[] =
   6641 {
   6642   {"GOTOFF",	BFD_RELOC_NDS32_GOTOFF,	1},
   6643   {"GOT",	BFD_RELOC_NDS32_GOT20,	1},
   6644   {"TPOFF",	BFD_RELOC_NDS32_TPOFF,	0},
   6645   {"PLT",	BFD_RELOC_NDS32_25_PLTREL,	1},
   6646   {"GOTTPOFF",	BFD_RELOC_NDS32_GOTTPOFF,	0}
   6647 };
   6648 
   6649 /* Implement md_parse_name.  */
   6650 
   6651 int
   6652 nds32_parse_name (char const *name, expressionS *exprP,
   6653 		  enum expr_mode mode ATTRIBUTE_UNUSED,
   6654 		  char *nextcharP ATTRIBUTE_UNUSED)
   6655 {
   6656   segT segment;
   6657 
   6658   exprP->X_op_symbol = NULL;
   6659   exprP->X_md = BFD_RELOC_UNUSED;
   6660 
   6661   exprP->X_add_symbol = symbol_find_or_make (name);
   6662   exprP->X_op = O_symbol;
   6663   exprP->X_add_number = 0;
   6664 
   6665   /* Check the specail name if a symbol.  */
   6666   segment = S_GET_SEGMENT (exprP->X_add_symbol);
   6667   if (segment != undefined_section)
   6668     return 0;
   6669 
   6670   if (strcmp (name, GOT_NAME) == 0 && *nextcharP != '@')
   6671     {
   6672       /* Set for _GOT_OFFSET_TABLE_.  */
   6673       exprP->X_md = BFD_RELOC_NDS32_GOTPC20;
   6674     }
   6675   else if (*nextcharP == '@')
   6676     {
   6677       size_t i;
   6678       char *next;
   6679       for (i = 0; i < ARRAY_SIZE (suffix_table); i++)
   6680 	{
   6681 	  next = input_line_pointer + 1 + strlen(suffix_table[i].suffix);
   6682 	  if (strncasecmp (input_line_pointer + 1, suffix_table[i].suffix,
   6683 			   strlen (suffix_table[i].suffix)) == 0
   6684 	      && !is_part_of_name (*next))
   6685 	    {
   6686 	      if (!nds32_pic && suffix_table[i].pic)
   6687 		as_bad (_("need PIC qualifier with symbol."));
   6688 	      exprP->X_md = suffix_table[i].reloc;
   6689 	      *input_line_pointer = *nextcharP;
   6690 	      input_line_pointer = next;
   6691 	      *nextcharP = *input_line_pointer;
   6692 	      *input_line_pointer = '\0';
   6693 	      break;
   6694 	    }
   6695 	}
   6696     }
   6697   return 1;
   6698 }
   6699 
   6700 /* Implement tc_regname_to_dw2regnum.  */
   6701 
   6702 int
   6703 tc_nds32_regname_to_dw2regnum (char *regname)
   6704 {
   6705   struct nds32_keyword *sym = hash_find (nds32_gprs_hash, regname);
   6706 
   6707   if (!sym)
   6708     return -1;
   6709 
   6710   return sym->value;
   6711 }
   6712 
   6713 void
   6714 tc_nds32_frame_initial_instructions (void)
   6715 {
   6716   /* CIE */
   6717   /* Default cfa is register-31/sp.  */
   6718   cfi_add_CFA_def_cfa (31, 0);
   6719 }
   6720