1 /* tc-nds32.c -- Assemble for the nds32
2 Copyright (C) 2012-2020 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 "opcode/nds32.h"
40 /* GAS definitions. */
42 /* Characters which start a comment. */
43 const char comment_chars
[] = "!";
44 /* Characters which start a comment when they appear at the start of a line. */
45 const char line_comment_chars
[] = "#!";
46 /* Characters which separate lines (null and newline are by default). */
47 const char line_separator_chars
[] = ";";
48 /* Characters which may be used as the exponent character
49 in a floating point number. */
50 const char EXP_CHARS
[] = "eE";
51 /* Characters which may be used to indicate a floating point constant. */
52 const char FLT_CHARS
[] = "dDfF";
54 static int enable_16bit
= 1;
55 /* Save for md_assemble to distinguish if this instruction is
56 expanded from the pseudo instruction. */
57 static bfd_boolean pseudo_opcode
= FALSE
;
58 static struct nds32_relocs_pattern
*relocs_list
= NULL
;
59 /* Save instruction relation to inserting relaxation relocation. */
60 struct nds32_relocs_pattern
67 struct nds32_opcode
*opcode
;
69 struct nds32_relocs_pattern
*next
;
70 /* Assembled instruction bytes. */
74 /* Suffix name and relocation. */
78 short unsigned int reloc
;
80 static int vec_size
= 0;
81 /* If the assembly code is generated by compiler, it is supposed to have
82 ".flag verbatim" at beginning of the content. We have
83 'nds32_flag' to parse it and set this field to be non-zero. */
84 static int verbatim
= 0;
85 static htab_t nds32_gprs_hash
;
86 static htab_t nds32_hint_hash
;
87 #define TLS_REG "$r27"
88 #define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
90 /* Generate relocation for relax or not, and the default is true. */
91 static int enable_relax_relocs
= 1;
92 /* Save option -O for performance. */
93 static int optimize
= 0;
94 /* Save option -Os for code size. */
95 static int optimize_for_space
= 0;
96 /* Flag to save label exist. */
97 static int label_exist
= 0;
98 /* Flag to save state in omit_fp region. */
99 static int in_omit_fp
= 0;
100 extern struct nds32_keyword keyword_gpr
[];
101 /* Tag there is relax relocation having to link. */
102 static bfd_boolean relaxing
= FALSE
;
109 static enum ict_option ict_flag
= ICT_NONE
;
112 static htab_t nds32_relax_info_hash
;
114 /* Branch patterns. */
115 static relax_info_t relax_table
[] =
119 .br_range
= BR_RANGE_S16M
,
124 .relax_code_seq
[BR_RANGE_S256
] =
126 INSN_JAL
/* jal label */
128 .relax_code_size
[BR_RANGE_S256
] = 4,
129 .relax_branch_isize
[BR_RANGE_S256
] = 4,
130 .relax_fixup
[BR_RANGE_S256
] =
132 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
136 .relax_code_seq
[BR_RANGE_S16K
] =
138 INSN_JAL
/* jal label */
140 .relax_code_size
[BR_RANGE_S16K
] = 4,
141 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
142 .relax_fixup
[BR_RANGE_S16K
] =
144 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
148 .relax_code_seq
[BR_RANGE_S64K
] =
150 INSN_JAL
/* jal label */
152 .relax_code_size
[BR_RANGE_S64K
] = 4,
153 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
154 .relax_fixup
[BR_RANGE_S64K
] =
156 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
160 .relax_code_seq
[BR_RANGE_S16M
] =
162 INSN_JAL
/* jal label */
164 .relax_code_size
[BR_RANGE_S16M
] = 4,
165 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
166 .relax_fixup
[BR_RANGE_S16M
] =
168 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
172 .relax_code_seq
[BR_RANGE_U4G
] =
174 INSN_SETHI_TA
, /* sethi $ta, label */
175 INSN_ORI_TA
, /* ori $ta, $ta, label */
176 INSN_JRAL_TA
/* jral $ta */
178 .relax_code_size
[BR_RANGE_U4G
] = 12,
179 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
180 .relax_fixup
[BR_RANGE_U4G
] =
182 {0, 4, 0, BFD_RELOC_NDS32_HI20
},
183 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGCALL4
},
184 {4, 4, NDS32_HINT
| NDS32_FIX
, BFD_RELOC_NDS32_LO12S0_ORI
},
185 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
186 {8, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
187 {8, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
188 {8, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
194 .br_range
= BR_RANGE_S64K
,
197 {0, 20, 0x1F, FALSE
},
200 .relax_code_seq
[BR_RANGE_S256
] =
202 INSN_BGEZAL
/* bgezal $rt, label */
204 .relax_code_condition
[BR_RANGE_S256
] =
206 {0, 20, 0x1F, FALSE
},
209 .relax_code_size
[BR_RANGE_S256
] = 4,
210 .relax_branch_isize
[BR_RANGE_S256
] = 4,
211 .relax_fixup
[BR_RANGE_S256
] =
213 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
217 .relax_code_seq
[BR_RANGE_S16K
] =
219 INSN_BGEZAL
/* bgezal $rt, label */
221 .relax_code_condition
[BR_RANGE_S16K
] =
223 {0, 20, 0x1F, FALSE
},
226 .relax_code_size
[BR_RANGE_S16K
] = 4,
227 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
228 .relax_fixup
[BR_RANGE_S16K
] =
230 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
234 .relax_code_seq
[BR_RANGE_S64K
] =
236 INSN_BGEZAL
/* bgezal $rt, label */
238 .relax_code_condition
[BR_RANGE_S64K
] =
240 {0, 20, 0x1F, FALSE
},
243 .relax_code_size
[BR_RANGE_S64K
] = 4,
244 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
245 .relax_fixup
[BR_RANGE_S64K
] =
247 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
251 .relax_code_seq
[BR_RANGE_S16M
] =
253 INSN_BLTZ
, /* bltz $rt, $1 */
254 INSN_JAL
/* jal label */
256 .relax_code_condition
[BR_RANGE_S16M
] =
258 {0, 20, 0x1F, FALSE
},
261 .relax_code_size
[BR_RANGE_S16M
] = 8,
262 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
263 .relax_fixup
[BR_RANGE_S16M
] =
265 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
266 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGCALL5
},
267 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
271 .relax_code_seq
[BR_RANGE_U4G
] =
273 INSN_BLTZ
, /* bltz $rt, $1 */
274 INSN_SETHI_TA
, /* sethi $ta, label */
275 INSN_ORI_TA
, /* ori $ta, $ta, label */
276 INSN_JRAL_TA
/* jral $ta */
278 .relax_code_condition
[BR_RANGE_U4G
] =
280 {0, 20, 0x1F, FALSE
},
283 .relax_code_size
[BR_RANGE_U4G
] = 16,
284 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
285 .relax_fixup
[BR_RANGE_U4G
] =
287 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
288 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGCALL6
},
289 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
290 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
291 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
292 {8, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
293 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
294 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
295 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
301 .br_range
= BR_RANGE_S64K
,
304 {0, 20, 0x1F, FALSE
},
307 .relax_code_seq
[BR_RANGE_S256
] =
309 INSN_BLTZAL
/* bltzal $rt, label */
311 .relax_code_condition
[BR_RANGE_S256
] =
313 {0, 20, 0x1F, FALSE
},
316 .relax_code_size
[BR_RANGE_S256
] = 4,
317 .relax_branch_isize
[BR_RANGE_S256
] = 4,
318 .relax_fixup
[BR_RANGE_S256
] =
320 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
324 .relax_code_seq
[BR_RANGE_S16K
] =
326 INSN_BLTZAL
/* bltzal $rt, label */
328 .relax_code_condition
[BR_RANGE_S16K
] =
330 {0, 20, 0x1F, FALSE
},
333 .relax_code_size
[BR_RANGE_S16K
] = 4,
334 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
335 .relax_fixup
[BR_RANGE_S16K
] =
337 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
341 .relax_code_seq
[BR_RANGE_S64K
] =
343 INSN_BLTZAL
/* bltzal $rt, label */
345 .relax_code_condition
[BR_RANGE_S64K
] =
347 {0, 20, 0x1F, FALSE
},
350 .relax_code_size
[BR_RANGE_S64K
] = 4,
351 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
352 .relax_fixup
[BR_RANGE_S64K
] =
354 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
358 .relax_code_seq
[BR_RANGE_S16M
] =
360 INSN_BGEZ
, /* bgez $rt, $1 */
361 INSN_JAL
/* jal label */
363 .relax_code_condition
[BR_RANGE_S16M
] =
365 {0, 20, 0x1F, FALSE
},
368 .relax_code_size
[BR_RANGE_S16M
] = 8,
369 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
370 .relax_fixup
[BR_RANGE_S16M
] =
372 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
373 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGCALL5
},
374 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
378 .relax_code_seq
[BR_RANGE_U4G
] =
380 INSN_BGEZ
, /* bgez $rt, $1 */
381 INSN_SETHI_TA
, /* sethi $ta, label */
382 INSN_ORI_TA
, /* ori $ta, $ta, label */
383 INSN_JRAL_TA
/* jral $ta */
385 .relax_code_condition
[BR_RANGE_U4G
] =
387 {0, 20, 0x1F, FALSE
},
390 .relax_code_size
[BR_RANGE_U4G
] = 16,
391 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
392 .relax_fixup
[BR_RANGE_U4G
] =
394 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
395 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGCALL6
},
396 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
397 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
398 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
399 {8, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
400 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
401 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
402 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
408 .br_range
= BR_RANGE_S16M
,
413 .relax_code_seq
[BR_RANGE_S256
] =
415 (INSN_J8
<< 16) /* j8 label */
417 .relax_code_size
[BR_RANGE_S256
] = 2,
418 .relax_branch_isize
[BR_RANGE_S256
] = 2,
419 .relax_fixup
[BR_RANGE_S256
] =
421 {0, 2, NDS32_PCREL
, BFD_RELOC_NDS32_9_PCREL
},
425 .relax_code_seq
[BR_RANGE_S16K
] =
429 . relax_code_size
[BR_RANGE_S16K
] = 4,
430 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
431 .relax_fixup
[BR_RANGE_S16K
] =
433 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
437 .relax_code_seq
[BR_RANGE_S64K
] =
441 .relax_code_size
[BR_RANGE_S64K
] = 4,
442 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
443 .relax_fixup
[BR_RANGE_S64K
] =
445 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
449 .relax_code_seq
[BR_RANGE_S16M
] =
453 .relax_code_size
[BR_RANGE_S16M
] = 4,
454 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
455 .relax_fixup
[BR_RANGE_S16M
] =
457 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
461 .relax_code_seq
[BR_RANGE_U4G
] =
463 INSN_SETHI_TA
, /* sethi $ta, label */
464 INSN_ORI_TA
, /* ori $ta, $ta, label */
465 INSN_JR_TA
/* jr $ta */
467 .relax_code_size
[BR_RANGE_U4G
] = 12,
468 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
469 .relax_fixup
[BR_RANGE_U4G
] =
471 {0, 4, 0, BFD_RELOC_NDS32_HI20
},
472 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP4
},
473 {4, 4, NDS32_HINT
| NDS32_FIX
, BFD_RELOC_NDS32_LO12S0_ORI
},
474 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
475 {8, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
476 {8, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
477 {8, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
483 .br_range
= BR_RANGE_S256
,
488 .relax_code_seq
[BR_RANGE_S256
] =
490 (INSN_J8
<< 16) /* j8 label */
492 .relax_code_size
[BR_RANGE_S256
] = 2,
493 .relax_branch_isize
[BR_RANGE_S256
] = 2,
494 .relax_fixup
[BR_RANGE_S256
] =
496 {0, 2, NDS32_PCREL
, BFD_RELOC_NDS32_9_PCREL
},
500 .relax_code_seq
[BR_RANGE_S16K
] =
504 .relax_code_size
[BR_RANGE_S16K
] = 4,
505 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
506 .relax_fixup
[BR_RANGE_S16K
] =
508 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
512 .relax_code_seq
[BR_RANGE_S64K
] =
516 .relax_code_size
[BR_RANGE_S64K
] = 4,
517 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
518 .relax_fixup
[BR_RANGE_S64K
] =
520 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
524 .relax_code_seq
[BR_RANGE_S16M
] =
528 .relax_code_size
[BR_RANGE_S16M
] = 4,
529 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
530 .relax_fixup
[BR_RANGE_S16M
] =
532 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
536 .relax_code_seq
[BR_RANGE_U4G
] =
538 INSN_SETHI_TA
, /* sethi $ta, label */
539 INSN_ORI_TA
, /* ori $ta, $ta, label */
540 INSN_JR_TA
/* jr $ta */
542 .relax_code_size
[BR_RANGE_U4G
] = 12,
543 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
544 .relax_fixup
[BR_RANGE_U4G
] =
546 {0, 4, 0, BFD_RELOC_NDS32_HI20
},
547 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP4
},
548 {4, 4, NDS32_HINT
| NDS32_FIX
, BFD_RELOC_NDS32_LO12S0_ORI
},
549 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
550 {8, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
551 {8, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
552 {8, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
558 .br_range
= BR_RANGE_S64K
,
561 {0, 20, 0x1F, FALSE
},
564 /* We do not use beqz38 and beqzs8 here directly because we
565 don't want to check register number for specail condition. */
566 .relax_code_seq
[BR_RANGE_S256
] =
568 INSN_BEQZ
/* beqz $rt, label */
570 .relax_code_condition
[BR_RANGE_S256
] =
572 {0, 20, 0x1F, FALSE
},
575 .relax_code_size
[BR_RANGE_S256
] = 4,
576 .relax_branch_isize
[BR_RANGE_S256
] = 4,
577 .relax_fixup
[BR_RANGE_S256
] =
579 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
580 {0, 4, NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
584 .relax_code_seq
[BR_RANGE_S16K
] =
586 INSN_BEQZ
/* beqz $rt, label */
588 .relax_code_condition
[BR_RANGE_S16K
] =
590 {0, 20, 0x1F, FALSE
},
593 .relax_code_size
[BR_RANGE_S16K
] = 4,
594 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
595 .relax_fixup
[BR_RANGE_S16K
] =
597 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
601 .relax_code_seq
[BR_RANGE_S64K
] =
603 INSN_BEQZ
/* beqz $rt, label */
605 .relax_code_condition
[BR_RANGE_S64K
] =
607 {0, 20, 0x1F, FALSE
},
610 .relax_code_size
[BR_RANGE_S64K
] = 4,
611 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
612 .relax_fixup
[BR_RANGE_S64K
] =
614 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
618 .relax_code_seq
[BR_RANGE_S16M
] =
620 INSN_BNEZ
, /* bnez $rt, $1 */
623 .relax_code_condition
[BR_RANGE_S16M
] =
625 {0, 20, 0x1F, FALSE
},
628 .relax_code_size
[BR_RANGE_S16M
] = 8,
629 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
630 .relax_fixup
[BR_RANGE_S16M
] =
632 /* bnez range is 17 pcrel, but it use 15 pcrel here since link time
633 relaxtion. If 17 pcrel can reach, it do not have to use S16M.
634 Therefore, 15 pcrel is just for linker to distinguish LONGJUMP5
636 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
637 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
638 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
639 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
640 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
644 .relax_code_seq
[BR_RANGE_U4G
] =
646 INSN_BNEZ
, /* bnez $rt, $1 */
647 INSN_SETHI_TA
, /* sethi $ta, label */
648 INSN_ORI_TA
, /* ori $ta, $ta, label */
649 INSN_JR_TA
/* jr $ta */
651 .relax_code_condition
[BR_RANGE_U4G
] =
653 {0, 20, 0x1F, FALSE
},
656 .relax_code_size
[BR_RANGE_U4G
] = 16,
657 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
658 .relax_fixup
[BR_RANGE_U4G
] =
660 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
661 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
662 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
663 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
664 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
665 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
666 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
667 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
668 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
669 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
675 .br_range
= BR_RANGE_S64K
,
678 {0, 20, 0x1F, FALSE
},
681 .relax_code_seq
[BR_RANGE_S256
] =
683 INSN_BGEZ
/* bgez $rt, label */
685 .relax_code_condition
[BR_RANGE_S256
] =
687 {0, 20, 0x1F, FALSE
},
690 .relax_code_size
[BR_RANGE_S256
] = 4,
691 .relax_branch_isize
[BR_RANGE_S256
] = 4,
692 .relax_fixup
[BR_RANGE_S256
] =
694 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
698 .relax_code_seq
[BR_RANGE_S16K
] =
700 INSN_BGEZ
/* bgez $rt, label */
702 .relax_code_condition
[BR_RANGE_S16K
] =
704 {0, 20, 0x1F, FALSE
},
707 .relax_code_size
[BR_RANGE_S16K
] = 4,
708 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
709 .relax_fixup
[BR_RANGE_S16K
] =
711 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
715 .relax_code_seq
[BR_RANGE_S64K
] =
717 INSN_BGEZ
/* bgez $rt, label */
719 .relax_code_condition
[BR_RANGE_S64K
] =
721 {0, 20, 0x1F, FALSE
},
724 .relax_code_size
[BR_RANGE_S64K
] = 4,
725 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
726 .relax_fixup
[BR_RANGE_S64K
] =
728 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
732 .relax_code_seq
[BR_RANGE_S16M
] =
734 INSN_BLTZ
, /* bltz $rt, $1 */
737 .relax_code_condition
[BR_RANGE_S16M
] =
739 {0, 20, 0x1F, FALSE
},
742 .relax_code_size
[BR_RANGE_S16M
] = 8,
743 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
744 .relax_fixup
[BR_RANGE_S16M
] =
746 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
747 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
748 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
751 .relax_code_seq
[BR_RANGE_U4G
] =
753 INSN_BLTZ
, /* bltz $rt, $1 */
754 INSN_SETHI_TA
, /* sethi $ta, label */
755 INSN_ORI_TA
, /* ori $ta, $ta, label */
756 INSN_JR_TA
/* jr $ta */
758 .relax_code_condition
[BR_RANGE_U4G
] =
760 {0, 20, 0x1F, FALSE
},
763 .relax_code_size
[BR_RANGE_U4G
] = 16,
764 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
765 .relax_fixup
[BR_RANGE_U4G
] =
767 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
768 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
769 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
770 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
771 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
772 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
773 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
774 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
775 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
781 .br_range
= BR_RANGE_S64K
,
784 {0, 20, 0x1F, FALSE
},
787 .relax_code_seq
[BR_RANGE_S256
] =
789 INSN_BNEZ
/* bnez $rt, label */
791 .relax_code_condition
[BR_RANGE_S256
] =
793 {0, 20, 0x1F, FALSE
},
796 .relax_code_size
[BR_RANGE_S256
] = 4,
797 .relax_branch_isize
[BR_RANGE_S256
] = 4,
798 .relax_fixup
[BR_RANGE_S256
] =
800 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
801 {0, 4, NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
805 .relax_code_seq
[BR_RANGE_S16K
] =
807 INSN_BNEZ
/* bnez $rt, label */
809 .relax_code_condition
[BR_RANGE_S16K
] =
811 {0, 20, 0x1F, FALSE
},
814 .relax_code_size
[BR_RANGE_S16K
] = 4,
815 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
816 .relax_fixup
[BR_RANGE_S16K
] =
818 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
822 .relax_code_seq
[BR_RANGE_S64K
] =
824 INSN_BNEZ
/* bnez $rt, label */
826 .relax_code_condition
[BR_RANGE_S64K
] =
828 {0, 20, 0x1F, FALSE
},
831 .relax_code_size
[BR_RANGE_S64K
] = 4,
832 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
833 .relax_fixup
[BR_RANGE_S64K
] =
835 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
839 .relax_code_seq
[BR_RANGE_S16M
] =
841 INSN_BEQZ
, /* beqz $rt, $1 */
844 .relax_code_condition
[BR_RANGE_S16M
] =
846 {0, 20, 0x1F, FALSE
},
849 .relax_code_size
[BR_RANGE_S16M
] = 8,
850 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
851 .relax_fixup
[BR_RANGE_S16M
] =
853 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
854 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
855 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
856 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
857 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
861 .relax_code_seq
[BR_RANGE_U4G
] =
863 INSN_BEQZ
, /* beqz $rt, $1 */
864 INSN_SETHI_TA
, /* sethi $ta, label */
865 INSN_ORI_TA
, /* ori $ta, $ta, label */
866 INSN_JR_TA
/* jr $ta */
868 .relax_code_condition
[BR_RANGE_U4G
] =
870 {0, 20, 0x1F, FALSE
},
873 .relax_code_size
[BR_RANGE_U4G
] = 16,
874 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
875 .relax_fixup
[BR_RANGE_U4G
] =
877 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
878 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
879 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
880 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
881 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
882 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
883 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
884 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
885 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
886 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
892 .br_range
= BR_RANGE_S64K
,
895 {0, 20, 0x1F, FALSE
},
898 .relax_code_seq
[BR_RANGE_S256
] =
900 INSN_BGTZ
/* bgtz $rt, label */
902 .relax_code_condition
[BR_RANGE_S256
] =
904 {0, 20, 0x1F, FALSE
},
907 .relax_code_size
[BR_RANGE_S256
] = 4,
908 .relax_branch_isize
[BR_RANGE_S256
] = 4,
909 .relax_fixup
[BR_RANGE_S256
] =
911 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
915 .relax_code_seq
[BR_RANGE_S16K
] =
917 INSN_BGTZ
/* bgtz $rt, label */
919 .relax_code_condition
[BR_RANGE_S16K
] =
921 {0, 20, 0x1F, FALSE
},
924 .relax_code_size
[BR_RANGE_S16K
] = 4,
925 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
926 .relax_fixup
[BR_RANGE_S16K
] =
928 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
932 .relax_code_seq
[BR_RANGE_S64K
] =
934 INSN_BGTZ
/* bgtz $rt, label */
936 .relax_code_condition
[BR_RANGE_S64K
] =
938 {0, 20, 0x1F, FALSE
},
941 .relax_code_size
[BR_RANGE_S64K
] = 4,
942 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
943 .relax_fixup
[BR_RANGE_S64K
] =
945 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
949 .relax_code_seq
[BR_RANGE_S16M
] =
951 INSN_BLEZ
, /* blez $rt, $1 */
954 .relax_code_condition
[BR_RANGE_S16M
] =
956 {0, 20, 0x1F, FALSE
},
959 .relax_code_size
[BR_RANGE_S16M
] = 8,
960 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
961 .relax_fixup
[BR_RANGE_S16M
] =
963 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
964 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
965 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
969 .relax_code_seq
[BR_RANGE_U4G
] =
971 INSN_BLEZ
, /* blez $rt, $1 */
972 INSN_SETHI_TA
, /* sethi $ta, label */
973 INSN_ORI_TA
, /* ori $ta, $ta, label */
974 INSN_JR_TA
/* jr $ta */
976 .relax_code_condition
[BR_RANGE_U4G
] =
978 {0, 20, 0x1F, FALSE
},
981 .relax_code_size
[BR_RANGE_U4G
] = 16,
982 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
983 .relax_fixup
[BR_RANGE_U4G
] =
985 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
986 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
987 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
988 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
989 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
990 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
991 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
992 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
993 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
999 .br_range
= BR_RANGE_S64K
,
1002 {0, 20, 0x1F, FALSE
},
1005 .relax_code_seq
[BR_RANGE_S256
] =
1007 INSN_BLEZ
/* blez $rt, label */
1009 .relax_code_condition
[BR_RANGE_S256
] =
1011 {0, 20, 0x1F, FALSE
},
1014 .relax_code_size
[BR_RANGE_S256
] = 4,
1015 .relax_branch_isize
[BR_RANGE_S256
] = 4,
1016 .relax_fixup
[BR_RANGE_S256
] =
1018 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1022 .relax_code_seq
[BR_RANGE_S16K
] =
1024 INSN_BLEZ
/* blez $rt, label */
1026 .relax_code_condition
[BR_RANGE_S16K
] =
1028 {0, 20, 0x1F, FALSE
},
1031 .relax_code_size
[BR_RANGE_S16K
] = 4,
1032 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
1033 .relax_fixup
[BR_RANGE_S16K
] =
1035 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1039 .relax_code_seq
[BR_RANGE_S64K
] =
1041 INSN_BLEZ
/* blez $rt, label */
1043 .relax_code_condition
[BR_RANGE_S64K
] =
1045 {0, 20, 0x1F, FALSE
},
1048 .relax_code_size
[BR_RANGE_S64K
] = 4,
1049 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
1050 .relax_fixup
[BR_RANGE_S64K
] =
1052 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1056 .relax_code_seq
[BR_RANGE_S16M
] =
1058 INSN_BGTZ
, /* bgtz $rt, $1 */
1059 INSN_J
/* j label */
1061 .relax_code_condition
[BR_RANGE_S16M
] =
1063 {0, 20, 0x1F, FALSE
},
1066 .relax_code_size
[BR_RANGE_S16M
] = 8,
1067 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
1068 .relax_fixup
[BR_RANGE_S16M
] =
1070 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1071 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1072 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1076 .relax_code_seq
[BR_RANGE_U4G
] =
1078 INSN_BGTZ
, /* bgtz $rt, $1 */
1079 INSN_SETHI_TA
, /* sethi $ta, label */
1080 INSN_ORI_TA
, /* ori $ta, $ta, label */
1081 INSN_JR_TA
/* jr $ta */
1083 .relax_code_condition
[BR_RANGE_U4G
] =
1085 {0, 20, 0x1F, FALSE
},
1088 .relax_code_size
[BR_RANGE_U4G
] = 16,
1089 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
1090 .relax_fixup
[BR_RANGE_U4G
] =
1092 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1093 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
1094 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
1095 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1096 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
1097 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1098 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
1099 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
1100 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1106 .br_range
= BR_RANGE_S64K
,
1109 {0, 20, 0x1F, FALSE
},
1112 .relax_code_seq
[BR_RANGE_S256
] =
1114 INSN_BLTZ
/* bltz $rt, label */
1116 .relax_code_condition
[BR_RANGE_S256
] =
1118 {0, 20, 0x1F, FALSE
},
1121 .relax_code_size
[BR_RANGE_S256
] = 4,
1122 .relax_branch_isize
[BR_RANGE_S256
] = 4,
1123 .relax_fixup
[BR_RANGE_S256
] =
1125 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1129 .relax_code_seq
[BR_RANGE_S16K
] =
1131 INSN_BLTZ
/* bltz $rt, label */
1133 .relax_code_condition
[BR_RANGE_S16K
] =
1135 {0, 20, 0x1F, FALSE
},
1138 .relax_code_size
[BR_RANGE_S16K
] = 4,
1139 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
1140 .relax_fixup
[BR_RANGE_S16K
] =
1142 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1146 .relax_code_seq
[BR_RANGE_S64K
] =
1148 INSN_BLTZ
/* bltz $rt, label */
1150 .relax_code_condition
[BR_RANGE_S64K
] =
1152 {0, 20, 0x1F, FALSE
},
1155 .relax_code_size
[BR_RANGE_S64K
] = 4,
1156 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
1157 .relax_fixup
[BR_RANGE_S64K
] =
1159 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1163 .relax_code_seq
[BR_RANGE_S16M
] =
1165 INSN_BGEZ
, /* bgez $rt, $1 */
1166 INSN_J
/* j label */
1168 .relax_code_condition
[BR_RANGE_S16M
] =
1170 {0, 20, 0x1F, FALSE
},
1173 .relax_code_size
[BR_RANGE_S16M
] = 8,
1174 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
1175 .relax_fixup
[BR_RANGE_S16M
] =
1177 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1178 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1179 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1183 .relax_code_seq
[BR_RANGE_U4G
] =
1185 INSN_BGEZ
, /* bgez $rt, $1 */
1186 INSN_SETHI_TA
, /* sethi $ta, label */
1187 INSN_ORI_TA
, /* ori $ta, $ta, label */
1188 INSN_JR_TA
/* jr $ta */
1190 .relax_code_condition
[BR_RANGE_U4G
] =
1192 {0, 20, 0x1F, FALSE
},
1195 .relax_code_size
[BR_RANGE_U4G
] = 16,
1196 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
1197 .relax_fixup
[BR_RANGE_U4G
] =
1199 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1200 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
1201 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
1202 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1203 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
1204 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1205 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
1206 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
1207 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1213 .br_range
= BR_RANGE_S16K
,
1216 {0, 20, 0x1F, FALSE
},
1217 {0, 15, 0x1F, FALSE
},
1220 .relax_code_seq
[BR_RANGE_S256
] =
1222 INSN_BEQ
/* beq $rt, $ra, label */
1224 .relax_code_condition
[BR_RANGE_S256
] =
1226 {0, 20, 0x1F, FALSE
},
1227 {0, 15, 0x1F, FALSE
},
1230 .relax_code_size
[BR_RANGE_S256
] = 4,
1231 .relax_branch_isize
[BR_RANGE_S256
] = 4,
1232 .relax_fixup
[BR_RANGE_S256
] =
1234 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1235 {0, 4, NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
1239 .relax_code_seq
[BR_RANGE_S16K
] =
1241 INSN_BEQ
/* beq $rt, $ra, label */
1243 .relax_code_condition
[BR_RANGE_S16K
] =
1245 {0, 20, 0x1F, FALSE
},
1246 {0, 15, 0x1F, FALSE
},
1249 .relax_code_size
[BR_RANGE_S16K
] = 4,
1250 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
1251 .relax_fixup
[BR_RANGE_S16K
] =
1253 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1257 .relax_code_seq
[BR_RANGE_S64K
] =
1259 INSN_BNE
, /* bne $rt, $ra, $1 */
1260 INSN_J
/* j label */
1262 .relax_code_condition
[BR_RANGE_S64K
] =
1264 {0, 20, 0x1F, FALSE
},
1265 {0, 15, 0x1F, FALSE
},
1268 .relax_code_size
[BR_RANGE_S64K
] = 8,
1269 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
1270 .relax_fixup
[BR_RANGE_S64K
] =
1272 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1273 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1274 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1275 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1276 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1280 .relax_code_seq
[BR_RANGE_S16M
] =
1282 INSN_BNE
, /* bne $rt, $ra, $1 */
1283 INSN_J
/* j label */
1285 .relax_code_condition
[BR_RANGE_S16M
] =
1287 {0, 20, 0x1F, FALSE
},
1288 {0, 15, 0x1F, FALSE
},
1291 .relax_code_size
[BR_RANGE_S16M
] = 8,
1292 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
1293 .relax_fixup
[BR_RANGE_S16M
] =
1295 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1296 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1297 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1298 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1299 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1303 .relax_code_seq
[BR_RANGE_U4G
] =
1305 INSN_BNE
, /* bne $rt, $ra, $1 */
1306 INSN_SETHI_TA
, /* sethi $ta, label */
1307 INSN_ORI_TA
, /* ori $ta, $ta, label */
1308 INSN_JR_TA
/* jr $ta */
1310 .relax_code_condition
[BR_RANGE_U4G
] =
1312 {0, 20, 0x1F, FALSE
},
1313 {0, 15, 0x1F, FALSE
},
1316 .relax_code_size
[BR_RANGE_U4G
] = 16,
1317 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
1318 .relax_fixup
[BR_RANGE_U4G
] =
1320 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1321 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1322 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
1323 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
1324 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1325 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
1326 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1327 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
1328 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
1329 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1335 .br_range
= BR_RANGE_S16K
,
1338 {0, 20, 0x1F, FALSE
},
1339 {0, 15, 0x1F, FALSE
},
1342 .relax_code_seq
[BR_RANGE_S256
] =
1344 INSN_BNE
/* bne $rt, $ra, label */
1346 .relax_code_condition
[BR_RANGE_S256
] =
1348 {0, 20, 0x1F, FALSE
},
1349 {0, 15, 0x1F, FALSE
},
1352 .relax_code_size
[BR_RANGE_S256
] = 4,
1353 .relax_branch_isize
[BR_RANGE_S256
] = 4,
1354 .relax_fixup
[BR_RANGE_S256
] =
1356 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1357 {0, 4, NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
1361 .relax_code_seq
[BR_RANGE_S16K
] =
1363 INSN_BNE
/* bne $rt, $ra, label */
1365 .relax_code_condition
[BR_RANGE_S16K
] =
1367 {0, 20, 0x1F, FALSE
},
1368 {0, 15, 0x1F, FALSE
},
1371 .relax_code_size
[BR_RANGE_S16K
] = 4,
1372 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
1373 .relax_fixup
[BR_RANGE_S16K
] =
1375 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1379 .relax_code_seq
[BR_RANGE_S64K
] =
1381 INSN_BEQ
, /* beq $rt, $ra, $1 */
1382 INSN_J
/* j label */
1384 .relax_code_condition
[BR_RANGE_S64K
] =
1386 {0, 20, 0x1F, FALSE
},
1387 {0, 15, 0x1F, FALSE
},
1390 .relax_code_size
[BR_RANGE_S64K
] = 8,
1391 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
1392 .relax_fixup
[BR_RANGE_S64K
] =
1394 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1395 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1396 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1397 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1398 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1402 .relax_code_seq
[BR_RANGE_S16M
] =
1404 INSN_BEQ
, /* beq $rt, $ra, $1 */
1405 INSN_J
/* j label */
1407 .relax_code_condition
[BR_RANGE_S16M
] =
1409 {0, 20, 0x1F, FALSE
},
1410 {0, 15, 0x1F, FALSE
},
1413 .relax_code_size
[BR_RANGE_S16M
] = 8,
1414 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
1415 .relax_fixup
[BR_RANGE_S16M
] =
1417 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1418 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1419 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1420 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1421 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1425 .relax_code_seq
[BR_RANGE_U4G
] =
1427 INSN_BEQ
, /* beq $rt, $ra, $1 */
1428 INSN_SETHI_TA
, /* sethi $ta, label */
1429 INSN_ORI_TA
, /* ori $ta, $ta, label */
1430 INSN_JR_TA
/* jr $ta */
1432 .relax_code_condition
[BR_RANGE_U4G
] =
1434 {0, 20, 0x1F, FALSE
},
1435 {0, 15, 0x1F, FALSE
},
1438 .relax_code_size
[BR_RANGE_U4G
] = 16,
1439 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
1440 .relax_fixup
[BR_RANGE_U4G
] =
1442 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1443 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1444 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
1445 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
1446 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1447 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
1448 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1449 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
1450 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
1451 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1457 .br_range
= BR_RANGE_S256
,
1463 .relax_code_seq
[BR_RANGE_S256
] =
1465 INSN_BEQZ38
<< 16 /* beqz $rt, label */
1467 .relax_code_condition
[BR_RANGE_S256
] =
1472 .relax_code_size
[BR_RANGE_S256
] = 2,
1473 .relax_branch_isize
[BR_RANGE_S256
] = 2,
1474 .relax_fixup
[BR_RANGE_S256
] =
1476 {0, 2, NDS32_PCREL
, BFD_RELOC_NDS32_9_PCREL
},
1480 .relax_code_seq
[BR_RANGE_S16K
] =
1482 INSN_BEQZ
/* beqz $rt, label */
1484 .relax_code_condition
[BR_RANGE_S16K
] =
1486 {0, 20, 0x1F, FALSE
},
1489 .relax_code_size
[BR_RANGE_S16K
] = 4,
1490 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
1491 .relax_fixup
[BR_RANGE_S16K
] =
1493 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1497 .relax_code_seq
[BR_RANGE_S64K
] =
1499 INSN_BEQZ
/* beqz $rt, label */
1501 .relax_code_condition
[BR_RANGE_S64K
] =
1503 {0, 20, 0x1F, FALSE
},
1506 .relax_code_size
[BR_RANGE_S64K
] = 4,
1507 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
1508 .relax_fixup
[BR_RANGE_S64K
] =
1510 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1514 .relax_code_seq
[BR_RANGE_S16M
] =
1516 INSN_BNEZ
, /* bnez $rt, $1 */
1517 INSN_J
/* j label */
1519 .relax_code_condition
[BR_RANGE_S16M
] =
1521 {0, 20, 0x1F, FALSE
},
1524 .relax_code_size
[BR_RANGE_S16M
] = 8,
1525 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
1526 .relax_fixup
[BR_RANGE_S16M
] =
1528 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1529 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1530 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1531 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1532 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1536 .relax_code_seq
[BR_RANGE_U4G
] =
1538 INSN_BNEZ
, /* bnez $rt, $1 */
1539 INSN_SETHI_TA
, /* sethi $ta, label */
1540 INSN_ORI_TA
, /* ori $ta, $ta, label */
1541 INSN_JR_TA
/* jr $ta */
1543 .relax_code_condition
[BR_RANGE_U4G
] =
1545 {0, 20, 0x1F, FALSE
},
1548 .relax_code_size
[BR_RANGE_U4G
] = 16,
1549 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
1550 .relax_fixup
[BR_RANGE_U4G
] =
1552 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1553 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1554 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
1555 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
1556 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1557 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
1558 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1559 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
1560 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
1561 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1567 .br_range
= BR_RANGE_S256
,
1573 .relax_code_seq
[BR_RANGE_S256
] =
1575 INSN_BNEZ38
<< 16 /* bnez $rt, label */
1577 .relax_code_condition
[BR_RANGE_S256
] =
1582 .relax_code_size
[BR_RANGE_S256
] = 2,
1583 .relax_branch_isize
[BR_RANGE_S256
] = 2,
1584 .relax_fixup
[BR_RANGE_S256
] =
1586 {0, 2, NDS32_PCREL
, BFD_RELOC_NDS32_9_PCREL
},
1590 .relax_code_seq
[BR_RANGE_S16K
] =
1592 INSN_BNEZ
/* bnez $rt, label */
1594 .relax_code_condition
[BR_RANGE_S16K
] =
1596 {0, 20, 0x1F, FALSE
},
1599 .relax_code_size
[BR_RANGE_S16K
] = 4,
1600 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
1601 .relax_fixup
[BR_RANGE_S16K
] =
1603 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1607 .relax_code_seq
[BR_RANGE_S64K
] =
1609 INSN_BNEZ
/* bnez $rt, label */
1611 .relax_code_condition
[BR_RANGE_S64K
] =
1613 {0, 20, 0x1F, FALSE
},
1616 .relax_code_size
[BR_RANGE_S64K
] = 4,
1617 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
1618 .relax_fixup
[BR_RANGE_S64K
] =
1620 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1624 .relax_code_seq
[BR_RANGE_S16M
] =
1626 INSN_BEQZ
, /* beqz $rt, $1 */
1627 INSN_J
/* j label */
1629 .relax_code_condition
[BR_RANGE_S16M
] =
1631 {0, 20, 0x1F, FALSE
},
1634 .relax_code_size
[BR_RANGE_S16M
] = 8,
1635 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
1636 .relax_fixup
[BR_RANGE_S16M
] =
1638 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1639 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1640 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1641 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1642 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1646 .relax_code_seq
[BR_RANGE_U4G
] =
1648 INSN_BEQZ
, /* beqz $rt, $1 */
1649 INSN_SETHI_TA
, /* sethi $ta, label */
1650 INSN_ORI_TA
, /* ori $ta, $ta, label */
1651 INSN_JR_TA
/* jr $ta */
1653 .relax_code_condition
[BR_RANGE_U4G
] =
1655 {0, 20, 0x1F, FALSE
},
1658 .relax_code_size
[BR_RANGE_U4G
] = 16,
1659 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
1660 .relax_fixup
[BR_RANGE_U4G
] =
1662 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1663 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1664 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
1665 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
1666 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1667 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
1668 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1669 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
1670 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
1671 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1677 .br_range
= BR_RANGE_S256
,
1682 .relax_code_seq
[BR_RANGE_S256
] =
1684 INSN_BEQZS8
<< 16 /* beqz $r15, label */
1686 .relax_code_size
[BR_RANGE_S256
] = 2,
1687 .relax_branch_isize
[BR_RANGE_S256
] = 2,
1688 .relax_fixup
[BR_RANGE_S256
] =
1690 {0, 2, NDS32_PCREL
, BFD_RELOC_NDS32_9_PCREL
},
1694 .relax_code_seq
[BR_RANGE_S16K
] =
1696 INSN_BEQZ_TA
/* beqz $r15, label */
1698 .relax_code_size
[BR_RANGE_S16K
] = 4,
1699 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
1700 .relax_fixup
[BR_RANGE_S16K
] =
1702 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1706 .relax_code_seq
[BR_RANGE_S64K
] =
1708 INSN_BEQZ_TA
/* beqz $r15, label */
1710 .relax_code_size
[BR_RANGE_S64K
] = 4,
1711 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
1712 .relax_fixup
[BR_RANGE_S64K
] =
1714 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1718 .relax_code_seq
[BR_RANGE_S16M
] =
1720 INSN_BNEZ_TA
, /* bnez $r15, $1 */
1721 INSN_J
/* j label */
1723 .relax_code_size
[BR_RANGE_S16M
] = 8,
1724 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
1725 .relax_fixup
[BR_RANGE_S16M
] =
1727 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1728 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1729 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1730 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1731 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1735 .relax_code_seq
[BR_RANGE_U4G
] =
1737 INSN_BNEZ_TA
, /* bnez $r15, $1 */
1738 INSN_SETHI_TA
, /* sethi $ta, label */
1739 INSN_ORI_TA
, /* ori $ta, $ta, label */
1740 INSN_JR_TA
/* jr $ta */
1742 .relax_code_size
[BR_RANGE_U4G
] = 16,
1743 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
1744 .relax_fixup
[BR_RANGE_U4G
] =
1746 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1747 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1748 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
1749 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
1750 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1751 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
1752 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1753 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
1754 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
1755 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1761 .br_range
= BR_RANGE_S256
,
1766 .relax_code_seq
[BR_RANGE_S256
] =
1768 INSN_BNEZS8
<< 16 /* bnez $r15, label */
1770 .relax_code_size
[BR_RANGE_S256
] = 2,
1771 .relax_branch_isize
[BR_RANGE_S256
] = 2,
1772 .relax_fixup
[BR_RANGE_S256
] =
1774 {0, 2, NDS32_PCREL
, BFD_RELOC_NDS32_9_PCREL
},
1778 .relax_code_seq
[BR_RANGE_S16K
] =
1780 INSN_BNEZ_TA
/* bnez $r15, label */
1782 .relax_code_size
[BR_RANGE_S16K
] = 4,
1783 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
1784 .relax_fixup
[BR_RANGE_S16K
] =
1786 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1790 .relax_code_seq
[BR_RANGE_S64K
] =
1792 INSN_BNEZ_TA
/* bnez $r15, label */
1794 .relax_code_size
[BR_RANGE_S64K
] = 4,
1795 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
1796 .relax_fixup
[BR_RANGE_S64K
] =
1798 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_17_PCREL
},
1802 .relax_code_seq
[BR_RANGE_S16M
] =
1804 INSN_BEQZ_TA
, /* beqz $r15, $1 */
1805 INSN_J
/* j label */
1807 .relax_code_size
[BR_RANGE_S16M
] = 8,
1808 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
1809 .relax_fixup
[BR_RANGE_S16M
] =
1811 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1812 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1813 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1814 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1815 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1819 .relax_code_seq
[BR_RANGE_U4G
] =
1821 INSN_BEQZ_TA
, /* beqz $r15, $1 */
1822 INSN_SETHI_TA
, /* sethi $ta, label */
1823 INSN_ORI_TA
, /* ori $ta, $ta, label */
1824 INSN_JR_TA
/* jr $ta */
1826 .relax_code_size
[BR_RANGE_U4G
] = 16,
1827 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
1828 .relax_fixup
[BR_RANGE_U4G
] =
1830 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1831 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1832 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
1833 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
1834 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1835 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
1836 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1837 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
1838 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
1839 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1845 .br_range
= BR_RANGE_S256
,
1851 .relax_code_seq
[BR_RANGE_S256
] =
1853 INSN_BNES38
<< 16 /* bne $rt, $r5, label */
1855 .relax_code_condition
[BR_RANGE_S256
] =
1860 .relax_code_size
[BR_RANGE_S256
] = 2,
1861 .relax_branch_isize
[BR_RANGE_S256
] = 2,
1862 .relax_fixup
[BR_RANGE_S256
] =
1864 {0, 2, NDS32_PCREL
, BFD_RELOC_NDS32_9_PCREL
},
1868 .relax_code_seq
[BR_RANGE_S16K
] =
1870 INSN_BNE_R5
/* bne $rt, $r5, label */
1872 .relax_code_condition
[BR_RANGE_S16K
] =
1874 {0, 20, 0x1F, FALSE
},
1877 .relax_code_size
[BR_RANGE_S16K
] = 4,
1878 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
1879 .relax_fixup
[BR_RANGE_S16K
] =
1881 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1885 .relax_code_seq
[BR_RANGE_S64K
] =
1887 INSN_BEQ_R5
, /* beq $rt, $r5, $1 */
1888 INSN_J
/* j label */
1890 .relax_code_condition
[BR_RANGE_S64K
] =
1892 {0, 20, 0x1F, FALSE
},
1895 .relax_code_size
[BR_RANGE_S64K
] = 8,
1896 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
1897 .relax_fixup
[BR_RANGE_S64K
] =
1899 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1900 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1901 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1902 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1903 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1907 .relax_code_seq
[BR_RANGE_S16M
] =
1909 INSN_BEQ_R5
, /* beq $rt, $r5, $1 */
1910 INSN_J
/* j label */
1912 .relax_code_condition
[BR_RANGE_S16M
] =
1914 {0, 20, 0x1F, FALSE
},
1917 .relax_code_size
[BR_RANGE_S16M
] = 8,
1918 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
1919 .relax_fixup
[BR_RANGE_S16M
] =
1921 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1922 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1923 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
1924 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
1925 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1929 .relax_code_seq
[BR_RANGE_U4G
] =
1931 INSN_BEQ_R5
, /* beq $rt, $r5, $1 */
1932 INSN_SETHI_TA
, /* sethi $ta, label */
1933 INSN_ORI_TA
, /* ori $ta, $ta, label */
1934 INSN_JR_TA
/* jr $ta */
1936 .relax_code_condition
[BR_RANGE_U4G
] =
1938 {0, 20, 0x1F, FALSE
},
1941 .relax_code_size
[BR_RANGE_U4G
] = 16,
1942 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
1943 .relax_fixup
[BR_RANGE_U4G
] =
1945 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
1946 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1947 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
1948 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
1949 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1950 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
1951 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
1952 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
1953 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
1954 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
1960 .br_range
= BR_RANGE_S256
,
1966 .relax_code_seq
[BR_RANGE_S256
] =
1968 INSN_BEQS38
<< 16 /* beq $rt, $r5, label */
1970 .relax_code_condition
[BR_RANGE_S256
] =
1975 .relax_code_size
[BR_RANGE_S256
] = 2,
1976 .relax_branch_isize
[BR_RANGE_S256
] = 2,
1977 .relax_fixup
[BR_RANGE_S256
] =
1979 {0, 2, NDS32_PCREL
, BFD_RELOC_NDS32_9_PCREL
},
1983 .relax_code_seq
[BR_RANGE_S16K
] =
1985 INSN_BEQ_R5
/* beq $rt, $r5, label */
1987 .relax_code_condition
[BR_RANGE_S16K
] =
1989 {0, 20, 0x1F, FALSE
},
1992 .relax_code_size
[BR_RANGE_S16K
] = 4,
1993 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
1994 .relax_fixup
[BR_RANGE_S16K
] =
1996 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
2000 .relax_code_seq
[BR_RANGE_S64K
] =
2002 INSN_BNE_R5
, /* bne $rt, $r5, $1 */
2003 INSN_J
/* j label */
2005 .relax_code_condition
[BR_RANGE_S64K
] =
2007 {0, 20, 0x1F, FALSE
},
2010 .relax_code_size
[BR_RANGE_S64K
] = 8,
2011 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
2012 .relax_fixup
[BR_RANGE_S64K
] =
2014 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
2015 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
2016 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
2017 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
2018 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
2022 .relax_code_seq
[BR_RANGE_S16M
] =
2024 INSN_BNE_R5
, /* bne $rt, $r5, $1 */
2025 INSN_J
/* j label */
2027 .relax_code_condition
[BR_RANGE_S16M
] =
2029 {0, 20, 0x1F, FALSE
},
2032 .relax_code_size
[BR_RANGE_S16M
] = 8,
2033 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
2034 .relax_fixup
[BR_RANGE_S16M
] =
2036 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
2037 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
2038 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP5
},
2039 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
2040 {4, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
2044 .relax_code_seq
[BR_RANGE_U4G
] =
2046 INSN_BNE_R5
, /* bne $rt, $r5, $1 */
2047 INSN_SETHI_TA
, /* sethi $ta, label */
2048 INSN_ORI_TA
, /* ori $ta, $ta, label */
2049 INSN_JR_TA
/* jr $ta */
2051 .relax_code_condition
[BR_RANGE_U4G
] =
2053 {0, 20, 0x1F, FALSE
},
2056 .relax_code_size
[BR_RANGE_U4G
] = 16,
2057 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
2058 .relax_fixup
[BR_RANGE_U4G
] =
2060 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
2061 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
2062 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP6
},
2063 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
2064 {4, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
2065 {8, 4, NDS32_FIX
| NDS32_HINT
, BFD_RELOC_NDS32_LO12S0_ORI
},
2066 {8, 4, NDS32_PTR
|NDS32_HINT
, BFD_RELOC_NDS32_PTR
},
2067 {12, 4, NDS32_ABS
| NDS32_HINT
, BFD_RELOC_NDS32_PTR_RESOLVED
},
2068 {12, 4, NDS32_SYM
| NDS32_HINT
, BFD_RELOC_NDS32_EMPTY
},
2069 {12, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
2075 .br_range
= BR_RANGE_S256
,
2078 {0, 8, 0x7FF, TRUE
},
2079 {0, 20, 0x1F, FALSE
},
2082 .relax_code_seq
[BR_RANGE_S256
] =
2084 INSN_BEQC
/* beqc $rt, imm11s, label */
2086 .relax_code_condition
[BR_RANGE_S256
] =
2088 {0, 8, 0x7FF, FALSE
},
2089 {0, 20, 0x1F, FALSE
},
2092 .relax_code_size
[BR_RANGE_S256
] = 4,
2093 .relax_branch_isize
[BR_RANGE_S256
] = 4,
2094 .relax_fixup
[BR_RANGE_S256
] =
2096 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_WORD_9_PCREL
},
2100 .relax_code_seq
[BR_RANGE_S16K
] =
2102 INSN_MOVI_TA
, /* movi $ta, imm11s */
2103 INSN_BEQ_TA
/* beq $rt, $ta, label */
2105 .relax_code_condition
[BR_RANGE_S16K
] =
2107 {0, 0, 0xFFFFF, FALSE
},
2108 {4, 20, 0x1F, FALSE
},
2111 .relax_code_size
[BR_RANGE_S16K
] = 8,
2112 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
2113 .relax_fixup
[BR_RANGE_S16K
] =
2115 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
2116 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP7
},
2117 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
2121 .relax_code_seq
[BR_RANGE_S64K
] =
2123 INSN_BNEC
, /* bnec $rt, imm11s, $1 */
2124 INSN_J
/* j label */
2126 .relax_code_condition
[BR_RANGE_S64K
] =
2128 {0, 8, 0x7FF, FALSE
},
2129 {0, 20, 0x1F, FALSE
},
2132 .relax_code_size
[BR_RANGE_S64K
] = 8,
2133 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
2134 .relax_fixup
[BR_RANGE_S64K
] =
2136 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_WORD_9_PCREL
},
2137 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
2141 .relax_code_seq
[BR_RANGE_S16M
] =
2143 INSN_BNEC
, /* bnec $rt, imm11s, $1 */
2144 INSN_J
/* j label */
2146 .relax_code_condition
[BR_RANGE_S16M
] =
2148 {0, 8, 0x7FF, FALSE
},
2149 {0, 20, 0x1F, FALSE
},
2152 .relax_code_size
[BR_RANGE_S16M
] = 8,
2153 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
2154 .relax_fixup
[BR_RANGE_S16M
] =
2156 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_WORD_9_PCREL
},
2157 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
2161 .relax_code_seq
[BR_RANGE_U4G
] =
2163 INSN_BNEC
, /* bnec $rt, imm11s, $1 */
2164 INSN_SETHI_TA
, /* sethi $ta, label */
2165 INSN_ORI_TA
, /* ori $ta, $ta, label */
2166 INSN_JR_TA
/* jr $ta */
2168 .relax_code_condition
[BR_RANGE_U4G
] =
2170 {0, 8, 0x7FF, FALSE
},
2171 {0, 20, 0x1F, FALSE
},
2174 .relax_code_size
[BR_RANGE_U4G
] = 16,
2175 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
2176 .relax_fixup
[BR_RANGE_U4G
] =
2178 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_WORD_9_PCREL
},
2179 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
2180 {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI
},
2181 {12, 4, NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
2187 .br_range
= BR_RANGE_S256
,
2190 {0, 8, 0x7FF, TRUE
},
2191 {0, 20, 0x1F, FALSE
},
2194 .relax_code_seq
[BR_RANGE_S256
] =
2196 INSN_BNEC
/* bnec $rt, imm11s, label */
2198 .relax_code_condition
[BR_RANGE_S256
] =
2200 {0, 8, 0x7FF, FALSE
},
2201 {0, 20, 0x1F, FALSE
},
2204 .relax_code_size
[BR_RANGE_S256
] = 4,
2205 .relax_branch_isize
[BR_RANGE_S256
] = 4,
2206 .relax_fixup
[BR_RANGE_S256
] =
2208 {0, 4, NDS32_PCREL
, BFD_RELOC_NDS32_WORD_9_PCREL
},
2212 .relax_code_seq
[BR_RANGE_S16K
] =
2214 INSN_MOVI_TA
, /* movi $ta, imm11s */
2215 INSN_BNE_TA
/* bne $rt, $ta, label */
2217 .relax_code_condition
[BR_RANGE_S16K
] =
2219 {0, 0, 0xFFFFF, FALSE
},
2220 {4, 20, 0x1F, FALSE
},
2223 .relax_code_size
[BR_RANGE_S16K
] = 8,
2224 .relax_branch_isize
[BR_RANGE_S16K
] = 4,
2225 .relax_fixup
[BR_RANGE_S16K
] =
2227 {0, 4, NDS32_INSN16
| NDS32_HINT
, BFD_RELOC_NDS32_INSN16
},
2228 {0, 4, NDS32_PTR
| NDS32_HINT
, BFD_RELOC_NDS32_LONGJUMP7
},
2229 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_15_PCREL
},
2233 .relax_code_seq
[BR_RANGE_S64K
] =
2235 INSN_BEQC
, /* beqc $rt, imm11s, $1 */
2236 INSN_J
/* j label */
2238 .relax_code_condition
[BR_RANGE_S64K
] =
2240 {0, 8, 0x7FF, FALSE
},
2241 {0, 20, 0x1F, FALSE
},
2244 .relax_code_size
[BR_RANGE_S64K
] = 8,
2245 .relax_branch_isize
[BR_RANGE_S64K
] = 4,
2246 .relax_fixup
[BR_RANGE_S64K
] =
2248 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_WORD_9_PCREL
},
2249 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
2253 .relax_code_seq
[BR_RANGE_S16M
] =
2255 INSN_BEQC
, /* beqc $rt, imm11s, $1 */
2256 INSN_J
/* j label */
2258 .relax_code_condition
[BR_RANGE_S16M
] =
2260 {0, 8, 0x7FF, FALSE
},
2261 {0, 20, 0x1F, FALSE
},
2264 .relax_code_size
[BR_RANGE_S16M
] = 8,
2265 .relax_branch_isize
[BR_RANGE_S16M
] = 4,
2266 .relax_fixup
[BR_RANGE_S16M
] =
2268 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_WORD_9_PCREL
},
2269 {4, 4, NDS32_PCREL
, BFD_RELOC_NDS32_25_PCREL
},
2273 .relax_code_seq
[BR_RANGE_U4G
] =
2275 INSN_BEQC
, /* beqc $rt, imm11s, $1 */
2276 INSN_SETHI_TA
, /* sethi $ta, label */
2277 INSN_ORI_TA
, /* ori $ta, $ta, label */
2278 INSN_JR_TA
/* jr $ta */
2280 .relax_code_condition
[BR_RANGE_U4G
] =
2282 {0, 8, 0x7FF, FALSE
},
2283 {0, 20, 0x1F, FALSE
},
2286 .relax_code_size
[BR_RANGE_U4G
] = 16,
2287 .relax_branch_isize
[BR_RANGE_U4G
] = 4,
2288 .relax_fixup
[BR_RANGE_U4G
] =
2290 {0, 4, NDS32_CREATE_LABEL
| NDS32_PCREL
, BFD_RELOC_NDS32_WORD_9_PCREL
},
2291 {4, 4, 0, BFD_RELOC_NDS32_HI20
},
2292 {8, 4, 0, BFD_RELOC_NDS32_LO12S0_ORI
},
2293 {12, 4, NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
2303 /* GAS definitions for command-line options. */
2306 OPTION_BIG
= OPTION_MD_BASE
,
2310 OPTION_RELAX_FP_AS_GP_OFF
,
2311 OPTION_RELAX_B2BB_ON
,
2312 OPTION_RELAX_ALL_OFF
,
2314 OPTION_OPTIMIZE_SPACE
2317 const char *md_shortopts
= "m:O:";
2318 struct option md_longopts
[] =
2320 {"O1", no_argument
, NULL
, OPTION_OPTIMIZE
},
2321 {"Os", no_argument
, NULL
, OPTION_OPTIMIZE_SPACE
},
2322 {"big", no_argument
, NULL
, OPTION_BIG
},
2323 {"little", no_argument
, NULL
, OPTION_LITTLE
},
2324 {"EB", no_argument
, NULL
, OPTION_BIG
},
2325 {"EL", no_argument
, NULL
, OPTION_LITTLE
},
2326 {"meb", no_argument
, NULL
, OPTION_BIG
},
2327 {"mel", no_argument
, NULL
, OPTION_LITTLE
},
2328 {"mall-ext", no_argument
, NULL
, OPTION_TURBO
},
2329 {"mext-all", no_argument
, NULL
, OPTION_TURBO
},
2330 {"mpic", no_argument
, NULL
, OPTION_PIC
},
2331 /* Relaxation related options. */
2332 {"mno-fp-as-gp-relax", no_argument
, NULL
, OPTION_RELAX_FP_AS_GP_OFF
},
2333 {"mb2bb", no_argument
, NULL
, OPTION_RELAX_B2BB_ON
},
2334 {"mno-all-relax", no_argument
, NULL
, OPTION_RELAX_ALL_OFF
},
2335 {NULL
, no_argument
, NULL
, 0}
2338 size_t md_longopts_size
= sizeof (md_longopts
);
2340 struct nds32_parse_option_table
2342 const char *name
; /* Option string. */
2343 const char *help
; /* Help description. */
2344 int (*func
) (const char *arg
); /* How to parse it. */
2348 /* The value `-1' represents this option has *NOT* been set. */
2349 #ifdef NDS32_DEFAULT_ARCH_NAME
2350 static const char* nds32_arch_name
= NDS32_DEFAULT_ARCH_NAME
;
2352 static const char* nds32_arch_name
= "v3";
2354 static int nds32_baseline
= -1;
2355 static int nds32_gpr16
= -1;
2356 static int nds32_fpu_sp_ext
= -1;
2357 static int nds32_fpu_dp_ext
= -1;
2358 static int nds32_freg
= -1;
2359 static int nds32_abi
= -1;
2361 /* Record ELF flags */
2362 static int nds32_elf_flags
= 0;
2363 static int nds32_fpu_com
= 0;
2365 static int nds32_parse_arch (const char *str
);
2366 static int nds32_parse_baseline (const char *str
);
2367 static int nds32_parse_freg (const char *str
);
2368 static int nds32_parse_abi (const char *str
);
2369 static void add_mapping_symbol (enum mstate state
,
2370 unsigned int padding_byte
,
2371 unsigned int align
);
2373 static struct nds32_parse_option_table parse_opts
[] =
2375 {"arch=", N_("<arch name>\t Assemble for architecture <arch name>\n\
2376 <arch name> could be\n\
2377 v3, v3j, v3m, v3f, v3s, "\
2378 "v2, v2j, v2f, v2s"), nds32_parse_arch
},
2379 {"baseline=", N_("<baseline>\t Assemble for baseline <baseline>\n\
2380 <baseline> could be v2, v3, v3m"),
2381 nds32_parse_baseline
},
2382 {"fpu-freg=", N_("<freg>\t Specify a FPU configuration\n\
2384 0: 8 SP / 4 DP registers\n\
2385 1: 16 SP / 8 DP registers\n\
2386 2: 32 SP / 16 DP registers\n\
2387 3: 32 SP / 32 DP registers"), nds32_parse_freg
},
2388 {"abi=", N_("<abi>\t Specify a abi version\n\
2389 <abi> could be v1, v2, v2fp, v2fpp"), nds32_parse_abi
},
2393 static int nds32_mac
= 1;
2394 static int nds32_div
= 1;
2395 static int nds32_16bit_ext
= 1;
2396 static int nds32_dx_regs
= NDS32_DEFAULT_DX_REGS
;
2397 static int nds32_perf_ext
= NDS32_DEFAULT_PERF_EXT
;
2398 static int nds32_perf_ext2
= NDS32_DEFAULT_PERF_EXT2
;
2399 static int nds32_string_ext
= NDS32_DEFAULT_STRING_EXT
;
2400 static int nds32_audio_ext
= NDS32_DEFAULT_AUDIO_EXT
;
2401 static int nds32_dsp_ext
= NDS32_DEFAULT_DSP_EXT
;
2402 static int nds32_zol_ext
= NDS32_DEFAULT_ZOL_EXT
;
2403 static int nds32_fpu_fma
= 0;
2404 static int nds32_pic
= 0;
2405 static int nds32_relax_fp_as_gp
= 1;
2406 static int nds32_relax_b2bb
= 0;
2407 static int nds32_relax_all
= 1;
2408 struct nds32_set_option_table
2410 const char *name
; /* Option string. */
2411 const char *help
; /* Help description. */
2412 int *var
; /* Variable to be set. */
2413 int value
; /* Value to set. */
2416 /* The option in this group has both Enable/Disable settings.
2417 Just list on here. */
2419 static struct nds32_set_option_table toggle_opts
[] =
2421 {"mac", N_("Multiply instructions support"), &nds32_mac
, 1},
2422 {"div", N_("Divide instructions support"), &nds32_div
, 1},
2423 {"16bit-ext", N_("16-bit extension"), &nds32_16bit_ext
, 1},
2424 {"dx-regs", N_("d0/d1 registers"), &nds32_dx_regs
, 1},
2425 {"perf-ext", N_("Performance extension"), &nds32_perf_ext
, 1},
2426 {"perf2-ext", N_("Performance extension 2"), &nds32_perf_ext2
, 1},
2427 {"string-ext", N_("String extension"), &nds32_string_ext
, 1},
2428 {"reduced-regs", N_("Reduced Register configuration (GPR16) option"), &nds32_gpr16
, 1},
2429 {"audio-isa-ext", N_("AUDIO ISA extension"), &nds32_audio_ext
, 1},
2430 {"fpu-sp-ext", N_("FPU SP extension"), &nds32_fpu_sp_ext
, 1},
2431 {"fpu-dp-ext", N_("FPU DP extension"), &nds32_fpu_dp_ext
, 1},
2432 {"fpu-fma", N_("FPU fused-multiply-add instructions"), &nds32_fpu_fma
, 1},
2433 {"dsp-ext", N_("DSP extension"), &nds32_dsp_ext
, 1},
2434 {"zol-ext", N_("hardware loop extension"), &nds32_zol_ext
, 1},
2435 {NULL
, NULL
, NULL
, 0}
2439 /* GAS declarations. */
2441 /* This is the callback for nds32-asm.c to parse operands. */
2443 nds32_asm_parse_operand (struct nds32_asm_desc
*pdesc
,
2444 struct nds32_asm_insn
*pinsn
,
2445 char **pstr
, int64_t *value
);
2448 static struct nds32_asm_desc asm_desc
;
2450 /* md_after_parse_args ()
2452 GAS will call md_after_parse_args whenever it is defined.
2453 This function checks any conflicting options specified. */
2456 nds32_after_parse_args (void)
2458 /* If -march option is not used in command-line, set the value of option
2459 variable according to NDS32_DEFAULT_ARCH_NAME. */
2460 nds32_parse_arch (nds32_arch_name
);
2463 /* This function is called when printing usage message (--help). */
2466 md_show_usage (FILE *stream
)
2468 struct nds32_parse_option_table
*coarse_tune
;
2469 struct nds32_set_option_table
*fine_tune
;
2471 fprintf (stream
, _("\n NDS32-specific assembler options:\n"));
2472 fprintf (stream
, _("\
2473 -O1, Optimize for performance\n\
2474 -Os Optimize for space\n"));
2475 fprintf (stream
, _("\
2476 -EL, -mel or -little Produce little endian output\n\
2477 -EB, -meb or -big Produce big endian output\n\
2478 -mpic Generate PIC\n\
2479 -mno-fp-as-gp-relax Suppress fp-as-gp relaxation for this file\n\
2480 -mb2bb-relax Back-to-back branch optimization\n\
2481 -mno-all-relax Suppress all relaxation for this file\n"));
2483 for (coarse_tune
= parse_opts
; coarse_tune
->name
!= NULL
; coarse_tune
++)
2485 if (coarse_tune
->help
!= NULL
)
2486 fprintf (stream
, _(" -m%s%s\n"),
2487 coarse_tune
->name
, _(coarse_tune
->help
));
2490 for (fine_tune
= toggle_opts
; fine_tune
->name
!= NULL
; fine_tune
++)
2492 if (fine_tune
->help
!= NULL
)
2493 fprintf (stream
, _(" -m[no-]%-17sEnable/Disable %s\n"),
2494 fine_tune
->name
, _(fine_tune
->help
));
2497 fprintf (stream
, _("\
2498 -mall-ext Turn on all extensions and instructions support\n"));
2502 nds32_frag_init (fragS
*fragp
)
2504 fragp
->tc_frag_data
.flag
= 0;
2505 fragp
->tc_frag_data
.opcode
= NULL
;
2506 fragp
->tc_frag_data
.fixup
= NULL
;
2511 /* This function reads an expression from a C string and returns a pointer past
2512 the end of the expression. */
2515 parse_expression (char *str
, expressionS
*exp
)
2520 tmp
= input_line_pointer
; /* Save line pointer. */
2521 input_line_pointer
= str
;
2523 s
= input_line_pointer
;
2524 input_line_pointer
= tmp
; /* Restore line pointer. */
2526 return s
; /* Return pointer to where parsing stopped. */
2530 nds32_start_line_hook (void)
2538 typedef void (*nds32_pseudo_opcode_func
) (int argc
, char *argv
[], unsigned int pv
);
2539 struct nds32_pseudo_opcode
2543 nds32_pseudo_opcode_func proc
;
2544 unsigned int pseudo_val
;
2546 /* Some instructions are not pseudo opcode, but they might still be
2547 expanded or changed with other instruction combination for some
2548 conditions. We also apply this structure to assist such work.
2550 For example, if the distance of branch target '.L0' is larger than
2557 will be transformed into:
2563 However, sometimes we do not want assembler to do such changes
2564 because compiler knows how to generate corresponding instruction sequence.
2565 Use this field to indicate that this opcode is also a physical instruction.
2566 If the flag 'verbatim' is nozero and this opcode
2567 is a physical instruction, we should not expand it. */
2570 #define PV_DONT_CARE 0
2572 static htab_t nds32_pseudo_opcode_hash
= NULL
;
2575 builtin_isreg (const char *s
, const char *x ATTRIBUTE_UNUSED
)
2577 if (s
[0] == '$' && str_hash_find (nds32_gprs_hash
, (s
+ 1)))
2583 builtin_regnum (const char *s
, const char *x ATTRIBUTE_UNUSED
)
2585 struct nds32_keyword
*k
;
2589 k
= str_hash_find (nds32_gprs_hash
, s
);
2598 builtin_addend (const char *s
, char *x ATTRIBUTE_UNUSED
)
2600 const char *ptr
= s
;
2602 while (*ptr
!= '+' && *ptr
!= '-' && *ptr
)
2608 return strtol (ptr
, NULL
, 0);
2612 md_assemblef (const char *format
, ...)
2614 /* FIXME: hope this is long enough. */
2619 va_start (ap
, format
);
2620 r
= vsnprintf (line
, sizeof (line
), format
, ap
);
2623 gas_assert (r
< sizeof (line
));
2626 /* Some prototypes here, since some op may use another op. */
2627 static void do_pseudo_li_internal (const char *rt
, int imm32s
);
2628 static void do_pseudo_move_reg_internal (char *dst
, char *src
);
2631 do_pseudo_b (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2632 unsigned int pv ATTRIBUTE_UNUSED
)
2634 char *arg_label
= argv
[0];
2639 md_assemblef ("sethi $ta,hi20(%s)", arg_label
);
2640 md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label
);
2641 md_assemble ((char *) "add $ta,$ta,$gp");
2642 md_assemble ((char *) "jr $ta");
2646 md_assemblef ("j %s", arg_label
);
2652 do_pseudo_bal (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2653 unsigned int pv ATTRIBUTE_UNUSED
)
2655 char *arg_label
= argv
[0];
2657 /* bal|call label */
2660 md_assemblef ("sethi $ta,hi20(%s)", arg_label
);
2661 md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label
);
2662 md_assemble ((char *) "add $ta,$ta,$gp");
2663 md_assemble ((char *) "jral $ta");
2667 md_assemblef ("jal %s", arg_label
);
2673 do_pseudo_bge (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2674 unsigned int pv ATTRIBUTE_UNUSED
)
2676 /* rt5, ra5, label */
2677 md_assemblef ("slt $ta,%s,%s", argv
[0], argv
[1]);
2678 md_assemblef ("beqz $ta,%s", argv
[2]);
2682 do_pseudo_bges (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2683 unsigned int pv ATTRIBUTE_UNUSED
)
2685 /* rt5, ra5, label */
2686 md_assemblef ("slts $ta,%s,%s", argv
[0], argv
[1]);
2687 md_assemblef ("beqz $ta,%s", argv
[2]);
2691 do_pseudo_bgt (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2692 unsigned int pv ATTRIBUTE_UNUSED
)
2694 /* bgt rt5, ra5, label */
2695 md_assemblef ("slt $ta,%s,%s", argv
[1], argv
[0]);
2696 md_assemblef ("bnez $ta,%s", argv
[2]);
2700 do_pseudo_bgts (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2701 unsigned int pv ATTRIBUTE_UNUSED
)
2703 /* bgt rt5, ra5, label */
2704 md_assemblef ("slts $ta,%s,%s", argv
[1], argv
[0]);
2705 md_assemblef ("bnez $ta,%s", argv
[2]);
2709 do_pseudo_ble (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2710 unsigned int pv ATTRIBUTE_UNUSED
)
2712 /* bgt rt5, ra5, label */
2713 md_assemblef ("slt $ta,%s,%s", argv
[1], argv
[0]);
2714 md_assemblef ("beqz $ta,%s", argv
[2]);
2718 do_pseudo_bles (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2719 unsigned int pv ATTRIBUTE_UNUSED
)
2721 /* bgt rt5, ra5, label */
2722 md_assemblef ("slts $ta,%s,%s", argv
[1], argv
[0]);
2723 md_assemblef ("beqz $ta,%s", argv
[2]);
2727 do_pseudo_blt (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2728 unsigned int pv ATTRIBUTE_UNUSED
)
2730 /* rt5, ra5, label */
2731 md_assemblef ("slt $ta,%s,%s", argv
[0], argv
[1]);
2732 md_assemblef ("bnez $ta,%s", argv
[2]);
2736 do_pseudo_blts (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2737 unsigned int pv ATTRIBUTE_UNUSED
)
2739 /* rt5, ra5, label */
2740 md_assemblef ("slts $ta,%s,%s", argv
[0], argv
[1]);
2741 md_assemblef ("bnez $ta,%s", argv
[2]);
2745 do_pseudo_br (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2746 unsigned int pv ATTRIBUTE_UNUSED
)
2748 md_assemblef ("jr %s", argv
[0]);
2752 do_pseudo_bral (int argc
, char *argv
[],
2753 unsigned int pv ATTRIBUTE_UNUSED
)
2756 md_assemblef ("jral $lp,%s", argv
[0]);
2758 md_assemblef ("jral %s,%s", argv
[0], argv
[1]);
2762 do_pseudo_la_internal (const char *arg_reg
, char *arg_label
,
2767 parse_expression (arg_label
, &exp
);
2768 if (exp
.X_op
!= O_symbol
)
2770 as_bad (_("la must use with symbol. '%s'"), line
);
2776 if (!nds32_pic
&& !strstr (arg_label
, "@"))
2778 md_assemblef ("sethi %s,hi20(%s)", arg_reg
, arg_label
);
2779 md_assemblef ("ori %s,%s,lo12(%s)", arg_reg
, arg_reg
, arg_label
);
2781 else if (strstr (arg_label
, "@TPOFF"))
2783 /* la $rt, sym@TPOFF */
2784 md_assemblef ("sethi $ta,hi20(%s)", arg_label
);
2785 md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label
);
2786 md_assemblef ("add %s,$ta,%s", arg_reg
, TLS_REG
);
2788 else if (strstr(arg_label
, "@GOTTPOFF"))
2790 /* la $rt, sym@GOTTPOFF*/
2791 md_assemblef ("sethi $ta,hi20(%s)", arg_label
);
2792 md_assemblef ("lwi $ta,[$ta+lo12(%s)]", arg_label
);
2793 md_assemblef ("add %s,$ta,%s", arg_reg
, TLS_REG
);
2795 else if (nds32_pic
&& ((strstr (arg_label
, "@PLT")
2796 || strstr (arg_label
, "@GOTOFF"))))
2798 md_assemblef ("sethi $ta,hi20(%s)", arg_label
);
2799 md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label
);
2800 md_assemblef ("add %s,$ta,$gp", arg_reg
);
2802 else if (nds32_pic
&& strstr (arg_label
, "@GOT"))
2804 long addend
= builtin_addend (arg_label
, NULL
);
2806 md_assemblef ("sethi $ta,hi20(%s)", arg_label
);
2807 md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label
);
2808 md_assemblef ("lw %s,[$gp+$ta]", arg_reg
);
2811 if (addend
< 0x4000 && addend
>= -0x4000)
2813 md_assemblef ("addi %s,%s,%d", arg_reg
, arg_reg
, addend
);
2817 do_pseudo_li_internal ("$ta", addend
);
2818 md_assemblef ("add %s,$ta,%s", arg_reg
, arg_reg
);
2823 as_bad (_("need PIC qualifier with symbol. '%s'"), line
);
2828 do_pseudo_la (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2829 unsigned int pv ATTRIBUTE_UNUSED
)
2831 do_pseudo_la_internal (argv
[0], argv
[1], argv
[argc
]);
2835 do_pseudo_li_internal (const char *rt
, int imm32s
)
2837 if (enable_16bit
&& imm32s
<= 0xf && imm32s
>= -0x10)
2838 md_assemblef ("movi55 %s,%d", rt
, imm32s
);
2839 else if (imm32s
<= 0x7ffff && imm32s
>= -0x80000)
2840 md_assemblef ("movi %s,%d", rt
, imm32s
);
2841 else if ((imm32s
& 0xfff) == 0)
2842 md_assemblef ("sethi %s,hi20(%d)", rt
, imm32s
);
2845 md_assemblef ("sethi %s,hi20(%d)", rt
, imm32s
);
2846 md_assemblef ("ori %s,%s,lo12(%d)", rt
, rt
, imm32s
);
2851 do_pseudo_li (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2852 unsigned int pv ATTRIBUTE_UNUSED
)
2854 /* Validate argv[1] for constant expression. */
2857 parse_expression (argv
[1], &exp
);
2858 if (exp
.X_op
!= O_constant
)
2860 as_bad (_("Operand is not a constant. `%s'"), argv
[argc
]);
2864 do_pseudo_li_internal (argv
[0], exp
.X_add_number
);
2868 do_pseudo_ls_bhw (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2873 const char *sign
= "";
2875 /* Prepare arguments for various load/store. */
2876 sign
= (pv
& 0x10) ? "s" : "";
2877 ls
= (pv
& 0x80000000) ? 's' : 'l';
2880 case 0: size
= 'b'; break;
2881 case 1: size
= 'h'; break;
2882 case 2: size
= 'w'; break;
2885 if (ls
== 's' || size
== 'w')
2888 if (builtin_isreg (argv
[1], NULL
))
2891 md_assemblef ("%c%ci %s,[%s]", ls
, size
, argv
[0], argv
[1]);
2893 else if (!nds32_pic
)
2896 if (strstr (argv
[1], "@TPOFF"))
2898 /* ls.w $rt, sym@TPOFF */
2899 md_assemblef ("sethi $ta,hi20(%s)", argv
[1]);
2900 md_assemblef ("ori $ta,$ta,lo12(%s)", argv
[1]);
2901 md_assemblef ("%c%c%s %s,[$ta+%s]", ls
, size
, sign
, argv
[0], TLS_REG
);
2903 else if (strstr (argv
[1], "@GOTTPOFF"))
2905 /* ls.w $rt, sym@GOTTPOFF */
2906 md_assemblef ("sethi $ta,hi20(%s)", argv
[1]);
2907 md_assemblef ("lwi $ta,[$ta+lo12(%s)]", argv
[1]);
2908 md_assemblef ("%c%c%s %s,[$ta+%s]", ls
, size
, sign
, argv
[0], TLS_REG
);
2913 md_assemblef ("sethi $ta,hi20(%s)", argv
[1]);
2914 md_assemblef ("%c%c%si %s,[$ta+lo12(%s)]", ls
, size
, sign
, argv
[0], argv
[1]);
2922 if (strstr (argv
[1], "@GOTOFF"))
2925 md_assemblef ("sethi $ta,hi20(%s)", argv
[1]);
2926 md_assemblef ("ori $ta,$ta,lo12(%s)", argv
[1]);
2927 md_assemblef ("%c%c%s %s,[$ta+$gp]", ls
, size
, sign
, argv
[0]);
2929 else if (strstr (argv
[1], "@GOT"))
2931 long addend
= builtin_addend (argv
[1], NULL
);
2933 md_assemblef ("sethi $ta,hi20(%s)", argv
[1]);
2934 md_assemblef ("ori $ta,$ta,lo12(%s)", argv
[1]);
2935 md_assemble ((char *) "lw $ta,[$gp+$ta]"); /* Load address word. */
2936 if (addend
< 0x10000 && addend
>= -0x10000)
2938 md_assemblef ("%c%c%si %s,[$ta+(%d)]", ls
, size
, sign
, argv
[0], addend
);
2943 do_pseudo_li_internal (argv
[0], addend
);
2944 md_assemblef ("%c%c%s %s,[$ta+%s]", ls
, size
, sign
, argv
[0], argv
[0]);
2949 as_bad (_("needs @GOT or @GOTOFF. %s"), argv
[argc
]);
2956 do_pseudo_ls_bhwp (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2959 char *arg_rt
= argv
[0];
2960 char *arg_label
= argv
[1];
2961 char *arg_inc
= argv
[2];
2964 const char *sign
= "";
2966 /* Prepare arguments for various load/store. */
2967 sign
= (pv
& 0x10) ? "s" : "";
2968 ls
= (pv
& 0x80000000) ? 's' : 'l';
2971 case 0: size
= 'b'; break;
2972 case 1: size
= 'h'; break;
2973 case 2: size
= 'w'; break;
2976 if (ls
== 's' || size
== 'w')
2979 do_pseudo_la_internal ("$ta", arg_label
, argv
[argc
]);
2980 md_assemblef ("%c%c%si.bi %s,[$ta],%s", ls
, size
, sign
, arg_rt
, arg_inc
);
2984 do_pseudo_ls_bhwpc (int argc ATTRIBUTE_UNUSED
, char *argv
[],
2987 char *arg_rt
= argv
[0];
2988 char *arg_inc
= argv
[1];
2991 const char *sign
= "";
2993 /* Prepare arguments for various load/store. */
2994 sign
= (pv
& 0x10) ? "s" : "";
2995 ls
= (pv
& 0x80000000) ? 's' : 'l';
2998 case 0: size
= 'b'; break;
2999 case 1: size
= 'h'; break;
3000 case 2: size
= 'w'; break;
3003 if (ls
== 's' || size
== 'w')
3006 md_assemblef ("%c%c%si.bi %s,[$ta],%s", ls
, size
, sign
, arg_rt
, arg_inc
);
3010 do_pseudo_ls_bhwi (int argc ATTRIBUTE_UNUSED
, char *argv
[],
3015 const char *sign
= "";
3017 /* Prepare arguments for various load/store. */
3018 sign
= (pv
& 0x10) ? "s" : "";
3019 ls
= (pv
& 0x80000000) ? 's' : 'l';
3022 case 0: size
= 'b'; break;
3023 case 1: size
= 'h'; break;
3024 case 2: size
= 'w'; break;
3027 if (ls
== 's' || size
== 'w')
3030 md_assemblef ("%c%c%si.bi %s,%s,%s",
3031 ls
, size
, sign
, argv
[0], argv
[1], argv
[2]);
3035 do_pseudo_move_reg_internal (char *dst
, char *src
)
3038 md_assemblef ("mov55 %s,%s", dst
, src
);
3040 md_assemblef ("ori %s,%s,0", dst
, src
);
3044 do_pseudo_move (int argc ATTRIBUTE_UNUSED
, char *argv
[],
3045 unsigned int pv ATTRIBUTE_UNUSED
)
3049 if (builtin_isreg (argv
[1], NULL
))
3050 do_pseudo_move_reg_internal (argv
[0], argv
[1]);
3053 parse_expression (argv
[1], &exp
);
3054 if (exp
.X_op
== O_constant
)
3055 /* move $rt, imm -> li $rt, imm */
3056 do_pseudo_li_internal (argv
[0], exp
.X_add_number
);
3058 /* l.w $rt, var -> l.w $rt, var */
3059 do_pseudo_ls_bhw (argc
, argv
, 2);
3064 do_pseudo_neg (int argc ATTRIBUTE_UNUSED
, char *argv
[],
3065 unsigned int pv ATTRIBUTE_UNUSED
)
3067 /* Instead of "subri". */
3068 md_assemblef ("subri %s,%s,0", argv
[0], argv
[1]);
3072 do_pseudo_not (int argc ATTRIBUTE_UNUSED
, char *argv
[],
3073 unsigned int pv ATTRIBUTE_UNUSED
)
3075 md_assemblef ("nor %s,%s,%s", argv
[0], argv
[1], argv
[1]);
3079 do_pseudo_pushpopm (int argc
, char *argv
[],
3080 unsigned int pv ATTRIBUTE_UNUSED
)
3082 /* posh/pop $ra, $rb */
3083 /* SMW.{b | a}{i | d}{m?} Rb, [Ra], Re, Enable4 */
3084 int rb
, re
, ra
, en4
;
3086 const char *opc
= "pushpopm";
3089 as_bad ("'pushm/popm $ra5, $rb5, $label' is deprecated. "
3090 "Only 'pushm/popm $ra5' is supported now. %s", argv
[argc
]);
3092 as_bad ("'pushm/popm $ra5, $rb5'. %s\n", argv
[argc
]);
3094 if (strstr (argv
[argc
], "pop") == argv
[argc
])
3096 else if (strstr (argv
[argc
], "push") == argv
[argc
])
3099 as_fatal ("nds32-as internal error. %s", argv
[argc
]);
3101 rb
= builtin_regnum (argv
[0], NULL
);
3102 re
= builtin_regnum (argv
[1], NULL
);
3106 as_warn ("$rb should not be smaller than $ra. %s", argv
[argc
]);
3107 /* Swap to right order. */
3113 /* Build enable4 mask. */
3115 if (re
>= 28 || rb
>= 28)
3117 for (i
= (rb
>= 28? rb
: 28); i
<= re
; i
++)
3118 en4
|= 1 << (3 - (i
- 28));
3121 /* Adjust $re, $rb. */
3124 else if (nds32_gpr16
!= 1 && re
>= 28)
3127 /* Reduce register. */
3128 if (nds32_gpr16
&& re
> 10 && !(rb
== 31 && re
== 31))
3130 if (re
>= 15 && strstr (opc
, "smw") != NULL
)
3131 md_assemblef ("%s $r15,[$sp],$r15,%d", opc
, en4
);
3133 md_assemblef ("%s $r%d,[$sp],$r10, 0x0", opc
, rb
);
3134 if (re
>= 15 && strstr (opc
, "lmw") != NULL
)
3135 md_assemblef ("%s $r15,[$sp],$r15,%d", opc
, en4
);
3138 md_assemblef ("%s $r%d,[$sp],$r%d,%d", opc
, rb
, re
, en4
);
3142 do_pseudo_pushpop (int argc
, char *argv
[],
3143 unsigned int pv ATTRIBUTE_UNUSED
)
3145 /* push/pop $ra5, $label=$sp */
3149 as_bad ("'push/pop $ra5, rb5' is deprecated. "
3150 "Only 'push/pop $ra5' is supported now. %s", argv
[argc
]);
3154 argvm
[2] = argv
[argc
];
3155 do_pseudo_pushpopm (2, argvm
, PV_DONT_CARE
);
3159 do_pseudo_v3push (int argc ATTRIBUTE_UNUSED
, char *argv
[],
3160 unsigned int pv ATTRIBUTE_UNUSED
)
3162 md_assemblef ("push25 %s,%s", argv
[0], argv
[1]);
3166 do_pseudo_v3pop (int argc ATTRIBUTE_UNUSED
, char *argv
[],
3167 unsigned int pv ATTRIBUTE_UNUSED
)
3169 md_assemblef ("pop25 %s,%s", argv
[0], argv
[1]);
3172 /* pv == 0, parsing "push.s" pseudo instruction operands.
3173 pv != 0, parsing "pop.s" pseudo instruction operands. */
3176 do_pseudo_pushpop_stack (int argc
, char *argv
[],
3179 /* push.s Rb,Re,{$fp $gp $lp $sp} ==> smw.adm Rb,[$sp],Re,Eable4 */
3180 /* pop.s Rb,Re,{$fp $gp $lp $sp} ==> lmw.bim Rb,[$sp],Re,Eable4 */
3185 const char *opc
= (pv
== 0) ? "smw.adm" : "lmw.bim";
3191 /* argc=1, operands pattern: { $fp $gp $lp $sp } */
3193 /* Set register number Rb = Re = $sp = $r31. */
3196 else if (argc
== 2 || argc
== 3)
3198 /* argc=2, operands pattern: Rb, Re */
3199 /* argc=3, operands pattern: Rb, Re, { $fp $gp $lp $sp } */
3201 /* Get register number in integer. */
3202 rb
= builtin_regnum (argv
[0], NULL
);
3203 re
= builtin_regnum (argv
[1], NULL
);
3205 /* Rb should be equal/less than Re. */
3207 as_bad ("The first operand (%s) should be equal to or smaller than "
3208 "second operand (%s).", argv
[0], argv
[1]);
3210 /* forbid using $fp|$gp|$lp|$sp in Rb or Re
3213 as_bad ("Cannot use $fp, $gp, $lp, or $sp at first operand !!");
3215 as_bad ("Cannot use $fp, $gp, $lp, or $sp at second operand !!");
3219 as_bad ("Invalid operands pattern !!");
3222 /* Build Enable4 mask. */
3223 /* Using last_arg_index for argc=1|2|3 is safe, because $fp, $gp, $lp,
3224 and $sp only appear in argc=1 or argc=3 if argc=2, en4 remains 0,
3225 which is also valid for code generation. */
3227 last_arg_index
= argc
- 1;
3228 if (strstr (argv
[last_arg_index
], "$fp"))
3230 if (strstr (argv
[last_arg_index
], "$gp"))
3232 if (strstr (argv
[last_arg_index
], "$lp"))
3234 if (strstr (argv
[last_arg_index
], "$sp"))
3237 md_assemblef ("%s $r%d,[$sp],$r%d,%d", opc
, rb
, re
, en4
);
3241 do_pseudo_push_bhwd (int argc ATTRIBUTE_UNUSED
, char *argv
[],
3242 unsigned int pv ATTRIBUTE_UNUSED
)
3245 /* If users omit push location, use $sp as default value. */
3246 char location
[8] = "$sp"; /* 8 is enough for register name. */
3250 case 0: size
= 'b'; break;
3251 case 1: size
= 'h'; break;
3252 case 2: size
= 'w'; break;
3253 case 3: size
= 'w'; break;
3258 strncpy (location
, argv
[1], 8);
3262 md_assemblef ("l.%c $ta,%s", size
, argv
[0]);
3263 md_assemblef ("smw.adm $ta,[%s],$ta", location
);
3265 if ((pv
& 0x3) == 0x3) /* double-word */
3267 md_assemblef ("l.w $ta,%s+4", argv
[0]);
3268 md_assemblef ("smw.adm $ta,[%s],$ta", location
);
3273 do_pseudo_pop_bhwd (int argc ATTRIBUTE_UNUSED
, char *argv
[],
3274 unsigned int pv ATTRIBUTE_UNUSED
)
3277 /* If users omit pop location, use $sp as default value. */
3278 char location
[8] = "$sp"; /* 8 is enough for register name. */
3282 case 0: size
= 'b'; break;
3283 case 1: size
= 'h'; break;
3284 case 2: size
= 'w'; break;
3285 case 3: size
= 'w'; break;
3290 strncpy (location
, argv
[2], 8);
3294 if ((pv
& 0x3) == 0x3) /* double-word */
3296 md_assemblef ("lmw.bim %s,[%s],%s", argv
[1], location
, argv
[1]);
3297 md_assemblef ("s.w %s,%s+4", argv
[1], argv
[0]);
3300 md_assemblef ("lmw.bim %s,[%s],%s", argv
[1], location
, argv
[1]);
3301 md_assemblef ("s.%c %s,%s", size
, argv
[1], argv
[0]);
3305 do_pseudo_pusha (int argc ATTRIBUTE_UNUSED
, char *argv
[],
3306 unsigned int pv ATTRIBUTE_UNUSED
)
3308 /* If users omit push location, use $sp as default value. */
3309 char location
[8] = "$sp"; /* 8 is enough for register name. */
3313 strncpy (location
, argv
[1], 8);
3317 md_assemblef ("la $ta,%s", argv
[0]);
3318 md_assemblef ("smw.adm $ta,[%s],$ta", location
);
3322 do_pseudo_pushi (int argc ATTRIBUTE_UNUSED
, char *argv
[],
3323 unsigned int pv ATTRIBUTE_UNUSED
)
3325 /* If users omit push location, use $sp as default value. */
3326 char location
[8] = "$sp"; /* 8 is enough for register name. */
3330 strncpy (location
, argv
[1], 8);
3334 md_assemblef ("li $ta,%s", argv
[0]);
3335 md_assemblef ("smw.adm $ta,[%s],$ta", location
);
3338 static struct nds32_pseudo_opcode nds32_pseudo_opcode_table
[] =
3340 {"b", 1, do_pseudo_b
, 0, 0},
3341 {"bal", 1, do_pseudo_bal
, 0, 0},
3343 {"bge", 3, do_pseudo_bge
, 0, 0},
3344 {"bges", 3, do_pseudo_bges
, 0, 0},
3346 {"bgt", 3, do_pseudo_bgt
, 0, 0},
3347 {"bgts", 3, do_pseudo_bgts
, 0, 0},
3349 {"ble", 3, do_pseudo_ble
, 0, 0},
3350 {"bles", 3, do_pseudo_bles
, 0, 0},
3352 {"blt", 3, do_pseudo_blt
, 0, 0},
3353 {"blts", 3, do_pseudo_blts
, 0, 0},
3355 {"br", 1, do_pseudo_br
, 0, 0},
3356 {"bral", 1, do_pseudo_bral
, 0, 0},
3358 {"call", 1, do_pseudo_bal
, 0, 0},
3360 {"la", 2, do_pseudo_la
, 0, 0},
3361 {"li", 2, do_pseudo_li
, 0, 0},
3363 {"l.b", 2, do_pseudo_ls_bhw
, 0, 0},
3364 {"l.h", 2, do_pseudo_ls_bhw
, 1, 0},
3365 {"l.w", 2, do_pseudo_ls_bhw
, 2, 0},
3366 {"l.bs", 2, do_pseudo_ls_bhw
, 0 | 0x10, 0},
3367 {"l.hs", 2, do_pseudo_ls_bhw
, 1 | 0x10, 0},
3368 {"s.b", 2, do_pseudo_ls_bhw
, 0 | 0x80000000, 0},
3369 {"s.h", 2, do_pseudo_ls_bhw
, 1 | 0x80000000, 0},
3370 {"s.w", 2, do_pseudo_ls_bhw
, 2 | 0x80000000, 0},
3372 {"l.bp", 3, do_pseudo_ls_bhwp
, 0, 0},
3373 {"l.bpc", 3, do_pseudo_ls_bhwpc
, 0, 0},
3374 {"l.hp", 3, do_pseudo_ls_bhwp
, 1, 0},
3375 {"l.hpc", 3, do_pseudo_ls_bhwpc
, 1, 0},
3376 {"l.wp", 3, do_pseudo_ls_bhwp
, 2, 0},
3377 {"l.wpc", 3, do_pseudo_ls_bhwpc
, 2, 0},
3378 {"l.bsp", 3, do_pseudo_ls_bhwp
, 0 | 0x10, 0},
3379 {"l.bspc", 3, do_pseudo_ls_bhwpc
, 0 | 0x10, 0},
3380 {"l.hsp", 3, do_pseudo_ls_bhwp
, 1 | 0x10, 0},
3381 {"l.hspc", 3, do_pseudo_ls_bhwpc
, 1 | 0x10, 0},
3382 {"s.bp", 3, do_pseudo_ls_bhwp
, 0 | 0x80000000, 0},
3383 {"s.bpc", 3, do_pseudo_ls_bhwpc
, 0 | 0x80000000, 0},
3384 {"s.hp", 3, do_pseudo_ls_bhwp
, 1 | 0x80000000, 0},
3385 {"s.hpc", 3, do_pseudo_ls_bhwpc
, 1 | 0x80000000, 0},
3386 {"s.wp", 3, do_pseudo_ls_bhwp
, 2 | 0x80000000, 0},
3387 {"s.wpc", 3, do_pseudo_ls_bhwpc
, 2 | 0x80000000, 0},
3388 {"s.bsp", 3, do_pseudo_ls_bhwp
, 0 | 0x80000000 | 0x10, 0},
3389 {"s.hsp", 3, do_pseudo_ls_bhwp
, 1 | 0x80000000 | 0x10, 0},
3391 {"lbi.p", 3, do_pseudo_ls_bhwi
, 0, 0},
3392 {"lhi.p", 3, do_pseudo_ls_bhwi
, 1, 0},
3393 {"lwi.p", 3, do_pseudo_ls_bhwi
, 2, 0},
3394 {"sbi.p", 3, do_pseudo_ls_bhwi
, 0 | 0x80000000, 0},
3395 {"shi.p", 3, do_pseudo_ls_bhwi
, 1 | 0x80000000, 0},
3396 {"swi.p", 3, do_pseudo_ls_bhwi
, 2 | 0x80000000, 0},
3397 {"lbsi.p", 3, do_pseudo_ls_bhwi
, 0 | 0x10, 0},
3398 {"lhsi.p", 3, do_pseudo_ls_bhwi
, 1 | 0x10, 0},
3399 {"lwsi.p", 3, do_pseudo_ls_bhwi
, 2 | 0x10, 0},
3401 {"move", 2, do_pseudo_move
, 0, 0},
3402 {"neg", 2, do_pseudo_neg
, 0, 0},
3403 {"not", 2, do_pseudo_not
, 0, 0},
3405 {"pop", 2, do_pseudo_pushpop
, 0, 0},
3406 {"push", 2, do_pseudo_pushpop
, 0, 0},
3407 {"popm", 2, do_pseudo_pushpopm
, 0, 0},
3408 {"pushm", 3, do_pseudo_pushpopm
, 0, 0},
3410 {"v3push", 2, do_pseudo_v3push
, 0, 0},
3411 {"v3pop", 2, do_pseudo_v3pop
, 0, 0},
3413 /* Support pseudo instructions of pushing/poping registers into/from stack
3414 push.s Rb, Re, { $fp $gp $lp $sp } ==> smw.adm Rb,[$sp],Re,Enable4
3415 pop.s Rb, Re, { $fp $gp $lp $sp } ==> lmw.bim Rb,[$sp],Re,Enable4 */
3416 { "push.s", 3, do_pseudo_pushpop_stack
, 0, 0 },
3417 { "pop.s", 3, do_pseudo_pushpop_stack
, 1, 0 },
3418 { "push.b", 2, do_pseudo_push_bhwd
, 0, 0 },
3419 { "push.h", 2, do_pseudo_push_bhwd
, 1, 0 },
3420 { "push.w", 2, do_pseudo_push_bhwd
, 2, 0 },
3421 { "push.d", 2, do_pseudo_push_bhwd
, 3, 0 },
3422 { "pop.b", 3, do_pseudo_pop_bhwd
, 0, 0 },
3423 { "pop.h", 3, do_pseudo_pop_bhwd
, 1, 0 },
3424 { "pop.w", 3, do_pseudo_pop_bhwd
, 2, 0 },
3425 { "pop.d", 3, do_pseudo_pop_bhwd
, 3, 0 },
3426 { "pusha", 2, do_pseudo_pusha
, 0, 0 },
3427 { "pushi", 2, do_pseudo_pushi
, 0, 0 },
3429 {NULL
, 0, NULL
, 0, 0}
3433 nds32_init_nds32_pseudo_opcodes (void)
3435 struct nds32_pseudo_opcode
*opcode
;
3437 nds32_pseudo_opcode_hash
= str_htab_create ();
3438 for (opcode
= nds32_pseudo_opcode_table
; opcode
->opcode
; opcode
++)
3439 if (str_hash_insert (nds32_pseudo_opcode_hash
, opcode
->opcode
, opcode
, 0))
3440 as_fatal (_("duplicate %s"), opcode
->opcode
);
3443 static struct nds32_pseudo_opcode
*
3444 nds32_lookup_pseudo_opcode (const char *str
)
3446 struct nds32_pseudo_opcode
*result
;
3449 /* (*op) is the first word of current source line (*str) */
3450 int maxlen
= strlen (str
);
3451 char *op
= xmalloc (maxlen
+ 1);
3453 for (i
= 0; i
< maxlen
; i
++)
3455 if (ISSPACE (op
[i
] = str
[i
]))
3460 result
= str_hash_find (nds32_pseudo_opcode_hash
, op
);
3466 nds32_pseudo_opcode_wrapper (char *line
, struct nds32_pseudo_opcode
*opcode
)
3469 char *argv
[8] = {NULL
};
3471 char *str
= xstrdup (line
);
3473 /* Parse arguments for opcode. */
3474 s
= str
+ strlen (opcode
->opcode
);
3479 /* Dummy comma to ease separate arguments as below. */
3485 if (argc
>= opcode
->argc
3486 || (argc
>= (int)ARRAY_SIZE (argv
) - 1))
3487 as_bad (_("Too many argument. `%s'"), line
);
3494 } while (s
[0] != '\0');
3496 /* Put the origin line for debugging. */
3498 opcode
->proc (argc
, argv
, opcode
->pseudo_val
);
3502 /* This function will be invoked from function `nds32_after_parse_args'.
3503 Thus, if the value of option has been set, keep the value the way it is. */
3506 nds32_parse_arch (const char *str
)
3508 static const struct nds32_arch
3519 {"v3m", ISA_V3M
, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_AABI
},
3520 {"v3j", ISA_V3
, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_AABI
},
3521 {"v3s", ISA_V3
, 0, 1, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_V2FP_PLUS
},
3522 {"v3f", ISA_V3
, 0, 1, 1, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_V2FP_PLUS
},
3523 {"v3", ISA_V3
, 0, 0, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_AABI
},
3524 {"v2j", ISA_V2
, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_AABI
},
3525 {"v2s", ISA_V2
, 0, 1, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_V2FP_PLUS
},
3526 {"v2f", ISA_V2
, 0, 1, 1, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_V2FP_PLUS
},
3527 {"v2", ISA_V2
, 0, 0, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_AABI
},
3531 for (i
= 0; i
< ARRAY_SIZE (archs
); i
++)
3533 if (strcmp (str
, archs
[i
].name
) != 0)
3536 /* The value `-1' represents this option has *NOT* been set. */
3537 nds32_baseline
= (-1 != nds32_baseline
) ? nds32_baseline
: archs
[i
].baseline
;
3538 nds32_gpr16
= (-1 != nds32_gpr16
) ? nds32_gpr16
: archs
[i
].reduced_reg
;
3539 nds32_fpu_sp_ext
= (-1 != nds32_fpu_sp_ext
) ? nds32_fpu_sp_ext
: archs
[i
].fpu_sp_ext
;
3540 nds32_fpu_dp_ext
= (-1 != nds32_fpu_dp_ext
) ? nds32_fpu_dp_ext
: archs
[i
].fpu_dp_ext
;
3541 nds32_freg
= (-1 != nds32_freg
) ? nds32_freg
: archs
[i
].fpu_freg
;
3542 nds32_abi
= (-1 != nds32_abi
) ? nds32_abi
: archs
[i
].abi
;
3547 /* Logic here rejects the input arch name. */
3548 as_bad (_("unknown arch name `%s'\n"), str
);
3553 /* This function parses "baseline" specified. */
3556 nds32_parse_baseline (const char *str
)
3558 if (strcmp (str
, "v3") == 0)
3559 nds32_baseline
= ISA_V3
;
3560 else if (strcmp (str
, "v3m") == 0)
3561 nds32_baseline
= ISA_V3M
;
3562 else if (strcmp (str
, "v2") == 0)
3563 nds32_baseline
= ISA_V2
;
3566 /* Logic here rejects the input baseline. */
3567 as_bad (_("unknown baseline `%s'\n"), str
);
3574 /* This function parses "fpu-freg" specified. */
3577 nds32_parse_freg (const char *str
)
3579 if (strcmp (str
, "2") == 0)
3580 nds32_freg
= E_NDS32_FPU_REG_32SP_16DP
;
3581 else if (strcmp (str
, "3") == 0)
3582 nds32_freg
= E_NDS32_FPU_REG_32SP_32DP
;
3583 else if (strcmp (str
, "1") == 0)
3584 nds32_freg
= E_NDS32_FPU_REG_16SP_8DP
;
3585 else if (strcmp (str
, "0") == 0)
3586 nds32_freg
= E_NDS32_FPU_REG_8SP_4DP
;
3589 /* Logic here rejects the input FPU configuration. */
3590 as_bad (_("unknown FPU configuration `%s'\n"), str
);
3597 /* This function parse "abi=" specified. */
3600 nds32_parse_abi (const char *str
)
3602 if (strcmp (str
, "v2") == 0)
3603 nds32_abi
= E_NDS_ABI_AABI
;
3605 else if (strcmp (str
, "v2fp") == 0)
3606 nds32_abi
= E_NDS_ABI_V2FP
;
3607 else if (strcmp (str
, "v1") == 0)
3608 nds32_abi
= E_NDS_ABI_V1
;
3609 else if (strcmp (str
,"v2fpp") == 0)
3610 nds32_abi
= E_NDS_ABI_V2FP_PLUS
;
3613 /* Logic here rejects the input abi version. */
3614 as_bad (_("unknown ABI version`%s'\n"), str
);
3621 /* This function turn on all extensions and instructions support. */
3624 nds32_all_ext (void)
3629 nds32_16bit_ext
= 1;
3631 nds32_perf_ext2
= 1;
3632 nds32_string_ext
= 1;
3633 nds32_audio_ext
= 1;
3635 nds32_fpu_sp_ext
= 1;
3636 nds32_fpu_dp_ext
= 1;
3639 /* Turn off reduced register. */
3645 /* GAS will call md_parse_option whenever getopt returns an unrecognized code,
3646 presumably indicating a special code value which appears in md_longopts.
3647 This function should return non-zero if it handled the option and zero
3648 otherwise. There is no need to print a message about an option not being
3649 recognized. This will be handled by the generic code. */
3652 nds32_parse_option (int c
, const char *arg
)
3654 struct nds32_parse_option_table
*coarse_tune
;
3655 struct nds32_set_option_table
*fine_tune
;
3656 const char *ptr_arg
= NULL
;
3660 case OPTION_OPTIMIZE
:
3662 optimize_for_space
= 0;
3664 case OPTION_OPTIMIZE_SPACE
:
3666 optimize_for_space
= 1;
3669 target_big_endian
= 1;
3672 target_big_endian
= 0;
3680 case OPTION_RELAX_FP_AS_GP_OFF
:
3681 nds32_relax_fp_as_gp
= 0;
3683 case OPTION_RELAX_B2BB_ON
:
3684 nds32_relax_b2bb
= 1;
3686 case OPTION_RELAX_ALL_OFF
:
3687 nds32_relax_all
= 0;
3690 /* Determination of which option table to search for to save time. */
3694 ptr_arg
= strchr (arg
, '=');
3698 /* Find the value after '='. */
3699 if (ptr_arg
!= NULL
)
3701 for (coarse_tune
= parse_opts
; coarse_tune
->name
!= NULL
; coarse_tune
++)
3703 if (strncmp (arg
, coarse_tune
->name
, (ptr_arg
- arg
)) == 0)
3705 coarse_tune
->func (ptr_arg
);
3714 /* Filter out the Disable option first. */
3715 if (strncmp (arg
, "no-", 3) == 0)
3721 for (fine_tune
= toggle_opts
; fine_tune
->name
!= NULL
; fine_tune
++)
3723 if (strcmp (arg
, fine_tune
->name
) == 0)
3725 if (fine_tune
->var
!= NULL
)
3726 *fine_tune
->var
= (disable
) ? 0 : 1;
3731 /* Nothing match. */
3738 /* tc_check_label */
3741 nds32_check_label (symbolS
*label ATTRIBUTE_UNUSED
)
3743 /* The code used to create BB is move to frob_label.
3744 They should go there. */
3748 set_endian_little (int on
)
3750 target_big_endian
= !on
;
3753 /* These functions toggles the generation of 16-bit. First encounter signals
3754 the beginning of not generating 16-bit instructions and next encounter
3755 signals the restoring back to default behavior. */
3758 trigger_16bit (int trigger
)
3760 enable_16bit
= trigger
;
3763 static int backup_16bit_mode
;
3765 restore_16bit (int no_use ATTRIBUTE_UNUSED
)
3767 enable_16bit
= backup_16bit_mode
;
3771 off_16bit (int no_use ATTRIBUTE_UNUSED
)
3773 backup_16bit_mode
= enable_16bit
;
3777 /* Built-in segments for small object. */
3778 typedef struct nds32_seg_entryT
3785 nds32_seg_entry nds32_seg_table
[] =
3787 {NULL
, ".sdata_f", SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
3788 | SEC_HAS_CONTENTS
| SEC_SMALL_DATA
},
3789 {NULL
, ".sdata_b", SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
3790 | SEC_HAS_CONTENTS
| SEC_SMALL_DATA
},
3791 {NULL
, ".sdata_h", SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
3792 | SEC_HAS_CONTENTS
| SEC_SMALL_DATA
},
3793 {NULL
, ".sdata_w", SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
3794 | SEC_HAS_CONTENTS
| SEC_SMALL_DATA
},
3795 {NULL
, ".sdata_d", SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
3796 | SEC_HAS_CONTENTS
| SEC_SMALL_DATA
},
3797 {NULL
, ".sbss_f", SEC_ALLOC
| SEC_SMALL_DATA
},
3798 {NULL
, ".sbss_b", SEC_ALLOC
| SEC_SMALL_DATA
},
3799 {NULL
, ".sbss_h", SEC_ALLOC
| SEC_SMALL_DATA
},
3800 {NULL
, ".sbss_w", SEC_ALLOC
| SEC_SMALL_DATA
},
3801 {NULL
, ".sbss_d", SEC_ALLOC
| SEC_SMALL_DATA
}
3804 /* Indexes to nds32_seg_table[]. */
3805 enum NDS32_SECTIONS_ENUM
3807 SDATA_F_SECTION
= 0,
3808 SDATA_B_SECTION
= 1,
3809 SDATA_H_SECTION
= 2,
3810 SDATA_W_SECTION
= 3,
3811 SDATA_D_SECTION
= 4,
3819 /* The following code is borrowed from v850_seg. Revise this is needed. */
3822 do_nds32_seg (int i
, subsegT sub
)
3824 nds32_seg_entry
*seg
= nds32_seg_table
+ i
;
3826 obj_elf_section_change_hook ();
3829 subseg_set (seg
->s
, sub
);
3832 seg
->s
= subseg_new (seg
->name
, sub
);
3833 if (OUTPUT_FLAVOR
== bfd_target_elf_flavour
)
3835 bfd_set_section_flags (seg
->s
, seg
->flags
);
3836 if ((seg
->flags
& SEC_LOAD
) == 0)
3837 seg_info (seg
->s
)->bss
= 1;
3845 subsegT sub
= get_absolute_expression ();
3847 do_nds32_seg (i
, sub
);
3848 demand_empty_rest_of_line ();
3851 /* Set if label adjustment is needed. I should not adjust .xbyte in dwarf. */
3852 static symbolS
*nds32_last_label
; /* Last label for alignment. */
3855 add_mapping_symbol_for_align (int shift
, valueT addr
, int is_data_align
)
3857 if ((shift
> 1) && (addr
& 1))
3859 int n
= (1 << shift
) - 1;
3861 add_mapping_symbol (MAP_CODE
, 1, 0);
3862 else if ((int) (addr
& n
) != n
)
3863 add_mapping_symbol (MAP_CODE
, 1, 0);
3865 else if ((shift
> 1) && ((int) (addr
& 1) == 0))
3866 add_mapping_symbol (MAP_CODE
, 0, 0);
3869 /* This code is referred from D30V for adjust label to be with pending
3870 alignment. For example,
3874 Without this, the above label will not attach to incoming data. */
3877 nds32_adjust_label (int n
)
3879 /* FIXME: I think adjust label and alignment is
3880 the programmer's obligation. Sadly, VLSI team doesn't
3881 properly use .align for their test cases.
3882 So I re-implement cons_align and auto adjust labels, again.
3884 I think d30v's implementation is simple and good enough. */
3886 symbolS
*label
= nds32_last_label
;
3887 nds32_last_label
= NULL
;
3889 /* SEC_ALLOC is used to eliminate .debug_ sections.
3890 SEC_CODE is used to include section for ILM. */
3891 if (((now_seg
->flags
& SEC_ALLOC
) == 0 && (now_seg
->flags
& SEC_CODE
) == 0)
3892 || strcmp (now_seg
->name
, ".eh_frame") == 0
3893 || strcmp (now_seg
->name
, ".gcc_except_table") == 0)
3896 /* Only frag by alignment when needed.
3897 Otherwise, it will fail to optimize labels on 4-byte boundary. (bug8454)
3898 See md_convert_frag () and RELAX_SET_RELAXABLE (frag) for details. */
3899 if (frag_now_fix () & ((1 << n
) -1 ))
3901 if (subseg_text_p (now_seg
))
3903 add_mapping_symbol_for_align (n
, frag_now_fix (), 1);
3904 frag_align_code (n
, 0);
3907 frag_align (n
, 0, 0);
3909 /* Record the minimum alignment for this segment. */
3910 record_alignment (now_seg
, n
- OCTETS_PER_BYTE_POWER
);
3916 int label_seen
= FALSE
;
3917 struct frag
*old_frag
;
3918 valueT old_value
, new_value
;
3920 gas_assert (S_GET_SEGMENT (label
) == now_seg
);
3922 old_frag
= symbol_get_frag (label
);
3923 old_value
= S_GET_VALUE (label
);
3924 new_value
= (valueT
) frag_now_fix ();
3926 /* Multiple labels may be on the same address. And the last symbol
3927 may not be a label at all, e.g., register name, external function names,
3928 so I have to track the last label in tc_frob_label instead of
3929 just using symbol_lastP. */
3930 for (sym
= symbol_lastP
; sym
!= NULL
; sym
= symbol_previous (sym
))
3932 if (symbol_get_frag (sym
) == old_frag
3933 && S_GET_VALUE (sym
) == old_value
)
3937 symbol_set_frag (sym
, frag_now
);
3938 S_SET_VALUE (sym
, new_value
);
3940 else if (label_seen
&& symbol_get_frag (sym
) != old_frag
)
3947 nds32_cons_align (int size ATTRIBUTE_UNUSED
)
3950 This is called before `md_flush_pending_output' is called by `cons'.
3952 There are two things should be done for auto-adjust-label.
3953 1. Align data/instructions and adjust label to be attached to them.
3954 2. Clear auto-adjust state, so incoming data/instructions will not
3962 in this case, '.word 0x2' will adjust the label, .L0, but '.word 0x3' should not.
3964 I think `md_flush_pending_output' is a good place to clear the auto-adjust state,
3965 but it is also called by `cons' before this function.
3966 To simplify the code, instead of overriding .zero, .fill, .space, etc,
3967 I think we should just adjust label in `nds32_aligned_X_cons' instead of here. */
3971 make_mapping_symbol (enum mstate state
, valueT value
, fragS
* frag
, unsigned int align
)
3973 symbolS
*symbol_p
= NULL
;
3974 const char *symbol_name
= NULL
;
3979 symbol_name
= "$d0";
3980 else if (align
== 1)
3981 symbol_name
= "$d1";
3982 else if (align
== 2)
3983 symbol_name
= "$d2";
3984 else if (align
== 3)
3985 symbol_name
= "$d3";
3986 else if (align
== 4)
3987 symbol_name
= "$d4";
3996 symbol_p
= symbol_new (symbol_name
, now_seg
, frag
, value
);
3997 /* local scope attribute */
3998 symbol_get_bfdsym (symbol_p
)->flags
|= BSF_NO_FLAGS
| BSF_LOCAL
;
4002 add_mapping_symbol (enum mstate state
, unsigned int padding_byte
,
4005 enum mstate current_mapping_state
=
4006 seg_info (now_seg
)->tc_segment_info_data
.mapstate
;
4008 if (state
== MAP_CODE
4009 && current_mapping_state
== state
)
4012 if (!SEG_NORMAL (now_seg
)
4013 || !subseg_text_p (now_seg
))
4016 /* start adding mapping symbol */
4017 seg_info (now_seg
)->tc_segment_info_data
.mapstate
= state
;
4018 make_mapping_symbol (state
, (valueT
) frag_now_fix () + padding_byte
,
4023 nds32_aligned_cons (int idx
)
4025 nds32_adjust_label (idx
);
4026 add_mapping_symbol (MAP_DATA
, 0, idx
);
4027 /* Call default handler. */
4029 if (now_seg
->flags
& SEC_CODE
4030 && now_seg
->flags
& SEC_ALLOC
&& now_seg
->flags
& SEC_RELOC
)
4032 /* Use BFD_RELOC_NDS32_DATA to avoid linker
4033 optimization replacing data. */
4036 exp
.X_add_number
= 0;
4037 exp
.X_op
= O_constant
;
4038 fix_new_exp (frag_now
, frag_now_fix () - (1 << idx
), 1 << idx
,
4039 &exp
, 0, BFD_RELOC_NDS32_DATA
);
4043 /* `.double' directive. */
4046 nds32_aligned_float_cons (int type
)
4054 nds32_adjust_label (2);
4060 nds32_adjust_label (4);
4063 as_bad ("Unrecognized float type, %c\n", (char)type
);
4065 /* Call default handler. */
4070 nds32_enable_pic (int ignore ATTRIBUTE_UNUSED
)
4072 /* Another way to do -mpic.
4073 This is for GCC internal use and should always be first line
4074 of code, otherwise, the effect is not determined. */
4079 nds32_set_abi (int ver
)
4084 /* Relax directive to set relocation R_NDS32_RELAX_ENTRY value. */
4087 nds32_relax_relocs (int relax
)
4092 const char *subtype_relax
[] =
4095 name
= input_line_pointer
;
4096 while (*input_line_pointer
&& !ISSPACE (*input_line_pointer
))
4097 input_line_pointer
++;
4098 saved_char
= *input_line_pointer
;
4099 *input_line_pointer
= 0;
4101 for (i
= 0; i
< (int) ARRAY_SIZE (subtype_relax
); i
++)
4103 if (strcmp (name
, subtype_relax
[i
]) == 0)
4109 enable_relax_relocs
= relax
& enable_relax_relocs
;
4117 *input_line_pointer
= saved_char
;
4118 ignore_rest_of_line ();
4121 /* Record which arguments register($r0 ~ $r5) is not used in callee.
4125 nds32_set_hint_func_args (int ignore ATTRIBUTE_UNUSED
)
4127 ignore_rest_of_line ();
4130 /* Insert relocations to mark the begin and end of a fp-omitted function,
4131 for further relaxation use.
4135 nds32_omit_fp_begin (int mode
)
4139 if (nds32_relax_fp_as_gp
== 0)
4141 exp
.X_op
= O_symbol
;
4142 exp
.X_add_symbol
= abs_section_sym
;
4146 exp
.X_add_number
= R_NDS32_RELAX_REGION_OMIT_FP_FLAG
;
4147 fix_new_exp (frag_now
, frag_now_fix (), 0, &exp
, 0,
4148 BFD_RELOC_NDS32_RELAX_REGION_BEGIN
);
4153 exp
.X_add_number
= R_NDS32_RELAX_REGION_OMIT_FP_FLAG
;
4154 fix_new_exp (frag_now
, frag_now_fix (), 0, &exp
, 0,
4155 BFD_RELOC_NDS32_RELAX_REGION_END
);
4160 nds32_loop_begin (int mode
)
4162 /* Insert loop region relocation here. */
4165 exp
.X_op
= O_symbol
;
4166 exp
.X_add_symbol
= abs_section_sym
;
4169 exp
.X_add_number
= R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG
;
4170 fix_new_exp (frag_now
, frag_now_fix (), 0, &exp
, 0,
4171 BFD_RELOC_NDS32_RELAX_REGION_BEGIN
);
4175 exp
.X_add_number
= R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG
;
4176 fix_new_exp (frag_now
, frag_now_fix (), 0, &exp
, 0,
4177 BFD_RELOC_NDS32_RELAX_REGION_END
);
4181 struct nds32_relocs_group
4183 struct nds32_relocs_pattern
*pattern
;
4184 struct nds32_relocs_group
*next
;
4187 static struct nds32_relocs_group
*nds32_relax_hint_current
= NULL
;
4188 /* Used to reorder the id for ".relax_hint id". */
4189 static int relax_hint_bias
= 0;
4190 /* Record current relax hint id. */
4191 static int relax_hint_id_current
= -1;
4193 /* If ".relax_hint begin" is triggered? */
4194 int relax_hint_begin
= 0;
4196 /* Record the reordered relax hint id. */
4198 struct relax_hint_id
4202 struct relax_hint_id
*next
;
4205 /* FIXME: Need to find somewhere to free the list. */
4206 struct relax_hint_id
*record_id_head
= NULL
;
4208 /* Is the buffer large enough? */
4209 #define MAX_BUFFER 12
4211 static char *nds_itoa (int n
);
4216 char *buf
= xmalloc (MAX_BUFFER
* sizeof (char));
4217 snprintf (buf
, MAX_BUFFER
, "%d", n
);
4221 /* Insert a relax hint. */
4224 nds32_relax_hint (int mode ATTRIBUTE_UNUSED
)
4228 struct nds32_relocs_pattern
*relocs
= NULL
;
4229 struct nds32_relocs_group
*group
, *new;
4230 struct relax_hint_id
*record_id
;
4232 name
= input_line_pointer
;
4233 while (*input_line_pointer
&& !ISSPACE (*input_line_pointer
))
4234 input_line_pointer
++;
4235 saved_char
= *input_line_pointer
;
4236 *input_line_pointer
= 0;
4237 name
= strdup (name
);
4239 if (name
&& strcmp (name
, "begin") == 0)
4241 if (relax_hint_id_current
== -1)
4244 relax_hint_id_current
++;
4245 relax_hint_begin
= 1;
4248 /* Original case ".relax_hint id". It's id may need to be reordered. */
4249 if (!relax_hint_begin
)
4251 int tmp
= strtol (name
, NULL
, 10);
4252 record_id
= record_id_head
;
4255 if (record_id
->old_id
== tmp
)
4257 name
= nds_itoa (record_id
->new_id
);
4260 record_id
= record_id
->next
;
4264 relax_hint_bias
= relax_hint_id_current
- atoi (name
) + 1;
4267 relax_hint_id_current
= tmp
+ relax_hint_bias
;
4269 /* Insert the element to the head of the link list. */
4270 struct relax_hint_id
*tmp_id
= malloc (sizeof (struct relax_hint_id
));
4271 tmp_id
->old_id
= tmp
;
4272 tmp_id
->new_id
= relax_hint_id_current
;
4273 tmp_id
->next
= record_id_head
;
4274 record_id_head
= tmp_id
;
4277 if (name
&& strcmp (name
, "end") == 0)
4278 relax_hint_begin
= 0;
4279 name
= nds_itoa (relax_hint_id_current
);
4283 /* Find relax hint entry for next instruction, and all member will be
4284 initialized at that time. */
4285 relocs
= str_hash_find (nds32_hint_hash
, name
);
4288 relocs
= XNEW (struct nds32_relocs_pattern
);
4289 memset (relocs
, 0, sizeof (struct nds32_relocs_pattern
));
4290 str_hash_insert (nds32_hint_hash
, name
, relocs
, 0);
4294 while (relocs
->next
)
4295 relocs
=relocs
->next
;
4296 relocs
->next
= XNEW (struct nds32_relocs_pattern
);
4297 relocs
= relocs
->next
;
4298 memset (relocs
, 0, sizeof (struct nds32_relocs_pattern
));
4301 relocs
->next
= NULL
;
4302 *input_line_pointer
= saved_char
;
4303 ignore_rest_of_line ();
4305 /* Get the final one of relax hint series. */
4307 /* It has to build this list because there are maybe more than one
4308 instructions relative to the same instruction. It to connect to
4309 next instruction after md_assemble. */
4310 new = XNEW (struct nds32_relocs_group
);
4311 memset (new, 0, sizeof (struct nds32_relocs_group
));
4312 new->pattern
= relocs
;
4314 group
= nds32_relax_hint_current
;
4316 nds32_relax_hint_current
= new;
4319 while (group
->next
!= NULL
)
4320 group
= group
->next
;
4326 /* Decide the size of vector entries, only accepts 4 or 16 now. */
4329 nds32_vec_size (int ignore ATTRIBUTE_UNUSED
)
4335 if (exp
.X_op
== O_constant
)
4337 if (exp
.X_add_number
== 4 || exp
.X_add_number
== 16)
4340 vec_size
= exp
.X_add_number
;
4341 else if (vec_size
!= exp
.X_add_number
)
4342 as_warn (_("Different arguments of .vec_size are found, "
4343 "previous %d, current %d"),
4344 (int) vec_size
, (int) exp
.X_add_number
);
4347 as_warn (_("Argument of .vec_size is expected 4 or 16, actual: %d."),
4348 (int) exp
.X_add_number
);
4351 as_warn (_("Argument of .vec_size is not a constant."));
4354 /* The behavior of ".flag" directive varies depending on the target.
4355 In nds32 target, we use it to recognize whether this assembly content is
4356 generated by compiler. Other features can also be added in this function
4360 nds32_flag (int ignore ATTRIBUTE_UNUSED
)
4365 const char *possible_flags
[] = { "verbatim" };
4367 /* Skip whitespaces. */
4368 name
= input_line_pointer
;
4369 while (*input_line_pointer
&& !ISSPACE (*input_line_pointer
))
4370 input_line_pointer
++;
4371 saved_char
= *input_line_pointer
;
4372 *input_line_pointer
= 0;
4374 for (i
= 0; i
< (int) ARRAY_SIZE (possible_flags
); i
++)
4376 if (strcmp (name
, possible_flags
[i
]) == 0)
4381 /* flag: verbatim */
4387 /* Already found the flag, no need to continue next loop. */
4392 *input_line_pointer
= saved_char
;
4393 ignore_rest_of_line ();
4397 ict_model (int ignore ATTRIBUTE_UNUSED
)
4402 const char *possible_flags
[] = { "small", "large" };
4404 /* Skip whitespaces. */
4405 name
= input_line_pointer
;
4406 while (*input_line_pointer
&& !ISSPACE (*input_line_pointer
))
4407 input_line_pointer
++;
4408 saved_char
= *input_line_pointer
;
4409 *input_line_pointer
= 0;
4411 for (i
= 0; i
< (int) ARRAY_SIZE (possible_flags
); i
++)
4413 if (strcmp (name
, possible_flags
[i
]) == 0)
4418 /* flag: verbatim */
4419 ict_flag
= ICT_SMALL
;
4422 ict_flag
= ICT_LARGE
;
4427 /* Already found the flag, no need to continue next loop. */
4432 *input_line_pointer
= saved_char
;
4433 ignore_rest_of_line ();
4437 nds32_n12hc (int ignore ATTRIBUTE_UNUSED
)
4439 /* N1213HC core is used. */
4443 /* The target specific pseudo-ops which we support. */
4444 const pseudo_typeS md_pseudo_table
[] =
4446 /* Forced alignment if declared these ways. */
4447 {"ascii", stringer
, 8 + 0},
4448 {"asciz", stringer
, 8 + 1},
4449 {"double", nds32_aligned_float_cons
, 'd'},
4450 {"dword", nds32_aligned_cons
, 3},
4451 {"float", nds32_aligned_float_cons
, 'f'},
4452 {"half", nds32_aligned_cons
, 1},
4453 {"hword", nds32_aligned_cons
, 1},
4454 {"int", nds32_aligned_cons
, 2},
4455 {"long", nds32_aligned_cons
, 2},
4456 {"octa", nds32_aligned_cons
, 4},
4457 {"quad", nds32_aligned_cons
, 3},
4458 {"qword", nds32_aligned_cons
, 4},
4459 {"short", nds32_aligned_cons
, 1},
4460 {"byte", nds32_aligned_cons
, 0},
4461 {"single", nds32_aligned_float_cons
, 'f'},
4462 {"string", stringer
, 8 + 1},
4463 {"word", nds32_aligned_cons
, 2},
4465 {"little", set_endian_little
, 1},
4466 {"big", set_endian_little
, 0},
4467 {"16bit_on", trigger_16bit
, 1},
4468 {"16bit_off", trigger_16bit
, 0},
4469 {"restore_16bit", restore_16bit
, 0},
4470 {"off_16bit", off_16bit
, 0},
4472 {"sdata_d", nds32_seg
, SDATA_D_SECTION
},
4473 {"sdata_w", nds32_seg
, SDATA_W_SECTION
},
4474 {"sdata_h", nds32_seg
, SDATA_H_SECTION
},
4475 {"sdata_b", nds32_seg
, SDATA_B_SECTION
},
4476 {"sdata_f", nds32_seg
, SDATA_F_SECTION
},
4478 {"sbss_d", nds32_seg
, SBSS_D_SECTION
},
4479 {"sbss_w", nds32_seg
, SBSS_W_SECTION
},
4480 {"sbss_h", nds32_seg
, SBSS_H_SECTION
},
4481 {"sbss_b", nds32_seg
, SBSS_B_SECTION
},
4482 {"sbss_f", nds32_seg
, SBSS_F_SECTION
},
4484 {"pic", nds32_enable_pic
, 0},
4485 {"n12_hc", nds32_n12hc
, 0},
4486 {"abi_1", nds32_set_abi
, E_NDS_ABI_V1
},
4487 {"abi_2", nds32_set_abi
, E_NDS_ABI_AABI
},
4489 {"abi_2fp", nds32_set_abi
, E_NDS_ABI_V2FP
},
4490 {"abi_2fp_plus", nds32_set_abi
, E_NDS_ABI_V2FP_PLUS
},
4491 {"relax", nds32_relax_relocs
, 1},
4492 {"no_relax", nds32_relax_relocs
, 0},
4493 {"hint_func_args", nds32_set_hint_func_args
, 0}, /* Abandon?? */
4494 {"omit_fp_begin", nds32_omit_fp_begin
, 1},
4495 {"omit_fp_end", nds32_omit_fp_begin
, 0},
4496 {"vec_size", nds32_vec_size
, 0},
4497 {"flag", nds32_flag
, 0},
4498 {"innermost_loop_begin", nds32_loop_begin
, 1},
4499 {"innermost_loop_end", nds32_loop_begin
, 0},
4500 {"relax_hint", nds32_relax_hint
, 0},
4501 {"ict_model", ict_model
, 0},
4506 nds32_pre_do_align (int n
, char *fill
, int len
, int max
)
4508 /* Only make a frag if we HAVE to... */
4510 if (n
!= 0 && !need_pass_2
)
4514 if (subseg_text_p (now_seg
))
4516 dwarf2_emit_insn (0);
4518 add_mapping_symbol_for_align (n
, frag_now_fix (), 0);
4519 frag_align_code (n
, max
);
4521 /* Tag this alignment when there is a label before it. */
4524 fragP
->tc_frag_data
.flag
= NDS32_FRAG_LABEL
;
4529 frag_align (n
, 0, max
);
4532 frag_align (n
, *fill
, max
);
4534 frag_align_pattern (n
, fill
, len
, max
);
4539 nds32_do_align (int n
)
4541 /* Optimize for space and label exists. */
4544 /* FIXME:I think this will break debug info sections and except_table. */
4545 if (!enable_relax_relocs
|| !subseg_text_p (now_seg
))
4548 /* Create and attach a BFD_RELOC_NDS32_LABEL fixup
4549 the size of instruction may not be correct because
4550 it could be relaxable. */
4551 exp
.X_op
= O_symbol
;
4552 exp
.X_add_symbol
= section_symbol (now_seg
);
4553 exp
.X_add_number
= n
;
4554 fix_new_exp (frag_now
,
4555 frag_now_fix (), 0, &exp
, 0, BFD_RELOC_NDS32_LABEL
);
4558 /* Supported Andes machines. */
4561 enum bfd_architecture bfd_mach
;
4565 /* This is the callback for nds32-asm.c to parse operands. */
4568 nds32_asm_parse_operand (struct nds32_asm_desc
*pdesc ATTRIBUTE_UNUSED
,
4569 struct nds32_asm_insn
*pinsn
,
4570 char **pstr
, int64_t *value
)
4573 expressionS
*pexp
= pinsn
->info
;
4575 hold
= input_line_pointer
;
4576 input_line_pointer
= *pstr
;
4578 *pstr
= input_line_pointer
;
4579 input_line_pointer
= hold
;
4585 return NASM_R_SYMBOL
;
4587 *value
= pexp
->X_add_number
;
4588 return NASM_R_CONST
;
4593 return NASM_R_ILLEGAL
;
4597 /* GAS will call this function at the start of the assembly, after the command
4598 line arguments have been parsed and all the machine independent
4599 initializations have been completed. */
4604 struct nds32_keyword
*k
;
4605 relax_info_t
*relax_info
;
4608 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, nds32_baseline
);
4610 nds32_init_nds32_pseudo_opcodes ();
4611 asm_desc
.parse_operand
= nds32_asm_parse_operand
;
4613 flags
|= NASM_OPEN_REDUCED_REG
;
4614 nds32_asm_init (&asm_desc
, flags
);
4616 /* Initial general purpose registers hash table. */
4617 nds32_gprs_hash
= str_htab_create ();
4618 for (k
= keyword_gpr
; k
->name
; k
++)
4619 str_hash_insert (nds32_gprs_hash
, k
->name
, k
, 0);
4621 /* Initial branch hash table. */
4622 nds32_relax_info_hash
= str_htab_create ();
4623 for (relax_info
= relax_table
; relax_info
->opcode
; relax_info
++)
4624 str_hash_insert (nds32_relax_info_hash
, relax_info
->opcode
, relax_info
, 0);
4626 /* Initial relax hint hash table. */
4627 nds32_hint_hash
= str_htab_create ();
4628 enable_16bit
= nds32_16bit_ext
;
4631 /* HANDLE_ALIGN in write.c. */
4634 nds32_handle_align (fragS
*fragp
)
4636 static const unsigned char nop16
[] = { 0x92, 0x00 };
4637 static const unsigned char nop32
[] = { 0x40, 0x00, 0x00, 0x09 };
4641 if (fragp
->fr_type
!= rs_align_code
)
4644 bytes
= fragp
->fr_next
->fr_address
- fragp
->fr_address
- fragp
->fr_fix
;
4645 p
= fragp
->fr_literal
+ fragp
->fr_fix
;
4656 exp_t
.X_op
= O_symbol
;
4657 exp_t
.X_add_symbol
= abs_section_sym
;
4658 exp_t
.X_add_number
= R_NDS32_INSN16_CONVERT_FLAG
;
4659 fix_new_exp (fragp
, fragp
->fr_fix
, 2, &exp_t
, 0,
4660 BFD_RELOC_NDS32_INSN16
);
4661 memcpy (p
, nop16
, 2);
4668 memcpy (p
, nop32
, 4);
4673 bytes
= fragp
->fr_next
->fr_address
- fragp
->fr_address
- fragp
->fr_fix
;
4674 fragp
->fr_fix
+= bytes
;
4677 /* md_flush_pending_output */
4680 nds32_flush_pending_output (void)
4682 nds32_last_label
= NULL
;
4686 nds32_frob_label (symbolS
*label
)
4688 dwarf2_emit_label (label
);
4691 /* TC_START_LABEL */
4694 nds32_start_label (int asmdone ATTRIBUTE_UNUSED
, int secdone ATTRIBUTE_UNUSED
)
4696 if (optimize
&& subseg_text_p (now_seg
))
4704 nds32_target_format (void)
4707 if (target_big_endian
)
4708 return "elf32-nds32be-linux";
4710 return "elf32-nds32le-linux";
4712 if (target_big_endian
)
4713 return "elf32-nds32be";
4715 return "elf32-nds32le";
4719 static enum nds32_br_range
4720 get_range_type (const struct nds32_field
*field
)
4722 gas_assert (field
!= NULL
);
4724 if (field
->bitpos
!= 0)
4725 return BR_RANGE_U4G
;
4727 if (field
->bitsize
== 24 && field
->shift
== 1)
4728 return BR_RANGE_S16M
;
4729 else if (field
->bitsize
== 16 && field
->shift
== 1)
4730 return BR_RANGE_S64K
;
4731 else if (field
->bitsize
== 14 && field
->shift
== 1)
4732 return BR_RANGE_S16K
;
4733 else if (field
->bitsize
== 8 && field
->shift
== 1)
4734 return BR_RANGE_S256
;
4736 return BR_RANGE_U4G
;
4739 /* Save pseudo instruction relocation list. */
4741 static struct nds32_relocs_pattern
*
4742 nds32_elf_save_pseudo_pattern (fixS
* fixP
, struct nds32_asm_insn
*insn
,
4743 char *out
, symbolS
*sym
,
4744 struct nds32_relocs_pattern
*reloc_ptr
,
4747 struct nds32_opcode
*opcode
= insn
->opcode
;
4749 reloc_ptr
= XNEW (struct nds32_relocs_pattern
);
4750 reloc_ptr
->seg
= now_seg
;
4751 reloc_ptr
->sym
= sym
;
4752 reloc_ptr
->frag
= fragP
;
4753 reloc_ptr
->frchain
= frchain_now
;
4754 reloc_ptr
->fixP
= fixP
;
4755 reloc_ptr
->opcode
= opcode
;
4756 reloc_ptr
->where
= out
;
4757 reloc_ptr
->insn
= insn
->insn
;
4758 reloc_ptr
->next
= NULL
;
4762 /* Check X_md to transform relocation. */
4765 nds32_elf_record_fixup_exp (fragS
*fragP
, const char *str
,
4766 const struct nds32_field
*fld
,
4767 expressionS
*pexp
, char* out
,
4768 struct nds32_asm_insn
*insn
)
4774 /* Handle instruction relocation. */
4775 if (fld
&& fld
->bitpos
== 0 && (insn
->attr
& NASM_ATTR_HI20
))
4777 /* Relocation for hi20 modifier. */
4780 case BFD_RELOC_NDS32_GOTOFF
: /* @GOTOFF */
4781 reloc
= BFD_RELOC_NDS32_GOTOFF_HI20
;
4783 case BFD_RELOC_NDS32_GOT20
: /* @GOT */
4784 reloc
= BFD_RELOC_NDS32_GOT_HI20
;
4786 case BFD_RELOC_NDS32_25_PLTREL
: /* @PLT */
4788 as_bad (_("Invalid PIC expression."));
4790 reloc
= BFD_RELOC_NDS32_PLT_GOTREL_HI20
;
4792 case BFD_RELOC_NDS32_GOTPC20
: /* _GLOBAL_OFFSET_TABLE_ */
4793 reloc
= BFD_RELOC_NDS32_GOTPC_HI20
;
4795 case BFD_RELOC_NDS32_TPOFF
: /* @TPOFF */
4796 reloc
= BFD_RELOC_NDS32_TLS_LE_HI20
;
4798 case BFD_RELOC_NDS32_GOTTPOFF
: /* @GOTTPOFF */
4799 reloc
= nds32_pic
? BFD_RELOC_NDS32_TLS_IEGP_HI20
: BFD_RELOC_NDS32_TLS_IE_HI20
;
4801 case BFD_RELOC_NDS32_TLS_DESC
: /* @TLSDESC */
4802 reloc
= BFD_RELOC_NDS32_TLS_DESC_HI20
;
4804 default: /* No suffix */
4806 /* When the file is pic, the address must be offset to gp.
4807 It may define another relocation or use GOTOFF. */
4808 reloc
= BFD_RELOC_NDS32_PLT_GOTREL_HI20
;
4810 reloc
= BFD_RELOC_NDS32_HI20
;
4813 fixP
= fix_new_exp (fragP
, out
- fragP
->fr_literal
, insn
->opcode
->isize
,
4814 insn
->info
, 0 /* pcrel */, reloc
);
4816 else if (fld
&& fld
->bitpos
== 0 && (insn
->attr
& NASM_ATTR_LO12
))
4818 /* Relocation for lo12 modifier. */
4819 if (fld
->bitsize
== 15 && fld
->shift
== 0)
4824 case BFD_RELOC_NDS32_GOTOFF
: /* @GOTOFF */
4825 reloc
= BFD_RELOC_NDS32_GOTOFF_LO12
;
4827 case BFD_RELOC_NDS32_GOT20
: /* @GOT */
4828 reloc
= BFD_RELOC_NDS32_GOT_LO12
;
4830 case BFD_RELOC_NDS32_25_PLTREL
: /* @PLT */
4832 as_bad (_("Invalid PIC expression."));
4834 reloc
= BFD_RELOC_NDS32_PLT_GOTREL_LO12
;
4836 case BFD_RELOC_NDS32_GOTPC20
: /* _GLOBAL_OFFSET_TABLE_ */
4837 reloc
= BFD_RELOC_NDS32_GOTPC_LO12
;
4839 case BFD_RELOC_NDS32_TPOFF
: /* @TPOFF */
4840 reloc
= BFD_RELOC_NDS32_TLS_LE_LO12
;
4842 case BFD_RELOC_NDS32_GOTTPOFF
: /* @GOTTPOFF */
4843 reloc
= nds32_pic
? BFD_RELOC_NDS32_TLS_IEGP_LO12
: BFD_RELOC_NDS32_TLS_IE_LO12
;
4845 case BFD_RELOC_NDS32_TLS_DESC
: /* @TLSDESC */
4846 reloc
= BFD_RELOC_NDS32_TLS_DESC_LO12
;
4848 default: /* No suffix */
4850 /* When the file is pic, the address must be offset to gp.
4851 It may define another relocation or use GOTOFF. */
4852 reloc
= BFD_RELOC_NDS32_PLT_GOTREL_LO12
;
4854 reloc
= BFD_RELOC_NDS32_LO12S0
;
4858 else if (fld
->bitsize
== 15 && fld
->shift
== 1)
4859 reloc
= BFD_RELOC_NDS32_LO12S1
; /* [ls]hi */
4860 else if (fld
->bitsize
== 15 && fld
->shift
== 2)
4865 case BFD_RELOC_NDS32_GOTTPOFF
: /* @GOTTPOFF */
4866 reloc
= nds32_pic
? BFD_RELOC_NDS32_TLS_IEGP_LO12S2
: BFD_RELOC_NDS32_TLS_IE_LO12S2
;
4868 default: /* No suffix */
4869 reloc
= BFD_RELOC_NDS32_LO12S2
;
4873 else if (fld
->bitsize
== 15 && fld
->shift
== 3)
4874 reloc
= BFD_RELOC_NDS32_LO12S3
; /* [ls]di */
4875 else if (fld
->bitsize
== 12 && fld
->shift
== 2)
4876 reloc
= BFD_RELOC_NDS32_LO12S2_SP
; /* f[ls][sd]i */
4878 fixP
= fix_new_exp (fragP
, out
- fragP
->fr_literal
, insn
->opcode
->isize
,
4879 insn
->info
, 0 /* pcrel */, reloc
);
4881 else if (fld
&& fld
->bitpos
== 0 && insn
->opcode
->isize
== 4
4882 && (insn
->attr
& NASM_ATTR_PCREL
))
4884 /* Relocation for 32-bit branch instructions. */
4885 if (fld
->bitsize
== 24 && fld
->shift
== 1)
4886 reloc
= BFD_RELOC_NDS32_25_PCREL
;
4887 else if (fld
->bitsize
== 16 && fld
->shift
== 1)
4888 reloc
= BFD_RELOC_NDS32_17_PCREL
;
4889 else if (fld
->bitsize
== 14 && fld
->shift
== 1)
4890 reloc
= BFD_RELOC_NDS32_15_PCREL
;
4891 else if (fld
->bitsize
== 8 && fld
->shift
== 1)
4892 reloc
= BFD_RELOC_NDS32_WORD_9_PCREL
;
4896 fixP
= fix_new_exp (fragP
, out
- fragP
->fr_literal
, insn
->opcode
->isize
,
4897 insn
->info
, 1 /* pcrel */, reloc
);
4899 else if (fld
&& fld
->bitpos
== 0 && insn
->opcode
->isize
== 4
4900 && (insn
->attr
& NASM_ATTR_GPREL
))
4902 /* Relocation for 32-bit gp-relative instructions. */
4903 if (fld
->bitsize
== 19 && fld
->shift
== 0)
4904 reloc
= BFD_RELOC_NDS32_SDA19S0
;
4905 else if (fld
->bitsize
== 18 && fld
->shift
== 1)
4906 reloc
= BFD_RELOC_NDS32_SDA18S1
;
4907 else if (fld
->bitsize
== 17 && fld
->shift
== 2)
4908 reloc
= BFD_RELOC_NDS32_SDA17S2
;
4912 fixP
= fix_new_exp (fragP
, out
- fragP
->fr_literal
, insn
->opcode
->isize
,
4913 insn
->info
, 0 /* pcrel */, reloc
);
4914 /* Insert INSN16 for converting fp_as_gp. */
4915 exp
.X_op
= O_symbol
;
4916 exp
.X_add_symbol
= abs_section_sym
;
4917 exp
.X_add_number
= 0;
4918 if (in_omit_fp
&& reloc
== BFD_RELOC_NDS32_SDA17S2
)
4919 fix_new_exp (fragP
, out
- fragP
->fr_literal
,
4920 insn
->opcode
->isize
, &exp
, 0 /* pcrel */,
4921 BFD_RELOC_NDS32_INSN16
);
4923 else if (fld
&& fld
->bitpos
== 0 && insn
->opcode
->isize
== 2
4924 && (insn
->attr
& NASM_ATTR_PCREL
))
4926 /* Relocation for 16-bit branch instructions. */
4927 if (fld
->bitsize
== 8 && fld
->shift
== 1)
4928 reloc
= BFD_RELOC_NDS32_9_PCREL
;
4932 fixP
= fix_new_exp (fragP
, out
- fragP
->fr_literal
, insn
->opcode
->isize
,
4933 insn
->info
, 1 /* pcrel */, reloc
);
4936 as_bad (_("Don't know how to handle this field. %s"), str
);
4941 /* Build instruction pattern to relax. There are two type group pattern
4942 including pseudo instruction and relax hint. */
4945 nds32_elf_build_relax_relation (fixS
*fixP
, expressionS
*pexp
, char* out
,
4946 struct nds32_asm_insn
*insn
, fragS
*fragP
,
4947 const struct nds32_field
*fld
,
4948 bfd_boolean pseudo_hint
)
4950 struct nds32_relocs_pattern
*reloc_ptr
;
4951 struct nds32_relocs_group
*group
;
4952 symbolS
*sym
= NULL
;
4954 /* The expression may be used uninitialized. */
4956 sym
= pexp
->X_add_symbol
;
4960 /* We cannot know how many instructions will be expanded for
4961 the pseudo instruction here. The first expanded instruction fills
4962 the memory created by relax_hint. The follower will created and link
4964 group
= nds32_relax_hint_current
;
4967 if (group
->pattern
->opcode
== NULL
)
4968 nds32_elf_save_pseudo_pattern (fixP
, insn
, out
, sym
,
4969 group
->pattern
, fragP
);
4972 group
->pattern
->next
=
4973 nds32_elf_save_pseudo_pattern (fixP
, insn
, out
, sym
,
4975 group
->pattern
= group
->pattern
->next
;
4977 group
= group
->next
;
4980 else if (pseudo_opcode
)
4982 /* Save instruction relation for pseudo instruction expanding pattern. */
4983 reloc_ptr
= nds32_elf_save_pseudo_pattern (fixP
, insn
, out
, sym
,
4986 relocs_list
= reloc_ptr
;
4989 struct nds32_relocs_pattern
*temp
= relocs_list
;
4992 temp
->next
= reloc_ptr
;
4995 else if (nds32_relax_hint_current
)
4997 /* Save instruction relation by relax hint. */
4998 group
= nds32_relax_hint_current
;
5001 nds32_elf_save_pseudo_pattern (fixP
, insn
, out
, sym
,
5002 group
->pattern
, fragP
);
5003 group
= group
->next
;
5004 free (nds32_relax_hint_current
);
5005 nds32_relax_hint_current
= group
;
5009 /* Set relaxing false only for relax_hint trigger it. */
5014 #define N32_MEM_EXT(insn) ((N32_OP6_MEM << 25) | insn)
5016 /* Relax pattern for link time relaxation. */
5017 /* Relaxation types only! relocation types are not necessary. */
5018 /* Refer to nds32_elf_record_fixup_exp (). */
5020 static struct nds32_relax_hint_table relax_ls_table
[] =
5023 /* LA and Floating LSI. */
5024 .main_type
= NDS32_RELAX_HINT_LA_FLSI
,
5025 .relax_code_size
= 12,
5034 {0, 4, NDS32_HINT
| NDS32_ADDEND
, BFD_RELOC_NDS32_LOADSTORE
},
5035 {4, 4, NDS32_HINT
| NDS32_PTR
, BFD_RELOC_NDS32_PTR
},
5036 {4, 4, NDS32_HINT
| NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
5037 {8, 4, NDS32_HINT
| NDS32_SYM
, BFD_RELOC_NDS32_LSI
},
5038 {8, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_PTR_RESOLVED
},
5039 {8, 4, NDS32_HINT
| NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
5044 /* Load Address / Load-Store (LALS). */
5045 .main_type
= NDS32_RELAX_HINT_LALS
,
5046 .relax_code_size
= 12,
5055 {0, 4, NDS32_HINT
| NDS32_ADDEND
, BFD_RELOC_NDS32_LOADSTORE
},
5056 {4, 4, NDS32_HINT
| NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
5057 {8, 4, NDS32_HINT
| NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
5062 /* B(AL) symbol@PLT */
5063 .main_type
= NDS32_RELAX_HINT_LA_PLT
,
5064 .relax_code_size
= 16,
5074 {0, 4, NDS32_HINT
| NDS32_ADDEND
, BFD_RELOC_NDS32_LOADSTORE
},
5075 {4, 4, NDS32_HINT
| NDS32_PTR
, BFD_RELOC_NDS32_PTR
},
5076 {8, 4, NDS32_HINT
| NDS32_PTR
, BFD_RELOC_NDS32_PTR
},
5077 {12, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_PLT_GOT_SUFF
},
5078 {12, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_PTR_RESOLVED
},
5079 {12, 4, NDS32_HINT
| NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
5085 .main_type
= NDS32_RELAX_HINT_LA_GOT
,
5086 .relax_code_size
= 12,
5095 {0, 4, NDS32_HINT
| NDS32_ADDEND
, BFD_RELOC_NDS32_LOADSTORE
},
5096 {4, 4, NDS32_HINT
| NDS32_PTR
, BFD_RELOC_NDS32_PTR
},
5097 {8, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_PTR_RESOLVED
},
5098 {8, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_GOT_SUFF
},
5104 .main_type
= NDS32_RELAX_HINT_LA_GOTOFF
,
5105 .relax_code_size
= 16,
5115 {0, 4, NDS32_HINT
| NDS32_ADDEND
, BFD_RELOC_NDS32_LOADSTORE
},
5116 {4, 4, NDS32_HINT
| NDS32_PTR
, BFD_RELOC_NDS32_PTR
},
5117 {8, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_PTR_RESOLVED
},
5118 {8, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_GOTOFF_SUFF
},
5119 {12, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_PTR_RESOLVED
},
5120 {12, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_GOTOFF_SUFF
},
5126 .main_type
= NDS32_RELAX_HINT_TLS_LE_LS
,
5127 .relax_code_size
= 16,
5137 {0, 4, NDS32_HINT
| NDS32_ADDEND
, BFD_RELOC_NDS32_LOADSTORE
},
5138 {4, 4, NDS32_HINT
| NDS32_PTR_MULTIPLE
, BFD_RELOC_NDS32_PTR
},
5139 {8, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_PTR_RESOLVED
},
5140 {8, 4, NDS32_HINT
| NDS32_SYM
, BFD_RELOC_NDS32_TLS_LE_LS
},
5141 {12, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_PTR_RESOLVED
},
5142 {12, 4, NDS32_HINT
| NDS32_SYM
, BFD_RELOC_NDS32_TLS_LE_ADD
},
5148 .main_type
= NDS32_RELAX_HINT_TLS_IE_LA
,
5149 .relax_code_size
= 8,
5157 {0, 4, NDS32_HINT
| NDS32_ADDEND
, BFD_RELOC_NDS32_LOADSTORE
},
5158 {4, 4, NDS32_HINT
| NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
5164 .main_type
= NDS32_RELAX_HINT_TLS_IEGP_LA
,
5165 .relax_code_size
= 12,
5174 {0, 4, NDS32_HINT
| NDS32_ADDEND
, BFD_RELOC_NDS32_LOADSTORE
},
5175 {4, 4, NDS32_HINT
| NDS32_PTR_PATTERN
, BFD_RELOC_NDS32_PTR
},
5176 {8, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_PTR_RESOLVED
},
5177 {8, 4, NDS32_HINT
| NDS32_SYM
, BFD_RELOC_NDS32_TLS_IEGP_LW
},
5183 .main_type
= NDS32_RELAX_HINT_TLS_DESC_LS
,
5184 .relax_code_size
= 24,
5190 OP6 (LBI
), /* load argument */
5192 OP6 (MEM
), /* load/store variable or load argument */
5196 {0, 4, NDS32_HINT
| NDS32_ADDEND
, BFD_RELOC_NDS32_LOADSTORE
},
5197 {4, 4, NDS32_HINT
| NDS32_PTR_PATTERN
, BFD_RELOC_NDS32_PTR
},
5198 {8, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_PTR_RESOLVED
},
5199 {8, 4, NDS32_HINT
| NDS32_SYM
, BFD_RELOC_NDS32_TLS_DESC_ADD
},
5200 {12, 4, NDS32_HINT
| NDS32_SYM
, BFD_RELOC_NDS32_TLS_DESC_FUNC
},
5201 {16, 4, NDS32_HINT
| NDS32_SYM
, BFD_RELOC_NDS32_TLS_DESC_CALL
},
5202 {20, 4, NDS32_HINT
| NDS32_SYM_DESC_MEM
, BFD_RELOC_NDS32_TLS_DESC_MEM
},
5208 .relax_code_seq
= {0},
5209 .relax_fixup
= {{0, 0 , 0, 0}}
5213 /* Since sethi loadstore relocation has to using next instruction to determine
5214 elimination itself or not, we have to return the next instruction range. */
5217 nds32_elf_sethi_range (struct nds32_relocs_pattern
*pattern
)
5222 switch (pattern
->opcode
->value
)
5227 case N32_MEM_EXT (N32_MEM_LB
):
5228 case N32_MEM_EXT (N32_MEM_LBS
):
5229 case N32_MEM_EXT (N32_MEM_SB
):
5230 range
= NDS32_LOADSTORE_BYTE
;
5235 case N32_MEM_EXT (N32_MEM_LH
):
5236 case N32_MEM_EXT (N32_MEM_LHS
):
5237 case N32_MEM_EXT (N32_MEM_SH
):
5238 range
= NDS32_LOADSTORE_HALF
;
5242 case N32_MEM_EXT (N32_MEM_LW
):
5243 case N32_MEM_EXT (N32_MEM_SW
):
5244 range
= NDS32_LOADSTORE_WORD
;
5248 range
= NDS32_LOADSTORE_FLOAT_S
;
5252 range
= NDS32_LOADSTORE_FLOAT_D
;
5255 range
= NDS32_LOADSTORE_IMM
;
5258 range
= NDS32_LOADSTORE_NONE
;
5261 if (range
!= NDS32_LOADSTORE_NONE
)
5263 pattern
= pattern
->next
;
5268 /* The args means: instruction size, the 1st instruction is converted to 16 or
5269 not, optimize option, 16 bit instruction is enable. */
5271 #define SET_ADDEND(size, convertible, optimize, insn16_on) \
5272 (((size) & 0xff) | ((convertible) ? 1u << 31 : 0) \
5273 | ((optimize) ? 1 << 30 : 0) | (insn16_on ? 1 << 29 : 0))
5274 #define MAC_COMBO (E_NDS32_HAS_FPU_MAC_INST|E_NDS32_HAS_MAC_DX_INST)
5277 nds32_set_elf_flags_by_insn (struct nds32_asm_insn
* insn
)
5279 static int skip_flags
= NASM_ATTR_FPU_FMA
5280 | NASM_ATTR_BRANCH
| NASM_ATTR_SATURATION_EXT
5281 | NASM_ATTR_GPREL
| NASM_ATTR_DXREG
5282 | NASM_ATTR_ISA_V1
| NASM_ATTR_ISA_V2
5283 | NASM_ATTR_ISA_V3
| NASM_ATTR_ISA_V3M
5286 int new_flags
= insn
->opcode
->attr
& ~skip_flags
;
5289 int next
= 1 << (ffs (new_flags
) - 1);
5293 case NASM_ATTR_PERF_EXT
:
5297 nds32_elf_flags
|= E_NDS32_HAS_EXT_INST
;
5298 skip_flags
|= NASM_ATTR_PERF_EXT
;
5301 as_bad (_("instruction %s requires enabling performance "
5302 "extension"), insn
->opcode
->opcode
);
5305 case NASM_ATTR_PERF2_EXT
:
5307 if (nds32_perf_ext2
)
5309 nds32_elf_flags
|= E_NDS32_HAS_EXT2_INST
;
5310 skip_flags
|= NASM_ATTR_PERF2_EXT
;
5313 as_bad (_("instruction %s requires enabling performance "
5314 "extension II"), insn
->opcode
->opcode
);
5317 case NASM_ATTR_AUDIO_ISAEXT
:
5319 if (nds32_audio_ext
)
5321 nds32_elf_flags
|= E_NDS32_HAS_AUDIO_INST
;
5322 skip_flags
|= NASM_ATTR_AUDIO_ISAEXT
;
5325 as_bad (_("instruction %s requires enabling AUDIO extension"),
5326 insn
->opcode
->opcode
);
5329 case NASM_ATTR_STR_EXT
:
5331 if (nds32_string_ext
)
5333 nds32_elf_flags
|= E_NDS32_HAS_STRING_INST
;
5334 skip_flags
|= NASM_ATTR_STR_EXT
;
5337 as_bad (_("instruction %s requires enabling STRING extension"),
5338 insn
->opcode
->opcode
);
5343 if (insn
->opcode
->attr
& NASM_ATTR_DXREG
)
5345 if (nds32_div
&& nds32_dx_regs
)
5347 nds32_elf_flags
|= E_NDS32_HAS_DIV_DX_INST
;
5348 skip_flags
|= NASM_ATTR_DIV
;
5351 as_bad (_("instruction %s requires enabling DIV & DX_REGS "
5352 "extension"), insn
->opcode
->opcode
);
5358 if (nds32_fpu_sp_ext
|| nds32_fpu_dp_ext
)
5360 if (!(nds32_elf_flags
5361 & (E_NDS32_HAS_FPU_INST
| E_NDS32_HAS_FPU_DP_INST
)))
5363 skip_flags
|= NASM_ATTR_FPU
;
5366 as_bad (_("instruction %s requires enabling FPU extension"),
5367 insn
->opcode
->opcode
);
5370 case NASM_ATTR_FPU_SP_EXT
:
5372 if (nds32_fpu_sp_ext
)
5374 nds32_elf_flags
|= E_NDS32_HAS_FPU_INST
;
5375 skip_flags
|= NASM_ATTR_FPU_SP_EXT
;
5378 as_bad (_("instruction %s requires enabling FPU_SP extension"),
5379 insn
->opcode
->opcode
);
5382 case NASM_ATTR_FPU_DP_EXT
:
5384 if (nds32_fpu_dp_ext
)
5386 nds32_elf_flags
|= E_NDS32_HAS_FPU_DP_INST
;
5387 skip_flags
|= NASM_ATTR_FPU_DP_EXT
;
5390 as_bad (_("instruction %s requires enabling FPU_DP extension"),
5391 insn
->opcode
->opcode
);
5396 if (insn
->opcode
->attr
& NASM_ATTR_FPU_SP_EXT
)
5398 if (nds32_fpu_sp_ext
&& nds32_mac
)
5399 nds32_elf_flags
|= E_NDS32_HAS_FPU_MAC_INST
;
5401 as_bad (_("instruction %s requires enabling FPU_MAC "
5402 "extension"), insn
->opcode
->opcode
);
5404 else if (insn
->opcode
->attr
& NASM_ATTR_FPU_DP_EXT
)
5406 if (nds32_fpu_dp_ext
&& nds32_mac
)
5407 nds32_elf_flags
|= E_NDS32_HAS_FPU_MAC_INST
;
5409 as_bad (_("instruction %s requires enabling FPU_MAC "
5410 "extension"), insn
->opcode
->opcode
);
5412 else if (insn
->opcode
->attr
& NASM_ATTR_DXREG
)
5414 if (nds32_dx_regs
&& nds32_mac
)
5415 nds32_elf_flags
|= E_NDS32_HAS_MAC_DX_INST
;
5417 as_bad (_("instruction %s requires enabling DX_REGS "
5418 "extension"), insn
->opcode
->opcode
);
5421 if (MAC_COMBO
== (MAC_COMBO
& nds32_elf_flags
))
5422 skip_flags
|= NASM_ATTR_MAC
;
5425 case NASM_ATTR_DSP_ISAEXT
:
5429 nds32_elf_flags
|= E_NDS32_HAS_DSP_INST
;
5430 skip_flags
|= NASM_ATTR_DSP_ISAEXT
;
5433 as_bad (_("instruction %s requires enabling dsp extension"),
5434 insn
->opcode
->opcode
);
5441 nds32_elf_flags
|= E_NDS32_HAS_ZOL
;
5442 skip_flags
|= NASM_ATTR_ZOL
;
5445 as_bad (_("instruction %s requires enabling zol extension"),
5446 insn
->opcode
->opcode
);
5450 as_bad (_("internal error: unknown instruction attribute: 0x%08x"),
5456 /* Flag for analysis relaxation type. */
5458 enum nds32_insn_type
5460 N32_RELAX_SETHI
= 1,
5461 N32_RELAX_BR
= (1 << 1),
5462 N32_RELAX_LSI
= (1 << 2),
5463 N32_RELAX_JUMP
= (1 << 3),
5464 N32_RELAX_CALL
= (1 << 4),
5465 N32_RELAX_ORI
= (1 << 5),
5466 N32_RELAX_MEM
= (1 << 6),
5467 N32_RELAX_MOVI
= (1 << 7),
5468 N32_RELAX_ALU1
= (1 << 8),
5469 N32_RELAX_16BIT
= (1 << 9),
5472 struct nds32_hint_map
5474 /* the preamble relocation */
5475 bfd_reloc_code_real_type hi_type
;
5478 /* relax pattern ID */
5479 enum nds32_relax_hint_type hint_type
;
5481 enum nds32_br_range range
;
5482 /* pattern character flags */
5483 enum nds32_insn_type insn_list
;
5484 /* optional pattern character flags */
5485 enum nds32_insn_type option_list
;
5488 /* Table to match instructions with hint and relax pattern. */
5490 static struct nds32_hint_map hint_map
[] =
5494 BFD_RELOC_NDS32_HI20
,
5496 NDS32_RELAX_HINT_NONE
,
5498 N32_RELAX_SETHI
| N32_RELAX_ORI
| N32_RELAX_CALL
,
5503 _dummy_first_bfd_reloc_code_real
,
5505 NDS32_RELAX_HINT_NONE
,
5507 N32_RELAX_BR
| N32_RELAX_CALL
,
5512 BFD_RELOC_NDS32_HI20
,
5514 NDS32_RELAX_HINT_NONE
,
5516 N32_RELAX_BR
| N32_RELAX_SETHI
| N32_RELAX_ORI
| N32_RELAX_CALL
,
5521 BFD_RELOC_NDS32_HI20
,
5523 NDS32_RELAX_HINT_NONE
,
5525 N32_RELAX_SETHI
| N32_RELAX_ORI
| N32_RELAX_JUMP
,
5530 /* There is two kinds of variation of LONGJUMP5. One of them
5531 generate EMPTY relocation for converted INSN16 if needed.
5532 But we don't distinguish them here. */
5533 _dummy_first_bfd_reloc_code_real
,
5535 NDS32_RELAX_HINT_NONE
,
5537 N32_RELAX_BR
| N32_RELAX_JUMP
,
5542 BFD_RELOC_NDS32_HI20
,
5544 NDS32_RELAX_HINT_NONE
,
5546 N32_RELAX_SETHI
| N32_RELAX_ORI
| N32_RELAX_BR
| N32_RELAX_JUMP
,
5551 _dummy_first_bfd_reloc_code_real
,
5553 NDS32_RELAX_HINT_NONE
,
5555 N32_RELAX_MOVI
| N32_RELAX_BR
,
5559 /* LONGCALL (BAL|JR|LA symbol@PLT). */
5560 BFD_RELOC_NDS32_PLT_GOTREL_HI20
,
5562 NDS32_RELAX_HINT_LA_PLT
,
5564 N32_RELAX_SETHI
| N32_RELAX_ORI
,
5565 N32_RELAX_ALU1
| N32_RELAX_CALL
| N32_RELAX_JUMP
,
5567 /* relative issue: #12566 */
5569 /* LA and Floating LSI. */
5570 BFD_RELOC_NDS32_HI20
,
5572 NDS32_RELAX_HINT_LA_FLSI
,
5574 N32_RELAX_SETHI
| N32_RELAX_ORI
| N32_RELAX_LSI
,
5577 /* relative issue: #11685 #11602 */
5579 /* load address / load-store (LALS). */
5580 BFD_RELOC_NDS32_HI20
,
5582 NDS32_RELAX_HINT_LALS
,
5585 N32_RELAX_ORI
| N32_RELAX_LSI
,
5588 /* setup $GP (_GLOBAL_OFFSET_TABLE_) */
5589 BFD_RELOC_NDS32_GOTPC_HI20
,
5591 NDS32_RELAX_HINT_LALS
,
5593 N32_RELAX_SETHI
| N32_RELAX_ORI
,
5597 /* GOT LA/LS (symbol@GOT) */
5598 BFD_RELOC_NDS32_GOT_HI20
,
5600 NDS32_RELAX_HINT_LA_GOT
,
5602 N32_RELAX_SETHI
| N32_RELAX_ORI
,
5606 /* GOTOFF LA/LS (symbol@GOTOFF) */
5607 BFD_RELOC_NDS32_GOTOFF_HI20
,
5609 NDS32_RELAX_HINT_LA_GOTOFF
,
5611 N32_RELAX_SETHI
| N32_RELAX_ORI
,
5612 N32_RELAX_ALU1
| N32_RELAX_MEM
, /* | N32_RELAX_LSI, */
5615 /* TLS LE LA|LS (@TPOFF) */
5616 BFD_RELOC_NDS32_TLS_LE_HI20
,
5618 NDS32_RELAX_HINT_TLS_LE_LS
,
5620 N32_RELAX_SETHI
| N32_RELAX_ORI
,
5621 N32_RELAX_ALU1
| N32_RELAX_MEM
,
5625 BFD_RELOC_NDS32_TLS_IE_HI20
,
5627 NDS32_RELAX_HINT_TLS_IE_LA
,
5629 N32_RELAX_SETHI
| N32_RELAX_LSI
,
5634 BFD_RELOC_NDS32_TLS_IE_HI20
,
5636 NDS32_RELAX_HINT_TLS_IE_LS
,
5638 N32_RELAX_SETHI
| N32_RELAX_LSI
| N32_RELAX_MEM
,
5643 BFD_RELOC_NDS32_TLS_IEGP_HI20
,
5645 NDS32_RELAX_HINT_TLS_IEGP_LA
,
5647 N32_RELAX_SETHI
| N32_RELAX_ORI
| N32_RELAX_MEM
,
5652 BFD_RELOC_NDS32_TLS_DESC_HI20
,
5654 NDS32_RELAX_HINT_TLS_DESC_LS
,
5656 N32_RELAX_SETHI
| N32_RELAX_ORI
| N32_RELAX_ALU1
| N32_RELAX_CALL
,
5657 N32_RELAX_LSI
| N32_RELAX_MEM
,
5660 {0, NULL
, 0, 0 ,0, 0}
5663 /* Find the relaxation pattern according to instructions. */
5666 nds32_find_reloc_table (struct nds32_relocs_pattern
*relocs_pattern
,
5667 struct nds32_relax_hint_table
*hint_info
)
5669 unsigned int opcode
, seq_size
;
5670 enum nds32_br_range range
;
5671 struct nds32_relocs_pattern
*pattern
, *hi_pattern
= NULL
;
5672 const char *opc
= NULL
;
5673 relax_info_t
*relax_info
= NULL
;
5674 nds32_relax_fixup_info_t
*fixup_info
, *hint_fixup
;
5675 enum nds32_relax_hint_type hint_type
= NDS32_RELAX_HINT_NONE
;
5676 struct nds32_relax_hint_table
*table_ptr
;
5677 uint32_t *code_seq
, *hint_code
;
5678 enum nds32_insn_type relax_type
= 0;
5679 struct nds32_hint_map
*map_ptr
= hint_map
;
5681 const char *check_insn
[] =
5682 { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" };
5684 /* TODO: PLT GOT. */
5685 /* Traverse all pattern instruction and set flag. */
5686 pattern
= relocs_pattern
;
5689 if (pattern
->opcode
->isize
== 4)
5691 /* 4 byte instruction. */
5692 opcode
= N32_OP6 (pattern
->opcode
->value
);
5696 hi_pattern
= pattern
;
5697 relax_type
|= N32_RELAX_SETHI
;
5700 relax_type
|= N32_RELAX_MEM
;
5703 relax_type
|= N32_RELAX_ALU1
;
5706 relax_type
|= N32_RELAX_ORI
;
5711 relax_type
|= N32_RELAX_BR
;
5714 relax_type
|= N32_RELAX_MOVI
;
5728 relax_type
|= N32_RELAX_LSI
;
5731 if (__GF (pattern
->opcode
->value
, 0, 1) == 1)
5732 relax_type
|= N32_RELAX_CALL
;
5734 relax_type
|= N32_RELAX_JUMP
;
5737 if (__GF (pattern
->opcode
->value
, 24, 1) == 1)
5738 relax_type
|= N32_RELAX_CALL
;
5740 relax_type
|= N32_RELAX_JUMP
;
5743 as_warn (_("relax hint unrecognized instruction: line %d."),
5744 pattern
->frag
->fr_line
);
5750 /* 2 byte instruction. Compare by opcode name because
5751 the opcode of 2byte instruction is not regular. */
5753 for (i
= 0; i
< ARRAY_SIZE (check_insn
); i
++)
5755 if (strcmp (pattern
->opcode
->opcode
, check_insn
[i
]) == 0)
5757 relax_type
|= N32_RELAX_BR
;
5763 relax_type
|= N32_RELAX_16BIT
;
5765 pattern
= pattern
->next
;
5768 /* Analysis instruction flag to choose relaxation table. */
5769 while (map_ptr
->insn_list
!= 0)
5771 struct nds32_hint_map
*hint
= map_ptr
++;
5772 enum nds32_insn_type must
= hint
->insn_list
;
5773 enum nds32_insn_type optional
= hint
->option_list
;
5774 enum nds32_insn_type extra
;
5776 if (must
!= (must
& relax_type
))
5779 extra
= relax_type
^ must
;
5780 if (extra
!= (extra
& optional
))
5784 || (hi_pattern
->fixP
5785 && hi_pattern
->fixP
->fx_r_type
== hint
->hi_type
))
5788 hint_type
= hint
->hint_type
;
5789 range
= hint
->range
;
5795 if (map_ptr
->insn_list
== 0)
5798 as_warn (_("Can not find match relax hint. Line: %d"),
5799 relocs_pattern
->frag
->fr_line
);
5803 /* Get the match table. */
5806 /* Branch relax pattern. */
5807 relax_info
= str_hash_find (nds32_relax_info_hash
, opc
);
5810 fixup_info
= relax_info
->relax_fixup
[range
];
5811 code_seq
= relax_info
->relax_code_seq
[range
];
5812 seq_size
= relax_info
->relax_code_size
[range
];
5816 /* Load-store relax pattern. */
5817 table_ptr
= relax_ls_table
;
5818 while (table_ptr
->main_type
!= 0)
5820 if (table_ptr
->main_type
== hint_type
)
5822 fixup_info
= table_ptr
->relax_fixup
;
5823 code_seq
= table_ptr
->relax_code_seq
;
5824 seq_size
= table_ptr
->relax_code_size
;
5829 if (table_ptr
->main_type
== 0)
5835 hint_fixup
= hint_info
->relax_fixup
;
5836 hint_code
= hint_info
->relax_code_seq
;
5837 hint_info
->relax_code_size
= seq_size
;
5839 while (fixup_info
->size
!= 0)
5841 if (fixup_info
->ramp
& NDS32_HINT
)
5843 memcpy (hint_fixup
, fixup_info
, sizeof (nds32_relax_fixup_info_t
));
5848 /* Clear final relocation. */
5849 memset (hint_fixup
, 0, sizeof (nds32_relax_fixup_info_t
));
5850 /* Copy code sequence. */
5851 memcpy (hint_code
, code_seq
, seq_size
);
5855 /* Because there are a lot of variant of load-store, check
5856 all these type here. */
5858 #define CLEAN_REG(insn) ((insn) & 0xfe0003ff)
5859 #define GET_OPCODE(insn) ((insn) & 0xfe000000)
5862 nds32_match_hint_insn (struct nds32_opcode
*opcode
, uint32_t seq
)
5864 const char *check_insn
[] =
5865 { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8", "jral5" };
5866 uint32_t insn
= opcode
->value
;
5869 insn
= CLEAN_REG (opcode
->value
);
5876 /* In relocation_table, it regards instruction LBI as representation
5877 of all the NDS32_RELAX_HINT_LS pattern. */
5878 if (insn
== OP6 (LBI
) || insn
== OP6 (SBI
) || insn
== OP6 (LBSI
)
5879 || insn
== OP6 (LHI
) || insn
== OP6 (SHI
) || insn
== OP6 (LHSI
)
5880 || insn
== OP6 (LWI
) || insn
== OP6 (SWI
)
5881 || insn
== OP6 (LWC
) || insn
== OP6 (SWC
)
5882 || insn
== OP6 (LDC
) || insn
== OP6 (SDC
))
5886 /* This is for LONGCALL5 and LONGCALL6. */
5887 if (insn
== OP6 (BR2
))
5891 /* This is for LONGJUMP5 and LONGJUMP6. */
5892 if (opcode
->isize
== 4
5893 && (insn
== OP6 (BR1
) || insn
== OP6 (BR2
) || insn
== OP6 (BR3
)))
5895 else if (opcode
->isize
== 2)
5897 for (i
= 0; i
< ARRAY_SIZE (check_insn
); i
++)
5898 if (strcmp (opcode
->opcode
, check_insn
[i
]) == 0)
5903 /* This is for LONGJUMP7. */
5904 if (opcode
->isize
== 2 && strcmp (opcode
->opcode
, "movi55") == 0)
5908 if (OP6 (MEM
) == GET_OPCODE (insn
))
5912 /* bit 24: N32_JI_JAL */ /* feed me! */
5913 if ((insn
& ~(N32_BIT (24))) == JREG (JRAL
))
5917 if (opcode
->isize
== 2)
5919 for (i
= 0; i
< ARRAY_SIZE (check_insn
); i
++)
5920 if (strcmp (opcode
->opcode
, check_insn
[i
]) == 0)
5923 if ((strcmp (opcode
->opcode
, "add5.pc") == 0) ||
5924 (strcmp (opcode
->opcode
, "add45") == 0))
5931 /* Append relax relocation for link time relaxing. */
5934 nds32_elf_append_relax_relocs (const char *key
, const void *value
)
5936 struct nds32_relocs_pattern
*relocs_pattern
=
5937 (struct nds32_relocs_pattern
*) value
;
5938 struct nds32_relocs_pattern
*pattern_temp
, *pattern_now
;
5939 symbolS
*sym
, *hi_sym
= NULL
;
5942 segT seg_bak
= now_seg
;
5943 frchainS
*frchain_bak
= frchain_now
;
5944 struct nds32_relax_hint_table hint_info
;
5945 nds32_relax_fixup_info_t
*hint_fixup
, *fixup_now
;
5947 offsetT branch_offset
, hi_branch_offset
= 0;
5950 unsigned int ptr_offset
, hint_count
, relax_code_size
, count
= 0;
5951 uint32_t *code_seq
, code_insn
;
5955 if (!relocs_pattern
)
5958 if (!nds32_find_reloc_table (relocs_pattern
, &hint_info
))
5961 /* Save symbol for some EMPTY relocation using. */
5962 pattern_now
= relocs_pattern
;
5965 if (pattern_now
->opcode
->value
== OP6 (SETHI
))
5967 hi_sym
= pattern_now
->sym
;
5968 hi_branch_offset
= pattern_now
->fixP
->fx_offset
;
5971 pattern_now
= pattern_now
->next
;
5974 /* Inserting fix up must specify now_seg or frchain_now. */
5975 now_seg
= relocs_pattern
->seg
;
5976 frchain_now
= relocs_pattern
->frchain
;
5977 fragP
= relocs_pattern
->frag
;
5978 branch_offset
= fragP
->fr_offset
;
5980 hint_fixup
= hint_info
.relax_fixup
;
5981 code_seq
= hint_info
.relax_code_seq
;
5982 relax_code_size
= hint_info
.relax_code_size
;
5983 pattern_now
= relocs_pattern
;
5985 #ifdef NDS32_LINUX_TOOLCHAIN
5986 /* prepare group relocation ID (number). */
5990 /* convert .relax_hint key to number */
5992 group_id
= strtol (key
, NULL
, 10);
5993 if ((errno
== ERANGE
&& (group_id
== LONG_MAX
|| group_id
== LONG_MIN
))
5994 || (errno
!= 0 && group_id
== 0))
5996 as_bad (_("Internal error: .relax_hint KEY is not a number!"));
6002 /* Insert relaxation. */
6003 exp
.X_op
= O_symbol
;
6005 /* For each instruction in the hint group. */
6008 if (count
>= relax_code_size
/ 4)
6011 /* Choose the match fixup by instruction. */
6012 code_insn
= CLEAN_REG (*(code_seq
+ count
));
6013 if (!nds32_match_hint_insn (pattern_now
->opcode
, code_insn
))
6015 /* Try search from head again */
6017 code_insn
= CLEAN_REG (*(code_seq
+ count
));
6019 while (!nds32_match_hint_insn (pattern_now
->opcode
, code_insn
))
6022 if (count
>= relax_code_size
/ 4)
6024 as_bad (_("Internal error: Relax hint (%s) error. %s: %s (%x)"),
6027 pattern_now
->opcode
->opcode
,
6028 pattern_now
->opcode
->value
);
6031 code_insn
= CLEAN_REG (*(code_seq
+ count
));
6034 fragP
= pattern_now
->frag
;
6035 sym
= pattern_now
->sym
;
6036 branch_offset
= fragP
->fr_offset
;
6038 where
= pattern_now
->where
;
6039 /* Find the instruction map fix. */
6040 fixup_now
= hint_fixup
;
6041 while (fixup_now
->offset
!= offset
)
6044 if (fixup_now
->size
== 0)
6047 /* This element is without relaxation relocation. */
6048 if (fixup_now
->size
== 0)
6050 pattern_now
= pattern_now
->next
;
6053 fixup_size
= fixup_now
->size
;
6055 /* Insert all fixup. */
6057 while (fixup_size
!= 0 && fixup_now
->offset
== offset
)
6059 /* Set the real instruction size in element. */
6060 fixup_size
= pattern_now
->opcode
->isize
;
6061 pcrel
= ((fixup_now
->ramp
& NDS32_PCREL
) != 0) ? 1 : 0;
6062 if (fixup_now
->ramp
& NDS32_FIX
)
6064 /* Convert original relocation. */
6065 pattern_now
->fixP
->fx_r_type
= fixup_now
->r_type
;
6068 else if ((fixup_now
->ramp
& NDS32_PTR
) != 0)
6070 /* This relocation has to point to another instruction. Make
6071 sure each resolved relocation has to be pointed. */
6072 pattern_temp
= relocs_pattern
;
6073 /* All instruction in relax_table should be 32-bit. */
6074 hint_count
= hint_info
.relax_code_size
/ 4;
6075 code_insn
= CLEAN_REG (*(code_seq
+ hint_count
- 1));
6076 while (pattern_temp
)
6078 /* Point to every resolved relocation. */
6079 if (nds32_match_hint_insn (pattern_temp
->opcode
, code_insn
))
6082 pattern_temp
->where
- pattern_temp
->frag
->fr_literal
;
6083 exp
.X_add_symbol
= symbol_temp_new (now_seg
,
6086 exp
.X_add_number
= 0;
6088 fix_new_exp (fragP
, where
- fragP
->fr_literal
,
6089 fixup_size
, &exp
, 0, fixup_now
->r_type
);
6090 fixP
->fx_addnumber
= fixP
->fx_offset
;
6092 pattern_temp
= pattern_temp
->next
;
6096 else if (fixup_now
->ramp
& NDS32_ADDEND
)
6098 range
= nds32_elf_sethi_range (relocs_pattern
);
6099 if (range
== NDS32_LOADSTORE_NONE
)
6101 as_bad (_("Internal error: Range error. %s"), now_seg
->name
);
6104 exp
.X_add_symbol
= abs_section_sym
;
6105 exp
.X_add_number
= SET_ADDEND (4, 0, optimize
, enable_16bit
);
6106 exp
.X_add_number
|= ((range
& 0x3f) << 8);
6108 else if ((fixup_now
->ramp
& NDS32_ABS
) != 0)
6110 /* This is a tag relocation. */
6111 exp
.X_add_symbol
= abs_section_sym
;
6112 exp
.X_add_number
= 0;
6114 else if ((fixup_now
->ramp
& NDS32_INSN16
) != 0)
6118 /* This is a tag relocation. */
6119 exp
.X_add_symbol
= abs_section_sym
;
6120 exp
.X_add_number
= 0;
6122 else if ((fixup_now
->ramp
& NDS32_SYM
) != 0)
6124 /* For EMPTY relocation save the true symbol. */
6125 exp
.X_add_symbol
= hi_sym
;
6126 exp
.X_add_number
= hi_branch_offset
;
6128 else if (NDS32_SYM_DESC_MEM
& fixup_now
->ramp
)
6130 /* Do the same as NDS32_SYM. */
6131 exp
.X_add_symbol
= hi_sym
;
6132 exp
.X_add_number
= hi_branch_offset
;
6134 /* Extra to NDS32_SYM. */
6135 /* Detect if DESC_FUNC relax type do apply. */
6136 if ((REG_GP
== N32_RA5 (pattern_now
->insn
))
6137 || (REG_GP
== N32_RB5 (pattern_now
->insn
)))
6139 fixP
= fix_new_exp (fragP
, where
- fragP
->fr_literal
,
6140 fixup_size
, &exp
, pcrel
,
6141 BFD_RELOC_NDS32_TLS_DESC_FUNC
);
6142 fixP
->fx_addnumber
= fixP
->fx_offset
;
6146 /* Else do as usual. */
6148 else if (fixup_now
->ramp
& NDS32_PTR_PATTERN
)
6150 /* Find out PTR_RESOLVED code pattern. */
6151 nds32_relax_fixup_info_t
*next_fixup
= fixup_now
+ 1;
6152 uint32_t resolved_pattern
= 0;
6153 while (next_fixup
->offset
)
6155 if (next_fixup
->r_type
== BFD_RELOC_NDS32_PTR_RESOLVED
)
6157 uint32_t new_pattern
= code_seq
[next_fixup
->offset
>> 2];
6158 if (!resolved_pattern
)
6159 resolved_pattern
= new_pattern
;
6160 else if (new_pattern
!= resolved_pattern
)
6162 as_warn (_("Multiple BFD_RELOC_NDS32_PTR_RESOLVED "
6163 "patterns are not supported yet!"));
6170 /* Find matched code and insert fix-ups. */
6171 struct nds32_relocs_pattern
*next_pattern
= pattern_now
->next
;
6172 /* This relocation has to point to another instruction.
6173 Make sure each resolved relocation has to be pointed. */
6174 /* All instruction in relax_table should be 32-bit. */
6175 while (next_pattern
)
6177 uint32_t cur_pattern
= GET_OPCODE (next_pattern
->opcode
->value
);
6178 if (cur_pattern
== resolved_pattern
)
6180 ptr_offset
= next_pattern
->where
6181 - next_pattern
->frag
->fr_literal
;
6182 exp
.X_add_symbol
= symbol_temp_new (now_seg
,
6185 exp
.X_add_number
= 0;
6186 fixP
= fix_new_exp (fragP
, where
- fragP
->fr_literal
,
6187 fixup_size
, &exp
, 0,
6189 fixP
->fx_addnumber
= fixP
->fx_offset
;
6191 next_pattern
= next_pattern
->next
;
6196 else if (fixup_now
->ramp
& NDS32_PTR_MULTIPLE
)
6198 /* Find each PTR_RESOLVED pattern after PTR. */
6199 nds32_relax_fixup_info_t
*next_fixup
= fixup_now
+ 1;
6200 while (next_fixup
->offset
)
6202 if (next_fixup
->r_type
== BFD_RELOC_NDS32_PTR_RESOLVED
)
6204 uint32_t pattern
= code_seq
[next_fixup
->offset
>> 2];
6205 /* Find matched code to insert fix-ups. */
6206 struct nds32_relocs_pattern
*next_insn
= pattern_now
->next
;
6209 uint32_t insn_pattern
= GET_OPCODE (next_insn
->opcode
->value
);
6210 if (insn_pattern
== pattern
)
6212 ptr_offset
= next_insn
->where
6213 - next_insn
->frag
->fr_literal
;
6214 exp
.X_add_symbol
= symbol_temp_new (now_seg
,
6217 exp
.X_add_number
= 0;
6218 fixP
= fix_new_exp (fragP
,
6219 where
- fragP
->fr_literal
,
6220 fixup_size
, &exp
, 0,
6222 fixP
->fx_addnumber
= fixP
->fx_offset
;
6224 next_insn
= next_insn
->next
;
6233 exp
.X_add_symbol
= sym
;
6234 exp
.X_add_number
= branch_offset
;
6237 if (fixup_size
!= 0)
6239 fixP
= fix_new_exp (fragP
, where
- fragP
->fr_literal
, fixup_size
,
6240 &exp
, pcrel
, fixup_now
->r_type
);
6241 fixP
->fx_addnumber
= fixP
->fx_offset
;
6244 fixup_size
= fixup_now
->size
;
6247 #ifdef NDS32_LINUX_TOOLCHAIN
6248 /* Insert group relocation for each relax hint. */
6251 exp
.X_add_symbol
= hi_sym
; /* for eyes only */
6252 exp
.X_add_number
= group_id
;
6253 fixP
= fix_new_exp (fragP
, where
- fragP
->fr_literal
, fixup_size
,
6254 &exp
, pcrel
, BFD_RELOC_NDS32_GROUP
);
6255 fixP
->fx_addnumber
= fixP
->fx_offset
;
6259 if (count
< relax_code_size
/ 4)
6261 pattern_now
= pattern_now
->next
;
6266 frchain_now
= frchain_bak
;
6270 nds32_elf_append_relax_relocs_traverse (void **slot
, void *arg ATTRIBUTE_UNUSED
)
6272 string_tuple_t
*tuple
= *((string_tuple_t
**) slot
);
6273 nds32_elf_append_relax_relocs (tuple
->key
, tuple
->value
);
6279 nds32_str_tolower (const char *src
, char *dest
)
6281 unsigned int i
, len
;
6285 for (i
= 0; i
< len
; i
++)
6286 *(dest
+ i
) = TOLOWER (*(src
+ i
));
6291 /* Check instruction if it can be used for the baseline. */
6294 nds32_check_insn_available (struct nds32_asm_insn insn
, const char *str
)
6296 int attr
= insn
.attr
& ATTR_ALL
;
6297 static int baseline_isa
= 0;
6300 s
= xmalloc (strlen (str
) + 1);
6301 nds32_str_tolower (str
, s
);
6303 && (((insn
.opcode
->value
== ALU2 (MTUSR
)
6304 || insn
.opcode
->value
== ALU2 (MFUSR
))
6305 && (strstr (s
, "lc")
6307 || strstr (s
, "lb")))
6308 || (insn
.attr
& NASM_ATTR_ZOL
)))
6310 as_bad (_("Not support instruction %s in verbatim."), str
);
6315 if (!enable_16bit
&& insn
.opcode
->isize
== 2)
6317 as_bad (_("16-bit instruction is disabled: %s."), str
);
6321 /* No isa setting or all isa can use. */
6322 if (attr
== 0 || attr
== ATTR_ALL
)
6325 if (baseline_isa
== 0)
6327 /* Map option baseline and instruction attribute. */
6328 switch (nds32_baseline
)
6331 baseline_isa
= ATTR (ISA_V2
);
6334 baseline_isa
= ATTR (ISA_V3
);
6337 baseline_isa
= ATTR (ISA_V3M
);
6342 if ((baseline_isa
& attr
) == 0)
6344 as_bad (_("Instruction %s not supported in the baseline."), str
);
6350 /* Stub of machine dependent. */
6353 md_assemble (char *str
)
6355 struct nds32_asm_insn insn
;
6357 struct nds32_pseudo_opcode
*popcode
;
6358 const struct nds32_field
*fld
= NULL
;
6361 struct nds32_relocs_pattern
*relocs_temp
;
6362 struct nds32_relocs_group
*group_temp
;
6364 int label
= label_exist
;
6365 static bfd_boolean pseudo_hint
= FALSE
;
6367 popcode
= nds32_lookup_pseudo_opcode (str
);
6368 /* Note that we need to check 'verbatim' and
6369 'opcode->physical_op'. If the assembly content is generated by
6370 compiler and this opcode is a physical instruction, there is no
6371 need to perform pseudo instruction expansion/transformation. */
6372 if (popcode
&& !(verbatim
&& popcode
->physical_op
))
6374 /* Pseudo instruction is with relax_hint. */
6377 pseudo_opcode
= TRUE
;
6378 nds32_pseudo_opcode_wrapper (str
, popcode
);
6379 pseudo_opcode
= FALSE
;
6380 pseudo_hint
= FALSE
;
6381 nds32_elf_append_relax_relocs (NULL
, relocs_list
);
6383 /* Free relax_hint group list. */
6384 while (nds32_relax_hint_current
)
6386 group_temp
= nds32_relax_hint_current
->next
;
6387 free (nds32_relax_hint_current
);
6388 nds32_relax_hint_current
= group_temp
;
6391 /* Free pseudo list. */
6392 relocs_temp
= relocs_list
;
6395 relocs_list
= relocs_list
->next
;
6397 relocs_temp
= relocs_list
;
6404 insn
.info
= XNEW (expressionS
);
6405 asm_desc
.result
= NASM_OK
;
6406 nds32_assemble (&asm_desc
, &insn
, str
);
6408 switch (asm_desc
.result
)
6410 case NASM_ERR_UNKNOWN_OP
:
6411 as_bad (_("Unrecognized opcode, %s."), str
);
6413 case NASM_ERR_SYNTAX
:
6414 as_bad (_("Incorrect syntax, %s."), str
);
6416 case NASM_ERR_OPERAND
:
6417 as_bad (_("Unrecognized operand/register, %s."), str
);
6419 case NASM_ERR_OUT_OF_RANGE
:
6420 as_bad (_("Operand out of range, %s."), str
);
6422 case NASM_ERR_REG_REDUCED
:
6423 as_bad (_("Prohibited register used for reduced-register, %s."), str
);
6425 case NASM_ERR_JUNK_EOL
:
6426 as_bad (_("Junk at end of line, %s."), str
);
6430 gas_assert (insn
.opcode
);
6432 nds32_set_elf_flags_by_insn (&insn
);
6434 gas_assert (insn
.opcode
->isize
== 4 || insn
.opcode
->isize
== 2);
6436 if (!nds32_check_insn_available (insn
, str
))
6439 /* Make sure the beginning of text being 2-byte align. */
6440 nds32_adjust_label (1);
6441 add_mapping_symbol (MAP_CODE
, 0, 0);
6443 /* Try to allocate the max size to guarantee relaxable same branch
6444 instructions in the same fragment. */
6445 frag_grow (NDS32_MAXCHAR
);
6448 if (fld
&& (insn
.attr
& NASM_ATTR_BRANCH
)
6449 && (pseudo_opcode
|| (insn
.opcode
->value
!= INSN_JAL
6450 && insn
.opcode
->value
!= INSN_J
))
6451 && (!verbatim
|| pseudo_opcode
))
6453 /* User assembly code branch relax for it. */
6454 /* If fld is not NULL, it is a symbol. */
6455 /* Branch must relax to proper pattern in user assembly code exclude
6456 J and JAL. Keep these two in original type for users which wants
6457 to keep their size be fixed. In general, assembler does not convert
6458 instruction generated by compiler. But jump instruction may be
6459 truncated in text virtual model. For workaround, compiler generate
6460 pseudo jump to fix this issue currently. */
6462 /* Get branch range type. */
6463 dwarf2_emit_insn (0);
6464 enum nds32_br_range range_type
;
6465 expressionS
*pexp
= insn
.info
;
6467 range_type
= get_range_type (fld
);
6469 out
= frag_var (rs_machine_dependent
, NDS32_MAXCHAR
,
6470 0, /* VAR is un-used. */
6471 range_type
, /* SUBTYPE is used as range type. */
6472 pexp
->X_add_symbol
, pexp
->X_add_number
, 0);
6474 fragP
->fr_fix
+= insn
.opcode
->isize
;
6475 fragP
->tc_frag_data
.opcode
= insn
.opcode
;
6476 fragP
->tc_frag_data
.insn
= insn
.insn
;
6477 if (insn
.opcode
->isize
== 4)
6478 bfd_putb32 (insn
.insn
, out
);
6479 else if (insn
.opcode
->isize
== 2)
6480 bfd_putb16 (insn
.insn
, out
);
6481 fragP
->tc_frag_data
.flag
|= NDS32_FRAG_BRANCH
;
6485 /* md_convert_frag will insert relocations. */
6487 else if (!relaxing
&& enable_16bit
&& (optimize
|| optimize_for_space
)
6488 && ((!fld
&& !verbatim
&& insn
.opcode
->isize
== 4
6489 && nds32_convert_32_to_16 (stdoutput
, insn
.insn
, &insn_16
, NULL
))
6490 || (insn
.opcode
->isize
== 2
6491 && nds32_convert_16_to_32 (stdoutput
, insn
.insn
, NULL
))))
6493 /* Record this one is relaxable. */
6494 expressionS
*pexp
= insn
.info
;
6495 dwarf2_emit_insn (0);
6498 out
= frag_var (rs_machine_dependent
,
6499 4, /* Max size is 32-bit instruction. */
6500 0, /* VAR is un-used. */
6501 0, pexp
->X_add_symbol
, pexp
->X_add_number
, 0);
6502 fragP
->tc_frag_data
.flag
|= NDS32_FRAG_RELAXABLE_BRANCH
;
6505 out
= frag_var (rs_machine_dependent
,
6506 4, /* Max size is 32-bit instruction. */
6507 0, /* VAR is un-used. */
6509 fragP
->tc_frag_data
.flag
|= NDS32_FRAG_RELAXABLE
;
6510 fragP
->tc_frag_data
.opcode
= insn
.opcode
;
6511 fragP
->tc_frag_data
.insn
= insn
.insn
;
6514 /* In original, we don't relax the instruction with label on it,
6515 but this may cause some redundant nop16. Therefore, tag this
6516 relaxable instruction and relax it carefully. */
6518 fragP
->tc_frag_data
.flag
|= NDS32_FRAG_LABEL
;
6520 if (insn
.opcode
->isize
== 4)
6521 bfd_putb16 (insn_16
, out
);
6522 else if (insn
.opcode
->isize
== 2)
6523 bfd_putb16 (insn
.insn
, out
);
6528 else if ((verbatim
|| !relaxing
) && optimize
&& label
)
6530 /* This instruction is with label. */
6532 out
= frag_var (rs_machine_dependent
, insn
.opcode
->isize
,
6533 0, 0, NULL
, 0, NULL
);
6534 /* If this instruction is branch target, it is not relaxable. */
6535 fragP
->tc_frag_data
.flag
= NDS32_FRAG_LABEL
;
6536 fragP
->tc_frag_data
.opcode
= insn
.opcode
;
6537 fragP
->tc_frag_data
.insn
= insn
.insn
;
6538 fragP
->fr_fix
+= insn
.opcode
->isize
;
6539 if (insn
.opcode
->isize
== 4)
6541 exp
.X_op
= O_symbol
;
6542 exp
.X_add_symbol
= abs_section_sym
;
6543 exp
.X_add_number
= 0;
6544 fixP
= fix_new_exp (fragP
, fragP
->fr_fix
- 4, 0, &exp
,
6545 0, BFD_RELOC_NDS32_LABEL
);
6547 fragP
->tc_frag_data
.flag
= NDS32_FRAG_ALIGN
;
6551 out
= frag_more (insn
.opcode
->isize
);
6553 if (insn
.opcode
->isize
== 4)
6554 bfd_putb32 (insn
.insn
, out
);
6555 else if (insn
.opcode
->isize
== 2)
6556 bfd_putb16 (insn
.insn
, out
);
6558 dwarf2_emit_insn (insn
.opcode
->isize
);
6560 /* Compiler generating code and user assembly pseudo load-store, insert
6562 expressionS
*pexp
= insn
.info
;
6563 fixP
= nds32_elf_record_fixup_exp (fragP
, str
, fld
, pexp
, out
, &insn
);
6564 /* Build relaxation pattern when relaxing is enable. */
6566 nds32_elf_build_relax_relation (fixP
, pexp
, out
, &insn
, fragP
, fld
,
6572 /* md_macro_start */
6575 nds32_macro_start (void)
6582 nds32_macro_info (void *info ATTRIBUTE_UNUSED
)
6589 nds32_macro_end (void)
6593 /* GAS will call this function with one argument, an expressionS pointer, for
6594 any expression that can not be recognized. When the function is called,
6595 input_line_pointer will point to the start of the expression. */
6598 md_operand (expressionS
*expressionP
)
6600 if (*input_line_pointer
== '#')
6602 input_line_pointer
++;
6603 expression (expressionP
);
6607 /* GAS will call this function for each section at the end of the assembly, to
6608 permit the CPU back end to adjust the alignment of a section. The function
6609 must take two arguments, a segT for the section and a valueT for the size of
6610 the section, and return a valueT for the rounded size. */
6613 md_section_align (segT segment
, valueT size
)
6615 int align
= bfd_section_alignment (segment
);
6617 return ((size
+ (1 << align
) - 1) & ((valueT
) -1 << align
));
6620 /* GAS will call this function when a symbol table lookup fails, before it
6621 creates a new symbol. Typically this would be used to supply symbols whose
6622 name or value changes dynamically, possibly in a context sensitive way.
6623 Predefined symbols with fixed values, such as register names or condition
6624 codes, are typically entered directly into the symbol table when md_begin
6625 is called. One argument is passed, a char * for the symbol. */
6628 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
6634 nds32_calc_branch_offset (segT segment
, fragS
*fragP
,
6635 long stretch ATTRIBUTE_UNUSED
,
6636 relax_info_t
*relax_info
,
6637 enum nds32_br_range branch_range_type
)
6639 struct nds32_opcode
*opcode
= fragP
->tc_frag_data
.opcode
;
6640 symbolS
*branch_symbol
= fragP
->fr_symbol
;
6641 offsetT branch_offset
= fragP
->fr_offset
;
6642 offsetT branch_target_address
;
6643 offsetT branch_insn_address
;
6646 if ((S_GET_SEGMENT (branch_symbol
) != segment
)
6647 || S_IS_WEAK (branch_symbol
))
6649 /* The symbol is not in the SEGMENT. It could be far far away. */
6650 offset
= 0x80000000;
6654 /* Calculate symbol-to-instruction offset. */
6655 branch_target_address
= S_GET_VALUE (branch_symbol
) + branch_offset
;
6656 /* If the destination symbol is beyond current frag address,
6657 STRETCH will take effect to symbol's position. */
6658 if (S_GET_VALUE (branch_symbol
) > fragP
->fr_address
)
6659 branch_target_address
+= stretch
;
6661 branch_insn_address
= fragP
->fr_address
+ fragP
->fr_fix
;
6662 branch_insn_address
-= opcode
->isize
;
6664 /* Update BRANCH_INSN_ADDRESS to relaxed position. */
6665 branch_insn_address
+= (relax_info
->relax_code_size
[branch_range_type
]
6666 - relax_info
->relax_branch_isize
[branch_range_type
]);
6668 offset
= branch_target_address
- branch_insn_address
;
6674 static enum nds32_br_range
6675 nds32_convert_to_range_type (long offset
)
6677 enum nds32_br_range range_type
;
6679 if (-(0x100) <= offset
&& offset
< 0x100) /* 256 bytes */
6680 range_type
= BR_RANGE_S256
;
6681 else if (-(0x4000) <= offset
&& offset
< 0x4000) /* 16K bytes */
6682 range_type
= BR_RANGE_S16K
;
6683 else if (-(0x10000) <= offset
&& offset
< 0x10000) /* 64K bytes */
6684 range_type
= BR_RANGE_S64K
;
6685 else if (-(0x1000000) <= offset
&& offset
< 0x1000000) /* 16M bytes */
6686 range_type
= BR_RANGE_S16M
;
6688 range_type
= BR_RANGE_U4G
;
6693 /* Set instruction register mask. */
6696 nds32_elf_get_set_cond (relax_info_t
*relax_info
, int offset
, uint32_t *insn
,
6697 uint32_t ori_insn
, int range
)
6699 nds32_cond_field_t
*cond_fields
= relax_info
->cond_field
;
6700 nds32_cond_field_t
*code_seq_cond
= relax_info
->relax_code_condition
[range
];
6704 /* The instruction has conditions. Collect condition values. */
6705 while (code_seq_cond
[i
].bitmask
!= 0)
6707 if (offset
== code_seq_cond
[i
].offset
)
6709 mask
= (ori_insn
>> cond_fields
[i
].bitpos
) & cond_fields
[i
].bitmask
;
6711 if (cond_fields
[i
].signed_extend
)
6712 mask
= (mask
^ ((cond_fields
[i
].bitmask
+ 1) >> 1)) -
6713 ((cond_fields
[i
].bitmask
+ 1) >> 1);
6714 *insn
|= (mask
& code_seq_cond
[i
].bitmask
) << code_seq_cond
[i
].bitpos
;
6721 nds32_relax_branch_instructions (segT segment
, fragS
*fragP
,
6722 long stretch ATTRIBUTE_UNUSED
,
6725 enum nds32_br_range branch_range_type
;
6726 struct nds32_opcode
*opcode
= fragP
->tc_frag_data
.opcode
;
6728 enum nds32_br_range real_range_type
;
6730 relax_info_t
*relax_info
;
6737 int code_seq_offset
;
6739 /* Replace with gas_assert (fragP->fr_symbol != NULL); */
6740 if (fragP
->fr_symbol
== NULL
)
6743 /* If frag_var is not enough room, the previous frag is fr_full and with
6744 opcode. The new one is rs_dependent but without opcode. */
6748 /* Use U4G mode for b and bal in verbatim mode because lto may combine
6749 functions into a file. And order the file in the last when linking.
6750 Once there is multiple definition, the same function will be kicked.
6751 This may cause relocation truncated error. */
6752 if (verbatim
&& !nds32_pic
6753 && (strcmp (opcode
->opcode
, "j") == 0
6754 || strcmp (opcode
->opcode
, "jal") == 0))
6756 fragP
->fr_subtype
= BR_RANGE_U4G
;
6763 relax_info
= str_hash_find (nds32_relax_info_hash
, opcode
->opcode
);
6765 if (relax_info
== NULL
)
6770 branch_range_type
= relax_info
->br_range
;
6775 branch_range_type
= fragP
->fr_subtype
;
6776 i
= branch_range_type
;
6779 offset
= nds32_calc_branch_offset (segment
, fragP
, stretch
,
6780 relax_info
, branch_range_type
);
6782 real_range_type
= nds32_convert_to_range_type (offset
);
6784 /* If actual range is equal to instruction jump range, do nothing. */
6785 if (real_range_type
== branch_range_type
)
6787 fragP
->fr_subtype
= real_range_type
;
6791 /* Find out proper relaxation code sequence. */
6792 for (; i
< BR_RANGE_NUM
; i
++)
6794 if (real_range_type
<= (unsigned int) i
)
6797 diff
= relax_info
->relax_code_size
[i
] - opcode
->isize
;
6798 else if (real_range_type
< (unsigned int) i
)
6799 diff
= relax_info
->relax_code_size
[real_range_type
]
6800 - relax_info
->relax_code_size
[branch_range_type
];
6802 diff
= relax_info
->relax_code_size
[i
]
6803 - relax_info
->relax_code_size
[branch_range_type
];
6805 /* If the instruction could be converted to 16-bits,
6806 minus the difference. */
6807 code_seq_offset
= 0;
6810 code_seq_size
= relax_info
->relax_code_size
[i
];
6811 code_seq
= relax_info
->relax_code_seq
[i
];
6812 while (code_seq_offset
< code_seq_size
)
6815 if (insn
& 0x80000000) /* 16-bits instruction. */
6819 else /* 32-bits instruction. */
6823 while (relax_info
->relax_fixup
[i
][k
].size
!=0
6824 && relax_info
->relax_fixup
[i
][k
].offset
< code_seq_offset
)
6828 code_seq_offset
+= insn_size
;
6832 /* Update fr_subtype to new NDS32_BR_RANGE. */
6833 fragP
->fr_subtype
= real_range_type
;
6838 return diff
+ adjust
;
6841 /* Adjust relaxable frag till current frag. */
6844 nds32_adjust_relaxable_frag (fragS
*startP
, fragS
*fragP
)
6847 if (startP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
)
6852 startP
->tc_frag_data
.flag
^= NDS32_FRAG_RELAXED
;
6856 startP
= startP
->fr_next
;
6859 startP
->fr_address
+= adj
;
6860 if (startP
== fragP
)
6868 nds32_get_align (addressT address
, int align
)
6870 addressT mask
, new_address
;
6872 mask
= ~((addressT
) (~0) << align
);
6873 new_address
= (address
+ mask
) & (~mask
);
6874 return (new_address
- address
);
6877 /* Check the prev_frag is legal. */
6879 invalid_prev_frag (fragS
* fragP
, fragS
**prev_frag
, bfd_boolean relax
)
6882 fragS
*frag_start
= *prev_frag
;
6884 if (!frag_start
|| !relax
)
6887 if (frag_start
->last_fr_address
>= fragP
->last_fr_address
)
6893 fragS
*frag_t
= *prev_frag
;
6894 while (frag_t
!= fragP
)
6896 if (frag_t
->fr_type
== rs_align
6897 || frag_t
->fr_type
== rs_align_code
6898 || frag_t
->fr_type
== rs_align_test
)
6900 /* Relax instruction can not walk across label. */
6901 if (frag_t
->tc_frag_data
.flag
& NDS32_FRAG_LABEL
)
6906 /* Relax previous relaxable to align rs_align frag. */
6907 address
= frag_t
->fr_address
+ frag_t
->fr_fix
;
6908 addressT offset
= nds32_get_align (address
, (int) frag_t
->fr_offset
);
6911 /* If there is label on the prev_frag, check if it is aligned. */
6912 if (!((*prev_frag
)->tc_frag_data
.flag
& NDS32_FRAG_LABEL
)
6913 || (((*prev_frag
)->fr_address
+ (*prev_frag
)->fr_fix
- 2 )
6915 nds32_adjust_relaxable_frag (*prev_frag
, frag_t
);
6920 frag_t
= frag_t
->fr_next
;
6923 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_ALIGN
)
6925 address
= fragP
->fr_address
;
6926 addressT offset
= nds32_get_align (address
, 2);
6929 /* If there is label on the prev_frag, check if it is aligned. */
6930 if (!((*prev_frag
)->tc_frag_data
.flag
& NDS32_FRAG_LABEL
)
6931 || (((*prev_frag
)->fr_address
+ (*prev_frag
)->fr_fix
- 2 )
6933 nds32_adjust_relaxable_frag (*prev_frag
, fragP
);
6943 nds32_relax_frag (segT segment
, fragS
*fragP
, long stretch ATTRIBUTE_UNUSED
)
6945 /* Currently, there are two kinds of relaxation in nds32 assembler.
6947 2. relax for 32-bits to 16-bits */
6949 static fragS
*prev_frag
= NULL
;
6952 invalid_prev_frag (fragP
, &prev_frag
, TRUE
);
6954 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_BRANCH
)
6955 adjust
= nds32_relax_branch_instructions (segment
, fragP
, stretch
, 0);
6956 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_LABEL
)
6958 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXABLE
6959 && (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
) == 0)
6960 /* Here is considered relaxed case originally. But it may cause
6961 an endless loop when relaxing. Once the instruction is relaxed,
6962 it can not be undone. */
6968 /* This function returns an initial guess of the length by which a fragment
6969 must grow to hold a branch to reach its destination. Also updates
6970 fr_type/fr_subtype as necessary.
6972 It is called just before doing relaxation. Any symbol that is now undefined
6973 will not become defined. The guess for fr_var is ACTUALLY the growth beyond
6974 fr_fix. Whatever we do to grow fr_fix or fr_var contributes to our returned
6975 value. Although it may not be explicit in the frag, pretend fr_var starts
6979 md_estimate_size_before_relax (fragS
*fragP
, segT segment
)
6981 /* Currently, there are two kinds of relaxation in nds32 assembler.
6983 2. relax for 32-bits to 16-bits */
6985 /* Save previous relaxable frag. */
6986 static fragS
*prev_frag
= NULL
;
6989 invalid_prev_frag (fragP
, &prev_frag
, FALSE
);
6991 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_BRANCH
)
6992 adjust
= nds32_relax_branch_instructions (segment
, fragP
, 0, 1);
6993 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_LABEL
)
6995 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
)
6997 else if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXABLE
)
7003 /* GAS will call this for each rs_machine_dependent fragment. The instruction
7004 is completed using the data from the relaxation pass. It may also create any
7005 necessary relocations.
7007 *FRAGP has been relaxed to its final size, and now needs to have the bytes
7008 inside it modified to conform to the new size. It is called after relaxation
7011 fragP->fr_type == rs_machine_dependent.
7012 fragP->fr_subtype is the subtype of what the address relaxed to. */
7015 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, segT sec
, fragS
*fragP
)
7017 /* Convert branch relaxation instructions. */
7018 symbolS
*branch_symbol
= fragP
->fr_symbol
;
7019 offsetT branch_offset
= fragP
->fr_offset
;
7020 enum nds32_br_range branch_range_type
= fragP
->fr_subtype
;
7021 struct nds32_opcode
*opcode
= fragP
->tc_frag_data
.opcode
;
7022 uint32_t origin_insn
= fragP
->tc_frag_data
.insn
;
7023 relax_info_t
*relax_info
;
7026 int addend ATTRIBUTE_UNUSED
;
7027 offsetT branch_target_address
, branch_insn_address
;
7032 int code_size
, insn_size
, offset
, fixup_size
;
7033 int buf_offset
, pcrel
;
7036 nds32_relax_fixup_info_t fixup_info
[MAX_RELAX_FIX
];
7037 /* Save the 1st instruction is converted to 16 bit or not. */
7038 unsigned int branch_size
;
7039 enum bfd_reloc_code_real final_r_type
;
7041 /* Replace with gas_assert (branch_symbol != NULL); */
7042 if (branch_symbol
== NULL
&& !(fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
))
7045 /* If frag_var is not enough room, the previous frag is fr_full and with
7046 opcode. The new one is rs_dependent but without opcode. */
7050 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXABLE_BRANCH
)
7052 relax_info
= str_hash_find (nds32_relax_info_hash
, opcode
->opcode
);
7054 if (relax_info
== NULL
)
7058 while (i
< BR_RANGE_NUM
7059 && relax_info
->relax_code_size
[i
]
7060 != (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
? 4 : 2))
7063 if (i
>= BR_RANGE_NUM
)
7064 as_bad ("Internal error: Cannot find relocation of"
7065 "relaxable branch.");
7067 exp
.X_op
= O_symbol
;
7068 exp
.X_add_symbol
= branch_symbol
;
7069 exp
.X_add_number
= branch_offset
;
7070 pcrel
= ((relax_info
->relax_fixup
[i
][0].ramp
& NDS32_PCREL
) != 0) ? 1 : 0;
7071 fr_where
= fragP
->fr_fix
- 2;
7072 fixP
= fix_new_exp (fragP
, fr_where
, relax_info
->relax_fixup
[i
][0].size
,
7073 &exp
, pcrel
, relax_info
->relax_fixup
[i
][0].r_type
);
7074 fixP
->fx_addnumber
= fixP
->fx_offset
;
7076 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
)
7078 insn_16
= fragP
->tc_frag_data
.insn
;
7079 nds32_convert_16_to_32 (stdoutput
, insn_16
, &insn
);
7080 fr_buffer
= fragP
->fr_literal
+ fr_where
;
7082 exp
.X_op
= O_symbol
;
7083 exp
.X_add_symbol
= abs_section_sym
;
7084 exp
.X_add_number
= 0;
7085 fix_new_exp (fragP
, fr_where
, 4,
7086 &exp
, 0, BFD_RELOC_NDS32_INSN16
);
7087 number_to_chars_bigendian (fr_buffer
, insn
, 4);
7090 else if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
)
7092 if (fragP
->tc_frag_data
.opcode
->isize
== 2)
7094 insn_16
= fragP
->tc_frag_data
.insn
;
7095 nds32_convert_16_to_32 (stdoutput
, insn_16
, &insn
);
7098 insn
= fragP
->tc_frag_data
.insn
;
7100 fr_where
= fragP
->fr_fix
- 4;
7101 fr_buffer
= fragP
->fr_literal
+ fr_where
;
7102 exp
.X_op
= O_symbol
;
7103 exp
.X_add_symbol
= abs_section_sym
;
7104 exp
.X_add_number
= 0;
7105 fix_new_exp (fragP
, fr_where
, 4, &exp
, 0,
7106 BFD_RELOC_NDS32_INSN16
);
7107 number_to_chars_bigendian (fr_buffer
, insn
, 4);
7109 else if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_BRANCH
)
7111 /* Branch instruction adjust and append relocations. */
7112 relax_info
= str_hash_find (nds32_relax_info_hash
, opcode
->opcode
);
7114 if (relax_info
== NULL
)
7117 fr_where
= fragP
->fr_fix
- opcode
->isize
;
7118 fr_buffer
= fragP
->fr_literal
+ fr_where
;
7120 if ((S_GET_SEGMENT (branch_symbol
) != sec
)
7121 || S_IS_WEAK (branch_symbol
))
7123 if (fragP
->fr_offset
& 3)
7124 as_warn (_("Addend to unresolved symbol is not on word boundary."));
7129 /* Calculate symbol-to-instruction offset. */
7130 branch_target_address
= S_GET_VALUE (branch_symbol
) + branch_offset
;
7131 branch_insn_address
= fragP
->fr_address
+ fr_where
;
7132 addend
= (branch_target_address
- branch_insn_address
) >> 1;
7135 code_size
= relax_info
->relax_code_size
[branch_range_type
];
7136 code_seq
= relax_info
->relax_code_seq
[branch_range_type
];
7138 memcpy (fixup_info
, relax_info
->relax_fixup
[branch_range_type
],
7139 sizeof (fixup_info
));
7144 offset
= 0; /* code_seq offset */
7145 buf_offset
= 0; /* fr_buffer offset */
7146 while (offset
< code_size
)
7149 if (insn
& 0x80000000) /* 16-bits instruction. */
7151 insn
= (insn
>> 16) & 0xFFFF;
7154 else /* 32-bits instruction. */
7159 nds32_elf_get_set_cond (relax_info
, offset
, &insn
,
7160 origin_insn
, branch_range_type
);
7162 /* Try to convert to 16-bits instruction. Currently, only the first
7163 instruction in pattern can be converted. EX: bnez sethi ori jr,
7164 only bnez can be converted to 16 bit and ori can't. */
7166 while (fixup_info
[k
].size
!= 0
7167 && relax_info
->relax_fixup
[branch_range_type
][k
].offset
< offset
)
7170 number_to_chars_bigendian (fr_buffer
+ buf_offset
, insn
, insn_size
);
7171 buf_offset
+= insn_size
;
7173 offset
+= insn_size
;
7178 exp
.X_op
= O_symbol
;
7180 for (i
= 0; fixup_info
[i
].size
!= 0; i
++)
7182 fixup_size
= fixup_info
[i
].size
;
7183 pcrel
= ((fixup_info
[i
].ramp
& NDS32_PCREL
) != 0) ? 1 : 0;
7185 if ((fixup_info
[i
].ramp
& NDS32_CREATE_LABEL
) != 0)
7187 /* This is a reverse branch. */
7188 exp
.X_add_symbol
= symbol_temp_new (sec
, fragP
->fr_next
, 0);
7189 exp
.X_add_number
= 0;
7191 else if ((fixup_info
[i
].ramp
& NDS32_PTR
) != 0)
7193 /* This relocation has to point to another instruction. */
7194 branch_size
= fr_where
+ code_size
- 4;
7195 exp
.X_add_symbol
= symbol_temp_new (sec
, fragP
, branch_size
);
7196 exp
.X_add_number
= 0;
7198 else if ((fixup_info
[i
].ramp
& NDS32_ABS
) != 0)
7200 /* This is a tag relocation. */
7201 exp
.X_add_symbol
= abs_section_sym
;
7202 exp
.X_add_number
= 0;
7204 else if ((fixup_info
[i
].ramp
& NDS32_INSN16
) != 0)
7208 /* This is a tag relocation. */
7209 exp
.X_add_symbol
= abs_section_sym
;
7210 exp
.X_add_number
= 0;
7214 exp
.X_add_symbol
= branch_symbol
;
7215 exp
.X_add_number
= branch_offset
;
7218 if (fixup_info
[i
].r_type
!= 0)
7220 final_r_type
= fixup_info
[i
].r_type
;
7221 fixP
= fix_new_exp (fragP
, fr_where
+ fixup_info
[i
].offset
,
7222 fixup_size
, &exp
, pcrel
,
7224 fixP
->fx_addnumber
= fixP
->fx_offset
;
7228 fragP
->fr_fix
= fr_where
+ buf_offset
;
7232 /* tc_frob_file_before_fix */
7235 nds32_frob_file_before_fix (void)
7240 nds32_relaxable_section (asection
*sec
)
7242 return ((sec
->flags
& SEC_DEBUGGING
) == 0
7243 && strcmp (sec
->name
, ".eh_frame") != 0);
7246 /* TC_FORCE_RELOCATION */
7248 nds32_force_relocation (fixS
* fix
)
7250 switch (fix
->fx_r_type
)
7252 case BFD_RELOC_NDS32_INSN16
:
7253 case BFD_RELOC_NDS32_LABEL
:
7254 case BFD_RELOC_NDS32_LONGCALL1
:
7255 case BFD_RELOC_NDS32_LONGCALL2
:
7256 case BFD_RELOC_NDS32_LONGCALL3
:
7257 case BFD_RELOC_NDS32_LONGJUMP1
:
7258 case BFD_RELOC_NDS32_LONGJUMP2
:
7259 case BFD_RELOC_NDS32_LONGJUMP3
:
7260 case BFD_RELOC_NDS32_LOADSTORE
:
7261 case BFD_RELOC_NDS32_9_FIXED
:
7262 case BFD_RELOC_NDS32_15_FIXED
:
7263 case BFD_RELOC_NDS32_17_FIXED
:
7264 case BFD_RELOC_NDS32_25_FIXED
:
7265 case BFD_RELOC_NDS32_9_PCREL
:
7266 case BFD_RELOC_NDS32_15_PCREL
:
7267 case BFD_RELOC_NDS32_17_PCREL
:
7268 case BFD_RELOC_NDS32_WORD_9_PCREL
:
7269 case BFD_RELOC_NDS32_10_UPCREL
:
7270 case BFD_RELOC_NDS32_25_PCREL
:
7271 case BFD_RELOC_NDS32_MINUEND
:
7272 case BFD_RELOC_NDS32_SUBTRAHEND
:
7278 case BFD_RELOC_NDS32_DIFF_ULEB128
:
7279 /* Linker should handle difference between two symbol. */
7280 return fix
->fx_subsy
!= NULL
7281 && nds32_relaxable_section (S_GET_SEGMENT (fix
->fx_addsy
));
7284 as_bad ("Double word for difference between two symbols "
7285 "is not supported across relaxation.");
7290 if (generic_force_reloc (fix
))
7293 return fix
->fx_pcrel
;
7296 /* TC_VALIDATE_FIX_SUB */
7299 nds32_validate_fix_sub (fixS
*fix
, segT add_symbol_segment
)
7301 segT sub_symbol_segment
;
7303 /* This code is referred from Xtensa. Check their implementation for
7306 /* Make sure both symbols are in the same segment, and that segment is
7307 "normal" and relaxable. */
7308 sub_symbol_segment
= S_GET_SEGMENT (fix
->fx_subsy
);
7309 return (sub_symbol_segment
== add_symbol_segment
7310 && add_symbol_segment
!= undefined_section
);
7314 md_number_to_chars (char *buf
, valueT val
, int n
)
7316 if (target_big_endian
)
7317 number_to_chars_bigendian (buf
, val
, n
);
7319 number_to_chars_littleendian (buf
, val
, n
);
7322 /* This function is called to convert an ASCII string into a floating point
7323 value in format used by the CPU. */
7326 md_atof (int type
, char *litP
, int *sizeP
)
7330 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
7349 return _("Bad call to md_atof()");
7352 t
= atof_ieee (input_line_pointer
, type
, words
);
7354 input_line_pointer
= t
;
7355 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
7357 if (target_big_endian
)
7359 for (i
= 0; i
< prec
; i
++)
7361 md_number_to_chars (litP
, (valueT
) words
[i
],
7362 sizeof (LITTLENUM_TYPE
));
7363 litP
+= sizeof (LITTLENUM_TYPE
);
7368 for (i
= prec
- 1; i
>= 0; i
--)
7370 md_number_to_chars (litP
, (valueT
) words
[i
],
7371 sizeof (LITTLENUM_TYPE
));
7372 litP
+= sizeof (LITTLENUM_TYPE
);
7379 /* md_elf_section_change_hook */
7382 nds32_elf_section_change_hook (void)
7389 nds32_cleanup (void)
7393 /* This function is used to scan leb128 subtraction expressions,
7394 and insert fixups for them.
7396 e.g., .leb128 .L1 - .L0
7398 These expressions are heavily used in debug information or
7399 exception tables. Because relaxation will change code size,
7400 we must resolve them in link time. */
7403 nds32_insert_leb128_fixes (bfd
*abfd ATTRIBUTE_UNUSED
,
7404 asection
*sec
, void *xxx ATTRIBUTE_UNUSED
)
7406 segment_info_type
*seginfo
= seg_info (sec
);
7409 subseg_set (sec
, 0);
7411 for (fragP
= seginfo
->frchainP
->frch_root
;
7412 fragP
; fragP
= fragP
->fr_next
)
7416 /* Only unsigned leb128 can be handle. */
7417 if (fragP
->fr_type
!= rs_leb128
|| fragP
->fr_subtype
!= 0
7418 || fragP
->fr_symbol
== NULL
)
7421 exp
= symbol_get_value_expression (fragP
->fr_symbol
);
7423 if (exp
->X_op
!= O_subtract
)
7426 fix_new_exp (fragP
, fragP
->fr_fix
, 0,
7427 exp
, 0, BFD_RELOC_NDS32_DIFF_ULEB128
);
7432 nds32_insert_relax_entry (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*sec
,
7433 void *xxx ATTRIBUTE_UNUSED
)
7435 segment_info_type
*seginfo
;
7441 seginfo
= seg_info (sec
);
7442 if (!seginfo
|| !symbol_rootP
|| !subseg_text_p (sec
) || sec
->size
== 0)
7445 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= fixp
->fx_next
)
7449 if (!fixp
&& !verbatim
&& ict_flag
== ICT_NONE
)
7452 subseg_change (sec
, 0);
7454 /* Set RELAX_ENTRY flags for linker. */
7455 fragP
= seginfo
->frchainP
->frch_root
;
7456 exp
.X_op
= O_symbol
;
7457 exp
.X_add_symbol
= abs_section_sym
;
7458 exp
.X_add_number
= 0;
7459 if (!enable_relax_relocs
)
7460 exp
.X_add_number
|= R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG
;
7463 /* These flags are only enabled when global relax is enabled.
7464 Maybe we can check DISABLE_RELAX_FLAG at link-time,
7465 so we set them anyway. */
7467 exp
.X_add_number
|= R_NDS32_RELAX_ENTRY_VERBATIM_FLAG
;
7468 if (ict_flag
== ICT_SMALL
)
7469 exp
.X_add_number
|= R_NDS32_RELAX_ENTRY_ICT_SMALL
;
7470 else if (ict_flag
== ICT_LARGE
)
7471 exp
.X_add_number
|= R_NDS32_RELAX_ENTRY_ICT_LARGE
;
7474 exp
.X_add_number
|= R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG
;
7475 if (optimize_for_space
)
7476 exp
.X_add_number
|= R_NDS32_RELAX_ENTRY_OPTIMIZE_FOR_SPACE_FLAG
;
7478 fixP
= fix_new_exp (fragP
, 0, 0, &exp
, 0, BFD_RELOC_NDS32_RELAX_ENTRY
);
7479 fixP
->fx_no_overflow
= 1;
7482 /* Analysis relax hint and insert suitable relocation pattern. */
7485 nds32_elf_analysis_relax_hint (void)
7487 htab_traverse (nds32_hint_hash
, nds32_elf_append_relax_relocs_traverse
, NULL
);
7491 nds32_elf_insert_final_frag (void)
7493 struct frchain
*frchainP
;
7500 for (s
= stdoutput
->sections
; s
; s
= s
->next
)
7502 segment_info_type
*seginfo
= seg_info (s
);
7506 for (frchainP
= seginfo
->frchainP
; frchainP
!= NULL
;
7507 frchainP
= frchainP
->frch_next
)
7509 subseg_set (s
, frchainP
->frch_subseg
);
7511 if (subseg_text_p (now_seg
))
7514 frag_var (rs_machine_dependent
, 2, /* Max size. */
7515 0, /* VAR is un-used. */ 0, NULL
, 0, NULL
);
7516 fragP
->tc_frag_data
.flag
|= NDS32_FRAG_FINAL
;
7525 nds32_elf_insert_final_frag ();
7526 nds32_elf_analysis_relax_hint ();
7527 bfd_map_over_sections (stdoutput
, nds32_insert_leb128_fixes
, NULL
);
7530 /* Implement md_allow_local_subtract. */
7533 nds32_allow_local_subtract (expressionS
*expr_l ATTRIBUTE_UNUSED
,
7534 expressionS
*expr_r ATTRIBUTE_UNUSED
,
7535 segT sec ATTRIBUTE_UNUSED
)
7537 /* Don't allow any subtraction, because relax may change the code. */
7541 /* Sort relocation by address.
7543 We didn't use qsort () in stdlib, because quick-sort is not a stable
7544 sorting algorithm. Relocations at the same address (r_offset) must keep
7545 their relative order. For example, RELAX_ENTRY must be the very first
7548 Currently, this function implements insertion-sort. */
7551 compar_relent (const void *lhs
, const void *rhs
)
7553 const arelent
**l
= (const arelent
**) lhs
;
7554 const arelent
**r
= (const arelent
**) rhs
;
7556 if ((*l
)->address
> (*r
)->address
)
7558 else if ((*l
)->address
== (*r
)->address
)
7564 /* SET_SECTION_RELOCS ()
7566 Although this macro is originally used to set a relocation for each section,
7567 we use it to sort relocations in the same section by the address of the
7571 nds32_set_section_relocs (asection
*sec ATTRIBUTE_UNUSED
,
7572 arelent
**relocs
, unsigned int n
)
7577 nds32_insertion_sort (relocs
, n
, sizeof (*relocs
), compar_relent
);
7581 nds32_pcrel_from_section (fixS
*fixP
, segT sec ATTRIBUTE_UNUSED
)
7583 if (fixP
->fx_addsy
== NULL
|| !S_IS_DEFINED (fixP
->fx_addsy
)
7584 || S_IS_EXTERNAL (fixP
->fx_addsy
) || S_IS_WEAK (fixP
->fx_addsy
))
7586 /* Let linker resolve undefined symbols. */
7590 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
7593 /* md_post_relax_hook ()
7594 Insert relax entry relocation into sections. */
7597 nds32_post_relax_hook (void)
7599 bfd_map_over_sections (stdoutput
, nds32_insert_relax_entry
, NULL
);
7602 /* tc_fix_adjustable ()
7604 Return whether this symbol (fixup) can be replaced with
7608 nds32_fix_adjustable (fixS
*fixP
)
7610 switch (fixP
->fx_r_type
)
7612 case BFD_RELOC_NDS32_WORD_9_PCREL
:
7613 case BFD_RELOC_NDS32_9_PCREL
:
7614 case BFD_RELOC_NDS32_15_PCREL
:
7615 case BFD_RELOC_NDS32_17_PCREL
:
7616 case BFD_RELOC_NDS32_25_PCREL
:
7617 case BFD_RELOC_NDS32_HI20
:
7618 case BFD_RELOC_NDS32_LO12S0
:
7622 case BFD_RELOC_NDS32_PTR
:
7623 case BFD_RELOC_NDS32_LONGCALL4
:
7624 case BFD_RELOC_NDS32_LONGCALL5
:
7625 case BFD_RELOC_NDS32_LONGCALL6
:
7626 case BFD_RELOC_NDS32_LONGJUMP4
:
7627 case BFD_RELOC_NDS32_LONGJUMP5
:
7628 case BFD_RELOC_NDS32_LONGJUMP6
:
7629 case BFD_RELOC_NDS32_LONGJUMP7
:
7636 /* elf_tc_final_processing */
7639 elf_nds32_final_processing (void)
7641 /* An FPU_COM instruction is found without previous non-FPU_COM
7644 && !(nds32_elf_flags
& (E_NDS32_HAS_FPU_INST
| E_NDS32_HAS_FPU_DP_INST
)))
7646 /* Since only FPU_COM instructions are used and no other FPU instructions
7647 are used. The nds32_elf_flags will be decided by the enabled options
7648 by command line or default configuration. */
7649 if (nds32_fpu_dp_ext
|| nds32_fpu_sp_ext
)
7651 nds32_elf_flags
|= nds32_fpu_dp_ext
? E_NDS32_HAS_FPU_DP_INST
: 0;
7652 nds32_elf_flags
|= nds32_fpu_sp_ext
? E_NDS32_HAS_FPU_INST
: 0;
7656 /* Should never here. */
7657 as_bad (_("Used FPU instructions requires enabling FPU extension"));
7661 if (nds32_elf_flags
& (E_NDS32_HAS_FPU_INST
| E_NDS32_HAS_FPU_DP_INST
))
7663 /* Single/double FPU has been used, set FPU register config. */
7664 /* We did not check the actual number of register used. We may
7665 want to do it while assemble. */
7666 nds32_elf_flags
&= ~E_NDS32_FPU_REG_CONF
;
7667 nds32_elf_flags
|= (nds32_freg
<< E_NDS32_FPU_REG_CONF_SHIFT
);
7671 nds32_elf_flags
|= E_NDS32_HAS_PIC
;
7674 nds32_elf_flags
|= E_NDS32_HAS_REDUCED_REGS
;
7676 nds32_elf_flags
|= (E_NDS32_ELF_VER_1_4
| nds32_abi
);
7677 elf_elfheader (stdoutput
)->e_flags
|= nds32_elf_flags
;
7680 /* Implement md_apply_fix. Apply the fix-up or transform the fix-up for
7681 later relocation generation. */
7684 nds32_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
7686 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
7687 bfd_vma value
= *valP
;
7689 if (fixP
->fx_r_type
< BFD_RELOC_UNUSED
7690 && fixP
->fx_r_type
> BFD_RELOC_NONE
7691 && fixP
->fx_r_type
!= BFD_RELOC_NDS32_DIFF_ULEB128
)
7693 /* In our old nds32 binutils, it must convert relocations which is
7694 generated by CGEN. However, it does not have to consider this anymore.
7695 In current, it only deal with data relocations which enum
7696 is smaller than BFD_RELOC_NONE and BFD_RELOC_NDS32_DIFF_ULEB128.
7697 It is believed that we can construct a better mechanism to
7698 deal with the whole relocation issue in nds32 target
7699 without using CGEN. */
7700 fixP
->fx_addnumber
= value
;
7701 fixP
->tc_fix_data
= NULL
;
7703 /* Transform specific relocations here for later relocation generation.
7704 Tag tls data for linker. */
7705 switch (fixP
->fx_r_type
)
7707 case BFD_RELOC_NDS32_DATA
:
7708 /* This reloc is obselete, we do not need it so far. */
7711 case BFD_RELOC_NDS32_TPOFF
:
7712 case BFD_RELOC_NDS32_TLS_LE_HI20
:
7713 case BFD_RELOC_NDS32_TLS_LE_LO12
:
7714 case BFD_RELOC_NDS32_TLS_LE_ADD
:
7715 case BFD_RELOC_NDS32_TLS_LE_LS
:
7716 case BFD_RELOC_NDS32_GOTTPOFF
:
7717 case BFD_RELOC_NDS32_TLS_IE_HI20
:
7718 case BFD_RELOC_NDS32_TLS_IE_LO12S2
:
7719 case BFD_RELOC_NDS32_TLS_DESC_HI20
:
7720 case BFD_RELOC_NDS32_TLS_DESC_LO12
:
7721 case BFD_RELOC_NDS32_TLS_IE_LO12
:
7722 case BFD_RELOC_NDS32_TLS_IEGP_HI20
:
7723 case BFD_RELOC_NDS32_TLS_IEGP_LO12
:
7724 case BFD_RELOC_NDS32_TLS_IEGP_LO12S2
:
7725 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
7733 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
7736 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
7738 /* HOW DIFF RELOCATION WORKS.
7740 First of all, this relocation is used to calculate the distance
7741 between two symbols in the SAME section. It is used for jump-
7742 table, debug information, exception table, et al. Therefore,
7743 it is a unsigned positive value. It is NOT used for general-
7746 Consider this example, the distance between .LEND and .LBEGIN
7747 is stored at the address of foo.
7749 ---- >8 ---- >8 ---- >8 ---- >8 ----
7752 .word .LBEGIN - .LEND
7762 ---- 8< ---- 8< ---- 8< ---- 8< ----
7764 We use a single relocation entry for this expression.
7765 * The initial distance value is stored directly in that location
7766 specified by r_offset (i.e., foo in this example.)
7767 * The begin of the region, i.e., .LBEGIN, is specified by
7768 r_info/R_SYM and r_addend, e.g., .text + 0x32.
7769 * The end of region, i.e., .LEND, is represented by
7770 .LBEGIN + distance instead of .LEND, so we only need
7771 a single relocation entry instead of two.
7773 When an instruction is relaxed, we adjust the relocation entry
7774 depending on where the instruction locates. There are three
7775 cases, before, after and between the region.
7776 * between: Distance value is read from r_offset, adjusted and
7777 written back into r_offset.
7778 * before: Only r_addend is adjust.
7779 * after: We don't care about it.
7781 Hereby, there are some limitation.
7783 `(.LEND - 1) - .LBEGIN' and `(.LEND - .LBEGIN) - 1'
7784 are semantically different, and we cannot handle latter case
7787 The latter expression means subtracting 1 from the distance
7788 between .LEND and .LBEGIN. And the former expression means
7789 the distance between (.LEND - 1) and .LBEGIN.
7791 The nuance affects whether to adjust distance value when relax
7792 an instruction. In another words, whether the instruction
7793 locates in the region. Because we use a single relocation entry,
7794 there is no field left for .LEND and the subtrahend.
7796 Since GCC-4.5, GCC may produce debug information in such expression
7798 in order to describe register clobbering during an function-call.
7803 Check http://gcc.gnu.org/ml/gcc-patches/2009-06/msg01317.html
7806 value
-= S_GET_VALUE (fixP
->fx_subsy
);
7808 fixP
->fx_subsy
= NULL
;
7809 fixP
->fx_offset
-= value
;
7811 switch (fixP
->fx_r_type
)
7814 fixP
->fx_r_type
= BFD_RELOC_NDS32_DIFF8
;
7815 md_number_to_chars (where
, value
, 1);
7818 fixP
->fx_r_type
= BFD_RELOC_NDS32_DIFF16
;
7819 md_number_to_chars (where
, value
, 2);
7822 fixP
->fx_r_type
= BFD_RELOC_NDS32_DIFF32
;
7823 md_number_to_chars (where
, value
, 4);
7825 case BFD_RELOC_NDS32_DIFF_ULEB128
:
7826 /* cvt_frag_to_fill () has called output_leb128 () for us. */
7829 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7830 _("expression too complex"));
7834 else if (fixP
->fx_done
)
7836 /* We're finished with this fixup. Install it because
7837 bfd_install_relocation won't be called to do it. */
7838 switch (fixP
->fx_r_type
)
7841 md_number_to_chars (where
, value
, 1);
7844 md_number_to_chars (where
, value
, 2);
7847 md_number_to_chars (where
, value
, 4);
7850 md_number_to_chars (where
, value
, 8);
7853 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7854 _("Internal error: Unknown fixup type %d (`%s')"),
7856 bfd_get_reloc_code_name (fixP
->fx_r_type
));
7862 /* Implement tc_gen_reloc. Generate ELF relocation for a fix-up. */
7865 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixP
)
7868 bfd_reloc_code_real_type code
;
7870 reloc
= XNEW (arelent
);
7872 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
7873 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
7874 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
7876 code
= fixP
->fx_r_type
;
7878 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
7879 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
7881 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7882 _("internal error: can't export reloc type %d (`%s')"),
7883 fixP
->fx_r_type
, bfd_get_reloc_code_name (code
));
7887 /* Add relocation handling here. */
7889 switch (fixP
->fx_r_type
)
7892 /* In general, addend of a relocation is the offset to the
7893 associated symbol. */
7894 reloc
->addend
= fixP
->fx_offset
;
7897 case BFD_RELOC_NDS32_DATA
:
7898 /* Prevent linker from optimizing data in text sections.
7899 For example, jump table. */
7900 reloc
->addend
= fixP
->fx_size
;
7907 static struct suffix_name suffix_table
[] =
7909 {"GOTOFF", BFD_RELOC_NDS32_GOTOFF
},
7910 {"GOT", BFD_RELOC_NDS32_GOT20
},
7911 {"TPOFF", BFD_RELOC_NDS32_TPOFF
},
7912 {"PLT", BFD_RELOC_NDS32_25_PLTREL
},
7913 {"GOTTPOFF", BFD_RELOC_NDS32_GOTTPOFF
},
7914 {"TLSDESC", BFD_RELOC_NDS32_TLS_DESC
},
7917 /* Implement md_parse_name. */
7920 nds32_parse_name (char const *name
, expressionS
*exprP
,
7921 enum expr_mode mode ATTRIBUTE_UNUSED
,
7922 char *nextcharP ATTRIBUTE_UNUSED
)
7926 exprP
->X_op_symbol
= NULL
;
7927 exprP
->X_md
= BFD_RELOC_UNUSED
;
7929 exprP
->X_add_symbol
= symbol_find_or_make (name
);
7930 exprP
->X_op
= O_symbol
;
7931 exprP
->X_add_number
= 0;
7933 /* Check the special name if a symbol. */
7934 segment
= S_GET_SEGMENT (exprP
->X_add_symbol
);
7935 if ((segment
!= undefined_section
) && (*nextcharP
!= '@'))
7938 if (strcmp (name
, GOT_NAME
) == 0 && *nextcharP
!= '@')
7940 /* Set for _GOT_OFFSET_TABLE_. */
7941 exprP
->X_md
= BFD_RELOC_NDS32_GOTPC20
;
7943 else if (*nextcharP
== '@')
7947 for (i
= 0; i
< ARRAY_SIZE (suffix_table
); i
++)
7949 next
= input_line_pointer
+ 1 + strlen (suffix_table
[i
].suffix
);
7950 if (strncasecmp (input_line_pointer
+ 1, suffix_table
[i
].suffix
,
7951 strlen (suffix_table
[i
].suffix
)) == 0
7952 && !is_part_of_name (*next
))
7954 exprP
->X_md
= suffix_table
[i
].reloc
;
7955 *input_line_pointer
= *nextcharP
;
7956 input_line_pointer
= next
;
7957 *nextcharP
= *input_line_pointer
;
7958 *input_line_pointer
= '\0';
7967 /* Implement tc_regname_to_dw2regnum. */
7970 tc_nds32_regname_to_dw2regnum (char *regname
)
7972 struct nds32_keyword
*sym
= str_hash_find (nds32_gprs_hash
, regname
);
7981 tc_nds32_frame_initial_instructions (void)
7984 /* Default cfa is register-31/sp. */
7985 cfi_add_CFA_def_cfa (31, 0);