3991622d0cd02d3e188a6bf84ecacd9de95e60f1
[deliverable/binutils-gdb.git] / gas / config / tc-bfin.c
1 /* tc-bfin.c -- Assembler for the ADI Blackfin.
2 Copyright 2005, 2006, 2007
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 static void bfin_s_bss PARAMS ((int));
41 static int md_chars_to_number PARAMS ((char *, int));
42
43 /* Global variables. */
44 struct bfin_insn *insn;
45 int last_insn_size;
46
47 extern struct obstack mempool;
48 FILE *errorf;
49
50 /* Flags to set in the elf header */
51 #define DEFAULT_FLAGS 0
52
53 #ifdef OBJ_FDPIC_ELF
54 # define DEFAULT_FDPIC EF_BFIN_FDPIC
55 #else
56 # define DEFAULT_FDPIC 0
57 #endif
58
59 static flagword bfin_flags = DEFAULT_FLAGS | DEFAULT_FDPIC;
60 static const char *bfin_pic_flag = DEFAULT_FDPIC ? "-mfdpic" : (const char *)0;
61
62 /* Registers list. */
63 struct bfin_reg_entry
64 {
65 const char *name;
66 int number;
67 };
68
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}
217 };
218
219 /* Blackfin specific function to handle FD-PIC pointer initializations. */
220
221 static void
222 bfin_pic_ptr (int nbytes)
223 {
224 expressionS exp;
225 char *p;
226
227 if (nbytes != 4)
228 abort ();
229
230 #ifdef md_flush_pending_output
231 md_flush_pending_output ();
232 #endif
233
234 if (is_it_end_of_statement ())
235 {
236 demand_empty_rest_of_line ();
237 return;
238 }
239
240 #ifdef md_cons_align
241 md_cons_align (nbytes);
242 #endif
243
244 do
245 {
246 bfd_reloc_code_real_type reloc_type = BFD_RELOC_BFIN_FUNCDESC;
247
248 if (strncasecmp (input_line_pointer, "funcdesc(", 9) == 0)
249 {
250 input_line_pointer += 9;
251 expression (&exp);
252 if (*input_line_pointer == ')')
253 input_line_pointer++;
254 else
255 as_bad (_("missing ')'"));
256 }
257 else
258 error ("missing funcdesc in picptr");
259
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);
264 }
265 while (*input_line_pointer++ == ',');
266
267 input_line_pointer--; /* Put terminator back into stream. */
268 demand_empty_rest_of_line ();
269 }
270
271 static void
272 bfin_s_bss (int ignore ATTRIBUTE_UNUSED)
273 {
274 register int temp;
275
276 temp = get_absolute_expression ();
277 subseg_set (bss_section, (subsegT) temp);
278 demand_empty_rest_of_line ();
279 }
280
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}
295 };
296
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[] = ";";
301
302 /* Characters that can be used to separate the mantissa from the
303 exponent in floating point numbers. */
304 const char EXP_CHARS[] = "eE";
305
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";
309
310 /* Define bfin-specific command-line options (there are none). */
311 const char *md_shortopts = "";
312
313 #define OPTION_FDPIC (OPTION_MD_BASE)
314 #define OPTION_NOPIC (OPTION_MD_BASE + 1)
315
316 struct option md_longopts[] =
317 {
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 },
322 };
323
324 size_t md_longopts_size = sizeof (md_longopts);
325
326
327 int
328 md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
329 {
330 switch (c)
331 {
332 default:
333 return 0;
334
335 case OPTION_FDPIC:
336 bfin_flags |= EF_BFIN_FDPIC;
337 bfin_pic_flag = "-mfdpic";
338 break;
339
340 case OPTION_NOPIC:
341 bfin_flags &= ~(EF_BFIN_FDPIC);
342 bfin_pic_flag = 0;
343 break;
344 }
345
346 return 1;
347 }
348
349 void
350 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
351 {
352 fprintf (stream, _(" BFIN specific command line options:\n"));
353 }
354
355 /* Perform machine-specific initializations. */
356 void
357 md_begin ()
358 {
359 /* Set the ELF flags if desired. */
360 if (bfin_flags)
361 bfd_set_private_flags (stdoutput, bfin_flags);
362
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."));
366
367 /* Ensure that lines can begin with '(', for multiple
368 register stack pops. */
369 lex_type ['('] = LEX_BEGIN_NAME;
370
371 #ifdef OBJ_ELF
372 record_alignment (text_section, 2);
373 record_alignment (data_section, 2);
374 record_alignment (bss_section, 2);
375 #endif
376
377 errorf = stderr;
378 obstack_init (&mempool);
379
380 #ifdef DEBUG
381 extern int debug_codeselection;
382 debug_codeselection = 1;
383 #endif
384
385 last_insn_size = 0;
386 }
387
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. */
391
392 void
393 md_assemble (char *line)
394 {
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;
402
403 len = strlen (line);
404 if (len + 2 > buffer_len)
405 {
406 if (buffer_len > 0)
407 free (current_inputline);
408 buffer_len = len + 40;
409 current_inputline = xmalloc (buffer_len);
410 }
411 memcpy (current_inputline, line, len);
412 current_inputline[len] = ';';
413 current_inputline[len + 1] = '\0';
414
415 state = parse (current_inputline);
416 if (state == NO_INSN_GENERATED)
417 return;
418
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;
422
423 if (insn_size)
424 toP = frag_more (insn_size);
425
426 last_insn_size = insn_size;
427
428 #ifdef DEBUG
429 printf ("INS:");
430 #endif
431 while (insn)
432 {
433 if (insn->reloc && insn->exp->symbol)
434 {
435 char *prev_toP = toP - 2;
436 switch (insn->reloc)
437 {
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;
446 }
447
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)
454 {
455 size = 2;
456 }
457 if (insn->reloc == BFD_ARELOC_BFIN_CONST
458 || insn->reloc == BFD_ARELOC_BFIN_PUSH)
459 size = 4;
460
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);
465 }
466 else
467 {
468 md_number_to_chars (toP, insn->value, 2);
469 toP += 2;
470 }
471
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;
479 }
480 #ifdef OBJ_ELF
481 dwarf2_emit_insn (insn_size);
482 #endif
483 }
484
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. */
492
493 static parse_state
494 parse (char *line)
495 {
496 parse_state state;
497 YY_BUFFER_STATE buffstate;
498
499 buffstate = yy_scan_string (line);
500
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 ();
505
506 /* Call yyparse here. */
507 state = yyparse ();
508 if (state == SEMANTIC_ERROR)
509 {
510 as_bad (_("Parse failed."));
511 insn = 0;
512 }
513
514 yy_delete_buffer (buffstate);
515 return state;
516 }
517
518 /* We need to handle various expressions properly.
519 Such as, [SP--] = 34, concerned by md_assemble(). */
520
521 void
522 md_operand (expressionS * expressionP)
523 {
524 if (*input_line_pointer == '[')
525 {
526 as_tsktsk ("We found a '['!");
527 input_line_pointer++;
528 expression (expressionP);
529 }
530 }
531
532 /* Handle undefined symbols. */
533 symbolS *
534 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
535 {
536 return (symbolS *) 0;
537 }
538
539 int
540 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED,
541 segT segment ATTRIBUTE_UNUSED)
542 {
543 return 0;
544 }
545
546 /* Convert from target byte order to host byte order. */
547
548 static int
549 md_chars_to_number (char *val, int n)
550 {
551 int retval;
552
553 for (retval = 0; n--;)
554 {
555 retval <<= 8;
556 retval |= val[n];
557 }
558 return retval;
559 }
560
561 void
562 md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
563 {
564 char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
565
566 long value = *valueP;
567 long newval;
568
569 switch (fixP->fx_r_type)
570 {
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;
579
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"));
586
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;
593
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;
599
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;
608
609 case BFD_RELOC_BFIN_16_LOW:
610 case BFD_RELOC_BFIN_16_HIGH:
611 fixP->fx_done = FALSE;
612 break;
613
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;
619
620 if (value < -16777216 || value > 16777214)
621 as_bad_where (fixP->fx_file, fixP->fx_line, _("pcrel too far BFD_RELOC_BFIN_24"));
622
623 /* 25 bit offset even numbered, so we remove right bit. */
624 value = value >> 1;
625 value++;
626
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;
631
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;
642
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;
655
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;
661
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;
668
669 case BFD_RELOC_32:
670 md_number_to_chars (where, value, 4);
671 break;
672
673 case BFD_RELOC_BFIN_PLTPC:
674 md_number_to_chars (where, value, 2);
675 break;
676
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;
682
683 default:
684 if ((BFD_ARELOC_BFIN_PUSH > fixP->fx_r_type) || (BFD_ARELOC_BFIN_COMP < fixP->fx_r_type))
685 {
686 fprintf (stderr, "Relocation %d not handled in gas." " Contact support.\n", fixP->fx_r_type);
687 return;
688 }
689 }
690
691 if (!fixP->fx_addsy)
692 fixP->fx_done = TRUE;
693
694 }
695
696 /* Round up a section size to the appropriate boundary. */
697 valueT
698 md_section_align (segment, size)
699 segT segment;
700 valueT size;
701 {
702 int boundary = bfd_get_section_alignment (stdoutput, segment);
703 return ((size + (1 << boundary) - 1) & (-1 << boundary));
704 }
705
706
707 char *
708 md_atof (int type, char * litP, int * sizeP)
709 {
710 return ieee_md_atof (type, litP, sizeP, FALSE);
711 }
712
713
714 /* If while processing a fixup, a reloc really needs to be created
715 then it is done here. */
716
717 arelent *
718 tc_gen_reloc (seg, fixp)
719 asection *seg ATTRIBUTE_UNUSED;
720 fixS *fixp;
721 {
722 arelent *reloc;
723
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;
728
729 reloc->addend = fixp->fx_offset;
730 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
731
732 if (reloc->howto == (reloc_howto_type *) NULL)
733 {
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);
738
739 xfree (reloc);
740
741 return NULL;
742 }
743
744 return reloc;
745 }
746
747 /* The location from which a PC relative jump should be calculated,
748 given a PC relative reloc. */
749
750 long
751 md_pcrel_from_section (fixP, sec)
752 fixS *fixP;
753 segT sec;
754 {
755 if (fixP->fx_addsy != (symbolS *) NULL
756 && (!S_IS_DEFINED (fixP->fx_addsy)
757 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
758 {
759 /* The symbol is undefined (or is defined but not in this section).
760 Let the linker figure it out. */
761 return 0;
762 }
763 return fixP->fx_frag->fr_address + fixP->fx_where;
764 }
765
766 /* Return true if the fix can be handled by GAS, false if it must
767 be passed through to the linker. */
768
769 bfd_boolean
770 bfin_fix_adjustable (fixS *fixP)
771 {
772 switch (fixP->fx_r_type)
773 {
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;
783
784 default:
785 return 1;
786 }
787 }
788
789
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 ()
794 {
795 bfd_boolean maybe_begin = FALSE;
796 bfd_boolean maybe_end = FALSE;
797
798 char *c1, *label_name;
799 symbolS *line_label;
800 char *c = input_line_pointer;
801 int cr_num = 0;
802
803 while (ISSPACE (*c))
804 {
805 if (*c == '\n')
806 cr_num++;
807 c++;
808 }
809
810 /* Look for Loop_Begin or Loop_End statements. */
811
812 if (*c != 'L' && *c != 'l')
813 return;
814
815 c++;
816 if (*c != 'O' && *c != 'o')
817 return;
818
819 c++;
820 if (*c != 'O' && *c != 'o')
821 return;
822
823 c++;
824 if (*c != 'P' && *c != 'p')
825 return;
826
827 c++;
828 if (*c != '_')
829 return;
830
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;
838
839 if (maybe_end)
840 {
841 c++;
842 if (*c != 'N' && *c != 'n')
843 return;
844
845 c++;
846 if (*c != 'D' && *c != 'd')
847 return;
848 }
849
850 if (maybe_begin)
851 {
852 c++;
853 if (*c != 'E' && *c != 'e')
854 return;
855
856 c++;
857 if (*c != 'G' && *c != 'g')
858 return;
859
860 c++;
861 if (*c != 'I' && *c != 'i')
862 return;
863
864 c++;
865 if (*c != 'N' && *c != 'n')
866 return;
867 }
868
869 c++;
870 while (ISSPACE (*c)) c++;
871 c1 = c;
872 while (ISALPHA (*c) || ISDIGIT (*c) || *c == '_') c++;
873
874 if (input_line_pointer[-1] == '\n')
875 bump_line_counters ();
876
877 while (cr_num--)
878 bump_line_counters ();
879
880 input_line_pointer = c;
881 if (maybe_end)
882 {
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");
888 }
889 else /* maybe_begin. */
890 {
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");
896 }
897
898 line_label = colon (label_name);
899
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;
904 }
905
906 /* Special extra functions that help bfin-parse.y perform its job. */
907
908 #include <assert.h>
909
910 struct obstack mempool;
911
912 INSTR_T
913 conscode (INSTR_T head, INSTR_T tail)
914 {
915 if (!head)
916 return tail;
917 head->next = tail;
918 return head;
919 }
920
921 INSTR_T
922 conctcode (INSTR_T head, INSTR_T tail)
923 {
924 INSTR_T temp = (head);
925 if (!head)
926 return tail;
927 while (temp->next)
928 temp = temp->next;
929 temp->next = tail;
930
931 return head;
932 }
933
934 INSTR_T
935 note_reloc (INSTR_T code, Expr_Node * symbol, int reloc, int pcrel)
936 {
937 /* Assert that the symbol is not an operator. */
938 assert (symbol->type == Expr_Node_Reloc);
939
940 return note_reloc1 (code, symbol->value.s_value, reloc, pcrel);
941
942 }
943
944 INSTR_T
945 note_reloc1 (INSTR_T code, const char *symbol, int reloc, int pcrel)
946 {
947 code->reloc = reloc;
948 code->exp = mkexpr (0, symbol_find_or_make (symbol));
949 code->pcrel = pcrel;
950 return code;
951 }
952
953 INSTR_T
954 note_reloc2 (INSTR_T code, const char *symbol, int reloc, int value, int pcrel)
955 {
956 code->reloc = reloc;
957 code->exp = mkexpr (value, symbol_find_or_make (symbol));
958 code->pcrel = pcrel;
959 return code;
960 }
961
962 INSTR_T
963 gencode (unsigned long x)
964 {
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;
969 }
970
971 int reloc;
972 int ninsns;
973 int count_insns;
974
975 static void *
976 allocate (int n)
977 {
978 return (void *) obstack_alloc (&mempool, n);
979 }
980
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)
986 {
987
988
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;
995 }
996
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);
1001
1002 INSTR_T
1003 Expr_Node_Gen_Reloc (Expr_Node * head, int parent_reloc)
1004 {
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. */
1008
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. */
1013
1014 if (parent_reloc)
1015 {
1016 /* If it's 32 bit quantity then 16bit code needs to be added. */
1017 int value = 0;
1018
1019 if (head->type == Expr_Node_Constant)
1020 {
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;
1026 }
1027 switch (parent_reloc)
1028 {
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;
1055 }
1056 }
1057 if (head->type == Expr_Node_Constant)
1058 note = note1;
1059 else if (head->type == Expr_Node_Reloc)
1060 {
1061 note = note_reloc1 (gencode (0), head->value.s_value, parent_reloc, pcrel);
1062 if (note1 != NULL_CODE)
1063 note = conscode (note1, note);
1064 }
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)
1070 {
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);
1079 }
1080 else
1081 {
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);
1087 }
1088 return note;
1089 }
1090
1091 static INSTR_T
1092 Expr_Node_Gen_Reloc_R (Expr_Node * head)
1093 {
1094
1095 INSTR_T note = 0;
1096 INSTR_T note1 = 0;
1097
1098 switch (head->type)
1099 {
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)
1109 {
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__);
1148
1149
1150 }
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)
1155 {
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__);
1164 }
1165 break;
1166 default:
1167 fprintf (stderr, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__, __LINE__);
1168 }
1169 return note;
1170 }
1171
1172
1173 /* Blackfin opcode generation. */
1174
1175 /* These functions are called by the generated parser
1176 (from bfin-parse.y), the register type classification
1177 happens in bfin-lex.l. */
1178
1179 #include "bfin-aux.h"
1180 #include "opcode/bfin.h"
1181
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)
1185
1186 #define HI(x) ((x >> 16) & 0xffff)
1187 #define LO(x) ((x ) & 0xffff)
1188
1189 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1190
1191 #define GEN_OPCODE32() \
1192 conscode (gencode (HI (c_code.opcode)), \
1193 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1194
1195 #define GEN_OPCODE16() \
1196 conscode (gencode (c_code.opcode), NULL_CODE)
1197
1198
1199 /* 32 BIT INSTRUCTIONS. */
1200
1201
1202 /* DSP32 instruction generation. */
1203
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)
1208 {
1209 INIT (DSP32Mac);
1210
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);
1222
1223 /* If we have full reg assignments, mask out LSB to encode
1224 single or simultaneous even/odd register moves. */
1225 if (P)
1226 {
1227 dst->regno &= 0x06;
1228 }
1229
1230 ASSIGN_R (dst);
1231 ASSIGN_R (src0);
1232 ASSIGN_R (src1);
1233
1234 return GEN_OPCODE32 ();
1235 }
1236
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)
1241 {
1242 INIT (DSP32Mult);
1243
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);
1255
1256 if (P)
1257 {
1258 dst->regno &= 0x06;
1259 }
1260
1261 ASSIGN_R (dst);
1262 ASSIGN_R (src0);
1263 ASSIGN_R (src1);
1264
1265 return GEN_OPCODE32 ();
1266 }
1267
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)
1271 {
1272 INIT (DSP32Alu);
1273
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);
1283
1284 return GEN_OPCODE32 ();
1285 }
1286
1287 INSTR_T
1288 bfin_gen_dsp32shift (int sopcde, REG_T dst0, REG_T src0,
1289 REG_T src1, int sop, int HLs)
1290 {
1291 INIT (DSP32Shift);
1292
1293 ASSIGN (sopcde);
1294 ASSIGN (sop);
1295 ASSIGN (HLs);
1296
1297 ASSIGN_R (dst0);
1298 ASSIGN_R (src0);
1299 ASSIGN_R (src1);
1300
1301 return GEN_OPCODE32 ();
1302 }
1303
1304 INSTR_T
1305 bfin_gen_dsp32shiftimm (int sopcde, REG_T dst0, int immag,
1306 REG_T src1, int sop, int HLs)
1307 {
1308 INIT (DSP32ShiftImm);
1309
1310 ASSIGN (sopcde);
1311 ASSIGN (sop);
1312 ASSIGN (HLs);
1313
1314 ASSIGN_R (dst0);
1315 ASSIGN (immag);
1316 ASSIGN_R (src1);
1317
1318 return GEN_OPCODE32 ();
1319 }
1320
1321 /* LOOP SETUP. */
1322
1323 INSTR_T
1324 bfin_gen_loopsetup (Expr_Node * psoffset, REG_T c, int rop,
1325 Expr_Node * peoffset, REG_T reg)
1326 {
1327 int soffset, eoffset;
1328 INIT (LoopSetup);
1329
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);
1337
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))));
1342
1343 }
1344
1345 /* Call, Link. */
1346
1347 INSTR_T
1348 bfin_gen_calla (Expr_Node * addr, int S)
1349 {
1350 int val;
1351 int high_val;
1352 int reloc = 0;
1353 INIT (CALLa);
1354
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;
1360 }
1361
1362 ASSIGN (S);
1363
1364 val = EXPR_VALUE (addr) >> 1;
1365 high_val = val >> 16;
1366
1367 return conscode (gencode (HI (c_code.opcode) | (high_val & 0xff)),
1368 Expr_Node_Gen_Reloc (addr, reloc));
1369 }
1370
1371 INSTR_T
1372 bfin_gen_linkage (int R, int framesize)
1373 {
1374 INIT (Linkage);
1375
1376 ASSIGN (R);
1377 ASSIGN (framesize);
1378
1379 return GEN_OPCODE32 ();
1380 }
1381
1382
1383 /* Load and Store. */
1384
1385 INSTR_T
1386 bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int reloc)
1387 {
1388 int grp, hword;
1389 unsigned val = EXPR_VALUE (phword);
1390 INIT (LDIMMhalf);
1391
1392 ASSIGN (H);
1393 ASSIGN (S);
1394 ASSIGN (Z);
1395
1396 ASSIGN_R (reg);
1397 grp = (GROUP (reg));
1398 ASSIGN (grp);
1399 if (reloc == 2)
1400 {
1401 return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, BFD_RELOC_BFIN_16_IMM));
1402 }
1403 else if (reloc == 1)
1404 {
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));
1406 }
1407 else
1408 {
1409 hword = val;
1410 ASSIGN (hword);
1411 }
1412 return GEN_OPCODE32 ();
1413 }
1414
1415 INSTR_T
1416 bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset)
1417 {
1418 INIT (LDSTidxI);
1419
1420 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1421 {
1422 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1423 return 0;
1424 }
1425
1426 ASSIGN_R (ptr);
1427 ASSIGN_R (reg);
1428 ASSIGN (W);
1429 ASSIGN (sz);
1430
1431 ASSIGN (Z);
1432
1433 if (poffset->type != Expr_Node_Constant)
1434 {
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_]
1438 */
1439 if (poffset->type == Expr_Node_Reloc
1440 && !strcmp (poffset->value.s_value,
1441 "_current_shared_library_p5_offset_"))
1442 {
1443 return conscode (gencode (HI (c_code.opcode)),
1444 Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16));
1445 }
1446 else if (poffset->type != Expr_Node_GOT_Reloc)
1447 abort ();
1448
1449 return conscode (gencode (HI (c_code.opcode)),
1450 Expr_Node_Gen_Reloc(poffset->Left_Child,
1451 poffset->value.i_value));
1452 }
1453 else
1454 {
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 ();
1469 }
1470
1471 offset = (value & 0xffff);
1472 ASSIGN (offset);
1473 return GEN_OPCODE32 ();
1474 }
1475 }
1476
1477
1478 INSTR_T
1479 bfin_gen_ldst (REG_T ptr, REG_T reg, int aop, int sz, int Z, int W)
1480 {
1481 INIT (LDST);
1482
1483 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1484 {
1485 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1486 return 0;
1487 }
1488
1489 ASSIGN_R (ptr);
1490 ASSIGN_R (reg);
1491 ASSIGN (aop);
1492 ASSIGN (sz);
1493 ASSIGN (Z);
1494 ASSIGN (W);
1495
1496 return GEN_OPCODE16 ();
1497 }
1498
1499 INSTR_T
1500 bfin_gen_ldstii (REG_T ptr, REG_T reg, Expr_Node * poffset, int W, int op)
1501 {
1502 int offset;
1503 int value = 0;
1504 INIT (LDSTii);
1505
1506
1507 if (!IS_PREG (*ptr))
1508 {
1509 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1510 return 0;
1511 }
1512
1513 switch (op)
1514 {
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;
1523 }
1524
1525 ASSIGN_R (ptr);
1526 ASSIGN_R (reg);
1527
1528 offset = value;
1529 ASSIGN (offset);
1530 ASSIGN (W);
1531 ASSIGN (op);
1532
1533 return GEN_OPCODE16 ();
1534 }
1535
1536 INSTR_T
1537 bfin_gen_ldstiifp (REG_T sreg, Expr_Node * poffset, int W)
1538 {
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);
1546
1547 return GEN_OPCODE16 ();
1548 }
1549
1550 INSTR_T
1551 bfin_gen_ldstpmod (REG_T ptr, REG_T reg, int aop, int W, REG_T idx)
1552 {
1553 INIT (LDSTpmod);
1554
1555 ASSIGN_R (ptr);
1556 ASSIGN_R (reg);
1557 ASSIGN (aop);
1558 ASSIGN (W);
1559 ASSIGN_R (idx);
1560
1561 return GEN_OPCODE16 ();
1562 }
1563
1564 INSTR_T
1565 bfin_gen_dspldst (REG_T i, REG_T reg, int aop, int W, int m)
1566 {
1567 INIT (DspLDST);
1568
1569 ASSIGN_R (i);
1570 ASSIGN_R (reg);
1571 ASSIGN (aop);
1572 ASSIGN (W);
1573 ASSIGN (m);
1574
1575 return GEN_OPCODE16 ();
1576 }
1577
1578 INSTR_T
1579 bfin_gen_logi2op (int opc, int src, int dst)
1580 {
1581 INIT (LOGI2op);
1582
1583 ASSIGN (opc);
1584 ASSIGN (src);
1585 ASSIGN (dst);
1586
1587 return GEN_OPCODE16 ();
1588 }
1589
1590 INSTR_T
1591 bfin_gen_brcc (int T, int B, Expr_Node * poffset)
1592 {
1593 int offset;
1594 INIT (BRCC);
1595
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));
1601 }
1602
1603 INSTR_T
1604 bfin_gen_ujump (Expr_Node * poffset)
1605 {
1606 int offset;
1607 INIT (UJump);
1608
1609 offset = ((EXPR_VALUE (poffset) >> 1));
1610 ASSIGN (offset);
1611
1612 return conscode (gencode (c_code.opcode),
1613 Expr_Node_Gen_Reloc (
1614 poffset, BFD_RELOC_BFIN_12_PCREL_JUMP_S));
1615 }
1616
1617 INSTR_T
1618 bfin_gen_alu2op (REG_T dst, REG_T src, int opc)
1619 {
1620 INIT (ALU2op);
1621
1622 ASSIGN_R (dst);
1623 ASSIGN_R (src);
1624 ASSIGN (opc);
1625
1626 return GEN_OPCODE16 ();
1627 }
1628
1629 INSTR_T
1630 bfin_gen_compi2opd (REG_T dst, int src, int op)
1631 {
1632 INIT (COMPI2opD);
1633
1634 ASSIGN_R (dst);
1635 ASSIGN (src);
1636 ASSIGN (op);
1637
1638 return GEN_OPCODE16 ();
1639 }
1640
1641 INSTR_T
1642 bfin_gen_compi2opp (REG_T dst, int src, int op)
1643 {
1644 INIT (COMPI2opP);
1645
1646 ASSIGN_R (dst);
1647 ASSIGN (src);
1648 ASSIGN (op);
1649
1650 return GEN_OPCODE16 ();
1651 }
1652
1653 INSTR_T
1654 bfin_gen_dagmodik (REG_T i, int op)
1655 {
1656 INIT (DagMODik);
1657
1658 ASSIGN_R (i);
1659 ASSIGN (op);
1660
1661 return GEN_OPCODE16 ();
1662 }
1663
1664 INSTR_T
1665 bfin_gen_dagmodim (REG_T i, REG_T m, int op, int br)
1666 {
1667 INIT (DagMODim);
1668
1669 ASSIGN_R (i);
1670 ASSIGN_R (m);
1671 ASSIGN (op);
1672 ASSIGN (br);
1673
1674 return GEN_OPCODE16 ();
1675 }
1676
1677 INSTR_T
1678 bfin_gen_ptr2op (REG_T dst, REG_T src, int opc)
1679 {
1680 INIT (PTR2op);
1681
1682 ASSIGN_R (dst);
1683 ASSIGN_R (src);
1684 ASSIGN (opc);
1685
1686 return GEN_OPCODE16 ();
1687 }
1688
1689 INSTR_T
1690 bfin_gen_comp3op (REG_T src0, REG_T src1, REG_T dst, int opc)
1691 {
1692 INIT (COMP3op);
1693
1694 ASSIGN_R (src0);
1695 ASSIGN_R (src1);
1696 ASSIGN_R (dst);
1697 ASSIGN (opc);
1698
1699 return GEN_OPCODE16 ();
1700 }
1701
1702 INSTR_T
1703 bfin_gen_ccflag (REG_T x, int y, int opc, int I, int G)
1704 {
1705 INIT (CCflag);
1706
1707 ASSIGN_R (x);
1708 ASSIGN (y);
1709 ASSIGN (opc);
1710 ASSIGN (I);
1711 ASSIGN (G);
1712
1713 return GEN_OPCODE16 ();
1714 }
1715
1716 INSTR_T
1717 bfin_gen_ccmv (REG_T src, REG_T dst, int T)
1718 {
1719 int s, d;
1720 INIT (CCmv);
1721
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);
1729
1730 return GEN_OPCODE16 ();
1731 }
1732
1733 INSTR_T
1734 bfin_gen_cc2stat (int cbit, int op, int D)
1735 {
1736 INIT (CC2stat);
1737
1738 ASSIGN (cbit);
1739 ASSIGN (op);
1740 ASSIGN (D);
1741
1742 return GEN_OPCODE16 ();
1743 }
1744
1745 INSTR_T
1746 bfin_gen_regmv (REG_T src, REG_T dst)
1747 {
1748 int gs, gd;
1749 INIT (RegMv);
1750
1751 ASSIGN_R (src);
1752 ASSIGN_R (dst);
1753
1754 gs = (GROUP (src));
1755 ASSIGN (gs);
1756 gd = (GROUP (dst));
1757 ASSIGN (gd);
1758
1759 return GEN_OPCODE16 ();
1760 }
1761
1762 INSTR_T
1763 bfin_gen_cc2dreg (int op, REG_T reg)
1764 {
1765 INIT (CC2dreg);
1766
1767 ASSIGN (op);
1768 ASSIGN_R (reg);
1769
1770 return GEN_OPCODE16 ();
1771 }
1772
1773 INSTR_T
1774 bfin_gen_progctrl (int prgfunc, int poprnd)
1775 {
1776 INIT (ProgCtrl);
1777
1778 ASSIGN (prgfunc);
1779 ASSIGN (poprnd);
1780
1781 return GEN_OPCODE16 ();
1782 }
1783
1784 INSTR_T
1785 bfin_gen_cactrl (REG_T reg, int a, int op)
1786 {
1787 INIT (CaCTRL);
1788
1789 ASSIGN_R (reg);
1790 ASSIGN (a);
1791 ASSIGN (op);
1792
1793 return GEN_OPCODE16 ();
1794 }
1795
1796 INSTR_T
1797 bfin_gen_pushpopmultiple (int dr, int pr, int d, int p, int W)
1798 {
1799 INIT (PushPopMultiple);
1800
1801 ASSIGN (dr);
1802 ASSIGN (pr);
1803 ASSIGN (d);
1804 ASSIGN (p);
1805 ASSIGN (W);
1806
1807 return GEN_OPCODE16 ();
1808 }
1809
1810 INSTR_T
1811 bfin_gen_pushpopreg (REG_T reg, int W)
1812 {
1813 int grp;
1814 INIT (PushPopReg);
1815
1816 ASSIGN_R (reg);
1817 grp = (GROUP (reg));
1818 ASSIGN (grp);
1819 ASSIGN (W);
1820
1821 return GEN_OPCODE16 ();
1822 }
1823
1824 /* Pseudo Debugging Support. */
1825
1826 INSTR_T
1827 bfin_gen_pseudodbg (int fn, int reg, int grp)
1828 {
1829 INIT (PseudoDbg);
1830
1831 ASSIGN (fn);
1832 ASSIGN (reg);
1833 ASSIGN (grp);
1834
1835 return GEN_OPCODE16 ();
1836 }
1837
1838 INSTR_T
1839 bfin_gen_pseudodbg_assert (int dbgop, REG_T regtest, int expected)
1840 {
1841 INIT (PseudoDbg_Assert);
1842
1843 ASSIGN (dbgop);
1844 ASSIGN_R (regtest);
1845 ASSIGN (expected);
1846
1847 return GEN_OPCODE32 ();
1848 }
1849
1850 /* Multiple instruction generation. */
1851
1852 INSTR_T
1853 bfin_gen_multi_instr (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2)
1854 {
1855 INSTR_T walk;
1856
1857 /* If it's a 0, convert into MNOP. */
1858 if (dsp32)
1859 {
1860 walk = dsp32->next;
1861 SET_MULTI_INSTRUCTION_BIT (dsp32);
1862 }
1863 else
1864 {
1865 dsp32 = gencode (0xc803);
1866 walk = gencode (0x1800);
1867 dsp32->next = walk;
1868 }
1869
1870 if (!dsp16_grp1)
1871 {
1872 dsp16_grp1 = gencode (0x0000);
1873 }
1874
1875 if (!dsp16_grp2)
1876 {
1877 dsp16_grp2 = gencode (0x0000);
1878 }
1879
1880 walk->next = dsp16_grp1;
1881 dsp16_grp1->next = dsp16_grp2;
1882 dsp16_grp2->next = NULL_CODE;
1883
1884 return dsp32;
1885 }
1886
1887 INSTR_T
1888 bfin_gen_loop (Expr_Node *expr, REG_T reg, int rop, REG_T preg)
1889 {
1890 const char *loopsym;
1891 char *lbeginsym, *lendsym;
1892 Expr_Node_Value lbeginval, lendval;
1893 Expr_Node *lbegin, *lend;
1894
1895 loopsym = expr->value.s_value;
1896 lbeginsym = (char *) xmalloc (strlen (loopsym) + strlen ("__BEGIN") + 5);
1897 lendsym = (char *) xmalloc (strlen (loopsym) + strlen ("__END") + 5);
1898
1899 lbeginsym[0] = 0;
1900 lendsym[0] = 0;
1901
1902 strcat (lbeginsym, "L$L$");
1903 strcat (lbeginsym, loopsym);
1904 strcat (lbeginsym, "__BEGIN");
1905
1906 strcat (lendsym, "L$L$");
1907 strcat (lendsym, loopsym);
1908 strcat (lendsym, "__END");
1909
1910 lbeginval.s_value = lbeginsym;
1911 lendval.s_value = lendsym;
1912
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);
1916 }
1917
1918 bfd_boolean
1919 bfin_eol_in_insn (char *line)
1920 {
1921 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1922
1923 char *temp = line;
1924
1925 if (*line != '\n')
1926 return FALSE;
1927
1928 /* A semi-colon followed by a newline is always the end of a line. */
1929 if (line[-1] == ';')
1930 return FALSE;
1931
1932 if (line[-1] == '|')
1933 return TRUE;
1934
1935 /* If the || is on the next line, there might be leading whitespace. */
1936 temp++;
1937 while (*temp == ' ' || *temp == '\t') temp++;
1938
1939 if (*temp == '|')
1940 return TRUE;
1941
1942 return FALSE;
1943 }
1944
1945 bfd_boolean
1946 bfin_start_label (char *ptr)
1947 {
1948 ptr--;
1949 while (!ISSPACE (*ptr) && !is_end_of_line[(unsigned char) *ptr])
1950 ptr--;
1951
1952 ptr++;
1953 if (*ptr == '(' || *ptr == '[')
1954 return FALSE;
1955
1956 return TRUE;
1957 }
1958
1959 int
1960 bfin_force_relocation (struct fix *fixp)
1961 {
1962 if (fixp->fx_r_type ==BFD_RELOC_BFIN_16_LOW
1963 || fixp->fx_r_type == BFD_RELOC_BFIN_16_HIGH)
1964 return TRUE;
1965
1966 return generic_force_reloc (fixp);
1967 }
This page took 0.072138 seconds and 4 git commands to generate.