Add TMS320C4x support
[binutils.git] / gas / config / tc-tic4x.c
blobdbd71d0bbf9f89ddbd7018f4250386e87d0dc01a
1 /* tc-c4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
2 Copyright (C) 1997,1998, 2002 Free Software Foundation.
4 Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
6 This file is part of GAS, the GNU Assembler.
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.
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.
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. */
24 /* Things not currently implemented:
25 > .usect if has symbol on previous line
27 > .sym, .eos, .stag, .etag, .member
29 > Evaluation of constant floating point expressions (expr.c needs work!)
31 > Warnings issued if parallel load of same register
33 Note that this is primarily designed to handle the code generated
34 by GCC. Anything else is a bonus! */
36 #include <stdio.h>
37 #include <ctype.h>
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"
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. */
52 #define C4X_ALT_SYNTAX
54 /* Equal to MAX_PRECISION in atof-ieee.c. */
55 #define MAX_LITTLENUMS 6 /* (12 bytes) */
57 /* Handle of the inst mnemonic hash table. */
58 static struct hash_control *c4x_op_hash = NULL;
60 /* Handle asg pseudo. */
61 static struct hash_control *c4x_asg_hash = NULL;
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. */
67 typedef enum
69 M_UNKNOWN, M_IMMED, M_DIRECT, M_REGISTER, M_INDIRECT,
70 M_IMMED_F, M_PARALLEL, M_HI
72 c4x_addr_mode_t;
74 typedef struct c4x_operand
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. */
82 c4x_operand_t;
84 typedef struct c4x_insn
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];
99 c4x_insn_t;
101 static c4x_insn_t the_insn; /* Info about our instruction. */
102 static c4x_insn_t *insn = &the_insn;
104 static void c4x_asg PARAMS ((int));
105 static void c4x_bss PARAMS ((int));
106 static void c4x_globl PARAMS ((int));
107 static void c4x_eval PARAMS ((int));
108 static void c4x_cons PARAMS ((int));
109 static void c4x_set PARAMS ((int));
110 static void c4x_newblock PARAMS ((int));
111 static void c4x_pseudo_ignore PARAMS ((int));
112 static void c4x_sect PARAMS ((int));
113 static void c4x_usect PARAMS ((int));
114 static void c4x_version PARAMS ((int));
116 const pseudo_typeS
117 md_pseudo_table[] =
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},
160 int md_short_jump_size = 4;
161 int md_long_jump_size = 4;
162 const int md_reloc_size = RELSZ; /* Coff headers. */
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
167 const char comment_chars[] = ";!";
168 #else
169 const char comment_chars[] = ";";
170 #endif
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. */
179 const char line_comment_chars[] = "#*";
181 /* We needed an unused char for line separation to work around the
182 lack of macros, using sed and such. */
183 const char line_separator_chars[] = "&";
185 /* Chars that can be used to separate mant from exp in floating point nums. */
186 const char EXP_CHARS[] = "eE";
188 /* Chars that mean this number is a floating point constant. */
189 /* As in 0f12.456 */
190 /* or 0d1.2345e12 */
191 const char FLT_CHARS[] = "fFilsS";
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. */
197 /* Flonums returned here. */
198 extern FLONUM_TYPE generic_floating_point_number;
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)
206 /* Turn generic_floating_point_number into a real short/float/double. */
208 c4x_gen_to_words (FLONUM_TYPE flonum, LITTLENUM_TYPE *words, int precision)
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. */
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.
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].
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
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]).
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.
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,
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)
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.
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
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:
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
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.
298 To convert a generic flonum into a TMS320C3X floating point
299 number, here's what we try to do....
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.
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.
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.
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. */
347 if (precision != S_PRECISION)
348 words[1] = 0x0000;
350 /* 0.0e0 seen. */
351 if (flonum.low > flonum.leader)
353 words[0] = 0x8000;
354 return return_value;
357 /* NaN: We can't do much... */
358 if (flonum.sign == 0)
360 as_bad ("Nan, using zero.");
361 words[0] = 0x8000;
362 return return_value;
364 else if (flonum.sign == 'P')
366 /* +INF: Replace with maximum float. */
367 if (precision == S_PRECISION)
368 words[0] = 0x77ff;
369 else
371 words[0] = 0x7f7f;
372 words[1] = 0xffff;
374 return return_value;
376 else if (flonum.sign == 'N')
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;
386 exponent = (flonum.exponent + flonum.leader - flonum.low + 1) * 16;
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. */
395 if (precision == S_PRECISION) /* Allow 1 rounding bit. */
397 exponent_bits = 4;
398 mantissa_bits = 12; /* Include suppr. bit but not rounding bit. */
400 else
402 exponent_bits = 8;
403 mantissa_bits = 24;
406 shift = mantissa_bits - shift;
408 smant = 0;
409 for (p = flonum.leader; p >= flonum.low && shift > -16; p--)
411 tmp = shift >= 0 ? *p << shift : *p >> -shift;
412 smant |= tmp;
413 shift -= 16;
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;
421 /* The number may be unnormalised so renormalise it... */
422 if (smant >> mantissa_bits)
424 smant >>= 1;
425 exponent++;
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. */
434 sone = (1 << (mantissa_bits - 1));
435 if (flonum.sign == '+')
436 sfract = smant - sone; /* smant - 1.0. */
437 else
439 /* This seems to work. */
440 if (smant == sone)
442 exponent--;
443 sfract = 0;
445 else
446 sfract = (sone << 1) - smant; /* 2.0 - smant. */
447 sfract |= sone; /* Insert sign bit. */
450 if (abs (exponent) >= (1 << (exponent_bits - 1)))
451 as_bad ("Cannot represent exponent in %d bits", exponent_bits);
453 /* Force exponent to fit in desired field width. */
454 exponent &= (1 << (exponent_bits)) - 1;
455 sfract |= exponent << mantissa_bits;
457 if (precision == S_PRECISION)
458 words[0] = sfract;
459 else
461 words[0] = sfract >> 16;
462 words[1] = sfract & 0xffff;
465 return return_value;
468 /* Returns pointer past text consumed. */
469 char *
470 c4x_atof (char *str, char what_kind, LITTLENUM_TYPE *words)
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;
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;
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';
493 /* Use more LittleNums than seems necessary: the highest flonum may
494 have 15 leading 0 bits, so could be useless. */
496 memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
498 switch (what_kind)
500 case 's':
501 case 'S':
502 precision = S_PRECISION;
503 break;
505 case 'd':
506 case 'D':
507 case 'f':
508 case 'F':
509 precision = F_PRECISION;
510 break;
512 default:
513 as_bad ("Invalid floating point number");
514 return (NULL);
517 generic_floating_point_number.high
518 = generic_floating_point_number.low + precision - 1 + GUARD;
520 if (atof_generic (&return_value, ".", EXP_CHARS,
521 &generic_floating_point_number))
523 as_bad ("Invalid floating point number");
524 return (NULL);
527 c4x_gen_to_words (generic_floating_point_number,
528 words, precision);
530 /* Restore the generic_floating_point_number's storage alloc (and
531 everything else). */
532 generic_floating_point_number = save_gen_flonum;
534 return return_value;
537 static void
538 c4x_insert_reg (char *regname, int regnum)
540 char buf[32];
541 int i;
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';
549 symbol_table_insert (symbol_new (buf, reg_section, (valueT) regnum,
550 &zero_address_frag));
553 static void
554 c4x_insert_sym (char *symname, int value)
556 symbolS *symbolP;
558 symbolP = symbol_new (symname, absolute_section,
559 (valueT) value, &zero_address_frag);
560 SF_SET_LOCAL (symbolP);
561 symbol_table_insert (symbolP);
564 static char *
565 c4x_expression (char *str, expressionS *exp)
567 char *s;
568 char *t;
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. */
578 static char *
579 c4x_expression_abs (char *str, int *value)
581 char *s;
582 char *t;
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;
592 static void
593 c4x_emit_char (char c)
595 expressionS exp;
597 exp.X_op = O_constant;
598 exp.X_add_number = c;
599 emit_expr (&exp, 4);
602 static void
603 c4x_seg_alloc (char *name, segT seg, int size, symbolS *symbolP)
605 /* Note that the size is in words
606 so we multiply it by 4 to get the number of bytes to allocate. */
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. */
612 if (size)
614 char *p;
616 p = frag_var (rs_fill, 1, 1, (relax_substateT) 0,
617 (symbolS *) symbolP,
618 size * OCTETS_PER_BYTE, (char *) 0);
619 *p = 0;
623 /* .asg ["]character-string["], symbol */
624 static void
625 c4x_asg (int x)
627 char c;
628 char *name;
629 char *str;
630 char *tmp;
632 SKIP_WHITESPACE ();
633 str = input_line_pointer;
635 /* Skip string expression. */
636 while (*input_line_pointer != ',' && *input_line_pointer)
637 input_line_pointer++;
638 if (*input_line_pointer != ',')
640 as_bad ("Comma expected\n");
641 return;
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 ();
660 /* .bss symbol, size */
661 static void
662 c4x_bss (int x)
664 char c;
665 char *name;
666 char *p;
667 int size;
668 segT current_seg;
669 subsegT current_subseg;
670 symbolS *symbolP;
672 current_seg = now_seg; /* Save current seg. */
673 current_subseg = now_subseg; /* Save current subseg. */
675 SKIP_WHITESPACE ();
676 name = input_line_pointer;
677 c = get_symbol_end (); /* Get terminator. */
678 if (c != ',')
680 as_bad (".bss size argument missing\n");
681 return;
684 input_line_pointer =
685 c4x_expression_abs (++input_line_pointer, &size);
686 if (size < 0)
688 as_bad (".bss size %d < 0!", size);
689 return;
691 subseg_set (bss_section, 0);
692 symbolP = symbol_find_or_make (name);
694 if (S_GET_SEGMENT (symbolP) == bss_section)
695 symbol_get_frag (symbolP)->fr_symbol = 0;
697 symbol_set_frag (symbolP, frag_now);
699 p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
700 size * OCTETS_PER_BYTE, (char *) 0);
701 *p = 0; /* Fill char. */
703 S_SET_SEGMENT (symbolP, bss_section);
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);
711 subseg_set (current_seg, current_subseg); /* Restore current seg. */
712 demand_empty_rest_of_line ();
715 void
716 c4x_globl (int ignore)
718 char *name;
719 int c;
720 symbolS *symbolP;
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 == ',')
732 input_line_pointer++;
733 SKIP_WHITESPACE ();
734 if (*input_line_pointer == '\n')
735 c = '\n';
738 while (c == ',');
740 demand_empty_rest_of_line ();
743 /* Handle .byte, .word. .int, .long */
744 static void
745 c4x_cons (int bytes)
747 register unsigned int c;
750 SKIP_WHITESPACE ();
751 if (*input_line_pointer == '"')
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] == '\"');
758 else
760 expressionS exp;
762 input_line_pointer = c4x_expression (input_line_pointer, &exp);
763 if (exp.X_op == O_constant)
765 switch (bytes)
767 case 1:
768 exp.X_add_number &= 255;
769 break;
770 case 2:
771 exp.X_add_number &= 65535;
772 break;
775 /* Perhaps we should disallow .byte and .hword with
776 a non constant expression that will require relocation. */
777 emit_expr (&exp, 4);
780 while (*input_line_pointer++ == ',');
782 input_line_pointer--; /* Put terminator back into stream. */
783 demand_empty_rest_of_line ();
786 /* .eval expression, symbol */
787 static void
788 c4x_eval (int x)
790 char c;
791 int value;
792 char *name;
794 SKIP_WHITESPACE ();
795 input_line_pointer =
796 c4x_expression_abs (input_line_pointer, &value);
797 if (*input_line_pointer++ != ',')
799 as_bad ("Symbol missing\n");
800 return;
802 name = input_line_pointer;
803 c = get_symbol_end (); /* Get terminator. */
804 demand_empty_rest_of_line ();
805 c4x_insert_sym (name, value);
808 /* Reset local labels. */
809 static void
810 c4x_newblock (int x)
812 dollar_label_clear ();
815 /* .sect "section-name" [, value] */
816 /* .sect ["]section-name[:subsection-name]["] [, value] */
817 static void
818 c4x_sect (int x)
820 char c;
821 char *section_name;
822 char *subsection_name;
823 char *name;
824 segT seg;
825 int num;
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);
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 == ':')
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");
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]. */
853 if (c == ',')
854 input_line_pointer =
855 c4x_expression_abs (input_line_pointer, &num);
856 else if (*input_line_pointer == ',')
858 input_line_pointer =
859 c4x_expression_abs (++input_line_pointer, &num);
861 else
862 num = 0;
864 seg = subseg_new (name, num);
865 if (line_label != NULL)
867 S_SET_SEGMENT (line_label, seg);
868 symbol_set_frag (line_label, frag_now);
871 if (bfd_get_section_flags (stdoutput, seg) == SEC_NO_FLAGS)
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 ()));
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;
886 demand_empty_rest_of_line ();
889 /* symbol[:] .set value or .set symbol, value */
890 static void
891 c4x_set (int x)
893 symbolS *symbolP;
895 SKIP_WHITESPACE ();
896 if ((symbolP = line_label) == NULL)
898 char c;
899 char *name;
901 name = input_line_pointer;
902 c = get_symbol_end (); /* Get terminator. */
903 if (c != ',')
905 as_bad (".set syntax invalid\n");
906 ignore_rest_of_line ();
907 return;
909 symbolP = symbol_find_or_make (name);
911 else
912 symbol_table_insert (symbolP);
914 pseudo_set (symbolP);
915 demand_empty_rest_of_line ();
918 /* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
919 static void
920 c4x_usect (int x)
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;
930 current_seg = now_seg; /* save current seg. */
931 current_subseg = now_subseg; /* save current subseg. */
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);
942 if (c == ',')
943 input_line_pointer =
944 c4x_expression_abs (input_line_pointer, &size);
945 else if (*input_line_pointer == ',')
947 input_line_pointer =
948 c4x_expression_abs (++input_line_pointer, &size);
950 else
951 size = 0;
953 /* Read a possibly present third argument (alignment flag) [VK]. */
954 if (*input_line_pointer == ',')
956 input_line_pointer =
957 c4x_expression_abs (++input_line_pointer, &alignment_flag);
959 else
960 alignment_flag = 0;
961 if (alignment_flag)
962 as_warn (".usect: non-zero alignment flag ignored");
964 seg = subseg_new (name, 0);
965 if (line_label != NULL)
967 S_SET_SEGMENT (line_label, seg);
968 symbol_set_frag (line_label, frag_now);
969 S_SET_VALUE (line_label, frag_now_fix ());
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);
977 if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
978 S_SET_STORAGE_CLASS (line_label, C_STAT);
980 subseg_set (current_seg, current_subseg); /* Restore current seg. */
981 demand_empty_rest_of_line ();
984 /* .version cpu-version. */
985 static void
986 c4x_version (int x)
988 unsigned int temp;
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);
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 ();
1002 static void
1003 c4x_pseudo_ignore (int x)
1005 /* We could print warning message here... */
1007 /* Ignore everything until end of line. */
1008 while (!is_end_of_line[(unsigned char) *input_line_pointer++]);
1011 static void
1012 c4x_init_regtable (void)
1014 unsigned int i;
1016 for (i = 0; i < c3x_num_registers; i++)
1017 c4x_insert_reg (c3x_registers[i].name,
1018 c3x_registers[i].regno);
1020 if (IS_CPU_C4X (c4x_cpu))
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);
1029 static void
1030 c4x_init_symbols (void)
1032 /* The TI tools accept case insensitive versions of these symbols,
1033 we don't !
1035 For TI C/Asm 5.0
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
1046 .REGPARM 1 or 0 1 if -mr option used
1047 .BIGMODEL 1 or 0 1 if -mb option used
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
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);
1083 /* Insert a new instruction template into hash table. */
1084 static int
1085 c4x_inst_insert (c4x_inst_t *inst)
1087 static char prev_name[16];
1088 const char *retval = NULL;
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;
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;
1103 /* Make a new instruction template. */
1104 static c4x_inst_t *
1105 c4x_inst_make (char *name, unsigned long opcode, char *args)
1107 static c4x_inst_t *insts = NULL;
1108 static char *names = NULL;
1109 static int index = 0;
1111 if (insts == NULL)
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);
1119 insts[index].name = names;
1120 insts[index].opcode = opcode;
1121 insts[index].opmask = 0xffffffff;
1122 insts[index].args = args;
1123 index++;
1126 *names++ = *name++;
1127 while (*name);
1128 *names++ = '\0';
1130 return &insts[index - 1];
1133 /* Add instruction template, creating dynamic templates as required. */
1134 static int
1135 c4x_inst_add (c4x_inst_t *insts)
1137 char *s = insts->name;
1138 char *d;
1139 unsigned int i;
1140 int ok = 1;
1141 char name[16];
1143 d = name;
1145 while (1)
1147 switch (*s)
1149 case 'B':
1150 case 'C':
1151 /* Dynamically create all the conditional insts. */
1152 for (i = 0; i < num_conds; i++)
1154 c4x_inst_t *inst;
1155 int k = 0;
1156 char *c = c4x_conds[i].name;
1157 char *e = d;
1159 while (*c)
1160 *e++ = *c++;
1161 c = s + 1;
1162 while (*c)
1163 *e++ = *c++;
1164 *e = '\0';
1166 /* If instruction found then have already processed it. */
1167 if (hash_find (c4x_op_hash, name))
1168 return 1;
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++;
1180 while (!strcmp (insts->name,
1181 insts[k].name));
1183 return ok;
1184 break;
1186 case '\0':
1187 return c4x_inst_insert (insts);
1188 break;
1190 default:
1191 *d++ = *s++;
1192 break;
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. */
1200 void
1201 md_begin (void)
1203 int ok = 1;
1204 unsigned int i;
1206 /* Create hash table for mnemonics. */
1207 c4x_op_hash = hash_new ();
1209 /* Create hash table for asg pseudo. */
1210 c4x_asg_hash = hash_new ();
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]);
1216 if (IS_CPU_C4X (c4x_cpu))
1218 for (i = 0; i < c4x_num_insts; i++)
1219 ok &= c4x_inst_add ((void *) &c4x_insts[i]);
1222 /* Create dummy inst to avoid errors accessing end of table. */
1223 c4x_inst_make ("", 0, "");
1225 if (!ok)
1226 as_fatal ("Broken assembler. No assembly attempted.");
1228 /* Add registers to symbol table. */
1229 c4x_init_regtable ();
1231 /* Add predefined symbols to symbol table. */
1232 c4x_init_symbols ();
1235 void
1236 c4x_end (void)
1238 bfd_set_arch_mach (stdoutput, bfd_arch_tic4x,
1239 IS_CPU_C4X (c4x_cpu) ? bfd_mach_c4x : bfd_mach_c3x);
1242 static int
1243 c4x_indirect_parse (c4x_operand_t *operand,
1244 const c4x_indirect_t *indirect)
1246 char *n = indirect->name;
1247 char *s = input_line_pointer;
1248 char *b;
1249 symbolS *symbolP;
1250 char name[32];
1252 operand->disp = 0;
1253 for (; *n; n++)
1255 switch (*n)
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;
1269 if (S_GET_SEGMENT (symbolP) != reg_section)
1270 return 0;
1272 operand->aregno = S_GET_VALUE (symbolP);
1273 if (operand->aregno >= REG_AR0 && operand->aregno <= REG_AR7)
1274 break;
1276 as_bad ("Auxiliary register AR0--AR7 required for indirect");
1277 return -1;
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)
1290 as_bad ("Bad displacement %d (require 0--255)\n",
1291 operand->disp);
1292 return -1;
1294 break;
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)
1308 as_bad ("Index register IR0,IR1 required for displacement");
1309 return -1;
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;
1318 case '(':
1319 if (*s != '(') /* No displacement, assume to be 1. */
1321 operand->disp = 1;
1322 while (*n != ')')
1323 n++;
1325 else
1326 s++;
1327 break;
1329 default:
1330 if (tolower (*s) != *n)
1331 return 0;
1332 s++;
1335 if (*s != ' ' && *s != ',' && *s != '\0')
1336 return 0;
1337 input_line_pointer = s;
1338 return 1;
1341 char *
1342 c4x_operand_parse (char *s, c4x_operand_t *operand)
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;
1353 input_line_pointer = s;
1354 SKIP_WHITESPACE ();
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)
1361 *input_line_pointer = c;
1362 input_line_pointer = (char *) entry;
1364 else
1366 *input_line_pointer = c;
1367 input_line_pointer = str;
1370 operand->mode = M_UNKNOWN;
1371 switch (*input_line_pointer)
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;
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)
1388 if (exp->X_add_number)
1389 as_bad ("Number too large"); /* bignum required */
1390 else
1392 c4x_gen_to_words (generic_floating_point_number,
1393 operand->fwords, S_PRECISION);
1394 operand->mode = M_IMMED_F;
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)
1401 operand->mode = M_HI;
1402 break;
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)
1411 if (exp->X_add_number > 0)
1412 as_bad ("Number too large"); /* bignum required. */
1413 else
1415 c4x_gen_to_words (generic_floating_point_number,
1416 operand->fwords, S_PRECISION);
1417 operand->mode = M_IMMED_F;
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)
1424 operand->mode = M_IMMED;
1425 break;
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)
1439 if (exp->X_add_number < 0)
1440 as_bad ("Direct value of %ld is not suitable",
1441 (long) exp->X_add_number);
1443 operand->mode = M_DIRECT;
1444 break;
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)
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;
1463 else
1464 as_bad ("Unknown indirect addressing mode");
1465 break;
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)
1473 know (exp->X_add_symbol == 0);
1474 know (exp->X_op_symbol == 0);
1475 operand->mode = M_REGISTER;
1476 break;
1478 else if (exp->X_op == O_big)
1480 if (exp->X_add_number > 0)
1481 as_bad ("Number too large"); /* bignum required. */
1482 else
1484 c4x_gen_to_words (generic_floating_point_number,
1485 operand->fwords, S_PRECISION);
1486 operand->mode = M_IMMED_F;
1488 break;
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)
1494 operand->mode = M_DIRECT;
1495 break;
1497 #endif
1499 if (entry == NULL)
1500 new = input_line_pointer;
1501 input_line_pointer = save;
1502 return new;
1505 static int
1506 c4x_operands_match (c4x_inst_t *inst, c4x_insn_t *insn)
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;
1516 /* Build the opcode, checking as we go to make sure that the
1517 operands match.
1519 If an operand matches, we modify insn or opcode appropriately,
1520 and do a "continue". If an operand fails to match, we "break". */
1522 insn->nchars = 4; /* Instructions always 4 bytes. */
1523 insn->reloc = NO_RELOC;
1524 insn->pcrel = 0;
1526 if (*args == '\0')
1528 insn->opcode = opcode;
1529 return num_operands == 0;
1532 for (;; ++args)
1534 switch (*args)
1537 case '\0': /* End of args. */
1538 if (num_operands == 1)
1540 insn->opcode = opcode;
1541 return ret;
1543 break; /* Too many operands. */
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)
1552 /* Maybe for C3x we should check for 8 bit number. */
1553 INSERTS (opcode, exp->X_add_number, 15, 0);
1554 continue;
1556 else if (exp->X_op == O_symbol)
1558 insn->reloc = BFD_RELOC_HI16;
1559 insn->exp = *exp;
1560 continue;
1562 break; /* Not direct (dp) addressing. */
1564 case '@': /* direct. */
1565 if (operand->mode != M_DIRECT)
1566 break;
1567 if (exp->X_op == O_constant)
1569 /* Store only the 16 LSBs of the number. */
1570 INSERTS (opcode, exp->X_add_number, 15, 0);
1571 continue;
1573 else if (exp->X_op == O_symbol)
1575 insn->reloc = BFD_RELOC_LO16;
1576 insn->exp = *exp;
1577 continue;
1579 break; /* Not direct addressing. */
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
1589 as_bad ("Destination register must be ARn");
1590 ret = -1;
1592 continue;
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)
1600 if (exp->X_add_number < (1 << 24))
1602 INSERTU (opcode, exp->X_add_number, 23, 0);
1603 continue;
1605 else
1607 as_bad ("Immediate value of %ld is too large",
1608 (long) exp->X_add_number);
1609 ret = -1;
1610 continue;
1613 if (IS_CPU_C4X (c4x_cpu))
1615 insn->reloc = BFD_RELOC_24_PCREL;
1616 insn->pcrel = 1;
1618 else
1620 insn->reloc = BFD_RELOC_24;
1621 insn->pcrel = 0;
1623 insn->exp = *exp;
1624 continue;
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)
1634 as_bad ("Invalid indirect addressing mode");
1635 ret = -1;
1636 continue;
1638 INSERTU (opcode, operand->aregno - REG_AR0, 2, 0);
1639 INSERTU (opcode, operand->disp, 7, 3);
1640 continue;
1642 case 'E':
1643 if (!(operand->mode == M_REGISTER))
1644 break;
1645 INSERTU (opcode, exp->X_add_number, 7, 0);
1646 continue;
1648 case 'F':
1649 if (operand->mode != M_IMMED_F
1650 && !(operand->mode == M_IMMED && exp->X_op == O_constant))
1651 break;
1653 if (operand->mode != M_IMMED_F)
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];
1659 /* Create floating point number string. */
1660 sprintf (string, "%d.0", (int) exp->X_add_number);
1661 c4x_atof (string, 's', operand->fwords);
1664 INSERTU (opcode, operand->fwords[0], 15, 0);
1665 continue;
1667 case 'G':
1668 if (operand->mode != M_REGISTER)
1669 break;
1670 INSERTU (opcode, exp->X_add_number, 15, 8);
1671 continue;
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
1681 as_bad ("Register must be R0--R7");
1682 ret = -1;
1684 continue;
1686 case 'I':
1687 if (operand->mode != M_INDIRECT)
1688 break;
1689 if (operand->disp != 0 && operand->disp != 1)
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;
1698 INSERTU (opcode, operand->aregno - REG_AR0, 2, 0);
1699 INSERTU (opcode, operand->expr.X_add_number, 7, 3);
1700 continue;
1702 case 'J':
1703 if (operand->mode != M_INDIRECT)
1704 break;
1705 if (operand->disp != 0 && operand->disp != 1)
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;
1714 INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
1715 INSERTU (opcode, operand->expr.X_add_number, 15, 11);
1716 continue;
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
1726 as_bad ("Register must be R0--R7");
1727 ret = -1;
1729 continue;
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
1739 as_bad ("Register must be R0--R7");
1740 ret = -1;
1742 continue;
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
1752 as_bad ("Destination register must be R2 or R3");
1753 ret = -1;
1755 continue;
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
1765 as_bad ("Destination register must be R0 or R1");
1766 ret = -1;
1768 continue;
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)
1779 as_bad ("Invalid indirect addressing mode");
1780 ret = -1;
1781 continue;
1783 INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
1784 INSERTU (opcode, operand->disp, 15, 11);
1785 continue;
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)
1793 if (exp->X_add_number >= -32768 && exp->X_add_number <= 32767)
1795 INSERTS (opcode, exp->X_add_number, 15, 0);
1796 continue;
1798 else
1800 as_bad ("Displacement value of %ld is too large",
1801 (long) exp->X_add_number);
1802 ret = -1;
1803 continue;
1806 insn->reloc = BFD_RELOC_16_PCREL;
1807 insn->pcrel = 1;
1808 insn->exp = *exp;
1809 continue;
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;
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;
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)
1830 as_bad ("Floating point number not valid in expression");
1831 ret = -1;
1832 continue;
1834 if (exp->X_op == O_constant)
1836 if (exp->X_add_number >= -32768 && exp->X_add_number <= 65535)
1838 INSERTS (opcode, exp->X_add_number, 15, 0);
1839 continue;
1841 else
1843 as_bad ("Signed immediate value %ld too large",
1844 (long) exp->X_add_number);
1845 ret = -1;
1846 continue;
1849 else if (exp->X_op == O_symbol)
1851 if (operand->mode == M_HI)
1853 insn->reloc = BFD_RELOC_HI16;
1855 else
1857 insn->reloc = BFD_RELOC_LO16;
1859 insn->exp = *exp;
1860 continue;
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;
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)
1877 if (exp->X_add_number < 16 && exp->X_add_number >= -16)
1879 INSERTS (opcode, exp->X_add_number, 20, 16);
1880 continue;
1882 else
1884 as_bad ("Immediate value of %ld is too large",
1885 (long) exp->X_add_number);
1886 ret = -1;
1887 continue;
1890 break; /* No relocations allowed. */
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)
1897 if (exp->X_add_number < (1 << 16) && exp->X_add_number >= 0)
1899 INSERTU (opcode, exp->X_add_number, 15, 0);
1900 continue;
1902 else
1904 as_bad ("Unsigned immediate value %ld too large",
1905 (long) exp->X_add_number);
1906 ret = -1;
1907 continue;
1910 else if (exp->X_op == O_symbol)
1912 if (operand->mode == M_HI)
1913 insn->reloc = BFD_RELOC_HI16;
1914 else
1915 insn->reloc = BFD_RELOC_LO16;
1917 insn->exp = *exp;
1918 continue;
1920 insn->reloc = BFD_RELOC_16;
1921 insn->exp = *exp;
1922 continue;
1924 case 'V': /* Trap numbers (immediate field). */
1925 if (operand->mode != M_IMMED)
1926 break;
1927 if (exp->X_op == O_constant)
1929 if (exp->X_add_number < 512 && IS_CPU_C4X (c4x_cpu))
1931 INSERTU (opcode, exp->X_add_number, 8, 0);
1932 continue;
1934 else if (exp->X_add_number < 32 && IS_CPU_C3X (c4x_cpu))
1936 INSERTU (opcode, exp->X_add_number | 0x20, 4, 0);
1937 continue;
1939 else
1941 as_bad ("Immediate value of %ld is too large",
1942 (long) exp->X_add_number);
1943 ret = -1;
1944 continue;
1947 break; /* No relocations allowed. */
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)
1956 as_bad ("Floating point number not valid in expression");
1957 ret = -1;
1958 continue;
1960 if (exp->X_op == O_constant)
1962 if (exp->X_add_number >= -256 && exp->X_add_number <= 127)
1964 INSERTS (opcode, exp->X_add_number, 7, 0);
1965 continue;
1967 else
1969 as_bad ("Immediate value %ld too large",
1970 (long) exp->X_add_number);
1971 ret = -1;
1972 continue;
1975 insn->reloc = BFD_RELOC_16;
1976 insn->exp = *exp;
1977 continue;
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
1987 as_bad ("Register must be ivtp or tvtp");
1988 ret = -1;
1990 continue;
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
2000 as_bad ("Register must be address register");
2001 ret = -1;
2003 continue;
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
2013 as_bad ("Register must be ivtp or tvtp");
2014 ret = -1;
2016 continue;
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;
2026 case '|': /* treat as `,' if have ldi_ldi form. */
2027 if (insn->parallel)
2029 if (--num_operands < 0)
2030 break; /* Too few operands. */
2031 operand++;
2032 if (operand->mode != M_PARALLEL)
2033 break;
2035 /* Fall through. */
2037 case ',': /* Another operand. */
2038 if (--num_operands < 0)
2039 break; /* Too few operands. */
2040 operand++;
2041 exp = &operand->expr;
2042 continue;
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;
2053 default:
2054 BAD_CASE (*args);
2056 return 0;
2060 void
2061 c4x_insn_output (c4x_insn_t *insn)
2063 char *dst;
2065 /* Grab another fragment for opcode. */
2066 dst = frag_more (insn->nchars);
2068 /* Put out opcode word as a series of bytes in little endian order. */
2069 md_number_to_chars (dst, insn->opcode, insn->nchars);
2071 /* Put out the symbol-dependent stuff. */
2072 if (insn->reloc != NO_RELOC)
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);
2084 /* Parse the operands. */
2085 int
2086 c4x_operands_parse (char *s, c4x_operand_t *operands, int num_operands)
2088 if (!*s)
2089 return num_operands;
2092 s = c4x_operand_parse (s, &operands[num_operands++]);
2093 while (num_operands < C4X_OPERANDS_MAX && *s++ == ',');
2095 if (num_operands > C4X_OPERANDS_MAX)
2097 as_bad ("Too many operands scanned");
2098 return -1;
2100 return num_operands;
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. */
2106 void
2107 md_assemble (char *str)
2109 int ok = 0;
2110 char *s;
2111 int i;
2112 int parsed = 0;
2113 c4x_inst_t *inst; /* Instruction template. */
2115 if (str && insn->parallel)
2117 int star;
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));
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 = '*';
2136 insn->operands[insn->num_operands++].mode = M_PARALLEL;
2138 if ((i = c4x_operands_parse
2139 (s, insn->operands, insn->num_operands)) < 0)
2141 insn->parallel = 0;
2142 insn->in_use = 0;
2143 return;
2145 insn->num_operands = i;
2146 parsed = 1;
2149 if (insn->in_use)
2151 if ((insn->inst = (struct c4x_inst *)
2152 hash_find (c4x_op_hash, insn->name)) == NULL)
2154 as_bad ("Unknown opcode `%s'.", insn->name);
2155 insn->parallel = 0;
2156 insn->in_use = 0;
2157 return;
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. */
2167 inst = insn->inst;
2170 ok = c4x_operands_match (inst, insn);
2171 while (!ok && !strcmp (inst->name, inst[1].name) && inst++);
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);
2181 if (str && !parsed)
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);
2191 if ((i = c4x_operands_parse (s, insn->operands, 0)) < 0)
2193 insn->inst = NULL; /* Flag that error occured. */
2194 insn->parallel = 0;
2195 insn->in_use = 0;
2196 return;
2198 insn->num_operands = i;
2199 insn->in_use = 1;
2201 else
2202 insn->in_use = 0;
2203 insn->parallel = 0;
2206 void
2207 c4x_cleanup (void)
2209 if (insn->in_use)
2210 md_assemble (NULL);
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. */
2218 char *
2219 md_atof (int type, char *litP, int *sizeP)
2221 int prec;
2222 int ieee;
2223 LITTLENUM_TYPE words[MAX_LITTLENUMS];
2224 LITTLENUM_TYPE *wordP;
2225 unsigned char *t;
2227 switch (type)
2229 case 's': /* .single */
2230 case 'S':
2231 ieee = 0;
2232 prec = 1;
2233 break;
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;
2243 case 'i': /* .ieee */
2244 prec = 2;
2245 ieee = 1;
2246 break;
2248 case 'l': /* .ldouble */
2249 prec = 4; /* 2 32-bit words */
2250 ieee = 1;
2251 break;
2253 default:
2254 *sizeP = 0;
2255 return "Bad call to md_atof()";
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--;)
2270 md_number_to_chars (litP, (valueT) (*wordP--),
2271 sizeof (LITTLENUM_TYPE));
2272 litP += sizeof (LITTLENUM_TYPE);
2274 return 0;
2277 void
2278 md_apply_fix3 (fixS *fixP, valueT *value, segT seg ATTRIBUTE_UNUSED)
2280 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
2281 valueT val = *value;
2283 switch (fixP->fx_r_type)
2285 case BFD_RELOC_HI16:
2286 val >>= 16;
2287 break;
2289 case BFD_RELOC_LO16:
2290 val &= 0xffff;
2291 break;
2292 default:
2293 break;
2296 switch (fixP->fx_r_type)
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;
2311 case NO_RELOC:
2312 default:
2313 as_bad ("Bad relocation type: 0x%02x", fixP->fx_r_type);
2314 break;
2317 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) fixP->fx_done = 1;
2320 /* Should never be called for c4x. */
2321 void
2322 md_convert_frag (bfd *headers, segT sec, fragS *fragP)
2324 as_fatal ("md_convert_frag");
2327 /* Should never be called for c4x. */
2328 void
2329 md_create_short_jump (char *ptr, addressT from_addr, addressT to_addr,
2330 fragS *frag, symbolS *to_symbol)
2332 as_fatal ("md_create_short_jmp\n");
2335 /* Should never be called for c4x. */
2336 void
2337 md_create_long_jump (char *ptr, addressT from_addr, addressT to_addr,
2338 fragS *frag, symbolS *to_symbol)
2340 as_fatal ("md_create_long_jump\n");
2343 /* Should never be called for c4x. */
2345 md_estimate_size_before_relax (register fragS *fragP, segT segtype)
2347 as_fatal ("md_estimate_size_before_relax\n");
2348 return 0;
2351 CONST char *md_shortopts = "bm:prs";
2352 struct option md_longopts[] =
2354 {NULL, no_argument, NULL, 0}
2357 size_t md_longopts_size = sizeof (md_longopts);
2360 md_parse_option (int c, char *arg)
2362 switch (c)
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;
2387 return 1;
2390 void
2391 md_show_usage (FILE *stream)
2393 fputs ("\
2394 C[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);
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. */
2407 int
2408 c4x_unrecognized_line (int c)
2410 int lab;
2411 char *s;
2413 if (c != '$' || !isdigit (input_line_pointer[0]))
2414 return 0;
2416 s = input_line_pointer;
2418 /* Let's allow multiple digit local labels. */
2419 lab = 0;
2420 while (isdigit (*s))
2422 lab = lab * 10 + *s - '0';
2423 s++;
2426 if (dollar_label_defined (lab))
2428 as_bad ("Label \"$%d\" redefined", lab);
2429 return 0;
2432 define_dollar_label (lab);
2433 colon (dollar_label_name (lab, 0));
2434 input_line_pointer = s + 1;
2436 return 1;
2439 /* Handle local labels peculiar to us referred to in an expression. */
2440 symbolS *
2441 md_undefined_symbol (char *name)
2443 /* Look for local labels of the form $n. */
2444 if (name[0] == '$' && isdigit (name[1]))
2446 symbolS *symbolP;
2447 char *s = name + 1;
2448 int lab = 0;
2450 while (isdigit ((unsigned char) *s))
2452 lab = lab * 10 + *s - '0';
2453 s++;
2455 if (dollar_label_defined (lab))
2457 name = dollar_label_name (lab, 0);
2458 symbolP = symbol_find (name);
2460 else
2462 name = dollar_label_name (lab, 1);
2463 symbolP = symbol_find_or_make (name);
2466 return symbolP;
2468 return NULL;
2471 /* Parse an operand that is machine-specific. */
2472 void
2473 md_operand (expressionS *expressionP)
2477 /* Round up a section size to the appropriate boundary---do we need this? */
2478 valueT
2479 md_section_align (segT segment, valueT size)
2481 return size; /* Byte (i.e., 32-bit) alignment is fine? */
2484 static int
2485 c4x_pc_offset (unsigned int op)
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)
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;
2507 switch ((op & 0xffe00000) >> 20)
2509 case 0x6a0: /* bB */
2510 case 0x720: /* callB */
2511 case 0x740: /* trapB */
2512 return 1;
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;
2522 default:
2523 break;
2526 switch ((op & 0xfe200000) >> 20)
2528 case 0x6e0: /* dbB */
2529 return 1;
2531 case 0x6e2: /* dbBd */
2532 return 3;
2534 default:
2535 break;
2538 return 0;
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
2546 long
2547 md_pcrel_from (fixS *fixP)
2549 unsigned char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
2550 unsigned int op;
2552 op = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
2554 return ((fixP->fx_where + fixP->fx_frag->fr_address) >> 2) +
2555 c4x_pc_offset (op);
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. */
2560 int
2561 c4x_do_align (int alignment, const char *fill, int len, int max)
2563 char *p;
2565 p = frag_var (rs_align, 1, 1, (relax_substateT) 0,
2566 (symbolS *) 0, (long) 2, (char *) 0);
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;
2573 /* Look for and remove parallel instruction operator ||. */
2574 void
2575 c4x_start_line (void)
2577 char *s = input_line_pointer;
2579 SKIP_WHITESPACE ();
2581 /* If parallel instruction prefix found at start of line, skip it. */
2582 if (*input_line_pointer == '|' && input_line_pointer[1] == '|')
2584 if (insn->in_use)
2586 insn->parallel = 1;
2587 input_line_pointer += 2;
2588 /* So line counters get bumped. */
2589 input_line_pointer[-1] = '\n';
2592 else
2594 if (insn->in_use)
2595 md_assemble (NULL);
2596 input_line_pointer = s;
2600 arelent *
2601 tc_gen_reloc (asection *seg, fixS *fixP)
2603 arelent *reloc;
2605 reloc = (arelent *) xmalloc (sizeof (arelent));
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)
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;
2620 if (fixP->fx_r_type == BFD_RELOC_HI16)
2621 reloc->addend = fixP->fx_offset;
2622 else
2623 reloc->addend = fixP->fx_addnumber;
2625 return reloc;