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