]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-pru.c
Use bool in gas
[thirdparty/binutils-gdb.git] / gas / config / tc-pru.c
CommitLineData
93f11b16 1/* TI PRU assembler.
250d07de 2 Copyright (C) 2014-2021 Free Software Foundation, Inc.
93f11b16
DD
3 Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
4 Based on tc-nios2.c
5
6 This file is part of GAS, the GNU Assembler.
7
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)
11 any later version.
12
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.
17
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
21 02110-1301, USA. */
22
23#include "as.h"
3dfb1b6d 24#include <stdint.h>
93f11b16
DD
25#include "opcode/pru.h"
26#include "elf/pru.h"
27#include "tc-pru.h"
28#include "bfd.h"
29#include "dwarf2dbg.h"
30#include "subsegs.h"
31#include "safe-ctype.h"
32#include "dw2gencfi.h"
33
34#ifndef OBJ_ELF
35/* We are not supporting any other target so we throw a compile time error. */
36 #error "OBJ_ELF not defined"
37#endif
38
39/* This array holds the chars that always start a comment. If the
40 pre-processor is disabled, these aren't very useful. */
41const char comment_chars[] = "#;";
42
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. */
50const char line_comment_chars[] = "#;*";
51
52/* This array holds machine specific line separator characters. */
53const char line_separator_chars[] = "";
54
55/* Chars that can be used to separate mant from exp in floating point nums. */
56const char EXP_CHARS[] = "eE";
57
58/* Chars that mean this number is a floating point constant.
59 As in 0f12.456
60 or 0d1.2345e12 */
61const char FLT_CHARS[] = "rRsSfFdDxXpP";
62
63/* Machine-dependent command-line options. */
64
65struct pru_opt_s
66{
67 /* -mno-link-relax / -mlink-relax: generate (or not)
68 relocations for linker relaxation. */
5b7c81bd 69 bool link_relax;
93f11b16
DD
70
71 /* -mno-warn-regname-label: do not output a warning that a label name
72 matches a register name. */
5b7c81bd 73 bool warn_regname_label;
93f11b16
DD
74};
75
5b7c81bd 76static struct pru_opt_s pru_opt = { true, true };
93f11b16
DD
77
78const char *md_shortopts = "r";
79
80enum options
81{
82 OPTION_LINK_RELAX = OPTION_MD_BASE + 1,
83 OPTION_NO_LINK_RELAX,
84 OPTION_NO_WARN_REGNAME_LABEL,
85};
86
87struct 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 }
93};
94
95size_t md_longopts_size = sizeof (md_longopts);
96
97typedef struct pru_insn_reloc
98{
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;
102
103 /* The type of the relocation to be applied. */
104 bfd_reloc_code_real_type reloc_type;
105
106 /* PC-relative. */
107 unsigned int reloc_pcrel;
108
109 /* The next relocation to be applied to the instruction. */
110 struct pru_insn_reloc *reloc_next;
111} pru_insn_relocS;
112
113/* This struct is used to hold state when assembling instructions. */
114typedef struct pru_insn_info
115{
116 /* Assembled instruction. */
117 unsigned long insn_code;
118 /* Used for assembling LDI32. */
119 unsigned long ldi32_imm32;
120
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];
128
129 /* This holds information used to generate fixups
130 and eventually relocations if it is not null. */
131 pru_insn_relocS *insn_reloc;
132} pru_insn_infoS;
133
134/* Opcode hash table. */
629310ab 135static htab_t pru_opcode_hash = NULL;
93f11b16 136#define pru_opcode_lookup(NAME) \
629310ab 137 ((struct pru_opcode *) str_hash_find (pru_opcode_hash, (NAME)))
93f11b16
DD
138
139/* Register hash table. */
629310ab 140static htab_t pru_reg_hash = NULL;
93f11b16 141#define pru_reg_lookup(NAME) \
629310ab 142 ((struct pru_reg *) str_hash_find (pru_reg_hash, (NAME)))
93f11b16
DD
143
144/* The known current alignment of the current section. */
145static int pru_current_align;
146static segT pru_current_align_seg;
147
148static int pru_auto_align_on = 1;
149
150/* The last seen label in the current section. This is used to auto-align
33eaf5de 151 labels preceding instructions. */
93f11b16
DD
152static symbolS *pru_last_label;
153
154\f
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. */
159static uint64_t
160md_chars_to_number (char *buf, int n)
161{
162 int i;
163 uint64_t val;
164
165 gas_assert (n == 1 || n == 2 || n == 4 || n == 8);
166
167 val = 0;
168 for (i = 0; i < n; ++i)
169 val = val | ((buf[i] & 0xff) << 8 * i);
170 return val;
171}
172
173
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. */
177void
ddb2c6fd 178md_number_to_chars (char *buf, valueT val, int n)
93f11b16
DD
179{
180 gas_assert (n == 1 || n == 2 || n == 4 || n == 8);
181 number_to_chars_littleendian (buf, val, n);
182}
183
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. */
188const char *
189md_atof (int type, char *litP, int *sizeP)
190{
5b7c81bd 191 return ieee_md_atof (type, litP, sizeP, false);
93f11b16
DD
192}
193
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)
197
198/* nop fill pattern for text section. */
199static char const nop[4] = { 0xe0, 0xe0, 0xe0, 0x12 };
200
201/* Handles all machine-dependent alignment needs. */
202static void
203pru_align (int log_size, const char *pfill, symbolS *label)
204{
205 int align;
206 long max_alignment = 15;
207
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);
211
212 align = log_size;
213 if (align > max_alignment)
214 {
215 align = max_alignment;
216 as_bad (_("Alignment too large: %d assumed"), align);
217 }
218 else if (align < 0)
219 {
220 as_warn (_("Alignment negative: 0 assumed"));
221 align = 0;
222 }
223
224 if (align != 0)
225 {
226 if (subseg_text_p (now_seg) && align >= 2)
227 {
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);
232
233 /* Now fill in the alignment pattern. */
234 if (pfill != NULL)
235 frag_align_pattern (align, pfill, sizeof nop, 0);
236 else
237 frag_align (align, 0, 0);
238 }
239 else
240 frag_align (align, 0, 0);
241
242 if (!switched_seg_p)
243 pru_current_align = align;
244
245 /* If the last label was in a different section we can't align it. */
246 if (label != NULL && !switched_seg_p)
247 {
248 symbolS *sym;
5b7c81bd 249 int label_seen = false;
93f11b16
DD
250 struct frag *old_frag;
251 valueT old_value;
252 valueT new_value;
253
254 gas_assert (S_GET_SEGMENT (label) == now_seg);
255
256 old_frag = symbol_get_frag (label);
257 old_value = S_GET_VALUE (label);
258 new_value = (valueT) frag_now_fix ();
259
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)
274 {
5b7c81bd 275 label_seen = true;
93f11b16
DD
276 symbol_set_frag (sym, frag_now);
277 S_SET_VALUE (sym, new_value);
278 }
279 else if (label_seen && symbol_get_frag (sym) != old_frag)
280 break;
281 }
282 record_alignment (now_seg, align);
283 }
284}
285
286\f
287/** Support for self-check mode. */
288
289/* Mode of the assembler. */
290typedef enum
291{
292 PRU_MODE_ASSEMBLE, /* Ordinary operation. */
293 PRU_MODE_TEST /* Hidden mode used for self testing. */
294} PRU_MODE;
295
296static PRU_MODE pru_mode = PRU_MODE_ASSEMBLE;
297
298/* This function is used to in self-checking mode
0bae9e9e
NC
299 to check the assembled instruction.
300 OPCODE should be the assembled opcode, and exp_opcode
93f11b16 301 the parsed string representing the expected opcode. */
0bae9e9e 302
93f11b16
DD
303static void
304pru_check_assembly (unsigned int opcode, const char *exp_opcode)
305{
306 if (pru_mode == PRU_MODE_TEST)
307 {
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);
312 }
313}
314
315\f
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. */
320static void
321s_pru_align (int ignore ATTRIBUTE_UNUSED)
322{
323 int align;
324 char fill;
325 const char *pfill = NULL;
326 long max_alignment = 15;
327
328 align = get_absolute_expression ();
329 if (align > max_alignment)
330 {
331 align = max_alignment;
332 as_bad (_("Alignment too large: %d assumed"), align);
333 }
334 else if (align < 0)
335 {
336 as_warn (_("Alignment negative: 0 assumed"));
337 align = 0;
338 }
339
340 if (*input_line_pointer == ',')
341 {
342 input_line_pointer++;
343 fill = get_absolute_expression ();
344 pfill = (const char *) &fill;
345 }
346 else if (subseg_text_p (now_seg))
347 pfill = (const char *) &nop;
348 else
349 {
350 pfill = NULL;
351 pru_last_label = NULL;
352 }
353
354 if (align != 0)
355 {
356 pru_auto_align_on = 1;
357 pru_align (align, pfill, pru_last_label);
358 pru_last_label = NULL;
359 }
360 else
361 pru_auto_align_on = 0;
362
363 demand_empty_rest_of_line ();
364}
365
366/* Handle the .text pseudo-op. This is like the usual one, but it
367 clears the saved last label and resets known alignment. */
368static void
369s_pru_text (int i)
370{
371 s_text (i);
372 pru_last_label = NULL;
373 pru_current_align = 0;
374 pru_current_align_seg = now_seg;
375}
376
377/* Handle the .data pseudo-op. This is like the usual one, but it
378 clears the saved last label and resets known alignment. */
379static void
380s_pru_data (int i)
381{
382 s_data (i);
383 pru_last_label = NULL;
384 pru_current_align = 0;
385 pru_current_align_seg = now_seg;
386}
387
388/* Handle the .section pseudo-op. This is like the usual one, but it
389 clears the saved last label and resets known alignment. */
390static void
391s_pru_section (int ignore)
392{
393 obj_elf_section (ignore);
394 pru_last_label = NULL;
395 pru_current_align = 0;
396 pru_current_align_seg = now_seg;
397}
398
399/* Explicitly unaligned cons. */
400static void
401s_pru_ucons (int nbytes)
402{
403 int hold;
404 hold = pru_auto_align_on;
405 pru_auto_align_on = 0;
406 cons (nbytes);
407 pru_auto_align_on = hold;
408}
409
410/* .set sets assembler options. */
411static void
412s_pru_set (int equiv)
413{
414 char *save = input_line_pointer;
415 char *directive;
416 char delim = get_symbol_name (&directive);
417 char *endline = input_line_pointer;
418
419 (void) restore_line_pointer (delim);
420
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. */
425 SKIP_WHITESPACE ();
426 if (is_end_of_line[(unsigned char) *input_line_pointer])
427 {
5b7c81bd 428 bool done = true;
93f11b16
DD
429 *endline = 0;
430
431 if (!strcmp (directive, "no_warn_regname_label"))
5b7c81bd 432 pru_opt.warn_regname_label = false;
93f11b16 433 else
5b7c81bd 434 done = false;
93f11b16
DD
435
436 if (done)
437 {
438 *endline = delim;
439 demand_empty_rest_of_line ();
440 return;
441 }
442 }
443
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
446 a syntax error. */
447 input_line_pointer = save;
448 s_set (equiv);
449}
450
451/* Machine-dependent assembler directives.
452 Format of each entry is:
453 { "directive", handler_func, param } */
454const 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. */
463 {"dword", cons, 8},
464 {"half", cons, 2},
465 /* PRU native word size is 4 bytes, so we override
466 the GAS default of 2. */
467 {"word", cons, 4},
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},
474 {NULL, NULL, 0}
475};
476
477\f
478int
479md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
480 asection *seg ATTRIBUTE_UNUSED)
481{
482 abort ();
483 return 0;
484}
485
486void
487md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED,
488 fragS *fragp ATTRIBUTE_UNUSED)
489{
490 abort ();
491}
492
493\f
5b7c81bd 494static bool
93f11b16
DD
495relaxable_section (asection *sec)
496{
497 return ((sec->flags & SEC_DEBUGGING) == 0
498 && (sec->flags & SEC_CODE) != 0
499 && (sec->flags & SEC_ALLOC) != 0);
500}
501
502/* Does whatever the xtensa port does. */
503int
504pru_validate_fix_sub (fixS *fix)
505{
506 segT add_symbol_segment, sub_symbol_segment;
507
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)
513 return 0;
514
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))
522 return 0;
523
524 sub_symbol_segment = S_GET_SEGMENT (fix->fx_subsy);
525 return (sub_symbol_segment == add_symbol_segment);
526}
527
528/* TC_FORCE_RELOCATION hook. */
529
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. */
533int
534pru_force_relocation (fixS *fix)
535{
536 if (linkrelax && fix->fx_addsy
537 && relaxable_section (S_GET_SEGMENT (fix->fx_addsy)))
538 return 1;
539
540 return generic_force_reloc (fix);
541}
542
543
544\f
545/** Fixups and overflow checking. */
546
547/* Check a fixup for overflow. */
548static bfd_reloc_status_type
549pru_check_overflow (valueT fixup, reloc_howto_type *howto)
550{
551 bfd_reloc_status_type ret;
552
553 ret = bfd_check_overflow (howto->complain_on_overflow,
554 howto->bitsize,
555 howto->rightshift,
556 bfd_get_reloc_size (howto) * 8,
557 fixup);
558
559 return ret;
560}
561
562/* Emit diagnostic for fixup overflow. */
563static void
564pru_diagnose_overflow (valueT fixup, reloc_howto_type *howto,
565 fixS *fixP, valueT value)
566{
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));
575 else
576 {
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);
587 gas_assert (opcode);
588 overflow_msg_type = opcode->overflow_msg;
589 switch (overflow_msg_type)
590 {
591 case call_target_overflow:
592 range_min
593 = ((fixP->fx_frag->fr_address + fixP->fx_where) & 0xf0000000);
594 range_max = range_min + 0x0fffffff;
595 address = fixup | range_min;
596
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);
600 break;
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);
605 break;
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);
610 break;
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);
615 break;
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);
620 break;
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);
625 break;
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);
630 break;
631 default:
632 as_bad_where (fixP->fx_file, fixP->fx_line,
633 _("overflow in immediate argument"));
634 break;
635 }
636 }
637}
638
639/* Apply a fixup to the object file. */
640void
641md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
642{
643 unsigned char *where;
644 valueT value = *valP;
93f11b16
DD
645
646 /* Assert that the fixup is one we can handle. */
647 gas_assert (fixP != NULL && valP != NULL
648 && (fixP->fx_r_type == BFD_RELOC_8
649 || fixP->fx_r_type == BFD_RELOC_16
650 || fixP->fx_r_type == BFD_RELOC_32
651 || fixP->fx_r_type == BFD_RELOC_64
652 || fixP->fx_r_type == BFD_RELOC_PRU_LDI32
653 || fixP->fx_r_type == BFD_RELOC_PRU_U16
654 || fixP->fx_r_type == BFD_RELOC_PRU_U16_PMEMIMM
655 || fixP->fx_r_type == BFD_RELOC_PRU_S10_PCREL
656 || fixP->fx_r_type == BFD_RELOC_PRU_U8_PCREL
657 || fixP->fx_r_type == BFD_RELOC_PRU_32_PMEM
658 || fixP->fx_r_type == BFD_RELOC_PRU_16_PMEM
659 /* Add other relocs here as we generate them. */
660 ));
661
662 if (fixP->fx_r_type == BFD_RELOC_64)
663 {
664 /* We may reach here due to .8byte directives, but we never output
665 BFD_RELOC_64; it must be resolved. */
666 if (fixP->fx_addsy != NULL)
667 as_bad_where (fixP->fx_file, fixP->fx_line,
668 _("cannot create 64-bit relocation"));
669 else
670 {
671 md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,
672 *valP, 8);
673 fixP->fx_done = 1;
674 }
675 return;
676 }
677
678 /* gas_assert (had_errors () || !fixP->fx_subsy); */
679
680 /* In general, fix instructions with immediate
681 constants. But leave LDI32 for the linker,
682 which is prepared to shorten insns. */
683 if (fixP->fx_addsy == (symbolS *) NULL
684 && fixP->fx_r_type != BFD_RELOC_PRU_LDI32)
685 fixP->fx_done = 1;
686
687 else if (fixP->fx_pcrel)
688 {
689 segT s = S_GET_SEGMENT (fixP->fx_addsy);
690
691 if (s == seg || s == absolute_section)
692 {
693 /* Blindly copied from AVR, but I don't understand why
694 this is needed in the first place. Fail hard to catch
695 when this curious code snippet is utilized. */
696 as_bad_where (fixP->fx_file, fixP->fx_line,
697 _("unexpected PC relative expression"));
698 value += S_GET_VALUE (fixP->fx_addsy);
699 fixP->fx_done = 1;
700 }
701 }
702 else if (linkrelax && fixP->fx_subsy)
703 {
704 /* For a subtraction relocation expression, generate one
705 of the DIFF relocs, with the value being the difference.
706 Note that a sym1 - sym2 expression is adjusted into a
707 section_start_sym + sym4_offset_from_section_start - sym1
708 expression. fixP->fx_addsy holds the section start symbol,
709 fixP->fx_offset holds sym2's offset, and fixP->fx_subsy
710 holds sym1. Calculate the current difference and write value,
711 but leave fx_offset as is - during relaxation,
712 fx_offset - value gives sym1's value. */
713
714 offsetT diffval; /* valueT is unsigned, so use offsetT. */
715
716 diffval = S_GET_VALUE (fixP->fx_addsy)
717 + fixP->fx_offset - S_GET_VALUE (fixP->fx_subsy);
718
719 switch (fixP->fx_r_type)
720 {
721 case BFD_RELOC_8:
722 fixP->fx_r_type = BFD_RELOC_PRU_GNU_DIFF8;
723 break;
724 case BFD_RELOC_16:
725 fixP->fx_r_type = BFD_RELOC_PRU_GNU_DIFF16;
726 break;
727 case BFD_RELOC_32:
728 fixP->fx_r_type = BFD_RELOC_PRU_GNU_DIFF32;
729 break;
730 case BFD_RELOC_PRU_16_PMEM:
731 fixP->fx_r_type = BFD_RELOC_PRU_GNU_DIFF16_PMEM;
732 if (diffval % 4)
733 as_bad_where (fixP->fx_file, fixP->fx_line,
734 _("residual low bits in pmem diff relocation"));
735 diffval /= 4;
736 break;
737 case BFD_RELOC_PRU_32_PMEM:
738 fixP->fx_r_type = BFD_RELOC_PRU_GNU_DIFF32_PMEM;
739 if (diffval % 4)
740 as_bad_where (fixP->fx_file, fixP->fx_line,
741 _("residual low bits in pmem diff relocation"));
742 diffval /= 4;
743 break;
744 default:
745 as_bad_where (fixP->fx_file, fixP->fx_line,
746 _("expression too complex"));
747 break;
748 }
749
750 value = *valP = diffval;
751
752 fixP->fx_subsy = NULL;
753 }
754 /* We don't actually support subtracting a symbol. */
755 if (fixP->fx_subsy != (symbolS *) NULL)
756 as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
757
758 /* For the DIFF relocs, write the value into the object file while still
759 keeping fx_done FALSE, as both the difference (recorded in the object file)
760 and the sym offset (part of fixP) are needed at link relax time. */
761 where = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
762 switch (fixP->fx_r_type)
763 {
764 case BFD_RELOC_PRU_GNU_DIFF8:
765 *where = value;
766 break;
767 case BFD_RELOC_PRU_GNU_DIFF16:
768 case BFD_RELOC_PRU_GNU_DIFF16_PMEM:
769 bfd_putl16 ((bfd_vma) value, where);
770 break;
771 case BFD_RELOC_PRU_GNU_DIFF32:
772 case BFD_RELOC_PRU_GNU_DIFF32_PMEM:
773 bfd_putl32 ((bfd_vma) value, where);
774 break;
775 default:
776 break;
777 }
778
779 if (fixP->fx_done)
780 /* Fully resolved fixup. */
781 {
782 reloc_howto_type *howto
783 = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
784
785 if (howto == NULL)
786 as_bad_where (fixP->fx_file, fixP->fx_line,
787 _("relocation is not supported"));
788 else
789 {
790 valueT fixup = value;
791 uint64_t insn;
792 char *buf;
793
794 /* Get the instruction or data to be fixed up. */
795 buf = fixP->fx_frag->fr_literal + fixP->fx_where;
796 insn = md_chars_to_number (buf, fixP->fx_size);
797
798 /* Check for overflow, emitting a diagnostic if necessary. */
799 if (pru_check_overflow (fixup, howto) != bfd_reloc_ok)
800 pru_diagnose_overflow (fixup, howto, fixP, insn);
801
802 /* Apply the right shift. */
4f7cc141 803 fixup = (offsetT) fixup >> howto->rightshift;
93f11b16
DD
804
805 /* Truncate the fixup to right size. */
4f7cc141
AM
806 if (howto->bitsize == 0)
807 fixup = 0;
808 else
809 fixup &= ((valueT) 2 << (howto->bitsize - 1)) - 1;
93f11b16
DD
810
811 /* Fix up the instruction. Non-contiguous bitfields need
812 special handling. */
ddb2c6fd 813 if (fixP->fx_r_type == BFD_RELOC_PRU_LDI32)
93f11b16
DD
814 {
815 /* As the only 64-bit "insn", LDI32 needs special handling. */
816 uint32_t insn1 = insn & 0xffffffff;
817 uint32_t insn2 = insn >> 32;
493ffac5
DD
818 SET_INSN_FIELD (IMM16, insn1, fixup >> 16);
819 SET_INSN_FIELD (IMM16, insn2, fixup & 0xffff);
820
821 SET_INSN_FIELD (RDSEL, insn1, RSEL_31_16);
822 SET_INSN_FIELD (RDSEL, insn2, RSEL_15_0);
ddb2c6fd
DD
823
824 md_number_to_chars (buf, insn1, 4);
825 md_number_to_chars (buf + 4, insn2, 4);
93f11b16
DD
826 }
827 else
ddb2c6fd
DD
828 {
829 if (fixP->fx_r_type == BFD_RELOC_PRU_S10_PCREL)
830 SET_BROFF_URAW (insn, fixup);
831 else
832 insn = (insn & ~howto->dst_mask) | (fixup << howto->bitpos);
833 md_number_to_chars (buf, insn, fixP->fx_size);
834 }
93f11b16
DD
835 }
836
837 fixP->fx_done = 1;
838 }
839
840 if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
841 {
842 fixP->fx_done = 0;
843 if (fixP->fx_addsy
844 && !S_IS_DEFINED (fixP->fx_addsy) && !S_IS_WEAK (fixP->fx_addsy))
845 S_SET_WEAK (fixP->fx_addsy);
846 }
847 else if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
848 fixP->fx_done = 0;
849}
850
851
852\f
853/** Instruction parsing support. */
854
855/* Creates a new pru_insn_relocS and returns a pointer to it. */
856static pru_insn_relocS *
857pru_insn_reloc_new (bfd_reloc_code_real_type reloc_type, unsigned int pcrel)
858{
859 pru_insn_relocS *retval;
860 retval = XNEW (pru_insn_relocS);
861 if (retval == NULL)
862 {
863 as_bad (_("can't create relocation"));
864 abort ();
865 }
866
867 /* Fill out the fields with default values. */
868 retval->reloc_next = NULL;
869 retval->reloc_type = reloc_type;
870 retval->reloc_pcrel = pcrel;
871 return retval;
872}
873
874/* Frees up memory previously allocated by pru_insn_reloc_new (). */
875static void
876pru_insn_reloc_destroy (pru_insn_relocS *reloc)
877{
878 pru_insn_relocS *next;
879
880 while (reloc)
881 {
882 next = reloc->reloc_next;
883 free (reloc);
884 reloc = next;
885 }
886}
887
888/* The various pru_assemble_* functions call this
889 function to generate an expression from a string representing an expression.
890 It then tries to evaluate the expression, and if it can, returns its value.
891 If not, it creates a new pru_insn_relocS and stores the expression and
892 reloc_type for future use. */
893static unsigned long
894pru_assemble_expression (const char *exprstr,
895 pru_insn_infoS *insn,
896 pru_insn_relocS *prev_reloc,
897 bfd_reloc_code_real_type reloc_type,
898 unsigned int pcrel)
899{
900 expressionS *ep;
901 pru_insn_relocS *reloc;
902 char *saved_line_ptr;
903 unsigned short value;
904
905 gas_assert (exprstr != NULL);
906 gas_assert (insn != NULL);
907
908 /* We use this blank keyword to distinguish register from
909 label operands. */
910 if (strstr (exprstr, "%label") != NULL)
911 {
912 exprstr += strlen ("%label") + 1;
913 }
914
915 /* Check for pmem relocation operator.
916 Change the relocation type and advance the ptr to the start of
917 the expression proper. */
918 if (strstr (exprstr, "%pmem") != NULL)
919 {
920 reloc_type = BFD_RELOC_PRU_U16_PMEMIMM;
921 exprstr += strlen ("%pmem") + 1;
922 }
923
924 /* We potentially have a relocation. */
925 reloc = pru_insn_reloc_new (reloc_type, pcrel);
926 if (prev_reloc != NULL)
927 prev_reloc->reloc_next = reloc;
928 else
929 insn->insn_reloc = reloc;
930
931 /* Parse the expression string. */
932 ep = &reloc->reloc_expression;
933 saved_line_ptr = input_line_pointer;
934 input_line_pointer = (char *) exprstr;
935 SKIP_WHITESPACE ();
936 expression (ep);
937 SKIP_WHITESPACE ();
938 if (*input_line_pointer)
939 as_bad (_("trailing garbage after expression: %s"), input_line_pointer);
940 input_line_pointer = saved_line_ptr;
941
942
943 if (ep->X_op == O_illegal || ep->X_op == O_absent)
944 as_bad (_("expected expression, got %s"), exprstr);
945
946 /* This is redundant as the fixup will put this into
947 the instruction, but it is included here so that
948 self-test mode (-r) works. */
949 value = 0;
950 if (pru_mode == PRU_MODE_TEST && ep->X_op == O_constant)
951 value = ep->X_add_number;
952
953 return (unsigned long) value;
954}
955
956/* Try to parse a non-relocatable expression. */
957static unsigned long
958pru_assemble_noreloc_expression (const char *exprstr)
959{
960 expressionS exp;
961 char *saved_line_ptr;
962 unsigned long val;
963
964 gas_assert (exprstr != NULL);
965
966 saved_line_ptr = input_line_pointer;
967 input_line_pointer = (char *) exprstr;
968 SKIP_WHITESPACE ();
969 expression (&exp);
970 SKIP_WHITESPACE ();
971 if (*input_line_pointer)
972 as_bad (_("trailing garbage after expression: %s"), input_line_pointer);
973 input_line_pointer = saved_line_ptr;
974
975 val = 0;
976 if (exp.X_op != O_constant)
977 as_bad (_("expected constant expression, got %s"), exprstr);
978 else
979 val = exp.X_add_number;
980
981 return val;
982}
983
984/* Argument assemble functions.
985 All take an instruction argument string, and a pointer
986 to an instruction opcode. Upon return the insn_opcode
987 has the relevant fields filled in to represent the arg
988 string. The return value is NULL if successful, or
989 an error message if an error was detected. */
990
991static void
992pru_assemble_arg_d (pru_insn_infoS *insn_info, const char *argstr)
993{
994 struct pru_reg *dst = pru_reg_lookup (argstr);
995
996 if (dst == NULL)
997 as_bad (_("unknown register %s"), argstr);
998 else
999 {
1000 SET_INSN_FIELD (RD, insn_info->insn_code, dst->index);
1001 SET_INSN_FIELD (RDSEL, insn_info->insn_code, dst->regsel);
1002 }
1003}
1004
1005static void
1006pru_assemble_arg_D (pru_insn_infoS *insn_info, const char *argstr)
1007{
1008 struct pru_reg *dst;
1009
1010 /* The leading & before an address register is optional. */
1011 if (*argstr == '&')
1012 argstr++;
1013
1014 dst = pru_reg_lookup (argstr);
1015
1016 if (dst == NULL)
1017 as_bad (_("unknown register %s"), argstr);
1018 else
1019 {
1020 unsigned long rxb = 0;
1021
1022 switch (dst->regsel)
1023 {
1024 case RSEL_31_0: rxb = 0; break; /* whole register defaults to .b0 */
1025 case RSEL_7_0: rxb = 0; break;
1026 case RSEL_15_8: rxb = 1; break;
1027 case RSEL_23_16: rxb = 2; break;
1028 case RSEL_31_24: rxb = 3; break;
1029 default:
1030 as_bad (_("data transfer register cannot be halfword"));
1031 }
1032
1033 SET_INSN_FIELD (RD, insn_info->insn_code, dst->index);
1034 SET_INSN_FIELD (RDB, insn_info->insn_code, rxb);
1035 }
1036}
1037
1038static void
1039pru_assemble_arg_R (pru_insn_infoS *insn_info, const char *argstr)
1040{
1041 struct pru_reg *dst = pru_reg_lookup (argstr);
1042
1043 if (dst == NULL)
1044 as_bad (_("unknown register %s"), argstr);
1045 else
1046 {
1047 if (dst->regsel != RSEL_31_0)
1048 {
1049 as_bad (_("destination register must be full-word"));
1050 }
1051
1052 SET_INSN_FIELD (RD, insn_info->insn_code, dst->index);
1053 SET_INSN_FIELD (RDSEL, insn_info->insn_code, dst->regsel);
1054 }
1055}
1056
1057static void
1058pru_assemble_arg_s (pru_insn_infoS *insn_info, const char *argstr)
1059{
1060 struct pru_reg *src1 = pru_reg_lookup (argstr);
1061
1062 if (src1 == NULL)
1063 as_bad (_("unknown register %s"), argstr);
1064 else
1065 {
1066 SET_INSN_FIELD (RS1, insn_info->insn_code, src1->index);
1067 SET_INSN_FIELD (RS1SEL, insn_info->insn_code, src1->regsel);
1068 }
1069}
1070
1071static void
1072pru_assemble_arg_S (pru_insn_infoS *insn_info, const char *argstr)
1073{
1074 struct pru_reg *src1 = pru_reg_lookup (argstr);
1075
1076 if (src1 == NULL)
1077 as_bad (_("unknown register %s"), argstr);
1078 else
1079 {
1080 if (src1->regsel != RSEL_31_0)
1081 as_bad (_("cannot use partial register %s for addressing"), argstr);
1082 SET_INSN_FIELD (RS1, insn_info->insn_code, src1->index);
1083 }
1084}
1085
1086static void
1087pru_assemble_arg_b (pru_insn_infoS *insn_info, const char *argstr)
1088{
1089 struct pru_reg *src2 = pru_reg_lookup (argstr);
1090 if (src2 == NULL)
1091 {
1092 unsigned long imm8 = pru_assemble_noreloc_expression (argstr);
493ffac5
DD
1093 if (imm8 >= 0x100)
1094 as_bad (_("value %lu is too large for a byte operand"), imm8);
93f11b16
DD
1095 SET_INSN_FIELD (IMM8, insn_info->insn_code, imm8);
1096 SET_INSN_FIELD (IO, insn_info->insn_code, 1);
1097 }
1098 else
1099 {
1100 SET_INSN_FIELD (IO, insn_info->insn_code, 0);
1101 SET_INSN_FIELD (RS2, insn_info->insn_code, src2->index);
1102 SET_INSN_FIELD (RS2SEL, insn_info->insn_code, src2->regsel);
1103 }
1104
1105}
1106
1107static void
1108pru_assemble_arg_B (pru_insn_infoS *insn_info, const char *argstr)
1109{
1110 struct pru_reg *src2 = pru_reg_lookup (argstr);
1111 if (src2 == NULL)
1112 {
1113 unsigned long imm8;
1114 imm8 = pru_assemble_noreloc_expression (argstr);
1115 if (!imm8 || imm8 > 0xff)
1116 as_bad (_("loop count constant %ld is out of range [1..%d]"),
1117 imm8, 0xff);
1118 /* Note: HW expects the immediate loop count field
1119 to be one less than the actual loop count. */
1120 SET_INSN_FIELD (IMM8, insn_info->insn_code, imm8 - 1);
1121 SET_INSN_FIELD (IO, insn_info->insn_code, 1);
1122 }
1123 else
1124 {
1125 SET_INSN_FIELD (IO, insn_info->insn_code, 0);
1126 SET_INSN_FIELD (RS2, insn_info->insn_code, src2->index);
1127 SET_INSN_FIELD (RS2SEL, insn_info->insn_code, src2->regsel);
1128 }
1129}
1130
1131static void
1132pru_assemble_arg_i (pru_insn_infoS *insn_info, const char *argstr)
1133{
1134 unsigned long imm32;
1135
1136 /* We must not generate PRU_LDI32 relocation if relaxation is disabled in
1137 GAS. Consider the following scenario: GAS relaxation is disabled, so
1138 DIFF* expressions are fixed and not emitted as relocations. Then if LD
1139 has relaxation enabled, it may shorten LDI32 but will not update
1140 accordingly the DIFF expressions. */
1141 if (pru_opt.link_relax)
1142 imm32 = pru_assemble_expression (argstr, insn_info,
1143 insn_info->insn_reloc,
1144 BFD_RELOC_PRU_LDI32, 0);
1145 else
1146 imm32 = pru_assemble_noreloc_expression (argstr);
1147
1148 /* QUIRK: LDI must clear IO bit high, even though it has immediate arg. */
1149 SET_INSN_FIELD (IO, insn_info->insn_code, 0);
493ffac5
DD
1150 SET_INSN_FIELD (RDSEL, insn_info->insn_code, RSEL_31_16);
1151 SET_INSN_FIELD (IMM16, insn_info->insn_code, imm32 >> 16);
93f11b16
DD
1152 insn_info->ldi32_imm32 = imm32;
1153}
1154
1155static void
1156pru_assemble_arg_j (pru_insn_infoS *insn_info, const char *argstr)
1157{
1158 struct pru_reg *src2 = pru_reg_lookup (argstr);
1159
1160 if (src2 == NULL)
1161 {
1162 unsigned long imm16 = pru_assemble_expression (argstr, insn_info,
1163 insn_info->insn_reloc,
1164 BFD_RELOC_PRU_U16_PMEMIMM,
1165 0);
1166 SET_INSN_FIELD (IMM16, insn_info->insn_code, imm16);
1167 SET_INSN_FIELD (IO, insn_info->insn_code, 1);
1168 }
1169 else
1170 {
1171 SET_INSN_FIELD (IO, insn_info->insn_code, 0);
1172 SET_INSN_FIELD (RS2, insn_info->insn_code, src2->index);
1173 SET_INSN_FIELD (RS2SEL, insn_info->insn_code, src2->regsel);
1174 }
1175}
1176
1177static void
1178pru_assemble_arg_W (pru_insn_infoS *insn_info, const char *argstr)
1179{
1180 unsigned long imm16 = pru_assemble_expression (argstr, insn_info,
1181 insn_info->insn_reloc,
1182 BFD_RELOC_PRU_U16, 0);
1183 /* QUIRK: LDI must clear IO bit high, even though it has immediate arg. */
1184 SET_INSN_FIELD (IO, insn_info->insn_code, 0);
1185 SET_INSN_FIELD (IMM16, insn_info->insn_code, imm16);
1186}
1187
1188static void
1189pru_assemble_arg_o (pru_insn_infoS *insn_info, const char *argstr)
1190{
1191 unsigned long imm10 = pru_assemble_expression (argstr, insn_info,
1192 insn_info->insn_reloc,
1193 BFD_RELOC_PRU_S10_PCREL, 1);
1194 SET_BROFF_URAW (insn_info->insn_code, imm10);
1195}
1196
1197static void
1198pru_assemble_arg_O (pru_insn_infoS *insn_info, const char *argstr)
1199{
1200 unsigned long imm8 = pru_assemble_expression (argstr, insn_info,
1201 insn_info->insn_reloc,
1202 BFD_RELOC_PRU_U8_PCREL, 1);
1203 SET_INSN_FIELD (LOOP_JMPOFFS, insn_info->insn_code, imm8);
1204}
1205
1206static void
1207pru_assemble_arg_l (pru_insn_infoS *insn_info, const char *argstr)
1208{
1209 unsigned long burstlen = 0;
1210 struct pru_reg *blreg = pru_reg_lookup (argstr);
1211
1212 if (blreg == NULL)
1213 {
1214 burstlen = pru_assemble_noreloc_expression (argstr);
1215 if (!burstlen || burstlen > LSSBBO_BYTECOUNT_R0_BITS7_0)
1216 as_bad (_("byte count constant %ld is out of range [1..%d]"),
1217 burstlen, LSSBBO_BYTECOUNT_R0_BITS7_0);
1218 burstlen--;
1219 }
1220 else
1221 {
1222 if (blreg->index != 0)
1223 as_bad (_("only r0 can be used as byte count register"));
1224 else if (blreg->regsel > RSEL_31_24)
1225 as_bad (_("only r0.bX byte fields of r0 can be used as byte count"));
1226 else
1227 burstlen = LSSBBO_BYTECOUNT_R0_BITS7_0 + blreg->regsel;
1228 }
1229 SET_BURSTLEN (insn_info->insn_code, burstlen);
1230}
1231
1232static void
1233pru_assemble_arg_n (pru_insn_infoS *insn_info, const char *argstr)
1234{
1235 unsigned long burstlen = 0;
1236 struct pru_reg *blreg = pru_reg_lookup (argstr);
1237
1238 if (blreg == NULL)
1239 {
1240 burstlen = pru_assemble_noreloc_expression (argstr);
1241 if (!burstlen || burstlen > LSSBBO_BYTECOUNT_R0_BITS7_0)
1242 as_bad (_("byte count constant %ld is out of range [1..%d]"),
1243 burstlen, LSSBBO_BYTECOUNT_R0_BITS7_0);
1244 burstlen--;
1245 }
1246 else
1247 {
1248 if (blreg->index != 0)
1249 as_bad (_("only r0 can be used as byte count register"));
1250 else if (blreg->regsel > RSEL_31_24)
1251 as_bad (_("only r0.bX byte fields of r0 can be used as byte count"));
1252 else
1253 burstlen = LSSBBO_BYTECOUNT_R0_BITS7_0 + blreg->regsel;
1254 }
1255 SET_INSN_FIELD (XFR_LENGTH, insn_info->insn_code, burstlen);
1256}
1257
1258static void
1259pru_assemble_arg_c (pru_insn_infoS *insn_info, const char *argstr)
1260{
1261 unsigned long cb = pru_assemble_noreloc_expression (argstr);
1262
1263 if (cb > 31)
1264 as_bad (_("invalid constant table offset %ld"), cb);
1265 else
1266 SET_INSN_FIELD (CB, insn_info->insn_code, cb);
1267}
1268
1269static void
1270pru_assemble_arg_w (pru_insn_infoS *insn_info, const char *argstr)
1271{
1272 unsigned long wk = pru_assemble_noreloc_expression (argstr);
1273
1274 if (wk != 0 && wk != 1)
1275 as_bad (_("invalid WakeOnStatus %ld"), wk);
1276 else
1277 SET_INSN_FIELD (WAKEONSTATUS, insn_info->insn_code, wk);
1278}
1279
1280static void
1281pru_assemble_arg_x (pru_insn_infoS *insn_info, const char *argstr)
1282{
1283 unsigned long wba = pru_assemble_noreloc_expression (argstr);
1284
1285 if (wba > 255)
1286 as_bad (_("invalid XFR WideBus Address %ld"), wba);
1287 else
1288 SET_INSN_FIELD (XFR_WBA, insn_info->insn_code, wba);
1289}
1290
1291/* The function consume_arg takes a pointer into a string
1292 of instruction tokens (args) and a pointer into a string
1293 representing the expected sequence of tokens and separators.
1294 It checks whether the first argument in argstr is of the
1295 expected type, throwing an error if it is not, and returns
1296 the pointer argstr. */
1297static char *
1298pru_consume_arg (char *argstr, const char *parsestr)
1299{
1300 char *temp;
1301
1302 switch (*parsestr)
1303 {
1304 case 'W':
1305 if (*argstr == '%')
1306 {
1307 if (strprefix (argstr, "%pmem") || strprefix (argstr, "%label"))
1308 {
1309 /* We zap the parentheses because we don't want them confused
1310 with separators. */
1311 temp = strchr (argstr, '(');
1312 if (temp != NULL)
1313 *temp = ' ';
1314 temp = strchr (argstr, ')');
1315 if (temp != NULL)
1316 *temp = ' ';
1317 }
1318 else
1319 as_bad (_("badly formed expression near %s"), argstr);
1320 }
1321 break;
1322
1323 case 'j':
1324 case 'o':
1325 case 'O':
1326 if (*argstr == '%')
1327 {
1328 /* Only 'j' really requires %label for distinguishing registers
1329 from labels, but we include 'o' and 'O' here to avoid
1330 confusing assembler programmers. Thus for completeness all
1331 jump operands can be prefixed with %label. */
1332 if (strprefix (argstr, "%label"))
1333 {
1334 /* We zap the parentheses because we don't want them confused
1335 with separators. */
1336 temp = strchr (argstr, '(');
1337 if (temp != NULL)
1338 *temp = ' ';
1339 temp = strchr (argstr, ')');
1340 if (temp != NULL)
1341 *temp = ' ';
1342 }
1343 else
1344 as_bad (_("badly formed expression near %s"), argstr);
1345 }
1346 break;
1347
1348 case 'b':
1349 case 'B':
1350 case 'c':
1351 case 'd':
1352 case 'D':
1353 case 'E':
1354 case 'i':
1355 case 's':
1356 case 'S':
1357 case 'l':
1358 case 'n':
1359 case 'R':
1360 case 'w':
1361 case 'x':
1362 /* We can't have %pmem here. */
1363 if (*argstr == '%')
1364 as_bad (_("badly formed expression near %s"), argstr);
1365 break;
1366 default:
1367 BAD_CASE (*parsestr);
1368 break;
1369 }
1370
1371 return argstr;
1372}
1373
1374/* The function consume_separator takes a pointer into a string
1375 of instruction tokens (args) and a pointer into a string representing
1376 the expected sequence of tokens and separators. It finds the first
1377 instance of the character pointed to by separator in argstr, and
1378 returns a pointer to the next element of argstr, which is the
1379 following token in the sequence. */
1380static char *
1381pru_consume_separator (char *argstr, const char *separator)
1382{
1383 char *p;
1384
1385 p = strchr (argstr, *separator);
1386
1387 if (p != NULL)
1388 *p++ = 0;
1389 else
1390 as_bad (_("expecting %c near %s"), *separator, argstr);
1391 return p;
1392}
1393
1394
1395/* The principal argument parsing function which takes a string argstr
1396 representing the instruction arguments for insn, and extracts the argument
1397 tokens matching parsestr into parsed_args. */
1398static void
1399pru_parse_args (pru_insn_infoS *insn ATTRIBUTE_UNUSED, char *argstr,
1400 const char *parsestr, char **parsed_args)
1401{
1402 char *p;
1403 char *end = NULL;
1404 int i;
1405 p = argstr;
1406 i = 0;
5b7c81bd 1407 bool terminate = false;
93f11b16
DD
1408
1409 /* This rest of this function is it too fragile and it mostly works,
1410 therefore special case this one. */
1411 if (*parsestr == 0 && argstr != 0)
1412 {
1413 as_bad (_("too many arguments"));
1414 parsed_args[0] = NULL;
1415 return;
1416 }
1417
1418 while (p != NULL && !terminate && i < PRU_MAX_INSN_TOKENS)
1419 {
1420 parsed_args[i] = pru_consume_arg (p, parsestr);
1421 ++parsestr;
1422 if (*parsestr != '\0')
1423 {
1424 p = pru_consume_separator (p, parsestr);
1425 ++parsestr;
1426 }
1427 else
1428 {
1429 /* Check that the argument string has no trailing arguments. */
1430 /* If we've got a %pmem relocation, we've zapped the parens with
1431 spaces. */
1432 if (strprefix (p, "%pmem") || strprefix (p, "%label"))
1433 end = strpbrk (p, ",");
1434 else
1435 end = strpbrk (p, " ,");
1436
1437 if (end != NULL)
1438 as_bad (_("too many arguments"));
1439 }
1440
1441 if (*parsestr == '\0' || (p != NULL && *p == '\0'))
5b7c81bd 1442 terminate = true;
93f11b16
DD
1443 ++i;
1444 }
1445
1446 parsed_args[i] = NULL;
1447
1448 /* There are no instructions with optional arguments; complain. */
1449 if (*parsestr != '\0')
1450 as_bad (_("missing argument"));
1451}
1452
1453\f
1454/** Assembler output support. */
1455
1456/* Output a normal instruction. */
1457static void
1458output_insn (pru_insn_infoS *insn)
1459{
1460 char *f;
1461 pru_insn_relocS *reloc;
1462
1463 f = frag_more (4);
1464 /* This allocates enough space for the instruction
1465 and puts it in the current frag. */
1466 md_number_to_chars (f, insn->insn_code, 4);
1467 /* Emit debug info. */
1468 dwarf2_emit_insn (4);
1469 /* Create any fixups to be acted on later. */
1470 for (reloc = insn->insn_reloc; reloc != NULL; reloc = reloc->reloc_next)
1471 fix_new_exp (frag_now, f - frag_now->fr_literal, 4,
1472 &reloc->reloc_expression, reloc->reloc_pcrel,
1473 reloc->reloc_type);
1474}
1475
1476/* Output two LDI instructions from LDI32 macro */
1477static void
1478output_insn_ldi32 (pru_insn_infoS *insn)
1479{
1480 char *f;
1481 pru_insn_relocS *reloc;
1482 unsigned long insn2;
1483
1484 f = frag_more (8);
493ffac5
DD
1485 SET_INSN_FIELD (IMM16, insn->insn_code, insn->ldi32_imm32 >> 16);
1486 SET_INSN_FIELD (RDSEL, insn->insn_code, RSEL_31_16);
93f11b16
DD
1487 md_number_to_chars (f, insn->insn_code, 4);
1488
1489 insn2 = insn->insn_code;
493ffac5
DD
1490 SET_INSN_FIELD (IMM16, insn2, insn->ldi32_imm32 & 0xffff);
1491 SET_INSN_FIELD (RDSEL, insn2, RSEL_15_0);
93f11b16
DD
1492 md_number_to_chars (f + 4, insn2, 4);
1493
1494 /* Emit debug info. */
1495 dwarf2_emit_insn (8);
1496
1497 /* Create any fixups to be acted on later. */
1498 for (reloc = insn->insn_reloc; reloc != NULL; reloc = reloc->reloc_next)
1499 fix_new_exp (frag_now, f - frag_now->fr_literal, 4,
1500 &reloc->reloc_expression, reloc->reloc_pcrel,
1501 reloc->reloc_type);
1502}
1503
1504\f
1505/** External interfaces. */
1506
1507/* The following functions are called by machine-independent parts of
1508 the assembler. */
1509int
1510md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
1511{
1512 switch (c)
1513 {
1514 case 'r':
1515 /* Hidden option for self-test mode. */
1516 pru_mode = PRU_MODE_TEST;
1517 break;
1518 case OPTION_LINK_RELAX:
5b7c81bd 1519 pru_opt.link_relax = true;
93f11b16
DD
1520 break;
1521 case OPTION_NO_LINK_RELAX:
5b7c81bd 1522 pru_opt.link_relax = false;
93f11b16
DD
1523 break;
1524 case OPTION_NO_WARN_REGNAME_LABEL:
5b7c81bd 1525 pru_opt.warn_regname_label = false;
93f11b16
DD
1526 break;
1527 default:
1528 return 0;
1529 break;
1530 }
1531
1532 return 1;
1533}
1534
1535const char *
1536pru_target_format (void)
1537{
1538 return "elf32-pru";
1539}
1540
1541/* Machine-dependent usage message. */
1542void
1543md_show_usage (FILE *stream)
1544{
1545 fprintf (stream,
1546 _("PRU options:\n"
1547 " -mlink-relax generate relocations for linker relaxation (default).\n"
1548 " -mno-link-relax don't generate relocations for linker relaxation.\n"
1549 ));
1550
1551}
1552
1553/* This function is called once, at assembler startup time.
1554 It should set up all the tables, etc. that the MD part of the
1555 assembler will need. */
1556void
1557md_begin (void)
1558{
1559 int i;
93f11b16
DD
1560
1561 /* Create and fill a hashtable for the PRU opcodes, registers and
1562 arguments. */
629310ab
ML
1563 pru_opcode_hash = str_htab_create ();
1564 pru_reg_hash = str_htab_create ();
93f11b16
DD
1565
1566 for (i = 0; i < NUMOPCODES; ++i)
fe0e921f
AM
1567 if (str_hash_insert (pru_opcode_hash, pru_opcodes[i].name,
1568 &pru_opcodes[i], 0) != NULL)
1569 as_fatal (_("duplicate %s"), pru_opcodes[i].name);
93f11b16
DD
1570
1571 for (i = 0; i < pru_num_regs; ++i)
fe0e921f
AM
1572 if (str_hash_insert (pru_reg_hash, pru_regs[i].name, &pru_regs[i], 0))
1573 as_fatal (_("duplicate %s"), pru_regs[i].name);
93f11b16
DD
1574
1575 linkrelax = pru_opt.link_relax;
1576 /* Initialize the alignment data. */
1577 pru_current_align_seg = now_seg;
1578 pru_last_label = NULL;
1579 pru_current_align = 0;
1580}
1581
1582
1583/* Assembles a single line of PRU assembly language. */
1584void
1585md_assemble (char *op_str)
1586{
1587 char *argstr;
1588 char *op_strdup = NULL;
1589 pru_insn_infoS thisinsn;
1590 pru_insn_infoS *insn = &thisinsn;
1591
1592 /* Make sure we are aligned on a 4-byte boundary. */
1593 if (pru_current_align < 2)
1594 pru_align (2, NULL, pru_last_label);
1595 else if (pru_current_align > 2)
1596 pru_current_align = 2;
1597 pru_last_label = NULL;
1598
1599 /* We don't want to clobber to op_str
1600 because we want to be able to use it in messages. */
1601 op_strdup = strdup (op_str);
1602 insn->insn_tokens[0] = strtok (op_strdup, " ");
1603 argstr = strtok (NULL, "");
1604
1605 /* Assemble the opcode. */
1606 insn->insn_pru_opcode = pru_opcode_lookup (insn->insn_tokens[0]);
1607 insn->insn_reloc = NULL;
1608
1609 if (insn->insn_pru_opcode != NULL)
1610 {
1611 const char *argsfmt = insn->insn_pru_opcode->args;
1612 const char **argtk = &insn->insn_tokens[1];
1613 const char *argp;
1614
1615 /* Set the opcode for the instruction. */
1616 insn->insn_code = insn->insn_pru_opcode->match;
1617
1618 if (pru_mode == PRU_MODE_TEST)
1619 {
1620 /* Add the "expected" instruction parameter used for validation. */
1621 argsfmt = malloc (strlen (argsfmt) + 3);
1622 sprintf ((char *)argsfmt, "%s,E", insn->insn_pru_opcode->args);
1623 }
1624 pru_parse_args (insn, argstr, argsfmt,
1625 (char **) &insn->insn_tokens[1]);
1626
1627 for (argp = argsfmt; !had_errors () && *argp && *argtk; ++argp)
1628 {
1629 gas_assert (argtk <= &insn->insn_tokens[PRU_MAX_INSN_TOKENS]);
1630
1631 switch (*argp)
1632 {
1633 case ',':
1634 continue;
1635
1636 case 'd':
1637 pru_assemble_arg_d (insn, *argtk++);
1638 continue;
1639 case 'D':
1640 pru_assemble_arg_D (insn, *argtk++);
1641 continue;
1642 case 'R':
1643 pru_assemble_arg_R (insn, *argtk++);
1644 continue;
1645 case 's':
1646 pru_assemble_arg_s (insn, *argtk++);
1647 continue;
1648 case 'S':
1649 pru_assemble_arg_S (insn, *argtk++);
1650 continue;
1651 case 'b':
1652 pru_assemble_arg_b (insn, *argtk++);
1653 continue;
1654 case 'B':
1655 pru_assemble_arg_B (insn, *argtk++);
1656 continue;
1657 case 'i':
1658 pru_assemble_arg_i (insn, *argtk++);
1659 continue;
1660 case 'j':
1661 pru_assemble_arg_j (insn, *argtk++);
1662 continue;
1663 case 'W':
1664 pru_assemble_arg_W (insn, *argtk++);
1665 continue;
1666 case 'o':
1667 pru_assemble_arg_o (insn, *argtk++);
1668 continue;
1669 case 'O':
1670 pru_assemble_arg_O (insn, *argtk++);
1671 continue;
1672 case 'l':
1673 pru_assemble_arg_l (insn, *argtk++);
1674 continue;
1675 case 'n':
1676 pru_assemble_arg_n (insn, *argtk++);
1677 continue;
1678 case 'c':
1679 pru_assemble_arg_c (insn, *argtk++);
1680 continue;
1681 case 'w':
1682 pru_assemble_arg_w (insn, *argtk++);
1683 continue;
1684 case 'x':
1685 pru_assemble_arg_x (insn, *argtk++);
1686 continue;
1687
1688 case 'E':
1689 pru_check_assembly (insn->insn_code, *argtk++);
0bae9e9e
NC
1690 continue;
1691
93f11b16
DD
1692 default:
1693 BAD_CASE (*argp);
1694 }
1695 }
1696
1697 if (*argp && !had_errors ())
1698 as_bad (_("missing argument"));
1699
1700 if (!had_errors ())
1701 {
1702 if (insn->insn_pru_opcode->pinfo & PRU_INSN_LDI32)
1703 {
1704 output_insn_ldi32 (insn);
1705 }
1706 else
1707 {
1708 output_insn (insn);
1709 }
1710 }
1711
1712 if (pru_mode == PRU_MODE_TEST)
1713 free ((char *)argsfmt);
1714 }
1715 else
1716 /* Unrecognised instruction - error. */
1717 as_bad (_("unrecognised instruction %s"), insn->insn_tokens[0]);
1718
1719 /* Don't leak memory. */
1720 pru_insn_reloc_destroy (insn->insn_reloc);
1721 free (op_strdup);
1722}
1723
1724/* Round up section size. */
1725valueT
1726md_section_align (asection *seg, valueT addr)
1727{
fd361982 1728 int align = bfd_section_alignment (seg);
93f11b16
DD
1729 return ((addr + (1 << align) - 1) & (-((valueT) 1 << align)));
1730}
1731
1732/* Implement tc_fix_adjustable. */
1733int
1734pru_fix_adjustable (fixS *fixp)
1735{
1736 if (fixp->fx_addsy == NULL)
1737 return 1;
1738
1739 /* Prevent all adjustments to global symbols. */
1740 if (OUTPUT_FLAVOR == bfd_target_elf_flavour
1741 && (S_IS_EXTERNAL (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)))
1742 return 0;
1743
1744 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
1745 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1746 return 0;
1747
1748 /* Preserve relocations against symbols with function type. */
1749 if (symbol_get_bfdsym (fixp->fx_addsy)->flags & BSF_FUNCTION)
1750 return 0;
1751
1752 return 1;
1753}
1754
1755/* The function tc_gen_reloc creates a relocation structure for the
1756 fixup fixp, and returns a pointer to it. This structure is passed
1757 to bfd_install_relocation so that it can be written to the object
1758 file for linking. */
1759arelent *
1760tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
1761{
1762 arelent *reloc = XNEW (arelent);
1763 reloc->sym_ptr_ptr = XNEW (asymbol *);
1764 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1765
1766 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1767 reloc->addend = fixp->fx_offset; /* fixp->fx_addnumber; */
1768
1769 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1770 if (reloc->howto == NULL)
1771 {
1772 as_bad_where (fixp->fx_file, fixp->fx_line,
1773 _("can't represent relocation type %s"),
1774 bfd_get_reloc_code_name (fixp->fx_r_type));
1775
1776 /* Set howto to a garbage value so that we can keep going. */
1777 reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
1778 gas_assert (reloc->howto != NULL);
1779 }
1780 return reloc;
1781}
1782
1783long
1784md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
1785{
1786 return fixP->fx_where + fixP->fx_frag->fr_address;
1787}
1788
1789/* Called just before the assembler exits. */
1790void
1791md_end (void)
1792{
629310ab
ML
1793 htab_delete (pru_opcode_hash);
1794 htab_delete (pru_reg_hash);
93f11b16
DD
1795}
1796
1797symbolS *
1798md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1799{
1800 return NULL;
1801}
1802
1803/* Implement tc_frob_label. */
1804void
1805pru_frob_label (symbolS *lab)
1806{
1807 /* Emit dwarf information. */
1808 dwarf2_emit_label (lab);
1809
1810 /* Update the label's address with the current output pointer. */
1811 symbol_set_frag (lab, frag_now);
1812 S_SET_VALUE (lab, (valueT) frag_now_fix ());
1813
1814 /* Record this label for future adjustment after we find out what
1815 kind of data it references, and the required alignment therewith. */
1816 pru_last_label = lab;
1817
1818 if (pru_opt.warn_regname_label && pru_reg_lookup (S_GET_NAME (lab)))
1819 as_warn (_("Label \"%s\" matches a CPU register name"), S_GET_NAME (lab));
1820}
1821
1822static inline char *
1823skip_space (char *s)
1824{
1825 while (*s == ' ' || *s == '\t')
1826 ++s;
1827 return s;
1828}
1829
1830/* Parse special CONS expression: pmem (expression). Idea from AVR.
1831
1832 Used to catch and mark code (program memory) in constant expression
1833 relocations. Return non-zero for program memory. */
1834
1835int
1836pru_parse_cons_expression (expressionS *exp, int nbytes)
1837{
5b7c81bd 1838 int is_pmem = false;
93f11b16
DD
1839 char *tmp;
1840
1841 tmp = input_line_pointer = skip_space (input_line_pointer);
1842
1843 if (nbytes == 4 || nbytes == 2)
1844 {
1845 const char *pmem_str = "%pmem";
1846 int len = strlen (pmem_str);
1847
1848 if (strncasecmp (input_line_pointer, pmem_str, len) == 0)
1849 {
1850 input_line_pointer = skip_space (input_line_pointer + len);
1851
1852 if (*input_line_pointer == '(')
1853 {
1854 input_line_pointer = skip_space (input_line_pointer + 1);
5b7c81bd 1855 is_pmem = true;
93f11b16
DD
1856 expression (exp);
1857
1858 if (*input_line_pointer == ')')
1859 ++input_line_pointer;
1860 else
1861 {
1862 as_bad (_("`)' required"));
5b7c81bd 1863 is_pmem = false;
93f11b16
DD
1864 }
1865
1866 return is_pmem;
1867 }
1868
1869 input_line_pointer = tmp;
1870 }
1871 }
1872
1873 expression (exp);
1874
1875 return is_pmem;
1876}
1877
1878/* Implement TC_CONS_FIX_NEW. */
1879void
1880pru_cons_fix_new (fragS *frag, int where, unsigned int nbytes,
1881 expressionS *exp, const int is_pmem)
1882{
1883 bfd_reloc_code_real_type r;
1884
1885 switch (nbytes | (!!is_pmem << 8))
1886 {
1887 case 1 | (0 << 8): r = BFD_RELOC_8; break;
1888 case 2 | (0 << 8): r = BFD_RELOC_16; break;
1889 case 4 | (0 << 8): r = BFD_RELOC_32; break;
1890 case 8 | (0 << 8): r = BFD_RELOC_64; break;
1891 case 2 | (1 << 8): r = BFD_RELOC_PRU_16_PMEM; break;
1892 case 4 | (1 << 8): r = BFD_RELOC_PRU_32_PMEM; break;
1893 default:
1894 as_bad (_("illegal %s relocation size: %d"),
1895 is_pmem ? "text" : "data", nbytes);
1896 return;
1897 }
1898
1899 fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
1900}
1901
1902/* Implement tc_regname_to_dw2regnum, to convert REGNAME to a DWARF-2
2688aab2
DD
1903 register number. Return the starting HW byte-register number. */
1904
93f11b16
DD
1905int
1906pru_regname_to_dw2regnum (char *regname)
1907{
2688aab2
DD
1908 static const unsigned int regstart[RSEL_NUM_ITEMS] =
1909 {
1910 [RSEL_7_0] = 0,
1911 [RSEL_15_8] = 1,
1912 [RSEL_23_16] = 2,
1913 [RSEL_31_24] = 3,
1914 [RSEL_15_0] = 0,
1915 [RSEL_23_8] = 1,
1916 [RSEL_31_16] = 2,
1917 [RSEL_31_0] = 0,
1918 };
1919
93f11b16 1920 struct pru_reg *r = pru_reg_lookup (regname);
2688aab2
DD
1921
1922 if (r == NULL || r->regsel >= RSEL_NUM_ITEMS)
93f11b16 1923 return -1;
2688aab2 1924 return r->index * 4 + regstart[r->regsel];
93f11b16
DD
1925}
1926
1927/* Implement tc_cfi_frame_initial_instructions, to initialize the DWARF-2
1928 unwind information for this procedure. */
1929void
1930pru_frame_initial_instructions (void)
1931{
2688aab2 1932 const unsigned fp_regno = 4 * 4;
93f11b16
DD
1933 cfi_add_CFA_def_cfa (fp_regno, 0);
1934}
1935
5b7c81bd 1936bool
93f11b16
DD
1937pru_allow_local_subtract (expressionS * left,
1938 expressionS * right,
1939 segT section)
1940{
1941 /* If we are not in relaxation mode, subtraction is OK. */
1942 if (!linkrelax)
5b7c81bd 1943 return true;
93f11b16
DD
1944
1945 /* If the symbols are not in a code section then they are OK. */
1946 if ((section->flags & SEC_CODE) == 0)
5b7c81bd 1947 return true;
93f11b16
DD
1948
1949 if (left->X_add_symbol == right->X_add_symbol)
5b7c81bd 1950 return true;
93f11b16
DD
1951
1952 /* We have to assume that there may be instructions between the
1953 two symbols and that relaxation may increase the distance between
1954 them. */
5b7c81bd 1955 return false;
93f11b16 1956}