271709edf4c9146c72f84ae99a4e74e85f6130dd
[deliverable/binutils-gdb.git] / gas / config / tc-bfin.c
1 /* tc-bfin.c -- Assembler for the ADI Blackfin.
2 Copyright 2005, 2006, 2007, 2008
3 Free Software Foundation, Inc.
4
5 This file is part of GAS, the GNU Assembler.
6
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.
11
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.
16
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. */
21
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"
33
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
41 /* Global variables. */
42 struct bfin_insn *insn;
43 int last_insn_size;
44
45 extern struct obstack mempool;
46 FILE *errorf;
47
48 /* Flags to set in the elf header */
49 #define DEFAULT_FLAGS 0
50
51 #ifdef OBJ_FDPIC_ELF
52 # define DEFAULT_FDPIC EF_BFIN_FDPIC
53 #else
54 # define DEFAULT_FDPIC 0
55 #endif
56
57 static flagword bfin_flags = DEFAULT_FLAGS | DEFAULT_FDPIC;
58 static const char *bfin_pic_flag = DEFAULT_FDPIC ? "-mfdpic" : (const char *)0;
59
60 /* Registers list. */
61 struct bfin_reg_entry
62 {
63 const char *name;
64 int number;
65 };
66
67 static const struct bfin_reg_entry bfin_reg_info[] = {
68 {"R0.L", REG_RL0},
69 {"R1.L", REG_RL1},
70 {"R2.L", REG_RL2},
71 {"R3.L", REG_RL3},
72 {"R4.L", REG_RL4},
73 {"R5.L", REG_RL5},
74 {"R6.L", REG_RL6},
75 {"R7.L", REG_RL7},
76 {"R0.H", REG_RH0},
77 {"R1.H", REG_RH1},
78 {"R2.H", REG_RH2},
79 {"R3.H", REG_RH3},
80 {"R4.H", REG_RH4},
81 {"R5.H", REG_RH5},
82 {"R6.H", REG_RH6},
83 {"R7.H", REG_RH7},
84 {"R0", REG_R0},
85 {"R1", REG_R1},
86 {"R2", REG_R2},
87 {"R3", REG_R3},
88 {"R4", REG_R4},
89 {"R5", REG_R5},
90 {"R6", REG_R6},
91 {"R7", REG_R7},
92 {"P0", REG_P0},
93 {"P0.H", REG_P0},
94 {"P0.L", REG_P0},
95 {"P1", REG_P1},
96 {"P1.H", REG_P1},
97 {"P1.L", REG_P1},
98 {"P2", REG_P2},
99 {"P2.H", REG_P2},
100 {"P2.L", REG_P2},
101 {"P3", REG_P3},
102 {"P3.H", REG_P3},
103 {"P3.L", REG_P3},
104 {"P4", REG_P4},
105 {"P4.H", REG_P4},
106 {"P4.L", REG_P4},
107 {"P5", REG_P5},
108 {"P5.H", REG_P5},
109 {"P5.L", REG_P5},
110 {"SP", REG_SP},
111 {"SP.L", REG_SP},
112 {"SP.H", REG_SP},
113 {"FP", REG_FP},
114 {"FP.L", REG_FP},
115 {"FP.H", REG_FP},
116 {"A0x", REG_A0x},
117 {"A1x", REG_A1x},
118 {"A0w", REG_A0w},
119 {"A1w", REG_A1w},
120 {"A0.x", REG_A0x},
121 {"A1.x", REG_A1x},
122 {"A0.w", REG_A0w},
123 {"A1.w", REG_A1w},
124 {"A0", REG_A0},
125 {"A0.L", REG_A0},
126 {"A0.H", REG_A0},
127 {"A1", REG_A1},
128 {"A1.L", REG_A1},
129 {"A1.H", REG_A1},
130 {"I0", REG_I0},
131 {"I0.L", REG_I0},
132 {"I0.H", REG_I0},
133 {"I1", REG_I1},
134 {"I1.L", REG_I1},
135 {"I1.H", REG_I1},
136 {"I2", REG_I2},
137 {"I2.L", REG_I2},
138 {"I2.H", REG_I2},
139 {"I3", REG_I3},
140 {"I3.L", REG_I3},
141 {"I3.H", REG_I3},
142 {"M0", REG_M0},
143 {"M0.H", REG_M0},
144 {"M0.L", REG_M0},
145 {"M1", REG_M1},
146 {"M1.H", REG_M1},
147 {"M1.L", REG_M1},
148 {"M2", REG_M2},
149 {"M2.H", REG_M2},
150 {"M2.L", REG_M2},
151 {"M3", REG_M3},
152 {"M3.H", REG_M3},
153 {"M3.L", REG_M3},
154 {"B0", REG_B0},
155 {"B0.H", REG_B0},
156 {"B0.L", REG_B0},
157 {"B1", REG_B1},
158 {"B1.H", REG_B1},
159 {"B1.L", REG_B1},
160 {"B2", REG_B2},
161 {"B2.H", REG_B2},
162 {"B2.L", REG_B2},
163 {"B3", REG_B3},
164 {"B3.H", REG_B3},
165 {"B3.L", REG_B3},
166 {"L0", REG_L0},
167 {"L0.H", REG_L0},
168 {"L0.L", REG_L0},
169 {"L1", REG_L1},
170 {"L1.H", REG_L1},
171 {"L1.L", REG_L1},
172 {"L2", REG_L2},
173 {"L2.H", REG_L2},
174 {"L2.L", REG_L2},
175 {"L3", REG_L3},
176 {"L3.H", REG_L3},
177 {"L3.L", REG_L3},
178 {"AZ", S_AZ},
179 {"AN", S_AN},
180 {"AC0", S_AC0},
181 {"AC1", S_AC1},
182 {"AV0", S_AV0},
183 {"AV0S", S_AV0S},
184 {"AV1", S_AV1},
185 {"AV1S", S_AV1S},
186 {"AQ", S_AQ},
187 {"V", S_V},
188 {"VS", S_VS},
189 {"sftreset", REG_sftreset},
190 {"omode", REG_omode},
191 {"excause", REG_excause},
192 {"emucause", REG_emucause},
193 {"idle_req", REG_idle_req},
194 {"hwerrcause", REG_hwerrcause},
195 {"CC", REG_CC},
196 {"LC0", REG_LC0},
197 {"LC1", REG_LC1},
198 {"ASTAT", REG_ASTAT},
199 {"RETS", REG_RETS},
200 {"LT0", REG_LT0},
201 {"LB0", REG_LB0},
202 {"LT1", REG_LT1},
203 {"LB1", REG_LB1},
204 {"CYCLES", REG_CYCLES},
205 {"CYCLES2", REG_CYCLES2},
206 {"USP", REG_USP},
207 {"SEQSTAT", REG_SEQSTAT},
208 {"SYSCFG", REG_SYSCFG},
209 {"RETI", REG_RETI},
210 {"RETX", REG_RETX},
211 {"RETN", REG_RETN},
212 {"RETE", REG_RETE},
213 {"EMUDAT", REG_EMUDAT},
214 {0, 0}
215 };
216
217 /* Blackfin specific function to handle FD-PIC pointer initializations. */
218
219 static void
220 bfin_pic_ptr (int nbytes)
221 {
222 expressionS exp;
223 char *p;
224
225 if (nbytes != 4)
226 abort ();
227
228 #ifdef md_flush_pending_output
229 md_flush_pending_output ();
230 #endif
231
232 if (is_it_end_of_statement ())
233 {
234 demand_empty_rest_of_line ();
235 return;
236 }
237
238 #ifdef md_cons_align
239 md_cons_align (nbytes);
240 #endif
241
242 do
243 {
244 bfd_reloc_code_real_type reloc_type = BFD_RELOC_BFIN_FUNCDESC;
245
246 if (strncasecmp (input_line_pointer, "funcdesc(", 9) == 0)
247 {
248 input_line_pointer += 9;
249 expression (&exp);
250 if (*input_line_pointer == ')')
251 input_line_pointer++;
252 else
253 as_bad (_("missing ')'"));
254 }
255 else
256 error ("missing funcdesc in picptr");
257
258 p = frag_more (4);
259 memset (p, 0, 4);
260 fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
261 reloc_type);
262 }
263 while (*input_line_pointer++ == ',');
264
265 input_line_pointer--; /* Put terminator back into stream. */
266 demand_empty_rest_of_line ();
267 }
268
269 static void
270 bfin_s_bss (int ignore ATTRIBUTE_UNUSED)
271 {
272 register int temp;
273
274 temp = get_absolute_expression ();
275 subseg_set (bss_section, (subsegT) temp);
276 demand_empty_rest_of_line ();
277 }
278
279 const pseudo_typeS md_pseudo_table[] = {
280 {"align", s_align_bytes, 0},
281 {"byte2", cons, 2},
282 {"byte4", cons, 4},
283 {"picptr", bfin_pic_ptr, 4},
284 {"code", obj_elf_section, 0},
285 {"db", cons, 1},
286 {"dd", cons, 4},
287 {"dw", cons, 2},
288 {"p", s_ignore, 0},
289 {"pdata", s_ignore, 0},
290 {"var", s_ignore, 0},
291 {"bss", bfin_s_bss, 0},
292 {0, 0, 0}
293 };
294
295 /* Characters that are used to denote comments and line separators. */
296 const char comment_chars[] = "";
297 const char line_comment_chars[] = "#";
298 const char line_separator_chars[] = ";";
299
300 /* Characters that can be used to separate the mantissa from the
301 exponent in floating point numbers. */
302 const char EXP_CHARS[] = "eE";
303
304 /* Characters that mean this number is a floating point constant.
305 As in 0f12.456 or 0d1.2345e12. */
306 const char FLT_CHARS[] = "fFdDxX";
307
308 /* Define bfin-specific command-line options (there are none). */
309 const char *md_shortopts = "";
310
311 #define OPTION_FDPIC (OPTION_MD_BASE)
312 #define OPTION_NOPIC (OPTION_MD_BASE + 1)
313
314 struct option md_longopts[] =
315 {
316 { "mfdpic", no_argument, NULL, OPTION_FDPIC },
317 { "mnopic", no_argument, NULL, OPTION_NOPIC },
318 { "mno-fdpic", no_argument, NULL, OPTION_NOPIC },
319 { NULL, no_argument, NULL, 0 },
320 };
321
322 size_t md_longopts_size = sizeof (md_longopts);
323
324
325 int
326 md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
327 {
328 switch (c)
329 {
330 default:
331 return 0;
332
333 case OPTION_FDPIC:
334 bfin_flags |= EF_BFIN_FDPIC;
335 bfin_pic_flag = "-mfdpic";
336 break;
337
338 case OPTION_NOPIC:
339 bfin_flags &= ~(EF_BFIN_FDPIC);
340 bfin_pic_flag = 0;
341 break;
342 }
343
344 return 1;
345 }
346
347 void
348 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
349 {
350 fprintf (stream, _(" BFIN specific command line options:\n"));
351 }
352
353 /* Perform machine-specific initializations. */
354 void
355 md_begin ()
356 {
357 /* Set the ELF flags if desired. */
358 if (bfin_flags)
359 bfd_set_private_flags (stdoutput, bfin_flags);
360
361 /* Set the default machine type. */
362 if (!bfd_set_arch_mach (stdoutput, bfd_arch_bfin, 0))
363 as_warn (_("Could not set architecture and machine."));
364
365 /* Ensure that lines can begin with '(', for multiple
366 register stack pops. */
367 lex_type ['('] = LEX_BEGIN_NAME;
368
369 #ifdef OBJ_ELF
370 record_alignment (text_section, 2);
371 record_alignment (data_section, 2);
372 record_alignment (bss_section, 2);
373 #endif
374
375 errorf = stderr;
376 obstack_init (&mempool);
377
378 #ifdef DEBUG
379 extern int debug_codeselection;
380 debug_codeselection = 1;
381 #endif
382
383 last_insn_size = 0;
384 }
385
386 /* Perform the main parsing, and assembly of the input here. Also,
387 call the required routines for alignment and fixups here.
388 This is called for every line that contains real assembly code. */
389
390 void
391 md_assemble (char *line)
392 {
393 char *toP = 0;
394 extern char *current_inputline;
395 int size, insn_size;
396 struct bfin_insn *tmp_insn;
397 size_t len;
398 static size_t buffer_len = 0;
399 parse_state state;
400
401 len = strlen (line);
402 if (len + 2 > buffer_len)
403 {
404 if (buffer_len > 0)
405 free (current_inputline);
406 buffer_len = len + 40;
407 current_inputline = xmalloc (buffer_len);
408 }
409 memcpy (current_inputline, line, len);
410 current_inputline[len] = ';';
411 current_inputline[len + 1] = '\0';
412
413 state = parse (current_inputline);
414 if (state == NO_INSN_GENERATED)
415 return;
416
417 for (insn_size = 0, tmp_insn = insn; tmp_insn; tmp_insn = tmp_insn->next)
418 if (!tmp_insn->reloc || !tmp_insn->exp->symbol)
419 insn_size += 2;
420
421 if (insn_size)
422 toP = frag_more (insn_size);
423
424 last_insn_size = insn_size;
425
426 #ifdef DEBUG
427 printf ("INS:");
428 #endif
429 while (insn)
430 {
431 if (insn->reloc && insn->exp->symbol)
432 {
433 char *prev_toP = toP - 2;
434 switch (insn->reloc)
435 {
436 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
437 case BFD_RELOC_24_PCREL:
438 case BFD_RELOC_BFIN_16_LOW:
439 case BFD_RELOC_BFIN_16_HIGH:
440 size = 4;
441 break;
442 default:
443 size = 2;
444 }
445
446 /* Following if condition checks for the arithmetic relocations.
447 If the case then it doesn't required to generate the code.
448 It has been assumed that, their ID will be contiguous. */
449 if ((BFD_ARELOC_BFIN_PUSH <= insn->reloc
450 && BFD_ARELOC_BFIN_COMP >= insn->reloc)
451 || insn->reloc == BFD_RELOC_BFIN_16_IMM)
452 {
453 size = 2;
454 }
455 if (insn->reloc == BFD_ARELOC_BFIN_CONST
456 || insn->reloc == BFD_ARELOC_BFIN_PUSH)
457 size = 4;
458
459 fix_new (frag_now,
460 (prev_toP - frag_now->fr_literal),
461 size, insn->exp->symbol, insn->exp->value,
462 insn->pcrel, insn->reloc);
463 }
464 else
465 {
466 md_number_to_chars (toP, insn->value, 2);
467 toP += 2;
468 }
469
470 #ifdef DEBUG
471 printf (" reloc :");
472 printf (" %02x%02x", ((unsigned char *) &insn->value)[0],
473 ((unsigned char *) &insn->value)[1]);
474 printf ("\n");
475 #endif
476 insn = insn->next;
477 }
478 #ifdef OBJ_ELF
479 dwarf2_emit_insn (insn_size);
480 #endif
481 }
482
483 /* Parse one line of instructions, and generate opcode for it.
484 To parse the line, YACC and LEX are used, because the instruction set
485 syntax doesn't confirm to the AT&T assembly syntax.
486 To call a YACC & LEX generated parser, we must provide the input via
487 a FILE stream, otherwise stdin is used by default. Below the input
488 to the function will be put into a temporary file, then the generated
489 parser uses the temporary file for parsing. */
490
491 static parse_state
492 parse (char *line)
493 {
494 parse_state state;
495 YY_BUFFER_STATE buffstate;
496
497 buffstate = yy_scan_string (line);
498
499 /* our lex requires setting the start state to keyword
500 every line as the first word may be a keyword.
501 Fixes a bug where we could not have keywords as labels. */
502 set_start_state ();
503
504 /* Call yyparse here. */
505 state = yyparse ();
506 if (state == SEMANTIC_ERROR)
507 {
508 as_bad (_("Parse failed."));
509 insn = 0;
510 }
511
512 yy_delete_buffer (buffstate);
513 return state;
514 }
515
516 /* We need to handle various expressions properly.
517 Such as, [SP--] = 34, concerned by md_assemble(). */
518
519 void
520 md_operand (expressionS * expressionP)
521 {
522 if (*input_line_pointer == '[')
523 {
524 as_tsktsk ("We found a '['!");
525 input_line_pointer++;
526 expression (expressionP);
527 }
528 }
529
530 /* Handle undefined symbols. */
531 symbolS *
532 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
533 {
534 return (symbolS *) 0;
535 }
536
537 int
538 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
539 segT segment ATTRIBUTE_UNUSED)
540 {
541 return 0;
542 }
543
544 /* Convert from target byte order to host byte order. */
545
546 static int
547 md_chars_to_number (char *val, int n)
548 {
549 int retval;
550
551 for (retval = 0; n--;)
552 {
553 retval <<= 8;
554 retval |= val[n];
555 }
556 return retval;
557 }
558
559 void
560 md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
561 {
562 char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
563
564 long value = *valueP;
565 long newval;
566
567 switch (fixP->fx_r_type)
568 {
569 case BFD_RELOC_BFIN_GOT:
570 case BFD_RELOC_BFIN_GOT17M4:
571 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
572 fixP->fx_no_overflow = 1;
573 newval = md_chars_to_number (where, 2);
574 newval |= 0x0 & 0x7f;
575 md_number_to_chars (where, newval, 2);
576 break;
577
578 case BFD_RELOC_BFIN_10_PCREL:
579 if (!value)
580 break;
581 if (value < -1024 || value > 1022)
582 as_bad_where (fixP->fx_file, fixP->fx_line,
583 _("pcrel too far BFD_RELOC_BFIN_10"));
584
585 /* 11 bit offset even numbered, so we remove right bit. */
586 value = value >> 1;
587 newval = md_chars_to_number (where, 2);
588 newval |= value & 0x03ff;
589 md_number_to_chars (where, newval, 2);
590 break;
591
592 case BFD_RELOC_BFIN_12_PCREL_JUMP:
593 case BFD_RELOC_BFIN_12_PCREL_JUMP_S:
594 case BFD_RELOC_12_PCREL:
595 if (!value)
596 break;
597
598 if (value < -4096 || value > 4094)
599 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_12"));
600 /* 13 bit offset even numbered, so we remove right bit. */
601 value = value >> 1;
602 newval = md_chars_to_number (where, 2);
603 newval |= value & 0xfff;
604 md_number_to_chars (where, newval, 2);
605 break;
606
607 case BFD_RELOC_BFIN_16_LOW:
608 case BFD_RELOC_BFIN_16_HIGH:
609 fixP->fx_done = FALSE;
610 break;
611
612 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
613 case BFD_RELOC_BFIN_24_PCREL_CALL_X:
614 case BFD_RELOC_24_PCREL:
615 if (!value)
616 break;
617
618 if (value < -16777216 || value > 16777214)
619 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_24"));
620
621 /* 25 bit offset even numbered, so we remove right bit. */
622 value = value >> 1;
623 value++;
624
625 md_number_to_chars (where - 2, value >> 16, 1);
626 md_number_to_chars (where, value, 1);
627 md_number_to_chars (where + 1, value >> 8, 1);
628 break;
629
630 case BFD_RELOC_BFIN_5_PCREL: /* LSETUP (a, b) : "a" */
631 if (!value)
632 break;
633 if (value < 4 || value > 30)
634 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_5"));
635 value = value >> 1;
636 newval = md_chars_to_number (where, 1);
637 newval = (newval & 0xf0) | (value & 0xf);
638 md_number_to_chars (where, newval, 1);
639 break;
640
641 case BFD_RELOC_BFIN_11_PCREL: /* LSETUP (a, b) : "b" */
642 if (!value)
643 break;
644 value += 2;
645 if (value < 4 || value > 2046)
646 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_11_PCREL"));
647 /* 11 bit unsigned even, so we remove right bit. */
648 value = value >> 1;
649 newval = md_chars_to_number (where, 2);
650 newval |= value & 0x03ff;
651 md_number_to_chars (where, newval, 2);
652 break;
653
654 case BFD_RELOC_8:
655 if (value < -0x80 || value >= 0x7f)
656 as_bad_where (fixP->fx_file, fixP->fx_line, _("rel too far BFD_RELOC_8"));
657 md_number_to_chars (where, value, 1);
658 break;
659
660 case BFD_RELOC_BFIN_16_IMM:
661 case BFD_RELOC_16:
662 if (value < -0x8000 || value >= 0x7fff)
663 as_bad_where (fixP->fx_file, fixP->fx_line, _("rel too far BFD_RELOC_16"));
664 md_number_to_chars (where, value, 2);
665 break;
666
667 case BFD_RELOC_32:
668 md_number_to_chars (where, value, 4);
669 break;
670
671 case BFD_RELOC_BFIN_PLTPC:
672 md_number_to_chars (where, value, 2);
673 break;
674
675 case BFD_RELOC_BFIN_FUNCDESC:
676 case BFD_RELOC_VTABLE_INHERIT:
677 case BFD_RELOC_VTABLE_ENTRY:
678 fixP->fx_done = FALSE;
679 break;
680
681 default:
682 if ((BFD_ARELOC_BFIN_PUSH > fixP->fx_r_type) || (BFD_ARELOC_BFIN_COMP < fixP->fx_r_type))
683 {
684 fprintf (stderr, "Relocation %d not handled in gas." " Contact support.\n", fixP->fx_r_type);
685 return;
686 }
687 }
688
689 if (!fixP->fx_addsy)
690 fixP->fx_done = TRUE;
691
692 }
693
694 /* Round up a section size to the appropriate boundary. */
695 valueT
696 md_section_align (segment, size)
697 segT segment;
698 valueT size;
699 {
700 int boundary = bfd_get_section_alignment (stdoutput, segment);
701 return ((size + (1 << boundary) - 1) & (-1 << boundary));
702 }
703
704
705 char *
706 md_atof (int type, char * litP, int * sizeP)
707 {
708 return ieee_md_atof (type, litP, sizeP, FALSE);
709 }
710
711
712 /* If while processing a fixup, a reloc really needs to be created
713 then it is done here. */
714
715 arelent *
716 tc_gen_reloc (seg, fixp)
717 asection *seg ATTRIBUTE_UNUSED;
718 fixS *fixp;
719 {
720 arelent *reloc;
721
722 reloc = (arelent *) xmalloc (sizeof (arelent));
723 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
724 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
725 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
726
727 reloc->addend = fixp->fx_offset;
728 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
729
730 if (reloc->howto == (reloc_howto_type *) NULL)
731 {
732 as_bad_where (fixp->fx_file, fixp->fx_line,
733 /* xgettext:c-format. */
734 _("reloc %d not supported by object file format"),
735 (int) fixp->fx_r_type);
736
737 xfree (reloc);
738
739 return NULL;
740 }
741
742 return reloc;
743 }
744
745 /* The location from which a PC relative jump should be calculated,
746 given a PC relative reloc. */
747
748 long
749 md_pcrel_from_section (fixP, sec)
750 fixS *fixP;
751 segT sec;
752 {
753 if (fixP->fx_addsy != (symbolS *) NULL
754 && (!S_IS_DEFINED (fixP->fx_addsy)
755 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
756 {
757 /* The symbol is undefined (or is defined but not in this section).
758 Let the linker figure it out. */
759 return 0;
760 }
761 return fixP->fx_frag->fr_address + fixP->fx_where;
762 }
763
764 /* Return true if the fix can be handled by GAS, false if it must
765 be passed through to the linker. */
766
767 bfd_boolean
768 bfin_fix_adjustable (fixS *fixP)
769 {
770 switch (fixP->fx_r_type)
771 {
772 /* Adjust_reloc_syms doesn't know about the GOT. */
773 case BFD_RELOC_BFIN_GOT:
774 case BFD_RELOC_BFIN_GOT17M4:
775 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
776 case BFD_RELOC_BFIN_PLTPC:
777 /* We need the symbol name for the VTABLE entries. */
778 case BFD_RELOC_VTABLE_INHERIT:
779 case BFD_RELOC_VTABLE_ENTRY:
780 return 0;
781
782 default:
783 return 1;
784 }
785 }
786
787
788 /* Handle the LOOP_BEGIN and LOOP_END statements.
789 Parse the Loop_Begin/Loop_End and create a label. */
790 void
791 bfin_start_line_hook ()
792 {
793 bfd_boolean maybe_begin = FALSE;
794 bfd_boolean maybe_end = FALSE;
795
796 char *c1, *label_name;
797 symbolS *line_label;
798 char *c = input_line_pointer;
799 int cr_num = 0;
800
801 while (ISSPACE (*c))
802 {
803 if (*c == '\n')
804 cr_num++;
805 c++;
806 }
807
808 /* Look for Loop_Begin or Loop_End statements. */
809
810 if (*c != 'L' && *c != 'l')
811 return;
812
813 c++;
814 if (*c != 'O' && *c != 'o')
815 return;
816
817 c++;
818 if (*c != 'O' && *c != 'o')
819 return;
820
821 c++;
822 if (*c != 'P' && *c != 'p')
823 return;
824
825 c++;
826 if (*c != '_')
827 return;
828
829 c++;
830 if (*c == 'E' || *c == 'e')
831 maybe_end = TRUE;
832 else if (*c == 'B' || *c == 'b')
833 maybe_begin = TRUE;
834 else
835 return;
836
837 if (maybe_end)
838 {
839 c++;
840 if (*c != 'N' && *c != 'n')
841 return;
842
843 c++;
844 if (*c != 'D' && *c != 'd')
845 return;
846 }
847
848 if (maybe_begin)
849 {
850 c++;
851 if (*c != 'E' && *c != 'e')
852 return;
853
854 c++;
855 if (*c != 'G' && *c != 'g')
856 return;
857
858 c++;
859 if (*c != 'I' && *c != 'i')
860 return;
861
862 c++;
863 if (*c != 'N' && *c != 'n')
864 return;
865 }
866
867 c++;
868 while (ISSPACE (*c)) c++;
869 c1 = c;
870 while (ISALPHA (*c) || ISDIGIT (*c) || *c == '_') c++;
871
872 if (input_line_pointer[-1] == '\n')
873 bump_line_counters ();
874
875 while (cr_num--)
876 bump_line_counters ();
877
878 input_line_pointer = c;
879 if (maybe_end)
880 {
881 label_name = (char *) xmalloc ((c - c1) + strlen ("__END") + 5);
882 label_name[0] = 0;
883 strcat (label_name, "L$L$");
884 strncat (label_name, c1, c-c1);
885 strcat (label_name, "__END");
886 }
887 else /* maybe_begin. */
888 {
889 label_name = (char *) xmalloc ((c - c1) + strlen ("__BEGIN") + 5);
890 label_name[0] = 0;
891 strcat (label_name, "L$L$");
892 strncat (label_name, c1, c-c1);
893 strcat (label_name, "__BEGIN");
894 }
895
896 line_label = colon (label_name);
897
898 /* Loop_End follows the last instruction in the loop.
899 Adjust label address. */
900 if (maybe_end)
901 ((struct local_symbol *) line_label)->lsy_value -= last_insn_size;
902 }
903
904 /* Special extra functions that help bfin-parse.y perform its job. */
905
906 struct obstack mempool;
907
908 INSTR_T
909 conscode (INSTR_T head, INSTR_T tail)
910 {
911 if (!head)
912 return tail;
913 head->next = tail;
914 return head;
915 }
916
917 INSTR_T
918 conctcode (INSTR_T head, INSTR_T tail)
919 {
920 INSTR_T temp = (head);
921 if (!head)
922 return tail;
923 while (temp->next)
924 temp = temp->next;
925 temp->next = tail;
926
927 return head;
928 }
929
930 INSTR_T
931 note_reloc (INSTR_T code, Expr_Node * symbol, int reloc, int pcrel)
932 {
933 /* Assert that the symbol is not an operator. */
934 gas_assert (symbol->type == Expr_Node_Reloc);
935
936 return note_reloc1 (code, symbol->value.s_value, reloc, pcrel);
937
938 }
939
940 INSTR_T
941 note_reloc1 (INSTR_T code, const char *symbol, int reloc, int pcrel)
942 {
943 code->reloc = reloc;
944 code->exp = mkexpr (0, symbol_find_or_make (symbol));
945 code->pcrel = pcrel;
946 return code;
947 }
948
949 INSTR_T
950 note_reloc2 (INSTR_T code, const char *symbol, int reloc, int value, int pcrel)
951 {
952 code->reloc = reloc;
953 code->exp = mkexpr (value, symbol_find_or_make (symbol));
954 code->pcrel = pcrel;
955 return code;
956 }
957
958 INSTR_T
959 gencode (unsigned long x)
960 {
961 INSTR_T cell = obstack_alloc (&mempool, sizeof (struct bfin_insn));
962 memset (cell, 0, sizeof (struct bfin_insn));
963 cell->value = (x);
964 return cell;
965 }
966
967 int reloc;
968 int ninsns;
969 int count_insns;
970
971 static void *
972 allocate (int n)
973 {
974 return obstack_alloc (&mempool, n);
975 }
976
977 Expr_Node *
978 Expr_Node_Create (Expr_Node_Type type,
979 Expr_Node_Value value,
980 Expr_Node *Left_Child,
981 Expr_Node *Right_Child)
982 {
983
984
985 Expr_Node *node = (Expr_Node *) allocate (sizeof (Expr_Node));
986 node->type = type;
987 node->value = value;
988 node->Left_Child = Left_Child;
989 node->Right_Child = Right_Child;
990 return node;
991 }
992
993 static const char *con = ".__constant";
994 static const char *op = ".__operator";
995 static INSTR_T Expr_Node_Gen_Reloc_R (Expr_Node * head);
996 INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc);
997
998 INSTR_T
999 Expr_Node_Gen_Reloc (Expr_Node * head, int parent_reloc)
1000 {
1001 /* Top level reloction expression generator VDSP style.
1002 If the relocation is just by itself, generate one item
1003 else generate this convoluted expression. */
1004
1005 INSTR_T note = NULL_CODE;
1006 INSTR_T note1 = NULL_CODE;
1007 int pcrel = 1; /* Is the parent reloc pcrelative?
1008 This calculation here and HOWTO should match. */
1009
1010 if (parent_reloc)
1011 {
1012 /* If it's 32 bit quantity then 16bit code needs to be added. */
1013 int value = 0;
1014
1015 if (head->type == Expr_Node_Constant)
1016 {
1017 /* If note1 is not null code, we have to generate a right
1018 aligned value for the constant. Otherwise the reloc is
1019 a part of the basic command and the yacc file
1020 generates this. */
1021 value = head->value.i_value;
1022 }
1023 switch (parent_reloc)
1024 {
1025 /* Some relocations will need to allocate extra words. */
1026 case BFD_RELOC_BFIN_16_IMM:
1027 case BFD_RELOC_BFIN_16_LOW:
1028 case BFD_RELOC_BFIN_16_HIGH:
1029 note1 = conscode (gencode (value), NULL_CODE);
1030 pcrel = 0;
1031 break;
1032 case BFD_RELOC_BFIN_PLTPC:
1033 note1 = conscode (gencode (value), NULL_CODE);
1034 pcrel = 0;
1035 break;
1036 case BFD_RELOC_16:
1037 case BFD_RELOC_BFIN_GOT:
1038 case BFD_RELOC_BFIN_GOT17M4:
1039 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4:
1040 note1 = conscode (gencode (value), NULL_CODE);
1041 pcrel = 0;
1042 break;
1043 case BFD_RELOC_24_PCREL:
1044 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
1045 case BFD_RELOC_BFIN_24_PCREL_CALL_X:
1046 /* These offsets are even numbered pcrel. */
1047 note1 = conscode (gencode (value >> 1), NULL_CODE);
1048 break;
1049 default:
1050 note1 = NULL_CODE;
1051 }
1052 }
1053 if (head->type == Expr_Node_Constant)
1054 note = note1;
1055 else if (head->type == Expr_Node_Reloc)
1056 {
1057 note = note_reloc1 (gencode (0), head->value.s_value, parent_reloc, pcrel);
1058 if (note1 != NULL_CODE)
1059 note = conscode (note1, note);
1060 }
1061 else if (head->type == Expr_Node_Binop
1062 && (head->value.op_value == Expr_Op_Type_Add
1063 || head->value.op_value == Expr_Op_Type_Sub)
1064 && head->Left_Child->type == Expr_Node_Reloc
1065 && head->Right_Child->type == Expr_Node_Constant)
1066 {
1067 int val = head->Right_Child->value.i_value;
1068 if (head->value.op_value == Expr_Op_Type_Sub)
1069 val = -val;
1070 note = conscode (note_reloc2 (gencode (0), head->Left_Child->value.s_value,
1071 parent_reloc, val, 0),
1072 NULL_CODE);
1073 if (note1 != NULL_CODE)
1074 note = conscode (note1, note);
1075 }
1076 else
1077 {
1078 /* Call the recursive function. */
1079 note = note_reloc1 (gencode (0), op, parent_reloc, pcrel);
1080 if (note1 != NULL_CODE)
1081 note = conscode (note1, note);
1082 note = conctcode (Expr_Node_Gen_Reloc_R (head), note);
1083 }
1084 return note;
1085 }
1086
1087 static INSTR_T
1088 Expr_Node_Gen_Reloc_R (Expr_Node * head)
1089 {
1090
1091 INSTR_T note = 0;
1092 INSTR_T note1 = 0;
1093
1094 switch (head->type)
1095 {
1096 case Expr_Node_Constant:
1097 note = conscode (note_reloc2 (gencode (0), con, BFD_ARELOC_BFIN_CONST, head->value.i_value, 0), NULL_CODE);
1098 break;
1099 case Expr_Node_Reloc:
1100 note = conscode (note_reloc (gencode (0), head, BFD_ARELOC_BFIN_PUSH, 0), NULL_CODE);
1101 break;
1102 case Expr_Node_Binop:
1103 note1 = conctcode (Expr_Node_Gen_Reloc_R (head->Left_Child), Expr_Node_Gen_Reloc_R (head->Right_Child));
1104 switch (head->value.op_value)
1105 {
1106 case Expr_Op_Type_Add:
1107 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_ADD, 0), NULL_CODE));
1108 break;
1109 case Expr_Op_Type_Sub:
1110 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_SUB, 0), NULL_CODE));
1111 break;
1112 case Expr_Op_Type_Mult:
1113 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MULT, 0), NULL_CODE));
1114 break;
1115 case Expr_Op_Type_Div:
1116 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_DIV, 0), NULL_CODE));
1117 break;
1118 case Expr_Op_Type_Mod:
1119 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MOD, 0), NULL_CODE));
1120 break;
1121 case Expr_Op_Type_Lshift:
1122 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LSHIFT, 0), NULL_CODE));
1123 break;
1124 case Expr_Op_Type_Rshift:
1125 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_RSHIFT, 0), NULL_CODE));
1126 break;
1127 case Expr_Op_Type_BAND:
1128 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_AND, 0), NULL_CODE));
1129 break;
1130 case Expr_Op_Type_BOR:
1131 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_OR, 0), NULL_CODE));
1132 break;
1133 case Expr_Op_Type_BXOR:
1134 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_XOR, 0), NULL_CODE));
1135 break;
1136 case Expr_Op_Type_LAND:
1137 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LAND, 0), NULL_CODE));
1138 break;
1139 case Expr_Op_Type_LOR:
1140 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LOR, 0), NULL_CODE));
1141 break;
1142 default:
1143 fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
1144
1145
1146 }
1147 break;
1148 case Expr_Node_Unop:
1149 note1 = conscode (Expr_Node_Gen_Reloc_R (head->Left_Child), NULL_CODE);
1150 switch (head->value.op_value)
1151 {
1152 case Expr_Op_Type_NEG:
1153 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_NEG, 0), NULL_CODE));
1154 break;
1155 case Expr_Op_Type_COMP:
1156 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_COMP, 0), NULL_CODE));
1157 break;
1158 default:
1159 fprintf (stderr, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__, __LINE__);
1160 }
1161 break;
1162 default:
1163 fprintf (stderr, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__, __LINE__);
1164 }
1165 return note;
1166 }
1167
1168
1169 /* Blackfin opcode generation. */
1170
1171 /* These functions are called by the generated parser
1172 (from bfin-parse.y), the register type classification
1173 happens in bfin-lex.l. */
1174
1175 #include "bfin-aux.h"
1176 #include "opcode/bfin.h"
1177
1178 #define INIT(t) t c_code = init_##t
1179 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1180 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1181
1182 #define HI(x) ((x >> 16) & 0xffff)
1183 #define LO(x) ((x ) & 0xffff)
1184
1185 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1186
1187 #define GEN_OPCODE32() \
1188 conscode (gencode (HI (c_code.opcode)), \
1189 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1190
1191 #define GEN_OPCODE16() \
1192 conscode (gencode (c_code.opcode), NULL_CODE)
1193
1194
1195 /* 32 BIT INSTRUCTIONS. */
1196
1197
1198 /* DSP32 instruction generation. */
1199
1200 INSTR_T
1201 bfin_gen_dsp32mac (int op1, int MM, int mmod, int w1, int P,
1202 int h01, int h11, int h00, int h10, int op0,
1203 REG_T dst, REG_T src0, REG_T src1, int w0)
1204 {
1205 INIT (DSP32Mac);
1206
1207 ASSIGN (op0);
1208 ASSIGN (op1);
1209 ASSIGN (MM);
1210 ASSIGN (mmod);
1211 ASSIGN (w0);
1212 ASSIGN (w1);
1213 ASSIGN (h01);
1214 ASSIGN (h11);
1215 ASSIGN (h00);
1216 ASSIGN (h10);
1217 ASSIGN (P);
1218
1219 /* If we have full reg assignments, mask out LSB to encode
1220 single or simultaneous even/odd register moves. */
1221 if (P)
1222 {
1223 dst->regno &= 0x06;
1224 }
1225
1226 ASSIGN_R (dst);
1227 ASSIGN_R (src0);
1228 ASSIGN_R (src1);
1229
1230 return GEN_OPCODE32 ();
1231 }
1232
1233 INSTR_T
1234 bfin_gen_dsp32mult (int op1, int MM, int mmod, int w1, int P,
1235 int h01, int h11, int h00, int h10, int op0,
1236 REG_T dst, REG_T src0, REG_T src1, int w0)
1237 {
1238 INIT (DSP32Mult);
1239
1240 ASSIGN (op0);
1241 ASSIGN (op1);
1242 ASSIGN (MM);
1243 ASSIGN (mmod);
1244 ASSIGN (w0);
1245 ASSIGN (w1);
1246 ASSIGN (h01);
1247 ASSIGN (h11);
1248 ASSIGN (h00);
1249 ASSIGN (h10);
1250 ASSIGN (P);
1251
1252 if (P)
1253 {
1254 dst->regno &= 0x06;
1255 }
1256
1257 ASSIGN_R (dst);
1258 ASSIGN_R (src0);
1259 ASSIGN_R (src1);
1260
1261 return GEN_OPCODE32 ();
1262 }
1263
1264 INSTR_T
1265 bfin_gen_dsp32alu (int HL, int aopcde, int aop, int s, int x,
1266 REG_T dst0, REG_T dst1, REG_T src0, REG_T src1)
1267 {
1268 INIT (DSP32Alu);
1269
1270 ASSIGN (HL);
1271 ASSIGN (aopcde);
1272 ASSIGN (aop);
1273 ASSIGN (s);
1274 ASSIGN (x);
1275 ASSIGN_R (dst0);
1276 ASSIGN_R (dst1);
1277 ASSIGN_R (src0);
1278 ASSIGN_R (src1);
1279
1280 return GEN_OPCODE32 ();
1281 }
1282
1283 INSTR_T
1284 bfin_gen_dsp32shift (int sopcde, REG_T dst0, REG_T src0,
1285 REG_T src1, int sop, int HLs)
1286 {
1287 INIT (DSP32Shift);
1288
1289 ASSIGN (sopcde);
1290 ASSIGN (sop);
1291 ASSIGN (HLs);
1292
1293 ASSIGN_R (dst0);
1294 ASSIGN_R (src0);
1295 ASSIGN_R (src1);
1296
1297 return GEN_OPCODE32 ();
1298 }
1299
1300 INSTR_T
1301 bfin_gen_dsp32shiftimm (int sopcde, REG_T dst0, int immag,
1302 REG_T src1, int sop, int HLs)
1303 {
1304 INIT (DSP32ShiftImm);
1305
1306 ASSIGN (sopcde);
1307 ASSIGN (sop);
1308 ASSIGN (HLs);
1309
1310 ASSIGN_R (dst0);
1311 ASSIGN (immag);
1312 ASSIGN_R (src1);
1313
1314 return GEN_OPCODE32 ();
1315 }
1316
1317 /* LOOP SETUP. */
1318
1319 INSTR_T
1320 bfin_gen_loopsetup (Expr_Node * psoffset, REG_T c, int rop,
1321 Expr_Node * peoffset, REG_T reg)
1322 {
1323 int soffset, eoffset;
1324 INIT (LoopSetup);
1325
1326 soffset = (EXPR_VALUE (psoffset) >> 1);
1327 ASSIGN (soffset);
1328 eoffset = (EXPR_VALUE (peoffset) >> 1);
1329 ASSIGN (eoffset);
1330 ASSIGN (rop);
1331 ASSIGN_R (c);
1332 ASSIGN_R (reg);
1333
1334 return
1335 conscode (gencode (HI (c_code.opcode)),
1336 conctcode (Expr_Node_Gen_Reloc (psoffset, BFD_RELOC_BFIN_5_PCREL),
1337 conctcode (gencode (LO (c_code.opcode)), Expr_Node_Gen_Reloc (peoffset, BFD_RELOC_BFIN_11_PCREL))));
1338
1339 }
1340
1341 /* Call, Link. */
1342
1343 INSTR_T
1344 bfin_gen_calla (Expr_Node * addr, int S)
1345 {
1346 int val;
1347 int high_val;
1348 int reloc = 0;
1349 INIT (CALLa);
1350
1351 switch(S){
1352 case 0 : reloc = BFD_RELOC_BFIN_24_PCREL_JUMP_L; break;
1353 case 1 : reloc = BFD_RELOC_24_PCREL; break;
1354 case 2 : reloc = BFD_RELOC_BFIN_PLTPC; break;
1355 default : break;
1356 }
1357
1358 ASSIGN (S);
1359
1360 val = EXPR_VALUE (addr) >> 1;
1361 high_val = val >> 16;
1362
1363 return conscode (gencode (HI (c_code.opcode) | (high_val & 0xff)),
1364 Expr_Node_Gen_Reloc (addr, reloc));
1365 }
1366
1367 INSTR_T
1368 bfin_gen_linkage (int R, int framesize)
1369 {
1370 INIT (Linkage);
1371
1372 ASSIGN (R);
1373 ASSIGN (framesize);
1374
1375 return GEN_OPCODE32 ();
1376 }
1377
1378
1379 /* Load and Store. */
1380
1381 INSTR_T
1382 bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int reloc)
1383 {
1384 int grp, hword;
1385 unsigned val = EXPR_VALUE (phword);
1386 INIT (LDIMMhalf);
1387
1388 ASSIGN (H);
1389 ASSIGN (S);
1390 ASSIGN (Z);
1391
1392 ASSIGN_R (reg);
1393 grp = (GROUP (reg));
1394 ASSIGN (grp);
1395 if (reloc == 2)
1396 {
1397 return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, BFD_RELOC_BFIN_16_IMM));
1398 }
1399 else if (reloc == 1)
1400 {
1401 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));
1402 }
1403 else
1404 {
1405 hword = val;
1406 ASSIGN (hword);
1407 }
1408 return GEN_OPCODE32 ();
1409 }
1410
1411 INSTR_T
1412 bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset)
1413 {
1414 INIT (LDSTidxI);
1415
1416 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1417 {
1418 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1419 return 0;
1420 }
1421
1422 ASSIGN_R (ptr);
1423 ASSIGN_R (reg);
1424 ASSIGN (W);
1425 ASSIGN (sz);
1426
1427 ASSIGN (Z);
1428
1429 if (poffset->type != Expr_Node_Constant)
1430 {
1431 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1432 /* distinguish between R0 = [P5 + symbol@GOT] and
1433 P5 = [P5 + _current_shared_library_p5_offset_]
1434 */
1435 if (poffset->type == Expr_Node_Reloc
1436 && !strcmp (poffset->value.s_value,
1437 "_current_shared_library_p5_offset_"))
1438 {
1439 return conscode (gencode (HI (c_code.opcode)),
1440 Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16));
1441 }
1442 else if (poffset->type != Expr_Node_GOT_Reloc)
1443 abort ();
1444
1445 return conscode (gencode (HI (c_code.opcode)),
1446 Expr_Node_Gen_Reloc(poffset->Left_Child,
1447 poffset->value.i_value));
1448 }
1449 else
1450 {
1451 int value, offset;
1452 switch (sz)
1453 { /* load/store access size */
1454 case 0: /* 32 bit */
1455 value = EXPR_VALUE (poffset) >> 2;
1456 break;
1457 case 1: /* 16 bit */
1458 value = EXPR_VALUE (poffset) >> 1;
1459 break;
1460 case 2: /* 8 bit */
1461 value = EXPR_VALUE (poffset);
1462 break;
1463 default:
1464 abort ();
1465 }
1466
1467 offset = (value & 0xffff);
1468 ASSIGN (offset);
1469 return GEN_OPCODE32 ();
1470 }
1471 }
1472
1473
1474 INSTR_T
1475 bfin_gen_ldst (REG_T ptr, REG_T reg, int aop, int sz, int Z, int W)
1476 {
1477 INIT (LDST);
1478
1479 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1480 {
1481 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1482 return 0;
1483 }
1484
1485 ASSIGN_R (ptr);
1486 ASSIGN_R (reg);
1487 ASSIGN (aop);
1488 ASSIGN (sz);
1489 ASSIGN (Z);
1490 ASSIGN (W);
1491
1492 return GEN_OPCODE16 ();
1493 }
1494
1495 INSTR_T
1496 bfin_gen_ldstii (REG_T ptr, REG_T reg, Expr_Node * poffset, int W, int op)
1497 {
1498 int offset;
1499 int value = 0;
1500 INIT (LDSTii);
1501
1502
1503 if (!IS_PREG (*ptr))
1504 {
1505 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1506 return 0;
1507 }
1508
1509 switch (op)
1510 {
1511 case 1:
1512 case 2:
1513 value = EXPR_VALUE (poffset) >> 1;
1514 break;
1515 case 0:
1516 case 3:
1517 value = EXPR_VALUE (poffset) >> 2;
1518 break;
1519 }
1520
1521 ASSIGN_R (ptr);
1522 ASSIGN_R (reg);
1523
1524 offset = value;
1525 ASSIGN (offset);
1526 ASSIGN (W);
1527 ASSIGN (op);
1528
1529 return GEN_OPCODE16 ();
1530 }
1531
1532 INSTR_T
1533 bfin_gen_ldstiifp (REG_T sreg, Expr_Node * poffset, int W)
1534 {
1535 /* Set bit 4 if it's a Preg. */
1536 int reg = (sreg->regno & CODE_MASK) | (IS_PREG (*sreg) ? 0x8 : 0x0);
1537 int offset = ((~(EXPR_VALUE (poffset) >> 2)) & 0x1f) + 1;
1538 INIT (LDSTiiFP);
1539 ASSIGN (reg);
1540 ASSIGN (offset);
1541 ASSIGN (W);
1542
1543 return GEN_OPCODE16 ();
1544 }
1545
1546 INSTR_T
1547 bfin_gen_ldstpmod (REG_T ptr, REG_T reg, int aop, int W, REG_T idx)
1548 {
1549 INIT (LDSTpmod);
1550
1551 ASSIGN_R (ptr);
1552 ASSIGN_R (reg);
1553 ASSIGN (aop);
1554 ASSIGN (W);
1555 ASSIGN_R (idx);
1556
1557 return GEN_OPCODE16 ();
1558 }
1559
1560 INSTR_T
1561 bfin_gen_dspldst (REG_T i, REG_T reg, int aop, int W, int m)
1562 {
1563 INIT (DspLDST);
1564
1565 ASSIGN_R (i);
1566 ASSIGN_R (reg);
1567 ASSIGN (aop);
1568 ASSIGN (W);
1569 ASSIGN (m);
1570
1571 return GEN_OPCODE16 ();
1572 }
1573
1574 INSTR_T
1575 bfin_gen_logi2op (int opc, int src, int dst)
1576 {
1577 INIT (LOGI2op);
1578
1579 ASSIGN (opc);
1580 ASSIGN (src);
1581 ASSIGN (dst);
1582
1583 return GEN_OPCODE16 ();
1584 }
1585
1586 INSTR_T
1587 bfin_gen_brcc (int T, int B, Expr_Node * poffset)
1588 {
1589 int offset;
1590 INIT (BRCC);
1591
1592 ASSIGN (T);
1593 ASSIGN (B);
1594 offset = ((EXPR_VALUE (poffset) >> 1));
1595 ASSIGN (offset);
1596 return conscode (gencode (c_code.opcode), Expr_Node_Gen_Reloc (poffset, BFD_RELOC_BFIN_10_PCREL));
1597 }
1598
1599 INSTR_T
1600 bfin_gen_ujump (Expr_Node * poffset)
1601 {
1602 int offset;
1603 INIT (UJump);
1604
1605 offset = ((EXPR_VALUE (poffset) >> 1));
1606 ASSIGN (offset);
1607
1608 return conscode (gencode (c_code.opcode),
1609 Expr_Node_Gen_Reloc (
1610 poffset, BFD_RELOC_BFIN_12_PCREL_JUMP_S));
1611 }
1612
1613 INSTR_T
1614 bfin_gen_alu2op (REG_T dst, REG_T src, int opc)
1615 {
1616 INIT (ALU2op);
1617
1618 ASSIGN_R (dst);
1619 ASSIGN_R (src);
1620 ASSIGN (opc);
1621
1622 return GEN_OPCODE16 ();
1623 }
1624
1625 INSTR_T
1626 bfin_gen_compi2opd (REG_T dst, int src, int op)
1627 {
1628 INIT (COMPI2opD);
1629
1630 ASSIGN_R (dst);
1631 ASSIGN (src);
1632 ASSIGN (op);
1633
1634 return GEN_OPCODE16 ();
1635 }
1636
1637 INSTR_T
1638 bfin_gen_compi2opp (REG_T dst, int src, int op)
1639 {
1640 INIT (COMPI2opP);
1641
1642 ASSIGN_R (dst);
1643 ASSIGN (src);
1644 ASSIGN (op);
1645
1646 return GEN_OPCODE16 ();
1647 }
1648
1649 INSTR_T
1650 bfin_gen_dagmodik (REG_T i, int op)
1651 {
1652 INIT (DagMODik);
1653
1654 ASSIGN_R (i);
1655 ASSIGN (op);
1656
1657 return GEN_OPCODE16 ();
1658 }
1659
1660 INSTR_T
1661 bfin_gen_dagmodim (REG_T i, REG_T m, int op, int br)
1662 {
1663 INIT (DagMODim);
1664
1665 ASSIGN_R (i);
1666 ASSIGN_R (m);
1667 ASSIGN (op);
1668 ASSIGN (br);
1669
1670 return GEN_OPCODE16 ();
1671 }
1672
1673 INSTR_T
1674 bfin_gen_ptr2op (REG_T dst, REG_T src, int opc)
1675 {
1676 INIT (PTR2op);
1677
1678 ASSIGN_R (dst);
1679 ASSIGN_R (src);
1680 ASSIGN (opc);
1681
1682 return GEN_OPCODE16 ();
1683 }
1684
1685 INSTR_T
1686 bfin_gen_comp3op (REG_T src0, REG_T src1, REG_T dst, int opc)
1687 {
1688 INIT (COMP3op);
1689
1690 ASSIGN_R (src0);
1691 ASSIGN_R (src1);
1692 ASSIGN_R (dst);
1693 ASSIGN (opc);
1694
1695 return GEN_OPCODE16 ();
1696 }
1697
1698 INSTR_T
1699 bfin_gen_ccflag (REG_T x, int y, int opc, int I, int G)
1700 {
1701 INIT (CCflag);
1702
1703 ASSIGN_R (x);
1704 ASSIGN (y);
1705 ASSIGN (opc);
1706 ASSIGN (I);
1707 ASSIGN (G);
1708
1709 return GEN_OPCODE16 ();
1710 }
1711
1712 INSTR_T
1713 bfin_gen_ccmv (REG_T src, REG_T dst, int T)
1714 {
1715 int s, d;
1716 INIT (CCmv);
1717
1718 ASSIGN_R (src);
1719 ASSIGN_R (dst);
1720 s = (GROUP (src));
1721 ASSIGN (s);
1722 d = (GROUP (dst));
1723 ASSIGN (d);
1724 ASSIGN (T);
1725
1726 return GEN_OPCODE16 ();
1727 }
1728
1729 INSTR_T
1730 bfin_gen_cc2stat (int cbit, int op, int D)
1731 {
1732 INIT (CC2stat);
1733
1734 ASSIGN (cbit);
1735 ASSIGN (op);
1736 ASSIGN (D);
1737
1738 return GEN_OPCODE16 ();
1739 }
1740
1741 INSTR_T
1742 bfin_gen_regmv (REG_T src, REG_T dst)
1743 {
1744 int gs, gd;
1745 INIT (RegMv);
1746
1747 ASSIGN_R (src);
1748 ASSIGN_R (dst);
1749
1750 gs = (GROUP (src));
1751 ASSIGN (gs);
1752 gd = (GROUP (dst));
1753 ASSIGN (gd);
1754
1755 return GEN_OPCODE16 ();
1756 }
1757
1758 INSTR_T
1759 bfin_gen_cc2dreg (int op, REG_T reg)
1760 {
1761 INIT (CC2dreg);
1762
1763 ASSIGN (op);
1764 ASSIGN_R (reg);
1765
1766 return GEN_OPCODE16 ();
1767 }
1768
1769 INSTR_T
1770 bfin_gen_progctrl (int prgfunc, int poprnd)
1771 {
1772 INIT (ProgCtrl);
1773
1774 ASSIGN (prgfunc);
1775 ASSIGN (poprnd);
1776
1777 return GEN_OPCODE16 ();
1778 }
1779
1780 INSTR_T
1781 bfin_gen_cactrl (REG_T reg, int a, int op)
1782 {
1783 INIT (CaCTRL);
1784
1785 ASSIGN_R (reg);
1786 ASSIGN (a);
1787 ASSIGN (op);
1788
1789 return GEN_OPCODE16 ();
1790 }
1791
1792 INSTR_T
1793 bfin_gen_pushpopmultiple (int dr, int pr, int d, int p, int W)
1794 {
1795 INIT (PushPopMultiple);
1796
1797 ASSIGN (dr);
1798 ASSIGN (pr);
1799 ASSIGN (d);
1800 ASSIGN (p);
1801 ASSIGN (W);
1802
1803 return GEN_OPCODE16 ();
1804 }
1805
1806 INSTR_T
1807 bfin_gen_pushpopreg (REG_T reg, int W)
1808 {
1809 int grp;
1810 INIT (PushPopReg);
1811
1812 ASSIGN_R (reg);
1813 grp = (GROUP (reg));
1814 ASSIGN (grp);
1815 ASSIGN (W);
1816
1817 return GEN_OPCODE16 ();
1818 }
1819
1820 /* Pseudo Debugging Support. */
1821
1822 INSTR_T
1823 bfin_gen_pseudodbg (int fn, int reg, int grp)
1824 {
1825 INIT (PseudoDbg);
1826
1827 ASSIGN (fn);
1828 ASSIGN (reg);
1829 ASSIGN (grp);
1830
1831 return GEN_OPCODE16 ();
1832 }
1833
1834 INSTR_T
1835 bfin_gen_pseudodbg_assert (int dbgop, REG_T regtest, int expected)
1836 {
1837 INIT (PseudoDbg_Assert);
1838
1839 ASSIGN (dbgop);
1840 ASSIGN_R (regtest);
1841 ASSIGN (expected);
1842
1843 return GEN_OPCODE32 ();
1844 }
1845
1846 /* Multiple instruction generation. */
1847
1848 INSTR_T
1849 bfin_gen_multi_instr (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2)
1850 {
1851 INSTR_T walk;
1852
1853 /* If it's a 0, convert into MNOP. */
1854 if (dsp32)
1855 {
1856 walk = dsp32->next;
1857 SET_MULTI_INSTRUCTION_BIT (dsp32);
1858 }
1859 else
1860 {
1861 dsp32 = gencode (0xc803);
1862 walk = gencode (0x1800);
1863 dsp32->next = walk;
1864 }
1865
1866 if (!dsp16_grp1)
1867 {
1868 dsp16_grp1 = gencode (0x0000);
1869 }
1870
1871 if (!dsp16_grp2)
1872 {
1873 dsp16_grp2 = gencode (0x0000);
1874 }
1875
1876 walk->next = dsp16_grp1;
1877 dsp16_grp1->next = dsp16_grp2;
1878 dsp16_grp2->next = NULL_CODE;
1879
1880 return dsp32;
1881 }
1882
1883 INSTR_T
1884 bfin_gen_loop (Expr_Node *expr, REG_T reg, int rop, REG_T preg)
1885 {
1886 const char *loopsym;
1887 char *lbeginsym, *lendsym;
1888 Expr_Node_Value lbeginval, lendval;
1889 Expr_Node *lbegin, *lend;
1890
1891 loopsym = expr->value.s_value;
1892 lbeginsym = (char *) xmalloc (strlen (loopsym) + strlen ("__BEGIN") + 5);
1893 lendsym = (char *) xmalloc (strlen (loopsym) + strlen ("__END") + 5);
1894
1895 lbeginsym[0] = 0;
1896 lendsym[0] = 0;
1897
1898 strcat (lbeginsym, "L$L$");
1899 strcat (lbeginsym, loopsym);
1900 strcat (lbeginsym, "__BEGIN");
1901
1902 strcat (lendsym, "L$L$");
1903 strcat (lendsym, loopsym);
1904 strcat (lendsym, "__END");
1905
1906 lbeginval.s_value = lbeginsym;
1907 lendval.s_value = lendsym;
1908
1909 lbegin = Expr_Node_Create (Expr_Node_Reloc, lbeginval, NULL, NULL);
1910 lend = Expr_Node_Create (Expr_Node_Reloc, lendval, NULL, NULL);
1911
1912 symbol_remove (symbol_find (loopsym), &symbol_rootP, &symbol_lastP);
1913
1914 return bfin_gen_loopsetup(lbegin, reg, rop, lend, preg);
1915 }
1916
1917 bfd_boolean
1918 bfin_eol_in_insn (char *line)
1919 {
1920 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1921
1922 char *temp = line;
1923
1924 if (*line != '\n')
1925 return FALSE;
1926
1927 /* A semi-colon followed by a newline is always the end of a line. */
1928 if (line[-1] == ';')
1929 return FALSE;
1930
1931 if (line[-1] == '|')
1932 return TRUE;
1933
1934 /* If the || is on the next line, there might be leading whitespace. */
1935 temp++;
1936 while (*temp == ' ' || *temp == '\t') temp++;
1937
1938 if (*temp == '|')
1939 return TRUE;
1940
1941 return FALSE;
1942 }
1943
1944 bfd_boolean
1945 bfin_start_label (char *ptr)
1946 {
1947 ptr--;
1948 while (!ISSPACE (*ptr) && !is_end_of_line[(unsigned char) *ptr])
1949 ptr--;
1950
1951 ptr++;
1952 if (*ptr == '(' || *ptr == '[')
1953 return FALSE;
1954
1955 return TRUE;
1956 }
1957
1958 int
1959 bfin_force_relocation (struct fix *fixp)
1960 {
1961 if (fixp->fx_r_type ==BFD_RELOC_BFIN_16_LOW
1962 || fixp->fx_r_type == BFD_RELOC_BFIN_16_HIGH)
1963 return TRUE;
1964
1965 return generic_force_reloc (fixp);
1966 }
This page took 0.071111 seconds and 4 git commands to generate.