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