2006-02-14 Paolo Bonzini <bonzini@gnu.org>
[binutils.git] / gas / config / tc-bfin.c
blobd9e88de19d51e4c84f9572fe0fb83d73d3613cb9
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
32 extern int yyparse (void);
33 struct yy_buffer_state;
34 typedef struct yy_buffer_state *YY_BUFFER_STATE;
35 extern YY_BUFFER_STATE yy_scan_string (const char *yy_str);
36 extern void yy_delete_buffer (YY_BUFFER_STATE b);
37 static parse_state parse (char *line);
38 static void bfin_s_bss PARAMS ((int));
39 static int md_chars_to_number PARAMS ((char *, int));
41 /* Global variables. */
42 struct bfin_insn *insn;
43 int last_insn_size;
45 extern struct obstack mempool;
46 FILE *errorf;
48 /* Registers list. */
49 struct bfin_reg_entry
51 const char *name;
52 int number;
55 static const struct bfin_reg_entry bfin_reg_info[] = {
56 {"R0.L", REG_RL0},
57 {"R1.L", REG_RL1},
58 {"R2.L", REG_RL2},
59 {"R3.L", REG_RL3},
60 {"R4.L", REG_RL4},
61 {"R5.L", REG_RL5},
62 {"R6.L", REG_RL6},
63 {"R7.L", REG_RL7},
64 {"R0.H", REG_RH0},
65 {"R1.H", REG_RH1},
66 {"R2.H", REG_RH2},
67 {"R3.H", REG_RH3},
68 {"R4.H", REG_RH4},
69 {"R5.H", REG_RH5},
70 {"R6.H", REG_RH6},
71 {"R7.H", REG_RH7},
72 {"R0", REG_R0},
73 {"R1", REG_R1},
74 {"R2", REG_R2},
75 {"R3", REG_R3},
76 {"R4", REG_R4},
77 {"R5", REG_R5},
78 {"R6", REG_R6},
79 {"R7", REG_R7},
80 {"P0", REG_P0},
81 {"P0.H", REG_P0},
82 {"P0.L", REG_P0},
83 {"P1", REG_P1},
84 {"P1.H", REG_P1},
85 {"P1.L", REG_P1},
86 {"P2", REG_P2},
87 {"P2.H", REG_P2},
88 {"P2.L", REG_P2},
89 {"P3", REG_P3},
90 {"P3.H", REG_P3},
91 {"P3.L", REG_P3},
92 {"P4", REG_P4},
93 {"P4.H", REG_P4},
94 {"P4.L", REG_P4},
95 {"P5", REG_P5},
96 {"P5.H", REG_P5},
97 {"P5.L", REG_P5},
98 {"SP", REG_SP},
99 {"SP.L", REG_SP},
100 {"SP.H", REG_SP},
101 {"FP", REG_FP},
102 {"FP.L", REG_FP},
103 {"FP.H", REG_FP},
104 {"A0x", REG_A0x},
105 {"A1x", REG_A1x},
106 {"A0w", REG_A0w},
107 {"A1w", REG_A1w},
108 {"A0.x", REG_A0x},
109 {"A1.x", REG_A1x},
110 {"A0.w", REG_A0w},
111 {"A1.w", REG_A1w},
112 {"A0", REG_A0},
113 {"A0.L", REG_A0},
114 {"A0.H", REG_A0},
115 {"A1", REG_A1},
116 {"A1.L", REG_A1},
117 {"A1.H", REG_A1},
118 {"I0", REG_I0},
119 {"I0.L", REG_I0},
120 {"I0.H", REG_I0},
121 {"I1", REG_I1},
122 {"I1.L", REG_I1},
123 {"I1.H", REG_I1},
124 {"I2", REG_I2},
125 {"I2.L", REG_I2},
126 {"I2.H", REG_I2},
127 {"I3", REG_I3},
128 {"I3.L", REG_I3},
129 {"I3.H", REG_I3},
130 {"M0", REG_M0},
131 {"M0.H", REG_M0},
132 {"M0.L", REG_M0},
133 {"M1", REG_M1},
134 {"M1.H", REG_M1},
135 {"M1.L", REG_M1},
136 {"M2", REG_M2},
137 {"M2.H", REG_M2},
138 {"M2.L", REG_M2},
139 {"M3", REG_M3},
140 {"M3.H", REG_M3},
141 {"M3.L", REG_M3},
142 {"B0", REG_B0},
143 {"B0.H", REG_B0},
144 {"B0.L", REG_B0},
145 {"B1", REG_B1},
146 {"B1.H", REG_B1},
147 {"B1.L", REG_B1},
148 {"B2", REG_B2},
149 {"B2.H", REG_B2},
150 {"B2.L", REG_B2},
151 {"B3", REG_B3},
152 {"B3.H", REG_B3},
153 {"B3.L", REG_B3},
154 {"L0", REG_L0},
155 {"L0.H", REG_L0},
156 {"L0.L", REG_L0},
157 {"L1", REG_L1},
158 {"L1.H", REG_L1},
159 {"L1.L", REG_L1},
160 {"L2", REG_L2},
161 {"L2.H", REG_L2},
162 {"L2.L", REG_L2},
163 {"L3", REG_L3},
164 {"L3.H", REG_L3},
165 {"L3.L", REG_L3},
166 {"AZ", S_AZ},
167 {"AN", S_AN},
168 {"AC0", S_AC0},
169 {"AC1", S_AC1},
170 {"AV0", S_AV0},
171 {"AV0S", S_AV0S},
172 {"AV1", S_AV1},
173 {"AV1S", S_AV1S},
174 {"AQ", S_AQ},
175 {"V", S_V},
176 {"VS", S_VS},
177 {"sftreset", REG_sftreset},
178 {"omode", REG_omode},
179 {"excause", REG_excause},
180 {"emucause", REG_emucause},
181 {"idle_req", REG_idle_req},
182 {"hwerrcause", REG_hwerrcause},
183 {"CC", REG_CC},
184 {"LC0", REG_LC0},
185 {"LC1", REG_LC1},
186 {"ASTAT", REG_ASTAT},
187 {"RETS", REG_RETS},
188 {"LT0", REG_LT0},
189 {"LB0", REG_LB0},
190 {"LT1", REG_LT1},
191 {"LB1", REG_LB1},
192 {"CYCLES", REG_CYCLES},
193 {"CYCLES2", REG_CYCLES2},
194 {"USP", REG_USP},
195 {"SEQSTAT", REG_SEQSTAT},
196 {"SYSCFG", REG_SYSCFG},
197 {"RETI", REG_RETI},
198 {"RETX", REG_RETX},
199 {"RETN", REG_RETN},
200 {"RETE", REG_RETE},
201 {"EMUDAT", REG_EMUDAT},
202 {0, 0}
206 const pseudo_typeS md_pseudo_table[] = {
207 {"align", s_align_bytes, 0},
208 {"byte2", cons, 2},
209 {"byte4", cons, 4},
210 {"code", obj_elf_section, 0},
211 {"db", cons, 1},
212 {"dd", cons, 4},
213 {"dw", cons, 2},
214 {"p", s_ignore, 0},
215 {"pdata", s_ignore, 0},
216 {"var", s_ignore, 0},
217 {"bss", bfin_s_bss, 0},
218 {0, 0, 0}
221 static void
222 bfin_s_bss (int ignore ATTRIBUTE_UNUSED)
224 register int temp;
226 temp = get_absolute_expression ();
227 subseg_set (bss_section, (subsegT) temp);
228 demand_empty_rest_of_line ();
232 /* Characters that are used to denote comments and line separators. */
233 const char comment_chars[] = "";
234 const char line_comment_chars[] = "#";
235 const char line_separator_chars[] = ";";
237 /* Characters that can be used to separate the mantissa from the
238 exponent in floating point numbers. */
239 const char EXP_CHARS[] = "eE";
241 /* Characters that mean this number is a floating point constant.
242 As in 0f12.456 or 0d1.2345e12. */
243 const char FLT_CHARS[] = "fFdDxX";
245 /* Define bfin-specific command-line options (there are none). */
246 const char *md_shortopts = "";
248 struct option md_longopts[] = {
249 {NULL, no_argument, NULL, 0}
251 size_t md_longopts_size = sizeof (md_longopts);
255 md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
257 return 0;
260 void
261 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
263 fprintf (stream, _(" BFIN specific command line options:\n"));
266 /* Perform machine-specific initializations. */
267 void
268 md_begin ()
270 /* Set the default machine type. */
271 if (!bfd_set_arch_mach (stdoutput, bfd_arch_bfin, 0))
272 as_warn ("Could not set architecture and machine.");
274 /* Ensure that lines can begin with '(', for multiple
275 register stack pops. */
276 lex_type ['('] = LEX_BEGIN_NAME;
278 #ifdef OBJ_ELF
279 record_alignment (text_section, 2);
280 record_alignment (data_section, 2);
281 record_alignment (bss_section, 2);
282 #endif
284 errorf = stderr;
285 obstack_init (&mempool);
287 #ifdef DEBUG
288 extern int debug_codeselection;
289 debug_codeselection = 1;
290 #endif
292 last_insn_size = 0;
295 /* Perform the main parsing, and assembly of the input here. Also,
296 call the required routines for alignment and fixups here.
297 This is called for every line that contains real assembly code. */
299 void
300 md_assemble (char *line)
302 char *toP = 0;
303 extern char *current_inputline;
304 int size, insn_size;
305 struct bfin_insn *tmp_insn;
306 size_t len;
307 static size_t buffer_len = 0;
308 parse_state state;
310 len = strlen (line);
311 if (len + 2 > buffer_len)
313 if (buffer_len > 0)
314 free (current_inputline);
315 buffer_len = len + 40;
316 current_inputline = xmalloc (buffer_len);
318 memcpy (current_inputline, line, len);
319 current_inputline[len] = ';';
320 current_inputline[len + 1] = '\0';
322 state = parse (current_inputline);
323 if (state == NO_INSN_GENERATED)
324 return;
326 for (insn_size = 0, tmp_insn = insn; tmp_insn; tmp_insn = tmp_insn->next)
327 if (!tmp_insn->reloc || !tmp_insn->exp->symbol)
328 insn_size += 2;
330 if (insn_size)
331 toP = frag_more (insn_size);
333 last_insn_size = insn_size;
335 #ifdef DEBUG
336 printf ("INS:");
337 #endif
338 while (insn)
340 if (insn->reloc && insn->exp->symbol)
342 char *prev_toP = toP - 2;
343 switch (insn->reloc)
345 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
346 case BFD_RELOC_24_PCREL:
347 case BFD_RELOC_BFIN_16_LOW:
348 case BFD_RELOC_BFIN_16_HIGH:
349 size = 4;
350 break;
351 default:
352 size = 2;
355 /* Following if condition checks for the arithmetic relocations.
356 If the case then it doesn't required to generate the code.
357 It has been assumed that, their ID will be contiguous. */
358 if ((BFD_ARELOC_BFIN_PUSH <= insn->reloc
359 && BFD_ARELOC_BFIN_COMP >= insn->reloc)
360 || insn->reloc == BFD_RELOC_BFIN_16_IMM)
362 size = 2;
364 if (insn->reloc == BFD_ARELOC_BFIN_CONST
365 || insn->reloc == BFD_ARELOC_BFIN_PUSH)
366 size = 4;
368 fix_new (frag_now,
369 (prev_toP - frag_now->fr_literal),
370 size, insn->exp->symbol, insn->exp->value,
371 insn->pcrel, insn->reloc);
373 else
375 md_number_to_chars (toP, insn->value, 2);
376 toP += 2;
379 #ifdef DEBUG
380 printf (" reloc :");
381 printf (" %02x%02x", ((unsigned char *) &insn->value)[0],
382 ((unsigned char *) &insn->value)[1]);
383 printf ("\n");
384 #endif
385 insn = insn->next;
387 #ifdef OBJ_ELF
388 dwarf2_emit_insn (insn_size);
389 #endif
392 /* Parse one line of instructions, and generate opcode for it.
393 To parse the line, YACC and LEX are used, because the instruction set
394 syntax doesn't confirm to the AT&T assembly syntax.
395 To call a YACC & LEX generated parser, we must provide the input via
396 a FILE stream, otherwise stdin is used by default. Below the input
397 to the function will be put into a temporary file, then the generated
398 parser uses the temporary file for parsing. */
400 static parse_state
401 parse (char *line)
403 parse_state state;
404 YY_BUFFER_STATE buffstate;
406 buffstate = yy_scan_string (line);
408 /* our lex requires setting the start state to keyword
409 every line as the first word may be a keyword.
410 Fixes a bug where we could not have keywords as labels. */
411 set_start_state ();
413 /* Call yyparse here. */
414 state = yyparse ();
415 if (state == SEMANTIC_ERROR)
417 as_bad ("Parse failed.");
418 insn = 0;
421 yy_delete_buffer (buffstate);
422 return state;
425 /* We need to handle various expressions properly.
426 Such as, [SP--] = 34, concerned by md_assemble(). */
428 void
429 md_operand (expressionS * expressionP)
431 if (*input_line_pointer == '[')
433 as_tsktsk ("We found a '['!");
434 input_line_pointer++;
435 expression (expressionP);
439 /* Handle undefined symbols. */
440 symbolS *
441 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
443 return (symbolS *) 0;
447 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
448 segT segment ATTRIBUTE_UNUSED)
450 return 0;
453 /* Convert from target byte order to host byte order. */
455 static int
456 md_chars_to_number (char *val, int n)
458 int retval;
460 for (retval = 0; n--;)
462 retval <<= 8;
463 retval |= val[n];
465 return retval;
468 void
469 md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
471 char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
473 long value = *valueP;
474 long newval;
476 switch (fixP->fx_r_type)
478 case BFD_RELOC_BFIN_GOT:
479 fixP->fx_no_overflow = 1;
480 newval = md_chars_to_number (where, 2);
481 newval |= 0x0 & 0x7f;
482 md_number_to_chars (where, newval, 2);
483 break;
485 case BFD_RELOC_BFIN_10_PCREL:
486 if (!value)
487 break;
488 if (value < -1024 || value > 1022)
489 as_bad_where (fixP->fx_file, fixP->fx_line,
490 "pcrel too far BFD_RELOC_BFIN_10");
492 /* 11 bit offset even numbered, so we remove right bit. */
493 value = value >> 1;
494 newval = md_chars_to_number (where, 2);
495 newval |= value & 0x03ff;
496 md_number_to_chars (where, newval, 2);
497 break;
499 case BFD_RELOC_BFIN_12_PCREL_JUMP:
500 case BFD_RELOC_BFIN_12_PCREL_JUMP_S:
501 case BFD_RELOC_12_PCREL:
502 if (!value)
503 break;
505 if (value < -4096 || value > 4094)
506 as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far BFD_RELOC_BFIN_12");
507 /* 13 bit offset even numbered, so we remove right bit. */
508 value = value >> 1;
509 newval = md_chars_to_number (where, 2);
510 newval |= value & 0xfff;
511 md_number_to_chars (where, newval, 2);
512 break;
514 case BFD_RELOC_BFIN_16_LOW:
515 case BFD_RELOC_BFIN_16_HIGH:
516 fixP->fx_done = FALSE;
517 break;
519 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
520 case BFD_RELOC_BFIN_24_PCREL_CALL_X:
521 case BFD_RELOC_24_PCREL:
522 if (!value)
523 break;
525 if (value < -16777216 || value > 16777214)
526 as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far BFD_RELOC_BFIN_24");
528 /* 25 bit offset even numbered, so we remove right bit. */
529 value = value >> 1;
530 value++;
532 md_number_to_chars (where - 2, value >> 16, 1);
533 md_number_to_chars (where, value, 1);
534 md_number_to_chars (where + 1, value >> 8, 1);
535 break;
537 case BFD_RELOC_BFIN_5_PCREL: /* LSETUP (a, b) : "a" */
538 if (!value)
539 break;
540 if (value < 4 || value > 30)
541 as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far BFD_RELOC_BFIN_5");
542 value = value >> 1;
543 newval = md_chars_to_number (where, 1);
544 newval = (newval & 0xf0) | (value & 0xf);
545 md_number_to_chars (where, newval, 1);
546 break;
548 case BFD_RELOC_BFIN_11_PCREL: /* LSETUP (a, b) : "b" */
549 if (!value)
550 break;
551 value += 2;
552 if (value < 4 || value > 2046)
553 as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far BFD_RELOC_BFIN_11_PCREL");
554 /* 11 bit unsigned even, so we remove right bit. */
555 value = value >> 1;
556 newval = md_chars_to_number (where, 2);
557 newval |= value & 0x03ff;
558 md_number_to_chars (where, newval, 2);
559 break;
561 case BFD_RELOC_8:
562 if (value < -0x80 || value >= 0x7f)
563 as_bad_where (fixP->fx_file, fixP->fx_line, "rel too far BFD_RELOC_8");
564 md_number_to_chars (where, value, 1);
565 break;
567 case BFD_RELOC_BFIN_16_IMM:
568 case BFD_RELOC_16:
569 if (value < -0x8000 || value >= 0x7fff)
570 as_bad_where (fixP->fx_file, fixP->fx_line, "rel too far BFD_RELOC_8");
571 md_number_to_chars (where, value, 2);
572 break;
574 case BFD_RELOC_32:
575 md_number_to_chars (where, value, 4);
576 break;
578 case BFD_RELOC_BFIN_PLTPC:
579 md_number_to_chars (where, value, 2);
580 break;
582 case BFD_RELOC_VTABLE_INHERIT:
583 case BFD_RELOC_VTABLE_ENTRY:
584 fixP->fx_done = FALSE;
585 break;
587 default:
588 if ((BFD_ARELOC_BFIN_PUSH > fixP->fx_r_type) || (BFD_ARELOC_BFIN_COMP < fixP->fx_r_type))
590 fprintf (stderr, "Relocation %d not handled in gas." " Contact support.\n", fixP->fx_r_type);
591 return;
595 if (!fixP->fx_addsy)
596 fixP->fx_done = TRUE;
600 /* Round up a section size to the appropriate boundary. */
601 valueT
602 md_section_align (segment, size)
603 segT segment;
604 valueT size;
606 int boundary = bfd_get_section_alignment (stdoutput, segment);
607 return ((size + (1 << boundary) - 1) & (-1 << boundary));
611 /* Turn a string in input_line_pointer into a floating point
612 constant of type type, and store the appropriate bytes in
613 *litP. The number of LITTLENUMS emitted is stored in *sizeP.
614 An error message is returned, or NULL on OK. */
616 /* Equal to MAX_PRECISION in atof-ieee.c. */
617 #define MAX_LITTLENUMS 6
619 char *
620 md_atof (type, litP, sizeP)
621 char type;
622 char * litP;
623 int * sizeP;
625 int prec;
626 LITTLENUM_TYPE words [MAX_LITTLENUMS];
627 LITTLENUM_TYPE *wordP;
628 char * t;
630 switch (type)
632 case 'f':
633 case 'F':
634 prec = 2;
635 break;
637 case 'd':
638 case 'D':
639 prec = 4;
640 break;
642 /* FIXME: Some targets allow other format chars for bigger sizes here. */
644 default:
645 *sizeP = 0;
646 return _("Bad call to md_atof()");
649 t = atof_ieee (input_line_pointer, type, words);
650 if (t)
651 input_line_pointer = t;
652 *sizeP = prec * sizeof (LITTLENUM_TYPE);
654 *sizeP = prec * sizeof (LITTLENUM_TYPE);
655 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
656 the littleendianness of the processor. */
657 for (wordP = words + prec - 1; prec--;)
659 md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
660 litP += sizeof (LITTLENUM_TYPE);
663 return 0;
667 /* If while processing a fixup, a reloc really needs to be created
668 then it is done here. */
670 arelent *
671 tc_gen_reloc (seg, fixp)
672 asection *seg ATTRIBUTE_UNUSED;
673 fixS *fixp;
675 arelent *reloc;
677 reloc = (arelent *) xmalloc (sizeof (arelent));
678 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
679 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
680 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
682 reloc->addend = fixp->fx_offset;
683 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
685 if (reloc->howto == (reloc_howto_type *) NULL)
687 as_bad_where (fixp->fx_file, fixp->fx_line,
688 /* xgettext:c-format. */
689 _("reloc %d not supported by object file format"),
690 (int) fixp->fx_r_type);
692 xfree (reloc);
694 return NULL;
697 return reloc;
700 /* The location from which a PC relative jump should be calculated,
701 given a PC relative reloc. */
703 long
704 md_pcrel_from_section (fixP, sec)
705 fixS *fixP;
706 segT sec;
708 if (fixP->fx_addsy != (symbolS *) NULL
709 && (!S_IS_DEFINED (fixP->fx_addsy)
710 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
712 /* The symbol is undefined (or is defined but not in this section).
713 Let the linker figure it out. */
714 return 0;
716 return fixP->fx_frag->fr_address + fixP->fx_where;
719 /* Return true if the fix can be handled by GAS, false if it must
720 be passed through to the linker. */
722 bfd_boolean
723 bfin_fix_adjustable (fixS *fixP)
725 switch (fixP->fx_r_type)
727 /* Adjust_reloc_syms doesn't know about the GOT. */
728 case BFD_RELOC_BFIN_GOT :
729 case BFD_RELOC_BFIN_PLTPC :
730 /* We need the symbol name for the VTABLE entries. */
731 case BFD_RELOC_VTABLE_INHERIT:
732 case BFD_RELOC_VTABLE_ENTRY:
733 return 0;
735 default:
736 return 1;
741 /* Handle the LOOP_BEGIN and LOOP_END statements.
742 Parse the Loop_Begin/Loop_End and create a label. */
743 void
744 bfin_start_line_hook ()
746 bfd_boolean maybe_begin = FALSE;
747 bfd_boolean maybe_end = FALSE;
749 char *c1, *label_name;
750 symbolS *line_label;
751 char *c = input_line_pointer;
753 while (ISSPACE (*c))
754 c++;
756 /* Look for Loop_Begin or Loop_End statements. */
758 if (*c != 'L' && *c != 'l')
759 return;
761 c++;
762 if (*c != 'O' && *c != 'o')
763 return;
765 c++;
766 if (*c != 'O' && *c != 'o')
767 return;
769 c++;
770 if (*c != 'P' && *c != 'p')
771 return;
773 c++;
774 if (*c != '_')
775 return;
777 c++;
778 if (*c == 'E' || *c == 'e')
779 maybe_end = TRUE;
780 else if (*c == 'B' || *c == 'b')
781 maybe_begin = TRUE;
782 else
783 return;
785 if (maybe_end)
787 c++;
788 if (*c != 'N' && *c != 'n')
789 return;
791 c++;
792 if (*c != 'D' && *c != 'd')
793 return;
796 if (maybe_begin)
798 c++;
799 if (*c != 'E' && *c != 'e')
800 return;
802 c++;
803 if (*c != 'G' && *c != 'g')
804 return;
806 c++;
807 if (*c != 'I' && *c != 'i')
808 return;
810 c++;
811 if (*c != 'N' && *c != 'n')
812 return;
815 c++;
816 while (ISSPACE (*c)) c++;
817 c1 = c;
818 while (ISALPHA (*c) || ISDIGIT (*c) || *c == '_') c++;
820 input_line_pointer = c;
821 if (maybe_end)
823 label_name = (char *) xmalloc ((c - c1) + strlen ("__END") + 1);
824 label_name[0] = 0;
825 strncat (label_name, c1, c-c1);
826 strcat (label_name, "__END");
828 else /* maybe_begin. */
830 label_name = (char *) xmalloc ((c - c1) + strlen ("__BEGIN") + 1);
831 label_name[0] = 0;
832 strncat (label_name, c1, c-c1);
833 strcat (label_name, "__BEGIN");
836 line_label = colon (label_name);
838 /* Loop_End follows the last instruction in the loop.
839 Adjust label address. */
840 if (maybe_end)
841 line_label->sy_value.X_add_number -= last_insn_size;
845 /* Special extra functions that help bfin-parse.y perform its job. */
847 #include <stdio.h>
848 #include <assert.h>
849 #include <obstack.h>
850 #include <bfd.h>
851 #include "bfin-defs.h"
853 struct obstack mempool;
855 INSTR_T
856 conscode (INSTR_T head, INSTR_T tail)
858 if (!head)
859 return tail;
860 head->next = tail;
861 return head;
864 INSTR_T
865 conctcode (INSTR_T head, INSTR_T tail)
867 INSTR_T temp = (head);
868 if (!head)
869 return tail;
870 while (temp->next)
871 temp = temp->next;
872 temp->next = tail;
874 return head;
877 INSTR_T
878 note_reloc (INSTR_T code, Expr_Node * symbol, int reloc, int pcrel)
880 /* Assert that the symbol is not an operator. */
881 assert (symbol->type == Expr_Node_Reloc);
883 return note_reloc1 (code, symbol->value.s_value, reloc, pcrel);
887 INSTR_T
888 note_reloc1 (INSTR_T code, const char *symbol, int reloc, int pcrel)
890 code->reloc = reloc;
891 code->exp = mkexpr (0, symbol_find_or_make (symbol));
892 code->pcrel = pcrel;
893 return code;
896 INSTR_T
897 note_reloc2 (INSTR_T code, const char *symbol, int reloc, int value, int pcrel)
899 code->reloc = reloc;
900 code->exp = mkexpr (value, symbol_find_or_make (symbol));
901 code->pcrel = pcrel;
902 return code;
905 INSTR_T
906 gencode (unsigned long x)
908 INSTR_T cell = (INSTR_T) obstack_alloc (&mempool, sizeof (struct bfin_insn));
909 memset (cell, 0, sizeof (struct bfin_insn));
910 cell->value = (x);
911 return cell;
914 int reloc;
915 int ninsns;
916 int count_insns;
918 static void *
919 allocate (int n)
921 return (void *) obstack_alloc (&mempool, n);
924 Expr_Node *
925 Expr_Node_Create (Expr_Node_Type type,
926 Expr_Node_Value value,
927 Expr_Node *Left_Child,
928 Expr_Node *Right_Child)
932 Expr_Node *node = (Expr_Node *) allocate (sizeof (Expr_Node));
933 node->type = type;
934 node->value = value;
935 node->Left_Child = Left_Child;
936 node->Right_Child = Right_Child;
937 return node;
940 static const char *con = ".__constant";
941 static const char *op = ".__operator";
942 static INSTR_T Expr_Node_Gen_Reloc_R (Expr_Node * head);
943 INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc);
945 INSTR_T
946 Expr_Node_Gen_Reloc (Expr_Node * head, int parent_reloc)
948 /* Top level reloction expression generator VDSP style.
949 If the relocation is just by itself, generate one item
950 else generate this convoluted expression. */
952 INSTR_T note = NULL_CODE;
953 INSTR_T note1 = NULL_CODE;
954 int pcrel = 1; /* Is the parent reloc pcrelative?
955 This calculation here and HOWTO should match. */
957 if (parent_reloc)
959 /* If it's 32 bit quantity then 16bit code needs to be added. */
960 int value = 0;
962 if (head->type == Expr_Node_Constant)
964 /* If note1 is not null code, we have to generate a right
965 aligned value for the constant. Otherwise the reloc is
966 a part of the basic command and the yacc file
967 generates this. */
968 value = head->value.i_value;
970 switch (parent_reloc)
972 /* Some reloctions will need to allocate extra words. */
973 case BFD_RELOC_BFIN_16_IMM:
974 case BFD_RELOC_BFIN_16_LOW:
975 case BFD_RELOC_BFIN_16_HIGH:
976 note1 = conscode (gencode (value), NULL_CODE);
977 pcrel = 0;
978 break;
979 case BFD_RELOC_BFIN_PLTPC:
980 note1 = conscode (gencode (value), NULL_CODE);
981 pcrel = 0;
982 break;
983 case BFD_RELOC_16:
984 case BFD_RELOC_BFIN_GOT:
985 note1 = conscode (gencode (value), NULL_CODE);
986 pcrel = 0;
987 break;
988 case BFD_RELOC_24_PCREL:
989 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
990 case BFD_RELOC_BFIN_24_PCREL_CALL_X:
991 /* These offsets are even numbered pcrel. */
992 note1 = conscode (gencode (value >> 1), NULL_CODE);
993 break;
994 default:
995 note1 = NULL_CODE;
998 if (head->type == Expr_Node_Constant)
999 note = note1;
1000 else if (head->type == Expr_Node_Reloc)
1002 note = note_reloc1 (gencode (0), head->value.s_value, parent_reloc, pcrel);
1003 if (note1 != NULL_CODE)
1004 note = conscode (note1, note);
1006 else if (head->type == Expr_Node_Binop
1007 && (head->value.op_value == Expr_Op_Type_Add
1008 || head->value.op_value == Expr_Op_Type_Sub)
1009 && head->Left_Child->type == Expr_Node_Reloc
1010 && head->Right_Child->type == Expr_Node_Constant)
1012 int val = head->Right_Child->value.i_value;
1013 if (head->value.op_value == Expr_Op_Type_Sub)
1014 val = -val;
1015 note = conscode (note_reloc2 (gencode (0), head->Left_Child->value.s_value,
1016 parent_reloc, val, 0),
1017 NULL_CODE);
1018 if (note1 != NULL_CODE)
1019 note = conscode (note1, note);
1021 else
1023 /* Call the recursive function. */
1024 note = note_reloc1 (gencode (0), op, parent_reloc, pcrel);
1025 if (note1 != NULL_CODE)
1026 note = conscode (note1, note);
1027 note = conctcode (Expr_Node_Gen_Reloc_R (head), note);
1029 return note;
1032 static INSTR_T
1033 Expr_Node_Gen_Reloc_R (Expr_Node * head)
1036 INSTR_T note = 0;
1037 INSTR_T note1 = 0;
1039 switch (head->type)
1041 case Expr_Node_Constant:
1042 note = conscode (note_reloc2 (gencode (0), con, BFD_ARELOC_BFIN_CONST, head->value.i_value, 0), NULL_CODE);
1043 break;
1044 case Expr_Node_Reloc:
1045 note = conscode (note_reloc (gencode (0), head, BFD_ARELOC_BFIN_PUSH, 0), NULL_CODE);
1046 break;
1047 case Expr_Node_Binop:
1048 note1 = conctcode (Expr_Node_Gen_Reloc_R (head->Left_Child), Expr_Node_Gen_Reloc_R (head->Right_Child));
1049 switch (head->value.op_value)
1051 case Expr_Op_Type_Add:
1052 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_ADD, 0), NULL_CODE));
1053 break;
1054 case Expr_Op_Type_Sub:
1055 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_SUB, 0), NULL_CODE));
1056 break;
1057 case Expr_Op_Type_Mult:
1058 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MULT, 0), NULL_CODE));
1059 break;
1060 case Expr_Op_Type_Div:
1061 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_DIV, 0), NULL_CODE));
1062 break;
1063 case Expr_Op_Type_Mod:
1064 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MOD, 0), NULL_CODE));
1065 break;
1066 case Expr_Op_Type_Lshift:
1067 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LSHIFT, 0), NULL_CODE));
1068 break;
1069 case Expr_Op_Type_Rshift:
1070 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_RSHIFT, 0), NULL_CODE));
1071 break;
1072 case Expr_Op_Type_BAND:
1073 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_AND, 0), NULL_CODE));
1074 break;
1075 case Expr_Op_Type_BOR:
1076 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_OR, 0), NULL_CODE));
1077 break;
1078 case Expr_Op_Type_BXOR:
1079 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_XOR, 0), NULL_CODE));
1080 break;
1081 case Expr_Op_Type_LAND:
1082 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LAND, 0), NULL_CODE));
1083 break;
1084 case Expr_Op_Type_LOR:
1085 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LOR, 0), NULL_CODE));
1086 break;
1087 default:
1088 fprintf (stderr, "%s:%d:Unkonwn operator found for arithmetic" " relocation", __FILE__, __LINE__);
1092 break;
1093 case Expr_Node_Unop:
1094 note1 = conscode (Expr_Node_Gen_Reloc_R (head->Left_Child), NULL_CODE);
1095 switch (head->value.op_value)
1097 case Expr_Op_Type_NEG:
1098 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_NEG, 0), NULL_CODE));
1099 break;
1100 case Expr_Op_Type_COMP:
1101 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_COMP, 0), NULL_CODE));
1102 break;
1103 default:
1104 fprintf (stderr, "%s:%d:Unkonwn operator found for arithmetic" " relocation", __FILE__, __LINE__);
1106 break;
1107 default:
1108 fprintf (stderr, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__, __LINE__);
1110 return note;
1114 /* Blackfin opcode generation. */
1116 /* These functions are called by the generated parser
1117 (from bfin-parse.y), the register type classification
1118 happens in bfin-lex.l. */
1120 #include "bfin-aux.h"
1121 #include "opcode/bfin.h"
1123 #define INIT(t) t c_code = init_##t
1124 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1125 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1127 #define HI(x) ((x >> 16) & 0xffff)
1128 #define LO(x) ((x ) & 0xffff)
1130 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1132 #define GEN_OPCODE32() \
1133 conscode (gencode (HI (c_code.opcode)), \
1134 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1136 #define GEN_OPCODE16() \
1137 conscode (gencode (c_code.opcode), NULL_CODE)
1140 /* 32 BIT INSTRUCTIONS. */
1143 /* DSP32 instruction generation. */
1145 INSTR_T
1146 bfin_gen_dsp32mac (int op1, int MM, int mmod, int w1, int P,
1147 int h01, int h11, int h00, int h10, int op0,
1148 REG_T dst, REG_T src0, REG_T src1, int w0)
1150 INIT (DSP32Mac);
1152 ASSIGN (op0);
1153 ASSIGN (op1);
1154 ASSIGN (MM);
1155 ASSIGN (mmod);
1156 ASSIGN (w0);
1157 ASSIGN (w1);
1158 ASSIGN (h01);
1159 ASSIGN (h11);
1160 ASSIGN (h00);
1161 ASSIGN (h10);
1162 ASSIGN (P);
1164 /* If we have full reg assignments, mask out LSB to encode
1165 single or simultaneous even/odd register moves. */
1166 if (P)
1168 dst->regno &= 0x06;
1171 ASSIGN_R (dst);
1172 ASSIGN_R (src0);
1173 ASSIGN_R (src1);
1175 return GEN_OPCODE32 ();
1178 INSTR_T
1179 bfin_gen_dsp32mult (int op1, int MM, int mmod, int w1, int P,
1180 int h01, int h11, int h00, int h10, int op0,
1181 REG_T dst, REG_T src0, REG_T src1, int w0)
1183 INIT (DSP32Mult);
1185 ASSIGN (op0);
1186 ASSIGN (op1);
1187 ASSIGN (MM);
1188 ASSIGN (mmod);
1189 ASSIGN (w0);
1190 ASSIGN (w1);
1191 ASSIGN (h01);
1192 ASSIGN (h11);
1193 ASSIGN (h00);
1194 ASSIGN (h10);
1195 ASSIGN (P);
1197 if (P)
1199 dst->regno &= 0x06;
1202 ASSIGN_R (dst);
1203 ASSIGN_R (src0);
1204 ASSIGN_R (src1);
1206 return GEN_OPCODE32 ();
1209 INSTR_T
1210 bfin_gen_dsp32alu (int HL, int aopcde, int aop, int s, int x,
1211 REG_T dst0, REG_T dst1, REG_T src0, REG_T src1)
1213 INIT (DSP32Alu);
1215 ASSIGN (HL);
1216 ASSIGN (aopcde);
1217 ASSIGN (aop);
1218 ASSIGN (s);
1219 ASSIGN (x);
1220 ASSIGN_R (dst0);
1221 ASSIGN_R (dst1);
1222 ASSIGN_R (src0);
1223 ASSIGN_R (src1);
1225 return GEN_OPCODE32 ();
1228 INSTR_T
1229 bfin_gen_dsp32shift (int sopcde, REG_T dst0, REG_T src0,
1230 REG_T src1, int sop, int HLs)
1232 INIT (DSP32Shift);
1234 ASSIGN (sopcde);
1235 ASSIGN (sop);
1236 ASSIGN (HLs);
1238 ASSIGN_R (dst0);
1239 ASSIGN_R (src0);
1240 ASSIGN_R (src1);
1242 return GEN_OPCODE32 ();
1245 INSTR_T
1246 bfin_gen_dsp32shiftimm (int sopcde, REG_T dst0, int immag,
1247 REG_T src1, int sop, int HLs)
1249 INIT (DSP32ShiftImm);
1251 ASSIGN (sopcde);
1252 ASSIGN (sop);
1253 ASSIGN (HLs);
1255 ASSIGN_R (dst0);
1256 ASSIGN (immag);
1257 ASSIGN_R (src1);
1259 return GEN_OPCODE32 ();
1262 /* LOOP SETUP. */
1264 INSTR_T
1265 bfin_gen_loopsetup (Expr_Node * psoffset, REG_T c, int rop,
1266 Expr_Node * peoffset, REG_T reg)
1268 int soffset, eoffset;
1269 INIT (LoopSetup);
1271 soffset = (EXPR_VALUE (psoffset) >> 1);
1272 ASSIGN (soffset);
1273 eoffset = (EXPR_VALUE (peoffset) >> 1);
1274 ASSIGN (eoffset);
1275 ASSIGN (rop);
1276 ASSIGN_R (c);
1277 ASSIGN_R (reg);
1279 return
1280 conscode (gencode (HI (c_code.opcode)),
1281 conctcode (Expr_Node_Gen_Reloc (psoffset, BFD_RELOC_BFIN_5_PCREL),
1282 conctcode (gencode (LO (c_code.opcode)), Expr_Node_Gen_Reloc (peoffset, BFD_RELOC_BFIN_11_PCREL))));
1286 /* Call, Link. */
1288 INSTR_T
1289 bfin_gen_calla (Expr_Node * addr, int S)
1291 int val;
1292 int high_val;
1293 int reloc = 0;
1294 INIT (CALLa);
1296 switch(S){
1297 case 0 : reloc = BFD_RELOC_BFIN_24_PCREL_JUMP_L; break;
1298 case 1 : reloc = BFD_RELOC_24_PCREL; break;
1299 case 2 : reloc = BFD_RELOC_BFIN_PLTPC; break;
1300 default : break;
1303 ASSIGN (S);
1305 val = EXPR_VALUE (addr) >> 1;
1306 high_val = val >> 16;
1308 return conscode (gencode (HI (c_code.opcode) | (high_val & 0xff)),
1309 Expr_Node_Gen_Reloc (addr, reloc));
1312 INSTR_T
1313 bfin_gen_linkage (int R, int framesize)
1315 INIT (Linkage);
1317 ASSIGN (R);
1318 ASSIGN (framesize);
1320 return GEN_OPCODE32 ();
1324 /* Load and Store. */
1326 INSTR_T
1327 bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int reloc)
1329 int grp, hword;
1330 unsigned val = EXPR_VALUE (phword);
1331 INIT (LDIMMhalf);
1333 ASSIGN (H);
1334 ASSIGN (S);
1335 ASSIGN (Z);
1337 ASSIGN_R (reg);
1338 grp = (GROUP (reg));
1339 ASSIGN (grp);
1340 if (reloc == 2)
1342 return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, BFD_RELOC_BFIN_16_IMM));
1344 else if (reloc == 1)
1346 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));
1348 else
1350 hword = val;
1351 ASSIGN (hword);
1353 return GEN_OPCODE32 ();
1356 INSTR_T
1357 bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset)
1359 int offset;
1360 int value = 0;
1361 INIT (LDSTidxI);
1363 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1365 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1366 return 0;
1369 ASSIGN_R (ptr);
1370 ASSIGN_R (reg);
1371 ASSIGN (W);
1372 ASSIGN (sz);
1373 switch (sz)
1375 case 0:
1376 value = EXPR_VALUE (poffset) >> 2;
1377 break;
1378 case 1:
1379 value = EXPR_VALUE (poffset) >> 1;
1380 break;
1381 case 2:
1382 value = EXPR_VALUE (poffset);
1383 break;
1387 ASSIGN (Z);
1389 offset = (value & 0xffff);
1390 ASSIGN (offset);
1391 /* TODO : test if you need to check this here.
1392 The reloc case should automatically generate instruction
1393 if constant. */
1394 if(poffset->type != Expr_Node_Constant){
1395 /* A GOT relocation such as R0 = [P5 + symbol@GOT].
1396 Distinguish between R0 = [P5 + symbol@GOT] and
1397 P5 = [P5 + _current_shared_library_p5_offset_]. */
1398 if(!strcmp(poffset->value.s_value, "_current_shared_library_p5_offset_")){
1399 return conscode (gencode (HI (c_code.opcode)),
1400 Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16));
1402 else
1404 return conscode (gencode (HI (c_code.opcode)),
1405 Expr_Node_Gen_Reloc(poffset, BFD_RELOC_BFIN_GOT));
1408 else{
1409 return GEN_OPCODE32 ();
1414 INSTR_T
1415 bfin_gen_ldst (REG_T ptr, REG_T reg, int aop, int sz, int Z, int W)
1417 INIT (LDST);
1419 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1421 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1422 return 0;
1425 ASSIGN_R (ptr);
1426 ASSIGN_R (reg);
1427 ASSIGN (aop);
1428 ASSIGN (sz);
1429 ASSIGN (Z);
1430 ASSIGN (W);
1432 return GEN_OPCODE16 ();
1435 INSTR_T
1436 bfin_gen_ldstii (REG_T ptr, REG_T reg, Expr_Node * poffset, int W, int op)
1438 int offset;
1439 int value = 0;
1440 INIT (LDSTii);
1443 if (!IS_PREG (*ptr))
1445 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1446 return 0;
1449 switch (op)
1451 case 1:
1452 case 2:
1453 value = EXPR_VALUE (poffset) >> 1;
1454 break;
1455 case 0:
1456 case 3:
1457 value = EXPR_VALUE (poffset) >> 2;
1458 break;
1461 ASSIGN_R (ptr);
1462 ASSIGN_R (reg);
1464 offset = value;
1465 ASSIGN (offset);
1466 ASSIGN (W);
1467 ASSIGN (op);
1469 return GEN_OPCODE16 ();
1472 INSTR_T
1473 bfin_gen_ldstiifp (REG_T sreg, Expr_Node * poffset, int W)
1475 /* Set bit 4 if it's a Preg. */
1476 int reg = (sreg->regno & CODE_MASK) | (IS_PREG (*sreg) ? 0x8 : 0x0);
1477 int offset = ((~(EXPR_VALUE (poffset) >> 2)) & 0x1f) + 1;
1478 INIT (LDSTiiFP);
1479 ASSIGN (reg);
1480 ASSIGN (offset);
1481 ASSIGN (W);
1483 return GEN_OPCODE16 ();
1486 INSTR_T
1487 bfin_gen_ldstpmod (REG_T ptr, REG_T reg, int aop, int W, REG_T idx)
1489 INIT (LDSTpmod);
1491 ASSIGN_R (ptr);
1492 ASSIGN_R (reg);
1493 ASSIGN (aop);
1494 ASSIGN (W);
1495 ASSIGN_R (idx);
1497 return GEN_OPCODE16 ();
1500 INSTR_T
1501 bfin_gen_dspldst (REG_T i, REG_T reg, int aop, int W, int m)
1503 INIT (DspLDST);
1505 ASSIGN_R (i);
1506 ASSIGN_R (reg);
1507 ASSIGN (aop);
1508 ASSIGN (W);
1509 ASSIGN (m);
1511 return GEN_OPCODE16 ();
1514 INSTR_T
1515 bfin_gen_logi2op (int opc, int src, int dst)
1517 INIT (LOGI2op);
1519 ASSIGN (opc);
1520 ASSIGN (src);
1521 ASSIGN (dst);
1523 return GEN_OPCODE16 ();
1526 INSTR_T
1527 bfin_gen_brcc (int T, int B, Expr_Node * poffset)
1529 int offset;
1530 INIT (BRCC);
1532 ASSIGN (T);
1533 ASSIGN (B);
1534 offset = ((EXPR_VALUE (poffset) >> 1));
1535 ASSIGN (offset);
1536 return conscode (gencode (c_code.opcode), Expr_Node_Gen_Reloc (poffset, BFD_RELOC_BFIN_10_PCREL));
1539 INSTR_T
1540 bfin_gen_ujump (Expr_Node * poffset)
1542 int offset;
1543 INIT (UJump);
1545 offset = ((EXPR_VALUE (poffset) >> 1));
1546 ASSIGN (offset);
1548 return conscode (gencode (c_code.opcode),
1549 Expr_Node_Gen_Reloc (
1550 poffset, BFD_RELOC_BFIN_12_PCREL_JUMP_S));
1553 INSTR_T
1554 bfin_gen_alu2op (REG_T dst, REG_T src, int opc)
1556 INIT (ALU2op);
1558 ASSIGN_R (dst);
1559 ASSIGN_R (src);
1560 ASSIGN (opc);
1562 return GEN_OPCODE16 ();
1565 INSTR_T
1566 bfin_gen_compi2opd (REG_T dst, int src, int op)
1568 INIT (COMPI2opD);
1570 ASSIGN_R (dst);
1571 ASSIGN (src);
1572 ASSIGN (op);
1574 return GEN_OPCODE16 ();
1577 INSTR_T
1578 bfin_gen_compi2opp (REG_T dst, int src, int op)
1580 INIT (COMPI2opP);
1582 ASSIGN_R (dst);
1583 ASSIGN (src);
1584 ASSIGN (op);
1586 return GEN_OPCODE16 ();
1589 INSTR_T
1590 bfin_gen_dagmodik (REG_T i, int op)
1592 INIT (DagMODik);
1594 ASSIGN_R (i);
1595 ASSIGN (op);
1597 return GEN_OPCODE16 ();
1600 INSTR_T
1601 bfin_gen_dagmodim (REG_T i, REG_T m, int op, int br)
1603 INIT (DagMODim);
1605 ASSIGN_R (i);
1606 ASSIGN_R (m);
1607 ASSIGN (op);
1608 ASSIGN (br);
1610 return GEN_OPCODE16 ();
1613 INSTR_T
1614 bfin_gen_ptr2op (REG_T dst, REG_T src, int opc)
1616 INIT (PTR2op);
1618 ASSIGN_R (dst);
1619 ASSIGN_R (src);
1620 ASSIGN (opc);
1622 return GEN_OPCODE16 ();
1625 INSTR_T
1626 bfin_gen_comp3op (REG_T src0, REG_T src1, REG_T dst, int opc)
1628 INIT (COMP3op);
1630 ASSIGN_R (src0);
1631 ASSIGN_R (src1);
1632 ASSIGN_R (dst);
1633 ASSIGN (opc);
1635 return GEN_OPCODE16 ();
1638 INSTR_T
1639 bfin_gen_ccflag (REG_T x, int y, int opc, int I, int G)
1641 INIT (CCflag);
1643 ASSIGN_R (x);
1644 ASSIGN (y);
1645 ASSIGN (opc);
1646 ASSIGN (I);
1647 ASSIGN (G);
1649 return GEN_OPCODE16 ();
1652 INSTR_T
1653 bfin_gen_ccmv (REG_T src, REG_T dst, int T)
1655 int s, d;
1656 INIT (CCmv);
1658 ASSIGN_R (src);
1659 ASSIGN_R (dst);
1660 s = (GROUP (src));
1661 ASSIGN (s);
1662 d = (GROUP (dst));
1663 ASSIGN (d);
1664 ASSIGN (T);
1666 return GEN_OPCODE16 ();
1669 INSTR_T
1670 bfin_gen_cc2stat (int cbit, int op, int D)
1672 INIT (CC2stat);
1674 ASSIGN (cbit);
1675 ASSIGN (op);
1676 ASSIGN (D);
1678 return GEN_OPCODE16 ();
1681 INSTR_T
1682 bfin_gen_regmv (REG_T src, REG_T dst)
1684 int gs, gd;
1685 INIT (RegMv);
1687 ASSIGN_R (src);
1688 ASSIGN_R (dst);
1690 gs = (GROUP (src));
1691 ASSIGN (gs);
1692 gd = (GROUP (dst));
1693 ASSIGN (gd);
1695 return GEN_OPCODE16 ();
1698 INSTR_T
1699 bfin_gen_cc2dreg (int op, REG_T reg)
1701 INIT (CC2dreg);
1703 ASSIGN (op);
1704 ASSIGN_R (reg);
1706 return GEN_OPCODE16 ();
1709 INSTR_T
1710 bfin_gen_progctrl (int prgfunc, int poprnd)
1712 INIT (ProgCtrl);
1714 ASSIGN (prgfunc);
1715 ASSIGN (poprnd);
1717 return GEN_OPCODE16 ();
1720 INSTR_T
1721 bfin_gen_cactrl (REG_T reg, int a, int op)
1723 INIT (CaCTRL);
1725 ASSIGN_R (reg);
1726 ASSIGN (a);
1727 ASSIGN (op);
1729 return GEN_OPCODE16 ();
1732 INSTR_T
1733 bfin_gen_pushpopmultiple (int dr, int pr, int d, int p, int W)
1735 INIT (PushPopMultiple);
1737 ASSIGN (dr);
1738 ASSIGN (pr);
1739 ASSIGN (d);
1740 ASSIGN (p);
1741 ASSIGN (W);
1743 return GEN_OPCODE16 ();
1746 INSTR_T
1747 bfin_gen_pushpopreg (REG_T reg, int W)
1749 int grp;
1750 INIT (PushPopReg);
1752 ASSIGN_R (reg);
1753 grp = (GROUP (reg));
1754 ASSIGN (grp);
1755 ASSIGN (W);
1757 return GEN_OPCODE16 ();
1760 /* Pseudo Debugging Support. */
1762 INSTR_T
1763 bfin_gen_pseudodbg (int fn, int reg, int grp)
1765 INIT (PseudoDbg);
1767 ASSIGN (fn);
1768 ASSIGN (reg);
1769 ASSIGN (grp);
1771 return GEN_OPCODE16 ();
1774 INSTR_T
1775 bfin_gen_pseudodbg_assert (int dbgop, REG_T regtest, int expected)
1777 INIT (PseudoDbg_Assert);
1779 ASSIGN (dbgop);
1780 ASSIGN_R (regtest);
1781 ASSIGN (expected);
1783 return GEN_OPCODE32 ();
1786 /* Multiple instruction generation. */
1788 INSTR_T
1789 bfin_gen_multi_instr (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2)
1791 INSTR_T walk;
1793 /* If it's a 0, convert into MNOP. */
1794 if (dsp32)
1796 walk = dsp32->next;
1797 SET_MULTI_INSTRUCTION_BIT (dsp32);
1799 else
1801 dsp32 = gencode (0xc803);
1802 walk = gencode (0x1800);
1803 dsp32->next = walk;
1806 if (!dsp16_grp1)
1808 dsp16_grp1 = gencode (0x0000);
1811 if (!dsp16_grp2)
1813 dsp16_grp2 = gencode (0x0000);
1816 walk->next = dsp16_grp1;
1817 dsp16_grp1->next = dsp16_grp2;
1818 dsp16_grp2->next = NULL_CODE;
1820 return dsp32;
1823 INSTR_T
1824 bfin_gen_loop (Expr_Node *expr, REG_T reg, int rop, REG_T preg)
1826 const char *loopsym;
1827 char *lbeginsym, *lendsym;
1828 Expr_Node_Value lbeginval, lendval;
1829 Expr_Node *lbegin, *lend;
1831 loopsym = expr->value.s_value;
1832 lbeginsym = (char *) xmalloc (strlen (loopsym) + strlen ("__BEGIN") + 1);
1833 lendsym = (char *) xmalloc (strlen (loopsym) + strlen ("__END") + 1);
1835 lbeginsym[0] = 0;
1836 lendsym[0] = 0;
1838 strcat (lbeginsym, loopsym);
1839 strcat (lbeginsym, "__BEGIN");
1841 strcat (lendsym, loopsym);
1842 strcat (lendsym, "__END");
1844 lbeginval.s_value = lbeginsym;
1845 lendval.s_value = lendsym;
1847 lbegin = Expr_Node_Create (Expr_Node_Reloc, lbeginval, NULL, NULL);
1848 lend = Expr_Node_Create (Expr_Node_Reloc, lendval, NULL, NULL);
1849 return bfin_gen_loopsetup(lbegin, reg, rop, lend, preg);
1852 bfd_boolean
1853 bfin_eol_in_insn (char *line)
1855 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1857 char *temp = line;
1859 if (*line != '\n')
1860 return FALSE;
1862 /* A semi-colon followed by a newline is always the end of a line. */
1863 if (line[-1] == ';')
1864 return FALSE;
1866 if (line[-1] == '|')
1867 return TRUE;
1869 /* If the || is on the next line, there might be leading whitespace. */
1870 temp++;
1871 while (*temp == ' ' || *temp == '\t') temp++;
1873 if (*temp == '|')
1874 return TRUE;
1876 return FALSE;
1879 bfd_boolean
1880 bfin_name_is_register (char *name)
1882 int i;
1884 if (*name == '[' || *name == '(')
1885 return TRUE;
1887 if ((name[0] == 'W' || name[0] == 'w') && name[1] == '[')
1888 return TRUE;
1890 if ((name[0] == 'B' || name[0] == 'b') && name[1] == '[')
1891 return TRUE;
1893 for (i=0; bfin_reg_info[i].name != 0; i++)
1895 if (!strcasecmp (bfin_reg_info[i].name, name))
1896 return TRUE;
1898 return FALSE;
1901 void
1902 bfin_equals (Expr_Node *sym)
1904 char *c;
1906 c = input_line_pointer;
1907 while (*c != '=')
1908 c--;
1910 input_line_pointer = c;
1912 equals ((char *) sym->value.s_value, 1);
1915 bfd_boolean
1916 bfin_start_label (char *ptr)
1918 ptr--;
1919 while (!ISSPACE (*ptr) && !is_end_of_line[(unsigned char) *ptr])
1920 ptr--;
1922 ptr++;
1923 if (*ptr == '(' || *ptr == '[')
1924 return FALSE;
1926 return TRUE;
1930 bfin_force_relocation (struct fix *fixp)
1932 if (fixp->fx_r_type ==BFD_RELOC_BFIN_16_LOW
1933 || fixp->fx_r_type == BFD_RELOC_BFIN_16_HIGH)
1934 return TRUE;
1936 return generic_force_reloc (fixp);