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