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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [gas/] [config/] [tc-tic4x.c] - Blame information for rev 205

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 205 julius
/* tc-tic4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
2
   Copyright (C) 1997,1998, 2002, 2003, 2005, 2006, 2007, 2008, 2009
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
  demand_empty_rest_of_line ();
953
  tic4x_insert_sym (name, value);
954
}
955
 
956
/* Reset local labels.  */
957
static void
958
tic4x_newblock (int x ATTRIBUTE_UNUSED)
959
{
960
  dollar_label_clear ();
961
}
962
 
963
/* .sect "section-name" [, value] */
964
/* .sect ["]section-name[:subsection-name]["] [, value] */
965
static void
966
tic4x_sect (int x ATTRIBUTE_UNUSED)
967
{
968
  char c;
969
  char *section_name;
970
  char *subsection_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
      subsection_name = input_line_pointer;
992
      c = get_symbol_end ();    /* Get terminator.  */
993
      input_line_pointer++;     /* Skip null symbol terminator.  */
994
      as_warn (_(".sect: subsection name ignored"));
995
    }
996
 
997
  /* We might still have a '"' to discard, but the character after a
998
     symbol name will be overwritten with a \0 by get_symbol_end()
999
     [VK].  */
1000
 
1001
  if (c == ',')
1002
    input_line_pointer =
1003
      tic4x_expression_abs (input_line_pointer, &num);
1004
  else if (*input_line_pointer == ',')
1005
    {
1006
      input_line_pointer =
1007
        tic4x_expression_abs (++input_line_pointer, &num);
1008
    }
1009
  else
1010
    num = 0;
1011
 
1012
  seg = subseg_new (name, num);
1013
  if (line_label != NULL)
1014
    {
1015
      S_SET_SEGMENT (line_label, seg);
1016
      symbol_set_frag (line_label, frag_now);
1017
    }
1018
 
1019
  if (bfd_get_section_flags (stdoutput, seg) == SEC_NO_FLAGS)
1020
    {
1021
      if (!bfd_set_section_flags (stdoutput, seg, SEC_DATA))
1022
        as_warn (_("Error setting flags for \"%s\": %s"), name,
1023
                 bfd_errmsg (bfd_get_error ()));
1024
    }
1025
 
1026
  /* If the last character overwritten by get_symbol_end() was an
1027
     end-of-line, we must restore it or the end of the line will not be
1028
     recognised and scanning extends into the next line, stopping with
1029
     an error (blame Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>
1030
     if this is not true).  */
1031
  if (is_end_of_line[(unsigned char) c])
1032
    *(--input_line_pointer) = c;
1033
 
1034
  demand_empty_rest_of_line ();
1035
}
1036
 
1037
/* symbol[:] .set value  or  .set symbol, value */
1038
static void
1039
tic4x_set (int x ATTRIBUTE_UNUSED)
1040
{
1041
  symbolS *symbolP;
1042
 
1043
  SKIP_WHITESPACE ();
1044
  if ((symbolP = line_label) == NULL)
1045
    {
1046
      char c;
1047
      char *name;
1048
 
1049
      name = input_line_pointer;
1050
      c = get_symbol_end ();    /* Get terminator.  */
1051
      if (c != ',')
1052
        {
1053
          as_bad (_(".set syntax invalid\n"));
1054
          ignore_rest_of_line ();
1055
          return;
1056
        }
1057
      ++input_line_pointer;
1058
      symbolP = symbol_find_or_make (name);
1059
    }
1060
  else
1061
    symbol_table_insert (symbolP);
1062
 
1063
  pseudo_set (symbolP);
1064
  demand_empty_rest_of_line ();
1065
}
1066
 
1067
/* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
1068
static void
1069
tic4x_usect (int x ATTRIBUTE_UNUSED)
1070
{
1071
  char c;
1072
  char *name;
1073
  char *section_name;
1074
  segT seg;
1075
  offsetT size, alignment_flag;
1076
  segT current_seg;
1077
  subsegT current_subseg;
1078
 
1079
  current_seg = now_seg;        /* save current seg.  */
1080
  current_subseg = now_subseg;  /* save current subseg.  */
1081
 
1082
  SKIP_WHITESPACE ();
1083
  if (*input_line_pointer == '"')
1084
    input_line_pointer++;
1085
  section_name = input_line_pointer;
1086
  c = get_symbol_end ();        /* Get terminator.  */
1087
  input_line_pointer++;         /* Skip null symbol terminator.  */
1088
  name = xmalloc (input_line_pointer - section_name + 1);
1089
  strcpy (name, section_name);
1090
 
1091
  if (c == ',')
1092
    input_line_pointer =
1093
      tic4x_expression_abs (input_line_pointer, &size);
1094
  else if (*input_line_pointer == ',')
1095
    {
1096
      input_line_pointer =
1097
        tic4x_expression_abs (++input_line_pointer, &size);
1098
    }
1099
  else
1100
    size = 0;
1101
 
1102
  /* Read a possibly present third argument (alignment flag) [VK].  */
1103
  if (*input_line_pointer == ',')
1104
    {
1105
      input_line_pointer =
1106
        tic4x_expression_abs (++input_line_pointer, &alignment_flag);
1107
    }
1108
  else
1109
    alignment_flag = 0;
1110
  if (alignment_flag)
1111
    as_warn (_(".usect: non-zero alignment flag ignored"));
1112
 
1113
  seg = subseg_new (name, 0);
1114
  if (line_label != NULL)
1115
    {
1116
      S_SET_SEGMENT (line_label, seg);
1117
      symbol_set_frag (line_label, frag_now);
1118
      S_SET_VALUE (line_label, frag_now_fix ());
1119
    }
1120
  seg_info (seg)->bss = 1;      /* Uninitialised data.  */
1121
  if (!bfd_set_section_flags (stdoutput, seg, SEC_ALLOC))
1122
    as_warn (_("Error setting flags for \"%s\": %s"), name,
1123
             bfd_errmsg (bfd_get_error ()));
1124
  tic4x_seg_alloc (name, seg, size, line_label);
1125
 
1126
  if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
1127
    S_SET_STORAGE_CLASS (line_label, C_STAT);
1128
 
1129
  subseg_set (current_seg, current_subseg);     /* Restore current seg.  */
1130
  demand_empty_rest_of_line ();
1131
}
1132
 
1133
/* .version cpu-version.  */
1134
static void
1135
tic4x_version (int x ATTRIBUTE_UNUSED)
1136
{
1137
  offsetT temp;
1138
 
1139
  input_line_pointer =
1140
    tic4x_expression_abs (input_line_pointer, &temp);
1141
  if (!IS_CPU_TIC3X (temp) && !IS_CPU_TIC4X (temp))
1142
    as_bad (_("This assembler does not support processor generation %ld"),
1143
            (long) temp);
1144
 
1145
  if (tic4x_cpu && temp != (offsetT) tic4x_cpu)
1146
    as_warn (_("Changing processor generation on fly not supported..."));
1147
  tic4x_cpu = temp;
1148
  demand_empty_rest_of_line ();
1149
}
1150
 
1151
static void
1152
tic4x_init_regtable (void)
1153
{
1154
  unsigned int i;
1155
 
1156
  for (i = 0; i < tic3x_num_registers; i++)
1157
    tic4x_insert_reg (tic3x_registers[i].name,
1158
                    tic3x_registers[i].regno);
1159
 
1160
  if (IS_CPU_TIC4X (tic4x_cpu))
1161
    {
1162
      /* Add additional Tic4x registers, overriding some C3x ones.  */
1163
      for (i = 0; i < tic4x_num_registers; i++)
1164
        tic4x_insert_reg (tic4x_registers[i].name,
1165
                        tic4x_registers[i].regno);
1166
    }
1167
}
1168
 
1169
static void
1170
tic4x_init_symbols (void)
1171
{
1172
  /* The TI tools accept case insensitive versions of these symbols,
1173
     we don't !
1174
 
1175
     For TI C/Asm 5.0
1176
 
1177
     .TMS320xx       30,31,32,40,or 44       set according to -v flag
1178
     .C3X or .C3x    1 or 0                  1 if -v30,-v31,or -v32
1179
     .C30            1 or 0                  1 if -v30
1180
     .C31            1 or 0                  1 if -v31
1181
     .C32            1 or 0                  1 if -v32
1182
     .C4X or .C4x    1 or 0                  1 if -v40, or -v44
1183
     .C40            1 or 0                  1 if -v40
1184
     .C44            1 or 0                  1 if -v44
1185
 
1186
     .REGPARM 1 or 0                  1 if -mr option used
1187
     .BIGMODEL        1 or 0                  1 if -mb option used
1188
 
1189
     These symbols are currently supported but will be removed in a
1190
     later version:
1191
     .TMS320C30      1 or 0                  1 if -v30,-v31,or -v32
1192
     .TMS320C31      1 or 0                  1 if -v31
1193
     .TMS320C32      1 or 0                  1 if -v32
1194
     .TMS320C40      1 or 0                  1 if -v40, or -v44
1195
     .TMS320C44      1 or 0                  1 if -v44
1196
 
1197
     Source: TI: TMS320C3x/C4x Assembly Language Tools User's Guide,
1198
     1997, SPRU035C, p. 3-17/3-18.  */
1199
  tic4x_insert_sym (".REGPARM", tic4x_reg_args);
1200
  tic4x_insert_sym (".MEMPARM", !tic4x_reg_args);
1201
  tic4x_insert_sym (".BIGMODEL", tic4x_big_model);
1202
  tic4x_insert_sym (".C30INTERRUPT", 0);
1203
  tic4x_insert_sym (".TMS320xx", tic4x_cpu == 0 ? 40 : tic4x_cpu);
1204
  tic4x_insert_sym (".C3X", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1205
  tic4x_insert_sym (".C3x", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1206
  tic4x_insert_sym (".C4X", tic4x_cpu == 0 || tic4x_cpu == 40 || tic4x_cpu == 44);
1207
  tic4x_insert_sym (".C4x", tic4x_cpu == 0 || tic4x_cpu == 40 || tic4x_cpu == 44);
1208
  /* Do we need to have the following symbols also in lower case?  */
1209
  tic4x_insert_sym (".TMS320C30", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1210
  tic4x_insert_sym (".tms320C30", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1211
  tic4x_insert_sym (".TMS320C31", tic4x_cpu == 31);
1212
  tic4x_insert_sym (".tms320C31", tic4x_cpu == 31);
1213
  tic4x_insert_sym (".TMS320C32", tic4x_cpu == 32);
1214
  tic4x_insert_sym (".tms320C32", tic4x_cpu == 32);
1215
  tic4x_insert_sym (".TMS320C33", tic4x_cpu == 33);
1216
  tic4x_insert_sym (".tms320C33", tic4x_cpu == 33);
1217
  tic4x_insert_sym (".TMS320C40", tic4x_cpu == 40 || tic4x_cpu == 44 || tic4x_cpu == 0);
1218
  tic4x_insert_sym (".tms320C40", tic4x_cpu == 40 || tic4x_cpu == 44 || tic4x_cpu == 0);
1219
  tic4x_insert_sym (".TMS320C44", tic4x_cpu == 44);
1220
  tic4x_insert_sym (".tms320C44", tic4x_cpu == 44);
1221
  tic4x_insert_sym (".TMX320C40", 0);    /* C40 first pass silicon ?  */
1222
  tic4x_insert_sym (".tmx320C40", 0);
1223
}
1224
 
1225
/* Insert a new instruction template into hash table.  */
1226
static int
1227
tic4x_inst_insert (const tic4x_inst_t *inst)
1228
{
1229
  static char prev_name[16];
1230
  const char *retval = NULL;
1231
 
1232
  /* Only insert the first name if have several similar entries.  */
1233
  if (!strcmp (inst->name, prev_name) || inst->name[0] == '\0')
1234
    return 1;
1235
 
1236
  retval = hash_insert (tic4x_op_hash, inst->name, (void *) inst);
1237
  if (retval != NULL)
1238
    fprintf (stderr, "internal error: can't hash `%s': %s\n",
1239
             inst->name, retval);
1240
  else
1241
    strcpy (prev_name, inst->name);
1242
  return retval == NULL;
1243
}
1244
 
1245
/* Make a new instruction template.  */
1246
static tic4x_inst_t *
1247
tic4x_inst_make (char *name, unsigned long opcode, char *args)
1248
{
1249
  static tic4x_inst_t *insts = NULL;
1250
  static char *names = NULL;
1251
  static int index = 0;
1252
 
1253
  if (insts == NULL)
1254
    {
1255
      /* Allocate memory to store name strings.  */
1256
      names = (char *) xmalloc (sizeof (char) * 8192);
1257
      /* Allocate memory for additional insts.  */
1258
      insts = (tic4x_inst_t *)
1259
        xmalloc (sizeof (tic4x_inst_t) * 1024);
1260
    }
1261
  insts[index].name = names;
1262
  insts[index].opcode = opcode;
1263
  insts[index].opmask = 0xffffffff;
1264
  insts[index].args = args;
1265
  index++;
1266
 
1267
  do
1268
    *names++ = *name++;
1269
  while (*name);
1270
  *names++ = '\0';
1271
 
1272
  return &insts[index - 1];
1273
}
1274
 
1275
/* Add instruction template, creating dynamic templates as required.  */
1276
static int
1277
tic4x_inst_add (const tic4x_inst_t *insts)
1278
{
1279
  char *s = insts->name;
1280
  char *d;
1281
  unsigned int i;
1282
  int ok = 1;
1283
  char name[16];
1284
 
1285
  d = name;
1286
 
1287
  /* We do not care about INSNs that is not a part of our
1288
     oplevel setting.  */
1289
  if ((insts->oplevel & tic4x_oplevel) == 0)
1290
    return ok;
1291
 
1292
  while (1)
1293
    {
1294
      switch (*s)
1295
        {
1296
        case 'B':
1297
        case 'C':
1298
          /* Dynamically create all the conditional insts.  */
1299
          for (i = 0; i < tic4x_num_conds; i++)
1300
            {
1301
              tic4x_inst_t *inst;
1302
              int k = 0;
1303
              char *c = tic4x_conds[i].name;
1304
              char *e = d;
1305
 
1306
              while (*c)
1307
                *e++ = *c++;
1308
              c = s + 1;
1309
              while (*c)
1310
                *e++ = *c++;
1311
              *e = '\0';
1312
 
1313
              /* If instruction found then have already processed it.  */
1314
              if (hash_find (tic4x_op_hash, name))
1315
                return 1;
1316
 
1317
              do
1318
                {
1319
                  inst = tic4x_inst_make (name, insts[k].opcode +
1320
                                        (tic4x_conds[i].cond <<
1321
                                         (*s == 'B' ? 16 : 23)),
1322
                                        insts[k].args);
1323
                  if (k == 0)    /* Save strcmp() with following func.  */
1324
                    ok &= tic4x_inst_insert (inst);
1325
                  k++;
1326
                }
1327
              while (!strcmp (insts->name,
1328
                              insts[k].name));
1329
            }
1330
          return ok;
1331
          break;
1332
 
1333
        case '\0':
1334
          return tic4x_inst_insert (insts);
1335
          break;
1336
 
1337
        default:
1338
          *d++ = *s++;
1339
          break;
1340
        }
1341
    }
1342
}
1343
 
1344
/* This function is called once, at assembler startup time.  It should
1345
   set up all the tables, etc., that the MD part of the assembler will
1346
   need.  */
1347
void
1348
md_begin (void)
1349
{
1350
  int ok = 1;
1351
  unsigned int i;
1352
 
1353
  /* Setup the proper opcode level according to the
1354
     commandline parameters */
1355
  tic4x_oplevel = OP_C3X;
1356
 
1357
  if ( IS_CPU_TIC4X(tic4x_cpu) )
1358
    tic4x_oplevel |= OP_C4X;
1359
 
1360
  if ( (   tic4x_cpu == 31 && tic4x_revision >= 6)
1361
       || (tic4x_cpu == 32 && tic4x_revision >= 2)
1362
       || (tic4x_cpu == 33)
1363
       || tic4x_enhanced )
1364
    tic4x_oplevel |= OP_ENH;
1365
 
1366
  if ( (   tic4x_cpu == 30 && tic4x_revision >= 7)
1367
       || (tic4x_cpu == 31 && tic4x_revision >= 5)
1368
       || (tic4x_cpu == 32)
1369
       || tic4x_lowpower )
1370
    tic4x_oplevel |= OP_LPWR;
1371
 
1372
  if ( (   tic4x_cpu == 30 && tic4x_revision >= 7)
1373
       || (tic4x_cpu == 31 && tic4x_revision >= 5)
1374
       || (tic4x_cpu == 32)
1375
       || (tic4x_cpu == 33)
1376
       || (tic4x_cpu == 40 && tic4x_revision >= 5)
1377
       || (tic4x_cpu == 44)
1378
       || tic4x_idle2 )
1379
    tic4x_oplevel |= OP_IDLE2;
1380
 
1381
  /* Create hash table for mnemonics.  */
1382
  tic4x_op_hash = hash_new ();
1383
 
1384
  /* Create hash table for asg pseudo.  */
1385
  tic4x_asg_hash = hash_new ();
1386
 
1387
  /* Add mnemonics to hash table, expanding conditional mnemonics on fly.  */
1388
  for (i = 0; i < tic4x_num_insts; i++)
1389
    ok &= tic4x_inst_add (tic4x_insts + i);
1390
 
1391
  /* Create dummy inst to avoid errors accessing end of table.  */
1392
  tic4x_inst_make ("", 0, "");
1393
 
1394
  if (!ok)
1395
    as_fatal ("Broken assembler.  No assembly attempted.");
1396
 
1397
  /* Add registers to symbol table.  */
1398
  tic4x_init_regtable ();
1399
 
1400
  /* Add predefined symbols to symbol table.  */
1401
  tic4x_init_symbols ();
1402
}
1403
 
1404
void
1405
tic4x_end (void)
1406
{
1407
  bfd_set_arch_mach (stdoutput, bfd_arch_tic4x,
1408
                     IS_CPU_TIC4X (tic4x_cpu) ? bfd_mach_tic4x : bfd_mach_tic3x);
1409
}
1410
 
1411
static int
1412
tic4x_indirect_parse (tic4x_operand_t *operand,
1413
                      const tic4x_indirect_t *indirect)
1414
{
1415
  char *n = indirect->name;
1416
  char *s = input_line_pointer;
1417
  char *b;
1418
  symbolS *symbolP;
1419
  char name[32];
1420
 
1421
  operand->disp = 0;
1422
  for (; *n; n++)
1423
    {
1424
      switch (*n)
1425
        {
1426
        case 'a':               /* Need to match aux register.  */
1427
          b = name;
1428
#ifdef TIC4X_ALT_SYNTAX
1429
          if (*s == '%')
1430
            s++;
1431
#endif
1432
          while (ISALNUM (*s))
1433
            *b++ = *s++;
1434
          *b++ = '\0';
1435
          if (!(symbolP = symbol_find (name)))
1436
            return 0;
1437
 
1438
          if (S_GET_SEGMENT (symbolP) != reg_section)
1439
            return 0;
1440
 
1441
          operand->aregno = S_GET_VALUE (symbolP);
1442
          if (operand->aregno >= REG_AR0 && operand->aregno <= REG_AR7)
1443
            break;
1444
 
1445
          as_bad (_("Auxiliary register AR0--AR7 required for indirect"));
1446
          return -1;
1447
 
1448
        case 'd':               /* Need to match constant for disp.  */
1449
#ifdef TIC4X_ALT_SYNTAX
1450
          if (*s == '%')        /* expr() will die if we don't skip this.  */
1451
            s++;
1452
#endif
1453
          s = tic4x_expression (s, &operand->expr);
1454
          if (operand->expr.X_op != O_constant)
1455
            return 0;
1456
          operand->disp = operand->expr.X_add_number;
1457
          if (operand->disp < 0 || operand->disp > 255)
1458
            {
1459
              as_bad (_("Bad displacement %d (require 0--255)\n"),
1460
                      operand->disp);
1461
              return -1;
1462
            }
1463
          break;
1464
 
1465
        case 'y':               /* Need to match IR0.  */
1466
        case 'z':               /* Need to match IR1.  */
1467
#ifdef TIC4X_ALT_SYNTAX
1468
          if (*s == '%')
1469
            s++;
1470
#endif
1471
          s = tic4x_expression (s, &operand->expr);
1472
          if (operand->expr.X_op != O_register)
1473
            return 0;
1474
          if (operand->expr.X_add_number != REG_IR0
1475
              && operand->expr.X_add_number != REG_IR1)
1476
            {
1477
              as_bad (_("Index register IR0,IR1 required for displacement"));
1478
              return -1;
1479
            }
1480
 
1481
          if (*n == 'y' && operand->expr.X_add_number == REG_IR0)
1482
            break;
1483
          if (*n == 'z' && operand->expr.X_add_number == REG_IR1)
1484
            break;
1485
          return 0;
1486
 
1487
        case '(':
1488
          if (*s != '(')        /* No displacement, assume to be 1.  */
1489
            {
1490
              operand->disp = 1;
1491
              while (*n != ')')
1492
                n++;
1493
            }
1494
          else
1495
            s++;
1496
          break;
1497
 
1498
        default:
1499
          if (TOLOWER (*s) != *n)
1500
            return 0;
1501
          s++;
1502
        }
1503
    }
1504
  if (*s != ' ' && *s != ',' && *s != '\0')
1505
    return 0;
1506
  input_line_pointer = s;
1507
  return 1;
1508
}
1509
 
1510
static char *
1511
tic4x_operand_parse (char *s, tic4x_operand_t *operand)
1512
{
1513
  unsigned int i;
1514
  char c;
1515
  int ret;
1516
  expressionS *exp = &operand->expr;
1517
  char *save = input_line_pointer;
1518
  char *str;
1519
  char *new_pointer;
1520
  struct hash_entry *entry = NULL;
1521
 
1522
  input_line_pointer = s;
1523
  SKIP_WHITESPACE ();
1524
 
1525
  str = input_line_pointer;
1526
  c = get_symbol_end ();        /* Get terminator.  */
1527
  new_pointer = input_line_pointer;
1528
  if (strlen (str) && (entry = hash_find (tic4x_asg_hash, str)) != NULL)
1529
    {
1530
      *input_line_pointer = c;
1531
      input_line_pointer = (char *) entry;
1532
    }
1533
  else
1534
    {
1535
      *input_line_pointer = c;
1536
      input_line_pointer = str;
1537
    }
1538
 
1539
  operand->mode = M_UNKNOWN;
1540
  switch (*input_line_pointer)
1541
    {
1542
#ifdef TIC4X_ALT_SYNTAX
1543
    case '%':
1544
      input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1545
      if (exp->X_op != O_register)
1546
        as_bad (_("Expecting a register name"));
1547
      operand->mode = M_REGISTER;
1548
      break;
1549
 
1550
    case '^':
1551
      /* Denotes high 16 bits.  */
1552
      input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1553
      if (exp->X_op == O_constant)
1554
        operand->mode = M_IMMED;
1555
      else if (exp->X_op == O_big)
1556
        {
1557
          if (exp->X_add_number)
1558
            as_bad (_("Number too large"));     /* bignum required */
1559
          else
1560
            {
1561
              tic4x_gen_to_words (generic_floating_point_number,
1562
                                operand->fwords, S_PRECISION);
1563
              operand->mode = M_IMMED_F;
1564
            }
1565
        }
1566
      /* Allow ori ^foo, ar0 to be equivalent to ldi .hi.foo, ar0  */
1567
      /* WARNING : The TI C40 assembler cannot do this.  */
1568
      else if (exp->X_op == O_symbol)
1569
        {
1570
          operand->mode = M_HI;
1571
          break;
1572
        }
1573
 
1574
    case '#':
1575
      input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1576
      if (exp->X_op == O_constant)
1577
        operand->mode = M_IMMED;
1578
      else if (exp->X_op == O_big)
1579
        {
1580
          if (exp->X_add_number > 0)
1581
            as_bad (_("Number too large"));     /* bignum required.  */
1582
          else
1583
            {
1584
              tic4x_gen_to_words (generic_floating_point_number,
1585
                                operand->fwords, S_PRECISION);
1586
              operand->mode = M_IMMED_F;
1587
            }
1588
        }
1589
      /* Allow ori foo, ar0 to be equivalent to ldi .lo.foo, ar0  */
1590
      /* WARNING : The TI C40 assembler cannot do this.  */
1591
      else if (exp->X_op == O_symbol)
1592
        {
1593
          operand->mode = M_IMMED;
1594
          break;
1595
        }
1596
 
1597
      else
1598
        as_bad (_("Expecting a constant value"));
1599
      break;
1600
    case '\\':
1601
#endif
1602
    case '@':
1603
      input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1604
      if (exp->X_op != O_constant && exp->X_op != O_symbol)
1605
        as_bad (_("Bad direct addressing construct %s"), s);
1606
      if (exp->X_op == O_constant)
1607
        {
1608
          if (exp->X_add_number < 0)
1609
            as_bad (_("Direct value of %ld is not suitable"),
1610
                    (long) exp->X_add_number);
1611
        }
1612
      operand->mode = M_DIRECT;
1613
      break;
1614
 
1615
    case '*':
1616
      ret = -1;
1617
      for (i = 0; i < tic4x_num_indirects; i++)
1618
        if ((ret = tic4x_indirect_parse (operand, &tic4x_indirects[i])))
1619
          break;
1620
      if (ret < 0)
1621
        break;
1622
      if (i < tic4x_num_indirects)
1623
        {
1624
          operand->mode = M_INDIRECT;
1625
          /* Indirect addressing mode number.  */
1626
          operand->expr.X_add_number = tic4x_indirects[i].modn;
1627
          /* Convert *+ARn(0) to *ARn etc.  Maybe we should
1628
             squeal about silly ones?  */
1629
          if (operand->expr.X_add_number < 0x08 && !operand->disp)
1630
            operand->expr.X_add_number = 0x18;
1631
        }
1632
      else
1633
        as_bad (_("Unknown indirect addressing mode"));
1634
      break;
1635
 
1636
    default:
1637
      operand->mode = M_IMMED;  /* Assume immediate.  */
1638
      str = input_line_pointer;
1639
      input_line_pointer = tic4x_expression (input_line_pointer, exp);
1640
      if (exp->X_op == O_register)
1641
        {
1642
          know (exp->X_add_symbol == 0);
1643
          know (exp->X_op_symbol == 0);
1644
          operand->mode = M_REGISTER;
1645
          break;
1646
        }
1647
      else if (exp->X_op == O_big)
1648
        {
1649
          if (exp->X_add_number > 0)
1650
            as_bad (_("Number too large"));     /* bignum required.  */
1651
          else
1652
            {
1653
              tic4x_gen_to_words (generic_floating_point_number,
1654
                                operand->fwords, S_PRECISION);
1655
              operand->mode = M_IMMED_F;
1656
            }
1657
          break;
1658
        }
1659
#ifdef TIC4X_ALT_SYNTAX
1660
      /* Allow ldi foo, ar0 to be equivalent to ldi @foo, ar0.  */
1661
      else if (exp->X_op == O_symbol)
1662
        {
1663
          operand->mode = M_DIRECT;
1664
          break;
1665
        }
1666
#endif
1667
    }
1668
  if (entry == NULL)
1669
    new_pointer = input_line_pointer;
1670
  input_line_pointer = save;
1671
  return new_pointer;
1672
}
1673
 
1674
static int
1675
tic4x_operands_match (tic4x_inst_t *inst, tic4x_insn_t *insn, int check)
1676
{
1677
  const char *args = inst->args;
1678
  unsigned long opcode = inst->opcode;
1679
  int num_operands = insn->num_operands;
1680
  tic4x_operand_t *operand = insn->operands;
1681
  expressionS *exp = &operand->expr;
1682
  int ret = 1;
1683
  int reg;
1684
 
1685
  /* Build the opcode, checking as we go to make sure that the
1686
     operands match.
1687
 
1688
     If an operand matches, we modify insn or opcode appropriately,
1689
     and do a "continue".  If an operand fails to match, we "break".  */
1690
 
1691
  insn->nchars = 4;             /* Instructions always 4 bytes.  */
1692
  insn->reloc = NO_RELOC;
1693
  insn->pcrel = 0;
1694
 
1695
  if (*args == '\0')
1696
    {
1697
      insn->opcode = opcode;
1698
      return num_operands == 0;
1699
    }
1700
 
1701
  for (;; ++args)
1702
    {
1703
      switch (*args)
1704
        {
1705
 
1706
        case '\0':              /* End of args.  */
1707
          if (num_operands == 1)
1708
            {
1709
              insn->opcode = opcode;
1710
              return ret;
1711
            }
1712
          break;                /* Too many operands.  */
1713
 
1714
        case '#':               /* This is only used for ldp.  */
1715
          if (operand->mode != M_DIRECT && operand->mode != M_IMMED)
1716
            break;
1717
          /* While this looks like a direct addressing mode, we actually
1718
             use an immediate mode form of ldiu or ldpk instruction.  */
1719
          if (exp->X_op == O_constant)
1720
            {
1721
              if( ( IS_CPU_TIC4X (tic4x_cpu) && exp->X_add_number <= 65535 )
1722
                  || ( IS_CPU_TIC3X (tic4x_cpu) && exp->X_add_number <= 255 ) )
1723
                {
1724
                  INSERTS (opcode, exp->X_add_number, 15, 0);
1725
                  continue;
1726
                }
1727
              else
1728
                {
1729
                  if (!check)
1730
                    as_bad (_("Immediate value of %ld is too large for ldf"),
1731
                            (long) exp->X_add_number);
1732
                  ret = -1;
1733
                  continue;
1734
                }
1735
            }
1736
          else if (exp->X_op == O_symbol)
1737
            {
1738
              insn->reloc = BFD_RELOC_HI16;
1739
              insn->exp = *exp;
1740
              continue;
1741
            }
1742
          break;                /* Not direct (dp) addressing.  */
1743
 
1744
        case '@':               /* direct.  */
1745
          if (operand->mode != M_DIRECT)
1746
            break;
1747
          if (exp->X_op == O_constant)
1748
            {
1749
              /* Store only the 16 LSBs of the number.  */
1750
              INSERTS (opcode, exp->X_add_number, 15, 0);
1751
              continue;
1752
            }
1753
          else if (exp->X_op == O_symbol)
1754
            {
1755
              insn->reloc = BFD_RELOC_LO16;
1756
              insn->exp = *exp;
1757
              continue;
1758
            }
1759
          break;                /* Not direct addressing.  */
1760
 
1761
        case 'A':
1762
          if (operand->mode != M_REGISTER)
1763
            break;
1764
          reg = exp->X_add_number;
1765
          if (reg >= REG_AR0 && reg <= REG_AR7)
1766
            INSERTU (opcode, reg - REG_AR0, 24, 22);
1767
          else
1768
            {
1769
              if (!check)
1770
                as_bad (_("Destination register must be ARn"));
1771
              ret = -1;
1772
            }
1773
          continue;
1774
 
1775
        case 'B':               /* Unsigned integer immediate.  */
1776
          /* Allow br label or br @label.  */
1777
          if (operand->mode != M_IMMED && operand->mode != M_DIRECT)
1778
            break;
1779
          if (exp->X_op == O_constant)
1780
            {
1781
              if (exp->X_add_number < (1 << 24))
1782
                {
1783
                  INSERTU (opcode, exp->X_add_number, 23, 0);
1784
                  continue;
1785
                }
1786
              else
1787
                {
1788
                  if (!check)
1789
                    as_bad (_("Immediate value of %ld is too large"),
1790
                            (long) exp->X_add_number);
1791
                  ret = -1;
1792
                  continue;
1793
                }
1794
            }
1795
          if (IS_CPU_TIC4X (tic4x_cpu))
1796
            {
1797
              insn->reloc = BFD_RELOC_24_PCREL;
1798
              insn->pcrel = 1;
1799
            }
1800
          else
1801
            {
1802
              insn->reloc = BFD_RELOC_24;
1803
              insn->pcrel = 0;
1804
            }
1805
          insn->exp = *exp;
1806
          continue;
1807
 
1808
        case 'C':
1809
          if (!IS_CPU_TIC4X (tic4x_cpu))
1810
            break;
1811
          if (operand->mode != M_INDIRECT)
1812
            break;
1813
          /* Require either *+ARn(disp) or *ARn.  */
1814
          if (operand->expr.X_add_number != 0
1815
              && operand->expr.X_add_number != 0x18)
1816
            {
1817
              if (!check)
1818
                as_bad (_("Invalid indirect addressing mode"));
1819
              ret = -1;
1820
              continue;
1821
            }
1822
          INSERTU (opcode, operand->aregno - REG_AR0, 2, 0);
1823
          INSERTU (opcode, operand->disp, 7, 3);
1824
          continue;
1825
 
1826
        case 'E':
1827
          if (!(operand->mode == M_REGISTER))
1828
            break;
1829
          INSERTU (opcode, exp->X_add_number, 7, 0);
1830
          continue;
1831
 
1832
        case 'e':
1833
          if (!(operand->mode == M_REGISTER))
1834
            break;
1835
          reg = exp->X_add_number;
1836
          if ( (reg >= REG_R0 && reg <= REG_R7)
1837
               || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
1838
            INSERTU (opcode, reg, 7, 0);
1839
          else
1840
            {
1841
              if (!check)
1842
                as_bad (_("Register must be Rn"));
1843
              ret = -1;
1844
            }
1845
          continue;
1846
 
1847
        case 'F':
1848
          if (operand->mode != M_IMMED_F
1849
              && !(operand->mode == M_IMMED && exp->X_op == O_constant))
1850
            break;
1851
 
1852
          if (operand->mode != M_IMMED_F)
1853
            {
1854
              /* OK, we 've got something like cmpf 0, r0
1855
                 Why can't they stick in a bloody decimal point ?!  */
1856
              char string[16];
1857
 
1858
              /* Create floating point number string.  */
1859
              sprintf (string, "%d.0", (int) exp->X_add_number);
1860
              tic4x_atof (string, 's', operand->fwords);
1861
            }
1862
 
1863
          INSERTU (opcode, operand->fwords[0], 15, 0);
1864
          continue;
1865
 
1866
        case 'G':
1867
          if (operand->mode != M_REGISTER)
1868
            break;
1869
          INSERTU (opcode, exp->X_add_number, 15, 8);
1870
          continue;
1871
 
1872
        case 'g':
1873
          if (operand->mode != M_REGISTER)
1874
            break;
1875
          reg = exp->X_add_number;
1876
          if ( (reg >= REG_R0 && reg <= REG_R7)
1877
               || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
1878
            INSERTU (opcode, reg, 15, 8);
1879
          else
1880
            {
1881
              if (!check)
1882
                as_bad (_("Register must be Rn"));
1883
              ret = -1;
1884
            }
1885
          continue;
1886
 
1887
        case 'H':
1888
          if (operand->mode != M_REGISTER)
1889
            break;
1890
          reg = exp->X_add_number;
1891
          if (reg >= REG_R0 && reg <= REG_R7)
1892
            INSERTU (opcode, reg - REG_R0, 18, 16);
1893
          else
1894
            {
1895
              if (!check)
1896
                as_bad (_("Register must be R0--R7"));
1897
              ret = -1;
1898
            }
1899
          continue;
1900
 
1901
        case 'i':
1902
          if ( operand->mode == M_REGISTER
1903
               && tic4x_oplevel & OP_ENH )
1904
            {
1905
              reg = exp->X_add_number;
1906
              INSERTU (opcode, reg, 4, 0);
1907
              INSERTU (opcode, 7, 7, 5);
1908
              continue;
1909
            }
1910
          /* Fallthrough */
1911
 
1912
        case 'I':
1913
          if (operand->mode != M_INDIRECT)
1914
            break;
1915
          if (operand->disp != 0 && operand->disp != 1)
1916
            {
1917
              if (IS_CPU_TIC4X (tic4x_cpu))
1918
                break;
1919
              if (!check)
1920
                as_bad (_("Invalid indirect addressing mode displacement %d"),
1921
                        operand->disp);
1922
              ret = -1;
1923
              continue;
1924
            }
1925
          INSERTU (opcode, operand->aregno - REG_AR0, 2, 0);
1926
          INSERTU (opcode, operand->expr.X_add_number, 7, 3);
1927
          continue;
1928
 
1929
        case 'j':
1930
          if ( operand->mode == M_REGISTER
1931
               && tic4x_oplevel & OP_ENH )
1932
            {
1933
              reg = exp->X_add_number;
1934
              INSERTU (opcode, reg, 12, 8);
1935
              INSERTU (opcode, 7, 15, 13);
1936
              continue;
1937
            }
1938
          /* Fallthrough */
1939
 
1940
        case 'J':
1941
          if (operand->mode != M_INDIRECT)
1942
            break;
1943
          if (operand->disp != 0 && operand->disp != 1)
1944
            {
1945
              if (IS_CPU_TIC4X (tic4x_cpu))
1946
                break;
1947
              if (!check)
1948
                as_bad (_("Invalid indirect addressing mode displacement %d"),
1949
                        operand->disp);
1950
              ret = -1;
1951
              continue;
1952
            }
1953
          INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
1954
          INSERTU (opcode, operand->expr.X_add_number, 15, 11);
1955
          continue;
1956
 
1957
        case 'K':
1958
          if (operand->mode != M_REGISTER)
1959
            break;
1960
          reg = exp->X_add_number;
1961
          if (reg >= REG_R0 && reg <= REG_R7)
1962
            INSERTU (opcode, reg - REG_R0, 21, 19);
1963
          else
1964
            {
1965
              if (!check)
1966
                as_bad (_("Register must be R0--R7"));
1967
              ret = -1;
1968
            }
1969
          continue;
1970
 
1971
        case 'L':
1972
          if (operand->mode != M_REGISTER)
1973
            break;
1974
          reg = exp->X_add_number;
1975
          if (reg >= REG_R0 && reg <= REG_R7)
1976
            INSERTU (opcode, reg - REG_R0, 24, 22);
1977
          else
1978
            {
1979
              if (!check)
1980
                as_bad (_("Register must be R0--R7"));
1981
              ret = -1;
1982
            }
1983
          continue;
1984
 
1985
        case 'M':
1986
          if (operand->mode != M_REGISTER)
1987
            break;
1988
          reg = exp->X_add_number;
1989
          if (reg == REG_R2 || reg == REG_R3)
1990
            INSERTU (opcode, reg - REG_R2, 22, 22);
1991
          else
1992
            {
1993
              if (!check)
1994
                as_bad (_("Destination register must be R2 or R3"));
1995
              ret = -1;
1996
            }
1997
          continue;
1998
 
1999
        case 'N':
2000
          if (operand->mode != M_REGISTER)
2001
            break;
2002
          reg = exp->X_add_number;
2003
          if (reg == REG_R0 || reg == REG_R1)
2004
            INSERTU (opcode, reg - REG_R0, 23, 23);
2005
          else
2006
            {
2007
              if (!check)
2008
                as_bad (_("Destination register must be R0 or R1"));
2009
              ret = -1;
2010
            }
2011
          continue;
2012
 
2013
        case 'O':
2014
          if (!IS_CPU_TIC4X (tic4x_cpu))
2015
            break;
2016
          if (operand->mode != M_INDIRECT)
2017
            break;
2018
          /* Require either *+ARn(disp) or *ARn.  */
2019
          if (operand->expr.X_add_number != 0
2020
              && operand->expr.X_add_number != 0x18)
2021
            {
2022
              if (!check)
2023
                as_bad (_("Invalid indirect addressing mode"));
2024
              ret = -1;
2025
              continue;
2026
            }
2027
          INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
2028
          INSERTU (opcode, operand->disp, 15, 11);
2029
          continue;
2030
 
2031
        case 'P':               /* PC relative displacement.  */
2032
          /* Allow br label or br @label.  */
2033
          if (operand->mode != M_IMMED && operand->mode != M_DIRECT)
2034
            break;
2035
          if (exp->X_op == O_constant)
2036
            {
2037
              if (exp->X_add_number >= -32768 && exp->X_add_number <= 32767)
2038
                {
2039
                  INSERTS (opcode, exp->X_add_number, 15, 0);
2040
                  continue;
2041
                }
2042
              else
2043
                {
2044
                  if (!check)
2045
                    as_bad (_("Displacement value of %ld is too large"),
2046
                            (long) exp->X_add_number);
2047
                  ret = -1;
2048
                  continue;
2049
                }
2050
            }
2051
          insn->reloc = BFD_RELOC_16_PCREL;
2052
          insn->pcrel = 1;
2053
          insn->exp = *exp;
2054
          continue;
2055
 
2056
        case 'Q':
2057
          if (operand->mode != M_REGISTER)
2058
            break;
2059
          reg = exp->X_add_number;
2060
          INSERTU (opcode, reg, 15, 0);
2061
          continue;
2062
 
2063
        case 'q':
2064
          if (operand->mode != M_REGISTER)
2065
            break;
2066
          reg = exp->X_add_number;
2067
          if ( (reg >= REG_R0 && reg <= REG_R7)
2068
               || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
2069
            INSERTU (opcode, reg, 15, 0);
2070
          else
2071
            {
2072
              if (!check)
2073
                as_bad (_("Register must be Rn"));
2074
              ret = -1;
2075
            }
2076
          continue;
2077
 
2078
        case 'R':
2079
          if (operand->mode != M_REGISTER)
2080
            break;
2081
          reg = exp->X_add_number;
2082
          INSERTU (opcode, reg, 20, 16);
2083
          continue;
2084
 
2085
        case 'r':
2086
          if (operand->mode != M_REGISTER)
2087
            break;
2088
          reg = exp->X_add_number;
2089
          if ( (reg >= REG_R0 && reg <= REG_R7)
2090
               || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
2091
            INSERTU (opcode, reg, 20, 16);
2092
          else
2093
            {
2094
              if (!check)
2095
                as_bad (_("Register must be Rn"));
2096
              ret = -1;
2097
            }
2098
          continue;
2099
 
2100
        case 'S':               /* Short immediate int.  */
2101
          if (operand->mode != M_IMMED && operand->mode != M_HI)
2102
            break;
2103
          if (exp->X_op == O_big)
2104
            {
2105
              if (!check)
2106
                as_bad (_("Floating point number not valid in expression"));
2107
              ret = -1;
2108
              continue;
2109
            }
2110
          if (exp->X_op == O_constant)
2111
            {
2112
              if (exp->X_add_number >= -32768 && exp->X_add_number <= 65535)
2113
                {
2114
                  INSERTS (opcode, exp->X_add_number, 15, 0);
2115
                  continue;
2116
                }
2117
              else
2118
                {
2119
                  if (!check)
2120
                    as_bad (_("Signed immediate value %ld too large"),
2121
                            (long) exp->X_add_number);
2122
                  ret = -1;
2123
                  continue;
2124
                }
2125
            }
2126
          else if (exp->X_op == O_symbol)
2127
            {
2128
              if (operand->mode == M_HI)
2129
                {
2130
                  insn->reloc = BFD_RELOC_HI16;
2131
                }
2132
              else
2133
                {
2134
                  insn->reloc = BFD_RELOC_LO16;
2135
                }
2136
              insn->exp = *exp;
2137
              continue;
2138
            }
2139
          /* Handle cases like ldi foo - $, ar0  where foo
2140
             is a forward reference.  Perhaps we should check
2141
             for X_op == O_symbol and disallow things like
2142
             ldi foo, ar0.  */
2143
          insn->reloc = BFD_RELOC_16;
2144
          insn->exp = *exp;
2145
          continue;
2146
 
2147
        case 'T':               /* 5-bit immediate value for tic4x stik.  */
2148
          if (!IS_CPU_TIC4X (tic4x_cpu))
2149
            break;
2150
          if (operand->mode != M_IMMED)
2151
            break;
2152
          if (exp->X_op == O_constant)
2153
            {
2154
              if (exp->X_add_number < 16 && exp->X_add_number >= -16)
2155
                {
2156
                  INSERTS (opcode, exp->X_add_number, 20, 16);
2157
                  continue;
2158
                }
2159
              else
2160
                {
2161
                  if (!check)
2162
                    as_bad (_("Immediate value of %ld is too large"),
2163
                            (long) exp->X_add_number);
2164
                  ret = -1;
2165
                  continue;
2166
                }
2167
            }
2168
          break;                /* No relocations allowed.  */
2169
 
2170
        case 'U':               /* Unsigned integer immediate.  */
2171
          if (operand->mode != M_IMMED && operand->mode != M_HI)
2172
            break;
2173
          if (exp->X_op == O_constant)
2174
            {
2175
              if (exp->X_add_number < (1 << 16) && exp->X_add_number >= 0)
2176
                {
2177
                  INSERTU (opcode, exp->X_add_number, 15, 0);
2178
                  continue;
2179
                }
2180
              else
2181
                {
2182
                  if (!check)
2183
                    as_bad (_("Unsigned immediate value %ld too large"),
2184
                            (long) exp->X_add_number);
2185
                  ret = -1;
2186
                  continue;
2187
                }
2188
            }
2189
          else if (exp->X_op == O_symbol)
2190
            {
2191
              if (operand->mode == M_HI)
2192
                insn->reloc = BFD_RELOC_HI16;
2193
              else
2194
                insn->reloc = BFD_RELOC_LO16;
2195
 
2196
              insn->exp = *exp;
2197
              continue;
2198
            }
2199
          insn->reloc = BFD_RELOC_16;
2200
          insn->exp = *exp;
2201
          continue;
2202
 
2203
        case 'V':               /* Trap numbers (immediate field).  */
2204
          if (operand->mode != M_IMMED)
2205
            break;
2206
          if (exp->X_op == O_constant)
2207
            {
2208
              if (exp->X_add_number < 512 && IS_CPU_TIC4X (tic4x_cpu))
2209
                {
2210
                  INSERTU (opcode, exp->X_add_number, 8, 0);
2211
                  continue;
2212
                }
2213
              else if (exp->X_add_number < 32 && IS_CPU_TIC3X (tic4x_cpu))
2214
                {
2215
                  INSERTU (opcode, exp->X_add_number | 0x20, 4, 0);
2216
                  continue;
2217
                }
2218
              else
2219
                {
2220
                  if (!check)
2221
                    as_bad (_("Immediate value of %ld is too large"),
2222
                            (long) exp->X_add_number);
2223
                  ret = -1;
2224
                  continue;
2225
                }
2226
            }
2227
          break;                /* No relocations allowed.  */
2228
 
2229
        case 'W':               /* Short immediate int (0--7).  */
2230
          if (!IS_CPU_TIC4X (tic4x_cpu))
2231
            break;
2232
          if (operand->mode != M_IMMED)
2233
            break;
2234
          if (exp->X_op == O_big)
2235
            {
2236
              if (!check)
2237
                as_bad (_("Floating point number not valid in expression"));
2238
              ret = -1;
2239
              continue;
2240
            }
2241
          if (exp->X_op == O_constant)
2242
            {
2243
              if (exp->X_add_number >= -256 && exp->X_add_number <= 127)
2244
                {
2245
                  INSERTS (opcode, exp->X_add_number, 7, 0);
2246
                  continue;
2247
                }
2248
              else
2249
                {
2250
                  if (!check)
2251
                    as_bad (_("Immediate value %ld too large"),
2252
                            (long) exp->X_add_number);
2253
                  ret = -1;
2254
                  continue;
2255
                }
2256
            }
2257
          insn->reloc = BFD_RELOC_16;
2258
          insn->exp = *exp;
2259
          continue;
2260
 
2261
        case 'X':               /* Expansion register for tic4x.  */
2262
          if (operand->mode != M_REGISTER)
2263
            break;
2264
          reg = exp->X_add_number;
2265
          if (reg >= REG_IVTP && reg <= REG_TVTP)
2266
            INSERTU (opcode, reg - REG_IVTP, 4, 0);
2267
          else
2268
            {
2269
              if (!check)
2270
                as_bad (_("Register must be ivtp or tvtp"));
2271
              ret = -1;
2272
            }
2273
          continue;
2274
 
2275
        case 'Y':               /* Address register for tic4x lda.  */
2276
          if (operand->mode != M_REGISTER)
2277
            break;
2278
          reg = exp->X_add_number;
2279
          if (reg >= REG_AR0 && reg <= REG_SP)
2280
            INSERTU (opcode, reg, 20, 16);
2281
          else
2282
            {
2283
              if (!check)
2284
                as_bad (_("Register must be address register"));
2285
              ret = -1;
2286
            }
2287
          continue;
2288
 
2289
        case 'Z':               /* Expansion register for tic4x.  */
2290
          if (operand->mode != M_REGISTER)
2291
            break;
2292
          reg = exp->X_add_number;
2293
          if (reg >= REG_IVTP && reg <= REG_TVTP)
2294
            INSERTU (opcode, reg - REG_IVTP, 20, 16);
2295
          else
2296
            {
2297
              if (!check)
2298
                as_bad (_("Register must be ivtp or tvtp"));
2299
              ret = -1;
2300
            }
2301
          continue;
2302
 
2303
        case '*':
2304
          if (operand->mode != M_INDIRECT)
2305
            break;
2306
          INSERTS (opcode, operand->disp, 7, 0);
2307
          INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
2308
          INSERTU (opcode, operand->expr.X_add_number, 15, 11);
2309
          continue;
2310
 
2311
        case '|':               /* treat as `,' if have ldi_ldi form.  */
2312
          if (insn->parallel)
2313
            {
2314
              if (--num_operands < 0)
2315
                break;          /* Too few operands.  */
2316
              operand++;
2317
              if (operand->mode != M_PARALLEL)
2318
                break;
2319
            }
2320
          /* Fall through.  */
2321
 
2322
        case ',':               /* Another operand.  */
2323
          if (--num_operands < 0)
2324
            break;              /* Too few operands.  */
2325
          operand++;
2326
          exp = &operand->expr;
2327
          continue;
2328
 
2329
        case ';':               /* Another optional operand.  */
2330
          if (num_operands == 1 || operand[1].mode == M_PARALLEL)
2331
            continue;
2332
          if (--num_operands < 0)
2333
            break;              /* Too few operands.  */
2334
          operand++;
2335
          exp = &operand->expr;
2336
          continue;
2337
 
2338
        default:
2339
          BAD_CASE (*args);
2340
        }
2341
      return 0;
2342
    }
2343
}
2344
 
2345
static void
2346
tic4x_insn_check (tic4x_insn_t *insn)
2347
{
2348
 
2349
  if (!strcmp(insn->name, "lda"))
2350
    {
2351
      if (insn->num_operands < 2 || insn->num_operands > 2)
2352
        as_fatal ("Illegal internal LDA insn definition");
2353
 
2354
      if ( insn->operands[0].mode == M_REGISTER
2355
           && insn->operands[1].mode == M_REGISTER
2356
           && insn->operands[0].expr.X_add_number == insn->operands[1].expr.X_add_number )
2357
        as_bad (_("Source and destination register should not be equal"));
2358
    }
2359
  else if( !strcmp(insn->name, "ldi_ldi")
2360
           || !strcmp(insn->name, "ldi1_ldi2")
2361
           || !strcmp(insn->name, "ldi2_ldi1")
2362
           || !strcmp(insn->name, "ldf_ldf")
2363
           || !strcmp(insn->name, "ldf1_ldf2")
2364
           || !strcmp(insn->name, "ldf2_ldf1") )
2365
    {
2366
      if ( insn->num_operands < 4 && insn->num_operands > 5 )
2367
        as_fatal ("Illegal internal %s insn definition", insn->name);
2368
 
2369
      if ( insn->operands[1].mode == M_REGISTER
2370
           && insn->operands[insn->num_operands-1].mode == M_REGISTER
2371
           && insn->operands[1].expr.X_add_number == insn->operands[insn->num_operands-1].expr.X_add_number )
2372
        as_warn (_("Equal parallell destination registers, one result will be discarded"));
2373
    }
2374
}
2375
 
2376
static void
2377
tic4x_insn_output (tic4x_insn_t *insn)
2378
{
2379
  char *dst;
2380
 
2381
  /* Grab another fragment for opcode.  */
2382
  dst = frag_more (insn->nchars);
2383
 
2384
  /* Put out opcode word as a series of bytes in little endian order.  */
2385
  md_number_to_chars (dst, insn->opcode, insn->nchars);
2386
 
2387
  /* Put out the symbol-dependent stuff.  */
2388
  if (insn->reloc != NO_RELOC)
2389
    {
2390
      /* Where is the offset into the fragment for this instruction.  */
2391
      fix_new_exp (frag_now,
2392
                   dst - frag_now->fr_literal,  /* where */
2393
                   insn->nchars,        /* size */
2394
                   &insn->exp,
2395
                   insn->pcrel,
2396
                   insn->reloc);
2397
    }
2398
}
2399
 
2400
/* Parse the operands.  */
2401
static int
2402
tic4x_operands_parse (char *s, tic4x_operand_t *operands, int num_operands)
2403
{
2404
  if (!*s)
2405
    return num_operands;
2406
 
2407
  do
2408
    s = tic4x_operand_parse (s, &operands[num_operands++]);
2409
  while (num_operands < TIC4X_OPERANDS_MAX && *s++ == ',');
2410
 
2411
  if (num_operands > TIC4X_OPERANDS_MAX)
2412
    {
2413
      as_bad (_("Too many operands scanned"));
2414
      return -1;
2415
    }
2416
  return num_operands;
2417
}
2418
 
2419
/* Assemble a single instruction.  Its label has already been handled
2420
   by the generic front end.  We just parse mnemonic and operands, and
2421
   produce the bytes of data and relocation.  */
2422
void
2423
md_assemble (char *str)
2424
{
2425
  int ok = 0;
2426
  char *s;
2427
  int i;
2428
  int parsed = 0;
2429
  tic4x_inst_t *inst;           /* Instruction template.  */
2430
  tic4x_inst_t *first_inst;
2431
 
2432
  /* Scan for parallel operators */
2433
  if (str)
2434
    {
2435
      s = str;
2436
      while (*s && *s != '|')
2437
        s++;
2438
 
2439
      if (*s && s[1]=='|')
2440
        {
2441
          if(insn->parallel)
2442
            {
2443
              as_bad (_("Parallel opcode cannot contain more than two instructions"));
2444
              insn->parallel = 0;
2445
              insn->in_use = 0;
2446
              return;
2447
            }
2448
 
2449
          /* Lets take care of the first part of the parallel insn */
2450
          *s++ = 0;
2451
          md_assemble(str);
2452
          insn->parallel = 1;
2453
          str = ++s;
2454
          /* .. and let the second run though here */
2455
        }
2456
    }
2457
 
2458
  if (str && insn->parallel)
2459
    {
2460
      /* Find mnemonic (second part of parallel instruction).  */
2461
      s = str;
2462
      /* Skip past instruction mnemonic.  */
2463
      while (*s && *s != ' ')
2464
        s++;
2465
      if (*s)                   /* Null terminate for hash_find.  */
2466
        *s++ = '\0';            /* and skip past null.  */
2467
      strcat (insn->name, "_");
2468
      strncat (insn->name, str, TIC4X_NAME_MAX - strlen (insn->name));
2469
 
2470
      insn->operands[insn->num_operands++].mode = M_PARALLEL;
2471
 
2472
      if ((i = tic4x_operands_parse
2473
           (s, insn->operands, insn->num_operands)) < 0)
2474
        {
2475
          insn->parallel = 0;
2476
          insn->in_use = 0;
2477
          return;
2478
        }
2479
      insn->num_operands = i;
2480
      parsed = 1;
2481
    }
2482
 
2483
  if (insn->in_use)
2484
    {
2485
      if ((insn->inst = (struct tic4x_inst *)
2486
           hash_find (tic4x_op_hash, insn->name)) == NULL)
2487
        {
2488
          as_bad (_("Unknown opcode `%s'."), insn->name);
2489
          insn->parallel = 0;
2490
          insn->in_use = 0;
2491
          return;
2492
        }
2493
 
2494
      inst = insn->inst;
2495
      first_inst = NULL;
2496
      do
2497
        {
2498
          ok = tic4x_operands_match (inst, insn, 1);
2499
          if (ok < 0)
2500
            {
2501
              if (!first_inst)
2502
                first_inst = inst;
2503
              ok = 0;
2504
            }
2505
      } while (!ok && !strcmp (inst->name, inst[1].name) && inst++);
2506
 
2507
      if (ok > 0)
2508
        {
2509
          tic4x_insn_check (insn);
2510
          tic4x_insn_output (insn);
2511
        }
2512
      else if (!ok)
2513
        {
2514
          if (first_inst)
2515
            tic4x_operands_match (first_inst, insn, 0);
2516
          as_bad (_("Invalid operands for %s"), insn->name);
2517
        }
2518
      else
2519
        as_bad (_("Invalid instruction %s"), insn->name);
2520
    }
2521
 
2522
  if (str && !parsed)
2523
    {
2524
      /* Find mnemonic.  */
2525
      s = str;
2526
      while (*s && *s != ' ')   /* Skip past instruction mnemonic.  */
2527
        s++;
2528
      if (*s)                   /* Null terminate for hash_find.  */
2529
        *s++ = '\0';            /* and skip past null.  */
2530
      strncpy (insn->name, str, TIC4X_NAME_MAX - 3);
2531
 
2532
      if ((i = tic4x_operands_parse (s, insn->operands, 0)) < 0)
2533
        {
2534
          insn->inst = NULL;    /* Flag that error occurred.  */
2535
          insn->parallel = 0;
2536
          insn->in_use = 0;
2537
          return;
2538
        }
2539
      insn->num_operands = i;
2540
      insn->in_use = 1;
2541
    }
2542
  else
2543
    insn->in_use = 0;
2544
  insn->parallel = 0;
2545
}
2546
 
2547
void
2548
tic4x_cleanup (void)
2549
{
2550
  if (insn->in_use)
2551
    md_assemble (NULL);
2552
}
2553
 
2554
/* Turn a string in input_line_pointer into a floating point constant
2555
   of type type, and store the appropriate bytes in *litP.  The number
2556
   of chars emitted is stored in *sizeP.  An error message is
2557
   returned, or NULL on OK.  */
2558
 
2559
char *
2560
md_atof (int type, char *litP, int *sizeP)
2561
{
2562
  int prec;
2563
  int ieee;
2564
  LITTLENUM_TYPE words[MAX_LITTLENUMS];
2565
  LITTLENUM_TYPE *wordP;
2566
  char *t;
2567
 
2568
  switch (type)
2569
    {
2570
    case 's':           /* .single  */
2571
    case 'S':
2572
      ieee = 0;
2573
      prec = 1;
2574
      break;
2575
 
2576
    case 'd':           /* .double  */
2577
    case 'D':
2578
    case 'f':           /* .float  */
2579
    case 'F':
2580
      ieee = 0;
2581
      prec = 2;         /* 1 32-bit word */
2582
      break;
2583
 
2584
    case 'i':           /* .ieee */
2585
    case 'I':
2586
      prec = 2;
2587
      ieee = 1;
2588
      type = 'f';  /* Rewrite type to be usable by atof_ieee().  */
2589
      break;
2590
 
2591
    case 'e':           /* .ldouble */
2592
    case 'E':
2593
      prec = 4;         /* 2 32-bit words */
2594
      ieee = 0;
2595
      break;
2596
 
2597
    default:
2598
      *sizeP = 0;
2599
      return _("Unrecognized or unsupported floating point constant");
2600
    }
2601
 
2602
  if (ieee)
2603
    t = atof_ieee (input_line_pointer, type, words);
2604
  else
2605
    t = tic4x_atof (input_line_pointer, type, words);
2606
  if (t)
2607
    input_line_pointer = t;
2608
  *sizeP = prec * sizeof (LITTLENUM_TYPE);
2609
 
2610
  /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
2611
     little endian byte order.  */
2612
  /* SES: However it is required to put the words (32-bits) out in the
2613
     correct order, hence we write 2 and 2 littlenums in little endian
2614
     order, while we keep the original order on successive words.  */
2615
  for (wordP = words; wordP<(words+prec) ; wordP+=2)
2616
    {
2617
      if (wordP < (words + prec - 1)) /* Dump wordP[1] (if we have one).  */
2618
        {
2619
          md_number_to_chars (litP, (valueT) (wordP[1]),
2620
                              sizeof (LITTLENUM_TYPE));
2621
          litP += sizeof (LITTLENUM_TYPE);
2622
        }
2623
 
2624
      /* Dump wordP[0] */
2625
      md_number_to_chars (litP, (valueT) (wordP[0]),
2626
                          sizeof (LITTLENUM_TYPE));
2627
      litP += sizeof (LITTLENUM_TYPE);
2628
    }
2629
  return NULL;
2630
}
2631
 
2632
void
2633
md_apply_fix (fixS *fixP, valueT *value, segT seg ATTRIBUTE_UNUSED)
2634
{
2635
  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
2636
  valueT val = *value;
2637
 
2638
  switch (fixP->fx_r_type)
2639
    {
2640
    case BFD_RELOC_HI16:
2641
      val >>= 16;
2642
      break;
2643
 
2644
    case BFD_RELOC_LO16:
2645
      val &= 0xffff;
2646
      break;
2647
    default:
2648
      break;
2649
    }
2650
 
2651
  switch (fixP->fx_r_type)
2652
    {
2653
    case BFD_RELOC_32:
2654
      buf[3] = val >> 24;
2655
    case BFD_RELOC_24:
2656
    case BFD_RELOC_24_PCREL:
2657
      buf[2] = val >> 16;
2658
    case BFD_RELOC_16:
2659
    case BFD_RELOC_16_PCREL:
2660
    case BFD_RELOC_LO16:
2661
    case BFD_RELOC_HI16:
2662
      buf[1] = val >> 8;
2663
      buf[0] = val;
2664
      break;
2665
 
2666
    case NO_RELOC:
2667
    default:
2668
      as_bad (_("Bad relocation type: 0x%02x"), fixP->fx_r_type);
2669
      break;
2670
    }
2671
 
2672
  if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) fixP->fx_done = 1;
2673
}
2674
 
2675
/* Should never be called for tic4x.  */
2676
void
2677
md_convert_frag (bfd *headers ATTRIBUTE_UNUSED,
2678
                 segT sec ATTRIBUTE_UNUSED,
2679
                 fragS *fragP ATTRIBUTE_UNUSED)
2680
{
2681
  as_fatal ("md_convert_frag");
2682
}
2683
 
2684
/* Should never be called for tic4x.  */
2685
void
2686
md_create_short_jump (char *ptr ATTRIBUTE_UNUSED,
2687
                      addressT from_addr ATTRIBUTE_UNUSED,
2688
                      addressT to_addr ATTRIBUTE_UNUSED,
2689
                      fragS *frag ATTRIBUTE_UNUSED,
2690
                      symbolS *to_symbol ATTRIBUTE_UNUSED)
2691
{
2692
  as_fatal ("md_create_short_jmp\n");
2693
}
2694
 
2695
/* Should never be called for tic4x.  */
2696
void
2697
md_create_long_jump (char *ptr ATTRIBUTE_UNUSED,
2698
                     addressT from_addr ATTRIBUTE_UNUSED,
2699
                     addressT to_addr ATTRIBUTE_UNUSED,
2700
                     fragS *frag ATTRIBUTE_UNUSED,
2701
                     symbolS *to_symbol ATTRIBUTE_UNUSED)
2702
{
2703
  as_fatal ("md_create_long_jump\n");
2704
}
2705
 
2706
/* Should never be called for tic4x.  */
2707
int
2708
md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
2709
                               segT segtype ATTRIBUTE_UNUSED)
2710
{
2711
  as_fatal ("md_estimate_size_before_relax\n");
2712
  return 0;
2713
}
2714
 
2715
 
2716
int
2717
md_parse_option (int c, char *arg)
2718
{
2719
  switch (c)
2720
    {
2721
    case OPTION_CPU:             /* cpu brand */
2722
      if (TOLOWER (*arg) == 'c')
2723
        arg++;
2724
      tic4x_cpu = atoi (arg);
2725
      if (!IS_CPU_TIC3X (tic4x_cpu) && !IS_CPU_TIC4X (tic4x_cpu))
2726
        as_warn (_("Unsupported processor generation %d"), tic4x_cpu);
2727
      break;
2728
 
2729
    case OPTION_REV:             /* cpu revision */
2730
      tic4x_revision = atoi (arg);
2731
      break;
2732
 
2733
    case 'b':
2734
      as_warn (_("Option -b is depreciated, please use -mbig"));
2735
    case OPTION_BIG:             /* big model */
2736
      tic4x_big_model = 1;
2737
      break;
2738
 
2739
    case 'p':
2740
      as_warn (_("Option -p is depreciated, please use -mmemparm"));
2741
    case OPTION_MEMPARM:         /* push args */
2742
      tic4x_reg_args = 0;
2743
      break;
2744
 
2745
    case 'r':
2746
      as_warn (_("Option -r is depreciated, please use -mregparm"));
2747
    case OPTION_REGPARM:        /* register args */
2748
      tic4x_reg_args = 1;
2749
      break;
2750
 
2751
    case 's':
2752
      as_warn (_("Option -s is depreciated, please use -msmall"));
2753
    case OPTION_SMALL:          /* small model */
2754
      tic4x_big_model = 0;
2755
      break;
2756
 
2757
    case OPTION_IDLE2:
2758
      tic4x_idle2 = 1;
2759
      break;
2760
 
2761
    case OPTION_LOWPOWER:
2762
      tic4x_lowpower = 1;
2763
      break;
2764
 
2765
    case OPTION_ENHANCED:
2766
      tic4x_enhanced = 1;
2767
      break;
2768
 
2769
    default:
2770
      return 0;
2771
    }
2772
 
2773
  return 1;
2774
}
2775
 
2776
void
2777
md_show_usage (FILE *stream)
2778
{
2779
  fprintf (stream,
2780
      _("\nTIC4X options:\n"
2781
        "  -mcpu=CPU  -mCPU        select architecture variant. CPU can be:\n"
2782
        "                            30 - TMS320C30\n"
2783
        "                            31 - TMS320C31, TMS320LC31\n"
2784
        "                            32 - TMS320C32\n"
2785
        "                            33 - TMS320VC33\n"
2786
        "                            40 - TMS320C40\n"
2787
        "                            44 - TMS320C44\n"
2788
        "  -mrev=REV               set cpu hardware revision (integer numbers).\n"
2789
        "                          Combinations of -mcpu and -mrev will enable/disable\n"
2790
        "                          the appropriate options (-midle2, -mlowpower and\n"
2791
        "                          -menhanced) according to the selected type\n"
2792
        "  -mbig                   select big memory model\n"
2793
        "  -msmall                 select small memory model (default)\n"
2794
        "  -mregparm               select register parameters (default)\n"
2795
        "  -mmemparm               select memory parameters\n"
2796
        "  -midle2                 enable IDLE2 support\n"
2797
        "  -mlowpower              enable LOPOWER and MAXSPEED support\n"
2798
        "  -menhanced              enable enhanced opcode support\n"));
2799
}
2800
 
2801
/* This is called when a line is unrecognized.  This is used to handle
2802
   definitions of TI C3x tools style local labels $n where n is a single
2803
   decimal digit.  */
2804
int
2805
tic4x_unrecognized_line (int c)
2806
{
2807
  int lab;
2808
  char *s;
2809
 
2810
  if (c != '$' || ! ISDIGIT (input_line_pointer[0]))
2811
    return 0;
2812
 
2813
  s = input_line_pointer;
2814
 
2815
  /* Let's allow multiple digit local labels.  */
2816
  lab = 0;
2817
  while (ISDIGIT (*s))
2818
    {
2819
      lab = lab * 10 + *s - '0';
2820
      s++;
2821
    }
2822
 
2823
  if (dollar_label_defined (lab))
2824
    {
2825
      as_bad (_("Label \"$%d\" redefined"), lab);
2826
      return 0;
2827
    }
2828
 
2829
  define_dollar_label (lab);
2830
  colon (dollar_label_name (lab, 0));
2831
  input_line_pointer = s + 1;
2832
 
2833
  return 1;
2834
}
2835
 
2836
/* Handle local labels peculiar to us referred to in an expression.  */
2837
symbolS *
2838
md_undefined_symbol (char *name)
2839
{
2840
  /* Look for local labels of the form $n.  */
2841
  if (name[0] == '$' && ISDIGIT (name[1]))
2842
    {
2843
      symbolS *symbolP;
2844
      char *s = name + 1;
2845
      int lab = 0;
2846
 
2847
      while (ISDIGIT ((unsigned char) *s))
2848
        {
2849
          lab = lab * 10 + *s - '0';
2850
          s++;
2851
        }
2852
      if (dollar_label_defined (lab))
2853
        {
2854
          name = dollar_label_name (lab, 0);
2855
          symbolP = symbol_find (name);
2856
        }
2857
      else
2858
        {
2859
          name = dollar_label_name (lab, 1);
2860
          symbolP = symbol_find_or_make (name);
2861
        }
2862
 
2863
      return symbolP;
2864
    }
2865
  return NULL;
2866
}
2867
 
2868
/* Parse an operand that is machine-specific.  */
2869
void
2870
md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
2871
{
2872
}
2873
 
2874
/* Round up a section size to the appropriate boundary---do we need this?  */
2875
valueT
2876
md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
2877
{
2878
  return size;                  /* Byte (i.e., 32-bit) alignment is fine?  */
2879
}
2880
 
2881
static int
2882
tic4x_pc_offset (unsigned int op)
2883
{
2884
  /* Determine the PC offset for a C[34]x instruction.
2885
     This could be simplified using some boolean algebra
2886
     but at the expense of readability.  */
2887
  switch (op >> 24)
2888
    {
2889
    case 0x60:                  /* br */
2890
    case 0x62:                  /* call  (C4x) */
2891
    case 0x64:                  /* rptb  (C4x) */
2892
      return 1;
2893
    case 0x61:                  /* brd */
2894
    case 0x63:                  /* laj */
2895
    case 0x65:                  /* rptbd (C4x) */
2896
      return 3;
2897
    case 0x66:                  /* swi */
2898
    case 0x67:
2899
      return 0;
2900
    default:
2901
      break;
2902
    }
2903
 
2904
  switch ((op & 0xffe00000) >> 20)
2905
    {
2906
    case 0x6a0:         /* bB */
2907
    case 0x720:         /* callB */
2908
    case 0x740:         /* trapB */
2909
      return 1;
2910
 
2911
    case 0x6a2:         /* bBd */
2912
    case 0x6a6:         /* bBat */
2913
    case 0x6aa:         /* bBaf */
2914
    case 0x722:         /* lajB */
2915
    case 0x748:         /* latB */
2916
    case 0x798:         /* rptbd */
2917
      return 3;
2918
 
2919
    default:
2920
      break;
2921
    }
2922
 
2923
  switch ((op & 0xfe200000) >> 20)
2924
    {
2925
    case 0x6e0:         /* dbB */
2926
      return 1;
2927
 
2928
    case 0x6e2:         /* dbBd */
2929
      return 3;
2930
 
2931
    default:
2932
      break;
2933
    }
2934
 
2935
  return 0;
2936
}
2937
 
2938
/* Exactly what point is a PC-relative offset relative TO?
2939
   With the C3x we have the following:
2940
   DBcond,  Bcond   disp + PC + 1 => PC
2941
   DBcondD, BcondD  disp + PC + 3 => PC
2942
 */
2943
long
2944
md_pcrel_from (fixS *fixP)
2945
{
2946
  unsigned char *buf;
2947
  unsigned int op;
2948
 
2949
  buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
2950
  op = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
2951
 
2952
  return ((fixP->fx_where + fixP->fx_frag->fr_address) >> 2) +
2953
    tic4x_pc_offset (op);
2954
}
2955
 
2956
/* Fill the alignment area with NOP's on .text, unless fill-data
2957
   was specified. */
2958
int
2959
tic4x_do_align (int alignment ATTRIBUTE_UNUSED,
2960
                const char *fill ATTRIBUTE_UNUSED,
2961
                int len ATTRIBUTE_UNUSED,
2962
                int max ATTRIBUTE_UNUSED)
2963
{
2964
  unsigned long nop = TIC_NOP_OPCODE;
2965
 
2966
  /* Because we are talking lwords, not bytes, adjust alignment to do words */
2967
  alignment += 2;
2968
 
2969
  if (alignment != 0 && !need_pass_2)
2970
    {
2971
      if (fill == NULL)
2972
        {
2973
          /*if (subseg_text_p (now_seg))*/  /* FIXME: doesn't work for .text for some reason */
2974
          frag_align_pattern( alignment, (const char *)&nop, sizeof(nop), max);
2975
          return 1;
2976
          /*else
2977
            frag_align (alignment, 0, max);*/
2978
        }
2979
      else if (len <= 1)
2980
        frag_align (alignment, *fill, max);
2981
      else
2982
        frag_align_pattern (alignment, fill, len, max);
2983
    }
2984
 
2985
  /* Return 1 to skip the default alignment function */
2986
  return 1;
2987
}
2988
 
2989
/* Look for and remove parallel instruction operator ||.  */
2990
void
2991
tic4x_start_line (void)
2992
{
2993
  char *s = input_line_pointer;
2994
 
2995
  SKIP_WHITESPACE ();
2996
 
2997
  /* If parallel instruction prefix found at start of line, skip it.  */
2998
  if (*input_line_pointer == '|' && input_line_pointer[1] == '|')
2999
    {
3000
      if (insn->in_use)
3001
        {
3002
          insn->parallel = 1;
3003
          input_line_pointer ++;
3004
          *input_line_pointer = ' ';
3005
          /* So line counters get bumped.  */
3006
          input_line_pointer[-1] = '\n';
3007
        }
3008
    }
3009
  else
3010
    {
3011
      /* Write out the previous insn here */
3012
      if (insn->in_use)
3013
        md_assemble (NULL);
3014
      input_line_pointer = s;
3015
    }
3016
}
3017
 
3018
arelent *
3019
tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixP)
3020
{
3021
  arelent *reloc;
3022
 
3023
  reloc = (arelent *) xmalloc (sizeof (arelent));
3024
 
3025
  reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
3026
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
3027
  reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
3028
  reloc->address /= OCTETS_PER_BYTE;
3029
  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
3030
  if (reloc->howto == (reloc_howto_type *) NULL)
3031
    {
3032
      as_bad_where (fixP->fx_file, fixP->fx_line,
3033
                    _("Reloc %d not supported by object file format"),
3034
                    (int) fixP->fx_r_type);
3035
      return NULL;
3036
    }
3037
 
3038
  if (fixP->fx_r_type == BFD_RELOC_HI16)
3039
    reloc->addend = fixP->fx_offset;
3040
  else
3041
    reloc->addend = fixP->fx_addnumber;
3042
 
3043
  return reloc;
3044
}

powered by: WebSVN 2.1.0

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