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