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