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