1/* tc-bfin.c -- Assembler for the ADI Blackfin.
2   Copyright 2005, 2006, 2007, 2008, 2009, 2010
3   Free Software Foundation, Inc.
4
5   This file is part of GAS, the GNU Assembler.
6
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)
10   any later version.
11
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.
16
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
20   02110-1301, USA.  */
21
22#include "as.h"
23#include "struc-symbol.h"
24#include "bfin-defs.h"
25#include "obstack.h"
26#include "safe-ctype.h"
27#ifdef OBJ_ELF
28#include "dwarf2dbg.h"
29#endif
30#include "libbfd.h"
31#include "elf/common.h"
32#include "elf/bfin.h"
33
34extern int yyparse (void);
35struct yy_buffer_state;
36typedef struct yy_buffer_state *YY_BUFFER_STATE;
37extern YY_BUFFER_STATE yy_scan_string (const char *yy_str);
38extern void yy_delete_buffer (YY_BUFFER_STATE b);
39static parse_state parse (char *line);
40
41/* Global variables. */
42struct bfin_insn *insn;
43int last_insn_size;
44
45extern struct obstack mempool;
46FILE *errorf;
47
48/* Flags to set in the elf header */
49#define DEFAULT_FLAGS 0
50
51#ifdef OBJ_FDPIC_ELF
52# define DEFAULT_FDPIC EF_BFIN_FDPIC
53#else
54# define DEFAULT_FDPIC 0
55#endif
56
57static flagword bfin_flags = DEFAULT_FLAGS | DEFAULT_FDPIC;
58static const char *bfin_pic_flag = DEFAULT_FDPIC ? "-mfdpic" : (const char *)0;
59
60/* Blackfin specific function to handle FD-PIC pointer initializations.  */
61
62static void
63bfin_pic_ptr (int nbytes)
64{
65  expressionS exp;
66  char *p;
67
68  if (nbytes != 4)
69    abort ();
70
71#ifdef md_flush_pending_output
72  md_flush_pending_output ();
73#endif
74
75  if (is_it_end_of_statement ())
76    {
77      demand_empty_rest_of_line ();
78      return;
79    }
80
81#ifdef md_cons_align
82  md_cons_align (nbytes);
83#endif
84
85  do
86    {
87      bfd_reloc_code_real_type reloc_type = BFD_RELOC_BFIN_FUNCDESC;
88
89      if (strncasecmp (input_line_pointer, "funcdesc(", 9) == 0)
90	{
91	  input_line_pointer += 9;
92	  expression (&exp);
93	  if (*input_line_pointer == ')')
94	    input_line_pointer++;
95	  else
96	    as_bad (_("missing ')'"));
97	}
98      else
99	error ("missing funcdesc in picptr");
100
101      p = frag_more (4);
102      memset (p, 0, 4);
103      fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
104		   reloc_type);
105    }
106  while (*input_line_pointer++ == ',');
107
108  input_line_pointer--;			/* Put terminator back into stream. */
109  demand_empty_rest_of_line ();
110}
111
112static void
113bfin_s_bss (int ignore ATTRIBUTE_UNUSED)
114{
115  register int temp;
116
117  temp = get_absolute_expression ();
118  subseg_set (bss_section, (subsegT) temp);
119  demand_empty_rest_of_line ();
120}
121
122const pseudo_typeS md_pseudo_table[] = {
123  {"align", s_align_bytes, 0},
124  {"byte2", cons, 2},
125  {"byte4", cons, 4},
126  {"picptr", bfin_pic_ptr, 4},
127  {"code", obj_elf_section, 0},
128  {"db", cons, 1},
129  {"dd", cons, 4},
130  {"dw", cons, 2},
131  {"p", s_ignore, 0},
132  {"pdata", s_ignore, 0},
133  {"var", s_ignore, 0},
134  {"bss", bfin_s_bss, 0},
135  {0, 0, 0}
136};
137
138/* Characters that are used to denote comments and line separators. */
139const char comment_chars[] = "#";
140const char line_comment_chars[] = "#";
141const char line_separator_chars[] = ";";
142
143/* Characters that can be used to separate the mantissa from the
144   exponent in floating point numbers. */
145const char EXP_CHARS[] = "eE";
146
147/* Characters that mean this number is a floating point constant.
148   As in 0f12.456 or  0d1.2345e12.  */
149const char FLT_CHARS[] = "fFdDxX";
150
151typedef enum bfin_cpu_type
152{
153  BFIN_CPU_UNKNOWN,
154  BFIN_CPU_BF504,
155  BFIN_CPU_BF506,
156  BFIN_CPU_BF512,
157  BFIN_CPU_BF514,
158  BFIN_CPU_BF516,
159  BFIN_CPU_BF518,
160  BFIN_CPU_BF522,
161  BFIN_CPU_BF523,
162  BFIN_CPU_BF524,
163  BFIN_CPU_BF525,
164  BFIN_CPU_BF526,
165  BFIN_CPU_BF527,
166  BFIN_CPU_BF531,
167  BFIN_CPU_BF532,
168  BFIN_CPU_BF533,
169  BFIN_CPU_BF534,
170  BFIN_CPU_BF536,
171  BFIN_CPU_BF537,
172  BFIN_CPU_BF538,
173  BFIN_CPU_BF539,
174  BFIN_CPU_BF542,
175  BFIN_CPU_BF542M,
176  BFIN_CPU_BF544,
177  BFIN_CPU_BF544M,
178  BFIN_CPU_BF547,
179  BFIN_CPU_BF547M,
180  BFIN_CPU_BF548,
181  BFIN_CPU_BF548M,
182  BFIN_CPU_BF549,
183  BFIN_CPU_BF549M,
184  BFIN_CPU_BF561,
185  BFIN_CPU_BF592,
186} bfin_cpu_t;
187
188bfin_cpu_t bfin_cpu_type = BFIN_CPU_UNKNOWN;
189/* -msi-revision support. There are three special values:
190   -1      -msi-revision=none.
191   0xffff  -msi-revision=any.  */
192int bfin_si_revision;
193
194unsigned int bfin_anomaly_checks = 0;
195
196struct bfin_cpu
197{
198  const char *name;
199  bfin_cpu_t type;
200  int si_revision;
201  unsigned int anomaly_checks;
202};
203
204struct bfin_cpu bfin_cpus[] =
205{
206  {"bf504", BFIN_CPU_BF504, 0x0000, AC_05000074},
207
208  {"bf506", BFIN_CPU_BF506, 0x0000, AC_05000074},
209
210  {"bf512", BFIN_CPU_BF512, 0x0002, AC_05000074},
211  {"bf512", BFIN_CPU_BF512, 0x0001, AC_05000074},
212  {"bf512", BFIN_CPU_BF512, 0x0000, AC_05000074},
213
214  {"bf514", BFIN_CPU_BF514, 0x0002, AC_05000074},
215  {"bf514", BFIN_CPU_BF514, 0x0001, AC_05000074},
216  {"bf514", BFIN_CPU_BF514, 0x0000, AC_05000074},
217
218  {"bf516", BFIN_CPU_BF516, 0x0002, AC_05000074},
219  {"bf516", BFIN_CPU_BF516, 0x0001, AC_05000074},
220  {"bf516", BFIN_CPU_BF516, 0x0000, AC_05000074},
221
222  {"bf518", BFIN_CPU_BF518, 0x0002, AC_05000074},
223  {"bf518", BFIN_CPU_BF518, 0x0001, AC_05000074},
224  {"bf518", BFIN_CPU_BF518, 0x0000, AC_05000074},
225
226  {"bf522", BFIN_CPU_BF522, 0x0002, AC_05000074},
227  {"bf522", BFIN_CPU_BF522, 0x0001, AC_05000074},
228  {"bf522", BFIN_CPU_BF522, 0x0000, AC_05000074},
229
230  {"bf523", BFIN_CPU_BF523, 0x0002, AC_05000074},
231  {"bf523", BFIN_CPU_BF523, 0x0001, AC_05000074},
232  {"bf523", BFIN_CPU_BF523, 0x0000, AC_05000074},
233
234  {"bf524", BFIN_CPU_BF524, 0x0002, AC_05000074},
235  {"bf524", BFIN_CPU_BF524, 0x0001, AC_05000074},
236  {"bf524", BFIN_CPU_BF524, 0x0000, AC_05000074},
237
238  {"bf525", BFIN_CPU_BF525, 0x0002, AC_05000074},
239  {"bf525", BFIN_CPU_BF525, 0x0001, AC_05000074},
240  {"bf525", BFIN_CPU_BF525, 0x0000, AC_05000074},
241
242  {"bf526", BFIN_CPU_BF526, 0x0002, AC_05000074},
243  {"bf526", BFIN_CPU_BF526, 0x0001, AC_05000074},
244  {"bf526", BFIN_CPU_BF526, 0x0000, AC_05000074},
245
246  {"bf527", BFIN_CPU_BF527, 0x0002, AC_05000074},
247  {"bf527", BFIN_CPU_BF527, 0x0001, AC_05000074},
248  {"bf527", BFIN_CPU_BF527, 0x0000, AC_05000074},
249
250  {"bf531", BFIN_CPU_BF531, 0x0006, AC_05000074},
251  {"bf531", BFIN_CPU_BF531, 0x0005, AC_05000074},
252  {"bf531", BFIN_CPU_BF531, 0x0004, AC_05000074},
253  {"bf531", BFIN_CPU_BF531, 0x0003, AC_05000074},
254
255  {"bf532", BFIN_CPU_BF532, 0x0006, AC_05000074},
256  {"bf532", BFIN_CPU_BF532, 0x0005, AC_05000074},
257  {"bf532", BFIN_CPU_BF532, 0x0004, AC_05000074},
258  {"bf532", BFIN_CPU_BF532, 0x0003, AC_05000074},
259
260  {"bf533", BFIN_CPU_BF533, 0x0006, AC_05000074},
261  {"bf533", BFIN_CPU_BF533, 0x0005, AC_05000074},
262  {"bf533", BFIN_CPU_BF533, 0x0004, AC_05000074},
263  {"bf533", BFIN_CPU_BF533, 0x0003, AC_05000074},
264
265  {"bf534", BFIN_CPU_BF534, 0x0003, AC_05000074},
266  {"bf534", BFIN_CPU_BF534, 0x0002, AC_05000074},
267  {"bf534", BFIN_CPU_BF534, 0x0001, AC_05000074},
268
269  {"bf536", BFIN_CPU_BF536, 0x0003, AC_05000074},
270  {"bf536", BFIN_CPU_BF536, 0x0002, AC_05000074},
271  {"bf536", BFIN_CPU_BF536, 0x0001, AC_05000074},
272
273  {"bf537", BFIN_CPU_BF537, 0x0003, AC_05000074},
274  {"bf537", BFIN_CPU_BF537, 0x0002, AC_05000074},
275  {"bf537", BFIN_CPU_BF537, 0x0001, AC_05000074},
276
277  {"bf538", BFIN_CPU_BF538, 0x0005, AC_05000074},
278  {"bf538", BFIN_CPU_BF538, 0x0004, AC_05000074},
279  {"bf538", BFIN_CPU_BF538, 0x0003, AC_05000074},
280  {"bf538", BFIN_CPU_BF538, 0x0002, AC_05000074},
281
282  {"bf539", BFIN_CPU_BF539, 0x0005, AC_05000074},
283  {"bf539", BFIN_CPU_BF539, 0x0004, AC_05000074},
284  {"bf539", BFIN_CPU_BF539, 0x0003, AC_05000074},
285  {"bf539", BFIN_CPU_BF539, 0x0002, AC_05000074},
286
287  {"bf542m", BFIN_CPU_BF542M, 0x0003, AC_05000074},
288
289  {"bf542", BFIN_CPU_BF542, 0x0002, AC_05000074},
290  {"bf542", BFIN_CPU_BF542, 0x0001, AC_05000074},
291  {"bf542", BFIN_CPU_BF542, 0x0000, AC_05000074},
292
293  {"bf544m", BFIN_CPU_BF544M, 0x0003, AC_05000074},
294
295  {"bf544", BFIN_CPU_BF544, 0x0002, AC_05000074},
296  {"bf544", BFIN_CPU_BF544, 0x0001, AC_05000074},
297  {"bf544", BFIN_CPU_BF544, 0x0000, AC_05000074},
298
299  {"bf547m", BFIN_CPU_BF547M, 0x0003, AC_05000074},
300
301  {"bf547", BFIN_CPU_BF547, 0x0002, AC_05000074},
302  {"bf547", BFIN_CPU_BF547, 0x0001, AC_05000074},
303  {"bf547", BFIN_CPU_BF547, 0x0000, AC_05000074},
304
305  {"bf548m", BFIN_CPU_BF548M, 0x0003, AC_05000074},
306
307  {"bf548", BFIN_CPU_BF548, 0x0002, AC_05000074},
308  {"bf548", BFIN_CPU_BF548, 0x0001, AC_05000074},
309  {"bf548", BFIN_CPU_BF548, 0x0000, AC_05000074},
310
311  {"bf549m", BFIN_CPU_BF549M, 0x0003, AC_05000074},
312
313  {"bf549", BFIN_CPU_BF549, 0x0002, AC_05000074},
314  {"bf549", BFIN_CPU_BF549, 0x0001, AC_05000074},
315  {"bf549", BFIN_CPU_BF549, 0x0000, AC_05000074},
316
317  {"bf561", BFIN_CPU_BF561, 0x0005, AC_05000074},
318  {"bf561", BFIN_CPU_BF561, 0x0003, AC_05000074},
319  {"bf561", BFIN_CPU_BF561, 0x0002, AC_05000074},
320
321  {"bf592", BFIN_CPU_BF592, 0x0001, AC_05000074},
322  {"bf592", BFIN_CPU_BF592, 0x0000, AC_05000074},
323
324  {NULL, 0, 0, 0}
325};
326
327/* Define bfin-specific command-line options (there are none). */
328const char *md_shortopts = "";
329
330#define OPTION_FDPIC		(OPTION_MD_BASE)
331#define OPTION_NOPIC		(OPTION_MD_BASE + 1)
332#define OPTION_MCPU		(OPTION_MD_BASE + 2)
333
334struct option md_longopts[] =
335{
336  { "mcpu",		required_argument,	NULL, OPTION_MCPU	},
337  { "mfdpic",		no_argument,		NULL, OPTION_FDPIC      },
338  { "mnopic",		no_argument,		NULL, OPTION_NOPIC      },
339  { "mno-fdpic",	no_argument,		NULL, OPTION_NOPIC      },
340  { NULL,		no_argument,		NULL, 0                 },
341};
342
343size_t md_longopts_size = sizeof (md_longopts);
344
345
346int
347md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
348{
349  switch (c)
350    {
351    default:
352      return 0;
353
354    case OPTION_MCPU:
355      {
356	const char *p, *q;
357	int i;
358
359	i = 0;
360	while ((p = bfin_cpus[i].name) != NULL)
361	  {
362	    if (strncmp (arg, p, strlen (p)) == 0)
363	      break;
364	    i++;
365	  }
366
367	if (p == NULL)
368	  as_fatal ("-mcpu=%s is not valid", arg);
369
370	bfin_cpu_type = bfin_cpus[i].type;
371
372	q = arg + strlen (p);
373
374	if (*q == '\0')
375	  {
376	    bfin_si_revision = bfin_cpus[i].si_revision;
377	    bfin_anomaly_checks |= bfin_cpus[i].anomaly_checks;
378	  }
379	else if (strcmp (q, "-none") == 0)
380	  bfin_si_revision = -1;
381      	else if (strcmp (q, "-any") == 0)
382	  {
383	    bfin_si_revision = 0xffff;
384	    while (bfin_cpus[i].type == bfin_cpu_type)
385	      {
386		bfin_anomaly_checks |= bfin_cpus[i].anomaly_checks;
387		i++;
388	      }
389	  }
390	else
391	  {
392	    unsigned int si_major, si_minor;
393	    int rev_len, n;
394
395	    rev_len = strlen (q);
396
397	    if (sscanf (q, "-%u.%u%n", &si_major, &si_minor, &n) != 2
398		|| n != rev_len
399		|| si_major > 0xff || si_minor > 0xff)
400	      {
401	      invalid_silicon_revision:
402		as_fatal ("-mcpu=%s has invalid silicon revision", arg);
403	      }
404
405	    bfin_si_revision = (si_major << 8) | si_minor;
406
407	    while (bfin_cpus[i].type == bfin_cpu_type
408		   && bfin_cpus[i].si_revision != bfin_si_revision)
409	      i++;
410
411	    if (bfin_cpus[i].type != bfin_cpu_type)
412	      goto invalid_silicon_revision;
413
414	    bfin_anomaly_checks |= bfin_cpus[i].anomaly_checks;
415	  }
416
417	break;
418      }
419
420    case OPTION_FDPIC:
421      bfin_flags |= EF_BFIN_FDPIC;
422      bfin_pic_flag = "-mfdpic";
423      break;
424
425    case OPTION_NOPIC:
426      bfin_flags &= ~(EF_BFIN_FDPIC);
427      bfin_pic_flag = 0;
428      break;
429    }
430
431  return 1;
432}
433
434void
435md_show_usage (FILE * stream)
436{
437  fprintf (stream, _(" Blackfin specific assembler options:\n"));
438  fprintf (stream, _("  -mcpu=<cpu[-sirevision]> specify the name of the target CPU\n"));
439  fprintf (stream, _("  -mfdpic                  assemble for the FDPIC ABI\n"));
440  fprintf (stream, _("  -mno-fdpic/-mnopic       disable -mfdpic\n"));
441}
442
443/* Perform machine-specific initializations.  */
444void
445md_begin ()
446{
447  /* Set the ELF flags if desired. */
448  if (bfin_flags)
449    bfd_set_private_flags (stdoutput, bfin_flags);
450
451  /* Set the default machine type. */
452  if (!bfd_set_arch_mach (stdoutput, bfd_arch_bfin, 0))
453    as_warn (_("Could not set architecture and machine."));
454
455  /* Ensure that lines can begin with '(', for multiple
456     register stack pops. */
457  lex_type ['('] = LEX_BEGIN_NAME;
458
459#ifdef OBJ_ELF
460  record_alignment (text_section, 2);
461  record_alignment (data_section, 2);
462  record_alignment (bss_section, 2);
463#endif
464
465  errorf = stderr;
466  obstack_init (&mempool);
467
468#ifdef DEBUG
469  extern int debug_codeselection;
470  debug_codeselection = 1;
471#endif
472
473  last_insn_size = 0;
474}
475
476/* Perform the main parsing, and assembly of the input here.  Also,
477   call the required routines for alignment and fixups here.
478   This is called for every line that contains real assembly code.  */
479
480void
481md_assemble (char *line)
482{
483  char *toP = 0;
484  extern char *current_inputline;
485  int size, insn_size;
486  struct bfin_insn *tmp_insn;
487  size_t len;
488  static size_t buffer_len = 0;
489  parse_state state;
490
491  len = strlen (line);
492  if (len + 2 > buffer_len)
493    {
494      if (buffer_len > 0)
495	free (current_inputline);
496      buffer_len = len + 40;
497      current_inputline = xmalloc (buffer_len);
498    }
499  memcpy (current_inputline, line, len);
500  current_inputline[len] = ';';
501  current_inputline[len + 1] = '\0';
502
503  state = parse (current_inputline);
504  if (state == NO_INSN_GENERATED)
505    return;
506
507  for (insn_size = 0, tmp_insn = insn; tmp_insn; tmp_insn = tmp_insn->next)
508    if (!tmp_insn->reloc || !tmp_insn->exp->symbol)
509      insn_size += 2;
510
511  if (insn_size)
512    toP = frag_more (insn_size);
513
514  last_insn_size = insn_size;
515
516#ifdef DEBUG
517  printf ("INS:");
518#endif
519  while (insn)
520    {
521      if (insn->reloc && insn->exp->symbol)
522	{
523	  char *prev_toP = toP - 2;
524	  switch (insn->reloc)
525	    {
526	    case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
527	    case BFD_RELOC_24_PCREL:
528	    case BFD_RELOC_BFIN_16_LOW:
529	    case BFD_RELOC_BFIN_16_HIGH:
530	      size = 4;
531	      break;
532	    default:
533	      size = 2;
534	    }
535
536	  /* Following if condition checks for the arithmetic relocations.
537	     If the case then it doesn't required to generate the code.
538	     It has been assumed that, their ID will be contiguous.  */
539	  if ((BFD_ARELOC_BFIN_PUSH <= insn->reloc
540               && BFD_ARELOC_BFIN_COMP >= insn->reloc)
541              || insn->reloc == BFD_RELOC_BFIN_16_IMM)
542	    {
543	      size = 2;
544	    }
545	  if (insn->reloc == BFD_ARELOC_BFIN_CONST
546              || insn->reloc == BFD_ARELOC_BFIN_PUSH)
547	    size = 4;
548
549	  fix_new (frag_now,
550                   (prev_toP - frag_now->fr_literal),
551		   size, insn->exp->symbol, insn->exp->value,
552                   insn->pcrel, insn->reloc);
553	}
554      else
555	{
556	  md_number_to_chars (toP, insn->value, 2);
557	  toP += 2;
558	}
559
560#ifdef DEBUG
561      printf (" reloc :");
562      printf (" %02x%02x", ((unsigned char *) &insn->value)[0],
563              ((unsigned char *) &insn->value)[1]);
564      printf ("\n");
565#endif
566      insn = insn->next;
567    }
568#ifdef OBJ_ELF
569  dwarf2_emit_insn (insn_size);
570#endif
571
572  while (*line++ != '\0')
573    if (*line == '\n')
574      bump_line_counters ();
575}
576
577/* Parse one line of instructions, and generate opcode for it.
578   To parse the line, YACC and LEX are used, because the instruction set
579   syntax doesn't confirm to the AT&T assembly syntax.
580   To call a YACC & LEX generated parser, we must provide the input via
581   a FILE stream, otherwise stdin is used by default.  Below the input
582   to the function will be put into a temporary file, then the generated
583   parser uses the temporary file for parsing.  */
584
585static parse_state
586parse (char *line)
587{
588  parse_state state;
589  YY_BUFFER_STATE buffstate;
590
591  buffstate = yy_scan_string (line);
592
593  /* our lex requires setting the start state to keyword
594     every line as the first word may be a keyword.
595     Fixes a bug where we could not have keywords as labels.  */
596  set_start_state ();
597
598  /* Call yyparse here.  */
599  state = yyparse ();
600  if (state == SEMANTIC_ERROR)
601    {
602      as_bad (_("Parse failed."));
603      insn = 0;
604    }
605
606  yy_delete_buffer (buffstate);
607  return state;
608}
609
610/* We need to handle various expressions properly.
611   Such as, [SP--] = 34, concerned by md_assemble().  */
612
613void
614md_operand (expressionS * expressionP)
615{
616  if (*input_line_pointer == '[')
617    {
618      as_tsktsk ("We found a '['!");
619      input_line_pointer++;
620      expression (expressionP);
621    }
622}
623
624/* Handle undefined symbols. */
625symbolS *
626md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
627{
628  return (symbolS *) 0;
629}
630
631int
632md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
633                               segT segment ATTRIBUTE_UNUSED)
634{
635  return 0;
636}
637
638/* Convert from target byte order to host byte order.  */
639
640static int
641md_chars_to_number (char *val, int n)
642{
643  int retval;
644
645  for (retval = 0; n--;)
646    {
647      retval <<= 8;
648      retval |= val[n];
649    }
650  return retval;
651}
652
653void
654md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
655{
656  char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
657
658  long value = *valueP;
659  long newval;
660
661  switch (fixP->fx_r_type)
662    {
663    case BFD_RELOC_BFIN_GOT:
664    case BFD_RELOC_BFIN_GOT17M4:
665    case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
666      fixP->fx_no_overflow = 1;
667      newval = md_chars_to_number (where, 2);
668      newval |= 0x0 & 0x7f;
669      md_number_to_chars (where, newval, 2);
670      break;
671
672    case BFD_RELOC_BFIN_10_PCREL:
673      if (!value)
674	break;
675      if (value < -1024 || value > 1022)
676	as_bad_where (fixP->fx_file, fixP->fx_line,
677                      _("pcrel too far BFD_RELOC_BFIN_10"));
678
679      /* 11 bit offset even numbered, so we remove right bit.  */
680      value = value >> 1;
681      newval = md_chars_to_number (where, 2);
682      newval |= value & 0x03ff;
683      md_number_to_chars (where, newval, 2);
684      break;
685
686    case BFD_RELOC_BFIN_12_PCREL_JUMP:
687    case BFD_RELOC_BFIN_12_PCREL_JUMP_S:
688    case BFD_RELOC_12_PCREL:
689      if (!value)
690	break;
691
692      if (value < -4096 || value > 4094)
693	as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_12"));
694      /* 13 bit offset even numbered, so we remove right bit.  */
695      value = value >> 1;
696      newval = md_chars_to_number (where, 2);
697      newval |= value & 0xfff;
698      md_number_to_chars (where, newval, 2);
699      break;
700
701    case BFD_RELOC_BFIN_16_LOW:
702    case BFD_RELOC_BFIN_16_HIGH:
703      fixP->fx_done = FALSE;
704      break;
705
706    case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
707    case BFD_RELOC_BFIN_24_PCREL_CALL_X:
708    case BFD_RELOC_24_PCREL:
709      if (!value)
710	break;
711
712      if (value < -16777216 || value > 16777214)
713	as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_24"));
714
715      /* 25 bit offset even numbered, so we remove right bit.  */
716      value = value >> 1;
717      value++;
718
719      md_number_to_chars (where - 2, value >> 16, 1);
720      md_number_to_chars (where, value, 1);
721      md_number_to_chars (where + 1, value >> 8, 1);
722      break;
723
724    case BFD_RELOC_BFIN_5_PCREL:	/* LSETUP (a, b) : "a" */
725      if (!value)
726	break;
727      if (value < 4 || value > 30)
728	as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_5"));
729      value = value >> 1;
730      newval = md_chars_to_number (where, 1);
731      newval = (newval & 0xf0) | (value & 0xf);
732      md_number_to_chars (where, newval, 1);
733      break;
734
735    case BFD_RELOC_BFIN_11_PCREL:	/* LSETUP (a, b) : "b" */
736      if (!value)
737	break;
738      value += 2;
739      if (value < 4 || value > 2046)
740	as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_11_PCREL"));
741      /* 11 bit unsigned even, so we remove right bit.  */
742      value = value >> 1;
743      newval = md_chars_to_number (where, 2);
744      newval |= value & 0x03ff;
745      md_number_to_chars (where, newval, 2);
746      break;
747
748    case BFD_RELOC_8:
749      if (value < -0x80 || value >= 0x7f)
750	as_bad_where (fixP->fx_file, fixP->fx_line, _("rel too far BFD_RELOC_8"));
751      md_number_to_chars (where, value, 1);
752      break;
753
754    case BFD_RELOC_BFIN_16_IMM:
755    case BFD_RELOC_16:
756      if (value < -0x8000 || value >= 0x7fff)
757	as_bad_where (fixP->fx_file, fixP->fx_line, _("rel too far BFD_RELOC_16"));
758      md_number_to_chars (where, value, 2);
759      break;
760
761    case BFD_RELOC_32:
762      md_number_to_chars (where, value, 4);
763      break;
764
765    case BFD_RELOC_BFIN_PLTPC:
766      md_number_to_chars (where, value, 2);
767      break;
768
769    case BFD_RELOC_BFIN_FUNCDESC:
770    case BFD_RELOC_VTABLE_INHERIT:
771    case BFD_RELOC_VTABLE_ENTRY:
772      fixP->fx_done = FALSE;
773      break;
774
775    default:
776      if ((BFD_ARELOC_BFIN_PUSH > fixP->fx_r_type) || (BFD_ARELOC_BFIN_COMP < fixP->fx_r_type))
777	{
778	  fprintf (stderr, "Relocation %d not handled in gas." " Contact support.\n", fixP->fx_r_type);
779	  return;
780	}
781    }
782
783  if (!fixP->fx_addsy)
784    fixP->fx_done = TRUE;
785
786}
787
788/* Round up a section size to the appropriate boundary.  */
789valueT
790md_section_align (segment, size)
791     segT segment;
792     valueT size;
793{
794  int boundary = bfd_get_section_alignment (stdoutput, segment);
795  return ((size + (1 << boundary) - 1) & (-1 << boundary));
796}
797
798
799char *
800md_atof (int type, char * litP, int * sizeP)
801{
802  return ieee_md_atof (type, litP, sizeP, FALSE);
803}
804
805
806/* If while processing a fixup, a reloc really needs to be created
807   then it is done here.  */
808
809arelent *
810tc_gen_reloc (seg, fixp)
811     asection *seg ATTRIBUTE_UNUSED;
812     fixS *fixp;
813{
814  arelent *reloc;
815
816  reloc		      = (arelent *) xmalloc (sizeof (arelent));
817  reloc->sym_ptr_ptr  = (asymbol **) xmalloc (sizeof (asymbol *));
818  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
819  reloc->address      = fixp->fx_frag->fr_address + fixp->fx_where;
820
821  reloc->addend = fixp->fx_offset;
822  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
823
824  if (reloc->howto == (reloc_howto_type *) NULL)
825    {
826      as_bad_where (fixp->fx_file, fixp->fx_line,
827		    /* xgettext:c-format.  */
828		    _("reloc %d not supported by object file format"),
829		    (int) fixp->fx_r_type);
830
831      xfree (reloc);
832
833      return NULL;
834    }
835
836  return reloc;
837}
838
839/*  The location from which a PC relative jump should be calculated,
840    given a PC relative reloc.  */
841
842long
843md_pcrel_from_section (fixP, sec)
844     fixS *fixP;
845     segT sec;
846{
847  if (fixP->fx_addsy != (symbolS *) NULL
848      && (!S_IS_DEFINED (fixP->fx_addsy)
849      || S_GET_SEGMENT (fixP->fx_addsy) != sec))
850    {
851      /* The symbol is undefined (or is defined but not in this section).
852         Let the linker figure it out.  */
853      return 0;
854    }
855  return fixP->fx_frag->fr_address + fixP->fx_where;
856}
857
858/* Return true if the fix can be handled by GAS, false if it must
859   be passed through to the linker.  */
860
861bfd_boolean
862bfin_fix_adjustable (fixS *fixP)
863{
864  switch (fixP->fx_r_type)
865    {
866  /* Adjust_reloc_syms doesn't know about the GOT.  */
867    case BFD_RELOC_BFIN_GOT:
868    case BFD_RELOC_BFIN_PLTPC:
869  /* We need the symbol name for the VTABLE entries.  */
870    case BFD_RELOC_VTABLE_INHERIT:
871    case BFD_RELOC_VTABLE_ENTRY:
872      return 0;
873
874    default:
875      return 1;
876    }
877}
878
879/* Special extra functions that help bfin-parse.y perform its job.  */
880
881struct obstack mempool;
882
883INSTR_T
884conscode (INSTR_T head, INSTR_T tail)
885{
886  if (!head)
887    return tail;
888  head->next = tail;
889  return head;
890}
891
892INSTR_T
893conctcode (INSTR_T head, INSTR_T tail)
894{
895  INSTR_T temp = (head);
896  if (!head)
897    return tail;
898  while (temp->next)
899    temp = temp->next;
900  temp->next = tail;
901
902  return head;
903}
904
905INSTR_T
906note_reloc (INSTR_T code, Expr_Node * symbol, int reloc, int pcrel)
907{
908  /* Assert that the symbol is not an operator.  */
909  gas_assert (symbol->type == Expr_Node_Reloc);
910
911  return note_reloc1 (code, symbol->value.s_value, reloc, pcrel);
912
913}
914
915INSTR_T
916note_reloc1 (INSTR_T code, const char *symbol, int reloc, int pcrel)
917{
918  code->reloc = reloc;
919  code->exp = mkexpr (0, symbol_find_or_make (symbol));
920  code->pcrel = pcrel;
921  return code;
922}
923
924INSTR_T
925note_reloc2 (INSTR_T code, const char *symbol, int reloc, int value, int pcrel)
926{
927  code->reloc = reloc;
928  code->exp = mkexpr (value, symbol_find_or_make (symbol));
929  code->pcrel = pcrel;
930  return code;
931}
932
933INSTR_T
934gencode (unsigned long x)
935{
936  INSTR_T cell = obstack_alloc (&mempool, sizeof (struct bfin_insn));
937  memset (cell, 0, sizeof (struct bfin_insn));
938  cell->value = (x);
939  return cell;
940}
941
942int reloc;
943int ninsns;
944int count_insns;
945
946static void *
947allocate (int n)
948{
949  return obstack_alloc (&mempool, n);
950}
951
952Expr_Node *
953Expr_Node_Create (Expr_Node_Type type,
954	          Expr_Node_Value value,
955                  Expr_Node *Left_Child,
956                  Expr_Node *Right_Child)
957{
958
959
960  Expr_Node *node = (Expr_Node *) allocate (sizeof (Expr_Node));
961  node->type = type;
962  node->value = value;
963  node->Left_Child = Left_Child;
964  node->Right_Child = Right_Child;
965  return node;
966}
967
968static const char *con = ".__constant";
969static const char *op = ".__operator";
970static INSTR_T Expr_Node_Gen_Reloc_R (Expr_Node * head);
971INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc);
972
973INSTR_T
974Expr_Node_Gen_Reloc (Expr_Node * head, int parent_reloc)
975{
976  /* Top level reloction expression generator VDSP style.
977   If the relocation is just by itself, generate one item
978   else generate this convoluted expression.  */
979
980  INSTR_T note = NULL_CODE;
981  INSTR_T note1 = NULL_CODE;
982  int pcrel = 1;  /* Is the parent reloc pcrelative?
983		  This calculation here and HOWTO should match.  */
984
985  if (parent_reloc)
986    {
987      /*  If it's 32 bit quantity then 16bit code needs to be added.  */
988      int value = 0;
989
990      if (head->type == Expr_Node_Constant)
991	{
992	  /* If note1 is not null code, we have to generate a right
993             aligned value for the constant. Otherwise the reloc is
994             a part of the basic command and the yacc file
995             generates this.  */
996	  value = head->value.i_value;
997	}
998      switch (parent_reloc)
999	{
1000	  /*  Some relocations will need to allocate extra words.  */
1001	case BFD_RELOC_BFIN_16_IMM:
1002	case BFD_RELOC_BFIN_16_LOW:
1003	case BFD_RELOC_BFIN_16_HIGH:
1004	  note1 = conscode (gencode (value), NULL_CODE);
1005	  pcrel = 0;
1006	  break;
1007	case BFD_RELOC_BFIN_PLTPC:
1008	  note1 = conscode (gencode (value), NULL_CODE);
1009	  pcrel = 0;
1010	  break;
1011	case BFD_RELOC_16:
1012	case BFD_RELOC_BFIN_GOT:
1013	case BFD_RELOC_BFIN_GOT17M4:
1014	case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
1015	  note1 = conscode (gencode (value), NULL_CODE);
1016	  pcrel = 0;
1017	  break;
1018	case BFD_RELOC_24_PCREL:
1019	case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
1020	case BFD_RELOC_BFIN_24_PCREL_CALL_X:
1021	  /* These offsets are even numbered pcrel.  */
1022	  note1 = conscode (gencode (value >> 1), NULL_CODE);
1023	  break;
1024	default:
1025	  note1 = NULL_CODE;
1026	}
1027    }
1028  if (head->type == Expr_Node_Constant)
1029    note = note1;
1030  else if (head->type == Expr_Node_Reloc)
1031    {
1032      note = note_reloc1 (gencode (0), head->value.s_value, parent_reloc, pcrel);
1033      if (note1 != NULL_CODE)
1034	note = conscode (note1, note);
1035    }
1036  else if (head->type == Expr_Node_Binop
1037	   && (head->value.op_value == Expr_Op_Type_Add
1038	       || head->value.op_value == Expr_Op_Type_Sub)
1039	   && head->Left_Child->type == Expr_Node_Reloc
1040	   && head->Right_Child->type == Expr_Node_Constant)
1041    {
1042      int val = head->Right_Child->value.i_value;
1043      if (head->value.op_value == Expr_Op_Type_Sub)
1044	val = -val;
1045      note = conscode (note_reloc2 (gencode (0), head->Left_Child->value.s_value,
1046				    parent_reloc, val, 0),
1047		       NULL_CODE);
1048      if (note1 != NULL_CODE)
1049	note = conscode (note1, note);
1050    }
1051  else
1052    {
1053      /* Call the recursive function.  */
1054      note = note_reloc1 (gencode (0), op, parent_reloc, pcrel);
1055      if (note1 != NULL_CODE)
1056	note = conscode (note1, note);
1057      note = conctcode (Expr_Node_Gen_Reloc_R (head), note);
1058    }
1059  return note;
1060}
1061
1062static INSTR_T
1063Expr_Node_Gen_Reloc_R (Expr_Node * head)
1064{
1065
1066  INSTR_T note = 0;
1067  INSTR_T note1 = 0;
1068
1069  switch (head->type)
1070    {
1071    case Expr_Node_Constant:
1072      note = conscode (note_reloc2 (gencode (0), con, BFD_ARELOC_BFIN_CONST, head->value.i_value, 0), NULL_CODE);
1073      break;
1074    case Expr_Node_Reloc:
1075      note = conscode (note_reloc (gencode (0), head, BFD_ARELOC_BFIN_PUSH, 0), NULL_CODE);
1076      break;
1077    case Expr_Node_Binop:
1078      note1 = conctcode (Expr_Node_Gen_Reloc_R (head->Left_Child), Expr_Node_Gen_Reloc_R (head->Right_Child));
1079      switch (head->value.op_value)
1080	{
1081	case Expr_Op_Type_Add:
1082	  note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_ADD, 0), NULL_CODE));
1083	  break;
1084	case Expr_Op_Type_Sub:
1085	  note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_SUB, 0), NULL_CODE));
1086	  break;
1087	case Expr_Op_Type_Mult:
1088	  note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MULT, 0), NULL_CODE));
1089	  break;
1090	case Expr_Op_Type_Div:
1091	  note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_DIV, 0), NULL_CODE));
1092	  break;
1093	case Expr_Op_Type_Mod:
1094	  note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MOD, 0), NULL_CODE));
1095	  break;
1096	case Expr_Op_Type_Lshift:
1097	  note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LSHIFT, 0), NULL_CODE));
1098	  break;
1099	case Expr_Op_Type_Rshift:
1100	  note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_RSHIFT, 0), NULL_CODE));
1101	  break;
1102	case Expr_Op_Type_BAND:
1103	  note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_AND, 0), NULL_CODE));
1104	  break;
1105	case Expr_Op_Type_BOR:
1106	  note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_OR, 0), NULL_CODE));
1107	  break;
1108	case Expr_Op_Type_BXOR:
1109	  note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_XOR, 0), NULL_CODE));
1110	  break;
1111	case Expr_Op_Type_LAND:
1112	  note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LAND, 0), NULL_CODE));
1113	  break;
1114	case Expr_Op_Type_LOR:
1115	  note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LOR, 0), NULL_CODE));
1116	  break;
1117	default:
1118	  fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
1119
1120
1121	}
1122      break;
1123    case Expr_Node_Unop:
1124      note1 = conscode (Expr_Node_Gen_Reloc_R (head->Left_Child), NULL_CODE);
1125      switch (head->value.op_value)
1126	{
1127	case Expr_Op_Type_NEG:
1128	  note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_NEG, 0), NULL_CODE));
1129	  break;
1130	case Expr_Op_Type_COMP:
1131	  note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_COMP, 0), NULL_CODE));
1132	  break;
1133	default:
1134	  fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
1135	}
1136      break;
1137    default:
1138      fprintf (stderr, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__, __LINE__);
1139    }
1140  return note;
1141}
1142
1143/* Blackfin opcode generation.  */
1144
1145/* These functions are called by the generated parser
1146   (from bfin-parse.y), the register type classification
1147   happens in bfin-lex.l.  */
1148
1149#include "bfin-aux.h"
1150#include "opcode/bfin.h"
1151
1152#define INIT(t)  t c_code = init_##t
1153#define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1154#define ASSIGNF(x,f) c_code.opcode |= ((x & c_code.mask_##f)<<c_code.bits_##f)
1155#define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1156
1157#define HI(x) ((x >> 16) & 0xffff)
1158#define LO(x) ((x      ) & 0xffff)
1159
1160#define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1161
1162#define GEN_OPCODE32()  \
1163	conscode (gencode (HI (c_code.opcode)), \
1164	conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1165
1166#define GEN_OPCODE16()  \
1167	conscode (gencode (c_code.opcode), NULL_CODE)
1168
1169
1170/*  32 BIT INSTRUCTIONS.  */
1171
1172
1173/* DSP32 instruction generation.  */
1174
1175INSTR_T
1176bfin_gen_dsp32mac (int op1, int MM, int mmod, int w1, int P,
1177	           int h01, int h11, int h00, int h10, int op0,
1178                   REG_T dst, REG_T src0, REG_T src1, int w0)
1179{
1180  INIT (DSP32Mac);
1181
1182  ASSIGN (op0);
1183  ASSIGN (op1);
1184  ASSIGN (MM);
1185  ASSIGN (mmod);
1186  ASSIGN (w0);
1187  ASSIGN (w1);
1188  ASSIGN (h01);
1189  ASSIGN (h11);
1190  ASSIGN (h00);
1191  ASSIGN (h10);
1192  ASSIGN (P);
1193
1194  /* If we have full reg assignments, mask out LSB to encode
1195  single or simultaneous even/odd register moves.  */
1196  if (P)
1197    {
1198      dst->regno &= 0x06;
1199    }
1200
1201  ASSIGN_R (dst);
1202  ASSIGN_R (src0);
1203  ASSIGN_R (src1);
1204
1205  return GEN_OPCODE32 ();
1206}
1207
1208INSTR_T
1209bfin_gen_dsp32mult (int op1, int MM, int mmod, int w1, int P,
1210	            int h01, int h11, int h00, int h10, int op0,
1211                    REG_T dst, REG_T src0, REG_T src1, int w0)
1212{
1213  INIT (DSP32Mult);
1214
1215  ASSIGN (op0);
1216  ASSIGN (op1);
1217  ASSIGN (MM);
1218  ASSIGN (mmod);
1219  ASSIGN (w0);
1220  ASSIGN (w1);
1221  ASSIGN (h01);
1222  ASSIGN (h11);
1223  ASSIGN (h00);
1224  ASSIGN (h10);
1225  ASSIGN (P);
1226
1227  if (P)
1228    {
1229      dst->regno &= 0x06;
1230    }
1231
1232  ASSIGN_R (dst);
1233  ASSIGN_R (src0);
1234  ASSIGN_R (src1);
1235
1236  return GEN_OPCODE32 ();
1237}
1238
1239INSTR_T
1240bfin_gen_dsp32alu (int HL, int aopcde, int aop, int s, int x,
1241              REG_T dst0, REG_T dst1, REG_T src0, REG_T src1)
1242{
1243  INIT (DSP32Alu);
1244
1245  ASSIGN (HL);
1246  ASSIGN (aopcde);
1247  ASSIGN (aop);
1248  ASSIGN (s);
1249  ASSIGN (x);
1250  ASSIGN_R (dst0);
1251  ASSIGN_R (dst1);
1252  ASSIGN_R (src0);
1253  ASSIGN_R (src1);
1254
1255  return GEN_OPCODE32 ();
1256}
1257
1258INSTR_T
1259bfin_gen_dsp32shift (int sopcde, REG_T dst0, REG_T src0,
1260                REG_T src1, int sop, int HLs)
1261{
1262  INIT (DSP32Shift);
1263
1264  ASSIGN (sopcde);
1265  ASSIGN (sop);
1266  ASSIGN (HLs);
1267
1268  ASSIGN_R (dst0);
1269  ASSIGN_R (src0);
1270  ASSIGN_R (src1);
1271
1272  return GEN_OPCODE32 ();
1273}
1274
1275INSTR_T
1276bfin_gen_dsp32shiftimm (int sopcde, REG_T dst0, int immag,
1277                   REG_T src1, int sop, int HLs)
1278{
1279  INIT (DSP32ShiftImm);
1280
1281  ASSIGN (sopcde);
1282  ASSIGN (sop);
1283  ASSIGN (HLs);
1284
1285  ASSIGN_R (dst0);
1286  ASSIGN (immag);
1287  ASSIGN_R (src1);
1288
1289  return GEN_OPCODE32 ();
1290}
1291
1292/* LOOP SETUP.  */
1293
1294INSTR_T
1295bfin_gen_loopsetup (Expr_Node * psoffset, REG_T c, int rop,
1296               Expr_Node * peoffset, REG_T reg)
1297{
1298  int soffset, eoffset;
1299  INIT (LoopSetup);
1300
1301  soffset = (EXPR_VALUE (psoffset) >> 1);
1302  ASSIGN (soffset);
1303  eoffset = (EXPR_VALUE (peoffset) >> 1);
1304  ASSIGN (eoffset);
1305  ASSIGN (rop);
1306  ASSIGN_R (c);
1307  ASSIGN_R (reg);
1308
1309  return
1310      conscode (gencode (HI (c_code.opcode)),
1311		conctcode (Expr_Node_Gen_Reloc (psoffset, BFD_RELOC_BFIN_5_PCREL),
1312			   conctcode (gencode (LO (c_code.opcode)), Expr_Node_Gen_Reloc (peoffset, BFD_RELOC_BFIN_11_PCREL))));
1313
1314}
1315
1316/*  Call, Link.  */
1317
1318INSTR_T
1319bfin_gen_calla (Expr_Node * addr, int S)
1320{
1321  int val;
1322  int high_val;
1323  int rel = 0;
1324  INIT (CALLa);
1325
1326  switch(S){
1327   case 0 : rel = BFD_RELOC_BFIN_24_PCREL_JUMP_L; break;
1328   case 1 : rel = BFD_RELOC_24_PCREL; break;
1329   case 2 : rel = BFD_RELOC_BFIN_PLTPC; break;
1330   default : break;
1331  }
1332
1333  ASSIGN (S);
1334
1335  val = EXPR_VALUE (addr) >> 1;
1336  high_val = val >> 16;
1337
1338  return conscode (gencode (HI (c_code.opcode) | (high_val & 0xff)),
1339                     Expr_Node_Gen_Reloc (addr, rel));
1340  }
1341
1342INSTR_T
1343bfin_gen_linkage (int R, int framesize)
1344{
1345  INIT (Linkage);
1346
1347  ASSIGN (R);
1348  ASSIGN (framesize);
1349
1350  return GEN_OPCODE32 ();
1351}
1352
1353
1354/* Load and Store.  */
1355
1356INSTR_T
1357bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int rel)
1358{
1359  int grp, hword;
1360  unsigned val = EXPR_VALUE (phword);
1361  INIT (LDIMMhalf);
1362
1363  ASSIGN (H);
1364  ASSIGN (S);
1365  ASSIGN (Z);
1366
1367  ASSIGN_R (reg);
1368  grp = (GROUP (reg));
1369  ASSIGN (grp);
1370  if (rel == 2)
1371    {
1372      return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, BFD_RELOC_BFIN_16_IMM));
1373    }
1374  else if (rel == 1)
1375    {
1376      return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, IS_H (*reg) ? BFD_RELOC_BFIN_16_HIGH : BFD_RELOC_BFIN_16_LOW));
1377    }
1378  else
1379    {
1380      hword = val;
1381      ASSIGN (hword);
1382    }
1383  return GEN_OPCODE32 ();
1384}
1385
1386INSTR_T
1387bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset)
1388{
1389  INIT (LDSTidxI);
1390
1391  if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1392    {
1393      fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1394      return 0;
1395    }
1396
1397  ASSIGN_R (ptr);
1398  ASSIGN_R (reg);
1399  ASSIGN (W);
1400  ASSIGN (sz);
1401
1402  ASSIGN (Z);
1403
1404  if (poffset->type != Expr_Node_Constant)
1405    {
1406      /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1407      /* distinguish between R0 = [P5 + symbol@GOT] and
1408	 P5 = [P5 + _current_shared_library_p5_offset_]
1409      */
1410      if (poffset->type == Expr_Node_Reloc
1411	  && !strcmp (poffset->value.s_value,
1412		      "_current_shared_library_p5_offset_"))
1413	{
1414	  return  conscode (gencode (HI (c_code.opcode)),
1415			    Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16));
1416	}
1417      else if (poffset->type != Expr_Node_GOT_Reloc)
1418	abort ();
1419
1420      return conscode (gencode (HI (c_code.opcode)),
1421		       Expr_Node_Gen_Reloc(poffset->Left_Child,
1422					   poffset->value.i_value));
1423    }
1424  else
1425    {
1426      int value, offset;
1427      switch (sz)
1428	{				/* load/store access size */
1429	case 0:			/* 32 bit */
1430	  value = EXPR_VALUE (poffset) >> 2;
1431	  break;
1432	case 1:			/* 16 bit */
1433	  value = EXPR_VALUE (poffset) >> 1;
1434	  break;
1435	case 2:			/* 8 bit */
1436	  value = EXPR_VALUE (poffset);
1437	  break;
1438	default:
1439	  abort ();
1440	}
1441
1442      offset = (value & 0xffff);
1443      ASSIGN (offset);
1444      return GEN_OPCODE32 ();
1445    }
1446}
1447
1448
1449INSTR_T
1450bfin_gen_ldst (REG_T ptr, REG_T reg, int aop, int sz, int Z, int W)
1451{
1452  INIT (LDST);
1453
1454  if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1455    {
1456      fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1457      return 0;
1458    }
1459
1460  ASSIGN_R (ptr);
1461  ASSIGN_R (reg);
1462  ASSIGN (aop);
1463  ASSIGN (sz);
1464  ASSIGN (Z);
1465  ASSIGN (W);
1466
1467  return GEN_OPCODE16 ();
1468}
1469
1470INSTR_T
1471bfin_gen_ldstii (REG_T ptr, REG_T reg, Expr_Node * poffset, int W, int opc)
1472{
1473  int offset;
1474  int value = 0;
1475  INIT (LDSTii);
1476
1477  if (!IS_PREG (*ptr))
1478    {
1479      fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1480      return 0;
1481    }
1482
1483  switch (opc)
1484    {
1485    case 1:
1486    case 2:
1487      value = EXPR_VALUE (poffset) >> 1;
1488      break;
1489    case 0:
1490    case 3:
1491      value = EXPR_VALUE (poffset) >> 2;
1492      break;
1493    }
1494
1495  ASSIGN_R (ptr);
1496  ASSIGN_R (reg);
1497
1498  offset = value;
1499  ASSIGN (offset);
1500  ASSIGN (W);
1501  ASSIGNF (opc, op);
1502
1503  return GEN_OPCODE16 ();
1504}
1505
1506INSTR_T
1507bfin_gen_ldstiifp (REG_T sreg, Expr_Node * poffset, int W)
1508{
1509  /* Set bit 4 if it's a Preg.  */
1510  int reg = (sreg->regno & CODE_MASK) | (IS_PREG (*sreg) ? 0x8 : 0x0);
1511  int offset = ((~(EXPR_VALUE (poffset) >> 2)) & 0x1f) + 1;
1512  INIT (LDSTiiFP);
1513  ASSIGN (reg);
1514  ASSIGN (offset);
1515  ASSIGN (W);
1516
1517  return GEN_OPCODE16 ();
1518}
1519
1520INSTR_T
1521bfin_gen_ldstpmod (REG_T ptr, REG_T reg, int aop, int W, REG_T idx)
1522{
1523  INIT (LDSTpmod);
1524
1525  ASSIGN_R (ptr);
1526  ASSIGN_R (reg);
1527  ASSIGN (aop);
1528  ASSIGN (W);
1529  ASSIGN_R (idx);
1530
1531  return GEN_OPCODE16 ();
1532}
1533
1534INSTR_T
1535bfin_gen_dspldst (REG_T i, REG_T reg, int aop, int W, int m)
1536{
1537  INIT (DspLDST);
1538
1539  ASSIGN_R (i);
1540  ASSIGN_R (reg);
1541  ASSIGN (aop);
1542  ASSIGN (W);
1543  ASSIGN (m);
1544
1545  return GEN_OPCODE16 ();
1546}
1547
1548INSTR_T
1549bfin_gen_logi2op (int opc, int src, int dst)
1550{
1551  INIT (LOGI2op);
1552
1553  ASSIGN (opc);
1554  ASSIGN (src);
1555  ASSIGN (dst);
1556
1557  return GEN_OPCODE16 ();
1558}
1559
1560INSTR_T
1561bfin_gen_brcc (int T, int B, Expr_Node * poffset)
1562{
1563  int offset;
1564  INIT (BRCC);
1565
1566  ASSIGN (T);
1567  ASSIGN (B);
1568  offset = ((EXPR_VALUE (poffset) >> 1));
1569  ASSIGN (offset);
1570  return conscode (gencode (c_code.opcode), Expr_Node_Gen_Reloc (poffset, BFD_RELOC_BFIN_10_PCREL));
1571}
1572
1573INSTR_T
1574bfin_gen_ujump (Expr_Node * poffset)
1575{
1576  int offset;
1577  INIT (UJump);
1578
1579  offset = ((EXPR_VALUE (poffset) >> 1));
1580  ASSIGN (offset);
1581
1582  return conscode (gencode (c_code.opcode),
1583                   Expr_Node_Gen_Reloc (
1584                       poffset, BFD_RELOC_BFIN_12_PCREL_JUMP_S));
1585}
1586
1587INSTR_T
1588bfin_gen_alu2op (REG_T dst, REG_T src, int opc)
1589{
1590  INIT (ALU2op);
1591
1592  ASSIGN_R (dst);
1593  ASSIGN_R (src);
1594  ASSIGN (opc);
1595
1596  return GEN_OPCODE16 ();
1597}
1598
1599INSTR_T
1600bfin_gen_compi2opd (REG_T dst, int src, int opc)
1601{
1602  INIT (COMPI2opD);
1603
1604  ASSIGN_R (dst);
1605  ASSIGN (src);
1606  ASSIGNF (opc, op);
1607
1608  return GEN_OPCODE16 ();
1609}
1610
1611INSTR_T
1612bfin_gen_compi2opp (REG_T dst, int src, int opc)
1613{
1614  INIT (COMPI2opP);
1615
1616  ASSIGN_R (dst);
1617  ASSIGN (src);
1618  ASSIGNF (opc, op);
1619
1620  return GEN_OPCODE16 ();
1621}
1622
1623INSTR_T
1624bfin_gen_dagmodik (REG_T i, int opc)
1625{
1626  INIT (DagMODik);
1627
1628  ASSIGN_R (i);
1629  ASSIGNF (opc, op);
1630
1631  return GEN_OPCODE16 ();
1632}
1633
1634INSTR_T
1635bfin_gen_dagmodim (REG_T i, REG_T m, int opc, int br)
1636{
1637  INIT (DagMODim);
1638
1639  ASSIGN_R (i);
1640  ASSIGN_R (m);
1641  ASSIGNF (opc, op);
1642  ASSIGN (br);
1643
1644  return GEN_OPCODE16 ();
1645}
1646
1647INSTR_T
1648bfin_gen_ptr2op (REG_T dst, REG_T src, int opc)
1649{
1650  INIT (PTR2op);
1651
1652  ASSIGN_R (dst);
1653  ASSIGN_R (src);
1654  ASSIGN (opc);
1655
1656  return GEN_OPCODE16 ();
1657}
1658
1659INSTR_T
1660bfin_gen_comp3op (REG_T src0, REG_T src1, REG_T dst, int opc)
1661{
1662  INIT (COMP3op);
1663
1664  ASSIGN_R (src0);
1665  ASSIGN_R (src1);
1666  ASSIGN_R (dst);
1667  ASSIGN (opc);
1668
1669  return GEN_OPCODE16 ();
1670}
1671
1672INSTR_T
1673bfin_gen_ccflag (REG_T x, int y, int opc, int I, int G)
1674{
1675  INIT (CCflag);
1676
1677  ASSIGN_R (x);
1678  ASSIGN (y);
1679  ASSIGN (opc);
1680  ASSIGN (I);
1681  ASSIGN (G);
1682
1683  return GEN_OPCODE16 ();
1684}
1685
1686INSTR_T
1687bfin_gen_ccmv (REG_T src, REG_T dst, int T)
1688{
1689  int s, d;
1690  INIT (CCmv);
1691
1692  ASSIGN_R (src);
1693  ASSIGN_R (dst);
1694  s = (GROUP (src));
1695  ASSIGN (s);
1696  d = (GROUP (dst));
1697  ASSIGN (d);
1698  ASSIGN (T);
1699
1700  return GEN_OPCODE16 ();
1701}
1702
1703INSTR_T
1704bfin_gen_cc2stat (int cbit, int opc, int D)
1705{
1706  INIT (CC2stat);
1707
1708  ASSIGN (cbit);
1709  ASSIGNF (opc, op);
1710  ASSIGN (D);
1711
1712  return GEN_OPCODE16 ();
1713}
1714
1715INSTR_T
1716bfin_gen_regmv (REG_T src, REG_T dst)
1717{
1718  int gs, gd;
1719  INIT (RegMv);
1720
1721  ASSIGN_R (src);
1722  ASSIGN_R (dst);
1723
1724  gs = (GROUP (src));
1725  ASSIGN (gs);
1726  gd = (GROUP (dst));
1727  ASSIGN (gd);
1728
1729  return GEN_OPCODE16 ();
1730}
1731
1732INSTR_T
1733bfin_gen_cc2dreg (int opc, REG_T reg)
1734{
1735  INIT (CC2dreg);
1736
1737  ASSIGNF (opc, op);
1738  ASSIGN_R (reg);
1739
1740  return GEN_OPCODE16 ();
1741}
1742
1743INSTR_T
1744bfin_gen_progctrl (int prgfunc, int poprnd)
1745{
1746  INIT (ProgCtrl);
1747
1748  ASSIGN (prgfunc);
1749  ASSIGN (poprnd);
1750
1751  return GEN_OPCODE16 ();
1752}
1753
1754INSTR_T
1755bfin_gen_cactrl (REG_T reg, int a, int opc)
1756{
1757  INIT (CaCTRL);
1758
1759  ASSIGN_R (reg);
1760  ASSIGN (a);
1761  ASSIGNF (opc, op);
1762
1763  return GEN_OPCODE16 ();
1764}
1765
1766INSTR_T
1767bfin_gen_pushpopmultiple (int dr, int pr, int d, int p, int W)
1768{
1769  INIT (PushPopMultiple);
1770
1771  ASSIGN (dr);
1772  ASSIGN (pr);
1773  ASSIGN (d);
1774  ASSIGN (p);
1775  ASSIGN (W);
1776
1777  return GEN_OPCODE16 ();
1778}
1779
1780INSTR_T
1781bfin_gen_pushpopreg (REG_T reg, int W)
1782{
1783  int grp;
1784  INIT (PushPopReg);
1785
1786  ASSIGN_R (reg);
1787  grp = (GROUP (reg));
1788  ASSIGN (grp);
1789  ASSIGN (W);
1790
1791  return GEN_OPCODE16 ();
1792}
1793
1794/* Pseudo Debugging Support.  */
1795
1796INSTR_T
1797bfin_gen_pseudodbg (int fn, int reg, int grp)
1798{
1799  INIT (PseudoDbg);
1800
1801  ASSIGN (fn);
1802  ASSIGN (reg);
1803  ASSIGN (grp);
1804
1805  return GEN_OPCODE16 ();
1806}
1807
1808INSTR_T
1809bfin_gen_pseudodbg_assert (int dbgop, REG_T regtest, int expected)
1810{
1811  int grp;
1812  INIT (PseudoDbg_Assert);
1813
1814  ASSIGN (dbgop);
1815  ASSIGN_R (regtest);
1816  grp = GROUP (regtest);
1817  ASSIGN (grp);
1818  ASSIGN (expected);
1819
1820  return GEN_OPCODE32 ();
1821}
1822
1823INSTR_T
1824bfin_gen_pseudochr (int ch)
1825{
1826  INIT (PseudoChr);
1827
1828  ASSIGN (ch);
1829
1830  return GEN_OPCODE16 ();
1831}
1832
1833/* Multiple instruction generation.  */
1834
1835INSTR_T
1836bfin_gen_multi_instr (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2)
1837{
1838  INSTR_T walk;
1839
1840  /* If it's a 0, convert into MNOP. */
1841  if (dsp32)
1842    {
1843      walk = dsp32->next;
1844      SET_MULTI_INSTRUCTION_BIT (dsp32);
1845    }
1846  else
1847    {
1848      dsp32 = gencode (0xc803);
1849      walk = gencode (0x1800);
1850      dsp32->next = walk;
1851    }
1852
1853  if (!dsp16_grp1)
1854    {
1855      dsp16_grp1 = gencode (0x0000);
1856    }
1857
1858  if (!dsp16_grp2)
1859    {
1860      dsp16_grp2 = gencode (0x0000);
1861    }
1862
1863  walk->next = dsp16_grp1;
1864  dsp16_grp1->next = dsp16_grp2;
1865  dsp16_grp2->next = NULL_CODE;
1866
1867  return dsp32;
1868}
1869
1870INSTR_T
1871bfin_gen_loop (Expr_Node *exp, REG_T reg, int rop, REG_T preg)
1872{
1873  const char *loopsym;
1874  char *lbeginsym, *lendsym;
1875  Expr_Node_Value lbeginval, lendval;
1876  Expr_Node *lbegin, *lend;
1877  symbolS *sym;
1878
1879  loopsym = exp->value.s_value;
1880  lbeginsym = (char *) xmalloc (strlen (loopsym) + strlen ("__BEGIN") + 5);
1881  lendsym = (char *) xmalloc (strlen (loopsym) + strlen ("__END") + 5);
1882
1883  lbeginsym[0] = 0;
1884  lendsym[0] = 0;
1885
1886  strcat (lbeginsym, "L$L$");
1887  strcat (lbeginsym, loopsym);
1888  strcat (lbeginsym, "__BEGIN");
1889
1890  strcat (lendsym, "L$L$");
1891  strcat (lendsym, loopsym);
1892  strcat (lendsym, "__END");
1893
1894  lbeginval.s_value = lbeginsym;
1895  lendval.s_value = lendsym;
1896
1897  lbegin = Expr_Node_Create (Expr_Node_Reloc, lbeginval, NULL, NULL);
1898  lend   = Expr_Node_Create (Expr_Node_Reloc, lendval, NULL, NULL);
1899
1900  sym = symbol_find(loopsym);
1901  if (!S_IS_LOCAL (sym) || (S_IS_LOCAL (sym) && !symbol_used_p (sym)))
1902    symbol_remove (sym, &symbol_rootP, &symbol_lastP);
1903
1904  return bfin_gen_loopsetup (lbegin, reg, rop, lend, preg);
1905}
1906
1907void
1908bfin_loop_attempt_create_label (Expr_Node *exp, int is_begin)
1909{
1910  char *name;
1911  name = fb_label_name (exp->value.i_value, is_begin);
1912  exp->value.s_value = xstrdup (name);
1913  exp->type = Expr_Node_Reloc;
1914}
1915
1916void
1917bfin_loop_beginend (Expr_Node *exp, int begin)
1918{
1919  const char *loopsym;
1920  char *label_name;
1921  symbolS *linelabel;
1922  const char *suffix = begin ? "__BEGIN" : "__END";
1923
1924  loopsym = exp->value.s_value;
1925  label_name = (char *) xmalloc (strlen (loopsym) + strlen (suffix) + 5);
1926
1927  label_name[0] = 0;
1928
1929  strcat (label_name, "L$L$");
1930  strcat (label_name, loopsym);
1931  strcat (label_name, suffix);
1932
1933  linelabel = colon (label_name);
1934
1935  /* LOOP_END follows the last instruction in the loop.
1936     Adjust label address.  */
1937  if (!begin)
1938    ((struct local_symbol *) linelabel)->lsy_value -= last_insn_size;
1939}
1940
1941bfd_boolean
1942bfin_eol_in_insn (char *line)
1943{
1944   /* Allow a new-line to appear in the middle of a multi-issue instruction.  */
1945
1946   char *temp = line;
1947
1948  if (*line != '\n')
1949    return FALSE;
1950
1951  /* A semi-colon followed by a newline is always the end of a line.  */
1952  if (line[-1] == ';')
1953    return FALSE;
1954
1955  if (line[-1] == '|')
1956    return TRUE;
1957
1958  /* If the || is on the next line, there might be leading whitespace.  */
1959  temp++;
1960  while (*temp == ' ' || *temp == '\t') temp++;
1961
1962  if (*temp == '|')
1963    return TRUE;
1964
1965  return FALSE;
1966}
1967
1968bfd_boolean
1969bfin_start_label (char *s, char *ptr)
1970{
1971  while (s != ptr)
1972    {
1973      if (*s == '(' || *s == '[')
1974	return FALSE;
1975      s++;
1976    }
1977
1978  return TRUE;
1979}
1980
1981int
1982bfin_force_relocation (struct fix *fixp)
1983{
1984  if (fixp->fx_r_type ==BFD_RELOC_BFIN_16_LOW
1985      || fixp->fx_r_type == BFD_RELOC_BFIN_16_HIGH)
1986    return TRUE;
1987
1988  return generic_force_reloc (fixp);
1989}
1990
1991/* This is a stripped down version of the disassembler.  The only thing it
1992   does is return a mask of registers modified by an instruction.  Only
1993   instructions that can occur in a parallel-issue bundle are handled, and
1994   only the registers that can cause a conflict are recorded.  */
1995
1996#define DREG_MASK(n) (0x101 << (n))
1997#define DREGH_MASK(n) (0x100 << (n))
1998#define DREGL_MASK(n) (0x001 << (n))
1999#define IREG_MASK(n) (1 << ((n) + 16))
2000
2001static int
2002decode_ProgCtrl_0 (int iw0)
2003{
2004  if (iw0 == 0)
2005    return 0;
2006  abort ();
2007}
2008
2009static int
2010decode_LDSTpmod_0 (int iw0)
2011{
2012  /* LDSTpmod
2013     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2014     | 1 | 0 | 0 | 0 |.W.|.aop...|.reg.......|.idx.......|.ptr.......|
2015     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2016  int W   = ((iw0 >> LDSTpmod_W_bits) & LDSTpmod_W_mask);
2017  int aop = ((iw0 >> LDSTpmod_aop_bits) & LDSTpmod_aop_mask);
2018  int idx = ((iw0 >> LDSTpmod_idx_bits) & LDSTpmod_idx_mask);
2019  int ptr = ((iw0 >> LDSTpmod_ptr_bits) & LDSTpmod_ptr_mask);
2020  int reg = ((iw0 >> LDSTpmod_reg_bits) & LDSTpmod_reg_mask);
2021
2022  if (aop == 1 && W == 0 && idx == ptr)
2023    return DREGL_MASK (reg);
2024  else if (aop == 2 && W == 0 && idx == ptr)
2025    return DREGH_MASK (reg);
2026  else if (aop == 1 && W == 1 && idx == ptr)
2027    return 0;
2028  else if (aop == 2 && W == 1 && idx == ptr)
2029    return 0;
2030  else if (aop == 0 && W == 0)
2031    return DREG_MASK (reg);
2032  else if (aop == 1 && W == 0)
2033    return DREGL_MASK (reg);
2034  else if (aop == 2 && W == 0)
2035    return DREGH_MASK (reg);
2036  else if (aop == 3 && W == 0)
2037    return DREG_MASK (reg);
2038  else if (aop == 3 && W == 1)
2039    return DREG_MASK (reg);
2040  else if (aop == 0 && W == 1)
2041    return 0;
2042  else if (aop == 1 && W == 1)
2043    return 0;
2044  else if (aop == 2 && W == 1)
2045    return 0;
2046  else
2047    return 0;
2048
2049  return 2;
2050}
2051
2052static int
2053decode_dagMODim_0 (int iw0)
2054{
2055  /* dagMODim
2056     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2057     | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |.br| 1 | 1 |.op|.m.....|.i.....|
2058     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2059  int i  = ((iw0 >> DagMODim_i_bits) & DagMODim_i_mask);
2060  int opc  = ((iw0 >> DagMODim_op_bits) & DagMODim_op_mask);
2061
2062  if (opc == 0 || opc == 1)
2063    return IREG_MASK (i);
2064  else
2065    return 0;
2066
2067  return 2;
2068}
2069
2070static int
2071decode_dagMODik_0 (int iw0)
2072{
2073  /* dagMODik
2074     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2075     | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |.op....|.i.....|
2076     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2077  int i  = ((iw0 >> DagMODik_i_bits) & DagMODik_i_mask);
2078  return IREG_MASK (i);
2079}
2080
2081/* GOOD */
2082static int
2083decode_dspLDST_0 (int iw0)
2084{
2085  /* dspLDST
2086     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2087     | 1 | 0 | 0 | 1 | 1 | 1 |.W.|.aop...|.m.....|.i.....|.reg.......|
2088     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2089  int i   = ((iw0 >> DspLDST_i_bits) & DspLDST_i_mask);
2090  int m   = ((iw0 >> DspLDST_m_bits) & DspLDST_m_mask);
2091  int W   = ((iw0 >> DspLDST_W_bits) & DspLDST_W_mask);
2092  int aop = ((iw0 >> DspLDST_aop_bits) & DspLDST_aop_mask);
2093  int reg = ((iw0 >> DspLDST_reg_bits) & DspLDST_reg_mask);
2094
2095  if (aop == 0 && W == 0 && m == 0)
2096    return DREG_MASK (reg) | IREG_MASK (i);
2097  else if (aop == 0 && W == 0 && m == 1)
2098    return DREGL_MASK (reg) | IREG_MASK (i);
2099  else if (aop == 0 && W == 0 && m == 2)
2100    return DREGH_MASK (reg) | IREG_MASK (i);
2101  else if (aop == 1 && W == 0 && m == 0)
2102    return DREG_MASK (reg) | IREG_MASK (i);
2103  else if (aop == 1 && W == 0 && m == 1)
2104    return DREGL_MASK (reg) | IREG_MASK (i);
2105  else if (aop == 1 && W == 0 && m == 2)
2106    return DREGH_MASK (reg) | IREG_MASK (i);
2107  else if (aop == 2 && W == 0 && m == 0)
2108    return DREG_MASK (reg);
2109  else if (aop == 2 && W == 0 && m == 1)
2110    return DREGL_MASK (reg);
2111  else if (aop == 2 && W == 0 && m == 2)
2112    return DREGH_MASK (reg);
2113  else if (aop == 0 && W == 1 && m == 0)
2114    return IREG_MASK (i);
2115  else if (aop == 0 && W == 1 && m == 1)
2116    return IREG_MASK (i);
2117  else if (aop == 0 && W == 1 && m == 2)
2118    return IREG_MASK (i);
2119  else if (aop == 1 && W == 1 && m == 0)
2120    return IREG_MASK (i);
2121  else if (aop == 1 && W == 1 && m == 1)
2122    return IREG_MASK (i);
2123  else if (aop == 1 && W == 1 && m == 2)
2124    return IREG_MASK (i);
2125  else if (aop == 2 && W == 1 && m == 0)
2126    return 0;
2127  else if (aop == 2 && W == 1 && m == 1)
2128    return 0;
2129  else if (aop == 2 && W == 1 && m == 2)
2130    return 0;
2131  else if (aop == 3 && W == 0)
2132    return DREG_MASK (reg) | IREG_MASK (i);
2133  else if (aop == 3 && W == 1)
2134    return IREG_MASK (i);
2135
2136  abort ();
2137}
2138
2139/* GOOD */
2140static int
2141decode_LDST_0 (int iw0)
2142{
2143  /* LDST
2144     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2145     | 1 | 0 | 0 | 1 |.sz....|.W.|.aop...|.Z.|.ptr.......|.reg.......|
2146     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2147  int Z   = ((iw0 >> LDST_Z_bits) & LDST_Z_mask);
2148  int W   = ((iw0 >> LDST_W_bits) & LDST_W_mask);
2149  int sz  = ((iw0 >> LDST_sz_bits) & LDST_sz_mask);
2150  int aop = ((iw0 >> LDST_aop_bits) & LDST_aop_mask);
2151  int reg = ((iw0 >> LDST_reg_bits) & LDST_reg_mask);
2152
2153  if (aop == 0 && sz == 0 && Z == 0 && W == 0)
2154    return DREG_MASK (reg);
2155  else if (aop == 0 && sz == 0 && Z == 1 && W == 0)
2156    return 0;
2157  else if (aop == 0 && sz == 1 && Z == 0 && W == 0)
2158    return DREG_MASK (reg);
2159  else if (aop == 0 && sz == 1 && Z == 1 && W == 0)
2160    return DREG_MASK (reg);
2161  else if (aop == 0 && sz == 2 && Z == 0 && W == 0)
2162    return DREG_MASK (reg);
2163  else if (aop == 0 && sz == 2 && Z == 1 && W == 0)
2164    return DREG_MASK (reg);
2165  else if (aop == 1 && sz == 0 && Z == 0 && W == 0)
2166    return DREG_MASK (reg);
2167  else if (aop == 1 && sz == 0 && Z == 1 && W == 0)
2168    return 0;
2169  else if (aop == 1 && sz == 1 && Z == 0 && W == 0)
2170    return DREG_MASK (reg);
2171  else if (aop == 1 && sz == 1 && Z == 1 && W == 0)
2172    return DREG_MASK (reg);
2173  else if (aop == 1 && sz == 2 && Z == 0 && W == 0)
2174    return DREG_MASK (reg);
2175  else if (aop == 1 && sz == 2 && Z == 1 && W == 0)
2176    return DREG_MASK (reg);
2177  else if (aop == 2 && sz == 0 && Z == 0 && W == 0)
2178    return DREG_MASK (reg);
2179  else if (aop == 2 && sz == 0 && Z == 1 && W == 0)
2180    return 0;
2181  else if (aop == 2 && sz == 1 && Z == 0 && W == 0)
2182    return DREG_MASK (reg);
2183  else if (aop == 2 && sz == 1 && Z == 1 && W == 0)
2184    return DREG_MASK (reg);
2185  else if (aop == 2 && sz == 2 && Z == 0 && W == 0)
2186    return DREG_MASK (reg);
2187  else if (aop == 2 && sz == 2 && Z == 1 && W == 0)
2188    return DREG_MASK (reg);
2189  else if (aop == 0 && sz == 0 && Z == 0 && W == 1)
2190    return 0;
2191  else if (aop == 0 && sz == 0 && Z == 1 && W == 1)
2192    return 0;
2193  else if (aop == 0 && sz == 1 && Z == 0 && W == 1)
2194    return 0;
2195  else if (aop == 0 && sz == 2 && Z == 0 && W == 1)
2196    return 0;
2197  else if (aop == 1 && sz == 0 && Z == 0 && W == 1)
2198    return 0;
2199  else if (aop == 1 && sz == 0 && Z == 1 && W == 1)
2200    return 0;
2201  else if (aop == 1 && sz == 1 && Z == 0 && W == 1)
2202    return 0;
2203  else if (aop == 1 && sz == 2 && Z == 0 && W == 1)
2204    return 0;
2205  else if (aop == 2 && sz == 0 && Z == 0 && W == 1)
2206    return 0;
2207  else if (aop == 2 && sz == 0 && Z == 1 && W == 1)
2208    return 0;
2209  else if (aop == 2 && sz == 1 && Z == 0 && W == 1)
2210    return 0;
2211  else if (aop == 2 && sz == 2 && Z == 0 && W == 1)
2212    return 0;
2213
2214  abort ();
2215}
2216
2217static int
2218decode_LDSTiiFP_0 (int iw0)
2219{
2220  /* LDSTiiFP
2221     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2222     | 1 | 0 | 1 | 1 | 1 | 0 |.W.|.offset............|.reg...........|
2223     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2224  int reg = ((iw0 >> LDSTiiFP_reg_bits) & LDSTiiFP_reg_mask);
2225  int W = ((iw0 >> LDSTiiFP_W_bits) & LDSTiiFP_W_mask);
2226
2227  if (W == 0)
2228    return reg < 8 ? DREG_MASK (reg) : 0;
2229  else
2230    return 0;
2231}
2232
2233static int
2234decode_LDSTii_0 (int iw0)
2235{
2236  /* LDSTii
2237     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2238     | 1 | 0 | 1 |.W.|.op....|.offset........|.ptr.......|.reg.......|
2239     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2240  int reg = ((iw0 >> LDSTii_reg_bit) & LDSTii_reg_mask);
2241  int opc = ((iw0 >> LDSTii_op_bit) & LDSTii_op_mask);
2242  int W = ((iw0 >> LDSTii_W_bit) & LDSTii_W_mask);
2243
2244  if (W == 0 && opc != 3)
2245    return DREG_MASK (reg);
2246  else if (W == 0 && opc == 3)
2247   return 0;
2248  else if (W == 1 && opc == 0)
2249    return 0;
2250  else if (W == 1 && opc == 1)
2251    return 0;
2252  else if (W == 1 && opc == 3)
2253    return 0;
2254
2255  abort ();
2256}
2257
2258static int
2259decode_dsp32mac_0 (int iw0, int iw1)
2260{
2261  int result = 0;
2262  /* dsp32mac
2263     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2264     | 1 | 1 | 0 | 0 |.M.| 0 | 0 |.mmod..........|.MM|.P.|.w1|.op1...|
2265     |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2266     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2267  int op1  = ((iw0 >> (DSP32Mac_op1_bits - 16)) & DSP32Mac_op1_mask);
2268  int w1   = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask);
2269  int P    = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask);
2270  int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask);
2271  int w0   = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask);
2272  int MM   = ((iw1 >> DSP32Mac_MM_bits) & DSP32Mac_MM_mask);
2273  int dst  = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask);
2274  int op0  = ((iw1 >> DSP32Mac_op0_bits) & DSP32Mac_op0_mask);
2275
2276  if (w0 == 0 && w1 == 0 && op1 == 3 && op0 == 3)
2277    return 0;
2278
2279  if (op1 == 3 && MM)
2280    return 0;
2281
2282  if ((w1 || w0) && mmod == M_W32)
2283    return 0;
2284
2285  if (((1 << mmod) & (P ? 0x131b : 0x1b5f)) == 0)
2286    return 0;
2287
2288  if (w1 == 1 || op1 != 3)
2289    {
2290      if (w1)
2291	{
2292	  if (P)
2293	    return DREG_MASK (dst + 1);
2294	  else
2295	    return DREGH_MASK (dst);
2296	}
2297    }
2298
2299  if (w0 == 1 || op0 != 3)
2300    {
2301      if (w0)
2302	{
2303	  if (P)
2304	    return DREG_MASK (dst);
2305	  else
2306	    return DREGL_MASK (dst);
2307	}
2308    }
2309
2310  return result;
2311}
2312
2313static int
2314decode_dsp32mult_0 (int iw0, int iw1)
2315{
2316  /* dsp32mult
2317     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2318     | 1 | 1 | 0 | 0 |.M.| 0 | 1 |.mmod..........|.MM|.P.|.w1|.op1...|
2319     |.h01|.h11|.w0|.op0...|.h00|.h10|.dst.......|.src0......|.src1..|
2320     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2321  int w1   = ((iw0 >> (DSP32Mac_w1_bits - 16)) & DSP32Mac_w1_mask);
2322  int P    = ((iw0 >> (DSP32Mac_p_bits - 16)) & DSP32Mac_p_mask);
2323  int mmod = ((iw0 >> (DSP32Mac_mmod_bits - 16)) & DSP32Mac_mmod_mask);
2324  int w0   = ((iw1 >> DSP32Mac_w0_bits) & DSP32Mac_w0_mask);
2325  int dst  = ((iw1 >> DSP32Mac_dst_bits) & DSP32Mac_dst_mask);
2326  int result = 0;
2327
2328  if (w1 == 0 && w0 == 0)
2329    return 0;
2330
2331  if (((1 << mmod) & (P ? 0x313 : 0x1b57)) == 0)
2332    return 0;
2333
2334  if (w1)
2335    {
2336      if (P)
2337	return DREG_MASK (dst | 1);
2338      else
2339	return DREGH_MASK (dst);
2340    }
2341
2342  if (w0)
2343    {
2344      if (P)
2345	return DREG_MASK (dst);
2346      else
2347	return DREGL_MASK (dst);
2348    }
2349
2350  return result;
2351}
2352
2353static int
2354decode_dsp32alu_0 (int iw0, int iw1)
2355{
2356  /* dsp32alu
2357     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2358     | 1 | 1 | 0 | 0 |.M.| 1 | 0 | - | - | - |.HL|.aopcde............|
2359     |.aop...|.s.|.x.|.dst0......|.dst1......|.src0......|.src1......|
2360     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2361  int s    = ((iw1 >> DSP32Alu_s_bits) & DSP32Alu_s_mask);
2362  int x    = ((iw1 >> DSP32Alu_x_bits) & DSP32Alu_x_mask);
2363  int aop  = ((iw1 >> DSP32Alu_aop_bits) & DSP32Alu_aop_mask);
2364  int dst0 = ((iw1 >> DSP32Alu_dst0_bits) & DSP32Alu_dst0_mask);
2365  int dst1 = ((iw1 >> DSP32Alu_dst1_bits) & DSP32Alu_dst1_mask);
2366  int HL   = ((iw0 >> (DSP32Alu_HL_bits - 16)) & DSP32Alu_HL_mask);
2367  int aopcde = ((iw0 >> (DSP32Alu_aopcde_bits - 16)) & DSP32Alu_aopcde_mask);
2368
2369  if (aop == 0 && aopcde == 9 && s == 0)
2370    return 0;
2371  else if (aop == 2 && aopcde == 9 && HL == 0 && s == 0)
2372    return 0;
2373  else if (aop >= x * 2 && aopcde == 5)
2374    return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2375  else if (HL == 0 && aopcde == 2)
2376    return DREGL_MASK (dst0);
2377  else if (HL == 1 && aopcde == 2)
2378    return DREGH_MASK (dst0);
2379  else if (HL == 0 && aopcde == 3)
2380    return DREGL_MASK (dst0);
2381  else if (HL == 1 && aopcde == 3)
2382    return DREGH_MASK (dst0);
2383
2384  else if (aop == 0 && aopcde == 9 && s == 1)
2385    return 0;
2386  else if (aop == 1 && aopcde == 9 && s == 0)
2387    return 0;
2388  else if (aop == 2 && aopcde == 9 && s == 1)
2389    return 0;
2390  else if (aop == 3 && aopcde == 9 && s == 0)
2391    return 0;
2392  else if (aopcde == 8)
2393    return 0;
2394  else if (aop == 0 && aopcde == 11)
2395    return DREG_MASK (dst0);
2396  else if (aop == 1 && aopcde == 11)
2397    return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2398  else if (aopcde == 11)
2399    return 0;
2400  else if (aopcde == 22)
2401    return DREG_MASK (dst0);
2402
2403  else if ((aop == 0 || aop == 1) && aopcde == 14)
2404    return 0;
2405  else if (aop == 3 && HL == 0 && aopcde == 14)
2406    return 0;
2407
2408  else if (aop == 3 && HL == 0 && aopcde == 15)
2409    return DREG_MASK (dst0);
2410
2411  else if (aop == 1 && aopcde == 16)
2412    return 0;
2413
2414  else if (aop == 0 && aopcde == 16)
2415    return 0;
2416
2417  else if (aop == 3 && HL == 0 && aopcde == 16)
2418    return 0;
2419
2420  else if (aop == 3 && HL == 0 && aopcde == 7)
2421    return DREG_MASK (dst0);
2422  else if ((aop == 0 || aop == 1 || aop == 2) && aopcde == 7)
2423    return DREG_MASK (dst0);
2424
2425  else if (aop == 0 && aopcde == 12)
2426    return DREG_MASK (dst0);
2427  else if (aop == 1 && aopcde == 12)
2428    return DREG_MASK (dst0) | DREG_MASK (dst1);
2429  else if (aop == 3 && aopcde == 12)
2430    return HL ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2431
2432  else if (aopcde == 0)
2433    return DREG_MASK (dst0);
2434  else if (aopcde == 1)
2435    return DREG_MASK (dst0) | DREG_MASK (dst1);
2436
2437  else if (aop == 0 && aopcde == 10)
2438    return DREGL_MASK (dst0);
2439  else if (aop == 1 && aopcde == 10)
2440    return DREGL_MASK (dst0);
2441
2442  else if ((aop == 1 || aop == 0) && aopcde == 4)
2443    return DREG_MASK (dst0);
2444  else if (aop == 2 && aopcde == 4)
2445    return DREG_MASK (dst0) | DREG_MASK (dst1);
2446
2447  else if (aop == 0 && aopcde == 17)
2448    return DREG_MASK (dst0) | DREG_MASK (dst1);
2449  else if (aop == 1 && aopcde == 17)
2450    return DREG_MASK (dst0) | DREG_MASK (dst1);
2451  else if (aop == 0 && aopcde == 18)
2452    return 0;
2453  else if (aop == 3 && aopcde == 18)
2454    return 0;
2455
2456  else if ((aop == 0 || aop == 1 || aop == 2) && aopcde == 6)
2457    return DREG_MASK (dst0);
2458
2459  else if ((aop == 0 || aop == 1) && aopcde == 20)
2460    return DREG_MASK (dst0);
2461
2462  else if ((aop == 0 || aop == 1) && aopcde == 21)
2463    return DREG_MASK (dst0) | DREG_MASK (dst1);
2464
2465  else if (aop == 0 && aopcde == 23 && HL == 1)
2466    return DREG_MASK (dst0);
2467  else if (aop == 0 && aopcde == 23 && HL == 0)
2468    return DREG_MASK (dst0);
2469
2470  else if (aop == 0 && aopcde == 24)
2471    return DREG_MASK (dst0);
2472  else if (aop == 1 && aopcde == 24)
2473    return DREG_MASK (dst0) | DREG_MASK (dst1);
2474  else if (aopcde == 13)
2475    return DREG_MASK (dst0) | DREG_MASK (dst1);
2476  else
2477    return 0;
2478
2479  return 4;
2480}
2481
2482static int
2483decode_dsp32shift_0 (int iw0, int iw1)
2484{
2485  /* dsp32shift
2486     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2487     | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 0 | - | - |.sopcde............|
2488     |.sop...|.HLs...|.dst0......| - | - | - |.src0......|.src1......|
2489     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2490  int HLs  = ((iw1 >> DSP32Shift_HLs_bits) & DSP32Shift_HLs_mask);
2491  int sop  = ((iw1 >> DSP32Shift_sop_bits) & DSP32Shift_sop_mask);
2492  int src0 = ((iw1 >> DSP32Shift_src0_bits) & DSP32Shift_src0_mask);
2493  int src1 = ((iw1 >> DSP32Shift_src1_bits) & DSP32Shift_src1_mask);
2494  int dst0 = ((iw1 >> DSP32Shift_dst0_bits) & DSP32Shift_dst0_mask);
2495  int sopcde = ((iw0 >> (DSP32Shift_sopcde_bits - 16)) & DSP32Shift_sopcde_mask);
2496
2497  if (sop == 0 && sopcde == 0)
2498    return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2499  else if (sop == 1 && sopcde == 0)
2500    return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2501  else if (sop == 2 && sopcde == 0)
2502    return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2503  else if (sop == 0 && sopcde == 3)
2504    return 0;
2505  else if (sop == 1 && sopcde == 3)
2506    return 0;
2507  else if (sop == 2 && sopcde == 3)
2508    return 0;
2509  else if (sop == 3 && sopcde == 3)
2510    return DREG_MASK (dst0);
2511  else if (sop == 0 && sopcde == 1)
2512    return DREG_MASK (dst0);
2513  else if (sop == 1 && sopcde == 1)
2514    return DREG_MASK (dst0);
2515  else if (sop == 2 && sopcde == 1)
2516    return DREG_MASK (dst0);
2517  else if (sopcde == 2)
2518    return DREG_MASK (dst0);
2519  else if (sopcde == 4)
2520    return DREG_MASK (dst0);
2521  else if (sop == 0 && sopcde == 5)
2522    return DREGL_MASK (dst0);
2523  else if (sop == 1 && sopcde == 5)
2524    return DREGL_MASK (dst0);
2525  else if (sop == 2 && sopcde == 5)
2526    return DREGL_MASK (dst0);
2527  else if (sop == 0 && sopcde == 6)
2528    return DREGL_MASK (dst0);
2529  else if (sop == 1 && sopcde == 6)
2530    return DREGL_MASK (dst0);
2531  else if (sop == 3 && sopcde == 6)
2532    return DREGL_MASK (dst0);
2533  else if (sop == 0 && sopcde == 7)
2534    return DREGL_MASK (dst0);
2535  else if (sop == 1 && sopcde == 7)
2536    return DREGL_MASK (dst0);
2537  else if (sop == 2 && sopcde == 7)
2538    return DREGL_MASK (dst0);
2539  else if (sop == 3 && sopcde == 7)
2540    return DREGL_MASK (dst0);
2541  else if (sop == 0 && sopcde == 8)
2542    return DREG_MASK (src0) | DREG_MASK (src1);
2543#if 0
2544    {
2545      OUTS (outf, "BITMUX (");
2546      OUTS (outf, dregs (src0));
2547      OUTS (outf, ", ");
2548      OUTS (outf, dregs (src1));
2549      OUTS (outf, ", A0) (ASR)");
2550    }
2551#endif
2552  else if (sop == 1 && sopcde == 8)
2553    return DREG_MASK (src0) | DREG_MASK (src1);
2554#if 0
2555    {
2556      OUTS (outf, "BITMUX (");
2557      OUTS (outf, dregs (src0));
2558      OUTS (outf, ", ");
2559      OUTS (outf, dregs (src1));
2560      OUTS (outf, ", A0) (ASL)");
2561    }
2562#endif
2563  else if (sopcde == 9)
2564    return sop < 2 ? DREGL_MASK (dst0) : DREG_MASK (dst0);
2565  else if (sopcde == 10)
2566    return DREG_MASK (dst0);
2567  else if (sop == 0 && sopcde == 11)
2568    return DREGL_MASK (dst0);
2569  else if (sop == 1 && sopcde == 11)
2570    return DREGL_MASK (dst0);
2571  else if (sop == 0 && sopcde == 12)
2572    return 0;
2573  else if (sop == 1 && sopcde == 12)
2574    return DREGL_MASK (dst0);
2575  else if (sop == 0 && sopcde == 13)
2576    return DREG_MASK (dst0);
2577  else if (sop == 1 && sopcde == 13)
2578    return DREG_MASK (dst0);
2579  else if (sop == 2 && sopcde == 13)
2580    return DREG_MASK (dst0);
2581
2582  abort ();
2583}
2584
2585static int
2586decode_dsp32shiftimm_0 (int iw0, int iw1)
2587{
2588  /* dsp32shiftimm
2589     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+
2590     | 1 | 1 | 0 | 0 |.M.| 1 | 1 | 0 | 1 | - | - |.sopcde............|
2591     |.sop...|.HLs...|.dst0......|.immag.................|.src1......|
2592     +---+---+---+---|---+---+---+---|---+---+---+---|---+---+---+---+  */
2593  int sop      = ((iw1 >> DSP32ShiftImm_sop_bits) & DSP32ShiftImm_sop_mask);
2594  int bit8     = ((iw1 >> 8) & 0x1);
2595  int dst0     = ((iw1 >> DSP32ShiftImm_dst0_bits) & DSP32ShiftImm_dst0_mask);
2596  int sopcde   = ((iw0 >> (DSP32ShiftImm_sopcde_bits - 16)) & DSP32ShiftImm_sopcde_mask);
2597  int HLs      = ((iw1 >> DSP32ShiftImm_HLs_bits) & DSP32ShiftImm_HLs_mask);
2598
2599
2600  if (sop == 0 && sopcde == 0)
2601    return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2602  else if (sop == 1 && sopcde == 0 && bit8 == 0)
2603    return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2604  else if (sop == 1 && sopcde == 0 && bit8 == 1)
2605    return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2606  else if (sop == 2 && sopcde == 0 && bit8 == 0)
2607    return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2608  else if (sop == 2 && sopcde == 0 && bit8 == 1)
2609    return HLs & 2 ? DREGH_MASK (dst0) : DREGL_MASK (dst0);
2610  else if (sop == 2 && sopcde == 3 && HLs == 1)
2611    return 0;
2612  else if (sop == 0 && sopcde == 3 && HLs == 0 && bit8 == 0)
2613    return 0;
2614  else if (sop == 0 && sopcde == 3 && HLs == 0 && bit8 == 1)
2615    return 0;
2616  else if (sop == 0 && sopcde == 3 && HLs == 1 && bit8 == 0)
2617    return 0;
2618  else if (sop == 0 && sopcde == 3 && HLs == 1 && bit8 == 1)
2619    return 0;
2620  else if (sop == 1 && sopcde == 3 && HLs == 0)
2621    return 0;
2622  else if (sop == 1 && sopcde == 3 && HLs == 1)
2623    return 0;
2624  else if (sop == 2 && sopcde == 3 && HLs == 0)
2625    return 0;
2626  else if (sop == 1 && sopcde == 1 && bit8 == 0)
2627    return DREG_MASK (dst0);
2628  else if (sop == 1 && sopcde == 1 && bit8 == 1)
2629    return DREG_MASK (dst0);
2630  else if (sop == 2 && sopcde == 1 && bit8 == 1)
2631    return DREG_MASK (dst0);
2632  else if (sop == 2 && sopcde == 1 && bit8 == 0)
2633    return DREG_MASK (dst0);
2634  else if (sop == 0 && sopcde == 1)
2635    return DREG_MASK (dst0);
2636  else if (sop == 1 && sopcde == 2)
2637    return DREG_MASK (dst0);
2638  else if (sop == 2 && sopcde == 2 && bit8 == 1)
2639    return DREG_MASK (dst0);
2640  else if (sop == 2 && sopcde == 2 && bit8 == 0)
2641    return DREG_MASK (dst0);
2642  else if (sop == 3 && sopcde == 2)
2643    return DREG_MASK (dst0);
2644  else if (sop == 0 && sopcde == 2)
2645    return DREG_MASK (dst0);
2646
2647  abort ();
2648}
2649
2650int
2651insn_regmask (int iw0, int iw1)
2652{
2653  if ((iw0 & 0xf7ff) == 0xc003 && iw1 == 0x1800)
2654    return 0; /* MNOP */
2655  else if ((iw0 & 0xff00) == 0x0000)
2656    return decode_ProgCtrl_0 (iw0);
2657  else if ((iw0 & 0xffc0) == 0x0240)
2658    abort ();
2659  else if ((iw0 & 0xff80) == 0x0100)
2660    abort ();
2661  else if ((iw0 & 0xfe00) == 0x0400)
2662    abort ();
2663  else if ((iw0 & 0xfe00) == 0x0600)
2664    abort ();
2665  else if ((iw0 & 0xf800) == 0x0800)
2666    abort ();
2667  else if ((iw0 & 0xffe0) == 0x0200)
2668    abort ();
2669  else if ((iw0 & 0xff00) == 0x0300)
2670    abort ();
2671  else if ((iw0 & 0xf000) == 0x1000)
2672    abort ();
2673  else if ((iw0 & 0xf000) == 0x2000)
2674    abort ();
2675  else if ((iw0 & 0xf000) == 0x3000)
2676    abort ();
2677  else if ((iw0 & 0xfc00) == 0x4000)
2678    abort ();
2679  else if ((iw0 & 0xfe00) == 0x4400)
2680    abort ();
2681  else if ((iw0 & 0xf800) == 0x4800)
2682    abort ();
2683  else if ((iw0 & 0xf000) == 0x5000)
2684    abort ();
2685  else if ((iw0 & 0xf800) == 0x6000)
2686    abort ();
2687  else if ((iw0 & 0xf800) == 0x6800)
2688    abort ();
2689  else if ((iw0 & 0xf000) == 0x8000)
2690    return decode_LDSTpmod_0 (iw0);
2691  else if ((iw0 & 0xff60) == 0x9e60)
2692    return decode_dagMODim_0 (iw0);
2693  else if ((iw0 & 0xfff0) == 0x9f60)
2694    return decode_dagMODik_0 (iw0);
2695  else if ((iw0 & 0xfc00) == 0x9c00)
2696    return decode_dspLDST_0 (iw0);
2697  else if ((iw0 & 0xf000) == 0x9000)
2698    return decode_LDST_0 (iw0);
2699  else if ((iw0 & 0xfc00) == 0xb800)
2700    return decode_LDSTiiFP_0 (iw0);
2701  else if ((iw0 & 0xe000) == 0xA000)
2702    return decode_LDSTii_0 (iw0);
2703  else if ((iw0 & 0xff80) == 0xe080 && (iw1 & 0x0C00) == 0x0000)
2704    abort ();
2705  else if ((iw0 & 0xff00) == 0xe100 && (iw1 & 0x0000) == 0x0000)
2706    abort ();
2707  else if ((iw0 & 0xfe00) == 0xe200 && (iw1 & 0x0000) == 0x0000)
2708    abort ();
2709  else if ((iw0 & 0xfc00) == 0xe400 && (iw1 & 0x0000) == 0x0000)
2710    abort ();
2711  else if ((iw0 & 0xfffe) == 0xe800 && (iw1 & 0x0000) == 0x0000)
2712    abort ();
2713  else if ((iw0 & 0xf600) == 0xc000 && (iw1 & 0x0000) == 0x0000)
2714    return decode_dsp32mac_0 (iw0, iw1);
2715  else if ((iw0 & 0xf600) == 0xc200 && (iw1 & 0x0000) == 0x0000)
2716    return decode_dsp32mult_0 (iw0, iw1);
2717  else if ((iw0 & 0xf7c0) == 0xc400 && (iw1 & 0x0000) == 0x0000)
2718    return decode_dsp32alu_0 (iw0, iw1);
2719  else if ((iw0 & 0xf780) == 0xc600 && (iw1 & 0x01c0) == 0x0000)
2720    return decode_dsp32shift_0 (iw0, iw1);
2721  else if ((iw0 & 0xf780) == 0xc680 && (iw1 & 0x0000) == 0x0000)
2722    return decode_dsp32shiftimm_0 (iw0, iw1);
2723  else if ((iw0 & 0xff00) == 0xf800)
2724    abort ();
2725  else if ((iw0 & 0xFFC0) == 0xf000 && (iw1 & 0x0000) == 0x0000)
2726    abort ();
2727
2728  abort ();
2729}
2730