blob: c5095ebe8af31dc31284d563c7e577255104508f [file] [log] [blame]
Raymes Khoury24354f72011-08-22 22:03:561/* TI C6X assembler.
2 Copyright 2010
3 Free Software Foundation, Inc.
4 Contributed by Joseph Myers <[email protected]>
5 Bernd Schmidt <[email protected]>
6
7 This file is part of GAS, the GNU Assembler.
8
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
12 any later version.
13
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to the Free
21 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
23
24#include "as.h"
25#include "dwarf2dbg.h"
26#include "safe-ctype.h"
27#include "subsegs.h"
28#include "opcode/tic6x.h"
29#include "elf/tic6x.h"
30#include "elf32-tic6x.h"
31
32/* Truncate and sign-extend at 32 bits, so that building on a 64-bit
33 host gives identical results to a 32-bit host. */
34#define TRUNC(X) ((valueT) (X) & 0xffffffffU)
35#define SEXT(X) ((TRUNC (X) ^ 0x80000000U) - 0x80000000U)
36
37const char comment_chars[] = ";";
38const char line_comment_chars[] = "#*;";
39const char line_separator_chars[] = "@";
40
41const char EXP_CHARS[] = "eE";
42const char FLT_CHARS[] = "dDfF";
43
44const char *md_shortopts = "";
45
46enum
47 {
48 OPTION_MARCH = OPTION_MD_BASE,
49 OPTION_MATOMIC,
50 OPTION_MNO_ATOMIC,
51 OPTION_MBIG_ENDIAN,
52 OPTION_MLITTLE_ENDIAN,
53 OPTION_MDSBT,
54 OPTION_MNO_DSBT,
55 OPTION_MPID,
56 OPTION_MPIC,
57 OPTION_MNO_PIC,
58 OPTION_MGENERATE_REL
59 };
60
61struct option md_longopts[] =
62 {
63 { "march", required_argument, NULL, OPTION_MARCH },
64 { "matomic", no_argument, NULL, OPTION_MATOMIC },
65 { "mno-atomic", no_argument, NULL, OPTION_MNO_ATOMIC },
66 { "mbig-endian", no_argument, NULL, OPTION_MBIG_ENDIAN },
67 { "mlittle-endian", no_argument, NULL, OPTION_MLITTLE_ENDIAN },
68 { "mdsbt", no_argument, NULL, OPTION_MDSBT },
69 { "mno-dsbt", no_argument, NULL, OPTION_MNO_DSBT },
70 { "mpid", required_argument, NULL, OPTION_MPID },
71 { "mpic", no_argument, NULL, OPTION_MPIC },
72 { "mno-pic", no_argument, NULL, OPTION_MNO_PIC },
73 { "mgenerate-rel", no_argument, NULL, OPTION_MGENERATE_REL },
74 { NULL, no_argument, NULL, 0 }
75 };
76size_t md_longopts_size = sizeof (md_longopts);
77
78/* Whether to enable atomic instructions. 1 to enable them, 0 to
79 disable, -1 to default from architecture. */
80static int tic6x_atomic = -1;
81
82/* The instructions enabled based only on the selected architecture
83 (all instructions, if no architecture specified). Atomic
84 instructions may be enabled or disabled separately. */
85static unsigned short tic6x_arch_enable = (TIC6X_INSN_C62X
86 | TIC6X_INSN_C64X
87 | TIC6X_INSN_C64XP
88 | TIC6X_INSN_C67X
89 | TIC6X_INSN_C67XP
90 | TIC6X_INSN_C674X
91 | TIC6X_INSN_ATOMIC);
92
93/* The instructions enabled based on the current set of features
94 (architecture, as modified by other options). */
95static unsigned short tic6x_features;
96
97/* The architecture attribute value, or C6XABI_Tag_ISA_none if
98 not yet set. */
99static int tic6x_arch_attribute = C6XABI_Tag_ISA_none;
100
101/* Whether any instructions at all have been seen. Once any
102 instructions have been seen, architecture attributes merge into the
103 previous attribute value rather than replacing it. */
104static bfd_boolean tic6x_seen_insns = FALSE;
105
106/* The number of registers in each register file supported by the
107 current architecture. */
108static unsigned int tic6x_num_registers;
109
110/* Whether predication on A0 is possible. */
111static bfd_boolean tic6x_predicate_a0;
112
113/* Whether execute packets can cross fetch packet boundaries. */
114static bfd_boolean tic6x_can_cross_fp_boundary;
115
116/* Whether there are constraints on simultaneous reads and writes of
117 40-bit data. */
118static bfd_boolean tic6x_long_data_constraints;
119
120/* Whether compact instructions are available. */
121static bfd_boolean tic6x_compact_insns;
122
123/* Whether to generate RELA relocations. */
124static bfd_boolean tic6x_generate_rela = TRUE;
125
126/* Whether the code uses DSBT addressing. */
127static bfd_boolean tic6x_dsbt;
128
129/* Types of position-independent data (attribute values for
130 Tag_ABI_PID). */
131typedef enum
132 {
133 tic6x_pid_no = 0,
134 tic6x_pid_near = 1,
135 tic6x_pid_far = 2
136 } tic6x_pid_type;
137
138/* The type of data addressing used in this code. */
139static tic6x_pid_type tic6x_pid;
140
141/* Whether the code uses position-independent code. */
142static bfd_boolean tic6x_pic;
143
144/* Table of supported architecture variants. */
145typedef struct
146{
147 const char *arch;
148 int attr;
149 unsigned short features;
150} tic6x_arch_table;
151static const tic6x_arch_table tic6x_arches[] =
152 {
153 { "c62x", C6XABI_Tag_ISA_C62X, TIC6X_INSN_C62X },
154 { "c64x", C6XABI_Tag_ISA_C64X, TIC6X_INSN_C62X | TIC6X_INSN_C64X },
155 { "c64x+", C6XABI_Tag_ISA_C64XP, (TIC6X_INSN_C62X
156 | TIC6X_INSN_C64X
157 | TIC6X_INSN_C64XP) },
158 { "c67x", C6XABI_Tag_ISA_C67X, TIC6X_INSN_C62X | TIC6X_INSN_C67X },
159 { "c67x+", C6XABI_Tag_ISA_C67XP, (TIC6X_INSN_C62X
160 | TIC6X_INSN_C67X
161 | TIC6X_INSN_C67XP) },
162 { "c674x", C6XABI_Tag_ISA_C674X, (TIC6X_INSN_C62X
163 | TIC6X_INSN_C64X
164 | TIC6X_INSN_C64XP
165 | TIC6X_INSN_C67X
166 | TIC6X_INSN_C67XP
167 | TIC6X_INSN_C674X) }
168 };
169
170/* Update the selected architecture based on ARCH, giving an error if
171 ARCH is an invalid value. Does not call tic6x_update_features; the
172 caller must do that if necessary. */
173
174static void
175tic6x_use_arch (const char *arch)
176{
177 unsigned int i;
178
179 for (i = 0; i < ARRAY_SIZE (tic6x_arches); i++)
180 if (strcmp (arch, tic6x_arches[i].arch) == 0)
181 {
182 tic6x_arch_enable = tic6x_arches[i].features;
183 if (tic6x_seen_insns)
184 tic6x_arch_attribute
185 = elf32_tic6x_merge_arch_attributes (tic6x_arch_attribute,
186 tic6x_arches[i].attr);
187 else
188 tic6x_arch_attribute = tic6x_arches[i].attr;
189 return;
190 }
191
192 as_bad (_("unknown architecture '%s'"), arch);
193}
194
195/* Table of supported -mpid arguments. */
196typedef struct
197{
198 const char *arg;
199 tic6x_pid_type attr;
200} tic6x_pid_type_table;
201static const tic6x_pid_type_table tic6x_pid_types[] =
202 {
203 { "no", tic6x_pid_no },
204 { "near", tic6x_pid_near },
205 { "far", tic6x_pid_far }
206 };
207
208/* Handle -mpid=ARG. */
209
210static void
211tic6x_use_pid (const char *arg)
212{
213 unsigned int i;
214
215 for (i = 0; i < ARRAY_SIZE (tic6x_pid_types); i++)
216 if (strcmp (arg, tic6x_pid_types[i].arg) == 0)
217 {
218 tic6x_pid = tic6x_pid_types[i].attr;
219 return;
220 }
221
222 as_bad (_("unknown -mpid= argument '%s'"), arg);
223}
224
225/* Parse a target-specific option. */
226
227int
228md_parse_option (int c, char *arg)
229{
230 switch (c)
231 {
232 case OPTION_MARCH:
233 tic6x_use_arch (arg);
234 break;
235
236 case OPTION_MATOMIC:
237 tic6x_atomic = 1;
238 break;
239
240 case OPTION_MNO_ATOMIC:
241 tic6x_atomic = 0;
242 break;
243
244 case OPTION_MBIG_ENDIAN:
245 target_big_endian = 1;
246 break;
247
248 case OPTION_MLITTLE_ENDIAN:
249 target_big_endian = 0;
250 break;
251
252 case OPTION_MDSBT:
253 tic6x_dsbt = 1;
254 break;
255
256 case OPTION_MNO_DSBT:
257 tic6x_dsbt = 0;
258 break;
259
260 case OPTION_MPID:
261 tic6x_use_pid (arg);
262 break;
263
264 case OPTION_MPIC:
265 tic6x_pic = 1;
266 break;
267
268 case OPTION_MNO_PIC:
269 tic6x_pic = 0;
270 break;
271
272 case OPTION_MGENERATE_REL:
273 tic6x_generate_rela = FALSE;
274 break;
275
276 default:
277 return 0;
278 }
279 return 1;
280}
281
282void
283md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
284{
285 unsigned int i;
286
287 fputc ('\n', stream);
288 fprintf (stream, _("TMS320C6000 options:\n"));
289 fprintf (stream, _(" -march=ARCH enable instructions from architecture ARCH\n"));
290 fprintf (stream, _(" -matomic enable atomic operation instructions\n"));
291 fprintf (stream, _(" -mno-atomic disable atomic operation instructions\n"));
292 fprintf (stream, _(" -mbig-endian generate big-endian code\n"));
293 fprintf (stream, _(" -mlittle-endian generate little-endian code\n"));
294 fprintf (stream, _(" -mdsbt code uses DSBT addressing\n"));
295 fprintf (stream, _(" -mno-dsbt code does not use DSBT addressing\n"));
296 fprintf (stream, _(" -mpid=no code uses position-dependent data addressing\n"));
297 fprintf (stream, _(" -mpid=near code uses position-independent data addressing,\n"
298 " GOT accesses use near DP addressing\n"));
299 fprintf (stream, _(" -mpid=far code uses position-independent data addressing,\n"
300 " GOT accesses use far DP addressing\n"));
301 fprintf (stream, _(" -mpic code addressing is position-independent\n"));
302 fprintf (stream, _(" -mno-pic code addressing is position-dependent\n"));
303 /* -mgenerate-rel is only for testsuite use and is deliberately
304 undocumented. */
305
306 fputc ('\n', stream);
307 fprintf (stream, _("Supported ARCH values are:"));
308 for (i = 0; i < ARRAY_SIZE (tic6x_arches); i++)
309 fprintf (stream, " %s", tic6x_arches[i].arch);
310 fputc ('\n', stream);
311}
312
313/* Update enabled features based on the current architecture and
314 related settings. */
315static void
316tic6x_update_features (void)
317{
318 switch (tic6x_atomic)
319 {
320 case -1:
321 tic6x_features = tic6x_arch_enable;
322 break;
323
324 case 0:
325 tic6x_features = tic6x_arch_enable & ~TIC6X_INSN_ATOMIC;
326 break;
327
328 case 1:
329 tic6x_features = tic6x_arch_enable | TIC6X_INSN_ATOMIC;
330 break;
331
332 default:
333 abort ();
334 }
335
336 tic6x_num_registers
337 = (tic6x_arch_enable & (TIC6X_INSN_C64X | TIC6X_INSN_C67XP)) ? 32 : 16;
338
339 tic6x_predicate_a0 = (tic6x_arch_enable & TIC6X_INSN_C64X) ? TRUE : FALSE;
340
341 tic6x_can_cross_fp_boundary
342 = (tic6x_arch_enable
343 & (TIC6X_INSN_C64X | TIC6X_INSN_C67XP)) ? TRUE : FALSE;
344
345 tic6x_long_data_constraints
346 = (tic6x_arch_enable & TIC6X_INSN_C64X) ? FALSE : TRUE;
347
348 tic6x_compact_insns = (tic6x_arch_enable & TIC6X_INSN_C64XP) ? TRUE : FALSE;
349}
350
351/* Do configuration after all options have been parsed. */
352
353void
354tic6x_after_parse_args (void)
355{
356 tic6x_update_features ();
357}
358
359/* Parse a .arch directive. */
360
361static void
362s_tic6x_arch (int ignored ATTRIBUTE_UNUSED)
363{
364 char c;
365 char *arch;
366
367 arch = input_line_pointer;
368 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
369 input_line_pointer++;
370 c = *input_line_pointer;
371 *input_line_pointer = 0;
372
373 tic6x_use_arch (arch);
374 tic6x_update_features ();
375 *input_line_pointer = c;
376 demand_empty_rest_of_line ();
377}
378
379/* Parse a .atomic directive. */
380
381static void
382s_tic6x_atomic (int ignored ATTRIBUTE_UNUSED)
383{
384 tic6x_atomic = 1;
385 tic6x_update_features ();
386 demand_empty_rest_of_line ();
387}
388
389/* Parse a .noatomic directive. */
390
391static void
392s_tic6x_noatomic (int ignored ATTRIBUTE_UNUSED)
393{
394 tic6x_atomic = 0;
395 tic6x_update_features ();
396 demand_empty_rest_of_line ();
397}
398
399/* Parse a .nocmp directive. */
400
401static void
402s_tic6x_nocmp (int ignored ATTRIBUTE_UNUSED)
403{
404 seg_info (now_seg)->tc_segment_info_data.nocmp = TRUE;
405 demand_empty_rest_of_line ();
406}
407
408/* Track for each attribute whether it has been set explicitly (and so
409 should not have a default value set by the assembler). */
410static bfd_boolean tic6x_attributes_set_explicitly[NUM_KNOWN_OBJ_ATTRIBUTES];
411
412/* Parse a .c6xabi_attribute directive. */
413
414static void
415s_tic6x_c6xabi_attribute (int ignored ATTRIBUTE_UNUSED)
416{
417 int tag = s_vendor_attribute (OBJ_ATTR_PROC);
418
419 if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
420 tic6x_attributes_set_explicitly[tag] = TRUE;
421}
422
423typedef struct
424{
425 const char *name;
426 int tag;
427} tic6x_attribute_table;
428
429static const tic6x_attribute_table tic6x_attributes[] =
430 {
431#define TAG(tag, value) { #tag, tag },
432#include "elf/tic6x-attrs.h"
433#undef TAG
434 };
435
436/* Convert an attribute name to a number. */
437
438int
439tic6x_convert_symbolic_attribute (const char *name)
440{
441 unsigned int i;
442
443 for (i = 0; i < ARRAY_SIZE (tic6x_attributes); i++)
444 if (strcmp (name, tic6x_attributes[i].name) == 0)
445 return tic6x_attributes[i].tag;
446
447 return -1;
448}
449
450const pseudo_typeS md_pseudo_table[] =
451 {
452 { "arch", s_tic6x_arch, 0 },
453 { "atomic", s_tic6x_atomic, 0 },
454 { "c6xabi_attribute", s_tic6x_c6xabi_attribute, 0 },
455 { "noatomic", s_tic6x_noatomic, 0 },
456 { "nocmp", s_tic6x_nocmp, 0 },
457 { "word", cons, 4 },
458 { 0, 0, 0 }
459 };
460
461/* Hash table of opcodes. For each opcode name, this stores a pointer
462 to a tic6x_opcode_list listing (in an arbitrary order) all opcode
463 table entries with that name. */
464static struct hash_control *opcode_hash;
465
466/* Initialize the assembler (called once at assembler startup). */
467
468void
469md_begin (void)
470{
471 tic6x_opcode_id id;
472
473 bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
474
475 /* Insert opcodes into the hash table. */
476 opcode_hash = hash_new ();
477 for (id = 0; id < tic6x_opcode_max; id++)
478 {
479 const char *errmsg;
480 tic6x_opcode_list *opc = xmalloc (sizeof (tic6x_opcode_list));
481
482 opc->id = id;
483 opc->next = hash_find (opcode_hash, tic6x_opcode_table[id].name);
484 if ((errmsg = hash_jam (opcode_hash, tic6x_opcode_table[id].name, opc))
485 != NULL)
486 as_fatal ("%s", _(errmsg));
487 }
488}
489
490/* Whether the current line being parsed had the "||" parallel bars. */
491static bfd_boolean tic6x_line_parallel;
492
493/* Whether the current line being parsed started "||^" to indicate an
494 SPMASKed parallel instruction. */
495static bfd_boolean tic6x_line_spmask;
496
497/* If the current line being parsed had an instruction predicate, the
498 creg value for that predicate (which must be nonzero); otherwise
499 0. */
500static unsigned int tic6x_line_creg;
501
502/* If the current line being parsed had an instruction predicate, the
503 z value for that predicate; otherwise 0. */
504static unsigned int tic6x_line_z;
505
506/* Return 1 (updating input_line_pointer as appropriate) if the line
507 starting with C (immediately before input_line_pointer) starts with
508 pre-opcode text appropriate for this target, 0 otherwise. */
509
510int
511tic6x_unrecognized_line (int c)
512{
513 char *p, *endp;
514 unsigned int z;
515 bfd_boolean areg;
516 bfd_boolean bad_predicate;
517
518 switch (c)
519 {
520 case '|':
521 if (input_line_pointer[0] == '|')
522 {
523 if (input_line_pointer[1] == '^')
524 {
525 tic6x_line_spmask = TRUE;
526 input_line_pointer += 2;
527 }
528 else
529 input_line_pointer += 1;
530 if (tic6x_line_parallel)
531 as_bad (_("multiple '||' on same line"));
532 tic6x_line_parallel = TRUE;
533 if (tic6x_line_creg)
534 as_bad (_("'||' after predicate"));
535 return 1;
536 }
537 return 0;
538
539 case '[':
540 /* If it doesn't look like a predicate at all, just return 0.
541 If it looks like one but not a valid one, give a better
542 error. */
543 p = input_line_pointer;
544 while (*p != ']' && !is_end_of_line[(unsigned char) *p])
545 p++;
546 if (*p != ']')
547 return 0;
548 endp = p + 1;
549 p = input_line_pointer;
550 z = 0;
551 bad_predicate = FALSE;
552 if (*p == '!')
553 {
554 z = 1;
555 p++;
556 }
557 if (*p == 'A' || *p == 'a')
558 areg = TRUE;
559 else if (*p == 'B' || *p == 'b')
560 areg = FALSE;
561 else
562 {
563 areg = TRUE; /* Avoid uninitialized warning. */
564 bad_predicate = TRUE;
565 }
566 if (!bad_predicate)
567 {
568 p++;
569 if (*p != '0' && *p != '1' && *p != '2')
570 bad_predicate = TRUE;
571 else if (p[1] != ']')
572 bad_predicate = TRUE;
573 else
574 input_line_pointer = p + 2;
575 }
576
577 if (tic6x_line_creg)
578 as_bad (_("multiple predicates on same line"));
579
580 if (bad_predicate)
581 {
582 char ctmp = *endp;
583 *endp = 0;
584 as_bad (_("bad predicate '%s'"), input_line_pointer - 1);
585 *endp = ctmp;
586 input_line_pointer = endp;
587 return 1;
588 }
589
590 switch (*p)
591 {
592 case '0':
593 tic6x_line_creg = (areg ? 6 : 1);
594 if (areg && !tic6x_predicate_a0)
595 as_bad (_("predication on A0 not supported on this architecture"));
596 break;
597
598 case '1':
599 tic6x_line_creg = (areg ? 4 : 2);
600 break;
601
602 case '2':
603 tic6x_line_creg = (areg ? 5 : 3);
604 break;
605
606 default:
607 abort ();
608 }
609
610 tic6x_line_z = z;
611 return 1;
612
613 default:
614 return 0;
615 }
616}
617
618/* Do any target-specific handling of a label required. */
619
620void
621tic6x_frob_label (symbolS *sym)
622{
623 segment_info_type *si;
624 tic6x_label_list *list;
625
626 if (tic6x_line_parallel)
627 {
628 as_bad (_("label after '||'"));
629 tic6x_line_parallel = FALSE;
630 tic6x_line_spmask = FALSE;
631 }
632 if (tic6x_line_creg)
633 {
634 as_bad (_("label after predicate"));
635 tic6x_line_creg = 0;
636 tic6x_line_z = 0;
637 }
638
639 si = seg_info (now_seg);
640 list = si->tc_segment_info_data.label_list;
641 si->tc_segment_info_data.label_list = xmalloc (sizeof (tic6x_label_list));
642 si->tc_segment_info_data.label_list->next = list;
643 si->tc_segment_info_data.label_list->label = sym;
644
645 /* Defining tc_frob_label overrides the ELF definition of
646 obj_frob_label, so we need to apply its effects here. */
647 dwarf2_emit_label (sym);
648}
649
650/* At end-of-line, give errors for start-of-line decorations that
651 needed an instruction but were not followed by one. */
652
653static void
654tic6x_end_of_line (void)
655{
656 if (tic6x_line_parallel)
657 {
658 as_bad (_("'||' not followed by instruction"));
659 tic6x_line_parallel = FALSE;
660 tic6x_line_spmask = FALSE;
661 }
662 if (tic6x_line_creg)
663 {
664 as_bad (_("predicate not followed by instruction"));
665 tic6x_line_creg = 0;
666 tic6x_line_z = 0;
667 }
668}
669
670/* Do any target-specific handling of the start of a logical line. */
671
672void
673tic6x_start_line_hook (void)
674{
675 tic6x_end_of_line ();
676}
677
678/* Do target-specific handling immediately after an input file from
679 the command line, and any other inputs it includes, have been
680 read. */
681
682void
683tic6x_cleanup (void)
684{
685 tic6x_end_of_line ();
686}
687
688/* Do target-specific initialization after arguments have been
689 processed and the output file created. */
690
691void
692tic6x_init_after_args (void)
693{
694 elf32_tic6x_set_use_rela_p (stdoutput, tic6x_generate_rela);
695}
696
697/* Free LIST of labels (possibly NULL). */
698
699static void
700tic6x_free_label_list (tic6x_label_list *list)
701{
702 while (list)
703 {
704 tic6x_label_list *old = list;
705
706 list = list->next;
707 free (old);
708 }
709}
710
711/* Handle a data alignment of N bytes. */
712
713void
714tic6x_cons_align (int n ATTRIBUTE_UNUSED)
715{
716 segment_info_type *seginfo = seg_info (now_seg);
717
718 /* Data means there is no current execute packet, and that any label
719 applies to that data rather than a subsequent instruction. */
720 tic6x_free_label_list (seginfo->tc_segment_info_data.label_list);
721 seginfo->tc_segment_info_data.label_list = NULL;
722 seginfo->tc_segment_info_data.execute_packet_frag = NULL;
723 seginfo->tc_segment_info_data.last_insn_lsb = NULL;
724 seginfo->tc_segment_info_data.spmask_addr = NULL;
725 seginfo->tc_segment_info_data.func_units_used = 0;
726}
727
728/* Handle an alignment directive. Return TRUE if the
729 machine-independent frag generation should be skipped. */
730
731bfd_boolean
732tic6x_do_align (int n, char *fill, int len ATTRIBUTE_UNUSED, int max)
733{
734 /* Given code alignments of 4, 8, 16 or 32 bytes, we try to handle
735 them in the md_end pass by inserting NOPs in parallel with
736 previous instructions. We only do this in sections containing
737 nothing but instructions. Code alignments of 1 or 2 bytes have
738 no effect in such sections (but we record them with
739 machine-dependent frags anyway so they can be skipped or
740 converted to machine-independent), while those of more than 64
741 bytes cannot reliably be handled in this way. */
742 if (n > 0
743 && max >= 0
744 && max < (1 << n)
745 && !need_pass_2
746 && fill == NULL
747 && subseg_text_p (now_seg))
748 {
749 fragS *align_frag;
750 char *p;
751
752 if (n > 5)
753 return FALSE;
754
755 /* Machine-independent code would generate a frag here, but we
756 wish to handle it in a machine-dependent way. */
757 if (frag_now_fix () != 0)
758 {
759 if (frag_now->fr_type != rs_machine_dependent)
760 frag_wane (frag_now);
761
762 frag_new (0);
763 }
764 frag_grow (32);
765 align_frag = frag_now;
766 p = frag_var (rs_machine_dependent, 32, 32, max, NULL, n, NULL);
767 /* This must be the same as the frag to which a pointer was just
768 saved. */
769 if (p != align_frag->fr_literal)
770 abort ();
771 align_frag->tc_frag_data.is_insns = FALSE;
772 return TRUE;
773 }
774 else
775 return FALSE;
776}
777
778/* Types of operand for parsing purposes. These are used as bit-masks
779 to tell tic6x_parse_operand what forms of operand are
780 permitted. */
781#define TIC6X_OP_EXP 0x0001u
782#define TIC6X_OP_REG 0x0002u
783#define TIC6X_OP_REGPAIR 0x0004u
784#define TIC6X_OP_IRP 0x0008u
785#define TIC6X_OP_NRP 0x0010u
786/* With TIC6X_OP_MEM_NOUNREG, the contents of a () offset are always
787 interpreted as an expression, which may be a symbol with the same
788 name as a register that ends up being implicitly DP-relative. With
789 TIC6X_OP_MEM_UNREG, the contents of a () offset are interpreted as
790 a register if they match one, and failing that as an expression,
791 which must be constant. */
792#define TIC6X_OP_MEM_NOUNREG 0x0020u
793#define TIC6X_OP_MEM_UNREG 0x0040u
794#define TIC6X_OP_CTRL 0x0080u
795#define TIC6X_OP_FUNC_UNIT 0x0100u
796
797/* A register or register pair read by the assembler. */
798typedef struct
799{
800 /* The side the register is on (1 or 2). */
801 unsigned int side;
802 /* The register number (0 to 31). */
803 unsigned int num;
804} tic6x_register;
805
806/* Types of modification of a base address. */
807typedef enum
808 {
809 tic6x_mem_mod_none,
810 tic6x_mem_mod_plus,
811 tic6x_mem_mod_minus,
812 tic6x_mem_mod_preinc,
813 tic6x_mem_mod_predec,
814 tic6x_mem_mod_postinc,
815 tic6x_mem_mod_postdec
816 } tic6x_mem_mod;
817
818/* Scaled [] or unscaled () nature of an offset. */
819typedef enum
820 {
821 tic6x_offset_none,
822 tic6x_offset_scaled,
823 tic6x_offset_unscaled
824 } tic6x_mem_scaling;
825
826/* A memory operand read by the assembler. */
827typedef struct
828{
829 /* The base register. */
830 tic6x_register base_reg;
831 /* How the base register is modified. */
832 tic6x_mem_mod mod;
833 /* Whether there is an offset (required with plain "+" and "-"), and
834 whether it is scaled or unscaled if so. */
835 tic6x_mem_scaling scaled;
836 /* Whether the offset is a register (TRUE) or an expression
837 (FALSE). */
838 bfd_boolean offset_is_reg;
839 /* The offset. */
840 union
841 {
842 expressionS exp;
843 tic6x_register reg;
844 } offset;
845} tic6x_mem_ref;
846
847/* A functional unit in SPMASK operands read by the assembler. */
848typedef struct
849{
850 /* The basic unit. */
851 tic6x_func_unit_base base;
852 /* The side (1 or 2). */
853 unsigned int side;
854} tic6x_func_unit_operand;
855
856/* An operand read by the assembler. */
857typedef struct
858{
859 /* The syntactic form of the operand, as one of the bit-masks
860 above. */
861 unsigned int form;
862 /* The operand value. */
863 union
864 {
865 /* An expression: TIC6X_OP_EXP. */
866 expressionS exp;
867 /* A register: TIC6X_OP_REG, TIC6X_OP_REGPAIR. */
868 tic6x_register reg;
869 /* A memory reference: TIC6X_OP_MEM_NOUNREG,
870 TIC6X_OP_MEM_UNREG. */
871 tic6x_mem_ref mem;
872 /* A control register: TIC6X_OP_CTRL. */
873 tic6x_ctrl_id ctrl;
874 /* A functional unit: TIC6X_OP_FUNC_UNIT. */
875 tic6x_func_unit_operand func_unit;
876 } value;
877} tic6x_operand;
878
879#define skip_whitespace(str) do { if (*(str) == ' ') ++(str); } while (0)
880
881/* Parse a register operand, or part of an operand, starting at *P.
882 If syntactically OK (including that the number is in the range 0 to
883 31, but not necessarily in range for this architecture), return
884 TRUE, putting the register side and number in *REG and update *P to
885 point immediately after the register number; otherwise return FALSE
886 without changing *P (but possibly changing *REG). Do not print any
887 diagnostics. */
888
889static bfd_boolean
890tic6x_parse_register (char **p, tic6x_register *reg)
891{
892 char *r = *p;
893
894 switch (*r)
895 {
896 case 'a':
897 case 'A':
898 reg->side = 1;
899 break;
900
901 case 'b':
902 case 'B':
903 reg->side = 2;
904 break;
905
906 default:
907 return FALSE;
908 }
909 r++;
910
911 if (*r >= '0' && *r <= '9')
912 {
913 reg->num = *r - '0';
914 r++;
915 }
916 else
917 return FALSE;
918
919 if (reg->num > 0 && *r >= '0' && *r <= '9')
920 {
921 reg->num = reg->num * 10 + (*r - '0');
922 r++;
923 }
924
925 if (*r >= '0' && *r <= '9')
926 return FALSE;
927
928 if (reg->num >= 32)
929 return FALSE;
930 *p = r;
931 return TRUE;
932}
933
934/* Parse the initial two characters of a functional unit name starting
935 at *P. If OK, set *BASE and *SIDE and return TRUE; otherwise,
936 return FALSE. */
937
938static bfd_boolean
939tic6x_parse_func_unit_base (char *p, tic6x_func_unit_base *base,
940 unsigned int *side)
941{
942 bfd_boolean good_func_unit = TRUE;
943 tic6x_func_unit_base maybe_base = tic6x_func_unit_nfu;
944 unsigned int maybe_side = 0;
945
946 switch (p[0])
947 {
948 case 'd':
949 case 'D':
950 maybe_base = tic6x_func_unit_d;
951 break;
952
953 case 'l':
954 case 'L':
955 maybe_base = tic6x_func_unit_l;
956 break;
957
958 case 'm':
959 case 'M':
960 maybe_base = tic6x_func_unit_m;
961 break;
962
963 case 's':
964 case 'S':
965 maybe_base = tic6x_func_unit_s;
966 break;
967
968 default:
969 good_func_unit = FALSE;
970 break;
971 }
972
973 if (good_func_unit)
974 switch (p[1])
975 {
976 case '1':
977 maybe_side = 1;
978 break;
979
980 case '2':
981 maybe_side = 2;
982 break;
983
984 default:
985 good_func_unit = FALSE;
986 break;
987 }
988
989 if (good_func_unit)
990 {
991 *base = maybe_base;
992 *side = maybe_side;
993 }
994
995 return good_func_unit;
996}
997
998/* Parse an operand starting at *P. If the operand parses OK, return
999 TRUE and store the value in *OP; otherwise return FALSE (possibly
1000 changing *OP). In any case, update *P to point to the following
1001 comma or end of line. The possible operand forms are given by
1002 OP_FORMS. For diagnostics, this is operand OPNO of an opcode
1003 starting at STR, length OPC_LEN. */
1004
1005static bfd_boolean
1006tic6x_parse_operand (char **p, tic6x_operand *op, unsigned int op_forms,
1007 char *str, int opc_len, unsigned int opno)
1008{
1009 bfd_boolean operand_parsed = FALSE;
1010 char *q = *p;
1011
1012 if ((op_forms & (TIC6X_OP_MEM_NOUNREG | TIC6X_OP_MEM_UNREG))
1013 == (TIC6X_OP_MEM_NOUNREG | TIC6X_OP_MEM_UNREG))
1014 abort ();
1015
1016 /* Check for functional unit names for SPMASK and SPMASKR. */
1017 if (!operand_parsed && (op_forms & TIC6X_OP_FUNC_UNIT))
1018 {
1019 tic6x_func_unit_base base = tic6x_func_unit_nfu;
1020 unsigned int side = 0;
1021
1022 if (tic6x_parse_func_unit_base (q, &base, &side))
1023 {
1024 char *rq = q + 2;
1025
1026 skip_whitespace (rq);
1027 if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
1028 {
1029 op->form = TIC6X_OP_FUNC_UNIT;
1030 op->value.func_unit.base = base;
1031 op->value.func_unit.side = side;
1032 operand_parsed = TRUE;
1033 q = rq;
1034 }
1035 }
1036 }
1037
1038 /* Check for literal "irp". */
1039 if (!operand_parsed && (op_forms & TIC6X_OP_IRP))
1040 {
1041 if ((q[0] == 'i' || q[0] == 'I')
1042 && (q[1] == 'r' || q[1] == 'R')
1043 && (q[2] == 'p' || q[2] == 'P'))
1044 {
1045 char *rq = q + 3;
1046
1047 skip_whitespace (rq);
1048 if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
1049 {
1050 op->form = TIC6X_OP_IRP;
1051 operand_parsed = TRUE;
1052 q = rq;
1053 }
1054 }
1055 }
1056
1057 /* Check for literal "nrp". */
1058 if (!operand_parsed && (op_forms & TIC6X_OP_NRP))
1059 {
1060 if ((q[0] == 'n' || q[0] == 'N')
1061 && (q[1] == 'r' || q[1] == 'R')
1062 && (q[2] == 'p' || q[2] == 'P'))
1063 {
1064 char *rq = q + 3;
1065
1066 skip_whitespace (rq);
1067 if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
1068 {
1069 op->form = TIC6X_OP_NRP;
1070 operand_parsed = TRUE;
1071 q = rq;
1072 }
1073 }
1074 }
1075
1076 /* Check for control register names. */
1077 if (!operand_parsed && (op_forms & TIC6X_OP_CTRL))
1078 {
1079 tic6x_ctrl_id crid;
1080
1081 for (crid = 0; crid < tic6x_ctrl_max; crid++)
1082 {
1083 size_t len = strlen (tic6x_ctrl_table[crid].name);
1084
1085 if (strncasecmp (tic6x_ctrl_table[crid].name, q, len) == 0)
1086 {
1087 char *rq = q + len;
1088
1089 skip_whitespace (rq);
1090 if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
1091 {
1092 op->form = TIC6X_OP_CTRL;
1093 op->value.ctrl = crid;
1094 operand_parsed = TRUE;
1095 q = rq;
1096 if (!(tic6x_ctrl_table[crid].isa_variants & tic6x_features))
1097 as_bad (_("control register '%s' not supported "
1098 "on this architecture"),
1099 tic6x_ctrl_table[crid].name);
1100 }
1101 }
1102 }
1103 }
1104
1105 /* See if this looks like a memory reference. */
1106 if (!operand_parsed
1107 && (op_forms & (TIC6X_OP_MEM_NOUNREG | TIC6X_OP_MEM_UNREG)))
1108 {
1109 bfd_boolean mem_ok = TRUE;
1110 char *mq = q;
1111 tic6x_mem_mod mem_mod = tic6x_mem_mod_none;
1112 tic6x_register base_reg;
1113 bfd_boolean require_offset, permit_offset;
1114 tic6x_mem_scaling scaled;
1115 bfd_boolean offset_is_reg;
1116 expressionS offset_exp;
1117 tic6x_register offset_reg;
1118
1119 if (*mq == '*')
1120 mq++;
1121 else
1122 mem_ok = FALSE;
1123
1124 if (mem_ok)
1125 {
1126 skip_whitespace (mq);
1127 switch (*mq)
1128 {
1129 case '+':
1130 if (mq[1] == '+')
1131 {
1132 mem_mod = tic6x_mem_mod_preinc;
1133 mq += 2;
1134 }
1135 else
1136 {
1137 mem_mod = tic6x_mem_mod_plus;
1138 mq++;
1139 }
1140 break;
1141
1142 case '-':
1143 if (mq[1] == '-')
1144 {
1145 mem_mod = tic6x_mem_mod_predec;
1146 mq += 2;
1147 }
1148 else
1149 {
1150 mem_mod = tic6x_mem_mod_minus;
1151 mq++;
1152 }
1153 break;
1154
1155 default:
1156 break;
1157 }
1158 }
1159
1160 if (mem_ok)
1161 {
1162 skip_whitespace (mq);
1163 mem_ok = tic6x_parse_register (&mq, &base_reg);
1164 }
1165
1166 if (mem_ok && mem_mod == tic6x_mem_mod_none)
1167 {
1168 skip_whitespace (mq);
1169 if (mq[0] == '+' && mq[1] == '+')
1170 {
1171 mem_mod = tic6x_mem_mod_postinc;
1172 mq += 2;
1173 }
1174 else if (mq[0] == '-' && mq[1] == '-')
1175 {
1176 mem_mod = tic6x_mem_mod_postdec;
1177 mq += 2;
1178 }
1179 }
1180
1181 if (mem_mod == tic6x_mem_mod_none)
1182 permit_offset = FALSE;
1183 else
1184 permit_offset = TRUE;
1185 if (mem_mod == tic6x_mem_mod_plus || mem_mod == tic6x_mem_mod_minus)
1186 require_offset = TRUE;
1187 else
1188 require_offset = FALSE;
1189 scaled = tic6x_offset_none;
1190 offset_is_reg = FALSE;
1191
1192 if (mem_ok && permit_offset)
1193 {
1194 char endc = 0;
1195
1196 skip_whitespace (mq);
1197 switch (*mq)
1198 {
1199 case '[':
1200 scaled = tic6x_offset_scaled;
1201 mq++;
1202 endc = ']';
1203 break;
1204
1205 case '(':
1206 scaled = tic6x_offset_unscaled;
1207 mq++;
1208 endc = ')';
1209 break;
1210
1211 default:
1212 break;
1213 }
1214 if (scaled != tic6x_offset_none)
1215 {
1216 skip_whitespace (mq);
1217 if (scaled == tic6x_offset_scaled
1218 || (op_forms & TIC6X_OP_MEM_UNREG))
1219 {
1220 bfd_boolean reg_ok;
1221 char *rq = mq;
1222
1223 reg_ok = tic6x_parse_register (&rq, &offset_reg);
1224 if (reg_ok)
1225 {
1226 skip_whitespace (rq);
1227 if (*rq == endc)
1228 {
1229 mq = rq;
1230 offset_is_reg = TRUE;
1231 }
1232 }
1233 }
1234 if (!offset_is_reg)
1235 {
1236 char *save_input_line_pointer;
1237
1238 save_input_line_pointer = input_line_pointer;
1239 input_line_pointer = mq;
1240 expression (&offset_exp);
1241 mq = input_line_pointer;
1242 input_line_pointer = save_input_line_pointer;
1243 }
1244 skip_whitespace (mq);
1245 if (*mq == endc)
1246 mq++;
1247 else
1248 mem_ok = FALSE;
1249 }
1250 }
1251
1252 if (mem_ok && require_offset && scaled == tic6x_offset_none)
1253 mem_ok = FALSE;
1254
1255 if (mem_ok)
1256 {
1257 skip_whitespace (mq);
1258 if (!is_end_of_line[(unsigned char) *mq] && *mq != ',')
1259 mem_ok = FALSE;
1260 }
1261
1262 if (mem_ok)
1263 {
1264 op->form = op_forms & (TIC6X_OP_MEM_NOUNREG | TIC6X_OP_MEM_UNREG);
1265 op->value.mem.base_reg = base_reg;
1266 op->value.mem.mod = mem_mod;
1267 op->value.mem.scaled = scaled;
1268 op->value.mem.offset_is_reg = offset_is_reg;
1269 if (offset_is_reg)
1270 op->value.mem.offset.reg = offset_reg;
1271 else
1272 op->value.mem.offset.exp = offset_exp;
1273 operand_parsed = TRUE;
1274 q = mq;
1275 if (base_reg.num >= tic6x_num_registers)
1276 as_bad (_("register number %u not supported on this architecture"),
1277 base_reg.num);
1278 if (offset_is_reg && offset_reg.num >= tic6x_num_registers)
1279 as_bad (_("register number %u not supported on this architecture"),
1280 offset_reg.num);
1281 }
1282 }
1283
1284 /* See if this looks like a register or register pair. */
1285 if (!operand_parsed && (op_forms & (TIC6X_OP_REG | TIC6X_OP_REGPAIR)))
1286 {
1287 tic6x_register first_reg, second_reg;
1288 bfd_boolean reg_ok;
1289 char *rq = q;
1290
1291 reg_ok = tic6x_parse_register (&rq, &first_reg);
1292
1293 if (reg_ok)
1294 {
1295 if (*rq == ':' && (op_forms & TIC6X_OP_REGPAIR))
1296 {
1297 rq++;
1298 reg_ok = tic6x_parse_register (&rq, &second_reg);
1299 if (reg_ok)
1300 {
1301 skip_whitespace (rq);
1302 if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
1303 {
1304 if ((second_reg.num & 1)
1305 || (first_reg.num != second_reg.num + 1)
1306 || (first_reg.side != second_reg.side))
1307 as_bad (_("register pair for operand %u of '%.*s'"
1308 " not a valid even/odd pair"), opno,
1309 opc_len, str);
1310 op->form = TIC6X_OP_REGPAIR;
1311 op->value.reg = second_reg;
1312 operand_parsed = TRUE;
1313 q = rq;
1314 }
1315 }
1316 }
1317 else if (op_forms & TIC6X_OP_REG)
1318 {
1319 skip_whitespace (rq);
1320 if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
1321 {
1322 op->form = TIC6X_OP_REG;
1323 op->value.reg = first_reg;
1324 operand_parsed = TRUE;
1325 q = rq;
1326 }
1327 }
1328 }
1329 if (operand_parsed)
1330 {
1331 if (first_reg.num >= tic6x_num_registers)
1332 as_bad (_("register number %u not supported on this architecture"),
1333 first_reg.num);
1334 if (op->form == TIC6X_OP_REGPAIR
1335 && second_reg.num >= tic6x_num_registers)
1336 as_bad (_("register number %u not supported on this architecture"),
1337 second_reg.num);
1338 }
1339 }
1340
1341 /* Otherwise, parse it as an expression. */
1342 if (!operand_parsed && (op_forms & TIC6X_OP_EXP))
1343 {
1344 char *save_input_line_pointer;
1345
1346 save_input_line_pointer = input_line_pointer;
1347 input_line_pointer = q;
1348 op->form = TIC6X_OP_EXP;
1349 expression (&op->value.exp);
1350 q = input_line_pointer;
1351 input_line_pointer = save_input_line_pointer;
1352 operand_parsed = TRUE;
1353 }
1354
1355 if (operand_parsed)
1356 {
1357 /* Now the operand has been parsed, there must be nothing more
1358 before the comma or end of line. */
1359 skip_whitespace (q);
1360 if (!is_end_of_line[(unsigned char) *q] && *q != ',')
1361 {
1362 operand_parsed = FALSE;
1363 as_bad (_("junk after operand %u of '%.*s'"), opno,
1364 opc_len, str);
1365 while (!is_end_of_line[(unsigned char) *q] && *q != ',')
1366 q++;
1367 }
1368 }
1369 else
1370 {
1371 /* This could not be parsed as any acceptable form of
1372 operand. */
1373 switch (op_forms)
1374 {
1375 case TIC6X_OP_REG | TIC6X_OP_REGPAIR:
1376 as_bad (_("bad register or register pair for operand %u of '%.*s'"),
1377 opno, opc_len, str);
1378 break;
1379
1380 case TIC6X_OP_REG | TIC6X_OP_CTRL:
1381 case TIC6X_OP_REG:
1382 as_bad (_("bad register for operand %u of '%.*s'"),
1383 opno, opc_len, str);
1384 break;
1385
1386 case TIC6X_OP_REGPAIR:
1387 as_bad (_("bad register pair for operand %u of '%.*s'"),
1388 opno, opc_len, str);
1389 break;
1390
1391 case TIC6X_OP_FUNC_UNIT:
1392 as_bad (_("bad functional unit for operand %u of '%.*s'"),
1393 opno, opc_len, str);
1394 break;
1395
1396 default:
1397 as_bad (_("bad operand %u of '%.*s'"),
1398 opno, opc_len, str);
1399 break;
1400
1401 }
1402 while (!is_end_of_line[(unsigned char) *q] && *q != ',')
1403 q++;
1404 }
1405 *p = q;
1406 return operand_parsed;
1407}
1408
1409/* Table of assembler operators and associated O_* values. */
1410typedef struct
1411{
1412 const char *name;
1413 operatorT op;
1414} tic6x_operator_table;
1415static const tic6x_operator_table tic6x_operators[] = {
1416#define O_dsbt_index O_md1
1417 { "dsbt_index", O_dsbt_index },
1418#define O_got O_md2
1419 { "got", O_got },
1420#define O_dpr_got O_md3
1421 { "dpr_got", O_dpr_got },
1422#define O_dpr_byte O_md4
1423 { "dpr_byte", O_dpr_byte },
1424#define O_dpr_hword O_md5
1425 { "dpr_hword", O_dpr_hword },
1426#define O_dpr_word O_md6
1427 { "dpr_word", O_dpr_word },
1428};
1429
1430/* Parse a name in some machine-specific way. Used on C6X to handle
1431 assembler operators. */
1432
1433int
1434tic6x_parse_name (const char *name, expressionS *exprP,
1435 enum expr_mode mode ATTRIBUTE_UNUSED, char *nextchar)
1436{
1437 char *p = input_line_pointer;
1438 char c, *name_start, *name_end;
1439 const char *inner_name;
1440 unsigned int i;
1441 operatorT op = O_illegal;
1442 symbolS *sym;
1443
1444 if (*name != '$')
1445 return 0;
1446
1447 for (i = 0; i < ARRAY_SIZE (tic6x_operators); i++)
1448 if (strcasecmp (name + 1, tic6x_operators[i].name) == 0)
1449 {
1450 op = tic6x_operators[i].op;
1451 break;
1452 }
1453
1454 if (op == O_illegal)
1455 return 0;
1456
1457 *input_line_pointer = *nextchar;
1458 skip_whitespace (p);
1459
1460 if (*p != '(')
1461 {
1462 *input_line_pointer = 0;
1463 return 0;
1464 }
1465 p++;
1466 skip_whitespace (p);
1467
1468 if (!is_name_beginner (*p))
1469 {
1470 *input_line_pointer = 0;
1471 return 0;
1472 }
1473
1474 name_start = p;
1475 p++;
1476 while (is_part_of_name (*p))
1477 p++;
1478 name_end = p;
1479 skip_whitespace (p);
1480
1481 if (*p != ')')
1482 {
1483 *input_line_pointer = 0;
1484 return 0;
1485 }
1486
1487 input_line_pointer = p + 1;
1488 *nextchar = *input_line_pointer;
1489 *input_line_pointer = 0;
1490
1491 c = *name_end;
1492 *name_end = 0;
1493 inner_name = name_start;
1494 if (op == O_dsbt_index && strcmp (inner_name, "__c6xabi_DSBT_BASE") != 0)
1495 {
1496 as_bad (_("$DSBT_INDEX must be used with __c6xabi_DSBT_BASE"));
1497 inner_name = "__c6xabi_DSBT_BASE";
1498 }
1499 sym = symbol_find_or_make (inner_name);
1500 *name_end = c;
1501
1502 exprP->X_op = op;
1503 exprP->X_add_symbol = sym;
1504 exprP->X_add_number = 0;
1505 exprP->X_op_symbol = NULL;
1506 exprP->X_md = 0;
1507
1508 return 1;
1509}
1510
1511/* Create a fixup for an expression. Same arguments as fix_new_exp,
1512 plus FIX_ADDA which is TRUE for ADDA instructions (to indicate that
1513 fixes resolving to constants should have those constants implicitly
1514 shifted) and FALSE otherwise, but look for C6X-specific expression
1515 types and adjust the relocations or give errors accordingly. */
1516
1517static void
1518tic6x_fix_new_exp (fragS *frag, int where, int size, expressionS *exp,
1519 int pcrel, bfd_reloc_code_real_type r_type,
1520 bfd_boolean fix_adda)
1521{
1522 bfd_reloc_code_real_type new_reloc = BFD_RELOC_UNUSED;
1523 fixS *fix;
1524
1525 switch (exp->X_op)
1526 {
1527 case O_dsbt_index:
1528 switch (r_type)
1529 {
1530 case BFD_RELOC_C6000_SBR_U15_W:
1531 new_reloc = BFD_RELOC_C6000_DSBT_INDEX;
1532 break;
1533
1534 default:
1535 as_bad (_("$DSBT_INDEX not supported in this context"));
1536 return;
1537 }
1538 break;
1539
1540 case O_got:
1541 switch (r_type)
1542 {
1543 case BFD_RELOC_C6000_SBR_U15_W:
1544 new_reloc = BFD_RELOC_C6000_SBR_GOT_U15_W;
1545 break;
1546
1547 default:
1548 as_bad (_("$GOT not supported in this context"));
1549 return;
1550 }
1551 break;
1552
1553 case O_dpr_got:
1554 switch (r_type)
1555 {
1556 case BFD_RELOC_C6000_ABS_L16:
1557 new_reloc = BFD_RELOC_C6000_SBR_GOT_L16_W;
1558 break;
1559
1560 case BFD_RELOC_C6000_ABS_H16:
1561 new_reloc = BFD_RELOC_C6000_SBR_GOT_H16_W;
1562 break;
1563
1564 default:
1565 as_bad (_("$DPR_GOT not supported in this context"));
1566 return;
1567 }
1568 break;
1569
1570 case O_dpr_byte:
1571 switch (r_type)
1572 {
1573 case BFD_RELOC_C6000_ABS_S16:
1574 new_reloc = BFD_RELOC_C6000_SBR_S16;
1575 break;
1576
1577 case BFD_RELOC_C6000_ABS_L16:
1578 new_reloc = BFD_RELOC_C6000_SBR_L16_B;
1579 break;
1580
1581 case BFD_RELOC_C6000_ABS_H16:
1582 new_reloc = BFD_RELOC_C6000_SBR_H16_B;
1583 break;
1584
1585 default:
1586 as_bad (_("$DPR_BYTE not supported in this context"));
1587 return;
1588 }
1589 break;
1590
1591 case O_dpr_hword:
1592 switch (r_type)
1593 {
1594 case BFD_RELOC_C6000_ABS_L16:
1595 new_reloc = BFD_RELOC_C6000_SBR_L16_H;
1596 break;
1597
1598 case BFD_RELOC_C6000_ABS_H16:
1599 new_reloc = BFD_RELOC_C6000_SBR_H16_H;
1600 break;
1601
1602 default:
1603 as_bad (_("$DPR_HWORD not supported in this context"));
1604 return;
1605 }
1606 break;
1607
1608 case O_dpr_word:
1609 switch (r_type)
1610 {
1611 case BFD_RELOC_C6000_ABS_L16:
1612 new_reloc = BFD_RELOC_C6000_SBR_L16_W;
1613 break;
1614
1615 case BFD_RELOC_C6000_ABS_H16:
1616 new_reloc = BFD_RELOC_C6000_SBR_H16_W;
1617 break;
1618
1619 default:
1620 as_bad (_("$DPR_WORD not supported in this context"));
1621 return;
1622 }
1623 break;
1624
1625 case O_symbol:
1626 break;
1627
1628 default:
1629 if (pcrel)
1630 {
1631 as_bad (_("invalid PC-relative operand"));
1632 return;
1633 }
1634 break;
1635 }
1636
1637 if (new_reloc == BFD_RELOC_UNUSED)
1638 fix = fix_new_exp (frag, where, size, exp, pcrel, r_type);
1639 else
1640 fix = fix_new (frag, where, size, exp->X_add_symbol, exp->X_add_number,
1641 pcrel, new_reloc);
1642 fix->tc_fix_data.fix_adda = fix_adda;
1643}
1644
1645/* Generate a fix for a constant (.word etc.). Needed to ensure these
1646 go through the error checking in tic6x_fix_new_exp. */
1647
1648void
1649tic6x_cons_fix_new (fragS *frag, int where, int size, expressionS *exp)
1650{
1651 bfd_reloc_code_real_type r_type;
1652
1653 switch (size)
1654 {
1655 case 1:
1656 r_type = BFD_RELOC_8;
1657 break;
1658
1659 case 2:
1660 r_type = BFD_RELOC_16;
1661 break;
1662
1663 case 4:
1664 r_type = BFD_RELOC_32;
1665 break;
1666
1667 default:
1668 as_bad (_("no %d-byte relocations available"), size);
1669 return;
1670 }
1671
1672 tic6x_fix_new_exp (frag, where, size, exp, 0, r_type, FALSE);
1673}
1674
1675/* Initialize target-specific fix data. */
1676
1677void
1678tic6x_init_fix_data (fixS *fixP)
1679{
1680 fixP->tc_fix_data.fix_adda = FALSE;
1681}
1682
1683/* Return true if the fix can be handled by GAS, false if it must
1684 be passed through to the linker. */
1685
1686bfd_boolean
1687tic6x_fix_adjustable (fixS *fixP)
1688{
1689 switch (fixP->fx_r_type)
1690 {
1691 /* Adjust_reloc_syms doesn't know about the GOT. */
1692 case BFD_RELOC_C6000_SBR_GOT_U15_W:
1693 case BFD_RELOC_C6000_SBR_GOT_H16_W:
1694 case BFD_RELOC_C6000_SBR_GOT_L16_W:
1695 return 0;
1696
1697 default:
1698 return 1;
1699 }
1700}
1701
1702/* Given the fine-grained form of an operand, return the coarse
1703 (bit-mask) form. */
1704
1705static unsigned int
1706tic6x_coarse_operand_form (tic6x_operand_form form)
1707{
1708 switch (form)
1709 {
1710 case tic6x_operand_asm_const:
1711 case tic6x_operand_link_const:
1712 return TIC6X_OP_EXP;
1713
1714 case tic6x_operand_reg:
1715 case tic6x_operand_xreg:
1716 case tic6x_operand_dreg:
1717 case tic6x_operand_areg:
1718 case tic6x_operand_retreg:
1719 return TIC6X_OP_REG;
1720
1721 case tic6x_operand_regpair:
1722 case tic6x_operand_xregpair:
1723 case tic6x_operand_dregpair:
1724 return TIC6X_OP_REGPAIR;
1725
1726 case tic6x_operand_irp:
1727 return TIC6X_OP_IRP;
1728
1729 case tic6x_operand_nrp:
1730 return TIC6X_OP_NRP;
1731
1732 case tic6x_operand_ctrl:
1733 return TIC6X_OP_CTRL;
1734
1735 case tic6x_operand_mem_short:
1736 case tic6x_operand_mem_long:
1737 case tic6x_operand_mem_deref:
1738 return TIC6X_OP_MEM_NOUNREG;
1739
1740 case tic6x_operand_mem_ndw:
1741 return TIC6X_OP_MEM_UNREG;
1742
1743 case tic6x_operand_func_unit:
1744 return TIC6X_OP_FUNC_UNIT;
1745
1746 default:
1747 abort ();
1748 }
1749}
1750
1751/* How an operand may match or not match a desired form. If different
1752 instruction alternatives fail in different ways, the first failure
1753 in this list determines the diagnostic. */
1754typedef enum
1755 {
1756 /* Matches. */
1757 tic6x_match_matches,
1758 /* Bad coarse form. */
1759 tic6x_match_coarse,
1760 /* Not constant. */
1761 tic6x_match_non_const,
1762 /* Register on wrong side. */
1763 tic6x_match_wrong_side,
1764 /* Not a valid address register. */
1765 tic6x_match_bad_address,
1766 /* Not a valid return address register. */
1767 tic6x_match_bad_return,
1768 /* Control register not readable. */
1769 tic6x_match_ctrl_write_only,
1770 /* Control register not writable. */
1771 tic6x_match_ctrl_read_only,
1772 /* Not a valid memory reference for this instruction. */
1773 tic6x_match_bad_mem
1774 } tic6x_operand_match;
1775
1776/* Return whether an operand matches the given fine-grained form and
1777 read/write usage, and, if it does not match, how it fails to match.
1778 The main functional unit side is SIDE; the cross-path side is CROSS
1779 (the same as SIDE if a cross path not used); the data side is
1780 DATA_SIDE. */
1781static tic6x_operand_match
1782tic6x_operand_matches_form (const tic6x_operand *op, tic6x_operand_form form,
1783 tic6x_rw rw, unsigned int side, unsigned int cross,
1784 unsigned int data_side)
1785{
1786 unsigned int coarse = tic6x_coarse_operand_form (form);
1787
1788 if (coarse != op->form)
1789 return tic6x_match_coarse;
1790
1791 switch (form)
1792 {
1793 case tic6x_operand_asm_const:
1794 if (op->value.exp.X_op == O_constant)
1795 return tic6x_match_matches;
1796 else
1797 return tic6x_match_non_const;
1798
1799 case tic6x_operand_link_const:
1800 case tic6x_operand_irp:
1801 case tic6x_operand_nrp:
1802 case tic6x_operand_func_unit:
1803 /* All expressions are link-time constants, although there may
1804 not be relocations to express them in the output file. "irp"
1805 and "nrp" are unique operand values. All parsed functional
1806 unit names are valid. */
1807 return tic6x_match_matches;
1808
1809 case tic6x_operand_reg:
1810 case tic6x_operand_regpair:
1811 if (op->value.reg.side == side)
1812 return tic6x_match_matches;
1813 else
1814 return tic6x_match_wrong_side;
1815
1816 case tic6x_operand_xreg:
1817 case tic6x_operand_xregpair:
1818 if (op->value.reg.side == cross)
1819 return tic6x_match_matches;
1820 else
1821 return tic6x_match_wrong_side;
1822
1823 case tic6x_operand_dreg:
1824 case tic6x_operand_dregpair:
1825 if (op->value.reg.side == data_side)
1826 return tic6x_match_matches;
1827 else
1828 return tic6x_match_wrong_side;
1829
1830 case tic6x_operand_areg:
1831 if (op->value.reg.side != cross)
1832 return tic6x_match_wrong_side;
1833 else if (op->value.reg.side == 2
1834 && (op->value.reg.num == 14 || op->value.reg.num == 15))
1835 return tic6x_match_matches;
1836 else
1837 return tic6x_match_bad_address;
1838
1839 case tic6x_operand_retreg:
1840 if (op->value.reg.side != side)
1841 return tic6x_match_wrong_side;
1842 else if (op->value.reg.num != 3)
1843 return tic6x_match_bad_return;
1844 else
1845 return tic6x_match_matches;
1846
1847 case tic6x_operand_ctrl:
1848 switch (rw)
1849 {
1850 case tic6x_rw_read:
1851 if (tic6x_ctrl_table[op->value.ctrl].rw == tic6x_rw_read
1852 || tic6x_ctrl_table[op->value.ctrl].rw == tic6x_rw_read_write)
1853 return tic6x_match_matches;
1854 else
1855 return tic6x_match_ctrl_write_only;
1856
1857 case tic6x_rw_write:
1858 if (tic6x_ctrl_table[op->value.ctrl].rw == tic6x_rw_write
1859 || tic6x_ctrl_table[op->value.ctrl].rw == tic6x_rw_read_write)
1860 return tic6x_match_matches;
1861 else
1862 return tic6x_match_ctrl_read_only;
1863
1864 default:
1865 abort ();
1866 }
1867
1868 case tic6x_operand_mem_deref:
1869 if (op->value.mem.mod != tic6x_mem_mod_none)
1870 return tic6x_match_bad_mem;
1871 else if (op->value.mem.scaled != tic6x_offset_none)
1872 abort ();
1873 else if (op->value.mem.base_reg.side != side)
1874 return tic6x_match_bad_mem;
1875 else
1876 return tic6x_match_matches;
1877
1878 case tic6x_operand_mem_short:
1879 case tic6x_operand_mem_ndw:
1880 if (op->value.mem.base_reg.side != side)
1881 return tic6x_match_bad_mem;
1882 if (op->value.mem.mod == tic6x_mem_mod_none)
1883 {
1884 if (op->value.mem.scaled != tic6x_offset_none)
1885 abort ();
1886 return tic6x_match_matches;
1887 }
1888 if (op->value.mem.scaled == tic6x_offset_none)
1889 {
1890 if (op->value.mem.mod == tic6x_mem_mod_plus
1891 || op->value.mem.mod == tic6x_mem_mod_minus)
1892 abort ();
1893 return tic6x_match_matches;
1894 }
1895 if (op->value.mem.offset_is_reg)