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