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