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