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