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