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