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