1 /* tc-nds32.c -- Assemble for the nds32
2 Copyright (C) 2012-2018 Free Software Foundation, Inc.
3 Contributed by Andes Technology Corporation.
5 This file is part of GAS, the GNU Assembler.
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)
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.
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
23 #include "safe-ctype.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"
34 #include "struc-symbol.h"
35 #include "opcode/nds32.h"
39 /* GAS definitions. */
41 /* Characters which start a comment. */
42 const char comment_chars
[] = "!";
43 /* Characters which start a comment when they appear at the start of a line. */
44 const char line_comment_chars
[] = "#!";
45 /* Characters which separate lines (null and newline are by default). */
46 const char line_separator_chars
[] = ";";
47 /* Characters which may be used as the exponent character
48 in a floating point number. */
49 const char EXP_CHARS
[] = "eE";
50 /* Characters which may be used to indicate a floating point constant. */
51 const char FLT_CHARS
[] = "dDfF";
53 static int enable_16bit
= 1;
54 /* Save for md_assemble to distinguish if this instruction is
55 expanded from the pseudo instruction. */
56 static bfd_boolean pseudo_opcode
= FALSE
;
57 static struct nds32_relocs_pattern
*relocs_list
= NULL
;
58 /* Save instruction relation to inserting relaxation relocation. */
59 struct nds32_relocs_pattern
66 struct nds32_opcode
*opcode
;
68 struct nds32_relocs_pattern
*next
;
71 /* Suffix name and relocation. */
75 short unsigned int reloc
;
78 static int vec_size
= 0;
79 /* If the assembly code is generated by compiler, it is supposed to have
80 ".flag verbatim" at beginning of the content. We have
81 'nds32_flag' to parse it and set this field to be non-zero. */
82 static int verbatim
= 0;
83 static struct hash_control
*nds32_gprs_hash
;
84 static struct hash_control
*nds32_hint_hash
;
85 #define TLS_REG "$r27"
86 #define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
88 /* Generate relocation for relax or not, and the default is true. */
89 static int enable_relax_relocs
= 1;
90 /* The value will be used in RELAX_ENTRY. */
91 static int enable_relax_ex9
= 0;
92 /* The value will be used in RELAX_ENTRY. */
93 static int enable_relax_ifc
= 0;
94 /* Save option -O for performance. */
95 static int optimize
= 0;
96 /* Save option -Os for code size. */
97 static int optimize_for_space
= 0;
98 /* Flag to save label exist. */
99 static int label_exist
= 0;
100 /* Flag to save state in omit_fp region. */
101 static int in_omit_fp
= 0;
102 extern struct nds32_keyword keyword_gpr
[];
103 /* Tag there is relax relocation having to link. */
104 static bfd_boolean relaxing
= FALSE
;
111 static enum ict_option ict_flag
= ICT_NONE
;
113 static struct hash_control
*nds32_relax_info_hash
;
114 static relax_info_t relax_table
[] =
118 BR_RANGE_S16M
, /* br_range */
119 {{0, 0, 0, FALSE
}}, /* cond_field */
122 INSN_JAL
/* jal label */
123 }, /* BR_RANGE_S256 */
125 INSN_JAL
/* jal label */
126 }, /* BR_RANGE_S16K */
128 INSN_JAL
/* jal label */
129 }, /* BR_RANGE_S64K */
131 INSN_JAL
/* jal label */
132 }, /* BR_RANGE_S16M */
134 INSN_SETHI_TA
, /* sethi $ta, label */
135 INSN_ORI_TA
, /* ori $ta, $ta, label */
137 }, /* BR_RANGE_U4G */
138 }, /* relax_code_seq */
140 {{0, 0, 0, FALSE
}}, /* BR_RANGE_S256 */
141 {{0, 0, 0, FALSE
}}, /* BR_RANGE_S16K */
142 {{0, 0, 0, FALSE
}}, /* BR_RANGE_S64K */
143 {{0, 0, 0, FALSE
}}, /* BR_RANGE_S16M */
144 {{0, 0, 0, FALSE
}} /* BR_RANGE_U4G */
145 }, /* relax_code_condition */
146 {4, 4, 4, 4, 12}, /* relax_code_size */
147 {4, 4, 4, 4, 4}, /* relax_branch_isize */
150 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
152 }, /* BR_RANGE_S256 */
154 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
156 }, /* BR_RANGE_S16K */
158 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
160 }, /* BR_RANGE_S64K */
162 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
164 }, /* BR_RANGE_S16M */
166 {0, 4, 0, BFD_RELOC_NDS32_HI20
},
167 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGCALL4
},
168 {4, 4, NDS32_HINT
| NDS32_FIX
, BFD_RELOC_NDS32_LO12S0_ORI
},
169 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
170 {8, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
171 {8, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
172 {8, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
178 "bltzal", /* opcode */
179 BR_RANGE_S64K
, /* br_range */
181 {0, 20, 0x1F, FALSE
},
186 INSN_BLTZAL
/* bltzal $rt, label */
187 }, /* BR_RANGE_S256 */
189 INSN_BLTZAL
/* bltzal $rt, label */
190 }, /* BR_RANGE_S16K */
192 INSN_BLTZAL
/* bltzal $rt, label */
193 }, /* BR_RANGE_S64K */
195 INSN_BGEZ
, /* bgez $rt, $1 */
196 INSN_JAL
/* jal label */
197 }, /* BR_RANGE_S16M */
199 INSN_BGEZ
, /* bgez $rt, $1 */
200 INSN_SETHI_TA
, /* sethi $ta, label */
201 INSN_ORI_TA
, /* ori $ta, $ta, label */
202 INSN_JRAL_TA
/* jral $ta */
204 }, /* relax_code_seq */
207 {0, 20, 0x1F, FALSE
},
209 }, /* BR_RANGE_S256 */
211 {0, 20, 0x1F, FALSE
},
213 }, /* BR_RANGE_S16K */
215 {0, 20, 0x1F, FALSE
},
217 }, /* BR_RANGE_S64K */
219 {0, 20, 0x1F, FALSE
},
221 }, /* BR_RANGE_S16M */
223 {0, 20, 0x1F, FALSE
},
226 }, /* relax_code_condition */
227 {4, 4, 4, 8, 16}, /* relax_code_size */
228 {4, 4, 4, 4, 4}, /* relax_branch_isize */
231 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
233 }, /* BR_RANGE_S256 */
235 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
237 }, /* BR_RANGE_S16K */
239 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
241 }, /* BR_RANGE_S64K */
243 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
244 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGCALL5
},
245 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
247 }, /* BR_RANGE_S16M */
249 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
250 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGCALL6
},
251 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
252 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
253 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
254 {8, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
255 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
256 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
257 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
263 "bgezal", /* opcode */
264 BR_RANGE_S64K
, /* br_range */
266 {0, 20, 0x1F, FALSE
},
271 INSN_BGEZAL
/* bgezal $rt, label */
272 }, /* BR_RANGE_S256 */
274 INSN_BGEZAL
/* bgezal $rt, label */
275 }, /* BR_RANGE_S16K */
277 INSN_BGEZAL
/* bgezal $rt, label */
278 }, /* BR_RANGE_S64K */
280 INSN_BLTZ
, /* bltz $rt, $1 */
281 INSN_JAL
/* jal label */
282 }, /* BR_RANGE_S16M */
284 INSN_BLTZ
, /* bltz $rt, $1 */
285 INSN_SETHI_TA
, /* sethi $ta, label */
286 INSN_ORI_TA
, /* ori $ta, $ta, label */
287 INSN_JRAL_TA
/* jral $ta */
289 }, /* relax_code_seq */
292 {0, 20, 0x1F, FALSE
},
294 }, /* BR_RANGE_S256 */
296 {0, 20, 0x1F, FALSE
},
298 }, /* BR_RANGE_S16K */
300 {0, 20, 0x1F, FALSE
},
302 }, /* BR_RANGE_S64K */
304 {0, 20, 0x1F, FALSE
},
306 }, /* BR_RANGE_S16M */
308 {0, 20, 0x1F, FALSE
},
311 }, /* relax_code_condition */
312 {4, 4, 4, 8, 16}, /* relax_code_size */
313 {4, 4, 4, 4, 4}, /* relax_branch_isize */
316 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
318 }, /* BR_RANGE_S256 */
320 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
322 }, /* BR_RANGE_S16K */
324 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
326 }, /* BR_RANGE_S64K */
328 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
329 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGCALL5
},
330 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
332 }, /* BR_RANGE_S16M */
334 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
335 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGCALL6
},
336 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
337 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
338 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
339 {8, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
340 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
341 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
342 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
349 BR_RANGE_S16M
, /* br_range */
350 {{0, 0, 0, FALSE
}}, /* cond_field */
353 (INSN_J8
<< 16) /* j8 label */
354 }, /* BR_RANGE_S256 */
357 }, /* BR_RANGE_S16K */
360 }, /* BR_RANGE_S64K */
363 }, /* BR_RANGE_S16M */
365 INSN_SETHI_TA
, /* sethi $ta, label */
366 INSN_ORI_TA
, /* ori $ta, $ta, label */
367 INSN_JR_TA
/* jr $ta */
368 }, /* BR_RANGE_U4G */
369 }, /* relax_code_seq */
371 {{0, 0, 0, FALSE
}}, /* BR_RANGE_S256 */
372 {{0, 0, 0, FALSE
}}, /* BR_RANGE_S16K */
373 {{0, 0, 0, FALSE
}}, /* BR_RANGE_S64K */
374 {{0, 0, 0, FALSE
}}, /* BR_RANGE_S16M */
375 {{0, 0, 0, FALSE
}} /* BR_RANGE_U4G */
376 }, /* relax_code_condition */
377 {2, 4, 4, 4, 12}, /* relax_code_size */
378 {2, 4, 4, 4, 4}, /* relax_branch_isize */
381 {0, 2, NDS32_PCREL
, BFD_RELOC_NDS32_9_PCREL
},
383 }, /* BR_RANGE_S256 */
385 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
387 }, /* BR_RANGE_S16K */
389 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
391 }, /* BR_RANGE_S64K */
393 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
395 }, /* BR_RANGE_S16M */
397 {0, 4, 0, BFD_RELOC_NDS32_HI20
},
398 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP4
},
399 {4, 4, NDS32_HINT
| NDS32_FIX
, BFD_RELOC_NDS32_LO12S0_ORI
},
400 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
401 {8, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
402 {8, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
403 {8, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
410 BR_RANGE_S256
, /* br_range */
411 {{0, 0, 0, FALSE
}}, /* cond_field */
414 (INSN_J8
<< 16) /* j8 label */
415 }, /* BR_RANGE_S256 */
418 }, /* BR_RANGE_S16K */
421 }, /* BR_RANGE_S64K */
424 }, /* BR_RANGE_S16M */
426 INSN_SETHI_TA
, /* sethi $ta, label */
427 INSN_ORI_TA
, /* ori $ta, $ta, label */
428 INSN_JR_TA
/* jr $ta */
429 }, /* BR_RANGE_U4G */
430 }, /* relax_code_seq */
432 {{0, 0, 0, FALSE
}}, /* BR_RANGE_S256 */
433 {{0, 0, 0, FALSE
}}, /* BR_RANGE_S16K */
434 {{0, 0, 0, FALSE
}}, /* BR_RANGE_S64K */
435 {{0, 0, 0, FALSE
}}, /* BR_RANGE_S16M */
436 {{0, 0, 0, FALSE
}} /* BR_RANGE_U4G */
437 }, /* relax_code_condition */
438 {2, 4, 4, 4, 12}, /* relax_code_size */
439 {2, 4, 4, 4, 4}, /* relax_branch_isize */
442 {0, 2, NDS32_PCREL
, BFD_RELOC_NDS32_9_PCREL
},
444 }, /* BR_RANGE_S256 */
446 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
448 }, /* BR_RANGE_S16K */
450 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
452 }, /* BR_RANGE_S64K */
454 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
456 }, /* BR_RANGE_S16M */
458 {0, 4, 0, BFD_RELOC_NDS32_HI20
},
459 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP4
},
460 {4, 4, NDS32_HINT
| NDS32_FIX
, BFD_RELOC_NDS32_LO12S0_ORI
},
461 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
462 {8, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
463 {8, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
464 {8, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
471 BR_RANGE_S64K
, /* br_range */
473 {0, 20, 0x1F, FALSE
},
478 INSN_BEQZ
/* beqz $rt, label */
479 }, /* BR_RANGE_S256 */
481 INSN_BEQZ
/* beqz $rt, label */
482 }, /* BR_RANGE_S16K */
484 INSN_BEQZ
/* beqz $rt, label */
485 }, /* BR_RANGE_S64K */
487 INSN_BNEZ
, /* bnez $rt, $1 */
489 }, /* BR_RANGE_S16M */
491 INSN_BNEZ
, /* bnez $rt, $1 */
492 INSN_SETHI_TA
, /* sethi $ta, label */
493 INSN_ORI_TA
, /* ori $ta, $ta, label */
494 INSN_JR_TA
/* jr $ta */
496 }, /* relax_code_seq */
499 {0, 20, 0x1F, FALSE
},
501 }, /* BR_RANGE_S256 */
503 {0, 20, 0x1F, FALSE
},
505 }, /* BR_RANGE_S16K */
507 {0, 20, 0x1F, FALSE
},
509 }, /* BR_RANGE_S64K */
511 {0, 20, 0x1F, FALSE
},
513 }, /* BR_RANGE_S16M */
515 {0, 20, 0x1F, FALSE
},
518 }, /* relax_code_condition */
519 {4, 4, 4, 8, 16}, /* relax_code_size */
520 {4, 4, 4, 4, 4}, /* relax_branch_isize */
523 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
524 {0, 4, NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
526 }, /* BR_RANGE_S256 */
528 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
530 }, /* BR_RANGE_S16K */
532 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
534 }, /* BR_RANGE_S64K */
536 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
537 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
538 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
539 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
540 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
542 }, /* BR_RANGE_S16M */
544 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
545 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
546 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
547 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
548 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
549 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
550 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
551 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
552 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
553 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
560 BR_RANGE_S64K
, /* br_range */
562 {0, 20, 0x1F, FALSE
},
567 INSN_BGEZ
/* bgez $rt, label */
568 }, /* BR_RANGE_S256 */
570 INSN_BGEZ
/* bgez $rt, label */
571 }, /* BR_RANGE_S16K */
573 INSN_BGEZ
/* bgez $rt, label */
574 }, /* BR_RANGE_S64K */
576 INSN_BLTZ
, /* bltz $rt, $1 */
578 }, /* BR_RANGE_S16M */
580 INSN_BLTZ
, /* bltz $rt, $1 */
581 INSN_SETHI_TA
, /* sethi $ta, label */
582 INSN_ORI_TA
, /* ori $ta, $ta, label */
583 INSN_JR_TA
/* jr $ta */
585 }, /* relax_code_seq */
588 {0, 20, 0x1F, FALSE
},
590 }, /* BR_RANGE_S256 */
592 {0, 20, 0x1F, FALSE
},
594 }, /* BR_RANGE_S16K */
596 {0, 20, 0x1F, FALSE
},
598 }, /* BR_RANGE_S64K */
600 {0, 20, 0x1F, FALSE
},
602 }, /* BR_RANGE_S16M */
604 {0, 20, 0x1F, FALSE
},
607 }, /* relax_code_condition */
608 {4, 4, 4, 8, 16}, /* relax_code_size */
609 {4, 4, 4, 4, 4}, /* relax_branch_isize */
612 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
614 }, /* BR_RANGE_S256 */
616 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
618 }, /* BR_RANGE_S16K */
620 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
622 }, /* BR_RANGE_S64K */
624 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
625 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
626 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
628 }, /* BR_RANGE_S16M */
630 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
631 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
632 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
633 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
634 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
635 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
636 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
637 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
638 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
645 BR_RANGE_S64K
, /* br_range */
647 {0, 20, 0x1F, FALSE
},
652 INSN_BNEZ
/* bnez $rt, label */
653 }, /* BR_RANGE_S256 */
655 INSN_BNEZ
/* bnez $rt, label */
656 }, /* BR_RANGE_S16K */
658 INSN_BNEZ
/* bnez $rt, label */
659 }, /* BR_RANGE_S64K */
661 INSN_BEQZ
, /* beqz $rt, $1 */
663 }, /* BR_RANGE_S16M */
665 INSN_BEQZ
, /* beqz $rt, $1 */
666 INSN_SETHI_TA
, /* sethi $ta, label */
667 INSN_ORI_TA
, /* ori $ta, $ta, label */
668 INSN_JR_TA
/* jr $ta */
670 }, /* relax_code_seq */
673 {0, 20, 0x1F, FALSE
},
675 }, /* BR_RANGE_S256 */
677 {0, 20, 0x1F, FALSE
},
679 }, /* BR_RANGE_S16K */
681 {0, 20, 0x1F, FALSE
},
683 }, /* BR_RANGE_S64K */
685 {0, 20, 0x1F, FALSE
},
687 }, /* BR_RANGE_S16M */
689 {0, 20, 0x1F, FALSE
},
692 }, /* relax_code_condition */
693 {4, 4, 4, 8, 16}, /* relax_code_size */
694 {4, 4, 4, 4, 4}, /* relax_branch_isize */
697 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
698 {0, 4, NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
700 }, /* BR_RANGE_S256 */
702 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
704 }, /* BR_RANGE_S16K */
706 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
708 }, /* BR_RANGE_S64K */
710 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
711 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
712 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
713 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
714 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
716 }, /* BR_RANGE_S16M */
718 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
719 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
720 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
721 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
722 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
723 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
724 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
725 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
726 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
727 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
734 BR_RANGE_S64K
, /* br_range */
736 {0, 20, 0x1F, FALSE
},
741 INSN_BGTZ
/* bgtz $rt, label */
742 }, /* BR_RANGE_S256 */
744 INSN_BGTZ
/* bgtz $rt, label */
745 }, /* BR_RANGE_S16K */
747 INSN_BGTZ
/* bgtz $rt, label */
748 }, /* BR_RANGE_S64K */
750 INSN_BLEZ
, /* blez $rt, $1 */
752 }, /* BR_RANGE_S16M */
754 INSN_BLEZ
, /* blez $rt, $1 */
755 INSN_SETHI_TA
, /* sethi $ta, label */
756 INSN_ORI_TA
, /* ori $ta, $ta, label */
757 INSN_JR_TA
/* jr $ta */
759 }, /* relax_code_seq */
762 {0, 20, 0x1F, FALSE
},
764 }, /* BR_RANGE_S256 */
766 {0, 20, 0x1F, FALSE
},
768 }, /* BR_RANGE_S16K */
770 {0, 20, 0x1F, FALSE
},
772 }, /* BR_RANGE_S64K */
774 {0, 20, 0x1F, FALSE
},
776 }, /* BR_RANGE_S16M */
778 {0, 20, 0x1F, FALSE
},
781 }, /* relax_code_condition */
782 {4, 4, 4, 8, 16}, /* relax_code_size */
783 {4, 4, 4, 4, 4}, /* relax_branch_isize */
786 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
788 }, /* BR_RANGE_S256 */
790 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
792 }, /* BR_RANGE_S16K */
794 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
796 }, /* BR_RANGE_S64K */
798 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
799 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
800 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
802 }, /* BR_RANGE_S16M */
804 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
805 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
806 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
807 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
808 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
809 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
810 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
811 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
812 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
819 BR_RANGE_S64K
, /* br_range */
821 {0, 20, 0x1F, FALSE
},
826 INSN_BLEZ
/* blez $rt, label */
827 }, /* BR_RANGE_S256 */
829 INSN_BLEZ
/* blez $rt, label */
830 }, /* BR_RANGE_S16K */
832 INSN_BLEZ
/* blez $rt, label */
833 }, /* BR_RANGE_S64K */
835 INSN_BGTZ
, /* bgtz $rt, $1 */
837 }, /* BR_RANGE_S16M */
839 INSN_BGTZ
, /* bgtz $rt, $1 */
840 INSN_SETHI_TA
, /* sethi $ta, label */
841 INSN_ORI_TA
, /* ori $ta, $ta, label */
842 INSN_JR_TA
/* jr $ta */
844 }, /* relax_code_seq */
847 {0, 20, 0x1F, FALSE
},
849 }, /* BR_RANGE_S256 */
851 {0, 20, 0x1F, FALSE
},
853 }, /* BR_RANGE_S16K */
855 {0, 20, 0x1F, FALSE
},
857 }, /* BR_RANGE_S64K */
859 {0, 20, 0x1F, FALSE
},
861 }, /* BR_RANGE_S16M */
863 {0, 20, 0x1F, FALSE
},
866 }, /* relax_code_condition */
867 {4, 4, 4, 8, 16}, /* relax_code_size */
868 {4, 4, 4, 4, 4}, /* relax_branch_isize */
871 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
873 }, /* BR_RANGE_S256 */
875 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
877 }, /* BR_RANGE_S16K */
879 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
881 }, /* BR_RANGE_S64K */
883 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
884 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
885 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
887 }, /* BR_RANGE_S16M */
889 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
890 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
891 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
892 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
893 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
894 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
895 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
896 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
897 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
904 BR_RANGE_S64K
, /* br_range */
906 {0, 20, 0x1F, FALSE
},
911 INSN_BLTZ
/* bltz $rt, label */
912 }, /* BR_RANGE_S256 */
914 INSN_BLTZ
/* bltz $rt, label */
915 }, /* BR_RANGE_S16K */
917 INSN_BLTZ
/* bltz $rt, label */
918 }, /* BR_RANGE_S64K */
920 INSN_BGEZ
, /* bgez $rt, $1 */
922 }, /* BR_RANGE_S16M */
924 INSN_BGEZ
, /* bgez $rt, $1 */
925 INSN_SETHI_TA
, /* sethi $ta, label */
926 INSN_ORI_TA
, /* ori $ta, $ta, label */
927 INSN_JR_TA
/* jr $ta */
929 }, /* relax_code_seq */
932 {0, 20, 0x1F, FALSE
},
934 }, /* BR_RANGE_S256 */
936 {0, 20, 0x1F, FALSE
},
938 }, /* BR_RANGE_S16K */
940 {0, 20, 0x1F, FALSE
},
942 }, /* BR_RANGE_S64K */
944 {0, 20, 0x1F, FALSE
},
946 }, /* BR_RANGE_S16M */
948 {0, 20, 0x1F, FALSE
},
951 }, /* relax_code_condition */
952 {4, 4, 4, 8, 16}, /* relax_code_size */
953 {4, 4, 4, 4, 4}, /* relax_branch_isize */
956 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
958 }, /* BR_RANGE_S256 */
960 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
962 }, /* BR_RANGE_S16K */
964 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
966 }, /* BR_RANGE_S64K */
968 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
969 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
970 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
972 }, /* BR_RANGE_S16M */
974 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
975 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
976 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
977 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
978 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
979 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
980 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
981 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
982 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
989 BR_RANGE_S16K
, /* br_range */
991 {0, 20, 0x1F, FALSE
},
992 {0, 15, 0x1F, FALSE
},
997 INSN_BEQ
/* beq $rt, $ra, label */
998 }, /* BR_RANGE_S256 */
1000 INSN_BEQ
/* beq $rt, $ra, label */
1001 }, /* BR_RANGE_S16K */
1003 INSN_BNE
, /* bne $rt, $ra, $1 */
1004 INSN_J
/* j label */
1005 }, /* BR_RANGE_S64K */
1007 INSN_BNE
, /* bne $rt, $ra, $1 */
1008 INSN_J
/* j label */
1009 }, /* BR_RANGE_S16M */
1011 INSN_BNE
, /* bne $rt, $ra, $1 */
1012 INSN_SETHI_TA
, /* sethi $ta, label */
1013 INSN_ORI_TA
, /* ori $ta, $ta, label */
1014 INSN_JR_TA
/* jr $ta */
1015 } /* BR_RANGE_U4G */
1016 }, /* relax_code_seq */
1019 {0, 20, 0x1F, FALSE
},
1020 {0, 15, 0x1F, FALSE
},
1022 }, /* BR_RANGE_S256 */
1024 {0, 20, 0x1F, FALSE
},
1025 {0, 15, 0x1F, FALSE
},
1027 }, /* BR_RANGE_S16K */
1029 {0, 20, 0x1F, FALSE
},
1030 {0, 15, 0x1F, FALSE
},
1032 }, /* BR_RANGE_S64K */
1034 {0, 20, 0x1F, FALSE
},
1035 {0, 15, 0x1F, FALSE
},
1037 }, /* BR_RANGE_S16M */
1039 {0, 20, 0x1F, FALSE
},
1040 {0, 15, 0x1F, FALSE
},
1042 } /* BR_RANGE_U4G */
1043 }, /* relax_code_condition */
1044 {4, 4, 8, 8, 16}, /* relax_code_size */
1045 {4, 4, 4, 4, 4}, /* relax_branch_isize */
1048 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1049 {0, 4, NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
1051 }, /* BR_RANGE_S256 */
1053 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1055 }, /* BR_RANGE_S16K */
1057 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1058 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1059 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1060 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1061 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1063 }, /* BR_RANGE_S64K */
1065 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1066 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1067 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1068 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1069 {4, 4, NDS32_ABS
, BFD_RELOC_NDS32_EMPTY
},
1070 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1072 }, /* BR_RANGE_S16M */
1074 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1075 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1076 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
1077 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
1078 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1079 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
1080 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1081 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
1082 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
1083 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1085 } /* BR_RANGE_U4G */
1090 BR_RANGE_S16K
, /* br_range */
1092 {0, 20, 0x1F, FALSE
},
1093 {0, 15, 0x1F, FALSE
},
1098 INSN_BNE
/* bne $rt, $ra, label */
1099 }, /* BR_RANGE_S256 */
1101 INSN_BNE
/* bne $rt, $ra, label */
1102 }, /* BR_RANGE_S16K */
1104 INSN_BEQ
, /* beq $rt, $ra, $1 */
1105 INSN_J
/* j label */
1106 }, /* BR_RANGE_S64K */
1108 INSN_BEQ
, /* beq $rt, $ra, $1 */
1109 INSN_J
/* j label */
1110 }, /* BR_RANGE_S16M */
1112 INSN_BEQ
, /* beq $rt, $ra, $1 */
1113 INSN_SETHI_TA
, /* sethi $ta, label */
1114 INSN_ORI_TA
, /* ori $ta, $ta, label */
1115 INSN_JR_TA
/* jr $ta */
1116 } /* BR_RANGE_U4G */
1117 }, /* relax_code_seq */
1120 {0, 20, 0x1F, FALSE
},
1121 {0, 15, 0x1F, FALSE
},
1123 }, /* BR_RANGE_S256 */
1125 {0, 20, 0x1F, FALSE
},
1126 {0, 15, 0x1F, FALSE
},
1128 }, /* BR_RANGE_S16K */
1130 {0, 20, 0x1F, FALSE
},
1131 {0, 15, 0x1F, FALSE
},
1133 }, /* BR_RANGE_S64K */
1135 {0, 20, 0x1F, FALSE
},
1136 {0, 15, 0x1F, FALSE
},
1138 }, /* BR_RANGE_S16M */
1140 {0, 20, 0x1F, FALSE
},
1141 {0, 15, 0x1F, FALSE
},
1143 } /* BR_RANGE_U4G */
1144 }, /* relax_code_condition */
1145 {4, 4, 8, 8, 16}, /* relax_code_size */
1146 {4, 4, 4, 4, 4}, /* relax_branch_isize */
1149 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1150 {0, 4, NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
1152 }, /* BR_RANGE_S256 */
1154 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1156 }, /* BR_RANGE_S16K */
1158 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1159 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1160 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1161 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1162 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1164 }, /* BR_RANGE_S64K */
1166 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1167 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1168 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1169 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1170 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1172 }, /* BR_RANGE_S16M */
1174 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1175 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1176 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
1177 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
1178 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1179 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
1180 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1181 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
1182 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
1183 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1185 } /* BR_RANGE_U4G */
1189 "beqz38", /* opcode */
1190 BR_RANGE_S256
, /* br_range */
1197 INSN_BEQZ38
<< 16 /* beqz $rt, label */
1198 }, /* BR_RANGE_S256 */
1200 INSN_BEQZ
/* beqz $rt, label */
1201 }, /* BR_RANGE_S16K */
1203 INSN_BEQZ
/* beqz $rt, label */
1204 }, /* BR_RANGE_S64K */
1206 INSN_BNEZ
, /* bnez $rt, $1 */
1207 INSN_J
/* j label */
1208 }, /* BR_RANGE_S16M */
1210 INSN_BNEZ
, /* bnez $rt, $1 */
1211 INSN_SETHI_TA
, /* sethi $ta, label */
1212 INSN_ORI_TA
, /* ori $ta, $ta, label */
1213 INSN_JR_TA
/* jr $ta */
1214 } /* BR_RANGE_U4G */
1215 }, /* relax_code_seq */
1220 }, /* BR_RANGE_S256 */
1222 {0, 20, 0x1F, FALSE
},
1224 }, /* BR_RANGE_S16K */
1226 {0, 20, 0x1F, FALSE
},
1228 }, /* BR_RANGE_S64K */
1230 {0, 20, 0x1F, FALSE
},
1232 }, /* BR_RANGE_S16M */
1234 {0, 20, 0x1F, FALSE
},
1236 } /* BR_RANGE_U4G */
1237 }, /* relax_code_condition */
1238 {2, 4, 4, 8, 16}, /* relax_code_size */
1239 {2, 4, 4, 4, 4}, /* relax_branch_isize */
1242 {0, 2, NDS32_PCREL
, BFD_RELOC_NDS32_9_PCREL
},
1244 }, /* BR_RANGE_S256 */
1246 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1248 }, /* BR_RANGE_S16K */
1250 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1252 }, /* BR_RANGE_S64K */
1254 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1255 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1256 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1257 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1258 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1260 }, /* BR_RANGE_S16M */
1262 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1263 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1264 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
1265 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
1266 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1267 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
1268 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1269 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
1270 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
1271 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1273 } /* BR_RANGE_U4G */
1277 "bnez38", /* opcode */
1278 BR_RANGE_S256
, /* br_range */
1285 INSN_BNEZ38
<< 16 /* bnez $rt, label */
1286 }, /* BR_RANGE_S256 */
1288 INSN_BNEZ
/* bnez $rt, label */
1289 }, /* BR_RANGE_S16K */
1291 INSN_BNEZ
/* bnez $rt, label */
1292 }, /* BR_RANGE_S64K */
1294 INSN_BEQZ
, /* beqz $rt, $1 */
1295 INSN_J
/* j label */
1296 }, /* BR_RANGE_S16M */
1298 INSN_BEQZ
, /* beqz $rt, $1 */
1299 INSN_SETHI_TA
, /* sethi $ta, label */
1300 INSN_ORI_TA
, /* ori $ta, $ta, label */
1301 INSN_JR_TA
/* jr $ta */
1302 } /* BR_RANGE_U4G */
1303 }, /* relax_code_seq */
1308 }, /* BR_RANGE_S256 */
1310 {0, 20, 0x1F, FALSE
},
1312 }, /* BR_RANGE_S16K */
1314 {0, 20, 0x1F, FALSE
},
1316 }, /* BR_RANGE_S64K */
1318 {0, 20, 0x1F, FALSE
},
1320 }, /* BR_RANGE_S16M */
1322 {0, 20, 0x1F, FALSE
},
1324 } /* BR_RANGE_U4G */
1325 }, /* relax_code_condition */
1326 {2, 4, 4, 8, 16}, /* relax_code_size */
1327 {2, 4, 4, 4, 4}, /* relax_branch_isize */
1330 {0, 2, NDS32_PCREL
, BFD_RELOC_NDS32_9_PCREL
},
1332 }, /* BR_RANGE_S256 */
1334 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1336 }, /* BR_RANGE_S16K */
1338 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1340 }, /* BR_RANGE_S64K */
1342 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1343 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1344 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1345 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1346 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1348 }, /* BR_RANGE_S16M */
1350 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1351 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1352 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
1353 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
1354 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1355 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
1356 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1357 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
1358 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
1359 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1361 } /* BR_RANGE_U4G */
1365 "beqzs8", /* opcode */
1366 BR_RANGE_S256
, /* br_range */
1367 {{0, 0, 0, FALSE
}}, /* cond_field */
1370 INSN_BEQZS8
<< 16 /* beqz $r15, label */
1371 }, /* BR_RANGE_S256 */
1373 INSN_BEQZ_TA
/* bnez $rt, label */
1374 }, /* BR_RANGE_S16K */
1376 INSN_BEQZ_TA
/* bnez $rt, label */
1377 }, /* BR_RANGE_S64K */
1379 INSN_BNEZ_TA
, /* bnez $r15, $1 */
1380 INSN_J
/* j label */
1381 }, /* BR_RANGE_S16M */
1383 INSN_BNEZ_TA
, /* bnez $r15, $1 */
1384 INSN_SETHI_TA
, /* sethi $ta, label */
1385 INSN_ORI_TA
, /* ori $ta, $ta, label */
1386 INSN_JR_TA
/* jr $ta */
1387 } /* BR_RANGE_U4G */
1388 }, /* relax_code_seq */
1390 {{0, 0, 0, FALSE
}}, /* BR_RANGE_S256 */
1391 {{0, 0, 0, FALSE
}}, /* BR_RANGE_S16K */
1392 {{0, 0, 0, FALSE
}}, /* BR_RANGE_S64K */
1393 {{0, 0, 0, FALSE
}}, /* BR_RANGE_S16M */
1394 {{0, 0, 0, FALSE
}} /* BR_RANGE_U4G */
1395 }, /* relax_code_condition */
1396 {2, 4, 4, 8, 16}, /* relax_code_size */
1397 {2, 4, 4, 4, 4}, /* relax_branch_isize */
1400 {0, 2, NDS32_PCREL
, BFD_RELOC_NDS32_9_PCREL
},
1402 }, /* BR_RANGE_S256 */
1404 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1406 }, /* BR_RANGE_S16K */
1408 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1410 }, /* BR_RANGE_S64K */
1412 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1413 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1414 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1415 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1416 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1418 }, /* BR_RANGE_S16M */
1420 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1421 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1422 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
1423 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
1424 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1425 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
1426 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1427 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
1428 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
1429 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1431 } /* BR_RANGE_U4G */
1435 "bnezs8", /* opcode */
1436 BR_RANGE_S256
, /* br_range */
1437 {{0, 0, 0, FALSE
}}, /* cond_field */
1440 INSN_BNEZS8
<< 16 /* bnez $r15, label */
1441 }, /* BR_RANGE_S256 */
1443 INSN_BNEZ_TA
/* bnez $r15, label */
1444 }, /* BR_RANGE_S16K */
1446 INSN_BNEZ_TA
/* bnez $r15, label */
1447 }, /* BR_RANGE_S64K */
1449 INSN_BEQZ_TA
, /* beqz $r15, $1 */
1450 INSN_J
/* j label */
1451 }, /* BR_RANGE_S16M */
1453 INSN_BEQZ_TA
, /* beqz $r15, $1 */
1454 INSN_SETHI_TA
, /* sethi $ta, label */
1455 INSN_ORI_TA
, /* ori $ta, $ta, label */
1456 INSN_JR_TA
/* jr $ta */
1457 } /* BR_RANGE_U4G */
1458 }, /* relax_code_seq */
1460 {{0, 0, 0, FALSE
}}, /* BR_RANGE_S256 */
1461 {{0, 0, 0, FALSE
}}, /* BR_RANGE_S16K */
1462 {{0, 0, 0, FALSE
}}, /* BR_RANGE_S64K */
1463 {{0, 0, 0, FALSE
}}, /* BR_RANGE_S16M */
1464 {{0, 0, 0, FALSE
}} /* BR_RANGE_U4G */
1465 }, /* relax_code_condition */
1466 {2, 4, 4, 8, 16}, /* relax_code_size */
1467 {2, 4, 4, 4, 4}, /* relax_branch_isize */
1470 {0, 2, NDS32_PCREL
, BFD_RELOC_NDS32_9_PCREL
},
1472 }, /* BR_RANGE_S256 */
1474 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1476 }, /* BR_RANGE_S16K */
1478 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1480 }, /* BR_RANGE_S64K */
1482 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1483 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1484 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1485 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1486 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1488 }, /* BR_RANGE_S16M */
1490 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1491 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1492 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
1493 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
1494 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1495 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
1496 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1497 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
1498 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
1499 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1501 } /* BR_RANGE_U4G */
1505 "bnes38", /* opcode */
1506 BR_RANGE_S256
, /* br_range */
1513 INSN_BNES38
<< 16 /* bne $rt, $R5, label */
1514 }, /* BR_RANGE_S256 */
1516 INSN_BNE_R5
/* bne $rt, $R5, label */
1517 }, /* BR_RANGE_S16K */
1519 INSN_BEQ_R5
, /* beq $rt, $R5, $1 */
1520 INSN_J
/* j label */
1521 }, /* BR_RANGE_S64K */
1523 INSN_BEQ_R5
, /* beq $rt, $R5, $1 */
1524 INSN_J
/* j label */
1525 }, /* BR_RANGE_S16M */
1527 INSN_BEQ_R5
, /* beq $rt, $R5, $1 */
1528 INSN_SETHI_TA
, /* sethi $ta, label */
1529 INSN_ORI_TA
, /* ori $ta, $ta, label */
1530 INSN_JR_TA
/* jr $ta */
1531 } /* BR_RANGE_U4G */
1532 }, /* relax_code_seq */
1537 }, /* BR_RANGE_S256 */
1539 {0, 20, 0x1F, FALSE
},
1541 }, /* BR_RANGE_S16K */
1543 {0, 20, 0x1F, FALSE
},
1545 }, /* BR_RANGE_S64K */
1547 {0, 20, 0x1F, FALSE
},
1549 }, /* BR_RANGE_S16M */
1551 {0, 20, 0x1F, FALSE
},
1553 } /* BR_RANGE_U4G */
1554 }, /* relax_code_condition */
1555 {2, 4, 8, 8, 16}, /* relax_code_size */
1556 {2, 4, 4, 4, 4}, /* relax_branch_isize */
1559 {0, 2, NDS32_PCREL
, BFD_RELOC_NDS32_9_PCREL
},
1561 }, /* BR_RANGE_S256 */
1563 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1565 }, /* BR_RANGE_S16K */
1567 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1568 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1569 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1570 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1571 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1573 }, /* BR_RANGE_S64K */
1575 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1576 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1577 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1578 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1579 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1581 }, /* BR_RANGE_S16M */
1583 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1584 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1585 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
1586 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
1587 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1588 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
1589 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1590 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
1591 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
1592 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1594 } /* BR_RANGE_U4G */
1598 "beqs38", /* opcode */
1599 BR_RANGE_S256
, /* br_range */
1606 INSN_BEQS38
<< 16 /* beq $rt, $R5, label */
1607 }, /* BR_RANGE_S256 */
1609 INSN_BEQ_R5
/* beq $rt, $R5, label */
1610 }, /* BR_RANGE_S16K */
1612 INSN_BNE_R5
, /* bne $rt, $R5, $1 */
1613 INSN_J
/* j label */
1614 }, /* BR_RANGE_S64K */
1616 INSN_BNE_R5
, /* bne $rt, $R5, $1 */
1617 INSN_J
/* j label */
1618 }, /* BR_RANGE_S16M */
1620 INSN_BNE_R5
, /* bne $rt, $R5, $1 */
1621 INSN_SETHI_TA
, /* sethi $ta, label */
1622 INSN_ORI_TA
, /* ori $ta, $ta, label */
1623 INSN_JR_TA
/* jr $ta */
1624 } /* BR_RANGE_U4G */
1625 }, /* relax_code_seq */
1630 }, /* BR_RANGE_S256 */
1632 {0, 20, 0x1F, FALSE
},
1634 }, /* BR_RANGE_S16K */
1636 {0, 20, 0x1F, FALSE
},
1638 }, /* BR_RANGE_S64K */
1640 {0, 20, 0x1F, FALSE
},
1642 }, /* BR_RANGE_S16M */
1644 {0, 20, 0x1F, FALSE
},
1646 } /* BR_RANGE_U4G */
1647 }, /* relax_code_condition */
1648 {2, 4, 8, 8, 16}, /* relax_code_size */
1649 {2, 4, 4, 4, 4}, /* relax_branch_isize */
1652 {0, 2, NDS32_PCREL
, BFD_RELOC_NDS32_9_PCREL
},
1654 }, /* BR_RANGE_S256 */
1656 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1658 }, /* BR_RANGE_S16K */
1660 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1661 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1662 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1663 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1664 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1666 }, /* BR_RANGE_S64K */
1668 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1669 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1670 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1671 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1672 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1674 }, /* BR_RANGE_S16M */
1676 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1677 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1678 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
1679 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
1680 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1681 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
1682 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1683 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
1684 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
1685 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1687 } /* BR_RANGE_U4G */
1691 "beqc", /* opcode */
1692 BR_RANGE_S256
, /* br_range */
1694 {0, 8, 0x7FF, TRUE
},
1695 {0, 20, 0x1F, FALSE
},
1700 INSN_BEQC
/* beqc $rt, imm11s, label */
1701 }, /* BR_RANGE_S256 */
1703 INSN_MOVI_TA
, /* movi $ta, imm11s */
1704 INSN_BEQ_TA
/* beq $rt, $ta, label */
1705 }, /* BR_RANGE_S16K */
1707 INSN_BNEC
, /* bnec $rt, imm11s, $1 */
1708 INSN_J
/* j label */
1709 }, /* BR_RANGE_S64K */
1711 INSN_BNEC
, /* bnec $rt, imm11s, $1 */
1712 INSN_J
/* j label */
1713 }, /* BR_RANGE_S16M */
1715 INSN_BNEC
, /* bnec $rt, imm11s, $1 */
1716 INSN_SETHI_TA
, /* sethi $ta, label */
1717 INSN_ORI_TA
, /* ori $ta, $ta, label */
1718 INSN_JR_TA
/* jr $ta */
1719 } /* BR_RANGE_U4G */
1720 }, /* relax_code_seq */
1723 {0, 8, 0x7FF, TRUE
},
1724 {0, 20, 0x1F, FALSE
},
1726 }, /* BR_RANGE_S256 */
1728 {0, 0, 0xFFFFF, FALSE
},
1729 {4, 20, 0x1F, FALSE
},
1731 }, /* BR_RANGE_S16K */
1733 {0, 8, 0x7FF, FALSE
},
1734 {0, 20, 0x1F, FALSE
},
1736 }, /* BR_RANGE_S64K */
1738 {0, 8, 0x7FF, FALSE
},
1739 {0, 20, 0x1F, FALSE
},
1741 }, /* BR_RANGE_S16M */
1743 {0, 8, 0x7FF, FALSE
},
1744 {0, 20, 0x1F, FALSE
},
1746 } /* BR_RANGE_U4G */
1747 }, /* relax_code_condition */
1748 {4, 8, 8, 8, 16}, /* relax_code_size */
1749 {4, 4, 4, 4, 4}, /* relax_branch_isize */
1752 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_WORD_9_PCREL
},
1754 }, /* BR_RANGE_S256 */
1756 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1757 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP7
},
1758 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1760 }, /* BR_RANGE_S16K */
1762 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_WORD_9_PCREL
},
1763 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1765 }, /* BR_RANGE_S64K */
1767 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_WORD_9_PCREL
},
1768 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1770 }, /* BR_RANGE_S16M */
1772 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_WORD_9_PCREL
},
1773 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
1774 {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI
},
1775 {12, 4, NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
1777 } /* BR_RANGE_U4G */
1781 "bnec", /* opcode */
1782 BR_RANGE_S256
, /* br_range */
1784 {0, 8, 0x7FF, TRUE
},
1785 {0, 20, 0x1F, FALSE
},
1790 INSN_BNEC
/* bnec $rt, imm11s, label */
1791 }, /* BR_RANGE_S256 */
1793 INSN_MOVI_TA
, /* movi $ta, imm11s */
1794 INSN_BNE_TA
/* bne $rt, $ta, label */
1795 }, /* BR_RANGE_S16K */
1797 INSN_BEQC
, /* beqc $rt, imm11s, $1 */
1798 INSN_J
/* j label */
1799 }, /* BR_RANGE_S64K */
1801 INSN_BEQC
, /* beqc $rt, imm11s, $1 */
1802 INSN_J
/* j label */
1803 }, /* BR_RANGE_S16M */
1805 INSN_BEQC
, /* beqc $rt, imm11s, $1 */
1806 INSN_SETHI_TA
, /* sethi $ta, label */
1807 INSN_ORI_TA
, /* ori $ta, $ta, label */
1808 INSN_JR_TA
/* jr $ta */
1809 } /* BR_RANGE_U4G */
1810 }, /* relax_code_seq */
1813 {0, 8, 0x7FF, TRUE
},
1814 {0, 20, 0x1F, FALSE
},
1816 }, /* BR_RANGE_S256 */
1818 {0, 0, 0xFFFFF, FALSE
},
1819 {4, 20, 0x1F, FALSE
},
1821 }, /* BR_RANGE_S16K */
1823 {0, 8, 0x7FF, FALSE
},
1824 {0, 20, 0x1F, FALSE
},
1826 }, /* BR_RANGE_S64K */
1828 {0, 8, 0x7FF, FALSE
},
1829 {0, 20, 0x1F, FALSE
},
1831 }, /* BR_RANGE_S16M */
1833 {0, 8, 0x7FF, FALSE
},
1834 {0, 20, 0x1F, FALSE
},
1836 } /* BR_RANGE_U4G */
1837 }, /* relax_code_condition */
1838 {4, 8, 8, 8, 16}, /* relax_code_size */
1839 {4, 4, 4, 4, 4}, /* relax_branch_isize */
1842 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_WORD_9_PCREL
},
1844 }, /* BR_RANGE_S256 */
1846 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1847 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP7
},
1848 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1850 }, /* BR_RANGE_S16K */
1852 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_WORD_9_PCREL
},
1853 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1855 }, /* BR_RANGE_S64K */
1857 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_WORD_9_PCREL
},
1858 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1860 }, /* BR_RANGE_S16M */
1862 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_WORD_9_PCREL
},
1863 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
1864 {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI
},
1865 {12, 4, NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
1867 } /* BR_RANGE_U4G */
1872 /* GAS definitions for command-line options. */
1875 OPTION_BIG
= OPTION_MD_BASE
,
1879 OPTION_RELAX_FP_AS_GP_OFF
,
1880 OPTION_RELAX_B2BB_ON
,
1881 OPTION_RELAX_ALL_OFF
,
1883 OPTION_OPTIMIZE_SPACE
1886 const char *md_shortopts
= "m:O:";
1887 struct option md_longopts
[] =
1889 {"O1", no_argument
, NULL
, OPTION_OPTIMIZE
},
1890 {"Os", no_argument
, NULL
, OPTION_OPTIMIZE_SPACE
},
1891 {"big", no_argument
, NULL
, OPTION_BIG
},
1892 {"little", no_argument
, NULL
, OPTION_LITTLE
},
1893 {"EB", no_argument
, NULL
, OPTION_BIG
},
1894 {"EL", no_argument
, NULL
, OPTION_LITTLE
},
1895 {"meb", no_argument
, NULL
, OPTION_BIG
},
1896 {"mel", no_argument
, NULL
, OPTION_LITTLE
},
1897 {"mall-ext", no_argument
, NULL
, OPTION_TURBO
},
1898 {"mext-all", no_argument
, NULL
, OPTION_TURBO
},
1899 {"mpic", no_argument
, NULL
, OPTION_PIC
},
1900 /* Relaxation related options. */
1901 {"mno-fp-as-gp-relax", no_argument
, NULL
, OPTION_RELAX_FP_AS_GP_OFF
},
1902 {"mb2bb", no_argument
, NULL
, OPTION_RELAX_B2BB_ON
},
1903 {"mno-all-relax", no_argument
, NULL
, OPTION_RELAX_ALL_OFF
},
1904 {NULL
, no_argument
, NULL
, 0}
1907 size_t md_longopts_size
= sizeof (md_longopts
);
1909 struct nds32_parse_option_table
1911 const char *name
; /* Option string. */
1912 const char *help
; /* Help description. */
1913 int (*func
) (const char *arg
); /* How to parse it. */
1917 /* The value `-1' represents this option has *NOT* been set. */
1918 #ifdef NDS32_DEFAULT_ARCH_NAME
1919 static const char* nds32_arch_name
= NDS32_DEFAULT_ARCH_NAME
;
1921 static const char* nds32_arch_name
= "v3";
1923 static int nds32_baseline
= -1;
1924 static int nds32_gpr16
= -1;
1925 static int nds32_fpu_sp_ext
= -1;
1926 static int nds32_fpu_dp_ext
= -1;
1927 static int nds32_freg
= -1;
1928 static int nds32_abi
= -1;
1930 /* Record ELF flags */
1931 static int nds32_elf_flags
= 0;
1932 static int nds32_fpu_com
= 0;
1934 static int nds32_parse_arch (const char *str
);
1935 static int nds32_parse_baseline (const char *str
);
1936 static int nds32_parse_freg (const char *str
);
1937 static int nds32_parse_abi (const char *str
);
1939 static struct nds32_parse_option_table parse_opts
[] =
1941 {"arch=", N_("<arch name>\t Assemble for architecture <arch name>\n\
1942 <arch name> could be\n\
1943 v3, v3j, v3m, v3f, v3s, "\
1944 "v2, v2j, v2f, v2s"), nds32_parse_arch
},
1945 {"baseline=", N_("<baseline>\t Assemble for baseline <baseline>\n\
1946 <baseline> could be v2, v3, v3m"),
1947 nds32_parse_baseline
},
1948 {"fpu-freg=", N_("<freg>\t Specify a FPU configuration\n\
1950 0: 8 SP / 4 DP registers\n\
1951 1: 16 SP / 8 DP registers\n\
1952 2: 32 SP / 16 DP registers\n\
1953 3: 32 SP / 32 DP registers"), nds32_parse_freg
},
1954 {"abi=", N_("<abi>\t Specify a abi version\n\
1955 <abi> could be v1, v2, v2fp, v2fpp"), nds32_parse_abi
},
1959 static int nds32_mac
= 1;
1960 static int nds32_div
= 1;
1961 static int nds32_16bit_ext
= 1;
1962 static int nds32_dx_regs
= 1;
1963 static int nds32_perf_ext
= 1;
1964 static int nds32_perf_ext2
= 1;
1965 static int nds32_string_ext
= 1;
1966 static int nds32_audio_ext
= 1;
1967 static int nds32_fpu_fma
= 0;
1968 static int nds32_pic
= 0;
1969 static int nds32_relax_fp_as_gp
= 1;
1970 static int nds32_relax_b2bb
= 0;
1971 static int nds32_relax_all
= 1;
1972 struct nds32_set_option_table
1974 const char *name
; /* Option string. */
1975 const char *help
; /* Help description. */
1976 int *var
; /* Variable to be set. */
1977 int value
; /* Value to set. */
1980 /* The option in this group has both Enable/Disable settings.
1981 Just list on here. */
1983 static struct nds32_set_option_table toggle_opts
[] =
1985 {"mac", N_("Multiply instructions support"), &nds32_mac
, 1},
1986 {"div", N_("Divide instructions support"), &nds32_div
, 1},
1987 {"16bit-ext", N_("16-bit extension"), &nds32_16bit_ext
, 1},
1988 {"dx-regs", N_("d0/d1 registers"), &nds32_dx_regs
, 1},
1989 {"perf-ext", N_("Performance extension"), &nds32_perf_ext
, 1},
1990 {"perf2-ext", N_("Performance extension 2"), &nds32_perf_ext2
, 1},
1991 {"string-ext", N_("String extension"), &nds32_string_ext
, 1},
1992 {"reduced-regs", N_("Reduced Register configuration (GPR16) option"), &nds32_gpr16
, 1},
1993 {"audio-isa-ext", N_("AUDIO ISA extension"), &nds32_audio_ext
, 1},
1994 {"fpu-sp-ext", N_("FPU SP extension"), &nds32_fpu_sp_ext
, 1},
1995 {"fpu-dp-ext", N_("FPU DP extension"), &nds32_fpu_dp_ext
, 1},
1996 {"fpu-fma", N_("FPU fused-multiply-add instructions"), &nds32_fpu_fma
, 1},
1997 {NULL
, NULL
, NULL
, 0}
2001 /* GAS declarations. */
2003 /* This is the callback for nds32-asm.c to parse operands. */
2005 nds32_asm_parse_operand (struct nds32_asm_desc
*pdesc
,
2006 struct nds32_asm_insn
*pinsn
,
2007 char **pstr
, int64_t *value
);
2010 struct nds32_asm_desc asm_desc
;
2012 /* md_after_parse_args ()
2014 GAS will call md_after_parse_args whenever it is defined.
2015 This function checks any conflicting options specified. */
2018 nds32_after_parse_args (void)
2020 /* If -march option is not used in command-line, set the value of option
2021 variable according to NDS32_DEFAULT_ARCH_NAME. */
2022 nds32_parse_arch (nds32_arch_name
);
2025 /* This function is called when printing usage message (--help). */
2028 md_show_usage (FILE *stream
)
2030 struct nds32_parse_option_table
*coarse_tune
;
2031 struct nds32_set_option_table
*fine_tune
;
2033 fprintf (stream
, _("\n NDS32-specific assembler options:\n"));
2034 fprintf (stream
, _("\
2035 -O1, Optimize for performance\n\
2036 -Os Optimize for space\n"));
2037 fprintf (stream
, _("\
2038 -EL, -mel or -little Produce little endian output\n\
2039 -EB, -meb or -big Produce big endian output\n\
2040 -mpic Generate PIC\n\
2041 -mno-fp-as-gp-relax Suppress fp-as-gp relaxation for this file\n\
2042 -mb2bb-relax Back-to-back branch optimization\n\
2043 -mno-all-relax Suppress all relaxation for this file\n"));
2045 for (coarse_tune
= parse_opts
; coarse_tune
->name
!= NULL
; coarse_tune
++)
2047 if (coarse_tune
->help
!= NULL
)
2048 fprintf (stream
, _(" -m%s%s\n"),
2049 coarse_tune
->name
, _(coarse_tune
->help
));
2052 for (fine_tune
= toggle_opts
; fine_tune
->name
!= NULL
; fine_tune
++)
2054 if (fine_tune
->help
!= NULL
)
2055 fprintf (stream
, _(" -m[no-]%-17sEnable/Disable %s\n"),
2056 fine_tune
->name
, _(fine_tune
->help
));
2059 fprintf (stream
, _("\
2060 -mall-ext Turn on all extensions and instructions support\n"));
2064 nds32_frag_init (fragS
*fragp
)
2066 fragp
->tc_frag_data
.flag
= 0;
2067 fragp
->tc_frag_data
.opcode
= NULL
;
2068 fragp
->tc_frag_data
.fixup
= NULL
;
2073 /* This function reads an expression from a C string and returns a pointer past
2074 the end of the expression. */
2077 parse_expression (char *str
, expressionS
*exp
)
2082 tmp
= input_line_pointer
; /* Save line pointer. */
2083 input_line_pointer
= str
;
2085 s
= input_line_pointer
;
2086 input_line_pointer
= tmp
; /* Restore line pointer. */
2088 return s
; /* Return pointer to where parsing stopped. */
2092 nds32_start_line_hook (void)
2100 typedef void (*nds32_pseudo_opcode_func
) (int argc
, char *argv
[], unsigned int pv
);
2101 struct nds32_pseudo_opcode
2105 nds32_pseudo_opcode_func proc
;
2106 unsigned int pseudo_val
;
2108 /* Some instructions are not pseudo opcode, but they might still be
2109 expanded or changed with other instruction combination for some
2110 conditions. We also apply this structure to assist such work.
2112 For example, if the distance of branch target '.L0' is larger than
2119 will be transformed into:
2125 However, sometimes we do not want assembler to do such changes
2126 because compiler knows how to generate corresponding instruction sequence.
2127 Use this field to indicate that this opcode is also a physical instruction.
2128 If the flag 'verbatim' is nozero and this opcode
2129 is a physical instruction, we should not expand it. */
2132 #define PV_DONT_CARE 0
2134 static struct hash_control
*nds32_pseudo_opcode_hash
= NULL
;
2137 builtin_isreg (const char *s
, const char *x ATTRIBUTE_UNUSED
)
2139 if (s
[0] == '$' && hash_find (nds32_gprs_hash
, (s
+ 1)))
2145 builtin_regnum (const char *s
, const char *x ATTRIBUTE_UNUSED
)
2147 struct nds32_keyword
*k
;
2151 k
= hash_find (nds32_gprs_hash
, s
);
2160 builtin_addend (const char *s
, char *x ATTRIBUTE_UNUSED
)
2162 const char *ptr
= s
;
2164 while (*ptr
!= '+' && *ptr
!= '-' && *ptr
)
2170 return strtol (ptr
, NULL
, 0);
2174 md_assemblef (const char *format
, ...)
2176 /* FIXME: hope this is long enough. */
2181 va_start (ap
, format
);
2182 r
= vsnprintf (line
, sizeof (line
), format
, ap
);
2185 gas_assert (r
< sizeof (line
));
2188 /* Some prototypes here, since some op may use another op. */
2189 static void do_pseudo_li_internal (const char *rt
, int imm32s
);
2190 static void do_pseudo_move_reg_internal (char *dst
, char *src
);
2193 do_pseudo_b (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2194 unsigned int pv ATTRIBUTE_UNUSED
)
2196 char *arg_label
= argv
[0];
2199 if (nds32_pic
&& strstr (arg_label
, "@PLT"))
2201 md_assemblef ("sethi $ta,hi20(%s)", arg_label
);
2202 md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label
);
2203 md_assemble ((char *) "add $ta,$ta,$gp");
2204 md_assemble ((char *) "jr $ta");
2208 md_assemblef ("j %s", arg_label
);
2214 do_pseudo_bal (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2215 unsigned int pv ATTRIBUTE_UNUSED
)
2217 char *arg_label
= argv
[0];
2219 /* bal|call label */
2221 && (strstr (arg_label
, "@GOT") || strstr (arg_label
, "@PLT")))
2223 md_assemblef ("sethi $ta,hi20(%s)", arg_label
);
2224 md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label
);
2225 md_assemble ((char *) "add $ta,$ta,$gp");
2226 md_assemble ((char *) "jral $ta");
2230 md_assemblef ("jal %s", arg_label
);
2236 do_pseudo_bge (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2237 unsigned int pv ATTRIBUTE_UNUSED
)
2239 /* rt5, ra5, label */
2240 md_assemblef ("slt $ta,%s,%s", argv
[0], argv
[1]);
2241 md_assemblef ("beqz $ta,%s", argv
[2]);
2245 do_pseudo_bges (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2246 unsigned int pv ATTRIBUTE_UNUSED
)
2248 /* rt5, ra5, label */
2249 md_assemblef ("slts $ta,%s,%s", argv
[0], argv
[1]);
2250 md_assemblef ("beqz $ta,%s", argv
[2]);
2254 do_pseudo_bgt (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2255 unsigned int pv ATTRIBUTE_UNUSED
)
2257 /* bgt rt5, ra5, label */
2258 md_assemblef ("slt $ta,%s,%s", argv
[1], argv
[0]);
2259 md_assemblef ("bnez $ta,%s", argv
[2]);
2263 do_pseudo_bgts (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2264 unsigned int pv ATTRIBUTE_UNUSED
)
2266 /* bgt rt5, ra5, label */
2267 md_assemblef ("slts $ta,%s,%s", argv
[1], argv
[0]);
2268 md_assemblef ("bnez $ta,%s", argv
[2]);
2272 do_pseudo_ble (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2273 unsigned int pv ATTRIBUTE_UNUSED
)
2275 /* bgt rt5, ra5, label */
2276 md_assemblef ("slt $ta,%s,%s", argv
[1], argv
[0]);
2277 md_assemblef ("beqz $ta,%s", argv
[2]);
2281 do_pseudo_bles (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2282 unsigned int pv ATTRIBUTE_UNUSED
)
2284 /* bgt rt5, ra5, label */
2285 md_assemblef ("slts $ta,%s,%s", argv
[1], argv
[0]);
2286 md_assemblef ("beqz $ta,%s", argv
[2]);
2290 do_pseudo_blt (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2291 unsigned int pv ATTRIBUTE_UNUSED
)
2293 /* rt5, ra5, label */
2294 md_assemblef ("slt $ta,%s,%s", argv
[0], argv
[1]);
2295 md_assemblef ("bnez $ta,%s", argv
[2]);
2299 do_pseudo_blts (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2300 unsigned int pv ATTRIBUTE_UNUSED
)
2302 /* rt5, ra5, label */
2303 md_assemblef ("slts $ta,%s,%s", argv
[0], argv
[1]);
2304 md_assemblef ("bnez $ta,%s", argv
[2]);
2308 do_pseudo_br (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2309 unsigned int pv ATTRIBUTE_UNUSED
)
2311 md_assemblef ("jr %s", argv
[0]);
2315 do_pseudo_bral (int argc
, char *argv
[],
2316 unsigned int pv ATTRIBUTE_UNUSED
)
2319 md_assemblef ("jral $lp,%s", argv
[0]);
2321 md_assemblef ("jral %s,%s", argv
[0], argv
[1]);
2325 do_pseudo_la_internal (const char *arg_reg
, char *arg_label
,
2330 parse_expression (arg_label
, &exp
);
2331 if (exp
.X_op
!= O_symbol
)
2333 as_bad (_("la must use with symbol. '%s'"), line
);
2339 if (!nds32_pic
&& !strstr(arg_label
, "@"))
2341 md_assemblef ("sethi %s,hi20(%s)", arg_reg
, arg_label
);
2342 md_assemblef ("ori %s,%s,lo12(%s)", arg_reg
, arg_reg
, arg_label
);
2344 else if (strstr (arg_label
, "@TPOFF"))
2346 /* la $rt, sym@TPOFF */
2347 md_assemblef ("sethi $ta,hi20(%s)", arg_label
);
2348 md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label
);
2349 md_assemblef ("add %s,$ta,%s", arg_reg
, TLS_REG
);
2351 else if (strstr(arg_label
, "@GOTTPOFF"))
2353 /* la $rt, sym@GOTTPOFF*/
2354 md_assemblef ("sethi $ta,hi20(%s)", arg_label
);
2355 md_assemblef ("lwi $ta,[$ta+lo12(%s)]", arg_label
);
2356 md_assemblef ("add %s,$ta,%s", arg_reg
, TLS_REG
);
2358 else if (nds32_pic
&& ((strstr (arg_label
, "@PLT")
2359 || strstr (arg_label
, "@GOTOFF"))))
2361 md_assemblef ("sethi $ta,hi20(%s)", arg_label
);
2362 md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label
);
2363 md_assemblef ("add %s,$ta,$gp", arg_reg
);
2365 else if (nds32_pic
&& strstr (arg_label
, "@GOT"))
2367 long addend
= builtin_addend (arg_label
, NULL
);
2369 md_assemblef ("sethi $ta,hi20(%s)", arg_label
);
2370 md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label
);
2371 md_assemblef ("lw %s,[$gp+$ta]", arg_reg
);
2374 if (addend
< 0x4000 && addend
>= -0x4000)
2376 md_assemblef ("addi %s,%s,%d", arg_reg
, arg_reg
, addend
);
2380 do_pseudo_li_internal ("$ta", addend
);
2381 md_assemblef ("add %s,$ta,%s", arg_reg
, arg_reg
);
2386 as_bad (_("need PIC qualifier with symbol. '%s'"), line
);
2391 do_pseudo_la (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2392 unsigned int pv ATTRIBUTE_UNUSED
)
2394 do_pseudo_la_internal (argv
[0], argv
[1], argv
[argc
]);
2398 do_pseudo_li_internal (const char *rt
, int imm32s
)
2400 if (enable_16bit
&& imm32s
<= 0xf && imm32s
>= -0x10)
2401 md_assemblef ("movi55 %s,%d", rt
, imm32s
);
2402 else if (imm32s
<= 0x7ffff && imm32s
>= -0x80000)
2403 md_assemblef ("movi %s,%d", rt
, imm32s
);
2404 else if ((imm32s
& 0xfff) == 0)
2405 md_assemblef ("sethi %s,hi20(%d)", rt
, imm32s
);
2408 md_assemblef ("sethi %s,hi20(%d)", rt
, imm32s
);
2409 md_assemblef ("ori %s,%s,lo12(%d)", rt
, rt
, imm32s
);
2414 do_pseudo_li (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2415 unsigned int pv ATTRIBUTE_UNUSED
)
2417 /* Validate argv[1] for constant expression. */
2420 parse_expression (argv
[1], &exp
);
2421 if (exp
.X_op
!= O_constant
)
2423 as_bad (_("Operand is not a constant. `%s'"), argv
[argc
]);
2427 do_pseudo_li_internal (argv
[0], exp
.X_add_number
);
2431 do_pseudo_ls_bhw (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2436 const char *sign
= "";
2438 /* Prepare arguments for various load/store. */
2439 sign
= (pv
& 0x10) ? "s" : "";
2440 ls
= (pv
& 0x80000000) ? 's' : 'l';
2443 case 0: size
= 'b'; break;
2444 case 1: size
= 'h'; break;
2445 case 2: size
= 'w'; break;
2448 if (ls
== 's' || size
== 'w')
2451 if (builtin_isreg (argv
[1], NULL
))
2454 md_assemblef ("%c%ci %s,[%s]", ls
, size
, argv
[0], argv
[1]);
2456 else if (!nds32_pic
)
2459 if (strstr (argv
[1], "@TPOFF"))
2461 /* ls.w $rt, sym@TPOFF */
2462 md_assemblef ("sethi $ta,hi20(%s)", argv
[1]);
2463 md_assemblef ("ori $ta,$ta,lo12(%s)", argv
[1]);
2464 md_assemblef ("%c%c%s %s,[$ta+%s]", ls
, size
, sign
, argv
[0], TLS_REG
);
2466 else if (strstr (argv
[1], "@GOTTPOFF"))
2468 /* ls.w $rt, sym@GOTTPOFF */
2469 md_assemblef ("sethi $ta,hi20(%s)", argv
[1]);
2470 md_assemblef ("lwi $ta,[$ta+lo12(%s)]", argv
[1]);
2471 md_assemblef ("%c%c%s %s,[$ta+%s]", ls
, size
, sign
, argv
[0], TLS_REG
);
2476 md_assemblef ("sethi $ta,hi20(%s)", argv
[1]);
2477 md_assemblef ("%c%c%si %s,[$ta+lo12(%s)]", ls
, size
, sign
, argv
[0], argv
[1]);
2485 if (strstr (argv
[1], "@GOTOFF"))
2488 md_assemblef ("sethi $ta,hi20(%s)", argv
[1]);
2489 md_assemblef ("ori $ta,$ta,lo12(%s)", argv
[1]);
2490 md_assemblef ("%c%c%s %s,[$ta+$gp]", ls
, size
, sign
, argv
[0]);
2492 else if (strstr (argv
[1], "@GOT"))
2494 long addend
= builtin_addend (argv
[1], NULL
);
2496 md_assemblef ("sethi $ta,hi20(%s)", argv
[1]);
2497 md_assemblef ("ori $ta,$ta,lo12(%s)", argv
[1]);
2498 md_assemble ((char *) "lw $ta,[$gp+$ta]"); /* Load address word. */
2499 if (addend
< 0x10000 && addend
>= -0x10000)
2501 md_assemblef ("%c%c%si %s,[$ta+(%d)]", ls
, size
, sign
, argv
[0], addend
);
2506 do_pseudo_li_internal (argv
[0], addend
);
2507 md_assemblef ("%c%c%s %s,[$ta+%s]", ls
, size
, sign
, argv
[0], argv
[0]);
2512 as_bad (_("needs @GOT or @GOTOFF. %s"), argv
[argc
]);
2519 do_pseudo_ls_bhwp (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2522 char *arg_rt
= argv
[0];
2523 char *arg_label
= argv
[1];
2524 char *arg_inc
= argv
[2];
2527 const char *sign
= "";
2529 /* Prepare arguments for various load/store. */
2530 sign
= (pv
& 0x10) ? "s" : "";
2531 ls
= (pv
& 0x80000000) ? 's' : 'l';
2534 case 0: size
= 'b'; break;
2535 case 1: size
= 'h'; break;
2536 case 2: size
= 'w'; break;
2539 if (ls
== 's' || size
== 'w')
2542 do_pseudo_la_internal ("$ta", arg_label
, argv
[argc
]);
2543 md_assemblef ("%c%c%si.bi %s,[$ta],%s", ls
, size
, sign
, arg_rt
, arg_inc
);
2547 do_pseudo_ls_bhwpc (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2550 char *arg_rt
= argv
[0];
2551 char *arg_inc
= argv
[1];
2554 const char *sign
= "";
2556 /* Prepare arguments for various load/store. */
2557 sign
= (pv
& 0x10) ? "s" : "";
2558 ls
= (pv
& 0x80000000) ? 's' : 'l';
2561 case 0: size
= 'b'; break;
2562 case 1: size
= 'h'; break;
2563 case 2: size
= 'w'; break;
2566 if (ls
== 's' || size
== 'w')
2569 md_assemblef ("%c%c%si.bi %s,[$ta],%s", ls
, size
, sign
, arg_rt
, arg_inc
);
2573 do_pseudo_ls_bhwi (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2578 const char *sign
= "";
2580 /* Prepare arguments for various load/store. */
2581 sign
= (pv
& 0x10) ? "s" : "";
2582 ls
= (pv
& 0x80000000) ? 's' : 'l';
2585 case 0: size
= 'b'; break;
2586 case 1: size
= 'h'; break;
2587 case 2: size
= 'w'; break;
2590 if (ls
== 's' || size
== 'w')
2593 md_assemblef ("%c%c%si.bi %s,%s,%s",
2594 ls
, size
, sign
, argv
[0], argv
[1], argv
[2]);
2598 do_pseudo_move_reg_internal (char *dst
, char *src
)
2601 md_assemblef ("mov55 %s,%s", dst
, src
);
2603 md_assemblef ("ori %s,%s,0", dst
, src
);
2607 do_pseudo_move (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2608 unsigned int pv ATTRIBUTE_UNUSED
)
2612 if (builtin_isreg (argv
[1], NULL
))
2613 do_pseudo_move_reg_internal (argv
[0], argv
[1]);
2616 parse_expression (argv
[1], &exp
);
2617 if (exp
.X_op
== O_constant
)
2618 /* move $rt, imm -> li $rt, imm */
2619 do_pseudo_li_internal (argv
[0], exp
.X_add_number
);
2621 /* l.w $rt, var -> l.w $rt, var */
2622 do_pseudo_ls_bhw (argc
, argv
, 2);
2627 do_pseudo_neg (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2628 unsigned int pv ATTRIBUTE_UNUSED
)
2630 /* Instead of "subri". */
2631 md_assemblef ("subri %s,%s,0", argv
[0], argv
[1]);
2635 do_pseudo_not (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2636 unsigned int pv ATTRIBUTE_UNUSED
)
2638 md_assemblef ("nor %s,%s,%s", argv
[0], argv
[1], argv
[1]);
2642 do_pseudo_pushpopm (int argc
, char *argv
[],
2643 unsigned int pv ATTRIBUTE_UNUSED
)
2645 /* posh/pop $ra, $rb */
2646 /* SMW.{b | a}{i | d}{m?} Rb, [Ra], Re, Enable4 */
2647 int rb
, re
, ra
, en4
;
2649 const char *opc
= "pushpopm";
2652 as_bad ("'pushm/popm $ra5, $rb5, $label' is deprecated. "
2653 "Only 'pushm/popm $ra5' is supported now. %s", argv
[argc
]);
2655 as_bad ("'pushm/popm $ra5, $rb5'. %s\n", argv
[argc
]);
2657 if (strstr (argv
[argc
], "pop") == argv
[argc
])
2659 else if (strstr (argv
[argc
], "push") == argv
[argc
])
2662 as_fatal ("nds32-as internal error. %s", argv
[argc
]);
2664 rb
= builtin_regnum (argv
[0], NULL
);
2665 re
= builtin_regnum (argv
[1], NULL
);
2669 as_warn ("$rb should not be smaller than $ra. %s", argv
[argc
]);
2670 /* Swap to right order. */
2676 /* Build enable4 mask. */
2678 if (re
>= 28 || rb
>= 28)
2680 for (i
= (rb
>= 28? rb
: 28); i
<= re
; i
++)
2681 en4
|= 1 << (3 - (i
- 28));
2684 /* Adjust $re, $rb. */
2687 else if (nds32_gpr16
!= 1 && re
>= 28)
2690 /* Reduce register. */
2691 if (nds32_gpr16
&& re
> 10 && !(rb
== 31 && re
== 31))
2693 if (re
>= 15 && strstr(opc
, "smw") != NULL
)
2694 md_assemblef ("%s $r15,[$sp],$r15,%d", opc
, en4
);
2696 md_assemblef ("%s $r%d,[$sp],$r10, 0x0", opc
, rb
);
2697 if (re
>= 15 && strstr(opc
, "lmw") != NULL
)
2698 md_assemblef ("%s $r15,[$sp],$r15,%d", opc
, en4
);
2701 md_assemblef ("%s $r%d,[$sp],$r%d,%d", opc
, rb
, re
, en4
);
2705 do_pseudo_pushpop (int argc
, char *argv
[],
2706 unsigned int pv ATTRIBUTE_UNUSED
)
2708 /* push/pop $ra5, $label=$sp */
2712 as_bad ("'push/pop $ra5, rb5' is deprecated. "
2713 "Only 'push/pop $ra5' is supported now. %s", argv
[argc
]);
2717 argvm
[2] = argv
[argc
];
2718 do_pseudo_pushpopm (2, argvm
, PV_DONT_CARE
);
2722 do_pseudo_v3push (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2723 unsigned int pv ATTRIBUTE_UNUSED
)
2725 md_assemblef ("push25 %s,%s", argv
[0], argv
[1]);
2729 do_pseudo_v3pop (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2730 unsigned int pv ATTRIBUTE_UNUSED
)
2732 md_assemblef ("pop25 %s,%s", argv
[0], argv
[1]);
2735 /* pv == 0, parsing "push.s" pseudo instruction operands.
2736 pv != 0, parsing "pop.s" pseudo instruction operands. */
2739 do_pseudo_pushpop_stack (int argc
, char *argv
[],
2742 /* push.s Rb,Re,{$fp $gp $lp $sp} ==> smw.adm Rb,[$sp],Re,Eable4 */
2743 /* pop.s Rb,Re,{$fp $gp $lp $sp} ==> lmw.bim Rb,[$sp],Re,Eable4 */
2748 const char *opc
= (pv
== 0) ? "smw.adm" : "lmw.bim";
2754 /* argc=1, operands pattern: { $fp $gp $lp $sp } */
2756 /* Set register number Rb = Re = $sp = $r31. */
2759 else if (argc
== 2 || argc
== 3)
2761 /* argc=2, operands pattern: Rb, Re */
2762 /* argc=3, operands pattern: Rb, Re, { $fp $gp $lp $sp } */
2764 /* Get register number in integer. */
2765 rb
= builtin_regnum (argv
[0], NULL
);
2766 re
= builtin_regnum (argv
[1], NULL
);
2768 /* Rb should be equal/less than Re. */
2770 as_bad ("The first operand (%s) should be equal to or smaller than "
2771 "second operand (%s).", argv
[0], argv
[1]);
2773 /* forbid using $fp|$gp|$lp|$sp in Rb or Re
2776 as_bad ("Cannot use $fp, $gp, $lp, or $sp at first operand !!");
2778 as_bad ("Cannot use $fp, $gp, $lp, or $sp at second operand !!");
2782 as_bad ("Invalid operands pattern !!");
2785 /* Build Enable4 mask. */
2786 /* Using last_arg_index for argc=1|2|3 is safe, because $fp, $gp, $lp,
2787 and $sp only appear in argc=1 or argc=3 if argc=2, en4 remains 0,
2788 which is also valid for code generation. */
2790 last_arg_index
= argc
- 1;
2791 if (strstr (argv
[last_arg_index
], "$fp"))
2793 if (strstr (argv
[last_arg_index
], "$gp"))
2795 if (strstr (argv
[last_arg_index
], "$lp"))
2797 if (strstr (argv
[last_arg_index
], "$sp"))
2800 md_assemblef ("%s $r%d,[$sp],$r%d,%d", opc
, rb
, re
, en4
);
2804 do_pseudo_push_bhwd (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2805 unsigned int pv ATTRIBUTE_UNUSED
)
2808 /* If users omit push location, use $sp as default value. */
2809 char location
[8] = "$sp"; /* 8 is enough for register name. */
2813 case 0: size
= 'b'; break;
2814 case 1: size
= 'h'; break;
2815 case 2: size
= 'w'; break;
2816 case 3: size
= 'w'; break;
2821 strncpy (location
, argv
[1], 8);
2825 md_assemblef ("l.%c $ta,%s", size
, argv
[0]);
2826 md_assemblef ("smw.adm $ta,[%s],$ta", location
);
2828 if ((pv
& 0x3) == 0x3) /* double-word */
2830 md_assemblef ("l.w $ta,%s+4", argv
[0]);
2831 md_assemblef ("smw.adm $ta,[%s],$ta", location
);
2836 do_pseudo_pop_bhwd (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2837 unsigned int pv ATTRIBUTE_UNUSED
)
2840 /* If users omit pop location, use $sp as default value. */
2841 char location
[8] = "$sp"; /* 8 is enough for register name. */
2845 case 0: size
= 'b'; break;
2846 case 1: size
= 'h'; break;
2847 case 2: size
= 'w'; break;
2848 case 3: size
= 'w'; break;
2853 strncpy (location
, argv
[2], 8);
2857 if ((pv
& 0x3) == 0x3) /* double-word */
2859 md_assemblef ("lmw.bim %s,[%s],%s", argv
[1], location
, argv
[1]);
2860 md_assemblef ("s.w %s,%s+4", argv
[1], argv
[0]);
2863 md_assemblef ("lmw.bim %s,[%s],%s", argv
[1], location
, argv
[1]);
2864 md_assemblef ("s.%c %s,%s", size
, argv
[1], argv
[0]);
2868 do_pseudo_pusha (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2869 unsigned int pv ATTRIBUTE_UNUSED
)
2871 /* If users omit push location, use $sp as default value. */
2872 char location
[8] = "$sp"; /* 8 is enough for register name. */
2876 strncpy (location
, argv
[1], 8);
2880 md_assemblef ("la $ta,%s", argv
[0]);
2881 md_assemblef ("smw.adm $ta,[%s],$ta", location
);
2885 do_pseudo_pushi (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2886 unsigned int pv ATTRIBUTE_UNUSED
)
2888 /* If users omit push location, use $sp as default value. */
2889 char location
[8] = "$sp"; /* 8 is enough for register name. */
2893 strncpy (location
, argv
[1], 8);
2897 md_assemblef ("li $ta,%s", argv
[0]);
2898 md_assemblef ("smw.adm $ta,[%s],$ta", location
);
2901 struct nds32_pseudo_opcode nds32_pseudo_opcode_table
[] =
2903 {"b", 1, do_pseudo_b
, 0, 0},
2904 {"bal", 1, do_pseudo_bal
, 0, 0},
2906 {"bge", 3, do_pseudo_bge
, 0, 0},
2907 {"bges", 3, do_pseudo_bges
, 0, 0},
2909 {"bgt", 3, do_pseudo_bgt
, 0, 0},
2910 {"bgts", 3, do_pseudo_bgts
, 0, 0},
2912 {"ble", 3, do_pseudo_ble
, 0, 0},
2913 {"bles", 3, do_pseudo_bles
, 0, 0},
2915 {"blt", 3, do_pseudo_blt
, 0, 0},
2916 {"blts", 3, do_pseudo_blts
, 0, 0},
2918 {"br", 1, do_pseudo_br
, 0, 0},
2919 {"bral", 1, do_pseudo_bral
, 0, 0},
2921 {"call", 1, do_pseudo_bal
, 0, 0},
2923 {"la", 2, do_pseudo_la
, 0, 0},
2924 {"li", 2, do_pseudo_li
, 0, 0},
2926 {"l.b", 2, do_pseudo_ls_bhw
, 0, 0},
2927 {"l.h", 2, do_pseudo_ls_bhw
, 1, 0},
2928 {"l.w", 2, do_pseudo_ls_bhw
, 2, 0},
2929 {"l.bs", 2, do_pseudo_ls_bhw
, 0 | 0x10, 0},
2930 {"l.hs", 2, do_pseudo_ls_bhw
, 1 | 0x10, 0},
2931 {"s.b", 2, do_pseudo_ls_bhw
, 0 | 0x80000000, 0},
2932 {"s.h", 2, do_pseudo_ls_bhw
, 1 | 0x80000000, 0},
2933 {"s.w", 2, do_pseudo_ls_bhw
, 2 | 0x80000000, 0},
2935 {"l.bp", 3, do_pseudo_ls_bhwp
, 0, 0},
2936 {"l.bpc", 3, do_pseudo_ls_bhwpc
, 0, 0},
2937 {"l.hp", 3, do_pseudo_ls_bhwp
, 1, 0},
2938 {"l.hpc", 3, do_pseudo_ls_bhwpc
, 1, 0},
2939 {"l.wp", 3, do_pseudo_ls_bhwp
, 2, 0},
2940 {"l.wpc", 3, do_pseudo_ls_bhwpc
, 2, 0},
2941 {"l.bsp", 3, do_pseudo_ls_bhwp
, 0 | 0x10, 0},
2942 {"l.bspc", 3, do_pseudo_ls_bhwpc
, 0 | 0x10, 0},
2943 {"l.hsp", 3, do_pseudo_ls_bhwp
, 1 | 0x10, 0},
2944 {"l.hspc", 3, do_pseudo_ls_bhwpc
, 1 | 0x10, 0},
2945 {"s.bp", 3, do_pseudo_ls_bhwp
, 0 | 0x80000000, 0},
2946 {"s.bpc", 3, do_pseudo_ls_bhwpc
, 0 | 0x80000000, 0},
2947 {"s.hp", 3, do_pseudo_ls_bhwp
, 1 | 0x80000000, 0},
2948 {"s.hpc", 3, do_pseudo_ls_bhwpc
, 1 | 0x80000000, 0},
2949 {"s.wp", 3, do_pseudo_ls_bhwp
, 2 | 0x80000000, 0},
2950 {"s.wpc", 3, do_pseudo_ls_bhwpc
, 2 | 0x80000000, 0},
2951 {"s.bsp", 3, do_pseudo_ls_bhwp
, 0 | 0x80000000 | 0x10, 0},
2952 {"s.hsp", 3, do_pseudo_ls_bhwp
, 1 | 0x80000000 | 0x10, 0},
2954 {"lbi.p", 3, do_pseudo_ls_bhwi
, 0, 0},
2955 {"lhi.p", 3, do_pseudo_ls_bhwi
, 1, 0},
2956 {"lwi.p", 3, do_pseudo_ls_bhwi
, 2, 0},
2957 {"sbi.p", 3, do_pseudo_ls_bhwi
, 0 | 0x80000000, 0},
2958 {"shi.p", 3, do_pseudo_ls_bhwi
, 1 | 0x80000000, 0},
2959 {"swi.p", 3, do_pseudo_ls_bhwi
, 2 | 0x80000000, 0},
2960 {"lbsi.p", 3, do_pseudo_ls_bhwi
, 0 | 0x10, 0},
2961 {"lhsi.p", 3, do_pseudo_ls_bhwi
, 1 | 0x10, 0},
2962 {"lwsi.p", 3, do_pseudo_ls_bhwi
, 2 | 0x10, 0},
2964 {"move", 2, do_pseudo_move
, 0, 0},
2965 {"neg", 2, do_pseudo_neg
, 0, 0},
2966 {"not", 2, do_pseudo_not
, 0, 0},
2968 {"pop", 2, do_pseudo_pushpop
, 0, 0},
2969 {"push", 2, do_pseudo_pushpop
, 0, 0},
2970 {"popm", 2, do_pseudo_pushpopm
, 0, 0},
2971 {"pushm", 3, do_pseudo_pushpopm
, 0, 0},
2973 {"v3push", 2, do_pseudo_v3push
, 0, 0},
2974 {"v3pop", 2, do_pseudo_v3pop
, 0, 0},
2976 /* Support pseudo instructions of pushing/poping registers into/from stack
2977 push.s Rb, Re, { $fp $gp $lp $sp } ==> smw.adm Rb,[$sp],Re,Enable4
2978 pop.s Rb, Re, { $fp $gp $lp $sp } ==> lmw.bim Rb,[$sp],Re,Enable4 */
2979 { "push.s", 3, do_pseudo_pushpop_stack
, 0, 0 },
2980 { "pop.s", 3, do_pseudo_pushpop_stack
, 1, 0 },
2981 { "push.b", 2, do_pseudo_push_bhwd
, 0, 0 },
2982 { "push.h", 2, do_pseudo_push_bhwd
, 1, 0 },
2983 { "push.w", 2, do_pseudo_push_bhwd
, 2, 0 },
2984 { "push.d", 2, do_pseudo_push_bhwd
, 3, 0 },
2985 { "pop.b", 3, do_pseudo_pop_bhwd
, 0, 0 },
2986 { "pop.h", 3, do_pseudo_pop_bhwd
, 1, 0 },
2987 { "pop.w", 3, do_pseudo_pop_bhwd
, 2, 0 },
2988 { "pop.d", 3, do_pseudo_pop_bhwd
, 3, 0 },
2989 { "pusha", 2, do_pseudo_pusha
, 0, 0 },
2990 { "pushi", 2, do_pseudo_pushi
, 0, 0 },
2992 {NULL
, 0, NULL
, 0, 0}
2996 nds32_init_nds32_pseudo_opcodes (void)
2998 struct nds32_pseudo_opcode
*opcode
= nds32_pseudo_opcode_table
;
3000 nds32_pseudo_opcode_hash
= hash_new ();
3001 for ( ; opcode
->opcode
; opcode
++)
3005 op
= hash_find (nds32_pseudo_opcode_hash
, opcode
->opcode
);
3008 as_warn (_("Duplicated pseudo-opcode %s."), opcode
->opcode
);
3011 hash_insert (nds32_pseudo_opcode_hash
, opcode
->opcode
, opcode
);
3015 static struct nds32_pseudo_opcode
*
3016 nds32_lookup_pseudo_opcode (const char *str
)
3019 /* Assume pseudo-opcode are less than 16-char in length. */
3022 for (i
= 0; i
< (int)ARRAY_SIZE (op
); i
++)
3024 if (ISSPACE (op
[i
] = str
[i
]))
3028 if (i
>= (int)ARRAY_SIZE (op
))
3033 return hash_find (nds32_pseudo_opcode_hash
, op
);
3037 nds32_pseudo_opcode_wrapper (char *line
, struct nds32_pseudo_opcode
*opcode
)
3040 char *argv
[8] = {NULL
};
3042 char *str
= xstrdup (line
);
3044 /* Parse arguments for opcode. */
3045 s
= str
+ strlen (opcode
->opcode
);
3050 /* Dummy comma to ease separate arguments as below. */
3056 if (argc
>= opcode
->argc
3057 || (argc
>= (int)ARRAY_SIZE (argv
) - 1))
3058 as_bad (_("Too many argument. `%s'"), line
);
3065 } while (s
[0] != '\0');
3067 /* Put the origin line for debugging. */
3069 opcode
->proc (argc
, argv
, opcode
->pseudo_val
);
3073 /* This function will be invoked from function `nds32_after_parse_args'.
3074 Thus, if the value of option has been set, keep the value the way it is. */
3077 nds32_parse_arch (const char *str
)
3079 static const struct nds32_arch
3090 {"v3m", ISA_V3M
, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_AABI
},
3091 {"v3j", ISA_V3
, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_AABI
},
3092 {"v3s", ISA_V3
, 0, 1, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_V2FP_PLUS
},
3093 {"v3f", ISA_V3
, 0, 1, 1, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_V2FP_PLUS
},
3094 {"v3", ISA_V3
, 0, 0, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_AABI
},
3095 {"v2j", ISA_V2
, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_AABI
},
3096 {"v2s", ISA_V2
, 0, 1, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_V2FP_PLUS
},
3097 {"v2f", ISA_V2
, 0, 1, 1, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_V2FP_PLUS
},
3098 {"v2", ISA_V2
, 0, 0, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_AABI
},
3102 for (i
= 0; i
< ARRAY_SIZE (archs
); i
++)
3104 if (strcmp (str
, archs
[i
].name
) != 0)
3107 /* The value `-1' represents this option has *NOT* been set. */
3108 nds32_baseline
= (-1 != nds32_baseline
) ? nds32_baseline
: archs
[i
].baseline
;
3109 nds32_gpr16
= (-1 != nds32_gpr16
) ? nds32_gpr16
: archs
[i
].reduced_reg
;
3110 nds32_fpu_sp_ext
= (-1 != nds32_fpu_sp_ext
) ? nds32_fpu_sp_ext
: archs
[i
].fpu_sp_ext
;
3111 nds32_fpu_dp_ext
= (-1 != nds32_fpu_dp_ext
) ? nds32_fpu_dp_ext
: archs
[i
].fpu_dp_ext
;
3112 nds32_freg
= (-1 != nds32_freg
) ? nds32_freg
: archs
[i
].fpu_freg
;
3113 nds32_abi
= (-1 != nds32_abi
) ? nds32_abi
: archs
[i
].abi
;
3118 /* Logic here rejects the input arch name. */
3119 as_bad (_("unknown arch name `%s'\n"), str
);
3124 /* This function parses "baseline" specified. */
3127 nds32_parse_baseline (const char *str
)
3129 if (strcmp (str
, "v3") == 0)
3130 nds32_baseline
= ISA_V3
;
3131 else if (strcmp (str
, "v3m") == 0)
3132 nds32_baseline
= ISA_V3M
;
3133 else if (strcmp (str
, "v2") == 0)
3134 nds32_baseline
= ISA_V2
;
3137 /* Logic here rejects the input baseline. */
3138 as_bad (_("unknown baseline `%s'\n"), str
);
3145 /* This function parses "fpu-freg" specified. */
3148 nds32_parse_freg (const char *str
)
3150 if (strcmp (str
, "2") == 0)
3151 nds32_freg
= E_NDS32_FPU_REG_32SP_16DP
;
3152 else if (strcmp (str
, "3") == 0)
3153 nds32_freg
= E_NDS32_FPU_REG_32SP_32DP
;
3154 else if (strcmp (str
, "1") == 0)
3155 nds32_freg
= E_NDS32_FPU_REG_16SP_8DP
;
3156 else if (strcmp (str
, "0") == 0)
3157 nds32_freg
= E_NDS32_FPU_REG_8SP_4DP
;
3160 /* Logic here rejects the input FPU configuration. */
3161 as_bad (_("unknown FPU configuration `%s'\n"), str
);
3168 /* This function parse "abi=" specified. */
3171 nds32_parse_abi (const char *str
)
3173 if (strcmp (str
, "v2") == 0)
3174 nds32_abi
= E_NDS_ABI_AABI
;
3176 else if (strcmp (str
, "v2fp") == 0)
3177 nds32_abi
= E_NDS_ABI_V2FP
;
3178 else if (strcmp (str
, "v1") == 0)
3179 nds32_abi
= E_NDS_ABI_V1
;
3180 else if (strcmp (str
,"v2fpp") == 0)
3181 nds32_abi
= E_NDS_ABI_V2FP_PLUS
;
3184 /* Logic here rejects the input abi version. */
3185 as_bad (_("unknown ABI version`%s'\n"), str
);
3192 /* This function turn on all extensions and instructions support. */
3195 nds32_all_ext (void)
3200 nds32_16bit_ext
= 1;
3202 nds32_perf_ext2
= 1;
3203 nds32_string_ext
= 1;
3204 nds32_audio_ext
= 1;
3206 nds32_fpu_sp_ext
= 1;
3207 nds32_fpu_dp_ext
= 1;
3212 /* GAS will call md_parse_option whenever getopt returns an unrecognized code,
3213 presumably indicating a special code value which appears in md_longopts.
3214 This function should return non-zero if it handled the option and zero
3215 otherwise. There is no need to print a message about an option not being
3216 recognized. This will be handled by the generic code. */
3219 nds32_parse_option (int c
, const char *arg
)
3221 struct nds32_parse_option_table
*coarse_tune
;
3222 struct nds32_set_option_table
*fine_tune
;
3223 const char *ptr_arg
= NULL
;
3227 case OPTION_OPTIMIZE
:
3229 optimize_for_space
= 0;
3231 case OPTION_OPTIMIZE_SPACE
:
3233 optimize_for_space
= 1;
3236 target_big_endian
= 1;
3239 target_big_endian
= 0;
3247 case OPTION_RELAX_FP_AS_GP_OFF
:
3248 nds32_relax_fp_as_gp
= 0;
3250 case OPTION_RELAX_B2BB_ON
:
3251 nds32_relax_b2bb
= 1;
3253 case OPTION_RELAX_ALL_OFF
:
3254 nds32_relax_all
= 0;
3257 /* Determination of which option table to search for to save time. */
3261 ptr_arg
= strchr (arg
, '=');
3265 /* Find the value after '='. */
3266 if (ptr_arg
!= NULL
)
3268 for (coarse_tune
= parse_opts
; coarse_tune
->name
!= NULL
; coarse_tune
++)
3270 if (strncmp (arg
, coarse_tune
->name
, (ptr_arg
- arg
)) == 0)
3272 coarse_tune
->func (ptr_arg
);
3281 /* Filter out the Disable option first. */
3282 if (strncmp (arg
, "no-", 3) == 0)
3288 for (fine_tune
= toggle_opts
; fine_tune
->name
!= NULL
; fine_tune
++)
3290 if (strcmp (arg
, fine_tune
->name
) == 0)
3292 if (fine_tune
->var
!= NULL
)
3293 *fine_tune
->var
= (disable
) ? 0 : 1;
3298 /* Nothing match. */
3305 /* tc_check_label */
3308 nds32_check_label (symbolS
*label ATTRIBUTE_UNUSED
)
3310 /* The code used to create BB is move to frob_label.
3311 They should go there. */
3315 set_endian_little (int on
)
3317 target_big_endian
= !on
;
3320 /* These functions toggles the generation of 16-bit. First encounter signals
3321 the beginning of not generating 16-bit instructions and next encounter
3322 signals the restoring back to default behavior. */
3325 trigger_16bit (int trigger
)
3327 enable_16bit
= trigger
;
3330 static int backup_16bit_mode
;
3332 restore_16bit (int no_use ATTRIBUTE_UNUSED
)
3334 enable_16bit
= backup_16bit_mode
;
3338 off_16bit (int no_use ATTRIBUTE_UNUSED
)
3340 backup_16bit_mode
= enable_16bit
;
3344 /* Built-in segments for small object. */
3345 typedef struct nds32_seg_entryT
3352 nds32_seg_entry nds32_seg_table
[] =
3354 {NULL
, ".sdata_f", SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
3355 | SEC_HAS_CONTENTS
| SEC_SMALL_DATA
},
3356 {NULL
, ".sdata_b", SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
3357 | SEC_HAS_CONTENTS
| SEC_SMALL_DATA
},
3358 {NULL
, ".sdata_h", SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
3359 | SEC_HAS_CONTENTS
| SEC_SMALL_DATA
},
3360 {NULL
, ".sdata_w", SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
3361 | SEC_HAS_CONTENTS
| SEC_SMALL_DATA
},
3362 {NULL
, ".sdata_d", SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
3363 | SEC_HAS_CONTENTS
| SEC_SMALL_DATA
},
3364 {NULL
, ".sbss_f", SEC_ALLOC
| SEC_SMALL_DATA
},
3365 {NULL
, ".sbss_b", SEC_ALLOC
| SEC_SMALL_DATA
},
3366 {NULL
, ".sbss_h", SEC_ALLOC
| SEC_SMALL_DATA
},
3367 {NULL
, ".sbss_w", SEC_ALLOC
| SEC_SMALL_DATA
},
3368 {NULL
, ".sbss_d", SEC_ALLOC
| SEC_SMALL_DATA
}
3371 /* Indexes to nds32_seg_table[]. */
3372 enum NDS32_SECTIONS_ENUM
3374 SDATA_F_SECTION
= 0,
3375 SDATA_B_SECTION
= 1,
3376 SDATA_H_SECTION
= 2,
3377 SDATA_W_SECTION
= 3,
3378 SDATA_D_SECTION
= 4,
3386 /* The following code is borrowed from v850_seg. Revise this is needed. */
3389 do_nds32_seg (int i
, subsegT sub
)
3391 nds32_seg_entry
*seg
= nds32_seg_table
+ i
;
3393 obj_elf_section_change_hook ();
3396 subseg_set (seg
->s
, sub
);
3399 seg
->s
= subseg_new (seg
->name
, sub
);
3400 if (OUTPUT_FLAVOR
== bfd_target_elf_flavour
)
3402 bfd_set_section_flags (stdoutput
, seg
->s
, seg
->flags
);
3403 if ((seg
->flags
& SEC_LOAD
) == 0)
3404 seg_info (seg
->s
)->bss
= 1;
3412 subsegT sub
= get_absolute_expression ();
3414 do_nds32_seg (i
, sub
);
3415 demand_empty_rest_of_line ();
3418 /* Set if label adjustment is needed. I should not adjust .xbyte in dwarf. */
3419 static symbolS
*nds32_last_label
; /* Last label for alignment. */
3421 /* This code is referred from D30V for adjust label to be with pending
3422 alignment. For example,
3426 Without this, the above label will not attach to incoming data. */
3429 nds32_adjust_label (int n
)
3431 /* FIXME: I think adjust label and alignment is
3432 the programmer's obligation. Sadly, VLSI team doesn't
3433 properly use .align for their test cases.
3434 So I re-implement cons_align and auto adjust labels, again.
3436 I think d30v's implementation is simple and good enough. */
3438 symbolS
*label
= nds32_last_label
;
3439 nds32_last_label
= NULL
;
3441 /* SEC_ALLOC is used to eliminate .debug_ sections.
3442 SEC_CODE is used to include section for ILM. */
3443 if (((now_seg
->flags
& SEC_ALLOC
) == 0 && (now_seg
->flags
& SEC_CODE
) == 0)
3444 || strcmp (now_seg
->name
, ".eh_frame") == 0
3445 || strcmp (now_seg
->name
, ".gcc_except_table") == 0)
3448 /* Only frag by alignment when needed.
3449 Otherwise, it will fail to optimize labels on 4-byte boundary. (bug8454)
3450 See md_convert_frag () and RELAX_SET_RELAXABLE (frag) for details. */
3451 if (frag_now_fix () & ((1 << n
) -1 ))
3453 if (subseg_text_p (now_seg
))
3454 frag_align_code (n
, 0);
3456 frag_align (n
, 0, 0);
3458 /* Record the minimum alignment for this segment. */
3459 record_alignment (now_seg
, n
- OCTETS_PER_BYTE_POWER
);
3465 int label_seen
= FALSE
;
3466 struct frag
*old_frag
;
3467 valueT old_value
, new_value
;
3469 gas_assert (S_GET_SEGMENT (label
) == now_seg
);
3471 old_frag
= symbol_get_frag (label
);
3472 old_value
= S_GET_VALUE (label
);
3473 new_value
= (valueT
) frag_now_fix ();
3475 /* Multiple labels may be on the same address. And the last symbol
3476 may not be a label at all, e.g., register name, external function names,
3477 so I have to track the last label in tc_frob_label instead of
3478 just using symbol_lastP. */
3479 for (sym
= symbol_lastP
; sym
!= NULL
; sym
= symbol_previous (sym
))
3481 if (symbol_get_frag (sym
) == old_frag
3482 && S_GET_VALUE (sym
) == old_value
)
3486 symbol_set_frag (sym
, frag_now
);
3487 S_SET_VALUE (sym
, new_value
);
3489 else if (label_seen
&& symbol_get_frag (sym
) != old_frag
)
3496 nds32_cons_align (int size ATTRIBUTE_UNUSED
)
3499 This is called before `md_flush_pending_output' is called by `cons'.
3501 There are two things should be done for auto-adjust-label.
3502 1. Align data/instructions and adjust label to be attached to them.
3503 2. Clear auto-adjust state, so incoming data/instructions will not
3511 in this case, '.word 0x2' will adjust the label, .L0, but '.word 0x3' should not.
3513 I think `md_flush_pending_output' is a good place to clear the auto-adjust state,
3514 but it is also called by `cons' before this function.
3515 To simplify the code, instead of overriding .zero, .fill, .space, etc,
3516 I think we should just adjust label in `nds32_aligned_X_cons' instead of here. */
3520 nds32_aligned_cons (int idx
)
3522 nds32_adjust_label (idx
);
3523 /* Call default handler. */
3525 if (now_seg
->flags
& SEC_CODE
3526 && now_seg
->flags
& SEC_ALLOC
&& now_seg
->flags
& SEC_RELOC
)
3528 /* Use BFD_RELOC_NDS32_DATA to avoid EX9 optimization replacing data. */
3531 exp
.X_add_number
= 0;
3532 exp
.X_op
= O_constant
;
3533 fix_new_exp (frag_now
, frag_now_fix () - (1 << idx
), 1 << idx
,
3534 &exp
, 0, BFD_RELOC_NDS32_DATA
);
3538 /* `.double' directive. */
3541 nds32_aligned_float_cons (int type
)
3549 nds32_adjust_label (2);
3555 nds32_adjust_label (4);
3558 as_bad ("Unrecognized float type, %c\n", (char)type
);
3560 /* Call default handler. */
3565 nds32_enable_pic (int ignore ATTRIBUTE_UNUSED
)
3567 /* Another way to do -mpic.
3568 This is for GCC internal use and should always be first line
3569 of code, otherwise, the effect is not determined. */
3574 nds32_set_abi (int ver
)
3579 /* Relax directive to set relocation R_NDS32_RELAX_ENTRY value. */
3582 nds32_relax_relocs (int relax
)
3587 const char *subtype_relax
[] =
3588 {"", "", "ex9", "ifc"};
3590 name
= input_line_pointer
;
3591 while (*input_line_pointer
&& !ISSPACE (*input_line_pointer
))
3592 input_line_pointer
++;
3593 saved_char
= *input_line_pointer
;
3594 *input_line_pointer
= 0;
3596 for (i
= 0; i
< (int) ARRAY_SIZE (subtype_relax
); i
++)
3598 if (strcmp (name
, subtype_relax
[i
]) == 0)
3604 enable_relax_relocs
= relax
& enable_relax_relocs
;
3605 enable_relax_ex9
= relax
& enable_relax_ex9
;
3606 enable_relax_ifc
= relax
& enable_relax_ifc
;
3609 enable_relax_ex9
= relax
;
3612 enable_relax_ifc
= relax
;
3620 *input_line_pointer
= saved_char
;
3621 ignore_rest_of_line ();
3624 /* Record which arguments register($r0 ~ $r5) is not used in callee.
3628 nds32_set_hint_func_args (int ignore ATTRIBUTE_UNUSED
)
3630 ignore_rest_of_line ();
3633 /* Insert relocations to mark the begin and end of a fp-omitted function,
3634 for further relaxation use.
3638 nds32_omit_fp_begin (int mode
)
3642 if (nds32_relax_fp_as_gp
== 0)
3644 exp
.X_op
= O_symbol
;
3645 exp
.X_add_symbol
= abs_section_sym
;
3649 exp
.X_add_number
= R_NDS32_RELAX_REGION_OMIT_FP_FLAG
;
3650 fix_new_exp (frag_now
, frag_now_fix (), 0, &exp
, 0,
3651 BFD_RELOC_NDS32_RELAX_REGION_BEGIN
);
3656 exp
.X_add_number
= R_NDS32_RELAX_REGION_OMIT_FP_FLAG
;
3657 fix_new_exp (frag_now
, frag_now_fix (), 0, &exp
, 0,
3658 BFD_RELOC_NDS32_RELAX_REGION_END
);
3662 /* Insert relocations to mark the begin and end of ex9 region,
3663 for further relaxation use.
3667 nds32_no_ex9_begin (int mode
)
3671 exp
.X_op
= O_symbol
;
3672 exp
.X_add_symbol
= abs_section_sym
;
3675 exp
.X_add_number
= R_NDS32_RELAX_REGION_NO_EX9_FLAG
;
3676 fix_new_exp (frag_now
, frag_now_fix (), 0, &exp
, 0,
3677 BFD_RELOC_NDS32_RELAX_REGION_BEGIN
);
3681 exp
.X_add_number
= R_NDS32_RELAX_REGION_NO_EX9_FLAG
;
3682 fix_new_exp (frag_now
, frag_now_fix (), 0, &exp
, 0,
3683 BFD_RELOC_NDS32_RELAX_REGION_END
);
3688 nds32_loop_begin (int mode
)
3690 /* Insert loop region relocation here. */
3693 exp
.X_op
= O_symbol
;
3694 exp
.X_add_symbol
= abs_section_sym
;
3697 exp
.X_add_number
= R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG
;
3698 fix_new_exp (frag_now
, frag_now_fix (), 0, &exp
, 0,
3699 BFD_RELOC_NDS32_RELAX_REGION_BEGIN
);
3703 exp
.X_add_number
= R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG
;
3704 fix_new_exp (frag_now
, frag_now_fix (), 0, &exp
, 0,
3705 BFD_RELOC_NDS32_RELAX_REGION_END
);
3709 struct nds32_relocs_group
3711 struct nds32_relocs_pattern
*pattern
;
3712 struct nds32_relocs_group
*next
;
3715 static struct nds32_relocs_group
*nds32_relax_hint_current
= NULL
;
3717 /* Insert a relax hint. */
3720 nds32_relax_hint (int mode ATTRIBUTE_UNUSED
)
3724 struct nds32_relocs_pattern
*relocs
= NULL
;
3725 struct nds32_relocs_group
*group
, *new;
3727 name
= input_line_pointer
;
3728 while (*input_line_pointer
&& !ISSPACE (*input_line_pointer
))
3729 input_line_pointer
++;
3730 saved_char
= *input_line_pointer
;
3731 *input_line_pointer
= 0;
3732 name
= strdup (name
);
3734 /* Find relax hint entry for next instruction, and all member will be
3735 initialized at that time. */
3736 relocs
= hash_find (nds32_hint_hash
, name
);
3739 relocs
= XNEW (struct nds32_relocs_pattern
);
3740 hash_insert (nds32_hint_hash
, name
, relocs
);
3744 while (relocs
->next
)
3745 relocs
=relocs
->next
;
3746 relocs
->next
= XNEW (struct nds32_relocs_pattern
);
3747 relocs
= relocs
->next
;
3750 relocs
->next
= NULL
;
3751 *input_line_pointer
= saved_char
;
3752 ignore_rest_of_line ();
3754 /* Get the final one of relax hint series. */
3756 /* It has to build this list because there are maybe more than one
3757 instructions relative to the same instruction. It to connect to
3758 next instruction after md_assemble. */
3759 new = XNEW (struct nds32_relocs_group
);
3760 new->pattern
= relocs
;
3762 group
= nds32_relax_hint_current
;
3764 nds32_relax_hint_current
= new;
3767 while (group
->next
!= NULL
)
3768 group
= group
->next
;
3774 /* Decide the size of vector entries, only accepts 4 or 16 now. */
3777 nds32_vec_size (int ignore ATTRIBUTE_UNUSED
)
3783 if (exp
.X_op
== O_constant
)
3785 if (exp
.X_add_number
== 4 || exp
.X_add_number
== 16)
3788 vec_size
= exp
.X_add_number
;
3789 else if (vec_size
!= exp
.X_add_number
)
3790 as_warn (_("Different arguments of .vec_size are found, "
3791 "previous %d, current %d"),
3792 (int) vec_size
, (int) exp
.X_add_number
);
3795 as_warn (_("Argument of .vec_size is expected 4 or 16, actual: %d."),
3796 (int) exp
.X_add_number
);
3799 as_warn (_("Argument of .vec_size is not a constant."));
3802 /* The behavior of ".flag" directive varies depending on the target.
3803 In nds32 target, we use it to recognize whether this assembly content is
3804 generated by compiler. Other features can also be added in this function
3808 nds32_flag (int ignore ATTRIBUTE_UNUSED
)
3813 const char *possible_flags
[] = { "verbatim" };
3815 /* Skip whitespaces. */
3816 name
= input_line_pointer
;
3817 while (*input_line_pointer
&& !ISSPACE (*input_line_pointer
))
3818 input_line_pointer
++;
3819 saved_char
= *input_line_pointer
;
3820 *input_line_pointer
= 0;
3822 for (i
= 0; i
< (int) ARRAY_SIZE (possible_flags
); i
++)
3824 if (strcmp (name
, possible_flags
[i
]) == 0)
3829 /* flag: verbatim */
3835 /* Already found the flag, no need to continue next loop. */
3840 *input_line_pointer
= saved_char
;
3841 ignore_rest_of_line ();
3844 ict_model (int ignore ATTRIBUTE_UNUSED
)
3849 const char *possible_flags
[] = { "small", "large" };
3851 /* Skip whitespaces. */
3852 name
= input_line_pointer
;
3853 while (*input_line_pointer
&& !ISSPACE (*input_line_pointer
))
3854 input_line_pointer
++;
3855 saved_char
= *input_line_pointer
;
3856 *input_line_pointer
= 0;
3858 for (i
= 0; i
< (int) ARRAY_SIZE (possible_flags
); i
++)
3860 if (strcmp (name
, possible_flags
[i
]) == 0)
3865 /* flag: verbatim */
3866 ict_flag
= ICT_SMALL
;
3869 ict_flag
= ICT_LARGE
;
3874 /* Already found the flag, no need to continue next loop. */
3879 *input_line_pointer
= saved_char
;
3880 ignore_rest_of_line ();
3884 nds32_n12hc (int ignore ATTRIBUTE_UNUSED
)
3886 /* N1213HC core is used. */
3890 /* The target specific pseudo-ops which we support. */
3891 const pseudo_typeS md_pseudo_table
[] =
3893 /* Forced alignment if declared these ways. */
3894 {"ascii", stringer
, 8 + 0},
3895 {"asciz", stringer
, 8 + 1},
3896 {"double", nds32_aligned_float_cons
, 'd'},
3897 {"dword", nds32_aligned_cons
, 3},
3898 {"float", nds32_aligned_float_cons
, 'f'},
3899 {"half", nds32_aligned_cons
, 1},
3900 {"hword", nds32_aligned_cons
, 1},
3901 {"int", nds32_aligned_cons
, 2},
3902 {"long", nds32_aligned_cons
, 2},
3903 {"octa", nds32_aligned_cons
, 4},
3904 {"quad", nds32_aligned_cons
, 3},
3905 {"qword", nds32_aligned_cons
, 4},
3906 {"short", nds32_aligned_cons
, 1},
3907 {"byte", nds32_aligned_cons
, 0},
3908 {"single", nds32_aligned_float_cons
, 'f'},
3909 {"string", stringer
, 8 + 1},
3910 {"word", nds32_aligned_cons
, 2},
3912 {"little", set_endian_little
, 1},
3913 {"big", set_endian_little
, 0},
3914 {"16bit_on", trigger_16bit
, 1},
3915 {"16bit_off", trigger_16bit
, 0},
3916 {"restore_16bit", restore_16bit
, 0},
3917 {"off_16bit", off_16bit
, 0},
3919 {"sdata_d", nds32_seg
, SDATA_D_SECTION
},
3920 {"sdata_w", nds32_seg
, SDATA_W_SECTION
},
3921 {"sdata_h", nds32_seg
, SDATA_H_SECTION
},
3922 {"sdata_b", nds32_seg
, SDATA_B_SECTION
},
3923 {"sdata_f", nds32_seg
, SDATA_F_SECTION
},
3925 {"sbss_d", nds32_seg
, SBSS_D_SECTION
},
3926 {"sbss_w", nds32_seg
, SBSS_W_SECTION
},
3927 {"sbss_h", nds32_seg
, SBSS_H_SECTION
},
3928 {"sbss_b", nds32_seg
, SBSS_B_SECTION
},
3929 {"sbss_f", nds32_seg
, SBSS_F_SECTION
},
3931 {"pic", nds32_enable_pic
, 0},
3932 {"n12_hc", nds32_n12hc
, 0},
3933 {"abi_1", nds32_set_abi
, E_NDS_ABI_V1
},
3934 {"abi_2", nds32_set_abi
, E_NDS_ABI_AABI
},
3936 {"abi_2fp", nds32_set_abi
, E_NDS_ABI_V2FP
},
3937 {"abi_2fp_plus", nds32_set_abi
, E_NDS_ABI_V2FP_PLUS
},
3938 {"relax", nds32_relax_relocs
, 1},
3939 {"no_relax", nds32_relax_relocs
, 0},
3940 {"hint_func_args", nds32_set_hint_func_args
, 0}, /* Abandon?? */
3941 {"omit_fp_begin", nds32_omit_fp_begin
, 1},
3942 {"omit_fp_end", nds32_omit_fp_begin
, 0},
3943 {"no_ex9_begin", nds32_no_ex9_begin
, 1},
3944 {"no_ex9_end", nds32_no_ex9_begin
, 0},
3945 {"vec_size", nds32_vec_size
, 0},
3946 {"flag", nds32_flag
, 0},
3947 {"innermost_loop_begin", nds32_loop_begin
, 1},
3948 {"innermost_loop_end", nds32_loop_begin
, 0},
3949 {"relax_hint", nds32_relax_hint
, 0},
3950 {"ict_model", ict_model
, 0},
3955 nds32_pre_do_align (int n
, char *fill
, int len
, int max
)
3957 /* Only make a frag if we HAVE to... */
3959 if (n
!= 0 && !need_pass_2
)
3963 if (subseg_text_p (now_seg
))
3965 dwarf2_emit_insn (0);
3967 frag_align_code (n
, max
);
3969 /* Tag this alignment when there is a label before it. */
3972 fragP
->tc_frag_data
.flag
= NDS32_FRAG_LABEL
;
3977 frag_align (n
, 0, max
);
3980 frag_align (n
, *fill
, max
);
3982 frag_align_pattern (n
, fill
, len
, max
);
3987 nds32_do_align (int n
)
3989 /* Optimize for space and label exists. */
3992 /* FIXME:I think this will break debug info sections and except_table. */
3993 if (!enable_relax_relocs
|| !subseg_text_p (now_seg
))
3996 /* Create and attach a BFD_RELOC_NDS32_LABEL fixup
3997 the size of instruction may not be correct because
3998 it could be relaxable. */
3999 exp
.X_op
= O_symbol
;
4000 exp
.X_add_symbol
= section_symbol (now_seg
);
4001 exp
.X_add_number
= n
;
4002 fix_new_exp (frag_now
,
4003 frag_now_fix (), 0, &exp
, 0, BFD_RELOC_NDS32_LABEL
);
4006 /* Supported Andes machines. */
4009 enum bfd_architecture bfd_mach
;
4013 /* This is the callback for nds32-asm.c to parse operands. */
4016 nds32_asm_parse_operand (struct nds32_asm_desc
*pdesc ATTRIBUTE_UNUSED
,
4017 struct nds32_asm_insn
*pinsn
,
4018 char **pstr
, int64_t *value
)
4021 expressionS
*pexp
= pinsn
->info
;
4023 hold
= input_line_pointer
;
4024 input_line_pointer
= *pstr
;
4026 *pstr
= input_line_pointer
;
4027 input_line_pointer
= hold
;
4033 return NASM_R_SYMBOL
;
4035 *value
= pexp
->X_add_number
;
4036 return NASM_R_CONST
;
4041 return NASM_R_ILLEGAL
;
4045 /* GAS will call this function at the start of the assembly, after the command
4046 line arguments have been parsed and all the machine independent
4047 initializations have been completed. */
4052 struct nds32_keyword
*k
;
4055 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, nds32_baseline
);
4057 nds32_init_nds32_pseudo_opcodes ();
4058 asm_desc
.parse_operand
= nds32_asm_parse_operand
;
4059 nds32_asm_init (&asm_desc
, 0);
4061 /* Initial general purpose registers hash table. */
4062 nds32_gprs_hash
= hash_new ();
4063 for (k
= keyword_gpr
; k
->name
; k
++)
4064 hash_insert (nds32_gprs_hash
, k
->name
, k
);
4066 /* Initial branch hash table. */
4067 nds32_relax_info_hash
= hash_new ();
4068 for (i
= 0; i
< ARRAY_SIZE (relax_table
); i
++)
4069 hash_insert (nds32_relax_info_hash
, relax_table
[i
].opcode
,
4072 /* Initial relax hint hash table. */
4073 nds32_hint_hash
= hash_new ();
4074 enable_16bit
= nds32_16bit_ext
;
4077 /* HANDLE_ALIGN in write.c. */
4080 nds32_handle_align (fragS
*fragp
)
4082 static const unsigned char nop16
[] = { 0x92, 0x00 };
4083 static const unsigned char nop32
[] = { 0x40, 0x00, 0x00, 0x09 };
4087 if (fragp
->fr_type
!= rs_align_code
)
4090 bytes
= fragp
->fr_next
->fr_address
- fragp
->fr_address
- fragp
->fr_fix
;
4091 p
= fragp
->fr_literal
+ fragp
->fr_fix
;
4102 exp_t
.X_op
= O_symbol
;
4103 exp_t
.X_add_symbol
= abs_section_sym
;
4104 exp_t
.X_add_number
= R_NDS32_INSN16_CONVERT_FLAG
;
4105 fix_new_exp (fragp
, fragp
->fr_fix
, 2, &exp_t
, 0,
4106 BFD_RELOC_NDS32_INSN16
);
4107 memcpy (p
, nop16
, 2);
4114 memcpy (p
, nop32
, 4);
4119 bytes
= fragp
->fr_next
->fr_address
- fragp
->fr_address
- fragp
->fr_fix
;
4120 fragp
->fr_fix
+= bytes
;
4123 /* md_flush_pending_output */
4126 nds32_flush_pending_output (void)
4128 nds32_last_label
= NULL
;
4132 nds32_frob_label (symbolS
*label
)
4134 dwarf2_emit_label (label
);
4137 /* TC_START_LABEL */
4140 nds32_start_label (int asmdone ATTRIBUTE_UNUSED
, int secdone ATTRIBUTE_UNUSED
)
4142 if (optimize
&& subseg_text_p (now_seg
))
4150 nds32_target_format (void)
4153 if (target_big_endian
)
4154 return "elf32-nds32be-linux";
4156 return "elf32-nds32le-linux";
4158 if (target_big_endian
)
4159 return "elf32-nds32be";
4161 return "elf32-nds32le";
4165 static enum nds32_br_range
4166 get_range_type (const struct nds32_field
*field
)
4168 gas_assert (field
!= NULL
);
4170 if (field
->bitpos
!= 0)
4171 return BR_RANGE_U4G
;
4173 if (field
->bitsize
== 24 && field
->shift
== 1)
4174 return BR_RANGE_S16M
;
4175 else if (field
->bitsize
== 16 && field
->shift
== 1)
4176 return BR_RANGE_S64K
;
4177 else if (field
->bitsize
== 14 && field
->shift
== 1)
4178 return BR_RANGE_S16K
;
4179 else if (field
->bitsize
== 8 && field
->shift
== 1)
4180 return BR_RANGE_S256
;
4182 return BR_RANGE_U4G
;
4185 /* Save pseudo instruction relocation list. */
4187 static struct nds32_relocs_pattern
*
4188 nds32_elf_save_pseudo_pattern (fixS
* fixP
, struct nds32_opcode
*opcode
,
4189 char *out
, symbolS
*sym
,
4190 struct nds32_relocs_pattern
*reloc_ptr
,
4194 reloc_ptr
= XNEW (struct nds32_relocs_pattern
);
4195 reloc_ptr
->seg
= now_seg
;
4196 reloc_ptr
->sym
= sym
;
4197 reloc_ptr
->frag
= fragP
;
4198 reloc_ptr
->frchain
= frchain_now
;
4199 reloc_ptr
->fixP
= fixP
;
4200 reloc_ptr
->opcode
= opcode
;
4201 reloc_ptr
->where
= out
;
4202 reloc_ptr
->next
= NULL
;
4206 /* Check X_md to transform relocation. */
4209 nds32_elf_record_fixup_exp (fragS
*fragP
, const char *str
,
4210 const struct nds32_field
*fld
,
4211 expressionS
*pexp
, char* out
,
4212 struct nds32_asm_insn
*insn
)
4218 /* Handle instruction relocation. */
4219 if (fld
&& fld
->bitpos
== 0 && (insn
->attr
& NASM_ATTR_HI20
))
4221 /* Relocation for hi20 modifier. */
4224 case BFD_RELOC_NDS32_GOTOFF
: /* @GOTOFF */
4225 reloc
= BFD_RELOC_NDS32_GOTOFF_HI20
;
4227 case BFD_RELOC_NDS32_GOT20
: /* @GOT */
4228 reloc
= BFD_RELOC_NDS32_GOT_HI20
;
4230 case BFD_RELOC_NDS32_25_PLTREL
: /* @PLT */
4232 as_bad (_("Invalid PIC expression."));
4234 reloc
= BFD_RELOC_NDS32_PLT_GOTREL_HI20
;
4236 case BFD_RELOC_NDS32_GOTPC20
: /* _GLOBAL_OFFSET_TABLE_ */
4237 reloc
= BFD_RELOC_NDS32_GOTPC_HI20
;
4239 case BFD_RELOC_NDS32_TPOFF
: /* @TPOFF */
4240 reloc
= BFD_RELOC_NDS32_TLS_LE_HI20
;
4242 case BFD_RELOC_NDS32_GOTTPOFF
: /* @GOTTPOFF */
4243 reloc
= BFD_RELOC_NDS32_TLS_IE_HI20
;
4245 default: /* No suffix. */
4246 reloc
= BFD_RELOC_NDS32_HI20
;
4249 fixP
= fix_new_exp (fragP
, out
- fragP
->fr_literal
, insn
->opcode
->isize
,
4250 insn
->info
, 0 /* pcrel */, reloc
);
4252 else if (fld
&& fld
->bitpos
== 0 && (insn
->attr
& NASM_ATTR_LO12
))
4254 /* Relocation for lo12 modifier. */
4255 if (fld
->bitsize
== 15 && fld
->shift
== 0)
4260 case BFD_RELOC_NDS32_GOTOFF
: /* @GOTOFF */
4261 reloc
= BFD_RELOC_NDS32_GOTOFF_LO12
;
4263 case BFD_RELOC_NDS32_GOT20
: /* @GOT */
4264 reloc
= BFD_RELOC_NDS32_GOT_LO12
;
4266 case BFD_RELOC_NDS32_25_PLTREL
: /* @PLT */
4268 as_bad (_("Invalid PIC expression."));
4270 reloc
= BFD_RELOC_NDS32_PLT_GOTREL_LO12
;
4272 case BFD_RELOC_NDS32_GOTPC20
: /* _GLOBAL_OFFSET_TABLE_ */
4273 reloc
= BFD_RELOC_NDS32_GOTPC_LO12
;
4275 case BFD_RELOC_NDS32_TPOFF
: /* @TPOFF */
4276 reloc
= BFD_RELOC_NDS32_TLS_LE_LO12
;
4278 default: /* No suffix. */
4279 reloc
= BFD_RELOC_NDS32_LO12S0
;
4283 else if (fld
->bitsize
== 15 && fld
->shift
== 1)
4284 reloc
= BFD_RELOC_NDS32_LO12S1
; /* [ls]hi */
4285 else if (fld
->bitsize
== 15 && fld
->shift
== 2)
4290 case BFD_RELOC_NDS32_GOTTPOFF
: /* @GOTTPOFF */
4291 reloc
= BFD_RELOC_NDS32_TLS_IE_LO12S2
;
4293 default: /* No suffix. */
4294 reloc
= BFD_RELOC_NDS32_LO12S2
;
4298 else if (fld
->bitsize
== 15 && fld
->shift
== 3)
4299 reloc
= BFD_RELOC_NDS32_LO12S3
; /* [ls]di */
4300 else if (fld
->bitsize
== 12 && fld
->shift
== 2)
4301 reloc
= R_NDS32_LO12S2_SP_RELA
; /* f[ls][sd]i */
4303 fixP
= fix_new_exp (fragP
, out
- fragP
->fr_literal
, insn
->opcode
->isize
,
4304 insn
->info
, 0 /* pcrel */, reloc
);
4306 else if (fld
&& fld
->bitpos
== 0 && insn
->opcode
->isize
== 4
4307 && (insn
->attr
& NASM_ATTR_PCREL
))
4309 /* Relocation for 32-bit branch instructions. */
4310 if (fld
->bitsize
== 24 && fld
->shift
== 1)
4311 reloc
= BFD_RELOC_NDS32_25_PCREL
;
4312 else if (fld
->bitsize
== 16 && fld
->shift
== 1)
4313 reloc
= BFD_RELOC_NDS32_17_PCREL
;
4314 else if (fld
->bitsize
== 14 && fld
->shift
== 1)
4315 reloc
= BFD_RELOC_NDS32_15_PCREL
;
4316 else if (fld
->bitsize
== 8 && fld
->shift
== 1)
4317 reloc
= BFD_RELOC_NDS32_WORD_9_PCREL
;
4321 fixP
= fix_new_exp (fragP
, out
- fragP
->fr_literal
, insn
->opcode
->isize
,
4322 insn
->info
, 1 /* pcrel */, reloc
);
4324 else if (fld
&& fld
->bitpos
== 0 && insn
->opcode
->isize
== 4
4325 && (insn
->attr
& NASM_ATTR_GPREL
))
4327 /* Relocation for 32-bit gp-relative instructions. */
4328 if (fld
->bitsize
== 19 && fld
->shift
== 0)
4329 reloc
= BFD_RELOC_NDS32_SDA19S0
;
4330 else if (fld
->bitsize
== 18 && fld
->shift
== 1)
4331 reloc
= BFD_RELOC_NDS32_SDA18S1
;
4332 else if (fld
->bitsize
== 17 && fld
->shift
== 2)
4333 reloc
= BFD_RELOC_NDS32_SDA17S2
;
4337 fixP
= fix_new_exp (fragP
, out
- fragP
->fr_literal
, insn
->opcode
->isize
,
4338 insn
->info
, 0 /* pcrel */, reloc
);
4339 /* Insert INSN16 for converting fp_as_gp. */
4340 exp
.X_op
= O_symbol
;
4341 exp
.X_add_symbol
= abs_section_sym
;
4342 exp
.X_add_number
= 0;
4343 if (in_omit_fp
&& reloc
== BFD_RELOC_NDS32_SDA17S2
)
4344 fix_new_exp (fragP
, out
- fragP
->fr_literal
,
4345 insn
->opcode
->isize
, &exp
, 0 /* pcrel */,
4346 BFD_RELOC_NDS32_INSN16
);
4348 else if (fld
&& fld
->bitpos
== 0 && insn
->opcode
->isize
== 2
4349 && (insn
->attr
& NASM_ATTR_PCREL
))
4351 /* Relocation for 16-bit branch instructions. */
4352 if (fld
->bitsize
== 8 && fld
->shift
== 1)
4353 reloc
= BFD_RELOC_NDS32_9_PCREL
;
4357 fixP
= fix_new_exp (fragP
, out
- fragP
->fr_literal
, insn
->opcode
->isize
,
4358 insn
->info
, 1 /* pcrel */, reloc
);
4360 else if (fld
&& fld
->bitpos
== 0 && (insn
->attr
& NASM_ATTR_IFC_EXT
))
4362 /* Relocation for ifcall instruction. */
4363 if (insn
->opcode
->isize
== 2 && fld
->bitsize
== 9 && fld
->shift
== 1)
4364 reloc
= BFD_RELOC_NDS32_10IFCU_PCREL
;
4365 else if (insn
->opcode
->isize
== 4 && fld
->bitsize
== 16
4367 reloc
= BFD_RELOC_NDS32_17IFC_PCREL
;
4371 fixP
= fix_new_exp (fragP
, out
- fragP
->fr_literal
, insn
->opcode
->isize
,
4372 insn
->info
, 1 /* pcrel */, reloc
);
4375 as_bad (_("Don't know how to handle this field. %s"), str
);
4380 /* Build instruction pattern to relax. There are two type group pattern
4381 including pseudo instruction and relax hint. */
4384 nds32_elf_build_relax_relation (fixS
*fixP
, expressionS
*pexp
, char* out
,
4385 struct nds32_opcode
*opcode
, fragS
*fragP
,
4386 const struct nds32_field
*fld
)
4388 struct nds32_relocs_pattern
*reloc_ptr
;
4389 struct nds32_relocs_group
*group
;
4390 symbolS
*sym
= NULL
;
4392 /* The expression may be used uninitialized. */
4394 sym
= pexp
->X_add_symbol
;
4398 /* Save instruction relation for pseudo instruction expanding pattern. */
4399 reloc_ptr
= nds32_elf_save_pseudo_pattern (fixP
, opcode
, out
, sym
,
4402 relocs_list
= reloc_ptr
;
4405 struct nds32_relocs_pattern
*temp
= relocs_list
;
4408 temp
->next
= reloc_ptr
;
4411 else if (nds32_relax_hint_current
)
4413 /* Save instruction relation by relax hint. */
4414 group
= nds32_relax_hint_current
;
4417 nds32_elf_save_pseudo_pattern (fixP
, opcode
, out
, sym
,
4418 group
->pattern
, fragP
);
4419 group
= group
->next
;
4420 free (nds32_relax_hint_current
);
4421 nds32_relax_hint_current
= group
;
4425 /* Set relaxing false only for relax_hint trigger it. */
4430 #define N32_MEM_EXT(insn) ((N32_OP6_MEM << 25) | insn)
4432 /* Relax pattern for link time relaxation. */
4434 static struct nds32_relax_hint_table relax_ls_table
[] =
4437 /* Set address: la -> sethi ori. */
4438 NDS32_RELAX_HINT_LA
, /* main_type */
4439 8, /* relax_code_size */
4443 }, /* relax_code_seq */
4445 {0, 4, NDS32_HINT
| NDS32_ADDEND
, BFD_RELOC_NDS32_LOADSTORE
},
4446 {4, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_INSN16
}
4450 /* Set address: l.w -> sethi ori. */
4451 NDS32_RELAX_HINT_LS
, /* main_type */
4452 8, /* relax_code_size */
4456 }, /* relax_code_seq */
4458 {0, 4, NDS32_HINT
| NDS32_ADDEND
, BFD_RELOC_NDS32_LOADSTORE
},
4459 {4, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_INSN16
}
4470 /* Since sethi loadstore relocation has to using next instruction to determine
4471 elimination itself or not, we have to return the next instruction range. */
4474 nds32_elf_sethi_range (struct nds32_relocs_pattern
*pattern
)
4479 switch (pattern
->opcode
->value
)
4484 case N32_MEM_EXT (N32_MEM_LB
):
4485 case N32_MEM_EXT (N32_MEM_LBS
):
4486 case N32_MEM_EXT (N32_MEM_SB
):
4487 range
= NDS32_LOADSTORE_BYTE
;
4492 case N32_MEM_EXT (N32_MEM_LH
):
4493 case N32_MEM_EXT (N32_MEM_LHS
):
4494 case N32_MEM_EXT (N32_MEM_SH
):
4495 range
= NDS32_LOADSTORE_HALF
;
4499 case N32_MEM_EXT (N32_MEM_LW
):
4500 case N32_MEM_EXT (N32_MEM_SW
):
4501 range
= NDS32_LOADSTORE_WORD
;
4505 range
= NDS32_LOADSTORE_FLOAT_S
;
4509 range
= NDS32_LOADSTORE_FLOAT_D
;
4512 range
= NDS32_LOADSTORE_IMM
;
4515 range
= NDS32_LOADSTORE_NONE
;
4518 if (range
!= NDS32_LOADSTORE_NONE
)
4520 pattern
= pattern
->next
;
4525 /* The args means: instruction size, the 1st instruction is converted to 16 or
4526 not, optimize option, 16 bit instruction is enable. */
4527 #define SET_ADDEND(size, convertible, optimize, insn16_on) \
4528 (((size) & 0xff) | ((convertible) ? 1 << 31 : 0) \
4529 | ((optimize) ? 1<< 30 : 0) | (insn16_on ? 1 << 29 : 0))
4532 nds32_set_elf_flags_by_insn (struct nds32_asm_insn
* insn
)
4534 /* Set E_NDS32_HAS_EXT_INST. */
4535 if (insn
->opcode
->attr
& NASM_ATTR_PERF_EXT
)
4538 nds32_elf_flags
|= E_NDS32_HAS_EXT_INST
;
4540 as_bad (_("instruction %s requires enabling performance extension"),
4541 insn
->opcode
->opcode
);
4543 else if (insn
->opcode
->attr
& NASM_ATTR_PERF2_EXT
)
4545 if (nds32_perf_ext2
)
4546 nds32_elf_flags
|= E_NDS32_HAS_EXT2_INST
;
4548 as_bad (_("instruction %s requires enabling performance extension II"),
4549 insn
->opcode
->opcode
);
4551 else if (insn
->opcode
->attr
& NASM_ATTR_AUDIO_ISAEXT
)
4553 if (nds32_audio_ext
)
4554 nds32_elf_flags
|= E_NDS32_HAS_AUDIO_INST
;
4556 as_bad (_("instruction %s requires enabling AUDIO extension"),
4557 insn
->opcode
->opcode
);
4559 else if (insn
->opcode
->attr
& NASM_ATTR_STR_EXT
)
4561 if (nds32_string_ext
)
4562 nds32_elf_flags
|= E_NDS32_HAS_STRING_INST
;
4564 as_bad (_("instruction %s requires enabling STRING extension"),
4565 insn
->opcode
->opcode
);
4567 else if ((insn
->opcode
->attr
& NASM_ATTR_DIV
)
4568 && (insn
->opcode
->attr
& NASM_ATTR_DXREG
))
4570 if (nds32_div
&& nds32_dx_regs
)
4571 nds32_elf_flags
|= E_NDS32_HAS_DIV_DX_INST
;
4573 as_bad (_("instruction %s requires enabling DIV & DX_REGS extension"),
4574 insn
->opcode
->opcode
);
4576 else if (insn
->opcode
->attr
& NASM_ATTR_FPU
)
4578 if (nds32_fpu_sp_ext
|| nds32_fpu_dp_ext
)
4580 if (!(nds32_elf_flags
& (E_NDS32_HAS_FPU_INST
| E_NDS32_HAS_FPU_DP_INST
)))
4584 as_bad (_("instruction %s requires enabling FPU extension"),
4585 insn
->opcode
->opcode
);
4587 else if (insn
->opcode
->attr
& NASM_ATTR_FPU_SP_EXT
)
4589 if (nds32_fpu_sp_ext
)
4590 nds32_elf_flags
|= E_NDS32_HAS_FPU_INST
;
4592 as_bad (_("instruction %s requires enabling FPU_SP extension"),
4593 insn
->opcode
->opcode
);
4595 else if ((insn
->opcode
->attr
& NASM_ATTR_FPU_SP_EXT
)
4596 && (insn
->opcode
->attr
& NASM_ATTR_MAC
))
4598 if (nds32_fpu_sp_ext
&& nds32_mac
)
4600 nds32_elf_flags
|= E_NDS32_HAS_FPU_MAC_INST
;
4601 nds32_elf_flags
|= E_NDS32_HAS_FPU_INST
;
4604 as_bad (_("instruction %s requires enabling FPU_MAC extension"),
4605 insn
->opcode
->opcode
);
4607 else if (insn
->opcode
->attr
& NASM_ATTR_FPU_DP_EXT
)
4609 if (nds32_fpu_dp_ext
)
4610 nds32_elf_flags
|= E_NDS32_HAS_FPU_DP_INST
;
4612 as_bad (_("instruction %s requires enabling FPU_DP extension"),
4613 insn
->opcode
->opcode
);
4615 else if ((insn
->opcode
->attr
& NASM_ATTR_FPU_DP_EXT
)
4616 && (insn
->opcode
->attr
& NASM_ATTR_MAC
))
4618 if (nds32_fpu_dp_ext
&& nds32_mac
)
4620 nds32_elf_flags
|= E_NDS32_HAS_FPU_MAC_INST
;
4621 nds32_elf_flags
|= E_NDS32_HAS_FPU_DP_INST
;
4624 as_bad (_("instruction %s requires enabling FPU_MAC extension"),
4625 insn
->opcode
->opcode
);
4627 /* TODO: FPU_BOTH */
4628 else if ((insn
->opcode
->attr
& NASM_ATTR_MAC
)
4629 && (insn
->opcode
->attr
& NASM_ATTR_DXREG
))
4631 if (nds32_mac
&& nds32_dx_regs
)
4632 nds32_elf_flags
|= E_NDS32_HAS_MAC_DX_INST
;
4634 as_bad (_("instruction %s requires enabling DX_REGS extension"),
4635 insn
->opcode
->opcode
);
4637 /* TODO: for DX_REG set but not for MAC, DIV, AUDIO */
4638 else if (insn
->opcode
->attr
& NASM_ATTR_IFC_EXT
)
4640 nds32_elf_flags
|= E_NDS32_HAS_IFC_INST
;
4642 /* TODO: E_NDS32_HAS_SATURATION_INST */
4645 /* Flag for analysis relaxation type. */
4647 enum nds32_insn_type
4649 N32_RELAX_SETHI
= 1,
4650 N32_RELAX_BR
= (1 << 1),
4651 N32_RELAX_LSI
= (1 << 2),
4652 N32_RELAX_JUMP
= (1 << 3),
4653 N32_RELAX_CALL
= (1 << 4),
4654 N32_RELAX_ORI
= (1 << 5),
4655 N32_RELAX_MEM
= (1 << 6),
4656 N32_RELAX_MOVI
= (1 << 7),
4659 struct nds32_hint_map
4661 bfd_reloc_code_real_type hi_type
;
4663 enum nds32_relax_hint_type hint_type
;
4664 enum nds32_br_range range
;
4665 enum nds32_insn_type insn_list
;
4668 /* Table to match instructions with hint and relax pattern. */
4670 static struct nds32_hint_map hint_map
[] =
4674 BFD_RELOC_NDS32_HI20
,
4676 NDS32_RELAX_HINT_NONE
,
4678 N32_RELAX_SETHI
| N32_RELAX_ORI
| N32_RELAX_CALL
4682 _dummy_first_bfd_reloc_code_real
,
4684 NDS32_RELAX_HINT_NONE
,
4686 N32_RELAX_BR
| N32_RELAX_CALL
4690 BFD_RELOC_NDS32_HI20
,
4692 NDS32_RELAX_HINT_NONE
,
4694 N32_RELAX_BR
| N32_RELAX_SETHI
| N32_RELAX_ORI
| N32_RELAX_CALL
4698 BFD_RELOC_NDS32_HI20
,
4700 NDS32_RELAX_HINT_NONE
,
4702 N32_RELAX_SETHI
| N32_RELAX_ORI
| N32_RELAX_JUMP
4706 /* There is two kinds of variations of LONGJUMP5. One of them
4707 generate EMPTY relocation for converted INSN16 if needed.
4708 But we don't distinguish them here. */
4709 _dummy_first_bfd_reloc_code_real
,
4711 NDS32_RELAX_HINT_NONE
,
4713 N32_RELAX_BR
| N32_RELAX_JUMP
4717 BFD_RELOC_NDS32_HI20
,
4719 NDS32_RELAX_HINT_NONE
,
4721 N32_RELAX_SETHI
| N32_RELAX_ORI
| N32_RELAX_BR
| N32_RELAX_JUMP
4725 _dummy_first_bfd_reloc_code_real
,
4727 NDS32_RELAX_HINT_NONE
,
4729 N32_RELAX_MOVI
| N32_RELAX_BR
4732 /* LOADSTORE ADDRESS. */
4733 BFD_RELOC_NDS32_HI20
,
4735 NDS32_RELAX_HINT_LA
,
4737 N32_RELAX_SETHI
| N32_RELAX_ORI
4740 /* LOADSTORE ADDRESS. */
4741 BFD_RELOC_NDS32_HI20
,
4743 NDS32_RELAX_HINT_LS
,
4745 N32_RELAX_SETHI
| N32_RELAX_LSI
4750 /* Find the relaxation pattern according to instructions. */
4753 nds32_find_reloc_table (struct nds32_relocs_pattern
*relocs_pattern
,
4754 struct nds32_relax_hint_table
*hint_info
)
4756 unsigned int opcode
, seq_size
;
4757 enum nds32_br_range range
;
4758 struct nds32_relocs_pattern
*pattern
, *hi_pattern
= NULL
;
4759 const char *opc
= NULL
;
4760 relax_info_t
*relax_info
= NULL
;
4761 nds32_relax_fixup_info_t
*fixup_info
, *hint_fixup
;
4762 enum nds32_relax_hint_type hint_type
= NDS32_RELAX_HINT_NONE
;
4763 struct nds32_relax_hint_table
*table_ptr
;
4764 uint32_t *code_seq
, *hint_code
;
4765 enum nds32_insn_type relax_type
= 0;
4766 struct nds32_hint_map
*map_ptr
= hint_map
;
4768 const char *check_insn
[] =
4769 { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" };
4771 /* TODO: PLT GOT. */
4772 /* Traverse all pattern instruction and set flag. */
4773 pattern
= relocs_pattern
;
4776 if (pattern
->opcode
->isize
== 4)
4778 /* 4 byte instruction. */
4779 opcode
= N32_OP6 (pattern
->opcode
->value
);
4783 hi_pattern
= pattern
;
4784 relax_type
|= N32_RELAX_SETHI
;
4787 relax_type
|= N32_RELAX_MEM
;
4790 relax_type
|= N32_RELAX_ORI
;
4795 relax_type
|= N32_RELAX_BR
;
4798 relax_type
|= N32_RELAX_MOVI
;
4810 relax_type
|= N32_RELAX_LSI
;
4813 if (__GF (pattern
->opcode
->value
, 0, 1) == 1)
4814 relax_type
|= N32_RELAX_CALL
;
4816 relax_type
|= N32_RELAX_JUMP
;
4819 if (__GF (pattern
->opcode
->value
, 24, 1) == 1)
4820 relax_type
|= N32_RELAX_CALL
;
4822 relax_type
|= N32_RELAX_JUMP
;
4825 as_warn (_("relax hint unrecognized instruction: line %d."),
4826 pattern
->frag
->fr_line
);
4832 /* 2 byte instruction. Compare by opcode name because the opcode of
4833 2byte instruction is not regular. */
4834 for (i
= 0; i
< sizeof (check_insn
) / sizeof (check_insn
[0]); i
++)
4836 if (strcmp (pattern
->opcode
->opcode
, check_insn
[i
]) == 0)
4838 relax_type
|= N32_RELAX_BR
;
4842 if (strcmp (pattern
->opcode
->opcode
, "movi55") == 0)
4843 relax_type
|= N32_RELAX_MOVI
;
4845 pattern
= pattern
->next
;
4848 /* Analysis instruction flag to choose relaxation table. */
4849 while (map_ptr
->insn_list
!= 0)
4851 if (map_ptr
->insn_list
== relax_type
4853 || (hi_pattern
->fixP
4854 && hi_pattern
->fixP
->fx_r_type
== map_ptr
->hi_type
)))
4857 hint_type
= map_ptr
->hint_type
;
4858 range
= map_ptr
->range
;
4864 if (map_ptr
->insn_list
== 0)
4866 as_warn (_("Can not find match relax hint. Line: %d"),
4867 relocs_pattern
->frag
->fr_line
);
4871 /* Get the match table. */
4874 /* Branch relax pattern. */
4875 relax_info
= hash_find (nds32_relax_info_hash
, opc
);
4878 fixup_info
= relax_info
->relax_fixup
[range
];
4879 code_seq
= relax_info
->relax_code_seq
[range
];
4880 seq_size
= relax_info
->relax_code_size
[range
];
4884 /* Load-store relax pattern. */
4885 table_ptr
= relax_ls_table
;
4886 while (table_ptr
->main_type
!= 0)
4888 if (table_ptr
->main_type
== hint_type
)
4890 fixup_info
= table_ptr
->relax_fixup
;
4891 code_seq
= table_ptr
->relax_code_seq
;
4892 seq_size
= table_ptr
->relax_code_size
;
4897 if (table_ptr
->main_type
== 0)
4903 hint_fixup
= hint_info
->relax_fixup
;
4904 hint_code
= hint_info
->relax_code_seq
;
4905 hint_info
->relax_code_size
= seq_size
;
4907 while (fixup_info
->size
!= 0)
4909 if (fixup_info
->ramp
& NDS32_HINT
)
4911 memcpy (hint_fixup
, fixup_info
, sizeof (nds32_relax_fixup_info_t
));
4916 /* Clear final relocation. */
4917 memset (hint_fixup
, 0, sizeof (nds32_relax_fixup_info_t
));
4918 /* Copy code sequence. */
4919 memcpy (hint_code
, code_seq
, seq_size
);
4923 /* Because there are a lot of variant of load-store, check
4924 all these type here. */
4926 #define CLEAN_REG(insn) ((insn) & 0xff0003ff)
4928 nds32_match_hint_insn (struct nds32_opcode
*opcode
, uint32_t seq
)
4930 const char *check_insn
[] =
4931 { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" };
4932 uint32_t insn
= opcode
->value
;
4935 insn
= CLEAN_REG (opcode
->value
);
4942 /* In relocation_table, it regards instruction LBI as representation
4943 of all the NDS32_RELAX_HINT_LS pattern. */
4944 if (insn
== OP6 (LBI
) || insn
== OP6 (SBI
) || insn
== OP6 (LBSI
)
4945 || insn
== OP6 (LHI
) || insn
== OP6 (SHI
) || insn
== OP6 (LHSI
)
4946 || insn
== OP6 (LWI
) || insn
== OP6 (SWI
)
4947 || insn
== OP6 (LWC
) || insn
== OP6 (SWC
))
4951 /* This is for LONGCALL5 and LONGCALL6. */
4952 if (insn
== OP6 (BR2
))
4956 /* This is for LONGJUMP5 and LONGJUMP6. */
4957 if (opcode
->isize
== 4
4958 && (insn
== OP6 (BR1
) || insn
== OP6 (BR2
) || insn
== OP6 (BR3
)))
4960 else if (opcode
->isize
== 2)
4962 for (i
= 0; i
< sizeof (check_insn
) / sizeof (check_insn
[0]); i
++)
4963 if (strcmp (opcode
->opcode
, check_insn
[i
]) == 0)
4968 /* This is for LONGJUMP7. */
4969 if (opcode
->isize
== 2 && strcmp (opcode
->opcode
, "movi55") == 0)
4976 /* Append relax relocation for link time relaxing. */
4979 nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED
, void *value
)
4981 struct nds32_relocs_pattern
*relocs_pattern
=
4982 (struct nds32_relocs_pattern
*) value
;
4983 struct nds32_relocs_pattern
*pattern_temp
, *pattern_now
;
4984 symbolS
*sym
, *hi_sym
= NULL
;
4987 segT seg_bak
= now_seg
;
4988 frchainS
*frchain_bak
= frchain_now
;
4989 struct nds32_relax_hint_table hint_info
;
4990 nds32_relax_fixup_info_t
*hint_fixup
, *fixup_now
;
4992 offsetT branch_offset
;
4995 unsigned int ptr_offset
, hint_count
, relax_code_size
, count
= 0;
4996 uint32_t *code_seq
, code_insn
;
5000 if (!relocs_pattern
)
5003 if (!nds32_find_reloc_table (relocs_pattern
, &hint_info
))
5006 /* Save symbol for some EMPTY relocation using. */
5007 pattern_now
= relocs_pattern
;
5010 if (pattern_now
->opcode
->value
== OP6 (SETHI
))
5012 hi_sym
= pattern_now
->sym
;
5015 pattern_now
= pattern_now
->next
;
5018 /* Inserting fix up must specify now_seg or frchain_now. */
5019 now_seg
= relocs_pattern
->seg
;
5020 frchain_now
= relocs_pattern
->frchain
;
5021 fragP
= relocs_pattern
->frag
;
5022 branch_offset
= fragP
->fr_offset
;
5024 hint_fixup
= hint_info
.relax_fixup
;
5025 code_seq
= hint_info
.relax_code_seq
;
5026 relax_code_size
= hint_info
.relax_code_size
;
5027 pattern_now
= relocs_pattern
;
5029 /* Insert relaxation. */
5030 exp
.X_op
= O_symbol
;
5034 /* Choose the match fixup by instruction. */
5035 code_insn
= CLEAN_REG (*(code_seq
+ count
));
5036 if (!nds32_match_hint_insn (pattern_now
->opcode
, code_insn
))
5039 code_insn
= CLEAN_REG (*(code_seq
+ count
));
5041 while (!nds32_match_hint_insn (pattern_now
->opcode
, code_insn
))
5044 if (count
>= relax_code_size
/ 4)
5046 as_bad (_("Internal error: Relax hint error. %s: %x"),
5047 now_seg
->name
, pattern_now
->opcode
->value
);
5050 code_insn
= CLEAN_REG (*(code_seq
+ count
));
5053 fragP
= pattern_now
->frag
;
5054 sym
= pattern_now
->sym
;
5055 branch_offset
= fragP
->fr_offset
;
5057 where
= pattern_now
->where
;
5058 /* Find the instruction map fix. */
5059 fixup_now
= hint_fixup
;
5060 while (fixup_now
->offset
!= offset
)
5063 if (fixup_now
->size
== 0)
5066 /* This element is without relaxation relocation. */
5067 if (fixup_now
->size
== 0)
5069 pattern_now
= pattern_now
->next
;
5072 fixup_size
= fixup_now
->size
;
5074 /* Insert all fixup. */
5075 while (fixup_size
!= 0 && fixup_now
->offset
== offset
)
5077 /* Set the real instruction size in element. */
5078 fixup_size
= pattern_now
->opcode
->isize
;
5079 pcrel
= ((fixup_now
->ramp
& NDS32_PCREL
) != 0) ? 1 : 0;
5080 if (fixup_now
->ramp
& NDS32_FIX
)
5082 /* Convert original relocation. */
5083 pattern_now
->fixP
->fx_r_type
= fixup_now
->r_type
;
5086 else if ((fixup_now
->ramp
& NDS32_PTR
) != 0)
5088 /* This relocation has to point to another instruction. Make
5089 sure each resolved relocation has to be pointed. */
5090 pattern_temp
= relocs_pattern
;
5091 /* All instruction in relax_table should be 32-bit. */
5092 hint_count
= hint_info
.relax_code_size
/ 4;
5093 code_insn
= CLEAN_REG (*(code_seq
+ hint_count
- 1));
5094 while (pattern_temp
)
5096 /* Point to every resolved relocation. */
5097 if (nds32_match_hint_insn (pattern_temp
->opcode
, code_insn
))
5100 pattern_temp
->where
- pattern_temp
->frag
->fr_literal
;
5101 exp
.X_add_symbol
= symbol_temp_new (now_seg
, ptr_offset
,
5102 pattern_temp
->frag
);
5103 exp
.X_add_number
= 0;
5105 fix_new_exp (fragP
, where
- fragP
->fr_literal
,
5106 fixup_size
, &exp
, 0, fixup_now
->r_type
);
5107 fixP
->fx_addnumber
= fixP
->fx_offset
;
5109 pattern_temp
= pattern_temp
->next
;
5113 else if (fixup_now
->ramp
& NDS32_ADDEND
)
5115 range
= nds32_elf_sethi_range (relocs_pattern
);
5116 if (range
== NDS32_LOADSTORE_NONE
)
5118 as_bad (_("Internal error: Range error. %s"), now_seg
->name
);
5121 exp
.X_add_symbol
= abs_section_sym
;
5122 exp
.X_add_number
= SET_ADDEND (4, 0, optimize
, enable_16bit
);
5123 exp
.X_add_number
|= ((range
& 0x3f) << 8);
5125 else if ((fixup_now
->ramp
& NDS32_ABS
) != 0)
5127 /* This is a tag relocation. */
5128 exp
.X_add_symbol
= abs_section_sym
;
5129 exp
.X_add_number
= 0;
5131 else if ((fixup_now
->ramp
& NDS32_INSN16
) != 0)
5135 /* This is a tag relocation. */
5136 exp
.X_add_symbol
= abs_section_sym
;
5137 exp
.X_add_number
= 0;
5139 else if ((fixup_now
->ramp
& NDS32_SYM
) != 0)
5141 /* For EMPTY relocation save the true symbol. */
5142 exp
.X_add_symbol
= hi_sym
;
5143 exp
.X_add_number
= branch_offset
;
5147 exp
.X_add_symbol
= sym
;
5148 exp
.X_add_number
= branch_offset
;
5151 if (fixup_size
!= 0)
5153 fixP
= fix_new_exp (fragP
, where
- fragP
->fr_literal
, fixup_size
,
5154 &exp
, pcrel
, fixup_now
->r_type
);
5155 fixP
->fx_addnumber
= fixP
->fx_offset
;
5158 fixup_size
= fixup_now
->size
;
5160 if (count
< relax_code_size
/ 4)
5162 pattern_now
= pattern_now
->next
;
5167 frchain_now
= frchain_bak
;
5170 /* Check instruction if it can be used for the baseline. */
5173 nds32_check_insn_available (struct nds32_asm_insn insn
, const char *str
)
5175 int attr
= insn
.attr
& ATTR_ALL
;
5176 static int baseline_isa
= 0;
5177 /* No isa setting or all isa can use. */
5178 if (attr
== 0 || attr
== ATTR_ALL
)
5181 if (baseline_isa
== 0)
5183 /* Map option baseline and instruction attribute. */
5184 switch (nds32_baseline
)
5187 baseline_isa
= ATTR (ISA_V2
);
5190 baseline_isa
= ATTR (ISA_V3
);
5193 baseline_isa
= ATTR (ISA_V3M
);
5198 if ((baseline_isa
& attr
) == 0)
5200 as_bad (_("Instruction %s not supported in the baseline."), str
);
5206 /* Stub of machine dependent. */
5209 md_assemble (char *str
)
5211 struct nds32_asm_insn insn
;
5214 struct nds32_pseudo_opcode
*popcode
;
5215 const struct nds32_field
*fld
= NULL
;
5218 struct nds32_relocs_pattern
*relocs_temp
;
5221 int label
= label_exist
;
5223 popcode
= nds32_lookup_pseudo_opcode (str
);
5224 /* Note that we need to check 'verbatim' and
5225 'opcode->physical_op'. If the assembly content is generated by
5226 compiler and this opcode is a physical instruction, there is no
5227 need to perform pseudo instruction expansion/transformation. */
5228 if (popcode
&& !(verbatim
&& popcode
->physical_op
))
5230 pseudo_opcode
= TRUE
;
5231 nds32_pseudo_opcode_wrapper (str
, popcode
);
5232 pseudo_opcode
= FALSE
;
5233 nds32_elf_append_relax_relocs (NULL
, relocs_list
);
5235 /* Free pseudo list. */
5236 relocs_temp
= relocs_list
;
5239 relocs_list
= relocs_list
->next
;
5241 relocs_temp
= relocs_list
;
5249 asm_desc
.result
= NASM_OK
;
5250 nds32_assemble (&asm_desc
, &insn
, str
);
5252 switch (asm_desc
.result
)
5254 case NASM_ERR_UNKNOWN_OP
:
5255 as_bad (_("Unrecognized opcode, %s."), str
);
5257 case NASM_ERR_SYNTAX
:
5258 as_bad (_("Incorrect syntax, %s."), str
);
5260 case NASM_ERR_OPERAND
:
5261 as_bad (_("Unrecognized operand/register, %s."), str
);
5263 case NASM_ERR_OUT_OF_RANGE
:
5264 as_bad (_("Operand out of range, %s."), str
);
5266 case NASM_ERR_REG_REDUCED
:
5267 as_bad (_("Prohibited register used for reduced-register, %s."), str
);
5269 case NASM_ERR_JUNK_EOL
:
5270 as_bad (_("Junk at end of line, %s."), str
);
5274 gas_assert (insn
.opcode
);
5276 nds32_set_elf_flags_by_insn (&insn
);
5278 gas_assert (insn
.opcode
->isize
== 4 || insn
.opcode
->isize
== 2);
5280 if (!nds32_check_insn_available (insn
, str
))
5283 /* Make sure the beginning of text being 2-byte align. */
5284 nds32_adjust_label (1);
5286 /* Try to allocate the max size to guarantee relaxable same branch
5287 instructions in the same fragment. */
5288 frag_grow (NDS32_MAXCHAR
);
5290 if (fld
&& (insn
.attr
& NASM_ATTR_BRANCH
)
5291 && (pseudo_opcode
|| (insn
.opcode
->value
!= INSN_JAL
5292 && insn
.opcode
->value
!= INSN_J
))
5293 && (!verbatim
|| pseudo_opcode
))
5295 /* User assembly code branch relax for it. */
5296 /* If fld is not NULL, it is a symbol. */
5297 /* Branch must relax to proper pattern in user assembly code exclude
5298 J and JAL. Keep these two in original type for users which wants
5299 to keep their size be fixed. In general, assembler does not convert
5300 instruction generated by compiler. But jump instruction may be
5301 truncated in text virtual model. For workaround, compiler generate
5302 pseudo jump to fix this issue currently. */
5304 /* Get branch range type. */
5305 dwarf2_emit_insn (0);
5306 enum nds32_br_range range_type
;
5309 range_type
= get_range_type (fld
);
5311 out
= frag_var (rs_machine_dependent
, NDS32_MAXCHAR
,
5312 0, /* VAR is un-used. */
5313 range_type
, /* SUBTYPE is used as range type. */
5314 pexp
->X_add_symbol
, pexp
->X_add_number
, 0);
5316 fragP
->fr_fix
+= insn
.opcode
->isize
;
5317 fragP
->tc_frag_data
.opcode
= insn
.opcode
;
5318 fragP
->tc_frag_data
.insn
= insn
.insn
;
5319 if (insn
.opcode
->isize
== 4)
5320 bfd_putb32 (insn
.insn
, out
);
5321 else if (insn
.opcode
->isize
== 2)
5322 bfd_putb16 (insn
.insn
, out
);
5323 fragP
->tc_frag_data
.flag
|= NDS32_FRAG_BRANCH
;
5325 /* md_convert_frag will insert relocations. */
5327 else if (!relaxing
&& enable_16bit
&& (optimize
|| optimize_for_space
)
5328 && ((!fld
&& !verbatim
&& insn
.opcode
->isize
== 4
5329 && nds32_convert_32_to_16 (stdoutput
, insn
.insn
, &insn_16
, NULL
))
5330 || (insn
.opcode
->isize
== 2
5331 && nds32_convert_16_to_32 (stdoutput
, insn
.insn
, NULL
))))
5333 /* Record this one is relaxable. */
5335 dwarf2_emit_insn (0);
5338 out
= frag_var (rs_machine_dependent
,
5339 4, /* Max size is 32-bit instruction. */
5340 0, /* VAR is un-used. */
5341 0, pexp
->X_add_symbol
, pexp
->X_add_number
, 0);
5342 fragP
->tc_frag_data
.flag
|= NDS32_FRAG_RELAXABLE_BRANCH
;
5345 out
= frag_var (rs_machine_dependent
,
5346 4, /* Max size is 32-bit instruction. */
5347 0, /* VAR is un-used. */
5349 fragP
->tc_frag_data
.flag
|= NDS32_FRAG_RELAXABLE
;
5350 fragP
->tc_frag_data
.opcode
= insn
.opcode
;
5351 fragP
->tc_frag_data
.insn
= insn
.insn
;
5354 /* In original, we don't relax the instruction with label on it,
5355 but this may cause some redundant nop16. Therefore, tag this
5356 relaxable instruction and relax it carefully. */
5358 fragP
->tc_frag_data
.flag
|= NDS32_FRAG_LABEL
;
5360 if (insn
.opcode
->isize
== 4)
5361 bfd_putb16 (insn_16
, out
);
5362 else if (insn
.opcode
->isize
== 2)
5363 bfd_putb16 (insn
.insn
, out
);
5366 else if ((verbatim
|| !relaxing
) && optimize
&& label
)
5368 /* This instruction is with label. */
5370 out
= frag_var (rs_machine_dependent
, insn
.opcode
->isize
,
5371 0, 0, NULL
, 0, NULL
);
5372 /* If this instruction is branch target, it is not relaxable. */
5373 fragP
->tc_frag_data
.flag
= NDS32_FRAG_LABEL
;
5374 fragP
->tc_frag_data
.opcode
= insn
.opcode
;
5375 fragP
->tc_frag_data
.insn
= insn
.insn
;
5376 fragP
->fr_fix
+= insn
.opcode
->isize
;
5377 if (insn
.opcode
->isize
== 4)
5379 exp
.X_op
= O_symbol
;
5380 exp
.X_add_symbol
= abs_section_sym
;
5381 exp
.X_add_number
= 0;
5382 fixP
= fix_new_exp (fragP
, fragP
->fr_fix
- 4, 0, &exp
,
5383 0, BFD_RELOC_NDS32_LABEL
);
5385 fragP
->tc_frag_data
.flag
= NDS32_FRAG_ALIGN
;
5389 out
= frag_more (insn
.opcode
->isize
);
5391 if (insn
.opcode
->isize
== 4)
5392 bfd_putb32 (insn
.insn
, out
);
5393 if (insn
.opcode
->isize
== 2)
5394 bfd_putb16 (insn
.insn
, out
);
5396 dwarf2_emit_insn (insn
.opcode
->isize
);
5398 /* Compiler generating code and user assembly pseudo load-store, insert
5401 fixP
= nds32_elf_record_fixup_exp (fragP
, str
, fld
, pexp
, out
, &insn
);
5402 /* Build relaxation pattern when relaxing is enable. */
5404 nds32_elf_build_relax_relation (fixP
, pexp
, out
, insn
.opcode
, fragP
, fld
);
5407 /* md_macro_start */
5410 nds32_macro_start (void)
5417 nds32_macro_info (void *info ATTRIBUTE_UNUSED
)
5424 nds32_macro_end (void)
5428 /* GAS will call this function with one argument, an expressionS pointer, for
5429 any expression that can not be recognized. When the function is called,
5430 input_line_pointer will point to the start of the expression. */
5433 md_operand (expressionS
*expressionP
)
5435 if (*input_line_pointer
== '#')
5437 input_line_pointer
++;
5438 expression (expressionP
);
5442 /* GAS will call this function for each section at the end of the assembly, to
5443 permit the CPU back end to adjust the alignment of a section. The function
5444 must take two arguments, a segT for the section and a valueT for the size of
5445 the section, and return a valueT for the rounded size. */
5448 md_section_align (segT segment
, valueT size
)
5450 int align
= bfd_get_section_alignment (stdoutput
, segment
);
5452 return ((size
+ (1 << align
) - 1) & -(1 << align
));
5455 /* GAS will call this function when a symbol table lookup fails, before it
5456 creates a new symbol. Typically this would be used to supply symbols whose
5457 name or value changes dynamically, possibly in a context sensitive way.
5458 Predefined symbols with fixed values, such as register names or condition
5459 codes, are typically entered directly into the symbol table when md_begin
5460 is called. One argument is passed, a char * for the symbol. */
5463 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
5469 nds32_calc_branch_offset (segT segment
, fragS
*fragP
,
5470 long stretch ATTRIBUTE_UNUSED
,
5471 relax_info_t
*relax_info
,
5472 enum nds32_br_range branch_range_type
)
5474 struct nds32_opcode
*opcode
= fragP
->tc_frag_data
.opcode
;
5475 symbolS
*branch_symbol
= fragP
->fr_symbol
;
5476 offsetT branch_offset
= fragP
->fr_offset
;
5477 offsetT branch_target_address
;
5478 offsetT branch_insn_address
;
5481 if ((S_GET_SEGMENT (branch_symbol
) != segment
)
5482 || S_IS_WEAK (branch_symbol
))
5484 /* The symbol is not in the SEGMENT. It could be far far away. */
5485 offset
= 0x80000000;
5489 /* Calculate symbol-to-instruction offset. */
5490 branch_target_address
= S_GET_VALUE (branch_symbol
) + branch_offset
;
5491 /* If the destination symbol is beyond current frag address,
5492 STRETCH will take effect to symbol's position. */
5493 if (S_GET_VALUE (branch_symbol
) > fragP
->fr_address
)
5494 branch_target_address
+= stretch
;
5496 branch_insn_address
= fragP
->fr_address
+ fragP
->fr_fix
;
5497 branch_insn_address
-= opcode
->isize
;
5499 /* Update BRANCH_INSN_ADDRESS to relaxed position. */
5500 branch_insn_address
+= (relax_info
->relax_code_size
[branch_range_type
]
5501 - relax_info
->relax_branch_isize
[branch_range_type
]);
5503 offset
= branch_target_address
- branch_insn_address
;
5509 static enum nds32_br_range
5510 nds32_convert_to_range_type (long offset
)
5512 enum nds32_br_range range_type
;
5514 if (-(0x100) <= offset
&& offset
< 0x100) /* 256 bytes */
5515 range_type
= BR_RANGE_S256
;
5516 else if (-(0x4000) <= offset
&& offset
< 0x4000) /* 16K bytes */
5517 range_type
= BR_RANGE_S16K
;
5518 else if (-(0x10000) <= offset
&& offset
< 0x10000) /* 64K bytes */
5519 range_type
= BR_RANGE_S64K
;
5520 else if (-(0x1000000) <= offset
&& offset
< 0x1000000) /* 16M bytes */
5521 range_type
= BR_RANGE_S16M
;
5523 range_type
= BR_RANGE_U4G
;
5528 /* Set instruction register mask. */
5531 nds32_elf_get_set_cond (relax_info_t
*relax_info
, int offset
, uint32_t *insn
,
5532 uint32_t ori_insn
, int range
)
5534 nds32_cond_field_t
*cond_fields
= relax_info
->cond_field
;
5535 nds32_cond_field_t
*code_seq_cond
= relax_info
->relax_code_condition
[range
];
5539 /* The instruction has conditions. Collect condition values. */
5540 while (code_seq_cond
[i
].bitmask
!= 0)
5542 if (offset
== code_seq_cond
[i
].offset
)
5544 mask
= (ori_insn
>> cond_fields
[i
].bitpos
) & cond_fields
[i
].bitmask
;
5546 if (cond_fields
[i
].signed_extend
)
5547 mask
= (mask
^ ((cond_fields
[i
].bitmask
+ 1) >> 1)) -
5548 ((cond_fields
[i
].bitmask
+ 1) >> 1);
5549 *insn
|= (mask
& code_seq_cond
[i
].bitmask
) << code_seq_cond
[i
].bitpos
;
5557 nds32_relax_branch_instructions (segT segment
, fragS
*fragP
,
5558 long stretch ATTRIBUTE_UNUSED
,
5561 enum nds32_br_range branch_range_type
;
5562 struct nds32_opcode
*opcode
= fragP
->tc_frag_data
.opcode
;
5564 enum nds32_br_range real_range_type
;
5566 relax_info_t
*relax_info
;
5573 int code_seq_offset
;
5575 /* Replace with gas_assert (fragP->fr_symbol != NULL); */
5576 if (fragP
->fr_symbol
== NULL
)
5579 /* If frag_var is not enough room, the previous frag is fr_full and with
5580 opcode. The new one is rs_dependent but without opcode. */
5584 relax_info
= hash_find (nds32_relax_info_hash
, opcode
->opcode
);
5586 if (relax_info
== NULL
)
5590 branch_range_type
= relax_info
->br_range
;
5592 branch_range_type
= fragP
->fr_subtype
;
5594 offset
= nds32_calc_branch_offset (segment
, fragP
, stretch
,
5595 relax_info
, branch_range_type
);
5597 real_range_type
= nds32_convert_to_range_type (offset
);
5599 /* If actual range is equal to instruction jump range, do nothing. */
5600 if (real_range_type
== branch_range_type
)
5603 /* Find out proper relaxation code sequence. */
5604 for (i
= BR_RANGE_S256
; i
< BR_RANGE_NUM
; i
++)
5606 if (real_range_type
<= (unsigned int) i
)
5609 diff
= relax_info
->relax_code_size
[i
] - opcode
->isize
;
5611 diff
= relax_info
->relax_code_size
[i
]
5612 - relax_info
->relax_code_size
[branch_range_type
];
5614 /* If the instruction could be converted to 16-bits,
5615 minus the difference. */
5616 code_seq_offset
= 0;
5619 code_seq_size
= relax_info
->relax_code_size
[i
];
5620 code_seq
= relax_info
->relax_code_seq
[i
];
5621 while (code_seq_offset
< code_seq_size
)
5624 if (insn
& 0x80000000) /* 16-bits instruction. */
5628 else /* 32-bits instruction. */
5632 while (relax_info
->relax_fixup
[i
][k
].size
!=0
5633 && relax_info
->relax_fixup
[i
][k
].offset
< code_seq_offset
)
5637 code_seq_offset
+= insn_size
;
5641 /* Update fr_subtype to new NDS32_BR_RANGE. */
5642 fragP
->fr_subtype
= i
;
5647 return diff
+ adjust
;
5650 /* Adjust relaxable frag till current frag. */
5653 nds32_adjust_relaxable_frag (fragS
*startP
, fragS
*fragP
)
5656 if (startP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
)
5661 startP
->tc_frag_data
.flag
^= NDS32_FRAG_RELAXED
;
5665 startP
= startP
->fr_next
;
5668 startP
->fr_address
+= adj
;
5669 if (startP
== fragP
)
5677 nds32_get_align (addressT address
, int align
)
5679 addressT mask
, new_address
;
5681 mask
= ~((~0U) << align
);
5682 new_address
= (address
+ mask
) & (~mask
);
5683 return (new_address
- address
);
5686 /* Check the prev_frag is legal. */
5688 invalid_prev_frag (fragS
* fragP
, fragS
**prev_frag
)
5691 fragS
*frag_start
= *prev_frag
;
5696 if (frag_start
->last_fr_address
>= fragP
->last_fr_address
)
5702 fragS
*frag_t
= *prev_frag
;
5703 while (frag_t
!= fragP
)
5705 if (frag_t
->fr_type
== rs_align
5706 || frag_t
->fr_type
== rs_align_code
5707 || frag_t
->fr_type
== rs_align_test
)
5709 /* Relax instruction can not walk across label. */
5710 if (frag_t
->tc_frag_data
.flag
& NDS32_FRAG_LABEL
)
5715 /* Relax previous relaxable to align rs_align frag. */
5716 address
= frag_t
->fr_address
+ frag_t
->fr_fix
;
5717 addressT offset
= nds32_get_align (address
, (int) frag_t
->fr_offset
);
5720 /* If there is label on the prev_frag, check if it is aligned. */
5721 if (!((*prev_frag
)->tc_frag_data
.flag
& NDS32_FRAG_LABEL
)
5722 || (((*prev_frag
)->fr_address
+ (*prev_frag
)->fr_fix
- 2 )
5724 nds32_adjust_relaxable_frag (*prev_frag
, frag_t
);
5729 frag_t
= frag_t
->fr_next
;
5732 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_ALIGN
)
5734 address
= fragP
->fr_address
;
5735 addressT offset
= nds32_get_align (address
, 2);
5738 /* If there is label on the prev_frag, check if it is aligned. */
5739 if (!((*prev_frag
)->tc_frag_data
.flag
& NDS32_FRAG_LABEL
)
5740 || (((*prev_frag
)->fr_address
+ (*prev_frag
)->fr_fix
- 2 )
5742 nds32_adjust_relaxable_frag (*prev_frag
, fragP
);
5752 nds32_relax_frag (segT segment
, fragS
*fragP
, long stretch ATTRIBUTE_UNUSED
)
5754 /* Currently, there are two kinds of relaxation in nds32 assembler.
5756 2. relax for 32-bits to 16-bits */
5758 static fragS
*prev_frag
= NULL
;
5761 invalid_prev_frag (fragP
, &prev_frag
);
5763 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_BRANCH
)
5764 adjust
= nds32_relax_branch_instructions (segment
, fragP
, stretch
, 0);
5765 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_LABEL
)
5767 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXABLE
5768 && (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
) == 0)
5769 /* Here is considered relaxed case originally. But it may cause
5770 an endless loop when relaxing. Once the instruction is relaxed,
5771 it can not be undone. */
5777 /* This function returns an initial guess of the length by which a fragment
5778 must grow to hold a branch to reach its destination. Also updates
5779 fr_type/fr_subtype as necessary.
5781 It is called just before doing relaxation. Any symbol that is now undefined
5782 will not become defined. The guess for fr_var is ACTUALLY the growth beyond
5783 fr_fix. Whatever we do to grow fr_fix or fr_var contributes to our returned
5784 value. Although it may not be explicit in the frag, pretend fr_var starts
5788 md_estimate_size_before_relax (fragS
*fragP
, segT segment
)
5790 /* Currently, there are two kinds of relaxation in nds32 assembler.
5792 2. relax for 32-bits to 16-bits */
5794 /* Save previous relaxable frag. */
5795 static fragS
*prev_frag
= NULL
;
5798 invalid_prev_frag (fragP
, &prev_frag
);
5800 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_BRANCH
)
5801 adjust
= nds32_relax_branch_instructions (segment
, fragP
, 0, 1);
5802 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_LABEL
)
5804 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
)
5806 else if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXABLE
)
5812 /* GAS will call this for each rs_machine_dependent fragment. The instruction
5813 is completed using the data from the relaxation pass. It may also create any
5814 necessary relocations.
5816 *FRAGP has been relaxed to its final size, and now needs to have the bytes
5817 inside it modified to conform to the new size. It is called after relaxation
5820 fragP->fr_type == rs_machine_dependent.
5821 fragP->fr_subtype is the subtype of what the address relaxed to. */
5824 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, segT sec
, fragS
*fragP
)
5826 /* Convert branch relaxation instructions. */
5827 symbolS
*branch_symbol
= fragP
->fr_symbol
;
5828 offsetT branch_offset
= fragP
->fr_offset
;
5829 enum nds32_br_range branch_range_type
= fragP
->fr_subtype
;
5830 struct nds32_opcode
*opcode
= fragP
->tc_frag_data
.opcode
;
5831 uint32_t origin_insn
= fragP
->tc_frag_data
.insn
;
5832 relax_info_t
*relax_info
;
5835 int addend ATTRIBUTE_UNUSED
;
5836 offsetT branch_target_address
, branch_insn_address
;
5841 int code_size
, insn_size
, offset
, fixup_size
;
5842 int buf_offset
, pcrel
;
5845 nds32_relax_fixup_info_t fixup_info
[MAX_RELAX_FIX
];
5846 /* Save the 1st instruction is converted to 16 bit or not. */
5847 unsigned int branch_size
;
5849 /* Replace with gas_assert (branch_symbol != NULL); */
5850 if (branch_symbol
== NULL
&& !(fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
))
5853 /* If frag_var is not enough room, the previous frag is fr_full and with
5854 opcode. The new one is rs_dependent but without opcode. */
5858 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXABLE_BRANCH
)
5860 relax_info
= hash_find (nds32_relax_info_hash
, opcode
->opcode
);
5862 if (relax_info
== NULL
)
5866 while (i
< BR_RANGE_NUM
5867 && relax_info
->relax_code_size
[i
]
5868 != (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
? 4 : 2))
5871 if (i
>= BR_RANGE_NUM
)
5872 as_bad ("Internal error: Cannot find relocation of"
5873 "relaxable branch.");
5875 exp
.X_op
= O_symbol
;
5876 exp
.X_add_symbol
= branch_symbol
;
5877 exp
.X_add_number
= branch_offset
;
5878 pcrel
= ((relax_info
->relax_fixup
[i
][0].ramp
& NDS32_PCREL
) != 0) ? 1 : 0;
5879 fr_where
= fragP
->fr_fix
- 2;
5880 fixP
= fix_new_exp (fragP
, fr_where
, relax_info
->relax_fixup
[i
][0].size
,
5881 &exp
, pcrel
, relax_info
->relax_fixup
[i
][0].r_type
);
5882 fixP
->fx_addnumber
= fixP
->fx_offset
;
5884 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
)
5886 insn_16
= fragP
->tc_frag_data
.insn
;
5887 nds32_convert_16_to_32 (stdoutput
, insn_16
, &insn
);
5888 fr_buffer
= fragP
->fr_literal
+ fr_where
;
5890 exp
.X_op
= O_symbol
;
5891 exp
.X_add_symbol
= abs_section_sym
;
5892 exp
.X_add_number
= 0;
5893 fix_new_exp (fragP
, fr_where
, 4,
5894 &exp
, 0, BFD_RELOC_NDS32_INSN16
);
5895 number_to_chars_bigendian (fr_buffer
, insn
, 4);
5898 else if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
)
5900 if (fragP
->tc_frag_data
.opcode
->isize
== 2)
5902 insn_16
= fragP
->tc_frag_data
.insn
;
5903 nds32_convert_16_to_32 (stdoutput
, insn_16
, &insn
);
5906 insn
= fragP
->tc_frag_data
.insn
;
5908 fr_where
= fragP
->fr_fix
- 4;
5909 fr_buffer
= fragP
->fr_literal
+ fr_where
;
5910 exp
.X_op
= O_symbol
;
5911 exp
.X_add_symbol
= abs_section_sym
;
5912 exp
.X_add_number
= 0;
5913 fix_new_exp (fragP
, fr_where
, 4, &exp
, 0,
5914 BFD_RELOC_NDS32_INSN16
);
5915 number_to_chars_bigendian (fr_buffer
, insn
, 4);
5917 else if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_BRANCH
)
5919 /* Branch instruction adjust and append relocations. */
5920 relax_info
= hash_find (nds32_relax_info_hash
, opcode
->opcode
);
5922 if (relax_info
== NULL
)
5925 fr_where
= fragP
->fr_fix
- opcode
->isize
;
5926 fr_buffer
= fragP
->fr_literal
+ fr_where
;
5928 if ((S_GET_SEGMENT (branch_symbol
) != sec
)
5929 || S_IS_WEAK (branch_symbol
))
5931 if (fragP
->fr_offset
& 3)
5932 as_warn (_("Addend to unresolved symbol is not on word boundary."));
5937 /* Calculate symbol-to-instruction offset. */
5938 branch_target_address
= S_GET_VALUE (branch_symbol
) + branch_offset
;
5939 branch_insn_address
= fragP
->fr_address
+ fr_where
;
5940 addend
= (branch_target_address
- branch_insn_address
) >> 1;
5943 code_size
= relax_info
->relax_code_size
[branch_range_type
];
5944 code_seq
= relax_info
->relax_code_seq
[branch_range_type
];
5946 memcpy (fixup_info
, relax_info
->relax_fixup
[branch_range_type
],
5947 sizeof (fixup_info
));
5952 offset
= 0; /* code_seq offset */
5953 buf_offset
= 0; /* fr_buffer offset */
5954 while (offset
< code_size
)
5957 if (insn
& 0x80000000) /* 16-bits instruction. */
5959 insn
= (insn
>> 16) & 0xFFFF;
5962 else /* 32-bits instruction. */
5967 nds32_elf_get_set_cond (relax_info
, offset
, &insn
,
5968 origin_insn
, branch_range_type
);
5970 /* Try to convert to 16-bits instruction. Currently, only the first
5971 instruction in pattern can be converted. EX: bnez sethi ori jr,
5972 only bnez can be converted to 16 bit and ori can't. */
5974 while (fixup_info
[k
].size
!= 0
5975 && relax_info
->relax_fixup
[branch_range_type
][k
].offset
< offset
)
5978 number_to_chars_bigendian (fr_buffer
+ buf_offset
, insn
, insn_size
);
5979 buf_offset
+= insn_size
;
5981 offset
+= insn_size
;
5986 exp
.X_op
= O_symbol
;
5988 for (i
= 0; fixup_info
[i
].size
!= 0; i
++)
5990 fixup_size
= fixup_info
[i
].size
;
5991 pcrel
= ((fixup_info
[i
].ramp
& NDS32_PCREL
) != 0) ? 1 : 0;
5993 if ((fixup_info
[i
].ramp
& NDS32_CREATE_LABEL
) != 0)
5995 /* This is a reverse branch. */
5996 exp
.X_add_symbol
= symbol_temp_new (sec
, 0, fragP
->fr_next
);
5997 exp
.X_add_number
= 0;
5999 else if ((fixup_info
[i
].ramp
& NDS32_PTR
) != 0)
6001 /* This relocation has to point to another instruction. */
6002 branch_size
= fr_where
+ code_size
- 4;
6003 exp
.X_add_symbol
= symbol_temp_new (sec
, branch_size
, fragP
);
6004 exp
.X_add_number
= 0;
6006 else if ((fixup_info
[i
].ramp
& NDS32_ABS
) != 0)
6008 /* This is a tag relocation. */
6009 exp
.X_add_symbol
= abs_section_sym
;
6010 exp
.X_add_number
= 0;
6012 else if ((fixup_info
[i
].ramp
& NDS32_INSN16
) != 0)
6016 /* This is a tag relocation. */
6017 exp
.X_add_symbol
= abs_section_sym
;
6018 exp
.X_add_number
= 0;
6022 exp
.X_add_symbol
= branch_symbol
;
6023 exp
.X_add_number
= branch_offset
;
6026 if (fixup_info
[i
].r_type
!= 0)
6028 fixP
= fix_new_exp (fragP
, fr_where
+ fixup_info
[i
].offset
,
6029 fixup_size
, &exp
, pcrel
,
6030 fixup_info
[i
].r_type
);
6031 fixP
->fx_addnumber
= fixP
->fx_offset
;
6035 fragP
->fr_fix
= fr_where
+ buf_offset
;
6039 /* tc_frob_file_before_fix */
6042 nds32_frob_file_before_fix (void)
6047 nds32_relaxable_section (asection
*sec
)
6049 return ((sec
->flags
& SEC_DEBUGGING
) == 0
6050 && strcmp (sec
->name
, ".eh_frame") != 0);
6053 /* TC_FORCE_RELOCATION */
6055 nds32_force_relocation (fixS
* fix
)
6057 switch (fix
->fx_r_type
)
6059 case BFD_RELOC_NDS32_INSN16
:
6060 case BFD_RELOC_NDS32_LABEL
:
6061 case BFD_RELOC_NDS32_LONGCALL1
:
6062 case BFD_RELOC_NDS32_LONGCALL2
:
6063 case BFD_RELOC_NDS32_LONGCALL3
:
6064 case BFD_RELOC_NDS32_LONGJUMP1
:
6065 case BFD_RELOC_NDS32_LONGJUMP2
:
6066 case BFD_RELOC_NDS32_LONGJUMP3
:
6067 case BFD_RELOC_NDS32_LOADSTORE
:
6068 case BFD_RELOC_NDS32_9_FIXED
:
6069 case BFD_RELOC_NDS32_15_FIXED
:
6070 case BFD_RELOC_NDS32_17_FIXED
:
6071 case BFD_RELOC_NDS32_25_FIXED
:
6072 case BFD_RELOC_NDS32_9_PCREL
:
6073 case BFD_RELOC_NDS32_15_PCREL
:
6074 case BFD_RELOC_NDS32_17_PCREL
:
6075 case BFD_RELOC_NDS32_WORD_9_PCREL
:
6076 case BFD_RELOC_NDS32_10_UPCREL
:
6077 case BFD_RELOC_NDS32_25_PCREL
:
6078 case BFD_RELOC_NDS32_MINUEND
:
6079 case BFD_RELOC_NDS32_SUBTRAHEND
:
6085 case BFD_RELOC_NDS32_DIFF_ULEB128
:
6086 /* Linker should handle difference between two symbol. */
6087 return fix
->fx_subsy
!= NULL
6088 && nds32_relaxable_section (S_GET_SEGMENT (fix
->fx_addsy
));
6091 as_bad ("Double word for difference between two symbols "
6092 "is not supported across relaxation.");
6097 if (generic_force_reloc (fix
))
6100 return fix
->fx_pcrel
;
6103 /* TC_VALIDATE_FIX_SUB */
6106 nds32_validate_fix_sub (fixS
*fix
, segT add_symbol_segment
)
6108 segT sub_symbol_segment
;
6110 /* This code is referred from Xtensa. Check their implementation for
6113 /* Make sure both symbols are in the same segment, and that segment is
6114 "normal" and relaxable. */
6115 sub_symbol_segment
= S_GET_SEGMENT (fix
->fx_subsy
);
6116 return (sub_symbol_segment
== add_symbol_segment
6117 && add_symbol_segment
!= undefined_section
);
6121 md_number_to_chars (char *buf
, valueT val
, int n
)
6123 if (target_big_endian
)
6124 number_to_chars_bigendian (buf
, val
, n
);
6126 number_to_chars_littleendian (buf
, val
, n
);
6129 /* Equal to MAX_PRECISION in atof-ieee.c. */
6130 #define MAX_LITTLENUMS 6
6132 /* This function is called to convert an ASCII string into a floating point
6133 value in format used by the CPU. */
6136 md_atof (int type
, char *litP
, int *sizeP
)
6140 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
6159 return _("Bad call to md_atof()");
6162 t
= atof_ieee (input_line_pointer
, type
, words
);
6164 input_line_pointer
= t
;
6165 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
6167 if (target_big_endian
)
6169 for (i
= 0; i
< prec
; i
++)
6171 md_number_to_chars (litP
, (valueT
) words
[i
],
6172 sizeof (LITTLENUM_TYPE
));
6173 litP
+= sizeof (LITTLENUM_TYPE
);
6178 for (i
= prec
- 1; i
>= 0; i
--)
6180 md_number_to_chars (litP
, (valueT
) words
[i
],
6181 sizeof (LITTLENUM_TYPE
));
6182 litP
+= sizeof (LITTLENUM_TYPE
);
6189 /* md_elf_section_change_hook */
6192 nds32_elf_section_change_hook (void)
6199 nds32_cleanup (void)
6203 /* This function is used to scan leb128 subtraction expressions,
6204 and insert fixups for them.
6206 e.g., .leb128 .L1 - .L0
6208 These expressions are heavily used in debug information or
6209 exception tables. Because relaxation will change code size,
6210 we must resolve them in link time. */
6213 nds32_insert_leb128_fixes (bfd
*abfd ATTRIBUTE_UNUSED
,
6214 asection
*sec
, void *xxx ATTRIBUTE_UNUSED
)
6216 segment_info_type
*seginfo
= seg_info (sec
);
6219 subseg_set (sec
, 0);
6221 for (fragP
= seginfo
->frchainP
->frch_root
;
6222 fragP
; fragP
= fragP
->fr_next
)
6226 /* Only unsigned leb128 can be handle. */
6227 if (fragP
->fr_type
!= rs_leb128
|| fragP
->fr_subtype
!= 0
6228 || fragP
->fr_symbol
== NULL
)
6231 exp
= symbol_get_value_expression (fragP
->fr_symbol
);
6233 if (exp
->X_op
!= O_subtract
)
6236 fix_new_exp (fragP
, fragP
->fr_fix
, 0,
6237 exp
, 0, BFD_RELOC_NDS32_DIFF_ULEB128
);
6242 nds32_insert_relax_entry (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*sec
,
6243 void *xxx ATTRIBUTE_UNUSED
)
6245 segment_info_type
*seginfo
;
6251 seginfo
= seg_info (sec
);
6252 if (!seginfo
|| !symbol_rootP
|| !subseg_text_p (sec
) || sec
->size
== 0)
6254 /* If there is no relocation and relax is disabled, it is not necessary to
6255 insert R_NDS32_RELAX_ENTRY for linker do EX9 or IFC optimization. */
6256 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= fixp
->fx_next
)
6259 if (!fixp
&& !enable_relax_ex9
&& !verbatim
&& ict_flag
== ICT_NONE
)
6262 subseg_change (sec
, 0);
6264 /* Set RELAX_ENTRY flags for linker. */
6265 fragP
= seginfo
->frchainP
->frch_root
;
6266 exp
.X_op
= O_symbol
;
6267 exp
.X_add_symbol
= section_symbol (sec
);
6268 exp
.X_add_number
= 0;
6269 if (!enable_relax_relocs
)
6270 exp
.X_add_number
|= R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG
;
6273 /* These flags are only enabled when global relax is enabled.
6274 Maybe we can check DISABLE_RELAX_FLAG at link-time,
6275 so we set them anyway. */
6276 if (enable_relax_ex9
)
6277 exp
.X_add_number
|= R_NDS32_RELAX_ENTRY_EX9_FLAG
;
6278 if (enable_relax_ifc
)
6279 exp
.X_add_number
|= R_NDS32_RELAX_ENTRY_IFC_FLAG
;
6281 exp
.X_add_number
|= R_NDS32_RELAX_ENTRY_VERBATIM_FLAG
;
6282 if (ict_flag
== ICT_SMALL
)
6283 exp
.X_add_number
|= R_NDS32_RELAX_ENTRY_ICT_SMALL
;
6284 else if (ict_flag
== ICT_LARGE
)
6285 exp
.X_add_number
|= R_NDS32_RELAX_ENTRY_ICT_LARGE
;
6288 exp
.X_add_number
|= R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG
;
6289 if (optimize_for_space
)
6290 exp
.X_add_number
|= R_NDS32_RELAX_ENTRY_OPTIMIZE_FOR_SPACE_FLAG
;
6292 fixP
= fix_new_exp (fragP
, 0, 0, &exp
, 0, BFD_RELOC_NDS32_RELAX_ENTRY
);
6293 fixP
->fx_no_overflow
= 1;
6296 /* Analysis relax hint and insert suitable relocation pattern. */
6299 nds32_elf_analysis_relax_hint (void)
6301 hash_traverse (nds32_hint_hash
, nds32_elf_append_relax_relocs
);
6305 nds32_elf_insert_final_frag (void)
6307 struct frchain
*frchainP
;
6314 for (s
= stdoutput
->sections
; s
; s
= s
->next
)
6316 segment_info_type
*seginfo
= seg_info (s
);
6320 for (frchainP
= seginfo
->frchainP
; frchainP
!= NULL
;
6321 frchainP
= frchainP
->frch_next
)
6323 subseg_set (s
, frchainP
->frch_subseg
);
6325 if (subseg_text_p (now_seg
))
6328 frag_var (rs_machine_dependent
, 2, /* Max size. */
6329 0, /* VAR is un-used. */ 0, NULL
, 0, NULL
);
6330 fragP
->tc_frag_data
.flag
|= NDS32_FRAG_FINAL
;
6339 nds32_elf_insert_final_frag ();
6340 nds32_elf_analysis_relax_hint ();
6341 bfd_map_over_sections (stdoutput
, nds32_insert_leb128_fixes
, NULL
);
6344 /* Implement md_allow_local_subtract. */
6347 nds32_allow_local_subtract (expressionS
*expr_l ATTRIBUTE_UNUSED
,
6348 expressionS
*expr_r ATTRIBUTE_UNUSED
,
6349 segT sec ATTRIBUTE_UNUSED
)
6351 /* Don't allow any subtraction, because relax may change the code. */
6355 /* Sort relocation by address.
6357 We didn't use qsort () in stdlib, because quick-sort is not a stable
6358 sorting algorithm. Relocations at the same address (r_offset) must keep
6359 their relative order. For example, RELAX_ENTRY must be the very first
6362 Currently, this function implements insertion-sort. */
6365 compar_relent (const void *lhs
, const void *rhs
)
6367 const arelent
**l
= (const arelent
**) lhs
;
6368 const arelent
**r
= (const arelent
**) rhs
;
6370 if ((*l
)->address
> (*r
)->address
)
6372 else if ((*l
)->address
== (*r
)->address
)
6378 /* SET_SECTION_RELOCS ()
6380 Although this macro is originally used to set a relocation for each section,
6381 we use it to sort relocations in the same section by the address of the
6385 nds32_set_section_relocs (asection
*sec
, arelent
** relocs ATTRIBUTE_UNUSED
,
6386 unsigned int n ATTRIBUTE_UNUSED
)
6388 bfd
*abfd ATTRIBUTE_UNUSED
= sec
->owner
;
6389 if (bfd_get_section_flags (abfd
, sec
) & (flagword
) SEC_RELOC
)
6390 nds32_insertion_sort (sec
->orelocation
, sec
->reloc_count
,
6391 sizeof (arelent
**), compar_relent
);
6395 nds32_pcrel_from_section (fixS
*fixP
, segT sec ATTRIBUTE_UNUSED
)
6397 if (fixP
->fx_addsy
== NULL
|| !S_IS_DEFINED (fixP
->fx_addsy
)
6398 || S_IS_EXTERNAL (fixP
->fx_addsy
) || S_IS_WEAK (fixP
->fx_addsy
))
6400 /* Let linker resolve undefined symbols. */
6404 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
6407 /* md_post_relax_hook ()
6408 Insert relax entry relocation into sections. */
6411 nds32_post_relax_hook (void)
6413 bfd_map_over_sections (stdoutput
, nds32_insert_relax_entry
, NULL
);
6416 /* tc_fix_adjustable ()
6418 Return whether this symbol (fixup) can be replaced with
6422 nds32_fix_adjustable (fixS
*fixP
)
6424 switch (fixP
->fx_r_type
)
6426 case BFD_RELOC_NDS32_WORD_9_PCREL
:
6427 case BFD_RELOC_NDS32_9_PCREL
:
6428 case BFD_RELOC_NDS32_15_PCREL
:
6429 case BFD_RELOC_NDS32_17_PCREL
:
6430 case BFD_RELOC_NDS32_25_PCREL
:
6431 case BFD_RELOC_NDS32_HI20
:
6432 case BFD_RELOC_NDS32_LO12S0
:
6436 case BFD_RELOC_NDS32_PTR
:
6437 case BFD_RELOC_NDS32_LONGCALL4
:
6438 case BFD_RELOC_NDS32_LONGCALL5
:
6439 case BFD_RELOC_NDS32_LONGCALL6
:
6440 case BFD_RELOC_NDS32_LONGJUMP4
:
6441 case BFD_RELOC_NDS32_LONGJUMP5
:
6442 case BFD_RELOC_NDS32_LONGJUMP6
:
6443 case BFD_RELOC_NDS32_LONGJUMP7
:
6450 /* elf_tc_final_processing */
6453 elf_nds32_final_processing (void)
6455 /* An FPU_COM instruction is found without previous non-FPU_COM
6458 && !(nds32_elf_flags
& (E_NDS32_HAS_FPU_INST
| E_NDS32_HAS_FPU_DP_INST
)))
6460 /* Since only FPU_COM instructions are used and no other FPU instructions
6461 are used. The nds32_elf_flags will be decided by the enabled options
6462 by command line or default configuration. */
6463 if (nds32_fpu_dp_ext
|| nds32_fpu_sp_ext
)
6465 nds32_elf_flags
|= nds32_fpu_dp_ext
? E_NDS32_HAS_FPU_DP_INST
: 0;
6466 nds32_elf_flags
|= nds32_fpu_sp_ext
? E_NDS32_HAS_FPU_INST
: 0;
6470 /* Should never here. */
6471 as_bad (_("Used FPU instructions requires enabling FPU extension"));
6475 if (nds32_elf_flags
& (E_NDS32_HAS_FPU_INST
| E_NDS32_HAS_FPU_DP_INST
))
6477 /* Single/double FPU has been used, set FPU register config. */
6478 /* We did not check the actual number of register used. We may
6479 want to do it while assemble. */
6480 nds32_elf_flags
&= ~E_NDS32_FPU_REG_CONF
;
6481 nds32_elf_flags
|= (nds32_freg
<< E_NDS32_FPU_REG_CONF_SHIFT
);
6485 nds32_elf_flags
|= E_NDS32_HAS_PIC
;
6488 nds32_elf_flags
|= E_NDS32_HAS_REDUCED_REGS
;
6490 nds32_elf_flags
|= (E_NDS32_ELF_VER_1_4
| nds32_abi
);
6491 elf_elfheader (stdoutput
)->e_flags
|= nds32_elf_flags
;
6494 /* Implement md_apply_fix. Apply the fix-up or transform the fix-up for
6495 later relocation generation. */
6498 nds32_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
6500 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
6501 bfd_vma value
= *valP
;
6503 if (fixP
->fx_r_type
< BFD_RELOC_UNUSED
6504 && fixP
->fx_r_type
> BFD_RELOC_NONE
6505 && fixP
->fx_r_type
!= BFD_RELOC_NDS32_DIFF_ULEB128
)
6507 /* In our old nds32 binutils, it must convert relocations which is
6508 generated by CGEN. However, it does not have to consider this anymore.
6509 In current, it only deal with data relocations which enum
6510 is smaller than BFD_RELOC_NONE and BFD_RELOC_NDS32_DIFF_ULEB128.
6511 It is believed that we can construct a better mechanism to
6512 deal with the whole relocation issue in nds32 target
6513 without using CGEN. */
6514 fixP
->fx_addnumber
= value
;
6515 fixP
->tc_fix_data
= NULL
;
6517 /* Transform specific relocations here for later relocation generation.
6518 Tag data here for ex9 relaxation and tag tls data for linker. */
6519 switch (fixP
->fx_r_type
)
6521 case BFD_RELOC_NDS32_DATA
:
6522 if (!enable_relax_ex9
)
6525 case BFD_RELOC_NDS32_TPOFF
:
6526 case BFD_RELOC_NDS32_TLS_LE_HI20
:
6527 case BFD_RELOC_NDS32_TLS_LE_LO12
:
6528 case BFD_RELOC_NDS32_TLS_LE_ADD
:
6529 case BFD_RELOC_NDS32_TLS_LE_LS
:
6530 case BFD_RELOC_NDS32_GOTTPOFF
:
6531 case BFD_RELOC_NDS32_TLS_IE_HI20
:
6532 case BFD_RELOC_NDS32_TLS_IE_LO12S2
:
6533 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
6541 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
6544 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
6546 /* HOW DIFF RELOCATION WORKS.
6548 First of all, this relocation is used to calculate the distance
6549 between two symbols in the SAME section. It is used for jump-
6550 table, debug information, exception table, et al. Therefore,
6551 it is a unsigned positive value. It is NOT used for general-
6554 Consider this example, the distance between .LEND and .LBEGIN
6555 is stored at the address of foo.
6557 ---- >8 ---- >8 ---- >8 ---- >8 ----
6560 .word .LBEGIN - .LEND
6570 ---- 8< ---- 8< ---- 8< ---- 8< ----
6572 We use a single relocation entry for this expression.
6573 * The initial distance value is stored directly in that location
6574 specified by r_offset (i.e., foo in this example.)
6575 * The begin of the region, i.e., .LBEGIN, is specified by
6576 r_info/R_SYM and r_addend, e.g., .text + 0x32.
6577 * The end of region, i.e., .LEND, is represented by
6578 .LBEGIN + distance instead of .LEND, so we only need
6579 a single relocation entry instead of two.
6581 When an instruction is relaxed, we adjust the relocation entry
6582 depending on where the instruction locates. There are three
6583 cases, before, after and between the region.
6584 * between: Distance value is read from r_offset, adjusted and
6585 written back into r_offset.
6586 * before: Only r_addend is adjust.
6587 * after: We don't care about it.
6589 Hereby, there are some limitation.
6591 `(.LEND - 1) - .LBEGIN' and `(.LEND - .LBEGIN) - 1'
6592 are semantically different, and we cannot handle latter case
6595 The latter expression means subtracting 1 from the distance
6596 between .LEND and .LBEGIN. And the former expression means
6597 the distance between (.LEND - 1) and .LBEGIN.
6599 The nuance affects whether to adjust distance value when relax
6600 an instruction. In another words, whether the instruction
6601 locates in the region. Because we use a single relocation entry,
6602 there is no field left for .LEND and the subtrahend.
6604 Since GCC-4.5, GCC may produce debug information in such expression
6606 in order to describe register clobbering during an function-call.
6611 Check http://gcc.gnu.org/ml/gcc-patches/2009-06/msg01317.html
6614 value
-= S_GET_VALUE (fixP
->fx_subsy
);
6616 fixP
->fx_subsy
= NULL
;
6617 fixP
->fx_offset
-= value
;
6619 switch (fixP
->fx_r_type
)
6622 fixP
->fx_r_type
= BFD_RELOC_NDS32_DIFF8
;
6623 md_number_to_chars (where
, value
, 1);
6626 fixP
->fx_r_type
= BFD_RELOC_NDS32_DIFF16
;
6627 md_number_to_chars (where
, value
, 2);
6630 fixP
->fx_r_type
= BFD_RELOC_NDS32_DIFF32
;
6631 md_number_to_chars (where
, value
, 4);
6633 case BFD_RELOC_NDS32_DIFF_ULEB128
:
6634 /* cvt_frag_to_fill () has called output_leb128 () for us. */
6637 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6638 _("expression too complex"));
6642 else if (fixP
->fx_done
)
6644 /* We're finished with this fixup. Install it because
6645 bfd_install_relocation won't be called to do it. */
6646 switch (fixP
->fx_r_type
)
6649 md_number_to_chars (where
, value
, 1);
6652 md_number_to_chars (where
, value
, 2);
6655 md_number_to_chars (where
, value
, 4);
6658 md_number_to_chars (where
, value
, 8);
6661 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6662 _("Internal error: Unknown fixup type %d (`%s')"),
6664 bfd_get_reloc_code_name (fixP
->fx_r_type
));
6670 /* Implement tc_gen_reloc. Generate ELF relocation for a fix-up. */
6673 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixP
)
6676 bfd_reloc_code_real_type code
;
6678 reloc
= XNEW (arelent
);
6680 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
6681 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
6682 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
6684 code
= fixP
->fx_r_type
;
6686 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
6687 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
6689 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6690 _("internal error: can't export reloc type %d (`%s')"),
6691 fixP
->fx_r_type
, bfd_get_reloc_code_name (code
));
6695 /* Add relocation handling here. */
6697 switch (fixP
->fx_r_type
)
6700 /* In general, addend of a relocation is the offset to the
6701 associated symbol. */
6702 reloc
->addend
= fixP
->fx_offset
;
6705 case BFD_RELOC_NDS32_DATA
:
6706 /* Prevent linker from optimizing data in text sections.
6707 For example, jump table. */
6708 reloc
->addend
= fixP
->fx_size
;
6715 struct suffix_name suffix_table
[] =
6717 {"GOTOFF", BFD_RELOC_NDS32_GOTOFF
, 1},
6718 {"GOT", BFD_RELOC_NDS32_GOT20
, 1},
6719 {"TPOFF", BFD_RELOC_NDS32_TPOFF
, 0},
6720 {"PLT", BFD_RELOC_NDS32_25_PLTREL
, 1},
6721 {"GOTTPOFF", BFD_RELOC_NDS32_GOTTPOFF
, 0}
6724 /* Implement md_parse_name. */
6727 nds32_parse_name (char const *name
, expressionS
*exprP
,
6728 enum expr_mode mode ATTRIBUTE_UNUSED
,
6729 char *nextcharP ATTRIBUTE_UNUSED
)
6733 exprP
->X_op_symbol
= NULL
;
6734 exprP
->X_md
= BFD_RELOC_UNUSED
;
6736 exprP
->X_add_symbol
= symbol_find_or_make (name
);
6737 exprP
->X_op
= O_symbol
;
6738 exprP
->X_add_number
= 0;
6740 /* Check the special name if a symbol. */
6741 segment
= S_GET_SEGMENT (exprP
->X_add_symbol
);
6742 if (segment
!= undefined_section
)
6745 if (strcmp (name
, GOT_NAME
) == 0 && *nextcharP
!= '@')
6747 /* Set for _GOT_OFFSET_TABLE_. */
6748 exprP
->X_md
= BFD_RELOC_NDS32_GOTPC20
;
6750 else if (*nextcharP
== '@')
6754 for (i
= 0; i
< ARRAY_SIZE (suffix_table
); i
++)
6756 next
= input_line_pointer
+ 1 + strlen(suffix_table
[i
].suffix
);
6757 if (strncasecmp (input_line_pointer
+ 1, suffix_table
[i
].suffix
,
6758 strlen (suffix_table
[i
].suffix
)) == 0
6759 && !is_part_of_name (*next
))
6761 if (!nds32_pic
&& suffix_table
[i
].pic
)
6762 as_bad (_("need PIC qualifier with symbol."));
6763 exprP
->X_md
= suffix_table
[i
].reloc
;
6764 *input_line_pointer
= *nextcharP
;
6765 input_line_pointer
= next
;
6766 *nextcharP
= *input_line_pointer
;
6767 *input_line_pointer
= '\0';
6775 /* Implement tc_regname_to_dw2regnum. */
6778 tc_nds32_regname_to_dw2regnum (char *regname
)
6780 struct nds32_keyword
*sym
= hash_find (nds32_gprs_hash
, regname
);
6789 tc_nds32_frame_initial_instructions (void)
6792 /* Default cfa is register-31/sp. */
6793 cfi_add_CFA_def_cfa (31, 0);