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"
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
);
40 static void bfin_s_bss
PARAMS ((int));
41 static int md_chars_to_number
PARAMS ((char *, int));
43 /* Global variables. */
44 struct bfin_insn
*insn
;
47 extern struct obstack mempool
;
50 /* Flags to set in the elf header */
51 #define DEFAULT_FLAGS 0
53 static flagword bfin_flags
= DEFAULT_FLAGS
;
54 static const char *bfin_pic_flag
= (const char *)0;
63 static const struct bfin_reg_entry bfin_reg_info
[] = {
185 {"sftreset", REG_sftreset
},
186 {"omode", REG_omode
},
187 {"excause", REG_excause
},
188 {"emucause", REG_emucause
},
189 {"idle_req", REG_idle_req
},
190 {"hwerrcause", REG_hwerrcause
},
194 {"ASTAT", REG_ASTAT
},
200 {"CYCLES", REG_CYCLES
},
201 {"CYCLES2", REG_CYCLES2
},
203 {"SEQSTAT", REG_SEQSTAT
},
204 {"SYSCFG", REG_SYSCFG
},
209 {"EMUDAT", REG_EMUDAT
},
213 /* Blackfin specific function to handle FD-PIC pointer initializations. */
216 bfin_pic_ptr (int nbytes
)
224 #ifdef md_flush_pending_output
225 md_flush_pending_output ();
228 if (is_it_end_of_statement ())
230 demand_empty_rest_of_line ();
235 md_cons_align (nbytes
);
240 bfd_reloc_code_real_type reloc_type
= BFD_RELOC_BFIN_FUNCDESC
;
242 if (strncasecmp (input_line_pointer
, "funcdesc(", 9) == 0)
244 input_line_pointer
+= 9;
246 if (*input_line_pointer
== ')')
247 input_line_pointer
++;
249 as_bad ("missing ')'");
252 error ("missing funcdesc in picptr");
256 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &exp
, 0,
259 while (*input_line_pointer
++ == ',');
261 input_line_pointer
--; /* Put terminator back into stream. */
262 demand_empty_rest_of_line ();
266 bfin_s_bss (int ignore ATTRIBUTE_UNUSED
)
270 temp
= get_absolute_expression ();
271 subseg_set (bss_section
, (subsegT
) temp
);
272 demand_empty_rest_of_line ();
275 const pseudo_typeS md_pseudo_table
[] = {
276 {"align", s_align_bytes
, 0},
279 {"picptr", bfin_pic_ptr
, 4},
280 {"code", obj_elf_section
, 0},
285 {"pdata", s_ignore
, 0},
286 {"var", s_ignore
, 0},
287 {"bss", bfin_s_bss
, 0},
291 /* Characters that are used to denote comments and line separators. */
292 const char comment_chars
[] = "";
293 const char line_comment_chars
[] = "#";
294 const char line_separator_chars
[] = ";";
296 /* Characters that can be used to separate the mantissa from the
297 exponent in floating point numbers. */
298 const char EXP_CHARS
[] = "eE";
300 /* Characters that mean this number is a floating point constant.
301 As in 0f12.456 or 0d1.2345e12. */
302 const char FLT_CHARS
[] = "fFdDxX";
304 /* Define bfin-specific command-line options (there are none). */
305 const char *md_shortopts
= "";
307 #define OPTION_FDPIC (OPTION_MD_BASE)
309 struct option md_longopts
[] =
311 { "mfdpic", no_argument
, NULL
, OPTION_FDPIC
},
312 { NULL
, no_argument
, NULL
, 0 },
315 size_t md_longopts_size
= sizeof (md_longopts
);
319 md_parse_option (int c ATTRIBUTE_UNUSED
, char *arg ATTRIBUTE_UNUSED
)
327 bfin_flags
|= EF_BFIN_FDPIC
;
328 bfin_pic_flag
= "-mfdpic";
336 md_show_usage (FILE * stream ATTRIBUTE_UNUSED
)
338 fprintf (stream
, _(" BFIN specific command line options:\n"));
341 /* Perform machine-specific initializations. */
345 /* Set the ELF flags if desired. */
347 bfd_set_private_flags (stdoutput
, bfin_flags
);
349 /* Set the default machine type. */
350 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_bfin
, 0))
351 as_warn ("Could not set architecture and machine.");
353 /* Ensure that lines can begin with '(', for multiple
354 register stack pops. */
355 lex_type
['('] = LEX_BEGIN_NAME
;
358 record_alignment (text_section
, 2);
359 record_alignment (data_section
, 2);
360 record_alignment (bss_section
, 2);
364 obstack_init (&mempool
);
367 extern int debug_codeselection
;
368 debug_codeselection
= 1;
374 /* Perform the main parsing, and assembly of the input here. Also,
375 call the required routines for alignment and fixups here.
376 This is called for every line that contains real assembly code. */
379 md_assemble (char *line
)
382 extern char *current_inputline
;
384 struct bfin_insn
*tmp_insn
;
386 static size_t buffer_len
= 0;
390 if (len
+ 2 > buffer_len
)
393 free (current_inputline
);
394 buffer_len
= len
+ 40;
395 current_inputline
= xmalloc (buffer_len
);
397 memcpy (current_inputline
, line
, len
);
398 current_inputline
[len
] = ';';
399 current_inputline
[len
+ 1] = '\0';
401 state
= parse (current_inputline
);
402 if (state
== NO_INSN_GENERATED
)
405 for (insn_size
= 0, tmp_insn
= insn
; tmp_insn
; tmp_insn
= tmp_insn
->next
)
406 if (!tmp_insn
->reloc
|| !tmp_insn
->exp
->symbol
)
410 toP
= frag_more (insn_size
);
412 last_insn_size
= insn_size
;
419 if (insn
->reloc
&& insn
->exp
->symbol
)
421 char *prev_toP
= toP
- 2;
424 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
425 case BFD_RELOC_24_PCREL
:
426 case BFD_RELOC_BFIN_16_LOW
:
427 case BFD_RELOC_BFIN_16_HIGH
:
434 /* Following if condition checks for the arithmetic relocations.
435 If the case then it doesn't required to generate the code.
436 It has been assumed that, their ID will be contiguous. */
437 if ((BFD_ARELOC_BFIN_PUSH
<= insn
->reloc
438 && BFD_ARELOC_BFIN_COMP
>= insn
->reloc
)
439 || insn
->reloc
== BFD_RELOC_BFIN_16_IMM
)
443 if (insn
->reloc
== BFD_ARELOC_BFIN_CONST
444 || insn
->reloc
== BFD_ARELOC_BFIN_PUSH
)
448 (prev_toP
- frag_now
->fr_literal
),
449 size
, insn
->exp
->symbol
, insn
->exp
->value
,
450 insn
->pcrel
, insn
->reloc
);
454 md_number_to_chars (toP
, insn
->value
, 2);
460 printf (" %02x%02x", ((unsigned char *) &insn
->value
)[0],
461 ((unsigned char *) &insn
->value
)[1]);
467 dwarf2_emit_insn (insn_size
);
471 /* Parse one line of instructions, and generate opcode for it.
472 To parse the line, YACC and LEX are used, because the instruction set
473 syntax doesn't confirm to the AT&T assembly syntax.
474 To call a YACC & LEX generated parser, we must provide the input via
475 a FILE stream, otherwise stdin is used by default. Below the input
476 to the function will be put into a temporary file, then the generated
477 parser uses the temporary file for parsing. */
483 YY_BUFFER_STATE buffstate
;
485 buffstate
= yy_scan_string (line
);
487 /* our lex requires setting the start state to keyword
488 every line as the first word may be a keyword.
489 Fixes a bug where we could not have keywords as labels. */
492 /* Call yyparse here. */
494 if (state
== SEMANTIC_ERROR
)
496 as_bad ("Parse failed.");
500 yy_delete_buffer (buffstate
);
504 /* We need to handle various expressions properly.
505 Such as, [SP--] = 34, concerned by md_assemble(). */
508 md_operand (expressionS
* expressionP
)
510 if (*input_line_pointer
== '[')
512 as_tsktsk ("We found a '['!");
513 input_line_pointer
++;
514 expression (expressionP
);
518 /* Handle undefined symbols. */
520 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
522 return (symbolS
*) 0;
526 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
527 segT segment ATTRIBUTE_UNUSED
)
532 /* Convert from target byte order to host byte order. */
535 md_chars_to_number (char *val
, int n
)
539 for (retval
= 0; n
--;)
548 md_apply_fix (fixS
*fixP
, valueT
*valueP
, segT seg ATTRIBUTE_UNUSED
)
550 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
552 long value
= *valueP
;
555 switch (fixP
->fx_r_type
)
557 case BFD_RELOC_BFIN_GOT
:
558 case BFD_RELOC_BFIN_GOT17M4
:
559 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
560 fixP
->fx_no_overflow
= 1;
561 newval
= md_chars_to_number (where
, 2);
562 newval
|= 0x0 & 0x7f;
563 md_number_to_chars (where
, newval
, 2);
566 case BFD_RELOC_BFIN_10_PCREL
:
569 if (value
< -1024 || value
> 1022)
570 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
571 "pcrel too far BFD_RELOC_BFIN_10");
573 /* 11 bit offset even numbered, so we remove right bit. */
575 newval
= md_chars_to_number (where
, 2);
576 newval
|= value
& 0x03ff;
577 md_number_to_chars (where
, newval
, 2);
580 case BFD_RELOC_BFIN_12_PCREL_JUMP
:
581 case BFD_RELOC_BFIN_12_PCREL_JUMP_S
:
582 case BFD_RELOC_12_PCREL
:
586 if (value
< -4096 || value
> 4094)
587 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "pcrel too far BFD_RELOC_BFIN_12");
588 /* 13 bit offset even numbered, so we remove right bit. */
590 newval
= md_chars_to_number (where
, 2);
591 newval
|= value
& 0xfff;
592 md_number_to_chars (where
, newval
, 2);
595 case BFD_RELOC_BFIN_16_LOW
:
596 case BFD_RELOC_BFIN_16_HIGH
:
597 fixP
->fx_done
= FALSE
;
600 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
601 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
602 case BFD_RELOC_24_PCREL
:
606 if (value
< -16777216 || value
> 16777214)
607 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "pcrel too far BFD_RELOC_BFIN_24");
609 /* 25 bit offset even numbered, so we remove right bit. */
613 md_number_to_chars (where
- 2, value
>> 16, 1);
614 md_number_to_chars (where
, value
, 1);
615 md_number_to_chars (where
+ 1, value
>> 8, 1);
618 case BFD_RELOC_BFIN_5_PCREL
: /* LSETUP (a, b) : "a" */
621 if (value
< 4 || value
> 30)
622 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "pcrel too far BFD_RELOC_BFIN_5");
624 newval
= md_chars_to_number (where
, 1);
625 newval
= (newval
& 0xf0) | (value
& 0xf);
626 md_number_to_chars (where
, newval
, 1);
629 case BFD_RELOC_BFIN_11_PCREL
: /* LSETUP (a, b) : "b" */
633 if (value
< 4 || value
> 2046)
634 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "pcrel too far BFD_RELOC_BFIN_11_PCREL");
635 /* 11 bit unsigned even, so we remove right bit. */
637 newval
= md_chars_to_number (where
, 2);
638 newval
|= value
& 0x03ff;
639 md_number_to_chars (where
, newval
, 2);
643 if (value
< -0x80 || value
>= 0x7f)
644 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "rel too far BFD_RELOC_8");
645 md_number_to_chars (where
, value
, 1);
648 case BFD_RELOC_BFIN_16_IMM
:
650 if (value
< -0x8000 || value
>= 0x7fff)
651 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "rel too far BFD_RELOC_8");
652 md_number_to_chars (where
, value
, 2);
656 md_number_to_chars (where
, value
, 4);
659 case BFD_RELOC_BFIN_PLTPC
:
660 md_number_to_chars (where
, value
, 2);
663 case BFD_RELOC_BFIN_FUNCDESC
:
664 case BFD_RELOC_VTABLE_INHERIT
:
665 case BFD_RELOC_VTABLE_ENTRY
:
666 fixP
->fx_done
= FALSE
;
670 if ((BFD_ARELOC_BFIN_PUSH
> fixP
->fx_r_type
) || (BFD_ARELOC_BFIN_COMP
< fixP
->fx_r_type
))
672 fprintf (stderr
, "Relocation %d not handled in gas." " Contact support.\n", fixP
->fx_r_type
);
678 fixP
->fx_done
= TRUE
;
682 /* Round up a section size to the appropriate boundary. */
684 md_section_align (segment
, size
)
688 int boundary
= bfd_get_section_alignment (stdoutput
, segment
);
689 return ((size
+ (1 << boundary
) - 1) & (-1 << boundary
));
693 /* Turn a string in input_line_pointer into a floating point
694 constant of type type, and store the appropriate bytes in
695 *litP. The number of LITTLENUMS emitted is stored in *sizeP.
696 An error message is returned, or NULL on OK. */
698 /* Equal to MAX_PRECISION in atof-ieee.c. */
699 #define MAX_LITTLENUMS 6
702 md_atof (type
, litP
, sizeP
)
708 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
709 LITTLENUM_TYPE
*wordP
;
724 /* FIXME: Some targets allow other format chars for bigger sizes here. */
728 return _("Bad call to md_atof()");
731 t
= atof_ieee (input_line_pointer
, type
, words
);
733 input_line_pointer
= t
;
734 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
736 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
737 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
738 the littleendianness of the processor. */
739 for (wordP
= words
+ prec
- 1; prec
--;)
741 md_number_to_chars (litP
, (valueT
) (*wordP
--), sizeof (LITTLENUM_TYPE
));
742 litP
+= sizeof (LITTLENUM_TYPE
);
749 /* If while processing a fixup, a reloc really needs to be created
750 then it is done here. */
753 tc_gen_reloc (seg
, fixp
)
754 asection
*seg ATTRIBUTE_UNUSED
;
759 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
760 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
761 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
762 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
764 reloc
->addend
= fixp
->fx_offset
;
765 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
767 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
769 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
770 /* xgettext:c-format. */
771 _("reloc %d not supported by object file format"),
772 (int) fixp
->fx_r_type
);
782 /* The location from which a PC relative jump should be calculated,
783 given a PC relative reloc. */
786 md_pcrel_from_section (fixP
, sec
)
790 if (fixP
->fx_addsy
!= (symbolS
*) NULL
791 && (!S_IS_DEFINED (fixP
->fx_addsy
)
792 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
794 /* The symbol is undefined (or is defined but not in this section).
795 Let the linker figure it out. */
798 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
801 /* Return true if the fix can be handled by GAS, false if it must
802 be passed through to the linker. */
805 bfin_fix_adjustable (fixS
*fixP
)
807 switch (fixP
->fx_r_type
)
809 /* Adjust_reloc_syms doesn't know about the GOT. */
810 case BFD_RELOC_BFIN_GOT
:
811 case BFD_RELOC_BFIN_GOT17M4
:
812 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
813 case BFD_RELOC_BFIN_PLTPC
:
814 /* We need the symbol name for the VTABLE entries. */
815 case BFD_RELOC_VTABLE_INHERIT
:
816 case BFD_RELOC_VTABLE_ENTRY
:
825 /* Handle the LOOP_BEGIN and LOOP_END statements.
826 Parse the Loop_Begin/Loop_End and create a label. */
828 bfin_start_line_hook ()
830 bfd_boolean maybe_begin
= FALSE
;
831 bfd_boolean maybe_end
= FALSE
;
833 char *c1
, *label_name
;
835 char *c
= input_line_pointer
;
845 /* Look for Loop_Begin or Loop_End statements. */
847 if (*c
!= 'L' && *c
!= 'l')
851 if (*c
!= 'O' && *c
!= 'o')
855 if (*c
!= 'O' && *c
!= 'o')
859 if (*c
!= 'P' && *c
!= 'p')
867 if (*c
== 'E' || *c
== 'e')
869 else if (*c
== 'B' || *c
== 'b')
877 if (*c
!= 'N' && *c
!= 'n')
881 if (*c
!= 'D' && *c
!= 'd')
888 if (*c
!= 'E' && *c
!= 'e')
892 if (*c
!= 'G' && *c
!= 'g')
896 if (*c
!= 'I' && *c
!= 'i')
900 if (*c
!= 'N' && *c
!= 'n')
905 while (ISSPACE (*c
)) c
++;
907 while (ISALPHA (*c
) || ISDIGIT (*c
) || *c
== '_') c
++;
909 if (input_line_pointer
[-1] == '\n')
910 bump_line_counters ();
913 bump_line_counters ();
915 input_line_pointer
= c
;
918 label_name
= (char *) xmalloc ((c
- c1
) + strlen ("__END") + 1);
920 strncat (label_name
, c1
, c
-c1
);
921 strcat (label_name
, "__END");
923 else /* maybe_begin. */
925 label_name
= (char *) xmalloc ((c
- c1
) + strlen ("__BEGIN") + 1);
927 strncat (label_name
, c1
, c
-c1
);
928 strcat (label_name
, "__BEGIN");
931 line_label
= colon (label_name
);
933 /* Loop_End follows the last instruction in the loop.
934 Adjust label address. */
936 line_label
->sy_value
.X_add_number
-= last_insn_size
;
940 /* Special extra functions that help bfin-parse.y perform its job. */
944 struct obstack mempool
;
947 conscode (INSTR_T head
, INSTR_T tail
)
956 conctcode (INSTR_T head
, INSTR_T tail
)
958 INSTR_T temp
= (head
);
969 note_reloc (INSTR_T code
, Expr_Node
* symbol
, int reloc
, int pcrel
)
971 /* Assert that the symbol is not an operator. */
972 assert (symbol
->type
== Expr_Node_Reloc
);
974 return note_reloc1 (code
, symbol
->value
.s_value
, reloc
, pcrel
);
979 note_reloc1 (INSTR_T code
, const char *symbol
, int reloc
, int pcrel
)
982 code
->exp
= mkexpr (0, symbol_find_or_make (symbol
));
988 note_reloc2 (INSTR_T code
, const char *symbol
, int reloc
, int value
, int pcrel
)
991 code
->exp
= mkexpr (value
, symbol_find_or_make (symbol
));
997 gencode (unsigned long x
)
999 INSTR_T cell
= (INSTR_T
) obstack_alloc (&mempool
, sizeof (struct bfin_insn
));
1000 memset (cell
, 0, sizeof (struct bfin_insn
));
1012 return (void *) obstack_alloc (&mempool
, n
);
1016 Expr_Node_Create (Expr_Node_Type type
,
1017 Expr_Node_Value value
,
1018 Expr_Node
*Left_Child
,
1019 Expr_Node
*Right_Child
)
1023 Expr_Node
*node
= (Expr_Node
*) allocate (sizeof (Expr_Node
));
1025 node
->value
= value
;
1026 node
->Left_Child
= Left_Child
;
1027 node
->Right_Child
= Right_Child
;
1031 static const char *con
= ".__constant";
1032 static const char *op
= ".__operator";
1033 static INSTR_T
Expr_Node_Gen_Reloc_R (Expr_Node
* head
);
1034 INSTR_T
Expr_Node_Gen_Reloc (Expr_Node
*head
, int parent_reloc
);
1037 Expr_Node_Gen_Reloc (Expr_Node
* head
, int parent_reloc
)
1039 /* Top level reloction expression generator VDSP style.
1040 If the relocation is just by itself, generate one item
1041 else generate this convoluted expression. */
1043 INSTR_T note
= NULL_CODE
;
1044 INSTR_T note1
= NULL_CODE
;
1045 int pcrel
= 1; /* Is the parent reloc pcrelative?
1046 This calculation here and HOWTO should match. */
1050 /* If it's 32 bit quantity then 16bit code needs to be added. */
1053 if (head
->type
== Expr_Node_Constant
)
1055 /* If note1 is not null code, we have to generate a right
1056 aligned value for the constant. Otherwise the reloc is
1057 a part of the basic command and the yacc file
1059 value
= head
->value
.i_value
;
1061 switch (parent_reloc
)
1063 /* Some relocations will need to allocate extra words. */
1064 case BFD_RELOC_BFIN_16_IMM
:
1065 case BFD_RELOC_BFIN_16_LOW
:
1066 case BFD_RELOC_BFIN_16_HIGH
:
1067 note1
= conscode (gencode (value
), NULL_CODE
);
1070 case BFD_RELOC_BFIN_PLTPC
:
1071 note1
= conscode (gencode (value
), NULL_CODE
);
1075 case BFD_RELOC_BFIN_GOT
:
1076 case BFD_RELOC_BFIN_GOT17M4
:
1077 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
1078 note1
= conscode (gencode (value
), NULL_CODE
);
1081 case BFD_RELOC_24_PCREL
:
1082 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
1083 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
1084 /* These offsets are even numbered pcrel. */
1085 note1
= conscode (gencode (value
>> 1), NULL_CODE
);
1091 if (head
->type
== Expr_Node_Constant
)
1093 else if (head
->type
== Expr_Node_Reloc
)
1095 note
= note_reloc1 (gencode (0), head
->value
.s_value
, parent_reloc
, pcrel
);
1096 if (note1
!= NULL_CODE
)
1097 note
= conscode (note1
, note
);
1099 else if (head
->type
== Expr_Node_Binop
1100 && (head
->value
.op_value
== Expr_Op_Type_Add
1101 || head
->value
.op_value
== Expr_Op_Type_Sub
)
1102 && head
->Left_Child
->type
== Expr_Node_Reloc
1103 && head
->Right_Child
->type
== Expr_Node_Constant
)
1105 int val
= head
->Right_Child
->value
.i_value
;
1106 if (head
->value
.op_value
== Expr_Op_Type_Sub
)
1108 note
= conscode (note_reloc2 (gencode (0), head
->Left_Child
->value
.s_value
,
1109 parent_reloc
, val
, 0),
1111 if (note1
!= NULL_CODE
)
1112 note
= conscode (note1
, note
);
1116 /* Call the recursive function. */
1117 note
= note_reloc1 (gencode (0), op
, parent_reloc
, pcrel
);
1118 if (note1
!= NULL_CODE
)
1119 note
= conscode (note1
, note
);
1120 note
= conctcode (Expr_Node_Gen_Reloc_R (head
), note
);
1126 Expr_Node_Gen_Reloc_R (Expr_Node
* head
)
1134 case Expr_Node_Constant
:
1135 note
= conscode (note_reloc2 (gencode (0), con
, BFD_ARELOC_BFIN_CONST
, head
->value
.i_value
, 0), NULL_CODE
);
1137 case Expr_Node_Reloc
:
1138 note
= conscode (note_reloc (gencode (0), head
, BFD_ARELOC_BFIN_PUSH
, 0), NULL_CODE
);
1140 case Expr_Node_Binop
:
1141 note1
= conctcode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), Expr_Node_Gen_Reloc_R (head
->Right_Child
));
1142 switch (head
->value
.op_value
)
1144 case Expr_Op_Type_Add
:
1145 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_ADD
, 0), NULL_CODE
));
1147 case Expr_Op_Type_Sub
:
1148 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_SUB
, 0), NULL_CODE
));
1150 case Expr_Op_Type_Mult
:
1151 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MULT
, 0), NULL_CODE
));
1153 case Expr_Op_Type_Div
:
1154 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_DIV
, 0), NULL_CODE
));
1156 case Expr_Op_Type_Mod
:
1157 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MOD
, 0), NULL_CODE
));
1159 case Expr_Op_Type_Lshift
:
1160 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LSHIFT
, 0), NULL_CODE
));
1162 case Expr_Op_Type_Rshift
:
1163 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_RSHIFT
, 0), NULL_CODE
));
1165 case Expr_Op_Type_BAND
:
1166 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_AND
, 0), NULL_CODE
));
1168 case Expr_Op_Type_BOR
:
1169 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_OR
, 0), NULL_CODE
));
1171 case Expr_Op_Type_BXOR
:
1172 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_XOR
, 0), NULL_CODE
));
1174 case Expr_Op_Type_LAND
:
1175 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LAND
, 0), NULL_CODE
));
1177 case Expr_Op_Type_LOR
:
1178 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LOR
, 0), NULL_CODE
));
1181 fprintf (stderr
, "%s:%d:Unkonwn operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1186 case Expr_Node_Unop
:
1187 note1
= conscode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), NULL_CODE
);
1188 switch (head
->value
.op_value
)
1190 case Expr_Op_Type_NEG
:
1191 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_NEG
, 0), NULL_CODE
));
1193 case Expr_Op_Type_COMP
:
1194 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_COMP
, 0), NULL_CODE
));
1197 fprintf (stderr
, "%s:%d:Unkonwn operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1201 fprintf (stderr
, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__
, __LINE__
);
1207 /* Blackfin opcode generation. */
1209 /* These functions are called by the generated parser
1210 (from bfin-parse.y), the register type classification
1211 happens in bfin-lex.l. */
1213 #include "bfin-aux.h"
1214 #include "opcode/bfin.h"
1216 #define INIT(t) t c_code = init_##t
1217 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1218 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1220 #define HI(x) ((x >> 16) & 0xffff)
1221 #define LO(x) ((x ) & 0xffff)
1223 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1225 #define GEN_OPCODE32() \
1226 conscode (gencode (HI (c_code.opcode)), \
1227 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1229 #define GEN_OPCODE16() \
1230 conscode (gencode (c_code.opcode), NULL_CODE)
1233 /* 32 BIT INSTRUCTIONS. */
1236 /* DSP32 instruction generation. */
1239 bfin_gen_dsp32mac (int op1
, int MM
, int mmod
, int w1
, int P
,
1240 int h01
, int h11
, int h00
, int h10
, int op0
,
1241 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1257 /* If we have full reg assignments, mask out LSB to encode
1258 single or simultaneous even/odd register moves. */
1268 return GEN_OPCODE32 ();
1272 bfin_gen_dsp32mult (int op1
, int MM
, int mmod
, int w1
, int P
,
1273 int h01
, int h11
, int h00
, int h10
, int op0
,
1274 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1299 return GEN_OPCODE32 ();
1303 bfin_gen_dsp32alu (int HL
, int aopcde
, int aop
, int s
, int x
,
1304 REG_T dst0
, REG_T dst1
, REG_T src0
, REG_T src1
)
1318 return GEN_OPCODE32 ();
1322 bfin_gen_dsp32shift (int sopcde
, REG_T dst0
, REG_T src0
,
1323 REG_T src1
, int sop
, int HLs
)
1335 return GEN_OPCODE32 ();
1339 bfin_gen_dsp32shiftimm (int sopcde
, REG_T dst0
, int immag
,
1340 REG_T src1
, int sop
, int HLs
)
1342 INIT (DSP32ShiftImm
);
1352 return GEN_OPCODE32 ();
1358 bfin_gen_loopsetup (Expr_Node
* psoffset
, REG_T c
, int rop
,
1359 Expr_Node
* peoffset
, REG_T reg
)
1361 int soffset
, eoffset
;
1364 soffset
= (EXPR_VALUE (psoffset
) >> 1);
1366 eoffset
= (EXPR_VALUE (peoffset
) >> 1);
1373 conscode (gencode (HI (c_code
.opcode
)),
1374 conctcode (Expr_Node_Gen_Reloc (psoffset
, BFD_RELOC_BFIN_5_PCREL
),
1375 conctcode (gencode (LO (c_code
.opcode
)), Expr_Node_Gen_Reloc (peoffset
, BFD_RELOC_BFIN_11_PCREL
))));
1382 bfin_gen_calla (Expr_Node
* addr
, int S
)
1390 case 0 : reloc
= BFD_RELOC_BFIN_24_PCREL_JUMP_L
; break;
1391 case 1 : reloc
= BFD_RELOC_24_PCREL
; break;
1392 case 2 : reloc
= BFD_RELOC_BFIN_PLTPC
; break;
1398 val
= EXPR_VALUE (addr
) >> 1;
1399 high_val
= val
>> 16;
1401 return conscode (gencode (HI (c_code
.opcode
) | (high_val
& 0xff)),
1402 Expr_Node_Gen_Reloc (addr
, reloc
));
1406 bfin_gen_linkage (int R
, int framesize
)
1413 return GEN_OPCODE32 ();
1417 /* Load and Store. */
1420 bfin_gen_ldimmhalf (REG_T reg
, int H
, int S
, int Z
, Expr_Node
* phword
, int reloc
)
1423 unsigned val
= EXPR_VALUE (phword
);
1431 grp
= (GROUP (reg
));
1435 return conscode (gencode (HI (c_code
.opcode
)), Expr_Node_Gen_Reloc (phword
, BFD_RELOC_BFIN_16_IMM
));
1437 else if (reloc
== 1)
1439 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
));
1446 return GEN_OPCODE32 ();
1450 bfin_gen_ldstidxi (REG_T ptr
, REG_T reg
, int W
, int sz
, int Z
, Expr_Node
* poffset
)
1454 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1456 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1467 if (poffset
->type
!= Expr_Node_Constant
)
1469 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1470 /* distinguish between R0 = [P5 + symbol@GOT] and
1471 P5 = [P5 + _current_shared_library_p5_offset_]
1473 if (poffset
->type
== Expr_Node_Reloc
1474 && !strcmp (poffset
->value
.s_value
,
1475 "_current_shared_library_p5_offset_"))
1477 return conscode (gencode (HI (c_code
.opcode
)),
1478 Expr_Node_Gen_Reloc(poffset
, BFD_RELOC_16
));
1480 else if (poffset
->type
!= Expr_Node_GOT_Reloc
)
1483 return conscode (gencode (HI (c_code
.opcode
)),
1484 Expr_Node_Gen_Reloc(poffset
->Left_Child
,
1485 poffset
->value
.i_value
));
1491 { // load/store access size
1493 value
= EXPR_VALUE (poffset
) >> 2;
1496 value
= EXPR_VALUE (poffset
) >> 1;
1499 value
= EXPR_VALUE (poffset
);
1505 offset
= (value
& 0xffff);
1507 return GEN_OPCODE32 ();
1513 bfin_gen_ldst (REG_T ptr
, REG_T reg
, int aop
, int sz
, int Z
, int W
)
1517 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1519 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1530 return GEN_OPCODE16 ();
1534 bfin_gen_ldstii (REG_T ptr
, REG_T reg
, Expr_Node
* poffset
, int W
, int op
)
1541 if (!IS_PREG (*ptr
))
1543 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1551 value
= EXPR_VALUE (poffset
) >> 1;
1555 value
= EXPR_VALUE (poffset
) >> 2;
1567 return GEN_OPCODE16 ();
1571 bfin_gen_ldstiifp (REG_T sreg
, Expr_Node
* poffset
, int W
)
1573 /* Set bit 4 if it's a Preg. */
1574 int reg
= (sreg
->regno
& CODE_MASK
) | (IS_PREG (*sreg
) ? 0x8 : 0x0);
1575 int offset
= ((~(EXPR_VALUE (poffset
) >> 2)) & 0x1f) + 1;
1581 return GEN_OPCODE16 ();
1585 bfin_gen_ldstpmod (REG_T ptr
, REG_T reg
, int aop
, int W
, REG_T idx
)
1595 return GEN_OPCODE16 ();
1599 bfin_gen_dspldst (REG_T i
, REG_T reg
, int aop
, int W
, int m
)
1609 return GEN_OPCODE16 ();
1613 bfin_gen_logi2op (int opc
, int src
, int dst
)
1621 return GEN_OPCODE16 ();
1625 bfin_gen_brcc (int T
, int B
, Expr_Node
* poffset
)
1632 offset
= ((EXPR_VALUE (poffset
) >> 1));
1634 return conscode (gencode (c_code
.opcode
), Expr_Node_Gen_Reloc (poffset
, BFD_RELOC_BFIN_10_PCREL
));
1638 bfin_gen_ujump (Expr_Node
* poffset
)
1643 offset
= ((EXPR_VALUE (poffset
) >> 1));
1646 return conscode (gencode (c_code
.opcode
),
1647 Expr_Node_Gen_Reloc (
1648 poffset
, BFD_RELOC_BFIN_12_PCREL_JUMP_S
));
1652 bfin_gen_alu2op (REG_T dst
, REG_T src
, int opc
)
1660 return GEN_OPCODE16 ();
1664 bfin_gen_compi2opd (REG_T dst
, int src
, int op
)
1672 return GEN_OPCODE16 ();
1676 bfin_gen_compi2opp (REG_T dst
, int src
, int op
)
1684 return GEN_OPCODE16 ();
1688 bfin_gen_dagmodik (REG_T i
, int op
)
1695 return GEN_OPCODE16 ();
1699 bfin_gen_dagmodim (REG_T i
, REG_T m
, int op
, int br
)
1708 return GEN_OPCODE16 ();
1712 bfin_gen_ptr2op (REG_T dst
, REG_T src
, int opc
)
1720 return GEN_OPCODE16 ();
1724 bfin_gen_comp3op (REG_T src0
, REG_T src1
, REG_T dst
, int opc
)
1733 return GEN_OPCODE16 ();
1737 bfin_gen_ccflag (REG_T x
, int y
, int opc
, int I
, int G
)
1747 return GEN_OPCODE16 ();
1751 bfin_gen_ccmv (REG_T src
, REG_T dst
, int T
)
1764 return GEN_OPCODE16 ();
1768 bfin_gen_cc2stat (int cbit
, int op
, int D
)
1776 return GEN_OPCODE16 ();
1780 bfin_gen_regmv (REG_T src
, REG_T dst
)
1793 return GEN_OPCODE16 ();
1797 bfin_gen_cc2dreg (int op
, REG_T reg
)
1804 return GEN_OPCODE16 ();
1808 bfin_gen_progctrl (int prgfunc
, int poprnd
)
1815 return GEN_OPCODE16 ();
1819 bfin_gen_cactrl (REG_T reg
, int a
, int op
)
1827 return GEN_OPCODE16 ();
1831 bfin_gen_pushpopmultiple (int dr
, int pr
, int d
, int p
, int W
)
1833 INIT (PushPopMultiple
);
1841 return GEN_OPCODE16 ();
1845 bfin_gen_pushpopreg (REG_T reg
, int W
)
1851 grp
= (GROUP (reg
));
1855 return GEN_OPCODE16 ();
1858 /* Pseudo Debugging Support. */
1861 bfin_gen_pseudodbg (int fn
, int reg
, int grp
)
1869 return GEN_OPCODE16 ();
1873 bfin_gen_pseudodbg_assert (int dbgop
, REG_T regtest
, int expected
)
1875 INIT (PseudoDbg_Assert
);
1881 return GEN_OPCODE32 ();
1884 /* Multiple instruction generation. */
1887 bfin_gen_multi_instr (INSTR_T dsp32
, INSTR_T dsp16_grp1
, INSTR_T dsp16_grp2
)
1891 /* If it's a 0, convert into MNOP. */
1895 SET_MULTI_INSTRUCTION_BIT (dsp32
);
1899 dsp32
= gencode (0xc803);
1900 walk
= gencode (0x1800);
1906 dsp16_grp1
= gencode (0x0000);
1911 dsp16_grp2
= gencode (0x0000);
1914 walk
->next
= dsp16_grp1
;
1915 dsp16_grp1
->next
= dsp16_grp2
;
1916 dsp16_grp2
->next
= NULL_CODE
;
1922 bfin_gen_loop (Expr_Node
*expr
, REG_T reg
, int rop
, REG_T preg
)
1924 const char *loopsym
;
1925 char *lbeginsym
, *lendsym
;
1926 Expr_Node_Value lbeginval
, lendval
;
1927 Expr_Node
*lbegin
, *lend
;
1929 loopsym
= expr
->value
.s_value
;
1930 lbeginsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__BEGIN") + 1);
1931 lendsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__END") + 1);
1936 strcat (lbeginsym
, loopsym
);
1937 strcat (lbeginsym
, "__BEGIN");
1939 strcat (lendsym
, loopsym
);
1940 strcat (lendsym
, "__END");
1942 lbeginval
.s_value
= lbeginsym
;
1943 lendval
.s_value
= lendsym
;
1945 lbegin
= Expr_Node_Create (Expr_Node_Reloc
, lbeginval
, NULL
, NULL
);
1946 lend
= Expr_Node_Create (Expr_Node_Reloc
, lendval
, NULL
, NULL
);
1947 return bfin_gen_loopsetup(lbegin
, reg
, rop
, lend
, preg
);
1951 bfin_eol_in_insn (char *line
)
1953 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1960 /* A semi-colon followed by a newline is always the end of a line. */
1961 if (line
[-1] == ';')
1964 if (line
[-1] == '|')
1967 /* If the || is on the next line, there might be leading whitespace. */
1969 while (*temp
== ' ' || *temp
== '\t') temp
++;
1978 bfin_start_label (char *ptr
)
1981 while (!ISSPACE (*ptr
) && !is_end_of_line
[(unsigned char) *ptr
])
1985 if (*ptr
== '(' || *ptr
== '[')
1992 bfin_force_relocation (struct fix
*fixp
)
1994 if (fixp
->fx_r_type
==BFD_RELOC_BFIN_16_LOW
1995 || fixp
->fx_r_type
== BFD_RELOC_BFIN_16_HIGH
)
1998 return generic_force_reloc (fixp
);