1 /* tc-bfin.c -- Assembler for the ADI Blackfin.
2 Copyright (C) 2005-2016 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to the Free
18 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
22 #include "struc-symbol.h"
23 #include "bfin-defs.h"
25 #include "safe-ctype.h"
27 #include "dwarf2dbg.h"
30 #include "elf/common.h"
33 extern int yyparse (void);
34 struct yy_buffer_state
;
35 typedef struct yy_buffer_state
*YY_BUFFER_STATE
;
36 extern YY_BUFFER_STATE
yy_scan_string (const char *yy_str
);
37 extern void yy_delete_buffer (YY_BUFFER_STATE b
);
38 static parse_state
parse (char *line
);
40 /* Global variables. */
41 struct bfin_insn
*insn
;
44 extern struct obstack mempool
;
47 /* Flags to set in the elf header */
48 #define DEFAULT_FLAGS 0
51 # define DEFAULT_FDPIC EF_BFIN_FDPIC
53 # define DEFAULT_FDPIC 0
56 static flagword bfin_flags
= DEFAULT_FLAGS
| DEFAULT_FDPIC
;
57 static const char *bfin_pic_flag
= DEFAULT_FDPIC
? "-mfdpic" : (const char *)0;
59 /* Blackfin specific function to handle FD-PIC pointer initializations. */
62 bfin_pic_ptr (int nbytes
)
70 #ifdef md_flush_pending_output
71 md_flush_pending_output ();
74 if (is_it_end_of_statement ())
76 demand_empty_rest_of_line ();
81 md_cons_align (nbytes
);
86 bfd_reloc_code_real_type reloc_type
= BFD_RELOC_BFIN_FUNCDESC
;
88 if (strncasecmp (input_line_pointer
, "funcdesc(", 9) == 0)
90 input_line_pointer
+= 9;
92 if (*input_line_pointer
== ')')
95 as_bad (_("missing ')'"));
98 error ("missing funcdesc in picptr");
102 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &exp
, 0,
105 while (*input_line_pointer
++ == ',');
107 input_line_pointer
--; /* Put terminator back into stream. */
108 demand_empty_rest_of_line ();
112 bfin_s_bss (int ignore ATTRIBUTE_UNUSED
)
116 temp
= get_absolute_expression ();
117 subseg_set (bss_section
, (subsegT
) temp
);
118 demand_empty_rest_of_line ();
121 const pseudo_typeS md_pseudo_table
[] = {
122 {"align", s_align_bytes
, 0},
125 {"picptr", bfin_pic_ptr
, 4},
126 {"code", obj_elf_section
, 0},
131 {"pdata", s_ignore
, 0},
132 {"var", s_ignore
, 0},
133 {"bss", bfin_s_bss
, 0},
137 /* Characters that are used to denote comments and line separators. */
138 const char comment_chars
[] = "#";
139 const char line_comment_chars
[] = "#";
140 const char line_separator_chars
[] = ";";
142 /* Characters that can be used to separate the mantissa from the
143 exponent in floating point numbers. */
144 const char EXP_CHARS
[] = "eE";
146 /* Characters that mean this number is a floating point constant.
147 As in 0f12.456 or 0d1.2345e12. */
148 const char FLT_CHARS
[] = "fFdDxX";
150 typedef enum bfin_cpu_type
187 bfin_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. */
191 int bfin_si_revision
;
193 unsigned int bfin_anomaly_checks
= 0;
200 unsigned int anomaly_checks
;
203 struct bfin_cpu bfin_cpus
[] =
205 {"bf504", BFIN_CPU_BF504
, 0x0000, AC_05000074
},
207 {"bf506", BFIN_CPU_BF506
, 0x0000, AC_05000074
},
209 {"bf512", BFIN_CPU_BF512
, 0x0002, AC_05000074
},
210 {"bf512", BFIN_CPU_BF512
, 0x0001, AC_05000074
},
211 {"bf512", BFIN_CPU_BF512
, 0x0000, AC_05000074
},
213 {"bf514", BFIN_CPU_BF514
, 0x0002, AC_05000074
},
214 {"bf514", BFIN_CPU_BF514
, 0x0001, AC_05000074
},
215 {"bf514", BFIN_CPU_BF514
, 0x0000, AC_05000074
},
217 {"bf516", BFIN_CPU_BF516
, 0x0002, AC_05000074
},
218 {"bf516", BFIN_CPU_BF516
, 0x0001, AC_05000074
},
219 {"bf516", BFIN_CPU_BF516
, 0x0000, AC_05000074
},
221 {"bf518", BFIN_CPU_BF518
, 0x0002, AC_05000074
},
222 {"bf518", BFIN_CPU_BF518
, 0x0001, AC_05000074
},
223 {"bf518", BFIN_CPU_BF518
, 0x0000, AC_05000074
},
225 {"bf522", BFIN_CPU_BF522
, 0x0002, AC_05000074
},
226 {"bf522", BFIN_CPU_BF522
, 0x0001, AC_05000074
},
227 {"bf522", BFIN_CPU_BF522
, 0x0000, AC_05000074
},
229 {"bf523", BFIN_CPU_BF523
, 0x0002, AC_05000074
},
230 {"bf523", BFIN_CPU_BF523
, 0x0001, AC_05000074
},
231 {"bf523", BFIN_CPU_BF523
, 0x0000, AC_05000074
},
233 {"bf524", BFIN_CPU_BF524
, 0x0002, AC_05000074
},
234 {"bf524", BFIN_CPU_BF524
, 0x0001, AC_05000074
},
235 {"bf524", BFIN_CPU_BF524
, 0x0000, AC_05000074
},
237 {"bf525", BFIN_CPU_BF525
, 0x0002, AC_05000074
},
238 {"bf525", BFIN_CPU_BF525
, 0x0001, AC_05000074
},
239 {"bf525", BFIN_CPU_BF525
, 0x0000, AC_05000074
},
241 {"bf526", BFIN_CPU_BF526
, 0x0002, AC_05000074
},
242 {"bf526", BFIN_CPU_BF526
, 0x0001, AC_05000074
},
243 {"bf526", BFIN_CPU_BF526
, 0x0000, AC_05000074
},
245 {"bf527", BFIN_CPU_BF527
, 0x0002, AC_05000074
},
246 {"bf527", BFIN_CPU_BF527
, 0x0001, AC_05000074
},
247 {"bf527", BFIN_CPU_BF527
, 0x0000, AC_05000074
},
249 {"bf531", BFIN_CPU_BF531
, 0x0006, AC_05000074
},
250 {"bf531", BFIN_CPU_BF531
, 0x0005, AC_05000074
},
251 {"bf531", BFIN_CPU_BF531
, 0x0004, AC_05000074
},
252 {"bf531", BFIN_CPU_BF531
, 0x0003, AC_05000074
},
254 {"bf532", BFIN_CPU_BF532
, 0x0006, AC_05000074
},
255 {"bf532", BFIN_CPU_BF532
, 0x0005, AC_05000074
},
256 {"bf532", BFIN_CPU_BF532
, 0x0004, AC_05000074
},
257 {"bf532", BFIN_CPU_BF532
, 0x0003, AC_05000074
},
259 {"bf533", BFIN_CPU_BF533
, 0x0006, AC_05000074
},
260 {"bf533", BFIN_CPU_BF533
, 0x0005, AC_05000074
},
261 {"bf533", BFIN_CPU_BF533
, 0x0004, AC_05000074
},
262 {"bf533", BFIN_CPU_BF533
, 0x0003, AC_05000074
},
264 {"bf534", BFIN_CPU_BF534
, 0x0003, AC_05000074
},
265 {"bf534", BFIN_CPU_BF534
, 0x0002, AC_05000074
},
266 {"bf534", BFIN_CPU_BF534
, 0x0001, AC_05000074
},
268 {"bf536", BFIN_CPU_BF536
, 0x0003, AC_05000074
},
269 {"bf536", BFIN_CPU_BF536
, 0x0002, AC_05000074
},
270 {"bf536", BFIN_CPU_BF536
, 0x0001, AC_05000074
},
272 {"bf537", BFIN_CPU_BF537
, 0x0003, AC_05000074
},
273 {"bf537", BFIN_CPU_BF537
, 0x0002, AC_05000074
},
274 {"bf537", BFIN_CPU_BF537
, 0x0001, AC_05000074
},
276 {"bf538", BFIN_CPU_BF538
, 0x0005, AC_05000074
},
277 {"bf538", BFIN_CPU_BF538
, 0x0004, AC_05000074
},
278 {"bf538", BFIN_CPU_BF538
, 0x0003, AC_05000074
},
279 {"bf538", BFIN_CPU_BF538
, 0x0002, AC_05000074
},
281 {"bf539", BFIN_CPU_BF539
, 0x0005, AC_05000074
},
282 {"bf539", BFIN_CPU_BF539
, 0x0004, AC_05000074
},
283 {"bf539", BFIN_CPU_BF539
, 0x0003, AC_05000074
},
284 {"bf539", BFIN_CPU_BF539
, 0x0002, AC_05000074
},
286 {"bf542m", BFIN_CPU_BF542M
, 0x0003, AC_05000074
},
288 {"bf542", BFIN_CPU_BF542
, 0x0004, AC_05000074
},
289 {"bf542", BFIN_CPU_BF542
, 0x0002, AC_05000074
},
290 {"bf542", BFIN_CPU_BF542
, 0x0001, AC_05000074
},
291 {"bf542", BFIN_CPU_BF542
, 0x0000, AC_05000074
},
293 {"bf544m", BFIN_CPU_BF544M
, 0x0003, AC_05000074
},
295 {"bf544", BFIN_CPU_BF544
, 0x0004, AC_05000074
},
296 {"bf544", BFIN_CPU_BF544
, 0x0002, AC_05000074
},
297 {"bf544", BFIN_CPU_BF544
, 0x0001, AC_05000074
},
298 {"bf544", BFIN_CPU_BF544
, 0x0000, AC_05000074
},
300 {"bf547m", BFIN_CPU_BF547M
, 0x0003, AC_05000074
},
302 {"bf547", BFIN_CPU_BF547
, 0x0004, AC_05000074
},
303 {"bf547", BFIN_CPU_BF547
, 0x0002, AC_05000074
},
304 {"bf547", BFIN_CPU_BF547
, 0x0001, AC_05000074
},
305 {"bf547", BFIN_CPU_BF547
, 0x0000, AC_05000074
},
307 {"bf548m", BFIN_CPU_BF548M
, 0x0003, AC_05000074
},
309 {"bf548", BFIN_CPU_BF548
, 0x0004, AC_05000074
},
310 {"bf548", BFIN_CPU_BF548
, 0x0002, AC_05000074
},
311 {"bf548", BFIN_CPU_BF548
, 0x0001, AC_05000074
},
312 {"bf548", BFIN_CPU_BF548
, 0x0000, AC_05000074
},
314 {"bf549m", BFIN_CPU_BF549M
, 0x0003, AC_05000074
},
316 {"bf549", BFIN_CPU_BF549
, 0x0004, AC_05000074
},
317 {"bf549", BFIN_CPU_BF549
, 0x0002, AC_05000074
},
318 {"bf549", BFIN_CPU_BF549
, 0x0001, AC_05000074
},
319 {"bf549", BFIN_CPU_BF549
, 0x0000, AC_05000074
},
321 {"bf561", BFIN_CPU_BF561
, 0x0005, AC_05000074
},
322 {"bf561", BFIN_CPU_BF561
, 0x0003, AC_05000074
},
323 {"bf561", BFIN_CPU_BF561
, 0x0002, AC_05000074
},
325 {"bf592", BFIN_CPU_BF592
, 0x0001, AC_05000074
},
326 {"bf592", BFIN_CPU_BF592
, 0x0000, AC_05000074
},
331 /* Define bfin-specific command-line options (there are none). */
332 const char *md_shortopts
= "";
334 #define OPTION_FDPIC (OPTION_MD_BASE)
335 #define OPTION_NOPIC (OPTION_MD_BASE + 1)
336 #define OPTION_MCPU (OPTION_MD_BASE + 2)
338 struct option md_longopts
[] =
340 { "mcpu", required_argument
, NULL
, OPTION_MCPU
},
341 { "mfdpic", no_argument
, NULL
, OPTION_FDPIC
},
342 { "mnopic", no_argument
, NULL
, OPTION_NOPIC
},
343 { "mno-fdpic", no_argument
, NULL
, OPTION_NOPIC
},
344 { NULL
, no_argument
, NULL
, 0 },
347 size_t md_longopts_size
= sizeof (md_longopts
);
351 md_parse_option (int c ATTRIBUTE_UNUSED
, const char *arg ATTRIBUTE_UNUSED
)
364 while ((p
= bfin_cpus
[i
].name
) != NULL
)
366 if (strncmp (arg
, p
, strlen (p
)) == 0)
372 as_fatal ("-mcpu=%s is not valid", arg
);
374 bfin_cpu_type
= bfin_cpus
[i
].type
;
376 q
= arg
+ strlen (p
);
380 bfin_si_revision
= bfin_cpus
[i
].si_revision
;
381 bfin_anomaly_checks
|= bfin_cpus
[i
].anomaly_checks
;
383 else if (strcmp (q
, "-none") == 0)
384 bfin_si_revision
= -1;
385 else if (strcmp (q
, "-any") == 0)
387 bfin_si_revision
= 0xffff;
388 while (bfin_cpus
[i
].type
== bfin_cpu_type
)
390 bfin_anomaly_checks
|= bfin_cpus
[i
].anomaly_checks
;
396 unsigned int si_major
, si_minor
;
399 rev_len
= strlen (q
);
401 if (sscanf (q
, "-%u.%u%n", &si_major
, &si_minor
, &n
) != 2
403 || si_major
> 0xff || si_minor
> 0xff)
405 invalid_silicon_revision
:
406 as_fatal ("-mcpu=%s has invalid silicon revision", arg
);
409 bfin_si_revision
= (si_major
<< 8) | si_minor
;
411 while (bfin_cpus
[i
].type
== bfin_cpu_type
412 && bfin_cpus
[i
].si_revision
!= bfin_si_revision
)
415 if (bfin_cpus
[i
].type
!= bfin_cpu_type
)
416 goto invalid_silicon_revision
;
418 bfin_anomaly_checks
|= bfin_cpus
[i
].anomaly_checks
;
425 bfin_flags
|= EF_BFIN_FDPIC
;
426 bfin_pic_flag
= "-mfdpic";
430 bfin_flags
&= ~(EF_BFIN_FDPIC
);
439 md_show_usage (FILE * stream
)
441 fprintf (stream
, _(" Blackfin specific assembler options:\n"));
442 fprintf (stream
, _(" -mcpu=<cpu[-sirevision]> specify the name of the target CPU\n"));
443 fprintf (stream
, _(" -mfdpic assemble for the FDPIC ABI\n"));
444 fprintf (stream
, _(" -mno-fdpic/-mnopic disable -mfdpic\n"));
447 /* Perform machine-specific initializations. */
451 /* Set the ELF flags if desired. */
453 bfd_set_private_flags (stdoutput
, bfin_flags
);
455 /* Set the default machine type. */
456 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_bfin
, 0))
457 as_warn (_("Could not set architecture and machine."));
459 /* Ensure that lines can begin with '(', for multiple
460 register stack pops. */
461 lex_type
['('] = LEX_BEGIN_NAME
;
464 record_alignment (text_section
, 2);
465 record_alignment (data_section
, 2);
466 record_alignment (bss_section
, 2);
470 obstack_init (&mempool
);
473 extern int debug_codeselection
;
474 debug_codeselection
= 1;
480 /* Perform the main parsing, and assembly of the input here. Also,
481 call the required routines for alignment and fixups here.
482 This is called for every line that contains real assembly code. */
485 md_assemble (char *line
)
489 struct bfin_insn
*tmp_insn
;
491 static size_t buffer_len
= 0;
492 static char *current_inputline
;
496 if (len
+ 2 > buffer_len
)
498 buffer_len
= len
+ 40;
499 current_inputline
= XRESIZEVEC (char, current_inputline
, buffer_len
);
501 memcpy (current_inputline
, line
, len
);
502 current_inputline
[len
] = ';';
503 current_inputline
[len
+ 1] = '\0';
505 state
= parse (current_inputline
);
506 if (state
== NO_INSN_GENERATED
)
509 for (insn_size
= 0, tmp_insn
= insn
; tmp_insn
; tmp_insn
= tmp_insn
->next
)
510 if (!tmp_insn
->reloc
|| !tmp_insn
->exp
->symbol
)
514 toP
= frag_more (insn_size
);
516 last_insn_size
= insn_size
;
523 if (insn
->reloc
&& insn
->exp
->symbol
)
525 char *prev_toP
= toP
- 2;
528 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
529 case BFD_RELOC_24_PCREL
:
530 case BFD_RELOC_BFIN_16_LOW
:
531 case BFD_RELOC_BFIN_16_HIGH
:
538 /* Following if condition checks for the arithmetic relocations.
539 If the case then it doesn't required to generate the code.
540 It has been assumed that, their ID will be contiguous. */
541 if ((BFD_ARELOC_BFIN_PUSH
<= insn
->reloc
542 && BFD_ARELOC_BFIN_COMP
>= insn
->reloc
)
543 || insn
->reloc
== BFD_RELOC_BFIN_16_IMM
)
547 if (insn
->reloc
== BFD_ARELOC_BFIN_CONST
548 || insn
->reloc
== BFD_ARELOC_BFIN_PUSH
)
552 (prev_toP
- frag_now
->fr_literal
),
553 size
, insn
->exp
->symbol
, insn
->exp
->value
,
554 insn
->pcrel
, insn
->reloc
);
558 md_number_to_chars (toP
, insn
->value
, 2);
564 printf (" %02x%02x", ((unsigned char *) &insn
->value
)[0],
565 ((unsigned char *) &insn
->value
)[1]);
571 dwarf2_emit_insn (insn_size
);
574 while (*line
++ != '\0')
576 bump_line_counters ();
579 /* Parse one line of instructions, and generate opcode for it.
580 To parse the line, YACC and LEX are used, because the instruction set
581 syntax doesn't confirm to the AT&T assembly syntax.
582 To call a YACC & LEX generated parser, we must provide the input via
583 a FILE stream, otherwise stdin is used by default. Below the input
584 to the function will be put into a temporary file, then the generated
585 parser uses the temporary file for parsing. */
591 YY_BUFFER_STATE buffstate
;
593 buffstate
= yy_scan_string (line
);
595 /* our lex requires setting the start state to keyword
596 every line as the first word may be a keyword.
597 Fixes a bug where we could not have keywords as labels. */
600 /* Call yyparse here. */
602 if (state
== SEMANTIC_ERROR
)
604 as_bad (_("Parse failed."));
608 yy_delete_buffer (buffstate
);
612 /* We need to handle various expressions properly.
613 Such as, [SP--] = 34, concerned by md_assemble(). */
616 md_operand (expressionS
* expressionP
)
618 if (*input_line_pointer
== '[')
620 as_tsktsk ("We found a '['!");
621 input_line_pointer
++;
622 expression (expressionP
);
626 /* Handle undefined symbols. */
628 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
630 return (symbolS
*) 0;
634 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
635 segT segment ATTRIBUTE_UNUSED
)
640 /* Convert from target byte order to host byte order. */
643 md_chars_to_number (char *val
, int n
)
647 for (retval
= 0; n
--;)
656 md_apply_fix (fixS
*fixP
, valueT
*valueP
, segT seg ATTRIBUTE_UNUSED
)
658 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
660 long value
= *valueP
;
663 switch (fixP
->fx_r_type
)
665 case BFD_RELOC_BFIN_GOT
:
666 case BFD_RELOC_BFIN_GOT17M4
:
667 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
668 fixP
->fx_no_overflow
= 1;
669 newval
= md_chars_to_number (where
, 2);
670 newval
|= 0x0 & 0x7f;
671 md_number_to_chars (where
, newval
, 2);
674 case BFD_RELOC_BFIN_10_PCREL
:
677 if (value
< -1024 || value
> 1022)
678 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
679 _("pcrel too far BFD_RELOC_BFIN_10"));
681 /* 11 bit offset even numbered, so we remove right bit. */
683 newval
= md_chars_to_number (where
, 2);
684 newval
|= value
& 0x03ff;
685 md_number_to_chars (where
, newval
, 2);
688 case BFD_RELOC_BFIN_12_PCREL_JUMP
:
689 case BFD_RELOC_BFIN_12_PCREL_JUMP_S
:
690 case BFD_RELOC_12_PCREL
:
694 if (value
< -4096 || value
> 4094)
695 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_12"));
696 /* 13 bit offset even numbered, so we remove right bit. */
698 newval
= md_chars_to_number (where
, 2);
699 newval
|= value
& 0xfff;
700 md_number_to_chars (where
, newval
, 2);
703 case BFD_RELOC_BFIN_16_LOW
:
704 case BFD_RELOC_BFIN_16_HIGH
:
705 fixP
->fx_done
= FALSE
;
708 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
709 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
710 case BFD_RELOC_24_PCREL
:
714 if (value
< -16777216 || value
> 16777214)
715 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_24"));
717 /* 25 bit offset even numbered, so we remove right bit. */
721 md_number_to_chars (where
- 2, value
>> 16, 1);
722 md_number_to_chars (where
, value
, 1);
723 md_number_to_chars (where
+ 1, value
>> 8, 1);
726 case BFD_RELOC_BFIN_5_PCREL
: /* LSETUP (a, b) : "a" */
729 if (value
< 4 || value
> 30)
730 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_5"));
732 newval
= md_chars_to_number (where
, 1);
733 newval
= (newval
& 0xf0) | (value
& 0xf);
734 md_number_to_chars (where
, newval
, 1);
737 case BFD_RELOC_BFIN_11_PCREL
: /* LSETUP (a, b) : "b" */
741 if (value
< 4 || value
> 2046)
742 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_11_PCREL"));
743 /* 11 bit unsigned even, so we remove right bit. */
745 newval
= md_chars_to_number (where
, 2);
746 newval
|= value
& 0x03ff;
747 md_number_to_chars (where
, newval
, 2);
751 if (value
< -0x80 || value
>= 0x7f)
752 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("rel too far BFD_RELOC_8"));
753 md_number_to_chars (where
, value
, 1);
756 case BFD_RELOC_BFIN_16_IMM
:
758 if (value
< -0x8000 || value
>= 0x7fff)
759 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("rel too far BFD_RELOC_16"));
760 md_number_to_chars (where
, value
, 2);
764 md_number_to_chars (where
, value
, 4);
767 case BFD_RELOC_BFIN_PLTPC
:
768 md_number_to_chars (where
, value
, 2);
771 case BFD_RELOC_BFIN_FUNCDESC
:
772 case BFD_RELOC_VTABLE_INHERIT
:
773 case BFD_RELOC_VTABLE_ENTRY
:
774 fixP
->fx_done
= FALSE
;
778 if ((BFD_ARELOC_BFIN_PUSH
> fixP
->fx_r_type
) || (BFD_ARELOC_BFIN_COMP
< fixP
->fx_r_type
))
780 fprintf (stderr
, "Relocation %d not handled in gas." " Contact support.\n", fixP
->fx_r_type
);
786 fixP
->fx_done
= TRUE
;
790 /* Round up a section size to the appropriate boundary. */
792 md_section_align (segT segment
, valueT size
)
794 int boundary
= bfd_get_section_alignment (stdoutput
, segment
);
795 return ((size
+ (1 << boundary
) - 1) & -(1 << boundary
));
800 md_atof (int type
, char * litP
, int * sizeP
)
802 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
806 /* If while processing a fixup, a reloc really needs to be created
807 then it is done here. */
810 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixp
)
814 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
815 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
816 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
817 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
819 reloc
->addend
= fixp
->fx_offset
;
820 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
822 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
824 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
825 /* xgettext:c-format. */
826 _("reloc %d not supported by object file format"),
827 (int) fixp
->fx_r_type
);
837 /* The location from which a PC relative jump should be calculated,
838 given a PC relative reloc. */
841 md_pcrel_from_section (fixS
*fixP
, segT sec
)
843 if (fixP
->fx_addsy
!= (symbolS
*) NULL
844 && (!S_IS_DEFINED (fixP
->fx_addsy
)
845 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
847 /* The symbol is undefined (or is defined but not in this section).
848 Let the linker figure it out. */
851 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
854 /* Return true if the fix can be handled by GAS, false if it must
855 be passed through to the linker. */
858 bfin_fix_adjustable (fixS
*fixP
)
860 switch (fixP
->fx_r_type
)
862 /* Adjust_reloc_syms doesn't know about the GOT. */
863 case BFD_RELOC_BFIN_GOT
:
864 case BFD_RELOC_BFIN_PLTPC
:
865 /* We need the symbol name for the VTABLE entries. */
866 case BFD_RELOC_VTABLE_INHERIT
:
867 case BFD_RELOC_VTABLE_ENTRY
:
875 /* Special extra functions that help bfin-parse.y perform its job. */
877 struct obstack mempool
;
880 conscode (INSTR_T head
, INSTR_T tail
)
889 conctcode (INSTR_T head
, INSTR_T tail
)
891 INSTR_T temp
= (head
);
902 note_reloc (INSTR_T code
, Expr_Node
* symbol
, int reloc
, int pcrel
)
904 /* Assert that the symbol is not an operator. */
905 gas_assert (symbol
->type
== Expr_Node_Reloc
);
907 return note_reloc1 (code
, symbol
->value
.s_value
, reloc
, pcrel
);
912 note_reloc1 (INSTR_T code
, const char *symbol
, int reloc
, int pcrel
)
915 code
->exp
= mkexpr (0, symbol_find_or_make (symbol
));
921 note_reloc2 (INSTR_T code
, const char *symbol
, int reloc
, int value
, int pcrel
)
924 code
->exp
= mkexpr (value
, symbol_find_or_make (symbol
));
930 gencode (unsigned long x
)
932 INSTR_T cell
= XOBNEW (&mempool
, struct bfin_insn
);
933 memset (cell
, 0, sizeof (struct bfin_insn
));
945 return obstack_alloc (&mempool
, n
);
949 Expr_Node_Create (Expr_Node_Type type
,
950 Expr_Node_Value value
,
951 Expr_Node
*Left_Child
,
952 Expr_Node
*Right_Child
)
956 Expr_Node
*node
= (Expr_Node
*) allocate (sizeof (Expr_Node
));
959 node
->Left_Child
= Left_Child
;
960 node
->Right_Child
= Right_Child
;
964 static const char *con
= ".__constant";
965 static const char *op
= ".__operator";
966 static INSTR_T
Expr_Node_Gen_Reloc_R (Expr_Node
* head
);
967 INSTR_T
Expr_Node_Gen_Reloc (Expr_Node
*head
, int parent_reloc
);
970 Expr_Node_Gen_Reloc (Expr_Node
* head
, int parent_reloc
)
972 /* Top level reloction expression generator VDSP style.
973 If the relocation is just by itself, generate one item
974 else generate this convoluted expression. */
976 INSTR_T note
= NULL_CODE
;
977 INSTR_T note1
= NULL_CODE
;
978 int pcrel
= 1; /* Is the parent reloc pcrelative?
979 This calculation here and HOWTO should match. */
983 /* If it's 32 bit quantity then 16bit code needs to be added. */
986 if (head
->type
== Expr_Node_Constant
)
988 /* If note1 is not null code, we have to generate a right
989 aligned value for the constant. Otherwise the reloc is
990 a part of the basic command and the yacc file
992 value
= head
->value
.i_value
;
994 switch (parent_reloc
)
996 /* Some relocations will need to allocate extra words. */
997 case BFD_RELOC_BFIN_16_IMM
:
998 case BFD_RELOC_BFIN_16_LOW
:
999 case BFD_RELOC_BFIN_16_HIGH
:
1000 note1
= conscode (gencode (value
), NULL_CODE
);
1003 case BFD_RELOC_BFIN_PLTPC
:
1004 note1
= conscode (gencode (value
), NULL_CODE
);
1008 case BFD_RELOC_BFIN_GOT
:
1009 case BFD_RELOC_BFIN_GOT17M4
:
1010 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
1011 note1
= conscode (gencode (value
), NULL_CODE
);
1014 case BFD_RELOC_24_PCREL
:
1015 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
1016 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
1017 /* These offsets are even numbered pcrel. */
1018 note1
= conscode (gencode (value
>> 1), NULL_CODE
);
1024 if (head
->type
== Expr_Node_Constant
)
1026 else if (head
->type
== Expr_Node_Reloc
)
1028 note
= note_reloc1 (gencode (0), head
->value
.s_value
, parent_reloc
, pcrel
);
1029 if (note1
!= NULL_CODE
)
1030 note
= conscode (note1
, note
);
1032 else if (head
->type
== Expr_Node_Binop
1033 && (head
->value
.op_value
== Expr_Op_Type_Add
1034 || head
->value
.op_value
== Expr_Op_Type_Sub
)
1035 && head
->Left_Child
->type
== Expr_Node_Reloc
1036 && head
->Right_Child
->type
== Expr_Node_Constant
)
1038 int val
= head
->Right_Child
->value
.i_value
;
1039 if (head
->value
.op_value
== Expr_Op_Type_Sub
)
1041 note
= conscode (note_reloc2 (gencode (0), head
->Left_Child
->value
.s_value
,
1042 parent_reloc
, val
, 0),
1044 if (note1
!= NULL_CODE
)
1045 note
= conscode (note1
, note
);
1049 /* Call the recursive function. */
1050 note
= note_reloc1 (gencode (0), op
, parent_reloc
, pcrel
);
1051 if (note1
!= NULL_CODE
)
1052 note
= conscode (note1
, note
);
1053 note
= conctcode (Expr_Node_Gen_Reloc_R (head
), note
);
1059 Expr_Node_Gen_Reloc_R (Expr_Node
* head
)
1067 case Expr_Node_Constant
:
1068 note
= conscode (note_reloc2 (gencode (0), con
, BFD_ARELOC_BFIN_CONST
, head
->value
.i_value
, 0), NULL_CODE
);
1070 case Expr_Node_Reloc
:
1071 note
= conscode (note_reloc (gencode (0), head
, BFD_ARELOC_BFIN_PUSH
, 0), NULL_CODE
);
1073 case Expr_Node_Binop
:
1074 note1
= conctcode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), Expr_Node_Gen_Reloc_R (head
->Right_Child
));
1075 switch (head
->value
.op_value
)
1077 case Expr_Op_Type_Add
:
1078 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_ADD
, 0), NULL_CODE
));
1080 case Expr_Op_Type_Sub
:
1081 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_SUB
, 0), NULL_CODE
));
1083 case Expr_Op_Type_Mult
:
1084 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MULT
, 0), NULL_CODE
));
1086 case Expr_Op_Type_Div
:
1087 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_DIV
, 0), NULL_CODE
));
1089 case Expr_Op_Type_Mod
:
1090 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MOD
, 0), NULL_CODE
));
1092 case Expr_Op_Type_Lshift
:
1093 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LSHIFT
, 0), NULL_CODE
));
1095 case Expr_Op_Type_Rshift
:
1096 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_RSHIFT
, 0), NULL_CODE
));
1098 case Expr_Op_Type_BAND
:
1099 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_AND
, 0), NULL_CODE
));
1101 case Expr_Op_Type_BOR
:
1102 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_OR
, 0), NULL_CODE
));
1104 case Expr_Op_Type_BXOR
:
1105 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_XOR
, 0), NULL_CODE
));
1107 case Expr_Op_Type_LAND
:
1108 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LAND
, 0), NULL_CODE
));
1110 case Expr_Op_Type_LOR
:
1111 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LOR
, 0), NULL_CODE
));
1114 fprintf (stderr
, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1119 case Expr_Node_Unop
:
1120 note1
= conscode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), NULL_CODE
);
1121 switch (head
->value
.op_value
)
1123 case Expr_Op_Type_NEG
:
1124 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_NEG
, 0), NULL_CODE
));
1126 case Expr_Op_Type_COMP
:
1127 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_COMP
, 0), NULL_CODE
));
1130 fprintf (stderr
, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1134 fprintf (stderr
, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__
, __LINE__
);
1139 /* Blackfin opcode generation. */
1141 /* These functions are called by the generated parser
1142 (from bfin-parse.y), the register type classification
1143 happens in bfin-lex.l. */
1145 #include "bfin-aux.h"
1146 #include "opcode/bfin.h"
1148 #define INIT(t) t c_code = init_##t
1149 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1150 #define ASSIGNF(x,f) c_code.opcode |= ((x & c_code.mask_##f)<<c_code.bits_##f)
1151 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1153 #define HI(x) ((x >> 16) & 0xffff)
1154 #define LO(x) ((x ) & 0xffff)
1156 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1158 #define GEN_OPCODE32() \
1159 conscode (gencode (HI (c_code.opcode)), \
1160 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1162 #define GEN_OPCODE16() \
1163 conscode (gencode (c_code.opcode), NULL_CODE)
1166 /* 32 BIT INSTRUCTIONS. */
1169 /* DSP32 instruction generation. */
1172 bfin_gen_dsp32mac (int op1
, int MM
, int mmod
, int w1
, int P
,
1173 int h01
, int h11
, int h00
, int h10
, int op0
,
1174 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1190 /* If we have full reg assignments, mask out LSB to encode
1191 single or simultaneous even/odd register moves. */
1201 return GEN_OPCODE32 ();
1205 bfin_gen_dsp32mult (int op1
, int MM
, int mmod
, int w1
, int P
,
1206 int h01
, int h11
, int h00
, int h10
, int op0
,
1207 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1232 return GEN_OPCODE32 ();
1236 bfin_gen_dsp32alu (int HL
, int aopcde
, int aop
, int s
, int x
,
1237 REG_T dst0
, REG_T dst1
, REG_T src0
, REG_T src1
)
1251 return GEN_OPCODE32 ();
1255 bfin_gen_dsp32shift (int sopcde
, REG_T dst0
, REG_T src0
,
1256 REG_T src1
, int sop
, int HLs
)
1268 return GEN_OPCODE32 ();
1272 bfin_gen_dsp32shiftimm (int sopcde
, REG_T dst0
, int immag
,
1273 REG_T src1
, int sop
, int HLs
)
1275 INIT (DSP32ShiftImm
);
1285 return GEN_OPCODE32 ();
1291 bfin_gen_loopsetup (Expr_Node
* psoffset
, REG_T c
, int rop
,
1292 Expr_Node
* peoffset
, REG_T reg
)
1294 int soffset
, eoffset
;
1297 soffset
= (EXPR_VALUE (psoffset
) >> 1);
1299 eoffset
= (EXPR_VALUE (peoffset
) >> 1);
1306 conscode (gencode (HI (c_code
.opcode
)),
1307 conctcode (Expr_Node_Gen_Reloc (psoffset
, BFD_RELOC_BFIN_5_PCREL
),
1308 conctcode (gencode (LO (c_code
.opcode
)), Expr_Node_Gen_Reloc (peoffset
, BFD_RELOC_BFIN_11_PCREL
))));
1315 bfin_gen_calla (Expr_Node
* addr
, int S
)
1323 case 0 : rel
= BFD_RELOC_BFIN_24_PCREL_JUMP_L
; break;
1324 case 1 : rel
= BFD_RELOC_24_PCREL
; break;
1325 case 2 : rel
= BFD_RELOC_BFIN_PLTPC
; break;
1331 val
= EXPR_VALUE (addr
) >> 1;
1332 high_val
= val
>> 16;
1334 return conscode (gencode (HI (c_code
.opcode
) | (high_val
& 0xff)),
1335 Expr_Node_Gen_Reloc (addr
, rel
));
1339 bfin_gen_linkage (int R
, int framesize
)
1346 return GEN_OPCODE32 ();
1350 /* Load and Store. */
1353 bfin_gen_ldimmhalf (REG_T reg
, int H
, int S
, int Z
, Expr_Node
* phword
, int rel
)
1356 unsigned val
= EXPR_VALUE (phword
);
1364 grp
= (GROUP (reg
));
1368 return conscode (gencode (HI (c_code
.opcode
)), Expr_Node_Gen_Reloc (phword
, BFD_RELOC_BFIN_16_IMM
));
1372 return conscode (gencode (HI (c_code
.opcode
)), Expr_Node_Gen_Reloc (phword
, IS_H (*reg
) ? BFD_RELOC_BFIN_16_HIGH
: BFD_RELOC_BFIN_16_LOW
));
1379 return GEN_OPCODE32 ();
1383 bfin_gen_ldstidxi (REG_T ptr
, REG_T reg
, int W
, int sz
, int Z
, Expr_Node
* poffset
)
1387 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1389 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1400 if (poffset
->type
!= Expr_Node_Constant
)
1402 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1403 /* distinguish between R0 = [P5 + symbol@GOT] and
1404 P5 = [P5 + _current_shared_library_p5_offset_]
1406 if (poffset
->type
== Expr_Node_Reloc
1407 && !strcmp (poffset
->value
.s_value
,
1408 "_current_shared_library_p5_offset_"))
1410 return conscode (gencode (HI (c_code
.opcode
)),
1411 Expr_Node_Gen_Reloc(poffset
, BFD_RELOC_16
));
1413 else if (poffset
->type
!= Expr_Node_GOT_Reloc
)
1416 return conscode (gencode (HI (c_code
.opcode
)),
1417 Expr_Node_Gen_Reloc(poffset
->Left_Child
,
1418 poffset
->value
.i_value
));
1424 { /* load/store access size */
1425 case 0: /* 32 bit */
1426 value
= EXPR_VALUE (poffset
) >> 2;
1428 case 1: /* 16 bit */
1429 value
= EXPR_VALUE (poffset
) >> 1;
1432 value
= EXPR_VALUE (poffset
);
1438 offset
= (value
& 0xffff);
1440 return GEN_OPCODE32 ();
1446 bfin_gen_ldst (REG_T ptr
, REG_T reg
, int aop
, int sz
, int Z
, int W
)
1450 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1452 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1463 return GEN_OPCODE16 ();
1467 bfin_gen_ldstii (REG_T ptr
, REG_T reg
, Expr_Node
* poffset
, int W
, int opc
)
1473 if (!IS_PREG (*ptr
))
1475 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1483 value
= EXPR_VALUE (poffset
) >> 1;
1487 value
= EXPR_VALUE (poffset
) >> 2;
1499 return GEN_OPCODE16 ();
1503 bfin_gen_ldstiifp (REG_T sreg
, Expr_Node
* poffset
, int W
)
1505 /* Set bit 4 if it's a Preg. */
1506 int reg
= (sreg
->regno
& CODE_MASK
) | (IS_PREG (*sreg
) ? 0x8 : 0x0);
1507 int offset
= ((~(EXPR_VALUE (poffset
) >> 2)) & 0x1f) + 1;
1513 return GEN_OPCODE16 ();
1517 bfin_gen_ldstpmod (REG_T ptr
, REG_T reg
, int aop
, int W
, REG_T idx
)
1527 return GEN_OPCODE16 ();
1531 bfin_gen_dspldst (REG_T i
, REG_T reg
, int aop
, int W
, int m
)
1541 return GEN_OPCODE16 ();
1545 bfin_gen_logi2op (int opc
, int src
, int dst
)
1553 return GEN_OPCODE16 ();
1557 bfin_gen_brcc (int T
, int B
, Expr_Node
* poffset
)
1564 offset
= ((EXPR_VALUE (poffset
) >> 1));
1566 return conscode (gencode (c_code
.opcode
), Expr_Node_Gen_Reloc (poffset
, BFD_RELOC_BFIN_10_PCREL
));
1570 bfin_gen_ujump (Expr_Node
* poffset
)
1575 offset
= ((EXPR_VALUE (poffset
) >> 1));
1578 return conscode (gencode (c_code
.opcode
),
1579 Expr_Node_Gen_Reloc (
1580 poffset
, BFD_RELOC_BFIN_12_PCREL_JUMP_S
));
1584 bfin_gen_alu2op (REG_T dst
, REG_T src
, int opc
)
1592 return GEN_OPCODE16 ();
1596 bfin_gen_compi2opd (REG_T dst
, int src
, int opc
)
1604 return GEN_OPCODE16 ();
1608 bfin_gen_compi2opp (REG_T dst
, int src
, int opc
)
1616 return GEN_OPCODE16 ();
1620 bfin_gen_dagmodik (REG_T i
, int opc
)
1627 return GEN_OPCODE16 ();
1631 bfin_gen_dagmodim (REG_T i
, REG_T m
, int opc
, int br
)
1640 return GEN_OPCODE16 ();
1644 bfin_gen_ptr2op (REG_T dst
, REG_T src
, int opc
)
1652 return GEN_OPCODE16 ();
1656 bfin_gen_comp3op (REG_T src0
, REG_T src1
, REG_T dst
, int opc
)
1665 return GEN_OPCODE16 ();
1669 bfin_gen_ccflag (REG_T x
, int y
, int opc
, int I
, int G
)
1679 return GEN_OPCODE16 ();
1683 bfin_gen_ccmv (REG_T src
, REG_T dst
, int T
)
1696 return GEN_OPCODE16 ();
1700 bfin_gen_cc2stat (int cbit
, int opc
, int D
)
1708 return GEN_OPCODE16 ();
1712 bfin_gen_regmv (REG_T src
, REG_T dst
)
1725 return GEN_OPCODE16 ();
1729 bfin_gen_cc2dreg (int opc
, REG_T reg
)
1736 return GEN_OPCODE16 ();
1740 bfin_gen_progctrl (int prgfunc
, int poprnd
)
1747 return GEN_OPCODE16 ();
1751 bfin_gen_cactrl (REG_T reg
, int a
, int opc
)
1759 return GEN_OPCODE16 ();
1763 bfin_gen_pushpopmultiple (int dr
, int pr
, int d
, int p
, int W
)
1765 INIT (PushPopMultiple
);
1773 return GEN_OPCODE16 ();
1777 bfin_gen_pushpopreg (REG_T reg
, int W
)
1783 grp
= (GROUP (reg
));
1787 return GEN_OPCODE16 ();
1790 /* Pseudo Debugging Support. */
1793 bfin_gen_pseudodbg (int fn
, int reg
, int grp
)
1801 return GEN_OPCODE16 ();
1805 bfin_gen_pseudodbg_assert (int dbgop
, REG_T regtest
, int expected
)
1808 INIT (PseudoDbg_Assert
);
1812 grp
= GROUP (regtest
);
1816 return GEN_OPCODE32 ();
1820 bfin_gen_pseudochr (int ch
)
1826 return GEN_OPCODE16 ();
1829 /* Multiple instruction generation. */
1832 bfin_gen_multi_instr (INSTR_T dsp32
, INSTR_T dsp16_grp1
, INSTR_T dsp16_grp2
)
1836 /* If it's a 0, convert into MNOP. */
1840 SET_MULTI_INSTRUCTION_BIT (dsp32
);
1844 dsp32
= gencode (0xc803);
1845 walk
= gencode (0x1800);
1851 dsp16_grp1
= gencode (0x0000);
1856 dsp16_grp2
= gencode (0x0000);
1859 walk
->next
= dsp16_grp1
;
1860 dsp16_grp1
->next
= dsp16_grp2
;
1861 dsp16_grp2
->next
= NULL_CODE
;
1867 bfin_gen_loop (Expr_Node
*exp
, REG_T reg
, int rop
, REG_T preg
)
1869 const char *loopsym
;
1870 char *lbeginsym
, *lendsym
;
1871 Expr_Node_Value lbeginval
, lendval
;
1872 Expr_Node
*lbegin
, *lend
;
1875 loopsym
= exp
->value
.s_value
;
1876 lbeginsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__BEGIN") + 5);
1877 lendsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__END") + 5);
1882 strcat (lbeginsym
, "L$L$");
1883 strcat (lbeginsym
, loopsym
);
1884 strcat (lbeginsym
, "__BEGIN");
1886 strcat (lendsym
, "L$L$");
1887 strcat (lendsym
, loopsym
);
1888 strcat (lendsym
, "__END");
1890 lbeginval
.s_value
= lbeginsym
;
1891 lendval
.s_value
= lendsym
;
1893 lbegin
= Expr_Node_Create (Expr_Node_Reloc
, lbeginval
, NULL
, NULL
);
1894 lend
= Expr_Node_Create (Expr_Node_Reloc
, lendval
, NULL
, NULL
);
1896 sym
= symbol_find(loopsym
);
1897 if (!S_IS_LOCAL (sym
) || (S_IS_LOCAL (sym
) && !symbol_used_p (sym
)))
1898 symbol_remove (sym
, &symbol_rootP
, &symbol_lastP
);
1900 return bfin_gen_loopsetup (lbegin
, reg
, rop
, lend
, preg
);
1904 bfin_loop_attempt_create_label (Expr_Node
*exp
, int is_begin
)
1907 name
= fb_label_name (exp
->value
.i_value
, is_begin
);
1908 exp
->value
.s_value
= xstrdup (name
);
1909 exp
->type
= Expr_Node_Reloc
;
1913 bfin_loop_beginend (Expr_Node
*exp
, int begin
)
1915 const char *loopsym
;
1918 const char *suffix
= begin
? "__BEGIN" : "__END";
1920 loopsym
= exp
->value
.s_value
;
1921 label_name
= (char *) xmalloc (strlen (loopsym
) + strlen (suffix
) + 5);
1925 strcat (label_name
, "L$L$");
1926 strcat (label_name
, loopsym
);
1927 strcat (label_name
, suffix
);
1929 linelabel
= colon (label_name
);
1931 /* LOOP_END follows the last instruction in the loop.
1932 Adjust label address. */
1934 ((struct local_symbol
*) linelabel
)->lsy_value
-= last_insn_size
;
1938 bfin_eol_in_insn (char *line
)
1940 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1947 /* A semi-colon followed by a newline is always the end of a line. */
1948 if (line
[-1] == ';')
1951 if (line
[-1] == '|')
1954 /* If the || is on the next line, there might be leading whitespace. */
1956 while (*temp
== ' ' || *temp
== '\t') temp
++;
1965 bfin_start_label (char *s
)
1969 if (*s
== '(' || *s
== '[')
1978 bfin_force_relocation (struct fix
*fixp
)
1980 if (fixp
->fx_r_type
==BFD_RELOC_BFIN_16_LOW
1981 || fixp
->fx_r_type
== BFD_RELOC_BFIN_16_HIGH
)
1984 return generic_force_reloc (fixp
);
1987 /* This is a stripped down version of the disassembler. The only thing it
1988 does is return a mask of registers modified by an instruction. Only
1989 instructions that can occur in a parallel-issue bundle are handled, and
1990 only the registers that can cause a conflict are recorded. */
1992 #define DREG_MASK(n) (0x101 << (n))
1993 #define DREGH_MASK(n) (0x100 << (n))
1994 #define DREGL_MASK(n) (0x001 << (n))
1995 #define IREG_MASK(n) (1 << ((n) + 16))
1998 decode_ProgCtrl_0 (int iw0
)
2006 decode_LDSTpmod_0 (int iw0
)
2009 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2010 | 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......|
2011 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2012 int W
= ((iw0
>> LDSTpmod_W_bits
) & LDSTpmod_W_mask
);
2013 int aop
= ((iw0
>> LDSTpmod_aop_bits
) & LDSTpmod_aop_mask
);
2014 int idx
= ((iw0
>> LDSTpmod_idx_bits
) & LDSTpmod_idx_mask
);
2015 int ptr
= ((iw0
>> LDSTpmod_ptr_bits
) & LDSTpmod_ptr_mask
);
2016 int reg
= ((iw0
>> LDSTpmod_reg_bits
) & LDSTpmod_reg_mask
);
2018 if (aop
== 1 && W
== 0 && idx
== ptr
)
2019 return DREGL_MASK (reg
);
2020 else if (aop
== 2 && W
== 0 && idx
== ptr
)
2021 return DREGH_MASK (reg
);
2022 else if (aop
== 1 && W
== 1 && idx
== ptr
)
2024 else if (aop
== 2 && W
== 1 && idx
== ptr
)
2026 else if (aop
== 0 && W
== 0)
2027 return DREG_MASK (reg
);
2028 else if (aop
== 1 && W
== 0)
2029 return DREGL_MASK (reg
);
2030 else if (aop
== 2 && W
== 0)
2031 return DREGH_MASK (reg
);
2032 else if (aop
== 3 && W
== 0)
2033 return DREG_MASK (reg
);
2034 else if (aop
== 3 && W
== 1)
2035 return DREG_MASK (reg
);
2036 else if (aop
== 0 && W
== 1)
2038 else if (aop
== 1 && W
== 1)
2040 else if (aop
== 2 && W
== 1)
2049 decode_dagMODim_0 (int iw0
)
2052 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2053 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....|
2054 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2055 int i
= ((iw0
>> DagMODim_i_bits
) & DagMODim_i_mask
);
2056 int opc
= ((iw0
>> DagMODim_op_bits
) & DagMODim_op_mask
);
2058 if (opc
== 0 || opc
== 1)
2059 return IREG_MASK (i
);
2067 decode_dagMODik_0 (int iw0
)
2070 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2071 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....|
2072 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2073 int i
= ((iw0
>> DagMODik_i_bits
) & DagMODik_i_mask
);
2074 return IREG_MASK (i
);
2079 decode_dspLDST_0 (int iw0
)
2082 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2083 | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......|
2084 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2085 int i
= ((iw0
>> DspLDST_i_bits
) & DspLDST_i_mask
);
2086 int m
= ((iw0
>> DspLDST_m_bits
) & DspLDST_m_mask
);
2087 int W
= ((iw0
>> DspLDST_W_bits
) & DspLDST_W_mask
);
2088 int aop
= ((iw0
>> DspLDST_aop_bits
) & DspLDST_aop_mask
);
2089 int reg
= ((iw0
>> DspLDST_reg_bits
) & DspLDST_reg_mask
);
2091 if (aop
== 0 && W
== 0 && m
== 0)
2092 return DREG_MASK (reg
) | IREG_MASK (i
);
2093 else if (aop
== 0 && W
== 0 && m
== 1)
2094 return DREGL_MASK (reg
) | IREG_MASK (i
);
2095 else if (aop
== 0 && W
== 0 && m
== 2)
2096 return DREGH_MASK (reg
) | IREG_MASK (i
);
2097 else if (aop
== 1 && W
== 0 && m
== 0)
2098 return DREG_MASK (reg
) | IREG_MASK (i
);
2099 else if (aop
== 1 && W
== 0 && m
== 1)
2100 return DREGL_MASK (reg
) | IREG_MASK (i
);
2101 else if (aop
== 1 && W
== 0 && m
== 2)
2102 return DREGH_MASK (reg
) | IREG_MASK (i
);
2103 else if (aop
== 2 && W
== 0 && m
== 0)
2104 return DREG_MASK (reg
);
2105 else if (aop
== 2 && W
== 0 && m
== 1)
2106 return DREGL_MASK (reg
);
2107 else if (aop
== 2 && W
== 0 && m
== 2)
2108 return DREGH_MASK (reg
);
2109 else if (aop
== 0 && W
== 1 && m
== 0)
2110 return IREG_MASK (i
);
2111 else if (aop
== 0 && W
== 1 && m
== 1)
2112 return IREG_MASK (i
);
2113 else if (aop
== 0 && W
== 1 && m
== 2)
2114 return IREG_MASK (i
);
2115 else if (aop
== 1 && W
== 1 && m
== 0)
2116 return IREG_MASK (i
);
2117 else if (aop
== 1 && W
== 1 && m
== 1)
2118 return IREG_MASK (i
);
2119 else if (aop
== 1 && W
== 1 && m
== 2)
2120 return IREG_MASK (i
);
2121 else if (aop
== 2 && W
== 1 && m
== 0)
2123 else if (aop
== 2 && W
== 1 && m
== 1)
2125 else if (aop
== 2 && W
== 1 && m
== 2)
2127 else if (aop
== 3 && W
== 0)
2128 return DREG_MASK (reg
) | IREG_MASK (i
);
2129 else if (aop
== 3 && W
== 1)
2130 return IREG_MASK (i
);
2137 decode_LDST_0 (int iw0
)
2140 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2141 | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......|
2142 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2143 int Z
= ((iw0
>> LDST_Z_bits
) & LDST_Z_mask
);
2144 int W
= ((iw0
>> LDST_W_bits
) & LDST_W_mask
);
2145 int sz
= ((iw0
>> LDST_sz_bits
) & LDST_sz_mask
);
2146 int aop
= ((iw0
>> LDST_aop_bits
) & LDST_aop_mask
);
2147 int reg
= ((iw0
>> LDST_reg_bits
) & LDST_reg_mask
);
2149 if (aop
== 0 && sz
== 0 && Z
== 0 && W
== 0)
2150 return DREG_MASK (reg
);
2151 else if (aop
== 0 && sz
== 0 && Z
== 1 && W
== 0)
2153 else if (aop
== 0 && sz
== 1 && Z
== 0 && W
== 0)
2154 return DREG_MASK (reg
);
2155 else if (aop
== 0 && sz
== 1 && Z
== 1 && W
== 0)
2156 return DREG_MASK (reg
);
2157 else if (aop
== 0 && sz
== 2 && Z
== 0 && W
== 0)
2158 return DREG_MASK (reg
);
2159 else if (aop
== 0 && sz
== 2 && Z
== 1 && W
== 0)
2160 return DREG_MASK (reg
);
2161 else if (aop
== 1 && sz
== 0 && Z
== 0 && W
== 0)
2162 return DREG_MASK (reg
);
2163 else if (aop
== 1 && sz
== 0 && Z
== 1 && W
== 0)
2165 else if (aop
== 1 && sz
== 1 && Z
== 0 && W
== 0)
2166 return DREG_MASK (reg
);
2167 else if (aop
== 1 && sz
== 1 && Z
== 1 && W
== 0)
2168 return DREG_MASK (reg
);
2169 else if (aop
== 1 && sz
== 2 && Z
== 0 && W
== 0)
2170 return DREG_MASK (reg
);
2171 else if (aop
== 1 && sz
== 2 && Z
== 1 && W
== 0)
2172 return DREG_MASK (reg
);
2173 else if (aop
== 2 && sz
== 0 && Z
== 0 && W
== 0)
2174 return DREG_MASK (reg
);
2175 else if (aop
== 2 && sz
== 0 && Z
== 1 && W
== 0)
2177 else if (aop
== 2 && sz
== 1 && Z
== 0 && W
== 0)
2178 return DREG_MASK (reg
);
2179 else if (aop
== 2 && sz
== 1 && Z
== 1 && W
== 0)
2180 return DREG_MASK (reg
);
2181 else if (aop
== 2 && sz
== 2 && Z
== 0 && W
== 0)
2182 return DREG_MASK (reg
);
2183 else if (aop
== 2 && sz
== 2 && Z
== 1 && W
== 0)
2184 return DREG_MASK (reg
);
2185 else if (aop
== 0 && sz
== 0 && Z
== 0 && W
== 1)
2187 else if (aop
== 0 && sz
== 0 && Z
== 1 && W
== 1)
2189 else if (aop
== 0 && sz
== 1 && Z
== 0 && W
== 1)
2191 else if (aop
== 0 && sz
== 2 && Z
== 0 && W
== 1)
2193 else if (aop
== 1 && sz
== 0 && Z
== 0 && W
== 1)
2195 else if (aop
== 1 && sz
== 0 && Z
== 1 && W
== 1)
2197 else if (aop
== 1 && sz
== 1 && Z
== 0 && W
== 1)
2199 else if (aop
== 1 && sz
== 2 && Z
== 0 && W
== 1)
2201 else if (aop
== 2 && sz
== 0 && Z
== 0 && W
== 1)
2203 else if (aop
== 2 && sz
== 0 && Z
== 1 && W
== 1)
2205 else if (aop
== 2 && sz
== 1 && Z
== 0 && W
== 1)
2207 else if (aop
== 2 && sz
== 2 && Z
== 0 && W
== 1)
2214 decode_LDSTiiFP_0 (int iw0
)
2217 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2218 | 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........|
2219 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2220 int reg
= ((iw0
>> LDSTiiFP_reg_bits
) & LDSTiiFP_reg_mask
);
2221 int W
= ((iw0
>> LDSTiiFP_W_bits
) & LDSTiiFP_W_mask
);
2224 return reg
< 8 ? DREG_MASK (reg
) : 0;
2230 decode_LDSTii_0 (int iw0
)
2233 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2234 | 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......|
2235 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2236 int reg
= ((iw0
>> LDSTii_reg_bit
) & LDSTii_reg_mask
);
2237 int opc
= ((iw0
>> LDSTii_op_bit
) & LDSTii_op_mask
);
2238 int W
= ((iw0
>> LDSTii_W_bit
) & LDSTii_W_mask
);
2240 if (W
== 0 && opc
!= 3)
2241 return DREG_MASK (reg
);
2242 else if (W
== 0 && opc
== 3)
2244 else if (W
== 1 && opc
== 0)
2246 else if (W
== 1 && opc
== 1)
2248 else if (W
== 1 && opc
== 3)
2255 decode_dsp32mac_0 (int iw0
, int iw1
)
2259 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2260 | 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...|
2261 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2262 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2263 int op1
= ((iw0
>> (DSP32Mac_op1_bits
- 16)) & DSP32Mac_op1_mask
);
2264 int w1
= ((iw0
>> (DSP32Mac_w1_bits
- 16)) & DSP32Mac_w1_mask
);
2265 int P
= ((iw0
>> (DSP32Mac_p_bits
- 16)) & DSP32Mac_p_mask
);
2266 int mmod
= ((iw0
>> (DSP32Mac_mmod_bits
- 16)) & DSP32Mac_mmod_mask
);
2267 int w0
= ((iw1
>> DSP32Mac_w0_bits
) & DSP32Mac_w0_mask
);
2268 int MM
= ((iw1
>> DSP32Mac_MM_bits
) & DSP32Mac_MM_mask
);
2269 int dst
= ((iw1
>> DSP32Mac_dst_bits
) & DSP32Mac_dst_mask
);
2270 int op0
= ((iw1
>> DSP32Mac_op0_bits
) & DSP32Mac_op0_mask
);
2272 if (w0
== 0 && w1
== 0 && op1
== 3 && op0
== 3)
2278 if ((w1
|| w0
) && mmod
== M_W32
)
2281 if (((1 << mmod
) & (P
? 0x131b : 0x1b5f)) == 0)
2284 if (w1
== 1 || op1
!= 3)
2289 return DREG_MASK (dst
+ 1);
2291 return DREGH_MASK (dst
);
2295 if (w0
== 1 || op0
!= 3)
2300 return DREG_MASK (dst
);
2302 return DREGL_MASK (dst
);
2310 decode_dsp32mult_0 (int iw0
, int iw1
)
2313 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2314 | 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...|
2315 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2316 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2317 int w1
= ((iw0
>> (DSP32Mac_w1_bits
- 16)) & DSP32Mac_w1_mask
);
2318 int P
= ((iw0
>> (DSP32Mac_p_bits
- 16)) & DSP32Mac_p_mask
);
2319 int mmod
= ((iw0
>> (DSP32Mac_mmod_bits
- 16)) & DSP32Mac_mmod_mask
);
2320 int w0
= ((iw1
>> DSP32Mac_w0_bits
) & DSP32Mac_w0_mask
);
2321 int dst
= ((iw1
>> DSP32Mac_dst_bits
) & DSP32Mac_dst_mask
);
2324 if (w1
== 0 && w0
== 0)
2327 if (((1 << mmod
) & (P
? 0x313 : 0x1b57)) == 0)
2333 return DREG_MASK (dst
| 1);
2335 return DREGH_MASK (dst
);
2341 return DREG_MASK (dst
);
2343 return DREGL_MASK (dst
);
2350 decode_dsp32alu_0 (int iw0
, int iw1
)
2353 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2354 | 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............|
2355 |.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......|
2356 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2357 int s
= ((iw1
>> DSP32Alu_s_bits
) & DSP32Alu_s_mask
);
2358 int x
= ((iw1
>> DSP32Alu_x_bits
) & DSP32Alu_x_mask
);
2359 int aop
= ((iw1
>> DSP32Alu_aop_bits
) & DSP32Alu_aop_mask
);
2360 int dst0
= ((iw1
>> DSP32Alu_dst0_bits
) & DSP32Alu_dst0_mask
);
2361 int dst1
= ((iw1
>> DSP32Alu_dst1_bits
) & DSP32Alu_dst1_mask
);
2362 int HL
= ((iw0
>> (DSP32Alu_HL_bits
- 16)) & DSP32Alu_HL_mask
);
2363 int aopcde
= ((iw0
>> (DSP32Alu_aopcde_bits
- 16)) & DSP32Alu_aopcde_mask
);
2365 if (aop
== 0 && aopcde
== 9 && s
== 0)
2367 else if (aop
== 2 && aopcde
== 9 && HL
== 0 && s
== 0)
2369 else if (aop
>= x
* 2 && aopcde
== 5)
2370 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2371 else if (HL
== 0 && aopcde
== 2)
2372 return DREGL_MASK (dst0
);
2373 else if (HL
== 1 && aopcde
== 2)
2374 return DREGH_MASK (dst0
);
2375 else if (HL
== 0 && aopcde
== 3)
2376 return DREGL_MASK (dst0
);
2377 else if (HL
== 1 && aopcde
== 3)
2378 return DREGH_MASK (dst0
);
2380 else if (aop
== 0 && aopcde
== 9 && s
== 1)
2382 else if (aop
== 1 && aopcde
== 9 && s
== 0)
2384 else if (aop
== 2 && aopcde
== 9 && s
== 1)
2386 else if (aop
== 3 && aopcde
== 9 && s
== 0)
2388 else if (aopcde
== 8)
2390 else if (aop
== 0 && aopcde
== 11)
2391 return DREG_MASK (dst0
);
2392 else if (aop
== 1 && aopcde
== 11)
2393 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2394 else if (aopcde
== 11)
2396 else if (aopcde
== 22)
2397 return DREG_MASK (dst0
);
2399 else if ((aop
== 0 || aop
== 1) && aopcde
== 14)
2401 else if (aop
== 3 && HL
== 0 && aopcde
== 14)
2404 else if (aop
== 3 && HL
== 0 && aopcde
== 15)
2405 return DREG_MASK (dst0
);
2407 else if (aop
== 1 && aopcde
== 16)
2410 else if (aop
== 0 && aopcde
== 16)
2413 else if (aop
== 3 && HL
== 0 && aopcde
== 16)
2416 else if (aop
== 3 && HL
== 0 && aopcde
== 7)
2417 return DREG_MASK (dst0
);
2418 else if ((aop
== 0 || aop
== 1 || aop
== 2) && aopcde
== 7)
2419 return DREG_MASK (dst0
);
2421 else if (aop
== 0 && aopcde
== 12)
2422 return DREG_MASK (dst0
);
2423 else if (aop
== 1 && aopcde
== 12)
2424 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2425 else if (aop
== 3 && aopcde
== 12)
2426 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2428 else if (aopcde
== 0)
2429 return DREG_MASK (dst0
);
2430 else if (aopcde
== 1)
2431 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2433 else if (aop
== 0 && aopcde
== 10)
2434 return DREGL_MASK (dst0
);
2435 else if (aop
== 1 && aopcde
== 10)
2436 return DREGL_MASK (dst0
);
2438 else if ((aop
== 1 || aop
== 0) && aopcde
== 4)
2439 return DREG_MASK (dst0
);
2440 else if (aop
== 2 && aopcde
== 4)
2441 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2443 else if (aop
== 0 && aopcde
== 17)
2444 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2445 else if (aop
== 1 && aopcde
== 17)
2446 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2447 else if (aop
== 0 && aopcde
== 18)
2449 else if (aop
== 3 && aopcde
== 18)
2452 else if ((aop
== 0 || aop
== 1 || aop
== 2) && aopcde
== 6)
2453 return DREG_MASK (dst0
);
2455 else if ((aop
== 0 || aop
== 1) && aopcde
== 20)
2456 return DREG_MASK (dst0
);
2458 else if ((aop
== 0 || aop
== 1) && aopcde
== 21)
2459 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2461 else if (aop
== 0 && aopcde
== 23 && HL
== 1)
2462 return DREG_MASK (dst0
);
2463 else if (aop
== 0 && aopcde
== 23 && HL
== 0)
2464 return DREG_MASK (dst0
);
2466 else if (aop
== 0 && aopcde
== 24)
2467 return DREG_MASK (dst0
);
2468 else if (aop
== 1 && aopcde
== 24)
2469 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2470 else if (aopcde
== 13)
2471 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2479 decode_dsp32shift_0 (int iw0
, int iw1
)
2482 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2483 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............|
2484 |.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......|
2485 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2486 int HLs
= ((iw1
>> DSP32Shift_HLs_bits
) & DSP32Shift_HLs_mask
);
2487 int sop
= ((iw1
>> DSP32Shift_sop_bits
) & DSP32Shift_sop_mask
);
2488 int src0
= ((iw1
>> DSP32Shift_src0_bits
) & DSP32Shift_src0_mask
);
2489 int src1
= ((iw1
>> DSP32Shift_src1_bits
) & DSP32Shift_src1_mask
);
2490 int dst0
= ((iw1
>> DSP32Shift_dst0_bits
) & DSP32Shift_dst0_mask
);
2491 int sopcde
= ((iw0
>> (DSP32Shift_sopcde_bits
- 16)) & DSP32Shift_sopcde_mask
);
2493 if (sop
== 0 && sopcde
== 0)
2494 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2495 else if (sop
== 1 && sopcde
== 0)
2496 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2497 else if (sop
== 2 && sopcde
== 0)
2498 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2499 else if (sop
== 0 && sopcde
== 3)
2501 else if (sop
== 1 && sopcde
== 3)
2503 else if (sop
== 2 && sopcde
== 3)
2505 else if (sop
== 3 && sopcde
== 3)
2506 return DREG_MASK (dst0
);
2507 else if (sop
== 0 && sopcde
== 1)
2508 return DREG_MASK (dst0
);
2509 else if (sop
== 1 && sopcde
== 1)
2510 return DREG_MASK (dst0
);
2511 else if (sop
== 2 && sopcde
== 1)
2512 return DREG_MASK (dst0
);
2513 else if (sopcde
== 2)
2514 return DREG_MASK (dst0
);
2515 else if (sopcde
== 4)
2516 return DREG_MASK (dst0
);
2517 else if (sop
== 0 && sopcde
== 5)
2518 return DREGL_MASK (dst0
);
2519 else if (sop
== 1 && sopcde
== 5)
2520 return DREGL_MASK (dst0
);
2521 else if (sop
== 2 && sopcde
== 5)
2522 return DREGL_MASK (dst0
);
2523 else if (sop
== 0 && sopcde
== 6)
2524 return DREGL_MASK (dst0
);
2525 else if (sop
== 1 && sopcde
== 6)
2526 return DREGL_MASK (dst0
);
2527 else if (sop
== 3 && sopcde
== 6)
2528 return DREGL_MASK (dst0
);
2529 else if (sop
== 0 && sopcde
== 7)
2530 return DREGL_MASK (dst0
);
2531 else if (sop
== 1 && sopcde
== 7)
2532 return DREGL_MASK (dst0
);
2533 else if (sop
== 2 && sopcde
== 7)
2534 return DREGL_MASK (dst0
);
2535 else if (sop
== 3 && sopcde
== 7)
2536 return DREGL_MASK (dst0
);
2537 else if (sop
== 0 && sopcde
== 8)
2538 return DREG_MASK (src0
) | DREG_MASK (src1
);
2541 OUTS (outf
, "BITMUX (");
2542 OUTS (outf
, dregs (src0
));
2544 OUTS (outf
, dregs (src1
));
2545 OUTS (outf
, ", A0) (ASR)");
2548 else if (sop
== 1 && sopcde
== 8)
2549 return DREG_MASK (src0
) | DREG_MASK (src1
);
2552 OUTS (outf
, "BITMUX (");
2553 OUTS (outf
, dregs (src0
));
2555 OUTS (outf
, dregs (src1
));
2556 OUTS (outf
, ", A0) (ASL)");
2559 else if (sopcde
== 9)
2560 return sop
< 2 ? DREGL_MASK (dst0
) : DREG_MASK (dst0
);
2561 else if (sopcde
== 10)
2562 return DREG_MASK (dst0
);
2563 else if (sop
== 0 && sopcde
== 11)
2564 return DREGL_MASK (dst0
);
2565 else if (sop
== 1 && sopcde
== 11)
2566 return DREGL_MASK (dst0
);
2567 else if (sop
== 0 && sopcde
== 12)
2569 else if (sop
== 1 && sopcde
== 12)
2570 return DREGL_MASK (dst0
);
2571 else if (sop
== 0 && sopcde
== 13)
2572 return DREG_MASK (dst0
);
2573 else if (sop
== 1 && sopcde
== 13)
2574 return DREG_MASK (dst0
);
2575 else if (sop
== 2 && sopcde
== 13)
2576 return DREG_MASK (dst0
);
2582 decode_dsp32shiftimm_0 (int iw0
, int iw1
)
2585 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2586 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............|
2587 |.sop...|.HLs...|.dst0......|.immag.................|.src1......|
2588 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2589 int sop
= ((iw1
>> DSP32ShiftImm_sop_bits
) & DSP32ShiftImm_sop_mask
);
2590 int bit8
= ((iw1
>> 8) & 0x1);
2591 int dst0
= ((iw1
>> DSP32ShiftImm_dst0_bits
) & DSP32ShiftImm_dst0_mask
);
2592 int sopcde
= ((iw0
>> (DSP32ShiftImm_sopcde_bits
- 16)) & DSP32ShiftImm_sopcde_mask
);
2593 int HLs
= ((iw1
>> DSP32ShiftImm_HLs_bits
) & DSP32ShiftImm_HLs_mask
);
2596 if (sop
== 0 && sopcde
== 0)
2597 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2598 else if (sop
== 1 && sopcde
== 0 && bit8
== 0)
2599 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2600 else if (sop
== 1 && sopcde
== 0 && bit8
== 1)
2601 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2602 else if (sop
== 2 && sopcde
== 0 && bit8
== 0)
2603 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2604 else if (sop
== 2 && sopcde
== 0 && bit8
== 1)
2605 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2606 else if (sop
== 2 && sopcde
== 3 && HLs
== 1)
2608 else if (sop
== 0 && sopcde
== 3 && HLs
== 0 && bit8
== 0)
2610 else if (sop
== 0 && sopcde
== 3 && HLs
== 0 && bit8
== 1)
2612 else if (sop
== 0 && sopcde
== 3 && HLs
== 1 && bit8
== 0)
2614 else if (sop
== 0 && sopcde
== 3 && HLs
== 1 && bit8
== 1)
2616 else if (sop
== 1 && sopcde
== 3 && HLs
== 0)
2618 else if (sop
== 1 && sopcde
== 3 && HLs
== 1)
2620 else if (sop
== 2 && sopcde
== 3 && HLs
== 0)
2622 else if (sop
== 1 && sopcde
== 1 && bit8
== 0)
2623 return DREG_MASK (dst0
);
2624 else if (sop
== 1 && sopcde
== 1 && bit8
== 1)
2625 return DREG_MASK (dst0
);
2626 else if (sop
== 2 && sopcde
== 1 && bit8
== 1)
2627 return DREG_MASK (dst0
);
2628 else if (sop
== 2 && sopcde
== 1 && bit8
== 0)
2629 return DREG_MASK (dst0
);
2630 else if (sop
== 0 && sopcde
== 1)
2631 return DREG_MASK (dst0
);
2632 else if (sop
== 1 && sopcde
== 2)
2633 return DREG_MASK (dst0
);
2634 else if (sop
== 2 && sopcde
== 2 && bit8
== 1)
2635 return DREG_MASK (dst0
);
2636 else if (sop
== 2 && sopcde
== 2 && bit8
== 0)
2637 return DREG_MASK (dst0
);
2638 else if (sop
== 3 && sopcde
== 2)
2639 return DREG_MASK (dst0
);
2640 else if (sop
== 0 && sopcde
== 2)
2641 return DREG_MASK (dst0
);
2647 insn_regmask (int iw0
, int iw1
)
2649 if ((iw0
& 0xf7ff) == 0xc003 && iw1
== 0x1800)
2650 return 0; /* MNOP */
2651 else if ((iw0
& 0xff00) == 0x0000)
2652 return decode_ProgCtrl_0 (iw0
);
2653 else if ((iw0
& 0xffc0) == 0x0240)
2655 else if ((iw0
& 0xff80) == 0x0100)
2657 else if ((iw0
& 0xfe00) == 0x0400)
2659 else if ((iw0
& 0xfe00) == 0x0600)
2661 else if ((iw0
& 0xf800) == 0x0800)
2663 else if ((iw0
& 0xffe0) == 0x0200)
2665 else if ((iw0
& 0xff00) == 0x0300)
2667 else if ((iw0
& 0xf000) == 0x1000)
2669 else if ((iw0
& 0xf000) == 0x2000)
2671 else if ((iw0
& 0xf000) == 0x3000)
2673 else if ((iw0
& 0xfc00) == 0x4000)
2675 else if ((iw0
& 0xfe00) == 0x4400)
2677 else if ((iw0
& 0xf800) == 0x4800)
2679 else if ((iw0
& 0xf000) == 0x5000)
2681 else if ((iw0
& 0xf800) == 0x6000)
2683 else if ((iw0
& 0xf800) == 0x6800)
2685 else if ((iw0
& 0xf000) == 0x8000)
2686 return decode_LDSTpmod_0 (iw0
);
2687 else if ((iw0
& 0xff60) == 0x9e60)
2688 return decode_dagMODim_0 (iw0
);
2689 else if ((iw0
& 0xfff0) == 0x9f60)
2690 return decode_dagMODik_0 (iw0
);
2691 else if ((iw0
& 0xfc00) == 0x9c00)
2692 return decode_dspLDST_0 (iw0
);
2693 else if ((iw0
& 0xf000) == 0x9000)
2694 return decode_LDST_0 (iw0
);
2695 else if ((iw0
& 0xfc00) == 0xb800)
2696 return decode_LDSTiiFP_0 (iw0
);
2697 else if ((iw0
& 0xe000) == 0xA000)
2698 return decode_LDSTii_0 (iw0
);
2699 else if ((iw0
& 0xff80) == 0xe080 && (iw1
& 0x0C00) == 0x0000)
2701 else if ((iw0
& 0xff00) == 0xe100 && (iw1
& 0x0000) == 0x0000)
2703 else if ((iw0
& 0xfe00) == 0xe200 && (iw1
& 0x0000) == 0x0000)
2705 else if ((iw0
& 0xfc00) == 0xe400 && (iw1
& 0x0000) == 0x0000)
2707 else if ((iw0
& 0xfffe) == 0xe800 && (iw1
& 0x0000) == 0x0000)
2709 else if ((iw0
& 0xf600) == 0xc000 && (iw1
& 0x0000) == 0x0000)
2710 return decode_dsp32mac_0 (iw0
, iw1
);
2711 else if ((iw0
& 0xf600) == 0xc200 && (iw1
& 0x0000) == 0x0000)
2712 return decode_dsp32mult_0 (iw0
, iw1
);
2713 else if ((iw0
& 0xf7c0) == 0xc400 && (iw1
& 0x0000) == 0x0000)
2714 return decode_dsp32alu_0 (iw0
, iw1
);
2715 else if ((iw0
& 0xf780) == 0xc600 && (iw1
& 0x01c0) == 0x0000)
2716 return decode_dsp32shift_0 (iw0
, iw1
);
2717 else if ((iw0
& 0xf780) == 0xc680 && (iw1
& 0x0000) == 0x0000)
2718 return decode_dsp32shiftimm_0 (iw0
, iw1
);
2719 else if ((iw0
& 0xff00) == 0xf800)
2721 else if ((iw0
& 0xFFC0) == 0xf000 && (iw1
& 0x0000) == 0x0000)