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 196

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

powered by: WebSVN 2.1.0

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