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