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
)
488 extern char *current_inputline
;
490 struct bfin_insn
*tmp_insn
;
492 static size_t buffer_len
= 0;
496 if (len
+ 2 > buffer_len
)
499 free (current_inputline
);
500 buffer_len
= len
+ 40;
501 current_inputline
= xmalloc (buffer_len
);
503 memcpy (current_inputline
, line
, len
);
504 current_inputline
[len
] = ';';
505 current_inputline
[len
+ 1] = '\0';
507 state
= parse (current_inputline
);
508 if (state
== NO_INSN_GENERATED
)
511 for (insn_size
= 0, tmp_insn
= insn
; tmp_insn
; tmp_insn
= tmp_insn
->next
)
512 if (!tmp_insn
->reloc
|| !tmp_insn
->exp
->symbol
)
516 toP
= frag_more (insn_size
);
518 last_insn_size
= insn_size
;
525 if (insn
->reloc
&& insn
->exp
->symbol
)
527 char *prev_toP
= toP
- 2;
530 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
531 case BFD_RELOC_24_PCREL
:
532 case BFD_RELOC_BFIN_16_LOW
:
533 case BFD_RELOC_BFIN_16_HIGH
:
540 /* Following if condition checks for the arithmetic relocations.
541 If the case then it doesn't required to generate the code.
542 It has been assumed that, their ID will be contiguous. */
543 if ((BFD_ARELOC_BFIN_PUSH
<= insn
->reloc
544 && BFD_ARELOC_BFIN_COMP
>= insn
->reloc
)
545 || insn
->reloc
== BFD_RELOC_BFIN_16_IMM
)
549 if (insn
->reloc
== BFD_ARELOC_BFIN_CONST
550 || insn
->reloc
== BFD_ARELOC_BFIN_PUSH
)
554 (prev_toP
- frag_now
->fr_literal
),
555 size
, insn
->exp
->symbol
, insn
->exp
->value
,
556 insn
->pcrel
, insn
->reloc
);
560 md_number_to_chars (toP
, insn
->value
, 2);
566 printf (" %02x%02x", ((unsigned char *) &insn
->value
)[0],
567 ((unsigned char *) &insn
->value
)[1]);
573 dwarf2_emit_insn (insn_size
);
576 while (*line
++ != '\0')
578 bump_line_counters ();
581 /* Parse one line of instructions, and generate opcode for it.
582 To parse the line, YACC and LEX are used, because the instruction set
583 syntax doesn't confirm to the AT&T assembly syntax.
584 To call a YACC & LEX generated parser, we must provide the input via
585 a FILE stream, otherwise stdin is used by default. Below the input
586 to the function will be put into a temporary file, then the generated
587 parser uses the temporary file for parsing. */
593 YY_BUFFER_STATE buffstate
;
595 buffstate
= yy_scan_string (line
);
597 /* our lex requires setting the start state to keyword
598 every line as the first word may be a keyword.
599 Fixes a bug where we could not have keywords as labels. */
602 /* Call yyparse here. */
604 if (state
== SEMANTIC_ERROR
)
606 as_bad (_("Parse failed."));
610 yy_delete_buffer (buffstate
);
614 /* We need to handle various expressions properly.
615 Such as, [SP--] = 34, concerned by md_assemble(). */
618 md_operand (expressionS
* expressionP
)
620 if (*input_line_pointer
== '[')
622 as_tsktsk ("We found a '['!");
623 input_line_pointer
++;
624 expression (expressionP
);
628 /* Handle undefined symbols. */
630 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
632 return (symbolS
*) 0;
636 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
637 segT segment ATTRIBUTE_UNUSED
)
642 /* Convert from target byte order to host byte order. */
645 md_chars_to_number (char *val
, int n
)
649 for (retval
= 0; n
--;)
658 md_apply_fix (fixS
*fixP
, valueT
*valueP
, segT seg ATTRIBUTE_UNUSED
)
660 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
662 long value
= *valueP
;
665 switch (fixP
->fx_r_type
)
667 case BFD_RELOC_BFIN_GOT
:
668 case BFD_RELOC_BFIN_GOT17M4
:
669 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
670 fixP
->fx_no_overflow
= 1;
671 newval
= md_chars_to_number (where
, 2);
672 newval
|= 0x0 & 0x7f;
673 md_number_to_chars (where
, newval
, 2);
676 case BFD_RELOC_BFIN_10_PCREL
:
679 if (value
< -1024 || value
> 1022)
680 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
681 _("pcrel too far BFD_RELOC_BFIN_10"));
683 /* 11 bit offset even numbered, so we remove right bit. */
685 newval
= md_chars_to_number (where
, 2);
686 newval
|= value
& 0x03ff;
687 md_number_to_chars (where
, newval
, 2);
690 case BFD_RELOC_BFIN_12_PCREL_JUMP
:
691 case BFD_RELOC_BFIN_12_PCREL_JUMP_S
:
692 case BFD_RELOC_12_PCREL
:
696 if (value
< -4096 || value
> 4094)
697 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_12"));
698 /* 13 bit offset even numbered, so we remove right bit. */
700 newval
= md_chars_to_number (where
, 2);
701 newval
|= value
& 0xfff;
702 md_number_to_chars (where
, newval
, 2);
705 case BFD_RELOC_BFIN_16_LOW
:
706 case BFD_RELOC_BFIN_16_HIGH
:
707 fixP
->fx_done
= FALSE
;
710 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
711 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
712 case BFD_RELOC_24_PCREL
:
716 if (value
< -16777216 || value
> 16777214)
717 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_24"));
719 /* 25 bit offset even numbered, so we remove right bit. */
723 md_number_to_chars (where
- 2, value
>> 16, 1);
724 md_number_to_chars (where
, value
, 1);
725 md_number_to_chars (where
+ 1, value
>> 8, 1);
728 case BFD_RELOC_BFIN_5_PCREL
: /* LSETUP (a, b) : "a" */
731 if (value
< 4 || value
> 30)
732 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_5"));
734 newval
= md_chars_to_number (where
, 1);
735 newval
= (newval
& 0xf0) | (value
& 0xf);
736 md_number_to_chars (where
, newval
, 1);
739 case BFD_RELOC_BFIN_11_PCREL
: /* LSETUP (a, b) : "b" */
743 if (value
< 4 || value
> 2046)
744 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_11_PCREL"));
745 /* 11 bit unsigned even, so we remove right bit. */
747 newval
= md_chars_to_number (where
, 2);
748 newval
|= value
& 0x03ff;
749 md_number_to_chars (where
, newval
, 2);
753 if (value
< -0x80 || value
>= 0x7f)
754 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("rel too far BFD_RELOC_8"));
755 md_number_to_chars (where
, value
, 1);
758 case BFD_RELOC_BFIN_16_IMM
:
760 if (value
< -0x8000 || value
>= 0x7fff)
761 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("rel too far BFD_RELOC_16"));
762 md_number_to_chars (where
, value
, 2);
766 md_number_to_chars (where
, value
, 4);
769 case BFD_RELOC_BFIN_PLTPC
:
770 md_number_to_chars (where
, value
, 2);
773 case BFD_RELOC_BFIN_FUNCDESC
:
774 case BFD_RELOC_VTABLE_INHERIT
:
775 case BFD_RELOC_VTABLE_ENTRY
:
776 fixP
->fx_done
= FALSE
;
780 if ((BFD_ARELOC_BFIN_PUSH
> fixP
->fx_r_type
) || (BFD_ARELOC_BFIN_COMP
< fixP
->fx_r_type
))
782 fprintf (stderr
, "Relocation %d not handled in gas." " Contact support.\n", fixP
->fx_r_type
);
788 fixP
->fx_done
= TRUE
;
792 /* Round up a section size to the appropriate boundary. */
794 md_section_align (segT segment
, valueT size
)
796 int boundary
= bfd_get_section_alignment (stdoutput
, segment
);
797 return ((size
+ (1 << boundary
) - 1) & -(1 << boundary
));
802 md_atof (int type
, char * litP
, int * sizeP
)
804 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
808 /* If while processing a fixup, a reloc really needs to be created
809 then it is done here. */
812 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixp
)
816 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
817 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
818 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
819 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
821 reloc
->addend
= fixp
->fx_offset
;
822 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
824 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
826 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
827 /* xgettext:c-format. */
828 _("reloc %d not supported by object file format"),
829 (int) fixp
->fx_r_type
);
839 /* The location from which a PC relative jump should be calculated,
840 given a PC relative reloc. */
843 md_pcrel_from_section (fixS
*fixP
, segT sec
)
845 if (fixP
->fx_addsy
!= (symbolS
*) NULL
846 && (!S_IS_DEFINED (fixP
->fx_addsy
)
847 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
849 /* The symbol is undefined (or is defined but not in this section).
850 Let the linker figure it out. */
853 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
856 /* Return true if the fix can be handled by GAS, false if it must
857 be passed through to the linker. */
860 bfin_fix_adjustable (fixS
*fixP
)
862 switch (fixP
->fx_r_type
)
864 /* Adjust_reloc_syms doesn't know about the GOT. */
865 case BFD_RELOC_BFIN_GOT
:
866 case BFD_RELOC_BFIN_PLTPC
:
867 /* We need the symbol name for the VTABLE entries. */
868 case BFD_RELOC_VTABLE_INHERIT
:
869 case BFD_RELOC_VTABLE_ENTRY
:
877 /* Special extra functions that help bfin-parse.y perform its job. */
879 struct obstack mempool
;
882 conscode (INSTR_T head
, INSTR_T tail
)
891 conctcode (INSTR_T head
, INSTR_T tail
)
893 INSTR_T temp
= (head
);
904 note_reloc (INSTR_T code
, Expr_Node
* symbol
, int reloc
, int pcrel
)
906 /* Assert that the symbol is not an operator. */
907 gas_assert (symbol
->type
== Expr_Node_Reloc
);
909 return note_reloc1 (code
, symbol
->value
.s_value
, reloc
, pcrel
);
914 note_reloc1 (INSTR_T code
, const char *symbol
, int reloc
, int pcrel
)
917 code
->exp
= mkexpr (0, symbol_find_or_make (symbol
));
923 note_reloc2 (INSTR_T code
, const char *symbol
, int reloc
, int value
, int pcrel
)
926 code
->exp
= mkexpr (value
, symbol_find_or_make (symbol
));
932 gencode (unsigned long x
)
934 INSTR_T cell
= XOBNEW (&mempool
, struct bfin_insn
);
935 memset (cell
, 0, sizeof (struct bfin_insn
));
947 return obstack_alloc (&mempool
, n
);
951 Expr_Node_Create (Expr_Node_Type type
,
952 Expr_Node_Value value
,
953 Expr_Node
*Left_Child
,
954 Expr_Node
*Right_Child
)
958 Expr_Node
*node
= (Expr_Node
*) allocate (sizeof (Expr_Node
));
961 node
->Left_Child
= Left_Child
;
962 node
->Right_Child
= Right_Child
;
966 static const char *con
= ".__constant";
967 static const char *op
= ".__operator";
968 static INSTR_T
Expr_Node_Gen_Reloc_R (Expr_Node
* head
);
969 INSTR_T
Expr_Node_Gen_Reloc (Expr_Node
*head
, int parent_reloc
);
972 Expr_Node_Gen_Reloc (Expr_Node
* head
, int parent_reloc
)
974 /* Top level reloction expression generator VDSP style.
975 If the relocation is just by itself, generate one item
976 else generate this convoluted expression. */
978 INSTR_T note
= NULL_CODE
;
979 INSTR_T note1
= NULL_CODE
;
980 int pcrel
= 1; /* Is the parent reloc pcrelative?
981 This calculation here and HOWTO should match. */
985 /* If it's 32 bit quantity then 16bit code needs to be added. */
988 if (head
->type
== Expr_Node_Constant
)
990 /* If note1 is not null code, we have to generate a right
991 aligned value for the constant. Otherwise the reloc is
992 a part of the basic command and the yacc file
994 value
= head
->value
.i_value
;
996 switch (parent_reloc
)
998 /* Some relocations will need to allocate extra words. */
999 case BFD_RELOC_BFIN_16_IMM
:
1000 case BFD_RELOC_BFIN_16_LOW
:
1001 case BFD_RELOC_BFIN_16_HIGH
:
1002 note1
= conscode (gencode (value
), NULL_CODE
);
1005 case BFD_RELOC_BFIN_PLTPC
:
1006 note1
= conscode (gencode (value
), NULL_CODE
);
1010 case BFD_RELOC_BFIN_GOT
:
1011 case BFD_RELOC_BFIN_GOT17M4
:
1012 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
1013 note1
= conscode (gencode (value
), NULL_CODE
);
1016 case BFD_RELOC_24_PCREL
:
1017 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
1018 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
1019 /* These offsets are even numbered pcrel. */
1020 note1
= conscode (gencode (value
>> 1), NULL_CODE
);
1026 if (head
->type
== Expr_Node_Constant
)
1028 else if (head
->type
== Expr_Node_Reloc
)
1030 note
= note_reloc1 (gencode (0), head
->value
.s_value
, parent_reloc
, pcrel
);
1031 if (note1
!= NULL_CODE
)
1032 note
= conscode (note1
, note
);
1034 else if (head
->type
== Expr_Node_Binop
1035 && (head
->value
.op_value
== Expr_Op_Type_Add
1036 || head
->value
.op_value
== Expr_Op_Type_Sub
)
1037 && head
->Left_Child
->type
== Expr_Node_Reloc
1038 && head
->Right_Child
->type
== Expr_Node_Constant
)
1040 int val
= head
->Right_Child
->value
.i_value
;
1041 if (head
->value
.op_value
== Expr_Op_Type_Sub
)
1043 note
= conscode (note_reloc2 (gencode (0), head
->Left_Child
->value
.s_value
,
1044 parent_reloc
, val
, 0),
1046 if (note1
!= NULL_CODE
)
1047 note
= conscode (note1
, note
);
1051 /* Call the recursive function. */
1052 note
= note_reloc1 (gencode (0), op
, parent_reloc
, pcrel
);
1053 if (note1
!= NULL_CODE
)
1054 note
= conscode (note1
, note
);
1055 note
= conctcode (Expr_Node_Gen_Reloc_R (head
), note
);
1061 Expr_Node_Gen_Reloc_R (Expr_Node
* head
)
1069 case Expr_Node_Constant
:
1070 note
= conscode (note_reloc2 (gencode (0), con
, BFD_ARELOC_BFIN_CONST
, head
->value
.i_value
, 0), NULL_CODE
);
1072 case Expr_Node_Reloc
:
1073 note
= conscode (note_reloc (gencode (0), head
, BFD_ARELOC_BFIN_PUSH
, 0), NULL_CODE
);
1075 case Expr_Node_Binop
:
1076 note1
= conctcode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), Expr_Node_Gen_Reloc_R (head
->Right_Child
));
1077 switch (head
->value
.op_value
)
1079 case Expr_Op_Type_Add
:
1080 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_ADD
, 0), NULL_CODE
));
1082 case Expr_Op_Type_Sub
:
1083 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_SUB
, 0), NULL_CODE
));
1085 case Expr_Op_Type_Mult
:
1086 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MULT
, 0), NULL_CODE
));
1088 case Expr_Op_Type_Div
:
1089 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_DIV
, 0), NULL_CODE
));
1091 case Expr_Op_Type_Mod
:
1092 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MOD
, 0), NULL_CODE
));
1094 case Expr_Op_Type_Lshift
:
1095 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LSHIFT
, 0), NULL_CODE
));
1097 case Expr_Op_Type_Rshift
:
1098 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_RSHIFT
, 0), NULL_CODE
));
1100 case Expr_Op_Type_BAND
:
1101 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_AND
, 0), NULL_CODE
));
1103 case Expr_Op_Type_BOR
:
1104 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_OR
, 0), NULL_CODE
));
1106 case Expr_Op_Type_BXOR
:
1107 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_XOR
, 0), NULL_CODE
));
1109 case Expr_Op_Type_LAND
:
1110 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LAND
, 0), NULL_CODE
));
1112 case Expr_Op_Type_LOR
:
1113 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LOR
, 0), NULL_CODE
));
1116 fprintf (stderr
, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1121 case Expr_Node_Unop
:
1122 note1
= conscode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), NULL_CODE
);
1123 switch (head
->value
.op_value
)
1125 case Expr_Op_Type_NEG
:
1126 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_NEG
, 0), NULL_CODE
));
1128 case Expr_Op_Type_COMP
:
1129 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_COMP
, 0), NULL_CODE
));
1132 fprintf (stderr
, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1136 fprintf (stderr
, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__
, __LINE__
);
1141 /* Blackfin opcode generation. */
1143 /* These functions are called by the generated parser
1144 (from bfin-parse.y), the register type classification
1145 happens in bfin-lex.l. */
1147 #include "bfin-aux.h"
1148 #include "opcode/bfin.h"
1150 #define INIT(t) t c_code = init_##t
1151 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1152 #define ASSIGNF(x,f) c_code.opcode |= ((x & c_code.mask_##f)<<c_code.bits_##f)
1153 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1155 #define HI(x) ((x >> 16) & 0xffff)
1156 #define LO(x) ((x ) & 0xffff)
1158 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1160 #define GEN_OPCODE32() \
1161 conscode (gencode (HI (c_code.opcode)), \
1162 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1164 #define GEN_OPCODE16() \
1165 conscode (gencode (c_code.opcode), NULL_CODE)
1168 /* 32 BIT INSTRUCTIONS. */
1171 /* DSP32 instruction generation. */
1174 bfin_gen_dsp32mac (int op1
, int MM
, int mmod
, int w1
, int P
,
1175 int h01
, int h11
, int h00
, int h10
, int op0
,
1176 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1192 /* If we have full reg assignments, mask out LSB to encode
1193 single or simultaneous even/odd register moves. */
1203 return GEN_OPCODE32 ();
1207 bfin_gen_dsp32mult (int op1
, int MM
, int mmod
, int w1
, int P
,
1208 int h01
, int h11
, int h00
, int h10
, int op0
,
1209 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1234 return GEN_OPCODE32 ();
1238 bfin_gen_dsp32alu (int HL
, int aopcde
, int aop
, int s
, int x
,
1239 REG_T dst0
, REG_T dst1
, REG_T src0
, REG_T src1
)
1253 return GEN_OPCODE32 ();
1257 bfin_gen_dsp32shift (int sopcde
, REG_T dst0
, REG_T src0
,
1258 REG_T src1
, int sop
, int HLs
)
1270 return GEN_OPCODE32 ();
1274 bfin_gen_dsp32shiftimm (int sopcde
, REG_T dst0
, int immag
,
1275 REG_T src1
, int sop
, int HLs
)
1277 INIT (DSP32ShiftImm
);
1287 return GEN_OPCODE32 ();
1293 bfin_gen_loopsetup (Expr_Node
* psoffset
, REG_T c
, int rop
,
1294 Expr_Node
* peoffset
, REG_T reg
)
1296 int soffset
, eoffset
;
1299 soffset
= (EXPR_VALUE (psoffset
) >> 1);
1301 eoffset
= (EXPR_VALUE (peoffset
) >> 1);
1308 conscode (gencode (HI (c_code
.opcode
)),
1309 conctcode (Expr_Node_Gen_Reloc (psoffset
, BFD_RELOC_BFIN_5_PCREL
),
1310 conctcode (gencode (LO (c_code
.opcode
)), Expr_Node_Gen_Reloc (peoffset
, BFD_RELOC_BFIN_11_PCREL
))));
1317 bfin_gen_calla (Expr_Node
* addr
, int S
)
1325 case 0 : rel
= BFD_RELOC_BFIN_24_PCREL_JUMP_L
; break;
1326 case 1 : rel
= BFD_RELOC_24_PCREL
; break;
1327 case 2 : rel
= BFD_RELOC_BFIN_PLTPC
; break;
1333 val
= EXPR_VALUE (addr
) >> 1;
1334 high_val
= val
>> 16;
1336 return conscode (gencode (HI (c_code
.opcode
) | (high_val
& 0xff)),
1337 Expr_Node_Gen_Reloc (addr
, rel
));
1341 bfin_gen_linkage (int R
, int framesize
)
1348 return GEN_OPCODE32 ();
1352 /* Load and Store. */
1355 bfin_gen_ldimmhalf (REG_T reg
, int H
, int S
, int Z
, Expr_Node
* phword
, int rel
)
1358 unsigned val
= EXPR_VALUE (phword
);
1366 grp
= (GROUP (reg
));
1370 return conscode (gencode (HI (c_code
.opcode
)), Expr_Node_Gen_Reloc (phword
, BFD_RELOC_BFIN_16_IMM
));
1374 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
));
1381 return GEN_OPCODE32 ();
1385 bfin_gen_ldstidxi (REG_T ptr
, REG_T reg
, int W
, int sz
, int Z
, Expr_Node
* poffset
)
1389 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1391 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1402 if (poffset
->type
!= Expr_Node_Constant
)
1404 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1405 /* distinguish between R0 = [P5 + symbol@GOT] and
1406 P5 = [P5 + _current_shared_library_p5_offset_]
1408 if (poffset
->type
== Expr_Node_Reloc
1409 && !strcmp (poffset
->value
.s_value
,
1410 "_current_shared_library_p5_offset_"))
1412 return conscode (gencode (HI (c_code
.opcode
)),
1413 Expr_Node_Gen_Reloc(poffset
, BFD_RELOC_16
));
1415 else if (poffset
->type
!= Expr_Node_GOT_Reloc
)
1418 return conscode (gencode (HI (c_code
.opcode
)),
1419 Expr_Node_Gen_Reloc(poffset
->Left_Child
,
1420 poffset
->value
.i_value
));
1426 { /* load/store access size */
1427 case 0: /* 32 bit */
1428 value
= EXPR_VALUE (poffset
) >> 2;
1430 case 1: /* 16 bit */
1431 value
= EXPR_VALUE (poffset
) >> 1;
1434 value
= EXPR_VALUE (poffset
);
1440 offset
= (value
& 0xffff);
1442 return GEN_OPCODE32 ();
1448 bfin_gen_ldst (REG_T ptr
, REG_T reg
, int aop
, int sz
, int Z
, int W
)
1452 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1454 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1465 return GEN_OPCODE16 ();
1469 bfin_gen_ldstii (REG_T ptr
, REG_T reg
, Expr_Node
* poffset
, int W
, int opc
)
1475 if (!IS_PREG (*ptr
))
1477 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1485 value
= EXPR_VALUE (poffset
) >> 1;
1489 value
= EXPR_VALUE (poffset
) >> 2;
1501 return GEN_OPCODE16 ();
1505 bfin_gen_ldstiifp (REG_T sreg
, Expr_Node
* poffset
, int W
)
1507 /* Set bit 4 if it's a Preg. */
1508 int reg
= (sreg
->regno
& CODE_MASK
) | (IS_PREG (*sreg
) ? 0x8 : 0x0);
1509 int offset
= ((~(EXPR_VALUE (poffset
) >> 2)) & 0x1f) + 1;
1515 return GEN_OPCODE16 ();
1519 bfin_gen_ldstpmod (REG_T ptr
, REG_T reg
, int aop
, int W
, REG_T idx
)
1529 return GEN_OPCODE16 ();
1533 bfin_gen_dspldst (REG_T i
, REG_T reg
, int aop
, int W
, int m
)
1543 return GEN_OPCODE16 ();
1547 bfin_gen_logi2op (int opc
, int src
, int dst
)
1555 return GEN_OPCODE16 ();
1559 bfin_gen_brcc (int T
, int B
, Expr_Node
* poffset
)
1566 offset
= ((EXPR_VALUE (poffset
) >> 1));
1568 return conscode (gencode (c_code
.opcode
), Expr_Node_Gen_Reloc (poffset
, BFD_RELOC_BFIN_10_PCREL
));
1572 bfin_gen_ujump (Expr_Node
* poffset
)
1577 offset
= ((EXPR_VALUE (poffset
) >> 1));
1580 return conscode (gencode (c_code
.opcode
),
1581 Expr_Node_Gen_Reloc (
1582 poffset
, BFD_RELOC_BFIN_12_PCREL_JUMP_S
));
1586 bfin_gen_alu2op (REG_T dst
, REG_T src
, int opc
)
1594 return GEN_OPCODE16 ();
1598 bfin_gen_compi2opd (REG_T dst
, int src
, int opc
)
1606 return GEN_OPCODE16 ();
1610 bfin_gen_compi2opp (REG_T dst
, int src
, int opc
)
1618 return GEN_OPCODE16 ();
1622 bfin_gen_dagmodik (REG_T i
, int opc
)
1629 return GEN_OPCODE16 ();
1633 bfin_gen_dagmodim (REG_T i
, REG_T m
, int opc
, int br
)
1642 return GEN_OPCODE16 ();
1646 bfin_gen_ptr2op (REG_T dst
, REG_T src
, int opc
)
1654 return GEN_OPCODE16 ();
1658 bfin_gen_comp3op (REG_T src0
, REG_T src1
, REG_T dst
, int opc
)
1667 return GEN_OPCODE16 ();
1671 bfin_gen_ccflag (REG_T x
, int y
, int opc
, int I
, int G
)
1681 return GEN_OPCODE16 ();
1685 bfin_gen_ccmv (REG_T src
, REG_T dst
, int T
)
1698 return GEN_OPCODE16 ();
1702 bfin_gen_cc2stat (int cbit
, int opc
, int D
)
1710 return GEN_OPCODE16 ();
1714 bfin_gen_regmv (REG_T src
, REG_T dst
)
1727 return GEN_OPCODE16 ();
1731 bfin_gen_cc2dreg (int opc
, REG_T reg
)
1738 return GEN_OPCODE16 ();
1742 bfin_gen_progctrl (int prgfunc
, int poprnd
)
1749 return GEN_OPCODE16 ();
1753 bfin_gen_cactrl (REG_T reg
, int a
, int opc
)
1761 return GEN_OPCODE16 ();
1765 bfin_gen_pushpopmultiple (int dr
, int pr
, int d
, int p
, int W
)
1767 INIT (PushPopMultiple
);
1775 return GEN_OPCODE16 ();
1779 bfin_gen_pushpopreg (REG_T reg
, int W
)
1785 grp
= (GROUP (reg
));
1789 return GEN_OPCODE16 ();
1792 /* Pseudo Debugging Support. */
1795 bfin_gen_pseudodbg (int fn
, int reg
, int grp
)
1803 return GEN_OPCODE16 ();
1807 bfin_gen_pseudodbg_assert (int dbgop
, REG_T regtest
, int expected
)
1810 INIT (PseudoDbg_Assert
);
1814 grp
= GROUP (regtest
);
1818 return GEN_OPCODE32 ();
1822 bfin_gen_pseudochr (int ch
)
1828 return GEN_OPCODE16 ();
1831 /* Multiple instruction generation. */
1834 bfin_gen_multi_instr (INSTR_T dsp32
, INSTR_T dsp16_grp1
, INSTR_T dsp16_grp2
)
1838 /* If it's a 0, convert into MNOP. */
1842 SET_MULTI_INSTRUCTION_BIT (dsp32
);
1846 dsp32
= gencode (0xc803);
1847 walk
= gencode (0x1800);
1853 dsp16_grp1
= gencode (0x0000);
1858 dsp16_grp2
= gencode (0x0000);
1861 walk
->next
= dsp16_grp1
;
1862 dsp16_grp1
->next
= dsp16_grp2
;
1863 dsp16_grp2
->next
= NULL_CODE
;
1869 bfin_gen_loop (Expr_Node
*exp
, REG_T reg
, int rop
, REG_T preg
)
1871 const char *loopsym
;
1872 char *lbeginsym
, *lendsym
;
1873 Expr_Node_Value lbeginval
, lendval
;
1874 Expr_Node
*lbegin
, *lend
;
1877 loopsym
= exp
->value
.s_value
;
1878 lbeginsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__BEGIN") + 5);
1879 lendsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__END") + 5);
1884 strcat (lbeginsym
, "L$L$");
1885 strcat (lbeginsym
, loopsym
);
1886 strcat (lbeginsym
, "__BEGIN");
1888 strcat (lendsym
, "L$L$");
1889 strcat (lendsym
, loopsym
);
1890 strcat (lendsym
, "__END");
1892 lbeginval
.s_value
= lbeginsym
;
1893 lendval
.s_value
= lendsym
;
1895 lbegin
= Expr_Node_Create (Expr_Node_Reloc
, lbeginval
, NULL
, NULL
);
1896 lend
= Expr_Node_Create (Expr_Node_Reloc
, lendval
, NULL
, NULL
);
1898 sym
= symbol_find(loopsym
);
1899 if (!S_IS_LOCAL (sym
) || (S_IS_LOCAL (sym
) && !symbol_used_p (sym
)))
1900 symbol_remove (sym
, &symbol_rootP
, &symbol_lastP
);
1902 return bfin_gen_loopsetup (lbegin
, reg
, rop
, lend
, preg
);
1906 bfin_loop_attempt_create_label (Expr_Node
*exp
, int is_begin
)
1909 name
= fb_label_name (exp
->value
.i_value
, is_begin
);
1910 exp
->value
.s_value
= xstrdup (name
);
1911 exp
->type
= Expr_Node_Reloc
;
1915 bfin_loop_beginend (Expr_Node
*exp
, int begin
)
1917 const char *loopsym
;
1920 const char *suffix
= begin
? "__BEGIN" : "__END";
1922 loopsym
= exp
->value
.s_value
;
1923 label_name
= (char *) xmalloc (strlen (loopsym
) + strlen (suffix
) + 5);
1927 strcat (label_name
, "L$L$");
1928 strcat (label_name
, loopsym
);
1929 strcat (label_name
, suffix
);
1931 linelabel
= colon (label_name
);
1933 /* LOOP_END follows the last instruction in the loop.
1934 Adjust label address. */
1936 ((struct local_symbol
*) linelabel
)->lsy_value
-= last_insn_size
;
1940 bfin_eol_in_insn (char *line
)
1942 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1949 /* A semi-colon followed by a newline is always the end of a line. */
1950 if (line
[-1] == ';')
1953 if (line
[-1] == '|')
1956 /* If the || is on the next line, there might be leading whitespace. */
1958 while (*temp
== ' ' || *temp
== '\t') temp
++;
1967 bfin_start_label (char *s
)
1971 if (*s
== '(' || *s
== '[')
1980 bfin_force_relocation (struct fix
*fixp
)
1982 if (fixp
->fx_r_type
==BFD_RELOC_BFIN_16_LOW
1983 || fixp
->fx_r_type
== BFD_RELOC_BFIN_16_HIGH
)
1986 return generic_force_reloc (fixp
);
1989 /* This is a stripped down version of the disassembler. The only thing it
1990 does is return a mask of registers modified by an instruction. Only
1991 instructions that can occur in a parallel-issue bundle are handled, and
1992 only the registers that can cause a conflict are recorded. */
1994 #define DREG_MASK(n) (0x101 << (n))
1995 #define DREGH_MASK(n) (0x100 << (n))
1996 #define DREGL_MASK(n) (0x001 << (n))
1997 #define IREG_MASK(n) (1 << ((n) + 16))
2000 decode_ProgCtrl_0 (int iw0
)
2008 decode_LDSTpmod_0 (int iw0
)
2011 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2012 | 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......|
2013 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2014 int W
= ((iw0
>> LDSTpmod_W_bits
) & LDSTpmod_W_mask
);
2015 int aop
= ((iw0
>> LDSTpmod_aop_bits
) & LDSTpmod_aop_mask
);
2016 int idx
= ((iw0
>> LDSTpmod_idx_bits
) & LDSTpmod_idx_mask
);
2017 int ptr
= ((iw0
>> LDSTpmod_ptr_bits
) & LDSTpmod_ptr_mask
);
2018 int reg
= ((iw0
>> LDSTpmod_reg_bits
) & LDSTpmod_reg_mask
);
2020 if (aop
== 1 && W
== 0 && idx
== ptr
)
2021 return DREGL_MASK (reg
);
2022 else if (aop
== 2 && W
== 0 && idx
== ptr
)
2023 return DREGH_MASK (reg
);
2024 else if (aop
== 1 && W
== 1 && idx
== ptr
)
2026 else if (aop
== 2 && W
== 1 && idx
== ptr
)
2028 else if (aop
== 0 && W
== 0)
2029 return DREG_MASK (reg
);
2030 else if (aop
== 1 && W
== 0)
2031 return DREGL_MASK (reg
);
2032 else if (aop
== 2 && W
== 0)
2033 return DREGH_MASK (reg
);
2034 else if (aop
== 3 && W
== 0)
2035 return DREG_MASK (reg
);
2036 else if (aop
== 3 && W
== 1)
2037 return DREG_MASK (reg
);
2038 else if (aop
== 0 && W
== 1)
2040 else if (aop
== 1 && W
== 1)
2042 else if (aop
== 2 && W
== 1)
2051 decode_dagMODim_0 (int iw0
)
2054 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2055 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....|
2056 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2057 int i
= ((iw0
>> DagMODim_i_bits
) & DagMODim_i_mask
);
2058 int opc
= ((iw0
>> DagMODim_op_bits
) & DagMODim_op_mask
);
2060 if (opc
== 0 || opc
== 1)
2061 return IREG_MASK (i
);
2069 decode_dagMODik_0 (int iw0
)
2072 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2073 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....|
2074 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2075 int i
= ((iw0
>> DagMODik_i_bits
) & DagMODik_i_mask
);
2076 return IREG_MASK (i
);
2081 decode_dspLDST_0 (int iw0
)
2084 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2085 | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......|
2086 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2087 int i
= ((iw0
>> DspLDST_i_bits
) & DspLDST_i_mask
);
2088 int m
= ((iw0
>> DspLDST_m_bits
) & DspLDST_m_mask
);
2089 int W
= ((iw0
>> DspLDST_W_bits
) & DspLDST_W_mask
);
2090 int aop
= ((iw0
>> DspLDST_aop_bits
) & DspLDST_aop_mask
);
2091 int reg
= ((iw0
>> DspLDST_reg_bits
) & DspLDST_reg_mask
);
2093 if (aop
== 0 && W
== 0 && m
== 0)
2094 return DREG_MASK (reg
) | IREG_MASK (i
);
2095 else if (aop
== 0 && W
== 0 && m
== 1)
2096 return DREGL_MASK (reg
) | IREG_MASK (i
);
2097 else if (aop
== 0 && W
== 0 && m
== 2)
2098 return DREGH_MASK (reg
) | IREG_MASK (i
);
2099 else if (aop
== 1 && W
== 0 && m
== 0)
2100 return DREG_MASK (reg
) | IREG_MASK (i
);
2101 else if (aop
== 1 && W
== 0 && m
== 1)
2102 return DREGL_MASK (reg
) | IREG_MASK (i
);
2103 else if (aop
== 1 && W
== 0 && m
== 2)
2104 return DREGH_MASK (reg
) | IREG_MASK (i
);
2105 else if (aop
== 2 && W
== 0 && m
== 0)
2106 return DREG_MASK (reg
);
2107 else if (aop
== 2 && W
== 0 && m
== 1)
2108 return DREGL_MASK (reg
);
2109 else if (aop
== 2 && W
== 0 && m
== 2)
2110 return DREGH_MASK (reg
);
2111 else if (aop
== 0 && W
== 1 && m
== 0)
2112 return IREG_MASK (i
);
2113 else if (aop
== 0 && W
== 1 && m
== 1)
2114 return IREG_MASK (i
);
2115 else if (aop
== 0 && W
== 1 && m
== 2)
2116 return IREG_MASK (i
);
2117 else if (aop
== 1 && W
== 1 && m
== 0)
2118 return IREG_MASK (i
);
2119 else if (aop
== 1 && W
== 1 && m
== 1)
2120 return IREG_MASK (i
);
2121 else if (aop
== 1 && W
== 1 && m
== 2)
2122 return IREG_MASK (i
);
2123 else if (aop
== 2 && W
== 1 && m
== 0)
2125 else if (aop
== 2 && W
== 1 && m
== 1)
2127 else if (aop
== 2 && W
== 1 && m
== 2)
2129 else if (aop
== 3 && W
== 0)
2130 return DREG_MASK (reg
) | IREG_MASK (i
);
2131 else if (aop
== 3 && W
== 1)
2132 return IREG_MASK (i
);
2139 decode_LDST_0 (int iw0
)
2142 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2143 | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......|
2144 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2145 int Z
= ((iw0
>> LDST_Z_bits
) & LDST_Z_mask
);
2146 int W
= ((iw0
>> LDST_W_bits
) & LDST_W_mask
);
2147 int sz
= ((iw0
>> LDST_sz_bits
) & LDST_sz_mask
);
2148 int aop
= ((iw0
>> LDST_aop_bits
) & LDST_aop_mask
);
2149 int reg
= ((iw0
>> LDST_reg_bits
) & LDST_reg_mask
);
2151 if (aop
== 0 && sz
== 0 && Z
== 0 && W
== 0)
2152 return DREG_MASK (reg
);
2153 else if (aop
== 0 && sz
== 0 && Z
== 1 && W
== 0)
2155 else if (aop
== 0 && sz
== 1 && Z
== 0 && W
== 0)
2156 return DREG_MASK (reg
);
2157 else if (aop
== 0 && sz
== 1 && Z
== 1 && W
== 0)
2158 return DREG_MASK (reg
);
2159 else if (aop
== 0 && sz
== 2 && Z
== 0 && W
== 0)
2160 return DREG_MASK (reg
);
2161 else if (aop
== 0 && sz
== 2 && Z
== 1 && W
== 0)
2162 return DREG_MASK (reg
);
2163 else if (aop
== 1 && sz
== 0 && Z
== 0 && W
== 0)
2164 return DREG_MASK (reg
);
2165 else if (aop
== 1 && sz
== 0 && Z
== 1 && W
== 0)
2167 else if (aop
== 1 && sz
== 1 && Z
== 0 && W
== 0)
2168 return DREG_MASK (reg
);
2169 else if (aop
== 1 && sz
== 1 && Z
== 1 && W
== 0)
2170 return DREG_MASK (reg
);
2171 else if (aop
== 1 && sz
== 2 && Z
== 0 && W
== 0)
2172 return DREG_MASK (reg
);
2173 else if (aop
== 1 && sz
== 2 && Z
== 1 && W
== 0)
2174 return DREG_MASK (reg
);
2175 else if (aop
== 2 && sz
== 0 && Z
== 0 && W
== 0)
2176 return DREG_MASK (reg
);
2177 else if (aop
== 2 && sz
== 0 && Z
== 1 && W
== 0)
2179 else if (aop
== 2 && sz
== 1 && Z
== 0 && W
== 0)
2180 return DREG_MASK (reg
);
2181 else if (aop
== 2 && sz
== 1 && Z
== 1 && W
== 0)
2182 return DREG_MASK (reg
);
2183 else if (aop
== 2 && sz
== 2 && Z
== 0 && W
== 0)
2184 return DREG_MASK (reg
);
2185 else if (aop
== 2 && sz
== 2 && Z
== 1 && W
== 0)
2186 return DREG_MASK (reg
);
2187 else if (aop
== 0 && sz
== 0 && Z
== 0 && W
== 1)
2189 else if (aop
== 0 && sz
== 0 && Z
== 1 && W
== 1)
2191 else if (aop
== 0 && sz
== 1 && Z
== 0 && W
== 1)
2193 else if (aop
== 0 && sz
== 2 && Z
== 0 && W
== 1)
2195 else if (aop
== 1 && sz
== 0 && Z
== 0 && W
== 1)
2197 else if (aop
== 1 && sz
== 0 && Z
== 1 && W
== 1)
2199 else if (aop
== 1 && sz
== 1 && Z
== 0 && W
== 1)
2201 else if (aop
== 1 && sz
== 2 && Z
== 0 && W
== 1)
2203 else if (aop
== 2 && sz
== 0 && Z
== 0 && W
== 1)
2205 else if (aop
== 2 && sz
== 0 && Z
== 1 && W
== 1)
2207 else if (aop
== 2 && sz
== 1 && Z
== 0 && W
== 1)
2209 else if (aop
== 2 && sz
== 2 && Z
== 0 && W
== 1)
2216 decode_LDSTiiFP_0 (int iw0
)
2219 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2220 | 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........|
2221 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2222 int reg
= ((iw0
>> LDSTiiFP_reg_bits
) & LDSTiiFP_reg_mask
);
2223 int W
= ((iw0
>> LDSTiiFP_W_bits
) & LDSTiiFP_W_mask
);
2226 return reg
< 8 ? DREG_MASK (reg
) : 0;
2232 decode_LDSTii_0 (int iw0
)
2235 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2236 | 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......|
2237 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2238 int reg
= ((iw0
>> LDSTii_reg_bit
) & LDSTii_reg_mask
);
2239 int opc
= ((iw0
>> LDSTii_op_bit
) & LDSTii_op_mask
);
2240 int W
= ((iw0
>> LDSTii_W_bit
) & LDSTii_W_mask
);
2242 if (W
== 0 && opc
!= 3)
2243 return DREG_MASK (reg
);
2244 else if (W
== 0 && opc
== 3)
2246 else if (W
== 1 && opc
== 0)
2248 else if (W
== 1 && opc
== 1)
2250 else if (W
== 1 && opc
== 3)
2257 decode_dsp32mac_0 (int iw0
, int iw1
)
2261 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2262 | 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...|
2263 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2264 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2265 int op1
= ((iw0
>> (DSP32Mac_op1_bits
- 16)) & DSP32Mac_op1_mask
);
2266 int w1
= ((iw0
>> (DSP32Mac_w1_bits
- 16)) & DSP32Mac_w1_mask
);
2267 int P
= ((iw0
>> (DSP32Mac_p_bits
- 16)) & DSP32Mac_p_mask
);
2268 int mmod
= ((iw0
>> (DSP32Mac_mmod_bits
- 16)) & DSP32Mac_mmod_mask
);
2269 int w0
= ((iw1
>> DSP32Mac_w0_bits
) & DSP32Mac_w0_mask
);
2270 int MM
= ((iw1
>> DSP32Mac_MM_bits
) & DSP32Mac_MM_mask
);
2271 int dst
= ((iw1
>> DSP32Mac_dst_bits
) & DSP32Mac_dst_mask
);
2272 int op0
= ((iw1
>> DSP32Mac_op0_bits
) & DSP32Mac_op0_mask
);
2274 if (w0
== 0 && w1
== 0 && op1
== 3 && op0
== 3)
2280 if ((w1
|| w0
) && mmod
== M_W32
)
2283 if (((1 << mmod
) & (P
? 0x131b : 0x1b5f)) == 0)
2286 if (w1
== 1 || op1
!= 3)
2291 return DREG_MASK (dst
+ 1);
2293 return DREGH_MASK (dst
);
2297 if (w0
== 1 || op0
!= 3)
2302 return DREG_MASK (dst
);
2304 return DREGL_MASK (dst
);
2312 decode_dsp32mult_0 (int iw0
, int iw1
)
2315 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2316 | 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...|
2317 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2318 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2319 int w1
= ((iw0
>> (DSP32Mac_w1_bits
- 16)) & DSP32Mac_w1_mask
);
2320 int P
= ((iw0
>> (DSP32Mac_p_bits
- 16)) & DSP32Mac_p_mask
);
2321 int mmod
= ((iw0
>> (DSP32Mac_mmod_bits
- 16)) & DSP32Mac_mmod_mask
);
2322 int w0
= ((iw1
>> DSP32Mac_w0_bits
) & DSP32Mac_w0_mask
);
2323 int dst
= ((iw1
>> DSP32Mac_dst_bits
) & DSP32Mac_dst_mask
);
2326 if (w1
== 0 && w0
== 0)
2329 if (((1 << mmod
) & (P
? 0x313 : 0x1b57)) == 0)
2335 return DREG_MASK (dst
| 1);
2337 return DREGH_MASK (dst
);
2343 return DREG_MASK (dst
);
2345 return DREGL_MASK (dst
);
2352 decode_dsp32alu_0 (int iw0
, int iw1
)
2355 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2356 | 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............|
2357 |.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......|
2358 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2359 int s
= ((iw1
>> DSP32Alu_s_bits
) & DSP32Alu_s_mask
);
2360 int x
= ((iw1
>> DSP32Alu_x_bits
) & DSP32Alu_x_mask
);
2361 int aop
= ((iw1
>> DSP32Alu_aop_bits
) & DSP32Alu_aop_mask
);
2362 int dst0
= ((iw1
>> DSP32Alu_dst0_bits
) & DSP32Alu_dst0_mask
);
2363 int dst1
= ((iw1
>> DSP32Alu_dst1_bits
) & DSP32Alu_dst1_mask
);
2364 int HL
= ((iw0
>> (DSP32Alu_HL_bits
- 16)) & DSP32Alu_HL_mask
);
2365 int aopcde
= ((iw0
>> (DSP32Alu_aopcde_bits
- 16)) & DSP32Alu_aopcde_mask
);
2367 if (aop
== 0 && aopcde
== 9 && s
== 0)
2369 else if (aop
== 2 && aopcde
== 9 && HL
== 0 && s
== 0)
2371 else if (aop
>= x
* 2 && aopcde
== 5)
2372 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2373 else if (HL
== 0 && aopcde
== 2)
2374 return DREGL_MASK (dst0
);
2375 else if (HL
== 1 && aopcde
== 2)
2376 return DREGH_MASK (dst0
);
2377 else if (HL
== 0 && aopcde
== 3)
2378 return DREGL_MASK (dst0
);
2379 else if (HL
== 1 && aopcde
== 3)
2380 return DREGH_MASK (dst0
);
2382 else if (aop
== 0 && aopcde
== 9 && s
== 1)
2384 else if (aop
== 1 && aopcde
== 9 && s
== 0)
2386 else if (aop
== 2 && aopcde
== 9 && s
== 1)
2388 else if (aop
== 3 && aopcde
== 9 && s
== 0)
2390 else if (aopcde
== 8)
2392 else if (aop
== 0 && aopcde
== 11)
2393 return DREG_MASK (dst0
);
2394 else if (aop
== 1 && aopcde
== 11)
2395 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2396 else if (aopcde
== 11)
2398 else if (aopcde
== 22)
2399 return DREG_MASK (dst0
);
2401 else if ((aop
== 0 || aop
== 1) && aopcde
== 14)
2403 else if (aop
== 3 && HL
== 0 && aopcde
== 14)
2406 else if (aop
== 3 && HL
== 0 && aopcde
== 15)
2407 return DREG_MASK (dst0
);
2409 else if (aop
== 1 && aopcde
== 16)
2412 else if (aop
== 0 && aopcde
== 16)
2415 else if (aop
== 3 && HL
== 0 && aopcde
== 16)
2418 else if (aop
== 3 && HL
== 0 && aopcde
== 7)
2419 return DREG_MASK (dst0
);
2420 else if ((aop
== 0 || aop
== 1 || aop
== 2) && aopcde
== 7)
2421 return DREG_MASK (dst0
);
2423 else if (aop
== 0 && aopcde
== 12)
2424 return DREG_MASK (dst0
);
2425 else if (aop
== 1 && aopcde
== 12)
2426 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2427 else if (aop
== 3 && aopcde
== 12)
2428 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2430 else if (aopcde
== 0)
2431 return DREG_MASK (dst0
);
2432 else if (aopcde
== 1)
2433 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2435 else if (aop
== 0 && aopcde
== 10)
2436 return DREGL_MASK (dst0
);
2437 else if (aop
== 1 && aopcde
== 10)
2438 return DREGL_MASK (dst0
);
2440 else if ((aop
== 1 || aop
== 0) && aopcde
== 4)
2441 return DREG_MASK (dst0
);
2442 else if (aop
== 2 && aopcde
== 4)
2443 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2445 else if (aop
== 0 && aopcde
== 17)
2446 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2447 else if (aop
== 1 && aopcde
== 17)
2448 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2449 else if (aop
== 0 && aopcde
== 18)
2451 else if (aop
== 3 && aopcde
== 18)
2454 else if ((aop
== 0 || aop
== 1 || aop
== 2) && aopcde
== 6)
2455 return DREG_MASK (dst0
);
2457 else if ((aop
== 0 || aop
== 1) && aopcde
== 20)
2458 return DREG_MASK (dst0
);
2460 else if ((aop
== 0 || aop
== 1) && aopcde
== 21)
2461 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2463 else if (aop
== 0 && aopcde
== 23 && HL
== 1)
2464 return DREG_MASK (dst0
);
2465 else if (aop
== 0 && aopcde
== 23 && HL
== 0)
2466 return DREG_MASK (dst0
);
2468 else if (aop
== 0 && aopcde
== 24)
2469 return DREG_MASK (dst0
);
2470 else if (aop
== 1 && aopcde
== 24)
2471 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2472 else if (aopcde
== 13)
2473 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2481 decode_dsp32shift_0 (int iw0
, int iw1
)
2484 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2485 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............|
2486 |.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......|
2487 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2488 int HLs
= ((iw1
>> DSP32Shift_HLs_bits
) & DSP32Shift_HLs_mask
);
2489 int sop
= ((iw1
>> DSP32Shift_sop_bits
) & DSP32Shift_sop_mask
);
2490 int src0
= ((iw1
>> DSP32Shift_src0_bits
) & DSP32Shift_src0_mask
);
2491 int src1
= ((iw1
>> DSP32Shift_src1_bits
) & DSP32Shift_src1_mask
);
2492 int dst0
= ((iw1
>> DSP32Shift_dst0_bits
) & DSP32Shift_dst0_mask
);
2493 int sopcde
= ((iw0
>> (DSP32Shift_sopcde_bits
- 16)) & DSP32Shift_sopcde_mask
);
2495 if (sop
== 0 && sopcde
== 0)
2496 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2497 else if (sop
== 1 && sopcde
== 0)
2498 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2499 else if (sop
== 2 && sopcde
== 0)
2500 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2501 else if (sop
== 0 && sopcde
== 3)
2503 else if (sop
== 1 && sopcde
== 3)
2505 else if (sop
== 2 && sopcde
== 3)
2507 else if (sop
== 3 && sopcde
== 3)
2508 return DREG_MASK (dst0
);
2509 else if (sop
== 0 && sopcde
== 1)
2510 return DREG_MASK (dst0
);
2511 else if (sop
== 1 && sopcde
== 1)
2512 return DREG_MASK (dst0
);
2513 else if (sop
== 2 && sopcde
== 1)
2514 return DREG_MASK (dst0
);
2515 else if (sopcde
== 2)
2516 return DREG_MASK (dst0
);
2517 else if (sopcde
== 4)
2518 return DREG_MASK (dst0
);
2519 else if (sop
== 0 && sopcde
== 5)
2520 return DREGL_MASK (dst0
);
2521 else if (sop
== 1 && sopcde
== 5)
2522 return DREGL_MASK (dst0
);
2523 else if (sop
== 2 && sopcde
== 5)
2524 return DREGL_MASK (dst0
);
2525 else if (sop
== 0 && sopcde
== 6)
2526 return DREGL_MASK (dst0
);
2527 else if (sop
== 1 && sopcde
== 6)
2528 return DREGL_MASK (dst0
);
2529 else if (sop
== 3 && sopcde
== 6)
2530 return DREGL_MASK (dst0
);
2531 else if (sop
== 0 && sopcde
== 7)
2532 return DREGL_MASK (dst0
);
2533 else if (sop
== 1 && sopcde
== 7)
2534 return DREGL_MASK (dst0
);
2535 else if (sop
== 2 && sopcde
== 7)
2536 return DREGL_MASK (dst0
);
2537 else if (sop
== 3 && sopcde
== 7)
2538 return DREGL_MASK (dst0
);
2539 else if (sop
== 0 && sopcde
== 8)
2540 return DREG_MASK (src0
) | DREG_MASK (src1
);
2543 OUTS (outf
, "BITMUX (");
2544 OUTS (outf
, dregs (src0
));
2546 OUTS (outf
, dregs (src1
));
2547 OUTS (outf
, ", A0) (ASR)");
2550 else if (sop
== 1 && sopcde
== 8)
2551 return DREG_MASK (src0
) | DREG_MASK (src1
);
2554 OUTS (outf
, "BITMUX (");
2555 OUTS (outf
, dregs (src0
));
2557 OUTS (outf
, dregs (src1
));
2558 OUTS (outf
, ", A0) (ASL)");
2561 else if (sopcde
== 9)
2562 return sop
< 2 ? DREGL_MASK (dst0
) : DREG_MASK (dst0
);
2563 else if (sopcde
== 10)
2564 return DREG_MASK (dst0
);
2565 else if (sop
== 0 && sopcde
== 11)
2566 return DREGL_MASK (dst0
);
2567 else if (sop
== 1 && sopcde
== 11)
2568 return DREGL_MASK (dst0
);
2569 else if (sop
== 0 && sopcde
== 12)
2571 else if (sop
== 1 && sopcde
== 12)
2572 return DREGL_MASK (dst0
);
2573 else if (sop
== 0 && sopcde
== 13)
2574 return DREG_MASK (dst0
);
2575 else if (sop
== 1 && sopcde
== 13)
2576 return DREG_MASK (dst0
);
2577 else if (sop
== 2 && sopcde
== 13)
2578 return DREG_MASK (dst0
);
2584 decode_dsp32shiftimm_0 (int iw0
, int iw1
)
2587 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2588 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............|
2589 |.sop...|.HLs...|.dst0......|.immag.................|.src1......|
2590 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2591 int sop
= ((iw1
>> DSP32ShiftImm_sop_bits
) & DSP32ShiftImm_sop_mask
);
2592 int bit8
= ((iw1
>> 8) & 0x1);
2593 int dst0
= ((iw1
>> DSP32ShiftImm_dst0_bits
) & DSP32ShiftImm_dst0_mask
);
2594 int sopcde
= ((iw0
>> (DSP32ShiftImm_sopcde_bits
- 16)) & DSP32ShiftImm_sopcde_mask
);
2595 int HLs
= ((iw1
>> DSP32ShiftImm_HLs_bits
) & DSP32ShiftImm_HLs_mask
);
2598 if (sop
== 0 && sopcde
== 0)
2599 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2600 else if (sop
== 1 && sopcde
== 0 && bit8
== 0)
2601 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2602 else if (sop
== 1 && sopcde
== 0 && bit8
== 1)
2603 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2604 else if (sop
== 2 && sopcde
== 0 && bit8
== 0)
2605 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2606 else if (sop
== 2 && sopcde
== 0 && bit8
== 1)
2607 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2608 else if (sop
== 2 && sopcde
== 3 && HLs
== 1)
2610 else if (sop
== 0 && sopcde
== 3 && HLs
== 0 && bit8
== 0)
2612 else if (sop
== 0 && sopcde
== 3 && HLs
== 0 && bit8
== 1)
2614 else if (sop
== 0 && sopcde
== 3 && HLs
== 1 && bit8
== 0)
2616 else if (sop
== 0 && sopcde
== 3 && HLs
== 1 && bit8
== 1)
2618 else if (sop
== 1 && sopcde
== 3 && HLs
== 0)
2620 else if (sop
== 1 && sopcde
== 3 && HLs
== 1)
2622 else if (sop
== 2 && sopcde
== 3 && HLs
== 0)
2624 else if (sop
== 1 && sopcde
== 1 && bit8
== 0)
2625 return DREG_MASK (dst0
);
2626 else if (sop
== 1 && sopcde
== 1 && bit8
== 1)
2627 return DREG_MASK (dst0
);
2628 else if (sop
== 2 && sopcde
== 1 && bit8
== 1)
2629 return DREG_MASK (dst0
);
2630 else if (sop
== 2 && sopcde
== 1 && bit8
== 0)
2631 return DREG_MASK (dst0
);
2632 else if (sop
== 0 && sopcde
== 1)
2633 return DREG_MASK (dst0
);
2634 else if (sop
== 1 && sopcde
== 2)
2635 return DREG_MASK (dst0
);
2636 else if (sop
== 2 && sopcde
== 2 && bit8
== 1)
2637 return DREG_MASK (dst0
);
2638 else if (sop
== 2 && sopcde
== 2 && bit8
== 0)
2639 return DREG_MASK (dst0
);
2640 else if (sop
== 3 && sopcde
== 2)
2641 return DREG_MASK (dst0
);
2642 else if (sop
== 0 && sopcde
== 2)
2643 return DREG_MASK (dst0
);
2649 insn_regmask (int iw0
, int iw1
)
2651 if ((iw0
& 0xf7ff) == 0xc003 && iw1
== 0x1800)
2652 return 0; /* MNOP */
2653 else if ((iw0
& 0xff00) == 0x0000)
2654 return decode_ProgCtrl_0 (iw0
);
2655 else if ((iw0
& 0xffc0) == 0x0240)
2657 else if ((iw0
& 0xff80) == 0x0100)
2659 else if ((iw0
& 0xfe00) == 0x0400)
2661 else if ((iw0
& 0xfe00) == 0x0600)
2663 else if ((iw0
& 0xf800) == 0x0800)
2665 else if ((iw0
& 0xffe0) == 0x0200)
2667 else if ((iw0
& 0xff00) == 0x0300)
2669 else if ((iw0
& 0xf000) == 0x1000)
2671 else if ((iw0
& 0xf000) == 0x2000)
2673 else if ((iw0
& 0xf000) == 0x3000)
2675 else if ((iw0
& 0xfc00) == 0x4000)
2677 else if ((iw0
& 0xfe00) == 0x4400)
2679 else if ((iw0
& 0xf800) == 0x4800)
2681 else if ((iw0
& 0xf000) == 0x5000)
2683 else if ((iw0
& 0xf800) == 0x6000)
2685 else if ((iw0
& 0xf800) == 0x6800)
2687 else if ((iw0
& 0xf000) == 0x8000)
2688 return decode_LDSTpmod_0 (iw0
);
2689 else if ((iw0
& 0xff60) == 0x9e60)
2690 return decode_dagMODim_0 (iw0
);
2691 else if ((iw0
& 0xfff0) == 0x9f60)
2692 return decode_dagMODik_0 (iw0
);
2693 else if ((iw0
& 0xfc00) == 0x9c00)
2694 return decode_dspLDST_0 (iw0
);
2695 else if ((iw0
& 0xf000) == 0x9000)
2696 return decode_LDST_0 (iw0
);
2697 else if ((iw0
& 0xfc00) == 0xb800)
2698 return decode_LDSTiiFP_0 (iw0
);
2699 else if ((iw0
& 0xe000) == 0xA000)
2700 return decode_LDSTii_0 (iw0
);
2701 else if ((iw0
& 0xff80) == 0xe080 && (iw1
& 0x0C00) == 0x0000)
2703 else if ((iw0
& 0xff00) == 0xe100 && (iw1
& 0x0000) == 0x0000)
2705 else if ((iw0
& 0xfe00) == 0xe200 && (iw1
& 0x0000) == 0x0000)
2707 else if ((iw0
& 0xfc00) == 0xe400 && (iw1
& 0x0000) == 0x0000)
2709 else if ((iw0
& 0xfffe) == 0xe800 && (iw1
& 0x0000) == 0x0000)
2711 else if ((iw0
& 0xf600) == 0xc000 && (iw1
& 0x0000) == 0x0000)
2712 return decode_dsp32mac_0 (iw0
, iw1
);
2713 else if ((iw0
& 0xf600) == 0xc200 && (iw1
& 0x0000) == 0x0000)
2714 return decode_dsp32mult_0 (iw0
, iw1
);
2715 else if ((iw0
& 0xf7c0) == 0xc400 && (iw1
& 0x0000) == 0x0000)
2716 return decode_dsp32alu_0 (iw0
, iw1
);
2717 else if ((iw0
& 0xf780) == 0xc600 && (iw1
& 0x01c0) == 0x0000)
2718 return decode_dsp32shift_0 (iw0
, iw1
);
2719 else if ((iw0
& 0xf780) == 0xc680 && (iw1
& 0x0000) == 0x0000)
2720 return decode_dsp32shiftimm_0 (iw0
, iw1
);
2721 else if ((iw0
& 0xff00) == 0xf800)
2723 else if ((iw0
& 0xFFC0) == 0xf000 && (iw1
& 0x0000) == 0x0000)