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