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