Update year range in copyright notice of all files.
[external/binutils.git] / gas / config / tc-nds32.c
1 /* tc-nds32.c -- Assemble for the nds32
2    Copyright (C) 2012-2017 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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 aligment.  */
3413
3414 /* This code is referred from D30V for adjust label to be with pedning
3415    aligment.  For example,
3416      LBYTE: .byte       0x12
3417      LHALF: .half       0x12
3418      LWORD: .word       0x12
3419    Without this, the above label will not attatch to incoming data.  */
3420
3421 static void
3422 nds32_adjust_label (int n)
3423 {
3424   /* FIXME: I think adjust lable and alignment is
3425      the programmer's obligation.  Saddly, 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 implmentation 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 incommng 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 lable 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 pupose 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 veriation 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 sequance.  */
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 (_("Not support instrcution %s 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 msut 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 instrucion 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 insturction 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 insntruction 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 previos 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 lable.  */
5663           if (frag_t->tc_frag_data.flag & NDS32_FRAG_LABEL)
5664             {
5665               prev_frag = NULL;
5666               return;
5667             }
5668           /* Relax previos 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        unendless loop when relaxing.  Once the instruction is relaxed,
5724        it can not be undo.  */
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 previos 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 previos 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              insntruction 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 linke-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 relaxtion 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 direcly 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 specail 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 }