1 /* tc-tic4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
2 Copyright (C) 1997-2020 Free Software Foundation, Inc.
4 Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, 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, 51 Franklin Street - Fifth Floor,
21 Boston, MA 02110-1301, 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: Implement a 'bu' insn if the number of nop's exceeds 4
30 within the align frag. if(fragsize>4words) insert bu fragend+1
33 o .usect if has symbol on previous line not implemented
35 o .sym, .eos, .stag, .etag, .member not implemented
37 o Evaluation of constant floating point expressions (expr.c needs
40 o Support 'abc' constants (that is 0x616263). */
43 #include "safe-ctype.h"
44 #include "opcode/tic4x.h"
47 /* OK, we accept a syntax similar to the other well known C30
48 assembly tools. With TIC4X_ALT_SYNTAX defined we are more
49 flexible, allowing a more Unix-like syntax: `%' in front of
50 register names, `#' in front of immediate constants, and
51 not requiring `@' in front of direct addresses. */
53 #define TIC4X_ALT_SYNTAX
55 /* Handle of the inst mnemonic hash table. */
56 static htab_t tic4x_op_hash
= NULL
;
58 /* Handle asg pseudo. */
59 static htab_t tic4x_asg_hash
= NULL
;
61 static unsigned int tic4x_cpu
= 0; /* Default to TMS320C40. */
62 static unsigned int tic4x_revision
= 0; /* CPU revision */
63 static unsigned int tic4x_idle2
= 0; /* Idle2 support */
64 static unsigned int tic4x_lowpower
= 0; /* Lowpower support */
65 static unsigned int tic4x_enhanced
= 0; /* Enhanced opcode support */
66 static unsigned int tic4x_big_model
= 0; /* Default to small memory model. */
67 static unsigned int tic4x_reg_args
= 0; /* Default to args passed on stack. */
68 static unsigned long tic4x_oplevel
= 0; /* Opcode level */
70 #define OPTION_CPU 'm'
71 #define OPTION_BIG (OPTION_MD_BASE + 1)
72 #define OPTION_SMALL (OPTION_MD_BASE + 2)
73 #define OPTION_MEMPARM (OPTION_MD_BASE + 3)
74 #define OPTION_REGPARM (OPTION_MD_BASE + 4)
75 #define OPTION_IDLE2 (OPTION_MD_BASE + 5)
76 #define OPTION_LOWPOWER (OPTION_MD_BASE + 6)
77 #define OPTION_ENHANCED (OPTION_MD_BASE + 7)
78 #define OPTION_REV (OPTION_MD_BASE + 8)
80 const char *md_shortopts
= "bm:prs";
81 struct option md_longopts
[] =
83 { "mcpu", required_argument
, NULL
, OPTION_CPU
},
84 { "mdsp", required_argument
, NULL
, OPTION_CPU
},
85 { "mbig", no_argument
, NULL
, OPTION_BIG
},
86 { "msmall", no_argument
, NULL
, OPTION_SMALL
},
87 { "mmemparm", no_argument
, NULL
, OPTION_MEMPARM
},
88 { "mregparm", no_argument
, NULL
, OPTION_REGPARM
},
89 { "midle2", no_argument
, NULL
, OPTION_IDLE2
},
90 { "mlowpower", no_argument
, NULL
, OPTION_LOWPOWER
},
91 { "menhanced", no_argument
, NULL
, OPTION_ENHANCED
},
92 { "mrev", required_argument
, NULL
, OPTION_REV
},
93 { NULL
, no_argument
, NULL
, 0 }
96 size_t md_longopts_size
= sizeof (md_longopts
);
101 M_UNKNOWN
, M_IMMED
, M_DIRECT
, M_REGISTER
, M_INDIRECT
,
102 M_IMMED_F
, M_PARALLEL
, M_HI
106 typedef struct tic4x_operand
108 tic4x_addr_mode_t mode
; /* Addressing mode. */
109 expressionS expr
; /* Expression. */
110 int disp
; /* Displacement for indirect addressing. */
111 int aregno
; /* Aux. register number. */
112 LITTLENUM_TYPE fwords
[MAX_LITTLENUMS
]; /* Float immed. number. */
116 typedef struct tic4x_insn
118 char name
[TIC4X_NAME_MAX
]; /* Mnemonic of instruction. */
119 unsigned int in_use
; /* True if in_use. */
120 unsigned int parallel
; /* True if parallel instruction. */
121 unsigned int nchars
; /* This is always 4 for the C30. */
122 unsigned long opcode
; /* Opcode number. */
123 expressionS exp
; /* Expression required for relocation. */
124 /* Relocation type required. */
125 bfd_reloc_code_real_type reloc
;
126 int pcrel
; /* True if relocation PC relative. */
127 char *pname
; /* Name of instruction in parallel. */
128 unsigned int num_operands
; /* Number of operands in total. */
129 tic4x_inst_t
*inst
; /* Pointer to first template. */
130 tic4x_operand_t operands
[TIC4X_OPERANDS_MAX
];
134 static tic4x_insn_t the_insn
; /* Info about our instruction. */
135 static tic4x_insn_t
*insn
= &the_insn
;
137 static void tic4x_asg (int);
138 static void tic4x_bss (int);
139 static void tic4x_globl (int);
140 static void tic4x_cons (int);
141 static void tic4x_stringer (int);
142 static void tic4x_eval (int);
143 static void tic4x_newblock (int);
144 static void tic4x_sect (int);
145 static void tic4x_set (int);
146 static void tic4x_usect (int);
147 static void tic4x_version (int);
153 {"align", s_align_bytes
, 32},
154 {"ascii", tic4x_stringer
, 1},
155 {"asciz", tic4x_stringer
, 0},
156 {"asg", tic4x_asg
, 0},
157 {"block", s_space
, 4},
158 {"byte", tic4x_cons
, 1},
159 {"bss", tic4x_bss
, 0},
160 {"copy", s_include
, 0},
161 {"def", tic4x_globl
, 0},
162 {"equ", tic4x_set
, 0},
163 {"eval", tic4x_eval
, 0},
164 {"global", tic4x_globl
, 0},
165 {"globl", tic4x_globl
, 0},
166 {"hword", tic4x_cons
, 2},
167 {"ieee", float_cons
, 'i'},
168 {"int", tic4x_cons
, 4}, /* .int allocates 4 bytes. */
169 {"ldouble", float_cons
, 'e'},
170 {"newblock", tic4x_newblock
, 0},
171 {"ref", s_ignore
, 0}, /* All undefined treated as external. */
172 {"set", tic4x_set
, 0},
173 {"sect", tic4x_sect
, 1}, /* Define named section. */
174 {"space", s_space
, 4},
175 {"string", tic4x_stringer
, 0},
176 {"usect", tic4x_usect
, 0}, /* Reserve space in uninit. named sect. */
177 {"version", tic4x_version
, 0},
178 {"word", tic4x_cons
, 4}, /* .word allocates 4 bytes. */
179 {"xdef", tic4x_globl
, 0},
183 int md_short_jump_size
= 4;
184 int md_long_jump_size
= 4;
186 /* This array holds the chars that always start a comment. If the
187 pre-processor is disabled, these aren't very useful. */
188 #ifdef TIC4X_ALT_SYNTAX
189 const char comment_chars
[] = ";!";
191 const char comment_chars
[] = ";";
194 /* This array holds the chars that only start a comment at the beginning of
195 a line. If the line seems to have the form '# 123 filename'
196 .line and .file directives will appear in the pre-processed output.
197 Note that input_file.c hand checks for '#' at the beginning of the
198 first line of the input file. This is because the compiler outputs
199 #NO_APP at the beginning of its output.
200 Also note that comments like this one will always work. */
201 const char line_comment_chars
[] = "#*";
203 /* We needed an unused char for line separation to work around the
204 lack of macros, using sed and such. */
205 const char line_separator_chars
[] = "&";
207 /* Chars that can be used to separate mant from exp in floating point nums. */
208 const char EXP_CHARS
[] = "eE";
210 /* Chars that mean this number is a floating point constant. */
213 const char FLT_CHARS
[] = "fFilsS";
215 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
216 changed in read.c. Ideally it shouldn't have to know about it at
217 all, but nothing is ideal around here. */
219 /* Flonums returned here. */
220 extern FLONUM_TYPE generic_floating_point_number
;
222 /* Precision in LittleNums. */
223 #define MAX_PRECISION (4) /* It's a bit overkill for us, but the code
225 #define S_PRECISION (1) /* Short float constants 16-bit. */
226 #define F_PRECISION (2) /* Float and double types 32-bit. */
227 #define E_PRECISION (4) /* Extended precision, 64-bit (real 40-bit). */
230 /* Turn generic_floating_point_number into a real short/float/double. */
232 tic4x_gen_to_words (FLONUM_TYPE flonum
, LITTLENUM_TYPE
*words
, int precision
)
234 int return_value
= 0;
235 LITTLENUM_TYPE
*p
; /* Littlenum pointer. */
236 int mantissa_bits
; /* Bits in mantissa field. */
237 int exponent_bits
; /* Bits in exponent field. */
239 unsigned int sone
; /* Scaled one. */
240 unsigned int sfract
; /* Scaled fraction. */
241 unsigned int smant
; /* Scaled mantissa. */
243 unsigned int mover
; /* Mantissa overflow bits */
244 unsigned int rbit
; /* Round bit. */
245 int shift
; /* Shift count. */
247 /* NOTE: Svein Seldal <Svein@dev.seldal.com>
248 The code in this function is altered slightly to support floats
249 with 31-bits mantissas, thus the documentation below may be a
250 little bit inaccurate.
252 By Michael P. Hayes <m.hayes@elec.canterbury.ac.nz>
253 Here is how a generic floating point number is stored using
254 flonums (an extension of bignums) where p is a pointer to an
257 For example 2e-3 is stored with exp = -4 and
264 with low = &bits[2], high = &bits[5], and leader = &bits[5].
266 This number can be written as
267 0x0083126e978d4fde.00000000 * 65536**-4 or
268 0x0.0083126e978d4fde * 65536**0 or
269 0x0.83126e978d4fde * 2**-8 = 2e-3
271 Note that low points to the 65536**0 littlenum (bits[2]) and
272 leader points to the most significant non-zero littlenum
275 TMS320C3X floating point numbers are a bit of a strange beast.
276 The 32-bit flavour has the 8 MSBs representing the exponent in
277 twos complement format (-128 to +127). There is then a sign bit
278 followed by 23 bits of mantissa. The mantissa is expressed in
279 twos complement format with the binary point after the most
280 significant non sign bit. The bit after the binary point is
281 suppressed since it is the complement of the sign bit. The
282 effective mantissa is thus 24 bits. Zero is represented by an
285 The 16-bit flavour has the 4 MSBs representing the exponent in
286 twos complement format (-8 to +7). There is then a sign bit
287 followed by 11 bits of mantissa. The mantissa is expressed in
288 twos complement format with the binary point after the most
289 significant non sign bit. The bit after the binary point is
290 suppressed since it is the complement of the sign bit. The
291 effective mantissa is thus 12 bits. Zero is represented by an
292 exponent of -8. For example,
294 number norm mant m x e s i fraction f
295 +0.500 => 1.00000000000 -1 -1 0 1 .00000000000 (1 + 0) * 2^(-1)
296 +0.999 => 1.11111111111 -1 -1 0 1 .11111111111 (1 + 0.99) * 2^(-1)
297 +1.000 => 1.00000000000 0 0 0 1 .00000000000 (1 + 0) * 2^(0)
298 +1.500 => 1.10000000000 0 0 0 1 .10000000000 (1 + 0.5) * 2^(0)
299 +1.999 => 1.11111111111 0 0 0 1 .11111111111 (1 + 0.9) * 2^(0)
300 +2.000 => 1.00000000000 1 1 0 1 .00000000000 (1 + 0) * 2^(1)
301 +4.000 => 1.00000000000 2 2 0 1 .00000000000 (1 + 0) * 2^(2)
302 -0.500 => 1.00000000000 -1 -1 1 0 .10000000000 (-2 + 0) * 2^(-2)
303 -1.000 => 1.00000000000 0 -1 1 0 .00000000000 (-2 + 0) * 2^(-1)
304 -1.500 => 1.10000000000 0 0 1 0 .10000000000 (-2 + 0.5) * 2^(0)
305 -1.999 => 1.11111111111 0 0 1 0 .00000000001 (-2 + 0.11) * 2^(0)
306 -2.000 => 1.00000000000 1 1 1 0 .00000000000 (-2 + 0) * 2^(0)
307 -4.000 => 1.00000000000 2 1 1 0 .00000000000 (-2 + 0) * 2^(1)
309 where e is the exponent, s is the sign bit, i is the implied bit,
310 and f is the fraction stored in the mantissa field.
312 num = (1 + f) * 2^x = m * 2^e if s = 0
313 num = (-2 + f) * 2^x = -m * 2^e if s = 1
314 where 0 <= f < 1.0 and 1.0 <= m < 2.0
316 The fraction (f) and exponent (e) fields for the TMS320C3X format
317 can be derived from the normalised mantissa (m) and exponent (x) using:
319 f = m - 1, e = x if s = 0
320 f = 2 - m, e = x if s = 1 and m != 1.0
321 f = 0, e = x - 1 if s = 1 and m = 1.0
322 f = 0, e = -8 if m = 0
325 OK, the other issue we have to consider is rounding since the
326 mantissa has a much higher potential precision than what we can
327 represent. To do this we add half the smallest storable fraction.
328 We then have to renormalise the number to allow for overflow.
330 To convert a generic flonum into a TMS320C3X floating point
331 number, here's what we try to do....
333 The first thing is to generate a normalised mantissa (m) where
334 1.0 <= m < 2 and to convert the exponent from base 16 to base 2.
335 We desire the binary point to be placed after the most significant
336 non zero bit. This process is done in two steps: firstly, the
337 littlenum with the most significant non zero bit is located (this
338 is done for us since leader points to this littlenum) and the
339 binary point (which is currently after the LSB of the littlenum
340 pointed to by low) is moved to before the MSB of the littlenum
341 pointed to by leader. This requires the exponent to be adjusted
342 by leader - low + 1. In the earlier example, the new exponent is
343 thus -4 + (5 - 2 + 1) = 0 (base 65536). We now need to convert
344 the exponent to base 2 by multiplying the exponent by 16 (log2
345 65536). The exponent base 2 is thus also zero.
347 The second step is to hunt for the most significant non zero bit
348 in the leader littlenum. We do this by left shifting a copy of
349 the leader littlenum until bit 16 is set (0x10000) and counting
350 the number of shifts, S, required. The number of shifts then has to
351 be added to correct the exponent (base 2). For our example, this
352 will require 9 shifts and thus our normalised exponent (base 2) is
353 0 + 9 = 9. Note that the worst case scenario is when the leader
354 littlenum is 1, thus requiring 16 shifts.
356 We now have to left shift the other littlenums by the same amount,
357 propagating the shifted bits into the more significant littlenums.
358 To save a lot of unnecessary shifting we only have to consider
359 two or three littlenums, since the greatest number of mantissa
360 bits required is 24 + 1 rounding bit. While two littlenums
361 provide 32 bits of precision, the most significant littlenum
362 may only contain a single significant bit and thus an extra
363 littlenum is required.
365 Denoting the number of bits in the fraction field as F, we require
366 G = F + 2 bits (one extra bit is for rounding, the other gets
367 suppressed). Say we required S shifts to find the most
368 significant bit in the leader littlenum, the number of left shifts
369 required to move this bit into bit position G - 1 is L = G + S - 17.
370 Note that this shift count may be negative for the short floating
371 point flavour (where F = 11 and thus G = 13 and potentially S < 3).
372 If L > 0 we have to shunt the next littlenum into position. Bit
373 15 (the MSB) of the next littlenum needs to get moved into position
374 L - 1 (If L > 15 we need all the bits of this littlenum and
375 some more from the next one.). We subtract 16 from L and use this
376 as the left shift count; the resultant value we or with the
377 previous result. If L > 0, we repeat this operation. */
379 if (precision
!= S_PRECISION
)
381 if (precision
== E_PRECISION
)
382 words
[2] = words
[3] = 0x0000;
384 /* 0.0e0 or NaN seen. */
385 if (flonum
.low
> flonum
.leader
/* = 0.0e0 */
386 || flonum
.sign
== 0) /* = NaN */
389 as_bad (_("Nan, using zero."));
394 if (flonum
.sign
== 'P')
396 /* +INF: Replace with maximum float. */
397 if (precision
== S_PRECISION
)
404 if (precision
== E_PRECISION
)
411 else if (flonum
.sign
== 'N')
413 /* -INF: Replace with maximum float. */
414 if (precision
== S_PRECISION
)
418 if (precision
== E_PRECISION
)
423 exponent
= (flonum
.exponent
+ flonum
.leader
- flonum
.low
+ 1) * 16;
425 if (!(tmp
= *flonum
.leader
))
426 abort (); /* Hmmm. */
427 shift
= 0; /* Find position of first sig. bit. */
430 exponent
-= (16 - shift
); /* Adjust exponent. */
432 if (precision
== S_PRECISION
) /* Allow 1 rounding bit. */
437 else if(precision
== F_PRECISION
)
442 else /* E_PRECISION */
448 shift
= mantissa_bits
- shift
;
453 /* Store the mantissa data into smant and the roundbit into rbit */
454 for (p
= flonum
.leader
; p
>= flonum
.low
&& shift
> -16; p
--)
456 tmp
= shift
>= 0 ? (unsigned) *p
<< shift
: (unsigned) *p
>> -shift
;
457 rbit
= shift
< 0 ? (((unsigned) *p
>> (-shift
-1)) & 0x1) : 0;
462 /* OK, we've got our scaled mantissa so let's round it up */
465 /* If the mantissa is going to overflow when added, lets store
466 the extra bit in mover. */
467 if (smant
== (1u << mantissa_bits
<< 1) - 1)
472 /* Get the scaled one value */
473 sone
= 1u << mantissa_bits
;
475 /* The number may be unnormalised so renormalise it... */
479 smant
|= sone
; /* Insert the bit from mover into smant */
483 /* The binary point is now between bit positions 11 and 10 or 23 and 22,
484 i.e., between mantissa_bits - 1 and mantissa_bits - 2 and the
485 bit at mantissa_bits - 1 should be set. */
487 abort (); /* Ooops. */
489 if (flonum
.sign
== '+')
490 sfract
= smant
- sone
; /* smant - 1.0. */
493 /* This seems to work. */
501 sfract
= -smant
& (sone
-1); /* 2.0 - smant. */
503 sfract
|= sone
; /* Insert sign bit. */
506 if (abs (exponent
) >= (1 << (exponent_bits
- 1)))
507 as_bad (_("Cannot represent exponent in %d bits"), exponent_bits
);
509 /* Force exponent to fit in desired field width. */
510 exponent
&= (1 << (exponent_bits
)) - 1;
512 if (precision
== E_PRECISION
)
514 /* Map the float part first (100% equal format as F_PRECISION) */
515 words
[0] = exponent
<< (mantissa_bits
+1-24);
516 words
[0] |= sfract
>> 24;
517 words
[1] = sfract
>> 8;
519 /* Map the mantissa in the next */
520 words
[2] = sfract
>> 16;
521 words
[3] = sfract
& 0xffff;
525 /* Insert the exponent data into the word */
526 sfract
|= (unsigned) exponent
<< (mantissa_bits
+ 1);
528 if (precision
== S_PRECISION
)
532 words
[0] = sfract
>> 16;
533 words
[1] = sfract
& 0xffff;
540 /* Returns pointer past text consumed. */
542 tic4x_atof (char *str
, char what_kind
, LITTLENUM_TYPE
*words
)
544 /* Extra bits for zeroed low-order bits. The 1st MAX_PRECISION are
545 zeroed, the last contain flonum bits. */
546 static LITTLENUM_TYPE bits
[MAX_PRECISION
+ MAX_PRECISION
+ GUARD
];
548 /* Number of 16-bit words in the format. */
550 FLONUM_TYPE save_gen_flonum
;
552 /* We have to save the generic_floating_point_number because it
553 contains storage allocation about the array of LITTLENUMs where
554 the value is actually stored. We will allocate our own array of
555 littlenums below, but have to restore the global one on exit. */
556 save_gen_flonum
= generic_floating_point_number
;
559 generic_floating_point_number
.low
= bits
+ MAX_PRECISION
;
560 generic_floating_point_number
.high
= NULL
;
561 generic_floating_point_number
.leader
= NULL
;
562 generic_floating_point_number
.exponent
= 0;
563 generic_floating_point_number
.sign
= '\0';
565 /* Use more LittleNums than seems necessary: the highest flonum may
566 have 15 leading 0 bits, so could be useless. */
568 memset (bits
, '\0', sizeof (LITTLENUM_TYPE
) * MAX_PRECISION
);
574 precision
= S_PRECISION
;
581 precision
= F_PRECISION
;
586 precision
= E_PRECISION
;
590 as_bad (_("Invalid floating point number"));
594 generic_floating_point_number
.high
595 = generic_floating_point_number
.low
+ precision
- 1 + GUARD
;
597 if (atof_generic (&return_value
, ".", EXP_CHARS
,
598 &generic_floating_point_number
))
600 as_bad (_("Invalid floating point number"));
604 tic4x_gen_to_words (generic_floating_point_number
,
607 /* Restore the generic_floating_point_number's storage alloc (and
609 generic_floating_point_number
= save_gen_flonum
;
615 tic4x_insert_reg (const char *regname
, int regnum
)
620 symbol_table_insert (symbol_new (regname
, reg_section
,
621 &zero_address_frag
, regnum
));
622 for (i
= 0; regname
[i
]; i
++)
623 buf
[i
] = ISLOWER (regname
[i
]) ? TOUPPER (regname
[i
]) : regname
[i
];
626 symbol_table_insert (symbol_new (buf
, reg_section
,
627 &zero_address_frag
, regnum
));
631 tic4x_insert_sym (const char *symname
, int value
)
635 symbolP
= symbol_new (symname
, absolute_section
,
636 &zero_address_frag
, value
);
637 SF_SET_LOCAL (symbolP
);
638 symbol_table_insert (symbolP
);
642 tic4x_expression (char *str
, expressionS
*exp
)
647 t
= input_line_pointer
; /* Save line pointer. */
648 input_line_pointer
= str
;
650 s
= input_line_pointer
;
651 input_line_pointer
= t
; /* Restore line pointer. */
652 return s
; /* Return pointer to where parsing stopped. */
656 tic4x_expression_abs (char *str
, offsetT
*value
)
661 t
= input_line_pointer
; /* Save line pointer. */
662 input_line_pointer
= str
;
663 *value
= get_absolute_expression ();
664 s
= input_line_pointer
;
665 input_line_pointer
= t
; /* Restore line pointer. */
670 tic4x_emit_char (char c
, int b
)
674 exp
.X_op
= O_constant
;
675 exp
.X_add_number
= c
;
680 tic4x_seg_alloc (char *name ATTRIBUTE_UNUSED
,
681 segT seg ATTRIBUTE_UNUSED
,
685 /* Note that the size is in words
686 so we multiply it by 4 to get the number of bytes to allocate. */
688 /* If we have symbol: .usect ".fred", size etc.,
689 the symbol needs to point to the first location reserved
696 p
= frag_var (rs_fill
, 1, 1, (relax_substateT
) 0,
698 size
* OCTETS_PER_BYTE
, (char *) 0);
703 /* .asg ["]character-string["], symbol */
705 tic4x_asg (int x ATTRIBUTE_UNUSED
)
712 str
= input_line_pointer
;
714 /* Skip string expression. */
715 while (*input_line_pointer
!= ',' && *input_line_pointer
)
716 input_line_pointer
++;
717 if (*input_line_pointer
!= ',')
719 as_bad (_("Comma expected\n"));
722 *input_line_pointer
++ = '\0';
723 c
= get_symbol_name (&name
); /* Get terminator. */
725 name
= xstrdup (name
);
726 str_hash_insert (tic4x_asg_hash
, name
, str
, 1);
727 (void) restore_line_pointer (c
);
728 demand_empty_rest_of_line ();
731 /* .bss symbol, size */
733 tic4x_bss (int x ATTRIBUTE_UNUSED
)
740 subsegT current_subseg
;
743 current_seg
= now_seg
; /* Save current seg. */
744 current_subseg
= now_subseg
; /* Save current subseg. */
747 c
= get_symbol_name (&name
); /* Get terminator. */
749 c
= * ++ input_line_pointer
;
752 as_bad (_(".bss size argument missing\n"));
757 tic4x_expression_abs (++input_line_pointer
, &size
);
760 as_bad (_(".bss size %ld < 0!"), (long) size
);
763 subseg_set (bss_section
, 0);
764 symbolP
= symbol_find_or_make (name
);
766 if (S_GET_SEGMENT (symbolP
) == bss_section
)
767 symbol_get_frag (symbolP
)->fr_symbol
= 0;
769 symbol_set_frag (symbolP
, frag_now
);
771 p
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
,
772 size
* OCTETS_PER_BYTE
, (char *) 0);
773 *p
= 0; /* Fill char. */
775 S_SET_SEGMENT (symbolP
, bss_section
);
777 /* The symbol may already have been created with a preceding
778 ".globl" directive -- be careful not to step on storage class
779 in that case. Otherwise, set it to static. */
780 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
781 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
783 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
784 demand_empty_rest_of_line ();
788 tic4x_globl (int ignore ATTRIBUTE_UNUSED
)
796 c
= get_symbol_name (&name
);
797 symbolP
= symbol_find_or_make (name
);
798 *input_line_pointer
= c
;
799 SKIP_WHITESPACE_AFTER_NAME ();
800 S_SET_STORAGE_CLASS (symbolP
, C_EXT
);
801 S_SET_EXTERNAL (symbolP
);
804 input_line_pointer
++;
806 if (*input_line_pointer
== '\n')
812 demand_empty_rest_of_line ();
815 /* Handle .byte, .word. .int, .long */
817 tic4x_cons (int bytes
)
823 if (*input_line_pointer
== '"')
825 input_line_pointer
++;
826 while (is_a_char (c
= next_char_of_string ()))
827 tic4x_emit_char (c
, 4);
828 know (input_line_pointer
[-1] == '\"');
834 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
835 if (exp
.X_op
== O_constant
)
840 exp
.X_add_number
&= 255;
843 exp
.X_add_number
&= 65535;
847 /* Perhaps we should disallow .byte and .hword with
848 a non constant expression that will require relocation. */
852 while (*input_line_pointer
++ == ',');
854 input_line_pointer
--; /* Put terminator back into stream. */
855 demand_empty_rest_of_line ();
858 /* Handle .ascii, .asciz, .string */
860 tic4x_stringer (int append_zero
)
869 if (*input_line_pointer
== '"')
871 input_line_pointer
++;
872 while (is_a_char (c
= next_char_of_string ()))
874 tic4x_emit_char (c
, 1);
880 tic4x_emit_char (c
, 1);
884 know (input_line_pointer
[-1] == '\"');
890 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
891 if (exp
.X_op
!= O_constant
)
893 as_bad (_("Non-constant symbols not allowed\n"));
896 exp
.X_add_number
&= 255; /* Limit number to 8-bit */
901 while (*input_line_pointer
++ == ',');
903 /* Fill out the rest of the expression with 0's to fill up a full word */
905 tic4x_emit_char (0, 4-(bytes
&0x3));
907 input_line_pointer
--; /* Put terminator back into stream. */
908 demand_empty_rest_of_line ();
911 /* .eval expression, symbol */
913 tic4x_eval (int x ATTRIBUTE_UNUSED
)
921 tic4x_expression_abs (input_line_pointer
, &value
);
922 if (*input_line_pointer
++ != ',')
924 as_bad (_("Symbol missing\n"));
927 c
= get_symbol_name (&name
); /* Get terminator. */
928 tic4x_insert_sym (name
, value
);
929 (void) restore_line_pointer (c
);
930 demand_empty_rest_of_line ();
933 /* Reset local labels. */
935 tic4x_newblock (int x ATTRIBUTE_UNUSED
)
937 dollar_label_clear ();
940 /* .sect "section-name" [, value] */
941 /* .sect ["]section-name[:subsection-name]["] [, value] */
943 tic4x_sect (int x ATTRIBUTE_UNUSED
)
952 if (*input_line_pointer
== '"')
953 input_line_pointer
++;
954 c
= get_symbol_name (§ion_name
); /* Get terminator. */
956 c
= * ++ input_line_pointer
;
957 input_line_pointer
++; /* Skip null symbol terminator. */
958 name
= xstrdup (section_name
);
960 /* TI C from version 5.0 allows a section name to contain a
961 subsection name as well. The subsection name is separated by a
962 ':' from the section name. Currently we scan the subsection
964 Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>. */
968 c
= get_symbol_name (&subname
); /* Get terminator. */
970 c
= * ++ input_line_pointer
;
971 input_line_pointer
++; /* Skip null symbol terminator. */
972 as_warn (_(".sect: subsection name ignored"));
975 /* We might still have a '"' to discard, but the character after a
976 symbol name will be overwritten with a \0 by get_symbol_name()
981 tic4x_expression_abs (input_line_pointer
, &num
);
982 else if (*input_line_pointer
== ',')
985 tic4x_expression_abs (++input_line_pointer
, &num
);
990 seg
= subseg_new (name
, num
);
991 if (line_label
!= NULL
)
993 S_SET_SEGMENT (line_label
, seg
);
994 symbol_set_frag (line_label
, frag_now
);
997 if (bfd_section_flags (seg
) == SEC_NO_FLAGS
)
999 if (!bfd_set_section_flags (seg
, SEC_DATA
))
1000 as_warn (_("Error setting flags for \"%s\": %s"), name
,
1001 bfd_errmsg (bfd_get_error ()));
1004 /* If the last character overwritten by get_symbol_name() was an
1005 end-of-line, we must restore it or the end of the line will not be
1006 recognised and scanning extends into the next line, stopping with
1007 an error (blame Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>
1008 if this is not true). */
1009 if (is_end_of_line
[(unsigned char) c
])
1010 *(--input_line_pointer
) = c
;
1012 demand_empty_rest_of_line ();
1015 /* symbol[:] .set value or .set symbol, value */
1017 tic4x_set (int x ATTRIBUTE_UNUSED
)
1022 if ((symbolP
= line_label
) == NULL
)
1027 c
= get_symbol_name (&name
); /* Get terminator. */
1029 c
= * ++ input_line_pointer
;
1032 as_bad (_(".set syntax invalid\n"));
1033 ignore_rest_of_line ();
1036 ++input_line_pointer
;
1037 symbolP
= symbol_find_or_make (name
);
1040 symbol_table_insert (symbolP
);
1042 pseudo_set (symbolP
);
1043 demand_empty_rest_of_line ();
1046 /* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
1048 tic4x_usect (int x ATTRIBUTE_UNUSED
)
1054 offsetT size
, alignment_flag
;
1056 subsegT current_subseg
;
1058 current_seg
= now_seg
; /* save current seg. */
1059 current_subseg
= now_subseg
; /* save current subseg. */
1062 if (*input_line_pointer
== '"')
1063 input_line_pointer
++;
1064 c
= get_symbol_name (§ion_name
); /* Get terminator. */
1066 c
= * ++ input_line_pointer
;
1067 input_line_pointer
++; /* Skip null symbol terminator. */
1068 name
= xstrdup (section_name
);
1071 input_line_pointer
=
1072 tic4x_expression_abs (input_line_pointer
, &size
);
1073 else if (*input_line_pointer
== ',')
1075 input_line_pointer
=
1076 tic4x_expression_abs (++input_line_pointer
, &size
);
1081 /* Read a possibly present third argument (alignment flag) [VK]. */
1082 if (*input_line_pointer
== ',')
1084 input_line_pointer
=
1085 tic4x_expression_abs (++input_line_pointer
, &alignment_flag
);
1090 as_warn (_(".usect: non-zero alignment flag ignored"));
1092 seg
= subseg_new (name
, 0);
1093 if (line_label
!= NULL
)
1095 S_SET_SEGMENT (line_label
, seg
);
1096 symbol_set_frag (line_label
, frag_now
);
1097 S_SET_VALUE (line_label
, frag_now_fix ());
1099 seg_info (seg
)->bss
= 1; /* Uninitialised data. */
1100 if (!bfd_set_section_flags (seg
, SEC_ALLOC
))
1101 as_warn (_("Error setting flags for \"%s\": %s"), name
,
1102 bfd_errmsg (bfd_get_error ()));
1103 tic4x_seg_alloc (name
, seg
, size
, line_label
);
1105 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1106 S_SET_STORAGE_CLASS (line_label
, C_STAT
);
1108 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
1109 demand_empty_rest_of_line ();
1112 /* .version cpu-version. */
1114 tic4x_version (int x ATTRIBUTE_UNUSED
)
1118 input_line_pointer
=
1119 tic4x_expression_abs (input_line_pointer
, &temp
);
1120 if (!IS_CPU_TIC3X (temp
) && !IS_CPU_TIC4X (temp
))
1121 as_bad (_("This assembler does not support processor generation %ld"),
1124 if (tic4x_cpu
&& temp
!= (offsetT
) tic4x_cpu
)
1125 as_warn (_("Changing processor generation on fly not supported..."));
1127 demand_empty_rest_of_line ();
1131 tic4x_init_regtable (void)
1135 for (i
= 0; i
< tic3x_num_registers
; i
++)
1136 tic4x_insert_reg (tic3x_registers
[i
].name
,
1137 tic3x_registers
[i
].regno
);
1139 if (IS_CPU_TIC4X (tic4x_cpu
))
1141 /* Add additional Tic4x registers, overriding some C3x ones. */
1142 for (i
= 0; i
< tic4x_num_registers
; i
++)
1143 tic4x_insert_reg (tic4x_registers
[i
].name
,
1144 tic4x_registers
[i
].regno
);
1149 tic4x_init_symbols (void)
1151 /* The TI tools accept case insensitive versions of these symbols,
1156 .TMS320xx 30,31,32,40,or 44 set according to -v flag
1157 .C3X or .C3x 1 or 0 1 if -v30,-v31,or -v32
1158 .C30 1 or 0 1 if -v30
1159 .C31 1 or 0 1 if -v31
1160 .C32 1 or 0 1 if -v32
1161 .C4X or .C4x 1 or 0 1 if -v40, or -v44
1162 .C40 1 or 0 1 if -v40
1163 .C44 1 or 0 1 if -v44
1165 .REGPARM 1 or 0 1 if -mr option used
1166 .BIGMODEL 1 or 0 1 if -mb option used
1168 These symbols are currently supported but will be removed in a
1170 .TMS320C30 1 or 0 1 if -v30,-v31,or -v32
1171 .TMS320C31 1 or 0 1 if -v31
1172 .TMS320C32 1 or 0 1 if -v32
1173 .TMS320C40 1 or 0 1 if -v40, or -v44
1174 .TMS320C44 1 or 0 1 if -v44
1176 Source: TI: TMS320C3x/C4x Assembly Language Tools User's Guide,
1177 1997, SPRU035C, p. 3-17/3-18. */
1178 tic4x_insert_sym (".REGPARM", tic4x_reg_args
);
1179 tic4x_insert_sym (".MEMPARM", !tic4x_reg_args
);
1180 tic4x_insert_sym (".BIGMODEL", tic4x_big_model
);
1181 tic4x_insert_sym (".C30INTERRUPT", 0);
1182 tic4x_insert_sym (".TMS320xx", tic4x_cpu
== 0 ? 40 : tic4x_cpu
);
1183 tic4x_insert_sym (".C3X", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1184 tic4x_insert_sym (".C3x", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1185 tic4x_insert_sym (".C4X", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1186 tic4x_insert_sym (".C4x", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1187 /* Do we need to have the following symbols also in lower case? */
1188 tic4x_insert_sym (".TMS320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1189 tic4x_insert_sym (".tms320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1190 tic4x_insert_sym (".TMS320C31", tic4x_cpu
== 31);
1191 tic4x_insert_sym (".tms320C31", tic4x_cpu
== 31);
1192 tic4x_insert_sym (".TMS320C32", tic4x_cpu
== 32);
1193 tic4x_insert_sym (".tms320C32", tic4x_cpu
== 32);
1194 tic4x_insert_sym (".TMS320C33", tic4x_cpu
== 33);
1195 tic4x_insert_sym (".tms320C33", tic4x_cpu
== 33);
1196 tic4x_insert_sym (".TMS320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1197 tic4x_insert_sym (".tms320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1198 tic4x_insert_sym (".TMS320C44", tic4x_cpu
== 44);
1199 tic4x_insert_sym (".tms320C44", tic4x_cpu
== 44);
1200 tic4x_insert_sym (".TMX320C40", 0); /* C40 first pass silicon ? */
1201 tic4x_insert_sym (".tmx320C40", 0);
1204 /* Insert a new instruction template into hash table. */
1206 tic4x_inst_insert (const tic4x_inst_t
*inst
)
1208 static char prev_name
[16];
1210 /* Only insert the first name if have several similar entries. */
1211 if (!strcmp (inst
->name
, prev_name
) || inst
->name
[0] == '\0')
1214 if (str_hash_insert (tic4x_op_hash
, inst
->name
, inst
, 0) != NULL
)
1215 as_fatal (_("duplicate %s"), inst
->name
);
1217 strcpy (prev_name
, inst
->name
);
1220 /* Make a new instruction template. */
1221 static tic4x_inst_t
*
1222 tic4x_inst_make (const char *name
, unsigned long opcode
, const char *args
)
1224 static tic4x_inst_t
*insts
= NULL
;
1225 static char *names
= NULL
;
1226 static int iindex
= 0;
1230 /* Allocate memory to store name strings. */
1231 names
= XNEWVEC (char, 8192);
1232 /* Allocate memory for additional insts. */
1233 insts
= XNEWVEC (tic4x_inst_t
, 1024);
1235 insts
[iindex
].name
= names
;
1236 insts
[iindex
].opcode
= opcode
;
1237 insts
[iindex
].opmask
= 0xffffffff;
1238 insts
[iindex
].args
= args
;
1245 return &insts
[iindex
- 1];
1248 /* Add instruction template, creating dynamic templates as required. */
1250 tic4x_inst_add (const tic4x_inst_t
*insts
)
1252 const char *s
= insts
->name
;
1259 /* We do not care about INSNs that is not a part of our
1261 if ((insts
->oplevel
& tic4x_oplevel
) == 0)
1270 /* Dynamically create all the conditional insts. */
1271 for (i
= 0; i
< tic4x_num_conds
; i
++)
1275 const char *c
= tic4x_conds
[i
].name
;
1285 /* If instruction found then have already processed it. */
1286 if (str_hash_find (tic4x_op_hash
, name
))
1291 inst
= tic4x_inst_make (name
, insts
[k
].opcode
+
1292 (tic4x_conds
[i
].cond
<<
1293 (*s
== 'B' ? 16 : 23)),
1295 if (k
== 0) /* Save strcmp() with following func. */
1296 tic4x_inst_insert (inst
);
1299 while (!strcmp (insts
->name
,
1305 tic4x_inst_insert (insts
);
1315 /* This function is called once, at assembler startup time. It should
1316 set up all the tables, etc., that the MD part of the assembler will
1323 /* Setup the proper opcode level according to the
1324 commandline parameters */
1325 tic4x_oplevel
= OP_C3X
;
1327 if ( IS_CPU_TIC4X(tic4x_cpu
) )
1328 tic4x_oplevel
|= OP_C4X
;
1330 if ( ( tic4x_cpu
== 31 && tic4x_revision
>= 6)
1331 || (tic4x_cpu
== 32 && tic4x_revision
>= 2)
1332 || (tic4x_cpu
== 33)
1334 tic4x_oplevel
|= OP_ENH
;
1336 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1337 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1338 || (tic4x_cpu
== 32)
1340 tic4x_oplevel
|= OP_LPWR
;
1342 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1343 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1344 || (tic4x_cpu
== 32)
1345 || (tic4x_cpu
== 33)
1346 || (tic4x_cpu
== 40 && tic4x_revision
>= 5)
1347 || (tic4x_cpu
== 44)
1349 tic4x_oplevel
|= OP_IDLE2
;
1351 /* Create hash table for mnemonics. */
1352 tic4x_op_hash
= str_htab_create ();
1354 /* Create hash table for asg pseudo. */
1355 tic4x_asg_hash
= str_htab_create ();
1357 /* Add mnemonics to hash table, expanding conditional mnemonics on fly. */
1358 for (i
= 0; i
< tic4x_num_insts
; i
++)
1359 tic4x_inst_add (tic4x_insts
+ i
);
1361 /* Create dummy inst to avoid errors accessing end of table. */
1362 tic4x_inst_make ("", 0, "");
1364 /* Add registers to symbol table. */
1365 tic4x_init_regtable ();
1367 /* Add predefined symbols to symbol table. */
1368 tic4x_init_symbols ();
1374 bfd_set_arch_mach (stdoutput
, bfd_arch_tic4x
,
1375 IS_CPU_TIC4X (tic4x_cpu
) ? bfd_mach_tic4x
: bfd_mach_tic3x
);
1379 tic4x_indirect_parse (tic4x_operand_t
*operand
,
1380 const tic4x_indirect_t
*indirect
)
1382 const char *n
= indirect
->name
;
1383 char *s
= input_line_pointer
;
1393 case 'a': /* Need to match aux register. */
1395 #ifdef TIC4X_ALT_SYNTAX
1399 while (ISALNUM (*s
))
1402 if (!(symbolP
= symbol_find (name
)))
1405 if (S_GET_SEGMENT (symbolP
) != reg_section
)
1408 operand
->aregno
= S_GET_VALUE (symbolP
);
1409 if (operand
->aregno
>= REG_AR0
&& operand
->aregno
<= REG_AR7
)
1412 as_bad (_("Auxiliary register AR0--AR7 required for indirect"));
1415 case 'd': /* Need to match constant for disp. */
1416 #ifdef TIC4X_ALT_SYNTAX
1417 if (*s
== '%') /* expr() will die if we don't skip this. */
1420 s
= tic4x_expression (s
, &operand
->expr
);
1421 if (operand
->expr
.X_op
!= O_constant
)
1423 operand
->disp
= operand
->expr
.X_add_number
;
1424 if (operand
->disp
< 0 || operand
->disp
> 255)
1426 as_bad (_("Bad displacement %d (require 0--255)\n"),
1432 case 'y': /* Need to match IR0. */
1433 case 'z': /* Need to match IR1. */
1434 #ifdef TIC4X_ALT_SYNTAX
1438 s
= tic4x_expression (s
, &operand
->expr
);
1439 if (operand
->expr
.X_op
!= O_register
)
1441 if (operand
->expr
.X_add_number
!= REG_IR0
1442 && operand
->expr
.X_add_number
!= REG_IR1
)
1444 as_bad (_("Index register IR0,IR1 required for displacement"));
1448 if (*n
== 'y' && operand
->expr
.X_add_number
== REG_IR0
)
1450 if (*n
== 'z' && operand
->expr
.X_add_number
== REG_IR1
)
1455 if (*s
!= '(') /* No displacement, assume to be 1. */
1466 if (TOLOWER (*s
) != *n
)
1471 if (*s
!= ' ' && *s
!= ',' && *s
!= '\0')
1473 input_line_pointer
= s
;
1478 tic4x_operand_parse (char *s
, tic4x_operand_t
*operand
)
1483 expressionS
*exp
= &operand
->expr
;
1484 char *save
= input_line_pointer
;
1487 struct hash_entry
*entry
= NULL
;
1489 input_line_pointer
= s
;
1492 c
= get_symbol_name (&str
); /* Get terminator. */
1493 new_pointer
= input_line_pointer
;
1494 if (strlen (str
) && (entry
= str_hash_find (tic4x_asg_hash
, str
)) != NULL
)
1496 (void) restore_line_pointer (c
);
1497 input_line_pointer
= (char *) entry
;
1501 (void) restore_line_pointer (c
);
1502 input_line_pointer
= str
;
1505 operand
->mode
= M_UNKNOWN
;
1506 switch (*input_line_pointer
)
1508 #ifdef TIC4X_ALT_SYNTAX
1510 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1511 if (exp
->X_op
!= O_register
)
1512 as_bad (_("Expecting a register name"));
1513 operand
->mode
= M_REGISTER
;
1517 /* Denotes high 16 bits. */
1518 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1519 if (exp
->X_op
== O_constant
)
1520 operand
->mode
= M_IMMED
;
1521 else if (exp
->X_op
== O_big
)
1523 if (exp
->X_add_number
)
1524 as_bad (_("Number too large")); /* bignum required */
1527 tic4x_gen_to_words (generic_floating_point_number
,
1528 operand
->fwords
, S_PRECISION
);
1529 operand
->mode
= M_IMMED_F
;
1532 /* Allow ori ^foo, ar0 to be equivalent to ldi .hi.foo, ar0 */
1533 /* WARNING : The TI C40 assembler cannot do this. */
1534 else if (exp
->X_op
== O_symbol
)
1535 operand
->mode
= M_HI
;
1537 as_bad (_("Expecting a constant value"));
1541 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1542 if (exp
->X_op
== O_constant
)
1543 operand
->mode
= M_IMMED
;
1544 else if (exp
->X_op
== O_big
)
1546 if (exp
->X_add_number
> 0)
1547 as_bad (_("Number too large")); /* bignum required. */
1550 tic4x_gen_to_words (generic_floating_point_number
,
1551 operand
->fwords
, S_PRECISION
);
1552 operand
->mode
= M_IMMED_F
;
1555 /* Allow ori foo, ar0 to be equivalent to ldi .lo.foo, ar0 */
1556 /* WARNING : The TI C40 assembler cannot do this. */
1557 else if (exp
->X_op
== O_symbol
)
1558 operand
->mode
= M_IMMED
;
1560 as_bad (_("Expecting a constant value"));
1566 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1567 if (exp
->X_op
!= O_constant
&& exp
->X_op
!= O_symbol
)
1568 as_bad (_("Bad direct addressing construct %s"), s
);
1569 if (exp
->X_op
== O_constant
)
1571 if (exp
->X_add_number
< 0)
1572 as_bad (_("Direct value of %ld is not suitable"),
1573 (long) exp
->X_add_number
);
1575 operand
->mode
= M_DIRECT
;
1580 for (i
= 0; i
< tic4x_num_indirects
; i
++)
1581 if ((ret
= tic4x_indirect_parse (operand
, &tic4x_indirects
[i
])))
1585 if (i
< tic4x_num_indirects
)
1587 operand
->mode
= M_INDIRECT
;
1588 /* Indirect addressing mode number. */
1589 operand
->expr
.X_add_number
= tic4x_indirects
[i
].modn
;
1590 /* Convert *+ARn(0) to *ARn etc. Maybe we should
1591 squeal about silly ones? */
1592 if (operand
->expr
.X_add_number
< 0x08 && !operand
->disp
)
1593 operand
->expr
.X_add_number
= 0x18;
1596 as_bad (_("Unknown indirect addressing mode"));
1600 operand
->mode
= M_IMMED
; /* Assume immediate. */
1601 str
= input_line_pointer
;
1602 input_line_pointer
= tic4x_expression (input_line_pointer
, exp
);
1603 if (exp
->X_op
== O_register
)
1605 know (exp
->X_add_symbol
== 0);
1606 know (exp
->X_op_symbol
== 0);
1607 operand
->mode
= M_REGISTER
;
1610 else if (exp
->X_op
== O_big
)
1612 if (exp
->X_add_number
> 0)
1613 as_bad (_("Number too large")); /* bignum required. */
1616 tic4x_gen_to_words (generic_floating_point_number
,
1617 operand
->fwords
, S_PRECISION
);
1618 operand
->mode
= M_IMMED_F
;
1622 #ifdef TIC4X_ALT_SYNTAX
1623 /* Allow ldi foo, ar0 to be equivalent to ldi @foo, ar0. */
1624 else if (exp
->X_op
== O_symbol
)
1626 operand
->mode
= M_DIRECT
;
1632 new_pointer
= input_line_pointer
;
1633 input_line_pointer
= save
;
1638 tic4x_operands_match (tic4x_inst_t
*inst
, tic4x_insn_t
*tinsn
, int check
)
1640 const char *args
= inst
->args
;
1641 unsigned long opcode
= inst
->opcode
;
1642 int num_operands
= tinsn
->num_operands
;
1643 tic4x_operand_t
*operand
= tinsn
->operands
;
1644 expressionS
*exp
= &operand
->expr
;
1648 /* Build the opcode, checking as we go to make sure that the
1651 If an operand matches, we modify insn or opcode appropriately,
1652 and do a "continue". If an operand fails to match, we "break". */
1654 tinsn
->nchars
= 4; /* Instructions always 4 bytes. */
1655 tinsn
->reloc
= NO_RELOC
;
1660 tinsn
->opcode
= opcode
;
1661 return num_operands
== 0;
1669 case '\0': /* End of args. */
1670 if (num_operands
== 1)
1672 tinsn
->opcode
= opcode
;
1675 break; /* Too many operands. */
1677 case '#': /* This is only used for ldp. */
1678 if (operand
->mode
!= M_DIRECT
&& operand
->mode
!= M_IMMED
)
1680 /* While this looks like a direct addressing mode, we actually
1681 use an immediate mode form of ldiu or ldpk instruction. */
1682 if (exp
->X_op
== O_constant
)
1684 if( ( IS_CPU_TIC4X (tic4x_cpu
) && exp
->X_add_number
<= 65535 )
1685 || ( IS_CPU_TIC3X (tic4x_cpu
) && exp
->X_add_number
<= 255 ) )
1687 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1693 as_bad (_("Immediate value of %ld is too large for ldf"),
1694 (long) exp
->X_add_number
);
1699 else if (exp
->X_op
== O_symbol
)
1701 tinsn
->reloc
= BFD_RELOC_HI16
;
1705 break; /* Not direct (dp) addressing. */
1707 case '@': /* direct. */
1708 if (operand
->mode
!= M_DIRECT
)
1710 if (exp
->X_op
== O_constant
)
1712 /* Store only the 16 LSBs of the number. */
1713 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1716 else if (exp
->X_op
== O_symbol
)
1718 tinsn
->reloc
= BFD_RELOC_LO16
;
1722 break; /* Not direct addressing. */
1725 if (operand
->mode
!= M_REGISTER
)
1727 reg
= exp
->X_add_number
;
1728 if (reg
>= REG_AR0
&& reg
<= REG_AR7
)
1729 INSERTU (opcode
, reg
- REG_AR0
, 24, 22);
1733 as_bad (_("Destination register must be ARn"));
1738 case 'B': /* Unsigned integer immediate. */
1739 /* Allow br label or br @label. */
1740 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
1742 if (exp
->X_op
== O_constant
)
1744 if (exp
->X_add_number
< (1 << 24))
1746 INSERTU (opcode
, exp
->X_add_number
, 23, 0);
1752 as_bad (_("Immediate value of %ld is too large"),
1753 (long) exp
->X_add_number
);
1758 if (IS_CPU_TIC4X (tic4x_cpu
))
1760 tinsn
->reloc
= BFD_RELOC_24_PCREL
;
1765 tinsn
->reloc
= BFD_RELOC_24
;
1772 if (!IS_CPU_TIC4X (tic4x_cpu
))
1774 if (operand
->mode
!= M_INDIRECT
)
1776 /* Require either *+ARn(disp) or *ARn. */
1777 if (operand
->expr
.X_add_number
!= 0
1778 && operand
->expr
.X_add_number
!= 0x18)
1781 as_bad (_("Invalid indirect addressing mode"));
1785 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1786 INSERTU (opcode
, operand
->disp
, 7, 3);
1790 if (!(operand
->mode
== M_REGISTER
))
1792 INSERTU (opcode
, exp
->X_add_number
, 7, 0);
1796 if (!(operand
->mode
== M_REGISTER
))
1798 reg
= exp
->X_add_number
;
1799 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1800 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1801 INSERTU (opcode
, reg
, 7, 0);
1805 as_bad (_("Register must be Rn"));
1811 if (operand
->mode
!= M_IMMED_F
1812 && !(operand
->mode
== M_IMMED
&& exp
->X_op
== O_constant
))
1815 if (operand
->mode
!= M_IMMED_F
)
1817 /* OK, we 've got something like cmpf 0, r0
1818 Why can't they stick in a bloody decimal point ?! */
1821 /* Create floating point number string. */
1822 sprintf (string
, "%d.0", (int) exp
->X_add_number
);
1823 tic4x_atof (string
, 's', operand
->fwords
);
1826 INSERTU (opcode
, operand
->fwords
[0], 15, 0);
1830 if (operand
->mode
!= M_REGISTER
)
1832 INSERTU (opcode
, exp
->X_add_number
, 15, 8);
1836 if (operand
->mode
!= M_REGISTER
)
1838 reg
= exp
->X_add_number
;
1839 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1840 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1841 INSERTU (opcode
, reg
, 15, 8);
1845 as_bad (_("Register must be Rn"));
1851 if (operand
->mode
!= M_REGISTER
)
1853 reg
= exp
->X_add_number
;
1854 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1855 INSERTU (opcode
, reg
- REG_R0
, 18, 16);
1859 as_bad (_("Register must be R0--R7"));
1865 if ( operand
->mode
== M_REGISTER
1866 && tic4x_oplevel
& OP_ENH
)
1868 reg
= exp
->X_add_number
;
1869 INSERTU (opcode
, reg
, 4, 0);
1870 INSERTU (opcode
, 7, 7, 5);
1876 if (operand
->mode
!= M_INDIRECT
)
1878 if (operand
->disp
!= 0 && operand
->disp
!= 1)
1880 if (IS_CPU_TIC4X (tic4x_cpu
))
1883 as_bad (_("Invalid indirect addressing mode displacement %d"),
1888 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1889 INSERTU (opcode
, operand
->expr
.X_add_number
, 7, 3);
1893 if ( operand
->mode
== M_REGISTER
1894 && tic4x_oplevel
& OP_ENH
)
1896 reg
= exp
->X_add_number
;
1897 INSERTU (opcode
, reg
, 12, 8);
1898 INSERTU (opcode
, 7, 15, 13);
1904 if (operand
->mode
!= M_INDIRECT
)
1906 if (operand
->disp
!= 0 && operand
->disp
!= 1)
1908 if (IS_CPU_TIC4X (tic4x_cpu
))
1911 as_bad (_("Invalid indirect addressing mode displacement %d"),
1916 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
1917 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
1921 if (operand
->mode
!= M_REGISTER
)
1923 reg
= exp
->X_add_number
;
1924 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1925 INSERTU (opcode
, reg
- REG_R0
, 21, 19);
1929 as_bad (_("Register must be R0--R7"));
1935 if (operand
->mode
!= M_REGISTER
)
1937 reg
= exp
->X_add_number
;
1938 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1939 INSERTU (opcode
, reg
- REG_R0
, 24, 22);
1943 as_bad (_("Register must be R0--R7"));
1949 if (operand
->mode
!= M_REGISTER
)
1951 reg
= exp
->X_add_number
;
1952 if (reg
== REG_R2
|| reg
== REG_R3
)
1953 INSERTU (opcode
, reg
- REG_R2
, 22, 22);
1957 as_bad (_("Destination register must be R2 or R3"));
1963 if (operand
->mode
!= M_REGISTER
)
1965 reg
= exp
->X_add_number
;
1966 if (reg
== REG_R0
|| reg
== REG_R1
)
1967 INSERTU (opcode
, reg
- REG_R0
, 23, 23);
1971 as_bad (_("Destination register must be R0 or R1"));
1977 if (!IS_CPU_TIC4X (tic4x_cpu
))
1979 if (operand
->mode
!= M_INDIRECT
)
1981 /* Require either *+ARn(disp) or *ARn. */
1982 if (operand
->expr
.X_add_number
!= 0
1983 && operand
->expr
.X_add_number
!= 0x18)
1986 as_bad (_("Invalid indirect addressing mode"));
1990 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
1991 INSERTU (opcode
, operand
->disp
, 15, 11);
1994 case 'P': /* PC relative displacement. */
1995 /* Allow br label or br @label. */
1996 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
1998 if (exp
->X_op
== O_constant
)
2000 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 32767)
2002 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2008 as_bad (_("Displacement value of %ld is too large"),
2009 (long) exp
->X_add_number
);
2014 tinsn
->reloc
= BFD_RELOC_16_PCREL
;
2020 if (operand
->mode
!= M_REGISTER
)
2022 reg
= exp
->X_add_number
;
2023 INSERTU (opcode
, reg
, 15, 0);
2027 if (operand
->mode
!= M_REGISTER
)
2029 reg
= exp
->X_add_number
;
2030 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2031 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2032 INSERTU (opcode
, reg
, 15, 0);
2036 as_bad (_("Register must be Rn"));
2042 if (operand
->mode
!= M_REGISTER
)
2044 reg
= exp
->X_add_number
;
2045 INSERTU (opcode
, reg
, 20, 16);
2049 if (operand
->mode
!= M_REGISTER
)
2051 reg
= exp
->X_add_number
;
2052 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2053 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2054 INSERTU (opcode
, reg
, 20, 16);
2058 as_bad (_("Register must be Rn"));
2063 case 'S': /* Short immediate int. */
2064 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2066 if (exp
->X_op
== O_big
)
2069 as_bad (_("Floating point number not valid in expression"));
2073 if (exp
->X_op
== O_constant
)
2075 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 65535)
2077 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2083 as_bad (_("Signed immediate value %ld too large"),
2084 (long) exp
->X_add_number
);
2089 else if (exp
->X_op
== O_symbol
)
2091 if (operand
->mode
== M_HI
)
2093 tinsn
->reloc
= BFD_RELOC_HI16
;
2097 tinsn
->reloc
= BFD_RELOC_LO16
;
2102 /* Handle cases like ldi foo - $, ar0 where foo
2103 is a forward reference. Perhaps we should check
2104 for X_op == O_symbol and disallow things like
2106 tinsn
->reloc
= BFD_RELOC_16
;
2110 case 'T': /* 5-bit immediate value for tic4x stik. */
2111 if (!IS_CPU_TIC4X (tic4x_cpu
))
2113 if (operand
->mode
!= M_IMMED
)
2115 if (exp
->X_op
== O_constant
)
2117 if (exp
->X_add_number
< 16 && exp
->X_add_number
>= -16)
2119 INSERTS (opcode
, exp
->X_add_number
, 20, 16);
2125 as_bad (_("Immediate value of %ld is too large"),
2126 (long) exp
->X_add_number
);
2131 break; /* No relocations allowed. */
2133 case 'U': /* Unsigned integer immediate. */
2134 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2136 if (exp
->X_op
== O_constant
)
2138 if (exp
->X_add_number
< (1 << 16) && exp
->X_add_number
>= 0)
2140 INSERTU (opcode
, exp
->X_add_number
, 15, 0);
2146 as_bad (_("Unsigned immediate value %ld too large"),
2147 (long) exp
->X_add_number
);
2152 else if (exp
->X_op
== O_symbol
)
2154 if (operand
->mode
== M_HI
)
2155 tinsn
->reloc
= BFD_RELOC_HI16
;
2157 tinsn
->reloc
= BFD_RELOC_LO16
;
2162 tinsn
->reloc
= BFD_RELOC_16
;
2166 case 'V': /* Trap numbers (immediate field). */
2167 if (operand
->mode
!= M_IMMED
)
2169 if (exp
->X_op
== O_constant
)
2171 if (exp
->X_add_number
< 512 && IS_CPU_TIC4X (tic4x_cpu
))
2173 INSERTU (opcode
, exp
->X_add_number
, 8, 0);
2176 else if (exp
->X_add_number
< 32 && IS_CPU_TIC3X (tic4x_cpu
))
2178 INSERTU (opcode
, exp
->X_add_number
| 0x20, 5, 0);
2184 as_bad (_("Immediate value of %ld is too large"),
2185 (long) exp
->X_add_number
);
2190 break; /* No relocations allowed. */
2192 case 'W': /* Short immediate int (0--7). */
2193 if (!IS_CPU_TIC4X (tic4x_cpu
))
2195 if (operand
->mode
!= M_IMMED
)
2197 if (exp
->X_op
== O_big
)
2200 as_bad (_("Floating point number not valid in expression"));
2204 if (exp
->X_op
== O_constant
)
2206 if (exp
->X_add_number
>= -256 && exp
->X_add_number
<= 127)
2208 INSERTS (opcode
, exp
->X_add_number
, 7, 0);
2214 as_bad (_("Immediate value %ld too large"),
2215 (long) exp
->X_add_number
);
2220 tinsn
->reloc
= BFD_RELOC_16
;
2224 case 'X': /* Expansion register for tic4x. */
2225 if (operand
->mode
!= M_REGISTER
)
2227 reg
= exp
->X_add_number
;
2228 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2229 INSERTU (opcode
, reg
- REG_IVTP
, 4, 0);
2233 as_bad (_("Register must be ivtp or tvtp"));
2238 case 'Y': /* Address register for tic4x lda. */
2239 if (operand
->mode
!= M_REGISTER
)
2241 reg
= exp
->X_add_number
;
2242 if (reg
>= REG_AR0
&& reg
<= REG_SP
)
2243 INSERTU (opcode
, reg
, 20, 16);
2247 as_bad (_("Register must be address register"));
2252 case 'Z': /* Expansion register for tic4x. */
2253 if (operand
->mode
!= M_REGISTER
)
2255 reg
= exp
->X_add_number
;
2256 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2257 INSERTU (opcode
, reg
- REG_IVTP
, 20, 16);
2261 as_bad (_("Register must be ivtp or tvtp"));
2267 if (operand
->mode
!= M_INDIRECT
)
2269 INSERTS (opcode
, operand
->disp
, 7, 0);
2270 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2271 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
2274 case '|': /* treat as `,' if have ldi_ldi form. */
2275 if (tinsn
->parallel
)
2277 if (--num_operands
< 0)
2278 break; /* Too few operands. */
2280 if (operand
->mode
!= M_PARALLEL
)
2285 case ',': /* Another operand. */
2286 if (--num_operands
< 0)
2287 break; /* Too few operands. */
2289 exp
= &operand
->expr
;
2292 case ';': /* Another optional operand. */
2293 if (num_operands
== 1 || operand
[1].mode
== M_PARALLEL
)
2295 if (--num_operands
< 0)
2296 break; /* Too few operands. */
2298 exp
= &operand
->expr
;
2309 tic4x_insn_check (tic4x_insn_t
*tinsn
)
2312 if (!strcmp (tinsn
->name
, "lda"))
2314 if (tinsn
->num_operands
< 2 || tinsn
->num_operands
> 2)
2315 as_fatal ("Illegal internal LDA insn definition");
2317 if (tinsn
->operands
[0].mode
== M_REGISTER
2318 && tinsn
->operands
[1].mode
== M_REGISTER
2319 && tinsn
->operands
[0].expr
.X_add_number
== tinsn
->operands
[1].expr
.X_add_number
)
2320 as_bad (_("Source and destination register should not be equal"));
2322 else if (!strcmp (tinsn
->name
, "ldi_ldi")
2323 || !strcmp (tinsn
->name
, "ldi1_ldi2")
2324 || !strcmp (tinsn
->name
, "ldi2_ldi1")
2325 || !strcmp (tinsn
->name
, "ldf_ldf")
2326 || !strcmp (tinsn
->name
, "ldf1_ldf2")
2327 || !strcmp (tinsn
->name
, "ldf2_ldf1") )
2329 if (tinsn
->num_operands
< 4 || tinsn
->num_operands
> 5)
2330 as_fatal ("Illegal internal %s insn definition", tinsn
->name
);
2332 if (tinsn
->operands
[1].mode
== M_REGISTER
2333 && tinsn
->operands
[tinsn
->num_operands
-1].mode
== M_REGISTER
2334 && tinsn
->operands
[1].expr
.X_add_number
== tinsn
->operands
[tinsn
->num_operands
-1].expr
.X_add_number
)
2335 as_warn (_("Equal parallel destination registers, one result will be discarded"));
2340 tic4x_insn_output (tic4x_insn_t
*tinsn
)
2344 /* Grab another fragment for opcode. */
2345 dst
= frag_more (tinsn
->nchars
);
2347 /* Put out opcode word as a series of bytes in little endian order. */
2348 md_number_to_chars (dst
, tinsn
->opcode
, tinsn
->nchars
);
2350 /* Put out the symbol-dependent stuff. */
2351 if (tinsn
->reloc
!= NO_RELOC
)
2353 /* Where is the offset into the fragment for this instruction. */
2354 fix_new_exp (frag_now
,
2355 dst
- frag_now
->fr_literal
, /* where */
2356 tinsn
->nchars
, /* size */
2363 /* Parse the operands. */
2365 tic4x_operands_parse (char *s
, tic4x_operand_t
*operands
, int num_operands
)
2368 return num_operands
;
2371 s
= tic4x_operand_parse (s
, &operands
[num_operands
++]);
2372 while (num_operands
< TIC4X_OPERANDS_MAX
&& *s
++ == ',');
2374 if (num_operands
> TIC4X_OPERANDS_MAX
)
2376 as_bad (_("Too many operands scanned"));
2379 return num_operands
;
2382 /* Assemble a single instruction. Its label has already been handled
2383 by the generic front end. We just parse mnemonic and operands, and
2384 produce the bytes of data and relocation. */
2386 md_assemble (char *str
)
2393 tic4x_inst_t
*inst
; /* Instruction template. */
2394 tic4x_inst_t
*first_inst
;
2396 /* Scan for parallel operators */
2400 while (*s
&& *s
!= '|')
2403 if (*s
&& s
[1]=='|')
2407 as_bad (_("Parallel opcode cannot contain more than two instructions"));
2413 /* Lets take care of the first part of the parallel insn */
2418 /* .. and let the second run though here */
2422 if (str
&& insn
->parallel
)
2424 /* Find mnemonic (second part of parallel instruction). */
2426 /* Skip past instruction mnemonic. */
2427 while (*s
&& *s
!= ' ')
2429 if (*s
) /* Null terminate for str_hash_find. */
2430 *s
++ = '\0'; /* and skip past null. */
2431 len
= strlen (insn
->name
);
2432 snprintf (insn
->name
+ len
, TIC4X_NAME_MAX
- len
, "_%s", str
);
2434 insn
->operands
[insn
->num_operands
++].mode
= M_PARALLEL
;
2436 if ((i
= tic4x_operands_parse
2437 (s
, insn
->operands
, insn
->num_operands
)) < 0)
2443 insn
->num_operands
= i
;
2449 if ((insn
->inst
= (struct tic4x_inst
*)
2450 str_hash_find (tic4x_op_hash
, insn
->name
)) == NULL
)
2452 as_bad (_("Unknown opcode `%s'."), insn
->name
);
2462 ok
= tic4x_operands_match (inst
, insn
, 1);
2470 while (!ok
&& !strcmp (inst
->name
, inst
[1].name
) && inst
++);
2474 tic4x_insn_check (insn
);
2475 tic4x_insn_output (insn
);
2480 tic4x_operands_match (first_inst
, insn
, 0);
2481 as_bad (_("Invalid operands for %s"), insn
->name
);
2484 as_bad (_("Invalid instruction %s"), insn
->name
);
2489 /* Find mnemonic. */
2491 while (*s
&& *s
!= ' ') /* Skip past instruction mnemonic. */
2493 if (*s
) /* Null terminate for str_hash_find. */
2494 *s
++ = '\0'; /* and skip past null. */
2495 strncpy (insn
->name
, str
, TIC4X_NAME_MAX
- 1);
2496 insn
->name
[TIC4X_NAME_MAX
- 1] = '\0';
2498 if ((i
= tic4x_operands_parse (s
, insn
->operands
, 0)) < 0)
2500 insn
->inst
= NULL
; /* Flag that error occurred. */
2505 insn
->num_operands
= i
;
2514 tic4x_cleanup (void)
2520 /* Turn a string in input_line_pointer into a floating point constant
2521 of type type, and store the appropriate bytes in *litP. The number
2522 of chars emitted is stored in *sizeP. An error message is
2523 returned, or NULL on OK. */
2526 md_atof (int type
, char *litP
, int *sizeP
)
2530 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2531 LITTLENUM_TYPE
*wordP
;
2536 case 's': /* .single */
2542 case 'd': /* .double */
2544 case 'f': /* .float */
2547 prec
= 2; /* 1 32-bit word */
2550 case 'i': /* .ieee */
2554 type
= 'f'; /* Rewrite type to be usable by atof_ieee(). */
2557 case 'e': /* .ldouble */
2559 prec
= 4; /* 2 32-bit words */
2565 return _("Unrecognized or unsupported floating point constant");
2569 t
= atof_ieee (input_line_pointer
, type
, words
);
2571 t
= tic4x_atof (input_line_pointer
, type
, words
);
2573 input_line_pointer
= t
;
2574 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
2576 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
2577 little endian byte order. */
2578 /* SES: However it is required to put the words (32-bits) out in the
2579 correct order, hence we write 2 and 2 littlenums in little endian
2580 order, while we keep the original order on successive words. */
2581 for (wordP
= words
; wordP
<(words
+prec
) ; wordP
+=2)
2583 if (wordP
< (words
+ prec
- 1)) /* Dump wordP[1] (if we have one). */
2585 md_number_to_chars (litP
, (valueT
) (wordP
[1]),
2586 sizeof (LITTLENUM_TYPE
));
2587 litP
+= sizeof (LITTLENUM_TYPE
);
2591 md_number_to_chars (litP
, (valueT
) (wordP
[0]),
2592 sizeof (LITTLENUM_TYPE
));
2593 litP
+= sizeof (LITTLENUM_TYPE
);
2599 md_apply_fix (fixS
*fixP
, valueT
*value
, segT seg ATTRIBUTE_UNUSED
)
2601 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
2602 valueT val
= *value
;
2604 switch (fixP
->fx_r_type
)
2606 case BFD_RELOC_HI16
:
2610 case BFD_RELOC_LO16
:
2617 switch (fixP
->fx_r_type
)
2623 case BFD_RELOC_24_PCREL
:
2627 case BFD_RELOC_16_PCREL
:
2628 case BFD_RELOC_LO16
:
2629 case BFD_RELOC_HI16
:
2636 as_bad (_("Bad relocation type: 0x%02x"), fixP
->fx_r_type
);
2640 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0) fixP
->fx_done
= 1;
2643 /* Should never be called for tic4x. */
2645 md_convert_frag (bfd
*headers ATTRIBUTE_UNUSED
,
2646 segT sec ATTRIBUTE_UNUSED
,
2647 fragS
*fragP ATTRIBUTE_UNUSED
)
2649 as_fatal ("md_convert_frag");
2652 /* Should never be called for tic4x. */
2654 md_create_short_jump (char *ptr ATTRIBUTE_UNUSED
,
2655 addressT from_addr ATTRIBUTE_UNUSED
,
2656 addressT to_addr ATTRIBUTE_UNUSED
,
2657 fragS
*frag ATTRIBUTE_UNUSED
,
2658 symbolS
*to_symbol ATTRIBUTE_UNUSED
)
2660 as_fatal ("md_create_short_jmp\n");
2663 /* Should never be called for tic4x. */
2665 md_create_long_jump (char *ptr ATTRIBUTE_UNUSED
,
2666 addressT from_addr ATTRIBUTE_UNUSED
,
2667 addressT to_addr ATTRIBUTE_UNUSED
,
2668 fragS
*frag ATTRIBUTE_UNUSED
,
2669 symbolS
*to_symbol ATTRIBUTE_UNUSED
)
2671 as_fatal ("md_create_long_jump\n");
2674 /* Should never be called for tic4x. */
2676 md_estimate_size_before_relax (fragS
*fragP ATTRIBUTE_UNUSED
,
2677 segT segtype ATTRIBUTE_UNUSED
)
2679 as_fatal ("md_estimate_size_before_relax\n");
2685 md_parse_option (int c
, const char *arg
)
2689 case OPTION_CPU
: /* cpu brand */
2690 if (TOLOWER (*arg
) == 'c')
2692 tic4x_cpu
= atoi (arg
);
2693 if (!IS_CPU_TIC3X (tic4x_cpu
) && !IS_CPU_TIC4X (tic4x_cpu
))
2694 as_warn (_("Unsupported processor generation %d"), tic4x_cpu
);
2697 case OPTION_REV
: /* cpu revision */
2698 tic4x_revision
= atoi (arg
);
2702 as_warn (_("Option -b is depreciated, please use -mbig"));
2704 case OPTION_BIG
: /* big model */
2705 tic4x_big_model
= 1;
2709 as_warn (_("Option -p is depreciated, please use -mmemparm"));
2711 case OPTION_MEMPARM
: /* push args */
2716 as_warn (_("Option -r is depreciated, please use -mregparm"));
2718 case OPTION_REGPARM
: /* register args */
2723 as_warn (_("Option -s is depreciated, please use -msmall"));
2725 case OPTION_SMALL
: /* small model */
2726 tic4x_big_model
= 0;
2733 case OPTION_LOWPOWER
:
2737 case OPTION_ENHANCED
:
2749 md_show_usage (FILE *stream
)
2752 _("\nTIC4X options:\n"
2753 " -mcpu=CPU -mCPU select architecture variant. CPU can be:\n"
2755 " 31 - TMS320C31, TMS320LC31\n"
2757 " 33 - TMS320VC33\n"
2760 " -mrev=REV set cpu hardware revision (integer numbers).\n"
2761 " Combinations of -mcpu and -mrev will enable/disable\n"
2762 " the appropriate options (-midle2, -mlowpower and\n"
2763 " -menhanced) according to the selected type\n"
2764 " -mbig select big memory model\n"
2765 " -msmall select small memory model (default)\n"
2766 " -mregparm select register parameters (default)\n"
2767 " -mmemparm select memory parameters\n"
2768 " -midle2 enable IDLE2 support\n"
2769 " -mlowpower enable LOPOWER and MAXSPEED support\n"
2770 " -menhanced enable enhanced opcode support\n"));
2773 /* This is called when a line is unrecognized. This is used to handle
2774 definitions of TI C3x tools style local labels $n where n is a single
2777 tic4x_unrecognized_line (int c
)
2782 if (c
!= '$' || ! ISDIGIT (input_line_pointer
[0]))
2785 s
= input_line_pointer
;
2787 /* Let's allow multiple digit local labels. */
2789 while (ISDIGIT (*s
))
2791 lab
= lab
* 10 + *s
- '0';
2795 if (dollar_label_defined (lab
))
2797 as_bad (_("Label \"$%d\" redefined"), lab
);
2801 define_dollar_label (lab
);
2802 colon (dollar_label_name (lab
, 0));
2803 input_line_pointer
= s
+ 1;
2808 /* Handle local labels peculiar to us referred to in an expression. */
2810 md_undefined_symbol (char *name
)
2812 /* Look for local labels of the form $n. */
2813 if (name
[0] == '$' && ISDIGIT (name
[1]))
2819 while (ISDIGIT ((unsigned char) *s
))
2821 lab
= lab
* 10 + *s
- '0';
2824 if (dollar_label_defined (lab
))
2826 name
= dollar_label_name (lab
, 0);
2827 symbolP
= symbol_find (name
);
2831 name
= dollar_label_name (lab
, 1);
2832 symbolP
= symbol_find_or_make (name
);
2840 /* Parse an operand that is machine-specific. */
2842 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
2846 /* Round up a section size to the appropriate boundary---do we need this? */
2848 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
2850 return size
; /* Byte (i.e., 32-bit) alignment is fine? */
2854 tic4x_pc_offset (unsigned int op
)
2856 /* Determine the PC offset for a C[34]x instruction.
2857 This could be simplified using some boolean algebra
2858 but at the expense of readability. */
2862 case 0x62: /* call (C4x) */
2863 case 0x64: /* rptb (C4x) */
2865 case 0x61: /* brd */
2866 case 0x63: /* laj */
2867 case 0x65: /* rptbd (C4x) */
2869 case 0x66: /* swi */
2876 switch ((op
& 0xffe00000) >> 20)
2878 case 0x6a0: /* bB */
2879 case 0x720: /* callB */
2880 case 0x740: /* trapB */
2883 case 0x6a2: /* bBd */
2884 case 0x6a6: /* bBat */
2885 case 0x6aa: /* bBaf */
2886 case 0x722: /* lajB */
2887 case 0x748: /* latB */
2888 case 0x798: /* rptbd */
2895 switch ((op
& 0xfe200000) >> 20)
2897 case 0x6e0: /* dbB */
2900 case 0x6e2: /* dbBd */
2910 /* Exactly what point is a PC-relative offset relative TO?
2911 With the C3x we have the following:
2912 DBcond, Bcond disp + PC + 1 => PC
2913 DBcondD, BcondD disp + PC + 3 => PC
2916 md_pcrel_from (fixS
*fixP
)
2921 buf
= (unsigned char *) fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2922 op
= ((unsigned) buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
2924 return ((fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) >> 2) +
2925 tic4x_pc_offset (op
);
2928 /* Fill the alignment area with NOP's on .text, unless fill-data
2931 tic4x_do_align (int alignment
,
2936 /* Because we are talking lwords, not bytes, adjust alignment to do words */
2939 if (alignment
!= 0 && !need_pass_2
)
2943 if (subseg_text_p (now_seg
))
2947 md_number_to_chars (nop
, TIC_NOP_OPCODE
, 4);
2948 frag_align_pattern (alignment
, nop
, sizeof (nop
), max
);
2951 frag_align (alignment
, 0, max
);
2954 frag_align (alignment
, *fill
, max
);
2956 frag_align_pattern (alignment
, fill
, len
, max
);
2959 /* Return 1 to skip the default alignment function */
2963 /* Look for and remove parallel instruction operator ||. */
2965 tic4x_start_line (void)
2967 char *s
= input_line_pointer
;
2971 /* If parallel instruction prefix found at start of line, skip it. */
2972 if (*input_line_pointer
== '|' && input_line_pointer
[1] == '|')
2977 input_line_pointer
++;
2978 *input_line_pointer
= ' ';
2979 /* So line counters get bumped. */
2980 input_line_pointer
[-1] = '\n';
2985 /* Write out the previous insn here */
2988 input_line_pointer
= s
;
2993 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixP
)
2997 reloc
= XNEW (arelent
);
2999 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
3000 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
3001 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
3002 reloc
->address
/= OCTETS_PER_BYTE
;
3003 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
3004 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
3006 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3007 _("Reloc %d not supported by object file format"),
3008 (int) fixP
->fx_r_type
);
3012 if (fixP
->fx_r_type
== BFD_RELOC_HI16
)
3013 reloc
->addend
= fixP
->fx_offset
;
3015 reloc
->addend
= fixP
->fx_addnumber
;