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 ();
1823 /* Multiple instruction generation. */
1826 bfin_gen_multi_instr (INSTR_T dsp32
, INSTR_T dsp16_grp1
, INSTR_T dsp16_grp2
)
1830 /* If it's a 0, convert into MNOP. */
1834 SET_MULTI_INSTRUCTION_BIT (dsp32
);
1838 dsp32
= gencode (0xc803);
1839 walk
= gencode (0x1800);
1845 dsp16_grp1
= gencode (0x0000);
1850 dsp16_grp2
= gencode (0x0000);
1853 walk
->next
= dsp16_grp1
;
1854 dsp16_grp1
->next
= dsp16_grp2
;
1855 dsp16_grp2
->next
= NULL_CODE
;
1861 bfin_gen_loop (Expr_Node
*exp
, REG_T reg
, int rop
, REG_T preg
)
1863 const char *loopsym
;
1864 char *lbeginsym
, *lendsym
;
1865 Expr_Node_Value lbeginval
, lendval
;
1866 Expr_Node
*lbegin
, *lend
;
1868 loopsym
= exp
->value
.s_value
;
1869 lbeginsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__BEGIN") + 5);
1870 lendsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__END") + 5);
1875 strcat (lbeginsym
, "L$L$");
1876 strcat (lbeginsym
, loopsym
);
1877 strcat (lbeginsym
, "__BEGIN");
1879 strcat (lendsym
, "L$L$");
1880 strcat (lendsym
, loopsym
);
1881 strcat (lendsym
, "__END");
1883 lbeginval
.s_value
= lbeginsym
;
1884 lendval
.s_value
= lendsym
;
1886 lbegin
= Expr_Node_Create (Expr_Node_Reloc
, lbeginval
, NULL
, NULL
);
1887 lend
= Expr_Node_Create (Expr_Node_Reloc
, lendval
, NULL
, NULL
);
1889 symbol_remove (symbol_find (loopsym
), &symbol_rootP
, &symbol_lastP
);
1891 return bfin_gen_loopsetup(lbegin
, reg
, rop
, lend
, preg
);
1895 bfin_loop_beginend (Expr_Node
*exp
, int begin
)
1897 const char *loopsym
;
1900 const char *suffix
= begin
? "__BEGIN" : "__END";
1902 loopsym
= exp
->value
.s_value
;
1903 label_name
= (char *) xmalloc (strlen (loopsym
) + strlen (suffix
) + 5);
1907 strcat (label_name
, "L$L$");
1908 strcat (label_name
, loopsym
);
1909 strcat (label_name
, suffix
);
1911 linelabel
= colon (label_name
);
1913 /* LOOP_END follows the last instruction in the loop.
1914 Adjust label address. */
1916 ((struct local_symbol
*) linelabel
)->lsy_value
-= last_insn_size
;
1920 bfin_eol_in_insn (char *line
)
1922 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1929 /* A semi-colon followed by a newline is always the end of a line. */
1930 if (line
[-1] == ';')
1933 if (line
[-1] == '|')
1936 /* If the || is on the next line, there might be leading whitespace. */
1938 while (*temp
== ' ' || *temp
== '\t') temp
++;
1947 bfin_start_label (char *s
, char *ptr
)
1951 if (*s
== '(' || *s
== '[')
1960 bfin_force_relocation (struct fix
*fixp
)
1962 if (fixp
->fx_r_type
==BFD_RELOC_BFIN_16_LOW
1963 || fixp
->fx_r_type
== BFD_RELOC_BFIN_16_HIGH
)
1966 return generic_force_reloc (fixp
);
1969 /* This is a stripped down version of the disassembler. The only thing it
1970 does is return a mask of registers modified by an instruction. Only
1971 instructions that can occur in a parallel-issue bundle are handled, and
1972 only the registers that can cause a conflict are recorded. */
1974 #define DREG_MASK(n) (0x101 << (n))
1975 #define DREGH_MASK(n) (0x100 << (n))
1976 #define DREGL_MASK(n) (0x001 << (n))
1977 #define IREG_MASK(n) (1 << ((n) + 16))
1980 decode_ProgCtrl_0 (int iw0
)
1988 decode_LDSTpmod_0 (int iw0
)
1991 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
1992 | 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......|
1993 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
1994 int W
= ((iw0
>> LDSTpmod_W_bits
) & LDSTpmod_W_mask
);
1995 int aop
= ((iw0
>> LDSTpmod_aop_bits
) & LDSTpmod_aop_mask
);
1996 int idx
= ((iw0
>> LDSTpmod_idx_bits
) & LDSTpmod_idx_mask
);
1997 int ptr
= ((iw0
>> LDSTpmod_ptr_bits
) & LDSTpmod_ptr_mask
);
1998 int reg
= ((iw0
>> LDSTpmod_reg_bits
) & LDSTpmod_reg_mask
);
2000 if (aop
== 1 && W
== 0 && idx
== ptr
)
2001 return DREGL_MASK (reg
);
2002 else if (aop
== 2 && W
== 0 && idx
== ptr
)
2003 return DREGH_MASK (reg
);
2004 else if (aop
== 1 && W
== 1 && idx
== ptr
)
2006 else if (aop
== 2 && W
== 1 && idx
== ptr
)
2008 else if (aop
== 0 && W
== 0)
2009 return DREG_MASK (reg
);
2010 else if (aop
== 1 && W
== 0)
2011 return DREGL_MASK (reg
);
2012 else if (aop
== 2 && W
== 0)
2013 return DREGH_MASK (reg
);
2014 else if (aop
== 3 && W
== 0)
2015 return DREG_MASK (reg
);
2016 else if (aop
== 3 && W
== 1)
2017 return DREG_MASK (reg
);
2018 else if (aop
== 0 && W
== 1)
2020 else if (aop
== 1 && W
== 1)
2022 else if (aop
== 2 && W
== 1)
2031 decode_dagMODim_0 (int iw0
)
2034 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2035 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....|
2036 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2037 int i
= ((iw0
>> DagMODim_i_bits
) & DagMODim_i_mask
);
2038 int opc
= ((iw0
>> DagMODim_op_bits
) & DagMODim_op_mask
);
2040 if (opc
== 0 || opc
== 1)
2041 return IREG_MASK (i
);
2049 decode_dagMODik_0 (int iw0
)
2052 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2053 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....|
2054 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2055 int i
= ((iw0
>> DagMODik_i_bits
) & DagMODik_i_mask
);
2056 return IREG_MASK (i
);
2061 decode_dspLDST_0 (int iw0
)
2064 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2065 | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......|
2066 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2067 int i
= ((iw0
>> DspLDST_i_bits
) & DspLDST_i_mask
);
2068 int m
= ((iw0
>> DspLDST_m_bits
) & DspLDST_m_mask
);
2069 int W
= ((iw0
>> DspLDST_W_bits
) & DspLDST_W_mask
);
2070 int aop
= ((iw0
>> DspLDST_aop_bits
) & DspLDST_aop_mask
);
2071 int reg
= ((iw0
>> DspLDST_reg_bits
) & DspLDST_reg_mask
);
2073 if (aop
== 0 && W
== 0 && m
== 0)
2074 return DREG_MASK (reg
) | IREG_MASK (i
);
2075 else if (aop
== 0 && W
== 0 && m
== 1)
2076 return DREGL_MASK (reg
) | IREG_MASK (i
);
2077 else if (aop
== 0 && W
== 0 && m
== 2)
2078 return DREGH_MASK (reg
) | IREG_MASK (i
);
2079 else if (aop
== 1 && W
== 0 && m
== 0)
2080 return DREG_MASK (reg
) | IREG_MASK (i
);
2081 else if (aop
== 1 && W
== 0 && m
== 1)
2082 return DREGL_MASK (reg
) | IREG_MASK (i
);
2083 else if (aop
== 1 && W
== 0 && m
== 2)
2084 return DREGH_MASK (reg
) | IREG_MASK (i
);
2085 else if (aop
== 2 && W
== 0 && m
== 0)
2086 return DREG_MASK (reg
);
2087 else if (aop
== 2 && W
== 0 && m
== 1)
2088 return DREGL_MASK (reg
);
2089 else if (aop
== 2 && W
== 0 && m
== 2)
2090 return DREGH_MASK (reg
);
2091 else if (aop
== 0 && W
== 1 && m
== 0)
2092 return IREG_MASK (i
);
2093 else if (aop
== 0 && W
== 1 && m
== 1)
2094 return IREG_MASK (i
);
2095 else if (aop
== 0 && W
== 1 && m
== 2)
2096 return IREG_MASK (i
);
2097 else if (aop
== 1 && W
== 1 && m
== 0)
2098 return IREG_MASK (i
);
2099 else if (aop
== 1 && W
== 1 && m
== 1)
2100 return IREG_MASK (i
);
2101 else if (aop
== 1 && W
== 1 && m
== 2)
2102 return IREG_MASK (i
);
2103 else if (aop
== 2 && W
== 1 && m
== 0)
2105 else if (aop
== 2 && W
== 1 && m
== 1)
2107 else if (aop
== 2 && W
== 1 && m
== 2)
2109 else if (aop
== 3 && W
== 0)
2110 return DREG_MASK (reg
) | IREG_MASK (i
);
2111 else if (aop
== 3 && W
== 1)
2112 return IREG_MASK (i
);
2119 decode_LDST_0 (int iw0
)
2122 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2123 | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......|
2124 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2125 int Z
= ((iw0
>> LDST_Z_bits
) & LDST_Z_mask
);
2126 int W
= ((iw0
>> LDST_W_bits
) & LDST_W_mask
);
2127 int sz
= ((iw0
>> LDST_sz_bits
) & LDST_sz_mask
);
2128 int aop
= ((iw0
>> LDST_aop_bits
) & LDST_aop_mask
);
2129 int reg
= ((iw0
>> LDST_reg_bits
) & LDST_reg_mask
);
2131 if (aop
== 0 && sz
== 0 && Z
== 0 && W
== 0)
2132 return DREG_MASK (reg
);
2133 else if (aop
== 0 && sz
== 0 && Z
== 1 && W
== 0)
2135 else if (aop
== 0 && sz
== 1 && Z
== 0 && W
== 0)
2136 return DREG_MASK (reg
);
2137 else if (aop
== 0 && sz
== 1 && Z
== 1 && W
== 0)
2138 return DREG_MASK (reg
);
2139 else if (aop
== 0 && sz
== 2 && Z
== 0 && W
== 0)
2140 return DREG_MASK (reg
);
2141 else if (aop
== 0 && sz
== 2 && Z
== 1 && W
== 0)
2142 return DREG_MASK (reg
);
2143 else if (aop
== 1 && sz
== 0 && Z
== 0 && W
== 0)
2144 return DREG_MASK (reg
);
2145 else if (aop
== 1 && sz
== 0 && Z
== 1 && W
== 0)
2147 else if (aop
== 1 && sz
== 1 && Z
== 0 && W
== 0)
2148 return DREG_MASK (reg
);
2149 else if (aop
== 1 && sz
== 1 && Z
== 1 && W
== 0)
2150 return DREG_MASK (reg
);
2151 else if (aop
== 1 && sz
== 2 && Z
== 0 && W
== 0)
2152 return DREG_MASK (reg
);
2153 else if (aop
== 1 && sz
== 2 && Z
== 1 && W
== 0)
2154 return DREG_MASK (reg
);
2155 else if (aop
== 2 && sz
== 0 && Z
== 0 && W
== 0)
2156 return DREG_MASK (reg
);
2157 else if (aop
== 2 && sz
== 0 && Z
== 1 && W
== 0)
2159 else if (aop
== 2 && sz
== 1 && Z
== 0 && W
== 0)
2160 return DREG_MASK (reg
);
2161 else if (aop
== 2 && sz
== 1 && Z
== 1 && W
== 0)
2162 return DREG_MASK (reg
);
2163 else if (aop
== 2 && sz
== 2 && Z
== 0 && W
== 0)
2164 return DREG_MASK (reg
);
2165 else if (aop
== 2 && sz
== 2 && Z
== 1 && W
== 0)
2166 return DREG_MASK (reg
);
2167 else if (aop
== 0 && sz
== 0 && Z
== 0 && W
== 1)
2169 else if (aop
== 0 && sz
== 0 && Z
== 1 && W
== 1)
2171 else if (aop
== 0 && sz
== 1 && Z
== 0 && W
== 1)
2173 else if (aop
== 0 && sz
== 2 && Z
== 0 && W
== 1)
2175 else if (aop
== 1 && sz
== 0 && Z
== 0 && W
== 1)
2177 else if (aop
== 1 && sz
== 0 && Z
== 1 && W
== 1)
2179 else if (aop
== 1 && sz
== 1 && Z
== 0 && W
== 1)
2181 else if (aop
== 1 && sz
== 2 && Z
== 0 && W
== 1)
2183 else if (aop
== 2 && sz
== 0 && Z
== 0 && W
== 1)
2185 else if (aop
== 2 && sz
== 0 && Z
== 1 && W
== 1)
2187 else if (aop
== 2 && sz
== 1 && Z
== 0 && W
== 1)
2189 else if (aop
== 2 && sz
== 2 && Z
== 0 && W
== 1)
2196 decode_LDSTiiFP_0 (int iw0
)
2199 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2200 | 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........|
2201 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2202 int reg
= ((iw0
>> LDSTiiFP_reg_bits
) & LDSTiiFP_reg_mask
);
2203 int W
= ((iw0
>> LDSTiiFP_W_bits
) & LDSTiiFP_W_mask
);
2206 return reg
< 8 ? DREG_MASK (reg
) : 0;
2212 decode_LDSTii_0 (int iw0
)
2215 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2216 | 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......|
2217 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2218 int reg
= ((iw0
>> LDSTii_reg_bit
) & LDSTii_reg_mask
);
2219 int opc
= ((iw0
>> LDSTii_op_bit
) & LDSTii_op_mask
);
2220 int W
= ((iw0
>> LDSTii_W_bit
) & LDSTii_W_mask
);
2222 if (W
== 0 && opc
!= 3)
2223 return DREG_MASK (reg
);
2224 else if (W
== 0 && opc
== 3)
2226 else if (W
== 1 && opc
== 0)
2228 else if (W
== 1 && opc
== 1)
2230 else if (W
== 1 && opc
== 3)
2237 decode_dsp32mac_0 (int iw0
, int iw1
)
2241 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2242 | 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...|
2243 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2244 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2245 int op1
= ((iw0
>> (DSP32Mac_op1_bits
- 16)) & DSP32Mac_op1_mask
);
2246 int w1
= ((iw0
>> (DSP32Mac_w1_bits
- 16)) & DSP32Mac_w1_mask
);
2247 int P
= ((iw0
>> (DSP32Mac_p_bits
- 16)) & DSP32Mac_p_mask
);
2248 int mmod
= ((iw0
>> (DSP32Mac_mmod_bits
- 16)) & DSP32Mac_mmod_mask
);
2249 int w0
= ((iw1
>> DSP32Mac_w0_bits
) & DSP32Mac_w0_mask
);
2250 int MM
= ((iw1
>> DSP32Mac_MM_bits
) & DSP32Mac_MM_mask
);
2251 int dst
= ((iw1
>> DSP32Mac_dst_bits
) & DSP32Mac_dst_mask
);
2252 int op0
= ((iw1
>> DSP32Mac_op0_bits
) & DSP32Mac_op0_mask
);
2254 if (w0
== 0 && w1
== 0 && op1
== 3 && op0
== 3)
2260 if ((w1
|| w0
) && mmod
== M_W32
)
2263 if (((1 << mmod
) & (P
? 0x131b : 0x1b5f)) == 0)
2266 if (w1
== 1 || op1
!= 3)
2271 return DREG_MASK (dst
+ 1);
2273 return DREGH_MASK (dst
);
2277 if (w0
== 1 || op0
!= 3)
2282 return DREG_MASK (dst
);
2284 return DREGL_MASK (dst
);
2292 decode_dsp32mult_0 (int iw0
, int iw1
)
2295 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2296 | 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...|
2297 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2298 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2299 int w1
= ((iw0
>> (DSP32Mac_w1_bits
- 16)) & DSP32Mac_w1_mask
);
2300 int P
= ((iw0
>> (DSP32Mac_p_bits
- 16)) & DSP32Mac_p_mask
);
2301 int mmod
= ((iw0
>> (DSP32Mac_mmod_bits
- 16)) & DSP32Mac_mmod_mask
);
2302 int w0
= ((iw1
>> DSP32Mac_w0_bits
) & DSP32Mac_w0_mask
);
2303 int dst
= ((iw1
>> DSP32Mac_dst_bits
) & DSP32Mac_dst_mask
);
2306 if (w1
== 0 && w0
== 0)
2309 if (((1 << mmod
) & (P
? 0x313 : 0x1b57)) == 0)
2315 return DREG_MASK (dst
| 1);
2317 return DREGH_MASK (dst
);
2323 return DREG_MASK (dst
);
2325 return DREGL_MASK (dst
);
2332 decode_dsp32alu_0 (int iw0
, int iw1
)
2335 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2336 | 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............|
2337 |.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......|
2338 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2339 int s
= ((iw1
>> DSP32Alu_s_bits
) & DSP32Alu_s_mask
);
2340 int x
= ((iw1
>> DSP32Alu_x_bits
) & DSP32Alu_x_mask
);
2341 int aop
= ((iw1
>> DSP32Alu_aop_bits
) & DSP32Alu_aop_mask
);
2342 int dst0
= ((iw1
>> DSP32Alu_dst0_bits
) & DSP32Alu_dst0_mask
);
2343 int dst1
= ((iw1
>> DSP32Alu_dst1_bits
) & DSP32Alu_dst1_mask
);
2344 int HL
= ((iw0
>> (DSP32Alu_HL_bits
- 16)) & DSP32Alu_HL_mask
);
2345 int aopcde
= ((iw0
>> (DSP32Alu_aopcde_bits
- 16)) & DSP32Alu_aopcde_mask
);
2347 if (aop
== 0 && aopcde
== 9 && s
== 0)
2349 else if (aop
== 2 && aopcde
== 9 && HL
== 0 && s
== 0)
2351 else if (aop
>= x
* 2 && aopcde
== 5)
2352 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2353 else if (HL
== 0 && aopcde
== 2)
2354 return DREGL_MASK (dst0
);
2355 else if (HL
== 1 && aopcde
== 2)
2356 return DREGH_MASK (dst0
);
2357 else if (HL
== 0 && aopcde
== 3)
2358 return DREGL_MASK (dst0
);
2359 else if (HL
== 1 && aopcde
== 3)
2360 return DREGH_MASK (dst0
);
2362 else if (aop
== 0 && aopcde
== 9 && s
== 1)
2364 else if (aop
== 1 && aopcde
== 9 && s
== 0)
2366 else if (aop
== 2 && aopcde
== 9 && s
== 1)
2368 else if (aop
== 3 && aopcde
== 9 && s
== 0)
2370 else if (aopcde
== 8)
2372 else if (aop
== 0 && aopcde
== 11)
2373 return DREG_MASK (dst0
);
2374 else if (aop
== 1 && aopcde
== 11)
2375 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2376 else if (aopcde
== 11)
2378 else if (aopcde
== 22)
2379 return DREG_MASK (dst0
);
2381 else if ((aop
== 0 || aop
== 1) && aopcde
== 14)
2383 else if (aop
== 3 && HL
== 0 && aopcde
== 14)
2386 else if (aop
== 3 && HL
== 0 && aopcde
== 15)
2387 return DREG_MASK (dst0
);
2389 else if (aop
== 1 && aopcde
== 16)
2392 else if (aop
== 0 && aopcde
== 16)
2395 else if (aop
== 3 && HL
== 0 && aopcde
== 16)
2398 else if (aop
== 3 && HL
== 0 && aopcde
== 7)
2399 return DREG_MASK (dst0
);
2400 else if ((aop
== 0 || aop
== 1 || aop
== 2) && aopcde
== 7)
2401 return DREG_MASK (dst0
);
2403 else if (aop
== 0 && aopcde
== 12)
2404 return DREG_MASK (dst0
);
2405 else if (aop
== 1 && aopcde
== 12)
2406 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2407 else if (aop
== 3 && aopcde
== 12)
2408 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2410 else if (aopcde
== 0)
2411 return DREG_MASK (dst0
);
2412 else if (aopcde
== 1)
2413 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2415 else if (aop
== 0 && aopcde
== 10)
2416 return DREGL_MASK (dst0
);
2417 else if (aop
== 1 && aopcde
== 10)
2418 return DREGL_MASK (dst0
);
2420 else if ((aop
== 1 || aop
== 0) && aopcde
== 4)
2421 return DREG_MASK (dst0
);
2422 else if (aop
== 2 && aopcde
== 4)
2423 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2425 else if (aop
== 0 && aopcde
== 17)
2426 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2427 else if (aop
== 1 && aopcde
== 17)
2428 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2429 else if (aop
== 0 && aopcde
== 18)
2431 else if (aop
== 3 && aopcde
== 18)
2434 else if ((aop
== 0 || aop
== 1 || aop
== 2) && aopcde
== 6)
2435 return DREG_MASK (dst0
);
2437 else if ((aop
== 0 || aop
== 1) && aopcde
== 20)
2438 return DREG_MASK (dst0
);
2440 else if ((aop
== 0 || aop
== 1) && aopcde
== 21)
2441 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2443 else if (aop
== 0 && aopcde
== 23 && HL
== 1)
2444 return DREG_MASK (dst0
);
2445 else if (aop
== 0 && aopcde
== 23 && HL
== 0)
2446 return DREG_MASK (dst0
);
2448 else if (aop
== 0 && aopcde
== 24)
2449 return DREG_MASK (dst0
);
2450 else if (aop
== 1 && aopcde
== 24)
2451 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2452 else if (aopcde
== 13)
2453 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2461 decode_dsp32shift_0 (int iw0
, int iw1
)
2464 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2465 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............|
2466 |.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......|
2467 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2468 int HLs
= ((iw1
>> DSP32Shift_HLs_bits
) & DSP32Shift_HLs_mask
);
2469 int sop
= ((iw1
>> DSP32Shift_sop_bits
) & DSP32Shift_sop_mask
);
2470 int src0
= ((iw1
>> DSP32Shift_src0_bits
) & DSP32Shift_src0_mask
);
2471 int src1
= ((iw1
>> DSP32Shift_src1_bits
) & DSP32Shift_src1_mask
);
2472 int dst0
= ((iw1
>> DSP32Shift_dst0_bits
) & DSP32Shift_dst0_mask
);
2473 int sopcde
= ((iw0
>> (DSP32Shift_sopcde_bits
- 16)) & DSP32Shift_sopcde_mask
);
2475 if (sop
== 0 && sopcde
== 0)
2476 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2477 else if (sop
== 1 && sopcde
== 0)
2478 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2479 else if (sop
== 2 && sopcde
== 0)
2480 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2481 else if (sop
== 0 && sopcde
== 3)
2483 else if (sop
== 1 && sopcde
== 3)
2485 else if (sop
== 2 && sopcde
== 3)
2487 else if (sop
== 3 && sopcde
== 3)
2488 return DREG_MASK (dst0
);
2489 else if (sop
== 0 && sopcde
== 1)
2490 return DREG_MASK (dst0
);
2491 else if (sop
== 1 && sopcde
== 1)
2492 return DREG_MASK (dst0
);
2493 else if (sop
== 2 && sopcde
== 1)
2494 return DREG_MASK (dst0
);
2495 else if (sopcde
== 2)
2496 return DREG_MASK (dst0
);
2497 else if (sopcde
== 4)
2498 return DREG_MASK (dst0
);
2499 else if (sop
== 0 && sopcde
== 5)
2500 return DREGL_MASK (dst0
);
2501 else if (sop
== 1 && sopcde
== 5)
2502 return DREGL_MASK (dst0
);
2503 else if (sop
== 2 && sopcde
== 5)
2504 return DREGL_MASK (dst0
);
2505 else if (sop
== 0 && sopcde
== 6)
2506 return DREGL_MASK (dst0
);
2507 else if (sop
== 1 && sopcde
== 6)
2508 return DREGL_MASK (dst0
);
2509 else if (sop
== 3 && sopcde
== 6)
2510 return DREGL_MASK (dst0
);
2511 else if (sop
== 0 && sopcde
== 7)
2512 return DREGL_MASK (dst0
);
2513 else if (sop
== 1 && sopcde
== 7)
2514 return DREGL_MASK (dst0
);
2515 else if (sop
== 2 && sopcde
== 7)
2516 return DREGL_MASK (dst0
);
2517 else if (sop
== 3 && sopcde
== 7)
2518 return DREGL_MASK (dst0
);
2519 else if (sop
== 0 && sopcde
== 8)
2520 return DREG_MASK (src0
) | DREG_MASK (src1
);
2523 OUTS (outf
, "BITMUX (");
2524 OUTS (outf
, dregs (src0
));
2526 OUTS (outf
, dregs (src1
));
2527 OUTS (outf
, ", A0) (ASR)");
2530 else if (sop
== 1 && sopcde
== 8)
2531 return DREG_MASK (src0
) | DREG_MASK (src1
);
2534 OUTS (outf
, "BITMUX (");
2535 OUTS (outf
, dregs (src0
));
2537 OUTS (outf
, dregs (src1
));
2538 OUTS (outf
, ", A0) (ASL)");
2541 else if (sopcde
== 9)
2542 return sop
< 2 ? DREGL_MASK (dst0
) : DREG_MASK (dst0
);
2543 else if (sopcde
== 10)
2544 return DREG_MASK (dst0
);
2545 else if (sop
== 0 && sopcde
== 11)
2546 return DREGL_MASK (dst0
);
2547 else if (sop
== 1 && sopcde
== 11)
2548 return DREGL_MASK (dst0
);
2549 else if (sop
== 0 && sopcde
== 12)
2551 else if (sop
== 1 && sopcde
== 12)
2552 return DREGL_MASK (dst0
);
2553 else if (sop
== 0 && sopcde
== 13)
2554 return DREG_MASK (dst0
);
2555 else if (sop
== 1 && sopcde
== 13)
2556 return DREG_MASK (dst0
);
2557 else if (sop
== 2 && sopcde
== 13)
2558 return DREG_MASK (dst0
);
2564 decode_dsp32shiftimm_0 (int iw0
, int iw1
)
2567 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2568 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............|
2569 |.sop...|.HLs...|.dst0......|.immag.................|.src1......|
2570 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2571 int sop
= ((iw1
>> DSP32ShiftImm_sop_bits
) & DSP32ShiftImm_sop_mask
);
2572 int bit8
= ((iw1
>> 8) & 0x1);
2573 int dst0
= ((iw1
>> DSP32ShiftImm_dst0_bits
) & DSP32ShiftImm_dst0_mask
);
2574 int sopcde
= ((iw0
>> (DSP32ShiftImm_sopcde_bits
- 16)) & DSP32ShiftImm_sopcde_mask
);
2575 int HLs
= ((iw1
>> DSP32ShiftImm_HLs_bits
) & DSP32ShiftImm_HLs_mask
);
2578 if (sop
== 0 && sopcde
== 0)
2579 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2580 else if (sop
== 1 && sopcde
== 0 && bit8
== 0)
2581 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2582 else if (sop
== 1 && sopcde
== 0 && bit8
== 1)
2583 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2584 else if (sop
== 2 && sopcde
== 0 && bit8
== 0)
2585 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2586 else if (sop
== 2 && sopcde
== 0 && bit8
== 1)
2587 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2588 else if (sop
== 2 && sopcde
== 3 && HLs
== 1)
2590 else if (sop
== 0 && sopcde
== 3 && HLs
== 0 && bit8
== 0)
2592 else if (sop
== 0 && sopcde
== 3 && HLs
== 0 && bit8
== 1)
2594 else if (sop
== 0 && sopcde
== 3 && HLs
== 1 && bit8
== 0)
2596 else if (sop
== 0 && sopcde
== 3 && HLs
== 1 && bit8
== 1)
2598 else if (sop
== 1 && sopcde
== 3 && HLs
== 0)
2600 else if (sop
== 1 && sopcde
== 3 && HLs
== 1)
2602 else if (sop
== 2 && sopcde
== 3 && HLs
== 0)
2604 else if (sop
== 1 && sopcde
== 1 && bit8
== 0)
2605 return DREG_MASK (dst0
);
2606 else if (sop
== 1 && sopcde
== 1 && bit8
== 1)
2607 return DREG_MASK (dst0
);
2608 else if (sop
== 2 && sopcde
== 1 && bit8
== 1)
2609 return DREG_MASK (dst0
);
2610 else if (sop
== 2 && sopcde
== 1 && bit8
== 0)
2611 return DREG_MASK (dst0
);
2612 else if (sop
== 0 && sopcde
== 1)
2613 return DREG_MASK (dst0
);
2614 else if (sop
== 1 && sopcde
== 2)
2615 return DREG_MASK (dst0
);
2616 else if (sop
== 2 && sopcde
== 2 && bit8
== 1)
2617 return DREG_MASK (dst0
);
2618 else if (sop
== 2 && sopcde
== 2 && bit8
== 0)
2619 return DREG_MASK (dst0
);
2620 else if (sop
== 3 && sopcde
== 2)
2621 return DREG_MASK (dst0
);
2622 else if (sop
== 0 && sopcde
== 2)
2623 return DREG_MASK (dst0
);
2629 insn_regmask (int iw0
, int iw1
)
2631 if ((iw0
& 0xf7ff) == 0xc003 && iw1
== 0x1800)
2632 return 0; /* MNOP */
2633 else if ((iw0
& 0xff00) == 0x0000)
2634 return decode_ProgCtrl_0 (iw0
);
2635 else if ((iw0
& 0xffc0) == 0x0240)
2637 else if ((iw0
& 0xff80) == 0x0100)
2639 else if ((iw0
& 0xfe00) == 0x0400)
2641 else if ((iw0
& 0xfe00) == 0x0600)
2643 else if ((iw0
& 0xf800) == 0x0800)
2645 else if ((iw0
& 0xffe0) == 0x0200)
2647 else if ((iw0
& 0xff00) == 0x0300)
2649 else if ((iw0
& 0xf000) == 0x1000)
2651 else if ((iw0
& 0xf000) == 0x2000)
2653 else if ((iw0
& 0xf000) == 0x3000)
2655 else if ((iw0
& 0xfc00) == 0x4000)
2657 else if ((iw0
& 0xfe00) == 0x4400)
2659 else if ((iw0
& 0xf800) == 0x4800)
2661 else if ((iw0
& 0xf000) == 0x5000)
2663 else if ((iw0
& 0xf800) == 0x6000)
2665 else if ((iw0
& 0xf800) == 0x6800)
2667 else if ((iw0
& 0xf000) == 0x8000)
2668 return decode_LDSTpmod_0 (iw0
);
2669 else if ((iw0
& 0xff60) == 0x9e60)
2670 return decode_dagMODim_0 (iw0
);
2671 else if ((iw0
& 0xfff0) == 0x9f60)
2672 return decode_dagMODik_0 (iw0
);
2673 else if ((iw0
& 0xfc00) == 0x9c00)
2674 return decode_dspLDST_0 (iw0
);
2675 else if ((iw0
& 0xf000) == 0x9000)
2676 return decode_LDST_0 (iw0
);
2677 else if ((iw0
& 0xfc00) == 0xb800)
2678 return decode_LDSTiiFP_0 (iw0
);
2679 else if ((iw0
& 0xe000) == 0xA000)
2680 return decode_LDSTii_0 (iw0
);
2681 else if ((iw0
& 0xff80) == 0xe080 && (iw1
& 0x0C00) == 0x0000)
2683 else if ((iw0
& 0xff00) == 0xe100 && (iw1
& 0x0000) == 0x0000)
2685 else if ((iw0
& 0xfe00) == 0xe200 && (iw1
& 0x0000) == 0x0000)
2687 else if ((iw0
& 0xfc00) == 0xe400 && (iw1
& 0x0000) == 0x0000)
2689 else if ((iw0
& 0xfffe) == 0xe800 && (iw1
& 0x0000) == 0x0000)
2691 else if ((iw0
& 0xf600) == 0xc000 && (iw1
& 0x0000) == 0x0000)
2692 return decode_dsp32mac_0 (iw0
, iw1
);
2693 else if ((iw0
& 0xf600) == 0xc200 && (iw1
& 0x0000) == 0x0000)
2694 return decode_dsp32mult_0 (iw0
, iw1
);
2695 else if ((iw0
& 0xf7c0) == 0xc400 && (iw1
& 0x0000) == 0x0000)
2696 return decode_dsp32alu_0 (iw0
, iw1
);
2697 else if ((iw0
& 0xf780) == 0xc600 && (iw1
& 0x01c0) == 0x0000)
2698 return decode_dsp32shift_0 (iw0
, iw1
);
2699 else if ((iw0
& 0xf780) == 0xc680 && (iw1
& 0x0000) == 0x0000)
2700 return decode_dsp32shiftimm_0 (iw0
, iw1
);
2701 else if ((iw0
& 0xff00) == 0xf800)
2703 else if ((iw0
& 0xFFC0) == 0xf000 && (iw1
& 0x0000) == 0x0000)