1 /* tc-bfin.c -- Assembler for the ADI Blackfin.
2 Copyright 2005, 2006, 2007
3 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
23 #include "struc-symbol.h"
24 #include "bfin-defs.h"
26 #include "safe-ctype.h"
28 #include "dwarf2dbg.h"
31 #include "elf/common.h"
34 extern int yyparse (void);
35 struct yy_buffer_state
;
36 typedef struct yy_buffer_state
*YY_BUFFER_STATE
;
37 extern YY_BUFFER_STATE
yy_scan_string (const char *yy_str
);
38 extern void yy_delete_buffer (YY_BUFFER_STATE b
);
39 static parse_state
parse (char *line
);
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
54 # define DEFAULT_FDPIC EF_BFIN_FDPIC
56 # define DEFAULT_FDPIC 0
59 static flagword bfin_flags
= DEFAULT_FLAGS
| DEFAULT_FDPIC
;
60 static const char *bfin_pic_flag
= DEFAULT_FDPIC
? "-mfdpic" : (const char *)0;
69 static const struct bfin_reg_entry bfin_reg_info
[] = {
191 {"sftreset", REG_sftreset
},
192 {"omode", REG_omode
},
193 {"excause", REG_excause
},
194 {"emucause", REG_emucause
},
195 {"idle_req", REG_idle_req
},
196 {"hwerrcause", REG_hwerrcause
},
200 {"ASTAT", REG_ASTAT
},
206 {"CYCLES", REG_CYCLES
},
207 {"CYCLES2", REG_CYCLES2
},
209 {"SEQSTAT", REG_SEQSTAT
},
210 {"SYSCFG", REG_SYSCFG
},
215 {"EMUDAT", REG_EMUDAT
},
219 /* Blackfin specific function to handle FD-PIC pointer initializations. */
222 bfin_pic_ptr (int nbytes
)
230 #ifdef md_flush_pending_output
231 md_flush_pending_output ();
234 if (is_it_end_of_statement ())
236 demand_empty_rest_of_line ();
241 md_cons_align (nbytes
);
246 bfd_reloc_code_real_type reloc_type
= BFD_RELOC_BFIN_FUNCDESC
;
248 if (strncasecmp (input_line_pointer
, "funcdesc(", 9) == 0)
250 input_line_pointer
+= 9;
252 if (*input_line_pointer
== ')')
253 input_line_pointer
++;
255 as_bad (_("missing ')'"));
258 error ("missing funcdesc in picptr");
262 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &exp
, 0,
265 while (*input_line_pointer
++ == ',');
267 input_line_pointer
--; /* Put terminator back into stream. */
268 demand_empty_rest_of_line ();
272 bfin_s_bss (int ignore ATTRIBUTE_UNUSED
)
276 temp
= get_absolute_expression ();
277 subseg_set (bss_section
, (subsegT
) temp
);
278 demand_empty_rest_of_line ();
281 const pseudo_typeS md_pseudo_table
[] = {
282 {"align", s_align_bytes
, 0},
285 {"picptr", bfin_pic_ptr
, 4},
286 {"code", obj_elf_section
, 0},
291 {"pdata", s_ignore
, 0},
292 {"var", s_ignore
, 0},
293 {"bss", bfin_s_bss
, 0},
297 /* Characters that are used to denote comments and line separators. */
298 const char comment_chars
[] = "";
299 const char line_comment_chars
[] = "#";
300 const char line_separator_chars
[] = ";";
302 /* Characters that can be used to separate the mantissa from the
303 exponent in floating point numbers. */
304 const char EXP_CHARS
[] = "eE";
306 /* Characters that mean this number is a floating point constant.
307 As in 0f12.456 or 0d1.2345e12. */
308 const char FLT_CHARS
[] = "fFdDxX";
310 /* Define bfin-specific command-line options (there are none). */
311 const char *md_shortopts
= "";
313 #define OPTION_FDPIC (OPTION_MD_BASE)
314 #define OPTION_NOPIC (OPTION_MD_BASE + 1)
316 struct option md_longopts
[] =
318 { "mfdpic", no_argument
, NULL
, OPTION_FDPIC
},
319 { "mnopic", no_argument
, NULL
, OPTION_NOPIC
},
320 { "mno-fdpic", no_argument
, NULL
, OPTION_NOPIC
},
321 { NULL
, no_argument
, NULL
, 0 },
324 size_t md_longopts_size
= sizeof (md_longopts
);
328 md_parse_option (int c ATTRIBUTE_UNUSED
, char *arg ATTRIBUTE_UNUSED
)
336 bfin_flags
|= EF_BFIN_FDPIC
;
337 bfin_pic_flag
= "-mfdpic";
341 bfin_flags
&= ~(EF_BFIN_FDPIC
);
350 md_show_usage (FILE * stream ATTRIBUTE_UNUSED
)
352 fprintf (stream
, _(" BFIN specific command line options:\n"));
355 /* Perform machine-specific initializations. */
359 /* Set the ELF flags if desired. */
361 bfd_set_private_flags (stdoutput
, bfin_flags
);
363 /* Set the default machine type. */
364 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_bfin
, 0))
365 as_warn (_("Could not set architecture and machine."));
367 /* Ensure that lines can begin with '(', for multiple
368 register stack pops. */
369 lex_type
['('] = LEX_BEGIN_NAME
;
372 record_alignment (text_section
, 2);
373 record_alignment (data_section
, 2);
374 record_alignment (bss_section
, 2);
378 obstack_init (&mempool
);
381 extern int debug_codeselection
;
382 debug_codeselection
= 1;
388 /* Perform the main parsing, and assembly of the input here. Also,
389 call the required routines for alignment and fixups here.
390 This is called for every line that contains real assembly code. */
393 md_assemble (char *line
)
396 extern char *current_inputline
;
398 struct bfin_insn
*tmp_insn
;
400 static size_t buffer_len
= 0;
404 if (len
+ 2 > buffer_len
)
407 free (current_inputline
);
408 buffer_len
= len
+ 40;
409 current_inputline
= xmalloc (buffer_len
);
411 memcpy (current_inputline
, line
, len
);
412 current_inputline
[len
] = ';';
413 current_inputline
[len
+ 1] = '\0';
415 state
= parse (current_inputline
);
416 if (state
== NO_INSN_GENERATED
)
419 for (insn_size
= 0, tmp_insn
= insn
; tmp_insn
; tmp_insn
= tmp_insn
->next
)
420 if (!tmp_insn
->reloc
|| !tmp_insn
->exp
->symbol
)
424 toP
= frag_more (insn_size
);
426 last_insn_size
= insn_size
;
433 if (insn
->reloc
&& insn
->exp
->symbol
)
435 char *prev_toP
= toP
- 2;
438 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
439 case BFD_RELOC_24_PCREL
:
440 case BFD_RELOC_BFIN_16_LOW
:
441 case BFD_RELOC_BFIN_16_HIGH
:
448 /* Following if condition checks for the arithmetic relocations.
449 If the case then it doesn't required to generate the code.
450 It has been assumed that, their ID will be contiguous. */
451 if ((BFD_ARELOC_BFIN_PUSH
<= insn
->reloc
452 && BFD_ARELOC_BFIN_COMP
>= insn
->reloc
)
453 || insn
->reloc
== BFD_RELOC_BFIN_16_IMM
)
457 if (insn
->reloc
== BFD_ARELOC_BFIN_CONST
458 || insn
->reloc
== BFD_ARELOC_BFIN_PUSH
)
462 (prev_toP
- frag_now
->fr_literal
),
463 size
, insn
->exp
->symbol
, insn
->exp
->value
,
464 insn
->pcrel
, insn
->reloc
);
468 md_number_to_chars (toP
, insn
->value
, 2);
474 printf (" %02x%02x", ((unsigned char *) &insn
->value
)[0],
475 ((unsigned char *) &insn
->value
)[1]);
481 dwarf2_emit_insn (insn_size
);
485 /* Parse one line of instructions, and generate opcode for it.
486 To parse the line, YACC and LEX are used, because the instruction set
487 syntax doesn't confirm to the AT&T assembly syntax.
488 To call a YACC & LEX generated parser, we must provide the input via
489 a FILE stream, otherwise stdin is used by default. Below the input
490 to the function will be put into a temporary file, then the generated
491 parser uses the temporary file for parsing. */
497 YY_BUFFER_STATE buffstate
;
499 buffstate
= yy_scan_string (line
);
501 /* our lex requires setting the start state to keyword
502 every line as the first word may be a keyword.
503 Fixes a bug where we could not have keywords as labels. */
506 /* Call yyparse here. */
508 if (state
== SEMANTIC_ERROR
)
510 as_bad (_("Parse failed."));
514 yy_delete_buffer (buffstate
);
518 /* We need to handle various expressions properly.
519 Such as, [SP--] = 34, concerned by md_assemble(). */
522 md_operand (expressionS
* expressionP
)
524 if (*input_line_pointer
== '[')
526 as_tsktsk ("We found a '['!");
527 input_line_pointer
++;
528 expression (expressionP
);
532 /* Handle undefined symbols. */
534 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
536 return (symbolS
*) 0;
540 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
541 segT segment ATTRIBUTE_UNUSED
)
546 /* Convert from target byte order to host byte order. */
549 md_chars_to_number (char *val
, int n
)
553 for (retval
= 0; n
--;)
562 md_apply_fix (fixS
*fixP
, valueT
*valueP
, segT seg ATTRIBUTE_UNUSED
)
564 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
566 long value
= *valueP
;
569 switch (fixP
->fx_r_type
)
571 case BFD_RELOC_BFIN_GOT
:
572 case BFD_RELOC_BFIN_GOT17M4
:
573 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
574 fixP
->fx_no_overflow
= 1;
575 newval
= md_chars_to_number (where
, 2);
576 newval
|= 0x0 & 0x7f;
577 md_number_to_chars (where
, newval
, 2);
580 case BFD_RELOC_BFIN_10_PCREL
:
583 if (value
< -1024 || value
> 1022)
584 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
585 _("pcrel too far BFD_RELOC_BFIN_10"));
587 /* 11 bit offset even numbered, so we remove right bit. */
589 newval
= md_chars_to_number (where
, 2);
590 newval
|= value
& 0x03ff;
591 md_number_to_chars (where
, newval
, 2);
594 case BFD_RELOC_BFIN_12_PCREL_JUMP
:
595 case BFD_RELOC_BFIN_12_PCREL_JUMP_S
:
596 case BFD_RELOC_12_PCREL
:
600 if (value
< -4096 || value
> 4094)
601 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_12"));
602 /* 13 bit offset even numbered, so we remove right bit. */
604 newval
= md_chars_to_number (where
, 2);
605 newval
|= value
& 0xfff;
606 md_number_to_chars (where
, newval
, 2);
609 case BFD_RELOC_BFIN_16_LOW
:
610 case BFD_RELOC_BFIN_16_HIGH
:
611 fixP
->fx_done
= FALSE
;
614 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
615 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
616 case BFD_RELOC_24_PCREL
:
620 if (value
< -16777216 || value
> 16777214)
621 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_24"));
623 /* 25 bit offset even numbered, so we remove right bit. */
627 md_number_to_chars (where
- 2, value
>> 16, 1);
628 md_number_to_chars (where
, value
, 1);
629 md_number_to_chars (where
+ 1, value
>> 8, 1);
632 case BFD_RELOC_BFIN_5_PCREL
: /* LSETUP (a, b) : "a" */
635 if (value
< 4 || value
> 30)
636 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_5"));
638 newval
= md_chars_to_number (where
, 1);
639 newval
= (newval
& 0xf0) | (value
& 0xf);
640 md_number_to_chars (where
, newval
, 1);
643 case BFD_RELOC_BFIN_11_PCREL
: /* LSETUP (a, b) : "b" */
647 if (value
< 4 || value
> 2046)
648 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("pcrel too far BFD_RELOC_BFIN_11_PCREL"));
649 /* 11 bit unsigned even, so we remove right bit. */
651 newval
= md_chars_to_number (where
, 2);
652 newval
|= value
& 0x03ff;
653 md_number_to_chars (where
, newval
, 2);
657 if (value
< -0x80 || value
>= 0x7f)
658 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("rel too far BFD_RELOC_8"));
659 md_number_to_chars (where
, value
, 1);
662 case BFD_RELOC_BFIN_16_IMM
:
664 if (value
< -0x8000 || value
>= 0x7fff)
665 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("rel too far BFD_RELOC_16"));
666 md_number_to_chars (where
, value
, 2);
670 md_number_to_chars (where
, value
, 4);
673 case BFD_RELOC_BFIN_PLTPC
:
674 md_number_to_chars (where
, value
, 2);
677 case BFD_RELOC_BFIN_FUNCDESC
:
678 case BFD_RELOC_VTABLE_INHERIT
:
679 case BFD_RELOC_VTABLE_ENTRY
:
680 fixP
->fx_done
= FALSE
;
684 if ((BFD_ARELOC_BFIN_PUSH
> fixP
->fx_r_type
) || (BFD_ARELOC_BFIN_COMP
< fixP
->fx_r_type
))
686 fprintf (stderr
, "Relocation %d not handled in gas." " Contact support.\n", fixP
->fx_r_type
);
692 fixP
->fx_done
= TRUE
;
696 /* Round up a section size to the appropriate boundary. */
698 md_section_align (segment
, size
)
702 int boundary
= bfd_get_section_alignment (stdoutput
, segment
);
703 return ((size
+ (1 << boundary
) - 1) & (-1 << boundary
));
708 md_atof (int type
, char * litP
, int * sizeP
)
710 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
714 /* If while processing a fixup, a reloc really needs to be created
715 then it is done here. */
718 tc_gen_reloc (seg
, fixp
)
719 asection
*seg ATTRIBUTE_UNUSED
;
724 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
725 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
726 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
727 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
729 reloc
->addend
= fixp
->fx_offset
;
730 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
732 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
734 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
735 /* xgettext:c-format. */
736 _("reloc %d not supported by object file format"),
737 (int) fixp
->fx_r_type
);
747 /* The location from which a PC relative jump should be calculated,
748 given a PC relative reloc. */
751 md_pcrel_from_section (fixP
, sec
)
755 if (fixP
->fx_addsy
!= (symbolS
*) NULL
756 && (!S_IS_DEFINED (fixP
->fx_addsy
)
757 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
759 /* The symbol is undefined (or is defined but not in this section).
760 Let the linker figure it out. */
763 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
766 /* Return true if the fix can be handled by GAS, false if it must
767 be passed through to the linker. */
770 bfin_fix_adjustable (fixS
*fixP
)
772 switch (fixP
->fx_r_type
)
774 /* Adjust_reloc_syms doesn't know about the GOT. */
775 case BFD_RELOC_BFIN_GOT
:
776 case BFD_RELOC_BFIN_GOT17M4
:
777 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
778 case BFD_RELOC_BFIN_PLTPC
:
779 /* We need the symbol name for the VTABLE entries. */
780 case BFD_RELOC_VTABLE_INHERIT
:
781 case BFD_RELOC_VTABLE_ENTRY
:
790 /* Handle the LOOP_BEGIN and LOOP_END statements.
791 Parse the Loop_Begin/Loop_End and create a label. */
793 bfin_start_line_hook ()
795 bfd_boolean maybe_begin
= FALSE
;
796 bfd_boolean maybe_end
= FALSE
;
798 char *c1
, *label_name
;
800 char *c
= input_line_pointer
;
810 /* Look for Loop_Begin or Loop_End statements. */
812 if (*c
!= 'L' && *c
!= 'l')
816 if (*c
!= 'O' && *c
!= 'o')
820 if (*c
!= 'O' && *c
!= 'o')
824 if (*c
!= 'P' && *c
!= 'p')
832 if (*c
== 'E' || *c
== 'e')
834 else if (*c
== 'B' || *c
== 'b')
842 if (*c
!= 'N' && *c
!= 'n')
846 if (*c
!= 'D' && *c
!= 'd')
853 if (*c
!= 'E' && *c
!= 'e')
857 if (*c
!= 'G' && *c
!= 'g')
861 if (*c
!= 'I' && *c
!= 'i')
865 if (*c
!= 'N' && *c
!= 'n')
870 while (ISSPACE (*c
)) c
++;
872 while (ISALPHA (*c
) || ISDIGIT (*c
) || *c
== '_') c
++;
874 if (input_line_pointer
[-1] == '\n')
875 bump_line_counters ();
878 bump_line_counters ();
880 input_line_pointer
= c
;
883 label_name
= (char *) xmalloc ((c
- c1
) + strlen ("__END") + 5);
885 strcat (label_name
, "L$L$");
886 strncat (label_name
, c1
, c
-c1
);
887 strcat (label_name
, "__END");
889 else /* maybe_begin. */
891 label_name
= (char *) xmalloc ((c
- c1
) + strlen ("__BEGIN") + 5);
893 strcat (label_name
, "L$L$");
894 strncat (label_name
, c1
, c
-c1
);
895 strcat (label_name
, "__BEGIN");
898 line_label
= colon (label_name
);
900 /* Loop_End follows the last instruction in the loop.
901 Adjust label address. */
903 ((struct local_symbol
*) line_label
)->lsy_value
-= last_insn_size
;
906 /* Special extra functions that help bfin-parse.y perform its job. */
910 struct obstack mempool
;
913 conscode (INSTR_T head
, INSTR_T tail
)
922 conctcode (INSTR_T head
, INSTR_T tail
)
924 INSTR_T temp
= (head
);
935 note_reloc (INSTR_T code
, Expr_Node
* symbol
, int reloc
, int pcrel
)
937 /* Assert that the symbol is not an operator. */
938 assert (symbol
->type
== Expr_Node_Reloc
);
940 return note_reloc1 (code
, symbol
->value
.s_value
, reloc
, pcrel
);
945 note_reloc1 (INSTR_T code
, const char *symbol
, int reloc
, int pcrel
)
948 code
->exp
= mkexpr (0, symbol_find_or_make (symbol
));
954 note_reloc2 (INSTR_T code
, const char *symbol
, int reloc
, int value
, int pcrel
)
957 code
->exp
= mkexpr (value
, symbol_find_or_make (symbol
));
963 gencode (unsigned long x
)
965 INSTR_T cell
= (INSTR_T
) obstack_alloc (&mempool
, sizeof (struct bfin_insn
));
966 memset (cell
, 0, sizeof (struct bfin_insn
));
978 return (void *) obstack_alloc (&mempool
, n
);
982 Expr_Node_Create (Expr_Node_Type type
,
983 Expr_Node_Value value
,
984 Expr_Node
*Left_Child
,
985 Expr_Node
*Right_Child
)
989 Expr_Node
*node
= (Expr_Node
*) allocate (sizeof (Expr_Node
));
992 node
->Left_Child
= Left_Child
;
993 node
->Right_Child
= Right_Child
;
997 static const char *con
= ".__constant";
998 static const char *op
= ".__operator";
999 static INSTR_T
Expr_Node_Gen_Reloc_R (Expr_Node
* head
);
1000 INSTR_T
Expr_Node_Gen_Reloc (Expr_Node
*head
, int parent_reloc
);
1003 Expr_Node_Gen_Reloc (Expr_Node
* head
, int parent_reloc
)
1005 /* Top level reloction expression generator VDSP style.
1006 If the relocation is just by itself, generate one item
1007 else generate this convoluted expression. */
1009 INSTR_T note
= NULL_CODE
;
1010 INSTR_T note1
= NULL_CODE
;
1011 int pcrel
= 1; /* Is the parent reloc pcrelative?
1012 This calculation here and HOWTO should match. */
1016 /* If it's 32 bit quantity then 16bit code needs to be added. */
1019 if (head
->type
== Expr_Node_Constant
)
1021 /* If note1 is not null code, we have to generate a right
1022 aligned value for the constant. Otherwise the reloc is
1023 a part of the basic command and the yacc file
1025 value
= head
->value
.i_value
;
1027 switch (parent_reloc
)
1029 /* Some relocations will need to allocate extra words. */
1030 case BFD_RELOC_BFIN_16_IMM
:
1031 case BFD_RELOC_BFIN_16_LOW
:
1032 case BFD_RELOC_BFIN_16_HIGH
:
1033 note1
= conscode (gencode (value
), NULL_CODE
);
1036 case BFD_RELOC_BFIN_PLTPC
:
1037 note1
= conscode (gencode (value
), NULL_CODE
);
1041 case BFD_RELOC_BFIN_GOT
:
1042 case BFD_RELOC_BFIN_GOT17M4
:
1043 case BFD_RELOC_BFIN_FUNCDESC_GOT17M4
:
1044 note1
= conscode (gencode (value
), NULL_CODE
);
1047 case BFD_RELOC_24_PCREL
:
1048 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
1049 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
1050 /* These offsets are even numbered pcrel. */
1051 note1
= conscode (gencode (value
>> 1), NULL_CODE
);
1057 if (head
->type
== Expr_Node_Constant
)
1059 else if (head
->type
== Expr_Node_Reloc
)
1061 note
= note_reloc1 (gencode (0), head
->value
.s_value
, parent_reloc
, pcrel
);
1062 if (note1
!= NULL_CODE
)
1063 note
= conscode (note1
, note
);
1065 else if (head
->type
== Expr_Node_Binop
1066 && (head
->value
.op_value
== Expr_Op_Type_Add
1067 || head
->value
.op_value
== Expr_Op_Type_Sub
)
1068 && head
->Left_Child
->type
== Expr_Node_Reloc
1069 && head
->Right_Child
->type
== Expr_Node_Constant
)
1071 int val
= head
->Right_Child
->value
.i_value
;
1072 if (head
->value
.op_value
== Expr_Op_Type_Sub
)
1074 note
= conscode (note_reloc2 (gencode (0), head
->Left_Child
->value
.s_value
,
1075 parent_reloc
, val
, 0),
1077 if (note1
!= NULL_CODE
)
1078 note
= conscode (note1
, note
);
1082 /* Call the recursive function. */
1083 note
= note_reloc1 (gencode (0), op
, parent_reloc
, pcrel
);
1084 if (note1
!= NULL_CODE
)
1085 note
= conscode (note1
, note
);
1086 note
= conctcode (Expr_Node_Gen_Reloc_R (head
), note
);
1092 Expr_Node_Gen_Reloc_R (Expr_Node
* head
)
1100 case Expr_Node_Constant
:
1101 note
= conscode (note_reloc2 (gencode (0), con
, BFD_ARELOC_BFIN_CONST
, head
->value
.i_value
, 0), NULL_CODE
);
1103 case Expr_Node_Reloc
:
1104 note
= conscode (note_reloc (gencode (0), head
, BFD_ARELOC_BFIN_PUSH
, 0), NULL_CODE
);
1106 case Expr_Node_Binop
:
1107 note1
= conctcode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), Expr_Node_Gen_Reloc_R (head
->Right_Child
));
1108 switch (head
->value
.op_value
)
1110 case Expr_Op_Type_Add
:
1111 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_ADD
, 0), NULL_CODE
));
1113 case Expr_Op_Type_Sub
:
1114 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_SUB
, 0), NULL_CODE
));
1116 case Expr_Op_Type_Mult
:
1117 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MULT
, 0), NULL_CODE
));
1119 case Expr_Op_Type_Div
:
1120 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_DIV
, 0), NULL_CODE
));
1122 case Expr_Op_Type_Mod
:
1123 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MOD
, 0), NULL_CODE
));
1125 case Expr_Op_Type_Lshift
:
1126 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LSHIFT
, 0), NULL_CODE
));
1128 case Expr_Op_Type_Rshift
:
1129 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_RSHIFT
, 0), NULL_CODE
));
1131 case Expr_Op_Type_BAND
:
1132 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_AND
, 0), NULL_CODE
));
1134 case Expr_Op_Type_BOR
:
1135 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_OR
, 0), NULL_CODE
));
1137 case Expr_Op_Type_BXOR
:
1138 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_XOR
, 0), NULL_CODE
));
1140 case Expr_Op_Type_LAND
:
1141 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LAND
, 0), NULL_CODE
));
1143 case Expr_Op_Type_LOR
:
1144 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LOR
, 0), NULL_CODE
));
1147 fprintf (stderr
, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1152 case Expr_Node_Unop
:
1153 note1
= conscode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), NULL_CODE
);
1154 switch (head
->value
.op_value
)
1156 case Expr_Op_Type_NEG
:
1157 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_NEG
, 0), NULL_CODE
));
1159 case Expr_Op_Type_COMP
:
1160 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_COMP
, 0), NULL_CODE
));
1163 fprintf (stderr
, "%s:%d:Unknown operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1167 fprintf (stderr
, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__
, __LINE__
);
1173 /* Blackfin opcode generation. */
1175 /* These functions are called by the generated parser
1176 (from bfin-parse.y), the register type classification
1177 happens in bfin-lex.l. */
1179 #include "bfin-aux.h"
1180 #include "opcode/bfin.h"
1182 #define INIT(t) t c_code = init_##t
1183 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1184 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1186 #define HI(x) ((x >> 16) & 0xffff)
1187 #define LO(x) ((x ) & 0xffff)
1189 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1191 #define GEN_OPCODE32() \
1192 conscode (gencode (HI (c_code.opcode)), \
1193 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1195 #define GEN_OPCODE16() \
1196 conscode (gencode (c_code.opcode), NULL_CODE)
1199 /* 32 BIT INSTRUCTIONS. */
1202 /* DSP32 instruction generation. */
1205 bfin_gen_dsp32mac (int op1
, int MM
, int mmod
, int w1
, int P
,
1206 int h01
, int h11
, int h00
, int h10
, int op0
,
1207 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1223 /* If we have full reg assignments, mask out LSB to encode
1224 single or simultaneous even/odd register moves. */
1234 return GEN_OPCODE32 ();
1238 bfin_gen_dsp32mult (int op1
, int MM
, int mmod
, int w1
, int P
,
1239 int h01
, int h11
, int h00
, int h10
, int op0
,
1240 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1265 return GEN_OPCODE32 ();
1269 bfin_gen_dsp32alu (int HL
, int aopcde
, int aop
, int s
, int x
,
1270 REG_T dst0
, REG_T dst1
, REG_T src0
, REG_T src1
)
1284 return GEN_OPCODE32 ();
1288 bfin_gen_dsp32shift (int sopcde
, REG_T dst0
, REG_T src0
,
1289 REG_T src1
, int sop
, int HLs
)
1301 return GEN_OPCODE32 ();
1305 bfin_gen_dsp32shiftimm (int sopcde
, REG_T dst0
, int immag
,
1306 REG_T src1
, int sop
, int HLs
)
1308 INIT (DSP32ShiftImm
);
1318 return GEN_OPCODE32 ();
1324 bfin_gen_loopsetup (Expr_Node
* psoffset
, REG_T c
, int rop
,
1325 Expr_Node
* peoffset
, REG_T reg
)
1327 int soffset
, eoffset
;
1330 soffset
= (EXPR_VALUE (psoffset
) >> 1);
1332 eoffset
= (EXPR_VALUE (peoffset
) >> 1);
1339 conscode (gencode (HI (c_code
.opcode
)),
1340 conctcode (Expr_Node_Gen_Reloc (psoffset
, BFD_RELOC_BFIN_5_PCREL
),
1341 conctcode (gencode (LO (c_code
.opcode
)), Expr_Node_Gen_Reloc (peoffset
, BFD_RELOC_BFIN_11_PCREL
))));
1348 bfin_gen_calla (Expr_Node
* addr
, int S
)
1356 case 0 : reloc
= BFD_RELOC_BFIN_24_PCREL_JUMP_L
; break;
1357 case 1 : reloc
= BFD_RELOC_24_PCREL
; break;
1358 case 2 : reloc
= BFD_RELOC_BFIN_PLTPC
; break;
1364 val
= EXPR_VALUE (addr
) >> 1;
1365 high_val
= val
>> 16;
1367 return conscode (gencode (HI (c_code
.opcode
) | (high_val
& 0xff)),
1368 Expr_Node_Gen_Reloc (addr
, reloc
));
1372 bfin_gen_linkage (int R
, int framesize
)
1379 return GEN_OPCODE32 ();
1383 /* Load and Store. */
1386 bfin_gen_ldimmhalf (REG_T reg
, int H
, int S
, int Z
, Expr_Node
* phword
, int reloc
)
1389 unsigned val
= EXPR_VALUE (phword
);
1397 grp
= (GROUP (reg
));
1401 return conscode (gencode (HI (c_code
.opcode
)), Expr_Node_Gen_Reloc (phword
, BFD_RELOC_BFIN_16_IMM
));
1403 else if (reloc
== 1)
1405 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
));
1412 return GEN_OPCODE32 ();
1416 bfin_gen_ldstidxi (REG_T ptr
, REG_T reg
, int W
, int sz
, int Z
, Expr_Node
* poffset
)
1420 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1422 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1433 if (poffset
->type
!= Expr_Node_Constant
)
1435 /* a GOT relocation such as R0 = [P5 + symbol@GOT] */
1436 /* distinguish between R0 = [P5 + symbol@GOT] and
1437 P5 = [P5 + _current_shared_library_p5_offset_]
1439 if (poffset
->type
== Expr_Node_Reloc
1440 && !strcmp (poffset
->value
.s_value
,
1441 "_current_shared_library_p5_offset_"))
1443 return conscode (gencode (HI (c_code
.opcode
)),
1444 Expr_Node_Gen_Reloc(poffset
, BFD_RELOC_16
));
1446 else if (poffset
->type
!= Expr_Node_GOT_Reloc
)
1449 return conscode (gencode (HI (c_code
.opcode
)),
1450 Expr_Node_Gen_Reloc(poffset
->Left_Child
,
1451 poffset
->value
.i_value
));
1457 { // load/store access size
1459 value
= EXPR_VALUE (poffset
) >> 2;
1462 value
= EXPR_VALUE (poffset
) >> 1;
1465 value
= EXPR_VALUE (poffset
);
1471 offset
= (value
& 0xffff);
1473 return GEN_OPCODE32 ();
1479 bfin_gen_ldst (REG_T ptr
, REG_T reg
, int aop
, int sz
, int Z
, int W
)
1483 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1485 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1496 return GEN_OPCODE16 ();
1500 bfin_gen_ldstii (REG_T ptr
, REG_T reg
, Expr_Node
* poffset
, int W
, int op
)
1507 if (!IS_PREG (*ptr
))
1509 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1517 value
= EXPR_VALUE (poffset
) >> 1;
1521 value
= EXPR_VALUE (poffset
) >> 2;
1533 return GEN_OPCODE16 ();
1537 bfin_gen_ldstiifp (REG_T sreg
, Expr_Node
* poffset
, int W
)
1539 /* Set bit 4 if it's a Preg. */
1540 int reg
= (sreg
->regno
& CODE_MASK
) | (IS_PREG (*sreg
) ? 0x8 : 0x0);
1541 int offset
= ((~(EXPR_VALUE (poffset
) >> 2)) & 0x1f) + 1;
1547 return GEN_OPCODE16 ();
1551 bfin_gen_ldstpmod (REG_T ptr
, REG_T reg
, int aop
, int W
, REG_T idx
)
1561 return GEN_OPCODE16 ();
1565 bfin_gen_dspldst (REG_T i
, REG_T reg
, int aop
, int W
, int m
)
1575 return GEN_OPCODE16 ();
1579 bfin_gen_logi2op (int opc
, int src
, int dst
)
1587 return GEN_OPCODE16 ();
1591 bfin_gen_brcc (int T
, int B
, Expr_Node
* poffset
)
1598 offset
= ((EXPR_VALUE (poffset
) >> 1));
1600 return conscode (gencode (c_code
.opcode
), Expr_Node_Gen_Reloc (poffset
, BFD_RELOC_BFIN_10_PCREL
));
1604 bfin_gen_ujump (Expr_Node
* poffset
)
1609 offset
= ((EXPR_VALUE (poffset
) >> 1));
1612 return conscode (gencode (c_code
.opcode
),
1613 Expr_Node_Gen_Reloc (
1614 poffset
, BFD_RELOC_BFIN_12_PCREL_JUMP_S
));
1618 bfin_gen_alu2op (REG_T dst
, REG_T src
, int opc
)
1626 return GEN_OPCODE16 ();
1630 bfin_gen_compi2opd (REG_T dst
, int src
, int op
)
1638 return GEN_OPCODE16 ();
1642 bfin_gen_compi2opp (REG_T dst
, int src
, int op
)
1650 return GEN_OPCODE16 ();
1654 bfin_gen_dagmodik (REG_T i
, int op
)
1661 return GEN_OPCODE16 ();
1665 bfin_gen_dagmodim (REG_T i
, REG_T m
, int op
, int br
)
1674 return GEN_OPCODE16 ();
1678 bfin_gen_ptr2op (REG_T dst
, REG_T src
, int opc
)
1686 return GEN_OPCODE16 ();
1690 bfin_gen_comp3op (REG_T src0
, REG_T src1
, REG_T dst
, int opc
)
1699 return GEN_OPCODE16 ();
1703 bfin_gen_ccflag (REG_T x
, int y
, int opc
, int I
, int G
)
1713 return GEN_OPCODE16 ();
1717 bfin_gen_ccmv (REG_T src
, REG_T dst
, int T
)
1730 return GEN_OPCODE16 ();
1734 bfin_gen_cc2stat (int cbit
, int op
, int D
)
1742 return GEN_OPCODE16 ();
1746 bfin_gen_regmv (REG_T src
, REG_T dst
)
1759 return GEN_OPCODE16 ();
1763 bfin_gen_cc2dreg (int op
, REG_T reg
)
1770 return GEN_OPCODE16 ();
1774 bfin_gen_progctrl (int prgfunc
, int poprnd
)
1781 return GEN_OPCODE16 ();
1785 bfin_gen_cactrl (REG_T reg
, int a
, int op
)
1793 return GEN_OPCODE16 ();
1797 bfin_gen_pushpopmultiple (int dr
, int pr
, int d
, int p
, int W
)
1799 INIT (PushPopMultiple
);
1807 return GEN_OPCODE16 ();
1811 bfin_gen_pushpopreg (REG_T reg
, int W
)
1817 grp
= (GROUP (reg
));
1821 return GEN_OPCODE16 ();
1824 /* Pseudo Debugging Support. */
1827 bfin_gen_pseudodbg (int fn
, int reg
, int grp
)
1835 return GEN_OPCODE16 ();
1839 bfin_gen_pseudodbg_assert (int dbgop
, REG_T regtest
, int expected
)
1841 INIT (PseudoDbg_Assert
);
1847 return GEN_OPCODE32 ();
1850 /* Multiple instruction generation. */
1853 bfin_gen_multi_instr (INSTR_T dsp32
, INSTR_T dsp16_grp1
, INSTR_T dsp16_grp2
)
1857 /* If it's a 0, convert into MNOP. */
1861 SET_MULTI_INSTRUCTION_BIT (dsp32
);
1865 dsp32
= gencode (0xc803);
1866 walk
= gencode (0x1800);
1872 dsp16_grp1
= gencode (0x0000);
1877 dsp16_grp2
= gencode (0x0000);
1880 walk
->next
= dsp16_grp1
;
1881 dsp16_grp1
->next
= dsp16_grp2
;
1882 dsp16_grp2
->next
= NULL_CODE
;
1888 bfin_gen_loop (Expr_Node
*expr
, REG_T reg
, int rop
, REG_T preg
)
1890 const char *loopsym
;
1891 char *lbeginsym
, *lendsym
;
1892 Expr_Node_Value lbeginval
, lendval
;
1893 Expr_Node
*lbegin
, *lend
;
1895 loopsym
= expr
->value
.s_value
;
1896 lbeginsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__BEGIN") + 5);
1897 lendsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__END") + 5);
1902 strcat (lbeginsym
, "L$L$");
1903 strcat (lbeginsym
, loopsym
);
1904 strcat (lbeginsym
, "__BEGIN");
1906 strcat (lendsym
, "L$L$");
1907 strcat (lendsym
, loopsym
);
1908 strcat (lendsym
, "__END");
1910 lbeginval
.s_value
= lbeginsym
;
1911 lendval
.s_value
= lendsym
;
1913 lbegin
= Expr_Node_Create (Expr_Node_Reloc
, lbeginval
, NULL
, NULL
);
1914 lend
= Expr_Node_Create (Expr_Node_Reloc
, lendval
, NULL
, NULL
);
1915 return bfin_gen_loopsetup(lbegin
, reg
, rop
, lend
, preg
);
1919 bfin_eol_in_insn (char *line
)
1921 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1928 /* A semi-colon followed by a newline is always the end of a line. */
1929 if (line
[-1] == ';')
1932 if (line
[-1] == '|')
1935 /* If the || is on the next line, there might be leading whitespace. */
1937 while (*temp
== ' ' || *temp
== '\t') temp
++;
1946 bfin_start_label (char *ptr
)
1949 while (!ISSPACE (*ptr
) && !is_end_of_line
[(unsigned char) *ptr
])
1953 if (*ptr
== '(' || *ptr
== '[')
1960 bfin_force_relocation (struct fix
*fixp
)
1962 if (fixp
->fx_r_type
==BFD_RELOC_BFIN_16_LOW
1963 || fixp
->fx_r_type
== BFD_RELOC_BFIN_16_HIGH
)
1966 return generic_force_reloc (fixp
);