1 /* tc-bfin.c -- Assembler for the ADI Blackfin.
2 Copyright (C) 2005-2017 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"
29 #include "elf/common.h"
32 extern int yyparse (void);
33 struct yy_buffer_state
;
34 typedef struct yy_buffer_state
*YY_BUFFER_STATE
;
35 extern YY_BUFFER_STATE
yy_scan_string (const char *yy_str
);
36 extern void yy_delete_buffer (YY_BUFFER_STATE b
);
37 static parse_state
parse (char *line
);
39 /* Global variables. */
40 struct bfin_insn
*insn
;
43 extern struct obstack mempool
;
46 /* Flags to set in the elf header */
47 #define DEFAULT_FLAGS 0
50 # define DEFAULT_FDPIC EF_BFIN_FDPIC
52 # define DEFAULT_FDPIC 0
55 static flagword bfin_flags
= DEFAULT_FLAGS
| DEFAULT_FDPIC
;
56 static const char *bfin_pic_flag
= DEFAULT_FDPIC
? "-mfdpic" : (const char *)0;
58 /* Blackfin specific function to handle FD-PIC pointer initializations. */
61 bfin_pic_ptr (int nbytes
)
69 #ifdef md_flush_pending_output
70 md_flush_pending_output ();
73 if (is_it_end_of_statement ())
75 demand_empty_rest_of_line ();
80 md_cons_align (nbytes
);
85 bfd_reloc_code_real_type reloc_type
= BFD_RELOC_BFIN_FUNCDESC
;
87 if (strncasecmp (input_line_pointer
, "funcdesc(", 9) == 0)
89 input_line_pointer
+= 9;
91 if (*input_line_pointer
== ')')
94 as_bad (_("missing ')'"));
97 error ("missing funcdesc in picptr");
101 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &exp
, 0,
104 while (*input_line_pointer
++ == ',');
106 input_line_pointer
--; /* Put terminator back into stream. */
107 demand_empty_rest_of_line ();
111 bfin_s_bss (int ignore ATTRIBUTE_UNUSED
)
115 temp
= get_absolute_expression ();
116 subseg_set (bss_section
, (subsegT
) temp
);
117 demand_empty_rest_of_line ();
120 const pseudo_typeS md_pseudo_table
[] = {
121 {"align", s_align_bytes
, 0},
124 {"picptr", bfin_pic_ptr
, 4},
125 {"code", obj_elf_section
, 0},
130 {"pdata", s_ignore
, 0},
131 {"var", s_ignore
, 0},
132 {"bss", bfin_s_bss
, 0},
136 /* Characters that are used to denote comments and line separators. */
137 const char comment_chars
[] = "#";
138 const char line_comment_chars
[] = "#";
139 const char line_separator_chars
[] = ";";
141 /* Characters that can be used to separate the mantissa from the
142 exponent in floating point numbers. */
143 const char EXP_CHARS
[] = "eE";
145 /* Characters that mean this number is a floating point constant.
146 As in 0f12.456 or 0d1.2345e12. */
147 const char FLT_CHARS
[] = "fFdDxX";
149 typedef enum bfin_cpu_type
186 bfin_cpu_t bfin_cpu_type
= BFIN_CPU_UNKNOWN
;
187 /* -msi-revision support. There are three special values:
188 -1 -msi-revision=none.
189 0xffff -msi-revision=any. */
190 int bfin_si_revision
;
192 unsigned int bfin_anomaly_checks
= 0;
199 unsigned int anomaly_checks
;
202 struct bfin_cpu bfin_cpus
[] =
204 {"bf504", BFIN_CPU_BF504
, 0x0000, AC_05000074
},
206 {"bf506", BFIN_CPU_BF506
, 0x0000, AC_05000074
},
208 {"bf512", BFIN_CPU_BF512
, 0x0002, AC_05000074
},
209 {"bf512", BFIN_CPU_BF512
, 0x0001, AC_05000074
},
210 {"bf512", BFIN_CPU_BF512
, 0x0000, AC_05000074
},
212 {"bf514", BFIN_CPU_BF514
, 0x0002, AC_05000074
},
213 {"bf514", BFIN_CPU_BF514
, 0x0001, AC_05000074
},
214 {"bf514", BFIN_CPU_BF514
, 0x0000, AC_05000074
},
216 {"bf516", BFIN_CPU_BF516
, 0x0002, AC_05000074
},
217 {"bf516", BFIN_CPU_BF516
, 0x0001, AC_05000074
},
218 {"bf516", BFIN_CPU_BF516
, 0x0000, AC_05000074
},
220 {"bf518", BFIN_CPU_BF518
, 0x0002, AC_05000074
},
221 {"bf518", BFIN_CPU_BF518
, 0x0001, AC_05000074
},
222 {"bf518", BFIN_CPU_BF518
, 0x0000, AC_05000074
},
224 {"bf522", BFIN_CPU_BF522
, 0x0002, AC_05000074
},
225 {"bf522", BFIN_CPU_BF522
, 0x0001, AC_05000074
},
226 {"bf522", BFIN_CPU_BF522
, 0x0000, AC_05000074
},
228 {"bf523", BFIN_CPU_BF523
, 0x0002, AC_05000074
},
229 {"bf523", BFIN_CPU_BF523
, 0x0001, AC_05000074
},
230 {"bf523", BFIN_CPU_BF523
, 0x0000, AC_05000074
},
232 {"bf524", BFIN_CPU_BF524
, 0x0002, AC_05000074
},
233 {"bf524", BFIN_CPU_BF524
, 0x0001, AC_05000074
},
234 {"bf524", BFIN_CPU_BF524
, 0x0000, AC_05000074
},
236 {"bf525", BFIN_CPU_BF525
, 0x0002, AC_05000074
},
237 {"bf525", BFIN_CPU_BF525
, 0x0001, AC_05000074
},
238 {"bf525", BFIN_CPU_BF525
, 0x0000, AC_05000074
},
240 {"bf526", BFIN_CPU_BF526
, 0x0002, AC_05000074
},
241 {"bf526", BFIN_CPU_BF526
, 0x0001, AC_05000074
},
242 {"bf526", BFIN_CPU_BF526
, 0x0000, AC_05000074
},
244 {"bf527", BFIN_CPU_BF527
, 0x0002, AC_05000074
},
245 {"bf527", BFIN_CPU_BF527
, 0x0001, AC_05000074
},
246 {"bf527", BFIN_CPU_BF527
, 0x0000, AC_05000074
},
248 {"bf531", BFIN_CPU_BF531
, 0x0006, AC_05000074
},
249 {"bf531", BFIN_CPU_BF531
, 0x0005, AC_05000074
},
250 {"bf531", BFIN_CPU_BF531
, 0x0004, AC_05000074
},
251 {"bf531", BFIN_CPU_BF531
, 0x0003, AC_05000074
},
253 {"bf532", BFIN_CPU_BF532
, 0x0006, AC_05000074
},
254 {"bf532", BFIN_CPU_BF532
, 0x0005, AC_05000074
},
255 {"bf532", BFIN_CPU_BF532
, 0x0004, AC_05000074
},
256 {"bf532", BFIN_CPU_BF532
, 0x0003, AC_05000074
},
258 {"bf533", BFIN_CPU_BF533
, 0x0006, AC_05000074
},
259 {"bf533", BFIN_CPU_BF533
, 0x0005, AC_05000074
},
260 {"bf533", BFIN_CPU_BF533
, 0x0004, AC_05000074
},
261 {"bf533", BFIN_CPU_BF533
, 0x0003, AC_05000074
},
263 {"bf534", BFIN_CPU_BF534
, 0x0003, AC_05000074
},
264 {"bf534", BFIN_CPU_BF534
, 0x0002, AC_05000074
},
265 {"bf534", BFIN_CPU_BF534
, 0x0001, AC_05000074
},
267 {"bf536", BFIN_CPU_BF536
, 0x0003, AC_05000074
},
268 {"bf536", BFIN_CPU_BF536
, 0x0002, AC_05000074
},
269 {"bf536", BFIN_CPU_BF536
, 0x0001, AC_05000074
},
271 {"bf537", BFIN_CPU_BF537
, 0x0003, AC_05000074
},
272 {"bf537", BFIN_CPU_BF537
, 0x0002, AC_05000074
},
273 {"bf537", BFIN_CPU_BF537
, 0x0001, AC_05000074
},
275 {"bf538", BFIN_CPU_BF538
, 0x0005, AC_05000074
},
276 {"bf538", BFIN_CPU_BF538
, 0x0004, AC_05000074
},
277 {"bf538", BFIN_CPU_BF538
, 0x0003, AC_05000074
},
278 {"bf538", BFIN_CPU_BF538
, 0x0002, AC_05000074
},
280 {"bf539", BFIN_CPU_BF539
, 0x0005, AC_05000074
},
281 {"bf539", BFIN_CPU_BF539
, 0x0004, AC_05000074
},
282 {"bf539", BFIN_CPU_BF539
, 0x0003, AC_05000074
},
283 {"bf539", BFIN_CPU_BF539
, 0x0002, AC_05000074
},
285 {"bf542m", BFIN_CPU_BF542M
, 0x0003, AC_05000074
},
287 {"bf542", BFIN_CPU_BF542
, 0x0004, AC_05000074
},
288 {"bf542", BFIN_CPU_BF542
, 0x0002, AC_05000074
},
289 {"bf542", BFIN_CPU_BF542
, 0x0001, AC_05000074
},
290 {"bf542", BFIN_CPU_BF542
, 0x0000, AC_05000074
},
292 {"bf544m", BFIN_CPU_BF544M
, 0x0003, AC_05000074
},
294 {"bf544", BFIN_CPU_BF544
, 0x0004, AC_05000074
},
295 {"bf544", BFIN_CPU_BF544
, 0x0002, AC_05000074
},
296 {"bf544", BFIN_CPU_BF544
, 0x0001, AC_05000074
},
297 {"bf544", BFIN_CPU_BF544
, 0x0000, AC_05000074
},
299 {"bf547m", BFIN_CPU_BF547M
, 0x0003, AC_05000074
},
301 {"bf547", BFIN_CPU_BF547
, 0x0004, AC_05000074
},
302 {"bf547", BFIN_CPU_BF547
, 0x0002, AC_05000074
},
303 {"bf547", BFIN_CPU_BF547
, 0x0001, AC_05000074
},
304 {"bf547", BFIN_CPU_BF547
, 0x0000, AC_05000074
},
306 {"bf548m", BFIN_CPU_BF548M
, 0x0003, AC_05000074
},
308 {"bf548", BFIN_CPU_BF548
, 0x0004, AC_05000074
},
309 {"bf548", BFIN_CPU_BF548
, 0x0002, AC_05000074
},
310 {"bf548", BFIN_CPU_BF548
, 0x0001, AC_05000074
},
311 {"bf548", BFIN_CPU_BF548
, 0x0000, AC_05000074
},
313 {"bf549m", BFIN_CPU_BF549M
, 0x0003, AC_05000074
},
315 {"bf549", BFIN_CPU_BF549
, 0x0004, AC_05000074
},
316 {"bf549", BFIN_CPU_BF549
, 0x0002, AC_05000074
},
317 {"bf549", BFIN_CPU_BF549
, 0x0001, AC_05000074
},
318 {"bf549", BFIN_CPU_BF549
, 0x0000, AC_05000074
},
320 {"bf561", BFIN_CPU_BF561
, 0x0005, AC_05000074
},
321 {"bf561", BFIN_CPU_BF561
, 0x0003, AC_05000074
},
322 {"bf561", BFIN_CPU_BF561
, 0x0002, AC_05000074
},
324 {"bf592", BFIN_CPU_BF592
, 0x0001, AC_05000074
},
325 {"bf592", BFIN_CPU_BF592
, 0x0000, AC_05000074
},
328 /* Define bfin-specific command-line options (there are none). */
329 const char *md_shortopts
= "";
331 #define OPTION_FDPIC (OPTION_MD_BASE)
332 #define OPTION_NOPIC (OPTION_MD_BASE + 1)
333 #define OPTION_MCPU (OPTION_MD_BASE + 2)
335 struct option md_longopts
[] =
337 { "mcpu", required_argument
, NULL
, OPTION_MCPU
},
338 { "mfdpic", no_argument
, NULL
, OPTION_FDPIC
},
339 { "mnopic", no_argument
, NULL
, OPTION_NOPIC
},
340 { "mno-fdpic", no_argument
, NULL
, OPTION_NOPIC
},
341 { NULL
, no_argument
, NULL
, 0 },
344 size_t md_longopts_size
= sizeof (md_longopts
);
348 md_parse_option (int c ATTRIBUTE_UNUSED
, const char *arg ATTRIBUTE_UNUSED
)
360 for (i
= 0; i
< ARRAY_SIZE (bfin_cpus
); i
++)
362 const char *p
= bfin_cpus
[i
].name
;
363 if (strncmp (arg
, p
, strlen (p
)) == 0)
367 if (i
== ARRAY_SIZE (bfin_cpus
))
368 as_fatal ("-mcpu=%s is not valid", arg
);
370 bfin_cpu_type
= bfin_cpus
[i
].type
;
372 q
= arg
+ strlen (bfin_cpus
[i
].name
);
376 bfin_si_revision
= bfin_cpus
[i
].si_revision
;
377 bfin_anomaly_checks
|= bfin_cpus
[i
].anomaly_checks
;
379 else if (strcmp (q
, "-none") == 0)
380 bfin_si_revision
= -1;
381 else if (strcmp (q
, "-any") == 0)
383 bfin_si_revision
= 0xffff;
384 while (i
< ARRAY_SIZE (bfin_cpus
)
385 && bfin_cpus
[i
].type
== bfin_cpu_type
)
387 bfin_anomaly_checks
|= bfin_cpus
[i
].anomaly_checks
;
393 unsigned int si_major
, si_minor
;
396 rev_len
= strlen (q
);
398 if (sscanf (q
, "-%u.%u%n", &si_major
, &si_minor
, &n
) != 2
400 || si_major
> 0xff || si_minor
> 0xff)
402 invalid_silicon_revision
:
403 as_fatal ("-mcpu=%s has invalid silicon revision", arg
);
406 bfin_si_revision
= (si_major
<< 8) | si_minor
;
408 while (i
< ARRAY_SIZE (bfin_cpus
)
409 && bfin_cpus
[i
].type
== bfin_cpu_type
410 && bfin_cpus
[i
].si_revision
!= bfin_si_revision
)
413 if (i
== ARRAY_SIZE (bfin_cpus
)
414 || bfin_cpus
[i
].type
!= bfin_cpu_type
)
415 goto invalid_silicon_revision
;
417 bfin_anomaly_checks
|= bfin_cpus
[i
].anomaly_checks
;
424 bfin_flags
|= EF_BFIN_FDPIC
;
425 bfin_pic_flag
= "-mfdpic";
429 bfin_flags
&= ~(EF_BFIN_FDPIC
);
438 md_show_usage (FILE * stream
)
440 fprintf (stream
, _(" Blackfin specific assembler options:\n"));
441 fprintf (stream
, _(" -mcpu=<cpu[-sirevision]> specify the name of the target CPU\n"));
442 fprintf (stream
, _(" -mfdpic assemble for the FDPIC ABI\n"));
443 fprintf (stream
, _(" -mno-fdpic/-mnopic disable -mfdpic\n"));
446 /* Perform machine-specific initializations. */
450 /* Set the ELF flags if desired. */
452 bfd_set_private_flags (stdoutput
, bfin_flags
);
454 /* Set the default machine type. */
455 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_bfin
, 0))
456 as_warn (_("Could not set architecture and machine."));
458 /* Ensure that lines can begin with '(', for multiple
459 register stack pops. */
460 lex_type
['('] = LEX_BEGIN_NAME
;
463 record_alignment (text_section
, 2);
464 record_alignment (data_section
, 2);
465 record_alignment (bss_section
, 2);
469 obstack_init (&mempool
);
472 extern int debug_codeselection
;
473 debug_codeselection
= 1;
479 /* Perform the main parsing, and assembly of the input here. Also,
480 call the required routines for alignment and fixups here.
481 This is called for every line that contains real assembly code. */
484 md_assemble (char *line
)
488 struct bfin_insn
*tmp_insn
;
490 static size_t buffer_len
= 0;
491 static char *current_inputline
;
495 if (len
+ 2 > buffer_len
)
497 buffer_len
= len
+ 40;
498 current_inputline
= XRESIZEVEC (char, current_inputline
, buffer_len
);
500 memcpy (current_inputline
, line
, len
);
501 current_inputline
[len
] = ';';
502 current_inputline
[len
+ 1] = '\0';
504 state
= parse (current_inputline
);
505 if (state
== NO_INSN_GENERATED
)
508 for (insn_size
= 0, tmp_insn
= insn
; tmp_insn
; tmp_insn
= tmp_insn
->next
)
509 if (!tmp_insn
->reloc
|| !tmp_insn
->exp
->symbol
)
513 toP
= frag_more (insn_size
);
515 last_insn_size
= insn_size
;
522 if (insn
->reloc
&& insn
->exp
->symbol
)
524 char *prev_toP
= toP
- 2;
527 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
528 case BFD_RELOC_24_PCREL
:
529 case BFD_RELOC_BFIN_16_LOW
:
530 case BFD_RELOC_BFIN_16_HIGH
:
537 /* Following if condition checks for the arithmetic relocations.
538 If the case then it doesn't required to generate the code.
539 It has been assumed that, their ID will be contiguous. */
540 if ((BFD_ARELOC_BFIN_PUSH
<= insn
->reloc
541 && BFD_ARELOC_BFIN_COMP
>= insn
->reloc
)
542 || insn
->reloc
== BFD_RELOC_BFIN_16_IMM
)
546 if (insn
->reloc
== BFD_ARELOC_BFIN_CONST
547 || insn
->reloc
== BFD_ARELOC_BFIN_PUSH
)
551 (prev_toP
- frag_now
->fr_literal
),
552 size
, insn
->exp
->symbol
, insn
->exp
->value
,
553 insn
->pcrel
, insn
->reloc
);
557 md_number_to_chars (toP
, insn
->value
, 2);
563 printf (" %02x%02x", ((unsigned char *) &insn
->value
)[0],
564 ((unsigned char *) &insn
->value
)[1]);
570 dwarf2_emit_insn (insn_size
);
573 while (*line
++ != '\0')
575 bump_line_counters ();
578 /* Parse one line of instructions, and generate opcode for it.
579 To parse the line, YACC and LEX are used, because the instruction set
580 syntax doesn't confirm to the AT&T assembly syntax.
581 To call a YACC & LEX generated parser, we must provide the input via
582 a FILE stream, otherwise stdin is used by default. Below the input
583 to the function will be put into a temporary file, then the generated
584 parser uses the temporary file for parsing. */
590 YY_BUFFER_STATE buffstate
;
592 buffstate
= yy_scan_string (line
);
594 /* our lex requires setting the start state to keyword
595 every line as the first word may be a keyword.
596 Fixes a bug where we could not have keywords as labels. */
599 /* Call yyparse here. */
601 if (state
== SEMANTIC_ERROR
)
603 as_bad (_("Parse failed."));
607 yy_delete_buffer (buffstate
);
611 /* We need to handle various expressions properly.
612 Such as, [SP--] = 34, concerned by md_assemble(). */
615 md_operand (expressionS
* expressionP
)
617 if (*input_line_pointer
== '[')
619 as_tsktsk ("We found a '['!");
620 input_line_pointer
++;
621 expression (expressionP
);
625 /* Handle undefined symbols. */
627 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
629 return (symbolS
*) 0;
633 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
634 segT segment ATTRIBUTE_UNUSED
)
639 /* Convert from target byte order to host byte order. */
642 md_chars_to_number (char *val
, int n
)
646 for (retval
= 0; n
--;)
655 md_apply_fix (fixS
*fixP
, valueT
*valueP
, segT seg ATTRIBUTE_UNUSED
)
657 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
659 long value
= *valueP
;
662 switch (fixP
->fx_r_type
)
664 case BFD_RELOC_BFIN_GOT
:
665 case BFD_RELOC_BFIN_GOT17M4
:
666 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
667 fixP
->fx_no_overflow
= 1;
668 newval
= md_chars_to_number (where
, 2);
669 newval
|= 0x0 & 0x7f;
670 md_number_to_chars (where
, newval
, 2);
673 case BFD_RELOC_BFIN_10_PCREL
:
676 if (value
< -1024 || value
> 1022)
677 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
678 _("pcrel too far BFD_RELOC_BFIN_10"));
680 /* 11 bit offset even numbered, so we remove right bit. */
682 newval
= md_chars_to_number (where
, 2);
683 newval
|= value
& 0x03ff;
684 md_number_to_chars (where
, newval
, 2);
687 case BFD_RELOC_BFIN_12_PCREL_JUMP
:
688 case BFD_RELOC_BFIN_12_PCREL_JUMP_S
:
689 case BFD_RELOC_12_PCREL
:
693 if (value
< -4096 || value
> 4094)
694 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_12"));
695 /* 13 bit offset even numbered, so we remove right bit. */
697 newval
= md_chars_to_number (where
, 2);
698 newval
|= value
& 0xfff;
699 md_number_to_chars (where
, newval
, 2);
702 case BFD_RELOC_BFIN_16_LOW
:
703 case BFD_RELOC_BFIN_16_HIGH
:
704 fixP
->fx_done
= FALSE
;
707 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
708 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
709 case BFD_RELOC_24_PCREL
:
713 if (value
< -16777216 || value
> 16777214)
714 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_24"));
716 /* 25 bit offset even numbered, so we remove right bit. */
720 md_number_to_chars (where
- 2, value
>> 16, 1);
721 md_number_to_chars (where
, value
, 1);
722 md_number_to_chars (where
+ 1, value
>> 8, 1);
725 case BFD_RELOC_BFIN_5_PCREL
: /* LSETUP (a, b) : "a" */
728 if (value
< 4 || value
> 30)
729 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_5"));
731 newval
= md_chars_to_number (where
, 1);
732 newval
= (newval
& 0xf0) | (value
& 0xf);
733 md_number_to_chars (where
, newval
, 1);
736 case BFD_RELOC_BFIN_11_PCREL
: /* LSETUP (a, b) : "b" */
740 if (value
< 4 || value
> 2046)
741 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_11_PCREL"));
742 /* 11 bit unsigned even, so we remove right bit. */
744 newval
= md_chars_to_number (where
, 2);
745 newval
|= value
& 0x03ff;
746 md_number_to_chars (where
, newval
, 2);
750 if (value
< -0x80 || value
>= 0x7f)
751 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("rel too far BFD_RELOC_8"));
752 md_number_to_chars (where
, value
, 1);
755 case BFD_RELOC_BFIN_16_IMM
:
757 if (value
< -0x8000 || value
>= 0x7fff)
758 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("rel too far BFD_RELOC_16"));
759 md_number_to_chars (where
, value
, 2);
763 md_number_to_chars (where
, value
, 4);
766 case BFD_RELOC_BFIN_PLTPC
:
767 md_number_to_chars (where
, value
, 2);
770 case BFD_RELOC_BFIN_FUNCDESC
:
771 case BFD_RELOC_VTABLE_INHERIT
:
772 case BFD_RELOC_VTABLE_ENTRY
:
773 fixP
->fx_done
= FALSE
;
777 if ((BFD_ARELOC_BFIN_PUSH
> fixP
->fx_r_type
) || (BFD_ARELOC_BFIN_COMP
< fixP
->fx_r_type
))
779 fprintf (stderr
, "Relocation %d not handled in gas." " Contact support.\n", fixP
->fx_r_type
);
785 fixP
->fx_done
= TRUE
;
789 /* Round up a section size to the appropriate boundary. */
791 md_section_align (segT segment
, valueT size
)
793 int boundary
= bfd_get_section_alignment (stdoutput
, segment
);
794 return ((size
+ (1 << boundary
) - 1) & -(1 << boundary
));
799 md_atof (int type
, char * litP
, int * sizeP
)
801 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
805 /* If while processing a fixup, a reloc really needs to be created
806 then it is done here. */
809 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixp
)
813 reloc
= XNEW (arelent
);
814 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
815 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
816 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
818 reloc
->addend
= fixp
->fx_offset
;
819 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
821 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
823 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
824 /* xgettext:c-format. */
825 _("reloc %d not supported by object file format"),
826 (int) fixp
->fx_r_type
);
836 /* The location from which a PC relative jump should be calculated,
837 given a PC relative reloc. */
840 md_pcrel_from_section (fixS
*fixP
, segT sec
)
842 if (fixP
->fx_addsy
!= (symbolS
*) NULL
843 && (!S_IS_DEFINED (fixP
->fx_addsy
)
844 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
846 /* The symbol is undefined (or is defined but not in this section).
847 Let the linker figure it out. */
850 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
853 /* Return true if the fix can be handled by GAS, false if it must
854 be passed through to the linker. */
857 bfin_fix_adjustable (fixS
*fixP
)
859 switch (fixP
->fx_r_type
)
861 /* Adjust_reloc_syms doesn't know about the GOT. */
862 case BFD_RELOC_BFIN_GOT
:
863 case BFD_RELOC_BFIN_PLTPC
:
864 /* We need the symbol name for the VTABLE entries. */
865 case BFD_RELOC_VTABLE_INHERIT
:
866 case BFD_RELOC_VTABLE_ENTRY
:
874 /* Special extra functions that help bfin-parse.y perform its job. */
876 struct obstack mempool
;
879 conscode (INSTR_T head
, INSTR_T tail
)
888 conctcode (INSTR_T head
, INSTR_T tail
)
890 INSTR_T temp
= (head
);
901 note_reloc (INSTR_T code
, Expr_Node
* symbol
, int reloc
, int pcrel
)
903 /* Assert that the symbol is not an operator. */
904 gas_assert (symbol
->type
== Expr_Node_Reloc
);
906 return note_reloc1 (code
, symbol
->value
.s_value
, reloc
, pcrel
);
911 note_reloc1 (INSTR_T code
, const char *symbol
, int reloc
, int pcrel
)
914 code
->exp
= mkexpr (0, symbol_find_or_make (symbol
));
920 note_reloc2 (INSTR_T code
, const char *symbol
, int reloc
, int value
, int pcrel
)
923 code
->exp
= mkexpr (value
, symbol_find_or_make (symbol
));
929 gencode (unsigned long x
)
931 INSTR_T cell
= XOBNEW (&mempool
, struct bfin_insn
);
932 memset (cell
, 0, sizeof (struct bfin_insn
));
944 return obstack_alloc (&mempool
, n
);
948 Expr_Node_Create (Expr_Node_Type type
,
949 Expr_Node_Value value
,
950 Expr_Node
*Left_Child
,
951 Expr_Node
*Right_Child
)
955 Expr_Node
*node
= (Expr_Node
*) allocate (sizeof (Expr_Node
));
958 node
->Left_Child
= Left_Child
;
959 node
->Right_Child
= Right_Child
;
963 static const char *con
= ".__constant";
964 static const char *op
= ".__operator";
965 static INSTR_T
Expr_Node_Gen_Reloc_R (Expr_Node
* head
);
966 INSTR_T
Expr_Node_Gen_Reloc (Expr_Node
*head
, int parent_reloc
);
969 Expr_Node_Gen_Reloc (Expr_Node
* head
, int parent_reloc
)
971 /* Top level relocation expression generator VDSP style.
972 If the relocation is just by itself, generate one item
973 else generate this convoluted expression. */
975 INSTR_T note
= NULL_CODE
;
976 INSTR_T note1
= NULL_CODE
;
977 int pcrel
= 1; /* Is the parent reloc pc-relative?
978 This calculation here and HOWTO should match. */
982 /* If it's 32 bit quantity then 16bit code needs to be added. */
985 if (head
->type
== Expr_Node_Constant
)
987 /* If note1 is not null code, we have to generate a right
988 aligned value for the constant. Otherwise the reloc is
989 a part of the basic command and the yacc file
991 value
= head
->value
.i_value
;
993 switch (parent_reloc
)
995 /* Some relocations will need to allocate extra words. */
996 case BFD_RELOC_BFIN_16_IMM
:
997 case BFD_RELOC_BFIN_16_LOW
:
998 case BFD_RELOC_BFIN_16_HIGH
:
999 note1
= conscode (gencode (value
), NULL_CODE
);
1002 case BFD_RELOC_BFIN_PLTPC
:
1003 note1
= conscode (gencode (value
), NULL_CODE
);
1007 case BFD_RELOC_BFIN_GOT
:
1008 case BFD_RELOC_BFIN_GOT17M4
:
1009 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
1010 note1
= conscode (gencode (value
), NULL_CODE
);
1013 case BFD_RELOC_24_PCREL
:
1014 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
1015 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
1016 /* These offsets are even numbered pcrel. */
1017 note1
= conscode (gencode (value
>> 1), NULL_CODE
);
1023 if (head
->type
== Expr_Node_Constant
)
1025 else if (head
->type
== Expr_Node_Reloc
)
1027 note
= note_reloc1 (gencode (0), head
->value
.s_value
, parent_reloc
, pcrel
);
1028 if (note1
!= NULL_CODE
)
1029 note
= conscode (note1
, note
);
1031 else if (head
->type
== Expr_Node_Binop
1032 && (head
->value
.op_value
== Expr_Op_Type_Add
1033 || head
->value
.op_value
== Expr_Op_Type_Sub
)
1034 && head
->Left_Child
->type
== Expr_Node_Reloc
1035 && head
->Right_Child
->type
== Expr_Node_Constant
)
1037 int val
= head
->Right_Child
->value
.i_value
;
1038 if (head
->value
.op_value
== Expr_Op_Type_Sub
)
1040 note
= conscode (note_reloc2 (gencode (0), head
->Left_Child
->value
.s_value
,
1041 parent_reloc
, val
, 0),
1043 if (note1
!= NULL_CODE
)
1044 note
= conscode (note1
, note
);
1048 /* Call the recursive function. */
1049 note
= note_reloc1 (gencode (0), op
, parent_reloc
, pcrel
);
1050 if (note1
!= NULL_CODE
)
1051 note
= conscode (note1
, note
);
1052 note
= conctcode (Expr_Node_Gen_Reloc_R (head
), note
);
1058 Expr_Node_Gen_Reloc_R (Expr_Node
* head
)
1066 case Expr_Node_Constant
:
1067 note
= conscode (note_reloc2 (gencode (0), con
, BFD_ARELOC_BFIN_CONST
, head
->value
.i_value
, 0), NULL_CODE
);
1069 case Expr_Node_Reloc
:
1070 note
= conscode (note_reloc (gencode (0), head
, BFD_ARELOC_BFIN_PUSH
, 0), NULL_CODE
);
1072 case Expr_Node_Binop
:
1073 note1
= conctcode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), Expr_Node_Gen_Reloc_R (head
->Right_Child
));
1074 switch (head
->value
.op_value
)
1076 case Expr_Op_Type_Add
:
1077 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_ADD
, 0), NULL_CODE
));
1079 case Expr_Op_Type_Sub
:
1080 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_SUB
, 0), NULL_CODE
));
1082 case Expr_Op_Type_Mult
:
1083 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MULT
, 0), NULL_CODE
));
1085 case Expr_Op_Type_Div
:
1086 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_DIV
, 0), NULL_CODE
));
1088 case Expr_Op_Type_Mod
:
1089 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MOD
, 0), NULL_CODE
));
1091 case Expr_Op_Type_Lshift
:
1092 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LSHIFT
, 0), NULL_CODE
));
1094 case Expr_Op_Type_Rshift
:
1095 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_RSHIFT
, 0), NULL_CODE
));
1097 case Expr_Op_Type_BAND
:
1098 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_AND
, 0), NULL_CODE
));
1100 case Expr_Op_Type_BOR
:
1101 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_OR
, 0), NULL_CODE
));
1103 case Expr_Op_Type_BXOR
:
1104 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_XOR
, 0), NULL_CODE
));
1106 case Expr_Op_Type_LAND
:
1107 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LAND
, 0), NULL_CODE
));
1109 case Expr_Op_Type_LOR
:
1110 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LOR
, 0), NULL_CODE
));
1113 fprintf (stderr
, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1118 case Expr_Node_Unop
:
1119 note1
= conscode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), NULL_CODE
);
1120 switch (head
->value
.op_value
)
1122 case Expr_Op_Type_NEG
:
1123 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_NEG
, 0), NULL_CODE
));
1125 case Expr_Op_Type_COMP
:
1126 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_COMP
, 0), NULL_CODE
));
1129 fprintf (stderr
, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1133 fprintf (stderr
, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__
, __LINE__
);
1138 /* Blackfin opcode generation. */
1140 /* These functions are called by the generated parser
1141 (from bfin-parse.y), the register type classification
1142 happens in bfin-lex.l. */
1144 #include "bfin-aux.h"
1145 #include "opcode/bfin.h"
1147 #define INIT(t) t c_code = init_##t
1148 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1149 #define ASSIGNF(x,f) c_code.opcode |= ((x & c_code.mask_##f)<<c_code.bits_##f)
1150 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1152 #define HI(x) ((x >> 16) & 0xffff)
1153 #define LO(x) ((x ) & 0xffff)
1155 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1157 #define GEN_OPCODE32() \
1158 conscode (gencode (HI (c_code.opcode)), \
1159 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1161 #define GEN_OPCODE16() \
1162 conscode (gencode (c_code.opcode), NULL_CODE)
1165 /* 32 BIT INSTRUCTIONS. */
1168 /* DSP32 instruction generation. */
1171 bfin_gen_dsp32mac (int op1
, int MM
, int mmod
, int w1
, int P
,
1172 int h01
, int h11
, int h00
, int h10
, int op0
,
1173 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1189 /* If we have full reg assignments, mask out LSB to encode
1190 single or simultaneous even/odd register moves. */
1200 return GEN_OPCODE32 ();
1204 bfin_gen_dsp32mult (int op1
, int MM
, int mmod
, int w1
, int P
,
1205 int h01
, int h11
, int h00
, int h10
, int op0
,
1206 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1231 return GEN_OPCODE32 ();
1235 bfin_gen_dsp32alu (int HL
, int aopcde
, int aop
, int s
, int x
,
1236 REG_T dst0
, REG_T dst1
, REG_T src0
, REG_T src1
)
1250 return GEN_OPCODE32 ();
1254 bfin_gen_dsp32shift (int sopcde
, REG_T dst0
, REG_T src0
,
1255 REG_T src1
, int sop
, int HLs
)
1267 return GEN_OPCODE32 ();
1271 bfin_gen_dsp32shiftimm (int sopcde
, REG_T dst0
, int immag
,
1272 REG_T src1
, int sop
, int HLs
)
1274 INIT (DSP32ShiftImm
);
1284 return GEN_OPCODE32 ();
1290 bfin_gen_loopsetup (Expr_Node
* psoffset
, REG_T c
, int rop
,
1291 Expr_Node
* peoffset
, REG_T reg
)
1293 int soffset
, eoffset
;
1296 soffset
= (EXPR_VALUE (psoffset
) >> 1);
1298 eoffset
= (EXPR_VALUE (peoffset
) >> 1);
1305 conscode (gencode (HI (c_code
.opcode
)),
1306 conctcode (Expr_Node_Gen_Reloc (psoffset
, BFD_RELOC_BFIN_5_PCREL
),
1307 conctcode (gencode (LO (c_code
.opcode
)), Expr_Node_Gen_Reloc (peoffset
, BFD_RELOC_BFIN_11_PCREL
))));
1314 bfin_gen_calla (Expr_Node
* addr
, int S
)
1322 case 0 : rel
= BFD_RELOC_BFIN_24_PCREL_JUMP_L
; break;
1323 case 1 : rel
= BFD_RELOC_24_PCREL
; break;
1324 case 2 : rel
= BFD_RELOC_BFIN_PLTPC
; break;
1330 val
= EXPR_VALUE (addr
) >> 1;
1331 high_val
= val
>> 16;
1333 return conscode (gencode (HI (c_code
.opcode
) | (high_val
& 0xff)),
1334 Expr_Node_Gen_Reloc (addr
, rel
));
1338 bfin_gen_linkage (int R
, int framesize
)
1345 return GEN_OPCODE32 ();
1349 /* Load and Store. */
1352 bfin_gen_ldimmhalf (REG_T reg
, int H
, int S
, int Z
, Expr_Node
* phword
, int rel
)
1355 unsigned val
= EXPR_VALUE (phword
);
1363 grp
= (GROUP (reg
));
1367 return conscode (gencode (HI (c_code
.opcode
)), Expr_Node_Gen_Reloc (phword
, BFD_RELOC_BFIN_16_IMM
));
1371 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
));
1378 return GEN_OPCODE32 ();
1382 bfin_gen_ldstidxi (REG_T ptr
, REG_T reg
, int W
, int sz
, int Z
, Expr_Node
* poffset
)
1386 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1388 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1399 if (poffset
->type
!= Expr_Node_Constant
)
1401 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1402 /* distinguish between R0 = [P5 + symbol@GOT] and
1403 P5 = [P5 + _current_shared_library_p5_offset_]
1405 if (poffset
->type
== Expr_Node_Reloc
1406 && !strcmp (poffset
->value
.s_value
,
1407 "_current_shared_library_p5_offset_"))
1409 return conscode (gencode (HI (c_code
.opcode
)),
1410 Expr_Node_Gen_Reloc(poffset
, BFD_RELOC_16
));
1412 else if (poffset
->type
!= Expr_Node_GOT_Reloc
)
1415 return conscode (gencode (HI (c_code
.opcode
)),
1416 Expr_Node_Gen_Reloc(poffset
->Left_Child
,
1417 poffset
->value
.i_value
));
1423 { /* load/store access size */
1424 case 0: /* 32 bit */
1425 value
= EXPR_VALUE (poffset
) >> 2;
1427 case 1: /* 16 bit */
1428 value
= EXPR_VALUE (poffset
) >> 1;
1431 value
= EXPR_VALUE (poffset
);
1437 offset
= (value
& 0xffff);
1439 return GEN_OPCODE32 ();
1445 bfin_gen_ldst (REG_T ptr
, REG_T reg
, int aop
, int sz
, int Z
, int W
)
1449 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1451 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1462 return GEN_OPCODE16 ();
1466 bfin_gen_ldstii (REG_T ptr
, REG_T reg
, Expr_Node
* poffset
, int W
, int opc
)
1472 if (!IS_PREG (*ptr
))
1474 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1482 value
= EXPR_VALUE (poffset
) >> 1;
1486 value
= EXPR_VALUE (poffset
) >> 2;
1498 return GEN_OPCODE16 ();
1502 bfin_gen_ldstiifp (REG_T sreg
, Expr_Node
* poffset
, int W
)
1504 /* Set bit 4 if it's a Preg. */
1505 int reg
= (sreg
->regno
& CODE_MASK
) | (IS_PREG (*sreg
) ? 0x8 : 0x0);
1506 int offset
= ((~(EXPR_VALUE (poffset
) >> 2)) & 0x1f) + 1;
1512 return GEN_OPCODE16 ();
1516 bfin_gen_ldstpmod (REG_T ptr
, REG_T reg
, int aop
, int W
, REG_T idx
)
1526 return GEN_OPCODE16 ();
1530 bfin_gen_dspldst (REG_T i
, REG_T reg
, int aop
, int W
, int m
)
1540 return GEN_OPCODE16 ();
1544 bfin_gen_logi2op (int opc
, int src
, int dst
)
1552 return GEN_OPCODE16 ();
1556 bfin_gen_brcc (int T
, int B
, Expr_Node
* poffset
)
1563 offset
= ((EXPR_VALUE (poffset
) >> 1));
1565 return conscode (gencode (c_code
.opcode
), Expr_Node_Gen_Reloc (poffset
, BFD_RELOC_BFIN_10_PCREL
));
1569 bfin_gen_ujump (Expr_Node
* poffset
)
1574 offset
= ((EXPR_VALUE (poffset
) >> 1));
1577 return conscode (gencode (c_code
.opcode
),
1578 Expr_Node_Gen_Reloc (
1579 poffset
, BFD_RELOC_BFIN_12_PCREL_JUMP_S
));
1583 bfin_gen_alu2op (REG_T dst
, REG_T src
, int opc
)
1591 return GEN_OPCODE16 ();
1595 bfin_gen_compi2opd (REG_T dst
, int src
, int opc
)
1603 return GEN_OPCODE16 ();
1607 bfin_gen_compi2opp (REG_T dst
, int src
, int opc
)
1615 return GEN_OPCODE16 ();
1619 bfin_gen_dagmodik (REG_T i
, int opc
)
1626 return GEN_OPCODE16 ();
1630 bfin_gen_dagmodim (REG_T i
, REG_T m
, int opc
, int br
)
1639 return GEN_OPCODE16 ();
1643 bfin_gen_ptr2op (REG_T dst
, REG_T src
, int opc
)
1651 return GEN_OPCODE16 ();
1655 bfin_gen_comp3op (REG_T src0
, REG_T src1
, REG_T dst
, int opc
)
1664 return GEN_OPCODE16 ();
1668 bfin_gen_ccflag (REG_T x
, int y
, int opc
, int I
, int G
)
1678 return GEN_OPCODE16 ();
1682 bfin_gen_ccmv (REG_T src
, REG_T dst
, int T
)
1695 return GEN_OPCODE16 ();
1699 bfin_gen_cc2stat (int cbit
, int opc
, int D
)
1707 return GEN_OPCODE16 ();
1711 bfin_gen_regmv (REG_T src
, REG_T dst
)
1724 return GEN_OPCODE16 ();
1728 bfin_gen_cc2dreg (int opc
, REG_T reg
)
1735 return GEN_OPCODE16 ();
1739 bfin_gen_progctrl (int prgfunc
, int poprnd
)
1746 return GEN_OPCODE16 ();
1750 bfin_gen_cactrl (REG_T reg
, int a
, int opc
)
1758 return GEN_OPCODE16 ();
1762 bfin_gen_pushpopmultiple (int dr
, int pr
, int d
, int p
, int W
)
1764 INIT (PushPopMultiple
);
1772 return GEN_OPCODE16 ();
1776 bfin_gen_pushpopreg (REG_T reg
, int W
)
1782 grp
= (GROUP (reg
));
1786 return GEN_OPCODE16 ();
1789 /* Pseudo Debugging Support. */
1792 bfin_gen_pseudodbg (int fn
, int reg
, int grp
)
1800 return GEN_OPCODE16 ();
1804 bfin_gen_pseudodbg_assert (int dbgop
, REG_T regtest
, int expected
)
1807 INIT (PseudoDbg_Assert
);
1811 grp
= GROUP (regtest
);
1815 return GEN_OPCODE32 ();
1819 bfin_gen_pseudochr (int ch
)
1825 return GEN_OPCODE16 ();
1828 /* Multiple instruction generation. */
1831 bfin_gen_multi_instr (INSTR_T dsp32
, INSTR_T dsp16_grp1
, INSTR_T dsp16_grp2
)
1835 /* If it's a 0, convert into MNOP. */
1839 SET_MULTI_INSTRUCTION_BIT (dsp32
);
1843 dsp32
= gencode (0xc803);
1844 walk
= gencode (0x1800);
1850 dsp16_grp1
= gencode (0x0000);
1855 dsp16_grp2
= gencode (0x0000);
1858 walk
->next
= dsp16_grp1
;
1859 dsp16_grp1
->next
= dsp16_grp2
;
1860 dsp16_grp2
->next
= NULL_CODE
;
1866 bfin_gen_loop (Expr_Node
*exp
, REG_T reg
, int rop
, REG_T preg
)
1868 const char *loopsym
;
1869 char *lbeginsym
, *lendsym
;
1870 Expr_Node_Value lbeginval
, lendval
;
1871 Expr_Node
*lbegin
, *lend
;
1874 loopsym
= exp
->value
.s_value
;
1875 lbeginsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__BEGIN") + 5);
1876 lendsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__END") + 5);
1881 strcat (lbeginsym
, "L$L$");
1882 strcat (lbeginsym
, loopsym
);
1883 strcat (lbeginsym
, "__BEGIN");
1885 strcat (lendsym
, "L$L$");
1886 strcat (lendsym
, loopsym
);
1887 strcat (lendsym
, "__END");
1889 lbeginval
.s_value
= lbeginsym
;
1890 lendval
.s_value
= lendsym
;
1892 lbegin
= Expr_Node_Create (Expr_Node_Reloc
, lbeginval
, NULL
, NULL
);
1893 lend
= Expr_Node_Create (Expr_Node_Reloc
, lendval
, NULL
, NULL
);
1895 sym
= symbol_find(loopsym
);
1896 if (!S_IS_LOCAL (sym
) || (S_IS_LOCAL (sym
) && !symbol_used_p (sym
)))
1897 symbol_remove (sym
, &symbol_rootP
, &symbol_lastP
);
1899 return bfin_gen_loopsetup (lbegin
, reg
, rop
, lend
, preg
);
1903 bfin_loop_attempt_create_label (Expr_Node
*exp
, int is_begin
)
1906 name
= fb_label_name (exp
->value
.i_value
, is_begin
);
1907 exp
->value
.s_value
= xstrdup (name
);
1908 exp
->type
= Expr_Node_Reloc
;
1912 bfin_loop_beginend (Expr_Node
*exp
, int begin
)
1914 const char *loopsym
;
1917 const char *suffix
= begin
? "__BEGIN" : "__END";
1919 loopsym
= exp
->value
.s_value
;
1920 label_name
= (char *) xmalloc (strlen (loopsym
) + strlen (suffix
) + 5);
1924 strcat (label_name
, "L$L$");
1925 strcat (label_name
, loopsym
);
1926 strcat (label_name
, suffix
);
1928 linelabel
= colon (label_name
);
1930 /* LOOP_END follows the last instruction in the loop.
1931 Adjust label address. */
1933 ((struct local_symbol
*) linelabel
)->lsy_value
-= last_insn_size
;
1937 bfin_eol_in_insn (char *line
)
1939 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1946 /* A semi-colon followed by a newline is always the end of a line. */
1947 if (line
[-1] == ';')
1950 if (line
[-1] == '|')
1953 /* If the || is on the next line, there might be leading whitespace. */
1955 while (*temp
== ' ' || *temp
== '\t') temp
++;
1964 bfin_start_label (char *s
)
1968 if (*s
== '(' || *s
== '[')
1977 bfin_force_relocation (struct fix
*fixp
)
1979 if (fixp
->fx_r_type
==BFD_RELOC_BFIN_16_LOW
1980 || fixp
->fx_r_type
== BFD_RELOC_BFIN_16_HIGH
)
1983 return generic_force_reloc (fixp
);
1986 /* This is a stripped down version of the disassembler. The only thing it
1987 does is return a mask of registers modified by an instruction. Only
1988 instructions that can occur in a parallel-issue bundle are handled, and
1989 only the registers that can cause a conflict are recorded. */
1991 #define DREG_MASK(n) (0x101 << (n))
1992 #define DREGH_MASK(n) (0x100 << (n))
1993 #define DREGL_MASK(n) (0x001 << (n))
1994 #define IREG_MASK(n) (1 << ((n) + 16))
1997 decode_ProgCtrl_0 (int iw0
)
2005 decode_LDSTpmod_0 (int iw0
)
2008 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2009 | 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......|
2010 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2011 int W
= ((iw0
>> LDSTpmod_W_bits
) & LDSTpmod_W_mask
);
2012 int aop
= ((iw0
>> LDSTpmod_aop_bits
) & LDSTpmod_aop_mask
);
2013 int idx
= ((iw0
>> LDSTpmod_idx_bits
) & LDSTpmod_idx_mask
);
2014 int ptr
= ((iw0
>> LDSTpmod_ptr_bits
) & LDSTpmod_ptr_mask
);
2015 int reg
= ((iw0
>> LDSTpmod_reg_bits
) & LDSTpmod_reg_mask
);
2017 if (aop
== 1 && W
== 0 && idx
== ptr
)
2018 return DREGL_MASK (reg
);
2019 else if (aop
== 2 && W
== 0 && idx
== ptr
)
2020 return DREGH_MASK (reg
);
2021 else if (aop
== 1 && W
== 1 && idx
== ptr
)
2023 else if (aop
== 2 && W
== 1 && idx
== ptr
)
2025 else if (aop
== 0 && W
== 0)
2026 return DREG_MASK (reg
);
2027 else if (aop
== 1 && W
== 0)
2028 return DREGL_MASK (reg
);
2029 else if (aop
== 2 && W
== 0)
2030 return DREGH_MASK (reg
);
2031 else if (aop
== 3 && W
== 0)
2032 return DREG_MASK (reg
);
2033 else if (aop
== 3 && W
== 1)
2034 return DREG_MASK (reg
);
2035 else if (aop
== 0 && W
== 1)
2037 else if (aop
== 1 && W
== 1)
2039 else if (aop
== 2 && W
== 1)
2048 decode_dagMODim_0 (int iw0
)
2051 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2052 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....|
2053 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2054 int i
= ((iw0
>> DagMODim_i_bits
) & DagMODim_i_mask
);
2055 int opc
= ((iw0
>> DagMODim_op_bits
) & DagMODim_op_mask
);
2057 if (opc
== 0 || opc
== 1)
2058 return IREG_MASK (i
);
2066 decode_dagMODik_0 (int iw0
)
2069 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2070 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....|
2071 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2072 int i
= ((iw0
>> DagMODik_i_bits
) & DagMODik_i_mask
);
2073 return IREG_MASK (i
);
2078 decode_dspLDST_0 (int iw0
)
2081 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2082 | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......|
2083 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2084 int i
= ((iw0
>> DspLDST_i_bits
) & DspLDST_i_mask
);
2085 int m
= ((iw0
>> DspLDST_m_bits
) & DspLDST_m_mask
);
2086 int W
= ((iw0
>> DspLDST_W_bits
) & DspLDST_W_mask
);
2087 int aop
= ((iw0
>> DspLDST_aop_bits
) & DspLDST_aop_mask
);
2088 int reg
= ((iw0
>> DspLDST_reg_bits
) & DspLDST_reg_mask
);
2090 if (aop
== 0 && W
== 0 && m
== 0)
2091 return DREG_MASK (reg
) | IREG_MASK (i
);
2092 else if (aop
== 0 && W
== 0 && m
== 1)
2093 return DREGL_MASK (reg
) | IREG_MASK (i
);
2094 else if (aop
== 0 && W
== 0 && m
== 2)
2095 return DREGH_MASK (reg
) | IREG_MASK (i
);
2096 else if (aop
== 1 && W
== 0 && m
== 0)
2097 return DREG_MASK (reg
) | IREG_MASK (i
);
2098 else if (aop
== 1 && W
== 0 && m
== 1)
2099 return DREGL_MASK (reg
) | IREG_MASK (i
);
2100 else if (aop
== 1 && W
== 0 && m
== 2)
2101 return DREGH_MASK (reg
) | IREG_MASK (i
);
2102 else if (aop
== 2 && W
== 0 && m
== 0)
2103 return DREG_MASK (reg
);
2104 else if (aop
== 2 && W
== 0 && m
== 1)
2105 return DREGL_MASK (reg
);
2106 else if (aop
== 2 && W
== 0 && m
== 2)
2107 return DREGH_MASK (reg
);
2108 else if (aop
== 0 && W
== 1 && m
== 0)
2109 return IREG_MASK (i
);
2110 else if (aop
== 0 && W
== 1 && m
== 1)
2111 return IREG_MASK (i
);
2112 else if (aop
== 0 && W
== 1 && m
== 2)
2113 return IREG_MASK (i
);
2114 else if (aop
== 1 && W
== 1 && m
== 0)
2115 return IREG_MASK (i
);
2116 else if (aop
== 1 && W
== 1 && m
== 1)
2117 return IREG_MASK (i
);
2118 else if (aop
== 1 && W
== 1 && m
== 2)
2119 return IREG_MASK (i
);
2120 else if (aop
== 2 && W
== 1 && m
== 0)
2122 else if (aop
== 2 && W
== 1 && m
== 1)
2124 else if (aop
== 2 && W
== 1 && m
== 2)
2126 else if (aop
== 3 && W
== 0)
2127 return DREG_MASK (reg
) | IREG_MASK (i
);
2128 else if (aop
== 3 && W
== 1)
2129 return IREG_MASK (i
);
2136 decode_LDST_0 (int iw0
)
2139 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2140 | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......|
2141 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2142 int Z
= ((iw0
>> LDST_Z_bits
) & LDST_Z_mask
);
2143 int W
= ((iw0
>> LDST_W_bits
) & LDST_W_mask
);
2144 int sz
= ((iw0
>> LDST_sz_bits
) & LDST_sz_mask
);
2145 int aop
= ((iw0
>> LDST_aop_bits
) & LDST_aop_mask
);
2146 int reg
= ((iw0
>> LDST_reg_bits
) & LDST_reg_mask
);
2148 if (aop
== 0 && sz
== 0 && Z
== 0 && W
== 0)
2149 return DREG_MASK (reg
);
2150 else if (aop
== 0 && sz
== 0 && Z
== 1 && W
== 0)
2152 else if (aop
== 0 && sz
== 1 && Z
== 0 && W
== 0)
2153 return DREG_MASK (reg
);
2154 else if (aop
== 0 && sz
== 1 && Z
== 1 && W
== 0)
2155 return DREG_MASK (reg
);
2156 else if (aop
== 0 && sz
== 2 && Z
== 0 && W
== 0)
2157 return DREG_MASK (reg
);
2158 else if (aop
== 0 && sz
== 2 && Z
== 1 && W
== 0)
2159 return DREG_MASK (reg
);
2160 else if (aop
== 1 && sz
== 0 && Z
== 0 && W
== 0)
2161 return DREG_MASK (reg
);
2162 else if (aop
== 1 && sz
== 0 && Z
== 1 && W
== 0)
2164 else if (aop
== 1 && sz
== 1 && Z
== 0 && W
== 0)
2165 return DREG_MASK (reg
);
2166 else if (aop
== 1 && sz
== 1 && Z
== 1 && W
== 0)
2167 return DREG_MASK (reg
);
2168 else if (aop
== 1 && sz
== 2 && Z
== 0 && W
== 0)
2169 return DREG_MASK (reg
);
2170 else if (aop
== 1 && sz
== 2 && Z
== 1 && W
== 0)
2171 return DREG_MASK (reg
);
2172 else if (aop
== 2 && sz
== 0 && Z
== 0 && W
== 0)
2173 return DREG_MASK (reg
);
2174 else if (aop
== 2 && sz
== 0 && Z
== 1 && W
== 0)
2176 else if (aop
== 2 && sz
== 1 && Z
== 0 && W
== 0)
2177 return DREG_MASK (reg
);
2178 else if (aop
== 2 && sz
== 1 && Z
== 1 && W
== 0)
2179 return DREG_MASK (reg
);
2180 else if (aop
== 2 && sz
== 2 && Z
== 0 && W
== 0)
2181 return DREG_MASK (reg
);
2182 else if (aop
== 2 && sz
== 2 && Z
== 1 && W
== 0)
2183 return DREG_MASK (reg
);
2184 else if (aop
== 0 && sz
== 0 && Z
== 0 && W
== 1)
2186 else if (aop
== 0 && sz
== 0 && Z
== 1 && W
== 1)
2188 else if (aop
== 0 && sz
== 1 && Z
== 0 && W
== 1)
2190 else if (aop
== 0 && sz
== 2 && Z
== 0 && W
== 1)
2192 else if (aop
== 1 && sz
== 0 && Z
== 0 && W
== 1)
2194 else if (aop
== 1 && sz
== 0 && Z
== 1 && W
== 1)
2196 else if (aop
== 1 && sz
== 1 && Z
== 0 && W
== 1)
2198 else if (aop
== 1 && sz
== 2 && Z
== 0 && W
== 1)
2200 else if (aop
== 2 && sz
== 0 && Z
== 0 && W
== 1)
2202 else if (aop
== 2 && sz
== 0 && Z
== 1 && W
== 1)
2204 else if (aop
== 2 && sz
== 1 && Z
== 0 && W
== 1)
2206 else if (aop
== 2 && sz
== 2 && Z
== 0 && W
== 1)
2213 decode_LDSTiiFP_0 (int iw0
)
2216 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2217 | 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........|
2218 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2219 int reg
= ((iw0
>> LDSTiiFP_reg_bits
) & LDSTiiFP_reg_mask
);
2220 int W
= ((iw0
>> LDSTiiFP_W_bits
) & LDSTiiFP_W_mask
);
2223 return reg
< 8 ? DREG_MASK (reg
) : 0;
2229 decode_LDSTii_0 (int iw0
)
2232 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2233 | 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......|
2234 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2235 int reg
= ((iw0
>> LDSTii_reg_bit
) & LDSTii_reg_mask
);
2236 int opc
= ((iw0
>> LDSTii_op_bit
) & LDSTii_op_mask
);
2237 int W
= ((iw0
>> LDSTii_W_bit
) & LDSTii_W_mask
);
2239 if (W
== 0 && opc
!= 3)
2240 return DREG_MASK (reg
);
2241 else if (W
== 0 && opc
== 3)
2243 else if (W
== 1 && opc
== 0)
2245 else if (W
== 1 && opc
== 1)
2247 else if (W
== 1 && opc
== 3)
2254 decode_dsp32mac_0 (int iw0
, int iw1
)
2258 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2259 | 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...|
2260 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2261 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2262 int op1
= ((iw0
>> (DSP32Mac_op1_bits
- 16)) & DSP32Mac_op1_mask
);
2263 int w1
= ((iw0
>> (DSP32Mac_w1_bits
- 16)) & DSP32Mac_w1_mask
);
2264 int P
= ((iw0
>> (DSP32Mac_p_bits
- 16)) & DSP32Mac_p_mask
);
2265 int mmod
= ((iw0
>> (DSP32Mac_mmod_bits
- 16)) & DSP32Mac_mmod_mask
);
2266 int w0
= ((iw1
>> DSP32Mac_w0_bits
) & DSP32Mac_w0_mask
);
2267 int MM
= ((iw1
>> DSP32Mac_MM_bits
) & DSP32Mac_MM_mask
);
2268 int dst
= ((iw1
>> DSP32Mac_dst_bits
) & DSP32Mac_dst_mask
);
2269 int op0
= ((iw1
>> DSP32Mac_op0_bits
) & DSP32Mac_op0_mask
);
2271 if (w0
== 0 && w1
== 0 && op1
== 3 && op0
== 3)
2277 if ((w1
|| w0
) && mmod
== M_W32
)
2280 if (((1 << mmod
) & (P
? 0x131b : 0x1b5f)) == 0)
2283 if (w1
== 1 || op1
!= 3)
2288 return DREG_MASK (dst
+ 1);
2290 return DREGH_MASK (dst
);
2294 if (w0
== 1 || op0
!= 3)
2299 return DREG_MASK (dst
);
2301 return DREGL_MASK (dst
);
2309 decode_dsp32mult_0 (int iw0
, int iw1
)
2312 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2313 | 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...|
2314 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2315 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2316 int w1
= ((iw0
>> (DSP32Mac_w1_bits
- 16)) & DSP32Mac_w1_mask
);
2317 int P
= ((iw0
>> (DSP32Mac_p_bits
- 16)) & DSP32Mac_p_mask
);
2318 int mmod
= ((iw0
>> (DSP32Mac_mmod_bits
- 16)) & DSP32Mac_mmod_mask
);
2319 int w0
= ((iw1
>> DSP32Mac_w0_bits
) & DSP32Mac_w0_mask
);
2320 int dst
= ((iw1
>> DSP32Mac_dst_bits
) & DSP32Mac_dst_mask
);
2323 if (w1
== 0 && w0
== 0)
2326 if (((1 << mmod
) & (P
? 0x313 : 0x1b57)) == 0)
2332 return DREG_MASK (dst
| 1);
2334 return DREGH_MASK (dst
);
2340 return DREG_MASK (dst
);
2342 return DREGL_MASK (dst
);
2349 decode_dsp32alu_0 (int iw0
, int iw1
)
2352 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2353 | 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............|
2354 |.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......|
2355 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2356 int s
= ((iw1
>> DSP32Alu_s_bits
) & DSP32Alu_s_mask
);
2357 int x
= ((iw1
>> DSP32Alu_x_bits
) & DSP32Alu_x_mask
);
2358 int aop
= ((iw1
>> DSP32Alu_aop_bits
) & DSP32Alu_aop_mask
);
2359 int dst0
= ((iw1
>> DSP32Alu_dst0_bits
) & DSP32Alu_dst0_mask
);
2360 int dst1
= ((iw1
>> DSP32Alu_dst1_bits
) & DSP32Alu_dst1_mask
);
2361 int HL
= ((iw0
>> (DSP32Alu_HL_bits
- 16)) & DSP32Alu_HL_mask
);
2362 int aopcde
= ((iw0
>> (DSP32Alu_aopcde_bits
- 16)) & DSP32Alu_aopcde_mask
);
2364 if (aop
== 0 && aopcde
== 9 && s
== 0)
2366 else if (aop
== 2 && aopcde
== 9 && HL
== 0 && s
== 0)
2368 else if (aop
>= x
* 2 && aopcde
== 5)
2369 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2370 else if (HL
== 0 && aopcde
== 2)
2371 return DREGL_MASK (dst0
);
2372 else if (HL
== 1 && aopcde
== 2)
2373 return DREGH_MASK (dst0
);
2374 else if (HL
== 0 && aopcde
== 3)
2375 return DREGL_MASK (dst0
);
2376 else if (HL
== 1 && aopcde
== 3)
2377 return DREGH_MASK (dst0
);
2379 else if (aop
== 0 && aopcde
== 9 && s
== 1)
2381 else if (aop
== 1 && aopcde
== 9 && s
== 0)
2383 else if (aop
== 2 && aopcde
== 9 && s
== 1)
2385 else if (aop
== 3 && aopcde
== 9 && s
== 0)
2387 else if (aopcde
== 8)
2389 else if (aop
== 0 && aopcde
== 11)
2390 return DREG_MASK (dst0
);
2391 else if (aop
== 1 && aopcde
== 11)
2392 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2393 else if (aopcde
== 11)
2395 else if (aopcde
== 22)
2396 return DREG_MASK (dst0
);
2398 else if ((aop
== 0 || aop
== 1) && aopcde
== 14)
2400 else if (aop
== 3 && HL
== 0 && aopcde
== 14)
2403 else if (aop
== 3 && HL
== 0 && aopcde
== 15)
2404 return DREG_MASK (dst0
);
2406 else if (aop
== 1 && aopcde
== 16)
2409 else if (aop
== 0 && aopcde
== 16)
2412 else if (aop
== 3 && HL
== 0 && aopcde
== 16)
2415 else if (aop
== 3 && HL
== 0 && aopcde
== 7)
2416 return DREG_MASK (dst0
);
2417 else if ((aop
== 0 || aop
== 1 || aop
== 2) && aopcde
== 7)
2418 return DREG_MASK (dst0
);
2420 else if (aop
== 0 && aopcde
== 12)
2421 return DREG_MASK (dst0
);
2422 else if (aop
== 1 && aopcde
== 12)
2423 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2424 else if (aop
== 3 && aopcde
== 12)
2425 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2427 else if (aopcde
== 0)
2428 return DREG_MASK (dst0
);
2429 else if (aopcde
== 1)
2430 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2432 else if (aop
== 0 && aopcde
== 10)
2433 return DREGL_MASK (dst0
);
2434 else if (aop
== 1 && aopcde
== 10)
2435 return DREGL_MASK (dst0
);
2437 else if ((aop
== 1 || aop
== 0) && aopcde
== 4)
2438 return DREG_MASK (dst0
);
2439 else if (aop
== 2 && aopcde
== 4)
2440 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2442 else if (aop
== 0 && aopcde
== 17)
2443 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2444 else if (aop
== 1 && aopcde
== 17)
2445 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2446 else if (aop
== 0 && aopcde
== 18)
2448 else if (aop
== 3 && aopcde
== 18)
2451 else if ((aop
== 0 || aop
== 1 || aop
== 2) && aopcde
== 6)
2452 return DREG_MASK (dst0
);
2454 else if ((aop
== 0 || aop
== 1) && aopcde
== 20)
2455 return DREG_MASK (dst0
);
2457 else if ((aop
== 0 || aop
== 1) && aopcde
== 21)
2458 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2460 else if (aop
== 0 && aopcde
== 23 && HL
== 1)
2461 return DREG_MASK (dst0
);
2462 else if (aop
== 0 && aopcde
== 23 && HL
== 0)
2463 return DREG_MASK (dst0
);
2465 else if (aop
== 0 && aopcde
== 24)
2466 return DREG_MASK (dst0
);
2467 else if (aop
== 1 && aopcde
== 24)
2468 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2469 else if (aopcde
== 13)
2470 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2478 decode_dsp32shift_0 (int iw0
, int iw1
)
2481 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2482 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............|
2483 |.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......|
2484 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2485 int HLs
= ((iw1
>> DSP32Shift_HLs_bits
) & DSP32Shift_HLs_mask
);
2486 int sop
= ((iw1
>> DSP32Shift_sop_bits
) & DSP32Shift_sop_mask
);
2487 int src0
= ((iw1
>> DSP32Shift_src0_bits
) & DSP32Shift_src0_mask
);
2488 int src1
= ((iw1
>> DSP32Shift_src1_bits
) & DSP32Shift_src1_mask
);
2489 int dst0
= ((iw1
>> DSP32Shift_dst0_bits
) & DSP32Shift_dst0_mask
);
2490 int sopcde
= ((iw0
>> (DSP32Shift_sopcde_bits
- 16)) & DSP32Shift_sopcde_mask
);
2492 if (sop
== 0 && sopcde
== 0)
2493 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2494 else if (sop
== 1 && sopcde
== 0)
2495 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2496 else if (sop
== 2 && sopcde
== 0)
2497 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2498 else if (sop
== 0 && sopcde
== 3)
2500 else if (sop
== 1 && sopcde
== 3)
2502 else if (sop
== 2 && sopcde
== 3)
2504 else if (sop
== 3 && sopcde
== 3)
2505 return DREG_MASK (dst0
);
2506 else if (sop
== 0 && sopcde
== 1)
2507 return DREG_MASK (dst0
);
2508 else if (sop
== 1 && sopcde
== 1)
2509 return DREG_MASK (dst0
);
2510 else if (sop
== 2 && sopcde
== 1)
2511 return DREG_MASK (dst0
);
2512 else if (sopcde
== 2)
2513 return DREG_MASK (dst0
);
2514 else if (sopcde
== 4)
2515 return DREG_MASK (dst0
);
2516 else if (sop
== 0 && sopcde
== 5)
2517 return DREGL_MASK (dst0
);
2518 else if (sop
== 1 && sopcde
== 5)
2519 return DREGL_MASK (dst0
);
2520 else if (sop
== 2 && sopcde
== 5)
2521 return DREGL_MASK (dst0
);
2522 else if (sop
== 0 && sopcde
== 6)
2523 return DREGL_MASK (dst0
);
2524 else if (sop
== 1 && sopcde
== 6)
2525 return DREGL_MASK (dst0
);
2526 else if (sop
== 3 && sopcde
== 6)
2527 return DREGL_MASK (dst0
);
2528 else if (sop
== 0 && sopcde
== 7)
2529 return DREGL_MASK (dst0
);
2530 else if (sop
== 1 && sopcde
== 7)
2531 return DREGL_MASK (dst0
);
2532 else if (sop
== 2 && sopcde
== 7)
2533 return DREGL_MASK (dst0
);
2534 else if (sop
== 3 && sopcde
== 7)
2535 return DREGL_MASK (dst0
);
2536 else if (sop
== 0 && sopcde
== 8)
2537 return DREG_MASK (src0
) | DREG_MASK (src1
);
2540 OUTS (outf
, "BITMUX (");
2541 OUTS (outf
, dregs (src0
));
2543 OUTS (outf
, dregs (src1
));
2544 OUTS (outf
, ", A0) (ASR)");
2547 else if (sop
== 1 && sopcde
== 8)
2548 return DREG_MASK (src0
) | DREG_MASK (src1
);
2551 OUTS (outf
, "BITMUX (");
2552 OUTS (outf
, dregs (src0
));
2554 OUTS (outf
, dregs (src1
));
2555 OUTS (outf
, ", A0) (ASL)");
2558 else if (sopcde
== 9)
2559 return sop
< 2 ? DREGL_MASK (dst0
) : DREG_MASK (dst0
);
2560 else if (sopcde
== 10)
2561 return DREG_MASK (dst0
);
2562 else if (sop
== 0 && sopcde
== 11)
2563 return DREGL_MASK (dst0
);
2564 else if (sop
== 1 && sopcde
== 11)
2565 return DREGL_MASK (dst0
);
2566 else if (sop
== 0 && sopcde
== 12)
2568 else if (sop
== 1 && sopcde
== 12)
2569 return DREGL_MASK (dst0
);
2570 else if (sop
== 0 && sopcde
== 13)
2571 return DREG_MASK (dst0
);
2572 else if (sop
== 1 && sopcde
== 13)
2573 return DREG_MASK (dst0
);
2574 else if (sop
== 2 && sopcde
== 13)
2575 return DREG_MASK (dst0
);
2581 decode_dsp32shiftimm_0 (int iw0
, int iw1
)
2584 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2585 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............|
2586 |.sop...|.HLs...|.dst0......|.immag.................|.src1......|
2587 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2588 int sop
= ((iw1
>> DSP32ShiftImm_sop_bits
) & DSP32ShiftImm_sop_mask
);
2589 int bit8
= ((iw1
>> 8) & 0x1);
2590 int dst0
= ((iw1
>> DSP32ShiftImm_dst0_bits
) & DSP32ShiftImm_dst0_mask
);
2591 int sopcde
= ((iw0
>> (DSP32ShiftImm_sopcde_bits
- 16)) & DSP32ShiftImm_sopcde_mask
);
2592 int HLs
= ((iw1
>> DSP32ShiftImm_HLs_bits
) & DSP32ShiftImm_HLs_mask
);
2595 if (sop
== 0 && sopcde
== 0)
2596 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2597 else if (sop
== 1 && sopcde
== 0 && bit8
== 0)
2598 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2599 else if (sop
== 1 && sopcde
== 0 && bit8
== 1)
2600 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2601 else if (sop
== 2 && sopcde
== 0 && bit8
== 0)
2602 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2603 else if (sop
== 2 && sopcde
== 0 && bit8
== 1)
2604 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2605 else if (sop
== 2 && sopcde
== 3 && HLs
== 1)
2607 else if (sop
== 0 && sopcde
== 3 && HLs
== 0 && bit8
== 0)
2609 else if (sop
== 0 && sopcde
== 3 && HLs
== 0 && bit8
== 1)
2611 else if (sop
== 0 && sopcde
== 3 && HLs
== 1 && bit8
== 0)
2613 else if (sop
== 0 && sopcde
== 3 && HLs
== 1 && bit8
== 1)
2615 else if (sop
== 1 && sopcde
== 3 && HLs
== 0)
2617 else if (sop
== 1 && sopcde
== 3 && HLs
== 1)
2619 else if (sop
== 2 && sopcde
== 3 && HLs
== 0)
2621 else if (sop
== 1 && sopcde
== 1 && bit8
== 0)
2622 return DREG_MASK (dst0
);
2623 else if (sop
== 1 && sopcde
== 1 && bit8
== 1)
2624 return DREG_MASK (dst0
);
2625 else if (sop
== 2 && sopcde
== 1 && bit8
== 1)
2626 return DREG_MASK (dst0
);
2627 else if (sop
== 2 && sopcde
== 1 && bit8
== 0)
2628 return DREG_MASK (dst0
);
2629 else if (sop
== 0 && sopcde
== 1)
2630 return DREG_MASK (dst0
);
2631 else if (sop
== 1 && sopcde
== 2)
2632 return DREG_MASK (dst0
);
2633 else if (sop
== 2 && sopcde
== 2 && bit8
== 1)
2634 return DREG_MASK (dst0
);
2635 else if (sop
== 2 && sopcde
== 2 && bit8
== 0)
2636 return DREG_MASK (dst0
);
2637 else if (sop
== 3 && sopcde
== 2)
2638 return DREG_MASK (dst0
);
2639 else if (sop
== 0 && sopcde
== 2)
2640 return DREG_MASK (dst0
);
2646 insn_regmask (int iw0
, int iw1
)
2648 if ((iw0
& 0xf7ff) == 0xc003 && iw1
== 0x1800)
2649 return 0; /* MNOP */
2650 else if ((iw0
& 0xff00) == 0x0000)
2651 return decode_ProgCtrl_0 (iw0
);
2652 else if ((iw0
& 0xffc0) == 0x0240)
2654 else if ((iw0
& 0xff80) == 0x0100)
2656 else if ((iw0
& 0xfe00) == 0x0400)
2658 else if ((iw0
& 0xfe00) == 0x0600)
2660 else if ((iw0
& 0xf800) == 0x0800)
2662 else if ((iw0
& 0xffe0) == 0x0200)
2664 else if ((iw0
& 0xff00) == 0x0300)
2666 else if ((iw0
& 0xf000) == 0x1000)
2668 else if ((iw0
& 0xf000) == 0x2000)
2670 else if ((iw0
& 0xf000) == 0x3000)
2672 else if ((iw0
& 0xfc00) == 0x4000)
2674 else if ((iw0
& 0xfe00) == 0x4400)
2676 else if ((iw0
& 0xf800) == 0x4800)
2678 else if ((iw0
& 0xf000) == 0x5000)
2680 else if ((iw0
& 0xf800) == 0x6000)
2682 else if ((iw0
& 0xf800) == 0x6800)
2684 else if ((iw0
& 0xf000) == 0x8000)
2685 return decode_LDSTpmod_0 (iw0
);
2686 else if ((iw0
& 0xff60) == 0x9e60)
2687 return decode_dagMODim_0 (iw0
);
2688 else if ((iw0
& 0xfff0) == 0x9f60)
2689 return decode_dagMODik_0 (iw0
);
2690 else if ((iw0
& 0xfc00) == 0x9c00)
2691 return decode_dspLDST_0 (iw0
);
2692 else if ((iw0
& 0xf000) == 0x9000)
2693 return decode_LDST_0 (iw0
);
2694 else if ((iw0
& 0xfc00) == 0xb800)
2695 return decode_LDSTiiFP_0 (iw0
);
2696 else if ((iw0
& 0xe000) == 0xA000)
2697 return decode_LDSTii_0 (iw0
);
2698 else if ((iw0
& 0xff80) == 0xe080 && (iw1
& 0x0C00) == 0x0000)
2700 else if ((iw0
& 0xff00) == 0xe100 && (iw1
& 0x0000) == 0x0000)
2702 else if ((iw0
& 0xfe00) == 0xe200 && (iw1
& 0x0000) == 0x0000)
2704 else if ((iw0
& 0xfc00) == 0xe400 && (iw1
& 0x0000) == 0x0000)
2706 else if ((iw0
& 0xfffe) == 0xe800 && (iw1
& 0x0000) == 0x0000)
2708 else if ((iw0
& 0xf600) == 0xc000 && (iw1
& 0x0000) == 0x0000)
2709 return decode_dsp32mac_0 (iw0
, iw1
);
2710 else if ((iw0
& 0xf600) == 0xc200 && (iw1
& 0x0000) == 0x0000)
2711 return decode_dsp32mult_0 (iw0
, iw1
);
2712 else if ((iw0
& 0xf7c0) == 0xc400 && (iw1
& 0x0000) == 0x0000)
2713 return decode_dsp32alu_0 (iw0
, iw1
);
2714 else if ((iw0
& 0xf780) == 0xc600 && (iw1
& 0x01c0) == 0x0000)
2715 return decode_dsp32shift_0 (iw0
, iw1
);
2716 else if ((iw0
& 0xf780) == 0xc680 && (iw1
& 0x0000) == 0x0000)
2717 return decode_dsp32shiftimm_0 (iw0
, iw1
);
2718 else if ((iw0
& 0xff00) == 0xf800)
2720 else if ((iw0
& 0xFFC0) == 0xf000 && (iw1
& 0x0000) == 0x0000)