]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-bfin.c
bfd_section_* macros
[thirdparty/binutils-gdb.git] / gas / config / tc-bfin.c
CommitLineData
07c1b327 1/* tc-bfin.c -- Assembler for the ADI Blackfin.
82704155 2 Copyright (C) 2005-2019 Free Software Foundation, Inc.
07c1b327
CM
3
4 This file is part of GAS, the GNU Assembler.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
ec2655a6 8 the Free Software Foundation; either version 3, or (at your option)
07c1b327
CM
9 any later version.
10
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to the Free
18 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19 02110-1301, USA. */
20
21#include "as.h"
07c1b327
CM
22#include "bfin-defs.h"
23#include "obstack.h"
24#include "safe-ctype.h"
25#ifdef OBJ_ELF
26#include "dwarf2dbg.h"
27#endif
1ac4baed
BS
28#include "elf/common.h"
29#include "elf/bfin.h"
07c1b327
CM
30
31extern int yyparse (void);
32struct yy_buffer_state;
33typedef struct yy_buffer_state *YY_BUFFER_STATE;
34extern YY_BUFFER_STATE yy_scan_string (const char *yy_str);
35extern void yy_delete_buffer (YY_BUFFER_STATE b);
36static parse_state parse (char *line);
07c1b327
CM
37
38/* Global variables. */
39struct bfin_insn *insn;
40int last_insn_size;
41
42extern struct obstack mempool;
43FILE *errorf;
44
1ac4baed
BS
45/* Flags to set in the elf header */
46#define DEFAULT_FLAGS 0
47
fe4fa32c
MF
48#ifdef OBJ_FDPIC_ELF
49# define DEFAULT_FDPIC EF_BFIN_FDPIC
50#else
51# define DEFAULT_FDPIC 0
52#endif
53
54static flagword bfin_flags = DEFAULT_FLAGS | DEFAULT_FDPIC;
55static const char *bfin_pic_flag = DEFAULT_FDPIC ? "-mfdpic" : (const char *)0;
1ac4baed 56
1ac4baed
BS
57/* Blackfin specific function to handle FD-PIC pointer initializations. */
58
59static void
60bfin_pic_ptr (int nbytes)
61{
62 expressionS exp;
63 char *p;
64
65 if (nbytes != 4)
66 abort ();
67
68#ifdef md_flush_pending_output
69 md_flush_pending_output ();
70#endif
71
72 if (is_it_end_of_statement ())
73 {
74 demand_empty_rest_of_line ();
75 return;
76 }
77
78#ifdef md_cons_align
79 md_cons_align (nbytes);
80#endif
81
82 do
83 {
84 bfd_reloc_code_real_type reloc_type = BFD_RELOC_BFIN_FUNCDESC;
ee9e7c78 85
1ac4baed
BS
86 if (strncasecmp (input_line_pointer, "funcdesc(", 9) == 0)
87 {
88 input_line_pointer += 9;
89 expression (&exp);
90 if (*input_line_pointer == ')')
91 input_line_pointer++;
92 else
bd3ba5d1 93 as_bad (_("missing ')'"));
1ac4baed
BS
94 }
95 else
96 error ("missing funcdesc in picptr");
97
98 p = frag_more (4);
99 memset (p, 0, 4);
100 fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
101 reloc_type);
102 }
103 while (*input_line_pointer++ == ',');
104
105 input_line_pointer--; /* Put terminator back into stream. */
106 demand_empty_rest_of_line ();
107}
108
109static void
110bfin_s_bss (int ignore ATTRIBUTE_UNUSED)
111{
ed9e98c2 112 int temp;
1ac4baed
BS
113
114 temp = get_absolute_expression ();
115 subseg_set (bss_section, (subsegT) temp);
116 demand_empty_rest_of_line ();
117}
07c1b327
CM
118
119const pseudo_typeS md_pseudo_table[] = {
120 {"align", s_align_bytes, 0},
121 {"byte2", cons, 2},
122 {"byte4", cons, 4},
1ac4baed 123 {"picptr", bfin_pic_ptr, 4},
07c1b327
CM
124 {"code", obj_elf_section, 0},
125 {"db", cons, 1},
126 {"dd", cons, 4},
127 {"dw", cons, 2},
128 {"p", s_ignore, 0},
129 {"pdata", s_ignore, 0},
130 {"var", s_ignore, 0},
131 {"bss", bfin_s_bss, 0},
132 {0, 0, 0}
133};
134
07c1b327 135/* Characters that are used to denote comments and line separators. */
7286ec15 136const char comment_chars[] = "#";
07c1b327
CM
137const char line_comment_chars[] = "#";
138const char line_separator_chars[] = ";";
139
140/* Characters that can be used to separate the mantissa from the
141 exponent in floating point numbers. */
142const char EXP_CHARS[] = "eE";
143
144/* Characters that mean this number is a floating point constant.
145 As in 0f12.456 or 0d1.2345e12. */
146const char FLT_CHARS[] = "fFdDxX";
147
6306cd85
BS
148typedef enum bfin_cpu_type
149{
150 BFIN_CPU_UNKNOWN,
a23c851a
MF
151 BFIN_CPU_BF504,
152 BFIN_CPU_BF506,
6306cd85
BS
153 BFIN_CPU_BF512,
154 BFIN_CPU_BF514,
155 BFIN_CPU_BF516,
156 BFIN_CPU_BF518,
157 BFIN_CPU_BF522,
158 BFIN_CPU_BF523,
159 BFIN_CPU_BF524,
160 BFIN_CPU_BF525,
161 BFIN_CPU_BF526,
162 BFIN_CPU_BF527,
163 BFIN_CPU_BF531,
164 BFIN_CPU_BF532,
165 BFIN_CPU_BF533,
166 BFIN_CPU_BF534,
167 BFIN_CPU_BF536,
168 BFIN_CPU_BF537,
169 BFIN_CPU_BF538,
170 BFIN_CPU_BF539,
171 BFIN_CPU_BF542,
172 BFIN_CPU_BF542M,
173 BFIN_CPU_BF544,
174 BFIN_CPU_BF544M,
175 BFIN_CPU_BF547,
176 BFIN_CPU_BF547M,
177 BFIN_CPU_BF548,
178 BFIN_CPU_BF548M,
179 BFIN_CPU_BF549,
180 BFIN_CPU_BF549M,
6e38d384
MF
181 BFIN_CPU_BF561,
182 BFIN_CPU_BF592,
6306cd85
BS
183} bfin_cpu_t;
184
185bfin_cpu_t bfin_cpu_type = BFIN_CPU_UNKNOWN;
186/* -msi-revision support. There are three special values:
187 -1 -msi-revision=none.
188 0xffff -msi-revision=any. */
189int bfin_si_revision;
190
191unsigned int bfin_anomaly_checks = 0;
192
193struct bfin_cpu
194{
195 const char *name;
196 bfin_cpu_t type;
197 int si_revision;
198 unsigned int anomaly_checks;
199};
200
201struct bfin_cpu bfin_cpus[] =
202{
a23c851a
MF
203 {"bf504", BFIN_CPU_BF504, 0x0000, AC_05000074},
204
205 {"bf506", BFIN_CPU_BF506, 0x0000, AC_05000074},
206
30208012 207 {"bf512", BFIN_CPU_BF512, 0x0002, AC_05000074},
6306cd85
BS
208 {"bf512", BFIN_CPU_BF512, 0x0001, AC_05000074},
209 {"bf512", BFIN_CPU_BF512, 0x0000, AC_05000074},
210
30208012 211 {"bf514", BFIN_CPU_BF514, 0x0002, AC_05000074},
6306cd85
BS
212 {"bf514", BFIN_CPU_BF514, 0x0001, AC_05000074},
213 {"bf514", BFIN_CPU_BF514, 0x0000, AC_05000074},
214
30208012 215 {"bf516", BFIN_CPU_BF516, 0x0002, AC_05000074},
6306cd85
BS
216 {"bf516", BFIN_CPU_BF516, 0x0001, AC_05000074},
217 {"bf516", BFIN_CPU_BF516, 0x0000, AC_05000074},
218
30208012 219 {"bf518", BFIN_CPU_BF518, 0x0002, AC_05000074},
6306cd85
BS
220 {"bf518", BFIN_CPU_BF518, 0x0001, AC_05000074},
221 {"bf518", BFIN_CPU_BF518, 0x0000, AC_05000074},
222
223 {"bf522", BFIN_CPU_BF522, 0x0002, AC_05000074},
224 {"bf522", BFIN_CPU_BF522, 0x0001, AC_05000074},
225 {"bf522", BFIN_CPU_BF522, 0x0000, AC_05000074},
226
227 {"bf523", BFIN_CPU_BF523, 0x0002, AC_05000074},
228 {"bf523", BFIN_CPU_BF523, 0x0001, AC_05000074},
229 {"bf523", BFIN_CPU_BF523, 0x0000, AC_05000074},
230
231 {"bf524", BFIN_CPU_BF524, 0x0002, AC_05000074},
232 {"bf524", BFIN_CPU_BF524, 0x0001, AC_05000074},
233 {"bf524", BFIN_CPU_BF524, 0x0000, AC_05000074},
234
235 {"bf525", BFIN_CPU_BF525, 0x0002, AC_05000074},
236 {"bf525", BFIN_CPU_BF525, 0x0001, AC_05000074},
237 {"bf525", BFIN_CPU_BF525, 0x0000, AC_05000074},
238
239 {"bf526", BFIN_CPU_BF526, 0x0002, AC_05000074},
240 {"bf526", BFIN_CPU_BF526, 0x0001, AC_05000074},
241 {"bf526", BFIN_CPU_BF526, 0x0000, AC_05000074},
242
243 {"bf527", BFIN_CPU_BF527, 0x0002, AC_05000074},
244 {"bf527", BFIN_CPU_BF527, 0x0001, AC_05000074},
245 {"bf527", BFIN_CPU_BF527, 0x0000, AC_05000074},
246
247 {"bf531", BFIN_CPU_BF531, 0x0006, AC_05000074},
248 {"bf531", BFIN_CPU_BF531, 0x0005, AC_05000074},
249 {"bf531", BFIN_CPU_BF531, 0x0004, AC_05000074},
250 {"bf531", BFIN_CPU_BF531, 0x0003, AC_05000074},
251
252 {"bf532", BFIN_CPU_BF532, 0x0006, AC_05000074},
253 {"bf532", BFIN_CPU_BF532, 0x0005, AC_05000074},
254 {"bf532", BFIN_CPU_BF532, 0x0004, AC_05000074},
255 {"bf532", BFIN_CPU_BF532, 0x0003, AC_05000074},
256
257 {"bf533", BFIN_CPU_BF533, 0x0006, AC_05000074},
258 {"bf533", BFIN_CPU_BF533, 0x0005, AC_05000074},
259 {"bf533", BFIN_CPU_BF533, 0x0004, AC_05000074},
260 {"bf533", BFIN_CPU_BF533, 0x0003, AC_05000074},
261
262 {"bf534", BFIN_CPU_BF534, 0x0003, AC_05000074},
263 {"bf534", BFIN_CPU_BF534, 0x0002, AC_05000074},
264 {"bf534", BFIN_CPU_BF534, 0x0001, AC_05000074},
265
266 {"bf536", BFIN_CPU_BF536, 0x0003, AC_05000074},
267 {"bf536", BFIN_CPU_BF536, 0x0002, AC_05000074},
268 {"bf536", BFIN_CPU_BF536, 0x0001, AC_05000074},
269
270 {"bf537", BFIN_CPU_BF537, 0x0003, AC_05000074},
271 {"bf537", BFIN_CPU_BF537, 0x0002, AC_05000074},
272 {"bf537", BFIN_CPU_BF537, 0x0001, AC_05000074},
273
274 {"bf538", BFIN_CPU_BF538, 0x0005, AC_05000074},
275 {"bf538", BFIN_CPU_BF538, 0x0004, AC_05000074},
276 {"bf538", BFIN_CPU_BF538, 0x0003, AC_05000074},
277 {"bf538", BFIN_CPU_BF538, 0x0002, AC_05000074},
278
279 {"bf539", BFIN_CPU_BF539, 0x0005, AC_05000074},
280 {"bf539", BFIN_CPU_BF539, 0x0004, AC_05000074},
281 {"bf539", BFIN_CPU_BF539, 0x0003, AC_05000074},
282 {"bf539", BFIN_CPU_BF539, 0x0002, AC_05000074},
283
284 {"bf542m", BFIN_CPU_BF542M, 0x0003, AC_05000074},
285
7f35e991 286 {"bf542", BFIN_CPU_BF542, 0x0004, AC_05000074},
6306cd85
BS
287 {"bf542", BFIN_CPU_BF542, 0x0002, AC_05000074},
288 {"bf542", BFIN_CPU_BF542, 0x0001, AC_05000074},
289 {"bf542", BFIN_CPU_BF542, 0x0000, AC_05000074},
290
291 {"bf544m", BFIN_CPU_BF544M, 0x0003, AC_05000074},
292
7f35e991 293 {"bf544", BFIN_CPU_BF544, 0x0004, AC_05000074},
6306cd85
BS
294 {"bf544", BFIN_CPU_BF544, 0x0002, AC_05000074},
295 {"bf544", BFIN_CPU_BF544, 0x0001, AC_05000074},
296 {"bf544", BFIN_CPU_BF544, 0x0000, AC_05000074},
297
298 {"bf547m", BFIN_CPU_BF547M, 0x0003, AC_05000074},
299
7f35e991 300 {"bf547", BFIN_CPU_BF547, 0x0004, AC_05000074},
6306cd85
BS
301 {"bf547", BFIN_CPU_BF547, 0x0002, AC_05000074},
302 {"bf547", BFIN_CPU_BF547, 0x0001, AC_05000074},
303 {"bf547", BFIN_CPU_BF547, 0x0000, AC_05000074},
304
305 {"bf548m", BFIN_CPU_BF548M, 0x0003, AC_05000074},
306
7f35e991 307 {"bf548", BFIN_CPU_BF548, 0x0004, AC_05000074},
6306cd85
BS
308 {"bf548", BFIN_CPU_BF548, 0x0002, AC_05000074},
309 {"bf548", BFIN_CPU_BF548, 0x0001, AC_05000074},
310 {"bf548", BFIN_CPU_BF548, 0x0000, AC_05000074},
311
312 {"bf549m", BFIN_CPU_BF549M, 0x0003, AC_05000074},
313
7f35e991 314 {"bf549", BFIN_CPU_BF549, 0x0004, AC_05000074},
6306cd85
BS
315 {"bf549", BFIN_CPU_BF549, 0x0002, AC_05000074},
316 {"bf549", BFIN_CPU_BF549, 0x0001, AC_05000074},
317 {"bf549", BFIN_CPU_BF549, 0x0000, AC_05000074},
318
319 {"bf561", BFIN_CPU_BF561, 0x0005, AC_05000074},
320 {"bf561", BFIN_CPU_BF561, 0x0003, AC_05000074},
321 {"bf561", BFIN_CPU_BF561, 0x0002, AC_05000074},
322
6e38d384
MF
323 {"bf592", BFIN_CPU_BF592, 0x0001, AC_05000074},
324 {"bf592", BFIN_CPU_BF592, 0x0000, AC_05000074},
6306cd85
BS
325};
326
07c1b327
CM
327/* Define bfin-specific command-line options (there are none). */
328const char *md_shortopts = "";
329
1ac4baed 330#define OPTION_FDPIC (OPTION_MD_BASE)
fe4fa32c 331#define OPTION_NOPIC (OPTION_MD_BASE + 1)
6306cd85 332#define OPTION_MCPU (OPTION_MD_BASE + 2)
1ac4baed
BS
333
334struct option md_longopts[] =
335{
6306cd85 336 { "mcpu", required_argument, NULL, OPTION_MCPU },
fe4fa32c
MF
337 { "mfdpic", no_argument, NULL, OPTION_FDPIC },
338 { "mnopic", no_argument, NULL, OPTION_NOPIC },
339 { "mno-fdpic", no_argument, NULL, OPTION_NOPIC },
1ac4baed 340 { NULL, no_argument, NULL, 0 },
07c1b327 341};
1ac4baed 342
07c1b327
CM
343size_t md_longopts_size = sizeof (md_longopts);
344
345
346int
17b9d67d 347md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED)
07c1b327 348{
1ac4baed
BS
349 switch (c)
350 {
351 default:
352 return 0;
353
6306cd85
BS
354 case OPTION_MCPU:
355 {
5703197e
TS
356 const char *q;
357 unsigned int i;
6306cd85 358
5703197e 359 for (i = 0; i < ARRAY_SIZE (bfin_cpus); i++)
6306cd85 360 {
5703197e 361 const char *p = bfin_cpus[i].name;
6306cd85
BS
362 if (strncmp (arg, p, strlen (p)) == 0)
363 break;
6306cd85
BS
364 }
365
5703197e 366 if (i == ARRAY_SIZE (bfin_cpus))
110c21e1 367 as_fatal ("-mcpu=%s is not valid", arg);
6306cd85
BS
368
369 bfin_cpu_type = bfin_cpus[i].type;
370
5703197e 371 q = arg + strlen (bfin_cpus[i].name);
6306cd85
BS
372
373 if (*q == '\0')
374 {
375 bfin_si_revision = bfin_cpus[i].si_revision;
376 bfin_anomaly_checks |= bfin_cpus[i].anomaly_checks;
377 }
378 else if (strcmp (q, "-none") == 0)
379 bfin_si_revision = -1;
380 else if (strcmp (q, "-any") == 0)
381 {
382 bfin_si_revision = 0xffff;
5703197e
TS
383 while (i < ARRAY_SIZE (bfin_cpus)
384 && bfin_cpus[i].type == bfin_cpu_type)
6306cd85
BS
385 {
386 bfin_anomaly_checks |= bfin_cpus[i].anomaly_checks;
387 i++;
388 }
389 }
390 else
391 {
392 unsigned int si_major, si_minor;
393 int rev_len, n;
394
395 rev_len = strlen (q);
396
397 if (sscanf (q, "-%u.%u%n", &si_major, &si_minor, &n) != 2
398 || n != rev_len
399 || si_major > 0xff || si_minor > 0xff)
400 {
401 invalid_silicon_revision:
110c21e1 402 as_fatal ("-mcpu=%s has invalid silicon revision", arg);
6306cd85
BS
403 }
404
405 bfin_si_revision = (si_major << 8) | si_minor;
406
5703197e
TS
407 while (i < ARRAY_SIZE (bfin_cpus)
408 && bfin_cpus[i].type == bfin_cpu_type
6306cd85
BS
409 && bfin_cpus[i].si_revision != bfin_si_revision)
410 i++;
411
5703197e
TS
412 if (i == ARRAY_SIZE (bfin_cpus)
413 || bfin_cpus[i].type != bfin_cpu_type)
6306cd85
BS
414 goto invalid_silicon_revision;
415
416 bfin_anomaly_checks |= bfin_cpus[i].anomaly_checks;
417 }
418
419 break;
420 }
421
1ac4baed
BS
422 case OPTION_FDPIC:
423 bfin_flags |= EF_BFIN_FDPIC;
424 bfin_pic_flag = "-mfdpic";
425 break;
fe4fa32c
MF
426
427 case OPTION_NOPIC:
428 bfin_flags &= ~(EF_BFIN_FDPIC);
429 bfin_pic_flag = 0;
430 break;
1ac4baed
BS
431 }
432
433 return 1;
07c1b327
CM
434}
435
436void
9982501a 437md_show_usage (FILE * stream)
07c1b327 438{
9982501a
JZ
439 fprintf (stream, _(" Blackfin specific assembler options:\n"));
440 fprintf (stream, _(" -mcpu=<cpu[-sirevision]> specify the name of the target CPU\n"));
441 fprintf (stream, _(" -mfdpic assemble for the FDPIC ABI\n"));
442 fprintf (stream, _(" -mno-fdpic/-mnopic disable -mfdpic\n"));
07c1b327
CM
443}
444
445/* Perform machine-specific initializations. */
446void
e6c7cdec 447md_begin (void)
07c1b327 448{
1ac4baed
BS
449 /* Set the ELF flags if desired. */
450 if (bfin_flags)
451 bfd_set_private_flags (stdoutput, bfin_flags);
452
07c1b327
CM
453 /* Set the default machine type. */
454 if (!bfd_set_arch_mach (stdoutput, bfd_arch_bfin, 0))
bd3ba5d1 455 as_warn (_("Could not set architecture and machine."));
07c1b327
CM
456
457 /* Ensure that lines can begin with '(', for multiple
458 register stack pops. */
9f8e671b 459 lex_type ['('] = LEX_BEGIN_NAME;
ee9e7c78 460
07c1b327
CM
461#ifdef OBJ_ELF
462 record_alignment (text_section, 2);
463 record_alignment (data_section, 2);
464 record_alignment (bss_section, 2);
465#endif
466
467 errorf = stderr;
468 obstack_init (&mempool);
469
470#ifdef DEBUG
471 extern int debug_codeselection;
472 debug_codeselection = 1;
ee9e7c78 473#endif
07c1b327
CM
474
475 last_insn_size = 0;
476}
477
478/* Perform the main parsing, and assembly of the input here. Also,
479 call the required routines for alignment and fixups here.
480 This is called for every line that contains real assembly code. */
481
482void
483md_assemble (char *line)
484{
485 char *toP = 0;
07c1b327
CM
486 int size, insn_size;
487 struct bfin_insn *tmp_insn;
488 size_t len;
489 static size_t buffer_len = 0;
e1ec8109 490 static char *current_inputline;
07c1b327
CM
491 parse_state state;
492
493 len = strlen (line);
494 if (len + 2 > buffer_len)
495 {
07c1b327 496 buffer_len = len + 40;
e1ec8109 497 current_inputline = XRESIZEVEC (char, current_inputline, buffer_len);
07c1b327
CM
498 }
499 memcpy (current_inputline, line, len);
500 current_inputline[len] = ';';
501 current_inputline[len + 1] = '\0';
502
503 state = parse (current_inputline);
504 if (state == NO_INSN_GENERATED)
505 return;
506
507 for (insn_size = 0, tmp_insn = insn; tmp_insn; tmp_insn = tmp_insn->next)
508 if (!tmp_insn->reloc || !tmp_insn->exp->symbol)
509 insn_size += 2;
510
511 if (insn_size)
512 toP = frag_more (insn_size);
513
514 last_insn_size = insn_size;
515
516#ifdef DEBUG
517 printf ("INS:");
518#endif
519 while (insn)
520 {
521 if (insn->reloc && insn->exp->symbol)
522 {
523 char *prev_toP = toP - 2;
524 switch (insn->reloc)
525 {
526 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
527 case BFD_RELOC_24_PCREL:
528 case BFD_RELOC_BFIN_16_LOW:
529 case BFD_RELOC_BFIN_16_HIGH:
530 size = 4;
531 break;
532 default:
533 size = 2;
534 }
535
536 /* Following if condition checks for the arithmetic relocations.
537 If the case then it doesn't required to generate the code.
538 It has been assumed that, their ID will be contiguous. */
539 if ((BFD_ARELOC_BFIN_PUSH <= insn->reloc
540 && BFD_ARELOC_BFIN_COMP >= insn->reloc)
541 || insn->reloc == BFD_RELOC_BFIN_16_IMM)
542 {
543 size = 2;
544 }
545 if (insn->reloc == BFD_ARELOC_BFIN_CONST
546 || insn->reloc == BFD_ARELOC_BFIN_PUSH)
547 size = 4;
548
549 fix_new (frag_now,
550 (prev_toP - frag_now->fr_literal),
551 size, insn->exp->symbol, insn->exp->value,
552 insn->pcrel, insn->reloc);
553 }
554 else
555 {
556 md_number_to_chars (toP, insn->value, 2);
557 toP += 2;
558 }
559
560#ifdef DEBUG
561 printf (" reloc :");
562 printf (" %02x%02x", ((unsigned char *) &insn->value)[0],
563 ((unsigned char *) &insn->value)[1]);
564 printf ("\n");
565#endif
566 insn = insn->next;
567 }
568#ifdef OBJ_ELF
569 dwarf2_emit_insn (insn_size);
570#endif
bd03da30
JZ
571
572 while (*line++ != '\0')
573 if (*line == '\n')
574 bump_line_counters ();
07c1b327
CM
575}
576
577/* Parse one line of instructions, and generate opcode for it.
578 To parse the line, YACC and LEX are used, because the instruction set
579 syntax doesn't confirm to the AT&T assembly syntax.
580 To call a YACC & LEX generated parser, we must provide the input via
581 a FILE stream, otherwise stdin is used by default. Below the input
582 to the function will be put into a temporary file, then the generated
583 parser uses the temporary file for parsing. */
584
585static parse_state
586parse (char *line)
587{
588 parse_state state;
589 YY_BUFFER_STATE buffstate;
590
591 buffstate = yy_scan_string (line);
592
593 /* our lex requires setting the start state to keyword
594 every line as the first word may be a keyword.
595 Fixes a bug where we could not have keywords as labels. */
596 set_start_state ();
597
598 /* Call yyparse here. */
599 state = yyparse ();
600 if (state == SEMANTIC_ERROR)
601 {
bd3ba5d1 602 as_bad (_("Parse failed."));
07c1b327
CM
603 insn = 0;
604 }
605
606 yy_delete_buffer (buffstate);
607 return state;
608}
609
610/* We need to handle various expressions properly.
611 Such as, [SP--] = 34, concerned by md_assemble(). */
612
613void
614md_operand (expressionS * expressionP)
615{
616 if (*input_line_pointer == '[')
617 {
618 as_tsktsk ("We found a '['!");
619 input_line_pointer++;
620 expression (expressionP);
621 }
622}
623
624/* Handle undefined symbols. */
625symbolS *
626md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
627{
628 return (symbolS *) 0;
629}
630
631int
632md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
633 segT segment ATTRIBUTE_UNUSED)
634{
635 return 0;
636}
637
638/* Convert from target byte order to host byte order. */
639
640static int
9ba4c445 641md_chars_to_number (char *val, int n)
07c1b327
CM
642{
643 int retval;
644
645 for (retval = 0; n--;)
646 {
647 retval <<= 8;
648 retval |= val[n];
649 }
650 return retval;
651}
652
653void
654md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
655{
656 char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
657
658 long value = *valueP;
659 long newval;
660
661 switch (fixP->fx_r_type)
662 {
663 case BFD_RELOC_BFIN_GOT:
1ac4baed
BS
664 case BFD_RELOC_BFIN_GOT17M4:
665 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
07c1b327
CM
666 fixP->fx_no_overflow = 1;
667 newval = md_chars_to_number (where, 2);
668 newval |= 0x0 & 0x7f;
669 md_number_to_chars (where, newval, 2);
670 break;
671
672 case BFD_RELOC_BFIN_10_PCREL:
673 if (!value)
674 break;
675 if (value < -1024 || value > 1022)
676 as_bad_where (fixP->fx_file, fixP->fx_line,
bd3ba5d1 677 _("pcrel too far BFD_RELOC_BFIN_10"));
07c1b327
CM
678
679 /* 11 bit offset even numbered, so we remove right bit. */
680 value = value >> 1;
681 newval = md_chars_to_number (where, 2);
682 newval |= value & 0x03ff;
683 md_number_to_chars (where, newval, 2);
684 break;
685
686 case BFD_RELOC_BFIN_12_PCREL_JUMP:
687 case BFD_RELOC_BFIN_12_PCREL_JUMP_S:
688 case BFD_RELOC_12_PCREL:
689 if (!value)
690 break;
691
692 if (value < -4096 || value > 4094)
bd3ba5d1 693 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_12"));
07c1b327
CM
694 /* 13 bit offset even numbered, so we remove right bit. */
695 value = value >> 1;
696 newval = md_chars_to_number (where, 2);
697 newval |= value & 0xfff;
698 md_number_to_chars (where, newval, 2);
699 break;
700
701 case BFD_RELOC_BFIN_16_LOW:
702 case BFD_RELOC_BFIN_16_HIGH:
703 fixP->fx_done = FALSE;
704 break;
705
706 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
707 case BFD_RELOC_BFIN_24_PCREL_CALL_X:
708 case BFD_RELOC_24_PCREL:
709 if (!value)
710 break;
711
712 if (value < -16777216 || value > 16777214)
bd3ba5d1 713 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_24"));
07c1b327
CM
714
715 /* 25 bit offset even numbered, so we remove right bit. */
716 value = value >> 1;
717 value++;
718
719 md_number_to_chars (where - 2, value >> 16, 1);
720 md_number_to_chars (where, value, 1);
721 md_number_to_chars (where + 1, value >> 8, 1);
722 break;
723
724 case BFD_RELOC_BFIN_5_PCREL: /* LSETUP (a, b) : "a" */
725 if (!value)
726 break;
727 if (value < 4 || value > 30)
bd3ba5d1 728 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_5"));
07c1b327
CM
729 value = value >> 1;
730 newval = md_chars_to_number (where, 1);
731 newval = (newval & 0xf0) | (value & 0xf);
732 md_number_to_chars (where, newval, 1);
733 break;
734
735 case BFD_RELOC_BFIN_11_PCREL: /* LSETUP (a, b) : "b" */
736 if (!value)
737 break;
738 value += 2;
739 if (value < 4 || value > 2046)
bd3ba5d1 740 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_11_PCREL"));
07c1b327
CM
741 /* 11 bit unsigned even, so we remove right bit. */
742 value = value >> 1;
743 newval = md_chars_to_number (where, 2);
744 newval |= value & 0x03ff;
745 md_number_to_chars (where, newval, 2);
746 break;
747
748 case BFD_RELOC_8:
749 if (value < -0x80 || value >= 0x7f)
bd3ba5d1 750 as_bad_where (fixP->fx_file, fixP->fx_line, _("rel too far BFD_RELOC_8"));
07c1b327
CM
751 md_number_to_chars (where, value, 1);
752 break;
753
754 case BFD_RELOC_BFIN_16_IMM:
755 case BFD_RELOC_16:
756 if (value < -0x8000 || value >= 0x7fff)
bd3ba5d1 757 as_bad_where (fixP->fx_file, fixP->fx_line, _("rel too far BFD_RELOC_16"));
07c1b327
CM
758 md_number_to_chars (where, value, 2);
759 break;
760
761 case BFD_RELOC_32:
762 md_number_to_chars (where, value, 4);
763 break;
764
765 case BFD_RELOC_BFIN_PLTPC:
766 md_number_to_chars (where, value, 2);
767 break;
768
1ac4baed 769 case BFD_RELOC_BFIN_FUNCDESC:
07c1b327
CM
770 case BFD_RELOC_VTABLE_INHERIT:
771 case BFD_RELOC_VTABLE_ENTRY:
772 fixP->fx_done = FALSE;
773 break;
774
775 default:
776 if ((BFD_ARELOC_BFIN_PUSH > fixP->fx_r_type) || (BFD_ARELOC_BFIN_COMP < fixP->fx_r_type))
777 {
778 fprintf (stderr, "Relocation %d not handled in gas." " Contact support.\n", fixP->fx_r_type);
779 return;
780 }
781 }
782
783 if (!fixP->fx_addsy)
784 fixP->fx_done = TRUE;
785
786}
787
788/* Round up a section size to the appropriate boundary. */
789valueT
e046cf80 790md_section_align (segT segment, valueT size)
07c1b327 791{
fd361982 792 int boundary = bfd_section_alignment (segment);
8d3842cd 793 return ((size + (1 << boundary) - 1) & -(1 << boundary));
07c1b327
CM
794}
795
796
6d4af3c2 797const char *
499ac353 798md_atof (int type, char * litP, int * sizeP)
07c1b327 799{
499ac353 800 return ieee_md_atof (type, litP, sizeP, FALSE);
07c1b327
CM
801}
802
803
804/* If while processing a fixup, a reloc really needs to be created
805 then it is done here. */
806
807arelent *
e046cf80 808tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
07c1b327
CM
809{
810 arelent *reloc;
811
add39d23
TS
812 reloc = XNEW (arelent);
813 reloc->sym_ptr_ptr = XNEW (asymbol *);
07c1b327
CM
814 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
815 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
816
817 reloc->addend = fixp->fx_offset;
818 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
819
820 if (reloc->howto == (reloc_howto_type *) NULL)
821 {
822 as_bad_where (fixp->fx_file, fixp->fx_line,
823 /* xgettext:c-format. */
824 _("reloc %d not supported by object file format"),
825 (int) fixp->fx_r_type);
826
827 xfree (reloc);
828
829 return NULL;
830 }
831
832 return reloc;
833}
834
835/* The location from which a PC relative jump should be calculated,
836 given a PC relative reloc. */
837
838long
e046cf80 839md_pcrel_from_section (fixS *fixP, segT sec)
07c1b327
CM
840{
841 if (fixP->fx_addsy != (symbolS *) NULL
842 && (!S_IS_DEFINED (fixP->fx_addsy)
843 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
844 {
845 /* The symbol is undefined (or is defined but not in this section).
846 Let the linker figure it out. */
847 return 0;
848 }
849 return fixP->fx_frag->fr_address + fixP->fx_where;
850}
851
852/* Return true if the fix can be handled by GAS, false if it must
853 be passed through to the linker. */
854
ee9e7c78 855bfd_boolean
07c1b327 856bfin_fix_adjustable (fixS *fixP)
ee9e7c78 857{
07c1b327 858 switch (fixP->fx_r_type)
ee9e7c78 859 {
07c1b327 860 /* Adjust_reloc_syms doesn't know about the GOT. */
1ac4baed 861 case BFD_RELOC_BFIN_GOT:
1ac4baed 862 case BFD_RELOC_BFIN_PLTPC:
07c1b327
CM
863 /* We need the symbol name for the VTABLE entries. */
864 case BFD_RELOC_VTABLE_INHERIT:
865 case BFD_RELOC_VTABLE_ENTRY:
866 return 0;
ee9e7c78 867
07c1b327
CM
868 default:
869 return 1;
ee9e7c78 870 }
07c1b327
CM
871}
872
07c1b327
CM
873/* Special extra functions that help bfin-parse.y perform its job. */
874
07c1b327
CM
875struct obstack mempool;
876
877INSTR_T
878conscode (INSTR_T head, INSTR_T tail)
879{
880 if (!head)
881 return tail;
882 head->next = tail;
883 return head;
884}
885
886INSTR_T
887conctcode (INSTR_T head, INSTR_T tail)
888{
889 INSTR_T temp = (head);
890 if (!head)
891 return tail;
892 while (temp->next)
893 temp = temp->next;
894 temp->next = tail;
895
896 return head;
897}
898
899INSTR_T
900note_reloc (INSTR_T code, Expr_Node * symbol, int reloc, int pcrel)
901{
902 /* Assert that the symbol is not an operator. */
9c2799c2 903 gas_assert (symbol->type == Expr_Node_Reloc);
07c1b327
CM
904
905 return note_reloc1 (code, symbol->value.s_value, reloc, pcrel);
906
907}
908
909INSTR_T
910note_reloc1 (INSTR_T code, const char *symbol, int reloc, int pcrel)
911{
912 code->reloc = reloc;
913 code->exp = mkexpr (0, symbol_find_or_make (symbol));
914 code->pcrel = pcrel;
915 return code;
916}
917
918INSTR_T
919note_reloc2 (INSTR_T code, const char *symbol, int reloc, int value, int pcrel)
920{
921 code->reloc = reloc;
922 code->exp = mkexpr (value, symbol_find_or_make (symbol));
923 code->pcrel = pcrel;
924 return code;
925}
926
927INSTR_T
928gencode (unsigned long x)
929{
aff7ae12 930 INSTR_T cell = XOBNEW (&mempool, struct bfin_insn);
07c1b327
CM
931 memset (cell, 0, sizeof (struct bfin_insn));
932 cell->value = (x);
933 return cell;
934}
935
936int reloc;
937int ninsns;
938int count_insns;
939
940static void *
e57e6ddc 941allocate (size_t n)
07c1b327 942{
78aff5a5 943 return obstack_alloc (&mempool, n);
07c1b327
CM
944}
945
946Expr_Node *
947Expr_Node_Create (Expr_Node_Type type,
948 Expr_Node_Value value,
949 Expr_Node *Left_Child,
950 Expr_Node *Right_Child)
951{
952
953
954 Expr_Node *node = (Expr_Node *) allocate (sizeof (Expr_Node));
955 node->type = type;
956 node->value = value;
957 node->Left_Child = Left_Child;
958 node->Right_Child = Right_Child;
959 return node;
960}
961
962static const char *con = ".__constant";
963static const char *op = ".__operator";
964static INSTR_T Expr_Node_Gen_Reloc_R (Expr_Node * head);
965INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc);
966
967INSTR_T
968Expr_Node_Gen_Reloc (Expr_Node * head, int parent_reloc)
969{
33eaf5de 970 /* Top level relocation expression generator VDSP style.
07c1b327
CM
971 If the relocation is just by itself, generate one item
972 else generate this convoluted expression. */
973
974 INSTR_T note = NULL_CODE;
975 INSTR_T note1 = NULL_CODE;
33eaf5de 976 int pcrel = 1; /* Is the parent reloc pc-relative?
07c1b327
CM
977 This calculation here and HOWTO should match. */
978
979 if (parent_reloc)
980 {
981 /* If it's 32 bit quantity then 16bit code needs to be added. */
982 int value = 0;
983
984 if (head->type == Expr_Node_Constant)
985 {
986 /* If note1 is not null code, we have to generate a right
987 aligned value for the constant. Otherwise the reloc is
988 a part of the basic command and the yacc file
989 generates this. */
990 value = head->value.i_value;
991 }
992 switch (parent_reloc)
993 {
708587a4 994 /* Some relocations will need to allocate extra words. */
07c1b327
CM
995 case BFD_RELOC_BFIN_16_IMM:
996 case BFD_RELOC_BFIN_16_LOW:
997 case BFD_RELOC_BFIN_16_HIGH:
998 note1 = conscode (gencode (value), NULL_CODE);
999 pcrel = 0;
1000 break;
1001 case BFD_RELOC_BFIN_PLTPC:
1002 note1 = conscode (gencode (value), NULL_CODE);
1003 pcrel = 0;
1004 break;
1005 case BFD_RELOC_16:
1006 case BFD_RELOC_BFIN_GOT:
1ac4baed
BS
1007 case BFD_RELOC_BFIN_GOT17M4:
1008 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
07c1b327
CM
1009 note1 = conscode (gencode (value), NULL_CODE);
1010 pcrel = 0;
1011 break;
1012 case BFD_RELOC_24_PCREL:
1013 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
1014 case BFD_RELOC_BFIN_24_PCREL_CALL_X:
1015 /* These offsets are even numbered pcrel. */
1016 note1 = conscode (gencode (value >> 1), NULL_CODE);
1017 break;
1018 default:
1019 note1 = NULL_CODE;
1020 }
1021 }
1022 if (head->type == Expr_Node_Constant)
1023 note = note1;
1024 else if (head->type == Expr_Node_Reloc)
1025 {
1026 note = note_reloc1 (gencode (0), head->value.s_value, parent_reloc, pcrel);
1027 if (note1 != NULL_CODE)
1028 note = conscode (note1, note);
1029 }
beb6bfe8
BS
1030 else if (head->type == Expr_Node_Binop
1031 && (head->value.op_value == Expr_Op_Type_Add
1032 || head->value.op_value == Expr_Op_Type_Sub)
1033 && head->Left_Child->type == Expr_Node_Reloc
1034 && head->Right_Child->type == Expr_Node_Constant)
1035 {
1036 int val = head->Right_Child->value.i_value;
1037 if (head->value.op_value == Expr_Op_Type_Sub)
1038 val = -val;
1039 note = conscode (note_reloc2 (gencode (0), head->Left_Child->value.s_value,
1040 parent_reloc, val, 0),
1041 NULL_CODE);
1042 if (note1 != NULL_CODE)
1043 note = conscode (note1, note);
1044 }
07c1b327
CM
1045 else
1046 {
1047 /* Call the recursive function. */
1048 note = note_reloc1 (gencode (0), op, parent_reloc, pcrel);
1049 if (note1 != NULL_CODE)
1050 note = conscode (note1, note);
1051 note = conctcode (Expr_Node_Gen_Reloc_R (head), note);
1052 }
1053 return note;
1054}
1055
1056static INSTR_T
1057Expr_Node_Gen_Reloc_R (Expr_Node * head)
1058{
1059
1060 INSTR_T note = 0;
1061 INSTR_T note1 = 0;
1062
1063 switch (head->type)
1064 {
1065 case Expr_Node_Constant:
1066 note = conscode (note_reloc2 (gencode (0), con, BFD_ARELOC_BFIN_CONST, head->value.i_value, 0), NULL_CODE);
1067 break;
1068 case Expr_Node_Reloc:
1069 note = conscode (note_reloc (gencode (0), head, BFD_ARELOC_BFIN_PUSH, 0), NULL_CODE);
1070 break;
1071 case Expr_Node_Binop:
1072 note1 = conctcode (Expr_Node_Gen_Reloc_R (head->Left_Child), Expr_Node_Gen_Reloc_R (head->Right_Child));
1073 switch (head->value.op_value)
1074 {
1075 case Expr_Op_Type_Add:
1076 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_ADD, 0), NULL_CODE));
1077 break;
1078 case Expr_Op_Type_Sub:
1079 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_SUB, 0), NULL_CODE));
1080 break;
1081 case Expr_Op_Type_Mult:
1082 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MULT, 0), NULL_CODE));
1083 break;
1084 case Expr_Op_Type_Div:
1085 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_DIV, 0), NULL_CODE));
1086 break;
1087 case Expr_Op_Type_Mod:
1088 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MOD, 0), NULL_CODE));
1089 break;
1090 case Expr_Op_Type_Lshift:
1091 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LSHIFT, 0), NULL_CODE));
1092 break;
1093 case Expr_Op_Type_Rshift:
1094 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_RSHIFT, 0), NULL_CODE));
1095 break;
1096 case Expr_Op_Type_BAND:
1097 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_AND, 0), NULL_CODE));
1098 break;
1099 case Expr_Op_Type_BOR:
1100 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_OR, 0), NULL_CODE));
1101 break;
1102 case Expr_Op_Type_BXOR:
1103 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_XOR, 0), NULL_CODE));
1104 break;
1105 case Expr_Op_Type_LAND:
1106 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LAND, 0), NULL_CODE));
1107 break;
1108 case Expr_Op_Type_LOR:
1109 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LOR, 0), NULL_CODE));
1110 break;
1111 default:
df3e8017 1112 fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
07c1b327
CM
1113
1114
1115 }
1116 break;
1117 case Expr_Node_Unop:
1118 note1 = conscode (Expr_Node_Gen_Reloc_R (head->Left_Child), NULL_CODE);
1119 switch (head->value.op_value)
1120 {
1121 case Expr_Op_Type_NEG:
1122 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_NEG, 0), NULL_CODE));
1123 break;
1124 case Expr_Op_Type_COMP:
1125 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_COMP, 0), NULL_CODE));
1126 break;
1127 default:
df3e8017 1128 fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
07c1b327
CM
1129 }
1130 break;
1131 default:
1132 fprintf (stderr, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__, __LINE__);
1133 }
1134 return note;
1135}
d55cb1c5 1136\f
07c1b327
CM
1137/* Blackfin opcode generation. */
1138
1139/* These functions are called by the generated parser
1140 (from bfin-parse.y), the register type classification
1141 happens in bfin-lex.l. */
1142
1143#include "bfin-aux.h"
1144#include "opcode/bfin.h"
1145
1146#define INIT(t) t c_code = init_##t
1147#define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
91d6fa6a 1148#define ASSIGNF(x,f) c_code.opcode |= ((x & c_code.mask_##f)<<c_code.bits_##f)
07c1b327
CM
1149#define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1150
1151#define HI(x) ((x >> 16) & 0xffff)
1152#define LO(x) ((x ) & 0xffff)
1153
1154#define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1155
1156#define GEN_OPCODE32() \
1157 conscode (gencode (HI (c_code.opcode)), \
1158 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1159
1160#define GEN_OPCODE16() \
1161 conscode (gencode (c_code.opcode), NULL_CODE)
1162
1163
1164/* 32 BIT INSTRUCTIONS. */
1165
1166
1167/* DSP32 instruction generation. */
1168
1169INSTR_T
1170bfin_gen_dsp32mac (int op1, int MM, int mmod, int w1, int P,
1171 int h01, int h11, int h00, int h10, int op0,
1172 REG_T dst, REG_T src0, REG_T src1, int w0)
1173{
1174 INIT (DSP32Mac);
1175
1176 ASSIGN (op0);
1177 ASSIGN (op1);
1178 ASSIGN (MM);
1179 ASSIGN (mmod);
1180 ASSIGN (w0);
1181 ASSIGN (w1);
1182 ASSIGN (h01);
1183 ASSIGN (h11);
1184 ASSIGN (h00);
1185 ASSIGN (h10);
1186 ASSIGN (P);
1187
1188 /* If we have full reg assignments, mask out LSB to encode
1189 single or simultaneous even/odd register moves. */
1190 if (P)
1191 {
1192 dst->regno &= 0x06;
1193 }
1194
1195 ASSIGN_R (dst);
1196 ASSIGN_R (src0);
1197 ASSIGN_R (src1);
1198
1199 return GEN_OPCODE32 ();
1200}
1201
1202INSTR_T
1203bfin_gen_dsp32mult (int op1, int MM, int mmod, int w1, int P,
1204 int h01, int h11, int h00, int h10, int op0,
1205 REG_T dst, REG_T src0, REG_T src1, int w0)
1206{
1207 INIT (DSP32Mult);
1208
1209 ASSIGN (op0);
1210 ASSIGN (op1);
1211 ASSIGN (MM);
1212 ASSIGN (mmod);
1213 ASSIGN (w0);
1214 ASSIGN (w1);
1215 ASSIGN (h01);
1216 ASSIGN (h11);
1217 ASSIGN (h00);
1218 ASSIGN (h10);
1219 ASSIGN (P);
1220
1221 if (P)
1222 {
1223 dst->regno &= 0x06;
1224 }
1225
1226 ASSIGN_R (dst);
1227 ASSIGN_R (src0);
1228 ASSIGN_R (src1);
1229
1230 return GEN_OPCODE32 ();
1231}
1232
1233INSTR_T
1234bfin_gen_dsp32alu (int HL, int aopcde, int aop, int s, int x,
1235 REG_T dst0, REG_T dst1, REG_T src0, REG_T src1)
1236{
1237 INIT (DSP32Alu);
1238
1239 ASSIGN (HL);
1240 ASSIGN (aopcde);
1241 ASSIGN (aop);
1242 ASSIGN (s);
1243 ASSIGN (x);
1244 ASSIGN_R (dst0);
1245 ASSIGN_R (dst1);
1246 ASSIGN_R (src0);
1247 ASSIGN_R (src1);
1248
1249 return GEN_OPCODE32 ();
1250}
1251
1252INSTR_T
1253bfin_gen_dsp32shift (int sopcde, REG_T dst0, REG_T src0,
1254 REG_T src1, int sop, int HLs)
1255{
1256 INIT (DSP32Shift);
1257
1258 ASSIGN (sopcde);
1259 ASSIGN (sop);
1260 ASSIGN (HLs);
1261
1262 ASSIGN_R (dst0);
1263 ASSIGN_R (src0);
1264 ASSIGN_R (src1);
1265
1266 return GEN_OPCODE32 ();
1267}
1268
1269INSTR_T
1270bfin_gen_dsp32shiftimm (int sopcde, REG_T dst0, int immag,
1271 REG_T src1, int sop, int HLs)
1272{
1273 INIT (DSP32ShiftImm);
1274
1275 ASSIGN (sopcde);
1276 ASSIGN (sop);
1277 ASSIGN (HLs);
1278
1279 ASSIGN_R (dst0);
1280 ASSIGN (immag);
1281 ASSIGN_R (src1);
1282
1283 return GEN_OPCODE32 ();
1284}
1285
1286/* LOOP SETUP. */
1287
1288INSTR_T
1289bfin_gen_loopsetup (Expr_Node * psoffset, REG_T c, int rop,
1290 Expr_Node * peoffset, REG_T reg)
1291{
1292 int soffset, eoffset;
1293 INIT (LoopSetup);
1294
1295 soffset = (EXPR_VALUE (psoffset) >> 1);
1296 ASSIGN (soffset);
1297 eoffset = (EXPR_VALUE (peoffset) >> 1);
1298 ASSIGN (eoffset);
1299 ASSIGN (rop);
1300 ASSIGN_R (c);
1301 ASSIGN_R (reg);
1302
1303 return
1304 conscode (gencode (HI (c_code.opcode)),
1305 conctcode (Expr_Node_Gen_Reloc (psoffset, BFD_RELOC_BFIN_5_PCREL),
1306 conctcode (gencode (LO (c_code.opcode)), Expr_Node_Gen_Reloc (peoffset, BFD_RELOC_BFIN_11_PCREL))));
1307
1308}
1309
1310/* Call, Link. */
1311
1312INSTR_T
1313bfin_gen_calla (Expr_Node * addr, int S)
1314{
1315 int val;
1316 int high_val;
91d6fa6a 1317 int rel = 0;
07c1b327
CM
1318 INIT (CALLa);
1319
1320 switch(S){
91d6fa6a
NC
1321 case 0 : rel = BFD_RELOC_BFIN_24_PCREL_JUMP_L; break;
1322 case 1 : rel = BFD_RELOC_24_PCREL; break;
1323 case 2 : rel = BFD_RELOC_BFIN_PLTPC; break;
07c1b327
CM
1324 default : break;
1325 }
1326
1327 ASSIGN (S);
1328
1329 val = EXPR_VALUE (addr) >> 1;
1330 high_val = val >> 16;
1331
1332 return conscode (gencode (HI (c_code.opcode) | (high_val & 0xff)),
91d6fa6a 1333 Expr_Node_Gen_Reloc (addr, rel));
07c1b327
CM
1334 }
1335
1336INSTR_T
1337bfin_gen_linkage (int R, int framesize)
1338{
1339 INIT (Linkage);
1340
1341 ASSIGN (R);
1342 ASSIGN (framesize);
1343
1344 return GEN_OPCODE32 ();
1345}
1346
1347
1348/* Load and Store. */
1349
1350INSTR_T
91d6fa6a 1351bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int rel)
07c1b327
CM
1352{
1353 int grp, hword;
1354 unsigned val = EXPR_VALUE (phword);
1355 INIT (LDIMMhalf);
1356
1357 ASSIGN (H);
1358 ASSIGN (S);
1359 ASSIGN (Z);
1360
1361 ASSIGN_R (reg);
1362 grp = (GROUP (reg));
1363 ASSIGN (grp);
91d6fa6a 1364 if (rel == 2)
07c1b327
CM
1365 {
1366 return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, BFD_RELOC_BFIN_16_IMM));
1367 }
91d6fa6a 1368 else if (rel == 1)
07c1b327
CM
1369 {
1370 return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, IS_H (*reg) ? BFD_RELOC_BFIN_16_HIGH : BFD_RELOC_BFIN_16_LOW));
1371 }
1372 else
1373 {
1374 hword = val;
1375 ASSIGN (hword);
1376 }
1377 return GEN_OPCODE32 ();
1378}
1379
1380INSTR_T
1381bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset)
1382{
07c1b327
CM
1383 INIT (LDSTidxI);
1384
1385 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1386 {
1387 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1388 return 0;
1389 }
1390
1391 ASSIGN_R (ptr);
1392 ASSIGN_R (reg);
1393 ASSIGN (W);
1394 ASSIGN (sz);
07c1b327
CM
1395
1396 ASSIGN (Z);
1397
1ac4baed
BS
1398 if (poffset->type != Expr_Node_Constant)
1399 {
1400 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1401 /* distinguish between R0 = [P5 + symbol@GOT] and
1402 P5 = [P5 + _current_shared_library_p5_offset_]
1403 */
1404 if (poffset->type == Expr_Node_Reloc
1405 && !strcmp (poffset->value.s_value,
1406 "_current_shared_library_p5_offset_"))
1407 {
1408 return conscode (gencode (HI (c_code.opcode)),
1409 Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16));
1410 }
1411 else if (poffset->type != Expr_Node_GOT_Reloc)
1412 abort ();
1413
1414 return conscode (gencode (HI (c_code.opcode)),
1415 Expr_Node_Gen_Reloc(poffset->Left_Child,
1416 poffset->value.i_value));
07c1b327 1417 }
1ac4baed 1418 else
07c1b327 1419 {
1ac4baed
BS
1420 int value, offset;
1421 switch (sz)
8fc4ee9b
AM
1422 { /* load/store access size */
1423 case 0: /* 32 bit */
1ac4baed
BS
1424 value = EXPR_VALUE (poffset) >> 2;
1425 break;
8fc4ee9b 1426 case 1: /* 16 bit */
1ac4baed
BS
1427 value = EXPR_VALUE (poffset) >> 1;
1428 break;
8fc4ee9b 1429 case 2: /* 8 bit */
1ac4baed
BS
1430 value = EXPR_VALUE (poffset);
1431 break;
1432 default:
1433 abort ();
1434 }
1435
1436 offset = (value & 0xffff);
1437 ASSIGN (offset);
1438 return GEN_OPCODE32 ();
07c1b327 1439 }
07c1b327
CM
1440}
1441
1442
1443INSTR_T
1444bfin_gen_ldst (REG_T ptr, REG_T reg, int aop, int sz, int Z, int W)
1445{
1446 INIT (LDST);
1447
1448 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1449 {
1450 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1451 return 0;
1452 }
1453
1454 ASSIGN_R (ptr);
1455 ASSIGN_R (reg);
1456 ASSIGN (aop);
1457 ASSIGN (sz);
1458 ASSIGN (Z);
1459 ASSIGN (W);
1460
1461 return GEN_OPCODE16 ();
1462}
1463
1464INSTR_T
91d6fa6a 1465bfin_gen_ldstii (REG_T ptr, REG_T reg, Expr_Node * poffset, int W, int opc)
07c1b327
CM
1466{
1467 int offset;
1468 int value = 0;
1469 INIT (LDSTii);
1470
07c1b327
CM
1471 if (!IS_PREG (*ptr))
1472 {
1473 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1474 return 0;
1475 }
1476
91d6fa6a 1477 switch (opc)
07c1b327
CM
1478 {
1479 case 1:
1480 case 2:
1481 value = EXPR_VALUE (poffset) >> 1;
1482 break;
1483 case 0:
1484 case 3:
1485 value = EXPR_VALUE (poffset) >> 2;
1486 break;
1487 }
1488
1489 ASSIGN_R (ptr);
1490 ASSIGN_R (reg);
1491
1492 offset = value;
1493 ASSIGN (offset);
1494 ASSIGN (W);
91d6fa6a 1495 ASSIGNF (opc, op);
07c1b327
CM
1496
1497 return GEN_OPCODE16 ();
1498}
1499
1500INSTR_T
1501bfin_gen_ldstiifp (REG_T sreg, Expr_Node * poffset, int W)
1502{
1503 /* Set bit 4 if it's a Preg. */
1504 int reg = (sreg->regno & CODE_MASK) | (IS_PREG (*sreg) ? 0x8 : 0x0);
1505 int offset = ((~(EXPR_VALUE (poffset) >> 2)) & 0x1f) + 1;
1506 INIT (LDSTiiFP);
1507 ASSIGN (reg);
1508 ASSIGN (offset);
1509 ASSIGN (W);
1510
1511 return GEN_OPCODE16 ();
1512}
1513
1514INSTR_T
1515bfin_gen_ldstpmod (REG_T ptr, REG_T reg, int aop, int W, REG_T idx)
1516{
1517 INIT (LDSTpmod);
1518
1519 ASSIGN_R (ptr);
1520 ASSIGN_R (reg);
1521 ASSIGN (aop);
1522 ASSIGN (W);
1523 ASSIGN_R (idx);
1524
1525 return GEN_OPCODE16 ();
1526}
1527
1528INSTR_T
1529bfin_gen_dspldst (REG_T i, REG_T reg, int aop, int W, int m)
1530{
1531 INIT (DspLDST);
1532
1533 ASSIGN_R (i);
1534 ASSIGN_R (reg);
1535 ASSIGN (aop);
1536 ASSIGN (W);
1537 ASSIGN (m);
1538
1539 return GEN_OPCODE16 ();
1540}
1541
1542INSTR_T
1543bfin_gen_logi2op (int opc, int src, int dst)
1544{
1545 INIT (LOGI2op);
1546
1547 ASSIGN (opc);
1548 ASSIGN (src);
1549 ASSIGN (dst);
1550
1551 return GEN_OPCODE16 ();
1552}
1553
1554INSTR_T
1555bfin_gen_brcc (int T, int B, Expr_Node * poffset)
1556{
1557 int offset;
1558 INIT (BRCC);
1559
1560 ASSIGN (T);
1561 ASSIGN (B);
1562 offset = ((EXPR_VALUE (poffset) >> 1));
1563 ASSIGN (offset);
1564 return conscode (gencode (c_code.opcode), Expr_Node_Gen_Reloc (poffset, BFD_RELOC_BFIN_10_PCREL));
1565}
1566
1567INSTR_T
1568bfin_gen_ujump (Expr_Node * poffset)
1569{
1570 int offset;
1571 INIT (UJump);
1572
1573 offset = ((EXPR_VALUE (poffset) >> 1));
1574 ASSIGN (offset);
1575
1576 return conscode (gencode (c_code.opcode),
1577 Expr_Node_Gen_Reloc (
1578 poffset, BFD_RELOC_BFIN_12_PCREL_JUMP_S));
1579}
1580
1581INSTR_T
1582bfin_gen_alu2op (REG_T dst, REG_T src, int opc)
1583{
1584 INIT (ALU2op);
1585
1586 ASSIGN_R (dst);
1587 ASSIGN_R (src);
1588 ASSIGN (opc);
1589
1590 return GEN_OPCODE16 ();
1591}
1592
1593INSTR_T
91d6fa6a 1594bfin_gen_compi2opd (REG_T dst, int src, int opc)
07c1b327
CM
1595{
1596 INIT (COMPI2opD);
1597
1598 ASSIGN_R (dst);
1599 ASSIGN (src);
91d6fa6a 1600 ASSIGNF (opc, op);
07c1b327
CM
1601
1602 return GEN_OPCODE16 ();
1603}
1604
1605INSTR_T
91d6fa6a 1606bfin_gen_compi2opp (REG_T dst, int src, int opc)
07c1b327
CM
1607{
1608 INIT (COMPI2opP);
1609
1610 ASSIGN_R (dst);
1611 ASSIGN (src);
91d6fa6a 1612 ASSIGNF (opc, op);
07c1b327
CM
1613
1614 return GEN_OPCODE16 ();
1615}
1616
1617INSTR_T
91d6fa6a 1618bfin_gen_dagmodik (REG_T i, int opc)
07c1b327
CM
1619{
1620 INIT (DagMODik);
1621
1622 ASSIGN_R (i);
91d6fa6a 1623 ASSIGNF (opc, op);
07c1b327
CM
1624
1625 return GEN_OPCODE16 ();
1626}
1627
1628INSTR_T
91d6fa6a 1629bfin_gen_dagmodim (REG_T i, REG_T m, int opc, int br)
07c1b327
CM
1630{
1631 INIT (DagMODim);
1632
1633 ASSIGN_R (i);
1634 ASSIGN_R (m);
91d6fa6a 1635 ASSIGNF (opc, op);
07c1b327
CM
1636 ASSIGN (br);
1637
1638 return GEN_OPCODE16 ();
1639}
1640
1641INSTR_T
1642bfin_gen_ptr2op (REG_T dst, REG_T src, int opc)
1643{
1644 INIT (PTR2op);
1645
1646 ASSIGN_R (dst);
1647 ASSIGN_R (src);
1648 ASSIGN (opc);
1649
1650 return GEN_OPCODE16 ();
1651}
1652
1653INSTR_T
1654bfin_gen_comp3op (REG_T src0, REG_T src1, REG_T dst, int opc)
1655{
1656 INIT (COMP3op);
1657
1658 ASSIGN_R (src0);
1659 ASSIGN_R (src1);
1660 ASSIGN_R (dst);
1661 ASSIGN (opc);
1662
1663 return GEN_OPCODE16 ();
1664}
1665
1666INSTR_T
1667bfin_gen_ccflag (REG_T x, int y, int opc, int I, int G)
1668{
1669 INIT (CCflag);
1670
1671 ASSIGN_R (x);
1672 ASSIGN (y);
1673 ASSIGN (opc);
1674 ASSIGN (I);
1675 ASSIGN (G);
1676
1677 return GEN_OPCODE16 ();
1678}
1679
1680INSTR_T
1681bfin_gen_ccmv (REG_T src, REG_T dst, int T)
1682{
1683 int s, d;
1684 INIT (CCmv);
1685
1686 ASSIGN_R (src);
1687 ASSIGN_R (dst);
1688 s = (GROUP (src));
1689 ASSIGN (s);
1690 d = (GROUP (dst));
1691 ASSIGN (d);
1692 ASSIGN (T);
1693
1694 return GEN_OPCODE16 ();
1695}
1696
1697INSTR_T
91d6fa6a 1698bfin_gen_cc2stat (int cbit, int opc, int D)
07c1b327
CM
1699{
1700 INIT (CC2stat);
1701
1702 ASSIGN (cbit);
91d6fa6a 1703 ASSIGNF (opc, op);
07c1b327
CM
1704 ASSIGN (D);
1705
1706 return GEN_OPCODE16 ();
1707}
1708
1709INSTR_T
1710bfin_gen_regmv (REG_T src, REG_T dst)
1711{
1712 int gs, gd;
1713 INIT (RegMv);
1714
1715 ASSIGN_R (src);
1716 ASSIGN_R (dst);
1717
1718 gs = (GROUP (src));
1719 ASSIGN (gs);
1720 gd = (GROUP (dst));
1721 ASSIGN (gd);
1722
1723 return GEN_OPCODE16 ();
1724}
1725
1726INSTR_T
91d6fa6a 1727bfin_gen_cc2dreg (int opc, REG_T reg)
07c1b327
CM
1728{
1729 INIT (CC2dreg);
1730
91d6fa6a 1731 ASSIGNF (opc, op);
07c1b327
CM
1732 ASSIGN_R (reg);
1733
1734 return GEN_OPCODE16 ();
1735}
1736
1737INSTR_T
1738bfin_gen_progctrl (int prgfunc, int poprnd)
1739{
1740 INIT (ProgCtrl);
1741
1742 ASSIGN (prgfunc);
1743 ASSIGN (poprnd);
1744
1745 return GEN_OPCODE16 ();
1746}
1747
1748INSTR_T
91d6fa6a 1749bfin_gen_cactrl (REG_T reg, int a, int opc)
07c1b327
CM
1750{
1751 INIT (CaCTRL);
1752
1753 ASSIGN_R (reg);
1754 ASSIGN (a);
91d6fa6a 1755 ASSIGNF (opc, op);
07c1b327
CM
1756
1757 return GEN_OPCODE16 ();
1758}
1759
1760INSTR_T
1761bfin_gen_pushpopmultiple (int dr, int pr, int d, int p, int W)
1762{
1763 INIT (PushPopMultiple);
1764
1765 ASSIGN (dr);
1766 ASSIGN (pr);
1767 ASSIGN (d);
1768 ASSIGN (p);
1769 ASSIGN (W);
1770
1771 return GEN_OPCODE16 ();
1772}
1773
1774INSTR_T
1775bfin_gen_pushpopreg (REG_T reg, int W)
1776{
1777 int grp;
1778 INIT (PushPopReg);
1779
1780 ASSIGN_R (reg);
1781 grp = (GROUP (reg));
1782 ASSIGN (grp);
1783 ASSIGN (W);
1784
1785 return GEN_OPCODE16 ();
1786}
1787
1788/* Pseudo Debugging Support. */
1789
1790INSTR_T
1791bfin_gen_pseudodbg (int fn, int reg, int grp)
1792{
1793 INIT (PseudoDbg);
1794
1795 ASSIGN (fn);
1796 ASSIGN (reg);
1797 ASSIGN (grp);
1798
1799 return GEN_OPCODE16 ();
1800}
1801
1802INSTR_T
1803bfin_gen_pseudodbg_assert (int dbgop, REG_T regtest, int expected)
1804{
66a6900a 1805 int grp;
07c1b327
CM
1806 INIT (PseudoDbg_Assert);
1807
1808 ASSIGN (dbgop);
1809 ASSIGN_R (regtest);
66a6900a
JZ
1810 grp = GROUP (regtest);
1811 ASSIGN (grp);
07c1b327
CM
1812 ASSIGN (expected);
1813
1814 return GEN_OPCODE32 ();
1815}
1816
73a63ccf
MF
1817INSTR_T
1818bfin_gen_pseudochr (int ch)
1819{
1820 INIT (PseudoChr);
1821
1822 ASSIGN (ch);
1823
1824 return GEN_OPCODE16 ();
1825}
1826
07c1b327
CM
1827/* Multiple instruction generation. */
1828
1829INSTR_T
1830bfin_gen_multi_instr (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2)
1831{
1832 INSTR_T walk;
1833
1834 /* If it's a 0, convert into MNOP. */
1835 if (dsp32)
1836 {
1837 walk = dsp32->next;
1838 SET_MULTI_INSTRUCTION_BIT (dsp32);
1839 }
1840 else
1841 {
1842 dsp32 = gencode (0xc803);
1843 walk = gencode (0x1800);
1844 dsp32->next = walk;
1845 }
1846
1847 if (!dsp16_grp1)
1848 {
1849 dsp16_grp1 = gencode (0x0000);
1850 }
1851
1852 if (!dsp16_grp2)
1853 {
1854 dsp16_grp2 = gencode (0x0000);
1855 }
1856
1857 walk->next = dsp16_grp1;
1858 dsp16_grp1->next = dsp16_grp2;
1859 dsp16_grp2->next = NULL_CODE;
1860
1861 return dsp32;
1862}
1863
1864INSTR_T
91d6fa6a 1865bfin_gen_loop (Expr_Node *exp, REG_T reg, int rop, REG_T preg)
07c1b327
CM
1866{
1867 const char *loopsym;
1868 char *lbeginsym, *lendsym;
1869 Expr_Node_Value lbeginval, lendval;
1870 Expr_Node *lbegin, *lend;
71ef6f79 1871 symbolS *sym;
07c1b327 1872
91d6fa6a 1873 loopsym = exp->value.s_value;
e2c038d3
BS
1874 lbeginsym = (char *) xmalloc (strlen (loopsym) + strlen ("__BEGIN") + 5);
1875 lendsym = (char *) xmalloc (strlen (loopsym) + strlen ("__END") + 5);
07c1b327
CM
1876
1877 lbeginsym[0] = 0;
1878 lendsym[0] = 0;
1879
e2c038d3 1880 strcat (lbeginsym, "L$L$");
07c1b327
CM
1881 strcat (lbeginsym, loopsym);
1882 strcat (lbeginsym, "__BEGIN");
1883
e2c038d3 1884 strcat (lendsym, "L$L$");
07c1b327
CM
1885 strcat (lendsym, loopsym);
1886 strcat (lendsym, "__END");
1887
1888 lbeginval.s_value = lbeginsym;
1889 lendval.s_value = lendsym;
1890
1891 lbegin = Expr_Node_Create (Expr_Node_Reloc, lbeginval, NULL, NULL);
1892 lend = Expr_Node_Create (Expr_Node_Reloc, lendval, NULL, NULL);
b4f42c96 1893
71ef6f79
MF
1894 sym = symbol_find(loopsym);
1895 if (!S_IS_LOCAL (sym) || (S_IS_LOCAL (sym) && !symbol_used_p (sym)))
1896 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
b4f42c96 1897
71ef6f79 1898 return bfin_gen_loopsetup (lbegin, reg, rop, lend, preg);
07c1b327
CM
1899}
1900
56640434
MF
1901void
1902bfin_loop_attempt_create_label (Expr_Node *exp, int is_begin)
1903{
1904 char *name;
1905 name = fb_label_name (exp->value.i_value, is_begin);
1906 exp->value.s_value = xstrdup (name);
1907 exp->type = Expr_Node_Reloc;
1908}
1909
d3a50e14 1910void
91d6fa6a 1911bfin_loop_beginend (Expr_Node *exp, int begin)
d3a50e14
JZ
1912{
1913 const char *loopsym;
1914 char *label_name;
91d6fa6a 1915 symbolS *linelabel;
d3a50e14
JZ
1916 const char *suffix = begin ? "__BEGIN" : "__END";
1917
91d6fa6a 1918 loopsym = exp->value.s_value;
d3a50e14
JZ
1919 label_name = (char *) xmalloc (strlen (loopsym) + strlen (suffix) + 5);
1920
1921 label_name[0] = 0;
1922
1923 strcat (label_name, "L$L$");
1924 strcat (label_name, loopsym);
1925 strcat (label_name, suffix);
1926
91d6fa6a 1927 linelabel = colon (label_name);
d3a50e14
JZ
1928
1929 /* LOOP_END follows the last instruction in the loop.
1930 Adjust label address. */
1931 if (!begin)
8d1015a8 1932 *symbol_X_add_number (linelabel) -= last_insn_size;
d3a50e14
JZ
1933}
1934
07c1b327
CM
1935bfd_boolean
1936bfin_eol_in_insn (char *line)
1937{
1938 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1939
1940 char *temp = line;
1941
1942 if (*line != '\n')
1943 return FALSE;
1944
1945 /* A semi-colon followed by a newline is always the end of a line. */
1946 if (line[-1] == ';')
1947 return FALSE;
1948
1949 if (line[-1] == '|')
1950 return TRUE;
1951
1952 /* If the || is on the next line, there might be leading whitespace. */
1953 temp++;
1954 while (*temp == ' ' || *temp == '\t') temp++;
1955
1956 if (*temp == '|')
1957 return TRUE;
1958
1959 return FALSE;
1960}
1961
07c1b327 1962bfd_boolean
2e57ce7b 1963bfin_start_label (char *s)
07c1b327 1964{
2e57ce7b 1965 while (*s != 0)
5e8c8f8f
JZ
1966 {
1967 if (*s == '(' || *s == '[')
1968 return FALSE;
1969 s++;
1970 }
07c1b327 1971
07c1b327 1972 return TRUE;
ee9e7c78 1973}
07c1b327
CM
1974
1975int
1976bfin_force_relocation (struct fix *fixp)
1977{
1978 if (fixp->fx_r_type ==BFD_RELOC_BFIN_16_LOW
1979 || fixp->fx_r_type == BFD_RELOC_BFIN_16_HIGH)
1980 return TRUE;
1981
1982 return generic_force_reloc (fixp);
1983}
d55cb1c5
BS
1984\f
1985/* This is a stripped down version of the disassembler. The only thing it
1986 does is return a mask of registers modified by an instruction. Only
1987 instructions that can occur in a parallel-issue bundle are handled, and
1988 only the registers that can cause a conflict are recorded. */
1989
1990#define DREG_MASK(n) (0x101 << (n))
1991#define DREGH_MASK(n) (0x100 << (n))
1992#define DREGL_MASK(n) (0x001 << (n))
1993#define IREG_MASK(n) (1 << ((n) + 16))
1994
1995static int
1996decode_ProgCtrl_0 (int iw0)
1997{
1998 if (iw0 == 0)
1999 return 0;
2000 abort ();
2001}
2002
2003static int
2004decode_LDSTpmod_0 (int iw0)
2005{
2006 /* LDSTpmod
2007 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2008 | 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......|
2009 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2010 int W = ((iw0 >> LDSTpmod_W_bits) & LDSTpmod_W_mask);
2011 int aop = ((iw0 >> LDSTpmod_aop_bits) & LDSTpmod_aop_mask);
2012 int idx = ((iw0 >> LDSTpmod_idx_bits) & LDSTpmod_idx_mask);
2013 int ptr = ((iw0 >> LDSTpmod_ptr_bits) & LDSTpmod_ptr_mask);
2014 int reg = ((iw0 >> LDSTpmod_reg_bits) & LDSTpmod_reg_mask);
2015
2016 if (aop == 1 && W == 0 && idx == ptr)
2017 return DREGL_MASK (reg);
2018 else if (aop == 2 && W == 0 && idx == ptr)
2019 return DREGH_MASK (reg);
2020 else if (aop == 1 && W == 1 && idx == ptr)
2021 return 0;
2022 else if (aop == 2 && W == 1 && idx == ptr)
2023 return 0;
2024 else if (aop == 0 && W == 0)
2025 return DREG_MASK (reg);
2026 else if (aop == 1 && W == 0)
2027 return DREGL_MASK (reg);
2028 else if (aop == 2 && W == 0)
2029 return DREGH_MASK (reg);
2030 else if (aop == 3 && W == 0)
2031 return DREG_MASK (reg);
2032 else if (aop == 3 && W == 1)
2033 return DREG_MASK (reg);
2034 else if (aop == 0 && W == 1)
2035 return 0;
2036 else if (aop == 1 && W == 1)
2037 return 0;
2038 else if (aop == 2 && W == 1)
2039 return 0;
2040 else
2041 return 0;
2042
2043 return 2;
2044}
2045
2046static int
2047decode_dagMODim_0 (int iw0)
2048{
2049 /* dagMODim
2050 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2051 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....|
2052 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2053 int i = ((iw0 >> DagMODim_i_bits) & DagMODim_i_mask);
91d6fa6a 2054 int opc = ((iw0 >> DagMODim_op_bits) & DagMODim_op_mask);
d55cb1c5 2055
91d6fa6a 2056 if (opc == 0 || opc == 1)
d55cb1c5
BS
2057 return IREG_MASK (i);
2058 else
2059 return 0;
2060
2061 return 2;
2062}
2063
2064static int
2065decode_dagMODik_0 (int iw0)
2066{
2067 /* dagMODik
2068 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2069 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....|
2070 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2071 int i = ((iw0 >> DagMODik_i_bits) & DagMODik_i_mask);
2072 return IREG_MASK (i);
2073}
2074
2075/* GOOD */
2076static int
2077decode_dspLDST_0 (int iw0)
2078{
2079 /* dspLDST
2080 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2081 | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......|
2082 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2083 int i = ((iw0 >> DspLDST_i_bits) & DspLDST_i_mask);
2084 int m = ((iw0 >> DspLDST_m_bits) & DspLDST_m_mask);
2085 int W = ((iw0 >> DspLDST_W_bits) & DspLDST_W_mask);
2086 int aop = ((iw0 >> DspLDST_aop_bits) & DspLDST_aop_mask);
2087 int reg = ((iw0 >> DspLDST_reg_bits) & DspLDST_reg_mask);
2088
2089 if (aop == 0 && W == 0 && m == 0)
2090 return DREG_MASK (reg) | IREG_MASK (i);
2091 else if (aop == 0 && W == 0 && m == 1)
2092 return DREGL_MASK (reg) | IREG_MASK (i);
2093 else if (aop == 0 && W == 0 && m == 2)
2094 return DREGH_MASK (reg) | IREG_MASK (i);
2095 else if (aop == 1 && W == 0 && m == 0)
2096 return DREG_MASK (reg) | IREG_MASK (i);
2097 else if (aop == 1 && W == 0 && m == 1)
2098 return DREGL_MASK (reg) | IREG_MASK (i);
2099 else if (aop == 1 && W == 0 && m == 2)
2100 return DREGH_MASK (reg) | IREG_MASK (i);
2101 else if (aop == 2 && W == 0 && m == 0)
2102 return DREG_MASK (reg);
2103 else if (aop == 2 && W == 0 && m == 1)
2104 return DREGL_MASK (reg);
2105 else if (aop == 2 && W == 0 && m == 2)
2106 return DREGH_MASK (reg);
2107 else if (aop == 0 && W == 1 && m == 0)
2108 return IREG_MASK (i);
2109 else if (aop == 0 && W == 1 && m == 1)
2110 return IREG_MASK (i);
2111 else if (aop == 0 && W == 1 && m == 2)
2112 return IREG_MASK (i);
2113 else if (aop == 1 && W == 1 && m == 0)
2114 return IREG_MASK (i);
2115 else if (aop == 1 && W == 1 && m == 1)
2116 return IREG_MASK (i);
2117 else if (aop == 1 && W == 1 && m == 2)
2118 return IREG_MASK (i);
2119 else if (aop == 2 && W == 1 && m == 0)
2120 return 0;
2121 else if (aop == 2 && W == 1 && m == 1)
2122 return 0;
2123 else if (aop == 2 && W == 1 && m == 2)
2124 return 0;
2125 else if (aop == 3 && W == 0)
2126 return DREG_MASK (reg) | IREG_MASK (i);
2127 else if (aop == 3 && W == 1)
2128 return IREG_MASK (i);
2129
2130 abort ();
2131}
2132
2133/* GOOD */
2134static int
2135decode_LDST_0 (int iw0)
2136{
2137 /* LDST
2138 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2139 | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......|
2140 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2141 int Z = ((iw0 >> LDST_Z_bits) & LDST_Z_mask);
2142 int W = ((iw0 >> LDST_W_bits) & LDST_W_mask);
2143 int sz = ((iw0 >> LDST_sz_bits) & LDST_sz_mask);
2144 int aop = ((iw0 >> LDST_aop_bits) & LDST_aop_mask);
2145 int reg = ((iw0 >> LDST_reg_bits) & LDST_reg_mask);
2146
2147 if (aop == 0 && sz == 0 && Z == 0 && W == 0)
2148 return DREG_MASK (reg);
2149 else if (aop == 0 && sz == 0 && Z == 1 && W == 0)
2150 return 0;
2151 else if (aop == 0 && sz == 1 && Z == 0 && W == 0)
2152 return DREG_MASK (reg);
2153 else if (aop == 0 && sz == 1 && Z == 1 && W == 0)
2154 return DREG_MASK (reg);
2155 else if (aop == 0 && sz == 2 && Z == 0 && W == 0)
2156 return DREG_MASK (reg);
2157 else if (aop == 0 && sz == 2 && Z == 1 && W == 0)
2158 return DREG_MASK (reg);
2159 else if (aop == 1 && sz == 0 && Z == 0 && W == 0)
2160 return DREG_MASK (reg);
2161 else if (aop == 1 && sz == 0 && Z == 1 && W == 0)
2162 return 0;
2163 else if (aop == 1 && sz == 1 && Z == 0 && W == 0)
2164 return DREG_MASK (reg);
2165 else if (aop == 1 && sz == 1 && Z == 1 && W == 0)
2166 return DREG_MASK (reg);
2167 else if (aop == 1 && sz == 2 && Z == 0 && W == 0)
2168 return DREG_MASK (reg);
2169 else if (aop == 1 && sz == 2 && Z == 1 && W == 0)
2170 return DREG_MASK (reg);
2171 else if (aop == 2 && sz == 0 && Z == 0 && W == 0)
2172 return DREG_MASK (reg);
2173 else if (aop == 2 && sz == 0 && Z == 1 && W == 0)
2174 return 0;
2175 else if (aop == 2 && sz == 1 && Z == 0 && W == 0)
2176 return DREG_MASK (reg);
2177 else if (aop == 2 && sz == 1 && Z == 1 && W == 0)
2178 return DREG_MASK (reg);
2179 else if (aop == 2 && sz == 2 && Z == 0 && W == 0)
2180 return DREG_MASK (reg);
2181 else if (aop == 2 && sz == 2 && Z == 1 && W == 0)
2182 return DREG_MASK (reg);
2183 else if (aop == 0 && sz == 0 && Z == 0 && W == 1)
2184 return 0;
2185 else if (aop == 0 && sz == 0 && Z == 1 && W == 1)
2186 return 0;
2187 else if (aop == 0 && sz == 1 && Z == 0 && W == 1)
2188 return 0;
2189 else if (aop == 0 && sz == 2 && Z == 0 && W == 1)
2190 return 0;
2191 else if (aop == 1 && sz == 0 && Z == 0 && W == 1)
2192 return 0;
2193 else if (aop == 1 && sz == 0 && Z == 1 && W == 1)
2194 return 0;
2195 else if (aop == 1 && sz == 1 && Z == 0 && W == 1)
2196 return 0;
2197 else if (aop == 1 && sz == 2 && Z == 0 && W == 1)
2198 return 0;
2199 else if (aop == 2 && sz == 0 && Z == 0 && W == 1)
2200 return 0;
2201 else if (aop == 2 && sz == 0 && Z == 1 && W == 1)
2202 return 0;
2203 else if (aop == 2 && sz == 1 && Z == 0 && W == 1)
2204 return 0;
2205 else if (aop == 2 && sz == 2 && Z == 0 && W == 1)
2206 return 0;
2207
2208 abort ();
2209}
2210
2211static int
2212decode_LDSTiiFP_0 (int iw0)
2213{
2214 /* LDSTiiFP
2215 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2216 | 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........|
2217 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2218 int reg = ((iw0 >> LDSTiiFP_reg_bits) & LDSTiiFP_reg_mask);
2219 int W = ((iw0 >> LDSTiiFP_W_bits) & LDSTiiFP_W_mask);
2220
2221 if (W == 0)
2222 return reg < 8 ? DREG_MASK (reg) : 0;
2223 else
2224 return 0;
2225}
2226
2227static int
2228decode_LDSTii_0 (int iw0)
2229{
2230 /* LDSTii
2231 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2232 | 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......|
2233 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2234 int reg = ((iw0 >> LDSTii_reg_bit) & LDSTii_reg_mask);
91d6fa6a 2235 int opc = ((iw0 >> LDSTii_op_bit) & LDSTii_op_mask);
d55cb1c5
BS
2236 int W = ((iw0 >> LDSTii_W_bit) & LDSTii_W_mask);
2237
91d6fa6a 2238 if (W == 0 && opc != 3)
d55cb1c5 2239 return DREG_MASK (reg);
91d6fa6a 2240 else if (W == 0 && opc == 3)
d55cb1c5 2241 return 0;
91d6fa6a 2242 else if (W == 1 && opc == 0)
d55cb1c5 2243 return 0;
91d6fa6a 2244 else if (W == 1 && opc == 1)
d55cb1c5 2245 return 0;
91d6fa6a 2246 else if (W == 1 && opc == 3)
d55cb1c5
BS
2247 return 0;
2248
2249 abort ();
2250}
2251
2252static int
2253decode_dsp32mac_0 (int iw0, int iw1)
2254{
2255 int result = 0;
2256 /* dsp32mac
2257 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2258 | 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...|
2259 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2260 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2261 int op1 = ((iw0 >> (DSP32Mac_op1_bits - 16)) & DSP32Mac_op1_mask);
2262 int w1 = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask);
2263 int P = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask);
2264 int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask);
2265 int w0 = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask);
2266 int MM = ((iw1 >> DSP32Mac_MM_bits) & DSP32Mac_MM_mask);
2267 int dst = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask);
2268 int op0 = ((iw1 >> DSP32Mac_op0_bits) & DSP32Mac_op0_mask);
2269
2270 if (w0 == 0 && w1 == 0 && op1 == 3 && op0 == 3)
2271 return 0;
2272
2273 if (op1 == 3 && MM)
2274 return 0;
2275
2276 if ((w1 || w0) && mmod == M_W32)
2277 return 0;
2278
2279 if (((1 << mmod) & (P ? 0x131b : 0x1b5f)) == 0)
2280 return 0;
2281
2282 if (w1 == 1 || op1 != 3)
2283 {
2284 if (w1)
2285 {
2286 if (P)
2287 return DREG_MASK (dst + 1);
2288 else
2289 return DREGH_MASK (dst);
2290 }
2291 }
2292
2293 if (w0 == 1 || op0 != 3)
2294 {
2295 if (w0)
2296 {
2297 if (P)
2298 return DREG_MASK (dst);
2299 else
2300 return DREGL_MASK (dst);
2301 }
2302 }
2303
2304 return result;
2305}
2306
2307static int
2308decode_dsp32mult_0 (int iw0, int iw1)
2309{
2310 /* dsp32mult
2311 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2312 | 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...|
2313 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2314 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2315 int w1 = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask);
2316 int P = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask);
2317 int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask);
2318 int w0 = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask);
2319 int dst = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask);
2320 int result = 0;
2321
2322 if (w1 == 0 && w0 == 0)
2323 return 0;
2324
2325 if (((1 << mmod) & (P ? 0x313 : 0x1b57)) == 0)
2326 return 0;
2327
2328 if (w1)
2329 {
2330 if (P)
2331 return DREG_MASK (dst | 1);
2332 else
2333 return DREGH_MASK (dst);
2334 }
2335
2336 if (w0)
2337 {
2338 if (P)
2339 return DREG_MASK (dst);
2340 else
2341 return DREGL_MASK (dst);
2342 }
2343
2344 return result;
2345}
2346
2347static int
2348decode_dsp32alu_0 (int iw0, int iw1)
2349{
2350 /* dsp32alu
2351 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2352 | 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............|
2353 |.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......|
2354 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2355 int s = ((iw1 >> DSP32Alu_s_bits) & DSP32Alu_s_mask);
2356 int x = ((iw1 >> DSP32Alu_x_bits) & DSP32Alu_x_mask);
2357 int aop = ((iw1 >> DSP32Alu_aop_bits) & DSP32Alu_aop_mask);
2358 int dst0 = ((iw1 >> DSP32Alu_dst0_bits) & DSP32Alu_dst0_mask);
2359 int dst1 = ((iw1 >> DSP32Alu_dst1_bits) & DSP32Alu_dst1_mask);
2360 int HL = ((iw0 >> (DSP32Alu_HL_bits - 16)) & DSP32Alu_HL_mask);
2361 int aopcde = ((iw0 >> (DSP32Alu_aopcde_bits - 16)) & DSP32Alu_aopcde_mask);
2362
2363 if (aop == 0 && aopcde == 9 && s == 0)
2364 return 0;
2365 else if (aop == 2 && aopcde == 9 && HL == 0 && s == 0)
2366 return 0;
2367 else if (aop >= x * 2 && aopcde == 5)
2368 return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2369 else if (HL == 0 && aopcde == 2)
2370 return DREGL_MASK (dst0);
2371 else if (HL == 1 && aopcde == 2)
2372 return DREGH_MASK (dst0);
2373 else if (HL == 0 && aopcde == 3)
2374 return DREGL_MASK (dst0);
2375 else if (HL == 1 && aopcde == 3)
2376 return DREGH_MASK (dst0);
2377
2378 else if (aop == 0 && aopcde == 9 && s == 1)
2379 return 0;
2380 else if (aop == 1 && aopcde == 9 && s == 0)
2381 return 0;
2382 else if (aop == 2 && aopcde == 9 && s == 1)
2383 return 0;
2384 else if (aop == 3 && aopcde == 9 && s == 0)
2385 return 0;
2386 else if (aopcde == 8)
2387 return 0;
2388 else if (aop == 0 && aopcde == 11)
2389 return DREG_MASK (dst0);
2390 else if (aop == 1 && aopcde == 11)
2391 return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2392 else if (aopcde == 11)
2393 return 0;
2394 else if (aopcde == 22)
2395 return DREG_MASK (dst0);
2396
2397 else if ((aop == 0 || aop == 1) && aopcde == 14)
2398 return 0;
2399 else if (aop == 3 && HL == 0 && aopcde == 14)
2400 return 0;
2401
2402 else if (aop == 3 && HL == 0 && aopcde == 15)
2403 return DREG_MASK (dst0);
2404
2405 else if (aop == 1 && aopcde == 16)
2406 return 0;
2407
2408 else if (aop == 0 && aopcde == 16)
2409 return 0;
2410
2411 else if (aop == 3 && HL == 0 && aopcde == 16)
2412 return 0;
2413
2414 else if (aop == 3 && HL == 0 && aopcde == 7)
2415 return DREG_MASK (dst0);
2416 else if ((aop == 0 || aop == 1 || aop == 2) && aopcde == 7)
2417 return DREG_MASK (dst0);
2418
2419 else if (aop == 0 && aopcde == 12)
2420 return DREG_MASK (dst0);
2421 else if (aop == 1 && aopcde == 12)
2422 return DREG_MASK (dst0) | DREG_MASK (dst1);
2423 else if (aop == 3 && aopcde == 12)
2424 return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2425
2426 else if (aopcde == 0)
2427 return DREG_MASK (dst0);
2428 else if (aopcde == 1)
2429 return DREG_MASK (dst0) | DREG_MASK (dst1);
2430
2431 else if (aop == 0 && aopcde == 10)
2432 return DREGL_MASK (dst0);
2433 else if (aop == 1 && aopcde == 10)
2434 return DREGL_MASK (dst0);
2435
2436 else if ((aop == 1 || aop == 0) && aopcde == 4)
2437 return DREG_MASK (dst0);
2438 else if (aop == 2 && aopcde == 4)
2439 return DREG_MASK (dst0) | DREG_MASK (dst1);
2440
2441 else if (aop == 0 && aopcde == 17)
2442 return DREG_MASK (dst0) | DREG_MASK (dst1);
2443 else if (aop == 1 && aopcde == 17)
2444 return DREG_MASK (dst0) | DREG_MASK (dst1);
2445 else if (aop == 0 && aopcde == 18)
2446 return 0;
2447 else if (aop == 3 && aopcde == 18)
2448 return 0;
2449
2450 else if ((aop == 0 || aop == 1 || aop == 2) && aopcde == 6)
2451 return DREG_MASK (dst0);
2452
2453 else if ((aop == 0 || aop == 1) && aopcde == 20)
2454 return DREG_MASK (dst0);
2455
2456 else if ((aop == 0 || aop == 1) && aopcde == 21)
2457 return DREG_MASK (dst0) | DREG_MASK (dst1);
2458
2459 else if (aop == 0 && aopcde == 23 && HL == 1)
2460 return DREG_MASK (dst0);
2461 else if (aop == 0 && aopcde == 23 && HL == 0)
2462 return DREG_MASK (dst0);
2463
2464 else if (aop == 0 && aopcde == 24)
2465 return DREG_MASK (dst0);
ee9e7c78 2466 else if (aop == 1 && aopcde == 24)
d55cb1c5
BS
2467 return DREG_MASK (dst0) | DREG_MASK (dst1);
2468 else if (aopcde == 13)
2469 return DREG_MASK (dst0) | DREG_MASK (dst1);
2470 else
2471 return 0;
2472
2473 return 4;
2474}
2475
2476static int
2477decode_dsp32shift_0 (int iw0, int iw1)
2478{
2479 /* dsp32shift
2480 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2481 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............|
2482 |.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......|
2483 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2484 int HLs = ((iw1 >> DSP32Shift_HLs_bits) & DSP32Shift_HLs_mask);
2485 int sop = ((iw1 >> DSP32Shift_sop_bits) & DSP32Shift_sop_mask);
2486 int src0 = ((iw1 >> DSP32Shift_src0_bits) & DSP32Shift_src0_mask);
2487 int src1 = ((iw1 >> DSP32Shift_src1_bits) & DSP32Shift_src1_mask);
2488 int dst0 = ((iw1 >> DSP32Shift_dst0_bits) & DSP32Shift_dst0_mask);
2489 int sopcde = ((iw0 >> (DSP32Shift_sopcde_bits - 16)) & DSP32Shift_sopcde_mask);
2490
2491 if (sop == 0 && sopcde == 0)
2492 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2493 else if (sop == 1 && sopcde == 0)
2494 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2495 else if (sop == 2 && sopcde == 0)
2496 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2497 else if (sop == 0 && sopcde == 3)
2498 return 0;
2499 else if (sop == 1 && sopcde == 3)
2500 return 0;
2501 else if (sop == 2 && sopcde == 3)
2502 return 0;
2503 else if (sop == 3 && sopcde == 3)
2504 return DREG_MASK (dst0);
2505 else if (sop == 0 && sopcde == 1)
2506 return DREG_MASK (dst0);
2507 else if (sop == 1 && sopcde == 1)
2508 return DREG_MASK (dst0);
2509 else if (sop == 2 && sopcde == 1)
2510 return DREG_MASK (dst0);
2511 else if (sopcde == 2)
2512 return DREG_MASK (dst0);
2513 else if (sopcde == 4)
2514 return DREG_MASK (dst0);
2515 else if (sop == 0 && sopcde == 5)
2516 return DREGL_MASK (dst0);
2517 else if (sop == 1 && sopcde == 5)
2518 return DREGL_MASK (dst0);
2519 else if (sop == 2 && sopcde == 5)
2520 return DREGL_MASK (dst0);
2521 else if (sop == 0 && sopcde == 6)
2522 return DREGL_MASK (dst0);
2523 else if (sop == 1 && sopcde == 6)
2524 return DREGL_MASK (dst0);
2525 else if (sop == 3 && sopcde == 6)
2526 return DREGL_MASK (dst0);
2527 else if (sop == 0 && sopcde == 7)
2528 return DREGL_MASK (dst0);
2529 else if (sop == 1 && sopcde == 7)
2530 return DREGL_MASK (dst0);
2531 else if (sop == 2 && sopcde == 7)
2532 return DREGL_MASK (dst0);
2533 else if (sop == 3 && sopcde == 7)
2534 return DREGL_MASK (dst0);
2535 else if (sop == 0 && sopcde == 8)
2536 return DREG_MASK (src0) | DREG_MASK (src1);
2537#if 0
2538 {
2539 OUTS (outf, "BITMUX (");
2540 OUTS (outf, dregs (src0));
2541 OUTS (outf, ", ");
2542 OUTS (outf, dregs (src1));
2543 OUTS (outf, ", A0) (ASR)");
2544 }
2545#endif
2546 else if (sop == 1 && sopcde == 8)
2547 return DREG_MASK (src0) | DREG_MASK (src1);
2548#if 0
2549 {
2550 OUTS (outf, "BITMUX (");
2551 OUTS (outf, dregs (src0));
2552 OUTS (outf, ", ");
2553 OUTS (outf, dregs (src1));
2554 OUTS (outf, ", A0) (ASL)");
2555 }
2556#endif
2557 else if (sopcde == 9)
2558 return sop < 2 ? DREGL_MASK (dst0) : DREG_MASK (dst0);
2559 else if (sopcde == 10)
2560 return DREG_MASK (dst0);
2561 else if (sop == 0 && sopcde == 11)
2562 return DREGL_MASK (dst0);
2563 else if (sop == 1 && sopcde == 11)
2564 return DREGL_MASK (dst0);
2565 else if (sop == 0 && sopcde == 12)
2566 return 0;
2567 else if (sop == 1 && sopcde == 12)
2568 return DREGL_MASK (dst0);
2569 else if (sop == 0 && sopcde == 13)
2570 return DREG_MASK (dst0);
2571 else if (sop == 1 && sopcde == 13)
2572 return DREG_MASK (dst0);
2573 else if (sop == 2 && sopcde == 13)
2574 return DREG_MASK (dst0);
2575
2576 abort ();
2577}
2578
2579static int
2580decode_dsp32shiftimm_0 (int iw0, int iw1)
2581{
2582 /* dsp32shiftimm
2583 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2584 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............|
2585 |.sop...|.HLs...|.dst0......|.immag.................|.src1......|
2586 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2587 int sop = ((iw1 >> DSP32ShiftImm_sop_bits) & DSP32ShiftImm_sop_mask);
2588 int bit8 = ((iw1 >> 8) & 0x1);
2589 int dst0 = ((iw1 >> DSP32ShiftImm_dst0_bits) & DSP32ShiftImm_dst0_mask);
2590 int sopcde = ((iw0 >> (DSP32ShiftImm_sopcde_bits - 16)) & DSP32ShiftImm_sopcde_mask);
2591 int HLs = ((iw1 >> DSP32ShiftImm_HLs_bits) & DSP32ShiftImm_HLs_mask);
2592
2593
2594 if (sop == 0 && sopcde == 0)
2595 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2596 else if (sop == 1 && sopcde == 0 && bit8 == 0)
2597 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2598 else if (sop == 1 && sopcde == 0 && bit8 == 1)
2599 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2600 else if (sop == 2 && sopcde == 0 && bit8 == 0)
2601 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2602 else if (sop == 2 && sopcde == 0 && bit8 == 1)
2603 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2604 else if (sop == 2 && sopcde == 3 && HLs == 1)
2605 return 0;
2606 else if (sop == 0 && sopcde == 3 && HLs == 0 && bit8 == 0)
2607 return 0;
2608 else if (sop == 0 && sopcde == 3 && HLs == 0 && bit8 == 1)
2609 return 0;
2610 else if (sop == 0 && sopcde == 3 && HLs == 1 && bit8 == 0)
2611 return 0;
2612 else if (sop == 0 && sopcde == 3 && HLs == 1 && bit8 == 1)
2613 return 0;
2614 else if (sop == 1 && sopcde == 3 && HLs == 0)
2615 return 0;
2616 else if (sop == 1 && sopcde == 3 && HLs == 1)
2617 return 0;
2618 else if (sop == 2 && sopcde == 3 && HLs == 0)
2619 return 0;
2620 else if (sop == 1 && sopcde == 1 && bit8 == 0)
2621 return DREG_MASK (dst0);
2622 else if (sop == 1 && sopcde == 1 && bit8 == 1)
2623 return DREG_MASK (dst0);
2624 else if (sop == 2 && sopcde == 1 && bit8 == 1)
2625 return DREG_MASK (dst0);
2626 else if (sop == 2 && sopcde == 1 && bit8 == 0)
2627 return DREG_MASK (dst0);
2628 else if (sop == 0 && sopcde == 1)
2629 return DREG_MASK (dst0);
2630 else if (sop == 1 && sopcde == 2)
2631 return DREG_MASK (dst0);
2632 else if (sop == 2 && sopcde == 2 && bit8 == 1)
2633 return DREG_MASK (dst0);
2634 else if (sop == 2 && sopcde == 2 && bit8 == 0)
2635 return DREG_MASK (dst0);
2636 else if (sop == 3 && sopcde == 2)
2637 return DREG_MASK (dst0);
2638 else if (sop == 0 && sopcde == 2)
2639 return DREG_MASK (dst0);
2640
2641 abort ();
2642}
2643
2644int
2645insn_regmask (int iw0, int iw1)
2646{
2647 if ((iw0 & 0xf7ff) == 0xc003 && iw1 == 0x1800)
2648 return 0; /* MNOP */
2649 else if ((iw0 & 0xff00) == 0x0000)
2650 return decode_ProgCtrl_0 (iw0);
2651 else if ((iw0 & 0xffc0) == 0x0240)
2652 abort ();
2653 else if ((iw0 & 0xff80) == 0x0100)
2654 abort ();
2655 else if ((iw0 & 0xfe00) == 0x0400)
2656 abort ();
2657 else if ((iw0 & 0xfe00) == 0x0600)
2658 abort ();
2659 else if ((iw0 & 0xf800) == 0x0800)
2660 abort ();
2661 else if ((iw0 & 0xffe0) == 0x0200)
2662 abort ();
2663 else if ((iw0 & 0xff00) == 0x0300)
2664 abort ();
2665 else if ((iw0 & 0xf000) == 0x1000)
2666 abort ();
2667 else if ((iw0 & 0xf000) == 0x2000)
2668 abort ();
2669 else if ((iw0 & 0xf000) == 0x3000)
2670 abort ();
2671 else if ((iw0 & 0xfc00) == 0x4000)
2672 abort ();
2673 else if ((iw0 & 0xfe00) == 0x4400)
2674 abort ();
2675 else if ((iw0 & 0xf800) == 0x4800)
2676 abort ();
2677 else if ((iw0 & 0xf000) == 0x5000)
2678 abort ();
2679 else if ((iw0 & 0xf800) == 0x6000)
2680 abort ();
2681 else if ((iw0 & 0xf800) == 0x6800)
2682 abort ();
2683 else if ((iw0 & 0xf000) == 0x8000)
2684 return decode_LDSTpmod_0 (iw0);
2685 else if ((iw0 & 0xff60) == 0x9e60)
2686 return decode_dagMODim_0 (iw0);
2687 else if ((iw0 & 0xfff0) == 0x9f60)
2688 return decode_dagMODik_0 (iw0);
2689 else if ((iw0 & 0xfc00) == 0x9c00)
2690 return decode_dspLDST_0 (iw0);
2691 else if ((iw0 & 0xf000) == 0x9000)
2692 return decode_LDST_0 (iw0);
2693 else if ((iw0 & 0xfc00) == 0xb800)
2694 return decode_LDSTiiFP_0 (iw0);
2695 else if ((iw0 & 0xe000) == 0xA000)
2696 return decode_LDSTii_0 (iw0);
2697 else if ((iw0 & 0xff80) == 0xe080 && (iw1 & 0x0C00) == 0x0000)
2698 abort ();
2699 else if ((iw0 & 0xff00) == 0xe100 && (iw1 & 0x0000) == 0x0000)
2700 abort ();
2701 else if ((iw0 & 0xfe00) == 0xe200 && (iw1 & 0x0000) == 0x0000)
2702 abort ();
2703 else if ((iw0 & 0xfc00) == 0xe400 && (iw1 & 0x0000) == 0x0000)
2704 abort ();
2705 else if ((iw0 & 0xfffe) == 0xe800 && (iw1 & 0x0000) == 0x0000)
2706 abort ();
2707 else if ((iw0 & 0xf600) == 0xc000 && (iw1 & 0x0000) == 0x0000)
2708 return decode_dsp32mac_0 (iw0, iw1);
2709 else if ((iw0 & 0xf600) == 0xc200 && (iw1 & 0x0000) == 0x0000)
2710 return decode_dsp32mult_0 (iw0, iw1);
2711 else if ((iw0 & 0xf7c0) == 0xc400 && (iw1 & 0x0000) == 0x0000)
2712 return decode_dsp32alu_0 (iw0, iw1);
2713 else if ((iw0 & 0xf780) == 0xc600 && (iw1 & 0x01c0) == 0x0000)
2714 return decode_dsp32shift_0 (iw0, iw1);
2715 else if ((iw0 & 0xf780) == 0xc680 && (iw1 & 0x0000) == 0x0000)
2716 return decode_dsp32shiftimm_0 (iw0, iw1);
2717 else if ((iw0 & 0xff00) == 0xf800)
2718 abort ();
2719 else if ((iw0 & 0xFFC0) == 0xf000 && (iw1 & 0x0000) == 0x0000)
2720 abort ();
2721
2722 abort ();
2723}