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

Subversion Repositories open8_urisc

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

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

Line No. Rev Author Line
1 148 khays
/* tc-tilegx.c -- Assemble for a Tile-Gx chip.
2
   Copyright 2011 Free Software Foundation, Inc.
3
 
4
   This file is part of GAS, the GNU Assembler.
5
 
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3 of the License, or
9
   (at your option) any later version.
10
 
11
   This program is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
 
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19
   MA 02110-1301, USA.  */
20
 
21
#include "as.h"
22
#include "struc-symbol.h"
23
#include "subsegs.h"
24
 
25
#include "elf/tilegx.h"
26
#include "opcode/tilegx.h"
27
 
28
#include "dwarf2dbg.h"
29
#include "dw2gencfi.h"
30
 
31
#include "safe-ctype.h"
32
 
33
 
34
/* Special registers.  */
35
#define TREG_IDN0     57
36
#define TREG_IDN1     58
37
#define TREG_UDN0     59
38
#define TREG_UDN1     60
39
#define TREG_UDN2     61
40
#define TREG_UDN3     62
41
#define TREG_ZERO     63
42
 
43
 
44
/* Generic assembler global variables which must be defined by all
45
   targets.  */
46
 
47
/* The dwarf2 data alignment, adjusted for 32 or 64 bit.  */
48
int tilegx_cie_data_alignment;
49
 
50
/* Characters which always start a comment.  */
51
const char comment_chars[] = "#";
52
 
53
/* Characters which start a comment at the beginning of a line.  */
54
const char line_comment_chars[] = "#";
55
 
56
/* Characters which may be used to separate multiple commands on a
57
   single line.  */
58
const char line_separator_chars[] = ";";
59
 
60
/* Characters which are used to indicate an exponent in a floating
61
   point number.  */
62
const char EXP_CHARS[] = "eE";
63
 
64
/* Characters which mean that a number is a floating point constant,
65
   as in 0d1.0.  */
66
const char FLT_CHARS[] = "rRsSfFdDxXpP";
67
 
68
/* Either 32 or 64.  */
69
static int tilegx_arch_size = 64;
70
 
71
 
72
const char *
73
tilegx_target_format (void)
74
{
75
  return tilegx_arch_size == 64 ? "elf64-tilegx" : "elf32-tilegx";
76
}
77
 
78
 
79
#define OPTION_32 (OPTION_MD_BASE + 0)
80
#define OPTION_64 (OPTION_MD_BASE + 1)
81
 
82
const char *md_shortopts = "VQ:";
83
 
84
struct option md_longopts[] =
85
{
86
  {"32", no_argument, NULL, OPTION_32},
87
  {"64", no_argument, NULL, OPTION_64},
88
  {NULL, no_argument, NULL, 0}
89
};
90
 
91
size_t md_longopts_size = sizeof (md_longopts);
92
 
93
int
94
md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
95
{
96
  switch (c)
97
    {
98
      /* -Qy, -Qn: SVR4 arguments controlling whether a .comment section
99
         should be emitted or not.  FIXME: Not implemented.  */
100
    case 'Q':
101
      break;
102
 
103
      /* -V: SVR4 argument to print version ID.  */
104
    case 'V':
105
      print_version_id ();
106
      break;
107
 
108
    case OPTION_32:
109
      tilegx_arch_size = 32;
110
      break;
111
 
112
    case OPTION_64:
113
      tilegx_arch_size = 64;
114
      break;
115
 
116
    default:
117
      return 0;
118
    }
119
 
120
  return 1;
121
}
122
 
123
void
124
md_show_usage (FILE *stream)
125
{
126
  fprintf (stream, _("\
127
  -Q                      ignored\n\
128
  -V                      print assembler version number\n\
129
  --32/--64               generate 32bit/64bit code\n"));
130
}
131
 
132
 
133
/* Extra expression types.  */
134
 
135
#define O_hw0                   O_md1
136
#define O_hw1                   O_md2
137
#define O_hw2                   O_md3
138
#define O_hw3                   O_md4
139
#define O_hw0_last              O_md5
140
#define O_hw1_last              O_md6
141
#define O_hw2_last              O_md7
142
#define O_hw0_got               O_md8
143
#define O_hw1_got               O_md9
144
#define O_hw2_got               O_md10
145
#define O_hw3_got               O_md11
146
#define O_hw0_last_got          O_md12
147
#define O_hw1_last_got          O_md13
148
#define O_hw2_last_got          O_md14
149
#define O_plt                   O_md15
150
#define O_hw0_tls_gd            O_md16
151
#define O_hw1_tls_gd            O_md17
152
#define O_hw2_tls_gd            O_md18
153
#define O_hw3_tls_gd            O_md19
154
#define O_hw0_last_tls_gd       O_md20
155
#define O_hw1_last_tls_gd       O_md21
156
#define O_hw2_last_tls_gd       O_md22
157
#define O_hw0_tls_ie            O_md23
158
#define O_hw1_tls_ie            O_md24
159
#define O_hw2_tls_ie            O_md25
160
#define O_hw3_tls_ie            O_md26
161
#define O_hw0_last_tls_ie       O_md27
162
#define O_hw1_last_tls_ie       O_md28
163
#define O_hw2_last_tls_ie       O_md29
164
 
165
static struct hash_control *special_operator_hash;
166
 
167
/* Hash tables for instruction mnemonic lookup.  */
168
static struct hash_control *op_hash;
169
 
170
/* Hash table for spr lookup.  */
171
static struct hash_control *spr_hash;
172
 
173
/* True temporarily while parsing an SPR expression. This changes the
174
 * namespace to include SPR names.  */
175
static int parsing_spr;
176
 
177
/* Are we currently inside `{ ... }'?  */
178
static int inside_bundle;
179
 
180
struct tilegx_instruction
181
{
182
  const struct tilegx_opcode *opcode;
183
  tilegx_pipeline pipe;
184
  expressionS operand_values[TILEGX_MAX_OPERANDS];
185
};
186
 
187
/* This keeps track of the current bundle being built up.  */
188
static struct tilegx_instruction current_bundle[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE];
189
 
190
/* Index in current_bundle for the next instruction to parse.  */
191
static int current_bundle_index;
192
 
193
/* Allow 'r63' in addition to 'zero', etc. Normally we disallow this as
194
   'zero' is not a real register, so using it accidentally would be a
195
   nasty bug. For other registers, such as 'sp', code using multiple names
196
   for the same physical register is excessively confusing.
197
 
198
   The '.require_canonical_reg_names' pseudo-op turns this error on,
199
   and the '.no_require_canonical_reg_names' pseudo-op turns this off.
200
   By default the error is on.  */
201
static int require_canonical_reg_names;
202
 
203
/* Allow bundles that do undefined or suspicious things like write
204
   two different values to the same register at the same time.
205
 
206
   The '.no_allow_suspicious_bundles' pseudo-op turns this error on,
207
   and the '.allow_suspicious_bundles' pseudo-op turns this off.  */
208
static int allow_suspicious_bundles;
209
 
210
 
211
/* A hash table of main processor registers, mapping each register name
212
   to its index.
213
 
214
   Furthermore, if the register number is greater than the number
215
   of registers for that processor, the user used an illegal alias
216
   for that register (e.g. r63 instead of zero), so we should generate
217
   a warning. The attempted register number can be found by clearing
218
   NONCANONICAL_REG_NAME_FLAG.  */
219
static struct hash_control *main_reg_hash;
220
 
221
 
222
/* We cannot unambiguously store a 0 in a hash table and look it up,
223
   so we OR in this flag to every canonical register.  */
224
#define CANONICAL_REG_NAME_FLAG    0x1000
225
 
226
/* By default we disallow register aliases like r63, but we record
227
   them in the hash table in case the .no_require_canonical_reg_names
228
   directive is used. Noncanonical names have this value added to them.  */
229
#define NONCANONICAL_REG_NAME_FLAG 0x2000
230
 
231
/* Discards flags for register hash table entries and returns the
232
   reg number.  */
233
#define EXTRACT_REGNO(p) ((p) & 63)
234
 
235
/* This function is called once, at assembler startup time.  It should
236
   set up all the tables, etc., that the MD part of the assembler will
237
   need.  */
238
 
239
void
240
md_begin (void)
241
{
242
  const struct tilegx_opcode *op;
243
  int i;
244
 
245
  /* Guarantee text section is aligned.  */
246
  bfd_set_section_alignment (stdoutput, text_section,
247
                             TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES);
248
 
249
  require_canonical_reg_names = 1;
250
  allow_suspicious_bundles = 0;
251
  current_bundle_index = 0;
252
  inside_bundle = 0;
253
 
254
  tilegx_cie_data_alignment = (tilegx_arch_size == 64 ? -8 : -4);
255
 
256
  /* Initialize special operator hash table.  */
257
  special_operator_hash = hash_new ();
258
#define INSERT_SPECIAL_OP(name)                                 \
259
  hash_insert (special_operator_hash, #name, (void *)O_##name)
260
 
261
  INSERT_SPECIAL_OP (hw0);
262
  INSERT_SPECIAL_OP (hw1);
263
  INSERT_SPECIAL_OP (hw2);
264
  INSERT_SPECIAL_OP (hw3);
265
  INSERT_SPECIAL_OP (hw0_last);
266
  INSERT_SPECIAL_OP (hw1_last);
267
  INSERT_SPECIAL_OP (hw2_last);
268
  /* hw3_last is a convenience alias for the equivalent hw3.  */
269
  hash_insert (special_operator_hash, "hw3_last", (void*)O_hw3);
270
  INSERT_SPECIAL_OP (hw0_got);
271
  INSERT_SPECIAL_OP (hw1_got);
272
  INSERT_SPECIAL_OP (hw2_got);
273
  INSERT_SPECIAL_OP (hw3_got);
274
  INSERT_SPECIAL_OP (hw0_last_got);
275
  INSERT_SPECIAL_OP (hw1_last_got);
276
  INSERT_SPECIAL_OP (hw2_last_got);
277
  INSERT_SPECIAL_OP(plt);
278
  INSERT_SPECIAL_OP (hw0_tls_gd);
279
  INSERT_SPECIAL_OP (hw1_tls_gd);
280
  INSERT_SPECIAL_OP (hw2_tls_gd);
281
  INSERT_SPECIAL_OP (hw3_tls_gd);
282
  INSERT_SPECIAL_OP (hw0_last_tls_gd);
283
  INSERT_SPECIAL_OP (hw1_last_tls_gd);
284
  INSERT_SPECIAL_OP (hw2_last_tls_gd);
285
  INSERT_SPECIAL_OP (hw0_tls_ie);
286
  INSERT_SPECIAL_OP (hw1_tls_ie);
287
  INSERT_SPECIAL_OP (hw2_tls_ie);
288
  INSERT_SPECIAL_OP (hw3_tls_ie);
289
  INSERT_SPECIAL_OP (hw0_last_tls_ie);
290
  INSERT_SPECIAL_OP (hw1_last_tls_ie);
291
  INSERT_SPECIAL_OP (hw2_last_tls_ie);
292
#undef INSERT_SPECIAL_OP
293
 
294
  /* Initialize op_hash hash table.  */
295
  op_hash = hash_new ();
296
  for (op = &tilegx_opcodes[0]; op->name != NULL; op++)
297
    {
298
      const char *hash_err = hash_insert (op_hash, op->name, (void *)op);
299
      if (hash_err != NULL)
300
        as_fatal (_("Internal Error:  Can't hash %s: %s"), op->name, hash_err);
301
    }
302
 
303
  /* Initialize the spr hash table.  */
304
  parsing_spr = 0;
305
  spr_hash = hash_new ();
306
  for (i = 0; i < tilegx_num_sprs; i++)
307
    hash_insert (spr_hash, tilegx_sprs[i].name,
308
                 (void *) &tilegx_sprs[i]);
309
 
310
  /* Set up the main_reg_hash table. We use this instead of
311
     creating a symbol in the register section to avoid ambiguities
312
     with labels that have the same names as registers.  */
313
  main_reg_hash = hash_new ();
314
  for (i = 0; i < TILEGX_NUM_REGISTERS; i++)
315
    {
316
      char buf[64];
317
 
318
      hash_insert (main_reg_hash, tilegx_register_names[i],
319
                   (void *) (long) (i | CANONICAL_REG_NAME_FLAG));
320
 
321
      /* See if we should insert a noncanonical alias, like r63.  */
322
      sprintf (buf, "r%d", i);
323
      if (strcmp (buf, tilegx_register_names[i]) != 0)
324
        hash_insert (main_reg_hash, xstrdup (buf),
325
                     (void *) (long) (i | NONCANONICAL_REG_NAME_FLAG));
326
    }
327
}
328
 
329
#define BUNDLE_TEMPLATE_MASK(p0, p1, p2) \
330
  ((p0) | ((p1) << 8) | ((p2) << 16))
331
#define BUNDLE_TEMPLATE(p0, p1, p2) \
332
  { { (p0), (p1), (p2) }, \
333
     BUNDLE_TEMPLATE_MASK(1 << (p0), 1 << (p1), (1 << (p2))) \
334
  }
335
 
336
#define NO_PIPELINE TILEGX_NUM_PIPELINE_ENCODINGS
337
 
338
struct bundle_template
339
{
340
  tilegx_pipeline pipe[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE];
341
  unsigned int pipe_mask;
342
};
343
 
344
static const struct bundle_template bundle_templates[] =
345
{
346
  /* In Y format we must always have something in Y2, since it has
347
     no fnop, so this conveys that Y2 must always be used.  */
348
  BUNDLE_TEMPLATE(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2, NO_PIPELINE),
349
  BUNDLE_TEMPLATE(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2, NO_PIPELINE),
350
  BUNDLE_TEMPLATE(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0, NO_PIPELINE),
351
  BUNDLE_TEMPLATE(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1, NO_PIPELINE),
352
 
353
  /* Y format has three instructions.  */
354
  BUNDLE_TEMPLATE(TILEGX_PIPELINE_Y0,TILEGX_PIPELINE_Y1,TILEGX_PIPELINE_Y2),
355
  BUNDLE_TEMPLATE(TILEGX_PIPELINE_Y0,TILEGX_PIPELINE_Y2,TILEGX_PIPELINE_Y1),
356
  BUNDLE_TEMPLATE(TILEGX_PIPELINE_Y1,TILEGX_PIPELINE_Y0,TILEGX_PIPELINE_Y2),
357
  BUNDLE_TEMPLATE(TILEGX_PIPELINE_Y1,TILEGX_PIPELINE_Y2,TILEGX_PIPELINE_Y0),
358
  BUNDLE_TEMPLATE(TILEGX_PIPELINE_Y2,TILEGX_PIPELINE_Y0,TILEGX_PIPELINE_Y1),
359
  BUNDLE_TEMPLATE(TILEGX_PIPELINE_Y2,TILEGX_PIPELINE_Y1,TILEGX_PIPELINE_Y0),
360
 
361
  /* X format has only two instructions.  */
362
  BUNDLE_TEMPLATE(TILEGX_PIPELINE_X0, TILEGX_PIPELINE_X1, NO_PIPELINE),
363
  BUNDLE_TEMPLATE(TILEGX_PIPELINE_X1, TILEGX_PIPELINE_X0, NO_PIPELINE)
364
};
365
 
366
 
367
static void
368
prepend_nop_to_bundle (tilegx_mnemonic mnemonic)
369
{
370
  memmove (&current_bundle[1], &current_bundle[0],
371
           current_bundle_index * sizeof current_bundle[0]);
372
  current_bundle[0].opcode = &tilegx_opcodes[mnemonic];
373
  ++current_bundle_index;
374
}
375
 
376
static tilegx_bundle_bits
377
insert_operand (tilegx_bundle_bits bits,
378
                const struct tilegx_operand *operand,
379
                int operand_value,
380
                char *file,
381
                unsigned lineno)
382
{
383
  /* Range-check the immediate.  */
384
  int num_bits = operand->num_bits;
385
 
386
  operand_value >>= operand->rightshift;
387
 
388
  if (bfd_check_overflow (operand->is_signed
389
                          ? complain_overflow_signed
390
                          : complain_overflow_unsigned,
391
                          num_bits,
392
                          0,
393
                          bfd_arch_bits_per_address (stdoutput),
394
                          operand_value)
395
      != bfd_reloc_ok)
396
    {
397
      offsetT min, max;
398
      if (operand->is_signed)
399
        {
400
          min = -(1 << (num_bits - 1));
401
          max = (1 << (num_bits - 1)) - 1;
402
        }
403
      else
404
        {
405
          min = 0;
406
          max = (1 << num_bits) - 1;
407
        }
408
      as_bad_value_out_of_range (_("operand"), operand_value, min, max,
409
                                 file, lineno);
410
    }
411
 
412
  /* Write out the bits for the immediate.  */
413
  return bits | operand->insert (operand_value);
414
}
415
 
416
 
417
static int
418
apply_special_operator (operatorT op, offsetT num, char *file, unsigned lineno)
419
{
420
  int ret;
421
  int check_shift = -1;
422
 
423
  switch (op)
424
    {
425
    case O_hw0_last_tls_gd:
426
    case O_hw0_last_tls_ie:
427
    case O_hw0_last:
428
      check_shift = 0;
429
      /* Fall through.  */
430
    case O_hw0_tls_gd:
431
    case O_hw0_tls_ie:
432
    case O_hw0:
433
      ret = (signed short)num;
434
      break;
435
 
436
    case O_hw1_last_tls_gd:
437
    case O_hw1_last_tls_ie:
438
    case O_hw1_last:
439
      check_shift = 16;
440
      /* Fall through.  */
441
    case O_hw1_tls_gd:
442
    case O_hw1_tls_ie:
443
    case O_hw1:
444
      ret = (signed short)(num >> 16);
445
      break;
446
 
447
    case O_hw2_last_tls_gd:
448
    case O_hw2_last_tls_ie:
449
    case O_hw2_last:
450
      check_shift = 32;
451
      /* Fall through.  */
452
    case O_hw2_tls_gd:
453
    case O_hw2_tls_ie:
454
    case O_hw2:
455
      ret = (signed short)(num >> 32);
456
      break;
457
 
458
    case O_hw3_tls_gd:
459
    case O_hw3_tls_ie:
460
    case O_hw3:
461
      ret = (signed short)(num >> 48);
462
      break;
463
 
464
    default:
465
      abort ();
466
      break;
467
    }
468
 
469
  if (check_shift >= 0 && ret != (num >> check_shift))
470
    {
471
      as_bad_value_out_of_range (_("operand"), num,
472
                                 ~0ULL << (check_shift + 16 - 1),
473
                                 ~0ULL >> (64 - (check_shift + 16 - 1)),
474
                                 file, lineno);
475
    }
476
 
477
  return ret;
478
}
479
 
480
static tilegx_bundle_bits
481
emit_tilegx_instruction (tilegx_bundle_bits bits,
482
                         int num_operands,
483
                         const unsigned char *operands,
484
                         expressionS *operand_values,
485
                         char *bundle_start)
486
{
487
  int i;
488
 
489
  for (i = 0; i < num_operands; i++)
490
    {
491
      const struct tilegx_operand *operand =
492
        &tilegx_operands[operands[i]];
493
      expressionS *operand_exp = &operand_values[i];
494
      int is_pc_relative = operand->is_pc_relative;
495
 
496
      if (operand_exp->X_op == O_register
497
          || (operand_exp->X_op == O_constant && !is_pc_relative))
498
        {
499
          /* We know what the bits are right now, so insert them.  */
500
          bits = insert_operand (bits, operand, operand_exp->X_add_number,
501
                                 NULL, 0);
502
        }
503
      else
504
        {
505
          bfd_reloc_code_real_type reloc = operand->default_reloc;
506
          expressionS subexp;
507
          int die = 0, use_subexp = 0, require_symbol = 0;
508
          fixS *fixP;
509
 
510
          /* Take an expression like hw0(x) and turn it into x with
511
             a different reloc type.  */
512
          switch (operand_exp->X_op)
513
            {
514
#define HANDLE_OP16(suffix)                                     \
515
              switch (reloc)                                    \
516
                {                                               \
517
                case BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST:        \
518
                  reloc = BFD_RELOC_TILEGX_IMM16_X0_##suffix;   \
519
                  break;                                        \
520
                case BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST:        \
521
                  reloc = BFD_RELOC_TILEGX_IMM16_X1_##suffix;   \
522
                  break;                                        \
523
                default:                                        \
524
                  die = 1;                                      \
525
                  break;                                        \
526
                }                                               \
527
              use_subexp = 1
528
 
529
            case O_hw0:
530
              HANDLE_OP16 (HW0);
531
              break;
532
 
533
            case O_hw1:
534
              HANDLE_OP16 (HW1);
535
              break;
536
 
537
            case O_hw2:
538
              HANDLE_OP16 (HW2);
539
              break;
540
 
541
            case O_hw3:
542
              HANDLE_OP16 (HW3);
543
              break;
544
 
545
            case O_hw0_last:
546
              HANDLE_OP16 (HW0_LAST);
547
              break;
548
 
549
            case O_hw1_last:
550
              HANDLE_OP16 (HW1_LAST);
551
              break;
552
 
553
            case O_hw2_last:
554
              HANDLE_OP16 (HW2_LAST);
555
              break;
556
 
557
            case O_hw0_got:
558
              HANDLE_OP16 (HW0_GOT);
559
              require_symbol = 1;
560
              break;
561
 
562
            case O_hw1_got:
563
              HANDLE_OP16 (HW1_GOT);
564
              require_symbol = 1;
565
              break;
566
 
567
            case O_hw2_got:
568
              HANDLE_OP16 (HW2_GOT);
569
              require_symbol = 1;
570
              break;
571
 
572
            case O_hw3_got:
573
              HANDLE_OP16 (HW3_GOT);
574
              require_symbol = 1;
575
              break;
576
 
577
            case O_hw0_last_got:
578
              HANDLE_OP16 (HW0_LAST_GOT);
579
              require_symbol = 1;
580
              break;
581
 
582
            case O_hw1_last_got:
583
              HANDLE_OP16 (HW1_LAST_GOT);
584
              require_symbol = 1;
585
              break;
586
 
587
            case O_hw2_last_got:
588
              HANDLE_OP16 (HW2_LAST_GOT);
589
              require_symbol = 1;
590
              break;
591
 
592
            case O_hw0_tls_gd:
593
              HANDLE_OP16 (HW0_TLS_GD);
594
              require_symbol = 1;
595
              break;
596
 
597
            case O_hw1_tls_gd:
598
              HANDLE_OP16 (HW1_TLS_GD);
599
              require_symbol = 1;
600
              break;
601
 
602
            case O_hw2_tls_gd:
603
              HANDLE_OP16 (HW2_TLS_GD);
604
              require_symbol = 1;
605
              break;
606
 
607
            case O_hw3_tls_gd:
608
              HANDLE_OP16 (HW3_TLS_GD);
609
              require_symbol = 1;
610
              break;
611
 
612
            case O_hw0_last_tls_gd:
613
              HANDLE_OP16 (HW0_LAST_TLS_GD);
614
              require_symbol = 1;
615
              break;
616
 
617
            case O_hw1_last_tls_gd:
618
              HANDLE_OP16 (HW1_LAST_TLS_GD);
619
              require_symbol = 1;
620
              break;
621
 
622
            case O_hw2_last_tls_gd:
623
              HANDLE_OP16 (HW2_LAST_TLS_GD);
624
              require_symbol = 1;
625
              break;
626
 
627
            case O_hw0_tls_ie:
628
              HANDLE_OP16 (HW0_TLS_IE);
629
              require_symbol = 1;
630
              break;
631
 
632
            case O_hw1_tls_ie:
633
              HANDLE_OP16 (HW1_TLS_IE);
634
              require_symbol = 1;
635
              break;
636
 
637
            case O_hw2_tls_ie:
638
              HANDLE_OP16 (HW2_TLS_IE);
639
              require_symbol = 1;
640
              break;
641
 
642
            case O_hw3_tls_ie:
643
              HANDLE_OP16 (HW3_TLS_IE);
644
              require_symbol = 1;
645
              break;
646
 
647
            case O_hw0_last_tls_ie:
648
              HANDLE_OP16 (HW0_LAST_TLS_IE);
649
              require_symbol = 1;
650
              break;
651
 
652
            case O_hw1_last_tls_ie:
653
              HANDLE_OP16 (HW1_LAST_TLS_IE);
654
              require_symbol = 1;
655
              break;
656
 
657
            case O_hw2_last_tls_ie:
658
              HANDLE_OP16 (HW2_LAST_TLS_IE);
659
              require_symbol = 1;
660
              break;
661
 
662
#undef HANDLE_OP16
663
 
664
            case O_plt:
665
              switch (reloc)
666
                {
667
                case BFD_RELOC_TILEGX_JUMPOFF_X1:
668
                  reloc = BFD_RELOC_TILEGX_JUMPOFF_X1_PLT;
669
                  break;
670
                default:
671
                  die = 1;
672
                  break;
673
                }
674
              use_subexp = 1;
675
              require_symbol = 1;
676
              break;
677
 
678
            default:
679
              /* Do nothing.  */
680
              break;
681
            }
682
 
683
          if (die)
684
            {
685
              as_bad (_("Invalid operator for operand."));
686
            }
687
          else if (use_subexp)
688
            {
689
              /* Now that we've changed the reloc, change ha16(x) into x,
690
                 etc.  */
691
 
692
              if (operand_exp->X_add_symbol->sy_value.X_md)
693
                {
694
                  if (require_symbol)
695
                    {
696
                      as_bad (_("Operator may only be applied to symbols."));
697
                    }
698
 
699
                  /* HACK: We used X_md to mark this symbol as a fake wrapper
700
                     around a real expression. To unwrap it, we just grab its
701
                     value here.  */
702
                  operand_exp = &operand_exp->X_add_symbol->sy_value;
703
                }
704
              else
705
                {
706
                  /* The value of this expression is an actual symbol, so
707
                     turn that into an expression.  */
708
                  memset (&subexp, 0, sizeof subexp);
709
                  subexp.X_op = O_symbol;
710
                  subexp.X_add_symbol = operand_exp->X_add_symbol;
711
                  operand_exp = &subexp;
712
                }
713
            }
714
 
715
          /* Create a fixup to handle this later.  */
716
          fixP = fix_new_exp (frag_now,
717
                              bundle_start - frag_now->fr_literal,
718
                              (operand->num_bits + 7) >> 3,
719
                              operand_exp,
720
                              is_pc_relative,
721
                              reloc);
722
          fixP->tc_fix_data = operand;
723
 
724
          /* Don't do overflow checking if we are applying a function like
725
             ha16.  */
726
          fixP->fx_no_overflow |= use_subexp;
727
        }
728
    }
729
  return bits;
730
}
731
 
732
 
733
/* Detects and complains if two instructions in current_bundle write
734
   to the same register, either implicitly or explicitly, or if a
735
   read-only register is written.  */
736
static void
737
check_illegal_reg_writes (void)
738
{
739
  BFD_HOST_U_64_BIT all_regs_written = 0;
740
  int j;
741
 
742
  for (j = 0; j < current_bundle_index; j++)
743
    {
744
      const struct tilegx_instruction *instr = &current_bundle[j];
745
      int k;
746
      BFD_HOST_U_64_BIT regs =
747
        ((BFD_HOST_U_64_BIT)1) << instr->opcode->implicitly_written_register;
748
      BFD_HOST_U_64_BIT conflict;
749
 
750
      for (k = 0; k < instr->opcode->num_operands; k++)
751
        {
752
          const struct tilegx_operand *operand =
753
            &tilegx_operands[instr->opcode->operands[instr->pipe][k]];
754
 
755
          if (operand->is_dest_reg)
756
            {
757
              int regno = instr->operand_values[k].X_add_number;
758
              BFD_HOST_U_64_BIT mask = ((BFD_HOST_U_64_BIT)1) << regno;
759
 
760
              if ((mask & (  (((BFD_HOST_U_64_BIT)1) << TREG_IDN1)
761
                             | (((BFD_HOST_U_64_BIT)1) << TREG_UDN1)
762
                             | (((BFD_HOST_U_64_BIT)1) << TREG_UDN2)
763
                             | (((BFD_HOST_U_64_BIT)1) << TREG_UDN3))) != 0
764
                  && !allow_suspicious_bundles)
765
                {
766
                  as_bad (_("Writes to register '%s' are not allowed."),
767
                          tilegx_register_names[regno]);
768
                }
769
 
770
              regs |= mask;
771
            }
772
        }
773
 
774
      /* Writing to the zero register doesn't count.  */
775
      regs &= ~(((BFD_HOST_U_64_BIT)1) << TREG_ZERO);
776
 
777
      conflict = all_regs_written & regs;
778
      if (conflict != 0 && !allow_suspicious_bundles)
779
        {
780
          /* Find which register caused the conflict.  */
781
          const char *conflicting_reg_name = "???";
782
          int i;
783
 
784
          for (i = 0; i < TILEGX_NUM_REGISTERS; i++)
785
            {
786
              if (((conflict >> i) & 1) != 0)
787
                {
788
                  conflicting_reg_name = tilegx_register_names[i];
789
                  break;
790
                }
791
            }
792
 
793
          as_bad (_("Two instructions in the same bundle both write "
794
                    "to register %s, which is not allowed."),
795
                  conflicting_reg_name);
796
        }
797
 
798
      all_regs_written |= regs;
799
    }
800
}
801
 
802
 
803
static void
804
tilegx_flush_bundle (void)
805
{
806
  unsigned i;
807
  int j;
808
  addressT addr_mod;
809
  unsigned compatible_pipes;
810
  const struct bundle_template *match;
811
  char *f;
812
 
813
  inside_bundle = 0;
814
 
815
  switch (current_bundle_index)
816
    {
817
    case 0:
818
      /* No instructions.  */
819
      return;
820
    case 1:
821
      if (current_bundle[0].opcode->can_bundle)
822
        {
823
          /* Simplify later logic by adding an explicit fnop.  */
824
          prepend_nop_to_bundle (TILEGX_OPC_FNOP);
825
        }
826
      else
827
        {
828
          /* This instruction cannot be bundled with anything else.
829
             Prepend an explicit 'nop', rather than an 'fnop', because
830
             fnops can be replaced by later binary-processing tools while
831
             nops cannot.  */
832
          prepend_nop_to_bundle (TILEGX_OPC_NOP);
833
        }
834
      break;
835
    default:
836
      if (!allow_suspicious_bundles)
837
        {
838
          /* Make sure all instructions can be bundled with other
839
             instructions.  */
840
          const struct tilegx_opcode *cannot_bundle = NULL;
841
          bfd_boolean seen_non_nop = FALSE;
842
 
843
          for (j = 0; j < current_bundle_index; j++)
844
            {
845
              const struct tilegx_opcode *op = current_bundle[j].opcode;
846
 
847
              if (!op->can_bundle && cannot_bundle == NULL)
848
                cannot_bundle = op;
849
              else if (op->mnemonic != TILEGX_OPC_NOP
850
                       && op->mnemonic != TILEGX_OPC_INFO
851
                       && op->mnemonic != TILEGX_OPC_INFOL)
852
                seen_non_nop = TRUE;
853
            }
854
 
855
          if (cannot_bundle != NULL && seen_non_nop)
856
            {
857
              current_bundle_index = 0;
858
              as_bad (_("'%s' may not be bundled with other instructions."),
859
                      cannot_bundle->name);
860
              return;
861
            }
862
        }
863
      break;
864
    }
865
 
866
  compatible_pipes =
867
    BUNDLE_TEMPLATE_MASK(current_bundle[0].opcode->pipes,
868
                         current_bundle[1].opcode->pipes,
869
                         (current_bundle_index == 3
870
                          ? current_bundle[2].opcode->pipes
871
                          : (1 << NO_PIPELINE)));
872
 
873
  /* Find a template that works, if any.  */
874
  match = NULL;
875
  for (i = 0; i < sizeof bundle_templates / sizeof bundle_templates[0]; i++)
876
    {
877
      const struct bundle_template *b = &bundle_templates[i];
878
      if ((b->pipe_mask & compatible_pipes) == b->pipe_mask)
879
        {
880
          match = b;
881
          break;
882
        }
883
    }
884
 
885
  if (match == NULL)
886
    {
887
      current_bundle_index = 0;
888
      as_bad (_("Invalid combination of instructions for bundle."));
889
      return;
890
    }
891
 
892
  /* If the section seems to have no alignment set yet, go ahead and
893
     make it large enough to hold code.  */
894
  if (bfd_get_section_alignment (stdoutput, now_seg) == 0)
895
    bfd_set_section_alignment (stdoutput, now_seg,
896
                               TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES);
897
 
898
  for (j = 0; j < current_bundle_index; j++)
899
    current_bundle[j].pipe = match->pipe[j];
900
 
901
  if (current_bundle_index == 2 && !tilegx_is_x_pipeline (match->pipe[0]))
902
    {
903
      /* We are in Y mode with only two instructions, so add an FNOP.  */
904
      prepend_nop_to_bundle (TILEGX_OPC_FNOP);
905
 
906
      /* Figure out what pipe the fnop must be in via arithmetic.
907
       * p0 + p1 + p2 must sum to the sum of TILEGX_PIPELINE_Y[012].  */
908
      current_bundle[0].pipe =
909
        (tilegx_pipeline)((TILEGX_PIPELINE_Y0
910
                           + TILEGX_PIPELINE_Y1
911
                           + TILEGX_PIPELINE_Y2) -
912
                          (current_bundle[1].pipe + current_bundle[2].pipe));
913
    }
914
 
915
  check_illegal_reg_writes ();
916
 
917
  f = frag_more (TILEGX_BUNDLE_SIZE_IN_BYTES);
918
 
919
  /* Check to see if this bundle is at an offset that is a multiple of 8-bytes
920
     from the start of the frag.  */
921
  addr_mod = frag_now_fix () & (TILEGX_BUNDLE_ALIGNMENT_IN_BYTES - 1);
922
  if (frag_now->has_code && frag_now->insn_addr != addr_mod)
923
    as_bad (_("instruction address is not a multiple of 8"));
924
  frag_now->insn_addr = addr_mod;
925
  frag_now->has_code = 1;
926
 
927
  tilegx_bundle_bits bits = 0;
928
  for (j = 0; j < current_bundle_index; j++)
929
    {
930
      struct tilegx_instruction *instr = &current_bundle[j];
931
      tilegx_pipeline pipeline = instr->pipe;
932
      const struct tilegx_opcode *opcode = instr->opcode;
933
 
934
      bits |= emit_tilegx_instruction (opcode->fixed_bit_values[pipeline],
935
                                       opcode->num_operands,
936
                                       &opcode->operands[pipeline][0],
937
                                       instr->operand_values,
938
                                       f);
939
    }
940
 
941
  number_to_chars_littleendian (f, bits, 8);
942
  current_bundle_index = 0;
943
 
944
  /* Emit DWARF2 debugging information.  */
945
  dwarf2_emit_insn (TILEGX_BUNDLE_SIZE_IN_BYTES);
946
}
947
 
948
 
949
/* Extend the expression parser to handle hw0(label), etc.
950
   as well as SPR names when in the context of parsing an SPR.  */
951
 
952
int
953
tilegx_parse_name (char *name, expressionS *e, char *nextcharP)
954
{
955
  operatorT op = O_illegal;
956
 
957
  if (parsing_spr)
958
    {
959
      void* val = hash_find (spr_hash, name);
960
      if (val == NULL)
961
        return 0;
962
 
963
      memset (e, 0, sizeof *e);
964
      e->X_op = O_constant;
965
      e->X_add_number = ((const struct tilegx_spr *)val)->number;
966
      return 1;
967
    }
968
 
969
  if (*nextcharP != '(')
970
    {
971
      /* hw0, etc. not followed by a paren is just a label with that name.  */
972
      return 0;
973
    }
974
  else
975
    {
976
      /* Look up the operator in our table.  */
977
      void* val = hash_find (special_operator_hash, name);
978
      if (val == 0)
979
        return 0;
980
      op = (operatorT)(long)val;
981
    }
982
 
983
  /* Restore old '(' and skip it.  */
984
  *input_line_pointer = '(';
985
  ++input_line_pointer;
986
 
987
  expression (e);
988
 
989
  if (*input_line_pointer != ')')
990
    {
991
      as_bad (_("Missing ')'"));
992
      *nextcharP = *input_line_pointer;
993
      return 0;
994
    }
995
  /* Skip ')'.  */
996
  ++input_line_pointer;
997
 
998
  if (e->X_op == O_register || e->X_op == O_absent)
999
    {
1000
      as_bad (_("Invalid expression."));
1001
      e->X_op = O_constant;
1002
      e->X_add_number = 0;
1003
    }
1004
  else
1005
    {
1006
      /* Wrap subexpression with a unary operator.  */
1007
      symbolS *sym = make_expr_symbol (e);
1008
 
1009
      if (sym != e->X_add_symbol)
1010
        {
1011
          /* HACK: mark this symbol as a temporary wrapper around a proper
1012
             expression, so we can unwrap it later once we have communicated
1013
             the relocation type.  */
1014
          sym->sy_value.X_md = 1;
1015
        }
1016
 
1017
      memset (e, 0, sizeof *e);
1018
      e->X_op = op;
1019
      e->X_add_symbol = sym;
1020
      e->X_add_number = 0;
1021
    }
1022
 
1023
  *nextcharP = *input_line_pointer;
1024
  return 1;
1025
}
1026
 
1027
 
1028
/* Parses an expression which must be a register name.  */
1029
 
1030
static void
1031
parse_reg_expression (expressionS* expression)
1032
{
1033
  /* Zero everything to make sure we don't miss any flags.  */
1034
  memset (expression, 0, sizeof *expression);
1035
 
1036
  char* regname = input_line_pointer;
1037
  char terminating_char = get_symbol_end ();
1038
 
1039
  void* pval = hash_find (main_reg_hash, regname);
1040
 
1041
  if (pval == NULL)
1042
    {
1043
      as_bad (_("Expected register, got '%s'."), regname);
1044
    }
1045
 
1046
  int regno_and_flags = (int)(size_t)pval;
1047
  int regno = EXTRACT_REGNO(regno_and_flags);
1048
 
1049
  if ((regno_and_flags & NONCANONICAL_REG_NAME_FLAG)
1050
      && require_canonical_reg_names)
1051
    {
1052
      as_warn (_("Found use of non-canonical register name %s; "
1053
                 "use %s instead."),
1054
               regname,
1055
               tilegx_register_names[regno]);
1056
    }
1057
 
1058
  /* Restore the old character following the register name.  */
1059
  *input_line_pointer = terminating_char;
1060
 
1061
  /* Fill in the expression fields to indicate it's a register.  */
1062
  expression->X_op = O_register;
1063
  expression->X_add_number = regno;
1064
}
1065
 
1066
 
1067
/* Parses and type-checks comma-separated operands in input_line_pointer.  */
1068
 
1069
static void
1070
parse_operands (const char *opcode_name,
1071
                const unsigned char *operands,
1072
                int num_operands,
1073
                expressionS *operand_values)
1074
{
1075
  int i;
1076
 
1077
  memset (operand_values, 0, num_operands * sizeof operand_values[0]);
1078
 
1079
  SKIP_WHITESPACE ();
1080
  for (i = 0; i < num_operands; i++)
1081
    {
1082
      tilegx_operand_type type = tilegx_operands[operands[i]].type;
1083
 
1084
      SKIP_WHITESPACE ();
1085
 
1086
      if (type == TILEGX_OP_TYPE_REGISTER)
1087
        {
1088
          parse_reg_expression (&operand_values[i]);
1089
        }
1090
      else if (*input_line_pointer == '}')
1091
        {
1092
          operand_values[i].X_op = O_absent;
1093
        }
1094
      else if (type == TILEGX_OP_TYPE_SPR)
1095
        {
1096
          /* Modify the expression parser to add SPRs to the namespace.  */
1097
          parsing_spr = 1;
1098
          expression (&operand_values[i]);
1099
          parsing_spr = 0;
1100
        }
1101
      else
1102
        {
1103
          expression (&operand_values[i]);
1104
        }
1105
 
1106
      SKIP_WHITESPACE ();
1107
 
1108
      if (i + 1 < num_operands)
1109
        {
1110
          int separator = (unsigned char)*input_line_pointer++;
1111
 
1112
          if (is_end_of_line[separator] || (separator == '}'))
1113
            {
1114
              as_bad (_("Too few operands to '%s'."), opcode_name);
1115
              return;
1116
            }
1117
          else if (separator != ',')
1118
            {
1119
              as_bad (_("Unexpected character '%c' after operand %d to %s."),
1120
                      (char)separator, i + 1, opcode_name);
1121
              return;
1122
            }
1123
        }
1124
 
1125
      /* Arbitrarily use the first valid pipe to get the operand type,
1126
         since they are all the same.  */
1127
      switch (tilegx_operands[operands[i]].type)
1128
        {
1129
        case TILEGX_OP_TYPE_REGISTER:
1130
          /* Handled in parse_reg_expression already.  */
1131
          break;
1132
        case TILEGX_OP_TYPE_SPR:
1133
          /* Fall through  */
1134
        case TILEGX_OP_TYPE_IMMEDIATE:
1135
          /* Fall through  */
1136
        case TILEGX_OP_TYPE_ADDRESS:
1137
          if (   operand_values[i].X_op == O_register
1138
                 || operand_values[i].X_op == O_illegal
1139
                 || operand_values[i].X_op == O_absent)
1140
            as_bad (_("Expected immediate expression"));
1141
          break;
1142
        default:
1143
          abort();
1144
        }
1145
    }
1146
 
1147
  if (!is_end_of_line[(unsigned char)*input_line_pointer])
1148
    {
1149
      switch (*input_line_pointer)
1150
        {
1151
        case '}':
1152
          if (!inside_bundle)
1153
            as_bad (_("Found '}' when not bundling."));
1154
          ++input_line_pointer;
1155
          inside_bundle = 0;
1156
          demand_empty_rest_of_line ();
1157
          break;
1158
 
1159
        case ',':
1160
          as_bad (_("Too many operands"));
1161
          break;
1162
 
1163
        default:
1164
          /* Use default error for unrecognized garbage.  */
1165
          demand_empty_rest_of_line ();
1166
          break;
1167
        }
1168
    }
1169
}
1170
 
1171
 
1172
/* This is the guts of the machine-dependent assembler.  STR points to a
1173
   machine dependent instruction.  This function is supposed to emit the
1174
   frags/bytes it assembles to.  */
1175
 
1176
void
1177
md_assemble (char *str)
1178
{
1179
  char old_char;
1180
  size_t opname_len;
1181
  char *old_input_line_pointer;
1182
  const struct tilegx_opcode *op;
1183
  int first_pipe;
1184
 
1185
  /* Split off the opcode and look it up.  */
1186
  opname_len = strcspn (str, " {}");
1187
  old_char = str[opname_len];
1188
  str[opname_len] = '\0';
1189
 
1190
  op = hash_find(op_hash, str);
1191
  str[opname_len] = old_char;
1192
  if (op == NULL)
1193
    {
1194
      as_bad (_("Unknown opcode `%.*s'."), (int)opname_len, str);
1195
      return;
1196
    }
1197
 
1198
  /* Prepare to parse the operands.  */
1199
  old_input_line_pointer = input_line_pointer;
1200
  input_line_pointer = str + opname_len;
1201
  SKIP_WHITESPACE ();
1202
 
1203
  if (current_bundle_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
1204
    {
1205
      as_bad (_("Too many instructions for bundle."));
1206
      tilegx_flush_bundle ();
1207
    }
1208
 
1209
  /* Make sure we have room for the upcoming bundle before we
1210
     create any fixups. Otherwise if we have to switch to a new
1211
     frag the fixup dot_value fields will be wrong.  */
1212
  frag_grow (TILEGX_BUNDLE_SIZE_IN_BYTES);
1213
 
1214
  /* Find a valid pipe for this opcode.  */
1215
  for (first_pipe = 0; (op->pipes & (1 << first_pipe)) == 0; first_pipe++)
1216
    ;
1217
 
1218
  /* Call the function that assembles this instruction.  */
1219
  current_bundle[current_bundle_index].opcode = op;
1220
  parse_operands (op->name,
1221
                  &op->operands[first_pipe][0],
1222
                  op->num_operands,
1223
                  current_bundle[current_bundle_index].operand_values);
1224
  ++current_bundle_index;
1225
 
1226
  /* Restore the saved value of input_line_pointer.  */
1227
  input_line_pointer = old_input_line_pointer;
1228
 
1229
  /* If we weren't inside curly braces, go ahead and emit
1230
     this lone instruction as a bundle right now.  */
1231
  if (!inside_bundle)
1232
    tilegx_flush_bundle ();
1233
}
1234
 
1235
 
1236
static void
1237
s_require_canonical_reg_names (int require)
1238
{
1239
  demand_empty_rest_of_line ();
1240
  require_canonical_reg_names = require;
1241
}
1242
 
1243
static void
1244
s_allow_suspicious_bundles (int allow)
1245
{
1246
  demand_empty_rest_of_line ();
1247
  allow_suspicious_bundles = allow;
1248
}
1249
 
1250
const pseudo_typeS md_pseudo_table[] =
1251
{
1252
  {"align", s_align_bytes, 0},   /* Defaulting is invalid (0).  */
1253
  {"word", cons, 4},
1254
  {"require_canonical_reg_names", s_require_canonical_reg_names, 1 },
1255
  {"no_require_canonical_reg_names", s_require_canonical_reg_names, 0 },
1256
  {"allow_suspicious_bundles", s_allow_suspicious_bundles, 1 },
1257
  {"no_allow_suspicious_bundles", s_allow_suspicious_bundles, 0 },
1258
  { NULL, 0, 0 }
1259
};
1260
 
1261
/* Equal to MAX_PRECISION in atof-ieee.c  */
1262
#define MAX_LITTLENUMS 6
1263
 
1264
/* Turn the string pointed to by litP into a floating point constant
1265
   of type TYPE, and emit the appropriate bytes.  The number of
1266
   LITTLENUMS emitted is stored in *SIZEP.  An error message is
1267
   returned, or NULL on OK.  */
1268
 
1269
char *
1270
md_atof (int type, char *litP, int *sizeP)
1271
{
1272
  int prec;
1273
  LITTLENUM_TYPE words[MAX_LITTLENUMS];
1274
  LITTLENUM_TYPE *wordP;
1275
  char *t;
1276
 
1277
  switch (type)
1278
    {
1279
    case 'f':
1280
    case 'F':
1281
      prec = 2;
1282
      break;
1283
 
1284
    case 'd':
1285
    case 'D':
1286
      prec = 4;
1287
      break;
1288
 
1289
    default:
1290
      *sizeP = 0;
1291
      return _("Bad call to md_atof ()");
1292
    }
1293
  t = atof_ieee (input_line_pointer, type, words);
1294
  if (t)
1295
    input_line_pointer = t;
1296
 
1297
  *sizeP = prec * sizeof (LITTLENUM_TYPE);
1298
  /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
1299
     the bigendian 386.  */
1300
  for (wordP = words + prec - 1; prec--;)
1301
    {
1302
      md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
1303
      litP += sizeof (LITTLENUM_TYPE);
1304
    }
1305
  return 0;
1306
}
1307
 
1308
 
1309
/* We have no need to default values of symbols.  */
1310
 
1311
symbolS *
1312
md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1313
{
1314
  return NULL;
1315
}
1316
 
1317
 
1318
void
1319
tilegx_cons_fix_new (fragS *frag,
1320
                     int where,
1321
                     int nbytes,
1322
                     expressionS *exp)
1323
{
1324
  expressionS subexp;
1325
  bfd_reloc_code_real_type reloc = BFD_RELOC_NONE;
1326
  int no_overflow = 0;
1327
  fixS *fixP;
1328
 
1329
  /* See if it's one of our special functions.  */
1330
  switch (exp->X_op)
1331
    {
1332
    case O_hw0:
1333
      reloc = BFD_RELOC_TILEGX_HW0;
1334
      no_overflow = 1;
1335
      break;
1336
    case O_hw1:
1337
      reloc = BFD_RELOC_TILEGX_HW1;
1338
      no_overflow = 1;
1339
      break;
1340
    case O_hw2:
1341
      reloc = BFD_RELOC_TILEGX_HW2;
1342
      no_overflow = 1;
1343
      break;
1344
    case O_hw3:
1345
      reloc = BFD_RELOC_TILEGX_HW3;
1346
      no_overflow = 1;
1347
      break;
1348
    case O_hw0_last:
1349
      reloc = BFD_RELOC_TILEGX_HW0_LAST;
1350
      break;
1351
    case O_hw1_last:
1352
      reloc = BFD_RELOC_TILEGX_HW1_LAST;
1353
      break;
1354
    case O_hw2_last:
1355
      reloc = BFD_RELOC_TILEGX_HW2_LAST;
1356
      break;
1357
 
1358
    default:
1359
      /* Do nothing.  */
1360
      break;
1361
    }
1362
 
1363
  if (reloc != BFD_RELOC_NONE)
1364
    {
1365
      if (nbytes != 2)
1366
        {
1367
          as_bad (_("This operator only produces two byte values."));
1368
          nbytes = 2;
1369
        }
1370
 
1371
      memset (&subexp, 0, sizeof subexp);
1372
      subexp.X_op = O_symbol;
1373
      subexp.X_add_symbol = exp->X_add_symbol;
1374
      exp = &subexp;
1375
    }
1376
  else
1377
    {
1378
      switch (nbytes)
1379
        {
1380
        case 1:
1381
          reloc = BFD_RELOC_8;
1382
          break;
1383
        case 2:
1384
          reloc = BFD_RELOC_16;
1385
          break;
1386
        case 4:
1387
          reloc = BFD_RELOC_32;
1388
          break;
1389
        case 8:
1390
          reloc = BFD_RELOC_64;
1391
          break;
1392
        default:
1393
          as_bad (_("unsupported BFD relocation size %d"), nbytes);
1394
          reloc = BFD_RELOC_64;
1395
          break;
1396
        }
1397
    }
1398
 
1399
  fixP = fix_new_exp (frag, where, nbytes, exp, 0, reloc);
1400
  fixP->tc_fix_data = NULL;
1401
  fixP->fx_no_overflow |= no_overflow;
1402
}
1403
 
1404
 
1405
void
1406
md_apply_fix (fixS *fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED)
1407
{
1408
  const struct tilegx_operand *operand;
1409
  valueT value = *valP;
1410
  operatorT special;
1411
  char *p;
1412
 
1413
  /* Leave these for the linker.  */
1414
  if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
1415
      || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1416
    return;
1417
 
1418
  if (fixP->fx_subsy != (symbolS *) NULL)
1419
    {
1420
      /* We can't actually support subtracting a symbol.  */
1421
      as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
1422
    }
1423
 
1424
  /* Correct relocation types for pc-relativeness.  */
1425
  switch (fixP->fx_r_type)
1426
    {
1427
#define FIX_PCREL(rtype)                        \
1428
      case rtype:                               \
1429
        if (fixP->fx_pcrel)                     \
1430
          fixP->fx_r_type = rtype##_PCREL;      \
1431
      break;                                    \
1432
                                                \
1433
    case rtype##_PCREL:                         \
1434
      if (!fixP->fx_pcrel)                      \
1435
        fixP->fx_r_type = rtype;                \
1436
      break
1437
 
1438
      FIX_PCREL (BFD_RELOC_8);
1439
      FIX_PCREL (BFD_RELOC_16);
1440
      FIX_PCREL (BFD_RELOC_32);
1441
      FIX_PCREL (BFD_RELOC_64);
1442
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X0_HW0);
1443
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X1_HW0);
1444
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X0_HW1);
1445
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X1_HW1);
1446
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X0_HW2);
1447
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X1_HW2);
1448
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X0_HW3);
1449
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X1_HW3);
1450
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST);
1451
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST);
1452
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST);
1453
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST);
1454
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST);
1455
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST);
1456
 
1457
#undef FIX_PCREL
1458
 
1459
    default:
1460
      /* Do nothing  */
1461
      break;
1462
    }
1463
 
1464
  if (fixP->fx_addsy != NULL)
1465
    {
1466
#ifdef OBJ_ELF
1467
      switch (fixP->fx_r_type)
1468
        {
1469
        case BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_GD:
1470
        case BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_GD:
1471
        case BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_IE:
1472
        case BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_IE:
1473
        case BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
1474
        case BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
1475
        case BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
1476
        case BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
1477
        case BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_GD:
1478
        case BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_GD:
1479
        case BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_IE:
1480
        case BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_IE:
1481
        case BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
1482
        case BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
1483
        case BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
1484
        case BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
1485
        case BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_GD:
1486
        case BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_GD:
1487
        case BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_IE:
1488
        case BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_IE:
1489
        case BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_GD:
1490
        case BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_GD:
1491
        case BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_IE:
1492
        case BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_IE:
1493
        case BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_GD:
1494
        case BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_GD:
1495
        case BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_IE:
1496
        case BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_IE:
1497
        case BFD_RELOC_TILEGX_TLS_DTPMOD64:
1498
        case BFD_RELOC_TILEGX_TLS_DTPOFF64:
1499
        case BFD_RELOC_TILEGX_TLS_TPOFF64:
1500
        case BFD_RELOC_TILEGX_TLS_DTPMOD32:
1501
        case BFD_RELOC_TILEGX_TLS_DTPOFF32:
1502
        case BFD_RELOC_TILEGX_TLS_TPOFF32:
1503
          S_SET_THREAD_LOCAL (fixP->fx_addsy);
1504
          break;
1505
 
1506
        default:
1507
          /* Do nothing  */
1508
          break;
1509
        }
1510
#endif
1511
      return;
1512
    }
1513
 
1514
  /* Apply hw0, etc.  */
1515
  special = O_illegal;
1516
  switch (fixP->fx_r_type)
1517
    {
1518
    case BFD_RELOC_TILEGX_HW0:
1519
    case BFD_RELOC_TILEGX_IMM16_X0_HW0:
1520
    case BFD_RELOC_TILEGX_IMM16_X1_HW0:
1521
    case BFD_RELOC_TILEGX_IMM16_X0_HW0_PCREL:
1522
    case BFD_RELOC_TILEGX_IMM16_X1_HW0_PCREL:
1523
    case BFD_RELOC_TILEGX_IMM16_X0_HW0_GOT:
1524
    case BFD_RELOC_TILEGX_IMM16_X1_HW0_GOT:
1525
    case BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_GD:
1526
    case BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_GD:
1527
    case BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_IE:
1528
    case BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_IE:
1529
      special = O_hw0;
1530
      break;
1531
 
1532
    case BFD_RELOC_TILEGX_HW0_LAST:
1533
    case BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST:
1534
    case BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST:
1535
    case BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PCREL:
1536
    case BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PCREL:
1537
    case BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_GOT:
1538
    case BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_GOT:
1539
    case BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
1540
    case BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
1541
    case BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
1542
    case BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
1543
      special = O_hw0_last;
1544
      break;
1545
 
1546
    case BFD_RELOC_TILEGX_HW1:
1547
    case BFD_RELOC_TILEGX_IMM16_X0_HW1:
1548
    case BFD_RELOC_TILEGX_IMM16_X1_HW1:
1549
    case BFD_RELOC_TILEGX_IMM16_X0_HW1_PCREL:
1550
    case BFD_RELOC_TILEGX_IMM16_X1_HW1_PCREL:
1551
    case BFD_RELOC_TILEGX_IMM16_X0_HW1_GOT:
1552
    case BFD_RELOC_TILEGX_IMM16_X1_HW1_GOT:
1553
    case BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_GD:
1554
    case BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_GD:
1555
    case BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_IE:
1556
    case BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_IE:
1557
      special = O_hw1;
1558
      break;
1559
 
1560
    case BFD_RELOC_TILEGX_HW1_LAST:
1561
    case BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST:
1562
    case BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST:
1563
    case BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PCREL:
1564
    case BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PCREL:
1565
    case BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_GOT:
1566
    case BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_GOT:
1567
    case BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
1568
    case BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
1569
    case BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
1570
    case BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
1571
      special = O_hw1_last;
1572
      break;
1573
 
1574
    case BFD_RELOC_TILEGX_HW2:
1575
    case BFD_RELOC_TILEGX_IMM16_X0_HW2:
1576
    case BFD_RELOC_TILEGX_IMM16_X1_HW2:
1577
    case BFD_RELOC_TILEGX_IMM16_X0_HW2_PCREL:
1578
    case BFD_RELOC_TILEGX_IMM16_X1_HW2_PCREL:
1579
    case BFD_RELOC_TILEGX_IMM16_X0_HW2_GOT:
1580
    case BFD_RELOC_TILEGX_IMM16_X1_HW2_GOT:
1581
    case BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_GD:
1582
    case BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_GD:
1583
    case BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_IE:
1584
    case BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_IE:
1585
      special = O_hw2;
1586
      break;
1587
 
1588
    case BFD_RELOC_TILEGX_HW2_LAST:
1589
    case BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST:
1590
    case BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST:
1591
    case BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PCREL:
1592
    case BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PCREL:
1593
    case BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_GOT:
1594
    case BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_GOT:
1595
    case BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_GD:
1596
    case BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_GD:
1597
    case BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_IE:
1598
    case BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_IE:
1599
      special = O_hw2_last;
1600
      break;
1601
 
1602
    case BFD_RELOC_TILEGX_HW3:
1603
    case BFD_RELOC_TILEGX_IMM16_X0_HW3:
1604
    case BFD_RELOC_TILEGX_IMM16_X1_HW3:
1605
    case BFD_RELOC_TILEGX_IMM16_X0_HW3_PCREL:
1606
    case BFD_RELOC_TILEGX_IMM16_X1_HW3_PCREL:
1607
    case BFD_RELOC_TILEGX_IMM16_X0_HW3_GOT:
1608
    case BFD_RELOC_TILEGX_IMM16_X1_HW3_GOT:
1609
    case BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_GD:
1610
    case BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_GD:
1611
    case BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_IE:
1612
    case BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_IE:
1613
      special = O_hw3;
1614
      break;
1615
 
1616
    default:
1617
      /* Do nothing  */
1618
      break;
1619
    }
1620
 
1621
  if (special != O_illegal)
1622
    {
1623
      *valP = value = apply_special_operator (special, value,
1624
                                              fixP->fx_file, fixP->fx_line);
1625
    }
1626
 
1627
  p = fixP->fx_frag->fr_literal + fixP->fx_where;
1628
 
1629
  operand = fixP->tc_fix_data;
1630
  if (operand != NULL)
1631
    {
1632
      /* It's an instruction operand.  */
1633
      tilegx_bundle_bits bits =
1634
        insert_operand (0, operand, value, fixP->fx_file, fixP->fx_line);
1635
 
1636
      /* Note that we might either be writing out bits for a bundle
1637
         or a static network instruction, which are different sizes, so it's
1638
         important to stop touching memory once we run out of bits.
1639
         ORing in values is OK since we know the existing bits for
1640
         this operand are zero.  */
1641
      for (; bits != 0; bits >>= 8)
1642
        *p++ |= (char)bits;
1643
    }
1644
  else
1645
    {
1646
      /* Some other kind of relocation.  */
1647
      switch (fixP->fx_r_type)
1648
        {
1649
        case BFD_RELOC_8:
1650
        case BFD_RELOC_8_PCREL:
1651
          md_number_to_chars (p, value, 1);
1652
          break;
1653
 
1654
        case BFD_RELOC_16:
1655
        case BFD_RELOC_16_PCREL:
1656
          md_number_to_chars (p, value, 2);
1657
          break;
1658
 
1659
        case BFD_RELOC_32:
1660
        case BFD_RELOC_32_PCREL:
1661
          md_number_to_chars (p, value, 4);
1662
          break;
1663
 
1664
        case BFD_RELOC_64:
1665
        case BFD_RELOC_64_PCREL:
1666
          md_number_to_chars (p, value, 8);
1667
          break;
1668
 
1669
        default:
1670
          /* Leave it for the linker.  */
1671
          return;
1672
        }
1673
    }
1674
 
1675
  fixP->fx_done = 1;
1676
}
1677
 
1678
 
1679
/* Generate the BFD reloc to be stuck in the object file from the
1680
   fixup used internally in the assembler.  */
1681
 
1682
arelent *
1683
tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED, fixS *fixp)
1684
{
1685
  arelent *reloc;
1686
 
1687
  reloc = (arelent *) xmalloc (sizeof (arelent));
1688
  reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1689
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1690
  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1691
 
1692
  /* Make sure none of our internal relocations make it this far.
1693
     They'd better have been fully resolved by this point.  */
1694
  gas_assert ((int) fixp->fx_r_type > 0);
1695
 
1696
  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1697
  if (reloc->howto == NULL)
1698
    {
1699
      as_bad_where (fixp->fx_file, fixp->fx_line,
1700
                    _("cannot represent `%s' relocation in object file"),
1701
                    bfd_get_reloc_code_name (fixp->fx_r_type));
1702
      return NULL;
1703
    }
1704
 
1705
  if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
1706
    {
1707
      as_fatal (_("internal error? cannot generate `%s' relocation (%d, %d)"),
1708
                bfd_get_reloc_code_name (fixp->fx_r_type),
1709
                fixp->fx_pcrel, reloc->howto->pc_relative);
1710
    }
1711
  gas_assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
1712
 
1713
  reloc->addend = fixp->fx_offset;
1714
 
1715
  return reloc;
1716
}
1717
 
1718
 
1719
/* The location from which a PC relative jump should be calculated,
1720
   given a PC relative reloc.  */
1721
 
1722
long
1723
md_pcrel_from (fixS *fixP)
1724
{
1725
  return fixP->fx_frag->fr_address + fixP->fx_where;
1726
}
1727
 
1728
 
1729
/* Return 1 if it's OK to adjust a reloc by replacing the symbol with
1730
   a section symbol plus some offset.  */
1731
int
1732
tilegx_fix_adjustable (fixS *fix)
1733
{
1734
  /* Prevent all adjustments to global symbols  */
1735
  if (S_IS_EXTERNAL (fix->fx_addsy) || S_IS_WEAK (fix->fx_addsy))
1736
    return 0;
1737
 
1738
  return 1;
1739
}
1740
 
1741
 
1742
int
1743
tilegx_unrecognized_line (int ch)
1744
{
1745
  switch (ch)
1746
    {
1747
    case '{':
1748
      if (inside_bundle)
1749
        {
1750
          as_bad (_("Found '{' when already bundling."));
1751
        }
1752
      else
1753
        {
1754
          inside_bundle = 1;
1755
          current_bundle_index = 0;
1756
        }
1757
      return 1;
1758
 
1759
    case '}':
1760
      if (!inside_bundle)
1761
        {
1762
          as_bad (_("Found '}' when not bundling."));
1763
        }
1764
      else
1765
        {
1766
          tilegx_flush_bundle ();
1767
        }
1768
 
1769
      /* Allow '{' to follow on the same line.  We also allow ";;", but that
1770
         happens automatically because ';' is an end of line marker.  */
1771
      SKIP_WHITESPACE ();
1772
      if (input_line_pointer[0] == '{')
1773
        {
1774
          input_line_pointer++;
1775
          return tilegx_unrecognized_line ('{');
1776
        }
1777
 
1778
      demand_empty_rest_of_line ();
1779
      return 1;
1780
 
1781
    default:
1782
      break;
1783
    }
1784
 
1785
  /* Not a valid line.  */
1786
  return 0;
1787
}
1788
 
1789
 
1790
/* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
1791
   of an rs_align_code fragment.  */
1792
 
1793
void
1794
tilegx_handle_align (fragS *fragp)
1795
{
1796
  addressT bytes, fix;
1797
  char *p;
1798
 
1799
  if (fragp->fr_type != rs_align_code)
1800
    return;
1801
 
1802
  bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
1803
  p = fragp->fr_literal + fragp->fr_fix;
1804
  fix = 0;
1805
 
1806
  /* Determine the bits for NOP.  */
1807
  const struct tilegx_opcode *nop_opcode =
1808
    &tilegx_opcodes[TILEGX_OPC_NOP];
1809
  tilegx_bundle_bits nop =
1810
    (  nop_opcode->fixed_bit_values[TILEGX_PIPELINE_X0]
1811
     | nop_opcode->fixed_bit_values[TILEGX_PIPELINE_X1]);
1812
 
1813
  if ((bytes & (TILEGX_BUNDLE_SIZE_IN_BYTES - 1)) != 0)
1814
    {
1815
      fix = bytes & (TILEGX_BUNDLE_SIZE_IN_BYTES - 1);
1816
      memset (p, 0, fix);
1817
      p += fix;
1818
      bytes -= fix;
1819
    }
1820
 
1821
  number_to_chars_littleendian (p, nop, 8);
1822
  fragp->fr_fix += fix;
1823
  fragp->fr_var = TILEGX_BUNDLE_SIZE_IN_BYTES;
1824
}
1825
 
1826
/* Standard calling conventions leave the CFA at SP on entry.  */
1827
void
1828
tilegx_cfi_frame_initial_instructions (void)
1829
{
1830
  cfi_add_CFA_def_cfa_register (54);
1831
}
1832
 
1833
int
1834
tc_tilegx_regname_to_dw2regnum (char *regname)
1835
{
1836
  int i;
1837
  for (i = 0; i < TILEGX_NUM_REGISTERS; i++)
1838
    {
1839
      if (!strcmp (regname, tilegx_register_names[i]))
1840
        return i;
1841
    }
1842
 
1843
  return -1;
1844
}

powered by: WebSVN 2.1.0

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