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