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