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