* emulparams/elf32bfinfd.sh: New file.
[deliverable/binutils-gdb.git] / gas / config / tc-bfin.c
CommitLineData
07c1b327
CM
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
32extern int yyparse (void);
33struct yy_buffer_state;
34typedef struct yy_buffer_state *YY_BUFFER_STATE;
35extern YY_BUFFER_STATE yy_scan_string (const char *yy_str);
36extern void yy_delete_buffer (YY_BUFFER_STATE b);
37static parse_state parse (char *line);
38static void bfin_s_bss PARAMS ((int));
9ba4c445 39static int md_chars_to_number PARAMS ((char *, int));
07c1b327
CM
40
41/* Global variables. */
42struct bfin_insn *insn;
43int last_insn_size;
44
45extern struct obstack mempool;
46FILE *errorf;
47
48/* Registers list. */
49struct bfin_reg_entry
50{
51 const char *name;
52 int number;
53};
54
55static 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
206const 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
221static void
222bfin_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. */
233const char comment_chars[] = "";
234const char line_comment_chars[] = "#";
235const char line_separator_chars[] = ";";
236
237/* Characters that can be used to separate the mantissa from the
238 exponent in floating point numbers. */
239const char EXP_CHARS[] = "eE";
240
241/* Characters that mean this number is a floating point constant.
242 As in 0f12.456 or 0d1.2345e12. */
243const char FLT_CHARS[] = "fFdDxX";
244
245/* Define bfin-specific command-line options (there are none). */
246const char *md_shortopts = "";
247
248struct option md_longopts[] = {
249 {NULL, no_argument, NULL, 0}
250};
251size_t md_longopts_size = sizeof (md_longopts);
252
253
254int
255md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
256{
257 return 0;
258}
259
260void
261md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
262{
263 fprintf (stream, _(" BFIN specific command line options:\n"));
264}
265
266/* Perform machine-specific initializations. */
267void
268md_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. */
9f8e671b 276 lex_type ['('] = LEX_BEGIN_NAME;
07c1b327
CM
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
299void
300md_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
400static parse_state
401parse (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
428void
429md_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. */
440symbolS *
441md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
442{
443 return (symbolS *) 0;
444}
445
446int
447md_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
455static int
9ba4c445 456md_chars_to_number (char *val, int n)
07c1b327
CM
457{
458 int retval;
459
460 for (retval = 0; n--;)
461 {
462 retval <<= 8;
463 retval |= val[n];
464 }
465 return retval;
466}
467
468void
469md_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. */
601valueT
602md_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
619char *
620md_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
670arelent *
671tc_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
703long
704md_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
722bfd_boolean
723bfin_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. */
743void
744bfin_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
07c1b327
CM
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
853struct obstack mempool;
854
855INSTR_T
856conscode (INSTR_T head, INSTR_T tail)
857{
858 if (!head)
859 return tail;
860 head->next = tail;
861 return head;
862}
863
864INSTR_T
865conctcode (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
877INSTR_T
878note_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
887INSTR_T
888note_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
896INSTR_T
897note_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
905INSTR_T
906gencode (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
914int reloc;
915int ninsns;
916int count_insns;
917
918static void *
919allocate (int n)
920{
921 return (void *) obstack_alloc (&mempool, n);
922}
923
924Expr_Node *
925Expr_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
940static const char *con = ".__constant";
941static const char *op = ".__operator";
942static INSTR_T Expr_Node_Gen_Reloc_R (Expr_Node * head);
943INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc);
944
945INSTR_T
946Expr_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 }
beb6bfe8
BS
1006 else if (head->type == Expr_Node_Binop
1007 && (head->value.op_value == Expr_Op_Type_Add
1008 || head->value.op_value == Expr_Op_Type_Sub)
1009 && head->Left_Child->type == Expr_Node_Reloc
1010 && head->Right_Child->type == Expr_Node_Constant)
1011 {
1012 int val = head->Right_Child->value.i_value;
1013 if (head->value.op_value == Expr_Op_Type_Sub)
1014 val = -val;
1015 note = conscode (note_reloc2 (gencode (0), head->Left_Child->value.s_value,
1016 parent_reloc, val, 0),
1017 NULL_CODE);
1018 if (note1 != NULL_CODE)
1019 note = conscode (note1, note);
1020 }
07c1b327
CM
1021 else
1022 {
1023 /* Call the recursive function. */
1024 note = note_reloc1 (gencode (0), op, parent_reloc, pcrel);
1025 if (note1 != NULL_CODE)
1026 note = conscode (note1, note);
1027 note = conctcode (Expr_Node_Gen_Reloc_R (head), note);
1028 }
1029 return note;
1030}
1031
1032static INSTR_T
1033Expr_Node_Gen_Reloc_R (Expr_Node * head)
1034{
1035
1036 INSTR_T note = 0;
1037 INSTR_T note1 = 0;
1038
1039 switch (head->type)
1040 {
1041 case Expr_Node_Constant:
1042 note = conscode (note_reloc2 (gencode (0), con, BFD_ARELOC_BFIN_CONST, head->value.i_value, 0), NULL_CODE);
1043 break;
1044 case Expr_Node_Reloc:
1045 note = conscode (note_reloc (gencode (0), head, BFD_ARELOC_BFIN_PUSH, 0), NULL_CODE);
1046 break;
1047 case Expr_Node_Binop:
1048 note1 = conctcode (Expr_Node_Gen_Reloc_R (head->Left_Child), Expr_Node_Gen_Reloc_R (head->Right_Child));
1049 switch (head->value.op_value)
1050 {
1051 case Expr_Op_Type_Add:
1052 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_ADD, 0), NULL_CODE));
1053 break;
1054 case Expr_Op_Type_Sub:
1055 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_SUB, 0), NULL_CODE));
1056 break;
1057 case Expr_Op_Type_Mult:
1058 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MULT, 0), NULL_CODE));
1059 break;
1060 case Expr_Op_Type_Div:
1061 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_DIV, 0), NULL_CODE));
1062 break;
1063 case Expr_Op_Type_Mod:
1064 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MOD, 0), NULL_CODE));
1065 break;
1066 case Expr_Op_Type_Lshift:
1067 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LSHIFT, 0), NULL_CODE));
1068 break;
1069 case Expr_Op_Type_Rshift:
1070 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_RSHIFT, 0), NULL_CODE));
1071 break;
1072 case Expr_Op_Type_BAND:
1073 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_AND, 0), NULL_CODE));
1074 break;
1075 case Expr_Op_Type_BOR:
1076 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_OR, 0), NULL_CODE));
1077 break;
1078 case Expr_Op_Type_BXOR:
1079 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_XOR, 0), NULL_CODE));
1080 break;
1081 case Expr_Op_Type_LAND:
1082 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LAND, 0), NULL_CODE));
1083 break;
1084 case Expr_Op_Type_LOR:
1085 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LOR, 0), NULL_CODE));
1086 break;
1087 default:
1088 fprintf (stderr, "%s:%d:Unkonwn operator found for arithmetic" " relocation", __FILE__, __LINE__);
1089
1090
1091 }
1092 break;
1093 case Expr_Node_Unop:
1094 note1 = conscode (Expr_Node_Gen_Reloc_R (head->Left_Child), NULL_CODE);
1095 switch (head->value.op_value)
1096 {
1097 case Expr_Op_Type_NEG:
1098 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_NEG, 0), NULL_CODE));
1099 break;
1100 case Expr_Op_Type_COMP:
1101 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_COMP, 0), NULL_CODE));
1102 break;
1103 default:
1104 fprintf (stderr, "%s:%d:Unkonwn operator found for arithmetic" " relocation", __FILE__, __LINE__);
1105 }
1106 break;
1107 default:
1108 fprintf (stderr, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__, __LINE__);
1109 }
1110 return note;
1111}
1112
1113
1114/* Blackfin opcode generation. */
1115
1116/* These functions are called by the generated parser
1117 (from bfin-parse.y), the register type classification
1118 happens in bfin-lex.l. */
1119
1120#include "bfin-aux.h"
1121#include "opcode/bfin.h"
1122
1123#define INIT(t) t c_code = init_##t
1124#define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1125#define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1126
1127#define HI(x) ((x >> 16) & 0xffff)
1128#define LO(x) ((x ) & 0xffff)
1129
1130#define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1131
1132#define GEN_OPCODE32() \
1133 conscode (gencode (HI (c_code.opcode)), \
1134 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1135
1136#define GEN_OPCODE16() \
1137 conscode (gencode (c_code.opcode), NULL_CODE)
1138
1139
1140/* 32 BIT INSTRUCTIONS. */
1141
1142
1143/* DSP32 instruction generation. */
1144
1145INSTR_T
1146bfin_gen_dsp32mac (int op1, int MM, int mmod, int w1, int P,
1147 int h01, int h11, int h00, int h10, int op0,
1148 REG_T dst, REG_T src0, REG_T src1, int w0)
1149{
1150 INIT (DSP32Mac);
1151
1152 ASSIGN (op0);
1153 ASSIGN (op1);
1154 ASSIGN (MM);
1155 ASSIGN (mmod);
1156 ASSIGN (w0);
1157 ASSIGN (w1);
1158 ASSIGN (h01);
1159 ASSIGN (h11);
1160 ASSIGN (h00);
1161 ASSIGN (h10);
1162 ASSIGN (P);
1163
1164 /* If we have full reg assignments, mask out LSB to encode
1165 single or simultaneous even/odd register moves. */
1166 if (P)
1167 {
1168 dst->regno &= 0x06;
1169 }
1170
1171 ASSIGN_R (dst);
1172 ASSIGN_R (src0);
1173 ASSIGN_R (src1);
1174
1175 return GEN_OPCODE32 ();
1176}
1177
1178INSTR_T
1179bfin_gen_dsp32mult (int op1, int MM, int mmod, int w1, int P,
1180 int h01, int h11, int h00, int h10, int op0,
1181 REG_T dst, REG_T src0, REG_T src1, int w0)
1182{
1183 INIT (DSP32Mult);
1184
1185 ASSIGN (op0);
1186 ASSIGN (op1);
1187 ASSIGN (MM);
1188 ASSIGN (mmod);
1189 ASSIGN (w0);
1190 ASSIGN (w1);
1191 ASSIGN (h01);
1192 ASSIGN (h11);
1193 ASSIGN (h00);
1194 ASSIGN (h10);
1195 ASSIGN (P);
1196
1197 if (P)
1198 {
1199 dst->regno &= 0x06;
1200 }
1201
1202 ASSIGN_R (dst);
1203 ASSIGN_R (src0);
1204 ASSIGN_R (src1);
1205
1206 return GEN_OPCODE32 ();
1207}
1208
1209INSTR_T
1210bfin_gen_dsp32alu (int HL, int aopcde, int aop, int s, int x,
1211 REG_T dst0, REG_T dst1, REG_T src0, REG_T src1)
1212{
1213 INIT (DSP32Alu);
1214
1215 ASSIGN (HL);
1216 ASSIGN (aopcde);
1217 ASSIGN (aop);
1218 ASSIGN (s);
1219 ASSIGN (x);
1220 ASSIGN_R (dst0);
1221 ASSIGN_R (dst1);
1222 ASSIGN_R (src0);
1223 ASSIGN_R (src1);
1224
1225 return GEN_OPCODE32 ();
1226}
1227
1228INSTR_T
1229bfin_gen_dsp32shift (int sopcde, REG_T dst0, REG_T src0,
1230 REG_T src1, int sop, int HLs)
1231{
1232 INIT (DSP32Shift);
1233
1234 ASSIGN (sopcde);
1235 ASSIGN (sop);
1236 ASSIGN (HLs);
1237
1238 ASSIGN_R (dst0);
1239 ASSIGN_R (src0);
1240 ASSIGN_R (src1);
1241
1242 return GEN_OPCODE32 ();
1243}
1244
1245INSTR_T
1246bfin_gen_dsp32shiftimm (int sopcde, REG_T dst0, int immag,
1247 REG_T src1, int sop, int HLs)
1248{
1249 INIT (DSP32ShiftImm);
1250
1251 ASSIGN (sopcde);
1252 ASSIGN (sop);
1253 ASSIGN (HLs);
1254
1255 ASSIGN_R (dst0);
1256 ASSIGN (immag);
1257 ASSIGN_R (src1);
1258
1259 return GEN_OPCODE32 ();
1260}
1261
1262/* LOOP SETUP. */
1263
1264INSTR_T
1265bfin_gen_loopsetup (Expr_Node * psoffset, REG_T c, int rop,
1266 Expr_Node * peoffset, REG_T reg)
1267{
1268 int soffset, eoffset;
1269 INIT (LoopSetup);
1270
1271 soffset = (EXPR_VALUE (psoffset) >> 1);
1272 ASSIGN (soffset);
1273 eoffset = (EXPR_VALUE (peoffset) >> 1);
1274 ASSIGN (eoffset);
1275 ASSIGN (rop);
1276 ASSIGN_R (c);
1277 ASSIGN_R (reg);
1278
1279 return
1280 conscode (gencode (HI (c_code.opcode)),
1281 conctcode (Expr_Node_Gen_Reloc (psoffset, BFD_RELOC_BFIN_5_PCREL),
1282 conctcode (gencode (LO (c_code.opcode)), Expr_Node_Gen_Reloc (peoffset, BFD_RELOC_BFIN_11_PCREL))));
1283
1284}
1285
1286/* Call, Link. */
1287
1288INSTR_T
1289bfin_gen_calla (Expr_Node * addr, int S)
1290{
1291 int val;
1292 int high_val;
1293 int reloc = 0;
1294 INIT (CALLa);
1295
1296 switch(S){
1297 case 0 : reloc = BFD_RELOC_BFIN_24_PCREL_JUMP_L; break;
1298 case 1 : reloc = BFD_RELOC_24_PCREL; break;
1299 case 2 : reloc = BFD_RELOC_BFIN_PLTPC; break;
1300 default : break;
1301 }
1302
1303 ASSIGN (S);
1304
1305 val = EXPR_VALUE (addr) >> 1;
1306 high_val = val >> 16;
1307
1308 return conscode (gencode (HI (c_code.opcode) | (high_val & 0xff)),
1309 Expr_Node_Gen_Reloc (addr, reloc));
1310 }
1311
1312INSTR_T
1313bfin_gen_linkage (int R, int framesize)
1314{
1315 INIT (Linkage);
1316
1317 ASSIGN (R);
1318 ASSIGN (framesize);
1319
1320 return GEN_OPCODE32 ();
1321}
1322
1323
1324/* Load and Store. */
1325
1326INSTR_T
1327bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int reloc)
1328{
1329 int grp, hword;
1330 unsigned val = EXPR_VALUE (phword);
1331 INIT (LDIMMhalf);
1332
1333 ASSIGN (H);
1334 ASSIGN (S);
1335 ASSIGN (Z);
1336
1337 ASSIGN_R (reg);
1338 grp = (GROUP (reg));
1339 ASSIGN (grp);
1340 if (reloc == 2)
1341 {
1342 return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, BFD_RELOC_BFIN_16_IMM));
1343 }
1344 else if (reloc == 1)
1345 {
1346 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));
1347 }
1348 else
1349 {
1350 hword = val;
1351 ASSIGN (hword);
1352 }
1353 return GEN_OPCODE32 ();
1354}
1355
1356INSTR_T
1357bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset)
1358{
1359 int offset;
1360 int value = 0;
1361 INIT (LDSTidxI);
1362
1363 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1364 {
1365 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1366 return 0;
1367 }
1368
1369 ASSIGN_R (ptr);
1370 ASSIGN_R (reg);
1371 ASSIGN (W);
1372 ASSIGN (sz);
1373 switch (sz)
1374 {
1375 case 0:
1376 value = EXPR_VALUE (poffset) >> 2;
1377 break;
1378 case 1:
1379 value = EXPR_VALUE (poffset) >> 1;
1380 break;
1381 case 2:
1382 value = EXPR_VALUE (poffset);
1383 break;
1384 }
1385
1386
1387 ASSIGN (Z);
1388
1389 offset = (value & 0xffff);
1390 ASSIGN (offset);
1391 /* TODO : test if you need to check this here.
1392 The reloc case should automatically generate instruction
1393 if constant. */
1394 if(poffset->type != Expr_Node_Constant){
1395 /* A GOT relocation such as R0 = [P5 + symbol@GOT].
1396 Distinguish between R0 = [P5 + symbol@GOT] and
1397 P5 = [P5 + _current_shared_library_p5_offset_]. */
1398 if(!strcmp(poffset->value.s_value, "_current_shared_library_p5_offset_")){
1399 return conscode (gencode (HI (c_code.opcode)),
1400 Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16));
1401 }
1402 else
1403 {
1404 return conscode (gencode (HI (c_code.opcode)),
1405 Expr_Node_Gen_Reloc(poffset, BFD_RELOC_BFIN_GOT));
1406 }
1407 }
1408 else{
1409 return GEN_OPCODE32 ();
1410 }
1411}
1412
1413
1414INSTR_T
1415bfin_gen_ldst (REG_T ptr, REG_T reg, int aop, int sz, int Z, int W)
1416{
1417 INIT (LDST);
1418
1419 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1420 {
1421 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1422 return 0;
1423 }
1424
1425 ASSIGN_R (ptr);
1426 ASSIGN_R (reg);
1427 ASSIGN (aop);
1428 ASSIGN (sz);
1429 ASSIGN (Z);
1430 ASSIGN (W);
1431
1432 return GEN_OPCODE16 ();
1433}
1434
1435INSTR_T
1436bfin_gen_ldstii (REG_T ptr, REG_T reg, Expr_Node * poffset, int W, int op)
1437{
1438 int offset;
1439 int value = 0;
1440 INIT (LDSTii);
1441
1442
1443 if (!IS_PREG (*ptr))
1444 {
1445 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1446 return 0;
1447 }
1448
1449 switch (op)
1450 {
1451 case 1:
1452 case 2:
1453 value = EXPR_VALUE (poffset) >> 1;
1454 break;
1455 case 0:
1456 case 3:
1457 value = EXPR_VALUE (poffset) >> 2;
1458 break;
1459 }
1460
1461 ASSIGN_R (ptr);
1462 ASSIGN_R (reg);
1463
1464 offset = value;
1465 ASSIGN (offset);
1466 ASSIGN (W);
1467 ASSIGN (op);
1468
1469 return GEN_OPCODE16 ();
1470}
1471
1472INSTR_T
1473bfin_gen_ldstiifp (REG_T sreg, Expr_Node * poffset, int W)
1474{
1475 /* Set bit 4 if it's a Preg. */
1476 int reg = (sreg->regno & CODE_MASK) | (IS_PREG (*sreg) ? 0x8 : 0x0);
1477 int offset = ((~(EXPR_VALUE (poffset) >> 2)) & 0x1f) + 1;
1478 INIT (LDSTiiFP);
1479 ASSIGN (reg);
1480 ASSIGN (offset);
1481 ASSIGN (W);
1482
1483 return GEN_OPCODE16 ();
1484}
1485
1486INSTR_T
1487bfin_gen_ldstpmod (REG_T ptr, REG_T reg, int aop, int W, REG_T idx)
1488{
1489 INIT (LDSTpmod);
1490
1491 ASSIGN_R (ptr);
1492 ASSIGN_R (reg);
1493 ASSIGN (aop);
1494 ASSIGN (W);
1495 ASSIGN_R (idx);
1496
1497 return GEN_OPCODE16 ();
1498}
1499
1500INSTR_T
1501bfin_gen_dspldst (REG_T i, REG_T reg, int aop, int W, int m)
1502{
1503 INIT (DspLDST);
1504
1505 ASSIGN_R (i);
1506 ASSIGN_R (reg);
1507 ASSIGN (aop);
1508 ASSIGN (W);
1509 ASSIGN (m);
1510
1511 return GEN_OPCODE16 ();
1512}
1513
1514INSTR_T
1515bfin_gen_logi2op (int opc, int src, int dst)
1516{
1517 INIT (LOGI2op);
1518
1519 ASSIGN (opc);
1520 ASSIGN (src);
1521 ASSIGN (dst);
1522
1523 return GEN_OPCODE16 ();
1524}
1525
1526INSTR_T
1527bfin_gen_brcc (int T, int B, Expr_Node * poffset)
1528{
1529 int offset;
1530 INIT (BRCC);
1531
1532 ASSIGN (T);
1533 ASSIGN (B);
1534 offset = ((EXPR_VALUE (poffset) >> 1));
1535 ASSIGN (offset);
1536 return conscode (gencode (c_code.opcode), Expr_Node_Gen_Reloc (poffset, BFD_RELOC_BFIN_10_PCREL));
1537}
1538
1539INSTR_T
1540bfin_gen_ujump (Expr_Node * poffset)
1541{
1542 int offset;
1543 INIT (UJump);
1544
1545 offset = ((EXPR_VALUE (poffset) >> 1));
1546 ASSIGN (offset);
1547
1548 return conscode (gencode (c_code.opcode),
1549 Expr_Node_Gen_Reloc (
1550 poffset, BFD_RELOC_BFIN_12_PCREL_JUMP_S));
1551}
1552
1553INSTR_T
1554bfin_gen_alu2op (REG_T dst, REG_T src, int opc)
1555{
1556 INIT (ALU2op);
1557
1558 ASSIGN_R (dst);
1559 ASSIGN_R (src);
1560 ASSIGN (opc);
1561
1562 return GEN_OPCODE16 ();
1563}
1564
1565INSTR_T
1566bfin_gen_compi2opd (REG_T dst, int src, int op)
1567{
1568 INIT (COMPI2opD);
1569
1570 ASSIGN_R (dst);
1571 ASSIGN (src);
1572 ASSIGN (op);
1573
1574 return GEN_OPCODE16 ();
1575}
1576
1577INSTR_T
1578bfin_gen_compi2opp (REG_T dst, int src, int op)
1579{
1580 INIT (COMPI2opP);
1581
1582 ASSIGN_R (dst);
1583 ASSIGN (src);
1584 ASSIGN (op);
1585
1586 return GEN_OPCODE16 ();
1587}
1588
1589INSTR_T
1590bfin_gen_dagmodik (REG_T i, int op)
1591{
1592 INIT (DagMODik);
1593
1594 ASSIGN_R (i);
1595 ASSIGN (op);
1596
1597 return GEN_OPCODE16 ();
1598}
1599
1600INSTR_T
1601bfin_gen_dagmodim (REG_T i, REG_T m, int op, int br)
1602{
1603 INIT (DagMODim);
1604
1605 ASSIGN_R (i);
1606 ASSIGN_R (m);
1607 ASSIGN (op);
1608 ASSIGN (br);
1609
1610 return GEN_OPCODE16 ();
1611}
1612
1613INSTR_T
1614bfin_gen_ptr2op (REG_T dst, REG_T src, int opc)
1615{
1616 INIT (PTR2op);
1617
1618 ASSIGN_R (dst);
1619 ASSIGN_R (src);
1620 ASSIGN (opc);
1621
1622 return GEN_OPCODE16 ();
1623}
1624
1625INSTR_T
1626bfin_gen_comp3op (REG_T src0, REG_T src1, REG_T dst, int opc)
1627{
1628 INIT (COMP3op);
1629
1630 ASSIGN_R (src0);
1631 ASSIGN_R (src1);
1632 ASSIGN_R (dst);
1633 ASSIGN (opc);
1634
1635 return GEN_OPCODE16 ();
1636}
1637
1638INSTR_T
1639bfin_gen_ccflag (REG_T x, int y, int opc, int I, int G)
1640{
1641 INIT (CCflag);
1642
1643 ASSIGN_R (x);
1644 ASSIGN (y);
1645 ASSIGN (opc);
1646 ASSIGN (I);
1647 ASSIGN (G);
1648
1649 return GEN_OPCODE16 ();
1650}
1651
1652INSTR_T
1653bfin_gen_ccmv (REG_T src, REG_T dst, int T)
1654{
1655 int s, d;
1656 INIT (CCmv);
1657
1658 ASSIGN_R (src);
1659 ASSIGN_R (dst);
1660 s = (GROUP (src));
1661 ASSIGN (s);
1662 d = (GROUP (dst));
1663 ASSIGN (d);
1664 ASSIGN (T);
1665
1666 return GEN_OPCODE16 ();
1667}
1668
1669INSTR_T
1670bfin_gen_cc2stat (int cbit, int op, int D)
1671{
1672 INIT (CC2stat);
1673
1674 ASSIGN (cbit);
1675 ASSIGN (op);
1676 ASSIGN (D);
1677
1678 return GEN_OPCODE16 ();
1679}
1680
1681INSTR_T
1682bfin_gen_regmv (REG_T src, REG_T dst)
1683{
1684 int gs, gd;
1685 INIT (RegMv);
1686
1687 ASSIGN_R (src);
1688 ASSIGN_R (dst);
1689
1690 gs = (GROUP (src));
1691 ASSIGN (gs);
1692 gd = (GROUP (dst));
1693 ASSIGN (gd);
1694
1695 return GEN_OPCODE16 ();
1696}
1697
1698INSTR_T
1699bfin_gen_cc2dreg (int op, REG_T reg)
1700{
1701 INIT (CC2dreg);
1702
1703 ASSIGN (op);
1704 ASSIGN_R (reg);
1705
1706 return GEN_OPCODE16 ();
1707}
1708
1709INSTR_T
1710bfin_gen_progctrl (int prgfunc, int poprnd)
1711{
1712 INIT (ProgCtrl);
1713
1714 ASSIGN (prgfunc);
1715 ASSIGN (poprnd);
1716
1717 return GEN_OPCODE16 ();
1718}
1719
1720INSTR_T
1721bfin_gen_cactrl (REG_T reg, int a, int op)
1722{
1723 INIT (CaCTRL);
1724
1725 ASSIGN_R (reg);
1726 ASSIGN (a);
1727 ASSIGN (op);
1728
1729 return GEN_OPCODE16 ();
1730}
1731
1732INSTR_T
1733bfin_gen_pushpopmultiple (int dr, int pr, int d, int p, int W)
1734{
1735 INIT (PushPopMultiple);
1736
1737 ASSIGN (dr);
1738 ASSIGN (pr);
1739 ASSIGN (d);
1740 ASSIGN (p);
1741 ASSIGN (W);
1742
1743 return GEN_OPCODE16 ();
1744}
1745
1746INSTR_T
1747bfin_gen_pushpopreg (REG_T reg, int W)
1748{
1749 int grp;
1750 INIT (PushPopReg);
1751
1752 ASSIGN_R (reg);
1753 grp = (GROUP (reg));
1754 ASSIGN (grp);
1755 ASSIGN (W);
1756
1757 return GEN_OPCODE16 ();
1758}
1759
1760/* Pseudo Debugging Support. */
1761
1762INSTR_T
1763bfin_gen_pseudodbg (int fn, int reg, int grp)
1764{
1765 INIT (PseudoDbg);
1766
1767 ASSIGN (fn);
1768 ASSIGN (reg);
1769 ASSIGN (grp);
1770
1771 return GEN_OPCODE16 ();
1772}
1773
1774INSTR_T
1775bfin_gen_pseudodbg_assert (int dbgop, REG_T regtest, int expected)
1776{
1777 INIT (PseudoDbg_Assert);
1778
1779 ASSIGN (dbgop);
1780 ASSIGN_R (regtest);
1781 ASSIGN (expected);
1782
1783 return GEN_OPCODE32 ();
1784}
1785
1786/* Multiple instruction generation. */
1787
1788INSTR_T
1789bfin_gen_multi_instr (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2)
1790{
1791 INSTR_T walk;
1792
1793 /* If it's a 0, convert into MNOP. */
1794 if (dsp32)
1795 {
1796 walk = dsp32->next;
1797 SET_MULTI_INSTRUCTION_BIT (dsp32);
1798 }
1799 else
1800 {
1801 dsp32 = gencode (0xc803);
1802 walk = gencode (0x1800);
1803 dsp32->next = walk;
1804 }
1805
1806 if (!dsp16_grp1)
1807 {
1808 dsp16_grp1 = gencode (0x0000);
1809 }
1810
1811 if (!dsp16_grp2)
1812 {
1813 dsp16_grp2 = gencode (0x0000);
1814 }
1815
1816 walk->next = dsp16_grp1;
1817 dsp16_grp1->next = dsp16_grp2;
1818 dsp16_grp2->next = NULL_CODE;
1819
1820 return dsp32;
1821}
1822
1823INSTR_T
1824bfin_gen_loop (Expr_Node *expr, REG_T reg, int rop, REG_T preg)
1825{
1826 const char *loopsym;
1827 char *lbeginsym, *lendsym;
1828 Expr_Node_Value lbeginval, lendval;
1829 Expr_Node *lbegin, *lend;
1830
1831 loopsym = expr->value.s_value;
1832 lbeginsym = (char *) xmalloc (strlen (loopsym) + strlen ("__BEGIN") + 1);
1833 lendsym = (char *) xmalloc (strlen (loopsym) + strlen ("__END") + 1);
1834
1835 lbeginsym[0] = 0;
1836 lendsym[0] = 0;
1837
1838 strcat (lbeginsym, loopsym);
1839 strcat (lbeginsym, "__BEGIN");
1840
1841 strcat (lendsym, loopsym);
1842 strcat (lendsym, "__END");
1843
1844 lbeginval.s_value = lbeginsym;
1845 lendval.s_value = lendsym;
1846
1847 lbegin = Expr_Node_Create (Expr_Node_Reloc, lbeginval, NULL, NULL);
1848 lend = Expr_Node_Create (Expr_Node_Reloc, lendval, NULL, NULL);
1849 return bfin_gen_loopsetup(lbegin, reg, rop, lend, preg);
1850}
1851
1852bfd_boolean
1853bfin_eol_in_insn (char *line)
1854{
1855 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1856
1857 char *temp = line;
1858
1859 if (*line != '\n')
1860 return FALSE;
1861
1862 /* A semi-colon followed by a newline is always the end of a line. */
1863 if (line[-1] == ';')
1864 return FALSE;
1865
1866 if (line[-1] == '|')
1867 return TRUE;
1868
1869 /* If the || is on the next line, there might be leading whitespace. */
1870 temp++;
1871 while (*temp == ' ' || *temp == '\t') temp++;
1872
1873 if (*temp == '|')
1874 return TRUE;
1875
1876 return FALSE;
1877}
1878
1879bfd_boolean
1880bfin_name_is_register (char *name)
1881{
1882 int i;
1883
1884 if (*name == '[' || *name == '(')
1885 return TRUE;
1886
1887 if ((name[0] == 'W' || name[0] == 'w') && name[1] == '[')
1888 return TRUE;
1889
1890 if ((name[0] == 'B' || name[0] == 'b') && name[1] == '[')
1891 return TRUE;
1892
07c1b327
CM
1893 for (i=0; bfin_reg_info[i].name != 0; i++)
1894 {
1895 if (!strcasecmp (bfin_reg_info[i].name, name))
1896 return TRUE;
1897 }
1898 return FALSE;
1899}
1900
1901void
1902bfin_equals (Expr_Node *sym)
1903{
1904 char *c;
1905
1906 c = input_line_pointer;
1907 while (*c != '=')
1908 c--;
1909
1910 input_line_pointer = c;
1911
1912 equals ((char *) sym->value.s_value, 1);
1913}
1914
1915bfd_boolean
1916bfin_start_label (char *ptr)
1917{
1918 ptr--;
1919 while (!ISSPACE (*ptr) && !is_end_of_line[(unsigned char) *ptr])
1920 ptr--;
1921
1922 ptr++;
1923 if (*ptr == '(' || *ptr == '[')
1924 return FALSE;
1925
07c1b327
CM
1926 return TRUE;
1927}
1928
1929int
1930bfin_force_relocation (struct fix *fixp)
1931{
1932 if (fixp->fx_r_type ==BFD_RELOC_BFIN_16_LOW
1933 || fixp->fx_r_type == BFD_RELOC_BFIN_16_HIGH)
1934 return TRUE;
1935
1936 return generic_force_reloc (fixp);
1937}
This page took 0.1901 seconds and 4 git commands to generate.