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