]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-bfin.c
* elf32-bfin.c (bfin_howto_table): Set src_mask to 0 for all relocs.
[thirdparty/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));
39static int md_chars_to_number PARAMS ((unsigned char *, int));
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
456md_chars_to_number (val, n)
457 unsigned char *val; /* Value in target byte order. */
458 int n; /* Number of bytes in the input. */
459{
460 int retval;
461
462 for (retval = 0; n--;)
463 {
464 retval <<= 8;
465 retval |= val[n];
466 }
467 return retval;
468}
469
470void
471md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
472{
473 char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
474
475 long value = *valueP;
476 long newval;
477
478 switch (fixP->fx_r_type)
479 {
480 case BFD_RELOC_BFIN_GOT:
481 fixP->fx_no_overflow = 1;
482 newval = md_chars_to_number (where, 2);
483 newval |= 0x0 & 0x7f;
484 md_number_to_chars (where, newval, 2);
485 break;
486
487 case BFD_RELOC_BFIN_10_PCREL:
488 if (!value)
489 break;
490 if (value < -1024 || value > 1022)
491 as_bad_where (fixP->fx_file, fixP->fx_line,
492 "pcrel too far BFD_RELOC_BFIN_10");
493
494 /* 11 bit offset even numbered, so we remove right bit. */
495 value = value >> 1;
496 newval = md_chars_to_number (where, 2);
497 newval |= value & 0x03ff;
498 md_number_to_chars (where, newval, 2);
499 break;
500
501 case BFD_RELOC_BFIN_12_PCREL_JUMP:
502 case BFD_RELOC_BFIN_12_PCREL_JUMP_S:
503 case BFD_RELOC_12_PCREL:
504 if (!value)
505 break;
506
507 if (value < -4096 || value > 4094)
508 as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far BFD_RELOC_BFIN_12");
509 /* 13 bit offset even numbered, so we remove right bit. */
510 value = value >> 1;
511 newval = md_chars_to_number (where, 2);
512 newval |= value & 0xfff;
513 md_number_to_chars (where, newval, 2);
514 break;
515
516 case BFD_RELOC_BFIN_16_LOW:
517 case BFD_RELOC_BFIN_16_HIGH:
518 fixP->fx_done = FALSE;
519 break;
520
521 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
522 case BFD_RELOC_BFIN_24_PCREL_CALL_X:
523 case BFD_RELOC_24_PCREL:
524 if (!value)
525 break;
526
527 if (value < -16777216 || value > 16777214)
528 as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far BFD_RELOC_BFIN_24");
529
530 /* 25 bit offset even numbered, so we remove right bit. */
531 value = value >> 1;
532 value++;
533
534 md_number_to_chars (where - 2, value >> 16, 1);
535 md_number_to_chars (where, value, 1);
536 md_number_to_chars (where + 1, value >> 8, 1);
537 break;
538
539 case BFD_RELOC_BFIN_5_PCREL: /* LSETUP (a, b) : "a" */
540 if (!value)
541 break;
542 if (value < 4 || value > 30)
543 as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far BFD_RELOC_BFIN_5");
544 value = value >> 1;
545 newval = md_chars_to_number (where, 1);
546 newval = (newval & 0xf0) | (value & 0xf);
547 md_number_to_chars (where, newval, 1);
548 break;
549
550 case BFD_RELOC_BFIN_11_PCREL: /* LSETUP (a, b) : "b" */
551 if (!value)
552 break;
553 value += 2;
554 if (value < 4 || value > 2046)
555 as_bad_where (fixP->fx_file, fixP->fx_line, "pcrel too far BFD_RELOC_BFIN_11_PCREL");
556 /* 11 bit unsigned even, so we remove right bit. */
557 value = value >> 1;
558 newval = md_chars_to_number (where, 2);
559 newval |= value & 0x03ff;
560 md_number_to_chars (where, newval, 2);
561 break;
562
563 case BFD_RELOC_8:
564 if (value < -0x80 || value >= 0x7f)
565 as_bad_where (fixP->fx_file, fixP->fx_line, "rel too far BFD_RELOC_8");
566 md_number_to_chars (where, value, 1);
567 break;
568
569 case BFD_RELOC_BFIN_16_IMM:
570 case BFD_RELOC_16:
571 if (value < -0x8000 || value >= 0x7fff)
572 as_bad_where (fixP->fx_file, fixP->fx_line, "rel too far BFD_RELOC_8");
573 md_number_to_chars (where, value, 2);
574 break;
575
576 case BFD_RELOC_32:
577 md_number_to_chars (where, value, 4);
578 break;
579
580 case BFD_RELOC_BFIN_PLTPC:
581 md_number_to_chars (where, value, 2);
582 break;
583
584 case BFD_RELOC_VTABLE_INHERIT:
585 case BFD_RELOC_VTABLE_ENTRY:
586 fixP->fx_done = FALSE;
587 break;
588
589 default:
590 if ((BFD_ARELOC_BFIN_PUSH > fixP->fx_r_type) || (BFD_ARELOC_BFIN_COMP < fixP->fx_r_type))
591 {
592 fprintf (stderr, "Relocation %d not handled in gas." " Contact support.\n", fixP->fx_r_type);
593 return;
594 }
595 }
596
597 if (!fixP->fx_addsy)
598 fixP->fx_done = TRUE;
599
600}
601
602/* Round up a section size to the appropriate boundary. */
603valueT
604md_section_align (segment, size)
605 segT segment;
606 valueT size;
607{
608 int boundary = bfd_get_section_alignment (stdoutput, segment);
609 return ((size + (1 << boundary) - 1) & (-1 << boundary));
610}
611
612
613/* Turn a string in input_line_pointer into a floating point
614 constant of type type, and store the appropriate bytes in
615 *litP. The number of LITTLENUMS emitted is stored in *sizeP.
616 An error message is returned, or NULL on OK. */
617
618/* Equal to MAX_PRECISION in atof-ieee.c. */
619#define MAX_LITTLENUMS 6
620
621char *
622md_atof (type, litP, sizeP)
623 char type;
624 char * litP;
625 int * sizeP;
626{
627 int prec;
628 LITTLENUM_TYPE words [MAX_LITTLENUMS];
629 LITTLENUM_TYPE *wordP;
630 char * t;
631
632 switch (type)
633 {
634 case 'f':
635 case 'F':
636 prec = 2;
637 break;
638
639 case 'd':
640 case 'D':
641 prec = 4;
642 break;
643
644 /* FIXME: Some targets allow other format chars for bigger sizes here. */
645
646 default:
647 *sizeP = 0;
648 return _("Bad call to md_atof()");
649 }
650
651 t = atof_ieee (input_line_pointer, type, words);
652 if (t)
653 input_line_pointer = t;
654 *sizeP = prec * sizeof (LITTLENUM_TYPE);
655
656 *sizeP = prec * sizeof (LITTLENUM_TYPE);
657 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
658 the littleendianness of the processor. */
659 for (wordP = words + prec - 1; prec--;)
660 {
661 md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
662 litP += sizeof (LITTLENUM_TYPE);
663 }
664
665 return 0;
666}
667
668
669/* If while processing a fixup, a reloc really needs to be created
670 then it is done here. */
671
672arelent *
673tc_gen_reloc (seg, fixp)
674 asection *seg ATTRIBUTE_UNUSED;
675 fixS *fixp;
676{
677 arelent *reloc;
678
679 reloc = (arelent *) xmalloc (sizeof (arelent));
680 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
681 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
682 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
683
684 reloc->addend = fixp->fx_offset;
685 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
686
687 if (reloc->howto == (reloc_howto_type *) NULL)
688 {
689 as_bad_where (fixp->fx_file, fixp->fx_line,
690 /* xgettext:c-format. */
691 _("reloc %d not supported by object file format"),
692 (int) fixp->fx_r_type);
693
694 xfree (reloc);
695
696 return NULL;
697 }
698
699 return reloc;
700}
701
702/* The location from which a PC relative jump should be calculated,
703 given a PC relative reloc. */
704
705long
706md_pcrel_from_section (fixP, sec)
707 fixS *fixP;
708 segT sec;
709{
710 if (fixP->fx_addsy != (symbolS *) NULL
711 && (!S_IS_DEFINED (fixP->fx_addsy)
712 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
713 {
714 /* The symbol is undefined (or is defined but not in this section).
715 Let the linker figure it out. */
716 return 0;
717 }
718 return fixP->fx_frag->fr_address + fixP->fx_where;
719}
720
721/* Return true if the fix can be handled by GAS, false if it must
722 be passed through to the linker. */
723
724bfd_boolean
725bfin_fix_adjustable (fixS *fixP)
726{
727 switch (fixP->fx_r_type)
728 {
729 /* Adjust_reloc_syms doesn't know about the GOT. */
730 case BFD_RELOC_BFIN_GOT :
731 case BFD_RELOC_BFIN_PLTPC :
732 /* We need the symbol name for the VTABLE entries. */
733 case BFD_RELOC_VTABLE_INHERIT:
734 case BFD_RELOC_VTABLE_ENTRY:
735 return 0;
736
737 default:
738 return 1;
739 }
740}
741
742
743/* Handle the LOOP_BEGIN and LOOP_END statements.
744 Parse the Loop_Begin/Loop_End and create a label. */
745void
746bfin_start_line_hook ()
747{
748 bfd_boolean maybe_begin = FALSE;
749 bfd_boolean maybe_end = FALSE;
750
751 char *c1, *label_name;
752 symbolS *line_label;
753 char *c = input_line_pointer;
754
755 while (ISSPACE (*c))
756 c++;
757
07c1b327
CM
758 /* Look for Loop_Begin or Loop_End statements. */
759
760 if (*c != 'L' && *c != 'l')
761 return;
762
763 c++;
764 if (*c != 'O' && *c != 'o')
765 return;
766
767 c++;
768 if (*c != 'O' && *c != 'o')
769 return;
770
771 c++;
772 if (*c != 'P' && *c != 'p')
773 return;
774
775 c++;
776 if (*c != '_')
777 return;
778
779 c++;
780 if (*c == 'E' || *c == 'e')
781 maybe_end = TRUE;
782 else if (*c == 'B' || *c == 'b')
783 maybe_begin = TRUE;
784 else
785 return;
786
787 if (maybe_end)
788 {
789 c++;
790 if (*c != 'N' && *c != 'n')
791 return;
792
793 c++;
794 if (*c != 'D' && *c != 'd')
795 return;
796 }
797
798 if (maybe_begin)
799 {
800 c++;
801 if (*c != 'E' && *c != 'e')
802 return;
803
804 c++;
805 if (*c != 'G' && *c != 'g')
806 return;
807
808 c++;
809 if (*c != 'I' && *c != 'i')
810 return;
811
812 c++;
813 if (*c != 'N' && *c != 'n')
814 return;
815 }
816
817 c++;
818 while (ISSPACE (*c)) c++;
819 c1 = c;
820 while (ISALPHA (*c) || ISDIGIT (*c) || *c == '_') c++;
821
822 input_line_pointer = c;
823 if (maybe_end)
824 {
825 label_name = (char *) xmalloc ((c - c1) + strlen ("__END") + 1);
826 label_name[0] = 0;
827 strncat (label_name, c1, c-c1);
828 strcat (label_name, "__END");
829 }
830 else /* maybe_begin. */
831 {
832 label_name = (char *) xmalloc ((c - c1) + strlen ("__BEGIN") + 1);
833 label_name[0] = 0;
834 strncat (label_name, c1, c-c1);
835 strcat (label_name, "__BEGIN");
836 }
837
838 line_label = colon (label_name);
839
840 /* Loop_End follows the last instruction in the loop.
841 Adjust label address. */
842 if (maybe_end)
843 line_label->sy_value.X_add_number -= last_insn_size;
844
845}
846
847/* Special extra functions that help bfin-parse.y perform its job. */
848
849#include <stdio.h>
850#include <assert.h>
851#include <obstack.h>
852#include <bfd.h>
853#include "bfin-defs.h"
854
855struct obstack mempool;
856
857INSTR_T
858conscode (INSTR_T head, INSTR_T tail)
859{
860 if (!head)
861 return tail;
862 head->next = tail;
863 return head;
864}
865
866INSTR_T
867conctcode (INSTR_T head, INSTR_T tail)
868{
869 INSTR_T temp = (head);
870 if (!head)
871 return tail;
872 while (temp->next)
873 temp = temp->next;
874 temp->next = tail;
875
876 return head;
877}
878
879INSTR_T
880note_reloc (INSTR_T code, Expr_Node * symbol, int reloc, int pcrel)
881{
882 /* Assert that the symbol is not an operator. */
883 assert (symbol->type == Expr_Node_Reloc);
884
885 return note_reloc1 (code, symbol->value.s_value, reloc, pcrel);
886
887}
888
889INSTR_T
890note_reloc1 (INSTR_T code, const char *symbol, int reloc, int pcrel)
891{
892 code->reloc = reloc;
893 code->exp = mkexpr (0, symbol_find_or_make (symbol));
894 code->pcrel = pcrel;
895 return code;
896}
897
898INSTR_T
899note_reloc2 (INSTR_T code, const char *symbol, int reloc, int value, int pcrel)
900{
901 code->reloc = reloc;
902 code->exp = mkexpr (value, symbol_find_or_make (symbol));
903 code->pcrel = pcrel;
904 return code;
905}
906
907INSTR_T
908gencode (unsigned long x)
909{
910 INSTR_T cell = (INSTR_T) obstack_alloc (&mempool, sizeof (struct bfin_insn));
911 memset (cell, 0, sizeof (struct bfin_insn));
912 cell->value = (x);
913 return cell;
914}
915
916int reloc;
917int ninsns;
918int count_insns;
919
920static void *
921allocate (int n)
922{
923 return (void *) obstack_alloc (&mempool, n);
924}
925
926Expr_Node *
927Expr_Node_Create (Expr_Node_Type type,
928 Expr_Node_Value value,
929 Expr_Node *Left_Child,
930 Expr_Node *Right_Child)
931{
932
933
934 Expr_Node *node = (Expr_Node *) allocate (sizeof (Expr_Node));
935 node->type = type;
936 node->value = value;
937 node->Left_Child = Left_Child;
938 node->Right_Child = Right_Child;
939 return node;
940}
941
942static const char *con = ".__constant";
943static const char *op = ".__operator";
944static INSTR_T Expr_Node_Gen_Reloc_R (Expr_Node * head);
945INSTR_T Expr_Node_Gen_Reloc (Expr_Node *head, int parent_reloc);
946
947INSTR_T
948Expr_Node_Gen_Reloc (Expr_Node * head, int parent_reloc)
949{
950 /* Top level reloction expression generator VDSP style.
951 If the relocation is just by itself, generate one item
952 else generate this convoluted expression. */
953
954 INSTR_T note = NULL_CODE;
955 INSTR_T note1 = NULL_CODE;
956 int pcrel = 1; /* Is the parent reloc pcrelative?
957 This calculation here and HOWTO should match. */
958
959 if (parent_reloc)
960 {
961 /* If it's 32 bit quantity then 16bit code needs to be added. */
962 int value = 0;
963
964 if (head->type == Expr_Node_Constant)
965 {
966 /* If note1 is not null code, we have to generate a right
967 aligned value for the constant. Otherwise the reloc is
968 a part of the basic command and the yacc file
969 generates this. */
970 value = head->value.i_value;
971 }
972 switch (parent_reloc)
973 {
974 /* Some reloctions will need to allocate extra words. */
975 case BFD_RELOC_BFIN_16_IMM:
976 case BFD_RELOC_BFIN_16_LOW:
977 case BFD_RELOC_BFIN_16_HIGH:
978 note1 = conscode (gencode (value), NULL_CODE);
979 pcrel = 0;
980 break;
981 case BFD_RELOC_BFIN_PLTPC:
982 note1 = conscode (gencode (value), NULL_CODE);
983 pcrel = 0;
984 break;
985 case BFD_RELOC_16:
986 case BFD_RELOC_BFIN_GOT:
987 note1 = conscode (gencode (value), NULL_CODE);
988 pcrel = 0;
989 break;
990 case BFD_RELOC_24_PCREL:
991 case BFD_RELOC_BFIN_24_PCREL_JUMP_L:
992 case BFD_RELOC_BFIN_24_PCREL_CALL_X:
993 /* These offsets are even numbered pcrel. */
994 note1 = conscode (gencode (value >> 1), NULL_CODE);
995 break;
996 default:
997 note1 = NULL_CODE;
998 }
999 }
1000 if (head->type == Expr_Node_Constant)
1001 note = note1;
1002 else if (head->type == Expr_Node_Reloc)
1003 {
1004 note = note_reloc1 (gencode (0), head->value.s_value, parent_reloc, pcrel);
1005 if (note1 != NULL_CODE)
1006 note = conscode (note1, note);
1007 }
1008 else
1009 {
1010 /* Call the recursive function. */
1011 note = note_reloc1 (gencode (0), op, parent_reloc, pcrel);
1012 if (note1 != NULL_CODE)
1013 note = conscode (note1, note);
1014 note = conctcode (Expr_Node_Gen_Reloc_R (head), note);
1015 }
1016 return note;
1017}
1018
1019static INSTR_T
1020Expr_Node_Gen_Reloc_R (Expr_Node * head)
1021{
1022
1023 INSTR_T note = 0;
1024 INSTR_T note1 = 0;
1025
1026 switch (head->type)
1027 {
1028 case Expr_Node_Constant:
1029 note = conscode (note_reloc2 (gencode (0), con, BFD_ARELOC_BFIN_CONST, head->value.i_value, 0), NULL_CODE);
1030 break;
1031 case Expr_Node_Reloc:
1032 note = conscode (note_reloc (gencode (0), head, BFD_ARELOC_BFIN_PUSH, 0), NULL_CODE);
1033 break;
1034 case Expr_Node_Binop:
1035 note1 = conctcode (Expr_Node_Gen_Reloc_R (head->Left_Child), Expr_Node_Gen_Reloc_R (head->Right_Child));
1036 switch (head->value.op_value)
1037 {
1038 case Expr_Op_Type_Add:
1039 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_ADD, 0), NULL_CODE));
1040 break;
1041 case Expr_Op_Type_Sub:
1042 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_SUB, 0), NULL_CODE));
1043 break;
1044 case Expr_Op_Type_Mult:
1045 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MULT, 0), NULL_CODE));
1046 break;
1047 case Expr_Op_Type_Div:
1048 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_DIV, 0), NULL_CODE));
1049 break;
1050 case Expr_Op_Type_Mod:
1051 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_MOD, 0), NULL_CODE));
1052 break;
1053 case Expr_Op_Type_Lshift:
1054 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LSHIFT, 0), NULL_CODE));
1055 break;
1056 case Expr_Op_Type_Rshift:
1057 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_RSHIFT, 0), NULL_CODE));
1058 break;
1059 case Expr_Op_Type_BAND:
1060 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_AND, 0), NULL_CODE));
1061 break;
1062 case Expr_Op_Type_BOR:
1063 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_OR, 0), NULL_CODE));
1064 break;
1065 case Expr_Op_Type_BXOR:
1066 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_XOR, 0), NULL_CODE));
1067 break;
1068 case Expr_Op_Type_LAND:
1069 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LAND, 0), NULL_CODE));
1070 break;
1071 case Expr_Op_Type_LOR:
1072 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_LOR, 0), NULL_CODE));
1073 break;
1074 default:
1075 fprintf (stderr, "%s:%d:Unkonwn operator found for arithmetic" " relocation", __FILE__, __LINE__);
1076
1077
1078 }
1079 break;
1080 case Expr_Node_Unop:
1081 note1 = conscode (Expr_Node_Gen_Reloc_R (head->Left_Child), NULL_CODE);
1082 switch (head->value.op_value)
1083 {
1084 case Expr_Op_Type_NEG:
1085 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_NEG, 0), NULL_CODE));
1086 break;
1087 case Expr_Op_Type_COMP:
1088 note = conctcode (note1, conscode (note_reloc1 (gencode (0), op, BFD_ARELOC_BFIN_COMP, 0), NULL_CODE));
1089 break;
1090 default:
1091 fprintf (stderr, "%s:%d:Unkonwn operator found for arithmetic" " relocation", __FILE__, __LINE__);
1092 }
1093 break;
1094 default:
1095 fprintf (stderr, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__, __LINE__);
1096 }
1097 return note;
1098}
1099
1100
1101/* Blackfin opcode generation. */
1102
1103/* These functions are called by the generated parser
1104 (from bfin-parse.y), the register type classification
1105 happens in bfin-lex.l. */
1106
1107#include "bfin-aux.h"
1108#include "opcode/bfin.h"
1109
1110#define INIT(t) t c_code = init_##t
1111#define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1112#define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1113
1114#define HI(x) ((x >> 16) & 0xffff)
1115#define LO(x) ((x ) & 0xffff)
1116
1117#define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1118
1119#define GEN_OPCODE32() \
1120 conscode (gencode (HI (c_code.opcode)), \
1121 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1122
1123#define GEN_OPCODE16() \
1124 conscode (gencode (c_code.opcode), NULL_CODE)
1125
1126
1127/* 32 BIT INSTRUCTIONS. */
1128
1129
1130/* DSP32 instruction generation. */
1131
1132INSTR_T
1133bfin_gen_dsp32mac (int op1, int MM, int mmod, int w1, int P,
1134 int h01, int h11, int h00, int h10, int op0,
1135 REG_T dst, REG_T src0, REG_T src1, int w0)
1136{
1137 INIT (DSP32Mac);
1138
1139 ASSIGN (op0);
1140 ASSIGN (op1);
1141 ASSIGN (MM);
1142 ASSIGN (mmod);
1143 ASSIGN (w0);
1144 ASSIGN (w1);
1145 ASSIGN (h01);
1146 ASSIGN (h11);
1147 ASSIGN (h00);
1148 ASSIGN (h10);
1149 ASSIGN (P);
1150
1151 /* If we have full reg assignments, mask out LSB to encode
1152 single or simultaneous even/odd register moves. */
1153 if (P)
1154 {
1155 dst->regno &= 0x06;
1156 }
1157
1158 ASSIGN_R (dst);
1159 ASSIGN_R (src0);
1160 ASSIGN_R (src1);
1161
1162 return GEN_OPCODE32 ();
1163}
1164
1165INSTR_T
1166bfin_gen_dsp32mult (int op1, int MM, int mmod, int w1, int P,
1167 int h01, int h11, int h00, int h10, int op0,
1168 REG_T dst, REG_T src0, REG_T src1, int w0)
1169{
1170 INIT (DSP32Mult);
1171
1172 ASSIGN (op0);
1173 ASSIGN (op1);
1174 ASSIGN (MM);
1175 ASSIGN (mmod);
1176 ASSIGN (w0);
1177 ASSIGN (w1);
1178 ASSIGN (h01);
1179 ASSIGN (h11);
1180 ASSIGN (h00);
1181 ASSIGN (h10);
1182 ASSIGN (P);
1183
1184 if (P)
1185 {
1186 dst->regno &= 0x06;
1187 }
1188
1189 ASSIGN_R (dst);
1190 ASSIGN_R (src0);
1191 ASSIGN_R (src1);
1192
1193 return GEN_OPCODE32 ();
1194}
1195
1196INSTR_T
1197bfin_gen_dsp32alu (int HL, int aopcde, int aop, int s, int x,
1198 REG_T dst0, REG_T dst1, REG_T src0, REG_T src1)
1199{
1200 INIT (DSP32Alu);
1201
1202 ASSIGN (HL);
1203 ASSIGN (aopcde);
1204 ASSIGN (aop);
1205 ASSIGN (s);
1206 ASSIGN (x);
1207 ASSIGN_R (dst0);
1208 ASSIGN_R (dst1);
1209 ASSIGN_R (src0);
1210 ASSIGN_R (src1);
1211
1212 return GEN_OPCODE32 ();
1213}
1214
1215INSTR_T
1216bfin_gen_dsp32shift (int sopcde, REG_T dst0, REG_T src0,
1217 REG_T src1, int sop, int HLs)
1218{
1219 INIT (DSP32Shift);
1220
1221 ASSIGN (sopcde);
1222 ASSIGN (sop);
1223 ASSIGN (HLs);
1224
1225 ASSIGN_R (dst0);
1226 ASSIGN_R (src0);
1227 ASSIGN_R (src1);
1228
1229 return GEN_OPCODE32 ();
1230}
1231
1232INSTR_T
1233bfin_gen_dsp32shiftimm (int sopcde, REG_T dst0, int immag,
1234 REG_T src1, int sop, int HLs)
1235{
1236 INIT (DSP32ShiftImm);
1237
1238 ASSIGN (sopcde);
1239 ASSIGN (sop);
1240 ASSIGN (HLs);
1241
1242 ASSIGN_R (dst0);
1243 ASSIGN (immag);
1244 ASSIGN_R (src1);
1245
1246 return GEN_OPCODE32 ();
1247}
1248
1249/* LOOP SETUP. */
1250
1251INSTR_T
1252bfin_gen_loopsetup (Expr_Node * psoffset, REG_T c, int rop,
1253 Expr_Node * peoffset, REG_T reg)
1254{
1255 int soffset, eoffset;
1256 INIT (LoopSetup);
1257
1258 soffset = (EXPR_VALUE (psoffset) >> 1);
1259 ASSIGN (soffset);
1260 eoffset = (EXPR_VALUE (peoffset) >> 1);
1261 ASSIGN (eoffset);
1262 ASSIGN (rop);
1263 ASSIGN_R (c);
1264 ASSIGN_R (reg);
1265
1266 return
1267 conscode (gencode (HI (c_code.opcode)),
1268 conctcode (Expr_Node_Gen_Reloc (psoffset, BFD_RELOC_BFIN_5_PCREL),
1269 conctcode (gencode (LO (c_code.opcode)), Expr_Node_Gen_Reloc (peoffset, BFD_RELOC_BFIN_11_PCREL))));
1270
1271}
1272
1273/* Call, Link. */
1274
1275INSTR_T
1276bfin_gen_calla (Expr_Node * addr, int S)
1277{
1278 int val;
1279 int high_val;
1280 int reloc = 0;
1281 INIT (CALLa);
1282
1283 switch(S){
1284 case 0 : reloc = BFD_RELOC_BFIN_24_PCREL_JUMP_L; break;
1285 case 1 : reloc = BFD_RELOC_24_PCREL; break;
1286 case 2 : reloc = BFD_RELOC_BFIN_PLTPC; break;
1287 default : break;
1288 }
1289
1290 ASSIGN (S);
1291
1292 val = EXPR_VALUE (addr) >> 1;
1293 high_val = val >> 16;
1294
1295 return conscode (gencode (HI (c_code.opcode) | (high_val & 0xff)),
1296 Expr_Node_Gen_Reloc (addr, reloc));
1297 }
1298
1299INSTR_T
1300bfin_gen_linkage (int R, int framesize)
1301{
1302 INIT (Linkage);
1303
1304 ASSIGN (R);
1305 ASSIGN (framesize);
1306
1307 return GEN_OPCODE32 ();
1308}
1309
1310
1311/* Load and Store. */
1312
1313INSTR_T
1314bfin_gen_ldimmhalf (REG_T reg, int H, int S, int Z, Expr_Node * phword, int reloc)
1315{
1316 int grp, hword;
1317 unsigned val = EXPR_VALUE (phword);
1318 INIT (LDIMMhalf);
1319
1320 ASSIGN (H);
1321 ASSIGN (S);
1322 ASSIGN (Z);
1323
1324 ASSIGN_R (reg);
1325 grp = (GROUP (reg));
1326 ASSIGN (grp);
1327 if (reloc == 2)
1328 {
1329 return conscode (gencode (HI (c_code.opcode)), Expr_Node_Gen_Reloc (phword, BFD_RELOC_BFIN_16_IMM));
1330 }
1331 else if (reloc == 1)
1332 {
1333 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));
1334 }
1335 else
1336 {
1337 hword = val;
1338 ASSIGN (hword);
1339 }
1340 return GEN_OPCODE32 ();
1341}
1342
1343INSTR_T
1344bfin_gen_ldstidxi (REG_T ptr, REG_T reg, int W, int sz, int Z, Expr_Node * poffset)
1345{
1346 int offset;
1347 int value = 0;
1348 INIT (LDSTidxI);
1349
1350 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1351 {
1352 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1353 return 0;
1354 }
1355
1356 ASSIGN_R (ptr);
1357 ASSIGN_R (reg);
1358 ASSIGN (W);
1359 ASSIGN (sz);
1360 switch (sz)
1361 {
1362 case 0:
1363 value = EXPR_VALUE (poffset) >> 2;
1364 break;
1365 case 1:
1366 value = EXPR_VALUE (poffset) >> 1;
1367 break;
1368 case 2:
1369 value = EXPR_VALUE (poffset);
1370 break;
1371 }
1372
1373
1374 ASSIGN (Z);
1375
1376 offset = (value & 0xffff);
1377 ASSIGN (offset);
1378 /* TODO : test if you need to check this here.
1379 The reloc case should automatically generate instruction
1380 if constant. */
1381 if(poffset->type != Expr_Node_Constant){
1382 /* A GOT relocation such as R0 = [P5 + symbol@GOT].
1383 Distinguish between R0 = [P5 + symbol@GOT] and
1384 P5 = [P5 + _current_shared_library_p5_offset_]. */
1385 if(!strcmp(poffset->value.s_value, "_current_shared_library_p5_offset_")){
1386 return conscode (gencode (HI (c_code.opcode)),
1387 Expr_Node_Gen_Reloc(poffset, BFD_RELOC_16));
1388 }
1389 else
1390 {
1391 return conscode (gencode (HI (c_code.opcode)),
1392 Expr_Node_Gen_Reloc(poffset, BFD_RELOC_BFIN_GOT));
1393 }
1394 }
1395 else{
1396 return GEN_OPCODE32 ();
1397 }
1398}
1399
1400
1401INSTR_T
1402bfin_gen_ldst (REG_T ptr, REG_T reg, int aop, int sz, int Z, int W)
1403{
1404 INIT (LDST);
1405
1406 if (!IS_PREG (*ptr) || (!IS_DREG (*reg) && !Z))
1407 {
1408 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1409 return 0;
1410 }
1411
1412 ASSIGN_R (ptr);
1413 ASSIGN_R (reg);
1414 ASSIGN (aop);
1415 ASSIGN (sz);
1416 ASSIGN (Z);
1417 ASSIGN (W);
1418
1419 return GEN_OPCODE16 ();
1420}
1421
1422INSTR_T
1423bfin_gen_ldstii (REG_T ptr, REG_T reg, Expr_Node * poffset, int W, int op)
1424{
1425 int offset;
1426 int value = 0;
1427 INIT (LDSTii);
1428
1429
1430 if (!IS_PREG (*ptr))
1431 {
1432 fprintf (stderr, "Warning: possible mixup of Preg/Dreg\n");
1433 return 0;
1434 }
1435
1436 switch (op)
1437 {
1438 case 1:
1439 case 2:
1440 value = EXPR_VALUE (poffset) >> 1;
1441 break;
1442 case 0:
1443 case 3:
1444 value = EXPR_VALUE (poffset) >> 2;
1445 break;
1446 }
1447
1448 ASSIGN_R (ptr);
1449 ASSIGN_R (reg);
1450
1451 offset = value;
1452 ASSIGN (offset);
1453 ASSIGN (W);
1454 ASSIGN (op);
1455
1456 return GEN_OPCODE16 ();
1457}
1458
1459INSTR_T
1460bfin_gen_ldstiifp (REG_T sreg, Expr_Node * poffset, int W)
1461{
1462 /* Set bit 4 if it's a Preg. */
1463 int reg = (sreg->regno & CODE_MASK) | (IS_PREG (*sreg) ? 0x8 : 0x0);
1464 int offset = ((~(EXPR_VALUE (poffset) >> 2)) & 0x1f) + 1;
1465 INIT (LDSTiiFP);
1466 ASSIGN (reg);
1467 ASSIGN (offset);
1468 ASSIGN (W);
1469
1470 return GEN_OPCODE16 ();
1471}
1472
1473INSTR_T
1474bfin_gen_ldstpmod (REG_T ptr, REG_T reg, int aop, int W, REG_T idx)
1475{
1476 INIT (LDSTpmod);
1477
1478 ASSIGN_R (ptr);
1479 ASSIGN_R (reg);
1480 ASSIGN (aop);
1481 ASSIGN (W);
1482 ASSIGN_R (idx);
1483
1484 return GEN_OPCODE16 ();
1485}
1486
1487INSTR_T
1488bfin_gen_dspldst (REG_T i, REG_T reg, int aop, int W, int m)
1489{
1490 INIT (DspLDST);
1491
1492 ASSIGN_R (i);
1493 ASSIGN_R (reg);
1494 ASSIGN (aop);
1495 ASSIGN (W);
1496 ASSIGN (m);
1497
1498 return GEN_OPCODE16 ();
1499}
1500
1501INSTR_T
1502bfin_gen_logi2op (int opc, int src, int dst)
1503{
1504 INIT (LOGI2op);
1505
1506 ASSIGN (opc);
1507 ASSIGN (src);
1508 ASSIGN (dst);
1509
1510 return GEN_OPCODE16 ();
1511}
1512
1513INSTR_T
1514bfin_gen_brcc (int T, int B, Expr_Node * poffset)
1515{
1516 int offset;
1517 INIT (BRCC);
1518
1519 ASSIGN (T);
1520 ASSIGN (B);
1521 offset = ((EXPR_VALUE (poffset) >> 1));
1522 ASSIGN (offset);
1523 return conscode (gencode (c_code.opcode), Expr_Node_Gen_Reloc (poffset, BFD_RELOC_BFIN_10_PCREL));
1524}
1525
1526INSTR_T
1527bfin_gen_ujump (Expr_Node * poffset)
1528{
1529 int offset;
1530 INIT (UJump);
1531
1532 offset = ((EXPR_VALUE (poffset) >> 1));
1533 ASSIGN (offset);
1534
1535 return conscode (gencode (c_code.opcode),
1536 Expr_Node_Gen_Reloc (
1537 poffset, BFD_RELOC_BFIN_12_PCREL_JUMP_S));
1538}
1539
1540INSTR_T
1541bfin_gen_alu2op (REG_T dst, REG_T src, int opc)
1542{
1543 INIT (ALU2op);
1544
1545 ASSIGN_R (dst);
1546 ASSIGN_R (src);
1547 ASSIGN (opc);
1548
1549 return GEN_OPCODE16 ();
1550}
1551
1552INSTR_T
1553bfin_gen_compi2opd (REG_T dst, int src, int op)
1554{
1555 INIT (COMPI2opD);
1556
1557 ASSIGN_R (dst);
1558 ASSIGN (src);
1559 ASSIGN (op);
1560
1561 return GEN_OPCODE16 ();
1562}
1563
1564INSTR_T
1565bfin_gen_compi2opp (REG_T dst, int src, int op)
1566{
1567 INIT (COMPI2opP);
1568
1569 ASSIGN_R (dst);
1570 ASSIGN (src);
1571 ASSIGN (op);
1572
1573 return GEN_OPCODE16 ();
1574}
1575
1576INSTR_T
1577bfin_gen_dagmodik (REG_T i, int op)
1578{
1579 INIT (DagMODik);
1580
1581 ASSIGN_R (i);
1582 ASSIGN (op);
1583
1584 return GEN_OPCODE16 ();
1585}
1586
1587INSTR_T
1588bfin_gen_dagmodim (REG_T i, REG_T m, int op, int br)
1589{
1590 INIT (DagMODim);
1591
1592 ASSIGN_R (i);
1593 ASSIGN_R (m);
1594 ASSIGN (op);
1595 ASSIGN (br);
1596
1597 return GEN_OPCODE16 ();
1598}
1599
1600INSTR_T
1601bfin_gen_ptr2op (REG_T dst, REG_T src, int opc)
1602{
1603 INIT (PTR2op);
1604
1605 ASSIGN_R (dst);
1606 ASSIGN_R (src);
1607 ASSIGN (opc);
1608
1609 return GEN_OPCODE16 ();
1610}
1611
1612INSTR_T
1613bfin_gen_comp3op (REG_T src0, REG_T src1, REG_T dst, int opc)
1614{
1615 INIT (COMP3op);
1616
1617 ASSIGN_R (src0);
1618 ASSIGN_R (src1);
1619 ASSIGN_R (dst);
1620 ASSIGN (opc);
1621
1622 return GEN_OPCODE16 ();
1623}
1624
1625INSTR_T
1626bfin_gen_ccflag (REG_T x, int y, int opc, int I, int G)
1627{
1628 INIT (CCflag);
1629
1630 ASSIGN_R (x);
1631 ASSIGN (y);
1632 ASSIGN (opc);
1633 ASSIGN (I);
1634 ASSIGN (G);
1635
1636 return GEN_OPCODE16 ();
1637}
1638
1639INSTR_T
1640bfin_gen_ccmv (REG_T src, REG_T dst, int T)
1641{
1642 int s, d;
1643 INIT (CCmv);
1644
1645 ASSIGN_R (src);
1646 ASSIGN_R (dst);
1647 s = (GROUP (src));
1648 ASSIGN (s);
1649 d = (GROUP (dst));
1650 ASSIGN (d);
1651 ASSIGN (T);
1652
1653 return GEN_OPCODE16 ();
1654}
1655
1656INSTR_T
1657bfin_gen_cc2stat (int cbit, int op, int D)
1658{
1659 INIT (CC2stat);
1660
1661 ASSIGN (cbit);
1662 ASSIGN (op);
1663 ASSIGN (D);
1664
1665 return GEN_OPCODE16 ();
1666}
1667
1668INSTR_T
1669bfin_gen_regmv (REG_T src, REG_T dst)
1670{
1671 int gs, gd;
1672 INIT (RegMv);
1673
1674 ASSIGN_R (src);
1675 ASSIGN_R (dst);
1676
1677 gs = (GROUP (src));
1678 ASSIGN (gs);
1679 gd = (GROUP (dst));
1680 ASSIGN (gd);
1681
1682 return GEN_OPCODE16 ();
1683}
1684
1685INSTR_T
1686bfin_gen_cc2dreg (int op, REG_T reg)
1687{
1688 INIT (CC2dreg);
1689
1690 ASSIGN (op);
1691 ASSIGN_R (reg);
1692
1693 return GEN_OPCODE16 ();
1694}
1695
1696INSTR_T
1697bfin_gen_progctrl (int prgfunc, int poprnd)
1698{
1699 INIT (ProgCtrl);
1700
1701 ASSIGN (prgfunc);
1702 ASSIGN (poprnd);
1703
1704 return GEN_OPCODE16 ();
1705}
1706
1707INSTR_T
1708bfin_gen_cactrl (REG_T reg, int a, int op)
1709{
1710 INIT (CaCTRL);
1711
1712 ASSIGN_R (reg);
1713 ASSIGN (a);
1714 ASSIGN (op);
1715
1716 return GEN_OPCODE16 ();
1717}
1718
1719INSTR_T
1720bfin_gen_pushpopmultiple (int dr, int pr, int d, int p, int W)
1721{
1722 INIT (PushPopMultiple);
1723
1724 ASSIGN (dr);
1725 ASSIGN (pr);
1726 ASSIGN (d);
1727 ASSIGN (p);
1728 ASSIGN (W);
1729
1730 return GEN_OPCODE16 ();
1731}
1732
1733INSTR_T
1734bfin_gen_pushpopreg (REG_T reg, int W)
1735{
1736 int grp;
1737 INIT (PushPopReg);
1738
1739 ASSIGN_R (reg);
1740 grp = (GROUP (reg));
1741 ASSIGN (grp);
1742 ASSIGN (W);
1743
1744 return GEN_OPCODE16 ();
1745}
1746
1747/* Pseudo Debugging Support. */
1748
1749INSTR_T
1750bfin_gen_pseudodbg (int fn, int reg, int grp)
1751{
1752 INIT (PseudoDbg);
1753
1754 ASSIGN (fn);
1755 ASSIGN (reg);
1756 ASSIGN (grp);
1757
1758 return GEN_OPCODE16 ();
1759}
1760
1761INSTR_T
1762bfin_gen_pseudodbg_assert (int dbgop, REG_T regtest, int expected)
1763{
1764 INIT (PseudoDbg_Assert);
1765
1766 ASSIGN (dbgop);
1767 ASSIGN_R (regtest);
1768 ASSIGN (expected);
1769
1770 return GEN_OPCODE32 ();
1771}
1772
1773/* Multiple instruction generation. */
1774
1775INSTR_T
1776bfin_gen_multi_instr (INSTR_T dsp32, INSTR_T dsp16_grp1, INSTR_T dsp16_grp2)
1777{
1778 INSTR_T walk;
1779
1780 /* If it's a 0, convert into MNOP. */
1781 if (dsp32)
1782 {
1783 walk = dsp32->next;
1784 SET_MULTI_INSTRUCTION_BIT (dsp32);
1785 }
1786 else
1787 {
1788 dsp32 = gencode (0xc803);
1789 walk = gencode (0x1800);
1790 dsp32->next = walk;
1791 }
1792
1793 if (!dsp16_grp1)
1794 {
1795 dsp16_grp1 = gencode (0x0000);
1796 }
1797
1798 if (!dsp16_grp2)
1799 {
1800 dsp16_grp2 = gencode (0x0000);
1801 }
1802
1803 walk->next = dsp16_grp1;
1804 dsp16_grp1->next = dsp16_grp2;
1805 dsp16_grp2->next = NULL_CODE;
1806
1807 return dsp32;
1808}
1809
1810INSTR_T
1811bfin_gen_loop (Expr_Node *expr, REG_T reg, int rop, REG_T preg)
1812{
1813 const char *loopsym;
1814 char *lbeginsym, *lendsym;
1815 Expr_Node_Value lbeginval, lendval;
1816 Expr_Node *lbegin, *lend;
1817
1818 loopsym = expr->value.s_value;
1819 lbeginsym = (char *) xmalloc (strlen (loopsym) + strlen ("__BEGIN") + 1);
1820 lendsym = (char *) xmalloc (strlen (loopsym) + strlen ("__END") + 1);
1821
1822 lbeginsym[0] = 0;
1823 lendsym[0] = 0;
1824
1825 strcat (lbeginsym, loopsym);
1826 strcat (lbeginsym, "__BEGIN");
1827
1828 strcat (lendsym, loopsym);
1829 strcat (lendsym, "__END");
1830
1831 lbeginval.s_value = lbeginsym;
1832 lendval.s_value = lendsym;
1833
1834 lbegin = Expr_Node_Create (Expr_Node_Reloc, lbeginval, NULL, NULL);
1835 lend = Expr_Node_Create (Expr_Node_Reloc, lendval, NULL, NULL);
1836 return bfin_gen_loopsetup(lbegin, reg, rop, lend, preg);
1837}
1838
1839bfd_boolean
1840bfin_eol_in_insn (char *line)
1841{
1842 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1843
1844 char *temp = line;
1845
1846 if (*line != '\n')
1847 return FALSE;
1848
1849 /* A semi-colon followed by a newline is always the end of a line. */
1850 if (line[-1] == ';')
1851 return FALSE;
1852
1853 if (line[-1] == '|')
1854 return TRUE;
1855
1856 /* If the || is on the next line, there might be leading whitespace. */
1857 temp++;
1858 while (*temp == ' ' || *temp == '\t') temp++;
1859
1860 if (*temp == '|')
1861 return TRUE;
1862
1863 return FALSE;
1864}
1865
1866bfd_boolean
1867bfin_name_is_register (char *name)
1868{
1869 int i;
1870
1871 if (*name == '[' || *name == '(')
1872 return TRUE;
1873
1874 if ((name[0] == 'W' || name[0] == 'w') && name[1] == '[')
1875 return TRUE;
1876
1877 if ((name[0] == 'B' || name[0] == 'b') && name[1] == '[')
1878 return TRUE;
1879
07c1b327
CM
1880 for (i=0; bfin_reg_info[i].name != 0; i++)
1881 {
1882 if (!strcasecmp (bfin_reg_info[i].name, name))
1883 return TRUE;
1884 }
1885 return FALSE;
1886}
1887
1888void
1889bfin_equals (Expr_Node *sym)
1890{
1891 char *c;
1892
1893 c = input_line_pointer;
1894 while (*c != '=')
1895 c--;
1896
1897 input_line_pointer = c;
1898
1899 equals ((char *) sym->value.s_value, 1);
1900}
1901
1902bfd_boolean
1903bfin_start_label (char *ptr)
1904{
1905 ptr--;
1906 while (!ISSPACE (*ptr) && !is_end_of_line[(unsigned char) *ptr])
1907 ptr--;
1908
1909 ptr++;
1910 if (*ptr == '(' || *ptr == '[')
1911 return FALSE;
1912
07c1b327
CM
1913 return TRUE;
1914}
1915
1916int
1917bfin_force_relocation (struct fix *fixp)
1918{
1919 if (fixp->fx_r_type ==BFD_RELOC_BFIN_16_LOW
1920 || fixp->fx_r_type == BFD_RELOC_BFIN_16_HIGH)
1921 return TRUE;
1922
1923 return generic_force_reloc (fixp);
1924}