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