summaryrefslogtreecommitdiffstats
path: root/binutils-2.24/gas/config/tc-bfin.c
diff options
context:
space:
mode:
Diffstat (limited to 'binutils-2.24/gas/config/tc-bfin.c')
-rw-r--r--binutils-2.24/gas/config/tc-bfin.c2734
1 files changed, 0 insertions, 2734 deletions
diff --git a/binutils-2.24/gas/config/tc-bfin.c b/binutils-2.24/gas/config/tc-bfin.c
deleted file mode 100644
index 99e9b1ee..00000000
--- a/binutils-2.24/gas/config/tc-bfin.c
+++ /dev/null
@@ -1,2734 +0,0 @@
-/* tc-bfin.c -- Assembler for the ADI Blackfin.
- Copyright 2005, 2006, 2007, 2008, 2009, 2010
- Free Software Foundation, Inc.
-
- This file is part of GAS, the GNU Assembler.
-
- GAS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
-
- GAS is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GAS; see the file COPYING. If not, write to the Free
- Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
- 02110-1301, USA. */
-
-#include "as.h"
-#include "struc-symbol.h"
-#include "bfin-defs.h"
-#include "obstack.h"
-#include "safe-ctype.h"
-#ifdef OBJ_ELF
-#include "dwarf2dbg.h"
-#endif
-#include "libbfd.h"
-#include "elf/common.h"
-#include "elf/bfin.h"
-
-extern int yyparse (void);
-struct yy_buffer_state;
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-extern YY_BUFFER_STATE yy_scan_string (const char *yy_str);
-extern void yy_delete_buffer (YY_BUFFER_STATE b);
-static parse_state parse (char *line);
-
-/* Global variables. */
-struct bfin_insn *insn;
-int last_insn_size;
-
-extern struct obstack mempool;
-FILE *errorf;
-
-/* Flags to set in the elf header */
-#define DEFAULT_FLAGS 0
-
-#ifdef OBJ_FDPIC_ELF
-# define DEFAULT_FDPIC EF_BFIN_FDPIC
-#else
-# define DEFAULT_FDPIC 0
-#endif
-
-static flagword bfin_flags = DEFAULT_FLAGS | DEFAULT_FDPIC;
-static const char *bfin_pic_flag = DEFAULT_FDPIC ? "-mfdpic" : (const char *)0;
-
-/* Blackfin specific function to handle FD-PIC pointer initializations. */
-
-static void
-bfin_pic_ptr (int nbytes)
-{
- expressionS exp;
- char *p;
-
- if (nbytes != 4)
- abort ();
-
-#ifdef md_flush_pending_output
- md_flush_pending_output ();
-#endif
-
- if (is_it_end_of_statement ())
- {
- demand_empty_rest_of_line ();
- return;
- }
-
-#ifdef md_cons_align
- md_cons_align (nbytes);
-#endif
-
- do
- {
- bfd_reloc_code_real_type reloc_type = BFD_RELOC_BFIN_FUNCDESC;
-
- if (strncasecmp (input_line_pointer, "funcdesc(", 9) == 0)
- {
- input_line_pointer += 9;
- expression (&exp);
- if (*input_line_pointer == ')')
- input_line_pointer++;
- else
- as_bad (_("missing ')'"));
- }
- else
- error ("missing funcdesc in picptr");
-
- p = frag_more (4);
- memset (p, 0, 4);
- fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
- reloc_type);
- }
- while (*input_line_pointer++ == ',');
-
- input_line_pointer--; /* Put terminator back into stream. */
- demand_empty_rest_of_line ();
-}
-
-static void
-bfin_s_bss (int ignore ATTRIBUTE_UNUSED)
-{
- register int temp;
-
- temp = get_absolute_expression ();
- subseg_set (bss_section, (subsegT) temp);
- demand_empty_rest_of_line ();
-}
-
-const pseudo_typeS md_pseudo_table[] = {
- {"align", s_align_bytes, 0},
- {"byte2", cons, 2},
- {"byte4", cons, 4},
- {"picptr", bfin_pic_ptr, 4},
- {"code", obj_elf_section, 0},
- {"db", cons, 1},
- {"dd", cons, 4},
- {"dw", cons, 2},
- {"p", s_ignore, 0},
- {"pdata", s_ignore, 0},
- {"var", s_ignore, 0},
- {"bss", bfin_s_bss, 0},
- {0, 0, 0}
-};
-
-/* Characters that are used to denote comments and line separators. */
-const char comment_chars[] = "#";
-const char line_comment_chars[] = "#";
-const char line_separator_chars[] = ";";
-
-/* Characters that can be used to separate the mantissa from the
- exponent in floating point numbers. */
-const char EXP_CHARS[] = "eE";
-
-/* Characters that mean this number is a floating point constant.
- As in 0f12.456 or 0d1.2345e12. */
-const char FLT_CHARS[] = "fFdDxX";
-
-typedef enum bfin_cpu_type
-{
- BFIN_CPU_UNKNOWN,
- BFIN_CPU_BF504,
- BFIN_CPU_BF506,
- BFIN_CPU_BF512,
- BFIN_CPU_BF514,
- BFIN_CPU_BF516,
- BFIN_CPU_BF518,
- BFIN_CPU_BF522,
- BFIN_CPU_BF523,
- BFIN_CPU_BF524,
- BFIN_CPU_BF525,
- BFIN_CPU_BF526,
- BFIN_CPU_BF527,
- BFIN_CPU_BF531,
- BFIN_CPU_BF532,
- BFIN_CPU_BF533,
- BFIN_CPU_BF534,
- BFIN_CPU_BF536,
- BFIN_CPU_BF537,
- BFIN_CPU_BF538,
- BFIN_CPU_BF539,
- BFIN_CPU_BF542,
- BFIN_CPU_BF542M,
- BFIN_CPU_BF544,
- BFIN_CPU_BF544M,
- BFIN_CPU_BF547,
- BFIN_CPU_BF547M,
- BFIN_CPU_BF548,
- BFIN_CPU_BF548M,
- BFIN_CPU_BF549,
- BFIN_CPU_BF549M,
- BFIN_CPU_BF561,
- BFIN_CPU_BF592,
-} bfin_cpu_t;
-
-bfin_cpu_t bfin_cpu_type = BFIN_CPU_UNKNOWN;
-/* -msi-revision support. There are three special values:
- -1 -msi-revision=none.
- 0xffff -msi-revision=any. */
-int bfin_si_revision;
-
-unsigned int bfin_anomaly_checks = 0;
-
-struct bfin_cpu
-{
- const char *name;
- bfin_cpu_t type;
- int si_revision;
- unsigned int anomaly_checks;
-};
-
-struct bfin_cpu bfin_cpus[] =
-{
- {"bf504", BFIN_CPU_BF504, 0x0000, AC_05000074},
-
- {"bf506", BFIN_CPU_BF506, 0x0000, AC_05000074},
-
- {"bf512", BFIN_CPU_BF512, 0x0002, AC_05000074},
- {"bf512", BFIN_CPU_BF512, 0x0001, AC_05000074},
- {"bf512", BFIN_CPU_BF512, 0x0000, AC_05000074},
-
- {"bf514", BFIN_CPU_BF514, 0x0002, AC_05000074},
- {"bf514", BFIN_CPU_BF514, 0x0001, AC_05000074},
- {"bf514", BFIN_CPU_BF514, 0x0000, AC_05000074},
-
- {"bf516", BFIN_CPU_BF516, 0x0002, AC_05000074},
- {"bf516", BFIN_CPU_BF516, 0x0001, AC_05000074},
- {"bf516", BFIN_CPU_BF516, 0x0000, AC_05000074},
-
- {"bf518", BFIN_CPU_BF518, 0x0002, AC_05000074},
- {"bf518", BFIN_CPU_BF518, 0x0001, AC_05000074},
- {"bf518", BFIN_CPU_BF518, 0x0000, AC_05000074},
-
- {"bf522", BFIN_CPU_BF522, 0x0002, AC_05000074},
- {"bf522", BFIN_CPU_BF522, 0x0001, AC_05000074},
- {"bf522", BFIN_CPU_BF522, 0x0000, AC_05000074},
-
- {"bf523", BFIN_CPU_BF523, 0x0002, AC_05000074},
- {"bf523", BFIN_CPU_BF523, 0x0001, AC_05000074},
- {"bf523", BFIN_CPU_BF523, 0x0000, AC_05000074},
-
- {"bf524", BFIN_CPU_BF524, 0x0002, AC_05000074},
- {"bf524", BFIN_CPU_BF524, 0x0001, AC_05000074},
- {"bf524", BFIN_CPU_BF524, 0x0000, AC_05000074},
-
- {"bf525", BFIN_CPU_BF525, 0x0002, AC_05000074},
- {"bf525", BFIN_CPU_BF525, 0x0001, AC_05000074},
- {"bf525", BFIN_CPU_BF525, 0x0000, AC_05000074},
-
- {"bf526", BFIN_CPU_BF526, 0x0002, AC_05000074},
- {"bf526", BFIN_CPU_BF526, 0x0001, AC_05000074},
- {"bf526", BFIN_CPU_BF526, 0x0000, AC_05000074},
-
- {"bf527", BFIN_CPU_BF527, 0x0002, AC_05000074},
- {"bf527", BFIN_CPU_BF527, 0x0001, AC_05000074},
- {"bf527", BFIN_CPU_BF527, 0x0000, AC_05000074},
-
- {"bf531", BFIN_CPU_BF531, 0x0006, AC_05000074},
- {"bf531", BFIN_CPU_BF531, 0x0005, AC_05000074},
- {"bf531", BFIN_CPU_BF531, 0x0004, AC_05000074},
- {"bf531", BFIN_CPU_BF531, 0x0003, AC_05000074},
-
- {"bf532", BFIN_CPU_BF532, 0x0006, AC_05000074},
- {"bf532", BFIN_CPU_BF532, 0x0005, AC_05000074},
- {"bf532", BFIN_CPU_BF532, 0x0004, AC_05000074},
- {"bf532", BFIN_CPU_BF532, 0x0003, AC_05000074},
-
- {"bf533", BFIN_CPU_BF533, 0x0006, AC_05000074},
- {"bf533", BFIN_CPU_BF533, 0x0005, AC_05000074},
- {"bf533", BFIN_CPU_BF533, 0x0004, AC_05000074},
- {"bf533", BFIN_CPU_BF533, 0x0003, AC_05000074},
-
- {"bf534", BFIN_CPU_BF534, 0x0003, AC_05000074},
- {"bf534", BFIN_CPU_BF534, 0x0002, AC_05000074},
- {"bf534", BFIN_CPU_BF534, 0x0001, AC_05000074},
-
- {"bf536", BFIN_CPU_BF536, 0x0003, AC_05000074},
- {"bf536", BFIN_CPU_BF536, 0x0002, AC_05000074},
- {"bf536", BFIN_CPU_BF536, 0x0001, AC_05000074},
-
- {"bf537", BFIN_CPU_BF537, 0x0003, AC_05000074},
- {"bf537", BFIN_CPU_BF537, 0x0002, AC_05000074},
- {"bf537", BFIN_CPU_BF537, 0x0001, AC_05000074},
-
- {"bf538", BFIN_CPU_BF538, 0x0005, AC_05000074},
- {"bf538", BFIN_CPU_BF538, 0x0004, AC_05000074},
- {"bf538", BFIN_CPU_BF538, 0x0003, AC_05000074},
- {"bf538", BFIN_CPU_BF538, 0x0002, AC_05000074},
-
- {"bf539", BFIN_CPU_BF539, 0x0005, AC_05000074},
- {"bf539", BFIN_CPU_BF539, 0x0004, AC_05000074},
- {"bf539", BFIN_CPU_BF539, 0x0003, AC_05000074},
- {"bf539", BFIN_CPU_BF539, 0x0002, AC_05000074},
-
- {"bf542m", BFIN_CPU_BF542M, 0x0003, AC_05000074},
-
- {"bf542", BFIN_CPU_BF542, 0x0004, AC_05000074},
- {"bf542", BFIN_CPU_BF542, 0x0002, AC_05000074},
- {"bf542", BFIN_CPU_BF542, 0x0001, AC_05000074},
- {"bf542", BFIN_CPU_BF542, 0x0000, AC_05000074},
-
- {"bf544m", BFIN_CPU_BF544M, 0x0003, AC_05000074},
-
- {"bf544", BFIN_CPU_BF544, 0x0004, AC_05000074},
- {"bf544", BFIN_CPU_BF544, 0x0002, AC_05000074},
- {"bf544", BFIN_CPU_BF544, 0x0001, AC_05000074},
- {"bf544", BFIN_CPU_BF544, 0x0000, AC_05000074},
-
- {"bf547m", BFIN_CPU_BF547M, 0x0003, AC_05000074},
-
- {"bf547", BFIN_CPU_BF547, 0x0004, AC_05000074},
- {"bf547", BFIN_CPU_BF547, 0x0002, AC_05000074},
- {"bf547", BFIN_CPU_BF547, 0x0001, AC_05000074},
- {"bf547", BFIN_CPU_BF547, 0x0000, AC_05000074},
-
- {"bf548m", BFIN_CPU_BF548M, 0x0003, AC_05000074},
-
- {"bf548", BFIN_CPU_BF548, 0x0004, AC_05000074},
- {"bf548", BFIN_CPU_BF548, 0x0002, AC_05000074},
- {"bf548", BFIN_CPU_BF548, 0x0001, AC_05000074},
- {"bf548", BFIN_CPU_BF548, 0x0000, AC_05000074},
-
- {"bf549m", BFIN_CPU_BF549M, 0x0003, AC_05000074},
-
- {"bf549", BFIN_CPU_BF549, 0x0004, AC_05000074},
- {"bf549", BFIN_CPU_BF549, 0x0002, AC_05000074},
- {"bf549", BFIN_CPU_BF549, 0x0001, AC_05000074},
- {"bf549", BFIN_CPU_BF549, 0x0000, AC_05000074},
-
- {"bf561", BFIN_CPU_BF561, 0x0005, AC_05000074},
- {"bf561", BFIN_CPU_BF561, 0x0003, AC_05000074},
- {"bf561", BFIN_CPU_BF561, 0x0002, AC_05000074},
-
- {"bf592", BFIN_CPU_BF592, 0x0001, AC_05000074},
- {"bf592", BFIN_CPU_BF592, 0x0000, AC_05000074},
-
- {NULL, 0, 0, 0}
-};
-
-/* Define bfin-specific command-line options (there are none). */
-const char *md_shortopts = "";
-
-#define OPTION_FDPIC (OPTION_MD_BASE)
-#define OPTION_NOPIC (OPTION_MD_BASE + 1)
-#define OPTION_MCPU (OPTION_MD_BASE + 2)
-
-struct option md_longopts[] =
-{
- { "mcpu", required_argument, NULL, OPTION_MCPU },
- { "mfdpic", no_argument, NULL, OPTION_FDPIC },
- { "mnopic", no_argument, NULL, OPTION_NOPIC },
- { "mno-fdpic", no_argument, NULL, OPTION_NOPIC },
- { NULL, no_argument, NULL, 0 },
-};
-
-size_t md_longopts_size = sizeof (md_longopts);
-
-
-int
-md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
-{
- switch (c)
- {
- default:
- return 0;
-
- case OPTION_MCPU:
- {
- const char *p, *q;
- int i;
-
- i = 0;
- while ((p = bfin_cpus[i].name) != NULL)
- {
- if (strncmp (arg, p, strlen (p)) == 0)
- break;
- i++;
- }
-
- if (p == NULL)
- as_fatal ("-mcpu=%s is not valid", arg);
-
- bfin_cpu_type = bfin_cpus[i].type;
-
- q = arg + strlen (p);
-
- if (*q == '\0')
- {
- bfin_si_revision = bfin_cpus[i].si_revision;
- bfin_anomaly_checks |= bfin_cpus[i].anomaly_checks;
- }
- else if (strcmp (q, "-none") == 0)
- bfin_si_revision = -1;
- else if (strcmp (q, "-any") == 0)
- {
- bfin_si_revision = 0xffff;
- while (bfin_cpus[i].type == bfin_cpu_type)
- {
- bfin_anomaly_checks |= bfin_cpus[i].anomaly_checks;
- i++;
- }
- }
- else
- {
- unsigned int si_major, si_minor;
- int rev_len, n;
-
- rev_len = strlen (q);
-
- if (sscanf (q, "-%u.%u%n", &si_major, &si_minor, &n) != 2
- || n != rev_len
- || si_major > 0xff || si_minor > 0xff)
- {
- invalid_silicon_revision:
- as_fatal ("-mcpu=%s has invalid silicon revision", arg);
- }
-
- bfin_si_revision = (si_major << 8) | si_minor;
-
- while (bfin_cpus[i].type == bfin_cpu_type
- && bfin_cpus[i].si_revision != bfin_si_revision)
- i++;
-
- if (bfin_cpus[i].type != bfin_cpu_type)
- goto invalid_silicon_revision;
-
- bfin_anomaly_checks |= bfin_cpus[i].anomaly_checks;
- }
-
- break;
- }
-
- case OPTION_FDPIC:
- bfin_flags |= EF_BFIN_FDPIC;
- bfin_pic_flag = "-mfdpic";
- break;
-
- case OPTION_NOPIC:
- bfin_flags &= ~(EF_BFIN_FDPIC);
- bfin_pic_flag = 0;
- break;
- }
-
- return 1;
-}
-
-void
-md_show_usage (FILE * stream)
-{
- fprintf (stream, _(" Blackfin specific assembler options:\n"));
- fprintf (stream, _(" -mcpu=<cpu[-sirevision]> specify the name of the target CPU\n"));
- fprintf (stream, _(" -mfdpic assemble for the FDPIC ABI\n"));
- fprintf (stream, _(" -mno-fdpic/-mnopic disable -mfdpic\n"));
-}
-
-/* Perform machine-specific initializations. */
-void
-md_begin ()
-{
- /* Set the ELF flags if desired. */
- if (bfin_flags)
- bfd_set_private_flags (stdoutput, bfin_flags);
-
- /* Set the default machine type. */
- if (!bfd_set_arch_mach (stdoutput, bfd_arch_bfin, 0))
- as_warn (_("Could not set architecture and machine."));
-
- /* Ensure that lines can begin with '(', for multiple
- register stack pops. */
- lex_type ['('] = LEX_BEGIN_NAME;
-
-#ifdef OBJ_ELF
- record_alignment (text_section, 2);
- record_alignment (data_section, 2);
- record_alignment (bss_section, 2);
-#endif
-
- errorf = stderr;
- obstack_init (&mempool);
-
-#ifdef DEBUG
- extern int debug_codeselection;
- debug_codeselection = 1;
-#endif
-
- last_insn_size = 0;
-}
-
-/* Perform the main parsing, and assembly of the input here. Also,
- call the required routines for alignment and fixups here.
- This is called for every line that contains real assembly code. */
-
-void
-md_assemble (char *line)
-{
- char *toP = 0;
- extern char *current_inputline;
- int size, insn_size;
- struct bfin_insn *tmp_insn;
- size_t len;
- static size_t buffer_len = 0;
- parse_state state;
-
- len = strlen (line);
- if (len + 2 > buffer_len)
- {
- if (buffer_len > 0)
- free (current_inputline);
- buffer_len = len + 40;
- current_inputline = xmalloc (buffer_len);
- }
- memcpy (current_inputline, line, len);
- current_inputline[len] = ';';
- current_inputline[len + 1] = '\0';
-
- state = parse (current_inputline);
- if (state == NO_INSN_GENERATED)
- return;
-
- for (insn_size = 0, tmp_insn = insn; tmp_insn; tmp_insn = tmp_insn->next)
- if (!tmp_insn->reloc || !tmp_insn->exp->symbol)
- insn_size += 2;
-
- if (insn_size)
- toP = frag_more (insn_size);
-
- last_insn_size = insn_size;
-
-#ifdef DEBUG
- printf ("INS:");
-#endif
- while (insn)
- {
- if (insn->reloc && insn->exp->symbol)
- {
- char *prev_toP = toP - 2;
- switch (insn->reloc)
- {
- case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
- case BFD_RELOC_24_PCREL:
- case BFD_RELOC_BFIN_16_LOW:
- case BFD_RELOC_BFIN_16_HIGH:
- size = 4;
- break;
- default:
- size = 2;
- }
-
- /* Following if condition checks for the arithmetic relocations.
- If the case then it doesn't required to generate the code.
- It has been assumed that, their ID will be contiguous. */
- if ((BFD_ARELOC_BFIN_PUSH <= insn->reloc
- && BFD_ARELOC_BFIN_COMP >= insn->reloc)
- || insn->reloc == BFD_RELOC_BFIN_16_IMM)
- {
- size = 2;
- }
- if (insn->reloc == BFD_ARELOC_BFIN_CONST
- || insn->reloc == BFD_ARELOC_BFIN_PUSH)
- size = 4;
-
- fix_new (frag_now,
- (prev_toP - frag_now->fr_literal),
- size, insn->exp->symbol, insn->exp->value,
- insn->pcrel, insn->reloc);
- }
- else
- {
- md_number_to_chars (toP, insn->value, 2);
- toP += 2;
- }
-
-#ifdef DEBUG
- printf (" reloc :");
- printf (" %02x%02x", ((unsigned char *) &insn->value)[0],
- ((unsigned char *) &insn->value)[1]);
- printf ("\n");
-#endif
- insn = insn->next;
- }
-#ifdef OBJ_ELF
- dwarf2_emit_insn (insn_size);
-#endif
-
- while (*line++ != '\0')
- if (*line == '\n')
- bump_line_counters ();
-}
-
-/* Parse one line of instructions, and generate opcode for it.
- To parse the line, YACC and LEX are used, because the instruction set
- syntax doesn't confirm to the AT&T assembly syntax.
- To call a YACC & LEX generated parser, we must provide the input via
- a FILE stream, otherwise stdin is used by default. Below the input
- to the function will be put into a temporary file, then the generated
- parser uses the temporary file for parsing. */
-
-static parse_state
-parse (char *line)
-{
- parse_state state;
- YY_BUFFER_STATE buffstate;
-
- buffstate = yy_scan_string (line);
-
- /* our lex requires setting the start state to keyword
- every line as the first word may be a keyword.
- Fixes a bug where we could not have keywords as labels. */
- set_start_state ();
-
- /* Call yyparse here. */
- state = yyparse ();
- if (state == SEMANTIC_ERROR)
- {
- as_bad (_("Parse failed."));
- insn = 0;
- }
-
- yy_delete_buffer (buffstate);
- return state;
-}
-
-/* We need to handle various expressions properly.
- Such as, [SP--] = 34, concerned by md_assemble(). */
-
-void
-md_operand (expressionS * expressionP)
-{
- if (*input_line_pointer == '[')
- {
- as_tsktsk ("We found a '['!");
- input_line_pointer++;
- expression (expressionP);
- }
-}
-
-/* Handle undefined symbols. */
-symbolS *
-md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
-{
- return (symbolS *) 0;
-}
-
-int
-md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
- segT segment ATTRIBUTE_UNUSED)
-{
- return 0;
-}
-
-/* Convert from target byte order to host byte order. */
-
-static int
-md_chars_to_number (char *val, int n)
-{
- int retval;
-
- for (retval = 0; n--;)
- {
- retval <<= 8;
- retval |= val[n];
- }
- return retval;
-}
-
-void
-md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
-{
- char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
-
- long value = *valueP;
- long newval;
-
- switch (fixP->fx_r_type)
- {
- case BFD_RELOC_BFIN_GOT:
- case BFD_RELOC_BFIN_GOT17M4:
- case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
- fixP->fx_no_overflow = 1;
- newval = md_chars_to_number (where, 2);
- newval |= 0x0 & 0x7f;
- md_number_to_chars (where, newval, 2);
- break;
-
- case BFD_RELOC_BFIN_10_PCREL:
- if (!value)
- break;
- if (value < -1024 || value > 1022)
- as_bad_where (fixP->fx_file, fixP->fx_line,
- _("pcrel too far BFD_RELOC_BFIN_10"));
-
- /* 11 bit offset even numbered, so we remove right bit. */
- value = value >> 1;
- newval = md_chars_to_number (where, 2);
- newval |= value & 0x03ff;
- md_number_to_chars (where, newval, 2);
- break;
-
- case BFD_RELOC_BFIN_12_PCREL_JUMP:
- case BFD_RELOC_BFIN_12_PCREL_JUMP_S:
- case BFD_RELOC_12_PCREL:
- if (!value)
- break;
-
- if (value < -4096 || value > 4094)
- as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_12"));
- /* 13 bit offset even numbered, so we remove right bit. */
- value = value >> 1;
- newval = md_chars_to_number (where, 2);
- newval |= value & 0xfff;
- md_number_to_chars (where, newval, 2);
- break;
-
- case BFD_RELOC_BFIN_16_LOW:
- case BFD_RELOC_BFIN_16_HIGH:
- fixP->fx_done = FALSE;
- break;
-
- case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
- case BFD_RELOC_BFIN_24_PCREL_CALL_X:
- case BFD_RELOC_24_PCREL:
- if (!value)
- break;
-
- if (value < -16777216 || value > 16777214)
- as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_24"));
-
- /* 25 bit offset even numbered, so we remove right bit. */
- value = value >> 1;
- value++;
-
- md_number_to_chars (where - 2, value >> 16, 1);
- md_number_to_chars (where, value, 1);
- md_number_to_chars (where + 1, value >> 8, 1);
- break;
-
- case BFD_RELOC_BFIN_5_PCREL: /* LSETUP (a, b) : "a" */
- if (!value)
- break;
- if (value < 4 || value > 30)
- as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_5"));
- value = value >> 1;
- newval = md_chars_to_number (where, 1);
- newval = (newval & 0xf0) | (value & 0xf);
- md_number_to_chars (where, newval, 1);
- break;
-
- case BFD_RELOC_BFIN_11_PCREL: /* LSETUP (a, b) : "b" */
- if (!value)
- break;
- value += 2;
- if (value < 4 || value > 2046)
- as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_11_PCREL"));
- /* 11 bit unsigned even, so we remove right bit. */
- value = value >> 1;
- newval = md_chars_to_number (where, 2);
- newval |= value & 0x03ff;
- md_number_to_chars (where, newval, 2);
- break;
-
- case BFD_RELOC_8:
- if (value < -0x80 || value >= 0x7f)
- as_bad_where (fixP->fx_file, fixP->fx_line, _("rel too far BFD_RELOC_8"));
- md_number_to_chars (where, value, 1);
- break;
-
- case BFD_RELOC_BFIN_16_IMM:
- case BFD_RELOC_16:
- if (value < -0x8000 || value >= 0x7fff)
- as_bad_where (fixP->fx_file, fixP->fx_line, _("rel too far BFD_RELOC_16"));
- md_number_to_chars (where, value, 2);
- break;
-
- case BFD_RELOC_32:
- md_number_to_chars (where, value, 4);
- break;
-
- case BFD_RELOC_BFIN_PLTPC:
- md_number_to_chars (where, value, 2);
- break;
-
- case BFD_RELOC_BFIN_FUNCDESC:
- case BFD_RELOC_VTABLE_INHERIT:
- case BFD_RELOC_VTABLE_ENTRY:
- fixP->fx_done = FALSE;
- break;
-
- default:
- if ((BFD_ARELOC_BFIN_PUSH > fixP->fx_r_type) || (BFD_ARELOC_BFIN_COMP < fixP->fx_r_type))
- {
- fprintf (stderr, "Relocation %d not handled in gas." " Contact support.\n", fixP->fx_r_type);
- return;
- }
- }
-
- if (!fixP->fx_addsy)
- fixP->fx_done = TRUE;
-
-}
-
-/* Round up a section size to the appropriate boundary. */
-valueT
-md_section_align (segment, size)
- segT segment;
- valueT size;
-{
- int boundary = bfd_get_section_alignment (stdoutput, segment);
- return ((size + (1 << boundary) - 1) & (-1 << boundary));
-}
-
-
-char *
-md_atof (int type, char * litP, int * sizeP)
-{
- return ieee_md_atof (type, litP, sizeP, FALSE);
-}
-
-
-/* If while processing a fixup, a reloc really needs to be created
- then it is done here. */
-
-arelent *
-tc_gen_reloc (seg, fixp)
- asection *seg ATTRIBUTE_UNUSED;
- fixS *fixp;
-{
- arelent *reloc;
-
- reloc = (arelent *) xmalloc (sizeof (arelent));
- reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
- *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
- reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
-
- reloc->addend = fixp->fx_offset;
- reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
-
- if (reloc->howto == (reloc_howto_type *) NULL)
- {
- as_bad_where (fixp->fx_file, fixp->fx_line,
- /* xgettext:c-format. */
- _("reloc %d not supported by object file format"),
- (int) fixp->fx_r_type);
-
- xfree (reloc);
-
- return NULL;
- }
-
- return reloc;
-}
-
-/* The location from which a PC relative jump should be calculated,
- given a PC relative reloc. */
-
-long
-md_pcrel_from_section (fixP, sec)
- fixS *fixP;
- segT sec;
-{
- if (fixP->fx_addsy != (symbolS *) NULL
- && (!S_IS_DEFINED (fixP->fx_addsy)
- || S_GET_SEGMENT (fixP->fx_addsy) != sec))
- {
- /* The symbol is undefined (or is defined but not in this section).
- Let the linker figure it out. */
- return 0;
- }
- return fixP->fx_frag->fr_address + fixP->fx_where;
-}
-
-/* Return true if the fix can be handled by GAS, false if it must
- be passed through to the linker. */
-
-bfd_boolean
-bfin_fix_adjustable (fixS *fixP)
-{
- switch (fixP->fx_r_type)
- {
- /* Adjust_reloc_syms doesn't know about the GOT. */
- case BFD_RELOC_BFIN_GOT:
- case BFD_RELOC_BFIN_PLTPC:
- /* We need the symbol name for the VTABLE entries. */
- case BFD_RELOC_VTABLE_INHERIT:
- case BFD_RELOC_VTABLE_ENTRY:
- return 0;
-
- default:
- return 1;
- }
-}
-
-/* Special extra functions that help bfin-parse.y perform its job. */
-
-struct obstack mempool;
-
-INSTR_T
-conscode (INSTR_T head, INSTR_T tail)
-{
- if (!head)
- return tail;
- head->next = tail;
- return head;
-}
-
-INSTR_T
-conctcode (INSTR_T head, INSTR_T tail)
-{
- INSTR_T temp = (head);
- if (!head)
- return tail;
- while (temp->next)
- temp = temp->next;
- temp->next = tail;
-
- return head;
-}
-
-INSTR_T
-note_reloc (INSTR_T code, Expr_Node * symbol, int reloc, int pcrel)
-{
- /* Assert that the symbol is not an operator. */
- gas_assert (symbol->type == Expr_Node_Reloc);
-
- return note_reloc1 (code, symbol->value.s_value, reloc, pcrel);
-
-}
-
-INSTR_T
-note_reloc1 (INSTR_T code, const char *symbol, int reloc, int pcrel)
-{
- code->reloc = reloc;
- code->exp = mkexpr (0, symbol_find_or_make (symbol));
- code->pcrel = pcrel;
- return code;
-}
-
-INSTR_T
-note_reloc2 (INSTR_T code, const char *symbol, int reloc, int value, int pcrel)
-{
- code->reloc = reloc;
- code->exp = mkexpr (value, symbol_find_or_make (symbol));
- code->pcrel = pcrel;
- return code;
-}
-
-INSTR_T
-gencode (unsigned long x)
-{
- INSTR_T cell = obstack_alloc (&mempool, sizeof (struct bfin_insn));
- memset (cell, 0, sizeof (struct bfin_insn));
- cell->value = (x);
- return cell;
-}
-
-int reloc;
-int ninsns;
-int count_insns;
-
-static void *
-allocate (int n)
-{
- return obstack_alloc (&mempool, n);
-}
-
-Expr_Node *
-Expr_Node_Create (Expr_Node_Type type,
- Expr_Node_Value value,
- Expr_Node *Left_Child,
- Expr_Node *Right_Child)
-{
-
-
- Expr_Node *node = (Expr_Node *) allocate (sizeof (Expr_Node));
- node->type = type;
- node->value = value;
- node->Left_Child = Left_Child;
- node->Right_Child = Right_Child;
- return node;
-}
-
-static const char *con = ".__constant";
-static const char *op = ".__operator";
-static INSTR_T Expr_Node_Gen_Reloc_R (Expr_Node * head);
-INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc);
-
-INSTR_T
-Expr_Node_Gen_Reloc (Expr_Node * head, int parent_reloc)
-{
- /* Top level reloction expression generator VDSP style.
- If the relocation is just by itself, generate one item
- else generate this convoluted expression. */
-
- INSTR_T note = NULL_CODE;
- INSTR_T note1 = NULL_CODE;
- int pcrel = 1; /* Is the parent reloc pcrelative?
- This calculation here and HOWTO should match. */
-
- if (parent_reloc)
- {
- /* If it's 32 bit quantity then 16bit code needs to be added. */
- int value = 0;
-
- if (head->type == Expr_Node_Constant)
- {
- /* If note1 is not null code, we have to generate a right
- aligned value for the constant. Otherwise the reloc is
- a part of the basic command and the yacc file
- generates this. */
- value = head->value.i_value;
- }
- switch (parent_reloc)
- {
- /* Some relocations will need to allocate extra words. */
- case BFD_RELOC_BFIN_16_IMM:
- case BFD_RELOC_BFIN_16_LOW:
- case BFD_RELOC_BFIN_16_HIGH:
- note1 = conscode (gencode (value), NULL_CODE);
- pcrel = 0;
- break;
- case BFD_RELOC_BFIN_PLTPC:
- note1 = conscode (gencode (value), NULL_CODE);
- pcrel = 0;
- break;
- case BFD_RELOC_16:
- case BFD_RELOC_BFIN_GOT:
- case BFD_RELOC_BFIN_GOT17M4:
- case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
- note1 = conscode (gencode (value), NULL_CODE);
- pcrel = 0;
- break;
- case BFD_RELOC_24_PCREL:
- case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
- case BFD_RELOC_BFIN_24_PCREL_CALL_X:
- /* These offsets are even numbered pcrel. */
- note1 = conscode (gencode (value >> 1), NULL_CODE);
- break;
- default:
- note1 = NULL_CODE;
- }
- }
- if (head->type == Expr_Node_Constant)
- note = note1;
- else if (head->type == Expr_Node_Reloc)
- {
- note = note_reloc1 (gencode (0), head->value.s_value, parent_reloc, pcrel);
- if (note1 != NULL_CODE)
- note = conscode (note1, note);
- }
- else if (head->type == Expr_Node_Binop
- && (head->value.op_value == Expr_Op_Type_Add
- || head->value.op_value == Expr_Op_Type_Sub)
- && head->Left_Child->type == Expr_Node_Reloc
- && head->Right_Child->type == Expr_Node_Constant)
- {
- int val = head->Right_Child->value.i_value;
- if (head->value.op_value == Expr_Op_Type_Sub)
- val = -val;
- note = conscode (note_reloc2 (gencode (0), head->Left_Child->value.s_value,
- parent_reloc, val, 0),
- NULL_CODE);
- if (note1 != NULL_CODE)
- note = conscode (note1, note);
- }
- else
- {
- /* Call the recursive function. */
- note = note_reloc1 (gencode (0), op, parent_reloc, pcrel);
- if (note1 != NULL_CODE)
- note = conscode (note1, note);
- note = conctcode (Expr_Node_Gen_Reloc_R (head), note);
- }
- return note;
-}
-
-static INSTR_T
-Expr_Node_Gen_Reloc_R (Expr_Node * head)
-{
-
- INSTR_T note = 0;
- INSTR_T note1 = 0;
-
- switch (head->type)
- {
- case Expr_Node_Constant:
- note = conscode (note_reloc2 (gencode (0), con, BFD_ARELOC_BFIN_CONST, head->value.i_value, 0), NULL_CODE);
- break;
- case Expr_Node_Reloc:
- note = conscode (note_reloc (gencode (0), head, BFD_ARELOC_BFIN_PUSH, 0), NULL_CODE);
- break;
- case Expr_Node_Binop:
- note1 = conctcode (Expr_Node_Gen_Reloc_R (head->Left_Child), Expr_Node_Gen_Reloc_R (head->Right_Child));
- switch (head->value.op_value)
- {
- case Expr_Op_Type_Add:
- note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_ADD, 0), NULL_CODE));
- break;
- case Expr_Op_Type_Sub:
- note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_SUB, 0), NULL_CODE));
- break;
- case Expr_Op_Type_Mult:
- note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MULT, 0), NULL_CODE));
- break;
- case Expr_Op_Type_Div:
- note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_DIV, 0), NULL_CODE));
- break;
- case Expr_Op_Type_Mod:
- note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MOD, 0), NULL_CODE));
- break;
- case Expr_Op_Type_Lshift:
- note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LSHIFT, 0), NULL_CODE));
- break;
- case Expr_Op_Type_Rshift:
- note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_RSHIFT, 0), NULL_CODE));
- break;
- case Expr_Op_Type_BAND:
- note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_AND, 0), NULL_CODE));
- break;
- case Expr_Op_Type_BOR:
- note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_OR, 0), NULL_CODE));
- break;
- case Expr_Op_Type_BXOR:
- note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_XOR, 0), NULL_CODE));
- break;
- case Expr_Op_Type_LAND:
- note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LAND, 0), NULL_CODE));
- break;
- case Expr_Op_Type_LOR:
- note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LOR, 0), NULL_CODE));
- break;
- default:
- fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
-
-
- }
- break;
- case Expr_Node_Unop:
- note1 = conscode (Expr_Node_Gen_Reloc_R (head->Left_Child), NULL_CODE);
- switch (head->value.op_value)
- {
- case Expr_Op_Type_NEG:
- note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_NEG, 0), NULL_CODE));
- break;
- case Expr_Op_Type_COMP:
- note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_COMP, 0), NULL_CODE));
- break;
- default:
- fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
- }
- break;
- default:
- fprintf (stderr, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__, __LINE__);
- }
- return note;
-}
-
-/* Blackfin opcode generation. */
-
-/* These functions are called by the generated parser
- (from bfin-parse.y), the register type classification
- happens in bfin-lex.l. */
-
-#include "bfin-aux.h"
-#include "opcode/bfin.h"
-
-#define INIT(t) t c_code = init_##t
-#define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
-#define ASSIGNF(x,f) c_code.opcode |= ((x & c_code.mask_##f)<<c_code.bits_##f)
-#define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
-
-#define HI(x) ((x >> 16) & 0xffff)
-#define LO(x) ((x ) & 0xffff)
-
-#define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
-
-#define GEN_OPCODE32() \
- conscode (gencode (HI (c_code.opcode)), \
- conscode (gencode (LO (c_code.opcode)), NULL_CODE))
-
-#define GEN_OPCODE16() \
- conscode (gencode (c_code.opcode), NULL_CODE)
-
-
-/* 32 BIT INSTRUCTIONS. */
-
-
-/* DSP32 instruction generation. */
-
-INSTR_T
-bfin_gen_dsp32mac (int op1, int MM, int mmod, int w1, int P,
- int h01, int h11, int h00, int h10, int op0,
- REG_T dst, REG_T src0, REG_T src1, int w0)
-{
- INIT (DSP32Mac);
-
- ASSIGN (op0);
- ASSIGN (op1);
- ASSIGN (MM);
- ASSIGN (mmod);
- ASSIGN (w0);
- ASSIGN (w1);
- ASSIGN (h01);
- ASSIGN (h11);
- ASSIGN (h00);
- ASSIGN (h10);
- ASSIGN (P);
-
- /* If we have full reg assignments, mask out LSB to encode
- single or simultaneous even/odd register moves. */
- if (P)
- {
- dst->regno &= 0x06;
- }
-
- ASSIGN_R (dst);
- ASSIGN_R (src0);
- ASSIGN_R (src1);
-
- return GEN_OPCODE32 ();
-}
-
-INSTR_T
-bfin_gen_dsp32mult (int op1, int MM, int mmod, int w1, int P,
- int h01, int h11, int h00, int h10, int op0,
- REG_T dst, REG_T src0, REG_T src1, int w0)
-{
- INIT (DSP32Mult);
-
- ASSIGN (op0);
- ASSIGN (op1);
- ASSIGN (MM);
- ASSIGN (mmod);
- ASSIGN (w0);
- ASSIGN (w1);
- ASSIGN (h01);
- ASSIGN (h11);
- ASSIGN (h00);
- ASSIGN (h10);
- ASSIGN (P);
-
- if (P)
- {
- dst->regno &= 0x06;
- }
-
- ASSIGN_R (dst);
- ASSIGN_R (src0);
- ASSIGN_R (src1);
-
- return GEN_OPCODE32 ();
-}
-
-INSTR_T
-bfin_gen_dsp32alu (int HL, int aopcde, int aop, int s, int x,
- REG_T dst0, REG_T dst1, REG_T src0, REG_T src1)
-{
- INIT (DSP32Alu);
-
- ASSIGN (HL);
- ASSIGN (aopcde);
- ASSIGN (aop);
- ASSIGN (s);
- ASSIGN (x);
- ASSIGN_R (dst0);
- ASSIGN_R (dst1);
- ASSIGN_R (src0);
- ASSIGN_R (src1);
-
- return GEN_OPCODE32 ();
-}
-
-INSTR_T
-bfin_gen_dsp32shift (int sopcde, REG_T dst0, REG_T src0,
- REG_T src1, int sop, int HLs)
-{
- INIT (DSP32Shift);
-
- ASSIGN (sopcde);
- ASSIGN (sop);
- ASSIGN (HLs);
-
- ASSIGN_R (dst0);
- ASSIGN_R (src0);
- ASSIGN_R (src1);
-
- return GEN_OPCODE32 ();
-}
-
-INSTR_T
-bfin_gen_dsp32shiftimm (int sopcde, REG_T dst0, int immag,
- REG_T src1, int sop, int HLs)
-{
- INIT (DSP32ShiftImm);
-
- ASSIGN (sopcde);
- ASSIGN (sop);
- ASSIGN (HLs);
-
- ASSIGN_R (dst0);
- ASSIGN (immag);
- ASSIGN_R (src1);
-
- return GEN_OPCODE32 ();
-}
-
-/* LOOP SETUP. */
-
-INSTR_T
-bfin_gen_loopsetup (Expr_Node * psoffset, REG_T c, int rop,
- Expr_Node * peoffset, REG_T reg)
-{
- int soffset, eoffset;
- INIT (LoopSetup);
-
- soffset = (EXPR_VALUE (psoffset) >> 1);
- ASSIGN (soffset);
- eoffset = (EXPR_VALUE (peoffset) >> 1);
- ASSIGN (eoffset);
- ASSIGN (rop);
- ASSIGN_R (c);
- ASSIGN_R (reg);
-
- return
- conscode (gencode (HI (c_code.opcode)),
- conctcode (Expr_Node_Gen_Reloc (psoffset, BFD_RELOC_BFIN_5_PCREL),
- conctcode (gencode (LO (c_code.opcode)), Expr_Node_Gen_Reloc (peoffset, BFD_RELOC_BFIN_11_PCREL))));
-
-}
-
-/* Call, Link. */
-
-INSTR_T
-bfin_gen_calla (Expr_Node * addr, int S)
-{
- int val;
- int high_val;
- int rel = 0;
- INIT (CALLa);
-
- switch(S){
- case 0 : rel = BFD_RELOC_BFIN_24_PCREL_JUMP_L; break;
- case 1 : rel = BFD_RELOC_24_PCREL; break;
- case 2 : rel = BFD_RELOC_BFIN_PLTPC; break;
- default : break;
- }
-
- ASSIGN (S);
-
- val = EXPR_VALUE (addr) >> 1;
- high_val = val >> 16;
-
- return conscode (gencode (HI (c_code.opcode) | (high_val & 0xff)),
- Expr_Node_Gen_Reloc (addr, rel));
- }
-
-INSTR_T
-bfin_gen_linkage (int R, int framesize)
-{
- INIT (Linkage);
-
- ASSIGN (R);
- ASSIGN (framesize);
-
- return GEN_OPCODE32 ();
-}
-
-
-/* Load and Store. */
-
-INSTR_T
-bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int rel)
-{
- int grp, hword;
- unsigned val = EXPR_VALUE (phword);
- INIT (LDIMMhalf);
-
- ASSIGN (H);
- ASSIGN (S);
- ASSIGN (Z);
-
- ASSIGN_R (reg);
- grp = (GROUP (reg));
- ASSIGN (grp);
- if (rel == 2)
- {
- return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, BFD_RELOC_BFIN_16_IMM));
- }
- else if (rel == 1)
- {
- 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));
- }
- else
- {
- hword = val;
- ASSIGN (hword);
- }
- return GEN_OPCODE32 ();
-}
-
-INSTR_T
-bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset)
-{
- INIT (LDSTidxI);
-
- if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
- {
- fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
- return 0;
- }
-
- ASSIGN_R (ptr);
- ASSIGN_R (reg);
- ASSIGN (W);
- ASSIGN (sz);
-
- ASSIGN (Z);
-
- if (poffset->type != Expr_Node_Constant)
- {
- /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
- /* distinguish between R0 = [P5 + symbol@GOT] and
- P5 = [P5 + _current_shared_library_p5_offset_]
- */
- if (poffset->type == Expr_Node_Reloc
- && !strcmp (poffset->value.s_value,
- "_current_shared_library_p5_offset_"))
- {
- return conscode (gencode (HI (c_code.opcode)),
- Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16));
- }
- else if (poffset->type != Expr_Node_GOT_Reloc)
- abort ();
-
- return conscode (gencode (HI (c_code.opcode)),
- Expr_Node_Gen_Reloc(poffset->Left_Child,
- poffset->value.i_value));
- }
- else
- {
- int value, offset;
- switch (sz)
- { /* load/store access size */
- case 0: /* 32 bit */
- value = EXPR_VALUE (poffset) >> 2;
- break;
- case 1: /* 16 bit */
- value = EXPR_VALUE (poffset) >> 1;
- break;
- case 2: /* 8 bit */
- value = EXPR_VALUE (poffset);
- break;
- default:
- abort ();
- }
-
- offset = (value & 0xffff);
- ASSIGN (offset);
- return GEN_OPCODE32 ();
- }
-}
-
-
-INSTR_T
-bfin_gen_ldst (REG_T ptr, REG_T reg, int aop, int sz, int Z, int W)
-{
- INIT (LDST);
-
- if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
- {
- fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
- return 0;
- }
-
- ASSIGN_R (ptr);
- ASSIGN_R (reg);
- ASSIGN (aop);
- ASSIGN (sz);
- ASSIGN (Z);
- ASSIGN (W);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_ldstii (REG_T ptr, REG_T reg, Expr_Node * poffset, int W, int opc)
-{
- int offset;
- int value = 0;
- INIT (LDSTii);
-
- if (!IS_PREG (*ptr))
- {
- fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
- return 0;
- }
-
- switch (opc)
- {
- case 1:
- case 2:
- value = EXPR_VALUE (poffset) >> 1;
- break;
- case 0:
- case 3:
- value = EXPR_VALUE (poffset) >> 2;
- break;
- }
-
- ASSIGN_R (ptr);
- ASSIGN_R (reg);
-
- offset = value;
- ASSIGN (offset);
- ASSIGN (W);
- ASSIGNF (opc, op);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_ldstiifp (REG_T sreg, Expr_Node * poffset, int W)
-{
- /* Set bit 4 if it's a Preg. */
- int reg = (sreg->regno & CODE_MASK) | (IS_PREG (*sreg) ? 0x8 : 0x0);
- int offset = ((~(EXPR_VALUE (poffset) >> 2)) & 0x1f) + 1;
- INIT (LDSTiiFP);
- ASSIGN (reg);
- ASSIGN (offset);
- ASSIGN (W);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_ldstpmod (REG_T ptr, REG_T reg, int aop, int W, REG_T idx)
-{
- INIT (LDSTpmod);
-
- ASSIGN_R (ptr);
- ASSIGN_R (reg);
- ASSIGN (aop);
- ASSIGN (W);
- ASSIGN_R (idx);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_dspldst (REG_T i, REG_T reg, int aop, int W, int m)
-{
- INIT (DspLDST);
-
- ASSIGN_R (i);
- ASSIGN_R (reg);
- ASSIGN (aop);
- ASSIGN (W);
- ASSIGN (m);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_logi2op (int opc, int src, int dst)
-{
- INIT (LOGI2op);
-
- ASSIGN (opc);
- ASSIGN (src);
- ASSIGN (dst);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_brcc (int T, int B, Expr_Node * poffset)
-{
- int offset;
- INIT (BRCC);
-
- ASSIGN (T);
- ASSIGN (B);
- offset = ((EXPR_VALUE (poffset) >> 1));
- ASSIGN (offset);
- return conscode (gencode (c_code.opcode), Expr_Node_Gen_Reloc (poffset, BFD_RELOC_BFIN_10_PCREL));
-}
-
-INSTR_T
-bfin_gen_ujump (Expr_Node * poffset)
-{
- int offset;
- INIT (UJump);
-
- offset = ((EXPR_VALUE (poffset) >> 1));
- ASSIGN (offset);
-
- return conscode (gencode (c_code.opcode),
- Expr_Node_Gen_Reloc (
- poffset, BFD_RELOC_BFIN_12_PCREL_JUMP_S));
-}
-
-INSTR_T
-bfin_gen_alu2op (REG_T dst, REG_T src, int opc)
-{
- INIT (ALU2op);
-
- ASSIGN_R (dst);
- ASSIGN_R (src);
- ASSIGN (opc);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_compi2opd (REG_T dst, int src, int opc)
-{
- INIT (COMPI2opD);
-
- ASSIGN_R (dst);
- ASSIGN (src);
- ASSIGNF (opc, op);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_compi2opp (REG_T dst, int src, int opc)
-{
- INIT (COMPI2opP);
-
- ASSIGN_R (dst);
- ASSIGN (src);
- ASSIGNF (opc, op);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_dagmodik (REG_T i, int opc)
-{
- INIT (DagMODik);
-
- ASSIGN_R (i);
- ASSIGNF (opc, op);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_dagmodim (REG_T i, REG_T m, int opc, int br)
-{
- INIT (DagMODim);
-
- ASSIGN_R (i);
- ASSIGN_R (m);
- ASSIGNF (opc, op);
- ASSIGN (br);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_ptr2op (REG_T dst, REG_T src, int opc)
-{
- INIT (PTR2op);
-
- ASSIGN_R (dst);
- ASSIGN_R (src);
- ASSIGN (opc);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_comp3op (REG_T src0, REG_T src1, REG_T dst, int opc)
-{
- INIT (COMP3op);
-
- ASSIGN_R (src0);
- ASSIGN_R (src1);
- ASSIGN_R (dst);
- ASSIGN (opc);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_ccflag (REG_T x, int y, int opc, int I, int G)
-{
- INIT (CCflag);
-
- ASSIGN_R (x);
- ASSIGN (y);
- ASSIGN (opc);
- ASSIGN (I);
- ASSIGN (G);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_ccmv (REG_T src, REG_T dst, int T)
-{
- int s, d;
- INIT (CCmv);
-
- ASSIGN_R (src);
- ASSIGN_R (dst);
- s = (GROUP (src));
- ASSIGN (s);
- d = (GROUP (dst));
- ASSIGN (d);
- ASSIGN (T);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_cc2stat (int cbit, int opc, int D)
-{
- INIT (CC2stat);
-
- ASSIGN (cbit);
- ASSIGNF (opc, op);
- ASSIGN (D);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_regmv (REG_T src, REG_T dst)
-{
- int gs, gd;
- INIT (RegMv);
-
- ASSIGN_R (src);
- ASSIGN_R (dst);
-
- gs = (GROUP (src));
- ASSIGN (gs);
- gd = (GROUP (dst));
- ASSIGN (gd);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_cc2dreg (int opc, REG_T reg)
-{
- INIT (CC2dreg);
-
- ASSIGNF (opc, op);
- ASSIGN_R (reg);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_progctrl (int prgfunc, int poprnd)
-{
- INIT (ProgCtrl);
-
- ASSIGN (prgfunc);
- ASSIGN (poprnd);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_cactrl (REG_T reg, int a, int opc)
-{
- INIT (CaCTRL);
-
- ASSIGN_R (reg);
- ASSIGN (a);
- ASSIGNF (opc, op);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_pushpopmultiple (int dr, int pr, int d, int p, int W)
-{
- INIT (PushPopMultiple);
-
- ASSIGN (dr);
- ASSIGN (pr);
- ASSIGN (d);
- ASSIGN (p);
- ASSIGN (W);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_pushpopreg (REG_T reg, int W)
-{
- int grp;
- INIT (PushPopReg);
-
- ASSIGN_R (reg);
- grp = (GROUP (reg));
- ASSIGN (grp);
- ASSIGN (W);
-
- return GEN_OPCODE16 ();
-}
-
-/* Pseudo Debugging Support. */
-
-INSTR_T
-bfin_gen_pseudodbg (int fn, int reg, int grp)
-{
- INIT (PseudoDbg);
-
- ASSIGN (fn);
- ASSIGN (reg);
- ASSIGN (grp);
-
- return GEN_OPCODE16 ();
-}
-
-INSTR_T
-bfin_gen_pseudodbg_assert (int dbgop, REG_T regtest, int expected)
-{
- int grp;
- INIT (PseudoDbg_Assert);
-
- ASSIGN (dbgop);
- ASSIGN_R (regtest);
- grp = GROUP (regtest);
- ASSIGN (grp);
- ASSIGN (expected);
-
- return GEN_OPCODE32 ();
-}
-
-INSTR_T
-bfin_gen_pseudochr (int ch)
-{
- INIT (PseudoChr);
-
- ASSIGN (ch);
-
- return GEN_OPCODE16 ();
-}
-
-/* Multiple instruction generation. */
-
-INSTR_T
-bfin_gen_multi_instr (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2)
-{
- INSTR_T walk;
-
- /* If it's a 0, convert into MNOP. */
- if (dsp32)
- {
- walk = dsp32->next;
- SET_MULTI_INSTRUCTION_BIT (dsp32);
- }
- else
- {
- dsp32 = gencode (0xc803);
- walk = gencode (0x1800);
- dsp32->next = walk;
- }
-
- if (!dsp16_grp1)
- {
- dsp16_grp1 = gencode (0x0000);
- }
-
- if (!dsp16_grp2)
- {
- dsp16_grp2 = gencode (0x0000);
- }
-
- walk->next = dsp16_grp1;
- dsp16_grp1->next = dsp16_grp2;
- dsp16_grp2->next = NULL_CODE;
-
- return dsp32;
-}
-
-INSTR_T
-bfin_gen_loop (Expr_Node *exp, REG_T reg, int rop, REG_T preg)
-{
- const char *loopsym;
- char *lbeginsym, *lendsym;
- Expr_Node_Value lbeginval, lendval;
- Expr_Node *lbegin, *lend;
- symbolS *sym;
-
- loopsym = exp->value.s_value;
- lbeginsym = (char *) xmalloc (strlen (loopsym) + strlen ("__BEGIN") + 5);
- lendsym = (char *) xmalloc (strlen (loopsym) + strlen ("__END") + 5);
-
- lbeginsym[0] = 0;
- lendsym[0] = 0;
-
- strcat (lbeginsym, "L$L$");
- strcat (lbeginsym, loopsym);
- strcat (lbeginsym, "__BEGIN");
-
- strcat (lendsym, "L$L$");
- strcat (lendsym, loopsym);
- strcat (lendsym, "__END");
-
- lbeginval.s_value = lbeginsym;
- lendval.s_value = lendsym;
-
- lbegin = Expr_Node_Create (Expr_Node_Reloc, lbeginval, NULL, NULL);
- lend = Expr_Node_Create (Expr_Node_Reloc, lendval, NULL, NULL);
-
- sym = symbol_find(loopsym);
- if (!S_IS_LOCAL (sym) || (S_IS_LOCAL (sym) && !symbol_used_p (sym)))
- symbol_remove (sym, &symbol_rootP, &symbol_lastP);
-
- return bfin_gen_loopsetup (lbegin, reg, rop, lend, preg);
-}
-
-void
-bfin_loop_attempt_create_label (Expr_Node *exp, int is_begin)
-{
- char *name;
- name = fb_label_name (exp->value.i_value, is_begin);
- exp->value.s_value = xstrdup (name);
- exp->type = Expr_Node_Reloc;
-}
-
-void
-bfin_loop_beginend (Expr_Node *exp, int begin)
-{
- const char *loopsym;
- char *label_name;
- symbolS *linelabel;
- const char *suffix = begin ? "__BEGIN" : "__END";
-
- loopsym = exp->value.s_value;
- label_name = (char *) xmalloc (strlen (loopsym) + strlen (suffix) + 5);
-
- label_name[0] = 0;
-
- strcat (label_name, "L$L$");
- strcat (label_name, loopsym);
- strcat (label_name, suffix);
-
- linelabel = colon (label_name);
-
- /* LOOP_END follows the last instruction in the loop.
- Adjust label address. */
- if (!begin)
- ((struct local_symbol *) linelabel)->lsy_value -= last_insn_size;
-}
-
-bfd_boolean
-bfin_eol_in_insn (char *line)
-{
- /* Allow a new-line to appear in the middle of a multi-issue instruction. */
-
- char *temp = line;
-
- if (*line != '\n')
- return FALSE;
-
- /* A semi-colon followed by a newline is always the end of a line. */
- if (line[-1] == ';')
- return FALSE;
-
- if (line[-1] == '|')
- return TRUE;
-
- /* If the || is on the next line, there might be leading whitespace. */
- temp++;
- while (*temp == ' ' || *temp == '\t') temp++;
-
- if (*temp == '|')
- return TRUE;
-
- return FALSE;
-}
-
-bfd_boolean
-bfin_start_label (char *s, char *ptr)
-{
- while (s != ptr)
- {
- if (*s == '(' || *s == '[')
- return FALSE;
- s++;
- }
-
- return TRUE;
-}
-
-int
-bfin_force_relocation (struct fix *fixp)
-{
- if (fixp->fx_r_type ==BFD_RELOC_BFIN_16_LOW
- || fixp->fx_r_type == BFD_RELOC_BFIN_16_HIGH)
- return TRUE;
-
- return generic_force_reloc (fixp);
-}
-
-/* This is a stripped down version of the disassembler. The only thing it
- does is return a mask of registers modified by an instruction. Only
- instructions that can occur in a parallel-issue bundle are handled, and
- only the registers that can cause a conflict are recorded. */
-
-#define DREG_MASK(n) (0x101 << (n))
-#define DREGH_MASK(n) (0x100 << (n))
-#define DREGL_MASK(n) (0x001 << (n))
-#define IREG_MASK(n) (1 << ((n) + 16))
-
-static int
-decode_ProgCtrl_0 (int iw0)
-{
- if (iw0 == 0)
- return 0;
- abort ();
-}
-
-static int
-decode_LDSTpmod_0 (int iw0)
-{
- /* LDSTpmod
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
- | 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......|
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
- int W = ((iw0 >> LDSTpmod_W_bits) & LDSTpmod_W_mask);
- int aop = ((iw0 >> LDSTpmod_aop_bits) & LDSTpmod_aop_mask);
- int idx = ((iw0 >> LDSTpmod_idx_bits) & LDSTpmod_idx_mask);
- int ptr = ((iw0 >> LDSTpmod_ptr_bits) & LDSTpmod_ptr_mask);
- int reg = ((iw0 >> LDSTpmod_reg_bits) & LDSTpmod_reg_mask);
-
- if (aop == 1 && W == 0 && idx == ptr)
- return DREGL_MASK (reg);
- else if (aop == 2 && W == 0 && idx == ptr)
- return DREGH_MASK (reg);
- else if (aop == 1 && W == 1 && idx == ptr)
- return 0;
- else if (aop == 2 && W == 1 && idx == ptr)
- return 0;
- else if (aop == 0 && W == 0)
- return DREG_MASK (reg);
- else if (aop == 1 && W == 0)
- return DREGL_MASK (reg);
- else if (aop == 2 && W == 0)
- return DREGH_MASK (reg);
- else if (aop == 3 && W == 0)
- return DREG_MASK (reg);
- else if (aop == 3 && W == 1)
- return DREG_MASK (reg);
- else if (aop == 0 && W == 1)
- return 0;
- else if (aop == 1 && W == 1)
- return 0;
- else if (aop == 2 && W == 1)
- return 0;
- else
- return 0;
-
- return 2;
-}
-
-static int
-decode_dagMODim_0 (int iw0)
-{
- /* dagMODim
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
- | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....|
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
- int i = ((iw0 >> DagMODim_i_bits) & DagMODim_i_mask);
- int opc = ((iw0 >> DagMODim_op_bits) & DagMODim_op_mask);
-
- if (opc == 0 || opc == 1)
- return IREG_MASK (i);
- else
- return 0;
-
- return 2;
-}
-
-static int
-decode_dagMODik_0 (int iw0)
-{
- /* dagMODik
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
- | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....|
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
- int i = ((iw0 >> DagMODik_i_bits) & DagMODik_i_mask);
- return IREG_MASK (i);
-}
-
-/* GOOD */
-static int
-decode_dspLDST_0 (int iw0)
-{
- /* dspLDST
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
- | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......|
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
- int i = ((iw0 >> DspLDST_i_bits) & DspLDST_i_mask);
- int m = ((iw0 >> DspLDST_m_bits) & DspLDST_m_mask);
- int W = ((iw0 >> DspLDST_W_bits) & DspLDST_W_mask);
- int aop = ((iw0 >> DspLDST_aop_bits) & DspLDST_aop_mask);
- int reg = ((iw0 >> DspLDST_reg_bits) & DspLDST_reg_mask);
-
- if (aop == 0 && W == 0 && m == 0)
- return DREG_MASK (reg) | IREG_MASK (i);
- else if (aop == 0 && W == 0 && m == 1)
- return DREGL_MASK (reg) | IREG_MASK (i);
- else if (aop == 0 && W == 0 && m == 2)
- return DREGH_MASK (reg) | IREG_MASK (i);
- else if (aop == 1 && W == 0 && m == 0)
- return DREG_MASK (reg) | IREG_MASK (i);
- else if (aop == 1 && W == 0 && m == 1)
- return DREGL_MASK (reg) | IREG_MASK (i);
- else if (aop == 1 && W == 0 && m == 2)
- return DREGH_MASK (reg) | IREG_MASK (i);
- else if (aop == 2 && W == 0 && m == 0)
- return DREG_MASK (reg);
- else if (aop == 2 && W == 0 && m == 1)
- return DREGL_MASK (reg);
- else if (aop == 2 && W == 0 && m == 2)
- return DREGH_MASK (reg);
- else if (aop == 0 && W == 1 && m == 0)
- return IREG_MASK (i);
- else if (aop == 0 && W == 1 && m == 1)
- return IREG_MASK (i);
- else if (aop == 0 && W == 1 && m == 2)
- return IREG_MASK (i);
- else if (aop == 1 && W == 1 && m == 0)
- return IREG_MASK (i);
- else if (aop == 1 && W == 1 && m == 1)
- return IREG_MASK (i);
- else if (aop == 1 && W == 1 && m == 2)
- return IREG_MASK (i);
- else if (aop == 2 && W == 1 && m == 0)
- return 0;
- else if (aop == 2 && W == 1 && m == 1)
- return 0;
- else if (aop == 2 && W == 1 && m == 2)
- return 0;
- else if (aop == 3 && W == 0)
- return DREG_MASK (reg) | IREG_MASK (i);
- else if (aop == 3 && W == 1)
- return IREG_MASK (i);
-
- abort ();
-}
-
-/* GOOD */
-static int
-decode_LDST_0 (int iw0)
-{
- /* LDST
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
- | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......|
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
- int Z = ((iw0 >> LDST_Z_bits) & LDST_Z_mask);
- int W = ((iw0 >> LDST_W_bits) & LDST_W_mask);
- int sz = ((iw0 >> LDST_sz_bits) & LDST_sz_mask);
- int aop = ((iw0 >> LDST_aop_bits) & LDST_aop_mask);
- int reg = ((iw0 >> LDST_reg_bits) & LDST_reg_mask);
-
- if (aop == 0 && sz == 0 && Z == 0 && W == 0)
- return DREG_MASK (reg);
- else if (aop == 0 && sz == 0 && Z == 1 && W == 0)
- return 0;
- else if (aop == 0 && sz == 1 && Z == 0 && W == 0)
- return DREG_MASK (reg);
- else if (aop == 0 && sz == 1 && Z == 1 && W == 0)
- return DREG_MASK (reg);
- else if (aop == 0 && sz == 2 && Z == 0 && W == 0)
- return DREG_MASK (reg);
- else if (aop == 0 && sz == 2 && Z == 1 && W == 0)
- return DREG_MASK (reg);
- else if (aop == 1 && sz == 0 && Z == 0 && W == 0)
- return DREG_MASK (reg);
- else if (aop == 1 && sz == 0 && Z == 1 && W == 0)
- return 0;
- else if (aop == 1 && sz == 1 && Z == 0 && W == 0)
- return DREG_MASK (reg);
- else if (aop == 1 && sz == 1 && Z == 1 && W == 0)
- return DREG_MASK (reg);
- else if (aop == 1 && sz == 2 && Z == 0 && W == 0)
- return DREG_MASK (reg);
- else if (aop == 1 && sz == 2 && Z == 1 && W == 0)
- return DREG_MASK (reg);
- else if (aop == 2 && sz == 0 && Z == 0 && W == 0)
- return DREG_MASK (reg);
- else if (aop == 2 && sz == 0 && Z == 1 && W == 0)
- return 0;
- else if (aop == 2 && sz == 1 && Z == 0 && W == 0)
- return DREG_MASK (reg);
- else if (aop == 2 && sz == 1 && Z == 1 && W == 0)
- return DREG_MASK (reg);
- else if (aop == 2 && sz == 2 && Z == 0 && W == 0)
- return DREG_MASK (reg);
- else if (aop == 2 && sz == 2 && Z == 1 && W == 0)
- return DREG_MASK (reg);
- else if (aop == 0 && sz == 0 && Z == 0 && W == 1)
- return 0;
- else if (aop == 0 && sz == 0 && Z == 1 && W == 1)
- return 0;
- else if (aop == 0 && sz == 1 && Z == 0 && W == 1)
- return 0;
- else if (aop == 0 && sz == 2 && Z == 0 && W == 1)
- return 0;
- else if (aop == 1 && sz == 0 && Z == 0 && W == 1)
- return 0;
- else if (aop == 1 && sz == 0 && Z == 1 && W == 1)
- return 0;
- else if (aop == 1 && sz == 1 && Z == 0 && W == 1)
- return 0;
- else if (aop == 1 && sz == 2 && Z == 0 && W == 1)
- return 0;
- else if (aop == 2 && sz == 0 && Z == 0 && W == 1)
- return 0;
- else if (aop == 2 && sz == 0 && Z == 1 && W == 1)
- return 0;
- else if (aop == 2 && sz == 1 && Z == 0 && W == 1)
- return 0;
- else if (aop == 2 && sz == 2 && Z == 0 && W == 1)
- return 0;
-
- abort ();
-}
-
-static int
-decode_LDSTiiFP_0 (int iw0)
-{
- /* LDSTiiFP
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
- | 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........|
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
- int reg = ((iw0 >> LDSTiiFP_reg_bits) & LDSTiiFP_reg_mask);
- int W = ((iw0 >> LDSTiiFP_W_bits) & LDSTiiFP_W_mask);
-
- if (W == 0)
- return reg < 8 ? DREG_MASK (reg) : 0;
- else
- return 0;
-}
-
-static int
-decode_LDSTii_0 (int iw0)
-{
- /* LDSTii
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
- | 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......|
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
- int reg = ((iw0 >> LDSTii_reg_bit) & LDSTii_reg_mask);
- int opc = ((iw0 >> LDSTii_op_bit) & LDSTii_op_mask);
- int W = ((iw0 >> LDSTii_W_bit) & LDSTii_W_mask);
-
- if (W == 0 && opc != 3)
- return DREG_MASK (reg);
- else if (W == 0 && opc == 3)
- return 0;
- else if (W == 1 && opc == 0)
- return 0;
- else if (W == 1 && opc == 1)
- return 0;
- else if (W == 1 && opc == 3)
- return 0;
-
- abort ();
-}
-
-static int
-decode_dsp32mac_0 (int iw0, int iw1)
-{
- int result = 0;
- /* dsp32mac
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
- | 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...|
- |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
- int op1 = ((iw0 >> (DSP32Mac_op1_bits - 16)) & DSP32Mac_op1_mask);
- int w1 = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask);
- int P = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask);
- int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask);
- int w0 = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask);
- int MM = ((iw1 >> DSP32Mac_MM_bits) & DSP32Mac_MM_mask);
- int dst = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask);
- int op0 = ((iw1 >> DSP32Mac_op0_bits) & DSP32Mac_op0_mask);
-
- if (w0 == 0 && w1 == 0 && op1 == 3 && op0 == 3)
- return 0;
-
- if (op1 == 3 && MM)
- return 0;
-
- if ((w1 || w0) && mmod == M_W32)
- return 0;
-
- if (((1 << mmod) & (P ? 0x131b : 0x1b5f)) == 0)
- return 0;
-
- if (w1 == 1 || op1 != 3)
- {
- if (w1)
- {
- if (P)
- return DREG_MASK (dst + 1);
- else
- return DREGH_MASK (dst);
- }
- }
-
- if (w0 == 1 || op0 != 3)
- {
- if (w0)
- {
- if (P)
- return DREG_MASK (dst);
- else
- return DREGL_MASK (dst);
- }
- }
-
- return result;
-}
-
-static int
-decode_dsp32mult_0 (int iw0, int iw1)
-{
- /* dsp32mult
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
- | 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...|
- |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
- int w1 = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask);
- int P = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask);
- int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask);
- int w0 = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask);
- int dst = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask);
- int result = 0;
-
- if (w1 == 0 && w0 == 0)
- return 0;
-
- if (((1 << mmod) & (P ? 0x313 : 0x1b57)) == 0)
- return 0;
-
- if (w1)
- {
- if (P)
- return DREG_MASK (dst | 1);
- else
- return DREGH_MASK (dst);
- }
-
- if (w0)
- {
- if (P)
- return DREG_MASK (dst);
- else
- return DREGL_MASK (dst);
- }
-
- return result;
-}
-
-static int
-decode_dsp32alu_0 (int iw0, int iw1)
-{
- /* dsp32alu
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
- | 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............|
- |.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......|
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
- int s = ((iw1 >> DSP32Alu_s_bits) & DSP32Alu_s_mask);
- int x = ((iw1 >> DSP32Alu_x_bits) & DSP32Alu_x_mask);
- int aop = ((iw1 >> DSP32Alu_aop_bits) & DSP32Alu_aop_mask);
- int dst0 = ((iw1 >> DSP32Alu_dst0_bits) & DSP32Alu_dst0_mask);
- int dst1 = ((iw1 >> DSP32Alu_dst1_bits) & DSP32Alu_dst1_mask);
- int HL = ((iw0 >> (DSP32Alu_HL_bits - 16)) & DSP32Alu_HL_mask);
- int aopcde = ((iw0 >> (DSP32Alu_aopcde_bits - 16)) & DSP32Alu_aopcde_mask);
-
- if (aop == 0 && aopcde == 9 && s == 0)
- return 0;
- else if (aop == 2 && aopcde == 9 && HL == 0 && s == 0)
- return 0;
- else if (aop >= x * 2 && aopcde == 5)
- return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
- else if (HL == 0 && aopcde == 2)
- return DREGL_MASK (dst0);
- else if (HL == 1 && aopcde == 2)
- return DREGH_MASK (dst0);
- else if (HL == 0 && aopcde == 3)
- return DREGL_MASK (dst0);
- else if (HL == 1 && aopcde == 3)
- return DREGH_MASK (dst0);
-
- else if (aop == 0 && aopcde == 9 && s == 1)
- return 0;
- else if (aop == 1 && aopcde == 9 && s == 0)
- return 0;
- else if (aop == 2 && aopcde == 9 && s == 1)
- return 0;
- else if (aop == 3 && aopcde == 9 && s == 0)
- return 0;
- else if (aopcde == 8)
- return 0;
- else if (aop == 0 && aopcde == 11)
- return DREG_MASK (dst0);
- else if (aop == 1 && aopcde == 11)
- return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
- else if (aopcde == 11)
- return 0;
- else if (aopcde == 22)
- return DREG_MASK (dst0);
-
- else if ((aop == 0 || aop == 1) && aopcde == 14)
- return 0;
- else if (aop == 3 && HL == 0 && aopcde == 14)
- return 0;
-
- else if (aop == 3 && HL == 0 && aopcde == 15)
- return DREG_MASK (dst0);
-
- else if (aop == 1 && aopcde == 16)
- return 0;
-
- else if (aop == 0 && aopcde == 16)
- return 0;
-
- else if (aop == 3 && HL == 0 && aopcde == 16)
- return 0;
-
- else if (aop == 3 && HL == 0 && aopcde == 7)
- return DREG_MASK (dst0);
- else if ((aop == 0 || aop == 1 || aop == 2) && aopcde == 7)
- return DREG_MASK (dst0);
-
- else if (aop == 0 && aopcde == 12)
- return DREG_MASK (dst0);
- else if (aop == 1 && aopcde == 12)
- return DREG_MASK (dst0) | DREG_MASK (dst1);
- else if (aop == 3 && aopcde == 12)
- return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
-
- else if (aopcde == 0)
- return DREG_MASK (dst0);
- else if (aopcde == 1)
- return DREG_MASK (dst0) | DREG_MASK (dst1);
-
- else if (aop == 0 && aopcde == 10)
- return DREGL_MASK (dst0);
- else if (aop == 1 && aopcde == 10)
- return DREGL_MASK (dst0);
-
- else if ((aop == 1 || aop == 0) && aopcde == 4)
- return DREG_MASK (dst0);
- else if (aop == 2 && aopcde == 4)
- return DREG_MASK (dst0) | DREG_MASK (dst1);
-
- else if (aop == 0 && aopcde == 17)
- return DREG_MASK (dst0) | DREG_MASK (dst1);
- else if (aop == 1 && aopcde == 17)
- return DREG_MASK (dst0) | DREG_MASK (dst1);
- else if (aop == 0 && aopcde == 18)
- return 0;
- else if (aop == 3 && aopcde == 18)
- return 0;
-
- else if ((aop == 0 || aop == 1 || aop == 2) && aopcde == 6)
- return DREG_MASK (dst0);
-
- else if ((aop == 0 || aop == 1) && aopcde == 20)
- return DREG_MASK (dst0);
-
- else if ((aop == 0 || aop == 1) && aopcde == 21)
- return DREG_MASK (dst0) | DREG_MASK (dst1);
-
- else if (aop == 0 && aopcde == 23 && HL == 1)
- return DREG_MASK (dst0);
- else if (aop == 0 && aopcde == 23 && HL == 0)
- return DREG_MASK (dst0);
-
- else if (aop == 0 && aopcde == 24)
- return DREG_MASK (dst0);
- else if (aop == 1 && aopcde == 24)
- return DREG_MASK (dst0) | DREG_MASK (dst1);
- else if (aopcde == 13)
- return DREG_MASK (dst0) | DREG_MASK (dst1);
- else
- return 0;
-
- return 4;
-}
-
-static int
-decode_dsp32shift_0 (int iw0, int iw1)
-{
- /* dsp32shift
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
- | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............|
- |.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......|
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
- int HLs = ((iw1 >> DSP32Shift_HLs_bits) & DSP32Shift_HLs_mask);
- int sop = ((iw1 >> DSP32Shift_sop_bits) & DSP32Shift_sop_mask);
- int src0 = ((iw1 >> DSP32Shift_src0_bits) & DSP32Shift_src0_mask);
- int src1 = ((iw1 >> DSP32Shift_src1_bits) & DSP32Shift_src1_mask);
- int dst0 = ((iw1 >> DSP32Shift_dst0_bits) & DSP32Shift_dst0_mask);
- int sopcde = ((iw0 >> (DSP32Shift_sopcde_bits - 16)) & DSP32Shift_sopcde_mask);
-
- if (sop == 0 && sopcde == 0)
- return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
- else if (sop == 1 && sopcde == 0)
- return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
- else if (sop == 2 && sopcde == 0)
- return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
- else if (sop == 0 && sopcde == 3)
- return 0;
- else if (sop == 1 && sopcde == 3)
- return 0;
- else if (sop == 2 && sopcde == 3)
- return 0;
- else if (sop == 3 && sopcde == 3)
- return DREG_MASK (dst0);
- else if (sop == 0 && sopcde == 1)
- return DREG_MASK (dst0);
- else if (sop == 1 && sopcde == 1)
- return DREG_MASK (dst0);
- else if (sop == 2 && sopcde == 1)
- return DREG_MASK (dst0);
- else if (sopcde == 2)
- return DREG_MASK (dst0);
- else if (sopcde == 4)
- return DREG_MASK (dst0);
- else if (sop == 0 && sopcde == 5)
- return DREGL_MASK (dst0);
- else if (sop == 1 && sopcde == 5)
- return DREGL_MASK (dst0);
- else if (sop == 2 && sopcde == 5)
- return DREGL_MASK (dst0);
- else if (sop == 0 && sopcde == 6)
- return DREGL_MASK (dst0);
- else if (sop == 1 && sopcde == 6)
- return DREGL_MASK (dst0);
- else if (sop == 3 && sopcde == 6)
- return DREGL_MASK (dst0);
- else if (sop == 0 && sopcde == 7)
- return DREGL_MASK (dst0);
- else if (sop == 1 && sopcde == 7)
- return DREGL_MASK (dst0);
- else if (sop == 2 && sopcde == 7)
- return DREGL_MASK (dst0);
- else if (sop == 3 && sopcde == 7)
- return DREGL_MASK (dst0);
- else if (sop == 0 && sopcde == 8)
- return DREG_MASK (src0) | DREG_MASK (src1);
-#if 0
- {
- OUTS (outf, "BITMUX (");
- OUTS (outf, dregs (src0));
- OUTS (outf, ", ");
- OUTS (outf, dregs (src1));
- OUTS (outf, ", A0) (ASR)");
- }
-#endif
- else if (sop == 1 && sopcde == 8)
- return DREG_MASK (src0) | DREG_MASK (src1);
-#if 0
- {
- OUTS (outf, "BITMUX (");
- OUTS (outf, dregs (src0));
- OUTS (outf, ", ");
- OUTS (outf, dregs (src1));
- OUTS (outf, ", A0) (ASL)");
- }
-#endif
- else if (sopcde == 9)
- return sop < 2 ? DREGL_MASK (dst0) : DREG_MASK (dst0);
- else if (sopcde == 10)
- return DREG_MASK (dst0);
- else if (sop == 0 && sopcde == 11)
- return DREGL_MASK (dst0);
- else if (sop == 1 && sopcde == 11)
- return DREGL_MASK (dst0);
- else if (sop == 0 && sopcde == 12)
- return 0;
- else if (sop == 1 && sopcde == 12)
- return DREGL_MASK (dst0);
- else if (sop == 0 && sopcde == 13)
- return DREG_MASK (dst0);
- else if (sop == 1 && sopcde == 13)
- return DREG_MASK (dst0);
- else if (sop == 2 && sopcde == 13)
- return DREG_MASK (dst0);
-
- abort ();
-}
-
-static int
-decode_dsp32shiftimm_0 (int iw0, int iw1)
-{
- /* dsp32shiftimm
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
- | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............|
- |.sop...|.HLs...|.dst0......|.immag.................|.src1......|
- +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+ */
- int sop = ((iw1 >> DSP32ShiftImm_sop_bits) & DSP32ShiftImm_sop_mask);
- int bit8 = ((iw1 >> 8) & 0x1);
- int dst0 = ((iw1 >> DSP32ShiftImm_dst0_bits) & DSP32ShiftImm_dst0_mask);
- int sopcde = ((iw0 >> (DSP32ShiftImm_sopcde_bits - 16)) & DSP32ShiftImm_sopcde_mask);
- int HLs = ((iw1 >> DSP32ShiftImm_HLs_bits) & DSP32ShiftImm_HLs_mask);
-
-
- if (sop == 0 && sopcde == 0)
- return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
- else if (sop == 1 && sopcde == 0 && bit8 == 0)
- return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
- else if (sop == 1 && sopcde == 0 && bit8 == 1)
- return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
- else if (sop == 2 && sopcde == 0 && bit8 == 0)
- return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
- else if (sop == 2 && sopcde == 0 && bit8 == 1)
- return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
- else if (sop == 2 && sopcde == 3 && HLs == 1)
- return 0;
- else if (sop == 0 && sopcde == 3 && HLs == 0 && bit8 == 0)
- return 0;
- else if (sop == 0 && sopcde == 3 && HLs == 0 && bit8 == 1)
- return 0;
- else if (sop == 0 && sopcde == 3 && HLs == 1 && bit8 == 0)
- return 0;
- else if (sop == 0 && sopcde == 3 && HLs == 1 && bit8 == 1)
- return 0;
- else if (sop == 1 && sopcde == 3 && HLs == 0)
- return 0;
- else if (sop == 1 && sopcde == 3 && HLs == 1)
- return 0;
- else if (sop == 2 && sopcde == 3 && HLs == 0)
- return 0;
- else if (sop == 1 && sopcde == 1 && bit8 == 0)
- return DREG_MASK (dst0);
- else if (sop == 1 && sopcde == 1 && bit8 == 1)
- return DREG_MASK (dst0);
- else if (sop == 2 && sopcde == 1 && bit8 == 1)
- return DREG_MASK (dst0);
- else if (sop == 2 && sopcde == 1 && bit8 == 0)
- return DREG_MASK (dst0);
- else if (sop == 0 && sopcde == 1)
- return DREG_MASK (dst0);
- else if (sop == 1 && sopcde == 2)
- return DREG_MASK (dst0);
- else if (sop == 2 && sopcde == 2 && bit8 == 1)
- return DREG_MASK (dst0);
- else if (sop == 2 && sopcde == 2 && bit8 == 0)
- return DREG_MASK (dst0);
- else if (sop == 3 && sopcde == 2)
- return DREG_MASK (dst0);
- else if (sop == 0 && sopcde == 2)
- return DREG_MASK (dst0);
-
- abort ();
-}
-
-int
-insn_regmask (int iw0, int iw1)
-{
- if ((iw0 & 0xf7ff) == 0xc003 && iw1 == 0x1800)
- return 0; /* MNOP */
- else if ((iw0 & 0xff00) == 0x0000)
- return decode_ProgCtrl_0 (iw0);
- else if ((iw0 & 0xffc0) == 0x0240)
- abort ();
- else if ((iw0 & 0xff80) == 0x0100)
- abort ();
- else if ((iw0 & 0xfe00) == 0x0400)
- abort ();
- else if ((iw0 & 0xfe00) == 0x0600)
- abort ();
- else if ((iw0 & 0xf800) == 0x0800)
- abort ();
- else if ((iw0 & 0xffe0) == 0x0200)
- abort ();
- else if ((iw0 & 0xff00) == 0x0300)
- abort ();
- else if ((iw0 & 0xf000) == 0x1000)
- abort ();
- else if ((iw0 & 0xf000) == 0x2000)
- abort ();
- else if ((iw0 & 0xf000) == 0x3000)
- abort ();
- else if ((iw0 & 0xfc00) == 0x4000)
- abort ();
- else if ((iw0 & 0xfe00) == 0x4400)
- abort ();
- else if ((iw0 & 0xf800) == 0x4800)
- abort ();
- else if ((iw0 & 0xf000) == 0x5000)
- abort ();
- else if ((iw0 & 0xf800) == 0x6000)
- abort ();
- else if ((iw0 & 0xf800) == 0x6800)
- abort ();
- else if ((iw0 & 0xf000) == 0x8000)
- return decode_LDSTpmod_0 (iw0);
- else if ((iw0 & 0xff60) == 0x9e60)
- return decode_dagMODim_0 (iw0);
- else if ((iw0 & 0xfff0) == 0x9f60)
- return decode_dagMODik_0 (iw0);
- else if ((iw0 & 0xfc00) == 0x9c00)
- return decode_dspLDST_0 (iw0);
- else if ((iw0 & 0xf000) == 0x9000)
- return decode_LDST_0 (iw0);
- else if ((iw0 & 0xfc00) == 0xb800)
- return decode_LDSTiiFP_0 (iw0);
- else if ((iw0 & 0xe000) == 0xA000)
- return decode_LDSTii_0 (iw0);
- else if ((iw0 & 0xff80) == 0xe080 && (iw1 & 0x0C00) == 0x0000)
- abort ();
- else if ((iw0 & 0xff00) == 0xe100 && (iw1 & 0x0000) == 0x0000)
- abort ();
- else if ((iw0 & 0xfe00) == 0xe200 && (iw1 & 0x0000) == 0x0000)
- abort ();
- else if ((iw0 & 0xfc00) == 0xe400 && (iw1 & 0x0000) == 0x0000)
- abort ();
- else if ((iw0 & 0xfffe) == 0xe800 && (iw1 & 0x0000) == 0x0000)
- abort ();
- else if ((iw0 & 0xf600) == 0xc000 && (iw1 & 0x0000) == 0x0000)
- return decode_dsp32mac_0 (iw0, iw1);
- else if ((iw0 & 0xf600) == 0xc200 && (iw1 & 0x0000) == 0x0000)
- return decode_dsp32mult_0 (iw0, iw1);
- else if ((iw0 & 0xf7c0) == 0xc400 && (iw1 & 0x0000) == 0x0000)
- return decode_dsp32alu_0 (iw0, iw1);
- else if ((iw0 & 0xf780) == 0xc600 && (iw1 & 0x01c0) == 0x0000)
- return decode_dsp32shift_0 (iw0, iw1);
- else if ((iw0 & 0xf780) == 0xc680 && (iw1 & 0x0000) == 0x0000)
- return decode_dsp32shiftimm_0 (iw0, iw1);
- else if ((iw0 & 0xff00) == 0xf800)
- abort ();
- else if ((iw0 & 0xFFC0) == 0xf000 && (iw1 & 0x0000) == 0x0000)
- abort ();
-
- abort ();
-}