PR gas/5135
[binutils.git] / gas / config / tc-bfin.c
bloba6c6e1332cc4948b4ec47047f3a34f4124a682bb
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 /* Turn a string in input_line_pointer into a floating point
694 constant of type type, and store the appropriate bytes in
695 *litP. The number of LITTLENUMS emitted is stored in *sizeP.
696 An error message is returned, or NULL on OK. */
698 /* Equal to MAX_PRECISION in atof-ieee.c. */
699 #define MAX_LITTLENUMS 6
701 char *
702 md_atof (type, litP, sizeP)
703 char type;
704 char * litP;
705 int * sizeP;
707 int prec;
708 LITTLENUM_TYPE words [MAX_LITTLENUMS];
709 LITTLENUM_TYPE *wordP;
710 char * t;
712 switch (type)
714 case 'f':
715 case 'F':
716 prec = 2;
717 break;
719 case 'd':
720 case 'D':
721 prec = 4;
722 break;
724 /* FIXME: Some targets allow other format chars for bigger sizes here. */
726 default:
727 *sizeP = 0;
728 return _("Bad call to md_atof()");
731 t = atof_ieee (input_line_pointer, type, words);
732 if (t)
733 input_line_pointer = t;
734 *sizeP = prec * sizeof (LITTLENUM_TYPE);
736 *sizeP = prec * sizeof (LITTLENUM_TYPE);
737 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
738 the littleendianness of the processor. */
739 for (wordP = words + prec - 1; prec--;)
741 md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
742 litP += sizeof (LITTLENUM_TYPE);
745 return 0;
749 /* If while processing a fixup, a reloc really needs to be created
750 then it is done here. */
752 arelent *
753 tc_gen_reloc (seg, fixp)
754 asection *seg ATTRIBUTE_UNUSED;
755 fixS *fixp;
757 arelent *reloc;
759 reloc = (arelent *) xmalloc (sizeof (arelent));
760 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
761 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
762 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
764 reloc->addend = fixp->fx_offset;
765 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
767 if (reloc->howto == (reloc_howto_type *) NULL)
769 as_bad_where (fixp->fx_file, fixp->fx_line,
770 /* xgettext:c-format. */
771 _("reloc %d not supported by object file format"),
772 (int) fixp->fx_r_type);
774 xfree (reloc);
776 return NULL;
779 return reloc;
782 /* The location from which a PC relative jump should be calculated,
783 given a PC relative reloc. */
785 long
786 md_pcrel_from_section (fixP, sec)
787 fixS *fixP;
788 segT sec;
790 if (fixP->fx_addsy != (symbolS *) NULL
791 && (!S_IS_DEFINED (fixP->fx_addsy)
792 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
794 /* The symbol is undefined (or is defined but not in this section).
795 Let the linker figure it out. */
796 return 0;
798 return fixP->fx_frag->fr_address + fixP->fx_where;
801 /* Return true if the fix can be handled by GAS, false if it must
802 be passed through to the linker. */
804 bfd_boolean
805 bfin_fix_adjustable (fixS *fixP)
807 switch (fixP->fx_r_type)
809 /* Adjust_reloc_syms doesn't know about the GOT. */
810 case BFD_RELOC_BFIN_GOT:
811 case BFD_RELOC_BFIN_GOT17M4:
812 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
813 case BFD_RELOC_BFIN_PLTPC:
814 /* We need the symbol name for the VTABLE entries. */
815 case BFD_RELOC_VTABLE_INHERIT:
816 case BFD_RELOC_VTABLE_ENTRY:
817 return 0;
819 default:
820 return 1;
825 /* Handle the LOOP_BEGIN and LOOP_END statements.
826 Parse the Loop_Begin/Loop_End and create a label. */
827 void
828 bfin_start_line_hook ()
830 bfd_boolean maybe_begin = FALSE;
831 bfd_boolean maybe_end = FALSE;
833 char *c1, *label_name;
834 symbolS *line_label;
835 char *c = input_line_pointer;
836 int cr_num = 0;
838 while (ISSPACE (*c))
840 if (*c == '\n')
841 cr_num++;
842 c++;
845 /* Look for Loop_Begin or Loop_End statements. */
847 if (*c != 'L' && *c != 'l')
848 return;
850 c++;
851 if (*c != 'O' && *c != 'o')
852 return;
854 c++;
855 if (*c != 'O' && *c != 'o')
856 return;
858 c++;
859 if (*c != 'P' && *c != 'p')
860 return;
862 c++;
863 if (*c != '_')
864 return;
866 c++;
867 if (*c == 'E' || *c == 'e')
868 maybe_end = TRUE;
869 else if (*c == 'B' || *c == 'b')
870 maybe_begin = TRUE;
871 else
872 return;
874 if (maybe_end)
876 c++;
877 if (*c != 'N' && *c != 'n')
878 return;
880 c++;
881 if (*c != 'D' && *c != 'd')
882 return;
885 if (maybe_begin)
887 c++;
888 if (*c != 'E' && *c != 'e')
889 return;
891 c++;
892 if (*c != 'G' && *c != 'g')
893 return;
895 c++;
896 if (*c != 'I' && *c != 'i')
897 return;
899 c++;
900 if (*c != 'N' && *c != 'n')
901 return;
904 c++;
905 while (ISSPACE (*c)) c++;
906 c1 = c;
907 while (ISALPHA (*c) || ISDIGIT (*c) || *c == '_') c++;
909 if (input_line_pointer[-1] == '\n')
910 bump_line_counters ();
912 while (cr_num--)
913 bump_line_counters ();
915 input_line_pointer = c;
916 if (maybe_end)
918 label_name = (char *) xmalloc ((c - c1) + strlen ("__END") + 1);
919 label_name[0] = 0;
920 strncat (label_name, c1, c-c1);
921 strcat (label_name, "__END");
923 else /* maybe_begin. */
925 label_name = (char *) xmalloc ((c - c1) + strlen ("__BEGIN") + 1);
926 label_name[0] = 0;
927 strncat (label_name, c1, c-c1);
928 strcat (label_name, "__BEGIN");
931 line_label = colon (label_name);
933 /* Loop_End follows the last instruction in the loop.
934 Adjust label address. */
935 if (maybe_end)
936 line_label->sy_value.X_add_number -= last_insn_size;
940 /* Special extra functions that help bfin-parse.y perform its job. */
942 #include <assert.h>
944 struct obstack mempool;
946 INSTR_T
947 conscode (INSTR_T head, INSTR_T tail)
949 if (!head)
950 return tail;
951 head->next = tail;
952 return head;
955 INSTR_T
956 conctcode (INSTR_T head, INSTR_T tail)
958 INSTR_T temp = (head);
959 if (!head)
960 return tail;
961 while (temp->next)
962 temp = temp->next;
963 temp->next = tail;
965 return head;
968 INSTR_T
969 note_reloc (INSTR_T code, Expr_Node * symbol, int reloc, int pcrel)
971 /* Assert that the symbol is not an operator. */
972 assert (symbol->type == Expr_Node_Reloc);
974 return note_reloc1 (code, symbol->value.s_value, reloc, pcrel);
978 INSTR_T
979 note_reloc1 (INSTR_T code, const char *symbol, int reloc, int pcrel)
981 code->reloc = reloc;
982 code->exp = mkexpr (0, symbol_find_or_make (symbol));
983 code->pcrel = pcrel;
984 return code;
987 INSTR_T
988 note_reloc2 (INSTR_T code, const char *symbol, int reloc, int value, int pcrel)
990 code->reloc = reloc;
991 code->exp = mkexpr (value, symbol_find_or_make (symbol));
992 code->pcrel = pcrel;
993 return code;
996 INSTR_T
997 gencode (unsigned long x)
999 INSTR_T cell = (INSTR_T) obstack_alloc (&mempool, sizeof (struct bfin_insn));
1000 memset (cell, 0, sizeof (struct bfin_insn));
1001 cell->value = (x);
1002 return cell;
1005 int reloc;
1006 int ninsns;
1007 int count_insns;
1009 static void *
1010 allocate (int n)
1012 return (void *) obstack_alloc (&mempool, n);
1015 Expr_Node *
1016 Expr_Node_Create (Expr_Node_Type type,
1017 Expr_Node_Value value,
1018 Expr_Node *Left_Child,
1019 Expr_Node *Right_Child)
1023 Expr_Node *node = (Expr_Node *) allocate (sizeof (Expr_Node));
1024 node->type = type;
1025 node->value = value;
1026 node->Left_Child = Left_Child;
1027 node->Right_Child = Right_Child;
1028 return node;
1031 static const char *con = ".__constant";
1032 static const char *op = ".__operator";
1033 static INSTR_T Expr_Node_Gen_Reloc_R (Expr_Node * head);
1034 INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc);
1036 INSTR_T
1037 Expr_Node_Gen_Reloc (Expr_Node * head, int parent_reloc)
1039 /* Top level reloction expression generator VDSP style.
1040 If the relocation is just by itself, generate one item
1041 else generate this convoluted expression. */
1043 INSTR_T note = NULL_CODE;
1044 INSTR_T note1 = NULL_CODE;
1045 int pcrel = 1; /* Is the parent reloc pcrelative?
1046 This calculation here and HOWTO should match. */
1048 if (parent_reloc)
1050 /* If it's 32 bit quantity then 16bit code needs to be added. */
1051 int value = 0;
1053 if (head->type == Expr_Node_Constant)
1055 /* If note1 is not null code, we have to generate a right
1056 aligned value for the constant. Otherwise the reloc is
1057 a part of the basic command and the yacc file
1058 generates this. */
1059 value = head->value.i_value;
1061 switch (parent_reloc)
1063 /* Some relocations will need to allocate extra words. */
1064 case BFD_RELOC_BFIN_16_IMM:
1065 case BFD_RELOC_BFIN_16_LOW:
1066 case BFD_RELOC_BFIN_16_HIGH:
1067 note1 = conscode (gencode (value), NULL_CODE);
1068 pcrel = 0;
1069 break;
1070 case BFD_RELOC_BFIN_PLTPC:
1071 note1 = conscode (gencode (value), NULL_CODE);
1072 pcrel = 0;
1073 break;
1074 case BFD_RELOC_16:
1075 case BFD_RELOC_BFIN_GOT:
1076 case BFD_RELOC_BFIN_GOT17M4:
1077 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
1078 note1 = conscode (gencode (value), NULL_CODE);
1079 pcrel = 0;
1080 break;
1081 case BFD_RELOC_24_PCREL:
1082 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
1083 case BFD_RELOC_BFIN_24_PCREL_CALL_X:
1084 /* These offsets are even numbered pcrel. */
1085 note1 = conscode (gencode (value >> 1), NULL_CODE);
1086 break;
1087 default:
1088 note1 = NULL_CODE;
1091 if (head->type == Expr_Node_Constant)
1092 note = note1;
1093 else if (head->type == Expr_Node_Reloc)
1095 note = note_reloc1 (gencode (0), head->value.s_value, parent_reloc, pcrel);
1096 if (note1 != NULL_CODE)
1097 note = conscode (note1, note);
1099 else if (head->type == Expr_Node_Binop
1100 && (head->value.op_value == Expr_Op_Type_Add
1101 || head->value.op_value == Expr_Op_Type_Sub)
1102 && head->Left_Child->type == Expr_Node_Reloc
1103 && head->Right_Child->type == Expr_Node_Constant)
1105 int val = head->Right_Child->value.i_value;
1106 if (head->value.op_value == Expr_Op_Type_Sub)
1107 val = -val;
1108 note = conscode (note_reloc2 (gencode (0), head->Left_Child->value.s_value,
1109 parent_reloc, val, 0),
1110 NULL_CODE);
1111 if (note1 != NULL_CODE)
1112 note = conscode (note1, note);
1114 else
1116 /* Call the recursive function. */
1117 note = note_reloc1 (gencode (0), op, parent_reloc, pcrel);
1118 if (note1 != NULL_CODE)
1119 note = conscode (note1, note);
1120 note = conctcode (Expr_Node_Gen_Reloc_R (head), note);
1122 return note;
1125 static INSTR_T
1126 Expr_Node_Gen_Reloc_R (Expr_Node * head)
1129 INSTR_T note = 0;
1130 INSTR_T note1 = 0;
1132 switch (head->type)
1134 case Expr_Node_Constant:
1135 note = conscode (note_reloc2 (gencode (0), con, BFD_ARELOC_BFIN_CONST, head->value.i_value, 0), NULL_CODE);
1136 break;
1137 case Expr_Node_Reloc:
1138 note = conscode (note_reloc (gencode (0), head, BFD_ARELOC_BFIN_PUSH, 0), NULL_CODE);
1139 break;
1140 case Expr_Node_Binop:
1141 note1 = conctcode (Expr_Node_Gen_Reloc_R (head->Left_Child), Expr_Node_Gen_Reloc_R (head->Right_Child));
1142 switch (head->value.op_value)
1144 case Expr_Op_Type_Add:
1145 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_ADD, 0), NULL_CODE));
1146 break;
1147 case Expr_Op_Type_Sub:
1148 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_SUB, 0), NULL_CODE));
1149 break;
1150 case Expr_Op_Type_Mult:
1151 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MULT, 0), NULL_CODE));
1152 break;
1153 case Expr_Op_Type_Div:
1154 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_DIV, 0), NULL_CODE));
1155 break;
1156 case Expr_Op_Type_Mod:
1157 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MOD, 0), NULL_CODE));
1158 break;
1159 case Expr_Op_Type_Lshift:
1160 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LSHIFT, 0), NULL_CODE));
1161 break;
1162 case Expr_Op_Type_Rshift:
1163 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_RSHIFT, 0), NULL_CODE));
1164 break;
1165 case Expr_Op_Type_BAND:
1166 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_AND, 0), NULL_CODE));
1167 break;
1168 case Expr_Op_Type_BOR:
1169 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_OR, 0), NULL_CODE));
1170 break;
1171 case Expr_Op_Type_BXOR:
1172 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_XOR, 0), NULL_CODE));
1173 break;
1174 case Expr_Op_Type_LAND:
1175 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LAND, 0), NULL_CODE));
1176 break;
1177 case Expr_Op_Type_LOR:
1178 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LOR, 0), NULL_CODE));
1179 break;
1180 default:
1181 fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
1185 break;
1186 case Expr_Node_Unop:
1187 note1 = conscode (Expr_Node_Gen_Reloc_R (head->Left_Child), NULL_CODE);
1188 switch (head->value.op_value)
1190 case Expr_Op_Type_NEG:
1191 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_NEG, 0), NULL_CODE));
1192 break;
1193 case Expr_Op_Type_COMP:
1194 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_COMP, 0), NULL_CODE));
1195 break;
1196 default:
1197 fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
1199 break;
1200 default:
1201 fprintf (stderr, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__, __LINE__);
1203 return note;
1207 /* Blackfin opcode generation. */
1209 /* These functions are called by the generated parser
1210 (from bfin-parse.y), the register type classification
1211 happens in bfin-lex.l. */
1213 #include "bfin-aux.h"
1214 #include "opcode/bfin.h"
1216 #define INIT(t) t c_code = init_##t
1217 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1218 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1220 #define HI(x) ((x >> 16) & 0xffff)
1221 #define LO(x) ((x ) & 0xffff)
1223 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1225 #define GEN_OPCODE32() \
1226 conscode (gencode (HI (c_code.opcode)), \
1227 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1229 #define GEN_OPCODE16() \
1230 conscode (gencode (c_code.opcode), NULL_CODE)
1233 /* 32 BIT INSTRUCTIONS. */
1236 /* DSP32 instruction generation. */
1238 INSTR_T
1239 bfin_gen_dsp32mac (int op1, int MM, int mmod, int w1, int P,
1240 int h01, int h11, int h00, int h10, int op0,
1241 REG_T dst, REG_T src0, REG_T src1, int w0)
1243 INIT (DSP32Mac);
1245 ASSIGN (op0);
1246 ASSIGN (op1);
1247 ASSIGN (MM);
1248 ASSIGN (mmod);
1249 ASSIGN (w0);
1250 ASSIGN (w1);
1251 ASSIGN (h01);
1252 ASSIGN (h11);
1253 ASSIGN (h00);
1254 ASSIGN (h10);
1255 ASSIGN (P);
1257 /* If we have full reg assignments, mask out LSB to encode
1258 single or simultaneous even/odd register moves. */
1259 if (P)
1261 dst->regno &= 0x06;
1264 ASSIGN_R (dst);
1265 ASSIGN_R (src0);
1266 ASSIGN_R (src1);
1268 return GEN_OPCODE32 ();
1271 INSTR_T
1272 bfin_gen_dsp32mult (int op1, int MM, int mmod, int w1, int P,
1273 int h01, int h11, int h00, int h10, int op0,
1274 REG_T dst, REG_T src0, REG_T src1, int w0)
1276 INIT (DSP32Mult);
1278 ASSIGN (op0);
1279 ASSIGN (op1);
1280 ASSIGN (MM);
1281 ASSIGN (mmod);
1282 ASSIGN (w0);
1283 ASSIGN (w1);
1284 ASSIGN (h01);
1285 ASSIGN (h11);
1286 ASSIGN (h00);
1287 ASSIGN (h10);
1288 ASSIGN (P);
1290 if (P)
1292 dst->regno &= 0x06;
1295 ASSIGN_R (dst);
1296 ASSIGN_R (src0);
1297 ASSIGN_R (src1);
1299 return GEN_OPCODE32 ();
1302 INSTR_T
1303 bfin_gen_dsp32alu (int HL, int aopcde, int aop, int s, int x,
1304 REG_T dst0, REG_T dst1, REG_T src0, REG_T src1)
1306 INIT (DSP32Alu);
1308 ASSIGN (HL);
1309 ASSIGN (aopcde);
1310 ASSIGN (aop);
1311 ASSIGN (s);
1312 ASSIGN (x);
1313 ASSIGN_R (dst0);
1314 ASSIGN_R (dst1);
1315 ASSIGN_R (src0);
1316 ASSIGN_R (src1);
1318 return GEN_OPCODE32 ();
1321 INSTR_T
1322 bfin_gen_dsp32shift (int sopcde, REG_T dst0, REG_T src0,
1323 REG_T src1, int sop, int HLs)
1325 INIT (DSP32Shift);
1327 ASSIGN (sopcde);
1328 ASSIGN (sop);
1329 ASSIGN (HLs);
1331 ASSIGN_R (dst0);
1332 ASSIGN_R (src0);
1333 ASSIGN_R (src1);
1335 return GEN_OPCODE32 ();
1338 INSTR_T
1339 bfin_gen_dsp32shiftimm (int sopcde, REG_T dst0, int immag,
1340 REG_T src1, int sop, int HLs)
1342 INIT (DSP32ShiftImm);
1344 ASSIGN (sopcde);
1345 ASSIGN (sop);
1346 ASSIGN (HLs);
1348 ASSIGN_R (dst0);
1349 ASSIGN (immag);
1350 ASSIGN_R (src1);
1352 return GEN_OPCODE32 ();
1355 /* LOOP SETUP. */
1357 INSTR_T
1358 bfin_gen_loopsetup (Expr_Node * psoffset, REG_T c, int rop,
1359 Expr_Node * peoffset, REG_T reg)
1361 int soffset, eoffset;
1362 INIT (LoopSetup);
1364 soffset = (EXPR_VALUE (psoffset) >> 1);
1365 ASSIGN (soffset);
1366 eoffset = (EXPR_VALUE (peoffset) >> 1);
1367 ASSIGN (eoffset);
1368 ASSIGN (rop);
1369 ASSIGN_R (c);
1370 ASSIGN_R (reg);
1372 return
1373 conscode (gencode (HI (c_code.opcode)),
1374 conctcode (Expr_Node_Gen_Reloc (psoffset, BFD_RELOC_BFIN_5_PCREL),
1375 conctcode (gencode (LO (c_code.opcode)), Expr_Node_Gen_Reloc (peoffset, BFD_RELOC_BFIN_11_PCREL))));
1379 /* Call, Link. */
1381 INSTR_T
1382 bfin_gen_calla (Expr_Node * addr, int S)
1384 int val;
1385 int high_val;
1386 int reloc = 0;
1387 INIT (CALLa);
1389 switch(S){
1390 case 0 : reloc = BFD_RELOC_BFIN_24_PCREL_JUMP_L; break;
1391 case 1 : reloc = BFD_RELOC_24_PCREL; break;
1392 case 2 : reloc = BFD_RELOC_BFIN_PLTPC; break;
1393 default : break;
1396 ASSIGN (S);
1398 val = EXPR_VALUE (addr) >> 1;
1399 high_val = val >> 16;
1401 return conscode (gencode (HI (c_code.opcode) | (high_val & 0xff)),
1402 Expr_Node_Gen_Reloc (addr, reloc));
1405 INSTR_T
1406 bfin_gen_linkage (int R, int framesize)
1408 INIT (Linkage);
1410 ASSIGN (R);
1411 ASSIGN (framesize);
1413 return GEN_OPCODE32 ();
1417 /* Load and Store. */
1419 INSTR_T
1420 bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int reloc)
1422 int grp, hword;
1423 unsigned val = EXPR_VALUE (phword);
1424 INIT (LDIMMhalf);
1426 ASSIGN (H);
1427 ASSIGN (S);
1428 ASSIGN (Z);
1430 ASSIGN_R (reg);
1431 grp = (GROUP (reg));
1432 ASSIGN (grp);
1433 if (reloc == 2)
1435 return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, BFD_RELOC_BFIN_16_IMM));
1437 else if (reloc == 1)
1439 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));
1441 else
1443 hword = val;
1444 ASSIGN (hword);
1446 return GEN_OPCODE32 ();
1449 INSTR_T
1450 bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset)
1452 INIT (LDSTidxI);
1454 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1456 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1457 return 0;
1460 ASSIGN_R (ptr);
1461 ASSIGN_R (reg);
1462 ASSIGN (W);
1463 ASSIGN (sz);
1465 ASSIGN (Z);
1467 if (poffset->type != Expr_Node_Constant)
1469 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1470 /* distinguish between R0 = [P5 + symbol@GOT] and
1471 P5 = [P5 + _current_shared_library_p5_offset_]
1473 if (poffset->type == Expr_Node_Reloc
1474 && !strcmp (poffset->value.s_value,
1475 "_current_shared_library_p5_offset_"))
1477 return conscode (gencode (HI (c_code.opcode)),
1478 Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16));
1480 else if (poffset->type != Expr_Node_GOT_Reloc)
1481 abort ();
1483 return conscode (gencode (HI (c_code.opcode)),
1484 Expr_Node_Gen_Reloc(poffset->Left_Child,
1485 poffset->value.i_value));
1487 else
1489 int value, offset;
1490 switch (sz)
1491 { // load/store access size
1492 case 0: // 32 bit
1493 value = EXPR_VALUE (poffset) >> 2;
1494 break;
1495 case 1: // 16 bit
1496 value = EXPR_VALUE (poffset) >> 1;
1497 break;
1498 case 2: // 8 bit
1499 value = EXPR_VALUE (poffset);
1500 break;
1501 default:
1502 abort ();
1505 offset = (value & 0xffff);
1506 ASSIGN (offset);
1507 return GEN_OPCODE32 ();
1512 INSTR_T
1513 bfin_gen_ldst (REG_T ptr, REG_T reg, int aop, int sz, int Z, int W)
1515 INIT (LDST);
1517 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1519 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1520 return 0;
1523 ASSIGN_R (ptr);
1524 ASSIGN_R (reg);
1525 ASSIGN (aop);
1526 ASSIGN (sz);
1527 ASSIGN (Z);
1528 ASSIGN (W);
1530 return GEN_OPCODE16 ();
1533 INSTR_T
1534 bfin_gen_ldstii (REG_T ptr, REG_T reg, Expr_Node * poffset, int W, int op)
1536 int offset;
1537 int value = 0;
1538 INIT (LDSTii);
1541 if (!IS_PREG (*ptr))
1543 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1544 return 0;
1547 switch (op)
1549 case 1:
1550 case 2:
1551 value = EXPR_VALUE (poffset) >> 1;
1552 break;
1553 case 0:
1554 case 3:
1555 value = EXPR_VALUE (poffset) >> 2;
1556 break;
1559 ASSIGN_R (ptr);
1560 ASSIGN_R (reg);
1562 offset = value;
1563 ASSIGN (offset);
1564 ASSIGN (W);
1565 ASSIGN (op);
1567 return GEN_OPCODE16 ();
1570 INSTR_T
1571 bfin_gen_ldstiifp (REG_T sreg, Expr_Node * poffset, int W)
1573 /* Set bit 4 if it's a Preg. */
1574 int reg = (sreg->regno & CODE_MASK) | (IS_PREG (*sreg) ? 0x8 : 0x0);
1575 int offset = ((~(EXPR_VALUE (poffset) >> 2)) & 0x1f) + 1;
1576 INIT (LDSTiiFP);
1577 ASSIGN (reg);
1578 ASSIGN (offset);
1579 ASSIGN (W);
1581 return GEN_OPCODE16 ();
1584 INSTR_T
1585 bfin_gen_ldstpmod (REG_T ptr, REG_T reg, int aop, int W, REG_T idx)
1587 INIT (LDSTpmod);
1589 ASSIGN_R (ptr);
1590 ASSIGN_R (reg);
1591 ASSIGN (aop);
1592 ASSIGN (W);
1593 ASSIGN_R (idx);
1595 return GEN_OPCODE16 ();
1598 INSTR_T
1599 bfin_gen_dspldst (REG_T i, REG_T reg, int aop, int W, int m)
1601 INIT (DspLDST);
1603 ASSIGN_R (i);
1604 ASSIGN_R (reg);
1605 ASSIGN (aop);
1606 ASSIGN (W);
1607 ASSIGN (m);
1609 return GEN_OPCODE16 ();
1612 INSTR_T
1613 bfin_gen_logi2op (int opc, int src, int dst)
1615 INIT (LOGI2op);
1617 ASSIGN (opc);
1618 ASSIGN (src);
1619 ASSIGN (dst);
1621 return GEN_OPCODE16 ();
1624 INSTR_T
1625 bfin_gen_brcc (int T, int B, Expr_Node * poffset)
1627 int offset;
1628 INIT (BRCC);
1630 ASSIGN (T);
1631 ASSIGN (B);
1632 offset = ((EXPR_VALUE (poffset) >> 1));
1633 ASSIGN (offset);
1634 return conscode (gencode (c_code.opcode), Expr_Node_Gen_Reloc (poffset, BFD_RELOC_BFIN_10_PCREL));
1637 INSTR_T
1638 bfin_gen_ujump (Expr_Node * poffset)
1640 int offset;
1641 INIT (UJump);
1643 offset = ((EXPR_VALUE (poffset) >> 1));
1644 ASSIGN (offset);
1646 return conscode (gencode (c_code.opcode),
1647 Expr_Node_Gen_Reloc (
1648 poffset, BFD_RELOC_BFIN_12_PCREL_JUMP_S));
1651 INSTR_T
1652 bfin_gen_alu2op (REG_T dst, REG_T src, int opc)
1654 INIT (ALU2op);
1656 ASSIGN_R (dst);
1657 ASSIGN_R (src);
1658 ASSIGN (opc);
1660 return GEN_OPCODE16 ();
1663 INSTR_T
1664 bfin_gen_compi2opd (REG_T dst, int src, int op)
1666 INIT (COMPI2opD);
1668 ASSIGN_R (dst);
1669 ASSIGN (src);
1670 ASSIGN (op);
1672 return GEN_OPCODE16 ();
1675 INSTR_T
1676 bfin_gen_compi2opp (REG_T dst, int src, int op)
1678 INIT (COMPI2opP);
1680 ASSIGN_R (dst);
1681 ASSIGN (src);
1682 ASSIGN (op);
1684 return GEN_OPCODE16 ();
1687 INSTR_T
1688 bfin_gen_dagmodik (REG_T i, int op)
1690 INIT (DagMODik);
1692 ASSIGN_R (i);
1693 ASSIGN (op);
1695 return GEN_OPCODE16 ();
1698 INSTR_T
1699 bfin_gen_dagmodim (REG_T i, REG_T m, int op, int br)
1701 INIT (DagMODim);
1703 ASSIGN_R (i);
1704 ASSIGN_R (m);
1705 ASSIGN (op);
1706 ASSIGN (br);
1708 return GEN_OPCODE16 ();
1711 INSTR_T
1712 bfin_gen_ptr2op (REG_T dst, REG_T src, int opc)
1714 INIT (PTR2op);
1716 ASSIGN_R (dst);
1717 ASSIGN_R (src);
1718 ASSIGN (opc);
1720 return GEN_OPCODE16 ();
1723 INSTR_T
1724 bfin_gen_comp3op (REG_T src0, REG_T src1, REG_T dst, int opc)
1726 INIT (COMP3op);
1728 ASSIGN_R (src0);
1729 ASSIGN_R (src1);
1730 ASSIGN_R (dst);
1731 ASSIGN (opc);
1733 return GEN_OPCODE16 ();
1736 INSTR_T
1737 bfin_gen_ccflag (REG_T x, int y, int opc, int I, int G)
1739 INIT (CCflag);
1741 ASSIGN_R (x);
1742 ASSIGN (y);
1743 ASSIGN (opc);
1744 ASSIGN (I);
1745 ASSIGN (G);
1747 return GEN_OPCODE16 ();
1750 INSTR_T
1751 bfin_gen_ccmv (REG_T src, REG_T dst, int T)
1753 int s, d;
1754 INIT (CCmv);
1756 ASSIGN_R (src);
1757 ASSIGN_R (dst);
1758 s = (GROUP (src));
1759 ASSIGN (s);
1760 d = (GROUP (dst));
1761 ASSIGN (d);
1762 ASSIGN (T);
1764 return GEN_OPCODE16 ();
1767 INSTR_T
1768 bfin_gen_cc2stat (int cbit, int op, int D)
1770 INIT (CC2stat);
1772 ASSIGN (cbit);
1773 ASSIGN (op);
1774 ASSIGN (D);
1776 return GEN_OPCODE16 ();
1779 INSTR_T
1780 bfin_gen_regmv (REG_T src, REG_T dst)
1782 int gs, gd;
1783 INIT (RegMv);
1785 ASSIGN_R (src);
1786 ASSIGN_R (dst);
1788 gs = (GROUP (src));
1789 ASSIGN (gs);
1790 gd = (GROUP (dst));
1791 ASSIGN (gd);
1793 return GEN_OPCODE16 ();
1796 INSTR_T
1797 bfin_gen_cc2dreg (int op, REG_T reg)
1799 INIT (CC2dreg);
1801 ASSIGN (op);
1802 ASSIGN_R (reg);
1804 return GEN_OPCODE16 ();
1807 INSTR_T
1808 bfin_gen_progctrl (int prgfunc, int poprnd)
1810 INIT (ProgCtrl);
1812 ASSIGN (prgfunc);
1813 ASSIGN (poprnd);
1815 return GEN_OPCODE16 ();
1818 INSTR_T
1819 bfin_gen_cactrl (REG_T reg, int a, int op)
1821 INIT (CaCTRL);
1823 ASSIGN_R (reg);
1824 ASSIGN (a);
1825 ASSIGN (op);
1827 return GEN_OPCODE16 ();
1830 INSTR_T
1831 bfin_gen_pushpopmultiple (int dr, int pr, int d, int p, int W)
1833 INIT (PushPopMultiple);
1835 ASSIGN (dr);
1836 ASSIGN (pr);
1837 ASSIGN (d);
1838 ASSIGN (p);
1839 ASSIGN (W);
1841 return GEN_OPCODE16 ();
1844 INSTR_T
1845 bfin_gen_pushpopreg (REG_T reg, int W)
1847 int grp;
1848 INIT (PushPopReg);
1850 ASSIGN_R (reg);
1851 grp = (GROUP (reg));
1852 ASSIGN (grp);
1853 ASSIGN (W);
1855 return GEN_OPCODE16 ();
1858 /* Pseudo Debugging Support. */
1860 INSTR_T
1861 bfin_gen_pseudodbg (int fn, int reg, int grp)
1863 INIT (PseudoDbg);
1865 ASSIGN (fn);
1866 ASSIGN (reg);
1867 ASSIGN (grp);
1869 return GEN_OPCODE16 ();
1872 INSTR_T
1873 bfin_gen_pseudodbg_assert (int dbgop, REG_T regtest, int expected)
1875 INIT (PseudoDbg_Assert);
1877 ASSIGN (dbgop);
1878 ASSIGN_R (regtest);
1879 ASSIGN (expected);
1881 return GEN_OPCODE32 ();
1884 /* Multiple instruction generation. */
1886 INSTR_T
1887 bfin_gen_multi_instr (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2)
1889 INSTR_T walk;
1891 /* If it's a 0, convert into MNOP. */
1892 if (dsp32)
1894 walk = dsp32->next;
1895 SET_MULTI_INSTRUCTION_BIT (dsp32);
1897 else
1899 dsp32 = gencode (0xc803);
1900 walk = gencode (0x1800);
1901 dsp32->next = walk;
1904 if (!dsp16_grp1)
1906 dsp16_grp1 = gencode (0x0000);
1909 if (!dsp16_grp2)
1911 dsp16_grp2 = gencode (0x0000);
1914 walk->next = dsp16_grp1;
1915 dsp16_grp1->next = dsp16_grp2;
1916 dsp16_grp2->next = NULL_CODE;
1918 return dsp32;
1921 INSTR_T
1922 bfin_gen_loop (Expr_Node *expr, REG_T reg, int rop, REG_T preg)
1924 const char *loopsym;
1925 char *lbeginsym, *lendsym;
1926 Expr_Node_Value lbeginval, lendval;
1927 Expr_Node *lbegin, *lend;
1929 loopsym = expr->value.s_value;
1930 lbeginsym = (char *) xmalloc (strlen (loopsym) + strlen ("__BEGIN") + 1);
1931 lendsym = (char *) xmalloc (strlen (loopsym) + strlen ("__END") + 1);
1933 lbeginsym[0] = 0;
1934 lendsym[0] = 0;
1936 strcat (lbeginsym, loopsym);
1937 strcat (lbeginsym, "__BEGIN");
1939 strcat (lendsym, loopsym);
1940 strcat (lendsym, "__END");
1942 lbeginval.s_value = lbeginsym;
1943 lendval.s_value = lendsym;
1945 lbegin = Expr_Node_Create (Expr_Node_Reloc, lbeginval, NULL, NULL);
1946 lend = Expr_Node_Create (Expr_Node_Reloc, lendval, NULL, NULL);
1947 return bfin_gen_loopsetup(lbegin, reg, rop, lend, preg);
1950 bfd_boolean
1951 bfin_eol_in_insn (char *line)
1953 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1955 char *temp = line;
1957 if (*line != '\n')
1958 return FALSE;
1960 /* A semi-colon followed by a newline is always the end of a line. */
1961 if (line[-1] == ';')
1962 return FALSE;
1964 if (line[-1] == '|')
1965 return TRUE;
1967 /* If the || is on the next line, there might be leading whitespace. */
1968 temp++;
1969 while (*temp == ' ' || *temp == '\t') temp++;
1971 if (*temp == '|')
1972 return TRUE;
1974 return FALSE;
1977 bfd_boolean
1978 bfin_start_label (char *ptr)
1980 ptr--;
1981 while (!ISSPACE (*ptr) && !is_end_of_line[(unsigned char) *ptr])
1982 ptr--;
1984 ptr++;
1985 if (*ptr == '(' || *ptr == '[')
1986 return FALSE;
1988 return TRUE;
1992 bfin_force_relocation (struct fix *fixp)
1994 if (fixp->fx_r_type ==BFD_RELOC_BFIN_16_LOW
1995 || fixp->fx_r_type == BFD_RELOC_BFIN_16_HIGH)
1996 return TRUE;
1998 return generic_force_reloc (fixp);