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