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
;
846 /* Look for Loop_Begin or Loop_End statements. */
848 if (*c
!= 'L' && *c
!= 'l')
852 if (*c
!= 'O' && *c
!= 'o')
856 if (*c
!= 'O' && *c
!= 'o')
860 if (*c
!= 'P' && *c
!= 'p')
868 if (*c
== 'E' || *c
== 'e')
870 else if (*c
== 'B' || *c
== 'b')
878 if (*c
!= 'N' && *c
!= 'n')
882 if (*c
!= 'D' && *c
!= 'd')
889 if (*c
!= 'E' && *c
!= 'e')
893 if (*c
!= 'G' && *c
!= 'g')
897 if (*c
!= 'I' && *c
!= 'i')
901 if (*c
!= 'N' && *c
!= 'n')
906 while (ISSPACE (*c
)) c
++;
908 while (ISALPHA (*c
) || ISDIGIT (*c
) || *c
== '_') c
++;
910 if (input_line_pointer
[-1] == '\n')
911 bump_line_counters ();
914 bump_line_counters ();
916 input_line_pointer
= c
;
919 label_name
= (char *) xmalloc ((c
- c1
) + strlen ("__END") + 1);
921 strncat (label_name
, c1
, c
-c1
);
922 strcat (label_name
, "__END");
924 else /* maybe_begin. */
926 label_name
= (char *) xmalloc ((c
- c1
) + strlen ("__BEGIN") + 1);
928 strncat (label_name
, c1
, c
-c1
);
929 strcat (label_name
, "__BEGIN");
932 line_label
= colon (label_name
);
934 /* Loop_End follows the last instruction in the loop.
935 Adjust label address. */
937 line_label
->sy_value
.X_add_number
-= last_insn_size
;
941 /* Special extra functions that help bfin-parse.y perform its job. */
947 #include "bfin-defs.h"
949 struct obstack mempool
;
952 conscode (INSTR_T head
, INSTR_T tail
)
961 conctcode (INSTR_T head
, INSTR_T tail
)
963 INSTR_T temp
= (head
);
974 note_reloc (INSTR_T code
, Expr_Node
* symbol
, int reloc
, int pcrel
)
976 /* Assert that the symbol is not an operator. */
977 assert (symbol
->type
== Expr_Node_Reloc
);
979 return note_reloc1 (code
, symbol
->value
.s_value
, reloc
, pcrel
);
984 note_reloc1 (INSTR_T code
, const char *symbol
, int reloc
, int pcrel
)
987 code
->exp
= mkexpr (0, symbol_find_or_make (symbol
));
993 note_reloc2 (INSTR_T code
, const char *symbol
, int reloc
, int value
, int pcrel
)
996 code
->exp
= mkexpr (value
, symbol_find_or_make (symbol
));
1002 gencode (unsigned long x
)
1004 INSTR_T cell
= (INSTR_T
) obstack_alloc (&mempool
, sizeof (struct bfin_insn
));
1005 memset (cell
, 0, sizeof (struct bfin_insn
));
1017 return (void *) obstack_alloc (&mempool
, n
);
1021 Expr_Node_Create (Expr_Node_Type type
,
1022 Expr_Node_Value value
,
1023 Expr_Node
*Left_Child
,
1024 Expr_Node
*Right_Child
)
1028 Expr_Node
*node
= (Expr_Node
*) allocate (sizeof (Expr_Node
));
1030 node
->value
= value
;
1031 node
->Left_Child
= Left_Child
;
1032 node
->Right_Child
= Right_Child
;
1036 static const char *con
= ".__constant";
1037 static const char *op
= ".__operator";
1038 static INSTR_T
Expr_Node_Gen_Reloc_R (Expr_Node
* head
);
1039 INSTR_T
Expr_Node_Gen_Reloc (Expr_Node
*head
, int parent_reloc
);
1042 Expr_Node_Gen_Reloc (Expr_Node
* head
, int parent_reloc
)
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. */
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. */
1055 /* If it's 32 bit quantity then 16bit code needs to be added. */
1058 if (head
->type
== Expr_Node_Constant
)
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
1064 value
= head
->value
.i_value
;
1066 switch (parent_reloc
)
1068 /* Some relocations will need to allocate extra words. */
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
);
1075 case BFD_RELOC_BFIN_PLTPC
:
1076 note1
= conscode (gencode (value
), NULL_CODE
);
1080 case BFD_RELOC_BFIN_GOT
:
1081 case BFD_RELOC_BFIN_GOT17M4
:
1082 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
1083 note1
= conscode (gencode (value
), NULL_CODE
);
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
);
1096 if (head
->type
== Expr_Node_Constant
)
1098 else if (head
->type
== Expr_Node_Reloc
)
1100 note
= note_reloc1 (gencode (0), head
->value
.s_value
, parent_reloc
, pcrel
);
1101 if (note1
!= NULL_CODE
)
1102 note
= conscode (note1
, note
);
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
)
1110 int val
= head
->Right_Child
->value
.i_value
;
1111 if (head
->value
.op_value
== Expr_Op_Type_Sub
)
1113 note
= conscode (note_reloc2 (gencode (0), head
->Left_Child
->value
.s_value
,
1114 parent_reloc
, val
, 0),
1116 if (note1
!= NULL_CODE
)
1117 note
= conscode (note1
, note
);
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
);
1131 Expr_Node_Gen_Reloc_R (Expr_Node
* head
)
1139 case Expr_Node_Constant
:
1140 note
= conscode (note_reloc2 (gencode (0), con
, BFD_ARELOC_BFIN_CONST
, head
->value
.i_value
, 0), NULL_CODE
);
1142 case Expr_Node_Reloc
:
1143 note
= conscode (note_reloc (gencode (0), head
, BFD_ARELOC_BFIN_PUSH
, 0), NULL_CODE
);
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
)
1149 case Expr_Op_Type_Add
:
1150 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_ADD
, 0), NULL_CODE
));
1152 case Expr_Op_Type_Sub
:
1153 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_SUB
, 0), NULL_CODE
));
1155 case Expr_Op_Type_Mult
:
1156 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MULT
, 0), NULL_CODE
));
1158 case Expr_Op_Type_Div
:
1159 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_DIV
, 0), NULL_CODE
));
1161 case Expr_Op_Type_Mod
:
1162 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MOD
, 0), NULL_CODE
));
1164 case Expr_Op_Type_Lshift
:
1165 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LSHIFT
, 0), NULL_CODE
));
1167 case Expr_Op_Type_Rshift
:
1168 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_RSHIFT
, 0), NULL_CODE
));
1170 case Expr_Op_Type_BAND
:
1171 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_AND
, 0), NULL_CODE
));
1173 case Expr_Op_Type_BOR
:
1174 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_OR
, 0), NULL_CODE
));
1176 case Expr_Op_Type_BXOR
:
1177 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_XOR
, 0), NULL_CODE
));
1179 case Expr_Op_Type_LAND
:
1180 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LAND
, 0), NULL_CODE
));
1182 case Expr_Op_Type_LOR
:
1183 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LOR
, 0), NULL_CODE
));
1186 fprintf (stderr
, "%s:%d:Unkonwn operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1191 case Expr_Node_Unop
:
1192 note1
= conscode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), NULL_CODE
);
1193 switch (head
->value
.op_value
)
1195 case Expr_Op_Type_NEG
:
1196 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_NEG
, 0), NULL_CODE
));
1198 case Expr_Op_Type_COMP
:
1199 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_COMP
, 0), NULL_CODE
));
1202 fprintf (stderr
, "%s:%d:Unkonwn operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1206 fprintf (stderr
, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__
, __LINE__
);
1212 /* Blackfin opcode generation. */
1214 /* These functions are called by the generated parser
1215 (from bfin-parse.y), the register type classification
1216 happens in bfin-lex.l. */
1218 #include "bfin-aux.h"
1219 #include "opcode/bfin.h"
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)
1225 #define HI(x) ((x >> 16) & 0xffff)
1226 #define LO(x) ((x ) & 0xffff)
1228 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1230 #define GEN_OPCODE32() \
1231 conscode (gencode (HI (c_code.opcode)), \
1232 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1234 #define GEN_OPCODE16() \
1235 conscode (gencode (c_code.opcode), NULL_CODE)
1238 /* 32 BIT INSTRUCTIONS. */
1241 /* DSP32 instruction generation. */
1244 bfin_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
)
1262 /* If we have full reg assignments, mask out LSB to encode
1263 single or simultaneous even/odd register moves. */
1273 return GEN_OPCODE32 ();
1277 bfin_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
)
1304 return GEN_OPCODE32 ();
1308 bfin_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
)
1323 return GEN_OPCODE32 ();
1327 bfin_gen_dsp32shift (int sopcde
, REG_T dst0
, REG_T src0
,
1328 REG_T src1
, int sop
, int HLs
)
1340 return GEN_OPCODE32 ();
1344 bfin_gen_dsp32shiftimm (int sopcde
, REG_T dst0
, int immag
,
1345 REG_T src1
, int sop
, int HLs
)
1347 INIT (DSP32ShiftImm
);
1357 return GEN_OPCODE32 ();
1363 bfin_gen_loopsetup (Expr_Node
* psoffset
, REG_T c
, int rop
,
1364 Expr_Node
* peoffset
, REG_T reg
)
1366 int soffset
, eoffset
;
1369 soffset
= (EXPR_VALUE (psoffset
) >> 1);
1371 eoffset
= (EXPR_VALUE (peoffset
) >> 1);
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
))));
1387 bfin_gen_calla (Expr_Node
* addr
, int 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;
1403 val
= EXPR_VALUE (addr
) >> 1;
1404 high_val
= val
>> 16;
1406 return conscode (gencode (HI (c_code
.opcode
) | (high_val
& 0xff)),
1407 Expr_Node_Gen_Reloc (addr
, reloc
));
1411 bfin_gen_linkage (int R
, int framesize
)
1418 return GEN_OPCODE32 ();
1422 /* Load and Store. */
1425 bfin_gen_ldimmhalf (REG_T reg
, int H
, int S
, int Z
, Expr_Node
* phword
, int reloc
)
1428 unsigned val
= EXPR_VALUE (phword
);
1436 grp
= (GROUP (reg
));
1440 return conscode (gencode (HI (c_code
.opcode
)), Expr_Node_Gen_Reloc (phword
, BFD_RELOC_BFIN_16_IMM
));
1442 else if (reloc
== 1)
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
));
1451 return GEN_OPCODE32 ();
1455 bfin_gen_ldstidxi (REG_T ptr
, REG_T reg
, int W
, int sz
, int Z
, Expr_Node
* poffset
)
1459 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1461 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1472 if (poffset
->type
!= Expr_Node_Constant
)
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_]
1478 if (poffset
->type
== Expr_Node_Reloc
1479 && !strcmp (poffset
->value
.s_value
,
1480 "_current_shared_library_p5_offset_"))
1482 return conscode (gencode (HI (c_code
.opcode
)),
1483 Expr_Node_Gen_Reloc(poffset
, BFD_RELOC_16
));
1485 else if (poffset
->type
!= Expr_Node_GOT_Reloc
)
1488 return conscode (gencode (HI (c_code
.opcode
)),
1489 Expr_Node_Gen_Reloc(poffset
->Left_Child
,
1490 poffset
->value
.i_value
));
1496 { // load/store access size
1498 value
= EXPR_VALUE (poffset
) >> 2;
1501 value
= EXPR_VALUE (poffset
) >> 1;
1504 value
= EXPR_VALUE (poffset
);
1510 offset
= (value
& 0xffff);
1512 return GEN_OPCODE32 ();
1518 bfin_gen_ldst (REG_T ptr
, REG_T reg
, int aop
, int sz
, int Z
, int W
)
1522 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1524 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1535 return GEN_OPCODE16 ();
1539 bfin_gen_ldstii (REG_T ptr
, REG_T reg
, Expr_Node
* poffset
, int W
, int op
)
1546 if (!IS_PREG (*ptr
))
1548 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1556 value
= EXPR_VALUE (poffset
) >> 1;
1560 value
= EXPR_VALUE (poffset
) >> 2;
1572 return GEN_OPCODE16 ();
1576 bfin_gen_ldstiifp (REG_T sreg
, Expr_Node
* poffset
, int W
)
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;
1586 return GEN_OPCODE16 ();
1590 bfin_gen_ldstpmod (REG_T ptr
, REG_T reg
, int aop
, int W
, REG_T idx
)
1600 return GEN_OPCODE16 ();
1604 bfin_gen_dspldst (REG_T i
, REG_T reg
, int aop
, int W
, int m
)
1614 return GEN_OPCODE16 ();
1618 bfin_gen_logi2op (int opc
, int src
, int dst
)
1626 return GEN_OPCODE16 ();
1630 bfin_gen_brcc (int T
, int B
, Expr_Node
* poffset
)
1637 offset
= ((EXPR_VALUE (poffset
) >> 1));
1639 return conscode (gencode (c_code
.opcode
), Expr_Node_Gen_Reloc (poffset
, BFD_RELOC_BFIN_10_PCREL
));
1643 bfin_gen_ujump (Expr_Node
* poffset
)
1648 offset
= ((EXPR_VALUE (poffset
) >> 1));
1651 return conscode (gencode (c_code
.opcode
),
1652 Expr_Node_Gen_Reloc (
1653 poffset
, BFD_RELOC_BFIN_12_PCREL_JUMP_S
));
1657 bfin_gen_alu2op (REG_T dst
, REG_T src
, int opc
)
1665 return GEN_OPCODE16 ();
1669 bfin_gen_compi2opd (REG_T dst
, int src
, int op
)
1677 return GEN_OPCODE16 ();
1681 bfin_gen_compi2opp (REG_T dst
, int src
, int op
)
1689 return GEN_OPCODE16 ();
1693 bfin_gen_dagmodik (REG_T i
, int op
)
1700 return GEN_OPCODE16 ();
1704 bfin_gen_dagmodim (REG_T i
, REG_T m
, int op
, int br
)
1713 return GEN_OPCODE16 ();
1717 bfin_gen_ptr2op (REG_T dst
, REG_T src
, int opc
)
1725 return GEN_OPCODE16 ();
1729 bfin_gen_comp3op (REG_T src0
, REG_T src1
, REG_T dst
, int opc
)
1738 return GEN_OPCODE16 ();
1742 bfin_gen_ccflag (REG_T x
, int y
, int opc
, int I
, int G
)
1752 return GEN_OPCODE16 ();
1756 bfin_gen_ccmv (REG_T src
, REG_T dst
, int T
)
1769 return GEN_OPCODE16 ();
1773 bfin_gen_cc2stat (int cbit
, int op
, int D
)
1781 return GEN_OPCODE16 ();
1785 bfin_gen_regmv (REG_T src
, REG_T dst
)
1798 return GEN_OPCODE16 ();
1802 bfin_gen_cc2dreg (int op
, REG_T reg
)
1809 return GEN_OPCODE16 ();
1813 bfin_gen_progctrl (int prgfunc
, int poprnd
)
1820 return GEN_OPCODE16 ();
1824 bfin_gen_cactrl (REG_T reg
, int a
, int op
)
1832 return GEN_OPCODE16 ();
1836 bfin_gen_pushpopmultiple (int dr
, int pr
, int d
, int p
, int W
)
1838 INIT (PushPopMultiple
);
1846 return GEN_OPCODE16 ();
1850 bfin_gen_pushpopreg (REG_T reg
, int W
)
1856 grp
= (GROUP (reg
));
1860 return GEN_OPCODE16 ();
1863 /* Pseudo Debugging Support. */
1866 bfin_gen_pseudodbg (int fn
, int reg
, int grp
)
1874 return GEN_OPCODE16 ();
1878 bfin_gen_pseudodbg_assert (int dbgop
, REG_T regtest
, int expected
)
1880 INIT (PseudoDbg_Assert
);
1886 return GEN_OPCODE32 ();
1889 /* Multiple instruction generation. */
1892 bfin_gen_multi_instr (INSTR_T dsp32
, INSTR_T dsp16_grp1
, INSTR_T dsp16_grp2
)
1896 /* If it's a 0, convert into MNOP. */
1900 SET_MULTI_INSTRUCTION_BIT (dsp32
);
1904 dsp32
= gencode (0xc803);
1905 walk
= gencode (0x1800);
1911 dsp16_grp1
= gencode (0x0000);
1916 dsp16_grp2
= gencode (0x0000);
1919 walk
->next
= dsp16_grp1
;
1920 dsp16_grp1
->next
= dsp16_grp2
;
1921 dsp16_grp2
->next
= NULL_CODE
;
1927 bfin_gen_loop (Expr_Node
*expr
, REG_T reg
, int rop
, REG_T preg
)
1929 const char *loopsym
;
1930 char *lbeginsym
, *lendsym
;
1931 Expr_Node_Value lbeginval
, lendval
;
1932 Expr_Node
*lbegin
, *lend
;
1934 loopsym
= expr
->value
.s_value
;
1935 lbeginsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__BEGIN") + 1);
1936 lendsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__END") + 1);
1941 strcat (lbeginsym
, loopsym
);
1942 strcat (lbeginsym
, "__BEGIN");
1944 strcat (lendsym
, loopsym
);
1945 strcat (lendsym
, "__END");
1947 lbeginval
.s_value
= lbeginsym
;
1948 lendval
.s_value
= lendsym
;
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
);
1956 bfin_eol_in_insn (char *line
)
1958 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1965 /* A semi-colon followed by a newline is always the end of a line. */
1966 if (line
[-1] == ';')
1969 if (line
[-1] == '|')
1972 /* If the || is on the next line, there might be leading whitespace. */
1974 while (*temp
== ' ' || *temp
== '\t') temp
++;
1983 bfin_start_label (char *ptr
)
1986 while (!ISSPACE (*ptr
) && !is_end_of_line
[(unsigned char) *ptr
])
1990 if (*ptr
== '(' || *ptr
== '[')
1997 bfin_force_relocation (struct fix
*fixp
)
1999 if (fixp
->fx_r_type
==BFD_RELOC_BFIN_16_LOW
2000 || fixp
->fx_r_type
== BFD_RELOC_BFIN_16_HIGH
)
2003 return generic_force_reloc (fixp
);