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)
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! */
40 #include "opcode/tic4x.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. */
69 M_UNKNOWN
, M_IMMED
, M_DIRECT
, M_REGISTER
, M_INDIRECT
,
70 M_IMMED_F
, M_PARALLEL
, M_HI
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. */
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
];
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));
119 {"align", s_align_bytes
, 32},
120 {"ascii", c4x_cons
, 1},
121 {"asciz", c4x_pseudo_ignore
, 0},
123 {"asect", c4x_pseudo_ignore
, 0}, /* Absolute named section. */
124 {"block", s_space
, 0},
125 {"byte", c4x_cons
, 1},
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},
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. */
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},
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
[] = ";!";
169 const char comment_chars
[] = ";";
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. */
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. */
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. */
215 unsigned int sone
; /* Scaled one. */
216 unsigned int sfract
; /* Scaled fraction. */
217 unsigned int smant
; /* Scaled mantissa. */
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
225 For example 2e-3 is stored with exp = -4 and
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
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
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
)
351 if (flonum
.low
> flonum
.leader
)
357 /* NaN: We can't do much... */
358 if (flonum
.sign
== 0)
360 as_bad ("Nan, using zero.");
364 else if (flonum
.sign
== 'P')
366 /* +INF: Replace with maximum float. */
367 if (precision
== S_PRECISION
)
376 else if (flonum
.sign
== 'N')
378 /* -INF: Replace with maximum float. */
379 if (precision
== S_PRECISION
)
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. */
393 exponent
-= (16 - shift
); /* Adjust exponent. */
395 if (precision
== S_PRECISION
) /* Allow 1 rounding bit. */
398 mantissa_bits
= 12; /* Include suppr. bit but not rounding bit. */
406 shift
= mantissa_bits
- shift
;
409 for (p
= flonum
.leader
; p
>= flonum
.low
&& shift
> -16; p
--)
411 tmp
= shift
>= 0 ? *p
<< shift
: *p
>> -shift
;
416 /* OK, we've got our scaled mantissa so let's round it up
417 and drop the rounding bit. */
421 /* The number may be unnormalised so renormalise it... */
422 if (smant
>> mantissa_bits
)
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. */
439 /* This seems to work. */
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
)
461 words
[0] = sfract
>> 16;
462 words
[1] = sfract
& 0xffff;
468 /* Returns pointer past text consumed. */
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
];
476 /* Number of 16-bit words in the format. */
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
;
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
);
502 precision
= S_PRECISION
;
509 precision
= F_PRECISION
;
513 as_bad ("Invalid floating point number");
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");
527 c4x_gen_to_words (generic_floating_point_number
,
530 /* Restore the generic_floating_point_number's storage alloc (and
532 generic_floating_point_number
= save_gen_flonum
;
538 c4x_insert_reg (char *regname
, int regnum
)
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
];
549 symbol_table_insert (symbol_new (buf
, reg_section
, (valueT
) regnum
,
550 &zero_address_frag
));
554 c4x_insert_sym (char *symname
, int value
)
558 symbolP
= symbol_new (symname
, absolute_section
,
559 (valueT
) value
, &zero_address_frag
);
560 SF_SET_LOCAL (symbolP
);
561 symbol_table_insert (symbolP
);
565 c4x_expression (char *str
, expressionS
*exp
)
570 t
= input_line_pointer
; /* Save line pointer. */
571 input_line_pointer
= str
;
573 s
= input_line_pointer
;
574 input_line_pointer
= t
; /* Restore line pointer. */
575 return s
; /* Return pointer to where parsing stopped. */
579 c4x_expression_abs (char *str
, int *value
)
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. */
593 c4x_emit_char (char c
)
597 exp
.X_op
= O_constant
;
598 exp
.X_add_number
= c
;
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
616 p
= frag_var (rs_fill
, 1, 1, (relax_substateT
) 0,
618 size
* OCTETS_PER_BYTE
, (char *) 0);
623 /* .asg ["]character-string["], symbol */
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");
643 *input_line_pointer
++ = '\0';
644 name
= input_line_pointer
;
645 c
= get_symbol_end (); /* Get terminator. */
646 tmp
= xmalloc (strlen (str
) + 1);
649 tmp
= xmalloc (strlen (name
) + 1);
652 if (hash_find (c4x_asg_hash
, name
))
653 hash_replace (c4x_asg_hash
, name
, (PTR
) str
);
655 hash_insert (c4x_asg_hash
, name
, (PTR
) str
);
656 *input_line_pointer
= c
;
657 demand_empty_rest_of_line ();
660 /* .bss symbol, size */
669 subsegT current_subseg
;
672 current_seg
= now_seg
; /* Save current seg. */
673 current_subseg
= now_subseg
; /* Save current subseg. */
676 name
= input_line_pointer
;
677 c
= get_symbol_end (); /* Get terminator. */
680 as_bad (".bss size argument missing\n");
685 c4x_expression_abs (++input_line_pointer
, &size
);
688 as_bad (".bss size %d < 0!", size
);
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 ();
716 c4x_globl (int ignore
)
724 name
= input_line_pointer
;
725 c
= get_symbol_end ();
726 symbolP
= symbol_find_or_make (name
);
727 *input_line_pointer
= c
;
729 S_SET_STORAGE_CLASS (symbolP
, C_EXT
);
732 input_line_pointer
++;
734 if (*input_line_pointer
== '\n')
740 demand_empty_rest_of_line ();
743 /* Handle .byte, .word. .int, .long */
747 register unsigned int c
;
751 if (*input_line_pointer
== '"')
753 input_line_pointer
++;
754 while (is_a_char (c
= next_char_of_string ()))
756 know (input_line_pointer
[-1] == '\"');
762 input_line_pointer
= c4x_expression (input_line_pointer
, &exp
);
763 if (exp
.X_op
== O_constant
)
768 exp
.X_add_number
&= 255;
771 exp
.X_add_number
&= 65535;
775 /* Perhaps we should disallow .byte and .hword with
776 a non constant expression that will require relocation. */
780 while (*input_line_pointer
++ == ',');
782 input_line_pointer
--; /* Put terminator back into stream. */
783 demand_empty_rest_of_line ();
786 /* .eval expression, symbol */
796 c4x_expression_abs (input_line_pointer
, &value
);
797 if (*input_line_pointer
++ != ',')
799 as_bad ("Symbol missing\n");
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. */
812 dollar_label_clear ();
815 /* .sect "section-name" [, value] */
816 /* .sect ["]section-name[:subsection-name]["] [, value] */
822 char *subsection_name
;
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
840 Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>. */
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()
855 c4x_expression_abs (input_line_pointer
, &num
);
856 else if (*input_line_pointer
== ',')
859 c4x_expression_abs (++input_line_pointer
, &num
);
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 */
896 if ((symbolP
= line_label
) == NULL
)
901 name
= input_line_pointer
;
902 c
= get_symbol_end (); /* Get terminator. */
905 as_bad (".set syntax invalid\n");
906 ignore_rest_of_line ();
909 symbolP
= symbol_find_or_make (name
);
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] */
926 int size
, alignment_flag
;
928 subsegT current_subseg
;
930 current_seg
= now_seg
; /* save current seg. */
931 current_subseg
= now_subseg
; /* save current subseg. */
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
);
944 c4x_expression_abs (input_line_pointer
, &size
);
945 else if (*input_line_pointer
== ',')
948 c4x_expression_abs (++input_line_pointer
, &size
);
953 /* Read a possibly present third argument (alignment flag) [VK]. */
954 if (*input_line_pointer
== ',')
957 c4x_expression_abs (++input_line_pointer
, &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. */
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",
996 if (c4x_cpu
&& temp
!= c4x_cpu
)
997 as_warn ("Changing processor generation on fly not supported...\n");
999 demand_empty_rest_of_line ();
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
++]);
1012 c4x_init_regtable (void)
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
);
1030 c4x_init_symbols (void)
1032 /* The TI tools accept case insensitive versions of these symbols,
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
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. */
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')
1094 retval
= hash_insert (c4x_op_hash
, inst
->name
, (PTR
) inst
);
1096 fprintf (stderr
, "internal error: can't hash `%s': %s\n",
1097 inst
->name
, retval
);
1099 strcpy (prev_name
, inst
->name
);
1100 return retval
== NULL
;
1103 /* Make a new instruction template. */
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;
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
;
1130 return &insts
[index
- 1];
1133 /* Add instruction template, creating dynamic templates as required. */
1135 c4x_inst_add (c4x_inst_t
*insts
)
1137 char *s
= insts
->name
;
1151 /* Dynamically create all the conditional insts. */
1152 for (i
= 0; i
< num_conds
; i
++)
1156 char *c
= c4x_conds
[i
].name
;
1166 /* If instruction found then have already processed it. */
1167 if (hash_find (c4x_op_hash
, name
))
1172 inst
= c4x_inst_make (name
, insts
[k
].opcode
+
1173 (c4x_conds
[i
].cond
<<
1174 (*s
== 'B' ? 16 : 23)),
1176 if (k
== 0) /* Save strcmp() with following func. */
1177 ok
&= c4x_inst_insert (inst
);
1180 while (!strcmp (insts
->name
,
1187 return c4x_inst_insert (insts
);
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
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, "");
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 ();
1238 bfd_set_arch_mach (stdoutput
, bfd_arch_tic4x
,
1239 IS_CPU_C4X (c4x_cpu
) ? bfd_mach_c4x
: bfd_mach_c3x
);
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
;
1257 case 'a': /* Need to match aux register. */
1259 #ifdef C4X_ALT_SYNTAX
1263 while (isalnum (*s
))
1266 if (!(symbolP
= symbol_find (name
)))
1269 if (S_GET_SEGMENT (symbolP
) != reg_section
)
1272 operand
->aregno
= S_GET_VALUE (symbolP
);
1273 if (operand
->aregno
>= REG_AR0
&& operand
->aregno
<= REG_AR7
)
1276 as_bad ("Auxiliary register AR0--AR7 required for indirect");
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. */
1284 s
= c4x_expression (s
, &operand
->expr
);
1285 if (operand
->expr
.X_op
!= O_constant
)
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",
1296 case 'y': /* Need to match IR0. */
1297 case 'z': /* Need to match IR1. */
1298 #ifdef C4X_ALT_SYNTAX
1302 s
= c4x_expression (s
, &operand
->expr
);
1303 if (operand
->expr
.X_op
!= O_register
)
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");
1312 if (*n
== 'y' && operand
->expr
.X_add_number
== REG_IR0
)
1314 if (*n
== 'z' && operand
->expr
.X_add_number
== REG_IR1
)
1319 if (*s
!= '(') /* No displacement, assume to be 1. */
1330 if (tolower (*s
) != *n
)
1335 if (*s
!= ' ' && *s
!= ',' && *s
!= '\0')
1337 input_line_pointer
= s
;
1342 c4x_operand_parse (char *s
, c4x_operand_t
*operand
)
1347 expressionS
*exp
= &operand
->expr
;
1348 char *save
= input_line_pointer
;
1351 struct hash_entry
*entry
= NULL
;
1353 input_line_pointer
= s
;
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
;
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
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
;
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 */
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
;
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. */
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
;
1429 as_bad ("Expecting a constant value");
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
;
1448 for (i
= 0; i
< num_indirects
; i
++)
1449 if ((ret
= c4x_indirect_parse (operand
, &c4x_indirects
[i
])))
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;
1464 as_bad ("Unknown indirect addressing mode");
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
;
1478 else if (exp
->X_op
== O_big
)
1480 if (exp
->X_add_number
> 0)
1481 as_bad ("Number too large"); /* bignum required. */
1484 c4x_gen_to_words (generic_floating_point_number
,
1485 operand
->fwords
, S_PRECISION
);
1486 operand
->mode
= M_IMMED_F
;
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
;
1500 new = input_line_pointer
;
1501 input_line_pointer
= save
;
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
;
1516 /* Build the opcode, checking as we go to make sure that the
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
;
1528 insn
->opcode
= opcode
;
1529 return num_operands
== 0;
1537 case '\0': /* End of args. */
1538 if (num_operands
== 1)
1540 insn
->opcode
= opcode
;
1543 break; /* Too many operands. */
1545 case '#': /* This is only used for ldp. */
1546 if (operand
->mode
!= M_DIRECT
&& operand
->mode
!= M_IMMED
)
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);
1556 else if (exp
->X_op
== O_symbol
)
1558 insn
->reloc
= BFD_RELOC_HI16
;
1562 break; /* Not direct (dp) addressing. */
1564 case '@': /* direct. */
1565 if (operand
->mode
!= M_DIRECT
)
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);
1573 else if (exp
->X_op
== O_symbol
)
1575 insn
->reloc
= BFD_RELOC_LO16
;
1579 break; /* Not direct addressing. */
1582 if (operand
->mode
!= M_REGISTER
)
1584 reg
= exp
->X_add_number
;
1585 if (reg
>= REG_AR0
&& reg
<= REG_AR7
)
1586 INSERTU (opcode
, reg
- REG_AR0
, 24, 22);
1589 as_bad ("Destination register must be ARn");
1594 case 'B': /* Unsigned integer immediate. */
1595 /* Allow br label or br @label. */
1596 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
1598 if (exp
->X_op
== O_constant
)
1600 if (exp
->X_add_number
< (1 << 24))
1602 INSERTU (opcode
, exp
->X_add_number
, 23, 0);
1607 as_bad ("Immediate value of %ld is too large",
1608 (long) exp
->X_add_number
);
1613 if (IS_CPU_C4X (c4x_cpu
))
1615 insn
->reloc
= BFD_RELOC_24_PCREL
;
1620 insn
->reloc
= BFD_RELOC_24
;
1627 if (!IS_CPU_C4X (c4x_cpu
))
1629 if (operand
->mode
!= M_INDIRECT
)
1631 if (operand
->expr
.X_add_number
!= 0
1632 && operand
->expr
.X_add_number
!= 0x18)
1634 as_bad ("Invalid indirect addressing mode");
1638 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1639 INSERTU (opcode
, operand
->disp
, 7, 3);
1643 if (!(operand
->mode
== M_REGISTER
))
1645 INSERTU (opcode
, exp
->X_add_number
, 7, 0);
1649 if (operand
->mode
!= M_IMMED_F
1650 && !(operand
->mode
== M_IMMED
&& exp
->X_op
== O_constant
))
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 ?! */
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);
1668 if (operand
->mode
!= M_REGISTER
)
1670 INSERTU (opcode
, exp
->X_add_number
, 15, 8);
1674 if (operand
->mode
!= M_REGISTER
)
1676 reg
= exp
->X_add_number
;
1677 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1678 INSERTU (opcode
, reg
- REG_R0
, 18, 16);
1681 as_bad ("Register must be R0--R7");
1687 if (operand
->mode
!= M_INDIRECT
)
1689 if (operand
->disp
!= 0 && operand
->disp
!= 1)
1691 if (IS_CPU_C4X (c4x_cpu
))
1693 as_bad ("Invalid indirect addressing mode displacement %d",
1698 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1699 INSERTU (opcode
, operand
->expr
.X_add_number
, 7, 3);
1703 if (operand
->mode
!= M_INDIRECT
)
1705 if (operand
->disp
!= 0 && operand
->disp
!= 1)
1707 if (IS_CPU_C4X (c4x_cpu
))
1709 as_bad ("Invalid indirect addressing mode displacement %d",
1714 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
1715 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
1719 if (operand
->mode
!= M_REGISTER
)
1721 reg
= exp
->X_add_number
;
1722 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1723 INSERTU (opcode
, reg
- REG_R0
, 21, 19);
1726 as_bad ("Register must be R0--R7");
1732 if (operand
->mode
!= M_REGISTER
)
1734 reg
= exp
->X_add_number
;
1735 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1736 INSERTU (opcode
, reg
- REG_R0
, 24, 22);
1739 as_bad ("Register must be R0--R7");
1745 if (operand
->mode
!= M_REGISTER
)
1747 reg
= exp
->X_add_number
;
1748 if (reg
== REG_R2
|| reg
== REG_R3
)
1749 INSERTU (opcode
, reg
- REG_R2
, 22, 22);
1752 as_bad ("Destination register must be R2 or R3");
1758 if (operand
->mode
!= M_REGISTER
)
1760 reg
= exp
->X_add_number
;
1761 if (reg
== REG_R0
|| reg
== REG_R1
)
1762 INSERTU (opcode
, reg
- REG_R0
, 23, 23);
1765 as_bad ("Destination register must be R0 or R1");
1771 if (!IS_CPU_C4X (c4x_cpu
))
1773 if (operand
->mode
!= M_INDIRECT
)
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");
1783 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
1784 INSERTU (opcode
, operand
->disp
, 15, 11);
1787 case 'P': /* PC relative displacement. */
1788 /* Allow br label or br @label. */
1789 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
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);
1800 as_bad ("Displacement value of %ld is too large",
1801 (long) exp
->X_add_number
);
1806 insn
->reloc
= BFD_RELOC_16_PCREL
;
1812 if (operand
->mode
!= M_REGISTER
)
1814 reg
= exp
->X_add_number
;
1815 INSERTU (opcode
, reg
, 15, 0);
1819 if (operand
->mode
!= M_REGISTER
)
1821 reg
= exp
->X_add_number
;
1822 INSERTU (opcode
, reg
, 20, 16);
1825 case 'S': /* Short immediate int. */
1826 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
1828 if (exp
->X_op
== O_big
)
1830 as_bad ("Floating point number not valid in expression");
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);
1843 as_bad ("Signed immediate value %ld too large",
1844 (long) exp
->X_add_number
);
1849 else if (exp
->X_op
== O_symbol
)
1851 if (operand
->mode
== M_HI
)
1853 insn
->reloc
= BFD_RELOC_HI16
;
1857 insn
->reloc
= BFD_RELOC_LO16
;
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
1866 insn
->reloc
= BFD_RELOC_16
;
1870 case 'T': /* 5-bit immediate value for c4x stik. */
1871 if (!IS_CPU_C4X (c4x_cpu
))
1873 if (operand
->mode
!= M_IMMED
)
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);
1884 as_bad ("Immediate value of %ld is too large",
1885 (long) exp
->X_add_number
);
1890 break; /* No relocations allowed. */
1892 case 'U': /* Unsigned integer immediate. */
1893 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
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);
1904 as_bad ("Unsigned immediate value %ld too large",
1905 (long) exp
->X_add_number
);
1910 else if (exp
->X_op
== O_symbol
)
1912 if (operand
->mode
== M_HI
)
1913 insn
->reloc
= BFD_RELOC_HI16
;
1915 insn
->reloc
= BFD_RELOC_LO16
;
1920 insn
->reloc
= BFD_RELOC_16
;
1924 case 'V': /* Trap numbers (immediate field). */
1925 if (operand
->mode
!= M_IMMED
)
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);
1934 else if (exp
->X_add_number
< 32 && IS_CPU_C3X (c4x_cpu
))
1936 INSERTU (opcode
, exp
->X_add_number
| 0x20, 4, 0);
1941 as_bad ("Immediate value of %ld is too large",
1942 (long) exp
->X_add_number
);
1947 break; /* No relocations allowed. */
1949 case 'W': /* Short immediate int (0--7). */
1950 if (!IS_CPU_C4X (c4x_cpu
))
1952 if (operand
->mode
!= M_IMMED
)
1954 if (exp
->X_op
== O_big
)
1956 as_bad ("Floating point number not valid in expression");
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);
1969 as_bad ("Immediate value %ld too large",
1970 (long) exp
->X_add_number
);
1975 insn
->reloc
= BFD_RELOC_16
;
1979 case 'X': /* Expansion register for c4x. */
1980 if (operand
->mode
!= M_REGISTER
)
1982 reg
= exp
->X_add_number
;
1983 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
1984 INSERTU (opcode
, reg
- REG_IVTP
, 4, 0);
1987 as_bad ("Register must be ivtp or tvtp");
1992 case 'Y': /* Address register for c4x lda. */
1993 if (operand
->mode
!= M_REGISTER
)
1995 reg
= exp
->X_add_number
;
1996 if (reg
>= REG_AR0
&& reg
<= REG_SP
)
1997 INSERTU (opcode
, reg
, 20, 16);
2000 as_bad ("Register must be address register");
2005 case 'Z': /* Expansion register for c4x. */
2006 if (operand
->mode
!= M_REGISTER
)
2008 reg
= exp
->X_add_number
;
2009 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2010 INSERTU (opcode
, reg
- REG_IVTP
, 20, 16);
2013 as_bad ("Register must be ivtp or tvtp");
2019 if (operand
->mode
!= M_INDIRECT
)
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);
2026 case '|': /* treat as `,' if have ldi_ldi form. */
2029 if (--num_operands
< 0)
2030 break; /* Too few operands. */
2032 if (operand
->mode
!= M_PARALLEL
)
2037 case ',': /* Another operand. */
2038 if (--num_operands
< 0)
2039 break; /* Too few operands. */
2041 exp
= &operand
->expr
;
2044 case ';': /* Another optional operand. */
2045 if (num_operands
== 1 || operand
[1].mode
== M_PARALLEL
)
2047 if (--num_operands
< 0)
2048 break; /* Too few operands. */
2050 exp
= &operand
->expr
;
2061 c4x_insn_output (c4x_insn_t
*insn
)
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 */
2084 /* Parse the operands. */
2086 c4x_operands_parse (char *s
, c4x_operand_t
*operands
, int num_operands
)
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");
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. */
2107 md_assemble (char *str
)
2113 c4x_inst_t
*inst
; /* Instruction template. */
2115 if (str
&& insn
->parallel
)
2119 /* Find mnemonic (second part of parallel instruction). */
2121 /* Skip past instruction mnemonic. */
2122 while (*s
&& *s
!= ' ' && *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. */
2136 insn
->operands
[insn
->num_operands
++].mode
= M_PARALLEL
;
2138 if ((i
= c4x_operands_parse
2139 (s
, insn
->operands
, insn
->num_operands
)) < 0)
2145 insn
->num_operands
= i
;
2151 if ((insn
->inst
= (struct c4x_inst
*)
2152 hash_find (c4x_op_hash
, insn
->name
)) == NULL
)
2154 as_bad ("Unknown opcode `%s'.", insn
->name
);
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. */
2170 ok
= c4x_operands_match (inst
, insn
);
2171 while (!ok
&& !strcmp (inst
->name
, inst
[1].name
) && inst
++);
2174 c4x_insn_output (insn
);
2176 as_bad ("Invalid operands for %s", insn
->name
);
2178 as_bad ("Invalid instruction %s", insn
->name
);
2183 /* Find mnemonic. */
2185 while (*s
&& *s
!= ' ') /* Skip past instruction mnemonic. */
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. */
2198 insn
->num_operands
= i
;
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. */
2219 md_atof (int type
, char *litP
, int *sizeP
)
2223 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2224 LITTLENUM_TYPE
*wordP
;
2229 case 's': /* .single */
2235 case 'd': /* .double */
2237 case 'f': /* .float or .single */
2240 prec
= 2; /* 1 32-bit word */
2243 case 'i': /* .ieee */
2248 case 'l': /* .ldouble */
2249 prec
= 4; /* 2 32-bit words */
2255 return "Bad call to md_atof()";
2259 t
= atof_ieee (input_line_pointer
, type
, words
);
2261 t
= c4x_atof (input_line_pointer
, type
, words
);
2263 input_line_pointer
= t
;
2264 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
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
);
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
:
2289 case BFD_RELOC_LO16
:
2296 switch (fixP
->fx_r_type
)
2301 case BFD_RELOC_24_PCREL
:
2304 case BFD_RELOC_16_PCREL
:
2305 case BFD_RELOC_LO16
:
2306 case BFD_RELOC_HI16
:
2313 as_bad ("Bad relocation type: 0x%02x", fixP
->fx_r_type
);
2317 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0) fixP
->fx_done
= 1;
2320 /* Should never be called for c4x. */
2322 md_convert_frag (bfd
*headers
, segT sec
, fragS
*fragP
)
2324 as_fatal ("md_convert_frag");
2327 /* Should never be called for c4x. */
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. */
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");
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
)
2364 case 'b': /* big model */
2367 case 'm': /* -m[c][34]x */
2368 if (tolower (*arg
) == 'c')
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
);
2374 case 'p': /* push args */
2377 case 'r': /* register args */
2380 case 's': /* small model */
2391 md_show_usage (FILE *stream
)
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",
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
2408 c4x_unrecognized_line (int c
)
2413 if (c
!= '$' || !isdigit (input_line_pointer
[0]))
2416 s
= input_line_pointer
;
2418 /* Let's allow multiple digit local labels. */
2420 while (isdigit (*s
))
2422 lab
= lab
* 10 + *s
- '0';
2426 if (dollar_label_defined (lab
))
2428 as_bad ("Label \"$%d\" redefined", lab
);
2432 define_dollar_label (lab
);
2433 colon (dollar_label_name (lab
, 0));
2434 input_line_pointer
= s
+ 1;
2439 /* Handle local labels peculiar to us referred to in an expression. */
2441 md_undefined_symbol (char *name
)
2443 /* Look for local labels of the form $n. */
2444 if (name
[0] == '$' && isdigit (name
[1]))
2450 while (isdigit ((unsigned char) *s
))
2452 lab
= lab
* 10 + *s
- '0';
2455 if (dollar_label_defined (lab
))
2457 name
= dollar_label_name (lab
, 0);
2458 symbolP
= symbol_find (name
);
2462 name
= dollar_label_name (lab
, 1);
2463 symbolP
= symbol_find_or_make (name
);
2471 /* Parse an operand that is machine-specific. */
2473 md_operand (expressionS
*expressionP
)
2477 /* Round up a section size to the appropriate boundary---do we need this? */
2479 md_section_align (segT segment
, valueT size
)
2481 return size
; /* Byte (i.e., 32-bit) alignment is fine? */
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. */
2493 case 0x62: /* call (C4x) */
2494 case 0x64: /* rptb (C4x) */
2496 case 0x61: /* brd */
2497 case 0x63: /* laj */
2498 case 0x65: /* rptbd (C4x) */
2500 case 0x66: /* swi */
2507 switch ((op
& 0xffe00000) >> 20)
2509 case 0x6a0: /* bB */
2510 case 0x720: /* callB */
2511 case 0x740: /* trapB */
2514 case 0x6a2: /* bBd */
2515 case 0x6a6: /* bBat */
2516 case 0x6aa: /* bBaf */
2517 case 0x722: /* lajB */
2518 case 0x748: /* latB */
2519 case 0x798: /* rptbd */
2526 switch ((op
& 0xfe200000) >> 20)
2528 case 0x6e0: /* dbB */
2531 case 0x6e2: /* dbBd */
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
2547 md_pcrel_from (fixS
*fixP
)
2549 unsigned char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
2552 op
= (buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
2554 return ((fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) >> 2) +
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. */
2561 c4x_do_align (int alignment
, const char *fill
, int len
, int max
)
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. */
2573 /* Look for and remove parallel instruction operator ||. */
2575 c4x_start_line (void)
2577 char *s
= input_line_pointer
;
2581 /* If parallel instruction prefix found at start of line, skip it. */
2582 if (*input_line_pointer
== '|' && input_line_pointer
[1] == '|')
2587 input_line_pointer
+= 2;
2588 /* So line counters get bumped. */
2589 input_line_pointer
[-1] = '\n';
2596 input_line_pointer
= s
;
2601 tc_gen_reloc (asection
*seg
, fixS
*fixP
)
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
);
2620 if (fixP
->fx_r_type
== BFD_RELOC_HI16
)
2621 reloc
->addend
= fixP
->fx_offset
;
2623 reloc
->addend
= fixP
->fx_addnumber
;