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