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