1 /* tc-bfin.c -- Assembler for the ADI Blackfin.
2 Copyright 2005, 2006, 2007, 2008, 2009
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
187 bfin_cpu_t bfin_cpu_type
= BFIN_CPU_UNKNOWN
;
188 /* -msi-revision support. There are three special values:
189 -1 -msi-revision=none.
190 0xffff -msi-revision=any. */
191 int bfin_si_revision
;
193 unsigned int bfin_anomaly_checks
= 0;
200 unsigned int anomaly_checks
;
203 struct bfin_cpu bfin_cpus
[] =
205 {"bf504", BFIN_CPU_BF504
, 0x0000, AC_05000074
},
207 {"bf506", BFIN_CPU_BF506
, 0x0000, AC_05000074
},
209 {"bf512", BFIN_CPU_BF512
, 0x0001, AC_05000074
},
210 {"bf512", BFIN_CPU_BF512
, 0x0000, AC_05000074
},
212 {"bf514", BFIN_CPU_BF514
, 0x0001, AC_05000074
},
213 {"bf514", BFIN_CPU_BF514
, 0x0000, AC_05000074
},
215 {"bf516", BFIN_CPU_BF516
, 0x0001, AC_05000074
},
216 {"bf516", BFIN_CPU_BF516
, 0x0000, AC_05000074
},
218 {"bf518", BFIN_CPU_BF518
, 0x0001, AC_05000074
},
219 {"bf518", BFIN_CPU_BF518
, 0x0000, AC_05000074
},
221 {"bf522", BFIN_CPU_BF522
, 0x0002, AC_05000074
},
222 {"bf522", BFIN_CPU_BF522
, 0x0001, AC_05000074
},
223 {"bf522", BFIN_CPU_BF522
, 0x0000, AC_05000074
},
225 {"bf523", BFIN_CPU_BF523
, 0x0002, AC_05000074
},
226 {"bf523", BFIN_CPU_BF523
, 0x0001, AC_05000074
},
227 {"bf523", BFIN_CPU_BF523
, 0x0000, AC_05000074
},
229 {"bf524", BFIN_CPU_BF524
, 0x0002, AC_05000074
},
230 {"bf524", BFIN_CPU_BF524
, 0x0001, AC_05000074
},
231 {"bf524", BFIN_CPU_BF524
, 0x0000, AC_05000074
},
233 {"bf525", BFIN_CPU_BF525
, 0x0002, AC_05000074
},
234 {"bf525", BFIN_CPU_BF525
, 0x0001, AC_05000074
},
235 {"bf525", BFIN_CPU_BF525
, 0x0000, AC_05000074
},
237 {"bf526", BFIN_CPU_BF526
, 0x0002, AC_05000074
},
238 {"bf526", BFIN_CPU_BF526
, 0x0001, AC_05000074
},
239 {"bf526", BFIN_CPU_BF526
, 0x0000, AC_05000074
},
241 {"bf527", BFIN_CPU_BF527
, 0x0002, AC_05000074
},
242 {"bf527", BFIN_CPU_BF527
, 0x0001, AC_05000074
},
243 {"bf527", BFIN_CPU_BF527
, 0x0000, AC_05000074
},
245 {"bf531", BFIN_CPU_BF531
, 0x0006, AC_05000074
},
246 {"bf531", BFIN_CPU_BF531
, 0x0005, AC_05000074
},
247 {"bf531", BFIN_CPU_BF531
, 0x0004, AC_05000074
},
248 {"bf531", BFIN_CPU_BF531
, 0x0003, AC_05000074
},
250 {"bf532", BFIN_CPU_BF532
, 0x0006, AC_05000074
},
251 {"bf532", BFIN_CPU_BF532
, 0x0005, AC_05000074
},
252 {"bf532", BFIN_CPU_BF532
, 0x0004, AC_05000074
},
253 {"bf532", BFIN_CPU_BF532
, 0x0003, AC_05000074
},
255 {"bf533", BFIN_CPU_BF533
, 0x0006, AC_05000074
},
256 {"bf533", BFIN_CPU_BF533
, 0x0005, AC_05000074
},
257 {"bf533", BFIN_CPU_BF533
, 0x0004, AC_05000074
},
258 {"bf533", BFIN_CPU_BF533
, 0x0003, AC_05000074
},
260 {"bf534", BFIN_CPU_BF534
, 0x0003, AC_05000074
},
261 {"bf534", BFIN_CPU_BF534
, 0x0002, AC_05000074
},
262 {"bf534", BFIN_CPU_BF534
, 0x0001, AC_05000074
},
264 {"bf536", BFIN_CPU_BF536
, 0x0003, AC_05000074
},
265 {"bf536", BFIN_CPU_BF536
, 0x0002, AC_05000074
},
266 {"bf536", BFIN_CPU_BF536
, 0x0001, AC_05000074
},
268 {"bf537", BFIN_CPU_BF537
, 0x0003, AC_05000074
},
269 {"bf537", BFIN_CPU_BF537
, 0x0002, AC_05000074
},
270 {"bf537", BFIN_CPU_BF537
, 0x0001, AC_05000074
},
272 {"bf538", BFIN_CPU_BF538
, 0x0005, AC_05000074
},
273 {"bf538", BFIN_CPU_BF538
, 0x0004, AC_05000074
},
274 {"bf538", BFIN_CPU_BF538
, 0x0003, AC_05000074
},
275 {"bf538", BFIN_CPU_BF538
, 0x0002, AC_05000074
},
277 {"bf539", BFIN_CPU_BF539
, 0x0005, AC_05000074
},
278 {"bf539", BFIN_CPU_BF539
, 0x0004, AC_05000074
},
279 {"bf539", BFIN_CPU_BF539
, 0x0003, AC_05000074
},
280 {"bf539", BFIN_CPU_BF539
, 0x0002, AC_05000074
},
282 {"bf542m", BFIN_CPU_BF542M
, 0x0003, AC_05000074
},
284 {"bf542", BFIN_CPU_BF542
, 0x0002, AC_05000074
},
285 {"bf542", BFIN_CPU_BF542
, 0x0001, AC_05000074
},
286 {"bf542", BFIN_CPU_BF542
, 0x0000, AC_05000074
},
288 {"bf544m", BFIN_CPU_BF544M
, 0x0003, AC_05000074
},
290 {"bf544", BFIN_CPU_BF544
, 0x0002, AC_05000074
},
291 {"bf544", BFIN_CPU_BF544
, 0x0001, AC_05000074
},
292 {"bf544", BFIN_CPU_BF544
, 0x0000, AC_05000074
},
294 {"bf547m", BFIN_CPU_BF547M
, 0x0003, AC_05000074
},
296 {"bf547", BFIN_CPU_BF547
, 0x0002, AC_05000074
},
297 {"bf547", BFIN_CPU_BF547
, 0x0001, AC_05000074
},
298 {"bf547", BFIN_CPU_BF547
, 0x0000, AC_05000074
},
300 {"bf548m", BFIN_CPU_BF548M
, 0x0003, AC_05000074
},
302 {"bf548", BFIN_CPU_BF548
, 0x0002, AC_05000074
},
303 {"bf548", BFIN_CPU_BF548
, 0x0001, AC_05000074
},
304 {"bf548", BFIN_CPU_BF548
, 0x0000, AC_05000074
},
306 {"bf549m", BFIN_CPU_BF549M
, 0x0003, AC_05000074
},
308 {"bf549", BFIN_CPU_BF549
, 0x0002, AC_05000074
},
309 {"bf549", BFIN_CPU_BF549
, 0x0001, AC_05000074
},
310 {"bf549", BFIN_CPU_BF549
, 0x0000, AC_05000074
},
312 {"bf561", BFIN_CPU_BF561
, 0x0005, AC_05000074
},
313 {"bf561", BFIN_CPU_BF561
, 0x0003, AC_05000074
},
314 {"bf561", BFIN_CPU_BF561
, 0x0002, AC_05000074
},
319 /* Define bfin-specific command-line options (there are none). */
320 const char *md_shortopts
= "";
322 #define OPTION_FDPIC (OPTION_MD_BASE)
323 #define OPTION_NOPIC (OPTION_MD_BASE + 1)
324 #define OPTION_MCPU (OPTION_MD_BASE + 2)
326 struct option md_longopts
[] =
328 { "mcpu", required_argument
, NULL
, OPTION_MCPU
},
329 { "mfdpic", no_argument
, NULL
, OPTION_FDPIC
},
330 { "mnopic", no_argument
, NULL
, OPTION_NOPIC
},
331 { "mno-fdpic", no_argument
, NULL
, OPTION_NOPIC
},
332 { NULL
, no_argument
, NULL
, 0 },
335 size_t md_longopts_size
= sizeof (md_longopts
);
339 md_parse_option (int c ATTRIBUTE_UNUSED
, char *arg ATTRIBUTE_UNUSED
)
352 while ((p
= bfin_cpus
[i
].name
) != NULL
)
354 if (strncmp (arg
, p
, strlen (p
)) == 0)
360 as_fatal ("-mcpu=%s is not valid", arg
);
362 bfin_cpu_type
= bfin_cpus
[i
].type
;
364 q
= arg
+ strlen (p
);
368 bfin_si_revision
= bfin_cpus
[i
].si_revision
;
369 bfin_anomaly_checks
|= bfin_cpus
[i
].anomaly_checks
;
371 else if (strcmp (q
, "-none") == 0)
372 bfin_si_revision
= -1;
373 else if (strcmp (q
, "-any") == 0)
375 bfin_si_revision
= 0xffff;
376 while (bfin_cpus
[i
].type
== bfin_cpu_type
)
378 bfin_anomaly_checks
|= bfin_cpus
[i
].anomaly_checks
;
384 unsigned int si_major
, si_minor
;
387 rev_len
= strlen (q
);
389 if (sscanf (q
, "-%u.%u%n", &si_major
, &si_minor
, &n
) != 2
391 || si_major
> 0xff || si_minor
> 0xff)
393 invalid_silicon_revision
:
394 as_fatal ("-mcpu=%s has invalid silicon revision", arg
);
397 bfin_si_revision
= (si_major
<< 8) | si_minor
;
399 while (bfin_cpus
[i
].type
== bfin_cpu_type
400 && bfin_cpus
[i
].si_revision
!= bfin_si_revision
)
403 if (bfin_cpus
[i
].type
!= bfin_cpu_type
)
404 goto invalid_silicon_revision
;
406 bfin_anomaly_checks
|= bfin_cpus
[i
].anomaly_checks
;
413 bfin_flags
|= EF_BFIN_FDPIC
;
414 bfin_pic_flag
= "-mfdpic";
418 bfin_flags
&= ~(EF_BFIN_FDPIC
);
427 md_show_usage (FILE * stream
)
429 fprintf (stream
, _(" Blackfin specific assembler options:\n"));
430 fprintf (stream
, _(" -mcpu=<cpu[-sirevision]> specify the name of the target CPU\n"));
431 fprintf (stream
, _(" -mfdpic assemble for the FDPIC ABI\n"));
432 fprintf (stream
, _(" -mno-fdpic/-mnopic disable -mfdpic\n"));
435 /* Perform machine-specific initializations. */
439 /* Set the ELF flags if desired. */
441 bfd_set_private_flags (stdoutput
, bfin_flags
);
443 /* Set the default machine type. */
444 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_bfin
, 0))
445 as_warn (_("Could not set architecture and machine."));
447 /* Ensure that lines can begin with '(', for multiple
448 register stack pops. */
449 lex_type
['('] = LEX_BEGIN_NAME
;
452 record_alignment (text_section
, 2);
453 record_alignment (data_section
, 2);
454 record_alignment (bss_section
, 2);
458 obstack_init (&mempool
);
461 extern int debug_codeselection
;
462 debug_codeselection
= 1;
468 /* Perform the main parsing, and assembly of the input here. Also,
469 call the required routines for alignment and fixups here.
470 This is called for every line that contains real assembly code. */
473 md_assemble (char *line
)
476 extern char *current_inputline
;
478 struct bfin_insn
*tmp_insn
;
480 static size_t buffer_len
= 0;
484 if (len
+ 2 > buffer_len
)
487 free (current_inputline
);
488 buffer_len
= len
+ 40;
489 current_inputline
= xmalloc (buffer_len
);
491 memcpy (current_inputline
, line
, len
);
492 current_inputline
[len
] = ';';
493 current_inputline
[len
+ 1] = '\0';
495 state
= parse (current_inputline
);
496 if (state
== NO_INSN_GENERATED
)
499 for (insn_size
= 0, tmp_insn
= insn
; tmp_insn
; tmp_insn
= tmp_insn
->next
)
500 if (!tmp_insn
->reloc
|| !tmp_insn
->exp
->symbol
)
504 toP
= frag_more (insn_size
);
506 last_insn_size
= insn_size
;
513 if (insn
->reloc
&& insn
->exp
->symbol
)
515 char *prev_toP
= toP
- 2;
518 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
519 case BFD_RELOC_24_PCREL
:
520 case BFD_RELOC_BFIN_16_LOW
:
521 case BFD_RELOC_BFIN_16_HIGH
:
528 /* Following if condition checks for the arithmetic relocations.
529 If the case then it doesn't required to generate the code.
530 It has been assumed that, their ID will be contiguous. */
531 if ((BFD_ARELOC_BFIN_PUSH
<= insn
->reloc
532 && BFD_ARELOC_BFIN_COMP
>= insn
->reloc
)
533 || insn
->reloc
== BFD_RELOC_BFIN_16_IMM
)
537 if (insn
->reloc
== BFD_ARELOC_BFIN_CONST
538 || insn
->reloc
== BFD_ARELOC_BFIN_PUSH
)
542 (prev_toP
- frag_now
->fr_literal
),
543 size
, insn
->exp
->symbol
, insn
->exp
->value
,
544 insn
->pcrel
, insn
->reloc
);
548 md_number_to_chars (toP
, insn
->value
, 2);
554 printf (" %02x%02x", ((unsigned char *) &insn
->value
)[0],
555 ((unsigned char *) &insn
->value
)[1]);
561 dwarf2_emit_insn (insn_size
);
564 while (*line
++ != '\0')
566 bump_line_counters ();
569 /* Parse one line of instructions, and generate opcode for it.
570 To parse the line, YACC and LEX are used, because the instruction set
571 syntax doesn't confirm to the AT&T assembly syntax.
572 To call a YACC & LEX generated parser, we must provide the input via
573 a FILE stream, otherwise stdin is used by default. Below the input
574 to the function will be put into a temporary file, then the generated
575 parser uses the temporary file for parsing. */
581 YY_BUFFER_STATE buffstate
;
583 buffstate
= yy_scan_string (line
);
585 /* our lex requires setting the start state to keyword
586 every line as the first word may be a keyword.
587 Fixes a bug where we could not have keywords as labels. */
590 /* Call yyparse here. */
592 if (state
== SEMANTIC_ERROR
)
594 as_bad (_("Parse failed."));
598 yy_delete_buffer (buffstate
);
602 /* We need to handle various expressions properly.
603 Such as, [SP--] = 34, concerned by md_assemble(). */
606 md_operand (expressionS
* expressionP
)
608 if (*input_line_pointer
== '[')
610 as_tsktsk ("We found a '['!");
611 input_line_pointer
++;
612 expression (expressionP
);
616 /* Handle undefined symbols. */
618 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
620 return (symbolS
*) 0;
624 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
625 segT segment ATTRIBUTE_UNUSED
)
630 /* Convert from target byte order to host byte order. */
633 md_chars_to_number (char *val
, int n
)
637 for (retval
= 0; n
--;)
646 md_apply_fix (fixS
*fixP
, valueT
*valueP
, segT seg ATTRIBUTE_UNUSED
)
648 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
650 long value
= *valueP
;
653 switch (fixP
->fx_r_type
)
655 case BFD_RELOC_BFIN_GOT
:
656 case BFD_RELOC_BFIN_GOT17M4
:
657 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
658 fixP
->fx_no_overflow
= 1;
659 newval
= md_chars_to_number (where
, 2);
660 newval
|= 0x0 & 0x7f;
661 md_number_to_chars (where
, newval
, 2);
664 case BFD_RELOC_BFIN_10_PCREL
:
667 if (value
< -1024 || value
> 1022)
668 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
669 _("pcrel too far BFD_RELOC_BFIN_10"));
671 /* 11 bit offset even numbered, so we remove right bit. */
673 newval
= md_chars_to_number (where
, 2);
674 newval
|= value
& 0x03ff;
675 md_number_to_chars (where
, newval
, 2);
678 case BFD_RELOC_BFIN_12_PCREL_JUMP
:
679 case BFD_RELOC_BFIN_12_PCREL_JUMP_S
:
680 case BFD_RELOC_12_PCREL
:
684 if (value
< -4096 || value
> 4094)
685 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_12"));
686 /* 13 bit offset even numbered, so we remove right bit. */
688 newval
= md_chars_to_number (where
, 2);
689 newval
|= value
& 0xfff;
690 md_number_to_chars (where
, newval
, 2);
693 case BFD_RELOC_BFIN_16_LOW
:
694 case BFD_RELOC_BFIN_16_HIGH
:
695 fixP
->fx_done
= FALSE
;
698 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
699 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
700 case BFD_RELOC_24_PCREL
:
704 if (value
< -16777216 || value
> 16777214)
705 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_24"));
707 /* 25 bit offset even numbered, so we remove right bit. */
711 md_number_to_chars (where
- 2, value
>> 16, 1);
712 md_number_to_chars (where
, value
, 1);
713 md_number_to_chars (where
+ 1, value
>> 8, 1);
716 case BFD_RELOC_BFIN_5_PCREL
: /* LSETUP (a, b) : "a" */
719 if (value
< 4 || value
> 30)
720 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_5"));
722 newval
= md_chars_to_number (where
, 1);
723 newval
= (newval
& 0xf0) | (value
& 0xf);
724 md_number_to_chars (where
, newval
, 1);
727 case BFD_RELOC_BFIN_11_PCREL
: /* LSETUP (a, b) : "b" */
731 if (value
< 4 || value
> 2046)
732 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_11_PCREL"));
733 /* 11 bit unsigned even, so we remove right bit. */
735 newval
= md_chars_to_number (where
, 2);
736 newval
|= value
& 0x03ff;
737 md_number_to_chars (where
, newval
, 2);
741 if (value
< -0x80 || value
>= 0x7f)
742 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("rel too far BFD_RELOC_8"));
743 md_number_to_chars (where
, value
, 1);
746 case BFD_RELOC_BFIN_16_IMM
:
748 if (value
< -0x8000 || value
>= 0x7fff)
749 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("rel too far BFD_RELOC_16"));
750 md_number_to_chars (where
, value
, 2);
754 md_number_to_chars (where
, value
, 4);
757 case BFD_RELOC_BFIN_PLTPC
:
758 md_number_to_chars (where
, value
, 2);
761 case BFD_RELOC_BFIN_FUNCDESC
:
762 case BFD_RELOC_VTABLE_INHERIT
:
763 case BFD_RELOC_VTABLE_ENTRY
:
764 fixP
->fx_done
= FALSE
;
768 if ((BFD_ARELOC_BFIN_PUSH
> fixP
->fx_r_type
) || (BFD_ARELOC_BFIN_COMP
< fixP
->fx_r_type
))
770 fprintf (stderr
, "Relocation %d not handled in gas." " Contact support.\n", fixP
->fx_r_type
);
776 fixP
->fx_done
= TRUE
;
780 /* Round up a section size to the appropriate boundary. */
782 md_section_align (segment
, size
)
786 int boundary
= bfd_get_section_alignment (stdoutput
, segment
);
787 return ((size
+ (1 << boundary
) - 1) & (-1 << boundary
));
792 md_atof (int type
, char * litP
, int * sizeP
)
794 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
798 /* If while processing a fixup, a reloc really needs to be created
799 then it is done here. */
802 tc_gen_reloc (seg
, fixp
)
803 asection
*seg ATTRIBUTE_UNUSED
;
808 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
809 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
810 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
811 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
813 reloc
->addend
= fixp
->fx_offset
;
814 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
816 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
818 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
819 /* xgettext:c-format. */
820 _("reloc %d not supported by object file format"),
821 (int) fixp
->fx_r_type
);
831 /* The location from which a PC relative jump should be calculated,
832 given a PC relative reloc. */
835 md_pcrel_from_section (fixP
, sec
)
839 if (fixP
->fx_addsy
!= (symbolS
*) NULL
840 && (!S_IS_DEFINED (fixP
->fx_addsy
)
841 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
843 /* The symbol is undefined (or is defined but not in this section).
844 Let the linker figure it out. */
847 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
850 /* Return true if the fix can be handled by GAS, false if it must
851 be passed through to the linker. */
854 bfin_fix_adjustable (fixS
*fixP
)
856 switch (fixP
->fx_r_type
)
858 /* Adjust_reloc_syms doesn't know about the GOT. */
859 case BFD_RELOC_BFIN_GOT
:
860 case BFD_RELOC_BFIN_PLTPC
:
861 /* We need the symbol name for the VTABLE entries. */
862 case BFD_RELOC_VTABLE_INHERIT
:
863 case BFD_RELOC_VTABLE_ENTRY
:
871 /* Special extra functions that help bfin-parse.y perform its job. */
873 struct obstack mempool
;
876 conscode (INSTR_T head
, INSTR_T tail
)
885 conctcode (INSTR_T head
, INSTR_T tail
)
887 INSTR_T temp
= (head
);
898 note_reloc (INSTR_T code
, Expr_Node
* symbol
, int reloc
, int pcrel
)
900 /* Assert that the symbol is not an operator. */
901 gas_assert (symbol
->type
== Expr_Node_Reloc
);
903 return note_reloc1 (code
, symbol
->value
.s_value
, reloc
, pcrel
);
908 note_reloc1 (INSTR_T code
, const char *symbol
, int reloc
, int pcrel
)
911 code
->exp
= mkexpr (0, symbol_find_or_make (symbol
));
917 note_reloc2 (INSTR_T code
, const char *symbol
, int reloc
, int value
, int pcrel
)
920 code
->exp
= mkexpr (value
, symbol_find_or_make (symbol
));
926 gencode (unsigned long x
)
928 INSTR_T cell
= obstack_alloc (&mempool
, sizeof (struct bfin_insn
));
929 memset (cell
, 0, sizeof (struct bfin_insn
));
941 return obstack_alloc (&mempool
, n
);
945 Expr_Node_Create (Expr_Node_Type type
,
946 Expr_Node_Value value
,
947 Expr_Node
*Left_Child
,
948 Expr_Node
*Right_Child
)
952 Expr_Node
*node
= (Expr_Node
*) allocate (sizeof (Expr_Node
));
955 node
->Left_Child
= Left_Child
;
956 node
->Right_Child
= Right_Child
;
960 static const char *con
= ".__constant";
961 static const char *op
= ".__operator";
962 static INSTR_T
Expr_Node_Gen_Reloc_R (Expr_Node
* head
);
963 INSTR_T
Expr_Node_Gen_Reloc (Expr_Node
*head
, int parent_reloc
);
966 Expr_Node_Gen_Reloc (Expr_Node
* head
, int parent_reloc
)
968 /* Top level reloction expression generator VDSP style.
969 If the relocation is just by itself, generate one item
970 else generate this convoluted expression. */
972 INSTR_T note
= NULL_CODE
;
973 INSTR_T note1
= NULL_CODE
;
974 int pcrel
= 1; /* Is the parent reloc pcrelative?
975 This calculation here and HOWTO should match. */
979 /* If it's 32 bit quantity then 16bit code needs to be added. */
982 if (head
->type
== Expr_Node_Constant
)
984 /* If note1 is not null code, we have to generate a right
985 aligned value for the constant. Otherwise the reloc is
986 a part of the basic command and the yacc file
988 value
= head
->value
.i_value
;
990 switch (parent_reloc
)
992 /* Some relocations will need to allocate extra words. */
993 case BFD_RELOC_BFIN_16_IMM
:
994 case BFD_RELOC_BFIN_16_LOW
:
995 case BFD_RELOC_BFIN_16_HIGH
:
996 note1
= conscode (gencode (value
), NULL_CODE
);
999 case BFD_RELOC_BFIN_PLTPC
:
1000 note1
= conscode (gencode (value
), NULL_CODE
);
1004 case BFD_RELOC_BFIN_GOT
:
1005 case BFD_RELOC_BFIN_GOT17M4
:
1006 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
1007 note1
= conscode (gencode (value
), NULL_CODE
);
1010 case BFD_RELOC_24_PCREL
:
1011 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
1012 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
1013 /* These offsets are even numbered pcrel. */
1014 note1
= conscode (gencode (value
>> 1), NULL_CODE
);
1020 if (head
->type
== Expr_Node_Constant
)
1022 else if (head
->type
== Expr_Node_Reloc
)
1024 note
= note_reloc1 (gencode (0), head
->value
.s_value
, parent_reloc
, pcrel
);
1025 if (note1
!= NULL_CODE
)
1026 note
= conscode (note1
, note
);
1028 else if (head
->type
== Expr_Node_Binop
1029 && (head
->value
.op_value
== Expr_Op_Type_Add
1030 || head
->value
.op_value
== Expr_Op_Type_Sub
)
1031 && head
->Left_Child
->type
== Expr_Node_Reloc
1032 && head
->Right_Child
->type
== Expr_Node_Constant
)
1034 int val
= head
->Right_Child
->value
.i_value
;
1035 if (head
->value
.op_value
== Expr_Op_Type_Sub
)
1037 note
= conscode (note_reloc2 (gencode (0), head
->Left_Child
->value
.s_value
,
1038 parent_reloc
, val
, 0),
1040 if (note1
!= NULL_CODE
)
1041 note
= conscode (note1
, note
);
1045 /* Call the recursive function. */
1046 note
= note_reloc1 (gencode (0), op
, parent_reloc
, pcrel
);
1047 if (note1
!= NULL_CODE
)
1048 note
= conscode (note1
, note
);
1049 note
= conctcode (Expr_Node_Gen_Reloc_R (head
), note
);
1055 Expr_Node_Gen_Reloc_R (Expr_Node
* head
)
1063 case Expr_Node_Constant
:
1064 note
= conscode (note_reloc2 (gencode (0), con
, BFD_ARELOC_BFIN_CONST
, head
->value
.i_value
, 0), NULL_CODE
);
1066 case Expr_Node_Reloc
:
1067 note
= conscode (note_reloc (gencode (0), head
, BFD_ARELOC_BFIN_PUSH
, 0), NULL_CODE
);
1069 case Expr_Node_Binop
:
1070 note1
= conctcode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), Expr_Node_Gen_Reloc_R (head
->Right_Child
));
1071 switch (head
->value
.op_value
)
1073 case Expr_Op_Type_Add
:
1074 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_ADD
, 0), NULL_CODE
));
1076 case Expr_Op_Type_Sub
:
1077 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_SUB
, 0), NULL_CODE
));
1079 case Expr_Op_Type_Mult
:
1080 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MULT
, 0), NULL_CODE
));
1082 case Expr_Op_Type_Div
:
1083 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_DIV
, 0), NULL_CODE
));
1085 case Expr_Op_Type_Mod
:
1086 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MOD
, 0), NULL_CODE
));
1088 case Expr_Op_Type_Lshift
:
1089 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LSHIFT
, 0), NULL_CODE
));
1091 case Expr_Op_Type_Rshift
:
1092 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_RSHIFT
, 0), NULL_CODE
));
1094 case Expr_Op_Type_BAND
:
1095 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_AND
, 0), NULL_CODE
));
1097 case Expr_Op_Type_BOR
:
1098 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_OR
, 0), NULL_CODE
));
1100 case Expr_Op_Type_BXOR
:
1101 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_XOR
, 0), NULL_CODE
));
1103 case Expr_Op_Type_LAND
:
1104 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LAND
, 0), NULL_CODE
));
1106 case Expr_Op_Type_LOR
:
1107 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LOR
, 0), NULL_CODE
));
1110 fprintf (stderr
, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1115 case Expr_Node_Unop
:
1116 note1
= conscode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), NULL_CODE
);
1117 switch (head
->value
.op_value
)
1119 case Expr_Op_Type_NEG
:
1120 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_NEG
, 0), NULL_CODE
));
1122 case Expr_Op_Type_COMP
:
1123 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_COMP
, 0), NULL_CODE
));
1126 fprintf (stderr
, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1130 fprintf (stderr
, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__
, __LINE__
);
1135 /* Blackfin opcode generation. */
1137 /* These functions are called by the generated parser
1138 (from bfin-parse.y), the register type classification
1139 happens in bfin-lex.l. */
1141 #include "bfin-aux.h"
1142 #include "opcode/bfin.h"
1144 #define INIT(t) t c_code = init_##t
1145 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1146 #define ASSIGNF(x,f) c_code.opcode |= ((x & c_code.mask_##f)<<c_code.bits_##f)
1147 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1149 #define HI(x) ((x >> 16) & 0xffff)
1150 #define LO(x) ((x ) & 0xffff)
1152 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1154 #define GEN_OPCODE32() \
1155 conscode (gencode (HI (c_code.opcode)), \
1156 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1158 #define GEN_OPCODE16() \
1159 conscode (gencode (c_code.opcode), NULL_CODE)
1162 /* 32 BIT INSTRUCTIONS. */
1165 /* DSP32 instruction generation. */
1168 bfin_gen_dsp32mac (int op1
, int MM
, int mmod
, int w1
, int P
,
1169 int h01
, int h11
, int h00
, int h10
, int op0
,
1170 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1186 /* If we have full reg assignments, mask out LSB to encode
1187 single or simultaneous even/odd register moves. */
1197 return GEN_OPCODE32 ();
1201 bfin_gen_dsp32mult (int op1
, int MM
, int mmod
, int w1
, int P
,
1202 int h01
, int h11
, int h00
, int h10
, int op0
,
1203 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1228 return GEN_OPCODE32 ();
1232 bfin_gen_dsp32alu (int HL
, int aopcde
, int aop
, int s
, int x
,
1233 REG_T dst0
, REG_T dst1
, REG_T src0
, REG_T src1
)
1247 return GEN_OPCODE32 ();
1251 bfin_gen_dsp32shift (int sopcde
, REG_T dst0
, REG_T src0
,
1252 REG_T src1
, int sop
, int HLs
)
1264 return GEN_OPCODE32 ();
1268 bfin_gen_dsp32shiftimm (int sopcde
, REG_T dst0
, int immag
,
1269 REG_T src1
, int sop
, int HLs
)
1271 INIT (DSP32ShiftImm
);
1281 return GEN_OPCODE32 ();
1287 bfin_gen_loopsetup (Expr_Node
* psoffset
, REG_T c
, int rop
,
1288 Expr_Node
* peoffset
, REG_T reg
)
1290 int soffset
, eoffset
;
1293 soffset
= (EXPR_VALUE (psoffset
) >> 1);
1295 eoffset
= (EXPR_VALUE (peoffset
) >> 1);
1302 conscode (gencode (HI (c_code
.opcode
)),
1303 conctcode (Expr_Node_Gen_Reloc (psoffset
, BFD_RELOC_BFIN_5_PCREL
),
1304 conctcode (gencode (LO (c_code
.opcode
)), Expr_Node_Gen_Reloc (peoffset
, BFD_RELOC_BFIN_11_PCREL
))));
1311 bfin_gen_calla (Expr_Node
* addr
, int S
)
1319 case 0 : rel
= BFD_RELOC_BFIN_24_PCREL_JUMP_L
; break;
1320 case 1 : rel
= BFD_RELOC_24_PCREL
; break;
1321 case 2 : rel
= BFD_RELOC_BFIN_PLTPC
; break;
1327 val
= EXPR_VALUE (addr
) >> 1;
1328 high_val
= val
>> 16;
1330 return conscode (gencode (HI (c_code
.opcode
) | (high_val
& 0xff)),
1331 Expr_Node_Gen_Reloc (addr
, rel
));
1335 bfin_gen_linkage (int R
, int framesize
)
1342 return GEN_OPCODE32 ();
1346 /* Load and Store. */
1349 bfin_gen_ldimmhalf (REG_T reg
, int H
, int S
, int Z
, Expr_Node
* phword
, int rel
)
1352 unsigned val
= EXPR_VALUE (phword
);
1360 grp
= (GROUP (reg
));
1364 return conscode (gencode (HI (c_code
.opcode
)), Expr_Node_Gen_Reloc (phword
, BFD_RELOC_BFIN_16_IMM
));
1368 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
));
1375 return GEN_OPCODE32 ();
1379 bfin_gen_ldstidxi (REG_T ptr
, REG_T reg
, int W
, int sz
, int Z
, Expr_Node
* poffset
)
1383 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1385 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1396 if (poffset
->type
!= Expr_Node_Constant
)
1398 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1399 /* distinguish between R0 = [P5 + symbol@GOT] and
1400 P5 = [P5 + _current_shared_library_p5_offset_]
1402 if (poffset
->type
== Expr_Node_Reloc
1403 && !strcmp (poffset
->value
.s_value
,
1404 "_current_shared_library_p5_offset_"))
1406 return conscode (gencode (HI (c_code
.opcode
)),
1407 Expr_Node_Gen_Reloc(poffset
, BFD_RELOC_16
));
1409 else if (poffset
->type
!= Expr_Node_GOT_Reloc
)
1412 return conscode (gencode (HI (c_code
.opcode
)),
1413 Expr_Node_Gen_Reloc(poffset
->Left_Child
,
1414 poffset
->value
.i_value
));
1420 { /* load/store access size */
1421 case 0: /* 32 bit */
1422 value
= EXPR_VALUE (poffset
) >> 2;
1424 case 1: /* 16 bit */
1425 value
= EXPR_VALUE (poffset
) >> 1;
1428 value
= EXPR_VALUE (poffset
);
1434 offset
= (value
& 0xffff);
1436 return GEN_OPCODE32 ();
1442 bfin_gen_ldst (REG_T ptr
, REG_T reg
, int aop
, int sz
, int Z
, int W
)
1446 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1448 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1459 return GEN_OPCODE16 ();
1463 bfin_gen_ldstii (REG_T ptr
, REG_T reg
, Expr_Node
* poffset
, int W
, int opc
)
1469 if (!IS_PREG (*ptr
))
1471 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1479 value
= EXPR_VALUE (poffset
) >> 1;
1483 value
= EXPR_VALUE (poffset
) >> 2;
1495 return GEN_OPCODE16 ();
1499 bfin_gen_ldstiifp (REG_T sreg
, Expr_Node
* poffset
, int W
)
1501 /* Set bit 4 if it's a Preg. */
1502 int reg
= (sreg
->regno
& CODE_MASK
) | (IS_PREG (*sreg
) ? 0x8 : 0x0);
1503 int offset
= ((~(EXPR_VALUE (poffset
) >> 2)) & 0x1f) + 1;
1509 return GEN_OPCODE16 ();
1513 bfin_gen_ldstpmod (REG_T ptr
, REG_T reg
, int aop
, int W
, REG_T idx
)
1523 return GEN_OPCODE16 ();
1527 bfin_gen_dspldst (REG_T i
, REG_T reg
, int aop
, int W
, int m
)
1537 return GEN_OPCODE16 ();
1541 bfin_gen_logi2op (int opc
, int src
, int dst
)
1549 return GEN_OPCODE16 ();
1553 bfin_gen_brcc (int T
, int B
, Expr_Node
* poffset
)
1560 offset
= ((EXPR_VALUE (poffset
) >> 1));
1562 return conscode (gencode (c_code
.opcode
), Expr_Node_Gen_Reloc (poffset
, BFD_RELOC_BFIN_10_PCREL
));
1566 bfin_gen_ujump (Expr_Node
* poffset
)
1571 offset
= ((EXPR_VALUE (poffset
) >> 1));
1574 return conscode (gencode (c_code
.opcode
),
1575 Expr_Node_Gen_Reloc (
1576 poffset
, BFD_RELOC_BFIN_12_PCREL_JUMP_S
));
1580 bfin_gen_alu2op (REG_T dst
, REG_T src
, int opc
)
1588 return GEN_OPCODE16 ();
1592 bfin_gen_compi2opd (REG_T dst
, int src
, int opc
)
1600 return GEN_OPCODE16 ();
1604 bfin_gen_compi2opp (REG_T dst
, int src
, int opc
)
1612 return GEN_OPCODE16 ();
1616 bfin_gen_dagmodik (REG_T i
, int opc
)
1623 return GEN_OPCODE16 ();
1627 bfin_gen_dagmodim (REG_T i
, REG_T m
, int opc
, int br
)
1636 return GEN_OPCODE16 ();
1640 bfin_gen_ptr2op (REG_T dst
, REG_T src
, int opc
)
1648 return GEN_OPCODE16 ();
1652 bfin_gen_comp3op (REG_T src0
, REG_T src1
, REG_T dst
, int opc
)
1661 return GEN_OPCODE16 ();
1665 bfin_gen_ccflag (REG_T x
, int y
, int opc
, int I
, int G
)
1675 return GEN_OPCODE16 ();
1679 bfin_gen_ccmv (REG_T src
, REG_T dst
, int T
)
1692 return GEN_OPCODE16 ();
1696 bfin_gen_cc2stat (int cbit
, int opc
, int D
)
1704 return GEN_OPCODE16 ();
1708 bfin_gen_regmv (REG_T src
, REG_T dst
)
1721 return GEN_OPCODE16 ();
1725 bfin_gen_cc2dreg (int opc
, REG_T reg
)
1732 return GEN_OPCODE16 ();
1736 bfin_gen_progctrl (int prgfunc
, int poprnd
)
1743 return GEN_OPCODE16 ();
1747 bfin_gen_cactrl (REG_T reg
, int a
, int opc
)
1755 return GEN_OPCODE16 ();
1759 bfin_gen_pushpopmultiple (int dr
, int pr
, int d
, int p
, int W
)
1761 INIT (PushPopMultiple
);
1769 return GEN_OPCODE16 ();
1773 bfin_gen_pushpopreg (REG_T reg
, int W
)
1779 grp
= (GROUP (reg
));
1783 return GEN_OPCODE16 ();
1786 /* Pseudo Debugging Support. */
1789 bfin_gen_pseudodbg (int fn
, int reg
, int grp
)
1797 return GEN_OPCODE16 ();
1801 bfin_gen_pseudodbg_assert (int dbgop
, REG_T regtest
, int expected
)
1804 INIT (PseudoDbg_Assert
);
1808 grp
= GROUP (regtest
);
1812 return GEN_OPCODE32 ();
1815 /* Multiple instruction generation. */
1818 bfin_gen_multi_instr (INSTR_T dsp32
, INSTR_T dsp16_grp1
, INSTR_T dsp16_grp2
)
1822 /* If it's a 0, convert into MNOP. */
1826 SET_MULTI_INSTRUCTION_BIT (dsp32
);
1830 dsp32
= gencode (0xc803);
1831 walk
= gencode (0x1800);
1837 dsp16_grp1
= gencode (0x0000);
1842 dsp16_grp2
= gencode (0x0000);
1845 walk
->next
= dsp16_grp1
;
1846 dsp16_grp1
->next
= dsp16_grp2
;
1847 dsp16_grp2
->next
= NULL_CODE
;
1853 bfin_gen_loop (Expr_Node
*exp
, REG_T reg
, int rop
, REG_T preg
)
1855 const char *loopsym
;
1856 char *lbeginsym
, *lendsym
;
1857 Expr_Node_Value lbeginval
, lendval
;
1858 Expr_Node
*lbegin
, *lend
;
1860 loopsym
= exp
->value
.s_value
;
1861 lbeginsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__BEGIN") + 5);
1862 lendsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__END") + 5);
1867 strcat (lbeginsym
, "L$L$");
1868 strcat (lbeginsym
, loopsym
);
1869 strcat (lbeginsym
, "__BEGIN");
1871 strcat (lendsym
, "L$L$");
1872 strcat (lendsym
, loopsym
);
1873 strcat (lendsym
, "__END");
1875 lbeginval
.s_value
= lbeginsym
;
1876 lendval
.s_value
= lendsym
;
1878 lbegin
= Expr_Node_Create (Expr_Node_Reloc
, lbeginval
, NULL
, NULL
);
1879 lend
= Expr_Node_Create (Expr_Node_Reloc
, lendval
, NULL
, NULL
);
1881 symbol_remove (symbol_find (loopsym
), &symbol_rootP
, &symbol_lastP
);
1883 return bfin_gen_loopsetup(lbegin
, reg
, rop
, lend
, preg
);
1887 bfin_loop_beginend (Expr_Node
*exp
, int begin
)
1889 const char *loopsym
;
1892 const char *suffix
= begin
? "__BEGIN" : "__END";
1894 loopsym
= exp
->value
.s_value
;
1895 label_name
= (char *) xmalloc (strlen (loopsym
) + strlen (suffix
) + 5);
1899 strcat (label_name
, "L$L$");
1900 strcat (label_name
, loopsym
);
1901 strcat (label_name
, suffix
);
1903 linelabel
= colon (label_name
);
1905 /* LOOP_END follows the last instruction in the loop.
1906 Adjust label address. */
1908 ((struct local_symbol
*) linelabel
)->lsy_value
-= last_insn_size
;
1912 bfin_eol_in_insn (char *line
)
1914 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1921 /* A semi-colon followed by a newline is always the end of a line. */
1922 if (line
[-1] == ';')
1925 if (line
[-1] == '|')
1928 /* If the || is on the next line, there might be leading whitespace. */
1930 while (*temp
== ' ' || *temp
== '\t') temp
++;
1939 bfin_start_label (char *s
, char *ptr
)
1943 if (*s
== '(' || *s
== '[')
1952 bfin_force_relocation (struct fix
*fixp
)
1954 if (fixp
->fx_r_type
==BFD_RELOC_BFIN_16_LOW
1955 || fixp
->fx_r_type
== BFD_RELOC_BFIN_16_HIGH
)
1958 return generic_force_reloc (fixp
);
1961 /* This is a stripped down version of the disassembler. The only thing it
1962 does is return a mask of registers modified by an instruction. Only
1963 instructions that can occur in a parallel-issue bundle are handled, and
1964 only the registers that can cause a conflict are recorded. */
1966 #define DREG_MASK(n) (0x101 << (n))
1967 #define DREGH_MASK(n) (0x100 << (n))
1968 #define DREGL_MASK(n) (0x001 << (n))
1969 #define IREG_MASK(n) (1 << ((n) + 16))
1972 decode_ProgCtrl_0 (int iw0
)
1980 decode_LDSTpmod_0 (int iw0
)
1983 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
1984 | 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......|
1985 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
1986 int W
= ((iw0
>> LDSTpmod_W_bits
) & LDSTpmod_W_mask
);
1987 int aop
= ((iw0
>> LDSTpmod_aop_bits
) & LDSTpmod_aop_mask
);
1988 int idx
= ((iw0
>> LDSTpmod_idx_bits
) & LDSTpmod_idx_mask
);
1989 int ptr
= ((iw0
>> LDSTpmod_ptr_bits
) & LDSTpmod_ptr_mask
);
1990 int reg
= ((iw0
>> LDSTpmod_reg_bits
) & LDSTpmod_reg_mask
);
1992 if (aop
== 1 && W
== 0 && idx
== ptr
)
1993 return DREGL_MASK (reg
);
1994 else if (aop
== 2 && W
== 0 && idx
== ptr
)
1995 return DREGH_MASK (reg
);
1996 else if (aop
== 1 && W
== 1 && idx
== ptr
)
1998 else if (aop
== 2 && W
== 1 && idx
== ptr
)
2000 else if (aop
== 0 && W
== 0)
2001 return DREG_MASK (reg
);
2002 else if (aop
== 1 && W
== 0)
2003 return DREGL_MASK (reg
);
2004 else if (aop
== 2 && W
== 0)
2005 return DREGH_MASK (reg
);
2006 else if (aop
== 3 && W
== 0)
2007 return DREG_MASK (reg
);
2008 else if (aop
== 3 && W
== 1)
2009 return DREG_MASK (reg
);
2010 else if (aop
== 0 && W
== 1)
2012 else if (aop
== 1 && W
== 1)
2014 else if (aop
== 2 && W
== 1)
2023 decode_dagMODim_0 (int iw0
)
2026 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2027 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....|
2028 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2029 int i
= ((iw0
>> DagMODim_i_bits
) & DagMODim_i_mask
);
2030 int opc
= ((iw0
>> DagMODim_op_bits
) & DagMODim_op_mask
);
2032 if (opc
== 0 || opc
== 1)
2033 return IREG_MASK (i
);
2041 decode_dagMODik_0 (int iw0
)
2044 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2045 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....|
2046 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2047 int i
= ((iw0
>> DagMODik_i_bits
) & DagMODik_i_mask
);
2048 return IREG_MASK (i
);
2053 decode_dspLDST_0 (int iw0
)
2056 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2057 | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......|
2058 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2059 int i
= ((iw0
>> DspLDST_i_bits
) & DspLDST_i_mask
);
2060 int m
= ((iw0
>> DspLDST_m_bits
) & DspLDST_m_mask
);
2061 int W
= ((iw0
>> DspLDST_W_bits
) & DspLDST_W_mask
);
2062 int aop
= ((iw0
>> DspLDST_aop_bits
) & DspLDST_aop_mask
);
2063 int reg
= ((iw0
>> DspLDST_reg_bits
) & DspLDST_reg_mask
);
2065 if (aop
== 0 && W
== 0 && m
== 0)
2066 return DREG_MASK (reg
) | IREG_MASK (i
);
2067 else if (aop
== 0 && W
== 0 && m
== 1)
2068 return DREGL_MASK (reg
) | IREG_MASK (i
);
2069 else if (aop
== 0 && W
== 0 && m
== 2)
2070 return DREGH_MASK (reg
) | IREG_MASK (i
);
2071 else if (aop
== 1 && W
== 0 && m
== 0)
2072 return DREG_MASK (reg
) | IREG_MASK (i
);
2073 else if (aop
== 1 && W
== 0 && m
== 1)
2074 return DREGL_MASK (reg
) | IREG_MASK (i
);
2075 else if (aop
== 1 && W
== 0 && m
== 2)
2076 return DREGH_MASK (reg
) | IREG_MASK (i
);
2077 else if (aop
== 2 && W
== 0 && m
== 0)
2078 return DREG_MASK (reg
);
2079 else if (aop
== 2 && W
== 0 && m
== 1)
2080 return DREGL_MASK (reg
);
2081 else if (aop
== 2 && W
== 0 && m
== 2)
2082 return DREGH_MASK (reg
);
2083 else if (aop
== 0 && W
== 1 && m
== 0)
2084 return IREG_MASK (i
);
2085 else if (aop
== 0 && W
== 1 && m
== 1)
2086 return IREG_MASK (i
);
2087 else if (aop
== 0 && W
== 1 && m
== 2)
2088 return IREG_MASK (i
);
2089 else if (aop
== 1 && W
== 1 && m
== 0)
2090 return IREG_MASK (i
);
2091 else if (aop
== 1 && W
== 1 && m
== 1)
2092 return IREG_MASK (i
);
2093 else if (aop
== 1 && W
== 1 && m
== 2)
2094 return IREG_MASK (i
);
2095 else if (aop
== 2 && W
== 1 && m
== 0)
2097 else if (aop
== 2 && W
== 1 && m
== 1)
2099 else if (aop
== 2 && W
== 1 && m
== 2)
2101 else if (aop
== 3 && W
== 0)
2102 return DREG_MASK (reg
) | IREG_MASK (i
);
2103 else if (aop
== 3 && W
== 1)
2104 return IREG_MASK (i
);
2111 decode_LDST_0 (int iw0
)
2114 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2115 | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......|
2116 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2117 int Z
= ((iw0
>> LDST_Z_bits
) & LDST_Z_mask
);
2118 int W
= ((iw0
>> LDST_W_bits
) & LDST_W_mask
);
2119 int sz
= ((iw0
>> LDST_sz_bits
) & LDST_sz_mask
);
2120 int aop
= ((iw0
>> LDST_aop_bits
) & LDST_aop_mask
);
2121 int reg
= ((iw0
>> LDST_reg_bits
) & LDST_reg_mask
);
2123 if (aop
== 0 && sz
== 0 && Z
== 0 && W
== 0)
2124 return DREG_MASK (reg
);
2125 else if (aop
== 0 && sz
== 0 && Z
== 1 && W
== 0)
2127 else if (aop
== 0 && sz
== 1 && Z
== 0 && W
== 0)
2128 return DREG_MASK (reg
);
2129 else if (aop
== 0 && sz
== 1 && Z
== 1 && W
== 0)
2130 return DREG_MASK (reg
);
2131 else if (aop
== 0 && sz
== 2 && Z
== 0 && W
== 0)
2132 return DREG_MASK (reg
);
2133 else if (aop
== 0 && sz
== 2 && Z
== 1 && W
== 0)
2134 return DREG_MASK (reg
);
2135 else if (aop
== 1 && sz
== 0 && Z
== 0 && W
== 0)
2136 return DREG_MASK (reg
);
2137 else if (aop
== 1 && sz
== 0 && Z
== 1 && W
== 0)
2139 else if (aop
== 1 && sz
== 1 && Z
== 0 && W
== 0)
2140 return DREG_MASK (reg
);
2141 else if (aop
== 1 && sz
== 1 && Z
== 1 && W
== 0)
2142 return DREG_MASK (reg
);
2143 else if (aop
== 1 && sz
== 2 && Z
== 0 && W
== 0)
2144 return DREG_MASK (reg
);
2145 else if (aop
== 1 && sz
== 2 && Z
== 1 && W
== 0)
2146 return DREG_MASK (reg
);
2147 else if (aop
== 2 && sz
== 0 && Z
== 0 && W
== 0)
2148 return DREG_MASK (reg
);
2149 else if (aop
== 2 && sz
== 0 && Z
== 1 && W
== 0)
2151 else if (aop
== 2 && sz
== 1 && Z
== 0 && W
== 0)
2152 return DREG_MASK (reg
);
2153 else if (aop
== 2 && sz
== 1 && Z
== 1 && W
== 0)
2154 return DREG_MASK (reg
);
2155 else if (aop
== 2 && sz
== 2 && Z
== 0 && W
== 0)
2156 return DREG_MASK (reg
);
2157 else if (aop
== 2 && sz
== 2 && Z
== 1 && W
== 0)
2158 return DREG_MASK (reg
);
2159 else if (aop
== 0 && sz
== 0 && Z
== 0 && W
== 1)
2161 else if (aop
== 0 && sz
== 0 && Z
== 1 && W
== 1)
2163 else if (aop
== 0 && sz
== 1 && Z
== 0 && W
== 1)
2165 else if (aop
== 0 && sz
== 2 && Z
== 0 && W
== 1)
2167 else if (aop
== 1 && sz
== 0 && Z
== 0 && W
== 1)
2169 else if (aop
== 1 && sz
== 0 && Z
== 1 && W
== 1)
2171 else if (aop
== 1 && sz
== 1 && Z
== 0 && W
== 1)
2173 else if (aop
== 1 && sz
== 2 && Z
== 0 && W
== 1)
2175 else if (aop
== 2 && sz
== 0 && Z
== 0 && W
== 1)
2177 else if (aop
== 2 && sz
== 0 && Z
== 1 && W
== 1)
2179 else if (aop
== 2 && sz
== 1 && Z
== 0 && W
== 1)
2181 else if (aop
== 2 && sz
== 2 && Z
== 0 && W
== 1)
2188 decode_LDSTiiFP_0 (int iw0
)
2191 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2192 | 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........|
2193 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2194 int reg
= ((iw0
>> LDSTiiFP_reg_bits
) & LDSTiiFP_reg_mask
);
2195 int W
= ((iw0
>> LDSTiiFP_W_bits
) & LDSTiiFP_W_mask
);
2198 return reg
< 8 ? DREG_MASK (reg
) : 0;
2204 decode_LDSTii_0 (int iw0
)
2207 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2208 | 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......|
2209 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2210 int reg
= ((iw0
>> LDSTii_reg_bit
) & LDSTii_reg_mask
);
2211 int opc
= ((iw0
>> LDSTii_op_bit
) & LDSTii_op_mask
);
2212 int W
= ((iw0
>> LDSTii_W_bit
) & LDSTii_W_mask
);
2214 if (W
== 0 && opc
!= 3)
2215 return DREG_MASK (reg
);
2216 else if (W
== 0 && opc
== 3)
2218 else if (W
== 1 && opc
== 0)
2220 else if (W
== 1 && opc
== 1)
2222 else if (W
== 1 && opc
== 3)
2229 decode_dsp32mac_0 (int iw0
, int iw1
)
2233 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2234 | 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...|
2235 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2236 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2237 int op1
= ((iw0
>> (DSP32Mac_op1_bits
- 16)) & DSP32Mac_op1_mask
);
2238 int w1
= ((iw0
>> (DSP32Mac_w1_bits
- 16)) & DSP32Mac_w1_mask
);
2239 int P
= ((iw0
>> (DSP32Mac_p_bits
- 16)) & DSP32Mac_p_mask
);
2240 int mmod
= ((iw0
>> (DSP32Mac_mmod_bits
- 16)) & DSP32Mac_mmod_mask
);
2241 int w0
= ((iw1
>> DSP32Mac_w0_bits
) & DSP32Mac_w0_mask
);
2242 int MM
= ((iw1
>> DSP32Mac_MM_bits
) & DSP32Mac_MM_mask
);
2243 int dst
= ((iw1
>> DSP32Mac_dst_bits
) & DSP32Mac_dst_mask
);
2244 int op0
= ((iw1
>> DSP32Mac_op0_bits
) & DSP32Mac_op0_mask
);
2246 if (w0
== 0 && w1
== 0 && op1
== 3 && op0
== 3)
2252 if ((w1
|| w0
) && mmod
== M_W32
)
2255 if (((1 << mmod
) & (P
? 0x131b : 0x1b5f)) == 0)
2258 if (w1
== 1 || op1
!= 3)
2263 return DREG_MASK (dst
+ 1);
2265 return DREGH_MASK (dst
);
2269 if (w0
== 1 || op0
!= 3)
2274 return DREG_MASK (dst
);
2276 return DREGL_MASK (dst
);
2284 decode_dsp32mult_0 (int iw0
, int iw1
)
2287 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2288 | 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...|
2289 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2290 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2291 int w1
= ((iw0
>> (DSP32Mac_w1_bits
- 16)) & DSP32Mac_w1_mask
);
2292 int P
= ((iw0
>> (DSP32Mac_p_bits
- 16)) & DSP32Mac_p_mask
);
2293 int mmod
= ((iw0
>> (DSP32Mac_mmod_bits
- 16)) & DSP32Mac_mmod_mask
);
2294 int w0
= ((iw1
>> DSP32Mac_w0_bits
) & DSP32Mac_w0_mask
);
2295 int dst
= ((iw1
>> DSP32Mac_dst_bits
) & DSP32Mac_dst_mask
);
2298 if (w1
== 0 && w0
== 0)
2301 if (((1 << mmod
) & (P
? 0x313 : 0x1b57)) == 0)
2307 return DREG_MASK (dst
| 1);
2309 return DREGH_MASK (dst
);
2315 return DREG_MASK (dst
);
2317 return DREGL_MASK (dst
);
2324 decode_dsp32alu_0 (int iw0
, int iw1
)
2327 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2328 | 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............|
2329 |.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......|
2330 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2331 int s
= ((iw1
>> DSP32Alu_s_bits
) & DSP32Alu_s_mask
);
2332 int x
= ((iw1
>> DSP32Alu_x_bits
) & DSP32Alu_x_mask
);
2333 int aop
= ((iw1
>> DSP32Alu_aop_bits
) & DSP32Alu_aop_mask
);
2334 int dst0
= ((iw1
>> DSP32Alu_dst0_bits
) & DSP32Alu_dst0_mask
);
2335 int dst1
= ((iw1
>> DSP32Alu_dst1_bits
) & DSP32Alu_dst1_mask
);
2336 int HL
= ((iw0
>> (DSP32Alu_HL_bits
- 16)) & DSP32Alu_HL_mask
);
2337 int aopcde
= ((iw0
>> (DSP32Alu_aopcde_bits
- 16)) & DSP32Alu_aopcde_mask
);
2339 if (aop
== 0 && aopcde
== 9 && s
== 0)
2341 else if (aop
== 2 && aopcde
== 9 && HL
== 0 && s
== 0)
2343 else if (aop
>= x
* 2 && aopcde
== 5)
2344 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2345 else if (HL
== 0 && aopcde
== 2)
2346 return DREGL_MASK (dst0
);
2347 else if (HL
== 1 && aopcde
== 2)
2348 return DREGH_MASK (dst0
);
2349 else if (HL
== 0 && aopcde
== 3)
2350 return DREGL_MASK (dst0
);
2351 else if (HL
== 1 && aopcde
== 3)
2352 return DREGH_MASK (dst0
);
2354 else if (aop
== 0 && aopcde
== 9 && s
== 1)
2356 else if (aop
== 1 && aopcde
== 9 && s
== 0)
2358 else if (aop
== 2 && aopcde
== 9 && s
== 1)
2360 else if (aop
== 3 && aopcde
== 9 && s
== 0)
2362 else if (aopcde
== 8)
2364 else if (aop
== 0 && aopcde
== 11)
2365 return DREG_MASK (dst0
);
2366 else if (aop
== 1 && aopcde
== 11)
2367 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2368 else if (aopcde
== 11)
2370 else if (aopcde
== 22)
2371 return DREG_MASK (dst0
);
2373 else if ((aop
== 0 || aop
== 1) && aopcde
== 14)
2375 else if (aop
== 3 && HL
== 0 && aopcde
== 14)
2378 else if (aop
== 3 && HL
== 0 && aopcde
== 15)
2379 return DREG_MASK (dst0
);
2381 else if (aop
== 1 && aopcde
== 16)
2384 else if (aop
== 0 && aopcde
== 16)
2387 else if (aop
== 3 && HL
== 0 && aopcde
== 16)
2390 else if (aop
== 3 && HL
== 0 && aopcde
== 7)
2391 return DREG_MASK (dst0
);
2392 else if ((aop
== 0 || aop
== 1 || aop
== 2) && aopcde
== 7)
2393 return DREG_MASK (dst0
);
2395 else if (aop
== 0 && aopcde
== 12)
2396 return DREG_MASK (dst0
);
2397 else if (aop
== 1 && aopcde
== 12)
2398 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2399 else if (aop
== 3 && aopcde
== 12)
2400 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2402 else if (aopcde
== 0)
2403 return DREG_MASK (dst0
);
2404 else if (aopcde
== 1)
2405 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2407 else if (aop
== 0 && aopcde
== 10)
2408 return DREGL_MASK (dst0
);
2409 else if (aop
== 1 && aopcde
== 10)
2410 return DREGL_MASK (dst0
);
2412 else if ((aop
== 1 || aop
== 0) && aopcde
== 4)
2413 return DREG_MASK (dst0
);
2414 else if (aop
== 2 && aopcde
== 4)
2415 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2417 else if (aop
== 0 && aopcde
== 17)
2418 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2419 else if (aop
== 1 && aopcde
== 17)
2420 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2421 else if (aop
== 0 && aopcde
== 18)
2423 else if (aop
== 3 && aopcde
== 18)
2426 else if ((aop
== 0 || aop
== 1 || aop
== 2) && aopcde
== 6)
2427 return DREG_MASK (dst0
);
2429 else if ((aop
== 0 || aop
== 1) && aopcde
== 20)
2430 return DREG_MASK (dst0
);
2432 else if ((aop
== 0 || aop
== 1) && aopcde
== 21)
2433 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2435 else if (aop
== 0 && aopcde
== 23 && HL
== 1)
2436 return DREG_MASK (dst0
);
2437 else if (aop
== 0 && aopcde
== 23 && HL
== 0)
2438 return DREG_MASK (dst0
);
2440 else if (aop
== 0 && aopcde
== 24)
2441 return DREG_MASK (dst0
);
2442 else if (aop
== 1 && aopcde
== 24)
2443 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2444 else if (aopcde
== 13)
2445 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2453 decode_dsp32shift_0 (int iw0
, int iw1
)
2456 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2457 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............|
2458 |.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......|
2459 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2460 int HLs
= ((iw1
>> DSP32Shift_HLs_bits
) & DSP32Shift_HLs_mask
);
2461 int sop
= ((iw1
>> DSP32Shift_sop_bits
) & DSP32Shift_sop_mask
);
2462 int src0
= ((iw1
>> DSP32Shift_src0_bits
) & DSP32Shift_src0_mask
);
2463 int src1
= ((iw1
>> DSP32Shift_src1_bits
) & DSP32Shift_src1_mask
);
2464 int dst0
= ((iw1
>> DSP32Shift_dst0_bits
) & DSP32Shift_dst0_mask
);
2465 int sopcde
= ((iw0
>> (DSP32Shift_sopcde_bits
- 16)) & DSP32Shift_sopcde_mask
);
2467 if (sop
== 0 && sopcde
== 0)
2468 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2469 else if (sop
== 1 && sopcde
== 0)
2470 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2471 else if (sop
== 2 && sopcde
== 0)
2472 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2473 else if (sop
== 0 && sopcde
== 3)
2475 else if (sop
== 1 && sopcde
== 3)
2477 else if (sop
== 2 && sopcde
== 3)
2479 else if (sop
== 3 && sopcde
== 3)
2480 return DREG_MASK (dst0
);
2481 else if (sop
== 0 && sopcde
== 1)
2482 return DREG_MASK (dst0
);
2483 else if (sop
== 1 && sopcde
== 1)
2484 return DREG_MASK (dst0
);
2485 else if (sop
== 2 && sopcde
== 1)
2486 return DREG_MASK (dst0
);
2487 else if (sopcde
== 2)
2488 return DREG_MASK (dst0
);
2489 else if (sopcde
== 4)
2490 return DREG_MASK (dst0
);
2491 else if (sop
== 0 && sopcde
== 5)
2492 return DREGL_MASK (dst0
);
2493 else if (sop
== 1 && sopcde
== 5)
2494 return DREGL_MASK (dst0
);
2495 else if (sop
== 2 && sopcde
== 5)
2496 return DREGL_MASK (dst0
);
2497 else if (sop
== 0 && sopcde
== 6)
2498 return DREGL_MASK (dst0
);
2499 else if (sop
== 1 && sopcde
== 6)
2500 return DREGL_MASK (dst0
);
2501 else if (sop
== 3 && sopcde
== 6)
2502 return DREGL_MASK (dst0
);
2503 else if (sop
== 0 && sopcde
== 7)
2504 return DREGL_MASK (dst0
);
2505 else if (sop
== 1 && sopcde
== 7)
2506 return DREGL_MASK (dst0
);
2507 else if (sop
== 2 && sopcde
== 7)
2508 return DREGL_MASK (dst0
);
2509 else if (sop
== 3 && sopcde
== 7)
2510 return DREGL_MASK (dst0
);
2511 else if (sop
== 0 && sopcde
== 8)
2512 return DREG_MASK (src0
) | DREG_MASK (src1
);
2515 OUTS (outf
, "BITMUX (");
2516 OUTS (outf
, dregs (src0
));
2518 OUTS (outf
, dregs (src1
));
2519 OUTS (outf
, ", A0) (ASR)");
2522 else if (sop
== 1 && sopcde
== 8)
2523 return DREG_MASK (src0
) | DREG_MASK (src1
);
2526 OUTS (outf
, "BITMUX (");
2527 OUTS (outf
, dregs (src0
));
2529 OUTS (outf
, dregs (src1
));
2530 OUTS (outf
, ", A0) (ASL)");
2533 else if (sopcde
== 9)
2534 return sop
< 2 ? DREGL_MASK (dst0
) : DREG_MASK (dst0
);
2535 else if (sopcde
== 10)
2536 return DREG_MASK (dst0
);
2537 else if (sop
== 0 && sopcde
== 11)
2538 return DREGL_MASK (dst0
);
2539 else if (sop
== 1 && sopcde
== 11)
2540 return DREGL_MASK (dst0
);
2541 else if (sop
== 0 && sopcde
== 12)
2543 else if (sop
== 1 && sopcde
== 12)
2544 return DREGL_MASK (dst0
);
2545 else if (sop
== 0 && sopcde
== 13)
2546 return DREG_MASK (dst0
);
2547 else if (sop
== 1 && sopcde
== 13)
2548 return DREG_MASK (dst0
);
2549 else if (sop
== 2 && sopcde
== 13)
2550 return DREG_MASK (dst0
);
2556 decode_dsp32shiftimm_0 (int iw0
, int iw1
)
2559 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2560 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............|
2561 |.sop...|.HLs...|.dst0......|.immag.................|.src1......|
2562 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2563 int sop
= ((iw1
>> DSP32ShiftImm_sop_bits
) & DSP32ShiftImm_sop_mask
);
2564 int bit8
= ((iw1
>> 8) & 0x1);
2565 int dst0
= ((iw1
>> DSP32ShiftImm_dst0_bits
) & DSP32ShiftImm_dst0_mask
);
2566 int sopcde
= ((iw0
>> (DSP32ShiftImm_sopcde_bits
- 16)) & DSP32ShiftImm_sopcde_mask
);
2567 int HLs
= ((iw1
>> DSP32ShiftImm_HLs_bits
) & DSP32ShiftImm_HLs_mask
);
2570 if (sop
== 0 && sopcde
== 0)
2571 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2572 else if (sop
== 1 && sopcde
== 0 && bit8
== 0)
2573 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2574 else if (sop
== 1 && sopcde
== 0 && bit8
== 1)
2575 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2576 else if (sop
== 2 && sopcde
== 0 && bit8
== 0)
2577 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2578 else if (sop
== 2 && sopcde
== 0 && bit8
== 1)
2579 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2580 else if (sop
== 2 && sopcde
== 3 && HLs
== 1)
2582 else if (sop
== 0 && sopcde
== 3 && HLs
== 0 && bit8
== 0)
2584 else if (sop
== 0 && sopcde
== 3 && HLs
== 0 && bit8
== 1)
2586 else if (sop
== 0 && sopcde
== 3 && HLs
== 1 && bit8
== 0)
2588 else if (sop
== 0 && sopcde
== 3 && HLs
== 1 && bit8
== 1)
2590 else if (sop
== 1 && sopcde
== 3 && HLs
== 0)
2592 else if (sop
== 1 && sopcde
== 3 && HLs
== 1)
2594 else if (sop
== 2 && sopcde
== 3 && HLs
== 0)
2596 else if (sop
== 1 && sopcde
== 1 && bit8
== 0)
2597 return DREG_MASK (dst0
);
2598 else if (sop
== 1 && sopcde
== 1 && bit8
== 1)
2599 return DREG_MASK (dst0
);
2600 else if (sop
== 2 && sopcde
== 1 && bit8
== 1)
2601 return DREG_MASK (dst0
);
2602 else if (sop
== 2 && sopcde
== 1 && bit8
== 0)
2603 return DREG_MASK (dst0
);
2604 else if (sop
== 0 && sopcde
== 1)
2605 return DREG_MASK (dst0
);
2606 else if (sop
== 1 && sopcde
== 2)
2607 return DREG_MASK (dst0
);
2608 else if (sop
== 2 && sopcde
== 2 && bit8
== 1)
2609 return DREG_MASK (dst0
);
2610 else if (sop
== 2 && sopcde
== 2 && bit8
== 0)
2611 return DREG_MASK (dst0
);
2612 else if (sop
== 3 && sopcde
== 2)
2613 return DREG_MASK (dst0
);
2614 else if (sop
== 0 && sopcde
== 2)
2615 return DREG_MASK (dst0
);
2621 insn_regmask (int iw0
, int iw1
)
2623 if ((iw0
& 0xf7ff) == 0xc003 && iw1
== 0x1800)
2624 return 0; /* MNOP */
2625 else if ((iw0
& 0xff00) == 0x0000)
2626 return decode_ProgCtrl_0 (iw0
);
2627 else if ((iw0
& 0xffc0) == 0x0240)
2629 else if ((iw0
& 0xff80) == 0x0100)
2631 else if ((iw0
& 0xfe00) == 0x0400)
2633 else if ((iw0
& 0xfe00) == 0x0600)
2635 else if ((iw0
& 0xf800) == 0x0800)
2637 else if ((iw0
& 0xffe0) == 0x0200)
2639 else if ((iw0
& 0xff00) == 0x0300)
2641 else if ((iw0
& 0xf000) == 0x1000)
2643 else if ((iw0
& 0xf000) == 0x2000)
2645 else if ((iw0
& 0xf000) == 0x3000)
2647 else if ((iw0
& 0xfc00) == 0x4000)
2649 else if ((iw0
& 0xfe00) == 0x4400)
2651 else if ((iw0
& 0xf800) == 0x4800)
2653 else if ((iw0
& 0xf000) == 0x5000)
2655 else if ((iw0
& 0xf800) == 0x6000)
2657 else if ((iw0
& 0xf800) == 0x6800)
2659 else if ((iw0
& 0xf000) == 0x8000)
2660 return decode_LDSTpmod_0 (iw0
);
2661 else if ((iw0
& 0xff60) == 0x9e60)
2662 return decode_dagMODim_0 (iw0
);
2663 else if ((iw0
& 0xfff0) == 0x9f60)
2664 return decode_dagMODik_0 (iw0
);
2665 else if ((iw0
& 0xfc00) == 0x9c00)
2666 return decode_dspLDST_0 (iw0
);
2667 else if ((iw0
& 0xf000) == 0x9000)
2668 return decode_LDST_0 (iw0
);
2669 else if ((iw0
& 0xfc00) == 0xb800)
2670 return decode_LDSTiiFP_0 (iw0
);
2671 else if ((iw0
& 0xe000) == 0xA000)
2672 return decode_LDSTii_0 (iw0
);
2673 else if ((iw0
& 0xff80) == 0xe080 && (iw1
& 0x0C00) == 0x0000)
2675 else if ((iw0
& 0xff00) == 0xe100 && (iw1
& 0x0000) == 0x0000)
2677 else if ((iw0
& 0xfe00) == 0xe200 && (iw1
& 0x0000) == 0x0000)
2679 else if ((iw0
& 0xfc00) == 0xe400 && (iw1
& 0x0000) == 0x0000)
2681 else if ((iw0
& 0xfffe) == 0xe800 && (iw1
& 0x0000) == 0x0000)
2683 else if ((iw0
& 0xf600) == 0xc000 && (iw1
& 0x0000) == 0x0000)
2684 return decode_dsp32mac_0 (iw0
, iw1
);
2685 else if ((iw0
& 0xf600) == 0xc200 && (iw1
& 0x0000) == 0x0000)
2686 return decode_dsp32mult_0 (iw0
, iw1
);
2687 else if ((iw0
& 0xf7c0) == 0xc400 && (iw1
& 0x0000) == 0x0000)
2688 return decode_dsp32alu_0 (iw0
, iw1
);
2689 else if ((iw0
& 0xf780) == 0xc600 && (iw1
& 0x01c0) == 0x0000)
2690 return decode_dsp32shift_0 (iw0
, iw1
);
2691 else if ((iw0
& 0xf780) == 0xc680 && (iw1
& 0x0000) == 0x0000)
2692 return decode_dsp32shiftimm_0 (iw0
, iw1
);
2693 else if ((iw0
& 0xff00) == 0xf800)
2695 else if ((iw0
& 0xFFC0) == 0xf000 && (iw1
& 0x0000) == 0x0000)