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