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