Remove use of alloca.
[deliverable/binutils-gdb.git] / gas / config / tc-nds32.c
CommitLineData
35c08157 1/* tc-nds32.c -- Assemble for the nds32
6f2750fe 2 Copyright (C) 2012-2016 Free Software Foundation, Inc.
35c08157
KLC
3 Contributed by Andes Technology Corporation.
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
21
22#include "as.h"
23#include "safe-ctype.h"
24#include "subsegs.h"
25#include "symcat.h"
26#include "dwarf2dbg.h"
27#include "dw2gencfi.h"
28#include "opcodes/nds32-asm.h"
29#include "elf/nds32.h"
30#include "bfd/elf32-nds32.h"
31#include "hash.h"
32#include "sb.h"
33#include "macro.h"
34#include "struc-symbol.h"
35#include "opcode/nds32.h"
36
37#include <stdio.h>
38
39/* GAS definitions. */
40
41/* Characters which start a comment. */
42const char comment_chars[] = "!";
43/* Characters which start a comment when they appear at the start of a line. */
44const char line_comment_chars[] = "#!";
45/* Characters which separate lines (null and newline are by default). */
46const char line_separator_chars[] = ";";
47/* Characters which may be used as the exponent character
48 in a floating point number. */
49const char EXP_CHARS[] = "eE";
50/* Characters which may be used to indicate a floating point constant. */
51const char FLT_CHARS[] = "dDfF";
52
53static int enable_16bit = 1;
54/* Save for md_assemble to distinguish if this instruction is
55 expanded from the pseudo instruction. */
56static bfd_boolean pseudo_opcode = FALSE;
57static struct nds32_relocs_pattern *relocs_list = NULL;
1c8f6a4d 58/* Save instruction relation to inserting relaxation relocation. */
35c08157
KLC
59struct nds32_relocs_pattern
60{
61 segT seg;
62 fragS *frag;
63 frchainS *frchain;
64 symbolS *sym;
1c8f6a4d
KLC
65 fixS* fixP;
66 struct nds32_opcode *opcode;
35c08157
KLC
67 char *where;
68 struct nds32_relocs_pattern *next;
69};
1c8f6a4d
KLC
70
71/* Suffix name and relocation. */
72struct suffix_name
73{
f86f5863 74 const char *suffix;
1c8f6a4d
KLC
75 short unsigned int reloc;
76 int pic;
77};
35c08157
KLC
78static int vec_size = 0;
79/* If the assembly code is generated by compiler, it is supposed to have
80 ".flag verbatim" at beginning of the content. We have
81 'nds32_flag' to parse it and set this field to be non-zero. */
82static int verbatim = 0;
83static struct hash_control *nds32_gprs_hash;
84static struct hash_control *nds32_hint_hash;
1c8f6a4d
KLC
85#define TLS_REG "$r27"
86#define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
35c08157
KLC
87
88/* Generate relocation for relax or not, and the default is true. */
89static int enable_relax_relocs = 1;
90/* The value will be used in RELAX_ENTRY. */
91static int enable_relax_ex9 = 0;
92/* The value will be used in RELAX_ENTRY. */
93static int enable_relax_ifc = 0;
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 {
ea16498d 143 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
35c08157
KLC
144 {0, 0, 0, 0}
145 }, /* BR_RANGE_S256 */
146 {
ea16498d 147 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
35c08157
KLC
148 {0, 0, 0, 0}
149 }, /* BR_RANGE_S16K */
150 {
ea16498d 151 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
35c08157
KLC
152 {0, 0, 0, 0}
153 }, /* BR_RANGE_S64K */
154 {
ea16498d 155 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
35c08157
KLC
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 {
ea16498d 224 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
225 {0, 0, 0, 0}
226 }, /* BR_RANGE_S256 */
227 {
ea16498d 228 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
229 {0, 0, 0, 0}
230 }, /* BR_RANGE_S16K */
231 {
ea16498d 232 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
233 {0, 0, 0, 0}
234 }, /* BR_RANGE_S64K */
235 {
ea16498d 236 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
1c8f6a4d 237 {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
ea16498d 238 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
35c08157
KLC
239 {0, 0, 0, 0}
240 }, /* BR_RANGE_S16M */
241 {
ea16498d 242 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
1c8f6a4d 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 {
ea16498d 309 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
310 {0, 0, 0, 0}
311 }, /* BR_RANGE_S256 */
312 {
ea16498d 313 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
314 {0, 0, 0, 0}
315 }, /* BR_RANGE_S16K */
316 {
ea16498d 317 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
318 {0, 0, 0, 0}
319 }, /* BR_RANGE_S64K */
320 {
ea16498d 321 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
1c8f6a4d 322 {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGCALL5},
ea16498d 323 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
35c08157
KLC
324 {0, 0, 0, 0}
325 }, /* BR_RANGE_S16M */
326 {
ea16498d 327 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
1c8f6a4d 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 {
ea16498d 374 {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
35c08157
KLC
375 {0, 0, 0, 0}
376 }, /* BR_RANGE_S256 */
377 {
ea16498d 378 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
35c08157
KLC
379 {0, 0, 0, 0}
380 }, /* BR_RANGE_S16K */
381 {
ea16498d 382 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
35c08157
KLC
383 {0, 0, 0, 0}
384 }, /* BR_RANGE_S64K */
385 {
ea16498d 386 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
35c08157
KLC
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 {
ea16498d 435 {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
35c08157
KLC
436 {0, 0, 0, 0}
437 }, /* BR_RANGE_S256 */
438 {
ea16498d 439 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
35c08157
KLC
440 {0, 0, 0, 0}
441 }, /* BR_RANGE_S16K */
442 {
ea16498d 443 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
35c08157
KLC
444 {0, 0, 0, 0}
445 }, /* BR_RANGE_S64K */
446 {
ea16498d 447 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
35c08157
KLC
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 {
ea16498d 516 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
1c8f6a4d 517 {0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16},
35c08157
KLC
518 {0, 0, 0, 0}
519 }, /* BR_RANGE_S256 */
520 {
ea16498d 521 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
522 {0, 0, 0, 0}
523 }, /* BR_RANGE_S16K */
524 {
ea16498d 525 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
526 {0, 0, 0, 0}
527 }, /* BR_RANGE_S64K */
528 {
ea16498d 529 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
530 {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
531 {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
ea16498d 532 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
1c8f6a4d
KLC
533 {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
534 {0, 0, 0, 0}
35c08157
KLC
535 }, /* BR_RANGE_S16M */
536 {
ea16498d 537 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
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 {
ea16498d 605 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
606 {0, 0, 0, 0}
607 }, /* BR_RANGE_S256 */
608 {
ea16498d 609 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
610 {0, 0, 0, 0}
611 }, /* BR_RANGE_S16K */
612 {
ea16498d 613 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
614 {0, 0, 0, 0}
615 }, /* BR_RANGE_S64K */
616 {
ea16498d 617 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d 618 {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
ea16498d 619 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
35c08157
KLC
620 {0, 0, 0, 0}
621 }, /* BR_RANGE_S16M */
622 {
ea16498d 623 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
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 {
ea16498d 690 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
1c8f6a4d 691 {0, 4, NDS32_INSN16 , BFD_RELOC_NDS32_INSN16},
35c08157
KLC
692 {0, 0, 0, 0}
693 }, /* BR_RANGE_S256 */
694 {
ea16498d 695 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
696 {0, 0, 0, 0}
697 }, /* BR_RANGE_S16K */
698 {
ea16498d 699 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
700 {0, 0, 0, 0}
701 }, /* BR_RANGE_S64K */
702 {
ea16498d 703 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
704 {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
705 {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
ea16498d 706 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
1c8f6a4d 707 {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
35c08157
KLC
708 {0, 0, 0, 0}
709 }, /* BR_RANGE_S16M */
710 {
ea16498d 711 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
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 {
ea16498d 779 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
780 {0, 0, 0, 0}
781 }, /* BR_RANGE_S256 */
782 {
ea16498d 783 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
784 {0, 0, 0, 0}
785 }, /* BR_RANGE_S16K */
786 {
ea16498d 787 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
788 {0, 0, 0, 0}
789 }, /* BR_RANGE_S64K */
790 {
ea16498d 791 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d 792 {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
ea16498d 793 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
35c08157
KLC
794 {0, 0, 0, 0}
795 }, /* BR_RANGE_S16M */
796 {
ea16498d 797 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
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 {
ea16498d 864 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
865 {0, 0, 0, 0}
866 }, /* BR_RANGE_S256 */
867 {
ea16498d 868 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
869 {0, 0, 0, 0}
870 }, /* BR_RANGE_S16K */
871 {
ea16498d 872 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
873 {0, 0, 0, 0}
874 }, /* BR_RANGE_S64K */
875 {
ea16498d 876 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d 877 {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
ea16498d 878 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
35c08157
KLC
879 {0, 0, 0, 0}
880 }, /* BR_RANGE_S16M */
881 {
ea16498d 882 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
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 {
ea16498d 949 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
950 {0, 0, 0, 0}
951 }, /* BR_RANGE_S256 */
952 {
ea16498d 953 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
954 {0, 0, 0, 0}
955 }, /* BR_RANGE_S16K */
956 {
ea16498d 957 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
958 {0, 0, 0, 0}
959 }, /* BR_RANGE_S64K */
960 {
ea16498d 961 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d 962 {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
ea16498d 963 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
35c08157
KLC
964 {0, 0, 0, 0}
965 }, /* BR_RANGE_S16M */
966 {
ea16498d 967 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
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 {
ea16498d 1041 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d 1042 {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
35c08157
KLC
1043 {0, 0, 0, 0}
1044 }, /* BR_RANGE_S256 */
1045 {
ea16498d 1046 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
35c08157
KLC
1047 {0, 0, 0, 0}
1048 }, /* BR_RANGE_S16K */
1049 {
ea16498d 1050 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
1051 {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
1052 {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
ea16498d 1053 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
1c8f6a4d 1054 {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
35c08157
KLC
1055 {0, 0, 0, 0}
1056 }, /* BR_RANGE_S64K */
1057 {
ea16498d 1058 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
1059 {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
1060 {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
ea16498d 1061 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
1c8f6a4d
KLC
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 {
ea16498d 1067 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
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 {
ea16498d 1142 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d 1143 {0, 4, NDS32_INSN16, BFD_RELOC_NDS32_INSN16},
35c08157
KLC
1144 {0, 0, 0, 0}
1145 }, /* BR_RANGE_S256 */
1146 {
ea16498d 1147 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
35c08157
KLC
1148 {0, 0, 0, 0}
1149 }, /* BR_RANGE_S16K */
1150 {
ea16498d 1151 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
1152 {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
1153 {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
ea16498d 1154 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
1c8f6a4d 1155 {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
35c08157
KLC
1156 {0, 0, 0, 0}
1157 }, /* BR_RANGE_S64K */
1158 {
ea16498d 1159 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
1160 {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
1161 {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
ea16498d 1162 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
1c8f6a4d 1163 {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
35c08157
KLC
1164 {0, 0, 0, 0}
1165 }, /* BR_RANGE_S16M */
1166 {
ea16498d 1167 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
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 {
ea16498d 1235 {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
35c08157
KLC
1236 {0, 0, 0, 0}
1237 }, /* BR_RANGE_S256 */
1238 {
ea16498d 1239 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
1240 {0, 0, 0, 0}
1241 }, /* BR_RANGE_S16K */
1242 {
ea16498d 1243 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
1244 {0, 0, 0, 0}
1245 }, /* BR_RANGE_S64K */
1246 {
ea16498d 1247 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
1248 {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
1249 {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
ea16498d 1250 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
1c8f6a4d 1251 {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
35c08157
KLC
1252 {0, 0, 0, 0}
1253 }, /* BR_RANGE_S16M */
1254 {
ea16498d 1255 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
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 {
ea16498d 1323 {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
35c08157
KLC
1324 {0, 0, 0, 0}
1325 }, /* BR_RANGE_S256 */
1326 {
ea16498d 1327 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
1328 {0, 0, 0, 0}
1329 }, /* BR_RANGE_S16K */
1330 {
ea16498d 1331 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
1332 {0, 0, 0, 0}
1333 }, /* BR_RANGE_S64K */
1334 {
ea16498d 1335 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
1336 {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
1337 {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
ea16498d 1338 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
1c8f6a4d 1339 {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
35c08157
KLC
1340 {0, 0, 0, 0}
1341 }, /* BR_RANGE_S16M */
1342 {
ea16498d 1343 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
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 {
ea16498d 1393 {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
35c08157
KLC
1394 {0, 0, 0, 0}
1395 }, /* BR_RANGE_S256 */
1396 {
ea16498d 1397 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
1398 {0, 0, 0, 0}
1399 }, /* BR_RANGE_S16K */
1400 {
ea16498d 1401 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
1402 {0, 0, 0, 0}
1403 }, /* BR_RANGE_S64K */
1404 {
ea16498d 1405 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
1406 {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
1407 {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
ea16498d 1408 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
1c8f6a4d 1409 {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
35c08157
KLC
1410 {0, 0, 0, 0}
1411 }, /* BR_RANGE_S16M */
1412 {
ea16498d 1413 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
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 {
ea16498d 1463 {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
35c08157
KLC
1464 {0, 0, 0, 0}
1465 }, /* BR_RANGE_S256 */
1466 {
ea16498d 1467 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
1468 {0, 0, 0, 0}
1469 }, /* BR_RANGE_S16K */
1470 {
ea16498d 1471 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_17_PCREL},
35c08157
KLC
1472 {0, 0, 0, 0}
1473 }, /* BR_RANGE_S64K */
1474 {
ea16498d 1475 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
1476 {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
1477 {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
ea16498d 1478 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
1c8f6a4d 1479 {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
35c08157
KLC
1480 {0, 0, 0, 0}
1481 }, /* BR_RANGE_S16M */
1482 {
ea16498d 1483 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
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 {
ea16498d 1552 {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
35c08157
KLC
1553 {0, 0, 0, 0}
1554 }, /* BR_RANGE_S256 */
1555 {
ea16498d 1556 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
35c08157
KLC
1557 {0, 0, 0, 0}
1558 }, /* BR_RANGE_S16K */
1559 {
ea16498d 1560 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
1561 {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
1562 {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
ea16498d 1563 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
1c8f6a4d 1564 {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
35c08157
KLC
1565 {0, 0, 0, 0}
1566 }, /* BR_RANGE_S64K */
1567 {
ea16498d 1568 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
1569 {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
1570 {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
ea16498d 1571 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
1c8f6a4d 1572 {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
35c08157
KLC
1573 {0, 0, 0, 0}
1574 }, /* BR_RANGE_S16M */
1575 {
ea16498d 1576 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
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 {
ea16498d 1645 {0, 2, NDS32_PCREL, BFD_RELOC_NDS32_9_PCREL},
35c08157
KLC
1646 {0, 0, 0, 0}
1647 }, /* BR_RANGE_S256 */
1648 {
ea16498d 1649 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
35c08157
KLC
1650 {0, 0, 0, 0}
1651 }, /* BR_RANGE_S16K */
1652 {
ea16498d 1653 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
1654 {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
1655 {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
ea16498d 1656 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
1c8f6a4d 1657 {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
35c08157
KLC
1658 {0, 0, 0, 0}
1659 }, /* BR_RANGE_S64K */
1660 {
ea16498d 1661 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
1662 {0, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
1663 {0, 4, NDS32_PTR | NDS32_HINT, BFD_RELOC_NDS32_LONGJUMP5},
ea16498d 1664 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
1c8f6a4d 1665 {4, 4, NDS32_INSN16 | NDS32_HINT, BFD_RELOC_NDS32_INSN16},
35c08157
KLC
1666 {0, 0, 0, 0}
1667 }, /* BR_RANGE_S16M */
1668 {
ea16498d 1669 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
1c8f6a4d
KLC
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 {
ea16498d 1745 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
35c08157
KLC
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},
ea16498d 1751 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
35c08157
KLC
1752 {0, 0, 0, 0}
1753 }, /* BR_RANGE_S16K */
1754 {
ea16498d
KLC
1755 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
1756 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
35c08157
KLC
1757 {0, 0, 0, 0}
1758 }, /* BR_RANGE_S64K */
1759 {
ea16498d
KLC
1760 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
1761 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
35c08157
KLC
1762 {0, 0, 0, 0}
1763 }, /* BR_RANGE_S16M */
1764 {
ea16498d 1765 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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 {
ea16498d 1835 {0, 4, NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
35c08157
KLC
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},
ea16498d 1841 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_15_PCREL},
35c08157
KLC
1842 {0, 0, 0, 0}
1843 }, /* BR_RANGE_S16K */
1844 {
ea16498d
KLC
1845 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
1846 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
35c08157
KLC
1847 {0, 0, 0, 0}
1848 }, /* BR_RANGE_S64K */
1849 {
ea16498d
KLC
1850 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, BFD_RELOC_NDS32_WORD_9_PCREL},
1851 {4, 4, NDS32_PCREL, BFD_RELOC_NDS32_25_PCREL},
35c08157
KLC
1852 {0, 0, 0, 0}
1853 }, /* BR_RANGE_S16M */
1854 {
ea16498d 1855 {0, 4, NDS32_CREATE_LABEL | NDS32_PCREL, 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. */
f86f5863
TS
1915 const char *help; /* Help description. */
1916 int (*func) (const char *arg); /* How to parse it. */
35c08157
KLC
1917};
1918
1919
1920/* The value `-1' represents this option has *NOT* been set. */
1921#ifdef NDS32_DEFAULT_ARCH_NAME
f86f5863 1922static const char* nds32_arch_name = NDS32_DEFAULT_ARCH_NAME;
35c08157 1923#else
f86f5863 1924static const char* nds32_arch_name = "v3";
35c08157
KLC
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
f86f5863
TS
1937static int nds32_parse_arch (const char *str);
1938static int nds32_parse_baseline (const char *str);
1939static int nds32_parse_freg (const char *str);
1940static int nds32_parse_abi (const char *str);
35c08157
KLC
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. */
f86f5863 1978 const char *help; /* Help description. */
35c08157
KLC
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{
ea16498d
KLC
2142 if (s [0] == '$' && hash_find (nds32_gprs_hash, (s + 1)))
2143 return 1;
2144 return 0;
35c08157
KLC
2145}
2146
2147static int
2148builtin_regnum (const char *s, const char *x ATTRIBUTE_UNUSED)
2149{
2150 struct nds32_keyword *k;
1c8f6a4d
KLC
2151 if (*s != '$')
2152 return -1;
2153 s++;
35c08157
KLC
2154 k = hash_find (nds32_gprs_hash, s);
2155
2156 if (k == NULL)
2157 return -1;
2158
2159 return k->value;
2160}
2161
2162static int
2163builtin_addend (const char *s, char *x ATTRIBUTE_UNUSED)
2164{
2165 const char *ptr = s;
2166
2167 while (*ptr != '+' && *ptr != '-' && *ptr)
2168 ++ptr;
2169
2170 if (*ptr == 0)
2171 return 0;
2172 else
2173 return strtol (ptr, NULL, 0);
2174}
2175
2176static void
f86f5863 2177md_assemblef (const char *format, ...)
35c08157
KLC
2178{
2179 /* FIXME: hope this is long enough. */
2180 char line[1024];
2181 va_list ap;
2182 unsigned int r;
2183
2184 va_start (ap, format);
2185 r = vsnprintf (line, sizeof (line), format, ap);
2186 md_assemble (line);
2187
2188 gas_assert (r < sizeof (line));
2189}
2190
2191/* Some prototypes here, since some op may use another op. */
f86f5863 2192static void do_pseudo_li_internal (const char *rt, int imm32s);
35c08157
KLC
2193static void do_pseudo_move_reg_internal (char *dst, char *src);
2194
2195static void
2196do_pseudo_b (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2197{
2198 char *arg_label = argv[0];
1c8f6a4d 2199 relaxing = TRUE;
35c08157 2200 /* b label */
1c8f6a4d 2201 if (nds32_pic && strstr (arg_label, "@PLT"))
35c08157
KLC
2202 {
2203 md_assemblef ("sethi $ta,hi20(%s)", arg_label);
2204 md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
2205 md_assemble ("add $ta,$ta,$gp");
2206 md_assemble ("jr $ta");
2207 }
2208 else
2209 {
2210 md_assemblef ("j %s", arg_label);
2211 }
1c8f6a4d 2212 relaxing = FALSE;
35c08157
KLC
2213}
2214
2215static void
2216do_pseudo_bal (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2217{
2218 char *arg_label = argv[0];
1c8f6a4d 2219 relaxing = TRUE;
35c08157
KLC
2220 /* bal|call label */
2221 if (nds32_pic
2222 && (strstr (arg_label, "@GOT") || strstr (arg_label, "@PLT")))
2223 {
2224 md_assemblef ("sethi $ta,hi20(%s)", arg_label);
2225 md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
2226 md_assemble ("add $ta,$ta,$gp");
2227 md_assemble ("jral $ta");
2228 }
2229 else
2230 {
2231 md_assemblef ("jal %s", arg_label);
2232 }
1c8f6a4d 2233 relaxing = FALSE;
35c08157
KLC
2234}
2235
2236static void
2237do_pseudo_bge (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2238{
2239 /* rt5, ra5, label */
2240 md_assemblef ("slt $ta,%s,%s", argv[0], argv[1]);
2241 md_assemblef ("beqz $ta,%s", argv[2]);
2242}
2243
2244static void
2245do_pseudo_bges (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2246{
2247 /* rt5, ra5, label */
2248 md_assemblef ("slts $ta,%s,%s", argv[0], argv[1]);
2249 md_assemblef ("beqz $ta,%s", argv[2]);
2250}
2251
2252static void
2253do_pseudo_bgt (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2254{
2255 /* bgt rt5, ra5, label */
2256 md_assemblef ("slt $ta,%s,%s", argv[1], argv[0]);
2257 md_assemblef ("bnez $ta,%s", argv[2]);
2258}
2259
2260static void
2261do_pseudo_bgts (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2262{
2263 /* bgt rt5, ra5, label */
2264 md_assemblef ("slts $ta,%s,%s", argv[1], argv[0]);
2265 md_assemblef ("bnez $ta,%s", argv[2]);
2266}
2267
2268static void
2269do_pseudo_ble (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2270{
2271 /* bgt rt5, ra5, label */
2272 md_assemblef ("slt $ta,%s,%s", argv[1], argv[0]);
2273 md_assemblef ("beqz $ta,%s", argv[2]);
2274}
2275
2276static void
2277do_pseudo_bles (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2278{
2279 /* bgt rt5, ra5, label */
2280 md_assemblef ("slts $ta,%s,%s", argv[1], argv[0]);
2281 md_assemblef ("beqz $ta,%s", argv[2]);
2282}
2283
2284static void
2285do_pseudo_blt (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2286{
2287 /* rt5, ra5, label */
2288 md_assemblef ("slt $ta,%s,%s", argv[0], argv[1]);
2289 md_assemblef ("bnez $ta,%s", argv[2]);
2290}
2291
2292static void
2293do_pseudo_blts (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2294{
2295 /* rt5, ra5, label */
2296 md_assemblef ("slts $ta,%s,%s", argv[0], argv[1]);
2297 md_assemblef ("bnez $ta,%s", argv[2]);
2298}
2299
2300static void
2301do_pseudo_br (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2302{
2303 md_assemblef ("jr %s", argv[0]);
2304}
2305
2306static void
2307do_pseudo_bral (int argc, char *argv[], int pv ATTRIBUTE_UNUSED)
2308{
2309 if (argc == 1)
2310 md_assemblef ("jral $lp,%s", argv[0]);
2311 else
2312 md_assemblef ("jral %s,%s", argv[0], argv[1]);
2313}
2314
2315static void
20d79870 2316do_pseudo_la_internal (const char *arg_reg, char *arg_label,
1c8f6a4d 2317 const char *line)
35c08157 2318{
20d79870
KLC
2319 expressionS exp;
2320
2321 parse_expression (arg_label, &exp);
2322 if (exp.X_op != O_symbol)
2323 {
2324 as_bad (_("la must use with symbol. '%s'"), line);
2325 return;
2326 }
2327
1c8f6a4d 2328 relaxing = TRUE;
35c08157 2329 /* rt, label */
1c8f6a4d 2330 if (!nds32_pic && !strstr(arg_label, "@"))
35c08157
KLC
2331 {
2332 md_assemblef ("sethi %s,hi20(%s)", arg_reg, arg_label);
2333 md_assemblef ("ori %s,%s,lo12(%s)", arg_reg, arg_reg, arg_label);
2334 }
1c8f6a4d
KLC
2335 else if (strstr (arg_label, "@TPOFF"))
2336 {
2337 /* la $rt, sym@TPOFF */
2338 md_assemblef ("sethi $ta,hi20(%s)", arg_label);
2339 md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
2340 md_assemblef ("add %s,$ta,%s", arg_reg, TLS_REG);
2341 }
2342 else if (strstr(arg_label, "@GOTTPOFF"))
2343 {
2344 /* la $rt, sym@GOTTPOFF*/
2345 md_assemblef ("sethi $ta,hi20(%s)", arg_label);
2346 md_assemblef ("lwi $ta,[$ta+lo12(%s)]", arg_label);
2347 md_assemblef ("add %s,$ta,%s", arg_reg, TLS_REG);
2348 }
2349 else if (nds32_pic && ((strstr (arg_label, "@PLT")
2350 || strstr (arg_label, "@GOTOFF"))))
35c08157
KLC
2351 {
2352 md_assemblef ("sethi $ta,hi20(%s)", arg_label);
2353 md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
2354 md_assemblef ("add %s,$ta,$gp", arg_reg);
2355 }
1c8f6a4d 2356 else if (nds32_pic && strstr (arg_label, "@GOT"))
35c08157
KLC
2357 {
2358 long addend = builtin_addend (arg_label, NULL);
2359
2360 md_assemblef ("sethi $ta,hi20(%s)", arg_label);
2361 md_assemblef ("ori $ta,$ta,lo12(%s)", arg_label);
2362 md_assemblef ("lw %s,[$gp+$ta]", arg_reg);
2363 if (addend != 0)
2364 {
2365 if (addend < 0x4000 && addend >= -0x4000)
2366 {
2367 md_assemblef ("addi %s,%s,%d", arg_reg, arg_reg, addend);
2368 }
2369 else
2370 {
2371 do_pseudo_li_internal ("$ta", addend);
2372 md_assemblef ("add %s,$ta,%s", arg_reg, arg_reg);
2373 }
2374 }
2375 }
2376 else
2377 as_bad (_("need PIC qualifier with symbol. '%s'"), line);
1c8f6a4d 2378 relaxing = FALSE;
35c08157
KLC
2379}
2380
2381static void
2382do_pseudo_la (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2383{
2384 do_pseudo_la_internal (argv[0], argv[1], argv[argc]);
2385}
2386
2387static void
f86f5863 2388do_pseudo_li_internal (const char *rt, int imm32s)
35c08157
KLC
2389{
2390 if (enable_16bit && imm32s <= 0xf && imm32s >= -0x10)
2391 md_assemblef ("movi55 %s,%d", rt, imm32s);
2392 else if (imm32s <= 0x7ffff && imm32s >= -0x80000)
2393 md_assemblef ("movi %s,%d", rt, imm32s);
2394 else if ((imm32s & 0xfff) == 0)
2395 md_assemblef ("sethi %s,hi20(%d)", rt, imm32s);
2396 else
2397 {
2398 md_assemblef ("sethi %s,hi20(%d)", rt, imm32s);
2399 md_assemblef ("ori %s,%s,lo12(%d)", rt, rt, imm32s);
2400 }
2401}
2402
2403static void
2404do_pseudo_li (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2405{
2406 /* Validate argv[1] for constant expression. */
2407 expressionS exp;
2408
2409 parse_expression (argv[1], &exp);
2410 if (exp.X_op != O_constant)
2411 {
2412 as_bad (_("Operand is not a constant. `%s'"), argv[argc]);
2413 return;
2414 }
2415
2416 do_pseudo_li_internal (argv[0], exp.X_add_number);
2417}
2418
2419static void
2420do_pseudo_ls_bhw (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
2421{
2422 char ls = 'r';
2423 char size = 'x';
2424 const char *sign = "";
2425
2426 /* Prepare arguments for various load/store. */
2427 sign = (pv & 0x10) ? "s" : "";
2428 ls = (pv & 0x80000000) ? 's' : 'l';
2429 switch (pv & 0x3)
2430 {
2431 case 0: size = 'b'; break;
2432 case 1: size = 'h'; break;
2433 case 2: size = 'w'; break;
2434 }
2435
2436 if (ls == 's' || size == 'w')
2437 sign = "";
2438
2439 if (builtin_isreg (argv[1], NULL))
2440 {
2441 /* lwi */
1c8f6a4d 2442 md_assemblef ("%c%ci %s,[%s]", ls, size, argv[0], argv[1]);
35c08157
KLC
2443 }
2444 else if (!nds32_pic)
2445 {
1c8f6a4d
KLC
2446 relaxing = TRUE;
2447 if (strstr (argv[1], "@TPOFF"))
2448 {
2449 /* ls.w $rt, sym@TPOFF */
2450 md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
2451 md_assemblef ("ori $ta,$ta,lo12(%s)", argv[1]);
2452 md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], TLS_REG);
2453 }
2454 else if (strstr (argv[1], "@GOTTPOFF"))
2455 {
2456 /* ls.w $rt, sym@GOTTPOFF */
2457 md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
2458 md_assemblef ("lwi $ta,[$ta+lo12(%s)]", argv[1]);
2459 md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], TLS_REG);
2460 }
2461 else
2462 {
2463 /* lwi */
2464 md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
2465 md_assemblef ("%c%c%si %s,[$ta+lo12(%s)]", ls, size, sign, argv[0], argv[1]);
2466 }
2467 relaxing = FALSE;
35c08157
KLC
2468 }
2469 else
2470 {
1c8f6a4d 2471 relaxing = TRUE;
35c08157
KLC
2472 /* PIC code. */
2473 if (strstr (argv[1], "@GOTOFF"))
2474 {
2475 /* lw */
2476 md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
2477 md_assemblef ("ori $ta,$ta,lo12(%s)", argv[1]);
2478 md_assemblef ("%c%c%s %s,[$ta+$gp]", ls, size, sign, argv[0]);
2479 }
2480 else if (strstr (argv[1], "@GOT"))
2481 {
2482 long addend = builtin_addend (argv[1], NULL);
2483 /* lw */
2484 md_assemblef ("sethi $ta,hi20(%s)", argv[1]);
2485 md_assemblef ("ori $ta,$ta,lo12(%s)", argv[1]);
2486 md_assemble ("lw $ta,[$gp+$ta]"); /* Load address word. */
2487 if (addend < 0x10000 && addend >= -0x10000)
2488 {
2489 md_assemblef ("%c%c%si %s,[$ta+(%d)]", ls, size, sign, argv[0], addend);
2490 }
2491 else
2492 {
2493 /* lw */
2494 do_pseudo_li_internal (argv[0], addend);
2495 md_assemblef ("%c%c%s %s,[$ta+%s]", ls, size, sign, argv[0], argv[0]);
2496 }
2497 }
2498 else
2499 {
2500 as_bad (_("needs @GOT or @GOTOFF. %s"), argv[argc]);
2501 }
1c8f6a4d 2502 relaxing = FALSE;
35c08157
KLC
2503 }
2504}
2505
2506static void
2507do_pseudo_ls_bhwp (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
2508{
2509 char *arg_rt = argv[0];
2510 char *arg_label = argv[1];
2511 char *arg_inc = argv[2];
2512 char ls = 'r';
2513 char size = 'x';
2514 const char *sign = "";
2515
2516 /* Prepare arguments for various load/store. */
2517 sign = (pv & 0x10) ? "s" : "";
2518 ls = (pv & 0x80000000) ? 's' : 'l';
2519 switch (pv & 0x3)
2520 {
2521 case 0: size = 'b'; break;
2522 case 1: size = 'h'; break;
2523 case 2: size = 'w'; break;
2524 }
2525
2526 if (ls == 's' || size == 'w')
2527 sign = "";
2528
2529 do_pseudo_la_internal ("$ta", arg_label, argv[argc]);
2530 md_assemblef ("%c%c%si.bi %s,[$ta],%s", ls, size, sign, arg_rt, arg_inc);
2531}
2532
2533static void
2534do_pseudo_ls_bhwpc (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
2535{
2536 char *arg_rt = argv[0];
1c8f6a4d 2537 char *arg_inc = argv[1];
35c08157
KLC
2538 char ls = 'r';
2539 char size = 'x';
2540 const char *sign = "";
2541
2542 /* Prepare arguments for various load/store. */
2543 sign = (pv & 0x10) ? "s" : "";
2544 ls = (pv & 0x80000000) ? 's' : 'l';
2545 switch (pv & 0x3)
2546 {
2547 case 0: size = 'b'; break;
2548 case 1: size = 'h'; break;
2549 case 2: size = 'w'; break;
2550 }
2551
2552 if (ls == 's' || size == 'w')
2553 sign = "";
2554
2555 md_assemblef ("%c%c%si.bi %s,[$ta],%s", ls, size, sign, arg_rt, arg_inc);
2556}
2557
2558static void
2559do_pseudo_ls_bhwi (int argc ATTRIBUTE_UNUSED, char *argv[], int pv)
2560{
2561 char ls = 'r';
2562 char size = 'x';
2563 const char *sign = "";
2564
2565 /* Prepare arguments for various load/store. */
2566 sign = (pv & 0x10) ? "s" : "";
2567 ls = (pv & 0x80000000) ? 's' : 'l';
2568 switch (pv & 0x3)
2569 {
2570 case 0: size = 'b'; break;
2571 case 1: size = 'h'; break;
2572 case 2: size = 'w'; break;
2573 }
2574
2575 if (ls == 's' || size == 'w')
2576 sign = "";
2577
2578 md_assemblef ("%c%c%si.bi %s,%s,%s",
2579 ls, size, sign, argv[0], argv[1], argv[2]);
2580}
2581
2582static void
2583do_pseudo_move_reg_internal (char *dst, char *src)
2584{
2585 if (enable_16bit)
2586 md_assemblef ("mov55 %s,%s", dst, src);
2587 else
2588 md_assemblef ("ori %s,%s,0", dst, src);
2589}
2590
2591static void
2592do_pseudo_move (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2593{
1c8f6a4d
KLC
2594 expressionS exp;
2595
35c08157
KLC
2596 if (builtin_isreg (argv[1], NULL))
2597 do_pseudo_move_reg_internal (argv[0], argv[1]);
2598 else
ea16498d
KLC
2599 {
2600 parse_expression (argv[1], &exp);
2601 if (exp.X_op == O_constant)
2602 /* move $rt, imm -> li $rt, imm */
2603 do_pseudo_li_internal (argv[0], exp.X_add_number);
2604 else
2605 /* l.w $rt, var -> l.w $rt, var */
2606 do_pseudo_ls_bhw (argc, argv, 2);
2607 }
35c08157
KLC
2608}
2609
2610static void
2611do_pseudo_neg (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2612{
1c8f6a4d
KLC
2613 /* Instead of "subri". */
2614 md_assemblef ("subri %s,%s,0", argv[0], argv[1]);
35c08157
KLC
2615}
2616
2617static void
2618do_pseudo_not (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2619{
2620 md_assemblef ("nor %s,%s,%s", argv[0], argv[1], argv[1]);
2621}
2622
2623static void
2624do_pseudo_pushpopm (int argc, char *argv[], int pv ATTRIBUTE_UNUSED)
2625{
2626 /* posh/pop $ra, $rb */
2627 /* SMW.{b | a}{i | d}{m?} Rb, [Ra], Re, Enable4 */
2628 int rb, re, ra, en4;
2629 int i;
f86f5863 2630 const char *opc = "pushpopm";
35c08157
KLC
2631
2632 if (argc == 3)
2633 as_bad ("'pushm/popm $ra5, $rb5, $label' is deprecated. "
2634 "Only 'pushm/popm $ra5' is supported now. %s", argv[argc]);
2635 else if (argc == 1)
2636 as_bad ("'pushm/popm $ra5, $rb5'. %s\n", argv[argc]);
2637
2638 if (strstr (argv[argc], "pop") == argv[argc])
2639 opc = "lmw.bim";
2640 else if (strstr (argv[argc], "push") == argv[argc])
2641 opc = "smw.adm";
2642 else
2643 as_fatal ("nds32-as internal error. %s", argv[argc]);
2644
2645 rb = builtin_regnum (argv[0], NULL);
2646 re = builtin_regnum (argv[1], NULL);
2647
2648 if (re < rb)
2649 {
2650 as_warn ("$rb should not be smaller than $ra. %s", argv[argc]);
2651 /* Swap to right order. */
2652 ra = re;
2653 re = rb;
2654 rb = ra;
2655 }
2656
2657 /* Build enable4 mask. */
2658 en4 = 0;
2659 if (re >= 28 || rb >= 28)
2660 {
2661 for (i = (rb >= 28? rb: 28); i <= re; i++)
2662 en4 |= 1 << (3 - (i - 28));
2663 }
2664
2665 /* Adjust $re, $rb. */
2666 if (rb >= 28)
2667 rb = re = 31;
1c8f6a4d 2668 else if (nds32_gpr16 != 1 && re >= 28)
35c08157
KLC
2669 re = 27;
2670
1c8f6a4d
KLC
2671 /* Reduce register. */
2672 if (nds32_gpr16 && re > 10 && !(rb == 31 && re == 31))
2673 {
2674 if (re >= 15 && strstr(opc, "smw") != NULL)
2675 md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
2676 if (rb <= 10)
2677 md_assemblef ("%s $r%d,[$sp],$r10, 0x0", opc, rb);
2678 if (re >= 15 && strstr(opc, "lmw") != NULL)
2679 md_assemblef ("%s $r15,[$sp],$r15,%d", opc, en4);
2680 }
2681 else
2682 md_assemblef ("%s $r%d,[$sp],$r%d,%d", opc, rb, re, en4);
35c08157
KLC
2683}
2684
2685static void
2686do_pseudo_pushpop (int argc, char *argv[], int pv ATTRIBUTE_UNUSED)
2687{
2688 /* push/pop $ra5, $label=$sp */
2689 char *argvm[3];
2690
2691 if (argc == 2)
2692 as_bad ("'push/pop $ra5, rb5' is deprecated. "
2693 "Only 'push/pop $ra5' is supported now. %s", argv[argc]);
2694
2695 argvm[0] = argv[0];
2696 argvm[1] = argv[0];
2697 argvm[2] = argv[argc];
2698 do_pseudo_pushpopm (2, argvm, PV_DONT_CARE);
2699}
2700
2701static void
2702do_pseudo_v3push (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2703{
2704 md_assemblef ("push25 %s,%s", argv[0], argv[1]);
2705}
2706
2707static void
2708do_pseudo_v3pop (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2709{
2710 md_assemblef ("pop25 %s,%s", argv[0], argv[1]);
2711}
2712
2713/* pv == 0, parsing "push.s" pseudo instruction operands.
2714 pv != 0, parsing "pop.s" pseudo instruction operands. */
2715
2716static void
2717do_pseudo_pushpop_stack (int argc, char *argv[], int pv)
2718{
2719 /* push.s Rb,Re,{$fp $gp $lp $sp} ==> smw.adm Rb,[$sp],Re,Eable4 */
2720 /* pop.s Rb,Re,{$fp $gp $lp $sp} ==> lmw.bim Rb,[$sp],Re,Eable4 */
2721
2722 int rb, re;
2723 int en4;
2724 int last_arg_index;
f86f5863 2725 const char *opc = (pv == 0) ? "smw.adm" : "lmw.bim";
35c08157
KLC
2726
2727 rb = re = 0;
2728
2729 if (argc == 1)
2730 {
2731 /* argc=1, operands pattern: { $fp $gp $lp $sp } */
2732
2733 /* Set register number Rb = Re = $sp = $r31. */
2734 rb = re = 31;
2735 }
2736 else if (argc == 2 || argc == 3)
2737 {
2738 /* argc=2, operands pattern: Rb, Re */
2739 /* argc=3, operands pattern: Rb, Re, { $fp $gp $lp $sp } */
2740
2741 /* Get register number in integer. */
2742 rb = builtin_regnum (argv[0], NULL);
2743 re = builtin_regnum (argv[1], NULL);
2744
2745 /* Rb should be equal/less than Re. */
2746 if (rb > re)
2747 as_bad ("The first operand (%s) should be equal to or smaller than "
2748 "second operand (%s).", argv[0], argv[1]);
2749
2750 /* forbid using $fp|$gp|$lp|$sp in Rb or Re
2751 r28 r29 r30 r31 */
2752 if (rb >= 28)
2753 as_bad ("Cannot use $fp, $gp, $lp, or $sp at first operand !!");
2754 if (re >= 28)
2755 as_bad ("Cannot use $fp, $gp, $lp, or $sp at second operand !!");
2756 }
2757 else
2758 {
2759 as_bad ("Invalid operands pattern !!");
2760 }
2761
2762 /* Build Enable4 mask. */
2763 /* Using last_arg_index for argc=1|2|3 is safe, because $fp, $gp, $lp,
2764 and $sp only appear in argc=1 or argc=3 if argc=2, en4 remains 0,
2765 which is also valid for code generation. */
2766 en4 = 0;
2767 last_arg_index = argc - 1;
2768 if (strstr (argv[last_arg_index], "$fp"))
2769 en4 |= 8;
2770 if (strstr (argv[last_arg_index], "$gp"))
2771 en4 |= 4;
2772 if (strstr (argv[last_arg_index], "$lp"))
2773 en4 |= 2;
2774 if (strstr (argv[last_arg_index], "$sp"))
2775 en4 |= 1;
2776
2777 md_assemblef ("%s $r%d,[$sp],$r%d,%d", opc, rb, re, en4);
2778}
2779
2780static void
2781do_pseudo_push_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2782{
2783 char size = 'x';
2784 /* If users omit push location, use $sp as default value. */
2785 char location[8] = "$sp"; /* 8 is enough for register name. */
2786
2787 switch (pv & 0x3)
2788 {
2789 case 0: size = 'b'; break;
2790 case 1: size = 'h'; break;
2791 case 2: size = 'w'; break;
2792 case 3: size = 'w'; break;
2793 }
2794
2795 if (argc == 2)
2796 {
2797 strncpy (location, argv[1], 8);
2798 location[7] = '\0';
2799 }
2800
2801 md_assemblef ("l.%c $ta,%s", size, argv[0]);
2802 md_assemblef ("smw.adm $ta,[%s],$ta", location);
2803
2804 if ((pv & 0x3) == 0x3) /* double-word */
2805 {
2806 md_assemblef ("l.w $ta,%s+4", argv[0]);
2807 md_assemblef ("smw.adm $ta,[%s],$ta", location);
2808 }
2809}
2810
2811static void
2812do_pseudo_pop_bhwd (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2813{
2814 char size = 'x';
2815 /* If users omit pop location, use $sp as default value. */
2816 char location[8] = "$sp"; /* 8 is enough for register name. */
2817
2818 switch (pv & 0x3)
2819 {
2820 case 0: size = 'b'; break;
2821 case 1: size = 'h'; break;
2822 case 2: size = 'w'; break;
2823 case 3: size = 'w'; break;
2824 }
2825
2826 if (argc == 3)
2827 {
2828 strncpy (location, argv[2], 8);
2829 location[7] = '\0';
2830 }
2831
2832 if ((pv & 0x3) == 0x3) /* double-word */
2833 {
2834 md_assemblef ("lmw.bim %s,[%s],%s", argv[1], location, argv[1]);
2835 md_assemblef ("s.w %s,%s+4", argv[1], argv[0]);
2836 }
2837
2838 md_assemblef ("lmw.bim %s,[%s],%s", argv[1], location, argv[1]);
2839 md_assemblef ("s.%c %s,%s", size, argv[1], argv[0]);
2840}
2841
2842static void
2843do_pseudo_pusha (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2844{
2845 /* If users omit push location, use $sp as default value. */
2846 char location[8] = "$sp"; /* 8 is enough for register name. */
2847
2848 if (argc == 2)
2849 {
2850 strncpy (location, argv[1], 8);
2851 location[7] = '\0';
2852 }
2853
2854 md_assemblef ("la $ta,%s", argv[0]);
2855 md_assemblef ("smw.adm $ta,[%s],$ta", location);
2856}
2857
2858static void
2859do_pseudo_pushi (int argc ATTRIBUTE_UNUSED, char *argv[], int pv ATTRIBUTE_UNUSED)
2860{
2861 /* If users omit push location, use $sp as default value. */
2862 char location[8] = "$sp"; /* 8 is enough for register name. */
2863
2864 if (argc == 2)
2865 {
2866 strncpy (location, argv[1], 8);
2867 location[7] = '\0';
2868 }
2869
2870 md_assemblef ("li $ta,%s", argv[0]);
2871 md_assemblef ("smw.adm $ta,[%s],$ta", location);
2872}
2873
2874struct nds32_pseudo_opcode nds32_pseudo_opcode_table[] =
2875{
2876 {"b", 1, do_pseudo_b, 0, 0},
2877 {"bal", 1, do_pseudo_bal, 0, 0},
2878
2879 {"bge", 3, do_pseudo_bge, 0, 0},
2880 {"bges", 3, do_pseudo_bges, 0, 0},
2881
2882 {"bgt", 3, do_pseudo_bgt, 0, 0},
2883 {"bgts", 3, do_pseudo_bgts, 0, 0},
2884
2885 {"ble", 3, do_pseudo_ble, 0, 0},
2886 {"bles", 3, do_pseudo_bles, 0, 0},
2887
2888 {"blt", 3, do_pseudo_blt, 0, 0},
2889 {"blts", 3, do_pseudo_blts, 0, 0},
2890
2891 {"br", 1, do_pseudo_br, 0, 0},
2892 {"bral", 1, do_pseudo_bral, 0, 0},
2893
2894 {"call", 1, do_pseudo_bal, 0, 0},
2895
2896 {"la", 2, do_pseudo_la, 0, 0},
2897 {"li", 2, do_pseudo_li, 0, 0},
2898
2899 {"l.b", 2, do_pseudo_ls_bhw, 0, 0},
2900 {"l.h", 2, do_pseudo_ls_bhw, 1, 0},
2901 {"l.w", 2, do_pseudo_ls_bhw, 2, 0},
2902 {"l.bs", 2, do_pseudo_ls_bhw, 0 | 0x10, 0},
2903 {"l.hs", 2, do_pseudo_ls_bhw, 1 | 0x10, 0},
2904 {"s.b", 2, do_pseudo_ls_bhw, 0 | 0x80000000, 0},
2905 {"s.h", 2, do_pseudo_ls_bhw, 1 | 0x80000000, 0},
2906 {"s.w", 2, do_pseudo_ls_bhw, 2 | 0x80000000, 0},
2907
2908 {"l.bp", 3, do_pseudo_ls_bhwp, 0, 0},
2909 {"l.bpc", 3, do_pseudo_ls_bhwpc, 0, 0},
2910 {"l.hp", 3, do_pseudo_ls_bhwp, 1, 0},
2911 {"l.hpc", 3, do_pseudo_ls_bhwpc, 1, 0},
2912 {"l.wp", 3, do_pseudo_ls_bhwp, 2, 0},
2913 {"l.wpc", 3, do_pseudo_ls_bhwpc, 2, 0},
2914 {"l.bsp", 3, do_pseudo_ls_bhwp, 0 | 0x10, 0},
2915 {"l.bspc", 3, do_pseudo_ls_bhwpc, 0 | 0x10, 0},
2916 {"l.hsp", 3, do_pseudo_ls_bhwp, 1 | 0x10, 0},
2917 {"l.hspc", 3, do_pseudo_ls_bhwpc, 1 | 0x10, 0},
2918 {"s.bp", 3, do_pseudo_ls_bhwp, 0 | 0x80000000, 0},
2919 {"s.bpc", 3, do_pseudo_ls_bhwpc, 0 | 0x80000000, 0},
2920 {"s.hp", 3, do_pseudo_ls_bhwp, 1 | 0x80000000, 0},
2921 {"s.hpc", 3, do_pseudo_ls_bhwpc, 1 | 0x80000000, 0},
2922 {"s.wp", 3, do_pseudo_ls_bhwp, 2 | 0x80000000, 0},
2923 {"s.wpc", 3, do_pseudo_ls_bhwpc, 2 | 0x80000000, 0},
2924 {"s.bsp", 3, do_pseudo_ls_bhwp, 0 | 0x80000000 | 0x10, 0},
2925 {"s.hsp", 3, do_pseudo_ls_bhwp, 1 | 0x80000000 | 0x10, 0},
2926
2927 {"lbi.p", 3, do_pseudo_ls_bhwi, 0, 0},
2928 {"lhi.p", 3, do_pseudo_ls_bhwi, 1, 0},
2929 {"lwi.p", 3, do_pseudo_ls_bhwi, 2, 0},
2930 {"sbi.p", 3, do_pseudo_ls_bhwi, 0 | 0x80000000, 0},
2931 {"shi.p", 3, do_pseudo_ls_bhwi, 1 | 0x80000000, 0},
2932 {"swi.p", 3, do_pseudo_ls_bhwi, 2 | 0x80000000, 0},
2933 {"lbsi.p", 3, do_pseudo_ls_bhwi, 0 | 0x10, 0},
2934 {"lhsi.p", 3, do_pseudo_ls_bhwi, 1 | 0x10, 0},
1c8f6a4d 2935 {"lwsi.p", 3, do_pseudo_ls_bhwi, 2 | 0x10, 0},
35c08157
KLC
2936
2937 {"move", 2, do_pseudo_move, 0, 0},
2938 {"neg", 2, do_pseudo_neg, 0, 0},
2939 {"not", 2, do_pseudo_not, 0, 0},
2940
2941 {"pop", 2, do_pseudo_pushpop, 0, 0},
2942 {"push", 2, do_pseudo_pushpop, 0, 0},
2943 {"popm", 2, do_pseudo_pushpopm, 0, 0},
2944 {"pushm", 3, do_pseudo_pushpopm, 0, 0},
2945
2946 {"v3push", 2, do_pseudo_v3push, 0, 0},
2947 {"v3pop", 2, do_pseudo_v3pop, 0, 0},
2948
2949 /* Support pseudo instructions of pushing/poping registers into/from stack
2950 push.s Rb, Re, { $fp $gp $lp $sp } ==> smw.adm Rb,[$sp],Re,Enable4
2951 pop.s Rb, Re, { $fp $gp $lp $sp } ==> lmw.bim Rb,[$sp],Re,Enable4 */
2952 { "push.s", 3, do_pseudo_pushpop_stack, 0, 0 },
2953 { "pop.s", 3, do_pseudo_pushpop_stack, 1, 0 },
2954 { "push.b", 2, do_pseudo_push_bhwd, 0, 0 },
2955 { "push.h", 2, do_pseudo_push_bhwd, 1, 0 },
2956 { "push.w", 2, do_pseudo_push_bhwd, 2, 0 },
2957 { "push.d", 2, do_pseudo_push_bhwd, 3, 0 },
2958 { "pop.b", 3, do_pseudo_pop_bhwd, 0, 0 },
2959 { "pop.h", 3, do_pseudo_pop_bhwd, 1, 0 },
2960 { "pop.w", 3, do_pseudo_pop_bhwd, 2, 0 },
2961 { "pop.d", 3, do_pseudo_pop_bhwd, 3, 0 },
2962 { "pusha", 2, do_pseudo_pusha, 0, 0 },
2963 { "pushi", 2, do_pseudo_pushi, 0, 0 },
2964
2965 {NULL, 0, NULL, 0, 0}
2966};
2967
2968static void
2969nds32_init_nds32_pseudo_opcodes (void)
2970{
2971 struct nds32_pseudo_opcode *opcode = nds32_pseudo_opcode_table;
2972
2973 nds32_pseudo_opcode_hash = hash_new ();
2974 for ( ; opcode->opcode; opcode++)
2975 {
2976 void *op;
2977
2978 op = hash_find (nds32_pseudo_opcode_hash, opcode->opcode);
2979 if (op != NULL)
2980 {
2981 as_warn (_("Duplicated pseudo-opcode %s."), opcode->opcode);
2982 continue;
2983 }
2984 hash_insert (nds32_pseudo_opcode_hash, opcode->opcode, opcode);
2985 }
2986}
2987
2988static struct nds32_pseudo_opcode *
2989nds32_lookup_pseudo_opcode (char *str)
2990{
2991 int i = 0;
2992 /* Assume pseudo-opcode are less than 16-char in length. */
2993 char op[16] = {0};
2994
2995 for (i = 0; i < (int)ARRAY_SIZE (op); i++)
2996 {
2997 if (ISSPACE (op[i] = str[i]))
2998 break;
2999 }
3000
3001 if (i >= (int)ARRAY_SIZE (op))
3002 return NULL;
3003
3004 op[i] = '\0';
3005
3006 return hash_find (nds32_pseudo_opcode_hash, op);
3007}
3008
3009static void
3010nds32_pseudo_opcode_wrapper (char *line, struct nds32_pseudo_opcode *opcode)
3011{
3012 int argc = 0;
3013 char *argv[8] = {NULL};
3014 char *s;
3015 char *str = xstrdup (line);
3016
3017 /* Parse arguments for opcode. */
3018 s = str + strlen (opcode->opcode);
3019
3020 if (!s[0])
3021 goto end;
3022
3023 /* Dummy comma to ease separate arguments as below. */
3024 s[0] = ',';
3025 do
3026 {
3027 if (s[0] == ',')
3028 {
3029 if (argc >= opcode->argc
3030 || (argc >= (int)ARRAY_SIZE (argv) - 1))
3031 as_bad (_("Too many argument. `%s'"), line);
3032
3033 argv[argc] = s + 1;
3034 argc ++;
3035 s[0] = '\0';
3036 }
3037 ++s;
3038 } while (s[0] != '\0');
3039end:
3040 /* Put the origin line for debugging. */
3041 argv[argc] = line;
3042 opcode->proc (argc, argv, opcode->pseudo_val);
3043 free (str);
3044}
3045\f
3046/* This function will be invoked from function `nds32_after_parse_args'.
3047 Thus, if the value of option has been set, keep the value the way it is. */
3048
3049static int
f86f5863 3050nds32_parse_arch (const char *str)
35c08157
KLC
3051{
3052 static const struct nds32_arch
3053 {
3054 const char *name;
3055 int baseline;
3056 int reduced_reg;
3057 int fpu_sp_ext;
3058 int fpu_dp_ext;
3059 int fpu_freg;
3060 int abi;
3061 } archs[] =
3062 {
3063 {"v3m", ISA_V3M, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
3064 {"v3j", ISA_V3, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
3065 {"v3s", ISA_V3, 0, 1, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
3066 {"v3f", ISA_V3, 0, 1, 1, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
3067 {"v3", ISA_V3, 0, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
3068 {"v2j", ISA_V2, 1, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
3069 {"v2s", ISA_V2, 0, 1, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
3070 {"v2f", ISA_V2, 0, 1, 1, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_V2FP_PLUS},
3071 {"v2", ISA_V2, 0, 0, 0, E_NDS32_FPU_REG_32SP_16DP, E_NDS_ABI_AABI},
3072 };
3073 size_t i;
3074
3075 for (i = 0; i < ARRAY_SIZE (archs); i++)
3076 {
3077 if (strcmp (str, archs[i].name) != 0)
3078 continue;
3079
3080 /* The value `-1' represents this option has *NOT* been set. */
3081 nds32_baseline = (-1 != nds32_baseline) ? nds32_baseline : archs[i].baseline;
3082 nds32_gpr16 = (-1 != nds32_gpr16) ? nds32_gpr16 : archs[i].reduced_reg;
3083 nds32_fpu_sp_ext = (-1 != nds32_fpu_sp_ext) ? nds32_fpu_sp_ext : archs[i].fpu_sp_ext;
3084 nds32_fpu_dp_ext = (-1 != nds32_fpu_dp_ext) ? nds32_fpu_dp_ext : archs[i].fpu_dp_ext;
3085 nds32_freg = (-1 != nds32_freg) ? nds32_freg : archs[i].fpu_freg;
3086 nds32_abi = (-1 != nds32_abi) ? nds32_abi : archs[i].abi;
3087
3088 return 1;
3089 }
3090
3091 /* Logic here rejects the input arch name. */
3092 as_bad (_("unknown arch name `%s'\n"), str);
3093
3094 return 1;
3095}
3096
3097/* This function parses "baseline" specified. */
3098
3099static int
f86f5863 3100nds32_parse_baseline (const char *str)
35c08157
KLC
3101{
3102 if (strcmp (str, "v3") == 0)
3103 nds32_baseline = ISA_V3;
3104 else if (strcmp (str, "v3m") == 0)
3105 nds32_baseline = ISA_V3M;
3106 else if (strcmp (str, "v2") == 0)
3107 nds32_baseline = ISA_V2;
3108 else
3109 {
3110 /* Logic here rejects the input baseline. */
3111 as_bad (_("unknown baseline `%s'\n"), str);
3112 return 0;
3113 }
3114
3115 return 1;
3116}
3117
3118/* This function parses "fpu-freg" specified. */
3119
3120static int
f86f5863 3121nds32_parse_freg (const char *str)
35c08157
KLC
3122{
3123 if (strcmp (str, "2") == 0)
3124 nds32_freg = E_NDS32_FPU_REG_32SP_16DP;
3125 else if (strcmp (str, "3") == 0)
3126 nds32_freg = E_NDS32_FPU_REG_32SP_32DP;
3127 else if (strcmp (str, "1") == 0)
3128 nds32_freg = E_NDS32_FPU_REG_16SP_8DP;
3129 else if (strcmp (str, "0") == 0)
3130 nds32_freg = E_NDS32_FPU_REG_8SP_4DP;
3131 else
3132 {
3133 /* Logic here rejects the input FPU configuration. */
3134 as_bad (_("unknown FPU configuration `%s'\n"), str);
3135 return 0;
3136 }
3137
3138 return 1;
3139}
3140
3141/* This function parse "abi=" specified. */
3142
3143static int
f86f5863 3144nds32_parse_abi (const char *str)
35c08157
KLC
3145{
3146 if (strcmp (str, "v2") == 0)
3147 nds32_abi = E_NDS_ABI_AABI;
3148 /* Obsolete. */
3149 else if (strcmp (str, "v2fp") == 0)
3150 nds32_abi = E_NDS_ABI_V2FP;
3151 else if (strcmp (str, "v1") == 0)
3152 nds32_abi = E_NDS_ABI_V1;
3153 else if (strcmp (str,"v2fpp") == 0)
3154 nds32_abi = E_NDS_ABI_V2FP_PLUS;
3155 else
3156 {
3157 /* Logic here rejects the input abi version. */
3158 as_bad (_("unknown ABI version`%s'\n"), str);
3159 return 0;
3160 }
3161
3162 return 1;
3163}
3164
3165/* This function turn on all extensions and instructions support. */
3166
3167static int
3168nds32_all_ext (void)
3169{
3170 nds32_mac = 1;
3171 nds32_div = 1;
3172 nds32_dx_regs = 1;
3173 nds32_16bit_ext = 1;
3174 nds32_perf_ext = 1;
3175 nds32_perf_ext2 = 1;
3176 nds32_string_ext = 1;
3177 nds32_audio_ext = 1;
3178 nds32_fpu_fma = 1;
3179 nds32_fpu_sp_ext = 1;
3180 nds32_fpu_dp_ext = 1;
3181
3182 return 1;
3183}
3184
3185/* GAS will call md_parse_option whenever getopt returns an unrecognized code,
3186 presumably indicating a special code value which appears in md_longopts.
3187 This function should return non-zero if it handled the option and zero
3188 otherwise. There is no need to print a message about an option not being
3189 recognized. This will be handled by the generic code. */
3190
3191int
3192nds32_parse_option (int c, char *arg)
3193{
3194 struct nds32_parse_option_table *coarse_tune;
3195 struct nds32_set_option_table *fine_tune;
3196 char *ptr_arg = NULL;
3197
3198 switch (c)
3199 {
3200 case OPTION_OPTIMIZE:
3201 optimize = 1;
3202 optimize_for_space = 0;
3203 break;
3204 case OPTION_OPTIMIZE_SPACE:
3205 optimize = 0;
3206 optimize_for_space = 1;
3207 break;
3208 case OPTION_BIG:
3209 target_big_endian = 1;
3210 break;
3211 case OPTION_LITTLE:
3212 target_big_endian = 0;
3213 break;
3214 case OPTION_TURBO:
3215 nds32_all_ext ();
3216 break;
3217 case OPTION_PIC:
3218 nds32_pic = 1;
3219 break;
3220 case OPTION_RELAX_FP_AS_GP_OFF:
3221 nds32_relax_fp_as_gp = 0;
3222 break;
3223 case OPTION_RELAX_B2BB_ON:
3224 nds32_relax_b2bb = 1;
3225 break;
3226 case OPTION_RELAX_ALL_OFF:
3227 nds32_relax_all = 0;
3228 break;
3229 default:
3230 /* Determination of which option table to search for to save time. */
1c8f6a4d
KLC
3231 if (!arg)
3232 return 0;
3233
35c08157 3234 ptr_arg = strchr (arg, '=');
1c8f6a4d 3235
35c08157
KLC
3236 if (ptr_arg)
3237 {
3238 /* Find the value after '='. */
3239 if (ptr_arg != NULL)
3240 ptr_arg++;
3241 for (coarse_tune = parse_opts; coarse_tune->name != NULL; coarse_tune++)
3242 {
3243 if (strncmp (arg, coarse_tune->name, (ptr_arg - arg)) == 0)
3244 {
3245 coarse_tune->func (ptr_arg);
3246 return 1;
3247 }
3248 }
3249 }
3250 else
3251 {
1c8f6a4d 3252 int disable = 0;
35c08157 3253
1c8f6a4d
KLC
3254 /* Filter out the Disable option first. */
3255 if (strncmp (arg, "no-", 3) == 0)
3256 {
3257 disable = 1;
3258 arg += 3;
3259 }
35c08157 3260
1c8f6a4d
KLC
3261 for (fine_tune = toggle_opts; fine_tune->name != NULL; fine_tune++)
3262 {
35c08157
KLC
3263 if (strcmp (arg, fine_tune->name) == 0)
3264 {
3265 if (fine_tune->var != NULL)
3266 *fine_tune->var = (disable) ? 0 : 1;
3267 return 1;
3268 }
3269 }
3270 }
3271 /* Nothing match. */
3272 return 0;
3273 }
3274
3275 return 1;
3276}
3277
3278/* tc_check_label */
3279
3280void
3281nds32_check_label (symbolS *label ATTRIBUTE_UNUSED)
3282{
3283 /* The code used to create BB is move to frob_label.
3284 They should go there. */
3285}
3286
3287static void
3288set_endian_little (int on)
3289{
3290 target_big_endian = !on;
3291}
3292
3293/* These functions toggles the generation of 16-bit. First encounter signals
3294 the beginning of not generating 16-bit instructions and next encounter
3295 signals the restoring back to default behavior. */
3296
3297static void
3298trigger_16bit (int trigger)
3299{
3300 enable_16bit = trigger;
3301}
3302
3303static int backup_16bit_mode;
3304static void
3305restore_16bit (int no_use ATTRIBUTE_UNUSED)
3306{
3307 enable_16bit = backup_16bit_mode;
3308}
3309
3310static void
3311off_16bit (int no_use ATTRIBUTE_UNUSED)
3312{
3313 backup_16bit_mode = enable_16bit;
3314 enable_16bit = 0;
3315}
3316
3317/* Built-in segments for small object. */
3318typedef struct nds32_seg_entryT
3319{
3320 segT s;
3321 const char *name;
3322 flagword flags;
3323} nds32_seg_entry;
3324
3325nds32_seg_entry nds32_seg_table[] =
3326{
3327 {NULL, ".sdata_f", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
3328 | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
3329 {NULL, ".sdata_b", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
3330 | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
3331 {NULL, ".sdata_h", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
3332 | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
3333 {NULL, ".sdata_w", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
3334 | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
3335 {NULL, ".sdata_d", SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA
3336 | SEC_HAS_CONTENTS | SEC_SMALL_DATA},
3337 {NULL, ".sbss_f", SEC_ALLOC | SEC_SMALL_DATA},
3338 {NULL, ".sbss_b", SEC_ALLOC | SEC_SMALL_DATA},
3339 {NULL, ".sbss_h", SEC_ALLOC | SEC_SMALL_DATA},
3340 {NULL, ".sbss_w", SEC_ALLOC | SEC_SMALL_DATA},
3341 {NULL, ".sbss_d", SEC_ALLOC | SEC_SMALL_DATA}
3342};
3343
3344/* Indexes to nds32_seg_table[]. */
3345enum NDS32_SECTIONS_ENUM
3346{
3347 SDATA_F_SECTION = 0,
3348 SDATA_B_SECTION = 1,
3349 SDATA_H_SECTION = 2,
3350 SDATA_W_SECTION = 3,
3351 SDATA_D_SECTION = 4,
3352 SBSS_F_SECTION = 5,
3353 SBSS_B_SECTION = 6,
3354 SBSS_H_SECTION = 7,
3355 SBSS_W_SECTION = 8,
3356 SBSS_D_SECTION = 9
3357};
3358
3359/* The following code is borrowed from v850_seg. Revise this is needed. */
3360
3361static void
3362do_nds32_seg (int i, subsegT sub)
3363{
3364 nds32_seg_entry *seg = nds32_seg_table + i;
3365
3366 obj_elf_section_change_hook ();
3367
3368 if (seg->s != NULL)
3369 subseg_set (seg->s, sub);
3370 else
3371 {
3372 seg->s = subseg_new (seg->name, sub);
3373 if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
3374 {
3375 bfd_set_section_flags (stdoutput, seg->s, seg->flags);
3376 if ((seg->flags & SEC_LOAD) == 0)
3377 seg_info (seg->s)->bss = 1;
3378 }
3379 }
3380}
3381
3382static void
3383nds32_seg (int i)
3384{
3385 subsegT sub = get_absolute_expression ();
3386
3387 do_nds32_seg (i, sub);
3388 demand_empty_rest_of_line ();
3389}
3390
3391/* Set if label adjustment is needed. I should not adjust .xbyte in dwarf. */
3392static symbolS *nds32_last_label; /* Last label for aligment. */
3393
3394/* This code is referred from D30V for adjust label to be with pedning
3395 aligment. For example,
3396 LBYTE: .byte 0x12
3397 LHALF: .half 0x12
3398 LWORD: .word 0x12
3399 Without this, the above label will not attatch to incoming data. */
3400
3401static void
3402nds32_adjust_label (int n)
3403{
3404 /* FIXME: I think adjust lable and alignment is
3405 the programmer's obligation. Saddly, VLSI team doesn't
3406 properly use .align for their test cases.
3407 So I re-implement cons_align and auto adjust labels, again.
3408
3409 I think d30v's implmentation is simple and good enough. */
3410
3411 symbolS *label = nds32_last_label;
3412 nds32_last_label = NULL;
3413
3414 /* SEC_ALLOC is used to eliminate .debug_ sections.
3415 SEC_CODE is used to include section for ILM. */
3416 if (((now_seg->flags & SEC_ALLOC) == 0 && (now_seg->flags & SEC_CODE) == 0)
3417 || strcmp (now_seg->name, ".eh_frame") == 0
3418 || strcmp (now_seg->name, ".gcc_except_table") == 0)
3419 return;
3420
3421 /* Only frag by alignment when needed.
3422 Otherwise, it will fail to optimize labels on 4-byte boundary. (bug8454)
3423 See md_convert_frag () and RELAX_SET_RELAXABLE (frag) for details. */
3424 if (frag_now_fix () & ((1 << n) -1 ))
3425 {
3426 if (subseg_text_p (now_seg))
3427 frag_align_code (n, 0);
3428 else
3429 frag_align (n, 0, 0);
3430
3431 /* Record the minimum alignment for this segment. */
3432 record_alignment (now_seg, n - OCTETS_PER_BYTE_POWER);
3433 }
3434
3435 if (label != NULL)
3436 {
3437 symbolS *sym;
3438 int label_seen = FALSE;
3439 struct frag *old_frag;
3440 valueT old_value, new_value;
3441
3442 gas_assert (S_GET_SEGMENT (label) == now_seg);
3443
3444 old_frag = symbol_get_frag (label);
3445 old_value = S_GET_VALUE (label);
3446 new_value = (valueT) frag_now_fix ();
3447
3448 /* Multiple labels may be on the same address. And the last symbol
3449 may not be a label at all, e.g., register name, external function names,
3450 so I have to track the last label in tc_frob_label instead of
3451 just using symbol_lastP. */
3452 for (sym = symbol_lastP; sym != NULL; sym = symbol_previous (sym))
3453 {
3454 if (symbol_get_frag (sym) == old_frag
3455 && S_GET_VALUE (sym) == old_value)
3456 {
3457 /* Warning HERE! */
3458 label_seen = TRUE;
3459 symbol_set_frag (sym, frag_now);
3460 S_SET_VALUE (sym, new_value);
3461 }
3462 else if (label_seen && symbol_get_frag (sym) != old_frag)
3463 break;
3464 }
3465 }
3466}
3467
3468void
3469nds32_cons_align (int size ATTRIBUTE_UNUSED)
3470{
3471 /* Do nothing here.
3472 This is called before `md_flush_pending_output' is called by `cons'.
3473
3474 There are two things should be done for auto-adjust-label.
3475 1. Align data/instructions and adjust label to be attached to them.
3476 2. Clear auto-adjust state, so incommng data/instructions will not
3477 adjust the label.
3478
3479 For example,
3480 .byte 0x1
3481 .L0:
3482 .word 0x2
3483 .word 0x3
3484 in this case, '.word 0x2' will adjust the label, .L0, but '.word 0x3' should not.
3485
3486 I think `md_flush_pending_output' is a good place to clear the auto-adjust state,
3487 but it is also called by `cons' before this function.
3488 To simplify the code, instead of overriding .zero, .fill, .space, etc,
3489 I think we should just adjust label in `nds32_aligned_X_cons' instead of here. */
3490}
3491
3492static void
3493nds32_aligned_cons (int idx)
3494{
3495 nds32_adjust_label (idx);
3496 /* Call default handler. */
3497 cons (1 << idx);
3498 if (now_seg->flags & SEC_CODE
3499 && now_seg->flags & SEC_ALLOC && now_seg->flags & SEC_RELOC)
3500 {
3501 /* Use BFD_RELOC_NDS32_DATA to avoid EX9 optimization replacing data. */
3502 expressionS exp;
3503
3504 exp.X_add_number = 0;
3505 exp.X_op = O_constant;
1c8f6a4d
KLC
3506 fix_new_exp (frag_now, frag_now_fix () - (1 << idx), 1 << idx,
3507 &exp, 0, BFD_RELOC_NDS32_DATA);
35c08157
KLC
3508 }
3509}
3510
3511/* `.double' directive. */
3512
3513static void
3514nds32_aligned_float_cons (int type)
3515{
3516 switch (type)
3517 {
3518 case 'f':
3519 case 'F':
3520 case 's':
3521 case 'S':
3522 nds32_adjust_label (2);
3523 break;
3524 case 'd':
3525 case 'D':
3526 case 'r':
3527 case 'R':
3528 nds32_adjust_label (4);
3529 break;
3530 default:
3531 as_bad ("Unrecognized float type, %c\n", (char)type);
3532 }
3533 /* Call default handler. */
3534 float_cons (type);
3535}
3536
3537static void
3538nds32_enable_pic (int ignore ATTRIBUTE_UNUSED)
3539{
3540 /* Another way to do -mpic.
3541 This is for GCC internal use and should always be first line
3542 of code, otherwise, the effect is not determined. */
3543 nds32_pic = 1;
3544}
3545
3546static void
3547nds32_set_abi (int ver)
3548{
3549 nds32_abi = ver;
3550}
3551
3552/* Relax directive to set relocation R_NDS32_RELAX_ENTRY value. */
3553
3554static void
3555nds32_relax_relocs (int relax)
3556{
3557 char saved_char;
3558 char *name;
3559 int i;
f86f5863 3560 const char *subtype_relax[] =
35c08157
KLC
3561 {"", "", "ex9", "ifc"};
3562
3563 name = input_line_pointer;
3564 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
3565 input_line_pointer++;
3566 saved_char = *input_line_pointer;
3567 *input_line_pointer = 0;
3568
3569 for (i = 0; i < (int) ARRAY_SIZE (subtype_relax); i++)
3570 {
3571 if (strcmp (name, subtype_relax[i]) == 0)
3572 {
3573 switch (i)
3574 {
3575 case 0:
3576 case 1:
3577 enable_relax_relocs = relax & enable_relax_relocs;
3578 enable_relax_ex9 = relax & enable_relax_ex9;
3579 enable_relax_ifc = relax & enable_relax_ifc;
3580 break;
3581 case 2:
3582 enable_relax_ex9 = relax;
3583 break;
3584 case 3:
3585 enable_relax_ifc = relax;
3586 break;
3587 default:
3588 break;
3589 }
3590 break;
3591 }
3592 }
3593 *input_line_pointer = saved_char;
3594 ignore_rest_of_line ();
3595}
3596
3597/* Record which arguments register($r0 ~ $r5) is not used in callee.
3598 bit[i] for $ri */
3599
3600static void
3601nds32_set_hint_func_args (int ignore ATTRIBUTE_UNUSED)
3602{
3603 ignore_rest_of_line ();
3604}
3605
3606/* Insert relocations to mark the begin and end of a fp-omitted function,
3607 for further relaxation use.
3608 bit[i] for $ri */
3609
3610static void
3611nds32_omit_fp_begin (int mode)
3612{
3613 expressionS exp;
3614
3615 if (nds32_relax_fp_as_gp == 0)
3616 return;
3617 exp.X_op = O_symbol;
3618 exp.X_add_symbol = abs_section_sym;
3619 if (mode == 1)
3620 {
1c8f6a4d 3621 in_omit_fp = 1;
35c08157
KLC
3622 exp.X_add_number = R_NDS32_RELAX_REGION_OMIT_FP_FLAG;
3623 fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
3624 BFD_RELOC_NDS32_RELAX_REGION_BEGIN);
3625 }
3626 else
3627 {
1c8f6a4d 3628 in_omit_fp = 0;
35c08157
KLC
3629 exp.X_add_number = R_NDS32_RELAX_REGION_OMIT_FP_FLAG;
3630 fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
3631 BFD_RELOC_NDS32_RELAX_REGION_END);
3632 }
3633}
3634
3635/* Insert relocations to mark the begin and end of ex9 region,
3636 for further relaxation use.
3637 bit[i] for $ri */
3638
3639static void
3640nds32_no_ex9_begin (int mode)
3641{
3642 expressionS exp;
3643
3644 exp.X_op = O_symbol;
3645 exp.X_add_symbol = abs_section_sym;
3646 if (mode == 1)
3647 {
3648 exp.X_add_number = R_NDS32_RELAX_REGION_NO_EX9_FLAG;
3649 fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
3650 BFD_RELOC_NDS32_RELAX_REGION_BEGIN);
3651 }
3652 else
3653 {
3654 exp.X_add_number = R_NDS32_RELAX_REGION_NO_EX9_FLAG;
3655 fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
3656 BFD_RELOC_NDS32_RELAX_REGION_END);
3657 }
3658}
3659
3660static void
3661nds32_loop_begin (int mode)
3662{
3663 /* Insert loop region relocation here. */
3664 expressionS exp;
3665
3666 exp.X_op = O_symbol;
3667 exp.X_add_symbol = abs_section_sym;
3668 if (mode == 1)
3669 {
3670 exp.X_add_number = R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG;
3671 fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
3672 BFD_RELOC_NDS32_RELAX_REGION_BEGIN);
3673 }
3674 else
3675 {
3676 exp.X_add_number = R_NDS32_RELAX_REGION_INNERMOST_LOOP_FLAG;
3677 fix_new_exp (frag_now, frag_now_fix (), 0, &exp, 0,
3678 BFD_RELOC_NDS32_RELAX_REGION_END);
3679 }
3680}
3681
3682struct nds32_relocs_group
3683{
3684 struct nds32_relocs_pattern *pattern;
3685 struct nds32_relocs_group *next;
3686};
3687
3688static struct nds32_relocs_group *nds32_relax_hint_current = NULL;
3689
3690/* Insert a relax hint. */
3691
3692static void
3693nds32_relax_hint (int mode ATTRIBUTE_UNUSED)
3694{
3695 char *name;
3696 char saved_char;
3697 struct nds32_relocs_pattern *relocs = NULL;
3698 struct nds32_relocs_group *group, *new;
3699
3700 name = input_line_pointer;
3701 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
3702 input_line_pointer++;
3703 saved_char = *input_line_pointer;
3704 *input_line_pointer = 0;
3705 name = strdup (name);
3706
3707 /* Find relax hint entry for next instruction, and all member will be
3708 initialized at that time. */
3709 relocs = hash_find (nds32_hint_hash, name);
3710 if (relocs == NULL)
3711 {
3712 relocs = malloc (sizeof (struct nds32_relocs_pattern));
3713 hash_insert (nds32_hint_hash, name, relocs);
3714 }
3715 else
3716 {
3717 while (relocs->next)
3718 relocs=relocs->next;
3719 relocs->next = malloc (sizeof (struct nds32_relocs_pattern));
3720 relocs = relocs->next;
3721 }
3722
3723 relocs->next = NULL;
3724 *input_line_pointer = saved_char;
3725 ignore_rest_of_line ();
3726
3727 /* Get the final one of relax hint series. */
3728
3729 /* It has to build this list because there are maybe more than one
3730 instructions relative to the same instruction. It to connect to
3731 next instruction after md_assemble. */
3732 new = malloc (sizeof (struct nds32_relocs_group));
3733 new->pattern = relocs;
3734 new->next = NULL;
3735 group = nds32_relax_hint_current;
3736 if (!group)
3737 nds32_relax_hint_current = new;
3738 else
3739 {
3740 while (group->next != NULL)
3741 group = group->next;
3742 group->next = new;
3743 }
1c8f6a4d 3744 relaxing = TRUE;
35c08157
KLC
3745}
3746
3747/* Decide the size of vector entries, only accepts 4 or 16 now. */
3748
3749static void
3750nds32_vec_size (int ignore ATTRIBUTE_UNUSED)
3751{
3752 expressionS exp;
3753
3754 expression (&exp);
3755
3756 if (exp.X_op == O_constant)
3757 {
3758 if (exp.X_add_number == 4 || exp.X_add_number == 16)
3759 {
3760 if (vec_size == 0)
3761 vec_size = exp.X_add_number;
3762 else if (vec_size != exp.X_add_number)
3763 as_warn (_("Different arguments of .vec_size are found, "
3764 "previous %d, current %d"),
3765 (int) vec_size, (int) exp.X_add_number);
3766 }
3767 else
3768 as_warn (_("Argument of .vec_size is expected 4 or 16, actual: %d."),
3769 (int) exp.X_add_number);
3770 }
3771 else
3772 as_warn (_("Argument of .vec_size is not a constant."));
3773}
3774
3775/* The behavior of ".flag" directive varies depending on the target.
3776 In nds32 target, we use it to recognize whether this assembly content is
3777 generated by compiler. Other features can also be added in this function
3778 in the future. */
3779
3780static void
3781nds32_flag (int ignore ATTRIBUTE_UNUSED)
3782{
3783 char *name;
3784 char saved_char;
3785 int i;
f86f5863 3786 const char *possible_flags[] = { "verbatim" };
35c08157
KLC
3787
3788 /* Skip whitespaces. */
3789 name = input_line_pointer;
3790 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
3791 input_line_pointer++;
3792 saved_char = *input_line_pointer;
3793 *input_line_pointer = 0;
3794
3795 for (i = 0; i < (int) ARRAY_SIZE (possible_flags); i++)
3796 {
3797 if (strcmp (name, possible_flags[i]) == 0)
3798 {
3799 switch (i)
3800 {
3801 case 0:
3802 /* flag: verbatim */
3803 verbatim = 1;
3804 break;
3805 default:
3806 break;
3807 }
3808 /* Already found the flag, no need to continue next loop. */
3809 break;
3810 }
3811 }
3812
3813 *input_line_pointer = saved_char;
3814 ignore_rest_of_line ();
3815}
3816
3817static void
3818nds32_n12hc (int ignore ATTRIBUTE_UNUSED)
3819{
3820 /* N1213HC core is used. */
3821}
3822
3823
3824/* The target specific pseudo-ops which we support. */
3825const pseudo_typeS md_pseudo_table[] =
3826{
3827 /* Forced alignment if declared these ways. */
3828 {"ascii", stringer, 8 + 0},
3829 {"asciz", stringer, 8 + 1},
3830 {"double", nds32_aligned_float_cons, 'd'},
3831 {"dword", nds32_aligned_cons, 3},
3832 {"float", nds32_aligned_float_cons, 'f'},
3833 {"half", nds32_aligned_cons, 1},
3834 {"hword", nds32_aligned_cons, 1},
3835 {"int", nds32_aligned_cons, 2},
3836 {"long", nds32_aligned_cons, 2},
3837 {"octa", nds32_aligned_cons, 4},
3838 {"quad", nds32_aligned_cons, 3},
3839 {"qword", nds32_aligned_cons, 4},
3840 {"short", nds32_aligned_cons, 1},
3841 {"byte", nds32_aligned_cons, 0},
3842 {"single", nds32_aligned_float_cons, 'f'},
3843 {"string", stringer, 8 + 1},
3844 {"word", nds32_aligned_cons, 2},
3845
3846 {"little", set_endian_little, 1},
3847 {"big", set_endian_little, 0},
3848 {"16bit_on", trigger_16bit, 1},
3849 {"16bit_off", trigger_16bit, 0},
3850 {"restore_16bit", restore_16bit, 0},
3851 {"off_16bit", off_16bit, 0},
3852
3853 {"sdata_d", nds32_seg, SDATA_D_SECTION},
3854 {"sdata_w", nds32_seg, SDATA_W_SECTION},
3855 {"sdata_h", nds32_seg, SDATA_H_SECTION},
3856 {"sdata_b", nds32_seg, SDATA_B_SECTION},
3857 {"sdata_f", nds32_seg, SDATA_F_SECTION},
3858
3859 {"sbss_d", nds32_seg, SBSS_D_SECTION},
3860 {"sbss_w", nds32_seg, SBSS_W_SECTION},
3861 {"sbss_h", nds32_seg, SBSS_H_SECTION},
3862 {"sbss_b", nds32_seg, SBSS_B_SECTION},
3863 {"sbss_f", nds32_seg, SBSS_F_SECTION},
3864
3865 {"pic", nds32_enable_pic, 0},
3866 {"n12_hc", nds32_n12hc, 0},
3867 {"abi_1", nds32_set_abi, E_NDS_ABI_V1},
3868 {"abi_2", nds32_set_abi, E_NDS_ABI_AABI},
3869 /* Obsolete. */
3870 {"abi_2fp", nds32_set_abi, E_NDS_ABI_V2FP},
3871 {"abi_2fp_plus", nds32_set_abi, E_NDS_ABI_V2FP_PLUS},
3872 {"relax", nds32_relax_relocs, 1},
3873 {"no_relax", nds32_relax_relocs, 0},
3874 {"hint_func_args", nds32_set_hint_func_args, 0}, /* Abandon?? */
3875 {"omit_fp_begin", nds32_omit_fp_begin, 1},
3876 {"omit_fp_end", nds32_omit_fp_begin, 0},
3877 {"no_ex9_begin", nds32_no_ex9_begin, 1},
3878 {"no_ex9_end", nds32_no_ex9_begin, 0},
3879 {"vec_size", nds32_vec_size, 0},
3880 {"flag", nds32_flag, 0},
3881 {"innermost_loop_begin", nds32_loop_begin, 1},
3882 {"innermost_loop_end", nds32_loop_begin, 0},
3883 {"relax_hint", nds32_relax_hint, 0},
3884 {NULL, NULL, 0}
3885};
3886
3887void
3888nds32_pre_do_align (int n, char *fill, int len, int max)
3889{
3890 /* Only make a frag if we HAVE to... */
1c8f6a4d 3891 fragS *fragP;
35c08157
KLC
3892 if (n != 0 && !need_pass_2)
3893 {
3894 if (fill == NULL)
3895 {
3896 if (subseg_text_p (now_seg))
1c8f6a4d 3897 {
ea16498d 3898 dwarf2_emit_insn (0);
1c8f6a4d
KLC
3899 fragP = frag_now;
3900 frag_align_code (n, max);
3901
3902 /* Tag this alignment when there is a lable before it. */
3903 if (label_exist)
3904 {
3905 fragP->tc_frag_data.flag = NDS32_FRAG_LABEL;
3906 label_exist = 0;
3907 }
3908 }
35c08157
KLC
3909 else
3910 frag_align (n, 0, max);
3911 }
3912 else if (len <= 1)
3913 frag_align (n, *fill, max);
3914 else
3915 frag_align_pattern (n, fill, len, max);
3916 }
3917}
3918
3919void
3920nds32_do_align (int n)
3921{
3922 /* Optimize for space and label exists. */
3923 expressionS exp;
3924
3925 /* FIXME:I think this will break debug info sections and except_table. */
3926 if (!enable_relax_relocs || !subseg_text_p (now_seg))
3927 return;
3928
3929 /* Create and attach a BFD_RELOC_NDS32_LABEL fixup
3930 the size of instruction may not be correct because
3931 it could be relaxable. */
3932 exp.X_op = O_symbol;
3933 exp.X_add_symbol = section_symbol (now_seg);
3934 exp.X_add_number = n;
3935 fix_new_exp (frag_now,
3936 frag_now_fix (), 0, &exp, 0, BFD_RELOC_NDS32_LABEL);
3937}
3938
3939/* Supported Andes machines. */
3940struct nds32_machs
3941{
3942 enum bfd_architecture bfd_mach;
3943 int mach_flags;
3944};
3945
3946/* This is the callback for nds32-asm.c to parse operands. */
3947
3948int
3949nds32_asm_parse_operand (struct nds32_asm_desc *pdesc ATTRIBUTE_UNUSED,
3950 struct nds32_asm_insn *pinsn,
3951 char **pstr, int64_t *value)
3952{
3953 char *hold;
3954 expressionS *pexp = pinsn->info;
3955
3956 hold = input_line_pointer;
3957 input_line_pointer = *pstr;
3958 expression (pexp);
3959 *pstr = input_line_pointer;
3960 input_line_pointer = hold;
3961
3962 switch (pexp->X_op)
3963 {
3964 case O_symbol:
3965 *value = 0;
3966 return NASM_R_SYMBOL;
3967 case O_constant:
3968 *value = pexp->X_add_number;
3969 return NASM_R_CONST;
3970 case O_illegal:
3971 case O_absent:
3972 case O_register:
3973 default:
3974 return NASM_R_ILLEGAL;
3975 }
3976}
3977
3978/* GAS will call this function at the start of the assembly, after the command
3979 line arguments have been parsed and all the machine independent
3980 initializations have been completed. */
3981
3982void
3983md_begin (void)
3984{
3985 struct nds32_keyword *k;
3986 relax_info_t *relax_info;
3987
3988 bfd_set_arch_mach (stdoutput, TARGET_ARCH, nds32_baseline);
3989
3990 nds32_init_nds32_pseudo_opcodes ();
3991 asm_desc.parse_operand = nds32_asm_parse_operand;
3992 nds32_asm_init (&asm_desc, 0);
3993
3994 /* Initial general pupose registers hash table. */
3995 nds32_gprs_hash = hash_new ();
1c8f6a4d 3996 for (k = keyword_gpr; k->name; k++)
35c08157
KLC
3997 hash_insert (nds32_gprs_hash, k->name, k);
3998
3999 /* Initial branch hash table. */
4000 nds32_relax_info_hash = hash_new ();
4001 for (relax_info = relax_table; relax_info->opcode; relax_info++)
4002 hash_insert (nds32_relax_info_hash, relax_info->opcode, relax_info);
4003
4004 /* Initial relax hint hash table. */
4005 nds32_hint_hash = hash_new ();
1c8f6a4d 4006 enable_16bit = nds32_16bit_ext;
35c08157
KLC
4007}
4008
4009/* HANDLE_ALIGN in write.c. */
4010
4011void
4012nds32_handle_align (fragS *fragp)
4013{
4014 static const unsigned char nop16[] = { 0x92, 0x00 };
4015 static const unsigned char nop32[] = { 0x40, 0x00, 0x00, 0x09 };
4016 int bytes;
4017 char *p;
4018
4019 if (fragp->fr_type != rs_align_code)
4020 return;
4021
4022 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
4023 p = fragp->fr_literal + fragp->fr_fix;
4024
4025 if (bytes & 1)
4026 {
4027 *p++ = 0;
4028 bytes--;
4029 }
4030
4031 if (bytes & 2)
4032 {
4033 expressionS exp_t;
4034 exp_t.X_op = O_symbol;
4035 exp_t.X_add_symbol = abs_section_sym;
4036 exp_t.X_add_number = R_NDS32_INSN16_CONVERT_FLAG;
4037 fix_new_exp (fragp, fragp->fr_fix, 2, &exp_t, 0,
4038 BFD_RELOC_NDS32_INSN16);
4039 memcpy (p, nop16, 2);
4040 p += 2;
4041 bytes -= 2;
4042 }
4043
4044 while (bytes >= 4)
4045 {
4046 memcpy (p, nop32, 4);
4047 p += 4;
4048 bytes -= 4;
4049 }
4050
4051 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
4052 fragp->fr_fix += bytes;
4053}
4054
4055/* md_flush_pending_output */
4056
4057void
4058nds32_flush_pending_output (void)
4059{
4060 nds32_last_label = NULL;
4061}
4062
4063void
4064nds32_frob_label (symbolS *label)
4065{
4066 dwarf2_emit_label (label);
4067}
4068
4069/* TC_START_LABEL */
4070
4071int
4072nds32_start_label (int asmdone ATTRIBUTE_UNUSED, int secdone ATTRIBUTE_UNUSED)
4073{
1c8f6a4d
KLC
4074 if (optimize && subseg_text_p (now_seg))
4075 label_exist = 1;
35c08157
KLC
4076 return 1;
4077}
4078
4079/* TARGET_FORMAT */
4080
4081const char *
4082nds32_target_format (void)
4083{
4084#ifdef TE_LINUX
4085 if (target_big_endian)
4086 return "elf32-nds32be-linux";
4087 else
4088 return "elf32-nds32le-linux";
4089#else
4090 if (target_big_endian)
4091 return "elf32-nds32be";
4092 else
4093 return "elf32-nds32le";
4094#endif
4095}
4096
4097static enum nds32_br_range
4098get_range_type (const struct nds32_field *field)
4099{
4100 gas_assert (field != NULL);
4101
4102 if (field->bitpos != 0)
4103 return BR_RANGE_U4G;
4104
4105 if (field->bitsize == 24 && field->shift == 1)
4106 return BR_RANGE_S16M;
4107 else if (field->bitsize == 16 && field->shift == 1)
4108 return BR_RANGE_S64K;
4109 else if (field->bitsize == 14 && field->shift == 1)
4110 return BR_RANGE_S16K;
4111 else if (field->bitsize == 8 && field->shift == 1)
4112 return BR_RANGE_S256;
4113 else
4114 return BR_RANGE_U4G;
4115}
4116
4117/* Save pseudo instruction relocation list. */
4118
4119static struct nds32_relocs_pattern*
1c8f6a4d 4120nds32_elf_save_pseudo_pattern (fixS* fixP, struct nds32_opcode *opcode,
35c08157 4121 char *out, symbolS *sym,
1c8f6a4d
KLC
4122 struct nds32_relocs_pattern *reloc_ptr,
4123 fragS *fragP)
35c08157
KLC
4124{
4125 if (!reloc_ptr)
4126 reloc_ptr = malloc (sizeof (struct nds32_relocs_pattern));
4127 reloc_ptr->seg = now_seg;
4128 reloc_ptr->sym = sym;
1c8f6a4d 4129 reloc_ptr->frag = fragP;
35c08157 4130 reloc_ptr->frchain = frchain_now;
1c8f6a4d
KLC
4131 reloc_ptr->fixP = fixP;
4132 reloc_ptr->opcode = opcode;
35c08157
KLC
4133 reloc_ptr->where = out;
4134 reloc_ptr->next = NULL;
4135 return reloc_ptr;
4136}
4137
4138/* Check X_md to transform relocation. */
4139
1c8f6a4d
KLC
4140static fixS*
4141nds32_elf_record_fixup_exp (fragS *fragP, char *str,
4142 const struct nds32_field *fld,
35c08157
KLC
4143 expressionS *pexp, char* out,
4144 struct nds32_asm_insn *insn)
4145{
4146 int reloc = -1;
1c8f6a4d
KLC
4147 expressionS exp;
4148 fixS *fixP = NULL;
35c08157
KLC
4149
4150 /* Handle instruction relocation. */
4151 if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_HI20))
4152 {
4153 /* Relocation for hi20 modifier. */
35c08157
KLC
4154 switch (pexp->X_md)
4155 {
1c8f6a4d 4156 case BFD_RELOC_NDS32_GOTOFF: /* @GOTOFF */
35c08157
KLC
4157 reloc = BFD_RELOC_NDS32_GOTOFF_HI20;
4158 break;
1c8f6a4d 4159 case BFD_RELOC_NDS32_GOT20: /* @GOT */
35c08157
KLC
4160 reloc = BFD_RELOC_NDS32_GOT_HI20;
4161 break;
1c8f6a4d 4162 case BFD_RELOC_NDS32_25_PLTREL: /* @PLT */
35c08157
KLC
4163 if (!nds32_pic)
4164 as_bad (_("Invalid PIC expression."));
4165 else
4166 reloc = BFD_RELOC_NDS32_PLT_GOTREL_HI20;
4167 break;
1c8f6a4d
KLC
4168 case BFD_RELOC_NDS32_GOTPC20: /* _GLOBAL_OFFSET_TABLE_ */
4169 reloc = BFD_RELOC_NDS32_GOTPC_HI20;
4170 break;
4171 case BFD_RELOC_NDS32_TPOFF: /* @TPOFF */
4172 reloc = BFD_RELOC_NDS32_TLS_LE_HI20;
4173 break;
4174 case BFD_RELOC_NDS32_GOTTPOFF: /* @GOTTPOFF */
4175 reloc = BFD_RELOC_NDS32_TLS_IE_HI20;
4176 break;
4177 default: /* No suffix. */
35c08157
KLC
4178 reloc = BFD_RELOC_NDS32_HI20;
4179 break;
4180 }
1c8f6a4d
KLC
4181 fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
4182 insn->info, 0 /* pcrel */, reloc);
35c08157
KLC
4183 }
4184 else if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_LO12))
4185 {
4186 /* Relocation for lo12 modifier. */
4187 if (fld->bitsize == 15 && fld->shift == 0)
4188 {
1c8f6a4d 4189 /* [ls]bi || ori */
35c08157
KLC
4190 switch (pexp->X_md)
4191 {
1c8f6a4d 4192 case BFD_RELOC_NDS32_GOTOFF: /* @GOTOFF */
35c08157
KLC
4193 reloc = BFD_RELOC_NDS32_GOTOFF_LO12;
4194 break;
1c8f6a4d 4195 case BFD_RELOC_NDS32_GOT20: /* @GOT */
35c08157
KLC
4196 reloc = BFD_RELOC_NDS32_GOT_LO12;
4197 break;
1c8f6a4d 4198 case BFD_RELOC_NDS32_25_PLTREL: /* @PLT */
35c08157
KLC
4199 if (!nds32_pic)
4200 as_bad (_("Invalid PIC expression."));
4201 else
4202 reloc = BFD_RELOC_NDS32_PLT_GOTREL_LO12;
4203 break;
1c8f6a4d
KLC
4204 case BFD_RELOC_NDS32_GOTPC20: /* _GLOBAL_OFFSET_TABLE_ */
4205 reloc = BFD_RELOC_NDS32_GOTPC_LO12;
4206 break;
4207 case BFD_RELOC_NDS32_TPOFF: /* @TPOFF */
4208 reloc = BFD_RELOC_NDS32_TLS_LE_LO12;
4209 break;
4210 default: /* No suffix. */
4211 reloc = BFD_RELOC_NDS32_LO12S0;
35c08157
KLC
4212 break;
4213 }
4214 }
4215 else if (fld->bitsize == 15 && fld->shift == 1)
4216 reloc = BFD_RELOC_NDS32_LO12S1; /* [ls]hi */
4217 else if (fld->bitsize == 15 && fld->shift == 2)
1c8f6a4d
KLC
4218 {
4219 /* [ls]wi */
4220 switch (pexp->X_md)
4221 {
4222 case BFD_RELOC_NDS32_GOTTPOFF: /* @GOTTPOFF */
4223 reloc = BFD_RELOC_NDS32_TLS_IE_LO12S2;
4224 break;
4225 default: /* No suffix. */
4226 reloc = BFD_RELOC_NDS32_LO12S2;
4227 break;
4228 }
4229 }
35c08157
KLC
4230 else if (fld->bitsize == 15 && fld->shift == 3)
4231 reloc = BFD_RELOC_NDS32_LO12S3; /* [ls]di */
4232 else if (fld->bitsize == 12 && fld->shift == 2)
1c8f6a4d 4233 reloc = R_NDS32_LO12S2_SP_RELA; /* f[ls][sd]i */
35c08157 4234
1c8f6a4d
KLC
4235 fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
4236 insn->info, 0 /* pcrel */, reloc);
35c08157
KLC
4237 }
4238 else if (fld && fld->bitpos == 0 && insn->opcode->isize == 4
4239 && (insn->attr & NASM_ATTR_PCREL))
4240 {
4241 /* Relocation for 32-bit branch instructions. */
4242 if (fld->bitsize == 24 && fld->shift == 1)
4243 reloc = BFD_RELOC_NDS32_25_PCREL;
4244 else if (fld->bitsize == 16 && fld->shift == 1)
4245 reloc = BFD_RELOC_NDS32_17_PCREL;
4246 else if (fld->bitsize == 14 && fld->shift == 1)
4247 reloc = BFD_RELOC_NDS32_15_PCREL;
4248 else if (fld->bitsize == 8 && fld->shift == 1)
4249 reloc = BFD_RELOC_NDS32_WORD_9_PCREL;
4250 else
4251 abort ();
4252
1c8f6a4d
KLC
4253 fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
4254 insn->info, 1 /* pcrel */, reloc);
35c08157
KLC
4255 }
4256 else if (fld && fld->bitpos == 0 && insn->opcode->isize == 4
4257 && (insn->attr & NASM_ATTR_GPREL))
4258 {
4259 /* Relocation for 32-bit gp-relative instructions. */
4260 if (fld->bitsize == 19 && fld->shift == 0)
4261 reloc = BFD_RELOC_NDS32_SDA19S0;
4262 else if (fld->bitsize == 18 && fld->shift == 1)
4263 reloc = BFD_RELOC_NDS32_SDA18S1;
4264 else if (fld->bitsize == 17 && fld->shift == 2)
4265 reloc = BFD_RELOC_NDS32_SDA17S2;
4266 else
4267 abort ();
4268
1c8f6a4d
KLC
4269 fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
4270 insn->info, 0 /* pcrel */, reloc);
4271 /* Insert INSN16 for converting fp_as_gp. */
4272 exp.X_op = O_symbol;
4273 exp.X_add_symbol = abs_section_sym;
4274 exp.X_add_number = 0;
4275 if (in_omit_fp && reloc == BFD_RELOC_NDS32_SDA17S2)
4276 fix_new_exp (fragP, out - fragP->fr_literal,
4277 insn->opcode->isize, &exp, 0 /* pcrel */,
4278 BFD_RELOC_NDS32_INSN16);
35c08157
KLC
4279 }
4280 else if (fld && fld->bitpos == 0 && insn->opcode->isize == 2
4281 && (insn->attr & NASM_ATTR_PCREL))
4282 {
4283 /* Relocation for 16-bit branch instructions. */
4284 if (fld->bitsize == 8 && fld->shift == 1)
4285 reloc = BFD_RELOC_NDS32_9_PCREL;
4286 else
4287 abort ();
4288
1c8f6a4d
KLC
4289 fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
4290 insn->info, 1 /* pcrel */, reloc);
35c08157 4291 }
1c8f6a4d
KLC
4292 else if (fld && fld->bitpos == 0 && (insn->attr & NASM_ATTR_IFC_EXT))
4293 {
4294 /* Relocation for ifcall instruction. */
4295 if (insn->opcode->isize == 2 && fld->bitsize == 9 && fld->shift == 1)
4296 reloc = BFD_RELOC_NDS32_10IFCU_PCREL;
4297 else if (insn->opcode->isize == 4 && fld->bitsize == 16
4298 && fld->shift == 1)
4299 reloc = BFD_RELOC_NDS32_17IFC_PCREL;
4300 else
4301 abort ();
4302
4303 fixP = fix_new_exp (fragP, out - fragP->fr_literal, insn->opcode->isize,
4304 insn->info, 1 /* pcrel */, reloc);
35c08157 4305 }
1c8f6a4d
KLC
4306 else if (fld)
4307 as_bad (_("Don't know how to handle this field. %s"), str);
4308
4309 return fixP;
4310}
4311
4312/* Build instruction pattern to relax. There are two type group pattern
4313 including pseudo instruction and relax hint. */
4314
4315static void
4316nds32_elf_build_relax_relation (fixS *fixP, expressionS *pexp, char* out,
4317 struct nds32_opcode *opcode, fragS *fragP,
4318 const struct nds32_field *fld)
4319{
4320 struct nds32_relocs_pattern *reloc_ptr;
4321 struct nds32_relocs_group *group;
4322 symbolS *sym = NULL;
4323
4324 /* The expression may be used uninitialized. */
4325 if (fld)
4326 sym = pexp->X_add_symbol;
35c08157
KLC
4327
4328 if (pseudo_opcode)
4329 {
4330 /* Save instruction relation for pseudo instruction expanding pattern. */
1c8f6a4d
KLC
4331 reloc_ptr = nds32_elf_save_pseudo_pattern (fixP, opcode, out, sym,
4332 NULL, fragP);
35c08157
KLC
4333 if (!relocs_list)
4334 relocs_list = reloc_ptr;
4335 else
4336 {
4337 struct nds32_relocs_pattern *temp = relocs_list;
4338 while (temp->next)
4339 temp = temp->next;
4340 temp->next = reloc_ptr;
4341 }
4342 }
4343 else if (nds32_relax_hint_current)
4344 {
4345 /* Save instruction relation by relax hint. */
4346 group = nds32_relax_hint_current;
4347 while (group)
4348 {
1c8f6a4d
KLC
4349 nds32_elf_save_pseudo_pattern (fixP, opcode, out, sym,
4350 group->pattern, fragP);
35c08157
KLC
4351 group = group->next;
4352 free (nds32_relax_hint_current);
4353 nds32_relax_hint_current = group;
4354 }
4355 }
1c8f6a4d
KLC
4356
4357 /* Set relaxing false only for relax_hint trigger it. */
4358 if (!pseudo_opcode)
4359 relaxing = FALSE;
35c08157
KLC
4360}
4361
1c8f6a4d 4362#define N32_MEM_EXT(insn) ((N32_OP6_MEM << 25) | insn)
35c08157
KLC
4363
4364/* Relax pattern for link time relaxation. */
4365
1c8f6a4d 4366static struct nds32_relax_hint_table relax_ls_table[] =
35c08157 4367{
1c8f6a4d
KLC
4368 {
4369 /* Set address: la -> sethi ori. */
4370 NDS32_RELAX_HINT_LA, /* main_type */
4371 8, /* relax_code_size */
35c08157 4372 {
1c8f6a4d
KLC
4373 OP6 (SETHI),
4374 OP6 (ORI),
4375 }, /* relax_code_seq */
35c08157 4376 {
1c8f6a4d
KLC
4377 {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
4378 {4, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_INSN16}
4379 } /* relax_fixup */
4380 },
4381 {
4382 /* Set address: l.w -> sethi ori. */
4383 NDS32_RELAX_HINT_LS, /* main_type */
4384 8, /* relax_code_size */
35c08157 4385 {
1c8f6a4d
KLC
4386 OP6 (SETHI),
4387 OP6 (LBI),
4388 }, /* relax_code_seq */
35c08157 4389 {
1c8f6a4d
KLC
4390 {0, 4, NDS32_HINT | NDS32_ADDEND, BFD_RELOC_NDS32_LOADSTORE},
4391 {4, 4, NDS32_HINT | NDS32_ABS, BFD_RELOC_NDS32_INSN16}
4392 } /* relax_fixup */
4393 },
4394 {
4395 0,
4396 0,
4397 {0},
4398 {{0, 0 , 0, 0}}
4399 }
35c08157
KLC
4400};
4401
4402/* Since sethi loadstore relocation has to using next instruction to determine
4403 elimination itself or not, we have to return the next instruction range. */
4404
4405static int
1c8f6a4d 4406nds32_elf_sethi_range (struct nds32_relocs_pattern *pattern)
35c08157 4407{
1c8f6a4d
KLC
4408 int range = 0;
4409 while (pattern)
35c08157 4410 {
1c8f6a4d 4411 switch (pattern->opcode->value)
35c08157 4412 {
1c8f6a4d
KLC
4413 case INSN_LBI:
4414 case INSN_SBI:
4415 case INSN_LBSI:
4416 case N32_MEM_EXT (N32_MEM_LB):
4417 case N32_MEM_EXT (N32_MEM_LBS):
4418 case N32_MEM_EXT (N32_MEM_SB):
4419 range = NDS32_LOADSTORE_BYTE;
4420 break;
4421 case INSN_LHI:
4422 case INSN_SHI:
4423 case INSN_LHSI:
4424 case N32_MEM_EXT (N32_MEM_LH):
4425 case N32_MEM_EXT (N32_MEM_LHS):
4426 case N32_MEM_EXT (N32_MEM_SH):
4427 range = NDS32_LOADSTORE_HALF;
4428 break;
4429 case INSN_LWI:
4430 case INSN_SWI:
4431 case N32_MEM_EXT (N32_MEM_LW):
4432 case N32_MEM_EXT (N32_MEM_SW):
4433 range = NDS32_LOADSTORE_WORD;
4434 break;
4435 case INSN_FLSI:
4436 case INSN_FSSI:
4437 range = NDS32_LOADSTORE_FLOAT_S;
4438 break;
4439 case INSN_FLDI:
4440 case INSN_FSDI:
4441 range = NDS32_LOADSTORE_FLOAT_D;
4442 break;
4443 case INSN_ORI:
4444 range = NDS32_LOADSTORE_IMM;
4445 break;
4446 default:
4447 range = NDS32_LOADSTORE_NONE;
4448 break;
35c08157 4449 }
1c8f6a4d
KLC
4450 if (range != NDS32_LOADSTORE_NONE)
4451 break;
4452 pattern = pattern->next;
35c08157 4453 }
1c8f6a4d 4454 return range;
35c08157
KLC
4455}
4456
1c8f6a4d
KLC
4457/* The args means: instruction size, the 1st instruction is converted to 16 or
4458 not, optimize option, 16 bit instruction is enable. */
4459#define SET_ADDEND(size, convertible, optimize, insn16_on) \
4460 (((size) & 0xff) | ((convertible) ? 1 << 31 : 0) \
4461 | ((optimize) ? 1<< 30 : 0) | (insn16_on ? 1 << 29 : 0))
4462
35c08157
KLC
4463static void
4464nds32_set_elf_flags_by_insn (struct nds32_asm_insn * insn)
4465{
4466 /* Set E_NDS32_HAS_EXT_INST. */
4467 if (insn->opcode->attr & NASM_ATTR_PERF_EXT)
4468 {
4469 if (nds32_perf_ext)
4470 nds32_elf_flags |= E_NDS32_HAS_EXT_INST;
4471 else
4472 as_bad (_("instruction %s requires enabling performance extension"),
4473 insn->opcode->opcode);
4474 }
4475 else if (insn->opcode->attr & NASM_ATTR_PERF2_EXT)
4476 {
4477 if (nds32_perf_ext2)
4478 nds32_elf_flags |= E_NDS32_HAS_EXT2_INST;
4479 else
4480 as_bad (_("instruction %s requires enabling performance extension II"),
4481 insn->opcode->opcode);
4482 }
4483 else if (insn->opcode->attr & NASM_ATTR_AUDIO_ISAEXT)
4484 {
4485 if (nds32_audio_ext)
4486 nds32_elf_flags |= E_NDS32_HAS_AUDIO_INST;
4487 else
4488 as_bad (_("instruction %s requires enabling AUDIO extension"),
4489 insn->opcode->opcode);
4490 }
4491 else if (insn->opcode->attr & NASM_ATTR_STR_EXT)
4492 {
4493 if (nds32_string_ext)
4494 nds32_elf_flags |= E_NDS32_HAS_STRING_INST;
4495 else
4496 as_bad (_("instruction %s requires enabling STRING extension"),
4497 insn->opcode->opcode);
4498 }
4499 else if ((insn->opcode->attr & NASM_ATTR_DIV)
4500 && (insn->opcode->attr & NASM_ATTR_DXREG))
4501 {
4502 if (nds32_div && nds32_dx_regs)
4503 nds32_elf_flags |= E_NDS32_HAS_DIV_DX_INST;
4504 else
4505 as_bad (_("instruction %s requires enabling DIV & DX_REGS extension"),
4506 insn->opcode->opcode);
4507 }
4508 else if (insn->opcode->attr & NASM_ATTR_FPU)
4509 {
4510 if (nds32_fpu_sp_ext || nds32_fpu_dp_ext)
4511 {
4512 if (!(nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
4513 nds32_fpu_com = 1;
4514 }
4515 else
4516 as_bad (_("instruction %s requires enabling FPU extension"),
4517 insn->opcode->opcode);
4518 }
4519 else if (insn->opcode->attr & NASM_ATTR_FPU_SP_EXT)
4520 {
4521 if (nds32_fpu_sp_ext)
4522 nds32_elf_flags |= E_NDS32_HAS_FPU_INST;
4523 else
4524 as_bad (_("instruction %s requires enabling FPU_SP extension"),
4525 insn->opcode->opcode);
4526 }
4527 else if ((insn->opcode->attr & NASM_ATTR_FPU_SP_EXT)
4528 && (insn->opcode->attr & NASM_ATTR_MAC))
4529 {
4530 if (nds32_fpu_sp_ext && nds32_mac)
4531 {
4532 nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
4533 nds32_elf_flags |= E_NDS32_HAS_FPU_INST;
4534 }
4535 else
4536 as_bad (_("instruction %s requires enabling FPU_MAC extension"),
4537 insn->opcode->opcode);
4538 }
4539 else if (insn->opcode->attr & NASM_ATTR_FPU_DP_EXT)
4540 {
4541 if (nds32_fpu_dp_ext)
4542 nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST;
4543 else
4544 as_bad (_("instruction %s requires enabling FPU_DP extension"),
4545 insn->opcode->opcode);
4546 }
4547 else if ((insn->opcode->attr & NASM_ATTR_FPU_DP_EXT)
4548 && (insn->opcode->attr & NASM_ATTR_MAC))
4549 {
4550 if (nds32_fpu_dp_ext && nds32_mac)
4551 {
4552 nds32_elf_flags |= E_NDS32_HAS_FPU_MAC_INST;
4553 nds32_elf_flags |= E_NDS32_HAS_FPU_DP_INST;
4554 }
4555 else
4556 as_bad (_("instruction %s requires enabling FPU_MAC extension"),
4557 insn->opcode->opcode);
4558 }
4559 /* TODO: FPU_BOTH */
4560 else if ((insn->opcode->attr & NASM_ATTR_MAC)
4561 && (insn->opcode->attr & NASM_ATTR_DXREG))
4562 {
4563 if (nds32_mac && nds32_dx_regs)
4564 nds32_elf_flags |= E_NDS32_HAS_MAC_DX_INST;
4565 else
4566 as_bad (_("instruction %s requires enabling DX_REGS extension"),
4567 insn->opcode->opcode);
4568 }
4569 /* TODO: for DX_REG set but not for MAC, DIV, AUDIO */
4570 else if (insn->opcode->attr & NASM_ATTR_IFC_EXT)
4571 {
4572 nds32_elf_flags |= E_NDS32_HAS_IFC_INST;
4573 }
4574 /* TODO: E_NDS32_HAS_SATURATION_INST */
4575}
4576
1c8f6a4d
KLC
4577/* Flag for analysis relaxation type. */
4578
4579enum nds32_insn_type
4580{
4581 N32_RELAX_SETHI = 1,
4582 N32_RELAX_BR = (1 << 1),
4583 N32_RELAX_LSI = (1 << 2),
4584 N32_RELAX_JUMP = (1 << 3),
4585 N32_RELAX_CALL = (1 << 4),
4586 N32_RELAX_ORI = (1 << 5),
4587 N32_RELAX_MEM = (1 << 6),
4588 N32_RELAX_MOVI = (1 << 7),
4589};
4590
4591struct nds32_hint_map
4592{
4593 bfd_reloc_code_real_type hi_type;
f86f5863 4594 const char *opc;
1c8f6a4d
KLC
4595 enum nds32_relax_hint_type hint_type;
4596 enum nds32_br_range range;
4597 enum nds32_insn_type insn_list;
4598};
4599
4600/* Table to match instructions with hint and relax pattern. */
4601
4602static struct nds32_hint_map hint_map [] =
4603{
4604 {
4605 /* LONGCALL4. */
4606 BFD_RELOC_NDS32_HI20,
4607 "jal",
4608 NDS32_RELAX_HINT_NONE,
4609 BR_RANGE_U4G,
4610 N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL
4611 },
4612 {
4613 /* LONGCALL5. */
4614 _dummy_first_bfd_reloc_code_real,
4615 "bgezal",
4616 NDS32_RELAX_HINT_NONE,
4617 BR_RANGE_S16M,
4618 N32_RELAX_BR | N32_RELAX_CALL
4619 },
4620 {
4621 /* LONGCALL6. */
4622 BFD_RELOC_NDS32_HI20,
4623 "bgezal",
4624 NDS32_RELAX_HINT_NONE,
4625 BR_RANGE_U4G,
4626 N32_RELAX_BR | N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_CALL
4627 },
4628 {
4629 /* LONGJUMP4. */
4630 BFD_RELOC_NDS32_HI20,
4631 "j",
4632 NDS32_RELAX_HINT_NONE,
4633 BR_RANGE_U4G,
4634 N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_JUMP
4635 },
4636 {
4637 /* LONGJUMP5. */
4638 /* There is two kinds of veriation of LONGJUMP5. One of them
4639 generate EMPTY relocation for converted INSN16 if needed.
4640 But we don't distinguish them here. */
4641 _dummy_first_bfd_reloc_code_real,
4642 "beq",
4643 NDS32_RELAX_HINT_NONE,
4644 BR_RANGE_S16M,
4645 N32_RELAX_BR | N32_RELAX_JUMP
4646 },
4647 {
4648 /* LONGJUMP6. */
4649 BFD_RELOC_NDS32_HI20,
4650 "beq",
4651 NDS32_RELAX_HINT_NONE,
4652 BR_RANGE_U4G,
4653 N32_RELAX_SETHI | N32_RELAX_ORI | N32_RELAX_BR | N32_RELAX_JUMP
4654 },
4655 {
4656 /* LONGJUMP7. */
4657 _dummy_first_bfd_reloc_code_real,
4658 "beqc",
4659 NDS32_RELAX_HINT_NONE,
4660 BR_RANGE_S16K,
4661 N32_RELAX_MOVI | N32_RELAX_BR
4662 },
4663 {
4664 /* LOADSTORE ADDRESS. */
4665 BFD_RELOC_NDS32_HI20,
4666 NULL,
4667 NDS32_RELAX_HINT_LA,
4668 BR_RANGE_U4G,
4669 N32_RELAX_SETHI | N32_RELAX_ORI
4670 },
4671 {
4672 /* LOADSTORE ADDRESS. */
4673 BFD_RELOC_NDS32_HI20,
4674 NULL,
4675 NDS32_RELAX_HINT_LS,
4676 BR_RANGE_U4G,
4677 N32_RELAX_SETHI | N32_RELAX_LSI
4678 },
4679 {0, NULL, 0, 0 ,0}
4680};
4681
4682/* Find the relaxation pattern according to instructions. */
4683
4684static bfd_boolean
4685nds32_find_reloc_table (struct nds32_relocs_pattern *relocs_pattern,
4686 struct nds32_relax_hint_table *hint_info)
4687{
4688 unsigned int opcode, seq_size;
4689 enum nds32_br_range range;
4690 struct nds32_relocs_pattern *pattern, *hi_pattern = NULL;
f86f5863 4691 const char *opc = NULL;
1c8f6a4d
KLC
4692 relax_info_t *relax_info = NULL;
4693 nds32_relax_fixup_info_t *fixup_info, *hint_fixup;
4694 enum nds32_relax_hint_type hint_type = NDS32_RELAX_HINT_NONE;
4695 struct nds32_relax_hint_table *table_ptr;
4696 uint32_t *code_seq, *hint_code;
4697 enum nds32_insn_type relax_type = 0;
4698 struct nds32_hint_map *map_ptr = hint_map;
4699 unsigned int i;
f86f5863 4700 const char *check_insn[] =
1c8f6a4d
KLC
4701 { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" };
4702
4703 /* TODO: PLT GOT. */
4704 /* Traverse all pattern instruction and set flag. */
4705 pattern = relocs_pattern;
4706 while (pattern)
4707 {
4708 if (pattern->opcode->isize == 4)
4709 {
4710 /* 4 byte instruction. */
4711 opcode = N32_OP6 (pattern->opcode->value);
4712 switch (opcode)
4713 {
4714 case N32_OP6_SETHI:
4715 hi_pattern = pattern;
4716 relax_type |= N32_RELAX_SETHI;
4717 break;
4718 case N32_OP6_MEM:
4719 relax_type |= N32_RELAX_MEM;
4720 break;
4721 case N32_OP6_ORI:
4722 relax_type |= N32_RELAX_ORI;
4723 break;
4724 case N32_OP6_BR1:
4725 case N32_OP6_BR2:
4726 case N32_OP6_BR3:
4727 relax_type |= N32_RELAX_BR;
4728 break;
4729 case N32_OP6_MOVI:
4730 relax_type |= N32_RELAX_MOVI;
4731 break;
4732 case N32_OP6_LBI:
4733 case N32_OP6_SBI:
4734 case N32_OP6_LBSI:
4735 case N32_OP6_LHI:
4736 case N32_OP6_SHI:
4737 case N32_OP6_LHSI:
4738 case N32_OP6_LWI:
4739 case N32_OP6_SWI:
4740 case N32_OP6_LWC:
4741 case N32_OP6_SWC:
4742 relax_type |= N32_RELAX_LSI;
4743 break;
4744 case N32_OP6_JREG:
4745 if (__GF (pattern->opcode->value, 0, 1) == 1)
4746 relax_type |= N32_RELAX_CALL;
4747 else
4748 relax_type |= N32_RELAX_JUMP;
4749 break;
4750 case N32_OP6_JI:
4751 if (__GF (pattern->opcode->value, 24, 1) == 1)
4752 relax_type |= N32_RELAX_CALL;
4753 else
4754 relax_type |= N32_RELAX_JUMP;
4755 break;
4756 default:
4757 as_warn (_("relax hint unrecognized instruction: line %d."),
4758 pattern->frag->fr_line);
4759 return FALSE;
4760 }
4761 }
4762 else
4763 {
4764 /* 2 byte instruction. Compare by opcode name because the opcode of
4765 2byte instruction is not regular. */
4766 for (i = 0; i < sizeof (check_insn) / sizeof (check_insn[0]); i++)
4767 {
4768 if (strcmp (pattern->opcode->opcode, check_insn[i]) == 0)
4769 {
4770 relax_type |= N32_RELAX_BR;
4771 break;
4772 }
4773 }
4774 if (strcmp (pattern->opcode->opcode, "movi55") == 0)
4775 relax_type |= N32_RELAX_MOVI;
4776 }
4777 pattern = pattern->next;
4778 }
4779
4780 /* Analysis instruction flag to choose relaxation table. */
4781 while (map_ptr->insn_list != 0)
4782 {
4783 if (map_ptr->insn_list == relax_type
4784 && (!hi_pattern
4785 || (hi_pattern->fixP
4786 && hi_pattern->fixP->fx_r_type == map_ptr->hi_type)))
4787 {
4788 opc = map_ptr->opc;
4789 hint_type = map_ptr->hint_type;
4790 range = map_ptr->range;
4791 break;
4792 }
4793 map_ptr++;
4794 }
4795
4796 if (map_ptr->insn_list == 0)
4797 {
4798 as_warn (_("Can not find match relax hint. line : %d"),
4799 relocs_pattern->frag->fr_line);
4800 return FALSE;
4801 }
4802
4803 /* Get the match table. */
4804 if (opc)
4805 {
4806 /* Branch relax pattern. */
4807 relax_info = hash_find (nds32_relax_info_hash, opc);
4808 if (!relax_info)
4809 return FALSE;
4810 fixup_info = relax_info->relax_fixup[range];
4811 code_seq = relax_info->relax_code_seq[range];
4812 seq_size = relax_info->relax_code_size[range];
4813 }
4814 else if (hint_type)
4815 {
4816 /* Load-store relax pattern. */
4817 table_ptr = relax_ls_table;
4818 while (table_ptr->main_type != 0)
4819 {
4820 if (table_ptr->main_type == hint_type)
4821 {
4822 fixup_info = table_ptr->relax_fixup;
4823 code_seq = table_ptr->relax_code_seq;
4824 seq_size = table_ptr->relax_code_size;
4825 break;
4826 }
4827 table_ptr++;
4828 }
4829 if (table_ptr->main_type == 0)
4830 return FALSE;
4831 }
4832 else
4833 return FALSE;
4834
4835 hint_fixup = hint_info->relax_fixup;
4836 hint_code = hint_info->relax_code_seq;
4837 hint_info->relax_code_size = seq_size;
4838
4839 while (fixup_info->size != 0)
4840 {
4841 if (fixup_info->ramp & NDS32_HINT)
4842 {
4843 memcpy (hint_fixup, fixup_info, sizeof (nds32_relax_fixup_info_t));
4844 hint_fixup++;
4845 }
4846 fixup_info++;
4847 }
4848 /* Clear final relocation. */
4849 memset (hint_fixup, 0, sizeof (nds32_relax_fixup_info_t));
4850 /* Copy code sequance. */
4851 memcpy (hint_code, code_seq, seq_size);
4852 return TRUE;
4853}
4854
4855/* Because there are a lot of variant of load-store, check
4856 all these type here. */
4857
4858#define CLEAN_REG(insn) ((insn) & 0xff0003ff)
4859static bfd_boolean
4860nds32_match_hint_insn (struct nds32_opcode *opcode, uint32_t seq)
4861{
f86f5863 4862 const char *check_insn[] =
1c8f6a4d
KLC
4863 { "bnes38", "beqs38", "bnez38", "bnezs8", "beqz38", "beqzs8" };
4864 uint32_t insn = opcode->value;
4865 unsigned int i;
4866
4867 insn = CLEAN_REG (opcode->value);
4868 if (insn == seq)
4869 return TRUE;
4870
4871 switch (seq)
4872 {
4873 case OP6 (LBI):
4874 /* In relocation_table, it regards instruction LBI as representation
4875 of all the NDS32_RELAX_HINT_LS pattern. */
4876 if (insn == OP6 (LBI) || insn == OP6 (SBI) || insn == OP6 (LBSI)
4877 || insn == OP6 (LHI) || insn == OP6 (SHI) || insn == OP6 (LHSI)
4878 || insn == OP6 (LWI) || insn == OP6 (SWI)
4879 || insn == OP6 (LWC) || insn == OP6 (SWC))
4880 return TRUE;
4881 break;
4882 case OP6 (BR2):
4883 /* This is for LONGCALL5 and LONGCALL6. */
4884 if (insn == OP6 (BR2))
4885 return TRUE;
4886 break;
4887 case OP6 (BR1):
4888 /* This is for LONGJUMP5 and LONGJUMP6. */
4889 if (opcode->isize == 4
4890 && (insn == OP6 (BR1) || insn == OP6 (BR2) || insn == OP6 (BR3)))
4891 return TRUE;
4892 else if (opcode->isize == 2)
4893 {
4894 for (i = 0; i < sizeof (check_insn) / sizeof (check_insn[0]); i++)
4895 if (strcmp (opcode->opcode, check_insn[i]) == 0)
4896 return TRUE;
4897 }
4898 break;
4899 case OP6 (MOVI):
4900 /* This is for LONGJUMP7. */
4901 if (opcode->isize == 2 && strcmp (opcode->opcode, "movi55") == 0)
4902 return TRUE;
4903 break;
4904 }
4905 return FALSE;
4906}
4907
35c08157
KLC
4908/* Append relax relocation for link time relaxing. */
4909
4910static void
4911nds32_elf_append_relax_relocs (const char *key ATTRIBUTE_UNUSED, void *value)
4912{
1c8f6a4d 4913 struct nds32_relocs_pattern *relocs_pattern =
35c08157 4914 (struct nds32_relocs_pattern *) value;
1c8f6a4d
KLC
4915 struct nds32_relocs_pattern *pattern_temp, *pattern_now;
4916 symbolS *sym, *hi_sym = NULL;
4917 expressionS exp;
4918 fragS *fragP;
35c08157
KLC
4919 segT seg_bak = now_seg;
4920 frchainS *frchain_bak = frchain_now;
1c8f6a4d
KLC
4921 struct nds32_relax_hint_table hint_info;
4922 nds32_relax_fixup_info_t *hint_fixup, *fixup_now;
4923 size_t fixup_size;
4924 offsetT branch_offset;
4925 fixS *fixP;
4926 int range, offset;
4927 unsigned int ptr_offset, hint_count, relax_code_size, count = 0;
4928 uint32_t *code_seq, code_insn;
4929 char *where;
ea16498d 4930 int pcrel;
1c8f6a4d
KLC
4931
4932 if (!relocs_pattern)
4933 return;
35c08157 4934
1c8f6a4d 4935 if (!nds32_find_reloc_table (relocs_pattern, &hint_info))
35c08157
KLC
4936 return;
4937
1c8f6a4d
KLC
4938 /* Save symbol for some EMPTY relocation using. */
4939 pattern_now = relocs_pattern;
4940 while (pattern_now)
4941 {
4942 if (pattern_now->opcode->value == OP6 (SETHI))
4943 {
4944 hi_sym = pattern_now->sym;
4945 break;
4946 }
4947 pattern_now = pattern_now->next;
4948 }
4949
35c08157 4950 /* Inserting fix up must specify now_seg or frchain_now. */
1c8f6a4d
KLC
4951 now_seg = relocs_pattern->seg;
4952 frchain_now = relocs_pattern->frchain;
4953 fragP = relocs_pattern->frag;
4954 branch_offset = fragP->fr_offset;
35c08157 4955
1c8f6a4d
KLC
4956 hint_fixup = hint_info.relax_fixup;
4957 code_seq = hint_info.relax_code_seq;
4958 relax_code_size = hint_info.relax_code_size;
4959 pattern_now = relocs_pattern;
35c08157 4960
1c8f6a4d
KLC
4961 /* Insert relaxation. */
4962 exp.X_op = O_symbol;
35c08157 4963
1c8f6a4d 4964 while (pattern_now)
35c08157 4965 {
1c8f6a4d
KLC
4966 /* Choose the match fixup by instruction. */
4967 code_insn = CLEAN_REG (*(code_seq + count));
4968 if (!nds32_match_hint_insn (pattern_now->opcode, code_insn))
4969 {
4970 count = 0;
4971 code_insn = CLEAN_REG (*(code_seq + count));
35c08157 4972
1c8f6a4d
KLC
4973 while (!nds32_match_hint_insn (pattern_now->opcode, code_insn))
4974 {
4975 count++;
4976 if (count >= relax_code_size / 4)
4977 {
4978 as_bad (_("Internal error: Relax hint error. %s: %x"),
4979 now_seg->name, pattern_now->opcode->value);
4980 goto restore;
4981 }
4982 code_insn = CLEAN_REG (*(code_seq + count));
4983 }
4984 }
4985 fragP = pattern_now->frag;
4986 sym = pattern_now->sym;
4987 branch_offset = fragP->fr_offset;
4988 offset = count * 4;
4989 where = pattern_now->where;
4990 /* Find the instruction map fix. */
4991 fixup_now = hint_fixup;
4992 while (fixup_now->offset != offset)
4993 {
4994 fixup_now++;
4995 if (fixup_now->size == 0)
4996 break;
4997 }
4998 /* This element is without relaxation relocation. */
4999 if (fixup_now->size == 0)
35c08157 5000 {
1c8f6a4d
KLC
5001 pattern_now = pattern_now->next;
5002 continue;
35c08157 5003 }
1c8f6a4d 5004 fixup_size = fixup_now->size;
35c08157 5005
1c8f6a4d
KLC
5006 /* Insert all fixup. */
5007 while (fixup_size != 0 && fixup_now->offset == offset)
5008 {
5009 /* Set the real instruction size in element. */
5010 fixup_size = pattern_now->opcode->isize;
ea16498d 5011 pcrel = ((fixup_now->ramp & NDS32_PCREL) != 0) ? 1 : 0;
1c8f6a4d
KLC
5012 if (fixup_now->ramp & NDS32_FIX)
5013 {
5014 /* Convert original relocation. */
5015 pattern_now->fixP->fx_r_type = fixup_now->r_type ;
5016 fixup_size = 0;
5017 }
5018 else if ((fixup_now->ramp & NDS32_PTR) != 0)
5019 {
5020 /* This relocation has to point to another instruction. Make
5021 sure each resolved relocation has to be pointed. */
5022 pattern_temp = relocs_pattern;
5023 /* All instruction in relax_table should be 32-bit. */
5024 hint_count = hint_info.relax_code_size / 4;
5025 code_insn = CLEAN_REG (*(code_seq + hint_count - 1));
5026 while (pattern_temp)
5027 {
5028 /* Point to every resolved relocation. */
5029 if (nds32_match_hint_insn (pattern_temp->opcode, code_insn))
5030 {
5031 ptr_offset =
5032 pattern_temp->where - pattern_temp->frag->fr_literal;
5033 exp.X_add_symbol = symbol_temp_new (now_seg, ptr_offset,
5034 pattern_temp->frag);
5035 exp.X_add_number = 0;
5036 fixP =
5037 fix_new_exp (fragP, where - fragP->fr_literal,
5038 fixup_size, &exp, 0, fixup_now->r_type);
5039 fixP->fx_addnumber = fixP->fx_offset;
5040 }
5041 pattern_temp = pattern_temp->next;
5042 }
5043 fixup_size = 0;
5044 }
5045 else if (fixup_now->ramp & NDS32_ADDEND)
5046 {
5047 range = nds32_elf_sethi_range (relocs_pattern);
5048 if (range == NDS32_LOADSTORE_NONE)
5049 {
5050 as_bad (_("Internal error: Range error. %s"), now_seg->name);
5051 return;
5052 }
5053 exp.X_add_symbol = abs_section_sym;
5054 exp.X_add_number = SET_ADDEND (4, 0, optimize, enable_16bit);
5055 exp.X_add_number |= ((range & 0x3f) << 8);
5056 }
5057 else if ((fixup_now->ramp & NDS32_ABS) != 0)
5058 {
5059 /* This is a tag relocation. */
5060 exp.X_add_symbol = abs_section_sym;
5061 exp.X_add_number = 0;
5062 }
5063 else if ((fixup_now->ramp & NDS32_INSN16) != 0)
5064 {
5065 if (!enable_16bit)
5066 fixup_size = 0;
5067 /* This is a tag relocation. */
5068 exp.X_add_symbol = abs_section_sym;
5069 exp.X_add_number = 0;
5070 }
5071 else if ((fixup_now->ramp & NDS32_SYM) != 0)
5072 {
5073 /* For EMPTY relocation save the true symbol. */
5074 exp.X_add_symbol = hi_sym;
5075 exp.X_add_number = branch_offset;
5076 }
5077 else
5078 {
5079 exp.X_add_symbol = sym;
5080 exp.X_add_number = branch_offset;
5081 }
35c08157 5082
1c8f6a4d
KLC
5083 if (fixup_size != 0)
5084 {
ea16498d
KLC
5085 fixP = fix_new_exp (fragP, where - fragP->fr_literal, fixup_size,
5086 &exp, pcrel, fixup_now->r_type);
1c8f6a4d
KLC
5087 fixP->fx_addnumber = fixP->fx_offset;
5088 }
5089 fixup_now++;
5090 fixup_size = fixup_now->size;
5091 }
5092 if (count < relax_code_size / 4)
5093 count++;
5094 pattern_now = pattern_now->next;
35c08157
KLC
5095 }
5096
1c8f6a4d 5097restore:
35c08157
KLC
5098 now_seg = seg_bak;
5099 frchain_now = frchain_bak;
5100}
5101
5102/* Check instruction if it can be used for the baseline. */
5103
5104static bfd_boolean
5105nds32_check_insn_available (struct nds32_asm_insn insn, char *str)
5106{
5107 int attr = insn.attr & ATTR_ALL;
5108 static int baseline_isa = 0;
5109 /* No isa setting or all isa can use. */
5110 if (attr == 0 || attr == ATTR_ALL)
5111 return TRUE;
5112
5113 if (baseline_isa == 0)
5114 {
5115 /* Map option baseline and instruction attribute. */
5116 switch (nds32_baseline)
5117 {
5118 case ISA_V2:
5119 baseline_isa = ATTR (ISA_V2);
5120 break;
5121 case ISA_V3:
5122 baseline_isa = ATTR (ISA_V3);
5123 break;
5124 case ISA_V3M:
5125 baseline_isa = ATTR (ISA_V3M);
5126 break;
5127 }
5128 }
5129
5130 if ((baseline_isa & attr) == 0)
5131 {
5132 as_bad (_("Not support instrcution %s in the baseline."), str);
5133 return FALSE;
5134 }
5135 return TRUE;
5136}
5137
5138/* Stub of machine dependent. */
5139
5140void
5141md_assemble (char *str)
5142{
5143 struct nds32_asm_insn insn;
e1fa0163 5144 expressionS expr;
35c08157
KLC
5145 char *out;
5146 struct nds32_pseudo_opcode *popcode;
5147 const struct nds32_field *fld = NULL;
1c8f6a4d 5148 fixS *fixP;
35c08157 5149 uint16_t insn_16;
35c08157
KLC
5150 struct nds32_relocs_pattern *relocs_temp;
5151 expressionS *pexp;
1c8f6a4d
KLC
5152 fragS *fragP;
5153 int label = label_exist;
35c08157
KLC
5154
5155 popcode = nds32_lookup_pseudo_opcode (str);
5156 /* Note that we need to check 'verbatim' and
5157 'opcode->physical_op'. If the assembly content is generated by
5158 compiler and this opcode is a physical instruction, there is no
5159 need to perform pseudo instruction expansion/transformation. */
5160 if (popcode && !(verbatim && popcode->physical_op))
5161 {
5162 pseudo_opcode = TRUE;
5163 nds32_pseudo_opcode_wrapper (str, popcode);
5164 pseudo_opcode = FALSE;
5165 nds32_elf_append_relax_relocs (NULL, relocs_list);
5166
5167 /* Free pseudo list. */
5168 relocs_temp = relocs_list;
5169 while (relocs_temp)
5170 {
5171 relocs_list = relocs_list->next;
5172 free (relocs_temp);
5173 relocs_temp = relocs_list;
5174 }
5175
5176 return;
5177 }
5178
1c8f6a4d 5179 label_exist = 0;
e1fa0163 5180 insn.info = & expr;
ea16498d 5181 asm_desc.result = NASM_OK;
35c08157
KLC
5182 nds32_assemble (&asm_desc, &insn, str);
5183
5184 switch (asm_desc.result)
5185 {
5186 case NASM_ERR_UNKNOWN_OP:
5187 as_bad (_("Unrecognized opcode, %s."), str);
5188 return;
5189 case NASM_ERR_SYNTAX:
5190 as_bad (_("Incorrect syntax, %s."), str);
5191 return;
5192 case NASM_ERR_OPERAND:
ea16498d 5193 as_bad (_("Unrecognized operand/register, %s."), str);
35c08157
KLC
5194 return;
5195 case NASM_ERR_OUT_OF_RANGE:
5196 as_bad (_("Operand out of range, %s."), str);
5197 return;
5198 case NASM_ERR_REG_REDUCED:
5199 as_bad (_("Prohibited register used for reduced-register, %s."), str);
5200 return;
5201 case NASM_ERR_JUNK_EOL:
5202 as_bad (_("Junk at end of line, %s."), str);
5203 return;
5204 }
5205
5206 gas_assert (insn.opcode);
5207
5208 nds32_set_elf_flags_by_insn (&insn);
5209
5210 gas_assert (insn.opcode->isize == 4 || insn.opcode->isize == 2);
5211
5212 if (!nds32_check_insn_available (insn, str))
5213 return;
5214
1c8f6a4d
KLC
5215 /* Make sure the begining of text being 2-byte align. */
5216 nds32_adjust_label (1);
35c08157 5217 fld = insn.field;
1c8f6a4d
KLC
5218 /* Try to allocate the max size to guarantee relaxable same branch
5219 instructions in the same fragment. */
5220 frag_grow (NDS32_MAXCHAR);
5221 fragP = frag_now;
5222 if (fld && (insn.attr & NASM_ATTR_BRANCH)
5223 && (pseudo_opcode || (insn.opcode->value != INSN_JAL
5224 && insn.opcode->value != INSN_J))
5225 && (!verbatim || pseudo_opcode))
35c08157
KLC
5226 {
5227 /* User assembly code branch relax for it. */
35c08157 5228 /* If fld is not NULL, it is a symbol. */
1c8f6a4d
KLC
5229 /* Branch msut relax to proper pattern in user assembly code exclude
5230 J and JAL. Keep these two in original type for users which wants
5231 to keep their size be fixed. In general, assembler does not convert
5232 instruction generated by compiler. But jump instruction may be
5233 truncated in text virtual model. For workaround, compiler generate
5234 pseudo jump to fix this issue currently. */
5235
35c08157 5236 /* Get branch range type. */
1c8f6a4d 5237 dwarf2_emit_insn (0);
35c08157 5238 enum nds32_br_range range_type;
35c08157
KLC
5239
5240 pexp = insn.info;
1c8f6a4d 5241 range_type = get_range_type (fld);
35c08157 5242
1c8f6a4d 5243 out = frag_var (rs_machine_dependent, NDS32_MAXCHAR,
35c08157
KLC
5244 0, /* VAR is un-used. */
5245 range_type, /* SUBTYPE is used as range type. */
1c8f6a4d
KLC
5246 pexp->X_add_symbol, pexp->X_add_number, 0);
5247
5248 fragP->fr_fix += insn.opcode->isize;
5249 fragP->tc_frag_data.opcode = insn.opcode;
5250 fragP->tc_frag_data.insn = insn.insn;
35c08157
KLC
5251 if (insn.opcode->isize == 4)
5252 bfd_putb32 (insn.insn, out);
5253 else if (insn.opcode->isize == 2)
5254 bfd_putb16 (insn.insn, out);
1c8f6a4d 5255 fragP->tc_frag_data.flag |= NDS32_FRAG_BRANCH;
35c08157
KLC
5256 return;
5257 /* md_convert_frag will insert relocations. */
5258 }
ea16498d
KLC
5259 else if (!relaxing && enable_16bit && (optimize || optimize_for_space)
5260 && ((!fld && !verbatim && insn.opcode->isize == 4
1c8f6a4d
KLC
5261 && nds32_convert_32_to_16 (stdoutput, insn.insn, &insn_16, NULL))
5262 || (insn.opcode->isize == 2
5263 && nds32_convert_16_to_32 (stdoutput, insn.insn, NULL))))
5264 {
5265 /* Record this one is relaxable. */
ea16498d 5266 pexp = insn.info;
1c8f6a4d 5267 dwarf2_emit_insn (0);
ea16498d
KLC
5268 if (fld)
5269 {
5270 out = frag_var (rs_machine_dependent,
5271 4, /* Max size is 32-bit instruction. */
5272 0, /* VAR is un-used. */
5273 0, pexp->X_add_symbol, pexp->X_add_number, 0);
5274 fragP->tc_frag_data.flag |= NDS32_FRAG_RELAXABLE_BRANCH;
5275 }
5276 else
5277 out = frag_var (rs_machine_dependent,
5278 4, /* Max size is 32-bit instruction. */
5279 0, /* VAR is un-used. */
5280 0, NULL, 0, NULL);
1c8f6a4d
KLC
5281 fragP->tc_frag_data.flag |= NDS32_FRAG_RELAXABLE;
5282 fragP->tc_frag_data.opcode = insn.opcode;
5283 fragP->tc_frag_data.insn = insn.insn;
5284 fragP->fr_fix += 2;
5285
5286 /* In original, we don't relax the instrucion with label on it,
5287 but this may cause some redundant nop16. Therefore, tag this
5288 relaxable instruction and relax it carefully. */
5289 if (label)
5290 fragP->tc_frag_data.flag |= NDS32_FRAG_LABEL;
35c08157 5291
1c8f6a4d
KLC
5292 if (insn.opcode->isize == 4)
5293 bfd_putb16 (insn_16, out);
5294 else if (insn.opcode->isize == 2)
5295 bfd_putb16 (insn.insn, out);
5296 return;
5297 }
5298 else if ((verbatim || !relaxing) && optimize && label)
5299 {
5300 /* This instruction is with label. */
5301 expressionS exp;
5302 out = frag_var (rs_machine_dependent, insn.opcode->isize,
5303 0, 0, NULL, 0, NULL);
5304 /* If this insturction is branch target, it is not relaxable. */
5305 fragP->tc_frag_data.flag = NDS32_FRAG_LABEL;
5306 fragP->tc_frag_data.opcode = insn.opcode;
5307 fragP->tc_frag_data.insn = insn.insn;
5308 fragP->fr_fix += insn.opcode->isize;
5309 if (insn.opcode->isize == 4)
35c08157 5310 {
1c8f6a4d
KLC
5311 exp.X_op = O_symbol;
5312 exp.X_add_symbol = abs_section_sym;
5313 exp.X_add_number = 0;
ea16498d
KLC
5314 fixP = fix_new_exp (fragP, fragP->fr_fix - 4, 0, &exp,
5315 0, BFD_RELOC_NDS32_LABEL);
5316 if (!verbatim)
5317 fragP->tc_frag_data.flag = NDS32_FRAG_ALIGN;
35c08157
KLC
5318 }
5319 }
1c8f6a4d
KLC
5320 else
5321 out = frag_more (insn.opcode->isize);
35c08157
KLC
5322
5323 if (insn.opcode->isize == 4)
5324 bfd_putb32 (insn.insn, out);
1c8f6a4d 5325 if (insn.opcode->isize == 2)
35c08157
KLC
5326 bfd_putb16 (insn.insn, out);
5327
5328 dwarf2_emit_insn (insn.opcode->isize);
5329
1c8f6a4d
KLC
5330 /* Compiler generating code and user assembly pseudo load-store, insert
5331 fixup here. */
5332 pexp = insn.info;
5333 fixP = nds32_elf_record_fixup_exp (fragP, str, fld, pexp, out, &insn);
5334 /* Build relaxation pattern when relaxing is enable. */
5335 if (relaxing)
5336 nds32_elf_build_relax_relation (fixP, pexp, out, insn.opcode, fragP, fld);
35c08157
KLC
5337}
5338
5339/* md_macro_start */
5340
5341void
5342nds32_macro_start (void)
5343{
5344}
5345
5346/* md_macro_info */
5347
5348void
5349nds32_macro_info (void *info ATTRIBUTE_UNUSED)
5350{
5351}
5352
5353/* md_macro_end */
5354
5355void
5356nds32_macro_end (void)
5357{
5358}
5359
5360/* GAS will call this function with one argument, an expressionS pointer, for
5361 any expression that can not be recognized. When the function is called,
5362 input_line_pointer will point to the start of the expression. */
5363
5364void
5365md_operand (expressionS *expressionP)
5366{
5367 if (*input_line_pointer == '#')
5368 {
5369 input_line_pointer++;
5370 expression (expressionP);
5371 }
5372}
5373
5374/* GAS will call this function for each section at the end of the assembly, to
5375 permit the CPU back end to adjust the alignment of a section. The function
5376 must take two arguments, a segT for the section and a valueT for the size of
5377 the section, and return a valueT for the rounded size. */
5378
5379valueT
5380md_section_align (segT segment, valueT size)
5381{
5382 int align = bfd_get_section_alignment (stdoutput, segment);
5383
8d3842cd 5384 return ((size + (1 << align) - 1) & -(1 << align));
35c08157
KLC
5385}
5386
5387/* GAS will call this function when a symbol table lookup fails, before it
5388 creates a new symbol. Typically this would be used to supply symbols whose
5389 name or value changes dynamically, possibly in a context sensitive way.
5390 Predefined symbols with fixed values, such as register names or condition
5391 codes, are typically entered directly into the symbol table when md_begin
5392 is called. One argument is passed, a char * for the symbol. */
5393
5394symbolS *
5395md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
5396{
5397 return NULL;
5398}
5399
5400static long
5401nds32_calc_branch_offset (segT segment, fragS *fragP,
5402 long stretch ATTRIBUTE_UNUSED,
5403 relax_info_t *relax_info,
5404 enum nds32_br_range branch_range_type)
5405{
5406 struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
5407 symbolS *branch_symbol = fragP->fr_symbol;
5408 offsetT branch_offset = fragP->fr_offset;
5409 offsetT branch_target_address;
5410 offsetT branch_insn_address;
5411 long offset = 0;
5412
5413 if ((S_GET_SEGMENT (branch_symbol) != segment)
5414 || S_IS_WEAK (branch_symbol))
5415 {
5416 /* The symbol is not in the SEGMENT. It could be far far away. */
5417 offset = 0x80000000;
5418 }
5419 else
5420 {
5421 /* Calculate symbol-to-instruction offset. */
5422 branch_target_address = S_GET_VALUE (branch_symbol) + branch_offset;
5423 /* If the destination symbol is beyond current frag address,
5424 STRETCH will take effect to symbol's position. */
5425 if (S_GET_VALUE (branch_symbol) > fragP->fr_address)
5426 branch_target_address += stretch;
5427
5428 branch_insn_address = fragP->fr_address + fragP->fr_fix;
5429 branch_insn_address -= opcode->isize;
5430
5431 /* Update BRANCH_INSN_ADDRESS to relaxed position. */
5432 branch_insn_address += (relax_info->relax_code_size[branch_range_type]
5433 - relax_info->relax_branch_isize[branch_range_type]);
5434
5435 offset = branch_target_address - branch_insn_address;
5436 }
5437
5438 return offset;
5439}
5440
5441static enum nds32_br_range
5442nds32_convert_to_range_type (long offset)
5443{
5444 enum nds32_br_range range_type;
5445
5446 if (-(0x100) <= offset && offset < 0x100) /* 256 bytes */
5447 range_type = BR_RANGE_S256;
5448 else if (-(0x4000) <= offset && offset < 0x4000) /* 16K bytes */
5449 range_type = BR_RANGE_S16K;
5450 else if (-(0x10000) <= offset && offset < 0x10000) /* 64K bytes */
5451 range_type = BR_RANGE_S64K;
5452 else if (-(0x1000000) <= offset && offset < 0x1000000) /* 16M bytes */
5453 range_type = BR_RANGE_S16M;
5454 else /* 4G bytes */
5455 range_type = BR_RANGE_U4G;
5456
5457 return range_type;
5458}
5459
5460/* Set insntruction register mask. */
5461
5462static void
5463nds32_elf_get_set_cond (relax_info_t *relax_info, int offset, uint32_t *insn,
5464 uint32_t ori_insn, int range)
5465{
5466 nds32_cond_field_t *cond_fields = relax_info->cond_field;
5467 nds32_cond_field_t *code_seq_cond = relax_info->relax_code_condition[range];
5468 uint32_t mask;
5469 int i = 0;
5470
5471 /* The instruction has conditions. Collect condition values. */
1c8f6a4d 5472 while (code_seq_cond[i].bitmask != 0)
35c08157 5473 {
1c8f6a4d
KLC
5474 if (offset == code_seq_cond[i].offset)
5475 {
5476 mask = (ori_insn >> cond_fields[i].bitpos) & cond_fields[i].bitmask;
5477 /* Sign extend. */
5478 if (cond_fields[i].signed_extend)
5479 mask = (mask ^ ((cond_fields[i].bitmask + 1) >> 1)) -
5480 ((cond_fields[i].bitmask + 1) >> 1);
5481 *insn |= (mask & code_seq_cond[i].bitmask) << code_seq_cond[i].bitpos;
5482 }
35c08157
KLC
5483 i++;
5484 }
5485}
5486
5487
5488static int
5489nds32_relax_branch_instructions (segT segment, fragS *fragP,
5490 long stretch ATTRIBUTE_UNUSED,
5491 int init)
5492{
5493 enum nds32_br_range branch_range_type;
5494 struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
5495 long offset = 0;
5496 enum nds32_br_range real_range_type;
5497 int adjust = 0;
5498 relax_info_t *relax_info;
5499 int diff = 0;
5500 int i, j, k;
5501 int code_seq_size;
5502 uint32_t *code_seq;
5503 uint32_t insn;
5504 int insn_size;
35c08157
KLC
5505 int code_seq_offset;
5506
5507 /* Replace with gas_assert (fragP->fr_symbol != NULL); */
5508 if (fragP->fr_symbol == NULL)
5509 return adjust;
5510
5511 /* If frag_var is not enough room, the previos frag is fr_full and with
5512 opcode. The new one is rs_dependent but without opcode. */
5513 if (opcode == NULL)
5514 return adjust;
5515
5516 relax_info = hash_find (nds32_relax_info_hash, opcode->opcode);
5517
5518 if (relax_info == NULL)
5519 return adjust;
5520
5521 if (init)
5522 branch_range_type = relax_info->br_range;
5523 else
5524 branch_range_type = fragP->fr_subtype;
5525
5526 offset = nds32_calc_branch_offset (segment, fragP, stretch,
5527 relax_info, branch_range_type);
5528
5529 real_range_type = nds32_convert_to_range_type (offset);
5530
5531 /* If actual range is equal to instruction jump range, do nothing. */
5532 if (real_range_type == branch_range_type)
5533 return adjust;
5534
5535 /* Find out proper relaxation code sequence. */
5536 for (i = BR_RANGE_S256; i < BR_RANGE_NUM; i++)
5537 {
5538 if (real_range_type <= (unsigned int) i)
5539 {
5540 if (init)
5541 diff = relax_info->relax_code_size[i] - opcode->isize;
5542 else
5543 diff = relax_info->relax_code_size[i]
5544 - relax_info->relax_code_size[branch_range_type];
5545
5546 /* If the instruction could be converted to 16-bits,
5547 minus the difference. */
5548 code_seq_offset = 0;
5549 j = 0;
5550 k = 0;
5551 code_seq_size = relax_info->relax_code_size[i];
5552 code_seq = relax_info->relax_code_seq[i];
5553 while (code_seq_offset < code_seq_size)
5554 {
5555 insn = code_seq[j];
5556 if (insn & 0x80000000) /* 16-bits instruction. */
5557 {
5558 insn_size = 2;
5559 }
5560 else /* 32-bits instruction. */
5561 {
5562 insn_size = 4;
5563
5564 while (relax_info->relax_fixup[i][k].size !=0
5565 && relax_info->relax_fixup[i][k].offset < code_seq_offset)
5566 k++;
35c08157
KLC
5567 }
5568
5569 code_seq_offset += insn_size;
5570 j++;
5571 }
5572
5573 /* Update fr_subtype to new NDS32_BR_RANGE. */
5574 fragP->fr_subtype = i;
5575 break;
5576 }
5577 }
5578
5579 return diff + adjust;
5580}
5581
1c8f6a4d
KLC
5582/* Adjust relaxable frag till current frag. */
5583
5584static int
5585nds32_adjust_relaxable_frag (fragS *startP, fragS *fragP)
5586{
5587 int adj;
5588 if (startP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
5589 adj = -2;
5590 else
5591 adj = 2;
5592
5593 startP->tc_frag_data.flag ^= NDS32_FRAG_RELAXED;
5594
5595 while (startP)
5596 {
5597 startP = startP->fr_next;
5598 if (startP)
5599 {
5600 startP->fr_address += adj;
5601 if (startP == fragP)
5602 break;
5603 }
5604 }
5605 return adj;
5606}
5607
5608static addressT
5609nds32_get_align (addressT address, int align)
5610{
5611 addressT mask, new_address;
5612
5613 mask = ~((~0) << align);
5614 new_address = (address + mask) & (~mask);
5615 return (new_address - address);
5616}
5617
5618/* Check the prev_frag is legal. */
5619static void
5620invalid_prev_frag (fragS * fragP, fragS **prev_frag)
5621{
5622 addressT address;
5623 fragS *frag_start = *prev_frag;
5624
5625 if (!frag_start)
5626 return;
5627
5628 if (frag_start->last_fr_address >= fragP->last_fr_address)
5629 {
5630 *prev_frag = NULL;
5631 return;
5632 }
5633
5634 fragS *frag_t = *prev_frag;
5635 while (frag_t != fragP)
5636 {
5637 if (frag_t->fr_type == rs_align
5638 || frag_t->fr_type == rs_align_code
5639 || frag_t->fr_type == rs_align_test)
5640 {
5641 /* Relax instruction can not walk across lable. */
5642 if (frag_t->tc_frag_data.flag & NDS32_FRAG_LABEL)
5643 {
5644 prev_frag = NULL;
5645 return;
5646 }
5647 /* Relax previos relaxable to align rs_align frag. */
5648 address = frag_t->fr_address + frag_t->fr_fix;
5649 addressT offset = nds32_get_align (address, (int) frag_t->fr_offset);
5650 if (offset & 0x2)
5651 {
5652 /* If there is label on the prev_frag, check if it is aligned. */
5653 if (!((*prev_frag)->tc_frag_data.flag & NDS32_FRAG_LABEL)
5654 || (((*prev_frag)->fr_address + (*prev_frag)->fr_fix - 2 )
5655 & 0x2) == 0)
5656 nds32_adjust_relaxable_frag (*prev_frag, frag_t);
5657 }
5658 *prev_frag = NULL;
5659 return;
5660 }
5661 frag_t = frag_t->fr_next;
5662 }
ea16498d
KLC
5663
5664 if (fragP->tc_frag_data.flag & NDS32_FRAG_ALIGN)
5665 {
5666 address = fragP->fr_address;
5667 addressT offset = nds32_get_align (address, 2);
5668 if (offset & 0x2)
5669 {
5670 /* If there is label on the prev_frag, check if it is aligned. */
5671 if (!((*prev_frag)->tc_frag_data.flag & NDS32_FRAG_LABEL)
5672 || (((*prev_frag)->fr_address + (*prev_frag)->fr_fix - 2 )
5673 & 0x2) == 0)
5674 nds32_adjust_relaxable_frag (*prev_frag, fragP);
5675 }
5676 *prev_frag = NULL;
5677 return;
5678 }
1c8f6a4d
KLC
5679}
5680
35c08157
KLC
5681/* md_relax_frag */
5682
5683int
5684nds32_relax_frag (segT segment, fragS *fragP, long stretch ATTRIBUTE_UNUSED)
5685{
5686 /* Currently, there are two kinds of relaxation in nds32 assembler.
5687 1. relax for branch
5688 2. relax for 32-bits to 16-bits */
5689
1c8f6a4d
KLC
5690 static fragS *prev_frag = NULL;
5691 int adjust = 0;
5692
5693 invalid_prev_frag (fragP, &prev_frag);
35c08157 5694
1c8f6a4d
KLC
5695 if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
5696 adjust = nds32_relax_branch_instructions (segment, fragP, stretch, 0);
5697 if (fragP->tc_frag_data.flag & NDS32_FRAG_LABEL)
5698 prev_frag = NULL;
5699 if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE
5700 && (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED) == 0)
5701 /* Here is considered relaxed case originally. But it may cause
5702 unendless loop when relaxing. Once the instruction is relaxed,
5703 it can not be undo. */
5704 prev_frag = fragP;
35c08157
KLC
5705
5706 return adjust;
5707}
5708
5709/* This function returns an initial guess of the length by which a fragment
5710 must grow to hold a branch to reach its destination. Also updates
5711 fr_type/fr_subtype as necessary.
5712
5713 It is called just before doing relaxation. Any symbol that is now undefined
5714 will not become defined. The guess for fr_var is ACTUALLY the growth beyond
5715 fr_fix. Whatever we do to grow fr_fix or fr_var contributes to our returned
5716 value. Although it may not be explicit in the frag, pretend fr_var starts
5717 with a 0 value. */
5718
5719int
5720md_estimate_size_before_relax (fragS *fragP, segT segment)
5721{
5722 /* Currently, there are two kinds of relaxation in nds32 assembler.
5723 1. relax for branch
5724 2. relax for 32-bits to 16-bits */
5725
1c8f6a4d
KLC
5726 /* Save previos relaxable frag. */
5727 static fragS *prev_frag = NULL;
5728 int adjust = 0;
5729
5730 invalid_prev_frag (fragP, &prev_frag);
35c08157 5731
1c8f6a4d
KLC
5732 if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
5733 adjust = nds32_relax_branch_instructions (segment, fragP, 0, 1);
5734 if (fragP->tc_frag_data.flag & NDS32_FRAG_LABEL)
5735 prev_frag = NULL;
5736 if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
5737 adjust = 2;
5738 else if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE)
5739 prev_frag = fragP;
35c08157
KLC
5740
5741 return adjust;
5742}
5743
5744/* GAS will call this for each rs_machine_dependent fragment. The instruction
5745 is completed using the data from the relaxation pass. It may also create any
5746 necessary relocations.
5747
5748 *FRAGP has been relaxed to its final size, and now needs to have the bytes
5749 inside it modified to conform to the new size. It is called after relaxation
5750 is finished.
5751
5752 fragP->fr_type == rs_machine_dependent.
5753 fragP->fr_subtype is the subtype of what the address relaxed to. */
5754
5755void
5756md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragP)
5757{
5758 /* Convert branch relaxation instructions. */
5759 symbolS *branch_symbol = fragP->fr_symbol;
5760 offsetT branch_offset = fragP->fr_offset;
5761 enum nds32_br_range branch_range_type = fragP->fr_subtype;
5762 struct nds32_opcode *opcode = fragP->tc_frag_data.opcode;
5763 uint32_t origin_insn = fragP->tc_frag_data.insn;
35c08157
KLC
5764 relax_info_t *relax_info;
5765 char *fr_buffer;
5766 int fr_where;
5767 int addend ATTRIBUTE_UNUSED;
1c8f6a4d 5768 offsetT branch_target_address, branch_insn_address;
35c08157
KLC
5769 expressionS exp;
5770 fixS *fixP;
5771 uint32_t *code_seq;
35c08157 5772 uint32_t insn;
1c8f6a4d 5773 int code_size, insn_size, offset, fixup_size;
ea16498d 5774 int buf_offset, pcrel;
1c8f6a4d
KLC
5775 int i, k;
5776 uint16_t insn_16;
5777 nds32_relax_fixup_info_t fixup_info[MAX_RELAX_FIX];
35c08157 5778 /* Save the 1st instruction is converted to 16 bit or not. */
1c8f6a4d 5779 unsigned int branch_size;
35c08157
KLC
5780
5781 /* Replace with gas_assert (branch_symbol != NULL); */
1c8f6a4d 5782 if (branch_symbol == NULL && !(fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED))
35c08157
KLC
5783 return;
5784
5785 /* If frag_var is not enough room, the previos frag is fr_full and with
5786 opcode. The new one is rs_dependent but without opcode. */
5787 if (opcode == NULL)
5788 return;
5789
ea16498d
KLC
5790 if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXABLE_BRANCH)
5791 {
5792 relax_info = hash_find (nds32_relax_info_hash, opcode->opcode);
5793
5794 if (relax_info == NULL)
5795 return;
5796
5797 i = BR_RANGE_S256;
5798 while (i < BR_RANGE_NUM
5799 && relax_info->relax_code_size[i]
5800 != (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED ? 4 : 2))
5801 i++;
5802
5803 if (i >= BR_RANGE_NUM)
5804 as_bad ("Internal error: Cannot find relocation of"
5805 "relaxable branch.");
5806
5807 exp.X_op = O_symbol;
5808 exp.X_add_symbol = branch_symbol;
5809 exp.X_add_number = branch_offset;
5810 pcrel = ((relax_info->relax_fixup[i][0].ramp & NDS32_PCREL) != 0) ? 1 : 0;
5811 fr_where = fragP->fr_fix - 2;
5812 fixP = fix_new_exp (fragP, fr_where, relax_info->relax_fixup[i][0].size,
5813 &exp, pcrel, relax_info->relax_fixup[i][0].r_type);
5814 fixP->fx_addnumber = fixP->fx_offset;
5815
5816 if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
5817 {
5818 insn_16 = fragP->tc_frag_data.insn;
5819 nds32_convert_16_to_32 (stdoutput, insn_16, &insn);
5820 fr_buffer = fragP->fr_literal + fr_where;
5821 fragP->fr_fix += 2;
5822 exp.X_op = O_symbol;
5823 exp.X_add_symbol = abs_section_sym;
5824 exp.X_add_number = 0;
5825 fix_new_exp (fragP, fr_where, 4,
5826 &exp, 0, BFD_RELOC_NDS32_INSN16);
5827 number_to_chars_bigendian (fr_buffer, insn, 4);
5828 }
5829 }
5830 else if (fragP->tc_frag_data.flag & NDS32_FRAG_RELAXED)
35c08157 5831 {
1c8f6a4d
KLC
5832 if (fragP->tc_frag_data.opcode->isize == 2)
5833 {
5834 insn_16 = fragP->tc_frag_data.insn;
5835 nds32_convert_16_to_32 (stdoutput, insn_16, &insn);
5836 }
5837 else
5838 insn = fragP->tc_frag_data.insn;
5839 fragP->fr_fix += 2;
5840 fr_where = fragP->fr_fix - 4;
5841 fr_buffer = fragP->fr_literal + fr_where;
ea16498d
KLC
5842 exp.X_op = O_symbol;
5843 exp.X_add_symbol = abs_section_sym;
5844 exp.X_add_number = 0;
5845 fix_new_exp (fragP, fr_where, 4, &exp, 0,
1c8f6a4d
KLC
5846 BFD_RELOC_NDS32_INSN16);
5847 number_to_chars_bigendian (fr_buffer, insn, 4);
35c08157 5848 }
ea16498d 5849 else if (fragP->tc_frag_data.flag & NDS32_FRAG_BRANCH)
35c08157 5850 {
1c8f6a4d
KLC
5851 /* Branch instruction adjust and append relocations. */
5852 relax_info = hash_find (nds32_relax_info_hash, opcode->opcode);
5853
5854 if (relax_info == NULL)
5855 return;
35c08157 5856
1c8f6a4d
KLC
5857 fr_where = fragP->fr_fix - opcode->isize;
5858 fr_buffer = fragP->fr_literal + fr_where;
35c08157 5859
1c8f6a4d
KLC
5860 if ((S_GET_SEGMENT (branch_symbol) != sec)
5861 || S_IS_WEAK (branch_symbol))
35c08157 5862 {
1c8f6a4d
KLC
5863 if (fragP->fr_offset & 3)
5864 as_warn (_("Addend to unresolved symbol is not on word boundary."));
5865 addend = 0;
35c08157 5866 }
1c8f6a4d 5867 else
35c08157 5868 {
1c8f6a4d
KLC
5869 /* Calculate symbol-to-instruction offset. */
5870 branch_target_address = S_GET_VALUE (branch_symbol) + branch_offset;
5871 branch_insn_address = fragP->fr_address + fr_where;
5872 addend = (branch_target_address - branch_insn_address) >> 1;
35c08157
KLC
5873 }
5874
1c8f6a4d
KLC
5875 code_size = relax_info->relax_code_size[branch_range_type];
5876 code_seq = relax_info->relax_code_seq[branch_range_type];
35c08157 5877
1c8f6a4d
KLC
5878 memcpy (fixup_info, relax_info->relax_fixup[branch_range_type],
5879 sizeof (fixup_info));
35c08157 5880
1c8f6a4d
KLC
5881 /* Fill in frag. */
5882 i = 0;
5883 k = 0;
5884 offset = 0; /* code_seq offset */
5885 buf_offset = 0; /* fr_buffer offset */
5886 while (offset < code_size)
35c08157 5887 {
1c8f6a4d
KLC
5888 insn = code_seq[i];
5889 if (insn & 0x80000000) /* 16-bits instruction. */
35c08157 5890 {
1c8f6a4d
KLC
5891 insn = (insn >> 16) & 0xFFFF;
5892 insn_size = 2;
5893 }
5894 else /* 32-bits instruction. */
5895 {
5896 insn_size = 4;
35c08157
KLC
5897 }
5898
1c8f6a4d
KLC
5899 nds32_elf_get_set_cond (relax_info, offset, &insn,
5900 origin_insn, branch_range_type);
35c08157 5901
1c8f6a4d
KLC
5902 /* Try to convert to 16-bits instruction. Currently, only the first
5903 insntruction in pattern can be converted. EX: bnez sethi ori jr,
5904 only bnez can be converted to 16 bit and ori can't. */
35c08157 5905
1c8f6a4d
KLC
5906 while (fixup_info[k].size != 0
5907 && relax_info->relax_fixup[branch_range_type][k].offset < offset)
5908 k++;
35c08157 5909
ea16498d 5910 number_to_chars_bigendian (fr_buffer + buf_offset, insn, insn_size);
1c8f6a4d 5911 buf_offset += insn_size;
35c08157 5912
1c8f6a4d
KLC
5913 offset += insn_size;
5914 i++;
35c08157
KLC
5915 }
5916
1c8f6a4d
KLC
5917 /* Set up fixup. */
5918 exp.X_op = O_symbol;
5919
5920 for (i = 0; fixup_info[i].size != 0; i++)
35c08157 5921 {
1c8f6a4d 5922 fixup_size = fixup_info[i].size;
ea16498d 5923 pcrel = ((fixup_info[i].ramp & NDS32_PCREL) != 0) ? 1 : 0;
1c8f6a4d
KLC
5924
5925 if ((fixup_info[i].ramp & NDS32_CREATE_LABEL) != 0)
5926 {
5927 /* This is a reverse branch. */
5928 exp.X_add_symbol = symbol_temp_new (sec, 0, fragP->fr_next);
5929 exp.X_add_number = 0;
5930 }
5931 else if ((fixup_info[i].ramp & NDS32_PTR) != 0)
5932 {
5933 /* This relocation has to point to another instruction. */
5934 branch_size = fr_where + code_size - 4;
5935 exp.X_add_symbol = symbol_temp_new (sec, branch_size, fragP);
5936 exp.X_add_number = 0;
5937 }
5938 else if ((fixup_info[i].ramp & NDS32_ABS) != 0)
5939 {
5940 /* This is a tag relocation. */
5941 exp.X_add_symbol = abs_section_sym;
5942 exp.X_add_number = 0;
5943 }
5944 else if ((fixup_info[i].ramp & NDS32_INSN16) != 0)
5945 {
5946 if (!enable_16bit)
5947 continue;
5948 /* This is a tag relocation. */
5949 exp.X_add_symbol = abs_section_sym;
5950 exp.X_add_number = 0;
5951 }
5952 else
5953 {
5954 exp.X_add_symbol = branch_symbol;
5955 exp.X_add_number = branch_offset;
5956 }
5957
5958 if (fixup_info[i].r_type != 0)
5959 {
5960 fixP = fix_new_exp (fragP, fr_where + fixup_info[i].offset,
ea16498d
KLC
5961 fixup_size, &exp, pcrel,
5962 fixup_info[i].r_type);
1c8f6a4d
KLC
5963 fixP->fx_addnumber = fixP->fx_offset;
5964 }
35c08157 5965 }
35c08157 5966
1c8f6a4d 5967 fragP->fr_fix = fr_where + buf_offset;
1c8f6a4d 5968 }
35c08157
KLC
5969}
5970
5971/* tc_frob_file_before_fix */
5972
5973void
5974nds32_frob_file_before_fix (void)
5975{
5976}
5977
1c8f6a4d
KLC
5978static bfd_boolean
5979nds32_relaxable_section (asection *sec)
35c08157 5980{
1c8f6a4d
KLC
5981 return ((sec->flags & SEC_DEBUGGING) == 0
5982 && strcmp (sec->name, ".eh_frame") != 0);
35c08157
KLC
5983}
5984
1c8f6a4d
KLC
5985/* TC_FORCE_RELOCATION */
5986int
5987nds32_force_relocation (fixS * fix)
5988{
5989 switch (fix->fx_r_type)
5990 {
5991 case BFD_RELOC_NDS32_INSN16:
5992 case BFD_RELOC_NDS32_LABEL:
5993 case BFD_RELOC_NDS32_LONGCALL1:
5994 case BFD_RELOC_NDS32_LONGCALL2:
5995 case BFD_RELOC_NDS32_LONGCALL3:
5996 case BFD_RELOC_NDS32_LONGJUMP1:
5997 case BFD_RELOC_NDS32_LONGJUMP2:
5998 case BFD_RELOC_NDS32_LONGJUMP3:
5999 case BFD_RELOC_NDS32_LOADSTORE:
6000 case BFD_RELOC_NDS32_9_FIXED:
6001 case BFD_RELOC_NDS32_15_FIXED:
6002 case BFD_RELOC_NDS32_17_FIXED:
6003 case BFD_RELOC_NDS32_25_FIXED:
6004 case BFD_RELOC_NDS32_9_PCREL:
6005 case BFD_RELOC_NDS32_15_PCREL:
6006 case BFD_RELOC_NDS32_17_PCREL:
6007 case BFD_RELOC_NDS32_WORD_9_PCREL:
6008 case BFD_RELOC_NDS32_10_UPCREL:
6009 case BFD_RELOC_NDS32_25_PCREL:
6010 case BFD_RELOC_NDS32_MINUEND:
6011 case BFD_RELOC_NDS32_SUBTRAHEND:
6012 return 1;
6013
6014 case BFD_RELOC_8:
6015 case BFD_RELOC_16:
6016 case BFD_RELOC_32:
6017 case BFD_RELOC_NDS32_DIFF_ULEB128:
6018 /* Linker should handle difference between two symbol. */
6019 return fix->fx_subsy != NULL
6020 && nds32_relaxable_section (S_GET_SEGMENT (fix->fx_addsy));
6021 case BFD_RELOC_64:
6022 if (fix->fx_subsy)
6023 as_bad ("Double word for difference between two symbols "
6024 "is not supported across relaxation.");
6025 default:
6026 ;
6027 }
6028
6029 if (generic_force_reloc (fix))
6030 return 1;
6031
6032 return fix->fx_pcrel;
6033}
35c08157
KLC
6034
6035/* TC_VALIDATE_FIX_SUB */
6036
6037int
6038nds32_validate_fix_sub (fixS *fix, segT add_symbol_segment)
6039{
6040 segT sub_symbol_segment;
6041
6042 /* This code is referred from Xtensa. Check their implementation for
6043 details. */
6044
6045 /* Make sure both symbols are in the same segment, and that segment is
6046 "normal" and relaxable. */
6047 sub_symbol_segment = S_GET_SEGMENT (fix->fx_subsy);
6048 return (sub_symbol_segment == add_symbol_segment
6049 && add_symbol_segment != undefined_section);
6050}
6051
6052void
6053md_number_to_chars (char *buf, valueT val, int n)
6054{
6055 if (target_big_endian)
6056 number_to_chars_bigendian (buf, val, n);
6057 else
6058 number_to_chars_littleendian (buf, val, n);
6059}
6060
6061/* Equal to MAX_PRECISION in atof-ieee.c. */
6062#define MAX_LITTLENUMS 6
6063
6064/* This function is called to convert an ASCII string into a floating point
6065 value in format used by the CPU. */
6066
6067char *
6068md_atof (int type, char *litP, int *sizeP)
6069{
6070 int i;
6071 int prec;
6072 LITTLENUM_TYPE words[MAX_LITTLENUMS];
6073 char *t;
6074
6075 switch (type)
6076 {
6077 case 'f':
6078 case 'F':
6079 case 's':
6080 case 'S':
6081 prec = 2;
6082 break;
6083 case 'd':
6084 case 'D':
6085 case 'r':
6086 case 'R':
6087 prec = 4;
6088 break;
6089 default:
6090 *sizeP = 0;
6091 return _("Bad call to md_atof()");
6092 }
6093
6094 t = atof_ieee (input_line_pointer, type, words);
6095 if (t)
6096 input_line_pointer = t;
6097 *sizeP = prec * sizeof (LITTLENUM_TYPE);
6098
6099 if (target_big_endian)
6100 {
6101 for (i = 0; i < prec; i++)
6102 {
6103 md_number_to_chars (litP, (valueT) words[i],
6104 sizeof (LITTLENUM_TYPE));
6105 litP += sizeof (LITTLENUM_TYPE);
6106 }
6107 }
6108 else
6109 {
6110 for (i = prec - 1; i >= 0; i--)
6111 {
6112 md_number_to_chars (litP, (valueT) words[i],
6113 sizeof (LITTLENUM_TYPE));
6114 litP += sizeof (LITTLENUM_TYPE);
6115 }
6116 }
6117
6118 return 0;
6119}
6120
6121/* md_elf_section_change_hook */
6122
6123void
6124nds32_elf_section_change_hook (void)
6125{
6126}
6127
6128/* md_cleanup */
6129
6130void
6131nds32_cleanup (void)
6132{
6133}
6134
6135/* This function is used to scan leb128 subtraction expressions,
6136 and insert fixups for them.
6137
6138 e.g., .leb128 .L1 - .L0
6139
6140 These expressions are heavily used in debug information or
6141 exception tables. Because relaxation will change code size,
6142 we must resolve them in link time. */
6143
6144static void
6145nds32_insert_leb128_fixes (bfd *abfd ATTRIBUTE_UNUSED,
6146 asection *sec, void *xxx ATTRIBUTE_UNUSED)
6147{
6148 segment_info_type *seginfo = seg_info (sec);
6149 struct frag *fragP;
6150
6151 subseg_set (sec, 0);
6152
6153 for (fragP = seginfo->frchainP->frch_root;
6154 fragP; fragP = fragP->fr_next)
6155 {
6156 expressionS *exp;
6157
6158 /* Only unsigned leb128 can be handle. */
6159 if (fragP->fr_type != rs_leb128 || fragP->fr_subtype != 0
6160 || fragP->fr_symbol == NULL)
6161 continue;
6162
6163 exp = symbol_get_value_expression (fragP->fr_symbol);
6164
6165 if (exp->X_op != O_subtract)
6166 continue;
6167
6168 fix_new_exp (fragP, fragP->fr_fix, 0,
6169 exp, 0, BFD_RELOC_NDS32_DIFF_ULEB128);
6170 }
6171}
6172
6173static void
6174nds32_insert_relax_entry (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
6175 void *xxx ATTRIBUTE_UNUSED)
6176{
6177 segment_info_type *seginfo;
6178 fragS *fragP;
6179 fixS *fixP;
6180 expressionS exp;
6181 fixS *fixp;
6182
6183 seginfo = seg_info (sec);
1c8f6a4d 6184 if (!seginfo || !symbol_rootP || !subseg_text_p (sec) || sec->size == 0)
35c08157
KLC
6185 return;
6186 /* If there is no relocation and relax is disabled, it is not necessary to
6187 insert R_NDS32_RELAX_ENTRY for linker do EX9 or IFC optimization. */
6188 for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
6189 if (!fixp->fx_done)
6190 break;
6191 if (!fixp && !enable_relax_ex9 && !verbatim)
6192 return;
6193
6194 subseg_change (sec, 0);
6195
6196 /* Set RELAX_ENTRY flags for linker. */
6197 fragP = seginfo->frchainP->frch_root;
6198 exp.X_op = O_symbol;
6199 exp.X_add_symbol = section_symbol (sec);
6200 exp.X_add_number = 0;
6201 if (!enable_relax_relocs)
6202 exp.X_add_number |= R_NDS32_RELAX_ENTRY_DISABLE_RELAX_FLAG;
6203 else
6204 {
6205 /* These flags are only enabled when global relax is enabled.
6206 Maybe we can check DISABLE_RELAX_FLAG at linke-time,
6207 so we set them anyway. */
6208 if (enable_relax_ex9)
6209 exp.X_add_number |= R_NDS32_RELAX_ENTRY_EX9_FLAG;
6210 if (enable_relax_ifc)
6211 exp.X_add_number |= R_NDS32_RELAX_ENTRY_IFC_FLAG;
6212 if (verbatim)
6213 exp.X_add_number |= R_NDS32_RELAX_ENTRY_VERBATIM_FLAG;
6214 }
6215 if (optimize)
6216 exp.X_add_number |= R_NDS32_RELAX_ENTRY_OPTIMIZE_FLAG;
6217 if (optimize_for_space)
6218 exp.X_add_number |= R_NDS32_RELAX_ENTRY_OPTIMIZE_FOR_SPACE_FLAG;
6219
6220 fixP = fix_new_exp (fragP, 0, 0, &exp, 0, BFD_RELOC_NDS32_RELAX_ENTRY);
6221 fixP->fx_no_overflow = 1;
6222}
6223
6224/* Analysis relax hint and insert suitable relocation pattern. */
6225
6226static void
6227nds32_elf_analysis_relax_hint (void)
6228{
6229 hash_traverse (nds32_hint_hash, nds32_elf_append_relax_relocs);
6230}
6231
ea16498d
KLC
6232static void
6233nds32_elf_insert_final_frag (void)
6234{
6235 struct frchain *frchainP;
6236 asection *s;
6237 fragS *fragP;
6238
6239 if (!optimize)
6240 return;
6241
6242 for (s = stdoutput->sections; s; s = s->next)
6243 {
6244 segment_info_type *seginfo = seg_info (s);
6245 if (!seginfo)
6246 continue;
6247
6248 for (frchainP = seginfo->frchainP; frchainP != NULL;
6249 frchainP = frchainP->frch_next)
6250 {
6251 subseg_set (s, frchainP->frch_subseg);
6252
6253 if (subseg_text_p (now_seg))
6254 {
6255 fragP = frag_now;
6256 frag_var (rs_machine_dependent, 2, /* Max size. */
6257 0, /* VAR is un-used. */ 0, NULL, 0, NULL);
6258 fragP->tc_frag_data.flag |= NDS32_FRAG_FINAL;
6259 }
6260 }
6261 }
6262}
6263
35c08157
KLC
6264void
6265md_end (void)
6266{
ea16498d 6267 nds32_elf_insert_final_frag ();
35c08157
KLC
6268 nds32_elf_analysis_relax_hint ();
6269 bfd_map_over_sections (stdoutput, nds32_insert_leb128_fixes, NULL);
6270}
6271
6272/* Implement md_allow_local_subtract. */
6273
6274bfd_boolean
6275nds32_allow_local_subtract (expressionS *expr_l ATTRIBUTE_UNUSED,
6276 expressionS *expr_r ATTRIBUTE_UNUSED,
6277 segT sec ATTRIBUTE_UNUSED)
6278{
6279 /* Don't allow any subtraction, because relax may change the code. */
6280 return FALSE;
6281}
6282
6283/* Sort relocation by address.
6284
6285 We didn't use qsort () in stdlib, because quick-sort is not a stable
6286 sorting algorithm. Relocations at the same address (r_offset) must keep
6287 their relative order. For example, RELAX_ENTRY must be the very first
6288 relocation entry.
6289
6290 Currently, this function implements insertion-sort. */
6291
6292static int
6293compar_relent (const void *lhs, const void *rhs)
6294{
6295 const arelent **l = (const arelent **) lhs;
6296 const arelent **r = (const arelent **) rhs;
6297
6298 if ((*l)->address > (*r)->address)
6299 return 1;
6300 else if ((*l)->address == (*r)->address)
6301 return 0;
6302 else
6303 return -1;
6304}
6305
6306/* SET_SECTION_RELOCS ()
6307
6308 Although this macro is originally used to set a relocation for each section,
6309 we use it to sort relocations in the same section by the address of the
6310 relocation. */
6311
6312void
6313nds32_set_section_relocs (asection *sec, arelent ** relocs ATTRIBUTE_UNUSED,
6314 unsigned int n ATTRIBUTE_UNUSED)
6315{
6316 bfd *abfd ATTRIBUTE_UNUSED = sec->owner;
6317 if (bfd_get_section_flags (abfd, sec) & (flagword) SEC_RELOC)
1c8f6a4d
KLC
6318 nds32_insertion_sort (sec->orelocation, sec->reloc_count,
6319 sizeof (arelent**), compar_relent);
35c08157
KLC
6320}
6321
6322long
6323nds32_pcrel_from_section (fixS *fixP, segT sec ATTRIBUTE_UNUSED)
6324{
6325 if (fixP->fx_addsy == NULL || !S_IS_DEFINED (fixP->fx_addsy)
6326 || S_IS_EXTERNAL (fixP->fx_addsy) || S_IS_WEAK (fixP->fx_addsy))
6327 {
6328 /* Let linker resolve undefined symbols. */
6329 return 0;
6330 }
6331
6332 return fixP->fx_frag->fr_address + fixP->fx_where;
6333}
6334
6335/* md_post_relax_hook ()
6336 Insert relax entry relocation into sections. */
6337
6338void
6339nds32_post_relax_hook (void)
6340{
6341 bfd_map_over_sections (stdoutput, nds32_insert_relax_entry, NULL);
6342}
6343
35c08157
KLC
6344/* tc_fix_adjustable ()
6345
6346 Return whether this symbol (fixup) can be replaced with
6347 section symbols. */
6348
6349bfd_boolean
6350nds32_fix_adjustable (fixS *fixP)
6351{
6352 switch (fixP->fx_r_type)
6353 {
6354 case BFD_RELOC_NDS32_WORD_9_PCREL:
6355 case BFD_RELOC_NDS32_9_PCREL:
6356 case BFD_RELOC_NDS32_15_PCREL:
6357 case BFD_RELOC_NDS32_17_PCREL:
6358 case BFD_RELOC_NDS32_25_PCREL:
6359 case BFD_RELOC_NDS32_HI20:
6360 case BFD_RELOC_NDS32_LO12S0:
6361 case BFD_RELOC_8:
6362 case BFD_RELOC_16:
6363 case BFD_RELOC_32:
6364 case BFD_RELOC_NDS32_PTR:
1c8f6a4d
KLC
6365 case BFD_RELOC_NDS32_LONGCALL4:
6366 case BFD_RELOC_NDS32_LONGCALL5:
6367 case BFD_RELOC_NDS32_LONGCALL6:
6368 case BFD_RELOC_NDS32_LONGJUMP4:
6369 case BFD_RELOC_NDS32_LONGJUMP5:
6370 case BFD_RELOC_NDS32_LONGJUMP6:
6371 case BFD_RELOC_NDS32_LONGJUMP7:
35c08157
KLC
6372 return 1;
6373 default:
6374 return 0;
6375 }
6376}
6377
6378/* elf_tc_final_processing */
6379
6380void
6381elf_nds32_final_processing (void)
6382{
1c8f6a4d
KLC
6383 /* An FPU_COM instruction is found without previous non-FPU_COM
6384 instruction. */
35c08157
KLC
6385 if (nds32_fpu_com
6386 && !(nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST)))
6387 {
6388 /* Since only FPU_COM instructions are used and no other FPU instructions
1c8f6a4d
KLC
6389 are used. The nds32_elf_flags will be decided by the enabled options
6390 by command line or default configuration. */
35c08157
KLC
6391 if (nds32_fpu_dp_ext || nds32_fpu_sp_ext)
6392 {
6393 nds32_elf_flags |= nds32_fpu_dp_ext ? E_NDS32_HAS_FPU_DP_INST : 0;
6394 nds32_elf_flags |= nds32_fpu_sp_ext ? E_NDS32_HAS_FPU_INST : 0;
6395 }
6396 else
6397 {
6398 /* Should never here. */
6399 as_bad (_("Used FPU instructions requires enabling FPU extension"));
6400 }
6401 }
6402
6403 if (nds32_elf_flags & (E_NDS32_HAS_FPU_INST | E_NDS32_HAS_FPU_DP_INST))
6404 {
6405 /* Single/double FPU has been used, set FPU register config. */
6406 /* We did not check the actual number of register used. We may
6407 want to do it while assemble. */
6408 nds32_elf_flags &= ~E_NDS32_FPU_REG_CONF;
6409 nds32_elf_flags |= (nds32_freg << E_NDS32_FPU_REG_CONF_SHIFT);
6410 }
6411
6412 if (nds32_pic)
6413 nds32_elf_flags |= E_NDS32_HAS_PIC;
6414
6415 if (nds32_gpr16)
6416 nds32_elf_flags |= E_NDS32_HAS_REDUCED_REGS;
6417
6418 nds32_elf_flags |= (E_NDS32_ELF_VER_1_4 | nds32_abi);
6419 elf_elfheader (stdoutput)->e_flags |= nds32_elf_flags;
6420}
6421
6422/* Implement md_apply_fix. Apply the fix-up or tranform the fix-up for
6423 later relocation generation. */
6424
6425void
6426nds32_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
6427{
6428 char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
6429 bfd_vma value = *valP;
6430
6431 if (fixP->fx_r_type < BFD_RELOC_UNUSED
6432 && fixP->fx_r_type > BFD_RELOC_NONE
6433 && fixP->fx_r_type != BFD_RELOC_NDS32_DIFF_ULEB128)
6434 {
1c8f6a4d
KLC
6435 /* In our old nds32 binutils, it must convert relocations which is
6436 generated by CGEN. However, it does not have to consider this anymore.
6437 In current, it only deal with data relocations which enum
6438 is smaller than BFD_RELOC_NONE and BFD_RELOC_NDS32_DIFF_ULEB128.
6439 It is believed that we can construct a better mechanism to
6440 deal with the whole relocation issue in nds32 target
6441 without using CGEN. */
35c08157
KLC
6442 fixP->fx_addnumber = value;
6443 fixP->tc_fix_data = NULL;
1c8f6a4d
KLC
6444
6445 /* Tranform specific relocations here for later relocation generation.
6446 Tag data here for ex9 relaxtion and tag tls data for linker. */
6447 switch (fixP->fx_r_type)
6448 {
6449 case BFD_RELOC_NDS32_DATA:
6450 if (!enable_relax_ex9)
6451 fixP->fx_done = 1;
6452 break;
6453 case BFD_RELOC_NDS32_TPOFF:
6454 case BFD_RELOC_NDS32_TLS_LE_HI20:
6455 case BFD_RELOC_NDS32_TLS_LE_LO12:
6456 case BFD_RELOC_NDS32_TLS_LE_ADD:
6457 case BFD_RELOC_NDS32_TLS_LE_LS:
6458 case BFD_RELOC_NDS32_GOTTPOFF:
6459 case BFD_RELOC_NDS32_TLS_IE_HI20:
6460 case BFD_RELOC_NDS32_TLS_IE_LO12S2:
6461 S_SET_THREAD_LOCAL (fixP->fx_addsy);
6462 break;
6463 default:
6464 break;
6465 }
35c08157
KLC
6466 return;
6467 }
6468
6469 if (fixP->fx_addsy == (symbolS *) NULL)
6470 fixP->fx_done = 1;
6471
6472 if (fixP->fx_subsy != (symbolS *) NULL)
6473 {
6474 /* HOW DIFF RELOCATION WORKS.
6475
6476 First of all, this relocation is used to calculate the distance
6477 between two symbols in the SAME section. It is used for jump-
6478 table, debug information, exception table, et al. Therefore,
6479 it is a unsigned positive value. It is NOT used for general-
6480 purpose arithmetic.
6481
6482 Consider this example, the distance between .LEND and .LBEGIN
6483 is stored at the address of foo.
6484
6485 ---- >8 ---- >8 ---- >8 ---- >8 ----
6486 .data
6487 foo:
6488 .word .LBEGIN - .LEND
6489
6490 .text
6491 [before]
6492 .LBEGIN
6493 \
6494 [between] distance
6495 /
6496 .LEND
6497 [after]
6498 ---- 8< ---- 8< ---- 8< ---- 8< ----
6499
6500 We use a single relocation entry for this expression.
6501 * The initial distance value is stored direcly in that location
6502 specified by r_offset (i.e., foo in this example.)
6503 * The begin of the region, i.e., .LBEGIN, is specified by
6504 r_info/R_SYM and r_addend, e.g., .text + 0x32.
6505 * The end of region, i.e., .LEND, is represented by
6506 .LBEGIN + distance instead of .LEND, so we only need
6507 a single relocation entry instead of two.
6508
6509 When an instruction is relaxed, we adjust the relocation entry
6510 depending on where the instruction locates. There are three
6511 cases, before, after and between the region.
6512 * between: Distance value is read from r_offset, adjusted and
6513 written back into r_offset.
6514 * before: Only r_addend is adjust.
6515 * after: We don't care about it.
6516
6517 Hereby, there are some limitation.
6518
6519 `(.LEND - 1) - .LBEGIN' and `(.LEND - .LBEGIN) - 1'
6520 are semantically different, and we cannot handle latter case
6521 when relaxation.
6522
6523 The latter expression means subtracting 1 from the distance
6524 between .LEND and .LBEGIN. And the former expression means
6525 the distance between (.LEND - 1) and .LBEGIN.
6526
6527 The nuance affects whether to adjust distance value when relax
6528 an instruction. In another words, whether the instruction
6529 locates in the region. Because we use a single relocation entry,
6530 there is no field left for .LEND and the subtrahend.
6531
6532 Since GCC-4.5, GCC may produce debug information in such expression
6533 .long .L1-1-.L0
6534 in order to describe register clobbering during an function-call.
6535 .L0:
6536 call foo
6537 .L1:
6538
6539 Check http://gcc.gnu.org/ml/gcc-patches/2009-06/msg01317.html
6540 for details. */
6541
6542 value -= S_GET_VALUE (fixP->fx_subsy);
6543 *valP = value;
6544 fixP->fx_subsy = NULL;
6545 fixP->fx_offset -= value;
6546
6547 switch (fixP->fx_r_type)
6548 {
6549 case BFD_RELOC_8:
6550 fixP->fx_r_type = BFD_RELOC_NDS32_DIFF8;
6551 md_number_to_chars (where, value, 1);
6552 break;
6553 case BFD_RELOC_16:
6554 fixP->fx_r_type = BFD_RELOC_NDS32_DIFF16;
6555 md_number_to_chars (where, value, 2);
6556 break;
6557 case BFD_RELOC_32:
6558 fixP->fx_r_type = BFD_RELOC_NDS32_DIFF32;
6559 md_number_to_chars (where, value, 4);
6560 break;
6561 case BFD_RELOC_NDS32_DIFF_ULEB128:
6562 /* cvt_frag_to_fill () has called output_leb128 () for us. */
6563 break;
6564 default:
1c8f6a4d
KLC
6565 as_bad_where (fixP->fx_file, fixP->fx_line,
6566 _("expression too complex"));
35c08157
KLC
6567 return;
6568 }
6569 }
6570 else if (fixP->fx_done)
6571 {
6572 /* We're finished with this fixup. Install it because
6573 bfd_install_relocation won't be called to do it. */
6574 switch (fixP->fx_r_type)
6575 {
6576 case BFD_RELOC_8:
6577 md_number_to_chars (where, value, 1);
6578 break;
6579 case BFD_RELOC_16:
6580 md_number_to_chars (where, value, 2);
6581 break;
6582 case BFD_RELOC_32:
6583 md_number_to_chars (where, value, 4);
6584 break;
6585 case BFD_RELOC_64:
6586 md_number_to_chars (where, value, 8);
6587 default:
6588 as_bad_where (fixP->fx_file, fixP->fx_line,
6589 _("Internal error: Unknown fixup type %d (`%s')"),
1c8f6a4d
KLC
6590 fixP->fx_r_type,
6591 bfd_get_reloc_code_name (fixP->fx_r_type));
35c08157
KLC
6592 break;
6593 }
6594 }
6595}
6596
6597/* Implement tc_gen_reloc. Generate ELF relocation for a fix-up. */
6598
6599arelent *
6600tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
6601{
6602 arelent *reloc;
6603 bfd_reloc_code_real_type code;
6604
6605 reloc = (arelent *) xmalloc (sizeof (arelent));
6606
6607 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
6608 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
6609 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
6610
6611 code = fixP->fx_r_type;
6612
6613 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
6614 if (reloc->howto == (reloc_howto_type *) NULL)
6615 {
6616 as_bad_where (fixP->fx_file, fixP->fx_line,
6617 _("internal error: can't export reloc type %d (`%s')"),
6618 fixP->fx_r_type, bfd_get_reloc_code_name (code));
6619 return NULL;
6620 }
6621
6622 /* Add relocation handling here. */
6623
6624 switch (fixP->fx_r_type)
6625 {
6626 default:
6627 /* In general, addend of a relocation is the offset to the
6628 associated symbol. */
6629 reloc->addend = fixP->fx_offset;
6630 break;
6631
6632 case BFD_RELOC_NDS32_DATA:
6633 /* Prevent linker from optimizing data in text sections.
6634 For example, jump table. */
6635 reloc->addend = fixP->fx_size;
6636 break;
6637 }
6638
6639 return reloc;
6640}
6641
1c8f6a4d
KLC
6642struct suffix_name suffix_table[] =
6643{
6644 {"GOTOFF", BFD_RELOC_NDS32_GOTOFF, 1},
6645 {"GOT", BFD_RELOC_NDS32_GOT20, 1},
6646 {"TPOFF", BFD_RELOC_NDS32_TPOFF, 0},
6647 {"PLT", BFD_RELOC_NDS32_25_PLTREL, 1},
6648 {"GOTTPOFF", BFD_RELOC_NDS32_GOTTPOFF, 0}
6649};
6650
35c08157
KLC
6651/* Implement md_parse_name. */
6652
6653int
6654nds32_parse_name (char const *name, expressionS *exprP,
6655 enum expr_mode mode ATTRIBUTE_UNUSED,
6656 char *nextcharP ATTRIBUTE_UNUSED)
6657{
3bd3aeb4
KLC
6658 segT segment;
6659
35c08157
KLC
6660 exprP->X_op_symbol = NULL;
6661 exprP->X_md = BFD_RELOC_UNUSED;
6662
6663 exprP->X_add_symbol = symbol_find_or_make (name);
1c8f6a4d
KLC
6664 exprP->X_op = O_symbol;
6665 exprP->X_add_number = 0;
35c08157 6666
3bd3aeb4
KLC
6667 /* Check the specail name if a symbol. */
6668 segment = S_GET_SEGMENT (exprP->X_add_symbol);
6669 if (segment != undefined_section)
6670 return 0;
6671
1c8f6a4d
KLC
6672 if (strcmp (name, GOT_NAME) == 0 && *nextcharP != '@')
6673 {
6674 /* Set for _GOT_OFFSET_TABLE_. */
6675 exprP->X_md = BFD_RELOC_NDS32_GOTPC20;
6676 }
6677 else if (*nextcharP == '@')
35c08157
KLC
6678 {
6679 size_t i;
6680 char *next;
6681 for (i = 0; i < ARRAY_SIZE (suffix_table); i++)
6682 {
1c8f6a4d
KLC
6683 next = input_line_pointer + 1 + strlen(suffix_table[i].suffix);
6684 if (strncasecmp (input_line_pointer + 1, suffix_table[i].suffix,
6685 strlen (suffix_table[i].suffix)) == 0
35c08157
KLC
6686 && !is_part_of_name (*next))
6687 {
1c8f6a4d
KLC
6688 if (!nds32_pic && suffix_table[i].pic)
6689 as_bad (_("need PIC qualifier with symbol."));
6690 exprP->X_md = suffix_table[i].reloc;
35c08157
KLC
6691 *input_line_pointer = *nextcharP;
6692 input_line_pointer = next;
6693 *nextcharP = *input_line_pointer;
6694 *input_line_pointer = '\0';
6695 break;
6696 }
6697 }
6698 }
35c08157
KLC
6699 return 1;
6700}
6701
6702/* Implement tc_regname_to_dw2regnum. */
6703
6704int
6705tc_nds32_regname_to_dw2regnum (char *regname)
6706{
1c8f6a4d
KLC
6707 struct nds32_keyword *sym = hash_find (nds32_gprs_hash, regname);
6708
6709 if (!sym)
6710 return -1;
35c08157 6711
1c8f6a4d 6712 return sym->value;
35c08157
KLC
6713}
6714
6715void
6716tc_nds32_frame_initial_instructions (void)
6717{
6718 /* CIE */
1c8f6a4d 6719 /* Default cfa is register-31/sp. */
35c08157
KLC
6720 cfi_add_CFA_def_cfa (31, 0);
6721}
This page took 0.403018 seconds and 4 git commands to generate.