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