OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gas/] [config/] [tc-tic6x.c] - Blame information for rev 241

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 16 khays
/* TI C6X assembler.
2
   Copyright 2010, 2011
3
   Free Software Foundation, Inc.
4
   Contributed by Joseph Myers <joseph@codesourcery.com>
5
                  Bernd Schmidt  <bernds@codesourcery.com>
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 "dw2gencfi.h"
27
#include "safe-ctype.h"
28
#include "subsegs.h"
29
#include "opcode/tic6x.h"
30
#include "elf/tic6x.h"
31
#include "elf32-tic6x.h"
32
 
33
/* Truncate and sign-extend at 32 bits, so that building on a 64-bit
34
   host gives identical results to a 32-bit host.  */
35
#define TRUNC(X)        ((valueT) (X) & 0xffffffffU)
36
#define SEXT(X)         ((TRUNC (X) ^ 0x80000000U) - 0x80000000U)
37
 
38
#define streq(a, b)           (strcmp (a, b) == 0)
39
 
40
/* Stuff for .scomm symbols.  */
41
static segT sbss_section;
42
static asection scom_section;
43
static asymbol scom_symbol;
44
 
45
const char comment_chars[] = ";";
46
const char line_comment_chars[] = "#*;";
47
const char line_separator_chars[] = "@";
48
 
49
const char EXP_CHARS[] = "eE";
50
const char FLT_CHARS[] = "dDfF";
51
 
52
const char *md_shortopts = "";
53
 
54
enum
55
  {
56
    OPTION_MARCH = OPTION_MD_BASE,
57
    OPTION_MBIG_ENDIAN,
58
    OPTION_MLITTLE_ENDIAN,
59
    OPTION_MDSBT,
60
    OPTION_MNO_DSBT,
61
    OPTION_MPID,
62
    OPTION_MPIC,
63
    OPTION_MNO_PIC,
64
    OPTION_MGENERATE_REL
65
  };
66
 
67
struct option md_longopts[] =
68
  {
69
    { "march", required_argument, NULL, OPTION_MARCH },
70
    { "mbig-endian", no_argument, NULL, OPTION_MBIG_ENDIAN },
71
    { "mlittle-endian", no_argument, NULL, OPTION_MLITTLE_ENDIAN },
72
    { "mdsbt", no_argument, NULL, OPTION_MDSBT },
73
    { "mno-dsbt", no_argument, NULL, OPTION_MNO_DSBT },
74
    { "mpid", required_argument, NULL, OPTION_MPID },
75
    { "mpic", no_argument, NULL, OPTION_MPIC },
76
    { "mno-pic", no_argument, NULL, OPTION_MNO_PIC },
77
    { "mgenerate-rel", no_argument, NULL, OPTION_MGENERATE_REL },
78
    { NULL, no_argument, NULL, 0 }
79
  };
80
size_t md_longopts_size = sizeof (md_longopts);
81
 
82
/* The instructions enabled based only on the selected architecture
83
   (all instructions, if no architecture specified).  */
84
static unsigned short tic6x_arch_enable = (TIC6X_INSN_C62X
85
                                           | TIC6X_INSN_C64X
86
                                           | TIC6X_INSN_C64XP
87
                                           | TIC6X_INSN_C67X
88
                                           | TIC6X_INSN_C67XP
89
                                           | TIC6X_INSN_C674X);
90
 
91
/* The instructions enabled based on the current set of features
92
   (architecture, as modified by other options).  */
93
static unsigned short tic6x_features;
94
 
95
/* The architecture attribute value, or C6XABI_Tag_ISA_none if
96
   not yet set.  */
97
static int tic6x_arch_attribute = C6XABI_Tag_ISA_none;
98
 
99
/* Whether any instructions at all have been seen.  Once any
100
   instructions have been seen, architecture attributes merge into the
101
   previous attribute value rather than replacing it.  */
102
static bfd_boolean tic6x_seen_insns = FALSE;
103
 
104
/* The number of registers in each register file supported by the
105
   current architecture.  */
106
static unsigned int tic6x_num_registers;
107
 
108
/* Whether predication on A0 is possible.  */
109
static bfd_boolean tic6x_predicate_a0;
110
 
111
/* Whether execute packets can cross fetch packet boundaries.  */
112
static bfd_boolean tic6x_can_cross_fp_boundary;
113
 
114
/* Whether there are constraints on simultaneous reads and writes of
115
   40-bit data.  */
116
static bfd_boolean tic6x_long_data_constraints;
117
 
118
/* Whether compact instructions are available.  */
119
static bfd_boolean tic6x_compact_insns;
120
 
121
/* Whether to generate RELA relocations.  */
122
static bfd_boolean tic6x_generate_rela = TRUE;
123
 
124
/* Whether the code uses DSBT addressing.  */
125
static bfd_boolean tic6x_dsbt;
126
 
127
/* Types of position-independent data (attribute values for
128
   Tag_ABI_PID).  */
129
typedef enum
130
  {
131
    tic6x_pid_no = 0,
132
    tic6x_pid_near = 1,
133
    tic6x_pid_far = 2
134
  } tic6x_pid_type;
135
 
136
/* The type of data addressing used in this code.  */
137
static tic6x_pid_type tic6x_pid;
138
 
139
/* Whether the code uses position-independent code.  */
140
static bfd_boolean tic6x_pic;
141
 
142
/* Table of supported architecture variants.  */
143
typedef struct
144
{
145
  const char *arch;
146
  int attr;
147
  unsigned short features;
148
} tic6x_arch_table;
149
static const tic6x_arch_table tic6x_arches[] =
150
  {
151
    { "c62x", C6XABI_Tag_ISA_C62X, TIC6X_INSN_C62X },
152
    { "c64x", C6XABI_Tag_ISA_C64X, TIC6X_INSN_C62X | TIC6X_INSN_C64X },
153
    { "c64x+", C6XABI_Tag_ISA_C64XP, (TIC6X_INSN_C62X
154
                                      | TIC6X_INSN_C64X
155
                                      | TIC6X_INSN_C64XP) },
156
    { "c67x", C6XABI_Tag_ISA_C67X, TIC6X_INSN_C62X | TIC6X_INSN_C67X },
157
    { "c67x+", C6XABI_Tag_ISA_C67XP, (TIC6X_INSN_C62X
158
                                      | TIC6X_INSN_C67X
159
                                      | TIC6X_INSN_C67XP) },
160
    { "c674x", C6XABI_Tag_ISA_C674X, (TIC6X_INSN_C62X
161
                                      | TIC6X_INSN_C64X
162
                                      | TIC6X_INSN_C64XP
163
                                      | TIC6X_INSN_C67X
164
                                      | TIC6X_INSN_C67XP
165
                                      | TIC6X_INSN_C674X) }
166
  };
167
 
168
/* Caller saved register encodings.  The standard frame layout uses this
169
   order, starting from the highest address.  There must be
170
   TIC6X_NUM_UNWIND_REGS values.  */
171
enum
172
{
173
  UNWIND_A15,
174
  UNWIND_B15,
175
  UNWIND_B14,
176
  UNWIND_B13,
177
  UNWIND_B12,
178
  UNWIND_B11,
179
  UNWIND_B10,
180
  UNWIND_B3,
181
  UNWIND_A14,
182
  UNWIND_A13,
183
  UNWIND_A12,
184
  UNWIND_A11,
185
  UNWIND_A10
186
};
187
 
188
static void tic6x_output_unwinding (bfd_boolean need_extab);
189
 
190
/* Return the frame unwind state for the current function, allocating
191
   as necessary.  */
192
 
193
static tic6x_unwind_info *tic6x_get_unwind (void)
194
{
195
  tic6x_unwind_info *unwind;
196
 
197
  unwind = seg_info (now_seg)->tc_segment_info_data.unwind;
198
  if (unwind)
199
    return unwind;
200
 
201
  unwind = seg_info (now_seg)->tc_segment_info_data.text_unwind;
202
  if (unwind)
203
    return unwind;
204
 
205
  unwind = (tic6x_unwind_info *)xmalloc (sizeof (tic6x_unwind_info));
206
  seg_info (now_seg)->tc_segment_info_data.unwind = unwind;
207
  memset (unwind, 0, sizeof (*unwind));
208
  return unwind;
209
}
210
 
211
/* Update the selected architecture based on ARCH, giving an error if
212
   ARCH is an invalid value.  Does not call tic6x_update_features; the
213
   caller must do that if necessary.  */
214
 
215
static void
216
tic6x_use_arch (const char *arch)
217
{
218
  unsigned int i;
219
 
220
  for (i = 0; i < ARRAY_SIZE (tic6x_arches); i++)
221
    if (strcmp (arch, tic6x_arches[i].arch) == 0)
222
      {
223
        tic6x_arch_enable = tic6x_arches[i].features;
224
        if (tic6x_seen_insns)
225
          tic6x_arch_attribute
226
            = elf32_tic6x_merge_arch_attributes (tic6x_arch_attribute,
227
                                                 tic6x_arches[i].attr);
228
        else
229
          tic6x_arch_attribute = tic6x_arches[i].attr;
230
        return;
231
      }
232
 
233
  as_bad (_("unknown architecture '%s'"), arch);
234
}
235
 
236
/* Table of supported -mpid arguments.  */
237
typedef struct
238
{
239
  const char *arg;
240
  tic6x_pid_type attr;
241
} tic6x_pid_type_table;
242
static const tic6x_pid_type_table tic6x_pid_types[] =
243
  {
244
    { "no", tic6x_pid_no },
245
    { "near", tic6x_pid_near },
246
    { "far", tic6x_pid_far }
247
  };
248
 
249
/* Handle -mpid=ARG.  */
250
 
251
static void
252
tic6x_use_pid (const char *arg)
253
{
254
  unsigned int i;
255
 
256
  for (i = 0; i < ARRAY_SIZE (tic6x_pid_types); i++)
257
    if (strcmp (arg, tic6x_pid_types[i].arg) == 0)
258
      {
259
        tic6x_pid = tic6x_pid_types[i].attr;
260
        return;
261
      }
262
 
263
  as_bad (_("unknown -mpid= argument '%s'"), arg);
264
}
265
 
266
/* Parse a target-specific option.  */
267
 
268
int
269
md_parse_option (int c, char *arg)
270
{
271
  switch (c)
272
    {
273
    case OPTION_MARCH:
274
      tic6x_use_arch (arg);
275
      break;
276
 
277
    case OPTION_MBIG_ENDIAN:
278
      target_big_endian = 1;
279
      break;
280
 
281
    case OPTION_MLITTLE_ENDIAN:
282
      target_big_endian = 0;
283
      break;
284
 
285
    case OPTION_MDSBT:
286
      tic6x_dsbt = 1;
287
      break;
288
 
289
    case OPTION_MNO_DSBT:
290
      tic6x_dsbt = 0;
291
      break;
292
 
293
    case OPTION_MPID:
294
      tic6x_use_pid (arg);
295
      break;
296
 
297
    case OPTION_MPIC:
298
      tic6x_pic = 1;
299
      break;
300
 
301
    case OPTION_MNO_PIC:
302
      tic6x_pic = 0;
303
      break;
304
 
305
    case OPTION_MGENERATE_REL:
306
      tic6x_generate_rela = FALSE;
307
      break;
308
 
309
    default:
310
      return 0;
311
    }
312
  return 1;
313
}
314
 
315
void
316
md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
317
{
318
  unsigned int i;
319
 
320
  fputc ('\n', stream);
321
  fprintf (stream, _("TMS320C6000 options:\n"));
322
  fprintf (stream, _("  -march=ARCH             enable instructions from architecture ARCH\n"));
323
  fprintf (stream, _("  -mbig-endian            generate big-endian code\n"));
324
  fprintf (stream, _("  -mlittle-endian         generate little-endian code\n"));
325
  fprintf (stream, _("  -mdsbt                  code uses DSBT addressing\n"));
326
  fprintf (stream, _("  -mno-dsbt               code does not use DSBT addressing\n"));
327
  fprintf (stream, _("  -mpid=no                code uses position-dependent data addressing\n"));
328
  fprintf (stream, _("  -mpid=near              code uses position-independent data addressing,\n"
329
                     "                            GOT accesses use near DP addressing\n"));
330
  fprintf (stream, _("  -mpid=far               code uses position-independent data addressing,\n"
331
                     "                            GOT accesses use far DP addressing\n"));
332
  fprintf (stream, _("  -mpic                   code addressing is position-independent\n"));
333
  fprintf (stream, _("  -mno-pic                code addressing is position-dependent\n"));
334
  /* -mgenerate-rel is only for testsuite use and is deliberately
335
      undocumented.  */
336
 
337
  fputc ('\n', stream);
338
  fprintf (stream, _("Supported ARCH values are:"));
339
  for (i = 0; i < ARRAY_SIZE (tic6x_arches); i++)
340
    fprintf (stream, " %s", tic6x_arches[i].arch);
341
  fputc ('\n', stream);
342
}
343
 
344
/* Update enabled features based on the current architecture and
345
   related settings.  */
346
static void
347
tic6x_update_features (void)
348
{
349
  tic6x_features = tic6x_arch_enable;
350
 
351
  tic6x_num_registers
352
    = (tic6x_arch_enable & (TIC6X_INSN_C64X | TIC6X_INSN_C67XP)) ? 32 : 16;
353
 
354
  tic6x_predicate_a0 = (tic6x_arch_enable & TIC6X_INSN_C64X) ? TRUE : FALSE;
355
 
356
  tic6x_can_cross_fp_boundary
357
    = (tic6x_arch_enable
358
       & (TIC6X_INSN_C64X | TIC6X_INSN_C67XP)) ? TRUE : FALSE;
359
 
360
  tic6x_long_data_constraints
361
    = (tic6x_arch_enable & TIC6X_INSN_C64X) ? FALSE : TRUE;
362
 
363
  tic6x_compact_insns = (tic6x_arch_enable & TIC6X_INSN_C64XP) ? TRUE : FALSE;
364
}
365
 
366
/* Do configuration after all options have been parsed.  */
367
 
368
void
369
tic6x_after_parse_args (void)
370
{
371
  tic6x_update_features ();
372
}
373
 
374
/* Parse a .cantunwind directive.  */
375
static void
376
s_tic6x_cantunwind (int ignored ATTRIBUTE_UNUSED)
377
{
378
  tic6x_unwind_info *unwind = tic6x_get_unwind ();
379
 
380
  /* GCC sometimes spits out superfluous .cantunwind directives, so ignore
381
     them.  */
382
  if (unwind->data_bytes == 0)
383
    return;
384
 
385
  if (unwind->data_bytes != -1)
386
    {
387
      as_bad (_("unexpected .cantunwind directive"));
388
      return;
389
    }
390
 
391
  demand_empty_rest_of_line ();
392
 
393
  if (unwind->personality_routine || unwind->personality_index != -1)
394
    as_bad (_("personality routine specified for cantunwind frame"));
395
 
396
  unwind->personality_index = -2;
397
}
398
 
399
/* Parse a .handlerdata directive.  */
400
static void
401
s_tic6x_handlerdata (int ignored ATTRIBUTE_UNUSED)
402
{
403
  tic6x_unwind_info *unwind = tic6x_get_unwind ();
404
 
405
  if (!unwind->saved_seg)
406
    {
407
      as_bad (_("unexpected .handlerdata directive"));
408
      return;
409
    }
410
 
411
  if (unwind->table_entry || unwind->personality_index == -2)
412
    {
413
      as_bad (_("duplicate .handlerdata directive"));
414
      return;
415
    }
416
 
417
  if (unwind->personality_index == -1 && unwind->personality_routine == NULL)
418
    {
419
      as_bad (_("personality routine required before .handlerdata directive"));
420
      return;
421
    }
422
 
423
  tic6x_output_unwinding (TRUE);
424
}
425
 
426
/* Parse a .endp directive.  */
427
static void
428
s_tic6x_endp (int ignored ATTRIBUTE_UNUSED)
429
{
430
  tic6x_unwind_info *unwind = tic6x_get_unwind ();
431
 
432
  if (unwind->data_bytes != 0)
433
    {
434
      /* Output a .exidx entry if we have not already done so.
435
         Then switch back to the text section.  */
436
      if (!unwind->table_entry)
437
        tic6x_output_unwinding (FALSE);
438
 
439
      subseg_set (unwind->saved_seg, unwind->saved_subseg);
440
    }
441
 
442
  unwind->saved_seg = NULL;
443
  unwind->table_entry = NULL;
444
  unwind->data_bytes = 0;
445
}
446
 
447
/* Parse a .personalityindex directive.  */
448
static void
449
s_tic6x_personalityindex (int ignored ATTRIBUTE_UNUSED)
450
{
451
  tic6x_unwind_info *unwind = tic6x_get_unwind ();
452
  expressionS exp;
453
 
454
  if (unwind->personality_routine || unwind->personality_index != -1)
455
    as_bad (_("duplicate .personalityindex directive"));
456
 
457
  expression (&exp);
458
 
459
  if (exp.X_op != O_constant
460
      || exp.X_add_number < 0 || exp.X_add_number > 15)
461
    {
462
      as_bad (_("bad personality routine number"));
463
      ignore_rest_of_line ();
464
      return;
465
    }
466
 
467
  unwind->personality_index = exp.X_add_number;
468
 
469
  demand_empty_rest_of_line ();
470
}
471
 
472
static void
473
s_tic6x_personality (int ignored ATTRIBUTE_UNUSED)
474
{
475
  char *name, *p, c;
476
  tic6x_unwind_info *unwind = tic6x_get_unwind ();
477
 
478
  if (unwind->personality_routine || unwind->personality_index != -1)
479
    as_bad (_("duplicate .personality directive"));
480
 
481
  name = input_line_pointer;
482
  c = get_symbol_end ();
483
  p = input_line_pointer;
484
  unwind->personality_routine = symbol_find_or_make (name);
485
  *p = c;
486
  demand_empty_rest_of_line ();
487
}
488
 
489
/* Parse a .arch directive.  */
490
static void
491
s_tic6x_arch (int ignored ATTRIBUTE_UNUSED)
492
{
493
  char c;
494
  char *arch;
495
 
496
  arch = input_line_pointer;
497
  while (*input_line_pointer && !ISSPACE (*input_line_pointer))
498
    input_line_pointer++;
499
  c = *input_line_pointer;
500
  *input_line_pointer = 0;
501
 
502
  tic6x_use_arch (arch);
503
  tic6x_update_features ();
504
  *input_line_pointer = c;
505
  demand_empty_rest_of_line ();
506
}
507
 
508
/* Parse a .ehtype directive.  */
509
 
510
static void
511
s_tic6x_ehtype (int ignored ATTRIBUTE_UNUSED)
512
{
513
  expressionS exp;
514
  char *p;
515
 
516
#ifdef md_flush_pending_output
517
  md_flush_pending_output ();
518
#endif
519
 
520
  if (is_it_end_of_statement ())
521
    {
522
      demand_empty_rest_of_line ();
523
      return;
524
    }
525
 
526
#ifdef md_cons_align
527
  md_cons_align (4);
528
#endif
529
 
530
 
531
  expression (&exp);
532
 
533
  if (exp.X_op != O_symbol)
534
    {
535
      as_bad (_("expected symbol"));
536
      return;
537
    }
538
 
539
  p = frag_more (4);
540
  fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
541
               &exp, 0, BFD_RELOC_C6000_EHTYPE);
542
 
543
  demand_empty_rest_of_line ();
544
}
545
 
546
/* Parse a .nocmp directive.  */
547
 
548
static void
549
s_tic6x_nocmp (int ignored ATTRIBUTE_UNUSED)
550
{
551
  seg_info (now_seg)->tc_segment_info_data.nocmp = TRUE;
552
  demand_empty_rest_of_line ();
553
}
554
 
555
/* .scomm pseudo-op handler.
556
 
557
   This is a new pseudo-op to handle putting objects in .scommon.
558
   By doing this the linker won't need to do any work,
559
   and more importantly it removes the implicit -G arg necessary to
560
   correctly link the object file.  */
561
 
562
static void
563
s_tic6x_scomm (int ignore ATTRIBUTE_UNUSED)
564
{
565
  char *name;
566
  char c;
567
  char *p;
568
  offsetT size;
569
  symbolS *symbolP;
570
  offsetT align;
571
  int align2;
572
 
573
  name = input_line_pointer;
574
  c = get_symbol_end ();
575
 
576
  /* Just after name is now '\0'.  */
577
  p = input_line_pointer;
578
  *p = c;
579
  SKIP_WHITESPACE ();
580
  if (*input_line_pointer != ',')
581
    {
582
      as_bad (_("expected comma after symbol name"));
583
      ignore_rest_of_line ();
584
      return;
585
    }
586
 
587
  /* Skip ','.  */
588
  input_line_pointer++;
589
  if ((size = get_absolute_expression ()) < 0)
590
    {
591
      /* xgettext:c-format  */
592
      as_warn (_("invalid length for .scomm directive"));
593
      ignore_rest_of_line ();
594
      return;
595
    }
596
 
597
  /* The third argument to .scomm is the alignment.  */
598
  if (*input_line_pointer != ',')
599
    align = 8;
600
  else
601
    {
602
      ++input_line_pointer;
603
      align = get_absolute_expression ();
604
      if (align <= 0)
605
        {
606
          as_warn (_("alignment is not a positive number"));
607
          align = 8;
608
        }
609
    }
610
 
611
  /* Convert to a power of 2 alignment.  */
612
  if (align)
613
    {
614
      for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2)
615
        continue;
616
      if (align != 1)
617
        {
618
          as_bad (_("alignment is not a power of 2"));
619
          ignore_rest_of_line ();
620
          return;
621
        }
622
    }
623
  else
624
    align2 = 0;
625
 
626
  *p = 0;
627
  symbolP = symbol_find_or_make (name);
628
  *p = c;
629
 
630
  if (S_IS_DEFINED (symbolP))
631
    {
632
      /* xgettext:c-format  */
633
      as_bad (_("attempt to re-define symbol `%s'"),
634
              S_GET_NAME (symbolP));
635
      ignore_rest_of_line ();
636
      return;
637
    }
638
 
639
  if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
640
    {
641
      /* xgettext:c-format  */
642
      as_bad (_("attempt to redefine `%s' with a different length"),
643
              S_GET_NAME (symbolP));
644
 
645
      ignore_rest_of_line ();
646
      return;
647
    }
648
 
649
  if (symbol_get_obj (symbolP)->local)
650
    {
651
      segT old_sec = now_seg;
652
      int old_subsec = now_subseg;
653
      char *pfrag;
654
 
655
      record_alignment (sbss_section, align2);
656
      subseg_set (sbss_section, 0);
657
 
658
      if (align2)
659
        frag_align (align2, 0, 0);
660
 
661
      if (S_GET_SEGMENT (symbolP) == sbss_section)
662
        symbol_get_frag (symbolP)->fr_symbol = 0;
663
 
664
      symbol_set_frag (symbolP, frag_now);
665
 
666
      pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
667
                        (char *) 0);
668
      *pfrag = 0;
669
      S_SET_SIZE (symbolP, size);
670
      S_SET_SEGMENT (symbolP, sbss_section);
671
      S_CLEAR_EXTERNAL (symbolP);
672
      subseg_set (old_sec, old_subsec);
673
    }
674
  else
675
    {
676
      S_SET_VALUE (symbolP, (valueT) size);
677
      S_SET_ALIGN (symbolP, 1 << align2);
678
      S_SET_EXTERNAL (symbolP);
679
      S_SET_SEGMENT (symbolP, &scom_section);
680
    }
681
 
682
  symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
683
 
684
  demand_empty_rest_of_line ();
685
}
686
 
687
/* Track for each attribute whether it has been set explicitly (and so
688
   should not have a default value set by the assembler).  */
689
static bfd_boolean tic6x_attributes_set_explicitly[NUM_KNOWN_OBJ_ATTRIBUTES];
690
 
691
/* Parse a .c6xabi_attribute directive.  */
692
 
693
static void
694
s_tic6x_c6xabi_attribute (int ignored ATTRIBUTE_UNUSED)
695
{
696
  int tag = s_vendor_attribute (OBJ_ATTR_PROC);
697
 
698
  if (tag < NUM_KNOWN_OBJ_ATTRIBUTES)
699
    tic6x_attributes_set_explicitly[tag] = TRUE;
700
}
701
 
702
typedef struct
703
{
704
  const char *name;
705
  int tag;
706
} tic6x_attribute_table;
707
 
708
static const tic6x_attribute_table tic6x_attributes[] =
709
  {
710
#define TAG(tag, value) { #tag, tag },
711
#include "elf/tic6x-attrs.h"
712
#undef TAG
713
  };
714
 
715
/* Convert an attribute name to a number.  */
716
 
717
int
718
tic6x_convert_symbolic_attribute (const char *name)
719
{
720
  unsigned int i;
721
 
722
  for (i = 0; i < ARRAY_SIZE (tic6x_attributes); i++)
723
    if (strcmp (name, tic6x_attributes[i].name) == 0)
724
      return tic6x_attributes[i].tag;
725
 
726
  return -1;
727
}
728
 
729
const pseudo_typeS md_pseudo_table[] =
730
  {
731
    { "arch", s_tic6x_arch, 0 },
732
    { "c6xabi_attribute", s_tic6x_c6xabi_attribute, 0 },
733
    { "nocmp", s_tic6x_nocmp, 0 },
734
    { "scomm",  s_tic6x_scomm, 0 },
735
    { "word", cons, 4 },
736
    { "ehtype", s_tic6x_ehtype, 0 },
737
    { "endp", s_tic6x_endp, 0 },
738
    { "handlerdata", s_tic6x_handlerdata, 0 },
739
    { "personalityindex", s_tic6x_personalityindex, 0 },
740
    { "personality", s_tic6x_personality, 0 },
741
    { "cantunwind", s_tic6x_cantunwind, 0 },
742
    { 0, 0, 0 }
743
  };
744
 
745
/* Hash table of opcodes.  For each opcode name, this stores a pointer
746
   to a tic6x_opcode_list listing (in an arbitrary order) all opcode
747
   table entries with that name.  */
748
static struct hash_control *opcode_hash;
749
 
750
/* Initialize the assembler (called once at assembler startup).  */
751
 
752
void
753
md_begin (void)
754
{
755
  tic6x_opcode_id id;
756
  flagword applicable;
757
  segT seg;
758
  subsegT subseg;
759
 
760
  bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
761
 
762
  /* Insert opcodes into the hash table.  */
763
  opcode_hash = hash_new ();
764
  for (id = 0; id < tic6x_opcode_max; id++)
765
    {
766
      const char *errmsg;
767
      tic6x_opcode_list *opc = xmalloc (sizeof (tic6x_opcode_list));
768
 
769
      opc->id = id;
770
      opc->next = hash_find (opcode_hash, tic6x_opcode_table[id].name);
771
      if ((errmsg = hash_jam (opcode_hash, tic6x_opcode_table[id].name, opc))
772
          != NULL)
773
        as_fatal ("%s", _(errmsg));
774
    }
775
 
776
  /* Save the current subseg so we can restore it [it's the default one and
777
     we don't want the initial section to be .sbss].  */
778
  seg = now_seg;
779
  subseg = now_subseg;
780
 
781
  /* The sbss section is for local .scomm symbols.  */
782
  sbss_section = subseg_new (".bss", 0);
783
  seg_info (sbss_section)->bss = 1;
784
 
785
  /* This is copied from perform_an_assembly_pass.  */
786
  applicable = bfd_applicable_section_flags (stdoutput);
787
  bfd_set_section_flags (stdoutput, sbss_section, applicable & SEC_ALLOC);
788
 
789
  subseg_set (seg, subseg);
790
 
791
  /* We must construct a fake section similar to bfd_com_section
792
     but with the name .scommon.  */
793
  scom_section                = bfd_com_section;
794
  scom_section.name           = ".scommon";
795
  scom_section.output_section = & scom_section;
796
  scom_section.symbol         = & scom_symbol;
797
  scom_section.symbol_ptr_ptr = & scom_section.symbol;
798
  scom_symbol                 = * bfd_com_section.symbol;
799
  scom_symbol.name            = ".scommon";
800
  scom_symbol.section         = & scom_section;
801
}
802
 
803
/* Whether the current line being parsed had the "||" parallel bars.  */
804
static bfd_boolean tic6x_line_parallel;
805
 
806
/* Whether the current line being parsed started "||^" to indicate an
807
   SPMASKed parallel instruction.  */
808
static bfd_boolean tic6x_line_spmask;
809
 
810
/* If the current line being parsed had an instruction predicate, the
811
   creg value for that predicate (which must be nonzero); otherwise
812
   0.  */
813
static unsigned int tic6x_line_creg;
814
 
815
/* If the current line being parsed had an instruction predicate, the
816
   z value for that predicate; otherwise 0.  */
817
static unsigned int tic6x_line_z;
818
 
819
/* Return 1 (updating input_line_pointer as appropriate) if the line
820
   starting with C (immediately before input_line_pointer) starts with
821
   pre-opcode text appropriate for this target, 0 otherwise.  */
822
 
823
int
824
tic6x_unrecognized_line (int c)
825
{
826
  char *p, *endp;
827
  unsigned int z;
828
  bfd_boolean areg;
829
  bfd_boolean bad_predicate;
830
 
831
  switch (c)
832
    {
833
    case '|':
834
      if (input_line_pointer[0] == '|')
835
        {
836
          if (input_line_pointer[1] == '^')
837
            {
838
              tic6x_line_spmask = TRUE;
839
              input_line_pointer += 2;
840
            }
841
          else
842
            input_line_pointer += 1;
843
          if (tic6x_line_parallel)
844
            as_bad (_("multiple '||' on same line"));
845
          tic6x_line_parallel = TRUE;
846
          if (tic6x_line_creg)
847
            as_bad (_("'||' after predicate"));
848
          return 1;
849
        }
850
      return 0;
851
 
852
    case '[':
853
      /* If it doesn't look like a predicate at all, just return 0.
854
         If it looks like one but not a valid one, give a better
855
         error.  */
856
      p = input_line_pointer;
857
      while (*p != ']' && !is_end_of_line[(unsigned char) *p])
858
        p++;
859
      if (*p != ']')
860
        return 0;
861
      endp = p + 1;
862
      p = input_line_pointer;
863
      z = 0;
864
      bad_predicate = FALSE;
865
      if (*p == '!')
866
        {
867
          z = 1;
868
          p++;
869
        }
870
      if (*p == 'A' || *p == 'a')
871
        areg = TRUE;
872
      else if (*p == 'B' || *p == 'b')
873
        areg = FALSE;
874
      else
875
        {
876
          areg = TRUE; /* Avoid uninitialized warning.  */
877
          bad_predicate = TRUE;
878
        }
879
      if (!bad_predicate)
880
        {
881
          p++;
882
          if (*p != '0' && *p != '1' && *p != '2')
883
            bad_predicate = TRUE;
884
          else if (p[1] != ']')
885
            bad_predicate = TRUE;
886
          else
887
            input_line_pointer = p + 2;
888
        }
889
 
890
      if (tic6x_line_creg)
891
        as_bad (_("multiple predicates on same line"));
892
 
893
      if (bad_predicate)
894
        {
895
          char ctmp = *endp;
896
          *endp = 0;
897
          as_bad (_("bad predicate '%s'"), input_line_pointer - 1);
898
          *endp = ctmp;
899
          input_line_pointer = endp;
900
          return 1;
901
        }
902
 
903
      switch (*p)
904
        {
905
        case '0':
906
          tic6x_line_creg = (areg ? 6 : 1);
907
          if (areg && !tic6x_predicate_a0)
908
            as_bad (_("predication on A0 not supported on this architecture"));
909
          break;
910
 
911
        case '1':
912
          tic6x_line_creg = (areg ? 4 : 2);
913
          break;
914
 
915
        case '2':
916
          tic6x_line_creg = (areg ? 5 : 3);
917
          break;
918
 
919
        default:
920
          abort ();
921
        }
922
 
923
      tic6x_line_z = z;
924
      return 1;
925
 
926
    default:
927
      return 0;
928
    }
929
}
930
 
931
/* Do any target-specific handling of a label required.  */
932
 
933
void
934
tic6x_frob_label (symbolS *sym)
935
{
936
  segment_info_type *si;
937
  tic6x_label_list *list;
938
 
939
  if (tic6x_line_parallel)
940
    {
941
      as_bad (_("label after '||'"));
942
      tic6x_line_parallel = FALSE;
943
      tic6x_line_spmask = FALSE;
944
    }
945
  if (tic6x_line_creg)
946
    {
947
      as_bad (_("label after predicate"));
948
      tic6x_line_creg = 0;
949
      tic6x_line_z = 0;
950
    }
951
 
952
  si = seg_info (now_seg);
953
  list = si->tc_segment_info_data.label_list;
954
  si->tc_segment_info_data.label_list = xmalloc (sizeof (tic6x_label_list));
955
  si->tc_segment_info_data.label_list->next = list;
956
  si->tc_segment_info_data.label_list->label = sym;
957
 
958
  /* Defining tc_frob_label overrides the ELF definition of
959
     obj_frob_label, so we need to apply its effects here.  */
960
  dwarf2_emit_label (sym);
961
}
962
 
963
/* At end-of-line, give errors for start-of-line decorations that
964
   needed an instruction but were not followed by one.  */
965
 
966
static void
967
tic6x_end_of_line (void)
968
{
969
  if (tic6x_line_parallel)
970
    {
971
      as_bad (_("'||' not followed by instruction"));
972
      tic6x_line_parallel = FALSE;
973
      tic6x_line_spmask = FALSE;
974
    }
975
  if (tic6x_line_creg)
976
    {
977
      as_bad (_("predicate not followed by instruction"));
978
      tic6x_line_creg = 0;
979
      tic6x_line_z = 0;
980
    }
981
}
982
 
983
/* Do any target-specific handling of the start of a logical line.  */
984
 
985
void
986
tic6x_start_line_hook (void)
987
{
988
  tic6x_end_of_line ();
989
}
990
 
991
/* Do target-specific handling immediately after an input file from
992
   the command line, and any other inputs it includes, have been
993
   read.  */
994
 
995
void
996
tic6x_cleanup (void)
997
{
998
  tic6x_end_of_line ();
999
}
1000
 
1001
/* Do target-specific initialization after arguments have been
1002
   processed and the output file created.  */
1003
 
1004
void
1005
tic6x_init_after_args (void)
1006
{
1007
  elf32_tic6x_set_use_rela_p (stdoutput, tic6x_generate_rela);
1008
}
1009
 
1010
/* Free LIST of labels (possibly NULL).  */
1011
 
1012
static void
1013
tic6x_free_label_list (tic6x_label_list *list)
1014
{
1015
  while (list)
1016
    {
1017
      tic6x_label_list *old = list;
1018
 
1019
      list = list->next;
1020
      free (old);
1021
    }
1022
}
1023
 
1024
/* Handle a data alignment of N bytes.  */
1025
 
1026
void
1027
tic6x_cons_align (int n ATTRIBUTE_UNUSED)
1028
{
1029
  segment_info_type *seginfo = seg_info (now_seg);
1030
 
1031
  /* Data means there is no current execute packet, and that any label
1032
     applies to that data rather than a subsequent instruction.  */
1033
  tic6x_free_label_list (seginfo->tc_segment_info_data.label_list);
1034
  seginfo->tc_segment_info_data.label_list = NULL;
1035
  seginfo->tc_segment_info_data.execute_packet_frag = NULL;
1036
  seginfo->tc_segment_info_data.last_insn_lsb = NULL;
1037
  seginfo->tc_segment_info_data.spmask_addr = NULL;
1038
  seginfo->tc_segment_info_data.func_units_used = 0;
1039
}
1040
 
1041
/* Handle an alignment directive.  Return TRUE if the
1042
   machine-independent frag generation should be skipped.  */
1043
 
1044
bfd_boolean
1045
tic6x_do_align (int n, char *fill, int len ATTRIBUTE_UNUSED, int max)
1046
{
1047
  /* Given code alignments of 4, 8, 16 or 32 bytes, we try to handle
1048
     them in the md_end pass by inserting NOPs in parallel with
1049
     previous instructions.  We only do this in sections containing
1050
     nothing but instructions.  Code alignments of 1 or 2 bytes have
1051
     no effect in such sections (but we record them with
1052
     machine-dependent frags anyway so they can be skipped or
1053
     converted to machine-independent), while those of more than 64
1054
     bytes cannot reliably be handled in this way.  */
1055
  if (n > 0
1056
      && max >= 0
1057
      && max < (1 << n)
1058
      && !need_pass_2
1059
      && fill == NULL
1060
      && subseg_text_p (now_seg))
1061
    {
1062
      fragS *align_frag;
1063
      char *p;
1064
 
1065
      if (n > 5)
1066
        return FALSE;
1067
 
1068
      /* Machine-independent code would generate a frag here, but we
1069
         wish to handle it in a machine-dependent way.  */
1070
      if (frag_now_fix () != 0)
1071
        {
1072
          if (frag_now->fr_type != rs_machine_dependent)
1073
            frag_wane (frag_now);
1074
 
1075
          frag_new (0);
1076
        }
1077
      frag_grow (32);
1078
      align_frag = frag_now;
1079
      p = frag_var (rs_machine_dependent, 32, 32, max, NULL, n, NULL);
1080
      /* This must be the same as the frag to which a pointer was just
1081
         saved.  */
1082
      if (p != align_frag->fr_literal)
1083
        abort ();
1084
      align_frag->tc_frag_data.is_insns = FALSE;
1085
      return TRUE;
1086
    }
1087
  else
1088
    return FALSE;
1089
}
1090
 
1091
/* Types of operand for parsing purposes.  These are used as bit-masks
1092
   to tell tic6x_parse_operand what forms of operand are
1093
   permitted.  */
1094
#define TIC6X_OP_EXP            0x0001u
1095
#define TIC6X_OP_REG            0x0002u
1096
#define TIC6X_OP_REGPAIR        0x0004u
1097
#define TIC6X_OP_IRP            0x0008u
1098
#define TIC6X_OP_NRP            0x0010u
1099
/* With TIC6X_OP_MEM_NOUNREG, the contents of a () offset are always
1100
   interpreted as an expression, which may be a symbol with the same
1101
   name as a register that ends up being implicitly DP-relative.  With
1102
   TIC6X_OP_MEM_UNREG, the contents of a () offset are interpreted as
1103
   a register if they match one, and failing that as an expression,
1104
   which must be constant.  */
1105
#define TIC6X_OP_MEM_NOUNREG    0x0020u
1106
#define TIC6X_OP_MEM_UNREG      0x0040u
1107
#define TIC6X_OP_CTRL           0x0080u
1108
#define TIC6X_OP_FUNC_UNIT      0x0100u
1109
 
1110
/* A register or register pair read by the assembler.  */
1111
typedef struct
1112
{
1113
  /* The side the register is on (1 or 2).  */
1114
  unsigned int side;
1115
  /* The register number (0 to 31).  */
1116
  unsigned int num;
1117
} tic6x_register;
1118
 
1119
/* Types of modification of a base address.  */
1120
typedef enum
1121
  {
1122
    tic6x_mem_mod_none,
1123
    tic6x_mem_mod_plus,
1124
    tic6x_mem_mod_minus,
1125
    tic6x_mem_mod_preinc,
1126
    tic6x_mem_mod_predec,
1127
    tic6x_mem_mod_postinc,
1128
    tic6x_mem_mod_postdec
1129
  } tic6x_mem_mod;
1130
 
1131
/* Scaled [] or unscaled () nature of an offset.  */
1132
typedef enum
1133
  {
1134
    tic6x_offset_none,
1135
    tic6x_offset_scaled,
1136
    tic6x_offset_unscaled
1137
  } tic6x_mem_scaling;
1138
 
1139
/* A memory operand read by the assembler.  */
1140
typedef struct
1141
{
1142
  /* The base register.  */
1143
  tic6x_register base_reg;
1144
  /* How the base register is modified.  */
1145
  tic6x_mem_mod mod;
1146
  /* Whether there is an offset (required with plain "+" and "-"), and
1147
     whether it is scaled or unscaled if so.  */
1148
  tic6x_mem_scaling scaled;
1149
  /* Whether the offset is a register (TRUE) or an expression
1150
     (FALSE).  */
1151
  bfd_boolean offset_is_reg;
1152
  /* The offset.  */
1153
  union
1154
  {
1155
    expressionS exp;
1156
    tic6x_register reg;
1157
  } offset;
1158
} tic6x_mem_ref;
1159
 
1160
/* A functional unit in SPMASK operands read by the assembler.  */
1161
typedef struct
1162
{
1163
  /* The basic unit.  */
1164
  tic6x_func_unit_base base;
1165
  /* The side (1 or 2).  */
1166
  unsigned int side;
1167
} tic6x_func_unit_operand;
1168
 
1169
/* An operand read by the assembler.  */
1170
typedef struct
1171
{
1172
  /* The syntactic form of the operand, as one of the bit-masks
1173
     above.  */
1174
  unsigned int form;
1175
  /* The operand value.  */
1176
  union
1177
  {
1178
    /* An expression: TIC6X_OP_EXP.  */
1179
    expressionS exp;
1180
    /* A register: TIC6X_OP_REG, TIC6X_OP_REGPAIR.  */
1181
    tic6x_register reg;
1182
    /* A memory reference: TIC6X_OP_MEM_NOUNREG,
1183
       TIC6X_OP_MEM_UNREG.  */
1184
    tic6x_mem_ref mem;
1185
    /* A control register: TIC6X_OP_CTRL.  */
1186
    tic6x_ctrl_id ctrl;
1187
    /* A functional unit: TIC6X_OP_FUNC_UNIT.  */
1188
    tic6x_func_unit_operand func_unit;
1189
  } value;
1190
} tic6x_operand;
1191
 
1192
#define skip_whitespace(str)  do { if (*(str) == ' ') ++(str); } while (0)
1193
 
1194
/* Parse a register operand, or part of an operand, starting at *P.
1195
   If syntactically OK (including that the number is in the range 0 to
1196
   31, but not necessarily in range for this architecture), return
1197
   TRUE, putting the register side and number in *REG and update *P to
1198
   point immediately after the register number; otherwise return FALSE
1199
   without changing *P (but possibly changing *REG).  Do not print any
1200
   diagnostics.  */
1201
 
1202
static bfd_boolean
1203
tic6x_parse_register (char **p, tic6x_register *reg)
1204
{
1205
  char *r = *p;
1206
 
1207
  switch (*r)
1208
    {
1209
    case 'a':
1210
    case 'A':
1211
      reg->side = 1;
1212
      break;
1213
 
1214
    case 'b':
1215
    case 'B':
1216
      reg->side = 2;
1217
      break;
1218
 
1219
    default:
1220
      return FALSE;
1221
    }
1222
  r++;
1223
 
1224
  if (*r >= '0' && *r <= '9')
1225
    {
1226
      reg->num = *r - '0';
1227
      r++;
1228
    }
1229
  else
1230
    return FALSE;
1231
 
1232
  if (reg->num > 0 && *r >= '0' && *r <= '9')
1233
    {
1234
      reg->num = reg->num * 10 + (*r - '0');
1235
      r++;
1236
    }
1237
 
1238
  if (*r >= '0' && *r <= '9')
1239
    return FALSE;
1240
 
1241
  if (reg->num >= 32)
1242
    return FALSE;
1243
  *p = r;
1244
  return TRUE;
1245
}
1246
 
1247
/* Parse the initial two characters of a functional unit name starting
1248
   at *P.  If OK, set *BASE and *SIDE and return TRUE; otherwise,
1249
   return FALSE.  */
1250
 
1251
static bfd_boolean
1252
tic6x_parse_func_unit_base (char *p, tic6x_func_unit_base *base,
1253
                            unsigned int *side)
1254
{
1255
  bfd_boolean good_func_unit = TRUE;
1256
  tic6x_func_unit_base maybe_base = tic6x_func_unit_nfu;
1257
  unsigned int maybe_side = 0;
1258
 
1259
  switch (p[0])
1260
    {
1261
    case 'd':
1262
    case 'D':
1263
      maybe_base = tic6x_func_unit_d;
1264
      break;
1265
 
1266
    case 'l':
1267
    case 'L':
1268
      maybe_base = tic6x_func_unit_l;
1269
      break;
1270
 
1271
    case 'm':
1272
    case 'M':
1273
      maybe_base = tic6x_func_unit_m;
1274
      break;
1275
 
1276
    case 's':
1277
    case 'S':
1278
      maybe_base = tic6x_func_unit_s;
1279
      break;
1280
 
1281
    default:
1282
      good_func_unit = FALSE;
1283
      break;
1284
    }
1285
 
1286
  if (good_func_unit)
1287
    switch (p[1])
1288
      {
1289
      case '1':
1290
        maybe_side = 1;
1291
        break;
1292
 
1293
      case '2':
1294
        maybe_side = 2;
1295
        break;
1296
 
1297
      default:
1298
        good_func_unit = FALSE;
1299
        break;
1300
      }
1301
 
1302
  if (good_func_unit)
1303
    {
1304
      *base = maybe_base;
1305
      *side = maybe_side;
1306
    }
1307
 
1308
  return good_func_unit;
1309
}
1310
 
1311
/* Parse an operand starting at *P.  If the operand parses OK, return
1312
   TRUE and store the value in *OP; otherwise return FALSE (possibly
1313
   changing *OP).  In any case, update *P to point to the following
1314
   comma or end of line.  The possible operand forms are given by
1315
   OP_FORMS.  For diagnostics, this is operand OPNO of an opcode
1316
   starting at STR, length OPC_LEN.  */
1317
 
1318
static bfd_boolean
1319
tic6x_parse_operand (char **p, tic6x_operand *op, unsigned int op_forms,
1320
                     char *str, int opc_len, unsigned int opno)
1321
{
1322
  bfd_boolean operand_parsed = FALSE;
1323
  char *q = *p;
1324
 
1325
  if ((op_forms & (TIC6X_OP_MEM_NOUNREG | TIC6X_OP_MEM_UNREG))
1326
      == (TIC6X_OP_MEM_NOUNREG | TIC6X_OP_MEM_UNREG))
1327
    abort ();
1328
 
1329
  /* Check for functional unit names for SPMASK and SPMASKR.  */
1330
  if (!operand_parsed && (op_forms & TIC6X_OP_FUNC_UNIT))
1331
    {
1332
      tic6x_func_unit_base base = tic6x_func_unit_nfu;
1333
      unsigned int side = 0;
1334
 
1335
      if (tic6x_parse_func_unit_base (q, &base, &side))
1336
        {
1337
          char *rq = q + 2;
1338
 
1339
          skip_whitespace (rq);
1340
          if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
1341
            {
1342
              op->form = TIC6X_OP_FUNC_UNIT;
1343
              op->value.func_unit.base = base;
1344
              op->value.func_unit.side = side;
1345
              operand_parsed = TRUE;
1346
              q = rq;
1347
            }
1348
        }
1349
    }
1350
 
1351
  /* Check for literal "irp".  */
1352
  if (!operand_parsed && (op_forms & TIC6X_OP_IRP))
1353
    {
1354
      if ((q[0] == 'i' || q[0] == 'I')
1355
          && (q[1] == 'r' || q[1] == 'R')
1356
          && (q[2] == 'p' || q[2] == 'P'))
1357
        {
1358
          char *rq = q + 3;
1359
 
1360
          skip_whitespace (rq);
1361
          if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
1362
            {
1363
              op->form = TIC6X_OP_IRP;
1364
              operand_parsed = TRUE;
1365
              q = rq;
1366
            }
1367
        }
1368
    }
1369
 
1370
  /* Check for literal "nrp".  */
1371
  if (!operand_parsed && (op_forms & TIC6X_OP_NRP))
1372
    {
1373
      if ((q[0] == 'n' || q[0] == 'N')
1374
          && (q[1] == 'r' || q[1] == 'R')
1375
          && (q[2] == 'p' || q[2] == 'P'))
1376
        {
1377
          char *rq = q + 3;
1378
 
1379
          skip_whitespace (rq);
1380
          if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
1381
            {
1382
              op->form = TIC6X_OP_NRP;
1383
              operand_parsed = TRUE;
1384
              q = rq;
1385
            }
1386
        }
1387
    }
1388
 
1389
  /* Check for control register names.  */
1390
  if (!operand_parsed && (op_forms & TIC6X_OP_CTRL))
1391
    {
1392
      tic6x_ctrl_id crid;
1393
 
1394
      for (crid = 0; crid < tic6x_ctrl_max; crid++)
1395
        {
1396
          size_t len = strlen (tic6x_ctrl_table[crid].name);
1397
 
1398
          if (strncasecmp (tic6x_ctrl_table[crid].name, q, len) == 0)
1399
            {
1400
              char *rq = q + len;
1401
 
1402
              skip_whitespace (rq);
1403
              if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
1404
                {
1405
                  op->form = TIC6X_OP_CTRL;
1406
                  op->value.ctrl = crid;
1407
                  operand_parsed = TRUE;
1408
                  q = rq;
1409
                  if (!(tic6x_ctrl_table[crid].isa_variants & tic6x_features))
1410
                    as_bad (_("control register '%s' not supported "
1411
                              "on this architecture"),
1412
                            tic6x_ctrl_table[crid].name);
1413
                }
1414
            }
1415
        }
1416
    }
1417
 
1418
  /* See if this looks like a memory reference.  */
1419
  if (!operand_parsed
1420
      && (op_forms & (TIC6X_OP_MEM_NOUNREG | TIC6X_OP_MEM_UNREG)))
1421
    {
1422
      bfd_boolean mem_ok = TRUE;
1423
      char *mq = q;
1424
      tic6x_mem_mod mem_mod = tic6x_mem_mod_none;
1425
      tic6x_register base_reg;
1426
      bfd_boolean require_offset, permit_offset;
1427
      tic6x_mem_scaling scaled;
1428
      bfd_boolean offset_is_reg;
1429
      expressionS offset_exp;
1430
      tic6x_register offset_reg;
1431
 
1432
      if (*mq == '*')
1433
        mq++;
1434
      else
1435
        mem_ok = FALSE;
1436
 
1437
      if (mem_ok)
1438
        {
1439
          skip_whitespace (mq);
1440
          switch (*mq)
1441
            {
1442
            case '+':
1443
              if (mq[1] == '+')
1444
                {
1445
                  mem_mod = tic6x_mem_mod_preinc;
1446
                  mq += 2;
1447
                }
1448
              else
1449
                {
1450
                  mem_mod = tic6x_mem_mod_plus;
1451
                  mq++;
1452
                }
1453
              break;
1454
 
1455
            case '-':
1456
              if (mq[1] == '-')
1457
                {
1458
                  mem_mod = tic6x_mem_mod_predec;
1459
                  mq += 2;
1460
                }
1461
              else
1462
                {
1463
                  mem_mod = tic6x_mem_mod_minus;
1464
                  mq++;
1465
                }
1466
              break;
1467
 
1468
            default:
1469
              break;
1470
            }
1471
        }
1472
 
1473
      if (mem_ok)
1474
        {
1475
          skip_whitespace (mq);
1476
          mem_ok = tic6x_parse_register (&mq, &base_reg);
1477
        }
1478
 
1479
      if (mem_ok && mem_mod == tic6x_mem_mod_none)
1480
        {
1481
          skip_whitespace (mq);
1482
          if (mq[0] == '+' && mq[1] == '+')
1483
            {
1484
              mem_mod = tic6x_mem_mod_postinc;
1485
              mq += 2;
1486
            }
1487
          else if (mq[0] == '-' && mq[1] == '-')
1488
            {
1489
              mem_mod = tic6x_mem_mod_postdec;
1490
              mq += 2;
1491
            }
1492
        }
1493
 
1494
      if (mem_mod == tic6x_mem_mod_none)
1495
        permit_offset = FALSE;
1496
      else
1497
        permit_offset = TRUE;
1498
      if (mem_mod == tic6x_mem_mod_plus || mem_mod == tic6x_mem_mod_minus)
1499
        require_offset = TRUE;
1500
      else
1501
        require_offset = FALSE;
1502
      scaled = tic6x_offset_none;
1503
      offset_is_reg = FALSE;
1504
 
1505
      if (mem_ok && permit_offset)
1506
        {
1507
          char endc = 0;
1508
 
1509
          skip_whitespace (mq);
1510
          switch (*mq)
1511
            {
1512
            case '[':
1513
              scaled = tic6x_offset_scaled;
1514
              mq++;
1515
              endc = ']';
1516
              break;
1517
 
1518
            case '(':
1519
              scaled = tic6x_offset_unscaled;
1520
              mq++;
1521
              endc = ')';
1522
              break;
1523
 
1524
            default:
1525
              break;
1526
            }
1527
          if (scaled != tic6x_offset_none)
1528
            {
1529
              skip_whitespace (mq);
1530
              if (scaled == tic6x_offset_scaled
1531
                  || (op_forms & TIC6X_OP_MEM_UNREG))
1532
                {
1533
                  bfd_boolean reg_ok;
1534
                  char *rq = mq;
1535
 
1536
                  reg_ok = tic6x_parse_register (&rq, &offset_reg);
1537
                  if (reg_ok)
1538
                    {
1539
                      skip_whitespace (rq);
1540
                      if (*rq == endc)
1541
                        {
1542
                          mq = rq;
1543
                          offset_is_reg = TRUE;
1544
                        }
1545
                    }
1546
                }
1547
              if (!offset_is_reg)
1548
                {
1549
                  char *save_input_line_pointer;
1550
 
1551
                  save_input_line_pointer = input_line_pointer;
1552
                  input_line_pointer = mq;
1553
                  expression (&offset_exp);
1554
                  mq = input_line_pointer;
1555
                  input_line_pointer = save_input_line_pointer;
1556
                }
1557
              skip_whitespace (mq);
1558
              if (*mq == endc)
1559
                mq++;
1560
              else
1561
                mem_ok = FALSE;
1562
            }
1563
        }
1564
 
1565
      if (mem_ok && require_offset && scaled == tic6x_offset_none)
1566
        mem_ok = FALSE;
1567
 
1568
      if (mem_ok)
1569
        {
1570
          skip_whitespace (mq);
1571
          if (!is_end_of_line[(unsigned char) *mq] && *mq != ',')
1572
            mem_ok = FALSE;
1573
        }
1574
 
1575
      if (mem_ok)
1576
        {
1577
          op->form = op_forms & (TIC6X_OP_MEM_NOUNREG | TIC6X_OP_MEM_UNREG);
1578
          op->value.mem.base_reg = base_reg;
1579
          op->value.mem.mod = mem_mod;
1580
          op->value.mem.scaled = scaled;
1581
          op->value.mem.offset_is_reg = offset_is_reg;
1582
          if (offset_is_reg)
1583
            op->value.mem.offset.reg = offset_reg;
1584
          else
1585
            op->value.mem.offset.exp = offset_exp;
1586
          operand_parsed = TRUE;
1587
          q = mq;
1588
          if (base_reg.num >= tic6x_num_registers)
1589
            as_bad (_("register number %u not supported on this architecture"),
1590
                    base_reg.num);
1591
          if (offset_is_reg && offset_reg.num >= tic6x_num_registers)
1592
            as_bad (_("register number %u not supported on this architecture"),
1593
                    offset_reg.num);
1594
        }
1595
    }
1596
 
1597
  /* See if this looks like a register or register pair.  */
1598
  if (!operand_parsed && (op_forms & (TIC6X_OP_REG | TIC6X_OP_REGPAIR)))
1599
    {
1600
      tic6x_register first_reg, second_reg;
1601
      bfd_boolean reg_ok;
1602
      char *rq = q;
1603
 
1604
      reg_ok = tic6x_parse_register (&rq, &first_reg);
1605
 
1606
      if (reg_ok)
1607
        {
1608
          if (*rq == ':' && (op_forms & TIC6X_OP_REGPAIR))
1609
            {
1610
              rq++;
1611
              reg_ok = tic6x_parse_register (&rq, &second_reg);
1612
              if (reg_ok)
1613
                {
1614
                  skip_whitespace (rq);
1615
                  if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
1616
                    {
1617
                      if ((second_reg.num & 1)
1618
                          || (first_reg.num != second_reg.num + 1)
1619
                          || (first_reg.side != second_reg.side))
1620
                        as_bad (_("register pair for operand %u of '%.*s'"
1621
                                  " not a valid even/odd pair"), opno,
1622
                                opc_len, str);
1623
                      op->form = TIC6X_OP_REGPAIR;
1624
                      op->value.reg = second_reg;
1625
                      operand_parsed = TRUE;
1626
                      q = rq;
1627
                    }
1628
                }
1629
            }
1630
          else if (op_forms & TIC6X_OP_REG)
1631
            {
1632
              skip_whitespace (rq);
1633
              if (is_end_of_line[(unsigned char) *rq] || *rq == ',')
1634
                {
1635
                  op->form = TIC6X_OP_REG;
1636
                  op->value.reg = first_reg;
1637
                  operand_parsed = TRUE;
1638
                  q = rq;
1639
                }
1640
            }
1641
        }
1642
      if (operand_parsed)
1643
        {
1644
          if (first_reg.num >= tic6x_num_registers)
1645
            as_bad (_("register number %u not supported on this architecture"),
1646
                    first_reg.num);
1647
          if (op->form == TIC6X_OP_REGPAIR
1648
              && second_reg.num >= tic6x_num_registers)
1649
            as_bad (_("register number %u not supported on this architecture"),
1650
                    second_reg.num);
1651
        }
1652
    }
1653
 
1654
  /* Otherwise, parse it as an expression.  */
1655
  if (!operand_parsed && (op_forms & TIC6X_OP_EXP))
1656
    {
1657
      char *save_input_line_pointer;
1658
 
1659
      save_input_line_pointer = input_line_pointer;
1660
      input_line_pointer = q;
1661
      op->form = TIC6X_OP_EXP;
1662
      expression (&op->value.exp);
1663
      q = input_line_pointer;
1664
      input_line_pointer = save_input_line_pointer;
1665
      operand_parsed = TRUE;
1666
    }
1667
 
1668
  if (operand_parsed)
1669
    {
1670
      /* Now the operand has been parsed, there must be nothing more
1671
         before the comma or end of line.  */
1672
      skip_whitespace (q);
1673
      if (!is_end_of_line[(unsigned char) *q] && *q != ',')
1674
        {
1675
          operand_parsed = FALSE;
1676
          as_bad (_("junk after operand %u of '%.*s'"), opno,
1677
                  opc_len, str);
1678
          while (!is_end_of_line[(unsigned char) *q] && *q != ',')
1679
            q++;
1680
        }
1681
    }
1682
  else
1683
    {
1684
      /* This could not be parsed as any acceptable form of
1685
         operand.  */
1686
      switch (op_forms)
1687
        {
1688
        case TIC6X_OP_REG | TIC6X_OP_REGPAIR:
1689
          as_bad (_("bad register or register pair for operand %u of '%.*s'"),
1690
                  opno, opc_len, str);
1691
          break;
1692
 
1693
        case TIC6X_OP_REG | TIC6X_OP_CTRL:
1694
        case TIC6X_OP_REG:
1695
          as_bad (_("bad register for operand %u of '%.*s'"),
1696
                  opno, opc_len, str);
1697
          break;
1698
 
1699
        case TIC6X_OP_REGPAIR:
1700
          as_bad (_("bad register pair for operand %u of '%.*s'"),
1701
                  opno, opc_len, str);
1702
          break;
1703
 
1704
        case TIC6X_OP_FUNC_UNIT:
1705
          as_bad (_("bad functional unit for operand %u of '%.*s'"),
1706
                  opno, opc_len, str);
1707
          break;
1708
 
1709
        default:
1710
          as_bad (_("bad operand %u of '%.*s'"),
1711
                  opno, opc_len, str);
1712
          break;
1713
 
1714
        }
1715
      while (!is_end_of_line[(unsigned char) *q] && *q != ',')
1716
        q++;
1717
    }
1718
  *p = q;
1719
  return operand_parsed;
1720
}
1721
 
1722
/* Table of assembler operators and associated O_* values.  */
1723
typedef struct
1724
{
1725
  const char *name;
1726
  operatorT op;
1727
} tic6x_operator_table;
1728
static const tic6x_operator_table tic6x_operators[] = {
1729
#define O_dsbt_index O_md1
1730
  { "dsbt_index", O_dsbt_index },
1731
#define O_got O_md2
1732
  { "got", O_got },
1733
#define O_dpr_got O_md3
1734
  { "dpr_got", O_dpr_got },
1735
#define O_dpr_byte O_md4
1736
  { "dpr_byte", O_dpr_byte },
1737
#define O_dpr_hword O_md5
1738
  { "dpr_hword", O_dpr_hword },
1739
#define O_dpr_word O_md6
1740
  { "dpr_word", O_dpr_word },
1741
#define O_pcr_offset O_md7
1742
  { "pcr_offset", O_pcr_offset }
1743
};
1744
 
1745
/* Parse a name in some machine-specific way.  Used on C6X to handle
1746
   assembler operators.  */
1747
 
1748
int
1749
tic6x_parse_name (const char *name, expressionS *exprP,
1750
                  enum expr_mode mode ATTRIBUTE_UNUSED, char *nextchar)
1751
{
1752
  char *p = input_line_pointer;
1753
  char c, *name_start, *name_end;
1754
  const char *inner_name;
1755
  unsigned int i;
1756
  operatorT op = O_illegal;
1757
  symbolS *sym, *op_sym = NULL;
1758
 
1759
  if (*name != '$')
1760
    return 0;
1761
 
1762
  for (i = 0; i < ARRAY_SIZE (tic6x_operators); i++)
1763
    if (strcasecmp (name + 1, tic6x_operators[i].name) == 0)
1764
      {
1765
        op = tic6x_operators[i].op;
1766
        break;
1767
      }
1768
 
1769
  if (op == O_illegal)
1770
    return 0;
1771
 
1772
  *input_line_pointer = *nextchar;
1773
  skip_whitespace (p);
1774
 
1775
  if (*p != '(')
1776
    {
1777
      *input_line_pointer = 0;
1778
      return 0;
1779
    }
1780
  p++;
1781
  skip_whitespace (p);
1782
 
1783
  if (!is_name_beginner (*p))
1784
    {
1785
      *input_line_pointer = 0;
1786
      return 0;
1787
    }
1788
 
1789
  name_start = p;
1790
  p++;
1791
  while (is_part_of_name (*p))
1792
    p++;
1793
  name_end = p;
1794
  skip_whitespace (p);
1795
 
1796
  if (op == O_pcr_offset)
1797
    {
1798
      char *op_name_start, *op_name_end;
1799
 
1800
      if (*p != ',')
1801
        {
1802
          *input_line_pointer = 0;
1803
          return 0;
1804
        }
1805
      p++;
1806
      skip_whitespace (p);
1807
 
1808
      if (!is_name_beginner (*p))
1809
        {
1810
          *input_line_pointer = 0;
1811
          return 0;
1812
        }
1813
 
1814
      op_name_start = p;
1815
      p++;
1816
      while (is_part_of_name (*p))
1817
        p++;
1818
      op_name_end = p;
1819
      skip_whitespace (p);
1820
 
1821
      c = *op_name_end;
1822
      *op_name_end = 0;
1823
      op_sym = symbol_find_or_make (op_name_start);
1824
      *op_name_end = c;
1825
    }
1826
 
1827
  if (*p != ')')
1828
    {
1829
      *input_line_pointer = 0;
1830
      return 0;
1831
    }
1832
 
1833
  input_line_pointer = p + 1;
1834
  *nextchar = *input_line_pointer;
1835
  *input_line_pointer = 0;
1836
 
1837
  c = *name_end;
1838
  *name_end = 0;
1839
  inner_name = name_start;
1840
  if (op == O_dsbt_index && strcmp (inner_name, "__c6xabi_DSBT_BASE") != 0)
1841
    {
1842
      as_bad (_("$DSBT_INDEX must be used with __c6xabi_DSBT_BASE"));
1843
      inner_name = "__c6xabi_DSBT_BASE";
1844
    }
1845
  sym = symbol_find_or_make (inner_name);
1846
  *name_end = c;
1847
 
1848
  exprP->X_op = op;
1849
  exprP->X_add_symbol = sym;
1850
  exprP->X_add_number = 0;
1851
  exprP->X_op_symbol = op_sym;
1852
  exprP->X_md = 0;
1853
 
1854
  return 1;
1855
}
1856
 
1857
/* Create a fixup for an expression.  Same arguments as fix_new_exp,
1858
   plus FIX_ADDA which is TRUE for ADDA instructions (to indicate that
1859
   fixes resolving to constants should have those constants implicitly
1860
   shifted) and FALSE otherwise, but look for C6X-specific expression
1861
   types and adjust the relocations or give errors accordingly.  */
1862
 
1863
static void
1864
tic6x_fix_new_exp (fragS *frag, int where, int size, expressionS *exp,
1865
                   int pcrel, bfd_reloc_code_real_type r_type,
1866
                   bfd_boolean fix_adda)
1867
{
1868
  bfd_reloc_code_real_type new_reloc = BFD_RELOC_UNUSED;
1869
  symbolS *subsy = NULL;
1870
  fixS *fix;
1871
 
1872
  switch (exp->X_op)
1873
    {
1874
    case O_dsbt_index:
1875
      switch (r_type)
1876
        {
1877
        case BFD_RELOC_C6000_SBR_U15_W:
1878
          new_reloc = BFD_RELOC_C6000_DSBT_INDEX;
1879
          break;
1880
 
1881
        default:
1882
          as_bad (_("$DSBT_INDEX not supported in this context"));
1883
          return;
1884
        }
1885
      break;
1886
 
1887
    case O_got:
1888
      switch (r_type)
1889
        {
1890
        case BFD_RELOC_C6000_SBR_U15_W:
1891
          new_reloc = BFD_RELOC_C6000_SBR_GOT_U15_W;
1892
          break;
1893
 
1894
        default:
1895
          as_bad (_("$GOT not supported in this context"));
1896
          return;
1897
        }
1898
      break;
1899
 
1900
    case O_dpr_got:
1901
      switch (r_type)
1902
        {
1903
        case BFD_RELOC_C6000_ABS_L16:
1904
          new_reloc = BFD_RELOC_C6000_SBR_GOT_L16_W;
1905
          break;
1906
 
1907
        case BFD_RELOC_C6000_ABS_H16:
1908
          new_reloc = BFD_RELOC_C6000_SBR_GOT_H16_W;
1909
          break;
1910
 
1911
        default:
1912
          as_bad (_("$DPR_GOT not supported in this context"));
1913
          return;
1914
        }
1915
      break;
1916
 
1917
    case O_dpr_byte:
1918
      switch (r_type)
1919
        {
1920
        case BFD_RELOC_C6000_ABS_S16:
1921
          new_reloc = BFD_RELOC_C6000_SBR_S16;
1922
          break;
1923
 
1924
        case BFD_RELOC_C6000_ABS_L16:
1925
          new_reloc = BFD_RELOC_C6000_SBR_L16_B;
1926
          break;
1927
 
1928
        case BFD_RELOC_C6000_ABS_H16:
1929
          new_reloc = BFD_RELOC_C6000_SBR_H16_B;
1930
          break;
1931
 
1932
        default:
1933
          as_bad (_("$DPR_BYTE not supported in this context"));
1934
          return;
1935
        }
1936
      break;
1937
 
1938
    case O_dpr_hword:
1939
      switch (r_type)
1940
        {
1941
        case BFD_RELOC_C6000_ABS_L16:
1942
          new_reloc = BFD_RELOC_C6000_SBR_L16_H;
1943
          break;
1944
 
1945
        case BFD_RELOC_C6000_ABS_H16:
1946
          new_reloc = BFD_RELOC_C6000_SBR_H16_H;
1947
          break;
1948
 
1949
        default:
1950
          as_bad (_("$DPR_HWORD not supported in this context"));
1951
          return;
1952
        }
1953
      break;
1954
 
1955
    case O_dpr_word:
1956
      switch (r_type)
1957
        {
1958
        case BFD_RELOC_C6000_ABS_L16:
1959
          new_reloc = BFD_RELOC_C6000_SBR_L16_W;
1960
          break;
1961
 
1962
        case BFD_RELOC_C6000_ABS_H16:
1963
          new_reloc = BFD_RELOC_C6000_SBR_H16_W;
1964
          break;
1965
 
1966
        default:
1967
          as_bad (_("$DPR_WORD not supported in this context"));
1968
          return;
1969
        }
1970
      break;
1971
 
1972
    case O_pcr_offset:
1973
      subsy = exp->X_op_symbol;
1974
      switch (r_type)
1975
        {
1976
        case BFD_RELOC_C6000_ABS_S16:
1977
        case BFD_RELOC_C6000_ABS_L16:
1978
          new_reloc = BFD_RELOC_C6000_PCR_L16;
1979
          break;
1980
 
1981
        case BFD_RELOC_C6000_ABS_H16:
1982
          new_reloc = BFD_RELOC_C6000_PCR_H16;
1983
          break;
1984
 
1985
        default:
1986
          as_bad (_("$PCR_OFFSET not supported in this context"));
1987
          return;
1988
        }
1989
      break;
1990
 
1991
    case O_symbol:
1992
      break;
1993
 
1994
    default:
1995
      if (pcrel)
1996
        {
1997
          as_bad (_("invalid PC-relative operand"));
1998
          return;
1999
        }
2000
      break;
2001
    }
2002
 
2003
  if (new_reloc == BFD_RELOC_UNUSED)
2004
    fix = fix_new_exp (frag, where, size, exp, pcrel, r_type);
2005
  else
2006
    fix = fix_new (frag, where, size, exp->X_add_symbol, exp->X_add_number,
2007
                   pcrel, new_reloc);
2008
  fix->tc_fix_data.fix_subsy = subsy;
2009
  fix->tc_fix_data.fix_adda = fix_adda;
2010
}
2011
 
2012
/* Generate a fix for a constant (.word etc.).  Needed to ensure these
2013
   go through the error checking in tic6x_fix_new_exp.  */
2014
 
2015
void
2016
tic6x_cons_fix_new (fragS *frag, int where, int size, expressionS *exp)
2017
{
2018
  bfd_reloc_code_real_type r_type;
2019
 
2020
  switch (size)
2021
    {
2022
    case 1:
2023
      r_type = BFD_RELOC_8;
2024
      break;
2025
 
2026
    case 2:
2027
      r_type = BFD_RELOC_16;
2028
      break;
2029
 
2030
    case 4:
2031
      r_type = BFD_RELOC_32;
2032
      break;
2033
 
2034
    default:
2035
      as_bad (_("no %d-byte relocations available"), size);
2036
      return;
2037
    }
2038
 
2039
  tic6x_fix_new_exp (frag, where, size, exp, 0, r_type, FALSE);
2040
}
2041
 
2042
/* Initialize target-specific fix data.  */
2043
 
2044
void
2045
tic6x_init_fix_data (fixS *fixP)
2046
{
2047
  fixP->tc_fix_data.fix_adda = FALSE;
2048
  fixP->tc_fix_data.fix_subsy = NULL;
2049
}
2050
 
2051
/* Return true if the fix can be handled by GAS, false if it must
2052
   be passed through to the linker.  */
2053
 
2054
bfd_boolean
2055
tic6x_fix_adjustable (fixS *fixP)
2056
{
2057
  switch (fixP->fx_r_type)
2058
    {
2059
      /* Adjust_reloc_syms doesn't know about the GOT.  */
2060
    case BFD_RELOC_C6000_SBR_GOT_U15_W:
2061
    case BFD_RELOC_C6000_SBR_GOT_H16_W:
2062
    case BFD_RELOC_C6000_SBR_GOT_L16_W:
2063
    case BFD_RELOC_C6000_EHTYPE:
2064
      return 0;
2065
 
2066
    case BFD_RELOC_C6000_PREL31:
2067
      return 0;
2068
 
2069
    case BFD_RELOC_C6000_PCR_H16:
2070
    case BFD_RELOC_C6000_PCR_L16:
2071
      return 0;
2072
 
2073
    default:
2074
      return 1;
2075
    }
2076
}
2077
 
2078
/* Given the fine-grained form of an operand, return the coarse
2079
   (bit-mask) form.  */
2080
 
2081
static unsigned int
2082
tic6x_coarse_operand_form (tic6x_operand_form form)
2083
{
2084
  switch (form)
2085
    {
2086
    case tic6x_operand_asm_const:
2087
    case tic6x_operand_link_const:
2088
      return TIC6X_OP_EXP;
2089
 
2090
    case tic6x_operand_reg:
2091
    case tic6x_operand_xreg:
2092
    case tic6x_operand_dreg:
2093
    case tic6x_operand_areg:
2094
    case tic6x_operand_retreg:
2095
      return TIC6X_OP_REG;
2096
 
2097
    case tic6x_operand_regpair:
2098
    case tic6x_operand_xregpair:
2099
    case tic6x_operand_dregpair:
2100
      return TIC6X_OP_REGPAIR;
2101
 
2102
    case tic6x_operand_irp:
2103
      return TIC6X_OP_IRP;
2104
 
2105
    case tic6x_operand_nrp:
2106
      return TIC6X_OP_NRP;
2107
 
2108
    case tic6x_operand_ctrl:
2109
      return TIC6X_OP_CTRL;
2110
 
2111
    case tic6x_operand_mem_short:
2112
    case tic6x_operand_mem_long:
2113
    case tic6x_operand_mem_deref:
2114
      return TIC6X_OP_MEM_NOUNREG;
2115
 
2116
    case tic6x_operand_mem_ndw:
2117
      return TIC6X_OP_MEM_UNREG;
2118
 
2119
    case tic6x_operand_func_unit:
2120
      return TIC6X_OP_FUNC_UNIT;
2121
 
2122
    default:
2123
      abort ();
2124
    }
2125
}
2126
 
2127
/* How an operand may match or not match a desired form.  If different
2128
   instruction alternatives fail in different ways, the first failure
2129
   in this list determines the diagnostic.  */
2130
typedef enum
2131
  {
2132
    /* Matches.  */
2133
    tic6x_match_matches,
2134
    /* Bad coarse form.  */
2135
    tic6x_match_coarse,
2136
    /* Not constant.  */
2137
    tic6x_match_non_const,
2138
    /* Register on wrong side.  */
2139
    tic6x_match_wrong_side,
2140
    /* Not a valid address register.  */
2141
    tic6x_match_bad_address,
2142
    /* Not a valid return address register.  */
2143
    tic6x_match_bad_return,
2144
    /* Control register not readable.  */
2145
    tic6x_match_ctrl_write_only,
2146
    /* Control register not writable.  */
2147
    tic6x_match_ctrl_read_only,
2148
    /* Not a valid memory reference for this instruction.  */
2149
    tic6x_match_bad_mem
2150
  } tic6x_operand_match;
2151
 
2152
/* Return whether an operand matches the given fine-grained form and
2153
   read/write usage, and, if it does not match, how it fails to match.
2154
   The main functional unit side is SIDE; the cross-path side is CROSS
2155
   (the same as SIDE if a cross path not used); the data side is
2156
   DATA_SIDE.  */
2157
static tic6x_operand_match
2158
tic6x_operand_matches_form (const tic6x_operand *op, tic6x_operand_form form,
2159
                            tic6x_rw rw, unsigned int side, unsigned int cross,
2160
                            unsigned int data_side)
2161
{
2162
  unsigned int coarse = tic6x_coarse_operand_form (form);
2163
 
2164
  if (coarse != op->form)
2165
    return tic6x_match_coarse;
2166
 
2167
  switch (form)
2168
    {
2169
    case tic6x_operand_asm_const:
2170
      if (op->value.exp.X_op == O_constant)
2171
        return tic6x_match_matches;
2172
      else
2173
        return tic6x_match_non_const;
2174
 
2175
    case tic6x_operand_link_const:
2176
    case tic6x_operand_irp:
2177
    case tic6x_operand_nrp:
2178
    case tic6x_operand_func_unit:
2179
      /* All expressions are link-time constants, although there may
2180
         not be relocations to express them in the output file.  "irp"
2181
         and "nrp" are unique operand values.  All parsed functional
2182
         unit names are valid.  */
2183
      return tic6x_match_matches;
2184
 
2185
    case tic6x_operand_reg:
2186
    case tic6x_operand_regpair:
2187
      if (op->value.reg.side == side)
2188
        return tic6x_match_matches;
2189
      else
2190
        return tic6x_match_wrong_side;
2191
 
2192
    case tic6x_operand_xreg:
2193
    case tic6x_operand_xregpair:
2194
      if (op->value.reg.side == cross)
2195
        return tic6x_match_matches;
2196
      else
2197
        return tic6x_match_wrong_side;
2198
 
2199
    case tic6x_operand_dreg:
2200
    case tic6x_operand_dregpair:
2201
      if (op->value.reg.side == data_side)
2202
        return tic6x_match_matches;
2203
      else
2204
        return tic6x_match_wrong_side;
2205
 
2206
    case tic6x_operand_areg:
2207
      if (op->value.reg.side != cross)
2208
        return tic6x_match_wrong_side;
2209
      else if (op->value.reg.side == 2
2210
               && (op->value.reg.num == 14 || op->value.reg.num == 15))
2211
        return tic6x_match_matches;
2212
      else
2213
        return tic6x_match_bad_address;
2214
 
2215
    case tic6x_operand_retreg:
2216
      if (op->value.reg.side != side)
2217
        return tic6x_match_wrong_side;
2218
      else if (op->value.reg.num != 3)
2219
        return tic6x_match_bad_return;
2220
      else
2221
        return tic6x_match_matches;
2222
 
2223
    case tic6x_operand_ctrl:
2224
      switch (rw)
2225
        {
2226
        case tic6x_rw_read:
2227
          if (tic6x_ctrl_table[op->value.ctrl].rw == tic6x_rw_read
2228
              || tic6x_ctrl_table[op->value.ctrl].rw == tic6x_rw_read_write)
2229
            return tic6x_match_matches;
2230
          else
2231
            return tic6x_match_ctrl_write_only;
2232
 
2233
        case tic6x_rw_write:
2234
          if (tic6x_ctrl_table[op->value.ctrl].rw == tic6x_rw_write
2235
              || tic6x_ctrl_table[op->value.ctrl].rw == tic6x_rw_read_write)
2236
            return tic6x_match_matches;
2237
          else
2238
            return tic6x_match_ctrl_read_only;
2239
 
2240
        default:
2241
          abort ();
2242
        }
2243
 
2244
    case tic6x_operand_mem_deref:
2245
      if (op->value.mem.mod != tic6x_mem_mod_none)
2246
        return tic6x_match_bad_mem;
2247
      else if (op->value.mem.scaled != tic6x_offset_none)
2248
        abort ();
2249
      else if (op->value.mem.base_reg.side != side)
2250
        return tic6x_match_bad_mem;
2251
      else
2252
        return tic6x_match_matches;
2253
 
2254
    case tic6x_operand_mem_short:
2255
    case tic6x_operand_mem_ndw:
2256
      if (op->value.mem.base_reg.side != side)
2257
        return tic6x_match_bad_mem;
2258
      if (op->value.mem.mod == tic6x_mem_mod_none)
2259
        {
2260
          if (op->value.mem.scaled != tic6x_offset_none)
2261
            abort ();
2262
          return tic6x_match_matches;
2263
        }
2264
      if (op->value.mem.scaled == tic6x_offset_none)
2265
        {
2266
          if (op->value.mem.mod == tic6x_mem_mod_plus
2267
              || op->value.mem.mod == tic6x_mem_mod_minus)
2268
            abort ();
2269
          return tic6x_match_matches;
2270
        }
2271
      if (op->value.mem.offset_is_reg)
2272
        {
2273
          if (op->value.mem.scaled == tic6x_offset_unscaled
2274
              && form != tic6x_operand_mem_ndw)
2275
            abort ();
2276
          if (op->value.mem.offset.reg.side == side)
2277
            return tic6x_match_matches;
2278
          else
2279
            return tic6x_match_bad_mem;
2280
        }
2281
      else
2282
        {
2283
          if (op->value.mem.offset.exp.X_op == O_constant)
2284
            return tic6x_match_matches;
2285
          else
2286
            return tic6x_match_bad_mem;
2287
        }
2288
 
2289
    case tic6x_operand_mem_long:
2290
      if (op->value.mem.base_reg.side == 2
2291
          && (op->value.mem.base_reg.num == 14
2292
              || op->value.mem.base_reg.num == 15))
2293
        {
2294
          switch (op->value.mem.mod)
2295
            {
2296
            case tic6x_mem_mod_none:
2297
              if (op->value.mem.scaled != tic6x_offset_none)
2298
                abort ();
2299
              return tic6x_match_matches;
2300
 
2301
            case tic6x_mem_mod_plus:
2302
              if (op->value.mem.scaled == tic6x_offset_none)
2303
                abort ();
2304
              if (op->value.mem.offset_is_reg)
2305
                return tic6x_match_bad_mem;
2306
              else if (op->value.mem.scaled == tic6x_offset_scaled
2307
                       && op->value.mem.offset.exp.X_op != O_constant)
2308
                return tic6x_match_bad_mem;
2309
              else
2310
                return tic6x_match_matches;
2311
 
2312
            case tic6x_mem_mod_minus:
2313
            case tic6x_mem_mod_preinc:
2314
            case tic6x_mem_mod_predec:
2315
            case tic6x_mem_mod_postinc:
2316
            case tic6x_mem_mod_postdec:
2317
              return tic6x_match_bad_mem;
2318
 
2319
            default:
2320
              abort ();
2321
            }
2322
 
2323
        }
2324
      else
2325
        return tic6x_match_bad_mem;
2326
 
2327
    default:
2328
      abort ();
2329
    }
2330
}
2331
 
2332
/* Return the number of bits shift used with DP-relative coding method
2333
   CODING.  */
2334
 
2335
static unsigned int
2336
tic6x_dpr_shift (tic6x_coding_method coding)
2337
{
2338
  switch (coding)
2339
    {
2340
    case tic6x_coding_ulcst_dpr_byte:
2341
      return 0;
2342
 
2343
    case tic6x_coding_ulcst_dpr_half:
2344
      return 1;
2345
 
2346
    case tic6x_coding_ulcst_dpr_word:
2347
      return 2;
2348
 
2349
    default:
2350
      abort ();
2351
    }
2352
}
2353
 
2354
/* Return the relocation used with DP-relative coding method
2355
   CODING.  */
2356
 
2357
static bfd_reloc_code_real_type
2358
tic6x_dpr_reloc (tic6x_coding_method coding)
2359
{
2360
  switch (coding)
2361
    {
2362
    case tic6x_coding_ulcst_dpr_byte:
2363
      return BFD_RELOC_C6000_SBR_U15_B;
2364
 
2365
    case tic6x_coding_ulcst_dpr_half:
2366
      return BFD_RELOC_C6000_SBR_U15_H;
2367
 
2368
    case tic6x_coding_ulcst_dpr_word:
2369
      return BFD_RELOC_C6000_SBR_U15_W;
2370
 
2371
    default:
2372
      abort ();
2373
    }
2374
}
2375
 
2376
/* Given a memory reference *MEM_REF as originally parsed, fill in
2377
   defaults for missing offsets.  */
2378
 
2379
static void
2380
tic6x_default_mem_ref (tic6x_mem_ref *mem_ref)
2381
{
2382
  switch (mem_ref->mod)
2383
    {
2384
    case tic6x_mem_mod_none:
2385
      if (mem_ref->scaled != tic6x_offset_none)
2386
        abort ();
2387
      mem_ref->mod = tic6x_mem_mod_plus;
2388
      mem_ref->scaled = tic6x_offset_unscaled;
2389
      mem_ref->offset_is_reg = FALSE;
2390
      memset (&mem_ref->offset.exp, 0, sizeof mem_ref->offset.exp);
2391
      mem_ref->offset.exp.X_op = O_constant;
2392
      mem_ref->offset.exp.X_add_number = 0;
2393
      mem_ref->offset.exp.X_unsigned = 0;
2394
      break;
2395
 
2396
    case tic6x_mem_mod_plus:
2397
    case tic6x_mem_mod_minus:
2398
      if (mem_ref->scaled == tic6x_offset_none)
2399
        abort ();
2400
      break;
2401
 
2402
    case tic6x_mem_mod_preinc:
2403
    case tic6x_mem_mod_predec:
2404
    case tic6x_mem_mod_postinc:
2405
    case tic6x_mem_mod_postdec:
2406
      if (mem_ref->scaled != tic6x_offset_none)
2407
        break;
2408
      mem_ref->scaled = tic6x_offset_scaled;
2409
      mem_ref->offset_is_reg = FALSE;
2410
      memset (&mem_ref->offset.exp, 0, sizeof mem_ref->offset.exp);
2411
      mem_ref->offset.exp.X_op = O_constant;
2412
      mem_ref->offset.exp.X_add_number = 1;
2413
      mem_ref->offset.exp.X_unsigned = 0;
2414
      break;
2415
 
2416
    default:
2417
      abort ();
2418
    }
2419
}
2420
 
2421
/* Return the encoding in the 8-bit field of an SPMASK or SPMASKR
2422
   instruction of the specified UNIT, side SIDE.  */
2423
 
2424
static unsigned int
2425
tic6x_encode_spmask (tic6x_func_unit_base unit, unsigned int side)
2426
{
2427
  switch (unit)
2428
    {
2429
    case tic6x_func_unit_l:
2430
      return 1 << (side - 1);
2431
 
2432
    case tic6x_func_unit_s:
2433
      return 1 << (side + 1);
2434
 
2435
    case tic6x_func_unit_d:
2436
      return 1 << (side + 3);
2437
 
2438
    case tic6x_func_unit_m:
2439
      return 1 << (side + 5);
2440
 
2441
    default:
2442
      abort ();
2443
    }
2444
}
2445
 
2446
/* Try to encode the instruction with opcode number ID and operands
2447
   OPERANDS (number NUM_OPERANDS), creg value THIS_LINE_CREG and z
2448
   value THIS_LINE_Z; FUNC_UNIT_SIDE, FUNC_UNIT_CROSS and
2449
   FUNC_UNIT_DATA_SIDE describe the functional unit specification;
2450
   SPLOOP_II is the ii value from the previous SPLOOP-family
2451
   instruction, or 0 if not in such a loop; the only possible problems
2452
   are operands being out of range (they already match the
2453
   fine-grained form), and inappropriate predication.  If this
2454
   succeeds, return the encoding and set *OK to TRUE; otherwise return
2455
 
2456
   true and fill in *FIX_EXP, *FIX_PCREL, *FX_R_TYPE and *FIX_ADDA.
2457
   Print error messages for failure if PRINT_ERRORS is TRUE; the
2458
   opcode starts at STR and has length OPC_LEN.  */
2459
 
2460
static unsigned int
2461
tic6x_try_encode (tic6x_opcode_id id, tic6x_operand *operands,
2462
                  unsigned int num_operands, unsigned int this_line_creg,
2463
                  unsigned int this_line_z, unsigned int func_unit_side,
2464
                  unsigned int func_unit_cross,
2465
                  unsigned int func_unit_data_side, int sploop_ii,
2466
                  expressionS **fix_exp, int *fix_pcrel,
2467
                  bfd_reloc_code_real_type *fx_r_type, bfd_boolean *fix_adda,
2468
                  bfd_boolean *fix_needed, bfd_boolean *ok,
2469
                  bfd_boolean print_errors, char *str, int opc_len)
2470
{
2471
  const tic6x_opcode *opct;
2472
  const tic6x_insn_format *fmt;
2473
  unsigned int opcode_value;
2474
  unsigned int fld;
2475
 
2476
  opct = &tic6x_opcode_table[id];
2477
  fmt = &tic6x_insn_format_table[opct->format];
2478
  opcode_value = fmt->cst_bits;
2479
 
2480
  for (fld = 0; fld < opct->num_fixed_fields; fld++)
2481
    {
2482
      if (opct->fixed_fields[fld].min_val == opct->fixed_fields[fld].max_val)
2483
        {
2484
          const tic6x_insn_field *fldd;
2485
          fldd = tic6x_field_from_fmt (fmt, opct->fixed_fields[fld].field_id);
2486
          if (fldd == NULL)
2487
            abort ();
2488
          opcode_value |= opct->fixed_fields[fld].min_val << fldd->low_pos;
2489
        }
2490
    }
2491
 
2492
  for (fld = 0; fld < opct->num_variable_fields; fld++)
2493
    {
2494
      const tic6x_insn_field *fldd;
2495
      unsigned int value;
2496
      unsigned int opno;
2497
      unsigned int ffld;
2498
      offsetT sign_value;
2499
      unsigned int bits;
2500
      unsigned int fcyc_bits;
2501
      expressionS *expp;
2502
      expressionS ucexp;
2503
      tic6x_mem_ref mem;
2504
 
2505
      fldd = tic6x_field_from_fmt (fmt, opct->variable_fields[fld].field_id);
2506
      if (fldd == NULL)
2507
        abort ();
2508
      opno = opct->variable_fields[fld].operand_num;
2509
      switch (opct->variable_fields[fld].coding_method)
2510
        {
2511
        case tic6x_coding_ucst:
2512
          if (operands[opno].form != TIC6X_OP_EXP)
2513
            abort ();
2514
          if (operands[opno].value.exp.X_op != O_constant)
2515
            abort ();
2516
          ucexp = operands[opno].value.exp;
2517
        unsigned_constant:
2518
          if (ucexp.X_add_number < 0
2519
              || ucexp.X_add_number >= (1 << fldd->width))
2520
            {
2521
              if (print_errors)
2522
                as_bad (_("operand %u of '%.*s' out of range"), opno + 1,
2523
                        opc_len, str);
2524
              *ok = FALSE;
2525
              return 0;
2526
            }
2527
          value = ucexp.X_add_number;
2528
          break;
2529
 
2530
        case tic6x_coding_scst:
2531
          if (operands[opno].form != TIC6X_OP_EXP)
2532
            abort ();
2533
          if (operands[opno].value.exp.X_op != O_constant)
2534
            {
2535
              value = 0;
2536
              /* Opcode table should not permit non-constants without
2537
                 a known relocation for them.  */
2538
              if (fldd->low_pos != 7 || fldd->width != 16)
2539
                abort ();
2540
              *fix_needed = TRUE;
2541
              *fix_exp = &operands[opno].value.exp;
2542
              *fix_pcrel = 0;
2543
              *fx_r_type = BFD_RELOC_C6000_ABS_S16;
2544
              *fix_adda = FALSE;
2545
              break;
2546
            }
2547
          sign_value = SEXT (operands[opno].value.exp.X_add_number);
2548
        signed_constant:
2549
          if (sign_value < -(1 << (fldd->width - 1))
2550
              || (sign_value >= (1 << (fldd->width - 1))))
2551
            {
2552
              if (print_errors)
2553
                as_bad (_("operand %u of '%.*s' out of range"), opno + 1,
2554
                        opc_len, str);
2555
              *ok = FALSE;
2556
              return 0;
2557
            }
2558
          value = sign_value + (1 << (fldd->width - 1));
2559
          value ^= (1 << (fldd->width - 1));
2560
          break;
2561
 
2562
        case tic6x_coding_ucst_minus_one:
2563
          if (operands[opno].form != TIC6X_OP_EXP)
2564
            abort ();
2565
          if (operands[opno].value.exp.X_op != O_constant)
2566
            abort ();
2567
          if (operands[opno].value.exp.X_add_number <= 0
2568
              || operands[opno].value.exp.X_add_number > (1 << fldd->width))
2569
            {
2570
              if (print_errors)
2571
                as_bad (_("operand %u of '%.*s' out of range"), opno + 1,
2572
                        opc_len, str);
2573
              *ok = FALSE;
2574
              return 0;
2575
            }
2576
          value = operands[opno].value.exp.X_add_number - 1;
2577
          break;
2578
 
2579
        case tic6x_coding_scst_negate:
2580
          if (operands[opno].form != TIC6X_OP_EXP)
2581
            abort ();
2582
          if (operands[opno].value.exp.X_op != O_constant)
2583
            abort ();
2584
          sign_value = SEXT (-operands[opno].value.exp.X_add_number);
2585
          goto signed_constant;
2586
 
2587
        case tic6x_coding_ulcst_dpr_byte:
2588
        case tic6x_coding_ulcst_dpr_half:
2589
        case tic6x_coding_ulcst_dpr_word:
2590
          bits = tic6x_dpr_shift (opct->variable_fields[fld].coding_method);
2591
          switch (operands[opno].form)
2592
            {
2593
            case TIC6X_OP_EXP:
2594
              if (operands[opno].value.exp.X_op == O_constant)
2595
                {
2596
                  ucexp = operands[opno].value.exp;
2597
                  goto unsigned_constant;
2598
                }
2599
              expp = &operands[opno].value.exp;
2600
              break;
2601
 
2602
            case TIC6X_OP_MEM_NOUNREG:
2603
              mem = operands[opno].value.mem;
2604
              tic6x_default_mem_ref (&mem);
2605
              if (mem.offset_is_reg)
2606
                abort ();
2607
              if (mem.offset.exp.X_op == O_constant)
2608
                {
2609
                  ucexp = mem.offset.exp;
2610
                  if (mem.scaled == tic6x_offset_unscaled)
2611
                    {
2612
                      if (ucexp.X_add_number & ((1 << bits) - 1))
2613
                        {
2614
                          if (print_errors)
2615
                            as_bad (_("offset in operand %u of '%.*s' not "
2616
                                      "divisible by %u"), opno + 1, opc_len,
2617
                                    str, 1u << bits);
2618
                          *ok = FALSE;
2619
                          return 0;
2620
                        }
2621
                      ucexp.X_add_number >>= bits;
2622
                    }
2623
                  goto unsigned_constant;
2624
                }
2625
              if (mem.scaled != tic6x_offset_unscaled)
2626
                abort ();
2627
              if (operands[opno].value.mem.mod == tic6x_mem_mod_none
2628
                  || operands[opno].value.mem.scaled != tic6x_offset_unscaled
2629
                  || operands[opno].value.mem.offset_is_reg)
2630
                abort ();
2631
              expp = &operands[opno].value.mem.offset.exp;
2632
              break;
2633
 
2634
            default:
2635
              abort ();
2636
            }
2637
          value = 0;
2638
          /* Opcode table should not use this encoding without a known
2639
             relocation.  */
2640
          if (fldd->low_pos != 8 || fldd->width != 15)
2641
            abort ();
2642
          /* We do not check for offset divisibility here; such a
2643
             check is not needed at this point to encode the value,
2644
             and if there is eventually a problem it will be detected
2645
             either in md_apply_fix or at link time.  */
2646
          *fix_needed = TRUE;
2647
          *fix_exp = expp;
2648
          *fix_pcrel = 0;
2649
          *fx_r_type
2650
            = tic6x_dpr_reloc (opct->variable_fields[fld].coding_method);
2651
          if (operands[opno].form == TIC6X_OP_EXP)
2652
            *fix_adda = TRUE;
2653
          else
2654
            *fix_adda = FALSE;
2655
          break;
2656
 
2657
        case tic6x_coding_lcst_low16:
2658
          if (operands[opno].form != TIC6X_OP_EXP)
2659
            abort ();
2660
          if (operands[opno].value.exp.X_op == O_constant)
2661
            value = operands[opno].value.exp.X_add_number & 0xffff;
2662
          else
2663
            {
2664
              value = 0;
2665
              /* Opcode table should not use this encoding without a
2666
                 known relocation.  */
2667
              if (fldd->low_pos != 7 || fldd->width != 16)
2668
                abort ();
2669
              *fix_needed = TRUE;
2670
              *fix_exp = &operands[opno].value.exp;
2671
              *fix_pcrel = 0;
2672
              *fx_r_type = BFD_RELOC_C6000_ABS_L16;
2673
              *fix_adda = FALSE;
2674
            }
2675
          break;
2676
 
2677
        case tic6x_coding_lcst_high16:
2678
          if (operands[opno].form != TIC6X_OP_EXP)
2679
            abort ();
2680
          if (operands[opno].value.exp.X_op == O_constant)
2681
            value = (operands[opno].value.exp.X_add_number >> 16) & 0xffff;
2682
          else
2683
            {
2684
              value = 0;
2685
              /* Opcode table should not use this encoding without a
2686
                 known relocation.  */
2687
              if (fldd->low_pos != 7 || fldd->width != 16)
2688
                abort ();
2689
              *fix_needed = TRUE;
2690
              *fix_exp = &operands[opno].value.exp;
2691
              *fix_pcrel = 0;
2692
              *fx_r_type = BFD_RELOC_C6000_ABS_H16;
2693
              *fix_adda = FALSE;
2694
            }
2695
          break;
2696
 
2697
        case tic6x_coding_pcrel:
2698
        case tic6x_coding_pcrel_half:
2699
          if (operands[opno].form != TIC6X_OP_EXP)
2700
            abort ();
2701
          value = 0;
2702
          *fix_needed = TRUE;
2703
          *fix_exp = &operands[opno].value.exp;
2704
          *fix_pcrel = 1;
2705
          if (fldd->low_pos == 7 && fldd->width == 21)
2706
            *fx_r_type = BFD_RELOC_C6000_PCR_S21;
2707
          else if (fldd->low_pos == 16 && fldd->width == 12)
2708
            *fx_r_type = BFD_RELOC_C6000_PCR_S12;
2709
          else if (fldd->low_pos == 13 && fldd->width == 10)
2710
            *fx_r_type = BFD_RELOC_C6000_PCR_S10;
2711
          else if (fldd->low_pos == 16 && fldd->width == 7)
2712
            *fx_r_type = BFD_RELOC_C6000_PCR_S7;
2713
          else
2714
            /* Opcode table should not use this encoding without a
2715
               known relocation.  */
2716
            abort ();
2717
          *fix_adda = FALSE;
2718
          break;
2719
 
2720
        case tic6x_coding_reg:
2721
          switch (operands[opno].form)
2722
            {
2723
            case TIC6X_OP_REG:
2724
            case TIC6X_OP_REGPAIR:
2725
              value = operands[opno].value.reg.num;
2726
              break;
2727
 
2728
            case TIC6X_OP_MEM_NOUNREG:
2729
            case TIC6X_OP_MEM_UNREG:
2730
              value = operands[opno].value.mem.base_reg.num;
2731
              break;
2732
 
2733
            default:
2734
              abort ();
2735
            }
2736
          break;
2737
 
2738
        case tic6x_coding_areg:
2739
          switch (operands[opno].form)
2740
            {
2741
            case TIC6X_OP_REG:
2742
              value = (operands[opno].value.reg.num == 15 ? 1 : 0);
2743
              break;
2744
 
2745
            case TIC6X_OP_MEM_NOUNREG:
2746
              value = (operands[opno].value.mem.base_reg.num == 15 ? 1 : 0);
2747
              break;
2748
 
2749
            default:
2750
              abort ();
2751
            }
2752
          break;
2753
 
2754
        case tic6x_coding_crlo:
2755
          if (operands[opno].form != TIC6X_OP_CTRL)
2756
            abort ();
2757
          value = tic6x_ctrl_table[operands[opno].value.ctrl].crlo;
2758
          break;
2759
 
2760
        case tic6x_coding_crhi:
2761
          if (operands[opno].form != TIC6X_OP_CTRL)
2762
            abort ();
2763
          value = 0;
2764
          break;
2765
 
2766
        case tic6x_coding_reg_shift:
2767
          if (operands[opno].form != TIC6X_OP_REGPAIR)
2768
            abort ();
2769
          value = operands[opno].value.reg.num >> 1;
2770
          break;
2771
 
2772
        case tic6x_coding_mem_offset:
2773
          if (operands[opno].form != TIC6X_OP_MEM_NOUNREG)
2774
            abort ();
2775
          mem = operands[opno].value.mem;
2776
          tic6x_default_mem_ref (&mem);
2777
          if (mem.offset_is_reg)
2778
            {
2779
              if (mem.scaled != tic6x_offset_scaled)
2780
                abort ();
2781
              value = mem.offset.reg.num;
2782
            }
2783
          else
2784
            {
2785
              int scale;
2786
 
2787
              if (mem.offset.exp.X_op != O_constant)
2788
                abort ();
2789
              switch (mem.scaled)
2790
                {
2791
                case tic6x_offset_scaled:
2792
                  scale = 1;
2793
                  break;
2794
 
2795
                case tic6x_offset_unscaled:
2796
                  scale = opct->operand_info[opno].size;
2797
                  if (scale != 1 && scale != 2 && scale != 4 && scale != 8)
2798
                    abort ();
2799
                  break;
2800
 
2801
                default:
2802
                  abort ();
2803
                }
2804
              if (mem.offset.exp.X_add_number < 0
2805
                  || mem.offset.exp.X_add_number >= (1 << fldd->width) * scale)
2806
                {
2807
                  if (print_errors)
2808
                    as_bad (_("offset in operand %u of '%.*s' out of range"),
2809
                            opno + 1, opc_len, str);
2810
                  *ok = FALSE;
2811
                  return 0;
2812
                }
2813
              if (mem.offset.exp.X_add_number % scale)
2814
                {
2815
                  if (print_errors)
2816
                    as_bad (_("offset in operand %u of '%.*s' not "
2817
                              "divisible by %u"),
2818
                            opno + 1, opc_len, str, scale);
2819
                  *ok = FALSE;
2820
                  return 0;
2821
                }
2822
              value = mem.offset.exp.X_add_number / scale;
2823
            }
2824
          break;
2825
 
2826
        case tic6x_coding_mem_offset_noscale:
2827
          if (operands[opno].form != TIC6X_OP_MEM_UNREG)
2828
            abort ();
2829
          mem = operands[opno].value.mem;
2830
          tic6x_default_mem_ref (&mem);
2831
          if (mem.offset_is_reg)
2832
            value = mem.offset.reg.num;
2833
          else
2834
            {
2835
              if (mem.offset.exp.X_op != O_constant)
2836
                abort ();
2837
              if (mem.offset.exp.X_add_number < 0
2838
                  || mem.offset.exp.X_add_number >= (1 << fldd->width))
2839
                {
2840
                  if (print_errors)
2841
                    as_bad (_("offset in operand %u of '%.*s' out of range"),
2842
                            opno + 1, opc_len, str);
2843
                  *ok = FALSE;
2844
                  return 0;
2845
                }
2846
              value = mem.offset.exp.X_add_number;
2847
            }
2848
          break;
2849
 
2850
        case tic6x_coding_mem_mode:
2851
          if (operands[opno].form != TIC6X_OP_MEM_NOUNREG
2852
              && operands[opno].form != TIC6X_OP_MEM_UNREG)
2853
            abort ();
2854
          mem = operands[opno].value.mem;
2855
          tic6x_default_mem_ref (&mem);
2856
          switch (mem.mod)
2857
            {
2858
            case tic6x_mem_mod_plus:
2859
              value = 1;
2860
              break;
2861
 
2862
            case tic6x_mem_mod_minus:
2863
              value = 0;
2864
              break;
2865
 
2866
            case tic6x_mem_mod_preinc:
2867
              value = 9;
2868
              break;
2869
 
2870
            case tic6x_mem_mod_predec:
2871
              value = 8;
2872
              break;
2873
 
2874
            case tic6x_mem_mod_postinc:
2875
              value = 11;
2876
              break;
2877
 
2878
            case tic6x_mem_mod_postdec:
2879
              value = 10;
2880
              break;
2881
 
2882
            default:
2883
              abort ();
2884
            }
2885
          value += (mem.offset_is_reg ? 4 : 0);
2886
          break;
2887
 
2888
        case tic6x_coding_scaled:
2889
          if (operands[opno].form != TIC6X_OP_MEM_UNREG)
2890
            abort ();
2891
          mem = operands[opno].value.mem;
2892
          tic6x_default_mem_ref (&mem);
2893
          switch (mem.scaled)
2894
            {
2895
            case tic6x_offset_unscaled:
2896
              value = 0;
2897
              break;
2898
 
2899
            case tic6x_offset_scaled:
2900
              value = 1;
2901
              break;
2902
 
2903
            default:
2904
              abort ();
2905
            }
2906
          break;
2907
 
2908
        case tic6x_coding_spmask:
2909
          /* The position of such a field is hardcoded in the handling
2910
             of "||^".  */
2911
          if (fldd->low_pos != 18)
2912
            abort ();
2913
          value = 0;
2914
          for (opno = 0; opno < num_operands; opno++)
2915
            {
2916
              unsigned int v;
2917
 
2918
              v = tic6x_encode_spmask (operands[opno].value.func_unit.base,
2919
                                       operands[opno].value.func_unit.side);
2920
              if (value & v)
2921
                {
2922
                  if (print_errors)
2923
                    as_bad (_("functional unit already masked for operand "
2924
                              "%u of '%.*s'"), opno + 1, opc_len, str);
2925
                  *ok = FALSE;
2926
                  return 0;
2927
                }
2928
              value |= v;
2929
            }
2930
          break;
2931
 
2932
        case tic6x_coding_reg_unused:
2933
          /* This is a placeholder; correct handling goes along with
2934
             resource constraint checks.  */
2935
          value = 0;
2936
          break;
2937
 
2938
        case tic6x_coding_fstg:
2939
        case tic6x_coding_fcyc:
2940
          if (operands[opno].form != TIC6X_OP_EXP)
2941
            abort ();
2942
          if (operands[opno].value.exp.X_op != O_constant)
2943
            abort ();
2944
          if (!sploop_ii)
2945
            {
2946
              if (print_errors)
2947
                as_bad (_("'%.*s' instruction not in a software "
2948
                          "pipelined loop"),
2949
                        opc_len, str);
2950
              *ok = FALSE;
2951
              return 0;
2952
            }
2953
 
2954
          if (sploop_ii <= 1)
2955
            fcyc_bits = 0;
2956
          else if (sploop_ii <= 2)
2957
            fcyc_bits = 1;
2958
          else if (sploop_ii <= 4)
2959
            fcyc_bits = 2;
2960
          else if (sploop_ii <= 8)
2961
            fcyc_bits = 3;
2962
          else if (sploop_ii <= 14)
2963
            fcyc_bits = 4;
2964
          else
2965
            abort ();
2966
          if (fcyc_bits > fldd->width)
2967
            abort ();
2968
 
2969
          if (opct->variable_fields[fld].coding_method == tic6x_coding_fstg)
2970
            {
2971
              int i, t;
2972
              if (operands[opno].value.exp.X_add_number < 0
2973
                  || (operands[opno].value.exp.X_add_number
2974
                      >= (1 << (fldd->width - fcyc_bits))))
2975
                {
2976
                  if (print_errors)
2977
                    as_bad (_("operand %u of '%.*s' out of range"), opno + 1,
2978
                            opc_len, str);
2979
                  *ok = FALSE;
2980
                  return 0;
2981
                }
2982
              value = operands[opno].value.exp.X_add_number;
2983
              for (t = 0, i = fcyc_bits; i < fldd->width; i++)
2984
                {
2985
                  t = (t << 1) | (value & 1);
2986
                  value >>= 1;
2987
                }
2988
              value = t << fcyc_bits;
2989
            }
2990
          else
2991
            {
2992
              if (operands[opno].value.exp.X_add_number < 0
2993
                  || (operands[opno].value.exp.X_add_number >= sploop_ii))
2994
                {
2995
                  if (print_errors)
2996
                    as_bad (_("operand %u of '%.*s' out of range"), opno + 1,
2997
                            opc_len, str);
2998
                  *ok = FALSE;
2999
                  return 0;
3000
                }
3001
              value = operands[opno].value.exp.X_add_number;
3002
            }
3003
          break;
3004
 
3005
        case tic6x_coding_fu:
3006
          value = func_unit_side == 2 ? 1 : 0;
3007
          break;
3008
 
3009
        case tic6x_coding_data_fu:
3010
          value = func_unit_data_side == 2 ? 1 : 0;
3011
          break;
3012
 
3013
        case tic6x_coding_xpath:
3014
          value = func_unit_cross;
3015
          break;
3016
 
3017
        default:
3018
          abort ();
3019
        }
3020
 
3021
      for (ffld = 0; ffld < opct->num_fixed_fields; ffld++)
3022
        if ((opct->fixed_fields[ffld].field_id
3023
             == opct->variable_fields[fld].field_id)
3024
            && (value < opct->fixed_fields[ffld].min_val
3025
                || value > opct->fixed_fields[ffld].max_val))
3026
          {
3027
            if (print_errors)
3028
              as_bad (_("operand %u of '%.*s' out of range"), opno + 1,
3029
                      opc_len, str);
3030
            *ok = FALSE;
3031
            return 0;
3032
          }
3033
 
3034
      opcode_value |= value << fldd->low_pos;
3035
    }
3036
 
3037
  if (this_line_creg)
3038
    {
3039
      const tic6x_insn_field *creg;
3040
      const tic6x_insn_field *z;
3041
 
3042
      creg = tic6x_field_from_fmt (fmt, tic6x_field_creg);
3043
      if (creg == NULL)
3044
        {
3045
          if (print_errors)
3046
            as_bad (_("instruction '%.*s' cannot be predicated"),
3047
                    opc_len, str);
3048
          *ok = FALSE;
3049
          return 0;
3050
        }
3051
      z = tic6x_field_from_fmt (fmt, tic6x_field_z);
3052
      /* If there is a creg field, there must be a z field; otherwise
3053
         there is an error in the format table.  */
3054
      if (z == NULL)
3055
        abort ();
3056
 
3057
      opcode_value |= this_line_creg << creg->low_pos;
3058
      opcode_value |= this_line_z << z->low_pos;
3059
    }
3060
 
3061
  *ok = TRUE;
3062
  return opcode_value;
3063
}
3064
 
3065
/* Convert the target integer stored in N bytes in BUF to a host
3066
   integer, returning that value.  */
3067
 
3068
static valueT
3069
md_chars_to_number (char *buf, int n)
3070
{
3071
  valueT result = 0;
3072
  unsigned char *p = (unsigned char *) buf;
3073
 
3074
  if (target_big_endian)
3075
    {
3076
      while (n--)
3077
        {
3078
          result <<= 8;
3079
          result |= (*p++ & 0xff);
3080
        }
3081
    }
3082
  else
3083
    {
3084
      while (n--)
3085
        {
3086
          result <<= 8;
3087
          result |= (p[n] & 0xff);
3088
        }
3089
    }
3090
 
3091
  return result;
3092
}
3093
 
3094
/* Assemble the instruction starting at STR (an opcode, with the
3095
   opcode name all-lowercase).  */
3096
 
3097
void
3098
md_assemble (char *str)
3099
{
3100
  char *p;
3101
  int opc_len;
3102
  bfd_boolean this_line_parallel;
3103
  bfd_boolean this_line_spmask;
3104
  unsigned int this_line_creg;
3105
  unsigned int this_line_z;
3106
  tic6x_label_list *this_insn_label_list;
3107
  segment_info_type *seginfo;
3108
  tic6x_opcode_list *opc_list, *opc;
3109
  tic6x_func_unit_base func_unit_base = tic6x_func_unit_nfu;
3110
  unsigned int func_unit_side = 0;
3111
  unsigned int func_unit_cross = 0;
3112
  unsigned int cross_side = 0;
3113
  unsigned int func_unit_data_side = 0;
3114
  unsigned int max_matching_opcodes, num_matching_opcodes;
3115
  tic6x_opcode_id *opcm = NULL;
3116
  unsigned int opc_rank[TIC6X_NUM_PREFER];
3117
  const tic6x_opcode *opct = NULL;
3118
  int min_rank, try_rank, max_rank;
3119
  bfd_boolean num_operands_permitted[TIC6X_MAX_SOURCE_OPERANDS + 1]
3120
    = { FALSE };
3121
  unsigned int operand_forms[TIC6X_MAX_SOURCE_OPERANDS] = { 0 };
3122
  tic6x_operand operands[TIC6X_MAX_SOURCE_OPERANDS];
3123
  unsigned int max_num_operands;
3124
  unsigned int num_operands_read;
3125
  bfd_boolean ok_this_arch, ok_this_fu, ok_this_arch_fu;
3126
  bfd_boolean bad_operands = FALSE;
3127
  unsigned int opcode_value;
3128
  bfd_boolean encoded_ok;
3129
  bfd_boolean fix_needed = FALSE;
3130
  expressionS *fix_exp = NULL;
3131
  int fix_pcrel = 0;
3132
  bfd_reloc_code_real_type fx_r_type = BFD_RELOC_UNUSED;
3133
  bfd_boolean fix_adda = FALSE;
3134
  fragS *insn_frag;
3135
  char *output;
3136
 
3137
  p = str;
3138
  while (*p && !is_end_of_line[(unsigned char) *p] && *p != ' ')
3139
    p++;
3140
 
3141
  /* This function should only have been called when there is actually
3142
     an instruction to assemble.  */
3143
  if (p == str)
3144
    abort ();
3145
 
3146
  /* Now an instruction has been seen, architecture attributes from
3147
     .arch directives merge with rather than overriding the previous
3148
     value.  */
3149
  tic6x_seen_insns = TRUE;
3150
  /* If no .arch directives or -march options have been seen, we are
3151
     assessing instruction validity based on the C674X default, so set
3152
     the attribute accordingly.  */
3153
  if (tic6x_arch_attribute == C6XABI_Tag_ISA_none)
3154
    tic6x_arch_attribute = C6XABI_Tag_ISA_C674X;
3155
 
3156
  /* Reset global settings for parallel bars and predicates now to
3157
     avoid extra errors if there are problems with this opcode.  */
3158
  this_line_parallel = tic6x_line_parallel;
3159
  this_line_spmask = tic6x_line_spmask;
3160
  this_line_creg = tic6x_line_creg;
3161
  this_line_z = tic6x_line_z;
3162
  tic6x_line_parallel = FALSE;
3163
  tic6x_line_spmask = FALSE;
3164
  tic6x_line_creg = 0;
3165
  tic6x_line_z = 0;
3166
  seginfo = seg_info (now_seg);
3167
  this_insn_label_list = seginfo->tc_segment_info_data.label_list;
3168
  seginfo->tc_segment_info_data.label_list = NULL;
3169
 
3170
  opc_list = hash_find_n (opcode_hash, str, p - str);
3171
  if (opc_list == NULL)
3172
    {
3173
      char c = *p;
3174
      *p = 0;
3175
      as_bad (_("unknown opcode '%s'"), str);
3176
      *p = c;
3177
      return;
3178
    }
3179
 
3180
  opc_len = p - str;
3181
  skip_whitespace (p);
3182
 
3183
  /* See if there is something that looks like a functional unit
3184
     specifier.  */
3185
  if (*p == '.')
3186
    {
3187
      bfd_boolean good_func_unit;
3188
      tic6x_func_unit_base maybe_base = tic6x_func_unit_nfu;
3189
      unsigned int maybe_side = 0;
3190
      unsigned int maybe_cross = 0;
3191
      unsigned int maybe_data_side = 0;
3192
 
3193
      good_func_unit = tic6x_parse_func_unit_base (p + 1, &maybe_base,
3194
                                                   &maybe_side);
3195
 
3196
      if (good_func_unit)
3197
        {
3198
          if (p[3] == ' ' || is_end_of_line[(unsigned char) p[3]])
3199
            p += 3;
3200
          else if ((p[3] == 'x' || p[3] == 'X')
3201
                   && (p[4] == ' ' || is_end_of_line[(unsigned char) p[4]]))
3202
            {
3203
              maybe_cross = 1;
3204
              p += 4;
3205
            }
3206
          else if (maybe_base == tic6x_func_unit_d
3207
                   && (p[3] == 't' || p[3] == 'T')
3208
                   && (p[4] == '1' || p[4] == '2')
3209
                   && (p[5] == ' ' || is_end_of_line[(unsigned char) p[5]]))
3210
            {
3211
              maybe_data_side = p[4] - '0';
3212
              p += 5;
3213
            }
3214
          else
3215
            good_func_unit = FALSE;
3216
        }
3217
 
3218
      if (good_func_unit)
3219
        {
3220
          func_unit_base = maybe_base;
3221
          func_unit_side = maybe_side;
3222
          func_unit_cross = maybe_cross;
3223
          cross_side = (func_unit_cross ? 3 - func_unit_side : func_unit_side);
3224
          func_unit_data_side = maybe_data_side;
3225
        }
3226
 
3227
      skip_whitespace (p);
3228
    }
3229
 
3230
  /* Determine which entries in the opcode table match, and the
3231
     associated permitted forms of operands.  */
3232
  max_matching_opcodes = 0;
3233
  for (opc = opc_list; opc; opc = opc->next)
3234
    max_matching_opcodes++;
3235
  num_matching_opcodes = 0;
3236
  opcm = xmalloc (max_matching_opcodes * sizeof (*opcm));
3237
  max_num_operands = 0;
3238
  ok_this_arch = FALSE;
3239
  ok_this_fu = FALSE;
3240
  ok_this_arch_fu = FALSE;
3241
  for (opc = opc_list; opc; opc = opc->next)
3242
    {
3243
      unsigned int num_operands;
3244
      unsigned int i;
3245
      bfd_boolean this_opc_arch_ok = TRUE;
3246
      bfd_boolean this_opc_fu_ok = TRUE;
3247
 
3248
      if (tic6x_insn_format_table[tic6x_opcode_table[opc->id].format].num_bits
3249
          != 32)
3250
        continue;
3251
      if (!(tic6x_opcode_table[opc->id].isa_variants & tic6x_features))
3252
        this_opc_arch_ok = FALSE;
3253
      if (tic6x_opcode_table[opc->id].func_unit != func_unit_base)
3254
        this_opc_fu_ok = FALSE;
3255
      if (func_unit_side == 1
3256
          && (tic6x_opcode_table[opc->id].flags & TIC6X_FLAG_SIDE_B_ONLY))
3257
        this_opc_fu_ok = FALSE;
3258
      if (func_unit_cross
3259
          && (tic6x_opcode_table[opc->id].flags & TIC6X_FLAG_NO_CROSS))
3260
        this_opc_fu_ok = FALSE;
3261
      if (!func_unit_data_side
3262
          && (tic6x_opcode_table[opc->id].flags
3263
              & (TIC6X_FLAG_LOAD | TIC6X_FLAG_STORE)))
3264
        this_opc_fu_ok = FALSE;
3265
      if (func_unit_data_side
3266
          && !(tic6x_opcode_table[opc->id].flags
3267
               & (TIC6X_FLAG_LOAD | TIC6X_FLAG_STORE)))
3268
        this_opc_fu_ok = FALSE;
3269
      if (func_unit_data_side == 1
3270
          && (tic6x_opcode_table[opc->id].flags & TIC6X_FLAG_SIDE_T2_ONLY))
3271
        this_opc_fu_ok = FALSE;
3272
      if (this_opc_arch_ok)
3273
        ok_this_arch = TRUE;
3274
      if (this_opc_fu_ok)
3275
        ok_this_fu = TRUE;
3276
      if (!this_opc_arch_ok || !this_opc_fu_ok)
3277
        continue;
3278
      ok_this_arch_fu = TRUE;
3279
      opcm[num_matching_opcodes] = opc->id;
3280
      num_matching_opcodes++;
3281
      num_operands = tic6x_opcode_table[opc->id].num_operands;
3282
 
3283
      if (tic6x_opcode_table[opc->id].flags & TIC6X_FLAG_SPMASK)
3284
        {
3285
          if (num_operands != 1
3286
              || (tic6x_opcode_table[opc->id].operand_info[0].form
3287
                  != tic6x_operand_func_unit))
3288
            abort ();
3289
          num_operands = 8;
3290
          for (i = 0; i < num_operands; i++)
3291
            {
3292
              operand_forms[i]
3293
                |= tic6x_coarse_operand_form (tic6x_operand_func_unit);
3294
              num_operands_permitted[i] = TRUE;
3295
            }
3296
        }
3297
      else
3298
        {
3299
          for (i = 0; i < num_operands; i++)
3300
            {
3301
              tic6x_operand_form f
3302
                = tic6x_opcode_table[opc->id].operand_info[i].form;
3303
 
3304
              operand_forms[i] |= tic6x_coarse_operand_form (f);
3305
            }
3306
        }
3307
      num_operands_permitted[num_operands] = TRUE;
3308
      if (num_operands > max_num_operands)
3309
        max_num_operands = num_operands;
3310
    }
3311
 
3312
  if (!ok_this_arch)
3313
    {
3314
      as_bad (_("'%.*s' instruction not supported on this architecture"),
3315
              opc_len, str);
3316
      free (opcm);
3317
      return;
3318
    }
3319
 
3320
  if (!ok_this_fu)
3321
    {
3322
      as_bad (_("'%.*s' instruction not supported on this functional unit"),
3323
              opc_len, str);
3324
      free (opcm);
3325
      return;
3326
    }
3327
 
3328
  if (!ok_this_arch_fu)
3329
    {
3330
      as_bad (_("'%.*s' instruction not supported on this functional unit"
3331
                " for this architecture"),
3332
              opc_len, str);
3333
      free (opcm);
3334
      return;
3335
    }
3336
 
3337
  /* If there were no instructions matching the above availability
3338
     checks, we should now have given an error and returned.  */
3339
  if (num_matching_opcodes == 0)
3340
    abort ();
3341
 
3342
  num_operands_read = 0;
3343
  while (TRUE)
3344
    {
3345
      skip_whitespace (p);
3346
      if (is_end_of_line[(unsigned char) *p])
3347
        {
3348
          if (num_operands_read > 0)
3349
            {
3350
              as_bad (_("missing operand after comma"));
3351
              bad_operands = TRUE;
3352
            }
3353
          break;
3354
        }
3355
 
3356
      if (max_num_operands == 0)
3357
        {
3358
          as_bad (_("too many operands to '%.*s'"), opc_len, str);
3359
          bad_operands = TRUE;
3360
          break;
3361
        }
3362
 
3363
      if (!tic6x_parse_operand (&p, &operands[num_operands_read],
3364
                                operand_forms[num_operands_read], str, opc_len,
3365
                                num_operands_read + 1))
3366
        bad_operands = TRUE;
3367
      num_operands_read++;
3368
 
3369
      if (is_end_of_line[(unsigned char) *p])
3370
        break;
3371
      else if (*p == ',')
3372
        {
3373
          p++;
3374
          if (num_operands_read == max_num_operands)
3375
            {
3376
              as_bad (_("too many operands to '%.*s'"), opc_len, str);
3377
              bad_operands = TRUE;
3378
              break;
3379
            }
3380
          continue;
3381
        }
3382
      else
3383
        /* Operand parsing should consume whole operands.  */
3384
        abort ();
3385
    }
3386
 
3387
  if (!bad_operands && !num_operands_permitted[num_operands_read])
3388
    {
3389
      as_bad (_("bad number of operands to '%.*s'"), opc_len, str);
3390
      bad_operands = TRUE;
3391
    }
3392
 
3393
  if (!bad_operands)
3394
    {
3395
      /* Each operand is of the right syntactic form for some opcode
3396
         choice, and the number of operands is valid.  Check that each
3397
         operand is OK in detail for some opcode choice with the right
3398
         number of operands.  */
3399
      unsigned int i;
3400
 
3401
      for (i = 0; i < num_operands_read; i++)
3402
        {
3403
          bfd_boolean coarse_ok = FALSE;
3404
          bfd_boolean fine_ok = FALSE;
3405
          tic6x_operand_match fine_failure = tic6x_match_matches;
3406
          unsigned int j;
3407
 
3408
          for (j = 0; j < num_matching_opcodes; j++)
3409
            {
3410
              tic6x_operand_form f;
3411
              tic6x_rw rw;
3412
              unsigned int cf;
3413
              tic6x_operand_match this_fine_failure;
3414
 
3415
              if (tic6x_opcode_table[opcm[j]].flags & TIC6X_FLAG_SPMASK)
3416
                {
3417
                  f = tic6x_operand_func_unit;
3418
                  rw = tic6x_rw_none;
3419
                }
3420
              else
3421
                {
3422
                  if (tic6x_opcode_table[opcm[j]].num_operands
3423
                      != num_operands_read)
3424
                    continue;
3425
 
3426
                  f = tic6x_opcode_table[opcm[j]].operand_info[i].form;
3427
                  rw = tic6x_opcode_table[opcm[j]].operand_info[i].rw;
3428
                }
3429
              cf = tic6x_coarse_operand_form (f);
3430
 
3431
              if (operands[i].form != cf)
3432
                continue;
3433
 
3434
              coarse_ok = TRUE;
3435
              this_fine_failure
3436
                = tic6x_operand_matches_form (&operands[i], f, rw,
3437
                                              func_unit_side,
3438
                                              cross_side,
3439
                                              func_unit_data_side);
3440
              if (this_fine_failure == tic6x_match_matches)
3441
                {
3442
                  fine_ok = TRUE;
3443
                  break;
3444
                }
3445
              if (fine_failure == tic6x_match_matches
3446
                  || fine_failure > this_fine_failure)
3447
                fine_failure = this_fine_failure;
3448
            }
3449
 
3450
          /* No instructions should have operand syntactic forms only
3451
             acceptable with certain numbers of operands, so no
3452
             diagnostic for this case.  */
3453
          if (!coarse_ok)
3454
            abort ();
3455
 
3456
          if (!fine_ok)
3457
            {
3458
              switch (fine_failure)
3459
                {
3460
                case tic6x_match_non_const:
3461
                  as_bad (_("operand %u of '%.*s' not constant"),
3462
                          i + 1, opc_len, str);
3463
                  break;
3464
 
3465
                case tic6x_match_wrong_side:
3466
                  as_bad (_("operand %u of '%.*s' on wrong side"),
3467
                          i + 1, opc_len, str);
3468
                  break;
3469
 
3470
                case tic6x_match_bad_return:
3471
                  as_bad (_("operand %u of '%.*s' not a valid return "
3472
                            "address register"),
3473
                          i + 1, opc_len, str);
3474
                  break;
3475
 
3476
                case tic6x_match_ctrl_write_only:
3477
                  as_bad (_("operand %u of '%.*s' is write-only"),
3478
                          i + 1, opc_len, str);
3479
                  break;
3480
 
3481
                case tic6x_match_ctrl_read_only:
3482
                  as_bad (_("operand %u of '%.*s' is read-only"),
3483
                          i + 1, opc_len, str);
3484
                  break;
3485
 
3486
                case tic6x_match_bad_mem:
3487
                  as_bad (_("operand %u of '%.*s' not a valid memory "
3488
                            "reference"),
3489
                          i + 1, opc_len, str);
3490
                  break;
3491
 
3492
                case tic6x_match_bad_address:
3493
                  as_bad (_("operand %u of '%.*s' not a valid base "
3494
                            "address register"),
3495
                          i + 1, opc_len, str);
3496
                  break;
3497
 
3498
                default:
3499
                  abort ();
3500
                }
3501
              bad_operands = TRUE;
3502
              break;
3503
            }
3504
        }
3505
    }
3506
 
3507
  if (!bad_operands)
3508
    {
3509
      /* Each operand is OK for some opcode choice, and the number of
3510
         operands is valid.  Check whether there is an opcode choice
3511
         for which all operands are simultaneously valid.  */
3512
      unsigned int i;
3513
      bfd_boolean found_match = FALSE;
3514
 
3515
      for (i = 0; i < TIC6X_NUM_PREFER; i++)
3516
        opc_rank[i] = (unsigned int) -1;
3517
 
3518
      min_rank = TIC6X_NUM_PREFER - 1;
3519
      max_rank = 0;
3520
 
3521
      for (i = 0; i < num_matching_opcodes; i++)
3522
        {
3523
          unsigned int j;
3524
          bfd_boolean this_matches = TRUE;
3525
 
3526
          if (!(tic6x_opcode_table[opcm[i]].flags & TIC6X_FLAG_SPMASK)
3527
              && tic6x_opcode_table[opcm[i]].num_operands != num_operands_read)
3528
            continue;
3529
 
3530
          for (j = 0; j < num_operands_read; j++)
3531
            {
3532
              tic6x_operand_form f;
3533
              tic6x_rw rw;
3534
 
3535
              if (tic6x_opcode_table[opcm[i]].flags & TIC6X_FLAG_SPMASK)
3536
                {
3537
                  f = tic6x_operand_func_unit;
3538
                  rw = tic6x_rw_none;
3539
                }
3540
              else
3541
                {
3542
                  f = tic6x_opcode_table[opcm[i]].operand_info[j].form;
3543
                  rw = tic6x_opcode_table[opcm[i]].operand_info[j].rw;
3544
                }
3545
              if (tic6x_operand_matches_form (&operands[j], f, rw,
3546
                                              func_unit_side,
3547
                                              cross_side,
3548
                                              func_unit_data_side)
3549
                  != tic6x_match_matches)
3550
                {
3551
                  this_matches = FALSE;
3552
                  break;
3553
                }
3554
            }
3555
 
3556
          if (this_matches)
3557
            {
3558
              int rank = TIC6X_PREFER_VAL (tic6x_opcode_table[opcm[i]].flags);
3559
 
3560
              if (rank < min_rank)
3561
                min_rank = rank;
3562
              if (rank > max_rank)
3563
                max_rank = rank;
3564
 
3565
              if (opc_rank[rank] == (unsigned int) -1)
3566
                opc_rank[rank] = i;
3567
              else
3568
                /* The opcode table should provide a total ordering
3569
                   for all cases where multiple matches may get
3570
                   here.  */
3571
                abort ();
3572
 
3573
              found_match = TRUE;
3574
            }
3575
        }
3576
 
3577
      if (!found_match)
3578
        {
3579
          as_bad (_("bad operand combination for '%.*s'"), opc_len, str);
3580
          bad_operands = TRUE;
3581
        }
3582
    }
3583
 
3584
  if (bad_operands)
3585
    {
3586
      free (opcm);
3587
      return;
3588
    }
3589
 
3590
  opcode_value = 0;
3591
  encoded_ok = FALSE;
3592
  for (try_rank = max_rank; try_rank >= min_rank; try_rank--)
3593
    {
3594
      fix_needed = FALSE;
3595
 
3596
      if (opc_rank[try_rank] == (unsigned int) -1)
3597
        continue;
3598
 
3599
      opcode_value = tic6x_try_encode (opcm[opc_rank[try_rank]], operands,
3600
                                       num_operands_read, this_line_creg,
3601
                                       this_line_z, func_unit_side,
3602
                                       func_unit_cross, func_unit_data_side,
3603
                                       seginfo->tc_segment_info_data.sploop_ii,
3604
                                       &fix_exp, &fix_pcrel, &fx_r_type,
3605
                                       &fix_adda, &fix_needed, &encoded_ok,
3606
                                       (try_rank == min_rank ? TRUE : FALSE),
3607
                                       str, opc_len);
3608
      if (encoded_ok)
3609
        {
3610
          opct = &tic6x_opcode_table[opcm[opc_rank[try_rank]]];
3611
          break;
3612
        }
3613
    }
3614
 
3615
  free (opcm);
3616
 
3617
  if (!encoded_ok)
3618
    return;
3619
 
3620
  if (this_line_parallel)
3621
    {
3622
      insn_frag = seginfo->tc_segment_info_data.execute_packet_frag;
3623
      if (insn_frag == NULL)
3624
        {
3625
          as_bad (_("parallel instruction not following another instruction"));
3626
          return;
3627
        }
3628
 
3629
      if (insn_frag->fr_fix >= 32)
3630
        {
3631
          as_bad (_("too many instructions in execute packet"));
3632
          return;
3633
        }
3634
 
3635
      if (this_insn_label_list != NULL)
3636
        as_bad (_("label not at start of execute packet"));
3637
 
3638
      if (opct->flags & TIC6X_FLAG_FIRST)
3639
        as_bad (_("'%.*s' instruction not at start of execute packet"),
3640
                opc_len, str);
3641
 
3642
      *seginfo->tc_segment_info_data.last_insn_lsb |= 0x1;
3643
      output = insn_frag->fr_literal + insn_frag->fr_fix;
3644
    }
3645
  else
3646
    {
3647
      tic6x_label_list *l;
3648
 
3649
      seginfo->tc_segment_info_data.spmask_addr = NULL;
3650
      seginfo->tc_segment_info_data.func_units_used = 0;
3651
 
3652
      /* Start a new frag for this execute packet.  */
3653
      if (frag_now_fix () != 0)
3654
        {
3655
          if (frag_now->fr_type != rs_machine_dependent)
3656
            frag_wane (frag_now);
3657
 
3658
          frag_new (0);
3659
        }
3660
      frag_grow (32);
3661
      insn_frag = seginfo->tc_segment_info_data.execute_packet_frag = frag_now;
3662
      for (l = this_insn_label_list; l; l = l->next)
3663
        {
3664
          symbol_set_frag (l->label, frag_now);
3665
          S_SET_VALUE (l->label, 0);
3666
          S_SET_SEGMENT (l->label, now_seg);
3667
        }
3668
      tic6x_free_label_list (this_insn_label_list);
3669
      dwarf2_emit_insn (0);
3670
      output = frag_var (rs_machine_dependent, 32, 32, 0, NULL, 0, NULL);
3671
      /* This must be the same as the frag to which a pointer was just
3672
         saved.  */
3673
      if (output != insn_frag->fr_literal)
3674
        abort ();
3675
      insn_frag->tc_frag_data.is_insns = TRUE;
3676
      insn_frag->tc_frag_data.can_cross_fp_boundary
3677
        = tic6x_can_cross_fp_boundary;
3678
    }
3679
 
3680
  if (func_unit_base != tic6x_func_unit_nfu)
3681
    {
3682
      unsigned int func_unit_enc;
3683
 
3684
      func_unit_enc = tic6x_encode_spmask (func_unit_base, func_unit_side);
3685
 
3686
      if (seginfo->tc_segment_info_data.func_units_used & func_unit_enc)
3687
        as_bad (_("functional unit already used in this execute packet"));
3688
 
3689
      seginfo->tc_segment_info_data.func_units_used |= func_unit_enc;
3690
    }
3691
 
3692
  if (opct->flags & TIC6X_FLAG_SPLOOP)
3693
    {
3694
      if (seginfo->tc_segment_info_data.sploop_ii)
3695
        as_bad (_("nested software pipelined loop"));
3696
      if (num_operands_read != 1
3697
          || operands[0].form != TIC6X_OP_EXP
3698
          || operands[0].value.exp.X_op != O_constant)
3699
        abort ();
3700
      seginfo->tc_segment_info_data.sploop_ii
3701
        = operands[0].value.exp.X_add_number;
3702
    }
3703
  else if (opct->flags & TIC6X_FLAG_SPKERNEL)
3704
    {
3705
      if (!seginfo->tc_segment_info_data.sploop_ii)
3706
        as_bad (_("'%.*s' instruction not in a software pipelined loop"),
3707
                opc_len, str);
3708
      seginfo->tc_segment_info_data.sploop_ii = 0;
3709
    }
3710
 
3711
  if (this_line_spmask)
3712
    {
3713
      if (seginfo->tc_segment_info_data.spmask_addr == NULL)
3714
        as_bad (_("'||^' without previous SPMASK"));
3715
      else if (func_unit_base == tic6x_func_unit_nfu)
3716
        as_bad (_("cannot mask instruction using no functional unit"));
3717
      else
3718
        {
3719
          unsigned int spmask_opcode;
3720
          unsigned int mask_bit;
3721
 
3722
          spmask_opcode
3723
            = md_chars_to_number (seginfo->tc_segment_info_data.spmask_addr,
3724
                                  4);
3725
          mask_bit = tic6x_encode_spmask (func_unit_base, func_unit_side);
3726
          mask_bit <<= 18;
3727
          if (spmask_opcode & mask_bit)
3728
            as_bad (_("functional unit already masked"));
3729
          spmask_opcode |= mask_bit;
3730
          md_number_to_chars (seginfo->tc_segment_info_data.spmask_addr,
3731
                              spmask_opcode, 4);
3732
        }
3733
    }
3734
 
3735
  record_alignment (now_seg, 5);
3736
  md_number_to_chars (output, opcode_value, 4);
3737
  if (fix_needed)
3738
    tic6x_fix_new_exp (insn_frag, output - insn_frag->fr_literal, 4, fix_exp,
3739
                       fix_pcrel, fx_r_type, fix_adda);
3740
  insn_frag->fr_fix += 4;
3741
  insn_frag->fr_var -= 4;
3742
  seginfo->tc_segment_info_data.last_insn_lsb
3743
    = (target_big_endian ? output + 3 : output);
3744
  if (opct->flags & TIC6X_FLAG_SPMASK)
3745
    seginfo->tc_segment_info_data.spmask_addr = output;
3746
}
3747
 
3748
/* Modify NEWVAL (32-bit) by inserting VALUE, shifted right by SHIFT
3749
   and the least significant BITS bits taken, at position POS.  */
3750
#define MODIFY_VALUE(NEWVAL, VALUE, SHIFT, POS, BITS)                   \
3751
  do {                                                                  \
3752
    (NEWVAL) &= 0xffffffffU & ~(((1U << (BITS)) - 1) << (POS));         \
3753
    (NEWVAL) |= (((VALUE) >> (SHIFT)) & ((1U << (BITS)) - 1)) << (POS); \
3754
  } while (0)
3755
 
3756
/* Apply a fixup to the object file.  */
3757
 
3758
void
3759
md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
3760
{
3761
  offsetT value = *valP;
3762
  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
3763
 
3764
  value = SEXT (value);
3765
  *valP = value;
3766
 
3767
  fixP->fx_offset = SEXT (fixP->fx_offset);
3768
 
3769
  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
3770
    fixP->fx_done = 1;
3771
 
3772
  /* We do our own overflow checks.  */
3773
  fixP->fx_no_overflow = 1;
3774
 
3775
  switch (fixP->fx_r_type)
3776
    {
3777
    case BFD_RELOC_NONE:
3778
    case BFD_RELOC_C6000_EHTYPE:
3779
      /* Force output to the object file.  */
3780
      fixP->fx_done = 0;
3781
      break;
3782
 
3783
    case BFD_RELOC_32:
3784
      if (fixP->fx_done || !seg->use_rela_p)
3785
        md_number_to_chars (buf, value, 4);
3786
      break;
3787
 
3788
    case BFD_RELOC_16:
3789
      if (fixP->fx_done || !seg->use_rela_p)
3790
        {
3791
          if (value < -0x8000 || value > 0xffff)
3792
            as_bad_where (fixP->fx_file, fixP->fx_line,
3793
                          _("value too large for 2-byte field"));
3794
          md_number_to_chars (buf, value, 2);
3795
        }
3796
      break;
3797
 
3798
    case BFD_RELOC_8:
3799
      if (fixP->fx_done || !seg->use_rela_p)
3800
        {
3801
          if (value < -0x80 || value > 0xff)
3802
            as_bad_where (fixP->fx_file, fixP->fx_line,
3803
                          _("value too large for 1-byte field"));
3804
          md_number_to_chars (buf, value, 1);
3805
        }
3806
      break;
3807
 
3808
    case BFD_RELOC_C6000_ABS_S16:
3809
    case BFD_RELOC_C6000_ABS_L16:
3810
    case BFD_RELOC_C6000_SBR_S16:
3811
    case BFD_RELOC_C6000_SBR_L16_B:
3812
    case BFD_RELOC_C6000_SBR_L16_H:
3813
    case BFD_RELOC_C6000_SBR_L16_W:
3814
    case BFD_RELOC_C6000_SBR_GOT_L16_W:
3815
      if (fixP->fx_done || !seg->use_rela_p)
3816
        {
3817
          offsetT newval = md_chars_to_number (buf, 4);
3818
          int shift;
3819
 
3820
          switch (fixP->fx_r_type)
3821
            {
3822
            case BFD_RELOC_C6000_SBR_L16_H:
3823
              shift = 1;
3824
              break;
3825
 
3826
            case BFD_RELOC_C6000_SBR_L16_W:
3827
            case BFD_RELOC_C6000_SBR_GOT_L16_W:
3828
              shift = 2;
3829
              break;
3830
 
3831
            default:
3832
              shift = 0;
3833
              break;
3834
            }
3835
 
3836
          MODIFY_VALUE (newval, value, shift, 7, 16);
3837
          if ((value < -0x8000 || value > 0x7fff)
3838
              && (fixP->fx_r_type == BFD_RELOC_C6000_ABS_S16
3839
                  || fixP->fx_r_type == BFD_RELOC_C6000_SBR_S16))
3840
            as_bad_where (fixP->fx_file, fixP->fx_line,
3841
                          _("immediate offset out of range"));
3842
 
3843
          md_number_to_chars (buf, newval, 4);
3844
        }
3845
      if (fixP->fx_done
3846
          && fixP->fx_r_type != BFD_RELOC_C6000_ABS_S16
3847
          && fixP->fx_r_type != BFD_RELOC_C6000_ABS_L16)
3848
        abort ();
3849
      break;
3850
 
3851
    case BFD_RELOC_C6000_ABS_H16:
3852
    case BFD_RELOC_C6000_SBR_H16_B:
3853
    case BFD_RELOC_C6000_SBR_H16_H:
3854
    case BFD_RELOC_C6000_SBR_H16_W:
3855
    case BFD_RELOC_C6000_SBR_GOT_H16_W:
3856
      if (fixP->fx_done || !seg->use_rela_p)
3857
        {
3858
          offsetT newval = md_chars_to_number (buf, 4);
3859
          int shift;
3860
 
3861
          switch (fixP->fx_r_type)
3862
            {
3863
            case BFD_RELOC_C6000_SBR_H16_H:
3864
              shift = 17;
3865
              break;
3866
 
3867
            case BFD_RELOC_C6000_SBR_H16_W:
3868
            case BFD_RELOC_C6000_SBR_GOT_H16_W:
3869
              shift = 18;
3870
              break;
3871
 
3872
            default:
3873
              shift = 16;
3874
              break;
3875
            }
3876
 
3877
          MODIFY_VALUE (newval, value, shift, 7, 16);
3878
 
3879
          md_number_to_chars (buf, newval, 4);
3880
        }
3881
      if (fixP->fx_done && fixP->fx_r_type != BFD_RELOC_C6000_ABS_H16)
3882
        abort ();
3883
      break;
3884
 
3885
    case BFD_RELOC_C6000_PCR_H16:
3886
    case BFD_RELOC_C6000_PCR_L16:
3887
      if (fixP->fx_done || !seg->use_rela_p)
3888
        {
3889
          offsetT newval = md_chars_to_number (buf, 4);
3890
          int shift = fixP->fx_r_type == BFD_RELOC_C6000_PCR_H16 ? 16 : 0;
3891
 
3892
          MODIFY_VALUE (newval, value, shift, 7, 16);
3893
 
3894
          md_number_to_chars (buf, newval, 4);
3895
        }
3896
      break;
3897
 
3898
    case BFD_RELOC_C6000_SBR_U15_B:
3899
      if (fixP->fx_done || !seg->use_rela_p)
3900
        {
3901
          offsetT newval = md_chars_to_number (buf, 4);
3902
 
3903
          MODIFY_VALUE (newval, value, 0, 8, 15);
3904
          if (value < 0 || value > 0x7fff)
3905
            as_bad_where (fixP->fx_file, fixP->fx_line,
3906
                          _("immediate offset out of range"));
3907
 
3908
          md_number_to_chars (buf, newval, 4);
3909
        }
3910
      break;
3911
 
3912
    case BFD_RELOC_C6000_SBR_U15_H:
3913
      if (fixP->fx_done || !seg->use_rela_p)
3914
        {
3915
          offsetT newval = md_chars_to_number (buf, 4);
3916
 
3917
          /* Constant ADDA operands, processed as constant when the
3918
             instruction is parsed, are encoded as-is rather than
3919
             shifted.  If the operand of an ADDA instruction is now
3920
             constant (for example, the difference between two labels
3921
             found after the instruction), ensure it is encoded the
3922
             same way it would have been if the constant value had
3923
             been known when the instruction was parsed.  */
3924
          if (fixP->tc_fix_data.fix_adda && fixP->fx_done)
3925
            value <<= 1;
3926
 
3927
          MODIFY_VALUE (newval, value, 1, 8, 15);
3928
          if (value & 1)
3929
            as_bad_where (fixP->fx_file, fixP->fx_line,
3930
                          _("immediate offset not 2-byte-aligned"));
3931
          if (value < 0 || value > 0xfffe)
3932
            as_bad_where (fixP->fx_file, fixP->fx_line,
3933
                          _("immediate offset out of range"));
3934
 
3935
          md_number_to_chars (buf, newval, 4);
3936
        }
3937
      break;
3938
 
3939
    case BFD_RELOC_C6000_SBR_U15_W:
3940
    case BFD_RELOC_C6000_SBR_GOT_U15_W:
3941
      if (fixP->fx_done || !seg->use_rela_p)
3942
        {
3943
          offsetT newval = md_chars_to_number (buf, 4);
3944
 
3945
          /* Constant ADDA operands, processed as constant when the
3946
             instruction is parsed, are encoded as-is rather than
3947
             shifted.  If the operand of an ADDA instruction is now
3948
             constant (for example, the difference between two labels
3949
             found after the instruction), ensure it is encoded the
3950
             same way it would have been if the constant value had
3951
             been known when the instruction was parsed.  */
3952
          if (fixP->tc_fix_data.fix_adda && fixP->fx_done)
3953
            value <<= 2;
3954
 
3955
          MODIFY_VALUE (newval, value, 2, 8, 15);
3956
          if (value & 3)
3957
            as_bad_where (fixP->fx_file, fixP->fx_line,
3958
                          _("immediate offset not 4-byte-aligned"));
3959
          if (value < 0 || value > 0x1fffc)
3960
            as_bad_where (fixP->fx_file, fixP->fx_line,
3961
                          _("immediate offset out of range"));
3962
 
3963
          md_number_to_chars (buf, newval, 4);
3964
        }
3965
      if (fixP->fx_done && fixP->fx_r_type != BFD_RELOC_C6000_SBR_U15_W)
3966
        abort ();
3967
      break;
3968
 
3969
    case BFD_RELOC_C6000_DSBT_INDEX:
3970
      if (value != 0)
3971
        as_bad_where (fixP->fx_file, fixP->fx_line,
3972
                      _("addend used with $DSBT_INDEX"));
3973
      if (fixP->fx_done)
3974
        abort ();
3975
      break;
3976
 
3977
    case BFD_RELOC_C6000_PCR_S21:
3978
      if (fixP->fx_done || !seg->use_rela_p)
3979
        {
3980
          offsetT newval = md_chars_to_number (buf, 4);
3981
 
3982
          MODIFY_VALUE (newval, value, 2, 7, 21);
3983
 
3984
          if (value & 3)
3985
            as_bad_where (fixP->fx_file, fixP->fx_line,
3986
                          _("PC-relative offset not 4-byte-aligned"));
3987
          if (value < -0x400000 || value > 0x3ffffc)
3988
            as_bad_where (fixP->fx_file, fixP->fx_line,
3989
                          _("PC-relative offset out of range"));
3990
 
3991
          md_number_to_chars (buf, newval, 4);
3992
        }
3993
      break;
3994
 
3995
    case BFD_RELOC_C6000_PCR_S12:
3996
      if (fixP->fx_done || !seg->use_rela_p)
3997
        {
3998
          offsetT newval = md_chars_to_number (buf, 4);
3999
 
4000
          MODIFY_VALUE (newval, value, 2, 16, 12);
4001
 
4002
          if (value & 3)
4003
            as_bad_where (fixP->fx_file, fixP->fx_line,
4004
                          _("PC-relative offset not 4-byte-aligned"));
4005
          if (value < -0x2000 || value > 0x1ffc)
4006
            as_bad_where (fixP->fx_file, fixP->fx_line,
4007
                          _("PC-relative offset out of range"));
4008
 
4009
          md_number_to_chars (buf, newval, 4);
4010
        }
4011
      break;
4012
 
4013
    case BFD_RELOC_C6000_PCR_S10:
4014
      if (fixP->fx_done || !seg->use_rela_p)
4015
        {
4016
          offsetT newval = md_chars_to_number (buf, 4);
4017
 
4018
          MODIFY_VALUE (newval, value, 2, 13, 10);
4019
 
4020
          if (value & 3)
4021
            as_bad_where (fixP->fx_file, fixP->fx_line,
4022
                          _("PC-relative offset not 4-byte-aligned"));
4023
          if (value < -0x800 || value > 0x7fc)
4024
            as_bad_where (fixP->fx_file, fixP->fx_line,
4025
                          _("PC-relative offset out of range"));
4026
 
4027
          md_number_to_chars (buf, newval, 4);
4028
        }
4029
      break;
4030
 
4031
    case BFD_RELOC_C6000_PCR_S7:
4032
      if (fixP->fx_done || !seg->use_rela_p)
4033
        {
4034
          offsetT newval = md_chars_to_number (buf, 4);
4035
 
4036
          MODIFY_VALUE (newval, value, 2, 16, 7);
4037
 
4038
          if (value & 3)
4039
            as_bad_where (fixP->fx_file, fixP->fx_line,
4040
                          _("PC-relative offset not 4-byte-aligned"));
4041
          if (value < -0x100 || value > 0xfc)
4042
            as_bad_where (fixP->fx_file, fixP->fx_line,
4043
                          _("PC-relative offset out of range"));
4044
 
4045
          md_number_to_chars (buf, newval, 4);
4046
        }
4047
      break;
4048
 
4049
    case BFD_RELOC_C6000_PREL31:
4050
      /* Force output to the object file.  */
4051
      fixP->fx_done = 0;
4052
      break;
4053
 
4054
    default:
4055
      abort ();
4056
    }
4057
}
4058
 
4059
/* Convert a floating-point number to target (IEEE) format.  */
4060
 
4061
char *
4062
md_atof (int type, char *litP, int *sizeP)
4063
{
4064
  return ieee_md_atof (type, litP, sizeP, target_big_endian);
4065
}
4066
 
4067
/* Adjust the frags in SECTION (see tic6x_end).  */
4068
 
4069
static void
4070
tic6x_adjust_section (bfd *abfd ATTRIBUTE_UNUSED, segT section,
4071
                      void *dummy ATTRIBUTE_UNUSED)
4072
{
4073
  segment_info_type *info;
4074
  frchainS *frchp;
4075
  fragS *fragp;
4076
  bfd_boolean have_code = FALSE;
4077
  bfd_boolean have_non_code = FALSE;
4078
 
4079
  info = seg_info (section);
4080
  if (info == NULL)
4081
    return;
4082
 
4083
  for (frchp = info->frchainP; frchp; frchp = frchp->frch_next)
4084
    for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
4085
      switch (fragp->fr_type)
4086
        {
4087
        case rs_machine_dependent:
4088
          if (fragp->tc_frag_data.is_insns)
4089
            have_code = TRUE;
4090
          break;
4091
 
4092
        case rs_dummy:
4093
        case rs_fill:
4094
          if (fragp->fr_fix > 0)
4095
            have_non_code = TRUE;
4096
          break;
4097
 
4098
        default:
4099
          have_non_code = TRUE;
4100
          break;
4101
        }
4102
 
4103
  /* Process alignment requirements in a code-only section.  */
4104
  if (have_code && !have_non_code)
4105
    {
4106
      /* If we need to insert an odd number of instructions to meet an
4107
         alignment requirement, there must have been an odd number of
4108
         instructions since the last 8-byte-aligned execute packet
4109
         boundary.  So there must have been an execute packet with an
4110
         odd number (and so a number fewer than 8) of instructions
4111
         into which we can insert a NOP without breaking any previous
4112
         alignments.
4113
 
4114
         If then we need to insert a number 2 mod 4 of instructions,
4115
         the number of instructions since the last 16-byte-aligned
4116
         execute packet boundary must be 2 mod 4.  So between that
4117
         boundary and the following 8-byte-aligned boundary there must
4118
         either be at least one execute packet with 2-mod-4
4119
         instructions, or at least two with an odd number of
4120
         instructions; again, greedily inserting NOPs as soon as
4121
         possible suffices to meet the alignment requirement.
4122
 
4123
         If then we need to insert 4 instructions, we look between the
4124
         last 32-byte-aligned boundary and the following
4125
         16-byte-aligned boundary.  The sizes of the execute packets
4126
         in this range total 4 instructions mod 8, so again there is
4127
         room for greedy insertion of NOPs to meet the alignment
4128
         requirement, and before any intermediate point with 8-byte
4129
         (2-instruction) alignment requirement the sizes of execute
4130
         packets (and so the room for NOPs) will total 2 instructions
4131
         mod 4 so greedy insertion will not break such alignments.
4132
 
4133
         So we can always meet these alignment requirements by
4134
         inserting NOPs in parallel with existing execute packets, and
4135
         by induction the approach described above inserts the minimum
4136
         number of such NOPs.  */
4137
 
4138
      /* The number of NOPs we are currently looking to insert, if we
4139
         have gone back to insert NOPs.  */
4140
      unsigned int want_insert = 0;
4141
 
4142
      /* Out of that number, the number inserted so far in the current
4143
         stage of the above algorithm.  */
4144
      unsigned int want_insert_done_so_far = 0;
4145
 
4146
      /* The position mod 32 at the start of the current frag.  */
4147
      unsigned int pos = 0;
4148
 
4149
      /* The locations in the frag chain of the most recent frags at
4150
         the start of which there is the given alignment.  */
4151
      frchainS *frchp_last32, *frchp_last16, *frchp_last8;
4152
      fragS *fragp_last32, *fragp_last16, *fragp_last8;
4153
      unsigned int pos_last32, pos_last16, pos_last8;
4154
 
4155
      frchp_last32 = frchp_last16 = frchp_last8 = info->frchainP;
4156
      fragp_last32 = fragp_last16 = fragp_last8 = info->frchainP->frch_root;
4157
      pos_last32 = pos_last16 = pos_last8 = 0;
4158
 
4159
      for (frchp = info->frchainP; frchp; frchp = frchp->frch_next)
4160
        for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
4161
        look_at_frag:
4162
          {
4163
            bfd_boolean go_back = FALSE;
4164
            frchainS *frchp_next;
4165
            fragS *fragp_next;
4166
 
4167
            if (fragp->fr_type != rs_machine_dependent)
4168
              continue;
4169
 
4170
            if (fragp->tc_frag_data.is_insns
4171
                && pos + fragp->fr_fix > 32
4172
                && !fragp->tc_frag_data.can_cross_fp_boundary)
4173
              {
4174
                /* As described above, we should always have met an
4175
                   alignment requirement by the time we come back to
4176
                   it.  */
4177
                if (want_insert)
4178
                  abort ();
4179
 
4180
                if (pos & 3)
4181
                  abort ();
4182
                want_insert = (32 - pos) >> 2;
4183
                if (want_insert > 7)
4184
                  abort ();
4185
                want_insert_done_so_far = 0;
4186
                go_back = TRUE;
4187
              }
4188
 
4189
            if (!fragp->tc_frag_data.is_insns)
4190
              {
4191
                unsigned int would_insert_bytes;
4192
 
4193
                if (!(pos & ((1 << fragp->fr_offset) - 1)))
4194
                  /* This alignment requirement is already met.  */
4195
                  continue;
4196
 
4197
                /* As described above, we should always have met an
4198
                   alignment requirement by the time we come back to
4199
                   it.  */
4200
                if (want_insert)
4201
                  abort ();
4202
 
4203
                /* We may not be able to meet this requirement within
4204
                   the given number of characters.  */
4205
                would_insert_bytes
4206
                  = ((1 << fragp->fr_offset)
4207
                     - (pos & ((1 << fragp->fr_offset) - 1)));
4208
 
4209
                if (fragp->fr_subtype != 0
4210
                    && would_insert_bytes > fragp->fr_subtype)
4211
                  continue;
4212
 
4213
                /* An unmet alignment must be 8, 16 or 32 bytes;
4214
                   smaller ones must always be met within code-only
4215
                   sections and larger ones cause the section not to
4216
                   be code-only.  */
4217
                if (fragp->fr_offset != 3
4218
                    && fragp->fr_offset != 4
4219
                    && fragp->fr_offset != 5)
4220
                  abort ();
4221
 
4222
                if (would_insert_bytes & 3)
4223
                  abort ();
4224
                want_insert = would_insert_bytes >> 2;
4225
                if (want_insert > 7)
4226
                  abort ();
4227
                want_insert_done_so_far = 0;
4228
                go_back = TRUE;
4229
              }
4230
            else if (want_insert && !go_back)
4231
              {
4232
                unsigned int num_insns = fragp->fr_fix >> 2;
4233
                unsigned int max_poss_nops = 8 - num_insns;
4234
 
4235
                if (max_poss_nops)
4236
                  {
4237
                    unsigned int cur_want_nops, max_want_nops, do_nops, i;
4238
 
4239
                    if (want_insert & 1)
4240
                      cur_want_nops = 1;
4241
                    else if (want_insert & 2)
4242
                      cur_want_nops = 2;
4243
                    else if (want_insert & 4)
4244
                      cur_want_nops = 4;
4245
                    else
4246
                      abort ();
4247
 
4248
                    max_want_nops = cur_want_nops - want_insert_done_so_far;
4249
 
4250
                    do_nops = (max_poss_nops < max_want_nops
4251
                               ? max_poss_nops
4252
                               : max_want_nops);
4253
                    for (i = 0; i < do_nops; i++)
4254
                      {
4255
                        md_number_to_chars (fragp->fr_literal + fragp->fr_fix,
4256
                                            0, 4);
4257
                        if (target_big_endian)
4258
                          fragp->fr_literal[fragp->fr_fix - 1] |= 0x1;
4259
                        else
4260
                          fragp->fr_literal[fragp->fr_fix - 4] |= 0x1;
4261
                        fragp->fr_fix += 4;
4262
                        fragp->fr_var -= 4;
4263
                      }
4264
                    want_insert_done_so_far += do_nops;
4265
                    if (want_insert_done_so_far == cur_want_nops)
4266
                      {
4267
                        want_insert -= want_insert_done_so_far;
4268
                        want_insert_done_so_far = 0;
4269
                        if (want_insert)
4270
                          go_back = TRUE;
4271
                      }
4272
                  }
4273
              }
4274
            if (go_back)
4275
              {
4276
                if (want_insert & 1)
4277
                  {
4278
                    frchp = frchp_last8;
4279
                    fragp = fragp_last8;
4280
                    pos = pos_last8;
4281
                  }
4282
                else if (want_insert & 2)
4283
                  {
4284
                    frchp = frchp_last8 = frchp_last16;
4285
                    fragp = fragp_last8 = fragp_last16;
4286
                    pos = pos_last8 = pos_last16;
4287
                  }
4288
                else if (want_insert & 4)
4289
                  {
4290
                    frchp = frchp_last8 = frchp_last16 = frchp_last32;
4291
                    fragp = fragp_last8 = fragp_last16 = fragp_last32;
4292
                    pos = pos_last8 = pos_last16 = pos_last32;
4293
                  }
4294
                else
4295
                  abort ();
4296
 
4297
                goto look_at_frag;
4298
              }
4299
 
4300
            /* Update current position for moving past a code
4301
               frag.  */
4302
            pos += fragp->fr_fix;
4303
            pos &= 31;
4304
            frchp_next = frchp;
4305
            fragp_next = fragp->fr_next;
4306
            if (fragp_next == NULL)
4307
              {
4308
                frchp_next = frchp->frch_next;
4309
                if (frchp_next != NULL)
4310
                  fragp_next = frchp_next->frch_root;
4311
              }
4312
            if (!(pos & 7))
4313
              {
4314
                frchp_last8 = frchp_next;
4315
                fragp_last8 = fragp_next;
4316
                pos_last8 = pos;
4317
              }
4318
            if (!(pos & 15))
4319
              {
4320
                frchp_last16 = frchp_next;
4321
                fragp_last16 = fragp_next;
4322
                pos_last16 = pos;
4323
              }
4324
            if (!(pos & 31))
4325
              {
4326
                frchp_last32 = frchp_next;
4327
                fragp_last32 = fragp_next;
4328
                pos_last32 = pos;
4329
              }
4330
          }
4331
    }
4332
 
4333
  /* Now convert the machine-dependent frags to machine-independent
4334
     ones.  */
4335
  for (frchp = info->frchainP; frchp; frchp = frchp->frch_next)
4336
    for (fragp = frchp->frch_root; fragp; fragp = fragp->fr_next)
4337
      {
4338
        if (fragp->fr_type == rs_machine_dependent)
4339
          {
4340
            if (fragp->tc_frag_data.is_insns)
4341
              frag_wane (fragp);
4342
            else
4343
              {
4344
                fragp->fr_type = rs_align_code;
4345
                fragp->fr_var = 1;
4346
                *fragp->fr_literal = 0;
4347
              }
4348
          }
4349
      }
4350
}
4351
 
4352
/* Initialize the machine-dependent parts of a frag.  */
4353
 
4354
void
4355
tic6x_frag_init (fragS *fragp)
4356
{
4357
  fragp->tc_frag_data.is_insns = FALSE;
4358
  fragp->tc_frag_data.can_cross_fp_boundary = FALSE;
4359
}
4360
 
4361
/* Set an attribute if it has not already been set by the user.  */
4362
 
4363
static void
4364
tic6x_set_attribute_int (int tag, int value)
4365
{
4366
  if (tag < 1
4367
      || tag >= NUM_KNOWN_OBJ_ATTRIBUTES)
4368
    abort ();
4369
  if (!tic6x_attributes_set_explicitly[tag])
4370
    bfd_elf_add_proc_attr_int (stdoutput, tag, value);
4371
}
4372
 
4373
/* Set object attributes deduced from the input file and command line
4374
   rather than given explicitly.  */
4375
static void
4376
tic6x_set_attributes (void)
4377
{
4378
  if (tic6x_arch_attribute == C6XABI_Tag_ISA_none)
4379
    tic6x_arch_attribute = C6XABI_Tag_ISA_C674X;
4380
 
4381
  tic6x_set_attribute_int (Tag_ISA, tic6x_arch_attribute);
4382
  tic6x_set_attribute_int (Tag_ABI_DSBT, tic6x_dsbt);
4383
  tic6x_set_attribute_int (Tag_ABI_PID, tic6x_pid);
4384
  tic6x_set_attribute_int (Tag_ABI_PIC, tic6x_pic);
4385
}
4386
 
4387
/* Do machine-dependent manipulations of the frag chains after all
4388
   input has been read and before the machine-independent sizing and
4389
   relaxing.  */
4390
 
4391
void
4392
tic6x_end (void)
4393
{
4394
  /* Set object attributes at this point if not explicitly set.  */
4395
  tic6x_set_attributes ();
4396
 
4397
  /* Meeting alignment requirements may require inserting NOPs in
4398
     parallel in execute packets earlier in the segment.  Future
4399
     16-bit instruction generation involves whole-segment optimization
4400
     to determine the best choice and ordering of 32-bit or 16-bit
4401
     instructions.  This doesn't fit will in the general relaxation
4402
     framework, so handle alignment and 16-bit instruction generation
4403
     here.  */
4404
  bfd_map_over_sections (stdoutput, tic6x_adjust_section, NULL);
4405
}
4406
 
4407
/* No machine-dependent frags at this stage; all converted in
4408
   tic6x_end.  */
4409
 
4410
void
4411
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec ATTRIBUTE_UNUSED,
4412
                 fragS *fragp ATTRIBUTE_UNUSED)
4413
{
4414
  abort ();
4415
}
4416
 
4417
/* No machine-dependent frags at this stage; all converted in
4418
   tic6x_end.  */
4419
 
4420
int
4421
md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
4422
                               segT seg ATTRIBUTE_UNUSED)
4423
{
4424
  abort ();
4425
}
4426
 
4427
/* Put a number into target byte order.  */
4428
 
4429
void
4430
md_number_to_chars (char *buf, valueT val, int n)
4431
{
4432
  if (target_big_endian)
4433
    number_to_chars_bigendian (buf, val, n);
4434
  else
4435
    number_to_chars_littleendian (buf, val, n);
4436
}
4437
 
4438
/* Machine-dependent operand parsing not currently needed.  */
4439
 
4440
void
4441
md_operand (expressionS *op ATTRIBUTE_UNUSED)
4442
{
4443
}
4444
 
4445
/* PC-relative operands are relative to the start of the fetch
4446
   packet.  */
4447
 
4448
long
4449
tic6x_pcrel_from_section (fixS *fixp, segT sec)
4450
{
4451
  if (fixp->fx_addsy != NULL
4452
      && (!S_IS_DEFINED (fixp->fx_addsy)
4453
          || S_GET_SEGMENT (fixp->fx_addsy) != sec))
4454
    return 0;
4455
  return (fixp->fx_where + fixp->fx_frag->fr_address) & ~(long) 0x1f;
4456
}
4457
 
4458
/* Round up a section size to the appropriate boundary.  */
4459
 
4460
valueT
4461
md_section_align (segT segment ATTRIBUTE_UNUSED,
4462
                  valueT size)
4463
{
4464
  /* Round up section sizes to ensure that text sections consist of
4465
     whole fetch packets.  */
4466
  int align = bfd_get_section_alignment (stdoutput, segment);
4467
  return ((size + (1 << align) - 1) & ((valueT) -1 << align));
4468
}
4469
 
4470
/* No special undefined symbol handling needed for now.  */
4471
 
4472
symbolS *
4473
md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
4474
{
4475
  return NULL;
4476
}
4477
 
4478
/* Translate internal representation of relocation info to BFD target
4479
   format.  */
4480
 
4481
arelent *
4482
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
4483
{
4484
  arelent *reloc;
4485
  asymbol *symbol;
4486
  bfd_reloc_code_real_type r_type;
4487
 
4488
  reloc = xmalloc (sizeof (arelent));
4489
  reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
4490
  symbol = symbol_get_bfdsym (fixp->fx_addsy);
4491
  *reloc->sym_ptr_ptr = symbol;
4492
  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
4493
  reloc->addend = (tic6x_generate_rela ? fixp->fx_offset : 0);
4494
  r_type = fixp->fx_r_type;
4495
  reloc->howto = bfd_reloc_type_lookup (stdoutput, r_type);
4496
 
4497
  if (reloc->howto == NULL)
4498
    {
4499
      as_bad_where (fixp->fx_file, fixp->fx_line,
4500
                    _("Cannot represent relocation type %s"),
4501
                    bfd_get_reloc_code_name (r_type));
4502
      return NULL;
4503
    }
4504
 
4505
  /* Correct for adjustments bfd_install_relocation will make.  */
4506
  if (reloc->howto->pcrel_offset && reloc->howto->partial_inplace)
4507
    {
4508
      reloc->addend += reloc->address;
4509
      if (!bfd_is_com_section (symbol))
4510
        reloc->addend -= symbol->value;
4511
    }
4512
  if (r_type == BFD_RELOC_C6000_PCR_H16
4513
      || r_type == BFD_RELOC_C6000_PCR_L16)
4514
    {
4515
      symbolS *t = fixp->tc_fix_data.fix_subsy;
4516
      segT sub_symbol_segment;
4517
 
4518
      resolve_symbol_value (t);
4519
      sub_symbol_segment = S_GET_SEGMENT (t);
4520
      if (sub_symbol_segment == undefined_section)
4521
        as_bad_where (fixp->fx_file, fixp->fx_line,
4522
                      _("undefined symbol %s in PCR relocation"),
4523
                      S_GET_NAME (t));
4524
      else
4525
        {
4526
          reloc->addend = reloc->address & ~0x1F;
4527
          reloc->addend -= S_GET_VALUE (t);
4528
        }
4529
    }
4530
  return reloc;
4531
}
4532
 
4533
/* Convert REGNAME to a DWARF-2 register number.  */
4534
 
4535
int
4536
tic6x_regname_to_dw2regnum (char *regname)
4537
{
4538
  bfd_boolean reg_ok;
4539
  tic6x_register reg;
4540
  char *rq = regname;
4541
 
4542
  reg_ok = tic6x_parse_register (&rq, &reg);
4543
 
4544
  if (!reg_ok)
4545
    return -1;
4546
 
4547
  switch (reg.side)
4548
    {
4549
    case 1: /* A regs.  */
4550
      if (reg.num < 16)
4551
        return reg.num;
4552
      else if (reg.num < 32)
4553
        return (reg.num - 16) + 37;
4554
      else
4555
        return -1;
4556
 
4557
    case 2: /* B regs.  */
4558
      if (reg.num < 16)
4559
        return reg.num + 16;
4560
      else if (reg.num < 32)
4561
        return (reg.num - 16) + 53;
4562
      else
4563
        return -1;
4564
 
4565
    default:
4566
      return -1;
4567
    }
4568
}
4569
 
4570
/* Initialize the DWARF-2 unwind information for this procedure.  */
4571
 
4572
void
4573
tic6x_frame_initial_instructions (void)
4574
{
4575
  /* CFA is initial stack pointer (B15).  */
4576
  cfi_add_CFA_def_cfa (31, 0);
4577
}
4578
 
4579
/* Start an exception table entry.  If idx is nonzero this is an index table
4580
   entry.  */
4581
 
4582
static void
4583
tic6x_start_unwind_section (const segT text_seg, int idx)
4584
{
4585
  tic6x_unwind_info *unwind = tic6x_get_unwind ();
4586
  const char * text_name;
4587
  const char * prefix;
4588
  const char * prefix_once;
4589
  const char * group_name;
4590
  size_t prefix_len;
4591
  size_t text_len;
4592
  char * sec_name;
4593
  size_t sec_name_len;
4594
  int type;
4595
  int flags;
4596
  int linkonce;
4597
 
4598
  if (idx)
4599
    {
4600
      prefix = ELF_STRING_C6000_unwind;
4601
      prefix_once = ELF_STRING_C6000_unwind_once;
4602
      type = SHT_C6000_UNWIND;
4603
    }
4604
  else
4605
    {
4606
      prefix = ELF_STRING_C6000_unwind_info;
4607
      prefix_once = ELF_STRING_C6000_unwind_info_once;
4608
      type = SHT_PROGBITS;
4609
    }
4610
 
4611
  text_name = segment_name (text_seg);
4612
  if (streq (text_name, ".text"))
4613
    text_name = "";
4614
 
4615
  if (strncmp (text_name, ".gnu.linkonce.t.",
4616
               strlen (".gnu.linkonce.t.")) == 0)
4617
    {
4618
      prefix = prefix_once;
4619
      text_name += strlen (".gnu.linkonce.t.");
4620
    }
4621
 
4622
  prefix_len = strlen (prefix);
4623
  text_len = strlen (text_name);
4624
  sec_name_len = prefix_len + text_len;
4625
  sec_name = (char *) xmalloc (sec_name_len + 1);
4626
  memcpy (sec_name, prefix, prefix_len);
4627
  memcpy (sec_name + prefix_len, text_name, text_len);
4628
  sec_name[prefix_len + text_len] = '\0';
4629
 
4630
  flags = SHF_ALLOC;
4631
  linkonce = 0;
4632
  group_name = 0;
4633
 
4634
  /* Handle COMDAT group.  */
4635
  if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
4636
    {
4637
      group_name = elf_group_name (text_seg);
4638
      if (group_name == NULL)
4639
        {
4640
          as_bad (_("group section `%s' has no group signature"),
4641
                  segment_name (text_seg));
4642
          ignore_rest_of_line ();
4643
          return;
4644
        }
4645
      flags |= SHF_GROUP;
4646
      linkonce = 1;
4647
    }
4648
 
4649
  obj_elf_change_section (sec_name, type, flags, 0, group_name, linkonce, 0);
4650
 
4651
  /* Set the section link for index tables.  */
4652
  if (idx)
4653
    elf_linked_to_section (now_seg) = text_seg;
4654
 
4655
  seg_info (now_seg)->tc_segment_info_data.text_unwind = unwind;
4656
}
4657
 
4658
 
4659
static const int
4660
tic6x_unwind_frame_regs[TIC6X_NUM_UNWIND_REGS] =
4661
/* A15 B15 B14 B13 B12 B11 B10  B3 A14 A13 A12 A11 A10.  */
4662
  { 15, 31, 30, 29, 28, 27, 26, 19, 14, 13, 12, 11, 10 };
4663
 
4664
/* Register save offsets for __c6xabi_push_rts.  */
4665
static const int
4666
tic6x_pop_rts_offset_little[TIC6X_NUM_UNWIND_REGS] =
4667
/* A15 B15 B14 B13 B12 B11 B10  B3 A14 A13 A12 A11 A10.  */
4668
  { -1,  1,  0, -3, -4, -7, -8,-11, -2, -5, -6, -9,-10};
4669
 
4670
static const int
4671
tic6x_pop_rts_offset_big[TIC6X_NUM_UNWIND_REGS] =
4672
/* A15 B15 B14 B13 B12 B11 B10  B3 A14 A13 A12 A11 A10.  */
4673
  { -2,  1,  0, -4, -3, -8, -7,-12, -1, -6, -5,-10, -9};
4674
 
4675
/* Map from dwarf register number to unwind frame register number.  */
4676
static int
4677
tic6x_unwind_reg_from_dwarf (int dwarf)
4678
{
4679
  int reg;
4680
 
4681
  for (reg = 0; reg < TIC6X_NUM_UNWIND_REGS; reg++)
4682
    {
4683
      if (tic6x_unwind_frame_regs[reg] == dwarf)
4684
        return reg;
4685
    }
4686
 
4687
  return -1;
4688
}
4689
 
4690
/* Unwinding bytecode definitions.  */
4691
#define UNWIND_OP_ADD_SP  0x00
4692
#define UNWIND_OP_ADD_SP2 0xd2
4693
#define UNWIND_OP2_POP 0x8000
4694
#define UNWIND_OP2_POP_COMPACT 0xa000
4695
#define UNWIND_OP_POP_REG 0xc0
4696
#define UNWIND_OP_MV_FP 0xd0
4697
#define UNWIND_OP_POP_RTS 0xd1
4698
#define UNWIND_OP_RET 0xe0
4699
 
4700
/* Maximum stack adjustment for __c6xabi_unwind_cpp_pr3/4 */
4701
#define MAX_COMPACT_SP_OFFSET (0x7f << 3)
4702
 
4703
static void
4704
tic6x_flush_unwind_word (valueT data)
4705
{
4706
  tic6x_unwind_info *unwind = tic6x_get_unwind ();
4707
  char *ptr;
4708
 
4709
  /* Create EXTAB entry if it does not exist.  */
4710
  if (unwind->table_entry == NULL)
4711
    {
4712
      tic6x_start_unwind_section (unwind->saved_seg, 0);
4713
      frag_align (2, 0, 0);
4714
      record_alignment (now_seg, 2);
4715
      unwind->table_entry = expr_build_dot ();
4716
      ptr = frag_more (4);
4717
      unwind->frag_start = ptr;
4718
    }
4719
  else
4720
    {
4721
      /* Append additional word of data.  */
4722
      ptr = frag_more (4);
4723
    }
4724
 
4725
  md_number_to_chars (ptr, data, 4);
4726
}
4727
 
4728
/* Add a single byte of unwinding data.  */
4729
 
4730
static void
4731
tic6x_unwind_byte (int byte)
4732
{
4733
  tic6x_unwind_info *unwind = tic6x_get_unwind ();
4734
 
4735
  unwind->data_bytes++;
4736
  /* Only flush the first word after we know multiple words are required.  */
4737
  if (unwind->data_bytes == 5)
4738
    {
4739
      if (unwind->personality_index == -1)
4740
        {
4741
          /* At this point we know we are too big for pr0.  */
4742
          unwind->personality_index = 1;
4743
          tic6x_flush_unwind_word (0x81000000 | ((unwind->data >> 8) & 0xffff));
4744
          unwind->data = ((unwind->data & 0xff) << 8) | byte;
4745
          unwind->data_bytes++;
4746
        }
4747
      else
4748
        {
4749
          tic6x_flush_unwind_word (unwind->data);
4750
          unwind->data = byte;
4751
        }
4752
    }
4753
  else
4754
    {
4755
      unwind->data = (unwind->data << 8) | byte;
4756
      if ((unwind->data_bytes & 3) == 0 && unwind->data_bytes > 4)
4757
        {
4758
          tic6x_flush_unwind_word (unwind->data);
4759
          unwind->data = 0;
4760
        }
4761
    }
4762
}
4763
 
4764
/* Add a two-byte unwinding opcode.  */
4765
static void
4766
tic6x_unwind_2byte (int bytes)
4767
{
4768
  tic6x_unwind_byte (bytes >> 8);
4769
  tic6x_unwind_byte (bytes & 0xff);
4770
}
4771
 
4772
static void
4773
tic6x_unwind_uleb (offsetT offset)
4774
{
4775
  while (offset > 0x7f)
4776
    {
4777
      tic6x_unwind_byte ((offset & 0x7f) | 0x80);
4778
      offset >>= 7;
4779
    }
4780
  tic6x_unwind_byte (offset);
4781
}
4782
 
4783
void
4784
tic6x_cfi_startproc (void)
4785
{
4786
  tic6x_unwind_info *unwind = tic6x_get_unwind ();
4787
 
4788
  unwind->personality_index = -1;
4789
  unwind->personality_routine = NULL;
4790
  if (unwind->table_entry)
4791
    as_bad (_("missing .endp before .cfi_startproc"));
4792
 
4793
  unwind->table_entry = NULL;
4794
  unwind->data_bytes = -1;
4795
}
4796
 
4797
static void
4798
tic6x_output_exidx_entry (void)
4799
{
4800
  char *ptr;
4801
  long where;
4802
  unsigned int marked_pr_dependency;
4803
  segT old_seg;
4804
  subsegT old_subseg;
4805
  tic6x_unwind_info *unwind = tic6x_get_unwind ();
4806
 
4807
  old_seg = now_seg;
4808
  old_subseg = now_subseg;
4809
 
4810
  /* Add index table entry.  This is two words.  */
4811
  tic6x_start_unwind_section (unwind->saved_seg, 1);
4812
  frag_align (2, 0, 0);
4813
  record_alignment (now_seg, 2);
4814
 
4815
  ptr = frag_more (8);
4816
  where = frag_now_fix () - 8;
4817
 
4818
  /* Self relative offset of the function start.  */
4819
  fix_new (frag_now, where, 4, unwind->function_start, 0, 1,
4820
           BFD_RELOC_C6000_PREL31);
4821
 
4822
  /* Indicate dependency on ABI-defined personality routines to the
4823
     linker, if it hasn't been done already.  */
4824
  marked_pr_dependency
4825
    = seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency;
4826
  if (unwind->personality_index >= 0 && unwind->personality_index < 5
4827
      && !(marked_pr_dependency & (1 << unwind->personality_index)))
4828
    {
4829
      static const char *const name[] =
4830
        {
4831
          "__c6xabi_unwind_cpp_pr0",
4832
          "__c6xabi_unwind_cpp_pr1",
4833
          "__c6xabi_unwind_cpp_pr2",
4834
          "__c6xabi_unwind_cpp_pr3",
4835
          "__c6xabi_unwind_cpp_pr4"
4836
        };
4837
      symbolS *pr = symbol_find_or_make (name[unwind->personality_index]);
4838
      fix_new (frag_now, where, 0, pr, 0, 1, BFD_RELOC_NONE);
4839
      seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency
4840
        |= 1 << unwind->personality_index;
4841
    }
4842
 
4843
  if (unwind->table_entry)
4844
    {
4845
      /* Self relative offset of the table entry.        */
4846
      fix_new (frag_now, where + 4, 4, unwind->table_entry, 0, 1,
4847
               BFD_RELOC_C6000_PREL31);
4848
    }
4849
  else
4850
    {
4851
      /* Inline exception table entry.  */
4852
      md_number_to_chars (ptr + 4, unwind->data, 4);
4853
    }
4854
 
4855
  /* Restore the original section.  */
4856
  subseg_set (old_seg, old_subseg);
4857
}
4858
 
4859
static void
4860
tic6x_output_unwinding (bfd_boolean need_extab)
4861
{
4862
  tic6x_unwind_info *unwind = tic6x_get_unwind ();
4863
  unsigned safe_mask = unwind->safe_mask;
4864
  unsigned compact_mask = unwind->compact_mask;
4865
  unsigned reg_saved_mask = unwind->reg_saved_mask;
4866
  offsetT cfa_offset = unwind->cfa_offset;
4867
  long where;
4868
  int reg;
4869
 
4870
  if (unwind->personality_index == -2)
4871
    {
4872
      /* Function can not be unwound.  */
4873
      unwind->data = 1;
4874
      tic6x_output_exidx_entry ();
4875
      return;
4876
    }
4877
 
4878
  if (unwind->personality_index == -1 && unwind->personality_routine == NULL)
4879
    {
4880
      /* Auto-select a personality routine if none specified.  */
4881
      if (reg_saved_mask || cfa_offset >= MAX_COMPACT_SP_OFFSET)
4882
        unwind->personality_index = -1;
4883
      else if (safe_mask)
4884
        unwind->personality_index = 3;
4885
      else
4886
        unwind->personality_index = 4;
4887
    }
4888
 
4889
  /* Calculate unwinding opcodes, and emit to EXTAB if necessary.  */
4890
  unwind->table_entry = NULL;
4891
  if (unwind->personality_index == 3 || unwind->personality_index == 4)
4892
    {
4893
      if (cfa_offset >= MAX_COMPACT_SP_OFFSET)
4894
        {
4895
          as_bad (_("stack pointer offset too large for personality routine"));
4896
          return;
4897
        }
4898
      if (reg_saved_mask
4899
          || (unwind->personality_index == 3 && compact_mask != 0)
4900
          || (unwind->personality_index == 4 && safe_mask != 0))
4901
        {
4902
          as_bad (_("stack frame layout does not match personality routine"));
4903
          return;
4904
        }
4905
 
4906
      unwind->data = (1u << 31) | (unwind->personality_index << 24);
4907
      if (unwind->cfa_reg == 15)
4908
        unwind->data |= 0x7f << 17;
4909
      else
4910
        unwind->data |= cfa_offset << (17 - 3);
4911
 
4912
      if (unwind->personality_index == 3)
4913
        unwind->data |= safe_mask << 4;
4914
      else
4915
        unwind->data |= compact_mask << 4;
4916
      unwind->data |= unwind->return_reg;
4917
      unwind->data_bytes = 4;
4918
    }
4919
  else
4920
    {
4921
      if (unwind->personality_routine)
4922
        {
4923
          unwind->data = 0;
4924
          unwind->data_bytes = 5;
4925
          tic6x_flush_unwind_word (0);
4926
          /* First word is personality routine.  */
4927
          where = frag_now_fix () - 4;
4928
          fix_new (frag_now, where, 4, unwind->personality_routine, 0, 1,
4929
                   BFD_RELOC_C6000_PREL31);
4930
        }
4931
      else if (unwind->personality_index > 0)
4932
        {
4933
          unwind->data = 0x8000 | (unwind->personality_index << 8);
4934
          unwind->data_bytes = 2;
4935
        }
4936
      else /* pr0 or undecided */
4937
        {
4938
          unwind->data = 0x80;
4939
          unwind->data_bytes = 1;
4940
        }
4941
 
4942
      if (unwind->return_reg != UNWIND_B3)
4943
        {
4944
          tic6x_unwind_byte (UNWIND_OP_RET | unwind->return_reg);
4945
        }
4946
 
4947
      if (unwind->cfa_reg == 15)
4948
        {
4949
          tic6x_unwind_byte (UNWIND_OP_MV_FP);
4950
        }
4951
      else if (cfa_offset != 0)
4952
        {
4953
          cfa_offset >>= 3;
4954
          if (cfa_offset > 0x80)
4955
            {
4956
              tic6x_unwind_byte (UNWIND_OP_ADD_SP2);
4957
              tic6x_unwind_uleb (cfa_offset - 0x81);
4958
            }
4959
          else if (cfa_offset > 0x40)
4960
            {
4961
              tic6x_unwind_byte (UNWIND_OP_ADD_SP | 0x3f);
4962
              tic6x_unwind_byte (UNWIND_OP_ADD_SP | (cfa_offset - 0x40));
4963
            }
4964
          else
4965
            {
4966
              tic6x_unwind_byte (UNWIND_OP_ADD_SP | (cfa_offset - 1));
4967
            }
4968
        }
4969
 
4970
      if (safe_mask)
4971
        tic6x_unwind_2byte (UNWIND_OP2_POP | unwind->safe_mask);
4972
      else if (unwind->pop_rts)
4973
        tic6x_unwind_byte (UNWIND_OP_POP_RTS);
4974
      else if (compact_mask)
4975
        tic6x_unwind_2byte (UNWIND_OP2_POP_COMPACT | unwind->compact_mask);
4976
      else if (reg_saved_mask)
4977
        {
4978
          offsetT cur_offset;
4979
          int val;
4980
          int last_val;
4981
 
4982
          tic6x_unwind_byte (UNWIND_OP_POP_REG | unwind->saved_reg_count);
4983
          last_val = 0;
4984
          for (cur_offset = 0; unwind->saved_reg_count > 0; cur_offset -= 4)
4985
            {
4986
              val = 0xf;
4987
              for (reg = 0; reg < TIC6X_NUM_UNWIND_REGS; reg++)
4988
                {
4989
                  if (!unwind->reg_saved[reg])
4990
                    continue;
4991
 
4992
                  if (unwind->reg_offset[reg] == cur_offset)
4993
                    {
4994
                      unwind->saved_reg_count--;
4995
                      val = reg;
4996
                      break;
4997
                    }
4998
                }
4999
              if ((cur_offset & 4) == 4)
5000
                tic6x_unwind_byte ((last_val << 4) | val);
5001
              else
5002
                last_val = val;
5003
            }
5004
          if ((cur_offset & 4) == 4)
5005
            tic6x_unwind_byte ((last_val << 4) | 0xf);
5006
        }
5007
 
5008
      /* Pad with RETURN opcodes.  */
5009
      while ((unwind->data_bytes & 3) != 0)
5010
        tic6x_unwind_byte (UNWIND_OP_RET | UNWIND_B3);
5011
 
5012
      if (unwind->personality_index == -1 && unwind->personality_routine == NULL)
5013
        unwind->personality_index = 0;
5014
    }
5015
 
5016
  /* Force creation of an EXTAB entry if an LSDA is required.  */
5017
  if (need_extab && !unwind->table_entry)
5018
    {
5019
      if (unwind->data_bytes != 4)
5020
        abort ();
5021
 
5022
      tic6x_flush_unwind_word (unwind->data);
5023
    }
5024
  else if (unwind->table_entry && !need_extab)
5025
    {
5026
      /* Add an empty descriptor if there is no user-specified data.   */
5027
      char *ptr = frag_more (4);
5028
      md_number_to_chars (ptr, 0, 4);
5029
    }
5030
 
5031
  /* Fill in length of unwinding bytecode.  */
5032
  if (unwind->table_entry)
5033
    {
5034
      valueT tmp;
5035
      if (unwind->data_bytes > 0x400)
5036
        as_bad (_("too many unwinding instructions"));
5037
 
5038
      if (unwind->personality_index == -1)
5039
        {
5040
          tmp = md_chars_to_number (unwind->frag_start + 4, 4);
5041
          tmp |= ((unwind->data_bytes - 8) >> 2) << 24;
5042
          md_number_to_chars (unwind->frag_start + 4, tmp, 4);
5043
        }
5044
      else if (unwind->personality_index == 1 || unwind->personality_index == 2)
5045
        {
5046
          tmp = md_chars_to_number (unwind->frag_start, 4);
5047
          tmp |= ((unwind->data_bytes - 4) >> 2) << 16;
5048
          md_number_to_chars (unwind->frag_start, tmp, 4);
5049
        }
5050
    }
5051
  tic6x_output_exidx_entry ();
5052
}
5053
 
5054
/* FIXME: This will get horribly confused if cfi directives are emitted for
5055
   function epilogue.  */
5056
void
5057
tic6x_cfi_endproc (struct fde_entry *fde)
5058
{
5059
  tic6x_unwind_info *unwind = tic6x_get_unwind ();
5060
  struct cfi_insn_data *insn;
5061
  int reg;
5062
  unsigned safe_mask = 0;
5063
  unsigned compact_mask = 0;
5064
  unsigned reg_saved_mask = 0;
5065
  offsetT cfa_offset = 0;
5066
  offsetT save_offset = 0;
5067
 
5068
  unwind->cfa_reg = 31;
5069
  unwind->return_reg = UNWIND_B3;
5070
  unwind->saved_reg_count = 0;
5071
  unwind->pop_rts = FALSE;
5072
 
5073
  unwind->saved_seg = now_seg;
5074
  unwind->saved_subseg = now_subseg;
5075
 
5076
  for (reg = 0; reg < TIC6X_NUM_UNWIND_REGS; reg++)
5077
    unwind->reg_saved[reg] = FALSE;
5078
 
5079
  /* Scan FDE instructions to build up stack frame layout.  */
5080
  for (insn = fde->data; insn; insn = insn->next)
5081
    {
5082
      switch (insn->insn)
5083
        {
5084
        case DW_CFA_advance_loc:
5085
          break;
5086
 
5087
        case DW_CFA_def_cfa:
5088
          unwind->cfa_reg = insn->u.ri.reg;
5089
          cfa_offset = insn->u.ri.offset;
5090
          break;
5091
 
5092
        case DW_CFA_def_cfa_register:
5093
          unwind->cfa_reg = insn->u.r;
5094
          break;
5095
 
5096
        case DW_CFA_def_cfa_offset:
5097
          cfa_offset = insn->u.i;
5098
          break;
5099
 
5100
        case DW_CFA_undefined:
5101
        case DW_CFA_same_value:
5102
          reg = tic6x_unwind_reg_from_dwarf (insn->u.r);
5103
          if (reg >= 0)
5104
            unwind->reg_saved[reg] = FALSE;
5105
          break;
5106
 
5107
        case DW_CFA_offset:
5108
          reg = tic6x_unwind_reg_from_dwarf (insn->u.ri.reg);
5109
          if (reg < 0)
5110
            {
5111
              as_bad (_("unable to generate unwinding opcode for reg %d"),
5112
                      insn->u.ri.reg);
5113
              return;
5114
            }
5115
          unwind->reg_saved[reg] = TRUE;
5116
          unwind->reg_offset[reg] = insn->u.ri.offset;
5117
          if (insn->u.ri.reg == UNWIND_B3)
5118
            unwind->return_reg = UNWIND_B3;
5119
          break;
5120
 
5121
        case DW_CFA_register:
5122
          if (insn->u.rr.reg1 != 19)
5123
            {
5124
              as_bad (_("unable to generate unwinding opcode for reg %d"),
5125
                      insn->u.rr.reg1);
5126
              return;
5127
            }
5128
 
5129
          reg = tic6x_unwind_reg_from_dwarf (insn->u.rr.reg2);
5130
          if (reg < 0)
5131
            {
5132
              as_bad (_("unable to generate unwinding opcode for reg %d"),
5133
                      insn->u.rr.reg2);
5134
              return;
5135
            }
5136
 
5137
          unwind->return_reg = reg;
5138
          unwind->reg_saved[UNWIND_B3] = FALSE;
5139
          if (unwind->reg_saved[reg])
5140
            {
5141
              as_bad (_("unable to restore return address from "
5142
                        "previously restored reg"));
5143
              return;
5144
            }
5145
          break;
5146
 
5147
        case DW_CFA_restore:
5148
        case DW_CFA_remember_state:
5149
        case DW_CFA_restore_state:
5150
        case DW_CFA_GNU_window_save:
5151
        case CFI_escape:
5152
        case CFI_val_encoded_addr:
5153
          as_bad (_("unhandled CFA insn for unwinding (%d)"), insn->insn);
5154
          break;
5155
 
5156
        default:
5157
          abort ();
5158
        }
5159
    }
5160
 
5161
  if (unwind->cfa_reg != 15 && unwind->cfa_reg != 31)
5162
    {
5163
      as_bad (_("unable to generate unwinding opcode for frame pointer reg %d"),
5164
              unwind->cfa_reg);
5165
      return;
5166
    }
5167
 
5168
  if (unwind->cfa_reg == 15)
5169
    {
5170
      if (cfa_offset != 0)
5171
        {
5172
          as_bad (_("unable to generate unwinding opcode for "
5173
                    "frame pointer offset"));
5174
          return;
5175
        }
5176
    }
5177
  else
5178
    {
5179
      if ((cfa_offset & 7) != 0)
5180
        {
5181
          as_bad (_("unwound stack pointer not doubleword aligned"));
5182
          return;
5183
        }
5184
    }
5185
 
5186
  for (reg = 0; reg < TIC6X_NUM_UNWIND_REGS; reg++)
5187
    {
5188
      if (unwind->reg_saved[reg])
5189
        reg_saved_mask |= 1 << (TIC6X_NUM_UNWIND_REGS - (reg + 1));
5190
    }
5191
 
5192
  /* Check for standard "safe debug" frame layout */
5193
  if (reg_saved_mask)
5194
    {
5195
      save_offset = 0;
5196
      for (reg = 0; reg < TIC6X_NUM_UNWIND_REGS; reg++)
5197
        {
5198
          if (!unwind->reg_saved[reg])
5199
            continue;
5200
 
5201
          if (target_big_endian
5202
              && reg < TIC6X_NUM_UNWIND_REGS - 1
5203
              && unwind->reg_saved[reg + 1]
5204
              && tic6x_unwind_frame_regs[reg]
5205
                  == tic6x_unwind_frame_regs[reg + 1] + 1
5206
              && (tic6x_unwind_frame_regs[reg] & 1) == 1
5207
              && (save_offset & 4) == 4)
5208
            {
5209
              /* Swapped pair */
5210
              if (save_offset != unwind->reg_offset[reg + 1]
5211
                  || save_offset - 4 != unwind->reg_offset[reg])
5212
                break;
5213
              save_offset -= 8;
5214
              reg++;
5215
            }
5216
          else
5217
            {
5218
              if (save_offset != unwind->reg_offset[reg])
5219
                break;
5220
              save_offset -= 4;
5221
            }
5222
        }
5223
      if (reg == TIC6X_NUM_UNWIND_REGS)
5224
        {
5225
          safe_mask = reg_saved_mask;
5226
          reg_saved_mask = 0;
5227
        }
5228
    }
5229
 
5230
  /* Check for compact frame layout.  */
5231
  if (reg_saved_mask)
5232
    {
5233
      save_offset = 0;
5234
      for (reg = 0; reg < TIC6X_NUM_UNWIND_REGS; reg++)
5235
        {
5236
          int reg2;
5237
 
5238
          if (!unwind->reg_saved[reg])
5239
            continue;
5240
 
5241
          if (reg < TIC6X_NUM_UNWIND_REGS - 1)
5242
            {
5243
              reg2 = reg + 1;
5244
 
5245
              if (!unwind->reg_saved[reg2]
5246
                  || tic6x_unwind_frame_regs[reg]
5247
                      != tic6x_unwind_frame_regs[reg2] + 1
5248
                  || (tic6x_unwind_frame_regs[reg2] & 1) != 0
5249
                  || save_offset == 0)
5250
                reg2 = -1;
5251
            }
5252
          else
5253
            reg2 = -1;
5254
 
5255
          if (reg2 >= 0)
5256
            {
5257
              int high_offset;
5258
              if (target_big_endian)
5259
                high_offset = 4; /* lower address = positive stack offset.  */
5260
              else
5261
                high_offset = 0;
5262
 
5263
              if (save_offset + 4 - high_offset != unwind->reg_offset[reg]
5264
                  || save_offset + high_offset != unwind->reg_offset[reg2])
5265
                {
5266
                  break;
5267
                }
5268
              reg++;
5269
            }
5270
          else
5271
            {
5272
              if (save_offset != unwind->reg_offset[reg])
5273
                break;
5274
            }
5275
          save_offset -= 8;
5276
        }
5277
 
5278
      if (reg == TIC6X_NUM_UNWIND_REGS)
5279
        {
5280
          compact_mask = reg_saved_mask;
5281
          reg_saved_mask = 0;
5282
        }
5283
    }
5284
 
5285
  /* Check for __c6xabi_pop_rts format */
5286
  if (reg_saved_mask == 0x17ff)
5287
    {
5288
      const int *pop_rts_offset = target_big_endian
5289
                                ? tic6x_pop_rts_offset_big
5290
                                : tic6x_pop_rts_offset_little;
5291
 
5292
      save_offset = 0;
5293
      for (reg = 0; reg < TIC6X_NUM_UNWIND_REGS; reg++)
5294
        {
5295
          if (reg == UNWIND_B15)
5296
            continue;
5297
 
5298
          if (unwind->reg_offset[reg] != pop_rts_offset[reg] * 4)
5299
            break;
5300
        }
5301
 
5302
      if (reg == TIC6X_NUM_UNWIND_REGS)
5303
        {
5304
          unwind->pop_rts = TRUE;
5305
          reg_saved_mask = 0;
5306
        }
5307
    }
5308
  /* If all else fails then describe the frame manually.  */
5309
  if (reg_saved_mask)
5310
    {
5311
      save_offset = 0;
5312
 
5313
      for (reg = 0; reg < TIC6X_NUM_UNWIND_REGS; reg++)
5314
        {
5315
          if (!unwind->reg_saved[reg])
5316
            continue;
5317
 
5318
          unwind->saved_reg_count++;
5319
          /* Encoding uses 4 bits per word, so size of unwinding opcode data
5320
             limits the save area size.  The exact cap will be figured out
5321
             later due to overflow, the 0x800 here is just a quick sanity
5322
             check to weed out obviously excessive offsets.  */
5323
          if (unwind->reg_offset[reg] > 0 || unwind->reg_offset[reg] < -0x800
5324
              || (unwind->reg_offset[reg] & 3) != 0)
5325
            {
5326
              as_bad (_("stack frame layout too complex for unwinder"));
5327
              return;
5328
            }
5329
 
5330
          if (unwind->reg_offset[reg] < save_offset)
5331
            save_offset = unwind->reg_offset[reg] - 4;
5332
        }
5333
    }
5334
 
5335
  /* Align to 8-byte boundary (stack grows towards negative offsets).  */
5336
  save_offset &= ~7;
5337
 
5338
  if (unwind->cfa_reg == 31 && !reg_saved_mask)
5339
    {
5340
      cfa_offset += save_offset;
5341
      if (cfa_offset < 0)
5342
        {
5343
          as_bad (_("unwound frame has negative size"));
5344
          return;
5345
        }
5346
    }
5347
 
5348
  unwind->safe_mask = safe_mask;
5349
  unwind->compact_mask = compact_mask;
5350
  unwind->reg_saved_mask = reg_saved_mask;
5351
  unwind->cfa_offset = cfa_offset;
5352
  unwind->function_start = fde->start_address;
5353
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.