1 /* tc-bfin.c -- Assembler for the ADI Blackfin.
2 Copyright (C) 2005-2024 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 "bfin-defs.h"
24 #include "safe-ctype.h"
26 #include "dwarf2dbg.h"
28 #include "elf/common.h"
31 extern int yyparse (void);
32 struct yy_buffer_state
;
33 typedef struct yy_buffer_state
*YY_BUFFER_STATE
;
34 extern YY_BUFFER_STATE
yy_scan_string (const char *yy_str
);
35 extern void yy_delete_buffer (YY_BUFFER_STATE b
);
36 static parse_state
parse (char *line
);
38 /* Global variables. */
39 struct bfin_insn
*insn
;
42 extern struct obstack mempool
;
45 /* Flags to set in the elf header */
46 #define DEFAULT_FLAGS 0
49 # define DEFAULT_FDPIC EF_BFIN_FDPIC
51 # define DEFAULT_FDPIC 0
54 static flagword bfin_flags
= DEFAULT_FLAGS
| DEFAULT_FDPIC
;
55 static const char *bfin_pic_flag
= DEFAULT_FDPIC
? "-mfdpic" : (const char *)0;
57 /* Blackfin specific function to handle FD-PIC pointer initializations. */
60 bfin_pic_ptr (int nbytes
)
68 #ifdef md_flush_pending_output
69 md_flush_pending_output ();
72 if (is_it_end_of_statement ())
74 demand_empty_rest_of_line ();
79 md_cons_align (nbytes
);
84 bfd_reloc_code_real_type reloc_type
= BFD_RELOC_BFIN_FUNCDESC
;
86 if (strncasecmp (input_line_pointer
, "funcdesc(", 9) == 0)
88 input_line_pointer
+= 9;
90 if (*input_line_pointer
== ')')
93 as_bad (_("missing ')'"));
96 error ("missing funcdesc in picptr");
100 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &exp
, 0,
103 while (*input_line_pointer
++ == ',');
105 input_line_pointer
--; /* Put terminator back into stream. */
106 demand_empty_rest_of_line ();
109 const pseudo_typeS md_pseudo_table
[] = {
110 {"align", s_align_bytes
, 0},
113 {"picptr", bfin_pic_ptr
, 4},
114 {"code", obj_elf_section
, 0},
119 {"pdata", s_ignore
, 0},
120 {"var", s_ignore
, 0},
124 /* Characters that are used to denote comments and line separators. */
125 const char comment_chars
[] = "#";
126 const char line_comment_chars
[] = "#";
127 const char line_separator_chars
[] = ";";
129 /* Characters that can be used to separate the mantissa from the
130 exponent in floating point numbers. */
131 const char EXP_CHARS
[] = "eE";
133 /* Characters that mean this number is a floating point constant.
134 As in 0f12.456 or 0d1.2345e12. */
135 const char FLT_CHARS
[] = "fFdDxX";
137 typedef enum bfin_cpu_type
174 bfin_cpu_t bfin_cpu_type
= BFIN_CPU_UNKNOWN
;
175 /* -msi-revision support. There are three special values:
176 -1 -msi-revision=none.
177 0xffff -msi-revision=any. */
178 int bfin_si_revision
;
180 unsigned int bfin_anomaly_checks
= 0;
187 unsigned int anomaly_checks
;
190 struct bfin_cpu bfin_cpus
[] =
192 {"bf504", BFIN_CPU_BF504
, 0x0000, AC_05000074
},
194 {"bf506", BFIN_CPU_BF506
, 0x0000, AC_05000074
},
196 {"bf512", BFIN_CPU_BF512
, 0x0002, AC_05000074
},
197 {"bf512", BFIN_CPU_BF512
, 0x0001, AC_05000074
},
198 {"bf512", BFIN_CPU_BF512
, 0x0000, AC_05000074
},
200 {"bf514", BFIN_CPU_BF514
, 0x0002, AC_05000074
},
201 {"bf514", BFIN_CPU_BF514
, 0x0001, AC_05000074
},
202 {"bf514", BFIN_CPU_BF514
, 0x0000, AC_05000074
},
204 {"bf516", BFIN_CPU_BF516
, 0x0002, AC_05000074
},
205 {"bf516", BFIN_CPU_BF516
, 0x0001, AC_05000074
},
206 {"bf516", BFIN_CPU_BF516
, 0x0000, AC_05000074
},
208 {"bf518", BFIN_CPU_BF518
, 0x0002, AC_05000074
},
209 {"bf518", BFIN_CPU_BF518
, 0x0001, AC_05000074
},
210 {"bf518", BFIN_CPU_BF518
, 0x0000, AC_05000074
},
212 {"bf522", BFIN_CPU_BF522
, 0x0002, AC_05000074
},
213 {"bf522", BFIN_CPU_BF522
, 0x0001, AC_05000074
},
214 {"bf522", BFIN_CPU_BF522
, 0x0000, AC_05000074
},
216 {"bf523", BFIN_CPU_BF523
, 0x0002, AC_05000074
},
217 {"bf523", BFIN_CPU_BF523
, 0x0001, AC_05000074
},
218 {"bf523", BFIN_CPU_BF523
, 0x0000, AC_05000074
},
220 {"bf524", BFIN_CPU_BF524
, 0x0002, AC_05000074
},
221 {"bf524", BFIN_CPU_BF524
, 0x0001, AC_05000074
},
222 {"bf524", BFIN_CPU_BF524
, 0x0000, AC_05000074
},
224 {"bf525", BFIN_CPU_BF525
, 0x0002, AC_05000074
},
225 {"bf525", BFIN_CPU_BF525
, 0x0001, AC_05000074
},
226 {"bf525", BFIN_CPU_BF525
, 0x0000, AC_05000074
},
228 {"bf526", BFIN_CPU_BF526
, 0x0002, AC_05000074
},
229 {"bf526", BFIN_CPU_BF526
, 0x0001, AC_05000074
},
230 {"bf526", BFIN_CPU_BF526
, 0x0000, AC_05000074
},
232 {"bf527", BFIN_CPU_BF527
, 0x0002, AC_05000074
},
233 {"bf527", BFIN_CPU_BF527
, 0x0001, AC_05000074
},
234 {"bf527", BFIN_CPU_BF527
, 0x0000, AC_05000074
},
236 {"bf531", BFIN_CPU_BF531
, 0x0006, AC_05000074
},
237 {"bf531", BFIN_CPU_BF531
, 0x0005, AC_05000074
},
238 {"bf531", BFIN_CPU_BF531
, 0x0004, AC_05000074
},
239 {"bf531", BFIN_CPU_BF531
, 0x0003, AC_05000074
},
241 {"bf532", BFIN_CPU_BF532
, 0x0006, AC_05000074
},
242 {"bf532", BFIN_CPU_BF532
, 0x0005, AC_05000074
},
243 {"bf532", BFIN_CPU_BF532
, 0x0004, AC_05000074
},
244 {"bf532", BFIN_CPU_BF532
, 0x0003, AC_05000074
},
246 {"bf533", BFIN_CPU_BF533
, 0x0006, AC_05000074
},
247 {"bf533", BFIN_CPU_BF533
, 0x0005, AC_05000074
},
248 {"bf533", BFIN_CPU_BF533
, 0x0004, AC_05000074
},
249 {"bf533", BFIN_CPU_BF533
, 0x0003, AC_05000074
},
251 {"bf534", BFIN_CPU_BF534
, 0x0003, AC_05000074
},
252 {"bf534", BFIN_CPU_BF534
, 0x0002, AC_05000074
},
253 {"bf534", BFIN_CPU_BF534
, 0x0001, AC_05000074
},
255 {"bf536", BFIN_CPU_BF536
, 0x0003, AC_05000074
},
256 {"bf536", BFIN_CPU_BF536
, 0x0002, AC_05000074
},
257 {"bf536", BFIN_CPU_BF536
, 0x0001, AC_05000074
},
259 {"bf537", BFIN_CPU_BF537
, 0x0003, AC_05000074
},
260 {"bf537", BFIN_CPU_BF537
, 0x0002, AC_05000074
},
261 {"bf537", BFIN_CPU_BF537
, 0x0001, AC_05000074
},
263 {"bf538", BFIN_CPU_BF538
, 0x0005, AC_05000074
},
264 {"bf538", BFIN_CPU_BF538
, 0x0004, AC_05000074
},
265 {"bf538", BFIN_CPU_BF538
, 0x0003, AC_05000074
},
266 {"bf538", BFIN_CPU_BF538
, 0x0002, AC_05000074
},
268 {"bf539", BFIN_CPU_BF539
, 0x0005, AC_05000074
},
269 {"bf539", BFIN_CPU_BF539
, 0x0004, AC_05000074
},
270 {"bf539", BFIN_CPU_BF539
, 0x0003, AC_05000074
},
271 {"bf539", BFIN_CPU_BF539
, 0x0002, AC_05000074
},
273 {"bf542m", BFIN_CPU_BF542M
, 0x0003, AC_05000074
},
275 {"bf542", BFIN_CPU_BF542
, 0x0004, AC_05000074
},
276 {"bf542", BFIN_CPU_BF542
, 0x0002, AC_05000074
},
277 {"bf542", BFIN_CPU_BF542
, 0x0001, AC_05000074
},
278 {"bf542", BFIN_CPU_BF542
, 0x0000, AC_05000074
},
280 {"bf544m", BFIN_CPU_BF544M
, 0x0003, AC_05000074
},
282 {"bf544", BFIN_CPU_BF544
, 0x0004, AC_05000074
},
283 {"bf544", BFIN_CPU_BF544
, 0x0002, AC_05000074
},
284 {"bf544", BFIN_CPU_BF544
, 0x0001, AC_05000074
},
285 {"bf544", BFIN_CPU_BF544
, 0x0000, AC_05000074
},
287 {"bf547m", BFIN_CPU_BF547M
, 0x0003, AC_05000074
},
289 {"bf547", BFIN_CPU_BF547
, 0x0004, AC_05000074
},
290 {"bf547", BFIN_CPU_BF547
, 0x0002, AC_05000074
},
291 {"bf547", BFIN_CPU_BF547
, 0x0001, AC_05000074
},
292 {"bf547", BFIN_CPU_BF547
, 0x0000, AC_05000074
},
294 {"bf548m", BFIN_CPU_BF548M
, 0x0003, AC_05000074
},
296 {"bf548", BFIN_CPU_BF548
, 0x0004, AC_05000074
},
297 {"bf548", BFIN_CPU_BF548
, 0x0002, AC_05000074
},
298 {"bf548", BFIN_CPU_BF548
, 0x0001, AC_05000074
},
299 {"bf548", BFIN_CPU_BF548
, 0x0000, AC_05000074
},
301 {"bf549m", BFIN_CPU_BF549M
, 0x0003, AC_05000074
},
303 {"bf549", BFIN_CPU_BF549
, 0x0004, AC_05000074
},
304 {"bf549", BFIN_CPU_BF549
, 0x0002, AC_05000074
},
305 {"bf549", BFIN_CPU_BF549
, 0x0001, AC_05000074
},
306 {"bf549", BFIN_CPU_BF549
, 0x0000, AC_05000074
},
308 {"bf561", BFIN_CPU_BF561
, 0x0005, AC_05000074
},
309 {"bf561", BFIN_CPU_BF561
, 0x0003, AC_05000074
},
310 {"bf561", BFIN_CPU_BF561
, 0x0002, AC_05000074
},
312 {"bf592", BFIN_CPU_BF592
, 0x0001, AC_05000074
},
313 {"bf592", BFIN_CPU_BF592
, 0x0000, AC_05000074
},
316 /* Define bfin-specific command-line options (there are none). */
317 const char *md_shortopts
= "";
319 #define OPTION_FDPIC (OPTION_MD_BASE)
320 #define OPTION_NOPIC (OPTION_MD_BASE + 1)
321 #define OPTION_MCPU (OPTION_MD_BASE + 2)
323 struct option md_longopts
[] =
325 { "mcpu", required_argument
, NULL
, OPTION_MCPU
},
326 { "mfdpic", no_argument
, NULL
, OPTION_FDPIC
},
327 { "mnopic", no_argument
, NULL
, OPTION_NOPIC
},
328 { "mno-fdpic", no_argument
, NULL
, OPTION_NOPIC
},
329 { NULL
, no_argument
, NULL
, 0 },
332 size_t md_longopts_size
= sizeof (md_longopts
);
336 md_parse_option (int c ATTRIBUTE_UNUSED
, const char *arg ATTRIBUTE_UNUSED
)
348 for (i
= 0; i
< ARRAY_SIZE (bfin_cpus
); i
++)
350 const char *p
= bfin_cpus
[i
].name
;
351 if (strncmp (arg
, p
, strlen (p
)) == 0)
355 if (i
== ARRAY_SIZE (bfin_cpus
))
356 as_fatal ("-mcpu=%s is not valid", arg
);
358 bfin_cpu_type
= bfin_cpus
[i
].type
;
360 q
= arg
+ strlen (bfin_cpus
[i
].name
);
364 bfin_si_revision
= bfin_cpus
[i
].si_revision
;
365 bfin_anomaly_checks
|= bfin_cpus
[i
].anomaly_checks
;
367 else if (strcmp (q
, "-none") == 0)
368 bfin_si_revision
= -1;
369 else if (strcmp (q
, "-any") == 0)
371 bfin_si_revision
= 0xffff;
372 while (i
< ARRAY_SIZE (bfin_cpus
)
373 && bfin_cpus
[i
].type
== bfin_cpu_type
)
375 bfin_anomaly_checks
|= bfin_cpus
[i
].anomaly_checks
;
381 unsigned int si_major
, si_minor
;
384 rev_len
= strlen (q
);
386 if (sscanf (q
, "-%u.%u%n", &si_major
, &si_minor
, &n
) != 2
388 || si_major
> 0xff || si_minor
> 0xff)
390 invalid_silicon_revision
:
391 as_fatal ("-mcpu=%s has invalid silicon revision", arg
);
394 bfin_si_revision
= (si_major
<< 8) | si_minor
;
396 while (i
< ARRAY_SIZE (bfin_cpus
)
397 && bfin_cpus
[i
].type
== bfin_cpu_type
398 && bfin_cpus
[i
].si_revision
!= bfin_si_revision
)
401 if (i
== ARRAY_SIZE (bfin_cpus
)
402 || bfin_cpus
[i
].type
!= bfin_cpu_type
)
403 goto invalid_silicon_revision
;
405 bfin_anomaly_checks
|= bfin_cpus
[i
].anomaly_checks
;
412 bfin_flags
|= EF_BFIN_FDPIC
;
413 bfin_pic_flag
= "-mfdpic";
417 bfin_flags
&= ~(EF_BFIN_FDPIC
);
426 md_show_usage (FILE * stream
)
428 fprintf (stream
, _(" Blackfin specific assembler options:\n"));
429 fprintf (stream
, _(" -mcpu=<cpu[-sirevision]> specify the name of the target CPU\n"));
430 fprintf (stream
, _(" -mfdpic assemble for the FDPIC ABI\n"));
431 fprintf (stream
, _(" -mno-fdpic/-mnopic disable -mfdpic\n"));
434 /* Perform machine-specific initializations. */
438 /* Set the ELF flags if desired. */
440 bfd_set_private_flags (stdoutput
, bfin_flags
);
442 /* Set the default machine type. */
443 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_bfin
, 0))
444 as_warn (_("Could not set architecture and machine."));
446 /* Ensure that lines can begin with '(', for multiple
447 register stack pops. */
448 lex_type
['('] = LEX_BEGIN_NAME
;
451 record_alignment (text_section
, 2);
452 record_alignment (data_section
, 2);
453 record_alignment (bss_section
, 2);
457 obstack_init (&mempool
);
460 extern int debug_codeselection
;
461 debug_codeselection
= 1;
467 /* Perform the main parsing, and assembly of the input here. Also,
468 call the required routines for alignment and fixups here.
469 This is called for every line that contains real assembly code. */
472 md_assemble (char *line
)
476 struct bfin_insn
*tmp_insn
;
478 static size_t buffer_len
= 0;
479 static char *current_inputline
;
483 if (len
+ 2 > buffer_len
)
485 buffer_len
= len
+ 40;
486 current_inputline
= XRESIZEVEC (char, current_inputline
, buffer_len
);
488 memcpy (current_inputline
, line
, len
);
489 current_inputline
[len
] = ';';
490 current_inputline
[len
+ 1] = '\0';
492 state
= parse (current_inputline
);
493 if (state
== NO_INSN_GENERATED
)
496 for (insn_size
= 0, tmp_insn
= insn
; tmp_insn
; tmp_insn
= tmp_insn
->next
)
497 if (!tmp_insn
->reloc
|| !tmp_insn
->exp
->symbol
)
501 toP
= frag_more (insn_size
);
503 last_insn_size
= insn_size
;
510 if (insn
->reloc
&& insn
->exp
->symbol
)
512 char *prev_toP
= toP
- 2;
515 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
516 case BFD_RELOC_24_PCREL
:
517 case BFD_RELOC_BFIN_16_LOW
:
518 case BFD_RELOC_BFIN_16_HIGH
:
525 /* Following if condition checks for the arithmetic relocations.
526 If the case then it doesn't required to generate the code.
527 It has been assumed that, their ID will be contiguous. */
528 if ((BFD_ARELOC_BFIN_PUSH
<= insn
->reloc
529 && BFD_ARELOC_BFIN_COMP
>= insn
->reloc
)
530 || insn
->reloc
== BFD_RELOC_BFIN_16_IMM
)
534 if (insn
->reloc
== BFD_ARELOC_BFIN_CONST
535 || insn
->reloc
== BFD_ARELOC_BFIN_PUSH
)
539 (prev_toP
- frag_now
->fr_literal
),
540 size
, insn
->exp
->symbol
, insn
->exp
->value
,
541 insn
->pcrel
, insn
->reloc
);
545 md_number_to_chars (toP
, insn
->value
, 2);
551 printf (" %02x%02x", ((unsigned char *) &insn
->value
)[0],
552 ((unsigned char *) &insn
->value
)[1]);
558 dwarf2_emit_insn (insn_size
);
561 while (*line
++ != '\0')
563 bump_line_counters ();
566 /* Parse one line of instructions, and generate opcode for it.
567 To parse the line, YACC and LEX are used, because the instruction set
568 syntax doesn't confirm to the AT&T assembly syntax.
569 To call a YACC & LEX generated parser, we must provide the input via
570 a FILE stream, otherwise stdin is used by default. Below the input
571 to the function will be put into a temporary file, then the generated
572 parser uses the temporary file for parsing. */
578 YY_BUFFER_STATE buffstate
;
580 buffstate
= yy_scan_string (line
);
582 /* our lex requires setting the start state to keyword
583 every line as the first word may be a keyword.
584 Fixes a bug where we could not have keywords as labels. */
587 /* Call yyparse here. */
589 if (state
== SEMANTIC_ERROR
)
591 as_bad (_("Parse failed."));
595 yy_delete_buffer (buffstate
);
599 /* We need to handle various expressions properly.
600 Such as, [SP--] = 34, concerned by md_assemble(). */
603 md_operand (expressionS
* expressionP
)
605 if (*input_line_pointer
== '[')
607 as_tsktsk ("We found a '['!");
608 input_line_pointer
++;
609 expression (expressionP
);
613 /* Handle undefined symbols. */
615 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
617 return (symbolS
*) 0;
621 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
622 segT segment ATTRIBUTE_UNUSED
)
627 /* Convert from target byte order to host byte order. */
630 md_chars_to_number (char *val
, int n
)
634 for (retval
= 0; n
--;)
643 md_apply_fix (fixS
*fixP
, valueT
*valueP
, segT seg ATTRIBUTE_UNUSED
)
645 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
647 long value
= *valueP
;
650 switch (fixP
->fx_r_type
)
652 case BFD_RELOC_BFIN_GOT
:
653 case BFD_RELOC_BFIN_GOT17M4
:
654 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
655 fixP
->fx_no_overflow
= 1;
656 newval
= md_chars_to_number (where
, 2);
657 newval
|= 0x0 & 0x7f;
658 md_number_to_chars (where
, newval
, 2);
661 case BFD_RELOC_BFIN_10_PCREL
:
664 if (value
< -1024 || value
> 1022)
665 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
666 _("pcrel too far BFD_RELOC_BFIN_10"));
668 /* 11 bit offset even numbered, so we remove right bit. */
670 newval
= md_chars_to_number (where
, 2);
671 newval
|= value
& 0x03ff;
672 md_number_to_chars (where
, newval
, 2);
675 case BFD_RELOC_BFIN_12_PCREL_JUMP
:
676 case BFD_RELOC_BFIN_12_PCREL_JUMP_S
:
677 case BFD_RELOC_12_PCREL
:
681 if (value
< -4096 || value
> 4094)
682 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_12"));
683 /* 13 bit offset even numbered, so we remove right bit. */
685 newval
= md_chars_to_number (where
, 2);
686 newval
|= value
& 0xfff;
687 md_number_to_chars (where
, newval
, 2);
690 case BFD_RELOC_BFIN_16_LOW
:
691 case BFD_RELOC_BFIN_16_HIGH
:
692 fixP
->fx_done
= false;
695 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
696 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
697 case BFD_RELOC_24_PCREL
:
701 if (value
< -16777216 || value
> 16777214)
702 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_24"));
704 /* 25 bit offset even numbered, so we remove right bit. */
708 md_number_to_chars (where
- 2, value
>> 16, 1);
709 md_number_to_chars (where
, value
, 1);
710 md_number_to_chars (where
+ 1, value
>> 8, 1);
713 case BFD_RELOC_BFIN_5_PCREL
: /* LSETUP (a, b) : "a" */
716 if (value
< 4 || value
> 30)
717 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_5"));
719 newval
= md_chars_to_number (where
, 1);
720 newval
= (newval
& 0xf0) | (value
& 0xf);
721 md_number_to_chars (where
, newval
, 1);
724 case BFD_RELOC_BFIN_11_PCREL
: /* LSETUP (a, b) : "b" */
728 if (value
< 4 || value
> 2046)
729 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_11_PCREL"));
730 /* 11 bit unsigned even, so we remove right bit. */
732 newval
= md_chars_to_number (where
, 2);
733 newval
|= value
& 0x03ff;
734 md_number_to_chars (where
, newval
, 2);
738 if (value
< -0x80 || value
>= 0x7f)
739 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("rel too far BFD_RELOC_8"));
740 md_number_to_chars (where
, value
, 1);
743 case BFD_RELOC_BFIN_16_IMM
:
745 if (value
< -0x8000 || value
>= 0x7fff)
746 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("rel too far BFD_RELOC_16"));
747 md_number_to_chars (where
, value
, 2);
751 md_number_to_chars (where
, value
, 4);
754 case BFD_RELOC_BFIN_PLTPC
:
755 md_number_to_chars (where
, value
, 2);
758 case BFD_RELOC_BFIN_FUNCDESC
:
759 case BFD_RELOC_VTABLE_INHERIT
:
760 case BFD_RELOC_VTABLE_ENTRY
:
761 fixP
->fx_done
= false;
765 if ((BFD_ARELOC_BFIN_PUSH
> fixP
->fx_r_type
) || (BFD_ARELOC_BFIN_COMP
< fixP
->fx_r_type
))
767 fprintf (stderr
, "Relocation %d not handled in gas." " Contact support.\n", fixP
->fx_r_type
);
773 fixP
->fx_done
= true;
777 /* Round up a section size to the appropriate boundary. */
779 md_section_align (segT segment
, valueT size
)
781 int boundary
= bfd_section_alignment (segment
);
782 return ((size
+ (1 << boundary
) - 1) & -(1 << boundary
));
787 md_atof (int type
, char * litP
, int * sizeP
)
789 return ieee_md_atof (type
, litP
, sizeP
, false);
793 /* If while processing a fixup, a reloc really needs to be created
794 then it is done here. */
797 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixp
)
801 reloc
= XNEW (arelent
);
802 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
803 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
804 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
806 reloc
->addend
= fixp
->fx_offset
;
807 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
809 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
811 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
812 /* xgettext:c-format. */
813 _("reloc %d not supported by object file format"),
814 (int) fixp
->fx_r_type
);
824 /* The location from which a PC relative jump should be calculated,
825 given a PC relative reloc. */
828 md_pcrel_from_section (fixS
*fixP
, segT sec
)
830 if (fixP
->fx_addsy
!= (symbolS
*) NULL
831 && (!S_IS_DEFINED (fixP
->fx_addsy
)
832 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
834 /* The symbol is undefined (or is defined but not in this section).
835 Let the linker figure it out. */
838 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
841 /* Return true if the fix can be handled by GAS, false if it must
842 be passed through to the linker. */
845 bfin_fix_adjustable (fixS
*fixP
)
847 switch (fixP
->fx_r_type
)
849 /* Adjust_reloc_syms doesn't know about the GOT. */
850 case BFD_RELOC_BFIN_GOT
:
851 case BFD_RELOC_BFIN_PLTPC
:
852 /* We need the symbol name for the VTABLE entries. */
853 case BFD_RELOC_VTABLE_INHERIT
:
854 case BFD_RELOC_VTABLE_ENTRY
:
862 /* Special extra functions that help bfin-parse.y perform its job. */
864 struct obstack mempool
;
867 conscode (INSTR_T head
, INSTR_T tail
)
876 conctcode (INSTR_T head
, INSTR_T tail
)
878 INSTR_T temp
= (head
);
889 note_reloc (INSTR_T code
, Expr_Node
* symbol
, int reloc
, int pcrel
)
891 /* Assert that the symbol is not an operator. */
892 gas_assert (symbol
->type
== Expr_Node_Reloc
);
894 return note_reloc1 (code
, symbol
->value
.s_value
, reloc
, pcrel
);
899 note_reloc1 (INSTR_T code
, const char *symbol
, int reloc
, int pcrel
)
902 code
->exp
= mkexpr (0, symbol_find_or_make (symbol
));
908 note_reloc2 (INSTR_T code
, const char *symbol
, int reloc
, int value
, int pcrel
)
911 code
->exp
= mkexpr (value
, symbol_find_or_make (symbol
));
917 gencode (unsigned long x
)
919 INSTR_T cell
= XOBNEW (&mempool
, struct bfin_insn
);
920 memset (cell
, 0, sizeof (struct bfin_insn
));
932 return obstack_alloc (&mempool
, n
);
936 Expr_Node_Create (Expr_Node_Type type
,
937 Expr_Node_Value value
,
938 Expr_Node
*Left_Child
,
939 Expr_Node
*Right_Child
)
943 Expr_Node
*node
= (Expr_Node
*) allocate (sizeof (Expr_Node
));
946 node
->Left_Child
= Left_Child
;
947 node
->Right_Child
= Right_Child
;
951 static const char *con
= ".__constant";
952 static const char *op
= ".__operator";
953 static INSTR_T
Expr_Node_Gen_Reloc_R (Expr_Node
* head
);
954 INSTR_T
Expr_Node_Gen_Reloc (Expr_Node
*head
, int parent_reloc
);
957 Expr_Node_Gen_Reloc (Expr_Node
* head
, int parent_reloc
)
959 /* Top level relocation expression generator VDSP style.
960 If the relocation is just by itself, generate one item
961 else generate this convoluted expression. */
963 INSTR_T note
= NULL_CODE
;
964 INSTR_T note1
= NULL_CODE
;
965 int pcrel
= 1; /* Is the parent reloc pc-relative?
966 This calculation here and HOWTO should match. */
970 /* If it's 32 bit quantity then 16bit code needs to be added. */
973 if (head
->type
== Expr_Node_Constant
)
975 /* If note1 is not null code, we have to generate a right
976 aligned value for the constant. Otherwise the reloc is
977 a part of the basic command and the yacc file
979 value
= head
->value
.i_value
;
981 switch (parent_reloc
)
983 /* Some relocations will need to allocate extra words. */
984 case BFD_RELOC_BFIN_16_IMM
:
985 case BFD_RELOC_BFIN_16_LOW
:
986 case BFD_RELOC_BFIN_16_HIGH
:
987 note1
= conscode (gencode (value
), NULL_CODE
);
990 case BFD_RELOC_BFIN_PLTPC
:
991 note1
= conscode (gencode (value
), NULL_CODE
);
995 case BFD_RELOC_BFIN_GOT
:
996 case BFD_RELOC_BFIN_GOT17M4
:
997 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
998 note1
= conscode (gencode (value
), NULL_CODE
);
1001 case BFD_RELOC_24_PCREL
:
1002 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
1003 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
1004 /* These offsets are even numbered pcrel. */
1005 note1
= conscode (gencode (value
>> 1), NULL_CODE
);
1011 if (head
->type
== Expr_Node_Constant
)
1013 else if (head
->type
== Expr_Node_Reloc
)
1015 note
= note_reloc1 (gencode (0), head
->value
.s_value
, parent_reloc
, pcrel
);
1016 if (note1
!= NULL_CODE
)
1017 note
= conscode (note1
, note
);
1019 else if (head
->type
== Expr_Node_Binop
1020 && (head
->value
.op_value
== Expr_Op_Type_Add
1021 || head
->value
.op_value
== Expr_Op_Type_Sub
)
1022 && head
->Left_Child
->type
== Expr_Node_Reloc
1023 && head
->Right_Child
->type
== Expr_Node_Constant
)
1025 int val
= head
->Right_Child
->value
.i_value
;
1026 if (head
->value
.op_value
== Expr_Op_Type_Sub
)
1028 note
= conscode (note_reloc2 (gencode (0), head
->Left_Child
->value
.s_value
,
1029 parent_reloc
, val
, 0),
1031 if (note1
!= NULL_CODE
)
1032 note
= conscode (note1
, note
);
1036 /* Call the recursive function. */
1037 note
= note_reloc1 (gencode (0), op
, parent_reloc
, pcrel
);
1038 if (note1
!= NULL_CODE
)
1039 note
= conscode (note1
, note
);
1040 note
= conctcode (Expr_Node_Gen_Reloc_R (head
), note
);
1046 Expr_Node_Gen_Reloc_R (Expr_Node
* head
)
1054 case Expr_Node_Constant
:
1055 note
= conscode (note_reloc2 (gencode (0), con
, BFD_ARELOC_BFIN_CONST
, head
->value
.i_value
, 0), NULL_CODE
);
1057 case Expr_Node_Reloc
:
1058 note
= conscode (note_reloc (gencode (0), head
, BFD_ARELOC_BFIN_PUSH
, 0), NULL_CODE
);
1060 case Expr_Node_Binop
:
1061 note1
= conctcode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), Expr_Node_Gen_Reloc_R (head
->Right_Child
));
1062 switch (head
->value
.op_value
)
1064 case Expr_Op_Type_Add
:
1065 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_ADD
, 0), NULL_CODE
));
1067 case Expr_Op_Type_Sub
:
1068 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_SUB
, 0), NULL_CODE
));
1070 case Expr_Op_Type_Mult
:
1071 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MULT
, 0), NULL_CODE
));
1073 case Expr_Op_Type_Div
:
1074 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_DIV
, 0), NULL_CODE
));
1076 case Expr_Op_Type_Mod
:
1077 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MOD
, 0), NULL_CODE
));
1079 case Expr_Op_Type_Lshift
:
1080 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LSHIFT
, 0), NULL_CODE
));
1082 case Expr_Op_Type_Rshift
:
1083 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_RSHIFT
, 0), NULL_CODE
));
1085 case Expr_Op_Type_BAND
:
1086 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_AND
, 0), NULL_CODE
));
1088 case Expr_Op_Type_BOR
:
1089 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_OR
, 0), NULL_CODE
));
1091 case Expr_Op_Type_BXOR
:
1092 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_XOR
, 0), NULL_CODE
));
1094 case Expr_Op_Type_LAND
:
1095 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LAND
, 0), NULL_CODE
));
1097 case Expr_Op_Type_LOR
:
1098 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LOR
, 0), NULL_CODE
));
1101 fprintf (stderr
, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1106 case Expr_Node_Unop
:
1107 note1
= conscode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), NULL_CODE
);
1108 switch (head
->value
.op_value
)
1110 case Expr_Op_Type_NEG
:
1111 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_NEG
, 0), NULL_CODE
));
1113 case Expr_Op_Type_COMP
:
1114 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_COMP
, 0), NULL_CODE
));
1117 fprintf (stderr
, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1121 fprintf (stderr
, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__
, __LINE__
);
1126 /* Blackfin opcode generation. */
1128 /* These functions are called by the generated parser
1129 (from bfin-parse.y), the register type classification
1130 happens in bfin-lex.l. */
1132 #include "bfin-aux.h"
1133 #include "opcode/bfin.h"
1135 #define INIT(t) t c_code = init_##t
1136 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1137 #define ASSIGNF(x,f) c_code.opcode |= ((x & c_code.mask_##f)<<c_code.bits_##f)
1138 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1140 #define HI(x) ((x >> 16) & 0xffff)
1141 #define LO(x) ((x ) & 0xffff)
1143 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1145 #define GEN_OPCODE32() \
1146 conscode (gencode (HI (c_code.opcode)), \
1147 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1149 #define GEN_OPCODE16() \
1150 conscode (gencode (c_code.opcode), NULL_CODE)
1153 /* 32 BIT INSTRUCTIONS. */
1156 /* DSP32 instruction generation. */
1159 bfin_gen_dsp32mac (int op1
, int MM
, int mmod
, int w1
, int P
,
1160 int h01
, int h11
, int h00
, int h10
, int op0
,
1161 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1177 /* If we have full reg assignments, mask out LSB to encode
1178 single or simultaneous even/odd register moves. */
1188 return GEN_OPCODE32 ();
1192 bfin_gen_dsp32mult (int op1
, int MM
, int mmod
, int w1
, int P
,
1193 int h01
, int h11
, int h00
, int h10
, int op0
,
1194 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1219 return GEN_OPCODE32 ();
1223 bfin_gen_dsp32alu (int HL
, int aopcde
, int aop
, int s
, int x
,
1224 REG_T dst0
, REG_T dst1
, REG_T src0
, REG_T src1
)
1238 return GEN_OPCODE32 ();
1242 bfin_gen_dsp32shift (int sopcde
, REG_T dst0
, REG_T src0
,
1243 REG_T src1
, int sop
, int HLs
)
1255 return GEN_OPCODE32 ();
1259 bfin_gen_dsp32shiftimm (int sopcde
, REG_T dst0
, int immag
,
1260 REG_T src1
, int sop
, int HLs
)
1262 INIT (DSP32ShiftImm
);
1272 return GEN_OPCODE32 ();
1278 bfin_gen_loopsetup (Expr_Node
* psoffset
, REG_T c
, int rop
,
1279 Expr_Node
* peoffset
, REG_T reg
)
1281 int soffset
, eoffset
;
1284 soffset
= (EXPR_VALUE (psoffset
) >> 1);
1286 eoffset
= (EXPR_VALUE (peoffset
) >> 1);
1293 conscode (gencode (HI (c_code
.opcode
)),
1294 conctcode (Expr_Node_Gen_Reloc (psoffset
, BFD_RELOC_BFIN_5_PCREL
),
1295 conctcode (gencode (LO (c_code
.opcode
)), Expr_Node_Gen_Reloc (peoffset
, BFD_RELOC_BFIN_11_PCREL
))));
1302 bfin_gen_calla (Expr_Node
* addr
, int S
)
1310 case 0 : rel
= BFD_RELOC_BFIN_24_PCREL_JUMP_L
; break;
1311 case 1 : rel
= BFD_RELOC_24_PCREL
; break;
1312 case 2 : rel
= BFD_RELOC_BFIN_PLTPC
; break;
1318 val
= EXPR_VALUE (addr
) >> 1;
1319 high_val
= val
>> 16;
1321 return conscode (gencode (HI (c_code
.opcode
) | (high_val
& 0xff)),
1322 Expr_Node_Gen_Reloc (addr
, rel
));
1326 bfin_gen_linkage (int R
, int framesize
)
1333 return GEN_OPCODE32 ();
1337 /* Load and Store. */
1340 bfin_gen_ldimmhalf (REG_T reg
, int H
, int S
, int Z
, Expr_Node
* phword
, int rel
)
1343 unsigned val
= EXPR_VALUE (phword
);
1351 grp
= (GROUP (reg
));
1355 return conscode (gencode (HI (c_code
.opcode
)), Expr_Node_Gen_Reloc (phword
, BFD_RELOC_BFIN_16_IMM
));
1359 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
));
1366 return GEN_OPCODE32 ();
1370 bfin_gen_ldstidxi (REG_T ptr
, REG_T reg
, int W
, int sz
, int Z
, Expr_Node
* poffset
)
1374 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1376 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1387 if (poffset
->type
!= Expr_Node_Constant
)
1389 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1390 /* distinguish between R0 = [P5 + symbol@GOT] and
1391 P5 = [P5 + _current_shared_library_p5_offset_]
1393 if (poffset
->type
== Expr_Node_Reloc
1394 && !strcmp (poffset
->value
.s_value
,
1395 "_current_shared_library_p5_offset_"))
1397 return conscode (gencode (HI (c_code
.opcode
)),
1398 Expr_Node_Gen_Reloc(poffset
, BFD_RELOC_16
));
1400 else if (poffset
->type
!= Expr_Node_GOT_Reloc
)
1403 return conscode (gencode (HI (c_code
.opcode
)),
1404 Expr_Node_Gen_Reloc(poffset
->Left_Child
,
1405 poffset
->value
.i_value
));
1411 { /* load/store access size */
1412 case 0: /* 32 bit */
1413 value
= EXPR_VALUE (poffset
) >> 2;
1415 case 1: /* 16 bit */
1416 value
= EXPR_VALUE (poffset
) >> 1;
1419 value
= EXPR_VALUE (poffset
);
1425 offset
= (value
& 0xffff);
1427 return GEN_OPCODE32 ();
1433 bfin_gen_ldst (REG_T ptr
, REG_T reg
, int aop
, int sz
, int Z
, int W
)
1437 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1439 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1450 return GEN_OPCODE16 ();
1454 bfin_gen_ldstii (REG_T ptr
, REG_T reg
, Expr_Node
* poffset
, int W
, int opc
)
1460 if (!IS_PREG (*ptr
))
1462 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1470 value
= EXPR_VALUE (poffset
) >> 1;
1474 value
= EXPR_VALUE (poffset
) >> 2;
1486 return GEN_OPCODE16 ();
1490 bfin_gen_ldstiifp (REG_T sreg
, Expr_Node
* poffset
, int W
)
1492 /* Set bit 4 if it's a Preg. */
1493 int reg
= (sreg
->regno
& CODE_MASK
) | (IS_PREG (*sreg
) ? 0x8 : 0x0);
1494 int offset
= ((~(EXPR_VALUE (poffset
) >> 2)) & 0x1f) + 1;
1500 return GEN_OPCODE16 ();
1504 bfin_gen_ldstpmod (REG_T ptr
, REG_T reg
, int aop
, int W
, REG_T idx
)
1514 return GEN_OPCODE16 ();
1518 bfin_gen_dspldst (REG_T i
, REG_T reg
, int aop
, int W
, int m
)
1528 return GEN_OPCODE16 ();
1532 bfin_gen_logi2op (int opc
, int src
, int dst
)
1540 return GEN_OPCODE16 ();
1544 bfin_gen_brcc (int T
, int B
, Expr_Node
* poffset
)
1551 offset
= ((EXPR_VALUE (poffset
) >> 1));
1553 return conscode (gencode (c_code
.opcode
), Expr_Node_Gen_Reloc (poffset
, BFD_RELOC_BFIN_10_PCREL
));
1557 bfin_gen_ujump (Expr_Node
* poffset
)
1562 offset
= ((EXPR_VALUE (poffset
) >> 1));
1565 return conscode (gencode (c_code
.opcode
),
1566 Expr_Node_Gen_Reloc (
1567 poffset
, BFD_RELOC_BFIN_12_PCREL_JUMP_S
));
1571 bfin_gen_alu2op (REG_T dst
, REG_T src
, int opc
)
1579 return GEN_OPCODE16 ();
1583 bfin_gen_compi2opd (REG_T dst
, int src
, int opc
)
1591 return GEN_OPCODE16 ();
1595 bfin_gen_compi2opp (REG_T dst
, int src
, int opc
)
1603 return GEN_OPCODE16 ();
1607 bfin_gen_dagmodik (REG_T i
, int opc
)
1614 return GEN_OPCODE16 ();
1618 bfin_gen_dagmodim (REG_T i
, REG_T m
, int opc
, int br
)
1627 return GEN_OPCODE16 ();
1631 bfin_gen_ptr2op (REG_T dst
, REG_T src
, int opc
)
1639 return GEN_OPCODE16 ();
1643 bfin_gen_comp3op (REG_T src0
, REG_T src1
, REG_T dst
, int opc
)
1652 return GEN_OPCODE16 ();
1656 bfin_gen_ccflag (REG_T x
, int y
, int opc
, int I
, int G
)
1666 return GEN_OPCODE16 ();
1670 bfin_gen_ccmv (REG_T src
, REG_T dst
, int T
)
1683 return GEN_OPCODE16 ();
1687 bfin_gen_cc2stat (int cbit
, int opc
, int D
)
1695 return GEN_OPCODE16 ();
1699 bfin_gen_regmv (REG_T src
, REG_T dst
)
1712 return GEN_OPCODE16 ();
1716 bfin_gen_cc2dreg (int opc
, REG_T reg
)
1723 return GEN_OPCODE16 ();
1727 bfin_gen_progctrl (int prgfunc
, int poprnd
)
1734 return GEN_OPCODE16 ();
1738 bfin_gen_cactrl (REG_T reg
, int a
, int opc
)
1746 return GEN_OPCODE16 ();
1750 bfin_gen_pushpopmultiple (int dr
, int pr
, int d
, int p
, int W
)
1752 INIT (PushPopMultiple
);
1760 return GEN_OPCODE16 ();
1764 bfin_gen_pushpopreg (REG_T reg
, int W
)
1770 grp
= (GROUP (reg
));
1774 return GEN_OPCODE16 ();
1777 /* Pseudo Debugging Support. */
1780 bfin_gen_pseudodbg (int fn
, int reg
, int grp
)
1788 return GEN_OPCODE16 ();
1792 bfin_gen_pseudodbg_assert (int dbgop
, REG_T regtest
, int expected
)
1795 INIT (PseudoDbg_Assert
);
1799 grp
= GROUP (regtest
);
1803 return GEN_OPCODE32 ();
1807 bfin_gen_pseudochr (int ch
)
1813 return GEN_OPCODE16 ();
1816 /* Multiple instruction generation. */
1819 bfin_gen_multi_instr (INSTR_T dsp32
, INSTR_T dsp16_grp1
, INSTR_T dsp16_grp2
)
1823 /* If it's a 0, convert into MNOP. */
1827 SET_MULTI_INSTRUCTION_BIT (dsp32
);
1831 dsp32
= gencode (0xc803);
1832 walk
= gencode (0x1800);
1838 dsp16_grp1
= gencode (0x0000);
1843 dsp16_grp2
= gencode (0x0000);
1846 walk
->next
= dsp16_grp1
;
1847 dsp16_grp1
->next
= dsp16_grp2
;
1848 dsp16_grp2
->next
= NULL_CODE
;
1854 bfin_gen_loop (Expr_Node
*exp
, REG_T reg
, int rop
, REG_T preg
)
1856 const char *loopsym
;
1857 char *lbeginsym
, *lendsym
;
1858 Expr_Node_Value lbeginval
, lendval
;
1859 Expr_Node
*lbegin
, *lend
;
1862 loopsym
= exp
->value
.s_value
;
1863 lbeginsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__BEGIN") + 5);
1864 lendsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__END") + 5);
1869 strcat (lbeginsym
, "L$L$");
1870 strcat (lbeginsym
, loopsym
);
1871 strcat (lbeginsym
, "__BEGIN");
1873 strcat (lendsym
, "L$L$");
1874 strcat (lendsym
, loopsym
);
1875 strcat (lendsym
, "__END");
1877 lbeginval
.s_value
= lbeginsym
;
1878 lendval
.s_value
= lendsym
;
1880 lbegin
= Expr_Node_Create (Expr_Node_Reloc
, lbeginval
, NULL
, NULL
);
1881 lend
= Expr_Node_Create (Expr_Node_Reloc
, lendval
, NULL
, NULL
);
1883 sym
= symbol_find(loopsym
);
1884 if (!S_IS_LOCAL (sym
) || (S_IS_LOCAL (sym
) && !symbol_used_p (sym
)))
1885 symbol_remove (sym
, &symbol_rootP
, &symbol_lastP
);
1887 return bfin_gen_loopsetup (lbegin
, reg
, rop
, lend
, preg
);
1891 bfin_loop_attempt_create_label (Expr_Node
*exp
, int is_begin
)
1894 name
= fb_label_name (exp
->value
.i_value
, is_begin
);
1895 exp
->value
.s_value
= xstrdup (name
);
1896 exp
->type
= Expr_Node_Reloc
;
1900 bfin_loop_beginend (Expr_Node
*exp
, int begin
)
1902 const char *loopsym
;
1905 const char *suffix
= begin
? "__BEGIN" : "__END";
1907 loopsym
= exp
->value
.s_value
;
1908 label_name
= (char *) xmalloc (strlen (loopsym
) + strlen (suffix
) + 5);
1912 strcat (label_name
, "L$L$");
1913 strcat (label_name
, loopsym
);
1914 strcat (label_name
, suffix
);
1916 linelabel
= colon (label_name
);
1918 /* LOOP_END follows the last instruction in the loop.
1919 Adjust label address. */
1921 *symbol_X_add_number (linelabel
) -= last_insn_size
;
1927 bfin_eol_in_insn (char *line
)
1929 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1936 /* A semi-colon followed by a newline is always the end of a line. */
1937 if (line
[-1] == ';')
1940 if (line
[-1] == '|')
1943 /* If the || is on the next line, there might be leading whitespace. */
1945 while (*temp
== ' ' || *temp
== '\t') temp
++;
1954 bfin_start_label (char *s
)
1958 if (*s
== '(' || *s
== '[')
1967 bfin_force_relocation (struct fix
*fixp
)
1969 if (fixp
->fx_r_type
==BFD_RELOC_BFIN_16_LOW
1970 || fixp
->fx_r_type
== BFD_RELOC_BFIN_16_HIGH
)
1973 return generic_force_reloc (fixp
);
1976 /* This is a stripped down version of the disassembler. The only thing it
1977 does is return a mask of registers modified by an instruction. Only
1978 instructions that can occur in a parallel-issue bundle are handled, and
1979 only the registers that can cause a conflict are recorded. */
1981 #define DREG_MASK(n) (0x101 << (n))
1982 #define DREGH_MASK(n) (0x100 << (n))
1983 #define DREGL_MASK(n) (0x001 << (n))
1984 #define IREG_MASK(n) (1 << ((n) + 16))
1987 decode_ProgCtrl_0 (int iw0
)
1995 decode_LDSTpmod_0 (int iw0
)
1998 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
1999 | 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......|
2000 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2001 int W
= ((iw0
>> LDSTpmod_W_bits
) & LDSTpmod_W_mask
);
2002 int aop
= ((iw0
>> LDSTpmod_aop_bits
) & LDSTpmod_aop_mask
);
2003 int idx
= ((iw0
>> LDSTpmod_idx_bits
) & LDSTpmod_idx_mask
);
2004 int ptr
= ((iw0
>> LDSTpmod_ptr_bits
) & LDSTpmod_ptr_mask
);
2005 int reg
= ((iw0
>> LDSTpmod_reg_bits
) & LDSTpmod_reg_mask
);
2007 if (aop
== 1 && W
== 0 && idx
== ptr
)
2008 return DREGL_MASK (reg
);
2009 else if (aop
== 2 && W
== 0 && idx
== ptr
)
2010 return DREGH_MASK (reg
);
2011 else if (aop
== 1 && W
== 1 && idx
== ptr
)
2013 else if (aop
== 2 && W
== 1 && idx
== ptr
)
2015 else if (aop
== 0 && W
== 0)
2016 return DREG_MASK (reg
);
2017 else if (aop
== 1 && W
== 0)
2018 return DREGL_MASK (reg
);
2019 else if (aop
== 2 && W
== 0)
2020 return DREGH_MASK (reg
);
2021 else if (aop
== 3 && W
== 0)
2022 return DREG_MASK (reg
);
2023 else if (aop
== 3 && W
== 1)
2024 return DREG_MASK (reg
);
2025 else if (aop
== 0 && W
== 1)
2027 else if (aop
== 1 && W
== 1)
2029 else if (aop
== 2 && W
== 1)
2038 decode_dagMODim_0 (int iw0
)
2041 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2042 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....|
2043 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2044 int i
= ((iw0
>> DagMODim_i_bits
) & DagMODim_i_mask
);
2045 int opc
= ((iw0
>> DagMODim_op_bits
) & DagMODim_op_mask
);
2047 if (opc
== 0 || opc
== 1)
2048 return IREG_MASK (i
);
2056 decode_dagMODik_0 (int iw0
)
2059 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2060 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....|
2061 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2062 int i
= ((iw0
>> DagMODik_i_bits
) & DagMODik_i_mask
);
2063 return IREG_MASK (i
);
2068 decode_dspLDST_0 (int iw0
)
2071 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2072 | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......|
2073 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2074 int i
= ((iw0
>> DspLDST_i_bits
) & DspLDST_i_mask
);
2075 int m
= ((iw0
>> DspLDST_m_bits
) & DspLDST_m_mask
);
2076 int W
= ((iw0
>> DspLDST_W_bits
) & DspLDST_W_mask
);
2077 int aop
= ((iw0
>> DspLDST_aop_bits
) & DspLDST_aop_mask
);
2078 int reg
= ((iw0
>> DspLDST_reg_bits
) & DspLDST_reg_mask
);
2080 if (aop
== 0 && W
== 0 && m
== 0)
2081 return DREG_MASK (reg
) | IREG_MASK (i
);
2082 else if (aop
== 0 && W
== 0 && m
== 1)
2083 return DREGL_MASK (reg
) | IREG_MASK (i
);
2084 else if (aop
== 0 && W
== 0 && m
== 2)
2085 return DREGH_MASK (reg
) | IREG_MASK (i
);
2086 else if (aop
== 1 && W
== 0 && m
== 0)
2087 return DREG_MASK (reg
) | IREG_MASK (i
);
2088 else if (aop
== 1 && W
== 0 && m
== 1)
2089 return DREGL_MASK (reg
) | IREG_MASK (i
);
2090 else if (aop
== 1 && W
== 0 && m
== 2)
2091 return DREGH_MASK (reg
) | IREG_MASK (i
);
2092 else if (aop
== 2 && W
== 0 && m
== 0)
2093 return DREG_MASK (reg
);
2094 else if (aop
== 2 && W
== 0 && m
== 1)
2095 return DREGL_MASK (reg
);
2096 else if (aop
== 2 && W
== 0 && m
== 2)
2097 return DREGH_MASK (reg
);
2098 else if (aop
== 0 && W
== 1 && m
== 0)
2099 return IREG_MASK (i
);
2100 else if (aop
== 0 && W
== 1 && m
== 1)
2101 return IREG_MASK (i
);
2102 else if (aop
== 0 && W
== 1 && m
== 2)
2103 return IREG_MASK (i
);
2104 else if (aop
== 1 && W
== 1 && m
== 0)
2105 return IREG_MASK (i
);
2106 else if (aop
== 1 && W
== 1 && m
== 1)
2107 return IREG_MASK (i
);
2108 else if (aop
== 1 && W
== 1 && m
== 2)
2109 return IREG_MASK (i
);
2110 else if (aop
== 2 && W
== 1 && m
== 0)
2112 else if (aop
== 2 && W
== 1 && m
== 1)
2114 else if (aop
== 2 && W
== 1 && m
== 2)
2116 else if (aop
== 3 && W
== 0)
2117 return DREG_MASK (reg
) | IREG_MASK (i
);
2118 else if (aop
== 3 && W
== 1)
2119 return IREG_MASK (i
);
2126 decode_LDST_0 (int iw0
)
2129 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2130 | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......|
2131 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2132 int Z
= ((iw0
>> LDST_Z_bits
) & LDST_Z_mask
);
2133 int W
= ((iw0
>> LDST_W_bits
) & LDST_W_mask
);
2134 int sz
= ((iw0
>> LDST_sz_bits
) & LDST_sz_mask
);
2135 int aop
= ((iw0
>> LDST_aop_bits
) & LDST_aop_mask
);
2136 int reg
= ((iw0
>> LDST_reg_bits
) & LDST_reg_mask
);
2138 if (aop
== 0 && sz
== 0 && Z
== 0 && W
== 0)
2139 return DREG_MASK (reg
);
2140 else if (aop
== 0 && sz
== 0 && Z
== 1 && W
== 0)
2142 else if (aop
== 0 && sz
== 1 && Z
== 0 && W
== 0)
2143 return DREG_MASK (reg
);
2144 else if (aop
== 0 && sz
== 1 && Z
== 1 && W
== 0)
2145 return DREG_MASK (reg
);
2146 else if (aop
== 0 && sz
== 2 && Z
== 0 && W
== 0)
2147 return DREG_MASK (reg
);
2148 else if (aop
== 0 && sz
== 2 && Z
== 1 && W
== 0)
2149 return DREG_MASK (reg
);
2150 else if (aop
== 1 && sz
== 0 && Z
== 0 && W
== 0)
2151 return DREG_MASK (reg
);
2152 else if (aop
== 1 && sz
== 0 && Z
== 1 && W
== 0)
2154 else if (aop
== 1 && sz
== 1 && Z
== 0 && W
== 0)
2155 return DREG_MASK (reg
);
2156 else if (aop
== 1 && sz
== 1 && Z
== 1 && W
== 0)
2157 return DREG_MASK (reg
);
2158 else if (aop
== 1 && sz
== 2 && Z
== 0 && W
== 0)
2159 return DREG_MASK (reg
);
2160 else if (aop
== 1 && sz
== 2 && Z
== 1 && W
== 0)
2161 return DREG_MASK (reg
);
2162 else if (aop
== 2 && sz
== 0 && Z
== 0 && W
== 0)
2163 return DREG_MASK (reg
);
2164 else if (aop
== 2 && sz
== 0 && Z
== 1 && W
== 0)
2166 else if (aop
== 2 && sz
== 1 && Z
== 0 && W
== 0)
2167 return DREG_MASK (reg
);
2168 else if (aop
== 2 && sz
== 1 && Z
== 1 && W
== 0)
2169 return DREG_MASK (reg
);
2170 else if (aop
== 2 && sz
== 2 && Z
== 0 && W
== 0)
2171 return DREG_MASK (reg
);
2172 else if (aop
== 2 && sz
== 2 && Z
== 1 && W
== 0)
2173 return DREG_MASK (reg
);
2174 else if (aop
== 0 && sz
== 0 && Z
== 0 && W
== 1)
2176 else if (aop
== 0 && sz
== 0 && Z
== 1 && W
== 1)
2178 else if (aop
== 0 && sz
== 1 && Z
== 0 && W
== 1)
2180 else if (aop
== 0 && sz
== 2 && Z
== 0 && W
== 1)
2182 else if (aop
== 1 && sz
== 0 && Z
== 0 && W
== 1)
2184 else if (aop
== 1 && sz
== 0 && Z
== 1 && W
== 1)
2186 else if (aop
== 1 && sz
== 1 && Z
== 0 && W
== 1)
2188 else if (aop
== 1 && sz
== 2 && Z
== 0 && W
== 1)
2190 else if (aop
== 2 && sz
== 0 && Z
== 0 && W
== 1)
2192 else if (aop
== 2 && sz
== 0 && Z
== 1 && W
== 1)
2194 else if (aop
== 2 && sz
== 1 && Z
== 0 && W
== 1)
2196 else if (aop
== 2 && sz
== 2 && Z
== 0 && W
== 1)
2203 decode_LDSTiiFP_0 (int iw0
)
2206 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2207 | 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........|
2208 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2209 int reg
= ((iw0
>> LDSTiiFP_reg_bits
) & LDSTiiFP_reg_mask
);
2210 int W
= ((iw0
>> LDSTiiFP_W_bits
) & LDSTiiFP_W_mask
);
2213 return reg
< 8 ? DREG_MASK (reg
) : 0;
2219 decode_LDSTii_0 (int iw0
)
2222 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2223 | 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......|
2224 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2225 int reg
= ((iw0
>> LDSTii_reg_bit
) & LDSTii_reg_mask
);
2226 int opc
= ((iw0
>> LDSTii_op_bit
) & LDSTii_op_mask
);
2227 int W
= ((iw0
>> LDSTii_W_bit
) & LDSTii_W_mask
);
2229 if (W
== 0 && opc
!= 3)
2230 return DREG_MASK (reg
);
2231 else if (W
== 0 && opc
== 3)
2233 else if (W
== 1 && opc
== 0)
2235 else if (W
== 1 && opc
== 1)
2237 else if (W
== 1 && opc
== 3)
2244 decode_dsp32mac_0 (int iw0
, int iw1
)
2248 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2249 | 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...|
2250 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2251 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2252 int op1
= ((iw0
>> (DSP32Mac_op1_bits
- 16)) & DSP32Mac_op1_mask
);
2253 int w1
= ((iw0
>> (DSP32Mac_w1_bits
- 16)) & DSP32Mac_w1_mask
);
2254 int P
= ((iw0
>> (DSP32Mac_p_bits
- 16)) & DSP32Mac_p_mask
);
2255 int mmod
= ((iw0
>> (DSP32Mac_mmod_bits
- 16)) & DSP32Mac_mmod_mask
);
2256 int w0
= ((iw1
>> DSP32Mac_w0_bits
) & DSP32Mac_w0_mask
);
2257 int MM
= ((iw1
>> DSP32Mac_MM_bits
) & DSP32Mac_MM_mask
);
2258 int dst
= ((iw1
>> DSP32Mac_dst_bits
) & DSP32Mac_dst_mask
);
2259 int op0
= ((iw1
>> DSP32Mac_op0_bits
) & DSP32Mac_op0_mask
);
2261 if (w0
== 0 && w1
== 0 && op1
== 3 && op0
== 3)
2267 if ((w1
|| w0
) && mmod
== M_W32
)
2270 if (((1 << mmod
) & (P
? 0x131b : 0x1b5f)) == 0)
2273 if (w1
== 1 || op1
!= 3)
2278 return DREG_MASK (dst
+ 1);
2280 return DREGH_MASK (dst
);
2284 if (w0
== 1 || op0
!= 3)
2289 return DREG_MASK (dst
);
2291 return DREGL_MASK (dst
);
2299 decode_dsp32mult_0 (int iw0
, int iw1
)
2302 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2303 | 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...|
2304 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2305 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2306 int w1
= ((iw0
>> (DSP32Mac_w1_bits
- 16)) & DSP32Mac_w1_mask
);
2307 int P
= ((iw0
>> (DSP32Mac_p_bits
- 16)) & DSP32Mac_p_mask
);
2308 int mmod
= ((iw0
>> (DSP32Mac_mmod_bits
- 16)) & DSP32Mac_mmod_mask
);
2309 int w0
= ((iw1
>> DSP32Mac_w0_bits
) & DSP32Mac_w0_mask
);
2310 int dst
= ((iw1
>> DSP32Mac_dst_bits
) & DSP32Mac_dst_mask
);
2313 if (w1
== 0 && w0
== 0)
2316 if (((1 << mmod
) & (P
? 0x313 : 0x1b57)) == 0)
2322 return DREG_MASK (dst
| 1);
2324 return DREGH_MASK (dst
);
2330 return DREG_MASK (dst
);
2332 return DREGL_MASK (dst
);
2339 decode_dsp32alu_0 (int iw0
, int iw1
)
2342 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2343 | 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............|
2344 |.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......|
2345 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2346 int s
= ((iw1
>> DSP32Alu_s_bits
) & DSP32Alu_s_mask
);
2347 int x
= ((iw1
>> DSP32Alu_x_bits
) & DSP32Alu_x_mask
);
2348 int aop
= ((iw1
>> DSP32Alu_aop_bits
) & DSP32Alu_aop_mask
);
2349 int dst0
= ((iw1
>> DSP32Alu_dst0_bits
) & DSP32Alu_dst0_mask
);
2350 int dst1
= ((iw1
>> DSP32Alu_dst1_bits
) & DSP32Alu_dst1_mask
);
2351 int HL
= ((iw0
>> (DSP32Alu_HL_bits
- 16)) & DSP32Alu_HL_mask
);
2352 int aopcde
= ((iw0
>> (DSP32Alu_aopcde_bits
- 16)) & DSP32Alu_aopcde_mask
);
2354 if (aop
== 0 && aopcde
== 9 && s
== 0)
2356 else if (aop
== 2 && aopcde
== 9 && HL
== 0 && s
== 0)
2358 else if (aop
>= x
* 2 && aopcde
== 5)
2359 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2360 else if (HL
== 0 && aopcde
== 2)
2361 return DREGL_MASK (dst0
);
2362 else if (HL
== 1 && aopcde
== 2)
2363 return DREGH_MASK (dst0
);
2364 else if (HL
== 0 && aopcde
== 3)
2365 return DREGL_MASK (dst0
);
2366 else if (HL
== 1 && aopcde
== 3)
2367 return DREGH_MASK (dst0
);
2369 else if (aop
== 0 && aopcde
== 9 && s
== 1)
2371 else if (aop
== 1 && aopcde
== 9 && s
== 0)
2373 else if (aop
== 2 && aopcde
== 9 && s
== 1)
2375 else if (aop
== 3 && aopcde
== 9 && s
== 0)
2377 else if (aopcde
== 8)
2379 else if (aop
== 0 && aopcde
== 11)
2380 return DREG_MASK (dst0
);
2381 else if (aop
== 1 && aopcde
== 11)
2382 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2383 else if (aopcde
== 11)
2385 else if (aopcde
== 22)
2386 return DREG_MASK (dst0
);
2388 else if ((aop
== 0 || aop
== 1) && aopcde
== 14)
2390 else if (aop
== 3 && HL
== 0 && aopcde
== 14)
2393 else if (aop
== 3 && HL
== 0 && aopcde
== 15)
2394 return DREG_MASK (dst0
);
2396 else if (aop
== 1 && aopcde
== 16)
2399 else if (aop
== 0 && aopcde
== 16)
2402 else if (aop
== 3 && HL
== 0 && aopcde
== 16)
2405 else if (aop
== 3 && HL
== 0 && aopcde
== 7)
2406 return DREG_MASK (dst0
);
2407 else if ((aop
== 0 || aop
== 1 || aop
== 2) && aopcde
== 7)
2408 return DREG_MASK (dst0
);
2410 else if (aop
== 0 && aopcde
== 12)
2411 return DREG_MASK (dst0
);
2412 else if (aop
== 1 && aopcde
== 12)
2413 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2414 else if (aop
== 3 && aopcde
== 12)
2415 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2417 else if (aopcde
== 0)
2418 return DREG_MASK (dst0
);
2419 else if (aopcde
== 1)
2420 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2422 else if (aop
== 0 && aopcde
== 10)
2423 return DREGL_MASK (dst0
);
2424 else if (aop
== 1 && aopcde
== 10)
2425 return DREGL_MASK (dst0
);
2427 else if ((aop
== 1 || aop
== 0) && aopcde
== 4)
2428 return DREG_MASK (dst0
);
2429 else if (aop
== 2 && aopcde
== 4)
2430 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2432 else if (aop
== 0 && aopcde
== 17)
2433 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2434 else if (aop
== 1 && aopcde
== 17)
2435 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2436 else if (aop
== 0 && aopcde
== 18)
2438 else if (aop
== 3 && aopcde
== 18)
2441 else if ((aop
== 0 || aop
== 1 || aop
== 2) && aopcde
== 6)
2442 return DREG_MASK (dst0
);
2444 else if ((aop
== 0 || aop
== 1) && aopcde
== 20)
2445 return DREG_MASK (dst0
);
2447 else if ((aop
== 0 || aop
== 1) && aopcde
== 21)
2448 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2450 else if (aop
== 0 && aopcde
== 23 && HL
== 1)
2451 return DREG_MASK (dst0
);
2452 else if (aop
== 0 && aopcde
== 23 && HL
== 0)
2453 return DREG_MASK (dst0
);
2455 else if (aop
== 0 && aopcde
== 24)
2456 return DREG_MASK (dst0
);
2457 else if (aop
== 1 && aopcde
== 24)
2458 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2459 else if (aopcde
== 13)
2460 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2468 decode_dsp32shift_0 (int iw0
, int iw1
)
2471 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2472 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............|
2473 |.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......|
2474 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2475 int HLs
= ((iw1
>> DSP32Shift_HLs_bits
) & DSP32Shift_HLs_mask
);
2476 int sop
= ((iw1
>> DSP32Shift_sop_bits
) & DSP32Shift_sop_mask
);
2477 int src0
= ((iw1
>> DSP32Shift_src0_bits
) & DSP32Shift_src0_mask
);
2478 int src1
= ((iw1
>> DSP32Shift_src1_bits
) & DSP32Shift_src1_mask
);
2479 int dst0
= ((iw1
>> DSP32Shift_dst0_bits
) & DSP32Shift_dst0_mask
);
2480 int sopcde
= ((iw0
>> (DSP32Shift_sopcde_bits
- 16)) & DSP32Shift_sopcde_mask
);
2482 if (sop
== 0 && sopcde
== 0)
2483 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2484 else if (sop
== 1 && sopcde
== 0)
2485 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2486 else if (sop
== 2 && sopcde
== 0)
2487 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2488 else if (sop
== 0 && sopcde
== 3)
2490 else if (sop
== 1 && sopcde
== 3)
2492 else if (sop
== 2 && sopcde
== 3)
2494 else if (sop
== 3 && sopcde
== 3)
2495 return DREG_MASK (dst0
);
2496 else if (sop
== 0 && sopcde
== 1)
2497 return DREG_MASK (dst0
);
2498 else if (sop
== 1 && sopcde
== 1)
2499 return DREG_MASK (dst0
);
2500 else if (sop
== 2 && sopcde
== 1)
2501 return DREG_MASK (dst0
);
2502 else if (sopcde
== 2)
2503 return DREG_MASK (dst0
);
2504 else if (sopcde
== 4)
2505 return DREG_MASK (dst0
);
2506 else if (sop
== 0 && sopcde
== 5)
2507 return DREGL_MASK (dst0
);
2508 else if (sop
== 1 && sopcde
== 5)
2509 return DREGL_MASK (dst0
);
2510 else if (sop
== 2 && sopcde
== 5)
2511 return DREGL_MASK (dst0
);
2512 else if (sop
== 0 && sopcde
== 6)
2513 return DREGL_MASK (dst0
);
2514 else if (sop
== 1 && sopcde
== 6)
2515 return DREGL_MASK (dst0
);
2516 else if (sop
== 3 && sopcde
== 6)
2517 return DREGL_MASK (dst0
);
2518 else if (sop
== 0 && sopcde
== 7)
2519 return DREGL_MASK (dst0
);
2520 else if (sop
== 1 && sopcde
== 7)
2521 return DREGL_MASK (dst0
);
2522 else if (sop
== 2 && sopcde
== 7)
2523 return DREGL_MASK (dst0
);
2524 else if (sop
== 3 && sopcde
== 7)
2525 return DREGL_MASK (dst0
);
2526 else if (sop
== 0 && sopcde
== 8)
2527 return DREG_MASK (src0
) | DREG_MASK (src1
);
2530 OUTS (outf
, "BITMUX (");
2531 OUTS (outf
, dregs (src0
));
2533 OUTS (outf
, dregs (src1
));
2534 OUTS (outf
, ", A0) (ASR)");
2537 else if (sop
== 1 && sopcde
== 8)
2538 return DREG_MASK (src0
) | DREG_MASK (src1
);
2541 OUTS (outf
, "BITMUX (");
2542 OUTS (outf
, dregs (src0
));
2544 OUTS (outf
, dregs (src1
));
2545 OUTS (outf
, ", A0) (ASL)");
2548 else if (sopcde
== 9)
2549 return sop
< 2 ? DREGL_MASK (dst0
) : DREG_MASK (dst0
);
2550 else if (sopcde
== 10)
2551 return DREG_MASK (dst0
);
2552 else if (sop
== 0 && sopcde
== 11)
2553 return DREGL_MASK (dst0
);
2554 else if (sop
== 1 && sopcde
== 11)
2555 return DREGL_MASK (dst0
);
2556 else if (sop
== 0 && sopcde
== 12)
2558 else if (sop
== 1 && sopcde
== 12)
2559 return DREGL_MASK (dst0
);
2560 else if (sop
== 0 && sopcde
== 13)
2561 return DREG_MASK (dst0
);
2562 else if (sop
== 1 && sopcde
== 13)
2563 return DREG_MASK (dst0
);
2564 else if (sop
== 2 && sopcde
== 13)
2565 return DREG_MASK (dst0
);
2571 decode_dsp32shiftimm_0 (int iw0
, int iw1
)
2574 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2575 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............|
2576 |.sop...|.HLs...|.dst0......|.immag.................|.src1......|
2577 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2578 int sop
= ((iw1
>> DSP32ShiftImm_sop_bits
) & DSP32ShiftImm_sop_mask
);
2579 int bit8
= ((iw1
>> 8) & 0x1);
2580 int dst0
= ((iw1
>> DSP32ShiftImm_dst0_bits
) & DSP32ShiftImm_dst0_mask
);
2581 int sopcde
= ((iw0
>> (DSP32ShiftImm_sopcde_bits
- 16)) & DSP32ShiftImm_sopcde_mask
);
2582 int HLs
= ((iw1
>> DSP32ShiftImm_HLs_bits
) & DSP32ShiftImm_HLs_mask
);
2585 if (sop
== 0 && sopcde
== 0)
2586 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2587 else if (sop
== 1 && sopcde
== 0 && bit8
== 0)
2588 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2589 else if (sop
== 1 && sopcde
== 0 && bit8
== 1)
2590 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2591 else if (sop
== 2 && sopcde
== 0 && bit8
== 0)
2592 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2593 else if (sop
== 2 && sopcde
== 0 && bit8
== 1)
2594 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2595 else if (sop
== 2 && sopcde
== 3 && HLs
== 1)
2597 else if (sop
== 0 && sopcde
== 3 && HLs
== 0 && bit8
== 0)
2599 else if (sop
== 0 && sopcde
== 3 && HLs
== 0 && bit8
== 1)
2601 else if (sop
== 0 && sopcde
== 3 && HLs
== 1 && bit8
== 0)
2603 else if (sop
== 0 && sopcde
== 3 && HLs
== 1 && bit8
== 1)
2605 else if (sop
== 1 && sopcde
== 3 && HLs
== 0)
2607 else if (sop
== 1 && sopcde
== 3 && HLs
== 1)
2609 else if (sop
== 2 && sopcde
== 3 && HLs
== 0)
2611 else if (sop
== 1 && sopcde
== 1 && bit8
== 0)
2612 return DREG_MASK (dst0
);
2613 else if (sop
== 1 && sopcde
== 1 && bit8
== 1)
2614 return DREG_MASK (dst0
);
2615 else if (sop
== 2 && sopcde
== 1 && bit8
== 1)
2616 return DREG_MASK (dst0
);
2617 else if (sop
== 2 && sopcde
== 1 && bit8
== 0)
2618 return DREG_MASK (dst0
);
2619 else if (sop
== 0 && sopcde
== 1)
2620 return DREG_MASK (dst0
);
2621 else if (sop
== 1 && sopcde
== 2)
2622 return DREG_MASK (dst0
);
2623 else if (sop
== 2 && sopcde
== 2 && bit8
== 1)
2624 return DREG_MASK (dst0
);
2625 else if (sop
== 2 && sopcde
== 2 && bit8
== 0)
2626 return DREG_MASK (dst0
);
2627 else if (sop
== 3 && sopcde
== 2)
2628 return DREG_MASK (dst0
);
2629 else if (sop
== 0 && sopcde
== 2)
2630 return DREG_MASK (dst0
);
2636 insn_regmask (int iw0
, int iw1
)
2638 if ((iw0
& 0xf7ff) == 0xc003 && iw1
== 0x1800)
2639 return 0; /* MNOP */
2640 else if ((iw0
& 0xff00) == 0x0000)
2641 return decode_ProgCtrl_0 (iw0
);
2642 else if ((iw0
& 0xffc0) == 0x0240)
2644 else if ((iw0
& 0xff80) == 0x0100)
2646 else if ((iw0
& 0xfe00) == 0x0400)
2648 else if ((iw0
& 0xfe00) == 0x0600)
2650 else if ((iw0
& 0xf800) == 0x0800)
2652 else if ((iw0
& 0xffe0) == 0x0200)
2654 else if ((iw0
& 0xff00) == 0x0300)
2656 else if ((iw0
& 0xf000) == 0x1000)
2658 else if ((iw0
& 0xf000) == 0x2000)
2660 else if ((iw0
& 0xf000) == 0x3000)
2662 else if ((iw0
& 0xfc00) == 0x4000)
2664 else if ((iw0
& 0xfe00) == 0x4400)
2666 else if ((iw0
& 0xf800) == 0x4800)
2668 else if ((iw0
& 0xf000) == 0x5000)
2670 else if ((iw0
& 0xf800) == 0x6000)
2672 else if ((iw0
& 0xf800) == 0x6800)
2674 else if ((iw0
& 0xf000) == 0x8000)
2675 return decode_LDSTpmod_0 (iw0
);
2676 else if ((iw0
& 0xff60) == 0x9e60)
2677 return decode_dagMODim_0 (iw0
);
2678 else if ((iw0
& 0xfff0) == 0x9f60)
2679 return decode_dagMODik_0 (iw0
);
2680 else if ((iw0
& 0xfc00) == 0x9c00)
2681 return decode_dspLDST_0 (iw0
);
2682 else if ((iw0
& 0xf000) == 0x9000)
2683 return decode_LDST_0 (iw0
);
2684 else if ((iw0
& 0xfc00) == 0xb800)
2685 return decode_LDSTiiFP_0 (iw0
);
2686 else if ((iw0
& 0xe000) == 0xA000)
2687 return decode_LDSTii_0 (iw0
);
2688 else if ((iw0
& 0xff80) == 0xe080 && (iw1
& 0x0C00) == 0x0000)
2690 else if ((iw0
& 0xff00) == 0xe100 && (iw1
& 0x0000) == 0x0000)
2692 else if ((iw0
& 0xfe00) == 0xe200 && (iw1
& 0x0000) == 0x0000)
2694 else if ((iw0
& 0xfc00) == 0xe400 && (iw1
& 0x0000) == 0x0000)
2696 else if ((iw0
& 0xfffe) == 0xe800 && (iw1
& 0x0000) == 0x0000)
2698 else if ((iw0
& 0xf600) == 0xc000 && (iw1
& 0x0000) == 0x0000)
2699 return decode_dsp32mac_0 (iw0
, iw1
);
2700 else if ((iw0
& 0xf600) == 0xc200 && (iw1
& 0x0000) == 0x0000)
2701 return decode_dsp32mult_0 (iw0
, iw1
);
2702 else if ((iw0
& 0xf7c0) == 0xc400 && (iw1
& 0x0000) == 0x0000)
2703 return decode_dsp32alu_0 (iw0
, iw1
);
2704 else if ((iw0
& 0xf780) == 0xc600 && (iw1
& 0x01c0) == 0x0000)
2705 return decode_dsp32shift_0 (iw0
, iw1
);
2706 else if ((iw0
& 0xf780) == 0xc680 && (iw1
& 0x0000) == 0x0000)
2707 return decode_dsp32shiftimm_0 (iw0
, iw1
);
2708 else if ((iw0
& 0xff00) == 0xf800)
2710 else if ((iw0
& 0xFFC0) == 0xf000 && (iw1
& 0x0000) == 0x0000)