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 163

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
                  /* HACK: We used X_md to mark this symbol as a fake wrapper
695
                     around a real expression. To unwrap it, we just grab its
696
                     value here.  */
697
                  operand_exp = &operand_exp->X_add_symbol->sy_value;
698 163 khays
 
699
                  if (require_symbol)
700
                    {
701
                      /* Look at the expression, and reject it if it's not a
702
                         plain symbol.  */
703
                      if (operand_exp->X_op != O_symbol
704
                          || operand_exp->X_add_number != 0)
705
                        as_bad (_("Operator may only be applied to symbols."));
706
                    }
707 148 khays
                }
708
              else
709
                {
710
                  /* The value of this expression is an actual symbol, so
711
                     turn that into an expression.  */
712
                  memset (&subexp, 0, sizeof subexp);
713
                  subexp.X_op = O_symbol;
714
                  subexp.X_add_symbol = operand_exp->X_add_symbol;
715
                  operand_exp = &subexp;
716
                }
717
            }
718
 
719
          /* Create a fixup to handle this later.  */
720
          fixP = fix_new_exp (frag_now,
721
                              bundle_start - frag_now->fr_literal,
722
                              (operand->num_bits + 7) >> 3,
723
                              operand_exp,
724
                              is_pc_relative,
725
                              reloc);
726
          fixP->tc_fix_data = operand;
727
 
728
          /* Don't do overflow checking if we are applying a function like
729
             ha16.  */
730
          fixP->fx_no_overflow |= use_subexp;
731
        }
732
    }
733
  return bits;
734
}
735
 
736
 
737
/* Detects and complains if two instructions in current_bundle write
738
   to the same register, either implicitly or explicitly, or if a
739
   read-only register is written.  */
740
static void
741
check_illegal_reg_writes (void)
742
{
743
  BFD_HOST_U_64_BIT all_regs_written = 0;
744
  int j;
745
 
746
  for (j = 0; j < current_bundle_index; j++)
747
    {
748
      const struct tilegx_instruction *instr = &current_bundle[j];
749
      int k;
750
      BFD_HOST_U_64_BIT regs =
751
        ((BFD_HOST_U_64_BIT)1) << instr->opcode->implicitly_written_register;
752
      BFD_HOST_U_64_BIT conflict;
753
 
754
      for (k = 0; k < instr->opcode->num_operands; k++)
755
        {
756
          const struct tilegx_operand *operand =
757
            &tilegx_operands[instr->opcode->operands[instr->pipe][k]];
758
 
759
          if (operand->is_dest_reg)
760
            {
761
              int regno = instr->operand_values[k].X_add_number;
762
              BFD_HOST_U_64_BIT mask = ((BFD_HOST_U_64_BIT)1) << regno;
763
 
764
              if ((mask & (  (((BFD_HOST_U_64_BIT)1) << TREG_IDN1)
765
                             | (((BFD_HOST_U_64_BIT)1) << TREG_UDN1)
766
                             | (((BFD_HOST_U_64_BIT)1) << TREG_UDN2)
767
                             | (((BFD_HOST_U_64_BIT)1) << TREG_UDN3))) != 0
768
                  && !allow_suspicious_bundles)
769
                {
770
                  as_bad (_("Writes to register '%s' are not allowed."),
771
                          tilegx_register_names[regno]);
772
                }
773
 
774
              regs |= mask;
775
            }
776
        }
777
 
778
      /* Writing to the zero register doesn't count.  */
779
      regs &= ~(((BFD_HOST_U_64_BIT)1) << TREG_ZERO);
780
 
781
      conflict = all_regs_written & regs;
782
      if (conflict != 0 && !allow_suspicious_bundles)
783
        {
784
          /* Find which register caused the conflict.  */
785
          const char *conflicting_reg_name = "???";
786
          int i;
787
 
788
          for (i = 0; i < TILEGX_NUM_REGISTERS; i++)
789
            {
790
              if (((conflict >> i) & 1) != 0)
791
                {
792
                  conflicting_reg_name = tilegx_register_names[i];
793
                  break;
794
                }
795
            }
796
 
797
          as_bad (_("Two instructions in the same bundle both write "
798
                    "to register %s, which is not allowed."),
799
                  conflicting_reg_name);
800
        }
801
 
802
      all_regs_written |= regs;
803
    }
804
}
805
 
806
 
807
static void
808
tilegx_flush_bundle (void)
809
{
810
  unsigned i;
811
  int j;
812
  addressT addr_mod;
813
  unsigned compatible_pipes;
814
  const struct bundle_template *match;
815
  char *f;
816
 
817
  inside_bundle = 0;
818
 
819
  switch (current_bundle_index)
820
    {
821
    case 0:
822
      /* No instructions.  */
823
      return;
824
    case 1:
825
      if (current_bundle[0].opcode->can_bundle)
826
        {
827
          /* Simplify later logic by adding an explicit fnop.  */
828
          prepend_nop_to_bundle (TILEGX_OPC_FNOP);
829
        }
830
      else
831
        {
832
          /* This instruction cannot be bundled with anything else.
833
             Prepend an explicit 'nop', rather than an 'fnop', because
834
             fnops can be replaced by later binary-processing tools while
835
             nops cannot.  */
836
          prepend_nop_to_bundle (TILEGX_OPC_NOP);
837
        }
838
      break;
839
    default:
840
      if (!allow_suspicious_bundles)
841
        {
842
          /* Make sure all instructions can be bundled with other
843
             instructions.  */
844
          const struct tilegx_opcode *cannot_bundle = NULL;
845
          bfd_boolean seen_non_nop = FALSE;
846
 
847
          for (j = 0; j < current_bundle_index; j++)
848
            {
849
              const struct tilegx_opcode *op = current_bundle[j].opcode;
850
 
851
              if (!op->can_bundle && cannot_bundle == NULL)
852
                cannot_bundle = op;
853
              else if (op->mnemonic != TILEGX_OPC_NOP
854
                       && op->mnemonic != TILEGX_OPC_INFO
855
                       && op->mnemonic != TILEGX_OPC_INFOL)
856
                seen_non_nop = TRUE;
857
            }
858
 
859
          if (cannot_bundle != NULL && seen_non_nop)
860
            {
861
              current_bundle_index = 0;
862
              as_bad (_("'%s' may not be bundled with other instructions."),
863
                      cannot_bundle->name);
864
              return;
865
            }
866
        }
867
      break;
868
    }
869
 
870
  compatible_pipes =
871
    BUNDLE_TEMPLATE_MASK(current_bundle[0].opcode->pipes,
872
                         current_bundle[1].opcode->pipes,
873
                         (current_bundle_index == 3
874
                          ? current_bundle[2].opcode->pipes
875
                          : (1 << NO_PIPELINE)));
876
 
877
  /* Find a template that works, if any.  */
878
  match = NULL;
879
  for (i = 0; i < sizeof bundle_templates / sizeof bundle_templates[0]; i++)
880
    {
881
      const struct bundle_template *b = &bundle_templates[i];
882
      if ((b->pipe_mask & compatible_pipes) == b->pipe_mask)
883
        {
884
          match = b;
885
          break;
886
        }
887
    }
888
 
889
  if (match == NULL)
890
    {
891
      current_bundle_index = 0;
892
      as_bad (_("Invalid combination of instructions for bundle."));
893
      return;
894
    }
895
 
896
  /* If the section seems to have no alignment set yet, go ahead and
897
     make it large enough to hold code.  */
898
  if (bfd_get_section_alignment (stdoutput, now_seg) == 0)
899
    bfd_set_section_alignment (stdoutput, now_seg,
900
                               TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES);
901
 
902
  for (j = 0; j < current_bundle_index; j++)
903
    current_bundle[j].pipe = match->pipe[j];
904
 
905
  if (current_bundle_index == 2 && !tilegx_is_x_pipeline (match->pipe[0]))
906
    {
907
      /* We are in Y mode with only two instructions, so add an FNOP.  */
908
      prepend_nop_to_bundle (TILEGX_OPC_FNOP);
909
 
910
      /* Figure out what pipe the fnop must be in via arithmetic.
911
       * p0 + p1 + p2 must sum to the sum of TILEGX_PIPELINE_Y[012].  */
912
      current_bundle[0].pipe =
913
        (tilegx_pipeline)((TILEGX_PIPELINE_Y0
914
                           + TILEGX_PIPELINE_Y1
915
                           + TILEGX_PIPELINE_Y2) -
916
                          (current_bundle[1].pipe + current_bundle[2].pipe));
917
    }
918
 
919
  check_illegal_reg_writes ();
920
 
921
  f = frag_more (TILEGX_BUNDLE_SIZE_IN_BYTES);
922
 
923
  /* Check to see if this bundle is at an offset that is a multiple of 8-bytes
924
     from the start of the frag.  */
925
  addr_mod = frag_now_fix () & (TILEGX_BUNDLE_ALIGNMENT_IN_BYTES - 1);
926
  if (frag_now->has_code && frag_now->insn_addr != addr_mod)
927
    as_bad (_("instruction address is not a multiple of 8"));
928
  frag_now->insn_addr = addr_mod;
929
  frag_now->has_code = 1;
930
 
931
  tilegx_bundle_bits bits = 0;
932
  for (j = 0; j < current_bundle_index; j++)
933
    {
934
      struct tilegx_instruction *instr = &current_bundle[j];
935
      tilegx_pipeline pipeline = instr->pipe;
936
      const struct tilegx_opcode *opcode = instr->opcode;
937
 
938
      bits |= emit_tilegx_instruction (opcode->fixed_bit_values[pipeline],
939
                                       opcode->num_operands,
940
                                       &opcode->operands[pipeline][0],
941
                                       instr->operand_values,
942
                                       f);
943
    }
944
 
945
  number_to_chars_littleendian (f, bits, 8);
946
  current_bundle_index = 0;
947
 
948
  /* Emit DWARF2 debugging information.  */
949
  dwarf2_emit_insn (TILEGX_BUNDLE_SIZE_IN_BYTES);
950
}
951
 
952
 
953
/* Extend the expression parser to handle hw0(label), etc.
954
   as well as SPR names when in the context of parsing an SPR.  */
955
 
956
int
957
tilegx_parse_name (char *name, expressionS *e, char *nextcharP)
958
{
959
  operatorT op = O_illegal;
960
 
961
  if (parsing_spr)
962
    {
963
      void* val = hash_find (spr_hash, name);
964
      if (val == NULL)
965
        return 0;
966
 
967
      memset (e, 0, sizeof *e);
968
      e->X_op = O_constant;
969
      e->X_add_number = ((const struct tilegx_spr *)val)->number;
970
      return 1;
971
    }
972
 
973
  if (*nextcharP != '(')
974
    {
975
      /* hw0, etc. not followed by a paren is just a label with that name.  */
976
      return 0;
977
    }
978
  else
979
    {
980
      /* Look up the operator in our table.  */
981
      void* val = hash_find (special_operator_hash, name);
982
      if (val == 0)
983
        return 0;
984
      op = (operatorT)(long)val;
985
    }
986
 
987
  /* Restore old '(' and skip it.  */
988
  *input_line_pointer = '(';
989
  ++input_line_pointer;
990
 
991
  expression (e);
992
 
993
  if (*input_line_pointer != ')')
994
    {
995
      as_bad (_("Missing ')'"));
996
      *nextcharP = *input_line_pointer;
997
      return 0;
998
    }
999
  /* Skip ')'.  */
1000
  ++input_line_pointer;
1001
 
1002
  if (e->X_op == O_register || e->X_op == O_absent)
1003
    {
1004
      as_bad (_("Invalid expression."));
1005
      e->X_op = O_constant;
1006
      e->X_add_number = 0;
1007
    }
1008
  else
1009
    {
1010
      /* Wrap subexpression with a unary operator.  */
1011
      symbolS *sym = make_expr_symbol (e);
1012
 
1013
      if (sym != e->X_add_symbol)
1014
        {
1015
          /* HACK: mark this symbol as a temporary wrapper around a proper
1016
             expression, so we can unwrap it later once we have communicated
1017
             the relocation type.  */
1018
          sym->sy_value.X_md = 1;
1019
        }
1020
 
1021
      memset (e, 0, sizeof *e);
1022
      e->X_op = op;
1023
      e->X_add_symbol = sym;
1024
      e->X_add_number = 0;
1025
    }
1026
 
1027
  *nextcharP = *input_line_pointer;
1028
  return 1;
1029
}
1030
 
1031
 
1032
/* Parses an expression which must be a register name.  */
1033
 
1034
static void
1035
parse_reg_expression (expressionS* expression)
1036
{
1037
  /* Zero everything to make sure we don't miss any flags.  */
1038
  memset (expression, 0, sizeof *expression);
1039
 
1040
  char* regname = input_line_pointer;
1041
  char terminating_char = get_symbol_end ();
1042
 
1043
  void* pval = hash_find (main_reg_hash, regname);
1044
 
1045
  if (pval == NULL)
1046
    {
1047
      as_bad (_("Expected register, got '%s'."), regname);
1048
    }
1049
 
1050
  int regno_and_flags = (int)(size_t)pval;
1051
  int regno = EXTRACT_REGNO(regno_and_flags);
1052
 
1053
  if ((regno_and_flags & NONCANONICAL_REG_NAME_FLAG)
1054
      && require_canonical_reg_names)
1055
    {
1056
      as_warn (_("Found use of non-canonical register name %s; "
1057
                 "use %s instead."),
1058
               regname,
1059
               tilegx_register_names[regno]);
1060
    }
1061
 
1062
  /* Restore the old character following the register name.  */
1063
  *input_line_pointer = terminating_char;
1064
 
1065
  /* Fill in the expression fields to indicate it's a register.  */
1066
  expression->X_op = O_register;
1067
  expression->X_add_number = regno;
1068
}
1069
 
1070
 
1071
/* Parses and type-checks comma-separated operands in input_line_pointer.  */
1072
 
1073
static void
1074
parse_operands (const char *opcode_name,
1075
                const unsigned char *operands,
1076
                int num_operands,
1077
                expressionS *operand_values)
1078
{
1079
  int i;
1080
 
1081
  memset (operand_values, 0, num_operands * sizeof operand_values[0]);
1082
 
1083
  SKIP_WHITESPACE ();
1084
  for (i = 0; i < num_operands; i++)
1085
    {
1086
      tilegx_operand_type type = tilegx_operands[operands[i]].type;
1087
 
1088
      SKIP_WHITESPACE ();
1089
 
1090
      if (type == TILEGX_OP_TYPE_REGISTER)
1091
        {
1092
          parse_reg_expression (&operand_values[i]);
1093
        }
1094
      else if (*input_line_pointer == '}')
1095
        {
1096
          operand_values[i].X_op = O_absent;
1097
        }
1098
      else if (type == TILEGX_OP_TYPE_SPR)
1099
        {
1100
          /* Modify the expression parser to add SPRs to the namespace.  */
1101
          parsing_spr = 1;
1102
          expression (&operand_values[i]);
1103
          parsing_spr = 0;
1104
        }
1105
      else
1106
        {
1107
          expression (&operand_values[i]);
1108
        }
1109
 
1110
      SKIP_WHITESPACE ();
1111
 
1112
      if (i + 1 < num_operands)
1113
        {
1114
          int separator = (unsigned char)*input_line_pointer++;
1115
 
1116
          if (is_end_of_line[separator] || (separator == '}'))
1117
            {
1118
              as_bad (_("Too few operands to '%s'."), opcode_name);
1119
              return;
1120
            }
1121
          else if (separator != ',')
1122
            {
1123
              as_bad (_("Unexpected character '%c' after operand %d to %s."),
1124
                      (char)separator, i + 1, opcode_name);
1125
              return;
1126
            }
1127
        }
1128
 
1129
      /* Arbitrarily use the first valid pipe to get the operand type,
1130
         since they are all the same.  */
1131
      switch (tilegx_operands[operands[i]].type)
1132
        {
1133
        case TILEGX_OP_TYPE_REGISTER:
1134
          /* Handled in parse_reg_expression already.  */
1135
          break;
1136
        case TILEGX_OP_TYPE_SPR:
1137
          /* Fall through  */
1138
        case TILEGX_OP_TYPE_IMMEDIATE:
1139
          /* Fall through  */
1140
        case TILEGX_OP_TYPE_ADDRESS:
1141
          if (   operand_values[i].X_op == O_register
1142
                 || operand_values[i].X_op == O_illegal
1143
                 || operand_values[i].X_op == O_absent)
1144
            as_bad (_("Expected immediate expression"));
1145
          break;
1146
        default:
1147
          abort();
1148
        }
1149
    }
1150
 
1151
  if (!is_end_of_line[(unsigned char)*input_line_pointer])
1152
    {
1153
      switch (*input_line_pointer)
1154
        {
1155
        case '}':
1156
          if (!inside_bundle)
1157
            as_bad (_("Found '}' when not bundling."));
1158
          ++input_line_pointer;
1159
          inside_bundle = 0;
1160
          demand_empty_rest_of_line ();
1161
          break;
1162
 
1163
        case ',':
1164
          as_bad (_("Too many operands"));
1165
          break;
1166
 
1167
        default:
1168
          /* Use default error for unrecognized garbage.  */
1169
          demand_empty_rest_of_line ();
1170
          break;
1171
        }
1172
    }
1173
}
1174
 
1175
 
1176
/* This is the guts of the machine-dependent assembler.  STR points to a
1177
   machine dependent instruction.  This function is supposed to emit the
1178
   frags/bytes it assembles to.  */
1179
 
1180
void
1181
md_assemble (char *str)
1182
{
1183
  char old_char;
1184
  size_t opname_len;
1185
  char *old_input_line_pointer;
1186
  const struct tilegx_opcode *op;
1187
  int first_pipe;
1188
 
1189
  /* Split off the opcode and look it up.  */
1190
  opname_len = strcspn (str, " {}");
1191
  old_char = str[opname_len];
1192
  str[opname_len] = '\0';
1193
 
1194
  op = hash_find(op_hash, str);
1195
  str[opname_len] = old_char;
1196
  if (op == NULL)
1197
    {
1198
      as_bad (_("Unknown opcode `%.*s'."), (int)opname_len, str);
1199
      return;
1200
    }
1201
 
1202
  /* Prepare to parse the operands.  */
1203
  old_input_line_pointer = input_line_pointer;
1204
  input_line_pointer = str + opname_len;
1205
  SKIP_WHITESPACE ();
1206
 
1207
  if (current_bundle_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
1208
    {
1209
      as_bad (_("Too many instructions for bundle."));
1210
      tilegx_flush_bundle ();
1211
    }
1212
 
1213
  /* Make sure we have room for the upcoming bundle before we
1214
     create any fixups. Otherwise if we have to switch to a new
1215
     frag the fixup dot_value fields will be wrong.  */
1216
  frag_grow (TILEGX_BUNDLE_SIZE_IN_BYTES);
1217
 
1218
  /* Find a valid pipe for this opcode.  */
1219
  for (first_pipe = 0; (op->pipes & (1 << first_pipe)) == 0; first_pipe++)
1220
    ;
1221
 
1222
  /* Call the function that assembles this instruction.  */
1223
  current_bundle[current_bundle_index].opcode = op;
1224
  parse_operands (op->name,
1225
                  &op->operands[first_pipe][0],
1226
                  op->num_operands,
1227
                  current_bundle[current_bundle_index].operand_values);
1228
  ++current_bundle_index;
1229
 
1230
  /* Restore the saved value of input_line_pointer.  */
1231
  input_line_pointer = old_input_line_pointer;
1232
 
1233
  /* If we weren't inside curly braces, go ahead and emit
1234
     this lone instruction as a bundle right now.  */
1235
  if (!inside_bundle)
1236
    tilegx_flush_bundle ();
1237
}
1238
 
1239
 
1240
static void
1241
s_require_canonical_reg_names (int require)
1242
{
1243
  demand_empty_rest_of_line ();
1244
  require_canonical_reg_names = require;
1245
}
1246
 
1247
static void
1248
s_allow_suspicious_bundles (int allow)
1249
{
1250
  demand_empty_rest_of_line ();
1251
  allow_suspicious_bundles = allow;
1252
}
1253
 
1254
const pseudo_typeS md_pseudo_table[] =
1255
{
1256
  {"align", s_align_bytes, 0},   /* Defaulting is invalid (0).  */
1257
  {"word", cons, 4},
1258
  {"require_canonical_reg_names", s_require_canonical_reg_names, 1 },
1259
  {"no_require_canonical_reg_names", s_require_canonical_reg_names, 0 },
1260
  {"allow_suspicious_bundles", s_allow_suspicious_bundles, 1 },
1261
  {"no_allow_suspicious_bundles", s_allow_suspicious_bundles, 0 },
1262
  { NULL, 0, 0 }
1263
};
1264
 
1265
/* Equal to MAX_PRECISION in atof-ieee.c  */
1266
#define MAX_LITTLENUMS 6
1267
 
1268
/* Turn the string pointed to by litP into a floating point constant
1269
   of type TYPE, and emit the appropriate bytes.  The number of
1270
   LITTLENUMS emitted is stored in *SIZEP.  An error message is
1271
   returned, or NULL on OK.  */
1272
 
1273
char *
1274
md_atof (int type, char *litP, int *sizeP)
1275
{
1276
  int prec;
1277
  LITTLENUM_TYPE words[MAX_LITTLENUMS];
1278
  LITTLENUM_TYPE *wordP;
1279
  char *t;
1280
 
1281
  switch (type)
1282
    {
1283
    case 'f':
1284
    case 'F':
1285
      prec = 2;
1286
      break;
1287
 
1288
    case 'd':
1289
    case 'D':
1290
      prec = 4;
1291
      break;
1292
 
1293
    default:
1294
      *sizeP = 0;
1295
      return _("Bad call to md_atof ()");
1296
    }
1297
  t = atof_ieee (input_line_pointer, type, words);
1298
  if (t)
1299
    input_line_pointer = t;
1300
 
1301
  *sizeP = prec * sizeof (LITTLENUM_TYPE);
1302
  /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
1303
     the bigendian 386.  */
1304
  for (wordP = words + prec - 1; prec--;)
1305
    {
1306
      md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
1307
      litP += sizeof (LITTLENUM_TYPE);
1308
    }
1309
  return 0;
1310
}
1311
 
1312
 
1313
/* We have no need to default values of symbols.  */
1314
 
1315
symbolS *
1316
md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1317
{
1318
  return NULL;
1319
}
1320
 
1321
 
1322
void
1323
tilegx_cons_fix_new (fragS *frag,
1324
                     int where,
1325
                     int nbytes,
1326
                     expressionS *exp)
1327
{
1328
  expressionS subexp;
1329
  bfd_reloc_code_real_type reloc = BFD_RELOC_NONE;
1330
  int no_overflow = 0;
1331
  fixS *fixP;
1332
 
1333
  /* See if it's one of our special functions.  */
1334
  switch (exp->X_op)
1335
    {
1336
    case O_hw0:
1337
      reloc = BFD_RELOC_TILEGX_HW0;
1338
      no_overflow = 1;
1339
      break;
1340
    case O_hw1:
1341
      reloc = BFD_RELOC_TILEGX_HW1;
1342
      no_overflow = 1;
1343
      break;
1344
    case O_hw2:
1345
      reloc = BFD_RELOC_TILEGX_HW2;
1346
      no_overflow = 1;
1347
      break;
1348
    case O_hw3:
1349
      reloc = BFD_RELOC_TILEGX_HW3;
1350
      no_overflow = 1;
1351
      break;
1352
    case O_hw0_last:
1353
      reloc = BFD_RELOC_TILEGX_HW0_LAST;
1354
      break;
1355
    case O_hw1_last:
1356
      reloc = BFD_RELOC_TILEGX_HW1_LAST;
1357
      break;
1358
    case O_hw2_last:
1359
      reloc = BFD_RELOC_TILEGX_HW2_LAST;
1360
      break;
1361
 
1362
    default:
1363
      /* Do nothing.  */
1364
      break;
1365
    }
1366
 
1367
  if (reloc != BFD_RELOC_NONE)
1368
    {
1369
      if (nbytes != 2)
1370
        {
1371
          as_bad (_("This operator only produces two byte values."));
1372
          nbytes = 2;
1373
        }
1374
 
1375
      memset (&subexp, 0, sizeof subexp);
1376
      subexp.X_op = O_symbol;
1377
      subexp.X_add_symbol = exp->X_add_symbol;
1378
      exp = &subexp;
1379
    }
1380
  else
1381
    {
1382
      switch (nbytes)
1383
        {
1384
        case 1:
1385
          reloc = BFD_RELOC_8;
1386
          break;
1387
        case 2:
1388
          reloc = BFD_RELOC_16;
1389
          break;
1390
        case 4:
1391
          reloc = BFD_RELOC_32;
1392
          break;
1393
        case 8:
1394
          reloc = BFD_RELOC_64;
1395
          break;
1396
        default:
1397
          as_bad (_("unsupported BFD relocation size %d"), nbytes);
1398
          reloc = BFD_RELOC_64;
1399
          break;
1400
        }
1401
    }
1402
 
1403
  fixP = fix_new_exp (frag, where, nbytes, exp, 0, reloc);
1404
  fixP->tc_fix_data = NULL;
1405
  fixP->fx_no_overflow |= no_overflow;
1406
}
1407
 
1408
 
1409
void
1410
md_apply_fix (fixS *fixP, valueT * valP, segT seg ATTRIBUTE_UNUSED)
1411
{
1412
  const struct tilegx_operand *operand;
1413
  valueT value = *valP;
1414
  operatorT special;
1415
  char *p;
1416
 
1417
  /* Leave these for the linker.  */
1418
  if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
1419
      || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1420
    return;
1421
 
1422
  if (fixP->fx_subsy != (symbolS *) NULL)
1423
    {
1424
      /* We can't actually support subtracting a symbol.  */
1425
      as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));
1426
    }
1427
 
1428
  /* Correct relocation types for pc-relativeness.  */
1429
  switch (fixP->fx_r_type)
1430
    {
1431
#define FIX_PCREL(rtype)                        \
1432
      case rtype:                               \
1433
        if (fixP->fx_pcrel)                     \
1434
          fixP->fx_r_type = rtype##_PCREL;      \
1435
      break;                                    \
1436
                                                \
1437
    case rtype##_PCREL:                         \
1438
      if (!fixP->fx_pcrel)                      \
1439
        fixP->fx_r_type = rtype;                \
1440
      break
1441
 
1442
      FIX_PCREL (BFD_RELOC_8);
1443
      FIX_PCREL (BFD_RELOC_16);
1444
      FIX_PCREL (BFD_RELOC_32);
1445
      FIX_PCREL (BFD_RELOC_64);
1446
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X0_HW0);
1447
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X1_HW0);
1448
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X0_HW1);
1449
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X1_HW1);
1450
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X0_HW2);
1451
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X1_HW2);
1452
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X0_HW3);
1453
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X1_HW3);
1454
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST);
1455
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST);
1456
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST);
1457
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST);
1458
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST);
1459
      FIX_PCREL (BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST);
1460
 
1461
#undef FIX_PCREL
1462
 
1463
    default:
1464
      /* Do nothing  */
1465
      break;
1466
    }
1467
 
1468
  if (fixP->fx_addsy != NULL)
1469
    {
1470
#ifdef OBJ_ELF
1471
      switch (fixP->fx_r_type)
1472
        {
1473
        case BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_GD:
1474
        case BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_GD:
1475
        case BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_IE:
1476
        case BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_IE:
1477
        case BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
1478
        case BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
1479
        case BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
1480
        case BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
1481
        case BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_GD:
1482
        case BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_GD:
1483
        case BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_IE:
1484
        case BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_IE:
1485
        case BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
1486
        case BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
1487
        case BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
1488
        case BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
1489
        case BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_GD:
1490
        case BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_GD:
1491
        case BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_IE:
1492
        case BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_IE:
1493
        case BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_GD:
1494
        case BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_GD:
1495
        case BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_IE:
1496
        case BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_IE:
1497
        case BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_GD:
1498
        case BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_GD:
1499
        case BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_IE:
1500
        case BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_IE:
1501
        case BFD_RELOC_TILEGX_TLS_DTPMOD64:
1502
        case BFD_RELOC_TILEGX_TLS_DTPOFF64:
1503
        case BFD_RELOC_TILEGX_TLS_TPOFF64:
1504
        case BFD_RELOC_TILEGX_TLS_DTPMOD32:
1505
        case BFD_RELOC_TILEGX_TLS_DTPOFF32:
1506
        case BFD_RELOC_TILEGX_TLS_TPOFF32:
1507
          S_SET_THREAD_LOCAL (fixP->fx_addsy);
1508
          break;
1509
 
1510
        default:
1511
          /* Do nothing  */
1512
          break;
1513
        }
1514
#endif
1515
      return;
1516
    }
1517
 
1518
  /* Apply hw0, etc.  */
1519
  special = O_illegal;
1520
  switch (fixP->fx_r_type)
1521
    {
1522
    case BFD_RELOC_TILEGX_HW0:
1523
    case BFD_RELOC_TILEGX_IMM16_X0_HW0:
1524
    case BFD_RELOC_TILEGX_IMM16_X1_HW0:
1525
    case BFD_RELOC_TILEGX_IMM16_X0_HW0_PCREL:
1526
    case BFD_RELOC_TILEGX_IMM16_X1_HW0_PCREL:
1527
    case BFD_RELOC_TILEGX_IMM16_X0_HW0_GOT:
1528
    case BFD_RELOC_TILEGX_IMM16_X1_HW0_GOT:
1529
    case BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_GD:
1530
    case BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_GD:
1531
    case BFD_RELOC_TILEGX_IMM16_X0_HW0_TLS_IE:
1532
    case BFD_RELOC_TILEGX_IMM16_X1_HW0_TLS_IE:
1533
      special = O_hw0;
1534
      break;
1535
 
1536
    case BFD_RELOC_TILEGX_HW0_LAST:
1537
    case BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST:
1538
    case BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST:
1539
    case BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_PCREL:
1540
    case BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_PCREL:
1541
    case BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_GOT:
1542
    case BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_GOT:
1543
    case BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
1544
    case BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
1545
    case BFD_RELOC_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
1546
    case BFD_RELOC_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
1547
      special = O_hw0_last;
1548
      break;
1549
 
1550
    case BFD_RELOC_TILEGX_HW1:
1551
    case BFD_RELOC_TILEGX_IMM16_X0_HW1:
1552
    case BFD_RELOC_TILEGX_IMM16_X1_HW1:
1553
    case BFD_RELOC_TILEGX_IMM16_X0_HW1_PCREL:
1554
    case BFD_RELOC_TILEGX_IMM16_X1_HW1_PCREL:
1555
    case BFD_RELOC_TILEGX_IMM16_X0_HW1_GOT:
1556
    case BFD_RELOC_TILEGX_IMM16_X1_HW1_GOT:
1557
    case BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_GD:
1558
    case BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_GD:
1559
    case BFD_RELOC_TILEGX_IMM16_X0_HW1_TLS_IE:
1560
    case BFD_RELOC_TILEGX_IMM16_X1_HW1_TLS_IE:
1561
      special = O_hw1;
1562
      break;
1563
 
1564
    case BFD_RELOC_TILEGX_HW1_LAST:
1565
    case BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST:
1566
    case BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST:
1567
    case BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_PCREL:
1568
    case BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_PCREL:
1569
    case BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_GOT:
1570
    case BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_GOT:
1571
    case BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
1572
    case BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
1573
    case BFD_RELOC_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
1574
    case BFD_RELOC_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
1575
      special = O_hw1_last;
1576
      break;
1577
 
1578
    case BFD_RELOC_TILEGX_HW2:
1579
    case BFD_RELOC_TILEGX_IMM16_X0_HW2:
1580
    case BFD_RELOC_TILEGX_IMM16_X1_HW2:
1581
    case BFD_RELOC_TILEGX_IMM16_X0_HW2_PCREL:
1582
    case BFD_RELOC_TILEGX_IMM16_X1_HW2_PCREL:
1583
    case BFD_RELOC_TILEGX_IMM16_X0_HW2_GOT:
1584
    case BFD_RELOC_TILEGX_IMM16_X1_HW2_GOT:
1585
    case BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_GD:
1586
    case BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_GD:
1587
    case BFD_RELOC_TILEGX_IMM16_X0_HW2_TLS_IE:
1588
    case BFD_RELOC_TILEGX_IMM16_X1_HW2_TLS_IE:
1589
      special = O_hw2;
1590
      break;
1591
 
1592
    case BFD_RELOC_TILEGX_HW2_LAST:
1593
    case BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST:
1594
    case BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST:
1595
    case BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_PCREL:
1596
    case BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_PCREL:
1597
    case BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_GOT:
1598
    case BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_GOT:
1599
    case BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_GD:
1600
    case BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_GD:
1601
    case BFD_RELOC_TILEGX_IMM16_X0_HW2_LAST_TLS_IE:
1602
    case BFD_RELOC_TILEGX_IMM16_X1_HW2_LAST_TLS_IE:
1603
      special = O_hw2_last;
1604
      break;
1605
 
1606
    case BFD_RELOC_TILEGX_HW3:
1607
    case BFD_RELOC_TILEGX_IMM16_X0_HW3:
1608
    case BFD_RELOC_TILEGX_IMM16_X1_HW3:
1609
    case BFD_RELOC_TILEGX_IMM16_X0_HW3_PCREL:
1610
    case BFD_RELOC_TILEGX_IMM16_X1_HW3_PCREL:
1611
    case BFD_RELOC_TILEGX_IMM16_X0_HW3_GOT:
1612
    case BFD_RELOC_TILEGX_IMM16_X1_HW3_GOT:
1613
    case BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_GD:
1614
    case BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_GD:
1615
    case BFD_RELOC_TILEGX_IMM16_X0_HW3_TLS_IE:
1616
    case BFD_RELOC_TILEGX_IMM16_X1_HW3_TLS_IE:
1617
      special = O_hw3;
1618
      break;
1619
 
1620
    default:
1621
      /* Do nothing  */
1622
      break;
1623
    }
1624
 
1625
  if (special != O_illegal)
1626
    {
1627
      *valP = value = apply_special_operator (special, value,
1628
                                              fixP->fx_file, fixP->fx_line);
1629
    }
1630
 
1631
  p = fixP->fx_frag->fr_literal + fixP->fx_where;
1632
 
1633
  operand = fixP->tc_fix_data;
1634
  if (operand != NULL)
1635
    {
1636
      /* It's an instruction operand.  */
1637
      tilegx_bundle_bits bits =
1638
        insert_operand (0, operand, value, fixP->fx_file, fixP->fx_line);
1639
 
1640
      /* Note that we might either be writing out bits for a bundle
1641
         or a static network instruction, which are different sizes, so it's
1642
         important to stop touching memory once we run out of bits.
1643
         ORing in values is OK since we know the existing bits for
1644
         this operand are zero.  */
1645
      for (; bits != 0; bits >>= 8)
1646
        *p++ |= (char)bits;
1647
    }
1648
  else
1649
    {
1650
      /* Some other kind of relocation.  */
1651
      switch (fixP->fx_r_type)
1652
        {
1653
        case BFD_RELOC_8:
1654
        case BFD_RELOC_8_PCREL:
1655
          md_number_to_chars (p, value, 1);
1656
          break;
1657
 
1658
        case BFD_RELOC_16:
1659
        case BFD_RELOC_16_PCREL:
1660
          md_number_to_chars (p, value, 2);
1661
          break;
1662
 
1663
        case BFD_RELOC_32:
1664
        case BFD_RELOC_32_PCREL:
1665
          md_number_to_chars (p, value, 4);
1666
          break;
1667
 
1668
        case BFD_RELOC_64:
1669
        case BFD_RELOC_64_PCREL:
1670
          md_number_to_chars (p, value, 8);
1671
          break;
1672
 
1673
        default:
1674
          /* Leave it for the linker.  */
1675
          return;
1676
        }
1677
    }
1678
 
1679
  fixP->fx_done = 1;
1680
}
1681
 
1682
 
1683
/* Generate the BFD reloc to be stuck in the object file from the
1684
   fixup used internally in the assembler.  */
1685
 
1686
arelent *
1687
tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED, fixS *fixp)
1688
{
1689
  arelent *reloc;
1690
 
1691
  reloc = (arelent *) xmalloc (sizeof (arelent));
1692
  reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1693
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1694
  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1695
 
1696
  /* Make sure none of our internal relocations make it this far.
1697
     They'd better have been fully resolved by this point.  */
1698
  gas_assert ((int) fixp->fx_r_type > 0);
1699
 
1700
  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1701
  if (reloc->howto == NULL)
1702
    {
1703
      as_bad_where (fixp->fx_file, fixp->fx_line,
1704
                    _("cannot represent `%s' relocation in object file"),
1705
                    bfd_get_reloc_code_name (fixp->fx_r_type));
1706
      return NULL;
1707
    }
1708
 
1709
  if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
1710
    {
1711
      as_fatal (_("internal error? cannot generate `%s' relocation (%d, %d)"),
1712
                bfd_get_reloc_code_name (fixp->fx_r_type),
1713
                fixp->fx_pcrel, reloc->howto->pc_relative);
1714
    }
1715
  gas_assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
1716
 
1717
  reloc->addend = fixp->fx_offset;
1718
 
1719
  return reloc;
1720
}
1721
 
1722
 
1723
/* The location from which a PC relative jump should be calculated,
1724
   given a PC relative reloc.  */
1725
 
1726
long
1727
md_pcrel_from (fixS *fixP)
1728
{
1729
  return fixP->fx_frag->fr_address + fixP->fx_where;
1730
}
1731
 
1732
 
1733
/* Return 1 if it's OK to adjust a reloc by replacing the symbol with
1734
   a section symbol plus some offset.  */
1735
int
1736
tilegx_fix_adjustable (fixS *fix)
1737
{
1738
  /* Prevent all adjustments to global symbols  */
1739
  if (S_IS_EXTERNAL (fix->fx_addsy) || S_IS_WEAK (fix->fx_addsy))
1740
    return 0;
1741
 
1742
  return 1;
1743
}
1744
 
1745
 
1746
int
1747
tilegx_unrecognized_line (int ch)
1748
{
1749
  switch (ch)
1750
    {
1751
    case '{':
1752
      if (inside_bundle)
1753
        {
1754
          as_bad (_("Found '{' when already bundling."));
1755
        }
1756
      else
1757
        {
1758
          inside_bundle = 1;
1759
          current_bundle_index = 0;
1760
        }
1761
      return 1;
1762
 
1763
    case '}':
1764
      if (!inside_bundle)
1765
        {
1766
          as_bad (_("Found '}' when not bundling."));
1767
        }
1768
      else
1769
        {
1770
          tilegx_flush_bundle ();
1771
        }
1772
 
1773
      /* Allow '{' to follow on the same line.  We also allow ";;", but that
1774
         happens automatically because ';' is an end of line marker.  */
1775
      SKIP_WHITESPACE ();
1776
      if (input_line_pointer[0] == '{')
1777
        {
1778
          input_line_pointer++;
1779
          return tilegx_unrecognized_line ('{');
1780
        }
1781
 
1782
      demand_empty_rest_of_line ();
1783
      return 1;
1784
 
1785
    default:
1786
      break;
1787
    }
1788
 
1789
  /* Not a valid line.  */
1790
  return 0;
1791
}
1792
 
1793
 
1794
/* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
1795
   of an rs_align_code fragment.  */
1796
 
1797
void
1798
tilegx_handle_align (fragS *fragp)
1799
{
1800
  addressT bytes, fix;
1801
  char *p;
1802
 
1803
  if (fragp->fr_type != rs_align_code)
1804
    return;
1805
 
1806
  bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
1807
  p = fragp->fr_literal + fragp->fr_fix;
1808
  fix = 0;
1809
 
1810
  /* Determine the bits for NOP.  */
1811
  const struct tilegx_opcode *nop_opcode =
1812
    &tilegx_opcodes[TILEGX_OPC_NOP];
1813
  tilegx_bundle_bits nop =
1814
    (  nop_opcode->fixed_bit_values[TILEGX_PIPELINE_X0]
1815
     | nop_opcode->fixed_bit_values[TILEGX_PIPELINE_X1]);
1816
 
1817
  if ((bytes & (TILEGX_BUNDLE_SIZE_IN_BYTES - 1)) != 0)
1818
    {
1819
      fix = bytes & (TILEGX_BUNDLE_SIZE_IN_BYTES - 1);
1820
      memset (p, 0, fix);
1821
      p += fix;
1822
      bytes -= fix;
1823
    }
1824
 
1825
  number_to_chars_littleendian (p, nop, 8);
1826
  fragp->fr_fix += fix;
1827
  fragp->fr_var = TILEGX_BUNDLE_SIZE_IN_BYTES;
1828
}
1829
 
1830
/* Standard calling conventions leave the CFA at SP on entry.  */
1831
void
1832
tilegx_cfi_frame_initial_instructions (void)
1833
{
1834
  cfi_add_CFA_def_cfa_register (54);
1835
}
1836
 
1837
int
1838
tc_tilegx_regname_to_dw2regnum (char *regname)
1839
{
1840
  int i;
1841
  for (i = 0; i < TILEGX_NUM_REGISTERS; i++)
1842
    {
1843
      if (!strcmp (regname, tilegx_register_names[i]))
1844
        return i;
1845
    }
1846
 
1847
  return -1;
1848
}

powered by: WebSVN 2.1.0

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