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;
67 static const struct bfin_reg_entry bfin_reg_info
[] = {
189 {"sftreset", REG_sftreset
},
190 {"omode", REG_omode
},
191 {"excause", REG_excause
},
192 {"emucause", REG_emucause
},
193 {"idle_req", REG_idle_req
},
194 {"hwerrcause", REG_hwerrcause
},
198 {"ASTAT", REG_ASTAT
},
204 {"CYCLES", REG_CYCLES
},
205 {"CYCLES2", REG_CYCLES2
},
207 {"SEQSTAT", REG_SEQSTAT
},
208 {"SYSCFG", REG_SYSCFG
},
213 {"EMUDAT", REG_EMUDAT
},
217 /* Blackfin specific function to handle FD-PIC pointer initializations. */
220 bfin_pic_ptr (int nbytes
)
228 #ifdef md_flush_pending_output
229 md_flush_pending_output ();
232 if (is_it_end_of_statement ())
234 demand_empty_rest_of_line ();
239 md_cons_align (nbytes
);
244 bfd_reloc_code_real_type reloc_type
= BFD_RELOC_BFIN_FUNCDESC
;
246 if (strncasecmp (input_line_pointer
, "funcdesc(", 9) == 0)
248 input_line_pointer
+= 9;
250 if (*input_line_pointer
== ')')
251 input_line_pointer
++;
253 as_bad (_("missing ')'"));
256 error ("missing funcdesc in picptr");
260 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &exp
, 0,
263 while (*input_line_pointer
++ == ',');
265 input_line_pointer
--; /* Put terminator back into stream. */
266 demand_empty_rest_of_line ();
270 bfin_s_bss (int ignore ATTRIBUTE_UNUSED
)
274 temp
= get_absolute_expression ();
275 subseg_set (bss_section
, (subsegT
) temp
);
276 demand_empty_rest_of_line ();
279 const pseudo_typeS md_pseudo_table
[] = {
280 {"align", s_align_bytes
, 0},
283 {"picptr", bfin_pic_ptr
, 4},
284 {"code", obj_elf_section
, 0},
289 {"pdata", s_ignore
, 0},
290 {"var", s_ignore
, 0},
291 {"bss", bfin_s_bss
, 0},
295 /* Characters that are used to denote comments and line separators. */
296 const char comment_chars
[] = "";
297 const char line_comment_chars
[] = "#";
298 const char line_separator_chars
[] = ";";
300 /* Characters that can be used to separate the mantissa from the
301 exponent in floating point numbers. */
302 const char EXP_CHARS
[] = "eE";
304 /* Characters that mean this number is a floating point constant.
305 As in 0f12.456 or 0d1.2345e12. */
306 const char FLT_CHARS
[] = "fFdDxX";
308 typedef enum bfin_cpu_type
342 bfin_cpu_t bfin_cpu_type
= BFIN_CPU_UNKNOWN
;
343 /* -msi-revision support. There are three special values:
344 -1 -msi-revision=none.
345 0xffff -msi-revision=any. */
346 int bfin_si_revision
;
348 unsigned int bfin_anomaly_checks
= 0;
355 unsigned int anomaly_checks
;
358 struct bfin_cpu bfin_cpus
[] =
360 {"bf512", BFIN_CPU_BF512
, 0x0001, AC_05000074
},
361 {"bf512", BFIN_CPU_BF512
, 0x0000, AC_05000074
},
363 {"bf514", BFIN_CPU_BF514
, 0x0001, AC_05000074
},
364 {"bf514", BFIN_CPU_BF514
, 0x0000, AC_05000074
},
366 {"bf516", BFIN_CPU_BF516
, 0x0001, AC_05000074
},
367 {"bf516", BFIN_CPU_BF516
, 0x0000, AC_05000074
},
369 {"bf518", BFIN_CPU_BF518
, 0x0001, AC_05000074
},
370 {"bf518", BFIN_CPU_BF518
, 0x0000, AC_05000074
},
372 {"bf522", BFIN_CPU_BF522
, 0x0002, AC_05000074
},
373 {"bf522", BFIN_CPU_BF522
, 0x0001, AC_05000074
},
374 {"bf522", BFIN_CPU_BF522
, 0x0000, AC_05000074
},
376 {"bf523", BFIN_CPU_BF523
, 0x0002, AC_05000074
},
377 {"bf523", BFIN_CPU_BF523
, 0x0001, AC_05000074
},
378 {"bf523", BFIN_CPU_BF523
, 0x0000, AC_05000074
},
380 {"bf524", BFIN_CPU_BF524
, 0x0002, AC_05000074
},
381 {"bf524", BFIN_CPU_BF524
, 0x0001, AC_05000074
},
382 {"bf524", BFIN_CPU_BF524
, 0x0000, AC_05000074
},
384 {"bf525", BFIN_CPU_BF525
, 0x0002, AC_05000074
},
385 {"bf525", BFIN_CPU_BF525
, 0x0001, AC_05000074
},
386 {"bf525", BFIN_CPU_BF525
, 0x0000, AC_05000074
},
388 {"bf526", BFIN_CPU_BF526
, 0x0002, AC_05000074
},
389 {"bf526", BFIN_CPU_BF526
, 0x0001, AC_05000074
},
390 {"bf526", BFIN_CPU_BF526
, 0x0000, AC_05000074
},
392 {"bf527", BFIN_CPU_BF527
, 0x0002, AC_05000074
},
393 {"bf527", BFIN_CPU_BF527
, 0x0001, AC_05000074
},
394 {"bf527", BFIN_CPU_BF527
, 0x0000, AC_05000074
},
396 {"bf531", BFIN_CPU_BF531
, 0x0006, AC_05000074
},
397 {"bf531", BFIN_CPU_BF531
, 0x0005, AC_05000074
},
398 {"bf531", BFIN_CPU_BF531
, 0x0004, AC_05000074
},
399 {"bf531", BFIN_CPU_BF531
, 0x0003, AC_05000074
},
401 {"bf532", BFIN_CPU_BF532
, 0x0006, AC_05000074
},
402 {"bf532", BFIN_CPU_BF532
, 0x0005, AC_05000074
},
403 {"bf532", BFIN_CPU_BF532
, 0x0004, AC_05000074
},
404 {"bf532", BFIN_CPU_BF532
, 0x0003, AC_05000074
},
406 {"bf533", BFIN_CPU_BF533
, 0x0006, AC_05000074
},
407 {"bf533", BFIN_CPU_BF533
, 0x0005, AC_05000074
},
408 {"bf533", BFIN_CPU_BF533
, 0x0004, AC_05000074
},
409 {"bf533", BFIN_CPU_BF533
, 0x0003, AC_05000074
},
411 {"bf534", BFIN_CPU_BF534
, 0x0003, AC_05000074
},
412 {"bf534", BFIN_CPU_BF534
, 0x0002, AC_05000074
},
413 {"bf534", BFIN_CPU_BF534
, 0x0001, AC_05000074
},
415 {"bf536", BFIN_CPU_BF536
, 0x0003, AC_05000074
},
416 {"bf536", BFIN_CPU_BF536
, 0x0002, AC_05000074
},
417 {"bf536", BFIN_CPU_BF536
, 0x0001, AC_05000074
},
419 {"bf537", BFIN_CPU_BF537
, 0x0003, AC_05000074
},
420 {"bf537", BFIN_CPU_BF537
, 0x0002, AC_05000074
},
421 {"bf537", BFIN_CPU_BF537
, 0x0001, AC_05000074
},
423 {"bf538", BFIN_CPU_BF538
, 0x0005, AC_05000074
},
424 {"bf538", BFIN_CPU_BF538
, 0x0004, AC_05000074
},
425 {"bf538", BFIN_CPU_BF538
, 0x0003, AC_05000074
},
426 {"bf538", BFIN_CPU_BF538
, 0x0002, AC_05000074
},
428 {"bf539", BFIN_CPU_BF539
, 0x0005, AC_05000074
},
429 {"bf539", BFIN_CPU_BF539
, 0x0004, AC_05000074
},
430 {"bf539", BFIN_CPU_BF539
, 0x0003, AC_05000074
},
431 {"bf539", BFIN_CPU_BF539
, 0x0002, AC_05000074
},
433 {"bf542m", BFIN_CPU_BF542M
, 0x0003, AC_05000074
},
435 {"bf542", BFIN_CPU_BF542
, 0x0002, AC_05000074
},
436 {"bf542", BFIN_CPU_BF542
, 0x0001, AC_05000074
},
437 {"bf542", BFIN_CPU_BF542
, 0x0000, AC_05000074
},
439 {"bf544m", BFIN_CPU_BF544M
, 0x0003, AC_05000074
},
441 {"bf544", BFIN_CPU_BF544
, 0x0002, AC_05000074
},
442 {"bf544", BFIN_CPU_BF544
, 0x0001, AC_05000074
},
443 {"bf544", BFIN_CPU_BF544
, 0x0000, AC_05000074
},
445 {"bf547m", BFIN_CPU_BF547M
, 0x0003, AC_05000074
},
447 {"bf547", BFIN_CPU_BF547
, 0x0002, AC_05000074
},
448 {"bf547", BFIN_CPU_BF547
, 0x0001, AC_05000074
},
449 {"bf547", BFIN_CPU_BF547
, 0x0000, AC_05000074
},
451 {"bf548m", BFIN_CPU_BF548M
, 0x0003, AC_05000074
},
453 {"bf548", BFIN_CPU_BF548
, 0x0002, AC_05000074
},
454 {"bf548", BFIN_CPU_BF548
, 0x0001, AC_05000074
},
455 {"bf548", BFIN_CPU_BF548
, 0x0000, AC_05000074
},
457 {"bf549m", BFIN_CPU_BF549M
, 0x0003, AC_05000074
},
459 {"bf549", BFIN_CPU_BF549
, 0x0002, AC_05000074
},
460 {"bf549", BFIN_CPU_BF549
, 0x0001, AC_05000074
},
461 {"bf549", BFIN_CPU_BF549
, 0x0000, AC_05000074
},
463 {"bf561", BFIN_CPU_BF561
, 0x0005, AC_05000074
},
464 {"bf561", BFIN_CPU_BF561
, 0x0003, AC_05000074
},
465 {"bf561", BFIN_CPU_BF561
, 0x0002, AC_05000074
},
470 /* Define bfin-specific command-line options (there are none). */
471 const char *md_shortopts
= "";
473 #define OPTION_FDPIC (OPTION_MD_BASE)
474 #define OPTION_NOPIC (OPTION_MD_BASE + 1)
475 #define OPTION_MCPU (OPTION_MD_BASE + 2)
477 struct option md_longopts
[] =
479 { "mcpu", required_argument
, NULL
, OPTION_MCPU
},
480 { "mfdpic", no_argument
, NULL
, OPTION_FDPIC
},
481 { "mnopic", no_argument
, NULL
, OPTION_NOPIC
},
482 { "mno-fdpic", no_argument
, NULL
, OPTION_NOPIC
},
483 { NULL
, no_argument
, NULL
, 0 },
486 size_t md_longopts_size
= sizeof (md_longopts
);
490 md_parse_option (int c ATTRIBUTE_UNUSED
, char *arg ATTRIBUTE_UNUSED
)
503 while ((p
= bfin_cpus
[i
].name
) != NULL
)
505 if (strncmp (arg
, p
, strlen (p
)) == 0)
512 error ("-mcpu=%s is not valid", arg
);
516 bfin_cpu_type
= bfin_cpus
[i
].type
;
518 q
= arg
+ strlen (p
);
522 bfin_si_revision
= bfin_cpus
[i
].si_revision
;
523 bfin_anomaly_checks
|= bfin_cpus
[i
].anomaly_checks
;
525 else if (strcmp (q
, "-none") == 0)
526 bfin_si_revision
= -1;
527 else if (strcmp (q
, "-any") == 0)
529 bfin_si_revision
= 0xffff;
530 while (bfin_cpus
[i
].type
== bfin_cpu_type
)
532 bfin_anomaly_checks
|= bfin_cpus
[i
].anomaly_checks
;
538 unsigned int si_major
, si_minor
;
541 rev_len
= strlen (q
);
543 if (sscanf (q
, "-%u.%u%n", &si_major
, &si_minor
, &n
) != 2
545 || si_major
> 0xff || si_minor
> 0xff)
547 invalid_silicon_revision
:
548 error ("-mcpu=%s has invalid silicon revision", arg
);
552 bfin_si_revision
= (si_major
<< 8) | si_minor
;
554 while (bfin_cpus
[i
].type
== bfin_cpu_type
555 && bfin_cpus
[i
].si_revision
!= bfin_si_revision
)
558 if (bfin_cpus
[i
].type
!= bfin_cpu_type
)
559 goto invalid_silicon_revision
;
561 bfin_anomaly_checks
|= bfin_cpus
[i
].anomaly_checks
;
568 bfin_flags
|= EF_BFIN_FDPIC
;
569 bfin_pic_flag
= "-mfdpic";
573 bfin_flags
&= ~(EF_BFIN_FDPIC
);
582 md_show_usage (FILE * stream ATTRIBUTE_UNUSED
)
584 fprintf (stream
, _(" BFIN specific command line options:\n"));
587 /* Perform machine-specific initializations. */
591 /* Set the ELF flags if desired. */
593 bfd_set_private_flags (stdoutput
, bfin_flags
);
595 /* Set the default machine type. */
596 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_bfin
, 0))
597 as_warn (_("Could not set architecture and machine."));
599 /* Ensure that lines can begin with '(', for multiple
600 register stack pops. */
601 lex_type
['('] = LEX_BEGIN_NAME
;
604 record_alignment (text_section
, 2);
605 record_alignment (data_section
, 2);
606 record_alignment (bss_section
, 2);
610 obstack_init (&mempool
);
613 extern int debug_codeselection
;
614 debug_codeselection
= 1;
620 /* Perform the main parsing, and assembly of the input here. Also,
621 call the required routines for alignment and fixups here.
622 This is called for every line that contains real assembly code. */
625 md_assemble (char *line
)
628 extern char *current_inputline
;
630 struct bfin_insn
*tmp_insn
;
632 static size_t buffer_len
= 0;
636 if (len
+ 2 > buffer_len
)
639 free (current_inputline
);
640 buffer_len
= len
+ 40;
641 current_inputline
= xmalloc (buffer_len
);
643 memcpy (current_inputline
, line
, len
);
644 current_inputline
[len
] = ';';
645 current_inputline
[len
+ 1] = '\0';
647 state
= parse (current_inputline
);
648 if (state
== NO_INSN_GENERATED
)
651 for (insn_size
= 0, tmp_insn
= insn
; tmp_insn
; tmp_insn
= tmp_insn
->next
)
652 if (!tmp_insn
->reloc
|| !tmp_insn
->exp
->symbol
)
656 toP
= frag_more (insn_size
);
658 last_insn_size
= insn_size
;
665 if (insn
->reloc
&& insn
->exp
->symbol
)
667 char *prev_toP
= toP
- 2;
670 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
671 case BFD_RELOC_24_PCREL
:
672 case BFD_RELOC_BFIN_16_LOW
:
673 case BFD_RELOC_BFIN_16_HIGH
:
680 /* Following if condition checks for the arithmetic relocations.
681 If the case then it doesn't required to generate the code.
682 It has been assumed that, their ID will be contiguous. */
683 if ((BFD_ARELOC_BFIN_PUSH
<= insn
->reloc
684 && BFD_ARELOC_BFIN_COMP
>= insn
->reloc
)
685 || insn
->reloc
== BFD_RELOC_BFIN_16_IMM
)
689 if (insn
->reloc
== BFD_ARELOC_BFIN_CONST
690 || insn
->reloc
== BFD_ARELOC_BFIN_PUSH
)
694 (prev_toP
- frag_now
->fr_literal
),
695 size
, insn
->exp
->symbol
, insn
->exp
->value
,
696 insn
->pcrel
, insn
->reloc
);
700 md_number_to_chars (toP
, insn
->value
, 2);
706 printf (" %02x%02x", ((unsigned char *) &insn
->value
)[0],
707 ((unsigned char *) &insn
->value
)[1]);
713 dwarf2_emit_insn (insn_size
);
717 /* Parse one line of instructions, and generate opcode for it.
718 To parse the line, YACC and LEX are used, because the instruction set
719 syntax doesn't confirm to the AT&T assembly syntax.
720 To call a YACC & LEX generated parser, we must provide the input via
721 a FILE stream, otherwise stdin is used by default. Below the input
722 to the function will be put into a temporary file, then the generated
723 parser uses the temporary file for parsing. */
729 YY_BUFFER_STATE buffstate
;
731 buffstate
= yy_scan_string (line
);
733 /* our lex requires setting the start state to keyword
734 every line as the first word may be a keyword.
735 Fixes a bug where we could not have keywords as labels. */
738 /* Call yyparse here. */
740 if (state
== SEMANTIC_ERROR
)
742 as_bad (_("Parse failed."));
746 yy_delete_buffer (buffstate
);
750 /* We need to handle various expressions properly.
751 Such as, [SP--] = 34, concerned by md_assemble(). */
754 md_operand (expressionS
* expressionP
)
756 if (*input_line_pointer
== '[')
758 as_tsktsk ("We found a '['!");
759 input_line_pointer
++;
760 expression (expressionP
);
764 /* Handle undefined symbols. */
766 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
768 return (symbolS
*) 0;
772 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
773 segT segment ATTRIBUTE_UNUSED
)
778 /* Convert from target byte order to host byte order. */
781 md_chars_to_number (char *val
, int n
)
785 for (retval
= 0; n
--;)
794 md_apply_fix (fixS
*fixP
, valueT
*valueP
, segT seg ATTRIBUTE_UNUSED
)
796 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
798 long value
= *valueP
;
801 switch (fixP
->fx_r_type
)
803 case BFD_RELOC_BFIN_GOT
:
804 case BFD_RELOC_BFIN_GOT17M4
:
805 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
806 fixP
->fx_no_overflow
= 1;
807 newval
= md_chars_to_number (where
, 2);
808 newval
|= 0x0 & 0x7f;
809 md_number_to_chars (where
, newval
, 2);
812 case BFD_RELOC_BFIN_10_PCREL
:
815 if (value
< -1024 || value
> 1022)
816 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
817 _("pcrel too far BFD_RELOC_BFIN_10"));
819 /* 11 bit offset even numbered, so we remove right bit. */
821 newval
= md_chars_to_number (where
, 2);
822 newval
|= value
& 0x03ff;
823 md_number_to_chars (where
, newval
, 2);
826 case BFD_RELOC_BFIN_12_PCREL_JUMP
:
827 case BFD_RELOC_BFIN_12_PCREL_JUMP_S
:
828 case BFD_RELOC_12_PCREL
:
832 if (value
< -4096 || value
> 4094)
833 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_12"));
834 /* 13 bit offset even numbered, so we remove right bit. */
836 newval
= md_chars_to_number (where
, 2);
837 newval
|= value
& 0xfff;
838 md_number_to_chars (where
, newval
, 2);
841 case BFD_RELOC_BFIN_16_LOW
:
842 case BFD_RELOC_BFIN_16_HIGH
:
843 fixP
->fx_done
= FALSE
;
846 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
847 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
848 case BFD_RELOC_24_PCREL
:
852 if (value
< -16777216 || value
> 16777214)
853 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_24"));
855 /* 25 bit offset even numbered, so we remove right bit. */
859 md_number_to_chars (where
- 2, value
>> 16, 1);
860 md_number_to_chars (where
, value
, 1);
861 md_number_to_chars (where
+ 1, value
>> 8, 1);
864 case BFD_RELOC_BFIN_5_PCREL
: /* LSETUP (a, b) : "a" */
867 if (value
< 4 || value
> 30)
868 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_5"));
870 newval
= md_chars_to_number (where
, 1);
871 newval
= (newval
& 0xf0) | (value
& 0xf);
872 md_number_to_chars (where
, newval
, 1);
875 case BFD_RELOC_BFIN_11_PCREL
: /* LSETUP (a, b) : "b" */
879 if (value
< 4 || value
> 2046)
880 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_11_PCREL"));
881 /* 11 bit unsigned even, so we remove right bit. */
883 newval
= md_chars_to_number (where
, 2);
884 newval
|= value
& 0x03ff;
885 md_number_to_chars (where
, newval
, 2);
889 if (value
< -0x80 || value
>= 0x7f)
890 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("rel too far BFD_RELOC_8"));
891 md_number_to_chars (where
, value
, 1);
894 case BFD_RELOC_BFIN_16_IMM
:
896 if (value
< -0x8000 || value
>= 0x7fff)
897 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("rel too far BFD_RELOC_16"));
898 md_number_to_chars (where
, value
, 2);
902 md_number_to_chars (where
, value
, 4);
905 case BFD_RELOC_BFIN_PLTPC
:
906 md_number_to_chars (where
, value
, 2);
909 case BFD_RELOC_BFIN_FUNCDESC
:
910 case BFD_RELOC_VTABLE_INHERIT
:
911 case BFD_RELOC_VTABLE_ENTRY
:
912 fixP
->fx_done
= FALSE
;
916 if ((BFD_ARELOC_BFIN_PUSH
> fixP
->fx_r_type
) || (BFD_ARELOC_BFIN_COMP
< fixP
->fx_r_type
))
918 fprintf (stderr
, "Relocation %d not handled in gas." " Contact support.\n", fixP
->fx_r_type
);
924 fixP
->fx_done
= TRUE
;
928 /* Round up a section size to the appropriate boundary. */
930 md_section_align (segment
, size
)
934 int boundary
= bfd_get_section_alignment (stdoutput
, segment
);
935 return ((size
+ (1 << boundary
) - 1) & (-1 << boundary
));
940 md_atof (int type
, char * litP
, int * sizeP
)
942 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
946 /* If while processing a fixup, a reloc really needs to be created
947 then it is done here. */
950 tc_gen_reloc (seg
, fixp
)
951 asection
*seg ATTRIBUTE_UNUSED
;
956 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
957 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
958 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
959 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
961 reloc
->addend
= fixp
->fx_offset
;
962 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
964 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
966 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
967 /* xgettext:c-format. */
968 _("reloc %d not supported by object file format"),
969 (int) fixp
->fx_r_type
);
979 /* The location from which a PC relative jump should be calculated,
980 given a PC relative reloc. */
983 md_pcrel_from_section (fixP
, sec
)
987 if (fixP
->fx_addsy
!= (symbolS
*) NULL
988 && (!S_IS_DEFINED (fixP
->fx_addsy
)
989 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
991 /* The symbol is undefined (or is defined but not in this section).
992 Let the linker figure it out. */
995 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
998 /* Return true if the fix can be handled by GAS, false if it must
999 be passed through to the linker. */
1002 bfin_fix_adjustable (fixS
*fixP
)
1004 switch (fixP
->fx_r_type
)
1006 /* Adjust_reloc_syms doesn't know about the GOT. */
1007 case BFD_RELOC_BFIN_GOT
:
1008 case BFD_RELOC_BFIN_PLTPC
:
1009 /* We need the symbol name for the VTABLE entries. */
1010 case BFD_RELOC_VTABLE_INHERIT
:
1011 case BFD_RELOC_VTABLE_ENTRY
:
1019 /* Special extra functions that help bfin-parse.y perform its job. */
1021 struct obstack mempool
;
1024 conscode (INSTR_T head
, INSTR_T tail
)
1033 conctcode (INSTR_T head
, INSTR_T tail
)
1035 INSTR_T temp
= (head
);
1046 note_reloc (INSTR_T code
, Expr_Node
* symbol
, int reloc
, int pcrel
)
1048 /* Assert that the symbol is not an operator. */
1049 gas_assert (symbol
->type
== Expr_Node_Reloc
);
1051 return note_reloc1 (code
, symbol
->value
.s_value
, reloc
, pcrel
);
1056 note_reloc1 (INSTR_T code
, const char *symbol
, int reloc
, int pcrel
)
1058 code
->reloc
= reloc
;
1059 code
->exp
= mkexpr (0, symbol_find_or_make (symbol
));
1060 code
->pcrel
= pcrel
;
1065 note_reloc2 (INSTR_T code
, const char *symbol
, int reloc
, int value
, int pcrel
)
1067 code
->reloc
= reloc
;
1068 code
->exp
= mkexpr (value
, symbol_find_or_make (symbol
));
1069 code
->pcrel
= pcrel
;
1074 gencode (unsigned long x
)
1076 INSTR_T cell
= obstack_alloc (&mempool
, sizeof (struct bfin_insn
));
1077 memset (cell
, 0, sizeof (struct bfin_insn
));
1089 return obstack_alloc (&mempool
, n
);
1093 Expr_Node_Create (Expr_Node_Type type
,
1094 Expr_Node_Value value
,
1095 Expr_Node
*Left_Child
,
1096 Expr_Node
*Right_Child
)
1100 Expr_Node
*node
= (Expr_Node
*) allocate (sizeof (Expr_Node
));
1102 node
->value
= value
;
1103 node
->Left_Child
= Left_Child
;
1104 node
->Right_Child
= Right_Child
;
1108 static const char *con
= ".__constant";
1109 static const char *op
= ".__operator";
1110 static INSTR_T
Expr_Node_Gen_Reloc_R (Expr_Node
* head
);
1111 INSTR_T
Expr_Node_Gen_Reloc (Expr_Node
*head
, int parent_reloc
);
1114 Expr_Node_Gen_Reloc (Expr_Node
* head
, int parent_reloc
)
1116 /* Top level reloction expression generator VDSP style.
1117 If the relocation is just by itself, generate one item
1118 else generate this convoluted expression. */
1120 INSTR_T note
= NULL_CODE
;
1121 INSTR_T note1
= NULL_CODE
;
1122 int pcrel
= 1; /* Is the parent reloc pcrelative?
1123 This calculation here and HOWTO should match. */
1127 /* If it's 32 bit quantity then 16bit code needs to be added. */
1130 if (head
->type
== Expr_Node_Constant
)
1132 /* If note1 is not null code, we have to generate a right
1133 aligned value for the constant. Otherwise the reloc is
1134 a part of the basic command and the yacc file
1136 value
= head
->value
.i_value
;
1138 switch (parent_reloc
)
1140 /* Some relocations will need to allocate extra words. */
1141 case BFD_RELOC_BFIN_16_IMM
:
1142 case BFD_RELOC_BFIN_16_LOW
:
1143 case BFD_RELOC_BFIN_16_HIGH
:
1144 note1
= conscode (gencode (value
), NULL_CODE
);
1147 case BFD_RELOC_BFIN_PLTPC
:
1148 note1
= conscode (gencode (value
), NULL_CODE
);
1152 case BFD_RELOC_BFIN_GOT
:
1153 case BFD_RELOC_BFIN_GOT17M4
:
1154 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
1155 note1
= conscode (gencode (value
), NULL_CODE
);
1158 case BFD_RELOC_24_PCREL
:
1159 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
1160 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
1161 /* These offsets are even numbered pcrel. */
1162 note1
= conscode (gencode (value
>> 1), NULL_CODE
);
1168 if (head
->type
== Expr_Node_Constant
)
1170 else if (head
->type
== Expr_Node_Reloc
)
1172 note
= note_reloc1 (gencode (0), head
->value
.s_value
, parent_reloc
, pcrel
);
1173 if (note1
!= NULL_CODE
)
1174 note
= conscode (note1
, note
);
1176 else if (head
->type
== Expr_Node_Binop
1177 && (head
->value
.op_value
== Expr_Op_Type_Add
1178 || head
->value
.op_value
== Expr_Op_Type_Sub
)
1179 && head
->Left_Child
->type
== Expr_Node_Reloc
1180 && head
->Right_Child
->type
== Expr_Node_Constant
)
1182 int val
= head
->Right_Child
->value
.i_value
;
1183 if (head
->value
.op_value
== Expr_Op_Type_Sub
)
1185 note
= conscode (note_reloc2 (gencode (0), head
->Left_Child
->value
.s_value
,
1186 parent_reloc
, val
, 0),
1188 if (note1
!= NULL_CODE
)
1189 note
= conscode (note1
, note
);
1193 /* Call the recursive function. */
1194 note
= note_reloc1 (gencode (0), op
, parent_reloc
, pcrel
);
1195 if (note1
!= NULL_CODE
)
1196 note
= conscode (note1
, note
);
1197 note
= conctcode (Expr_Node_Gen_Reloc_R (head
), note
);
1203 Expr_Node_Gen_Reloc_R (Expr_Node
* head
)
1211 case Expr_Node_Constant
:
1212 note
= conscode (note_reloc2 (gencode (0), con
, BFD_ARELOC_BFIN_CONST
, head
->value
.i_value
, 0), NULL_CODE
);
1214 case Expr_Node_Reloc
:
1215 note
= conscode (note_reloc (gencode (0), head
, BFD_ARELOC_BFIN_PUSH
, 0), NULL_CODE
);
1217 case Expr_Node_Binop
:
1218 note1
= conctcode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), Expr_Node_Gen_Reloc_R (head
->Right_Child
));
1219 switch (head
->value
.op_value
)
1221 case Expr_Op_Type_Add
:
1222 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_ADD
, 0), NULL_CODE
));
1224 case Expr_Op_Type_Sub
:
1225 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_SUB
, 0), NULL_CODE
));
1227 case Expr_Op_Type_Mult
:
1228 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MULT
, 0), NULL_CODE
));
1230 case Expr_Op_Type_Div
:
1231 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_DIV
, 0), NULL_CODE
));
1233 case Expr_Op_Type_Mod
:
1234 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MOD
, 0), NULL_CODE
));
1236 case Expr_Op_Type_Lshift
:
1237 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LSHIFT
, 0), NULL_CODE
));
1239 case Expr_Op_Type_Rshift
:
1240 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_RSHIFT
, 0), NULL_CODE
));
1242 case Expr_Op_Type_BAND
:
1243 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_AND
, 0), NULL_CODE
));
1245 case Expr_Op_Type_BOR
:
1246 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_OR
, 0), NULL_CODE
));
1248 case Expr_Op_Type_BXOR
:
1249 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_XOR
, 0), NULL_CODE
));
1251 case Expr_Op_Type_LAND
:
1252 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LAND
, 0), NULL_CODE
));
1254 case Expr_Op_Type_LOR
:
1255 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LOR
, 0), NULL_CODE
));
1258 fprintf (stderr
, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1263 case Expr_Node_Unop
:
1264 note1
= conscode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), NULL_CODE
);
1265 switch (head
->value
.op_value
)
1267 case Expr_Op_Type_NEG
:
1268 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_NEG
, 0), NULL_CODE
));
1270 case Expr_Op_Type_COMP
:
1271 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_COMP
, 0), NULL_CODE
));
1274 fprintf (stderr
, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1278 fprintf (stderr
, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__
, __LINE__
);
1283 /* Blackfin opcode generation. */
1285 /* These functions are called by the generated parser
1286 (from bfin-parse.y), the register type classification
1287 happens in bfin-lex.l. */
1289 #include "bfin-aux.h"
1290 #include "opcode/bfin.h"
1292 #define INIT(t) t c_code = init_##t
1293 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1294 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1296 #define HI(x) ((x >> 16) & 0xffff)
1297 #define LO(x) ((x ) & 0xffff)
1299 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1301 #define GEN_OPCODE32() \
1302 conscode (gencode (HI (c_code.opcode)), \
1303 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1305 #define GEN_OPCODE16() \
1306 conscode (gencode (c_code.opcode), NULL_CODE)
1309 /* 32 BIT INSTRUCTIONS. */
1312 /* DSP32 instruction generation. */
1315 bfin_gen_dsp32mac (int op1
, int MM
, int mmod
, int w1
, int P
,
1316 int h01
, int h11
, int h00
, int h10
, int op0
,
1317 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1333 /* If we have full reg assignments, mask out LSB to encode
1334 single or simultaneous even/odd register moves. */
1344 return GEN_OPCODE32 ();
1348 bfin_gen_dsp32mult (int op1
, int MM
, int mmod
, int w1
, int P
,
1349 int h01
, int h11
, int h00
, int h10
, int op0
,
1350 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1375 return GEN_OPCODE32 ();
1379 bfin_gen_dsp32alu (int HL
, int aopcde
, int aop
, int s
, int x
,
1380 REG_T dst0
, REG_T dst1
, REG_T src0
, REG_T src1
)
1394 return GEN_OPCODE32 ();
1398 bfin_gen_dsp32shift (int sopcde
, REG_T dst0
, REG_T src0
,
1399 REG_T src1
, int sop
, int HLs
)
1411 return GEN_OPCODE32 ();
1415 bfin_gen_dsp32shiftimm (int sopcde
, REG_T dst0
, int immag
,
1416 REG_T src1
, int sop
, int HLs
)
1418 INIT (DSP32ShiftImm
);
1428 return GEN_OPCODE32 ();
1434 bfin_gen_loopsetup (Expr_Node
* psoffset
, REG_T c
, int rop
,
1435 Expr_Node
* peoffset
, REG_T reg
)
1437 int soffset
, eoffset
;
1440 soffset
= (EXPR_VALUE (psoffset
) >> 1);
1442 eoffset
= (EXPR_VALUE (peoffset
) >> 1);
1449 conscode (gencode (HI (c_code
.opcode
)),
1450 conctcode (Expr_Node_Gen_Reloc (psoffset
, BFD_RELOC_BFIN_5_PCREL
),
1451 conctcode (gencode (LO (c_code
.opcode
)), Expr_Node_Gen_Reloc (peoffset
, BFD_RELOC_BFIN_11_PCREL
))));
1458 bfin_gen_calla (Expr_Node
* addr
, int S
)
1466 case 0 : reloc
= BFD_RELOC_BFIN_24_PCREL_JUMP_L
; break;
1467 case 1 : reloc
= BFD_RELOC_24_PCREL
; break;
1468 case 2 : reloc
= BFD_RELOC_BFIN_PLTPC
; break;
1474 val
= EXPR_VALUE (addr
) >> 1;
1475 high_val
= val
>> 16;
1477 return conscode (gencode (HI (c_code
.opcode
) | (high_val
& 0xff)),
1478 Expr_Node_Gen_Reloc (addr
, reloc
));
1482 bfin_gen_linkage (int R
, int framesize
)
1489 return GEN_OPCODE32 ();
1493 /* Load and Store. */
1496 bfin_gen_ldimmhalf (REG_T reg
, int H
, int S
, int Z
, Expr_Node
* phword
, int reloc
)
1499 unsigned val
= EXPR_VALUE (phword
);
1507 grp
= (GROUP (reg
));
1511 return conscode (gencode (HI (c_code
.opcode
)), Expr_Node_Gen_Reloc (phword
, BFD_RELOC_BFIN_16_IMM
));
1513 else if (reloc
== 1)
1515 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
));
1522 return GEN_OPCODE32 ();
1526 bfin_gen_ldstidxi (REG_T ptr
, REG_T reg
, int W
, int sz
, int Z
, Expr_Node
* poffset
)
1530 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1532 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1543 if (poffset
->type
!= Expr_Node_Constant
)
1545 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1546 /* distinguish between R0 = [P5 + symbol@GOT] and
1547 P5 = [P5 + _current_shared_library_p5_offset_]
1549 if (poffset
->type
== Expr_Node_Reloc
1550 && !strcmp (poffset
->value
.s_value
,
1551 "_current_shared_library_p5_offset_"))
1553 return conscode (gencode (HI (c_code
.opcode
)),
1554 Expr_Node_Gen_Reloc(poffset
, BFD_RELOC_16
));
1556 else if (poffset
->type
!= Expr_Node_GOT_Reloc
)
1559 return conscode (gencode (HI (c_code
.opcode
)),
1560 Expr_Node_Gen_Reloc(poffset
->Left_Child
,
1561 poffset
->value
.i_value
));
1567 { /* load/store access size */
1568 case 0: /* 32 bit */
1569 value
= EXPR_VALUE (poffset
) >> 2;
1571 case 1: /* 16 bit */
1572 value
= EXPR_VALUE (poffset
) >> 1;
1575 value
= EXPR_VALUE (poffset
);
1581 offset
= (value
& 0xffff);
1583 return GEN_OPCODE32 ();
1589 bfin_gen_ldst (REG_T ptr
, REG_T reg
, int aop
, int sz
, int Z
, int W
)
1593 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1595 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1606 return GEN_OPCODE16 ();
1610 bfin_gen_ldstii (REG_T ptr
, REG_T reg
, Expr_Node
* poffset
, int W
, int op
)
1617 if (!IS_PREG (*ptr
))
1619 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1627 value
= EXPR_VALUE (poffset
) >> 1;
1631 value
= EXPR_VALUE (poffset
) >> 2;
1643 return GEN_OPCODE16 ();
1647 bfin_gen_ldstiifp (REG_T sreg
, Expr_Node
* poffset
, int W
)
1649 /* Set bit 4 if it's a Preg. */
1650 int reg
= (sreg
->regno
& CODE_MASK
) | (IS_PREG (*sreg
) ? 0x8 : 0x0);
1651 int offset
= ((~(EXPR_VALUE (poffset
) >> 2)) & 0x1f) + 1;
1657 return GEN_OPCODE16 ();
1661 bfin_gen_ldstpmod (REG_T ptr
, REG_T reg
, int aop
, int W
, REG_T idx
)
1671 return GEN_OPCODE16 ();
1675 bfin_gen_dspldst (REG_T i
, REG_T reg
, int aop
, int W
, int m
)
1685 return GEN_OPCODE16 ();
1689 bfin_gen_logi2op (int opc
, int src
, int dst
)
1697 return GEN_OPCODE16 ();
1701 bfin_gen_brcc (int T
, int B
, Expr_Node
* poffset
)
1708 offset
= ((EXPR_VALUE (poffset
) >> 1));
1710 return conscode (gencode (c_code
.opcode
), Expr_Node_Gen_Reloc (poffset
, BFD_RELOC_BFIN_10_PCREL
));
1714 bfin_gen_ujump (Expr_Node
* poffset
)
1719 offset
= ((EXPR_VALUE (poffset
) >> 1));
1722 return conscode (gencode (c_code
.opcode
),
1723 Expr_Node_Gen_Reloc (
1724 poffset
, BFD_RELOC_BFIN_12_PCREL_JUMP_S
));
1728 bfin_gen_alu2op (REG_T dst
, REG_T src
, int opc
)
1736 return GEN_OPCODE16 ();
1740 bfin_gen_compi2opd (REG_T dst
, int src
, int op
)
1748 return GEN_OPCODE16 ();
1752 bfin_gen_compi2opp (REG_T dst
, int src
, int op
)
1760 return GEN_OPCODE16 ();
1764 bfin_gen_dagmodik (REG_T i
, int op
)
1771 return GEN_OPCODE16 ();
1775 bfin_gen_dagmodim (REG_T i
, REG_T m
, int op
, int br
)
1784 return GEN_OPCODE16 ();
1788 bfin_gen_ptr2op (REG_T dst
, REG_T src
, int opc
)
1796 return GEN_OPCODE16 ();
1800 bfin_gen_comp3op (REG_T src0
, REG_T src1
, REG_T dst
, int opc
)
1809 return GEN_OPCODE16 ();
1813 bfin_gen_ccflag (REG_T x
, int y
, int opc
, int I
, int G
)
1823 return GEN_OPCODE16 ();
1827 bfin_gen_ccmv (REG_T src
, REG_T dst
, int T
)
1840 return GEN_OPCODE16 ();
1844 bfin_gen_cc2stat (int cbit
, int op
, int D
)
1852 return GEN_OPCODE16 ();
1856 bfin_gen_regmv (REG_T src
, REG_T dst
)
1869 return GEN_OPCODE16 ();
1873 bfin_gen_cc2dreg (int op
, REG_T reg
)
1880 return GEN_OPCODE16 ();
1884 bfin_gen_progctrl (int prgfunc
, int poprnd
)
1891 return GEN_OPCODE16 ();
1895 bfin_gen_cactrl (REG_T reg
, int a
, int op
)
1903 return GEN_OPCODE16 ();
1907 bfin_gen_pushpopmultiple (int dr
, int pr
, int d
, int p
, int W
)
1909 INIT (PushPopMultiple
);
1917 return GEN_OPCODE16 ();
1921 bfin_gen_pushpopreg (REG_T reg
, int W
)
1927 grp
= (GROUP (reg
));
1931 return GEN_OPCODE16 ();
1934 /* Pseudo Debugging Support. */
1937 bfin_gen_pseudodbg (int fn
, int reg
, int grp
)
1945 return GEN_OPCODE16 ();
1949 bfin_gen_pseudodbg_assert (int dbgop
, REG_T regtest
, int expected
)
1951 INIT (PseudoDbg_Assert
);
1957 return GEN_OPCODE32 ();
1960 /* Multiple instruction generation. */
1963 bfin_gen_multi_instr (INSTR_T dsp32
, INSTR_T dsp16_grp1
, INSTR_T dsp16_grp2
)
1967 /* If it's a 0, convert into MNOP. */
1971 SET_MULTI_INSTRUCTION_BIT (dsp32
);
1975 dsp32
= gencode (0xc803);
1976 walk
= gencode (0x1800);
1982 dsp16_grp1
= gencode (0x0000);
1987 dsp16_grp2
= gencode (0x0000);
1990 walk
->next
= dsp16_grp1
;
1991 dsp16_grp1
->next
= dsp16_grp2
;
1992 dsp16_grp2
->next
= NULL_CODE
;
1998 bfin_gen_loop (Expr_Node
*expr
, REG_T reg
, int rop
, REG_T preg
)
2000 const char *loopsym
;
2001 char *lbeginsym
, *lendsym
;
2002 Expr_Node_Value lbeginval
, lendval
;
2003 Expr_Node
*lbegin
, *lend
;
2005 loopsym
= expr
->value
.s_value
;
2006 lbeginsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__BEGIN") + 5);
2007 lendsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__END") + 5);
2012 strcat (lbeginsym
, "L$L$");
2013 strcat (lbeginsym
, loopsym
);
2014 strcat (lbeginsym
, "__BEGIN");
2016 strcat (lendsym
, "L$L$");
2017 strcat (lendsym
, loopsym
);
2018 strcat (lendsym
, "__END");
2020 lbeginval
.s_value
= lbeginsym
;
2021 lendval
.s_value
= lendsym
;
2023 lbegin
= Expr_Node_Create (Expr_Node_Reloc
, lbeginval
, NULL
, NULL
);
2024 lend
= Expr_Node_Create (Expr_Node_Reloc
, lendval
, NULL
, NULL
);
2026 symbol_remove (symbol_find (loopsym
), &symbol_rootP
, &symbol_lastP
);
2028 return bfin_gen_loopsetup(lbegin
, reg
, rop
, lend
, preg
);
2032 bfin_loop_beginend (Expr_Node
*expr
, int begin
)
2034 const char *loopsym
;
2036 symbolS
*line_label
;
2037 const char *suffix
= begin
? "__BEGIN" : "__END";
2039 loopsym
= expr
->value
.s_value
;
2040 label_name
= (char *) xmalloc (strlen (loopsym
) + strlen (suffix
) + 5);
2044 strcat (label_name
, "L$L$");
2045 strcat (label_name
, loopsym
);
2046 strcat (label_name
, suffix
);
2048 line_label
= colon (label_name
);
2050 /* LOOP_END follows the last instruction in the loop.
2051 Adjust label address. */
2053 ((struct local_symbol
*) line_label
)->lsy_value
-= last_insn_size
;
2057 bfin_eol_in_insn (char *line
)
2059 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
2066 /* A semi-colon followed by a newline is always the end of a line. */
2067 if (line
[-1] == ';')
2070 if (line
[-1] == '|')
2073 /* If the || is on the next line, there might be leading whitespace. */
2075 while (*temp
== ' ' || *temp
== '\t') temp
++;
2084 bfin_start_label (char *s
, char *ptr
)
2088 if (*s
== '(' || *s
== '[')
2097 bfin_force_relocation (struct fix
*fixp
)
2099 if (fixp
->fx_r_type
==BFD_RELOC_BFIN_16_LOW
2100 || fixp
->fx_r_type
== BFD_RELOC_BFIN_16_HIGH
)
2103 return generic_force_reloc (fixp
);
2106 /* This is a stripped down version of the disassembler. The only thing it
2107 does is return a mask of registers modified by an instruction. Only
2108 instructions that can occur in a parallel-issue bundle are handled, and
2109 only the registers that can cause a conflict are recorded. */
2111 #define DREG_MASK(n) (0x101 << (n))
2112 #define DREGH_MASK(n) (0x100 << (n))
2113 #define DREGL_MASK(n) (0x001 << (n))
2114 #define IREG_MASK(n) (1 << ((n) + 16))
2117 decode_ProgCtrl_0 (int iw0
)
2125 decode_LDSTpmod_0 (int iw0
)
2128 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2129 | 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......|
2130 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2131 int W
= ((iw0
>> LDSTpmod_W_bits
) & LDSTpmod_W_mask
);
2132 int aop
= ((iw0
>> LDSTpmod_aop_bits
) & LDSTpmod_aop_mask
);
2133 int idx
= ((iw0
>> LDSTpmod_idx_bits
) & LDSTpmod_idx_mask
);
2134 int ptr
= ((iw0
>> LDSTpmod_ptr_bits
) & LDSTpmod_ptr_mask
);
2135 int reg
= ((iw0
>> LDSTpmod_reg_bits
) & LDSTpmod_reg_mask
);
2137 if (aop
== 1 && W
== 0 && idx
== ptr
)
2138 return DREGL_MASK (reg
);
2139 else if (aop
== 2 && W
== 0 && idx
== ptr
)
2140 return DREGH_MASK (reg
);
2141 else if (aop
== 1 && W
== 1 && idx
== ptr
)
2143 else if (aop
== 2 && W
== 1 && idx
== ptr
)
2145 else if (aop
== 0 && W
== 0)
2146 return DREG_MASK (reg
);
2147 else if (aop
== 1 && W
== 0)
2148 return DREGL_MASK (reg
);
2149 else if (aop
== 2 && W
== 0)
2150 return DREGH_MASK (reg
);
2151 else if (aop
== 3 && W
== 0)
2152 return DREG_MASK (reg
);
2153 else if (aop
== 3 && W
== 1)
2154 return DREG_MASK (reg
);
2155 else if (aop
== 0 && W
== 1)
2157 else if (aop
== 1 && W
== 1)
2159 else if (aop
== 2 && W
== 1)
2168 decode_dagMODim_0 (int iw0
)
2171 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2172 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....|
2173 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2174 int i
= ((iw0
>> DagMODim_i_bits
) & DagMODim_i_mask
);
2175 int op
= ((iw0
>> DagMODim_op_bits
) & DagMODim_op_mask
);
2177 if (op
== 0 || op
== 1)
2178 return IREG_MASK (i
);
2186 decode_dagMODik_0 (int iw0
)
2189 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2190 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....|
2191 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2192 int i
= ((iw0
>> DagMODik_i_bits
) & DagMODik_i_mask
);
2193 return IREG_MASK (i
);
2198 decode_dspLDST_0 (int iw0
)
2201 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2202 | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......|
2203 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2204 int i
= ((iw0
>> DspLDST_i_bits
) & DspLDST_i_mask
);
2205 int m
= ((iw0
>> DspLDST_m_bits
) & DspLDST_m_mask
);
2206 int W
= ((iw0
>> DspLDST_W_bits
) & DspLDST_W_mask
);
2207 int aop
= ((iw0
>> DspLDST_aop_bits
) & DspLDST_aop_mask
);
2208 int reg
= ((iw0
>> DspLDST_reg_bits
) & DspLDST_reg_mask
);
2210 if (aop
== 0 && W
== 0 && m
== 0)
2211 return DREG_MASK (reg
) | IREG_MASK (i
);
2212 else if (aop
== 0 && W
== 0 && m
== 1)
2213 return DREGL_MASK (reg
) | IREG_MASK (i
);
2214 else if (aop
== 0 && W
== 0 && m
== 2)
2215 return DREGH_MASK (reg
) | IREG_MASK (i
);
2216 else if (aop
== 1 && W
== 0 && m
== 0)
2217 return DREG_MASK (reg
) | IREG_MASK (i
);
2218 else if (aop
== 1 && W
== 0 && m
== 1)
2219 return DREGL_MASK (reg
) | IREG_MASK (i
);
2220 else if (aop
== 1 && W
== 0 && m
== 2)
2221 return DREGH_MASK (reg
) | IREG_MASK (i
);
2222 else if (aop
== 2 && W
== 0 && m
== 0)
2223 return DREG_MASK (reg
);
2224 else if (aop
== 2 && W
== 0 && m
== 1)
2225 return DREGL_MASK (reg
);
2226 else if (aop
== 2 && W
== 0 && m
== 2)
2227 return DREGH_MASK (reg
);
2228 else if (aop
== 0 && W
== 1 && m
== 0)
2229 return IREG_MASK (i
);
2230 else if (aop
== 0 && W
== 1 && m
== 1)
2231 return IREG_MASK (i
);
2232 else if (aop
== 0 && W
== 1 && m
== 2)
2233 return IREG_MASK (i
);
2234 else if (aop
== 1 && W
== 1 && m
== 0)
2235 return IREG_MASK (i
);
2236 else if (aop
== 1 && W
== 1 && m
== 1)
2237 return IREG_MASK (i
);
2238 else if (aop
== 1 && W
== 1 && m
== 2)
2239 return IREG_MASK (i
);
2240 else if (aop
== 2 && W
== 1 && m
== 0)
2242 else if (aop
== 2 && W
== 1 && m
== 1)
2244 else if (aop
== 2 && W
== 1 && m
== 2)
2246 else if (aop
== 3 && W
== 0)
2247 return DREG_MASK (reg
) | IREG_MASK (i
);
2248 else if (aop
== 3 && W
== 1)
2249 return IREG_MASK (i
);
2256 decode_LDST_0 (int iw0
)
2259 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2260 | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......|
2261 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2262 int Z
= ((iw0
>> LDST_Z_bits
) & LDST_Z_mask
);
2263 int W
= ((iw0
>> LDST_W_bits
) & LDST_W_mask
);
2264 int sz
= ((iw0
>> LDST_sz_bits
) & LDST_sz_mask
);
2265 int aop
= ((iw0
>> LDST_aop_bits
) & LDST_aop_mask
);
2266 int reg
= ((iw0
>> LDST_reg_bits
) & LDST_reg_mask
);
2268 if (aop
== 0 && sz
== 0 && Z
== 0 && W
== 0)
2269 return DREG_MASK (reg
);
2270 else if (aop
== 0 && sz
== 0 && Z
== 1 && W
== 0)
2272 else if (aop
== 0 && sz
== 1 && Z
== 0 && W
== 0)
2273 return DREG_MASK (reg
);
2274 else if (aop
== 0 && sz
== 1 && Z
== 1 && W
== 0)
2275 return DREG_MASK (reg
);
2276 else if (aop
== 0 && sz
== 2 && Z
== 0 && W
== 0)
2277 return DREG_MASK (reg
);
2278 else if (aop
== 0 && sz
== 2 && Z
== 1 && W
== 0)
2279 return DREG_MASK (reg
);
2280 else if (aop
== 1 && sz
== 0 && Z
== 0 && W
== 0)
2281 return DREG_MASK (reg
);
2282 else if (aop
== 1 && sz
== 0 && Z
== 1 && W
== 0)
2284 else if (aop
== 1 && sz
== 1 && Z
== 0 && W
== 0)
2285 return DREG_MASK (reg
);
2286 else if (aop
== 1 && sz
== 1 && Z
== 1 && W
== 0)
2287 return DREG_MASK (reg
);
2288 else if (aop
== 1 && sz
== 2 && Z
== 0 && W
== 0)
2289 return DREG_MASK (reg
);
2290 else if (aop
== 1 && sz
== 2 && Z
== 1 && W
== 0)
2291 return DREG_MASK (reg
);
2292 else if (aop
== 2 && sz
== 0 && Z
== 0 && W
== 0)
2293 return DREG_MASK (reg
);
2294 else if (aop
== 2 && sz
== 0 && Z
== 1 && W
== 0)
2296 else if (aop
== 2 && sz
== 1 && Z
== 0 && W
== 0)
2297 return DREG_MASK (reg
);
2298 else if (aop
== 2 && sz
== 1 && Z
== 1 && W
== 0)
2299 return DREG_MASK (reg
);
2300 else if (aop
== 2 && sz
== 2 && Z
== 0 && W
== 0)
2301 return DREG_MASK (reg
);
2302 else if (aop
== 2 && sz
== 2 && Z
== 1 && W
== 0)
2303 return DREG_MASK (reg
);
2304 else if (aop
== 0 && sz
== 0 && Z
== 0 && W
== 1)
2306 else if (aop
== 0 && sz
== 0 && Z
== 1 && W
== 1)
2308 else if (aop
== 0 && sz
== 1 && Z
== 0 && W
== 1)
2310 else if (aop
== 0 && sz
== 2 && Z
== 0 && W
== 1)
2312 else if (aop
== 1 && sz
== 0 && Z
== 0 && W
== 1)
2314 else if (aop
== 1 && sz
== 0 && Z
== 1 && W
== 1)
2316 else if (aop
== 1 && sz
== 1 && Z
== 0 && W
== 1)
2318 else if (aop
== 1 && sz
== 2 && Z
== 0 && W
== 1)
2320 else if (aop
== 2 && sz
== 0 && Z
== 0 && W
== 1)
2322 else if (aop
== 2 && sz
== 0 && Z
== 1 && W
== 1)
2324 else if (aop
== 2 && sz
== 1 && Z
== 0 && W
== 1)
2326 else if (aop
== 2 && sz
== 2 && Z
== 0 && W
== 1)
2333 decode_LDSTiiFP_0 (int iw0
)
2336 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2337 | 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........|
2338 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2339 int reg
= ((iw0
>> LDSTiiFP_reg_bits
) & LDSTiiFP_reg_mask
);
2340 int W
= ((iw0
>> LDSTiiFP_W_bits
) & LDSTiiFP_W_mask
);
2343 return reg
< 8 ? DREG_MASK (reg
) : 0;
2349 decode_LDSTii_0 (int iw0
)
2352 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2353 | 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......|
2354 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2355 int reg
= ((iw0
>> LDSTii_reg_bit
) & LDSTii_reg_mask
);
2356 int op
= ((iw0
>> LDSTii_op_bit
) & LDSTii_op_mask
);
2357 int W
= ((iw0
>> LDSTii_W_bit
) & LDSTii_W_mask
);
2359 if (W
== 0 && op
!= 3)
2360 return DREG_MASK (reg
);
2361 else if (W
== 0 && op
== 3)
2363 else if (W
== 1 && op
== 0)
2365 else if (W
== 1 && op
== 1)
2367 else if (W
== 1 && op
== 3)
2374 decode_dsp32mac_0 (int iw0
, int iw1
)
2378 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2379 | 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...|
2380 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2381 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2382 int op1
= ((iw0
>> (DSP32Mac_op1_bits
- 16)) & DSP32Mac_op1_mask
);
2383 int w1
= ((iw0
>> (DSP32Mac_w1_bits
- 16)) & DSP32Mac_w1_mask
);
2384 int P
= ((iw0
>> (DSP32Mac_p_bits
- 16)) & DSP32Mac_p_mask
);
2385 int mmod
= ((iw0
>> (DSP32Mac_mmod_bits
- 16)) & DSP32Mac_mmod_mask
);
2386 int w0
= ((iw1
>> DSP32Mac_w0_bits
) & DSP32Mac_w0_mask
);
2387 int MM
= ((iw1
>> DSP32Mac_MM_bits
) & DSP32Mac_MM_mask
);
2388 int dst
= ((iw1
>> DSP32Mac_dst_bits
) & DSP32Mac_dst_mask
);
2389 int op0
= ((iw1
>> DSP32Mac_op0_bits
) & DSP32Mac_op0_mask
);
2391 if (w0
== 0 && w1
== 0 && op1
== 3 && op0
== 3)
2397 if ((w1
|| w0
) && mmod
== M_W32
)
2400 if (((1 << mmod
) & (P
? 0x131b : 0x1b5f)) == 0)
2403 if (w1
== 1 || op1
!= 3)
2408 return DREG_MASK (dst
+ 1);
2410 return DREGH_MASK (dst
);
2414 if (w0
== 1 || op0
!= 3)
2419 return DREG_MASK (dst
);
2421 return DREGL_MASK (dst
);
2429 decode_dsp32mult_0 (int iw0
, int iw1
)
2432 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2433 | 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...|
2434 |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2435 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2436 int w1
= ((iw0
>> (DSP32Mac_w1_bits
- 16)) & DSP32Mac_w1_mask
);
2437 int P
= ((iw0
>> (DSP32Mac_p_bits
- 16)) & DSP32Mac_p_mask
);
2438 int mmod
= ((iw0
>> (DSP32Mac_mmod_bits
- 16)) & DSP32Mac_mmod_mask
);
2439 int w0
= ((iw1
>> DSP32Mac_w0_bits
) & DSP32Mac_w0_mask
);
2440 int dst
= ((iw1
>> DSP32Mac_dst_bits
) & DSP32Mac_dst_mask
);
2443 if (w1
== 0 && w0
== 0)
2446 if (((1 << mmod
) & (P
? 0x313 : 0x1b57)) == 0)
2452 return DREG_MASK (dst
| 1);
2454 return DREGH_MASK (dst
);
2460 return DREG_MASK (dst
);
2462 return DREGL_MASK (dst
);
2469 decode_dsp32alu_0 (int iw0
, int iw1
)
2472 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2473 | 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............|
2474 |.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......|
2475 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2476 int s
= ((iw1
>> DSP32Alu_s_bits
) & DSP32Alu_s_mask
);
2477 int x
= ((iw1
>> DSP32Alu_x_bits
) & DSP32Alu_x_mask
);
2478 int aop
= ((iw1
>> DSP32Alu_aop_bits
) & DSP32Alu_aop_mask
);
2479 int dst0
= ((iw1
>> DSP32Alu_dst0_bits
) & DSP32Alu_dst0_mask
);
2480 int dst1
= ((iw1
>> DSP32Alu_dst1_bits
) & DSP32Alu_dst1_mask
);
2481 int HL
= ((iw0
>> (DSP32Alu_HL_bits
- 16)) & DSP32Alu_HL_mask
);
2482 int aopcde
= ((iw0
>> (DSP32Alu_aopcde_bits
- 16)) & DSP32Alu_aopcde_mask
);
2484 if (aop
== 0 && aopcde
== 9 && s
== 0)
2486 else if (aop
== 2 && aopcde
== 9 && HL
== 0 && s
== 0)
2488 else if (aop
>= x
* 2 && aopcde
== 5)
2489 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2490 else if (HL
== 0 && aopcde
== 2)
2491 return DREGL_MASK (dst0
);
2492 else if (HL
== 1 && aopcde
== 2)
2493 return DREGH_MASK (dst0
);
2494 else if (HL
== 0 && aopcde
== 3)
2495 return DREGL_MASK (dst0
);
2496 else if (HL
== 1 && aopcde
== 3)
2497 return DREGH_MASK (dst0
);
2499 else if (aop
== 0 && aopcde
== 9 && s
== 1)
2501 else if (aop
== 1 && aopcde
== 9 && s
== 0)
2503 else if (aop
== 2 && aopcde
== 9 && s
== 1)
2505 else if (aop
== 3 && aopcde
== 9 && s
== 0)
2507 else if (aopcde
== 8)
2509 else if (aop
== 0 && aopcde
== 11)
2510 return DREG_MASK (dst0
);
2511 else if (aop
== 1 && aopcde
== 11)
2512 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2513 else if (aopcde
== 11)
2515 else if (aopcde
== 22)
2516 return DREG_MASK (dst0
);
2518 else if ((aop
== 0 || aop
== 1) && aopcde
== 14)
2520 else if (aop
== 3 && HL
== 0 && aopcde
== 14)
2523 else if (aop
== 3 && HL
== 0 && aopcde
== 15)
2524 return DREG_MASK (dst0
);
2526 else if (aop
== 1 && aopcde
== 16)
2529 else if (aop
== 0 && aopcde
== 16)
2532 else if (aop
== 3 && HL
== 0 && aopcde
== 16)
2535 else if (aop
== 3 && HL
== 0 && aopcde
== 7)
2536 return DREG_MASK (dst0
);
2537 else if ((aop
== 0 || aop
== 1 || aop
== 2) && aopcde
== 7)
2538 return DREG_MASK (dst0
);
2540 else if (aop
== 0 && aopcde
== 12)
2541 return DREG_MASK (dst0
);
2542 else if (aop
== 1 && aopcde
== 12)
2543 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2544 else if (aop
== 3 && aopcde
== 12)
2545 return HL
? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2547 else if (aopcde
== 0)
2548 return DREG_MASK (dst0
);
2549 else if (aopcde
== 1)
2550 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2552 else if (aop
== 0 && aopcde
== 10)
2553 return DREGL_MASK (dst0
);
2554 else if (aop
== 1 && aopcde
== 10)
2555 return DREGL_MASK (dst0
);
2557 else if ((aop
== 1 || aop
== 0) && aopcde
== 4)
2558 return DREG_MASK (dst0
);
2559 else if (aop
== 2 && aopcde
== 4)
2560 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2562 else if (aop
== 0 && aopcde
== 17)
2563 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2564 else if (aop
== 1 && aopcde
== 17)
2565 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2566 else if (aop
== 0 && aopcde
== 18)
2568 else if (aop
== 3 && aopcde
== 18)
2571 else if ((aop
== 0 || aop
== 1 || aop
== 2) && aopcde
== 6)
2572 return DREG_MASK (dst0
);
2574 else if ((aop
== 0 || aop
== 1) && aopcde
== 20)
2575 return DREG_MASK (dst0
);
2577 else if ((aop
== 0 || aop
== 1) && aopcde
== 21)
2578 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2580 else if (aop
== 0 && aopcde
== 23 && HL
== 1)
2581 return DREG_MASK (dst0
);
2582 else if (aop
== 0 && aopcde
== 23 && HL
== 0)
2583 return DREG_MASK (dst0
);
2585 else if (aop
== 0 && aopcde
== 24)
2586 return DREG_MASK (dst0
);
2587 else if (aop
== 1 && aopcde
== 24)
2588 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2589 else if (aopcde
== 13)
2590 return DREG_MASK (dst0
) | DREG_MASK (dst1
);
2598 decode_dsp32shift_0 (int iw0
, int iw1
)
2601 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2602 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............|
2603 |.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......|
2604 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2605 int HLs
= ((iw1
>> DSP32Shift_HLs_bits
) & DSP32Shift_HLs_mask
);
2606 int sop
= ((iw1
>> DSP32Shift_sop_bits
) & DSP32Shift_sop_mask
);
2607 int src0
= ((iw1
>> DSP32Shift_src0_bits
) & DSP32Shift_src0_mask
);
2608 int src1
= ((iw1
>> DSP32Shift_src1_bits
) & DSP32Shift_src1_mask
);
2609 int dst0
= ((iw1
>> DSP32Shift_dst0_bits
) & DSP32Shift_dst0_mask
);
2610 int sopcde
= ((iw0
>> (DSP32Shift_sopcde_bits
- 16)) & DSP32Shift_sopcde_mask
);
2612 if (sop
== 0 && sopcde
== 0)
2613 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2614 else if (sop
== 1 && sopcde
== 0)
2615 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2616 else if (sop
== 2 && sopcde
== 0)
2617 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2618 else if (sop
== 0 && sopcde
== 3)
2620 else if (sop
== 1 && sopcde
== 3)
2622 else if (sop
== 2 && sopcde
== 3)
2624 else if (sop
== 3 && sopcde
== 3)
2625 return DREG_MASK (dst0
);
2626 else if (sop
== 0 && sopcde
== 1)
2627 return DREG_MASK (dst0
);
2628 else if (sop
== 1 && sopcde
== 1)
2629 return DREG_MASK (dst0
);
2630 else if (sop
== 2 && sopcde
== 1)
2631 return DREG_MASK (dst0
);
2632 else if (sopcde
== 2)
2633 return DREG_MASK (dst0
);
2634 else if (sopcde
== 4)
2635 return DREG_MASK (dst0
);
2636 else if (sop
== 0 && sopcde
== 5)
2637 return DREGL_MASK (dst0
);
2638 else if (sop
== 1 && sopcde
== 5)
2639 return DREGL_MASK (dst0
);
2640 else if (sop
== 2 && sopcde
== 5)
2641 return DREGL_MASK (dst0
);
2642 else if (sop
== 0 && sopcde
== 6)
2643 return DREGL_MASK (dst0
);
2644 else if (sop
== 1 && sopcde
== 6)
2645 return DREGL_MASK (dst0
);
2646 else if (sop
== 3 && sopcde
== 6)
2647 return DREGL_MASK (dst0
);
2648 else if (sop
== 0 && sopcde
== 7)
2649 return DREGL_MASK (dst0
);
2650 else if (sop
== 1 && sopcde
== 7)
2651 return DREGL_MASK (dst0
);
2652 else if (sop
== 2 && sopcde
== 7)
2653 return DREGL_MASK (dst0
);
2654 else if (sop
== 3 && sopcde
== 7)
2655 return DREGL_MASK (dst0
);
2656 else if (sop
== 0 && sopcde
== 8)
2657 return DREG_MASK (src0
) | DREG_MASK (src1
);
2660 OUTS (outf
, "BITMUX (");
2661 OUTS (outf
, dregs (src0
));
2663 OUTS (outf
, dregs (src1
));
2664 OUTS (outf
, ", A0) (ASR)");
2667 else if (sop
== 1 && sopcde
== 8)
2668 return DREG_MASK (src0
) | DREG_MASK (src1
);
2671 OUTS (outf
, "BITMUX (");
2672 OUTS (outf
, dregs (src0
));
2674 OUTS (outf
, dregs (src1
));
2675 OUTS (outf
, ", A0) (ASL)");
2678 else if (sopcde
== 9)
2679 return sop
< 2 ? DREGL_MASK (dst0
) : DREG_MASK (dst0
);
2680 else if (sopcde
== 10)
2681 return DREG_MASK (dst0
);
2682 else if (sop
== 0 && sopcde
== 11)
2683 return DREGL_MASK (dst0
);
2684 else if (sop
== 1 && sopcde
== 11)
2685 return DREGL_MASK (dst0
);
2686 else if (sop
== 0 && sopcde
== 12)
2688 else if (sop
== 1 && sopcde
== 12)
2689 return DREGL_MASK (dst0
);
2690 else if (sop
== 0 && sopcde
== 13)
2691 return DREG_MASK (dst0
);
2692 else if (sop
== 1 && sopcde
== 13)
2693 return DREG_MASK (dst0
);
2694 else if (sop
== 2 && sopcde
== 13)
2695 return DREG_MASK (dst0
);
2701 decode_dsp32shiftimm_0 (int iw0
, int iw1
)
2704 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2705 | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............|
2706 |.sop...|.HLs...|.dst0......|.immag.................|.src1......|
2707 +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
2708 int sop
= ((iw1
>> DSP32ShiftImm_sop_bits
) & DSP32ShiftImm_sop_mask
);
2709 int bit8
= ((iw1
>> 8) & 0x1);
2710 int dst0
= ((iw1
>> DSP32ShiftImm_dst0_bits
) & DSP32ShiftImm_dst0_mask
);
2711 int sopcde
= ((iw0
>> (DSP32ShiftImm_sopcde_bits
- 16)) & DSP32ShiftImm_sopcde_mask
);
2712 int HLs
= ((iw1
>> DSP32ShiftImm_HLs_bits
) & DSP32ShiftImm_HLs_mask
);
2715 if (sop
== 0 && sopcde
== 0)
2716 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2717 else if (sop
== 1 && sopcde
== 0 && bit8
== 0)
2718 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2719 else if (sop
== 1 && sopcde
== 0 && bit8
== 1)
2720 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2721 else if (sop
== 2 && sopcde
== 0 && bit8
== 0)
2722 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2723 else if (sop
== 2 && sopcde
== 0 && bit8
== 1)
2724 return HLs
& 2 ? DREGH_MASK (dst0
) : DREGL_MASK (dst0
);
2725 else if (sop
== 2 && sopcde
== 3 && HLs
== 1)
2727 else if (sop
== 0 && sopcde
== 3 && HLs
== 0 && bit8
== 0)
2729 else if (sop
== 0 && sopcde
== 3 && HLs
== 0 && bit8
== 1)
2731 else if (sop
== 0 && sopcde
== 3 && HLs
== 1 && bit8
== 0)
2733 else if (sop
== 0 && sopcde
== 3 && HLs
== 1 && bit8
== 1)
2735 else if (sop
== 1 && sopcde
== 3 && HLs
== 0)
2737 else if (sop
== 1 && sopcde
== 3 && HLs
== 1)
2739 else if (sop
== 2 && sopcde
== 3 && HLs
== 0)
2741 else if (sop
== 1 && sopcde
== 1 && bit8
== 0)
2742 return DREG_MASK (dst0
);
2743 else if (sop
== 1 && sopcde
== 1 && bit8
== 1)
2744 return DREG_MASK (dst0
);
2745 else if (sop
== 2 && sopcde
== 1 && bit8
== 1)
2746 return DREG_MASK (dst0
);
2747 else if (sop
== 2 && sopcde
== 1 && bit8
== 0)
2748 return DREG_MASK (dst0
);
2749 else if (sop
== 0 && sopcde
== 1)
2750 return DREG_MASK (dst0
);
2751 else if (sop
== 1 && sopcde
== 2)
2752 return DREG_MASK (dst0
);
2753 else if (sop
== 2 && sopcde
== 2 && bit8
== 1)
2754 return DREG_MASK (dst0
);
2755 else if (sop
== 2 && sopcde
== 2 && bit8
== 0)
2756 return DREG_MASK (dst0
);
2757 else if (sop
== 3 && sopcde
== 2)
2758 return DREG_MASK (dst0
);
2759 else if (sop
== 0 && sopcde
== 2)
2760 return DREG_MASK (dst0
);
2766 insn_regmask (int iw0
, int iw1
)
2768 if ((iw0
& 0xf7ff) == 0xc003 && iw1
== 0x1800)
2769 return 0; /* MNOP */
2770 else if ((iw0
& 0xff00) == 0x0000)
2771 return decode_ProgCtrl_0 (iw0
);
2772 else if ((iw0
& 0xffc0) == 0x0240)
2774 else if ((iw0
& 0xff80) == 0x0100)
2776 else if ((iw0
& 0xfe00) == 0x0400)
2778 else if ((iw0
& 0xfe00) == 0x0600)
2780 else if ((iw0
& 0xf800) == 0x0800)
2782 else if ((iw0
& 0xffe0) == 0x0200)
2784 else if ((iw0
& 0xff00) == 0x0300)
2786 else if ((iw0
& 0xf000) == 0x1000)
2788 else if ((iw0
& 0xf000) == 0x2000)
2790 else if ((iw0
& 0xf000) == 0x3000)
2792 else if ((iw0
& 0xfc00) == 0x4000)
2794 else if ((iw0
& 0xfe00) == 0x4400)
2796 else if ((iw0
& 0xf800) == 0x4800)
2798 else if ((iw0
& 0xf000) == 0x5000)
2800 else if ((iw0
& 0xf800) == 0x6000)
2802 else if ((iw0
& 0xf800) == 0x6800)
2804 else if ((iw0
& 0xf000) == 0x8000)
2805 return decode_LDSTpmod_0 (iw0
);
2806 else if ((iw0
& 0xff60) == 0x9e60)
2807 return decode_dagMODim_0 (iw0
);
2808 else if ((iw0
& 0xfff0) == 0x9f60)
2809 return decode_dagMODik_0 (iw0
);
2810 else if ((iw0
& 0xfc00) == 0x9c00)
2811 return decode_dspLDST_0 (iw0
);
2812 else if ((iw0
& 0xf000) == 0x9000)
2813 return decode_LDST_0 (iw0
);
2814 else if ((iw0
& 0xfc00) == 0xb800)
2815 return decode_LDSTiiFP_0 (iw0
);
2816 else if ((iw0
& 0xe000) == 0xA000)
2817 return decode_LDSTii_0 (iw0
);
2818 else if ((iw0
& 0xff80) == 0xe080 && (iw1
& 0x0C00) == 0x0000)
2820 else if ((iw0
& 0xff00) == 0xe100 && (iw1
& 0x0000) == 0x0000)
2822 else if ((iw0
& 0xfe00) == 0xe200 && (iw1
& 0x0000) == 0x0000)
2824 else if ((iw0
& 0xfc00) == 0xe400 && (iw1
& 0x0000) == 0x0000)
2826 else if ((iw0
& 0xfffe) == 0xe800 && (iw1
& 0x0000) == 0x0000)
2828 else if ((iw0
& 0xf600) == 0xc000 && (iw1
& 0x0000) == 0x0000)
2829 return decode_dsp32mac_0 (iw0
, iw1
);
2830 else if ((iw0
& 0xf600) == 0xc200 && (iw1
& 0x0000) == 0x0000)
2831 return decode_dsp32mult_0 (iw0
, iw1
);
2832 else if ((iw0
& 0xf7c0) == 0xc400 && (iw1
& 0x0000) == 0x0000)
2833 return decode_dsp32alu_0 (iw0
, iw1
);
2834 else if ((iw0
& 0xf780) == 0xc600 && (iw1
& 0x01c0) == 0x0000)
2835 return decode_dsp32shift_0 (iw0
, iw1
);
2836 else if ((iw0
& 0xf780) == 0xc680 && (iw1
& 0x0000) == 0x0000)
2837 return decode_dsp32shiftimm_0 (iw0
, iw1
);
2838 else if ((iw0
& 0xff00) == 0xf800)
2840 else if ((iw0
& 0xFFC0) == 0xf000 && (iw1
& 0x0000) == 0x0000)