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