]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-pru.c
Update year range in copyright notice of all files.
[thirdparty/binutils-gdb.git] / gas / config / tc-pru.c
CommitLineData
93f11b16 1/* TI PRU assembler.
2571583a 2 Copyright (C) 2014-2017 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"
24#include "bfd_stdint.h"
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. */
69 bfd_boolean link_relax;
70
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;
74};
75
76static struct pru_opt_s pru_opt = { TRUE, TRUE };
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. */
135static struct hash_control *pru_opcode_hash = NULL;
136#define pru_opcode_lookup(NAME) \
137 ((struct pru_opcode *) hash_find (pru_opcode_hash, (NAME)))
138
139/* Register hash table. */
140static struct hash_control *pru_reg_hash = NULL;
141#define pru_reg_lookup(NAME) \
142 ((struct pru_reg *) hash_find (pru_reg_hash, (NAME)))
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
151 labels preceeding instructions. */
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
178md_number_to_chars (char *buf, uint64_t val, int n)
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{
191 return ieee_md_atof (type, litP, sizeP, FALSE);
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;
249 int label_seen = FALSE;
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 {
275 label_seen = TRUE;
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
299 to check the assembled instruction
300 opcode should be the assembled opcode, and exp_opcode
301 the parsed string representing the expected opcode. */
302static void
303pru_check_assembly (unsigned int opcode, const char *exp_opcode)
304{
305 if (pru_mode == PRU_MODE_TEST)
306 {
307 if (exp_opcode == NULL)
308 as_bad (_("expecting opcode string in self test mode"));
309 else if (opcode != strtoul (exp_opcode, NULL, 16))
310 as_bad (_("assembly 0x%08x, expected %s"), opcode, exp_opcode);
311 }
312}
313
314\f
315/** Support for machine-dependent assembler directives. */
316/* Handle the .align pseudo-op. This aligns to a power of two. It
317 also adjusts any current instruction label. We treat this the same
318 way the MIPS port does: .align 0 turns off auto alignment. */
319static void
320s_pru_align (int ignore ATTRIBUTE_UNUSED)
321{
322 int align;
323 char fill;
324 const char *pfill = NULL;
325 long max_alignment = 15;
326
327 align = get_absolute_expression ();
328 if (align > max_alignment)
329 {
330 align = max_alignment;
331 as_bad (_("Alignment too large: %d assumed"), align);
332 }
333 else if (align < 0)
334 {
335 as_warn (_("Alignment negative: 0 assumed"));
336 align = 0;
337 }
338
339 if (*input_line_pointer == ',')
340 {
341 input_line_pointer++;
342 fill = get_absolute_expression ();
343 pfill = (const char *) &fill;
344 }
345 else if (subseg_text_p (now_seg))
346 pfill = (const char *) &nop;
347 else
348 {
349 pfill = NULL;
350 pru_last_label = NULL;
351 }
352
353 if (align != 0)
354 {
355 pru_auto_align_on = 1;
356 pru_align (align, pfill, pru_last_label);
357 pru_last_label = NULL;
358 }
359 else
360 pru_auto_align_on = 0;
361
362 demand_empty_rest_of_line ();
363}
364
365/* Handle the .text pseudo-op. This is like the usual one, but it
366 clears the saved last label and resets known alignment. */
367static void
368s_pru_text (int i)
369{
370 s_text (i);
371 pru_last_label = NULL;
372 pru_current_align = 0;
373 pru_current_align_seg = now_seg;
374}
375
376/* Handle the .data pseudo-op. This is like the usual one, but it
377 clears the saved last label and resets known alignment. */
378static void
379s_pru_data (int i)
380{
381 s_data (i);
382 pru_last_label = NULL;
383 pru_current_align = 0;
384 pru_current_align_seg = now_seg;
385}
386
387/* Handle the .section pseudo-op. This is like the usual one, but it
388 clears the saved last label and resets known alignment. */
389static void
390s_pru_section (int ignore)
391{
392 obj_elf_section (ignore);
393 pru_last_label = NULL;
394 pru_current_align = 0;
395 pru_current_align_seg = now_seg;
396}
397
398/* Explicitly unaligned cons. */
399static void
400s_pru_ucons (int nbytes)
401{
402 int hold;
403 hold = pru_auto_align_on;
404 pru_auto_align_on = 0;
405 cons (nbytes);
406 pru_auto_align_on = hold;
407}
408
409/* .set sets assembler options. */
410static void
411s_pru_set (int equiv)
412{
413 char *save = input_line_pointer;
414 char *directive;
415 char delim = get_symbol_name (&directive);
416 char *endline = input_line_pointer;
417
418 (void) restore_line_pointer (delim);
419
420 /* We only want to handle ".set XXX" if the
421 user has tried ".set XXX, YYY" they are not
422 trying a directive. This prevents
423 us from polluting the name space. */
424 SKIP_WHITESPACE ();
425 if (is_end_of_line[(unsigned char) *input_line_pointer])
426 {
427 bfd_boolean done = TRUE;
428 *endline = 0;
429
430 if (!strcmp (directive, "no_warn_regname_label"))
431 pru_opt.warn_regname_label = FALSE;
432 else
433 done = FALSE;
434
435 if (done)
436 {
437 *endline = delim;
438 demand_empty_rest_of_line ();
439 return;
440 }
441 }
442
443 /* If we fall through to here, either we have ".set XXX, YYY"
444 or we have ".set XXX" where XXX is unknown or we have
445 a syntax error. */
446 input_line_pointer = save;
447 s_set (equiv);
448}
449
450/* Machine-dependent assembler directives.
451 Format of each entry is:
452 { "directive", handler_func, param } */
453const pseudo_typeS md_pseudo_table[] = {
454 {"align", s_pru_align, 0},
455 {"text", s_pru_text, 0},
456 {"data", s_pru_data, 0},
457 {"section", s_pru_section, 0},
458 {"section.s", s_pru_section, 0},
459 {"sect", s_pru_section, 0},
460 {"sect.s", s_pru_section, 0},
461 /* .dword and .half are included for compatibility with MIPS. */
462 {"dword", cons, 8},
463 {"half", cons, 2},
464 /* PRU native word size is 4 bytes, so we override
465 the GAS default of 2. */
466 {"word", cons, 4},
467 /* Explicitly unaligned directives. */
468 {"2byte", s_pru_ucons, 2},
469 {"4byte", s_pru_ucons, 4},
470 {"8byte", s_pru_ucons, 8},
471 {"16byte", s_pru_ucons, 16},
472 {"set", s_pru_set, 0},
473 {NULL, NULL, 0}
474};
475
476\f
477int
478md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
479 asection *seg ATTRIBUTE_UNUSED)
480{
481 abort ();
482 return 0;
483}
484
485void
486md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED,
487 fragS *fragp ATTRIBUTE_UNUSED)
488{
489 abort ();
490}
491
492\f
493static bfd_boolean
494relaxable_section (asection *sec)
495{
496 return ((sec->flags & SEC_DEBUGGING) == 0
497 && (sec->flags & SEC_CODE) != 0
498 && (sec->flags & SEC_ALLOC) != 0);
499}
500
501/* Does whatever the xtensa port does. */
502int
503pru_validate_fix_sub (fixS *fix)
504{
505 segT add_symbol_segment, sub_symbol_segment;
506
507 /* The difference of two symbols should be resolved by the assembler when
508 linkrelax is not set. If the linker may relax the section containing
509 the symbols, then an Xtensa DIFF relocation must be generated so that
510 the linker knows to adjust the difference value. */
511 if (!linkrelax || fix->fx_addsy == NULL)
512 return 0;
513
514 /* Make sure both symbols are in the same segment, and that segment is
515 "normal" and relaxable. If the segment is not "normal", then the
516 fix is not valid. If the segment is not "relaxable", then the fix
517 should have been handled earlier. */
518 add_symbol_segment = S_GET_SEGMENT (fix->fx_addsy);
519 if (! SEG_NORMAL (add_symbol_segment)
520 || ! relaxable_section (add_symbol_segment))
521 return 0;
522
523 sub_symbol_segment = S_GET_SEGMENT (fix->fx_subsy);
524 return (sub_symbol_segment == add_symbol_segment);
525}
526
527/* TC_FORCE_RELOCATION hook. */
528
529/* If linkrelax is turned on, and the symbol to relocate
530 against is in a relaxable segment, don't compute the value -
531 generate a relocation instead. */
532int
533pru_force_relocation (fixS *fix)
534{
535 if (linkrelax && fix->fx_addsy
536 && relaxable_section (S_GET_SEGMENT (fix->fx_addsy)))
537 return 1;
538
539 return generic_force_reloc (fix);
540}
541
542
543\f
544/** Fixups and overflow checking. */
545
546/* Check a fixup for overflow. */
547static bfd_reloc_status_type
548pru_check_overflow (valueT fixup, reloc_howto_type *howto)
549{
550 bfd_reloc_status_type ret;
551
552 ret = bfd_check_overflow (howto->complain_on_overflow,
553 howto->bitsize,
554 howto->rightshift,
555 bfd_get_reloc_size (howto) * 8,
556 fixup);
557
558 return ret;
559}
560
561/* Emit diagnostic for fixup overflow. */
562static void
563pru_diagnose_overflow (valueT fixup, reloc_howto_type *howto,
564 fixS *fixP, valueT value)
565{
566 if (fixP->fx_r_type == BFD_RELOC_8
567 || fixP->fx_r_type == BFD_RELOC_16
568 || fixP->fx_r_type == BFD_RELOC_32)
569 /* These relocs are against data, not instructions. */
570 as_bad_where (fixP->fx_file, fixP->fx_line,
571 _("immediate value 0x%x truncated to 0x%x"),
572 (unsigned int) fixup,
573 (unsigned int) (~(~(valueT) 0 << howto->bitsize) & fixup));
574 else
575 {
576 /* What opcode is the instruction? This will determine
577 whether we check for overflow in immediate values
578 and what error message we get. */
579 const struct pru_opcode *opcode;
580 enum overflow_type overflow_msg_type;
581 unsigned int range_min;
582 unsigned int range_max;
583 unsigned int address;
584 gas_assert (fixP->fx_size == 4);
585 opcode = pru_find_opcode (value);
586 gas_assert (opcode);
587 overflow_msg_type = opcode->overflow_msg;
588 switch (overflow_msg_type)
589 {
590 case call_target_overflow:
591 range_min
592 = ((fixP->fx_frag->fr_address + fixP->fx_where) & 0xf0000000);
593 range_max = range_min + 0x0fffffff;
594 address = fixup | range_min;
595
596 as_bad_where (fixP->fx_file, fixP->fx_line,
597 _("call target address 0x%08x out of range 0x%08x to 0x%08x"),
598 address, range_min, range_max);
599 break;
600 case qbranch_target_overflow:
601 as_bad_where (fixP->fx_file, fixP->fx_line,
602 _("quick branch offset %d out of range %d to %d"),
603 (int)fixup, -((1<<9) * 4), (1 << 9) * 4);
604 break;
605 case address_offset_overflow:
606 as_bad_where (fixP->fx_file, fixP->fx_line,
607 _("%s offset %d out of range %d to %d"),
608 opcode->name, (int)fixup, -32768, 32767);
609 break;
610 case signed_immed16_overflow:
611 as_bad_where (fixP->fx_file, fixP->fx_line,
612 _("immediate value %d out of range %d to %d"),
613 (int)fixup, -32768, 32767);
614 break;
615 case unsigned_immed32_overflow:
616 as_bad_where (fixP->fx_file, fixP->fx_line,
617 _("immediate value %llu out of range %u to %lu"),
618 (unsigned long long)fixup, 0, 0xfffffffflu);
619 break;
620 case unsigned_immed16_overflow:
621 as_bad_where (fixP->fx_file, fixP->fx_line,
622 _("immediate value %u out of range %u to %u"),
623 (unsigned int)fixup, 0, 65535);
624 break;
625 case unsigned_immed5_overflow:
626 as_bad_where (fixP->fx_file, fixP->fx_line,
627 _("immediate value %u out of range %u to %u"),
628 (unsigned int)fixup, 0, 31);
629 break;
630 default:
631 as_bad_where (fixP->fx_file, fixP->fx_line,
632 _("overflow in immediate argument"));
633 break;
634 }
635 }
636}
637
638/* Apply a fixup to the object file. */
639void
640md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
641{
642 unsigned char *where;
643 valueT value = *valP;
644 long n;
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. */
803 fixup = ((offsetT)fixup) >> howto->rightshift;
804
805 /* Truncate the fixup to right size. */
806 n = sizeof (fixup) * 8 - howto->bitsize;
807 fixup = (fixup << n) >> n;
808
809 /* Fix up the instruction. Non-contiguous bitfields need
810 special handling. */
811 if (fixP->fx_r_type == BFD_RELOC_PRU_S10_PCREL)
812 SET_BROFF_URAW (insn, fixup);
813 else if (fixP->fx_r_type == BFD_RELOC_PRU_LDI32)
814 {
815 /* As the only 64-bit "insn", LDI32 needs special handling. */
816 uint32_t insn1 = insn & 0xffffffff;
817 uint32_t insn2 = insn >> 32;
818 SET_INSN_FIELD (IMM16, insn1, fixup & 0xffff);
819 SET_INSN_FIELD (IMM16, insn2, fixup >> 16);
820 insn = insn1 | ((uint64_t)insn2 << 32);
821 }
822 else
823 insn = (insn & ~howto->dst_mask) | (fixup << howto->bitpos);
824 md_number_to_chars (buf, insn, fixP->fx_size);
825 }
826
827 fixP->fx_done = 1;
828 }
829
830 if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
831 {
832 fixP->fx_done = 0;
833 if (fixP->fx_addsy
834 && !S_IS_DEFINED (fixP->fx_addsy) && !S_IS_WEAK (fixP->fx_addsy))
835 S_SET_WEAK (fixP->fx_addsy);
836 }
837 else if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
838 fixP->fx_done = 0;
839}
840
841
842\f
843/** Instruction parsing support. */
844
845/* Creates a new pru_insn_relocS and returns a pointer to it. */
846static pru_insn_relocS *
847pru_insn_reloc_new (bfd_reloc_code_real_type reloc_type, unsigned int pcrel)
848{
849 pru_insn_relocS *retval;
850 retval = XNEW (pru_insn_relocS);
851 if (retval == NULL)
852 {
853 as_bad (_("can't create relocation"));
854 abort ();
855 }
856
857 /* Fill out the fields with default values. */
858 retval->reloc_next = NULL;
859 retval->reloc_type = reloc_type;
860 retval->reloc_pcrel = pcrel;
861 return retval;
862}
863
864/* Frees up memory previously allocated by pru_insn_reloc_new (). */
865static void
866pru_insn_reloc_destroy (pru_insn_relocS *reloc)
867{
868 pru_insn_relocS *next;
869
870 while (reloc)
871 {
872 next = reloc->reloc_next;
873 free (reloc);
874 reloc = next;
875 }
876}
877
878/* The various pru_assemble_* functions call this
879 function to generate an expression from a string representing an expression.
880 It then tries to evaluate the expression, and if it can, returns its value.
881 If not, it creates a new pru_insn_relocS and stores the expression and
882 reloc_type for future use. */
883static unsigned long
884pru_assemble_expression (const char *exprstr,
885 pru_insn_infoS *insn,
886 pru_insn_relocS *prev_reloc,
887 bfd_reloc_code_real_type reloc_type,
888 unsigned int pcrel)
889{
890 expressionS *ep;
891 pru_insn_relocS *reloc;
892 char *saved_line_ptr;
893 unsigned short value;
894
895 gas_assert (exprstr != NULL);
896 gas_assert (insn != NULL);
897
898 /* We use this blank keyword to distinguish register from
899 label operands. */
900 if (strstr (exprstr, "%label") != NULL)
901 {
902 exprstr += strlen ("%label") + 1;
903 }
904
905 /* Check for pmem relocation operator.
906 Change the relocation type and advance the ptr to the start of
907 the expression proper. */
908 if (strstr (exprstr, "%pmem") != NULL)
909 {
910 reloc_type = BFD_RELOC_PRU_U16_PMEMIMM;
911 exprstr += strlen ("%pmem") + 1;
912 }
913
914 /* We potentially have a relocation. */
915 reloc = pru_insn_reloc_new (reloc_type, pcrel);
916 if (prev_reloc != NULL)
917 prev_reloc->reloc_next = reloc;
918 else
919 insn->insn_reloc = reloc;
920
921 /* Parse the expression string. */
922 ep = &reloc->reloc_expression;
923 saved_line_ptr = input_line_pointer;
924 input_line_pointer = (char *) exprstr;
925 SKIP_WHITESPACE ();
926 expression (ep);
927 SKIP_WHITESPACE ();
928 if (*input_line_pointer)
929 as_bad (_("trailing garbage after expression: %s"), input_line_pointer);
930 input_line_pointer = saved_line_ptr;
931
932
933 if (ep->X_op == O_illegal || ep->X_op == O_absent)
934 as_bad (_("expected expression, got %s"), exprstr);
935
936 /* This is redundant as the fixup will put this into
937 the instruction, but it is included here so that
938 self-test mode (-r) works. */
939 value = 0;
940 if (pru_mode == PRU_MODE_TEST && ep->X_op == O_constant)
941 value = ep->X_add_number;
942
943 return (unsigned long) value;
944}
945
946/* Try to parse a non-relocatable expression. */
947static unsigned long
948pru_assemble_noreloc_expression (const char *exprstr)
949{
950 expressionS exp;
951 char *saved_line_ptr;
952 unsigned long val;
953
954 gas_assert (exprstr != NULL);
955
956 saved_line_ptr = input_line_pointer;
957 input_line_pointer = (char *) exprstr;
958 SKIP_WHITESPACE ();
959 expression (&exp);
960 SKIP_WHITESPACE ();
961 if (*input_line_pointer)
962 as_bad (_("trailing garbage after expression: %s"), input_line_pointer);
963 input_line_pointer = saved_line_ptr;
964
965 val = 0;
966 if (exp.X_op != O_constant)
967 as_bad (_("expected constant expression, got %s"), exprstr);
968 else
969 val = exp.X_add_number;
970
971 return val;
972}
973
974/* Argument assemble functions.
975 All take an instruction argument string, and a pointer
976 to an instruction opcode. Upon return the insn_opcode
977 has the relevant fields filled in to represent the arg
978 string. The return value is NULL if successful, or
979 an error message if an error was detected. */
980
981static void
982pru_assemble_arg_d (pru_insn_infoS *insn_info, const char *argstr)
983{
984 struct pru_reg *dst = pru_reg_lookup (argstr);
985
986 if (dst == NULL)
987 as_bad (_("unknown register %s"), argstr);
988 else
989 {
990 SET_INSN_FIELD (RD, insn_info->insn_code, dst->index);
991 SET_INSN_FIELD (RDSEL, insn_info->insn_code, dst->regsel);
992 }
993}
994
995static void
996pru_assemble_arg_D (pru_insn_infoS *insn_info, const char *argstr)
997{
998 struct pru_reg *dst;
999
1000 /* The leading & before an address register is optional. */
1001 if (*argstr == '&')
1002 argstr++;
1003
1004 dst = pru_reg_lookup (argstr);
1005
1006 if (dst == NULL)
1007 as_bad (_("unknown register %s"), argstr);
1008 else
1009 {
1010 unsigned long rxb = 0;
1011
1012 switch (dst->regsel)
1013 {
1014 case RSEL_31_0: rxb = 0; break; /* whole register defaults to .b0 */
1015 case RSEL_7_0: rxb = 0; break;
1016 case RSEL_15_8: rxb = 1; break;
1017 case RSEL_23_16: rxb = 2; break;
1018 case RSEL_31_24: rxb = 3; break;
1019 default:
1020 as_bad (_("data transfer register cannot be halfword"));
1021 }
1022
1023 SET_INSN_FIELD (RD, insn_info->insn_code, dst->index);
1024 SET_INSN_FIELD (RDB, insn_info->insn_code, rxb);
1025 }
1026}
1027
1028static void
1029pru_assemble_arg_R (pru_insn_infoS *insn_info, const char *argstr)
1030{
1031 struct pru_reg *dst = pru_reg_lookup (argstr);
1032
1033 if (dst == NULL)
1034 as_bad (_("unknown register %s"), argstr);
1035 else
1036 {
1037 if (dst->regsel != RSEL_31_0)
1038 {
1039 as_bad (_("destination register must be full-word"));
1040 }
1041
1042 SET_INSN_FIELD (RD, insn_info->insn_code, dst->index);
1043 SET_INSN_FIELD (RDSEL, insn_info->insn_code, dst->regsel);
1044 }
1045}
1046
1047static void
1048pru_assemble_arg_s (pru_insn_infoS *insn_info, const char *argstr)
1049{
1050 struct pru_reg *src1 = pru_reg_lookup (argstr);
1051
1052 if (src1 == NULL)
1053 as_bad (_("unknown register %s"), argstr);
1054 else
1055 {
1056 SET_INSN_FIELD (RS1, insn_info->insn_code, src1->index);
1057 SET_INSN_FIELD (RS1SEL, insn_info->insn_code, src1->regsel);
1058 }
1059}
1060
1061static void
1062pru_assemble_arg_S (pru_insn_infoS *insn_info, const char *argstr)
1063{
1064 struct pru_reg *src1 = pru_reg_lookup (argstr);
1065
1066 if (src1 == NULL)
1067 as_bad (_("unknown register %s"), argstr);
1068 else
1069 {
1070 if (src1->regsel != RSEL_31_0)
1071 as_bad (_("cannot use partial register %s for addressing"), argstr);
1072 SET_INSN_FIELD (RS1, insn_info->insn_code, src1->index);
1073 }
1074}
1075
1076static void
1077pru_assemble_arg_b (pru_insn_infoS *insn_info, const char *argstr)
1078{
1079 struct pru_reg *src2 = pru_reg_lookup (argstr);
1080 if (src2 == NULL)
1081 {
1082 unsigned long imm8 = pru_assemble_noreloc_expression (argstr);
1083 SET_INSN_FIELD (IMM8, insn_info->insn_code, imm8);
1084 SET_INSN_FIELD (IO, insn_info->insn_code, 1);
1085 }
1086 else
1087 {
1088 SET_INSN_FIELD (IO, insn_info->insn_code, 0);
1089 SET_INSN_FIELD (RS2, insn_info->insn_code, src2->index);
1090 SET_INSN_FIELD (RS2SEL, insn_info->insn_code, src2->regsel);
1091 }
1092
1093}
1094
1095static void
1096pru_assemble_arg_B (pru_insn_infoS *insn_info, const char *argstr)
1097{
1098 struct pru_reg *src2 = pru_reg_lookup (argstr);
1099 if (src2 == NULL)
1100 {
1101 unsigned long imm8;
1102 imm8 = pru_assemble_noreloc_expression (argstr);
1103 if (!imm8 || imm8 > 0xff)
1104 as_bad (_("loop count constant %ld is out of range [1..%d]"),
1105 imm8, 0xff);
1106 /* Note: HW expects the immediate loop count field
1107 to be one less than the actual loop count. */
1108 SET_INSN_FIELD (IMM8, insn_info->insn_code, imm8 - 1);
1109 SET_INSN_FIELD (IO, insn_info->insn_code, 1);
1110 }
1111 else
1112 {
1113 SET_INSN_FIELD (IO, insn_info->insn_code, 0);
1114 SET_INSN_FIELD (RS2, insn_info->insn_code, src2->index);
1115 SET_INSN_FIELD (RS2SEL, insn_info->insn_code, src2->regsel);
1116 }
1117}
1118
1119static void
1120pru_assemble_arg_i (pru_insn_infoS *insn_info, const char *argstr)
1121{
1122 unsigned long imm32;
1123
1124 /* We must not generate PRU_LDI32 relocation if relaxation is disabled in
1125 GAS. Consider the following scenario: GAS relaxation is disabled, so
1126 DIFF* expressions are fixed and not emitted as relocations. Then if LD
1127 has relaxation enabled, it may shorten LDI32 but will not update
1128 accordingly the DIFF expressions. */
1129 if (pru_opt.link_relax)
1130 imm32 = pru_assemble_expression (argstr, insn_info,
1131 insn_info->insn_reloc,
1132 BFD_RELOC_PRU_LDI32, 0);
1133 else
1134 imm32 = pru_assemble_noreloc_expression (argstr);
1135
1136 /* QUIRK: LDI must clear IO bit high, even though it has immediate arg. */
1137 SET_INSN_FIELD (IO, insn_info->insn_code, 0);
1138 SET_INSN_FIELD (IMM16, insn_info->insn_code, imm32 & 0xffff);
1139 insn_info->ldi32_imm32 = imm32;
1140}
1141
1142static void
1143pru_assemble_arg_j (pru_insn_infoS *insn_info, const char *argstr)
1144{
1145 struct pru_reg *src2 = pru_reg_lookup (argstr);
1146
1147 if (src2 == NULL)
1148 {
1149 unsigned long imm16 = pru_assemble_expression (argstr, insn_info,
1150 insn_info->insn_reloc,
1151 BFD_RELOC_PRU_U16_PMEMIMM,
1152 0);
1153 SET_INSN_FIELD (IMM16, insn_info->insn_code, imm16);
1154 SET_INSN_FIELD (IO, insn_info->insn_code, 1);
1155 }
1156 else
1157 {
1158 SET_INSN_FIELD (IO, insn_info->insn_code, 0);
1159 SET_INSN_FIELD (RS2, insn_info->insn_code, src2->index);
1160 SET_INSN_FIELD (RS2SEL, insn_info->insn_code, src2->regsel);
1161 }
1162}
1163
1164static void
1165pru_assemble_arg_W (pru_insn_infoS *insn_info, const char *argstr)
1166{
1167 unsigned long imm16 = pru_assemble_expression (argstr, insn_info,
1168 insn_info->insn_reloc,
1169 BFD_RELOC_PRU_U16, 0);
1170 /* QUIRK: LDI must clear IO bit high, even though it has immediate arg. */
1171 SET_INSN_FIELD (IO, insn_info->insn_code, 0);
1172 SET_INSN_FIELD (IMM16, insn_info->insn_code, imm16);
1173}
1174
1175static void
1176pru_assemble_arg_o (pru_insn_infoS *insn_info, const char *argstr)
1177{
1178 unsigned long imm10 = pru_assemble_expression (argstr, insn_info,
1179 insn_info->insn_reloc,
1180 BFD_RELOC_PRU_S10_PCREL, 1);
1181 SET_BROFF_URAW (insn_info->insn_code, imm10);
1182}
1183
1184static void
1185pru_assemble_arg_O (pru_insn_infoS *insn_info, const char *argstr)
1186{
1187 unsigned long imm8 = pru_assemble_expression (argstr, insn_info,
1188 insn_info->insn_reloc,
1189 BFD_RELOC_PRU_U8_PCREL, 1);
1190 SET_INSN_FIELD (LOOP_JMPOFFS, insn_info->insn_code, imm8);
1191}
1192
1193static void
1194pru_assemble_arg_l (pru_insn_infoS *insn_info, const char *argstr)
1195{
1196 unsigned long burstlen = 0;
1197 struct pru_reg *blreg = pru_reg_lookup (argstr);
1198
1199 if (blreg == NULL)
1200 {
1201 burstlen = pru_assemble_noreloc_expression (argstr);
1202 if (!burstlen || burstlen > LSSBBO_BYTECOUNT_R0_BITS7_0)
1203 as_bad (_("byte count constant %ld is out of range [1..%d]"),
1204 burstlen, LSSBBO_BYTECOUNT_R0_BITS7_0);
1205 burstlen--;
1206 }
1207 else
1208 {
1209 if (blreg->index != 0)
1210 as_bad (_("only r0 can be used as byte count register"));
1211 else if (blreg->regsel > RSEL_31_24)
1212 as_bad (_("only r0.bX byte fields of r0 can be used as byte count"));
1213 else
1214 burstlen = LSSBBO_BYTECOUNT_R0_BITS7_0 + blreg->regsel;
1215 }
1216 SET_BURSTLEN (insn_info->insn_code, burstlen);
1217}
1218
1219static void
1220pru_assemble_arg_n (pru_insn_infoS *insn_info, const char *argstr)
1221{
1222 unsigned long burstlen = 0;
1223 struct pru_reg *blreg = pru_reg_lookup (argstr);
1224
1225 if (blreg == NULL)
1226 {
1227 burstlen = pru_assemble_noreloc_expression (argstr);
1228 if (!burstlen || burstlen > LSSBBO_BYTECOUNT_R0_BITS7_0)
1229 as_bad (_("byte count constant %ld is out of range [1..%d]"),
1230 burstlen, LSSBBO_BYTECOUNT_R0_BITS7_0);
1231 burstlen--;
1232 }
1233 else
1234 {
1235 if (blreg->index != 0)
1236 as_bad (_("only r0 can be used as byte count register"));
1237 else if (blreg->regsel > RSEL_31_24)
1238 as_bad (_("only r0.bX byte fields of r0 can be used as byte count"));
1239 else
1240 burstlen = LSSBBO_BYTECOUNT_R0_BITS7_0 + blreg->regsel;
1241 }
1242 SET_INSN_FIELD (XFR_LENGTH, insn_info->insn_code, burstlen);
1243}
1244
1245static void
1246pru_assemble_arg_c (pru_insn_infoS *insn_info, const char *argstr)
1247{
1248 unsigned long cb = pru_assemble_noreloc_expression (argstr);
1249
1250 if (cb > 31)
1251 as_bad (_("invalid constant table offset %ld"), cb);
1252 else
1253 SET_INSN_FIELD (CB, insn_info->insn_code, cb);
1254}
1255
1256static void
1257pru_assemble_arg_w (pru_insn_infoS *insn_info, const char *argstr)
1258{
1259 unsigned long wk = pru_assemble_noreloc_expression (argstr);
1260
1261 if (wk != 0 && wk != 1)
1262 as_bad (_("invalid WakeOnStatus %ld"), wk);
1263 else
1264 SET_INSN_FIELD (WAKEONSTATUS, insn_info->insn_code, wk);
1265}
1266
1267static void
1268pru_assemble_arg_x (pru_insn_infoS *insn_info, const char *argstr)
1269{
1270 unsigned long wba = pru_assemble_noreloc_expression (argstr);
1271
1272 if (wba > 255)
1273 as_bad (_("invalid XFR WideBus Address %ld"), wba);
1274 else
1275 SET_INSN_FIELD (XFR_WBA, insn_info->insn_code, wba);
1276}
1277
1278/* The function consume_arg takes a pointer into a string
1279 of instruction tokens (args) and a pointer into a string
1280 representing the expected sequence of tokens and separators.
1281 It checks whether the first argument in argstr is of the
1282 expected type, throwing an error if it is not, and returns
1283 the pointer argstr. */
1284static char *
1285pru_consume_arg (char *argstr, const char *parsestr)
1286{
1287 char *temp;
1288
1289 switch (*parsestr)
1290 {
1291 case 'W':
1292 if (*argstr == '%')
1293 {
1294 if (strprefix (argstr, "%pmem") || strprefix (argstr, "%label"))
1295 {
1296 /* We zap the parentheses because we don't want them confused
1297 with separators. */
1298 temp = strchr (argstr, '(');
1299 if (temp != NULL)
1300 *temp = ' ';
1301 temp = strchr (argstr, ')');
1302 if (temp != NULL)
1303 *temp = ' ';
1304 }
1305 else
1306 as_bad (_("badly formed expression near %s"), argstr);
1307 }
1308 break;
1309
1310 case 'j':
1311 case 'o':
1312 case 'O':
1313 if (*argstr == '%')
1314 {
1315 /* Only 'j' really requires %label for distinguishing registers
1316 from labels, but we include 'o' and 'O' here to avoid
1317 confusing assembler programmers. Thus for completeness all
1318 jump operands can be prefixed with %label. */
1319 if (strprefix (argstr, "%label"))
1320 {
1321 /* We zap the parentheses because we don't want them confused
1322 with separators. */
1323 temp = strchr (argstr, '(');
1324 if (temp != NULL)
1325 *temp = ' ';
1326 temp = strchr (argstr, ')');
1327 if (temp != NULL)
1328 *temp = ' ';
1329 }
1330 else
1331 as_bad (_("badly formed expression near %s"), argstr);
1332 }
1333 break;
1334
1335 case 'b':
1336 case 'B':
1337 case 'c':
1338 case 'd':
1339 case 'D':
1340 case 'E':
1341 case 'i':
1342 case 's':
1343 case 'S':
1344 case 'l':
1345 case 'n':
1346 case 'R':
1347 case 'w':
1348 case 'x':
1349 /* We can't have %pmem here. */
1350 if (*argstr == '%')
1351 as_bad (_("badly formed expression near %s"), argstr);
1352 break;
1353 default:
1354 BAD_CASE (*parsestr);
1355 break;
1356 }
1357
1358 return argstr;
1359}
1360
1361/* The function consume_separator takes a pointer into a string
1362 of instruction tokens (args) and a pointer into a string representing
1363 the expected sequence of tokens and separators. It finds the first
1364 instance of the character pointed to by separator in argstr, and
1365 returns a pointer to the next element of argstr, which is the
1366 following token in the sequence. */
1367static char *
1368pru_consume_separator (char *argstr, const char *separator)
1369{
1370 char *p;
1371
1372 p = strchr (argstr, *separator);
1373
1374 if (p != NULL)
1375 *p++ = 0;
1376 else
1377 as_bad (_("expecting %c near %s"), *separator, argstr);
1378 return p;
1379}
1380
1381
1382/* The principal argument parsing function which takes a string argstr
1383 representing the instruction arguments for insn, and extracts the argument
1384 tokens matching parsestr into parsed_args. */
1385static void
1386pru_parse_args (pru_insn_infoS *insn ATTRIBUTE_UNUSED, char *argstr,
1387 const char *parsestr, char **parsed_args)
1388{
1389 char *p;
1390 char *end = NULL;
1391 int i;
1392 p = argstr;
1393 i = 0;
1394 bfd_boolean terminate = FALSE;
1395
1396 /* This rest of this function is it too fragile and it mostly works,
1397 therefore special case this one. */
1398 if (*parsestr == 0 && argstr != 0)
1399 {
1400 as_bad (_("too many arguments"));
1401 parsed_args[0] = NULL;
1402 return;
1403 }
1404
1405 while (p != NULL && !terminate && i < PRU_MAX_INSN_TOKENS)
1406 {
1407 parsed_args[i] = pru_consume_arg (p, parsestr);
1408 ++parsestr;
1409 if (*parsestr != '\0')
1410 {
1411 p = pru_consume_separator (p, parsestr);
1412 ++parsestr;
1413 }
1414 else
1415 {
1416 /* Check that the argument string has no trailing arguments. */
1417 /* If we've got a %pmem relocation, we've zapped the parens with
1418 spaces. */
1419 if (strprefix (p, "%pmem") || strprefix (p, "%label"))
1420 end = strpbrk (p, ",");
1421 else
1422 end = strpbrk (p, " ,");
1423
1424 if (end != NULL)
1425 as_bad (_("too many arguments"));
1426 }
1427
1428 if (*parsestr == '\0' || (p != NULL && *p == '\0'))
1429 terminate = TRUE;
1430 ++i;
1431 }
1432
1433 parsed_args[i] = NULL;
1434
1435 /* There are no instructions with optional arguments; complain. */
1436 if (*parsestr != '\0')
1437 as_bad (_("missing argument"));
1438}
1439
1440\f
1441/** Assembler output support. */
1442
1443/* Output a normal instruction. */
1444static void
1445output_insn (pru_insn_infoS *insn)
1446{
1447 char *f;
1448 pru_insn_relocS *reloc;
1449
1450 f = frag_more (4);
1451 /* This allocates enough space for the instruction
1452 and puts it in the current frag. */
1453 md_number_to_chars (f, insn->insn_code, 4);
1454 /* Emit debug info. */
1455 dwarf2_emit_insn (4);
1456 /* Create any fixups to be acted on later. */
1457 for (reloc = insn->insn_reloc; reloc != NULL; reloc = reloc->reloc_next)
1458 fix_new_exp (frag_now, f - frag_now->fr_literal, 4,
1459 &reloc->reloc_expression, reloc->reloc_pcrel,
1460 reloc->reloc_type);
1461}
1462
1463/* Output two LDI instructions from LDI32 macro */
1464static void
1465output_insn_ldi32 (pru_insn_infoS *insn)
1466{
1467 char *f;
1468 pru_insn_relocS *reloc;
1469 unsigned long insn2;
1470
1471 f = frag_more (8);
1472 md_number_to_chars (f, insn->insn_code, 4);
1473
1474 insn2 = insn->insn_code;
1475 SET_INSN_FIELD (IMM16, insn2, insn->ldi32_imm32 >> 16);
1476 SET_INSN_FIELD (RDSEL, insn2, RSEL_31_16);
1477 md_number_to_chars (f + 4, insn2, 4);
1478
1479 /* Emit debug info. */
1480 dwarf2_emit_insn (8);
1481
1482 /* Create any fixups to be acted on later. */
1483 for (reloc = insn->insn_reloc; reloc != NULL; reloc = reloc->reloc_next)
1484 fix_new_exp (frag_now, f - frag_now->fr_literal, 4,
1485 &reloc->reloc_expression, reloc->reloc_pcrel,
1486 reloc->reloc_type);
1487}
1488
1489\f
1490/** External interfaces. */
1491
1492/* The following functions are called by machine-independent parts of
1493 the assembler. */
1494int
1495md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
1496{
1497 switch (c)
1498 {
1499 case 'r':
1500 /* Hidden option for self-test mode. */
1501 pru_mode = PRU_MODE_TEST;
1502 break;
1503 case OPTION_LINK_RELAX:
1504 pru_opt.link_relax = TRUE;
1505 break;
1506 case OPTION_NO_LINK_RELAX:
1507 pru_opt.link_relax = FALSE;
1508 break;
1509 case OPTION_NO_WARN_REGNAME_LABEL:
1510 pru_opt.warn_regname_label = FALSE;
1511 break;
1512 default:
1513 return 0;
1514 break;
1515 }
1516
1517 return 1;
1518}
1519
1520const char *
1521pru_target_format (void)
1522{
1523 return "elf32-pru";
1524}
1525
1526/* Machine-dependent usage message. */
1527void
1528md_show_usage (FILE *stream)
1529{
1530 fprintf (stream,
1531 _("PRU options:\n"
1532 " -mlink-relax generate relocations for linker relaxation (default).\n"
1533 " -mno-link-relax don't generate relocations for linker relaxation.\n"
1534 ));
1535
1536}
1537
1538/* This function is called once, at assembler startup time.
1539 It should set up all the tables, etc. that the MD part of the
1540 assembler will need. */
1541void
1542md_begin (void)
1543{
1544 int i;
1545 const char *inserted;
1546
1547 /* Create and fill a hashtable for the PRU opcodes, registers and
1548 arguments. */
1549 pru_opcode_hash = hash_new ();
1550 pru_reg_hash = hash_new ();
1551
1552 for (i = 0; i < NUMOPCODES; ++i)
1553 {
1554 inserted
1555 = hash_insert (pru_opcode_hash, pru_opcodes[i].name,
1556 (PTR) & pru_opcodes[i]);
1557 if (inserted != NULL)
1558 {
1559 fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
1560 pru_opcodes[i].name, inserted);
1561 /* Probably a memory allocation problem? Give up now. */
1562 as_fatal (_("Broken assembler. No assembly attempted."));
1563 }
1564 }
1565
1566 for (i = 0; i < pru_num_regs; ++i)
1567 {
1568 inserted
1569 = hash_insert (pru_reg_hash, pru_regs[i].name,
1570 (PTR) & pru_regs[i]);
1571 if (inserted != NULL)
1572 {
1573 fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
1574 pru_regs[i].name, inserted);
1575 /* Probably a memory allocation problem? Give up now. */
1576 as_fatal (_("Broken assembler. No assembly attempted."));
1577 }
1578
1579 }
1580
1581 linkrelax = pru_opt.link_relax;
1582 /* Initialize the alignment data. */
1583 pru_current_align_seg = now_seg;
1584 pru_last_label = NULL;
1585 pru_current_align = 0;
1586}
1587
1588
1589/* Assembles a single line of PRU assembly language. */
1590void
1591md_assemble (char *op_str)
1592{
1593 char *argstr;
1594 char *op_strdup = NULL;
1595 pru_insn_infoS thisinsn;
1596 pru_insn_infoS *insn = &thisinsn;
1597
1598 /* Make sure we are aligned on a 4-byte boundary. */
1599 if (pru_current_align < 2)
1600 pru_align (2, NULL, pru_last_label);
1601 else if (pru_current_align > 2)
1602 pru_current_align = 2;
1603 pru_last_label = NULL;
1604
1605 /* We don't want to clobber to op_str
1606 because we want to be able to use it in messages. */
1607 op_strdup = strdup (op_str);
1608 insn->insn_tokens[0] = strtok (op_strdup, " ");
1609 argstr = strtok (NULL, "");
1610
1611 /* Assemble the opcode. */
1612 insn->insn_pru_opcode = pru_opcode_lookup (insn->insn_tokens[0]);
1613 insn->insn_reloc = NULL;
1614
1615 if (insn->insn_pru_opcode != NULL)
1616 {
1617 const char *argsfmt = insn->insn_pru_opcode->args;
1618 const char **argtk = &insn->insn_tokens[1];
1619 const char *argp;
1620
1621 /* Set the opcode for the instruction. */
1622 insn->insn_code = insn->insn_pru_opcode->match;
1623
1624 if (pru_mode == PRU_MODE_TEST)
1625 {
1626 /* Add the "expected" instruction parameter used for validation. */
1627 argsfmt = malloc (strlen (argsfmt) + 3);
1628 sprintf ((char *)argsfmt, "%s,E", insn->insn_pru_opcode->args);
1629 }
1630 pru_parse_args (insn, argstr, argsfmt,
1631 (char **) &insn->insn_tokens[1]);
1632
1633 for (argp = argsfmt; !had_errors () && *argp && *argtk; ++argp)
1634 {
1635 gas_assert (argtk <= &insn->insn_tokens[PRU_MAX_INSN_TOKENS]);
1636
1637 switch (*argp)
1638 {
1639 case ',':
1640 continue;
1641
1642 case 'd':
1643 pru_assemble_arg_d (insn, *argtk++);
1644 continue;
1645 case 'D':
1646 pru_assemble_arg_D (insn, *argtk++);
1647 continue;
1648 case 'R':
1649 pru_assemble_arg_R (insn, *argtk++);
1650 continue;
1651 case 's':
1652 pru_assemble_arg_s (insn, *argtk++);
1653 continue;
1654 case 'S':
1655 pru_assemble_arg_S (insn, *argtk++);
1656 continue;
1657 case 'b':
1658 pru_assemble_arg_b (insn, *argtk++);
1659 continue;
1660 case 'B':
1661 pru_assemble_arg_B (insn, *argtk++);
1662 continue;
1663 case 'i':
1664 pru_assemble_arg_i (insn, *argtk++);
1665 continue;
1666 case 'j':
1667 pru_assemble_arg_j (insn, *argtk++);
1668 continue;
1669 case 'W':
1670 pru_assemble_arg_W (insn, *argtk++);
1671 continue;
1672 case 'o':
1673 pru_assemble_arg_o (insn, *argtk++);
1674 continue;
1675 case 'O':
1676 pru_assemble_arg_O (insn, *argtk++);
1677 continue;
1678 case 'l':
1679 pru_assemble_arg_l (insn, *argtk++);
1680 continue;
1681 case 'n':
1682 pru_assemble_arg_n (insn, *argtk++);
1683 continue;
1684 case 'c':
1685 pru_assemble_arg_c (insn, *argtk++);
1686 continue;
1687 case 'w':
1688 pru_assemble_arg_w (insn, *argtk++);
1689 continue;
1690 case 'x':
1691 pru_assemble_arg_x (insn, *argtk++);
1692 continue;
1693
1694 case 'E':
1695 pru_check_assembly (insn->insn_code, *argtk++);
1696 default:
1697 BAD_CASE (*argp);
1698 }
1699 }
1700
1701 if (*argp && !had_errors ())
1702 as_bad (_("missing argument"));
1703
1704 if (!had_errors ())
1705 {
1706 if (insn->insn_pru_opcode->pinfo & PRU_INSN_LDI32)
1707 {
1708 output_insn_ldi32 (insn);
1709 }
1710 else
1711 {
1712 output_insn (insn);
1713 }
1714 }
1715
1716 if (pru_mode == PRU_MODE_TEST)
1717 free ((char *)argsfmt);
1718 }
1719 else
1720 /* Unrecognised instruction - error. */
1721 as_bad (_("unrecognised instruction %s"), insn->insn_tokens[0]);
1722
1723 /* Don't leak memory. */
1724 pru_insn_reloc_destroy (insn->insn_reloc);
1725 free (op_strdup);
1726}
1727
1728/* Round up section size. */
1729valueT
1730md_section_align (asection *seg, valueT addr)
1731{
1732 int align = bfd_get_section_alignment (stdoutput, seg);
1733 return ((addr + (1 << align) - 1) & (-((valueT) 1 << align)));
1734}
1735
1736/* Implement tc_fix_adjustable. */
1737int
1738pru_fix_adjustable (fixS *fixp)
1739{
1740 if (fixp->fx_addsy == NULL)
1741 return 1;
1742
1743 /* Prevent all adjustments to global symbols. */
1744 if (OUTPUT_FLAVOR == bfd_target_elf_flavour
1745 && (S_IS_EXTERNAL (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)))
1746 return 0;
1747
1748 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
1749 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1750 return 0;
1751
1752 /* Preserve relocations against symbols with function type. */
1753 if (symbol_get_bfdsym (fixp->fx_addsy)->flags & BSF_FUNCTION)
1754 return 0;
1755
1756 return 1;
1757}
1758
1759/* The function tc_gen_reloc creates a relocation structure for the
1760 fixup fixp, and returns a pointer to it. This structure is passed
1761 to bfd_install_relocation so that it can be written to the object
1762 file for linking. */
1763arelent *
1764tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
1765{
1766 arelent *reloc = XNEW (arelent);
1767 reloc->sym_ptr_ptr = XNEW (asymbol *);
1768 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1769
1770 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1771 reloc->addend = fixp->fx_offset; /* fixp->fx_addnumber; */
1772
1773 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1774 if (reloc->howto == NULL)
1775 {
1776 as_bad_where (fixp->fx_file, fixp->fx_line,
1777 _("can't represent relocation type %s"),
1778 bfd_get_reloc_code_name (fixp->fx_r_type));
1779
1780 /* Set howto to a garbage value so that we can keep going. */
1781 reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
1782 gas_assert (reloc->howto != NULL);
1783 }
1784 return reloc;
1785}
1786
1787long
1788md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
1789{
1790 return fixP->fx_where + fixP->fx_frag->fr_address;
1791}
1792
1793/* Called just before the assembler exits. */
1794void
1795md_end (void)
1796{
1797 hash_die (pru_opcode_hash);
1798 hash_die (pru_reg_hash);
1799}
1800
1801symbolS *
1802md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1803{
1804 return NULL;
1805}
1806
1807/* Implement tc_frob_label. */
1808void
1809pru_frob_label (symbolS *lab)
1810{
1811 /* Emit dwarf information. */
1812 dwarf2_emit_label (lab);
1813
1814 /* Update the label's address with the current output pointer. */
1815 symbol_set_frag (lab, frag_now);
1816 S_SET_VALUE (lab, (valueT) frag_now_fix ());
1817
1818 /* Record this label for future adjustment after we find out what
1819 kind of data it references, and the required alignment therewith. */
1820 pru_last_label = lab;
1821
1822 if (pru_opt.warn_regname_label && pru_reg_lookup (S_GET_NAME (lab)))
1823 as_warn (_("Label \"%s\" matches a CPU register name"), S_GET_NAME (lab));
1824}
1825
1826static inline char *
1827skip_space (char *s)
1828{
1829 while (*s == ' ' || *s == '\t')
1830 ++s;
1831 return s;
1832}
1833
1834/* Parse special CONS expression: pmem (expression). Idea from AVR.
1835
1836 Used to catch and mark code (program memory) in constant expression
1837 relocations. Return non-zero for program memory. */
1838
1839int
1840pru_parse_cons_expression (expressionS *exp, int nbytes)
1841{
1842 int is_pmem = FALSE;
1843 char *tmp;
1844
1845 tmp = input_line_pointer = skip_space (input_line_pointer);
1846
1847 if (nbytes == 4 || nbytes == 2)
1848 {
1849 const char *pmem_str = "%pmem";
1850 int len = strlen (pmem_str);
1851
1852 if (strncasecmp (input_line_pointer, pmem_str, len) == 0)
1853 {
1854 input_line_pointer = skip_space (input_line_pointer + len);
1855
1856 if (*input_line_pointer == '(')
1857 {
1858 input_line_pointer = skip_space (input_line_pointer + 1);
1859 is_pmem = TRUE;
1860 expression (exp);
1861
1862 if (*input_line_pointer == ')')
1863 ++input_line_pointer;
1864 else
1865 {
1866 as_bad (_("`)' required"));
1867 is_pmem = FALSE;
1868 }
1869
1870 return is_pmem;
1871 }
1872
1873 input_line_pointer = tmp;
1874 }
1875 }
1876
1877 expression (exp);
1878
1879 return is_pmem;
1880}
1881
1882/* Implement TC_CONS_FIX_NEW. */
1883void
1884pru_cons_fix_new (fragS *frag, int where, unsigned int nbytes,
1885 expressionS *exp, const int is_pmem)
1886{
1887 bfd_reloc_code_real_type r;
1888
1889 switch (nbytes | (!!is_pmem << 8))
1890 {
1891 case 1 | (0 << 8): r = BFD_RELOC_8; break;
1892 case 2 | (0 << 8): r = BFD_RELOC_16; break;
1893 case 4 | (0 << 8): r = BFD_RELOC_32; break;
1894 case 8 | (0 << 8): r = BFD_RELOC_64; break;
1895 case 2 | (1 << 8): r = BFD_RELOC_PRU_16_PMEM; break;
1896 case 4 | (1 << 8): r = BFD_RELOC_PRU_32_PMEM; break;
1897 default:
1898 as_bad (_("illegal %s relocation size: %d"),
1899 is_pmem ? "text" : "data", nbytes);
1900 return;
1901 }
1902
1903 fix_new_exp (frag, where, (int) nbytes, exp, 0, r);
1904}
1905
1906/* Implement tc_regname_to_dw2regnum, to convert REGNAME to a DWARF-2
1907 register number. */
1908int
1909pru_regname_to_dw2regnum (char *regname)
1910{
1911 struct pru_reg *r = pru_reg_lookup (regname);
1912 if (r == NULL)
1913 return -1;
1914 return r->index;
1915}
1916
1917/* Implement tc_cfi_frame_initial_instructions, to initialize the DWARF-2
1918 unwind information for this procedure. */
1919void
1920pru_frame_initial_instructions (void)
1921{
1922 const unsigned fp_regno = 4;
1923 cfi_add_CFA_def_cfa (fp_regno, 0);
1924}
1925
1926bfd_boolean
1927pru_allow_local_subtract (expressionS * left,
1928 expressionS * right,
1929 segT section)
1930{
1931 /* If we are not in relaxation mode, subtraction is OK. */
1932 if (!linkrelax)
1933 return TRUE;
1934
1935 /* If the symbols are not in a code section then they are OK. */
1936 if ((section->flags & SEC_CODE) == 0)
1937 return TRUE;
1938
1939 if (left->X_add_symbol == right->X_add_symbol)
1940 return TRUE;
1941
1942 /* We have to assume that there may be instructions between the
1943 two symbols and that relaxation may increase the distance between
1944 them. */
1945 return FALSE;
1946}