1 /* tc-tic4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
2 Copyright (C) 1997,1998, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010,
3 2012 Free Software Foundation. Inc.
5 Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
7 This file is part of GAS, the GNU Assembler.
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to
21 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
22 Boston, MA 02110-1301, USA. */
27 o .align cannot handle fill-data-width larger than 0xFF/8-bits. It
28 should be possible to define a 32-bits pattern.
30 o .align: Implement a 'bu' insn if the number of nop's exceeds 4
31 within the align frag. if(fragsize>4words) insert bu fragend+1
34 o .usect if has symbol on previous line not implemented
36 o .sym, .eos, .stag, .etag, .member not implemented
38 o Evaluation of constant floating point expressions (expr.c needs
41 o Support 'abc' constants (that is 0x616263). */
44 #include "safe-ctype.h"
45 #include "opcode/tic4x.h"
49 /* OK, we accept a syntax similar to the other well known C30
50 assembly tools. With TIC4X_ALT_SYNTAX defined we are more
51 flexible, allowing a more Unix-like syntax: `%' in front of
52 register names, `#' in front of immediate constants, and
53 not requiring `@' in front of direct addresses. */
55 #define TIC4X_ALT_SYNTAX
57 /* Equal to MAX_PRECISION in atof-ieee.c. */
58 #define MAX_LITTLENUMS 6 /* (12 bytes) */
60 /* Handle of the inst mnemonic hash table. */
61 static struct hash_control *tic4x_op_hash = NULL;
63 /* Handle asg pseudo. */
64 static struct hash_control *tic4x_asg_hash = NULL;
66 static unsigned int tic4x_cpu = 0; /* Default to TMS320C40. */
67 static unsigned int tic4x_revision = 0; /* CPU revision */
68 static unsigned int tic4x_idle2 = 0; /* Idle2 support */
69 static unsigned int tic4x_lowpower = 0; /* Lowpower support */
70 static unsigned int tic4x_enhanced = 0; /* Enhanced opcode support */
71 static unsigned int tic4x_big_model = 0; /* Default to small memory model. */
72 static unsigned int tic4x_reg_args = 0; /* Default to args passed on stack. */
73 static unsigned long tic4x_oplevel = 0; /* Opcode level */
75 #define OPTION_CPU 'm'
76 #define OPTION_BIG (OPTION_MD_BASE + 1)
77 #define OPTION_SMALL (OPTION_MD_BASE + 2)
78 #define OPTION_MEMPARM (OPTION_MD_BASE + 3)
79 #define OPTION_REGPARM (OPTION_MD_BASE + 4)
80 #define OPTION_IDLE2 (OPTION_MD_BASE + 5)
81 #define OPTION_LOWPOWER (OPTION_MD_BASE + 6)
82 #define OPTION_ENHANCED (OPTION_MD_BASE + 7)
83 #define OPTION_REV (OPTION_MD_BASE + 8)
85 CONST char *md_shortopts = "bm:prs";
86 struct option md_longopts[] =
88 { "mcpu", required_argument, NULL, OPTION_CPU },
89 { "mdsp", required_argument, NULL, OPTION_CPU },
90 { "mbig", no_argument, NULL, OPTION_BIG },
91 { "msmall", no_argument, NULL, OPTION_SMALL },
92 { "mmemparm", no_argument, NULL, OPTION_MEMPARM },
93 { "mregparm", no_argument, NULL, OPTION_REGPARM },
94 { "midle2", no_argument, NULL, OPTION_IDLE2 },
95 { "mlowpower", no_argument, NULL, OPTION_LOWPOWER },
96 { "menhanced", no_argument, NULL, OPTION_ENHANCED },
97 { "mrev", required_argument, NULL, OPTION_REV },
98 { NULL, no_argument, NULL, 0 }
101 size_t md_longopts_size = sizeof (md_longopts);
106 M_UNKNOWN, M_IMMED, M_DIRECT, M_REGISTER, M_INDIRECT,
107 M_IMMED_F, M_PARALLEL, M_HI
111 typedef struct tic4x_operand
113 tic4x_addr_mode_t mode; /* Addressing mode. */
114 expressionS expr; /* Expression. */
115 int disp; /* Displacement for indirect addressing. */
116 int aregno; /* Aux. register number. */
117 LITTLENUM_TYPE fwords[MAX_LITTLENUMS]; /* Float immed. number. */
121 typedef struct tic4x_insn
123 char name[TIC4X_NAME_MAX]; /* Mnemonic of instruction. */
124 unsigned int in_use; /* True if in_use. */
125 unsigned int parallel; /* True if parallel instruction. */
126 unsigned int nchars; /* This is always 4 for the C30. */
127 unsigned long opcode; /* Opcode number. */
128 expressionS exp; /* Expression required for relocation. */
129 int reloc; /* Relocation type required. */
130 int pcrel; /* True if relocation PC relative. */
131 char *pname; /* Name of instruction in parallel. */
132 unsigned int num_operands; /* Number of operands in total. */
133 tic4x_inst_t *inst; /* Pointer to first template. */
134 tic4x_operand_t operands[TIC4X_OPERANDS_MAX];
138 static tic4x_insn_t the_insn; /* Info about our instruction. */
139 static tic4x_insn_t *insn = &the_insn;
141 static void tic4x_asg (int);
142 static void tic4x_bss (int);
143 static void tic4x_globl (int);
144 static void tic4x_cons (int);
145 static void tic4x_stringer (int);
146 static void tic4x_eval (int);
147 static void tic4x_newblock (int);
148 static void tic4x_sect (int);
149 static void tic4x_set (int);
150 static void tic4x_usect (int);
151 static void tic4x_version (int);
157 {"align", s_align_bytes, 32},
158 {"ascii", tic4x_stringer, 1},
159 {"asciz", tic4x_stringer, 0},
160 {"asg", tic4x_asg, 0},
161 {"block", s_space, 4},
162 {"byte", tic4x_cons, 1},
163 {"bss", tic4x_bss, 0},
164 {"copy", s_include, 0},
165 {"def", tic4x_globl, 0},
166 {"equ", tic4x_set, 0},
167 {"eval", tic4x_eval, 0},
168 {"global", tic4x_globl, 0},
169 {"globl", tic4x_globl, 0},
170 {"hword", tic4x_cons, 2},
171 {"ieee", float_cons, 'i'},
172 {"int", tic4x_cons, 4}, /* .int allocates 4 bytes. */
173 {"ldouble", float_cons, 'e'},
174 {"newblock", tic4x_newblock, 0},
175 {"ref", s_ignore, 0}, /* All undefined treated as external. */
176 {"set", tic4x_set, 0},
177 {"sect", tic4x_sect, 1}, /* Define named section. */
178 {"space", s_space, 4},
179 {"string", tic4x_stringer, 0},
180 {"usect", tic4x_usect, 0}, /* Reserve space in uninit. named sect. */
181 {"version", tic4x_version, 0},
182 {"word", tic4x_cons, 4}, /* .word allocates 4 bytes. */
183 {"xdef", tic4x_globl, 0},
187 int md_short_jump_size = 4;
188 int md_long_jump_size = 4;
190 /* This array holds the chars that always start a comment. If the
191 pre-processor is disabled, these aren't very useful. */
192 #ifdef TIC4X_ALT_SYNTAX
193 const char comment_chars[] = ";!";
195 const char comment_chars[] = ";";
198 /* This array holds the chars that only start a comment at the beginning of
199 a line. If the line seems to have the form '# 123 filename'
200 .line and .file directives will appear in the pre-processed output.
201 Note that input_file.c hand checks for '#' at the beginning of the
202 first line of the input file. This is because the compiler outputs
203 #NO_APP at the beginning of its output.
204 Also note that comments like this one will always work. */
205 const char line_comment_chars[] = "#*";
207 /* We needed an unused char for line separation to work around the
208 lack of macros, using sed and such. */
209 const char line_separator_chars[] = "&";
211 /* Chars that can be used to separate mant from exp in floating point nums. */
212 const char EXP_CHARS[] = "eE";
214 /* Chars that mean this number is a floating point constant. */
217 const char FLT_CHARS[] = "fFilsS";
219 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
220 changed in read.c. Ideally it shouldn't have to know about it at
221 all, but nothing is ideal around here. */
223 /* Flonums returned here. */
224 extern FLONUM_TYPE generic_floating_point_number;
226 /* Precision in LittleNums. */
227 #define MAX_PRECISION (4) /* Its a bit overkill for us, but the code
229 #define S_PRECISION (1) /* Short float constants 16-bit. */
230 #define F_PRECISION (2) /* Float and double types 32-bit. */
231 #define E_PRECISION (4) /* Extended precision, 64-bit (real 40-bit). */
234 /* Turn generic_floating_point_number into a real short/float/double. */
236 tic4x_gen_to_words (FLONUM_TYPE flonum, LITTLENUM_TYPE *words, int precision)
238 int return_value = 0;
239 LITTLENUM_TYPE *p; /* Littlenum pointer. */
240 int mantissa_bits; /* Bits in mantissa field. */
241 int exponent_bits; /* Bits in exponent field. */
243 unsigned int sone; /* Scaled one. */
244 unsigned int sfract; /* Scaled fraction. */
245 unsigned int smant; /* Scaled mantissa. */
247 unsigned int mover; /* Mantissa overflow bits */
248 unsigned int rbit; /* Round bit. */
249 int shift; /* Shift count. */
251 /* NOTE: Svein Seldal <Svein@dev.seldal.com>
252 The code in this function is altered slightly to support floats
253 with 31-bits mantissas, thus the documentation below may be a
254 little bit inaccurate.
256 By Michael P. Hayes <m.hayes@elec.canterbury.ac.nz>
257 Here is how a generic floating point number is stored using
258 flonums (an extension of bignums) where p is a pointer to an
261 For example 2e-3 is stored with exp = -4 and
268 with low = &bits[2], high = &bits[5], and leader = &bits[5].
270 This number can be written as
271 0x0083126e978d4fde.00000000 * 65536**-4 or
272 0x0.0083126e978d4fde * 65536**0 or
273 0x0.83126e978d4fde * 2**-8 = 2e-3
275 Note that low points to the 65536**0 littlenum (bits[2]) and
276 leader points to the most significant non-zero littlenum
279 TMS320C3X floating point numbers are a bit of a strange beast.
280 The 32-bit flavour has the 8 MSBs representing the exponent in
281 twos complement format (-128 to +127). There is then a sign bit
282 followed by 23 bits of mantissa. The mantissa is expressed in
283 twos complement format with the binary point after the most
284 significant non sign bit. The bit after the binary point is
285 suppressed since it is the complement of the sign bit. The
286 effective mantissa is thus 24 bits. Zero is represented by an
289 The 16-bit flavour has the 4 MSBs representing the exponent in
290 twos complement format (-8 to +7). There is then a sign bit
291 followed by 11 bits of mantissa. The mantissa is expressed in
292 twos complement format with the binary point after the most
293 significant non sign bit. The bit after the binary point is
294 suppressed since it is the complement of the sign bit. The
295 effective mantissa is thus 12 bits. Zero is represented by an
296 exponent of -8. For example,
298 number norm mant m x e s i fraction f
299 +0.500 => 1.00000000000 -1 -1 0 1 .00000000000 (1 + 0) * 2^(-1)
300 +0.999 => 1.11111111111 -1 -1 0 1 .11111111111 (1 + 0.99) * 2^(-1)
301 +1.000 => 1.00000000000 0 0 0 1 .00000000000 (1 + 0) * 2^(0)
302 +1.500 => 1.10000000000 0 0 0 1 .10000000000 (1 + 0.5) * 2^(0)
303 +1.999 => 1.11111111111 0 0 0 1 .11111111111 (1 + 0.9) * 2^(0)
304 +2.000 => 1.00000000000 1 1 0 1 .00000000000 (1 + 0) * 2^(1)
305 +4.000 => 1.00000000000 2 2 0 1 .00000000000 (1 + 0) * 2^(2)
306 -0.500 => 1.00000000000 -1 -1 1 0 .10000000000 (-2 + 0) * 2^(-2)
307 -1.000 => 1.00000000000 0 -1 1 0 .00000000000 (-2 + 0) * 2^(-1)
308 -1.500 => 1.10000000000 0 0 1 0 .10000000000 (-2 + 0.5) * 2^(0)
309 -1.999 => 1.11111111111 0 0 1 0 .00000000001 (-2 + 0.11) * 2^(0)
310 -2.000 => 1.00000000000 1 1 1 0 .00000000000 (-2 + 0) * 2^(0)
311 -4.000 => 1.00000000000 2 1 1 0 .00000000000 (-2 + 0) * 2^(1)
313 where e is the exponent, s is the sign bit, i is the implied bit,
314 and f is the fraction stored in the mantissa field.
316 num = (1 + f) * 2^x = m * 2^e if s = 0
317 num = (-2 + f) * 2^x = -m * 2^e if s = 1
318 where 0 <= f < 1.0 and 1.0 <= m < 2.0
320 The fraction (f) and exponent (e) fields for the TMS320C3X format
321 can be derived from the normalised mantissa (m) and exponent (x) using:
323 f = m - 1, e = x if s = 0
324 f = 2 - m, e = x if s = 1 and m != 1.0
325 f = 0, e = x - 1 if s = 1 and m = 1.0
326 f = 0, e = -8 if m = 0
329 OK, the other issue we have to consider is rounding since the
330 mantissa has a much higher potential precision than what we can
331 represent. To do this we add half the smallest storable fraction.
332 We then have to renormalise the number to allow for overflow.
334 To convert a generic flonum into a TMS320C3X floating point
335 number, here's what we try to do....
337 The first thing is to generate a normalised mantissa (m) where
338 1.0 <= m < 2 and to convert the exponent from base 16 to base 2.
339 We desire the binary point to be placed after the most significant
340 non zero bit. This process is done in two steps: firstly, the
341 littlenum with the most significant non zero bit is located (this
342 is done for us since leader points to this littlenum) and the
343 binary point (which is currently after the LSB of the littlenum
344 pointed to by low) is moved to before the MSB of the littlenum
345 pointed to by leader. This requires the exponent to be adjusted
346 by leader - low + 1. In the earlier example, the new exponent is
347 thus -4 + (5 - 2 + 1) = 0 (base 65536). We now need to convert
348 the exponent to base 2 by multiplying the exponent by 16 (log2
349 65536). The exponent base 2 is thus also zero.
351 The second step is to hunt for the most significant non zero bit
352 in the leader littlenum. We do this by left shifting a copy of
353 the leader littlenum until bit 16 is set (0x10000) and counting
354 the number of shifts, S, required. The number of shifts then has to
355 be added to correct the exponent (base 2). For our example, this
356 will require 9 shifts and thus our normalised exponent (base 2) is
357 0 + 9 = 9. Note that the worst case scenario is when the leader
358 littlenum is 1, thus requiring 16 shifts.
360 We now have to left shift the other littlenums by the same amount,
361 propagating the shifted bits into the more significant littlenums.
362 To save a lot of unnecessary shifting we only have to consider
363 two or three littlenums, since the greatest number of mantissa
364 bits required is 24 + 1 rounding bit. While two littlenums
365 provide 32 bits of precision, the most significant littlenum
366 may only contain a single significant bit and thus an extra
367 littlenum is required.
369 Denoting the number of bits in the fraction field as F, we require
370 G = F + 2 bits (one extra bit is for rounding, the other gets
371 suppressed). Say we required S shifts to find the most
372 significant bit in the leader littlenum, the number of left shifts
373 required to move this bit into bit position G - 1 is L = G + S - 17.
374 Note that this shift count may be negative for the short floating
375 point flavour (where F = 11 and thus G = 13 and potentially S < 3).
376 If L > 0 we have to shunt the next littlenum into position. Bit
377 15 (the MSB) of the next littlenum needs to get moved into position
378 L - 1 (If L > 15 we need all the bits of this littlenum and
379 some more from the next one.). We subtract 16 from L and use this
380 as the left shift count; the resultant value we or with the
381 previous result. If L > 0, we repeat this operation. */
383 if (precision != S_PRECISION)
385 if (precision == E_PRECISION)
386 words[2] = words[3] = 0x0000;
388 /* 0.0e0 or NaN seen. */
389 if (flonum.low > flonum.leader /* = 0.0e0 */
390 || flonum.sign == 0) /* = NaN */
393 as_bad (_("Nan, using zero."));
398 if (flonum.sign == 'P')
400 /* +INF: Replace with maximum float. */
401 if (precision == S_PRECISION)
408 if (precision == E_PRECISION)
415 else if (flonum.sign == 'N')
417 /* -INF: Replace with maximum float. */
418 if (precision == S_PRECISION)
422 if (precision == E_PRECISION)
427 exponent = (flonum.exponent + flonum.leader - flonum.low + 1) * 16;
429 if (!(tmp = *flonum.leader))
430 abort (); /* Hmmm. */
431 shift = 0; /* Find position of first sig. bit. */
434 exponent -= (16 - shift); /* Adjust exponent. */
436 if (precision == S_PRECISION) /* Allow 1 rounding bit. */
441 else if(precision == F_PRECISION)
446 else /* E_PRECISION */
452 shift = mantissa_bits - shift;
457 /* Store the mantissa data into smant and the roundbit into rbit */
458 for (p = flonum.leader; p >= flonum.low && shift > -16; p--)
460 tmp = shift >= 0 ? *p << shift : *p >> -shift;
461 rbit = shift < 0 ? ((*p >> (-shift-1)) & 0x1) : 0;
466 /* OK, we've got our scaled mantissa so let's round it up */
469 /* If the mantissa is going to overflow when added, lets store
470 the extra bit in mover. -- A special case exists when
471 mantissa_bits is 31 (E_PRECISION). Then the first test cannot
472 be trusted, as result is host-dependent, thus the second
474 if( smant == ((unsigned)(1<<(mantissa_bits+1))-1)
475 || smant == (unsigned)-1 ) /* This is to catch E_PRECISION cases */
480 /* Get the scaled one value */
481 sone = (1 << (mantissa_bits));
483 /* The number may be unnormalised so renormalise it... */
487 smant |= sone; /* Insert the bit from mover into smant */
491 /* The binary point is now between bit positions 11 and 10 or 23 and 22,
492 i.e., between mantissa_bits - 1 and mantissa_bits - 2 and the
493 bit at mantissa_bits - 1 should be set. */
495 abort (); /* Ooops. */
497 if (flonum.sign == '+')
498 sfract = smant - sone; /* smant - 1.0. */
501 /* This seems to work. */
509 sfract = -smant & (sone-1); /* 2.0 - smant. */
511 sfract |= sone; /* Insert sign bit. */
514 if (abs (exponent) >= (1 << (exponent_bits - 1)))
515 as_bad (_("Cannot represent exponent in %d bits"), exponent_bits);
517 /* Force exponent to fit in desired field width. */
518 exponent &= (1 << (exponent_bits)) - 1;
520 if (precision == E_PRECISION)
522 /* Map the float part first (100% equal format as F_PRECISION) */
523 words[0] = exponent << (mantissa_bits+1-24);
524 words[0] |= sfract >> 24;
525 words[1] = sfract >> 8;
527 /* Map the mantissa in the next */
528 words[2] = sfract >> 16;
529 words[3] = sfract & 0xffff;
533 /* Insert the exponent data into the word */
534 sfract |= exponent << (mantissa_bits+1);
536 if (precision == S_PRECISION)
540 words[0] = sfract >> 16;
541 words[1] = sfract & 0xffff;
548 /* Returns pointer past text consumed. */
550 tic4x_atof (char *str, char what_kind, LITTLENUM_TYPE *words)
552 /* Extra bits for zeroed low-order bits. The 1st MAX_PRECISION are
553 zeroed, the last contain flonum bits. */
554 static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
556 /* Number of 16-bit words in the format. */
558 FLONUM_TYPE save_gen_flonum;
560 /* We have to save the generic_floating_point_number because it
561 contains storage allocation about the array of LITTLENUMs where
562 the value is actually stored. We will allocate our own array of
563 littlenums below, but have to restore the global one on exit. */
564 save_gen_flonum = generic_floating_point_number;
567 generic_floating_point_number.low = bits + MAX_PRECISION;
568 generic_floating_point_number.high = NULL;
569 generic_floating_point_number.leader = NULL;
570 generic_floating_point_number.exponent = 0;
571 generic_floating_point_number.sign = '\0';
573 /* Use more LittleNums than seems necessary: the highest flonum may
574 have 15 leading 0 bits, so could be useless. */
576 memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
582 precision = S_PRECISION;
589 precision = F_PRECISION;
594 precision = E_PRECISION;
598 as_bad (_("Invalid floating point number"));
602 generic_floating_point_number.high
603 = generic_floating_point_number.low + precision - 1 + GUARD;
605 if (atof_generic (&return_value, ".", EXP_CHARS,
606 &generic_floating_point_number))
608 as_bad (_("Invalid floating point number"));
612 tic4x_gen_to_words (generic_floating_point_number,
615 /* Restore the generic_floating_point_number's storage alloc (and
617 generic_floating_point_number = save_gen_flonum;
623 tic4x_insert_reg (char *regname, int regnum)
628 symbol_table_insert (symbol_new (regname, reg_section, (valueT) regnum,
629 &zero_address_frag));
630 for (i = 0; regname[i]; i++)
631 buf[i] = ISLOWER (regname[i]) ? TOUPPER (regname[i]) : regname[i];
634 symbol_table_insert (symbol_new (buf, reg_section, (valueT) regnum,
635 &zero_address_frag));
639 tic4x_insert_sym (char *symname, int value)
643 symbolP = symbol_new (symname, absolute_section,
644 (valueT) value, &zero_address_frag);
645 SF_SET_LOCAL (symbolP);
646 symbol_table_insert (symbolP);
650 tic4x_expression (char *str, expressionS *exp)
655 t = input_line_pointer; /* Save line pointer. */
656 input_line_pointer = str;
658 s = input_line_pointer;
659 input_line_pointer = t; /* Restore line pointer. */
660 return s; /* Return pointer to where parsing stopped. */
664 tic4x_expression_abs (char *str, offsetT *value)
669 t = input_line_pointer; /* Save line pointer. */
670 input_line_pointer = str;
671 *value = get_absolute_expression ();
672 s = input_line_pointer;
673 input_line_pointer = t; /* Restore line pointer. */
678 tic4x_emit_char (char c, int b)
682 exp.X_op = O_constant;
683 exp.X_add_number = c;
688 tic4x_seg_alloc (char *name ATTRIBUTE_UNUSED,
689 segT seg ATTRIBUTE_UNUSED,
693 /* Note that the size is in words
694 so we multiply it by 4 to get the number of bytes to allocate. */
696 /* If we have symbol: .usect ".fred", size etc.,
697 the symbol needs to point to the first location reserved
704 p = frag_var (rs_fill, 1, 1, (relax_substateT) 0,
706 size * OCTETS_PER_BYTE, (char *) 0);
711 /* .asg ["]character-string["], symbol */
713 tic4x_asg (int x ATTRIBUTE_UNUSED)
721 str = input_line_pointer;
723 /* Skip string expression. */
724 while (*input_line_pointer != ',' && *input_line_pointer)
725 input_line_pointer++;
726 if (*input_line_pointer != ',')
728 as_bad (_("Comma expected\n"));
731 *input_line_pointer++ = '\0';
732 name = input_line_pointer;
733 c = get_symbol_end (); /* Get terminator. */
734 tmp = xmalloc (strlen (str) + 1);
737 tmp = xmalloc (strlen (name) + 1);
740 if (hash_find (tic4x_asg_hash, name))
741 hash_replace (tic4x_asg_hash, name, (void *) str);
743 hash_insert (tic4x_asg_hash, name, (void *) str);
744 *input_line_pointer = c;
745 demand_empty_rest_of_line ();
748 /* .bss symbol, size */
750 tic4x_bss (int x ATTRIBUTE_UNUSED)
757 subsegT current_subseg;
760 current_seg = now_seg; /* Save current seg. */
761 current_subseg = now_subseg; /* Save current subseg. */
764 name = input_line_pointer;
765 c = get_symbol_end (); /* Get terminator. */
768 as_bad (_(".bss size argument missing\n"));
773 tic4x_expression_abs (++input_line_pointer, &size);
776 as_bad (_(".bss size %ld < 0!"), (long) size);
779 subseg_set (bss_section, 0);
780 symbolP = symbol_find_or_make (name);
782 if (S_GET_SEGMENT (symbolP) == bss_section)
783 symbol_get_frag (symbolP)->fr_symbol = 0;
785 symbol_set_frag (symbolP, frag_now);
787 p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
788 size * OCTETS_PER_BYTE, (char *) 0);
789 *p = 0; /* Fill char. */
791 S_SET_SEGMENT (symbolP, bss_section);
793 /* The symbol may already have been created with a preceding
794 ".globl" directive -- be careful not to step on storage class
795 in that case. Otherwise, set it to static. */
796 if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
797 S_SET_STORAGE_CLASS (symbolP, C_STAT);
799 subseg_set (current_seg, current_subseg); /* Restore current seg. */
800 demand_empty_rest_of_line ();
804 tic4x_globl (int ignore ATTRIBUTE_UNUSED)
812 name = input_line_pointer;
813 c = get_symbol_end ();
814 symbolP = symbol_find_or_make (name);
815 *input_line_pointer = c;
817 S_SET_STORAGE_CLASS (symbolP, C_EXT);
818 S_SET_EXTERNAL (symbolP);
821 input_line_pointer++;
823 if (*input_line_pointer == '\n')
829 demand_empty_rest_of_line ();
832 /* Handle .byte, .word. .int, .long */
834 tic4x_cons (int bytes)
836 register unsigned int c;
840 if (*input_line_pointer == '"')
842 input_line_pointer++;
843 while (is_a_char (c = next_char_of_string ()))
844 tic4x_emit_char (c, 4);
845 know (input_line_pointer[-1] == '\"');
851 input_line_pointer = tic4x_expression (input_line_pointer, &exp);
852 if (exp.X_op == O_constant)
857 exp.X_add_number &= 255;
860 exp.X_add_number &= 65535;
864 /* Perhaps we should disallow .byte and .hword with
865 a non constant expression that will require relocation. */
869 while (*input_line_pointer++ == ',');
871 input_line_pointer--; /* Put terminator back into stream. */
872 demand_empty_rest_of_line ();
875 /* Handle .ascii, .asciz, .string */
877 tic4x_stringer (int append_zero)
880 register unsigned int c;
886 if (*input_line_pointer == '"')
888 input_line_pointer++;
889 while (is_a_char (c = next_char_of_string ()))
891 tic4x_emit_char (c, 1);
897 tic4x_emit_char (c, 1);
901 know (input_line_pointer[-1] == '\"');
907 input_line_pointer = tic4x_expression (input_line_pointer, &exp);
908 if (exp.X_op != O_constant)
910 as_bad (_("Non-constant symbols not allowed\n"));
913 exp.X_add_number &= 255; /* Limit numeber to 8-bit */
918 while (*input_line_pointer++ == ',');
920 /* Fill out the rest of the expression with 0's to fill up a full word */
922 tic4x_emit_char (0, 4-(bytes&0x3));
924 input_line_pointer--; /* Put terminator back into stream. */
925 demand_empty_rest_of_line ();
928 /* .eval expression, symbol */
930 tic4x_eval (int x ATTRIBUTE_UNUSED)
938 tic4x_expression_abs (input_line_pointer, &value);
939 if (*input_line_pointer++ != ',')
941 as_bad (_("Symbol missing\n"));
944 name = input_line_pointer;
945 c = get_symbol_end (); /* Get terminator. */
946 tic4x_insert_sym (name, value);
947 *input_line_pointer++ = c;
948 demand_empty_rest_of_line ();
951 /* Reset local labels. */
953 tic4x_newblock (int x ATTRIBUTE_UNUSED)
955 dollar_label_clear ();
958 /* .sect "section-name" [, value] */
959 /* .sect ["]section-name[:subsection-name]["] [, value] */
961 tic4x_sect (int x ATTRIBUTE_UNUSED)
970 if (*input_line_pointer == '"')
971 input_line_pointer++;
972 section_name = input_line_pointer;
973 c = get_symbol_end (); /* Get terminator. */
974 input_line_pointer++; /* Skip null symbol terminator. */
975 name = xmalloc (input_line_pointer - section_name + 1);
976 strcpy (name, section_name);
978 /* TI C from version 5.0 allows a section name to contain a
979 subsection name as well. The subsection name is separated by a
980 ':' from the section name. Currently we scan the subsection
982 Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>. */
985 c = get_symbol_end (); /* Get terminator. */
986 input_line_pointer++; /* Skip null symbol terminator. */
987 as_warn (_(".sect: subsection name ignored"));
990 /* We might still have a '"' to discard, but the character after a
991 symbol name will be overwritten with a \0 by get_symbol_end()
996 tic4x_expression_abs (input_line_pointer, &num);
997 else if (*input_line_pointer == ',')
1000 tic4x_expression_abs (++input_line_pointer, &num);
1005 seg = subseg_new (name, num);
1006 if (line_label != NULL)
1008 S_SET_SEGMENT (line_label, seg);
1009 symbol_set_frag (line_label, frag_now);
1012 if (bfd_get_section_flags (stdoutput, seg) == SEC_NO_FLAGS)
1014 if (!bfd_set_section_flags (stdoutput, seg, SEC_DATA))
1015 as_warn (_("Error setting flags for \"%s\": %s"), name,
1016 bfd_errmsg (bfd_get_error ()));
1019 /* If the last character overwritten by get_symbol_end() was an
1020 end-of-line, we must restore it or the end of the line will not be
1021 recognised and scanning extends into the next line, stopping with
1022 an error (blame Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>
1023 if this is not true). */
1024 if (is_end_of_line[(unsigned char) c])
1025 *(--input_line_pointer) = c;
1027 demand_empty_rest_of_line ();
1030 /* symbol[:] .set value or .set symbol, value */
1032 tic4x_set (int x ATTRIBUTE_UNUSED)
1037 if ((symbolP = line_label) == NULL)
1042 name = input_line_pointer;
1043 c = get_symbol_end (); /* Get terminator. */
1046 as_bad (_(".set syntax invalid\n"));
1047 ignore_rest_of_line ();
1050 ++input_line_pointer;
1051 symbolP = symbol_find_or_make (name);
1054 symbol_table_insert (symbolP);
1056 pseudo_set (symbolP);
1057 demand_empty_rest_of_line ();
1060 /* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
1062 tic4x_usect (int x ATTRIBUTE_UNUSED)
1068 offsetT size, alignment_flag;
1070 subsegT current_subseg;
1072 current_seg = now_seg; /* save current seg. */
1073 current_subseg = now_subseg; /* save current subseg. */
1076 if (*input_line_pointer == '"')
1077 input_line_pointer++;
1078 section_name = input_line_pointer;
1079 c = get_symbol_end (); /* Get terminator. */
1080 input_line_pointer++; /* Skip null symbol terminator. */
1081 name = xmalloc (input_line_pointer - section_name + 1);
1082 strcpy (name, section_name);
1085 input_line_pointer =
1086 tic4x_expression_abs (input_line_pointer, &size);
1087 else if (*input_line_pointer == ',')
1089 input_line_pointer =
1090 tic4x_expression_abs (++input_line_pointer, &size);
1095 /* Read a possibly present third argument (alignment flag) [VK]. */
1096 if (*input_line_pointer == ',')
1098 input_line_pointer =
1099 tic4x_expression_abs (++input_line_pointer, &alignment_flag);
1104 as_warn (_(".usect: non-zero alignment flag ignored"));
1106 seg = subseg_new (name, 0);
1107 if (line_label != NULL)
1109 S_SET_SEGMENT (line_label, seg);
1110 symbol_set_frag (line_label, frag_now);
1111 S_SET_VALUE (line_label, frag_now_fix ());
1113 seg_info (seg)->bss = 1; /* Uninitialised data. */
1114 if (!bfd_set_section_flags (stdoutput, seg, SEC_ALLOC))
1115 as_warn (_("Error setting flags for \"%s\": %s"), name,
1116 bfd_errmsg (bfd_get_error ()));
1117 tic4x_seg_alloc (name, seg, size, line_label);
1119 if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
1120 S_SET_STORAGE_CLASS (line_label, C_STAT);
1122 subseg_set (current_seg, current_subseg); /* Restore current seg. */
1123 demand_empty_rest_of_line ();
1126 /* .version cpu-version. */
1128 tic4x_version (int x ATTRIBUTE_UNUSED)
1132 input_line_pointer =
1133 tic4x_expression_abs (input_line_pointer, &temp);
1134 if (!IS_CPU_TIC3X (temp) && !IS_CPU_TIC4X (temp))
1135 as_bad (_("This assembler does not support processor generation %ld"),
1138 if (tic4x_cpu && temp != (offsetT) tic4x_cpu)
1139 as_warn (_("Changing processor generation on fly not supported..."));
1141 demand_empty_rest_of_line ();
1145 tic4x_init_regtable (void)
1149 for (i = 0; i < tic3x_num_registers; i++)
1150 tic4x_insert_reg (tic3x_registers[i].name,
1151 tic3x_registers[i].regno);
1153 if (IS_CPU_TIC4X (tic4x_cpu))
1155 /* Add additional Tic4x registers, overriding some C3x ones. */
1156 for (i = 0; i < tic4x_num_registers; i++)
1157 tic4x_insert_reg (tic4x_registers[i].name,
1158 tic4x_registers[i].regno);
1163 tic4x_init_symbols (void)
1165 /* The TI tools accept case insensitive versions of these symbols,
1170 .TMS320xx 30,31,32,40,or 44 set according to -v flag
1171 .C3X or .C3x 1 or 0 1 if -v30,-v31,or -v32
1172 .C30 1 or 0 1 if -v30
1173 .C31 1 or 0 1 if -v31
1174 .C32 1 or 0 1 if -v32
1175 .C4X or .C4x 1 or 0 1 if -v40, or -v44
1176 .C40 1 or 0 1 if -v40
1177 .C44 1 or 0 1 if -v44
1179 .REGPARM 1 or 0 1 if -mr option used
1180 .BIGMODEL 1 or 0 1 if -mb option used
1182 These symbols are currently supported but will be removed in a
1184 .TMS320C30 1 or 0 1 if -v30,-v31,or -v32
1185 .TMS320C31 1 or 0 1 if -v31
1186 .TMS320C32 1 or 0 1 if -v32
1187 .TMS320C40 1 or 0 1 if -v40, or -v44
1188 .TMS320C44 1 or 0 1 if -v44
1190 Source: TI: TMS320C3x/C4x Assembly Language Tools User's Guide,
1191 1997, SPRU035C, p. 3-17/3-18. */
1192 tic4x_insert_sym (".REGPARM", tic4x_reg_args);
1193 tic4x_insert_sym (".MEMPARM", !tic4x_reg_args);
1194 tic4x_insert_sym (".BIGMODEL", tic4x_big_model);
1195 tic4x_insert_sym (".C30INTERRUPT", 0);
1196 tic4x_insert_sym (".TMS320xx", tic4x_cpu == 0 ? 40 : tic4x_cpu);
1197 tic4x_insert_sym (".C3X", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1198 tic4x_insert_sym (".C3x", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1199 tic4x_insert_sym (".C4X", tic4x_cpu == 0 || tic4x_cpu == 40 || tic4x_cpu == 44);
1200 tic4x_insert_sym (".C4x", tic4x_cpu == 0 || tic4x_cpu == 40 || tic4x_cpu == 44);
1201 /* Do we need to have the following symbols also in lower case? */
1202 tic4x_insert_sym (".TMS320C30", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1203 tic4x_insert_sym (".tms320C30", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1204 tic4x_insert_sym (".TMS320C31", tic4x_cpu == 31);
1205 tic4x_insert_sym (".tms320C31", tic4x_cpu == 31);
1206 tic4x_insert_sym (".TMS320C32", tic4x_cpu == 32);
1207 tic4x_insert_sym (".tms320C32", tic4x_cpu == 32);
1208 tic4x_insert_sym (".TMS320C33", tic4x_cpu == 33);
1209 tic4x_insert_sym (".tms320C33", tic4x_cpu == 33);
1210 tic4x_insert_sym (".TMS320C40", tic4x_cpu == 40 || tic4x_cpu == 44 || tic4x_cpu == 0);
1211 tic4x_insert_sym (".tms320C40", tic4x_cpu == 40 || tic4x_cpu == 44 || tic4x_cpu == 0);
1212 tic4x_insert_sym (".TMS320C44", tic4x_cpu == 44);
1213 tic4x_insert_sym (".tms320C44", tic4x_cpu == 44);
1214 tic4x_insert_sym (".TMX320C40", 0); /* C40 first pass silicon ? */
1215 tic4x_insert_sym (".tmx320C40", 0);
1218 /* Insert a new instruction template into hash table. */
1220 tic4x_inst_insert (const tic4x_inst_t *inst)
1222 static char prev_name[16];
1223 const char *retval = NULL;
1225 /* Only insert the first name if have several similar entries. */
1226 if (!strcmp (inst->name, prev_name) || inst->name[0] == '\0')
1229 retval = hash_insert (tic4x_op_hash, inst->name, (void *) inst);
1231 fprintf (stderr, "internal error: can't hash `%s': %s\n",
1232 inst->name, retval);
1234 strcpy (prev_name, inst->name);
1235 return retval == NULL;
1238 /* Make a new instruction template. */
1239 static tic4x_inst_t *
1240 tic4x_inst_make (char *name, unsigned long opcode, char *args)
1242 static tic4x_inst_t *insts = NULL;
1243 static char *names = NULL;
1244 static int iindex = 0;
1248 /* Allocate memory to store name strings. */
1249 names = (char *) xmalloc (sizeof (char) * 8192);
1250 /* Allocate memory for additional insts. */
1251 insts = (tic4x_inst_t *)
1252 xmalloc (sizeof (tic4x_inst_t) * 1024);
1254 insts[iindex].name = names;
1255 insts[iindex].opcode = opcode;
1256 insts[iindex].opmask = 0xffffffff;
1257 insts[iindex].args = args;
1265 return &insts[iindex - 1];
1268 /* Add instruction template, creating dynamic templates as required. */
1270 tic4x_inst_add (const tic4x_inst_t *insts)
1272 char *s = insts->name;
1280 /* We do not care about INSNs that is not a part of our
1282 if ((insts->oplevel & tic4x_oplevel) == 0)
1291 /* Dynamically create all the conditional insts. */
1292 for (i = 0; i < tic4x_num_conds; i++)
1296 char *c = tic4x_conds[i].name;
1306 /* If instruction found then have already processed it. */
1307 if (hash_find (tic4x_op_hash, name))
1312 inst = tic4x_inst_make (name, insts[k].opcode +
1313 (tic4x_conds[i].cond <<
1314 (*s == 'B' ? 16 : 23)),
1316 if (k == 0) /* Save strcmp() with following func. */
1317 ok &= tic4x_inst_insert (inst);
1320 while (!strcmp (insts->name,
1327 return tic4x_inst_insert (insts);
1337 /* This function is called once, at assembler startup time. It should
1338 set up all the tables, etc., that the MD part of the assembler will
1346 /* Setup the proper opcode level according to the
1347 commandline parameters */
1348 tic4x_oplevel = OP_C3X;
1350 if ( IS_CPU_TIC4X(tic4x_cpu) )
1351 tic4x_oplevel |= OP_C4X;
1353 if ( ( tic4x_cpu == 31 && tic4x_revision >= 6)
1354 || (tic4x_cpu == 32 && tic4x_revision >= 2)
1355 || (tic4x_cpu == 33)
1357 tic4x_oplevel |= OP_ENH;
1359 if ( ( tic4x_cpu == 30 && tic4x_revision >= 7)
1360 || (tic4x_cpu == 31 && tic4x_revision >= 5)
1361 || (tic4x_cpu == 32)
1363 tic4x_oplevel |= OP_LPWR;
1365 if ( ( tic4x_cpu == 30 && tic4x_revision >= 7)
1366 || (tic4x_cpu == 31 && tic4x_revision >= 5)
1367 || (tic4x_cpu == 32)
1368 || (tic4x_cpu == 33)
1369 || (tic4x_cpu == 40 && tic4x_revision >= 5)
1370 || (tic4x_cpu == 44)
1372 tic4x_oplevel |= OP_IDLE2;
1374 /* Create hash table for mnemonics. */
1375 tic4x_op_hash = hash_new ();
1377 /* Create hash table for asg pseudo. */
1378 tic4x_asg_hash = hash_new ();
1380 /* Add mnemonics to hash table, expanding conditional mnemonics on fly. */
1381 for (i = 0; i < tic4x_num_insts; i++)
1382 ok &= tic4x_inst_add (tic4x_insts + i);
1384 /* Create dummy inst to avoid errors accessing end of table. */
1385 tic4x_inst_make ("", 0, "");
1388 as_fatal ("Broken assembler. No assembly attempted.");
1390 /* Add registers to symbol table. */
1391 tic4x_init_regtable ();
1393 /* Add predefined symbols to symbol table. */
1394 tic4x_init_symbols ();
1400 bfd_set_arch_mach (stdoutput, bfd_arch_tic4x,
1401 IS_CPU_TIC4X (tic4x_cpu) ? bfd_mach_tic4x : bfd_mach_tic3x);
1405 tic4x_indirect_parse (tic4x_operand_t *operand,
1406 const tic4x_indirect_t *indirect)
1408 char *n = indirect->name;
1409 char *s = input_line_pointer;
1419 case 'a': /* Need to match aux register. */
1421 #ifdef TIC4X_ALT_SYNTAX
1425 while (ISALNUM (*s))
1428 if (!(symbolP = symbol_find (name)))
1431 if (S_GET_SEGMENT (symbolP) != reg_section)
1434 operand->aregno = S_GET_VALUE (symbolP);
1435 if (operand->aregno >= REG_AR0 && operand->aregno <= REG_AR7)
1438 as_bad (_("Auxiliary register AR0--AR7 required for indirect"));
1441 case 'd': /* Need to match constant for disp. */
1442 #ifdef TIC4X_ALT_SYNTAX
1443 if (*s == '%') /* expr() will die if we don't skip this. */
1446 s = tic4x_expression (s, &operand->expr);
1447 if (operand->expr.X_op != O_constant)
1449 operand->disp = operand->expr.X_add_number;
1450 if (operand->disp < 0 || operand->disp > 255)
1452 as_bad (_("Bad displacement %d (require 0--255)\n"),
1458 case 'y': /* Need to match IR0. */
1459 case 'z': /* Need to match IR1. */
1460 #ifdef TIC4X_ALT_SYNTAX
1464 s = tic4x_expression (s, &operand->expr);
1465 if (operand->expr.X_op != O_register)
1467 if (operand->expr.X_add_number != REG_IR0
1468 && operand->expr.X_add_number != REG_IR1)
1470 as_bad (_("Index register IR0,IR1 required for displacement"));
1474 if (*n == 'y' && operand->expr.X_add_number == REG_IR0)
1476 if (*n == 'z' && operand->expr.X_add_number == REG_IR1)
1481 if (*s != '(') /* No displacement, assume to be 1. */
1492 if (TOLOWER (*s) != *n)
1497 if (*s != ' ' && *s != ',' && *s != '\0')
1499 input_line_pointer = s;
1504 tic4x_operand_parse (char *s, tic4x_operand_t *operand)
1509 expressionS *exp = &operand->expr;
1510 char *save = input_line_pointer;
1513 struct hash_entry *entry = NULL;
1515 input_line_pointer = s;
1518 str = input_line_pointer;
1519 c = get_symbol_end (); /* Get terminator. */
1520 new_pointer = input_line_pointer;
1521 if (strlen (str) && (entry = hash_find (tic4x_asg_hash, str)) != NULL)
1523 *input_line_pointer = c;
1524 input_line_pointer = (char *) entry;
1528 *input_line_pointer = c;
1529 input_line_pointer = str;
1532 operand->mode = M_UNKNOWN;
1533 switch (*input_line_pointer)
1535 #ifdef TIC4X_ALT_SYNTAX
1537 input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1538 if (exp->X_op != O_register)
1539 as_bad (_("Expecting a register name"));
1540 operand->mode = M_REGISTER;
1544 /* Denotes high 16 bits. */
1545 input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1546 if (exp->X_op == O_constant)
1547 operand->mode = M_IMMED;
1548 else if (exp->X_op == O_big)
1550 if (exp->X_add_number)
1551 as_bad (_("Number too large")); /* bignum required */
1554 tic4x_gen_to_words (generic_floating_point_number,
1555 operand->fwords, S_PRECISION);
1556 operand->mode = M_IMMED_F;
1559 /* Allow ori ^foo, ar0 to be equivalent to ldi .hi.foo, ar0 */
1560 /* WARNING : The TI C40 assembler cannot do this. */
1561 else if (exp->X_op == O_symbol)
1563 operand->mode = M_HI;
1568 input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1569 if (exp->X_op == O_constant)
1570 operand->mode = M_IMMED;
1571 else if (exp->X_op == O_big)
1573 if (exp->X_add_number > 0)
1574 as_bad (_("Number too large")); /* bignum required. */
1577 tic4x_gen_to_words (generic_floating_point_number,
1578 operand->fwords, S_PRECISION);
1579 operand->mode = M_IMMED_F;
1582 /* Allow ori foo, ar0 to be equivalent to ldi .lo.foo, ar0 */
1583 /* WARNING : The TI C40 assembler cannot do this. */
1584 else if (exp->X_op == O_symbol)
1586 operand->mode = M_IMMED;
1591 as_bad (_("Expecting a constant value"));
1596 input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1597 if (exp->X_op != O_constant && exp->X_op != O_symbol)
1598 as_bad (_("Bad direct addressing construct %s"), s);
1599 if (exp->X_op == O_constant)
1601 if (exp->X_add_number < 0)
1602 as_bad (_("Direct value of %ld is not suitable"),
1603 (long) exp->X_add_number);
1605 operand->mode = M_DIRECT;
1610 for (i = 0; i < tic4x_num_indirects; i++)
1611 if ((ret = tic4x_indirect_parse (operand, &tic4x_indirects[i])))
1615 if (i < tic4x_num_indirects)
1617 operand->mode = M_INDIRECT;
1618 /* Indirect addressing mode number. */
1619 operand->expr.X_add_number = tic4x_indirects[i].modn;
1620 /* Convert *+ARn(0) to *ARn etc. Maybe we should
1621 squeal about silly ones? */
1622 if (operand->expr.X_add_number < 0x08 && !operand->disp)
1623 operand->expr.X_add_number = 0x18;
1626 as_bad (_("Unknown indirect addressing mode"));
1630 operand->mode = M_IMMED; /* Assume immediate. */
1631 str = input_line_pointer;
1632 input_line_pointer = tic4x_expression (input_line_pointer, exp);
1633 if (exp->X_op == O_register)
1635 know (exp->X_add_symbol == 0);
1636 know (exp->X_op_symbol == 0);
1637 operand->mode = M_REGISTER;
1640 else if (exp->X_op == O_big)
1642 if (exp->X_add_number > 0)
1643 as_bad (_("Number too large")); /* bignum required. */
1646 tic4x_gen_to_words (generic_floating_point_number,
1647 operand->fwords, S_PRECISION);
1648 operand->mode = M_IMMED_F;
1652 #ifdef TIC4X_ALT_SYNTAX
1653 /* Allow ldi foo, ar0 to be equivalent to ldi @foo, ar0. */
1654 else if (exp->X_op == O_symbol)
1656 operand->mode = M_DIRECT;
1662 new_pointer = input_line_pointer;
1663 input_line_pointer = save;
1668 tic4x_operands_match (tic4x_inst_t *inst, tic4x_insn_t *tinsn, int check)
1670 const char *args = inst->args;
1671 unsigned long opcode = inst->opcode;
1672 int num_operands = tinsn->num_operands;
1673 tic4x_operand_t *operand = tinsn->operands;
1674 expressionS *exp = &operand->expr;
1678 /* Build the opcode, checking as we go to make sure that the
1681 If an operand matches, we modify insn or opcode appropriately,
1682 and do a "continue". If an operand fails to match, we "break". */
1684 tinsn->nchars = 4; /* Instructions always 4 bytes. */
1685 tinsn->reloc = NO_RELOC;
1690 tinsn->opcode = opcode;
1691 return num_operands == 0;
1699 case '\0': /* End of args. */
1700 if (num_operands == 1)
1702 tinsn->opcode = opcode;
1705 break; /* Too many operands. */
1707 case '#': /* This is only used for ldp. */
1708 if (operand->mode != M_DIRECT && operand->mode != M_IMMED)
1710 /* While this looks like a direct addressing mode, we actually
1711 use an immediate mode form of ldiu or ldpk instruction. */
1712 if (exp->X_op == O_constant)
1714 if( ( IS_CPU_TIC4X (tic4x_cpu) && exp->X_add_number <= 65535 )
1715 || ( IS_CPU_TIC3X (tic4x_cpu) && exp->X_add_number <= 255 ) )
1717 INSERTS (opcode, exp->X_add_number, 15, 0);
1723 as_bad (_("Immediate value of %ld is too large for ldf"),
1724 (long) exp->X_add_number);
1729 else if (exp->X_op == O_symbol)
1731 tinsn->reloc = BFD_RELOC_HI16;
1735 break; /* Not direct (dp) addressing. */
1737 case '@': /* direct. */
1738 if (operand->mode != M_DIRECT)
1740 if (exp->X_op == O_constant)
1742 /* Store only the 16 LSBs of the number. */
1743 INSERTS (opcode, exp->X_add_number, 15, 0);
1746 else if (exp->X_op == O_symbol)
1748 tinsn->reloc = BFD_RELOC_LO16;
1752 break; /* Not direct addressing. */
1755 if (operand->mode != M_REGISTER)
1757 reg = exp->X_add_number;
1758 if (reg >= REG_AR0 && reg <= REG_AR7)
1759 INSERTU (opcode, reg - REG_AR0, 24, 22);
1763 as_bad (_("Destination register must be ARn"));
1768 case 'B': /* Unsigned integer immediate. */
1769 /* Allow br label or br @label. */
1770 if (operand->mode != M_IMMED && operand->mode != M_DIRECT)
1772 if (exp->X_op == O_constant)
1774 if (exp->X_add_number < (1 << 24))
1776 INSERTU (opcode, exp->X_add_number, 23, 0);
1782 as_bad (_("Immediate value of %ld is too large"),
1783 (long) exp->X_add_number);
1788 if (IS_CPU_TIC4X (tic4x_cpu))
1790 tinsn->reloc = BFD_RELOC_24_PCREL;
1795 tinsn->reloc = BFD_RELOC_24;
1802 if (!IS_CPU_TIC4X (tic4x_cpu))
1804 if (operand->mode != M_INDIRECT)
1806 /* Require either *+ARn(disp) or *ARn. */
1807 if (operand->expr.X_add_number != 0
1808 && operand->expr.X_add_number != 0x18)
1811 as_bad (_("Invalid indirect addressing mode"));
1815 INSERTU (opcode, operand->aregno - REG_AR0, 2, 0);
1816 INSERTU (opcode, operand->disp, 7, 3);
1820 if (!(operand->mode == M_REGISTER))
1822 INSERTU (opcode, exp->X_add_number, 7, 0);
1826 if (!(operand->mode == M_REGISTER))
1828 reg = exp->X_add_number;
1829 if ( (reg >= REG_R0 && reg <= REG_R7)
1830 || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
1831 INSERTU (opcode, reg, 7, 0);
1835 as_bad (_("Register must be Rn"));
1841 if (operand->mode != M_IMMED_F
1842 && !(operand->mode == M_IMMED && exp->X_op == O_constant))
1845 if (operand->mode != M_IMMED_F)
1847 /* OK, we 've got something like cmpf 0, r0
1848 Why can't they stick in a bloody decimal point ?! */
1851 /* Create floating point number string. */
1852 sprintf (string, "%d.0", (int) exp->X_add_number);
1853 tic4x_atof (string, 's', operand->fwords);
1856 INSERTU (opcode, operand->fwords[0], 15, 0);
1860 if (operand->mode != M_REGISTER)
1862 INSERTU (opcode, exp->X_add_number, 15, 8);
1866 if (operand->mode != M_REGISTER)
1868 reg = exp->X_add_number;
1869 if ( (reg >= REG_R0 && reg <= REG_R7)
1870 || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
1871 INSERTU (opcode, reg, 15, 8);
1875 as_bad (_("Register must be Rn"));
1881 if (operand->mode != M_REGISTER)
1883 reg = exp->X_add_number;
1884 if (reg >= REG_R0 && reg <= REG_R7)
1885 INSERTU (opcode, reg - REG_R0, 18, 16);
1889 as_bad (_("Register must be R0--R7"));
1895 if ( operand->mode == M_REGISTER
1896 && tic4x_oplevel & OP_ENH )
1898 reg = exp->X_add_number;
1899 INSERTU (opcode, reg, 4, 0);
1900 INSERTU (opcode, 7, 7, 5);
1906 if (operand->mode != M_INDIRECT)
1908 if (operand->disp != 0 && operand->disp != 1)
1910 if (IS_CPU_TIC4X (tic4x_cpu))
1913 as_bad (_("Invalid indirect addressing mode displacement %d"),
1918 INSERTU (opcode, operand->aregno - REG_AR0, 2, 0);
1919 INSERTU (opcode, operand->expr.X_add_number, 7, 3);
1923 if ( operand->mode == M_REGISTER
1924 && tic4x_oplevel & OP_ENH )
1926 reg = exp->X_add_number;
1927 INSERTU (opcode, reg, 12, 8);
1928 INSERTU (opcode, 7, 15, 13);
1934 if (operand->mode != M_INDIRECT)
1936 if (operand->disp != 0 && operand->disp != 1)
1938 if (IS_CPU_TIC4X (tic4x_cpu))
1941 as_bad (_("Invalid indirect addressing mode displacement %d"),
1946 INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
1947 INSERTU (opcode, operand->expr.X_add_number, 15, 11);
1951 if (operand->mode != M_REGISTER)
1953 reg = exp->X_add_number;
1954 if (reg >= REG_R0 && reg <= REG_R7)
1955 INSERTU (opcode, reg - REG_R0, 21, 19);
1959 as_bad (_("Register must be R0--R7"));
1965 if (operand->mode != M_REGISTER)
1967 reg = exp->X_add_number;
1968 if (reg >= REG_R0 && reg <= REG_R7)
1969 INSERTU (opcode, reg - REG_R0, 24, 22);
1973 as_bad (_("Register must be R0--R7"));
1979 if (operand->mode != M_REGISTER)
1981 reg = exp->X_add_number;
1982 if (reg == REG_R2 || reg == REG_R3)
1983 INSERTU (opcode, reg - REG_R2, 22, 22);
1987 as_bad (_("Destination register must be R2 or R3"));
1993 if (operand->mode != M_REGISTER)
1995 reg = exp->X_add_number;
1996 if (reg == REG_R0 || reg == REG_R1)
1997 INSERTU (opcode, reg - REG_R0, 23, 23);
2001 as_bad (_("Destination register must be R0 or R1"));
2007 if (!IS_CPU_TIC4X (tic4x_cpu))
2009 if (operand->mode != M_INDIRECT)
2011 /* Require either *+ARn(disp) or *ARn. */
2012 if (operand->expr.X_add_number != 0
2013 && operand->expr.X_add_number != 0x18)
2016 as_bad (_("Invalid indirect addressing mode"));
2020 INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
2021 INSERTU (opcode, operand->disp, 15, 11);
2024 case 'P': /* PC relative displacement. */
2025 /* Allow br label or br @label. */
2026 if (operand->mode != M_IMMED && operand->mode != M_DIRECT)
2028 if (exp->X_op == O_constant)
2030 if (exp->X_add_number >= -32768 && exp->X_add_number <= 32767)
2032 INSERTS (opcode, exp->X_add_number, 15, 0);
2038 as_bad (_("Displacement value of %ld is too large"),
2039 (long) exp->X_add_number);
2044 tinsn->reloc = BFD_RELOC_16_PCREL;
2050 if (operand->mode != M_REGISTER)
2052 reg = exp->X_add_number;
2053 INSERTU (opcode, reg, 15, 0);
2057 if (operand->mode != M_REGISTER)
2059 reg = exp->X_add_number;
2060 if ( (reg >= REG_R0 && reg <= REG_R7)
2061 || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
2062 INSERTU (opcode, reg, 15, 0);
2066 as_bad (_("Register must be Rn"));
2072 if (operand->mode != M_REGISTER)
2074 reg = exp->X_add_number;
2075 INSERTU (opcode, reg, 20, 16);
2079 if (operand->mode != M_REGISTER)
2081 reg = exp->X_add_number;
2082 if ( (reg >= REG_R0 && reg <= REG_R7)
2083 || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
2084 INSERTU (opcode, reg, 20, 16);
2088 as_bad (_("Register must be Rn"));
2093 case 'S': /* Short immediate int. */
2094 if (operand->mode != M_IMMED && operand->mode != M_HI)
2096 if (exp->X_op == O_big)
2099 as_bad (_("Floating point number not valid in expression"));
2103 if (exp->X_op == O_constant)
2105 if (exp->X_add_number >= -32768 && exp->X_add_number <= 65535)
2107 INSERTS (opcode, exp->X_add_number, 15, 0);
2113 as_bad (_("Signed immediate value %ld too large"),
2114 (long) exp->X_add_number);
2119 else if (exp->X_op == O_symbol)
2121 if (operand->mode == M_HI)
2123 tinsn->reloc = BFD_RELOC_HI16;
2127 tinsn->reloc = BFD_RELOC_LO16;
2132 /* Handle cases like ldi foo - $, ar0 where foo
2133 is a forward reference. Perhaps we should check
2134 for X_op == O_symbol and disallow things like
2136 tinsn->reloc = BFD_RELOC_16;
2140 case 'T': /* 5-bit immediate value for tic4x stik. */
2141 if (!IS_CPU_TIC4X (tic4x_cpu))
2143 if (operand->mode != M_IMMED)
2145 if (exp->X_op == O_constant)
2147 if (exp->X_add_number < 16 && exp->X_add_number >= -16)
2149 INSERTS (opcode, exp->X_add_number, 20, 16);
2155 as_bad (_("Immediate value of %ld is too large"),
2156 (long) exp->X_add_number);
2161 break; /* No relocations allowed. */
2163 case 'U': /* Unsigned integer immediate. */
2164 if (operand->mode != M_IMMED && operand->mode != M_HI)
2166 if (exp->X_op == O_constant)
2168 if (exp->X_add_number < (1 << 16) && exp->X_add_number >= 0)
2170 INSERTU (opcode, exp->X_add_number, 15, 0);
2176 as_bad (_("Unsigned immediate value %ld too large"),
2177 (long) exp->X_add_number);
2182 else if (exp->X_op == O_symbol)
2184 if (operand->mode == M_HI)
2185 tinsn->reloc = BFD_RELOC_HI16;
2187 tinsn->reloc = BFD_RELOC_LO16;
2192 tinsn->reloc = BFD_RELOC_16;
2196 case 'V': /* Trap numbers (immediate field). */
2197 if (operand->mode != M_IMMED)
2199 if (exp->X_op == O_constant)
2201 if (exp->X_add_number < 512 && IS_CPU_TIC4X (tic4x_cpu))
2203 INSERTU (opcode, exp->X_add_number, 8, 0);
2206 else if (exp->X_add_number < 32 && IS_CPU_TIC3X (tic4x_cpu))
2208 INSERTU (opcode, exp->X_add_number | 0x20, 4, 0);
2214 as_bad (_("Immediate value of %ld is too large"),
2215 (long) exp->X_add_number);
2220 break; /* No relocations allowed. */
2222 case 'W': /* Short immediate int (0--7). */
2223 if (!IS_CPU_TIC4X (tic4x_cpu))
2225 if (operand->mode != M_IMMED)
2227 if (exp->X_op == O_big)
2230 as_bad (_("Floating point number not valid in expression"));
2234 if (exp->X_op == O_constant)
2236 if (exp->X_add_number >= -256 && exp->X_add_number <= 127)
2238 INSERTS (opcode, exp->X_add_number, 7, 0);
2244 as_bad (_("Immediate value %ld too large"),
2245 (long) exp->X_add_number);
2250 tinsn->reloc = BFD_RELOC_16;
2254 case 'X': /* Expansion register for tic4x. */
2255 if (operand->mode != M_REGISTER)
2257 reg = exp->X_add_number;
2258 if (reg >= REG_IVTP && reg <= REG_TVTP)
2259 INSERTU (opcode, reg - REG_IVTP, 4, 0);
2263 as_bad (_("Register must be ivtp or tvtp"));
2268 case 'Y': /* Address register for tic4x lda. */
2269 if (operand->mode != M_REGISTER)
2271 reg = exp->X_add_number;
2272 if (reg >= REG_AR0 && reg <= REG_SP)
2273 INSERTU (opcode, reg, 20, 16);
2277 as_bad (_("Register must be address register"));
2282 case 'Z': /* Expansion register for tic4x. */
2283 if (operand->mode != M_REGISTER)
2285 reg = exp->X_add_number;
2286 if (reg >= REG_IVTP && reg <= REG_TVTP)
2287 INSERTU (opcode, reg - REG_IVTP, 20, 16);
2291 as_bad (_("Register must be ivtp or tvtp"));
2297 if (operand->mode != M_INDIRECT)
2299 INSERTS (opcode, operand->disp, 7, 0);
2300 INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
2301 INSERTU (opcode, operand->expr.X_add_number, 15, 11);
2304 case '|': /* treat as `,' if have ldi_ldi form. */
2305 if (tinsn->parallel)
2307 if (--num_operands < 0)
2308 break; /* Too few operands. */
2310 if (operand->mode != M_PARALLEL)
2315 case ',': /* Another operand. */
2316 if (--num_operands < 0)
2317 break; /* Too few operands. */
2319 exp = &operand->expr;
2322 case ';': /* Another optional operand. */
2323 if (num_operands == 1 || operand[1].mode == M_PARALLEL)
2325 if (--num_operands < 0)
2326 break; /* Too few operands. */
2328 exp = &operand->expr;
2339 tic4x_insn_check (tic4x_insn_t *tinsn)
2342 if (!strcmp (tinsn->name, "lda"))
2344 if (tinsn->num_operands < 2 || tinsn->num_operands > 2)
2345 as_fatal ("Illegal internal LDA insn definition");
2347 if (tinsn->operands[0].mode == M_REGISTER
2348 && tinsn->operands[1].mode == M_REGISTER
2349 && tinsn->operands[0].expr.X_add_number == tinsn->operands[1].expr.X_add_number )
2350 as_bad (_("Source and destination register should not be equal"));
2352 else if (!strcmp (tinsn->name, "ldi_ldi")
2353 || !strcmp (tinsn->name, "ldi1_ldi2")
2354 || !strcmp (tinsn->name, "ldi2_ldi1")
2355 || !strcmp (tinsn->name, "ldf_ldf")
2356 || !strcmp (tinsn->name, "ldf1_ldf2")
2357 || !strcmp (tinsn->name, "ldf2_ldf1") )
2359 if (tinsn->num_operands < 4 && tinsn->num_operands > 5 )
2360 as_fatal ("Illegal internal %s insn definition", tinsn->name);
2362 if (tinsn->operands[1].mode == M_REGISTER
2363 && tinsn->operands[tinsn->num_operands-1].mode == M_REGISTER
2364 && tinsn->operands[1].expr.X_add_number == tinsn->operands[tinsn->num_operands-1].expr.X_add_number )
2365 as_warn (_("Equal parallell destination registers, one result will be discarded"));
2370 tic4x_insn_output (tic4x_insn_t *tinsn)
2374 /* Grab another fragment for opcode. */
2375 dst = frag_more (tinsn->nchars);
2377 /* Put out opcode word as a series of bytes in little endian order. */
2378 md_number_to_chars (dst, tinsn->opcode, tinsn->nchars);
2380 /* Put out the symbol-dependent stuff. */
2381 if (tinsn->reloc != NO_RELOC)
2383 /* Where is the offset into the fragment for this instruction. */
2384 fix_new_exp (frag_now,
2385 dst - frag_now->fr_literal, /* where */
2386 tinsn->nchars, /* size */
2393 /* Parse the operands. */
2395 tic4x_operands_parse (char *s, tic4x_operand_t *operands, int num_operands)
2398 return num_operands;
2401 s = tic4x_operand_parse (s, &operands[num_operands++]);
2402 while (num_operands < TIC4X_OPERANDS_MAX && *s++ == ',');
2404 if (num_operands > TIC4X_OPERANDS_MAX)
2406 as_bad (_("Too many operands scanned"));
2409 return num_operands;
2412 /* Assemble a single instruction. Its label has already been handled
2413 by the generic front end. We just parse mnemonic and operands, and
2414 produce the bytes of data and relocation. */
2416 md_assemble (char *str)
2422 tic4x_inst_t *inst; /* Instruction template. */
2423 tic4x_inst_t *first_inst;
2425 /* Scan for parallel operators */
2429 while (*s && *s != '|')
2432 if (*s && s[1]=='|')
2436 as_bad (_("Parallel opcode cannot contain more than two instructions"));
2442 /* Lets take care of the first part of the parallel insn */
2447 /* .. and let the second run though here */
2451 if (str && insn->parallel)
2453 /* Find mnemonic (second part of parallel instruction). */
2455 /* Skip past instruction mnemonic. */
2456 while (*s && *s != ' ')
2458 if (*s) /* Null terminate for hash_find. */
2459 *s++ = '\0'; /* and skip past null. */
2460 strcat (insn->name, "_");
2461 strncat (insn->name, str, TIC4X_NAME_MAX - strlen (insn->name));
2463 insn->operands[insn->num_operands++].mode = M_PARALLEL;
2465 if ((i = tic4x_operands_parse
2466 (s, insn->operands, insn->num_operands)) < 0)
2472 insn->num_operands = i;
2478 if ((insn->inst = (struct tic4x_inst *)
2479 hash_find (tic4x_op_hash, insn->name)) == NULL)
2481 as_bad (_("Unknown opcode `%s'."), insn->name);
2491 ok = tic4x_operands_match (inst, insn, 1);
2498 } while (!ok && !strcmp (inst->name, inst[1].name) && inst++);
2502 tic4x_insn_check (insn);
2503 tic4x_insn_output (insn);
2508 tic4x_operands_match (first_inst, insn, 0);
2509 as_bad (_("Invalid operands for %s"), insn->name);
2512 as_bad (_("Invalid instruction %s"), insn->name);
2517 /* Find mnemonic. */
2519 while (*s && *s != ' ') /* Skip past instruction mnemonic. */
2521 if (*s) /* Null terminate for hash_find. */
2522 *s++ = '\0'; /* and skip past null. */
2523 strncpy (insn->name, str, TIC4X_NAME_MAX - 3);
2525 if ((i = tic4x_operands_parse (s, insn->operands, 0)) < 0)
2527 insn->inst = NULL; /* Flag that error occurred. */
2532 insn->num_operands = i;
2541 tic4x_cleanup (void)
2547 /* Turn a string in input_line_pointer into a floating point constant
2548 of type type, and store the appropriate bytes in *litP. The number
2549 of chars emitted is stored in *sizeP. An error message is
2550 returned, or NULL on OK. */
2553 md_atof (int type, char *litP, int *sizeP)
2557 LITTLENUM_TYPE words[MAX_LITTLENUMS];
2558 LITTLENUM_TYPE *wordP;
2563 case 's': /* .single */
2569 case 'd': /* .double */
2571 case 'f': /* .float */
2574 prec = 2; /* 1 32-bit word */
2577 case 'i': /* .ieee */
2581 type = 'f'; /* Rewrite type to be usable by atof_ieee(). */
2584 case 'e': /* .ldouble */
2586 prec = 4; /* 2 32-bit words */
2592 return _("Unrecognized or unsupported floating point constant");
2596 t = atof_ieee (input_line_pointer, type, words);
2598 t = tic4x_atof (input_line_pointer, type, words);
2600 input_line_pointer = t;
2601 *sizeP = prec * sizeof (LITTLENUM_TYPE);
2603 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
2604 little endian byte order. */
2605 /* SES: However it is required to put the words (32-bits) out in the
2606 correct order, hence we write 2 and 2 littlenums in little endian
2607 order, while we keep the original order on successive words. */
2608 for (wordP = words; wordP<(words+prec) ; wordP+=2)
2610 if (wordP < (words + prec - 1)) /* Dump wordP[1] (if we have one). */
2612 md_number_to_chars (litP, (valueT) (wordP[1]),
2613 sizeof (LITTLENUM_TYPE));
2614 litP += sizeof (LITTLENUM_TYPE);
2618 md_number_to_chars (litP, (valueT) (wordP[0]),
2619 sizeof (LITTLENUM_TYPE));
2620 litP += sizeof (LITTLENUM_TYPE);
2626 md_apply_fix (fixS *fixP, valueT *value, segT seg ATTRIBUTE_UNUSED)
2628 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
2629 valueT val = *value;
2631 switch (fixP->fx_r_type)
2633 case BFD_RELOC_HI16:
2637 case BFD_RELOC_LO16:
2644 switch (fixP->fx_r_type)
2649 case BFD_RELOC_24_PCREL:
2652 case BFD_RELOC_16_PCREL:
2653 case BFD_RELOC_LO16:
2654 case BFD_RELOC_HI16:
2661 as_bad (_("Bad relocation type: 0x%02x"), fixP->fx_r_type);
2665 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) fixP->fx_done = 1;
2668 /* Should never be called for tic4x. */
2670 md_convert_frag (bfd *headers ATTRIBUTE_UNUSED,
2671 segT sec ATTRIBUTE_UNUSED,
2672 fragS *fragP ATTRIBUTE_UNUSED)
2674 as_fatal ("md_convert_frag");
2677 /* Should never be called for tic4x. */
2679 md_create_short_jump (char *ptr ATTRIBUTE_UNUSED,
2680 addressT from_addr ATTRIBUTE_UNUSED,
2681 addressT to_addr ATTRIBUTE_UNUSED,
2682 fragS *frag ATTRIBUTE_UNUSED,
2683 symbolS *to_symbol ATTRIBUTE_UNUSED)
2685 as_fatal ("md_create_short_jmp\n");
2688 /* Should never be called for tic4x. */
2690 md_create_long_jump (char *ptr ATTRIBUTE_UNUSED,
2691 addressT from_addr ATTRIBUTE_UNUSED,
2692 addressT to_addr ATTRIBUTE_UNUSED,
2693 fragS *frag ATTRIBUTE_UNUSED,
2694 symbolS *to_symbol ATTRIBUTE_UNUSED)
2696 as_fatal ("md_create_long_jump\n");
2699 /* Should never be called for tic4x. */
2701 md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
2702 segT segtype ATTRIBUTE_UNUSED)
2704 as_fatal ("md_estimate_size_before_relax\n");
2710 md_parse_option (int c, char *arg)
2714 case OPTION_CPU: /* cpu brand */
2715 if (TOLOWER (*arg) == 'c')
2717 tic4x_cpu = atoi (arg);
2718 if (!IS_CPU_TIC3X (tic4x_cpu) && !IS_CPU_TIC4X (tic4x_cpu))
2719 as_warn (_("Unsupported processor generation %d"), tic4x_cpu);
2722 case OPTION_REV: /* cpu revision */
2723 tic4x_revision = atoi (arg);
2727 as_warn (_("Option -b is depreciated, please use -mbig"));
2728 case OPTION_BIG: /* big model */
2729 tic4x_big_model = 1;
2733 as_warn (_("Option -p is depreciated, please use -mmemparm"));
2734 case OPTION_MEMPARM: /* push args */
2739 as_warn (_("Option -r is depreciated, please use -mregparm"));
2740 case OPTION_REGPARM: /* register args */
2745 as_warn (_("Option -s is depreciated, please use -msmall"));
2746 case OPTION_SMALL: /* small model */
2747 tic4x_big_model = 0;
2754 case OPTION_LOWPOWER:
2758 case OPTION_ENHANCED:
2770 md_show_usage (FILE *stream)
2773 _("\nTIC4X options:\n"
2774 " -mcpu=CPU -mCPU select architecture variant. CPU can be:\n"
2776 " 31 - TMS320C31, TMS320LC31\n"
2778 " 33 - TMS320VC33\n"
2781 " -mrev=REV set cpu hardware revision (integer numbers).\n"
2782 " Combinations of -mcpu and -mrev will enable/disable\n"
2783 " the appropriate options (-midle2, -mlowpower and\n"
2784 " -menhanced) according to the selected type\n"
2785 " -mbig select big memory model\n"
2786 " -msmall select small memory model (default)\n"
2787 " -mregparm select register parameters (default)\n"
2788 " -mmemparm select memory parameters\n"
2789 " -midle2 enable IDLE2 support\n"
2790 " -mlowpower enable LOPOWER and MAXSPEED support\n"
2791 " -menhanced enable enhanced opcode support\n"));
2794 /* This is called when a line is unrecognized. This is used to handle
2795 definitions of TI C3x tools style local labels $n where n is a single
2798 tic4x_unrecognized_line (int c)
2803 if (c != '$' || ! ISDIGIT (input_line_pointer[0]))
2806 s = input_line_pointer;
2808 /* Let's allow multiple digit local labels. */
2810 while (ISDIGIT (*s))
2812 lab = lab * 10 + *s - '0';
2816 if (dollar_label_defined (lab))
2818 as_bad (_("Label \"$%d\" redefined"), lab);
2822 define_dollar_label (lab);
2823 colon (dollar_label_name (lab, 0));
2824 input_line_pointer = s + 1;
2829 /* Handle local labels peculiar to us referred to in an expression. */
2831 md_undefined_symbol (char *name)
2833 /* Look for local labels of the form $n. */
2834 if (name[0] == '$' && ISDIGIT (name[1]))
2840 while (ISDIGIT ((unsigned char) *s))
2842 lab = lab * 10 + *s - '0';
2845 if (dollar_label_defined (lab))
2847 name = dollar_label_name (lab, 0);
2848 symbolP = symbol_find (name);
2852 name = dollar_label_name (lab, 1);
2853 symbolP = symbol_find_or_make (name);
2861 /* Parse an operand that is machine-specific. */
2863 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
2867 /* Round up a section size to the appropriate boundary---do we need this? */
2869 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
2871 return size; /* Byte (i.e., 32-bit) alignment is fine? */
2875 tic4x_pc_offset (unsigned int op)
2877 /* Determine the PC offset for a C[34]x instruction.
2878 This could be simplified using some boolean algebra
2879 but at the expense of readability. */
2883 case 0x62: /* call (C4x) */
2884 case 0x64: /* rptb (C4x) */
2886 case 0x61: /* brd */
2887 case 0x63: /* laj */
2888 case 0x65: /* rptbd (C4x) */
2890 case 0x66: /* swi */
2897 switch ((op & 0xffe00000) >> 20)
2899 case 0x6a0: /* bB */
2900 case 0x720: /* callB */
2901 case 0x740: /* trapB */
2904 case 0x6a2: /* bBd */
2905 case 0x6a6: /* bBat */
2906 case 0x6aa: /* bBaf */
2907 case 0x722: /* lajB */
2908 case 0x748: /* latB */
2909 case 0x798: /* rptbd */
2916 switch ((op & 0xfe200000) >> 20)
2918 case 0x6e0: /* dbB */
2921 case 0x6e2: /* dbBd */
2931 /* Exactly what point is a PC-relative offset relative TO?
2932 With the C3x we have the following:
2933 DBcond, Bcond disp + PC + 1 => PC
2934 DBcondD, BcondD disp + PC + 3 => PC
2937 md_pcrel_from (fixS *fixP)
2942 buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
2943 op = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
2945 return ((fixP->fx_where + fixP->fx_frag->fr_address) >> 2) +
2946 tic4x_pc_offset (op);
2949 /* Fill the alignment area with NOP's on .text, unless fill-data
2952 tic4x_do_align (int alignment,
2957 /* Because we are talking lwords, not bytes, adjust alignment to do words */
2960 if (alignment != 0 && !need_pass_2)
2964 if (subseg_text_p (now_seg))
2968 md_number_to_chars (nop, TIC_NOP_OPCODE, 4);
2969 frag_align_pattern (alignment, nop, sizeof (nop), max);
2972 frag_align (alignment, 0, max);
2975 frag_align (alignment, *fill, max);
2977 frag_align_pattern (alignment, fill, len, max);
2980 /* Return 1 to skip the default alignment function */
2984 /* Look for and remove parallel instruction operator ||. */
2986 tic4x_start_line (void)
2988 char *s = input_line_pointer;
2992 /* If parallel instruction prefix found at start of line, skip it. */
2993 if (*input_line_pointer == '|' && input_line_pointer[1] == '|')
2998 input_line_pointer ++;
2999 *input_line_pointer = ' ';
3000 /* So line counters get bumped. */
3001 input_line_pointer[-1] = '\n';
3006 /* Write out the previous insn here */
3009 input_line_pointer = s;
3014 tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixP)
3018 reloc = (arelent *) xmalloc (sizeof (arelent));
3020 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
3021 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
3022 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
3023 reloc->address /= OCTETS_PER_BYTE;
3024 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
3025 if (reloc->howto == (reloc_howto_type *) NULL)
3027 as_bad_where (fixP->fx_file, fixP->fx_line,
3028 _("Reloc %d not supported by object file format"),
3029 (int) fixP->fx_r_type);
3033 if (fixP->fx_r_type == BFD_RELOC_HI16)
3034 reloc->addend = fixP->fx_offset;
3036 reloc->addend = fixP->fx_addnumber;