1 /* tc-nds32.c -- Assemble for the nds32
2    Copyright (C) 2012-2021 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   s = input_line_pointer;
2523   input_line_pointer = tmp;	/* Restore line pointer.  */
2524 
2525   return s;			/* Return pointer to where parsing stopped.  */
2526 }
2527 
2528 void
nds32_start_line_hook(void)2529 nds32_start_line_hook (void)
2530 {
2531 }
2532 
2533 /*
2534  * Pseudo opcodes
2535  */
2536 
2537 typedef void (*nds32_pseudo_opcode_func) (int argc, char *argv[], unsigned int pv);
2538 struct nds32_pseudo_opcode
2539 {
2540   const char *opcode;
2541   int argc;
2542   nds32_pseudo_opcode_func proc;
2543   unsigned int pseudo_val;
2544 
2545   /* Some instructions are not pseudo opcode, but they might still be
2546      expanded or changed with other instruction combination for some
2547      conditions.  We also apply this structure to assist such work.
2548 
2549      For example, if the distance of branch target '.L0' is larger than
2550      imm8s<<1 range,
2551 
2552      the instruction:
2553 
2554          beqzs8 .L0
2555 
2556      will be transformed into:
2557 
2558          bnezs8  .LCB0
2559          j  .L0
2560        .LCB0:
2561 
2562      However, sometimes we do not want assembler to do such changes
2563      because compiler knows how to generate corresponding instruction sequence.
2564      Use this field to indicate that this opcode is also a physical instruction.
2565      If the flag 'verbatim' is nozero and this opcode
2566      is a physical instruction, we should not expand it.  */
2567   int physical_op;
2568 };
2569 #define PV_DONT_CARE 0
2570 
2571 static htab_t nds32_pseudo_opcode_hash = NULL;
2572 
2573 static int
builtin_isreg(const char * s,const char * x ATTRIBUTE_UNUSED)2574 builtin_isreg (const char *s, const char *x ATTRIBUTE_UNUSED)
2575 {
2576   if (s [0] == '$' && str_hash_find (nds32_gprs_hash, (s + 1)))
2577     return 1;
2578   return 0;
2579 }
2580 
2581 static int
builtin_regnum(const char * s,const char * x ATTRIBUTE_UNUSED)2582 builtin_regnum (const char *s, const char *x ATTRIBUTE_UNUSED)
2583 {
2584   struct nds32_keyword *k;
2585   if (*s != '$')
2586     return -1;
2587   s++;
2588   k = str_hash_find (nds32_gprs_hash, s);
2589 
2590   if (k == NULL)
2591     return -1;
2592 
2593   return k->value;
2594 }
2595 
2596 static int
builtin_addend(const char * s,char * x ATTRIBUTE_UNUSED)2597 builtin_addend (const char *s, char *x ATTRIBUTE_UNUSED)
2598 {
2599   const char *ptr = s;
2600 
2601   while (*ptr != '+' && *ptr != '-' && *ptr)
2602     ++ptr;
2603 
2604   if (*ptr == 0)
2605     return 0;
2606   else
2607     return strtol (ptr, NULL, 0);
2608 }
2609 
2610 static void
md_assemblef(const char * format,...)2611 md_assemblef (const char *format, ...)
2612 {
2613   /* FIXME: hope this is long enough.  */
2614   char line[1024];
2615   va_list ap;
2616   unsigned int r;
2617 
2618   va_start (ap, format);
2619   r = vsnprintf (line, sizeof (line), format, ap);
2620   md_assemble (line);
2621 
2622   gas_assert (r < sizeof (line));
2623 }
2624 
2625 /* Some prototypes here, since some op may use another op.  */
2626 static void do_pseudo_li_internal (const char *rt, int imm32s);
2627 static void do_pseudo_move_reg_internal (char *dst, char *src);
2628 
2629 static void
do_pseudo_b(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)2630 do_pseudo_b (int argc ATTRIBUTE_UNUSED, char *argv[],
2631 	     unsigned int pv ATTRIBUTE_UNUSED)
2632 {
2633   char *arg_label = argv[0];
2634   relaxing = true;
2635   /* b   label */
2636   if (nds32_pic)
2637     {
2638       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
2639       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
2640       md_assemble  ((char *) "add $ta,$ta,$gp");
2641       md_assemble  ((char *) "jr $ta");
2642     }
2643   else
2644     {
2645       md_assemblef ("j %s", arg_label);
2646     }
2647   relaxing = false;
2648 }
2649 
2650 static void
do_pseudo_bal(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)2651 do_pseudo_bal (int argc ATTRIBUTE_UNUSED, char *argv[],
2652 	       unsigned int pv ATTRIBUTE_UNUSED)
2653 {
2654   char *arg_label = argv[0];
2655   relaxing = true;
2656   /* bal|call  label */
2657   if (nds32_pic)
2658     {
2659       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
2660       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
2661       md_assemble ((char *) "add $ta,$ta,$gp");
2662       md_assemble ((char *) "jral $ta");
2663     }
2664   else
2665     {
2666       md_assemblef ("jal %s", arg_label);
2667     }
2668   relaxing = false;
2669 }
2670 
2671 static void
do_pseudo_bge(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)2672 do_pseudo_bge (int argc ATTRIBUTE_UNUSED, char *argv[],
2673 	       unsigned int pv ATTRIBUTE_UNUSED)
2674 {
2675   /* rt5, ra5, label */
2676   md_assemblef ("slt $ta,%s,%s", argv[0], argv[1]);
2677   md_assemblef ("beqz $ta,%s", argv[2]);
2678 }
2679 
2680 static void
do_pseudo_bges(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)2681 do_pseudo_bges (int argc ATTRIBUTE_UNUSED, char *argv[],
2682 		unsigned int pv ATTRIBUTE_UNUSED)
2683 {
2684   /* rt5, ra5, label */
2685   md_assemblef ("slts $ta,%s,%s", argv[0], argv[1]);
2686   md_assemblef ("beqz $ta,%s", argv[2]);
2687 }
2688 
2689 static void
do_pseudo_bgt(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)2690 do_pseudo_bgt (int argc ATTRIBUTE_UNUSED, char *argv[],
2691 	       unsigned int pv ATTRIBUTE_UNUSED)
2692 {
2693   /* bgt rt5, ra5, label */
2694   md_assemblef ("slt $ta,%s,%s", argv[1], argv[0]);
2695   md_assemblef ("bnez $ta,%s", argv[2]);
2696 }
2697 
2698 static void
do_pseudo_bgts(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)2699 do_pseudo_bgts (int argc ATTRIBUTE_UNUSED, char *argv[],
2700 		unsigned int pv ATTRIBUTE_UNUSED)
2701 {
2702   /* bgt rt5, ra5, label */
2703   md_assemblef ("slts $ta,%s,%s", argv[1], argv[0]);
2704   md_assemblef ("bnez $ta,%s", argv[2]);
2705 }
2706 
2707 static void
do_pseudo_ble(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)2708 do_pseudo_ble (int argc ATTRIBUTE_UNUSED, char *argv[],
2709 	       unsigned int pv ATTRIBUTE_UNUSED)
2710 {
2711   /* bgt rt5, ra5, label */
2712   md_assemblef ("slt $ta,%s,%s", argv[1], argv[0]);
2713   md_assemblef ("beqz $ta,%s", argv[2]);
2714 }
2715 
2716 static void
do_pseudo_bles(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)2717 do_pseudo_bles (int argc ATTRIBUTE_UNUSED, char *argv[],
2718 		unsigned int pv ATTRIBUTE_UNUSED)
2719 {
2720   /* bgt rt5, ra5, label */
2721   md_assemblef ("slts $ta,%s,%s", argv[1], argv[0]);
2722   md_assemblef ("beqz $ta,%s", argv[2]);
2723 }
2724 
2725 static void
do_pseudo_blt(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)2726 do_pseudo_blt (int argc ATTRIBUTE_UNUSED, char *argv[],
2727 	       unsigned int pv ATTRIBUTE_UNUSED)
2728 {
2729   /* rt5, ra5, label */
2730   md_assemblef ("slt $ta,%s,%s", argv[0], argv[1]);
2731   md_assemblef ("bnez $ta,%s", argv[2]);
2732 }
2733 
2734 static void
do_pseudo_blts(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)2735 do_pseudo_blts (int argc ATTRIBUTE_UNUSED, char *argv[],
2736 		unsigned int pv ATTRIBUTE_UNUSED)
2737 {
2738   /* rt5, ra5, label */
2739   md_assemblef ("slts $ta,%s,%s", argv[0], argv[1]);
2740   md_assemblef ("bnez $ta,%s", argv[2]);
2741 }
2742 
2743 static void
do_pseudo_br(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)2744 do_pseudo_br (int argc ATTRIBUTE_UNUSED, char *argv[],
2745 	      unsigned int pv ATTRIBUTE_UNUSED)
2746 {
2747   md_assemblef ("jr %s", argv[0]);
2748 }
2749 
2750 static void
do_pseudo_bral(int argc,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)2751 do_pseudo_bral (int argc, char *argv[],
2752 		unsigned int pv ATTRIBUTE_UNUSED)
2753 {
2754   if (argc == 1)
2755     md_assemblef ("jral $lp,%s", argv[0]);
2756   else
2757     md_assemblef ("jral %s,%s", argv[0], argv[1]);
2758 }
2759 
2760 static void
do_pseudo_la_internal(const char * arg_reg,char * arg_label,const char * line)2761 do_pseudo_la_internal (const char *arg_reg, char *arg_label,
2762 		       const char *line)
2763 {
2764   expressionS exp;
2765 
2766   parse_expression (arg_label, &exp);
2767   if (exp.X_op != O_symbol)
2768     {
2769       as_bad (_("la must use with symbol. '%s'"), line);
2770       return;
2771     }
2772 
2773   relaxing = true;
2774   /* rt, label */
2775   if (!nds32_pic && !strstr (arg_label, "@"))
2776     {
2777       md_assemblef ("sethi %s,hi20(%s)", arg_reg, arg_label);
2778       md_assemblef ("ori %s,%s,lo12(%s)", arg_reg, arg_reg, arg_label);
2779     }
2780   else if (strstr (arg_label, "@TPOFF"))
2781     {
2782       /* la $rt, sym@TPOFF  */
2783       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
2784       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
2785       md_assemblef ("add %s,$ta,%s", arg_reg, TLS_REG);
2786     }
2787   else if (strstr(arg_label, "@GOTTPOFF"))
2788     {
2789       /* la $rt, sym@GOTTPOFF*/
2790       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
2791       md_assemblef ("lwi $ta,[$ta+lo12(%s)]", arg_label);
2792       md_assemblef ("add %s,$ta,%s", arg_reg, TLS_REG);
2793     }
2794   else if (nds32_pic && ((strstr (arg_label, "@PLT")
2795 			  || strstr (arg_label, "@GOTOFF"))))
2796     {
2797       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
2798       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
2799       md_assemblef ("add %s,$ta,$gp", arg_reg);
2800     }
2801   else if (nds32_pic && strstr (arg_label, "@GOT"))
2802     {
2803       long addend = builtin_addend (arg_label, NULL);
2804 
2805       md_assemblef ("sethi $ta,hi20(%s)", arg_label);
2806       md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
2807       md_assemblef ("lw %s,[$gp+$ta]", arg_reg);
2808       if (addend != 0)
2809 	{
2810 	  if (addend < 0x4000 && addend >= -0x4000)
2811 	    {
2812 	      md_assemblef ("addi %s,%s,%d", arg_reg, arg_reg, addend);
2813 	    }
2814 	  else
2815 	    {
2816 	      do_pseudo_li_internal ("$ta", addend);
2817 	      md_assemblef ("add %s,$ta,%s", arg_reg, arg_reg);
2818 	    }
2819 	}
2820     }
2821    else
2822       as_bad (_("need PIC qualifier with symbol. '%s'"), line);
2823   relaxing = false;
2824 }
2825 
2826 static void
do_pseudo_la(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)2827 do_pseudo_la (int argc ATTRIBUTE_UNUSED, char *argv[],
2828 	      unsigned int pv ATTRIBUTE_UNUSED)
2829 {
2830   do_pseudo_la_internal (argv[0], argv[1], argv[argc]);
2831 }
2832 
2833 static void
do_pseudo_li_internal(const char * rt,int imm32s)2834 do_pseudo_li_internal (const char *rt, int imm32s)
2835 {
2836   if (enable_16bit && imm32s <= 0xf && imm32s >= -0x10)
2837     md_assemblef ("movi55 %s,%d", rt, imm32s);
2838   else if (imm32s <= 0x7ffff && imm32s >= -0x80000)
2839     md_assemblef ("movi %s,%d", rt, imm32s);
2840   else if ((imm32s & 0xfff) == 0)
2841     md_assemblef ("sethi %s,hi20(%d)", rt, imm32s);
2842   else
2843     {
2844       md_assemblef ("sethi %s,hi20(%d)", rt, imm32s);
2845       md_assemblef ("ori %s,%s,lo12(%d)", rt, rt, imm32s);
2846     }
2847 }
2848 
2849 static void
do_pseudo_li(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)2850 do_pseudo_li (int argc ATTRIBUTE_UNUSED, char *argv[],
2851 	      unsigned int pv ATTRIBUTE_UNUSED)
2852 {
2853   /* Validate argv[1] for constant expression.  */
2854   expressionS exp;
2855 
2856   parse_expression (argv[1], &exp);
2857   if (exp.X_op != O_constant)
2858     {
2859       as_bad (_("Operand is not a constant. `%s'"), argv[argc]);
2860       return;
2861     }
2862 
2863   do_pseudo_li_internal (argv[0], exp.X_add_number);
2864 }
2865 
2866 static void
do_pseudo_ls_bhw(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv)2867 do_pseudo_ls_bhw (int argc ATTRIBUTE_UNUSED, char *argv[],
2868 		  unsigned int pv)
2869 {
2870   char ls = 'r';
2871   char size = 'x';
2872   const char *sign = "";
2873 
2874   /* Prepare arguments for various load/store.  */
2875   sign = (pv & 0x10) ? "s" : "";
2876   ls = (pv & 0x80000000) ? 's' : 'l';
2877   switch (pv & 0x3)
2878     {
2879     case 0: size = 'b'; break;
2880     case 1: size = 'h'; break;
2881     case 2: size = 'w'; break;
2882     }
2883 
2884   if (ls == 's' || size == 'w')
2885     sign = "";
2886 
2887   if (builtin_isreg (argv[1], NULL))
2888     {
2889       /* lwi */
2890       md_assemblef ("%c%ci %s,[%s]", ls, size, argv[0], argv[1]);
2891     }
2892   else if (!nds32_pic)
2893     {
2894       relaxing = true;
2895       if (strstr (argv[1], "@TPOFF"))
2896 	{
2897 	  /* ls.w $rt, sym@TPOFF  */
2898 	  md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
2899 	  md_assemblef ("ori $ta,$ta,lo12(%s)", argv[1]);
2900 	  md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], TLS_REG);
2901 	}
2902       else if (strstr (argv[1], "@GOTTPOFF"))
2903 	{
2904 	  /* ls.w $rt, sym@GOTTPOFF  */
2905 	  md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
2906 	  md_assemblef ("lwi $ta,[$ta+lo12(%s)]", argv[1]);
2907 	  md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], TLS_REG);
2908 	}
2909       else
2910 	{
2911 	  /* lwi */
2912 	  md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
2913 	  md_assemblef ("%c%c%si %s,[$ta+lo12(%s)]", ls, size, sign, argv[0], argv[1]);
2914 	}
2915       relaxing = false;
2916     }
2917   else
2918     {
2919       relaxing = true;
2920       /* PIC code.  */
2921       if (strstr (argv[1], "@GOTOFF"))
2922 	{
2923 	  /* lw */
2924 	  md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
2925 	  md_assemblef ("ori $ta,$ta,lo12(%s)", argv[1]);
2926 	  md_assemblef ("%c%c%s %s,[$ta+$gp]", ls, size, sign, argv[0]);
2927 	}
2928       else if (strstr (argv[1], "@GOT"))
2929 	{
2930 	  long addend = builtin_addend (argv[1], NULL);
2931 	  /* lw */
2932 	  md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
2933 	  md_assemblef ("ori $ta,$ta,lo12(%s)", argv[1]);
2934 	  md_assemble ((char *) "lw $ta,[$gp+$ta]");	/* Load address word.  */
2935 	  if (addend < 0x10000 && addend >= -0x10000)
2936 	    {
2937 	      md_assemblef ("%c%c%si %s,[$ta+(%d)]", ls, size, sign, argv[0], addend);
2938 	    }
2939 	  else
2940 	    {
2941 	      /* lw */
2942 	      do_pseudo_li_internal (argv[0], addend);
2943 	      md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], argv[0]);
2944 	    }
2945 	}
2946       else
2947 	{
2948 	  as_bad (_("needs @GOT or @GOTOFF. %s"), argv[argc]);
2949 	}
2950       relaxing = false;
2951     }
2952 }
2953 
2954 static void
do_pseudo_ls_bhwp(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv)2955 do_pseudo_ls_bhwp (int argc ATTRIBUTE_UNUSED, char *argv[],
2956 		   unsigned int pv)
2957 {
2958   char *arg_rt = argv[0];
2959   char *arg_label = argv[1];
2960   char *arg_inc = argv[2];
2961   char ls = 'r';
2962   char size = 'x';
2963   const char *sign = "";
2964 
2965   /* Prepare arguments for various load/store.  */
2966   sign = (pv & 0x10) ? "s" : "";
2967   ls = (pv & 0x80000000) ? 's' : 'l';
2968   switch (pv & 0x3)
2969     {
2970     case 0: size = 'b'; break;
2971     case 1: size = 'h'; break;
2972     case 2: size = 'w'; break;
2973     }
2974 
2975   if (ls == 's' || size == 'w')
2976     sign = "";
2977 
2978   do_pseudo_la_internal ("$ta", arg_label, argv[argc]);
2979   md_assemblef ("%c%c%si.bi %s,[$ta],%s", ls, size, sign, arg_rt, arg_inc);
2980 }
2981 
2982 static void
do_pseudo_ls_bhwpc(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv)2983 do_pseudo_ls_bhwpc (int argc ATTRIBUTE_UNUSED, char *argv[],
2984 		    unsigned int pv)
2985 {
2986   char *arg_rt = argv[0];
2987   char *arg_inc = argv[1];
2988   char ls = 'r';
2989   char size = 'x';
2990   const char *sign = "";
2991 
2992   /* Prepare arguments for various load/store.  */
2993   sign = (pv & 0x10) ? "s" : "";
2994   ls = (pv & 0x80000000) ? 's' : 'l';
2995   switch (pv & 0x3)
2996     {
2997     case 0: size = 'b'; break;
2998     case 1: size = 'h'; break;
2999     case 2: size = 'w'; break;
3000     }
3001 
3002   if (ls == 's' || size == 'w')
3003     sign = "";
3004 
3005   md_assemblef ("%c%c%si.bi %s,[$ta],%s", ls, size, sign, arg_rt, arg_inc);
3006 }
3007 
3008 static void
do_pseudo_ls_bhwi(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv)3009 do_pseudo_ls_bhwi (int argc ATTRIBUTE_UNUSED, char *argv[],
3010 		   unsigned int pv)
3011 {
3012   char ls = 'r';
3013   char size = 'x';
3014   const char *sign = "";
3015 
3016   /* Prepare arguments for various load/store.  */
3017   sign = (pv & 0x10) ? "s" : "";
3018   ls = (pv & 0x80000000) ? 's' : 'l';
3019   switch (pv & 0x3)
3020     {
3021     case 0: size = 'b'; break;
3022     case 1: size = 'h'; break;
3023     case 2: size = 'w'; break;
3024     }
3025 
3026   if (ls == 's' || size == 'w')
3027     sign = "";
3028 
3029   md_assemblef ("%c%c%si.bi %s,%s,%s",
3030 		ls, size, sign, argv[0], argv[1], argv[2]);
3031 }
3032 
3033 static void
do_pseudo_move_reg_internal(char * dst,char * src)3034 do_pseudo_move_reg_internal (char *dst, char *src)
3035 {
3036   if (enable_16bit)
3037     md_assemblef ("mov55 %s,%s", dst, src);
3038   else
3039     md_assemblef ("ori %s,%s,0", dst, src);
3040 }
3041 
3042 static void
do_pseudo_move(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)3043 do_pseudo_move (int argc ATTRIBUTE_UNUSED, char *argv[],
3044 		unsigned int pv ATTRIBUTE_UNUSED)
3045 {
3046   expressionS exp;
3047 
3048   if (builtin_isreg (argv[1], NULL))
3049     do_pseudo_move_reg_internal (argv[0], argv[1]);
3050   else
3051     {
3052       parse_expression (argv[1], &exp);
3053       if (exp.X_op == O_constant)
3054 	/* move $rt, imm  -> li $rt, imm  */
3055 	do_pseudo_li_internal (argv[0], exp.X_add_number);
3056       else
3057 	/* l.w $rt, var  -> l.w $rt, var  */
3058 	do_pseudo_ls_bhw (argc, argv, 2);
3059     }
3060 }
3061 
3062 static void
do_pseudo_neg(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)3063 do_pseudo_neg (int argc ATTRIBUTE_UNUSED, char *argv[],
3064 	       unsigned int pv ATTRIBUTE_UNUSED)
3065 {
3066   /* Instead of "subri".  */
3067   md_assemblef ("subri %s,%s,0", argv[0], argv[1]);
3068 }
3069 
3070 static void
do_pseudo_not(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)3071 do_pseudo_not (int argc ATTRIBUTE_UNUSED, char *argv[],
3072 	       unsigned int pv ATTRIBUTE_UNUSED)
3073 {
3074   md_assemblef ("nor %s,%s,%s", argv[0], argv[1], argv[1]);
3075 }
3076 
3077 static void
do_pseudo_pushpopm(int argc,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)3078 do_pseudo_pushpopm (int argc, char *argv[],
3079 		    unsigned int pv ATTRIBUTE_UNUSED)
3080 {
3081   /* posh/pop $ra, $rb */
3082   /* SMW.{b | a}{i | d}{m?} Rb, [Ra], Re, Enable4 */
3083   int rb, re, ra, en4;
3084   int i;
3085   const char *opc = "pushpopm";
3086 
3087   if (argc == 3)
3088     as_bad ("'pushm/popm $ra5, $rb5, $label' is deprecated.  "
3089 	    "Only 'pushm/popm $ra5' is supported now. %s", argv[argc]);
3090   else if (argc == 1)
3091     as_bad ("'pushm/popm $ra5, $rb5'. %s\n", argv[argc]);
3092 
3093   if (strstr (argv[argc], "pop") == argv[argc])
3094     opc = "lmw.bim";
3095   else if (strstr (argv[argc], "push") == argv[argc])
3096     opc = "smw.adm";
3097   else
3098     as_fatal ("nds32-as internal error. %s", argv[argc]);
3099 
3100   rb = builtin_regnum (argv[0], NULL);
3101   re = builtin_regnum (argv[1], NULL);
3102 
3103   if (re < rb)
3104     {
3105       as_warn ("$rb should not be smaller than $ra. %s", argv[argc]);
3106       /* Swap to right order.  */
3107       ra = re;
3108       re = rb;
3109       rb = ra;
3110     }
3111 
3112   /* Build enable4 mask.  */
3113   en4 = 0;
3114   if (re >= 28 || rb >= 28)
3115     {
3116       for (i = (rb >= 28? rb: 28); i <= re; i++)
3117 	en4 |= 1 << (3 - (i - 28));
3118     }
3119 
3120   /* Adjust $re, $rb.  */
3121   if (rb >= 28)
3122     rb = re = 31;
3123   else if (nds32_gpr16 != 1 && re >= 28)
3124     re = 27;
3125 
3126   /* Reduce register.  */
3127   if (nds32_gpr16 && re > 10 && !(rb == 31 && re == 31))
3128     {
3129       if (re >= 15 && strstr (opc, "smw") != NULL)
3130 	md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
3131       if (rb <= 10)
3132 	md_assemblef ("%s $r%d,[$sp],$r10, 0x0", opc, rb);
3133       if (re >= 15 && strstr (opc, "lmw") != NULL)
3134 	md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
3135     }
3136   else
3137     md_assemblef ("%s $r%d,[$sp],$r%d,%d", opc, rb, re, en4);
3138 }
3139 
3140 static void
do_pseudo_pushpop(int argc,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)3141 do_pseudo_pushpop (int argc, char *argv[],
3142 		   unsigned int pv ATTRIBUTE_UNUSED)
3143 {
3144   /* push/pop $ra5, $label=$sp */
3145   char *argvm[3];
3146 
3147   if (argc == 2)
3148     as_bad ("'push/pop $ra5, rb5' is deprecated.  "
3149 	    "Only 'push/pop $ra5' is supported now. %s", argv[argc]);
3150 
3151   argvm[0] = argv[0];
3152   argvm[1] = argv[0];
3153   argvm[2] = argv[argc];
3154   do_pseudo_pushpopm (2, argvm, PV_DONT_CARE);
3155 }
3156 
3157 static void
do_pseudo_v3push(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)3158 do_pseudo_v3push (int argc ATTRIBUTE_UNUSED, char *argv[],
3159 		  unsigned int pv ATTRIBUTE_UNUSED)
3160 {
3161   md_assemblef ("push25 %s,%s", argv[0], argv[1]);
3162 }
3163 
3164 static void
do_pseudo_v3pop(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)3165 do_pseudo_v3pop (int argc ATTRIBUTE_UNUSED, char *argv[],
3166 		 unsigned int pv ATTRIBUTE_UNUSED)
3167 {
3168   md_assemblef ("pop25 %s,%s", argv[0], argv[1]);
3169 }
3170 
3171 /* pv == 0, parsing "push.s" pseudo instruction operands.
3172    pv != 0, parsing "pop.s" pseudo instruction operands.  */
3173 
3174 static void
do_pseudo_pushpop_stack(int argc,char * argv[],unsigned int pv)3175 do_pseudo_pushpop_stack (int argc, char *argv[],
3176 			 unsigned int pv)
3177 {
3178   /* push.s Rb,Re,{$fp $gp $lp $sp}  ==>  smw.adm Rb,[$sp],Re,Eable4  */
3179   /* pop.s Rb,Re,{$fp $gp $lp $sp}   ==>  lmw.bim Rb,[$sp],Re,Eable4  */
3180 
3181   int rb, re;
3182   int en4;
3183   int last_arg_index;
3184   const char *opc = (pv == 0) ? "smw.adm" : "lmw.bim";
3185 
3186   rb = re = 0;
3187 
3188   if (argc == 1)
3189     {
3190       /* argc=1, operands pattern: { $fp $gp $lp $sp }  */
3191 
3192       /* Set register number Rb = Re = $sp = $r31.  */
3193       rb = re = 31;
3194     }
3195   else if (argc == 2 || argc == 3)
3196     {
3197       /* argc=2, operands pattern: Rb, Re  */
3198       /* argc=3, operands pattern: Rb, Re, { $fp $gp $lp $sp }  */
3199 
3200       /* Get register number in integer.  */
3201       rb = builtin_regnum (argv[0], NULL);
3202       re = builtin_regnum (argv[1], NULL);
3203 
3204       /* Rb should be equal/less than Re.  */
3205       if (rb > re)
3206 	as_bad ("The first operand (%s) should be equal to or smaller than "
3207 		"second operand (%s).", argv[0], argv[1]);
3208 
3209       /* forbid using $fp|$gp|$lp|$sp in Rb or Re
3210 		      r28 r29 r30 r31  */
3211       if (rb >= 28)
3212 	as_bad ("Cannot use $fp, $gp, $lp, or $sp at first operand !!");
3213       if (re >= 28)
3214 	as_bad ("Cannot use $fp, $gp, $lp, or $sp at second operand !!");
3215     }
3216   else
3217     {
3218       as_bad ("Invalid operands pattern !!");
3219     }
3220 
3221   /* Build Enable4 mask.  */
3222   /* Using last_arg_index for argc=1|2|3 is safe, because $fp, $gp, $lp,
3223      and $sp only appear in argc=1 or argc=3 if argc=2, en4 remains 0,
3224      which is also valid for code generation.  */
3225   en4 = 0;
3226   last_arg_index = argc - 1;
3227   if (strstr (argv[last_arg_index], "$fp"))
3228     en4 |= 8;
3229   if (strstr (argv[last_arg_index], "$gp"))
3230     en4 |= 4;
3231   if (strstr (argv[last_arg_index], "$lp"))
3232     en4 |= 2;
3233   if (strstr (argv[last_arg_index], "$sp"))
3234     en4 |= 1;
3235 
3236   md_assemblef ("%s $r%d,[$sp],$r%d,%d", opc, rb, re, en4);
3237 }
3238 
3239 static void
do_pseudo_push_bhwd(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)3240 do_pseudo_push_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[],
3241 		     unsigned int pv ATTRIBUTE_UNUSED)
3242 {
3243   char size = 'x';
3244   /* If users omit push location, use $sp as default value.  */
3245   char location[8] = "$sp";  /* 8 is enough for register name.  */
3246 
3247   switch (pv & 0x3)
3248     {
3249     case 0: size = 'b'; break;
3250     case 1: size = 'h'; break;
3251     case 2: size = 'w'; break;
3252     case 3: size = 'w'; break;
3253     }
3254 
3255   if (argc == 2)
3256     {
3257       strncpy (location, argv[1], sizeof (location) - 1);
3258       location[sizeof (location) - 1] = '\0';
3259     }
3260 
3261   md_assemblef ("l.%c $ta,%s", size, argv[0]);
3262   md_assemblef ("smw.adm $ta,[%s],$ta", location);
3263 
3264   if ((pv & 0x3) == 0x3) /* double-word */
3265     {
3266       md_assemblef ("l.w $ta,%s+4", argv[0]);
3267       md_assemblef ("smw.adm $ta,[%s],$ta", location);
3268     }
3269 }
3270 
3271 static void
do_pseudo_pop_bhwd(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)3272 do_pseudo_pop_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[],
3273 		    unsigned int pv ATTRIBUTE_UNUSED)
3274 {
3275   char size = 'x';
3276   /* If users omit pop location, use $sp as default value.  */
3277   char location[8] = "$sp";  /* 8 is enough for register name.  */
3278 
3279   switch (pv & 0x3)
3280     {
3281     case 0: size = 'b'; break;
3282     case 1: size = 'h'; break;
3283     case 2: size = 'w'; break;
3284     case 3: size = 'w'; break;
3285     }
3286 
3287   if (argc == 3)
3288     {
3289       strncpy (location, argv[2], sizeof (location) - 1);
3290       location[sizeof (location) - 1] = '\0';
3291     }
3292 
3293   if ((pv & 0x3) == 0x3) /* double-word */
3294     {
3295       md_assemblef ("lmw.bim %s,[%s],%s", argv[1], location, argv[1]);
3296       md_assemblef ("s.w %s,%s+4", argv[1], argv[0]);
3297     }
3298 
3299   md_assemblef ("lmw.bim %s,[%s],%s", argv[1], location, argv[1]);
3300   md_assemblef ("s.%c %s,%s", size, argv[1], argv[0]);
3301 }
3302 
3303 static void
do_pseudo_pusha(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)3304 do_pseudo_pusha (int argc ATTRIBUTE_UNUSED, char *argv[],
3305 		 unsigned int pv ATTRIBUTE_UNUSED)
3306 {
3307   /* If users omit push location, use $sp as default value.  */
3308   char location[8] = "$sp";  /* 8 is enough for register name.  */
3309 
3310   if (argc == 2)
3311     {
3312       strncpy (location, argv[1], sizeof (location) - 1);
3313       location[sizeof (location) - 1] = '\0';
3314     }
3315 
3316   md_assemblef ("la $ta,%s", argv[0]);
3317   md_assemblef ("smw.adm $ta,[%s],$ta", location);
3318 }
3319 
3320 static void
do_pseudo_pushi(int argc ATTRIBUTE_UNUSED,char * argv[],unsigned int pv ATTRIBUTE_UNUSED)3321 do_pseudo_pushi (int argc ATTRIBUTE_UNUSED, char *argv[],
3322 		 unsigned int pv ATTRIBUTE_UNUSED)
3323 {
3324   /* If users omit push location, use $sp as default value.  */
3325   char location[8] = "$sp";  /* 8 is enough for register name.  */
3326 
3327   if (argc == 2)
3328     {
3329       strncpy (location, argv[1], sizeof (location) - 1);
3330       location[sizeof (location) - 1] = '\0';
3331     }
3332 
3333   md_assemblef ("li $ta,%s", argv[0]);
3334   md_assemblef ("smw.adm $ta,[%s],$ta", location);
3335 }
3336 
3337 static struct nds32_pseudo_opcode nds32_pseudo_opcode_table[] =
3338 {
3339   {"b",      1, do_pseudo_b,      0, 0},
3340   {"bal",    1, do_pseudo_bal,    0, 0},
3341 
3342   {"bge",    3, do_pseudo_bge,    0, 0},
3343   {"bges",   3, do_pseudo_bges,   0, 0},
3344 
3345   {"bgt",    3, do_pseudo_bgt,    0, 0},
3346   {"bgts",   3, do_pseudo_bgts,   0, 0},
3347 
3348   {"ble",    3, do_pseudo_ble,    0, 0},
3349   {"bles",   3, do_pseudo_bles,   0, 0},
3350 
3351   {"blt",    3, do_pseudo_blt,    0, 0},
3352   {"blts",   3, do_pseudo_blts,   0, 0},
3353 
3354   {"br",     1, do_pseudo_br,     0, 0},
3355   {"bral",   1, do_pseudo_bral,   0, 0},
3356 
3357   {"call",   1, do_pseudo_bal,    0, 0},
3358 
3359   {"la",     2, do_pseudo_la, 0, 0},
3360   {"li",     2, do_pseudo_li, 0, 0},
3361 
3362   {"l.b",    2, do_pseudo_ls_bhw, 0, 0},
3363   {"l.h",    2, do_pseudo_ls_bhw, 1, 0},
3364   {"l.w",    2, do_pseudo_ls_bhw, 2, 0},
3365   {"l.bs",   2, do_pseudo_ls_bhw, 0 | 0x10, 0},
3366   {"l.hs",   2, do_pseudo_ls_bhw, 1 | 0x10, 0},
3367   {"s.b",    2, do_pseudo_ls_bhw, 0 | 0x80000000, 0},
3368   {"s.h",    2, do_pseudo_ls_bhw, 1 | 0x80000000, 0},
3369   {"s.w",    2, do_pseudo_ls_bhw, 2 | 0x80000000, 0},
3370 
3371   {"l.bp",   3, do_pseudo_ls_bhwp, 0, 0},
3372   {"l.bpc",  3, do_pseudo_ls_bhwpc, 0, 0},
3373   {"l.hp",   3, do_pseudo_ls_bhwp, 1, 0},
3374   {"l.hpc",  3, do_pseudo_ls_bhwpc, 1, 0},
3375   {"l.wp",   3, do_pseudo_ls_bhwp, 2, 0},
3376   {"l.wpc",  3, do_pseudo_ls_bhwpc, 2, 0},
3377   {"l.bsp",  3, do_pseudo_ls_bhwp, 0 | 0x10, 0},
3378   {"l.bspc", 3, do_pseudo_ls_bhwpc, 0 | 0x10, 0},
3379   {"l.hsp",  3, do_pseudo_ls_bhwp, 1 | 0x10, 0},
3380   {"l.hspc", 3, do_pseudo_ls_bhwpc, 1 | 0x10, 0},
3381   {"s.bp",   3, do_pseudo_ls_bhwp, 0 | 0x80000000, 0},
3382   {"s.bpc",   3, do_pseudo_ls_bhwpc, 0 | 0x80000000, 0},
3383   {"s.hp",   3, do_pseudo_ls_bhwp, 1 | 0x80000000, 0},
3384   {"s.hpc",   3, do_pseudo_ls_bhwpc, 1 | 0x80000000, 0},
3385   {"s.wp",   3, do_pseudo_ls_bhwp, 2 | 0x80000000, 0},
3386   {"s.wpc",   3, do_pseudo_ls_bhwpc, 2 | 0x80000000, 0},
3387   {"s.bsp",  3, do_pseudo_ls_bhwp, 0 | 0x80000000 | 0x10, 0},
3388   {"s.hsp",  3, do_pseudo_ls_bhwp, 1 | 0x80000000 | 0x10, 0},
3389 
3390   {"lbi.p",  3, do_pseudo_ls_bhwi, 0, 0},
3391   {"lhi.p",  3, do_pseudo_ls_bhwi, 1, 0},
3392   {"lwi.p",  3, do_pseudo_ls_bhwi, 2, 0},
3393   {"sbi.p",  3, do_pseudo_ls_bhwi, 0 | 0x80000000, 0},
3394   {"shi.p",  3, do_pseudo_ls_bhwi, 1 | 0x80000000, 0},
3395   {"swi.p",  3, do_pseudo_ls_bhwi, 2 | 0x80000000, 0},
3396   {"lbsi.p", 3, do_pseudo_ls_bhwi, 0 | 0x10, 0},
3397   {"lhsi.p", 3, do_pseudo_ls_bhwi, 1 | 0x10, 0},
3398   {"lwsi.p", 3, do_pseudo_ls_bhwi, 2 | 0x10, 0},
3399 
3400   {"move",   2, do_pseudo_move, 0, 0},
3401   {"neg",    2, do_pseudo_neg,  0, 0},
3402   {"not",    2, do_pseudo_not,  0, 0},
3403 
3404   {"pop",    2, do_pseudo_pushpop,   0, 0},
3405   {"push",   2, do_pseudo_pushpop,   0, 0},
3406   {"popm",   2, do_pseudo_pushpopm,  0, 0},
3407   {"pushm",   3, do_pseudo_pushpopm, 0, 0},
3408 
3409   {"v3push", 2, do_pseudo_v3push, 0, 0},
3410   {"v3pop",  2, do_pseudo_v3pop,  0, 0},
3411 
3412   /* Support pseudo instructions of pushing/poping registers into/from stack
3413      push.s  Rb, Re, { $fp $gp $lp $sp }  ==>  smw.adm  Rb,[$sp],Re,Enable4
3414      pop.s   Rb, Re, { $fp $gp $lp $sp }  ==>  lmw.bim  Rb,[$sp],Re,Enable4 */
3415   { "push.s", 3, do_pseudo_pushpop_stack, 0, 0 },
3416   { "pop.s", 3, do_pseudo_pushpop_stack, 1, 0 },
3417   { "push.b", 2, do_pseudo_push_bhwd, 0, 0 },
3418   { "push.h", 2, do_pseudo_push_bhwd, 1, 0 },
3419   { "push.w", 2, do_pseudo_push_bhwd, 2, 0 },
3420   { "push.d", 2, do_pseudo_push_bhwd, 3, 0 },
3421   { "pop.b", 3, do_pseudo_pop_bhwd, 0, 0 },
3422   { "pop.h", 3, do_pseudo_pop_bhwd, 1, 0 },
3423   { "pop.w", 3, do_pseudo_pop_bhwd, 2, 0 },
3424   { "pop.d", 3, do_pseudo_pop_bhwd, 3, 0 },
3425   { "pusha", 2, do_pseudo_pusha, 0, 0 },
3426   { "pushi", 2, do_pseudo_pushi, 0, 0 },
3427 
3428   {NULL, 0, NULL, 0, 0}
3429 };
3430 
3431 static void
nds32_init_nds32_pseudo_opcodes(void)3432 nds32_init_nds32_pseudo_opcodes (void)
3433 {
3434   struct nds32_pseudo_opcode *opcode;
3435 
3436   nds32_pseudo_opcode_hash = str_htab_create ();
3437   for (opcode = nds32_pseudo_opcode_table; opcode->opcode; opcode++)
3438     if (str_hash_insert (nds32_pseudo_opcode_hash, opcode->opcode, opcode, 0))
3439       as_fatal (_("duplicate %s"), opcode->opcode);
3440 }
3441 
3442 static struct nds32_pseudo_opcode *
nds32_lookup_pseudo_opcode(const char * str)3443 nds32_lookup_pseudo_opcode (const char *str)
3444 {
3445   struct nds32_pseudo_opcode *result;
3446   int i = 0;
3447 
3448   /* (*op) is the first word of current source line (*str)  */
3449   int maxlen = strlen (str);
3450   char *op = xmalloc (maxlen + 1);
3451 
3452   for (i = 0; i < maxlen; i++)
3453     {
3454       if (ISSPACE (op[i] = str[i]))
3455 	break;
3456     }
3457   op[i] = '\0';
3458 
3459   result = str_hash_find (nds32_pseudo_opcode_hash, op);
3460   free (op);
3461   return result;
3462 }
3463 
3464 static void
nds32_pseudo_opcode_wrapper(char * line,struct nds32_pseudo_opcode * opcode)3465 nds32_pseudo_opcode_wrapper (char *line, struct nds32_pseudo_opcode *opcode)
3466 {
3467   int argc = 0;
3468   char *argv[8] = {NULL};
3469   char *s;
3470   char *str = xstrdup (line);
3471 
3472   /* Parse arguments for opcode.  */
3473   s = str + strlen (opcode->opcode);
3474 
3475   if (!s[0])
3476     goto end;
3477 
3478   /* Dummy comma to ease separate arguments as below.  */
3479   s[0] = ',';
3480   do
3481     {
3482       if (s[0] == ',')
3483 	{
3484 	  if (argc >= opcode->argc
3485 	      || (argc >= (int)ARRAY_SIZE (argv) - 1))
3486 	    as_bad (_("Too many argument. `%s'"), line);
3487 
3488 	  argv[argc] = s + 1;
3489 	  argc ++;
3490 	  s[0] = '\0';
3491 	}
3492       ++s;
3493     } while (s[0] != '\0');
3494  end:
3495   /* Put the origin line for debugging.  */
3496   argv[argc] = line;
3497   opcode->proc (argc, argv, opcode->pseudo_val);
3498   free (str);
3499 }
3500 
3501 /* This function will be invoked from function `nds32_after_parse_args'.
3502    Thus, if the value of option has been set, keep the value the way it is.  */
3503 
3504 static int
nds32_parse_arch(const char * str)3505 nds32_parse_arch (const char *str)
3506 {
3507   static const struct nds32_arch
3508   {
3509     const char *name;
3510     int baseline;
3511     int reduced_reg;
3512     int fpu_sp_ext;
3513     int fpu_dp_ext;
3514     int fpu_freg;
3515     int abi;
3516   } archs[] =
3517   {
3518     {"v3m", ISA_V3M, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
3519     {"v3j", ISA_V3,  1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
3520     {"v3s", ISA_V3,  0, 1, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
3521     {"v3f", ISA_V3,  0, 1, 1, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
3522     {"v3",  ISA_V3,  0, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
3523     {"v2j", ISA_V2,  1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
3524     {"v2s", ISA_V2,  0, 1, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
3525     {"v2f", ISA_V2,  0, 1, 1, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
3526     {"v2",  ISA_V2,  0, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
3527   };
3528   size_t i;
3529 
3530   for (i = 0; i < ARRAY_SIZE (archs); i++)
3531     {
3532       if (strcmp (str, archs[i].name) != 0)
3533 	continue;
3534 
3535       /* The value `-1' represents this option has *NOT* been set.  */
3536       nds32_baseline = (-1 != nds32_baseline) ? nds32_baseline : archs[i].baseline;
3537       nds32_gpr16 = (-1 != nds32_gpr16) ? nds32_gpr16 : archs[i].reduced_reg;
3538       nds32_fpu_sp_ext = (-1 != nds32_fpu_sp_ext) ? nds32_fpu_sp_ext : archs[i].fpu_sp_ext;
3539       nds32_fpu_dp_ext = (-1 != nds32_fpu_dp_ext) ? nds32_fpu_dp_ext : archs[i].fpu_dp_ext;
3540       nds32_freg = (-1 != nds32_freg) ? nds32_freg : archs[i].fpu_freg;
3541       nds32_abi = (-1 != nds32_abi) ? nds32_abi : archs[i].abi;
3542 
3543       return 1;
3544     }
3545 
3546   /* Logic here rejects the input arch name.  */
3547   as_bad (_("unknown arch name `%s'\n"), str);
3548 
3549   return 1;
3550 }
3551 
3552 /* This function parses "baseline" specified.  */
3553 
3554 static int
nds32_parse_baseline(const char * str)3555 nds32_parse_baseline (const char *str)
3556 {
3557   if (strcmp (str, "v3") == 0)
3558     nds32_baseline = ISA_V3;
3559   else if (strcmp (str, "v3m") == 0)
3560     nds32_baseline = ISA_V3M;
3561   else if (strcmp (str, "v2") == 0)
3562     nds32_baseline = ISA_V2;
3563   else
3564     {
3565       /* Logic here rejects the input baseline.  */
3566       as_bad (_("unknown baseline `%s'\n"), str);
3567       return 0;
3568     }
3569 
3570   return 1;
3571 }
3572 
3573 /* This function parses "fpu-freg" specified.  */
3574 
3575 static int
nds32_parse_freg(const char * str)3576 nds32_parse_freg (const char *str)
3577 {
3578   if (strcmp (str, "2") == 0)
3579     nds32_freg = E_NDS32_FPU_REG_32SP_16DP;
3580   else if (strcmp (str, "3") == 0)
3581     nds32_freg = E_NDS32_FPU_REG_32SP_32DP;
3582   else if (strcmp (str, "1") == 0)
3583     nds32_freg = E_NDS32_FPU_REG_16SP_8DP;
3584   else if (strcmp (str, "0") == 0)
3585     nds32_freg = E_NDS32_FPU_REG_8SP_4DP;
3586   else
3587     {
3588       /* Logic here rejects the input FPU configuration.  */
3589       as_bad (_("unknown FPU configuration `%s'\n"), str);
3590       return 0;
3591     }
3592 
3593   return 1;
3594 }
3595 
3596 /* This function parse "abi=" specified.  */
3597 
3598 static int
nds32_parse_abi(const char * str)3599 nds32_parse_abi (const char *str)
3600 {
3601   if (strcmp (str, "v2") == 0)
3602     nds32_abi = E_NDS_ABI_AABI;
3603   /* Obsolete.  */
3604   else if (strcmp (str, "v2fp") == 0)
3605     nds32_abi = E_NDS_ABI_V2FP;
3606   else if (strcmp (str, "v1") == 0)
3607     nds32_abi = E_NDS_ABI_V1;
3608   else if (strcmp (str,"v2fpp") == 0)
3609     nds32_abi = E_NDS_ABI_V2FP_PLUS;
3610   else
3611     {
3612       /* Logic here rejects the input abi version.  */
3613       as_bad (_("unknown ABI version`%s'\n"), str);
3614       return 0;
3615     }
3616 
3617   return 1;
3618 }
3619 
3620 /* This function turn on all extensions and instructions support.  */
3621 
3622 static int
nds32_all_ext(void)3623 nds32_all_ext (void)
3624 {
3625   nds32_mac = 1;
3626   nds32_div = 1;
3627   nds32_dx_regs = 1;
3628   nds32_16bit_ext = 1;
3629   nds32_perf_ext = 1;
3630   nds32_perf_ext2 = 1;
3631   nds32_string_ext = 1;
3632   nds32_audio_ext = 1;
3633   nds32_fpu_fma = 1;
3634   nds32_fpu_sp_ext = 1;
3635   nds32_fpu_dp_ext = 1;
3636   nds32_dsp_ext = 1;
3637   nds32_zol_ext = 1;
3638   /* Turn off reduced register.  */
3639   nds32_gpr16 = 0;
3640 
3641   return 1;
3642 }
3643 
3644 /* GAS will call md_parse_option whenever getopt returns an unrecognized code,
3645    presumably indicating a special code value which appears in md_longopts.
3646    This function should return non-zero if it handled the option and zero
3647    otherwise.  There is no need to print a message about an option not being
3648    recognized.  This will be handled by the generic code.  */
3649 
3650 int
nds32_parse_option(int c,const char * arg)3651 nds32_parse_option (int c, const char *arg)
3652 {
3653   struct nds32_parse_option_table *coarse_tune;
3654   struct nds32_set_option_table *fine_tune;
3655   const char *ptr_arg = NULL;
3656 
3657   switch (c)
3658     {
3659     case OPTION_OPTIMIZE:
3660       optimize = 1;
3661       optimize_for_space = 0;
3662       break;
3663     case OPTION_OPTIMIZE_SPACE:
3664       optimize = 0;
3665       optimize_for_space = 1;
3666       break;
3667     case OPTION_BIG:
3668       target_big_endian = 1;
3669       break;
3670     case OPTION_LITTLE:
3671       target_big_endian = 0;
3672       break;
3673     case OPTION_TURBO:
3674       nds32_all_ext ();
3675       break;
3676     case OPTION_PIC:
3677       nds32_pic = 1;
3678       break;
3679     case OPTION_RELAX_FP_AS_GP_OFF:
3680       nds32_relax_fp_as_gp = 0;
3681       break;
3682     case OPTION_RELAX_B2BB_ON:
3683       nds32_relax_b2bb = 1;
3684       break;
3685     case OPTION_RELAX_ALL_OFF:
3686       nds32_relax_all = 0;
3687       break;
3688     default:
3689       /* Determination of which option table to search for to save time.  */
3690       if (!arg)
3691 	return 0;
3692 
3693       ptr_arg = strchr (arg, '=');
3694 
3695       if (ptr_arg)
3696 	{
3697 	  /* Find the value after '='.  */
3698 	  if (ptr_arg != NULL)
3699 	    ptr_arg++;
3700 	  for (coarse_tune = parse_opts; coarse_tune->name != NULL; coarse_tune++)
3701 	    {
3702 	      if (strncmp (arg, coarse_tune->name, (ptr_arg - arg)) == 0)
3703 		{
3704 		  coarse_tune->func (ptr_arg);
3705 		  return 1;
3706 		}
3707 	    }
3708 	}
3709       else
3710 	{
3711 	  int disable = 0;
3712 
3713 	  /* Filter out the Disable option first.  */
3714 	  if (startswith (arg, "no-"))
3715 	    {
3716 	      disable = 1;
3717 	      arg += 3;
3718 	    }
3719 
3720 	  for (fine_tune = toggle_opts; fine_tune->name != NULL; fine_tune++)
3721 	    {
3722 	      if (strcmp (arg, fine_tune->name) == 0)
3723 		{
3724 		  if (fine_tune->var != NULL)
3725 		    *fine_tune->var = (disable) ? 0 : 1;
3726 		  return 1;
3727 		}
3728 	    }
3729 	}
3730       /* Nothing match.  */
3731       return 0;
3732     }
3733 
3734   return 1;
3735 }
3736 
3737 /* tc_check_label  */
3738 
3739 void
nds32_check_label(symbolS * label ATTRIBUTE_UNUSED)3740 nds32_check_label (symbolS *label ATTRIBUTE_UNUSED)
3741 {
3742   /* The code used to create BB is move to frob_label.
3743      They should go there.  */
3744 }
3745 
3746 static void
set_endian_little(int on)3747 set_endian_little (int on)
3748 {
3749   target_big_endian = !on;
3750 }
3751 
3752 /* These functions toggles the generation of 16-bit.  First encounter signals
3753    the beginning of not generating 16-bit instructions and next encounter
3754    signals the restoring back to default behavior.  */
3755 
3756 static void
trigger_16bit(int trigger)3757 trigger_16bit (int trigger)
3758 {
3759   enable_16bit = trigger;
3760 }
3761 
3762 static int backup_16bit_mode;
3763 static void
restore_16bit(int no_use ATTRIBUTE_UNUSED)3764 restore_16bit (int no_use ATTRIBUTE_UNUSED)
3765 {
3766   enable_16bit = backup_16bit_mode;
3767 }
3768 
3769 static void
off_16bit(int no_use ATTRIBUTE_UNUSED)3770 off_16bit (int no_use ATTRIBUTE_UNUSED)
3771 {
3772   backup_16bit_mode = enable_16bit;
3773   enable_16bit = 0;
3774 }
3775 
3776 /* Built-in segments for small object.  */
3777 typedef struct nds32_seg_entryT
3778 {
3779   segT s;
3780   const char *name;
3781   flagword flags;
3782 } nds32_seg_entry;
3783 
3784 nds32_seg_entry nds32_seg_table[] =
3785 {
3786   {NULL, ".sdata_f", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
3787 		     | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
3788   {NULL, ".sdata_b", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
3789 		     | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
3790   {NULL, ".sdata_h", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
3791 		     | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
3792   {NULL, ".sdata_w", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
3793 		     | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
3794   {NULL, ".sdata_d", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
3795 		     | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
3796   {NULL, ".sbss_f", SEC_ALLOC | SEC_SMALL_DATA},
3797   {NULL, ".sbss_b", SEC_ALLOC | SEC_SMALL_DATA},
3798   {NULL, ".sbss_h", SEC_ALLOC | SEC_SMALL_DATA},
3799   {NULL, ".sbss_w", SEC_ALLOC | SEC_SMALL_DATA},
3800   {NULL, ".sbss_d", SEC_ALLOC | SEC_SMALL_DATA}
3801 };
3802 
3803 /* Indexes to nds32_seg_table[].  */
3804 enum NDS32_SECTIONS_ENUM
3805 {
3806   SDATA_F_SECTION = 0,
3807   SDATA_B_SECTION = 1,
3808   SDATA_H_SECTION = 2,
3809   SDATA_W_SECTION = 3,
3810   SDATA_D_SECTION = 4,
3811   SBSS_F_SECTION = 5,
3812   SBSS_B_SECTION = 6,
3813   SBSS_H_SECTION = 7,
3814   SBSS_W_SECTION = 8,
3815   SBSS_D_SECTION = 9
3816 };
3817 
3818 /* The following code is borrowed from v850_seg.  Revise this is needed.  */
3819 
3820 static void
do_nds32_seg(int i,subsegT sub)3821 do_nds32_seg (int i, subsegT sub)
3822 {
3823   nds32_seg_entry *seg = nds32_seg_table + i;
3824 
3825   obj_elf_section_change_hook ();
3826 
3827   if (seg->s != NULL)
3828     subseg_set (seg->s, sub);
3829   else
3830     {
3831       seg->s = subseg_new (seg->name, sub);
3832       if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
3833 	{
3834 	  bfd_set_section_flags (seg->s, seg->flags);
3835 	  if ((seg->flags & SEC_LOAD) == 0)
3836 	    seg_info (seg->s)->bss = 1;
3837 	}
3838     }
3839 }
3840 
3841 static void
nds32_seg(int i)3842 nds32_seg (int i)
3843 {
3844   subsegT sub = get_absolute_expression ();
3845 
3846   do_nds32_seg (i, sub);
3847   demand_empty_rest_of_line ();
3848 }
3849 
3850 /* Set if label adjustment is needed.  I should not adjust .xbyte in dwarf.  */
3851 static symbolS *nds32_last_label;	/* Last label for alignment.  */
3852 
3853 static void
add_mapping_symbol_for_align(int shift,valueT addr,int is_data_align)3854 add_mapping_symbol_for_align (int shift, valueT addr, int is_data_align)
3855 {
3856   if ((shift > 1) && (addr & 1))
3857     {
3858       int n = (1 << shift) - 1;
3859       if (!is_data_align)
3860 	add_mapping_symbol (MAP_CODE, 1, 0);
3861       else if ((int) (addr & n) != n)
3862 	add_mapping_symbol (MAP_CODE, 1, 0);
3863     }
3864   else if ((shift > 1) && ((int) (addr & 1) == 0))
3865     add_mapping_symbol (MAP_CODE, 0, 0);
3866 }
3867 
3868 /* This code is referred from D30V for adjust label to be with pending
3869    alignment.  For example,
3870      LBYTE: .byte	0x12
3871      LHALF: .half	0x12
3872      LWORD: .word	0x12
3873    Without this, the above label will not attach to incoming data.  */
3874 
3875 static void
nds32_adjust_label(int n)3876 nds32_adjust_label (int n)
3877 {
3878   /* FIXME: I think adjust label and alignment is
3879      the programmer's obligation.  Sadly, VLSI team doesn't
3880      properly use .align for their test cases.
3881      So I re-implement cons_align and auto adjust labels, again.
3882 
3883      I think d30v's implementation is simple and good enough.  */
3884 
3885   symbolS *label = nds32_last_label;
3886   nds32_last_label = NULL;
3887 
3888   /* SEC_ALLOC is used to eliminate .debug_ sections.
3889      SEC_CODE is used to include section for ILM.  */
3890   if (((now_seg->flags & SEC_ALLOC) == 0 && (now_seg->flags & SEC_CODE) == 0)
3891       || strcmp (now_seg->name, ".eh_frame") == 0
3892       || strcmp (now_seg->name, ".gcc_except_table") == 0)
3893     return;
3894 
3895   /* Only frag by alignment when needed.
3896      Otherwise, it will fail to optimize labels on 4-byte boundary.  (bug8454)
3897      See md_convert_frag () and RELAX_SET_RELAXABLE (frag) for details.  */
3898   if (frag_now_fix () & ((1 << n) -1 ))
3899     {
3900       if (subseg_text_p (now_seg))
3901 	{
3902 	  add_mapping_symbol_for_align (n, frag_now_fix (), 1);
3903 	  frag_align_code (n, 0);
3904 	}
3905       else
3906 	frag_align (n, 0, 0);
3907 
3908       /* Record the minimum alignment for this segment.  */
3909       record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER);
3910     }
3911 
3912   if (label != NULL)
3913     {
3914       symbolS *sym;
3915       int label_seen = false;
3916       struct frag *old_frag;
3917       valueT old_value, new_value;
3918 
3919       gas_assert (S_GET_SEGMENT (label) == now_seg);
3920 
3921       old_frag  = symbol_get_frag (label);
3922       old_value = S_GET_VALUE (label);
3923       new_value = (valueT) frag_now_fix ();
3924 
3925       /* Multiple labels may be on the same address.  And the last symbol
3926 	 may not be a label at all, e.g., register name, external function names,
3927 	 so I have to track the last label in tc_frob_label instead of
3928 	 just using symbol_lastP.  */
3929       for (sym = symbol_lastP; sym != NULL; sym = symbol_previous (sym))
3930 	{
3931 	  if (symbol_get_frag (sym) == old_frag
3932 	      && S_GET_VALUE (sym) == old_value)
3933 	    {
3934 	      /* Warning HERE! */
3935 	      label_seen = true;
3936 	      symbol_set_frag (sym, frag_now);
3937 	      S_SET_VALUE (sym, new_value);
3938 	    }
3939 	  else if (label_seen && symbol_get_frag (sym) != old_frag)
3940 	    break;
3941 	}
3942     }
3943 }
3944 
3945 void
nds32_cons_align(int size ATTRIBUTE_UNUSED)3946 nds32_cons_align (int size ATTRIBUTE_UNUSED)
3947 {
3948   /* Do nothing here.
3949      This is called before `md_flush_pending_output' is called by `cons'.
3950 
3951      There are two things should be done for auto-adjust-label.
3952      1. Align data/instructions and adjust label to be attached to them.
3953      2. Clear auto-adjust state, so incoming data/instructions will not
3954 	adjust the label.
3955 
3956      For example,
3957 	  .byte 0x1
3958 	.L0:
3959 	  .word 0x2
3960 	  .word 0x3
3961      in this case, '.word 0x2' will adjust the label, .L0, but '.word 0x3' should not.
3962 
3963      I think `md_flush_pending_output' is a good place to clear the auto-adjust state,
3964      but it is also called by `cons' before this function.
3965      To simplify the code, instead of overriding .zero, .fill, .space, etc,
3966      I think we should just adjust label in `nds32_aligned_X_cons' instead of here.  */
3967 }
3968 
3969 static void
make_mapping_symbol(enum mstate state,valueT value,fragS * frag,unsigned int align)3970 make_mapping_symbol (enum mstate state, valueT value, fragS * frag, unsigned int align)
3971 {
3972   symbolS *symbol_p = NULL;
3973   const char *symbol_name = NULL;
3974   switch (state)
3975     {
3976     case MAP_DATA:
3977       if (align == 0)
3978 	symbol_name = "$d0";
3979       else if (align == 1)
3980 	symbol_name = "$d1";
3981       else if (align == 2)
3982 	symbol_name = "$d2";
3983       else if (align == 3)
3984 	symbol_name = "$d3";
3985       else if (align == 4)
3986 	symbol_name = "$d4";
3987       break;
3988     case MAP_CODE:
3989       symbol_name = "$c";
3990       break;
3991     default:
3992       abort ();
3993     }
3994 
3995   symbol_p = symbol_new (symbol_name, now_seg, frag, value);
3996   /* local scope attribute  */
3997   symbol_get_bfdsym (symbol_p)->flags |= BSF_NO_FLAGS | BSF_LOCAL;
3998 }
3999 
4000 static void
add_mapping_symbol(enum mstate state,unsigned int padding_byte,unsigned int align)4001 add_mapping_symbol (enum mstate state, unsigned int padding_byte,
4002 		    unsigned int align)
4003 {
4004   enum mstate current_mapping_state =
4005     seg_info (now_seg)->tc_segment_info_data.mapstate;
4006 
4007   if (state == MAP_CODE
4008       && current_mapping_state == state)
4009     return;
4010 
4011   if (!SEG_NORMAL (now_seg)
4012       || !subseg_text_p (now_seg))
4013     return;
4014 
4015   /* start adding mapping symbol  */
4016   seg_info (now_seg)->tc_segment_info_data.mapstate = state;
4017   make_mapping_symbol (state, (valueT) frag_now_fix () + padding_byte,
4018 		       frag_now, align);
4019 }
4020 
4021 static void
nds32_aligned_cons(int idx)4022 nds32_aligned_cons (int idx)
4023 {
4024   nds32_adjust_label (idx);
4025   add_mapping_symbol (MAP_DATA, 0, idx);
4026   /* Call default handler.  */
4027   cons (1 << idx);
4028   if (now_seg->flags & SEC_CODE
4029       && now_seg->flags & SEC_ALLOC && now_seg->flags & SEC_RELOC)
4030     {
4031       /* Use BFD_RELOC_NDS32_DATA to avoid linker
4032 	 optimization replacing data.  */
4033       expressionS exp;
4034 
4035       exp.X_add_number = 0;
4036       exp.X_op = O_constant;
4037       fix_new_exp (frag_now, frag_now_fix () - (1 << idx), 1 << idx,
4038 		   &exp, 0, BFD_RELOC_NDS32_DATA);
4039     }
4040 }
4041 
4042 /* `.double' directive.  */
4043 
4044 static void
nds32_aligned_float_cons(int type)4045 nds32_aligned_float_cons (int type)
4046 {
4047   switch (type)
4048     {
4049     case 'f':
4050     case 'F':
4051     case 's':
4052     case 'S':
4053       nds32_adjust_label (2);
4054       break;
4055     case 'd':
4056     case 'D':
4057     case 'r':
4058     case 'R':
4059       nds32_adjust_label (4);
4060       break;
4061     default:
4062       as_bad ("Unrecognized float type, %c\n", (char)type);
4063     }
4064   /* Call default handler.  */
4065   float_cons (type);
4066 }
4067 
4068 static void
nds32_enable_pic(int ignore ATTRIBUTE_UNUSED)4069 nds32_enable_pic (int ignore ATTRIBUTE_UNUSED)
4070 {
4071   /* Another way to do -mpic.
4072      This is for GCC internal use and should always be first line
4073      of code, otherwise, the effect is not determined.  */
4074   nds32_pic = 1;
4075 }
4076 
4077 static void
nds32_set_abi(int ver)4078 nds32_set_abi (int ver)
4079 {
4080   nds32_abi = ver;
4081 }
4082 
4083 /* Relax directive to set relocation R_NDS32_RELAX_ENTRY value.  */
4084 
4085 static void
nds32_relax_relocs(int relax)4086 nds32_relax_relocs (int relax)
4087 {
4088   char saved_char;
4089   char *name;
4090   int i;
4091   const char *subtype_relax[] =
4092     {"", "",};
4093 
4094   name = input_line_pointer;
4095   while (*input_line_pointer && !ISSPACE (*input_line_pointer))
4096     input_line_pointer++;
4097   saved_char = *input_line_pointer;
4098   *input_line_pointer = 0;
4099 
4100   for (i = 0; i < (int) ARRAY_SIZE (subtype_relax); i++)
4101     {
4102       if (strcmp (name, subtype_relax[i]) == 0)
4103 	{
4104 	  switch (i)
4105 	    {
4106 	    case 0:
4107 	    case 1:
4108 	      enable_relax_relocs = relax & enable_relax_relocs;
4109 	      break;
4110 	    default:
4111 	      break;
4112 	    }
4113 	  break;
4114 	}
4115     }
4116   *input_line_pointer = saved_char;
4117   ignore_rest_of_line ();
4118 }
4119 
4120 /* Record which arguments register($r0 ~ $r5) is not used in callee.
4121    bit[i] for $ri  */
4122 
4123 static void
nds32_set_hint_func_args(int ignore ATTRIBUTE_UNUSED)4124 nds32_set_hint_func_args (int ignore ATTRIBUTE_UNUSED)
4125 {
4126   ignore_rest_of_line ();
4127 }
4128 
4129 /* Insert relocations to mark the begin and end of a fp-omitted function,
4130    for further relaxation use.
4131    bit[i] for $ri  */
4132 
4133 static void
nds32_omit_fp_begin(int mode)4134 nds32_omit_fp_begin (int mode)
4135 {
4136   expressionS exp;
4137 
4138   if (nds32_relax_fp_as_gp == 0)
4139     return;
4140   exp.X_op = O_symbol;
4141   exp.X_add_symbol = abs_section_sym;
4142   if (mode == 1)
4143     {
4144       in_omit_fp = 1;
4145       exp.X_add_number = R_NDS32_RELAX_REGION_OMIT_FP_FLAG;
4146       fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
4147 		   BFD_RELOC_NDS32_RELAX_REGION_BEGIN);
4148     }
4149   else
4150     {
4151       in_omit_fp = 0;
4152       exp.X_add_number = R_NDS32_RELAX_REGION_OMIT_FP_FLAG;
4153       fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
4154 		   BFD_RELOC_NDS32_RELAX_REGION_END);
4155     }
4156 }
4157 
4158 static void
nds32_loop_begin(int mode)4159 nds32_loop_begin (int mode)
4160 {
4161   /* Insert loop region relocation here.  */
4162   expressionS exp;
4163 
4164   exp.X_op = O_symbol;
4165   exp.X_add_symbol = abs_section_sym;
4166   if (mode == 1)
4167     {
4168       exp.X_add_number = R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG;
4169       fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
4170 		   BFD_RELOC_NDS32_RELAX_REGION_BEGIN);
4171     }
4172   else
4173     {
4174       exp.X_add_number = R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG;
4175       fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
4176 		   BFD_RELOC_NDS32_RELAX_REGION_END);
4177     }
4178 }
4179 
4180 struct nds32_relocs_group
4181 {
4182   struct nds32_relocs_pattern *pattern;
4183   struct nds32_relocs_group *next;
4184 };
4185 
4186 static struct nds32_relocs_group *nds32_relax_hint_current = NULL;
4187 /* Used to reorder the id for ".relax_hint id".  */
4188 static int relax_hint_bias = 0;
4189 /* Record current relax hint id.  */
4190 static int relax_hint_id_current = -1;
4191 int reset_bias = 0;
4192 /* If ".relax_hint begin" is triggered?  */
4193 int relax_hint_begin = 0;
4194 
4195 /* Record the reordered relax hint id.  */
4196 
4197 struct relax_hint_id
4198 {
4199   int old_id;
4200   int new_id;
4201   struct relax_hint_id *next;
4202 };
4203 
4204 /* FIXME: Need to find somewhere to free the list.  */
4205 struct relax_hint_id *record_id_head = NULL;
4206 
4207 /* Is the buffer large enough?  */
4208 #define MAX_BUFFER 12
4209 
4210 static char *nds_itoa (int n);
4211 
4212 static char *
nds_itoa(int n)4213 nds_itoa (int n)
4214 {
4215   char *buf = xmalloc (MAX_BUFFER * sizeof (char));
4216   snprintf (buf, MAX_BUFFER, "%d", n);
4217   return buf;
4218 }
4219 
4220 /* Insert a relax hint.  */
4221 
4222 static void
nds32_relax_hint(int mode ATTRIBUTE_UNUSED)4223 nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
4224 {
4225   char *name = NULL;
4226   char saved_char;
4227   struct nds32_relocs_pattern *relocs = NULL;
4228   struct nds32_relocs_group *group, *new;
4229   struct relax_hint_id *record_id;
4230 
4231   name = input_line_pointer;
4232   while (*input_line_pointer && !ISSPACE (*input_line_pointer))
4233     input_line_pointer++;
4234   saved_char = *input_line_pointer;
4235   *input_line_pointer = 0;
4236   name = strdup (name);
4237 
4238   if (name && strcmp (name, "begin") == 0)
4239     {
4240       if (relax_hint_id_current == -1)
4241 	reset_bias = 1;
4242       relax_hint_bias++;
4243       relax_hint_id_current++;
4244       relax_hint_begin = 1;
4245     }
4246 
4247   /* Original case ".relax_hint id".  It's id may need to be reordered. */
4248   if (!relax_hint_begin)
4249     {
4250       int tmp = strtol (name, NULL, 10);
4251       record_id = record_id_head;
4252       while (record_id)
4253 	{
4254 	  if (record_id->old_id == tmp)
4255 	    {
4256 	      name = nds_itoa (record_id->new_id);
4257 	      goto reordered_id;
4258 	    }
4259 	  record_id = record_id->next;
4260 	}
4261       if (reset_bias)
4262 	{
4263 	  relax_hint_bias = relax_hint_id_current - atoi (name) + 1;
4264 	  reset_bias = 0;
4265 	}
4266       relax_hint_id_current = tmp + relax_hint_bias;
4267 
4268       /* Insert the element to the head of the link list.  */
4269       struct relax_hint_id *tmp_id = malloc (sizeof (struct relax_hint_id));
4270       tmp_id->old_id = tmp;
4271       tmp_id->new_id = relax_hint_id_current;
4272       tmp_id->next = record_id_head;
4273       record_id_head = tmp_id;
4274     }
4275 
4276   if (name && strcmp (name, "end") == 0)
4277     relax_hint_begin = 0;
4278   name = nds_itoa (relax_hint_id_current);
4279 
4280  reordered_id:
4281 
4282   /* Find relax hint entry for next instruction, and all member will be
4283      initialized at that time.  */
4284   relocs = str_hash_find (nds32_hint_hash, name);
4285   if (relocs == NULL)
4286     {
4287       relocs = XNEW (struct nds32_relocs_pattern);
4288       memset (relocs, 0, sizeof (struct nds32_relocs_pattern));
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 = XNEW (struct nds32_relocs_pattern);
4296       relocs = relocs->next;
4297       memset (relocs, 0, sizeof (struct nds32_relocs_pattern));
4298     }
4299 
4300   relocs->next = NULL;
4301   *input_line_pointer = saved_char;
4302   ignore_rest_of_line ();
4303 
4304   /* Get the final one of relax hint series.  */
4305 
4306   /* It has to build this list because there are maybe more than one
4307      instructions relative to the same instruction.  It to connect to
4308      next instruction after md_assemble.  */
4309   new = XNEW (struct nds32_relocs_group);
4310   memset (new, 0, sizeof (struct nds32_relocs_group));
4311   new->pattern = relocs;
4312   new->next = NULL;
4313   group = nds32_relax_hint_current;
4314   if (!group)
4315     nds32_relax_hint_current = new;
4316   else
4317     {
4318       while (group->next != NULL)
4319 	group = group->next;
4320       group->next = new;
4321     }
4322   relaxing = true;
4323 }
4324 
4325 /* Decide the size of vector entries, only accepts 4 or 16 now.  */
4326 
4327 static void
nds32_vec_size(int ignore ATTRIBUTE_UNUSED)4328 nds32_vec_size (int ignore ATTRIBUTE_UNUSED)
4329 {
4330   expressionS exp;
4331 
4332   expression (&exp);
4333 
4334   if (exp.X_op == O_constant)
4335     {
4336       if (exp.X_add_number == 4 || exp.X_add_number == 16)
4337 	{
4338 	  if (vec_size == 0)
4339 	    vec_size = exp.X_add_number;
4340 	  else if (vec_size != exp.X_add_number)
4341 	    as_warn (_("Different arguments of .vec_size are found, "
4342 		       "previous %d, current %d"),
4343 		     (int) vec_size, (int) exp.X_add_number);
4344 	}
4345       else
4346 	as_warn (_("Argument of .vec_size is expected 4 or 16, actual: %d."),
4347 		 (int) exp.X_add_number);
4348     }
4349   else
4350     as_warn (_("Argument of .vec_size is not a constant."));
4351 }
4352 
4353 /* The behavior of ".flag" directive varies depending on the target.
4354    In nds32 target, we use it to recognize whether this assembly content is
4355    generated by compiler.  Other features can also be added in this function
4356    in the future.  */
4357 
4358 static void
nds32_flag(int ignore ATTRIBUTE_UNUSED)4359 nds32_flag (int ignore ATTRIBUTE_UNUSED)
4360 {
4361   char *name;
4362   char saved_char;
4363   int i;
4364   const char *possible_flags[] = { "verbatim" };
4365 
4366   /* Skip whitespaces.  */
4367   name = input_line_pointer;
4368   while (*input_line_pointer && !ISSPACE (*input_line_pointer))
4369     input_line_pointer++;
4370   saved_char = *input_line_pointer;
4371   *input_line_pointer = 0;
4372 
4373   for (i = 0; i < (int) ARRAY_SIZE (possible_flags); i++)
4374     {
4375       if (strcmp (name, possible_flags[i]) == 0)
4376 	{
4377 	  switch (i)
4378 	    {
4379 	    case 0:
4380 	      /* flag: verbatim */
4381 	      verbatim = 1;
4382 	      break;
4383 	    default:
4384 	      break;
4385 	    }
4386 	  /* Already found the flag, no need to continue next loop.   */
4387 	  break;
4388 	}
4389     }
4390 
4391   *input_line_pointer = saved_char;
4392   ignore_rest_of_line ();
4393 }
4394 
4395 static void
ict_model(int ignore ATTRIBUTE_UNUSED)4396 ict_model (int ignore ATTRIBUTE_UNUSED)
4397 {
4398   char *name;
4399   char saved_char;
4400   int i;
4401   const char *possible_flags[] = { "small", "large" };
4402 
4403   /* Skip whitespaces.  */
4404   name = input_line_pointer;
4405   while (*input_line_pointer && !ISSPACE (*input_line_pointer))
4406     input_line_pointer++;
4407   saved_char = *input_line_pointer;
4408   *input_line_pointer = 0;
4409 
4410   for (i = 0; i < (int) ARRAY_SIZE (possible_flags); i++)
4411     {
4412       if (strcmp (name, possible_flags[i]) == 0)
4413 	{
4414 	  switch (i)
4415 	    {
4416 	    case 0:
4417 	      /* flag: verbatim  */
4418 	      ict_flag = ICT_SMALL;
4419 	      break;
4420 	    case 1:
4421 	      ict_flag = ICT_LARGE;
4422 	      break;
4423 	    default:
4424 	      break;
4425 	    }
4426 	  /* Already found the flag, no need to continue next loop.   */
4427 	  break;
4428 	}
4429     }
4430 
4431   *input_line_pointer = saved_char;
4432   ignore_rest_of_line ();
4433 }
4434 
4435 static void
nds32_n12hc(int ignore ATTRIBUTE_UNUSED)4436 nds32_n12hc (int ignore ATTRIBUTE_UNUSED)
4437 {
4438   /* N1213HC core is used.  */
4439 }
4440 
4441 
4442 /* The target specific pseudo-ops which we support.  */
4443 const pseudo_typeS md_pseudo_table[] =
4444 {
4445   /* Forced alignment if declared these ways.  */
4446   {"ascii", stringer, 8 + 0},
4447   {"asciz", stringer, 8 + 1},
4448   {"double", nds32_aligned_float_cons, 'd'},
4449   {"dword", nds32_aligned_cons, 3},
4450   {"float", nds32_aligned_float_cons, 'f'},
4451   {"half", nds32_aligned_cons, 1},
4452   {"hword", nds32_aligned_cons, 1},
4453   {"int", nds32_aligned_cons, 2},
4454   {"long", nds32_aligned_cons, 2},
4455   {"octa", nds32_aligned_cons, 4},
4456   {"quad", nds32_aligned_cons, 3},
4457   {"qword", nds32_aligned_cons, 4},
4458   {"short", nds32_aligned_cons, 1},
4459   {"byte", nds32_aligned_cons, 0},
4460   {"single", nds32_aligned_float_cons, 'f'},
4461   {"string", stringer, 8 + 1},
4462   {"word", nds32_aligned_cons, 2},
4463 
4464   {"little", set_endian_little, 1},
4465   {"big", set_endian_little, 0},
4466   {"16bit_on", trigger_16bit, 1},
4467   {"16bit_off", trigger_16bit, 0},
4468   {"restore_16bit", restore_16bit, 0},
4469   {"off_16bit", off_16bit, 0},
4470 
4471   {"sdata_d", nds32_seg, SDATA_D_SECTION},
4472   {"sdata_w", nds32_seg, SDATA_W_SECTION},
4473   {"sdata_h", nds32_seg, SDATA_H_SECTION},
4474   {"sdata_b", nds32_seg, SDATA_B_SECTION},
4475   {"sdata_f", nds32_seg, SDATA_F_SECTION},
4476 
4477   {"sbss_d", nds32_seg, SBSS_D_SECTION},
4478   {"sbss_w", nds32_seg, SBSS_W_SECTION},
4479   {"sbss_h", nds32_seg, SBSS_H_SECTION},
4480   {"sbss_b", nds32_seg, SBSS_B_SECTION},
4481   {"sbss_f", nds32_seg, SBSS_F_SECTION},
4482 
4483   {"pic", nds32_enable_pic, 0},
4484   {"n12_hc", nds32_n12hc, 0},
4485   {"abi_1", nds32_set_abi, E_NDS_ABI_V1},
4486   {"abi_2", nds32_set_abi, E_NDS_ABI_AABI},
4487   /* Obsolete.  */
4488   {"abi_2fp", nds32_set_abi, E_NDS_ABI_V2FP},
4489   {"abi_2fp_plus", nds32_set_abi, E_NDS_ABI_V2FP_PLUS},
4490   {"relax", nds32_relax_relocs, 1},
4491   {"no_relax", nds32_relax_relocs, 0},
4492   {"hint_func_args", nds32_set_hint_func_args, 0}, /* Abandon??  */
4493   {"omit_fp_begin", nds32_omit_fp_begin, 1},
4494   {"omit_fp_end", nds32_omit_fp_begin, 0},
4495   {"vec_size", nds32_vec_size, 0},
4496   {"flag", nds32_flag, 0},
4497   {"innermost_loop_begin", nds32_loop_begin, 1},
4498   {"innermost_loop_end", nds32_loop_begin, 0},
4499   {"relax_hint", nds32_relax_hint, 0},
4500   {"ict_model", ict_model, 0},
4501   {NULL, NULL, 0}
4502 };
4503 
4504 void
nds32_pre_do_align(int n,char * fill,int len,int max)4505 nds32_pre_do_align (int n, char *fill, int len, int max)
4506 {
4507   /* Only make a frag if we HAVE to...  */
4508   fragS *fragP;
4509   if (n != 0 && !need_pass_2)
4510     {
4511       if (fill == NULL)
4512 	{
4513 	  if (subseg_text_p (now_seg))
4514 	    {
4515 	      dwarf2_emit_insn (0);
4516 	      fragP = frag_now;
4517 	      add_mapping_symbol_for_align (n, frag_now_fix (), 0);
4518 	      frag_align_code (n, max);
4519 
4520 	      /* Tag this alignment when there is a label before it.  */
4521 	      if (label_exist)
4522 		{
4523 		  fragP->tc_frag_data.flag = NDS32_FRAG_LABEL;
4524 		  label_exist = 0;
4525 		}
4526 	    }
4527 	  else
4528 	    frag_align (n, 0, max);
4529 	}
4530       else if (len <= 1)
4531 	frag_align (n, *fill, max);
4532       else
4533 	frag_align_pattern (n, fill, len, max);
4534     }
4535 }
4536 
4537 void
nds32_do_align(int n)4538 nds32_do_align (int n)
4539 {
4540   /* Optimize for space and label exists.  */
4541   expressionS exp;
4542 
4543   /* FIXME:I think this will break debug info sections and except_table.  */
4544   if (!enable_relax_relocs || !subseg_text_p (now_seg))
4545     return;
4546 
4547   /* Create and attach a BFD_RELOC_NDS32_LABEL fixup
4548      the size of instruction may not be correct because
4549      it could be relaxable.  */
4550   exp.X_op = O_symbol;
4551   exp.X_add_symbol = section_symbol (now_seg);
4552   exp.X_add_number = n;
4553   fix_new_exp (frag_now,
4554 	       frag_now_fix (), 0, &exp, 0, BFD_RELOC_NDS32_LABEL);
4555 }
4556 
4557 /* Supported Andes machines.  */
4558 struct nds32_machs
4559 {
4560   enum bfd_architecture bfd_mach;
4561   int mach_flags;
4562 };
4563 
4564 /* This is the callback for nds32-asm.c to parse operands.  */
4565 
4566 int
nds32_asm_parse_operand(struct nds32_asm_desc * pdesc ATTRIBUTE_UNUSED,struct nds32_asm_insn * pinsn,char ** pstr,int64_t * value)4567 nds32_asm_parse_operand (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
4568 			 struct nds32_asm_insn *pinsn,
4569 			 char **pstr, int64_t *value)
4570 {
4571   char *hold;
4572   expressionS *pexp = pinsn->info;
4573 
4574   hold = input_line_pointer;
4575   input_line_pointer = *pstr;
4576   expression (pexp);
4577   *pstr = input_line_pointer;
4578   input_line_pointer = hold;
4579 
4580   switch (pexp->X_op)
4581     {
4582     case O_symbol:
4583       *value = 0;
4584       return NASM_R_SYMBOL;
4585     case O_constant:
4586       *value = pexp->X_add_number;
4587       return NASM_R_CONST;
4588     case O_illegal:
4589     case O_absent:
4590     case O_register:
4591     default:
4592       return NASM_R_ILLEGAL;
4593     }
4594 }
4595 
4596 /* GAS will call this function at the start of the assembly, after the command
4597    line arguments have been parsed and all the machine independent
4598    initializations have been completed.  */
4599 
4600 void
md_begin(void)4601 md_begin (void)
4602 {
4603   const struct nds32_keyword *k;
4604   relax_info_t *relax_info;
4605   int flags = 0;
4606 
4607   bfd_set_arch_mach (stdoutput, TARGET_ARCH, nds32_baseline);
4608 
4609   nds32_init_nds32_pseudo_opcodes ();
4610   asm_desc.parse_operand = nds32_asm_parse_operand;
4611   if (nds32_gpr16)
4612     flags |= NASM_OPEN_REDUCED_REG;
4613   nds32_asm_init (&asm_desc, flags);
4614 
4615   /* Initial general purpose registers hash table.  */
4616   nds32_gprs_hash = str_htab_create ();
4617   for (k = nds32_keyword_gpr; k->name; k++)
4618     str_hash_insert (nds32_gprs_hash, k->name, k, 0);
4619 
4620   /* Initial branch hash table.  */
4621   nds32_relax_info_hash = str_htab_create ();
4622   for (relax_info = relax_table; relax_info->opcode; relax_info++)
4623     str_hash_insert (nds32_relax_info_hash, relax_info->opcode, relax_info, 0);
4624 
4625   /* Initial relax hint hash table.  */
4626   nds32_hint_hash = str_htab_create ();
4627   enable_16bit = nds32_16bit_ext;
4628 }
4629 
4630 /* HANDLE_ALIGN in write.c.  */
4631 
4632 void
nds32_handle_align(fragS * fragp)4633 nds32_handle_align (fragS *fragp)
4634 {
4635   static const unsigned char nop16[] = { 0x92, 0x00 };
4636   static const unsigned char nop32[] = { 0x40, 0x00, 0x00, 0x09 };
4637   int bytes;
4638   char *p;
4639 
4640   if (fragp->fr_type != rs_align_code)
4641     return;
4642 
4643   bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
4644   p = fragp->fr_literal + fragp->fr_fix;
4645 
4646   if (bytes & 1)
4647     {
4648       *p++ = 0;
4649       bytes--;
4650     }
4651 
4652   if (bytes & 2)
4653     {
4654       expressionS exp_t;
4655       exp_t.X_op = O_symbol;
4656       exp_t.X_add_symbol = abs_section_sym;
4657       exp_t.X_add_number = R_NDS32_INSN16_CONVERT_FLAG;
4658       fix_new_exp (fragp, fragp->fr_fix, 2, &exp_t, 0,
4659 		   BFD_RELOC_NDS32_INSN16);
4660       memcpy (p, nop16, 2);
4661       p += 2;
4662       bytes -= 2;
4663     }
4664 
4665   while (bytes >= 4)
4666     {
4667       memcpy (p, nop32, 4);
4668       p += 4;
4669       bytes -= 4;
4670     }
4671 
4672   bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
4673   fragp->fr_fix += bytes;
4674 }
4675 
4676 /* md_flush_pending_output  */
4677 
4678 void
nds32_flush_pending_output(void)4679 nds32_flush_pending_output (void)
4680 {
4681   nds32_last_label = NULL;
4682 }
4683 
4684 void
nds32_frob_label(symbolS * label)4685 nds32_frob_label (symbolS *label)
4686 {
4687   dwarf2_emit_label (label);
4688 }
4689 
4690 /* TC_START_LABEL  */
4691 
4692 int
nds32_start_label(int asmdone ATTRIBUTE_UNUSED,int secdone ATTRIBUTE_UNUSED)4693 nds32_start_label (int asmdone ATTRIBUTE_UNUSED, int secdone ATTRIBUTE_UNUSED)
4694 {
4695   if (optimize && subseg_text_p (now_seg))
4696     label_exist = 1;
4697   return 1;
4698 }
4699 
4700 /* TARGET_FORMAT  */
4701 
4702 const char *
nds32_target_format(void)4703 nds32_target_format (void)
4704 {
4705 #ifdef TE_LINUX
4706   if (target_big_endian)
4707     return "elf32-nds32be-linux";
4708   else
4709     return "elf32-nds32le-linux";
4710 #else
4711   if (target_big_endian)
4712     return "elf32-nds32be";
4713   else
4714     return "elf32-nds32le";
4715 #endif
4716 }
4717 
4718 static enum nds32_br_range
get_range_type(const struct nds32_field * field)4719 get_range_type (const struct nds32_field *field)
4720 {
4721   gas_assert (field != NULL);
4722 
4723   if (field->bitpos != 0)
4724     return BR_RANGE_U4G;
4725 
4726   if (field->bitsize == 24 && field->shift == 1)
4727     return BR_RANGE_S16M;
4728   else if (field->bitsize == 16 && field->shift == 1)
4729     return BR_RANGE_S64K;
4730   else if (field->bitsize == 14 && field->shift == 1)
4731     return BR_RANGE_S16K;
4732   else if (field->bitsize == 8 && field->shift == 1)
4733     return BR_RANGE_S256;
4734   else
4735     return BR_RANGE_U4G;
4736 }
4737 
4738 /* Save pseudo instruction relocation list.  */
4739 
4740 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)4741 nds32_elf_save_pseudo_pattern (fixS* fixP, struct nds32_asm_insn *insn,
4742 			       char *out, symbolS *sym,
4743 			       struct nds32_relocs_pattern *reloc_ptr,
4744 			       fragS *fragP)
4745 {
4746   struct nds32_opcode *opcode = insn->opcode;
4747   if (!reloc_ptr)
4748     reloc_ptr = XNEW (struct nds32_relocs_pattern);
4749   reloc_ptr->seg = now_seg;
4750   reloc_ptr->sym = sym;
4751   reloc_ptr->frag = fragP;
4752   reloc_ptr->frchain = frchain_now;
4753   reloc_ptr->fixP = fixP;
4754   reloc_ptr->opcode = opcode;
4755   reloc_ptr->where = out;
4756   reloc_ptr->insn = insn->insn;
4757   reloc_ptr->next = NULL;
4758   return reloc_ptr;
4759 }
4760 
4761 /* Check X_md to transform relocation.  */
4762 
4763 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)4764 nds32_elf_record_fixup_exp (fragS *fragP, const char *str,
4765 			    const struct nds32_field *fld,
4766 			    expressionS *pexp, char* out,
4767 			    struct nds32_asm_insn *insn)
4768 {
4769   int reloc = -1;
4770   expressionS exp;
4771   fixS *fixP = NULL;
4772 
4773   /* Handle instruction relocation.  */
4774   if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_HI20))
4775     {
4776       /* Relocation for hi20 modifier.  */
4777       switch (pexp->X_md)
4778 	{
4779 	case BFD_RELOC_NDS32_GOTOFF:	/* @GOTOFF */
4780 	  reloc = BFD_RELOC_NDS32_GOTOFF_HI20;
4781 	  break;
4782 	case BFD_RELOC_NDS32_GOT20:	/* @GOT */
4783 	  reloc = BFD_RELOC_NDS32_GOT_HI20;
4784 	  break;
4785 	case BFD_RELOC_NDS32_25_PLTREL:	/* @PLT */
4786 	  if (!nds32_pic)
4787 	    as_bad (_("Invalid PIC expression."));
4788 	  else
4789 	    reloc = BFD_RELOC_NDS32_PLT_GOTREL_HI20;
4790 	  break;
4791 	case BFD_RELOC_NDS32_GOTPC20:	/* _GLOBAL_OFFSET_TABLE_ */
4792 	  reloc = BFD_RELOC_NDS32_GOTPC_HI20;
4793 	  break;
4794 	case BFD_RELOC_NDS32_TPOFF:	/* @TPOFF */
4795 	  reloc = BFD_RELOC_NDS32_TLS_LE_HI20;
4796 	  break;
4797 	case BFD_RELOC_NDS32_GOTTPOFF:	/* @GOTTPOFF */
4798 	  reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_HI20 : BFD_RELOC_NDS32_TLS_IE_HI20;
4799 	  break;
4800 	case BFD_RELOC_NDS32_TLS_DESC:	/* @TLSDESC */
4801 	  reloc = BFD_RELOC_NDS32_TLS_DESC_HI20;
4802 	  break;
4803 	default:	/* No suffix */
4804 	  if (nds32_pic)
4805 	    /* When the file is pic, the address must be offset to gp.
4806 	       It may define another relocation or use GOTOFF.  */
4807 	    reloc = BFD_RELOC_NDS32_PLT_GOTREL_HI20;
4808 	  else
4809 	    reloc = BFD_RELOC_NDS32_HI20;
4810 	  break;
4811 	}
4812       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
4813 			  insn->info, 0 /* pcrel */, reloc);
4814     }
4815   else if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_LO12))
4816     {
4817       /* Relocation for lo12 modifier.  */
4818       if (fld->bitsize == 15 && fld->shift == 0)
4819 	{
4820 	  /* [ls]bi || ori */
4821 	  switch (pexp->X_md)
4822 	    {
4823 	    case BFD_RELOC_NDS32_GOTOFF:	/* @GOTOFF */
4824 	      reloc = BFD_RELOC_NDS32_GOTOFF_LO12;
4825 	      break;
4826 	    case BFD_RELOC_NDS32_GOT20:		/* @GOT */
4827 	      reloc = BFD_RELOC_NDS32_GOT_LO12;
4828 	      break;
4829 	    case BFD_RELOC_NDS32_25_PLTREL:	/* @PLT */
4830 	      if (!nds32_pic)
4831 		as_bad (_("Invalid PIC expression."));
4832 	      else
4833 		reloc = BFD_RELOC_NDS32_PLT_GOTREL_LO12;
4834 	      break;
4835 	    case BFD_RELOC_NDS32_GOTPC20:	/* _GLOBAL_OFFSET_TABLE_ */
4836 	      reloc = BFD_RELOC_NDS32_GOTPC_LO12;
4837 	      break;
4838 	    case BFD_RELOC_NDS32_TPOFF:		/* @TPOFF */
4839 	      reloc = BFD_RELOC_NDS32_TLS_LE_LO12;
4840 	      break;
4841 	    case BFD_RELOC_NDS32_GOTTPOFF:	/* @GOTTPOFF */
4842 	      reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_LO12 : BFD_RELOC_NDS32_TLS_IE_LO12;
4843 	      break;
4844 	    case BFD_RELOC_NDS32_TLS_DESC:	/* @TLSDESC */
4845 	      reloc = BFD_RELOC_NDS32_TLS_DESC_LO12;
4846 	      break;
4847 	    default:	/* No suffix */
4848 	      if (nds32_pic)
4849 		/* When the file is pic, the address must be offset to gp.
4850 		   It may define another relocation or use GOTOFF.  */
4851 		reloc = BFD_RELOC_NDS32_PLT_GOTREL_LO12;
4852 	      else
4853 		reloc = BFD_RELOC_NDS32_LO12S0;
4854 	      break;
4855 	    }
4856 	}
4857       else if (fld->bitsize == 15 && fld->shift == 1)
4858 	reloc = BFD_RELOC_NDS32_LO12S1;		/* [ls]hi */
4859       else if (fld->bitsize == 15 && fld->shift == 2)
4860 	{
4861 	  /* [ls]wi */
4862 	  switch (pexp->X_md)
4863 	    {
4864 	    case BFD_RELOC_NDS32_GOTTPOFF:	/* @GOTTPOFF */
4865 	      reloc = nds32_pic ? BFD_RELOC_NDS32_TLS_IEGP_LO12S2 : BFD_RELOC_NDS32_TLS_IE_LO12S2;
4866 	      break;
4867 	    default:	/* No suffix */
4868 	      reloc = BFD_RELOC_NDS32_LO12S2;
4869 	      break;
4870 	    }
4871 	}
4872       else if (fld->bitsize == 15 && fld->shift == 3)
4873 	reloc = BFD_RELOC_NDS32_LO12S3;		/* [ls]di */
4874       else if (fld->bitsize == 12 && fld->shift == 2)
4875 	reloc = BFD_RELOC_NDS32_LO12S2_SP;	/* f[ls][sd]i */
4876 
4877       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
4878 			  insn->info, 0 /* pcrel */, reloc);
4879     }
4880   else if (fld && fld->bitpos == 0 && insn->opcode->isize == 4
4881 	   && (insn->attr & NASM_ATTR_PCREL))
4882     {
4883       /* Relocation for 32-bit branch instructions.  */
4884       if (fld->bitsize == 24 && fld->shift == 1)
4885 	reloc = BFD_RELOC_NDS32_25_PCREL;
4886       else if (fld->bitsize == 16 && fld->shift == 1)
4887 	reloc = BFD_RELOC_NDS32_17_PCREL;
4888       else if (fld->bitsize == 14 && fld->shift == 1)
4889 	reloc = BFD_RELOC_NDS32_15_PCREL;
4890       else if (fld->bitsize == 8 && fld->shift == 1)
4891 	reloc = BFD_RELOC_NDS32_WORD_9_PCREL;
4892       else
4893 	abort ();
4894 
4895       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
4896 		   insn->info, 1 /* pcrel */, reloc);
4897     }
4898   else if (fld && fld->bitpos == 0 && insn->opcode->isize == 4
4899 	   && (insn->attr & NASM_ATTR_GPREL))
4900     {
4901       /* Relocation for 32-bit gp-relative instructions.  */
4902       if (fld->bitsize == 19 && fld->shift == 0)
4903 	reloc = BFD_RELOC_NDS32_SDA19S0;
4904       else if (fld->bitsize == 18 && fld->shift == 1)
4905 	reloc = BFD_RELOC_NDS32_SDA18S1;
4906       else if (fld->bitsize == 17 && fld->shift == 2)
4907 	reloc = BFD_RELOC_NDS32_SDA17S2;
4908       else
4909 	abort ();
4910 
4911       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
4912 		   insn->info, 0 /* pcrel */, reloc);
4913       /* Insert INSN16 for converting fp_as_gp.  */
4914       exp.X_op = O_symbol;
4915       exp.X_add_symbol = abs_section_sym;
4916       exp.X_add_number = 0;
4917       if (in_omit_fp && reloc == BFD_RELOC_NDS32_SDA17S2)
4918 	fix_new_exp (fragP, out - fragP->fr_literal,
4919 		     insn->opcode->isize, &exp, 0 /* pcrel */,
4920 		     BFD_RELOC_NDS32_INSN16);
4921     }
4922   else if (fld && fld->bitpos == 0 && insn->opcode->isize == 2
4923 	   && (insn->attr & NASM_ATTR_PCREL))
4924     {
4925       /* Relocation for 16-bit branch instructions.  */
4926       if (fld->bitsize == 8 && fld->shift == 1)
4927 	reloc = BFD_RELOC_NDS32_9_PCREL;
4928       else
4929 	abort ();
4930 
4931       fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
4932 		   insn->info, 1 /* pcrel */, reloc);
4933     }
4934   else if (fld)
4935     as_bad (_("Don't know how to handle this field. %s"), str);
4936 
4937   return fixP;
4938 }
4939 
4940 /* Build instruction pattern to relax.  There are two type group pattern
4941    including pseudo instruction and relax hint.  */
4942 
4943 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)4944 nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out,
4945 				struct nds32_asm_insn *insn, fragS *fragP,
4946 				const struct nds32_field *fld,
4947 				bool pseudo_hint)
4948 {
4949   struct nds32_relocs_pattern *reloc_ptr;
4950   struct nds32_relocs_group *group;
4951   symbolS *sym = NULL;
4952 
4953   /* The expression may be used uninitialized.  */
4954   if (fld)
4955     sym = pexp->X_add_symbol;
4956 
4957   if (pseudo_hint)
4958     {
4959       /* We cannot know how many instructions will be expanded for
4960 	 the pseudo instruction here.  The first expanded instruction fills
4961 	 the memory created by relax_hint.  The follower will created and link
4962 	 here.  */
4963       group = nds32_relax_hint_current;
4964       while (group)
4965 	{
4966 	  if (group->pattern->opcode == NULL)
4967 	    nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
4968 					   group->pattern, fragP);
4969 	  else
4970 	    {
4971 	      group->pattern->next =
4972 		nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
4973 					       NULL, fragP);
4974 	      group->pattern = group->pattern->next;
4975 	    }
4976 	  group = group->next;
4977 	}
4978     }
4979   else if (pseudo_opcode)
4980     {
4981       /* Save instruction relation for pseudo instruction expanding pattern.  */
4982       reloc_ptr = nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
4983 						 NULL, fragP);
4984       if (!relocs_list)
4985 	relocs_list = reloc_ptr;
4986       else
4987 	{
4988 	  struct nds32_relocs_pattern *temp = relocs_list;
4989 	  while (temp->next)
4990 	    temp = temp->next;
4991 	  temp->next = reloc_ptr;
4992 	}
4993     }
4994   else if (nds32_relax_hint_current)
4995     {
4996       /* Save instruction relation by relax hint.  */
4997       group = nds32_relax_hint_current;
4998       while (group)
4999 	{
5000 	  nds32_elf_save_pseudo_pattern (fixP, insn, out, sym,
5001 					 group->pattern, fragP);
5002 	  group = group->next;
5003 	  free (nds32_relax_hint_current);
5004 	  nds32_relax_hint_current = group;
5005 	}
5006     }
5007 
5008   /* Set relaxing false only for relax_hint trigger it.  */
5009   if (!pseudo_opcode)
5010     relaxing = false;
5011 }
5012 
5013 #define N32_MEM_EXT(insn) ((N32_OP6_MEM << 25) | insn)
5014 
5015 /* Relax pattern for link time relaxation.  */
5016 /* Relaxation types only! relocation types are not necessary.  */
5017 /* Refer to nds32_elf_record_fixup_exp ().  */
5018 
5019 static struct nds32_relax_hint_table relax_ls_table[] =
5020 {
5021   {
5022     /* LA and Floating LSI.  */
5023     .main_type = NDS32_RELAX_HINT_LA_FLSI,
5024     .relax_code_size = 12,
5025     .relax_code_seq =
5026       {
5027 	OP6 (SETHI),
5028 	OP6 (ORI),
5029 	OP6 (LBI),
5030       },
5031     .relax_fixup =
5032       {
5033 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
5034 	{4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
5035 	{4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
5036 	{8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_LSI},
5037 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
5038 	{8, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
5039 	{0, 0, 0, 0}
5040       }
5041   },
5042   {
5043     /* Load Address / Load-Store (LALS).  */
5044     .main_type = NDS32_RELAX_HINT_LALS,
5045     .relax_code_size = 12,
5046     .relax_code_seq =
5047       {
5048 	OP6 (SETHI),
5049 	OP6 (ORI),
5050 	OP6 (LBI),
5051       },
5052     .relax_fixup =
5053       {
5054 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
5055 	{4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
5056 	{8, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
5057 	{0, 0, 0, 0}
5058       }
5059   },
5060   {
5061     /* B(AL) symbol@PLT  */
5062     .main_type = NDS32_RELAX_HINT_LA_PLT,
5063     .relax_code_size = 16,
5064     .relax_code_seq =
5065       {
5066 	OP6 (SETHI),
5067 	OP6 (ORI),
5068 	OP6 (ALU1),
5069 	OP6 (JREG),
5070       },
5071     .relax_fixup =
5072       {
5073 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
5074 	{4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
5075 	{8, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
5076 	{12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PLT_GOT_SUFF},
5077 	{12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
5078 	{12, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
5079 	{0, 0, 0, 0}
5080       }
5081   },
5082   {
5083     /* LA (@GOT).  */
5084     .main_type = NDS32_RELAX_HINT_LA_GOT,
5085     .relax_code_size = 12,
5086     .relax_code_seq =
5087       {
5088 	OP6 (SETHI),
5089 	OP6 (ORI),
5090 	OP6 (MEM),
5091       },
5092     .relax_fixup =
5093       {
5094 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
5095 	{4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
5096 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
5097 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOT_SUFF},
5098 	{0, 0, 0, 0}
5099       }
5100   },
5101   {
5102     /* LA (@GOTOFF).  */
5103     .main_type = NDS32_RELAX_HINT_LA_GOTOFF,
5104     .relax_code_size = 16,
5105     .relax_code_seq =
5106       {
5107 	OP6 (SETHI),
5108 	OP6 (ORI),
5109 	OP6 (ALU1),
5110 	OP6 (MEM),
5111       },
5112     .relax_fixup =
5113       {
5114 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
5115 	{4, 4, NDS32_HINT | NDS32_PTR, BFD_RELOC_NDS32_PTR},
5116 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
5117 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOTOFF_SUFF},
5118 	{12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
5119 	{12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_GOTOFF_SUFF},
5120 	{0, 0, 0, 0}
5121       }
5122   },
5123   {
5124     /* TLS LE LS|LA */
5125     .main_type = NDS32_RELAX_HINT_TLS_LE_LS,
5126     .relax_code_size = 16,
5127     .relax_code_seq =
5128       {
5129 	OP6(SETHI),
5130 	OP6(ORI),
5131 	OP6(MEM),
5132 	OP6(ALU1),
5133       },
5134     .relax_fixup =
5135       {
5136 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
5137 	{4, 4, NDS32_HINT | NDS32_PTR_MULTIPLE, BFD_RELOC_NDS32_PTR},
5138 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
5139 	{8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_LE_LS},
5140 	{12, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
5141 	{12, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_LE_ADD},
5142 	{0, 0, 0, 0}
5143       }
5144   },
5145   {
5146     /* TLS IE LA */
5147     .main_type = NDS32_RELAX_HINT_TLS_IE_LA,
5148     .relax_code_size = 8,
5149     .relax_code_seq =
5150       {
5151 	OP6(SETHI),
5152 	OP6(LBI),
5153       },
5154     .relax_fixup =
5155       {
5156 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
5157 	{4, 4, NDS32_HINT | NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
5158 	{0, 0, 0, 0}
5159       }
5160   },
5161   {
5162     /* TLS IEGP LA */
5163     .main_type = NDS32_RELAX_HINT_TLS_IEGP_LA,
5164     .relax_code_size = 12,
5165     .relax_code_seq =
5166       {
5167 	OP6 (SETHI),
5168 	OP6 (ORI),
5169 	OP6 (MEM),
5170       },
5171     .relax_fixup =
5172       {
5173 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
5174 	{4, 4, NDS32_HINT | NDS32_PTR_PATTERN, BFD_RELOC_NDS32_PTR},
5175 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
5176 	{8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_IEGP_LW},
5177 	{0, 0, 0, 0}
5178       }
5179   },
5180   {
5181     /* TLS DESC LS:  */
5182     .main_type = NDS32_RELAX_HINT_TLS_DESC_LS,
5183     .relax_code_size = 24,
5184     .relax_code_seq =
5185       {
5186 	OP6 (SETHI),
5187 	OP6 (ORI),
5188 	OP6 (ALU1),
5189 	OP6 (LBI),	/* load argument */
5190 	OP6 (JREG),
5191 	OP6 (MEM),	/* load/store variable or load argument */
5192       },
5193     .relax_fixup =
5194       {
5195 	{0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
5196 	{4, 4, NDS32_HINT | NDS32_PTR_PATTERN, BFD_RELOC_NDS32_PTR},
5197 	{8, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_PTR_RESOLVED},
5198 	{8, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_ADD},
5199 	{12, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_FUNC},
5200 	{16, 4, NDS32_HINT | NDS32_SYM, BFD_RELOC_NDS32_TLS_DESC_CALL},
5201 	{20, 4, NDS32_HINT | NDS32_SYM_DESC_MEM, BFD_RELOC_NDS32_TLS_DESC_MEM},
5202 	{0, 0, 0, 0}
5203       }
5204   },
5205   {
5206     .main_type = 0,
5207     .relax_code_seq = {0},
5208     .relax_fixup = {{0, 0 , 0, 0}}
5209   }
5210 };
5211 
5212 /* Since sethi loadstore relocation has to using next instruction to determine
5213    elimination itself or not, we have to return the next instruction range.  */
5214 
5215 static int
nds32_elf_sethi_range(struct nds32_relocs_pattern * pattern)5216 nds32_elf_sethi_range (struct nds32_relocs_pattern *pattern)
5217 {
5218   int range = 0;
5219   while (pattern)
5220     {
5221       switch (pattern->opcode->value)
5222 	{
5223 	case INSN_LBI:
5224 	case INSN_SBI:
5225 	case INSN_LBSI:
5226 	case N32_MEM_EXT (N32_MEM_LB):
5227 	case N32_MEM_EXT (N32_MEM_LBS):
5228 	case N32_MEM_EXT (N32_MEM_SB):
5229 	  range = NDS32_LOADSTORE_BYTE;
5230 	  break;
5231 	case INSN_LHI:
5232 	case INSN_SHI:
5233 	case INSN_LHSI:
5234 	case N32_MEM_EXT (N32_MEM_LH):
5235 	case N32_MEM_EXT (N32_MEM_LHS):
5236 	case N32_MEM_EXT (N32_MEM_SH):
5237 	  range = NDS32_LOADSTORE_HALF;
5238 	  break;
5239 	case INSN_LWI:
5240 	case INSN_SWI:
5241 	case N32_MEM_EXT (N32_MEM_LW):
5242 	case N32_MEM_EXT (N32_MEM_SW):
5243 	  range = NDS32_LOADSTORE_WORD;
5244 	  break;
5245 	case INSN_FLSI:
5246 	case INSN_FSSI:
5247 	  range = NDS32_LOADSTORE_FLOAT_S;
5248 	  break;
5249 	case INSN_FLDI:
5250 	case INSN_FSDI:
5251 	  range = NDS32_LOADSTORE_FLOAT_D;
5252 	  break;
5253 	case INSN_ORI:
5254 	  range = NDS32_LOADSTORE_IMM;
5255 	  break;
5256 	default:
5257 	  range = NDS32_LOADSTORE_NONE;
5258 	  break;
5259 	}
5260       if (range != NDS32_LOADSTORE_NONE)
5261 	break;
5262       pattern = pattern->next;
5263     }
5264   return range;
5265 }
5266 
5267 /* The args means: instruction size, the 1st instruction is converted to 16 or
5268    not, optimize option, 16 bit instruction is enable.  */
5269 
5270 #define SET_ADDEND(size, convertible, optimize, insn16_on) \
5271   (((size) & 0xff) | ((convertible) ? 1u << 31 : 0) \
5272    | ((optimize) ? 1 << 30 : 0) | (insn16_on ? 1 << 29 : 0))
5273 #define MAC_COMBO (E_NDS32_HAS_FPU_MAC_INST|E_NDS32_HAS_MAC_DX_INST)
5274 
5275 static void
nds32_set_elf_flags_by_insn(struct nds32_asm_insn * insn)5276 nds32_set_elf_flags_by_insn (struct nds32_asm_insn * insn)
5277 {
5278   static int skip_flags = NASM_ATTR_FPU_FMA
5279     | NASM_ATTR_BRANCH | NASM_ATTR_SATURATION_EXT
5280     | NASM_ATTR_GPREL | NASM_ATTR_DXREG
5281     | NASM_ATTR_ISA_V1 | NASM_ATTR_ISA_V2
5282     | NASM_ATTR_ISA_V3 | NASM_ATTR_ISA_V3M
5283     | NASM_ATTR_PCREL;
5284 
5285   int new_flags = insn->opcode->attr & ~skip_flags;
5286   while (new_flags)
5287     {
5288       int next = 1 << (ffs (new_flags) - 1);
5289       new_flags &= ~next;
5290       switch (next)
5291 	{
5292 	case NASM_ATTR_PERF_EXT:
5293 	  {
5294 	    if (nds32_perf_ext)
5295 	      {
5296 		nds32_elf_flags |= E_NDS32_HAS_EXT_INST;
5297 		skip_flags |= NASM_ATTR_PERF_EXT;
5298 	      }
5299 	    else
5300 	      as_bad (_("instruction %s requires enabling performance "
5301 			"extension"), insn->opcode->opcode);
5302 	  }
5303 	  break;
5304 	case NASM_ATTR_PERF2_EXT:
5305 	  {
5306 	    if (nds32_perf_ext2)
5307 	      {
5308 		nds32_elf_flags |= E_NDS32_HAS_EXT2_INST;
5309 		skip_flags |= NASM_ATTR_PERF2_EXT;
5310 	      }
5311 	    else
5312 	      as_bad (_("instruction %s requires enabling performance "
5313 			"extension II"), insn->opcode->opcode);
5314 	  }
5315 	  break;
5316 	case NASM_ATTR_AUDIO_ISAEXT:
5317 	  {
5318 	    if (nds32_audio_ext)
5319 	      {
5320 		nds32_elf_flags |= E_NDS32_HAS_AUDIO_INST;
5321 		skip_flags |= NASM_ATTR_AUDIO_ISAEXT;
5322 	      }
5323 	    else
5324 	      as_bad (_("instruction %s requires enabling AUDIO extension"),
5325 		      insn->opcode->opcode);
5326 	  }
5327 	  break;
5328 	case NASM_ATTR_STR_EXT:
5329 	  {
5330 	    if (nds32_string_ext)
5331 	      {
5332 		nds32_elf_flags |= E_NDS32_HAS_STRING_INST;
5333 		skip_flags |= NASM_ATTR_STR_EXT;
5334 	      }
5335 	    else
5336 	      as_bad (_("instruction %s requires enabling STRING extension"),
5337 		      insn->opcode->opcode);
5338 	  }
5339 	  break;
5340 	case NASM_ATTR_DIV:
5341 	  {
5342 	    if (insn->opcode->attr & NASM_ATTR_DXREG)
5343 	      {
5344 		if (nds32_div && nds32_dx_regs)
5345 		  {
5346 		    nds32_elf_flags |= E_NDS32_HAS_DIV_DX_INST;
5347 		    skip_flags |= NASM_ATTR_DIV;
5348 		  }
5349 		else
5350 		  as_bad (_("instruction %s requires enabling DIV & DX_REGS "
5351 			    "extension"), insn->opcode->opcode);
5352 	      }
5353 	  }
5354 	  break;
5355 	case NASM_ATTR_FPU:
5356 	  {
5357 	    if (nds32_fpu_sp_ext || nds32_fpu_dp_ext)
5358 	      {
5359 		if (!(nds32_elf_flags
5360 		      & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
5361 		  nds32_fpu_com = 1;
5362 		skip_flags |= NASM_ATTR_FPU;
5363 	      }
5364 	    else
5365 	      as_bad (_("instruction %s requires enabling FPU extension"),
5366 		      insn->opcode->opcode);
5367 	  }
5368 	  break;
5369 	case NASM_ATTR_FPU_SP_EXT:
5370 	  {
5371 	    if (nds32_fpu_sp_ext)
5372 	      {
5373 		nds32_elf_flags |= E_NDS32_HAS_FPU_INST;
5374 		skip_flags |= NASM_ATTR_FPU_SP_EXT;
5375 	      }
5376 	    else
5377 	      as_bad (_("instruction %s requires enabling FPU_SP extension"),
5378 		      insn->opcode->opcode);
5379 	  }
5380 	  break;
5381 	case NASM_ATTR_FPU_DP_EXT:
5382 	  {
5383 	    if (nds32_fpu_dp_ext)
5384 	      {
5385 		nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST;
5386 		skip_flags |= NASM_ATTR_FPU_DP_EXT;
5387 	      }
5388 	    else
5389 	      as_bad (_("instruction %s requires enabling FPU_DP extension"),
5390 		      insn->opcode->opcode);
5391 	  }
5392 	  break;
5393 	case NASM_ATTR_MAC:
5394 	  {
5395 	    if (insn->opcode->attr & NASM_ATTR_FPU_SP_EXT)
5396 	      {
5397 		if (nds32_fpu_sp_ext && nds32_mac)
5398 		  nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
5399 		else
5400 		  as_bad (_("instruction %s requires enabling FPU_MAC "
5401 			    "extension"), insn->opcode->opcode);
5402 	      }
5403 	    else if (insn->opcode->attr & NASM_ATTR_FPU_DP_EXT)
5404 	      {
5405 		if (nds32_fpu_dp_ext && nds32_mac)
5406 		  nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
5407 		else
5408 		  as_bad (_("instruction %s requires enabling FPU_MAC "
5409 			    "extension"), insn->opcode->opcode);
5410 	      }
5411 	    else if (insn->opcode->attr & NASM_ATTR_DXREG)
5412 	      {
5413 		if (nds32_dx_regs && nds32_mac)
5414 		  nds32_elf_flags |= E_NDS32_HAS_MAC_DX_INST;
5415 		else
5416 		  as_bad (_("instruction %s requires enabling DX_REGS "
5417 			    "extension"), insn->opcode->opcode);
5418 	      }
5419 
5420 	    if (MAC_COMBO == (MAC_COMBO & nds32_elf_flags))
5421 	      skip_flags |= NASM_ATTR_MAC;
5422 	  }
5423 	  break;
5424 	case NASM_ATTR_DSP_ISAEXT:
5425 	  {
5426 	    if (nds32_dsp_ext)
5427 	      {
5428 		nds32_elf_flags |= E_NDS32_HAS_DSP_INST;
5429 		skip_flags |= NASM_ATTR_DSP_ISAEXT;
5430 	      }
5431 	    else
5432 	      as_bad (_("instruction %s requires enabling dsp extension"),
5433 		      insn->opcode->opcode);
5434 	  }
5435 	  break;
5436 	case NASM_ATTR_ZOL:
5437 	  {
5438 	    if (nds32_zol_ext)
5439 	      {
5440 		nds32_elf_flags |= E_NDS32_HAS_ZOL;
5441 		skip_flags |= NASM_ATTR_ZOL;
5442 	      }
5443 	    else
5444 	      as_bad (_("instruction %s requires enabling zol extension"),
5445 		      insn->opcode->opcode);
5446 	  }
5447 	  break;
5448 	default:
5449 	  as_bad (_("internal error: unknown instruction attribute: 0x%08x"),
5450 		  next);
5451 	}
5452     }
5453 }
5454 
5455 /* Flag for analysis relaxation type.  */
5456 
5457 enum nds32_insn_type
5458 {
5459   N32_RELAX_SETHI = 1,
5460   N32_RELAX_BR = (1 << 1),
5461   N32_RELAX_LSI = (1 << 2),
5462   N32_RELAX_JUMP = (1 << 3),
5463   N32_RELAX_CALL = (1 << 4),
5464   N32_RELAX_ORI = (1 << 5),
5465   N32_RELAX_MEM = (1 << 6),
5466   N32_RELAX_MOVI = (1 << 7),
5467   N32_RELAX_ALU1 = (1 << 8),
5468   N32_RELAX_16BIT = (1 << 9),
5469 };
5470 
5471 struct nds32_hint_map
5472 {
5473   /* the preamble relocation */
5474   bfd_reloc_code_real_type hi_type;
5475   /* mnemonic */
5476   const char *opc;
5477   /* relax pattern ID */
5478   enum nds32_relax_hint_type hint_type;
5479   /* range */
5480   enum nds32_br_range range;
5481   /* pattern character flags */
5482   enum nds32_insn_type insn_list;
5483   /* optional pattern character flags */
5484   enum nds32_insn_type option_list;
5485 };
5486 
5487 /* Table to match instructions with hint and relax pattern.  */
5488 
5489 static struct nds32_hint_map hint_map [] =
5490 {
5491   {
5492     /* LONGCALL4.  */
5493     BFD_RELOC_NDS32_HI20,
5494     "jal",
5495     NDS32_RELAX_HINT_NONE,
5496     BR_RANGE_U4G,
5497     N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL,
5498     0,
5499   },
5500   {
5501     /* LONGCALL5.  */
5502     _dummy_first_bfd_reloc_code_real,
5503     "bgezal",
5504     NDS32_RELAX_HINT_NONE,
5505     BR_RANGE_S16M,
5506     N32_RELAX_BR | N32_RELAX_CALL,
5507     0,
5508   },
5509   {
5510     /* LONGCALL6.  */
5511     BFD_RELOC_NDS32_HI20,
5512     "bgezal",
5513     NDS32_RELAX_HINT_NONE,
5514     BR_RANGE_U4G,
5515     N32_RELAX_BR | N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL,
5516     0,
5517   },
5518   {
5519     /* LONGJUMP4.  */
5520     BFD_RELOC_NDS32_HI20,
5521     "j",
5522     NDS32_RELAX_HINT_NONE,
5523     BR_RANGE_U4G,
5524     N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_JUMP,
5525     0,
5526   },
5527   {
5528     /* LONGJUMP5.  */
5529     /* There is two kinds of variation of LONGJUMP5.  One of them
5530        generate EMPTY relocation for converted INSN16 if needed.
5531        But we don't distinguish them here.  */
5532     _dummy_first_bfd_reloc_code_real,
5533     "beq",
5534     NDS32_RELAX_HINT_NONE,
5535     BR_RANGE_S16M,
5536     N32_RELAX_BR | N32_RELAX_JUMP,
5537     0,
5538   },
5539   {
5540     /* LONGJUMP6.  */
5541     BFD_RELOC_NDS32_HI20,
5542     "beq",
5543     NDS32_RELAX_HINT_NONE,
5544     BR_RANGE_U4G,
5545     N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_BR | N32_RELAX_JUMP,
5546     0,
5547   },
5548   {
5549     /* LONGJUMP7.  */
5550     _dummy_first_bfd_reloc_code_real,
5551     "beqc",
5552     NDS32_RELAX_HINT_NONE,
5553     BR_RANGE_S16K,
5554     N32_RELAX_MOVI | N32_RELAX_BR,
5555     0,
5556   },
5557   {
5558     /* LONGCALL (BAL|JR|LA symbol@PLT).  */
5559     BFD_RELOC_NDS32_PLT_GOTREL_HI20,
5560     NULL,
5561     NDS32_RELAX_HINT_LA_PLT,
5562     BR_RANGE_U4G,
5563     N32_RELAX_SETHI | N32_RELAX_ORI,
5564     N32_RELAX_ALU1 | N32_RELAX_CALL | N32_RELAX_JUMP,
5565   },
5566   /* relative issue: #12566 */
5567   {
5568     /* LA and Floating LSI.  */
5569     BFD_RELOC_NDS32_HI20,
5570     NULL,
5571     NDS32_RELAX_HINT_LA_FLSI,
5572     BR_RANGE_U4G,
5573     N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_LSI,
5574     0,
5575   },
5576   /* relative issue: #11685 #11602 */
5577   {
5578     /* load address / load-store (LALS).  */
5579     BFD_RELOC_NDS32_HI20,
5580     NULL,
5581     NDS32_RELAX_HINT_LALS,
5582     BR_RANGE_U4G,
5583     N32_RELAX_SETHI,
5584     N32_RELAX_ORI | N32_RELAX_LSI,
5585   },
5586   {
5587     /* setup $GP (_GLOBAL_OFFSET_TABLE_)  */
5588     BFD_RELOC_NDS32_GOTPC_HI20,
5589     NULL,
5590     NDS32_RELAX_HINT_LALS,
5591     BR_RANGE_U4G,
5592     N32_RELAX_SETHI | N32_RELAX_ORI,
5593     0,
5594   },
5595   {
5596     /* GOT LA/LS (symbol@GOT)  */
5597     BFD_RELOC_NDS32_GOT_HI20,
5598     NULL,
5599     NDS32_RELAX_HINT_LA_GOT,
5600     BR_RANGE_U4G,
5601     N32_RELAX_SETHI | N32_RELAX_ORI,
5602     N32_RELAX_MEM,
5603   },
5604   {
5605     /* GOTOFF LA/LS (symbol@GOTOFF)  */
5606     BFD_RELOC_NDS32_GOTOFF_HI20,
5607     NULL,
5608     NDS32_RELAX_HINT_LA_GOTOFF,
5609     BR_RANGE_U4G,
5610     N32_RELAX_SETHI | N32_RELAX_ORI,
5611     N32_RELAX_ALU1  | N32_RELAX_MEM, /* | N32_RELAX_LSI, */
5612   },
5613   {
5614     /* TLS LE LA|LS (@TPOFF)  */
5615     BFD_RELOC_NDS32_TLS_LE_HI20,
5616     NULL,
5617     NDS32_RELAX_HINT_TLS_LE_LS,
5618     BR_RANGE_U4G,
5619     N32_RELAX_SETHI | N32_RELAX_ORI,
5620     N32_RELAX_ALU1 | N32_RELAX_MEM,
5621   },
5622   {
5623     /* TLS IE LA */
5624     BFD_RELOC_NDS32_TLS_IE_HI20,
5625     NULL,
5626     NDS32_RELAX_HINT_TLS_IE_LA,
5627     BR_RANGE_U4G,
5628     N32_RELAX_SETHI | N32_RELAX_LSI,
5629     0,
5630   },
5631 {
5632     /* TLS IE LS */
5633     BFD_RELOC_NDS32_TLS_IE_HI20,
5634     NULL,
5635     NDS32_RELAX_HINT_TLS_IE_LS,
5636     BR_RANGE_U4G,
5637     N32_RELAX_SETHI | N32_RELAX_LSI | N32_RELAX_MEM,
5638     0,
5639   },
5640   {
5641     /* TLS IEGP LA */
5642     BFD_RELOC_NDS32_TLS_IEGP_HI20,
5643     NULL,
5644     NDS32_RELAX_HINT_TLS_IEGP_LA,
5645     BR_RANGE_U4G,
5646     N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_MEM,
5647     0,
5648   },
5649   {
5650     /* TLS DESC LS */
5651     BFD_RELOC_NDS32_TLS_DESC_HI20,
5652     NULL,
5653     NDS32_RELAX_HINT_TLS_DESC_LS,
5654     BR_RANGE_U4G,
5655     N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_ALU1 | N32_RELAX_CALL,
5656     N32_RELAX_LSI | N32_RELAX_MEM,
5657   },
5658   /* last one */
5659   {0, NULL, 0, 0 ,0, 0}
5660 };
5661 
5662 /* Find the relaxation pattern according to instructions.  */
5663 
5664 static bool
nds32_find_reloc_table(struct nds32_relocs_pattern * relocs_pattern,struct nds32_relax_hint_table * hint_info)5665 nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern,
5666 			struct nds32_relax_hint_table *hint_info)
5667 {
5668   unsigned int opcode, seq_size;
5669   enum nds32_br_range range;
5670   struct nds32_relocs_pattern *pattern, *hi_pattern = NULL;
5671   const char *opc = NULL;
5672   relax_info_t *relax_info = NULL;
5673   nds32_relax_fixup_info_t *fixup_info, *hint_fixup;
5674   enum nds32_relax_hint_type hint_type = NDS32_RELAX_HINT_NONE;
5675   struct nds32_relax_hint_table *table_ptr;
5676   uint32_t *code_seq, *hint_code;
5677   enum nds32_insn_type relax_type = 0;
5678   struct nds32_hint_map *map_ptr = hint_map;
5679   unsigned int i;
5680   const char *check_insn[] =
5681     { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" };
5682 
5683   /* TODO: PLT GOT.  */
5684   /* Traverse all pattern instruction and set flag.  */
5685   pattern = relocs_pattern;
5686   while (pattern)
5687     {
5688       if (pattern->opcode->isize == 4)
5689 	{
5690 	  /* 4 byte instruction.  */
5691 	  opcode = N32_OP6 (pattern->opcode->value);
5692 	  switch (opcode)
5693 	    {
5694 	    case N32_OP6_SETHI:
5695 	      hi_pattern = pattern;
5696 	      relax_type |= N32_RELAX_SETHI;
5697 	      break;
5698 	    case N32_OP6_MEM:
5699 	      relax_type |= N32_RELAX_MEM;
5700 	      break;
5701 	    case N32_OP6_ALU1:
5702 	      relax_type |= N32_RELAX_ALU1;
5703 	      break;
5704 	    case N32_OP6_ORI:
5705 	      relax_type |= N32_RELAX_ORI;
5706 	      break;
5707 	    case N32_OP6_BR1:
5708 	    case N32_OP6_BR2:
5709 	    case N32_OP6_BR3:
5710 	      relax_type |= N32_RELAX_BR;
5711 	      break;
5712 	    case N32_OP6_MOVI:
5713 	      relax_type |= N32_RELAX_MOVI;
5714 	      break;
5715 	    case N32_OP6_LBI:
5716 	    case N32_OP6_SBI:
5717 	    case N32_OP6_LBSI:
5718 	    case N32_OP6_LHI:
5719 	    case N32_OP6_SHI:
5720 	    case N32_OP6_LHSI:
5721 	    case N32_OP6_LWI:
5722 	    case N32_OP6_SWI:
5723 	    case N32_OP6_LWC:
5724 	    case N32_OP6_SWC:
5725 	    case N32_OP6_LDC:
5726 	    case N32_OP6_SDC:
5727 	      relax_type |= N32_RELAX_LSI;
5728 	      break;
5729 	    case N32_OP6_JREG:
5730 	      if (__GF (pattern->opcode->value, 0, 1) == 1)
5731 		relax_type |= N32_RELAX_CALL;
5732 	      else
5733 		relax_type |= N32_RELAX_JUMP;
5734 	      break;
5735 	    case N32_OP6_JI:
5736 	      if (__GF (pattern->opcode->value, 24, 1) == 1)
5737 		relax_type |= N32_RELAX_CALL;
5738 	      else
5739 		relax_type |= N32_RELAX_JUMP;
5740 	      break;
5741 	    default:
5742 	      as_warn (_("relax hint unrecognized instruction: line %d."),
5743 		       pattern->frag->fr_line);
5744 	      return false;
5745 	    }
5746 	}
5747       else
5748 	{
5749 	  /* 2 byte instruction.  Compare by opcode name because
5750 	     the opcode of 2byte instruction is not regular.  */
5751 	  int is_matched = 0;
5752 	  for (i = 0; i < ARRAY_SIZE (check_insn); i++)
5753 	    {
5754 	      if (strcmp (pattern->opcode->opcode, check_insn[i]) == 0)
5755 		{
5756 		  relax_type |= N32_RELAX_BR;
5757 		  is_matched += 1;
5758 		  break;
5759 		}
5760 	    }
5761 	  if (!is_matched)
5762 	    relax_type |= N32_RELAX_16BIT;
5763 	}
5764       pattern = pattern->next;
5765     }
5766 
5767   /* Analysis instruction flag to choose relaxation table.  */
5768   while (map_ptr->insn_list != 0)
5769     {
5770       struct nds32_hint_map *hint = map_ptr++;
5771       enum nds32_insn_type must = hint->insn_list;
5772       enum nds32_insn_type optional = hint->option_list;
5773       enum nds32_insn_type extra;
5774 
5775       if (must != (must & relax_type))
5776 	continue;
5777 
5778       extra = relax_type ^ must;
5779       if (extra != (extra & optional))
5780 	continue;
5781 
5782       if (!hi_pattern
5783 	  || (hi_pattern->fixP
5784 	      && hi_pattern->fixP->fx_r_type == hint->hi_type))
5785 	{
5786 	  opc = hint->opc;
5787 	  hint_type = hint->hint_type;
5788 	  range = hint->range;
5789 	  map_ptr = hint;
5790 	  break;
5791 	}
5792     }
5793 
5794   if (map_ptr->insn_list == 0)
5795     {
5796       if (!nds32_pic)
5797 	as_warn (_("Can not find match relax hint.  Line: %d"),
5798 		 relocs_pattern->frag->fr_line);
5799       return false;
5800     }
5801 
5802   /* Get the match table.  */
5803   if (opc)
5804     {
5805       /* Branch relax pattern.  */
5806       relax_info = str_hash_find (nds32_relax_info_hash, opc);
5807       if (!relax_info)
5808 	return false;
5809       fixup_info = relax_info->relax_fixup[range];
5810       code_seq = relax_info->relax_code_seq[range];
5811       seq_size = relax_info->relax_code_size[range];
5812     }
5813   else if (hint_type)
5814     {
5815       /* Load-store relax pattern.  */
5816       table_ptr = relax_ls_table;
5817       while (table_ptr->main_type != 0)
5818 	{
5819 	  if (table_ptr->main_type == hint_type)
5820 	    {
5821 	      fixup_info = table_ptr->relax_fixup;
5822 	      code_seq = table_ptr->relax_code_seq;
5823 	      seq_size = table_ptr->relax_code_size;
5824 	      break;
5825 	    }
5826 	  table_ptr++;
5827 	}
5828       if (table_ptr->main_type == 0)
5829 	return false;
5830     }
5831   else
5832     return false;
5833 
5834   hint_fixup = hint_info->relax_fixup;
5835   hint_code = hint_info->relax_code_seq;
5836   hint_info->relax_code_size = seq_size;
5837 
5838   while (fixup_info->size != 0)
5839     {
5840       if (fixup_info->ramp & NDS32_HINT)
5841 	{
5842 	  memcpy (hint_fixup, fixup_info, sizeof (nds32_relax_fixup_info_t));
5843 	  hint_fixup++;
5844 	}
5845       fixup_info++;
5846     }
5847   /* Clear final relocation.  */
5848   memset (hint_fixup, 0, sizeof (nds32_relax_fixup_info_t));
5849   /* Copy code sequence.  */
5850   memcpy (hint_code, code_seq, seq_size);
5851   return true;
5852 }
5853 
5854 /* Because there are a lot of variant of load-store, check
5855    all these type here.  */
5856 
5857 #define CLEAN_REG(insn) ((insn) & 0xfe0003ff)
5858 #define GET_OPCODE(insn) ((insn) & 0xfe000000)
5859 
5860 static bool
nds32_match_hint_insn(struct nds32_opcode * opcode,uint32_t seq)5861 nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq)
5862 {
5863   const char *check_insn[] =
5864     { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8", "jral5" };
5865   uint32_t insn = opcode->value;
5866   unsigned int i;
5867 
5868   insn = CLEAN_REG (opcode->value);
5869   if (insn == seq)
5870     return true;
5871 
5872   switch (seq)
5873     {
5874     case OP6 (LBI):
5875       /* In relocation_table, it regards instruction LBI as representation
5876 	 of all the NDS32_RELAX_HINT_LS pattern.  */
5877       if (insn == OP6 (LBI) || insn == OP6 (SBI) || insn == OP6 (LBSI)
5878 	  || insn == OP6 (LHI) || insn == OP6 (SHI) || insn == OP6 (LHSI)
5879 	  || insn == OP6 (LWI) || insn == OP6 (SWI)
5880 	  || insn == OP6 (LWC) || insn == OP6 (SWC)
5881 	  || insn == OP6 (LDC) || insn == OP6 (SDC))
5882 	return true;
5883       break;
5884     case OP6 (BR2):
5885       /* This is for LONGCALL5 and LONGCALL6.  */
5886       if (insn == OP6 (BR2))
5887 	return true;
5888       break;
5889     case OP6 (BR1):
5890       /* This is for LONGJUMP5 and LONGJUMP6.  */
5891       if (opcode->isize == 4
5892 	  && (insn == OP6 (BR1) || insn == OP6 (BR2) || insn == OP6 (BR3)))
5893 	return true;
5894       else if (opcode->isize == 2)
5895 	{
5896 	  for (i = 0; i < ARRAY_SIZE (check_insn); i++)
5897 	    if (strcmp (opcode->opcode, check_insn[i]) == 0)
5898 	      return true;
5899 	}
5900       break;
5901     case OP6 (MOVI):
5902       /* This is for LONGJUMP7.  */
5903       if (opcode->isize == 2 && strcmp (opcode->opcode, "movi55") == 0)
5904 	return true;
5905       break;
5906     case OP6 (MEM):
5907       if (OP6 (MEM) == GET_OPCODE (insn))
5908 	return true;
5909       break;
5910     case OP6 (JREG):
5911       /* bit 24: N32_JI_JAL  */ /* feed me!  */
5912       if ((insn & ~(N32_BIT (24))) == JREG (JRAL))
5913 	return true;
5914       break;
5915     default:
5916       if (opcode->isize == 2)
5917 	{
5918 	  for (i = 0; i < ARRAY_SIZE (check_insn); i++)
5919 	    if (strcmp (opcode->opcode, check_insn[i]) == 0)
5920 	      return true;
5921 
5922 	  if ((strcmp (opcode->opcode, "add5.pc") == 0) ||
5923 	      (strcmp (opcode->opcode, "add45") == 0))
5924 	    return true;
5925 	}
5926     }
5927   return false;
5928 }
5929 
5930 /* Append relax relocation for link time relaxing.  */
5931 
5932 static void
nds32_elf_append_relax_relocs(const char * key,const void * value)5933 nds32_elf_append_relax_relocs (const char *key, const void *value)
5934 {
5935   struct nds32_relocs_pattern *relocs_pattern =
5936     (struct nds32_relocs_pattern *) value;
5937   struct nds32_relocs_pattern *pattern_temp, *pattern_now;
5938   symbolS *sym, *hi_sym = NULL;
5939   expressionS exp;
5940   fragS *fragP;
5941   segT seg_bak = now_seg;
5942   frchainS *frchain_bak = frchain_now;
5943   struct nds32_relax_hint_table hint_info;
5944   nds32_relax_fixup_info_t *hint_fixup, *fixup_now;
5945   size_t fixup_size;
5946   offsetT branch_offset, hi_branch_offset = 0;
5947   fixS *fixP;
5948   int range, offset;
5949   unsigned int ptr_offset, hint_count, relax_code_size, count = 0;
5950   uint32_t *code_seq, code_insn;
5951   char *where;
5952   int pcrel;
5953 
5954   if (!relocs_pattern)
5955     return;
5956 
5957   if (!nds32_find_reloc_table (relocs_pattern, &hint_info))
5958     return;
5959 
5960   /* Save symbol for some EMPTY relocation using.  */
5961   pattern_now = relocs_pattern;
5962   while (pattern_now)
5963     {
5964       if (pattern_now->opcode->value == OP6 (SETHI))
5965 	{
5966 	  hi_sym = pattern_now->sym;
5967 	  hi_branch_offset = pattern_now->fixP->fx_offset;
5968 	  break;
5969 	}
5970       pattern_now = pattern_now->next;
5971     }
5972 
5973   /* Inserting fix up must specify now_seg or frchain_now.  */
5974   now_seg = relocs_pattern->seg;
5975   frchain_now = relocs_pattern->frchain;
5976   fragP = relocs_pattern->frag;
5977   branch_offset = fragP->fr_offset;
5978 
5979   hint_fixup = hint_info.relax_fixup;
5980   code_seq = hint_info.relax_code_seq;
5981   relax_code_size = hint_info.relax_code_size;
5982   pattern_now = relocs_pattern;
5983 
5984 #ifdef NDS32_LINUX_TOOLCHAIN
5985   /* prepare group relocation ID (number).  */
5986   long group_id = 0;
5987   if (key)
5988     {
5989       /* convert .relax_hint key to number */
5990       errno = 0;
5991       group_id = strtol (key, NULL, 10);
5992       if ((errno == ERANGE && (group_id == LONG_MAX || group_id == LONG_MIN))
5993 	  || (errno != 0 && group_id == 0))
5994 	{
5995 	  as_bad (_("Internal error: .relax_hint KEY is not a number!"));
5996 	  goto restore;
5997 	}
5998     }
5999 #endif
6000 
6001   /* Insert relaxation.  */
6002   exp.X_op = O_symbol;
6003 
6004   /* For each instruction in the hint group.  */
6005   while (pattern_now)
6006     {
6007       if (count >= relax_code_size / 4)
6008 	count = 0;
6009 
6010       /* Choose the match fixup by instruction.  */
6011       code_insn = CLEAN_REG (*(code_seq + count));
6012       if (!nds32_match_hint_insn (pattern_now->opcode, code_insn))
6013 	{
6014 	  /* Try search from head again */
6015 	  count = 0;
6016 	  code_insn = CLEAN_REG (*(code_seq + count));
6017 
6018 	  while (!nds32_match_hint_insn (pattern_now->opcode, code_insn))
6019 	    {
6020 	      count++;
6021 	      if (count >= relax_code_size / 4)
6022 		{
6023 		  as_bad (_("Internal error: Relax hint (%s) error. %s: %s (%x)"),
6024 			  key,
6025 			  now_seg->name,
6026 			  pattern_now->opcode->opcode,
6027 			  pattern_now->opcode->value);
6028 		  goto restore;
6029 		}
6030 	      code_insn = CLEAN_REG (*(code_seq + count));
6031 	    }
6032 	}
6033       fragP = pattern_now->frag;
6034       sym = pattern_now->sym;
6035       branch_offset = fragP->fr_offset;
6036       offset = count * 4;
6037       where = pattern_now->where;
6038       /* Find the instruction map fix.  */
6039       fixup_now = hint_fixup;
6040       while (fixup_now->offset != offset)
6041 	{
6042 	  fixup_now++;
6043 	  if (fixup_now->size == 0)
6044 	    break;
6045 	}
6046       /* This element is without relaxation relocation.  */
6047       if (fixup_now->size == 0)
6048 	{
6049 	  pattern_now = pattern_now->next;
6050 	  continue;
6051 	}
6052       fixup_size = fixup_now->size;
6053 
6054       /* Insert all fixup.  */
6055       pcrel = 0;
6056       while (fixup_size != 0 && fixup_now->offset == offset)
6057 	{
6058 	  /* Set the real instruction size in element.  */
6059 	  fixup_size = pattern_now->opcode->isize;
6060 	  pcrel = ((fixup_now->ramp & NDS32_PCREL) != 0) ? 1 : 0;
6061 	  if (fixup_now->ramp & NDS32_FIX)
6062 	    {
6063 	      /* Convert original relocation.  */
6064 	      pattern_now->fixP->fx_r_type = fixup_now->r_type ;
6065 	      fixup_size = 0;
6066 	    }
6067 	  else if ((fixup_now->ramp & NDS32_PTR) != 0)
6068 	    {
6069 	      /* This relocation has to point to another instruction.  Make
6070 		 sure each resolved relocation has to be pointed.  */
6071 	      pattern_temp = relocs_pattern;
6072 	      /* All instruction in relax_table should be 32-bit.  */
6073 	      hint_count = hint_info.relax_code_size / 4;
6074 	      code_insn = CLEAN_REG (*(code_seq + hint_count - 1));
6075 	      while (pattern_temp)
6076 		{
6077 		  /* Point to every resolved relocation.  */
6078 		  if (nds32_match_hint_insn (pattern_temp->opcode, code_insn))
6079 		    {
6080 		      ptr_offset =
6081 			pattern_temp->where - pattern_temp->frag->fr_literal;
6082 		      exp.X_add_symbol = symbol_temp_new (now_seg,
6083 							  pattern_temp->frag,
6084 							  ptr_offset);
6085 		      exp.X_add_number = 0;
6086 		      fixP =
6087 			fix_new_exp (fragP, where - fragP->fr_literal,
6088 				     fixup_size, &exp, 0, fixup_now->r_type);
6089 		      fixP->fx_addnumber = fixP->fx_offset;
6090 		    }
6091 		  pattern_temp = pattern_temp->next;
6092 		}
6093 	      fixup_size = 0;
6094 	    }
6095 	  else if (fixup_now->ramp & NDS32_ADDEND)
6096 	    {
6097 	      range = nds32_elf_sethi_range (relocs_pattern);
6098 	      if (range == NDS32_LOADSTORE_NONE)
6099 		{
6100 		  as_bad (_("Internal error: Range error. %s"), now_seg->name);
6101 		  return;
6102 		}
6103 	      exp.X_add_symbol = abs_section_sym;
6104 	      exp.X_add_number = SET_ADDEND (4, 0, optimize, enable_16bit);
6105 	      exp.X_add_number |= ((range & 0x3f) << 8);
6106 	    }
6107 	  else if ((fixup_now->ramp & NDS32_ABS) != 0)
6108 	    {
6109 	      /* This is a tag relocation.  */
6110 	      exp.X_add_symbol = abs_section_sym;
6111 	      exp.X_add_number = 0;
6112 	    }
6113 	  else if ((fixup_now->ramp & NDS32_INSN16) != 0)
6114 	    {
6115 	      if (!enable_16bit)
6116 		fixup_size = 0;
6117 	      /* This is a tag relocation.  */
6118 	      exp.X_add_symbol = abs_section_sym;
6119 	      exp.X_add_number = 0;
6120 	    }
6121 	  else if ((fixup_now->ramp & NDS32_SYM) != 0)
6122 	    {
6123 	      /* For EMPTY relocation save the true symbol.  */
6124 	      exp.X_add_symbol = hi_sym;
6125 	      exp.X_add_number = hi_branch_offset;
6126 	    }
6127 	  else if (NDS32_SYM_DESC_MEM & fixup_now->ramp)
6128 	    {
6129 	      /* Do the same as NDS32_SYM.  */
6130 	      exp.X_add_symbol = hi_sym;
6131 	      exp.X_add_number = hi_branch_offset;
6132 
6133 	      /* Extra to NDS32_SYM.  */
6134 	      /* Detect if DESC_FUNC relax type do apply.  */
6135 	      if ((REG_GP == N32_RA5 (pattern_now->insn))
6136 		  || (REG_GP == N32_RB5 (pattern_now->insn)))
6137 		{
6138 		  fixP = fix_new_exp (fragP, where - fragP->fr_literal,
6139 				      fixup_size, &exp, pcrel,
6140 				      BFD_RELOC_NDS32_TLS_DESC_FUNC);
6141 		  fixP->fx_addnumber = fixP->fx_offset;
6142 
6143 		  fixup_size = 0;
6144 		}
6145 	      /* Else do as usual.  */
6146 	    }
6147 	  else if (fixup_now->ramp & NDS32_PTR_PATTERN)
6148 	    {
6149 	      /* Find out PTR_RESOLVED code pattern.  */
6150 	      nds32_relax_fixup_info_t *next_fixup = fixup_now + 1;
6151 	      uint32_t resolved_pattern = 0;
6152 	      while (next_fixup->offset)
6153 		{
6154 		  if (next_fixup->r_type == BFD_RELOC_NDS32_PTR_RESOLVED)
6155 		    {
6156 		      uint32_t new_pattern = code_seq[next_fixup->offset >> 2];
6157 		      if (!resolved_pattern)
6158 			resolved_pattern = new_pattern;
6159 		      else if (new_pattern != resolved_pattern)
6160 			{
6161 			  as_warn (_("Multiple BFD_RELOC_NDS32_PTR_RESOLVED "
6162 				     "patterns are not supported yet!"));
6163 			  break;
6164 			}
6165 		    }
6166 		  ++next_fixup;
6167 		}
6168 
6169 	      /* Find matched code and insert fix-ups.  */
6170 	      struct nds32_relocs_pattern *next_pattern = pattern_now->next;
6171 	      /* This relocation has to point to another instruction.
6172 		 Make sure each resolved relocation has to be pointed.  */
6173 	      /* All instruction in relax_table should be 32-bit.  */
6174 	      while (next_pattern)
6175 		{
6176 		  uint32_t cur_pattern = GET_OPCODE (next_pattern->opcode->value);
6177 		  if (cur_pattern == resolved_pattern)
6178 		    {
6179 		      ptr_offset = next_pattern->where
6180 			- next_pattern->frag->fr_literal;
6181 		      exp.X_add_symbol = symbol_temp_new (now_seg,
6182 							  next_pattern->frag,
6183 							  ptr_offset);
6184 		      exp.X_add_number = 0;
6185 		      fixP = fix_new_exp (fragP, where - fragP->fr_literal,
6186 					  fixup_size, &exp, 0,
6187 					  fixup_now->r_type);
6188 		      fixP->fx_addnumber = fixP->fx_offset;
6189 		    }
6190 		  next_pattern = next_pattern->next;
6191 		}
6192 
6193 	      fixup_size = 0;
6194 	    }
6195 	  else if (fixup_now->ramp & NDS32_PTR_MULTIPLE)
6196 	    {
6197 	      /* Find each PTR_RESOLVED pattern after PTR.  */
6198 	      nds32_relax_fixup_info_t *next_fixup = fixup_now + 1;
6199 	      while (next_fixup->offset)
6200 		{
6201 		  if (next_fixup->r_type == BFD_RELOC_NDS32_PTR_RESOLVED)
6202 		    {
6203 		      uint32_t pattern = code_seq[next_fixup->offset >> 2];
6204 		      /* Find matched code to insert fix-ups.  */
6205 		      struct nds32_relocs_pattern *next_insn = pattern_now->next;
6206 		      while (next_insn)
6207 			{
6208 			  uint32_t insn_pattern = GET_OPCODE (next_insn->opcode->value);
6209 			  if (insn_pattern == pattern)
6210 			    {
6211 			      ptr_offset = next_insn->where
6212 				- next_insn->frag->fr_literal;
6213 			      exp.X_add_symbol = symbol_temp_new (now_seg,
6214 								  next_insn->frag,
6215 								  ptr_offset);
6216 			      exp.X_add_number = 0;
6217 			      fixP = fix_new_exp (fragP,
6218 						  where - fragP->fr_literal,
6219 						  fixup_size, &exp, 0,
6220 						  fixup_now->r_type);
6221 			      fixP->fx_addnumber = fixP->fx_offset;
6222 			    }
6223 			  next_insn = next_insn->next;
6224 			}
6225 		    }
6226 		  ++next_fixup;
6227 		}
6228 	      fixup_size = 0;
6229 	    }
6230 	  else
6231 	    {
6232 	      exp.X_add_symbol = sym;
6233 	      exp.X_add_number = branch_offset;
6234 	    }
6235 
6236 	  if (fixup_size != 0)
6237 	    {
6238 	      fixP = fix_new_exp (fragP, where - fragP->fr_literal, fixup_size,
6239 				  &exp, pcrel, fixup_now->r_type);
6240 	      fixP->fx_addnumber = fixP->fx_offset;
6241 	    }
6242 	  fixup_now++;
6243 	  fixup_size = fixup_now->size;
6244 	}
6245 
6246 #ifdef NDS32_LINUX_TOOLCHAIN
6247       /* Insert group relocation for each relax hint.  */
6248       if (key)
6249 	{
6250 	  exp.X_add_symbol = hi_sym; /* for eyes only */
6251 	  exp.X_add_number = group_id;
6252 	  fixP = fix_new_exp (fragP, where - fragP->fr_literal, fixup_size,
6253 			      &exp, pcrel, BFD_RELOC_NDS32_GROUP);
6254 	  fixP->fx_addnumber = fixP->fx_offset;
6255 	}
6256 #endif
6257 
6258       if (count < relax_code_size / 4)
6259 	count++;
6260       pattern_now = pattern_now->next;
6261     }
6262 
6263  restore:
6264   now_seg = seg_bak;
6265   frchain_now = frchain_bak;
6266 }
6267 
6268 static int
nds32_elf_append_relax_relocs_traverse(void ** slot,void * arg ATTRIBUTE_UNUSED)6269 nds32_elf_append_relax_relocs_traverse (void **slot, void *arg ATTRIBUTE_UNUSED)
6270 {
6271   string_tuple_t *tuple = *((string_tuple_t **) slot);
6272   nds32_elf_append_relax_relocs (tuple->key, tuple->value);
6273   return 1;
6274 }
6275 
6276 
6277 static void
nds32_str_tolower(const char * src,char * dest)6278 nds32_str_tolower (const char *src, char *dest)
6279 {
6280   unsigned int i, len;
6281 
6282   len = strlen (src);
6283 
6284   for (i = 0; i < len; i++)
6285     *(dest + i) = TOLOWER (*(src + i));
6286 
6287   *(dest + i) = '\0';
6288 }
6289 
6290 /* Check instruction if it can be used for the baseline.  */
6291 
6292 static bool
nds32_check_insn_available(struct nds32_asm_insn insn,const char * str)6293 nds32_check_insn_available (struct nds32_asm_insn insn, const char *str)
6294 {
6295   int attr = insn.attr & ATTR_ALL;
6296   static int baseline_isa = 0;
6297   char *s;
6298 
6299   s = xmalloc (strlen (str) + 1);
6300   nds32_str_tolower (str, s);
6301   if (verbatim
6302       && (((insn.opcode->value == ALU2 (MTUSR)
6303 	    || insn.opcode->value == ALU2 (MFUSR))
6304 	   && (strstr (s, "lc")
6305 	       || strstr (s, "le")
6306 	       || strstr (s, "lb")))
6307 	  || (insn.attr & NASM_ATTR_ZOL)))
6308     {
6309       as_bad (_("Not support instruction %s in verbatim."), str);
6310       return false;
6311     }
6312   free (s);
6313 
6314   if (!enable_16bit && insn.opcode->isize == 2)
6315     {
6316       as_bad (_("16-bit instruction is disabled: %s."), str);
6317       return false;
6318     }
6319 
6320   /* No isa setting or all isa can use.  */
6321   if (attr == 0 || attr == ATTR_ALL)
6322     return true;
6323 
6324   if (baseline_isa == 0)
6325     {
6326       /* Map option baseline and instruction attribute.  */
6327       switch (nds32_baseline)
6328 	{
6329 	case ISA_V2:
6330 	  baseline_isa = ATTR (ISA_V2);
6331 	  break;
6332 	case ISA_V3:
6333 	  baseline_isa = ATTR (ISA_V3);
6334 	  break;
6335 	case ISA_V3M:
6336 	  baseline_isa = ATTR (ISA_V3M);
6337 	  break;
6338 	}
6339     }
6340 
6341   if  ((baseline_isa & attr) == 0)
6342     {
6343       as_bad (_("Instruction %s not supported in the baseline."), str);
6344       return false;
6345     }
6346   return true;
6347 }
6348 
6349 /* Stub of machine dependent.  */
6350 
6351 void
md_assemble(char * str)6352 md_assemble (char *str)
6353 {
6354   struct nds32_asm_insn insn;
6355   char *out;
6356   struct nds32_pseudo_opcode *popcode;
6357   const struct nds32_field *fld = NULL;
6358   fixS *fixP;
6359   uint16_t insn_16;
6360   struct nds32_relocs_pattern *relocs_temp;
6361   struct nds32_relocs_group *group_temp;
6362   fragS *fragP;
6363   int label = label_exist;
6364   static bool pseudo_hint = false;
6365 
6366   popcode = nds32_lookup_pseudo_opcode (str);
6367   /* Note that we need to check 'verbatim' and
6368      'opcode->physical_op'.  If the assembly content is generated by
6369      compiler and this opcode is a physical instruction, there is no
6370      need to perform pseudo instruction expansion/transformation.  */
6371   if (popcode && !(verbatim && popcode->physical_op))
6372     {
6373       /* Pseudo instruction is with relax_hint.  */
6374       if (relaxing)
6375 	pseudo_hint = true;
6376       pseudo_opcode = true;
6377       nds32_pseudo_opcode_wrapper (str, popcode);
6378       pseudo_opcode = false;
6379       pseudo_hint = false;
6380       nds32_elf_append_relax_relocs (NULL, relocs_list);
6381 
6382       /* Free relax_hint group list.  */
6383       while (nds32_relax_hint_current)
6384 	{
6385 	  group_temp = nds32_relax_hint_current->next;
6386 	  free (nds32_relax_hint_current);
6387 	  nds32_relax_hint_current = group_temp;
6388 	}
6389 
6390       /* Free pseudo list.  */
6391       relocs_temp = relocs_list;
6392       while (relocs_temp)
6393 	{
6394 	  relocs_list = relocs_list->next;
6395 	  free (relocs_temp);
6396 	  relocs_temp = relocs_list;
6397 	}
6398 
6399       return;
6400     }
6401 
6402   label_exist = 0;
6403   insn.info = XNEW (expressionS);
6404   asm_desc.result = NASM_OK;
6405   nds32_assemble (&asm_desc, &insn, str);
6406 
6407   switch (asm_desc.result)
6408     {
6409     case NASM_ERR_UNKNOWN_OP:
6410       as_bad (_("Unrecognized opcode, %s."), str);
6411       return;
6412     case NASM_ERR_SYNTAX:
6413       as_bad (_("Incorrect syntax, %s."), str);
6414       return;
6415     case NASM_ERR_OPERAND:
6416       as_bad (_("Unrecognized operand/register, %s."), str);
6417       return;
6418     case NASM_ERR_OUT_OF_RANGE:
6419       as_bad (_("Operand out of range, %s."), str);
6420       return;
6421     case NASM_ERR_REG_REDUCED:
6422       as_bad (_("Prohibited register used for reduced-register, %s."), str);
6423       return;
6424     case NASM_ERR_JUNK_EOL:
6425       as_bad (_("Junk at end of line, %s."), str);
6426       return;
6427     }
6428 
6429   gas_assert (insn.opcode);
6430 
6431   nds32_set_elf_flags_by_insn (&insn);
6432 
6433   gas_assert (insn.opcode->isize == 4 || insn.opcode->isize == 2);
6434 
6435   if (!nds32_check_insn_available (insn, str))
6436     return;
6437 
6438   /* Make sure the beginning of text being 2-byte align.  */
6439   nds32_adjust_label (1);
6440   add_mapping_symbol (MAP_CODE, 0, 0);
6441   fld = insn.field;
6442   /* Try to allocate the max size to guarantee relaxable same branch
6443      instructions in the same fragment.  */
6444   frag_grow (NDS32_MAXCHAR);
6445   fragP = frag_now;
6446 
6447   if (fld && (insn.attr & NASM_ATTR_BRANCH)
6448       && (pseudo_opcode || (insn.opcode->value != INSN_JAL
6449 			    && insn.opcode->value != INSN_J))
6450       && (!verbatim || pseudo_opcode))
6451     {
6452       /* User assembly code branch relax for it.  */
6453       /* If fld is not NULL, it is a symbol.  */
6454       /* Branch must relax to proper pattern in user assembly code exclude
6455 	 J and JAL.  Keep these two in original type for users which wants
6456 	 to keep their size be fixed.  In general, assembler does not convert
6457 	 instruction generated by compiler.  But jump instruction may be
6458 	 truncated in text virtual model.  For workaround, compiler generate
6459 	 pseudo jump to fix this issue currently.  */
6460 
6461       /* Get branch range type.  */
6462       dwarf2_emit_insn (0);
6463       enum nds32_br_range range_type;
6464       expressionS *pexp = insn.info;
6465 
6466       range_type = get_range_type (fld);
6467 
6468       out = frag_var (rs_machine_dependent, NDS32_MAXCHAR,
6469 		      0, /* VAR is un-used.  */
6470 		      range_type, /* SUBTYPE is used as range type.  */
6471 		      pexp->X_add_symbol, pexp->X_add_number, 0);
6472 
6473       fragP->fr_fix += insn.opcode->isize;
6474       fragP->tc_frag_data.opcode = insn.opcode;
6475       fragP->tc_frag_data.insn = insn.insn;
6476       if (insn.opcode->isize == 4)
6477 	bfd_putb32 (insn.insn, out);
6478       else if (insn.opcode->isize == 2)
6479 	bfd_putb16 (insn.insn, out);
6480       fragP->tc_frag_data.flag |= NDS32_FRAG_BRANCH;
6481 
6482       free (insn.info);
6483       return;
6484       /* md_convert_frag will insert relocations.  */
6485     }
6486   else if (!relaxing && enable_16bit && (optimize || optimize_for_space)
6487 	   && ((!fld && !verbatim && insn.opcode->isize == 4
6488 		&& nds32_convert_32_to_16 (stdoutput, insn.insn, &insn_16, NULL))
6489 	       || (insn.opcode->isize == 2
6490 		   && nds32_convert_16_to_32 (stdoutput, insn.insn, NULL))))
6491     {
6492       /* Record this one is relaxable.  */
6493       expressionS *pexp = insn.info;
6494       dwarf2_emit_insn (0);
6495       if (fld)
6496 	{
6497 	  out = frag_var (rs_machine_dependent,
6498 			  4, /* Max size is 32-bit instruction.  */
6499 			  0, /* VAR is un-used.  */
6500 			  0, pexp->X_add_symbol, pexp->X_add_number, 0);
6501 	  fragP->tc_frag_data.flag |= NDS32_FRAG_RELAXABLE_BRANCH;
6502 	}
6503       else
6504 	out = frag_var (rs_machine_dependent,
6505 			4, /* Max size is 32-bit instruction.  */
6506 			0, /* VAR is un-used.  */
6507 			0, NULL, 0, NULL);
6508       fragP->tc_frag_data.flag |= NDS32_FRAG_RELAXABLE;
6509       fragP->tc_frag_data.opcode = insn.opcode;
6510       fragP->tc_frag_data.insn = insn.insn;
6511       fragP->fr_fix += 2;
6512 
6513       /* In original, we don't relax the instruction with label on it,
6514 	 but this may cause some redundant nop16.  Therefore, tag this
6515 	 relaxable instruction and relax it carefully.  */
6516       if (label)
6517 	fragP->tc_frag_data.flag |= NDS32_FRAG_LABEL;
6518 
6519       if (insn.opcode->isize == 4)
6520 	bfd_putb16 (insn_16, out);
6521       else if (insn.opcode->isize == 2)
6522 	bfd_putb16 (insn.insn, out);
6523 
6524       free (insn.info);
6525       return;
6526     }
6527   else if ((verbatim || !relaxing) && optimize && label)
6528     {
6529       /* This instruction is with label.  */
6530       expressionS exp;
6531       out = frag_var (rs_machine_dependent, insn.opcode->isize,
6532 		      0, 0, NULL, 0, NULL);
6533       /* If this instruction is branch target, it is not relaxable.  */
6534       fragP->tc_frag_data.flag = NDS32_FRAG_LABEL;
6535       fragP->tc_frag_data.opcode = insn.opcode;
6536       fragP->tc_frag_data.insn = insn.insn;
6537       fragP->fr_fix += insn.opcode->isize;
6538       if (insn.opcode->isize == 4)
6539 	{
6540 	  exp.X_op = O_symbol;
6541 	  exp.X_add_symbol = abs_section_sym;
6542 	  exp.X_add_number = 0;
6543 	  fixP = fix_new_exp (fragP, fragP->fr_fix - 4, 0, &exp,
6544 			      0, BFD_RELOC_NDS32_LABEL);
6545 	  if (!verbatim)
6546 	    fragP->tc_frag_data.flag = NDS32_FRAG_ALIGN;
6547 	}
6548     }
6549   else
6550     out = frag_more (insn.opcode->isize);
6551 
6552   if (insn.opcode->isize == 4)
6553     bfd_putb32 (insn.insn, out);
6554   else if (insn.opcode->isize == 2)
6555     bfd_putb16 (insn.insn, out);
6556 
6557   dwarf2_emit_insn (insn.opcode->isize);
6558 
6559   /* Compiler generating code and user assembly pseudo load-store, insert
6560      fixup here.  */
6561   expressionS *pexp = insn.info;
6562   fixP = nds32_elf_record_fixup_exp (fragP, str, fld, pexp, out, &insn);
6563   /* Build relaxation pattern when relaxing is enable.  */
6564   if (relaxing)
6565     nds32_elf_build_relax_relation (fixP, pexp, out, &insn, fragP, fld,
6566 				    pseudo_hint);
6567 
6568   free (insn.info);
6569 }
6570 
6571 /* md_macro_start  */
6572 
6573 void
nds32_macro_start(void)6574 nds32_macro_start (void)
6575 {
6576 }
6577 
6578 /* md_macro_info  */
6579 
6580 void
nds32_macro_info(void * info ATTRIBUTE_UNUSED)6581 nds32_macro_info (void *info ATTRIBUTE_UNUSED)
6582 {
6583 }
6584 
6585 /* md_macro_end  */
6586 
6587 void
nds32_macro_end(void)6588 nds32_macro_end (void)
6589 {
6590 }
6591 
6592 /* GAS will call this function with one argument, an expressionS pointer, for
6593    any expression that can not be recognized.  When the function is called,
6594    input_line_pointer will point to the start of the expression.  */
6595 
6596 void
md_operand(expressionS * expressionP)6597 md_operand (expressionS *expressionP)
6598 {
6599   if (*input_line_pointer == '#')
6600     {
6601       input_line_pointer++;
6602       expression (expressionP);
6603     }
6604 }
6605 
6606 /* GAS will call this function for each section at the end of the assembly, to
6607    permit the CPU back end to adjust the alignment of a section.  The function
6608    must take two arguments, a segT for the section and a valueT for the size of
6609    the section, and return a valueT for the rounded size.  */
6610 
6611 valueT
md_section_align(segT segment,valueT size)6612 md_section_align (segT segment, valueT size)
6613 {
6614   int align = bfd_section_alignment (segment);
6615 
6616   return ((size + (1 << align) - 1) & ((valueT) -1 << align));
6617 }
6618 
6619 /* GAS will call this function when a symbol table lookup fails, before it
6620    creates a new symbol.  Typically this would be used to supply symbols whose
6621    name or value changes dynamically, possibly in a context sensitive way.
6622    Predefined symbols with fixed values, such as register names or condition
6623    codes, are typically entered directly into the symbol table when md_begin
6624    is called.  One argument is passed, a char * for the symbol.  */
6625 
6626 symbolS *
md_undefined_symbol(char * name ATTRIBUTE_UNUSED)6627 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
6628 {
6629   return NULL;
6630 }
6631 
6632 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)6633 nds32_calc_branch_offset (segT segment, fragS *fragP,
6634 			  long stretch ATTRIBUTE_UNUSED,
6635 			  relax_info_t *relax_info,
6636 			  enum nds32_br_range branch_range_type)
6637 {
6638   struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
6639   symbolS *branch_symbol = fragP->fr_symbol;
6640   offsetT branch_offset = fragP->fr_offset;
6641   offsetT branch_target_address;
6642   offsetT branch_insn_address;
6643   long offset = 0;
6644 
6645   if ((S_GET_SEGMENT (branch_symbol) != segment)
6646       || S_IS_WEAK (branch_symbol))
6647     {
6648       /* The symbol is not in the SEGMENT.  It could be far far away.  */
6649       offset = 0x80000000;
6650     }
6651   else
6652     {
6653       /* Calculate symbol-to-instruction offset.  */
6654       branch_target_address = S_GET_VALUE (branch_symbol) + branch_offset;
6655       /* If the destination symbol is beyond current frag address,
6656 	 STRETCH will take effect to symbol's position.  */
6657       if (S_GET_VALUE (branch_symbol) > fragP->fr_address)
6658 	branch_target_address += stretch;
6659 
6660       branch_insn_address = fragP->fr_address + fragP->fr_fix;
6661       branch_insn_address -= opcode->isize;
6662 
6663       /* Update BRANCH_INSN_ADDRESS to relaxed position.  */
6664       branch_insn_address += (relax_info->relax_code_size[branch_range_type]
6665 			      - relax_info->relax_branch_isize[branch_range_type]);
6666 
6667       offset = branch_target_address - branch_insn_address;
6668     }
6669 
6670   return offset;
6671 }
6672 
6673 static enum nds32_br_range
nds32_convert_to_range_type(long offset)6674 nds32_convert_to_range_type (long offset)
6675 {
6676   enum nds32_br_range range_type;
6677 
6678   if (-(0x100) <= offset && offset < 0x100) /* 256 bytes */
6679     range_type = BR_RANGE_S256;
6680   else if (-(0x4000) <= offset && offset < 0x4000) /* 16K bytes */
6681     range_type = BR_RANGE_S16K;
6682   else if (-(0x10000) <= offset && offset < 0x10000) /* 64K bytes */
6683     range_type = BR_RANGE_S64K;
6684   else if (-(0x1000000) <= offset && offset < 0x1000000) /* 16M bytes */
6685     range_type = BR_RANGE_S16M;
6686   else /* 4G bytes */
6687     range_type = BR_RANGE_U4G;
6688 
6689   return range_type;
6690 }
6691 
6692 /* Set instruction register mask.  */
6693 
6694 static void
nds32_elf_get_set_cond(relax_info_t * relax_info,int offset,uint32_t * insn,uint32_t ori_insn,int range)6695 nds32_elf_get_set_cond (relax_info_t *relax_info, int offset, uint32_t *insn,
6696 			uint32_t ori_insn, int range)
6697 {
6698   nds32_cond_field_t *cond_fields = relax_info->cond_field;
6699   nds32_cond_field_t *code_seq_cond = relax_info->relax_code_condition[range];
6700   uint32_t mask;
6701   int i = 0;
6702 
6703   /* The instruction has conditions.  Collect condition values.  */
6704   while (code_seq_cond[i].bitmask != 0)
6705     {
6706       if (offset == code_seq_cond[i].offset)
6707 	{
6708 	  mask = (ori_insn >> cond_fields[i].bitpos) & cond_fields[i].bitmask;
6709 	  /* Sign extend.  */
6710 	  if (cond_fields[i].signed_extend)
6711 	    mask = (mask ^ ((cond_fields[i].bitmask + 1) >> 1)) -
6712 	      ((cond_fields[i].bitmask + 1) >> 1);
6713 	  *insn |= (mask & code_seq_cond[i].bitmask) << code_seq_cond[i].bitpos;
6714 	}
6715       i++;
6716     }
6717 }
6718 
6719 static int
nds32_relax_branch_instructions(segT segment,fragS * fragP,long stretch ATTRIBUTE_UNUSED,int init)6720 nds32_relax_branch_instructions (segT segment, fragS *fragP,
6721 				 long stretch ATTRIBUTE_UNUSED,
6722 				 int init)
6723 {
6724   enum nds32_br_range branch_range_type;
6725   struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
6726   long offset = 0;
6727   enum nds32_br_range real_range_type;
6728   int adjust = 0;
6729   relax_info_t *relax_info;
6730   int diff = 0;
6731   int i, j, k;
6732   int code_seq_size;
6733   uint32_t *code_seq;
6734   uint32_t insn;
6735   int insn_size;
6736   int code_seq_offset;
6737 
6738   /* Replace with gas_assert (fragP->fr_symbol != NULL); */
6739   if (fragP->fr_symbol == NULL)
6740     return adjust;
6741 
6742   /* If frag_var is not enough room, the previous frag is fr_full and with
6743      opcode.  The new one is rs_dependent but without opcode.  */
6744   if (opcode == NULL)
6745     return adjust;
6746 
6747   /* Use U4G mode for b and bal in verbatim mode because lto may combine
6748      functions into a file.  And order the file in the last when linking.
6749      Once there is multiple definition, the same function will be kicked.
6750      This may cause relocation truncated error.  */
6751   if (verbatim && !nds32_pic
6752       && (strcmp (opcode->opcode, "j") == 0
6753 	  || strcmp (opcode->opcode, "jal") == 0))
6754     {
6755       fragP->fr_subtype = BR_RANGE_U4G;
6756       if (init)
6757 	return 8;
6758       else
6759 	return 0;
6760     }
6761 
6762   relax_info = str_hash_find (nds32_relax_info_hash, opcode->opcode);
6763 
6764   if (relax_info == NULL)
6765     return adjust;
6766 
6767   if (init)
6768     {
6769       branch_range_type = relax_info->br_range;
6770       i = BR_RANGE_S256;
6771     }
6772   else
6773     {
6774       branch_range_type = fragP->fr_subtype;
6775       i = branch_range_type;
6776     }
6777 
6778   offset = nds32_calc_branch_offset (segment, fragP, stretch,
6779 				     relax_info, branch_range_type);
6780 
6781   real_range_type = nds32_convert_to_range_type (offset);
6782 
6783   /* If actual range is equal to instruction jump range, do nothing.  */
6784   if (real_range_type == branch_range_type)
6785     {
6786       fragP->fr_subtype = real_range_type;
6787       return adjust;
6788     }
6789 
6790   /* Find out proper relaxation code sequence.  */
6791   for (; i < BR_RANGE_NUM; i++)
6792     {
6793       if (real_range_type <= (unsigned int) i)
6794 	{
6795 	  if (init)
6796 	    diff = relax_info->relax_code_size[i] - opcode->isize;
6797 	  else if (real_range_type < (unsigned int) i)
6798 	    diff = relax_info->relax_code_size[real_range_type]
6799 	      - relax_info->relax_code_size[branch_range_type];
6800 	  else
6801 	    diff = relax_info->relax_code_size[i]
6802 	      - relax_info->relax_code_size[branch_range_type];
6803 
6804 	  /* If the instruction could be converted to 16-bits,
6805 	     minus the difference.  */
6806 	  code_seq_offset = 0;
6807 	  j = 0;
6808 	  k = 0;
6809 	  code_seq_size = relax_info->relax_code_size[i];
6810 	  code_seq = relax_info->relax_code_seq[i];
6811 	  while (code_seq_offset < code_seq_size)
6812 	    {
6813 	      insn = code_seq[j];
6814 	      if (insn & 0x80000000) /* 16-bits instruction.  */
6815 		{
6816 		  insn_size = 2;
6817 		}
6818 	      else /* 32-bits instruction.  */
6819 		{
6820 		  insn_size = 4;
6821 
6822 		  while (relax_info->relax_fixup[i][k].size !=0
6823 			 && relax_info->relax_fixup[i][k].offset < code_seq_offset)
6824 		    k++;
6825 		}
6826 
6827 	      code_seq_offset += insn_size;
6828 	      j++;
6829 	    }
6830 
6831 	  /* Update fr_subtype to new NDS32_BR_RANGE.  */
6832 	  fragP->fr_subtype = real_range_type;
6833 	  break;
6834 	}
6835     }
6836 
6837   return diff + adjust;
6838 }
6839 
6840 /* Adjust relaxable frag till current frag.  */
6841 
6842 static int
nds32_adjust_relaxable_frag(fragS * startP,fragS * fragP)6843 nds32_adjust_relaxable_frag (fragS *startP, fragS *fragP)
6844 {
6845   int adj;
6846   if (startP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
6847     adj = -2;
6848   else
6849     adj = 2;
6850 
6851   startP->tc_frag_data.flag ^= NDS32_FRAG_RELAXED;
6852 
6853   while (startP)
6854     {
6855       startP = startP->fr_next;
6856       if (startP)
6857 	{
6858 	  startP->fr_address += adj;
6859 	  if (startP == fragP)
6860 	    break;
6861 	}
6862     }
6863   return adj;
6864 }
6865 
6866 static addressT
nds32_get_align(addressT address,int align)6867 nds32_get_align (addressT address, int align)
6868 {
6869   addressT mask, new_address;
6870 
6871   mask = ~((addressT) (~0) << align);
6872   new_address = (address + mask) & (~mask);
6873   return (new_address - address);
6874 }
6875 
6876 /* Check the prev_frag is legal.  */
6877 static void
invalid_prev_frag(fragS * fragP,fragS ** prev_frag,bool relax)6878 invalid_prev_frag (fragS * fragP, fragS **prev_frag, bool relax)
6879 {
6880   addressT address;
6881   fragS *frag_start = *prev_frag;
6882 
6883   if (!frag_start || !relax)
6884     return;
6885 
6886   if (frag_start->last_fr_address >= fragP->last_fr_address)
6887     {
6888       *prev_frag = NULL;
6889       return;
6890     }
6891 
6892   fragS *frag_t = *prev_frag;
6893   while (frag_t != fragP)
6894     {
6895       if (frag_t->fr_type == rs_align
6896 	  || frag_t->fr_type == rs_align_code
6897 	  || frag_t->fr_type == rs_align_test)
6898 	{
6899 	  /* Relax instruction can not walk across label.  */
6900 	  if (frag_t->tc_frag_data.flag & NDS32_FRAG_LABEL)
6901 	    {
6902 	      prev_frag = NULL;
6903 	      return;
6904 	    }
6905 	  /* Relax previous relaxable to align rs_align frag.  */
6906 	  address = frag_t->fr_address + frag_t->fr_fix;
6907 	  addressT offset = nds32_get_align (address, (int) frag_t->fr_offset);
6908 	  if (offset & 0x2)
6909 	    {
6910 	      /* If there is label on the prev_frag, check if it is aligned.  */
6911 	      if (!((*prev_frag)->tc_frag_data.flag & NDS32_FRAG_LABEL)
6912 		  || (((*prev_frag)->fr_address + (*prev_frag)->fr_fix  - 2 )
6913 		      & 0x2) == 0)
6914 		nds32_adjust_relaxable_frag (*prev_frag, frag_t);
6915 	    }
6916 	  *prev_frag = NULL;
6917 	  return;
6918 	}
6919       frag_t = frag_t->fr_next;
6920     }
6921 
6922   if (fragP->tc_frag_data.flag & NDS32_FRAG_ALIGN)
6923     {
6924       address = fragP->fr_address;
6925       addressT offset = nds32_get_align (address, 2);
6926       if (offset & 0x2)
6927 	{
6928 	  /* If there is label on the prev_frag, check if it is aligned.  */
6929 	  if (!((*prev_frag)->tc_frag_data.flag & NDS32_FRAG_LABEL)
6930 	      || (((*prev_frag)->fr_address + (*prev_frag)->fr_fix  - 2 )
6931 		  & 0x2) == 0)
6932 	    nds32_adjust_relaxable_frag (*prev_frag, fragP);
6933 	}
6934       *prev_frag = NULL;
6935       return;
6936     }
6937 }
6938 
6939 /* md_relax_frag  */
6940 
6941 int
nds32_relax_frag(segT segment,fragS * fragP,long stretch ATTRIBUTE_UNUSED)6942 nds32_relax_frag (segT segment, fragS *fragP, long stretch ATTRIBUTE_UNUSED)
6943 {
6944   /* Currently, there are two kinds of relaxation in nds32 assembler.
6945      1. relax for branch
6946      2. relax for 32-bits to 16-bits  */
6947 
6948   static fragS *prev_frag = NULL;
6949   int adjust = 0;
6950 
6951   invalid_prev_frag (fragP, &prev_frag, true);
6952 
6953   if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
6954     adjust = nds32_relax_branch_instructions (segment, fragP, stretch, 0);
6955   if (fragP->tc_frag_data.flag & NDS32_FRAG_LABEL)
6956     prev_frag = NULL;
6957   if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE
6958       && (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED) == 0)
6959     /* Here is considered relaxed case originally.  But it may cause
6960        an endless loop when relaxing.  Once the instruction is relaxed,
6961        it can not be undone.  */
6962     prev_frag = fragP;
6963 
6964   return adjust;
6965 }
6966 
6967 /* This function returns an initial guess of the length by which a fragment
6968    must grow to hold a branch to reach its destination.  Also updates
6969    fr_type/fr_subtype as necessary.
6970 
6971    It is called just before doing relaxation.  Any symbol that is now undefined
6972    will not become defined.  The guess for fr_var is ACTUALLY the growth beyond
6973    fr_fix.  Whatever we do to grow fr_fix or fr_var contributes to our returned
6974    value.  Although it may not be explicit in the frag, pretend fr_var starts
6975    with a 0 value.  */
6976 
6977 int
md_estimate_size_before_relax(fragS * fragP,segT segment)6978 md_estimate_size_before_relax (fragS *fragP, segT segment)
6979 {
6980   /* Currently, there are two kinds of relaxation in nds32 assembler.
6981      1. relax for branch
6982      2. relax for 32-bits to 16-bits  */
6983 
6984   /* Save previous relaxable frag.  */
6985   static fragS *prev_frag = NULL;
6986   int adjust = 0;
6987 
6988   invalid_prev_frag (fragP, &prev_frag, false);
6989 
6990   if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
6991     adjust = nds32_relax_branch_instructions (segment, fragP, 0, 1);
6992   if (fragP->tc_frag_data.flag & NDS32_FRAG_LABEL)
6993     prev_frag = NULL;
6994   if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
6995     adjust = 2;
6996   else if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE)
6997     prev_frag = fragP;
6998 
6999   return adjust;
7000 }
7001 
7002 /* GAS will call this for each rs_machine_dependent fragment.  The instruction
7003    is completed using the data from the relaxation pass.  It may also create any
7004    necessary relocations.
7005 
7006    *FRAGP has been relaxed to its final size, and now needs to have the bytes
7007    inside it modified to conform to the new size.  It is called after relaxation
7008    is finished.
7009 
7010    fragP->fr_type == rs_machine_dependent.
7011    fragP->fr_subtype is the subtype of what the address relaxed to.  */
7012 
7013 void
md_convert_frag(bfd * abfd ATTRIBUTE_UNUSED,segT sec,fragS * fragP)7014 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP)
7015 {
7016   /* Convert branch relaxation instructions.  */
7017   symbolS *branch_symbol = fragP->fr_symbol;
7018   offsetT branch_offset = fragP->fr_offset;
7019   enum nds32_br_range branch_range_type = fragP->fr_subtype;
7020   struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
7021   uint32_t origin_insn = fragP->tc_frag_data.insn;
7022   relax_info_t *relax_info;
7023   char *fr_buffer;
7024   int fr_where;
7025   int addend ATTRIBUTE_UNUSED;
7026   offsetT branch_target_address, branch_insn_address;
7027   expressionS exp;
7028   fixS *fixP;
7029   uint32_t *code_seq;
7030   uint32_t insn;
7031   int code_size, insn_size, offset, fixup_size;
7032   int buf_offset, pcrel;
7033   int i, k;
7034   uint16_t insn_16;
7035   nds32_relax_fixup_info_t fixup_info[MAX_RELAX_FIX];
7036   /* Save the 1st instruction is converted to 16 bit or not.  */
7037   unsigned int branch_size;
7038   enum bfd_reloc_code_real final_r_type;
7039 
7040   /* Replace with gas_assert (branch_symbol != NULL); */
7041   if (branch_symbol == NULL && !(fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED))
7042     return;
7043 
7044   /* If frag_var is not enough room, the previous frag is fr_full and with
7045      opcode.  The new one is rs_dependent but without opcode.  */
7046   if (opcode == NULL)
7047     return;
7048 
7049   if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE_BRANCH)
7050     {
7051       relax_info = str_hash_find (nds32_relax_info_hash, opcode->opcode);
7052 
7053       if (relax_info == NULL)
7054 	return;
7055 
7056       i = BR_RANGE_S256;
7057       while (i < BR_RANGE_NUM
7058 	     && relax_info->relax_code_size[i]
7059 	     != (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED ? 4 : 2))
7060 	i++;
7061 
7062       if (i >= BR_RANGE_NUM)
7063 	as_bad ("Internal error: Cannot find relocation of"
7064 		"relaxable branch.");
7065 
7066       exp.X_op = O_symbol;
7067       exp.X_add_symbol = branch_symbol;
7068       exp.X_add_number = branch_offset;
7069       pcrel = ((relax_info->relax_fixup[i][0].ramp & NDS32_PCREL) != 0) ? 1 : 0;
7070       fr_where = fragP->fr_fix - 2;
7071       fixP = fix_new_exp (fragP, fr_where, relax_info->relax_fixup[i][0].size,
7072 			  &exp, pcrel, relax_info->relax_fixup[i][0].r_type);
7073       fixP->fx_addnumber = fixP->fx_offset;
7074 
7075       if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
7076 	{
7077 	  insn_16 = fragP->tc_frag_data.insn;
7078 	  nds32_convert_16_to_32 (stdoutput, insn_16, &insn);
7079 	  fr_buffer = fragP->fr_literal + fr_where;
7080 	  fragP->fr_fix += 2;
7081 	  exp.X_op = O_symbol;
7082 	  exp.X_add_symbol = abs_section_sym;
7083 	  exp.X_add_number = 0;
7084 	  fix_new_exp (fragP, fr_where, 4,
7085 		       &exp, 0, BFD_RELOC_NDS32_INSN16);
7086 	  number_to_chars_bigendian (fr_buffer, insn, 4);
7087 	}
7088     }
7089   else if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
7090     {
7091       if (fragP->tc_frag_data.opcode->isize == 2)
7092 	{
7093 	  insn_16 = fragP->tc_frag_data.insn;
7094 	  nds32_convert_16_to_32 (stdoutput, insn_16, &insn);
7095 	}
7096       else
7097 	insn = fragP->tc_frag_data.insn;
7098       fragP->fr_fix += 2;
7099       fr_where = fragP->fr_fix - 4;
7100       fr_buffer = fragP->fr_literal + fr_where;
7101       exp.X_op = O_symbol;
7102       exp.X_add_symbol = abs_section_sym;
7103       exp.X_add_number = 0;
7104       fix_new_exp (fragP, fr_where, 4, &exp, 0,
7105 		   BFD_RELOC_NDS32_INSN16);
7106       number_to_chars_bigendian (fr_buffer, insn, 4);
7107     }
7108   else if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
7109     {
7110       /* Branch instruction adjust and append relocations.  */
7111       relax_info = str_hash_find (nds32_relax_info_hash, opcode->opcode);
7112 
7113       if (relax_info == NULL)
7114 	return;
7115 
7116       fr_where = fragP->fr_fix - opcode->isize;
7117       fr_buffer = fragP->fr_literal + fr_where;
7118 
7119       if ((S_GET_SEGMENT (branch_symbol) != sec)
7120 	  || S_IS_WEAK (branch_symbol))
7121 	{
7122 	  if (fragP->fr_offset & 3)
7123 	    as_warn (_("Addend to unresolved symbol is not on word boundary."));
7124 	  addend = 0;
7125 	}
7126       else
7127 	{
7128 	  /* Calculate symbol-to-instruction offset.  */
7129 	  branch_target_address = S_GET_VALUE (branch_symbol) + branch_offset;
7130 	  branch_insn_address = fragP->fr_address + fr_where;
7131 	  addend = (branch_target_address - branch_insn_address) >> 1;
7132 	}
7133 
7134       code_size = relax_info->relax_code_size[branch_range_type];
7135       code_seq = relax_info->relax_code_seq[branch_range_type];
7136 
7137       memcpy (fixup_info, relax_info->relax_fixup[branch_range_type],
7138 	      sizeof (fixup_info));
7139 
7140       /* Fill in frag.  */
7141       i = 0;
7142       k = 0;
7143       offset = 0; /* code_seq offset */
7144       buf_offset = 0; /* fr_buffer offset */
7145       while (offset < code_size)
7146 	{
7147 	  insn = code_seq[i];
7148 	  if (insn & 0x80000000) /* 16-bits instruction.  */
7149 	    {
7150 	      insn = (insn >> 16) & 0xFFFF;
7151 	      insn_size = 2;
7152 	    }
7153 	  else /* 32-bits instruction.  */
7154 	    {
7155 	      insn_size = 4;
7156 	    }
7157 
7158 	  nds32_elf_get_set_cond (relax_info, offset, &insn,
7159 				  origin_insn, branch_range_type);
7160 
7161 	  /* Try to convert to 16-bits instruction.  Currently, only the first
7162 	     instruction in pattern can be converted.  EX: bnez sethi ori jr,
7163 	     only bnez can be converted to 16 bit and ori can't.  */
7164 
7165 	  while (fixup_info[k].size != 0
7166 		 && relax_info->relax_fixup[branch_range_type][k].offset < offset)
7167 	    k++;
7168 
7169 	  number_to_chars_bigendian (fr_buffer + buf_offset, insn, insn_size);
7170 	  buf_offset += insn_size;
7171 
7172 	  offset += insn_size;
7173 	  i++;
7174 	}
7175 
7176       /* Set up fixup.  */
7177       exp.X_op = O_symbol;
7178 
7179       for (i = 0; fixup_info[i].size != 0; i++)
7180 	{
7181 	  fixup_size = fixup_info[i].size;
7182 	  pcrel = ((fixup_info[i].ramp & NDS32_PCREL) != 0) ? 1 : 0;
7183 
7184 	  if ((fixup_info[i].ramp & NDS32_CREATE_LABEL) != 0)
7185 	    {
7186 	      /* This is a reverse branch.  */
7187 	      exp.X_add_symbol = symbol_temp_new (sec, fragP->fr_next, 0);
7188 	      exp.X_add_number = 0;
7189 	    }
7190 	  else if ((fixup_info[i].ramp & NDS32_PTR) != 0)
7191 	    {
7192 	      /* This relocation has to point to another instruction.  */
7193 	      branch_size = fr_where + code_size - 4;
7194 	      exp.X_add_symbol = symbol_temp_new (sec, fragP, branch_size);
7195 	      exp.X_add_number = 0;
7196 	    }
7197 	  else if ((fixup_info[i].ramp & NDS32_ABS) != 0)
7198 	    {
7199 	      /* This is a tag relocation.  */
7200 	      exp.X_add_symbol = abs_section_sym;
7201 	      exp.X_add_number = 0;
7202 	    }
7203 	  else if ((fixup_info[i].ramp & NDS32_INSN16) != 0)
7204 	    {
7205 	      if (!enable_16bit)
7206 		continue;
7207 	      /* This is a tag relocation.  */
7208 	      exp.X_add_symbol = abs_section_sym;
7209 	      exp.X_add_number = 0;
7210 	    }
7211 	  else
7212 	    {
7213 	      exp.X_add_symbol = branch_symbol;
7214 	      exp.X_add_number = branch_offset;
7215 	    }
7216 
7217 	  if (fixup_info[i].r_type != 0)
7218 	    {
7219 	      final_r_type = fixup_info[i].r_type;
7220 	      fixP = fix_new_exp (fragP, fr_where + fixup_info[i].offset,
7221 				  fixup_size, &exp, pcrel,
7222 				  final_r_type);
7223 	      fixP->fx_addnumber = fixP->fx_offset;
7224 	    }
7225 	}
7226 
7227       fragP->fr_fix = fr_where + buf_offset;
7228     }
7229 }
7230 
7231 /* tc_frob_file_before_fix  */
7232 
7233 void
nds32_frob_file_before_fix(void)7234 nds32_frob_file_before_fix (void)
7235 {
7236 }
7237 
7238 static bool
nds32_relaxable_section(asection * sec)7239 nds32_relaxable_section (asection *sec)
7240 {
7241   return ((sec->flags & SEC_DEBUGGING) == 0
7242 	  && strcmp (sec->name, ".eh_frame") != 0);
7243 }
7244 
7245 /* TC_FORCE_RELOCATION */
7246 int
nds32_force_relocation(fixS * fix)7247 nds32_force_relocation (fixS * fix)
7248 {
7249   switch (fix->fx_r_type)
7250     {
7251     case BFD_RELOC_NDS32_INSN16:
7252     case BFD_RELOC_NDS32_LABEL:
7253     case BFD_RELOC_NDS32_LONGCALL1:
7254     case BFD_RELOC_NDS32_LONGCALL2:
7255     case BFD_RELOC_NDS32_LONGCALL3:
7256     case BFD_RELOC_NDS32_LONGJUMP1:
7257     case BFD_RELOC_NDS32_LONGJUMP2:
7258     case BFD_RELOC_NDS32_LONGJUMP3:
7259     case BFD_RELOC_NDS32_LOADSTORE:
7260     case BFD_RELOC_NDS32_9_FIXED:
7261     case BFD_RELOC_NDS32_15_FIXED:
7262     case BFD_RELOC_NDS32_17_FIXED:
7263     case BFD_RELOC_NDS32_25_FIXED:
7264     case BFD_RELOC_NDS32_9_PCREL:
7265     case BFD_RELOC_NDS32_15_PCREL:
7266     case BFD_RELOC_NDS32_17_PCREL:
7267     case BFD_RELOC_NDS32_WORD_9_PCREL:
7268     case BFD_RELOC_NDS32_10_UPCREL:
7269     case BFD_RELOC_NDS32_25_PCREL:
7270     case BFD_RELOC_NDS32_MINUEND:
7271     case BFD_RELOC_NDS32_SUBTRAHEND:
7272       return 1;
7273 
7274     case BFD_RELOC_8:
7275     case BFD_RELOC_16:
7276     case BFD_RELOC_32:
7277     case BFD_RELOC_NDS32_DIFF_ULEB128:
7278       /* Linker should handle difference between two symbol.  */
7279       return fix->fx_subsy != NULL
7280 	&& nds32_relaxable_section (S_GET_SEGMENT (fix->fx_addsy));
7281     case BFD_RELOC_64:
7282       if (fix->fx_subsy)
7283 	as_bad ("Double word for difference between two symbols "
7284 		"is not supported across relaxation.");
7285     default:
7286       ;
7287     }
7288 
7289   if (generic_force_reloc (fix))
7290     return 1;
7291 
7292   return fix->fx_pcrel;
7293 }
7294 
7295 /* TC_VALIDATE_FIX_SUB  */
7296 
7297 int
nds32_validate_fix_sub(fixS * fix,segT add_symbol_segment)7298 nds32_validate_fix_sub (fixS *fix, segT add_symbol_segment)
7299 {
7300   segT sub_symbol_segment;
7301 
7302   /* This code is referred from Xtensa.  Check their implementation for
7303      details.  */
7304 
7305   /* Make sure both symbols are in the same segment, and that segment is
7306      "normal" and relaxable.  */
7307   sub_symbol_segment = S_GET_SEGMENT (fix->fx_subsy);
7308   return (sub_symbol_segment == add_symbol_segment
7309 	  && add_symbol_segment != undefined_section);
7310 }
7311 
7312 void
md_number_to_chars(char * buf,valueT val,int n)7313 md_number_to_chars (char *buf, valueT val, int n)
7314 {
7315   if (target_big_endian)
7316     number_to_chars_bigendian (buf, val, n);
7317   else
7318     number_to_chars_littleendian (buf, val, n);
7319 }
7320 
7321 /* This function is called to convert an ASCII string into a floating point
7322    value in format used by the CPU.  */
7323 
7324 const char *
md_atof(int type,char * litP,int * sizeP)7325 md_atof (int type, char *litP, int *sizeP)
7326 {
7327   int i;
7328   int prec;
7329   LITTLENUM_TYPE words[MAX_LITTLENUMS];
7330   char *t;
7331 
7332   switch (type)
7333     {
7334     case 'f':
7335     case 'F':
7336     case 's':
7337     case 'S':
7338       prec = 2;
7339       break;
7340     case 'd':
7341     case 'D':
7342     case 'r':
7343     case 'R':
7344       prec = 4;
7345       break;
7346     default:
7347       *sizeP = 0;
7348       return _("Bad call to md_atof()");
7349     }
7350 
7351   t = atof_ieee (input_line_pointer, type, words);
7352   if (t)
7353     input_line_pointer = t;
7354   *sizeP = prec * sizeof (LITTLENUM_TYPE);
7355 
7356   if (target_big_endian)
7357     {
7358       for (i = 0; i < prec; i++)
7359 	{
7360 	  md_number_to_chars (litP, (valueT) words[i],
7361 			      sizeof (LITTLENUM_TYPE));
7362 	  litP += sizeof (LITTLENUM_TYPE);
7363 	}
7364     }
7365   else
7366     {
7367       for (i = prec - 1; i >= 0; i--)
7368 	{
7369 	  md_number_to_chars (litP, (valueT) words[i],
7370 			      sizeof (LITTLENUM_TYPE));
7371 	  litP += sizeof (LITTLENUM_TYPE);
7372 	}
7373     }
7374 
7375   return 0;
7376 }
7377 
7378 /* md_elf_section_change_hook  */
7379 
7380 void
nds32_elf_section_change_hook(void)7381 nds32_elf_section_change_hook (void)
7382 {
7383 }
7384 
7385 /* md_cleanup  */
7386 
7387 void
nds32_cleanup(void)7388 nds32_cleanup (void)
7389 {
7390 }
7391 
7392 /* This function is used to scan leb128 subtraction expressions,
7393    and insert fixups for them.
7394 
7395       e.g., .leb128  .L1 - .L0
7396 
7397    These expressions are heavily used in debug information or
7398    exception tables.  Because relaxation will change code size,
7399    we must resolve them in link time.  */
7400 
7401 static void
nds32_insert_leb128_fixes(bfd * abfd ATTRIBUTE_UNUSED,asection * sec,void * xxx ATTRIBUTE_UNUSED)7402 nds32_insert_leb128_fixes (bfd *abfd ATTRIBUTE_UNUSED,
7403 			   asection *sec, void *xxx ATTRIBUTE_UNUSED)
7404 {
7405   segment_info_type *seginfo = seg_info (sec);
7406   struct frag *fragP;
7407 
7408   subseg_set (sec, 0);
7409 
7410   for (fragP = seginfo->frchainP->frch_root;
7411        fragP; fragP = fragP->fr_next)
7412     {
7413       expressionS *exp;
7414 
7415       /* Only unsigned leb128 can be handle.  */
7416       if (fragP->fr_type != rs_leb128 || fragP->fr_subtype != 0
7417 	  || fragP->fr_symbol == NULL)
7418 	continue;
7419 
7420       exp = symbol_get_value_expression (fragP->fr_symbol);
7421 
7422       if (exp->X_op != O_subtract)
7423 	continue;
7424 
7425       fix_new_exp (fragP, fragP->fr_fix, 0,
7426 		   exp, 0, BFD_RELOC_NDS32_DIFF_ULEB128);
7427     }
7428 }
7429 
7430 static void
nds32_insert_relax_entry(bfd * abfd ATTRIBUTE_UNUSED,asection * sec,void * xxx ATTRIBUTE_UNUSED)7431 nds32_insert_relax_entry (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
7432 			  void *xxx ATTRIBUTE_UNUSED)
7433 {
7434   segment_info_type *seginfo;
7435   fragS *fragP;
7436   fixS *fixP;
7437   expressionS exp;
7438   fixS *fixp;
7439 
7440   seginfo = seg_info (sec);
7441   if (!seginfo || !symbol_rootP || !subseg_text_p (sec) || sec->size == 0)
7442     return;
7443 
7444   for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
7445     if (!fixp->fx_done)
7446       break;
7447 
7448   if (!fixp && !verbatim && ict_flag == ICT_NONE)
7449     return;
7450 
7451   subseg_change (sec, 0);
7452 
7453   /* Set RELAX_ENTRY flags for linker.  */
7454   fragP = seginfo->frchainP->frch_root;
7455   exp.X_op = O_symbol;
7456   exp.X_add_symbol = abs_section_sym;
7457   exp.X_add_number = 0;
7458   if (!enable_relax_relocs)
7459     exp.X_add_number |= R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG;
7460   else
7461     {
7462       /* These flags are only enabled when global relax is enabled.
7463 	 Maybe we can check DISABLE_RELAX_FLAG at link-time,
7464 	 so we set them anyway.  */
7465       if (verbatim)
7466 	exp.X_add_number |= R_NDS32_RELAX_ENTRY_VERBATIM_FLAG;
7467       if (ict_flag == ICT_SMALL)
7468 	exp.X_add_number |= R_NDS32_RELAX_ENTRY_ICT_SMALL;
7469       else if (ict_flag == ICT_LARGE)
7470 	exp.X_add_number |= R_NDS32_RELAX_ENTRY_ICT_LARGE;
7471     }
7472   if (optimize)
7473     exp.X_add_number |= R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG;
7474   if (optimize_for_space)
7475     exp.X_add_number |= R_NDS32_RELAX_ENTRY_OPTIMIZE_FOR_SPACE_FLAG;
7476 
7477   fixP = fix_new_exp (fragP, 0, 0, &exp, 0, BFD_RELOC_NDS32_RELAX_ENTRY);
7478   fixP->fx_no_overflow = 1;
7479 }
7480 
7481 /* Analysis relax hint and insert suitable relocation pattern.  */
7482 
7483 static void
nds32_elf_analysis_relax_hint(void)7484 nds32_elf_analysis_relax_hint (void)
7485 {
7486   htab_traverse (nds32_hint_hash, 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_end(void)7522 md_end (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 /* Sort relocation by address.
7541 
7542    We didn't use qsort () in stdlib, because quick-sort is not a stable
7543    sorting algorithm.  Relocations at the same address (r_offset) must keep
7544    their relative order.  For example, RELAX_ENTRY must be the very first
7545    relocation entry.
7546 
7547    Currently, this function implements insertion-sort.  */
7548 
7549 static int
compar_relent(const void * lhs,const void * rhs)7550 compar_relent (const void *lhs, const void *rhs)
7551 {
7552   const arelent **l = (const arelent **) lhs;
7553   const arelent **r = (const arelent **) rhs;
7554 
7555   if ((*l)->address > (*r)->address)
7556     return 1;
7557   else if ((*l)->address == (*r)->address)
7558     return 0;
7559   else
7560     return -1;
7561 }
7562 
7563 /* SET_SECTION_RELOCS ()
7564 
7565    Although this macro is originally used to set a relocation for each section,
7566    we use it to sort relocations in the same section by the address of the
7567    relocation.  */
7568 
7569 void
nds32_set_section_relocs(asection * sec ATTRIBUTE_UNUSED,arelent ** relocs,unsigned int n)7570 nds32_set_section_relocs (asection *sec ATTRIBUTE_UNUSED,
7571 			  arelent **relocs, unsigned int n)
7572 {
7573   if (n <= 1)
7574     return;
7575 
7576   nds32_insertion_sort (relocs, n, sizeof (*relocs), compar_relent);
7577 }
7578 
7579 long
nds32_pcrel_from_section(fixS * fixP,segT sec ATTRIBUTE_UNUSED)7580 nds32_pcrel_from_section (fixS *fixP, segT sec ATTRIBUTE_UNUSED)
7581 {
7582   if (fixP->fx_addsy == NULL || !S_IS_DEFINED (fixP->fx_addsy)
7583       || S_IS_EXTERNAL (fixP->fx_addsy) || S_IS_WEAK (fixP->fx_addsy))
7584     {
7585       /* Let linker resolve undefined symbols.  */
7586       return 0;
7587     }
7588 
7589   return fixP->fx_frag->fr_address + fixP->fx_where;
7590 }
7591 
7592 /* md_post_relax_hook ()
7593    Insert relax entry relocation into sections.  */
7594 
7595 void
nds32_post_relax_hook(void)7596 nds32_post_relax_hook (void)
7597 {
7598   bfd_map_over_sections (stdoutput, nds32_insert_relax_entry, NULL);
7599 }
7600 
7601 /* tc_fix_adjustable ()
7602 
7603    Return whether this symbol (fixup) can be replaced with
7604    section symbols.  */
7605 
7606 bool
nds32_fix_adjustable(fixS * fixP)7607 nds32_fix_adjustable (fixS *fixP)
7608 {
7609   switch (fixP->fx_r_type)
7610     {
7611     case BFD_RELOC_NDS32_WORD_9_PCREL:
7612     case BFD_RELOC_NDS32_9_PCREL:
7613     case BFD_RELOC_NDS32_15_PCREL:
7614     case BFD_RELOC_NDS32_17_PCREL:
7615     case BFD_RELOC_NDS32_25_PCREL:
7616     case BFD_RELOC_NDS32_HI20:
7617     case BFD_RELOC_NDS32_LO12S0:
7618     case BFD_RELOC_8:
7619     case BFD_RELOC_16:
7620     case BFD_RELOC_32:
7621     case BFD_RELOC_NDS32_PTR:
7622     case BFD_RELOC_NDS32_LONGCALL4:
7623     case BFD_RELOC_NDS32_LONGCALL5:
7624     case BFD_RELOC_NDS32_LONGCALL6:
7625     case BFD_RELOC_NDS32_LONGJUMP4:
7626     case BFD_RELOC_NDS32_LONGJUMP5:
7627     case BFD_RELOC_NDS32_LONGJUMP6:
7628     case BFD_RELOC_NDS32_LONGJUMP7:
7629       return 1;
7630     default:
7631       return 0;
7632     }
7633 }
7634 
7635 /* elf_tc_final_processing  */
7636 
7637 void
elf_nds32_final_processing(void)7638 elf_nds32_final_processing (void)
7639 {
7640   /* An FPU_COM instruction is found without previous non-FPU_COM
7641      instruction.  */
7642   if (nds32_fpu_com
7643       && !(nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
7644     {
7645       /* Since only FPU_COM instructions are used and no other FPU instructions
7646 	 are used.  The nds32_elf_flags will be decided by the enabled options
7647 	 by command line or default configuration.  */
7648       if (nds32_fpu_dp_ext || nds32_fpu_sp_ext)
7649 	{
7650 	  nds32_elf_flags |= nds32_fpu_dp_ext ? E_NDS32_HAS_FPU_DP_INST : 0;
7651 	  nds32_elf_flags |= nds32_fpu_sp_ext ? E_NDS32_HAS_FPU_INST : 0;
7652 	}
7653       else
7654 	{
7655 	  /* Should never here.  */
7656 	  as_bad (_("Used FPU instructions requires enabling FPU extension"));
7657 	}
7658     }
7659 
7660   if (nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST))
7661     {
7662       /* Single/double FPU has been used, set FPU register config.  */
7663       /* We did not check the actual number of register used.  We may
7664 	 want to do it while assemble.  */
7665       nds32_elf_flags &= ~E_NDS32_FPU_REG_CONF;
7666       nds32_elf_flags |= (nds32_freg << E_NDS32_FPU_REG_CONF_SHIFT);
7667     }
7668 
7669   if (nds32_pic)
7670     nds32_elf_flags |= E_NDS32_HAS_PIC;
7671 
7672   if (nds32_gpr16)
7673     nds32_elf_flags |= E_NDS32_HAS_REDUCED_REGS;
7674 
7675   nds32_elf_flags |= (E_NDS32_ELF_VER_1_4 | nds32_abi);
7676   elf_elfheader (stdoutput)->e_flags |= nds32_elf_flags;
7677 }
7678 
7679 /* Implement md_apply_fix.  Apply the fix-up or transform the fix-up for
7680    later relocation generation.  */
7681 
7682 void
nds32_apply_fix(fixS * fixP,valueT * valP,segT seg ATTRIBUTE_UNUSED)7683 nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
7684 {
7685   char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
7686   bfd_vma value = *valP;
7687 
7688   if (fixP->fx_r_type < BFD_RELOC_UNUSED
7689       && fixP->fx_r_type > BFD_RELOC_NONE
7690       && fixP->fx_r_type != BFD_RELOC_NDS32_DIFF_ULEB128)
7691     {
7692       /* In our old nds32 binutils, it must convert relocations which is
7693 	 generated by CGEN.  However, it does not have to consider this anymore.
7694 	 In current, it only deal with data relocations which enum
7695 	 is smaller than BFD_RELOC_NONE and BFD_RELOC_NDS32_DIFF_ULEB128.
7696 	 It is believed that we can construct a better mechanism to
7697 	 deal with the whole relocation issue in nds32 target
7698 	 without using CGEN.  */
7699       fixP->fx_addnumber = value;
7700       fixP->tc_fix_data = NULL;
7701 
7702       /* Transform specific relocations here for later relocation generation.
7703 	 Tag tls data for linker.  */
7704       switch (fixP->fx_r_type)
7705 	{
7706 	case BFD_RELOC_NDS32_DATA:
7707 	  /* This reloc is obselete, we do not need it so far.  */
7708 	  fixP->fx_done = 1;
7709 	  break;
7710 	case BFD_RELOC_NDS32_TPOFF:
7711 	case BFD_RELOC_NDS32_TLS_LE_HI20:
7712 	case BFD_RELOC_NDS32_TLS_LE_LO12:
7713 	case BFD_RELOC_NDS32_TLS_LE_ADD:
7714 	case BFD_RELOC_NDS32_TLS_LE_LS:
7715 	case BFD_RELOC_NDS32_GOTTPOFF:
7716 	case BFD_RELOC_NDS32_TLS_IE_HI20:
7717 	case BFD_RELOC_NDS32_TLS_IE_LO12S2:
7718 	case BFD_RELOC_NDS32_TLS_DESC_HI20:
7719 	case BFD_RELOC_NDS32_TLS_DESC_LO12:
7720 	case BFD_RELOC_NDS32_TLS_IE_LO12:
7721 	case BFD_RELOC_NDS32_TLS_IEGP_HI20:
7722 	case BFD_RELOC_NDS32_TLS_IEGP_LO12:
7723 	case BFD_RELOC_NDS32_TLS_IEGP_LO12S2:
7724 	  S_SET_THREAD_LOCAL (fixP->fx_addsy);
7725 	  break;
7726 	default:
7727 	  break;
7728 	}
7729       return;
7730     }
7731 
7732   if (fixP->fx_addsy == (symbolS *) NULL)
7733     fixP->fx_done = 1;
7734 
7735   if (fixP->fx_subsy != (symbolS *) NULL)
7736     {
7737       /* HOW DIFF RELOCATION WORKS.
7738 
7739 	 First of all, this relocation is used to calculate the distance
7740 	 between two symbols in the SAME section.  It is used for  jump-
7741 	 table, debug information, exception table, et al.    Therefore,
7742 	 it is a unsigned positive value.   It is NOT used for  general-
7743 	 purpose arithmetic.
7744 
7745 	 Consider this example,  the distance between  .LEND and .LBEGIN
7746 	 is stored at the address of foo.
7747 
7748 	 ---- >8 ---- >8 ---- >8 ---- >8 ----
7749 	  .data
7750 	  foo:
7751 	    .word	.LBEGIN - .LEND
7752 
7753 	  .text
7754 	     [before]
7755 	  .LBEGIN
7756 			 \
7757 	     [between]    distance
7758 			 /
7759 	  .LEND
7760 	     [after]
7761 	 ---- 8< ---- 8< ---- 8< ---- 8< ----
7762 
7763 	 We use a single relocation entry for this expression.
7764 	 * The initial distance value is stored directly in that location
7765 	   specified by r_offset (i.e., foo in this example.)
7766 	 * The begin of the region, i.e., .LBEGIN, is specified by
7767 	   r_info/R_SYM and r_addend, e.g., .text + 0x32.
7768 	 * The end of region, i.e., .LEND, is represented by
7769 	   .LBEGIN + distance instead of .LEND, so we only need
7770 	   a single relocation entry instead of two.
7771 
7772 	 When an instruction is relaxed, we adjust the relocation entry
7773 	 depending on where the instruction locates.    There are three
7774 	 cases, before, after and between the region.
7775 	 * between: Distance value is read from r_offset,  adjusted and
7776 	   written back into r_offset.
7777 	 * before: Only r_addend is adjust.
7778 	 * after: We don't care about it.
7779 
7780 	 Hereby, there are some limitation.
7781 
7782 	 `(.LEND - 1) - .LBEGIN' and `(.LEND - .LBEGIN) - 1'
7783 	 are semantically different, and we cannot handle latter case
7784 	 when relaxation.
7785 
7786 	 The latter expression means subtracting 1 from the distance
7787 	 between .LEND and .LBEGIN.  And the former expression means
7788 	 the distance between (.LEND - 1) and .LBEGIN.
7789 
7790 	 The nuance affects whether to adjust distance value when relax
7791 	 an instruction.  In another words, whether the instruction
7792 	 locates in the region.  Because we use a single relocation entry,
7793 	 there is no field left for .LEND and the subtrahend.
7794 
7795 	 Since GCC-4.5, GCC may produce debug information in such expression
7796 	     .long  .L1-1-.L0
7797 	 in order to describe register clobbering during an function-call.
7798 	     .L0:
7799 		call foo
7800 	     .L1:
7801 
7802 	 Check http://gcc.gnu.org/ml/gcc-patches/2009-06/msg01317.html
7803 	 for details.  */
7804 
7805       value -= S_GET_VALUE (fixP->fx_subsy);
7806       *valP = value;
7807       fixP->fx_subsy = NULL;
7808       fixP->fx_offset -= value;
7809 
7810       switch (fixP->fx_r_type)
7811 	{
7812 	case BFD_RELOC_8:
7813 	  fixP->fx_r_type = BFD_RELOC_NDS32_DIFF8;
7814 	  md_number_to_chars (where, value, 1);
7815 	  break;
7816 	case BFD_RELOC_16:
7817 	  fixP->fx_r_type = BFD_RELOC_NDS32_DIFF16;
7818 	  md_number_to_chars (where, value, 2);
7819 	  break;
7820 	case BFD_RELOC_32:
7821 	  fixP->fx_r_type = BFD_RELOC_NDS32_DIFF32;
7822 	  md_number_to_chars (where, value, 4);
7823 	  break;
7824 	case BFD_RELOC_NDS32_DIFF_ULEB128:
7825 	  /* cvt_frag_to_fill () has called output_leb128 () for us.  */
7826 	  break;
7827 	default:
7828 	  as_bad_where (fixP->fx_file, fixP->fx_line,
7829 			_("expression too complex"));
7830 	  return;
7831 	}
7832     }
7833   else if (fixP->fx_done)
7834     {
7835       /* We're finished with this fixup.  Install it because
7836 	 bfd_install_relocation won't be called to do it.  */
7837       switch (fixP->fx_r_type)
7838 	{
7839 	case BFD_RELOC_8:
7840 	  md_number_to_chars (where, value, 1);
7841 	  break;
7842 	case BFD_RELOC_16:
7843 	  md_number_to_chars (where, value, 2);
7844 	  break;
7845 	case BFD_RELOC_32:
7846 	  md_number_to_chars (where, value, 4);
7847 	  break;
7848 	case BFD_RELOC_64:
7849 	  md_number_to_chars (where, value, 8);
7850 	  break;
7851 	default:
7852 	  as_bad_where (fixP->fx_file, fixP->fx_line,
7853 			_("Internal error: Unknown fixup type %d (`%s')"),
7854 			fixP->fx_r_type,
7855 			bfd_get_reloc_code_name (fixP->fx_r_type));
7856 	  break;
7857 	}
7858     }
7859 }
7860 
7861 /* Implement tc_gen_reloc.  Generate ELF relocation for a fix-up.  */
7862 
7863 arelent *
tc_gen_reloc(asection * section ATTRIBUTE_UNUSED,fixS * fixP)7864 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
7865 {
7866   arelent *reloc;
7867   bfd_reloc_code_real_type code;
7868 
7869   reloc = XNEW (arelent);
7870 
7871   reloc->sym_ptr_ptr = XNEW (asymbol *);
7872   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
7873   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
7874 
7875   code = fixP->fx_r_type;
7876 
7877   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
7878   if (reloc->howto == (reloc_howto_type *) NULL)
7879     {
7880       as_bad_where (fixP->fx_file, fixP->fx_line,
7881 		    _("internal error: can't export reloc type %d (`%s')"),
7882 		    fixP->fx_r_type, bfd_get_reloc_code_name (code));
7883       return NULL;
7884     }
7885 
7886   /* Add relocation handling here.  */
7887 
7888   switch (fixP->fx_r_type)
7889     {
7890     default:
7891       /* In general, addend of a relocation is the offset to the
7892 	 associated symbol.  */
7893       reloc->addend = fixP->fx_offset;
7894       break;
7895 
7896     case BFD_RELOC_NDS32_DATA:
7897       /* Prevent linker from optimizing data in text sections.
7898 	 For example, jump table.  */
7899       reloc->addend = fixP->fx_size;
7900       break;
7901     }
7902 
7903   return reloc;
7904 }
7905 
7906 static struct suffix_name suffix_table[] =
7907 {
7908   {"GOTOFF",	BFD_RELOC_NDS32_GOTOFF},
7909   {"GOT",	BFD_RELOC_NDS32_GOT20},
7910   {"TPOFF",	BFD_RELOC_NDS32_TPOFF},
7911   {"PLT",	BFD_RELOC_NDS32_25_PLTREL},
7912   {"GOTTPOFF",	BFD_RELOC_NDS32_GOTTPOFF},
7913   {"TLSDESC",  BFD_RELOC_NDS32_TLS_DESC},
7914 };
7915 
7916 /* Implement md_parse_name.  */
7917 
7918 int
nds32_parse_name(char const * name,expressionS * exprP,enum expr_mode mode ATTRIBUTE_UNUSED,char * nextcharP ATTRIBUTE_UNUSED)7919 nds32_parse_name (char const *name, expressionS *exprP,
7920 		  enum expr_mode mode ATTRIBUTE_UNUSED,
7921 		  char *nextcharP ATTRIBUTE_UNUSED)
7922 {
7923   segT segment;
7924 
7925   exprP->X_op_symbol = NULL;
7926   exprP->X_md = BFD_RELOC_UNUSED;
7927 
7928   exprP->X_add_symbol = symbol_find_or_make (name);
7929   exprP->X_op = O_symbol;
7930   exprP->X_add_number = 0;
7931 
7932   /* Check the special name if a symbol.  */
7933   segment = S_GET_SEGMENT (exprP->X_add_symbol);
7934   if ((segment != undefined_section) && (*nextcharP != '@'))
7935     return 0;
7936 
7937   if (strcmp (name, GOT_NAME) == 0 && *nextcharP != '@')
7938     {
7939       /* Set for _GOT_OFFSET_TABLE_.  */
7940       exprP->X_md = BFD_RELOC_NDS32_GOTPC20;
7941     }
7942   else if (*nextcharP == '@')
7943     {
7944       size_t i;
7945       char *next;
7946       for (i = 0; i < ARRAY_SIZE (suffix_table); i++)
7947 	{
7948 	  next = input_line_pointer + 1 + strlen (suffix_table[i].suffix);
7949 	  if (strncasecmp (input_line_pointer + 1, suffix_table[i].suffix,
7950 			   strlen (suffix_table[i].suffix)) == 0
7951 	      && !is_part_of_name (*next))
7952 	    {
7953 	      exprP->X_md = suffix_table[i].reloc;
7954 	      *input_line_pointer = *nextcharP;
7955 	      input_line_pointer = next;
7956 	      *nextcharP = *input_line_pointer;
7957 	      *input_line_pointer = '\0';
7958 	      break;
7959 	    }
7960 	}
7961     }
7962 
7963   return 1;
7964 }
7965 
7966 /* Implement tc_regname_to_dw2regnum.  */
7967 
7968 int
tc_nds32_regname_to_dw2regnum(char * regname)7969 tc_nds32_regname_to_dw2regnum (char *regname)
7970 {
7971   struct nds32_keyword *sym = str_hash_find (nds32_gprs_hash, regname);
7972 
7973   if (!sym)
7974     return -1;
7975 
7976   return sym->value;
7977 }
7978 
7979 void
tc_nds32_frame_initial_instructions(void)7980 tc_nds32_frame_initial_instructions (void)
7981 {
7982   /* CIE */
7983   /* Default cfa is register-31/sp.  */
7984   cfi_add_CFA_def_cfa (31, 0);
7985 }
7986