2008-04-23 Mike Frysinger <vapier@gentoo.org>
[binutils.git] / gas / config / tc-bfin.c
blob3991622d0cd02d3e188a6bf84ecacd9de95e60f1
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 #ifdef OBJ_FDPIC_ELF
54 # define DEFAULT_FDPIC EF_BFIN_FDPIC
55 #else
56 # define DEFAULT_FDPIC 0
57 #endif
59 static flagword bfin_flags = DEFAULT_FLAGS | DEFAULT_FDPIC;
60 static const char *bfin_pic_flag = DEFAULT_FDPIC ? "-mfdpic" : (const char *)0;
62 /* Registers list. */
63 struct bfin_reg_entry
65 const char *name;
66 int number;
69 static const struct bfin_reg_entry bfin_reg_info[] = {
70 {"R0.L", REG_RL0},
71 {"R1.L", REG_RL1},
72 {"R2.L", REG_RL2},
73 {"R3.L", REG_RL3},
74 {"R4.L", REG_RL4},
75 {"R5.L", REG_RL5},
76 {"R6.L", REG_RL6},
77 {"R7.L", REG_RL7},
78 {"R0.H", REG_RH0},
79 {"R1.H", REG_RH1},
80 {"R2.H", REG_RH2},
81 {"R3.H", REG_RH3},
82 {"R4.H", REG_RH4},
83 {"R5.H", REG_RH5},
84 {"R6.H", REG_RH6},
85 {"R7.H", REG_RH7},
86 {"R0", REG_R0},
87 {"R1", REG_R1},
88 {"R2", REG_R2},
89 {"R3", REG_R3},
90 {"R4", REG_R4},
91 {"R5", REG_R5},
92 {"R6", REG_R6},
93 {"R7", REG_R7},
94 {"P0", REG_P0},
95 {"P0.H", REG_P0},
96 {"P0.L", REG_P0},
97 {"P1", REG_P1},
98 {"P1.H", REG_P1},
99 {"P1.L", REG_P1},
100 {"P2", REG_P2},
101 {"P2.H", REG_P2},
102 {"P2.L", REG_P2},
103 {"P3", REG_P3},
104 {"P3.H", REG_P3},
105 {"P3.L", REG_P3},
106 {"P4", REG_P4},
107 {"P4.H", REG_P4},
108 {"P4.L", REG_P4},
109 {"P5", REG_P5},
110 {"P5.H", REG_P5},
111 {"P5.L", REG_P5},
112 {"SP", REG_SP},
113 {"SP.L", REG_SP},
114 {"SP.H", REG_SP},
115 {"FP", REG_FP},
116 {"FP.L", REG_FP},
117 {"FP.H", REG_FP},
118 {"A0x", REG_A0x},
119 {"A1x", REG_A1x},
120 {"A0w", REG_A0w},
121 {"A1w", REG_A1w},
122 {"A0.x", REG_A0x},
123 {"A1.x", REG_A1x},
124 {"A0.w", REG_A0w},
125 {"A1.w", REG_A1w},
126 {"A0", REG_A0},
127 {"A0.L", REG_A0},
128 {"A0.H", REG_A0},
129 {"A1", REG_A1},
130 {"A1.L", REG_A1},
131 {"A1.H", REG_A1},
132 {"I0", REG_I0},
133 {"I0.L", REG_I0},
134 {"I0.H", REG_I0},
135 {"I1", REG_I1},
136 {"I1.L", REG_I1},
137 {"I1.H", REG_I1},
138 {"I2", REG_I2},
139 {"I2.L", REG_I2},
140 {"I2.H", REG_I2},
141 {"I3", REG_I3},
142 {"I3.L", REG_I3},
143 {"I3.H", REG_I3},
144 {"M0", REG_M0},
145 {"M0.H", REG_M0},
146 {"M0.L", REG_M0},
147 {"M1", REG_M1},
148 {"M1.H", REG_M1},
149 {"M1.L", REG_M1},
150 {"M2", REG_M2},
151 {"M2.H", REG_M2},
152 {"M2.L", REG_M2},
153 {"M3", REG_M3},
154 {"M3.H", REG_M3},
155 {"M3.L", REG_M3},
156 {"B0", REG_B0},
157 {"B0.H", REG_B0},
158 {"B0.L", REG_B0},
159 {"B1", REG_B1},
160 {"B1.H", REG_B1},
161 {"B1.L", REG_B1},
162 {"B2", REG_B2},
163 {"B2.H", REG_B2},
164 {"B2.L", REG_B2},
165 {"B3", REG_B3},
166 {"B3.H", REG_B3},
167 {"B3.L", REG_B3},
168 {"L0", REG_L0},
169 {"L0.H", REG_L0},
170 {"L0.L", REG_L0},
171 {"L1", REG_L1},
172 {"L1.H", REG_L1},
173 {"L1.L", REG_L1},
174 {"L2", REG_L2},
175 {"L2.H", REG_L2},
176 {"L2.L", REG_L2},
177 {"L3", REG_L3},
178 {"L3.H", REG_L3},
179 {"L3.L", REG_L3},
180 {"AZ", S_AZ},
181 {"AN", S_AN},
182 {"AC0", S_AC0},
183 {"AC1", S_AC1},
184 {"AV0", S_AV0},
185 {"AV0S", S_AV0S},
186 {"AV1", S_AV1},
187 {"AV1S", S_AV1S},
188 {"AQ", S_AQ},
189 {"V", S_V},
190 {"VS", S_VS},
191 {"sftreset", REG_sftreset},
192 {"omode", REG_omode},
193 {"excause", REG_excause},
194 {"emucause", REG_emucause},
195 {"idle_req", REG_idle_req},
196 {"hwerrcause", REG_hwerrcause},
197 {"CC", REG_CC},
198 {"LC0", REG_LC0},
199 {"LC1", REG_LC1},
200 {"ASTAT", REG_ASTAT},
201 {"RETS", REG_RETS},
202 {"LT0", REG_LT0},
203 {"LB0", REG_LB0},
204 {"LT1", REG_LT1},
205 {"LB1", REG_LB1},
206 {"CYCLES", REG_CYCLES},
207 {"CYCLES2", REG_CYCLES2},
208 {"USP", REG_USP},
209 {"SEQSTAT", REG_SEQSTAT},
210 {"SYSCFG", REG_SYSCFG},
211 {"RETI", REG_RETI},
212 {"RETX", REG_RETX},
213 {"RETN", REG_RETN},
214 {"RETE", REG_RETE},
215 {"EMUDAT", REG_EMUDAT},
216 {0, 0}
219 /* Blackfin specific function to handle FD-PIC pointer initializations. */
221 static void
222 bfin_pic_ptr (int nbytes)
224 expressionS exp;
225 char *p;
227 if (nbytes != 4)
228 abort ();
230 #ifdef md_flush_pending_output
231 md_flush_pending_output ();
232 #endif
234 if (is_it_end_of_statement ())
236 demand_empty_rest_of_line ();
237 return;
240 #ifdef md_cons_align
241 md_cons_align (nbytes);
242 #endif
246 bfd_reloc_code_real_type reloc_type = BFD_RELOC_BFIN_FUNCDESC;
248 if (strncasecmp (input_line_pointer, "funcdesc(", 9) == 0)
250 input_line_pointer += 9;
251 expression (&exp);
252 if (*input_line_pointer == ')')
253 input_line_pointer++;
254 else
255 as_bad (_("missing ')'"));
257 else
258 error ("missing funcdesc in picptr");
260 p = frag_more (4);
261 memset (p, 0, 4);
262 fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
263 reloc_type);
265 while (*input_line_pointer++ == ',');
267 input_line_pointer--; /* Put terminator back into stream. */
268 demand_empty_rest_of_line ();
271 static void
272 bfin_s_bss (int ignore ATTRIBUTE_UNUSED)
274 register int temp;
276 temp = get_absolute_expression ();
277 subseg_set (bss_section, (subsegT) temp);
278 demand_empty_rest_of_line ();
281 const pseudo_typeS md_pseudo_table[] = {
282 {"align", s_align_bytes, 0},
283 {"byte2", cons, 2},
284 {"byte4", cons, 4},
285 {"picptr", bfin_pic_ptr, 4},
286 {"code", obj_elf_section, 0},
287 {"db", cons, 1},
288 {"dd", cons, 4},
289 {"dw", cons, 2},
290 {"p", s_ignore, 0},
291 {"pdata", s_ignore, 0},
292 {"var", s_ignore, 0},
293 {"bss", bfin_s_bss, 0},
294 {0, 0, 0}
297 /* Characters that are used to denote comments and line separators. */
298 const char comment_chars[] = "";
299 const char line_comment_chars[] = "#";
300 const char line_separator_chars[] = ";";
302 /* Characters that can be used to separate the mantissa from the
303 exponent in floating point numbers. */
304 const char EXP_CHARS[] = "eE";
306 /* Characters that mean this number is a floating point constant.
307 As in 0f12.456 or 0d1.2345e12. */
308 const char FLT_CHARS[] = "fFdDxX";
310 /* Define bfin-specific command-line options (there are none). */
311 const char *md_shortopts = "";
313 #define OPTION_FDPIC (OPTION_MD_BASE)
314 #define OPTION_NOPIC (OPTION_MD_BASE + 1)
316 struct option md_longopts[] =
318 { "mfdpic", no_argument, NULL, OPTION_FDPIC },
319 { "mnopic", no_argument, NULL, OPTION_NOPIC },
320 { "mno-fdpic", no_argument, NULL, OPTION_NOPIC },
321 { NULL, no_argument, NULL, 0 },
324 size_t md_longopts_size = sizeof (md_longopts);
328 md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
330 switch (c)
332 default:
333 return 0;
335 case OPTION_FDPIC:
336 bfin_flags |= EF_BFIN_FDPIC;
337 bfin_pic_flag = "-mfdpic";
338 break;
340 case OPTION_NOPIC:
341 bfin_flags &= ~(EF_BFIN_FDPIC);
342 bfin_pic_flag = 0;
343 break;
346 return 1;
349 void
350 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
352 fprintf (stream, _(" BFIN specific command line options:\n"));
355 /* Perform machine-specific initializations. */
356 void
357 md_begin ()
359 /* Set the ELF flags if desired. */
360 if (bfin_flags)
361 bfd_set_private_flags (stdoutput, bfin_flags);
363 /* Set the default machine type. */
364 if (!bfd_set_arch_mach (stdoutput, bfd_arch_bfin, 0))
365 as_warn (_("Could not set architecture and machine."));
367 /* Ensure that lines can begin with '(', for multiple
368 register stack pops. */
369 lex_type ['('] = LEX_BEGIN_NAME;
371 #ifdef OBJ_ELF
372 record_alignment (text_section, 2);
373 record_alignment (data_section, 2);
374 record_alignment (bss_section, 2);
375 #endif
377 errorf = stderr;
378 obstack_init (&mempool);
380 #ifdef DEBUG
381 extern int debug_codeselection;
382 debug_codeselection = 1;
383 #endif
385 last_insn_size = 0;
388 /* Perform the main parsing, and assembly of the input here. Also,
389 call the required routines for alignment and fixups here.
390 This is called for every line that contains real assembly code. */
392 void
393 md_assemble (char *line)
395 char *toP = 0;
396 extern char *current_inputline;
397 int size, insn_size;
398 struct bfin_insn *tmp_insn;
399 size_t len;
400 static size_t buffer_len = 0;
401 parse_state state;
403 len = strlen (line);
404 if (len + 2 > buffer_len)
406 if (buffer_len > 0)
407 free (current_inputline);
408 buffer_len = len + 40;
409 current_inputline = xmalloc (buffer_len);
411 memcpy (current_inputline, line, len);
412 current_inputline[len] = ';';
413 current_inputline[len + 1] = '\0';
415 state = parse (current_inputline);
416 if (state == NO_INSN_GENERATED)
417 return;
419 for (insn_size = 0, tmp_insn = insn; tmp_insn; tmp_insn = tmp_insn->next)
420 if (!tmp_insn->reloc || !tmp_insn->exp->symbol)
421 insn_size += 2;
423 if (insn_size)
424 toP = frag_more (insn_size);
426 last_insn_size = insn_size;
428 #ifdef DEBUG
429 printf ("INS:");
430 #endif
431 while (insn)
433 if (insn->reloc && insn->exp->symbol)
435 char *prev_toP = toP - 2;
436 switch (insn->reloc)
438 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
439 case BFD_RELOC_24_PCREL:
440 case BFD_RELOC_BFIN_16_LOW:
441 case BFD_RELOC_BFIN_16_HIGH:
442 size = 4;
443 break;
444 default:
445 size = 2;
448 /* Following if condition checks for the arithmetic relocations.
449 If the case then it doesn't required to generate the code.
450 It has been assumed that, their ID will be contiguous. */
451 if ((BFD_ARELOC_BFIN_PUSH <= insn->reloc
452 && BFD_ARELOC_BFIN_COMP >= insn->reloc)
453 || insn->reloc == BFD_RELOC_BFIN_16_IMM)
455 size = 2;
457 if (insn->reloc == BFD_ARELOC_BFIN_CONST
458 || insn->reloc == BFD_ARELOC_BFIN_PUSH)
459 size = 4;
461 fix_new (frag_now,
462 (prev_toP - frag_now->fr_literal),
463 size, insn->exp->symbol, insn->exp->value,
464 insn->pcrel, insn->reloc);
466 else
468 md_number_to_chars (toP, insn->value, 2);
469 toP += 2;
472 #ifdef DEBUG
473 printf (" reloc :");
474 printf (" %02x%02x", ((unsigned char *) &insn->value)[0],
475 ((unsigned char *) &insn->value)[1]);
476 printf ("\n");
477 #endif
478 insn = insn->next;
480 #ifdef OBJ_ELF
481 dwarf2_emit_insn (insn_size);
482 #endif
485 /* Parse one line of instructions, and generate opcode for it.
486 To parse the line, YACC and LEX are used, because the instruction set
487 syntax doesn't confirm to the AT&T assembly syntax.
488 To call a YACC & LEX generated parser, we must provide the input via
489 a FILE stream, otherwise stdin is used by default. Below the input
490 to the function will be put into a temporary file, then the generated
491 parser uses the temporary file for parsing. */
493 static parse_state
494 parse (char *line)
496 parse_state state;
497 YY_BUFFER_STATE buffstate;
499 buffstate = yy_scan_string (line);
501 /* our lex requires setting the start state to keyword
502 every line as the first word may be a keyword.
503 Fixes a bug where we could not have keywords as labels. */
504 set_start_state ();
506 /* Call yyparse here. */
507 state = yyparse ();
508 if (state == SEMANTIC_ERROR)
510 as_bad (_("Parse failed."));
511 insn = 0;
514 yy_delete_buffer (buffstate);
515 return state;
518 /* We need to handle various expressions properly.
519 Such as, [SP--] = 34, concerned by md_assemble(). */
521 void
522 md_operand (expressionS * expressionP)
524 if (*input_line_pointer == '[')
526 as_tsktsk ("We found a '['!");
527 input_line_pointer++;
528 expression (expressionP);
532 /* Handle undefined symbols. */
533 symbolS *
534 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
536 return (symbolS *) 0;
540 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
541 segT segment ATTRIBUTE_UNUSED)
543 return 0;
546 /* Convert from target byte order to host byte order. */
548 static int
549 md_chars_to_number (char *val, int n)
551 int retval;
553 for (retval = 0; n--;)
555 retval <<= 8;
556 retval |= val[n];
558 return retval;
561 void
562 md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
564 char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
566 long value = *valueP;
567 long newval;
569 switch (fixP->fx_r_type)
571 case BFD_RELOC_BFIN_GOT:
572 case BFD_RELOC_BFIN_GOT17M4:
573 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
574 fixP->fx_no_overflow = 1;
575 newval = md_chars_to_number (where, 2);
576 newval |= 0x0 & 0x7f;
577 md_number_to_chars (where, newval, 2);
578 break;
580 case BFD_RELOC_BFIN_10_PCREL:
581 if (!value)
582 break;
583 if (value < -1024 || value > 1022)
584 as_bad_where (fixP->fx_file, fixP->fx_line,
585 _("pcrel too far BFD_RELOC_BFIN_10"));
587 /* 11 bit offset even numbered, so we remove right bit. */
588 value = value >> 1;
589 newval = md_chars_to_number (where, 2);
590 newval |= value & 0x03ff;
591 md_number_to_chars (where, newval, 2);
592 break;
594 case BFD_RELOC_BFIN_12_PCREL_JUMP:
595 case BFD_RELOC_BFIN_12_PCREL_JUMP_S:
596 case BFD_RELOC_12_PCREL:
597 if (!value)
598 break;
600 if (value < -4096 || value > 4094)
601 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_12"));
602 /* 13 bit offset even numbered, so we remove right bit. */
603 value = value >> 1;
604 newval = md_chars_to_number (where, 2);
605 newval |= value & 0xfff;
606 md_number_to_chars (where, newval, 2);
607 break;
609 case BFD_RELOC_BFIN_16_LOW:
610 case BFD_RELOC_BFIN_16_HIGH:
611 fixP->fx_done = FALSE;
612 break;
614 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
615 case BFD_RELOC_BFIN_24_PCREL_CALL_X:
616 case BFD_RELOC_24_PCREL:
617 if (!value)
618 break;
620 if (value < -16777216 || value > 16777214)
621 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_24"));
623 /* 25 bit offset even numbered, so we remove right bit. */
624 value = value >> 1;
625 value++;
627 md_number_to_chars (where - 2, value >> 16, 1);
628 md_number_to_chars (where, value, 1);
629 md_number_to_chars (where + 1, value >> 8, 1);
630 break;
632 case BFD_RELOC_BFIN_5_PCREL: /* LSETUP (a, b) : "a" */
633 if (!value)
634 break;
635 if (value < 4 || value > 30)
636 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_5"));
637 value = value >> 1;
638 newval = md_chars_to_number (where, 1);
639 newval = (newval & 0xf0) | (value & 0xf);
640 md_number_to_chars (where, newval, 1);
641 break;
643 case BFD_RELOC_BFIN_11_PCREL: /* LSETUP (a, b) : "b" */
644 if (!value)
645 break;
646 value += 2;
647 if (value < 4 || value > 2046)
648 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_11_PCREL"));
649 /* 11 bit unsigned even, so we remove right bit. */
650 value = value >> 1;
651 newval = md_chars_to_number (where, 2);
652 newval |= value & 0x03ff;
653 md_number_to_chars (where, newval, 2);
654 break;
656 case BFD_RELOC_8:
657 if (value < -0x80 || value >= 0x7f)
658 as_bad_where (fixP->fx_file, fixP->fx_line, _("rel too far BFD_RELOC_8"));
659 md_number_to_chars (where, value, 1);
660 break;
662 case BFD_RELOC_BFIN_16_IMM:
663 case BFD_RELOC_16:
664 if (value < -0x8000 || value >= 0x7fff)
665 as_bad_where (fixP->fx_file, fixP->fx_line, _("rel too far BFD_RELOC_16"));
666 md_number_to_chars (where, value, 2);
667 break;
669 case BFD_RELOC_32:
670 md_number_to_chars (where, value, 4);
671 break;
673 case BFD_RELOC_BFIN_PLTPC:
674 md_number_to_chars (where, value, 2);
675 break;
677 case BFD_RELOC_BFIN_FUNCDESC:
678 case BFD_RELOC_VTABLE_INHERIT:
679 case BFD_RELOC_VTABLE_ENTRY:
680 fixP->fx_done = FALSE;
681 break;
683 default:
684 if ((BFD_ARELOC_BFIN_PUSH > fixP->fx_r_type) || (BFD_ARELOC_BFIN_COMP < fixP->fx_r_type))
686 fprintf (stderr, "Relocation %d not handled in gas." " Contact support.\n", fixP->fx_r_type);
687 return;
691 if (!fixP->fx_addsy)
692 fixP->fx_done = TRUE;
696 /* Round up a section size to the appropriate boundary. */
697 valueT
698 md_section_align (segment, size)
699 segT segment;
700 valueT size;
702 int boundary = bfd_get_section_alignment (stdoutput, segment);
703 return ((size + (1 << boundary) - 1) & (-1 << boundary));
707 char *
708 md_atof (int type, char * litP, int * sizeP)
710 return ieee_md_atof (type, litP, sizeP, FALSE);
714 /* If while processing a fixup, a reloc really needs to be created
715 then it is done here. */
717 arelent *
718 tc_gen_reloc (seg, fixp)
719 asection *seg ATTRIBUTE_UNUSED;
720 fixS *fixp;
722 arelent *reloc;
724 reloc = (arelent *) xmalloc (sizeof (arelent));
725 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
726 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
727 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
729 reloc->addend = fixp->fx_offset;
730 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
732 if (reloc->howto == (reloc_howto_type *) NULL)
734 as_bad_where (fixp->fx_file, fixp->fx_line,
735 /* xgettext:c-format. */
736 _("reloc %d not supported by object file format"),
737 (int) fixp->fx_r_type);
739 xfree (reloc);
741 return NULL;
744 return reloc;
747 /* The location from which a PC relative jump should be calculated,
748 given a PC relative reloc. */
750 long
751 md_pcrel_from_section (fixP, sec)
752 fixS *fixP;
753 segT sec;
755 if (fixP->fx_addsy != (symbolS *) NULL
756 && (!S_IS_DEFINED (fixP->fx_addsy)
757 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
759 /* The symbol is undefined (or is defined but not in this section).
760 Let the linker figure it out. */
761 return 0;
763 return fixP->fx_frag->fr_address + fixP->fx_where;
766 /* Return true if the fix can be handled by GAS, false if it must
767 be passed through to the linker. */
769 bfd_boolean
770 bfin_fix_adjustable (fixS *fixP)
772 switch (fixP->fx_r_type)
774 /* Adjust_reloc_syms doesn't know about the GOT. */
775 case BFD_RELOC_BFIN_GOT:
776 case BFD_RELOC_BFIN_GOT17M4:
777 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
778 case BFD_RELOC_BFIN_PLTPC:
779 /* We need the symbol name for the VTABLE entries. */
780 case BFD_RELOC_VTABLE_INHERIT:
781 case BFD_RELOC_VTABLE_ENTRY:
782 return 0;
784 default:
785 return 1;
790 /* Handle the LOOP_BEGIN and LOOP_END statements.
791 Parse the Loop_Begin/Loop_End and create a label. */
792 void
793 bfin_start_line_hook ()
795 bfd_boolean maybe_begin = FALSE;
796 bfd_boolean maybe_end = FALSE;
798 char *c1, *label_name;
799 symbolS *line_label;
800 char *c = input_line_pointer;
801 int cr_num = 0;
803 while (ISSPACE (*c))
805 if (*c == '\n')
806 cr_num++;
807 c++;
810 /* Look for Loop_Begin or Loop_End statements. */
812 if (*c != 'L' && *c != 'l')
813 return;
815 c++;
816 if (*c != 'O' && *c != 'o')
817 return;
819 c++;
820 if (*c != 'O' && *c != 'o')
821 return;
823 c++;
824 if (*c != 'P' && *c != 'p')
825 return;
827 c++;
828 if (*c != '_')
829 return;
831 c++;
832 if (*c == 'E' || *c == 'e')
833 maybe_end = TRUE;
834 else if (*c == 'B' || *c == 'b')
835 maybe_begin = TRUE;
836 else
837 return;
839 if (maybe_end)
841 c++;
842 if (*c != 'N' && *c != 'n')
843 return;
845 c++;
846 if (*c != 'D' && *c != 'd')
847 return;
850 if (maybe_begin)
852 c++;
853 if (*c != 'E' && *c != 'e')
854 return;
856 c++;
857 if (*c != 'G' && *c != 'g')
858 return;
860 c++;
861 if (*c != 'I' && *c != 'i')
862 return;
864 c++;
865 if (*c != 'N' && *c != 'n')
866 return;
869 c++;
870 while (ISSPACE (*c)) c++;
871 c1 = c;
872 while (ISALPHA (*c) || ISDIGIT (*c) || *c == '_') c++;
874 if (input_line_pointer[-1] == '\n')
875 bump_line_counters ();
877 while (cr_num--)
878 bump_line_counters ();
880 input_line_pointer = c;
881 if (maybe_end)
883 label_name = (char *) xmalloc ((c - c1) + strlen ("__END") + 5);
884 label_name[0] = 0;
885 strcat (label_name, "L$L$");
886 strncat (label_name, c1, c-c1);
887 strcat (label_name, "__END");
889 else /* maybe_begin. */
891 label_name = (char *) xmalloc ((c - c1) + strlen ("__BEGIN") + 5);
892 label_name[0] = 0;
893 strcat (label_name, "L$L$");
894 strncat (label_name, c1, c-c1);
895 strcat (label_name, "__BEGIN");
898 line_label = colon (label_name);
900 /* Loop_End follows the last instruction in the loop.
901 Adjust label address. */
902 if (maybe_end)
903 ((struct local_symbol *) line_label)->lsy_value -= last_insn_size;
906 /* Special extra functions that help bfin-parse.y perform its job. */
908 #include <assert.h>
910 struct obstack mempool;
912 INSTR_T
913 conscode (INSTR_T head, INSTR_T tail)
915 if (!head)
916 return tail;
917 head->next = tail;
918 return head;
921 INSTR_T
922 conctcode (INSTR_T head, INSTR_T tail)
924 INSTR_T temp = (head);
925 if (!head)
926 return tail;
927 while (temp->next)
928 temp = temp->next;
929 temp->next = tail;
931 return head;
934 INSTR_T
935 note_reloc (INSTR_T code, Expr_Node * symbol, int reloc, int pcrel)
937 /* Assert that the symbol is not an operator. */
938 assert (symbol->type == Expr_Node_Reloc);
940 return note_reloc1 (code, symbol->value.s_value, reloc, pcrel);
944 INSTR_T
945 note_reloc1 (INSTR_T code, const char *symbol, int reloc, int pcrel)
947 code->reloc = reloc;
948 code->exp = mkexpr (0, symbol_find_or_make (symbol));
949 code->pcrel = pcrel;
950 return code;
953 INSTR_T
954 note_reloc2 (INSTR_T code, const char *symbol, int reloc, int value, int pcrel)
956 code->reloc = reloc;
957 code->exp = mkexpr (value, symbol_find_or_make (symbol));
958 code->pcrel = pcrel;
959 return code;
962 INSTR_T
963 gencode (unsigned long x)
965 INSTR_T cell = (INSTR_T) obstack_alloc (&mempool, sizeof (struct bfin_insn));
966 memset (cell, 0, sizeof (struct bfin_insn));
967 cell->value = (x);
968 return cell;
971 int reloc;
972 int ninsns;
973 int count_insns;
975 static void *
976 allocate (int n)
978 return (void *) obstack_alloc (&mempool, n);
981 Expr_Node *
982 Expr_Node_Create (Expr_Node_Type type,
983 Expr_Node_Value value,
984 Expr_Node *Left_Child,
985 Expr_Node *Right_Child)
989 Expr_Node *node = (Expr_Node *) allocate (sizeof (Expr_Node));
990 node->type = type;
991 node->value = value;
992 node->Left_Child = Left_Child;
993 node->Right_Child = Right_Child;
994 return node;
997 static const char *con = ".__constant";
998 static const char *op = ".__operator";
999 static INSTR_T Expr_Node_Gen_Reloc_R (Expr_Node * head);
1000 INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc);
1002 INSTR_T
1003 Expr_Node_Gen_Reloc (Expr_Node * head, int parent_reloc)
1005 /* Top level reloction expression generator VDSP style.
1006 If the relocation is just by itself, generate one item
1007 else generate this convoluted expression. */
1009 INSTR_T note = NULL_CODE;
1010 INSTR_T note1 = NULL_CODE;
1011 int pcrel = 1; /* Is the parent reloc pcrelative?
1012 This calculation here and HOWTO should match. */
1014 if (parent_reloc)
1016 /* If it's 32 bit quantity then 16bit code needs to be added. */
1017 int value = 0;
1019 if (head->type == Expr_Node_Constant)
1021 /* If note1 is not null code, we have to generate a right
1022 aligned value for the constant. Otherwise the reloc is
1023 a part of the basic command and the yacc file
1024 generates this. */
1025 value = head->value.i_value;
1027 switch (parent_reloc)
1029 /* Some relocations will need to allocate extra words. */
1030 case BFD_RELOC_BFIN_16_IMM:
1031 case BFD_RELOC_BFIN_16_LOW:
1032 case BFD_RELOC_BFIN_16_HIGH:
1033 note1 = conscode (gencode (value), NULL_CODE);
1034 pcrel = 0;
1035 break;
1036 case BFD_RELOC_BFIN_PLTPC:
1037 note1 = conscode (gencode (value), NULL_CODE);
1038 pcrel = 0;
1039 break;
1040 case BFD_RELOC_16:
1041 case BFD_RELOC_BFIN_GOT:
1042 case BFD_RELOC_BFIN_GOT17M4:
1043 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
1044 note1 = conscode (gencode (value), NULL_CODE);
1045 pcrel = 0;
1046 break;
1047 case BFD_RELOC_24_PCREL:
1048 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
1049 case BFD_RELOC_BFIN_24_PCREL_CALL_X:
1050 /* These offsets are even numbered pcrel. */
1051 note1 = conscode (gencode (value >> 1), NULL_CODE);
1052 break;
1053 default:
1054 note1 = NULL_CODE;
1057 if (head->type == Expr_Node_Constant)
1058 note = note1;
1059 else if (head->type == Expr_Node_Reloc)
1061 note = note_reloc1 (gencode (0), head->value.s_value, parent_reloc, pcrel);
1062 if (note1 != NULL_CODE)
1063 note = conscode (note1, note);
1065 else if (head->type == Expr_Node_Binop
1066 && (head->value.op_value == Expr_Op_Type_Add
1067 || head->value.op_value == Expr_Op_Type_Sub)
1068 && head->Left_Child->type == Expr_Node_Reloc
1069 && head->Right_Child->type == Expr_Node_Constant)
1071 int val = head->Right_Child->value.i_value;
1072 if (head->value.op_value == Expr_Op_Type_Sub)
1073 val = -val;
1074 note = conscode (note_reloc2 (gencode (0), head->Left_Child->value.s_value,
1075 parent_reloc, val, 0),
1076 NULL_CODE);
1077 if (note1 != NULL_CODE)
1078 note = conscode (note1, note);
1080 else
1082 /* Call the recursive function. */
1083 note = note_reloc1 (gencode (0), op, parent_reloc, pcrel);
1084 if (note1 != NULL_CODE)
1085 note = conscode (note1, note);
1086 note = conctcode (Expr_Node_Gen_Reloc_R (head), note);
1088 return note;
1091 static INSTR_T
1092 Expr_Node_Gen_Reloc_R (Expr_Node * head)
1095 INSTR_T note = 0;
1096 INSTR_T note1 = 0;
1098 switch (head->type)
1100 case Expr_Node_Constant:
1101 note = conscode (note_reloc2 (gencode (0), con, BFD_ARELOC_BFIN_CONST, head->value.i_value, 0), NULL_CODE);
1102 break;
1103 case Expr_Node_Reloc:
1104 note = conscode (note_reloc (gencode (0), head, BFD_ARELOC_BFIN_PUSH, 0), NULL_CODE);
1105 break;
1106 case Expr_Node_Binop:
1107 note1 = conctcode (Expr_Node_Gen_Reloc_R (head->Left_Child), Expr_Node_Gen_Reloc_R (head->Right_Child));
1108 switch (head->value.op_value)
1110 case Expr_Op_Type_Add:
1111 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_ADD, 0), NULL_CODE));
1112 break;
1113 case Expr_Op_Type_Sub:
1114 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_SUB, 0), NULL_CODE));
1115 break;
1116 case Expr_Op_Type_Mult:
1117 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MULT, 0), NULL_CODE));
1118 break;
1119 case Expr_Op_Type_Div:
1120 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_DIV, 0), NULL_CODE));
1121 break;
1122 case Expr_Op_Type_Mod:
1123 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MOD, 0), NULL_CODE));
1124 break;
1125 case Expr_Op_Type_Lshift:
1126 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LSHIFT, 0), NULL_CODE));
1127 break;
1128 case Expr_Op_Type_Rshift:
1129 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_RSHIFT, 0), NULL_CODE));
1130 break;
1131 case Expr_Op_Type_BAND:
1132 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_AND, 0), NULL_CODE));
1133 break;
1134 case Expr_Op_Type_BOR:
1135 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_OR, 0), NULL_CODE));
1136 break;
1137 case Expr_Op_Type_BXOR:
1138 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_XOR, 0), NULL_CODE));
1139 break;
1140 case Expr_Op_Type_LAND:
1141 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LAND, 0), NULL_CODE));
1142 break;
1143 case Expr_Op_Type_LOR:
1144 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LOR, 0), NULL_CODE));
1145 break;
1146 default:
1147 fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
1151 break;
1152 case Expr_Node_Unop:
1153 note1 = conscode (Expr_Node_Gen_Reloc_R (head->Left_Child), NULL_CODE);
1154 switch (head->value.op_value)
1156 case Expr_Op_Type_NEG:
1157 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_NEG, 0), NULL_CODE));
1158 break;
1159 case Expr_Op_Type_COMP:
1160 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_COMP, 0), NULL_CODE));
1161 break;
1162 default:
1163 fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
1165 break;
1166 default:
1167 fprintf (stderr, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__, __LINE__);
1169 return note;
1173 /* Blackfin opcode generation. */
1175 /* These functions are called by the generated parser
1176 (from bfin-parse.y), the register type classification
1177 happens in bfin-lex.l. */
1179 #include "bfin-aux.h"
1180 #include "opcode/bfin.h"
1182 #define INIT(t) t c_code = init_##t
1183 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1184 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1186 #define HI(x) ((x >> 16) & 0xffff)
1187 #define LO(x) ((x ) & 0xffff)
1189 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1191 #define GEN_OPCODE32() \
1192 conscode (gencode (HI (c_code.opcode)), \
1193 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1195 #define GEN_OPCODE16() \
1196 conscode (gencode (c_code.opcode), NULL_CODE)
1199 /* 32 BIT INSTRUCTIONS. */
1202 /* DSP32 instruction generation. */
1204 INSTR_T
1205 bfin_gen_dsp32mac (int op1, int MM, int mmod, int w1, int P,
1206 int h01, int h11, int h00, int h10, int op0,
1207 REG_T dst, REG_T src0, REG_T src1, int w0)
1209 INIT (DSP32Mac);
1211 ASSIGN (op0);
1212 ASSIGN (op1);
1213 ASSIGN (MM);
1214 ASSIGN (mmod);
1215 ASSIGN (w0);
1216 ASSIGN (w1);
1217 ASSIGN (h01);
1218 ASSIGN (h11);
1219 ASSIGN (h00);
1220 ASSIGN (h10);
1221 ASSIGN (P);
1223 /* If we have full reg assignments, mask out LSB to encode
1224 single or simultaneous even/odd register moves. */
1225 if (P)
1227 dst->regno &= 0x06;
1230 ASSIGN_R (dst);
1231 ASSIGN_R (src0);
1232 ASSIGN_R (src1);
1234 return GEN_OPCODE32 ();
1237 INSTR_T
1238 bfin_gen_dsp32mult (int op1, int MM, int mmod, int w1, int P,
1239 int h01, int h11, int h00, int h10, int op0,
1240 REG_T dst, REG_T src0, REG_T src1, int w0)
1242 INIT (DSP32Mult);
1244 ASSIGN (op0);
1245 ASSIGN (op1);
1246 ASSIGN (MM);
1247 ASSIGN (mmod);
1248 ASSIGN (w0);
1249 ASSIGN (w1);
1250 ASSIGN (h01);
1251 ASSIGN (h11);
1252 ASSIGN (h00);
1253 ASSIGN (h10);
1254 ASSIGN (P);
1256 if (P)
1258 dst->regno &= 0x06;
1261 ASSIGN_R (dst);
1262 ASSIGN_R (src0);
1263 ASSIGN_R (src1);
1265 return GEN_OPCODE32 ();
1268 INSTR_T
1269 bfin_gen_dsp32alu (int HL, int aopcde, int aop, int s, int x,
1270 REG_T dst0, REG_T dst1, REG_T src0, REG_T src1)
1272 INIT (DSP32Alu);
1274 ASSIGN (HL);
1275 ASSIGN (aopcde);
1276 ASSIGN (aop);
1277 ASSIGN (s);
1278 ASSIGN (x);
1279 ASSIGN_R (dst0);
1280 ASSIGN_R (dst1);
1281 ASSIGN_R (src0);
1282 ASSIGN_R (src1);
1284 return GEN_OPCODE32 ();
1287 INSTR_T
1288 bfin_gen_dsp32shift (int sopcde, REG_T dst0, REG_T src0,
1289 REG_T src1, int sop, int HLs)
1291 INIT (DSP32Shift);
1293 ASSIGN (sopcde);
1294 ASSIGN (sop);
1295 ASSIGN (HLs);
1297 ASSIGN_R (dst0);
1298 ASSIGN_R (src0);
1299 ASSIGN_R (src1);
1301 return GEN_OPCODE32 ();
1304 INSTR_T
1305 bfin_gen_dsp32shiftimm (int sopcde, REG_T dst0, int immag,
1306 REG_T src1, int sop, int HLs)
1308 INIT (DSP32ShiftImm);
1310 ASSIGN (sopcde);
1311 ASSIGN (sop);
1312 ASSIGN (HLs);
1314 ASSIGN_R (dst0);
1315 ASSIGN (immag);
1316 ASSIGN_R (src1);
1318 return GEN_OPCODE32 ();
1321 /* LOOP SETUP. */
1323 INSTR_T
1324 bfin_gen_loopsetup (Expr_Node * psoffset, REG_T c, int rop,
1325 Expr_Node * peoffset, REG_T reg)
1327 int soffset, eoffset;
1328 INIT (LoopSetup);
1330 soffset = (EXPR_VALUE (psoffset) >> 1);
1331 ASSIGN (soffset);
1332 eoffset = (EXPR_VALUE (peoffset) >> 1);
1333 ASSIGN (eoffset);
1334 ASSIGN (rop);
1335 ASSIGN_R (c);
1336 ASSIGN_R (reg);
1338 return
1339 conscode (gencode (HI (c_code.opcode)),
1340 conctcode (Expr_Node_Gen_Reloc (psoffset, BFD_RELOC_BFIN_5_PCREL),
1341 conctcode (gencode (LO (c_code.opcode)), Expr_Node_Gen_Reloc (peoffset, BFD_RELOC_BFIN_11_PCREL))));
1345 /* Call, Link. */
1347 INSTR_T
1348 bfin_gen_calla (Expr_Node * addr, int S)
1350 int val;
1351 int high_val;
1352 int reloc = 0;
1353 INIT (CALLa);
1355 switch(S){
1356 case 0 : reloc = BFD_RELOC_BFIN_24_PCREL_JUMP_L; break;
1357 case 1 : reloc = BFD_RELOC_24_PCREL; break;
1358 case 2 : reloc = BFD_RELOC_BFIN_PLTPC; break;
1359 default : break;
1362 ASSIGN (S);
1364 val = EXPR_VALUE (addr) >> 1;
1365 high_val = val >> 16;
1367 return conscode (gencode (HI (c_code.opcode) | (high_val & 0xff)),
1368 Expr_Node_Gen_Reloc (addr, reloc));
1371 INSTR_T
1372 bfin_gen_linkage (int R, int framesize)
1374 INIT (Linkage);
1376 ASSIGN (R);
1377 ASSIGN (framesize);
1379 return GEN_OPCODE32 ();
1383 /* Load and Store. */
1385 INSTR_T
1386 bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int reloc)
1388 int grp, hword;
1389 unsigned val = EXPR_VALUE (phword);
1390 INIT (LDIMMhalf);
1392 ASSIGN (H);
1393 ASSIGN (S);
1394 ASSIGN (Z);
1396 ASSIGN_R (reg);
1397 grp = (GROUP (reg));
1398 ASSIGN (grp);
1399 if (reloc == 2)
1401 return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, BFD_RELOC_BFIN_16_IMM));
1403 else if (reloc == 1)
1405 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));
1407 else
1409 hword = val;
1410 ASSIGN (hword);
1412 return GEN_OPCODE32 ();
1415 INSTR_T
1416 bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset)
1418 INIT (LDSTidxI);
1420 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1422 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1423 return 0;
1426 ASSIGN_R (ptr);
1427 ASSIGN_R (reg);
1428 ASSIGN (W);
1429 ASSIGN (sz);
1431 ASSIGN (Z);
1433 if (poffset->type != Expr_Node_Constant)
1435 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1436 /* distinguish between R0 = [P5 + symbol@GOT] and
1437 P5 = [P5 + _current_shared_library_p5_offset_]
1439 if (poffset->type == Expr_Node_Reloc
1440 && !strcmp (poffset->value.s_value,
1441 "_current_shared_library_p5_offset_"))
1443 return conscode (gencode (HI (c_code.opcode)),
1444 Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16));
1446 else if (poffset->type != Expr_Node_GOT_Reloc)
1447 abort ();
1449 return conscode (gencode (HI (c_code.opcode)),
1450 Expr_Node_Gen_Reloc(poffset->Left_Child,
1451 poffset->value.i_value));
1453 else
1455 int value, offset;
1456 switch (sz)
1457 { // load/store access size
1458 case 0: // 32 bit
1459 value = EXPR_VALUE (poffset) >> 2;
1460 break;
1461 case 1: // 16 bit
1462 value = EXPR_VALUE (poffset) >> 1;
1463 break;
1464 case 2: // 8 bit
1465 value = EXPR_VALUE (poffset);
1466 break;
1467 default:
1468 abort ();
1471 offset = (value & 0xffff);
1472 ASSIGN (offset);
1473 return GEN_OPCODE32 ();
1478 INSTR_T
1479 bfin_gen_ldst (REG_T ptr, REG_T reg, int aop, int sz, int Z, int W)
1481 INIT (LDST);
1483 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1485 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1486 return 0;
1489 ASSIGN_R (ptr);
1490 ASSIGN_R (reg);
1491 ASSIGN (aop);
1492 ASSIGN (sz);
1493 ASSIGN (Z);
1494 ASSIGN (W);
1496 return GEN_OPCODE16 ();
1499 INSTR_T
1500 bfin_gen_ldstii (REG_T ptr, REG_T reg, Expr_Node * poffset, int W, int op)
1502 int offset;
1503 int value = 0;
1504 INIT (LDSTii);
1507 if (!IS_PREG (*ptr))
1509 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1510 return 0;
1513 switch (op)
1515 case 1:
1516 case 2:
1517 value = EXPR_VALUE (poffset) >> 1;
1518 break;
1519 case 0:
1520 case 3:
1521 value = EXPR_VALUE (poffset) >> 2;
1522 break;
1525 ASSIGN_R (ptr);
1526 ASSIGN_R (reg);
1528 offset = value;
1529 ASSIGN (offset);
1530 ASSIGN (W);
1531 ASSIGN (op);
1533 return GEN_OPCODE16 ();
1536 INSTR_T
1537 bfin_gen_ldstiifp (REG_T sreg, Expr_Node * poffset, int W)
1539 /* Set bit 4 if it's a Preg. */
1540 int reg = (sreg->regno & CODE_MASK) | (IS_PREG (*sreg) ? 0x8 : 0x0);
1541 int offset = ((~(EXPR_VALUE (poffset) >> 2)) & 0x1f) + 1;
1542 INIT (LDSTiiFP);
1543 ASSIGN (reg);
1544 ASSIGN (offset);
1545 ASSIGN (W);
1547 return GEN_OPCODE16 ();
1550 INSTR_T
1551 bfin_gen_ldstpmod (REG_T ptr, REG_T reg, int aop, int W, REG_T idx)
1553 INIT (LDSTpmod);
1555 ASSIGN_R (ptr);
1556 ASSIGN_R (reg);
1557 ASSIGN (aop);
1558 ASSIGN (W);
1559 ASSIGN_R (idx);
1561 return GEN_OPCODE16 ();
1564 INSTR_T
1565 bfin_gen_dspldst (REG_T i, REG_T reg, int aop, int W, int m)
1567 INIT (DspLDST);
1569 ASSIGN_R (i);
1570 ASSIGN_R (reg);
1571 ASSIGN (aop);
1572 ASSIGN (W);
1573 ASSIGN (m);
1575 return GEN_OPCODE16 ();
1578 INSTR_T
1579 bfin_gen_logi2op (int opc, int src, int dst)
1581 INIT (LOGI2op);
1583 ASSIGN (opc);
1584 ASSIGN (src);
1585 ASSIGN (dst);
1587 return GEN_OPCODE16 ();
1590 INSTR_T
1591 bfin_gen_brcc (int T, int B, Expr_Node * poffset)
1593 int offset;
1594 INIT (BRCC);
1596 ASSIGN (T);
1597 ASSIGN (B);
1598 offset = ((EXPR_VALUE (poffset) >> 1));
1599 ASSIGN (offset);
1600 return conscode (gencode (c_code.opcode), Expr_Node_Gen_Reloc (poffset, BFD_RELOC_BFIN_10_PCREL));
1603 INSTR_T
1604 bfin_gen_ujump (Expr_Node * poffset)
1606 int offset;
1607 INIT (UJump);
1609 offset = ((EXPR_VALUE (poffset) >> 1));
1610 ASSIGN (offset);
1612 return conscode (gencode (c_code.opcode),
1613 Expr_Node_Gen_Reloc (
1614 poffset, BFD_RELOC_BFIN_12_PCREL_JUMP_S));
1617 INSTR_T
1618 bfin_gen_alu2op (REG_T dst, REG_T src, int opc)
1620 INIT (ALU2op);
1622 ASSIGN_R (dst);
1623 ASSIGN_R (src);
1624 ASSIGN (opc);
1626 return GEN_OPCODE16 ();
1629 INSTR_T
1630 bfin_gen_compi2opd (REG_T dst, int src, int op)
1632 INIT (COMPI2opD);
1634 ASSIGN_R (dst);
1635 ASSIGN (src);
1636 ASSIGN (op);
1638 return GEN_OPCODE16 ();
1641 INSTR_T
1642 bfin_gen_compi2opp (REG_T dst, int src, int op)
1644 INIT (COMPI2opP);
1646 ASSIGN_R (dst);
1647 ASSIGN (src);
1648 ASSIGN (op);
1650 return GEN_OPCODE16 ();
1653 INSTR_T
1654 bfin_gen_dagmodik (REG_T i, int op)
1656 INIT (DagMODik);
1658 ASSIGN_R (i);
1659 ASSIGN (op);
1661 return GEN_OPCODE16 ();
1664 INSTR_T
1665 bfin_gen_dagmodim (REG_T i, REG_T m, int op, int br)
1667 INIT (DagMODim);
1669 ASSIGN_R (i);
1670 ASSIGN_R (m);
1671 ASSIGN (op);
1672 ASSIGN (br);
1674 return GEN_OPCODE16 ();
1677 INSTR_T
1678 bfin_gen_ptr2op (REG_T dst, REG_T src, int opc)
1680 INIT (PTR2op);
1682 ASSIGN_R (dst);
1683 ASSIGN_R (src);
1684 ASSIGN (opc);
1686 return GEN_OPCODE16 ();
1689 INSTR_T
1690 bfin_gen_comp3op (REG_T src0, REG_T src1, REG_T dst, int opc)
1692 INIT (COMP3op);
1694 ASSIGN_R (src0);
1695 ASSIGN_R (src1);
1696 ASSIGN_R (dst);
1697 ASSIGN (opc);
1699 return GEN_OPCODE16 ();
1702 INSTR_T
1703 bfin_gen_ccflag (REG_T x, int y, int opc, int I, int G)
1705 INIT (CCflag);
1707 ASSIGN_R (x);
1708 ASSIGN (y);
1709 ASSIGN (opc);
1710 ASSIGN (I);
1711 ASSIGN (G);
1713 return GEN_OPCODE16 ();
1716 INSTR_T
1717 bfin_gen_ccmv (REG_T src, REG_T dst, int T)
1719 int s, d;
1720 INIT (CCmv);
1722 ASSIGN_R (src);
1723 ASSIGN_R (dst);
1724 s = (GROUP (src));
1725 ASSIGN (s);
1726 d = (GROUP (dst));
1727 ASSIGN (d);
1728 ASSIGN (T);
1730 return GEN_OPCODE16 ();
1733 INSTR_T
1734 bfin_gen_cc2stat (int cbit, int op, int D)
1736 INIT (CC2stat);
1738 ASSIGN (cbit);
1739 ASSIGN (op);
1740 ASSIGN (D);
1742 return GEN_OPCODE16 ();
1745 INSTR_T
1746 bfin_gen_regmv (REG_T src, REG_T dst)
1748 int gs, gd;
1749 INIT (RegMv);
1751 ASSIGN_R (src);
1752 ASSIGN_R (dst);
1754 gs = (GROUP (src));
1755 ASSIGN (gs);
1756 gd = (GROUP (dst));
1757 ASSIGN (gd);
1759 return GEN_OPCODE16 ();
1762 INSTR_T
1763 bfin_gen_cc2dreg (int op, REG_T reg)
1765 INIT (CC2dreg);
1767 ASSIGN (op);
1768 ASSIGN_R (reg);
1770 return GEN_OPCODE16 ();
1773 INSTR_T
1774 bfin_gen_progctrl (int prgfunc, int poprnd)
1776 INIT (ProgCtrl);
1778 ASSIGN (prgfunc);
1779 ASSIGN (poprnd);
1781 return GEN_OPCODE16 ();
1784 INSTR_T
1785 bfin_gen_cactrl (REG_T reg, int a, int op)
1787 INIT (CaCTRL);
1789 ASSIGN_R (reg);
1790 ASSIGN (a);
1791 ASSIGN (op);
1793 return GEN_OPCODE16 ();
1796 INSTR_T
1797 bfin_gen_pushpopmultiple (int dr, int pr, int d, int p, int W)
1799 INIT (PushPopMultiple);
1801 ASSIGN (dr);
1802 ASSIGN (pr);
1803 ASSIGN (d);
1804 ASSIGN (p);
1805 ASSIGN (W);
1807 return GEN_OPCODE16 ();
1810 INSTR_T
1811 bfin_gen_pushpopreg (REG_T reg, int W)
1813 int grp;
1814 INIT (PushPopReg);
1816 ASSIGN_R (reg);
1817 grp = (GROUP (reg));
1818 ASSIGN (grp);
1819 ASSIGN (W);
1821 return GEN_OPCODE16 ();
1824 /* Pseudo Debugging Support. */
1826 INSTR_T
1827 bfin_gen_pseudodbg (int fn, int reg, int grp)
1829 INIT (PseudoDbg);
1831 ASSIGN (fn);
1832 ASSIGN (reg);
1833 ASSIGN (grp);
1835 return GEN_OPCODE16 ();
1838 INSTR_T
1839 bfin_gen_pseudodbg_assert (int dbgop, REG_T regtest, int expected)
1841 INIT (PseudoDbg_Assert);
1843 ASSIGN (dbgop);
1844 ASSIGN_R (regtest);
1845 ASSIGN (expected);
1847 return GEN_OPCODE32 ();
1850 /* Multiple instruction generation. */
1852 INSTR_T
1853 bfin_gen_multi_instr (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2)
1855 INSTR_T walk;
1857 /* If it's a 0, convert into MNOP. */
1858 if (dsp32)
1860 walk = dsp32->next;
1861 SET_MULTI_INSTRUCTION_BIT (dsp32);
1863 else
1865 dsp32 = gencode (0xc803);
1866 walk = gencode (0x1800);
1867 dsp32->next = walk;
1870 if (!dsp16_grp1)
1872 dsp16_grp1 = gencode (0x0000);
1875 if (!dsp16_grp2)
1877 dsp16_grp2 = gencode (0x0000);
1880 walk->next = dsp16_grp1;
1881 dsp16_grp1->next = dsp16_grp2;
1882 dsp16_grp2->next = NULL_CODE;
1884 return dsp32;
1887 INSTR_T
1888 bfin_gen_loop (Expr_Node *expr, REG_T reg, int rop, REG_T preg)
1890 const char *loopsym;
1891 char *lbeginsym, *lendsym;
1892 Expr_Node_Value lbeginval, lendval;
1893 Expr_Node *lbegin, *lend;
1895 loopsym = expr->value.s_value;
1896 lbeginsym = (char *) xmalloc (strlen (loopsym) + strlen ("__BEGIN") + 5);
1897 lendsym = (char *) xmalloc (strlen (loopsym) + strlen ("__END") + 5);
1899 lbeginsym[0] = 0;
1900 lendsym[0] = 0;
1902 strcat (lbeginsym, "L$L$");
1903 strcat (lbeginsym, loopsym);
1904 strcat (lbeginsym, "__BEGIN");
1906 strcat (lendsym, "L$L$");
1907 strcat (lendsym, loopsym);
1908 strcat (lendsym, "__END");
1910 lbeginval.s_value = lbeginsym;
1911 lendval.s_value = lendsym;
1913 lbegin = Expr_Node_Create (Expr_Node_Reloc, lbeginval, NULL, NULL);
1914 lend = Expr_Node_Create (Expr_Node_Reloc, lendval, NULL, NULL);
1915 return bfin_gen_loopsetup(lbegin, reg, rop, lend, preg);
1918 bfd_boolean
1919 bfin_eol_in_insn (char *line)
1921 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1923 char *temp = line;
1925 if (*line != '\n')
1926 return FALSE;
1928 /* A semi-colon followed by a newline is always the end of a line. */
1929 if (line[-1] == ';')
1930 return FALSE;
1932 if (line[-1] == '|')
1933 return TRUE;
1935 /* If the || is on the next line, there might be leading whitespace. */
1936 temp++;
1937 while (*temp == ' ' || *temp == '\t') temp++;
1939 if (*temp == '|')
1940 return TRUE;
1942 return FALSE;
1945 bfd_boolean
1946 bfin_start_label (char *ptr)
1948 ptr--;
1949 while (!ISSPACE (*ptr) && !is_end_of_line[(unsigned char) *ptr])
1950 ptr--;
1952 ptr++;
1953 if (*ptr == '(' || *ptr == '[')
1954 return FALSE;
1956 return TRUE;
1960 bfin_force_relocation (struct fix *fixp)
1962 if (fixp->fx_r_type ==BFD_RELOC_BFIN_16_LOW
1963 || fixp->fx_r_type == BFD_RELOC_BFIN_16_HIGH)
1964 return TRUE;
1966 return generic_force_reloc (fixp);