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