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