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