1 /* tc-bfin.c -- Assembler for the ADI Blackfin.
2 Copyright 2005, 2006, 2007, 2008
3 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
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 3, or (at your option)
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.
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
23 #include "struc-symbol.h"
24 #include "bfin-defs.h"
26 #include "safe-ctype.h"
28 #include "dwarf2dbg.h"
31 #include "elf/common.h"
34 extern int yyparse (void);
35 struct yy_buffer_state
;
36 typedef struct yy_buffer_state
*YY_BUFFER_STATE
;
37 extern YY_BUFFER_STATE
yy_scan_string (const char *yy_str
);
38 extern void yy_delete_buffer (YY_BUFFER_STATE b
);
39 static parse_state
parse (char *line
);
41 /* Global variables. */
42 struct bfin_insn
*insn
;
45 extern struct obstack mempool
;
48 /* Flags to set in the elf header */
49 #define DEFAULT_FLAGS 0
52 # define DEFAULT_FDPIC EF_BFIN_FDPIC
54 # define DEFAULT_FDPIC 0
57 static flagword bfin_flags
= DEFAULT_FLAGS
| DEFAULT_FDPIC
;
58 static const char *bfin_pic_flag
= DEFAULT_FDPIC
? "-mfdpic" : (const char *)0;
67 static const struct bfin_reg_entry bfin_reg_info
[] = {
189 {"sftreset", REG_sftreset
},
190 {"omode", REG_omode
},
191 {"excause", REG_excause
},
192 {"emucause", REG_emucause
},
193 {"idle_req", REG_idle_req
},
194 {"hwerrcause", REG_hwerrcause
},
198 {"ASTAT", REG_ASTAT
},
204 {"CYCLES", REG_CYCLES
},
205 {"CYCLES2", REG_CYCLES2
},
207 {"SEQSTAT", REG_SEQSTAT
},
208 {"SYSCFG", REG_SYSCFG
},
213 {"EMUDAT", REG_EMUDAT
},
217 /* Blackfin specific function to handle FD-PIC pointer initializations. */
220 bfin_pic_ptr (int nbytes
)
228 #ifdef md_flush_pending_output
229 md_flush_pending_output ();
232 if (is_it_end_of_statement ())
234 demand_empty_rest_of_line ();
239 md_cons_align (nbytes
);
244 bfd_reloc_code_real_type reloc_type
= BFD_RELOC_BFIN_FUNCDESC
;
246 if (strncasecmp (input_line_pointer
, "funcdesc(", 9) == 0)
248 input_line_pointer
+= 9;
250 if (*input_line_pointer
== ')')
251 input_line_pointer
++;
253 as_bad (_("missing ')'"));
256 error ("missing funcdesc in picptr");
260 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &exp
, 0,
263 while (*input_line_pointer
++ == ',');
265 input_line_pointer
--; /* Put terminator back into stream. */
266 demand_empty_rest_of_line ();
270 bfin_s_bss (int ignore ATTRIBUTE_UNUSED
)
274 temp
= get_absolute_expression ();
275 subseg_set (bss_section
, (subsegT
) temp
);
276 demand_empty_rest_of_line ();
279 const pseudo_typeS md_pseudo_table
[] = {
280 {"align", s_align_bytes
, 0},
283 {"picptr", bfin_pic_ptr
, 4},
284 {"code", obj_elf_section
, 0},
289 {"pdata", s_ignore
, 0},
290 {"var", s_ignore
, 0},
291 {"bss", bfin_s_bss
, 0},
295 /* Characters that are used to denote comments and line separators. */
296 const char comment_chars
[] = "";
297 const char line_comment_chars
[] = "#";
298 const char line_separator_chars
[] = ";";
300 /* Characters that can be used to separate the mantissa from the
301 exponent in floating point numbers. */
302 const char EXP_CHARS
[] = "eE";
304 /* Characters that mean this number is a floating point constant.
305 As in 0f12.456 or 0d1.2345e12. */
306 const char FLT_CHARS
[] = "fFdDxX";
308 /* Define bfin-specific command-line options (there are none). */
309 const char *md_shortopts
= "";
311 #define OPTION_FDPIC (OPTION_MD_BASE)
312 #define OPTION_NOPIC (OPTION_MD_BASE + 1)
314 struct option md_longopts
[] =
316 { "mfdpic", no_argument
, NULL
, OPTION_FDPIC
},
317 { "mnopic", no_argument
, NULL
, OPTION_NOPIC
},
318 { "mno-fdpic", no_argument
, NULL
, OPTION_NOPIC
},
319 { NULL
, no_argument
, NULL
, 0 },
322 size_t md_longopts_size
= sizeof (md_longopts
);
326 md_parse_option (int c ATTRIBUTE_UNUSED
, char *arg ATTRIBUTE_UNUSED
)
334 bfin_flags
|= EF_BFIN_FDPIC
;
335 bfin_pic_flag
= "-mfdpic";
339 bfin_flags
&= ~(EF_BFIN_FDPIC
);
348 md_show_usage (FILE * stream ATTRIBUTE_UNUSED
)
350 fprintf (stream
, _(" BFIN specific command line options:\n"));
353 /* Perform machine-specific initializations. */
357 /* Set the ELF flags if desired. */
359 bfd_set_private_flags (stdoutput
, bfin_flags
);
361 /* Set the default machine type. */
362 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_bfin
, 0))
363 as_warn (_("Could not set architecture and machine."));
365 /* Ensure that lines can begin with '(', for multiple
366 register stack pops. */
367 lex_type
['('] = LEX_BEGIN_NAME
;
370 record_alignment (text_section
, 2);
371 record_alignment (data_section
, 2);
372 record_alignment (bss_section
, 2);
376 obstack_init (&mempool
);
379 extern int debug_codeselection
;
380 debug_codeselection
= 1;
386 /* Perform the main parsing, and assembly of the input here. Also,
387 call the required routines for alignment and fixups here.
388 This is called for every line that contains real assembly code. */
391 md_assemble (char *line
)
394 extern char *current_inputline
;
396 struct bfin_insn
*tmp_insn
;
398 static size_t buffer_len
= 0;
402 if (len
+ 2 > buffer_len
)
405 free (current_inputline
);
406 buffer_len
= len
+ 40;
407 current_inputline
= xmalloc (buffer_len
);
409 memcpy (current_inputline
, line
, len
);
410 current_inputline
[len
] = ';';
411 current_inputline
[len
+ 1] = '\0';
413 state
= parse (current_inputline
);
414 if (state
== NO_INSN_GENERATED
)
417 for (insn_size
= 0, tmp_insn
= insn
; tmp_insn
; tmp_insn
= tmp_insn
->next
)
418 if (!tmp_insn
->reloc
|| !tmp_insn
->exp
->symbol
)
422 toP
= frag_more (insn_size
);
424 last_insn_size
= insn_size
;
431 if (insn
->reloc
&& insn
->exp
->symbol
)
433 char *prev_toP
= toP
- 2;
436 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
437 case BFD_RELOC_24_PCREL
:
438 case BFD_RELOC_BFIN_16_LOW
:
439 case BFD_RELOC_BFIN_16_HIGH
:
446 /* Following if condition checks for the arithmetic relocations.
447 If the case then it doesn't required to generate the code.
448 It has been assumed that, their ID will be contiguous. */
449 if ((BFD_ARELOC_BFIN_PUSH
<= insn
->reloc
450 && BFD_ARELOC_BFIN_COMP
>= insn
->reloc
)
451 || insn
->reloc
== BFD_RELOC_BFIN_16_IMM
)
455 if (insn
->reloc
== BFD_ARELOC_BFIN_CONST
456 || insn
->reloc
== BFD_ARELOC_BFIN_PUSH
)
460 (prev_toP
- frag_now
->fr_literal
),
461 size
, insn
->exp
->symbol
, insn
->exp
->value
,
462 insn
->pcrel
, insn
->reloc
);
466 md_number_to_chars (toP
, insn
->value
, 2);
472 printf (" %02x%02x", ((unsigned char *) &insn
->value
)[0],
473 ((unsigned char *) &insn
->value
)[1]);
479 dwarf2_emit_insn (insn_size
);
483 /* Parse one line of instructions, and generate opcode for it.
484 To parse the line, YACC and LEX are used, because the instruction set
485 syntax doesn't confirm to the AT&T assembly syntax.
486 To call a YACC & LEX generated parser, we must provide the input via
487 a FILE stream, otherwise stdin is used by default. Below the input
488 to the function will be put into a temporary file, then the generated
489 parser uses the temporary file for parsing. */
495 YY_BUFFER_STATE buffstate
;
497 buffstate
= yy_scan_string (line
);
499 /* our lex requires setting the start state to keyword
500 every line as the first word may be a keyword.
501 Fixes a bug where we could not have keywords as labels. */
504 /* Call yyparse here. */
506 if (state
== SEMANTIC_ERROR
)
508 as_bad (_("Parse failed."));
512 yy_delete_buffer (buffstate
);
516 /* We need to handle various expressions properly.
517 Such as, [SP--] = 34, concerned by md_assemble(). */
520 md_operand (expressionS
* expressionP
)
522 if (*input_line_pointer
== '[')
524 as_tsktsk ("We found a '['!");
525 input_line_pointer
++;
526 expression (expressionP
);
530 /* Handle undefined symbols. */
532 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
534 return (symbolS
*) 0;
538 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
539 segT segment ATTRIBUTE_UNUSED
)
544 /* Convert from target byte order to host byte order. */
547 md_chars_to_number (char *val
, int n
)
551 for (retval
= 0; n
--;)
560 md_apply_fix (fixS
*fixP
, valueT
*valueP
, segT seg ATTRIBUTE_UNUSED
)
562 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
564 long value
= *valueP
;
567 switch (fixP
->fx_r_type
)
569 case BFD_RELOC_BFIN_GOT
:
570 case BFD_RELOC_BFIN_GOT17M4
:
571 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
572 fixP
->fx_no_overflow
= 1;
573 newval
= md_chars_to_number (where
, 2);
574 newval
|= 0x0 & 0x7f;
575 md_number_to_chars (where
, newval
, 2);
578 case BFD_RELOC_BFIN_10_PCREL
:
581 if (value
< -1024 || value
> 1022)
582 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
583 _("pcrel too far BFD_RELOC_BFIN_10"));
585 /* 11 bit offset even numbered, so we remove right bit. */
587 newval
= md_chars_to_number (where
, 2);
588 newval
|= value
& 0x03ff;
589 md_number_to_chars (where
, newval
, 2);
592 case BFD_RELOC_BFIN_12_PCREL_JUMP
:
593 case BFD_RELOC_BFIN_12_PCREL_JUMP_S
:
594 case BFD_RELOC_12_PCREL
:
598 if (value
< -4096 || value
> 4094)
599 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_12"));
600 /* 13 bit offset even numbered, so we remove right bit. */
602 newval
= md_chars_to_number (where
, 2);
603 newval
|= value
& 0xfff;
604 md_number_to_chars (where
, newval
, 2);
607 case BFD_RELOC_BFIN_16_LOW
:
608 case BFD_RELOC_BFIN_16_HIGH
:
609 fixP
->fx_done
= FALSE
;
612 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
613 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
614 case BFD_RELOC_24_PCREL
:
618 if (value
< -16777216 || value
> 16777214)
619 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_24"));
621 /* 25 bit offset even numbered, so we remove right bit. */
625 md_number_to_chars (where
- 2, value
>> 16, 1);
626 md_number_to_chars (where
, value
, 1);
627 md_number_to_chars (where
+ 1, value
>> 8, 1);
630 case BFD_RELOC_BFIN_5_PCREL
: /* LSETUP (a, b) : "a" */
633 if (value
< 4 || value
> 30)
634 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_5"));
636 newval
= md_chars_to_number (where
, 1);
637 newval
= (newval
& 0xf0) | (value
& 0xf);
638 md_number_to_chars (where
, newval
, 1);
641 case BFD_RELOC_BFIN_11_PCREL
: /* LSETUP (a, b) : "b" */
645 if (value
< 4 || value
> 2046)
646 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_11_PCREL"));
647 /* 11 bit unsigned even, so we remove right bit. */
649 newval
= md_chars_to_number (where
, 2);
650 newval
|= value
& 0x03ff;
651 md_number_to_chars (where
, newval
, 2);
655 if (value
< -0x80 || value
>= 0x7f)
656 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("rel too far BFD_RELOC_8"));
657 md_number_to_chars (where
, value
, 1);
660 case BFD_RELOC_BFIN_16_IMM
:
662 if (value
< -0x8000 || value
>= 0x7fff)
663 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("rel too far BFD_RELOC_16"));
664 md_number_to_chars (where
, value
, 2);
668 md_number_to_chars (where
, value
, 4);
671 case BFD_RELOC_BFIN_PLTPC
:
672 md_number_to_chars (where
, value
, 2);
675 case BFD_RELOC_BFIN_FUNCDESC
:
676 case BFD_RELOC_VTABLE_INHERIT
:
677 case BFD_RELOC_VTABLE_ENTRY
:
678 fixP
->fx_done
= FALSE
;
682 if ((BFD_ARELOC_BFIN_PUSH
> fixP
->fx_r_type
) || (BFD_ARELOC_BFIN_COMP
< fixP
->fx_r_type
))
684 fprintf (stderr
, "Relocation %d not handled in gas." " Contact support.\n", fixP
->fx_r_type
);
690 fixP
->fx_done
= TRUE
;
694 /* Round up a section size to the appropriate boundary. */
696 md_section_align (segment
, size
)
700 int boundary
= bfd_get_section_alignment (stdoutput
, segment
);
701 return ((size
+ (1 << boundary
) - 1) & (-1 << boundary
));
706 md_atof (int type
, char * litP
, int * sizeP
)
708 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
712 /* If while processing a fixup, a reloc really needs to be created
713 then it is done here. */
716 tc_gen_reloc (seg
, fixp
)
717 asection
*seg ATTRIBUTE_UNUSED
;
722 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
723 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
724 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
725 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
727 reloc
->addend
= fixp
->fx_offset
;
728 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
730 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
732 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
733 /* xgettext:c-format. */
734 _("reloc %d not supported by object file format"),
735 (int) fixp
->fx_r_type
);
745 /* The location from which a PC relative jump should be calculated,
746 given a PC relative reloc. */
749 md_pcrel_from_section (fixP
, sec
)
753 if (fixP
->fx_addsy
!= (symbolS
*) NULL
754 && (!S_IS_DEFINED (fixP
->fx_addsy
)
755 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
757 /* The symbol is undefined (or is defined but not in this section).
758 Let the linker figure it out. */
761 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
764 /* Return true if the fix can be handled by GAS, false if it must
765 be passed through to the linker. */
768 bfin_fix_adjustable (fixS
*fixP
)
770 switch (fixP
->fx_r_type
)
772 /* Adjust_reloc_syms doesn't know about the GOT. */
773 case BFD_RELOC_BFIN_GOT
:
774 case BFD_RELOC_BFIN_GOT17M4
:
775 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
776 case BFD_RELOC_BFIN_PLTPC
:
777 /* We need the symbol name for the VTABLE entries. */
778 case BFD_RELOC_VTABLE_INHERIT
:
779 case BFD_RELOC_VTABLE_ENTRY
:
788 /* Handle the LOOP_BEGIN and LOOP_END statements.
789 Parse the Loop_Begin/Loop_End and create a label. */
791 bfin_start_line_hook ()
793 bfd_boolean maybe_begin
= FALSE
;
794 bfd_boolean maybe_end
= FALSE
;
796 char *c1
, *label_name
;
798 char *c
= input_line_pointer
;
808 /* Look for Loop_Begin or Loop_End statements. */
810 if (*c
!= 'L' && *c
!= 'l')
814 if (*c
!= 'O' && *c
!= 'o')
818 if (*c
!= 'O' && *c
!= 'o')
822 if (*c
!= 'P' && *c
!= 'p')
830 if (*c
== 'E' || *c
== 'e')
832 else if (*c
== 'B' || *c
== 'b')
840 if (*c
!= 'N' && *c
!= 'n')
844 if (*c
!= 'D' && *c
!= 'd')
851 if (*c
!= 'E' && *c
!= 'e')
855 if (*c
!= 'G' && *c
!= 'g')
859 if (*c
!= 'I' && *c
!= 'i')
863 if (*c
!= 'N' && *c
!= 'n')
868 while (ISSPACE (*c
)) c
++;
870 while (ISALPHA (*c
) || ISDIGIT (*c
) || *c
== '_') c
++;
872 if (input_line_pointer
[-1] == '\n')
873 bump_line_counters ();
876 bump_line_counters ();
878 input_line_pointer
= c
;
881 label_name
= (char *) xmalloc ((c
- c1
) + strlen ("__END") + 5);
883 strcat (label_name
, "L$L$");
884 strncat (label_name
, c1
, c
-c1
);
885 strcat (label_name
, "__END");
887 else /* maybe_begin. */
889 label_name
= (char *) xmalloc ((c
- c1
) + strlen ("__BEGIN") + 5);
891 strcat (label_name
, "L$L$");
892 strncat (label_name
, c1
, c
-c1
);
893 strcat (label_name
, "__BEGIN");
896 line_label
= colon (label_name
);
898 /* Loop_End follows the last instruction in the loop.
899 Adjust label address. */
901 ((struct local_symbol
*) line_label
)->lsy_value
-= last_insn_size
;
904 /* Special extra functions that help bfin-parse.y perform its job. */
906 struct obstack mempool
;
909 conscode (INSTR_T head
, INSTR_T tail
)
918 conctcode (INSTR_T head
, INSTR_T tail
)
920 INSTR_T temp
= (head
);
931 note_reloc (INSTR_T code
, Expr_Node
* symbol
, int reloc
, int pcrel
)
933 /* Assert that the symbol is not an operator. */
934 gas_assert (symbol
->type
== Expr_Node_Reloc
);
936 return note_reloc1 (code
, symbol
->value
.s_value
, reloc
, pcrel
);
941 note_reloc1 (INSTR_T code
, const char *symbol
, int reloc
, int pcrel
)
944 code
->exp
= mkexpr (0, symbol_find_or_make (symbol
));
950 note_reloc2 (INSTR_T code
, const char *symbol
, int reloc
, int value
, int pcrel
)
953 code
->exp
= mkexpr (value
, symbol_find_or_make (symbol
));
959 gencode (unsigned long x
)
961 INSTR_T cell
= obstack_alloc (&mempool
, sizeof (struct bfin_insn
));
962 memset (cell
, 0, sizeof (struct bfin_insn
));
974 return obstack_alloc (&mempool
, n
);
978 Expr_Node_Create (Expr_Node_Type type
,
979 Expr_Node_Value value
,
980 Expr_Node
*Left_Child
,
981 Expr_Node
*Right_Child
)
985 Expr_Node
*node
= (Expr_Node
*) allocate (sizeof (Expr_Node
));
988 node
->Left_Child
= Left_Child
;
989 node
->Right_Child
= Right_Child
;
993 static const char *con
= ".__constant";
994 static const char *op
= ".__operator";
995 static INSTR_T
Expr_Node_Gen_Reloc_R (Expr_Node
* head
);
996 INSTR_T
Expr_Node_Gen_Reloc (Expr_Node
*head
, int parent_reloc
);
999 Expr_Node_Gen_Reloc (Expr_Node
* head
, int parent_reloc
)
1001 /* Top level reloction expression generator VDSP style.
1002 If the relocation is just by itself, generate one item
1003 else generate this convoluted expression. */
1005 INSTR_T note
= NULL_CODE
;
1006 INSTR_T note1
= NULL_CODE
;
1007 int pcrel
= 1; /* Is the parent reloc pcrelative?
1008 This calculation here and HOWTO should match. */
1012 /* If it's 32 bit quantity then 16bit code needs to be added. */
1015 if (head
->type
== Expr_Node_Constant
)
1017 /* If note1 is not null code, we have to generate a right
1018 aligned value for the constant. Otherwise the reloc is
1019 a part of the basic command and the yacc file
1021 value
= head
->value
.i_value
;
1023 switch (parent_reloc
)
1025 /* Some relocations will need to allocate extra words. */
1026 case BFD_RELOC_BFIN_16_IMM
:
1027 case BFD_RELOC_BFIN_16_LOW
:
1028 case BFD_RELOC_BFIN_16_HIGH
:
1029 note1
= conscode (gencode (value
), NULL_CODE
);
1032 case BFD_RELOC_BFIN_PLTPC
:
1033 note1
= conscode (gencode (value
), NULL_CODE
);
1037 case BFD_RELOC_BFIN_GOT
:
1038 case BFD_RELOC_BFIN_GOT17M4
:
1039 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
1040 note1
= conscode (gencode (value
), NULL_CODE
);
1043 case BFD_RELOC_24_PCREL
:
1044 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
1045 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
1046 /* These offsets are even numbered pcrel. */
1047 note1
= conscode (gencode (value
>> 1), NULL_CODE
);
1053 if (head
->type
== Expr_Node_Constant
)
1055 else if (head
->type
== Expr_Node_Reloc
)
1057 note
= note_reloc1 (gencode (0), head
->value
.s_value
, parent_reloc
, pcrel
);
1058 if (note1
!= NULL_CODE
)
1059 note
= conscode (note1
, note
);
1061 else if (head
->type
== Expr_Node_Binop
1062 && (head
->value
.op_value
== Expr_Op_Type_Add
1063 || head
->value
.op_value
== Expr_Op_Type_Sub
)
1064 && head
->Left_Child
->type
== Expr_Node_Reloc
1065 && head
->Right_Child
->type
== Expr_Node_Constant
)
1067 int val
= head
->Right_Child
->value
.i_value
;
1068 if (head
->value
.op_value
== Expr_Op_Type_Sub
)
1070 note
= conscode (note_reloc2 (gencode (0), head
->Left_Child
->value
.s_value
,
1071 parent_reloc
, val
, 0),
1073 if (note1
!= NULL_CODE
)
1074 note
= conscode (note1
, note
);
1078 /* Call the recursive function. */
1079 note
= note_reloc1 (gencode (0), op
, parent_reloc
, pcrel
);
1080 if (note1
!= NULL_CODE
)
1081 note
= conscode (note1
, note
);
1082 note
= conctcode (Expr_Node_Gen_Reloc_R (head
), note
);
1088 Expr_Node_Gen_Reloc_R (Expr_Node
* head
)
1096 case Expr_Node_Constant
:
1097 note
= conscode (note_reloc2 (gencode (0), con
, BFD_ARELOC_BFIN_CONST
, head
->value
.i_value
, 0), NULL_CODE
);
1099 case Expr_Node_Reloc
:
1100 note
= conscode (note_reloc (gencode (0), head
, BFD_ARELOC_BFIN_PUSH
, 0), NULL_CODE
);
1102 case Expr_Node_Binop
:
1103 note1
= conctcode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), Expr_Node_Gen_Reloc_R (head
->Right_Child
));
1104 switch (head
->value
.op_value
)
1106 case Expr_Op_Type_Add
:
1107 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_ADD
, 0), NULL_CODE
));
1109 case Expr_Op_Type_Sub
:
1110 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_SUB
, 0), NULL_CODE
));
1112 case Expr_Op_Type_Mult
:
1113 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MULT
, 0), NULL_CODE
));
1115 case Expr_Op_Type_Div
:
1116 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_DIV
, 0), NULL_CODE
));
1118 case Expr_Op_Type_Mod
:
1119 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MOD
, 0), NULL_CODE
));
1121 case Expr_Op_Type_Lshift
:
1122 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LSHIFT
, 0), NULL_CODE
));
1124 case Expr_Op_Type_Rshift
:
1125 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_RSHIFT
, 0), NULL_CODE
));
1127 case Expr_Op_Type_BAND
:
1128 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_AND
, 0), NULL_CODE
));
1130 case Expr_Op_Type_BOR
:
1131 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_OR
, 0), NULL_CODE
));
1133 case Expr_Op_Type_BXOR
:
1134 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_XOR
, 0), NULL_CODE
));
1136 case Expr_Op_Type_LAND
:
1137 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LAND
, 0), NULL_CODE
));
1139 case Expr_Op_Type_LOR
:
1140 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LOR
, 0), NULL_CODE
));
1143 fprintf (stderr
, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1148 case Expr_Node_Unop
:
1149 note1
= conscode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), NULL_CODE
);
1150 switch (head
->value
.op_value
)
1152 case Expr_Op_Type_NEG
:
1153 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_NEG
, 0), NULL_CODE
));
1155 case Expr_Op_Type_COMP
:
1156 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_COMP
, 0), NULL_CODE
));
1159 fprintf (stderr
, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1163 fprintf (stderr
, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__
, __LINE__
);
1169 /* Blackfin opcode generation. */
1171 /* These functions are called by the generated parser
1172 (from bfin-parse.y), the register type classification
1173 happens in bfin-lex.l. */
1175 #include "bfin-aux.h"
1176 #include "opcode/bfin.h"
1178 #define INIT(t) t c_code = init_##t
1179 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1180 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1182 #define HI(x) ((x >> 16) & 0xffff)
1183 #define LO(x) ((x ) & 0xffff)
1185 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1187 #define GEN_OPCODE32() \
1188 conscode (gencode (HI (c_code.opcode)), \
1189 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1191 #define GEN_OPCODE16() \
1192 conscode (gencode (c_code.opcode), NULL_CODE)
1195 /* 32 BIT INSTRUCTIONS. */
1198 /* DSP32 instruction generation. */
1201 bfin_gen_dsp32mac (int op1
, int MM
, int mmod
, int w1
, int P
,
1202 int h01
, int h11
, int h00
, int h10
, int op0
,
1203 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1219 /* If we have full reg assignments, mask out LSB to encode
1220 single or simultaneous even/odd register moves. */
1230 return GEN_OPCODE32 ();
1234 bfin_gen_dsp32mult (int op1
, int MM
, int mmod
, int w1
, int P
,
1235 int h01
, int h11
, int h00
, int h10
, int op0
,
1236 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1261 return GEN_OPCODE32 ();
1265 bfin_gen_dsp32alu (int HL
, int aopcde
, int aop
, int s
, int x
,
1266 REG_T dst0
, REG_T dst1
, REG_T src0
, REG_T src1
)
1280 return GEN_OPCODE32 ();
1284 bfin_gen_dsp32shift (int sopcde
, REG_T dst0
, REG_T src0
,
1285 REG_T src1
, int sop
, int HLs
)
1297 return GEN_OPCODE32 ();
1301 bfin_gen_dsp32shiftimm (int sopcde
, REG_T dst0
, int immag
,
1302 REG_T src1
, int sop
, int HLs
)
1304 INIT (DSP32ShiftImm
);
1314 return GEN_OPCODE32 ();
1320 bfin_gen_loopsetup (Expr_Node
* psoffset
, REG_T c
, int rop
,
1321 Expr_Node
* peoffset
, REG_T reg
)
1323 int soffset
, eoffset
;
1326 soffset
= (EXPR_VALUE (psoffset
) >> 1);
1328 eoffset
= (EXPR_VALUE (peoffset
) >> 1);
1335 conscode (gencode (HI (c_code
.opcode
)),
1336 conctcode (Expr_Node_Gen_Reloc (psoffset
, BFD_RELOC_BFIN_5_PCREL
),
1337 conctcode (gencode (LO (c_code
.opcode
)), Expr_Node_Gen_Reloc (peoffset
, BFD_RELOC_BFIN_11_PCREL
))));
1344 bfin_gen_calla (Expr_Node
* addr
, int S
)
1352 case 0 : reloc
= BFD_RELOC_BFIN_24_PCREL_JUMP_L
; break;
1353 case 1 : reloc
= BFD_RELOC_24_PCREL
; break;
1354 case 2 : reloc
= BFD_RELOC_BFIN_PLTPC
; break;
1360 val
= EXPR_VALUE (addr
) >> 1;
1361 high_val
= val
>> 16;
1363 return conscode (gencode (HI (c_code
.opcode
) | (high_val
& 0xff)),
1364 Expr_Node_Gen_Reloc (addr
, reloc
));
1368 bfin_gen_linkage (int R
, int framesize
)
1375 return GEN_OPCODE32 ();
1379 /* Load and Store. */
1382 bfin_gen_ldimmhalf (REG_T reg
, int H
, int S
, int Z
, Expr_Node
* phword
, int reloc
)
1385 unsigned val
= EXPR_VALUE (phword
);
1393 grp
= (GROUP (reg
));
1397 return conscode (gencode (HI (c_code
.opcode
)), Expr_Node_Gen_Reloc (phword
, BFD_RELOC_BFIN_16_IMM
));
1399 else if (reloc
== 1)
1401 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
));
1408 return GEN_OPCODE32 ();
1412 bfin_gen_ldstidxi (REG_T ptr
, REG_T reg
, int W
, int sz
, int Z
, Expr_Node
* poffset
)
1416 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1418 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1429 if (poffset
->type
!= Expr_Node_Constant
)
1431 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1432 /* distinguish between R0 = [P5 + symbol@GOT] and
1433 P5 = [P5 + _current_shared_library_p5_offset_]
1435 if (poffset
->type
== Expr_Node_Reloc
1436 && !strcmp (poffset
->value
.s_value
,
1437 "_current_shared_library_p5_offset_"))
1439 return conscode (gencode (HI (c_code
.opcode
)),
1440 Expr_Node_Gen_Reloc(poffset
, BFD_RELOC_16
));
1442 else if (poffset
->type
!= Expr_Node_GOT_Reloc
)
1445 return conscode (gencode (HI (c_code
.opcode
)),
1446 Expr_Node_Gen_Reloc(poffset
->Left_Child
,
1447 poffset
->value
.i_value
));
1453 { /* load/store access size */
1454 case 0: /* 32 bit */
1455 value
= EXPR_VALUE (poffset
) >> 2;
1457 case 1: /* 16 bit */
1458 value
= EXPR_VALUE (poffset
) >> 1;
1461 value
= EXPR_VALUE (poffset
);
1467 offset
= (value
& 0xffff);
1469 return GEN_OPCODE32 ();
1475 bfin_gen_ldst (REG_T ptr
, REG_T reg
, int aop
, int sz
, int Z
, int W
)
1479 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1481 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1492 return GEN_OPCODE16 ();
1496 bfin_gen_ldstii (REG_T ptr
, REG_T reg
, Expr_Node
* poffset
, int W
, int op
)
1503 if (!IS_PREG (*ptr
))
1505 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1513 value
= EXPR_VALUE (poffset
) >> 1;
1517 value
= EXPR_VALUE (poffset
) >> 2;
1529 return GEN_OPCODE16 ();
1533 bfin_gen_ldstiifp (REG_T sreg
, Expr_Node
* poffset
, int W
)
1535 /* Set bit 4 if it's a Preg. */
1536 int reg
= (sreg
->regno
& CODE_MASK
) | (IS_PREG (*sreg
) ? 0x8 : 0x0);
1537 int offset
= ((~(EXPR_VALUE (poffset
) >> 2)) & 0x1f) + 1;
1543 return GEN_OPCODE16 ();
1547 bfin_gen_ldstpmod (REG_T ptr
, REG_T reg
, int aop
, int W
, REG_T idx
)
1557 return GEN_OPCODE16 ();
1561 bfin_gen_dspldst (REG_T i
, REG_T reg
, int aop
, int W
, int m
)
1571 return GEN_OPCODE16 ();
1575 bfin_gen_logi2op (int opc
, int src
, int dst
)
1583 return GEN_OPCODE16 ();
1587 bfin_gen_brcc (int T
, int B
, Expr_Node
* poffset
)
1594 offset
= ((EXPR_VALUE (poffset
) >> 1));
1596 return conscode (gencode (c_code
.opcode
), Expr_Node_Gen_Reloc (poffset
, BFD_RELOC_BFIN_10_PCREL
));
1600 bfin_gen_ujump (Expr_Node
* poffset
)
1605 offset
= ((EXPR_VALUE (poffset
) >> 1));
1608 return conscode (gencode (c_code
.opcode
),
1609 Expr_Node_Gen_Reloc (
1610 poffset
, BFD_RELOC_BFIN_12_PCREL_JUMP_S
));
1614 bfin_gen_alu2op (REG_T dst
, REG_T src
, int opc
)
1622 return GEN_OPCODE16 ();
1626 bfin_gen_compi2opd (REG_T dst
, int src
, int op
)
1634 return GEN_OPCODE16 ();
1638 bfin_gen_compi2opp (REG_T dst
, int src
, int op
)
1646 return GEN_OPCODE16 ();
1650 bfin_gen_dagmodik (REG_T i
, int op
)
1657 return GEN_OPCODE16 ();
1661 bfin_gen_dagmodim (REG_T i
, REG_T m
, int op
, int br
)
1670 return GEN_OPCODE16 ();
1674 bfin_gen_ptr2op (REG_T dst
, REG_T src
, int opc
)
1682 return GEN_OPCODE16 ();
1686 bfin_gen_comp3op (REG_T src0
, REG_T src1
, REG_T dst
, int opc
)
1695 return GEN_OPCODE16 ();
1699 bfin_gen_ccflag (REG_T x
, int y
, int opc
, int I
, int G
)
1709 return GEN_OPCODE16 ();
1713 bfin_gen_ccmv (REG_T src
, REG_T dst
, int T
)
1726 return GEN_OPCODE16 ();
1730 bfin_gen_cc2stat (int cbit
, int op
, int D
)
1738 return GEN_OPCODE16 ();
1742 bfin_gen_regmv (REG_T src
, REG_T dst
)
1755 return GEN_OPCODE16 ();
1759 bfin_gen_cc2dreg (int op
, REG_T reg
)
1766 return GEN_OPCODE16 ();
1770 bfin_gen_progctrl (int prgfunc
, int poprnd
)
1777 return GEN_OPCODE16 ();
1781 bfin_gen_cactrl (REG_T reg
, int a
, int op
)
1789 return GEN_OPCODE16 ();
1793 bfin_gen_pushpopmultiple (int dr
, int pr
, int d
, int p
, int W
)
1795 INIT (PushPopMultiple
);
1803 return GEN_OPCODE16 ();
1807 bfin_gen_pushpopreg (REG_T reg
, int W
)
1813 grp
= (GROUP (reg
));
1817 return GEN_OPCODE16 ();
1820 /* Pseudo Debugging Support. */
1823 bfin_gen_pseudodbg (int fn
, int reg
, int grp
)
1831 return GEN_OPCODE16 ();
1835 bfin_gen_pseudodbg_assert (int dbgop
, REG_T regtest
, int expected
)
1837 INIT (PseudoDbg_Assert
);
1843 return GEN_OPCODE32 ();
1846 /* Multiple instruction generation. */
1849 bfin_gen_multi_instr (INSTR_T dsp32
, INSTR_T dsp16_grp1
, INSTR_T dsp16_grp2
)
1853 /* If it's a 0, convert into MNOP. */
1857 SET_MULTI_INSTRUCTION_BIT (dsp32
);
1861 dsp32
= gencode (0xc803);
1862 walk
= gencode (0x1800);
1868 dsp16_grp1
= gencode (0x0000);
1873 dsp16_grp2
= gencode (0x0000);
1876 walk
->next
= dsp16_grp1
;
1877 dsp16_grp1
->next
= dsp16_grp2
;
1878 dsp16_grp2
->next
= NULL_CODE
;
1884 bfin_gen_loop (Expr_Node
*expr
, REG_T reg
, int rop
, REG_T preg
)
1886 const char *loopsym
;
1887 char *lbeginsym
, *lendsym
;
1888 Expr_Node_Value lbeginval
, lendval
;
1889 Expr_Node
*lbegin
, *lend
;
1891 loopsym
= expr
->value
.s_value
;
1892 lbeginsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__BEGIN") + 5);
1893 lendsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__END") + 5);
1898 strcat (lbeginsym
, "L$L$");
1899 strcat (lbeginsym
, loopsym
);
1900 strcat (lbeginsym
, "__BEGIN");
1902 strcat (lendsym
, "L$L$");
1903 strcat (lendsym
, loopsym
);
1904 strcat (lendsym
, "__END");
1906 lbeginval
.s_value
= lbeginsym
;
1907 lendval
.s_value
= lendsym
;
1909 lbegin
= Expr_Node_Create (Expr_Node_Reloc
, lbeginval
, NULL
, NULL
);
1910 lend
= Expr_Node_Create (Expr_Node_Reloc
, lendval
, NULL
, NULL
);
1912 symbol_remove (symbol_find (loopsym
), &symbol_rootP
, &symbol_lastP
);
1914 return bfin_gen_loopsetup(lbegin
, reg
, rop
, lend
, preg
);
1918 bfin_eol_in_insn (char *line
)
1920 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1927 /* A semi-colon followed by a newline is always the end of a line. */
1928 if (line
[-1] == ';')
1931 if (line
[-1] == '|')
1934 /* If the || is on the next line, there might be leading whitespace. */
1936 while (*temp
== ' ' || *temp
== '\t') temp
++;
1945 bfin_start_label (char *ptr
)
1948 while (!ISSPACE (*ptr
) && !is_end_of_line
[(unsigned char) *ptr
])
1952 if (*ptr
== '(' || *ptr
== '[')
1959 bfin_force_relocation (struct fix
*fixp
)
1961 if (fixp
->fx_r_type
==BFD_RELOC_BFIN_16_LOW
1962 || fixp
->fx_r_type
== BFD_RELOC_BFIN_16_HIGH
)
1965 return generic_force_reloc (fixp
);