]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-bfin.c
* Makefile.in (tmp-ld-decode): Fix dependencies.
[thirdparty/binutils-gdb.git] / gas / config / tc-bfin.c
CommitLineData
07c1b327
CM
1/* tc-bfin.c -- Assembler for the ADI Blackfin.
2 Copyright 2005
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
9 the Free Software Foundation; either version 2, or (at your option)
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"
24#include "obj-elf.h"
25#include "bfin-defs.h"
26#include "obstack.h"
27#include "safe-ctype.h"
28#ifdef OBJ_ELF
29#include "dwarf2dbg.h"
30#endif
1ac4baed
BS
31#include "libbfd.h"
32#include "elf/common.h"
33#include "elf/bfin.h"
07c1b327
CM
34
35extern int yyparse (void);
36struct yy_buffer_state;
37typedef struct yy_buffer_state *YY_BUFFER_STATE;
38extern YY_BUFFER_STATE yy_scan_string (const char *yy_str);
39extern void yy_delete_buffer (YY_BUFFER_STATE b);
40static parse_state parse (char *line);
41static void bfin_s_bss PARAMS ((int));
9ba4c445 42static int md_chars_to_number PARAMS ((char *, int));
07c1b327
CM
43
44/* Global variables. */
45struct bfin_insn *insn;
46int last_insn_size;
47
48extern struct obstack mempool;
49FILE *errorf;
50
1ac4baed
BS
51/* Flags to set in the elf header */
52#define DEFAULT_FLAGS 0
53
54static flagword bfin_flags = DEFAULT_FLAGS;
55static const char *bfin_pic_flag = (const char *)0;
56
07c1b327
CM
57/* Registers list. */
58struct bfin_reg_entry
59{
60 const char *name;
61 int number;
62};
63
64static const struct bfin_reg_entry bfin_reg_info[] = {
65 {"R0.L", REG_RL0},
66 {"R1.L", REG_RL1},
67 {"R2.L", REG_RL2},
68 {"R3.L", REG_RL3},
69 {"R4.L", REG_RL4},
70 {"R5.L", REG_RL5},
71 {"R6.L", REG_RL6},
72 {"R7.L", REG_RL7},
73 {"R0.H", REG_RH0},
74 {"R1.H", REG_RH1},
75 {"R2.H", REG_RH2},
76 {"R3.H", REG_RH3},
77 {"R4.H", REG_RH4},
78 {"R5.H", REG_RH5},
79 {"R6.H", REG_RH6},
80 {"R7.H", REG_RH7},
81 {"R0", REG_R0},
82 {"R1", REG_R1},
83 {"R2", REG_R2},
84 {"R3", REG_R3},
85 {"R4", REG_R4},
86 {"R5", REG_R5},
87 {"R6", REG_R6},
88 {"R7", REG_R7},
89 {"P0", REG_P0},
90 {"P0.H", REG_P0},
91 {"P0.L", REG_P0},
92 {"P1", REG_P1},
93 {"P1.H", REG_P1},
94 {"P1.L", REG_P1},
95 {"P2", REG_P2},
96 {"P2.H", REG_P2},
97 {"P2.L", REG_P2},
98 {"P3", REG_P3},
99 {"P3.H", REG_P3},
100 {"P3.L", REG_P3},
101 {"P4", REG_P4},
102 {"P4.H", REG_P4},
103 {"P4.L", REG_P4},
104 {"P5", REG_P5},
105 {"P5.H", REG_P5},
106 {"P5.L", REG_P5},
107 {"SP", REG_SP},
108 {"SP.L", REG_SP},
109 {"SP.H", REG_SP},
110 {"FP", REG_FP},
111 {"FP.L", REG_FP},
112 {"FP.H", REG_FP},
113 {"A0x", REG_A0x},
114 {"A1x", REG_A1x},
115 {"A0w", REG_A0w},
116 {"A1w", REG_A1w},
117 {"A0.x", REG_A0x},
118 {"A1.x", REG_A1x},
119 {"A0.w", REG_A0w},
120 {"A1.w", REG_A1w},
121 {"A0", REG_A0},
122 {"A0.L", REG_A0},
123 {"A0.H", REG_A0},
124 {"A1", REG_A1},
125 {"A1.L", REG_A1},
126 {"A1.H", REG_A1},
127 {"I0", REG_I0},
128 {"I0.L", REG_I0},
129 {"I0.H", REG_I0},
130 {"I1", REG_I1},
131 {"I1.L", REG_I1},
132 {"I1.H", REG_I1},
133 {"I2", REG_I2},
134 {"I2.L", REG_I2},
135 {"I2.H", REG_I2},
136 {"I3", REG_I3},
137 {"I3.L", REG_I3},
138 {"I3.H", REG_I3},
139 {"M0", REG_M0},
140 {"M0.H", REG_M0},
141 {"M0.L", REG_M0},
142 {"M1", REG_M1},
143 {"M1.H", REG_M1},
144 {"M1.L", REG_M1},
145 {"M2", REG_M2},
146 {"M2.H", REG_M2},
147 {"M2.L", REG_M2},
148 {"M3", REG_M3},
149 {"M3.H", REG_M3},
150 {"M3.L", REG_M3},
151 {"B0", REG_B0},
152 {"B0.H", REG_B0},
153 {"B0.L", REG_B0},
154 {"B1", REG_B1},
155 {"B1.H", REG_B1},
156 {"B1.L", REG_B1},
157 {"B2", REG_B2},
158 {"B2.H", REG_B2},
159 {"B2.L", REG_B2},
160 {"B3", REG_B3},
161 {"B3.H", REG_B3},
162 {"B3.L", REG_B3},
163 {"L0", REG_L0},
164 {"L0.H", REG_L0},
165 {"L0.L", REG_L0},
166 {"L1", REG_L1},
167 {"L1.H", REG_L1},
168 {"L1.L", REG_L1},
169 {"L2", REG_L2},
170 {"L2.H", REG_L2},
171 {"L2.L", REG_L2},
172 {"L3", REG_L3},
173 {"L3.H", REG_L3},
174 {"L3.L", REG_L3},
175 {"AZ", S_AZ},
176 {"AN", S_AN},
177 {"AC0", S_AC0},
178 {"AC1", S_AC1},
179 {"AV0", S_AV0},
180 {"AV0S", S_AV0S},
181 {"AV1", S_AV1},
182 {"AV1S", S_AV1S},
183 {"AQ", S_AQ},
184 {"V", S_V},
185 {"VS", S_VS},
186 {"sftreset", REG_sftreset},
187 {"omode", REG_omode},
188 {"excause", REG_excause},
189 {"emucause", REG_emucause},
190 {"idle_req", REG_idle_req},
191 {"hwerrcause", REG_hwerrcause},
192 {"CC", REG_CC},
193 {"LC0", REG_LC0},
194 {"LC1", REG_LC1},
195 {"ASTAT", REG_ASTAT},
196 {"RETS", REG_RETS},
197 {"LT0", REG_LT0},
198 {"LB0", REG_LB0},
199 {"LT1", REG_LT1},
200 {"LB1", REG_LB1},
201 {"CYCLES", REG_CYCLES},
202 {"CYCLES2", REG_CYCLES2},
203 {"USP", REG_USP},
204 {"SEQSTAT", REG_SEQSTAT},
205 {"SYSCFG", REG_SYSCFG},
206 {"RETI", REG_RETI},
207 {"RETX", REG_RETX},
208 {"RETN", REG_RETN},
209 {"RETE", REG_RETE},
210 {"EMUDAT", REG_EMUDAT},
211 {0, 0}
212};
213
1ac4baed
BS
214/* Blackfin specific function to handle FD-PIC pointer initializations. */
215
216static void
217bfin_pic_ptr (int nbytes)
218{
219 expressionS exp;
220 char *p;
221
222 if (nbytes != 4)
223 abort ();
224
225#ifdef md_flush_pending_output
226 md_flush_pending_output ();
227#endif
228
229 if (is_it_end_of_statement ())
230 {
231 demand_empty_rest_of_line ();
232 return;
233 }
234
235#ifdef md_cons_align
236 md_cons_align (nbytes);
237#endif
238
239 do
240 {
241 bfd_reloc_code_real_type reloc_type = BFD_RELOC_BFIN_FUNCDESC;
242
243 if (strncasecmp (input_line_pointer, "funcdesc(", 9) == 0)
244 {
245 input_line_pointer += 9;
246 expression (&exp);
247 if (*input_line_pointer == ')')
248 input_line_pointer++;
249 else
250 as_bad ("missing ')'");
251 }
252 else
253 error ("missing funcdesc in picptr");
254
255 p = frag_more (4);
256 memset (p, 0, 4);
257 fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
258 reloc_type);
259 }
260 while (*input_line_pointer++ == ',');
261
262 input_line_pointer--; /* Put terminator back into stream. */
263 demand_empty_rest_of_line ();
264}
265
266static void
267bfin_s_bss (int ignore ATTRIBUTE_UNUSED)
268{
269 register int temp;
270
271 temp = get_absolute_expression ();
272 subseg_set (bss_section, (subsegT) temp);
273 demand_empty_rest_of_line ();
274}
07c1b327
CM
275
276const pseudo_typeS md_pseudo_table[] = {
277 {"align", s_align_bytes, 0},
278 {"byte2", cons, 2},
279 {"byte4", cons, 4},
1ac4baed 280 {"picptr", bfin_pic_ptr, 4},
07c1b327
CM
281 {"code", obj_elf_section, 0},
282 {"db", cons, 1},
283 {"dd", cons, 4},
284 {"dw", cons, 2},
285 {"p", s_ignore, 0},
286 {"pdata", s_ignore, 0},
287 {"var", s_ignore, 0},
288 {"bss", bfin_s_bss, 0},
289 {0, 0, 0}
290};
291
07c1b327
CM
292/* Characters that are used to denote comments and line separators. */
293const char comment_chars[] = "";
294const char line_comment_chars[] = "#";
295const char line_separator_chars[] = ";";
296
297/* Characters that can be used to separate the mantissa from the
298 exponent in floating point numbers. */
299const char EXP_CHARS[] = "eE";
300
301/* Characters that mean this number is a floating point constant.
302 As in 0f12.456 or 0d1.2345e12. */
303const char FLT_CHARS[] = "fFdDxX";
304
305/* Define bfin-specific command-line options (there are none). */
306const char *md_shortopts = "";
307
1ac4baed
BS
308#define OPTION_FDPIC (OPTION_MD_BASE)
309
310struct option md_longopts[] =
311{
312 { "mfdpic", no_argument, NULL, OPTION_FDPIC },
313 { NULL, no_argument, NULL, 0 },
07c1b327 314};
1ac4baed 315
07c1b327
CM
316size_t md_longopts_size = sizeof (md_longopts);
317
318
319int
320md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
321{
1ac4baed
BS
322 switch (c)
323 {
324 default:
325 return 0;
326
327 case OPTION_FDPIC:
328 bfin_flags |= EF_BFIN_FDPIC;
329 bfin_pic_flag = "-mfdpic";
330 break;
331 }
332
333 return 1;
07c1b327
CM
334}
335
336void
337md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
338{
339 fprintf (stream, _(" BFIN specific command line options:\n"));
340}
341
342/* Perform machine-specific initializations. */
343void
344md_begin ()
345{
1ac4baed
BS
346 /* Set the ELF flags if desired. */
347 if (bfin_flags)
348 bfd_set_private_flags (stdoutput, bfin_flags);
349
07c1b327
CM
350 /* Set the default machine type. */
351 if (!bfd_set_arch_mach (stdoutput, bfd_arch_bfin, 0))
352 as_warn ("Could not set architecture and machine.");
353
354 /* Ensure that lines can begin with '(', for multiple
355 register stack pops. */
9f8e671b 356 lex_type ['('] = LEX_BEGIN_NAME;
07c1b327
CM
357
358#ifdef OBJ_ELF
359 record_alignment (text_section, 2);
360 record_alignment (data_section, 2);
361 record_alignment (bss_section, 2);
362#endif
363
364 errorf = stderr;
365 obstack_init (&mempool);
366
367#ifdef DEBUG
368 extern int debug_codeselection;
369 debug_codeselection = 1;
370#endif
371
372 last_insn_size = 0;
373}
374
375/* Perform the main parsing, and assembly of the input here. Also,
376 call the required routines for alignment and fixups here.
377 This is called for every line that contains real assembly code. */
378
379void
380md_assemble (char *line)
381{
382 char *toP = 0;
383 extern char *current_inputline;
384 int size, insn_size;
385 struct bfin_insn *tmp_insn;
386 size_t len;
387 static size_t buffer_len = 0;
388 parse_state state;
389
390 len = strlen (line);
391 if (len + 2 > buffer_len)
392 {
393 if (buffer_len > 0)
394 free (current_inputline);
395 buffer_len = len + 40;
396 current_inputline = xmalloc (buffer_len);
397 }
398 memcpy (current_inputline, line, len);
399 current_inputline[len] = ';';
400 current_inputline[len + 1] = '\0';
401
402 state = parse (current_inputline);
403 if (state == NO_INSN_GENERATED)
404 return;
405
406 for (insn_size = 0, tmp_insn = insn; tmp_insn; tmp_insn = tmp_insn->next)
407 if (!tmp_insn->reloc || !tmp_insn->exp->symbol)
408 insn_size += 2;
409
410 if (insn_size)
411 toP = frag_more (insn_size);
412
413 last_insn_size = insn_size;
414
415#ifdef DEBUG
416 printf ("INS:");
417#endif
418 while (insn)
419 {
420 if (insn->reloc && insn->exp->symbol)
421 {
422 char *prev_toP = toP - 2;
423 switch (insn->reloc)
424 {
425 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
426 case BFD_RELOC_24_PCREL:
427 case BFD_RELOC_BFIN_16_LOW:
428 case BFD_RELOC_BFIN_16_HIGH:
429 size = 4;
430 break;
431 default:
432 size = 2;
433 }
434
435 /* Following if condition checks for the arithmetic relocations.
436 If the case then it doesn't required to generate the code.
437 It has been assumed that, their ID will be contiguous. */
438 if ((BFD_ARELOC_BFIN_PUSH <= insn->reloc
439 && BFD_ARELOC_BFIN_COMP >= insn->reloc)
440 || insn->reloc == BFD_RELOC_BFIN_16_IMM)
441 {
442 size = 2;
443 }
444 if (insn->reloc == BFD_ARELOC_BFIN_CONST
445 || insn->reloc == BFD_ARELOC_BFIN_PUSH)
446 size = 4;
447
448 fix_new (frag_now,
449 (prev_toP - frag_now->fr_literal),
450 size, insn->exp->symbol, insn->exp->value,
451 insn->pcrel, insn->reloc);
452 }
453 else
454 {
455 md_number_to_chars (toP, insn->value, 2);
456 toP += 2;
457 }
458
459#ifdef DEBUG
460 printf (" reloc :");
461 printf (" %02x%02x", ((unsigned char *) &insn->value)[0],
462 ((unsigned char *) &insn->value)[1]);
463 printf ("\n");
464#endif
465 insn = insn->next;
466 }
467#ifdef OBJ_ELF
468 dwarf2_emit_insn (insn_size);
469#endif
470}
471
472/* Parse one line of instructions, and generate opcode for it.
473 To parse the line, YACC and LEX are used, because the instruction set
474 syntax doesn't confirm to the AT&T assembly syntax.
475 To call a YACC & LEX generated parser, we must provide the input via
476 a FILE stream, otherwise stdin is used by default. Below the input
477 to the function will be put into a temporary file, then the generated
478 parser uses the temporary file for parsing. */
479
480static parse_state
481parse (char *line)
482{
483 parse_state state;
484 YY_BUFFER_STATE buffstate;
485
486 buffstate = yy_scan_string (line);
487
488 /* our lex requires setting the start state to keyword
489 every line as the first word may be a keyword.
490 Fixes a bug where we could not have keywords as labels. */
491 set_start_state ();
492
493 /* Call yyparse here. */
494 state = yyparse ();
495 if (state == SEMANTIC_ERROR)
496 {
497 as_bad ("Parse failed.");
498 insn = 0;
499 }
500
501 yy_delete_buffer (buffstate);
502 return state;
503}
504
505/* We need to handle various expressions properly.
506 Such as, [SP--] = 34, concerned by md_assemble(). */
507
508void
509md_operand (expressionS * expressionP)
510{
511 if (*input_line_pointer == '[')
512 {
513 as_tsktsk ("We found a '['!");
514 input_line_pointer++;
515 expression (expressionP);
516 }
517}
518
519/* Handle undefined symbols. */
520symbolS *
521md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
522{
523 return (symbolS *) 0;
524}
525
526int
527md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
528 segT segment ATTRIBUTE_UNUSED)
529{
530 return 0;
531}
532
533/* Convert from target byte order to host byte order. */
534
535static int
9ba4c445 536md_chars_to_number (char *val, int n)
07c1b327
CM
537{
538 int retval;
539
540 for (retval = 0; n--;)
541 {
542 retval <<= 8;
543 retval |= val[n];
544 }
545 return retval;
546}
547
548void
549md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
550{
551 char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
552
553 long value = *valueP;
554 long newval;
555
556 switch (fixP->fx_r_type)
557 {
558 case BFD_RELOC_BFIN_GOT:
1ac4baed
BS
559 case BFD_RELOC_BFIN_GOT17M4:
560 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
07c1b327
CM
561 fixP->fx_no_overflow = 1;
562 newval = md_chars_to_number (where, 2);
563 newval |= 0x0 & 0x7f;
564 md_number_to_chars (where, newval, 2);
565 break;
566
567 case BFD_RELOC_BFIN_10_PCREL:
568 if (!value)
569 break;
570 if (value < -1024 || value > 1022)
571 as_bad_where (fixP->fx_file, fixP->fx_line,
572 "pcrel too far BFD_RELOC_BFIN_10");
573
574 /* 11 bit offset even numbered, so we remove right bit. */
575 value = value >> 1;
576 newval = md_chars_to_number (where, 2);
577 newval |= value & 0x03ff;
578 md_number_to_chars (where, newval, 2);
579 break;
580
581 case BFD_RELOC_BFIN_12_PCREL_JUMP:
582 case BFD_RELOC_BFIN_12_PCREL_JUMP_S:
583 case BFD_RELOC_12_PCREL:
584 if (!value)
585 break;
586
587 if (value < -4096 || value > 4094)
588 as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far BFD_RELOC_BFIN_12");
589 /* 13 bit offset even numbered, so we remove right bit. */
590 value = value >> 1;
591 newval = md_chars_to_number (where, 2);
592 newval |= value & 0xfff;
593 md_number_to_chars (where, newval, 2);
594 break;
595
596 case BFD_RELOC_BFIN_16_LOW:
597 case BFD_RELOC_BFIN_16_HIGH:
598 fixP->fx_done = FALSE;
599 break;
600
601 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
602 case BFD_RELOC_BFIN_24_PCREL_CALL_X:
603 case BFD_RELOC_24_PCREL:
604 if (!value)
605 break;
606
607 if (value < -16777216 || value > 16777214)
608 as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far BFD_RELOC_BFIN_24");
609
610 /* 25 bit offset even numbered, so we remove right bit. */
611 value = value >> 1;
612 value++;
613
614 md_number_to_chars (where - 2, value >> 16, 1);
615 md_number_to_chars (where, value, 1);
616 md_number_to_chars (where + 1, value >> 8, 1);
617 break;
618
619 case BFD_RELOC_BFIN_5_PCREL: /* LSETUP (a, b) : "a" */
620 if (!value)
621 break;
622 if (value < 4 || value > 30)
623 as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far BFD_RELOC_BFIN_5");
624 value = value >> 1;
625 newval = md_chars_to_number (where, 1);
626 newval = (newval & 0xf0) | (value & 0xf);
627 md_number_to_chars (where, newval, 1);
628 break;
629
630 case BFD_RELOC_BFIN_11_PCREL: /* LSETUP (a, b) : "b" */
631 if (!value)
632 break;
633 value += 2;
634 if (value < 4 || value > 2046)
635 as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far BFD_RELOC_BFIN_11_PCREL");
636 /* 11 bit unsigned even, so we remove right bit. */
637 value = value >> 1;
638 newval = md_chars_to_number (where, 2);
639 newval |= value & 0x03ff;
640 md_number_to_chars (where, newval, 2);
641 break;
642
643 case BFD_RELOC_8:
644 if (value < -0x80 || value >= 0x7f)
645 as_bad_where (fixP->fx_file, fixP->fx_line, "rel too far BFD_RELOC_8");
646 md_number_to_chars (where, value, 1);
647 break;
648
649 case BFD_RELOC_BFIN_16_IMM:
650 case BFD_RELOC_16:
651 if (value < -0x8000 || value >= 0x7fff)
652 as_bad_where (fixP->fx_file, fixP->fx_line, "rel too far BFD_RELOC_8");
653 md_number_to_chars (where, value, 2);
654 break;
655
656 case BFD_RELOC_32:
657 md_number_to_chars (where, value, 4);
658 break;
659
660 case BFD_RELOC_BFIN_PLTPC:
661 md_number_to_chars (where, value, 2);
662 break;
663
1ac4baed 664 case BFD_RELOC_BFIN_FUNCDESC:
07c1b327
CM
665 case BFD_RELOC_VTABLE_INHERIT:
666 case BFD_RELOC_VTABLE_ENTRY:
667 fixP->fx_done = FALSE;
668 break;
669
670 default:
671 if ((BFD_ARELOC_BFIN_PUSH > fixP->fx_r_type) || (BFD_ARELOC_BFIN_COMP < fixP->fx_r_type))
672 {
673 fprintf (stderr, "Relocation %d not handled in gas." " Contact support.\n", fixP->fx_r_type);
674 return;
675 }
676 }
677
678 if (!fixP->fx_addsy)
679 fixP->fx_done = TRUE;
680
681}
682
683/* Round up a section size to the appropriate boundary. */
684valueT
685md_section_align (segment, size)
686 segT segment;
687 valueT size;
688{
689 int boundary = bfd_get_section_alignment (stdoutput, segment);
690 return ((size + (1 << boundary) - 1) & (-1 << boundary));
691}
692
693
694/* Turn a string in input_line_pointer into a floating point
695 constant of type type, and store the appropriate bytes in
696 *litP. The number of LITTLENUMS emitted is stored in *sizeP.
697 An error message is returned, or NULL on OK. */
698
699/* Equal to MAX_PRECISION in atof-ieee.c. */
700#define MAX_LITTLENUMS 6
701
702char *
703md_atof (type, litP, sizeP)
704 char type;
705 char * litP;
706 int * sizeP;
707{
708 int prec;
709 LITTLENUM_TYPE words [MAX_LITTLENUMS];
710 LITTLENUM_TYPE *wordP;
711 char * t;
712
713 switch (type)
714 {
715 case 'f':
716 case 'F':
717 prec = 2;
718 break;
719
720 case 'd':
721 case 'D':
722 prec = 4;
723 break;
724
725 /* FIXME: Some targets allow other format chars for bigger sizes here. */
726
727 default:
728 *sizeP = 0;
729 return _("Bad call to md_atof()");
730 }
731
732 t = atof_ieee (input_line_pointer, type, words);
733 if (t)
734 input_line_pointer = t;
735 *sizeP = prec * sizeof (LITTLENUM_TYPE);
736
737 *sizeP = prec * sizeof (LITTLENUM_TYPE);
738 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
739 the littleendianness of the processor. */
740 for (wordP = words + prec - 1; prec--;)
741 {
742 md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
743 litP += sizeof (LITTLENUM_TYPE);
744 }
745
746 return 0;
747}
748
749
750/* If while processing a fixup, a reloc really needs to be created
751 then it is done here. */
752
753arelent *
754tc_gen_reloc (seg, fixp)
755 asection *seg ATTRIBUTE_UNUSED;
756 fixS *fixp;
757{
758 arelent *reloc;
759
760 reloc = (arelent *) xmalloc (sizeof (arelent));
761 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
762 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
763 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
764
765 reloc->addend = fixp->fx_offset;
766 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
767
768 if (reloc->howto == (reloc_howto_type *) NULL)
769 {
770 as_bad_where (fixp->fx_file, fixp->fx_line,
771 /* xgettext:c-format. */
772 _("reloc %d not supported by object file format"),
773 (int) fixp->fx_r_type);
774
775 xfree (reloc);
776
777 return NULL;
778 }
779
780 return reloc;
781}
782
783/* The location from which a PC relative jump should be calculated,
784 given a PC relative reloc. */
785
786long
787md_pcrel_from_section (fixP, sec)
788 fixS *fixP;
789 segT sec;
790{
791 if (fixP->fx_addsy != (symbolS *) NULL
792 && (!S_IS_DEFINED (fixP->fx_addsy)
793 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
794 {
795 /* The symbol is undefined (or is defined but not in this section).
796 Let the linker figure it out. */
797 return 0;
798 }
799 return fixP->fx_frag->fr_address + fixP->fx_where;
800}
801
802/* Return true if the fix can be handled by GAS, false if it must
803 be passed through to the linker. */
804
805bfd_boolean
806bfin_fix_adjustable (fixS *fixP)
807{
808 switch (fixP->fx_r_type)
809 {
810 /* Adjust_reloc_syms doesn't know about the GOT. */
1ac4baed
BS
811 case BFD_RELOC_BFIN_GOT:
812 case BFD_RELOC_BFIN_GOT17M4:
813 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
814 case BFD_RELOC_BFIN_PLTPC:
07c1b327
CM
815 /* We need the symbol name for the VTABLE entries. */
816 case BFD_RELOC_VTABLE_INHERIT:
817 case BFD_RELOC_VTABLE_ENTRY:
818 return 0;
819
820 default:
821 return 1;
822 }
823}
824
825
826/* Handle the LOOP_BEGIN and LOOP_END statements.
827 Parse the Loop_Begin/Loop_End and create a label. */
828void
829bfin_start_line_hook ()
830{
831 bfd_boolean maybe_begin = FALSE;
832 bfd_boolean maybe_end = FALSE;
833
834 char *c1, *label_name;
835 symbolS *line_label;
836 char *c = input_line_pointer;
837
838 while (ISSPACE (*c))
839 c++;
840
07c1b327
CM
841 /* Look for Loop_Begin or Loop_End statements. */
842
843 if (*c != 'L' && *c != 'l')
844 return;
845
846 c++;
847 if (*c != 'O' && *c != 'o')
848 return;
849
850 c++;
851 if (*c != 'O' && *c != 'o')
852 return;
853
854 c++;
855 if (*c != 'P' && *c != 'p')
856 return;
857
858 c++;
859 if (*c != '_')
860 return;
861
862 c++;
863 if (*c == 'E' || *c == 'e')
864 maybe_end = TRUE;
865 else if (*c == 'B' || *c == 'b')
866 maybe_begin = TRUE;
867 else
868 return;
869
870 if (maybe_end)
871 {
872 c++;
873 if (*c != 'N' && *c != 'n')
874 return;
875
876 c++;
877 if (*c != 'D' && *c != 'd')
878 return;
879 }
880
881 if (maybe_begin)
882 {
883 c++;
884 if (*c != 'E' && *c != 'e')
885 return;
886
887 c++;
888 if (*c != 'G' && *c != 'g')
889 return;
890
891 c++;
892 if (*c != 'I' && *c != 'i')
893 return;
894
895 c++;
896 if (*c != 'N' && *c != 'n')
897 return;
898 }
899
900 c++;
901 while (ISSPACE (*c)) c++;
902 c1 = c;
903 while (ISALPHA (*c) || ISDIGIT (*c) || *c == '_') c++;
904
905 input_line_pointer = c;
906 if (maybe_end)
907 {
908 label_name = (char *) xmalloc ((c - c1) + strlen ("__END") + 1);
909 label_name[0] = 0;
910 strncat (label_name, c1, c-c1);
911 strcat (label_name, "__END");
912 }
913 else /* maybe_begin. */
914 {
915 label_name = (char *) xmalloc ((c - c1) + strlen ("__BEGIN") + 1);
916 label_name[0] = 0;
917 strncat (label_name, c1, c-c1);
918 strcat (label_name, "__BEGIN");
919 }
920
921 line_label = colon (label_name);
922
923 /* Loop_End follows the last instruction in the loop.
924 Adjust label address. */
925 if (maybe_end)
926 line_label->sy_value.X_add_number -= last_insn_size;
927
928}
929
930/* Special extra functions that help bfin-parse.y perform its job. */
931
932#include <stdio.h>
933#include <assert.h>
934#include <obstack.h>
935#include <bfd.h>
936#include "bfin-defs.h"
937
938struct obstack mempool;
939
940INSTR_T
941conscode (INSTR_T head, INSTR_T tail)
942{
943 if (!head)
944 return tail;
945 head->next = tail;
946 return head;
947}
948
949INSTR_T
950conctcode (INSTR_T head, INSTR_T tail)
951{
952 INSTR_T temp = (head);
953 if (!head)
954 return tail;
955 while (temp->next)
956 temp = temp->next;
957 temp->next = tail;
958
959 return head;
960}
961
962INSTR_T
963note_reloc (INSTR_T code, Expr_Node * symbol, int reloc, int pcrel)
964{
965 /* Assert that the symbol is not an operator. */
966 assert (symbol->type == Expr_Node_Reloc);
967
968 return note_reloc1 (code, symbol->value.s_value, reloc, pcrel);
969
970}
971
972INSTR_T
973note_reloc1 (INSTR_T code, const char *symbol, int reloc, int pcrel)
974{
975 code->reloc = reloc;
976 code->exp = mkexpr (0, symbol_find_or_make (symbol));
977 code->pcrel = pcrel;
978 return code;
979}
980
981INSTR_T
982note_reloc2 (INSTR_T code, const char *symbol, int reloc, int value, int pcrel)
983{
984 code->reloc = reloc;
985 code->exp = mkexpr (value, symbol_find_or_make (symbol));
986 code->pcrel = pcrel;
987 return code;
988}
989
990INSTR_T
991gencode (unsigned long x)
992{
993 INSTR_T cell = (INSTR_T) obstack_alloc (&mempool, sizeof (struct bfin_insn));
994 memset (cell, 0, sizeof (struct bfin_insn));
995 cell->value = (x);
996 return cell;
997}
998
999int reloc;
1000int ninsns;
1001int count_insns;
1002
1003static void *
1004allocate (int n)
1005{
1006 return (void *) obstack_alloc (&mempool, n);
1007}
1008
1009Expr_Node *
1010Expr_Node_Create (Expr_Node_Type type,
1011 Expr_Node_Value value,
1012 Expr_Node *Left_Child,
1013 Expr_Node *Right_Child)
1014{
1015
1016
1017 Expr_Node *node = (Expr_Node *) allocate (sizeof (Expr_Node));
1018 node->type = type;
1019 node->value = value;
1020 node->Left_Child = Left_Child;
1021 node->Right_Child = Right_Child;
1022 return node;
1023}
1024
1025static const char *con = ".__constant";
1026static const char *op = ".__operator";
1027static INSTR_T Expr_Node_Gen_Reloc_R (Expr_Node * head);
1028INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc);
1029
1030INSTR_T
1031Expr_Node_Gen_Reloc (Expr_Node * head, int parent_reloc)
1032{
1033 /* Top level reloction expression generator VDSP style.
1034 If the relocation is just by itself, generate one item
1035 else generate this convoluted expression. */
1036
1037 INSTR_T note = NULL_CODE;
1038 INSTR_T note1 = NULL_CODE;
1039 int pcrel = 1; /* Is the parent reloc pcrelative?
1040 This calculation here and HOWTO should match. */
1041
1042 if (parent_reloc)
1043 {
1044 /* If it's 32 bit quantity then 16bit code needs to be added. */
1045 int value = 0;
1046
1047 if (head->type == Expr_Node_Constant)
1048 {
1049 /* If note1 is not null code, we have to generate a right
1050 aligned value for the constant. Otherwise the reloc is
1051 a part of the basic command and the yacc file
1052 generates this. */
1053 value = head->value.i_value;
1054 }
1055 switch (parent_reloc)
1056 {
1057 /* Some reloctions will need to allocate extra words. */
1058 case BFD_RELOC_BFIN_16_IMM:
1059 case BFD_RELOC_BFIN_16_LOW:
1060 case BFD_RELOC_BFIN_16_HIGH:
1061 note1 = conscode (gencode (value), NULL_CODE);
1062 pcrel = 0;
1063 break;
1064 case BFD_RELOC_BFIN_PLTPC:
1065 note1 = conscode (gencode (value), NULL_CODE);
1066 pcrel = 0;
1067 break;
1068 case BFD_RELOC_16:
1069 case BFD_RELOC_BFIN_GOT:
1ac4baed
BS
1070 case BFD_RELOC_BFIN_GOT17M4:
1071 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
07c1b327
CM
1072 note1 = conscode (gencode (value), NULL_CODE);
1073 pcrel = 0;
1074 break;
1075 case BFD_RELOC_24_PCREL:
1076 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
1077 case BFD_RELOC_BFIN_24_PCREL_CALL_X:
1078 /* These offsets are even numbered pcrel. */
1079 note1 = conscode (gencode (value >> 1), NULL_CODE);
1080 break;
1081 default:
1082 note1 = NULL_CODE;
1083 }
1084 }
1085 if (head->type == Expr_Node_Constant)
1086 note = note1;
1087 else if (head->type == Expr_Node_Reloc)
1088 {
1089 note = note_reloc1 (gencode (0), head->value.s_value, parent_reloc, pcrel);
1090 if (note1 != NULL_CODE)
1091 note = conscode (note1, note);
1092 }
beb6bfe8
BS
1093 else if (head->type == Expr_Node_Binop
1094 && (head->value.op_value == Expr_Op_Type_Add
1095 || head->value.op_value == Expr_Op_Type_Sub)
1096 && head->Left_Child->type == Expr_Node_Reloc
1097 && head->Right_Child->type == Expr_Node_Constant)
1098 {
1099 int val = head->Right_Child->value.i_value;
1100 if (head->value.op_value == Expr_Op_Type_Sub)
1101 val = -val;
1102 note = conscode (note_reloc2 (gencode (0), head->Left_Child->value.s_value,
1103 parent_reloc, val, 0),
1104 NULL_CODE);
1105 if (note1 != NULL_CODE)
1106 note = conscode (note1, note);
1107 }
07c1b327
CM
1108 else
1109 {
1110 /* Call the recursive function. */
1111 note = note_reloc1 (gencode (0), op, parent_reloc, pcrel);
1112 if (note1 != NULL_CODE)
1113 note = conscode (note1, note);
1114 note = conctcode (Expr_Node_Gen_Reloc_R (head), note);
1115 }
1116 return note;
1117}
1118
1119static INSTR_T
1120Expr_Node_Gen_Reloc_R (Expr_Node * head)
1121{
1122
1123 INSTR_T note = 0;
1124 INSTR_T note1 = 0;
1125
1126 switch (head->type)
1127 {
1128 case Expr_Node_Constant:
1129 note = conscode (note_reloc2 (gencode (0), con, BFD_ARELOC_BFIN_CONST, head->value.i_value, 0), NULL_CODE);
1130 break;
1131 case Expr_Node_Reloc:
1132 note = conscode (note_reloc (gencode (0), head, BFD_ARELOC_BFIN_PUSH, 0), NULL_CODE);
1133 break;
1134 case Expr_Node_Binop:
1135 note1 = conctcode (Expr_Node_Gen_Reloc_R (head->Left_Child), Expr_Node_Gen_Reloc_R (head->Right_Child));
1136 switch (head->value.op_value)
1137 {
1138 case Expr_Op_Type_Add:
1139 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_ADD, 0), NULL_CODE));
1140 break;
1141 case Expr_Op_Type_Sub:
1142 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_SUB, 0), NULL_CODE));
1143 break;
1144 case Expr_Op_Type_Mult:
1145 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MULT, 0), NULL_CODE));
1146 break;
1147 case Expr_Op_Type_Div:
1148 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_DIV, 0), NULL_CODE));
1149 break;
1150 case Expr_Op_Type_Mod:
1151 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MOD, 0), NULL_CODE));
1152 break;
1153 case Expr_Op_Type_Lshift:
1154 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LSHIFT, 0), NULL_CODE));
1155 break;
1156 case Expr_Op_Type_Rshift:
1157 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_RSHIFT, 0), NULL_CODE));
1158 break;
1159 case Expr_Op_Type_BAND:
1160 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_AND, 0), NULL_CODE));
1161 break;
1162 case Expr_Op_Type_BOR:
1163 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_OR, 0), NULL_CODE));
1164 break;
1165 case Expr_Op_Type_BXOR:
1166 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_XOR, 0), NULL_CODE));
1167 break;
1168 case Expr_Op_Type_LAND:
1169 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LAND, 0), NULL_CODE));
1170 break;
1171 case Expr_Op_Type_LOR:
1172 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LOR, 0), NULL_CODE));
1173 break;
1174 default:
1175 fprintf (stderr, "%s:%d:Unkonwn operator found for arithmetic" " relocation", __FILE__, __LINE__);
1176
1177
1178 }
1179 break;
1180 case Expr_Node_Unop:
1181 note1 = conscode (Expr_Node_Gen_Reloc_R (head->Left_Child), NULL_CODE);
1182 switch (head->value.op_value)
1183 {
1184 case Expr_Op_Type_NEG:
1185 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_NEG, 0), NULL_CODE));
1186 break;
1187 case Expr_Op_Type_COMP:
1188 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_COMP, 0), NULL_CODE));
1189 break;
1190 default:
1191 fprintf (stderr, "%s:%d:Unkonwn operator found for arithmetic" " relocation", __FILE__, __LINE__);
1192 }
1193 break;
1194 default:
1195 fprintf (stderr, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__, __LINE__);
1196 }
1197 return note;
1198}
1199
1200
1201/* Blackfin opcode generation. */
1202
1203/* These functions are called by the generated parser
1204 (from bfin-parse.y), the register type classification
1205 happens in bfin-lex.l. */
1206
1207#include "bfin-aux.h"
1208#include "opcode/bfin.h"
1209
1210#define INIT(t) t c_code = init_##t
1211#define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1212#define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1213
1214#define HI(x) ((x >> 16) & 0xffff)
1215#define LO(x) ((x ) & 0xffff)
1216
1217#define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1218
1219#define GEN_OPCODE32() \
1220 conscode (gencode (HI (c_code.opcode)), \
1221 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1222
1223#define GEN_OPCODE16() \
1224 conscode (gencode (c_code.opcode), NULL_CODE)
1225
1226
1227/* 32 BIT INSTRUCTIONS. */
1228
1229
1230/* DSP32 instruction generation. */
1231
1232INSTR_T
1233bfin_gen_dsp32mac (int op1, int MM, int mmod, int w1, int P,
1234 int h01, int h11, int h00, int h10, int op0,
1235 REG_T dst, REG_T src0, REG_T src1, int w0)
1236{
1237 INIT (DSP32Mac);
1238
1239 ASSIGN (op0);
1240 ASSIGN (op1);
1241 ASSIGN (MM);
1242 ASSIGN (mmod);
1243 ASSIGN (w0);
1244 ASSIGN (w1);
1245 ASSIGN (h01);
1246 ASSIGN (h11);
1247 ASSIGN (h00);
1248 ASSIGN (h10);
1249 ASSIGN (P);
1250
1251 /* If we have full reg assignments, mask out LSB to encode
1252 single or simultaneous even/odd register moves. */
1253 if (P)
1254 {
1255 dst->regno &= 0x06;
1256 }
1257
1258 ASSIGN_R (dst);
1259 ASSIGN_R (src0);
1260 ASSIGN_R (src1);
1261
1262 return GEN_OPCODE32 ();
1263}
1264
1265INSTR_T
1266bfin_gen_dsp32mult (int op1, int MM, int mmod, int w1, int P,
1267 int h01, int h11, int h00, int h10, int op0,
1268 REG_T dst, REG_T src0, REG_T src1, int w0)
1269{
1270 INIT (DSP32Mult);
1271
1272 ASSIGN (op0);
1273 ASSIGN (op1);
1274 ASSIGN (MM);
1275 ASSIGN (mmod);
1276 ASSIGN (w0);
1277 ASSIGN (w1);
1278 ASSIGN (h01);
1279 ASSIGN (h11);
1280 ASSIGN (h00);
1281 ASSIGN (h10);
1282 ASSIGN (P);
1283
1284 if (P)
1285 {
1286 dst->regno &= 0x06;
1287 }
1288
1289 ASSIGN_R (dst);
1290 ASSIGN_R (src0);
1291 ASSIGN_R (src1);
1292
1293 return GEN_OPCODE32 ();
1294}
1295
1296INSTR_T
1297bfin_gen_dsp32alu (int HL, int aopcde, int aop, int s, int x,
1298 REG_T dst0, REG_T dst1, REG_T src0, REG_T src1)
1299{
1300 INIT (DSP32Alu);
1301
1302 ASSIGN (HL);
1303 ASSIGN (aopcde);
1304 ASSIGN (aop);
1305 ASSIGN (s);
1306 ASSIGN (x);
1307 ASSIGN_R (dst0);
1308 ASSIGN_R (dst1);
1309 ASSIGN_R (src0);
1310 ASSIGN_R (src1);
1311
1312 return GEN_OPCODE32 ();
1313}
1314
1315INSTR_T
1316bfin_gen_dsp32shift (int sopcde, REG_T dst0, REG_T src0,
1317 REG_T src1, int sop, int HLs)
1318{
1319 INIT (DSP32Shift);
1320
1321 ASSIGN (sopcde);
1322 ASSIGN (sop);
1323 ASSIGN (HLs);
1324
1325 ASSIGN_R (dst0);
1326 ASSIGN_R (src0);
1327 ASSIGN_R (src1);
1328
1329 return GEN_OPCODE32 ();
1330}
1331
1332INSTR_T
1333bfin_gen_dsp32shiftimm (int sopcde, REG_T dst0, int immag,
1334 REG_T src1, int sop, int HLs)
1335{
1336 INIT (DSP32ShiftImm);
1337
1338 ASSIGN (sopcde);
1339 ASSIGN (sop);
1340 ASSIGN (HLs);
1341
1342 ASSIGN_R (dst0);
1343 ASSIGN (immag);
1344 ASSIGN_R (src1);
1345
1346 return GEN_OPCODE32 ();
1347}
1348
1349/* LOOP SETUP. */
1350
1351INSTR_T
1352bfin_gen_loopsetup (Expr_Node * psoffset, REG_T c, int rop,
1353 Expr_Node * peoffset, REG_T reg)
1354{
1355 int soffset, eoffset;
1356 INIT (LoopSetup);
1357
1358 soffset = (EXPR_VALUE (psoffset) >> 1);
1359 ASSIGN (soffset);
1360 eoffset = (EXPR_VALUE (peoffset) >> 1);
1361 ASSIGN (eoffset);
1362 ASSIGN (rop);
1363 ASSIGN_R (c);
1364 ASSIGN_R (reg);
1365
1366 return
1367 conscode (gencode (HI (c_code.opcode)),
1368 conctcode (Expr_Node_Gen_Reloc (psoffset, BFD_RELOC_BFIN_5_PCREL),
1369 conctcode (gencode (LO (c_code.opcode)), Expr_Node_Gen_Reloc (peoffset, BFD_RELOC_BFIN_11_PCREL))));
1370
1371}
1372
1373/* Call, Link. */
1374
1375INSTR_T
1376bfin_gen_calla (Expr_Node * addr, int S)
1377{
1378 int val;
1379 int high_val;
1380 int reloc = 0;
1381 INIT (CALLa);
1382
1383 switch(S){
1384 case 0 : reloc = BFD_RELOC_BFIN_24_PCREL_JUMP_L; break;
1385 case 1 : reloc = BFD_RELOC_24_PCREL; break;
1386 case 2 : reloc = BFD_RELOC_BFIN_PLTPC; break;
1387 default : break;
1388 }
1389
1390 ASSIGN (S);
1391
1392 val = EXPR_VALUE (addr) >> 1;
1393 high_val = val >> 16;
1394
1395 return conscode (gencode (HI (c_code.opcode) | (high_val & 0xff)),
1396 Expr_Node_Gen_Reloc (addr, reloc));
1397 }
1398
1399INSTR_T
1400bfin_gen_linkage (int R, int framesize)
1401{
1402 INIT (Linkage);
1403
1404 ASSIGN (R);
1405 ASSIGN (framesize);
1406
1407 return GEN_OPCODE32 ();
1408}
1409
1410
1411/* Load and Store. */
1412
1413INSTR_T
1414bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int reloc)
1415{
1416 int grp, hword;
1417 unsigned val = EXPR_VALUE (phword);
1418 INIT (LDIMMhalf);
1419
1420 ASSIGN (H);
1421 ASSIGN (S);
1422 ASSIGN (Z);
1423
1424 ASSIGN_R (reg);
1425 grp = (GROUP (reg));
1426 ASSIGN (grp);
1427 if (reloc == 2)
1428 {
1429 return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, BFD_RELOC_BFIN_16_IMM));
1430 }
1431 else if (reloc == 1)
1432 {
1433 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));
1434 }
1435 else
1436 {
1437 hword = val;
1438 ASSIGN (hword);
1439 }
1440 return GEN_OPCODE32 ();
1441}
1442
1443INSTR_T
1444bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset)
1445{
07c1b327
CM
1446 INIT (LDSTidxI);
1447
1448 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1449 {
1450 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1451 return 0;
1452 }
1453
1454 ASSIGN_R (ptr);
1455 ASSIGN_R (reg);
1456 ASSIGN (W);
1457 ASSIGN (sz);
07c1b327
CM
1458
1459 ASSIGN (Z);
1460
1ac4baed
BS
1461 if (poffset->type != Expr_Node_Constant)
1462 {
1463 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1464 /* distinguish between R0 = [P5 + symbol@GOT] and
1465 P5 = [P5 + _current_shared_library_p5_offset_]
1466 */
1467 if (poffset->type == Expr_Node_Reloc
1468 && !strcmp (poffset->value.s_value,
1469 "_current_shared_library_p5_offset_"))
1470 {
1471 return conscode (gencode (HI (c_code.opcode)),
1472 Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16));
1473 }
1474 else if (poffset->type != Expr_Node_GOT_Reloc)
1475 abort ();
1476
1477 return conscode (gencode (HI (c_code.opcode)),
1478 Expr_Node_Gen_Reloc(poffset->Left_Child,
1479 poffset->value.i_value));
07c1b327 1480 }
1ac4baed 1481 else
07c1b327 1482 {
1ac4baed
BS
1483 int value, offset;
1484 switch (sz)
1485 { // load/store access size
1486 case 0: // 32 bit
1487 value = EXPR_VALUE (poffset) >> 2;
1488 break;
1489 case 1: // 16 bit
1490 value = EXPR_VALUE (poffset) >> 1;
1491 break;
1492 case 2: // 8 bit
1493 value = EXPR_VALUE (poffset);
1494 break;
1495 default:
1496 abort ();
1497 }
1498
1499 offset = (value & 0xffff);
1500 ASSIGN (offset);
1501 return GEN_OPCODE32 ();
07c1b327 1502 }
07c1b327
CM
1503}
1504
1505
1506INSTR_T
1507bfin_gen_ldst (REG_T ptr, REG_T reg, int aop, int sz, int Z, int W)
1508{
1509 INIT (LDST);
1510
1511 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1512 {
1513 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1514 return 0;
1515 }
1516
1517 ASSIGN_R (ptr);
1518 ASSIGN_R (reg);
1519 ASSIGN (aop);
1520 ASSIGN (sz);
1521 ASSIGN (Z);
1522 ASSIGN (W);
1523
1524 return GEN_OPCODE16 ();
1525}
1526
1527INSTR_T
1528bfin_gen_ldstii (REG_T ptr, REG_T reg, Expr_Node * poffset, int W, int op)
1529{
1530 int offset;
1531 int value = 0;
1532 INIT (LDSTii);
1533
1534
1535 if (!IS_PREG (*ptr))
1536 {
1537 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1538 return 0;
1539 }
1540
1541 switch (op)
1542 {
1543 case 1:
1544 case 2:
1545 value = EXPR_VALUE (poffset) >> 1;
1546 break;
1547 case 0:
1548 case 3:
1549 value = EXPR_VALUE (poffset) >> 2;
1550 break;
1551 }
1552
1553 ASSIGN_R (ptr);
1554 ASSIGN_R (reg);
1555
1556 offset = value;
1557 ASSIGN (offset);
1558 ASSIGN (W);
1559 ASSIGN (op);
1560
1561 return GEN_OPCODE16 ();
1562}
1563
1564INSTR_T
1565bfin_gen_ldstiifp (REG_T sreg, Expr_Node * poffset, int W)
1566{
1567 /* Set bit 4 if it's a Preg. */
1568 int reg = (sreg->regno & CODE_MASK) | (IS_PREG (*sreg) ? 0x8 : 0x0);
1569 int offset = ((~(EXPR_VALUE (poffset) >> 2)) & 0x1f) + 1;
1570 INIT (LDSTiiFP);
1571 ASSIGN (reg);
1572 ASSIGN (offset);
1573 ASSIGN (W);
1574
1575 return GEN_OPCODE16 ();
1576}
1577
1578INSTR_T
1579bfin_gen_ldstpmod (REG_T ptr, REG_T reg, int aop, int W, REG_T idx)
1580{
1581 INIT (LDSTpmod);
1582
1583 ASSIGN_R (ptr);
1584 ASSIGN_R (reg);
1585 ASSIGN (aop);
1586 ASSIGN (W);
1587 ASSIGN_R (idx);
1588
1589 return GEN_OPCODE16 ();
1590}
1591
1592INSTR_T
1593bfin_gen_dspldst (REG_T i, REG_T reg, int aop, int W, int m)
1594{
1595 INIT (DspLDST);
1596
1597 ASSIGN_R (i);
1598 ASSIGN_R (reg);
1599 ASSIGN (aop);
1600 ASSIGN (W);
1601 ASSIGN (m);
1602
1603 return GEN_OPCODE16 ();
1604}
1605
1606INSTR_T
1607bfin_gen_logi2op (int opc, int src, int dst)
1608{
1609 INIT (LOGI2op);
1610
1611 ASSIGN (opc);
1612 ASSIGN (src);
1613 ASSIGN (dst);
1614
1615 return GEN_OPCODE16 ();
1616}
1617
1618INSTR_T
1619bfin_gen_brcc (int T, int B, Expr_Node * poffset)
1620{
1621 int offset;
1622 INIT (BRCC);
1623
1624 ASSIGN (T);
1625 ASSIGN (B);
1626 offset = ((EXPR_VALUE (poffset) >> 1));
1627 ASSIGN (offset);
1628 return conscode (gencode (c_code.opcode), Expr_Node_Gen_Reloc (poffset, BFD_RELOC_BFIN_10_PCREL));
1629}
1630
1631INSTR_T
1632bfin_gen_ujump (Expr_Node * poffset)
1633{
1634 int offset;
1635 INIT (UJump);
1636
1637 offset = ((EXPR_VALUE (poffset) >> 1));
1638 ASSIGN (offset);
1639
1640 return conscode (gencode (c_code.opcode),
1641 Expr_Node_Gen_Reloc (
1642 poffset, BFD_RELOC_BFIN_12_PCREL_JUMP_S));
1643}
1644
1645INSTR_T
1646bfin_gen_alu2op (REG_T dst, REG_T src, int opc)
1647{
1648 INIT (ALU2op);
1649
1650 ASSIGN_R (dst);
1651 ASSIGN_R (src);
1652 ASSIGN (opc);
1653
1654 return GEN_OPCODE16 ();
1655}
1656
1657INSTR_T
1658bfin_gen_compi2opd (REG_T dst, int src, int op)
1659{
1660 INIT (COMPI2opD);
1661
1662 ASSIGN_R (dst);
1663 ASSIGN (src);
1664 ASSIGN (op);
1665
1666 return GEN_OPCODE16 ();
1667}
1668
1669INSTR_T
1670bfin_gen_compi2opp (REG_T dst, int src, int op)
1671{
1672 INIT (COMPI2opP);
1673
1674 ASSIGN_R (dst);
1675 ASSIGN (src);
1676 ASSIGN (op);
1677
1678 return GEN_OPCODE16 ();
1679}
1680
1681INSTR_T
1682bfin_gen_dagmodik (REG_T i, int op)
1683{
1684 INIT (DagMODik);
1685
1686 ASSIGN_R (i);
1687 ASSIGN (op);
1688
1689 return GEN_OPCODE16 ();
1690}
1691
1692INSTR_T
1693bfin_gen_dagmodim (REG_T i, REG_T m, int op, int br)
1694{
1695 INIT (DagMODim);
1696
1697 ASSIGN_R (i);
1698 ASSIGN_R (m);
1699 ASSIGN (op);
1700 ASSIGN (br);
1701
1702 return GEN_OPCODE16 ();
1703}
1704
1705INSTR_T
1706bfin_gen_ptr2op (REG_T dst, REG_T src, int opc)
1707{
1708 INIT (PTR2op);
1709
1710 ASSIGN_R (dst);
1711 ASSIGN_R (src);
1712 ASSIGN (opc);
1713
1714 return GEN_OPCODE16 ();
1715}
1716
1717INSTR_T
1718bfin_gen_comp3op (REG_T src0, REG_T src1, REG_T dst, int opc)
1719{
1720 INIT (COMP3op);
1721
1722 ASSIGN_R (src0);
1723 ASSIGN_R (src1);
1724 ASSIGN_R (dst);
1725 ASSIGN (opc);
1726
1727 return GEN_OPCODE16 ();
1728}
1729
1730INSTR_T
1731bfin_gen_ccflag (REG_T x, int y, int opc, int I, int G)
1732{
1733 INIT (CCflag);
1734
1735 ASSIGN_R (x);
1736 ASSIGN (y);
1737 ASSIGN (opc);
1738 ASSIGN (I);
1739 ASSIGN (G);
1740
1741 return GEN_OPCODE16 ();
1742}
1743
1744INSTR_T
1745bfin_gen_ccmv (REG_T src, REG_T dst, int T)
1746{
1747 int s, d;
1748 INIT (CCmv);
1749
1750 ASSIGN_R (src);
1751 ASSIGN_R (dst);
1752 s = (GROUP (src));
1753 ASSIGN (s);
1754 d = (GROUP (dst));
1755 ASSIGN (d);
1756 ASSIGN (T);
1757
1758 return GEN_OPCODE16 ();
1759}
1760
1761INSTR_T
1762bfin_gen_cc2stat (int cbit, int op, int D)
1763{
1764 INIT (CC2stat);
1765
1766 ASSIGN (cbit);
1767 ASSIGN (op);
1768 ASSIGN (D);
1769
1770 return GEN_OPCODE16 ();
1771}
1772
1773INSTR_T
1774bfin_gen_regmv (REG_T src, REG_T dst)
1775{
1776 int gs, gd;
1777 INIT (RegMv);
1778
1779 ASSIGN_R (src);
1780 ASSIGN_R (dst);
1781
1782 gs = (GROUP (src));
1783 ASSIGN (gs);
1784 gd = (GROUP (dst));
1785 ASSIGN (gd);
1786
1787 return GEN_OPCODE16 ();
1788}
1789
1790INSTR_T
1791bfin_gen_cc2dreg (int op, REG_T reg)
1792{
1793 INIT (CC2dreg);
1794
1795 ASSIGN (op);
1796 ASSIGN_R (reg);
1797
1798 return GEN_OPCODE16 ();
1799}
1800
1801INSTR_T
1802bfin_gen_progctrl (int prgfunc, int poprnd)
1803{
1804 INIT (ProgCtrl);
1805
1806 ASSIGN (prgfunc);
1807 ASSIGN (poprnd);
1808
1809 return GEN_OPCODE16 ();
1810}
1811
1812INSTR_T
1813bfin_gen_cactrl (REG_T reg, int a, int op)
1814{
1815 INIT (CaCTRL);
1816
1817 ASSIGN_R (reg);
1818 ASSIGN (a);
1819 ASSIGN (op);
1820
1821 return GEN_OPCODE16 ();
1822}
1823
1824INSTR_T
1825bfin_gen_pushpopmultiple (int dr, int pr, int d, int p, int W)
1826{
1827 INIT (PushPopMultiple);
1828
1829 ASSIGN (dr);
1830 ASSIGN (pr);
1831 ASSIGN (d);
1832 ASSIGN (p);
1833 ASSIGN (W);
1834
1835 return GEN_OPCODE16 ();
1836}
1837
1838INSTR_T
1839bfin_gen_pushpopreg (REG_T reg, int W)
1840{
1841 int grp;
1842 INIT (PushPopReg);
1843
1844 ASSIGN_R (reg);
1845 grp = (GROUP (reg));
1846 ASSIGN (grp);
1847 ASSIGN (W);
1848
1849 return GEN_OPCODE16 ();
1850}
1851
1852/* Pseudo Debugging Support. */
1853
1854INSTR_T
1855bfin_gen_pseudodbg (int fn, int reg, int grp)
1856{
1857 INIT (PseudoDbg);
1858
1859 ASSIGN (fn);
1860 ASSIGN (reg);
1861 ASSIGN (grp);
1862
1863 return GEN_OPCODE16 ();
1864}
1865
1866INSTR_T
1867bfin_gen_pseudodbg_assert (int dbgop, REG_T regtest, int expected)
1868{
1869 INIT (PseudoDbg_Assert);
1870
1871 ASSIGN (dbgop);
1872 ASSIGN_R (regtest);
1873 ASSIGN (expected);
1874
1875 return GEN_OPCODE32 ();
1876}
1877
1878/* Multiple instruction generation. */
1879
1880INSTR_T
1881bfin_gen_multi_instr (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2)
1882{
1883 INSTR_T walk;
1884
1885 /* If it's a 0, convert into MNOP. */
1886 if (dsp32)
1887 {
1888 walk = dsp32->next;
1889 SET_MULTI_INSTRUCTION_BIT (dsp32);
1890 }
1891 else
1892 {
1893 dsp32 = gencode (0xc803);
1894 walk = gencode (0x1800);
1895 dsp32->next = walk;
1896 }
1897
1898 if (!dsp16_grp1)
1899 {
1900 dsp16_grp1 = gencode (0x0000);
1901 }
1902
1903 if (!dsp16_grp2)
1904 {
1905 dsp16_grp2 = gencode (0x0000);
1906 }
1907
1908 walk->next = dsp16_grp1;
1909 dsp16_grp1->next = dsp16_grp2;
1910 dsp16_grp2->next = NULL_CODE;
1911
1912 return dsp32;
1913}
1914
1915INSTR_T
1916bfin_gen_loop (Expr_Node *expr, REG_T reg, int rop, REG_T preg)
1917{
1918 const char *loopsym;
1919 char *lbeginsym, *lendsym;
1920 Expr_Node_Value lbeginval, lendval;
1921 Expr_Node *lbegin, *lend;
1922
1923 loopsym = expr->value.s_value;
1924 lbeginsym = (char *) xmalloc (strlen (loopsym) + strlen ("__BEGIN") + 1);
1925 lendsym = (char *) xmalloc (strlen (loopsym) + strlen ("__END") + 1);
1926
1927 lbeginsym[0] = 0;
1928 lendsym[0] = 0;
1929
1930 strcat (lbeginsym, loopsym);
1931 strcat (lbeginsym, "__BEGIN");
1932
1933 strcat (lendsym, loopsym);
1934 strcat (lendsym, "__END");
1935
1936 lbeginval.s_value = lbeginsym;
1937 lendval.s_value = lendsym;
1938
1939 lbegin = Expr_Node_Create (Expr_Node_Reloc, lbeginval, NULL, NULL);
1940 lend = Expr_Node_Create (Expr_Node_Reloc, lendval, NULL, NULL);
1941 return bfin_gen_loopsetup(lbegin, reg, rop, lend, preg);
1942}
1943
1944bfd_boolean
1945bfin_eol_in_insn (char *line)
1946{
1947 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1948
1949 char *temp = line;
1950
1951 if (*line != '\n')
1952 return FALSE;
1953
1954 /* A semi-colon followed by a newline is always the end of a line. */
1955 if (line[-1] == ';')
1956 return FALSE;
1957
1958 if (line[-1] == '|')
1959 return TRUE;
1960
1961 /* If the || is on the next line, there might be leading whitespace. */
1962 temp++;
1963 while (*temp == ' ' || *temp == '\t') temp++;
1964
1965 if (*temp == '|')
1966 return TRUE;
1967
1968 return FALSE;
1969}
1970
1971bfd_boolean
1972bfin_name_is_register (char *name)
1973{
1974 int i;
1975
1976 if (*name == '[' || *name == '(')
1977 return TRUE;
1978
1979 if ((name[0] == 'W' || name[0] == 'w') && name[1] == '[')
1980 return TRUE;
1981
1982 if ((name[0] == 'B' || name[0] == 'b') && name[1] == '[')
1983 return TRUE;
1984
07c1b327
CM
1985 for (i=0; bfin_reg_info[i].name != 0; i++)
1986 {
1987 if (!strcasecmp (bfin_reg_info[i].name, name))
1988 return TRUE;
1989 }
1990 return FALSE;
1991}
1992
1993void
1994bfin_equals (Expr_Node *sym)
1995{
1996 char *c;
1997
1998 c = input_line_pointer;
1999 while (*c != '=')
2000 c--;
2001
2002 input_line_pointer = c;
2003
2004 equals ((char *) sym->value.s_value, 1);
2005}
2006
2007bfd_boolean
2008bfin_start_label (char *ptr)
2009{
2010 ptr--;
2011 while (!ISSPACE (*ptr) && !is_end_of_line[(unsigned char) *ptr])
2012 ptr--;
2013
2014 ptr++;
2015 if (*ptr == '(' || *ptr == '[')
2016 return FALSE;
2017
07c1b327
CM
2018 return TRUE;
2019}
2020
2021int
2022bfin_force_relocation (struct fix *fixp)
2023{
2024 if (fixp->fx_r_type ==BFD_RELOC_BFIN_16_LOW
2025 || fixp->fx_r_type == BFD_RELOC_BFIN_16_HIGH)
2026 return TRUE;
2027
2028 return generic_force_reloc (fixp);
2029}