1 /* tc-bfin.c -- Assembler for the ADI Blackfin.
2 Copyright 2005, 2006, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
23 #include "struc-symbol.h"
24 #include "bfin-defs.h"
26 #include "safe-ctype.h"
28 #include "dwarf2dbg.h"
31 #include "elf/common.h"
34 extern int yyparse (void);
35 struct yy_buffer_state
;
36 typedef struct yy_buffer_state
*YY_BUFFER_STATE
;
37 extern YY_BUFFER_STATE
yy_scan_string (const char *yy_str
);
38 extern void yy_delete_buffer (YY_BUFFER_STATE b
);
39 static parse_state
parse (char *line
);
41 /* Global variables. */
42 struct bfin_insn
*insn
;
45 extern struct obstack mempool
;
48 /* Flags to set in the elf header */
49 #define DEFAULT_FLAGS 0
52 # define DEFAULT_FDPIC EF_BFIN_FDPIC
54 # define DEFAULT_FDPIC 0
57 static flagword bfin_flags
= DEFAULT_FLAGS
| DEFAULT_FDPIC
;
58 static const char *bfin_pic_flag
= DEFAULT_FDPIC
? "-mfdpic" : (const char *)0;
60 /* Blackfin specific function to handle FD-PIC pointer initializations. */
63 bfin_pic_ptr (int nbytes
)
71 #ifdef md_flush_pending_output
72 md_flush_pending_output ();
75 if (is_it_end_of_statement ())
77 demand_empty_rest_of_line ();
82 md_cons_align (nbytes
);
87 bfd_reloc_code_real_type reloc_type
= BFD_RELOC_BFIN_FUNCDESC
;
89 if (strncasecmp (input_line_pointer
, "funcdesc(", 9) == 0)
91 input_line_pointer
+= 9;
93 if (*input_line_pointer
== ')')
96 as_bad (_("missing ')'"));
99 error ("missing funcdesc in picptr");
103 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &exp
, 0,
106 while (*input_line_pointer
++ == ',');
108 input_line_pointer
--; /* Put terminator back into stream. */
109 demand_empty_rest_of_line ();
113 bfin_s_bss (int ignore ATTRIBUTE_UNUSED
)
117 temp
= get_absolute_expression ();
118 subseg_set (bss_section
, (subsegT
) temp
);
119 demand_empty_rest_of_line ();
122 const pseudo_typeS md_pseudo_table
[] = {
123 {"align", s_align_bytes
, 0},
126 {"picptr", bfin_pic_ptr
, 4},
127 {"code", obj_elf_section
, 0},
132 {"pdata", s_ignore
, 0},
133 {"var", s_ignore
, 0},
134 {"bss", bfin_s_bss
, 0},
138 /* Characters that are used to denote comments and line separators. */
139 const char comment_chars
[] = "#";
140 const char line_comment_chars
[] = "#";
141 const char line_separator_chars
[] = ";";
143 /* Characters that can be used to separate the mantissa from the
144 exponent in floating point numbers. */
145 const char EXP_CHARS
[] = "eE";
147 /* Characters that mean this number is a floating point constant.
148 As in 0f12.456 or 0d1.2345e12. */
149 const char FLT_CHARS
[] = "fFdDxX";
151 typedef enum bfin_cpu_type
188 bfin_cpu_t bfin_cpu_type
= BFIN_CPU_UNKNOWN
;
189 /* -msi-revision support. There are three special values:
190 -1 -msi-revision=none.
191 0xffff -msi-revision=any. */
192 int bfin_si_revision
;
194 unsigned int bfin_anomaly_checks
= 0;
201 unsigned int anomaly_checks
;
204 struct bfin_cpu bfin_cpus
[] =
206 {"bf504", BFIN_CPU_BF504
, 0x0000, AC_05000074
},
208 {"bf506", BFIN_CPU_BF506
, 0x0000, AC_05000074
},
210 {"bf512", BFIN_CPU_BF512
, 0x0002, AC_05000074
},
211 {"bf512", BFIN_CPU_BF512
, 0x0001, AC_05000074
},
212 {"bf512", BFIN_CPU_BF512
, 0x0000, AC_05000074
},
214 {"bf514", BFIN_CPU_BF514
, 0x0002, AC_05000074
},
215 {"bf514", BFIN_CPU_BF514
, 0x0001, AC_05000074
},
216 {"bf514", BFIN_CPU_BF514
, 0x0000, AC_05000074
},
218 {"bf516", BFIN_CPU_BF516
, 0x0002, AC_05000074
},
219 {"bf516", BFIN_CPU_BF516
, 0x0001, AC_05000074
},
220 {"bf516", BFIN_CPU_BF516
, 0x0000, AC_05000074
},
222 {"bf518", BFIN_CPU_BF518
, 0x0002, AC_05000074
},
223 {"bf518", BFIN_CPU_BF518
, 0x0001, AC_05000074
},
224 {"bf518", BFIN_CPU_BF518
, 0x0000, AC_05000074
},
226 {"bf522", BFIN_CPU_BF522
, 0x0002, AC_05000074
},
227 {"bf522", BFIN_CPU_BF522
, 0x0001, AC_05000074
},
228 {"bf522", BFIN_CPU_BF522
, 0x0000, AC_05000074
},
230 {"bf523", BFIN_CPU_BF523
, 0x0002, AC_05000074
},
231 {"bf523", BFIN_CPU_BF523
, 0x0001, AC_05000074
},
232 {"bf523", BFIN_CPU_BF523
, 0x0000, AC_05000074
},
234 {"bf524", BFIN_CPU_BF524
, 0x0002, AC_05000074
},
235 {"bf524", BFIN_CPU_BF524
, 0x0001, AC_05000074
},
236 {"bf524", BFIN_CPU_BF524
, 0x0000, AC_05000074
},
238 {"bf525", BFIN_CPU_BF525
, 0x0002, AC_05000074
},
239 {"bf525", BFIN_CPU_BF525
, 0x0001, AC_05000074
},
240 {"bf525", BFIN_CPU_BF525
, 0x0000, AC_05000074
},
242 {"bf526", BFIN_CPU_BF526
, 0x0002, AC_05000074
},
243 {"bf526", BFIN_CPU_BF526
, 0x0001, AC_05000074
},
244 {"bf526", BFIN_CPU_BF526
, 0x0000, AC_05000074
},
246 {"bf527", BFIN_CPU_BF527
, 0x0002, AC_05000074
},
247 {"bf527", BFIN_CPU_BF527
, 0x0001, AC_05000074
},
248 {"bf527", BFIN_CPU_BF527
, 0x0000, AC_05000074
},
250 {"bf531", BFIN_CPU_BF531
, 0x0006, AC_05000074
},
251 {"bf531", BFIN_CPU_BF531
, 0x0005, AC_05000074
},
252 {"bf531", BFIN_CPU_BF531
, 0x0004, AC_05000074
},
253 {"bf531", BFIN_CPU_BF531
, 0x0003, AC_05000074
},
255 {"bf532", BFIN_CPU_BF532
, 0x0006, AC_05000074
},
256 {"bf532", BFIN_CPU_BF532
, 0x0005, AC_05000074
},
257 {"bf532", BFIN_CPU_BF532
, 0x0004, AC_05000074
},
258 {"bf532", BFIN_CPU_BF532
, 0x0003, AC_05000074
},
260 {"bf533", BFIN_CPU_BF533
, 0x0006, AC_05000074
},
261 {"bf533", BFIN_CPU_BF533
, 0x0005, AC_05000074
},
262 {"bf533", BFIN_CPU_BF533
, 0x0004, AC_05000074
},
263 {"bf533", BFIN_CPU_BF533
, 0x0003, AC_05000074
},
265 {"bf534", BFIN_CPU_BF534
, 0x0003, AC_05000074
},
266 {"bf534", BFIN_CPU_BF534
, 0x0002, AC_05000074
},
267 {"bf534", BFIN_CPU_BF534
, 0x0001, AC_05000074
},
269 {"bf536", BFIN_CPU_BF536
, 0x0003, AC_05000074
},
270 {"bf536", BFIN_CPU_BF536
, 0x0002, AC_05000074
},
271 {"bf536", BFIN_CPU_BF536
, 0x0001, AC_05000074
},
273 {"bf537", BFIN_CPU_BF537
, 0x0003, AC_05000074
},
274 {"bf537", BFIN_CPU_BF537
, 0x0002, AC_05000074
},
275 {"bf537", BFIN_CPU_BF537
, 0x0001, AC_05000074
},
277 {"bf538", BFIN_CPU_BF538
, 0x0005, AC_05000074
},
278 {"bf538", BFIN_CPU_BF538
, 0x0004, AC_05000074
},
279 {"bf538", BFIN_CPU_BF538
, 0x0003, AC_05000074
},
280 {"bf538", BFIN_CPU_BF538
, 0x0002, AC_05000074
},
282 {"bf539", BFIN_CPU_BF539
, 0x0005, AC_05000074
},
283 {"bf539", BFIN_CPU_BF539
, 0x0004, AC_05000074
},
284 {"bf539", BFIN_CPU_BF539
, 0x0003, AC_05000074
},
285 {"bf539", BFIN_CPU_BF539
, 0x0002, AC_05000074
},
287 {"bf542m", BFIN_CPU_BF542M
, 0x0003, AC_05000074
},
289 {"bf542", BFIN_CPU_BF542
, 0x0002, AC_05000074
},
290 {"bf542", BFIN_CPU_BF542
, 0x0001, AC_05000074
},
291 {"bf542", BFIN_CPU_BF542
, 0x0000, AC_05000074
},
293 {"bf544m", BFIN_CPU_BF544M
, 0x0003, AC_05000074
},
295 {"bf544", BFIN_CPU_BF544
, 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
, 0x0002, AC_05000074
},
302 {"bf547", BFIN_CPU_BF547
, 0x0001, AC_05000074
},
303 {"bf547", BFIN_CPU_BF547
, 0x0000, AC_05000074
},
305 {"bf548m", BFIN_CPU_BF548M
, 0x0003, AC_05000074
},
307 {"bf548", BFIN_CPU_BF548
, 0x0002, AC_05000074
},
308 {"bf548", BFIN_CPU_BF548
, 0x0001, AC_05000074
},
309 {"bf548", BFIN_CPU_BF548
, 0x0000, AC_05000074
},
311 {"bf549m", BFIN_CPU_BF549M
, 0x0003, AC_05000074
},
313 {"bf549", BFIN_CPU_BF549
, 0x0002, AC_05000074
},
314 {"bf549", BFIN_CPU_BF549
, 0x0001, AC_05000074
},
315 {"bf549", BFIN_CPU_BF549
, 0x0000, AC_05000074
},
317 {"bf561", BFIN_CPU_BF561
, 0x0005, AC_05000074
},
318 {"bf561", BFIN_CPU_BF561
, 0x0003, AC_05000074
},
319 {"bf561", BFIN_CPU_BF561
, 0x0002, AC_05000074
},
321 {"bf592", BFIN_CPU_BF592
, 0x0001, AC_05000074
},
322 {"bf592", BFIN_CPU_BF592
, 0x0000, AC_05000074
},
327 /* Define bfin-specific command-line options (there are none). */
328 const char *md_shortopts
= "";
330 #define OPTION_FDPIC (OPTION_MD_BASE)
331 #define OPTION_NOPIC (OPTION_MD_BASE + 1)
332 #define OPTION_MCPU (OPTION_MD_BASE + 2)
334 struct option md_longopts
[] =
336 { "mcpu", required_argument
, NULL
, OPTION_MCPU
},
337 { "mfdpic", no_argument
, NULL
, OPTION_FDPIC
},
338 { "mnopic", no_argument
, NULL
, OPTION_NOPIC
},
339 { "mno-fdpic", no_argument
, NULL
, OPTION_NOPIC
},
340 { NULL
, no_argument
, NULL
, 0 },
343 size_t md_longopts_size
= sizeof (md_longopts
);
347 md_parse_option (int c ATTRIBUTE_UNUSED
, char *arg ATTRIBUTE_UNUSED
)
360 while ((p
= bfin_cpus
[i
].name
) != NULL
)
362 if (strncmp (arg
, p
, strlen (p
)) == 0)
368 as_fatal ("-mcpu=%s is not valid", arg
);
370 bfin_cpu_type
= bfin_cpus
[i
].type
;
372 q
= arg
+ strlen (p
);
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 (bfin_cpus
[i
].type
== bfin_cpu_type
)
386 bfin_anomaly_checks
|= bfin_cpus
[i
].anomaly_checks
;
392 unsigned int si_major
, si_minor
;
395 rev_len
= strlen (q
);
397 if (sscanf (q
, "-%u.%u%n", &si_major
, &si_minor
, &n
) != 2
399 || si_major
> 0xff || si_minor
> 0xff)
401 invalid_silicon_revision
:
402 as_fatal ("-mcpu=%s has invalid silicon revision", arg
);
405 bfin_si_revision
= (si_major
<< 8) | si_minor
;
407 while (bfin_cpus
[i
].type
== bfin_cpu_type
408 && bfin_cpus
[i
].si_revision
!= bfin_si_revision
)
411 if (bfin_cpus
[i
].type
!= bfin_cpu_type
)
412 goto invalid_silicon_revision
;
414 bfin_anomaly_checks
|= bfin_cpus
[i
].anomaly_checks
;
421 bfin_flags
|= EF_BFIN_FDPIC
;
422 bfin_pic_flag
= "-mfdpic";
426 bfin_flags
&= ~(EF_BFIN_FDPIC
);
435 md_show_usage (FILE * stream
)
437 fprintf (stream
, _(" Blackfin specific assembler options:\n"));
438 fprintf (stream
, _(" -mcpu=<cpu[-sirevision]> specify the name of the target CPU\n"));
439 fprintf (stream
, _(" -mfdpic assemble for the FDPIC ABI\n"));
440 fprintf (stream
, _(" -mno-fdpic/-mnopic disable -mfdpic\n"));
443 /* Perform machine-specific initializations. */
447 /* Set the ELF flags if desired. */
449 bfd_set_private_flags (stdoutput
, bfin_flags
);
451 /* Set the default machine type. */
452 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_bfin
, 0))
453 as_warn (_("Could not set architecture and machine."));
455 /* Ensure that lines can begin with '(', for multiple
456 register stack pops. */
457 lex_type
['('] = LEX_BEGIN_NAME
;
460 record_alignment (text_section
, 2);
461 record_alignment (data_section
, 2);
462 record_alignment (bss_section
, 2);
466 obstack_init (&mempool
);
469 extern int debug_codeselection
;
470 debug_codeselection
= 1;
476 /* Perform the main parsing, and assembly of the input here. Also,
477 call the required routines for alignment and fixups here.
478 This is called for every line that contains real assembly code. */
481 md_assemble (char *line
)
484 extern char *current_inputline
;
486 struct bfin_insn
*tmp_insn
;
488 static size_t buffer_len
= 0;
492 if (len
+ 2 > buffer_len
)
495 free (current_inputline
);
496 buffer_len
= len
+ 40;
497 current_inputline
= xmalloc (buffer_len
);
499 memcpy (current_inputline
, line
, len
);
500 current_inputline
[len
] = ';';
501 current_inputline
[len
+ 1] = '\0';
503 state
= parse (current_inputline
);
504 if (state
== NO_INSN_GENERATED
)
507 for (insn_size
= 0, tmp_insn
= insn
; tmp_insn
; tmp_insn
= tmp_insn
->next
)
508 if (!tmp_insn
->reloc
|| !tmp_insn
->exp
->symbol
)
512 toP
= frag_more (insn_size
);
514 last_insn_size
= insn_size
;
521 if (insn
->reloc
&& insn
->exp
->symbol
)
523 char *prev_toP
= toP
- 2;
526 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
527 case BFD_RELOC_24_PCREL
:
528 case BFD_RELOC_BFIN_16_LOW
:
529 case BFD_RELOC_BFIN_16_HIGH
:
536 /* Following if condition checks for the arithmetic relocations.
537 If the case then it doesn't required to generate the code.
538 It has been assumed that, their ID will be contiguous. */
539 if ((BFD_ARELOC_BFIN_PUSH
<= insn
->reloc
540 && BFD_ARELOC_BFIN_COMP
>= insn
->reloc
)
541 || insn
->reloc
== BFD_RELOC_BFIN_16_IMM
)
545 if (insn
->reloc
== BFD_ARELOC_BFIN_CONST
546 || insn
->reloc
== BFD_ARELOC_BFIN_PUSH
)
550 (prev_toP
- frag_now
->fr_literal
),
551 size
, insn
->exp
->symbol
, insn
->exp
->value
,
552 insn
->pcrel
, insn
->reloc
);
556 md_number_to_chars (toP
, insn
->value
, 2);
562 printf (" %02x%02x", ((unsigned char *) &insn
->value
)[0],
563 ((unsigned char *) &insn
->value
)[1]);
569 dwarf2_emit_insn (insn_size
);
572 while (*line
++ != '\0')
574 bump_line_counters ();
577 /* Parse one line of instructions, and generate opcode for it.
578 To parse the line, YACC and LEX are used, because the instruction set
579 syntax doesn't confirm to the AT&T assembly syntax.
580 To call a YACC & LEX generated parser, we must provide the input via
581 a FILE stream, otherwise stdin is used by default. Below the input
582 to the function will be put into a temporary file, then the generated
583 parser uses the temporary file for parsing. */
589 YY_BUFFER_STATE buffstate
;
591 buffstate
= yy_scan_string (line
);
593 /* our lex requires setting the start state to keyword
594 every line as the first word may be a keyword.
595 Fixes a bug where we could not have keywords as labels. */
598 /* Call yyparse here. */
600 if (state
== SEMANTIC_ERROR
)
602 as_bad (_("Parse failed."));
606 yy_delete_buffer (buffstate
);
610 /* We need to handle various expressions properly.
611 Such as, [SP--] = 34, concerned by md_assemble(). */
614 md_operand (expressionS
* expressionP
)
616 if (*input_line_pointer
== '[')
618 as_tsktsk ("We found a '['!");
619 input_line_pointer
++;
620 expression (expressionP
);
624 /* Handle undefined symbols. */
626 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
628 return (symbolS
*) 0;
632 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
633 segT segment ATTRIBUTE_UNUSED
)
638 /* Convert from target byte order to host byte order. */
641 md_chars_to_number (char *val
, int n
)
645 for (retval
= 0; n
--;)
654 md_apply_fix (fixS
*fixP
, valueT
*valueP
, segT seg ATTRIBUTE_UNUSED
)
656 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
658 long value
= *valueP
;
661 switch (fixP
->fx_r_type
)
663 case BFD_RELOC_BFIN_GOT
:
664 case BFD_RELOC_BFIN_GOT17M4
:
665 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
666 fixP
->fx_no_overflow
= 1;
667 newval
= md_chars_to_number (where
, 2);
668 newval
|= 0x0 & 0x7f;
669 md_number_to_chars (where
, newval
, 2);
672 case BFD_RELOC_BFIN_10_PCREL
:
675 if (value
< -1024 || value
> 1022)
676 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
677 _("pcrel too far BFD_RELOC_BFIN_10"));
679 /* 11 bit offset even numbered, so we remove right bit. */
681 newval
= md_chars_to_number (where
, 2);
682 newval
|= value
& 0x03ff;
683 md_number_to_chars (where
, newval
, 2);
686 case BFD_RELOC_BFIN_12_PCREL_JUMP
:
687 case BFD_RELOC_BFIN_12_PCREL_JUMP_S
:
688 case BFD_RELOC_12_PCREL
:
692 if (value
< -4096 || value
> 4094)
693 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_12"));
694 /* 13 bit offset even numbered, so we remove right bit. */
696 newval
= md_chars_to_number (where
, 2);
697 newval
|= value
& 0xfff;
698 md_number_to_chars (where
, newval
, 2);
701 case BFD_RELOC_BFIN_16_LOW
:
702 case BFD_RELOC_BFIN_16_HIGH
:
703 fixP
->fx_done
= FALSE
;
706 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
707 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
708 case BFD_RELOC_24_PCREL
:
712 if (value
< -16777216 || value
> 16777214)
713 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_24"));
715 /* 25 bit offset even numbered, so we remove right bit. */
719 md_number_to_chars (where
- 2, value
>> 16, 1);
720 md_number_to_chars (where
, value
, 1);
721 md_number_to_chars (where
+ 1, value
>> 8, 1);
724 case BFD_RELOC_BFIN_5_PCREL
: /* LSETUP (a, b) : "a" */
727 if (value
< 4 || value
> 30)
728 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_5"));
730 newval
= md_chars_to_number (where
, 1);
731 newval
= (newval
& 0xf0) | (value
& 0xf);
732 md_number_to_chars (where
, newval
, 1);
735 case BFD_RELOC_BFIN_11_PCREL
: /* LSETUP (a, b) : "b" */
739 if (value
< 4 || value
> 2046)
740 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_11_PCREL"));
741 /* 11 bit unsigned even, so we remove right bit. */
743 newval
= md_chars_to_number (where
, 2);
744 newval
|= value
& 0x03ff;
745 md_number_to_chars (where
, newval
, 2);
749 if (value
< -0x80 || value
>= 0x7f)
750 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("rel too far BFD_RELOC_8"));
751 md_number_to_chars (where
, value
, 1);
754 case BFD_RELOC_BFIN_16_IMM
:
756 if (value
< -0x8000 || value
>= 0x7fff)
757 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("rel too far BFD_RELOC_16"));
758 md_number_to_chars (where
, value
, 2);
762 md_number_to_chars (where
, value
, 4);
765 case BFD_RELOC_BFIN_PLTPC
:
766 md_number_to_chars (where
, value
, 2);
769 case BFD_RELOC_BFIN_FUNCDESC
:
770 case BFD_RELOC_VTABLE_INHERIT
:
771 case BFD_RELOC_VTABLE_ENTRY
:
772 fixP
->fx_done
= FALSE
;
776 if ((BFD_ARELOC_BFIN_PUSH
> fixP
->fx_r_type
) || (BFD_ARELOC_BFIN_COMP
< fixP
->fx_r_type
))
778 fprintf (stderr
, "Relocation %d not handled in gas." " Contact support.\n", fixP
->fx_r_type
);
784 fixP
->fx_done
= TRUE
;
788 /* Round up a section size to the appropriate boundary. */
790 md_section_align (segment
, size
)
794 int boundary
= bfd_get_section_alignment (stdoutput
, segment
);
795 return ((size
+ (1 << boundary
) - 1) & (-1 << boundary
));
800 md_atof (int type
, char * litP
, int * sizeP
)
802 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
806 /* If while processing a fixup, a reloc really needs to be created
807 then it is done here. */
810 tc_gen_reloc (seg
, fixp
)
811 asection
*seg ATTRIBUTE_UNUSED
;
816 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
817 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
818 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
819 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
821 reloc
->addend
= fixp
->fx_offset
;
822 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
824 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
826 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
827 /* xgettext:c-format. */
828 _("reloc %d not supported by object file format"),
829 (int) fixp
->fx_r_type
);
839 /* The location from which a PC relative jump should be calculated,
840 given a PC relative reloc. */
843 md_pcrel_from_section (fixP
, sec
)
847 if (fixP
->fx_addsy
!= (symbolS
*) NULL
848 && (!S_IS_DEFINED (fixP
->fx_addsy
)
849 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
851 /* The symbol is undefined (or is defined but not in this section).
852 Let the linker figure it out. */
855 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
858 /* Return true if the fix can be handled by GAS, false if it must
859 be passed through to the linker. */
862 bfin_fix_adjustable (fixS
*fixP
)
864 switch (fixP
->fx_r_type
)
866 /* Adjust_reloc_syms doesn't know about the GOT. */
867 case BFD_RELOC_BFIN_GOT
:
868 case BFD_RELOC_BFIN_PLTPC
:
869 /* We need the symbol name for the VTABLE entries. */
870 case BFD_RELOC_VTABLE_INHERIT
:
871 case BFD_RELOC_VTABLE_ENTRY
:
879 /* Special extra functions that help bfin-parse.y perform its job. */
881 struct obstack mempool
;
884 conscode (INSTR_T head
, INSTR_T tail
)
893 conctcode (INSTR_T head
, INSTR_T tail
)
895 INSTR_T temp
= (head
);
906 note_reloc (INSTR_T code
, Expr_Node
* symbol
, int reloc
, int pcrel
)
908 /* Assert that the symbol is not an operator. */
909 gas_assert (symbol
->type
== Expr_Node_Reloc
);
911 return note_reloc1 (code
, symbol
->value
.s_value
, reloc
, pcrel
);
916 note_reloc1 (INSTR_T code
, const char *symbol
, int reloc
, int pcrel
)
919 code
->exp
= mkexpr (0, symbol_find_or_make (symbol
));
925 note_reloc2 (INSTR_T code
, const char *symbol
, int reloc
, int value
, int pcrel
)
928 code
->exp
= mkexpr (value
, symbol_find_or_make (symbol
));
934 gencode (unsigned long x
)
936 INSTR_T cell
= obstack_alloc (&mempool
, sizeof (struct bfin_insn
));
937 memset (cell
, 0, sizeof (struct bfin_insn
));
949 return obstack_alloc (&mempool
, n
);
953 Expr_Node_Create (Expr_Node_Type type
,
954 Expr_Node_Value value
,
955 Expr_Node
*Left_Child
,
956 Expr_Node
*Right_Child
)
960 Expr_Node
*node
= (Expr_Node
*) allocate (sizeof (Expr_Node
));
963 node
->Left_Child
= Left_Child
;
964 node
->Right_Child
= Right_Child
;
968 static const char *con
= ".__constant";
969 static const char *op
= ".__operator";
970 static INSTR_T
Expr_Node_Gen_Reloc_R (Expr_Node
* head
);
971 INSTR_T
Expr_Node_Gen_Reloc (Expr_Node
*head
, int parent_reloc
);
974 Expr_Node_Gen_Reloc (Expr_Node
* head
, int parent_reloc
)
976 /* Top level reloction expression generator VDSP style.
977 If the relocation is just by itself, generate one item
978 else generate this convoluted expression. */
980 INSTR_T note
= NULL_CODE
;
981 INSTR_T note1
= NULL_CODE
;
982 int pcrel
= 1; /* Is the parent reloc pcrelative?
983 This calculation here and HOWTO should match. */
987 /* If it's 32 bit quantity then 16bit code needs to be added. */
990 if (head
->type
== Expr_Node_Constant
)
992 /* If note1 is not null code, we have to generate a right
993 aligned value for the constant. Otherwise the reloc is
994 a part of the basic command and the yacc file
996 value
= head
->value
.i_value
;
998 switch (parent_reloc
)
1000 /* Some relocations will need to allocate extra words. */
1001 case BFD_RELOC_BFIN_16_IMM
:
1002 case BFD_RELOC_BFIN_16_LOW
:
1003 case BFD_RELOC_BFIN_16_HIGH
:
1004 note1
= conscode (gencode (value
), NULL_CODE
);
1007 case BFD_RELOC_BFIN_PLTPC
:
1008 note1
= conscode (gencode (value
), NULL_CODE
);
1012 case BFD_RELOC_BFIN_GOT
:
1013 case BFD_RELOC_BFIN_GOT17M4
:
1014 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
1015 note1
= conscode (gencode (value
), NULL_CODE
);
1018 case BFD_RELOC_24_PCREL
:
1019 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
1020 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
1021 /* These offsets are even numbered pcrel. */
1022 note1
= conscode (gencode (value
>> 1), NULL_CODE
);
1028 if (head
->type
== Expr_Node_Constant
)
1030 else if (head
->type
== Expr_Node_Reloc
)
1032 note
= note_reloc1 (gencode (0), head
->value
.s_value
, parent_reloc
, pcrel
);
1033 if (note1
!= NULL_CODE
)
1034 note
= conscode (note1
, note
);
1036 else if (head
->type
== Expr_Node_Binop
1037 && (head
->value
.op_value
== Expr_Op_Type_Add
1038 || head
->value
.op_value
== Expr_Op_Type_Sub
)
1039 && head
->Left_Child
->type
== Expr_Node_Reloc
1040 && head
->Right_Child
->type
== Expr_Node_Constant
)
1042 int val
= head
->Right_Child
->value
.i_value
;
1043 if (head
->value
.op_value
== Expr_Op_Type_Sub
)
1045 note
= conscode (note_reloc2 (gencode (0), head
->Left_Child
->value
.s_value
,
1046 parent_reloc
, val
, 0),
1048 if (note1
!= NULL_CODE
)
1049 note
= conscode (note1
, note
);
1053 /* Call the recursive function. */
1054 note
= note_reloc1 (gencode (0), op
, parent_reloc
, pcrel
);
1055 if (note1
!= NULL_CODE
)
1056 note
= conscode (note1
, note
);
1057 note
= conctcode (Expr_Node_Gen_Reloc_R (head
), note
);
1063 Expr_Node_Gen_Reloc_R (Expr_Node
* head
)
1071 case Expr_Node_Constant
:
1072 note
= conscode (note_reloc2 (gencode (0), con
, BFD_ARELOC_BFIN_CONST
, head
->value
.i_value
, 0), NULL_CODE
);
1074 case Expr_Node_Reloc
:
1075 note
= conscode (note_reloc (gencode (0), head
, BFD_ARELOC_BFIN_PUSH
, 0), NULL_CODE
);
1077 case Expr_Node_Binop
:
1078 note1
= conctcode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), Expr_Node_Gen_Reloc_R (head
->Right_Child
));
1079 switch (head
->value
.op_value
)
1081 case Expr_Op_Type_Add
:
1082 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_ADD
, 0), NULL_CODE
));
1084 case Expr_Op_Type_Sub
:
1085 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_SUB
, 0), NULL_CODE
));
1087 case Expr_Op_Type_Mult
:
1088 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MULT
, 0), NULL_CODE
));
1090 case Expr_Op_Type_Div
:
1091 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_DIV
, 0), NULL_CODE
));
1093 case Expr_Op_Type_Mod
:
1094 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MOD
, 0), NULL_CODE
));
1096 case Expr_Op_Type_Lshift
:
1097 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LSHIFT
, 0), NULL_CODE
));
1099 case Expr_Op_Type_Rshift
:
1100 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_RSHIFT
, 0), NULL_CODE
));
1102 case Expr_Op_Type_BAND
:
1103 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_AND
, 0), NULL_CODE
));
1105 case Expr_Op_Type_BOR
:
1106 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_OR
, 0), NULL_CODE
));
1108 case Expr_Op_Type_BXOR
:
1109 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_XOR
, 0), NULL_CODE
));
1111 case Expr_Op_Type_LAND
:
1112 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LAND
, 0), NULL_CODE
));
1114 case Expr_Op_Type_LOR
:
1115 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LOR
, 0), NULL_CODE
));
1118 fprintf (stderr
, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1123 case Expr_Node_Unop
:
1124 note1
= conscode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), NULL_CODE
);
1125 switch (head
->value
.op_value
)
1127 case Expr_Op_Type_NEG
:
1128 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_NEG
, 0), NULL_CODE
));
1130 case Expr_Op_Type_COMP
:
1131 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_COMP
, 0), NULL_CODE
));
1134 fprintf (stderr
, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1138 fprintf (stderr
, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__
, __LINE__
);
1143 /* Blackfin opcode generation. */
1145 /* These functions are called by the generated parser
1146 (from bfin-parse.y), the register type classification
1147 happens in bfin-lex.l. */
1149 #include "bfin-aux.h"
1150 #include "opcode/bfin.h"
1152 #define INIT(t) t c_code = init_##t
1153 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1154 #define ASSIGNF(x,f) c_code.opcode |= ((x & c_code.mask_##f)<<c_code.bits_##f)
1155 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1157 #define HI(x) ((x >> 16) & 0xffff)
1158 #define LO(x) ((x ) & 0xffff)
1160 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1162 #define GEN_OPCODE32() \
1163 conscode (gencode (HI (c_code.opcode)), \
1164 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1166 #define GEN_OPCODE16() \
1167 conscode (gencode (c_code.opcode), NULL_CODE)
1170 /* 32 BIT INSTRUCTIONS. */
1173 /* DSP32 instruction generation. */
1176 bfin_gen_dsp32mac (int op1
, int MM
, int mmod
, int w1
, int P
,
1177 int h01
, int h11
, int h00
, int h10
, int op0
,
1178 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1194 /* If we have full reg assignments, mask out LSB to encode
1195 single or simultaneous even/odd register moves. */
1205 return GEN_OPCODE32 ();
1209 bfin_gen_dsp32mult (int op1
, int MM
, int mmod
, int w1
, int P
,
1210 int h01
, int h11
, int h00
, int h10
, int op0
,
1211 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1236 return GEN_OPCODE32 ();
1240 bfin_gen_dsp32alu (int HL
, int aopcde
, int aop
, int s
, int x
,
1241 REG_T dst0
, REG_T dst1
, REG_T src0
, REG_T src1
)
1255 return GEN_OPCODE32 ();
1259 bfin_gen_dsp32shift (int sopcde
, REG_T dst0
, REG_T src0
,
1260 REG_T src1
, int sop
, int HLs
)
1272 return GEN_OPCODE32 ();
1276 bfin_gen_dsp32shiftimm (int sopcde
, REG_T dst0
, int immag
,
1277 REG_T src1
, int sop
, int HLs
)
1279 INIT (DSP32ShiftImm
);
1289 return GEN_OPCODE32 ();
1295 bfin_gen_loopsetup (Expr_Node
* psoffset
, REG_T c
, int rop
,
1296 Expr_Node
* peoffset
, REG_T reg
)
1298 int soffset
, eoffset
;
1301 soffset
= (EXPR_VALUE (psoffset
) >> 1);
1303 eoffset
= (EXPR_VALUE (peoffset
) >> 1);
1310 conscode (gencode (HI (c_code
.opcode
)),
1311 conctcode (Expr_Node_Gen_Reloc (psoffset
, BFD_RELOC_BFIN_5_PCREL
),
1312 conctcode (gencode (LO (c_code
.opcode
)), Expr_Node_Gen_Reloc (peoffset
, BFD_RELOC_BFIN_11_PCREL
))));
1319 bfin_gen_calla (Expr_Node
* addr
, int S
)
1327 case 0 : rel
= BFD_RELOC_BFIN_24_PCREL_JUMP_L
; break;
1328 case 1 : rel
= BFD_RELOC_24_PCREL
; break;
1329 case 2 : rel
= BFD_RELOC_BFIN_PLTPC
; break;
1335 val
= EXPR_VALUE (addr
) >> 1;
1336 high_val
= val
>> 16;
1338 return conscode (gencode (HI (c_code
.opcode
) | (high_val
& 0xff)),
1339 Expr_Node_Gen_Reloc (addr
, rel
));
1343 bfin_gen_linkage (int R
, int framesize
)
1350 return GEN_OPCODE32 ();
1354 /* Load and Store. */
1357 bfin_gen_ldimmhalf (REG_T reg
, int H
, int S
, int Z
, Expr_Node
* phword
, int rel
)
1360 unsigned val
= EXPR_VALUE (phword
);
1368 grp
= (GROUP (reg
));
1372 return conscode (gencode (HI (c_code
.opcode
)), Expr_Node_Gen_Reloc (phword
, BFD_RELOC_BFIN_16_IMM
));
1376 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
));
1383 return GEN_OPCODE32 ();
1387 bfin_gen_ldstidxi (REG_T ptr
, REG_T reg
, int W
, int sz
, int Z
, Expr_Node
* poffset
)
1391 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1393 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1404 if (poffset
->type
!= Expr_Node_Constant
)
1406 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1407 /* distinguish between R0 = [P5 + symbol@GOT] and
1408 P5 = [P5 + _current_shared_library_p5_offset_]
1410 if (poffset
->type
== Expr_Node_Reloc
1411 && !strcmp (poffset
->value
.s_value
,
1412 "_current_shared_library_p5_offset_"))
1414 return conscode (gencode (HI (c_code
.opcode
)),
1415 Expr_Node_Gen_Reloc(poffset
, BFD_RELOC_16
));
1417 else if (poffset
->type
!= Expr_Node_GOT_Reloc
)
1420 return conscode (gencode (HI (c_code
.opcode
)),
1421 Expr_Node_Gen_Reloc(poffset
->Left_Child
,
1422 poffset
->value
.i_value
));
1428 { /* load/store access size */
1429 case 0: /* 32 bit */
1430 value
= EXPR_VALUE (poffset
) >> 2;
1432 case 1: /* 16 bit */
1433 value
= EXPR_VALUE (poffset
) >> 1;
1436 value
= EXPR_VALUE (poffset
);
1442 offset
= (value
& 0xffff);
1444 return GEN_OPCODE32 ();
1450 bfin_gen_ldst (REG_T ptr
, REG_T reg
, int aop
, int sz
, int Z
, int W
)
1454 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1456 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1467 return GEN_OPCODE16 ();
1471 bfin_gen_ldstii (REG_T ptr
, REG_T reg
, Expr_Node
* poffset
, int W
, int opc
)
1477 if (!IS_PREG (*ptr
))
1479 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1487 value
= EXPR_VALUE (poffset
) >> 1;
1491 value
= EXPR_VALUE (poffset
) >> 2;
1503 return GEN_OPCODE16 ();
1507 bfin_gen_ldstiifp (REG_T sreg
, Expr_Node
* poffset
, int W
)
1509 /* Set bit 4 if it's a Preg. */
1510 int reg
= (sreg
->regno
& CODE_MASK
) | (IS_PREG (*sreg
) ? 0x8 : 0x0);
1511 int offset
= ((~(EXPR_VALUE (poffset
) >> 2)) & 0x1f) + 1;
1517 return GEN_OPCODE16 ();
1521 bfin_gen_ldstpmod (REG_T ptr
, REG_T reg
, int aop
, int W
, REG_T idx
)
1531 return GEN_OPCODE16 ();
1535 bfin_gen_dspldst (REG_T i
, REG_T reg
, int aop
, int W
, int m
)
1545 return GEN_OPCODE16 ();
1549 bfin_gen_logi2op (int opc
, int src
, int dst
)
1557 return GEN_OPCODE16 ();
1561 bfin_gen_brcc (int T
, int B
, Expr_Node
* poffset
)
1568 offset
= ((EXPR_VALUE (poffset
) >> 1));
1570 return conscode (gencode (c_code
.opcode
), Expr_Node_Gen_Reloc (poffset
, BFD_RELOC_BFIN_10_PCREL
));
1574 bfin_gen_ujump (Expr_Node
* poffset
)
1579 offset
= ((EXPR_VALUE (poffset
) >> 1));
1582 return conscode (gencode (c_code
.opcode
),
1583 Expr_Node_Gen_Reloc (
1584 poffset
, BFD_RELOC_BFIN_12_PCREL_JUMP_S
));
1588 bfin_gen_alu2op (REG_T dst
, REG_T src
, int opc
)
1596 return GEN_OPCODE16 ();
1600 bfin_gen_compi2opd (REG_T dst
, int src
, int opc
)
1608 return GEN_OPCODE16 ();
1612 bfin_gen_compi2opp (REG_T dst
, int src
, int opc
)
1620 return GEN_OPCODE16 ();
1624 bfin_gen_dagmodik (REG_T i
, int opc
)
1631 return GEN_OPCODE16 ();
1635 bfin_gen_dagmodim (REG_T i
, REG_T m
, int opc
, int br
)
1644 return GEN_OPCODE16 ();
1648 bfin_gen_ptr2op (REG_T dst
, REG_T src
, int opc
)
1656 return GEN_OPCODE16 ();
1660 bfin_gen_comp3op (REG_T src0
, REG_T src1
, REG_T dst
, int opc
)
1669 return GEN_OPCODE16 ();
1673 bfin_gen_ccflag (REG_T x
, int y
, int opc
, int I
, int G
)
1683 return GEN_OPCODE16 ();
1687 bfin_gen_ccmv (REG_T src
, REG_T dst
, int T
)
1700 return GEN_OPCODE16 ();
1704 bfin_gen_cc2stat (int cbit
, int opc
, int D
)
1712 return GEN_OPCODE16 ();
1716 bfin_gen_regmv (REG_T src
, REG_T dst
)
1729 return GEN_OPCODE16 ();
1733 bfin_gen_cc2dreg (int opc
, REG_T reg
)
1740 return GEN_OPCODE16 ();
1744 bfin_gen_progctrl (int prgfunc
, int poprnd
)
1751 return GEN_OPCODE16 ();
1755 bfin_gen_cactrl (REG_T reg
, int a
, int opc
)
1763 return GEN_OPCODE16 ();
1767 bfin_gen_pushpopmultiple (int dr
, int pr
, int d
, int p
, int W
)
1769 INIT (PushPopMultiple
);
1777 return GEN_OPCODE16 ();
1781 bfin_gen_pushpopreg (REG_T reg
, int W
)
1787 grp
= (GROUP (reg
));
1791 return GEN_OPCODE16 ();
1794 /* Pseudo Debugging Support. */
1797 bfin_gen_pseudodbg (int fn
, int reg
, int grp
)
1805 return GEN_OPCODE16 ();
1809 bfin_gen_pseudodbg_assert (int dbgop
, REG_T regtest
, int expected
)
1812 INIT (PseudoDbg_Assert
);
1816 grp
= GROUP (regtest
);
1820 return GEN_OPCODE32 ();
1824 bfin_gen_pseudochr (int ch
)
1830 return GEN_OPCODE16 ();
1833 /* Multiple instruction generation. */
1836 bfin_gen_multi_instr (INSTR_T dsp32
, INSTR_T dsp16_grp1
, INSTR_T dsp16_grp2
)
1840 /* If it's a 0, convert into MNOP. */
1844 SET_MULTI_INSTRUCTION_BIT (dsp32
);
1848 dsp32
= gencode (0xc803);
1849 walk
= gencode (0x1800);
1855 dsp16_grp1
= gencode (0x0000);
1860 dsp16_grp2
= gencode (0x0000);
1863 walk
->next
= dsp16_grp1
;
1864 dsp16_grp1
->next
= dsp16_grp2
;
1865 dsp16_grp2
->next
= NULL_CODE
;
1871 bfin_gen_loop (Expr_Node
*exp
, REG_T reg
, int rop
, REG_T preg
)
1873 const char *loopsym
;
1874 char *lbeginsym
, *lendsym
;
1875 Expr_Node_Value lbeginval
, lendval
;
1876 Expr_Node
*lbegin
, *lend
;
1879 loopsym
= exp
->value
.s_value
;
1880 lbeginsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__BEGIN") + 5);
1881 lendsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__END") + 5);
1886 strcat (lbeginsym
, "L$L$");
1887 strcat (lbeginsym
, loopsym
);
1888 strcat (lbeginsym
, "__BEGIN");
1890 strcat (lendsym
, "L$L$");
1891 strcat (lendsym
, loopsym
);
1892 strcat (lendsym
, "__END");
1894 lbeginval
.s_value
= lbeginsym
;
1895 lendval
.s_value
= lendsym
;
1897 lbegin
= Expr_Node_Create (Expr_Node_Reloc
, lbeginval
, NULL
, NULL
);
1898 lend
= Expr_Node_Create (Expr_Node_Reloc
, lendval
, NULL
, NULL
);
1900 sym
= symbol_find(loopsym
);
1901 if (!S_IS_LOCAL (sym
) || (S_IS_LOCAL (sym
) && !symbol_used_p (sym
)))
1902 symbol_remove (sym
, &symbol_rootP
, &symbol_lastP
);
1904 return bfin_gen_loopsetup (lbegin
, reg
, rop
, lend
, preg
);
1908 bfin_loop_attempt_create_label (Expr_Node
*exp
, int is_begin
)
1911 name
= fb_label_name (exp
->value
.i_value
, is_begin
);
1912 exp
->value
.s_value
= xstrdup (name
);
1913 exp
->type
= Expr_Node_Reloc
;
1917 bfin_loop_beginend (Expr_Node
*exp
, int begin
)
1919 const char *loopsym
;
1922 const char *suffix
= begin
? "__BEGIN" : "__END";
1924 loopsym
= exp
->value
.s_value
;
1925 label_name
= (char *) xmalloc (strlen (loopsym
) + strlen (suffix
) + 5);
1929 strcat (label_name
, "L$L$");
1930 strcat (label_name
, loopsym
);
1931 strcat (label_name
, suffix
);
1933 linelabel
= colon (label_name
);
1935 /* LOOP_END follows the last instruction in the loop.
1936 Adjust label address. */
1938 ((struct local_symbol
*) linelabel
)->lsy_value
-= last_insn_size
;
1942 bfin_eol_in_insn (char *line
)
1944 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1951 /* A semi-colon followed by a newline is always the end of a line. */
1952 if (line
[-1] == ';')
1955 if (line
[-1] == '|')
1958 /* If the || is on the next line, there might be leading whitespace. */
1960 while (*temp
== ' ' || *temp
== '\t') temp
++;
1969 bfin_start_label (char *s
, char *ptr
)
1973 if (*s
== '(' || *s
== '[')
1982 bfin_force_relocation (struct fix
*fixp
)
1984 if (fixp
->fx_r_type
==BFD_RELOC_BFIN_16_LOW
1985 || fixp
->fx_r_type
== BFD_RELOC_BFIN_16_HIGH
)
1988 return generic_force_reloc (fixp
);
1991 /* This is a stripped down version of the disassembler. The only thing it
1992 does is return a mask of registers modified by an instruction. Only
1993 instructions that can occur in a parallel-issue bundle are handled, and
1994 only the registers that can cause a conflict are recorded. */
1996 #define DREG_MASK(n) (0x101 << (n))
1997 #define DREGH_MASK(n) (0x100 << (n))
1998 #define DREGL_MASK(n) (0x001 << (n))
1999 #define IREG_MASK(n) (1 << ((n) + 16))
2002 decode_ProgCtrl_0 (int iw0
)
2010 decode_LDSTpmod_0 (int iw0
)
2013 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2014 | 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......|
2015 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2016 int W
= ((iw0
>> LDSTpmod_W_bits
) & LDSTpmod_W_mask
);
2017 int aop
= ((iw0
>> LDSTpmod_aop_bits
) & LDSTpmod_aop_mask
);
2018 int idx
= ((iw0
>> LDSTpmod_idx_bits
) & LDSTpmod_idx_mask
);
2019 int ptr
= ((iw0
>> LDSTpmod_ptr_bits
) & LDSTpmod_ptr_mask
);
2020 int reg
= ((iw0
>> LDSTpmod_reg_bits
) & LDSTpmod_reg_mask
);
2022 if (aop
== 1 && W
== 0 && idx
== ptr
)
2023 return DREGL_MASK (reg
);
2024 else if (aop
== 2 && W
== 0 && idx
== ptr
)
2025 return DREGH_MASK (reg
);
2026 else if (aop
== 1 && W
== 1 && idx
== ptr
)
2028 else if (aop
== 2 && W
== 1 && idx
== ptr
)
2030 else if (aop
== 0 && W
== 0)
2031 return DREG_MASK (reg
);
2032 else if (aop
== 1 && W
== 0)
2033 return DREGL_MASK (reg
);
2034 else if (aop
== 2 && W
== 0)
2035 return DREGH_MASK (reg
);
2036 else if (aop
== 3 && W
== 0)
2037 return DREG_MASK (reg
);
2038 else if (aop
== 3 && W
== 1)
2039 return DREG_MASK (reg
);
2040 else if (aop
== 0 && W
== 1)
2042 else if (aop
== 1 && W
== 1)
2044 else if (aop
== 2 && W
== 1)
2053 decode_dagMODim_0 (int iw0
)
2056 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2057 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....|
2058 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2059 int i
= ((iw0
>> DagMODim_i_bits
) & DagMODim_i_mask
);
2060 int opc
= ((iw0
>> DagMODim_op_bits
) & DagMODim_op_mask
);
2062 if (opc
== 0 || opc
== 1)
2063 return IREG_MASK (i
);
2071 decode_dagMODik_0 (int iw0
)
2074 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2075 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....|
2076 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2077 int i
= ((iw0
>> DagMODik_i_bits
) & DagMODik_i_mask
);
2078 return IREG_MASK (i
);
2083 decode_dspLDST_0 (int iw0
)
2086 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2087 | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......|
2088 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2089 int i
= ((iw0
>> DspLDST_i_bits
) & DspLDST_i_mask
);
2090 int m
= ((iw0
>> DspLDST_m_bits
) & DspLDST_m_mask
);
2091 int W
= ((iw0
>> DspLDST_W_bits
) & DspLDST_W_mask
);
2092 int aop
= ((iw0
>> DspLDST_aop_bits
) & DspLDST_aop_mask
);
2093 int reg
= ((iw0
>> DspLDST_reg_bits
) & DspLDST_reg_mask
);
2095 if (aop
== 0 && W
== 0 && m
== 0)
2096 return DREG_MASK (reg
) | IREG_MASK (i
);
2097 else if (aop
== 0 && W
== 0 && m
== 1)
2098 return DREGL_MASK (reg
) | IREG_MASK (i
);
2099 else if (aop
== 0 && W
== 0 && m
== 2)
2100 return DREGH_MASK (reg
) | IREG_MASK (i
);
2101 else if (aop
== 1 && W
== 0 && m
== 0)
2102 return DREG_MASK (reg
) | IREG_MASK (i
);
2103 else if (aop
== 1 && W
== 0 && m
== 1)
2104 return DREGL_MASK (reg
) | IREG_MASK (i
);
2105 else if (aop
== 1 && W
== 0 && m
== 2)
2106 return DREGH_MASK (reg
) | IREG_MASK (i
);
2107 else if (aop
== 2 && W
== 0 && m
== 0)
2108 return DREG_MASK (reg
);
2109 else if (aop
== 2 && W
== 0 && m
== 1)
2110 return DREGL_MASK (reg
);
2111 else if (aop
== 2 && W
== 0 && m
== 2)
2112 return DREGH_MASK (reg
);
2113 else if (aop
== 0 && W
== 1 && m
== 0)
2114 return IREG_MASK (i
);
2115 else if (aop
== 0 && W
== 1 && m
== 1)
2116 return IREG_MASK (i
);
2117 else if (aop
== 0 && W
== 1 && m
== 2)
2118 return IREG_MASK (i
);
2119 else if (aop
== 1 && W
== 1 && m
== 0)
2120 return IREG_MASK (i
);
2121 else if (aop
== 1 && W
== 1 && m
== 1)
2122 return IREG_MASK (i
);
2123 else if (aop
== 1 && W
== 1 && m
== 2)
2124 return IREG_MASK (i
);
2125 else if (aop
== 2 && W
== 1 && m
== 0)
2127 else if (aop
== 2 && W
== 1 && m
== 1)
2129 else if (aop
== 2 && W
== 1 && m
== 2)
2131 else if (aop
== 3 && W
== 0)
2132 return DREG_MASK (reg
) | IREG_MASK (i
);
2133 else if (aop
== 3 && W
== 1)
2134 return IREG_MASK (i
);
2141 decode_LDST_0 (int iw0
)
2144 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2145 | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......|
2146 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2147 int Z
= ((iw0
>> LDST_Z_bits
) & LDST_Z_mask
);
2148 int W
= ((iw0
>> LDST_W_bits
) & LDST_W_mask
);
2149 int sz
= ((iw0
>> LDST_sz_bits
) & LDST_sz_mask
);
2150 int aop
= ((iw0
>> LDST_aop_bits
) & LDST_aop_mask
);
2151 int reg
= ((iw0
>> LDST_reg_bits
) & LDST_reg_mask
);
2153 if (aop
== 0 && sz
== 0 && Z
== 0 && W
== 0)
2154 return DREG_MASK (reg
);
2155 else if (aop
== 0 && sz
== 0 && Z
== 1 && W
== 0)
2157 else if (aop
== 0 && sz
== 1 && Z
== 0 && W
== 0)
2158 return DREG_MASK (reg
);
2159 else if (aop
== 0 && sz
== 1 && Z
== 1 && W
== 0)
2160 return DREG_MASK (reg
);
2161 else if (aop
== 0 && sz
== 2 && Z
== 0 && W
== 0)
2162 return DREG_MASK (reg
);
2163 else if (aop
== 0 && sz
== 2 && Z
== 1 && W
== 0)
2164 return DREG_MASK (reg
);
2165 else if (aop
== 1 && sz
== 0 && Z
== 0 && W
== 0)
2166 return DREG_MASK (reg
);
2167 else if (aop
== 1 && sz
== 0 && Z
== 1 && W
== 0)
2169 else if (aop
== 1 && sz
== 1 && Z
== 0 && W
== 0)
2170 return DREG_MASK (reg
);
2171 else if (aop
== 1 && sz
== 1 && Z
== 1 && W
== 0)
2172 return DREG_MASK (reg
);
2173 else if (aop
== 1 && sz
== 2 && Z
== 0 && W
== 0)
2174 return DREG_MASK (reg
);
2175 else if (aop
== 1 && sz
== 2 && Z
== 1 && W
== 0)
2176 return DREG_MASK (reg
);
2177 else if (aop
== 2 && sz
== 0 && Z
== 0 && W
== 0)
2178 return DREG_MASK (reg
);
2179 else if (aop
== 2 && sz
== 0 && Z
== 1 && W
== 0)
2181 else if (aop
== 2 && sz
== 1 && Z
== 0 && W
== 0)
2182 return DREG_MASK (reg
);
2183 else if (aop
== 2 && sz
== 1 && Z
== 1 && W
== 0)
2184 return DREG_MASK (reg
);
2185 else if (aop
== 2 && sz
== 2 && Z
== 0 && W
== 0)
2186 return DREG_MASK (reg
);
2187 else if (aop
== 2 && sz
== 2 && Z
== 1 && W
== 0)
2188 return DREG_MASK (reg
);
2189 else if (aop
== 0 && sz
== 0 && Z
== 0 && W
== 1)
2191 else if (aop
== 0 && sz
== 0 && Z
== 1 && W
== 1)
2193 else if (aop
== 0 && sz
== 1 && Z
== 0 && W
== 1)
2195 else if (aop
== 0 && sz
== 2 && Z
== 0 && W
== 1)
2197 else if (aop
== 1 && sz
== 0 && Z
== 0 && W
== 1)
2199 else if (aop
== 1 && sz
== 0 && Z
== 1 && W
== 1)
2201 else if (aop
== 1 && sz
== 1 && Z
== 0 && W
== 1)
2203 else if (aop
== 1 && sz
== 2 && Z
== 0 && W
== 1)
2205 else if (aop
== 2 && sz
== 0 && Z
== 0 && W
== 1)
2207 else if (aop
== 2 && sz
== 0 && Z
== 1 && W
== 1)
2209 else if (aop
== 2 && sz
== 1 && Z
== 0 && W
== 1)
2211 else if (aop
== 2 && sz
== 2 && Z
== 0 && W
== 1)
2218 decode_LDSTiiFP_0 (int iw0
)
2221 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2222 | 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........|
2223 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2224 int reg
= ((iw0
>> LDSTiiFP_reg_bits
) & LDSTiiFP_reg_mask
);
2225 int W
= ((iw0
>> LDSTiiFP_W_bits
) & LDSTiiFP_W_mask
);
2228 return reg
< 8 ? DREG_MASK (reg
) : 0;
2234 decode_LDSTii_0 (int iw0
)
2237 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2238 | 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......|
2239 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2240 int reg
= ((iw0
>> LDSTii_reg_bit
) & LDSTii_reg_mask
);
2241 int opc
= ((iw0
>> LDSTii_op_bit
) & LDSTii_op_mask
);
2242 int W
= ((iw0
>> LDSTii_W_bit
) & LDSTii_W_mask
);
2244 if (W
== 0 && opc
!= 3)
2245 return DREG_MASK (reg
);
2246 else if (W
== 0 && opc
== 3)
2248 else if (W
== 1 && opc
== 0)
2250 else if (W
== 1 && opc
== 1)
2252 else if (W
== 1 && opc
== 3)
2259 decode_dsp32mac_0 (int iw0
, int iw1
)
2263 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2264 | 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...|
2265 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2266 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2267 int op1
= ((iw0
>> (DSP32Mac_op1_bits
- 16)) & DSP32Mac_op1_mask
);
2268 int w1
= ((iw0
>> (DSP32Mac_w1_bits
- 16)) & DSP32Mac_w1_mask
);
2269 int P
= ((iw0
>> (DSP32Mac_p_bits
- 16)) & DSP32Mac_p_mask
);
2270 int mmod
= ((iw0
>> (DSP32Mac_mmod_bits
- 16)) & DSP32Mac_mmod_mask
);
2271 int w0
= ((iw1
>> DSP32Mac_w0_bits
) & DSP32Mac_w0_mask
);
2272 int MM
= ((iw1
>> DSP32Mac_MM_bits
) & DSP32Mac_MM_mask
);
2273 int dst
= ((iw1
>> DSP32Mac_dst_bits
) & DSP32Mac_dst_mask
);
2274 int op0
= ((iw1
>> DSP32Mac_op0_bits
) & DSP32Mac_op0_mask
);
2276 if (w0
== 0 && w1
== 0 && op1
== 3 && op0
== 3)
2282 if ((w1
|| w0
) && mmod
== M_W32
)
2285 if (((1 << mmod
) & (P
? 0x131b : 0x1b5f)) == 0)
2288 if (w1
== 1 || op1
!= 3)
2293 return DREG_MASK (dst
+ 1);
2295 return DREGH_MASK (dst
);
2299 if (w0
== 1 || op0
!= 3)
2304 return DREG_MASK (dst
);
2306 return DREGL_MASK (dst
);
2314 decode_dsp32mult_0 (int iw0
, int iw1
)
2317 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2318 | 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...|
2319 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2320 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2321 int w1
= ((iw0
>> (DSP32Mac_w1_bits
- 16)) & DSP32Mac_w1_mask
);
2322 int P
= ((iw0
>> (DSP32Mac_p_bits
- 16)) & DSP32Mac_p_mask
);
2323 int mmod
= ((iw0
>> (DSP32Mac_mmod_bits
- 16)) & DSP32Mac_mmod_mask
);
2324 int w0
= ((iw1
>> DSP32Mac_w0_bits
) & DSP32Mac_w0_mask
);
2325 int dst
= ((iw1
>> DSP32Mac_dst_bits
) & DSP32Mac_dst_mask
);
2328 if (w1
== 0 && w0
== 0)
2331 if (((1 << mmod
) & (P
? 0x313 : 0x1b57)) == 0)
2337 return DREG_MASK (dst
| 1);
2339 return DREGH_MASK (dst
);
2345 return DREG_MASK (dst
);
2347 return DREGL_MASK (dst
);
2354 decode_dsp32alu_0 (int iw0
, int iw1
)
2357 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2358 | 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............|
2359 |.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......|
2360 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2361 int s
= ((iw1
>> DSP32Alu_s_bits
) & DSP32Alu_s_mask
);
2362 int x
= ((iw1
>> DSP32Alu_x_bits
) & DSP32Alu_x_mask
);
2363 int aop
= ((iw1
>> DSP32Alu_aop_bits
) & DSP32Alu_aop_mask
);
2364 int dst0
= ((iw1
>> DSP32Alu_dst0_bits
) & DSP32Alu_dst0_mask
);
2365 int dst1
= ((iw1
>> DSP32Alu_dst1_bits
) & DSP32Alu_dst1_mask
);
2366 int HL
= ((iw0
>> (DSP32Alu_HL_bits
- 16)) & DSP32Alu_HL_mask
);
2367 int aopcde
= ((iw0
>> (DSP32Alu_aopcde_bits
- 16)) & DSP32Alu_aopcde_mask
);
2369 if (aop
== 0 && aopcde
== 9 && s
== 0)
2371 else if (aop
== 2 && aopcde
== 9 && HL
== 0 && s
== 0)
2373 else if (aop
>= x
* 2 && aopcde
== 5)
2374 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2375 else if (HL
== 0 && aopcde
== 2)
2376 return DREGL_MASK (dst0
);
2377 else if (HL
== 1 && aopcde
== 2)
2378 return DREGH_MASK (dst0
);
2379 else if (HL
== 0 && aopcde
== 3)
2380 return DREGL_MASK (dst0
);
2381 else if (HL
== 1 && aopcde
== 3)
2382 return DREGH_MASK (dst0
);
2384 else if (aop
== 0 && aopcde
== 9 && s
== 1)
2386 else if (aop
== 1 && aopcde
== 9 && s
== 0)
2388 else if (aop
== 2 && aopcde
== 9 && s
== 1)
2390 else if (aop
== 3 && aopcde
== 9 && s
== 0)
2392 else if (aopcde
== 8)
2394 else if (aop
== 0 && aopcde
== 11)
2395 return DREG_MASK (dst0
);
2396 else if (aop
== 1 && aopcde
== 11)
2397 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2398 else if (aopcde
== 11)
2400 else if (aopcde
== 22)
2401 return DREG_MASK (dst0
);
2403 else if ((aop
== 0 || aop
== 1) && aopcde
== 14)
2405 else if (aop
== 3 && HL
== 0 && aopcde
== 14)
2408 else if (aop
== 3 && HL
== 0 && aopcde
== 15)
2409 return DREG_MASK (dst0
);
2411 else if (aop
== 1 && aopcde
== 16)
2414 else if (aop
== 0 && aopcde
== 16)
2417 else if (aop
== 3 && HL
== 0 && aopcde
== 16)
2420 else if (aop
== 3 && HL
== 0 && aopcde
== 7)
2421 return DREG_MASK (dst0
);
2422 else if ((aop
== 0 || aop
== 1 || aop
== 2) && aopcde
== 7)
2423 return DREG_MASK (dst0
);
2425 else if (aop
== 0 && aopcde
== 12)
2426 return DREG_MASK (dst0
);
2427 else if (aop
== 1 && aopcde
== 12)
2428 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2429 else if (aop
== 3 && aopcde
== 12)
2430 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2432 else if (aopcde
== 0)
2433 return DREG_MASK (dst0
);
2434 else if (aopcde
== 1)
2435 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2437 else if (aop
== 0 && aopcde
== 10)
2438 return DREGL_MASK (dst0
);
2439 else if (aop
== 1 && aopcde
== 10)
2440 return DREGL_MASK (dst0
);
2442 else if ((aop
== 1 || aop
== 0) && aopcde
== 4)
2443 return DREG_MASK (dst0
);
2444 else if (aop
== 2 && aopcde
== 4)
2445 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2447 else if (aop
== 0 && aopcde
== 17)
2448 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2449 else if (aop
== 1 && aopcde
== 17)
2450 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2451 else if (aop
== 0 && aopcde
== 18)
2453 else if (aop
== 3 && aopcde
== 18)
2456 else if ((aop
== 0 || aop
== 1 || aop
== 2) && aopcde
== 6)
2457 return DREG_MASK (dst0
);
2459 else if ((aop
== 0 || aop
== 1) && aopcde
== 20)
2460 return DREG_MASK (dst0
);
2462 else if ((aop
== 0 || aop
== 1) && aopcde
== 21)
2463 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2465 else if (aop
== 0 && aopcde
== 23 && HL
== 1)
2466 return DREG_MASK (dst0
);
2467 else if (aop
== 0 && aopcde
== 23 && HL
== 0)
2468 return DREG_MASK (dst0
);
2470 else if (aop
== 0 && aopcde
== 24)
2471 return DREG_MASK (dst0
);
2472 else if (aop
== 1 && aopcde
== 24)
2473 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2474 else if (aopcde
== 13)
2475 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2483 decode_dsp32shift_0 (int iw0
, int iw1
)
2486 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2487 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............|
2488 |.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......|
2489 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2490 int HLs
= ((iw1
>> DSP32Shift_HLs_bits
) & DSP32Shift_HLs_mask
);
2491 int sop
= ((iw1
>> DSP32Shift_sop_bits
) & DSP32Shift_sop_mask
);
2492 int src0
= ((iw1
>> DSP32Shift_src0_bits
) & DSP32Shift_src0_mask
);
2493 int src1
= ((iw1
>> DSP32Shift_src1_bits
) & DSP32Shift_src1_mask
);
2494 int dst0
= ((iw1
>> DSP32Shift_dst0_bits
) & DSP32Shift_dst0_mask
);
2495 int sopcde
= ((iw0
>> (DSP32Shift_sopcde_bits
- 16)) & DSP32Shift_sopcde_mask
);
2497 if (sop
== 0 && sopcde
== 0)
2498 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2499 else if (sop
== 1 && sopcde
== 0)
2500 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2501 else if (sop
== 2 && sopcde
== 0)
2502 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2503 else if (sop
== 0 && sopcde
== 3)
2505 else if (sop
== 1 && sopcde
== 3)
2507 else if (sop
== 2 && sopcde
== 3)
2509 else if (sop
== 3 && sopcde
== 3)
2510 return DREG_MASK (dst0
);
2511 else if (sop
== 0 && sopcde
== 1)
2512 return DREG_MASK (dst0
);
2513 else if (sop
== 1 && sopcde
== 1)
2514 return DREG_MASK (dst0
);
2515 else if (sop
== 2 && sopcde
== 1)
2516 return DREG_MASK (dst0
);
2517 else if (sopcde
== 2)
2518 return DREG_MASK (dst0
);
2519 else if (sopcde
== 4)
2520 return DREG_MASK (dst0
);
2521 else if (sop
== 0 && sopcde
== 5)
2522 return DREGL_MASK (dst0
);
2523 else if (sop
== 1 && sopcde
== 5)
2524 return DREGL_MASK (dst0
);
2525 else if (sop
== 2 && sopcde
== 5)
2526 return DREGL_MASK (dst0
);
2527 else if (sop
== 0 && sopcde
== 6)
2528 return DREGL_MASK (dst0
);
2529 else if (sop
== 1 && sopcde
== 6)
2530 return DREGL_MASK (dst0
);
2531 else if (sop
== 3 && sopcde
== 6)
2532 return DREGL_MASK (dst0
);
2533 else if (sop
== 0 && sopcde
== 7)
2534 return DREGL_MASK (dst0
);
2535 else if (sop
== 1 && sopcde
== 7)
2536 return DREGL_MASK (dst0
);
2537 else if (sop
== 2 && sopcde
== 7)
2538 return DREGL_MASK (dst0
);
2539 else if (sop
== 3 && sopcde
== 7)
2540 return DREGL_MASK (dst0
);
2541 else if (sop
== 0 && sopcde
== 8)
2542 return DREG_MASK (src0
) | DREG_MASK (src1
);
2545 OUTS (outf
, "BITMUX (");
2546 OUTS (outf
, dregs (src0
));
2548 OUTS (outf
, dregs (src1
));
2549 OUTS (outf
, ", A0) (ASR)");
2552 else if (sop
== 1 && sopcde
== 8)
2553 return DREG_MASK (src0
) | DREG_MASK (src1
);
2556 OUTS (outf
, "BITMUX (");
2557 OUTS (outf
, dregs (src0
));
2559 OUTS (outf
, dregs (src1
));
2560 OUTS (outf
, ", A0) (ASL)");
2563 else if (sopcde
== 9)
2564 return sop
< 2 ? DREGL_MASK (dst0
) : DREG_MASK (dst0
);
2565 else if (sopcde
== 10)
2566 return DREG_MASK (dst0
);
2567 else if (sop
== 0 && sopcde
== 11)
2568 return DREGL_MASK (dst0
);
2569 else if (sop
== 1 && sopcde
== 11)
2570 return DREGL_MASK (dst0
);
2571 else if (sop
== 0 && sopcde
== 12)
2573 else if (sop
== 1 && sopcde
== 12)
2574 return DREGL_MASK (dst0
);
2575 else if (sop
== 0 && sopcde
== 13)
2576 return DREG_MASK (dst0
);
2577 else if (sop
== 1 && sopcde
== 13)
2578 return DREG_MASK (dst0
);
2579 else if (sop
== 2 && sopcde
== 13)
2580 return DREG_MASK (dst0
);
2586 decode_dsp32shiftimm_0 (int iw0
, int iw1
)
2589 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2590 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............|
2591 |.sop...|.HLs...|.dst0......|.immag.................|.src1......|
2592 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2593 int sop
= ((iw1
>> DSP32ShiftImm_sop_bits
) & DSP32ShiftImm_sop_mask
);
2594 int bit8
= ((iw1
>> 8) & 0x1);
2595 int dst0
= ((iw1
>> DSP32ShiftImm_dst0_bits
) & DSP32ShiftImm_dst0_mask
);
2596 int sopcde
= ((iw0
>> (DSP32ShiftImm_sopcde_bits
- 16)) & DSP32ShiftImm_sopcde_mask
);
2597 int HLs
= ((iw1
>> DSP32ShiftImm_HLs_bits
) & DSP32ShiftImm_HLs_mask
);
2600 if (sop
== 0 && sopcde
== 0)
2601 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2602 else if (sop
== 1 && sopcde
== 0 && bit8
== 0)
2603 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2604 else if (sop
== 1 && sopcde
== 0 && bit8
== 1)
2605 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2606 else if (sop
== 2 && sopcde
== 0 && bit8
== 0)
2607 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2608 else if (sop
== 2 && sopcde
== 0 && bit8
== 1)
2609 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2610 else if (sop
== 2 && sopcde
== 3 && HLs
== 1)
2612 else if (sop
== 0 && sopcde
== 3 && HLs
== 0 && bit8
== 0)
2614 else if (sop
== 0 && sopcde
== 3 && HLs
== 0 && bit8
== 1)
2616 else if (sop
== 0 && sopcde
== 3 && HLs
== 1 && bit8
== 0)
2618 else if (sop
== 0 && sopcde
== 3 && HLs
== 1 && bit8
== 1)
2620 else if (sop
== 1 && sopcde
== 3 && HLs
== 0)
2622 else if (sop
== 1 && sopcde
== 3 && HLs
== 1)
2624 else if (sop
== 2 && sopcde
== 3 && HLs
== 0)
2626 else if (sop
== 1 && sopcde
== 1 && bit8
== 0)
2627 return DREG_MASK (dst0
);
2628 else if (sop
== 1 && sopcde
== 1 && bit8
== 1)
2629 return DREG_MASK (dst0
);
2630 else if (sop
== 2 && sopcde
== 1 && bit8
== 1)
2631 return DREG_MASK (dst0
);
2632 else if (sop
== 2 && sopcde
== 1 && bit8
== 0)
2633 return DREG_MASK (dst0
);
2634 else if (sop
== 0 && sopcde
== 1)
2635 return DREG_MASK (dst0
);
2636 else if (sop
== 1 && sopcde
== 2)
2637 return DREG_MASK (dst0
);
2638 else if (sop
== 2 && sopcde
== 2 && bit8
== 1)
2639 return DREG_MASK (dst0
);
2640 else if (sop
== 2 && sopcde
== 2 && bit8
== 0)
2641 return DREG_MASK (dst0
);
2642 else if (sop
== 3 && sopcde
== 2)
2643 return DREG_MASK (dst0
);
2644 else if (sop
== 0 && sopcde
== 2)
2645 return DREG_MASK (dst0
);
2651 insn_regmask (int iw0
, int iw1
)
2653 if ((iw0
& 0xf7ff) == 0xc003 && iw1
== 0x1800)
2654 return 0; /* MNOP */
2655 else if ((iw0
& 0xff00) == 0x0000)
2656 return decode_ProgCtrl_0 (iw0
);
2657 else if ((iw0
& 0xffc0) == 0x0240)
2659 else if ((iw0
& 0xff80) == 0x0100)
2661 else if ((iw0
& 0xfe00) == 0x0400)
2663 else if ((iw0
& 0xfe00) == 0x0600)
2665 else if ((iw0
& 0xf800) == 0x0800)
2667 else if ((iw0
& 0xffe0) == 0x0200)
2669 else if ((iw0
& 0xff00) == 0x0300)
2671 else if ((iw0
& 0xf000) == 0x1000)
2673 else if ((iw0
& 0xf000) == 0x2000)
2675 else if ((iw0
& 0xf000) == 0x3000)
2677 else if ((iw0
& 0xfc00) == 0x4000)
2679 else if ((iw0
& 0xfe00) == 0x4400)
2681 else if ((iw0
& 0xf800) == 0x4800)
2683 else if ((iw0
& 0xf000) == 0x5000)
2685 else if ((iw0
& 0xf800) == 0x6000)
2687 else if ((iw0
& 0xf800) == 0x6800)
2689 else if ((iw0
& 0xf000) == 0x8000)
2690 return decode_LDSTpmod_0 (iw0
);
2691 else if ((iw0
& 0xff60) == 0x9e60)
2692 return decode_dagMODim_0 (iw0
);
2693 else if ((iw0
& 0xfff0) == 0x9f60)
2694 return decode_dagMODik_0 (iw0
);
2695 else if ((iw0
& 0xfc00) == 0x9c00)
2696 return decode_dspLDST_0 (iw0
);
2697 else if ((iw0
& 0xf000) == 0x9000)
2698 return decode_LDST_0 (iw0
);
2699 else if ((iw0
& 0xfc00) == 0xb800)
2700 return decode_LDSTiiFP_0 (iw0
);
2701 else if ((iw0
& 0xe000) == 0xA000)
2702 return decode_LDSTii_0 (iw0
);
2703 else if ((iw0
& 0xff80) == 0xe080 && (iw1
& 0x0C00) == 0x0000)
2705 else if ((iw0
& 0xff00) == 0xe100 && (iw1
& 0x0000) == 0x0000)
2707 else if ((iw0
& 0xfe00) == 0xe200 && (iw1
& 0x0000) == 0x0000)
2709 else if ((iw0
& 0xfc00) == 0xe400 && (iw1
& 0x0000) == 0x0000)
2711 else if ((iw0
& 0xfffe) == 0xe800 && (iw1
& 0x0000) == 0x0000)
2713 else if ((iw0
& 0xf600) == 0xc000 && (iw1
& 0x0000) == 0x0000)
2714 return decode_dsp32mac_0 (iw0
, iw1
);
2715 else if ((iw0
& 0xf600) == 0xc200 && (iw1
& 0x0000) == 0x0000)
2716 return decode_dsp32mult_0 (iw0
, iw1
);
2717 else if ((iw0
& 0xf7c0) == 0xc400 && (iw1
& 0x0000) == 0x0000)
2718 return decode_dsp32alu_0 (iw0
, iw1
);
2719 else if ((iw0
& 0xf780) == 0xc600 && (iw1
& 0x01c0) == 0x0000)
2720 return decode_dsp32shift_0 (iw0
, iw1
);
2721 else if ((iw0
& 0xf780) == 0xc680 && (iw1
& 0x0000) == 0x0000)
2722 return decode_dsp32shiftimm_0 (iw0
, iw1
);
2723 else if ((iw0
& 0xff00) == 0xf800)
2725 else if ((iw0
& 0xFFC0) == 0xf000 && (iw1
& 0x0000) == 0x0000)