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