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