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

Subversion Repositories open8_urisc

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

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

Line No. Rev Author Line
1 16 khays
/* tc-tic4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
2
   Copyright (C) 1997,1998, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010
3
   Free Software Foundation. Inc.
4
 
5
   Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
6
 
7
   This file is part of GAS, the GNU Assembler.
8
 
9
   GAS is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3, or (at your option)
12
   any later version.
13
 
14
   GAS is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
 
19
   You should have received a copy of the GNU General Public License
20
   along with GAS; see the file COPYING.  If not, write to
21
   the Free Software Foundation, 51 Franklin Street - Fifth Floor,
22
   Boston, MA 02110-1301, USA.  */
23
/*
24
  TODOs:
25
  ------
26
 
27
  o .align cannot handle fill-data-width larger than 0xFF/8-bits. It
28
    should be possible to define a 32-bits pattern.
29
 
30
  o .align fills all section with NOP's when used regardless if has
31
    been used in .text or .data. (However the .align is primarily
32
    intended used in .text sections. If you require something else,
33
    use .align <size>,0x00)
34
 
35
  o .align: Implement a 'bu' insn if the number of nop's exceeds 4
36
    within the align frag. if(fragsize>4words) insert bu fragend+1
37
    first.
38
 
39
  o .usect if has symbol on previous line not implemented
40
 
41
  o .sym, .eos, .stag, .etag, .member not implemented
42
 
43
  o Evaluation of constant floating point expressions (expr.c needs
44
    work!)
45
 
46
  o Support 'abc' constants (that is 0x616263)
47
*/
48
 
49
#include "safe-ctype.h"
50
#include "as.h"
51
#include "opcode/tic4x.h"
52
#include "subsegs.h"
53
#include "obstack.h"
54
 
55
/* OK, we accept a syntax similar to the other well known C30
56
   assembly tools.  With TIC4X_ALT_SYNTAX defined we are more
57
   flexible, allowing a more Unix-like syntax:  `%' in front of
58
   register names, `#' in front of immediate constants, and
59
   not requiring `@' in front of direct addresses.  */
60
 
61
#define TIC4X_ALT_SYNTAX
62
 
63
/* Equal to MAX_PRECISION in atof-ieee.c.  */
64
#define MAX_LITTLENUMS 6        /* (12 bytes) */
65
 
66
/* Handle of the inst mnemonic hash table.  */
67
static struct hash_control *tic4x_op_hash = NULL;
68
 
69
/* Handle asg pseudo.  */
70
static struct hash_control *tic4x_asg_hash = NULL;
71
 
72
static unsigned int tic4x_cpu = 0;        /* Default to TMS320C40.  */
73
static unsigned int tic4x_revision = 0;   /* CPU revision */
74
static unsigned int tic4x_idle2 = 0;      /* Idle2 support */
75
static unsigned int tic4x_lowpower = 0;   /* Lowpower support */
76
static unsigned int tic4x_enhanced = 0;   /* Enhanced opcode support */
77
static unsigned int tic4x_big_model = 0;  /* Default to small memory model.  */
78
static unsigned int tic4x_reg_args = 0;   /* Default to args passed on stack.  */
79
static unsigned long tic4x_oplevel = 0;   /* Opcode level */
80
 
81
#define OPTION_CPU      'm'
82
#define OPTION_BIG      (OPTION_MD_BASE + 1)
83
#define OPTION_SMALL    (OPTION_MD_BASE + 2)
84
#define OPTION_MEMPARM  (OPTION_MD_BASE + 3)
85
#define OPTION_REGPARM  (OPTION_MD_BASE + 4)
86
#define OPTION_IDLE2    (OPTION_MD_BASE + 5)
87
#define OPTION_LOWPOWER (OPTION_MD_BASE + 6)
88
#define OPTION_ENHANCED (OPTION_MD_BASE + 7)
89
#define OPTION_REV      (OPTION_MD_BASE + 8)
90
 
91
CONST char *md_shortopts = "bm:prs";
92
struct option md_longopts[] =
93
{
94
  { "mcpu",   required_argument, NULL, OPTION_CPU },
95
  { "mdsp",   required_argument, NULL, OPTION_CPU },
96
  { "mbig",         no_argument, NULL, OPTION_BIG },
97
  { "msmall",       no_argument, NULL, OPTION_SMALL },
98
  { "mmemparm",     no_argument, NULL, OPTION_MEMPARM },
99
  { "mregparm",     no_argument, NULL, OPTION_REGPARM },
100
  { "midle2",       no_argument, NULL, OPTION_IDLE2 },
101
  { "mlowpower",    no_argument, NULL, OPTION_LOWPOWER },
102
  { "menhanced",    no_argument, NULL, OPTION_ENHANCED },
103
  { "mrev",   required_argument, NULL, OPTION_REV },
104
  { NULL, no_argument, NULL, 0 }
105
};
106
 
107
size_t md_longopts_size = sizeof (md_longopts);
108
 
109
 
110
typedef enum
111
  {
112
    M_UNKNOWN, M_IMMED, M_DIRECT, M_REGISTER, M_INDIRECT,
113
    M_IMMED_F, M_PARALLEL, M_HI
114
  }
115
tic4x_addr_mode_t;
116
 
117
typedef struct tic4x_operand
118
  {
119
    tic4x_addr_mode_t mode;     /* Addressing mode.  */
120
    expressionS expr;           /* Expression.  */
121
    int disp;                   /* Displacement for indirect addressing.  */
122
    int aregno;                 /* Aux. register number.  */
123
    LITTLENUM_TYPE fwords[MAX_LITTLENUMS];      /* Float immed. number.  */
124
  }
125
tic4x_operand_t;
126
 
127
typedef struct tic4x_insn
128
  {
129
    char name[TIC4X_NAME_MAX];  /* Mnemonic of instruction.  */
130
    unsigned int in_use;        /* True if in_use.  */
131
    unsigned int parallel;      /* True if parallel instruction.  */
132
    unsigned int nchars;        /* This is always 4 for the C30.  */
133
    unsigned long opcode;       /* Opcode number.  */
134
    expressionS exp;            /* Expression required for relocation.  */
135
    int reloc;                  /* Relocation type required.  */
136
    int pcrel;                  /* True if relocation PC relative.  */
137
    char *pname;                /* Name of instruction in parallel.  */
138
    unsigned int num_operands;  /* Number of operands in total.  */
139
    tic4x_inst_t *inst;         /* Pointer to first template.  */
140
    tic4x_operand_t operands[TIC4X_OPERANDS_MAX];
141
  }
142
tic4x_insn_t;
143
 
144
static tic4x_insn_t the_insn;   /* Info about our instruction.  */
145
static tic4x_insn_t *insn = &the_insn;
146
 
147
static void tic4x_asg (int);
148
static void tic4x_bss (int);
149
static void tic4x_globl (int);
150
static void tic4x_cons (int);
151
static void tic4x_stringer (int);
152
static void tic4x_eval (int);
153
static void tic4x_newblock (int);
154
static void tic4x_sect (int);
155
static void tic4x_set (int);
156
static void tic4x_usect (int);
157
static void tic4x_version (int);
158
 
159
 
160
const pseudo_typeS
161
  md_pseudo_table[] =
162
{
163
  {"align", s_align_bytes, 32},
164
  {"ascii", tic4x_stringer, 1},
165
  {"asciz", tic4x_stringer, 0},
166
  {"asg", tic4x_asg, 0},
167
  {"block", s_space, 4},
168
  {"byte", tic4x_cons, 1},
169
  {"bss", tic4x_bss, 0},
170
  {"copy", s_include, 0},
171
  {"def", tic4x_globl, 0},
172
  {"equ", tic4x_set, 0},
173
  {"eval", tic4x_eval, 0},
174
  {"global", tic4x_globl, 0},
175
  {"globl", tic4x_globl, 0},
176
  {"hword", tic4x_cons, 2},
177
  {"ieee", float_cons, 'i'},
178
  {"int", tic4x_cons, 4},                /* .int allocates 4 bytes.  */
179
  {"ldouble", float_cons, 'e'},
180
  {"newblock", tic4x_newblock, 0},
181
  {"ref", s_ignore, 0},           /* All undefined treated as external.  */
182
  {"set", tic4x_set, 0},
183
  {"sect", tic4x_sect, 1},       /* Define named section.  */
184
  {"space", s_space, 4},
185
  {"string", tic4x_stringer, 0},
186
  {"usect", tic4x_usect, 0},       /* Reserve space in uninit. named sect.  */
187
  {"version", tic4x_version, 0},
188
  {"word", tic4x_cons, 4},       /* .word allocates 4 bytes.  */
189
  {"xdef", tic4x_globl, 0},
190
  {NULL, 0, 0},
191
};
192
 
193
int md_short_jump_size = 4;
194
int md_long_jump_size = 4;
195
 
196
/* This array holds the chars that always start a comment.  If the
197
   pre-processor is disabled, these aren't very useful.  */
198
#ifdef TIC4X_ALT_SYNTAX
199
const char comment_chars[] = ";!";
200
#else
201
const char comment_chars[] = ";";
202
#endif
203
 
204
/* This array holds the chars that only start a comment at the beginning of
205
   a line.  If the line seems to have the form '# 123 filename'
206
   .line and .file directives will appear in the pre-processed output.
207
   Note that input_file.c hand checks for '#' at the beginning of the
208
   first line of the input file.  This is because the compiler outputs
209
   #NO_APP at the beginning of its output.
210
   Also note that comments like this one will always work.  */
211
const char line_comment_chars[] = "#*";
212
 
213
/* We needed an unused char for line separation to work around the
214
   lack of macros, using sed and such.  */
215
const char line_separator_chars[] = "&";
216
 
217
/* Chars that can be used to separate mant from exp in floating point nums.  */
218
const char EXP_CHARS[] = "eE";
219
 
220
/* Chars that mean this number is a floating point constant.  */
221
/* As in 0f12.456 */
222
/* or    0d1.2345e12 */
223
const char FLT_CHARS[] = "fFilsS";
224
 
225
/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
226
   changed in read.c.  Ideally it shouldn't have to know about it at
227
   all, but nothing is ideal around here.  */
228
 
229
/* Flonums returned here.  */
230
extern FLONUM_TYPE generic_floating_point_number;
231
 
232
/* Precision in LittleNums.  */
233
#define MAX_PRECISION (4)       /* Its a bit overkill for us, but the code
234
                                   requires it... */
235
#define S_PRECISION (1)         /* Short float constants 16-bit.  */
236
#define F_PRECISION (2)         /* Float and double types 32-bit.  */
237
#define E_PRECISION (4)         /* Extended precision, 64-bit (real 40-bit). */
238
#define GUARD (2)
239
 
240
/* Turn generic_floating_point_number into a real short/float/double.  */
241
static int
242
tic4x_gen_to_words (FLONUM_TYPE flonum, LITTLENUM_TYPE *words, int precision)
243
{
244
  int return_value = 0;
245
  LITTLENUM_TYPE *p;            /* Littlenum pointer.  */
246
  int mantissa_bits;            /* Bits in mantissa field.  */
247
  int exponent_bits;            /* Bits in exponent field.  */
248
  int exponent;
249
  unsigned int sone;            /* Scaled one.  */
250
  unsigned int sfract;          /* Scaled fraction.  */
251
  unsigned int smant;           /* Scaled mantissa.  */
252
  unsigned int tmp;
253
  unsigned int mover;           /* Mantissa overflow bits */
254
  unsigned int rbit;            /* Round bit. */
255
  int shift;                    /* Shift count.  */
256
 
257
  /* NOTE: Svein Seldal <Svein@dev.seldal.com>
258
     The code in this function is altered slightly to support floats
259
     with 31-bits mantissas, thus the documentation below may be a
260
     little bit inaccurate.
261
 
262
     By Michael P. Hayes <m.hayes@elec.canterbury.ac.nz>
263
     Here is how a generic floating point number is stored using
264
     flonums (an extension of bignums) where p is a pointer to an
265
     array of LITTLENUMs.
266
 
267
     For example 2e-3 is stored with exp = -4 and
268
     bits[0] = 0x0000
269
     bits[1] = 0x0000
270
     bits[2] = 0x4fde
271
     bits[3] = 0x978d
272
     bits[4] = 0x126e
273
     bits[5] = 0x0083
274
     with low = &bits[2], high = &bits[5], and leader = &bits[5].
275
 
276
     This number can be written as
277
     0x0083126e978d4fde.00000000 * 65536**-4  or
278
     0x0.0083126e978d4fde        * 65536**0   or
279
     0x0.83126e978d4fde          * 2**-8   = 2e-3
280
 
281
     Note that low points to the 65536**0 littlenum (bits[2]) and
282
     leader points to the most significant non-zero littlenum
283
     (bits[5]).
284
 
285
     TMS320C3X floating point numbers are a bit of a strange beast.
286
     The 32-bit flavour has the 8 MSBs representing the exponent in
287
     twos complement format (-128 to +127).  There is then a sign bit
288
     followed by 23 bits of mantissa.  The mantissa is expressed in
289
     twos complement format with the binary point after the most
290
     significant non sign bit.  The bit after the binary point is
291
     suppressed since it is the complement of the sign bit.  The
292
     effective mantissa is thus 24 bits.  Zero is represented by an
293
     exponent of -128.
294
 
295
     The 16-bit flavour has the 4 MSBs representing the exponent in
296
     twos complement format (-8 to +7).  There is then a sign bit
297
     followed by 11 bits of mantissa.  The mantissa is expressed in
298
     twos complement format with the binary point after the most
299
     significant non sign bit.  The bit after the binary point is
300
     suppressed since it is the complement of the sign bit.  The
301
     effective mantissa is thus 12 bits.  Zero is represented by an
302
     exponent of -8.  For example,
303
 
304
     number       norm mant m  x  e  s  i    fraction f
305
     +0.500 =>  1.00000000000 -1 -1  0  1  .00000000000   (1 + 0) * 2^(-1)
306
     +0.999 =>  1.11111111111 -1 -1  0  1  .11111111111   (1 + 0.99) * 2^(-1)
307
     +1.000 =>  1.00000000000  0  0  0  1  .00000000000   (1 + 0) * 2^(0)
308
     +1.500 =>  1.10000000000  0  0  0  1  .10000000000   (1 + 0.5) * 2^(0)
309
     +1.999 =>  1.11111111111  0  0  0  1  .11111111111   (1 + 0.9) * 2^(0)
310
     +2.000 =>  1.00000000000  1  1  0  1  .00000000000   (1 + 0) * 2^(1)
311
     +4.000 =>  1.00000000000  2  2  0  1  .00000000000   (1 + 0) * 2^(2)
312
     -0.500 =>  1.00000000000 -1 -1  1  0  .10000000000   (-2 + 0) * 2^(-2)
313
     -1.000 =>  1.00000000000  0 -1  1  0  .00000000000   (-2 + 0) * 2^(-1)
314
     -1.500 =>  1.10000000000  0  0  1  0  .10000000000   (-2 + 0.5) * 2^(0)
315
     -1.999 =>  1.11111111111  0  0  1  0  .00000000001   (-2 + 0.11) * 2^(0)
316
     -2.000 =>  1.00000000000  1  1  1  0  .00000000000   (-2 + 0) * 2^(0)
317
     -4.000 =>  1.00000000000  2  1  1  0  .00000000000   (-2 + 0) * 2^(1)
318
 
319
     where e is the exponent, s is the sign bit, i is the implied bit,
320
     and f is the fraction stored in the mantissa field.
321
 
322
     num = (1 + f) * 2^x   =  m * 2^e if s = 0
323
     num = (-2 + f) * 2^x  = -m * 2^e if s = 1
324
     where 0 <= f < 1.0  and 1.0 <= m < 2.0
325
 
326
     The fraction (f) and exponent (e) fields for the TMS320C3X format
327
     can be derived from the normalised mantissa (m) and exponent (x) using:
328
 
329
     f = m - 1, e = x       if s = 0
330
     f = 2 - m, e = x       if s = 1 and m != 1.0
331
     f = 0,     e = x - 1   if s = 1 and m = 1.0
332
     f = 0,     e = -8      if m = 0
333
 
334
 
335
     OK, the other issue we have to consider is rounding since the
336
     mantissa has a much higher potential precision than what we can
337
     represent.  To do this we add half the smallest storable fraction.
338
     We then have to renormalise the number to allow for overflow.
339
 
340
     To convert a generic flonum into a TMS320C3X floating point
341
     number, here's what we try to do....
342
 
343
     The first thing is to generate a normalised mantissa (m) where
344
     1.0 <= m < 2 and to convert the exponent from base 16 to base 2.
345
     We desire the binary point to be placed after the most significant
346
     non zero bit.  This process is done in two steps: firstly, the
347
     littlenum with the most significant non zero bit is located (this
348
     is done for us since leader points to this littlenum) and the
349
     binary point (which is currently after the LSB of the littlenum
350
     pointed to by low) is moved to before the MSB of the littlenum
351
     pointed to by leader.  This requires the exponent to be adjusted
352
     by leader - low + 1.  In the earlier example, the new exponent is
353
     thus -4 + (5 - 2 + 1) = 0 (base 65536).  We now need to convert
354
     the exponent to base 2 by multiplying the exponent by 16 (log2
355
     65536).  The exponent base 2 is thus also zero.
356
 
357
     The second step is to hunt for the most significant non zero bit
358
     in the leader littlenum.  We do this by left shifting a copy of
359
     the leader littlenum until bit 16 is set (0x10000) and counting
360
     the number of shifts, S, required.  The number of shifts then has to
361
     be added to correct the exponent (base 2).  For our example, this
362
     will require 9 shifts and thus our normalised exponent (base 2) is
363
 
364
     littlenum is 1, thus requiring 16 shifts.
365
 
366
     We now have to left shift the other littlenums by the same amount,
367
     propagating the shifted bits into the more significant littlenums.
368
     To save a lot of unnecessary shifting we only have to consider
369
     two or three littlenums, since the greatest number of mantissa
370
     bits required is 24 + 1 rounding bit.  While two littlenums
371
     provide 32 bits of precision, the most significant littlenum
372
     may only contain a single significant bit  and thus an extra
373
     littlenum is required.
374
 
375
     Denoting the number of bits in the fraction field as F, we require
376
     G = F + 2 bits (one extra bit is for rounding, the other gets
377
     suppressed).  Say we required S shifts to find the most
378
     significant bit in the leader littlenum, the number of left shifts
379
     required to move this bit into bit position G - 1 is L = G + S - 17.
380
     Note that this shift count may be negative for the short floating
381
     point flavour (where F = 11 and thus G = 13 and potentially S < 3).
382
     If L > 0 we have to shunt the next littlenum into position.  Bit
383
     15 (the MSB) of the next littlenum needs to get moved into position
384
     L - 1 (If L > 15 we need all the bits of this littlenum and
385
     some more from the next one.).  We subtract 16 from L and use this
386
     as the left shift count;  the resultant value we or with the
387
     previous result.  If L > 0, we repeat this operation.   */
388
 
389
  if (precision != S_PRECISION)
390
    words[1] = 0x0000;
391
  if (precision == E_PRECISION)
392
    words[2] = words[3] = 0x0000;
393
 
394
  /* 0.0e0 or NaN seen.  */
395
  if (flonum.low > flonum.leader  /* = 0.0e0 */
396
      || flonum.sign == 0) /* = NaN */
397
    {
398
      if(flonum.sign == 0)
399
        as_bad (_("Nan, using zero."));
400
      words[0] = 0x8000;
401
      return return_value;
402
    }
403
 
404
  if (flonum.sign == 'P')
405
    {
406
      /* +INF:  Replace with maximum float.  */
407
      if (precision == S_PRECISION)
408
        words[0] = 0x77ff;
409
      else
410
        {
411
          words[0] = 0x7f7f;
412
          words[1] = 0xffff;
413
        }
414
      if (precision == E_PRECISION)
415
        {
416
          words[2] = 0x7fff;
417
          words[3] = 0xffff;
418
        }
419
      return return_value;
420
    }
421
  else if (flonum.sign == 'N')
422
    {
423
      /* -INF:  Replace with maximum float.  */
424
      if (precision == S_PRECISION)
425
        words[0] = 0x7800;
426
      else
427
        words[0] = 0x7f80;
428
      if (precision == E_PRECISION)
429
        words[2] = 0x8000;
430
      return return_value;
431
    }
432
 
433
  exponent = (flonum.exponent + flonum.leader - flonum.low + 1) * 16;
434
 
435
  if (!(tmp = *flonum.leader))
436
    abort ();                   /* Hmmm.  */
437
  shift = 0;                     /* Find position of first sig. bit.  */
438
  while (tmp >>= 1)
439
    shift++;
440
  exponent -= (16 - shift);     /* Adjust exponent.  */
441
 
442
  if (precision == S_PRECISION) /* Allow 1 rounding bit.  */
443
    {
444
      exponent_bits = 4;
445
      mantissa_bits = 11;
446
    }
447
  else if(precision == F_PRECISION)
448
    {
449
      exponent_bits = 8;
450
      mantissa_bits = 23;
451
    }
452
  else /* E_PRECISION */
453
    {
454
      exponent_bits = 8;
455
      mantissa_bits = 31;
456
    }
457
 
458
  shift = mantissa_bits - shift;
459
 
460
  smant = 0;
461
  mover = 0;
462
  rbit = 0;
463
  /* Store the mantissa data into smant and the roundbit into rbit */
464
  for (p = flonum.leader; p >= flonum.low && shift > -16; p--)
465
    {
466
      tmp = shift >= 0 ? *p << shift : *p >> -shift;
467
      rbit = shift < 0 ? ((*p >> (-shift-1)) & 0x1) : 0;
468
      smant |= tmp;
469
      shift -= 16;
470
    }
471
 
472
  /* OK, we've got our scaled mantissa so let's round it up */
473
  if(rbit)
474
    {
475
      /* If the mantissa is going to overflow when added, lets store
476
         the extra bit in mover. -- A special case exists when
477
         mantissa_bits is 31 (E_PRECISION). Then the first test cannot
478
         be trusted, as result is host-dependent, thus the second
479
         test. */
480
      if( smant == ((unsigned)(1<<(mantissa_bits+1))-1)
481
          || smant == (unsigned)-1 )  /* This is to catch E_PRECISION cases */
482
        mover=1;
483
      smant++;
484
    }
485
 
486
  /* Get the scaled one value */
487
  sone = (1 << (mantissa_bits));
488
 
489
  /* The number may be unnormalised so renormalise it...  */
490
  if(mover)
491
    {
492
      smant >>= 1;
493
      smant |= sone; /* Insert the bit from mover into smant */
494
      exponent++;
495
    }
496
 
497
  /* The binary point is now between bit positions 11 and 10 or 23 and 22,
498
     i.e., between mantissa_bits - 1 and mantissa_bits - 2 and the
499
     bit at mantissa_bits - 1 should be set.  */
500
  if (!(sone&smant))
501
    abort ();                   /* Ooops.  */
502
 
503
  if (flonum.sign == '+')
504
    sfract = smant - sone;      /* smant - 1.0.  */
505
  else
506
    {
507
      /* This seems to work.  */
508
      if (smant == sone)
509
        {
510
          exponent--;
511
          sfract = 0;
512
        }
513
      else
514
        {
515
          sfract = -smant & (sone-1);   /* 2.0 - smant.  */
516
        }
517
      sfract |= sone;           /* Insert sign bit.  */
518
    }
519
 
520
  if (abs (exponent) >= (1 << (exponent_bits - 1)))
521
    as_bad (_("Cannot represent exponent in %d bits"), exponent_bits);
522
 
523
  /* Force exponent to fit in desired field width.  */
524
  exponent &= (1 << (exponent_bits)) - 1;
525
 
526
  if (precision == E_PRECISION)
527
    {
528
      /* Map the float part first (100% equal format as F_PRECISION) */
529
      words[0]  = exponent << (mantissa_bits+1-24);
530
      words[0] |= sfract >> 24;
531
      words[1]  = sfract >> 8;
532
 
533
      /* Map the mantissa in the next */
534
      words[2]  = sfract >> 16;
535
      words[3]  = sfract & 0xffff;
536
    }
537
  else
538
    {
539
      /* Insert the exponent data into the word */
540
      sfract |= exponent << (mantissa_bits+1);
541
 
542
      if (precision == S_PRECISION)
543
        words[0] = sfract;
544
      else
545
        {
546
          words[0] = sfract >> 16;
547
          words[1] = sfract & 0xffff;
548
        }
549
    }
550
 
551
  return return_value;
552
}
553
 
554
/* Returns pointer past text consumed.  */
555
static char *
556
tic4x_atof (char *str, char what_kind, LITTLENUM_TYPE *words)
557
{
558
  /* Extra bits for zeroed low-order bits.  The 1st MAX_PRECISION are
559
     zeroed, the last contain flonum bits.  */
560
  static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
561
  char *return_value;
562
  /* Number of 16-bit words in the format.  */
563
  int precision;
564
  FLONUM_TYPE save_gen_flonum;
565
 
566
  /* We have to save the generic_floating_point_number because it
567
     contains storage allocation about the array of LITTLENUMs where
568
     the value is actually stored.  We will allocate our own array of
569
     littlenums below, but have to restore the global one on exit.  */
570
  save_gen_flonum = generic_floating_point_number;
571
 
572
  return_value = str;
573
  generic_floating_point_number.low = bits + MAX_PRECISION;
574
  generic_floating_point_number.high = NULL;
575
  generic_floating_point_number.leader = NULL;
576
  generic_floating_point_number.exponent = 0;
577
  generic_floating_point_number.sign = '\0';
578
 
579
  /* Use more LittleNums than seems necessary: the highest flonum may
580
     have 15 leading 0 bits, so could be useless.  */
581
 
582
  memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
583
 
584
  switch (what_kind)
585
    {
586
    case 's':
587
    case 'S':
588
      precision = S_PRECISION;
589
      break;
590
 
591
    case 'd':
592
    case 'D':
593
    case 'f':
594
    case 'F':
595
      precision = F_PRECISION;
596
      break;
597
 
598
    case 'E':
599
    case 'e':
600
      precision = E_PRECISION;
601
      break;
602
 
603
    default:
604
      as_bad (_("Invalid floating point number"));
605
      return (NULL);
606
    }
607
 
608
  generic_floating_point_number.high
609
    = generic_floating_point_number.low + precision - 1 + GUARD;
610
 
611
  if (atof_generic (&return_value, ".", EXP_CHARS,
612
                    &generic_floating_point_number))
613
    {
614
      as_bad (_("Invalid floating point number"));
615
      return (NULL);
616
    }
617
 
618
  tic4x_gen_to_words (generic_floating_point_number,
619
                    words, precision);
620
 
621
  /* Restore the generic_floating_point_number's storage alloc (and
622
     everything else).  */
623
  generic_floating_point_number = save_gen_flonum;
624
 
625
  return return_value;
626
}
627
 
628
static void
629
tic4x_insert_reg (char *regname, int regnum)
630
{
631
  char buf[32];
632
  int i;
633
 
634
  symbol_table_insert (symbol_new (regname, reg_section, (valueT) regnum,
635
                                   &zero_address_frag));
636
  for (i = 0; regname[i]; i++)
637
    buf[i] = ISLOWER (regname[i]) ? TOUPPER (regname[i]) : regname[i];
638
  buf[i] = '\0';
639
 
640
  symbol_table_insert (symbol_new (buf, reg_section, (valueT) regnum,
641
                                   &zero_address_frag));
642
}
643
 
644
static void
645
tic4x_insert_sym (char *symname, int value)
646
{
647
  symbolS *symbolP;
648
 
649
  symbolP = symbol_new (symname, absolute_section,
650
                        (valueT) value, &zero_address_frag);
651
  SF_SET_LOCAL (symbolP);
652
  symbol_table_insert (symbolP);
653
}
654
 
655
static char *
656
tic4x_expression (char *str, expressionS *exp)
657
{
658
  char *s;
659
  char *t;
660
 
661
  t = input_line_pointer;       /* Save line pointer.  */
662
  input_line_pointer = str;
663
  expression (exp);
664
  s = input_line_pointer;
665
  input_line_pointer = t;       /* Restore line pointer.  */
666
  return s;                     /* Return pointer to where parsing stopped.  */
667
}
668
 
669
static char *
670
tic4x_expression_abs (char *str, offsetT *value)
671
{
672
  char *s;
673
  char *t;
674
 
675
  t = input_line_pointer;       /* Save line pointer.  */
676
  input_line_pointer = str;
677
  *value = get_absolute_expression ();
678
  s = input_line_pointer;
679
  input_line_pointer = t;       /* Restore line pointer.  */
680
  return s;
681
}
682
 
683
static void
684
tic4x_emit_char (char c, int b)
685
{
686
  expressionS exp;
687
 
688
  exp.X_op = O_constant;
689
  exp.X_add_number = c;
690
  emit_expr (&exp, b);
691
}
692
 
693
static void
694
tic4x_seg_alloc (char *name ATTRIBUTE_UNUSED,
695
                 segT seg ATTRIBUTE_UNUSED,
696
                 int size,
697
                 symbolS *symbolP)
698
{
699
  /* Note that the size is in words
700
     so we multiply it by 4 to get the number of bytes to allocate.  */
701
 
702
  /* If we have symbol:  .usect  ".fred", size etc.,
703
     the symbol needs to point to the first location reserved
704
     by the pseudo op.  */
705
 
706
  if (size)
707
    {
708
      char *p;
709
 
710
      p = frag_var (rs_fill, 1, 1, (relax_substateT) 0,
711
                    (symbolS *) symbolP,
712
                    size * OCTETS_PER_BYTE, (char *) 0);
713
      *p = 0;
714
    }
715
}
716
 
717
/* .asg ["]character-string["], symbol */
718
static void
719
tic4x_asg (int x ATTRIBUTE_UNUSED)
720
{
721
  char c;
722
  char *name;
723
  char *str;
724
  char *tmp;
725
 
726
  SKIP_WHITESPACE ();
727
  str = input_line_pointer;
728
 
729
  /* Skip string expression.  */
730
  while (*input_line_pointer != ',' && *input_line_pointer)
731
    input_line_pointer++;
732
  if (*input_line_pointer != ',')
733
    {
734
      as_bad (_("Comma expected\n"));
735
      return;
736
    }
737
  *input_line_pointer++ = '\0';
738
  name = input_line_pointer;
739
  c = get_symbol_end ();        /* Get terminator.  */
740
  tmp = xmalloc (strlen (str) + 1);
741
  strcpy (tmp, str);
742
  str = tmp;
743
  tmp = xmalloc (strlen (name) + 1);
744
  strcpy (tmp, name);
745
  name = tmp;
746
  if (hash_find (tic4x_asg_hash, name))
747
    hash_replace (tic4x_asg_hash, name, (void *) str);
748
  else
749
    hash_insert (tic4x_asg_hash, name, (void *) str);
750
  *input_line_pointer = c;
751
  demand_empty_rest_of_line ();
752
}
753
 
754
/* .bss symbol, size  */
755
static void
756
tic4x_bss (int x ATTRIBUTE_UNUSED)
757
{
758
  char c;
759
  char *name;
760
  char *p;
761
  offsetT size;
762
  segT current_seg;
763
  subsegT current_subseg;
764
  symbolS *symbolP;
765
 
766
  current_seg = now_seg;        /* Save current seg.  */
767
  current_subseg = now_subseg;  /* Save current subseg.  */
768
 
769
  SKIP_WHITESPACE ();
770
  name = input_line_pointer;
771
  c = get_symbol_end ();        /* Get terminator.  */
772
  if (c != ',')
773
    {
774
      as_bad (_(".bss size argument missing\n"));
775
      return;
776
    }
777
 
778
  input_line_pointer =
779
    tic4x_expression_abs (++input_line_pointer, &size);
780
  if (size < 0)
781
    {
782
      as_bad (_(".bss size %ld < 0!"), (long) size);
783
      return;
784
    }
785
  subseg_set (bss_section, 0);
786
  symbolP = symbol_find_or_make (name);
787
 
788
  if (S_GET_SEGMENT (symbolP) == bss_section)
789
    symbol_get_frag (symbolP)->fr_symbol = 0;
790
 
791
  symbol_set_frag (symbolP, frag_now);
792
 
793
  p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
794
                size * OCTETS_PER_BYTE, (char *) 0);
795
  *p = 0;                        /* Fill char.  */
796
 
797
  S_SET_SEGMENT (symbolP, bss_section);
798
 
799
  /* The symbol may already have been created with a preceding
800
     ".globl" directive -- be careful not to step on storage class
801
     in that case.  Otherwise, set it to static.  */
802
  if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
803
    S_SET_STORAGE_CLASS (symbolP, C_STAT);
804
 
805
  subseg_set (current_seg, current_subseg); /* Restore current seg.  */
806
  demand_empty_rest_of_line ();
807
}
808
 
809
static void
810
tic4x_globl (int ignore ATTRIBUTE_UNUSED)
811
{
812
  char *name;
813
  int c;
814
  symbolS *symbolP;
815
 
816
  do
817
    {
818
      name = input_line_pointer;
819
      c = get_symbol_end ();
820
      symbolP = symbol_find_or_make (name);
821
      *input_line_pointer = c;
822
      SKIP_WHITESPACE ();
823
      S_SET_STORAGE_CLASS (symbolP, C_EXT);
824
      S_SET_EXTERNAL (symbolP);
825
      if (c == ',')
826
        {
827
          input_line_pointer++;
828
          SKIP_WHITESPACE ();
829
          if (*input_line_pointer == '\n')
830
            c = '\n';
831
        }
832
    }
833
  while (c == ',');
834
 
835
  demand_empty_rest_of_line ();
836
}
837
 
838
/* Handle .byte, .word. .int, .long */
839
static void
840
tic4x_cons (int bytes)
841
{
842
  register unsigned int c;
843
  do
844
    {
845
      SKIP_WHITESPACE ();
846
      if (*input_line_pointer == '"')
847
        {
848
          input_line_pointer++;
849
          while (is_a_char (c = next_char_of_string ()))
850
            tic4x_emit_char (c, 4);
851
          know (input_line_pointer[-1] == '\"');
852
        }
853
      else
854
        {
855
          expressionS exp;
856
 
857
          input_line_pointer = tic4x_expression (input_line_pointer, &exp);
858
          if (exp.X_op == O_constant)
859
            {
860
              switch (bytes)
861
                {
862
                case 1:
863
                  exp.X_add_number &= 255;
864
                  break;
865
                case 2:
866
                  exp.X_add_number &= 65535;
867
                  break;
868
                }
869
            }
870
          /* Perhaps we should disallow .byte and .hword with
871
             a non constant expression that will require relocation.  */
872
          emit_expr (&exp, 4);
873
        }
874
    }
875
  while (*input_line_pointer++ == ',');
876
 
877
  input_line_pointer--;         /* Put terminator back into stream.  */
878
  demand_empty_rest_of_line ();
879
}
880
 
881
/* Handle .ascii, .asciz, .string */
882
static void
883
tic4x_stringer (int append_zero)
884
{
885
  int bytes;
886
  register unsigned int c;
887
 
888
  bytes = 0;
889
  do
890
    {
891
      SKIP_WHITESPACE ();
892
      if (*input_line_pointer == '"')
893
        {
894
          input_line_pointer++;
895
          while (is_a_char (c = next_char_of_string ()))
896
            {
897
              tic4x_emit_char (c, 1);
898
              bytes++;
899
            }
900
 
901
          if (append_zero)
902
            {
903
              tic4x_emit_char (c, 1);
904
              bytes++;
905
            }
906
 
907
          know (input_line_pointer[-1] == '\"');
908
        }
909
      else
910
        {
911
          expressionS exp;
912
 
913
          input_line_pointer = tic4x_expression (input_line_pointer, &exp);
914
          if (exp.X_op != O_constant)
915
            {
916
              as_bad (_("Non-constant symbols not allowed\n"));
917
              return;
918
            }
919
          exp.X_add_number &= 255; /* Limit numeber to 8-bit */
920
          emit_expr (&exp, 1);
921
          bytes++;
922
        }
923
    }
924
  while (*input_line_pointer++ == ',');
925
 
926
  /* Fill out the rest of the expression with 0's to fill up a full word */
927
  if ( bytes&0x3 )
928
    tic4x_emit_char (0, 4-(bytes&0x3));
929
 
930
  input_line_pointer--;         /* Put terminator back into stream.  */
931
  demand_empty_rest_of_line ();
932
}
933
 
934
/* .eval expression, symbol */
935
static void
936
tic4x_eval (int x ATTRIBUTE_UNUSED)
937
{
938
  char c;
939
  offsetT value;
940
  char *name;
941
 
942
  SKIP_WHITESPACE ();
943
  input_line_pointer =
944
    tic4x_expression_abs (input_line_pointer, &value);
945
  if (*input_line_pointer++ != ',')
946
    {
947
      as_bad (_("Symbol missing\n"));
948
      return;
949
    }
950
  name = input_line_pointer;
951
  c = get_symbol_end ();        /* Get terminator.  */
952
  tic4x_insert_sym (name, value);
953
  *input_line_pointer++ = c;
954
  demand_empty_rest_of_line ();
955
}
956
 
957
/* Reset local labels.  */
958
static void
959
tic4x_newblock (int x ATTRIBUTE_UNUSED)
960
{
961
  dollar_label_clear ();
962
}
963
 
964
/* .sect "section-name" [, value] */
965
/* .sect ["]section-name[:subsection-name]["] [, value] */
966
static void
967
tic4x_sect (int x ATTRIBUTE_UNUSED)
968
{
969
  char c;
970
  char *section_name;
971
  char *name;
972
  segT seg;
973
  offsetT num;
974
 
975
  SKIP_WHITESPACE ();
976
  if (*input_line_pointer == '"')
977
    input_line_pointer++;
978
  section_name = input_line_pointer;
979
  c = get_symbol_end ();        /* Get terminator.  */
980
  input_line_pointer++;         /* Skip null symbol terminator.  */
981
  name = xmalloc (input_line_pointer - section_name + 1);
982
  strcpy (name, section_name);
983
 
984
  /* TI C from version 5.0 allows a section name to contain a
985
     subsection name as well. The subsection name is separated by a
986
     ':' from the section name.  Currently we scan the subsection
987
     name and discard it.
988
     Volker Kuhlmann  <v.kuhlmann@elec.canterbury.ac.nz>.  */
989
  if (c == ':')
990
    {
991
      c = get_symbol_end ();    /* Get terminator.  */
992
      input_line_pointer++;     /* Skip null symbol terminator.  */
993
      as_warn (_(".sect: subsection name ignored"));
994
    }
995
 
996
  /* We might still have a '"' to discard, but the character after a
997
     symbol name will be overwritten with a \0 by get_symbol_end()
998
     [VK].  */
999
 
1000
  if (c == ',')
1001
    input_line_pointer =
1002
      tic4x_expression_abs (input_line_pointer, &num);
1003
  else if (*input_line_pointer == ',')
1004
    {
1005
      input_line_pointer =
1006
        tic4x_expression_abs (++input_line_pointer, &num);
1007
    }
1008
  else
1009
    num = 0;
1010
 
1011
  seg = subseg_new (name, num);
1012
  if (line_label != NULL)
1013
    {
1014
      S_SET_SEGMENT (line_label, seg);
1015
      symbol_set_frag (line_label, frag_now);
1016
    }
1017
 
1018
  if (bfd_get_section_flags (stdoutput, seg) == SEC_NO_FLAGS)
1019
    {
1020
      if (!bfd_set_section_flags (stdoutput, seg, SEC_DATA))
1021
        as_warn (_("Error setting flags for \"%s\": %s"), name,
1022
                 bfd_errmsg (bfd_get_error ()));
1023
    }
1024
 
1025
  /* If the last character overwritten by get_symbol_end() was an
1026
     end-of-line, we must restore it or the end of the line will not be
1027
     recognised and scanning extends into the next line, stopping with
1028
     an error (blame Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>
1029
     if this is not true).  */
1030
  if (is_end_of_line[(unsigned char) c])
1031
    *(--input_line_pointer) = c;
1032
 
1033
  demand_empty_rest_of_line ();
1034
}
1035
 
1036
/* symbol[:] .set value  or  .set symbol, value */
1037
static void
1038
tic4x_set (int x ATTRIBUTE_UNUSED)
1039
{
1040
  symbolS *symbolP;
1041
 
1042
  SKIP_WHITESPACE ();
1043
  if ((symbolP = line_label) == NULL)
1044
    {
1045
      char c;
1046
      char *name;
1047
 
1048
      name = input_line_pointer;
1049
      c = get_symbol_end ();    /* Get terminator.  */
1050
      if (c != ',')
1051
        {
1052
          as_bad (_(".set syntax invalid\n"));
1053
          ignore_rest_of_line ();
1054
          return;
1055
        }
1056
      ++input_line_pointer;
1057
      symbolP = symbol_find_or_make (name);
1058
    }
1059
  else
1060
    symbol_table_insert (symbolP);
1061
 
1062
  pseudo_set (symbolP);
1063
  demand_empty_rest_of_line ();
1064
}
1065
 
1066
/* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
1067
static void
1068
tic4x_usect (int x ATTRIBUTE_UNUSED)
1069
{
1070
  char c;
1071
  char *name;
1072
  char *section_name;
1073
  segT seg;
1074
  offsetT size, alignment_flag;
1075
  segT current_seg;
1076
  subsegT current_subseg;
1077
 
1078
  current_seg = now_seg;        /* save current seg.  */
1079
  current_subseg = now_subseg;  /* save current subseg.  */
1080
 
1081
  SKIP_WHITESPACE ();
1082
  if (*input_line_pointer == '"')
1083
    input_line_pointer++;
1084
  section_name = input_line_pointer;
1085
  c = get_symbol_end ();        /* Get terminator.  */
1086
  input_line_pointer++;         /* Skip null symbol terminator.  */
1087
  name = xmalloc (input_line_pointer - section_name + 1);
1088
  strcpy (name, section_name);
1089
 
1090
  if (c == ',')
1091
    input_line_pointer =
1092
      tic4x_expression_abs (input_line_pointer, &size);
1093
  else if (*input_line_pointer == ',')
1094
    {
1095
      input_line_pointer =
1096
        tic4x_expression_abs (++input_line_pointer, &size);
1097
    }
1098
  else
1099
    size = 0;
1100
 
1101
  /* Read a possibly present third argument (alignment flag) [VK].  */
1102
  if (*input_line_pointer == ',')
1103
    {
1104
      input_line_pointer =
1105
        tic4x_expression_abs (++input_line_pointer, &alignment_flag);
1106
    }
1107
  else
1108
    alignment_flag = 0;
1109
  if (alignment_flag)
1110
    as_warn (_(".usect: non-zero alignment flag ignored"));
1111
 
1112
  seg = subseg_new (name, 0);
1113
  if (line_label != NULL)
1114
    {
1115
      S_SET_SEGMENT (line_label, seg);
1116
      symbol_set_frag (line_label, frag_now);
1117
      S_SET_VALUE (line_label, frag_now_fix ());
1118
    }
1119
  seg_info (seg)->bss = 1;      /* Uninitialised data.  */
1120
  if (!bfd_set_section_flags (stdoutput, seg, SEC_ALLOC))
1121
    as_warn (_("Error setting flags for \"%s\": %s"), name,
1122
             bfd_errmsg (bfd_get_error ()));
1123
  tic4x_seg_alloc (name, seg, size, line_label);
1124
 
1125
  if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
1126
    S_SET_STORAGE_CLASS (line_label, C_STAT);
1127
 
1128
  subseg_set (current_seg, current_subseg);     /* Restore current seg.  */
1129
  demand_empty_rest_of_line ();
1130
}
1131
 
1132
/* .version cpu-version.  */
1133
static void
1134
tic4x_version (int x ATTRIBUTE_UNUSED)
1135
{
1136
  offsetT temp;
1137
 
1138
  input_line_pointer =
1139
    tic4x_expression_abs (input_line_pointer, &temp);
1140
  if (!IS_CPU_TIC3X (temp) && !IS_CPU_TIC4X (temp))
1141
    as_bad (_("This assembler does not support processor generation %ld"),
1142
            (long) temp);
1143
 
1144
  if (tic4x_cpu && temp != (offsetT) tic4x_cpu)
1145
    as_warn (_("Changing processor generation on fly not supported..."));
1146
  tic4x_cpu = temp;
1147
  demand_empty_rest_of_line ();
1148
}
1149
 
1150
static void
1151
tic4x_init_regtable (void)
1152
{
1153
  unsigned int i;
1154
 
1155
  for (i = 0; i < tic3x_num_registers; i++)
1156
    tic4x_insert_reg (tic3x_registers[i].name,
1157
                    tic3x_registers[i].regno);
1158
 
1159
  if (IS_CPU_TIC4X (tic4x_cpu))
1160
    {
1161
      /* Add additional Tic4x registers, overriding some C3x ones.  */
1162
      for (i = 0; i < tic4x_num_registers; i++)
1163
        tic4x_insert_reg (tic4x_registers[i].name,
1164
                        tic4x_registers[i].regno);
1165
    }
1166
}
1167
 
1168
static void
1169
tic4x_init_symbols (void)
1170
{
1171
  /* The TI tools accept case insensitive versions of these symbols,
1172
     we don't !
1173
 
1174
     For TI C/Asm 5.0
1175
 
1176
     .TMS320xx       30,31,32,40,or 44       set according to -v flag
1177
     .C3X or .C3x    1 or 0                  1 if -v30,-v31,or -v32
1178
     .C30            1 or 0                  1 if -v30
1179
     .C31            1 or 0                  1 if -v31
1180
     .C32            1 or 0                  1 if -v32
1181
     .C4X or .C4x    1 or 0                  1 if -v40, or -v44
1182
     .C40            1 or 0                  1 if -v40
1183
     .C44            1 or 0                  1 if -v44
1184
 
1185
     .REGPARM 1 or 0                  1 if -mr option used
1186
     .BIGMODEL        1 or 0                  1 if -mb option used
1187
 
1188
     These symbols are currently supported but will be removed in a
1189
     later version:
1190
     .TMS320C30      1 or 0                  1 if -v30,-v31,or -v32
1191
     .TMS320C31      1 or 0                  1 if -v31
1192
     .TMS320C32      1 or 0                  1 if -v32
1193
     .TMS320C40      1 or 0                  1 if -v40, or -v44
1194
     .TMS320C44      1 or 0                  1 if -v44
1195
 
1196
     Source: TI: TMS320C3x/C4x Assembly Language Tools User's Guide,
1197
     1997, SPRU035C, p. 3-17/3-18.  */
1198
  tic4x_insert_sym (".REGPARM", tic4x_reg_args);
1199
  tic4x_insert_sym (".MEMPARM", !tic4x_reg_args);
1200
  tic4x_insert_sym (".BIGMODEL", tic4x_big_model);
1201
  tic4x_insert_sym (".C30INTERRUPT", 0);
1202
  tic4x_insert_sym (".TMS320xx", tic4x_cpu == 0 ? 40 : tic4x_cpu);
1203
  tic4x_insert_sym (".C3X", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1204
  tic4x_insert_sym (".C3x", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1205
  tic4x_insert_sym (".C4X", tic4x_cpu == 0 || tic4x_cpu == 40 || tic4x_cpu == 44);
1206
  tic4x_insert_sym (".C4x", tic4x_cpu == 0 || tic4x_cpu == 40 || tic4x_cpu == 44);
1207
  /* Do we need to have the following symbols also in lower case?  */
1208
  tic4x_insert_sym (".TMS320C30", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1209
  tic4x_insert_sym (".tms320C30", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1210
  tic4x_insert_sym (".TMS320C31", tic4x_cpu == 31);
1211
  tic4x_insert_sym (".tms320C31", tic4x_cpu == 31);
1212
  tic4x_insert_sym (".TMS320C32", tic4x_cpu == 32);
1213
  tic4x_insert_sym (".tms320C32", tic4x_cpu == 32);
1214
  tic4x_insert_sym (".TMS320C33", tic4x_cpu == 33);
1215
  tic4x_insert_sym (".tms320C33", tic4x_cpu == 33);
1216
  tic4x_insert_sym (".TMS320C40", tic4x_cpu == 40 || tic4x_cpu == 44 || tic4x_cpu == 0);
1217
  tic4x_insert_sym (".tms320C40", tic4x_cpu == 40 || tic4x_cpu == 44 || tic4x_cpu == 0);
1218
  tic4x_insert_sym (".TMS320C44", tic4x_cpu == 44);
1219
  tic4x_insert_sym (".tms320C44", tic4x_cpu == 44);
1220
  tic4x_insert_sym (".TMX320C40", 0);    /* C40 first pass silicon ?  */
1221
  tic4x_insert_sym (".tmx320C40", 0);
1222
}
1223
 
1224
/* Insert a new instruction template into hash table.  */
1225
static int
1226
tic4x_inst_insert (const tic4x_inst_t *inst)
1227
{
1228
  static char prev_name[16];
1229
  const char *retval = NULL;
1230
 
1231
  /* Only insert the first name if have several similar entries.  */
1232
  if (!strcmp (inst->name, prev_name) || inst->name[0] == '\0')
1233
    return 1;
1234
 
1235
  retval = hash_insert (tic4x_op_hash, inst->name, (void *) inst);
1236
  if (retval != NULL)
1237
    fprintf (stderr, "internal error: can't hash `%s': %s\n",
1238
             inst->name, retval);
1239
  else
1240
    strcpy (prev_name, inst->name);
1241
  return retval == NULL;
1242
}
1243
 
1244
/* Make a new instruction template.  */
1245
static tic4x_inst_t *
1246
tic4x_inst_make (char *name, unsigned long opcode, char *args)
1247
{
1248
  static tic4x_inst_t *insts = NULL;
1249
  static char *names = NULL;
1250
  static int iindex = 0;
1251
 
1252
  if (insts == NULL)
1253
    {
1254
      /* Allocate memory to store name strings.  */
1255
      names = (char *) xmalloc (sizeof (char) * 8192);
1256
      /* Allocate memory for additional insts.  */
1257
      insts = (tic4x_inst_t *)
1258
        xmalloc (sizeof (tic4x_inst_t) * 1024);
1259
    }
1260
  insts[iindex].name = names;
1261
  insts[iindex].opcode = opcode;
1262
  insts[iindex].opmask = 0xffffffff;
1263
  insts[iindex].args = args;
1264
  iindex++;
1265
 
1266
  do
1267
    *names++ = *name++;
1268
  while (*name);
1269
  *names++ = '\0';
1270
 
1271
  return &insts[iindex - 1];
1272
}
1273
 
1274
/* Add instruction template, creating dynamic templates as required.  */
1275
static int
1276
tic4x_inst_add (const tic4x_inst_t *insts)
1277
{
1278
  char *s = insts->name;
1279
  char *d;
1280
  unsigned int i;
1281
  int ok = 1;
1282
  char name[16];
1283
 
1284
  d = name;
1285
 
1286
  /* We do not care about INSNs that is not a part of our
1287
     oplevel setting.  */
1288
  if ((insts->oplevel & tic4x_oplevel) == 0)
1289
    return ok;
1290
 
1291
  while (1)
1292
    {
1293
      switch (*s)
1294
        {
1295
        case 'B':
1296
        case 'C':
1297
          /* Dynamically create all the conditional insts.  */
1298
          for (i = 0; i < tic4x_num_conds; i++)
1299
            {
1300
              tic4x_inst_t *inst;
1301
              int k = 0;
1302
              char *c = tic4x_conds[i].name;
1303
              char *e = d;
1304
 
1305
              while (*c)
1306
                *e++ = *c++;
1307
              c = s + 1;
1308
              while (*c)
1309
                *e++ = *c++;
1310
              *e = '\0';
1311
 
1312
              /* If instruction found then have already processed it.  */
1313
              if (hash_find (tic4x_op_hash, name))
1314
                return 1;
1315
 
1316
              do
1317
                {
1318
                  inst = tic4x_inst_make (name, insts[k].opcode +
1319
                                        (tic4x_conds[i].cond <<
1320
                                         (*s == 'B' ? 16 : 23)),
1321
                                        insts[k].args);
1322
                  if (k == 0)    /* Save strcmp() with following func.  */
1323
                    ok &= tic4x_inst_insert (inst);
1324
                  k++;
1325
                }
1326
              while (!strcmp (insts->name,
1327
                              insts[k].name));
1328
            }
1329
          return ok;
1330
          break;
1331
 
1332
        case '\0':
1333
          return tic4x_inst_insert (insts);
1334
          break;
1335
 
1336
        default:
1337
          *d++ = *s++;
1338
          break;
1339
        }
1340
    }
1341
}
1342
 
1343
/* This function is called once, at assembler startup time.  It should
1344
   set up all the tables, etc., that the MD part of the assembler will
1345
   need.  */
1346
void
1347
md_begin (void)
1348
{
1349
  int ok = 1;
1350
  unsigned int i;
1351
 
1352
  /* Setup the proper opcode level according to the
1353
     commandline parameters */
1354
  tic4x_oplevel = OP_C3X;
1355
 
1356
  if ( IS_CPU_TIC4X(tic4x_cpu) )
1357
    tic4x_oplevel |= OP_C4X;
1358
 
1359
  if ( (   tic4x_cpu == 31 && tic4x_revision >= 6)
1360
       || (tic4x_cpu == 32 && tic4x_revision >= 2)
1361
       || (tic4x_cpu == 33)
1362
       || tic4x_enhanced )
1363
    tic4x_oplevel |= OP_ENH;
1364
 
1365
  if ( (   tic4x_cpu == 30 && tic4x_revision >= 7)
1366
       || (tic4x_cpu == 31 && tic4x_revision >= 5)
1367
       || (tic4x_cpu == 32)
1368
       || tic4x_lowpower )
1369
    tic4x_oplevel |= OP_LPWR;
1370
 
1371
  if ( (   tic4x_cpu == 30 && tic4x_revision >= 7)
1372
       || (tic4x_cpu == 31 && tic4x_revision >= 5)
1373
       || (tic4x_cpu == 32)
1374
       || (tic4x_cpu == 33)
1375
       || (tic4x_cpu == 40 && tic4x_revision >= 5)
1376
       || (tic4x_cpu == 44)
1377
       || tic4x_idle2 )
1378
    tic4x_oplevel |= OP_IDLE2;
1379
 
1380
  /* Create hash table for mnemonics.  */
1381
  tic4x_op_hash = hash_new ();
1382
 
1383
  /* Create hash table for asg pseudo.  */
1384
  tic4x_asg_hash = hash_new ();
1385
 
1386
  /* Add mnemonics to hash table, expanding conditional mnemonics on fly.  */
1387
  for (i = 0; i < tic4x_num_insts; i++)
1388
    ok &= tic4x_inst_add (tic4x_insts + i);
1389
 
1390
  /* Create dummy inst to avoid errors accessing end of table.  */
1391
  tic4x_inst_make ("", 0, "");
1392
 
1393
  if (!ok)
1394
    as_fatal ("Broken assembler.  No assembly attempted.");
1395
 
1396
  /* Add registers to symbol table.  */
1397
  tic4x_init_regtable ();
1398
 
1399
  /* Add predefined symbols to symbol table.  */
1400
  tic4x_init_symbols ();
1401
}
1402
 
1403
void
1404
tic4x_end (void)
1405
{
1406
  bfd_set_arch_mach (stdoutput, bfd_arch_tic4x,
1407
                     IS_CPU_TIC4X (tic4x_cpu) ? bfd_mach_tic4x : bfd_mach_tic3x);
1408
}
1409
 
1410
static int
1411
tic4x_indirect_parse (tic4x_operand_t *operand,
1412
                      const tic4x_indirect_t *indirect)
1413
{
1414
  char *n = indirect->name;
1415
  char *s = input_line_pointer;
1416
  char *b;
1417
  symbolS *symbolP;
1418
  char name[32];
1419
 
1420
  operand->disp = 0;
1421
  for (; *n; n++)
1422
    {
1423
      switch (*n)
1424
        {
1425
        case 'a':               /* Need to match aux register.  */
1426
          b = name;
1427
#ifdef TIC4X_ALT_SYNTAX
1428
          if (*s == '%')
1429
            s++;
1430
#endif
1431
          while (ISALNUM (*s))
1432
            *b++ = *s++;
1433
          *b++ = '\0';
1434
          if (!(symbolP = symbol_find (name)))
1435
            return 0;
1436
 
1437
          if (S_GET_SEGMENT (symbolP) != reg_section)
1438
            return 0;
1439
 
1440
          operand->aregno = S_GET_VALUE (symbolP);
1441
          if (operand->aregno >= REG_AR0 && operand->aregno <= REG_AR7)
1442
            break;
1443
 
1444
          as_bad (_("Auxiliary register AR0--AR7 required for indirect"));
1445
          return -1;
1446
 
1447
        case 'd':               /* Need to match constant for disp.  */
1448
#ifdef TIC4X_ALT_SYNTAX
1449
          if (*s == '%')        /* expr() will die if we don't skip this.  */
1450
            s++;
1451
#endif
1452
          s = tic4x_expression (s, &operand->expr);
1453
          if (operand->expr.X_op != O_constant)
1454
            return 0;
1455
          operand->disp = operand->expr.X_add_number;
1456
          if (operand->disp < 0 || operand->disp > 255)
1457
            {
1458
              as_bad (_("Bad displacement %d (require 0--255)\n"),
1459
                      operand->disp);
1460
              return -1;
1461
            }
1462
          break;
1463
 
1464
        case 'y':               /* Need to match IR0.  */
1465
        case 'z':               /* Need to match IR1.  */
1466
#ifdef TIC4X_ALT_SYNTAX
1467
          if (*s == '%')
1468
            s++;
1469
#endif
1470
          s = tic4x_expression (s, &operand->expr);
1471
          if (operand->expr.X_op != O_register)
1472
            return 0;
1473
          if (operand->expr.X_add_number != REG_IR0
1474
              && operand->expr.X_add_number != REG_IR1)
1475
            {
1476
              as_bad (_("Index register IR0,IR1 required for displacement"));
1477
              return -1;
1478
            }
1479
 
1480
          if (*n == 'y' && operand->expr.X_add_number == REG_IR0)
1481
            break;
1482
          if (*n == 'z' && operand->expr.X_add_number == REG_IR1)
1483
            break;
1484
          return 0;
1485
 
1486
        case '(':
1487
          if (*s != '(')        /* No displacement, assume to be 1.  */
1488
            {
1489
              operand->disp = 1;
1490
              while (*n != ')')
1491
                n++;
1492
            }
1493
          else
1494
            s++;
1495
          break;
1496
 
1497
        default:
1498
          if (TOLOWER (*s) != *n)
1499
            return 0;
1500
          s++;
1501
        }
1502
    }
1503
  if (*s != ' ' && *s != ',' && *s != '\0')
1504
    return 0;
1505
  input_line_pointer = s;
1506
  return 1;
1507
}
1508
 
1509
static char *
1510
tic4x_operand_parse (char *s, tic4x_operand_t *operand)
1511
{
1512
  unsigned int i;
1513
  char c;
1514
  int ret;
1515
  expressionS *exp = &operand->expr;
1516
  char *save = input_line_pointer;
1517
  char *str;
1518
  char *new_pointer;
1519
  struct hash_entry *entry = NULL;
1520
 
1521
  input_line_pointer = s;
1522
  SKIP_WHITESPACE ();
1523
 
1524
  str = input_line_pointer;
1525
  c = get_symbol_end ();        /* Get terminator.  */
1526
  new_pointer = input_line_pointer;
1527
  if (strlen (str) && (entry = hash_find (tic4x_asg_hash, str)) != NULL)
1528
    {
1529
      *input_line_pointer = c;
1530
      input_line_pointer = (char *) entry;
1531
    }
1532
  else
1533
    {
1534
      *input_line_pointer = c;
1535
      input_line_pointer = str;
1536
    }
1537
 
1538
  operand->mode = M_UNKNOWN;
1539
  switch (*input_line_pointer)
1540
    {
1541
#ifdef TIC4X_ALT_SYNTAX
1542
    case '%':
1543
      input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1544
      if (exp->X_op != O_register)
1545
        as_bad (_("Expecting a register name"));
1546
      operand->mode = M_REGISTER;
1547
      break;
1548
 
1549
    case '^':
1550
      /* Denotes high 16 bits.  */
1551
      input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1552
      if (exp->X_op == O_constant)
1553
        operand->mode = M_IMMED;
1554
      else if (exp->X_op == O_big)
1555
        {
1556
          if (exp->X_add_number)
1557
            as_bad (_("Number too large"));     /* bignum required */
1558
          else
1559
            {
1560
              tic4x_gen_to_words (generic_floating_point_number,
1561
                                operand->fwords, S_PRECISION);
1562
              operand->mode = M_IMMED_F;
1563
            }
1564
        }
1565
      /* Allow ori ^foo, ar0 to be equivalent to ldi .hi.foo, ar0  */
1566
      /* WARNING : The TI C40 assembler cannot do this.  */
1567
      else if (exp->X_op == O_symbol)
1568
        {
1569
          operand->mode = M_HI;
1570
          break;
1571
        }
1572
 
1573
    case '#':
1574
      input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1575
      if (exp->X_op == O_constant)
1576
        operand->mode = M_IMMED;
1577
      else if (exp->X_op == O_big)
1578
        {
1579
          if (exp->X_add_number > 0)
1580
            as_bad (_("Number too large"));     /* bignum required.  */
1581
          else
1582
            {
1583
              tic4x_gen_to_words (generic_floating_point_number,
1584
                                operand->fwords, S_PRECISION);
1585
              operand->mode = M_IMMED_F;
1586
            }
1587
        }
1588
      /* Allow ori foo, ar0 to be equivalent to ldi .lo.foo, ar0  */
1589
      /* WARNING : The TI C40 assembler cannot do this.  */
1590
      else if (exp->X_op == O_symbol)
1591
        {
1592
          operand->mode = M_IMMED;
1593
          break;
1594
        }
1595
 
1596
      else
1597
        as_bad (_("Expecting a constant value"));
1598
      break;
1599
    case '\\':
1600
#endif
1601
    case '@':
1602
      input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1603
      if (exp->X_op != O_constant && exp->X_op != O_symbol)
1604
        as_bad (_("Bad direct addressing construct %s"), s);
1605
      if (exp->X_op == O_constant)
1606
        {
1607
          if (exp->X_add_number < 0)
1608
            as_bad (_("Direct value of %ld is not suitable"),
1609
                    (long) exp->X_add_number);
1610
        }
1611
      operand->mode = M_DIRECT;
1612
      break;
1613
 
1614
    case '*':
1615
      ret = -1;
1616
      for (i = 0; i < tic4x_num_indirects; i++)
1617
        if ((ret = tic4x_indirect_parse (operand, &tic4x_indirects[i])))
1618
          break;
1619
      if (ret < 0)
1620
        break;
1621
      if (i < tic4x_num_indirects)
1622
        {
1623
          operand->mode = M_INDIRECT;
1624
          /* Indirect addressing mode number.  */
1625
          operand->expr.X_add_number = tic4x_indirects[i].modn;
1626
          /* Convert *+ARn(0) to *ARn etc.  Maybe we should
1627
             squeal about silly ones?  */
1628
          if (operand->expr.X_add_number < 0x08 && !operand->disp)
1629
            operand->expr.X_add_number = 0x18;
1630
        }
1631
      else
1632
        as_bad (_("Unknown indirect addressing mode"));
1633
      break;
1634
 
1635
    default:
1636
      operand->mode = M_IMMED;  /* Assume immediate.  */
1637
      str = input_line_pointer;
1638
      input_line_pointer = tic4x_expression (input_line_pointer, exp);
1639
      if (exp->X_op == O_register)
1640
        {
1641
          know (exp->X_add_symbol == 0);
1642
          know (exp->X_op_symbol == 0);
1643
          operand->mode = M_REGISTER;
1644
          break;
1645
        }
1646
      else if (exp->X_op == O_big)
1647
        {
1648
          if (exp->X_add_number > 0)
1649
            as_bad (_("Number too large"));     /* bignum required.  */
1650
          else
1651
            {
1652
              tic4x_gen_to_words (generic_floating_point_number,
1653
                                operand->fwords, S_PRECISION);
1654
              operand->mode = M_IMMED_F;
1655
            }
1656
          break;
1657
        }
1658
#ifdef TIC4X_ALT_SYNTAX
1659
      /* Allow ldi foo, ar0 to be equivalent to ldi @foo, ar0.  */
1660
      else if (exp->X_op == O_symbol)
1661
        {
1662
          operand->mode = M_DIRECT;
1663
          break;
1664
        }
1665
#endif
1666
    }
1667
  if (entry == NULL)
1668
    new_pointer = input_line_pointer;
1669
  input_line_pointer = save;
1670
  return new_pointer;
1671
}
1672
 
1673
static int
1674
tic4x_operands_match (tic4x_inst_t *inst, tic4x_insn_t *tinsn, int check)
1675
{
1676
  const char *args = inst->args;
1677
  unsigned long opcode = inst->opcode;
1678
  int num_operands = tinsn->num_operands;
1679
  tic4x_operand_t *operand = tinsn->operands;
1680
  expressionS *exp = &operand->expr;
1681
  int ret = 1;
1682
  int reg;
1683
 
1684
  /* Build the opcode, checking as we go to make sure that the
1685
     operands match.
1686
 
1687
     If an operand matches, we modify insn or opcode appropriately,
1688
     and do a "continue".  If an operand fails to match, we "break".  */
1689
 
1690
  tinsn->nchars = 4;            /* Instructions always 4 bytes.  */
1691
  tinsn->reloc = NO_RELOC;
1692
  tinsn->pcrel = 0;
1693
 
1694
  if (*args == '\0')
1695
    {
1696
      tinsn->opcode = opcode;
1697
      return num_operands == 0;
1698
    }
1699
 
1700
  for (;; ++args)
1701
    {
1702
      switch (*args)
1703
        {
1704
 
1705
        case '\0':              /* End of args.  */
1706
          if (num_operands == 1)
1707
            {
1708
              tinsn->opcode = opcode;
1709
              return ret;
1710
            }
1711
          break;                /* Too many operands.  */
1712
 
1713
        case '#':               /* This is only used for ldp.  */
1714
          if (operand->mode != M_DIRECT && operand->mode != M_IMMED)
1715
            break;
1716
          /* While this looks like a direct addressing mode, we actually
1717
             use an immediate mode form of ldiu or ldpk instruction.  */
1718
          if (exp->X_op == O_constant)
1719
            {
1720
              if( ( IS_CPU_TIC4X (tic4x_cpu) && exp->X_add_number <= 65535 )
1721
                  || ( IS_CPU_TIC3X (tic4x_cpu) && exp->X_add_number <= 255 ) )
1722
                {
1723
                  INSERTS (opcode, exp->X_add_number, 15, 0);
1724
                  continue;
1725
                }
1726
              else
1727
                {
1728
                  if (!check)
1729
                    as_bad (_("Immediate value of %ld is too large for ldf"),
1730
                            (long) exp->X_add_number);
1731
                  ret = -1;
1732
                  continue;
1733
                }
1734
            }
1735
          else if (exp->X_op == O_symbol)
1736
            {
1737
              tinsn->reloc = BFD_RELOC_HI16;
1738
              tinsn->exp = *exp;
1739
              continue;
1740
            }
1741
          break;                /* Not direct (dp) addressing.  */
1742
 
1743
        case '@':               /* direct.  */
1744
          if (operand->mode != M_DIRECT)
1745
            break;
1746
          if (exp->X_op == O_constant)
1747
            {
1748
              /* Store only the 16 LSBs of the number.  */
1749
              INSERTS (opcode, exp->X_add_number, 15, 0);
1750
              continue;
1751
            }
1752
          else if (exp->X_op == O_symbol)
1753
            {
1754
              tinsn->reloc = BFD_RELOC_LO16;
1755
              tinsn->exp = *exp;
1756
              continue;
1757
            }
1758
          break;                /* Not direct addressing.  */
1759
 
1760
        case 'A':
1761
          if (operand->mode != M_REGISTER)
1762
            break;
1763
          reg = exp->X_add_number;
1764
          if (reg >= REG_AR0 && reg <= REG_AR7)
1765
            INSERTU (opcode, reg - REG_AR0, 24, 22);
1766
          else
1767
            {
1768
              if (!check)
1769
                as_bad (_("Destination register must be ARn"));
1770
              ret = -1;
1771
            }
1772
          continue;
1773
 
1774
        case 'B':               /* Unsigned integer immediate.  */
1775
          /* Allow br label or br @label.  */
1776
          if (operand->mode != M_IMMED && operand->mode != M_DIRECT)
1777
            break;
1778
          if (exp->X_op == O_constant)
1779
            {
1780
              if (exp->X_add_number < (1 << 24))
1781
                {
1782
                  INSERTU (opcode, exp->X_add_number, 23, 0);
1783
                  continue;
1784
                }
1785
              else
1786
                {
1787
                  if (!check)
1788
                    as_bad (_("Immediate value of %ld is too large"),
1789
                            (long) exp->X_add_number);
1790
                  ret = -1;
1791
                  continue;
1792
                }
1793
            }
1794
          if (IS_CPU_TIC4X (tic4x_cpu))
1795
            {
1796
              tinsn->reloc = BFD_RELOC_24_PCREL;
1797
              tinsn->pcrel = 1;
1798
            }
1799
          else
1800
            {
1801
              tinsn->reloc = BFD_RELOC_24;
1802
              tinsn->pcrel = 0;
1803
            }
1804
          tinsn->exp = *exp;
1805
          continue;
1806
 
1807
        case 'C':
1808
          if (!IS_CPU_TIC4X (tic4x_cpu))
1809
            break;
1810
          if (operand->mode != M_INDIRECT)
1811
            break;
1812
          /* Require either *+ARn(disp) or *ARn.  */
1813
          if (operand->expr.X_add_number != 0
1814
              && operand->expr.X_add_number != 0x18)
1815
            {
1816
              if (!check)
1817
                as_bad (_("Invalid indirect addressing mode"));
1818
              ret = -1;
1819
              continue;
1820
            }
1821
          INSERTU (opcode, operand->aregno - REG_AR0, 2, 0);
1822
          INSERTU (opcode, operand->disp, 7, 3);
1823
          continue;
1824
 
1825
        case 'E':
1826
          if (!(operand->mode == M_REGISTER))
1827
            break;
1828
          INSERTU (opcode, exp->X_add_number, 7, 0);
1829
          continue;
1830
 
1831
        case 'e':
1832
          if (!(operand->mode == M_REGISTER))
1833
            break;
1834
          reg = exp->X_add_number;
1835
          if ( (reg >= REG_R0 && reg <= REG_R7)
1836
               || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
1837
            INSERTU (opcode, reg, 7, 0);
1838
          else
1839
            {
1840
              if (!check)
1841
                as_bad (_("Register must be Rn"));
1842
              ret = -1;
1843
            }
1844
          continue;
1845
 
1846
        case 'F':
1847
          if (operand->mode != M_IMMED_F
1848
              && !(operand->mode == M_IMMED && exp->X_op == O_constant))
1849
            break;
1850
 
1851
          if (operand->mode != M_IMMED_F)
1852
            {
1853
              /* OK, we 've got something like cmpf 0, r0
1854
                 Why can't they stick in a bloody decimal point ?!  */
1855
              char string[16];
1856
 
1857
              /* Create floating point number string.  */
1858
              sprintf (string, "%d.0", (int) exp->X_add_number);
1859
              tic4x_atof (string, 's', operand->fwords);
1860
            }
1861
 
1862
          INSERTU (opcode, operand->fwords[0], 15, 0);
1863
          continue;
1864
 
1865
        case 'G':
1866
          if (operand->mode != M_REGISTER)
1867
            break;
1868
          INSERTU (opcode, exp->X_add_number, 15, 8);
1869
          continue;
1870
 
1871
        case 'g':
1872
          if (operand->mode != M_REGISTER)
1873
            break;
1874
          reg = exp->X_add_number;
1875
          if ( (reg >= REG_R0 && reg <= REG_R7)
1876
               || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
1877
            INSERTU (opcode, reg, 15, 8);
1878
          else
1879
            {
1880
              if (!check)
1881
                as_bad (_("Register must be Rn"));
1882
              ret = -1;
1883
            }
1884
          continue;
1885
 
1886
        case 'H':
1887
          if (operand->mode != M_REGISTER)
1888
            break;
1889
          reg = exp->X_add_number;
1890
          if (reg >= REG_R0 && reg <= REG_R7)
1891
            INSERTU (opcode, reg - REG_R0, 18, 16);
1892
          else
1893
            {
1894
              if (!check)
1895
                as_bad (_("Register must be R0--R7"));
1896
              ret = -1;
1897
            }
1898
          continue;
1899
 
1900
        case 'i':
1901
          if ( operand->mode == M_REGISTER
1902
               && tic4x_oplevel & OP_ENH )
1903
            {
1904
              reg = exp->X_add_number;
1905
              INSERTU (opcode, reg, 4, 0);
1906
              INSERTU (opcode, 7, 7, 5);
1907
              continue;
1908
            }
1909
          /* Fallthrough */
1910
 
1911
        case 'I':
1912
          if (operand->mode != M_INDIRECT)
1913
            break;
1914
          if (operand->disp != 0 && operand->disp != 1)
1915
            {
1916
              if (IS_CPU_TIC4X (tic4x_cpu))
1917
                break;
1918
              if (!check)
1919
                as_bad (_("Invalid indirect addressing mode displacement %d"),
1920
                        operand->disp);
1921
              ret = -1;
1922
              continue;
1923
            }
1924
          INSERTU (opcode, operand->aregno - REG_AR0, 2, 0);
1925
          INSERTU (opcode, operand->expr.X_add_number, 7, 3);
1926
          continue;
1927
 
1928
        case 'j':
1929
          if ( operand->mode == M_REGISTER
1930
               && tic4x_oplevel & OP_ENH )
1931
            {
1932
              reg = exp->X_add_number;
1933
              INSERTU (opcode, reg, 12, 8);
1934
              INSERTU (opcode, 7, 15, 13);
1935
              continue;
1936
            }
1937
          /* Fallthrough */
1938
 
1939
        case 'J':
1940
          if (operand->mode != M_INDIRECT)
1941
            break;
1942
          if (operand->disp != 0 && operand->disp != 1)
1943
            {
1944
              if (IS_CPU_TIC4X (tic4x_cpu))
1945
                break;
1946
              if (!check)
1947
                as_bad (_("Invalid indirect addressing mode displacement %d"),
1948
                        operand->disp);
1949
              ret = -1;
1950
              continue;
1951
            }
1952
          INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
1953
          INSERTU (opcode, operand->expr.X_add_number, 15, 11);
1954
          continue;
1955
 
1956
        case 'K':
1957
          if (operand->mode != M_REGISTER)
1958
            break;
1959
          reg = exp->X_add_number;
1960
          if (reg >= REG_R0 && reg <= REG_R7)
1961
            INSERTU (opcode, reg - REG_R0, 21, 19);
1962
          else
1963
            {
1964
              if (!check)
1965
                as_bad (_("Register must be R0--R7"));
1966
              ret = -1;
1967
            }
1968
          continue;
1969
 
1970
        case 'L':
1971
          if (operand->mode != M_REGISTER)
1972
            break;
1973
          reg = exp->X_add_number;
1974
          if (reg >= REG_R0 && reg <= REG_R7)
1975
            INSERTU (opcode, reg - REG_R0, 24, 22);
1976
          else
1977
            {
1978
              if (!check)
1979
                as_bad (_("Register must be R0--R7"));
1980
              ret = -1;
1981
            }
1982
          continue;
1983
 
1984
        case 'M':
1985
          if (operand->mode != M_REGISTER)
1986
            break;
1987
          reg = exp->X_add_number;
1988
          if (reg == REG_R2 || reg == REG_R3)
1989
            INSERTU (opcode, reg - REG_R2, 22, 22);
1990
          else
1991
            {
1992
              if (!check)
1993
                as_bad (_("Destination register must be R2 or R3"));
1994
              ret = -1;
1995
            }
1996
          continue;
1997
 
1998
        case 'N':
1999
          if (operand->mode != M_REGISTER)
2000
            break;
2001
          reg = exp->X_add_number;
2002
          if (reg == REG_R0 || reg == REG_R1)
2003
            INSERTU (opcode, reg - REG_R0, 23, 23);
2004
          else
2005
            {
2006
              if (!check)
2007
                as_bad (_("Destination register must be R0 or R1"));
2008
              ret = -1;
2009
            }
2010
          continue;
2011
 
2012
        case 'O':
2013
          if (!IS_CPU_TIC4X (tic4x_cpu))
2014
            break;
2015
          if (operand->mode != M_INDIRECT)
2016
            break;
2017
          /* Require either *+ARn(disp) or *ARn.  */
2018
          if (operand->expr.X_add_number != 0
2019
              && operand->expr.X_add_number != 0x18)
2020
            {
2021
              if (!check)
2022
                as_bad (_("Invalid indirect addressing mode"));
2023
              ret = -1;
2024
              continue;
2025
            }
2026
          INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
2027
          INSERTU (opcode, operand->disp, 15, 11);
2028
          continue;
2029
 
2030
        case 'P':               /* PC relative displacement.  */
2031
          /* Allow br label or br @label.  */
2032
          if (operand->mode != M_IMMED && operand->mode != M_DIRECT)
2033
            break;
2034
          if (exp->X_op == O_constant)
2035
            {
2036
              if (exp->X_add_number >= -32768 && exp->X_add_number <= 32767)
2037
                {
2038
                  INSERTS (opcode, exp->X_add_number, 15, 0);
2039
                  continue;
2040
                }
2041
              else
2042
                {
2043
                  if (!check)
2044
                    as_bad (_("Displacement value of %ld is too large"),
2045
                            (long) exp->X_add_number);
2046
                  ret = -1;
2047
                  continue;
2048
                }
2049
            }
2050
          tinsn->reloc = BFD_RELOC_16_PCREL;
2051
          tinsn->pcrel = 1;
2052
          tinsn->exp = *exp;
2053
          continue;
2054
 
2055
        case 'Q':
2056
          if (operand->mode != M_REGISTER)
2057
            break;
2058
          reg = exp->X_add_number;
2059
          INSERTU (opcode, reg, 15, 0);
2060
          continue;
2061
 
2062
        case 'q':
2063
          if (operand->mode != M_REGISTER)
2064
            break;
2065
          reg = exp->X_add_number;
2066
          if ( (reg >= REG_R0 && reg <= REG_R7)
2067
               || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
2068
            INSERTU (opcode, reg, 15, 0);
2069
          else
2070
            {
2071
              if (!check)
2072
                as_bad (_("Register must be Rn"));
2073
              ret = -1;
2074
            }
2075
          continue;
2076
 
2077
        case 'R':
2078
          if (operand->mode != M_REGISTER)
2079
            break;
2080
          reg = exp->X_add_number;
2081
          INSERTU (opcode, reg, 20, 16);
2082
          continue;
2083
 
2084
        case 'r':
2085
          if (operand->mode != M_REGISTER)
2086
            break;
2087
          reg = exp->X_add_number;
2088
          if ( (reg >= REG_R0 && reg <= REG_R7)
2089
               || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
2090
            INSERTU (opcode, reg, 20, 16);
2091
          else
2092
            {
2093
              if (!check)
2094
                as_bad (_("Register must be Rn"));
2095
              ret = -1;
2096
            }
2097
          continue;
2098
 
2099
        case 'S':               /* Short immediate int.  */
2100
          if (operand->mode != M_IMMED && operand->mode != M_HI)
2101
            break;
2102
          if (exp->X_op == O_big)
2103
            {
2104
              if (!check)
2105
                as_bad (_("Floating point number not valid in expression"));
2106
              ret = -1;
2107
              continue;
2108
            }
2109
          if (exp->X_op == O_constant)
2110
            {
2111
              if (exp->X_add_number >= -32768 && exp->X_add_number <= 65535)
2112
                {
2113
                  INSERTS (opcode, exp->X_add_number, 15, 0);
2114
                  continue;
2115
                }
2116
              else
2117
                {
2118
                  if (!check)
2119
                    as_bad (_("Signed immediate value %ld too large"),
2120
                            (long) exp->X_add_number);
2121
                  ret = -1;
2122
                  continue;
2123
                }
2124
            }
2125
          else if (exp->X_op == O_symbol)
2126
            {
2127
              if (operand->mode == M_HI)
2128
                {
2129
                  tinsn->reloc = BFD_RELOC_HI16;
2130
                }
2131
              else
2132
                {
2133
                  tinsn->reloc = BFD_RELOC_LO16;
2134
                }
2135
              tinsn->exp = *exp;
2136
              continue;
2137
            }
2138
          /* Handle cases like ldi foo - $, ar0  where foo
2139
             is a forward reference.  Perhaps we should check
2140
             for X_op == O_symbol and disallow things like
2141
             ldi foo, ar0.  */
2142
          tinsn->reloc = BFD_RELOC_16;
2143
          tinsn->exp = *exp;
2144
          continue;
2145
 
2146
        case 'T':               /* 5-bit immediate value for tic4x stik.  */
2147
          if (!IS_CPU_TIC4X (tic4x_cpu))
2148
            break;
2149
          if (operand->mode != M_IMMED)
2150
            break;
2151
          if (exp->X_op == O_constant)
2152
            {
2153
              if (exp->X_add_number < 16 && exp->X_add_number >= -16)
2154
                {
2155
                  INSERTS (opcode, exp->X_add_number, 20, 16);
2156
                  continue;
2157
                }
2158
              else
2159
                {
2160
                  if (!check)
2161
                    as_bad (_("Immediate value of %ld is too large"),
2162
                            (long) exp->X_add_number);
2163
                  ret = -1;
2164
                  continue;
2165
                }
2166
            }
2167
          break;                /* No relocations allowed.  */
2168
 
2169
        case 'U':               /* Unsigned integer immediate.  */
2170
          if (operand->mode != M_IMMED && operand->mode != M_HI)
2171
            break;
2172
          if (exp->X_op == O_constant)
2173
            {
2174
              if (exp->X_add_number < (1 << 16) && exp->X_add_number >= 0)
2175
                {
2176
                  INSERTU (opcode, exp->X_add_number, 15, 0);
2177
                  continue;
2178
                }
2179
              else
2180
                {
2181
                  if (!check)
2182
                    as_bad (_("Unsigned immediate value %ld too large"),
2183
                            (long) exp->X_add_number);
2184
                  ret = -1;
2185
                  continue;
2186
                }
2187
            }
2188
          else if (exp->X_op == O_symbol)
2189
            {
2190
              if (operand->mode == M_HI)
2191
                tinsn->reloc = BFD_RELOC_HI16;
2192
              else
2193
                tinsn->reloc = BFD_RELOC_LO16;
2194
 
2195
              tinsn->exp = *exp;
2196
              continue;
2197
            }
2198
          tinsn->reloc = BFD_RELOC_16;
2199
          tinsn->exp = *exp;
2200
          continue;
2201
 
2202
        case 'V':               /* Trap numbers (immediate field).  */
2203
          if (operand->mode != M_IMMED)
2204
            break;
2205
          if (exp->X_op == O_constant)
2206
            {
2207
              if (exp->X_add_number < 512 && IS_CPU_TIC4X (tic4x_cpu))
2208
                {
2209
                  INSERTU (opcode, exp->X_add_number, 8, 0);
2210
                  continue;
2211
                }
2212
              else if (exp->X_add_number < 32 && IS_CPU_TIC3X (tic4x_cpu))
2213
                {
2214
                  INSERTU (opcode, exp->X_add_number | 0x20, 4, 0);
2215
                  continue;
2216
                }
2217
              else
2218
                {
2219
                  if (!check)
2220
                    as_bad (_("Immediate value of %ld is too large"),
2221
                            (long) exp->X_add_number);
2222
                  ret = -1;
2223
                  continue;
2224
                }
2225
            }
2226
          break;                /* No relocations allowed.  */
2227
 
2228
        case 'W':               /* Short immediate int (0--7).  */
2229
          if (!IS_CPU_TIC4X (tic4x_cpu))
2230
            break;
2231
          if (operand->mode != M_IMMED)
2232
            break;
2233
          if (exp->X_op == O_big)
2234
            {
2235
              if (!check)
2236
                as_bad (_("Floating point number not valid in expression"));
2237
              ret = -1;
2238
              continue;
2239
            }
2240
          if (exp->X_op == O_constant)
2241
            {
2242
              if (exp->X_add_number >= -256 && exp->X_add_number <= 127)
2243
                {
2244
                  INSERTS (opcode, exp->X_add_number, 7, 0);
2245
                  continue;
2246
                }
2247
              else
2248
                {
2249
                  if (!check)
2250
                    as_bad (_("Immediate value %ld too large"),
2251
                            (long) exp->X_add_number);
2252
                  ret = -1;
2253
                  continue;
2254
                }
2255
            }
2256
          tinsn->reloc = BFD_RELOC_16;
2257
          tinsn->exp = *exp;
2258
          continue;
2259
 
2260
        case 'X':               /* Expansion register for tic4x.  */
2261
          if (operand->mode != M_REGISTER)
2262
            break;
2263
          reg = exp->X_add_number;
2264
          if (reg >= REG_IVTP && reg <= REG_TVTP)
2265
            INSERTU (opcode, reg - REG_IVTP, 4, 0);
2266
          else
2267
            {
2268
              if (!check)
2269
                as_bad (_("Register must be ivtp or tvtp"));
2270
              ret = -1;
2271
            }
2272
          continue;
2273
 
2274
        case 'Y':               /* Address register for tic4x lda.  */
2275
          if (operand->mode != M_REGISTER)
2276
            break;
2277
          reg = exp->X_add_number;
2278
          if (reg >= REG_AR0 && reg <= REG_SP)
2279
            INSERTU (opcode, reg, 20, 16);
2280
          else
2281
            {
2282
              if (!check)
2283
                as_bad (_("Register must be address register"));
2284
              ret = -1;
2285
            }
2286
          continue;
2287
 
2288
        case 'Z':               /* Expansion register for tic4x.  */
2289
          if (operand->mode != M_REGISTER)
2290
            break;
2291
          reg = exp->X_add_number;
2292
          if (reg >= REG_IVTP && reg <= REG_TVTP)
2293
            INSERTU (opcode, reg - REG_IVTP, 20, 16);
2294
          else
2295
            {
2296
              if (!check)
2297
                as_bad (_("Register must be ivtp or tvtp"));
2298
              ret = -1;
2299
            }
2300
          continue;
2301
 
2302
        case '*':
2303
          if (operand->mode != M_INDIRECT)
2304
            break;
2305
          INSERTS (opcode, operand->disp, 7, 0);
2306
          INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
2307
          INSERTU (opcode, operand->expr.X_add_number, 15, 11);
2308
          continue;
2309
 
2310
        case '|':               /* treat as `,' if have ldi_ldi form.  */
2311
          if (tinsn->parallel)
2312
            {
2313
              if (--num_operands < 0)
2314
                break;          /* Too few operands.  */
2315
              operand++;
2316
              if (operand->mode != M_PARALLEL)
2317
                break;
2318
            }
2319
          /* Fall through.  */
2320
 
2321
        case ',':               /* Another operand.  */
2322
          if (--num_operands < 0)
2323
            break;              /* Too few operands.  */
2324
          operand++;
2325
          exp = &operand->expr;
2326
          continue;
2327
 
2328
        case ';':               /* Another optional operand.  */
2329
          if (num_operands == 1 || operand[1].mode == M_PARALLEL)
2330
            continue;
2331
          if (--num_operands < 0)
2332
            break;              /* Too few operands.  */
2333
          operand++;
2334
          exp = &operand->expr;
2335
          continue;
2336
 
2337
        default:
2338
          BAD_CASE (*args);
2339
        }
2340
      return 0;
2341
    }
2342
}
2343
 
2344
static void
2345
tic4x_insn_check (tic4x_insn_t *tinsn)
2346
{
2347
 
2348
  if (!strcmp (tinsn->name, "lda"))
2349
    {
2350
      if (tinsn->num_operands < 2 || tinsn->num_operands > 2)
2351
        as_fatal ("Illegal internal LDA insn definition");
2352
 
2353
      if (tinsn->operands[0].mode == M_REGISTER
2354
          && tinsn->operands[1].mode == M_REGISTER
2355
          && tinsn->operands[0].expr.X_add_number == tinsn->operands[1].expr.X_add_number )
2356
        as_bad (_("Source and destination register should not be equal"));
2357
    }
2358
  else if (!strcmp (tinsn->name, "ldi_ldi")
2359
           || !strcmp (tinsn->name, "ldi1_ldi2")
2360
           || !strcmp (tinsn->name, "ldi2_ldi1")
2361
           || !strcmp (tinsn->name, "ldf_ldf")
2362
           || !strcmp (tinsn->name, "ldf1_ldf2")
2363
           || !strcmp (tinsn->name, "ldf2_ldf1") )
2364
    {
2365
      if (tinsn->num_operands < 4 && tinsn->num_operands > 5 )
2366
        as_fatal ("Illegal internal %s insn definition", tinsn->name);
2367
 
2368
      if (tinsn->operands[1].mode == M_REGISTER
2369
          && tinsn->operands[tinsn->num_operands-1].mode == M_REGISTER
2370
          && tinsn->operands[1].expr.X_add_number == tinsn->operands[tinsn->num_operands-1].expr.X_add_number )
2371
        as_warn (_("Equal parallell destination registers, one result will be discarded"));
2372
    }
2373
}
2374
 
2375
static void
2376
tic4x_insn_output (tic4x_insn_t *tinsn)
2377
{
2378
  char *dst;
2379
 
2380
  /* Grab another fragment for opcode.  */
2381
  dst = frag_more (tinsn->nchars);
2382
 
2383
  /* Put out opcode word as a series of bytes in little endian order.  */
2384
  md_number_to_chars (dst, tinsn->opcode, tinsn->nchars);
2385
 
2386
  /* Put out the symbol-dependent stuff.  */
2387
  if (tinsn->reloc != NO_RELOC)
2388
    {
2389
      /* Where is the offset into the fragment for this instruction.  */
2390
      fix_new_exp (frag_now,
2391
                   dst - frag_now->fr_literal,  /* where */
2392
                   tinsn->nchars,       /* size */
2393
                   &tinsn->exp,
2394
                   tinsn->pcrel,
2395
                   tinsn->reloc);
2396
    }
2397
}
2398
 
2399
/* Parse the operands.  */
2400
static int
2401
tic4x_operands_parse (char *s, tic4x_operand_t *operands, int num_operands)
2402
{
2403
  if (!*s)
2404
    return num_operands;
2405
 
2406
  do
2407
    s = tic4x_operand_parse (s, &operands[num_operands++]);
2408
  while (num_operands < TIC4X_OPERANDS_MAX && *s++ == ',');
2409
 
2410
  if (num_operands > TIC4X_OPERANDS_MAX)
2411
    {
2412
      as_bad (_("Too many operands scanned"));
2413
      return -1;
2414
    }
2415
  return num_operands;
2416
}
2417
 
2418
/* Assemble a single instruction.  Its label has already been handled
2419
   by the generic front end.  We just parse mnemonic and operands, and
2420
   produce the bytes of data and relocation.  */
2421
void
2422
md_assemble (char *str)
2423
{
2424
  int ok = 0;
2425
  char *s;
2426
  int i;
2427
  int parsed = 0;
2428
  tic4x_inst_t *inst;           /* Instruction template.  */
2429
  tic4x_inst_t *first_inst;
2430
 
2431
  /* Scan for parallel operators */
2432
  if (str)
2433
    {
2434
      s = str;
2435
      while (*s && *s != '|')
2436
        s++;
2437
 
2438
      if (*s && s[1]=='|')
2439
        {
2440
          if(insn->parallel)
2441
            {
2442
              as_bad (_("Parallel opcode cannot contain more than two instructions"));
2443
              insn->parallel = 0;
2444
              insn->in_use = 0;
2445
              return;
2446
            }
2447
 
2448
          /* Lets take care of the first part of the parallel insn */
2449
          *s++ = 0;
2450
          md_assemble(str);
2451
          insn->parallel = 1;
2452
          str = ++s;
2453
          /* .. and let the second run though here */
2454
        }
2455
    }
2456
 
2457
  if (str && insn->parallel)
2458
    {
2459
      /* Find mnemonic (second part of parallel instruction).  */
2460
      s = str;
2461
      /* Skip past instruction mnemonic.  */
2462
      while (*s && *s != ' ')
2463
        s++;
2464
      if (*s)                   /* Null terminate for hash_find.  */
2465
        *s++ = '\0';            /* and skip past null.  */
2466
      strcat (insn->name, "_");
2467
      strncat (insn->name, str, TIC4X_NAME_MAX - strlen (insn->name));
2468
 
2469
      insn->operands[insn->num_operands++].mode = M_PARALLEL;
2470
 
2471
      if ((i = tic4x_operands_parse
2472
           (s, insn->operands, insn->num_operands)) < 0)
2473
        {
2474
          insn->parallel = 0;
2475
          insn->in_use = 0;
2476
          return;
2477
        }
2478
      insn->num_operands = i;
2479
      parsed = 1;
2480
    }
2481
 
2482
  if (insn->in_use)
2483
    {
2484
      if ((insn->inst = (struct tic4x_inst *)
2485
           hash_find (tic4x_op_hash, insn->name)) == NULL)
2486
        {
2487
          as_bad (_("Unknown opcode `%s'."), insn->name);
2488
          insn->parallel = 0;
2489
          insn->in_use = 0;
2490
          return;
2491
        }
2492
 
2493
      inst = insn->inst;
2494
      first_inst = NULL;
2495
      do
2496
        {
2497
          ok = tic4x_operands_match (inst, insn, 1);
2498
          if (ok < 0)
2499
            {
2500
              if (!first_inst)
2501
                first_inst = inst;
2502
              ok = 0;
2503
            }
2504
      } while (!ok && !strcmp (inst->name, inst[1].name) && inst++);
2505
 
2506
      if (ok > 0)
2507
        {
2508
          tic4x_insn_check (insn);
2509
          tic4x_insn_output (insn);
2510
        }
2511
      else if (!ok)
2512
        {
2513
          if (first_inst)
2514
            tic4x_operands_match (first_inst, insn, 0);
2515
          as_bad (_("Invalid operands for %s"), insn->name);
2516
        }
2517
      else
2518
        as_bad (_("Invalid instruction %s"), insn->name);
2519
    }
2520
 
2521
  if (str && !parsed)
2522
    {
2523
      /* Find mnemonic.  */
2524
      s = str;
2525
      while (*s && *s != ' ')   /* Skip past instruction mnemonic.  */
2526
        s++;
2527
      if (*s)                   /* Null terminate for hash_find.  */
2528
        *s++ = '\0';            /* and skip past null.  */
2529
      strncpy (insn->name, str, TIC4X_NAME_MAX - 3);
2530
 
2531
      if ((i = tic4x_operands_parse (s, insn->operands, 0)) < 0)
2532
        {
2533
          insn->inst = NULL;    /* Flag that error occurred.  */
2534
          insn->parallel = 0;
2535
          insn->in_use = 0;
2536
          return;
2537
        }
2538
      insn->num_operands = i;
2539
      insn->in_use = 1;
2540
    }
2541
  else
2542
    insn->in_use = 0;
2543
  insn->parallel = 0;
2544
}
2545
 
2546
void
2547
tic4x_cleanup (void)
2548
{
2549
  if (insn->in_use)
2550
    md_assemble (NULL);
2551
}
2552
 
2553
/* Turn a string in input_line_pointer into a floating point constant
2554
   of type type, and store the appropriate bytes in *litP.  The number
2555
   of chars emitted is stored in *sizeP.  An error message is
2556
   returned, or NULL on OK.  */
2557
 
2558
char *
2559
md_atof (int type, char *litP, int *sizeP)
2560
{
2561
  int prec;
2562
  int ieee;
2563
  LITTLENUM_TYPE words[MAX_LITTLENUMS];
2564
  LITTLENUM_TYPE *wordP;
2565
  char *t;
2566
 
2567
  switch (type)
2568
    {
2569
    case 's':           /* .single  */
2570
    case 'S':
2571
      ieee = 0;
2572
      prec = 1;
2573
      break;
2574
 
2575
    case 'd':           /* .double  */
2576
    case 'D':
2577
    case 'f':           /* .float  */
2578
    case 'F':
2579
      ieee = 0;
2580
      prec = 2;         /* 1 32-bit word */
2581
      break;
2582
 
2583
    case 'i':           /* .ieee */
2584
    case 'I':
2585
      prec = 2;
2586
      ieee = 1;
2587
      type = 'f';  /* Rewrite type to be usable by atof_ieee().  */
2588
      break;
2589
 
2590
    case 'e':           /* .ldouble */
2591
    case 'E':
2592
      prec = 4;         /* 2 32-bit words */
2593
      ieee = 0;
2594
      break;
2595
 
2596
    default:
2597
      *sizeP = 0;
2598
      return _("Unrecognized or unsupported floating point constant");
2599
    }
2600
 
2601
  if (ieee)
2602
    t = atof_ieee (input_line_pointer, type, words);
2603
  else
2604
    t = tic4x_atof (input_line_pointer, type, words);
2605
  if (t)
2606
    input_line_pointer = t;
2607
  *sizeP = prec * sizeof (LITTLENUM_TYPE);
2608
 
2609
  /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
2610
     little endian byte order.  */
2611
  /* SES: However it is required to put the words (32-bits) out in the
2612
     correct order, hence we write 2 and 2 littlenums in little endian
2613
     order, while we keep the original order on successive words.  */
2614
  for (wordP = words; wordP<(words+prec) ; wordP+=2)
2615
    {
2616
      if (wordP < (words + prec - 1)) /* Dump wordP[1] (if we have one).  */
2617
        {
2618
          md_number_to_chars (litP, (valueT) (wordP[1]),
2619
                              sizeof (LITTLENUM_TYPE));
2620
          litP += sizeof (LITTLENUM_TYPE);
2621
        }
2622
 
2623
      /* Dump wordP[0] */
2624
      md_number_to_chars (litP, (valueT) (wordP[0]),
2625
                          sizeof (LITTLENUM_TYPE));
2626
      litP += sizeof (LITTLENUM_TYPE);
2627
    }
2628
  return NULL;
2629
}
2630
 
2631
void
2632
md_apply_fix (fixS *fixP, valueT *value, segT seg ATTRIBUTE_UNUSED)
2633
{
2634
  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
2635
  valueT val = *value;
2636
 
2637
  switch (fixP->fx_r_type)
2638
    {
2639
    case BFD_RELOC_HI16:
2640
      val >>= 16;
2641
      break;
2642
 
2643
    case BFD_RELOC_LO16:
2644
      val &= 0xffff;
2645
      break;
2646
    default:
2647
      break;
2648
    }
2649
 
2650
  switch (fixP->fx_r_type)
2651
    {
2652
    case BFD_RELOC_32:
2653
      buf[3] = val >> 24;
2654
    case BFD_RELOC_24:
2655
    case BFD_RELOC_24_PCREL:
2656
      buf[2] = val >> 16;
2657
    case BFD_RELOC_16:
2658
    case BFD_RELOC_16_PCREL:
2659
    case BFD_RELOC_LO16:
2660
    case BFD_RELOC_HI16:
2661
      buf[1] = val >> 8;
2662
      buf[0] = val;
2663
      break;
2664
 
2665
    case NO_RELOC:
2666
    default:
2667
      as_bad (_("Bad relocation type: 0x%02x"), fixP->fx_r_type);
2668
      break;
2669
    }
2670
 
2671
  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) fixP->fx_done = 1;
2672
}
2673
 
2674
/* Should never be called for tic4x.  */
2675
void
2676
md_convert_frag (bfd *headers ATTRIBUTE_UNUSED,
2677
                 segT sec ATTRIBUTE_UNUSED,
2678
                 fragS *fragP ATTRIBUTE_UNUSED)
2679
{
2680
  as_fatal ("md_convert_frag");
2681
}
2682
 
2683
/* Should never be called for tic4x.  */
2684
void
2685
md_create_short_jump (char *ptr ATTRIBUTE_UNUSED,
2686
                      addressT from_addr ATTRIBUTE_UNUSED,
2687
                      addressT to_addr ATTRIBUTE_UNUSED,
2688
                      fragS *frag ATTRIBUTE_UNUSED,
2689
                      symbolS *to_symbol ATTRIBUTE_UNUSED)
2690
{
2691
  as_fatal ("md_create_short_jmp\n");
2692
}
2693
 
2694
/* Should never be called for tic4x.  */
2695
void
2696
md_create_long_jump (char *ptr ATTRIBUTE_UNUSED,
2697
                     addressT from_addr ATTRIBUTE_UNUSED,
2698
                     addressT to_addr ATTRIBUTE_UNUSED,
2699
                     fragS *frag ATTRIBUTE_UNUSED,
2700
                     symbolS *to_symbol ATTRIBUTE_UNUSED)
2701
{
2702
  as_fatal ("md_create_long_jump\n");
2703
}
2704
 
2705
/* Should never be called for tic4x.  */
2706
int
2707
md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
2708
                               segT segtype ATTRIBUTE_UNUSED)
2709
{
2710
  as_fatal ("md_estimate_size_before_relax\n");
2711
  return 0;
2712
}
2713
 
2714
 
2715
int
2716
md_parse_option (int c, char *arg)
2717
{
2718
  switch (c)
2719
    {
2720
    case OPTION_CPU:             /* cpu brand */
2721
      if (TOLOWER (*arg) == 'c')
2722
        arg++;
2723
      tic4x_cpu = atoi (arg);
2724
      if (!IS_CPU_TIC3X (tic4x_cpu) && !IS_CPU_TIC4X (tic4x_cpu))
2725
        as_warn (_("Unsupported processor generation %d"), tic4x_cpu);
2726
      break;
2727
 
2728
    case OPTION_REV:             /* cpu revision */
2729
      tic4x_revision = atoi (arg);
2730
      break;
2731
 
2732
    case 'b':
2733
      as_warn (_("Option -b is depreciated, please use -mbig"));
2734
    case OPTION_BIG:             /* big model */
2735
      tic4x_big_model = 1;
2736
      break;
2737
 
2738
    case 'p':
2739
      as_warn (_("Option -p is depreciated, please use -mmemparm"));
2740
    case OPTION_MEMPARM:         /* push args */
2741
      tic4x_reg_args = 0;
2742
      break;
2743
 
2744
    case 'r':
2745
      as_warn (_("Option -r is depreciated, please use -mregparm"));
2746
    case OPTION_REGPARM:        /* register args */
2747
      tic4x_reg_args = 1;
2748
      break;
2749
 
2750
    case 's':
2751
      as_warn (_("Option -s is depreciated, please use -msmall"));
2752
    case OPTION_SMALL:          /* small model */
2753
      tic4x_big_model = 0;
2754
      break;
2755
 
2756
    case OPTION_IDLE2:
2757
      tic4x_idle2 = 1;
2758
      break;
2759
 
2760
    case OPTION_LOWPOWER:
2761
      tic4x_lowpower = 1;
2762
      break;
2763
 
2764
    case OPTION_ENHANCED:
2765
      tic4x_enhanced = 1;
2766
      break;
2767
 
2768
    default:
2769
      return 0;
2770
    }
2771
 
2772
  return 1;
2773
}
2774
 
2775
void
2776
md_show_usage (FILE *stream)
2777
{
2778
  fprintf (stream,
2779
      _("\nTIC4X options:\n"
2780
        "  -mcpu=CPU  -mCPU        select architecture variant. CPU can be:\n"
2781
        "                            30 - TMS320C30\n"
2782
        "                            31 - TMS320C31, TMS320LC31\n"
2783
        "                            32 - TMS320C32\n"
2784
        "                            33 - TMS320VC33\n"
2785
        "                            40 - TMS320C40\n"
2786
        "                            44 - TMS320C44\n"
2787
        "  -mrev=REV               set cpu hardware revision (integer numbers).\n"
2788
        "                          Combinations of -mcpu and -mrev will enable/disable\n"
2789
        "                          the appropriate options (-midle2, -mlowpower and\n"
2790
        "                          -menhanced) according to the selected type\n"
2791
        "  -mbig                   select big memory model\n"
2792
        "  -msmall                 select small memory model (default)\n"
2793
        "  -mregparm               select register parameters (default)\n"
2794
        "  -mmemparm               select memory parameters\n"
2795
        "  -midle2                 enable IDLE2 support\n"
2796
        "  -mlowpower              enable LOPOWER and MAXSPEED support\n"
2797
        "  -menhanced              enable enhanced opcode support\n"));
2798
}
2799
 
2800
/* This is called when a line is unrecognized.  This is used to handle
2801
   definitions of TI C3x tools style local labels $n where n is a single
2802
   decimal digit.  */
2803
int
2804
tic4x_unrecognized_line (int c)
2805
{
2806
  int lab;
2807
  char *s;
2808
 
2809
  if (c != '$' || ! ISDIGIT (input_line_pointer[0]))
2810
    return 0;
2811
 
2812
  s = input_line_pointer;
2813
 
2814
  /* Let's allow multiple digit local labels.  */
2815
  lab = 0;
2816
  while (ISDIGIT (*s))
2817
    {
2818
      lab = lab * 10 + *s - '0';
2819
      s++;
2820
    }
2821
 
2822
  if (dollar_label_defined (lab))
2823
    {
2824
      as_bad (_("Label \"$%d\" redefined"), lab);
2825
      return 0;
2826
    }
2827
 
2828
  define_dollar_label (lab);
2829
  colon (dollar_label_name (lab, 0));
2830
  input_line_pointer = s + 1;
2831
 
2832
  return 1;
2833
}
2834
 
2835
/* Handle local labels peculiar to us referred to in an expression.  */
2836
symbolS *
2837
md_undefined_symbol (char *name)
2838
{
2839
  /* Look for local labels of the form $n.  */
2840
  if (name[0] == '$' && ISDIGIT (name[1]))
2841
    {
2842
      symbolS *symbolP;
2843
      char *s = name + 1;
2844
      int lab = 0;
2845
 
2846
      while (ISDIGIT ((unsigned char) *s))
2847
        {
2848
          lab = lab * 10 + *s - '0';
2849
          s++;
2850
        }
2851
      if (dollar_label_defined (lab))
2852
        {
2853
          name = dollar_label_name (lab, 0);
2854
          symbolP = symbol_find (name);
2855
        }
2856
      else
2857
        {
2858
          name = dollar_label_name (lab, 1);
2859
          symbolP = symbol_find_or_make (name);
2860
        }
2861
 
2862
      return symbolP;
2863
    }
2864
  return NULL;
2865
}
2866
 
2867
/* Parse an operand that is machine-specific.  */
2868
void
2869
md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
2870
{
2871
}
2872
 
2873
/* Round up a section size to the appropriate boundary---do we need this?  */
2874
valueT
2875
md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
2876
{
2877
  return size;                  /* Byte (i.e., 32-bit) alignment is fine?  */
2878
}
2879
 
2880
static int
2881
tic4x_pc_offset (unsigned int op)
2882
{
2883
  /* Determine the PC offset for a C[34]x instruction.
2884
     This could be simplified using some boolean algebra
2885
     but at the expense of readability.  */
2886
  switch (op >> 24)
2887
    {
2888
    case 0x60:                  /* br */
2889
    case 0x62:                  /* call  (C4x) */
2890
    case 0x64:                  /* rptb  (C4x) */
2891
      return 1;
2892
    case 0x61:                  /* brd */
2893
    case 0x63:                  /* laj */
2894
    case 0x65:                  /* rptbd (C4x) */
2895
      return 3;
2896
    case 0x66:                  /* swi */
2897
    case 0x67:
2898
      return 0;
2899
    default:
2900
      break;
2901
    }
2902
 
2903
  switch ((op & 0xffe00000) >> 20)
2904
    {
2905
    case 0x6a0:         /* bB */
2906
    case 0x720:         /* callB */
2907
    case 0x740:         /* trapB */
2908
      return 1;
2909
 
2910
    case 0x6a2:         /* bBd */
2911
    case 0x6a6:         /* bBat */
2912
    case 0x6aa:         /* bBaf */
2913
    case 0x722:         /* lajB */
2914
    case 0x748:         /* latB */
2915
    case 0x798:         /* rptbd */
2916
      return 3;
2917
 
2918
    default:
2919
      break;
2920
    }
2921
 
2922
  switch ((op & 0xfe200000) >> 20)
2923
    {
2924
    case 0x6e0:         /* dbB */
2925
      return 1;
2926
 
2927
    case 0x6e2:         /* dbBd */
2928
      return 3;
2929
 
2930
    default:
2931
      break;
2932
    }
2933
 
2934
  return 0;
2935
}
2936
 
2937
/* Exactly what point is a PC-relative offset relative TO?
2938
   With the C3x we have the following:
2939
   DBcond,  Bcond   disp + PC + 1 => PC
2940
   DBcondD, BcondD  disp + PC + 3 => PC
2941
 */
2942
long
2943
md_pcrel_from (fixS *fixP)
2944
{
2945
  unsigned char *buf;
2946
  unsigned int op;
2947
 
2948
  buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
2949
  op = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
2950
 
2951
  return ((fixP->fx_where + fixP->fx_frag->fr_address) >> 2) +
2952
    tic4x_pc_offset (op);
2953
}
2954
 
2955
/* Fill the alignment area with NOP's on .text, unless fill-data
2956
   was specified. */
2957
int
2958
tic4x_do_align (int alignment ATTRIBUTE_UNUSED,
2959
                const char *fill ATTRIBUTE_UNUSED,
2960
                int len ATTRIBUTE_UNUSED,
2961
                int max ATTRIBUTE_UNUSED)
2962
{
2963
  unsigned long nop = TIC_NOP_OPCODE;
2964
 
2965
  /* Because we are talking lwords, not bytes, adjust alignment to do words */
2966
  alignment += 2;
2967
 
2968
  if (alignment != 0 && !need_pass_2)
2969
    {
2970
      if (fill == NULL)
2971
        {
2972
          /*if (subseg_text_p (now_seg))*/  /* FIXME: doesn't work for .text for some reason */
2973
          frag_align_pattern( alignment, (const char *)&nop, sizeof(nop), max);
2974
          return 1;
2975
          /*else
2976
            frag_align (alignment, 0, max);*/
2977
        }
2978
      else if (len <= 1)
2979
        frag_align (alignment, *fill, max);
2980
      else
2981
        frag_align_pattern (alignment, fill, len, max);
2982
    }
2983
 
2984
  /* Return 1 to skip the default alignment function */
2985
  return 1;
2986
}
2987
 
2988
/* Look for and remove parallel instruction operator ||.  */
2989
void
2990
tic4x_start_line (void)
2991
{
2992
  char *s = input_line_pointer;
2993
 
2994
  SKIP_WHITESPACE ();
2995
 
2996
  /* If parallel instruction prefix found at start of line, skip it.  */
2997
  if (*input_line_pointer == '|' && input_line_pointer[1] == '|')
2998
    {
2999
      if (insn->in_use)
3000
        {
3001
          insn->parallel = 1;
3002
          input_line_pointer ++;
3003
          *input_line_pointer = ' ';
3004
          /* So line counters get bumped.  */
3005
          input_line_pointer[-1] = '\n';
3006
        }
3007
    }
3008
  else
3009
    {
3010
      /* Write out the previous insn here */
3011
      if (insn->in_use)
3012
        md_assemble (NULL);
3013
      input_line_pointer = s;
3014
    }
3015
}
3016
 
3017
arelent *
3018
tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixP)
3019
{
3020
  arelent *reloc;
3021
 
3022
  reloc = (arelent *) xmalloc (sizeof (arelent));
3023
 
3024
  reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
3025
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
3026
  reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
3027
  reloc->address /= OCTETS_PER_BYTE;
3028
  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
3029
  if (reloc->howto == (reloc_howto_type *) NULL)
3030
    {
3031
      as_bad_where (fixP->fx_file, fixP->fx_line,
3032
                    _("Reloc %d not supported by object file format"),
3033
                    (int) fixP->fx_r_type);
3034
      return NULL;
3035
    }
3036
 
3037
  if (fixP->fx_r_type == BFD_RELOC_HI16)
3038
    reloc->addend = fixP->fx_offset;
3039
  else
3040
    reloc->addend = fixP->fx_addnumber;
3041
 
3042
  return reloc;
3043
}

powered by: WebSVN 2.1.0

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