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