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