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