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