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 ((unsigned 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. */
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 (val
, n
)
457 unsigned char *val
; /* Value in target byte order. */
458 int n
; /* Number of bytes in the input. */
462 for (retval
= 0; n
--;)
471 md_apply_fix (fixS
*fixP
, valueT
*valueP
, segT seg ATTRIBUTE_UNUSED
)
473 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
475 long value
= *valueP
;
478 switch (fixP
->fx_r_type
)
480 case BFD_RELOC_BFIN_GOT
:
481 fixP
->fx_no_overflow
= 1;
482 newval
= md_chars_to_number (where
, 2);
483 newval
|= 0x0 & 0x7f;
484 md_number_to_chars (where
, newval
, 2);
487 case BFD_RELOC_BFIN_10_PCREL
:
490 if (value
< -1024 || value
> 1022)
491 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
492 "pcrel too far BFD_RELOC_BFIN_10");
494 /* 11 bit offset even numbered, so we remove right bit. */
496 newval
= md_chars_to_number (where
, 2);
497 newval
|= value
& 0x03ff;
498 md_number_to_chars (where
, newval
, 2);
501 case BFD_RELOC_BFIN_12_PCREL_JUMP
:
502 case BFD_RELOC_BFIN_12_PCREL_JUMP_S
:
503 case BFD_RELOC_12_PCREL
:
507 if (value
< -4096 || value
> 4094)
508 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "pcrel too far BFD_RELOC_BFIN_12");
509 /* 13 bit offset even numbered, so we remove right bit. */
511 newval
= md_chars_to_number (where
, 2);
512 newval
|= value
& 0xfff;
513 md_number_to_chars (where
, newval
, 2);
516 case BFD_RELOC_BFIN_16_LOW
:
517 case BFD_RELOC_BFIN_16_HIGH
:
518 fixP
->fx_done
= FALSE
;
521 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
522 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
523 case BFD_RELOC_24_PCREL
:
527 if (value
< -16777216 || value
> 16777214)
528 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "pcrel too far BFD_RELOC_BFIN_24");
530 /* 25 bit offset even numbered, so we remove right bit. */
534 md_number_to_chars (where
- 2, value
>> 16, 1);
535 md_number_to_chars (where
, value
, 1);
536 md_number_to_chars (where
+ 1, value
>> 8, 1);
539 case BFD_RELOC_BFIN_5_PCREL
: /* LSETUP (a, b) : "a" */
542 if (value
< 4 || value
> 30)
543 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "pcrel too far BFD_RELOC_BFIN_5");
545 newval
= md_chars_to_number (where
, 1);
546 newval
= (newval
& 0xf0) | (value
& 0xf);
547 md_number_to_chars (where
, newval
, 1);
550 case BFD_RELOC_BFIN_11_PCREL
: /* LSETUP (a, b) : "b" */
554 if (value
< 4 || value
> 2046)
555 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "pcrel too far BFD_RELOC_BFIN_11_PCREL");
556 /* 11 bit unsigned even, so we remove right bit. */
558 newval
= md_chars_to_number (where
, 2);
559 newval
|= value
& 0x03ff;
560 md_number_to_chars (where
, newval
, 2);
564 if (value
< -0x80 || value
>= 0x7f)
565 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "rel too far BFD_RELOC_8");
566 md_number_to_chars (where
, value
, 1);
569 case BFD_RELOC_BFIN_16_IMM
:
571 if (value
< -0x8000 || value
>= 0x7fff)
572 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "rel too far BFD_RELOC_8");
573 md_number_to_chars (where
, value
, 2);
577 md_number_to_chars (where
, value
, 4);
580 case BFD_RELOC_BFIN_PLTPC
:
581 md_number_to_chars (where
, value
, 2);
584 case BFD_RELOC_VTABLE_INHERIT
:
585 case BFD_RELOC_VTABLE_ENTRY
:
586 fixP
->fx_done
= FALSE
;
590 if ((BFD_ARELOC_BFIN_PUSH
> fixP
->fx_r_type
) || (BFD_ARELOC_BFIN_COMP
< fixP
->fx_r_type
))
592 fprintf (stderr
, "Relocation %d not handled in gas." " Contact support.\n", fixP
->fx_r_type
);
598 fixP
->fx_done
= TRUE
;
602 /* Round up a section size to the appropriate boundary. */
604 md_section_align (segment
, size
)
608 int boundary
= bfd_get_section_alignment (stdoutput
, segment
);
609 return ((size
+ (1 << boundary
) - 1) & (-1 << boundary
));
613 /* Turn a string in input_line_pointer into a floating point
614 constant of type type, and store the appropriate bytes in
615 *litP. The number of LITTLENUMS emitted is stored in *sizeP.
616 An error message is returned, or NULL on OK. */
618 /* Equal to MAX_PRECISION in atof-ieee.c. */
619 #define MAX_LITTLENUMS 6
622 md_atof (type
, litP
, sizeP
)
628 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
629 LITTLENUM_TYPE
*wordP
;
644 /* FIXME: Some targets allow other format chars for bigger sizes here. */
648 return _("Bad call to md_atof()");
651 t
= atof_ieee (input_line_pointer
, type
, words
);
653 input_line_pointer
= t
;
654 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
656 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
657 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
658 the littleendianness of the processor. */
659 for (wordP
= words
+ prec
- 1; prec
--;)
661 md_number_to_chars (litP
, (valueT
) (*wordP
--), sizeof (LITTLENUM_TYPE
));
662 litP
+= sizeof (LITTLENUM_TYPE
);
669 /* If while processing a fixup, a reloc really needs to be created
670 then it is done here. */
673 tc_gen_reloc (seg
, fixp
)
674 asection
*seg ATTRIBUTE_UNUSED
;
679 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
680 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
681 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
682 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
684 reloc
->addend
= fixp
->fx_offset
;
685 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
687 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
689 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
690 /* xgettext:c-format. */
691 _("reloc %d not supported by object file format"),
692 (int) fixp
->fx_r_type
);
702 /* The location from which a PC relative jump should be calculated,
703 given a PC relative reloc. */
706 md_pcrel_from_section (fixP
, sec
)
710 if (fixP
->fx_addsy
!= (symbolS
*) NULL
711 && (!S_IS_DEFINED (fixP
->fx_addsy
)
712 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
714 /* The symbol is undefined (or is defined but not in this section).
715 Let the linker figure it out. */
718 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
721 /* Return true if the fix can be handled by GAS, false if it must
722 be passed through to the linker. */
725 bfin_fix_adjustable (fixS
*fixP
)
727 switch (fixP
->fx_r_type
)
729 /* Adjust_reloc_syms doesn't know about the GOT. */
730 case BFD_RELOC_BFIN_GOT
:
731 case BFD_RELOC_BFIN_PLTPC
:
732 /* We need the symbol name for the VTABLE entries. */
733 case BFD_RELOC_VTABLE_INHERIT
:
734 case BFD_RELOC_VTABLE_ENTRY
:
743 /* Handle the LOOP_BEGIN and LOOP_END statements.
744 Parse the Loop_Begin/Loop_End and create a label. */
746 bfin_start_line_hook ()
748 bfd_boolean maybe_begin
= FALSE
;
749 bfd_boolean maybe_end
= FALSE
;
751 char *c1
, *label_name
;
753 char *c
= input_line_pointer
;
758 /* Look for LSETUP(. */
759 if (!strncasecmp (input_line_pointer
, "lsetup(", 7))
761 /* Need to insert space between lsetup and paren. */
762 input_line_pointer
--;
763 input_line_pointer
[0] = 'l';
764 input_line_pointer
[1] = 's';
765 input_line_pointer
[2] = 'e';
766 input_line_pointer
[3] = 't';
767 input_line_pointer
[4] = 'u';
768 input_line_pointer
[5] = 'p';
769 input_line_pointer
[6] = ' ';
773 /* Look for Loop_Begin or Loop_End statements. */
775 if (*c
!= 'L' && *c
!= 'l')
779 if (*c
!= 'O' && *c
!= 'o')
783 if (*c
!= 'O' && *c
!= 'o')
787 if (*c
!= 'P' && *c
!= 'p')
795 if (*c
== 'E' || *c
== 'e')
797 else if (*c
== 'B' || *c
== 'b')
805 if (*c
!= 'N' && *c
!= 'n')
809 if (*c
!= 'D' && *c
!= 'd')
816 if (*c
!= 'E' && *c
!= 'e')
820 if (*c
!= 'G' && *c
!= 'g')
824 if (*c
!= 'I' && *c
!= 'i')
828 if (*c
!= 'N' && *c
!= 'n')
833 while (ISSPACE (*c
)) c
++;
835 while (ISALPHA (*c
) || ISDIGIT (*c
) || *c
== '_') c
++;
837 input_line_pointer
= c
;
840 label_name
= (char *) xmalloc ((c
- c1
) + strlen ("__END") + 1);
842 strncat (label_name
, c1
, c
-c1
);
843 strcat (label_name
, "__END");
845 else /* maybe_begin. */
847 label_name
= (char *) xmalloc ((c
- c1
) + strlen ("__BEGIN") + 1);
849 strncat (label_name
, c1
, c
-c1
);
850 strcat (label_name
, "__BEGIN");
853 line_label
= colon (label_name
);
855 /* Loop_End follows the last instruction in the loop.
856 Adjust label address. */
858 line_label
->sy_value
.X_add_number
-= last_insn_size
;
862 /* Special extra functions that help bfin-parse.y perform its job. */
868 #include "bfin-defs.h"
870 struct obstack mempool
;
873 conscode (INSTR_T head
, INSTR_T tail
)
882 conctcode (INSTR_T head
, INSTR_T tail
)
884 INSTR_T temp
= (head
);
895 note_reloc (INSTR_T code
, Expr_Node
* symbol
, int reloc
, int pcrel
)
897 /* Assert that the symbol is not an operator. */
898 assert (symbol
->type
== Expr_Node_Reloc
);
900 return note_reloc1 (code
, symbol
->value
.s_value
, reloc
, pcrel
);
905 note_reloc1 (INSTR_T code
, const char *symbol
, int reloc
, int pcrel
)
908 code
->exp
= mkexpr (0, symbol_find_or_make (symbol
));
914 note_reloc2 (INSTR_T code
, const char *symbol
, int reloc
, int value
, int pcrel
)
917 code
->exp
= mkexpr (value
, symbol_find_or_make (symbol
));
923 gencode (unsigned long x
)
925 INSTR_T cell
= (INSTR_T
) obstack_alloc (&mempool
, sizeof (struct bfin_insn
));
926 memset (cell
, 0, sizeof (struct bfin_insn
));
938 return (void *) obstack_alloc (&mempool
, n
);
942 Expr_Node_Create (Expr_Node_Type type
,
943 Expr_Node_Value value
,
944 Expr_Node
*Left_Child
,
945 Expr_Node
*Right_Child
)
949 Expr_Node
*node
= (Expr_Node
*) allocate (sizeof (Expr_Node
));
952 node
->Left_Child
= Left_Child
;
953 node
->Right_Child
= Right_Child
;
957 static const char *con
= ".__constant";
958 static const char *op
= ".__operator";
959 static INSTR_T
Expr_Node_Gen_Reloc_R (Expr_Node
* head
);
960 INSTR_T
Expr_Node_Gen_Reloc (Expr_Node
*head
, int parent_reloc
);
963 Expr_Node_Gen_Reloc (Expr_Node
* head
, int parent_reloc
)
965 /* Top level reloction expression generator VDSP style.
966 If the relocation is just by itself, generate one item
967 else generate this convoluted expression. */
969 INSTR_T note
= NULL_CODE
;
970 INSTR_T note1
= NULL_CODE
;
971 int pcrel
= 1; /* Is the parent reloc pcrelative?
972 This calculation here and HOWTO should match. */
976 /* If it's 32 bit quantity then 16bit code needs to be added. */
979 if (head
->type
== Expr_Node_Constant
)
981 /* If note1 is not null code, we have to generate a right
982 aligned value for the constant. Otherwise the reloc is
983 a part of the basic command and the yacc file
985 value
= head
->value
.i_value
;
987 switch (parent_reloc
)
989 /* Some reloctions will need to allocate extra words. */
990 case BFD_RELOC_BFIN_16_IMM
:
991 case BFD_RELOC_BFIN_16_LOW
:
992 case BFD_RELOC_BFIN_16_HIGH
:
993 note1
= conscode (gencode (value
), NULL_CODE
);
996 case BFD_RELOC_BFIN_PLTPC
:
997 note1
= conscode (gencode (value
), NULL_CODE
);
1001 case BFD_RELOC_BFIN_GOT
:
1002 note1
= conscode (gencode (value
), NULL_CODE
);
1005 case BFD_RELOC_24_PCREL
:
1006 case BFD_RELOC_BFIN_24_PCREL_JUMP_L
:
1007 case BFD_RELOC_BFIN_24_PCREL_CALL_X
:
1008 /* These offsets are even numbered pcrel. */
1009 note1
= conscode (gencode (value
>> 1), NULL_CODE
);
1015 if (head
->type
== Expr_Node_Constant
)
1017 else if (head
->type
== Expr_Node_Reloc
)
1019 note
= note_reloc1 (gencode (0), head
->value
.s_value
, parent_reloc
, pcrel
);
1020 if (note1
!= NULL_CODE
)
1021 note
= conscode (note1
, note
);
1025 /* Call the recursive function. */
1026 note
= note_reloc1 (gencode (0), op
, parent_reloc
, pcrel
);
1027 if (note1
!= NULL_CODE
)
1028 note
= conscode (note1
, note
);
1029 note
= conctcode (Expr_Node_Gen_Reloc_R (head
), note
);
1035 Expr_Node_Gen_Reloc_R (Expr_Node
* head
)
1043 case Expr_Node_Constant
:
1044 note
= conscode (note_reloc2 (gencode (0), con
, BFD_ARELOC_BFIN_CONST
, head
->value
.i_value
, 0), NULL_CODE
);
1046 case Expr_Node_Reloc
:
1047 note
= conscode (note_reloc (gencode (0), head
, BFD_ARELOC_BFIN_PUSH
, 0), NULL_CODE
);
1049 case Expr_Node_Binop
:
1050 note1
= conctcode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), Expr_Node_Gen_Reloc_R (head
->Right_Child
));
1051 switch (head
->value
.op_value
)
1053 case Expr_Op_Type_Add
:
1054 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_ADD
, 0), NULL_CODE
));
1056 case Expr_Op_Type_Sub
:
1057 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_SUB
, 0), NULL_CODE
));
1059 case Expr_Op_Type_Mult
:
1060 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MULT
, 0), NULL_CODE
));
1062 case Expr_Op_Type_Div
:
1063 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_DIV
, 0), NULL_CODE
));
1065 case Expr_Op_Type_Mod
:
1066 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_MOD
, 0), NULL_CODE
));
1068 case Expr_Op_Type_Lshift
:
1069 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LSHIFT
, 0), NULL_CODE
));
1071 case Expr_Op_Type_Rshift
:
1072 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_RSHIFT
, 0), NULL_CODE
));
1074 case Expr_Op_Type_BAND
:
1075 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_AND
, 0), NULL_CODE
));
1077 case Expr_Op_Type_BOR
:
1078 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_OR
, 0), NULL_CODE
));
1080 case Expr_Op_Type_BXOR
:
1081 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_XOR
, 0), NULL_CODE
));
1083 case Expr_Op_Type_LAND
:
1084 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LAND
, 0), NULL_CODE
));
1086 case Expr_Op_Type_LOR
:
1087 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_LOR
, 0), NULL_CODE
));
1090 fprintf (stderr
, "%s:%d:Unkonwn operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1095 case Expr_Node_Unop
:
1096 note1
= conscode (Expr_Node_Gen_Reloc_R (head
->Left_Child
), NULL_CODE
);
1097 switch (head
->value
.op_value
)
1099 case Expr_Op_Type_NEG
:
1100 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_NEG
, 0), NULL_CODE
));
1102 case Expr_Op_Type_COMP
:
1103 note
= conctcode (note1
, conscode (note_reloc1 (gencode (0), op
, BFD_ARELOC_BFIN_COMP
, 0), NULL_CODE
));
1106 fprintf (stderr
, "%s:%d:Unkonwn operator found for arithmetic" " relocation", __FILE__
, __LINE__
);
1110 fprintf (stderr
, "%s:%d:Unknown node expression found during " "arithmetic relocation generation", __FILE__
, __LINE__
);
1116 /* Blackfin opcode generation. */
1118 /* These functions are called by the generated parser
1119 (from bfin-parse.y), the register type classification
1120 happens in bfin-lex.l. */
1122 #include "bfin-aux.h"
1123 #include "opcode/bfin.h"
1125 #define INIT(t) t c_code = init_##t
1126 #define ASSIGN(x) c_code.opcode |= ((x & c_code.mask_##x)<<c_code.bits_##x)
1127 #define ASSIGN_R(x) c_code.opcode |= (((x ? (x->regno & CODE_MASK) : 0) & c_code.mask_##x)<<c_code.bits_##x)
1129 #define HI(x) ((x >> 16) & 0xffff)
1130 #define LO(x) ((x ) & 0xffff)
1132 #define GROUP(x) ((x->regno & CLASS_MASK) >> 4)
1134 #define GEN_OPCODE32() \
1135 conscode (gencode (HI (c_code.opcode)), \
1136 conscode (gencode (LO (c_code.opcode)), NULL_CODE))
1138 #define GEN_OPCODE16() \
1139 conscode (gencode (c_code.opcode), NULL_CODE)
1142 /* 32 BIT INSTRUCTIONS. */
1145 /* DSP32 instruction generation. */
1148 bfin_gen_dsp32mac (int op1
, int MM
, int mmod
, int w1
, int P
,
1149 int h01
, int h11
, int h00
, int h10
, int op0
,
1150 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1166 /* If we have full reg assignments, mask out LSB to encode
1167 single or simultaneous even/odd register moves. */
1177 return GEN_OPCODE32 ();
1181 bfin_gen_dsp32mult (int op1
, int MM
, int mmod
, int w1
, int P
,
1182 int h01
, int h11
, int h00
, int h10
, int op0
,
1183 REG_T dst
, REG_T src0
, REG_T src1
, int w0
)
1208 return GEN_OPCODE32 ();
1212 bfin_gen_dsp32alu (int HL
, int aopcde
, int aop
, int s
, int x
,
1213 REG_T dst0
, REG_T dst1
, REG_T src0
, REG_T src1
)
1227 return GEN_OPCODE32 ();
1231 bfin_gen_dsp32shift (int sopcde
, REG_T dst0
, REG_T src0
,
1232 REG_T src1
, int sop
, int HLs
)
1244 return GEN_OPCODE32 ();
1248 bfin_gen_dsp32shiftimm (int sopcde
, REG_T dst0
, int immag
,
1249 REG_T src1
, int sop
, int HLs
)
1251 INIT (DSP32ShiftImm
);
1261 return GEN_OPCODE32 ();
1267 bfin_gen_loopsetup (Expr_Node
* psoffset
, REG_T c
, int rop
,
1268 Expr_Node
* peoffset
, REG_T reg
)
1270 int soffset
, eoffset
;
1273 soffset
= (EXPR_VALUE (psoffset
) >> 1);
1275 eoffset
= (EXPR_VALUE (peoffset
) >> 1);
1282 conscode (gencode (HI (c_code
.opcode
)),
1283 conctcode (Expr_Node_Gen_Reloc (psoffset
, BFD_RELOC_BFIN_5_PCREL
),
1284 conctcode (gencode (LO (c_code
.opcode
)), Expr_Node_Gen_Reloc (peoffset
, BFD_RELOC_BFIN_11_PCREL
))));
1291 bfin_gen_calla (Expr_Node
* addr
, int S
)
1299 case 0 : reloc
= BFD_RELOC_BFIN_24_PCREL_JUMP_L
; break;
1300 case 1 : reloc
= BFD_RELOC_24_PCREL
; break;
1301 case 2 : reloc
= BFD_RELOC_BFIN_PLTPC
; break;
1307 val
= EXPR_VALUE (addr
) >> 1;
1308 high_val
= val
>> 16;
1310 return conscode (gencode (HI (c_code
.opcode
) | (high_val
& 0xff)),
1311 Expr_Node_Gen_Reloc (addr
, reloc
));
1315 bfin_gen_linkage (int R
, int framesize
)
1322 return GEN_OPCODE32 ();
1326 /* Load and Store. */
1329 bfin_gen_ldimmhalf (REG_T reg
, int H
, int S
, int Z
, Expr_Node
* phword
, int reloc
)
1332 unsigned val
= EXPR_VALUE (phword
);
1340 grp
= (GROUP (reg
));
1344 return conscode (gencode (HI (c_code
.opcode
)), Expr_Node_Gen_Reloc (phword
, BFD_RELOC_BFIN_16_IMM
));
1346 else if (reloc
== 1)
1348 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
));
1355 return GEN_OPCODE32 ();
1359 bfin_gen_ldstidxi (REG_T ptr
, REG_T reg
, int W
, int sz
, int Z
, Expr_Node
* poffset
)
1365 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1367 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1378 value
= EXPR_VALUE (poffset
) >> 2;
1381 value
= EXPR_VALUE (poffset
) >> 1;
1384 value
= EXPR_VALUE (poffset
);
1391 offset
= (value
& 0xffff);
1393 /* TODO : test if you need to check this here.
1394 The reloc case should automatically generate instruction
1396 if(poffset
->type
!= Expr_Node_Constant
){
1397 /* A GOT relocation such as R0 = [P5 + symbol@GOT].
1398 Distinguish between R0 = [P5 + symbol@GOT] and
1399 P5 = [P5 + _current_shared_library_p5_offset_]. */
1400 if(!strcmp(poffset
->value
.s_value
, "_current_shared_library_p5_offset_")){
1401 return conscode (gencode (HI (c_code
.opcode
)),
1402 Expr_Node_Gen_Reloc(poffset
, BFD_RELOC_16
));
1406 return conscode (gencode (HI (c_code
.opcode
)),
1407 Expr_Node_Gen_Reloc(poffset
, BFD_RELOC_BFIN_GOT
));
1411 return GEN_OPCODE32 ();
1417 bfin_gen_ldst (REG_T ptr
, REG_T reg
, int aop
, int sz
, int Z
, int W
)
1421 if (!IS_PREG (*ptr
) || (!IS_DREG (*reg
) && !Z
))
1423 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1434 return GEN_OPCODE16 ();
1438 bfin_gen_ldstii (REG_T ptr
, REG_T reg
, Expr_Node
* poffset
, int W
, int op
)
1445 if (!IS_PREG (*ptr
))
1447 fprintf (stderr
, "Warning: possible mixup of Preg/Dreg\n");
1455 value
= EXPR_VALUE (poffset
) >> 1;
1459 value
= EXPR_VALUE (poffset
) >> 2;
1471 return GEN_OPCODE16 ();
1475 bfin_gen_ldstiifp (REG_T sreg
, Expr_Node
* poffset
, int W
)
1477 /* Set bit 4 if it's a Preg. */
1478 int reg
= (sreg
->regno
& CODE_MASK
) | (IS_PREG (*sreg
) ? 0x8 : 0x0);
1479 int offset
= ((~(EXPR_VALUE (poffset
) >> 2)) & 0x1f) + 1;
1485 return GEN_OPCODE16 ();
1489 bfin_gen_ldstpmod (REG_T ptr
, REG_T reg
, int aop
, int W
, REG_T idx
)
1499 return GEN_OPCODE16 ();
1503 bfin_gen_dspldst (REG_T i
, REG_T reg
, int aop
, int W
, int m
)
1513 return GEN_OPCODE16 ();
1517 bfin_gen_logi2op (int opc
, int src
, int dst
)
1525 return GEN_OPCODE16 ();
1529 bfin_gen_brcc (int T
, int B
, Expr_Node
* poffset
)
1536 offset
= ((EXPR_VALUE (poffset
) >> 1));
1538 return conscode (gencode (c_code
.opcode
), Expr_Node_Gen_Reloc (poffset
, BFD_RELOC_BFIN_10_PCREL
));
1542 bfin_gen_ujump (Expr_Node
* poffset
)
1547 offset
= ((EXPR_VALUE (poffset
) >> 1));
1550 return conscode (gencode (c_code
.opcode
),
1551 Expr_Node_Gen_Reloc (
1552 poffset
, BFD_RELOC_BFIN_12_PCREL_JUMP_S
));
1556 bfin_gen_alu2op (REG_T dst
, REG_T src
, int opc
)
1564 return GEN_OPCODE16 ();
1568 bfin_gen_compi2opd (REG_T dst
, int src
, int op
)
1576 return GEN_OPCODE16 ();
1580 bfin_gen_compi2opp (REG_T dst
, int src
, int op
)
1588 return GEN_OPCODE16 ();
1592 bfin_gen_dagmodik (REG_T i
, int op
)
1599 return GEN_OPCODE16 ();
1603 bfin_gen_dagmodim (REG_T i
, REG_T m
, int op
, int br
)
1612 return GEN_OPCODE16 ();
1616 bfin_gen_ptr2op (REG_T dst
, REG_T src
, int opc
)
1624 return GEN_OPCODE16 ();
1628 bfin_gen_comp3op (REG_T src0
, REG_T src1
, REG_T dst
, int opc
)
1637 return GEN_OPCODE16 ();
1641 bfin_gen_ccflag (REG_T x
, int y
, int opc
, int I
, int G
)
1651 return GEN_OPCODE16 ();
1655 bfin_gen_ccmv (REG_T src
, REG_T dst
, int T
)
1668 return GEN_OPCODE16 ();
1672 bfin_gen_cc2stat (int cbit
, int op
, int D
)
1680 return GEN_OPCODE16 ();
1684 bfin_gen_regmv (REG_T src
, REG_T dst
)
1697 return GEN_OPCODE16 ();
1701 bfin_gen_cc2dreg (int op
, REG_T reg
)
1708 return GEN_OPCODE16 ();
1712 bfin_gen_progctrl (int prgfunc
, int poprnd
)
1719 return GEN_OPCODE16 ();
1723 bfin_gen_cactrl (REG_T reg
, int a
, int op
)
1731 return GEN_OPCODE16 ();
1735 bfin_gen_pushpopmultiple (int dr
, int pr
, int d
, int p
, int W
)
1737 INIT (PushPopMultiple
);
1745 return GEN_OPCODE16 ();
1749 bfin_gen_pushpopreg (REG_T reg
, int W
)
1755 grp
= (GROUP (reg
));
1759 return GEN_OPCODE16 ();
1762 /* Pseudo Debugging Support. */
1765 bfin_gen_pseudodbg (int fn
, int reg
, int grp
)
1773 return GEN_OPCODE16 ();
1777 bfin_gen_pseudodbg_assert (int dbgop
, REG_T regtest
, int expected
)
1779 INIT (PseudoDbg_Assert
);
1785 return GEN_OPCODE32 ();
1788 /* Multiple instruction generation. */
1791 bfin_gen_multi_instr (INSTR_T dsp32
, INSTR_T dsp16_grp1
, INSTR_T dsp16_grp2
)
1795 /* If it's a 0, convert into MNOP. */
1799 SET_MULTI_INSTRUCTION_BIT (dsp32
);
1803 dsp32
= gencode (0xc803);
1804 walk
= gencode (0x1800);
1810 dsp16_grp1
= gencode (0x0000);
1815 dsp16_grp2
= gencode (0x0000);
1818 walk
->next
= dsp16_grp1
;
1819 dsp16_grp1
->next
= dsp16_grp2
;
1820 dsp16_grp2
->next
= NULL_CODE
;
1826 bfin_gen_loop (Expr_Node
*expr
, REG_T reg
, int rop
, REG_T preg
)
1828 const char *loopsym
;
1829 char *lbeginsym
, *lendsym
;
1830 Expr_Node_Value lbeginval
, lendval
;
1831 Expr_Node
*lbegin
, *lend
;
1833 loopsym
= expr
->value
.s_value
;
1834 lbeginsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__BEGIN") + 1);
1835 lendsym
= (char *) xmalloc (strlen (loopsym
) + strlen ("__END") + 1);
1840 strcat (lbeginsym
, loopsym
);
1841 strcat (lbeginsym
, "__BEGIN");
1843 strcat (lendsym
, loopsym
);
1844 strcat (lendsym
, "__END");
1846 lbeginval
.s_value
= lbeginsym
;
1847 lendval
.s_value
= lendsym
;
1849 lbegin
= Expr_Node_Create (Expr_Node_Reloc
, lbeginval
, NULL
, NULL
);
1850 lend
= Expr_Node_Create (Expr_Node_Reloc
, lendval
, NULL
, NULL
);
1851 return bfin_gen_loopsetup(lbegin
, reg
, rop
, lend
, preg
);
1855 bfin_eol_in_insn (char *line
)
1857 /* Allow a new-line to appear in the middle of a multi-issue instruction. */
1864 /* A semi-colon followed by a newline is always the end of a line. */
1865 if (line
[-1] == ';')
1868 if (line
[-1] == '|')
1871 /* If the || is on the next line, there might be leading whitespace. */
1873 while (*temp
== ' ' || *temp
== '\t') temp
++;
1882 bfin_name_is_register (char *name
)
1886 if (*name
== '[' || *name
== '(')
1889 if ((name
[0] == 'W' || name
[0] == 'w') && name
[1] == '[')
1892 if ((name
[0] == 'B' || name
[0] == 'b') && name
[1] == '[')
1895 if (!strncasecmp (name
, "saa(", 4))
1898 if (!strncasecmp (name
, "lsetup(", 7))
1901 for (i
=0; bfin_reg_info
[i
].name
!= 0; i
++)
1903 if (!strcasecmp (bfin_reg_info
[i
].name
, name
))
1910 bfin_equals (Expr_Node
*sym
)
1914 c
= input_line_pointer
;
1918 input_line_pointer
= c
;
1920 equals ((char *) sym
->value
.s_value
, 1);
1924 bfin_start_label (char *ptr
)
1927 while (!ISSPACE (*ptr
) && !is_end_of_line
[(unsigned char) *ptr
])
1931 if (*ptr
== '(' || *ptr
== '[')
1934 if (!strncmp (ptr
, "saa(", 4))
1937 if (!strncmp (ptr
, "lsetup(", 7))
1944 bfin_force_relocation (struct fix
*fixp
)
1946 if (fixp
->fx_r_type
==BFD_RELOC_BFIN_16_LOW
1947 || fixp
->fx_r_type
== BFD_RELOC_BFIN_16_HIGH
)
1950 return generic_force_reloc (fixp
);