]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-bfin.c
* ld-mmix/sec-3.d: Adjust for 2010-09-29 orphan change.
[thirdparty/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
289 {"bf542", BFIN_CPU_BF542, 0x0002, AC_05000074},
290 {"bf542", BFIN_CPU_BF542, 0x0001, AC_05000074},
291 {"bf542", BFIN_CPU_BF542, 0x0000, AC_05000074},
292
293 {"bf544m", BFIN_CPU_BF544M, 0x0003, AC_05000074},
294
295 {"bf544", BFIN_CPU_BF544, 0x0002, AC_05000074},
296 {"bf544", BFIN_CPU_BF544, 0x0001, AC_05000074},
297 {"bf544", BFIN_CPU_BF544, 0x0000, AC_05000074},
298
299 {"bf547m", BFIN_CPU_BF547M, 0x0003, AC_05000074},
300
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
307 {"bf548", BFIN_CPU_BF548, 0x0002, AC_05000074},
308 {"bf548", BFIN_CPU_BF548, 0x0001, AC_05000074},
309 {"bf548", BFIN_CPU_BF548, 0x0000, AC_05000074},
310
311 {"bf549m", BFIN_CPU_BF549M, 0x0003, AC_05000074},
312
313 {"bf549", BFIN_CPU_BF549, 0x0002, AC_05000074},
314 {"bf549", BFIN_CPU_BF549, 0x0001, AC_05000074},
315 {"bf549", BFIN_CPU_BF549, 0x0000, AC_05000074},
316
317 {"bf561", BFIN_CPU_BF561, 0x0005, AC_05000074},
318 {"bf561", BFIN_CPU_BF561, 0x0003, AC_05000074},
319 {"bf561", BFIN_CPU_BF561, 0x0002, AC_05000074},
320
6e38d384
MF
321 {"bf592", BFIN_CPU_BF592, 0x0001, AC_05000074},
322 {"bf592", BFIN_CPU_BF592, 0x0000, AC_05000074},
323
6306cd85
BS
324 {NULL, 0, 0, 0}
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
347md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
348{
1ac4baed
BS
349 switch (c)
350 {
351 default:
352 return 0;
353
6306cd85
BS
354 case OPTION_MCPU:
355 {
356 const char *p, *q;
357 int i;
358
359 i = 0;
360 while ((p = bfin_cpus[i].name) != NULL)
361 {
362 if (strncmp (arg, p, strlen (p)) == 0)
363 break;
364 i++;
365 }
366
367 if (p == NULL)
110c21e1 368 as_fatal ("-mcpu=%s is not valid", arg);
6306cd85
BS
369
370 bfin_cpu_type = bfin_cpus[i].type;
371
372 q = arg + strlen (p);
373
374 if (*q == '\0')
375 {
376 bfin_si_revision = bfin_cpus[i].si_revision;
377 bfin_anomaly_checks |= bfin_cpus[i].anomaly_checks;
378 }
379 else if (strcmp (q, "-none") == 0)
380 bfin_si_revision = -1;
381 else if (strcmp (q, "-any") == 0)
382 {
383 bfin_si_revision = 0xffff;
384 while (bfin_cpus[i].type == bfin_cpu_type)
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
407 while (bfin_cpus[i].type == bfin_cpu_type
408 && bfin_cpus[i].si_revision != bfin_si_revision)
409 i++;
410
411 if (bfin_cpus[i].type != bfin_cpu_type)
412 goto invalid_silicon_revision;
413
414 bfin_anomaly_checks |= bfin_cpus[i].anomaly_checks;
415 }
416
417 break;
418 }
419
1ac4baed
BS
420 case OPTION_FDPIC:
421 bfin_flags |= EF_BFIN_FDPIC;
422 bfin_pic_flag = "-mfdpic";
423 break;
fe4fa32c
MF
424
425 case OPTION_NOPIC:
426 bfin_flags &= ~(EF_BFIN_FDPIC);
427 bfin_pic_flag = 0;
428 break;
1ac4baed
BS
429 }
430
431 return 1;
07c1b327
CM
432}
433
434void
9982501a 435md_show_usage (FILE * stream)
07c1b327 436{
9982501a
JZ
437 fprintf (stream, _(" Blackfin specific assembler options:\n"));
438 fprintf (stream, _(" -mcpu=<cpu[-sirevision]> specify the name of the target CPU\n"));
439 fprintf (stream, _(" -mfdpic assemble for the FDPIC ABI\n"));
440 fprintf (stream, _(" -mno-fdpic/-mnopic disable -mfdpic\n"));
07c1b327
CM
441}
442
443/* Perform machine-specific initializations. */
444void
445md_begin ()
446{
1ac4baed
BS
447 /* Set the ELF flags if desired. */
448 if (bfin_flags)
449 bfd_set_private_flags (stdoutput, bfin_flags);
450
07c1b327
CM
451 /* Set the default machine type. */
452 if (!bfd_set_arch_mach (stdoutput, bfd_arch_bfin, 0))
bd3ba5d1 453 as_warn (_("Could not set architecture and machine."));
07c1b327
CM
454
455 /* Ensure that lines can begin with '(', for multiple
456 register stack pops. */
9f8e671b 457 lex_type ['('] = LEX_BEGIN_NAME;
ee9e7c78 458
07c1b327
CM
459#ifdef OBJ_ELF
460 record_alignment (text_section, 2);
461 record_alignment (data_section, 2);
462 record_alignment (bss_section, 2);
463#endif
464
465 errorf = stderr;
466 obstack_init (&mempool);
467
468#ifdef DEBUG
469 extern int debug_codeselection;
470 debug_codeselection = 1;
ee9e7c78 471#endif
07c1b327
CM
472
473 last_insn_size = 0;
474}
475
476/* Perform the main parsing, and assembly of the input here. Also,
477 call the required routines for alignment and fixups here.
478 This is called for every line that contains real assembly code. */
479
480void
481md_assemble (char *line)
482{
483 char *toP = 0;
484 extern char *current_inputline;
485 int size, insn_size;
486 struct bfin_insn *tmp_insn;
487 size_t len;
488 static size_t buffer_len = 0;
489 parse_state state;
490
491 len = strlen (line);
492 if (len + 2 > buffer_len)
493 {
494 if (buffer_len > 0)
495 free (current_inputline);
496 buffer_len = len + 40;
497 current_inputline = xmalloc (buffer_len);
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
790md_section_align (segment, size)
791 segT segment;
792 valueT size;
793{
794 int boundary = bfd_get_section_alignment (stdoutput, segment);
795 return ((size + (1 << boundary) - 1) & (-1 << boundary));
796}
797
798
07c1b327 799char *
499ac353 800md_atof (int type, char * litP, int * sizeP)
07c1b327 801{
499ac353 802 return ieee_md_atof (type, litP, sizeP, FALSE);
07c1b327
CM
803}
804
805
806/* If while processing a fixup, a reloc really needs to be created
807 then it is done here. */
808
809arelent *
810tc_gen_reloc (seg, fixp)
811 asection *seg ATTRIBUTE_UNUSED;
812 fixS *fixp;
813{
814 arelent *reloc;
815
816 reloc = (arelent *) xmalloc (sizeof (arelent));
817 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
818 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
819 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
820
821 reloc->addend = fixp->fx_offset;
822 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
823
824 if (reloc->howto == (reloc_howto_type *) NULL)
825 {
826 as_bad_where (fixp->fx_file, fixp->fx_line,
827 /* xgettext:c-format. */
828 _("reloc %d not supported by object file format"),
829 (int) fixp->fx_r_type);
830
831 xfree (reloc);
832
833 return NULL;
834 }
835
836 return reloc;
837}
838
839/* The location from which a PC relative jump should be calculated,
840 given a PC relative reloc. */
841
842long
843md_pcrel_from_section (fixP, sec)
844 fixS *fixP;
845 segT sec;
846{
847 if (fixP->fx_addsy != (symbolS *) NULL
848 && (!S_IS_DEFINED (fixP->fx_addsy)
849 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
850 {
851 /* The symbol is undefined (or is defined but not in this section).
852 Let the linker figure it out. */
853 return 0;
854 }
855 return fixP->fx_frag->fr_address + fixP->fx_where;
856}
857
858/* Return true if the fix can be handled by GAS, false if it must
859 be passed through to the linker. */
860
ee9e7c78 861bfd_boolean
07c1b327 862bfin_fix_adjustable (fixS *fixP)
ee9e7c78 863{
07c1b327 864 switch (fixP->fx_r_type)
ee9e7c78 865 {
07c1b327 866 /* Adjust_reloc_syms doesn't know about the GOT. */
1ac4baed 867 case BFD_RELOC_BFIN_GOT:
1ac4baed 868 case BFD_RELOC_BFIN_PLTPC:
07c1b327
CM
869 /* We need the symbol name for the VTABLE entries. */
870 case BFD_RELOC_VTABLE_INHERIT:
871 case BFD_RELOC_VTABLE_ENTRY:
872 return 0;
ee9e7c78 873
07c1b327
CM
874 default:
875 return 1;
ee9e7c78 876 }
07c1b327
CM
877}
878
07c1b327
CM
879/* Special extra functions that help bfin-parse.y perform its job. */
880
07c1b327
CM
881struct obstack mempool;
882
883INSTR_T
884conscode (INSTR_T head, INSTR_T tail)
885{
886 if (!head)
887 return tail;
888 head->next = tail;
889 return head;
890}
891
892INSTR_T
893conctcode (INSTR_T head, INSTR_T tail)
894{
895 INSTR_T temp = (head);
896 if (!head)
897 return tail;
898 while (temp->next)
899 temp = temp->next;
900 temp->next = tail;
901
902 return head;
903}
904
905INSTR_T
906note_reloc (INSTR_T code, Expr_Node * symbol, int reloc, int pcrel)
907{
908 /* Assert that the symbol is not an operator. */
9c2799c2 909 gas_assert (symbol->type == Expr_Node_Reloc);
07c1b327
CM
910
911 return note_reloc1 (code, symbol->value.s_value, reloc, pcrel);
912
913}
914
915INSTR_T
916note_reloc1 (INSTR_T code, const char *symbol, int reloc, int pcrel)
917{
918 code->reloc = reloc;
919 code->exp = mkexpr (0, symbol_find_or_make (symbol));
920 code->pcrel = pcrel;
921 return code;
922}
923
924INSTR_T
925note_reloc2 (INSTR_T code, const char *symbol, int reloc, int value, int pcrel)
926{
927 code->reloc = reloc;
928 code->exp = mkexpr (value, symbol_find_or_make (symbol));
929 code->pcrel = pcrel;
930 return code;
931}
932
933INSTR_T
934gencode (unsigned long x)
935{
78aff5a5 936 INSTR_T cell = obstack_alloc (&mempool, sizeof (struct bfin_insn));
07c1b327
CM
937 memset (cell, 0, sizeof (struct bfin_insn));
938 cell->value = (x);
939 return cell;
940}
941
942int reloc;
943int ninsns;
944int count_insns;
945
946static void *
947allocate (int n)
948{
78aff5a5 949 return obstack_alloc (&mempool, n);
07c1b327
CM
950}
951
952Expr_Node *
953Expr_Node_Create (Expr_Node_Type type,
954 Expr_Node_Value value,
955 Expr_Node *Left_Child,
956 Expr_Node *Right_Child)
957{
958
959
960 Expr_Node *node = (Expr_Node *) allocate (sizeof (Expr_Node));
961 node->type = type;
962 node->value = value;
963 node->Left_Child = Left_Child;
964 node->Right_Child = Right_Child;
965 return node;
966}
967
968static const char *con = ".__constant";
969static const char *op = ".__operator";
970static INSTR_T Expr_Node_Gen_Reloc_R (Expr_Node * head);
971INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc);
972
973INSTR_T
974Expr_Node_Gen_Reloc (Expr_Node * head, int parent_reloc)
975{
976 /* Top level reloction expression generator VDSP style.
977 If the relocation is just by itself, generate one item
978 else generate this convoluted expression. */
979
980 INSTR_T note = NULL_CODE;
981 INSTR_T note1 = NULL_CODE;
982 int pcrel = 1; /* Is the parent reloc pcrelative?
983 This calculation here and HOWTO should match. */
984
985 if (parent_reloc)
986 {
987 /* If it's 32 bit quantity then 16bit code needs to be added. */
988 int value = 0;
989
990 if (head->type == Expr_Node_Constant)
991 {
992 /* If note1 is not null code, we have to generate a right
993 aligned value for the constant. Otherwise the reloc is
994 a part of the basic command and the yacc file
995 generates this. */
996 value = head->value.i_value;
997 }
998 switch (parent_reloc)
999 {
708587a4 1000 /* Some relocations will need to allocate extra words. */
07c1b327
CM
1001 case BFD_RELOC_BFIN_16_IMM:
1002 case BFD_RELOC_BFIN_16_LOW:
1003 case BFD_RELOC_BFIN_16_HIGH:
1004 note1 = conscode (gencode (value), NULL_CODE);
1005 pcrel = 0;
1006 break;
1007 case BFD_RELOC_BFIN_PLTPC:
1008 note1 = conscode (gencode (value), NULL_CODE);
1009 pcrel = 0;
1010 break;
1011 case BFD_RELOC_16:
1012 case BFD_RELOC_BFIN_GOT:
1ac4baed
BS
1013 case BFD_RELOC_BFIN_GOT17M4:
1014 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
07c1b327
CM
1015 note1 = conscode (gencode (value), NULL_CODE);
1016 pcrel = 0;
1017 break;
1018 case BFD_RELOC_24_PCREL:
1019 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
1020 case BFD_RELOC_BFIN_24_PCREL_CALL_X:
1021 /* These offsets are even numbered pcrel. */
1022 note1 = conscode (gencode (value >> 1), NULL_CODE);
1023 break;
1024 default:
1025 note1 = NULL_CODE;
1026 }
1027 }
1028 if (head->type == Expr_Node_Constant)
1029 note = note1;
1030 else if (head->type == Expr_Node_Reloc)
1031 {
1032 note = note_reloc1 (gencode (0), head->value.s_value, parent_reloc, pcrel);
1033 if (note1 != NULL_CODE)
1034 note = conscode (note1, note);
1035 }
beb6bfe8
BS
1036 else if (head->type == Expr_Node_Binop
1037 && (head->value.op_value == Expr_Op_Type_Add
1038 || head->value.op_value == Expr_Op_Type_Sub)
1039 && head->Left_Child->type == Expr_Node_Reloc
1040 && head->Right_Child->type == Expr_Node_Constant)
1041 {
1042 int val = head->Right_Child->value.i_value;
1043 if (head->value.op_value == Expr_Op_Type_Sub)
1044 val = -val;
1045 note = conscode (note_reloc2 (gencode (0), head->Left_Child->value.s_value,
1046 parent_reloc, val, 0),
1047 NULL_CODE);
1048 if (note1 != NULL_CODE)
1049 note = conscode (note1, note);
1050 }
07c1b327
CM
1051 else
1052 {
1053 /* Call the recursive function. */
1054 note = note_reloc1 (gencode (0), op, parent_reloc, pcrel);
1055 if (note1 != NULL_CODE)
1056 note = conscode (note1, note);
1057 note = conctcode (Expr_Node_Gen_Reloc_R (head), note);
1058 }
1059 return note;
1060}
1061
1062static INSTR_T
1063Expr_Node_Gen_Reloc_R (Expr_Node * head)
1064{
1065
1066 INSTR_T note = 0;
1067 INSTR_T note1 = 0;
1068
1069 switch (head->type)
1070 {
1071 case Expr_Node_Constant:
1072 note = conscode (note_reloc2 (gencode (0), con, BFD_ARELOC_BFIN_CONST, head->value.i_value, 0), NULL_CODE);
1073 break;
1074 case Expr_Node_Reloc:
1075 note = conscode (note_reloc (gencode (0), head, BFD_ARELOC_BFIN_PUSH, 0), NULL_CODE);
1076 break;
1077 case Expr_Node_Binop:
1078 note1 = conctcode (Expr_Node_Gen_Reloc_R (head->Left_Child), Expr_Node_Gen_Reloc_R (head->Right_Child));
1079 switch (head->value.op_value)
1080 {
1081 case Expr_Op_Type_Add:
1082 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_ADD, 0), NULL_CODE));
1083 break;
1084 case Expr_Op_Type_Sub:
1085 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_SUB, 0), NULL_CODE));
1086 break;
1087 case Expr_Op_Type_Mult:
1088 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MULT, 0), NULL_CODE));
1089 break;
1090 case Expr_Op_Type_Div:
1091 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_DIV, 0), NULL_CODE));
1092 break;
1093 case Expr_Op_Type_Mod:
1094 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MOD, 0), NULL_CODE));
1095 break;
1096 case Expr_Op_Type_Lshift:
1097 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LSHIFT, 0), NULL_CODE));
1098 break;
1099 case Expr_Op_Type_Rshift:
1100 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_RSHIFT, 0), NULL_CODE));
1101 break;
1102 case Expr_Op_Type_BAND:
1103 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_AND, 0), NULL_CODE));
1104 break;
1105 case Expr_Op_Type_BOR:
1106 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_OR, 0), NULL_CODE));
1107 break;
1108 case Expr_Op_Type_BXOR:
1109 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_XOR, 0), NULL_CODE));
1110 break;
1111 case Expr_Op_Type_LAND:
1112 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LAND, 0), NULL_CODE));
1113 break;
1114 case Expr_Op_Type_LOR:
1115 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LOR, 0), NULL_CODE));
1116 break;
1117 default:
df3e8017 1118 fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
07c1b327
CM
1119
1120
1121 }
1122 break;
1123 case Expr_Node_Unop:
1124 note1 = conscode (Expr_Node_Gen_Reloc_R (head->Left_Child), NULL_CODE);
1125 switch (head->value.op_value)
1126 {
1127 case Expr_Op_Type_NEG:
1128 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_NEG, 0), NULL_CODE));
1129 break;
1130 case Expr_Op_Type_COMP:
1131 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_COMP, 0), NULL_CODE));
1132 break;
1133 default:
df3e8017 1134 fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
07c1b327
CM
1135 }
1136 break;
1137 default:
1138 fprintf (stderr, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__, __LINE__);
1139 }
1140 return note;
1141}
d55cb1c5 1142\f
07c1b327
CM
1143/* Blackfin opcode generation. */
1144
1145/* These functions are called by the generated parser
1146 (from bfin-parse.y), the register type classification
1147 happens in bfin-lex.l. */
1148
1149#include "bfin-aux.h"
1150#include "opcode/bfin.h"
1151
1152#define INIT(t) t c_code = init_##t
1153#define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
91d6fa6a 1154#define ASSIGNF(x,f) c_code.opcode |= ((x & c_code.mask_##f)<<c_code.bits_##f)
07c1b327
CM
1155#define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1156
1157#define HI(x) ((x >> 16) & 0xffff)
1158#define LO(x) ((x ) & 0xffff)
1159
1160#define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1161
1162#define GEN_OPCODE32() \
1163 conscode (gencode (HI (c_code.opcode)), \
1164 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1165
1166#define GEN_OPCODE16() \
1167 conscode (gencode (c_code.opcode), NULL_CODE)
1168
1169
1170/* 32 BIT INSTRUCTIONS. */
1171
1172
1173/* DSP32 instruction generation. */
1174
1175INSTR_T
1176bfin_gen_dsp32mac (int op1, int MM, int mmod, int w1, int P,
1177 int h01, int h11, int h00, int h10, int op0,
1178 REG_T dst, REG_T src0, REG_T src1, int w0)
1179{
1180 INIT (DSP32Mac);
1181
1182 ASSIGN (op0);
1183 ASSIGN (op1);
1184 ASSIGN (MM);
1185 ASSIGN (mmod);
1186 ASSIGN (w0);
1187 ASSIGN (w1);
1188 ASSIGN (h01);
1189 ASSIGN (h11);
1190 ASSIGN (h00);
1191 ASSIGN (h10);
1192 ASSIGN (P);
1193
1194 /* If we have full reg assignments, mask out LSB to encode
1195 single or simultaneous even/odd register moves. */
1196 if (P)
1197 {
1198 dst->regno &= 0x06;
1199 }
1200
1201 ASSIGN_R (dst);
1202 ASSIGN_R (src0);
1203 ASSIGN_R (src1);
1204
1205 return GEN_OPCODE32 ();
1206}
1207
1208INSTR_T
1209bfin_gen_dsp32mult (int op1, int MM, int mmod, int w1, int P,
1210 int h01, int h11, int h00, int h10, int op0,
1211 REG_T dst, REG_T src0, REG_T src1, int w0)
1212{
1213 INIT (DSP32Mult);
1214
1215 ASSIGN (op0);
1216 ASSIGN (op1);
1217 ASSIGN (MM);
1218 ASSIGN (mmod);
1219 ASSIGN (w0);
1220 ASSIGN (w1);
1221 ASSIGN (h01);
1222 ASSIGN (h11);
1223 ASSIGN (h00);
1224 ASSIGN (h10);
1225 ASSIGN (P);
1226
1227 if (P)
1228 {
1229 dst->regno &= 0x06;
1230 }
1231
1232 ASSIGN_R (dst);
1233 ASSIGN_R (src0);
1234 ASSIGN_R (src1);
1235
1236 return GEN_OPCODE32 ();
1237}
1238
1239INSTR_T
1240bfin_gen_dsp32alu (int HL, int aopcde, int aop, int s, int x,
1241 REG_T dst0, REG_T dst1, REG_T src0, REG_T src1)
1242{
1243 INIT (DSP32Alu);
1244
1245 ASSIGN (HL);
1246 ASSIGN (aopcde);
1247 ASSIGN (aop);
1248 ASSIGN (s);
1249 ASSIGN (x);
1250 ASSIGN_R (dst0);
1251 ASSIGN_R (dst1);
1252 ASSIGN_R (src0);
1253 ASSIGN_R (src1);
1254
1255 return GEN_OPCODE32 ();
1256}
1257
1258INSTR_T
1259bfin_gen_dsp32shift (int sopcde, REG_T dst0, REG_T src0,
1260 REG_T src1, int sop, int HLs)
1261{
1262 INIT (DSP32Shift);
1263
1264 ASSIGN (sopcde);
1265 ASSIGN (sop);
1266 ASSIGN (HLs);
1267
1268 ASSIGN_R (dst0);
1269 ASSIGN_R (src0);
1270 ASSIGN_R (src1);
1271
1272 return GEN_OPCODE32 ();
1273}
1274
1275INSTR_T
1276bfin_gen_dsp32shiftimm (int sopcde, REG_T dst0, int immag,
1277 REG_T src1, int sop, int HLs)
1278{
1279 INIT (DSP32ShiftImm);
1280
1281 ASSIGN (sopcde);
1282 ASSIGN (sop);
1283 ASSIGN (HLs);
1284
1285 ASSIGN_R (dst0);
1286 ASSIGN (immag);
1287 ASSIGN_R (src1);
1288
1289 return GEN_OPCODE32 ();
1290}
1291
1292/* LOOP SETUP. */
1293
1294INSTR_T
1295bfin_gen_loopsetup (Expr_Node * psoffset, REG_T c, int rop,
1296 Expr_Node * peoffset, REG_T reg)
1297{
1298 int soffset, eoffset;
1299 INIT (LoopSetup);
1300
1301 soffset = (EXPR_VALUE (psoffset) >> 1);
1302 ASSIGN (soffset);
1303 eoffset = (EXPR_VALUE (peoffset) >> 1);
1304 ASSIGN (eoffset);
1305 ASSIGN (rop);
1306 ASSIGN_R (c);
1307 ASSIGN_R (reg);
1308
1309 return
1310 conscode (gencode (HI (c_code.opcode)),
1311 conctcode (Expr_Node_Gen_Reloc (psoffset, BFD_RELOC_BFIN_5_PCREL),
1312 conctcode (gencode (LO (c_code.opcode)), Expr_Node_Gen_Reloc (peoffset, BFD_RELOC_BFIN_11_PCREL))));
1313
1314}
1315
1316/* Call, Link. */
1317
1318INSTR_T
1319bfin_gen_calla (Expr_Node * addr, int S)
1320{
1321 int val;
1322 int high_val;
91d6fa6a 1323 int rel = 0;
07c1b327
CM
1324 INIT (CALLa);
1325
1326 switch(S){
91d6fa6a
NC
1327 case 0 : rel = BFD_RELOC_BFIN_24_PCREL_JUMP_L; break;
1328 case 1 : rel = BFD_RELOC_24_PCREL; break;
1329 case 2 : rel = BFD_RELOC_BFIN_PLTPC; break;
07c1b327
CM
1330 default : break;
1331 }
1332
1333 ASSIGN (S);
1334
1335 val = EXPR_VALUE (addr) >> 1;
1336 high_val = val >> 16;
1337
1338 return conscode (gencode (HI (c_code.opcode) | (high_val & 0xff)),
91d6fa6a 1339 Expr_Node_Gen_Reloc (addr, rel));
07c1b327
CM
1340 }
1341
1342INSTR_T
1343bfin_gen_linkage (int R, int framesize)
1344{
1345 INIT (Linkage);
1346
1347 ASSIGN (R);
1348 ASSIGN (framesize);
1349
1350 return GEN_OPCODE32 ();
1351}
1352
1353
1354/* Load and Store. */
1355
1356INSTR_T
91d6fa6a 1357bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int rel)
07c1b327
CM
1358{
1359 int grp, hword;
1360 unsigned val = EXPR_VALUE (phword);
1361 INIT (LDIMMhalf);
1362
1363 ASSIGN (H);
1364 ASSIGN (S);
1365 ASSIGN (Z);
1366
1367 ASSIGN_R (reg);
1368 grp = (GROUP (reg));
1369 ASSIGN (grp);
91d6fa6a 1370 if (rel == 2)
07c1b327
CM
1371 {
1372 return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, BFD_RELOC_BFIN_16_IMM));
1373 }
91d6fa6a 1374 else if (rel == 1)
07c1b327
CM
1375 {
1376 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));
1377 }
1378 else
1379 {
1380 hword = val;
1381 ASSIGN (hword);
1382 }
1383 return GEN_OPCODE32 ();
1384}
1385
1386INSTR_T
1387bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset)
1388{
07c1b327
CM
1389 INIT (LDSTidxI);
1390
1391 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1392 {
1393 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1394 return 0;
1395 }
1396
1397 ASSIGN_R (ptr);
1398 ASSIGN_R (reg);
1399 ASSIGN (W);
1400 ASSIGN (sz);
07c1b327
CM
1401
1402 ASSIGN (Z);
1403
1ac4baed
BS
1404 if (poffset->type != Expr_Node_Constant)
1405 {
1406 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1407 /* distinguish between R0 = [P5 + symbol@GOT] and
1408 P5 = [P5 + _current_shared_library_p5_offset_]
1409 */
1410 if (poffset->type == Expr_Node_Reloc
1411 && !strcmp (poffset->value.s_value,
1412 "_current_shared_library_p5_offset_"))
1413 {
1414 return conscode (gencode (HI (c_code.opcode)),
1415 Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16));
1416 }
1417 else if (poffset->type != Expr_Node_GOT_Reloc)
1418 abort ();
1419
1420 return conscode (gencode (HI (c_code.opcode)),
1421 Expr_Node_Gen_Reloc(poffset->Left_Child,
1422 poffset->value.i_value));
07c1b327 1423 }
1ac4baed 1424 else
07c1b327 1425 {
1ac4baed
BS
1426 int value, offset;
1427 switch (sz)
8fc4ee9b
AM
1428 { /* load/store access size */
1429 case 0: /* 32 bit */
1ac4baed
BS
1430 value = EXPR_VALUE (poffset) >> 2;
1431 break;
8fc4ee9b 1432 case 1: /* 16 bit */
1ac4baed
BS
1433 value = EXPR_VALUE (poffset) >> 1;
1434 break;
8fc4ee9b 1435 case 2: /* 8 bit */
1ac4baed
BS
1436 value = EXPR_VALUE (poffset);
1437 break;
1438 default:
1439 abort ();
1440 }
1441
1442 offset = (value & 0xffff);
1443 ASSIGN (offset);
1444 return GEN_OPCODE32 ();
07c1b327 1445 }
07c1b327
CM
1446}
1447
1448
1449INSTR_T
1450bfin_gen_ldst (REG_T ptr, REG_T reg, int aop, int sz, int Z, int W)
1451{
1452 INIT (LDST);
1453
1454 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1455 {
1456 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1457 return 0;
1458 }
1459
1460 ASSIGN_R (ptr);
1461 ASSIGN_R (reg);
1462 ASSIGN (aop);
1463 ASSIGN (sz);
1464 ASSIGN (Z);
1465 ASSIGN (W);
1466
1467 return GEN_OPCODE16 ();
1468}
1469
1470INSTR_T
91d6fa6a 1471bfin_gen_ldstii (REG_T ptr, REG_T reg, Expr_Node * poffset, int W, int opc)
07c1b327
CM
1472{
1473 int offset;
1474 int value = 0;
1475 INIT (LDSTii);
1476
07c1b327
CM
1477 if (!IS_PREG (*ptr))
1478 {
1479 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1480 return 0;
1481 }
1482
91d6fa6a 1483 switch (opc)
07c1b327
CM
1484 {
1485 case 1:
1486 case 2:
1487 value = EXPR_VALUE (poffset) >> 1;
1488 break;
1489 case 0:
1490 case 3:
1491 value = EXPR_VALUE (poffset) >> 2;
1492 break;
1493 }
1494
1495 ASSIGN_R (ptr);
1496 ASSIGN_R (reg);
1497
1498 offset = value;
1499 ASSIGN (offset);
1500 ASSIGN (W);
91d6fa6a 1501 ASSIGNF (opc, op);
07c1b327
CM
1502
1503 return GEN_OPCODE16 ();
1504}
1505
1506INSTR_T
1507bfin_gen_ldstiifp (REG_T sreg, Expr_Node * poffset, int W)
1508{
1509 /* Set bit 4 if it's a Preg. */
1510 int reg = (sreg->regno & CODE_MASK) | (IS_PREG (*sreg) ? 0x8 : 0x0);
1511 int offset = ((~(EXPR_VALUE (poffset) >> 2)) & 0x1f) + 1;
1512 INIT (LDSTiiFP);
1513 ASSIGN (reg);
1514 ASSIGN (offset);
1515 ASSIGN (W);
1516
1517 return GEN_OPCODE16 ();
1518}
1519
1520INSTR_T
1521bfin_gen_ldstpmod (REG_T ptr, REG_T reg, int aop, int W, REG_T idx)
1522{
1523 INIT (LDSTpmod);
1524
1525 ASSIGN_R (ptr);
1526 ASSIGN_R (reg);
1527 ASSIGN (aop);
1528 ASSIGN (W);
1529 ASSIGN_R (idx);
1530
1531 return GEN_OPCODE16 ();
1532}
1533
1534INSTR_T
1535bfin_gen_dspldst (REG_T i, REG_T reg, int aop, int W, int m)
1536{
1537 INIT (DspLDST);
1538
1539 ASSIGN_R (i);
1540 ASSIGN_R (reg);
1541 ASSIGN (aop);
1542 ASSIGN (W);
1543 ASSIGN (m);
1544
1545 return GEN_OPCODE16 ();
1546}
1547
1548INSTR_T
1549bfin_gen_logi2op (int opc, int src, int dst)
1550{
1551 INIT (LOGI2op);
1552
1553 ASSIGN (opc);
1554 ASSIGN (src);
1555 ASSIGN (dst);
1556
1557 return GEN_OPCODE16 ();
1558}
1559
1560INSTR_T
1561bfin_gen_brcc (int T, int B, Expr_Node * poffset)
1562{
1563 int offset;
1564 INIT (BRCC);
1565
1566 ASSIGN (T);
1567 ASSIGN (B);
1568 offset = ((EXPR_VALUE (poffset) >> 1));
1569 ASSIGN (offset);
1570 return conscode (gencode (c_code.opcode), Expr_Node_Gen_Reloc (poffset, BFD_RELOC_BFIN_10_PCREL));
1571}
1572
1573INSTR_T
1574bfin_gen_ujump (Expr_Node * poffset)
1575{
1576 int offset;
1577 INIT (UJump);
1578
1579 offset = ((EXPR_VALUE (poffset) >> 1));
1580 ASSIGN (offset);
1581
1582 return conscode (gencode (c_code.opcode),
1583 Expr_Node_Gen_Reloc (
1584 poffset, BFD_RELOC_BFIN_12_PCREL_JUMP_S));
1585}
1586
1587INSTR_T
1588bfin_gen_alu2op (REG_T dst, REG_T src, int opc)
1589{
1590 INIT (ALU2op);
1591
1592 ASSIGN_R (dst);
1593 ASSIGN_R (src);
1594 ASSIGN (opc);
1595
1596 return GEN_OPCODE16 ();
1597}
1598
1599INSTR_T
91d6fa6a 1600bfin_gen_compi2opd (REG_T dst, int src, int opc)
07c1b327
CM
1601{
1602 INIT (COMPI2opD);
1603
1604 ASSIGN_R (dst);
1605 ASSIGN (src);
91d6fa6a 1606 ASSIGNF (opc, op);
07c1b327
CM
1607
1608 return GEN_OPCODE16 ();
1609}
1610
1611INSTR_T
91d6fa6a 1612bfin_gen_compi2opp (REG_T dst, int src, int opc)
07c1b327
CM
1613{
1614 INIT (COMPI2opP);
1615
1616 ASSIGN_R (dst);
1617 ASSIGN (src);
91d6fa6a 1618 ASSIGNF (opc, op);
07c1b327
CM
1619
1620 return GEN_OPCODE16 ();
1621}
1622
1623INSTR_T
91d6fa6a 1624bfin_gen_dagmodik (REG_T i, int opc)
07c1b327
CM
1625{
1626 INIT (DagMODik);
1627
1628 ASSIGN_R (i);
91d6fa6a 1629 ASSIGNF (opc, op);
07c1b327
CM
1630
1631 return GEN_OPCODE16 ();
1632}
1633
1634INSTR_T
91d6fa6a 1635bfin_gen_dagmodim (REG_T i, REG_T m, int opc, int br)
07c1b327
CM
1636{
1637 INIT (DagMODim);
1638
1639 ASSIGN_R (i);
1640 ASSIGN_R (m);
91d6fa6a 1641 ASSIGNF (opc, op);
07c1b327
CM
1642 ASSIGN (br);
1643
1644 return GEN_OPCODE16 ();
1645}
1646
1647INSTR_T
1648bfin_gen_ptr2op (REG_T dst, REG_T src, int opc)
1649{
1650 INIT (PTR2op);
1651
1652 ASSIGN_R (dst);
1653 ASSIGN_R (src);
1654 ASSIGN (opc);
1655
1656 return GEN_OPCODE16 ();
1657}
1658
1659INSTR_T
1660bfin_gen_comp3op (REG_T src0, REG_T src1, REG_T dst, int opc)
1661{
1662 INIT (COMP3op);
1663
1664 ASSIGN_R (src0);
1665 ASSIGN_R (src1);
1666 ASSIGN_R (dst);
1667 ASSIGN (opc);
1668
1669 return GEN_OPCODE16 ();
1670}
1671
1672INSTR_T
1673bfin_gen_ccflag (REG_T x, int y, int opc, int I, int G)
1674{
1675 INIT (CCflag);
1676
1677 ASSIGN_R (x);
1678 ASSIGN (y);
1679 ASSIGN (opc);
1680 ASSIGN (I);
1681 ASSIGN (G);
1682
1683 return GEN_OPCODE16 ();
1684}
1685
1686INSTR_T
1687bfin_gen_ccmv (REG_T src, REG_T dst, int T)
1688{
1689 int s, d;
1690 INIT (CCmv);
1691
1692 ASSIGN_R (src);
1693 ASSIGN_R (dst);
1694 s = (GROUP (src));
1695 ASSIGN (s);
1696 d = (GROUP (dst));
1697 ASSIGN (d);
1698 ASSIGN (T);
1699
1700 return GEN_OPCODE16 ();
1701}
1702
1703INSTR_T
91d6fa6a 1704bfin_gen_cc2stat (int cbit, int opc, int D)
07c1b327
CM
1705{
1706 INIT (CC2stat);
1707
1708 ASSIGN (cbit);
91d6fa6a 1709 ASSIGNF (opc, op);
07c1b327
CM
1710 ASSIGN (D);
1711
1712 return GEN_OPCODE16 ();
1713}
1714
1715INSTR_T
1716bfin_gen_regmv (REG_T src, REG_T dst)
1717{
1718 int gs, gd;
1719 INIT (RegMv);
1720
1721 ASSIGN_R (src);
1722 ASSIGN_R (dst);
1723
1724 gs = (GROUP (src));
1725 ASSIGN (gs);
1726 gd = (GROUP (dst));
1727 ASSIGN (gd);
1728
1729 return GEN_OPCODE16 ();
1730}
1731
1732INSTR_T
91d6fa6a 1733bfin_gen_cc2dreg (int opc, REG_T reg)
07c1b327
CM
1734{
1735 INIT (CC2dreg);
1736
91d6fa6a 1737 ASSIGNF (opc, op);
07c1b327
CM
1738 ASSIGN_R (reg);
1739
1740 return GEN_OPCODE16 ();
1741}
1742
1743INSTR_T
1744bfin_gen_progctrl (int prgfunc, int poprnd)
1745{
1746 INIT (ProgCtrl);
1747
1748 ASSIGN (prgfunc);
1749 ASSIGN (poprnd);
1750
1751 return GEN_OPCODE16 ();
1752}
1753
1754INSTR_T
91d6fa6a 1755bfin_gen_cactrl (REG_T reg, int a, int opc)
07c1b327
CM
1756{
1757 INIT (CaCTRL);
1758
1759 ASSIGN_R (reg);
1760 ASSIGN (a);
91d6fa6a 1761 ASSIGNF (opc, op);
07c1b327
CM
1762
1763 return GEN_OPCODE16 ();
1764}
1765
1766INSTR_T
1767bfin_gen_pushpopmultiple (int dr, int pr, int d, int p, int W)
1768{
1769 INIT (PushPopMultiple);
1770
1771 ASSIGN (dr);
1772 ASSIGN (pr);
1773 ASSIGN (d);
1774 ASSIGN (p);
1775 ASSIGN (W);
1776
1777 return GEN_OPCODE16 ();
1778}
1779
1780INSTR_T
1781bfin_gen_pushpopreg (REG_T reg, int W)
1782{
1783 int grp;
1784 INIT (PushPopReg);
1785
1786 ASSIGN_R (reg);
1787 grp = (GROUP (reg));
1788 ASSIGN (grp);
1789 ASSIGN (W);
1790
1791 return GEN_OPCODE16 ();
1792}
1793
1794/* Pseudo Debugging Support. */
1795
1796INSTR_T
1797bfin_gen_pseudodbg (int fn, int reg, int grp)
1798{
1799 INIT (PseudoDbg);
1800
1801 ASSIGN (fn);
1802 ASSIGN (reg);
1803 ASSIGN (grp);
1804
1805 return GEN_OPCODE16 ();
1806}
1807
1808INSTR_T
1809bfin_gen_pseudodbg_assert (int dbgop, REG_T regtest, int expected)
1810{
66a6900a 1811 int grp;
07c1b327
CM
1812 INIT (PseudoDbg_Assert);
1813
1814 ASSIGN (dbgop);
1815 ASSIGN_R (regtest);
66a6900a
JZ
1816 grp = GROUP (regtest);
1817 ASSIGN (grp);
07c1b327
CM
1818 ASSIGN (expected);
1819
1820 return GEN_OPCODE32 ();
1821}
1822
73a63ccf
MF
1823INSTR_T
1824bfin_gen_pseudochr (int ch)
1825{
1826 INIT (PseudoChr);
1827
1828 ASSIGN (ch);
1829
1830 return GEN_OPCODE16 ();
1831}
1832
07c1b327
CM
1833/* Multiple instruction generation. */
1834
1835INSTR_T
1836bfin_gen_multi_instr (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2)
1837{
1838 INSTR_T walk;
1839
1840 /* If it's a 0, convert into MNOP. */
1841 if (dsp32)
1842 {
1843 walk = dsp32->next;
1844 SET_MULTI_INSTRUCTION_BIT (dsp32);
1845 }
1846 else
1847 {
1848 dsp32 = gencode (0xc803);
1849 walk = gencode (0x1800);
1850 dsp32->next = walk;
1851 }
1852
1853 if (!dsp16_grp1)
1854 {
1855 dsp16_grp1 = gencode (0x0000);
1856 }
1857
1858 if (!dsp16_grp2)
1859 {
1860 dsp16_grp2 = gencode (0x0000);
1861 }
1862
1863 walk->next = dsp16_grp1;
1864 dsp16_grp1->next = dsp16_grp2;
1865 dsp16_grp2->next = NULL_CODE;
1866
1867 return dsp32;
1868}
1869
1870INSTR_T
91d6fa6a 1871bfin_gen_loop (Expr_Node *exp, REG_T reg, int rop, REG_T preg)
07c1b327
CM
1872{
1873 const char *loopsym;
1874 char *lbeginsym, *lendsym;
1875 Expr_Node_Value lbeginval, lendval;
1876 Expr_Node *lbegin, *lend;
1877
91d6fa6a 1878 loopsym = exp->value.s_value;
e2c038d3
BS
1879 lbeginsym = (char *) xmalloc (strlen (loopsym) + strlen ("__BEGIN") + 5);
1880 lendsym = (char *) xmalloc (strlen (loopsym) + strlen ("__END") + 5);
07c1b327
CM
1881
1882 lbeginsym[0] = 0;
1883 lendsym[0] = 0;
1884
e2c038d3 1885 strcat (lbeginsym, "L$L$");
07c1b327
CM
1886 strcat (lbeginsym, loopsym);
1887 strcat (lbeginsym, "__BEGIN");
1888
e2c038d3 1889 strcat (lendsym, "L$L$");
07c1b327
CM
1890 strcat (lendsym, loopsym);
1891 strcat (lendsym, "__END");
1892
1893 lbeginval.s_value = lbeginsym;
1894 lendval.s_value = lendsym;
1895
1896 lbegin = Expr_Node_Create (Expr_Node_Reloc, lbeginval, NULL, NULL);
1897 lend = Expr_Node_Create (Expr_Node_Reloc, lendval, NULL, NULL);
b4f42c96
JZ
1898
1899 symbol_remove (symbol_find (loopsym), &symbol_rootP, &symbol_lastP);
1900
07c1b327
CM
1901 return bfin_gen_loopsetup(lbegin, reg, rop, lend, preg);
1902}
1903
d3a50e14 1904void
91d6fa6a 1905bfin_loop_beginend (Expr_Node *exp, int begin)
d3a50e14
JZ
1906{
1907 const char *loopsym;
1908 char *label_name;
91d6fa6a 1909 symbolS *linelabel;
d3a50e14
JZ
1910 const char *suffix = begin ? "__BEGIN" : "__END";
1911
91d6fa6a 1912 loopsym = exp->value.s_value;
d3a50e14
JZ
1913 label_name = (char *) xmalloc (strlen (loopsym) + strlen (suffix) + 5);
1914
1915 label_name[0] = 0;
1916
1917 strcat (label_name, "L$L$");
1918 strcat (label_name, loopsym);
1919 strcat (label_name, suffix);
1920
91d6fa6a 1921 linelabel = colon (label_name);
d3a50e14
JZ
1922
1923 /* LOOP_END follows the last instruction in the loop.
1924 Adjust label address. */
1925 if (!begin)
91d6fa6a 1926 ((struct local_symbol *) linelabel)->lsy_value -= last_insn_size;
d3a50e14
JZ
1927}
1928
07c1b327
CM
1929bfd_boolean
1930bfin_eol_in_insn (char *line)
1931{
1932 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1933
1934 char *temp = line;
1935
1936 if (*line != '\n')
1937 return FALSE;
1938
1939 /* A semi-colon followed by a newline is always the end of a line. */
1940 if (line[-1] == ';')
1941 return FALSE;
1942
1943 if (line[-1] == '|')
1944 return TRUE;
1945
1946 /* If the || is on the next line, there might be leading whitespace. */
1947 temp++;
1948 while (*temp == ' ' || *temp == '\t') temp++;
1949
1950 if (*temp == '|')
1951 return TRUE;
1952
1953 return FALSE;
1954}
1955
07c1b327 1956bfd_boolean
5e8c8f8f 1957bfin_start_label (char *s, char *ptr)
07c1b327 1958{
5e8c8f8f
JZ
1959 while (s != ptr)
1960 {
1961 if (*s == '(' || *s == '[')
1962 return FALSE;
1963 s++;
1964 }
07c1b327 1965
07c1b327 1966 return TRUE;
ee9e7c78 1967}
07c1b327
CM
1968
1969int
1970bfin_force_relocation (struct fix *fixp)
1971{
1972 if (fixp->fx_r_type ==BFD_RELOC_BFIN_16_LOW
1973 || fixp->fx_r_type == BFD_RELOC_BFIN_16_HIGH)
1974 return TRUE;
1975
1976 return generic_force_reloc (fixp);
1977}
d55cb1c5
BS
1978\f
1979/* This is a stripped down version of the disassembler. The only thing it
1980 does is return a mask of registers modified by an instruction. Only
1981 instructions that can occur in a parallel-issue bundle are handled, and
1982 only the registers that can cause a conflict are recorded. */
1983
1984#define DREG_MASK(n) (0x101 << (n))
1985#define DREGH_MASK(n) (0x100 << (n))
1986#define DREGL_MASK(n) (0x001 << (n))
1987#define IREG_MASK(n) (1 << ((n) + 16))
1988
1989static int
1990decode_ProgCtrl_0 (int iw0)
1991{
1992 if (iw0 == 0)
1993 return 0;
1994 abort ();
1995}
1996
1997static int
1998decode_LDSTpmod_0 (int iw0)
1999{
2000 /* LDSTpmod
2001 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2002 | 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......|
2003 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2004 int W = ((iw0 >> LDSTpmod_W_bits) & LDSTpmod_W_mask);
2005 int aop = ((iw0 >> LDSTpmod_aop_bits) & LDSTpmod_aop_mask);
2006 int idx = ((iw0 >> LDSTpmod_idx_bits) & LDSTpmod_idx_mask);
2007 int ptr = ((iw0 >> LDSTpmod_ptr_bits) & LDSTpmod_ptr_mask);
2008 int reg = ((iw0 >> LDSTpmod_reg_bits) & LDSTpmod_reg_mask);
2009
2010 if (aop == 1 && W == 0 && idx == ptr)
2011 return DREGL_MASK (reg);
2012 else if (aop == 2 && W == 0 && idx == ptr)
2013 return DREGH_MASK (reg);
2014 else if (aop == 1 && W == 1 && idx == ptr)
2015 return 0;
2016 else if (aop == 2 && W == 1 && idx == ptr)
2017 return 0;
2018 else if (aop == 0 && W == 0)
2019 return DREG_MASK (reg);
2020 else if (aop == 1 && W == 0)
2021 return DREGL_MASK (reg);
2022 else if (aop == 2 && W == 0)
2023 return DREGH_MASK (reg);
2024 else if (aop == 3 && W == 0)
2025 return DREG_MASK (reg);
2026 else if (aop == 3 && W == 1)
2027 return DREG_MASK (reg);
2028 else if (aop == 0 && W == 1)
2029 return 0;
2030 else if (aop == 1 && W == 1)
2031 return 0;
2032 else if (aop == 2 && W == 1)
2033 return 0;
2034 else
2035 return 0;
2036
2037 return 2;
2038}
2039
2040static int
2041decode_dagMODim_0 (int iw0)
2042{
2043 /* dagMODim
2044 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2045 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....|
2046 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2047 int i = ((iw0 >> DagMODim_i_bits) & DagMODim_i_mask);
91d6fa6a 2048 int opc = ((iw0 >> DagMODim_op_bits) & DagMODim_op_mask);
d55cb1c5 2049
91d6fa6a 2050 if (opc == 0 || opc == 1)
d55cb1c5
BS
2051 return IREG_MASK (i);
2052 else
2053 return 0;
2054
2055 return 2;
2056}
2057
2058static int
2059decode_dagMODik_0 (int iw0)
2060{
2061 /* dagMODik
2062 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2063 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....|
2064 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2065 int i = ((iw0 >> DagMODik_i_bits) & DagMODik_i_mask);
2066 return IREG_MASK (i);
2067}
2068
2069/* GOOD */
2070static int
2071decode_dspLDST_0 (int iw0)
2072{
2073 /* dspLDST
2074 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2075 | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......|
2076 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2077 int i = ((iw0 >> DspLDST_i_bits) & DspLDST_i_mask);
2078 int m = ((iw0 >> DspLDST_m_bits) & DspLDST_m_mask);
2079 int W = ((iw0 >> DspLDST_W_bits) & DspLDST_W_mask);
2080 int aop = ((iw0 >> DspLDST_aop_bits) & DspLDST_aop_mask);
2081 int reg = ((iw0 >> DspLDST_reg_bits) & DspLDST_reg_mask);
2082
2083 if (aop == 0 && W == 0 && m == 0)
2084 return DREG_MASK (reg) | IREG_MASK (i);
2085 else if (aop == 0 && W == 0 && m == 1)
2086 return DREGL_MASK (reg) | IREG_MASK (i);
2087 else if (aop == 0 && W == 0 && m == 2)
2088 return DREGH_MASK (reg) | IREG_MASK (i);
2089 else if (aop == 1 && W == 0 && m == 0)
2090 return DREG_MASK (reg) | IREG_MASK (i);
2091 else if (aop == 1 && W == 0 && m == 1)
2092 return DREGL_MASK (reg) | IREG_MASK (i);
2093 else if (aop == 1 && W == 0 && m == 2)
2094 return DREGH_MASK (reg) | IREG_MASK (i);
2095 else if (aop == 2 && W == 0 && m == 0)
2096 return DREG_MASK (reg);
2097 else if (aop == 2 && W == 0 && m == 1)
2098 return DREGL_MASK (reg);
2099 else if (aop == 2 && W == 0 && m == 2)
2100 return DREGH_MASK (reg);
2101 else if (aop == 0 && W == 1 && m == 0)
2102 return IREG_MASK (i);
2103 else if (aop == 0 && W == 1 && m == 1)
2104 return IREG_MASK (i);
2105 else if (aop == 0 && W == 1 && m == 2)
2106 return IREG_MASK (i);
2107 else if (aop == 1 && W == 1 && m == 0)
2108 return IREG_MASK (i);
2109 else if (aop == 1 && W == 1 && m == 1)
2110 return IREG_MASK (i);
2111 else if (aop == 1 && W == 1 && m == 2)
2112 return IREG_MASK (i);
2113 else if (aop == 2 && W == 1 && m == 0)
2114 return 0;
2115 else if (aop == 2 && W == 1 && m == 1)
2116 return 0;
2117 else if (aop == 2 && W == 1 && m == 2)
2118 return 0;
2119 else if (aop == 3 && W == 0)
2120 return DREG_MASK (reg) | IREG_MASK (i);
2121 else if (aop == 3 && W == 1)
2122 return IREG_MASK (i);
2123
2124 abort ();
2125}
2126
2127/* GOOD */
2128static int
2129decode_LDST_0 (int iw0)
2130{
2131 /* LDST
2132 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2133 | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......|
2134 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2135 int Z = ((iw0 >> LDST_Z_bits) & LDST_Z_mask);
2136 int W = ((iw0 >> LDST_W_bits) & LDST_W_mask);
2137 int sz = ((iw0 >> LDST_sz_bits) & LDST_sz_mask);
2138 int aop = ((iw0 >> LDST_aop_bits) & LDST_aop_mask);
2139 int reg = ((iw0 >> LDST_reg_bits) & LDST_reg_mask);
2140
2141 if (aop == 0 && sz == 0 && Z == 0 && W == 0)
2142 return DREG_MASK (reg);
2143 else if (aop == 0 && sz == 0 && Z == 1 && W == 0)
2144 return 0;
2145 else if (aop == 0 && sz == 1 && Z == 0 && W == 0)
2146 return DREG_MASK (reg);
2147 else if (aop == 0 && sz == 1 && Z == 1 && W == 0)
2148 return DREG_MASK (reg);
2149 else if (aop == 0 && sz == 2 && Z == 0 && W == 0)
2150 return DREG_MASK (reg);
2151 else if (aop == 0 && sz == 2 && Z == 1 && W == 0)
2152 return DREG_MASK (reg);
2153 else if (aop == 1 && sz == 0 && Z == 0 && W == 0)
2154 return DREG_MASK (reg);
2155 else if (aop == 1 && sz == 0 && Z == 1 && W == 0)
2156 return 0;
2157 else if (aop == 1 && sz == 1 && Z == 0 && W == 0)
2158 return DREG_MASK (reg);
2159 else if (aop == 1 && sz == 1 && Z == 1 && W == 0)
2160 return DREG_MASK (reg);
2161 else if (aop == 1 && sz == 2 && Z == 0 && W == 0)
2162 return DREG_MASK (reg);
2163 else if (aop == 1 && sz == 2 && Z == 1 && W == 0)
2164 return DREG_MASK (reg);
2165 else if (aop == 2 && sz == 0 && Z == 0 && W == 0)
2166 return DREG_MASK (reg);
2167 else if (aop == 2 && sz == 0 && Z == 1 && W == 0)
2168 return 0;
2169 else if (aop == 2 && sz == 1 && Z == 0 && W == 0)
2170 return DREG_MASK (reg);
2171 else if (aop == 2 && sz == 1 && Z == 1 && W == 0)
2172 return DREG_MASK (reg);
2173 else if (aop == 2 && sz == 2 && Z == 0 && W == 0)
2174 return DREG_MASK (reg);
2175 else if (aop == 2 && sz == 2 && Z == 1 && W == 0)
2176 return DREG_MASK (reg);
2177 else if (aop == 0 && sz == 0 && Z == 0 && W == 1)
2178 return 0;
2179 else if (aop == 0 && sz == 0 && Z == 1 && W == 1)
2180 return 0;
2181 else if (aop == 0 && sz == 1 && Z == 0 && W == 1)
2182 return 0;
2183 else if (aop == 0 && sz == 2 && Z == 0 && W == 1)
2184 return 0;
2185 else if (aop == 1 && sz == 0 && Z == 0 && W == 1)
2186 return 0;
2187 else if (aop == 1 && sz == 0 && Z == 1 && W == 1)
2188 return 0;
2189 else if (aop == 1 && sz == 1 && Z == 0 && W == 1)
2190 return 0;
2191 else if (aop == 1 && sz == 2 && Z == 0 && W == 1)
2192 return 0;
2193 else if (aop == 2 && sz == 0 && Z == 0 && W == 1)
2194 return 0;
2195 else if (aop == 2 && sz == 0 && Z == 1 && W == 1)
2196 return 0;
2197 else if (aop == 2 && sz == 1 && Z == 0 && W == 1)
2198 return 0;
2199 else if (aop == 2 && sz == 2 && Z == 0 && W == 1)
2200 return 0;
2201
2202 abort ();
2203}
2204
2205static int
2206decode_LDSTiiFP_0 (int iw0)
2207{
2208 /* LDSTiiFP
2209 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2210 | 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........|
2211 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2212 int reg = ((iw0 >> LDSTiiFP_reg_bits) & LDSTiiFP_reg_mask);
2213 int W = ((iw0 >> LDSTiiFP_W_bits) & LDSTiiFP_W_mask);
2214
2215 if (W == 0)
2216 return reg < 8 ? DREG_MASK (reg) : 0;
2217 else
2218 return 0;
2219}
2220
2221static int
2222decode_LDSTii_0 (int iw0)
2223{
2224 /* LDSTii
2225 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2226 | 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......|
2227 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2228 int reg = ((iw0 >> LDSTii_reg_bit) & LDSTii_reg_mask);
91d6fa6a 2229 int opc = ((iw0 >> LDSTii_op_bit) & LDSTii_op_mask);
d55cb1c5
BS
2230 int W = ((iw0 >> LDSTii_W_bit) & LDSTii_W_mask);
2231
91d6fa6a 2232 if (W == 0 && opc != 3)
d55cb1c5 2233 return DREG_MASK (reg);
91d6fa6a 2234 else if (W == 0 && opc == 3)
d55cb1c5 2235 return 0;
91d6fa6a 2236 else if (W == 1 && opc == 0)
d55cb1c5 2237 return 0;
91d6fa6a 2238 else if (W == 1 && opc == 1)
d55cb1c5 2239 return 0;
91d6fa6a 2240 else if (W == 1 && opc == 3)
d55cb1c5
BS
2241 return 0;
2242
2243 abort ();
2244}
2245
2246static int
2247decode_dsp32mac_0 (int iw0, int iw1)
2248{
2249 int result = 0;
2250 /* dsp32mac
2251 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2252 | 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...|
2253 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2254 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2255 int op1 = ((iw0 >> (DSP32Mac_op1_bits - 16)) & DSP32Mac_op1_mask);
2256 int w1 = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask);
2257 int P = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask);
2258 int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask);
2259 int w0 = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask);
2260 int MM = ((iw1 >> DSP32Mac_MM_bits) & DSP32Mac_MM_mask);
2261 int dst = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask);
2262 int op0 = ((iw1 >> DSP32Mac_op0_bits) & DSP32Mac_op0_mask);
2263
2264 if (w0 == 0 && w1 == 0 && op1 == 3 && op0 == 3)
2265 return 0;
2266
2267 if (op1 == 3 && MM)
2268 return 0;
2269
2270 if ((w1 || w0) && mmod == M_W32)
2271 return 0;
2272
2273 if (((1 << mmod) & (P ? 0x131b : 0x1b5f)) == 0)
2274 return 0;
2275
2276 if (w1 == 1 || op1 != 3)
2277 {
2278 if (w1)
2279 {
2280 if (P)
2281 return DREG_MASK (dst + 1);
2282 else
2283 return DREGH_MASK (dst);
2284 }
2285 }
2286
2287 if (w0 == 1 || op0 != 3)
2288 {
2289 if (w0)
2290 {
2291 if (P)
2292 return DREG_MASK (dst);
2293 else
2294 return DREGL_MASK (dst);
2295 }
2296 }
2297
2298 return result;
2299}
2300
2301static int
2302decode_dsp32mult_0 (int iw0, int iw1)
2303{
2304 /* dsp32mult
2305 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2306 | 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...|
2307 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2308 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2309 int w1 = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask);
2310 int P = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask);
2311 int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask);
2312 int w0 = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask);
2313 int dst = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask);
2314 int result = 0;
2315
2316 if (w1 == 0 && w0 == 0)
2317 return 0;
2318
2319 if (((1 << mmod) & (P ? 0x313 : 0x1b57)) == 0)
2320 return 0;
2321
2322 if (w1)
2323 {
2324 if (P)
2325 return DREG_MASK (dst | 1);
2326 else
2327 return DREGH_MASK (dst);
2328 }
2329
2330 if (w0)
2331 {
2332 if (P)
2333 return DREG_MASK (dst);
2334 else
2335 return DREGL_MASK (dst);
2336 }
2337
2338 return result;
2339}
2340
2341static int
2342decode_dsp32alu_0 (int iw0, int iw1)
2343{
2344 /* dsp32alu
2345 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2346 | 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............|
2347 |.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......|
2348 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2349 int s = ((iw1 >> DSP32Alu_s_bits) & DSP32Alu_s_mask);
2350 int x = ((iw1 >> DSP32Alu_x_bits) & DSP32Alu_x_mask);
2351 int aop = ((iw1 >> DSP32Alu_aop_bits) & DSP32Alu_aop_mask);
2352 int dst0 = ((iw1 >> DSP32Alu_dst0_bits) & DSP32Alu_dst0_mask);
2353 int dst1 = ((iw1 >> DSP32Alu_dst1_bits) & DSP32Alu_dst1_mask);
2354 int HL = ((iw0 >> (DSP32Alu_HL_bits - 16)) & DSP32Alu_HL_mask);
2355 int aopcde = ((iw0 >> (DSP32Alu_aopcde_bits - 16)) & DSP32Alu_aopcde_mask);
2356
2357 if (aop == 0 && aopcde == 9 && s == 0)
2358 return 0;
2359 else if (aop == 2 && aopcde == 9 && HL == 0 && s == 0)
2360 return 0;
2361 else if (aop >= x * 2 && aopcde == 5)
2362 return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2363 else if (HL == 0 && aopcde == 2)
2364 return DREGL_MASK (dst0);
2365 else if (HL == 1 && aopcde == 2)
2366 return DREGH_MASK (dst0);
2367 else if (HL == 0 && aopcde == 3)
2368 return DREGL_MASK (dst0);
2369 else if (HL == 1 && aopcde == 3)
2370 return DREGH_MASK (dst0);
2371
2372 else if (aop == 0 && aopcde == 9 && s == 1)
2373 return 0;
2374 else if (aop == 1 && aopcde == 9 && s == 0)
2375 return 0;
2376 else if (aop == 2 && aopcde == 9 && s == 1)
2377 return 0;
2378 else if (aop == 3 && aopcde == 9 && s == 0)
2379 return 0;
2380 else if (aopcde == 8)
2381 return 0;
2382 else if (aop == 0 && aopcde == 11)
2383 return DREG_MASK (dst0);
2384 else if (aop == 1 && aopcde == 11)
2385 return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2386 else if (aopcde == 11)
2387 return 0;
2388 else if (aopcde == 22)
2389 return DREG_MASK (dst0);
2390
2391 else if ((aop == 0 || aop == 1) && aopcde == 14)
2392 return 0;
2393 else if (aop == 3 && HL == 0 && aopcde == 14)
2394 return 0;
2395
2396 else if (aop == 3 && HL == 0 && aopcde == 15)
2397 return DREG_MASK (dst0);
2398
2399 else if (aop == 1 && aopcde == 16)
2400 return 0;
2401
2402 else if (aop == 0 && aopcde == 16)
2403 return 0;
2404
2405 else if (aop == 3 && HL == 0 && aopcde == 16)
2406 return 0;
2407
2408 else if (aop == 3 && HL == 0 && aopcde == 7)
2409 return DREG_MASK (dst0);
2410 else if ((aop == 0 || aop == 1 || aop == 2) && aopcde == 7)
2411 return DREG_MASK (dst0);
2412
2413 else if (aop == 0 && aopcde == 12)
2414 return DREG_MASK (dst0);
2415 else if (aop == 1 && aopcde == 12)
2416 return DREG_MASK (dst0) | DREG_MASK (dst1);
2417 else if (aop == 3 && aopcde == 12)
2418 return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2419
2420 else if (aopcde == 0)
2421 return DREG_MASK (dst0);
2422 else if (aopcde == 1)
2423 return DREG_MASK (dst0) | DREG_MASK (dst1);
2424
2425 else if (aop == 0 && aopcde == 10)
2426 return DREGL_MASK (dst0);
2427 else if (aop == 1 && aopcde == 10)
2428 return DREGL_MASK (dst0);
2429
2430 else if ((aop == 1 || aop == 0) && aopcde == 4)
2431 return DREG_MASK (dst0);
2432 else if (aop == 2 && aopcde == 4)
2433 return DREG_MASK (dst0) | DREG_MASK (dst1);
2434
2435 else if (aop == 0 && aopcde == 17)
2436 return DREG_MASK (dst0) | DREG_MASK (dst1);
2437 else if (aop == 1 && aopcde == 17)
2438 return DREG_MASK (dst0) | DREG_MASK (dst1);
2439 else if (aop == 0 && aopcde == 18)
2440 return 0;
2441 else if (aop == 3 && aopcde == 18)
2442 return 0;
2443
2444 else if ((aop == 0 || aop == 1 || aop == 2) && aopcde == 6)
2445 return DREG_MASK (dst0);
2446
2447 else if ((aop == 0 || aop == 1) && aopcde == 20)
2448 return DREG_MASK (dst0);
2449
2450 else if ((aop == 0 || aop == 1) && aopcde == 21)
2451 return DREG_MASK (dst0) | DREG_MASK (dst1);
2452
2453 else if (aop == 0 && aopcde == 23 && HL == 1)
2454 return DREG_MASK (dst0);
2455 else if (aop == 0 && aopcde == 23 && HL == 0)
2456 return DREG_MASK (dst0);
2457
2458 else if (aop == 0 && aopcde == 24)
2459 return DREG_MASK (dst0);
ee9e7c78 2460 else if (aop == 1 && aopcde == 24)
d55cb1c5
BS
2461 return DREG_MASK (dst0) | DREG_MASK (dst1);
2462 else if (aopcde == 13)
2463 return DREG_MASK (dst0) | DREG_MASK (dst1);
2464 else
2465 return 0;
2466
2467 return 4;
2468}
2469
2470static int
2471decode_dsp32shift_0 (int iw0, int iw1)
2472{
2473 /* dsp32shift
2474 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2475 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............|
2476 |.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......|
2477 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2478 int HLs = ((iw1 >> DSP32Shift_HLs_bits) & DSP32Shift_HLs_mask);
2479 int sop = ((iw1 >> DSP32Shift_sop_bits) & DSP32Shift_sop_mask);
2480 int src0 = ((iw1 >> DSP32Shift_src0_bits) & DSP32Shift_src0_mask);
2481 int src1 = ((iw1 >> DSP32Shift_src1_bits) & DSP32Shift_src1_mask);
2482 int dst0 = ((iw1 >> DSP32Shift_dst0_bits) & DSP32Shift_dst0_mask);
2483 int sopcde = ((iw0 >> (DSP32Shift_sopcde_bits - 16)) & DSP32Shift_sopcde_mask);
2484
2485 if (sop == 0 && sopcde == 0)
2486 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2487 else if (sop == 1 && sopcde == 0)
2488 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2489 else if (sop == 2 && sopcde == 0)
2490 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2491 else if (sop == 0 && sopcde == 3)
2492 return 0;
2493 else if (sop == 1 && sopcde == 3)
2494 return 0;
2495 else if (sop == 2 && sopcde == 3)
2496 return 0;
2497 else if (sop == 3 && sopcde == 3)
2498 return DREG_MASK (dst0);
2499 else if (sop == 0 && sopcde == 1)
2500 return DREG_MASK (dst0);
2501 else if (sop == 1 && sopcde == 1)
2502 return DREG_MASK (dst0);
2503 else if (sop == 2 && sopcde == 1)
2504 return DREG_MASK (dst0);
2505 else if (sopcde == 2)
2506 return DREG_MASK (dst0);
2507 else if (sopcde == 4)
2508 return DREG_MASK (dst0);
2509 else if (sop == 0 && sopcde == 5)
2510 return DREGL_MASK (dst0);
2511 else if (sop == 1 && sopcde == 5)
2512 return DREGL_MASK (dst0);
2513 else if (sop == 2 && sopcde == 5)
2514 return DREGL_MASK (dst0);
2515 else if (sop == 0 && sopcde == 6)
2516 return DREGL_MASK (dst0);
2517 else if (sop == 1 && sopcde == 6)
2518 return DREGL_MASK (dst0);
2519 else if (sop == 3 && sopcde == 6)
2520 return DREGL_MASK (dst0);
2521 else if (sop == 0 && sopcde == 7)
2522 return DREGL_MASK (dst0);
2523 else if (sop == 1 && sopcde == 7)
2524 return DREGL_MASK (dst0);
2525 else if (sop == 2 && sopcde == 7)
2526 return DREGL_MASK (dst0);
2527 else if (sop == 3 && sopcde == 7)
2528 return DREGL_MASK (dst0);
2529 else if (sop == 0 && sopcde == 8)
2530 return DREG_MASK (src0) | DREG_MASK (src1);
2531#if 0
2532 {
2533 OUTS (outf, "BITMUX (");
2534 OUTS (outf, dregs (src0));
2535 OUTS (outf, ", ");
2536 OUTS (outf, dregs (src1));
2537 OUTS (outf, ", A0) (ASR)");
2538 }
2539#endif
2540 else if (sop == 1 && sopcde == 8)
2541 return DREG_MASK (src0) | DREG_MASK (src1);
2542#if 0
2543 {
2544 OUTS (outf, "BITMUX (");
2545 OUTS (outf, dregs (src0));
2546 OUTS (outf, ", ");
2547 OUTS (outf, dregs (src1));
2548 OUTS (outf, ", A0) (ASL)");
2549 }
2550#endif
2551 else if (sopcde == 9)
2552 return sop < 2 ? DREGL_MASK (dst0) : DREG_MASK (dst0);
2553 else if (sopcde == 10)
2554 return DREG_MASK (dst0);
2555 else if (sop == 0 && sopcde == 11)
2556 return DREGL_MASK (dst0);
2557 else if (sop == 1 && sopcde == 11)
2558 return DREGL_MASK (dst0);
2559 else if (sop == 0 && sopcde == 12)
2560 return 0;
2561 else if (sop == 1 && sopcde == 12)
2562 return DREGL_MASK (dst0);
2563 else if (sop == 0 && sopcde == 13)
2564 return DREG_MASK (dst0);
2565 else if (sop == 1 && sopcde == 13)
2566 return DREG_MASK (dst0);
2567 else if (sop == 2 && sopcde == 13)
2568 return DREG_MASK (dst0);
2569
2570 abort ();
2571}
2572
2573static int
2574decode_dsp32shiftimm_0 (int iw0, int iw1)
2575{
2576 /* dsp32shiftimm
2577 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2578 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............|
2579 |.sop...|.HLs...|.dst0......|.immag.................|.src1......|
2580 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2581 int sop = ((iw1 >> DSP32ShiftImm_sop_bits) & DSP32ShiftImm_sop_mask);
2582 int bit8 = ((iw1 >> 8) & 0x1);
2583 int dst0 = ((iw1 >> DSP32ShiftImm_dst0_bits) & DSP32ShiftImm_dst0_mask);
2584 int sopcde = ((iw0 >> (DSP32ShiftImm_sopcde_bits - 16)) & DSP32ShiftImm_sopcde_mask);
2585 int HLs = ((iw1 >> DSP32ShiftImm_HLs_bits) & DSP32ShiftImm_HLs_mask);
2586
2587
2588 if (sop == 0 && sopcde == 0)
2589 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2590 else if (sop == 1 && sopcde == 0 && bit8 == 0)
2591 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2592 else if (sop == 1 && sopcde == 0 && bit8 == 1)
2593 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2594 else if (sop == 2 && sopcde == 0 && bit8 == 0)
2595 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2596 else if (sop == 2 && sopcde == 0 && bit8 == 1)
2597 return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2598 else if (sop == 2 && sopcde == 3 && HLs == 1)
2599 return 0;
2600 else if (sop == 0 && sopcde == 3 && HLs == 0 && bit8 == 0)
2601 return 0;
2602 else if (sop == 0 && sopcde == 3 && HLs == 0 && bit8 == 1)
2603 return 0;
2604 else if (sop == 0 && sopcde == 3 && HLs == 1 && bit8 == 0)
2605 return 0;
2606 else if (sop == 0 && sopcde == 3 && HLs == 1 && bit8 == 1)
2607 return 0;
2608 else if (sop == 1 && sopcde == 3 && HLs == 0)
2609 return 0;
2610 else if (sop == 1 && sopcde == 3 && HLs == 1)
2611 return 0;
2612 else if (sop == 2 && sopcde == 3 && HLs == 0)
2613 return 0;
2614 else if (sop == 1 && sopcde == 1 && bit8 == 0)
2615 return DREG_MASK (dst0);
2616 else if (sop == 1 && sopcde == 1 && bit8 == 1)
2617 return DREG_MASK (dst0);
2618 else if (sop == 2 && sopcde == 1 && bit8 == 1)
2619 return DREG_MASK (dst0);
2620 else if (sop == 2 && sopcde == 1 && bit8 == 0)
2621 return DREG_MASK (dst0);
2622 else if (sop == 0 && sopcde == 1)
2623 return DREG_MASK (dst0);
2624 else if (sop == 1 && sopcde == 2)
2625 return DREG_MASK (dst0);
2626 else if (sop == 2 && sopcde == 2 && bit8 == 1)
2627 return DREG_MASK (dst0);
2628 else if (sop == 2 && sopcde == 2 && bit8 == 0)
2629 return DREG_MASK (dst0);
2630 else if (sop == 3 && sopcde == 2)
2631 return DREG_MASK (dst0);
2632 else if (sop == 0 && sopcde == 2)
2633 return DREG_MASK (dst0);
2634
2635 abort ();
2636}
2637
2638int
2639insn_regmask (int iw0, int iw1)
2640{
2641 if ((iw0 & 0xf7ff) == 0xc003 && iw1 == 0x1800)
2642 return 0; /* MNOP */
2643 else if ((iw0 & 0xff00) == 0x0000)
2644 return decode_ProgCtrl_0 (iw0);
2645 else if ((iw0 & 0xffc0) == 0x0240)
2646 abort ();
2647 else if ((iw0 & 0xff80) == 0x0100)
2648 abort ();
2649 else if ((iw0 & 0xfe00) == 0x0400)
2650 abort ();
2651 else if ((iw0 & 0xfe00) == 0x0600)
2652 abort ();
2653 else if ((iw0 & 0xf800) == 0x0800)
2654 abort ();
2655 else if ((iw0 & 0xffe0) == 0x0200)
2656 abort ();
2657 else if ((iw0 & 0xff00) == 0x0300)
2658 abort ();
2659 else if ((iw0 & 0xf000) == 0x1000)
2660 abort ();
2661 else if ((iw0 & 0xf000) == 0x2000)
2662 abort ();
2663 else if ((iw0 & 0xf000) == 0x3000)
2664 abort ();
2665 else if ((iw0 & 0xfc00) == 0x4000)
2666 abort ();
2667 else if ((iw0 & 0xfe00) == 0x4400)
2668 abort ();
2669 else if ((iw0 & 0xf800) == 0x4800)
2670 abort ();
2671 else if ((iw0 & 0xf000) == 0x5000)
2672 abort ();
2673 else if ((iw0 & 0xf800) == 0x6000)
2674 abort ();
2675 else if ((iw0 & 0xf800) == 0x6800)
2676 abort ();
2677 else if ((iw0 & 0xf000) == 0x8000)
2678 return decode_LDSTpmod_0 (iw0);
2679 else if ((iw0 & 0xff60) == 0x9e60)
2680 return decode_dagMODim_0 (iw0);
2681 else if ((iw0 & 0xfff0) == 0x9f60)
2682 return decode_dagMODik_0 (iw0);
2683 else if ((iw0 & 0xfc00) == 0x9c00)
2684 return decode_dspLDST_0 (iw0);
2685 else if ((iw0 & 0xf000) == 0x9000)
2686 return decode_LDST_0 (iw0);
2687 else if ((iw0 & 0xfc00) == 0xb800)
2688 return decode_LDSTiiFP_0 (iw0);
2689 else if ((iw0 & 0xe000) == 0xA000)
2690 return decode_LDSTii_0 (iw0);
2691 else if ((iw0 & 0xff80) == 0xe080 && (iw1 & 0x0C00) == 0x0000)
2692 abort ();
2693 else if ((iw0 & 0xff00) == 0xe100 && (iw1 & 0x0000) == 0x0000)
2694 abort ();
2695 else if ((iw0 & 0xfe00) == 0xe200 && (iw1 & 0x0000) == 0x0000)
2696 abort ();
2697 else if ((iw0 & 0xfc00) == 0xe400 && (iw1 & 0x0000) == 0x0000)
2698 abort ();
2699 else if ((iw0 & 0xfffe) == 0xe800 && (iw1 & 0x0000) == 0x0000)
2700 abort ();
2701 else if ((iw0 & 0xf600) == 0xc000 && (iw1 & 0x0000) == 0x0000)
2702 return decode_dsp32mac_0 (iw0, iw1);
2703 else if ((iw0 & 0xf600) == 0xc200 && (iw1 & 0x0000) == 0x0000)
2704 return decode_dsp32mult_0 (iw0, iw1);
2705 else if ((iw0 & 0xf7c0) == 0xc400 && (iw1 & 0x0000) == 0x0000)
2706 return decode_dsp32alu_0 (iw0, iw1);
2707 else if ((iw0 & 0xf780) == 0xc600 && (iw1 & 0x01c0) == 0x0000)
2708 return decode_dsp32shift_0 (iw0, iw1);
2709 else if ((iw0 & 0xf780) == 0xc680 && (iw1 & 0x0000) == 0x0000)
2710 return decode_dsp32shiftimm_0 (iw0, iw1);
2711 else if ((iw0 & 0xff00) == 0xf800)
2712 abort ();
2713 else if ((iw0 & 0xFFC0) == 0xf000 && (iw1 & 0x0000) == 0x0000)
2714 abort ();
2715
2716 abort ();
2717}