1 /* tc-tic4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
2 Copyright (C) 1997-2016 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 /* Equal to MAX_PRECISION in atof-ieee.c. */
56 #define MAX_LITTLENUMS 6 /* (12 bytes) */
58 /* Handle of the inst mnemonic hash table. */
59 static struct hash_control
*tic4x_op_hash
= NULL
;
61 /* Handle asg pseudo. */
62 static struct hash_control
*tic4x_asg_hash
= NULL
;
64 static unsigned int tic4x_cpu
= 0; /* Default to TMS320C40. */
65 static unsigned int tic4x_revision
= 0; /* CPU revision */
66 static unsigned int tic4x_idle2
= 0; /* Idle2 support */
67 static unsigned int tic4x_lowpower
= 0; /* Lowpower support */
68 static unsigned int tic4x_enhanced
= 0; /* Enhanced opcode support */
69 static unsigned int tic4x_big_model
= 0; /* Default to small memory model. */
70 static unsigned int tic4x_reg_args
= 0; /* Default to args passed on stack. */
71 static unsigned long tic4x_oplevel
= 0; /* Opcode level */
73 #define OPTION_CPU 'm'
74 #define OPTION_BIG (OPTION_MD_BASE + 1)
75 #define OPTION_SMALL (OPTION_MD_BASE + 2)
76 #define OPTION_MEMPARM (OPTION_MD_BASE + 3)
77 #define OPTION_REGPARM (OPTION_MD_BASE + 4)
78 #define OPTION_IDLE2 (OPTION_MD_BASE + 5)
79 #define OPTION_LOWPOWER (OPTION_MD_BASE + 6)
80 #define OPTION_ENHANCED (OPTION_MD_BASE + 7)
81 #define OPTION_REV (OPTION_MD_BASE + 8)
83 const char *md_shortopts
= "bm:prs";
84 struct option md_longopts
[] =
86 { "mcpu", required_argument
, NULL
, OPTION_CPU
},
87 { "mdsp", required_argument
, NULL
, OPTION_CPU
},
88 { "mbig", no_argument
, NULL
, OPTION_BIG
},
89 { "msmall", no_argument
, NULL
, OPTION_SMALL
},
90 { "mmemparm", no_argument
, NULL
, OPTION_MEMPARM
},
91 { "mregparm", no_argument
, NULL
, OPTION_REGPARM
},
92 { "midle2", no_argument
, NULL
, OPTION_IDLE2
},
93 { "mlowpower", no_argument
, NULL
, OPTION_LOWPOWER
},
94 { "menhanced", no_argument
, NULL
, OPTION_ENHANCED
},
95 { "mrev", required_argument
, NULL
, OPTION_REV
},
96 { NULL
, no_argument
, NULL
, 0 }
99 size_t md_longopts_size
= sizeof (md_longopts
);
104 M_UNKNOWN
, M_IMMED
, M_DIRECT
, M_REGISTER
, M_INDIRECT
,
105 M_IMMED_F
, M_PARALLEL
, M_HI
109 typedef struct tic4x_operand
111 tic4x_addr_mode_t mode
; /* Addressing mode. */
112 expressionS expr
; /* Expression. */
113 int disp
; /* Displacement for indirect addressing. */
114 int aregno
; /* Aux. register number. */
115 LITTLENUM_TYPE fwords
[MAX_LITTLENUMS
]; /* Float immed. number. */
119 typedef struct tic4x_insn
121 char name
[TIC4X_NAME_MAX
]; /* Mnemonic of instruction. */
122 unsigned int in_use
; /* True if in_use. */
123 unsigned int parallel
; /* True if parallel instruction. */
124 unsigned int nchars
; /* This is always 4 for the C30. */
125 unsigned long opcode
; /* Opcode number. */
126 expressionS exp
; /* Expression required for relocation. */
127 int reloc
; /* Relocation type required. */
128 int pcrel
; /* True if relocation PC relative. */
129 char *pname
; /* Name of instruction in parallel. */
130 unsigned int num_operands
; /* Number of operands in total. */
131 tic4x_inst_t
*inst
; /* Pointer to first template. */
132 tic4x_operand_t operands
[TIC4X_OPERANDS_MAX
];
136 static tic4x_insn_t the_insn
; /* Info about our instruction. */
137 static tic4x_insn_t
*insn
= &the_insn
;
139 static void tic4x_asg (int);
140 static void tic4x_bss (int);
141 static void tic4x_globl (int);
142 static void tic4x_cons (int);
143 static void tic4x_stringer (int);
144 static void tic4x_eval (int);
145 static void tic4x_newblock (int);
146 static void tic4x_sect (int);
147 static void tic4x_set (int);
148 static void tic4x_usect (int);
149 static void tic4x_version (int);
155 {"align", s_align_bytes
, 32},
156 {"ascii", tic4x_stringer
, 1},
157 {"asciz", tic4x_stringer
, 0},
158 {"asg", tic4x_asg
, 0},
159 {"block", s_space
, 4},
160 {"byte", tic4x_cons
, 1},
161 {"bss", tic4x_bss
, 0},
162 {"copy", s_include
, 0},
163 {"def", tic4x_globl
, 0},
164 {"equ", tic4x_set
, 0},
165 {"eval", tic4x_eval
, 0},
166 {"global", tic4x_globl
, 0},
167 {"globl", tic4x_globl
, 0},
168 {"hword", tic4x_cons
, 2},
169 {"ieee", float_cons
, 'i'},
170 {"int", tic4x_cons
, 4}, /* .int allocates 4 bytes. */
171 {"ldouble", float_cons
, 'e'},
172 {"newblock", tic4x_newblock
, 0},
173 {"ref", s_ignore
, 0}, /* All undefined treated as external. */
174 {"set", tic4x_set
, 0},
175 {"sect", tic4x_sect
, 1}, /* Define named section. */
176 {"space", s_space
, 4},
177 {"string", tic4x_stringer
, 0},
178 {"usect", tic4x_usect
, 0}, /* Reserve space in uninit. named sect. */
179 {"version", tic4x_version
, 0},
180 {"word", tic4x_cons
, 4}, /* .word allocates 4 bytes. */
181 {"xdef", tic4x_globl
, 0},
185 int md_short_jump_size
= 4;
186 int md_long_jump_size
= 4;
188 /* This array holds the chars that always start a comment. If the
189 pre-processor is disabled, these aren't very useful. */
190 #ifdef TIC4X_ALT_SYNTAX
191 const char comment_chars
[] = ";!";
193 const char comment_chars
[] = ";";
196 /* This array holds the chars that only start a comment at the beginning of
197 a line. If the line seems to have the form '# 123 filename'
198 .line and .file directives will appear in the pre-processed output.
199 Note that input_file.c hand checks for '#' at the beginning of the
200 first line of the input file. This is because the compiler outputs
201 #NO_APP at the beginning of its output.
202 Also note that comments like this one will always work. */
203 const char line_comment_chars
[] = "#*";
205 /* We needed an unused char for line separation to work around the
206 lack of macros, using sed and such. */
207 const char line_separator_chars
[] = "&";
209 /* Chars that can be used to separate mant from exp in floating point nums. */
210 const char EXP_CHARS
[] = "eE";
212 /* Chars that mean this number is a floating point constant. */
215 const char FLT_CHARS
[] = "fFilsS";
217 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
218 changed in read.c. Ideally it shouldn't have to know about it at
219 all, but nothing is ideal around here. */
221 /* Flonums returned here. */
222 extern FLONUM_TYPE generic_floating_point_number
;
224 /* Precision in LittleNums. */
225 #define MAX_PRECISION (4) /* Its a bit overkill for us, but the code
227 #define S_PRECISION (1) /* Short float constants 16-bit. */
228 #define F_PRECISION (2) /* Float and double types 32-bit. */
229 #define E_PRECISION (4) /* Extended precision, 64-bit (real 40-bit). */
232 /* Turn generic_floating_point_number into a real short/float/double. */
234 tic4x_gen_to_words (FLONUM_TYPE flonum
, LITTLENUM_TYPE
*words
, int precision
)
236 int return_value
= 0;
237 LITTLENUM_TYPE
*p
; /* Littlenum pointer. */
238 int mantissa_bits
; /* Bits in mantissa field. */
239 int exponent_bits
; /* Bits in exponent field. */
241 unsigned int sone
; /* Scaled one. */
242 unsigned int sfract
; /* Scaled fraction. */
243 unsigned int smant
; /* Scaled mantissa. */
245 unsigned int mover
; /* Mantissa overflow bits */
246 unsigned int rbit
; /* Round bit. */
247 int shift
; /* Shift count. */
249 /* NOTE: Svein Seldal <Svein@dev.seldal.com>
250 The code in this function is altered slightly to support floats
251 with 31-bits mantissas, thus the documentation below may be a
252 little bit inaccurate.
254 By Michael P. Hayes <m.hayes@elec.canterbury.ac.nz>
255 Here is how a generic floating point number is stored using
256 flonums (an extension of bignums) where p is a pointer to an
259 For example 2e-3 is stored with exp = -4 and
266 with low = &bits[2], high = &bits[5], and leader = &bits[5].
268 This number can be written as
269 0x0083126e978d4fde.00000000 * 65536**-4 or
270 0x0.0083126e978d4fde * 65536**0 or
271 0x0.83126e978d4fde * 2**-8 = 2e-3
273 Note that low points to the 65536**0 littlenum (bits[2]) and
274 leader points to the most significant non-zero littlenum
277 TMS320C3X floating point numbers are a bit of a strange beast.
278 The 32-bit flavour has the 8 MSBs representing the exponent in
279 twos complement format (-128 to +127). There is then a sign bit
280 followed by 23 bits of mantissa. The mantissa is expressed in
281 twos complement format with the binary point after the most
282 significant non sign bit. The bit after the binary point is
283 suppressed since it is the complement of the sign bit. The
284 effective mantissa is thus 24 bits. Zero is represented by an
287 The 16-bit flavour has the 4 MSBs representing the exponent in
288 twos complement format (-8 to +7). There is then a sign bit
289 followed by 11 bits of mantissa. The mantissa is expressed in
290 twos complement format with the binary point after the most
291 significant non sign bit. The bit after the binary point is
292 suppressed since it is the complement of the sign bit. The
293 effective mantissa is thus 12 bits. Zero is represented by an
294 exponent of -8. For example,
296 number norm mant m x e s i fraction f
297 +0.500 => 1.00000000000 -1 -1 0 1 .00000000000 (1 + 0) * 2^(-1)
298 +0.999 => 1.11111111111 -1 -1 0 1 .11111111111 (1 + 0.99) * 2^(-1)
299 +1.000 => 1.00000000000 0 0 0 1 .00000000000 (1 + 0) * 2^(0)
300 +1.500 => 1.10000000000 0 0 0 1 .10000000000 (1 + 0.5) * 2^(0)
301 +1.999 => 1.11111111111 0 0 0 1 .11111111111 (1 + 0.9) * 2^(0)
302 +2.000 => 1.00000000000 1 1 0 1 .00000000000 (1 + 0) * 2^(1)
303 +4.000 => 1.00000000000 2 2 0 1 .00000000000 (1 + 0) * 2^(2)
304 -0.500 => 1.00000000000 -1 -1 1 0 .10000000000 (-2 + 0) * 2^(-2)
305 -1.000 => 1.00000000000 0 -1 1 0 .00000000000 (-2 + 0) * 2^(-1)
306 -1.500 => 1.10000000000 0 0 1 0 .10000000000 (-2 + 0.5) * 2^(0)
307 -1.999 => 1.11111111111 0 0 1 0 .00000000001 (-2 + 0.11) * 2^(0)
308 -2.000 => 1.00000000000 1 1 1 0 .00000000000 (-2 + 0) * 2^(0)
309 -4.000 => 1.00000000000 2 1 1 0 .00000000000 (-2 + 0) * 2^(1)
311 where e is the exponent, s is the sign bit, i is the implied bit,
312 and f is the fraction stored in the mantissa field.
314 num = (1 + f) * 2^x = m * 2^e if s = 0
315 num = (-2 + f) * 2^x = -m * 2^e if s = 1
316 where 0 <= f < 1.0 and 1.0 <= m < 2.0
318 The fraction (f) and exponent (e) fields for the TMS320C3X format
319 can be derived from the normalised mantissa (m) and exponent (x) using:
321 f = m - 1, e = x if s = 0
322 f = 2 - m, e = x if s = 1 and m != 1.0
323 f = 0, e = x - 1 if s = 1 and m = 1.0
324 f = 0, e = -8 if m = 0
327 OK, the other issue we have to consider is rounding since the
328 mantissa has a much higher potential precision than what we can
329 represent. To do this we add half the smallest storable fraction.
330 We then have to renormalise the number to allow for overflow.
332 To convert a generic flonum into a TMS320C3X floating point
333 number, here's what we try to do....
335 The first thing is to generate a normalised mantissa (m) where
336 1.0 <= m < 2 and to convert the exponent from base 16 to base 2.
337 We desire the binary point to be placed after the most significant
338 non zero bit. This process is done in two steps: firstly, the
339 littlenum with the most significant non zero bit is located (this
340 is done for us since leader points to this littlenum) and the
341 binary point (which is currently after the LSB of the littlenum
342 pointed to by low) is moved to before the MSB of the littlenum
343 pointed to by leader. This requires the exponent to be adjusted
344 by leader - low + 1. In the earlier example, the new exponent is
345 thus -4 + (5 - 2 + 1) = 0 (base 65536). We now need to convert
346 the exponent to base 2 by multiplying the exponent by 16 (log2
347 65536). The exponent base 2 is thus also zero.
349 The second step is to hunt for the most significant non zero bit
350 in the leader littlenum. We do this by left shifting a copy of
351 the leader littlenum until bit 16 is set (0x10000) and counting
352 the number of shifts, S, required. The number of shifts then has to
353 be added to correct the exponent (base 2). For our example, this
354 will require 9 shifts and thus our normalised exponent (base 2) is
355 0 + 9 = 9. Note that the worst case scenario is when the leader
356 littlenum is 1, thus requiring 16 shifts.
358 We now have to left shift the other littlenums by the same amount,
359 propagating the shifted bits into the more significant littlenums.
360 To save a lot of unnecessary shifting we only have to consider
361 two or three littlenums, since the greatest number of mantissa
362 bits required is 24 + 1 rounding bit. While two littlenums
363 provide 32 bits of precision, the most significant littlenum
364 may only contain a single significant bit and thus an extra
365 littlenum is required.
367 Denoting the number of bits in the fraction field as F, we require
368 G = F + 2 bits (one extra bit is for rounding, the other gets
369 suppressed). Say we required S shifts to find the most
370 significant bit in the leader littlenum, the number of left shifts
371 required to move this bit into bit position G - 1 is L = G + S - 17.
372 Note that this shift count may be negative for the short floating
373 point flavour (where F = 11 and thus G = 13 and potentially S < 3).
374 If L > 0 we have to shunt the next littlenum into position. Bit
375 15 (the MSB) of the next littlenum needs to get moved into position
376 L - 1 (If L > 15 we need all the bits of this littlenum and
377 some more from the next one.). We subtract 16 from L and use this
378 as the left shift count; the resultant value we or with the
379 previous result. If L > 0, we repeat this operation. */
381 if (precision
!= S_PRECISION
)
383 if (precision
== E_PRECISION
)
384 words
[2] = words
[3] = 0x0000;
386 /* 0.0e0 or NaN seen. */
387 if (flonum
.low
> flonum
.leader
/* = 0.0e0 */
388 || flonum
.sign
== 0) /* = NaN */
391 as_bad (_("Nan, using zero."));
396 if (flonum
.sign
== 'P')
398 /* +INF: Replace with maximum float. */
399 if (precision
== S_PRECISION
)
406 if (precision
== E_PRECISION
)
413 else if (flonum
.sign
== 'N')
415 /* -INF: Replace with maximum float. */
416 if (precision
== S_PRECISION
)
420 if (precision
== E_PRECISION
)
425 exponent
= (flonum
.exponent
+ flonum
.leader
- flonum
.low
+ 1) * 16;
427 if (!(tmp
= *flonum
.leader
))
428 abort (); /* Hmmm. */
429 shift
= 0; /* Find position of first sig. bit. */
432 exponent
-= (16 - shift
); /* Adjust exponent. */
434 if (precision
== S_PRECISION
) /* Allow 1 rounding bit. */
439 else if(precision
== F_PRECISION
)
444 else /* E_PRECISION */
450 shift
= mantissa_bits
- shift
;
455 /* Store the mantissa data into smant and the roundbit into rbit */
456 for (p
= flonum
.leader
; p
>= flonum
.low
&& shift
> -16; p
--)
458 tmp
= shift
>= 0 ? *p
<< shift
: *p
>> -shift
;
459 rbit
= shift
< 0 ? ((*p
>> (-shift
-1)) & 0x1) : 0;
464 /* OK, we've got our scaled mantissa so let's round it up */
467 /* If the mantissa is going to overflow when added, lets store
468 the extra bit in mover. -- A special case exists when
469 mantissa_bits is 31 (E_PRECISION). Then the first test cannot
470 be trusted, as result is host-dependent, thus the second
472 if( smant
== ((unsigned)(1<<(mantissa_bits
+1))-1)
473 || smant
== (unsigned)-1 ) /* This is to catch E_PRECISION cases */
478 /* Get the scaled one value */
479 sone
= (1 << (mantissa_bits
));
481 /* The number may be unnormalised so renormalise it... */
485 smant
|= sone
; /* Insert the bit from mover into smant */
489 /* The binary point is now between bit positions 11 and 10 or 23 and 22,
490 i.e., between mantissa_bits - 1 and mantissa_bits - 2 and the
491 bit at mantissa_bits - 1 should be set. */
493 abort (); /* Ooops. */
495 if (flonum
.sign
== '+')
496 sfract
= smant
- sone
; /* smant - 1.0. */
499 /* This seems to work. */
507 sfract
= -smant
& (sone
-1); /* 2.0 - smant. */
509 sfract
|= sone
; /* Insert sign bit. */
512 if (abs (exponent
) >= (1 << (exponent_bits
- 1)))
513 as_bad (_("Cannot represent exponent in %d bits"), exponent_bits
);
515 /* Force exponent to fit in desired field width. */
516 exponent
&= (1 << (exponent_bits
)) - 1;
518 if (precision
== E_PRECISION
)
520 /* Map the float part first (100% equal format as F_PRECISION) */
521 words
[0] = exponent
<< (mantissa_bits
+1-24);
522 words
[0] |= sfract
>> 24;
523 words
[1] = sfract
>> 8;
525 /* Map the mantissa in the next */
526 words
[2] = sfract
>> 16;
527 words
[3] = sfract
& 0xffff;
531 /* Insert the exponent data into the word */
532 sfract
|= exponent
<< (mantissa_bits
+1);
534 if (precision
== S_PRECISION
)
538 words
[0] = sfract
>> 16;
539 words
[1] = sfract
& 0xffff;
546 /* Returns pointer past text consumed. */
548 tic4x_atof (char *str
, char what_kind
, LITTLENUM_TYPE
*words
)
550 /* Extra bits for zeroed low-order bits. The 1st MAX_PRECISION are
551 zeroed, the last contain flonum bits. */
552 static LITTLENUM_TYPE bits
[MAX_PRECISION
+ MAX_PRECISION
+ GUARD
];
554 /* Number of 16-bit words in the format. */
556 FLONUM_TYPE save_gen_flonum
;
558 /* We have to save the generic_floating_point_number because it
559 contains storage allocation about the array of LITTLENUMs where
560 the value is actually stored. We will allocate our own array of
561 littlenums below, but have to restore the global one on exit. */
562 save_gen_flonum
= generic_floating_point_number
;
565 generic_floating_point_number
.low
= bits
+ MAX_PRECISION
;
566 generic_floating_point_number
.high
= NULL
;
567 generic_floating_point_number
.leader
= NULL
;
568 generic_floating_point_number
.exponent
= 0;
569 generic_floating_point_number
.sign
= '\0';
571 /* Use more LittleNums than seems necessary: the highest flonum may
572 have 15 leading 0 bits, so could be useless. */
574 memset (bits
, '\0', sizeof (LITTLENUM_TYPE
) * MAX_PRECISION
);
580 precision
= S_PRECISION
;
587 precision
= F_PRECISION
;
592 precision
= E_PRECISION
;
596 as_bad (_("Invalid floating point number"));
600 generic_floating_point_number
.high
601 = generic_floating_point_number
.low
+ precision
- 1 + GUARD
;
603 if (atof_generic (&return_value
, ".", EXP_CHARS
,
604 &generic_floating_point_number
))
606 as_bad (_("Invalid floating point number"));
610 tic4x_gen_to_words (generic_floating_point_number
,
613 /* Restore the generic_floating_point_number's storage alloc (and
615 generic_floating_point_number
= save_gen_flonum
;
621 tic4x_insert_reg (char *regname
, int regnum
)
626 symbol_table_insert (symbol_new (regname
, reg_section
, (valueT
) regnum
,
627 &zero_address_frag
));
628 for (i
= 0; regname
[i
]; i
++)
629 buf
[i
] = ISLOWER (regname
[i
]) ? TOUPPER (regname
[i
]) : regname
[i
];
632 symbol_table_insert (symbol_new (buf
, reg_section
, (valueT
) regnum
,
633 &zero_address_frag
));
637 tic4x_insert_sym (char *symname
, int value
)
641 symbolP
= symbol_new (symname
, absolute_section
,
642 (valueT
) value
, &zero_address_frag
);
643 SF_SET_LOCAL (symbolP
);
644 symbol_table_insert (symbolP
);
648 tic4x_expression (char *str
, expressionS
*exp
)
653 t
= input_line_pointer
; /* Save line pointer. */
654 input_line_pointer
= str
;
656 s
= input_line_pointer
;
657 input_line_pointer
= t
; /* Restore line pointer. */
658 return s
; /* Return pointer to where parsing stopped. */
662 tic4x_expression_abs (char *str
, offsetT
*value
)
667 t
= input_line_pointer
; /* Save line pointer. */
668 input_line_pointer
= str
;
669 *value
= get_absolute_expression ();
670 s
= input_line_pointer
;
671 input_line_pointer
= t
; /* Restore line pointer. */
676 tic4x_emit_char (char c
, int b
)
680 exp
.X_op
= O_constant
;
681 exp
.X_add_number
= c
;
686 tic4x_seg_alloc (char *name ATTRIBUTE_UNUSED
,
687 segT seg ATTRIBUTE_UNUSED
,
691 /* Note that the size is in words
692 so we multiply it by 4 to get the number of bytes to allocate. */
694 /* If we have symbol: .usect ".fred", size etc.,
695 the symbol needs to point to the first location reserved
702 p
= frag_var (rs_fill
, 1, 1, (relax_substateT
) 0,
704 size
* OCTETS_PER_BYTE
, (char *) 0);
709 /* .asg ["]character-string["], symbol */
711 tic4x_asg (int x ATTRIBUTE_UNUSED
)
719 str
= input_line_pointer
;
721 /* Skip string expression. */
722 while (*input_line_pointer
!= ',' && *input_line_pointer
)
723 input_line_pointer
++;
724 if (*input_line_pointer
!= ',')
726 as_bad (_("Comma expected\n"));
729 *input_line_pointer
++ = '\0';
730 c
= get_symbol_name (&name
); /* Get terminator. */
731 tmp
= xmalloc (strlen (str
) + 1);
734 tmp
= xmalloc (strlen (name
) + 1);
737 if (hash_find (tic4x_asg_hash
, name
))
738 hash_replace (tic4x_asg_hash
, name
, (void *) str
);
740 hash_insert (tic4x_asg_hash
, name
, (void *) str
);
741 (void) restore_line_pointer (c
);
742 demand_empty_rest_of_line ();
745 /* .bss symbol, size */
747 tic4x_bss (int x ATTRIBUTE_UNUSED
)
754 subsegT current_subseg
;
757 current_seg
= now_seg
; /* Save current seg. */
758 current_subseg
= now_subseg
; /* Save current subseg. */
761 c
= get_symbol_name (&name
); /* Get terminator. */
763 c
= * ++ input_line_pointer
;
766 as_bad (_(".bss size argument missing\n"));
771 tic4x_expression_abs (++input_line_pointer
, &size
);
774 as_bad (_(".bss size %ld < 0!"), (long) size
);
777 subseg_set (bss_section
, 0);
778 symbolP
= symbol_find_or_make (name
);
780 if (S_GET_SEGMENT (symbolP
) == bss_section
)
781 symbol_get_frag (symbolP
)->fr_symbol
= 0;
783 symbol_set_frag (symbolP
, frag_now
);
785 p
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
,
786 size
* OCTETS_PER_BYTE
, (char *) 0);
787 *p
= 0; /* Fill char. */
789 S_SET_SEGMENT (symbolP
, bss_section
);
791 /* The symbol may already have been created with a preceding
792 ".globl" directive -- be careful not to step on storage class
793 in that case. Otherwise, set it to static. */
794 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
795 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
797 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
798 demand_empty_rest_of_line ();
802 tic4x_globl (int ignore ATTRIBUTE_UNUSED
)
810 c
= get_symbol_name (&name
);
811 symbolP
= symbol_find_or_make (name
);
812 *input_line_pointer
= c
;
813 SKIP_WHITESPACE_AFTER_NAME ();
814 S_SET_STORAGE_CLASS (symbolP
, C_EXT
);
815 S_SET_EXTERNAL (symbolP
);
818 input_line_pointer
++;
820 if (*input_line_pointer
== '\n')
826 demand_empty_rest_of_line ();
829 /* Handle .byte, .word. .int, .long */
831 tic4x_cons (int bytes
)
837 if (*input_line_pointer
== '"')
839 input_line_pointer
++;
840 while (is_a_char (c
= next_char_of_string ()))
841 tic4x_emit_char (c
, 4);
842 know (input_line_pointer
[-1] == '\"');
848 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
849 if (exp
.X_op
== O_constant
)
854 exp
.X_add_number
&= 255;
857 exp
.X_add_number
&= 65535;
861 /* Perhaps we should disallow .byte and .hword with
862 a non constant expression that will require relocation. */
866 while (*input_line_pointer
++ == ',');
868 input_line_pointer
--; /* Put terminator back into stream. */
869 demand_empty_rest_of_line ();
872 /* Handle .ascii, .asciz, .string */
874 tic4x_stringer (int append_zero
)
883 if (*input_line_pointer
== '"')
885 input_line_pointer
++;
886 while (is_a_char (c
= next_char_of_string ()))
888 tic4x_emit_char (c
, 1);
894 tic4x_emit_char (c
, 1);
898 know (input_line_pointer
[-1] == '\"');
904 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
905 if (exp
.X_op
!= O_constant
)
907 as_bad (_("Non-constant symbols not allowed\n"));
910 exp
.X_add_number
&= 255; /* Limit numeber to 8-bit */
915 while (*input_line_pointer
++ == ',');
917 /* Fill out the rest of the expression with 0's to fill up a full word */
919 tic4x_emit_char (0, 4-(bytes
&0x3));
921 input_line_pointer
--; /* Put terminator back into stream. */
922 demand_empty_rest_of_line ();
925 /* .eval expression, symbol */
927 tic4x_eval (int x ATTRIBUTE_UNUSED
)
935 tic4x_expression_abs (input_line_pointer
, &value
);
936 if (*input_line_pointer
++ != ',')
938 as_bad (_("Symbol missing\n"));
941 c
= get_symbol_name (&name
); /* Get terminator. */
942 tic4x_insert_sym (name
, value
);
943 (void) restore_line_pointer (c
);
944 demand_empty_rest_of_line ();
947 /* Reset local labels. */
949 tic4x_newblock (int x ATTRIBUTE_UNUSED
)
951 dollar_label_clear ();
954 /* .sect "section-name" [, value] */
955 /* .sect ["]section-name[:subsection-name]["] [, value] */
957 tic4x_sect (int x ATTRIBUTE_UNUSED
)
966 if (*input_line_pointer
== '"')
967 input_line_pointer
++;
968 c
= get_symbol_name (§ion_name
); /* Get terminator. */
970 c
= * ++ input_line_pointer
;
971 input_line_pointer
++; /* Skip null symbol terminator. */
972 name
= xmalloc (input_line_pointer
- section_name
+ 1);
973 strcpy (name
, section_name
);
975 /* TI C from version 5.0 allows a section name to contain a
976 subsection name as well. The subsection name is separated by a
977 ':' from the section name. Currently we scan the subsection
979 Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>. */
983 c
= get_symbol_name (&subname
); /* Get terminator. */
985 c
= * ++ input_line_pointer
;
986 input_line_pointer
++; /* Skip null symbol terminator. */
987 as_warn (_(".sect: subsection name ignored"));
990 /* We might still have a '"' to discard, but the character after a
991 symbol name will be overwritten with a \0 by get_symbol_name()
996 tic4x_expression_abs (input_line_pointer
, &num
);
997 else if (*input_line_pointer
== ',')
1000 tic4x_expression_abs (++input_line_pointer
, &num
);
1005 seg
= subseg_new (name
, num
);
1006 if (line_label
!= NULL
)
1008 S_SET_SEGMENT (line_label
, seg
);
1009 symbol_set_frag (line_label
, frag_now
);
1012 if (bfd_get_section_flags (stdoutput
, seg
) == SEC_NO_FLAGS
)
1014 if (!bfd_set_section_flags (stdoutput
, seg
, SEC_DATA
))
1015 as_warn (_("Error setting flags for \"%s\": %s"), name
,
1016 bfd_errmsg (bfd_get_error ()));
1019 /* If the last character overwritten by get_symbol_name() was an
1020 end-of-line, we must restore it or the end of the line will not be
1021 recognised and scanning extends into the next line, stopping with
1022 an error (blame Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>
1023 if this is not true). */
1024 if (is_end_of_line
[(unsigned char) c
])
1025 *(--input_line_pointer
) = c
;
1027 demand_empty_rest_of_line ();
1030 /* symbol[:] .set value or .set symbol, value */
1032 tic4x_set (int x ATTRIBUTE_UNUSED
)
1037 if ((symbolP
= line_label
) == NULL
)
1042 c
= get_symbol_name (&name
); /* Get terminator. */
1044 c
= * ++ input_line_pointer
;
1047 as_bad (_(".set syntax invalid\n"));
1048 ignore_rest_of_line ();
1051 ++input_line_pointer
;
1052 symbolP
= symbol_find_or_make (name
);
1055 symbol_table_insert (symbolP
);
1057 pseudo_set (symbolP
);
1058 demand_empty_rest_of_line ();
1061 /* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
1063 tic4x_usect (int x ATTRIBUTE_UNUSED
)
1069 offsetT size
, alignment_flag
;
1071 subsegT current_subseg
;
1073 current_seg
= now_seg
; /* save current seg. */
1074 current_subseg
= now_subseg
; /* save current subseg. */
1077 if (*input_line_pointer
== '"')
1078 input_line_pointer
++;
1079 c
= get_symbol_name (§ion_name
); /* Get terminator. */
1081 c
= * ++ input_line_pointer
;
1082 input_line_pointer
++; /* Skip null symbol terminator. */
1083 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1084 strcpy (name
, section_name
);
1087 input_line_pointer
=
1088 tic4x_expression_abs (input_line_pointer
, &size
);
1089 else if (*input_line_pointer
== ',')
1091 input_line_pointer
=
1092 tic4x_expression_abs (++input_line_pointer
, &size
);
1097 /* Read a possibly present third argument (alignment flag) [VK]. */
1098 if (*input_line_pointer
== ',')
1100 input_line_pointer
=
1101 tic4x_expression_abs (++input_line_pointer
, &alignment_flag
);
1106 as_warn (_(".usect: non-zero alignment flag ignored"));
1108 seg
= subseg_new (name
, 0);
1109 if (line_label
!= NULL
)
1111 S_SET_SEGMENT (line_label
, seg
);
1112 symbol_set_frag (line_label
, frag_now
);
1113 S_SET_VALUE (line_label
, frag_now_fix ());
1115 seg_info (seg
)->bss
= 1; /* Uninitialised data. */
1116 if (!bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
))
1117 as_warn (_("Error setting flags for \"%s\": %s"), name
,
1118 bfd_errmsg (bfd_get_error ()));
1119 tic4x_seg_alloc (name
, seg
, size
, line_label
);
1121 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1122 S_SET_STORAGE_CLASS (line_label
, C_STAT
);
1124 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
1125 demand_empty_rest_of_line ();
1128 /* .version cpu-version. */
1130 tic4x_version (int x ATTRIBUTE_UNUSED
)
1134 input_line_pointer
=
1135 tic4x_expression_abs (input_line_pointer
, &temp
);
1136 if (!IS_CPU_TIC3X (temp
) && !IS_CPU_TIC4X (temp
))
1137 as_bad (_("This assembler does not support processor generation %ld"),
1140 if (tic4x_cpu
&& temp
!= (offsetT
) tic4x_cpu
)
1141 as_warn (_("Changing processor generation on fly not supported..."));
1143 demand_empty_rest_of_line ();
1147 tic4x_init_regtable (void)
1151 for (i
= 0; i
< tic3x_num_registers
; i
++)
1152 tic4x_insert_reg (tic3x_registers
[i
].name
,
1153 tic3x_registers
[i
].regno
);
1155 if (IS_CPU_TIC4X (tic4x_cpu
))
1157 /* Add additional Tic4x registers, overriding some C3x ones. */
1158 for (i
= 0; i
< tic4x_num_registers
; i
++)
1159 tic4x_insert_reg (tic4x_registers
[i
].name
,
1160 tic4x_registers
[i
].regno
);
1165 tic4x_init_symbols (void)
1167 /* The TI tools accept case insensitive versions of these symbols,
1172 .TMS320xx 30,31,32,40,or 44 set according to -v flag
1173 .C3X or .C3x 1 or 0 1 if -v30,-v31,or -v32
1174 .C30 1 or 0 1 if -v30
1175 .C31 1 or 0 1 if -v31
1176 .C32 1 or 0 1 if -v32
1177 .C4X or .C4x 1 or 0 1 if -v40, or -v44
1178 .C40 1 or 0 1 if -v40
1179 .C44 1 or 0 1 if -v44
1181 .REGPARM 1 or 0 1 if -mr option used
1182 .BIGMODEL 1 or 0 1 if -mb option used
1184 These symbols are currently supported but will be removed in a
1186 .TMS320C30 1 or 0 1 if -v30,-v31,or -v32
1187 .TMS320C31 1 or 0 1 if -v31
1188 .TMS320C32 1 or 0 1 if -v32
1189 .TMS320C40 1 or 0 1 if -v40, or -v44
1190 .TMS320C44 1 or 0 1 if -v44
1192 Source: TI: TMS320C3x/C4x Assembly Language Tools User's Guide,
1193 1997, SPRU035C, p. 3-17/3-18. */
1194 tic4x_insert_sym (".REGPARM", tic4x_reg_args
);
1195 tic4x_insert_sym (".MEMPARM", !tic4x_reg_args
);
1196 tic4x_insert_sym (".BIGMODEL", tic4x_big_model
);
1197 tic4x_insert_sym (".C30INTERRUPT", 0);
1198 tic4x_insert_sym (".TMS320xx", tic4x_cpu
== 0 ? 40 : tic4x_cpu
);
1199 tic4x_insert_sym (".C3X", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1200 tic4x_insert_sym (".C3x", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1201 tic4x_insert_sym (".C4X", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1202 tic4x_insert_sym (".C4x", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1203 /* Do we need to have the following symbols also in lower case? */
1204 tic4x_insert_sym (".TMS320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1205 tic4x_insert_sym (".tms320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1206 tic4x_insert_sym (".TMS320C31", tic4x_cpu
== 31);
1207 tic4x_insert_sym (".tms320C31", tic4x_cpu
== 31);
1208 tic4x_insert_sym (".TMS320C32", tic4x_cpu
== 32);
1209 tic4x_insert_sym (".tms320C32", tic4x_cpu
== 32);
1210 tic4x_insert_sym (".TMS320C33", tic4x_cpu
== 33);
1211 tic4x_insert_sym (".tms320C33", tic4x_cpu
== 33);
1212 tic4x_insert_sym (".TMS320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1213 tic4x_insert_sym (".tms320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1214 tic4x_insert_sym (".TMS320C44", tic4x_cpu
== 44);
1215 tic4x_insert_sym (".tms320C44", tic4x_cpu
== 44);
1216 tic4x_insert_sym (".TMX320C40", 0); /* C40 first pass silicon ? */
1217 tic4x_insert_sym (".tmx320C40", 0);
1220 /* Insert a new instruction template into hash table. */
1222 tic4x_inst_insert (const tic4x_inst_t
*inst
)
1224 static char prev_name
[16];
1225 const char *retval
= NULL
;
1227 /* Only insert the first name if have several similar entries. */
1228 if (!strcmp (inst
->name
, prev_name
) || inst
->name
[0] == '\0')
1231 retval
= hash_insert (tic4x_op_hash
, inst
->name
, (void *) inst
);
1233 fprintf (stderr
, "internal error: can't hash `%s': %s\n",
1234 inst
->name
, retval
);
1236 strcpy (prev_name
, inst
->name
);
1237 return retval
== NULL
;
1240 /* Make a new instruction template. */
1241 static tic4x_inst_t
*
1242 tic4x_inst_make (char *name
, unsigned long opcode
, char *args
)
1244 static tic4x_inst_t
*insts
= NULL
;
1245 static char *names
= NULL
;
1246 static int iindex
= 0;
1250 /* Allocate memory to store name strings. */
1251 names
= (char *) xmalloc (sizeof (char) * 8192);
1252 /* Allocate memory for additional insts. */
1253 insts
= (tic4x_inst_t
*)
1254 xmalloc (sizeof (tic4x_inst_t
) * 1024);
1256 insts
[iindex
].name
= names
;
1257 insts
[iindex
].opcode
= opcode
;
1258 insts
[iindex
].opmask
= 0xffffffff;
1259 insts
[iindex
].args
= args
;
1267 return &insts
[iindex
- 1];
1270 /* Add instruction template, creating dynamic templates as required. */
1272 tic4x_inst_add (const tic4x_inst_t
*insts
)
1274 char *s
= insts
->name
;
1282 /* We do not care about INSNs that is not a part of our
1284 if ((insts
->oplevel
& tic4x_oplevel
) == 0)
1293 /* Dynamically create all the conditional insts. */
1294 for (i
= 0; i
< tic4x_num_conds
; i
++)
1298 char *c
= tic4x_conds
[i
].name
;
1308 /* If instruction found then have already processed it. */
1309 if (hash_find (tic4x_op_hash
, name
))
1314 inst
= tic4x_inst_make (name
, insts
[k
].opcode
+
1315 (tic4x_conds
[i
].cond
<<
1316 (*s
== 'B' ? 16 : 23)),
1318 if (k
== 0) /* Save strcmp() with following func. */
1319 ok
&= tic4x_inst_insert (inst
);
1322 while (!strcmp (insts
->name
,
1329 return tic4x_inst_insert (insts
);
1339 /* This function is called once, at assembler startup time. It should
1340 set up all the tables, etc., that the MD part of the assembler will
1348 /* Setup the proper opcode level according to the
1349 commandline parameters */
1350 tic4x_oplevel
= OP_C3X
;
1352 if ( IS_CPU_TIC4X(tic4x_cpu
) )
1353 tic4x_oplevel
|= OP_C4X
;
1355 if ( ( tic4x_cpu
== 31 && tic4x_revision
>= 6)
1356 || (tic4x_cpu
== 32 && tic4x_revision
>= 2)
1357 || (tic4x_cpu
== 33)
1359 tic4x_oplevel
|= OP_ENH
;
1361 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1362 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1363 || (tic4x_cpu
== 32)
1365 tic4x_oplevel
|= OP_LPWR
;
1367 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1368 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1369 || (tic4x_cpu
== 32)
1370 || (tic4x_cpu
== 33)
1371 || (tic4x_cpu
== 40 && tic4x_revision
>= 5)
1372 || (tic4x_cpu
== 44)
1374 tic4x_oplevel
|= OP_IDLE2
;
1376 /* Create hash table for mnemonics. */
1377 tic4x_op_hash
= hash_new ();
1379 /* Create hash table for asg pseudo. */
1380 tic4x_asg_hash
= hash_new ();
1382 /* Add mnemonics to hash table, expanding conditional mnemonics on fly. */
1383 for (i
= 0; i
< tic4x_num_insts
; i
++)
1384 ok
&= tic4x_inst_add (tic4x_insts
+ i
);
1386 /* Create dummy inst to avoid errors accessing end of table. */
1387 tic4x_inst_make ("", 0, "");
1390 as_fatal ("Broken assembler. No assembly attempted.");
1392 /* Add registers to symbol table. */
1393 tic4x_init_regtable ();
1395 /* Add predefined symbols to symbol table. */
1396 tic4x_init_symbols ();
1402 bfd_set_arch_mach (stdoutput
, bfd_arch_tic4x
,
1403 IS_CPU_TIC4X (tic4x_cpu
) ? bfd_mach_tic4x
: bfd_mach_tic3x
);
1407 tic4x_indirect_parse (tic4x_operand_t
*operand
,
1408 const tic4x_indirect_t
*indirect
)
1410 char *n
= indirect
->name
;
1411 char *s
= input_line_pointer
;
1421 case 'a': /* Need to match aux register. */
1423 #ifdef TIC4X_ALT_SYNTAX
1427 while (ISALNUM (*s
))
1430 if (!(symbolP
= symbol_find (name
)))
1433 if (S_GET_SEGMENT (symbolP
) != reg_section
)
1436 operand
->aregno
= S_GET_VALUE (symbolP
);
1437 if (operand
->aregno
>= REG_AR0
&& operand
->aregno
<= REG_AR7
)
1440 as_bad (_("Auxiliary register AR0--AR7 required for indirect"));
1443 case 'd': /* Need to match constant for disp. */
1444 #ifdef TIC4X_ALT_SYNTAX
1445 if (*s
== '%') /* expr() will die if we don't skip this. */
1448 s
= tic4x_expression (s
, &operand
->expr
);
1449 if (operand
->expr
.X_op
!= O_constant
)
1451 operand
->disp
= operand
->expr
.X_add_number
;
1452 if (operand
->disp
< 0 || operand
->disp
> 255)
1454 as_bad (_("Bad displacement %d (require 0--255)\n"),
1460 case 'y': /* Need to match IR0. */
1461 case 'z': /* Need to match IR1. */
1462 #ifdef TIC4X_ALT_SYNTAX
1466 s
= tic4x_expression (s
, &operand
->expr
);
1467 if (operand
->expr
.X_op
!= O_register
)
1469 if (operand
->expr
.X_add_number
!= REG_IR0
1470 && operand
->expr
.X_add_number
!= REG_IR1
)
1472 as_bad (_("Index register IR0,IR1 required for displacement"));
1476 if (*n
== 'y' && operand
->expr
.X_add_number
== REG_IR0
)
1478 if (*n
== 'z' && operand
->expr
.X_add_number
== REG_IR1
)
1483 if (*s
!= '(') /* No displacement, assume to be 1. */
1494 if (TOLOWER (*s
) != *n
)
1499 if (*s
!= ' ' && *s
!= ',' && *s
!= '\0')
1501 input_line_pointer
= s
;
1506 tic4x_operand_parse (char *s
, tic4x_operand_t
*operand
)
1511 expressionS
*exp
= &operand
->expr
;
1512 char *save
= input_line_pointer
;
1515 struct hash_entry
*entry
= NULL
;
1517 input_line_pointer
= s
;
1520 c
= get_symbol_name (&str
); /* Get terminator. */
1521 new_pointer
= input_line_pointer
;
1522 if (strlen (str
) && (entry
= hash_find (tic4x_asg_hash
, str
)) != NULL
)
1524 (void) restore_line_pointer (c
);
1525 input_line_pointer
= (char *) entry
;
1529 (void) restore_line_pointer (c
);
1530 input_line_pointer
= str
;
1533 operand
->mode
= M_UNKNOWN
;
1534 switch (*input_line_pointer
)
1536 #ifdef TIC4X_ALT_SYNTAX
1538 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1539 if (exp
->X_op
!= O_register
)
1540 as_bad (_("Expecting a register name"));
1541 operand
->mode
= M_REGISTER
;
1545 /* Denotes high 16 bits. */
1546 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1547 if (exp
->X_op
== O_constant
)
1548 operand
->mode
= M_IMMED
;
1549 else if (exp
->X_op
== O_big
)
1551 if (exp
->X_add_number
)
1552 as_bad (_("Number too large")); /* bignum required */
1555 tic4x_gen_to_words (generic_floating_point_number
,
1556 operand
->fwords
, S_PRECISION
);
1557 operand
->mode
= M_IMMED_F
;
1560 /* Allow ori ^foo, ar0 to be equivalent to ldi .hi.foo, ar0 */
1561 /* WARNING : The TI C40 assembler cannot do this. */
1562 else if (exp
->X_op
== O_symbol
)
1564 operand
->mode
= M_HI
;
1569 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1570 if (exp
->X_op
== O_constant
)
1571 operand
->mode
= M_IMMED
;
1572 else if (exp
->X_op
== O_big
)
1574 if (exp
->X_add_number
> 0)
1575 as_bad (_("Number too large")); /* bignum required. */
1578 tic4x_gen_to_words (generic_floating_point_number
,
1579 operand
->fwords
, S_PRECISION
);
1580 operand
->mode
= M_IMMED_F
;
1583 /* Allow ori foo, ar0 to be equivalent to ldi .lo.foo, ar0 */
1584 /* WARNING : The TI C40 assembler cannot do this. */
1585 else if (exp
->X_op
== O_symbol
)
1587 operand
->mode
= M_IMMED
;
1592 as_bad (_("Expecting a constant value"));
1597 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1598 if (exp
->X_op
!= O_constant
&& exp
->X_op
!= O_symbol
)
1599 as_bad (_("Bad direct addressing construct %s"), s
);
1600 if (exp
->X_op
== O_constant
)
1602 if (exp
->X_add_number
< 0)
1603 as_bad (_("Direct value of %ld is not suitable"),
1604 (long) exp
->X_add_number
);
1606 operand
->mode
= M_DIRECT
;
1611 for (i
= 0; i
< tic4x_num_indirects
; i
++)
1612 if ((ret
= tic4x_indirect_parse (operand
, &tic4x_indirects
[i
])))
1616 if (i
< tic4x_num_indirects
)
1618 operand
->mode
= M_INDIRECT
;
1619 /* Indirect addressing mode number. */
1620 operand
->expr
.X_add_number
= tic4x_indirects
[i
].modn
;
1621 /* Convert *+ARn(0) to *ARn etc. Maybe we should
1622 squeal about silly ones? */
1623 if (operand
->expr
.X_add_number
< 0x08 && !operand
->disp
)
1624 operand
->expr
.X_add_number
= 0x18;
1627 as_bad (_("Unknown indirect addressing mode"));
1631 operand
->mode
= M_IMMED
; /* Assume immediate. */
1632 str
= input_line_pointer
;
1633 input_line_pointer
= tic4x_expression (input_line_pointer
, exp
);
1634 if (exp
->X_op
== O_register
)
1636 know (exp
->X_add_symbol
== 0);
1637 know (exp
->X_op_symbol
== 0);
1638 operand
->mode
= M_REGISTER
;
1641 else if (exp
->X_op
== O_big
)
1643 if (exp
->X_add_number
> 0)
1644 as_bad (_("Number too large")); /* bignum required. */
1647 tic4x_gen_to_words (generic_floating_point_number
,
1648 operand
->fwords
, S_PRECISION
);
1649 operand
->mode
= M_IMMED_F
;
1653 #ifdef TIC4X_ALT_SYNTAX
1654 /* Allow ldi foo, ar0 to be equivalent to ldi @foo, ar0. */
1655 else if (exp
->X_op
== O_symbol
)
1657 operand
->mode
= M_DIRECT
;
1663 new_pointer
= input_line_pointer
;
1664 input_line_pointer
= save
;
1669 tic4x_operands_match (tic4x_inst_t
*inst
, tic4x_insn_t
*tinsn
, int check
)
1671 const char *args
= inst
->args
;
1672 unsigned long opcode
= inst
->opcode
;
1673 int num_operands
= tinsn
->num_operands
;
1674 tic4x_operand_t
*operand
= tinsn
->operands
;
1675 expressionS
*exp
= &operand
->expr
;
1679 /* Build the opcode, checking as we go to make sure that the
1682 If an operand matches, we modify insn or opcode appropriately,
1683 and do a "continue". If an operand fails to match, we "break". */
1685 tinsn
->nchars
= 4; /* Instructions always 4 bytes. */
1686 tinsn
->reloc
= NO_RELOC
;
1691 tinsn
->opcode
= opcode
;
1692 return num_operands
== 0;
1700 case '\0': /* End of args. */
1701 if (num_operands
== 1)
1703 tinsn
->opcode
= opcode
;
1706 break; /* Too many operands. */
1708 case '#': /* This is only used for ldp. */
1709 if (operand
->mode
!= M_DIRECT
&& operand
->mode
!= M_IMMED
)
1711 /* While this looks like a direct addressing mode, we actually
1712 use an immediate mode form of ldiu or ldpk instruction. */
1713 if (exp
->X_op
== O_constant
)
1715 if( ( IS_CPU_TIC4X (tic4x_cpu
) && exp
->X_add_number
<= 65535 )
1716 || ( IS_CPU_TIC3X (tic4x_cpu
) && exp
->X_add_number
<= 255 ) )
1718 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1724 as_bad (_("Immediate value of %ld is too large for ldf"),
1725 (long) exp
->X_add_number
);
1730 else if (exp
->X_op
== O_symbol
)
1732 tinsn
->reloc
= BFD_RELOC_HI16
;
1736 break; /* Not direct (dp) addressing. */
1738 case '@': /* direct. */
1739 if (operand
->mode
!= M_DIRECT
)
1741 if (exp
->X_op
== O_constant
)
1743 /* Store only the 16 LSBs of the number. */
1744 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1747 else if (exp
->X_op
== O_symbol
)
1749 tinsn
->reloc
= BFD_RELOC_LO16
;
1753 break; /* Not direct addressing. */
1756 if (operand
->mode
!= M_REGISTER
)
1758 reg
= exp
->X_add_number
;
1759 if (reg
>= REG_AR0
&& reg
<= REG_AR7
)
1760 INSERTU (opcode
, reg
- REG_AR0
, 24, 22);
1764 as_bad (_("Destination register must be ARn"));
1769 case 'B': /* Unsigned integer immediate. */
1770 /* Allow br label or br @label. */
1771 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
1773 if (exp
->X_op
== O_constant
)
1775 if (exp
->X_add_number
< (1 << 24))
1777 INSERTU (opcode
, exp
->X_add_number
, 23, 0);
1783 as_bad (_("Immediate value of %ld is too large"),
1784 (long) exp
->X_add_number
);
1789 if (IS_CPU_TIC4X (tic4x_cpu
))
1791 tinsn
->reloc
= BFD_RELOC_24_PCREL
;
1796 tinsn
->reloc
= BFD_RELOC_24
;
1803 if (!IS_CPU_TIC4X (tic4x_cpu
))
1805 if (operand
->mode
!= M_INDIRECT
)
1807 /* Require either *+ARn(disp) or *ARn. */
1808 if (operand
->expr
.X_add_number
!= 0
1809 && operand
->expr
.X_add_number
!= 0x18)
1812 as_bad (_("Invalid indirect addressing mode"));
1816 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1817 INSERTU (opcode
, operand
->disp
, 7, 3);
1821 if (!(operand
->mode
== M_REGISTER
))
1823 INSERTU (opcode
, exp
->X_add_number
, 7, 0);
1827 if (!(operand
->mode
== M_REGISTER
))
1829 reg
= exp
->X_add_number
;
1830 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1831 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1832 INSERTU (opcode
, reg
, 7, 0);
1836 as_bad (_("Register must be Rn"));
1842 if (operand
->mode
!= M_IMMED_F
1843 && !(operand
->mode
== M_IMMED
&& exp
->X_op
== O_constant
))
1846 if (operand
->mode
!= M_IMMED_F
)
1848 /* OK, we 've got something like cmpf 0, r0
1849 Why can't they stick in a bloody decimal point ?! */
1852 /* Create floating point number string. */
1853 sprintf (string
, "%d.0", (int) exp
->X_add_number
);
1854 tic4x_atof (string
, 's', operand
->fwords
);
1857 INSERTU (opcode
, operand
->fwords
[0], 15, 0);
1861 if (operand
->mode
!= M_REGISTER
)
1863 INSERTU (opcode
, exp
->X_add_number
, 15, 8);
1867 if (operand
->mode
!= M_REGISTER
)
1869 reg
= exp
->X_add_number
;
1870 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1871 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1872 INSERTU (opcode
, reg
, 15, 8);
1876 as_bad (_("Register must be Rn"));
1882 if (operand
->mode
!= M_REGISTER
)
1884 reg
= exp
->X_add_number
;
1885 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1886 INSERTU (opcode
, reg
- REG_R0
, 18, 16);
1890 as_bad (_("Register must be R0--R7"));
1896 if ( operand
->mode
== M_REGISTER
1897 && tic4x_oplevel
& OP_ENH
)
1899 reg
= exp
->X_add_number
;
1900 INSERTU (opcode
, reg
, 4, 0);
1901 INSERTU (opcode
, 7, 7, 5);
1907 if (operand
->mode
!= M_INDIRECT
)
1909 if (operand
->disp
!= 0 && operand
->disp
!= 1)
1911 if (IS_CPU_TIC4X (tic4x_cpu
))
1914 as_bad (_("Invalid indirect addressing mode displacement %d"),
1919 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1920 INSERTU (opcode
, operand
->expr
.X_add_number
, 7, 3);
1924 if ( operand
->mode
== M_REGISTER
1925 && tic4x_oplevel
& OP_ENH
)
1927 reg
= exp
->X_add_number
;
1928 INSERTU (opcode
, reg
, 12, 8);
1929 INSERTU (opcode
, 7, 15, 13);
1935 if (operand
->mode
!= M_INDIRECT
)
1937 if (operand
->disp
!= 0 && operand
->disp
!= 1)
1939 if (IS_CPU_TIC4X (tic4x_cpu
))
1942 as_bad (_("Invalid indirect addressing mode displacement %d"),
1947 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
1948 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
1952 if (operand
->mode
!= M_REGISTER
)
1954 reg
= exp
->X_add_number
;
1955 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1956 INSERTU (opcode
, reg
- REG_R0
, 21, 19);
1960 as_bad (_("Register must be R0--R7"));
1966 if (operand
->mode
!= M_REGISTER
)
1968 reg
= exp
->X_add_number
;
1969 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1970 INSERTU (opcode
, reg
- REG_R0
, 24, 22);
1974 as_bad (_("Register must be R0--R7"));
1980 if (operand
->mode
!= M_REGISTER
)
1982 reg
= exp
->X_add_number
;
1983 if (reg
== REG_R2
|| reg
== REG_R3
)
1984 INSERTU (opcode
, reg
- REG_R2
, 22, 22);
1988 as_bad (_("Destination register must be R2 or R3"));
1994 if (operand
->mode
!= M_REGISTER
)
1996 reg
= exp
->X_add_number
;
1997 if (reg
== REG_R0
|| reg
== REG_R1
)
1998 INSERTU (opcode
, reg
- REG_R0
, 23, 23);
2002 as_bad (_("Destination register must be R0 or R1"));
2008 if (!IS_CPU_TIC4X (tic4x_cpu
))
2010 if (operand
->mode
!= M_INDIRECT
)
2012 /* Require either *+ARn(disp) or *ARn. */
2013 if (operand
->expr
.X_add_number
!= 0
2014 && operand
->expr
.X_add_number
!= 0x18)
2017 as_bad (_("Invalid indirect addressing mode"));
2021 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2022 INSERTU (opcode
, operand
->disp
, 15, 11);
2025 case 'P': /* PC relative displacement. */
2026 /* Allow br label or br @label. */
2027 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
2029 if (exp
->X_op
== O_constant
)
2031 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 32767)
2033 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2039 as_bad (_("Displacement value of %ld is too large"),
2040 (long) exp
->X_add_number
);
2045 tinsn
->reloc
= BFD_RELOC_16_PCREL
;
2051 if (operand
->mode
!= M_REGISTER
)
2053 reg
= exp
->X_add_number
;
2054 INSERTU (opcode
, reg
, 15, 0);
2058 if (operand
->mode
!= M_REGISTER
)
2060 reg
= exp
->X_add_number
;
2061 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2062 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2063 INSERTU (opcode
, reg
, 15, 0);
2067 as_bad (_("Register must be Rn"));
2073 if (operand
->mode
!= M_REGISTER
)
2075 reg
= exp
->X_add_number
;
2076 INSERTU (opcode
, reg
, 20, 16);
2080 if (operand
->mode
!= M_REGISTER
)
2082 reg
= exp
->X_add_number
;
2083 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2084 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2085 INSERTU (opcode
, reg
, 20, 16);
2089 as_bad (_("Register must be Rn"));
2094 case 'S': /* Short immediate int. */
2095 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2097 if (exp
->X_op
== O_big
)
2100 as_bad (_("Floating point number not valid in expression"));
2104 if (exp
->X_op
== O_constant
)
2106 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 65535)
2108 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2114 as_bad (_("Signed immediate value %ld too large"),
2115 (long) exp
->X_add_number
);
2120 else if (exp
->X_op
== O_symbol
)
2122 if (operand
->mode
== M_HI
)
2124 tinsn
->reloc
= BFD_RELOC_HI16
;
2128 tinsn
->reloc
= BFD_RELOC_LO16
;
2133 /* Handle cases like ldi foo - $, ar0 where foo
2134 is a forward reference. Perhaps we should check
2135 for X_op == O_symbol and disallow things like
2137 tinsn
->reloc
= BFD_RELOC_16
;
2141 case 'T': /* 5-bit immediate value for tic4x stik. */
2142 if (!IS_CPU_TIC4X (tic4x_cpu
))
2144 if (operand
->mode
!= M_IMMED
)
2146 if (exp
->X_op
== O_constant
)
2148 if (exp
->X_add_number
< 16 && exp
->X_add_number
>= -16)
2150 INSERTS (opcode
, exp
->X_add_number
, 20, 16);
2156 as_bad (_("Immediate value of %ld is too large"),
2157 (long) exp
->X_add_number
);
2162 break; /* No relocations allowed. */
2164 case 'U': /* Unsigned integer immediate. */
2165 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2167 if (exp
->X_op
== O_constant
)
2169 if (exp
->X_add_number
< (1 << 16) && exp
->X_add_number
>= 0)
2171 INSERTU (opcode
, exp
->X_add_number
, 15, 0);
2177 as_bad (_("Unsigned immediate value %ld too large"),
2178 (long) exp
->X_add_number
);
2183 else if (exp
->X_op
== O_symbol
)
2185 if (operand
->mode
== M_HI
)
2186 tinsn
->reloc
= BFD_RELOC_HI16
;
2188 tinsn
->reloc
= BFD_RELOC_LO16
;
2193 tinsn
->reloc
= BFD_RELOC_16
;
2197 case 'V': /* Trap numbers (immediate field). */
2198 if (operand
->mode
!= M_IMMED
)
2200 if (exp
->X_op
== O_constant
)
2202 if (exp
->X_add_number
< 512 && IS_CPU_TIC4X (tic4x_cpu
))
2204 INSERTU (opcode
, exp
->X_add_number
, 8, 0);
2207 else if (exp
->X_add_number
< 32 && IS_CPU_TIC3X (tic4x_cpu
))
2209 INSERTU (opcode
, exp
->X_add_number
| 0x20, 4, 0);
2215 as_bad (_("Immediate value of %ld is too large"),
2216 (long) exp
->X_add_number
);
2221 break; /* No relocations allowed. */
2223 case 'W': /* Short immediate int (0--7). */
2224 if (!IS_CPU_TIC4X (tic4x_cpu
))
2226 if (operand
->mode
!= M_IMMED
)
2228 if (exp
->X_op
== O_big
)
2231 as_bad (_("Floating point number not valid in expression"));
2235 if (exp
->X_op
== O_constant
)
2237 if (exp
->X_add_number
>= -256 && exp
->X_add_number
<= 127)
2239 INSERTS (opcode
, exp
->X_add_number
, 7, 0);
2245 as_bad (_("Immediate value %ld too large"),
2246 (long) exp
->X_add_number
);
2251 tinsn
->reloc
= BFD_RELOC_16
;
2255 case 'X': /* Expansion register for tic4x. */
2256 if (operand
->mode
!= M_REGISTER
)
2258 reg
= exp
->X_add_number
;
2259 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2260 INSERTU (opcode
, reg
- REG_IVTP
, 4, 0);
2264 as_bad (_("Register must be ivtp or tvtp"));
2269 case 'Y': /* Address register for tic4x lda. */
2270 if (operand
->mode
!= M_REGISTER
)
2272 reg
= exp
->X_add_number
;
2273 if (reg
>= REG_AR0
&& reg
<= REG_SP
)
2274 INSERTU (opcode
, reg
, 20, 16);
2278 as_bad (_("Register must be address register"));
2283 case 'Z': /* Expansion register for tic4x. */
2284 if (operand
->mode
!= M_REGISTER
)
2286 reg
= exp
->X_add_number
;
2287 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2288 INSERTU (opcode
, reg
- REG_IVTP
, 20, 16);
2292 as_bad (_("Register must be ivtp or tvtp"));
2298 if (operand
->mode
!= M_INDIRECT
)
2300 INSERTS (opcode
, operand
->disp
, 7, 0);
2301 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2302 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
2305 case '|': /* treat as `,' if have ldi_ldi form. */
2306 if (tinsn
->parallel
)
2308 if (--num_operands
< 0)
2309 break; /* Too few operands. */
2311 if (operand
->mode
!= M_PARALLEL
)
2316 case ',': /* Another operand. */
2317 if (--num_operands
< 0)
2318 break; /* Too few operands. */
2320 exp
= &operand
->expr
;
2323 case ';': /* Another optional operand. */
2324 if (num_operands
== 1 || operand
[1].mode
== M_PARALLEL
)
2326 if (--num_operands
< 0)
2327 break; /* Too few operands. */
2329 exp
= &operand
->expr
;
2340 tic4x_insn_check (tic4x_insn_t
*tinsn
)
2343 if (!strcmp (tinsn
->name
, "lda"))
2345 if (tinsn
->num_operands
< 2 || tinsn
->num_operands
> 2)
2346 as_fatal ("Illegal internal LDA insn definition");
2348 if (tinsn
->operands
[0].mode
== M_REGISTER
2349 && tinsn
->operands
[1].mode
== M_REGISTER
2350 && tinsn
->operands
[0].expr
.X_add_number
== tinsn
->operands
[1].expr
.X_add_number
)
2351 as_bad (_("Source and destination register should not be equal"));
2353 else if (!strcmp (tinsn
->name
, "ldi_ldi")
2354 || !strcmp (tinsn
->name
, "ldi1_ldi2")
2355 || !strcmp (tinsn
->name
, "ldi2_ldi1")
2356 || !strcmp (tinsn
->name
, "ldf_ldf")
2357 || !strcmp (tinsn
->name
, "ldf1_ldf2")
2358 || !strcmp (tinsn
->name
, "ldf2_ldf1") )
2360 if (tinsn
->num_operands
< 4 || tinsn
->num_operands
> 5)
2361 as_fatal ("Illegal internal %s insn definition", tinsn
->name
);
2363 if (tinsn
->operands
[1].mode
== M_REGISTER
2364 && tinsn
->operands
[tinsn
->num_operands
-1].mode
== M_REGISTER
2365 && tinsn
->operands
[1].expr
.X_add_number
== tinsn
->operands
[tinsn
->num_operands
-1].expr
.X_add_number
)
2366 as_warn (_("Equal parallell destination registers, one result will be discarded"));
2371 tic4x_insn_output (tic4x_insn_t
*tinsn
)
2375 /* Grab another fragment for opcode. */
2376 dst
= frag_more (tinsn
->nchars
);
2378 /* Put out opcode word as a series of bytes in little endian order. */
2379 md_number_to_chars (dst
, tinsn
->opcode
, tinsn
->nchars
);
2381 /* Put out the symbol-dependent stuff. */
2382 if (tinsn
->reloc
!= NO_RELOC
)
2384 /* Where is the offset into the fragment for this instruction. */
2385 fix_new_exp (frag_now
,
2386 dst
- frag_now
->fr_literal
, /* where */
2387 tinsn
->nchars
, /* size */
2394 /* Parse the operands. */
2396 tic4x_operands_parse (char *s
, tic4x_operand_t
*operands
, int num_operands
)
2399 return num_operands
;
2402 s
= tic4x_operand_parse (s
, &operands
[num_operands
++]);
2403 while (num_operands
< TIC4X_OPERANDS_MAX
&& *s
++ == ',');
2405 if (num_operands
> TIC4X_OPERANDS_MAX
)
2407 as_bad (_("Too many operands scanned"));
2410 return num_operands
;
2413 /* Assemble a single instruction. Its label has already been handled
2414 by the generic front end. We just parse mnemonic and operands, and
2415 produce the bytes of data and relocation. */
2417 md_assemble (char *str
)
2424 tic4x_inst_t
*inst
; /* Instruction template. */
2425 tic4x_inst_t
*first_inst
;
2427 /* Scan for parallel operators */
2431 while (*s
&& *s
!= '|')
2434 if (*s
&& s
[1]=='|')
2438 as_bad (_("Parallel opcode cannot contain more than two instructions"));
2444 /* Lets take care of the first part of the parallel insn */
2449 /* .. and let the second run though here */
2453 if (str
&& insn
->parallel
)
2455 /* Find mnemonic (second part of parallel instruction). */
2457 /* Skip past instruction mnemonic. */
2458 while (*s
&& *s
!= ' ')
2460 if (*s
) /* Null terminate for hash_find. */
2461 *s
++ = '\0'; /* and skip past null. */
2462 len
= strlen (insn
->name
);
2463 snprintf (insn
->name
+ len
, TIC4X_NAME_MAX
- len
, "_%s", str
);
2465 insn
->operands
[insn
->num_operands
++].mode
= M_PARALLEL
;
2467 if ((i
= tic4x_operands_parse
2468 (s
, insn
->operands
, insn
->num_operands
)) < 0)
2474 insn
->num_operands
= i
;
2480 if ((insn
->inst
= (struct tic4x_inst
*)
2481 hash_find (tic4x_op_hash
, insn
->name
)) == NULL
)
2483 as_bad (_("Unknown opcode `%s'."), insn
->name
);
2493 ok
= tic4x_operands_match (inst
, insn
, 1);
2500 } while (!ok
&& !strcmp (inst
->name
, inst
[1].name
) && inst
++);
2504 tic4x_insn_check (insn
);
2505 tic4x_insn_output (insn
);
2510 tic4x_operands_match (first_inst
, insn
, 0);
2511 as_bad (_("Invalid operands for %s"), insn
->name
);
2514 as_bad (_("Invalid instruction %s"), insn
->name
);
2519 /* Find mnemonic. */
2521 while (*s
&& *s
!= ' ') /* Skip past instruction mnemonic. */
2523 if (*s
) /* Null terminate for hash_find. */
2524 *s
++ = '\0'; /* and skip past null. */
2525 strncpy (insn
->name
, str
, TIC4X_NAME_MAX
- 1);
2526 insn
->name
[TIC4X_NAME_MAX
- 1] = '\0';
2528 if ((i
= tic4x_operands_parse (s
, insn
->operands
, 0)) < 0)
2530 insn
->inst
= NULL
; /* Flag that error occurred. */
2535 insn
->num_operands
= i
;
2544 tic4x_cleanup (void)
2550 /* Turn a string in input_line_pointer into a floating point constant
2551 of type type, and store the appropriate bytes in *litP. The number
2552 of chars emitted is stored in *sizeP. An error message is
2553 returned, or NULL on OK. */
2556 md_atof (int type
, char *litP
, int *sizeP
)
2560 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2561 LITTLENUM_TYPE
*wordP
;
2566 case 's': /* .single */
2572 case 'd': /* .double */
2574 case 'f': /* .float */
2577 prec
= 2; /* 1 32-bit word */
2580 case 'i': /* .ieee */
2584 type
= 'f'; /* Rewrite type to be usable by atof_ieee(). */
2587 case 'e': /* .ldouble */
2589 prec
= 4; /* 2 32-bit words */
2595 return _("Unrecognized or unsupported floating point constant");
2599 t
= atof_ieee (input_line_pointer
, type
, words
);
2601 t
= tic4x_atof (input_line_pointer
, type
, words
);
2603 input_line_pointer
= t
;
2604 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
2606 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
2607 little endian byte order. */
2608 /* SES: However it is required to put the words (32-bits) out in the
2609 correct order, hence we write 2 and 2 littlenums in little endian
2610 order, while we keep the original order on successive words. */
2611 for (wordP
= words
; wordP
<(words
+prec
) ; wordP
+=2)
2613 if (wordP
< (words
+ prec
- 1)) /* Dump wordP[1] (if we have one). */
2615 md_number_to_chars (litP
, (valueT
) (wordP
[1]),
2616 sizeof (LITTLENUM_TYPE
));
2617 litP
+= sizeof (LITTLENUM_TYPE
);
2621 md_number_to_chars (litP
, (valueT
) (wordP
[0]),
2622 sizeof (LITTLENUM_TYPE
));
2623 litP
+= sizeof (LITTLENUM_TYPE
);
2629 md_apply_fix (fixS
*fixP
, valueT
*value
, segT seg ATTRIBUTE_UNUSED
)
2631 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
2632 valueT val
= *value
;
2634 switch (fixP
->fx_r_type
)
2636 case BFD_RELOC_HI16
:
2640 case BFD_RELOC_LO16
:
2647 switch (fixP
->fx_r_type
)
2652 case BFD_RELOC_24_PCREL
:
2655 case BFD_RELOC_16_PCREL
:
2656 case BFD_RELOC_LO16
:
2657 case BFD_RELOC_HI16
:
2664 as_bad (_("Bad relocation type: 0x%02x"), fixP
->fx_r_type
);
2668 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0) fixP
->fx_done
= 1;
2671 /* Should never be called for tic4x. */
2673 md_convert_frag (bfd
*headers ATTRIBUTE_UNUSED
,
2674 segT sec ATTRIBUTE_UNUSED
,
2675 fragS
*fragP ATTRIBUTE_UNUSED
)
2677 as_fatal ("md_convert_frag");
2680 /* Should never be called for tic4x. */
2682 md_create_short_jump (char *ptr ATTRIBUTE_UNUSED
,
2683 addressT from_addr ATTRIBUTE_UNUSED
,
2684 addressT to_addr ATTRIBUTE_UNUSED
,
2685 fragS
*frag ATTRIBUTE_UNUSED
,
2686 symbolS
*to_symbol ATTRIBUTE_UNUSED
)
2688 as_fatal ("md_create_short_jmp\n");
2691 /* Should never be called for tic4x. */
2693 md_create_long_jump (char *ptr ATTRIBUTE_UNUSED
,
2694 addressT from_addr ATTRIBUTE_UNUSED
,
2695 addressT to_addr ATTRIBUTE_UNUSED
,
2696 fragS
*frag ATTRIBUTE_UNUSED
,
2697 symbolS
*to_symbol ATTRIBUTE_UNUSED
)
2699 as_fatal ("md_create_long_jump\n");
2702 /* Should never be called for tic4x. */
2704 md_estimate_size_before_relax (fragS
*fragP ATTRIBUTE_UNUSED
,
2705 segT segtype ATTRIBUTE_UNUSED
)
2707 as_fatal ("md_estimate_size_before_relax\n");
2713 md_parse_option (int c
, char *arg
)
2717 case OPTION_CPU
: /* cpu brand */
2718 if (TOLOWER (*arg
) == 'c')
2720 tic4x_cpu
= atoi (arg
);
2721 if (!IS_CPU_TIC3X (tic4x_cpu
) && !IS_CPU_TIC4X (tic4x_cpu
))
2722 as_warn (_("Unsupported processor generation %d"), tic4x_cpu
);
2725 case OPTION_REV
: /* cpu revision */
2726 tic4x_revision
= atoi (arg
);
2730 as_warn (_("Option -b is depreciated, please use -mbig"));
2731 case OPTION_BIG
: /* big model */
2732 tic4x_big_model
= 1;
2736 as_warn (_("Option -p is depreciated, please use -mmemparm"));
2737 case OPTION_MEMPARM
: /* push args */
2742 as_warn (_("Option -r is depreciated, please use -mregparm"));
2743 case OPTION_REGPARM
: /* register args */
2748 as_warn (_("Option -s is depreciated, please use -msmall"));
2749 case OPTION_SMALL
: /* small model */
2750 tic4x_big_model
= 0;
2757 case OPTION_LOWPOWER
:
2761 case OPTION_ENHANCED
:
2773 md_show_usage (FILE *stream
)
2776 _("\nTIC4X options:\n"
2777 " -mcpu=CPU -mCPU select architecture variant. CPU can be:\n"
2779 " 31 - TMS320C31, TMS320LC31\n"
2781 " 33 - TMS320VC33\n"
2784 " -mrev=REV set cpu hardware revision (integer numbers).\n"
2785 " Combinations of -mcpu and -mrev will enable/disable\n"
2786 " the appropriate options (-midle2, -mlowpower and\n"
2787 " -menhanced) according to the selected type\n"
2788 " -mbig select big memory model\n"
2789 " -msmall select small memory model (default)\n"
2790 " -mregparm select register parameters (default)\n"
2791 " -mmemparm select memory parameters\n"
2792 " -midle2 enable IDLE2 support\n"
2793 " -mlowpower enable LOPOWER and MAXSPEED support\n"
2794 " -menhanced enable enhanced opcode support\n"));
2797 /* This is called when a line is unrecognized. This is used to handle
2798 definitions of TI C3x tools style local labels $n where n is a single
2801 tic4x_unrecognized_line (int c
)
2806 if (c
!= '$' || ! ISDIGIT (input_line_pointer
[0]))
2809 s
= input_line_pointer
;
2811 /* Let's allow multiple digit local labels. */
2813 while (ISDIGIT (*s
))
2815 lab
= lab
* 10 + *s
- '0';
2819 if (dollar_label_defined (lab
))
2821 as_bad (_("Label \"$%d\" redefined"), lab
);
2825 define_dollar_label (lab
);
2826 colon (dollar_label_name (lab
, 0));
2827 input_line_pointer
= s
+ 1;
2832 /* Handle local labels peculiar to us referred to in an expression. */
2834 md_undefined_symbol (char *name
)
2836 /* Look for local labels of the form $n. */
2837 if (name
[0] == '$' && ISDIGIT (name
[1]))
2843 while (ISDIGIT ((unsigned char) *s
))
2845 lab
= lab
* 10 + *s
- '0';
2848 if (dollar_label_defined (lab
))
2850 name
= dollar_label_name (lab
, 0);
2851 symbolP
= symbol_find (name
);
2855 name
= dollar_label_name (lab
, 1);
2856 symbolP
= symbol_find_or_make (name
);
2864 /* Parse an operand that is machine-specific. */
2866 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
2870 /* Round up a section size to the appropriate boundary---do we need this? */
2872 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
2874 return size
; /* Byte (i.e., 32-bit) alignment is fine? */
2878 tic4x_pc_offset (unsigned int op
)
2880 /* Determine the PC offset for a C[34]x instruction.
2881 This could be simplified using some boolean algebra
2882 but at the expense of readability. */
2886 case 0x62: /* call (C4x) */
2887 case 0x64: /* rptb (C4x) */
2889 case 0x61: /* brd */
2890 case 0x63: /* laj */
2891 case 0x65: /* rptbd (C4x) */
2893 case 0x66: /* swi */
2900 switch ((op
& 0xffe00000) >> 20)
2902 case 0x6a0: /* bB */
2903 case 0x720: /* callB */
2904 case 0x740: /* trapB */
2907 case 0x6a2: /* bBd */
2908 case 0x6a6: /* bBat */
2909 case 0x6aa: /* bBaf */
2910 case 0x722: /* lajB */
2911 case 0x748: /* latB */
2912 case 0x798: /* rptbd */
2919 switch ((op
& 0xfe200000) >> 20)
2921 case 0x6e0: /* dbB */
2924 case 0x6e2: /* dbBd */
2934 /* Exactly what point is a PC-relative offset relative TO?
2935 With the C3x we have the following:
2936 DBcond, Bcond disp + PC + 1 => PC
2937 DBcondD, BcondD disp + PC + 3 => PC
2940 md_pcrel_from (fixS
*fixP
)
2945 buf
= (unsigned char *) fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2946 op
= (buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
2948 return ((fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) >> 2) +
2949 tic4x_pc_offset (op
);
2952 /* Fill the alignment area with NOP's on .text, unless fill-data
2955 tic4x_do_align (int alignment
,
2960 /* Because we are talking lwords, not bytes, adjust alignment to do words */
2963 if (alignment
!= 0 && !need_pass_2
)
2967 if (subseg_text_p (now_seg
))
2971 md_number_to_chars (nop
, TIC_NOP_OPCODE
, 4);
2972 frag_align_pattern (alignment
, nop
, sizeof (nop
), max
);
2975 frag_align (alignment
, 0, max
);
2978 frag_align (alignment
, *fill
, max
);
2980 frag_align_pattern (alignment
, fill
, len
, max
);
2983 /* Return 1 to skip the default alignment function */
2987 /* Look for and remove parallel instruction operator ||. */
2989 tic4x_start_line (void)
2991 char *s
= input_line_pointer
;
2995 /* If parallel instruction prefix found at start of line, skip it. */
2996 if (*input_line_pointer
== '|' && input_line_pointer
[1] == '|')
3001 input_line_pointer
++;
3002 *input_line_pointer
= ' ';
3003 /* So line counters get bumped. */
3004 input_line_pointer
[-1] = '\n';
3009 /* Write out the previous insn here */
3012 input_line_pointer
= s
;
3017 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixP
)
3021 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
3023 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
3024 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
3025 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
3026 reloc
->address
/= OCTETS_PER_BYTE
;
3027 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
3028 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
3030 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3031 _("Reloc %d not supported by object file format"),
3032 (int) fixP
->fx_r_type
);
3036 if (fixP
->fx_r_type
== BFD_RELOC_HI16
)
3037 reloc
->addend
= fixP
->fx_offset
;
3039 reloc
->addend
= fixP
->fx_addnumber
;