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