file bfin-parse.h was initially added on branch binutils-2_17-branch.
[binutils.git] / gas / config / tc-bfin.c
blob43d48d624ea0b111eca6d7837e87e86419ea76b2
1 /* tc-bfin.c -- Assembler for the ADI Blackfin.
2 Copyright 2005
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 2, 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 "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
31 #include "libbfd.h"
32 #include "elf/common.h"
33 #include "elf/bfin.h"
35 extern int yyparse (void);
36 struct yy_buffer_state;
37 typedef struct yy_buffer_state *YY_BUFFER_STATE;
38 extern YY_BUFFER_STATE yy_scan_string (const char *yy_str);
39 extern void yy_delete_buffer (YY_BUFFER_STATE b);
40 static parse_state parse (char *line);
41 static void bfin_s_bss PARAMS ((int));
42 static int md_chars_to_number PARAMS ((char *, int));
44 /* Global variables. */
45 struct bfin_insn *insn;
46 int last_insn_size;
48 extern struct obstack mempool;
49 FILE *errorf;
51 /* Flags to set in the elf header */
52 #define DEFAULT_FLAGS 0
54 static flagword bfin_flags = DEFAULT_FLAGS;
55 static const char *bfin_pic_flag = (const char *)0;
57 /* Registers list. */
58 struct bfin_reg_entry
60 const char *name;
61 int number;
64 static 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}
214 /* Blackfin specific function to handle FD-PIC pointer initializations. */
216 static void
217 bfin_pic_ptr (int nbytes)
219 expressionS exp;
220 char *p;
222 if (nbytes != 4)
223 abort ();
225 #ifdef md_flush_pending_output
226 md_flush_pending_output ();
227 #endif
229 if (is_it_end_of_statement ())
231 demand_empty_rest_of_line ();
232 return;
235 #ifdef md_cons_align
236 md_cons_align (nbytes);
237 #endif
241 bfd_reloc_code_real_type reloc_type = BFD_RELOC_BFIN_FUNCDESC;
243 if (strncasecmp (input_line_pointer, "funcdesc(", 9) == 0)
245 input_line_pointer += 9;
246 expression (&exp);
247 if (*input_line_pointer == ')')
248 input_line_pointer++;
249 else
250 as_bad ("missing ')'");
252 else
253 error ("missing funcdesc in picptr");
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);
260 while (*input_line_pointer++ == ',');
262 input_line_pointer--; /* Put terminator back into stream. */
263 demand_empty_rest_of_line ();
266 static void
267 bfin_s_bss (int ignore ATTRIBUTE_UNUSED)
269 register int temp;
271 temp = get_absolute_expression ();
272 subseg_set (bss_section, (subsegT) temp);
273 demand_empty_rest_of_line ();
276 const pseudo_typeS md_pseudo_table[] = {
277 {"align", s_align_bytes, 0},
278 {"byte2", cons, 2},
279 {"byte4", cons, 4},
280 {"picptr", bfin_pic_ptr, 4},
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}
292 /* Characters that are used to denote comments and line separators. */
293 const char comment_chars[] = "";
294 const char line_comment_chars[] = "#";
295 const char line_separator_chars[] = ";";
297 /* Characters that can be used to separate the mantissa from the
298 exponent in floating point numbers. */
299 const char EXP_CHARS[] = "eE";
301 /* Characters that mean this number is a floating point constant.
302 As in 0f12.456 or 0d1.2345e12. */
303 const char FLT_CHARS[] = "fFdDxX";
305 /* Define bfin-specific command-line options (there are none). */
306 const char *md_shortopts = "";
308 #define OPTION_FDPIC (OPTION_MD_BASE)
310 struct option md_longopts[] =
312 { "mfdpic", no_argument, NULL, OPTION_FDPIC },
313 { NULL, no_argument, NULL, 0 },
316 size_t md_longopts_size = sizeof (md_longopts);
320 md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
322 switch (c)
324 default:
325 return 0;
327 case OPTION_FDPIC:
328 bfin_flags |= EF_BFIN_FDPIC;
329 bfin_pic_flag = "-mfdpic";
330 break;
333 return 1;
336 void
337 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
339 fprintf (stream, _(" BFIN specific command line options:\n"));
342 /* Perform machine-specific initializations. */
343 void
344 md_begin ()
346 /* Set the ELF flags if desired. */
347 if (bfin_flags)
348 bfd_set_private_flags (stdoutput, bfin_flags);
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.");
354 /* Ensure that lines can begin with '(', for multiple
355 register stack pops. */
356 lex_type ['('] = LEX_BEGIN_NAME;
358 #ifdef OBJ_ELF
359 record_alignment (text_section, 2);
360 record_alignment (data_section, 2);
361 record_alignment (bss_section, 2);
362 #endif
364 errorf = stderr;
365 obstack_init (&mempool);
367 #ifdef DEBUG
368 extern int debug_codeselection;
369 debug_codeselection = 1;
370 #endif
372 last_insn_size = 0;
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. */
379 void
380 md_assemble (char *line)
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;
390 len = strlen (line);
391 if (len + 2 > buffer_len)
393 if (buffer_len > 0)
394 free (current_inputline);
395 buffer_len = len + 40;
396 current_inputline = xmalloc (buffer_len);
398 memcpy (current_inputline, line, len);
399 current_inputline[len] = ';';
400 current_inputline[len + 1] = '\0';
402 state = parse (current_inputline);
403 if (state == NO_INSN_GENERATED)
404 return;
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;
410 if (insn_size)
411 toP = frag_more (insn_size);
413 last_insn_size = insn_size;
415 #ifdef DEBUG
416 printf ("INS:");
417 #endif
418 while (insn)
420 if (insn->reloc && insn->exp->symbol)
422 char *prev_toP = toP - 2;
423 switch (insn->reloc)
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;
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)
442 size = 2;
444 if (insn->reloc == BFD_ARELOC_BFIN_CONST
445 || insn->reloc == BFD_ARELOC_BFIN_PUSH)
446 size = 4;
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);
453 else
455 md_number_to_chars (toP, insn->value, 2);
456 toP += 2;
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;
467 #ifdef OBJ_ELF
468 dwarf2_emit_insn (insn_size);
469 #endif
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. */
480 static parse_state
481 parse (char *line)
483 parse_state state;
484 YY_BUFFER_STATE buffstate;
486 buffstate = yy_scan_string (line);
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 ();
493 /* Call yyparse here. */
494 state = yyparse ();
495 if (state == SEMANTIC_ERROR)
497 as_bad ("Parse failed.");
498 insn = 0;
501 yy_delete_buffer (buffstate);
502 return state;
505 /* We need to handle various expressions properly.
506 Such as, [SP--] = 34, concerned by md_assemble(). */
508 void
509 md_operand (expressionS * expressionP)
511 if (*input_line_pointer == '[')
513 as_tsktsk ("We found a '['!");
514 input_line_pointer++;
515 expression (expressionP);
519 /* Handle undefined symbols. */
520 symbolS *
521 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
523 return (symbolS *) 0;
527 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
528 segT segment ATTRIBUTE_UNUSED)
530 return 0;
533 /* Convert from target byte order to host byte order. */
535 static int
536 md_chars_to_number (char *val, int n)
538 int retval;
540 for (retval = 0; n--;)
542 retval <<= 8;
543 retval |= val[n];
545 return retval;
548 void
549 md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
551 char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
553 long value = *valueP;
554 long newval;
556 switch (fixP->fx_r_type)
558 case BFD_RELOC_BFIN_GOT:
559 case BFD_RELOC_BFIN_GOT17M4:
560 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
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;
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");
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;
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;
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;
596 case BFD_RELOC_BFIN_16_LOW:
597 case BFD_RELOC_BFIN_16_HIGH:
598 fixP->fx_done = FALSE;
599 break;
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;
607 if (value < -16777216 || value > 16777214)
608 as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far BFD_RELOC_BFIN_24");
610 /* 25 bit offset even numbered, so we remove right bit. */
611 value = value >> 1;
612 value++;
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;
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;
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;
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;
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;
656 case BFD_RELOC_32:
657 md_number_to_chars (where, value, 4);
658 break;
660 case BFD_RELOC_BFIN_PLTPC:
661 md_number_to_chars (where, value, 2);
662 break;
664 case BFD_RELOC_BFIN_FUNCDESC:
665 case BFD_RELOC_VTABLE_INHERIT:
666 case BFD_RELOC_VTABLE_ENTRY:
667 fixP->fx_done = FALSE;
668 break;
670 default:
671 if ((BFD_ARELOC_BFIN_PUSH > fixP->fx_r_type) || (BFD_ARELOC_BFIN_COMP < fixP->fx_r_type))
673 fprintf (stderr, "Relocation %d not handled in gas." " Contact support.\n", fixP->fx_r_type);
674 return;
678 if (!fixP->fx_addsy)
679 fixP->fx_done = TRUE;
683 /* Round up a section size to the appropriate boundary. */
684 valueT
685 md_section_align (segment, size)
686 segT segment;
687 valueT size;
689 int boundary = bfd_get_section_alignment (stdoutput, segment);
690 return ((size + (1 << boundary) - 1) & (-1 << boundary));
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. */
699 /* Equal to MAX_PRECISION in atof-ieee.c. */
700 #define MAX_LITTLENUMS 6
702 char *
703 md_atof (type, litP, sizeP)
704 char type;
705 char * litP;
706 int * sizeP;
708 int prec;
709 LITTLENUM_TYPE words [MAX_LITTLENUMS];
710 LITTLENUM_TYPE *wordP;
711 char * t;
713 switch (type)
715 case 'f':
716 case 'F':
717 prec = 2;
718 break;
720 case 'd':
721 case 'D':
722 prec = 4;
723 break;
725 /* FIXME: Some targets allow other format chars for bigger sizes here. */
727 default:
728 *sizeP = 0;
729 return _("Bad call to md_atof()");
732 t = atof_ieee (input_line_pointer, type, words);
733 if (t)
734 input_line_pointer = t;
735 *sizeP = prec * sizeof (LITTLENUM_TYPE);
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--;)
742 md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
743 litP += sizeof (LITTLENUM_TYPE);
746 return 0;
750 /* If while processing a fixup, a reloc really needs to be created
751 then it is done here. */
753 arelent *
754 tc_gen_reloc (seg, fixp)
755 asection *seg ATTRIBUTE_UNUSED;
756 fixS *fixp;
758 arelent *reloc;
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;
765 reloc->addend = fixp->fx_offset;
766 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
768 if (reloc->howto == (reloc_howto_type *) NULL)
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);
775 xfree (reloc);
777 return NULL;
780 return reloc;
783 /* The location from which a PC relative jump should be calculated,
784 given a PC relative reloc. */
786 long
787 md_pcrel_from_section (fixP, sec)
788 fixS *fixP;
789 segT sec;
791 if (fixP->fx_addsy != (symbolS *) NULL
792 && (!S_IS_DEFINED (fixP->fx_addsy)
793 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
795 /* The symbol is undefined (or is defined but not in this section).
796 Let the linker figure it out. */
797 return 0;
799 return fixP->fx_frag->fr_address + fixP->fx_where;
802 /* Return true if the fix can be handled by GAS, false if it must
803 be passed through to the linker. */
805 bfd_boolean
806 bfin_fix_adjustable (fixS *fixP)
808 switch (fixP->fx_r_type)
810 /* Adjust_reloc_syms doesn't know about the GOT. */
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:
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;
820 default:
821 return 1;
826 /* Handle the LOOP_BEGIN and LOOP_END statements.
827 Parse the Loop_Begin/Loop_End and create a label. */
828 void
829 bfin_start_line_hook ()
831 bfd_boolean maybe_begin = FALSE;
832 bfd_boolean maybe_end = FALSE;
834 char *c1, *label_name;
835 symbolS *line_label;
836 char *c = input_line_pointer;
838 while (ISSPACE (*c))
839 c++;
841 /* Look for Loop_Begin or Loop_End statements. */
843 if (*c != 'L' && *c != 'l')
844 return;
846 c++;
847 if (*c != 'O' && *c != 'o')
848 return;
850 c++;
851 if (*c != 'O' && *c != 'o')
852 return;
854 c++;
855 if (*c != 'P' && *c != 'p')
856 return;
858 c++;
859 if (*c != '_')
860 return;
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;
870 if (maybe_end)
872 c++;
873 if (*c != 'N' && *c != 'n')
874 return;
876 c++;
877 if (*c != 'D' && *c != 'd')
878 return;
881 if (maybe_begin)
883 c++;
884 if (*c != 'E' && *c != 'e')
885 return;
887 c++;
888 if (*c != 'G' && *c != 'g')
889 return;
891 c++;
892 if (*c != 'I' && *c != 'i')
893 return;
895 c++;
896 if (*c != 'N' && *c != 'n')
897 return;
900 c++;
901 while (ISSPACE (*c)) c++;
902 c1 = c;
903 while (ISALPHA (*c) || ISDIGIT (*c) || *c == '_') c++;
905 input_line_pointer = c;
906 if (maybe_end)
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");
913 else /* maybe_begin. */
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");
921 line_label = colon (label_name);
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;
930 /* Special extra functions that help bfin-parse.y perform its job. */
932 #include <stdio.h>
933 #include <assert.h>
934 #include <obstack.h>
935 #include <bfd.h>
936 #include "bfin-defs.h"
938 struct obstack mempool;
940 INSTR_T
941 conscode (INSTR_T head, INSTR_T tail)
943 if (!head)
944 return tail;
945 head->next = tail;
946 return head;
949 INSTR_T
950 conctcode (INSTR_T head, INSTR_T tail)
952 INSTR_T temp = (head);
953 if (!head)
954 return tail;
955 while (temp->next)
956 temp = temp->next;
957 temp->next = tail;
959 return head;
962 INSTR_T
963 note_reloc (INSTR_T code, Expr_Node * symbol, int reloc, int pcrel)
965 /* Assert that the symbol is not an operator. */
966 assert (symbol->type == Expr_Node_Reloc);
968 return note_reloc1 (code, symbol->value.s_value, reloc, pcrel);
972 INSTR_T
973 note_reloc1 (INSTR_T code, const char *symbol, int reloc, int pcrel)
975 code->reloc = reloc;
976 code->exp = mkexpr (0, symbol_find_or_make (symbol));
977 code->pcrel = pcrel;
978 return code;
981 INSTR_T
982 note_reloc2 (INSTR_T code, const char *symbol, int reloc, int value, int pcrel)
984 code->reloc = reloc;
985 code->exp = mkexpr (value, symbol_find_or_make (symbol));
986 code->pcrel = pcrel;
987 return code;
990 INSTR_T
991 gencode (unsigned long x)
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;
999 int reloc;
1000 int ninsns;
1001 int count_insns;
1003 static void *
1004 allocate (int n)
1006 return (void *) obstack_alloc (&mempool, n);
1009 Expr_Node *
1010 Expr_Node_Create (Expr_Node_Type type,
1011 Expr_Node_Value value,
1012 Expr_Node *Left_Child,
1013 Expr_Node *Right_Child)
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;
1025 static const char *con = ".__constant";
1026 static const char *op = ".__operator";
1027 static INSTR_T Expr_Node_Gen_Reloc_R (Expr_Node * head);
1028 INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc);
1030 INSTR_T
1031 Expr_Node_Gen_Reloc (Expr_Node * head, int parent_reloc)
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. */
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. */
1042 if (parent_reloc)
1044 /* If it's 32 bit quantity then 16bit code needs to be added. */
1045 int value = 0;
1047 if (head->type == Expr_Node_Constant)
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;
1055 switch (parent_reloc)
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:
1070 case BFD_RELOC_BFIN_GOT17M4:
1071 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
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;
1085 if (head->type == Expr_Node_Constant)
1086 note = note1;
1087 else if (head->type == Expr_Node_Reloc)
1089 note = note_reloc1 (gencode (0), head->value.s_value, parent_reloc, pcrel);
1090 if (note1 != NULL_CODE)
1091 note = conscode (note1, note);
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)
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);
1108 else
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);
1116 return note;
1119 static INSTR_T
1120 Expr_Node_Gen_Reloc_R (Expr_Node * head)
1123 INSTR_T note = 0;
1124 INSTR_T note1 = 0;
1126 switch (head->type)
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)
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__);
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)
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__);
1193 break;
1194 default:
1195 fprintf (stderr, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__, __LINE__);
1197 return note;
1201 /* Blackfin opcode generation. */
1203 /* These functions are called by the generated parser
1204 (from bfin-parse.y), the register type classification
1205 happens in bfin-lex.l. */
1207 #include "bfin-aux.h"
1208 #include "opcode/bfin.h"
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)
1214 #define HI(x) ((x >> 16) & 0xffff)
1215 #define LO(x) ((x ) & 0xffff)
1217 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1219 #define GEN_OPCODE32() \
1220 conscode (gencode (HI (c_code.opcode)), \
1221 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1223 #define GEN_OPCODE16() \
1224 conscode (gencode (c_code.opcode), NULL_CODE)
1227 /* 32 BIT INSTRUCTIONS. */
1230 /* DSP32 instruction generation. */
1232 INSTR_T
1233 bfin_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)
1237 INIT (DSP32Mac);
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);
1251 /* If we have full reg assignments, mask out LSB to encode
1252 single or simultaneous even/odd register moves. */
1253 if (P)
1255 dst->regno &= 0x06;
1258 ASSIGN_R (dst);
1259 ASSIGN_R (src0);
1260 ASSIGN_R (src1);
1262 return GEN_OPCODE32 ();
1265 INSTR_T
1266 bfin_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)
1270 INIT (DSP32Mult);
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);
1284 if (P)
1286 dst->regno &= 0x06;
1289 ASSIGN_R (dst);
1290 ASSIGN_R (src0);
1291 ASSIGN_R (src1);
1293 return GEN_OPCODE32 ();
1296 INSTR_T
1297 bfin_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)
1300 INIT (DSP32Alu);
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);
1312 return GEN_OPCODE32 ();
1315 INSTR_T
1316 bfin_gen_dsp32shift (int sopcde, REG_T dst0, REG_T src0,
1317 REG_T src1, int sop, int HLs)
1319 INIT (DSP32Shift);
1321 ASSIGN (sopcde);
1322 ASSIGN (sop);
1323 ASSIGN (HLs);
1325 ASSIGN_R (dst0);
1326 ASSIGN_R (src0);
1327 ASSIGN_R (src1);
1329 return GEN_OPCODE32 ();
1332 INSTR_T
1333 bfin_gen_dsp32shiftimm (int sopcde, REG_T dst0, int immag,
1334 REG_T src1, int sop, int HLs)
1336 INIT (DSP32ShiftImm);
1338 ASSIGN (sopcde);
1339 ASSIGN (sop);
1340 ASSIGN (HLs);
1342 ASSIGN_R (dst0);
1343 ASSIGN (immag);
1344 ASSIGN_R (src1);
1346 return GEN_OPCODE32 ();
1349 /* LOOP SETUP. */
1351 INSTR_T
1352 bfin_gen_loopsetup (Expr_Node * psoffset, REG_T c, int rop,
1353 Expr_Node * peoffset, REG_T reg)
1355 int soffset, eoffset;
1356 INIT (LoopSetup);
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);
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))));
1373 /* Call, Link. */
1375 INSTR_T
1376 bfin_gen_calla (Expr_Node * addr, int S)
1378 int val;
1379 int high_val;
1380 int reloc = 0;
1381 INIT (CALLa);
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;
1390 ASSIGN (S);
1392 val = EXPR_VALUE (addr) >> 1;
1393 high_val = val >> 16;
1395 return conscode (gencode (HI (c_code.opcode) | (high_val & 0xff)),
1396 Expr_Node_Gen_Reloc (addr, reloc));
1399 INSTR_T
1400 bfin_gen_linkage (int R, int framesize)
1402 INIT (Linkage);
1404 ASSIGN (R);
1405 ASSIGN (framesize);
1407 return GEN_OPCODE32 ();
1411 /* Load and Store. */
1413 INSTR_T
1414 bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int reloc)
1416 int grp, hword;
1417 unsigned val = EXPR_VALUE (phword);
1418 INIT (LDIMMhalf);
1420 ASSIGN (H);
1421 ASSIGN (S);
1422 ASSIGN (Z);
1424 ASSIGN_R (reg);
1425 grp = (GROUP (reg));
1426 ASSIGN (grp);
1427 if (reloc == 2)
1429 return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, BFD_RELOC_BFIN_16_IMM));
1431 else if (reloc == 1)
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));
1435 else
1437 hword = val;
1438 ASSIGN (hword);
1440 return GEN_OPCODE32 ();
1443 INSTR_T
1444 bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset)
1446 INIT (LDSTidxI);
1448 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1450 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1451 return 0;
1454 ASSIGN_R (ptr);
1455 ASSIGN_R (reg);
1456 ASSIGN (W);
1457 ASSIGN (sz);
1459 ASSIGN (Z);
1461 if (poffset->type != Expr_Node_Constant)
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_]
1467 if (poffset->type == Expr_Node_Reloc
1468 && !strcmp (poffset->value.s_value,
1469 "_current_shared_library_p5_offset_"))
1471 return conscode (gencode (HI (c_code.opcode)),
1472 Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16));
1474 else if (poffset->type != Expr_Node_GOT_Reloc)
1475 abort ();
1477 return conscode (gencode (HI (c_code.opcode)),
1478 Expr_Node_Gen_Reloc(poffset->Left_Child,
1479 poffset->value.i_value));
1481 else
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 ();
1499 offset = (value & 0xffff);
1500 ASSIGN (offset);
1501 return GEN_OPCODE32 ();
1506 INSTR_T
1507 bfin_gen_ldst (REG_T ptr, REG_T reg, int aop, int sz, int Z, int W)
1509 INIT (LDST);
1511 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1513 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1514 return 0;
1517 ASSIGN_R (ptr);
1518 ASSIGN_R (reg);
1519 ASSIGN (aop);
1520 ASSIGN (sz);
1521 ASSIGN (Z);
1522 ASSIGN (W);
1524 return GEN_OPCODE16 ();
1527 INSTR_T
1528 bfin_gen_ldstii (REG_T ptr, REG_T reg, Expr_Node * poffset, int W, int op)
1530 int offset;
1531 int value = 0;
1532 INIT (LDSTii);
1535 if (!IS_PREG (*ptr))
1537 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1538 return 0;
1541 switch (op)
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;
1553 ASSIGN_R (ptr);
1554 ASSIGN_R (reg);
1556 offset = value;
1557 ASSIGN (offset);
1558 ASSIGN (W);
1559 ASSIGN (op);
1561 return GEN_OPCODE16 ();
1564 INSTR_T
1565 bfin_gen_ldstiifp (REG_T sreg, Expr_Node * poffset, int W)
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);
1575 return GEN_OPCODE16 ();
1578 INSTR_T
1579 bfin_gen_ldstpmod (REG_T ptr, REG_T reg, int aop, int W, REG_T idx)
1581 INIT (LDSTpmod);
1583 ASSIGN_R (ptr);
1584 ASSIGN_R (reg);
1585 ASSIGN (aop);
1586 ASSIGN (W);
1587 ASSIGN_R (idx);
1589 return GEN_OPCODE16 ();
1592 INSTR_T
1593 bfin_gen_dspldst (REG_T i, REG_T reg, int aop, int W, int m)
1595 INIT (DspLDST);
1597 ASSIGN_R (i);
1598 ASSIGN_R (reg);
1599 ASSIGN (aop);
1600 ASSIGN (W);
1601 ASSIGN (m);
1603 return GEN_OPCODE16 ();
1606 INSTR_T
1607 bfin_gen_logi2op (int opc, int src, int dst)
1609 INIT (LOGI2op);
1611 ASSIGN (opc);
1612 ASSIGN (src);
1613 ASSIGN (dst);
1615 return GEN_OPCODE16 ();
1618 INSTR_T
1619 bfin_gen_brcc (int T, int B, Expr_Node * poffset)
1621 int offset;
1622 INIT (BRCC);
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));
1631 INSTR_T
1632 bfin_gen_ujump (Expr_Node * poffset)
1634 int offset;
1635 INIT (UJump);
1637 offset = ((EXPR_VALUE (poffset) >> 1));
1638 ASSIGN (offset);
1640 return conscode (gencode (c_code.opcode),
1641 Expr_Node_Gen_Reloc (
1642 poffset, BFD_RELOC_BFIN_12_PCREL_JUMP_S));
1645 INSTR_T
1646 bfin_gen_alu2op (REG_T dst, REG_T src, int opc)
1648 INIT (ALU2op);
1650 ASSIGN_R (dst);
1651 ASSIGN_R (src);
1652 ASSIGN (opc);
1654 return GEN_OPCODE16 ();
1657 INSTR_T
1658 bfin_gen_compi2opd (REG_T dst, int src, int op)
1660 INIT (COMPI2opD);
1662 ASSIGN_R (dst);
1663 ASSIGN (src);
1664 ASSIGN (op);
1666 return GEN_OPCODE16 ();
1669 INSTR_T
1670 bfin_gen_compi2opp (REG_T dst, int src, int op)
1672 INIT (COMPI2opP);
1674 ASSIGN_R (dst);
1675 ASSIGN (src);
1676 ASSIGN (op);
1678 return GEN_OPCODE16 ();
1681 INSTR_T
1682 bfin_gen_dagmodik (REG_T i, int op)
1684 INIT (DagMODik);
1686 ASSIGN_R (i);
1687 ASSIGN (op);
1689 return GEN_OPCODE16 ();
1692 INSTR_T
1693 bfin_gen_dagmodim (REG_T i, REG_T m, int op, int br)
1695 INIT (DagMODim);
1697 ASSIGN_R (i);
1698 ASSIGN_R (m);
1699 ASSIGN (op);
1700 ASSIGN (br);
1702 return GEN_OPCODE16 ();
1705 INSTR_T
1706 bfin_gen_ptr2op (REG_T dst, REG_T src, int opc)
1708 INIT (PTR2op);
1710 ASSIGN_R (dst);
1711 ASSIGN_R (src);
1712 ASSIGN (opc);
1714 return GEN_OPCODE16 ();
1717 INSTR_T
1718 bfin_gen_comp3op (REG_T src0, REG_T src1, REG_T dst, int opc)
1720 INIT (COMP3op);
1722 ASSIGN_R (src0);
1723 ASSIGN_R (src1);
1724 ASSIGN_R (dst);
1725 ASSIGN (opc);
1727 return GEN_OPCODE16 ();
1730 INSTR_T
1731 bfin_gen_ccflag (REG_T x, int y, int opc, int I, int G)
1733 INIT (CCflag);
1735 ASSIGN_R (x);
1736 ASSIGN (y);
1737 ASSIGN (opc);
1738 ASSIGN (I);
1739 ASSIGN (G);
1741 return GEN_OPCODE16 ();
1744 INSTR_T
1745 bfin_gen_ccmv (REG_T src, REG_T dst, int T)
1747 int s, d;
1748 INIT (CCmv);
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);
1758 return GEN_OPCODE16 ();
1761 INSTR_T
1762 bfin_gen_cc2stat (int cbit, int op, int D)
1764 INIT (CC2stat);
1766 ASSIGN (cbit);
1767 ASSIGN (op);
1768 ASSIGN (D);
1770 return GEN_OPCODE16 ();
1773 INSTR_T
1774 bfin_gen_regmv (REG_T src, REG_T dst)
1776 int gs, gd;
1777 INIT (RegMv);
1779 ASSIGN_R (src);
1780 ASSIGN_R (dst);
1782 gs = (GROUP (src));
1783 ASSIGN (gs);
1784 gd = (GROUP (dst));
1785 ASSIGN (gd);
1787 return GEN_OPCODE16 ();
1790 INSTR_T
1791 bfin_gen_cc2dreg (int op, REG_T reg)
1793 INIT (CC2dreg);
1795 ASSIGN (op);
1796 ASSIGN_R (reg);
1798 return GEN_OPCODE16 ();
1801 INSTR_T
1802 bfin_gen_progctrl (int prgfunc, int poprnd)
1804 INIT (ProgCtrl);
1806 ASSIGN (prgfunc);
1807 ASSIGN (poprnd);
1809 return GEN_OPCODE16 ();
1812 INSTR_T
1813 bfin_gen_cactrl (REG_T reg, int a, int op)
1815 INIT (CaCTRL);
1817 ASSIGN_R (reg);
1818 ASSIGN (a);
1819 ASSIGN (op);
1821 return GEN_OPCODE16 ();
1824 INSTR_T
1825 bfin_gen_pushpopmultiple (int dr, int pr, int d, int p, int W)
1827 INIT (PushPopMultiple);
1829 ASSIGN (dr);
1830 ASSIGN (pr);
1831 ASSIGN (d);
1832 ASSIGN (p);
1833 ASSIGN (W);
1835 return GEN_OPCODE16 ();
1838 INSTR_T
1839 bfin_gen_pushpopreg (REG_T reg, int W)
1841 int grp;
1842 INIT (PushPopReg);
1844 ASSIGN_R (reg);
1845 grp = (GROUP (reg));
1846 ASSIGN (grp);
1847 ASSIGN (W);
1849 return GEN_OPCODE16 ();
1852 /* Pseudo Debugging Support. */
1854 INSTR_T
1855 bfin_gen_pseudodbg (int fn, int reg, int grp)
1857 INIT (PseudoDbg);
1859 ASSIGN (fn);
1860 ASSIGN (reg);
1861 ASSIGN (grp);
1863 return GEN_OPCODE16 ();
1866 INSTR_T
1867 bfin_gen_pseudodbg_assert (int dbgop, REG_T regtest, int expected)
1869 INIT (PseudoDbg_Assert);
1871 ASSIGN (dbgop);
1872 ASSIGN_R (regtest);
1873 ASSIGN (expected);
1875 return GEN_OPCODE32 ();
1878 /* Multiple instruction generation. */
1880 INSTR_T
1881 bfin_gen_multi_instr (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2)
1883 INSTR_T walk;
1885 /* If it's a 0, convert into MNOP. */
1886 if (dsp32)
1888 walk = dsp32->next;
1889 SET_MULTI_INSTRUCTION_BIT (dsp32);
1891 else
1893 dsp32 = gencode (0xc803);
1894 walk = gencode (0x1800);
1895 dsp32->next = walk;
1898 if (!dsp16_grp1)
1900 dsp16_grp1 = gencode (0x0000);
1903 if (!dsp16_grp2)
1905 dsp16_grp2 = gencode (0x0000);
1908 walk->next = dsp16_grp1;
1909 dsp16_grp1->next = dsp16_grp2;
1910 dsp16_grp2->next = NULL_CODE;
1912 return dsp32;
1915 INSTR_T
1916 bfin_gen_loop (Expr_Node *expr, REG_T reg, int rop, REG_T preg)
1918 const char *loopsym;
1919 char *lbeginsym, *lendsym;
1920 Expr_Node_Value lbeginval, lendval;
1921 Expr_Node *lbegin, *lend;
1923 loopsym = expr->value.s_value;
1924 lbeginsym = (char *) xmalloc (strlen (loopsym) + strlen ("__BEGIN") + 1);
1925 lendsym = (char *) xmalloc (strlen (loopsym) + strlen ("__END") + 1);
1927 lbeginsym[0] = 0;
1928 lendsym[0] = 0;
1930 strcat (lbeginsym, loopsym);
1931 strcat (lbeginsym, "__BEGIN");
1933 strcat (lendsym, loopsym);
1934 strcat (lendsym, "__END");
1936 lbeginval.s_value = lbeginsym;
1937 lendval.s_value = lendsym;
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);
1944 bfd_boolean
1945 bfin_eol_in_insn (char *line)
1947 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1949 char *temp = line;
1951 if (*line != '\n')
1952 return FALSE;
1954 /* A semi-colon followed by a newline is always the end of a line. */
1955 if (line[-1] == ';')
1956 return FALSE;
1958 if (line[-1] == '|')
1959 return TRUE;
1961 /* If the || is on the next line, there might be leading whitespace. */
1962 temp++;
1963 while (*temp == ' ' || *temp == '\t') temp++;
1965 if (*temp == '|')
1966 return TRUE;
1968 return FALSE;
1971 bfd_boolean
1972 bfin_name_is_register (char *name)
1974 int i;
1976 if (*name == '[' || *name == '(')
1977 return TRUE;
1979 if ((name[0] == 'W' || name[0] == 'w') && name[1] == '[')
1980 return TRUE;
1982 if ((name[0] == 'B' || name[0] == 'b') && name[1] == '[')
1983 return TRUE;
1985 for (i=0; bfin_reg_info[i].name != 0; i++)
1987 if (!strcasecmp (bfin_reg_info[i].name, name))
1988 return TRUE;
1990 return FALSE;
1993 void
1994 bfin_equals (Expr_Node *sym)
1996 char *c;
1998 c = input_line_pointer;
1999 while (*c != '=')
2000 c--;
2002 input_line_pointer = c;
2004 equals ((char *) sym->value.s_value, 1);
2007 bfd_boolean
2008 bfin_start_label (char *ptr)
2010 ptr--;
2011 while (!ISSPACE (*ptr) && !is_end_of_line[(unsigned char) *ptr])
2012 ptr--;
2014 ptr++;
2015 if (*ptr == '(' || *ptr == '[')
2016 return FALSE;
2018 return TRUE;
2022 bfin_force_relocation (struct fix *fixp)
2024 if (fixp->fx_r_type ==BFD_RELOC_BFIN_16_LOW
2025 || fixp->fx_r_type == BFD_RELOC_BFIN_16_HIGH)
2026 return TRUE;
2028 return generic_force_reloc (fixp);