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 extern int yyparse (void);
33 struct yy_buffer_state
;
34 typedef struct yy_buffer_state
*YY_BUFFER_STATE
;
35 extern YY_BUFFER_STATE
yy_scan_string (const char *yy_str
);
36 extern void yy_delete_buffer (YY_BUFFER_STATE b
);
37 static parse_state
parse (char *line
);
38 static void bfin_s_bss
PARAMS ((int));
39 static int md_chars_to_number
PARAMS ((char *, int));
41 /* Global variables. */
42 struct bfin_insn
*insn
;
45 extern struct obstack mempool
;
55 static const struct bfin_reg_entry bfin_reg_info
[] = {
177 {"sftreset", REG_sftreset
},
178 {"omode", REG_omode
},
179 {"excause", REG_excause
},
180 {"emucause", REG_emucause
},
181 {"idle_req", REG_idle_req
},
182 {"hwerrcause", REG_hwerrcause
},
186 {"ASTAT", REG_ASTAT
},
192 {"CYCLES", REG_CYCLES
},
193 {"CYCLES2", REG_CYCLES2
},
195 {"SEQSTAT", REG_SEQSTAT
},
196 {"SYSCFG", REG_SYSCFG
},
201 {"EMUDAT", REG_EMUDAT
},
206 const pseudo_typeS md_pseudo_table
[] = {
207 {"align", s_align_bytes
, 0},
210 {"code", obj_elf_section
, 0},
215 {"pdata", s_ignore
, 0},
216 {"var", s_ignore
, 0},
217 {"bss", bfin_s_bss
, 0},
222 bfin_s_bss (int ignore ATTRIBUTE_UNUSED
)
226 temp
= get_absolute_expression ();
227 subseg_set (bss_section
, (subsegT
) temp
);
228 demand_empty_rest_of_line ();
232 /* Characters that are used to denote comments and line separators. */
233 const char comment_chars
[] = "";
234 const char line_comment_chars
[] = "#";
235 const char line_separator_chars
[] = ";";
237 /* Characters that can be used to separate the mantissa from the
238 exponent in floating point numbers. */
239 const char EXP_CHARS
[] = "eE";
241 /* Characters that mean this number is a floating point constant.
242 As in 0f12.456 or 0d1.2345e12. */
243 const char FLT_CHARS
[] = "fFdDxX";
245 /* Define bfin-specific command-line options (there are none). */
246 const char *md_shortopts
= "";
248 struct option md_longopts
[] = {
249 {NULL
, no_argument
, NULL
, 0}
251 size_t md_longopts_size
= sizeof (md_longopts
);
255 md_parse_option (int c ATTRIBUTE_UNUSED
, char *arg ATTRIBUTE_UNUSED
)
261 md_show_usage (FILE * stream ATTRIBUTE_UNUSED
)
263 fprintf (stream
, _(" BFIN specific command line options:\n"));
266 /* Perform machine-specific initializations. */
270 /* Set the default machine type. */
271 if (!bfd_set_arch_mach (stdoutput
, bfd_arch_bfin
, 0))
272 as_warn ("Could not set architecture and machine.");
274 /* Ensure that lines can begin with '(', for multiple
275 register stack pops. */
276 lex_type
['('] = LEX_BEGIN_NAME
;
279 record_alignment (text_section
, 2);
280 record_alignment (data_section
, 2);
281 record_alignment (bss_section
, 2);
285 obstack_init (&mempool
);
288 extern int debug_codeselection
;
289 debug_codeselection
= 1;
295 /* Perform the main parsing, and assembly of the input here. Also,
296 call the required routines for alignment and fixups here.
297 This is called for every line that contains real assembly code. */
300 md_assemble (char *line
)
303 extern char *current_inputline
;
305 struct bfin_insn
*tmp_insn
;
307 static size_t buffer_len
= 0;
311 if (len
+ 2 > buffer_len
)
314 free (current_inputline
);
315 buffer_len
= len
+ 40;
316 current_inputline
= xmalloc (buffer_len
);
318 memcpy (current_inputline
, line
, len
);
319 current_inputline
[len
] = ';';
320 current_inputline
[len
+ 1] = '\0';
322 state
= parse (current_inputline
);
323 if (state
== NO_INSN_GENERATED
)
326 for (insn_size
= 0, tmp_insn
= insn
; tmp_insn
; tmp_insn
= tmp_insn
->next
)
327 if (!tmp_insn
->reloc
|| !tmp_insn
->exp
->symbol
)
331 toP
= frag_more (insn_size
);
333 last_insn_size
= insn_size
;
340 if (insn
->reloc
&& insn
->exp
->symbol
)
342 char *prev_toP
= toP
- 2;
345 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
346 case BFD_RELOC_24_PCREL
:
347 case BFD_RELOC_BFIN_16_LOW
:
348 case BFD_RELOC_BFIN_16_HIGH
:
355 /* Following if condition checks for the arithmetic relocations.
356 If the case then it doesn't required to generate the code.
357 It has been assumed that, their ID will be contiguous. */
358 if ((BFD_ARELOC_BFIN_PUSH
<= insn
->reloc
359 && BFD_ARELOC_BFIN_COMP
>= insn
->reloc
)
360 || insn
->reloc
== BFD_RELOC_BFIN_16_IMM
)
364 if (insn
->reloc
== BFD_ARELOC_BFIN_CONST
365 || insn
->reloc
== BFD_ARELOC_BFIN_PUSH
)
369 (prev_toP
- frag_now
->fr_literal
),
370 size
, insn
->exp
->symbol
, insn
->exp
->value
,
371 insn
->pcrel
, insn
->reloc
);
375 md_number_to_chars (toP
, insn
->value
, 2);
381 printf (" %02x%02x", ((unsigned char *) &insn
->value
)[0],
382 ((unsigned char *) &insn
->value
)[1]);
388 dwarf2_emit_insn (insn_size
);
392 /* Parse one line of instructions, and generate opcode for it.
393 To parse the line, YACC and LEX are used, because the instruction set
394 syntax doesn't confirm to the AT&T assembly syntax.
395 To call a YACC & LEX generated parser, we must provide the input via
396 a FILE stream, otherwise stdin is used by default. Below the input
397 to the function will be put into a temporary file, then the generated
398 parser uses the temporary file for parsing. */
404 YY_BUFFER_STATE buffstate
;
406 buffstate
= yy_scan_string (line
);
408 /* our lex requires setting the start state to keyword
409 every line as the first word may be a keyword.
410 Fixes a bug where we could not have keywords as labels. */
413 /* Call yyparse here. */
415 if (state
== SEMANTIC_ERROR
)
417 as_bad ("Parse failed.");
421 yy_delete_buffer (buffstate
);
425 /* We need to handle various expressions properly.
426 Such as, [SP--] = 34, concerned by md_assemble(). */
429 md_operand (expressionS
* expressionP
)
431 if (*input_line_pointer
== '[')
433 as_tsktsk ("We found a '['!");
434 input_line_pointer
++;
435 expression (expressionP
);
439 /* Handle undefined symbols. */
441 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
443 return (symbolS
*) 0;
447 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
,
448 segT segment ATTRIBUTE_UNUSED
)
453 /* Convert from target byte order to host byte order. */
456 md_chars_to_number (char *val
, int n
)
460 for (retval
= 0; n
--;)
469 md_apply_fix (fixS
*fixP
, valueT
*valueP
, segT seg ATTRIBUTE_UNUSED
)
471 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
473 long value
= *valueP
;
476 switch (fixP
->fx_r_type
)
478 case BFD_RELOC_BFIN_GOT
:
479 fixP
->fx_no_overflow
= 1;
480 newval
= md_chars_to_number (where
, 2);
481 newval
|= 0x0 & 0x7f;
482 md_number_to_chars (where
, newval
, 2);
485 case BFD_RELOC_BFIN_10_PCREL
:
488 if (value
< -1024 || value
> 1022)
489 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
490 "pcrel too far BFD_RELOC_BFIN_10");
492 /* 11 bit offset even numbered, so we remove right bit. */
494 newval
= md_chars_to_number (where
, 2);
495 newval
|= value
& 0x03ff;
496 md_number_to_chars (where
, newval
, 2);
499 case BFD_RELOC_BFIN_12_PCREL_JUMP
:
500 case BFD_RELOC_BFIN_12_PCREL_JUMP_S
:
501 case BFD_RELOC_12_PCREL
:
505 if (value
< -4096 || value
> 4094)
506 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "pcrel too far BFD_RELOC_BFIN_12");
507 /* 13 bit offset even numbered, so we remove right bit. */
509 newval
= md_chars_to_number (where
, 2);
510 newval
|= value
& 0xfff;
511 md_number_to_chars (where
, newval
, 2);
514 case BFD_RELOC_BFIN_16_LOW
:
515 case BFD_RELOC_BFIN_16_HIGH
:
516 fixP
->fx_done
= FALSE
;
519 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
520 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
521 case BFD_RELOC_24_PCREL
:
525 if (value
< -16777216 || value
> 16777214)
526 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "pcrel too far BFD_RELOC_BFIN_24");
528 /* 25 bit offset even numbered, so we remove right bit. */
532 md_number_to_chars (where
- 2, value
>> 16, 1);
533 md_number_to_chars (where
, value
, 1);
534 md_number_to_chars (where
+ 1, value
>> 8, 1);
537 case BFD_RELOC_BFIN_5_PCREL
: /* LSETUP (a, b) : "a" */
540 if (value
< 4 || value
> 30)
541 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "pcrel too far BFD_RELOC_BFIN_5");
543 newval
= md_chars_to_number (where
, 1);
544 newval
= (newval
& 0xf0) | (value
& 0xf);
545 md_number_to_chars (where
, newval
, 1);
548 case BFD_RELOC_BFIN_11_PCREL
: /* LSETUP (a, b) : "b" */
552 if (value
< 4 || value
> 2046)
553 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "pcrel too far BFD_RELOC_BFIN_11_PCREL");
554 /* 11 bit unsigned even, so we remove right bit. */
556 newval
= md_chars_to_number (where
, 2);
557 newval
|= value
& 0x03ff;
558 md_number_to_chars (where
, newval
, 2);
562 if (value
< -0x80 || value
>= 0x7f)
563 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "rel too far BFD_RELOC_8");
564 md_number_to_chars (where
, value
, 1);
567 case BFD_RELOC_BFIN_16_IMM
:
569 if (value
< -0x8000 || value
>= 0x7fff)
570 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "rel too far BFD_RELOC_8");
571 md_number_to_chars (where
, value
, 2);
575 md_number_to_chars (where
, value
, 4);
578 case BFD_RELOC_BFIN_PLTPC
:
579 md_number_to_chars (where
, value
, 2);
582 case BFD_RELOC_VTABLE_INHERIT
:
583 case BFD_RELOC_VTABLE_ENTRY
:
584 fixP
->fx_done
= FALSE
;
588 if ((BFD_ARELOC_BFIN_PUSH
> fixP
->fx_r_type
) || (BFD_ARELOC_BFIN_COMP
< fixP
->fx_r_type
))
590 fprintf (stderr
, "Relocation %d not handled in gas." " Contact support.\n", fixP
->fx_r_type
);
596 fixP
->fx_done
= TRUE
;
600 /* Round up a section size to the appropriate boundary. */
602 md_section_align (segment
, size
)
606 int boundary
= bfd_get_section_alignment (stdoutput
, segment
);
607 return ((size
+ (1 << boundary
) - 1) & (-1 << boundary
));
611 /* Turn a string in input_line_pointer into a floating point
612 constant of type type, and store the appropriate bytes in
613 *litP. The number of LITTLENUMS emitted is stored in *sizeP.
614 An error message is returned, or NULL on OK. */
616 /* Equal to MAX_PRECISION in atof-ieee.c. */
617 #define MAX_LITTLENUMS 6
620 md_atof (type
, litP
, sizeP
)
626 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
627 LITTLENUM_TYPE
*wordP
;
642 /* FIXME: Some targets allow other format chars for bigger sizes here. */
646 return _("Bad call to md_atof()");
649 t
= atof_ieee (input_line_pointer
, type
, words
);
651 input_line_pointer
= t
;
652 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
654 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
655 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
656 the littleendianness of the processor. */
657 for (wordP
= words
+ prec
- 1; prec
--;)
659 md_number_to_chars (litP
, (valueT
) (*wordP
--), sizeof (LITTLENUM_TYPE
));
660 litP
+= sizeof (LITTLENUM_TYPE
);
667 /* If while processing a fixup, a reloc really needs to be created
668 then it is done here. */
671 tc_gen_reloc (seg
, fixp
)
672 asection
*seg ATTRIBUTE_UNUSED
;
677 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
678 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
679 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
680 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
682 reloc
->addend
= fixp
->fx_offset
;
683 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
685 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
687 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
688 /* xgettext:c-format. */
689 _("reloc %d not supported by object file format"),
690 (int) fixp
->fx_r_type
);
700 /* The location from which a PC relative jump should be calculated,
701 given a PC relative reloc. */
704 md_pcrel_from_section (fixP
, sec
)
708 if (fixP
->fx_addsy
!= (symbolS
*) NULL
709 && (!S_IS_DEFINED (fixP
->fx_addsy
)
710 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
712 /* The symbol is undefined (or is defined but not in this section).
713 Let the linker figure it out. */
716 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
719 /* Return true if the fix can be handled by GAS, false if it must
720 be passed through to the linker. */
723 bfin_fix_adjustable (fixS
*fixP
)
725 switch (fixP
->fx_r_type
)
727 /* Adjust_reloc_syms doesn't know about the GOT. */
728 case BFD_RELOC_BFIN_GOT
:
729 case BFD_RELOC_BFIN_PLTPC
:
730 /* We need the symbol name for the VTABLE entries. */
731 case BFD_RELOC_VTABLE_INHERIT
:
732 case BFD_RELOC_VTABLE_ENTRY
:
741 /* Handle the LOOP_BEGIN and LOOP_END statements.
742 Parse the Loop_Begin/Loop_End and create a label. */
744 bfin_start_line_hook ()
746 bfd_boolean maybe_begin
= FALSE
;
747 bfd_boolean maybe_end
= FALSE
;
749 char *c1
, *label_name
;
751 char *c
= input_line_pointer
;
756 /* Look for Loop_Begin or Loop_End statements. */
758 if (*c
!= 'L' && *c
!= 'l')
762 if (*c
!= 'O' && *c
!= 'o')
766 if (*c
!= 'O' && *c
!= 'o')
770 if (*c
!= 'P' && *c
!= 'p')
778 if (*c
== 'E' || *c
== 'e')
780 else if (*c
== 'B' || *c
== 'b')
788 if (*c
!= 'N' && *c
!= 'n')
792 if (*c
!= 'D' && *c
!= 'd')
799 if (*c
!= 'E' && *c
!= 'e')
803 if (*c
!= 'G' && *c
!= 'g')
807 if (*c
!= 'I' && *c
!= 'i')
811 if (*c
!= 'N' && *c
!= 'n')
816 while (ISSPACE (*c
)) c
++;
818 while (ISALPHA (*c
) || ISDIGIT (*c
) || *c
== '_') c
++;
820 input_line_pointer
= c
;
823 label_name
= (char *) xmalloc ((c
- c1
) + strlen ("__END") + 1);
825 strncat (label_name
, c1
, c
-c1
);
826 strcat (label_name
, "__END");
828 else /* maybe_begin. */
830 label_name
= (char *) xmalloc ((c
- c1
) + strlen ("__BEGIN") + 1);
832 strncat (label_name
, c1
, c
-c1
);
833 strcat (label_name
, "__BEGIN");
836 line_label
= colon (label_name
);
838 /* Loop_End follows the last instruction in the loop.
839 Adjust label address. */
841 line_label
->sy_value
.X_add_number
-= last_insn_size
;
845 /* Special extra functions that help bfin-parse.y perform its job. */
851 #include "bfin-defs.h"
853 struct obstack mempool
;
856 conscode (INSTR_T head
, INSTR_T tail
)
865 conctcode (INSTR_T head
, INSTR_T tail
)
867 INSTR_T temp
= (head
);
878 note_reloc (INSTR_T code
, Expr_Node
* symbol
, int reloc
, int pcrel
)
880 /* Assert that the symbol is not an operator. */
881 assert (symbol
->type
== Expr_Node_Reloc
);
883 return note_reloc1 (code
, symbol
->value
.s_value
, reloc
, pcrel
);
888 note_reloc1 (INSTR_T code
, const char *symbol
, int reloc
, int pcrel
)
891 code
->exp
= mkexpr (0, symbol_find_or_make (symbol
));
897 note_reloc2 (INSTR_T code
, const char *symbol
, int reloc
, int value
, int pcrel
)
900 code
->exp
= mkexpr (value
, symbol_find_or_make (symbol
));
906 gencode (unsigned long x
)
908 INSTR_T cell
= (INSTR_T
) obstack_alloc (&mempool
, sizeof (struct bfin_insn
));
909 memset (cell
, 0, sizeof (struct bfin_insn
));
921 return (void *) obstack_alloc (&mempool
, n
);
925 Expr_Node_Create (Expr_Node_Type type
,
926 Expr_Node_Value value
,
927 Expr_Node
*Left_Child
,
928 Expr_Node
*Right_Child
)
932 Expr_Node
*node
= (Expr_Node
*) allocate (sizeof (Expr_Node
));
935 node
->Left_Child
= Left_Child
;
936 node
->Right_Child
= Right_Child
;
940 static const char *con
= ".__constant";
941 static const char *op
= ".__operator";
942 static INSTR_T
Expr_Node_Gen_Reloc_R (Expr_Node
* head
);
943 INSTR_T
Expr_Node_Gen_Reloc (Expr_Node
*head
, int parent_reloc
);
946 Expr_Node_Gen_Reloc (Expr_Node
* head
, int parent_reloc
)
948 /* Top level reloction expression generator VDSP style.
949 If the relocation is just by itself, generate one item
950 else generate this convoluted expression. */
952 INSTR_T note
= NULL_CODE
;
953 INSTR_T note1
= NULL_CODE
;
954 int pcrel
= 1; /* Is the parent reloc pcrelative?
955 This calculation here and HOWTO should match. */
959 /* If it's 32 bit quantity then 16bit code needs to be added. */
962 if (head
->type
== Expr_Node_Constant
)
964 /* If note1 is not null code, we have to generate a right
965 aligned value for the constant. Otherwise the reloc is
966 a part of the basic command and the yacc file
968 value
= head
->value
.i_value
;
970 switch (parent_reloc
)
972 /* Some reloctions will need to allocate extra words. */
973 case BFD_RELOC_BFIN_16_IMM
:
974 case BFD_RELOC_BFIN_16_LOW
:
975 case BFD_RELOC_BFIN_16_HIGH
:
976 note1
= conscode (gencode (value
), NULL_CODE
);
979 case BFD_RELOC_BFIN_PLTPC
:
980 note1
= conscode (gencode (value
), NULL_CODE
);
984 case BFD_RELOC_BFIN_GOT
:
985 note1
= conscode (gencode (value
), NULL_CODE
);
988 case BFD_RELOC_24_PCREL
:
989 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
990 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
991 /* These offsets are even numbered pcrel. */
992 note1
= conscode (gencode (value
>> 1), NULL_CODE
);
998 if (head
->type
== Expr_Node_Constant
)
1000 else if (head
->type
== Expr_Node_Reloc
)
1002 note
= note_reloc1 (gencode (0), head
->value
.s_value
, parent_reloc
, pcrel
);
1003 if (note1
!= NULL_CODE
)
1004 note
= conscode (note1
, note
);
1006 else if (head
->type
== Expr_Node_Binop
1007 && (head
->value
.op_value
== Expr_Op_Type_Add
1008 || head
->value
.op_value
== Expr_Op_Type_Sub
)
1009 && head
->Left_Child
->type
== Expr_Node_Reloc
1010 && head
->Right_Child
->type
== Expr_Node_Constant
)
1012 int val
= head
->Right_Child
->value
.i_value
;
1013 if (head
->value
.op_value
== Expr_Op_Type_Sub
)
1015 note
= conscode (note_reloc2 (gencode (0), head
->Left_Child
->value
.s_value
,
1016 parent_reloc
, val
, 0),
1018 if (note1
!= NULL_CODE
)
1019 note
= conscode (note1
, note
);
1023 /* Call the recursive function. */
1024 note
= note_reloc1 (gencode (0), op
, parent_reloc
, pcrel
);
1025 if (note1
!= NULL_CODE
)
1026 note
= conscode (note1
, note
);
1027 note
= conctcode (Expr_Node_Gen_Reloc_R (head
), note
);
1033 Expr_Node_Gen_Reloc_R (Expr_Node
* head
)
1041 case Expr_Node_Constant
:
1042 note
= conscode (note_reloc2 (gencode (0), con
, BFD_ARELOC_BFIN_CONST
, head
->value
.i_value
, 0), NULL_CODE
);
1044 case Expr_Node_Reloc
:
1045 note
= conscode (note_reloc (gencode (0), head
, BFD_ARELOC_BFIN_PUSH
, 0), NULL_CODE
);
1047 case Expr_Node_Binop
:
1048 note1
= conctcode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), Expr_Node_Gen_Reloc_R (head
->Right_Child
));
1049 switch (head
->value
.op_value
)
1051 case Expr_Op_Type_Add
:
1052 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_ADD
, 0), NULL_CODE
));
1054 case Expr_Op_Type_Sub
:
1055 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_SUB
, 0), NULL_CODE
));
1057 case Expr_Op_Type_Mult
:
1058 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MULT
, 0), NULL_CODE
));
1060 case Expr_Op_Type_Div
:
1061 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_DIV
, 0), NULL_CODE
));
1063 case Expr_Op_Type_Mod
:
1064 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MOD
, 0), NULL_CODE
));
1066 case Expr_Op_Type_Lshift
:
1067 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LSHIFT
, 0), NULL_CODE
));
1069 case Expr_Op_Type_Rshift
:
1070 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_RSHIFT
, 0), NULL_CODE
));
1072 case Expr_Op_Type_BAND
:
1073 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_AND
, 0), NULL_CODE
));
1075 case Expr_Op_Type_BOR
:
1076 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_OR
, 0), NULL_CODE
));
1078 case Expr_Op_Type_BXOR
:
1079 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_XOR
, 0), NULL_CODE
));
1081 case Expr_Op_Type_LAND
:
1082 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LAND
, 0), NULL_CODE
));
1084 case Expr_Op_Type_LOR
:
1085 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LOR
, 0), NULL_CODE
));
1088 fprintf (stderr
, "%s:%d:Unkonwn operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1093 case Expr_Node_Unop
:
1094 note1
= conscode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), NULL_CODE
);
1095 switch (head
->value
.op_value
)
1097 case Expr_Op_Type_NEG
:
1098 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_NEG
, 0), NULL_CODE
));
1100 case Expr_Op_Type_COMP
:
1101 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_COMP
, 0), NULL_CODE
));
1104 fprintf (stderr
, "%s:%d:Unkonwn operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1108 fprintf (stderr
, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__
, __LINE__
);
1114 /* Blackfin opcode generation. */
1116 /* These functions are called by the generated parser
1117 (from bfin-parse.y), the register type classification
1118 happens in bfin-lex.l. */
1120 #include "bfin-aux.h"
1121 #include "opcode/bfin.h"
1123 #define INIT(t) t c_code = init_##t
1124 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1125 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1127 #define HI(x) ((x >> 16) & 0xffff)
1128 #define LO(x) ((x ) & 0xffff)
1130 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1132 #define GEN_OPCODE32() \
1133 conscode (gencode (HI (c_code.opcode)), \
1134 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1136 #define GEN_OPCODE16() \
1137 conscode (gencode (c_code.opcode), NULL_CODE)
1140 /* 32 BIT INSTRUCTIONS. */
1143 /* DSP32 instruction generation. */
1146 bfin_gen_dsp32mac (int op1
, int MM
, int mmod
, int w1
, int P
,
1147 int h01
, int h11
, int h00
, int h10
, int op0
,
1148 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1164 /* If we have full reg assignments, mask out LSB to encode
1165 single or simultaneous even/odd register moves. */
1175 return GEN_OPCODE32 ();
1179 bfin_gen_dsp32mult (int op1
, int MM
, int mmod
, int w1
, int P
,
1180 int h01
, int h11
, int h00
, int h10
, int op0
,
1181 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1206 return GEN_OPCODE32 ();
1210 bfin_gen_dsp32alu (int HL
, int aopcde
, int aop
, int s
, int x
,
1211 REG_T dst0
, REG_T dst1
, REG_T src0
, REG_T src1
)
1225 return GEN_OPCODE32 ();
1229 bfin_gen_dsp32shift (int sopcde
, REG_T dst0
, REG_T src0
,
1230 REG_T src1
, int sop
, int HLs
)
1242 return GEN_OPCODE32 ();
1246 bfin_gen_dsp32shiftimm (int sopcde
, REG_T dst0
, int immag
,
1247 REG_T src1
, int sop
, int HLs
)
1249 INIT (DSP32ShiftImm
);
1259 return GEN_OPCODE32 ();
1265 bfin_gen_loopsetup (Expr_Node
* psoffset
, REG_T c
, int rop
,
1266 Expr_Node
* peoffset
, REG_T reg
)
1268 int soffset
, eoffset
;
1271 soffset
= (EXPR_VALUE (psoffset
) >> 1);
1273 eoffset
= (EXPR_VALUE (peoffset
) >> 1);
1280 conscode (gencode (HI (c_code
.opcode
)),
1281 conctcode (Expr_Node_Gen_Reloc (psoffset
, BFD_RELOC_BFIN_5_PCREL
),
1282 conctcode (gencode (LO (c_code
.opcode
)), Expr_Node_Gen_Reloc (peoffset
, BFD_RELOC_BFIN_11_PCREL
))));
1289 bfin_gen_calla (Expr_Node
* addr
, int S
)
1297 case 0 : reloc
= BFD_RELOC_BFIN_24_PCREL_JUMP_L
; break;
1298 case 1 : reloc
= BFD_RELOC_24_PCREL
; break;
1299 case 2 : reloc
= BFD_RELOC_BFIN_PLTPC
; break;
1305 val
= EXPR_VALUE (addr
) >> 1;
1306 high_val
= val
>> 16;
1308 return conscode (gencode (HI (c_code
.opcode
) | (high_val
& 0xff)),
1309 Expr_Node_Gen_Reloc (addr
, reloc
));
1313 bfin_gen_linkage (int R
, int framesize
)
1320 return GEN_OPCODE32 ();
1324 /* Load and Store. */
1327 bfin_gen_ldimmhalf (REG_T reg
, int H
, int S
, int Z
, Expr_Node
* phword
, int reloc
)
1330 unsigned val
= EXPR_VALUE (phword
);
1338 grp
= (GROUP (reg
));
1342 return conscode (gencode (HI (c_code
.opcode
)), Expr_Node_Gen_Reloc (phword
, BFD_RELOC_BFIN_16_IMM
));
1344 else if (reloc
== 1)
1346 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
));
1353 return GEN_OPCODE32 ();
1357 bfin_gen_ldstidxi (REG_T ptr
, REG_T reg
, int W
, int sz
, int Z
, Expr_Node
* poffset
)
1363 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1365 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1376 value
= EXPR_VALUE (poffset
) >> 2;
1379 value
= EXPR_VALUE (poffset
) >> 1;
1382 value
= EXPR_VALUE (poffset
);
1389 offset
= (value
& 0xffff);
1391 /* TODO : test if you need to check this here.
1392 The reloc case should automatically generate instruction
1394 if(poffset
->type
!= Expr_Node_Constant
){
1395 /* A GOT relocation such as R0 = [P5 + symbol@GOT].
1396 Distinguish between R0 = [P5 + symbol@GOT] and
1397 P5 = [P5 + _current_shared_library_p5_offset_]. */
1398 if(!strcmp(poffset
->value
.s_value
, "_current_shared_library_p5_offset_")){
1399 return conscode (gencode (HI (c_code
.opcode
)),
1400 Expr_Node_Gen_Reloc(poffset
, BFD_RELOC_16
));
1404 return conscode (gencode (HI (c_code
.opcode
)),
1405 Expr_Node_Gen_Reloc(poffset
, BFD_RELOC_BFIN_GOT
));
1409 return GEN_OPCODE32 ();
1415 bfin_gen_ldst (REG_T ptr
, REG_T reg
, int aop
, int sz
, int Z
, int W
)
1419 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1421 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1432 return GEN_OPCODE16 ();
1436 bfin_gen_ldstii (REG_T ptr
, REG_T reg
, Expr_Node
* poffset
, int W
, int op
)
1443 if (!IS_PREG (*ptr
))
1445 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1453 value
= EXPR_VALUE (poffset
) >> 1;
1457 value
= EXPR_VALUE (poffset
) >> 2;
1469 return GEN_OPCODE16 ();
1473 bfin_gen_ldstiifp (REG_T sreg
, Expr_Node
* poffset
, int W
)
1475 /* Set bit 4 if it's a Preg. */
1476 int reg
= (sreg
->regno
& CODE_MASK
) | (IS_PREG (*sreg
) ? 0x8 : 0x0);
1477 int offset
= ((~(EXPR_VALUE (poffset
) >> 2)) & 0x1f) + 1;
1483 return GEN_OPCODE16 ();
1487 bfin_gen_ldstpmod (REG_T ptr
, REG_T reg
, int aop
, int W
, REG_T idx
)
1497 return GEN_OPCODE16 ();
1501 bfin_gen_dspldst (REG_T i
, REG_T reg
, int aop
, int W
, int m
)
1511 return GEN_OPCODE16 ();
1515 bfin_gen_logi2op (int opc
, int src
, int dst
)
1523 return GEN_OPCODE16 ();
1527 bfin_gen_brcc (int T
, int B
, Expr_Node
* poffset
)
1534 offset
= ((EXPR_VALUE (poffset
) >> 1));
1536 return conscode (gencode (c_code
.opcode
), Expr_Node_Gen_Reloc (poffset
, BFD_RELOC_BFIN_10_PCREL
));
1540 bfin_gen_ujump (Expr_Node
* poffset
)
1545 offset
= ((EXPR_VALUE (poffset
) >> 1));
1548 return conscode (gencode (c_code
.opcode
),
1549 Expr_Node_Gen_Reloc (
1550 poffset
, BFD_RELOC_BFIN_12_PCREL_JUMP_S
));
1554 bfin_gen_alu2op (REG_T dst
, REG_T src
, int opc
)
1562 return GEN_OPCODE16 ();
1566 bfin_gen_compi2opd (REG_T dst
, int src
, int op
)
1574 return GEN_OPCODE16 ();
1578 bfin_gen_compi2opp (REG_T dst
, int src
, int op
)
1586 return GEN_OPCODE16 ();
1590 bfin_gen_dagmodik (REG_T i
, int op
)
1597 return GEN_OPCODE16 ();
1601 bfin_gen_dagmodim (REG_T i
, REG_T m
, int op
, int br
)
1610 return GEN_OPCODE16 ();
1614 bfin_gen_ptr2op (REG_T dst
, REG_T src
, int opc
)
1622 return GEN_OPCODE16 ();
1626 bfin_gen_comp3op (REG_T src0
, REG_T src1
, REG_T dst
, int opc
)
1635 return GEN_OPCODE16 ();
1639 bfin_gen_ccflag (REG_T x
, int y
, int opc
, int I
, int G
)
1649 return GEN_OPCODE16 ();
1653 bfin_gen_ccmv (REG_T src
, REG_T dst
, int T
)
1666 return GEN_OPCODE16 ();
1670 bfin_gen_cc2stat (int cbit
, int op
, int D
)
1678 return GEN_OPCODE16 ();
1682 bfin_gen_regmv (REG_T src
, REG_T dst
)
1695 return GEN_OPCODE16 ();
1699 bfin_gen_cc2dreg (int op
, REG_T reg
)
1706 return GEN_OPCODE16 ();
1710 bfin_gen_progctrl (int prgfunc
, int poprnd
)
1717 return GEN_OPCODE16 ();
1721 bfin_gen_cactrl (REG_T reg
, int a
, int op
)
1729 return GEN_OPCODE16 ();
1733 bfin_gen_pushpopmultiple (int dr
, int pr
, int d
, int p
, int W
)
1735 INIT (PushPopMultiple
);
1743 return GEN_OPCODE16 ();
1747 bfin_gen_pushpopreg (REG_T reg
, int W
)
1753 grp
= (GROUP (reg
));
1757 return GEN_OPCODE16 ();
1760 /* Pseudo Debugging Support. */
1763 bfin_gen_pseudodbg (int fn
, int reg
, int grp
)
1771 return GEN_OPCODE16 ();
1775 bfin_gen_pseudodbg_assert (int dbgop
, REG_T regtest
, int expected
)
1777 INIT (PseudoDbg_Assert
);
1783 return GEN_OPCODE32 ();
1786 /* Multiple instruction generation. */
1789 bfin_gen_multi_instr (INSTR_T dsp32
, INSTR_T dsp16_grp1
, INSTR_T dsp16_grp2
)
1793 /* If it's a 0, convert into MNOP. */
1797 SET_MULTI_INSTRUCTION_BIT (dsp32
);
1801 dsp32
= gencode (0xc803);
1802 walk
= gencode (0x1800);
1808 dsp16_grp1
= gencode (0x0000);
1813 dsp16_grp2
= gencode (0x0000);
1816 walk
->next
= dsp16_grp1
;
1817 dsp16_grp1
->next
= dsp16_grp2
;
1818 dsp16_grp2
->next
= NULL_CODE
;
1824 bfin_gen_loop (Expr_Node
*expr
, REG_T reg
, int rop
, REG_T preg
)
1826 const char *loopsym
;
1827 char *lbeginsym
, *lendsym
;
1828 Expr_Node_Value lbeginval
, lendval
;
1829 Expr_Node
*lbegin
, *lend
;
1831 loopsym
= expr
->value
.s_value
;
1832 lbeginsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__BEGIN") + 1);
1833 lendsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__END") + 1);
1838 strcat (lbeginsym
, loopsym
);
1839 strcat (lbeginsym
, "__BEGIN");
1841 strcat (lendsym
, loopsym
);
1842 strcat (lendsym
, "__END");
1844 lbeginval
.s_value
= lbeginsym
;
1845 lendval
.s_value
= lendsym
;
1847 lbegin
= Expr_Node_Create (Expr_Node_Reloc
, lbeginval
, NULL
, NULL
);
1848 lend
= Expr_Node_Create (Expr_Node_Reloc
, lendval
, NULL
, NULL
);
1849 return bfin_gen_loopsetup(lbegin
, reg
, rop
, lend
, preg
);
1853 bfin_eol_in_insn (char *line
)
1855 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1862 /* A semi-colon followed by a newline is always the end of a line. */
1863 if (line
[-1] == ';')
1866 if (line
[-1] == '|')
1869 /* If the || is on the next line, there might be leading whitespace. */
1871 while (*temp
== ' ' || *temp
== '\t') temp
++;
1880 bfin_name_is_register (char *name
)
1884 if (*name
== '[' || *name
== '(')
1887 if ((name
[0] == 'W' || name
[0] == 'w') && name
[1] == '[')
1890 if ((name
[0] == 'B' || name
[0] == 'b') && name
[1] == '[')
1893 for (i
=0; bfin_reg_info
[i
].name
!= 0; i
++)
1895 if (!strcasecmp (bfin_reg_info
[i
].name
, name
))
1902 bfin_equals (Expr_Node
*sym
)
1906 c
= input_line_pointer
;
1910 input_line_pointer
= c
;
1912 equals ((char *) sym
->value
.s_value
, 1);
1916 bfin_start_label (char *ptr
)
1919 while (!ISSPACE (*ptr
) && !is_end_of_line
[(unsigned char) *ptr
])
1923 if (*ptr
== '(' || *ptr
== '[')
1930 bfin_force_relocation (struct fix
*fixp
)
1932 if (fixp
->fx_r_type
==BFD_RELOC_BFIN_16_LOW
1933 || fixp
->fx_r_type
== BFD_RELOC_BFIN_16_HIGH
)
1936 return generic_force_reloc (fixp
);