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