2 Copyright (C) 2014-2018 Free Software Foundation, Inc.
3 Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
24 #include "bfd_stdint.h"
25 #include "opcode/pru.h"
29 #include "dwarf2dbg.h"
31 #include "safe-ctype.h"
32 #include "dw2gencfi.h"
35 /* We are not supporting any other target so we throw a compile time error. */
36 #error "OBJ_ELF not defined"
39 /* This array holds the chars that always start a comment. If the
40 pre-processor is disabled, these aren't very useful. */
41 const char comment_chars
[] = "#;";
43 /* This array holds the chars that only start a comment at the beginning of
44 a line. If the line seems to have the form '# 123 filename'
45 .line and .file directives will appear in the pre-processed output. */
46 /* Note that input_file.c hand checks for '#' at the beginning of the
47 first line of the input file. This is because the compiler outputs
48 #NO_APP at the beginning of its output. */
49 /* Also note that C style comments are always supported. */
50 const char line_comment_chars
[] = "#;*";
52 /* This array holds machine specific line separator characters. */
53 const char line_separator_chars
[] = "";
55 /* Chars that can be used to separate mant from exp in floating point nums. */
56 const char EXP_CHARS
[] = "eE";
58 /* Chars that mean this number is a floating point constant.
61 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
63 /* Machine-dependent command-line options. */
67 /* -mno-link-relax / -mlink-relax: generate (or not)
68 relocations for linker relaxation. */
69 bfd_boolean link_relax
;
71 /* -mno-warn-regname-label: do not output a warning that a label name
72 matches a register name. */
73 bfd_boolean warn_regname_label
;
76 static struct pru_opt_s pru_opt
= { TRUE
, TRUE
};
78 const char *md_shortopts
= "r";
82 OPTION_LINK_RELAX
= OPTION_MD_BASE
+ 1,
84 OPTION_NO_WARN_REGNAME_LABEL
,
87 struct option md_longopts
[] = {
88 { "mlink-relax", no_argument
, NULL
, OPTION_LINK_RELAX
},
89 { "mno-link-relax", no_argument
, NULL
, OPTION_NO_LINK_RELAX
},
90 { "mno-warn-regname-label", no_argument
, NULL
,
91 OPTION_NO_WARN_REGNAME_LABEL
},
92 { NULL
, no_argument
, NULL
, 0 }
95 size_t md_longopts_size
= sizeof (md_longopts
);
97 typedef struct pru_insn_reloc
99 /* Any expression in the instruction is parsed into this field,
100 which is passed to fix_new_exp () to generate a fixup. */
101 expressionS reloc_expression
;
103 /* The type of the relocation to be applied. */
104 bfd_reloc_code_real_type reloc_type
;
107 unsigned int reloc_pcrel
;
109 /* The next relocation to be applied to the instruction. */
110 struct pru_insn_reloc
*reloc_next
;
113 /* This struct is used to hold state when assembling instructions. */
114 typedef struct pru_insn_info
116 /* Assembled instruction. */
117 unsigned long insn_code
;
118 /* Used for assembling LDI32. */
119 unsigned long ldi32_imm32
;
121 /* Pointer to the relevant bit of the opcode table. */
122 const struct pru_opcode
*insn_pru_opcode
;
123 /* After parsing ptrs to the tokens in the instruction fill this array
124 it is terminated with a null pointer (hence the first +1).
125 The second +1 is because in some parts of the code the opcode
126 is not counted as a token, but still placed in this array. */
127 const char *insn_tokens
[PRU_MAX_INSN_TOKENS
+ 1 + 1];
129 /* This holds information used to generate fixups
130 and eventually relocations if it is not null. */
131 pru_insn_relocS
*insn_reloc
;
134 /* Opcode hash table. */
135 static struct hash_control
*pru_opcode_hash
= NULL
;
136 #define pru_opcode_lookup(NAME) \
137 ((struct pru_opcode *) hash_find (pru_opcode_hash, (NAME)))
139 /* Register hash table. */
140 static struct hash_control
*pru_reg_hash
= NULL
;
141 #define pru_reg_lookup(NAME) \
142 ((struct pru_reg *) hash_find (pru_reg_hash, (NAME)))
144 /* The known current alignment of the current section. */
145 static int pru_current_align
;
146 static segT pru_current_align_seg
;
148 static int pru_auto_align_on
= 1;
150 /* The last seen label in the current section. This is used to auto-align
151 labels preceding instructions. */
152 static symbolS
*pru_last_label
;
155 /** Utility routines. */
156 /* Function md_chars_to_number takes the sequence of
157 bytes in buf and returns the corresponding value
158 in an int. n must be 1, 2, 4 or 8. */
160 md_chars_to_number (char *buf
, int n
)
165 gas_assert (n
== 1 || n
== 2 || n
== 4 || n
== 8);
168 for (i
= 0; i
< n
; ++i
)
169 val
= val
| ((buf
[i
] & 0xff) << 8 * i
);
174 /* This function turns a C long int, short int or char
175 into the series of bytes that represent the number
176 on the target machine. */
178 md_number_to_chars (char *buf
, valueT val
, int n
)
180 gas_assert (n
== 1 || n
== 2 || n
== 4 || n
== 8);
181 number_to_chars_littleendian (buf
, val
, n
);
184 /* Turn a string in input_line_pointer into a floating point constant
185 of type TYPE, and store the appropriate bytes in *LITP. The number
186 of LITTLENUMS emitted is stored in *SIZEP. An error message is
187 returned, or NULL on OK. */
189 md_atof (int type
, char *litP
, int *sizeP
)
191 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
194 /* Return true if STR starts with PREFIX, which should be a string literal. */
195 #define strprefix(STR, PREFIX) \
196 (strncmp ((STR), PREFIX, strlen (PREFIX)) == 0)
198 /* nop fill pattern for text section. */
199 static char const nop
[4] = { 0xe0, 0xe0, 0xe0, 0x12 };
201 /* Handles all machine-dependent alignment needs. */
203 pru_align (int log_size
, const char *pfill
, symbolS
*label
)
206 long max_alignment
= 15;
208 /* The front end is prone to changing segments out from under us
209 temporarily when -g is in effect. */
210 int switched_seg_p
= (pru_current_align_seg
!= now_seg
);
213 if (align
> max_alignment
)
215 align
= max_alignment
;
216 as_bad (_("Alignment too large: %d assumed"), align
);
220 as_warn (_("Alignment negative: 0 assumed"));
226 if (subseg_text_p (now_seg
) && align
>= 2)
228 /* First, make sure we're on a four-byte boundary, in case
229 someone has been putting .byte values the text section. */
230 if (pru_current_align
< 2 || switched_seg_p
)
231 frag_align (2, 0, 0);
233 /* Now fill in the alignment pattern. */
235 frag_align_pattern (align
, pfill
, sizeof nop
, 0);
237 frag_align (align
, 0, 0);
240 frag_align (align
, 0, 0);
243 pru_current_align
= align
;
245 /* If the last label was in a different section we can't align it. */
246 if (label
!= NULL
&& !switched_seg_p
)
249 int label_seen
= FALSE
;
250 struct frag
*old_frag
;
254 gas_assert (S_GET_SEGMENT (label
) == now_seg
);
256 old_frag
= symbol_get_frag (label
);
257 old_value
= S_GET_VALUE (label
);
258 new_value
= (valueT
) frag_now_fix ();
260 /* It is possible to have more than one label at a particular
261 address, especially if debugging is enabled, so we must
262 take care to adjust all the labels at this address in this
263 fragment. To save time we search from the end of the symbol
264 list, backwards, since the symbols we are interested in are
265 almost certainly the ones that were most recently added.
266 Also to save time we stop searching once we have seen at least
267 one matching label, and we encounter a label that is no longer
268 in the target fragment. Note, this search is guaranteed to
269 find at least one match when sym == label, so no special case
270 code is necessary. */
271 for (sym
= symbol_lastP
; sym
!= NULL
; sym
= symbol_previous (sym
))
272 if (symbol_get_frag (sym
) == old_frag
273 && S_GET_VALUE (sym
) == old_value
)
276 symbol_set_frag (sym
, frag_now
);
277 S_SET_VALUE (sym
, new_value
);
279 else if (label_seen
&& symbol_get_frag (sym
) != old_frag
)
282 record_alignment (now_seg
, align
);
287 /** Support for self-check mode. */
289 /* Mode of the assembler. */
292 PRU_MODE_ASSEMBLE
, /* Ordinary operation. */
293 PRU_MODE_TEST
/* Hidden mode used for self testing. */
296 static PRU_MODE pru_mode
= PRU_MODE_ASSEMBLE
;
298 /* This function is used to in self-checking mode
299 to check the assembled instruction.
300 OPCODE should be the assembled opcode, and exp_opcode
301 the parsed string representing the expected opcode. */
304 pru_check_assembly (unsigned int opcode
, const char *exp_opcode
)
306 if (pru_mode
== PRU_MODE_TEST
)
308 if (exp_opcode
== NULL
)
309 as_bad (_("expecting opcode string in self test mode"));
310 else if (opcode
!= strtoul (exp_opcode
, NULL
, 16))
311 as_bad (_("assembly 0x%08x, expected %s"), opcode
, exp_opcode
);
316 /** Support for machine-dependent assembler directives. */
317 /* Handle the .align pseudo-op. This aligns to a power of two. It
318 also adjusts any current instruction label. We treat this the same
319 way the MIPS port does: .align 0 turns off auto alignment. */
321 s_pru_align (int ignore ATTRIBUTE_UNUSED
)
325 const char *pfill
= NULL
;
326 long max_alignment
= 15;
328 align
= get_absolute_expression ();
329 if (align
> max_alignment
)
331 align
= max_alignment
;
332 as_bad (_("Alignment too large: %d assumed"), align
);
336 as_warn (_("Alignment negative: 0 assumed"));
340 if (*input_line_pointer
== ',')
342 input_line_pointer
++;
343 fill
= get_absolute_expression ();
344 pfill
= (const char *) &fill
;
346 else if (subseg_text_p (now_seg
))
347 pfill
= (const char *) &nop
;
351 pru_last_label
= NULL
;
356 pru_auto_align_on
= 1;
357 pru_align (align
, pfill
, pru_last_label
);
358 pru_last_label
= NULL
;
361 pru_auto_align_on
= 0;
363 demand_empty_rest_of_line ();
366 /* Handle the .text pseudo-op. This is like the usual one, but it
367 clears the saved last label and resets known alignment. */
372 pru_last_label
= NULL
;
373 pru_current_align
= 0;
374 pru_current_align_seg
= now_seg
;
377 /* Handle the .data pseudo-op. This is like the usual one, but it
378 clears the saved last label and resets known alignment. */
383 pru_last_label
= NULL
;
384 pru_current_align
= 0;
385 pru_current_align_seg
= now_seg
;
388 /* Handle the .section pseudo-op. This is like the usual one, but it
389 clears the saved last label and resets known alignment. */
391 s_pru_section (int ignore
)
393 obj_elf_section (ignore
);
394 pru_last_label
= NULL
;
395 pru_current_align
= 0;
396 pru_current_align_seg
= now_seg
;
399 /* Explicitly unaligned cons. */
401 s_pru_ucons (int nbytes
)
404 hold
= pru_auto_align_on
;
405 pru_auto_align_on
= 0;
407 pru_auto_align_on
= hold
;
410 /* .set sets assembler options. */
412 s_pru_set (int equiv
)
414 char *save
= input_line_pointer
;
416 char delim
= get_symbol_name (&directive
);
417 char *endline
= input_line_pointer
;
419 (void) restore_line_pointer (delim
);
421 /* We only want to handle ".set XXX" if the
422 user has tried ".set XXX, YYY" they are not
423 trying a directive. This prevents
424 us from polluting the name space. */
426 if (is_end_of_line
[(unsigned char) *input_line_pointer
])
428 bfd_boolean done
= TRUE
;
431 if (!strcmp (directive
, "no_warn_regname_label"))
432 pru_opt
.warn_regname_label
= FALSE
;
439 demand_empty_rest_of_line ();
444 /* If we fall through to here, either we have ".set XXX, YYY"
445 or we have ".set XXX" where XXX is unknown or we have
447 input_line_pointer
= save
;
451 /* Machine-dependent assembler directives.
452 Format of each entry is:
453 { "directive", handler_func, param } */
454 const pseudo_typeS md_pseudo_table
[] = {
455 {"align", s_pru_align
, 0},
456 {"text", s_pru_text
, 0},
457 {"data", s_pru_data
, 0},
458 {"section", s_pru_section
, 0},
459 {"section.s", s_pru_section
, 0},
460 {"sect", s_pru_section
, 0},
461 {"sect.s", s_pru_section
, 0},
462 /* .dword and .half are included for compatibility with MIPS. */
465 /* PRU native word size is 4 bytes, so we override
466 the GAS default of 2. */
468 /* Explicitly unaligned directives. */
469 {"2byte", s_pru_ucons
, 2},
470 {"4byte", s_pru_ucons
, 4},
471 {"8byte", s_pru_ucons
, 8},
472 {"16byte", s_pru_ucons
, 16},
473 {"set", s_pru_set
, 0},
479 md_estimate_size_before_relax (fragS
*fragp ATTRIBUTE_UNUSED
,
480 asection
*seg ATTRIBUTE_UNUSED
)
487 md_convert_frag (bfd
*headers ATTRIBUTE_UNUSED
, segT segment ATTRIBUTE_UNUSED
,
488 fragS
*fragp ATTRIBUTE_UNUSED
)
495 relaxable_section (asection
*sec
)
497 return ((sec
->flags
& SEC_DEBUGGING
) == 0
498 && (sec
->flags
& SEC_CODE
) != 0
499 && (sec
->flags
& SEC_ALLOC
) != 0);
502 /* Does whatever the xtensa port does. */
504 pru_validate_fix_sub (fixS
*fix
)
506 segT add_symbol_segment
, sub_symbol_segment
;
508 /* The difference of two symbols should be resolved by the assembler when
509 linkrelax is not set. If the linker may relax the section containing
510 the symbols, then an Xtensa DIFF relocation must be generated so that
511 the linker knows to adjust the difference value. */
512 if (!linkrelax
|| fix
->fx_addsy
== NULL
)
515 /* Make sure both symbols are in the same segment, and that segment is
516 "normal" and relaxable. If the segment is not "normal", then the
517 fix is not valid. If the segment is not "relaxable", then the fix
518 should have been handled earlier. */
519 add_symbol_segment
= S_GET_SEGMENT (fix
->fx_addsy
);
520 if (! SEG_NORMAL (add_symbol_segment
)
521 || ! relaxable_section (add_symbol_segment
))
524 sub_symbol_segment
= S_GET_SEGMENT (fix
->fx_subsy
);
525 return (sub_symbol_segment
== add_symbol_segment
);
528 /* TC_FORCE_RELOCATION hook. */
530 /* If linkrelax is turned on, and the symbol to relocate
531 against is in a relaxable segment, don't compute the value -
532 generate a relocation instead. */
534 pru_force_relocation (fixS
*fix
)
536 if (linkrelax
&& fix
->fx_addsy
537 && relaxable_section (S_GET_SEGMENT (fix
->fx_addsy
)))
540 return generic_force_reloc (fix
);
545 /** Fixups and overflow checking. */
547 /* Check a fixup for overflow. */
548 static bfd_reloc_status_type
549 pru_check_overflow (valueT fixup
, reloc_howto_type
*howto
)
551 bfd_reloc_status_type ret
;
553 ret
= bfd_check_overflow (howto
->complain_on_overflow
,
556 bfd_get_reloc_size (howto
) * 8,
562 /* Emit diagnostic for fixup overflow. */
564 pru_diagnose_overflow (valueT fixup
, reloc_howto_type
*howto
,
565 fixS
*fixP
, valueT value
)
567 if (fixP
->fx_r_type
== BFD_RELOC_8
568 || fixP
->fx_r_type
== BFD_RELOC_16
569 || fixP
->fx_r_type
== BFD_RELOC_32
)
570 /* These relocs are against data, not instructions. */
571 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
572 _("immediate value 0x%x truncated to 0x%x"),
573 (unsigned int) fixup
,
574 (unsigned int) (~(~(valueT
) 0 << howto
->bitsize
) & fixup
));
577 /* What opcode is the instruction? This will determine
578 whether we check for overflow in immediate values
579 and what error message we get. */
580 const struct pru_opcode
*opcode
;
581 enum overflow_type overflow_msg_type
;
582 unsigned int range_min
;
583 unsigned int range_max
;
584 unsigned int address
;
585 gas_assert (fixP
->fx_size
== 4);
586 opcode
= pru_find_opcode (value
);
588 overflow_msg_type
= opcode
->overflow_msg
;
589 switch (overflow_msg_type
)
591 case call_target_overflow
:
593 = ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
) & 0xf0000000);
594 range_max
= range_min
+ 0x0fffffff;
595 address
= fixup
| range_min
;
597 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
598 _("call target address 0x%08x out of range 0x%08x to 0x%08x"),
599 address
, range_min
, range_max
);
601 case qbranch_target_overflow
:
602 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
603 _("quick branch offset %d out of range %d to %d"),
604 (int)fixup
, -((1<<9) * 4), (1 << 9) * 4);
606 case address_offset_overflow
:
607 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
608 _("%s offset %d out of range %d to %d"),
609 opcode
->name
, (int)fixup
, -32768, 32767);
611 case signed_immed16_overflow
:
612 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
613 _("immediate value %d out of range %d to %d"),
614 (int)fixup
, -32768, 32767);
616 case unsigned_immed32_overflow
:
617 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
618 _("immediate value %llu out of range %u to %lu"),
619 (unsigned long long)fixup
, 0, 0xfffffffflu
);
621 case unsigned_immed16_overflow
:
622 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
623 _("immediate value %u out of range %u to %u"),
624 (unsigned int)fixup
, 0, 65535);
626 case unsigned_immed5_overflow
:
627 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
628 _("immediate value %u out of range %u to %u"),
629 (unsigned int)fixup
, 0, 31);
632 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
633 _("overflow in immediate argument"));
639 /* Apply a fixup to the object file. */
641 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
643 unsigned char *where
;
644 valueT value
= *valP
;
647 /* Assert that the fixup is one we can handle. */
648 gas_assert (fixP
!= NULL
&& valP
!= NULL
649 && (fixP
->fx_r_type
== BFD_RELOC_8
650 || fixP
->fx_r_type
== BFD_RELOC_16
651 || fixP
->fx_r_type
== BFD_RELOC_32
652 || fixP
->fx_r_type
== BFD_RELOC_64
653 || fixP
->fx_r_type
== BFD_RELOC_PRU_LDI32
654 || fixP
->fx_r_type
== BFD_RELOC_PRU_U16
655 || fixP
->fx_r_type
== BFD_RELOC_PRU_U16_PMEMIMM
656 || fixP
->fx_r_type
== BFD_RELOC_PRU_S10_PCREL
657 || fixP
->fx_r_type
== BFD_RELOC_PRU_U8_PCREL
658 || fixP
->fx_r_type
== BFD_RELOC_PRU_32_PMEM
659 || fixP
->fx_r_type
== BFD_RELOC_PRU_16_PMEM
660 /* Add other relocs here as we generate them. */
663 if (fixP
->fx_r_type
== BFD_RELOC_64
)
665 /* We may reach here due to .8byte directives, but we never output
666 BFD_RELOC_64; it must be resolved. */
667 if (fixP
->fx_addsy
!= NULL
)
668 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
669 _("cannot create 64-bit relocation"));
672 md_number_to_chars (fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
,
679 /* gas_assert (had_errors () || !fixP->fx_subsy); */
681 /* In general, fix instructions with immediate
682 constants. But leave LDI32 for the linker,
683 which is prepared to shorten insns. */
684 if (fixP
->fx_addsy
== (symbolS
*) NULL
685 && fixP
->fx_r_type
!= BFD_RELOC_PRU_LDI32
)
688 else if (fixP
->fx_pcrel
)
690 segT s
= S_GET_SEGMENT (fixP
->fx_addsy
);
692 if (s
== seg
|| s
== absolute_section
)
694 /* Blindly copied from AVR, but I don't understand why
695 this is needed in the first place. Fail hard to catch
696 when this curious code snippet is utilized. */
697 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
698 _("unexpected PC relative expression"));
699 value
+= S_GET_VALUE (fixP
->fx_addsy
);
703 else if (linkrelax
&& fixP
->fx_subsy
)
705 /* For a subtraction relocation expression, generate one
706 of the DIFF relocs, with the value being the difference.
707 Note that a sym1 - sym2 expression is adjusted into a
708 section_start_sym + sym4_offset_from_section_start - sym1
709 expression. fixP->fx_addsy holds the section start symbol,
710 fixP->fx_offset holds sym2's offset, and fixP->fx_subsy
711 holds sym1. Calculate the current difference and write value,
712 but leave fx_offset as is - during relaxation,
713 fx_offset - value gives sym1's value. */
715 offsetT diffval
; /* valueT is unsigned, so use offsetT. */
717 diffval
= S_GET_VALUE (fixP
->fx_addsy
)
718 + fixP
->fx_offset
- S_GET_VALUE (fixP
->fx_subsy
);
720 switch (fixP
->fx_r_type
)
723 fixP
->fx_r_type
= BFD_RELOC_PRU_GNU_DIFF8
;
726 fixP
->fx_r_type
= BFD_RELOC_PRU_GNU_DIFF16
;
729 fixP
->fx_r_type
= BFD_RELOC_PRU_GNU_DIFF32
;
731 case BFD_RELOC_PRU_16_PMEM
:
732 fixP
->fx_r_type
= BFD_RELOC_PRU_GNU_DIFF16_PMEM
;
734 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
735 _("residual low bits in pmem diff relocation"));
738 case BFD_RELOC_PRU_32_PMEM
:
739 fixP
->fx_r_type
= BFD_RELOC_PRU_GNU_DIFF32_PMEM
;
741 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
742 _("residual low bits in pmem diff relocation"));
746 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
747 _("expression too complex"));
751 value
= *valP
= diffval
;
753 fixP
->fx_subsy
= NULL
;
755 /* We don't actually support subtracting a symbol. */
756 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
757 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("expression too complex"));
759 /* For the DIFF relocs, write the value into the object file while still
760 keeping fx_done FALSE, as both the difference (recorded in the object file)
761 and the sym offset (part of fixP) are needed at link relax time. */
762 where
= (unsigned char *) fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
763 switch (fixP
->fx_r_type
)
765 case BFD_RELOC_PRU_GNU_DIFF8
:
768 case BFD_RELOC_PRU_GNU_DIFF16
:
769 case BFD_RELOC_PRU_GNU_DIFF16_PMEM
:
770 bfd_putl16 ((bfd_vma
) value
, where
);
772 case BFD_RELOC_PRU_GNU_DIFF32
:
773 case BFD_RELOC_PRU_GNU_DIFF32_PMEM
:
774 bfd_putl32 ((bfd_vma
) value
, where
);
781 /* Fully resolved fixup. */
783 reloc_howto_type
*howto
784 = bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
787 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
788 _("relocation is not supported"));
791 valueT fixup
= value
;
795 /* Get the instruction or data to be fixed up. */
796 buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
797 insn
= md_chars_to_number (buf
, fixP
->fx_size
);
799 /* Check for overflow, emitting a diagnostic if necessary. */
800 if (pru_check_overflow (fixup
, howto
) != bfd_reloc_ok
)
801 pru_diagnose_overflow (fixup
, howto
, fixP
, insn
);
803 /* Apply the right shift. */
804 fixup
= ((offsetT
)fixup
) >> howto
->rightshift
;
806 /* Truncate the fixup to right size. */
807 n
= sizeof (fixup
) * 8 - howto
->bitsize
;
808 fixup
= (fixup
<< n
) >> n
;
810 /* Fix up the instruction. Non-contiguous bitfields need
812 if (fixP
->fx_r_type
== BFD_RELOC_PRU_LDI32
)
814 /* As the only 64-bit "insn", LDI32 needs special handling. */
815 uint32_t insn1
= insn
& 0xffffffff;
816 uint32_t insn2
= insn
>> 32;
817 SET_INSN_FIELD (IMM16
, insn1
, fixup
& 0xffff);
818 SET_INSN_FIELD (IMM16
, insn2
, fixup
>> 16);
820 md_number_to_chars (buf
, insn1
, 4);
821 md_number_to_chars (buf
+ 4, insn2
, 4);
825 if (fixP
->fx_r_type
== BFD_RELOC_PRU_S10_PCREL
)
826 SET_BROFF_URAW (insn
, fixup
);
828 insn
= (insn
& ~howto
->dst_mask
) | (fixup
<< howto
->bitpos
);
829 md_number_to_chars (buf
, insn
, fixP
->fx_size
);
836 if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
)
840 && !S_IS_DEFINED (fixP
->fx_addsy
) && !S_IS_WEAK (fixP
->fx_addsy
))
841 S_SET_WEAK (fixP
->fx_addsy
);
843 else if (fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
849 /** Instruction parsing support. */
851 /* Creates a new pru_insn_relocS and returns a pointer to it. */
852 static pru_insn_relocS
*
853 pru_insn_reloc_new (bfd_reloc_code_real_type reloc_type
, unsigned int pcrel
)
855 pru_insn_relocS
*retval
;
856 retval
= XNEW (pru_insn_relocS
);
859 as_bad (_("can't create relocation"));
863 /* Fill out the fields with default values. */
864 retval
->reloc_next
= NULL
;
865 retval
->reloc_type
= reloc_type
;
866 retval
->reloc_pcrel
= pcrel
;
870 /* Frees up memory previously allocated by pru_insn_reloc_new (). */
872 pru_insn_reloc_destroy (pru_insn_relocS
*reloc
)
874 pru_insn_relocS
*next
;
878 next
= reloc
->reloc_next
;
884 /* The various pru_assemble_* functions call this
885 function to generate an expression from a string representing an expression.
886 It then tries to evaluate the expression, and if it can, returns its value.
887 If not, it creates a new pru_insn_relocS and stores the expression and
888 reloc_type for future use. */
890 pru_assemble_expression (const char *exprstr
,
891 pru_insn_infoS
*insn
,
892 pru_insn_relocS
*prev_reloc
,
893 bfd_reloc_code_real_type reloc_type
,
897 pru_insn_relocS
*reloc
;
898 char *saved_line_ptr
;
899 unsigned short value
;
901 gas_assert (exprstr
!= NULL
);
902 gas_assert (insn
!= NULL
);
904 /* We use this blank keyword to distinguish register from
906 if (strstr (exprstr
, "%label") != NULL
)
908 exprstr
+= strlen ("%label") + 1;
911 /* Check for pmem relocation operator.
912 Change the relocation type and advance the ptr to the start of
913 the expression proper. */
914 if (strstr (exprstr
, "%pmem") != NULL
)
916 reloc_type
= BFD_RELOC_PRU_U16_PMEMIMM
;
917 exprstr
+= strlen ("%pmem") + 1;
920 /* We potentially have a relocation. */
921 reloc
= pru_insn_reloc_new (reloc_type
, pcrel
);
922 if (prev_reloc
!= NULL
)
923 prev_reloc
->reloc_next
= reloc
;
925 insn
->insn_reloc
= reloc
;
927 /* Parse the expression string. */
928 ep
= &reloc
->reloc_expression
;
929 saved_line_ptr
= input_line_pointer
;
930 input_line_pointer
= (char *) exprstr
;
934 if (*input_line_pointer
)
935 as_bad (_("trailing garbage after expression: %s"), input_line_pointer
);
936 input_line_pointer
= saved_line_ptr
;
939 if (ep
->X_op
== O_illegal
|| ep
->X_op
== O_absent
)
940 as_bad (_("expected expression, got %s"), exprstr
);
942 /* This is redundant as the fixup will put this into
943 the instruction, but it is included here so that
944 self-test mode (-r) works. */
946 if (pru_mode
== PRU_MODE_TEST
&& ep
->X_op
== O_constant
)
947 value
= ep
->X_add_number
;
949 return (unsigned long) value
;
952 /* Try to parse a non-relocatable expression. */
954 pru_assemble_noreloc_expression (const char *exprstr
)
957 char *saved_line_ptr
;
960 gas_assert (exprstr
!= NULL
);
962 saved_line_ptr
= input_line_pointer
;
963 input_line_pointer
= (char *) exprstr
;
967 if (*input_line_pointer
)
968 as_bad (_("trailing garbage after expression: %s"), input_line_pointer
);
969 input_line_pointer
= saved_line_ptr
;
972 if (exp
.X_op
!= O_constant
)
973 as_bad (_("expected constant expression, got %s"), exprstr
);
975 val
= exp
.X_add_number
;
980 /* Argument assemble functions.
981 All take an instruction argument string, and a pointer
982 to an instruction opcode. Upon return the insn_opcode
983 has the relevant fields filled in to represent the arg
984 string. The return value is NULL if successful, or
985 an error message if an error was detected. */
988 pru_assemble_arg_d (pru_insn_infoS
*insn_info
, const char *argstr
)
990 struct pru_reg
*dst
= pru_reg_lookup (argstr
);
993 as_bad (_("unknown register %s"), argstr
);
996 SET_INSN_FIELD (RD
, insn_info
->insn_code
, dst
->index
);
997 SET_INSN_FIELD (RDSEL
, insn_info
->insn_code
, dst
->regsel
);
1002 pru_assemble_arg_D (pru_insn_infoS
*insn_info
, const char *argstr
)
1004 struct pru_reg
*dst
;
1006 /* The leading & before an address register is optional. */
1010 dst
= pru_reg_lookup (argstr
);
1013 as_bad (_("unknown register %s"), argstr
);
1016 unsigned long rxb
= 0;
1018 switch (dst
->regsel
)
1020 case RSEL_31_0
: rxb
= 0; break; /* whole register defaults to .b0 */
1021 case RSEL_7_0
: rxb
= 0; break;
1022 case RSEL_15_8
: rxb
= 1; break;
1023 case RSEL_23_16
: rxb
= 2; break;
1024 case RSEL_31_24
: rxb
= 3; break;
1026 as_bad (_("data transfer register cannot be halfword"));
1029 SET_INSN_FIELD (RD
, insn_info
->insn_code
, dst
->index
);
1030 SET_INSN_FIELD (RDB
, insn_info
->insn_code
, rxb
);
1035 pru_assemble_arg_R (pru_insn_infoS
*insn_info
, const char *argstr
)
1037 struct pru_reg
*dst
= pru_reg_lookup (argstr
);
1040 as_bad (_("unknown register %s"), argstr
);
1043 if (dst
->regsel
!= RSEL_31_0
)
1045 as_bad (_("destination register must be full-word"));
1048 SET_INSN_FIELD (RD
, insn_info
->insn_code
, dst
->index
);
1049 SET_INSN_FIELD (RDSEL
, insn_info
->insn_code
, dst
->regsel
);
1054 pru_assemble_arg_s (pru_insn_infoS
*insn_info
, const char *argstr
)
1056 struct pru_reg
*src1
= pru_reg_lookup (argstr
);
1059 as_bad (_("unknown register %s"), argstr
);
1062 SET_INSN_FIELD (RS1
, insn_info
->insn_code
, src1
->index
);
1063 SET_INSN_FIELD (RS1SEL
, insn_info
->insn_code
, src1
->regsel
);
1068 pru_assemble_arg_S (pru_insn_infoS
*insn_info
, const char *argstr
)
1070 struct pru_reg
*src1
= pru_reg_lookup (argstr
);
1073 as_bad (_("unknown register %s"), argstr
);
1076 if (src1
->regsel
!= RSEL_31_0
)
1077 as_bad (_("cannot use partial register %s for addressing"), argstr
);
1078 SET_INSN_FIELD (RS1
, insn_info
->insn_code
, src1
->index
);
1083 pru_assemble_arg_b (pru_insn_infoS
*insn_info
, const char *argstr
)
1085 struct pru_reg
*src2
= pru_reg_lookup (argstr
);
1088 unsigned long imm8
= pru_assemble_noreloc_expression (argstr
);
1089 SET_INSN_FIELD (IMM8
, insn_info
->insn_code
, imm8
);
1090 SET_INSN_FIELD (IO
, insn_info
->insn_code
, 1);
1094 SET_INSN_FIELD (IO
, insn_info
->insn_code
, 0);
1095 SET_INSN_FIELD (RS2
, insn_info
->insn_code
, src2
->index
);
1096 SET_INSN_FIELD (RS2SEL
, insn_info
->insn_code
, src2
->regsel
);
1102 pru_assemble_arg_B (pru_insn_infoS
*insn_info
, const char *argstr
)
1104 struct pru_reg
*src2
= pru_reg_lookup (argstr
);
1108 imm8
= pru_assemble_noreloc_expression (argstr
);
1109 if (!imm8
|| imm8
> 0xff)
1110 as_bad (_("loop count constant %ld is out of range [1..%d]"),
1112 /* Note: HW expects the immediate loop count field
1113 to be one less than the actual loop count. */
1114 SET_INSN_FIELD (IMM8
, insn_info
->insn_code
, imm8
- 1);
1115 SET_INSN_FIELD (IO
, insn_info
->insn_code
, 1);
1119 SET_INSN_FIELD (IO
, insn_info
->insn_code
, 0);
1120 SET_INSN_FIELD (RS2
, insn_info
->insn_code
, src2
->index
);
1121 SET_INSN_FIELD (RS2SEL
, insn_info
->insn_code
, src2
->regsel
);
1126 pru_assemble_arg_i (pru_insn_infoS
*insn_info
, const char *argstr
)
1128 unsigned long imm32
;
1130 /* We must not generate PRU_LDI32 relocation if relaxation is disabled in
1131 GAS. Consider the following scenario: GAS relaxation is disabled, so
1132 DIFF* expressions are fixed and not emitted as relocations. Then if LD
1133 has relaxation enabled, it may shorten LDI32 but will not update
1134 accordingly the DIFF expressions. */
1135 if (pru_opt
.link_relax
)
1136 imm32
= pru_assemble_expression (argstr
, insn_info
,
1137 insn_info
->insn_reloc
,
1138 BFD_RELOC_PRU_LDI32
, 0);
1140 imm32
= pru_assemble_noreloc_expression (argstr
);
1142 /* QUIRK: LDI must clear IO bit high, even though it has immediate arg. */
1143 SET_INSN_FIELD (IO
, insn_info
->insn_code
, 0);
1144 SET_INSN_FIELD (IMM16
, insn_info
->insn_code
, imm32
& 0xffff);
1145 insn_info
->ldi32_imm32
= imm32
;
1149 pru_assemble_arg_j (pru_insn_infoS
*insn_info
, const char *argstr
)
1151 struct pru_reg
*src2
= pru_reg_lookup (argstr
);
1155 unsigned long imm16
= pru_assemble_expression (argstr
, insn_info
,
1156 insn_info
->insn_reloc
,
1157 BFD_RELOC_PRU_U16_PMEMIMM
,
1159 SET_INSN_FIELD (IMM16
, insn_info
->insn_code
, imm16
);
1160 SET_INSN_FIELD (IO
, insn_info
->insn_code
, 1);
1164 SET_INSN_FIELD (IO
, insn_info
->insn_code
, 0);
1165 SET_INSN_FIELD (RS2
, insn_info
->insn_code
, src2
->index
);
1166 SET_INSN_FIELD (RS2SEL
, insn_info
->insn_code
, src2
->regsel
);
1171 pru_assemble_arg_W (pru_insn_infoS
*insn_info
, const char *argstr
)
1173 unsigned long imm16
= pru_assemble_expression (argstr
, insn_info
,
1174 insn_info
->insn_reloc
,
1175 BFD_RELOC_PRU_U16
, 0);
1176 /* QUIRK: LDI must clear IO bit high, even though it has immediate arg. */
1177 SET_INSN_FIELD (IO
, insn_info
->insn_code
, 0);
1178 SET_INSN_FIELD (IMM16
, insn_info
->insn_code
, imm16
);
1182 pru_assemble_arg_o (pru_insn_infoS
*insn_info
, const char *argstr
)
1184 unsigned long imm10
= pru_assemble_expression (argstr
, insn_info
,
1185 insn_info
->insn_reloc
,
1186 BFD_RELOC_PRU_S10_PCREL
, 1);
1187 SET_BROFF_URAW (insn_info
->insn_code
, imm10
);
1191 pru_assemble_arg_O (pru_insn_infoS
*insn_info
, const char *argstr
)
1193 unsigned long imm8
= pru_assemble_expression (argstr
, insn_info
,
1194 insn_info
->insn_reloc
,
1195 BFD_RELOC_PRU_U8_PCREL
, 1);
1196 SET_INSN_FIELD (LOOP_JMPOFFS
, insn_info
->insn_code
, imm8
);
1200 pru_assemble_arg_l (pru_insn_infoS
*insn_info
, const char *argstr
)
1202 unsigned long burstlen
= 0;
1203 struct pru_reg
*blreg
= pru_reg_lookup (argstr
);
1207 burstlen
= pru_assemble_noreloc_expression (argstr
);
1208 if (!burstlen
|| burstlen
> LSSBBO_BYTECOUNT_R0_BITS7_0
)
1209 as_bad (_("byte count constant %ld is out of range [1..%d]"),
1210 burstlen
, LSSBBO_BYTECOUNT_R0_BITS7_0
);
1215 if (blreg
->index
!= 0)
1216 as_bad (_("only r0 can be used as byte count register"));
1217 else if (blreg
->regsel
> RSEL_31_24
)
1218 as_bad (_("only r0.bX byte fields of r0 can be used as byte count"));
1220 burstlen
= LSSBBO_BYTECOUNT_R0_BITS7_0
+ blreg
->regsel
;
1222 SET_BURSTLEN (insn_info
->insn_code
, burstlen
);
1226 pru_assemble_arg_n (pru_insn_infoS
*insn_info
, const char *argstr
)
1228 unsigned long burstlen
= 0;
1229 struct pru_reg
*blreg
= pru_reg_lookup (argstr
);
1233 burstlen
= pru_assemble_noreloc_expression (argstr
);
1234 if (!burstlen
|| burstlen
> LSSBBO_BYTECOUNT_R0_BITS7_0
)
1235 as_bad (_("byte count constant %ld is out of range [1..%d]"),
1236 burstlen
, LSSBBO_BYTECOUNT_R0_BITS7_0
);
1241 if (blreg
->index
!= 0)
1242 as_bad (_("only r0 can be used as byte count register"));
1243 else if (blreg
->regsel
> RSEL_31_24
)
1244 as_bad (_("only r0.bX byte fields of r0 can be used as byte count"));
1246 burstlen
= LSSBBO_BYTECOUNT_R0_BITS7_0
+ blreg
->regsel
;
1248 SET_INSN_FIELD (XFR_LENGTH
, insn_info
->insn_code
, burstlen
);
1252 pru_assemble_arg_c (pru_insn_infoS
*insn_info
, const char *argstr
)
1254 unsigned long cb
= pru_assemble_noreloc_expression (argstr
);
1257 as_bad (_("invalid constant table offset %ld"), cb
);
1259 SET_INSN_FIELD (CB
, insn_info
->insn_code
, cb
);
1263 pru_assemble_arg_w (pru_insn_infoS
*insn_info
, const char *argstr
)
1265 unsigned long wk
= pru_assemble_noreloc_expression (argstr
);
1267 if (wk
!= 0 && wk
!= 1)
1268 as_bad (_("invalid WakeOnStatus %ld"), wk
);
1270 SET_INSN_FIELD (WAKEONSTATUS
, insn_info
->insn_code
, wk
);
1274 pru_assemble_arg_x (pru_insn_infoS
*insn_info
, const char *argstr
)
1276 unsigned long wba
= pru_assemble_noreloc_expression (argstr
);
1279 as_bad (_("invalid XFR WideBus Address %ld"), wba
);
1281 SET_INSN_FIELD (XFR_WBA
, insn_info
->insn_code
, wba
);
1284 /* The function consume_arg takes a pointer into a string
1285 of instruction tokens (args) and a pointer into a string
1286 representing the expected sequence of tokens and separators.
1287 It checks whether the first argument in argstr is of the
1288 expected type, throwing an error if it is not, and returns
1289 the pointer argstr. */
1291 pru_consume_arg (char *argstr
, const char *parsestr
)
1300 if (strprefix (argstr
, "%pmem") || strprefix (argstr
, "%label"))
1302 /* We zap the parentheses because we don't want them confused
1304 temp
= strchr (argstr
, '(');
1307 temp
= strchr (argstr
, ')');
1312 as_bad (_("badly formed expression near %s"), argstr
);
1321 /* Only 'j' really requires %label for distinguishing registers
1322 from labels, but we include 'o' and 'O' here to avoid
1323 confusing assembler programmers. Thus for completeness all
1324 jump operands can be prefixed with %label. */
1325 if (strprefix (argstr
, "%label"))
1327 /* We zap the parentheses because we don't want them confused
1329 temp
= strchr (argstr
, '(');
1332 temp
= strchr (argstr
, ')');
1337 as_bad (_("badly formed expression near %s"), argstr
);
1355 /* We can't have %pmem here. */
1357 as_bad (_("badly formed expression near %s"), argstr
);
1360 BAD_CASE (*parsestr
);
1367 /* The function consume_separator takes a pointer into a string
1368 of instruction tokens (args) and a pointer into a string representing
1369 the expected sequence of tokens and separators. It finds the first
1370 instance of the character pointed to by separator in argstr, and
1371 returns a pointer to the next element of argstr, which is the
1372 following token in the sequence. */
1374 pru_consume_separator (char *argstr
, const char *separator
)
1378 p
= strchr (argstr
, *separator
);
1383 as_bad (_("expecting %c near %s"), *separator
, argstr
);
1388 /* The principal argument parsing function which takes a string argstr
1389 representing the instruction arguments for insn, and extracts the argument
1390 tokens matching parsestr into parsed_args. */
1392 pru_parse_args (pru_insn_infoS
*insn ATTRIBUTE_UNUSED
, char *argstr
,
1393 const char *parsestr
, char **parsed_args
)
1400 bfd_boolean terminate
= FALSE
;
1402 /* This rest of this function is it too fragile and it mostly works,
1403 therefore special case this one. */
1404 if (*parsestr
== 0 && argstr
!= 0)
1406 as_bad (_("too many arguments"));
1407 parsed_args
[0] = NULL
;
1411 while (p
!= NULL
&& !terminate
&& i
< PRU_MAX_INSN_TOKENS
)
1413 parsed_args
[i
] = pru_consume_arg (p
, parsestr
);
1415 if (*parsestr
!= '\0')
1417 p
= pru_consume_separator (p
, parsestr
);
1422 /* Check that the argument string has no trailing arguments. */
1423 /* If we've got a %pmem relocation, we've zapped the parens with
1425 if (strprefix (p
, "%pmem") || strprefix (p
, "%label"))
1426 end
= strpbrk (p
, ",");
1428 end
= strpbrk (p
, " ,");
1431 as_bad (_("too many arguments"));
1434 if (*parsestr
== '\0' || (p
!= NULL
&& *p
== '\0'))
1439 parsed_args
[i
] = NULL
;
1441 /* There are no instructions with optional arguments; complain. */
1442 if (*parsestr
!= '\0')
1443 as_bad (_("missing argument"));
1447 /** Assembler output support. */
1449 /* Output a normal instruction. */
1451 output_insn (pru_insn_infoS
*insn
)
1454 pru_insn_relocS
*reloc
;
1457 /* This allocates enough space for the instruction
1458 and puts it in the current frag. */
1459 md_number_to_chars (f
, insn
->insn_code
, 4);
1460 /* Emit debug info. */
1461 dwarf2_emit_insn (4);
1462 /* Create any fixups to be acted on later. */
1463 for (reloc
= insn
->insn_reloc
; reloc
!= NULL
; reloc
= reloc
->reloc_next
)
1464 fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 4,
1465 &reloc
->reloc_expression
, reloc
->reloc_pcrel
,
1469 /* Output two LDI instructions from LDI32 macro */
1471 output_insn_ldi32 (pru_insn_infoS
*insn
)
1474 pru_insn_relocS
*reloc
;
1475 unsigned long insn2
;
1478 md_number_to_chars (f
, insn
->insn_code
, 4);
1480 insn2
= insn
->insn_code
;
1481 SET_INSN_FIELD (IMM16
, insn2
, insn
->ldi32_imm32
>> 16);
1482 SET_INSN_FIELD (RDSEL
, insn2
, RSEL_31_16
);
1483 md_number_to_chars (f
+ 4, insn2
, 4);
1485 /* Emit debug info. */
1486 dwarf2_emit_insn (8);
1488 /* Create any fixups to be acted on later. */
1489 for (reloc
= insn
->insn_reloc
; reloc
!= NULL
; reloc
= reloc
->reloc_next
)
1490 fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, 4,
1491 &reloc
->reloc_expression
, reloc
->reloc_pcrel
,
1496 /** External interfaces. */
1498 /* The following functions are called by machine-independent parts of
1501 md_parse_option (int c
, const char *arg ATTRIBUTE_UNUSED
)
1506 /* Hidden option for self-test mode. */
1507 pru_mode
= PRU_MODE_TEST
;
1509 case OPTION_LINK_RELAX
:
1510 pru_opt
.link_relax
= TRUE
;
1512 case OPTION_NO_LINK_RELAX
:
1513 pru_opt
.link_relax
= FALSE
;
1515 case OPTION_NO_WARN_REGNAME_LABEL
:
1516 pru_opt
.warn_regname_label
= FALSE
;
1527 pru_target_format (void)
1532 /* Machine-dependent usage message. */
1534 md_show_usage (FILE *stream
)
1538 " -mlink-relax generate relocations for linker relaxation (default).\n"
1539 " -mno-link-relax don't generate relocations for linker relaxation.\n"
1544 /* This function is called once, at assembler startup time.
1545 It should set up all the tables, etc. that the MD part of the
1546 assembler will need. */
1551 const char *inserted
;
1553 /* Create and fill a hashtable for the PRU opcodes, registers and
1555 pru_opcode_hash
= hash_new ();
1556 pru_reg_hash
= hash_new ();
1558 for (i
= 0; i
< NUMOPCODES
; ++i
)
1561 = hash_insert (pru_opcode_hash
, pru_opcodes
[i
].name
,
1562 (PTR
) & pru_opcodes
[i
]);
1563 if (inserted
!= NULL
)
1565 fprintf (stderr
, _("internal error: can't hash `%s': %s\n"),
1566 pru_opcodes
[i
].name
, inserted
);
1567 /* Probably a memory allocation problem? Give up now. */
1568 as_fatal (_("Broken assembler. No assembly attempted."));
1572 for (i
= 0; i
< pru_num_regs
; ++i
)
1575 = hash_insert (pru_reg_hash
, pru_regs
[i
].name
,
1576 (PTR
) & pru_regs
[i
]);
1577 if (inserted
!= NULL
)
1579 fprintf (stderr
, _("internal error: can't hash `%s': %s\n"),
1580 pru_regs
[i
].name
, inserted
);
1581 /* Probably a memory allocation problem? Give up now. */
1582 as_fatal (_("Broken assembler. No assembly attempted."));
1587 linkrelax
= pru_opt
.link_relax
;
1588 /* Initialize the alignment data. */
1589 pru_current_align_seg
= now_seg
;
1590 pru_last_label
= NULL
;
1591 pru_current_align
= 0;
1595 /* Assembles a single line of PRU assembly language. */
1597 md_assemble (char *op_str
)
1600 char *op_strdup
= NULL
;
1601 pru_insn_infoS thisinsn
;
1602 pru_insn_infoS
*insn
= &thisinsn
;
1604 /* Make sure we are aligned on a 4-byte boundary. */
1605 if (pru_current_align
< 2)
1606 pru_align (2, NULL
, pru_last_label
);
1607 else if (pru_current_align
> 2)
1608 pru_current_align
= 2;
1609 pru_last_label
= NULL
;
1611 /* We don't want to clobber to op_str
1612 because we want to be able to use it in messages. */
1613 op_strdup
= strdup (op_str
);
1614 insn
->insn_tokens
[0] = strtok (op_strdup
, " ");
1615 argstr
= strtok (NULL
, "");
1617 /* Assemble the opcode. */
1618 insn
->insn_pru_opcode
= pru_opcode_lookup (insn
->insn_tokens
[0]);
1619 insn
->insn_reloc
= NULL
;
1621 if (insn
->insn_pru_opcode
!= NULL
)
1623 const char *argsfmt
= insn
->insn_pru_opcode
->args
;
1624 const char **argtk
= &insn
->insn_tokens
[1];
1627 /* Set the opcode for the instruction. */
1628 insn
->insn_code
= insn
->insn_pru_opcode
->match
;
1630 if (pru_mode
== PRU_MODE_TEST
)
1632 /* Add the "expected" instruction parameter used for validation. */
1633 argsfmt
= malloc (strlen (argsfmt
) + 3);
1634 sprintf ((char *)argsfmt
, "%s,E", insn
->insn_pru_opcode
->args
);
1636 pru_parse_args (insn
, argstr
, argsfmt
,
1637 (char **) &insn
->insn_tokens
[1]);
1639 for (argp
= argsfmt
; !had_errors () && *argp
&& *argtk
; ++argp
)
1641 gas_assert (argtk
<= &insn
->insn_tokens
[PRU_MAX_INSN_TOKENS
]);
1649 pru_assemble_arg_d (insn
, *argtk
++);
1652 pru_assemble_arg_D (insn
, *argtk
++);
1655 pru_assemble_arg_R (insn
, *argtk
++);
1658 pru_assemble_arg_s (insn
, *argtk
++);
1661 pru_assemble_arg_S (insn
, *argtk
++);
1664 pru_assemble_arg_b (insn
, *argtk
++);
1667 pru_assemble_arg_B (insn
, *argtk
++);
1670 pru_assemble_arg_i (insn
, *argtk
++);
1673 pru_assemble_arg_j (insn
, *argtk
++);
1676 pru_assemble_arg_W (insn
, *argtk
++);
1679 pru_assemble_arg_o (insn
, *argtk
++);
1682 pru_assemble_arg_O (insn
, *argtk
++);
1685 pru_assemble_arg_l (insn
, *argtk
++);
1688 pru_assemble_arg_n (insn
, *argtk
++);
1691 pru_assemble_arg_c (insn
, *argtk
++);
1694 pru_assemble_arg_w (insn
, *argtk
++);
1697 pru_assemble_arg_x (insn
, *argtk
++);
1701 pru_check_assembly (insn
->insn_code
, *argtk
++);
1709 if (*argp
&& !had_errors ())
1710 as_bad (_("missing argument"));
1714 if (insn
->insn_pru_opcode
->pinfo
& PRU_INSN_LDI32
)
1716 output_insn_ldi32 (insn
);
1724 if (pru_mode
== PRU_MODE_TEST
)
1725 free ((char *)argsfmt
);
1728 /* Unrecognised instruction - error. */
1729 as_bad (_("unrecognised instruction %s"), insn
->insn_tokens
[0]);
1731 /* Don't leak memory. */
1732 pru_insn_reloc_destroy (insn
->insn_reloc
);
1736 /* Round up section size. */
1738 md_section_align (asection
*seg
, valueT addr
)
1740 int align
= bfd_get_section_alignment (stdoutput
, seg
);
1741 return ((addr
+ (1 << align
) - 1) & (-((valueT
) 1 << align
)));
1744 /* Implement tc_fix_adjustable. */
1746 pru_fix_adjustable (fixS
*fixp
)
1748 if (fixp
->fx_addsy
== NULL
)
1751 /* Prevent all adjustments to global symbols. */
1752 if (OUTPUT_FLAVOR
== bfd_target_elf_flavour
1753 && (S_IS_EXTERNAL (fixp
->fx_addsy
) || S_IS_WEAK (fixp
->fx_addsy
)))
1756 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
1757 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
1760 /* Preserve relocations against symbols with function type. */
1761 if (symbol_get_bfdsym (fixp
->fx_addsy
)->flags
& BSF_FUNCTION
)
1767 /* The function tc_gen_reloc creates a relocation structure for the
1768 fixup fixp, and returns a pointer to it. This structure is passed
1769 to bfd_install_relocation so that it can be written to the object
1770 file for linking. */
1772 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixp
)
1774 arelent
*reloc
= XNEW (arelent
);
1775 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
1776 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1778 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1779 reloc
->addend
= fixp
->fx_offset
; /* fixp->fx_addnumber; */
1781 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1782 if (reloc
->howto
== NULL
)
1784 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1785 _("can't represent relocation type %s"),
1786 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1788 /* Set howto to a garbage value so that we can keep going. */
1789 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
1790 gas_assert (reloc
->howto
!= NULL
);
1796 md_pcrel_from (fixS
*fixP ATTRIBUTE_UNUSED
)
1798 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1801 /* Called just before the assembler exits. */
1805 hash_die (pru_opcode_hash
);
1806 hash_die (pru_reg_hash
);
1810 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
1815 /* Implement tc_frob_label. */
1817 pru_frob_label (symbolS
*lab
)
1819 /* Emit dwarf information. */
1820 dwarf2_emit_label (lab
);
1822 /* Update the label's address with the current output pointer. */
1823 symbol_set_frag (lab
, frag_now
);
1824 S_SET_VALUE (lab
, (valueT
) frag_now_fix ());
1826 /* Record this label for future adjustment after we find out what
1827 kind of data it references, and the required alignment therewith. */
1828 pru_last_label
= lab
;
1830 if (pru_opt
.warn_regname_label
&& pru_reg_lookup (S_GET_NAME (lab
)))
1831 as_warn (_("Label \"%s\" matches a CPU register name"), S_GET_NAME (lab
));
1834 static inline char *
1835 skip_space (char *s
)
1837 while (*s
== ' ' || *s
== '\t')
1842 /* Parse special CONS expression: pmem (expression). Idea from AVR.
1844 Used to catch and mark code (program memory) in constant expression
1845 relocations. Return non-zero for program memory. */
1848 pru_parse_cons_expression (expressionS
*exp
, int nbytes
)
1850 int is_pmem
= FALSE
;
1853 tmp
= input_line_pointer
= skip_space (input_line_pointer
);
1855 if (nbytes
== 4 || nbytes
== 2)
1857 const char *pmem_str
= "%pmem";
1858 int len
= strlen (pmem_str
);
1860 if (strncasecmp (input_line_pointer
, pmem_str
, len
) == 0)
1862 input_line_pointer
= skip_space (input_line_pointer
+ len
);
1864 if (*input_line_pointer
== '(')
1866 input_line_pointer
= skip_space (input_line_pointer
+ 1);
1870 if (*input_line_pointer
== ')')
1871 ++input_line_pointer
;
1874 as_bad (_("`)' required"));
1881 input_line_pointer
= tmp
;
1890 /* Implement TC_CONS_FIX_NEW. */
1892 pru_cons_fix_new (fragS
*frag
, int where
, unsigned int nbytes
,
1893 expressionS
*exp
, const int is_pmem
)
1895 bfd_reloc_code_real_type r
;
1897 switch (nbytes
| (!!is_pmem
<< 8))
1899 case 1 | (0 << 8): r
= BFD_RELOC_8
; break;
1900 case 2 | (0 << 8): r
= BFD_RELOC_16
; break;
1901 case 4 | (0 << 8): r
= BFD_RELOC_32
; break;
1902 case 8 | (0 << 8): r
= BFD_RELOC_64
; break;
1903 case 2 | (1 << 8): r
= BFD_RELOC_PRU_16_PMEM
; break;
1904 case 4 | (1 << 8): r
= BFD_RELOC_PRU_32_PMEM
; break;
1906 as_bad (_("illegal %s relocation size: %d"),
1907 is_pmem
? "text" : "data", nbytes
);
1911 fix_new_exp (frag
, where
, (int) nbytes
, exp
, 0, r
);
1914 /* Implement tc_regname_to_dw2regnum, to convert REGNAME to a DWARF-2
1917 pru_regname_to_dw2regnum (char *regname
)
1919 struct pru_reg
*r
= pru_reg_lookup (regname
);
1925 /* Implement tc_cfi_frame_initial_instructions, to initialize the DWARF-2
1926 unwind information for this procedure. */
1928 pru_frame_initial_instructions (void)
1930 const unsigned fp_regno
= 4;
1931 cfi_add_CFA_def_cfa (fp_regno
, 0);
1935 pru_allow_local_subtract (expressionS
* left
,
1936 expressionS
* right
,
1939 /* If we are not in relaxation mode, subtraction is OK. */
1943 /* If the symbols are not in a code section then they are OK. */
1944 if ((section
->flags
& SEC_CODE
) == 0)
1947 if (left
->X_add_symbol
== right
->X_add_symbol
)
1950 /* We have to assume that there may be instructions between the
1951 two symbols and that relaxation may increase the distance between