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