Move entries for changes in sub-directories into the changelogs in those sub-
[binutils.git] / gas / config / tc-bfin.c
blob4652efa81161804c1064e5d1117503d278462a13
1 /* tc-bfin.c -- Assembler for the ADI Blackfin.
2 Copyright 2005, 2006, 2007
3 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
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 3, or (at your option)
10 any later version.
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.
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. */
22 #include "as.h"
23 #include "struc-symbol.h"
24 #include "bfin-defs.h"
25 #include "obstack.h"
26 #include "safe-ctype.h"
27 #ifdef OBJ_ELF
28 #include "dwarf2dbg.h"
29 #endif
30 #include "libbfd.h"
31 #include "elf/common.h"
32 #include "elf/bfin.h"
34 extern int yyparse (void);
35 struct yy_buffer_state;
36 typedef struct yy_buffer_state *YY_BUFFER_STATE;
37 extern YY_BUFFER_STATE yy_scan_string (const char *yy_str);
38 extern void yy_delete_buffer (YY_BUFFER_STATE b);
39 static parse_state parse (char *line);
40 static void bfin_s_bss PARAMS ((int));
41 static int md_chars_to_number PARAMS ((char *, int));
43 /* Global variables. */
44 struct bfin_insn *insn;
45 int last_insn_size;
47 extern struct obstack mempool;
48 FILE *errorf;
50 /* Flags to set in the elf header */
51 #define DEFAULT_FLAGS 0
53 static flagword bfin_flags = DEFAULT_FLAGS;
54 static const char *bfin_pic_flag = (const char *)0;
56 /* Registers list. */
57 struct bfin_reg_entry
59 const char *name;
60 int number;
63 static const struct bfin_reg_entry bfin_reg_info[] = {
64 {"R0.L", REG_RL0},
65 {"R1.L", REG_RL1},
66 {"R2.L", REG_RL2},
67 {"R3.L", REG_RL3},
68 {"R4.L", REG_RL4},
69 {"R5.L", REG_RL5},
70 {"R6.L", REG_RL6},
71 {"R7.L", REG_RL7},
72 {"R0.H", REG_RH0},
73 {"R1.H", REG_RH1},
74 {"R2.H", REG_RH2},
75 {"R3.H", REG_RH3},
76 {"R4.H", REG_RH4},
77 {"R5.H", REG_RH5},
78 {"R6.H", REG_RH6},
79 {"R7.H", REG_RH7},
80 {"R0", REG_R0},
81 {"R1", REG_R1},
82 {"R2", REG_R2},
83 {"R3", REG_R3},
84 {"R4", REG_R4},
85 {"R5", REG_R5},
86 {"R6", REG_R6},
87 {"R7", REG_R7},
88 {"P0", REG_P0},
89 {"P0.H", REG_P0},
90 {"P0.L", REG_P0},
91 {"P1", REG_P1},
92 {"P1.H", REG_P1},
93 {"P1.L", REG_P1},
94 {"P2", REG_P2},
95 {"P2.H", REG_P2},
96 {"P2.L", REG_P2},
97 {"P3", REG_P3},
98 {"P3.H", REG_P3},
99 {"P3.L", REG_P3},
100 {"P4", REG_P4},
101 {"P4.H", REG_P4},
102 {"P4.L", REG_P4},
103 {"P5", REG_P5},
104 {"P5.H", REG_P5},
105 {"P5.L", REG_P5},
106 {"SP", REG_SP},
107 {"SP.L", REG_SP},
108 {"SP.H", REG_SP},
109 {"FP", REG_FP},
110 {"FP.L", REG_FP},
111 {"FP.H", REG_FP},
112 {"A0x", REG_A0x},
113 {"A1x", REG_A1x},
114 {"A0w", REG_A0w},
115 {"A1w", REG_A1w},
116 {"A0.x", REG_A0x},
117 {"A1.x", REG_A1x},
118 {"A0.w", REG_A0w},
119 {"A1.w", REG_A1w},
120 {"A0", REG_A0},
121 {"A0.L", REG_A0},
122 {"A0.H", REG_A0},
123 {"A1", REG_A1},
124 {"A1.L", REG_A1},
125 {"A1.H", REG_A1},
126 {"I0", REG_I0},
127 {"I0.L", REG_I0},
128 {"I0.H", REG_I0},
129 {"I1", REG_I1},
130 {"I1.L", REG_I1},
131 {"I1.H", REG_I1},
132 {"I2", REG_I2},
133 {"I2.L", REG_I2},
134 {"I2.H", REG_I2},
135 {"I3", REG_I3},
136 {"I3.L", REG_I3},
137 {"I3.H", REG_I3},
138 {"M0", REG_M0},
139 {"M0.H", REG_M0},
140 {"M0.L", REG_M0},
141 {"M1", REG_M1},
142 {"M1.H", REG_M1},
143 {"M1.L", REG_M1},
144 {"M2", REG_M2},
145 {"M2.H", REG_M2},
146 {"M2.L", REG_M2},
147 {"M3", REG_M3},
148 {"M3.H", REG_M3},
149 {"M3.L", REG_M3},
150 {"B0", REG_B0},
151 {"B0.H", REG_B0},
152 {"B0.L", REG_B0},
153 {"B1", REG_B1},
154 {"B1.H", REG_B1},
155 {"B1.L", REG_B1},
156 {"B2", REG_B2},
157 {"B2.H", REG_B2},
158 {"B2.L", REG_B2},
159 {"B3", REG_B3},
160 {"B3.H", REG_B3},
161 {"B3.L", REG_B3},
162 {"L0", REG_L0},
163 {"L0.H", REG_L0},
164 {"L0.L", REG_L0},
165 {"L1", REG_L1},
166 {"L1.H", REG_L1},
167 {"L1.L", REG_L1},
168 {"L2", REG_L2},
169 {"L2.H", REG_L2},
170 {"L2.L", REG_L2},
171 {"L3", REG_L3},
172 {"L3.H", REG_L3},
173 {"L3.L", REG_L3},
174 {"AZ", S_AZ},
175 {"AN", S_AN},
176 {"AC0", S_AC0},
177 {"AC1", S_AC1},
178 {"AV0", S_AV0},
179 {"AV0S", S_AV0S},
180 {"AV1", S_AV1},
181 {"AV1S", S_AV1S},
182 {"AQ", S_AQ},
183 {"V", S_V},
184 {"VS", S_VS},
185 {"sftreset", REG_sftreset},
186 {"omode", REG_omode},
187 {"excause", REG_excause},
188 {"emucause", REG_emucause},
189 {"idle_req", REG_idle_req},
190 {"hwerrcause", REG_hwerrcause},
191 {"CC", REG_CC},
192 {"LC0", REG_LC0},
193 {"LC1", REG_LC1},
194 {"ASTAT", REG_ASTAT},
195 {"RETS", REG_RETS},
196 {"LT0", REG_LT0},
197 {"LB0", REG_LB0},
198 {"LT1", REG_LT1},
199 {"LB1", REG_LB1},
200 {"CYCLES", REG_CYCLES},
201 {"CYCLES2", REG_CYCLES2},
202 {"USP", REG_USP},
203 {"SEQSTAT", REG_SEQSTAT},
204 {"SYSCFG", REG_SYSCFG},
205 {"RETI", REG_RETI},
206 {"RETX", REG_RETX},
207 {"RETN", REG_RETN},
208 {"RETE", REG_RETE},
209 {"EMUDAT", REG_EMUDAT},
210 {0, 0}
213 /* Blackfin specific function to handle FD-PIC pointer initializations. */
215 static void
216 bfin_pic_ptr (int nbytes)
218 expressionS exp;
219 char *p;
221 if (nbytes != 4)
222 abort ();
224 #ifdef md_flush_pending_output
225 md_flush_pending_output ();
226 #endif
228 if (is_it_end_of_statement ())
230 demand_empty_rest_of_line ();
231 return;
234 #ifdef md_cons_align
235 md_cons_align (nbytes);
236 #endif
240 bfd_reloc_code_real_type reloc_type = BFD_RELOC_BFIN_FUNCDESC;
242 if (strncasecmp (input_line_pointer, "funcdesc(", 9) == 0)
244 input_line_pointer += 9;
245 expression (&exp);
246 if (*input_line_pointer == ')')
247 input_line_pointer++;
248 else
249 as_bad (_("missing ')'"));
251 else
252 error ("missing funcdesc in picptr");
254 p = frag_more (4);
255 memset (p, 0, 4);
256 fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
257 reloc_type);
259 while (*input_line_pointer++ == ',');
261 input_line_pointer--; /* Put terminator back into stream. */
262 demand_empty_rest_of_line ();
265 static void
266 bfin_s_bss (int ignore ATTRIBUTE_UNUSED)
268 register int temp;
270 temp = get_absolute_expression ();
271 subseg_set (bss_section, (subsegT) temp);
272 demand_empty_rest_of_line ();
275 const pseudo_typeS md_pseudo_table[] = {
276 {"align", s_align_bytes, 0},
277 {"byte2", cons, 2},
278 {"byte4", cons, 4},
279 {"picptr", bfin_pic_ptr, 4},
280 {"code", obj_elf_section, 0},
281 {"db", cons, 1},
282 {"dd", cons, 4},
283 {"dw", cons, 2},
284 {"p", s_ignore, 0},
285 {"pdata", s_ignore, 0},
286 {"var", s_ignore, 0},
287 {"bss", bfin_s_bss, 0},
288 {0, 0, 0}
291 /* Characters that are used to denote comments and line separators. */
292 const char comment_chars[] = "";
293 const char line_comment_chars[] = "#";
294 const char line_separator_chars[] = ";";
296 /* Characters that can be used to separate the mantissa from the
297 exponent in floating point numbers. */
298 const char EXP_CHARS[] = "eE";
300 /* Characters that mean this number is a floating point constant.
301 As in 0f12.456 or 0d1.2345e12. */
302 const char FLT_CHARS[] = "fFdDxX";
304 /* Define bfin-specific command-line options (there are none). */
305 const char *md_shortopts = "";
307 #define OPTION_FDPIC (OPTION_MD_BASE)
309 struct option md_longopts[] =
311 { "mfdpic", no_argument, NULL, OPTION_FDPIC },
312 { NULL, no_argument, NULL, 0 },
315 size_t md_longopts_size = sizeof (md_longopts);
319 md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
321 switch (c)
323 default:
324 return 0;
326 case OPTION_FDPIC:
327 bfin_flags |= EF_BFIN_FDPIC;
328 bfin_pic_flag = "-mfdpic";
329 break;
332 return 1;
335 void
336 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
338 fprintf (stream, _(" BFIN specific command line options:\n"));
341 /* Perform machine-specific initializations. */
342 void
343 md_begin ()
345 /* Set the ELF flags if desired. */
346 if (bfin_flags)
347 bfd_set_private_flags (stdoutput, bfin_flags);
349 /* Set the default machine type. */
350 if (!bfd_set_arch_mach (stdoutput, bfd_arch_bfin, 0))
351 as_warn (_("Could not set architecture and machine."));
353 /* Ensure that lines can begin with '(', for multiple
354 register stack pops. */
355 lex_type ['('] = LEX_BEGIN_NAME;
357 #ifdef OBJ_ELF
358 record_alignment (text_section, 2);
359 record_alignment (data_section, 2);
360 record_alignment (bss_section, 2);
361 #endif
363 errorf = stderr;
364 obstack_init (&mempool);
366 #ifdef DEBUG
367 extern int debug_codeselection;
368 debug_codeselection = 1;
369 #endif
371 last_insn_size = 0;
374 /* Perform the main parsing, and assembly of the input here. Also,
375 call the required routines for alignment and fixups here.
376 This is called for every line that contains real assembly code. */
378 void
379 md_assemble (char *line)
381 char *toP = 0;
382 extern char *current_inputline;
383 int size, insn_size;
384 struct bfin_insn *tmp_insn;
385 size_t len;
386 static size_t buffer_len = 0;
387 parse_state state;
389 len = strlen (line);
390 if (len + 2 > buffer_len)
392 if (buffer_len > 0)
393 free (current_inputline);
394 buffer_len = len + 40;
395 current_inputline = xmalloc (buffer_len);
397 memcpy (current_inputline, line, len);
398 current_inputline[len] = ';';
399 current_inputline[len + 1] = '\0';
401 state = parse (current_inputline);
402 if (state == NO_INSN_GENERATED)
403 return;
405 for (insn_size = 0, tmp_insn = insn; tmp_insn; tmp_insn = tmp_insn->next)
406 if (!tmp_insn->reloc || !tmp_insn->exp->symbol)
407 insn_size += 2;
409 if (insn_size)
410 toP = frag_more (insn_size);
412 last_insn_size = insn_size;
414 #ifdef DEBUG
415 printf ("INS:");
416 #endif
417 while (insn)
419 if (insn->reloc && insn->exp->symbol)
421 char *prev_toP = toP - 2;
422 switch (insn->reloc)
424 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
425 case BFD_RELOC_24_PCREL:
426 case BFD_RELOC_BFIN_16_LOW:
427 case BFD_RELOC_BFIN_16_HIGH:
428 size = 4;
429 break;
430 default:
431 size = 2;
434 /* Following if condition checks for the arithmetic relocations.
435 If the case then it doesn't required to generate the code.
436 It has been assumed that, their ID will be contiguous. */
437 if ((BFD_ARELOC_BFIN_PUSH <= insn->reloc
438 && BFD_ARELOC_BFIN_COMP >= insn->reloc)
439 || insn->reloc == BFD_RELOC_BFIN_16_IMM)
441 size = 2;
443 if (insn->reloc == BFD_ARELOC_BFIN_CONST
444 || insn->reloc == BFD_ARELOC_BFIN_PUSH)
445 size = 4;
447 fix_new (frag_now,
448 (prev_toP - frag_now->fr_literal),
449 size, insn->exp->symbol, insn->exp->value,
450 insn->pcrel, insn->reloc);
452 else
454 md_number_to_chars (toP, insn->value, 2);
455 toP += 2;
458 #ifdef DEBUG
459 printf (" reloc :");
460 printf (" %02x%02x", ((unsigned char *) &insn->value)[0],
461 ((unsigned char *) &insn->value)[1]);
462 printf ("\n");
463 #endif
464 insn = insn->next;
466 #ifdef OBJ_ELF
467 dwarf2_emit_insn (insn_size);
468 #endif
471 /* Parse one line of instructions, and generate opcode for it.
472 To parse the line, YACC and LEX are used, because the instruction set
473 syntax doesn't confirm to the AT&T assembly syntax.
474 To call a YACC & LEX generated parser, we must provide the input via
475 a FILE stream, otherwise stdin is used by default. Below the input
476 to the function will be put into a temporary file, then the generated
477 parser uses the temporary file for parsing. */
479 static parse_state
480 parse (char *line)
482 parse_state state;
483 YY_BUFFER_STATE buffstate;
485 buffstate = yy_scan_string (line);
487 /* our lex requires setting the start state to keyword
488 every line as the first word may be a keyword.
489 Fixes a bug where we could not have keywords as labels. */
490 set_start_state ();
492 /* Call yyparse here. */
493 state = yyparse ();
494 if (state == SEMANTIC_ERROR)
496 as_bad (_("Parse failed."));
497 insn = 0;
500 yy_delete_buffer (buffstate);
501 return state;
504 /* We need to handle various expressions properly.
505 Such as, [SP--] = 34, concerned by md_assemble(). */
507 void
508 md_operand (expressionS * expressionP)
510 if (*input_line_pointer == '[')
512 as_tsktsk ("We found a '['!");
513 input_line_pointer++;
514 expression (expressionP);
518 /* Handle undefined symbols. */
519 symbolS *
520 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
522 return (symbolS *) 0;
526 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
527 segT segment ATTRIBUTE_UNUSED)
529 return 0;
532 /* Convert from target byte order to host byte order. */
534 static int
535 md_chars_to_number (char *val, int n)
537 int retval;
539 for (retval = 0; n--;)
541 retval <<= 8;
542 retval |= val[n];
544 return retval;
547 void
548 md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
550 char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
552 long value = *valueP;
553 long newval;
555 switch (fixP->fx_r_type)
557 case BFD_RELOC_BFIN_GOT:
558 case BFD_RELOC_BFIN_GOT17M4:
559 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
560 fixP->fx_no_overflow = 1;
561 newval = md_chars_to_number (where, 2);
562 newval |= 0x0 & 0x7f;
563 md_number_to_chars (where, newval, 2);
564 break;
566 case BFD_RELOC_BFIN_10_PCREL:
567 if (!value)
568 break;
569 if (value < -1024 || value > 1022)
570 as_bad_where (fixP->fx_file, fixP->fx_line,
571 _("pcrel too far BFD_RELOC_BFIN_10"));
573 /* 11 bit offset even numbered, so we remove right bit. */
574 value = value >> 1;
575 newval = md_chars_to_number (where, 2);
576 newval |= value & 0x03ff;
577 md_number_to_chars (where, newval, 2);
578 break;
580 case BFD_RELOC_BFIN_12_PCREL_JUMP:
581 case BFD_RELOC_BFIN_12_PCREL_JUMP_S:
582 case BFD_RELOC_12_PCREL:
583 if (!value)
584 break;
586 if (value < -4096 || value > 4094)
587 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_12"));
588 /* 13 bit offset even numbered, so we remove right bit. */
589 value = value >> 1;
590 newval = md_chars_to_number (where, 2);
591 newval |= value & 0xfff;
592 md_number_to_chars (where, newval, 2);
593 break;
595 case BFD_RELOC_BFIN_16_LOW:
596 case BFD_RELOC_BFIN_16_HIGH:
597 fixP->fx_done = FALSE;
598 break;
600 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
601 case BFD_RELOC_BFIN_24_PCREL_CALL_X:
602 case BFD_RELOC_24_PCREL:
603 if (!value)
604 break;
606 if (value < -16777216 || value > 16777214)
607 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_24"));
609 /* 25 bit offset even numbered, so we remove right bit. */
610 value = value >> 1;
611 value++;
613 md_number_to_chars (where - 2, value >> 16, 1);
614 md_number_to_chars (where, value, 1);
615 md_number_to_chars (where + 1, value >> 8, 1);
616 break;
618 case BFD_RELOC_BFIN_5_PCREL: /* LSETUP (a, b) : "a" */
619 if (!value)
620 break;
621 if (value < 4 || value > 30)
622 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_5"));
623 value = value >> 1;
624 newval = md_chars_to_number (where, 1);
625 newval = (newval & 0xf0) | (value & 0xf);
626 md_number_to_chars (where, newval, 1);
627 break;
629 case BFD_RELOC_BFIN_11_PCREL: /* LSETUP (a, b) : "b" */
630 if (!value)
631 break;
632 value += 2;
633 if (value < 4 || value > 2046)
634 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_11_PCREL"));
635 /* 11 bit unsigned even, so we remove right bit. */
636 value = value >> 1;
637 newval = md_chars_to_number (where, 2);
638 newval |= value & 0x03ff;
639 md_number_to_chars (where, newval, 2);
640 break;
642 case BFD_RELOC_8:
643 if (value < -0x80 || value >= 0x7f)
644 as_bad_where (fixP->fx_file, fixP->fx_line, _("rel too far BFD_RELOC_8"));
645 md_number_to_chars (where, value, 1);
646 break;
648 case BFD_RELOC_BFIN_16_IMM:
649 case BFD_RELOC_16:
650 if (value < -0x8000 || value >= 0x7fff)
651 as_bad_where (fixP->fx_file, fixP->fx_line, _("rel too far BFD_RELOC_16"));
652 md_number_to_chars (where, value, 2);
653 break;
655 case BFD_RELOC_32:
656 md_number_to_chars (where, value, 4);
657 break;
659 case BFD_RELOC_BFIN_PLTPC:
660 md_number_to_chars (where, value, 2);
661 break;
663 case BFD_RELOC_BFIN_FUNCDESC:
664 case BFD_RELOC_VTABLE_INHERIT:
665 case BFD_RELOC_VTABLE_ENTRY:
666 fixP->fx_done = FALSE;
667 break;
669 default:
670 if ((BFD_ARELOC_BFIN_PUSH > fixP->fx_r_type) || (BFD_ARELOC_BFIN_COMP < fixP->fx_r_type))
672 fprintf (stderr, "Relocation %d not handled in gas." " Contact support.\n", fixP->fx_r_type);
673 return;
677 if (!fixP->fx_addsy)
678 fixP->fx_done = TRUE;
682 /* Round up a section size to the appropriate boundary. */
683 valueT
684 md_section_align (segment, size)
685 segT segment;
686 valueT size;
688 int boundary = bfd_get_section_alignment (stdoutput, segment);
689 return ((size + (1 << boundary) - 1) & (-1 << boundary));
693 char *
694 md_atof (int type, char * litP, int * sizeP)
696 return ieee_md_atof (type, litP, sizeP, FALSE);
700 /* If while processing a fixup, a reloc really needs to be created
701 then it is done here. */
703 arelent *
704 tc_gen_reloc (seg, fixp)
705 asection *seg ATTRIBUTE_UNUSED;
706 fixS *fixp;
708 arelent *reloc;
710 reloc = (arelent *) xmalloc (sizeof (arelent));
711 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
712 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
713 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
715 reloc->addend = fixp->fx_offset;
716 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
718 if (reloc->howto == (reloc_howto_type *) NULL)
720 as_bad_where (fixp->fx_file, fixp->fx_line,
721 /* xgettext:c-format. */
722 _("reloc %d not supported by object file format"),
723 (int) fixp->fx_r_type);
725 xfree (reloc);
727 return NULL;
730 return reloc;
733 /* The location from which a PC relative jump should be calculated,
734 given a PC relative reloc. */
736 long
737 md_pcrel_from_section (fixP, sec)
738 fixS *fixP;
739 segT sec;
741 if (fixP->fx_addsy != (symbolS *) NULL
742 && (!S_IS_DEFINED (fixP->fx_addsy)
743 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
745 /* The symbol is undefined (or is defined but not in this section).
746 Let the linker figure it out. */
747 return 0;
749 return fixP->fx_frag->fr_address + fixP->fx_where;
752 /* Return true if the fix can be handled by GAS, false if it must
753 be passed through to the linker. */
755 bfd_boolean
756 bfin_fix_adjustable (fixS *fixP)
758 switch (fixP->fx_r_type)
760 /* Adjust_reloc_syms doesn't know about the GOT. */
761 case BFD_RELOC_BFIN_GOT:
762 case BFD_RELOC_BFIN_GOT17M4:
763 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
764 case BFD_RELOC_BFIN_PLTPC:
765 /* We need the symbol name for the VTABLE entries. */
766 case BFD_RELOC_VTABLE_INHERIT:
767 case BFD_RELOC_VTABLE_ENTRY:
768 return 0;
770 default:
771 return 1;
776 /* Handle the LOOP_BEGIN and LOOP_END statements.
777 Parse the Loop_Begin/Loop_End and create a label. */
778 void
779 bfin_start_line_hook ()
781 bfd_boolean maybe_begin = FALSE;
782 bfd_boolean maybe_end = FALSE;
784 char *c1, *label_name;
785 symbolS *line_label;
786 char *c = input_line_pointer;
787 int cr_num = 0;
789 while (ISSPACE (*c))
791 if (*c == '\n')
792 cr_num++;
793 c++;
796 /* Look for Loop_Begin or Loop_End statements. */
798 if (*c != 'L' && *c != 'l')
799 return;
801 c++;
802 if (*c != 'O' && *c != 'o')
803 return;
805 c++;
806 if (*c != 'O' && *c != 'o')
807 return;
809 c++;
810 if (*c != 'P' && *c != 'p')
811 return;
813 c++;
814 if (*c != '_')
815 return;
817 c++;
818 if (*c == 'E' || *c == 'e')
819 maybe_end = TRUE;
820 else if (*c == 'B' || *c == 'b')
821 maybe_begin = TRUE;
822 else
823 return;
825 if (maybe_end)
827 c++;
828 if (*c != 'N' && *c != 'n')
829 return;
831 c++;
832 if (*c != 'D' && *c != 'd')
833 return;
836 if (maybe_begin)
838 c++;
839 if (*c != 'E' && *c != 'e')
840 return;
842 c++;
843 if (*c != 'G' && *c != 'g')
844 return;
846 c++;
847 if (*c != 'I' && *c != 'i')
848 return;
850 c++;
851 if (*c != 'N' && *c != 'n')
852 return;
855 c++;
856 while (ISSPACE (*c)) c++;
857 c1 = c;
858 while (ISALPHA (*c) || ISDIGIT (*c) || *c == '_') c++;
860 if (input_line_pointer[-1] == '\n')
861 bump_line_counters ();
863 while (cr_num--)
864 bump_line_counters ();
866 input_line_pointer = c;
867 if (maybe_end)
869 label_name = (char *) xmalloc ((c - c1) + strlen ("__END") + 5);
870 label_name[0] = 0;
871 strcat (label_name, "L$L$");
872 strncat (label_name, c1, c-c1);
873 strcat (label_name, "__END");
875 else /* maybe_begin. */
877 label_name = (char *) xmalloc ((c - c1) + strlen ("__BEGIN") + 5);
878 label_name[0] = 0;
879 strcat (label_name, "L$L$");
880 strncat (label_name, c1, c-c1);
881 strcat (label_name, "__BEGIN");
884 line_label = colon (label_name);
886 /* Loop_End follows the last instruction in the loop.
887 Adjust label address. */
888 if (maybe_end)
889 ((struct local_symbol *) line_label)->lsy_value -= last_insn_size;
892 /* Special extra functions that help bfin-parse.y perform its job. */
894 #include <assert.h>
896 struct obstack mempool;
898 INSTR_T
899 conscode (INSTR_T head, INSTR_T tail)
901 if (!head)
902 return tail;
903 head->next = tail;
904 return head;
907 INSTR_T
908 conctcode (INSTR_T head, INSTR_T tail)
910 INSTR_T temp = (head);
911 if (!head)
912 return tail;
913 while (temp->next)
914 temp = temp->next;
915 temp->next = tail;
917 return head;
920 INSTR_T
921 note_reloc (INSTR_T code, Expr_Node * symbol, int reloc, int pcrel)
923 /* Assert that the symbol is not an operator. */
924 assert (symbol->type == Expr_Node_Reloc);
926 return note_reloc1 (code, symbol->value.s_value, reloc, pcrel);
930 INSTR_T
931 note_reloc1 (INSTR_T code, const char *symbol, int reloc, int pcrel)
933 code->reloc = reloc;
934 code->exp = mkexpr (0, symbol_find_or_make (symbol));
935 code->pcrel = pcrel;
936 return code;
939 INSTR_T
940 note_reloc2 (INSTR_T code, const char *symbol, int reloc, int value, int pcrel)
942 code->reloc = reloc;
943 code->exp = mkexpr (value, symbol_find_or_make (symbol));
944 code->pcrel = pcrel;
945 return code;
948 INSTR_T
949 gencode (unsigned long x)
951 INSTR_T cell = (INSTR_T) obstack_alloc (&mempool, sizeof (struct bfin_insn));
952 memset (cell, 0, sizeof (struct bfin_insn));
953 cell->value = (x);
954 return cell;
957 int reloc;
958 int ninsns;
959 int count_insns;
961 static void *
962 allocate (int n)
964 return (void *) obstack_alloc (&mempool, n);
967 Expr_Node *
968 Expr_Node_Create (Expr_Node_Type type,
969 Expr_Node_Value value,
970 Expr_Node *Left_Child,
971 Expr_Node *Right_Child)
975 Expr_Node *node = (Expr_Node *) allocate (sizeof (Expr_Node));
976 node->type = type;
977 node->value = value;
978 node->Left_Child = Left_Child;
979 node->Right_Child = Right_Child;
980 return node;
983 static const char *con = ".__constant";
984 static const char *op = ".__operator";
985 static INSTR_T Expr_Node_Gen_Reloc_R (Expr_Node * head);
986 INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc);
988 INSTR_T
989 Expr_Node_Gen_Reloc (Expr_Node * head, int parent_reloc)
991 /* Top level reloction expression generator VDSP style.
992 If the relocation is just by itself, generate one item
993 else generate this convoluted expression. */
995 INSTR_T note = NULL_CODE;
996 INSTR_T note1 = NULL_CODE;
997 int pcrel = 1; /* Is the parent reloc pcrelative?
998 This calculation here and HOWTO should match. */
1000 if (parent_reloc)
1002 /* If it's 32 bit quantity then 16bit code needs to be added. */
1003 int value = 0;
1005 if (head->type == Expr_Node_Constant)
1007 /* If note1 is not null code, we have to generate a right
1008 aligned value for the constant. Otherwise the reloc is
1009 a part of the basic command and the yacc file
1010 generates this. */
1011 value = head->value.i_value;
1013 switch (parent_reloc)
1015 /* Some relocations will need to allocate extra words. */
1016 case BFD_RELOC_BFIN_16_IMM:
1017 case BFD_RELOC_BFIN_16_LOW:
1018 case BFD_RELOC_BFIN_16_HIGH:
1019 note1 = conscode (gencode (value), NULL_CODE);
1020 pcrel = 0;
1021 break;
1022 case BFD_RELOC_BFIN_PLTPC:
1023 note1 = conscode (gencode (value), NULL_CODE);
1024 pcrel = 0;
1025 break;
1026 case BFD_RELOC_16:
1027 case BFD_RELOC_BFIN_GOT:
1028 case BFD_RELOC_BFIN_GOT17M4:
1029 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
1030 note1 = conscode (gencode (value), NULL_CODE);
1031 pcrel = 0;
1032 break;
1033 case BFD_RELOC_24_PCREL:
1034 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
1035 case BFD_RELOC_BFIN_24_PCREL_CALL_X:
1036 /* These offsets are even numbered pcrel. */
1037 note1 = conscode (gencode (value >> 1), NULL_CODE);
1038 break;
1039 default:
1040 note1 = NULL_CODE;
1043 if (head->type == Expr_Node_Constant)
1044 note = note1;
1045 else if (head->type == Expr_Node_Reloc)
1047 note = note_reloc1 (gencode (0), head->value.s_value, parent_reloc, pcrel);
1048 if (note1 != NULL_CODE)
1049 note = conscode (note1, note);
1051 else if (head->type == Expr_Node_Binop
1052 && (head->value.op_value == Expr_Op_Type_Add
1053 || head->value.op_value == Expr_Op_Type_Sub)
1054 && head->Left_Child->type == Expr_Node_Reloc
1055 && head->Right_Child->type == Expr_Node_Constant)
1057 int val = head->Right_Child->value.i_value;
1058 if (head->value.op_value == Expr_Op_Type_Sub)
1059 val = -val;
1060 note = conscode (note_reloc2 (gencode (0), head->Left_Child->value.s_value,
1061 parent_reloc, val, 0),
1062 NULL_CODE);
1063 if (note1 != NULL_CODE)
1064 note = conscode (note1, note);
1066 else
1068 /* Call the recursive function. */
1069 note = note_reloc1 (gencode (0), op, parent_reloc, pcrel);
1070 if (note1 != NULL_CODE)
1071 note = conscode (note1, note);
1072 note = conctcode (Expr_Node_Gen_Reloc_R (head), note);
1074 return note;
1077 static INSTR_T
1078 Expr_Node_Gen_Reloc_R (Expr_Node * head)
1081 INSTR_T note = 0;
1082 INSTR_T note1 = 0;
1084 switch (head->type)
1086 case Expr_Node_Constant:
1087 note = conscode (note_reloc2 (gencode (0), con, BFD_ARELOC_BFIN_CONST, head->value.i_value, 0), NULL_CODE);
1088 break;
1089 case Expr_Node_Reloc:
1090 note = conscode (note_reloc (gencode (0), head, BFD_ARELOC_BFIN_PUSH, 0), NULL_CODE);
1091 break;
1092 case Expr_Node_Binop:
1093 note1 = conctcode (Expr_Node_Gen_Reloc_R (head->Left_Child), Expr_Node_Gen_Reloc_R (head->Right_Child));
1094 switch (head->value.op_value)
1096 case Expr_Op_Type_Add:
1097 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_ADD, 0), NULL_CODE));
1098 break;
1099 case Expr_Op_Type_Sub:
1100 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_SUB, 0), NULL_CODE));
1101 break;
1102 case Expr_Op_Type_Mult:
1103 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MULT, 0), NULL_CODE));
1104 break;
1105 case Expr_Op_Type_Div:
1106 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_DIV, 0), NULL_CODE));
1107 break;
1108 case Expr_Op_Type_Mod:
1109 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MOD, 0), NULL_CODE));
1110 break;
1111 case Expr_Op_Type_Lshift:
1112 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LSHIFT, 0), NULL_CODE));
1113 break;
1114 case Expr_Op_Type_Rshift:
1115 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_RSHIFT, 0), NULL_CODE));
1116 break;
1117 case Expr_Op_Type_BAND:
1118 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_AND, 0), NULL_CODE));
1119 break;
1120 case Expr_Op_Type_BOR:
1121 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_OR, 0), NULL_CODE));
1122 break;
1123 case Expr_Op_Type_BXOR:
1124 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_XOR, 0), NULL_CODE));
1125 break;
1126 case Expr_Op_Type_LAND:
1127 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LAND, 0), NULL_CODE));
1128 break;
1129 case Expr_Op_Type_LOR:
1130 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LOR, 0), NULL_CODE));
1131 break;
1132 default:
1133 fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
1137 break;
1138 case Expr_Node_Unop:
1139 note1 = conscode (Expr_Node_Gen_Reloc_R (head->Left_Child), NULL_CODE);
1140 switch (head->value.op_value)
1142 case Expr_Op_Type_NEG:
1143 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_NEG, 0), NULL_CODE));
1144 break;
1145 case Expr_Op_Type_COMP:
1146 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_COMP, 0), NULL_CODE));
1147 break;
1148 default:
1149 fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
1151 break;
1152 default:
1153 fprintf (stderr, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__, __LINE__);
1155 return note;
1159 /* Blackfin opcode generation. */
1161 /* These functions are called by the generated parser
1162 (from bfin-parse.y), the register type classification
1163 happens in bfin-lex.l. */
1165 #include "bfin-aux.h"
1166 #include "opcode/bfin.h"
1168 #define INIT(t) t c_code = init_##t
1169 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1170 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1172 #define HI(x) ((x >> 16) & 0xffff)
1173 #define LO(x) ((x ) & 0xffff)
1175 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1177 #define GEN_OPCODE32() \
1178 conscode (gencode (HI (c_code.opcode)), \
1179 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1181 #define GEN_OPCODE16() \
1182 conscode (gencode (c_code.opcode), NULL_CODE)
1185 /* 32 BIT INSTRUCTIONS. */
1188 /* DSP32 instruction generation. */
1190 INSTR_T
1191 bfin_gen_dsp32mac (int op1, int MM, int mmod, int w1, int P,
1192 int h01, int h11, int h00, int h10, int op0,
1193 REG_T dst, REG_T src0, REG_T src1, int w0)
1195 INIT (DSP32Mac);
1197 ASSIGN (op0);
1198 ASSIGN (op1);
1199 ASSIGN (MM);
1200 ASSIGN (mmod);
1201 ASSIGN (w0);
1202 ASSIGN (w1);
1203 ASSIGN (h01);
1204 ASSIGN (h11);
1205 ASSIGN (h00);
1206 ASSIGN (h10);
1207 ASSIGN (P);
1209 /* If we have full reg assignments, mask out LSB to encode
1210 single or simultaneous even/odd register moves. */
1211 if (P)
1213 dst->regno &= 0x06;
1216 ASSIGN_R (dst);
1217 ASSIGN_R (src0);
1218 ASSIGN_R (src1);
1220 return GEN_OPCODE32 ();
1223 INSTR_T
1224 bfin_gen_dsp32mult (int op1, int MM, int mmod, int w1, int P,
1225 int h01, int h11, int h00, int h10, int op0,
1226 REG_T dst, REG_T src0, REG_T src1, int w0)
1228 INIT (DSP32Mult);
1230 ASSIGN (op0);
1231 ASSIGN (op1);
1232 ASSIGN (MM);
1233 ASSIGN (mmod);
1234 ASSIGN (w0);
1235 ASSIGN (w1);
1236 ASSIGN (h01);
1237 ASSIGN (h11);
1238 ASSIGN (h00);
1239 ASSIGN (h10);
1240 ASSIGN (P);
1242 if (P)
1244 dst->regno &= 0x06;
1247 ASSIGN_R (dst);
1248 ASSIGN_R (src0);
1249 ASSIGN_R (src1);
1251 return GEN_OPCODE32 ();
1254 INSTR_T
1255 bfin_gen_dsp32alu (int HL, int aopcde, int aop, int s, int x,
1256 REG_T dst0, REG_T dst1, REG_T src0, REG_T src1)
1258 INIT (DSP32Alu);
1260 ASSIGN (HL);
1261 ASSIGN (aopcde);
1262 ASSIGN (aop);
1263 ASSIGN (s);
1264 ASSIGN (x);
1265 ASSIGN_R (dst0);
1266 ASSIGN_R (dst1);
1267 ASSIGN_R (src0);
1268 ASSIGN_R (src1);
1270 return GEN_OPCODE32 ();
1273 INSTR_T
1274 bfin_gen_dsp32shift (int sopcde, REG_T dst0, REG_T src0,
1275 REG_T src1, int sop, int HLs)
1277 INIT (DSP32Shift);
1279 ASSIGN (sopcde);
1280 ASSIGN (sop);
1281 ASSIGN (HLs);
1283 ASSIGN_R (dst0);
1284 ASSIGN_R (src0);
1285 ASSIGN_R (src1);
1287 return GEN_OPCODE32 ();
1290 INSTR_T
1291 bfin_gen_dsp32shiftimm (int sopcde, REG_T dst0, int immag,
1292 REG_T src1, int sop, int HLs)
1294 INIT (DSP32ShiftImm);
1296 ASSIGN (sopcde);
1297 ASSIGN (sop);
1298 ASSIGN (HLs);
1300 ASSIGN_R (dst0);
1301 ASSIGN (immag);
1302 ASSIGN_R (src1);
1304 return GEN_OPCODE32 ();
1307 /* LOOP SETUP. */
1309 INSTR_T
1310 bfin_gen_loopsetup (Expr_Node * psoffset, REG_T c, int rop,
1311 Expr_Node * peoffset, REG_T reg)
1313 int soffset, eoffset;
1314 INIT (LoopSetup);
1316 soffset = (EXPR_VALUE (psoffset) >> 1);
1317 ASSIGN (soffset);
1318 eoffset = (EXPR_VALUE (peoffset) >> 1);
1319 ASSIGN (eoffset);
1320 ASSIGN (rop);
1321 ASSIGN_R (c);
1322 ASSIGN_R (reg);
1324 return
1325 conscode (gencode (HI (c_code.opcode)),
1326 conctcode (Expr_Node_Gen_Reloc (psoffset, BFD_RELOC_BFIN_5_PCREL),
1327 conctcode (gencode (LO (c_code.opcode)), Expr_Node_Gen_Reloc (peoffset, BFD_RELOC_BFIN_11_PCREL))));
1331 /* Call, Link. */
1333 INSTR_T
1334 bfin_gen_calla (Expr_Node * addr, int S)
1336 int val;
1337 int high_val;
1338 int reloc = 0;
1339 INIT (CALLa);
1341 switch(S){
1342 case 0 : reloc = BFD_RELOC_BFIN_24_PCREL_JUMP_L; break;
1343 case 1 : reloc = BFD_RELOC_24_PCREL; break;
1344 case 2 : reloc = BFD_RELOC_BFIN_PLTPC; break;
1345 default : break;
1348 ASSIGN (S);
1350 val = EXPR_VALUE (addr) >> 1;
1351 high_val = val >> 16;
1353 return conscode (gencode (HI (c_code.opcode) | (high_val & 0xff)),
1354 Expr_Node_Gen_Reloc (addr, reloc));
1357 INSTR_T
1358 bfin_gen_linkage (int R, int framesize)
1360 INIT (Linkage);
1362 ASSIGN (R);
1363 ASSIGN (framesize);
1365 return GEN_OPCODE32 ();
1369 /* Load and Store. */
1371 INSTR_T
1372 bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int reloc)
1374 int grp, hword;
1375 unsigned val = EXPR_VALUE (phword);
1376 INIT (LDIMMhalf);
1378 ASSIGN (H);
1379 ASSIGN (S);
1380 ASSIGN (Z);
1382 ASSIGN_R (reg);
1383 grp = (GROUP (reg));
1384 ASSIGN (grp);
1385 if (reloc == 2)
1387 return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, BFD_RELOC_BFIN_16_IMM));
1389 else if (reloc == 1)
1391 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));
1393 else
1395 hword = val;
1396 ASSIGN (hword);
1398 return GEN_OPCODE32 ();
1401 INSTR_T
1402 bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset)
1404 INIT (LDSTidxI);
1406 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1408 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1409 return 0;
1412 ASSIGN_R (ptr);
1413 ASSIGN_R (reg);
1414 ASSIGN (W);
1415 ASSIGN (sz);
1417 ASSIGN (Z);
1419 if (poffset->type != Expr_Node_Constant)
1421 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1422 /* distinguish between R0 = [P5 + symbol@GOT] and
1423 P5 = [P5 + _current_shared_library_p5_offset_]
1425 if (poffset->type == Expr_Node_Reloc
1426 && !strcmp (poffset->value.s_value,
1427 "_current_shared_library_p5_offset_"))
1429 return conscode (gencode (HI (c_code.opcode)),
1430 Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16));
1432 else if (poffset->type != Expr_Node_GOT_Reloc)
1433 abort ();
1435 return conscode (gencode (HI (c_code.opcode)),
1436 Expr_Node_Gen_Reloc(poffset->Left_Child,
1437 poffset->value.i_value));
1439 else
1441 int value, offset;
1442 switch (sz)
1443 { // load/store access size
1444 case 0: // 32 bit
1445 value = EXPR_VALUE (poffset) >> 2;
1446 break;
1447 case 1: // 16 bit
1448 value = EXPR_VALUE (poffset) >> 1;
1449 break;
1450 case 2: // 8 bit
1451 value = EXPR_VALUE (poffset);
1452 break;
1453 default:
1454 abort ();
1457 offset = (value & 0xffff);
1458 ASSIGN (offset);
1459 return GEN_OPCODE32 ();
1464 INSTR_T
1465 bfin_gen_ldst (REG_T ptr, REG_T reg, int aop, int sz, int Z, int W)
1467 INIT (LDST);
1469 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1471 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1472 return 0;
1475 ASSIGN_R (ptr);
1476 ASSIGN_R (reg);
1477 ASSIGN (aop);
1478 ASSIGN (sz);
1479 ASSIGN (Z);
1480 ASSIGN (W);
1482 return GEN_OPCODE16 ();
1485 INSTR_T
1486 bfin_gen_ldstii (REG_T ptr, REG_T reg, Expr_Node * poffset, int W, int op)
1488 int offset;
1489 int value = 0;
1490 INIT (LDSTii);
1493 if (!IS_PREG (*ptr))
1495 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1496 return 0;
1499 switch (op)
1501 case 1:
1502 case 2:
1503 value = EXPR_VALUE (poffset) >> 1;
1504 break;
1505 case 0:
1506 case 3:
1507 value = EXPR_VALUE (poffset) >> 2;
1508 break;
1511 ASSIGN_R (ptr);
1512 ASSIGN_R (reg);
1514 offset = value;
1515 ASSIGN (offset);
1516 ASSIGN (W);
1517 ASSIGN (op);
1519 return GEN_OPCODE16 ();
1522 INSTR_T
1523 bfin_gen_ldstiifp (REG_T sreg, Expr_Node * poffset, int W)
1525 /* Set bit 4 if it's a Preg. */
1526 int reg = (sreg->regno & CODE_MASK) | (IS_PREG (*sreg) ? 0x8 : 0x0);
1527 int offset = ((~(EXPR_VALUE (poffset) >> 2)) & 0x1f) + 1;
1528 INIT (LDSTiiFP);
1529 ASSIGN (reg);
1530 ASSIGN (offset);
1531 ASSIGN (W);
1533 return GEN_OPCODE16 ();
1536 INSTR_T
1537 bfin_gen_ldstpmod (REG_T ptr, REG_T reg, int aop, int W, REG_T idx)
1539 INIT (LDSTpmod);
1541 ASSIGN_R (ptr);
1542 ASSIGN_R (reg);
1543 ASSIGN (aop);
1544 ASSIGN (W);
1545 ASSIGN_R (idx);
1547 return GEN_OPCODE16 ();
1550 INSTR_T
1551 bfin_gen_dspldst (REG_T i, REG_T reg, int aop, int W, int m)
1553 INIT (DspLDST);
1555 ASSIGN_R (i);
1556 ASSIGN_R (reg);
1557 ASSIGN (aop);
1558 ASSIGN (W);
1559 ASSIGN (m);
1561 return GEN_OPCODE16 ();
1564 INSTR_T
1565 bfin_gen_logi2op (int opc, int src, int dst)
1567 INIT (LOGI2op);
1569 ASSIGN (opc);
1570 ASSIGN (src);
1571 ASSIGN (dst);
1573 return GEN_OPCODE16 ();
1576 INSTR_T
1577 bfin_gen_brcc (int T, int B, Expr_Node * poffset)
1579 int offset;
1580 INIT (BRCC);
1582 ASSIGN (T);
1583 ASSIGN (B);
1584 offset = ((EXPR_VALUE (poffset) >> 1));
1585 ASSIGN (offset);
1586 return conscode (gencode (c_code.opcode), Expr_Node_Gen_Reloc (poffset, BFD_RELOC_BFIN_10_PCREL));
1589 INSTR_T
1590 bfin_gen_ujump (Expr_Node * poffset)
1592 int offset;
1593 INIT (UJump);
1595 offset = ((EXPR_VALUE (poffset) >> 1));
1596 ASSIGN (offset);
1598 return conscode (gencode (c_code.opcode),
1599 Expr_Node_Gen_Reloc (
1600 poffset, BFD_RELOC_BFIN_12_PCREL_JUMP_S));
1603 INSTR_T
1604 bfin_gen_alu2op (REG_T dst, REG_T src, int opc)
1606 INIT (ALU2op);
1608 ASSIGN_R (dst);
1609 ASSIGN_R (src);
1610 ASSIGN (opc);
1612 return GEN_OPCODE16 ();
1615 INSTR_T
1616 bfin_gen_compi2opd (REG_T dst, int src, int op)
1618 INIT (COMPI2opD);
1620 ASSIGN_R (dst);
1621 ASSIGN (src);
1622 ASSIGN (op);
1624 return GEN_OPCODE16 ();
1627 INSTR_T
1628 bfin_gen_compi2opp (REG_T dst, int src, int op)
1630 INIT (COMPI2opP);
1632 ASSIGN_R (dst);
1633 ASSIGN (src);
1634 ASSIGN (op);
1636 return GEN_OPCODE16 ();
1639 INSTR_T
1640 bfin_gen_dagmodik (REG_T i, int op)
1642 INIT (DagMODik);
1644 ASSIGN_R (i);
1645 ASSIGN (op);
1647 return GEN_OPCODE16 ();
1650 INSTR_T
1651 bfin_gen_dagmodim (REG_T i, REG_T m, int op, int br)
1653 INIT (DagMODim);
1655 ASSIGN_R (i);
1656 ASSIGN_R (m);
1657 ASSIGN (op);
1658 ASSIGN (br);
1660 return GEN_OPCODE16 ();
1663 INSTR_T
1664 bfin_gen_ptr2op (REG_T dst, REG_T src, int opc)
1666 INIT (PTR2op);
1668 ASSIGN_R (dst);
1669 ASSIGN_R (src);
1670 ASSIGN (opc);
1672 return GEN_OPCODE16 ();
1675 INSTR_T
1676 bfin_gen_comp3op (REG_T src0, REG_T src1, REG_T dst, int opc)
1678 INIT (COMP3op);
1680 ASSIGN_R (src0);
1681 ASSIGN_R (src1);
1682 ASSIGN_R (dst);
1683 ASSIGN (opc);
1685 return GEN_OPCODE16 ();
1688 INSTR_T
1689 bfin_gen_ccflag (REG_T x, int y, int opc, int I, int G)
1691 INIT (CCflag);
1693 ASSIGN_R (x);
1694 ASSIGN (y);
1695 ASSIGN (opc);
1696 ASSIGN (I);
1697 ASSIGN (G);
1699 return GEN_OPCODE16 ();
1702 INSTR_T
1703 bfin_gen_ccmv (REG_T src, REG_T dst, int T)
1705 int s, d;
1706 INIT (CCmv);
1708 ASSIGN_R (src);
1709 ASSIGN_R (dst);
1710 s = (GROUP (src));
1711 ASSIGN (s);
1712 d = (GROUP (dst));
1713 ASSIGN (d);
1714 ASSIGN (T);
1716 return GEN_OPCODE16 ();
1719 INSTR_T
1720 bfin_gen_cc2stat (int cbit, int op, int D)
1722 INIT (CC2stat);
1724 ASSIGN (cbit);
1725 ASSIGN (op);
1726 ASSIGN (D);
1728 return GEN_OPCODE16 ();
1731 INSTR_T
1732 bfin_gen_regmv (REG_T src, REG_T dst)
1734 int gs, gd;
1735 INIT (RegMv);
1737 ASSIGN_R (src);
1738 ASSIGN_R (dst);
1740 gs = (GROUP (src));
1741 ASSIGN (gs);
1742 gd = (GROUP (dst));
1743 ASSIGN (gd);
1745 return GEN_OPCODE16 ();
1748 INSTR_T
1749 bfin_gen_cc2dreg (int op, REG_T reg)
1751 INIT (CC2dreg);
1753 ASSIGN (op);
1754 ASSIGN_R (reg);
1756 return GEN_OPCODE16 ();
1759 INSTR_T
1760 bfin_gen_progctrl (int prgfunc, int poprnd)
1762 INIT (ProgCtrl);
1764 ASSIGN (prgfunc);
1765 ASSIGN (poprnd);
1767 return GEN_OPCODE16 ();
1770 INSTR_T
1771 bfin_gen_cactrl (REG_T reg, int a, int op)
1773 INIT (CaCTRL);
1775 ASSIGN_R (reg);
1776 ASSIGN (a);
1777 ASSIGN (op);
1779 return GEN_OPCODE16 ();
1782 INSTR_T
1783 bfin_gen_pushpopmultiple (int dr, int pr, int d, int p, int W)
1785 INIT (PushPopMultiple);
1787 ASSIGN (dr);
1788 ASSIGN (pr);
1789 ASSIGN (d);
1790 ASSIGN (p);
1791 ASSIGN (W);
1793 return GEN_OPCODE16 ();
1796 INSTR_T
1797 bfin_gen_pushpopreg (REG_T reg, int W)
1799 int grp;
1800 INIT (PushPopReg);
1802 ASSIGN_R (reg);
1803 grp = (GROUP (reg));
1804 ASSIGN (grp);
1805 ASSIGN (W);
1807 return GEN_OPCODE16 ();
1810 /* Pseudo Debugging Support. */
1812 INSTR_T
1813 bfin_gen_pseudodbg (int fn, int reg, int grp)
1815 INIT (PseudoDbg);
1817 ASSIGN (fn);
1818 ASSIGN (reg);
1819 ASSIGN (grp);
1821 return GEN_OPCODE16 ();
1824 INSTR_T
1825 bfin_gen_pseudodbg_assert (int dbgop, REG_T regtest, int expected)
1827 INIT (PseudoDbg_Assert);
1829 ASSIGN (dbgop);
1830 ASSIGN_R (regtest);
1831 ASSIGN (expected);
1833 return GEN_OPCODE32 ();
1836 /* Multiple instruction generation. */
1838 INSTR_T
1839 bfin_gen_multi_instr (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2)
1841 INSTR_T walk;
1843 /* If it's a 0, convert into MNOP. */
1844 if (dsp32)
1846 walk = dsp32->next;
1847 SET_MULTI_INSTRUCTION_BIT (dsp32);
1849 else
1851 dsp32 = gencode (0xc803);
1852 walk = gencode (0x1800);
1853 dsp32->next = walk;
1856 if (!dsp16_grp1)
1858 dsp16_grp1 = gencode (0x0000);
1861 if (!dsp16_grp2)
1863 dsp16_grp2 = gencode (0x0000);
1866 walk->next = dsp16_grp1;
1867 dsp16_grp1->next = dsp16_grp2;
1868 dsp16_grp2->next = NULL_CODE;
1870 return dsp32;
1873 INSTR_T
1874 bfin_gen_loop (Expr_Node *expr, REG_T reg, int rop, REG_T preg)
1876 const char *loopsym;
1877 char *lbeginsym, *lendsym;
1878 Expr_Node_Value lbeginval, lendval;
1879 Expr_Node *lbegin, *lend;
1881 loopsym = expr->value.s_value;
1882 lbeginsym = (char *) xmalloc (strlen (loopsym) + strlen ("__BEGIN") + 5);
1883 lendsym = (char *) xmalloc (strlen (loopsym) + strlen ("__END") + 5);
1885 lbeginsym[0] = 0;
1886 lendsym[0] = 0;
1888 strcat (lbeginsym, "L$L$");
1889 strcat (lbeginsym, loopsym);
1890 strcat (lbeginsym, "__BEGIN");
1892 strcat (lendsym, "L$L$");
1893 strcat (lendsym, loopsym);
1894 strcat (lendsym, "__END");
1896 lbeginval.s_value = lbeginsym;
1897 lendval.s_value = lendsym;
1899 lbegin = Expr_Node_Create (Expr_Node_Reloc, lbeginval, NULL, NULL);
1900 lend = Expr_Node_Create (Expr_Node_Reloc, lendval, NULL, NULL);
1901 return bfin_gen_loopsetup(lbegin, reg, rop, lend, preg);
1904 bfd_boolean
1905 bfin_eol_in_insn (char *line)
1907 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1909 char *temp = line;
1911 if (*line != '\n')
1912 return FALSE;
1914 /* A semi-colon followed by a newline is always the end of a line. */
1915 if (line[-1] == ';')
1916 return FALSE;
1918 if (line[-1] == '|')
1919 return TRUE;
1921 /* If the || is on the next line, there might be leading whitespace. */
1922 temp++;
1923 while (*temp == ' ' || *temp == '\t') temp++;
1925 if (*temp == '|')
1926 return TRUE;
1928 return FALSE;
1931 bfd_boolean
1932 bfin_start_label (char *ptr)
1934 ptr--;
1935 while (!ISSPACE (*ptr) && !is_end_of_line[(unsigned char) *ptr])
1936 ptr--;
1938 ptr++;
1939 if (*ptr == '(' || *ptr == '[')
1940 return FALSE;
1942 return TRUE;
1946 bfin_force_relocation (struct fix *fixp)
1948 if (fixp->fx_r_type ==BFD_RELOC_BFIN_16_LOW
1949 || fixp->fx_r_type == BFD_RELOC_BFIN_16_HIGH)
1950 return TRUE;
1952 return generic_force_reloc (fixp);