1 /* tc-bfin.c -- Assembler for the ADI Blackfin.
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 2, 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"
25 #include "bfin-defs.h"
27 #include "safe-ctype.h"
29 #include "dwarf2dbg.h"
32 #include "elf/common.h"
35 extern int yyparse (void);
36 struct yy_buffer_state
;
37 typedef struct yy_buffer_state
*YY_BUFFER_STATE
;
38 extern YY_BUFFER_STATE
yy_scan_string (const char *yy_str
);
39 extern void yy_delete_buffer (YY_BUFFER_STATE b
);
40 static parse_state
parse (char *line
);
41 static void bfin_s_bss
PARAMS ((int));
42 static int md_chars_to_number
PARAMS ((char *, int));
44 /* Global variables. */
45 struct bfin_insn
*insn
;
48 extern struct obstack mempool
;
51 /* Flags to set in the elf header */
52 #define DEFAULT_FLAGS 0
54 static flagword bfin_flags
= DEFAULT_FLAGS
;
55 static const char *bfin_pic_flag
= (const char *)0;
64 static const struct bfin_reg_entry bfin_reg_info
[] = {
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
},
195 {"ASTAT", REG_ASTAT
},
201 {"CYCLES", REG_CYCLES
},
202 {"CYCLES2", REG_CYCLES2
},
204 {"SEQSTAT", REG_SEQSTAT
},
205 {"SYSCFG", REG_SYSCFG
},
210 {"EMUDAT", REG_EMUDAT
},
214 /* Blackfin specific function to handle FD-PIC pointer initializations. */
217 bfin_pic_ptr (int nbytes
)
225 #ifdef md_flush_pending_output
226 md_flush_pending_output ();
229 if (is_it_end_of_statement ())
231 demand_empty_rest_of_line ();
236 md_cons_align (nbytes
);
241 bfd_reloc_code_real_type reloc_type
= BFD_RELOC_BFIN_FUNCDESC
;
243 if (strncasecmp (input_line_pointer
, "funcdesc(", 9) == 0)
245 input_line_pointer
+= 9;
247 if (*input_line_pointer
== ')')
248 input_line_pointer
++;
250 as_bad ("missing ')'");
253 error ("missing funcdesc in picptr");
257 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &exp
, 0,
260 while (*input_line_pointer
++ == ',');
262 input_line_pointer
--; /* Put terminator back into stream. */
263 demand_empty_rest_of_line ();
267 bfin_s_bss (int ignore ATTRIBUTE_UNUSED
)
271 temp
= get_absolute_expression ();
272 subseg_set (bss_section
, (subsegT
) temp
);
273 demand_empty_rest_of_line ();
276 const pseudo_typeS md_pseudo_table
[] = {
277 {"align", s_align_bytes
, 0},
280 {"picptr", bfin_pic_ptr
, 4},
281 {"code", obj_elf_section
, 0},
286 {"pdata", s_ignore
, 0},
287 {"var", s_ignore
, 0},
288 {"bss", bfin_s_bss
, 0},
292 /* Characters that are used to denote comments and line separators. */
293 const char comment_chars
[] = "";
294 const char line_comment_chars
[] = "#";
295 const char line_separator_chars
[] = ";";
297 /* Characters that can be used to separate the mantissa from the
298 exponent in floating point numbers. */
299 const char EXP_CHARS
[] = "eE";
301 /* Characters that mean this number is a floating point constant.
302 As in 0f12.456 or 0d1.2345e12. */
303 const char FLT_CHARS
[] = "fFdDxX";
305 /* Define bfin-specific command-line options (there are none). */
306 const char *md_shortopts
= "";
308 #define OPTION_FDPIC (OPTION_MD_BASE)
310 struct option md_longopts
[] =
312 { "mfdpic", no_argument
, NULL
, OPTION_FDPIC
},
313 { NULL
, no_argument
, NULL
, 0 },
316 size_t md_longopts_size
= sizeof (md_longopts
);
320 md_parse_option (int c ATTRIBUTE_UNUSED
, char *arg ATTRIBUTE_UNUSED
)
328 bfin_flags
|= EF_BFIN_FDPIC
;
329 bfin_pic_flag
= "-mfdpic";
337 md_show_usage (FILE * stream ATTRIBUTE_UNUSED
)
339 fprintf (stream
, _(" BFIN specific command line options:\n"));
342 /* Perform machine-specific initializations. */
346 /* Set the ELF flags if desired. */
348 bfd_set_private_flags (stdoutput
, bfin_flags
);
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.");
354 /* Ensure that lines can begin with '(', for multiple
355 register stack pops. */
356 lex_type
['('] = LEX_BEGIN_NAME
;
359 record_alignment (text_section
, 2);
360 record_alignment (data_section
, 2);
361 record_alignment (bss_section
, 2);
365 obstack_init (&mempool
);
368 extern int debug_codeselection
;
369 debug_codeselection
= 1;
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. */
380 md_assemble (char *line
)
383 extern char *current_inputline
;
385 struct bfin_insn
*tmp_insn
;
387 static size_t buffer_len
= 0;
391 if (len
+ 2 > buffer_len
)
394 free (current_inputline
);
395 buffer_len
= len
+ 40;
396 current_inputline
= xmalloc (buffer_len
);
398 memcpy (current_inputline
, line
, len
);
399 current_inputline
[len
] = ';';
400 current_inputline
[len
+ 1] = '\0';
402 state
= parse (current_inputline
);
403 if (state
== NO_INSN_GENERATED
)
406 for (insn_size
= 0, tmp_insn
= insn
; tmp_insn
; tmp_insn
= tmp_insn
->next
)
407 if (!tmp_insn
->reloc
|| !tmp_insn
->exp
->symbol
)
411 toP
= frag_more (insn_size
);
413 last_insn_size
= insn_size
;
420 if (insn
->reloc
&& insn
->exp
->symbol
)
422 char *prev_toP
= toP
- 2;
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
:
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
)
444 if (insn
->reloc
== BFD_ARELOC_BFIN_CONST
445 || insn
->reloc
== BFD_ARELOC_BFIN_PUSH
)
449 (prev_toP
- frag_now
->fr_literal
),
450 size
, insn
->exp
->symbol
, insn
->exp
->value
,
451 insn
->pcrel
, insn
->reloc
);
455 md_number_to_chars (toP
, insn
->value
, 2);
461 printf (" %02x%02x", ((unsigned char *) &insn
->value
)[0],
462 ((unsigned char *) &insn
->value
)[1]);
468 dwarf2_emit_insn (insn_size
);
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. */
484 YY_BUFFER_STATE buffstate
;
486 buffstate
= yy_scan_string (line
);
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. */
493 /* Call yyparse here. */
495 if (state
== SEMANTIC_ERROR
)
497 as_bad ("Parse failed.");
501 yy_delete_buffer (buffstate
);
505 /* We need to handle various expressions properly.
506 Such as, [SP--] = 34, concerned by md_assemble(). */
509 md_operand (expressionS
* expressionP
)
511 if (*input_line_pointer
== '[')
513 as_tsktsk ("We found a '['!");
514 input_line_pointer
++;
515 expression (expressionP
);
519 /* Handle undefined symbols. */
521 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
523 return (symbolS
*) 0;
527 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
528 segT segment ATTRIBUTE_UNUSED
)
533 /* Convert from target byte order to host byte order. */
536 md_chars_to_number (char *val
, int n
)
540 for (retval
= 0; n
--;)
549 md_apply_fix (fixS
*fixP
, valueT
*valueP
, segT seg ATTRIBUTE_UNUSED
)
551 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
553 long value
= *valueP
;
556 switch (fixP
->fx_r_type
)
558 case BFD_RELOC_BFIN_GOT
:
559 case BFD_RELOC_BFIN_GOT17M4
:
560 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
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);
567 case BFD_RELOC_BFIN_10_PCREL
:
570 if (value
< -1024 || value
> 1022)
571 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
572 "pcrel too far BFD_RELOC_BFIN_10");
574 /* 11 bit offset even numbered, so we remove right bit. */
576 newval
= md_chars_to_number (where
, 2);
577 newval
|= value
& 0x03ff;
578 md_number_to_chars (where
, newval
, 2);
581 case BFD_RELOC_BFIN_12_PCREL_JUMP
:
582 case BFD_RELOC_BFIN_12_PCREL_JUMP_S
:
583 case BFD_RELOC_12_PCREL
:
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. */
591 newval
= md_chars_to_number (where
, 2);
592 newval
|= value
& 0xfff;
593 md_number_to_chars (where
, newval
, 2);
596 case BFD_RELOC_BFIN_16_LOW
:
597 case BFD_RELOC_BFIN_16_HIGH
:
598 fixP
->fx_done
= FALSE
;
601 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
602 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
603 case BFD_RELOC_24_PCREL
:
607 if (value
< -16777216 || value
> 16777214)
608 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "pcrel too far BFD_RELOC_BFIN_24");
610 /* 25 bit offset even numbered, so we remove right bit. */
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);
619 case BFD_RELOC_BFIN_5_PCREL
: /* LSETUP (a, b) : "a" */
622 if (value
< 4 || value
> 30)
623 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "pcrel too far BFD_RELOC_BFIN_5");
625 newval
= md_chars_to_number (where
, 1);
626 newval
= (newval
& 0xf0) | (value
& 0xf);
627 md_number_to_chars (where
, newval
, 1);
630 case BFD_RELOC_BFIN_11_PCREL
: /* LSETUP (a, b) : "b" */
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. */
638 newval
= md_chars_to_number (where
, 2);
639 newval
|= value
& 0x03ff;
640 md_number_to_chars (where
, newval
, 2);
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);
649 case BFD_RELOC_BFIN_16_IMM
:
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);
657 md_number_to_chars (where
, value
, 4);
660 case BFD_RELOC_BFIN_PLTPC
:
661 md_number_to_chars (where
, value
, 2);
664 case BFD_RELOC_BFIN_FUNCDESC
:
665 case BFD_RELOC_VTABLE_INHERIT
:
666 case BFD_RELOC_VTABLE_ENTRY
:
667 fixP
->fx_done
= FALSE
;
671 if ((BFD_ARELOC_BFIN_PUSH
> fixP
->fx_r_type
) || (BFD_ARELOC_BFIN_COMP
< fixP
->fx_r_type
))
673 fprintf (stderr
, "Relocation %d not handled in gas." " Contact support.\n", fixP
->fx_r_type
);
679 fixP
->fx_done
= TRUE
;
683 /* Round up a section size to the appropriate boundary. */
685 md_section_align (segment
, size
)
689 int boundary
= bfd_get_section_alignment (stdoutput
, segment
);
690 return ((size
+ (1 << boundary
) - 1) & (-1 << boundary
));
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. */
699 /* Equal to MAX_PRECISION in atof-ieee.c. */
700 #define MAX_LITTLENUMS 6
703 md_atof (type
, litP
, sizeP
)
709 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
710 LITTLENUM_TYPE
*wordP
;
725 /* FIXME: Some targets allow other format chars for bigger sizes here. */
729 return _("Bad call to md_atof()");
732 t
= atof_ieee (input_line_pointer
, type
, words
);
734 input_line_pointer
= t
;
735 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
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
--;)
742 md_number_to_chars (litP
, (valueT
) (*wordP
--), sizeof (LITTLENUM_TYPE
));
743 litP
+= sizeof (LITTLENUM_TYPE
);
750 /* If while processing a fixup, a reloc really needs to be created
751 then it is done here. */
754 tc_gen_reloc (seg
, fixp
)
755 asection
*seg ATTRIBUTE_UNUSED
;
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
;
765 reloc
->addend
= fixp
->fx_offset
;
766 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
768 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
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
);
783 /* The location from which a PC relative jump should be calculated,
784 given a PC relative reloc. */
787 md_pcrel_from_section (fixP
, sec
)
791 if (fixP
->fx_addsy
!= (symbolS
*) NULL
792 && (!S_IS_DEFINED (fixP
->fx_addsy
)
793 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
795 /* The symbol is undefined (or is defined but not in this section).
796 Let the linker figure it out. */
799 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
802 /* Return true if the fix can be handled by GAS, false if it must
803 be passed through to the linker. */
806 bfin_fix_adjustable (fixS
*fixP
)
808 switch (fixP
->fx_r_type
)
810 /* Adjust_reloc_syms doesn't know about the GOT. */
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
:
815 /* We need the symbol name for the VTABLE entries. */
816 case BFD_RELOC_VTABLE_INHERIT
:
817 case BFD_RELOC_VTABLE_ENTRY
:
826 /* Handle the LOOP_BEGIN and LOOP_END statements.
827 Parse the Loop_Begin/Loop_End and create a label. */
829 bfin_start_line_hook ()
831 bfd_boolean maybe_begin
= FALSE
;
832 bfd_boolean maybe_end
= FALSE
;
834 char *c1
, *label_name
;
836 char *c
= input_line_pointer
;
841 /* Look for Loop_Begin or Loop_End statements. */
843 if (*c
!= 'L' && *c
!= 'l')
847 if (*c
!= 'O' && *c
!= 'o')
851 if (*c
!= 'O' && *c
!= 'o')
855 if (*c
!= 'P' && *c
!= 'p')
863 if (*c
== 'E' || *c
== 'e')
865 else if (*c
== 'B' || *c
== 'b')
873 if (*c
!= 'N' && *c
!= 'n')
877 if (*c
!= 'D' && *c
!= 'd')
884 if (*c
!= 'E' && *c
!= 'e')
888 if (*c
!= 'G' && *c
!= 'g')
892 if (*c
!= 'I' && *c
!= 'i')
896 if (*c
!= 'N' && *c
!= 'n')
901 while (ISSPACE (*c
)) c
++;
903 while (ISALPHA (*c
) || ISDIGIT (*c
) || *c
== '_') c
++;
905 input_line_pointer
= c
;
908 label_name
= (char *) xmalloc ((c
- c1
) + strlen ("__END") + 1);
910 strncat (label_name
, c1
, c
-c1
);
911 strcat (label_name
, "__END");
913 else /* maybe_begin. */
915 label_name
= (char *) xmalloc ((c
- c1
) + strlen ("__BEGIN") + 1);
917 strncat (label_name
, c1
, c
-c1
);
918 strcat (label_name
, "__BEGIN");
921 line_label
= colon (label_name
);
923 /* Loop_End follows the last instruction in the loop.
924 Adjust label address. */
926 line_label
->sy_value
.X_add_number
-= last_insn_size
;
930 /* Special extra functions that help bfin-parse.y perform its job. */
936 #include "bfin-defs.h"
938 struct obstack mempool
;
941 conscode (INSTR_T head
, INSTR_T tail
)
950 conctcode (INSTR_T head
, INSTR_T tail
)
952 INSTR_T temp
= (head
);
963 note_reloc (INSTR_T code
, Expr_Node
* symbol
, int reloc
, int pcrel
)
965 /* Assert that the symbol is not an operator. */
966 assert (symbol
->type
== Expr_Node_Reloc
);
968 return note_reloc1 (code
, symbol
->value
.s_value
, reloc
, pcrel
);
973 note_reloc1 (INSTR_T code
, const char *symbol
, int reloc
, int pcrel
)
976 code
->exp
= mkexpr (0, symbol_find_or_make (symbol
));
982 note_reloc2 (INSTR_T code
, const char *symbol
, int reloc
, int value
, int pcrel
)
985 code
->exp
= mkexpr (value
, symbol_find_or_make (symbol
));
991 gencode (unsigned long x
)
993 INSTR_T cell
= (INSTR_T
) obstack_alloc (&mempool
, sizeof (struct bfin_insn
));
994 memset (cell
, 0, sizeof (struct bfin_insn
));
1006 return (void *) obstack_alloc (&mempool
, n
);
1010 Expr_Node_Create (Expr_Node_Type type
,
1011 Expr_Node_Value value
,
1012 Expr_Node
*Left_Child
,
1013 Expr_Node
*Right_Child
)
1017 Expr_Node
*node
= (Expr_Node
*) allocate (sizeof (Expr_Node
));
1019 node
->value
= value
;
1020 node
->Left_Child
= Left_Child
;
1021 node
->Right_Child
= Right_Child
;
1025 static const char *con
= ".__constant";
1026 static const char *op
= ".__operator";
1027 static INSTR_T
Expr_Node_Gen_Reloc_R (Expr_Node
* head
);
1028 INSTR_T
Expr_Node_Gen_Reloc (Expr_Node
*head
, int parent_reloc
);
1031 Expr_Node_Gen_Reloc (Expr_Node
* head
, int parent_reloc
)
1033 /* Top level reloction expression generator VDSP style.
1034 If the relocation is just by itself, generate one item
1035 else generate this convoluted expression. */
1037 INSTR_T note
= NULL_CODE
;
1038 INSTR_T note1
= NULL_CODE
;
1039 int pcrel
= 1; /* Is the parent reloc pcrelative?
1040 This calculation here and HOWTO should match. */
1044 /* If it's 32 bit quantity then 16bit code needs to be added. */
1047 if (head
->type
== Expr_Node_Constant
)
1049 /* If note1 is not null code, we have to generate a right
1050 aligned value for the constant. Otherwise the reloc is
1051 a part of the basic command and the yacc file
1053 value
= head
->value
.i_value
;
1055 switch (parent_reloc
)
1057 /* Some reloctions will need to allocate extra words. */
1058 case BFD_RELOC_BFIN_16_IMM
:
1059 case BFD_RELOC_BFIN_16_LOW
:
1060 case BFD_RELOC_BFIN_16_HIGH
:
1061 note1
= conscode (gencode (value
), NULL_CODE
);
1064 case BFD_RELOC_BFIN_PLTPC
:
1065 note1
= conscode (gencode (value
), NULL_CODE
);
1069 case BFD_RELOC_BFIN_GOT
:
1070 case BFD_RELOC_BFIN_GOT17M4
:
1071 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
1072 note1
= conscode (gencode (value
), NULL_CODE
);
1075 case BFD_RELOC_24_PCREL
:
1076 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
1077 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
1078 /* These offsets are even numbered pcrel. */
1079 note1
= conscode (gencode (value
>> 1), NULL_CODE
);
1085 if (head
->type
== Expr_Node_Constant
)
1087 else if (head
->type
== Expr_Node_Reloc
)
1089 note
= note_reloc1 (gencode (0), head
->value
.s_value
, parent_reloc
, pcrel
);
1090 if (note1
!= NULL_CODE
)
1091 note
= conscode (note1
, note
);
1093 else if (head
->type
== Expr_Node_Binop
1094 && (head
->value
.op_value
== Expr_Op_Type_Add
1095 || head
->value
.op_value
== Expr_Op_Type_Sub
)
1096 && head
->Left_Child
->type
== Expr_Node_Reloc
1097 && head
->Right_Child
->type
== Expr_Node_Constant
)
1099 int val
= head
->Right_Child
->value
.i_value
;
1100 if (head
->value
.op_value
== Expr_Op_Type_Sub
)
1102 note
= conscode (note_reloc2 (gencode (0), head
->Left_Child
->value
.s_value
,
1103 parent_reloc
, val
, 0),
1105 if (note1
!= NULL_CODE
)
1106 note
= conscode (note1
, note
);
1110 /* Call the recursive function. */
1111 note
= note_reloc1 (gencode (0), op
, parent_reloc
, pcrel
);
1112 if (note1
!= NULL_CODE
)
1113 note
= conscode (note1
, note
);
1114 note
= conctcode (Expr_Node_Gen_Reloc_R (head
), note
);
1120 Expr_Node_Gen_Reloc_R (Expr_Node
* head
)
1128 case Expr_Node_Constant
:
1129 note
= conscode (note_reloc2 (gencode (0), con
, BFD_ARELOC_BFIN_CONST
, head
->value
.i_value
, 0), NULL_CODE
);
1131 case Expr_Node_Reloc
:
1132 note
= conscode (note_reloc (gencode (0), head
, BFD_ARELOC_BFIN_PUSH
, 0), NULL_CODE
);
1134 case Expr_Node_Binop
:
1135 note1
= conctcode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), Expr_Node_Gen_Reloc_R (head
->Right_Child
));
1136 switch (head
->value
.op_value
)
1138 case Expr_Op_Type_Add
:
1139 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_ADD
, 0), NULL_CODE
));
1141 case Expr_Op_Type_Sub
:
1142 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_SUB
, 0), NULL_CODE
));
1144 case Expr_Op_Type_Mult
:
1145 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MULT
, 0), NULL_CODE
));
1147 case Expr_Op_Type_Div
:
1148 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_DIV
, 0), NULL_CODE
));
1150 case Expr_Op_Type_Mod
:
1151 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MOD
, 0), NULL_CODE
));
1153 case Expr_Op_Type_Lshift
:
1154 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LSHIFT
, 0), NULL_CODE
));
1156 case Expr_Op_Type_Rshift
:
1157 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_RSHIFT
, 0), NULL_CODE
));
1159 case Expr_Op_Type_BAND
:
1160 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_AND
, 0), NULL_CODE
));
1162 case Expr_Op_Type_BOR
:
1163 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_OR
, 0), NULL_CODE
));
1165 case Expr_Op_Type_BXOR
:
1166 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_XOR
, 0), NULL_CODE
));
1168 case Expr_Op_Type_LAND
:
1169 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LAND
, 0), NULL_CODE
));
1171 case Expr_Op_Type_LOR
:
1172 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LOR
, 0), NULL_CODE
));
1175 fprintf (stderr
, "%s:%d:Unkonwn operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1180 case Expr_Node_Unop
:
1181 note1
= conscode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), NULL_CODE
);
1182 switch (head
->value
.op_value
)
1184 case Expr_Op_Type_NEG
:
1185 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_NEG
, 0), NULL_CODE
));
1187 case Expr_Op_Type_COMP
:
1188 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_COMP
, 0), NULL_CODE
));
1191 fprintf (stderr
, "%s:%d:Unkonwn operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1195 fprintf (stderr
, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__
, __LINE__
);
1201 /* Blackfin opcode generation. */
1203 /* These functions are called by the generated parser
1204 (from bfin-parse.y), the register type classification
1205 happens in bfin-lex.l. */
1207 #include "bfin-aux.h"
1208 #include "opcode/bfin.h"
1210 #define INIT(t) t c_code = init_##t
1211 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1212 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1214 #define HI(x) ((x >> 16) & 0xffff)
1215 #define LO(x) ((x ) & 0xffff)
1217 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1219 #define GEN_OPCODE32() \
1220 conscode (gencode (HI (c_code.opcode)), \
1221 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1223 #define GEN_OPCODE16() \
1224 conscode (gencode (c_code.opcode), NULL_CODE)
1227 /* 32 BIT INSTRUCTIONS. */
1230 /* DSP32 instruction generation. */
1233 bfin_gen_dsp32mac (int op1
, int MM
, int mmod
, int w1
, int P
,
1234 int h01
, int h11
, int h00
, int h10
, int op0
,
1235 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1251 /* If we have full reg assignments, mask out LSB to encode
1252 single or simultaneous even/odd register moves. */
1262 return GEN_OPCODE32 ();
1266 bfin_gen_dsp32mult (int op1
, int MM
, int mmod
, int w1
, int P
,
1267 int h01
, int h11
, int h00
, int h10
, int op0
,
1268 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1293 return GEN_OPCODE32 ();
1297 bfin_gen_dsp32alu (int HL
, int aopcde
, int aop
, int s
, int x
,
1298 REG_T dst0
, REG_T dst1
, REG_T src0
, REG_T src1
)
1312 return GEN_OPCODE32 ();
1316 bfin_gen_dsp32shift (int sopcde
, REG_T dst0
, REG_T src0
,
1317 REG_T src1
, int sop
, int HLs
)
1329 return GEN_OPCODE32 ();
1333 bfin_gen_dsp32shiftimm (int sopcde
, REG_T dst0
, int immag
,
1334 REG_T src1
, int sop
, int HLs
)
1336 INIT (DSP32ShiftImm
);
1346 return GEN_OPCODE32 ();
1352 bfin_gen_loopsetup (Expr_Node
* psoffset
, REG_T c
, int rop
,
1353 Expr_Node
* peoffset
, REG_T reg
)
1355 int soffset
, eoffset
;
1358 soffset
= (EXPR_VALUE (psoffset
) >> 1);
1360 eoffset
= (EXPR_VALUE (peoffset
) >> 1);
1367 conscode (gencode (HI (c_code
.opcode
)),
1368 conctcode (Expr_Node_Gen_Reloc (psoffset
, BFD_RELOC_BFIN_5_PCREL
),
1369 conctcode (gencode (LO (c_code
.opcode
)), Expr_Node_Gen_Reloc (peoffset
, BFD_RELOC_BFIN_11_PCREL
))));
1376 bfin_gen_calla (Expr_Node
* addr
, int S
)
1384 case 0 : reloc
= BFD_RELOC_BFIN_24_PCREL_JUMP_L
; break;
1385 case 1 : reloc
= BFD_RELOC_24_PCREL
; break;
1386 case 2 : reloc
= BFD_RELOC_BFIN_PLTPC
; break;
1392 val
= EXPR_VALUE (addr
) >> 1;
1393 high_val
= val
>> 16;
1395 return conscode (gencode (HI (c_code
.opcode
) | (high_val
& 0xff)),
1396 Expr_Node_Gen_Reloc (addr
, reloc
));
1400 bfin_gen_linkage (int R
, int framesize
)
1407 return GEN_OPCODE32 ();
1411 /* Load and Store. */
1414 bfin_gen_ldimmhalf (REG_T reg
, int H
, int S
, int Z
, Expr_Node
* phword
, int reloc
)
1417 unsigned val
= EXPR_VALUE (phword
);
1425 grp
= (GROUP (reg
));
1429 return conscode (gencode (HI (c_code
.opcode
)), Expr_Node_Gen_Reloc (phword
, BFD_RELOC_BFIN_16_IMM
));
1431 else if (reloc
== 1)
1433 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
));
1440 return GEN_OPCODE32 ();
1444 bfin_gen_ldstidxi (REG_T ptr
, REG_T reg
, int W
, int sz
, int Z
, Expr_Node
* poffset
)
1448 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1450 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1461 if (poffset
->type
!= Expr_Node_Constant
)
1463 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1464 /* distinguish between R0 = [P5 + symbol@GOT] and
1465 P5 = [P5 + _current_shared_library_p5_offset_]
1467 if (poffset
->type
== Expr_Node_Reloc
1468 && !strcmp (poffset
->value
.s_value
,
1469 "_current_shared_library_p5_offset_"))
1471 return conscode (gencode (HI (c_code
.opcode
)),
1472 Expr_Node_Gen_Reloc(poffset
, BFD_RELOC_16
));
1474 else if (poffset
->type
!= Expr_Node_GOT_Reloc
)
1477 return conscode (gencode (HI (c_code
.opcode
)),
1478 Expr_Node_Gen_Reloc(poffset
->Left_Child
,
1479 poffset
->value
.i_value
));
1485 { // load/store access size
1487 value
= EXPR_VALUE (poffset
) >> 2;
1490 value
= EXPR_VALUE (poffset
) >> 1;
1493 value
= EXPR_VALUE (poffset
);
1499 offset
= (value
& 0xffff);
1501 return GEN_OPCODE32 ();
1507 bfin_gen_ldst (REG_T ptr
, REG_T reg
, int aop
, int sz
, int Z
, int W
)
1511 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1513 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1524 return GEN_OPCODE16 ();
1528 bfin_gen_ldstii (REG_T ptr
, REG_T reg
, Expr_Node
* poffset
, int W
, int op
)
1535 if (!IS_PREG (*ptr
))
1537 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1545 value
= EXPR_VALUE (poffset
) >> 1;
1549 value
= EXPR_VALUE (poffset
) >> 2;
1561 return GEN_OPCODE16 ();
1565 bfin_gen_ldstiifp (REG_T sreg
, Expr_Node
* poffset
, int W
)
1567 /* Set bit 4 if it's a Preg. */
1568 int reg
= (sreg
->regno
& CODE_MASK
) | (IS_PREG (*sreg
) ? 0x8 : 0x0);
1569 int offset
= ((~(EXPR_VALUE (poffset
) >> 2)) & 0x1f) + 1;
1575 return GEN_OPCODE16 ();
1579 bfin_gen_ldstpmod (REG_T ptr
, REG_T reg
, int aop
, int W
, REG_T idx
)
1589 return GEN_OPCODE16 ();
1593 bfin_gen_dspldst (REG_T i
, REG_T reg
, int aop
, int W
, int m
)
1603 return GEN_OPCODE16 ();
1607 bfin_gen_logi2op (int opc
, int src
, int dst
)
1615 return GEN_OPCODE16 ();
1619 bfin_gen_brcc (int T
, int B
, Expr_Node
* poffset
)
1626 offset
= ((EXPR_VALUE (poffset
) >> 1));
1628 return conscode (gencode (c_code
.opcode
), Expr_Node_Gen_Reloc (poffset
, BFD_RELOC_BFIN_10_PCREL
));
1632 bfin_gen_ujump (Expr_Node
* poffset
)
1637 offset
= ((EXPR_VALUE (poffset
) >> 1));
1640 return conscode (gencode (c_code
.opcode
),
1641 Expr_Node_Gen_Reloc (
1642 poffset
, BFD_RELOC_BFIN_12_PCREL_JUMP_S
));
1646 bfin_gen_alu2op (REG_T dst
, REG_T src
, int opc
)
1654 return GEN_OPCODE16 ();
1658 bfin_gen_compi2opd (REG_T dst
, int src
, int op
)
1666 return GEN_OPCODE16 ();
1670 bfin_gen_compi2opp (REG_T dst
, int src
, int op
)
1678 return GEN_OPCODE16 ();
1682 bfin_gen_dagmodik (REG_T i
, int op
)
1689 return GEN_OPCODE16 ();
1693 bfin_gen_dagmodim (REG_T i
, REG_T m
, int op
, int br
)
1702 return GEN_OPCODE16 ();
1706 bfin_gen_ptr2op (REG_T dst
, REG_T src
, int opc
)
1714 return GEN_OPCODE16 ();
1718 bfin_gen_comp3op (REG_T src0
, REG_T src1
, REG_T dst
, int opc
)
1727 return GEN_OPCODE16 ();
1731 bfin_gen_ccflag (REG_T x
, int y
, int opc
, int I
, int G
)
1741 return GEN_OPCODE16 ();
1745 bfin_gen_ccmv (REG_T src
, REG_T dst
, int T
)
1758 return GEN_OPCODE16 ();
1762 bfin_gen_cc2stat (int cbit
, int op
, int D
)
1770 return GEN_OPCODE16 ();
1774 bfin_gen_regmv (REG_T src
, REG_T dst
)
1787 return GEN_OPCODE16 ();
1791 bfin_gen_cc2dreg (int op
, REG_T reg
)
1798 return GEN_OPCODE16 ();
1802 bfin_gen_progctrl (int prgfunc
, int poprnd
)
1809 return GEN_OPCODE16 ();
1813 bfin_gen_cactrl (REG_T reg
, int a
, int op
)
1821 return GEN_OPCODE16 ();
1825 bfin_gen_pushpopmultiple (int dr
, int pr
, int d
, int p
, int W
)
1827 INIT (PushPopMultiple
);
1835 return GEN_OPCODE16 ();
1839 bfin_gen_pushpopreg (REG_T reg
, int W
)
1845 grp
= (GROUP (reg
));
1849 return GEN_OPCODE16 ();
1852 /* Pseudo Debugging Support. */
1855 bfin_gen_pseudodbg (int fn
, int reg
, int grp
)
1863 return GEN_OPCODE16 ();
1867 bfin_gen_pseudodbg_assert (int dbgop
, REG_T regtest
, int expected
)
1869 INIT (PseudoDbg_Assert
);
1875 return GEN_OPCODE32 ();
1878 /* Multiple instruction generation. */
1881 bfin_gen_multi_instr (INSTR_T dsp32
, INSTR_T dsp16_grp1
, INSTR_T dsp16_grp2
)
1885 /* If it's a 0, convert into MNOP. */
1889 SET_MULTI_INSTRUCTION_BIT (dsp32
);
1893 dsp32
= gencode (0xc803);
1894 walk
= gencode (0x1800);
1900 dsp16_grp1
= gencode (0x0000);
1905 dsp16_grp2
= gencode (0x0000);
1908 walk
->next
= dsp16_grp1
;
1909 dsp16_grp1
->next
= dsp16_grp2
;
1910 dsp16_grp2
->next
= NULL_CODE
;
1916 bfin_gen_loop (Expr_Node
*expr
, REG_T reg
, int rop
, REG_T preg
)
1918 const char *loopsym
;
1919 char *lbeginsym
, *lendsym
;
1920 Expr_Node_Value lbeginval
, lendval
;
1921 Expr_Node
*lbegin
, *lend
;
1923 loopsym
= expr
->value
.s_value
;
1924 lbeginsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__BEGIN") + 1);
1925 lendsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__END") + 1);
1930 strcat (lbeginsym
, loopsym
);
1931 strcat (lbeginsym
, "__BEGIN");
1933 strcat (lendsym
, loopsym
);
1934 strcat (lendsym
, "__END");
1936 lbeginval
.s_value
= lbeginsym
;
1937 lendval
.s_value
= lendsym
;
1939 lbegin
= Expr_Node_Create (Expr_Node_Reloc
, lbeginval
, NULL
, NULL
);
1940 lend
= Expr_Node_Create (Expr_Node_Reloc
, lendval
, NULL
, NULL
);
1941 return bfin_gen_loopsetup(lbegin
, reg
, rop
, lend
, preg
);
1945 bfin_eol_in_insn (char *line
)
1947 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1954 /* A semi-colon followed by a newline is always the end of a line. */
1955 if (line
[-1] == ';')
1958 if (line
[-1] == '|')
1961 /* If the || is on the next line, there might be leading whitespace. */
1963 while (*temp
== ' ' || *temp
== '\t') temp
++;
1972 bfin_name_is_register (char *name
)
1976 if (*name
== '[' || *name
== '(')
1979 if ((name
[0] == 'W' || name
[0] == 'w') && name
[1] == '[')
1982 if ((name
[0] == 'B' || name
[0] == 'b') && name
[1] == '[')
1985 for (i
=0; bfin_reg_info
[i
].name
!= 0; i
++)
1987 if (!strcasecmp (bfin_reg_info
[i
].name
, name
))
1994 bfin_equals (Expr_Node
*sym
)
1998 c
= input_line_pointer
;
2002 input_line_pointer
= c
;
2004 equals ((char *) sym
->value
.s_value
, 1);
2008 bfin_start_label (char *ptr
)
2011 while (!ISSPACE (*ptr
) && !is_end_of_line
[(unsigned char) *ptr
])
2015 if (*ptr
== '(' || *ptr
== '[')
2022 bfin_force_relocation (struct fix
*fixp
)
2024 if (fixp
->fx_r_type
==BFD_RELOC_BFIN_16_LOW
2025 || fixp
->fx_r_type
== BFD_RELOC_BFIN_16_HIGH
)
2028 return generic_force_reloc (fixp
);