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