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