1 /* tc-tic4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
2 Copyright (C) 1997,1998, 2002, 2003 Free Software Foundation.
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. */
26 o .align cannot handle fill-data-width larger than 0xFF/8-bits. It
27 should be possible to define a 32-bits pattern.
29 o .align fills all section with NOP's when used regardless if has
30 been used in .text or .data. (However the .align is primarely
31 intended used in .text sections. If you require something else,
32 use .align <size>,0x00)
34 o .align: Implement a 'bu' insn if the number of nop's exeeds 4
35 within the align frag. if(fragsize>4words) insert bu fragend+1
38 o .usect if has symbol on previous line not implemented
40 o .sym, .eos, .stag, .etag, .member not implemented
42 o Evaluation of constant floating point expressions (expr.c needs
45 o Support 'abc' constants (that is 0x616263)
52 #include "opcode/tic4x.h"
58 /* OK, we accept a syntax similar to the other well known C30
59 assembly tools. With TIC4X_ALT_SYNTAX defined we are more
60 flexible, allowing a more Unix-like syntax: `%' in front of
61 register names, `#' in front of immediate constants, and
62 not requiring `@' in front of direct addresses. */
64 #define TIC4X_ALT_SYNTAX
66 /* Equal to MAX_PRECISION in atof-ieee.c. */
67 #define MAX_LITTLENUMS 6 /* (12 bytes) */
69 /* Handle of the inst mnemonic hash table. */
70 static struct hash_control *tic4x_op_hash = NULL;
72 /* Handle asg pseudo. */
73 static struct hash_control *tic4x_asg_hash = NULL;
75 static unsigned int tic4x_cpu = 0; /* Default to TMS320C40. */
76 static unsigned int tic4x_revision = 0; /* CPU revision */
77 static unsigned int tic4x_idle2 = 0; /* Idle2 support */
78 static unsigned int tic4x_lowpower = 0; /* Lowpower support */
79 static unsigned int tic4x_enhanced = 0; /* Enhanced opcode support */
80 static unsigned int tic4x_big_model = 0; /* Default to small memory model. */
81 static unsigned int tic4x_reg_args = 0; /* Default to args passed on stack. */
82 static unsigned long tic4x_oplevel = 0; /* Opcode level */
84 #define OPTION_CPU 'm'
85 #define OPTION_BIG (OPTION_MD_BASE + 1)
86 #define OPTION_SMALL (OPTION_MD_BASE + 2)
87 #define OPTION_MEMPARM (OPTION_MD_BASE + 3)
88 #define OPTION_REGPARM (OPTION_MD_BASE + 4)
89 #define OPTION_IDLE2 (OPTION_MD_BASE + 5)
90 #define OPTION_LOWPOWER (OPTION_MD_BASE + 6)
91 #define OPTION_ENHANCED (OPTION_MD_BASE + 7)
92 #define OPTION_REV (OPTION_MD_BASE + 8)
94 CONST char *md_shortopts = "bm:prs";
95 struct option md_longopts[] =
97 { "mcpu", required_argument, NULL, OPTION_CPU },
98 { "mdsp", required_argument, NULL, OPTION_CPU },
99 { "mbig", no_argument, NULL, OPTION_BIG },
100 { "msmall", no_argument, NULL, OPTION_SMALL },
101 { "mmemparm", no_argument, NULL, OPTION_MEMPARM },
102 { "mregparm", no_argument, NULL, OPTION_REGPARM },
103 { "midle2", no_argument, NULL, OPTION_IDLE2 },
104 { "mlowpower", no_argument, NULL, OPTION_LOWPOWER },
105 { "menhanced", no_argument, NULL, OPTION_ENHANCED },
106 { "mrev", required_argument, NULL, OPTION_REV },
107 { NULL, no_argument, NULL, 0 }
110 size_t md_longopts_size = sizeof (md_longopts);
115 M_UNKNOWN, M_IMMED, M_DIRECT, M_REGISTER, M_INDIRECT,
116 M_IMMED_F, M_PARALLEL, M_HI
120 typedef struct tic4x_operand
122 tic4x_addr_mode_t mode; /* Addressing mode. */
123 expressionS expr; /* Expression. */
124 int disp; /* Displacement for indirect addressing. */
125 int aregno; /* Aux. register number. */
126 LITTLENUM_TYPE fwords[MAX_LITTLENUMS]; /* Float immed. number. */
130 typedef struct tic4x_insn
132 char name[TIC4X_NAME_MAX]; /* Mnemonic of instruction. */
133 unsigned int in_use; /* True if in_use. */
134 unsigned int parallel; /* True if parallel instruction. */
135 unsigned int nchars; /* This is always 4 for the C30. */
136 unsigned long opcode; /* Opcode number. */
137 expressionS exp; /* Expression required for relocation. */
138 int reloc; /* Relocation type required. */
139 int pcrel; /* True if relocation PC relative. */
140 char *pname; /* Name of instruction in parallel. */
141 unsigned int num_operands; /* Number of operands in total. */
142 tic4x_inst_t *inst; /* Pointer to first template. */
143 tic4x_operand_t operands[TIC4X_OPERANDS_MAX];
147 static tic4x_insn_t the_insn; /* Info about our instruction. */
148 static tic4x_insn_t *insn = &the_insn;
150 static int tic4x_gen_to_words
151 PARAMS ((FLONUM_TYPE, LITTLENUM_TYPE *, int ));
152 static char *tic4x_atof
153 PARAMS ((char *, char, LITTLENUM_TYPE * ));
154 static void tic4x_insert_reg
155 PARAMS ((char *, int ));
156 static void tic4x_insert_sym
157 PARAMS ((char *, int ));
158 static char *tic4x_expression
159 PARAMS ((char *, expressionS *));
160 static char *tic4x_expression_abs
161 PARAMS ((char *, int *));
162 static void tic4x_emit_char
163 PARAMS ((char, int));
164 static void tic4x_seg_alloc
165 PARAMS ((char *, segT, int, symbolS *));
166 static void tic4x_asg
168 static void tic4x_bss
170 static void tic4x_globl
172 static void tic4x_cons
174 static void tic4x_stringer
176 static void tic4x_eval
178 static void tic4x_newblock
180 static void tic4x_sect
182 static void tic4x_set
184 static void tic4x_usect
186 static void tic4x_version
188 static void tic4x_init_regtable
190 static void tic4x_init_symbols
192 static int tic4x_inst_insert
193 PARAMS ((tic4x_inst_t *));
194 static tic4x_inst_t *tic4x_inst_make
195 PARAMS ((char *, unsigned long, char *));
196 static int tic4x_inst_add
197 PARAMS ((tic4x_inst_t *));
202 static int tic4x_indirect_parse
203 PARAMS ((tic4x_operand_t *, const tic4x_indirect_t *));
204 static char *tic4x_operand_parse
205 PARAMS ((char *, tic4x_operand_t *));
206 static int tic4x_operands_match
207 PARAMS ((tic4x_inst_t *, tic4x_insn_t *, int));
208 static void tic4x_insn_check
209 PARAMS ((tic4x_insn_t *));
210 static void tic4x_insn_output
211 PARAMS ((tic4x_insn_t *));
212 static int tic4x_operands_parse
213 PARAMS ((char *, tic4x_operand_t *, int ));
219 PARAMS ((int, char *, int *));
221 PARAMS ((fixS *, valueT *, segT ));
223 PARAMS ((bfd *, segT, fragS *));
224 void md_create_short_jump
225 PARAMS ((char *, addressT, addressT, fragS *, symbolS *));
226 void md_create_long_jump
227 PARAMS ((char *, addressT, addressT, fragS *, symbolS *));
228 int md_estimate_size_before_relax
229 PARAMS ((register fragS *, segT));
231 PARAMS ((int, char *));
234 int tic4x_unrecognized_line
236 symbolS *md_undefined_symbol
239 PARAMS ((expressionS *));
240 valueT md_section_align
241 PARAMS ((segT, valueT));
242 static int tic4x_pc_offset
243 PARAMS ((unsigned int));
247 PARAMS ((int, const char *, int, int));
248 void tic4x_start_line
250 arelent *tc_gen_reloc
251 PARAMS ((asection *, fixS *));
257 {"align", s_align_bytes, 32},
258 {"ascii", tic4x_stringer, 1},
259 {"asciz", tic4x_stringer, 0},
260 {"asg", tic4x_asg, 0},
261 {"block", s_space, 4},
262 {"byte", tic4x_cons, 1},
263 {"bss", tic4x_bss, 0},
264 {"copy", s_include, 0},
265 {"def", tic4x_globl, 0},
266 {"equ", tic4x_set, 0},
267 {"eval", tic4x_eval, 0},
268 {"global", tic4x_globl, 0},
269 {"globl", tic4x_globl, 0},
270 {"hword", tic4x_cons, 2},
271 {"ieee", float_cons, 'i'},
272 {"int", tic4x_cons, 4}, /* .int allocates 4 bytes. */
273 {"ldouble", float_cons, 'e'},
274 {"newblock", tic4x_newblock, 0},
275 {"ref", s_ignore, 0}, /* All undefined treated as external. */
276 {"set", tic4x_set, 0},
277 {"sect", tic4x_sect, 1}, /* Define named section. */
278 {"space", s_space, 4},
279 {"string", tic4x_stringer, 0},
280 {"usect", tic4x_usect, 0}, /* Reserve space in uninit. named sect. */
281 {"version", tic4x_version, 0},
282 {"word", tic4x_cons, 4}, /* .word allocates 4 bytes. */
283 {"xdef", tic4x_globl, 0},
287 int md_short_jump_size = 4;
288 int md_long_jump_size = 4;
289 const int md_reloc_size = RELSZ; /* Coff headers. */
291 /* This array holds the chars that always start a comment. If the
292 pre-processor is disabled, these aren't very useful. */
293 #ifdef TIC4X_ALT_SYNTAX
294 const char comment_chars[] = ";!";
296 const char comment_chars[] = ";";
299 /* This array holds the chars that only start a comment at the beginning of
300 a line. If the line seems to have the form '# 123 filename'
301 .line and .file directives will appear in the pre-processed output.
302 Note that input_file.c hand checks for '#' at the beginning of the
303 first line of the input file. This is because the compiler outputs
304 #NO_APP at the beginning of its output.
305 Also note that comments like this one will always work. */
306 const char line_comment_chars[] = "#*";
308 /* We needed an unused char for line separation to work around the
309 lack of macros, using sed and such. */
310 const char line_separator_chars[] = "&";
312 /* Chars that can be used to separate mant from exp in floating point nums. */
313 const char EXP_CHARS[] = "eE";
315 /* Chars that mean this number is a floating point constant. */
318 const char FLT_CHARS[] = "fFilsS";
320 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
321 changed in read.c. Ideally it shouldn't have to know about it at
322 all, but nothing is ideal around here. */
324 /* Flonums returned here. */
325 extern FLONUM_TYPE generic_floating_point_number;
327 /* Precision in LittleNums. */
328 #define MAX_PRECISION (4) /* Its a bit overkill for us, but the code
330 #define S_PRECISION (1) /* Short float constants 16-bit. */
331 #define F_PRECISION (2) /* Float and double types 32-bit. */
332 #define E_PRECISION (4) /* Extended precision, 64-bit (real 40-bit). */
335 /* Turn generic_floating_point_number into a real short/float/double. */
337 tic4x_gen_to_words (flonum, words, precision)
339 LITTLENUM_TYPE *words;
342 int return_value = 0;
343 LITTLENUM_TYPE *p; /* Littlenum pointer. */
344 int mantissa_bits; /* Bits in mantissa field. */
345 int exponent_bits; /* Bits in exponent field. */
347 unsigned int sone; /* Scaled one. */
348 unsigned int sfract; /* Scaled fraction. */
349 unsigned int smant; /* Scaled mantissa. */
351 unsigned int mover; /* Mantissa overflow bits */
352 unsigned int rbit; /* Round bit. */
353 int shift; /* Shift count. */
356 The code in this function is altered slightly to support floats
357 with 31-bits mantissas, thus the documentation below may be a
358 little bit inaccurate.
361 Here is how a generic floating point number is stored using
362 flonums (an extension of bignums) where p is a pointer to an
365 For example 2e-3 is stored with exp = -4 and
372 with low = &bits[2], high = &bits[5], and leader = &bits[5].
374 This number can be written as
375 0x0083126e978d4fde.00000000 * 65536**-4 or
376 0x0.0083126e978d4fde * 65536**0 or
377 0x0.83126e978d4fde * 2**-8 = 2e-3
379 Note that low points to the 65536**0 littlenum (bits[2]) and
380 leader points to the most significant non-zero littlenum
383 TMS320C3X floating point numbers are a bit of a strange beast.
384 The 32-bit flavour has the 8 MSBs representing the exponent in
385 twos complement format (-128 to +127). There is then a sign bit
386 followed by 23 bits of mantissa. The mantissa is expressed in
387 twos complement format with the binary point after the most
388 significant non sign bit. The bit after the binary point is
389 suppressed since it is the complement of the sign bit. The
390 effective mantissa is thus 24 bits. Zero is represented by an
393 The 16-bit flavour has the 4 MSBs representing the exponent in
394 twos complement format (-8 to +7). There is then a sign bit
395 followed by 11 bits of mantissa. The mantissa is expressed in
396 twos complement format with the binary point after the most
397 significant non sign bit. The bit after the binary point is
398 suppressed since it is the complement of the sign bit. The
399 effective mantissa is thus 12 bits. Zero is represented by an
400 exponent of -8. For example,
402 number norm mant m x e s i fraction f
403 +0.500 => 1.00000000000 -1 -1 0 1 .00000000000 (1 + 0) * 2^(-1)
404 +0.999 => 1.11111111111 -1 -1 0 1 .11111111111 (1 + 0.99) * 2^(-1)
405 +1.000 => 1.00000000000 0 0 0 1 .00000000000 (1 + 0) * 2^(0)
406 +1.500 => 1.10000000000 0 0 0 1 .10000000000 (1 + 0.5) * 2^(0)
407 +1.999 => 1.11111111111 0 0 0 1 .11111111111 (1 + 0.9) * 2^(0)
408 +2.000 => 1.00000000000 1 1 0 1 .00000000000 (1 + 0) * 2^(1)
409 +4.000 => 1.00000000000 2 2 0 1 .00000000000 (1 + 0) * 2^(2)
410 -0.500 => 1.00000000000 -1 -1 1 0 .10000000000 (-2 + 0) * 2^(-2)
411 -1.000 => 1.00000000000 0 -1 1 0 .00000000000 (-2 + 0) * 2^(-1)
412 -1.500 => 1.10000000000 0 0 1 0 .10000000000 (-2 + 0.5) * 2^(0)
413 -1.999 => 1.11111111111 0 0 1 0 .00000000001 (-2 + 0.11) * 2^(0)
414 -2.000 => 1.00000000000 1 1 1 0 .00000000000 (-2 + 0) * 2^(0)
415 -4.000 => 1.00000000000 2 1 1 0 .00000000000 (-2 + 0) * 2^(1)
417 where e is the exponent, s is the sign bit, i is the implied bit,
418 and f is the fraction stored in the mantissa field.
420 num = (1 + f) * 2^x = m * 2^e if s = 0
421 num = (-2 + f) * 2^x = -m * 2^e if s = 1
422 where 0 <= f < 1.0 and 1.0 <= m < 2.0
424 The fraction (f) and exponent (e) fields for the TMS320C3X format
425 can be derived from the normalised mantissa (m) and exponent (x) using:
427 f = m - 1, e = x if s = 0
428 f = 2 - m, e = x if s = 1 and m != 1.0
429 f = 0, e = x - 1 if s = 1 and m = 1.0
430 f = 0, e = -8 if m = 0
433 OK, the other issue we have to consider is rounding since the
434 mantissa has a much higher potential precision than what we can
435 represent. To do this we add half the smallest storable fraction.
436 We then have to renormalise the number to allow for overflow.
438 To convert a generic flonum into a TMS320C3X floating point
439 number, here's what we try to do....
441 The first thing is to generate a normalised mantissa (m) where
442 1.0 <= m < 2 and to convert the exponent from base 16 to base 2.
443 We desire the binary point to be placed after the most significant
444 non zero bit. This process is done in two steps: firstly, the
445 littlenum with the most significant non zero bit is located (this
446 is done for us since leader points to this littlenum) and the
447 binary point (which is currently after the LSB of the littlenum
448 pointed to by low) is moved to before the MSB of the littlenum
449 pointed to by leader. This requires the exponent to be adjusted
450 by leader - low + 1. In the earlier example, the new exponent is
451 thus -4 + (5 - 2 + 1) = 0 (base 65536). We now need to convert
452 the exponent to base 2 by multiplying the exponent by 16 (log2
453 65536). The exponent base 2 is thus also zero.
455 The second step is to hunt for the most significant non zero bit
456 in the leader littlenum. We do this by left shifting a copy of
457 the leader littlenum until bit 16 is set (0x10000) and counting
458 the number of shifts, S, required. The number of shifts then has to
459 be added to correct the exponent (base 2). For our example, this
460 will require 9 shifts and thus our normalised exponent (base 2) is
461 0 + 9 = 9. Note that the worst case scenario is when the leader
462 littlenum is 1, thus requiring 16 shifts.
464 We now have to left shift the other littlenums by the same amount,
465 propagating the shifted bits into the more significant littlenums.
466 To save a lot of unecessary shifting we only have to consider
467 two or three littlenums, since the greatest number of mantissa
468 bits required is 24 + 1 rounding bit. While two littlenums
469 provide 32 bits of precision, the most significant littlenum
470 may only contain a single significant bit and thus an extra
471 littlenum is required.
473 Denoting the number of bits in the fraction field as F, we require
474 G = F + 2 bits (one extra bit is for rounding, the other gets
475 suppressed). Say we required S shifts to find the most
476 significant bit in the leader littlenum, the number of left shifts
477 required to move this bit into bit position G - 1 is L = G + S - 17.
478 Note that this shift count may be negative for the short floating
479 point flavour (where F = 11 and thus G = 13 and potentially S < 3).
480 If L > 0 we have to shunt the next littlenum into position. Bit
481 15 (the MSB) of the next littlenum needs to get moved into position
482 L - 1 (If L > 15 we need all the bits of this littlenum and
483 some more from the next one.). We subtract 16 from L and use this
484 as the left shift count; the resultant value we or with the
485 previous result. If L > 0, we repeat this operation. */
487 if (precision != S_PRECISION)
489 if (precision == E_PRECISION)
490 words[2] = words[3] = 0x0000;
492 /* 0.0e0 or NaN seen. */
493 if (flonum.low > flonum.leader /* = 0.0e0 */
494 || flonum.sign == 0) /* = NaN */
497 as_bad ("Nan, using zero.");
502 if (flonum.sign == 'P')
504 /* +INF: Replace with maximum float. */
505 if (precision == S_PRECISION)
512 if (precision == E_PRECISION)
519 else if (flonum.sign == 'N')
521 /* -INF: Replace with maximum float. */
522 if (precision == S_PRECISION)
526 if (precision == E_PRECISION)
531 exponent = (flonum.exponent + flonum.leader - flonum.low + 1) * 16;
533 if (!(tmp = *flonum.leader))
534 abort (); /* Hmmm. */
535 shift = 0; /* Find position of first sig. bit. */
538 exponent -= (16 - shift); /* Adjust exponent. */
540 if (precision == S_PRECISION) /* Allow 1 rounding bit. */
545 else if(precision == F_PRECISION)
550 else /* E_PRECISION */
556 shift = mantissa_bits - shift;
561 /* Store the mantissa data into smant and the roundbit into rbit */
562 for (p = flonum.leader; p >= flonum.low && shift > -16; p--)
564 tmp = shift >= 0 ? *p << shift : *p >> -shift;
565 rbit = shift < 0 ? ((*p >> (-shift-1)) & 0x1) : 0;
570 /* OK, we've got our scaled mantissa so let's round it up */
573 /* If the mantissa is going to overflow when added, lets store
574 the extra bit in mover. -- A special case exists when
575 mantissa_bits is 31 (E_PRECISION). Then the first test cannot
576 be trusted, as result is host-dependent, thus the second
578 if( smant == ((unsigned)(1<<(mantissa_bits+1))-1)
579 || smant == (unsigned)-1 ) /* This is to catch E_PRECISION cases */
584 /* Get the scaled one value */
585 sone = (1 << (mantissa_bits));
587 /* The number may be unnormalised so renormalise it... */
591 smant |= sone; /* Insert the bit from mover into smant */
595 /* The binary point is now between bit positions 11 and 10 or 23 and 22,
596 i.e., between mantissa_bits - 1 and mantissa_bits - 2 and the
597 bit at mantissa_bits - 1 should be set. */
599 abort (); /* Ooops. */
601 if (flonum.sign == '+')
602 sfract = smant - sone; /* smant - 1.0. */
605 /* This seems to work. */
613 sfract = -smant & (sone-1); /* 2.0 - smant. */
615 sfract |= sone; /* Insert sign bit. */
618 if (abs (exponent) >= (1 << (exponent_bits - 1)))
619 as_bad ("Cannot represent exponent in %d bits", exponent_bits);
621 /* Force exponent to fit in desired field width. */
622 exponent &= (1 << (exponent_bits)) - 1;
624 if (precision == E_PRECISION)
626 /* Map the float part first (100% equal format as F_PRECISION) */
627 words[0] = exponent << (mantissa_bits+1-24);
628 words[0] |= sfract >> 24;
629 words[1] = sfract >> 8;
631 /* Map the mantissa in the next */
632 words[2] = sfract >> 16;
633 words[3] = sfract & 0xffff;
637 /* Insert the exponent data into the word */
638 sfract |= exponent << (mantissa_bits+1);
640 if (precision == S_PRECISION)
644 words[0] = sfract >> 16;
645 words[1] = sfract & 0xffff;
652 /* Returns pointer past text consumed. */
654 tic4x_atof (str, what_kind, words)
657 LITTLENUM_TYPE *words;
659 /* Extra bits for zeroed low-order bits. The 1st MAX_PRECISION are
660 zeroed, the last contain flonum bits. */
661 static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
663 /* Number of 16-bit words in the format. */
665 FLONUM_TYPE save_gen_flonum;
667 /* We have to save the generic_floating_point_number because it
668 contains storage allocation about the array of LITTLENUMs where
669 the value is actually stored. We will allocate our own array of
670 littlenums below, but have to restore the global one on exit. */
671 save_gen_flonum = generic_floating_point_number;
674 generic_floating_point_number.low = bits + MAX_PRECISION;
675 generic_floating_point_number.high = NULL;
676 generic_floating_point_number.leader = NULL;
677 generic_floating_point_number.exponent = 0;
678 generic_floating_point_number.sign = '\0';
680 /* Use more LittleNums than seems necessary: the highest flonum may
681 have 15 leading 0 bits, so could be useless. */
683 memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
689 precision = S_PRECISION;
696 precision = F_PRECISION;
701 precision = E_PRECISION;
705 as_bad ("Invalid floating point number");
709 generic_floating_point_number.high
710 = generic_floating_point_number.low + precision - 1 + GUARD;
712 if (atof_generic (&return_value, ".", EXP_CHARS,
713 &generic_floating_point_number))
715 as_bad ("Invalid floating point number");
719 tic4x_gen_to_words (generic_floating_point_number,
722 /* Restore the generic_floating_point_number's storage alloc (and
724 generic_floating_point_number = save_gen_flonum;
730 tic4x_insert_reg (regname, regnum)
737 symbol_table_insert (symbol_new (regname, reg_section, (valueT) regnum,
738 &zero_address_frag));
739 for (i = 0; regname[i]; i++)
740 buf[i] = islower (regname[i]) ? toupper (regname[i]) : regname[i];
743 symbol_table_insert (symbol_new (buf, reg_section, (valueT) regnum,
744 &zero_address_frag));
748 tic4x_insert_sym (symname, value)
754 symbolP = symbol_new (symname, absolute_section,
755 (valueT) value, &zero_address_frag);
756 SF_SET_LOCAL (symbolP);
757 symbol_table_insert (symbolP);
761 tic4x_expression (str, exp)
768 t = input_line_pointer; /* Save line pointer. */
769 input_line_pointer = str;
771 s = input_line_pointer;
772 input_line_pointer = t; /* Restore line pointer. */
773 return s; /* Return pointer to where parsing stopped. */
777 tic4x_expression_abs (str, value)
784 t = input_line_pointer; /* Save line pointer. */
785 input_line_pointer = str;
786 *value = get_absolute_expression ();
787 s = input_line_pointer;
788 input_line_pointer = t; /* Restore line pointer. */
793 tic4x_emit_char (c,b)
799 exp.X_op = O_constant;
800 exp.X_add_number = c;
805 tic4x_seg_alloc (name, seg, size, symbolP)
806 char *name ATTRIBUTE_UNUSED;
807 segT seg ATTRIBUTE_UNUSED;
811 /* Note that the size is in words
812 so we multiply it by 4 to get the number of bytes to allocate. */
814 /* If we have symbol: .usect ".fred", size etc.,
815 the symbol needs to point to the first location reserved
822 p = frag_var (rs_fill, 1, 1, (relax_substateT) 0,
824 size * OCTETS_PER_BYTE, (char *) 0);
829 /* .asg ["]character-string["], symbol */
832 int x ATTRIBUTE_UNUSED;
840 str = input_line_pointer;
842 /* Skip string expression. */
843 while (*input_line_pointer != ',' && *input_line_pointer)
844 input_line_pointer++;
845 if (*input_line_pointer != ',')
847 as_bad ("Comma expected\n");
850 *input_line_pointer++ = '\0';
851 name = input_line_pointer;
852 c = get_symbol_end (); /* Get terminator. */
853 tmp = xmalloc (strlen (str) + 1);
856 tmp = xmalloc (strlen (name) + 1);
859 if (hash_find (tic4x_asg_hash, name))
860 hash_replace (tic4x_asg_hash, name, (PTR) str);
862 hash_insert (tic4x_asg_hash, name, (PTR) str);
863 *input_line_pointer = c;
864 demand_empty_rest_of_line ();
867 /* .bss symbol, size */
870 int x ATTRIBUTE_UNUSED;
877 subsegT current_subseg;
880 current_seg = now_seg; /* Save current seg. */
881 current_subseg = now_subseg; /* Save current subseg. */
884 name = input_line_pointer;
885 c = get_symbol_end (); /* Get terminator. */
888 as_bad (".bss size argument missing\n");
893 tic4x_expression_abs (++input_line_pointer, &size);
896 as_bad (".bss size %d < 0!", size);
899 subseg_set (bss_section, 0);
900 symbolP = symbol_find_or_make (name);
902 if (S_GET_SEGMENT (symbolP) == bss_section)
903 symbol_get_frag (symbolP)->fr_symbol = 0;
905 symbol_set_frag (symbolP, frag_now);
907 p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
908 size * OCTETS_PER_BYTE, (char *) 0);
909 *p = 0; /* Fill char. */
911 S_SET_SEGMENT (symbolP, bss_section);
913 /* The symbol may already have been created with a preceding
914 ".globl" directive -- be careful not to step on storage class
915 in that case. Otherwise, set it to static. */
916 if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
917 S_SET_STORAGE_CLASS (symbolP, C_STAT);
919 subseg_set (current_seg, current_subseg); /* Restore current seg. */
920 demand_empty_rest_of_line ();
925 int ignore ATTRIBUTE_UNUSED;
933 name = input_line_pointer;
934 c = get_symbol_end ();
935 symbolP = symbol_find_or_make (name);
936 *input_line_pointer = c;
938 S_SET_STORAGE_CLASS (symbolP, C_EXT);
941 input_line_pointer++;
943 if (*input_line_pointer == '\n')
949 demand_empty_rest_of_line ();
952 /* Handle .byte, .word. .int, .long */
957 register unsigned int c;
961 if (*input_line_pointer == '"')
963 input_line_pointer++;
964 while (is_a_char (c = next_char_of_string ()))
965 tic4x_emit_char (c, 4);
966 know (input_line_pointer[-1] == '\"');
972 input_line_pointer = tic4x_expression (input_line_pointer, &exp);
973 if (exp.X_op == O_constant)
978 exp.X_add_number &= 255;
981 exp.X_add_number &= 65535;
985 /* Perhaps we should disallow .byte and .hword with
986 a non constant expression that will require relocation. */
990 while (*input_line_pointer++ == ',');
992 input_line_pointer--; /* Put terminator back into stream. */
993 demand_empty_rest_of_line ();
996 /* Handle .ascii, .asciz, .string */
998 tic4x_stringer (append_zero)
999 int append_zero; /*ex: bytes */
1002 register unsigned int c;
1008 if (*input_line_pointer == '"')
1010 input_line_pointer++;
1011 while (is_a_char (c = next_char_of_string ()))
1013 tic4x_emit_char (c, 1);
1019 tic4x_emit_char (c, 1);
1023 know (input_line_pointer[-1] == '\"');
1029 input_line_pointer = tic4x_expression (input_line_pointer, &exp);
1030 if (exp.X_op != O_constant)
1032 as_bad("Non-constant symbols not allowed\n");
1035 exp.X_add_number &= 255; /* Limit numeber to 8-bit */
1036 emit_expr (&exp, 1);
1040 while (*input_line_pointer++ == ',');
1042 /* Fill out the rest of the expression with 0's to fill up a full word */
1044 tic4x_emit_char (0, 4-(bytes&0x3));
1046 input_line_pointer--; /* Put terminator back into stream. */
1047 demand_empty_rest_of_line ();
1050 /* .eval expression, symbol */
1053 int x ATTRIBUTE_UNUSED;
1060 input_line_pointer =
1061 tic4x_expression_abs (input_line_pointer, &value);
1062 if (*input_line_pointer++ != ',')
1064 as_bad ("Symbol missing\n");
1067 name = input_line_pointer;
1068 c = get_symbol_end (); /* Get terminator. */
1069 demand_empty_rest_of_line ();
1070 tic4x_insert_sym (name, value);
1073 /* Reset local labels. */
1076 int x ATTRIBUTE_UNUSED;
1078 dollar_label_clear ();
1081 /* .sect "section-name" [, value] */
1082 /* .sect ["]section-name[:subsection-name]["] [, value] */
1085 int x ATTRIBUTE_UNUSED;
1089 char *subsection_name;
1095 if (*input_line_pointer == '"')
1096 input_line_pointer++;
1097 section_name = input_line_pointer;
1098 c = get_symbol_end (); /* Get terminator. */
1099 input_line_pointer++; /* Skip null symbol terminator. */
1100 name = xmalloc (input_line_pointer - section_name + 1);
1101 strcpy (name, section_name);
1103 /* TI C from version 5.0 allows a section name to contain a
1104 subsection name as well. The subsection name is separated by a
1105 ':' from the section name. Currently we scan the subsection
1106 name and discard it.
1110 subsection_name = input_line_pointer;
1111 c = get_symbol_end (); /* Get terminator. */
1112 input_line_pointer++; /* Skip null symbol terminator. */
1113 as_warn (".sect: subsection name ignored");
1116 /* We might still have a '"' to discard, but the character after a
1117 symbol name will be overwritten with a \0 by get_symbol_end()
1121 input_line_pointer =
1122 tic4x_expression_abs (input_line_pointer, &num);
1123 else if (*input_line_pointer == ',')
1125 input_line_pointer =
1126 tic4x_expression_abs (++input_line_pointer, &num);
1131 seg = subseg_new (name, num);
1132 if (line_label != NULL)
1134 S_SET_SEGMENT (line_label, seg);
1135 symbol_set_frag (line_label, frag_now);
1138 if (bfd_get_section_flags (stdoutput, seg) == SEC_NO_FLAGS)
1140 if (!bfd_set_section_flags (stdoutput, seg, SEC_DATA))
1141 as_warn ("Error setting flags for \"%s\": %s", name,
1142 bfd_errmsg (bfd_get_error ()));
1145 /* If the last character overwritten by get_symbol_end() was an
1146 end-of-line, we must restore it or the end of the line will not be
1147 recognised and scanning extends into the next line, stopping with
1149 if this is not true). */
1150 if (is_end_of_line[(unsigned char) c])
1151 *(--input_line_pointer) = c;
1153 demand_empty_rest_of_line ();
1156 /* symbol[:] .set value or .set symbol, value */
1159 int x ATTRIBUTE_UNUSED;
1164 if ((symbolP = line_label) == NULL)
1169 name = input_line_pointer;
1170 c = get_symbol_end (); /* Get terminator. */
1173 as_bad (".set syntax invalid\n");
1174 ignore_rest_of_line ();
1177 symbolP = symbol_find_or_make (name);
1180 symbol_table_insert (symbolP);
1182 pseudo_set (symbolP);
1183 demand_empty_rest_of_line ();
1186 /* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
1189 int x ATTRIBUTE_UNUSED;
1195 int size, alignment_flag;
1197 subsegT current_subseg;
1199 current_seg = now_seg; /* save current seg. */
1200 current_subseg = now_subseg; /* save current subseg. */
1203 if (*input_line_pointer == '"')
1204 input_line_pointer++;
1205 section_name = input_line_pointer;
1206 c = get_symbol_end (); /* Get terminator. */
1207 input_line_pointer++; /* Skip null symbol terminator. */
1208 name = xmalloc (input_line_pointer - section_name + 1);
1209 strcpy (name, section_name);
1212 input_line_pointer =
1213 tic4x_expression_abs (input_line_pointer, &size);
1214 else if (*input_line_pointer == ',')
1216 input_line_pointer =
1217 tic4x_expression_abs (++input_line_pointer, &size);
1222 /* Read a possibly present third argument (alignment flag) [VK]. */
1223 if (*input_line_pointer == ',')
1225 input_line_pointer =
1226 tic4x_expression_abs (++input_line_pointer, &alignment_flag);
1231 as_warn (".usect: non-zero alignment flag ignored");
1233 seg = subseg_new (name, 0);
1234 if (line_label != NULL)
1236 S_SET_SEGMENT (line_label, seg);
1237 symbol_set_frag (line_label, frag_now);
1238 S_SET_VALUE (line_label, frag_now_fix ());
1240 seg_info (seg)->bss = 1; /* Uninitialised data. */
1241 if (!bfd_set_section_flags (stdoutput, seg, SEC_ALLOC))
1242 as_warn ("Error setting flags for \"%s\": %s", name,
1243 bfd_errmsg (bfd_get_error ()));
1244 tic4x_seg_alloc (name, seg, size, line_label);
1246 if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
1247 S_SET_STORAGE_CLASS (line_label, C_STAT);
1249 subseg_set (current_seg, current_subseg); /* Restore current seg. */
1250 demand_empty_rest_of_line ();
1253 /* .version cpu-version. */
1256 int x ATTRIBUTE_UNUSED;
1260 input_line_pointer =
1261 tic4x_expression_abs (input_line_pointer, &temp);
1262 if (!IS_CPU_TIC3X (temp) && !IS_CPU_TIC4X (temp))
1263 as_bad ("This assembler does not support processor generation %d",
1266 if (tic4x_cpu && temp != tic4x_cpu)
1267 as_warn ("Changing processor generation on fly not supported...");
1269 demand_empty_rest_of_line ();
1273 tic4x_init_regtable ()
1277 for (i = 0; i < tic3x_num_registers; i++)
1278 tic4x_insert_reg (tic3x_registers[i].name,
1279 tic3x_registers[i].regno);
1281 if (IS_CPU_TIC4X (tic4x_cpu))
1283 /* Add additional Tic4x registers, overriding some C3x ones. */
1284 for (i = 0; i < tic4x_num_registers; i++)
1285 tic4x_insert_reg (tic4x_registers[i].name,
1286 tic4x_registers[i].regno);
1291 tic4x_init_symbols ()
1293 /* The TI tools accept case insensitive versions of these symbols,
1298 .TMS320xx 30,31,32,40,or 44 set according to -v flag
1299 .C3X or .C3x 1 or 0 1 if -v30,-v31,or -v32
1300 .C30 1 or 0 1 if -v30
1301 .C31 1 or 0 1 if -v31
1302 .C32 1 or 0 1 if -v32
1303 .C4X or .C4x 1 or 0 1 if -v40, or -v44
1304 .C40 1 or 0 1 if -v40
1305 .C44 1 or 0 1 if -v44
1307 .REGPARM 1 or 0 1 if -mr option used
1308 .BIGMODEL 1 or 0 1 if -mb option used
1310 These symbols are currently supported but will be removed in a
1312 .TMS320C30 1 or 0 1 if -v30,-v31,or -v32
1313 .TMS320C31 1 or 0 1 if -v31
1314 .TMS320C32 1 or 0 1 if -v32
1315 .TMS320C40 1 or 0 1 if -v40, or -v44
1316 .TMS320C44 1 or 0 1 if -v44
1318 Source: TI: TMS320C3x/C4x Assembly Language Tools User's Guide,
1319 1997, SPRU035C, p. 3-17/3-18. */
1320 tic4x_insert_sym (".REGPARM", tic4x_reg_args);
1321 tic4x_insert_sym (".MEMPARM", !tic4x_reg_args);
1322 tic4x_insert_sym (".BIGMODEL", tic4x_big_model);
1323 tic4x_insert_sym (".C30INTERRUPT", 0);
1324 tic4x_insert_sym (".TMS320xx", tic4x_cpu == 0 ? 40 : tic4x_cpu);
1325 tic4x_insert_sym (".C3X", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1326 tic4x_insert_sym (".C3x", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1327 tic4x_insert_sym (".C4X", tic4x_cpu == 0 || tic4x_cpu == 40 || tic4x_cpu == 44);
1328 tic4x_insert_sym (".C4x", tic4x_cpu == 0 || tic4x_cpu == 40 || tic4x_cpu == 44);
1329 /* Do we need to have the following symbols also in lower case? */
1330 tic4x_insert_sym (".TMS320C30", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1331 tic4x_insert_sym (".tms320C30", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1332 tic4x_insert_sym (".TMS320C31", tic4x_cpu == 31);
1333 tic4x_insert_sym (".tms320C31", tic4x_cpu == 31);
1334 tic4x_insert_sym (".TMS320C32", tic4x_cpu == 32);
1335 tic4x_insert_sym (".tms320C32", tic4x_cpu == 32);
1336 tic4x_insert_sym (".TMS320C33", tic4x_cpu == 33);
1337 tic4x_insert_sym (".tms320C33", tic4x_cpu == 33);
1338 tic4x_insert_sym (".TMS320C40", tic4x_cpu == 40 || tic4x_cpu == 44 || tic4x_cpu == 0);
1339 tic4x_insert_sym (".tms320C40", tic4x_cpu == 40 || tic4x_cpu == 44 || tic4x_cpu == 0);
1340 tic4x_insert_sym (".TMS320C44", tic4x_cpu == 44);
1341 tic4x_insert_sym (".tms320C44", tic4x_cpu == 44);
1342 tic4x_insert_sym (".TMX320C40", 0); /* C40 first pass silicon ? */
1343 tic4x_insert_sym (".tmx320C40", 0);
1346 /* Insert a new instruction template into hash table. */
1348 tic4x_inst_insert (inst)
1351 static char prev_name[16];
1352 const char *retval = NULL;
1354 /* Only insert the first name if have several similar entries. */
1355 if (!strcmp (inst->name, prev_name) || inst->name[0] == '\0')
1358 retval = hash_insert (tic4x_op_hash, inst->name, (PTR) inst);
1360 fprintf (stderr, "internal error: can't hash `%s': %s\n",
1361 inst->name, retval);
1363 strcpy (prev_name, inst->name);
1364 return retval == NULL;
1367 /* Make a new instruction template. */
1368 static tic4x_inst_t *
1369 tic4x_inst_make (name, opcode, args)
1371 unsigned long opcode;
1374 static tic4x_inst_t *insts = NULL;
1375 static char *names = NULL;
1376 static int index = 0;
1380 /* Allocate memory to store name strings. */
1381 names = (char *) xmalloc (sizeof (char) * 8192);
1382 /* Allocate memory for additional insts. */
1383 insts = (tic4x_inst_t *)
1384 xmalloc (sizeof (tic4x_inst_t) * 1024);
1386 insts[index].name = names;
1387 insts[index].opcode = opcode;
1388 insts[index].opmask = 0xffffffff;
1389 insts[index].args = args;
1397 return &insts[index - 1];
1400 /* Add instruction template, creating dynamic templates as required. */
1402 tic4x_inst_add (insts)
1403 tic4x_inst_t *insts;
1405 char *s = insts->name;
1413 /* We do not care about INSNs that is not a part of our
1415 if (!insts->oplevel & tic4x_oplevel)
1424 /* Dynamically create all the conditional insts. */
1425 for (i = 0; i < tic4x_num_conds; i++)
1429 char *c = tic4x_conds[i].name;
1439 /* If instruction found then have already processed it. */
1440 if (hash_find (tic4x_op_hash, name))
1445 inst = tic4x_inst_make (name, insts[k].opcode +
1446 (tic4x_conds[i].cond <<
1447 (*s == 'B' ? 16 : 23)),
1449 if (k == 0) /* Save strcmp() with following func. */
1450 ok &= tic4x_inst_insert (inst);
1453 while (!strcmp (insts->name,
1460 return tic4x_inst_insert (insts);
1470 /* This function is called once, at assembler startup time. It should
1471 set up all the tables, etc., that the MD part of the assembler will
1479 /* Setup the proper opcode level according to the
1480 commandline parameters */
1481 tic4x_oplevel = OP_C3X;
1483 if ( IS_CPU_TIC4X(tic4x_cpu) )
1484 tic4x_oplevel |= OP_C4X;
1486 if ( ( tic4x_cpu == 31 && tic4x_revision >= 6)
1487 || (tic4x_cpu == 32 && tic4x_revision >= 2)
1488 || (tic4x_cpu == 33)
1490 tic4x_oplevel |= OP_ENH;
1492 if ( ( tic4x_cpu == 30 && tic4x_revision >= 7)
1493 || (tic4x_cpu == 31 && tic4x_revision >= 5)
1494 || (tic4x_cpu == 32)
1496 tic4x_oplevel |= OP_LPWR;
1498 if ( ( tic4x_cpu == 30 && tic4x_revision >= 7)
1499 || (tic4x_cpu == 31 && tic4x_revision >= 5)
1500 || (tic4x_cpu == 32)
1501 || (tic4x_cpu == 33)
1502 || (tic4x_cpu == 40 && tic4x_revision >= 5)
1503 || (tic4x_cpu == 44)
1505 tic4x_oplevel |= OP_IDLE2;
1507 /* Create hash table for mnemonics. */
1508 tic4x_op_hash = hash_new ();
1510 /* Create hash table for asg pseudo. */
1511 tic4x_asg_hash = hash_new ();
1513 /* Add mnemonics to hash table, expanding conditional mnemonics on fly. */
1514 for (i = 0; i < tic4x_num_insts; i++)
1515 ok &= tic4x_inst_add ((void *) &tic4x_insts[i]);
1517 /* Create dummy inst to avoid errors accessing end of table. */
1518 tic4x_inst_make ("", 0, "");
1521 as_fatal ("Broken assembler. No assembly attempted.");
1523 /* Add registers to symbol table. */
1524 tic4x_init_regtable ();
1526 /* Add predefined symbols to symbol table. */
1527 tic4x_init_symbols ();
1533 bfd_set_arch_mach (stdoutput, bfd_arch_tic4x,
1534 IS_CPU_TIC4X (tic4x_cpu) ? bfd_mach_tic4x : bfd_mach_tic3x);
1538 tic4x_indirect_parse (operand, indirect)
1539 tic4x_operand_t *operand;
1540 const tic4x_indirect_t *indirect;
1542 char *n = indirect->name;
1543 char *s = input_line_pointer;
1553 case 'a': /* Need to match aux register. */
1555 #ifdef TIC4X_ALT_SYNTAX
1559 while (isalnum (*s))
1562 if (!(symbolP = symbol_find (name)))
1565 if (S_GET_SEGMENT (symbolP) != reg_section)
1568 operand->aregno = S_GET_VALUE (symbolP);
1569 if (operand->aregno >= REG_AR0 && operand->aregno <= REG_AR7)
1572 as_bad ("Auxiliary register AR0--AR7 required for indirect");
1575 case 'd': /* Need to match constant for disp. */
1576 #ifdef TIC4X_ALT_SYNTAX
1577 if (*s == '%') /* expr() will die if we don't skip this. */
1580 s = tic4x_expression (s, &operand->expr);
1581 if (operand->expr.X_op != O_constant)
1583 operand->disp = operand->expr.X_add_number;
1584 if (operand->disp < 0 || operand->disp > 255)
1586 as_bad ("Bad displacement %d (require 0--255)\n",
1592 case 'y': /* Need to match IR0. */
1593 case 'z': /* Need to match IR1. */
1594 #ifdef TIC4X_ALT_SYNTAX
1598 s = tic4x_expression (s, &operand->expr);
1599 if (operand->expr.X_op != O_register)
1601 if (operand->expr.X_add_number != REG_IR0
1602 && operand->expr.X_add_number != REG_IR1)
1604 as_bad ("Index register IR0,IR1 required for displacement");
1608 if (*n == 'y' && operand->expr.X_add_number == REG_IR0)
1610 if (*n == 'z' && operand->expr.X_add_number == REG_IR1)
1615 if (*s != '(') /* No displacement, assume to be 1. */
1626 if (tolower (*s) != *n)
1631 if (*s != ' ' && *s != ',' && *s != '\0')
1633 input_line_pointer = s;
1638 tic4x_operand_parse (s, operand)
1640 tic4x_operand_t *operand;
1645 expressionS *exp = &operand->expr;
1646 char *save = input_line_pointer;
1649 struct hash_entry *entry = NULL;
1651 input_line_pointer = s;
1654 str = input_line_pointer;
1655 c = get_symbol_end (); /* Get terminator. */
1656 new = input_line_pointer;
1657 if (strlen (str) && (entry = hash_find (tic4x_asg_hash, str)) != NULL)
1659 *input_line_pointer = c;
1660 input_line_pointer = (char *) entry;
1664 *input_line_pointer = c;
1665 input_line_pointer = str;
1668 operand->mode = M_UNKNOWN;
1669 switch (*input_line_pointer)
1671 #ifdef TIC4X_ALT_SYNTAX
1673 input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1674 if (exp->X_op != O_register)
1675 as_bad ("Expecting a register name");
1676 operand->mode = M_REGISTER;
1680 /* Denotes high 16 bits. */
1681 input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1682 if (exp->X_op == O_constant)
1683 operand->mode = M_IMMED;
1684 else if (exp->X_op == O_big)
1686 if (exp->X_add_number)
1687 as_bad ("Number too large"); /* bignum required */
1690 tic4x_gen_to_words (generic_floating_point_number,
1691 operand->fwords, S_PRECISION);
1692 operand->mode = M_IMMED_F;
1695 /* Allow ori ^foo, ar0 to be equivalent to ldi .hi.foo, ar0 */
1696 /* WARNING : The TI C40 assembler cannot do this. */
1697 else if (exp->X_op == O_symbol)
1699 operand->mode = M_HI;
1704 input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1705 if (exp->X_op == O_constant)
1706 operand->mode = M_IMMED;
1707 else if (exp->X_op == O_big)
1709 if (exp->X_add_number > 0)
1710 as_bad ("Number too large"); /* bignum required. */
1713 tic4x_gen_to_words (generic_floating_point_number,
1714 operand->fwords, S_PRECISION);
1715 operand->mode = M_IMMED_F;
1718 /* Allow ori foo, ar0 to be equivalent to ldi .lo.foo, ar0 */
1719 /* WARNING : The TI C40 assembler cannot do this. */
1720 else if (exp->X_op == O_symbol)
1722 operand->mode = M_IMMED;
1727 as_bad ("Expecting a constant value");
1732 input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1733 if (exp->X_op != O_constant && exp->X_op != O_symbol)
1734 as_bad ("Bad direct addressing construct %s", s);
1735 if (exp->X_op == O_constant)
1737 if (exp->X_add_number < 0)
1738 as_bad ("Direct value of %ld is not suitable",
1739 (long) exp->X_add_number);
1741 operand->mode = M_DIRECT;
1746 for (i = 0; i < tic4x_num_indirects; i++)
1747 if ((ret = tic4x_indirect_parse (operand, &tic4x_indirects[i])))
1751 if (i < tic4x_num_indirects)
1753 operand->mode = M_INDIRECT;
1754 /* Indirect addressing mode number. */
1755 operand->expr.X_add_number = tic4x_indirects[i].modn;
1756 /* Convert *+ARn(0) to *ARn etc. Maybe we should
1757 squeal about silly ones? */
1758 if (operand->expr.X_add_number < 0x08 && !operand->disp)
1759 operand->expr.X_add_number = 0x18;
1762 as_bad ("Unknown indirect addressing mode");
1766 operand->mode = M_IMMED; /* Assume immediate. */
1767 str = input_line_pointer;
1768 input_line_pointer = tic4x_expression (input_line_pointer, exp);
1769 if (exp->X_op == O_register)
1771 know (exp->X_add_symbol == 0);
1772 know (exp->X_op_symbol == 0);
1773 operand->mode = M_REGISTER;
1776 else if (exp->X_op == O_big)
1778 if (exp->X_add_number > 0)
1779 as_bad ("Number too large"); /* bignum required. */
1782 tic4x_gen_to_words (generic_floating_point_number,
1783 operand->fwords, S_PRECISION);
1784 operand->mode = M_IMMED_F;
1788 #ifdef TIC4X_ALT_SYNTAX
1789 /* Allow ldi foo, ar0 to be equivalent to ldi @foo, ar0. */
1790 else if (exp->X_op == O_symbol)
1792 operand->mode = M_DIRECT;
1798 new = input_line_pointer;
1799 input_line_pointer = save;
1804 tic4x_operands_match (inst, insn, check)
1809 const char *args = inst->args;
1810 unsigned long opcode = inst->opcode;
1811 int num_operands = insn->num_operands;
1812 tic4x_operand_t *operand = insn->operands;
1813 expressionS *exp = &operand->expr;
1817 /* Build the opcode, checking as we go to make sure that the
1820 If an operand matches, we modify insn or opcode appropriately,
1821 and do a "continue". If an operand fails to match, we "break". */
1823 insn->nchars = 4; /* Instructions always 4 bytes. */
1824 insn->reloc = NO_RELOC;
1829 insn->opcode = opcode;
1830 return num_operands == 0;
1838 case '\0': /* End of args. */
1839 if (num_operands == 1)
1841 insn->opcode = opcode;
1844 break; /* Too many operands. */
1846 case '#': /* This is only used for ldp. */
1847 if (operand->mode != M_DIRECT && operand->mode != M_IMMED)
1849 /* While this looks like a direct addressing mode, we actually
1850 use an immediate mode form of ldiu or ldpk instruction. */
1851 if (exp->X_op == O_constant)
1853 if( ( IS_CPU_TIC4X (tic4x_cpu) && exp->X_add_number <= 65535 )
1854 || ( IS_CPU_TIC3X (tic4x_cpu) && exp->X_add_number <= 255 ) )
1856 INSERTS (opcode, exp->X_add_number, 15, 0);
1862 as_bad ("Immediate value of %ld is too large for ldf",
1863 (long) exp->X_add_number);
1868 else if (exp->X_op == O_symbol)
1870 insn->reloc = BFD_RELOC_HI16;
1874 break; /* Not direct (dp) addressing. */
1876 case '@': /* direct. */
1877 if (operand->mode != M_DIRECT)
1879 if (exp->X_op == O_constant)
1881 /* Store only the 16 LSBs of the number. */
1882 INSERTS (opcode, exp->X_add_number, 15, 0);
1885 else if (exp->X_op == O_symbol)
1887 insn->reloc = BFD_RELOC_LO16;
1891 break; /* Not direct addressing. */
1894 if (operand->mode != M_REGISTER)
1896 reg = exp->X_add_number;
1897 if (reg >= REG_AR0 && reg <= REG_AR7)
1898 INSERTU (opcode, reg - REG_AR0, 24, 22);
1902 as_bad ("Destination register must be ARn");
1907 case 'B': /* Unsigned integer immediate. */
1908 /* Allow br label or br @label. */
1909 if (operand->mode != M_IMMED && operand->mode != M_DIRECT)
1911 if (exp->X_op == O_constant)
1913 if (exp->X_add_number < (1 << 24))
1915 INSERTU (opcode, exp->X_add_number, 23, 0);
1921 as_bad ("Immediate value of %ld is too large",
1922 (long) exp->X_add_number);
1927 if (IS_CPU_TIC4X (tic4x_cpu))
1929 insn->reloc = BFD_RELOC_24_PCREL;
1934 insn->reloc = BFD_RELOC_24;
1941 if (!IS_CPU_TIC4X (tic4x_cpu))
1943 if (operand->mode != M_INDIRECT)
1945 /* Require either *+ARn(disp) or *ARn. */
1946 if (operand->expr.X_add_number != 0
1947 && operand->expr.X_add_number != 0x18)
1950 as_bad ("Invalid indirect addressing mode");
1954 INSERTU (opcode, operand->aregno - REG_AR0, 2, 0);
1955 INSERTU (opcode, operand->disp, 7, 3);
1959 if (!(operand->mode == M_REGISTER))
1961 INSERTU (opcode, exp->X_add_number, 7, 0);
1965 if (!(operand->mode == M_REGISTER))
1967 reg = exp->X_add_number;
1968 if ( (reg >= REG_R0 && reg <= REG_R7)
1969 || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
1970 INSERTU (opcode, reg, 7, 0);
1974 as_bad ("Register must be Rn");
1980 if (operand->mode != M_IMMED_F
1981 && !(operand->mode == M_IMMED && exp->X_op == O_constant))
1984 if (operand->mode != M_IMMED_F)
1986 /* OK, we 've got something like cmpf 0, r0
1987 Why can't they stick in a bloody decimal point ?! */
1990 /* Create floating point number string. */
1991 sprintf (string, "%d.0", (int) exp->X_add_number);
1992 tic4x_atof (string, 's', operand->fwords);
1995 INSERTU (opcode, operand->fwords[0], 15, 0);
1999 if (operand->mode != M_REGISTER)
2001 INSERTU (opcode, exp->X_add_number, 15, 8);
2005 if (operand->mode != M_REGISTER)
2007 reg = exp->X_add_number;
2008 if ( (reg >= REG_R0 && reg <= REG_R7)
2009 || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
2010 INSERTU (opcode, reg, 15, 8);
2014 as_bad ("Register must be Rn");
2020 if (operand->mode != M_REGISTER)
2022 reg = exp->X_add_number;
2023 if (reg >= REG_R0 && reg <= REG_R7)
2024 INSERTU (opcode, reg - REG_R0, 18, 16);
2028 as_bad ("Register must be R0--R7");
2034 if ( operand->mode == M_REGISTER
2035 && tic4x_oplevel & OP_ENH )
2037 reg = exp->X_add_number;
2038 INSERTU (opcode, reg, 4, 0);
2039 INSERTU (opcode, 7, 7, 5);
2045 if (operand->mode != M_INDIRECT)
2047 if (operand->disp != 0 && operand->disp != 1)
2049 if (IS_CPU_TIC4X (tic4x_cpu))
2052 as_bad ("Invalid indirect addressing mode displacement %d",
2057 INSERTU (opcode, operand->aregno - REG_AR0, 2, 0);
2058 INSERTU (opcode, operand->expr.X_add_number, 7, 3);
2062 if ( operand->mode == M_REGISTER
2063 && tic4x_oplevel & OP_ENH )
2065 reg = exp->X_add_number;
2066 INSERTU (opcode, reg, 12, 8);
2067 INSERTU (opcode, 7, 15, 13);
2073 if (operand->mode != M_INDIRECT)
2075 if (operand->disp != 0 && operand->disp != 1)
2077 if (IS_CPU_TIC4X (tic4x_cpu))
2080 as_bad ("Invalid indirect addressing mode displacement %d",
2085 INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
2086 INSERTU (opcode, operand->expr.X_add_number, 15, 11);
2090 if (operand->mode != M_REGISTER)
2092 reg = exp->X_add_number;
2093 if (reg >= REG_R0 && reg <= REG_R7)
2094 INSERTU (opcode, reg - REG_R0, 21, 19);
2098 as_bad ("Register must be R0--R7");
2104 if (operand->mode != M_REGISTER)
2106 reg = exp->X_add_number;
2107 if (reg >= REG_R0 && reg <= REG_R7)
2108 INSERTU (opcode, reg - REG_R0, 24, 22);
2112 as_bad ("Register must be R0--R7");
2118 if (operand->mode != M_REGISTER)
2120 reg = exp->X_add_number;
2121 if (reg == REG_R2 || reg == REG_R3)
2122 INSERTU (opcode, reg - REG_R2, 22, 22);
2126 as_bad ("Destination register must be R2 or R3");
2132 if (operand->mode != M_REGISTER)
2134 reg = exp->X_add_number;
2135 if (reg == REG_R0 || reg == REG_R1)
2136 INSERTU (opcode, reg - REG_R0, 23, 23);
2140 as_bad ("Destination register must be R0 or R1");
2146 if (!IS_CPU_TIC4X (tic4x_cpu))
2148 if (operand->mode != M_INDIRECT)
2150 /* Require either *+ARn(disp) or *ARn. */
2151 if (operand->expr.X_add_number != 0
2152 && operand->expr.X_add_number != 0x18)
2155 as_bad ("Invalid indirect addressing mode");
2159 INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
2160 INSERTU (opcode, operand->disp, 15, 11);
2163 case 'P': /* PC relative displacement. */
2164 /* Allow br label or br @label. */
2165 if (operand->mode != M_IMMED && operand->mode != M_DIRECT)
2167 if (exp->X_op == O_constant)
2169 if (exp->X_add_number >= -32768 && exp->X_add_number <= 32767)
2171 INSERTS (opcode, exp->X_add_number, 15, 0);
2177 as_bad ("Displacement value of %ld is too large",
2178 (long) exp->X_add_number);
2183 insn->reloc = BFD_RELOC_16_PCREL;
2189 if (operand->mode != M_REGISTER)
2191 reg = exp->X_add_number;
2192 INSERTU (opcode, reg, 15, 0);
2196 if (operand->mode != M_REGISTER)
2198 reg = exp->X_add_number;
2199 if ( (reg >= REG_R0 && reg <= REG_R7)
2200 || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
2201 INSERTU (opcode, reg, 15, 0);
2205 as_bad ("Register must be Rn");
2211 if (operand->mode != M_REGISTER)
2213 reg = exp->X_add_number;
2214 INSERTU (opcode, reg, 20, 16);
2218 if (operand->mode != M_REGISTER)
2220 reg = exp->X_add_number;
2221 if ( (reg >= REG_R0 && reg <= REG_R7)
2222 || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
2223 INSERTU (opcode, reg, 20, 16);
2227 as_bad ("Register must be Rn");
2232 case 'S': /* Short immediate int. */
2233 if (operand->mode != M_IMMED && operand->mode != M_HI)
2235 if (exp->X_op == O_big)
2238 as_bad ("Floating point number not valid in expression");
2242 if (exp->X_op == O_constant)
2244 if (exp->X_add_number >= -32768 && exp->X_add_number <= 65535)
2246 INSERTS (opcode, exp->X_add_number, 15, 0);
2252 as_bad ("Signed immediate value %ld too large",
2253 (long) exp->X_add_number);
2258 else if (exp->X_op == O_symbol)
2260 if (operand->mode == M_HI)
2262 insn->reloc = BFD_RELOC_HI16;
2266 insn->reloc = BFD_RELOC_LO16;
2271 /* Handle cases like ldi foo - $, ar0 where foo
2272 is a forward reference. Perhaps we should check
2273 for X_op == O_symbol and disallow things like
2275 insn->reloc = BFD_RELOC_16;
2279 case 'T': /* 5-bit immediate value for tic4x stik. */
2280 if (!IS_CPU_TIC4X (tic4x_cpu))
2282 if (operand->mode != M_IMMED)
2284 if (exp->X_op == O_constant)
2286 if (exp->X_add_number < 16 && exp->X_add_number >= -16)
2288 INSERTS (opcode, exp->X_add_number, 20, 16);
2294 as_bad ("Immediate value of %ld is too large",
2295 (long) exp->X_add_number);
2300 break; /* No relocations allowed. */
2302 case 'U': /* Unsigned integer immediate. */
2303 if (operand->mode != M_IMMED && operand->mode != M_HI)
2305 if (exp->X_op == O_constant)
2307 if (exp->X_add_number < (1 << 16) && exp->X_add_number >= 0)
2309 INSERTU (opcode, exp->X_add_number, 15, 0);
2315 as_bad ("Unsigned immediate value %ld too large",
2316 (long) exp->X_add_number);
2321 else if (exp->X_op == O_symbol)
2323 if (operand->mode == M_HI)
2324 insn->reloc = BFD_RELOC_HI16;
2326 insn->reloc = BFD_RELOC_LO16;
2331 insn->reloc = BFD_RELOC_16;
2335 case 'V': /* Trap numbers (immediate field). */
2336 if (operand->mode != M_IMMED)
2338 if (exp->X_op == O_constant)
2340 if (exp->X_add_number < 512 && IS_CPU_TIC4X (tic4x_cpu))
2342 INSERTU (opcode, exp->X_add_number, 8, 0);
2345 else if (exp->X_add_number < 32 && IS_CPU_TIC3X (tic4x_cpu))
2347 INSERTU (opcode, exp->X_add_number | 0x20, 4, 0);
2353 as_bad ("Immediate value of %ld is too large",
2354 (long) exp->X_add_number);
2359 break; /* No relocations allowed. */
2361 case 'W': /* Short immediate int (0--7). */
2362 if (!IS_CPU_TIC4X (tic4x_cpu))
2364 if (operand->mode != M_IMMED)
2366 if (exp->X_op == O_big)
2369 as_bad ("Floating point number not valid in expression");
2373 if (exp->X_op == O_constant)
2375 if (exp->X_add_number >= -256 && exp->X_add_number <= 127)
2377 INSERTS (opcode, exp->X_add_number, 7, 0);
2383 as_bad ("Immediate value %ld too large",
2384 (long) exp->X_add_number);
2389 insn->reloc = BFD_RELOC_16;
2393 case 'X': /* Expansion register for tic4x. */
2394 if (operand->mode != M_REGISTER)
2396 reg = exp->X_add_number;
2397 if (reg >= REG_IVTP && reg <= REG_TVTP)
2398 INSERTU (opcode, reg - REG_IVTP, 4, 0);
2402 as_bad ("Register must be ivtp or tvtp");
2407 case 'Y': /* Address register for tic4x lda. */
2408 if (operand->mode != M_REGISTER)
2410 reg = exp->X_add_number;
2411 if (reg >= REG_AR0 && reg <= REG_SP)
2412 INSERTU (opcode, reg, 20, 16);
2416 as_bad ("Register must be address register");
2421 case 'Z': /* Expansion register for tic4x. */
2422 if (operand->mode != M_REGISTER)
2424 reg = exp->X_add_number;
2425 if (reg >= REG_IVTP && reg <= REG_TVTP)
2426 INSERTU (opcode, reg - REG_IVTP, 20, 16);
2430 as_bad ("Register must be ivtp or tvtp");
2436 if (operand->mode != M_INDIRECT)
2438 INSERTS (opcode, operand->disp, 7, 0);
2439 INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
2440 INSERTU (opcode, operand->expr.X_add_number, 15, 11);
2443 case '|': /* treat as `,' if have ldi_ldi form. */
2446 if (--num_operands < 0)
2447 break; /* Too few operands. */
2449 if (operand->mode != M_PARALLEL)
2454 case ',': /* Another operand. */
2455 if (--num_operands < 0)
2456 break; /* Too few operands. */
2458 exp = &operand->expr;
2461 case ';': /* Another optional operand. */
2462 if (num_operands == 1 || operand[1].mode == M_PARALLEL)
2464 if (--num_operands < 0)
2465 break; /* Too few operands. */
2467 exp = &operand->expr;
2478 tic4x_insn_check (insn)
2482 if (!strcmp(insn->name, "lda"))
2484 if (insn->num_operands < 2 || insn->num_operands > 2)
2485 as_fatal ("Illegal internal LDA insn definition");
2487 if ( insn->operands[0].mode == M_REGISTER
2488 && insn->operands[1].mode == M_REGISTER
2489 && insn->operands[0].expr.X_add_number == insn->operands[1].expr.X_add_number )
2490 as_bad ("Source and destination register should not be equal");
2492 else if( !strcmp(insn->name, "ldi_ldi")
2493 || !strcmp(insn->name, "ldi1_ldi2")
2494 || !strcmp(insn->name, "ldi2_ldi1")
2495 || !strcmp(insn->name, "ldf_ldf")
2496 || !strcmp(insn->name, "ldf1_ldf2")
2497 || !strcmp(insn->name, "ldf2_ldf1") )
2499 if ( insn->num_operands < 4 && insn->num_operands > 5 )
2500 as_fatal ("Illegal internal %s insn definition", insn->name);
2502 if ( insn->operands[1].mode == M_REGISTER
2503 && insn->operands[insn->num_operands-1].mode == M_REGISTER
2504 && insn->operands[1].expr.X_add_number == insn->operands[insn->num_operands-1].expr.X_add_number )
2505 as_warn ("Equal parallell destination registers, one result will be discarded");
2510 tic4x_insn_output (insn)
2515 /* Grab another fragment for opcode. */
2516 dst = frag_more (insn->nchars);
2518 /* Put out opcode word as a series of bytes in little endian order. */
2519 md_number_to_chars (dst, insn->opcode, insn->nchars);
2521 /* Put out the symbol-dependent stuff. */
2522 if (insn->reloc != NO_RELOC)
2524 /* Where is the offset into the fragment for this instruction. */
2525 fix_new_exp (frag_now,
2526 dst - frag_now->fr_literal, /* where */
2527 insn->nchars, /* size */
2534 /* Parse the operands. */
2536 tic4x_operands_parse (s, operands, num_operands)
2538 tic4x_operand_t *operands;
2542 return num_operands;
2545 s = tic4x_operand_parse (s, &operands[num_operands++]);
2546 while (num_operands < TIC4X_OPERANDS_MAX && *s++ == ',');
2548 if (num_operands > TIC4X_OPERANDS_MAX)
2550 as_bad ("Too many operands scanned");
2553 return num_operands;
2556 /* Assemble a single instruction. Its label has already been handled
2557 by the generic front end. We just parse mnemonic and operands, and
2558 produce the bytes of data and relocation. */
2567 tic4x_inst_t *inst; /* Instruction template. */
2568 tic4x_inst_t *first_inst;
2570 /* Scan for parallel operators */
2574 while (*s && *s != '|')
2577 if (*s && s[1]=='|')
2581 as_bad ("Parallel opcode cannot contain more than two instructions");
2587 /* Lets take care of the first part of the parallel insn */
2592 /* .. and let the second run though here */
2596 if (str && insn->parallel)
2598 /* Find mnemonic (second part of parallel instruction). */
2600 /* Skip past instruction mnemonic. */
2601 while (*s && *s != ' ')
2603 if (*s) /* Null terminate for hash_find. */
2604 *s++ = '\0'; /* and skip past null. */
2605 strcat (insn->name, "_");
2606 strncat (insn->name, str, TIC4X_NAME_MAX - strlen (insn->name));
2608 insn->operands[insn->num_operands++].mode = M_PARALLEL;
2610 if ((i = tic4x_operands_parse
2611 (s, insn->operands, insn->num_operands)) < 0)
2617 insn->num_operands = i;
2623 if ((insn->inst = (struct tic4x_inst *)
2624 hash_find (tic4x_op_hash, insn->name)) == NULL)
2626 as_bad ("Unknown opcode `%s'.", insn->name);
2636 ok = tic4x_operands_match (inst, insn, 1);
2643 } while (!ok && !strcmp (inst->name, inst[1].name) && inst++);
2647 tic4x_insn_check (insn);
2648 tic4x_insn_output (insn);
2653 tic4x_operands_match (first_inst, insn, 0);
2654 as_bad ("Invalid operands for %s", insn->name);
2657 as_bad ("Invalid instruction %s", insn->name);
2662 /* Find mnemonic. */
2664 while (*s && *s != ' ') /* Skip past instruction mnemonic. */
2666 if (*s) /* Null terminate for hash_find. */
2667 *s++ = '\0'; /* and skip past null. */
2668 strncpy (insn->name, str, TIC4X_NAME_MAX - 3);
2670 if ((i = tic4x_operands_parse (s, insn->operands, 0)) < 0)
2672 insn->inst = NULL; /* Flag that error occured. */
2677 insn->num_operands = i;
2692 /* Turn a string in input_line_pointer into a floating point constant
2693 of type type, and store the appropriate bytes in *litP. The number
2694 of LITTLENUMS emitted is stored in *sizeP. An error message is
2695 returned, or NULL on OK. */
2698 md_atof (type, litP, sizeP)
2705 LITTLENUM_TYPE words[MAX_LITTLENUMS];
2706 LITTLENUM_TYPE *wordP;
2711 case 's': /* .single */
2717 case 'd': /* .double */
2719 case 'f': /* .float or .single */
2722 prec = 2; /* 1 32-bit word */
2725 case 'i': /* .ieee */
2729 type = 'f'; /* Rewrite type to be usable by atof_ieee() */
2732 case 'e': /* .ldouble */
2734 prec = 4; /* 2 32-bit words */
2740 return "Bad call to md_atof()";
2744 t = atof_ieee (input_line_pointer, type, words);
2746 t = tic4x_atof (input_line_pointer, type, words);
2748 input_line_pointer = t;
2749 *sizeP = prec * sizeof (LITTLENUM_TYPE);
2751 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
2752 little endian byte order. */
2753 /* SES: However it is required to put the words (32-bits) out in the
2754 correct order, hence we write 2 and 2 littlenums in little endian
2755 order, while we keep the original order on successive words. */
2756 for(wordP = words; wordP<(words+prec) ; wordP+=2)
2758 if (wordP<(words+prec-1)) /* Dump wordP[1] (if we have one) */
2760 md_number_to_chars (litP, (valueT) (wordP[1]),
2761 sizeof (LITTLENUM_TYPE));
2762 litP += sizeof (LITTLENUM_TYPE);
2766 md_number_to_chars (litP, (valueT) (wordP[0]),
2767 sizeof (LITTLENUM_TYPE));
2768 litP += sizeof (LITTLENUM_TYPE);
2774 md_apply_fix3 (fixP, value, seg)
2777 segT seg ATTRIBUTE_UNUSED;
2779 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
2780 valueT val = *value;
2782 switch (fixP->fx_r_type)
2784 case BFD_RELOC_HI16:
2788 case BFD_RELOC_LO16:
2795 switch (fixP->fx_r_type)
2800 case BFD_RELOC_24_PCREL:
2803 case BFD_RELOC_16_PCREL:
2804 case BFD_RELOC_LO16:
2805 case BFD_RELOC_HI16:
2812 as_bad ("Bad relocation type: 0x%02x", fixP->fx_r_type);
2816 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) fixP->fx_done = 1;
2819 /* Should never be called for tic4x. */
2821 md_convert_frag (headers, sec, fragP)
2822 bfd *headers ATTRIBUTE_UNUSED;
2823 segT sec ATTRIBUTE_UNUSED;
2824 fragS *fragP ATTRIBUTE_UNUSED;
2826 as_fatal ("md_convert_frag");
2829 /* Should never be called for tic4x. */
2831 md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
2832 char *ptr ATTRIBUTE_UNUSED;
2833 addressT from_addr ATTRIBUTE_UNUSED;
2834 addressT to_addr ATTRIBUTE_UNUSED;
2835 fragS *frag ATTRIBUTE_UNUSED;
2836 symbolS *to_symbol ATTRIBUTE_UNUSED;
2838 as_fatal ("md_create_short_jmp\n");
2841 /* Should never be called for tic4x. */
2843 md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
2844 char *ptr ATTRIBUTE_UNUSED;
2845 addressT from_addr ATTRIBUTE_UNUSED;
2846 addressT to_addr ATTRIBUTE_UNUSED;
2847 fragS *frag ATTRIBUTE_UNUSED;
2848 symbolS *to_symbol ATTRIBUTE_UNUSED;
2850 as_fatal ("md_create_long_jump\n");
2853 /* Should never be called for tic4x. */
2855 md_estimate_size_before_relax (fragP, segtype)
2856 register fragS *fragP ATTRIBUTE_UNUSED;
2857 segT segtype ATTRIBUTE_UNUSED;
2859 as_fatal ("md_estimate_size_before_relax\n");
2865 md_parse_option (c, arg)
2871 case OPTION_CPU: /* cpu brand */
2872 if (tolower (*arg) == 'c')
2874 tic4x_cpu = atoi (arg);
2875 if (!IS_CPU_TIC3X (tic4x_cpu) && !IS_CPU_TIC4X (tic4x_cpu))
2876 as_warn ("Unsupported processor generation %d", tic4x_cpu);
2879 case OPTION_REV: /* cpu revision */
2880 tic4x_revision = atoi (arg);
2884 as_warn ("Option -b is depreciated, please use -mbig");
2885 case OPTION_BIG: /* big model */
2886 tic4x_big_model = 1;
2890 as_warn ("Option -p is depreciated, please use -mmemparm");
2891 case OPTION_MEMPARM: /* push args */
2896 as_warn ("Option -r is depreciated, please use -mregparm");
2897 case OPTION_REGPARM: /* register args */
2902 as_warn ("Option -s is depreciated, please use -msmall");
2903 case OPTION_SMALL: /* small model */
2904 tic4x_big_model = 0;
2911 case OPTION_LOWPOWER:
2915 case OPTION_ENHANCED:
2927 md_show_usage (stream)
2931 _("\nTIC4X options:\n"
2932 " -mcpu=CPU -mCPU select architecture variant. CPU can be:\n"
2934 " 31 - TMS320C31, TMS320LC31\n"
2936 " 33 - TMS320VC33\n"
2939 " -mrev=REV set cpu hardware revision (integer numbers).\n"
2940 " Combinations of -mcpu and -mrev will enable/disable\n"
2941 " the appropriate options (-midle2, -mlowpower and\n"
2942 " -menhanced) according to the selected type\n"
2943 " -mbig select big memory model\n"
2944 " -msmall select small memory model (default)\n"
2945 " -mregparm select register parameters (default)\n"
2946 " -mmemparm select memory parameters\n"
2947 " -midle2 enable IDLE2 support\n"
2948 " -mlowpower enable LOPOWER and MAXSPEED support\n"
2949 " -menhanced enable enhanced opcode support\n"));
2952 /* This is called when a line is unrecognized. This is used to handle
2953 definitions of TI C3x tools style local labels $n where n is a single
2956 tic4x_unrecognized_line (c)
2962 if (c != '$' || !isdigit (input_line_pointer[0]))
2965 s = input_line_pointer;
2967 /* Let's allow multiple digit local labels. */
2969 while (isdigit (*s))
2971 lab = lab * 10 + *s - '0';
2975 if (dollar_label_defined (lab))
2977 as_bad ("Label \"$%d\" redefined", lab);
2981 define_dollar_label (lab);
2982 colon (dollar_label_name (lab, 0));
2983 input_line_pointer = s + 1;
2988 /* Handle local labels peculiar to us referred to in an expression. */
2990 md_undefined_symbol (name)
2993 /* Look for local labels of the form $n. */
2994 if (name[0] == '$' && isdigit (name[1]))
3000 while (isdigit ((unsigned char) *s))
3002 lab = lab * 10 + *s - '0';
3005 if (dollar_label_defined (lab))
3007 name = dollar_label_name (lab, 0);
3008 symbolP = symbol_find (name);
3012 name = dollar_label_name (lab, 1);
3013 symbolP = symbol_find_or_make (name);
3021 /* Parse an operand that is machine-specific. */
3023 md_operand (expressionP)
3024 expressionS *expressionP ATTRIBUTE_UNUSED;
3028 /* Round up a section size to the appropriate boundary---do we need this? */
3030 md_section_align (segment, size)
3031 segT segment ATTRIBUTE_UNUSED;
3034 return size; /* Byte (i.e., 32-bit) alignment is fine? */
3038 tic4x_pc_offset (op)
3041 /* Determine the PC offset for a C[34]x instruction.
3042 This could be simplified using some boolean algebra
3043 but at the expense of readability. */
3047 case 0x62: /* call (C4x) */
3048 case 0x64: /* rptb (C4x) */
3050 case 0x61: /* brd */
3051 case 0x63: /* laj */
3052 case 0x65: /* rptbd (C4x) */
3054 case 0x66: /* swi */
3061 switch ((op & 0xffe00000) >> 20)
3063 case 0x6a0: /* bB */
3064 case 0x720: /* callB */
3065 case 0x740: /* trapB */
3068 case 0x6a2: /* bBd */
3069 case 0x6a6: /* bBat */
3070 case 0x6aa: /* bBaf */
3071 case 0x722: /* lajB */
3072 case 0x748: /* latB */
3073 case 0x798: /* rptbd */
3080 switch ((op & 0xfe200000) >> 20)
3082 case 0x6e0: /* dbB */
3085 case 0x6e2: /* dbBd */
3095 /* Exactly what point is a PC-relative offset relative TO?
3096 With the C3x we have the following:
3097 DBcond, Bcond disp + PC + 1 => PC
3098 DBcondD, BcondD disp + PC + 3 => PC
3101 md_pcrel_from (fixP)
3104 unsigned char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
3107 op = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
3109 return ((fixP->fx_where + fixP->fx_frag->fr_address) >> 2) +
3110 tic4x_pc_offset (op);
3113 /* Fill the alignment area with NOP's on .text, unless fill-data
3116 tic4x_do_align (alignment, fill, len, max)
3117 int alignment ATTRIBUTE_UNUSED;
3118 const char *fill ATTRIBUTE_UNUSED;
3119 int len ATTRIBUTE_UNUSED;
3120 int max ATTRIBUTE_UNUSED;
3122 unsigned long nop = NOP_OPCODE;
3124 /* Because we are talking lwords, not bytes, adjust aligment to do words */
3127 if (alignment != 0 && !need_pass_2)
3131 /*if (subseg_text_p (now_seg))*/ /* FIXME: doesnt work for .text for some reason */
3132 frag_align_pattern( alignment, (const char *)&nop, sizeof(nop), max);
3135 frag_align (alignment, 0, max);*/
3138 frag_align (alignment, *fill, max);
3140 frag_align_pattern (alignment, fill, len, max);
3143 /* Return 1 to skip the default aligment function */
3147 /* Look for and remove parallel instruction operator ||. */
3151 char *s = input_line_pointer;
3155 /* If parallel instruction prefix found at start of line, skip it. */
3156 if (*input_line_pointer == '|' && input_line_pointer[1] == '|')
3161 input_line_pointer ++;
3162 *input_line_pointer = ' ';
3163 /* So line counters get bumped. */
3164 input_line_pointer[-1] = '\n';
3169 /* Write out the previous insn here */
3172 input_line_pointer = s;
3177 tc_gen_reloc (seg, fixP)
3178 asection *seg ATTRIBUTE_UNUSED;
3183 reloc = (arelent *) xmalloc (sizeof (arelent));
3185 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
3186 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
3187 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
3188 reloc->address /= OCTETS_PER_BYTE;
3189 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
3190 if (reloc->howto == (reloc_howto_type *) NULL)
3192 as_bad_where (fixP->fx_file, fixP->fx_line,
3193 "Reloc %d not supported by object file format",
3194 (int) fixP->fx_r_type);
3198 if (fixP->fx_r_type == BFD_RELOC_HI16)
3199 reloc->addend = fixP->fx_offset;
3201 reloc->addend = fixP->fx_addnumber;