1 /* tc-nds32.c -- Assemble for the nds32
2 Copyright (C) 2012-2019 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 struct hash_control
*nds32_gprs_hash
;
86 static struct hash_control
*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 struct hash_control
*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 struct hash_control
*nds32_pseudo_opcode_hash
= NULL
;
2575 builtin_isreg (const char *s
, const char *x ATTRIBUTE_UNUSED
)
2577 if (s
[0] == '$' && 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
= 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
= nds32_pseudo_opcode_table
;
3437 nds32_pseudo_opcode_hash
= hash_new ();
3438 for ( ; opcode
->opcode
; opcode
++)
3442 op
= hash_find (nds32_pseudo_opcode_hash
, opcode
->opcode
);
3445 as_warn (_("Duplicated pseudo-opcode %s."), opcode
->opcode
);
3448 hash_insert (nds32_pseudo_opcode_hash
, opcode
->opcode
, opcode
);
3452 static struct nds32_pseudo_opcode
*
3453 nds32_lookup_pseudo_opcode (const char *str
)
3455 struct nds32_pseudo_opcode
*result
;
3458 /* (*op) is the first word of current source line (*str) */
3459 int maxlen
= strlen (str
);
3460 char *op
= xmalloc (maxlen
+ 1);
3462 for (i
= 0; i
< maxlen
; i
++)
3464 if (ISSPACE (op
[i
] = str
[i
]))
3469 result
= hash_find (nds32_pseudo_opcode_hash
, op
);
3475 nds32_pseudo_opcode_wrapper (char *line
, struct nds32_pseudo_opcode
*opcode
)
3478 char *argv
[8] = {NULL
};
3480 char *str
= xstrdup (line
);
3482 /* Parse arguments for opcode. */
3483 s
= str
+ strlen (opcode
->opcode
);
3488 /* Dummy comma to ease separate arguments as below. */
3494 if (argc
>= opcode
->argc
3495 || (argc
>= (int)ARRAY_SIZE (argv
) - 1))
3496 as_bad (_("Too many argument. `%s'"), line
);
3503 } while (s
[0] != '\0');
3505 /* Put the origin line for debugging. */
3507 opcode
->proc (argc
, argv
, opcode
->pseudo_val
);
3511 /* This function will be invoked from function `nds32_after_parse_args'.
3512 Thus, if the value of option has been set, keep the value the way it is. */
3515 nds32_parse_arch (const char *str
)
3517 static const struct nds32_arch
3528 {"v3m", ISA_V3M
, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_AABI
},
3529 {"v3j", ISA_V3
, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_AABI
},
3530 {"v3s", ISA_V3
, 0, 1, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_V2FP_PLUS
},
3531 {"v3f", ISA_V3
, 0, 1, 1, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_V2FP_PLUS
},
3532 {"v3", ISA_V3
, 0, 0, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_AABI
},
3533 {"v2j", ISA_V2
, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_AABI
},
3534 {"v2s", ISA_V2
, 0, 1, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_V2FP_PLUS
},
3535 {"v2f", ISA_V2
, 0, 1, 1, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_V2FP_PLUS
},
3536 {"v2", ISA_V2
, 0, 0, 0, E_NDS32_FPU_REG_32SP_16DP
, E_NDS_ABI_AABI
},
3540 for (i
= 0; i
< ARRAY_SIZE (archs
); i
++)
3542 if (strcmp (str
, archs
[i
].name
) != 0)
3545 /* The value `-1' represents this option has *NOT* been set. */
3546 nds32_baseline
= (-1 != nds32_baseline
) ? nds32_baseline
: archs
[i
].baseline
;
3547 nds32_gpr16
= (-1 != nds32_gpr16
) ? nds32_gpr16
: archs
[i
].reduced_reg
;
3548 nds32_fpu_sp_ext
= (-1 != nds32_fpu_sp_ext
) ? nds32_fpu_sp_ext
: archs
[i
].fpu_sp_ext
;
3549 nds32_fpu_dp_ext
= (-1 != nds32_fpu_dp_ext
) ? nds32_fpu_dp_ext
: archs
[i
].fpu_dp_ext
;
3550 nds32_freg
= (-1 != nds32_freg
) ? nds32_freg
: archs
[i
].fpu_freg
;
3551 nds32_abi
= (-1 != nds32_abi
) ? nds32_abi
: archs
[i
].abi
;
3556 /* Logic here rejects the input arch name. */
3557 as_bad (_("unknown arch name `%s'\n"), str
);
3562 /* This function parses "baseline" specified. */
3565 nds32_parse_baseline (const char *str
)
3567 if (strcmp (str
, "v3") == 0)
3568 nds32_baseline
= ISA_V3
;
3569 else if (strcmp (str
, "v3m") == 0)
3570 nds32_baseline
= ISA_V3M
;
3571 else if (strcmp (str
, "v2") == 0)
3572 nds32_baseline
= ISA_V2
;
3575 /* Logic here rejects the input baseline. */
3576 as_bad (_("unknown baseline `%s'\n"), str
);
3583 /* This function parses "fpu-freg" specified. */
3586 nds32_parse_freg (const char *str
)
3588 if (strcmp (str
, "2") == 0)
3589 nds32_freg
= E_NDS32_FPU_REG_32SP_16DP
;
3590 else if (strcmp (str
, "3") == 0)
3591 nds32_freg
= E_NDS32_FPU_REG_32SP_32DP
;
3592 else if (strcmp (str
, "1") == 0)
3593 nds32_freg
= E_NDS32_FPU_REG_16SP_8DP
;
3594 else if (strcmp (str
, "0") == 0)
3595 nds32_freg
= E_NDS32_FPU_REG_8SP_4DP
;
3598 /* Logic here rejects the input FPU configuration. */
3599 as_bad (_("unknown FPU configuration `%s'\n"), str
);
3606 /* This function parse "abi=" specified. */
3609 nds32_parse_abi (const char *str
)
3611 if (strcmp (str
, "v2") == 0)
3612 nds32_abi
= E_NDS_ABI_AABI
;
3614 else if (strcmp (str
, "v2fp") == 0)
3615 nds32_abi
= E_NDS_ABI_V2FP
;
3616 else if (strcmp (str
, "v1") == 0)
3617 nds32_abi
= E_NDS_ABI_V1
;
3618 else if (strcmp (str
,"v2fpp") == 0)
3619 nds32_abi
= E_NDS_ABI_V2FP_PLUS
;
3622 /* Logic here rejects the input abi version. */
3623 as_bad (_("unknown ABI version`%s'\n"), str
);
3630 /* This function turn on all extensions and instructions support. */
3633 nds32_all_ext (void)
3638 nds32_16bit_ext
= 1;
3640 nds32_perf_ext2
= 1;
3641 nds32_string_ext
= 1;
3642 nds32_audio_ext
= 1;
3644 nds32_fpu_sp_ext
= 1;
3645 nds32_fpu_dp_ext
= 1;
3648 /* Turn off reduced register. */
3654 /* GAS will call md_parse_option whenever getopt returns an unrecognized code,
3655 presumably indicating a special code value which appears in md_longopts.
3656 This function should return non-zero if it handled the option and zero
3657 otherwise. There is no need to print a message about an option not being
3658 recognized. This will be handled by the generic code. */
3661 nds32_parse_option (int c
, const char *arg
)
3663 struct nds32_parse_option_table
*coarse_tune
;
3664 struct nds32_set_option_table
*fine_tune
;
3665 const char *ptr_arg
= NULL
;
3669 case OPTION_OPTIMIZE
:
3671 optimize_for_space
= 0;
3673 case OPTION_OPTIMIZE_SPACE
:
3675 optimize_for_space
= 1;
3678 target_big_endian
= 1;
3681 target_big_endian
= 0;
3689 case OPTION_RELAX_FP_AS_GP_OFF
:
3690 nds32_relax_fp_as_gp
= 0;
3692 case OPTION_RELAX_B2BB_ON
:
3693 nds32_relax_b2bb
= 1;
3695 case OPTION_RELAX_ALL_OFF
:
3696 nds32_relax_all
= 0;
3699 /* Determination of which option table to search for to save time. */
3703 ptr_arg
= strchr (arg
, '=');
3707 /* Find the value after '='. */
3708 if (ptr_arg
!= NULL
)
3710 for (coarse_tune
= parse_opts
; coarse_tune
->name
!= NULL
; coarse_tune
++)
3712 if (strncmp (arg
, coarse_tune
->name
, (ptr_arg
- arg
)) == 0)
3714 coarse_tune
->func (ptr_arg
);
3723 /* Filter out the Disable option first. */
3724 if (strncmp (arg
, "no-", 3) == 0)
3730 for (fine_tune
= toggle_opts
; fine_tune
->name
!= NULL
; fine_tune
++)
3732 if (strcmp (arg
, fine_tune
->name
) == 0)
3734 if (fine_tune
->var
!= NULL
)
3735 *fine_tune
->var
= (disable
) ? 0 : 1;
3740 /* Nothing match. */
3747 /* tc_check_label */
3750 nds32_check_label (symbolS
*label ATTRIBUTE_UNUSED
)
3752 /* The code used to create BB is move to frob_label.
3753 They should go there. */
3757 set_endian_little (int on
)
3759 target_big_endian
= !on
;
3762 /* These functions toggles the generation of 16-bit. First encounter signals
3763 the beginning of not generating 16-bit instructions and next encounter
3764 signals the restoring back to default behavior. */
3767 trigger_16bit (int trigger
)
3769 enable_16bit
= trigger
;
3772 static int backup_16bit_mode
;
3774 restore_16bit (int no_use ATTRIBUTE_UNUSED
)
3776 enable_16bit
= backup_16bit_mode
;
3780 off_16bit (int no_use ATTRIBUTE_UNUSED
)
3782 backup_16bit_mode
= enable_16bit
;
3786 /* Built-in segments for small object. */
3787 typedef struct nds32_seg_entryT
3794 nds32_seg_entry nds32_seg_table
[] =
3796 {NULL
, ".sdata_f", SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
3797 | SEC_HAS_CONTENTS
| SEC_SMALL_DATA
},
3798 {NULL
, ".sdata_b", SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
3799 | SEC_HAS_CONTENTS
| SEC_SMALL_DATA
},
3800 {NULL
, ".sdata_h", SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
3801 | SEC_HAS_CONTENTS
| SEC_SMALL_DATA
},
3802 {NULL
, ".sdata_w", SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
3803 | SEC_HAS_CONTENTS
| SEC_SMALL_DATA
},
3804 {NULL
, ".sdata_d", SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
| SEC_DATA
3805 | SEC_HAS_CONTENTS
| SEC_SMALL_DATA
},
3806 {NULL
, ".sbss_f", SEC_ALLOC
| SEC_SMALL_DATA
},
3807 {NULL
, ".sbss_b", SEC_ALLOC
| SEC_SMALL_DATA
},
3808 {NULL
, ".sbss_h", SEC_ALLOC
| SEC_SMALL_DATA
},
3809 {NULL
, ".sbss_w", SEC_ALLOC
| SEC_SMALL_DATA
},
3810 {NULL
, ".sbss_d", SEC_ALLOC
| SEC_SMALL_DATA
}
3813 /* Indexes to nds32_seg_table[]. */
3814 enum NDS32_SECTIONS_ENUM
3816 SDATA_F_SECTION
= 0,
3817 SDATA_B_SECTION
= 1,
3818 SDATA_H_SECTION
= 2,
3819 SDATA_W_SECTION
= 3,
3820 SDATA_D_SECTION
= 4,
3828 /* The following code is borrowed from v850_seg. Revise this is needed. */
3831 do_nds32_seg (int i
, subsegT sub
)
3833 nds32_seg_entry
*seg
= nds32_seg_table
+ i
;
3835 obj_elf_section_change_hook ();
3838 subseg_set (seg
->s
, sub
);
3841 seg
->s
= subseg_new (seg
->name
, sub
);
3842 if (OUTPUT_FLAVOR
== bfd_target_elf_flavour
)
3844 bfd_set_section_flags (stdoutput
, seg
->s
, seg
->flags
);
3845 if ((seg
->flags
& SEC_LOAD
) == 0)
3846 seg_info (seg
->s
)->bss
= 1;
3854 subsegT sub
= get_absolute_expression ();
3856 do_nds32_seg (i
, sub
);
3857 demand_empty_rest_of_line ();
3860 /* Set if label adjustment is needed. I should not adjust .xbyte in dwarf. */
3861 static symbolS
*nds32_last_label
; /* Last label for alignment. */
3864 add_mapping_symbol_for_align (int shift
, valueT addr
, int is_data_align
)
3866 if ((shift
> 1) && (addr
& 1))
3868 int n
= (1 << shift
) - 1;
3870 add_mapping_symbol (MAP_CODE
, 1, 0);
3871 else if ((int) (addr
& n
) != n
)
3872 add_mapping_symbol (MAP_CODE
, 1, 0);
3874 else if ((shift
> 1) && ((int) (addr
& 1) == 0))
3875 add_mapping_symbol (MAP_CODE
, 0, 0);
3878 /* This code is referred from D30V for adjust label to be with pending
3879 alignment. For example,
3883 Without this, the above label will not attach to incoming data. */
3886 nds32_adjust_label (int n
)
3888 /* FIXME: I think adjust label and alignment is
3889 the programmer's obligation. Sadly, VLSI team doesn't
3890 properly use .align for their test cases.
3891 So I re-implement cons_align and auto adjust labels, again.
3893 I think d30v's implementation is simple and good enough. */
3895 symbolS
*label
= nds32_last_label
;
3896 nds32_last_label
= NULL
;
3898 /* SEC_ALLOC is used to eliminate .debug_ sections.
3899 SEC_CODE is used to include section for ILM. */
3900 if (((now_seg
->flags
& SEC_ALLOC
) == 0 && (now_seg
->flags
& SEC_CODE
) == 0)
3901 || strcmp (now_seg
->name
, ".eh_frame") == 0
3902 || strcmp (now_seg
->name
, ".gcc_except_table") == 0)
3905 /* Only frag by alignment when needed.
3906 Otherwise, it will fail to optimize labels on 4-byte boundary. (bug8454)
3907 See md_convert_frag () and RELAX_SET_RELAXABLE (frag) for details. */
3908 if (frag_now_fix () & ((1 << n
) -1 ))
3910 if (subseg_text_p (now_seg
))
3912 add_mapping_symbol_for_align (n
, frag_now_fix (), 1);
3913 frag_align_code (n
, 0);
3916 frag_align (n
, 0, 0);
3918 /* Record the minimum alignment for this segment. */
3919 record_alignment (now_seg
, n
- OCTETS_PER_BYTE_POWER
);
3925 int label_seen
= FALSE
;
3926 struct frag
*old_frag
;
3927 valueT old_value
, new_value
;
3929 gas_assert (S_GET_SEGMENT (label
) == now_seg
);
3931 old_frag
= symbol_get_frag (label
);
3932 old_value
= S_GET_VALUE (label
);
3933 new_value
= (valueT
) frag_now_fix ();
3935 /* Multiple labels may be on the same address. And the last symbol
3936 may not be a label at all, e.g., register name, external function names,
3937 so I have to track the last label in tc_frob_label instead of
3938 just using symbol_lastP. */
3939 for (sym
= symbol_lastP
; sym
!= NULL
; sym
= symbol_previous (sym
))
3941 if (symbol_get_frag (sym
) == old_frag
3942 && S_GET_VALUE (sym
) == old_value
)
3946 symbol_set_frag (sym
, frag_now
);
3947 S_SET_VALUE (sym
, new_value
);
3949 else if (label_seen
&& symbol_get_frag (sym
) != old_frag
)
3956 nds32_cons_align (int size ATTRIBUTE_UNUSED
)
3959 This is called before `md_flush_pending_output' is called by `cons'.
3961 There are two things should be done for auto-adjust-label.
3962 1. Align data/instructions and adjust label to be attached to them.
3963 2. Clear auto-adjust state, so incoming data/instructions will not
3971 in this case, '.word 0x2' will adjust the label, .L0, but '.word 0x3' should not.
3973 I think `md_flush_pending_output' is a good place to clear the auto-adjust state,
3974 but it is also called by `cons' before this function.
3975 To simplify the code, instead of overriding .zero, .fill, .space, etc,
3976 I think we should just adjust label in `nds32_aligned_X_cons' instead of here. */
3980 make_mapping_symbol (enum mstate state
, valueT value
, fragS
* frag
, unsigned int align
)
3982 symbolS
*symbol_p
= NULL
;
3983 const char *symbol_name
= NULL
;
3988 symbol_name
= "$d0";
3989 else if (align
== 1)
3990 symbol_name
= "$d1";
3991 else if (align
== 2)
3992 symbol_name
= "$d2";
3993 else if (align
== 3)
3994 symbol_name
= "$d3";
3995 else if (align
== 4)
3996 symbol_name
= "$d4";
4005 symbol_p
= symbol_new (symbol_name
, now_seg
, value
, frag
);
4006 /* local scope attribute */
4007 symbol_get_bfdsym (symbol_p
)->flags
|= BSF_NO_FLAGS
| BSF_LOCAL
;
4011 add_mapping_symbol (enum mstate state
, unsigned int padding_byte
,
4014 enum mstate current_mapping_state
=
4015 seg_info (now_seg
)->tc_segment_info_data
.mapstate
;
4017 if (state
== MAP_CODE
4018 && current_mapping_state
== state
)
4021 if (!SEG_NORMAL (now_seg
)
4022 || !subseg_text_p (now_seg
))
4025 /* start adding mapping symbol */
4026 seg_info (now_seg
)->tc_segment_info_data
.mapstate
= state
;
4027 make_mapping_symbol (state
, (valueT
) frag_now_fix () + padding_byte
,
4032 nds32_aligned_cons (int idx
)
4034 nds32_adjust_label (idx
);
4035 add_mapping_symbol (MAP_DATA
, 0, idx
);
4036 /* Call default handler. */
4038 if (now_seg
->flags
& SEC_CODE
4039 && now_seg
->flags
& SEC_ALLOC
&& now_seg
->flags
& SEC_RELOC
)
4041 /* Use BFD_RELOC_NDS32_DATA to avoid linker
4042 optimization replacing data. */
4045 exp
.X_add_number
= 0;
4046 exp
.X_op
= O_constant
;
4047 fix_new_exp (frag_now
, frag_now_fix () - (1 << idx
), 1 << idx
,
4048 &exp
, 0, BFD_RELOC_NDS32_DATA
);
4052 /* `.double' directive. */
4055 nds32_aligned_float_cons (int type
)
4063 nds32_adjust_label (2);
4069 nds32_adjust_label (4);
4072 as_bad ("Unrecognized float type, %c\n", (char)type
);
4074 /* Call default handler. */
4079 nds32_enable_pic (int ignore ATTRIBUTE_UNUSED
)
4081 /* Another way to do -mpic.
4082 This is for GCC internal use and should always be first line
4083 of code, otherwise, the effect is not determined. */
4088 nds32_set_abi (int ver
)
4093 /* Relax directive to set relocation R_NDS32_RELAX_ENTRY value. */
4096 nds32_relax_relocs (int relax
)
4101 const char *subtype_relax
[] =
4104 name
= input_line_pointer
;
4105 while (*input_line_pointer
&& !ISSPACE (*input_line_pointer
))
4106 input_line_pointer
++;
4107 saved_char
= *input_line_pointer
;
4108 *input_line_pointer
= 0;
4110 for (i
= 0; i
< (int) ARRAY_SIZE (subtype_relax
); i
++)
4112 if (strcmp (name
, subtype_relax
[i
]) == 0)
4118 enable_relax_relocs
= relax
& enable_relax_relocs
;
4126 *input_line_pointer
= saved_char
;
4127 ignore_rest_of_line ();
4130 /* Record which arguments register($r0 ~ $r5) is not used in callee.
4134 nds32_set_hint_func_args (int ignore ATTRIBUTE_UNUSED
)
4136 ignore_rest_of_line ();
4139 /* Insert relocations to mark the begin and end of a fp-omitted function,
4140 for further relaxation use.
4144 nds32_omit_fp_begin (int mode
)
4148 if (nds32_relax_fp_as_gp
== 0)
4150 exp
.X_op
= O_symbol
;
4151 exp
.X_add_symbol
= abs_section_sym
;
4155 exp
.X_add_number
= R_NDS32_RELAX_REGION_OMIT_FP_FLAG
;
4156 fix_new_exp (frag_now
, frag_now_fix (), 0, &exp
, 0,
4157 BFD_RELOC_NDS32_RELAX_REGION_BEGIN
);
4162 exp
.X_add_number
= R_NDS32_RELAX_REGION_OMIT_FP_FLAG
;
4163 fix_new_exp (frag_now
, frag_now_fix (), 0, &exp
, 0,
4164 BFD_RELOC_NDS32_RELAX_REGION_END
);
4169 nds32_loop_begin (int mode
)
4171 /* Insert loop region relocation here. */
4174 exp
.X_op
= O_symbol
;
4175 exp
.X_add_symbol
= abs_section_sym
;
4178 exp
.X_add_number
= R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG
;
4179 fix_new_exp (frag_now
, frag_now_fix (), 0, &exp
, 0,
4180 BFD_RELOC_NDS32_RELAX_REGION_BEGIN
);
4184 exp
.X_add_number
= R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG
;
4185 fix_new_exp (frag_now
, frag_now_fix (), 0, &exp
, 0,
4186 BFD_RELOC_NDS32_RELAX_REGION_END
);
4190 struct nds32_relocs_group
4192 struct nds32_relocs_pattern
*pattern
;
4193 struct nds32_relocs_group
*next
;
4196 static struct nds32_relocs_group
*nds32_relax_hint_current
= NULL
;
4197 /* Used to reorder the id for ".relax_hint id". */
4198 static int relax_hint_bias
= 0;
4199 /* Record current relax hint id. */
4200 static int relax_hint_id_current
= -1;
4202 /* If ".relax_hint begin" is triggered? */
4203 int relax_hint_begin
= 0;
4205 /* Record the reordered relax hint id. */
4207 struct relax_hint_id
4211 struct relax_hint_id
*next
;
4214 /* FIXME: Need to find somewhere to free the list. */
4215 struct relax_hint_id
*record_id_head
= NULL
;
4217 /* Is the buffer large enough? */
4218 #define MAX_BUFFER 12
4220 static char *nds_itoa (int n
);
4225 char *buf
= xmalloc (MAX_BUFFER
* sizeof (char));
4226 snprintf (buf
, MAX_BUFFER
, "%d", n
);
4230 /* Insert a relax hint. */
4233 nds32_relax_hint (int mode ATTRIBUTE_UNUSED
)
4237 struct nds32_relocs_pattern
*relocs
= NULL
;
4238 struct nds32_relocs_group
*group
, *new;
4239 struct relax_hint_id
*record_id
;
4241 name
= input_line_pointer
;
4242 while (*input_line_pointer
&& !ISSPACE (*input_line_pointer
))
4243 input_line_pointer
++;
4244 saved_char
= *input_line_pointer
;
4245 *input_line_pointer
= 0;
4246 name
= strdup (name
);
4248 if (name
&& strcmp (name
, "begin") == 0)
4250 if (relax_hint_id_current
== -1)
4253 relax_hint_id_current
++;
4254 relax_hint_begin
= 1;
4257 /* Original case ".relax_hint id". It's id may need to be reordered. */
4258 if (!relax_hint_begin
)
4260 int tmp
= strtol (name
, NULL
, 10);
4261 record_id
= record_id_head
;
4264 if (record_id
->old_id
== tmp
)
4266 name
= nds_itoa (record_id
->new_id
);
4269 record_id
= record_id
->next
;
4273 relax_hint_bias
= relax_hint_id_current
- atoi (name
) + 1;
4276 relax_hint_id_current
= tmp
+ relax_hint_bias
;
4278 /* Insert the element to the head of the link list. */
4279 struct relax_hint_id
*tmp_id
= malloc (sizeof (struct relax_hint_id
));
4280 tmp_id
->old_id
= tmp
;
4281 tmp_id
->new_id
= relax_hint_id_current
;
4282 tmp_id
->next
= record_id_head
;
4283 record_id_head
= tmp_id
;
4286 if (name
&& strcmp (name
, "end") == 0)
4287 relax_hint_begin
= 0;
4288 name
= nds_itoa (relax_hint_id_current
);
4292 /* Find relax hint entry for next instruction, and all member will be
4293 initialized at that time. */
4294 relocs
= hash_find (nds32_hint_hash
, name
);
4297 relocs
= XNEW (struct nds32_relocs_pattern
);
4298 memset (relocs
, 0, sizeof (struct nds32_relocs_pattern
));
4299 hash_insert (nds32_hint_hash
, name
, relocs
);
4303 while (relocs
->next
)
4304 relocs
=relocs
->next
;
4305 relocs
->next
= XNEW (struct nds32_relocs_pattern
);
4306 relocs
= relocs
->next
;
4307 memset (relocs
, 0, sizeof (struct nds32_relocs_pattern
));
4310 relocs
->next
= NULL
;
4311 *input_line_pointer
= saved_char
;
4312 ignore_rest_of_line ();
4314 /* Get the final one of relax hint series. */
4316 /* It has to build this list because there are maybe more than one
4317 instructions relative to the same instruction. It to connect to
4318 next instruction after md_assemble. */
4319 new = XNEW (struct nds32_relocs_group
);
4320 memset (new, 0, sizeof (struct nds32_relocs_group
));
4321 new->pattern
= relocs
;
4323 group
= nds32_relax_hint_current
;
4325 nds32_relax_hint_current
= new;
4328 while (group
->next
!= NULL
)
4329 group
= group
->next
;
4335 /* Decide the size of vector entries, only accepts 4 or 16 now. */
4338 nds32_vec_size (int ignore ATTRIBUTE_UNUSED
)
4344 if (exp
.X_op
== O_constant
)
4346 if (exp
.X_add_number
== 4 || exp
.X_add_number
== 16)
4349 vec_size
= exp
.X_add_number
;
4350 else if (vec_size
!= exp
.X_add_number
)
4351 as_warn (_("Different arguments of .vec_size are found, "
4352 "previous %d, current %d"),
4353 (int) vec_size
, (int) exp
.X_add_number
);
4356 as_warn (_("Argument of .vec_size is expected 4 or 16, actual: %d."),
4357 (int) exp
.X_add_number
);
4360 as_warn (_("Argument of .vec_size is not a constant."));
4363 /* The behavior of ".flag" directive varies depending on the target.
4364 In nds32 target, we use it to recognize whether this assembly content is
4365 generated by compiler. Other features can also be added in this function
4369 nds32_flag (int ignore ATTRIBUTE_UNUSED
)
4374 const char *possible_flags
[] = { "verbatim" };
4376 /* Skip whitespaces. */
4377 name
= input_line_pointer
;
4378 while (*input_line_pointer
&& !ISSPACE (*input_line_pointer
))
4379 input_line_pointer
++;
4380 saved_char
= *input_line_pointer
;
4381 *input_line_pointer
= 0;
4383 for (i
= 0; i
< (int) ARRAY_SIZE (possible_flags
); i
++)
4385 if (strcmp (name
, possible_flags
[i
]) == 0)
4390 /* flag: verbatim */
4396 /* Already found the flag, no need to continue next loop. */
4401 *input_line_pointer
= saved_char
;
4402 ignore_rest_of_line ();
4406 ict_model (int ignore ATTRIBUTE_UNUSED
)
4411 const char *possible_flags
[] = { "small", "large" };
4413 /* Skip whitespaces. */
4414 name
= input_line_pointer
;
4415 while (*input_line_pointer
&& !ISSPACE (*input_line_pointer
))
4416 input_line_pointer
++;
4417 saved_char
= *input_line_pointer
;
4418 *input_line_pointer
= 0;
4420 for (i
= 0; i
< (int) ARRAY_SIZE (possible_flags
); i
++)
4422 if (strcmp (name
, possible_flags
[i
]) == 0)
4427 /* flag: verbatim */
4428 ict_flag
= ICT_SMALL
;
4431 ict_flag
= ICT_LARGE
;
4436 /* Already found the flag, no need to continue next loop. */
4441 *input_line_pointer
= saved_char
;
4442 ignore_rest_of_line ();
4446 nds32_n12hc (int ignore ATTRIBUTE_UNUSED
)
4448 /* N1213HC core is used. */
4452 /* The target specific pseudo-ops which we support. */
4453 const pseudo_typeS md_pseudo_table
[] =
4455 /* Forced alignment if declared these ways. */
4456 {"ascii", stringer
, 8 + 0},
4457 {"asciz", stringer
, 8 + 1},
4458 {"double", nds32_aligned_float_cons
, 'd'},
4459 {"dword", nds32_aligned_cons
, 3},
4460 {"float", nds32_aligned_float_cons
, 'f'},
4461 {"half", nds32_aligned_cons
, 1},
4462 {"hword", nds32_aligned_cons
, 1},
4463 {"int", nds32_aligned_cons
, 2},
4464 {"long", nds32_aligned_cons
, 2},
4465 {"octa", nds32_aligned_cons
, 4},
4466 {"quad", nds32_aligned_cons
, 3},
4467 {"qword", nds32_aligned_cons
, 4},
4468 {"short", nds32_aligned_cons
, 1},
4469 {"byte", nds32_aligned_cons
, 0},
4470 {"single", nds32_aligned_float_cons
, 'f'},
4471 {"string", stringer
, 8 + 1},
4472 {"word", nds32_aligned_cons
, 2},
4474 {"little", set_endian_little
, 1},
4475 {"big", set_endian_little
, 0},
4476 {"16bit_on", trigger_16bit
, 1},
4477 {"16bit_off", trigger_16bit
, 0},
4478 {"restore_16bit", restore_16bit
, 0},
4479 {"off_16bit", off_16bit
, 0},
4481 {"sdata_d", nds32_seg
, SDATA_D_SECTION
},
4482 {"sdata_w", nds32_seg
, SDATA_W_SECTION
},
4483 {"sdata_h", nds32_seg
, SDATA_H_SECTION
},
4484 {"sdata_b", nds32_seg
, SDATA_B_SECTION
},
4485 {"sdata_f", nds32_seg
, SDATA_F_SECTION
},
4487 {"sbss_d", nds32_seg
, SBSS_D_SECTION
},
4488 {"sbss_w", nds32_seg
, SBSS_W_SECTION
},
4489 {"sbss_h", nds32_seg
, SBSS_H_SECTION
},
4490 {"sbss_b", nds32_seg
, SBSS_B_SECTION
},
4491 {"sbss_f", nds32_seg
, SBSS_F_SECTION
},
4493 {"pic", nds32_enable_pic
, 0},
4494 {"n12_hc", nds32_n12hc
, 0},
4495 {"abi_1", nds32_set_abi
, E_NDS_ABI_V1
},
4496 {"abi_2", nds32_set_abi
, E_NDS_ABI_AABI
},
4498 {"abi_2fp", nds32_set_abi
, E_NDS_ABI_V2FP
},
4499 {"abi_2fp_plus", nds32_set_abi
, E_NDS_ABI_V2FP_PLUS
},
4500 {"relax", nds32_relax_relocs
, 1},
4501 {"no_relax", nds32_relax_relocs
, 0},
4502 {"hint_func_args", nds32_set_hint_func_args
, 0}, /* Abandon?? */
4503 {"omit_fp_begin", nds32_omit_fp_begin
, 1},
4504 {"omit_fp_end", nds32_omit_fp_begin
, 0},
4505 {"vec_size", nds32_vec_size
, 0},
4506 {"flag", nds32_flag
, 0},
4507 {"innermost_loop_begin", nds32_loop_begin
, 1},
4508 {"innermost_loop_end", nds32_loop_begin
, 0},
4509 {"relax_hint", nds32_relax_hint
, 0},
4510 {"ict_model", ict_model
, 0},
4515 nds32_pre_do_align (int n
, char *fill
, int len
, int max
)
4517 /* Only make a frag if we HAVE to... */
4519 if (n
!= 0 && !need_pass_2
)
4523 if (subseg_text_p (now_seg
))
4525 dwarf2_emit_insn (0);
4527 add_mapping_symbol_for_align (n
, frag_now_fix (), 0);
4528 frag_align_code (n
, max
);
4530 /* Tag this alignment when there is a label before it. */
4533 fragP
->tc_frag_data
.flag
= NDS32_FRAG_LABEL
;
4538 frag_align (n
, 0, max
);
4541 frag_align (n
, *fill
, max
);
4543 frag_align_pattern (n
, fill
, len
, max
);
4548 nds32_do_align (int n
)
4550 /* Optimize for space and label exists. */
4553 /* FIXME:I think this will break debug info sections and except_table. */
4554 if (!enable_relax_relocs
|| !subseg_text_p (now_seg
))
4557 /* Create and attach a BFD_RELOC_NDS32_LABEL fixup
4558 the size of instruction may not be correct because
4559 it could be relaxable. */
4560 exp
.X_op
= O_symbol
;
4561 exp
.X_add_symbol
= section_symbol (now_seg
);
4562 exp
.X_add_number
= n
;
4563 fix_new_exp (frag_now
,
4564 frag_now_fix (), 0, &exp
, 0, BFD_RELOC_NDS32_LABEL
);
4567 /* Supported Andes machines. */
4570 enum bfd_architecture bfd_mach
;
4574 /* This is the callback for nds32-asm.c to parse operands. */
4577 nds32_asm_parse_operand (struct nds32_asm_desc
*pdesc ATTRIBUTE_UNUSED
,
4578 struct nds32_asm_insn
*pinsn
,
4579 char **pstr
, int64_t *value
)
4582 expressionS
*pexp
= pinsn
->info
;
4584 hold
= input_line_pointer
;
4585 input_line_pointer
= *pstr
;
4587 *pstr
= input_line_pointer
;
4588 input_line_pointer
= hold
;
4594 return NASM_R_SYMBOL
;
4596 *value
= pexp
->X_add_number
;
4597 return NASM_R_CONST
;
4602 return NASM_R_ILLEGAL
;
4606 /* GAS will call this function at the start of the assembly, after the command
4607 line arguments have been parsed and all the machine independent
4608 initializations have been completed. */
4613 struct nds32_keyword
*k
;
4614 relax_info_t
*relax_info
;
4617 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, nds32_baseline
);
4619 nds32_init_nds32_pseudo_opcodes ();
4620 asm_desc
.parse_operand
= nds32_asm_parse_operand
;
4622 flags
|= NASM_OPEN_REDUCED_REG
;
4623 nds32_asm_init (&asm_desc
, flags
);
4625 /* Initial general purpose registers hash table. */
4626 nds32_gprs_hash
= hash_new ();
4627 for (k
= keyword_gpr
; k
->name
; k
++)
4628 hash_insert (nds32_gprs_hash
, k
->name
, k
);
4630 /* Initial branch hash table. */
4631 nds32_relax_info_hash
= hash_new ();
4632 for (relax_info
= relax_table
; relax_info
->opcode
; relax_info
++)
4633 hash_insert (nds32_relax_info_hash
, relax_info
->opcode
, relax_info
);
4635 /* Initial relax hint hash table. */
4636 nds32_hint_hash
= hash_new ();
4637 enable_16bit
= nds32_16bit_ext
;
4640 /* HANDLE_ALIGN in write.c. */
4643 nds32_handle_align (fragS
*fragp
)
4645 static const unsigned char nop16
[] = { 0x92, 0x00 };
4646 static const unsigned char nop32
[] = { 0x40, 0x00, 0x00, 0x09 };
4650 if (fragp
->fr_type
!= rs_align_code
)
4653 bytes
= fragp
->fr_next
->fr_address
- fragp
->fr_address
- fragp
->fr_fix
;
4654 p
= fragp
->fr_literal
+ fragp
->fr_fix
;
4665 exp_t
.X_op
= O_symbol
;
4666 exp_t
.X_add_symbol
= abs_section_sym
;
4667 exp_t
.X_add_number
= R_NDS32_INSN16_CONVERT_FLAG
;
4668 fix_new_exp (fragp
, fragp
->fr_fix
, 2, &exp_t
, 0,
4669 BFD_RELOC_NDS32_INSN16
);
4670 memcpy (p
, nop16
, 2);
4677 memcpy (p
, nop32
, 4);
4682 bytes
= fragp
->fr_next
->fr_address
- fragp
->fr_address
- fragp
->fr_fix
;
4683 fragp
->fr_fix
+= bytes
;
4686 /* md_flush_pending_output */
4689 nds32_flush_pending_output (void)
4691 nds32_last_label
= NULL
;
4695 nds32_frob_label (symbolS
*label
)
4697 dwarf2_emit_label (label
);
4700 /* TC_START_LABEL */
4703 nds32_start_label (int asmdone ATTRIBUTE_UNUSED
, int secdone ATTRIBUTE_UNUSED
)
4705 if (optimize
&& subseg_text_p (now_seg
))
4713 nds32_target_format (void)
4716 if (target_big_endian
)
4717 return "elf32-nds32be-linux";
4719 return "elf32-nds32le-linux";
4721 if (target_big_endian
)
4722 return "elf32-nds32be";
4724 return "elf32-nds32le";
4728 static enum nds32_br_range
4729 get_range_type (const struct nds32_field
*field
)
4731 gas_assert (field
!= NULL
);
4733 if (field
->bitpos
!= 0)
4734 return BR_RANGE_U4G
;
4736 if (field
->bitsize
== 24 && field
->shift
== 1)
4737 return BR_RANGE_S16M
;
4738 else if (field
->bitsize
== 16 && field
->shift
== 1)
4739 return BR_RANGE_S64K
;
4740 else if (field
->bitsize
== 14 && field
->shift
== 1)
4741 return BR_RANGE_S16K
;
4742 else if (field
->bitsize
== 8 && field
->shift
== 1)
4743 return BR_RANGE_S256
;
4745 return BR_RANGE_U4G
;
4748 /* Save pseudo instruction relocation list. */
4750 static struct nds32_relocs_pattern
*
4751 nds32_elf_save_pseudo_pattern (fixS
* fixP
, struct nds32_asm_insn
*insn
,
4752 char *out
, symbolS
*sym
,
4753 struct nds32_relocs_pattern
*reloc_ptr
,
4756 struct nds32_opcode
*opcode
= insn
->opcode
;
4758 reloc_ptr
= XNEW (struct nds32_relocs_pattern
);
4759 reloc_ptr
->seg
= now_seg
;
4760 reloc_ptr
->sym
= sym
;
4761 reloc_ptr
->frag
= fragP
;
4762 reloc_ptr
->frchain
= frchain_now
;
4763 reloc_ptr
->fixP
= fixP
;
4764 reloc_ptr
->opcode
= opcode
;
4765 reloc_ptr
->where
= out
;
4766 reloc_ptr
->insn
= insn
->insn
;
4767 reloc_ptr
->next
= NULL
;
4771 /* Check X_md to transform relocation. */
4774 nds32_elf_record_fixup_exp (fragS
*fragP
, const char *str
,
4775 const struct nds32_field
*fld
,
4776 expressionS
*pexp
, char* out
,
4777 struct nds32_asm_insn
*insn
)
4783 /* Handle instruction relocation. */
4784 if (fld
&& fld
->bitpos
== 0 && (insn
->attr
& NASM_ATTR_HI20
))
4786 /* Relocation for hi20 modifier. */
4789 case BFD_RELOC_NDS32_GOTOFF
: /* @GOTOFF */
4790 reloc
= BFD_RELOC_NDS32_GOTOFF_HI20
;
4792 case BFD_RELOC_NDS32_GOT20
: /* @GOT */
4793 reloc
= BFD_RELOC_NDS32_GOT_HI20
;
4795 case BFD_RELOC_NDS32_25_PLTREL
: /* @PLT */
4797 as_bad (_("Invalid PIC expression."));
4799 reloc
= BFD_RELOC_NDS32_PLT_GOTREL_HI20
;
4801 case BFD_RELOC_NDS32_GOTPC20
: /* _GLOBAL_OFFSET_TABLE_ */
4802 reloc
= BFD_RELOC_NDS32_GOTPC_HI20
;
4804 case BFD_RELOC_NDS32_TPOFF
: /* @TPOFF */
4805 reloc
= BFD_RELOC_NDS32_TLS_LE_HI20
;
4807 case BFD_RELOC_NDS32_GOTTPOFF
: /* @GOTTPOFF */
4808 reloc
= nds32_pic
? BFD_RELOC_NDS32_TLS_IEGP_HI20
: BFD_RELOC_NDS32_TLS_IE_HI20
;
4810 case BFD_RELOC_NDS32_TLS_DESC
: /* @TLSDESC */
4811 reloc
= BFD_RELOC_NDS32_TLS_DESC_HI20
;
4813 default: /* No suffix */
4815 /* When the file is pic, the address must be offset to gp.
4816 It may define another relocation or use GOTOFF. */
4817 reloc
= BFD_RELOC_NDS32_PLT_GOTREL_HI20
;
4819 reloc
= BFD_RELOC_NDS32_HI20
;
4822 fixP
= fix_new_exp (fragP
, out
- fragP
->fr_literal
, insn
->opcode
->isize
,
4823 insn
->info
, 0 /* pcrel */, reloc
);
4825 else if (fld
&& fld
->bitpos
== 0 && (insn
->attr
& NASM_ATTR_LO12
))
4827 /* Relocation for lo12 modifier. */
4828 if (fld
->bitsize
== 15 && fld
->shift
== 0)
4833 case BFD_RELOC_NDS32_GOTOFF
: /* @GOTOFF */
4834 reloc
= BFD_RELOC_NDS32_GOTOFF_LO12
;
4836 case BFD_RELOC_NDS32_GOT20
: /* @GOT */
4837 reloc
= BFD_RELOC_NDS32_GOT_LO12
;
4839 case BFD_RELOC_NDS32_25_PLTREL
: /* @PLT */
4841 as_bad (_("Invalid PIC expression."));
4843 reloc
= BFD_RELOC_NDS32_PLT_GOTREL_LO12
;
4845 case BFD_RELOC_NDS32_GOTPC20
: /* _GLOBAL_OFFSET_TABLE_ */
4846 reloc
= BFD_RELOC_NDS32_GOTPC_LO12
;
4848 case BFD_RELOC_NDS32_TPOFF
: /* @TPOFF */
4849 reloc
= BFD_RELOC_NDS32_TLS_LE_LO12
;
4851 case BFD_RELOC_NDS32_GOTTPOFF
: /* @GOTTPOFF */
4852 reloc
= nds32_pic
? BFD_RELOC_NDS32_TLS_IEGP_LO12
: BFD_RELOC_NDS32_TLS_IE_LO12
;
4854 case BFD_RELOC_NDS32_TLS_DESC
: /* @TLSDESC */
4855 reloc
= BFD_RELOC_NDS32_TLS_DESC_LO12
;
4857 default: /* No suffix */
4859 /* When the file is pic, the address must be offset to gp.
4860 It may define another relocation or use GOTOFF. */
4861 reloc
= BFD_RELOC_NDS32_PLT_GOTREL_LO12
;
4863 reloc
= BFD_RELOC_NDS32_LO12S0
;
4867 else if (fld
->bitsize
== 15 && fld
->shift
== 1)
4868 reloc
= BFD_RELOC_NDS32_LO12S1
; /* [ls]hi */
4869 else if (fld
->bitsize
== 15 && fld
->shift
== 2)
4874 case BFD_RELOC_NDS32_GOTTPOFF
: /* @GOTTPOFF */
4875 reloc
= nds32_pic
? BFD_RELOC_NDS32_TLS_IEGP_LO12S2
: BFD_RELOC_NDS32_TLS_IE_LO12S2
;
4877 default: /* No suffix */
4878 reloc
= BFD_RELOC_NDS32_LO12S2
;
4882 else if (fld
->bitsize
== 15 && fld
->shift
== 3)
4883 reloc
= BFD_RELOC_NDS32_LO12S3
; /* [ls]di */
4884 else if (fld
->bitsize
== 12 && fld
->shift
== 2)
4885 reloc
= BFD_RELOC_NDS32_LO12S2_SP
; /* f[ls][sd]i */
4887 fixP
= fix_new_exp (fragP
, out
- fragP
->fr_literal
, insn
->opcode
->isize
,
4888 insn
->info
, 0 /* pcrel */, reloc
);
4890 else if (fld
&& fld
->bitpos
== 0 && insn
->opcode
->isize
== 4
4891 && (insn
->attr
& NASM_ATTR_PCREL
))
4893 /* Relocation for 32-bit branch instructions. */
4894 if (fld
->bitsize
== 24 && fld
->shift
== 1)
4895 reloc
= BFD_RELOC_NDS32_25_PCREL
;
4896 else if (fld
->bitsize
== 16 && fld
->shift
== 1)
4897 reloc
= BFD_RELOC_NDS32_17_PCREL
;
4898 else if (fld
->bitsize
== 14 && fld
->shift
== 1)
4899 reloc
= BFD_RELOC_NDS32_15_PCREL
;
4900 else if (fld
->bitsize
== 8 && fld
->shift
== 1)
4901 reloc
= BFD_RELOC_NDS32_WORD_9_PCREL
;
4905 fixP
= fix_new_exp (fragP
, out
- fragP
->fr_literal
, insn
->opcode
->isize
,
4906 insn
->info
, 1 /* pcrel */, reloc
);
4908 else if (fld
&& fld
->bitpos
== 0 && insn
->opcode
->isize
== 4
4909 && (insn
->attr
& NASM_ATTR_GPREL
))
4911 /* Relocation for 32-bit gp-relative instructions. */
4912 if (fld
->bitsize
== 19 && fld
->shift
== 0)
4913 reloc
= BFD_RELOC_NDS32_SDA19S0
;
4914 else if (fld
->bitsize
== 18 && fld
->shift
== 1)
4915 reloc
= BFD_RELOC_NDS32_SDA18S1
;
4916 else if (fld
->bitsize
== 17 && fld
->shift
== 2)
4917 reloc
= BFD_RELOC_NDS32_SDA17S2
;
4921 fixP
= fix_new_exp (fragP
, out
- fragP
->fr_literal
, insn
->opcode
->isize
,
4922 insn
->info
, 0 /* pcrel */, reloc
);
4923 /* Insert INSN16 for converting fp_as_gp. */
4924 exp
.X_op
= O_symbol
;
4925 exp
.X_add_symbol
= abs_section_sym
;
4926 exp
.X_add_number
= 0;
4927 if (in_omit_fp
&& reloc
== BFD_RELOC_NDS32_SDA17S2
)
4928 fix_new_exp (fragP
, out
- fragP
->fr_literal
,
4929 insn
->opcode
->isize
, &exp
, 0 /* pcrel */,
4930 BFD_RELOC_NDS32_INSN16
);
4932 else if (fld
&& fld
->bitpos
== 0 && insn
->opcode
->isize
== 2
4933 && (insn
->attr
& NASM_ATTR_PCREL
))
4935 /* Relocation for 16-bit branch instructions. */
4936 if (fld
->bitsize
== 8 && fld
->shift
== 1)
4937 reloc
= BFD_RELOC_NDS32_9_PCREL
;
4941 fixP
= fix_new_exp (fragP
, out
- fragP
->fr_literal
, insn
->opcode
->isize
,
4942 insn
->info
, 1 /* pcrel */, reloc
);
4945 as_bad (_("Don't know how to handle this field. %s"), str
);
4950 /* Build instruction pattern to relax. There are two type group pattern
4951 including pseudo instruction and relax hint. */
4954 nds32_elf_build_relax_relation (fixS
*fixP
, expressionS
*pexp
, char* out
,
4955 struct nds32_asm_insn
*insn
, fragS
*fragP
,
4956 const struct nds32_field
*fld
,
4957 bfd_boolean pseudo_hint
)
4959 struct nds32_relocs_pattern
*reloc_ptr
;
4960 struct nds32_relocs_group
*group
;
4961 symbolS
*sym
= NULL
;
4963 /* The expression may be used uninitialized. */
4965 sym
= pexp
->X_add_symbol
;
4969 /* We cannot know how many instructions will be expanded for
4970 the pseudo instruction here. The first expanded instruction fills
4971 the memory created by relax_hint. The follower will created and link
4973 group
= nds32_relax_hint_current
;
4976 if (group
->pattern
->opcode
== NULL
)
4977 nds32_elf_save_pseudo_pattern (fixP
, insn
, out
, sym
,
4978 group
->pattern
, fragP
);
4981 group
->pattern
->next
=
4982 nds32_elf_save_pseudo_pattern (fixP
, insn
, out
, sym
,
4984 group
->pattern
= group
->pattern
->next
;
4986 group
= group
->next
;
4989 else if (pseudo_opcode
)
4991 /* Save instruction relation for pseudo instruction expanding pattern. */
4992 reloc_ptr
= nds32_elf_save_pseudo_pattern (fixP
, insn
, out
, sym
,
4995 relocs_list
= reloc_ptr
;
4998 struct nds32_relocs_pattern
*temp
= relocs_list
;
5001 temp
->next
= reloc_ptr
;
5004 else if (nds32_relax_hint_current
)
5006 /* Save instruction relation by relax hint. */
5007 group
= nds32_relax_hint_current
;
5010 nds32_elf_save_pseudo_pattern (fixP
, insn
, out
, sym
,
5011 group
->pattern
, fragP
);
5012 group
= group
->next
;
5013 free (nds32_relax_hint_current
);
5014 nds32_relax_hint_current
= group
;
5018 /* Set relaxing false only for relax_hint trigger it. */
5023 #define N32_MEM_EXT(insn) ((N32_OP6_MEM << 25) | insn)
5025 /* Relax pattern for link time relaxation. */
5026 /* Relaxation types only! relocation types are not necessary. */
5027 /* Refer to nds32_elf_record_fixup_exp (). */
5029 static struct nds32_relax_hint_table relax_ls_table
[] =
5032 /* LA and Floating LSI. */
5033 .main_type
= NDS32_RELAX_HINT_LA_FLSI
,
5034 .relax_code_size
= 12,
5043 {0, 4, NDS32_HINT
| NDS32_ADDEND
, BFD_RELOC_NDS32_LOADSTORE
},
5044 {4, 4, NDS32_HINT
| NDS32_PTR
, BFD_RELOC_NDS32_PTR
},
5045 {4, 4, NDS32_HINT
| NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
5046 {8, 4, NDS32_HINT
| NDS32_SYM
, BFD_RELOC_NDS32_LSI
},
5047 {8, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_PTR_RESOLVED
},
5048 {8, 4, NDS32_HINT
| NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
5053 /* Load Address / Load-Store (LALS). */
5054 .main_type
= NDS32_RELAX_HINT_LALS
,
5055 .relax_code_size
= 12,
5064 {0, 4, NDS32_HINT
| NDS32_ADDEND
, BFD_RELOC_NDS32_LOADSTORE
},
5065 {4, 4, NDS32_HINT
| NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
5066 {8, 4, NDS32_HINT
| NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
5071 /* B(AL) symbol@PLT */
5072 .main_type
= NDS32_RELAX_HINT_LA_PLT
,
5073 .relax_code_size
= 16,
5083 {0, 4, NDS32_HINT
| NDS32_ADDEND
, BFD_RELOC_NDS32_LOADSTORE
},
5084 {4, 4, NDS32_HINT
| NDS32_PTR
, BFD_RELOC_NDS32_PTR
},
5085 {8, 4, NDS32_HINT
| NDS32_PTR
, BFD_RELOC_NDS32_PTR
},
5086 {12, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_PLT_GOT_SUFF
},
5087 {12, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_PTR_RESOLVED
},
5088 {12, 4, NDS32_HINT
| NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
5094 .main_type
= NDS32_RELAX_HINT_LA_GOT
,
5095 .relax_code_size
= 12,
5104 {0, 4, NDS32_HINT
| NDS32_ADDEND
, BFD_RELOC_NDS32_LOADSTORE
},
5105 {4, 4, NDS32_HINT
| NDS32_PTR
, BFD_RELOC_NDS32_PTR
},
5106 {8, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_PTR_RESOLVED
},
5107 {8, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_GOT_SUFF
},
5113 .main_type
= NDS32_RELAX_HINT_LA_GOTOFF
,
5114 .relax_code_size
= 16,
5124 {0, 4, NDS32_HINT
| NDS32_ADDEND
, BFD_RELOC_NDS32_LOADSTORE
},
5125 {4, 4, NDS32_HINT
| NDS32_PTR
, BFD_RELOC_NDS32_PTR
},
5126 {8, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_PTR_RESOLVED
},
5127 {8, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_GOTOFF_SUFF
},
5128 {12, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_PTR_RESOLVED
},
5129 {12, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_GOTOFF_SUFF
},
5135 .main_type
= NDS32_RELAX_HINT_TLS_LE_LS
,
5136 .relax_code_size
= 16,
5146 {0, 4, NDS32_HINT
| NDS32_ADDEND
, BFD_RELOC_NDS32_LOADSTORE
},
5147 {4, 4, NDS32_HINT
| NDS32_PTR_MULTIPLE
, BFD_RELOC_NDS32_PTR
},
5148 {8, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_PTR_RESOLVED
},
5149 {8, 4, NDS32_HINT
| NDS32_SYM
, BFD_RELOC_NDS32_TLS_LE_LS
},
5150 {12, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_PTR_RESOLVED
},
5151 {12, 4, NDS32_HINT
| NDS32_SYM
, BFD_RELOC_NDS32_TLS_LE_ADD
},
5157 .main_type
= NDS32_RELAX_HINT_TLS_IE_LA
,
5158 .relax_code_size
= 8,
5166 {0, 4, NDS32_HINT
| NDS32_ADDEND
, BFD_RELOC_NDS32_LOADSTORE
},
5167 {4, 4, NDS32_HINT
| NDS32_INSN16
, BFD_RELOC_NDS32_INSN16
},
5173 .main_type
= NDS32_RELAX_HINT_TLS_IEGP_LA
,
5174 .relax_code_size
= 12,
5183 {0, 4, NDS32_HINT
| NDS32_ADDEND
, BFD_RELOC_NDS32_LOADSTORE
},
5184 {4, 4, NDS32_HINT
| NDS32_PTR_PATTERN
, BFD_RELOC_NDS32_PTR
},
5185 {8, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_PTR_RESOLVED
},
5186 {8, 4, NDS32_HINT
| NDS32_SYM
, BFD_RELOC_NDS32_TLS_IEGP_LW
},
5192 .main_type
= NDS32_RELAX_HINT_TLS_DESC_LS
,
5193 .relax_code_size
= 24,
5199 OP6 (LBI
), /* load argument */
5201 OP6 (MEM
), /* load/store variable or load argument */
5205 {0, 4, NDS32_HINT
| NDS32_ADDEND
, BFD_RELOC_NDS32_LOADSTORE
},
5206 {4, 4, NDS32_HINT
| NDS32_PTR_PATTERN
, BFD_RELOC_NDS32_PTR
},
5207 {8, 4, NDS32_HINT
| NDS32_ABS
, BFD_RELOC_NDS32_PTR_RESOLVED
},
5208 {8, 4, NDS32_HINT
| NDS32_SYM
, BFD_RELOC_NDS32_TLS_DESC_ADD
},
5209 {12, 4, NDS32_HINT
| NDS32_SYM
, BFD_RELOC_NDS32_TLS_DESC_FUNC
},
5210 {16, 4, NDS32_HINT
| NDS32_SYM
, BFD_RELOC_NDS32_TLS_DESC_CALL
},
5211 {20, 4, NDS32_HINT
| NDS32_SYM_DESC_MEM
, BFD_RELOC_NDS32_TLS_DESC_MEM
},
5217 .relax_code_seq
= {0},
5218 .relax_fixup
= {{0, 0 , 0, 0}}
5222 /* Since sethi loadstore relocation has to using next instruction to determine
5223 elimination itself or not, we have to return the next instruction range. */
5226 nds32_elf_sethi_range (struct nds32_relocs_pattern
*pattern
)
5231 switch (pattern
->opcode
->value
)
5236 case N32_MEM_EXT (N32_MEM_LB
):
5237 case N32_MEM_EXT (N32_MEM_LBS
):
5238 case N32_MEM_EXT (N32_MEM_SB
):
5239 range
= NDS32_LOADSTORE_BYTE
;
5244 case N32_MEM_EXT (N32_MEM_LH
):
5245 case N32_MEM_EXT (N32_MEM_LHS
):
5246 case N32_MEM_EXT (N32_MEM_SH
):
5247 range
= NDS32_LOADSTORE_HALF
;
5251 case N32_MEM_EXT (N32_MEM_LW
):
5252 case N32_MEM_EXT (N32_MEM_SW
):
5253 range
= NDS32_LOADSTORE_WORD
;
5257 range
= NDS32_LOADSTORE_FLOAT_S
;
5261 range
= NDS32_LOADSTORE_FLOAT_D
;
5264 range
= NDS32_LOADSTORE_IMM
;
5267 range
= NDS32_LOADSTORE_NONE
;
5270 if (range
!= NDS32_LOADSTORE_NONE
)
5272 pattern
= pattern
->next
;
5277 /* The args means: instruction size, the 1st instruction is converted to 16 or
5278 not, optimize option, 16 bit instruction is enable. */
5280 #define SET_ADDEND(size, convertible, optimize, insn16_on) \
5281 (((size) & 0xff) | ((convertible) ? 1 << 31 : 0) \
5282 | ((optimize) ? 1<< 30 : 0) | (insn16_on ? 1 << 29 : 0))
5283 #define MAC_COMBO (E_NDS32_HAS_FPU_MAC_INST|E_NDS32_HAS_MAC_DX_INST)
5286 nds32_set_elf_flags_by_insn (struct nds32_asm_insn
* insn
)
5288 static int skip_flags
= NASM_ATTR_FPU_FMA
5289 | NASM_ATTR_BRANCH
| NASM_ATTR_SATURATION_EXT
5290 | NASM_ATTR_GPREL
| NASM_ATTR_DXREG
5291 | NASM_ATTR_ISA_V1
| NASM_ATTR_ISA_V2
5292 | NASM_ATTR_ISA_V3
| NASM_ATTR_ISA_V3M
5295 int new_flags
= insn
->opcode
->attr
& ~skip_flags
;
5298 int next
= 1 << (ffs (new_flags
) - 1);
5302 case NASM_ATTR_PERF_EXT
:
5306 nds32_elf_flags
|= E_NDS32_HAS_EXT_INST
;
5307 skip_flags
|= NASM_ATTR_PERF_EXT
;
5310 as_bad (_("instruction %s requires enabling performance "
5311 "extension"), insn
->opcode
->opcode
);
5314 case NASM_ATTR_PERF2_EXT
:
5316 if (nds32_perf_ext2
)
5318 nds32_elf_flags
|= E_NDS32_HAS_EXT2_INST
;
5319 skip_flags
|= NASM_ATTR_PERF2_EXT
;
5322 as_bad (_("instruction %s requires enabling performance "
5323 "extension II"), insn
->opcode
->opcode
);
5326 case NASM_ATTR_AUDIO_ISAEXT
:
5328 if (nds32_audio_ext
)
5330 nds32_elf_flags
|= E_NDS32_HAS_AUDIO_INST
;
5331 skip_flags
|= NASM_ATTR_AUDIO_ISAEXT
;
5334 as_bad (_("instruction %s requires enabling AUDIO extension"),
5335 insn
->opcode
->opcode
);
5338 case NASM_ATTR_STR_EXT
:
5340 if (nds32_string_ext
)
5342 nds32_elf_flags
|= E_NDS32_HAS_STRING_INST
;
5343 skip_flags
|= NASM_ATTR_STR_EXT
;
5346 as_bad (_("instruction %s requires enabling STRING extension"),
5347 insn
->opcode
->opcode
);
5352 if (insn
->opcode
->attr
& NASM_ATTR_DXREG
)
5354 if (nds32_div
&& nds32_dx_regs
)
5356 nds32_elf_flags
|= E_NDS32_HAS_DIV_DX_INST
;
5357 skip_flags
|= NASM_ATTR_DIV
;
5360 as_bad (_("instruction %s requires enabling DIV & DX_REGS "
5361 "extension"), insn
->opcode
->opcode
);
5367 if (nds32_fpu_sp_ext
|| nds32_fpu_dp_ext
)
5369 if (!(nds32_elf_flags
5370 & (E_NDS32_HAS_FPU_INST
| E_NDS32_HAS_FPU_DP_INST
)))
5372 skip_flags
|= NASM_ATTR_FPU
;
5375 as_bad (_("instruction %s requires enabling FPU extension"),
5376 insn
->opcode
->opcode
);
5379 case NASM_ATTR_FPU_SP_EXT
:
5381 if (nds32_fpu_sp_ext
)
5383 nds32_elf_flags
|= E_NDS32_HAS_FPU_INST
;
5384 skip_flags
|= NASM_ATTR_FPU_SP_EXT
;
5387 as_bad (_("instruction %s requires enabling FPU_SP extension"),
5388 insn
->opcode
->opcode
);
5391 case NASM_ATTR_FPU_DP_EXT
:
5393 if (nds32_fpu_dp_ext
)
5395 nds32_elf_flags
|= E_NDS32_HAS_FPU_DP_INST
;
5396 skip_flags
|= NASM_ATTR_FPU_DP_EXT
;
5399 as_bad (_("instruction %s requires enabling FPU_DP extension"),
5400 insn
->opcode
->opcode
);
5405 if (insn
->opcode
->attr
& NASM_ATTR_FPU_SP_EXT
)
5407 if (nds32_fpu_sp_ext
&& nds32_mac
)
5408 nds32_elf_flags
|= E_NDS32_HAS_FPU_MAC_INST
;
5410 as_bad (_("instruction %s requires enabling FPU_MAC "
5411 "extension"), insn
->opcode
->opcode
);
5413 else if (insn
->opcode
->attr
& NASM_ATTR_FPU_DP_EXT
)
5415 if (nds32_fpu_dp_ext
&& nds32_mac
)
5416 nds32_elf_flags
|= E_NDS32_HAS_FPU_MAC_INST
;
5418 as_bad (_("instruction %s requires enabling FPU_MAC "
5419 "extension"), insn
->opcode
->opcode
);
5421 else if (insn
->opcode
->attr
& NASM_ATTR_DXREG
)
5423 if (nds32_dx_regs
&& nds32_mac
)
5424 nds32_elf_flags
|= E_NDS32_HAS_MAC_DX_INST
;
5426 as_bad (_("instruction %s requires enabling DX_REGS "
5427 "extension"), insn
->opcode
->opcode
);
5430 if (MAC_COMBO
== (MAC_COMBO
& nds32_elf_flags
))
5431 skip_flags
|= NASM_ATTR_MAC
;
5434 case NASM_ATTR_DSP_ISAEXT
:
5438 nds32_elf_flags
|= E_NDS32_HAS_DSP_INST
;
5439 skip_flags
|= NASM_ATTR_DSP_ISAEXT
;
5442 as_bad (_("instruction %s requires enabling dsp extension"),
5443 insn
->opcode
->opcode
);
5450 nds32_elf_flags
|= E_NDS32_HAS_ZOL
;
5451 skip_flags
|= NASM_ATTR_ZOL
;
5454 as_bad (_("instruction %s requires enabling zol extension"),
5455 insn
->opcode
->opcode
);
5459 as_bad (_("internal error: unknown instruction attribute: 0x%08x"),
5465 /* Flag for analysis relaxation type. */
5467 enum nds32_insn_type
5469 N32_RELAX_SETHI
= 1,
5470 N32_RELAX_BR
= (1 << 1),
5471 N32_RELAX_LSI
= (1 << 2),
5472 N32_RELAX_JUMP
= (1 << 3),
5473 N32_RELAX_CALL
= (1 << 4),
5474 N32_RELAX_ORI
= (1 << 5),
5475 N32_RELAX_MEM
= (1 << 6),
5476 N32_RELAX_MOVI
= (1 << 7),
5477 N32_RELAX_ALU1
= (1 << 8),
5478 N32_RELAX_16BIT
= (1 << 9),
5481 struct nds32_hint_map
5483 /* the preamble relocation */
5484 bfd_reloc_code_real_type hi_type
;
5487 /* relax pattern ID */
5488 enum nds32_relax_hint_type hint_type
;
5490 enum nds32_br_range range
;
5491 /* pattern character flags */
5492 enum nds32_insn_type insn_list
;
5493 /* optional pattern character flags */
5494 enum nds32_insn_type option_list
;
5497 /* Table to match instructions with hint and relax pattern. */
5499 static struct nds32_hint_map hint_map
[] =
5503 BFD_RELOC_NDS32_HI20
,
5505 NDS32_RELAX_HINT_NONE
,
5507 N32_RELAX_SETHI
| N32_RELAX_ORI
| N32_RELAX_CALL
,
5512 _dummy_first_bfd_reloc_code_real
,
5514 NDS32_RELAX_HINT_NONE
,
5516 N32_RELAX_BR
| N32_RELAX_CALL
,
5521 BFD_RELOC_NDS32_HI20
,
5523 NDS32_RELAX_HINT_NONE
,
5525 N32_RELAX_BR
| N32_RELAX_SETHI
| N32_RELAX_ORI
| N32_RELAX_CALL
,
5530 BFD_RELOC_NDS32_HI20
,
5532 NDS32_RELAX_HINT_NONE
,
5534 N32_RELAX_SETHI
| N32_RELAX_ORI
| N32_RELAX_JUMP
,
5539 /* There is two kinds of variation of LONGJUMP5. One of them
5540 generate EMPTY relocation for converted INSN16 if needed.
5541 But we don't distinguish them here. */
5542 _dummy_first_bfd_reloc_code_real
,
5544 NDS32_RELAX_HINT_NONE
,
5546 N32_RELAX_BR
| N32_RELAX_JUMP
,
5551 BFD_RELOC_NDS32_HI20
,
5553 NDS32_RELAX_HINT_NONE
,
5555 N32_RELAX_SETHI
| N32_RELAX_ORI
| N32_RELAX_BR
| N32_RELAX_JUMP
,
5560 _dummy_first_bfd_reloc_code_real
,
5562 NDS32_RELAX_HINT_NONE
,
5564 N32_RELAX_MOVI
| N32_RELAX_BR
,
5568 /* LONGCALL (BAL|JR|LA symbol@PLT). */
5569 BFD_RELOC_NDS32_PLT_GOTREL_HI20
,
5571 NDS32_RELAX_HINT_LA_PLT
,
5573 N32_RELAX_SETHI
| N32_RELAX_ORI
,
5574 N32_RELAX_ALU1
| N32_RELAX_CALL
| N32_RELAX_JUMP
,
5576 /* relative issue: #12566 */
5578 /* LA and Floating LSI. */
5579 BFD_RELOC_NDS32_HI20
,
5581 NDS32_RELAX_HINT_LA_FLSI
,
5583 N32_RELAX_SETHI
| N32_RELAX_ORI
| N32_RELAX_LSI
,
5586 /* relative issue: #11685 #11602 */
5588 /* load address / load-store (LALS). */
5589 BFD_RELOC_NDS32_HI20
,
5591 NDS32_RELAX_HINT_LALS
,
5594 N32_RELAX_ORI
| N32_RELAX_LSI
,
5597 /* setup $GP (_GLOBAL_OFFSET_TABLE_) */
5598 BFD_RELOC_NDS32_GOTPC_HI20
,
5600 NDS32_RELAX_HINT_LALS
,
5602 N32_RELAX_SETHI
| N32_RELAX_ORI
,
5606 /* GOT LA/LS (symbol@GOT) */
5607 BFD_RELOC_NDS32_GOT_HI20
,
5609 NDS32_RELAX_HINT_LA_GOT
,
5611 N32_RELAX_SETHI
| N32_RELAX_ORI
,
5615 /* GOTOFF LA/LS (symbol@GOTOFF) */
5616 BFD_RELOC_NDS32_GOTOFF_HI20
,
5618 NDS32_RELAX_HINT_LA_GOTOFF
,
5620 N32_RELAX_SETHI
| N32_RELAX_ORI
,
5621 N32_RELAX_ALU1
| N32_RELAX_MEM
, /* | N32_RELAX_LSI, */
5624 /* TLS LE LA|LS (@TPOFF) */
5625 BFD_RELOC_NDS32_TLS_LE_HI20
,
5627 NDS32_RELAX_HINT_TLS_LE_LS
,
5629 N32_RELAX_SETHI
| N32_RELAX_ORI
,
5630 N32_RELAX_ALU1
| N32_RELAX_MEM
,
5634 BFD_RELOC_NDS32_TLS_IE_HI20
,
5636 NDS32_RELAX_HINT_TLS_IE_LA
,
5638 N32_RELAX_SETHI
| N32_RELAX_LSI
,
5643 BFD_RELOC_NDS32_TLS_IE_HI20
,
5645 NDS32_RELAX_HINT_TLS_IE_LS
,
5647 N32_RELAX_SETHI
| N32_RELAX_LSI
| N32_RELAX_MEM
,
5652 BFD_RELOC_NDS32_TLS_IEGP_HI20
,
5654 NDS32_RELAX_HINT_TLS_IEGP_LA
,
5656 N32_RELAX_SETHI
| N32_RELAX_ORI
| N32_RELAX_MEM
,
5661 BFD_RELOC_NDS32_TLS_DESC_HI20
,
5663 NDS32_RELAX_HINT_TLS_DESC_LS
,
5665 N32_RELAX_SETHI
| N32_RELAX_ORI
| N32_RELAX_ALU1
| N32_RELAX_CALL
,
5666 N32_RELAX_LSI
| N32_RELAX_MEM
,
5669 {0, NULL
, 0, 0 ,0, 0}
5672 /* Find the relaxation pattern according to instructions. */
5675 nds32_find_reloc_table (struct nds32_relocs_pattern
*relocs_pattern
,
5676 struct nds32_relax_hint_table
*hint_info
)
5678 unsigned int opcode
, seq_size
;
5679 enum nds32_br_range range
;
5680 struct nds32_relocs_pattern
*pattern
, *hi_pattern
= NULL
;
5681 const char *opc
= NULL
;
5682 relax_info_t
*relax_info
= NULL
;
5683 nds32_relax_fixup_info_t
*fixup_info
, *hint_fixup
;
5684 enum nds32_relax_hint_type hint_type
= NDS32_RELAX_HINT_NONE
;
5685 struct nds32_relax_hint_table
*table_ptr
;
5686 uint32_t *code_seq
, *hint_code
;
5687 enum nds32_insn_type relax_type
= 0;
5688 struct nds32_hint_map
*map_ptr
= hint_map
;
5690 const char *check_insn
[] =
5691 { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" };
5693 /* TODO: PLT GOT. */
5694 /* Traverse all pattern instruction and set flag. */
5695 pattern
= relocs_pattern
;
5698 if (pattern
->opcode
->isize
== 4)
5700 /* 4 byte instruction. */
5701 opcode
= N32_OP6 (pattern
->opcode
->value
);
5705 hi_pattern
= pattern
;
5706 relax_type
|= N32_RELAX_SETHI
;
5709 relax_type
|= N32_RELAX_MEM
;
5712 relax_type
|= N32_RELAX_ALU1
;
5715 relax_type
|= N32_RELAX_ORI
;
5720 relax_type
|= N32_RELAX_BR
;
5723 relax_type
|= N32_RELAX_MOVI
;
5737 relax_type
|= N32_RELAX_LSI
;
5740 if (__GF (pattern
->opcode
->value
, 0, 1) == 1)
5741 relax_type
|= N32_RELAX_CALL
;
5743 relax_type
|= N32_RELAX_JUMP
;
5746 if (__GF (pattern
->opcode
->value
, 24, 1) == 1)
5747 relax_type
|= N32_RELAX_CALL
;
5749 relax_type
|= N32_RELAX_JUMP
;
5752 as_warn (_("relax hint unrecognized instruction: line %d."),
5753 pattern
->frag
->fr_line
);
5759 /* 2 byte instruction. Compare by opcode name because
5760 the opcode of 2byte instruction is not regular. */
5762 for (i
= 0; i
< ARRAY_SIZE (check_insn
); i
++)
5764 if (strcmp (pattern
->opcode
->opcode
, check_insn
[i
]) == 0)
5766 relax_type
|= N32_RELAX_BR
;
5772 relax_type
|= N32_RELAX_16BIT
;
5774 pattern
= pattern
->next
;
5777 /* Analysis instruction flag to choose relaxation table. */
5778 while (map_ptr
->insn_list
!= 0)
5780 struct nds32_hint_map
*hint
= map_ptr
++;
5781 enum nds32_insn_type must
= hint
->insn_list
;
5782 enum nds32_insn_type optional
= hint
->option_list
;
5783 enum nds32_insn_type extra
;
5785 if (must
!= (must
& relax_type
))
5788 extra
= relax_type
^ must
;
5789 if (extra
!= (extra
& optional
))
5793 || (hi_pattern
->fixP
5794 && hi_pattern
->fixP
->fx_r_type
== hint
->hi_type
))
5797 hint_type
= hint
->hint_type
;
5798 range
= hint
->range
;
5804 if (map_ptr
->insn_list
== 0)
5807 as_warn (_("Can not find match relax hint. Line: %d"),
5808 relocs_pattern
->frag
->fr_line
);
5812 /* Get the match table. */
5815 /* Branch relax pattern. */
5816 relax_info
= hash_find (nds32_relax_info_hash
, opc
);
5819 fixup_info
= relax_info
->relax_fixup
[range
];
5820 code_seq
= relax_info
->relax_code_seq
[range
];
5821 seq_size
= relax_info
->relax_code_size
[range
];
5825 /* Load-store relax pattern. */
5826 table_ptr
= relax_ls_table
;
5827 while (table_ptr
->main_type
!= 0)
5829 if (table_ptr
->main_type
== hint_type
)
5831 fixup_info
= table_ptr
->relax_fixup
;
5832 code_seq
= table_ptr
->relax_code_seq
;
5833 seq_size
= table_ptr
->relax_code_size
;
5838 if (table_ptr
->main_type
== 0)
5844 hint_fixup
= hint_info
->relax_fixup
;
5845 hint_code
= hint_info
->relax_code_seq
;
5846 hint_info
->relax_code_size
= seq_size
;
5848 while (fixup_info
->size
!= 0)
5850 if (fixup_info
->ramp
& NDS32_HINT
)
5852 memcpy (hint_fixup
, fixup_info
, sizeof (nds32_relax_fixup_info_t
));
5857 /* Clear final relocation. */
5858 memset (hint_fixup
, 0, sizeof (nds32_relax_fixup_info_t
));
5859 /* Copy code sequence. */
5860 memcpy (hint_code
, code_seq
, seq_size
);
5864 /* Because there are a lot of variant of load-store, check
5865 all these type here. */
5867 #define CLEAN_REG(insn) ((insn) & 0xfe0003ff)
5868 #define GET_OPCODE(insn) ((insn) & 0xfe000000)
5871 nds32_match_hint_insn (struct nds32_opcode
*opcode
, uint32_t seq
)
5873 const char *check_insn
[] =
5874 { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8", "jral5" };
5875 uint32_t insn
= opcode
->value
;
5878 insn
= CLEAN_REG (opcode
->value
);
5885 /* In relocation_table, it regards instruction LBI as representation
5886 of all the NDS32_RELAX_HINT_LS pattern. */
5887 if (insn
== OP6 (LBI
) || insn
== OP6 (SBI
) || insn
== OP6 (LBSI
)
5888 || insn
== OP6 (LHI
) || insn
== OP6 (SHI
) || insn
== OP6 (LHSI
)
5889 || insn
== OP6 (LWI
) || insn
== OP6 (SWI
)
5890 || insn
== OP6 (LWC
) || insn
== OP6 (SWC
)
5891 || insn
== OP6 (LDC
) || insn
== OP6 (SDC
))
5895 /* This is for LONGCALL5 and LONGCALL6. */
5896 if (insn
== OP6 (BR2
))
5900 /* This is for LONGJUMP5 and LONGJUMP6. */
5901 if (opcode
->isize
== 4
5902 && (insn
== OP6 (BR1
) || insn
== OP6 (BR2
) || insn
== OP6 (BR3
)))
5904 else if (opcode
->isize
== 2)
5906 for (i
= 0; i
< ARRAY_SIZE (check_insn
); i
++)
5907 if (strcmp (opcode
->opcode
, check_insn
[i
]) == 0)
5912 /* This is for LONGJUMP7. */
5913 if (opcode
->isize
== 2 && strcmp (opcode
->opcode
, "movi55") == 0)
5917 if (OP6 (MEM
) == GET_OPCODE (insn
))
5921 /* bit 24: N32_JI_JAL */ /* feed me! */
5922 if ((insn
& ~(N32_BIT (24))) == JREG (JRAL
))
5926 if (opcode
->isize
== 2)
5928 for (i
= 0; i
< ARRAY_SIZE (check_insn
); i
++)
5929 if (strcmp (opcode
->opcode
, check_insn
[i
]) == 0)
5932 if ((strcmp (opcode
->opcode
, "add5.pc") == 0) ||
5933 (strcmp (opcode
->opcode
, "add45") == 0))
5940 /* Append relax relocation for link time relaxing. */
5943 nds32_elf_append_relax_relocs (const char *key
, void *value
)
5945 struct nds32_relocs_pattern
*relocs_pattern
=
5946 (struct nds32_relocs_pattern
*) value
;
5947 struct nds32_relocs_pattern
*pattern_temp
, *pattern_now
;
5948 symbolS
*sym
, *hi_sym
= NULL
;
5951 segT seg_bak
= now_seg
;
5952 frchainS
*frchain_bak
= frchain_now
;
5953 struct nds32_relax_hint_table hint_info
;
5954 nds32_relax_fixup_info_t
*hint_fixup
, *fixup_now
;
5956 offsetT branch_offset
, hi_branch_offset
= 0;
5959 unsigned int ptr_offset
, hint_count
, relax_code_size
, count
= 0;
5960 uint32_t *code_seq
, code_insn
;
5964 if (!relocs_pattern
)
5967 if (!nds32_find_reloc_table (relocs_pattern
, &hint_info
))
5970 /* Save symbol for some EMPTY relocation using. */
5971 pattern_now
= relocs_pattern
;
5974 if (pattern_now
->opcode
->value
== OP6 (SETHI
))
5976 hi_sym
= pattern_now
->sym
;
5977 hi_branch_offset
= pattern_now
->fixP
->fx_offset
;
5980 pattern_now
= pattern_now
->next
;
5983 /* Inserting fix up must specify now_seg or frchain_now. */
5984 now_seg
= relocs_pattern
->seg
;
5985 frchain_now
= relocs_pattern
->frchain
;
5986 fragP
= relocs_pattern
->frag
;
5987 branch_offset
= fragP
->fr_offset
;
5989 hint_fixup
= hint_info
.relax_fixup
;
5990 code_seq
= hint_info
.relax_code_seq
;
5991 relax_code_size
= hint_info
.relax_code_size
;
5992 pattern_now
= relocs_pattern
;
5994 #ifdef NDS32_LINUX_TOOLCHAIN
5995 /* prepare group relocation ID (number). */
5999 /* convert .relax_hint key to number */
6001 group_id
= strtol (key
, NULL
, 10);
6002 if ((errno
== ERANGE
&& (group_id
== LONG_MAX
|| group_id
== LONG_MIN
))
6003 || (errno
!= 0 && group_id
== 0))
6005 as_bad (_("Internal error: .relax_hint KEY is not a number!"));
6011 /* Insert relaxation. */
6012 exp
.X_op
= O_symbol
;
6014 /* For each instruction in the hint group. */
6017 if (count
>= relax_code_size
/ 4)
6020 /* Choose the match fixup by instruction. */
6021 code_insn
= CLEAN_REG (*(code_seq
+ count
));
6022 if (!nds32_match_hint_insn (pattern_now
->opcode
, code_insn
))
6024 /* Try search from head again */
6026 code_insn
= CLEAN_REG (*(code_seq
+ count
));
6028 while (!nds32_match_hint_insn (pattern_now
->opcode
, code_insn
))
6031 if (count
>= relax_code_size
/ 4)
6033 as_bad (_("Internal error: Relax hint (%s) error. %s: %s (%x)"),
6036 pattern_now
->opcode
->opcode
,
6037 pattern_now
->opcode
->value
);
6040 code_insn
= CLEAN_REG (*(code_seq
+ count
));
6043 fragP
= pattern_now
->frag
;
6044 sym
= pattern_now
->sym
;
6045 branch_offset
= fragP
->fr_offset
;
6047 where
= pattern_now
->where
;
6048 /* Find the instruction map fix. */
6049 fixup_now
= hint_fixup
;
6050 while (fixup_now
->offset
!= offset
)
6053 if (fixup_now
->size
== 0)
6056 /* This element is without relaxation relocation. */
6057 if (fixup_now
->size
== 0)
6059 pattern_now
= pattern_now
->next
;
6062 fixup_size
= fixup_now
->size
;
6064 /* Insert all fixup. */
6065 while (fixup_size
!= 0 && fixup_now
->offset
== offset
)
6067 /* Set the real instruction size in element. */
6068 fixup_size
= pattern_now
->opcode
->isize
;
6069 pcrel
= ((fixup_now
->ramp
& NDS32_PCREL
) != 0) ? 1 : 0;
6070 if (fixup_now
->ramp
& NDS32_FIX
)
6072 /* Convert original relocation. */
6073 pattern_now
->fixP
->fx_r_type
= fixup_now
->r_type
;
6076 else if ((fixup_now
->ramp
& NDS32_PTR
) != 0)
6078 /* This relocation has to point to another instruction. Make
6079 sure each resolved relocation has to be pointed. */
6080 pattern_temp
= relocs_pattern
;
6081 /* All instruction in relax_table should be 32-bit. */
6082 hint_count
= hint_info
.relax_code_size
/ 4;
6083 code_insn
= CLEAN_REG (*(code_seq
+ hint_count
- 1));
6084 while (pattern_temp
)
6086 /* Point to every resolved relocation. */
6087 if (nds32_match_hint_insn (pattern_temp
->opcode
, code_insn
))
6090 pattern_temp
->where
- pattern_temp
->frag
->fr_literal
;
6091 exp
.X_add_symbol
= symbol_temp_new (now_seg
, ptr_offset
,
6092 pattern_temp
->frag
);
6093 exp
.X_add_number
= 0;
6095 fix_new_exp (fragP
, where
- fragP
->fr_literal
,
6096 fixup_size
, &exp
, 0, fixup_now
->r_type
);
6097 fixP
->fx_addnumber
= fixP
->fx_offset
;
6099 pattern_temp
= pattern_temp
->next
;
6103 else if (fixup_now
->ramp
& NDS32_ADDEND
)
6105 range
= nds32_elf_sethi_range (relocs_pattern
);
6106 if (range
== NDS32_LOADSTORE_NONE
)
6108 as_bad (_("Internal error: Range error. %s"), now_seg
->name
);
6111 exp
.X_add_symbol
= abs_section_sym
;
6112 exp
.X_add_number
= SET_ADDEND (4, 0, optimize
, enable_16bit
);
6113 exp
.X_add_number
|= ((range
& 0x3f) << 8);
6115 else if ((fixup_now
->ramp
& NDS32_ABS
) != 0)
6117 /* This is a tag relocation. */
6118 exp
.X_add_symbol
= abs_section_sym
;
6119 exp
.X_add_number
= 0;
6121 else if ((fixup_now
->ramp
& NDS32_INSN16
) != 0)
6125 /* This is a tag relocation. */
6126 exp
.X_add_symbol
= abs_section_sym
;
6127 exp
.X_add_number
= 0;
6129 else if ((fixup_now
->ramp
& NDS32_SYM
) != 0)
6131 /* For EMPTY relocation save the true symbol. */
6132 exp
.X_add_symbol
= hi_sym
;
6133 exp
.X_add_number
= hi_branch_offset
;
6135 else if (NDS32_SYM_DESC_MEM
& fixup_now
->ramp
)
6137 /* Do the same as NDS32_SYM. */
6138 exp
.X_add_symbol
= hi_sym
;
6139 exp
.X_add_number
= hi_branch_offset
;
6141 /* Extra to NDS32_SYM. */
6142 /* Detect if DESC_FUNC relax type do apply. */
6143 if ((REG_GP
== N32_RA5 (pattern_now
->insn
))
6144 || (REG_GP
== N32_RB5 (pattern_now
->insn
)))
6146 fixP
= fix_new_exp (fragP
, where
- fragP
->fr_literal
,
6147 fixup_size
, &exp
, pcrel
,
6148 BFD_RELOC_NDS32_TLS_DESC_FUNC
);
6149 fixP
->fx_addnumber
= fixP
->fx_offset
;
6153 /* Else do as usual. */
6155 else if (fixup_now
->ramp
& NDS32_PTR_PATTERN
)
6157 /* Find out PTR_RESOLVED code pattern. */
6158 nds32_relax_fixup_info_t
*next_fixup
= fixup_now
+ 1;
6159 uint32_t resolved_pattern
= 0;
6160 while (next_fixup
->offset
)
6162 if (next_fixup
->r_type
== BFD_RELOC_NDS32_PTR_RESOLVED
)
6164 uint32_t new_pattern
= code_seq
[next_fixup
->offset
>> 2];
6165 if (!resolved_pattern
)
6166 resolved_pattern
= new_pattern
;
6167 else if (new_pattern
!= resolved_pattern
)
6169 as_warn (_("Multiple BFD_RELOC_NDS32_PTR_RESOLVED "
6170 "patterns are not supported yet!"));
6177 /* Find matched code and insert fix-ups. */
6178 struct nds32_relocs_pattern
*next_pattern
= pattern_now
->next
;
6179 /* This relocation has to point to another instruction.
6180 Make sure each resolved relocation has to be pointed. */
6181 /* All instruction in relax_table should be 32-bit. */
6182 while (next_pattern
)
6184 uint32_t cur_pattern
= GET_OPCODE (next_pattern
->opcode
->value
);
6185 if (cur_pattern
== resolved_pattern
)
6187 ptr_offset
= next_pattern
->where
6188 - next_pattern
->frag
->fr_literal
;
6189 exp
.X_add_symbol
= symbol_temp_new (now_seg
, ptr_offset
,
6190 next_pattern
->frag
);
6191 exp
.X_add_number
= 0;
6192 fixP
= fix_new_exp (fragP
, where
- fragP
->fr_literal
,
6193 fixup_size
, &exp
, 0,
6195 fixP
->fx_addnumber
= fixP
->fx_offset
;
6197 next_pattern
= next_pattern
->next
;
6202 else if (fixup_now
->ramp
& NDS32_PTR_MULTIPLE
)
6204 /* Find each PTR_RESOLVED pattern after PTR. */
6205 nds32_relax_fixup_info_t
*next_fixup
= fixup_now
+ 1;
6206 while (next_fixup
->offset
)
6208 if (next_fixup
->r_type
== BFD_RELOC_NDS32_PTR_RESOLVED
)
6210 uint32_t pattern
= code_seq
[next_fixup
->offset
>> 2];
6211 /* Find matched code to insert fix-ups. */
6212 struct nds32_relocs_pattern
*next_insn
= pattern_now
->next
;
6215 uint32_t insn_pattern
= GET_OPCODE (next_insn
->opcode
->value
);
6216 if (insn_pattern
== pattern
)
6218 ptr_offset
= next_insn
->where
6219 - next_insn
->frag
->fr_literal
;
6220 exp
.X_add_symbol
= symbol_temp_new (now_seg
,
6223 exp
.X_add_number
= 0;
6224 fixP
= fix_new_exp (fragP
,
6225 where
- fragP
->fr_literal
,
6226 fixup_size
, &exp
, 0,
6228 fixP
->fx_addnumber
= fixP
->fx_offset
;
6230 next_insn
= next_insn
->next
;
6239 exp
.X_add_symbol
= sym
;
6240 exp
.X_add_number
= branch_offset
;
6243 if (fixup_size
!= 0)
6245 fixP
= fix_new_exp (fragP
, where
- fragP
->fr_literal
, fixup_size
,
6246 &exp
, pcrel
, fixup_now
->r_type
);
6247 fixP
->fx_addnumber
= fixP
->fx_offset
;
6250 fixup_size
= fixup_now
->size
;
6253 #ifdef NDS32_LINUX_TOOLCHAIN
6254 /* Insert group relocation for each relax hint. */
6257 exp
.X_add_symbol
= hi_sym
; /* for eyes only */
6258 exp
.X_add_number
= group_id
;
6259 fixP
= fix_new_exp (fragP
, where
- fragP
->fr_literal
, fixup_size
,
6260 &exp
, pcrel
, BFD_RELOC_NDS32_GROUP
);
6261 fixP
->fx_addnumber
= fixP
->fx_offset
;
6265 if (count
< relax_code_size
/ 4)
6267 pattern_now
= pattern_now
->next
;
6272 frchain_now
= frchain_bak
;
6276 nds32_str_tolower (const char *src
, char *dest
)
6278 unsigned int i
, len
;
6282 for (i
= 0; i
< len
; i
++)
6283 *(dest
+ i
) = TOLOWER (*(src
+ i
));
6288 /* Check instruction if it can be used for the baseline. */
6291 nds32_check_insn_available (struct nds32_asm_insn insn
, const char *str
)
6293 int attr
= insn
.attr
& ATTR_ALL
;
6294 static int baseline_isa
= 0;
6297 s
= xmalloc (strlen (str
) + 1);
6298 nds32_str_tolower (str
, s
);
6300 && (((insn
.opcode
->value
== ALU2 (MTUSR
)
6301 || insn
.opcode
->value
== ALU2 (MFUSR
))
6302 && (strstr (s
, "lc")
6304 || strstr (s
, "lb")))
6305 || (insn
.attr
& NASM_ATTR_ZOL
)))
6307 as_bad (_("Not support instruction %s in verbatim."), str
);
6312 if (!enable_16bit
&& insn
.opcode
->isize
== 2)
6314 as_bad (_("16-bit instruction is disabled: %s."), str
);
6318 /* No isa setting or all isa can use. */
6319 if (attr
== 0 || attr
== ATTR_ALL
)
6322 if (baseline_isa
== 0)
6324 /* Map option baseline and instruction attribute. */
6325 switch (nds32_baseline
)
6328 baseline_isa
= ATTR (ISA_V2
);
6331 baseline_isa
= ATTR (ISA_V3
);
6334 baseline_isa
= ATTR (ISA_V3M
);
6339 if ((baseline_isa
& attr
) == 0)
6341 as_bad (_("Instruction %s not supported in the baseline."), str
);
6347 /* Stub of machine dependent. */
6350 md_assemble (char *str
)
6352 struct nds32_asm_insn insn
;
6354 struct nds32_pseudo_opcode
*popcode
;
6355 const struct nds32_field
*fld
= NULL
;
6358 struct nds32_relocs_pattern
*relocs_temp
;
6359 struct nds32_relocs_group
*group_temp
;
6361 int label
= label_exist
;
6362 static bfd_boolean pseudo_hint
= FALSE
;
6364 popcode
= nds32_lookup_pseudo_opcode (str
);
6365 /* Note that we need to check 'verbatim' and
6366 'opcode->physical_op'. If the assembly content is generated by
6367 compiler and this opcode is a physical instruction, there is no
6368 need to perform pseudo instruction expansion/transformation. */
6369 if (popcode
&& !(verbatim
&& popcode
->physical_op
))
6371 /* Pseudo instruction is with relax_hint. */
6374 pseudo_opcode
= TRUE
;
6375 nds32_pseudo_opcode_wrapper (str
, popcode
);
6376 pseudo_opcode
= FALSE
;
6377 pseudo_hint
= FALSE
;
6378 nds32_elf_append_relax_relocs (NULL
, relocs_list
);
6380 /* Free relax_hint group list. */
6381 while (nds32_relax_hint_current
)
6383 group_temp
= nds32_relax_hint_current
->next
;
6384 free (nds32_relax_hint_current
);
6385 nds32_relax_hint_current
= group_temp
;
6388 /* Free pseudo list. */
6389 relocs_temp
= relocs_list
;
6392 relocs_list
= relocs_list
->next
;
6394 relocs_temp
= relocs_list
;
6401 insn
.info
= XNEW (expressionS
);
6402 asm_desc
.result
= NASM_OK
;
6403 nds32_assemble (&asm_desc
, &insn
, str
);
6405 switch (asm_desc
.result
)
6407 case NASM_ERR_UNKNOWN_OP
:
6408 as_bad (_("Unrecognized opcode, %s."), str
);
6410 case NASM_ERR_SYNTAX
:
6411 as_bad (_("Incorrect syntax, %s."), str
);
6413 case NASM_ERR_OPERAND
:
6414 as_bad (_("Unrecognized operand/register, %s."), str
);
6416 case NASM_ERR_OUT_OF_RANGE
:
6417 as_bad (_("Operand out of range, %s."), str
);
6419 case NASM_ERR_REG_REDUCED
:
6420 as_bad (_("Prohibited register used for reduced-register, %s."), str
);
6422 case NASM_ERR_JUNK_EOL
:
6423 as_bad (_("Junk at end of line, %s."), str
);
6427 gas_assert (insn
.opcode
);
6429 nds32_set_elf_flags_by_insn (&insn
);
6431 gas_assert (insn
.opcode
->isize
== 4 || insn
.opcode
->isize
== 2);
6433 if (!nds32_check_insn_available (insn
, str
))
6436 /* Make sure the beginning of text being 2-byte align. */
6437 nds32_adjust_label (1);
6438 add_mapping_symbol (MAP_CODE
, 0, 0);
6440 /* Try to allocate the max size to guarantee relaxable same branch
6441 instructions in the same fragment. */
6442 frag_grow (NDS32_MAXCHAR
);
6445 if (fld
&& (insn
.attr
& NASM_ATTR_BRANCH
)
6446 && (pseudo_opcode
|| (insn
.opcode
->value
!= INSN_JAL
6447 && insn
.opcode
->value
!= INSN_J
))
6448 && (!verbatim
|| pseudo_opcode
))
6450 /* User assembly code branch relax for it. */
6451 /* If fld is not NULL, it is a symbol. */
6452 /* Branch must relax to proper pattern in user assembly code exclude
6453 J and JAL. Keep these two in original type for users which wants
6454 to keep their size be fixed. In general, assembler does not convert
6455 instruction generated by compiler. But jump instruction may be
6456 truncated in text virtual model. For workaround, compiler generate
6457 pseudo jump to fix this issue currently. */
6459 /* Get branch range type. */
6460 dwarf2_emit_insn (0);
6461 enum nds32_br_range range_type
;
6462 expressionS
*pexp
= insn
.info
;
6464 range_type
= get_range_type (fld
);
6466 out
= frag_var (rs_machine_dependent
, NDS32_MAXCHAR
,
6467 0, /* VAR is un-used. */
6468 range_type
, /* SUBTYPE is used as range type. */
6469 pexp
->X_add_symbol
, pexp
->X_add_number
, 0);
6471 fragP
->fr_fix
+= insn
.opcode
->isize
;
6472 fragP
->tc_frag_data
.opcode
= insn
.opcode
;
6473 fragP
->tc_frag_data
.insn
= insn
.insn
;
6474 if (insn
.opcode
->isize
== 4)
6475 bfd_putb32 (insn
.insn
, out
);
6476 else if (insn
.opcode
->isize
== 2)
6477 bfd_putb16 (insn
.insn
, out
);
6478 fragP
->tc_frag_data
.flag
|= NDS32_FRAG_BRANCH
;
6482 /* md_convert_frag will insert relocations. */
6484 else if (!relaxing
&& enable_16bit
&& (optimize
|| optimize_for_space
)
6485 && ((!fld
&& !verbatim
&& insn
.opcode
->isize
== 4
6486 && nds32_convert_32_to_16 (stdoutput
, insn
.insn
, &insn_16
, NULL
))
6487 || (insn
.opcode
->isize
== 2
6488 && nds32_convert_16_to_32 (stdoutput
, insn
.insn
, NULL
))))
6490 /* Record this one is relaxable. */
6491 expressionS
*pexp
= insn
.info
;
6492 dwarf2_emit_insn (0);
6495 out
= frag_var (rs_machine_dependent
,
6496 4, /* Max size is 32-bit instruction. */
6497 0, /* VAR is un-used. */
6498 0, pexp
->X_add_symbol
, pexp
->X_add_number
, 0);
6499 fragP
->tc_frag_data
.flag
|= NDS32_FRAG_RELAXABLE_BRANCH
;
6502 out
= frag_var (rs_machine_dependent
,
6503 4, /* Max size is 32-bit instruction. */
6504 0, /* VAR is un-used. */
6506 fragP
->tc_frag_data
.flag
|= NDS32_FRAG_RELAXABLE
;
6507 fragP
->tc_frag_data
.opcode
= insn
.opcode
;
6508 fragP
->tc_frag_data
.insn
= insn
.insn
;
6511 /* In original, we don't relax the instruction with label on it,
6512 but this may cause some redundant nop16. Therefore, tag this
6513 relaxable instruction and relax it carefully. */
6515 fragP
->tc_frag_data
.flag
|= NDS32_FRAG_LABEL
;
6517 if (insn
.opcode
->isize
== 4)
6518 bfd_putb16 (insn_16
, out
);
6519 else if (insn
.opcode
->isize
== 2)
6520 bfd_putb16 (insn
.insn
, out
);
6525 else if ((verbatim
|| !relaxing
) && optimize
&& label
)
6527 /* This instruction is with label. */
6529 out
= frag_var (rs_machine_dependent
, insn
.opcode
->isize
,
6530 0, 0, NULL
, 0, NULL
);
6531 /* If this instruction is branch target, it is not relaxable. */
6532 fragP
->tc_frag_data
.flag
= NDS32_FRAG_LABEL
;
6533 fragP
->tc_frag_data
.opcode
= insn
.opcode
;
6534 fragP
->tc_frag_data
.insn
= insn
.insn
;
6535 fragP
->fr_fix
+= insn
.opcode
->isize
;
6536 if (insn
.opcode
->isize
== 4)
6538 exp
.X_op
= O_symbol
;
6539 exp
.X_add_symbol
= abs_section_sym
;
6540 exp
.X_add_number
= 0;
6541 fixP
= fix_new_exp (fragP
, fragP
->fr_fix
- 4, 0, &exp
,
6542 0, BFD_RELOC_NDS32_LABEL
);
6544 fragP
->tc_frag_data
.flag
= NDS32_FRAG_ALIGN
;
6548 out
= frag_more (insn
.opcode
->isize
);
6550 if (insn
.opcode
->isize
== 4)
6551 bfd_putb32 (insn
.insn
, out
);
6552 else if (insn
.opcode
->isize
== 2)
6553 bfd_putb16 (insn
.insn
, out
);
6555 dwarf2_emit_insn (insn
.opcode
->isize
);
6557 /* Compiler generating code and user assembly pseudo load-store, insert
6559 expressionS
*pexp
= insn
.info
;
6560 fixP
= nds32_elf_record_fixup_exp (fragP
, str
, fld
, pexp
, out
, &insn
);
6561 /* Build relaxation pattern when relaxing is enable. */
6563 nds32_elf_build_relax_relation (fixP
, pexp
, out
, &insn
, fragP
, fld
,
6569 /* md_macro_start */
6572 nds32_macro_start (void)
6579 nds32_macro_info (void *info ATTRIBUTE_UNUSED
)
6586 nds32_macro_end (void)
6590 /* GAS will call this function with one argument, an expressionS pointer, for
6591 any expression that can not be recognized. When the function is called,
6592 input_line_pointer will point to the start of the expression. */
6595 md_operand (expressionS
*expressionP
)
6597 if (*input_line_pointer
== '#')
6599 input_line_pointer
++;
6600 expression (expressionP
);
6604 /* GAS will call this function for each section at the end of the assembly, to
6605 permit the CPU back end to adjust the alignment of a section. The function
6606 must take two arguments, a segT for the section and a valueT for the size of
6607 the section, and return a valueT for the rounded size. */
6610 md_section_align (segT segment
, valueT size
)
6612 int align
= bfd_get_section_alignment (stdoutput
, segment
);
6614 return ((size
+ (1 << align
) - 1) & ((valueT
) -1 << align
));
6617 /* GAS will call this function when a symbol table lookup fails, before it
6618 creates a new symbol. Typically this would be used to supply symbols whose
6619 name or value changes dynamically, possibly in a context sensitive way.
6620 Predefined symbols with fixed values, such as register names or condition
6621 codes, are typically entered directly into the symbol table when md_begin
6622 is called. One argument is passed, a char * for the symbol. */
6625 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
6631 nds32_calc_branch_offset (segT segment
, fragS
*fragP
,
6632 long stretch ATTRIBUTE_UNUSED
,
6633 relax_info_t
*relax_info
,
6634 enum nds32_br_range branch_range_type
)
6636 struct nds32_opcode
*opcode
= fragP
->tc_frag_data
.opcode
;
6637 symbolS
*branch_symbol
= fragP
->fr_symbol
;
6638 offsetT branch_offset
= fragP
->fr_offset
;
6639 offsetT branch_target_address
;
6640 offsetT branch_insn_address
;
6643 if ((S_GET_SEGMENT (branch_symbol
) != segment
)
6644 || S_IS_WEAK (branch_symbol
))
6646 /* The symbol is not in the SEGMENT. It could be far far away. */
6647 offset
= 0x80000000;
6651 /* Calculate symbol-to-instruction offset. */
6652 branch_target_address
= S_GET_VALUE (branch_symbol
) + branch_offset
;
6653 /* If the destination symbol is beyond current frag address,
6654 STRETCH will take effect to symbol's position. */
6655 if (S_GET_VALUE (branch_symbol
) > fragP
->fr_address
)
6656 branch_target_address
+= stretch
;
6658 branch_insn_address
= fragP
->fr_address
+ fragP
->fr_fix
;
6659 branch_insn_address
-= opcode
->isize
;
6661 /* Update BRANCH_INSN_ADDRESS to relaxed position. */
6662 branch_insn_address
+= (relax_info
->relax_code_size
[branch_range_type
]
6663 - relax_info
->relax_branch_isize
[branch_range_type
]);
6665 offset
= branch_target_address
- branch_insn_address
;
6671 static enum nds32_br_range
6672 nds32_convert_to_range_type (long offset
)
6674 enum nds32_br_range range_type
;
6676 if (-(0x100) <= offset
&& offset
< 0x100) /* 256 bytes */
6677 range_type
= BR_RANGE_S256
;
6678 else if (-(0x4000) <= offset
&& offset
< 0x4000) /* 16K bytes */
6679 range_type
= BR_RANGE_S16K
;
6680 else if (-(0x10000) <= offset
&& offset
< 0x10000) /* 64K bytes */
6681 range_type
= BR_RANGE_S64K
;
6682 else if (-(0x1000000) <= offset
&& offset
< 0x1000000) /* 16M bytes */
6683 range_type
= BR_RANGE_S16M
;
6685 range_type
= BR_RANGE_U4G
;
6690 /* Set instruction register mask. */
6693 nds32_elf_get_set_cond (relax_info_t
*relax_info
, int offset
, uint32_t *insn
,
6694 uint32_t ori_insn
, int range
)
6696 nds32_cond_field_t
*cond_fields
= relax_info
->cond_field
;
6697 nds32_cond_field_t
*code_seq_cond
= relax_info
->relax_code_condition
[range
];
6701 /* The instruction has conditions. Collect condition values. */
6702 while (code_seq_cond
[i
].bitmask
!= 0)
6704 if (offset
== code_seq_cond
[i
].offset
)
6706 mask
= (ori_insn
>> cond_fields
[i
].bitpos
) & cond_fields
[i
].bitmask
;
6708 if (cond_fields
[i
].signed_extend
)
6709 mask
= (mask
^ ((cond_fields
[i
].bitmask
+ 1) >> 1)) -
6710 ((cond_fields
[i
].bitmask
+ 1) >> 1);
6711 *insn
|= (mask
& code_seq_cond
[i
].bitmask
) << code_seq_cond
[i
].bitpos
;
6718 nds32_relax_branch_instructions (segT segment
, fragS
*fragP
,
6719 long stretch ATTRIBUTE_UNUSED
,
6722 enum nds32_br_range branch_range_type
;
6723 struct nds32_opcode
*opcode
= fragP
->tc_frag_data
.opcode
;
6725 enum nds32_br_range real_range_type
;
6727 relax_info_t
*relax_info
;
6734 int code_seq_offset
;
6736 /* Replace with gas_assert (fragP->fr_symbol != NULL); */
6737 if (fragP
->fr_symbol
== NULL
)
6740 /* If frag_var is not enough room, the previous frag is fr_full and with
6741 opcode. The new one is rs_dependent but without opcode. */
6745 /* Use U4G mode for b and bal in verbatim mode because lto may combine
6746 functions into a file. And order the file in the last when linking.
6747 Once there is multiple definition, the same function will be kicked.
6748 This may cause relocation truncated error. */
6749 if (verbatim
&& !nds32_pic
6750 && (strcmp (opcode
->opcode
, "j") == 0
6751 || strcmp (opcode
->opcode
, "jal") == 0))
6753 fragP
->fr_subtype
= BR_RANGE_U4G
;
6760 relax_info
= hash_find (nds32_relax_info_hash
, opcode
->opcode
);
6762 if (relax_info
== NULL
)
6767 branch_range_type
= relax_info
->br_range
;
6772 branch_range_type
= fragP
->fr_subtype
;
6773 i
= branch_range_type
;
6776 offset
= nds32_calc_branch_offset (segment
, fragP
, stretch
,
6777 relax_info
, branch_range_type
);
6779 real_range_type
= nds32_convert_to_range_type (offset
);
6781 /* If actual range is equal to instruction jump range, do nothing. */
6782 if (real_range_type
== branch_range_type
)
6784 fragP
->fr_subtype
= real_range_type
;
6788 /* Find out proper relaxation code sequence. */
6789 for (; i
< BR_RANGE_NUM
; i
++)
6791 if (real_range_type
<= (unsigned int) i
)
6794 diff
= relax_info
->relax_code_size
[i
] - opcode
->isize
;
6795 else if (real_range_type
< (unsigned int) i
)
6796 diff
= relax_info
->relax_code_size
[real_range_type
]
6797 - relax_info
->relax_code_size
[branch_range_type
];
6799 diff
= relax_info
->relax_code_size
[i
]
6800 - relax_info
->relax_code_size
[branch_range_type
];
6802 /* If the instruction could be converted to 16-bits,
6803 minus the difference. */
6804 code_seq_offset
= 0;
6807 code_seq_size
= relax_info
->relax_code_size
[i
];
6808 code_seq
= relax_info
->relax_code_seq
[i
];
6809 while (code_seq_offset
< code_seq_size
)
6812 if (insn
& 0x80000000) /* 16-bits instruction. */
6816 else /* 32-bits instruction. */
6820 while (relax_info
->relax_fixup
[i
][k
].size
!=0
6821 && relax_info
->relax_fixup
[i
][k
].offset
< code_seq_offset
)
6825 code_seq_offset
+= insn_size
;
6829 /* Update fr_subtype to new NDS32_BR_RANGE. */
6830 fragP
->fr_subtype
= real_range_type
;
6835 return diff
+ adjust
;
6838 /* Adjust relaxable frag till current frag. */
6841 nds32_adjust_relaxable_frag (fragS
*startP
, fragS
*fragP
)
6844 if (startP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
)
6849 startP
->tc_frag_data
.flag
^= NDS32_FRAG_RELAXED
;
6853 startP
= startP
->fr_next
;
6856 startP
->fr_address
+= adj
;
6857 if (startP
== fragP
)
6865 nds32_get_align (addressT address
, int align
)
6867 addressT mask
, new_address
;
6869 mask
= ~((addressT
) (~0) << align
);
6870 new_address
= (address
+ mask
) & (~mask
);
6871 return (new_address
- address
);
6874 /* Check the prev_frag is legal. */
6876 invalid_prev_frag (fragS
* fragP
, fragS
**prev_frag
, bfd_boolean relax
)
6879 fragS
*frag_start
= *prev_frag
;
6881 if (!frag_start
|| !relax
)
6884 if (frag_start
->last_fr_address
>= fragP
->last_fr_address
)
6890 fragS
*frag_t
= *prev_frag
;
6891 while (frag_t
!= fragP
)
6893 if (frag_t
->fr_type
== rs_align
6894 || frag_t
->fr_type
== rs_align_code
6895 || frag_t
->fr_type
== rs_align_test
)
6897 /* Relax instruction can not walk across label. */
6898 if (frag_t
->tc_frag_data
.flag
& NDS32_FRAG_LABEL
)
6903 /* Relax previous relaxable to align rs_align frag. */
6904 address
= frag_t
->fr_address
+ frag_t
->fr_fix
;
6905 addressT offset
= nds32_get_align (address
, (int) frag_t
->fr_offset
);
6908 /* If there is label on the prev_frag, check if it is aligned. */
6909 if (!((*prev_frag
)->tc_frag_data
.flag
& NDS32_FRAG_LABEL
)
6910 || (((*prev_frag
)->fr_address
+ (*prev_frag
)->fr_fix
- 2 )
6912 nds32_adjust_relaxable_frag (*prev_frag
, frag_t
);
6917 frag_t
= frag_t
->fr_next
;
6920 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_ALIGN
)
6922 address
= fragP
->fr_address
;
6923 addressT offset
= nds32_get_align (address
, 2);
6926 /* If there is label on the prev_frag, check if it is aligned. */
6927 if (!((*prev_frag
)->tc_frag_data
.flag
& NDS32_FRAG_LABEL
)
6928 || (((*prev_frag
)->fr_address
+ (*prev_frag
)->fr_fix
- 2 )
6930 nds32_adjust_relaxable_frag (*prev_frag
, fragP
);
6940 nds32_relax_frag (segT segment
, fragS
*fragP
, long stretch ATTRIBUTE_UNUSED
)
6942 /* Currently, there are two kinds of relaxation in nds32 assembler.
6944 2. relax for 32-bits to 16-bits */
6946 static fragS
*prev_frag
= NULL
;
6949 invalid_prev_frag (fragP
, &prev_frag
, TRUE
);
6951 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_BRANCH
)
6952 adjust
= nds32_relax_branch_instructions (segment
, fragP
, stretch
, 0);
6953 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_LABEL
)
6955 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXABLE
6956 && (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
) == 0)
6957 /* Here is considered relaxed case originally. But it may cause
6958 an endless loop when relaxing. Once the instruction is relaxed,
6959 it can not be undone. */
6965 /* This function returns an initial guess of the length by which a fragment
6966 must grow to hold a branch to reach its destination. Also updates
6967 fr_type/fr_subtype as necessary.
6969 It is called just before doing relaxation. Any symbol that is now undefined
6970 will not become defined. The guess for fr_var is ACTUALLY the growth beyond
6971 fr_fix. Whatever we do to grow fr_fix or fr_var contributes to our returned
6972 value. Although it may not be explicit in the frag, pretend fr_var starts
6976 md_estimate_size_before_relax (fragS
*fragP
, segT segment
)
6978 /* Currently, there are two kinds of relaxation in nds32 assembler.
6980 2. relax for 32-bits to 16-bits */
6982 /* Save previous relaxable frag. */
6983 static fragS
*prev_frag
= NULL
;
6986 invalid_prev_frag (fragP
, &prev_frag
, FALSE
);
6988 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_BRANCH
)
6989 adjust
= nds32_relax_branch_instructions (segment
, fragP
, 0, 1);
6990 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_LABEL
)
6992 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
)
6994 else if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXABLE
)
7000 /* GAS will call this for each rs_machine_dependent fragment. The instruction
7001 is completed using the data from the relaxation pass. It may also create any
7002 necessary relocations.
7004 *FRAGP has been relaxed to its final size, and now needs to have the bytes
7005 inside it modified to conform to the new size. It is called after relaxation
7008 fragP->fr_type == rs_machine_dependent.
7009 fragP->fr_subtype is the subtype of what the address relaxed to. */
7012 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, segT sec
, fragS
*fragP
)
7014 /* Convert branch relaxation instructions. */
7015 symbolS
*branch_symbol
= fragP
->fr_symbol
;
7016 offsetT branch_offset
= fragP
->fr_offset
;
7017 enum nds32_br_range branch_range_type
= fragP
->fr_subtype
;
7018 struct nds32_opcode
*opcode
= fragP
->tc_frag_data
.opcode
;
7019 uint32_t origin_insn
= fragP
->tc_frag_data
.insn
;
7020 relax_info_t
*relax_info
;
7023 int addend ATTRIBUTE_UNUSED
;
7024 offsetT branch_target_address
, branch_insn_address
;
7029 int code_size
, insn_size
, offset
, fixup_size
;
7030 int buf_offset
, pcrel
;
7033 nds32_relax_fixup_info_t fixup_info
[MAX_RELAX_FIX
];
7034 /* Save the 1st instruction is converted to 16 bit or not. */
7035 unsigned int branch_size
;
7036 enum bfd_reloc_code_real final_r_type
;
7038 /* Replace with gas_assert (branch_symbol != NULL); */
7039 if (branch_symbol
== NULL
&& !(fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
))
7042 /* If frag_var is not enough room, the previous frag is fr_full and with
7043 opcode. The new one is rs_dependent but without opcode. */
7047 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXABLE_BRANCH
)
7049 relax_info
= hash_find (nds32_relax_info_hash
, opcode
->opcode
);
7051 if (relax_info
== NULL
)
7055 while (i
< BR_RANGE_NUM
7056 && relax_info
->relax_code_size
[i
]
7057 != (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
? 4 : 2))
7060 if (i
>= BR_RANGE_NUM
)
7061 as_bad ("Internal error: Cannot find relocation of"
7062 "relaxable branch.");
7064 exp
.X_op
= O_symbol
;
7065 exp
.X_add_symbol
= branch_symbol
;
7066 exp
.X_add_number
= branch_offset
;
7067 pcrel
= ((relax_info
->relax_fixup
[i
][0].ramp
& NDS32_PCREL
) != 0) ? 1 : 0;
7068 fr_where
= fragP
->fr_fix
- 2;
7069 fixP
= fix_new_exp (fragP
, fr_where
, relax_info
->relax_fixup
[i
][0].size
,
7070 &exp
, pcrel
, relax_info
->relax_fixup
[i
][0].r_type
);
7071 fixP
->fx_addnumber
= fixP
->fx_offset
;
7073 if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
)
7075 insn_16
= fragP
->tc_frag_data
.insn
;
7076 nds32_convert_16_to_32 (stdoutput
, insn_16
, &insn
);
7077 fr_buffer
= fragP
->fr_literal
+ fr_where
;
7079 exp
.X_op
= O_symbol
;
7080 exp
.X_add_symbol
= abs_section_sym
;
7081 exp
.X_add_number
= 0;
7082 fix_new_exp (fragP
, fr_where
, 4,
7083 &exp
, 0, BFD_RELOC_NDS32_INSN16
);
7084 number_to_chars_bigendian (fr_buffer
, insn
, 4);
7087 else if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_RELAXED
)
7089 if (fragP
->tc_frag_data
.opcode
->isize
== 2)
7091 insn_16
= fragP
->tc_frag_data
.insn
;
7092 nds32_convert_16_to_32 (stdoutput
, insn_16
, &insn
);
7095 insn
= fragP
->tc_frag_data
.insn
;
7097 fr_where
= fragP
->fr_fix
- 4;
7098 fr_buffer
= fragP
->fr_literal
+ fr_where
;
7099 exp
.X_op
= O_symbol
;
7100 exp
.X_add_symbol
= abs_section_sym
;
7101 exp
.X_add_number
= 0;
7102 fix_new_exp (fragP
, fr_where
, 4, &exp
, 0,
7103 BFD_RELOC_NDS32_INSN16
);
7104 number_to_chars_bigendian (fr_buffer
, insn
, 4);
7106 else if (fragP
->tc_frag_data
.flag
& NDS32_FRAG_BRANCH
)
7108 /* Branch instruction adjust and append relocations. */
7109 relax_info
= hash_find (nds32_relax_info_hash
, opcode
->opcode
);
7111 if (relax_info
== NULL
)
7114 fr_where
= fragP
->fr_fix
- opcode
->isize
;
7115 fr_buffer
= fragP
->fr_literal
+ fr_where
;
7117 if ((S_GET_SEGMENT (branch_symbol
) != sec
)
7118 || S_IS_WEAK (branch_symbol
))
7120 if (fragP
->fr_offset
& 3)
7121 as_warn (_("Addend to unresolved symbol is not on word boundary."));
7126 /* Calculate symbol-to-instruction offset. */
7127 branch_target_address
= S_GET_VALUE (branch_symbol
) + branch_offset
;
7128 branch_insn_address
= fragP
->fr_address
+ fr_where
;
7129 addend
= (branch_target_address
- branch_insn_address
) >> 1;
7132 code_size
= relax_info
->relax_code_size
[branch_range_type
];
7133 code_seq
= relax_info
->relax_code_seq
[branch_range_type
];
7135 memcpy (fixup_info
, relax_info
->relax_fixup
[branch_range_type
],
7136 sizeof (fixup_info
));
7141 offset
= 0; /* code_seq offset */
7142 buf_offset
= 0; /* fr_buffer offset */
7143 while (offset
< code_size
)
7146 if (insn
& 0x80000000) /* 16-bits instruction. */
7148 insn
= (insn
>> 16) & 0xFFFF;
7151 else /* 32-bits instruction. */
7156 nds32_elf_get_set_cond (relax_info
, offset
, &insn
,
7157 origin_insn
, branch_range_type
);
7159 /* Try to convert to 16-bits instruction. Currently, only the first
7160 instruction in pattern can be converted. EX: bnez sethi ori jr,
7161 only bnez can be converted to 16 bit and ori can't. */
7163 while (fixup_info
[k
].size
!= 0
7164 && relax_info
->relax_fixup
[branch_range_type
][k
].offset
< offset
)
7167 number_to_chars_bigendian (fr_buffer
+ buf_offset
, insn
, insn_size
);
7168 buf_offset
+= insn_size
;
7170 offset
+= insn_size
;
7175 exp
.X_op
= O_symbol
;
7177 for (i
= 0; fixup_info
[i
].size
!= 0; i
++)
7179 fixup_size
= fixup_info
[i
].size
;
7180 pcrel
= ((fixup_info
[i
].ramp
& NDS32_PCREL
) != 0) ? 1 : 0;
7182 if ((fixup_info
[i
].ramp
& NDS32_CREATE_LABEL
) != 0)
7184 /* This is a reverse branch. */
7185 exp
.X_add_symbol
= symbol_temp_new (sec
, 0, fragP
->fr_next
);
7186 exp
.X_add_number
= 0;
7188 else if ((fixup_info
[i
].ramp
& NDS32_PTR
) != 0)
7190 /* This relocation has to point to another instruction. */
7191 branch_size
= fr_where
+ code_size
- 4;
7192 exp
.X_add_symbol
= symbol_temp_new (sec
, branch_size
, fragP
);
7193 exp
.X_add_number
= 0;
7195 else if ((fixup_info
[i
].ramp
& NDS32_ABS
) != 0)
7197 /* This is a tag relocation. */
7198 exp
.X_add_symbol
= abs_section_sym
;
7199 exp
.X_add_number
= 0;
7201 else if ((fixup_info
[i
].ramp
& NDS32_INSN16
) != 0)
7205 /* This is a tag relocation. */
7206 exp
.X_add_symbol
= abs_section_sym
;
7207 exp
.X_add_number
= 0;
7211 exp
.X_add_symbol
= branch_symbol
;
7212 exp
.X_add_number
= branch_offset
;
7215 if (fixup_info
[i
].r_type
!= 0)
7217 final_r_type
= fixup_info
[i
].r_type
;
7218 fixP
= fix_new_exp (fragP
, fr_where
+ fixup_info
[i
].offset
,
7219 fixup_size
, &exp
, pcrel
,
7221 fixP
->fx_addnumber
= fixP
->fx_offset
;
7225 fragP
->fr_fix
= fr_where
+ buf_offset
;
7229 /* tc_frob_file_before_fix */
7232 nds32_frob_file_before_fix (void)
7237 nds32_relaxable_section (asection
*sec
)
7239 return ((sec
->flags
& SEC_DEBUGGING
) == 0
7240 && strcmp (sec
->name
, ".eh_frame") != 0);
7243 /* TC_FORCE_RELOCATION */
7245 nds32_force_relocation (fixS
* fix
)
7247 switch (fix
->fx_r_type
)
7249 case BFD_RELOC_NDS32_INSN16
:
7250 case BFD_RELOC_NDS32_LABEL
:
7251 case BFD_RELOC_NDS32_LONGCALL1
:
7252 case BFD_RELOC_NDS32_LONGCALL2
:
7253 case BFD_RELOC_NDS32_LONGCALL3
:
7254 case BFD_RELOC_NDS32_LONGJUMP1
:
7255 case BFD_RELOC_NDS32_LONGJUMP2
:
7256 case BFD_RELOC_NDS32_LONGJUMP3
:
7257 case BFD_RELOC_NDS32_LOADSTORE
:
7258 case BFD_RELOC_NDS32_9_FIXED
:
7259 case BFD_RELOC_NDS32_15_FIXED
:
7260 case BFD_RELOC_NDS32_17_FIXED
:
7261 case BFD_RELOC_NDS32_25_FIXED
:
7262 case BFD_RELOC_NDS32_9_PCREL
:
7263 case BFD_RELOC_NDS32_15_PCREL
:
7264 case BFD_RELOC_NDS32_17_PCREL
:
7265 case BFD_RELOC_NDS32_WORD_9_PCREL
:
7266 case BFD_RELOC_NDS32_10_UPCREL
:
7267 case BFD_RELOC_NDS32_25_PCREL
:
7268 case BFD_RELOC_NDS32_MINUEND
:
7269 case BFD_RELOC_NDS32_SUBTRAHEND
:
7275 case BFD_RELOC_NDS32_DIFF_ULEB128
:
7276 /* Linker should handle difference between two symbol. */
7277 return fix
->fx_subsy
!= NULL
7278 && nds32_relaxable_section (S_GET_SEGMENT (fix
->fx_addsy
));
7281 as_bad ("Double word for difference between two symbols "
7282 "is not supported across relaxation.");
7287 if (generic_force_reloc (fix
))
7290 return fix
->fx_pcrel
;
7293 /* TC_VALIDATE_FIX_SUB */
7296 nds32_validate_fix_sub (fixS
*fix
, segT add_symbol_segment
)
7298 segT sub_symbol_segment
;
7300 /* This code is referred from Xtensa. Check their implementation for
7303 /* Make sure both symbols are in the same segment, and that segment is
7304 "normal" and relaxable. */
7305 sub_symbol_segment
= S_GET_SEGMENT (fix
->fx_subsy
);
7306 return (sub_symbol_segment
== add_symbol_segment
7307 && add_symbol_segment
!= undefined_section
);
7311 md_number_to_chars (char *buf
, valueT val
, int n
)
7313 if (target_big_endian
)
7314 number_to_chars_bigendian (buf
, val
, n
);
7316 number_to_chars_littleendian (buf
, val
, n
);
7319 /* This function is called to convert an ASCII string into a floating point
7320 value in format used by the CPU. */
7323 md_atof (int type
, char *litP
, int *sizeP
)
7327 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
7346 return _("Bad call to md_atof()");
7349 t
= atof_ieee (input_line_pointer
, type
, words
);
7351 input_line_pointer
= t
;
7352 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
7354 if (target_big_endian
)
7356 for (i
= 0; i
< prec
; i
++)
7358 md_number_to_chars (litP
, (valueT
) words
[i
],
7359 sizeof (LITTLENUM_TYPE
));
7360 litP
+= sizeof (LITTLENUM_TYPE
);
7365 for (i
= prec
- 1; i
>= 0; i
--)
7367 md_number_to_chars (litP
, (valueT
) words
[i
],
7368 sizeof (LITTLENUM_TYPE
));
7369 litP
+= sizeof (LITTLENUM_TYPE
);
7376 /* md_elf_section_change_hook */
7379 nds32_elf_section_change_hook (void)
7386 nds32_cleanup (void)
7390 /* This function is used to scan leb128 subtraction expressions,
7391 and insert fixups for them.
7393 e.g., .leb128 .L1 - .L0
7395 These expressions are heavily used in debug information or
7396 exception tables. Because relaxation will change code size,
7397 we must resolve them in link time. */
7400 nds32_insert_leb128_fixes (bfd
*abfd ATTRIBUTE_UNUSED
,
7401 asection
*sec
, void *xxx ATTRIBUTE_UNUSED
)
7403 segment_info_type
*seginfo
= seg_info (sec
);
7406 subseg_set (sec
, 0);
7408 for (fragP
= seginfo
->frchainP
->frch_root
;
7409 fragP
; fragP
= fragP
->fr_next
)
7413 /* Only unsigned leb128 can be handle. */
7414 if (fragP
->fr_type
!= rs_leb128
|| fragP
->fr_subtype
!= 0
7415 || fragP
->fr_symbol
== NULL
)
7418 exp
= symbol_get_value_expression (fragP
->fr_symbol
);
7420 if (exp
->X_op
!= O_subtract
)
7423 fix_new_exp (fragP
, fragP
->fr_fix
, 0,
7424 exp
, 0, BFD_RELOC_NDS32_DIFF_ULEB128
);
7429 nds32_insert_relax_entry (bfd
*abfd ATTRIBUTE_UNUSED
, asection
*sec
,
7430 void *xxx ATTRIBUTE_UNUSED
)
7432 segment_info_type
*seginfo
;
7438 seginfo
= seg_info (sec
);
7439 if (!seginfo
|| !symbol_rootP
|| !subseg_text_p (sec
) || sec
->size
== 0)
7442 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= fixp
->fx_next
)
7446 if (!fixp
&& !verbatim
&& ict_flag
== ICT_NONE
)
7449 subseg_change (sec
, 0);
7451 /* Set RELAX_ENTRY flags for linker. */
7452 fragP
= seginfo
->frchainP
->frch_root
;
7453 exp
.X_op
= O_symbol
;
7454 exp
.X_add_symbol
= abs_section_sym
;
7455 exp
.X_add_number
= 0;
7456 if (!enable_relax_relocs
)
7457 exp
.X_add_number
|= R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG
;
7460 /* These flags are only enabled when global relax is enabled.
7461 Maybe we can check DISABLE_RELAX_FLAG at link-time,
7462 so we set them anyway. */
7464 exp
.X_add_number
|= R_NDS32_RELAX_ENTRY_VERBATIM_FLAG
;
7465 if (ict_flag
== ICT_SMALL
)
7466 exp
.X_add_number
|= R_NDS32_RELAX_ENTRY_ICT_SMALL
;
7467 else if (ict_flag
== ICT_LARGE
)
7468 exp
.X_add_number
|= R_NDS32_RELAX_ENTRY_ICT_LARGE
;
7471 exp
.X_add_number
|= R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG
;
7472 if (optimize_for_space
)
7473 exp
.X_add_number
|= R_NDS32_RELAX_ENTRY_OPTIMIZE_FOR_SPACE_FLAG
;
7475 fixP
= fix_new_exp (fragP
, 0, 0, &exp
, 0, BFD_RELOC_NDS32_RELAX_ENTRY
);
7476 fixP
->fx_no_overflow
= 1;
7479 /* Analysis relax hint and insert suitable relocation pattern. */
7482 nds32_elf_analysis_relax_hint (void)
7484 hash_traverse (nds32_hint_hash
, nds32_elf_append_relax_relocs
);
7488 nds32_elf_insert_final_frag (void)
7490 struct frchain
*frchainP
;
7497 for (s
= stdoutput
->sections
; s
; s
= s
->next
)
7499 segment_info_type
*seginfo
= seg_info (s
);
7503 for (frchainP
= seginfo
->frchainP
; frchainP
!= NULL
;
7504 frchainP
= frchainP
->frch_next
)
7506 subseg_set (s
, frchainP
->frch_subseg
);
7508 if (subseg_text_p (now_seg
))
7511 frag_var (rs_machine_dependent
, 2, /* Max size. */
7512 0, /* VAR is un-used. */ 0, NULL
, 0, NULL
);
7513 fragP
->tc_frag_data
.flag
|= NDS32_FRAG_FINAL
;
7522 nds32_elf_insert_final_frag ();
7523 nds32_elf_analysis_relax_hint ();
7524 bfd_map_over_sections (stdoutput
, nds32_insert_leb128_fixes
, NULL
);
7527 /* Implement md_allow_local_subtract. */
7530 nds32_allow_local_subtract (expressionS
*expr_l ATTRIBUTE_UNUSED
,
7531 expressionS
*expr_r ATTRIBUTE_UNUSED
,
7532 segT sec ATTRIBUTE_UNUSED
)
7534 /* Don't allow any subtraction, because relax may change the code. */
7538 /* Sort relocation by address.
7540 We didn't use qsort () in stdlib, because quick-sort is not a stable
7541 sorting algorithm. Relocations at the same address (r_offset) must keep
7542 their relative order. For example, RELAX_ENTRY must be the very first
7545 Currently, this function implements insertion-sort. */
7548 compar_relent (const void *lhs
, const void *rhs
)
7550 const arelent
**l
= (const arelent
**) lhs
;
7551 const arelent
**r
= (const arelent
**) rhs
;
7553 if ((*l
)->address
> (*r
)->address
)
7555 else if ((*l
)->address
== (*r
)->address
)
7561 /* SET_SECTION_RELOCS ()
7563 Although this macro is originally used to set a relocation for each section,
7564 we use it to sort relocations in the same section by the address of the
7568 nds32_set_section_relocs (asection
*sec
, arelent
** relocs ATTRIBUTE_UNUSED
,
7569 unsigned int n ATTRIBUTE_UNUSED
)
7571 bfd
*abfd ATTRIBUTE_UNUSED
= sec
->owner
;
7572 if (bfd_get_section_flags (abfd
, sec
) & (flagword
) SEC_RELOC
)
7573 nds32_insertion_sort (sec
->orelocation
, sec
->reloc_count
,
7574 sizeof (arelent
**), compar_relent
);
7578 nds32_pcrel_from_section (fixS
*fixP
, segT sec ATTRIBUTE_UNUSED
)
7580 if (fixP
->fx_addsy
== NULL
|| !S_IS_DEFINED (fixP
->fx_addsy
)
7581 || S_IS_EXTERNAL (fixP
->fx_addsy
) || S_IS_WEAK (fixP
->fx_addsy
))
7583 /* Let linker resolve undefined symbols. */
7587 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
7590 /* md_post_relax_hook ()
7591 Insert relax entry relocation into sections. */
7594 nds32_post_relax_hook (void)
7596 bfd_map_over_sections (stdoutput
, nds32_insert_relax_entry
, NULL
);
7599 /* tc_fix_adjustable ()
7601 Return whether this symbol (fixup) can be replaced with
7605 nds32_fix_adjustable (fixS
*fixP
)
7607 switch (fixP
->fx_r_type
)
7609 case BFD_RELOC_NDS32_WORD_9_PCREL
:
7610 case BFD_RELOC_NDS32_9_PCREL
:
7611 case BFD_RELOC_NDS32_15_PCREL
:
7612 case BFD_RELOC_NDS32_17_PCREL
:
7613 case BFD_RELOC_NDS32_25_PCREL
:
7614 case BFD_RELOC_NDS32_HI20
:
7615 case BFD_RELOC_NDS32_LO12S0
:
7619 case BFD_RELOC_NDS32_PTR
:
7620 case BFD_RELOC_NDS32_LONGCALL4
:
7621 case BFD_RELOC_NDS32_LONGCALL5
:
7622 case BFD_RELOC_NDS32_LONGCALL6
:
7623 case BFD_RELOC_NDS32_LONGJUMP4
:
7624 case BFD_RELOC_NDS32_LONGJUMP5
:
7625 case BFD_RELOC_NDS32_LONGJUMP6
:
7626 case BFD_RELOC_NDS32_LONGJUMP7
:
7633 /* elf_tc_final_processing */
7636 elf_nds32_final_processing (void)
7638 /* An FPU_COM instruction is found without previous non-FPU_COM
7641 && !(nds32_elf_flags
& (E_NDS32_HAS_FPU_INST
| E_NDS32_HAS_FPU_DP_INST
)))
7643 /* Since only FPU_COM instructions are used and no other FPU instructions
7644 are used. The nds32_elf_flags will be decided by the enabled options
7645 by command line or default configuration. */
7646 if (nds32_fpu_dp_ext
|| nds32_fpu_sp_ext
)
7648 nds32_elf_flags
|= nds32_fpu_dp_ext
? E_NDS32_HAS_FPU_DP_INST
: 0;
7649 nds32_elf_flags
|= nds32_fpu_sp_ext
? E_NDS32_HAS_FPU_INST
: 0;
7653 /* Should never here. */
7654 as_bad (_("Used FPU instructions requires enabling FPU extension"));
7658 if (nds32_elf_flags
& (E_NDS32_HAS_FPU_INST
| E_NDS32_HAS_FPU_DP_INST
))
7660 /* Single/double FPU has been used, set FPU register config. */
7661 /* We did not check the actual number of register used. We may
7662 want to do it while assemble. */
7663 nds32_elf_flags
&= ~E_NDS32_FPU_REG_CONF
;
7664 nds32_elf_flags
|= (nds32_freg
<< E_NDS32_FPU_REG_CONF_SHIFT
);
7668 nds32_elf_flags
|= E_NDS32_HAS_PIC
;
7671 nds32_elf_flags
|= E_NDS32_HAS_REDUCED_REGS
;
7673 nds32_elf_flags
|= (E_NDS32_ELF_VER_1_4
| nds32_abi
);
7674 elf_elfheader (stdoutput
)->e_flags
|= nds32_elf_flags
;
7677 /* Implement md_apply_fix. Apply the fix-up or transform the fix-up for
7678 later relocation generation. */
7681 nds32_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
7683 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
7684 bfd_vma value
= *valP
;
7686 if (fixP
->fx_r_type
< BFD_RELOC_UNUSED
7687 && fixP
->fx_r_type
> BFD_RELOC_NONE
7688 && fixP
->fx_r_type
!= BFD_RELOC_NDS32_DIFF_ULEB128
)
7690 /* In our old nds32 binutils, it must convert relocations which is
7691 generated by CGEN. However, it does not have to consider this anymore.
7692 In current, it only deal with data relocations which enum
7693 is smaller than BFD_RELOC_NONE and BFD_RELOC_NDS32_DIFF_ULEB128.
7694 It is believed that we can construct a better mechanism to
7695 deal with the whole relocation issue in nds32 target
7696 without using CGEN. */
7697 fixP
->fx_addnumber
= value
;
7698 fixP
->tc_fix_data
= NULL
;
7700 /* Transform specific relocations here for later relocation generation.
7701 Tag tls data for linker. */
7702 switch (fixP
->fx_r_type
)
7704 case BFD_RELOC_NDS32_DATA
:
7705 /* This reloc is obselete, we do not need it so far. */
7708 case BFD_RELOC_NDS32_TPOFF
:
7709 case BFD_RELOC_NDS32_TLS_LE_HI20
:
7710 case BFD_RELOC_NDS32_TLS_LE_LO12
:
7711 case BFD_RELOC_NDS32_TLS_LE_ADD
:
7712 case BFD_RELOC_NDS32_TLS_LE_LS
:
7713 case BFD_RELOC_NDS32_GOTTPOFF
:
7714 case BFD_RELOC_NDS32_TLS_IE_HI20
:
7715 case BFD_RELOC_NDS32_TLS_IE_LO12S2
:
7716 case BFD_RELOC_NDS32_TLS_DESC_HI20
:
7717 case BFD_RELOC_NDS32_TLS_DESC_LO12
:
7718 case BFD_RELOC_NDS32_TLS_IE_LO12
:
7719 case BFD_RELOC_NDS32_TLS_IEGP_HI20
:
7720 case BFD_RELOC_NDS32_TLS_IEGP_LO12
:
7721 case BFD_RELOC_NDS32_TLS_IEGP_LO12S2
:
7722 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
7730 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
7733 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
7735 /* HOW DIFF RELOCATION WORKS.
7737 First of all, this relocation is used to calculate the distance
7738 between two symbols in the SAME section. It is used for jump-
7739 table, debug information, exception table, et al. Therefore,
7740 it is a unsigned positive value. It is NOT used for general-
7743 Consider this example, the distance between .LEND and .LBEGIN
7744 is stored at the address of foo.
7746 ---- >8 ---- >8 ---- >8 ---- >8 ----
7749 .word .LBEGIN - .LEND
7759 ---- 8< ---- 8< ---- 8< ---- 8< ----
7761 We use a single relocation entry for this expression.
7762 * The initial distance value is stored directly in that location
7763 specified by r_offset (i.e., foo in this example.)
7764 * The begin of the region, i.e., .LBEGIN, is specified by
7765 r_info/R_SYM and r_addend, e.g., .text + 0x32.
7766 * The end of region, i.e., .LEND, is represented by
7767 .LBEGIN + distance instead of .LEND, so we only need
7768 a single relocation entry instead of two.
7770 When an instruction is relaxed, we adjust the relocation entry
7771 depending on where the instruction locates. There are three
7772 cases, before, after and between the region.
7773 * between: Distance value is read from r_offset, adjusted and
7774 written back into r_offset.
7775 * before: Only r_addend is adjust.
7776 * after: We don't care about it.
7778 Hereby, there are some limitation.
7780 `(.LEND - 1) - .LBEGIN' and `(.LEND - .LBEGIN) - 1'
7781 are semantically different, and we cannot handle latter case
7784 The latter expression means subtracting 1 from the distance
7785 between .LEND and .LBEGIN. And the former expression means
7786 the distance between (.LEND - 1) and .LBEGIN.
7788 The nuance affects whether to adjust distance value when relax
7789 an instruction. In another words, whether the instruction
7790 locates in the region. Because we use a single relocation entry,
7791 there is no field left for .LEND and the subtrahend.
7793 Since GCC-4.5, GCC may produce debug information in such expression
7795 in order to describe register clobbering during an function-call.
7800 Check http://gcc.gnu.org/ml/gcc-patches/2009-06/msg01317.html
7803 value
-= S_GET_VALUE (fixP
->fx_subsy
);
7805 fixP
->fx_subsy
= NULL
;
7806 fixP
->fx_offset
-= value
;
7808 switch (fixP
->fx_r_type
)
7811 fixP
->fx_r_type
= BFD_RELOC_NDS32_DIFF8
;
7812 md_number_to_chars (where
, value
, 1);
7815 fixP
->fx_r_type
= BFD_RELOC_NDS32_DIFF16
;
7816 md_number_to_chars (where
, value
, 2);
7819 fixP
->fx_r_type
= BFD_RELOC_NDS32_DIFF32
;
7820 md_number_to_chars (where
, value
, 4);
7822 case BFD_RELOC_NDS32_DIFF_ULEB128
:
7823 /* cvt_frag_to_fill () has called output_leb128 () for us. */
7826 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7827 _("expression too complex"));
7831 else if (fixP
->fx_done
)
7833 /* We're finished with this fixup. Install it because
7834 bfd_install_relocation won't be called to do it. */
7835 switch (fixP
->fx_r_type
)
7838 md_number_to_chars (where
, value
, 1);
7841 md_number_to_chars (where
, value
, 2);
7844 md_number_to_chars (where
, value
, 4);
7847 md_number_to_chars (where
, value
, 8);
7850 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7851 _("Internal error: Unknown fixup type %d (`%s')"),
7853 bfd_get_reloc_code_name (fixP
->fx_r_type
));
7859 /* Implement tc_gen_reloc. Generate ELF relocation for a fix-up. */
7862 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixP
)
7865 bfd_reloc_code_real_type code
;
7867 reloc
= XNEW (arelent
);
7869 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
7870 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
7871 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
7873 code
= fixP
->fx_r_type
;
7875 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
7876 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
7878 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7879 _("internal error: can't export reloc type %d (`%s')"),
7880 fixP
->fx_r_type
, bfd_get_reloc_code_name (code
));
7884 /* Add relocation handling here. */
7886 switch (fixP
->fx_r_type
)
7889 /* In general, addend of a relocation is the offset to the
7890 associated symbol. */
7891 reloc
->addend
= fixP
->fx_offset
;
7894 case BFD_RELOC_NDS32_DATA
:
7895 /* Prevent linker from optimizing data in text sections.
7896 For example, jump table. */
7897 reloc
->addend
= fixP
->fx_size
;
7904 static struct suffix_name suffix_table
[] =
7906 {"GOTOFF", BFD_RELOC_NDS32_GOTOFF
},
7907 {"GOT", BFD_RELOC_NDS32_GOT20
},
7908 {"TPOFF", BFD_RELOC_NDS32_TPOFF
},
7909 {"PLT", BFD_RELOC_NDS32_25_PLTREL
},
7910 {"GOTTPOFF", BFD_RELOC_NDS32_GOTTPOFF
},
7911 {"TLSDESC", BFD_RELOC_NDS32_TLS_DESC
},
7914 /* Implement md_parse_name. */
7917 nds32_parse_name (char const *name
, expressionS
*exprP
,
7918 enum expr_mode mode ATTRIBUTE_UNUSED
,
7919 char *nextcharP ATTRIBUTE_UNUSED
)
7923 exprP
->X_op_symbol
= NULL
;
7924 exprP
->X_md
= BFD_RELOC_UNUSED
;
7926 exprP
->X_add_symbol
= symbol_find_or_make (name
);
7927 exprP
->X_op
= O_symbol
;
7928 exprP
->X_add_number
= 0;
7930 /* Check the special name if a symbol. */
7931 segment
= S_GET_SEGMENT (exprP
->X_add_symbol
);
7932 if ((segment
!= undefined_section
) && (*nextcharP
!= '@'))
7935 if (strcmp (name
, GOT_NAME
) == 0 && *nextcharP
!= '@')
7937 /* Set for _GOT_OFFSET_TABLE_. */
7938 exprP
->X_md
= BFD_RELOC_NDS32_GOTPC20
;
7940 else if (*nextcharP
== '@')
7944 for (i
= 0; i
< ARRAY_SIZE (suffix_table
); i
++)
7946 next
= input_line_pointer
+ 1 + strlen (suffix_table
[i
].suffix
);
7947 if (strncasecmp (input_line_pointer
+ 1, suffix_table
[i
].suffix
,
7948 strlen (suffix_table
[i
].suffix
)) == 0
7949 && !is_part_of_name (*next
))
7951 exprP
->X_md
= suffix_table
[i
].reloc
;
7952 *input_line_pointer
= *nextcharP
;
7953 input_line_pointer
= next
;
7954 *nextcharP
= *input_line_pointer
;
7955 *input_line_pointer
= '\0';
7964 /* Implement tc_regname_to_dw2regnum. */
7967 tc_nds32_regname_to_dw2regnum (char *regname
)
7969 struct nds32_keyword
*sym
= hash_find (nds32_gprs_hash
, regname
);
7978 tc_nds32_frame_initial_instructions (void)
7981 /* Default cfa is register-31/sp. */
7982 cfi_add_CFA_def_cfa (31, 0);