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 (const 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 (const 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
)
718 str
= input_line_pointer
;
720 /* Skip string expression. */
721 while (*input_line_pointer
!= ',' && *input_line_pointer
)
722 input_line_pointer
++;
723 if (*input_line_pointer
!= ',')
725 as_bad (_("Comma expected\n"));
728 *input_line_pointer
++ = '\0';
729 c
= get_symbol_name (&name
); /* Get terminator. */
731 name
= xstrdup (name
);
732 if (hash_find (tic4x_asg_hash
, name
))
733 hash_replace (tic4x_asg_hash
, name
, (void *) str
);
735 hash_insert (tic4x_asg_hash
, name
, (void *) str
);
736 (void) restore_line_pointer (c
);
737 demand_empty_rest_of_line ();
740 /* .bss symbol, size */
742 tic4x_bss (int x ATTRIBUTE_UNUSED
)
749 subsegT current_subseg
;
752 current_seg
= now_seg
; /* Save current seg. */
753 current_subseg
= now_subseg
; /* Save current subseg. */
756 c
= get_symbol_name (&name
); /* Get terminator. */
758 c
= * ++ input_line_pointer
;
761 as_bad (_(".bss size argument missing\n"));
766 tic4x_expression_abs (++input_line_pointer
, &size
);
769 as_bad (_(".bss size %ld < 0!"), (long) size
);
772 subseg_set (bss_section
, 0);
773 symbolP
= symbol_find_or_make (name
);
775 if (S_GET_SEGMENT (symbolP
) == bss_section
)
776 symbol_get_frag (symbolP
)->fr_symbol
= 0;
778 symbol_set_frag (symbolP
, frag_now
);
780 p
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
,
781 size
* OCTETS_PER_BYTE
, (char *) 0);
782 *p
= 0; /* Fill char. */
784 S_SET_SEGMENT (symbolP
, bss_section
);
786 /* The symbol may already have been created with a preceding
787 ".globl" directive -- be careful not to step on storage class
788 in that case. Otherwise, set it to static. */
789 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
790 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
792 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
793 demand_empty_rest_of_line ();
797 tic4x_globl (int ignore ATTRIBUTE_UNUSED
)
805 c
= get_symbol_name (&name
);
806 symbolP
= symbol_find_or_make (name
);
807 *input_line_pointer
= c
;
808 SKIP_WHITESPACE_AFTER_NAME ();
809 S_SET_STORAGE_CLASS (symbolP
, C_EXT
);
810 S_SET_EXTERNAL (symbolP
);
813 input_line_pointer
++;
815 if (*input_line_pointer
== '\n')
821 demand_empty_rest_of_line ();
824 /* Handle .byte, .word. .int, .long */
826 tic4x_cons (int bytes
)
832 if (*input_line_pointer
== '"')
834 input_line_pointer
++;
835 while (is_a_char (c
= next_char_of_string ()))
836 tic4x_emit_char (c
, 4);
837 know (input_line_pointer
[-1] == '\"');
843 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
844 if (exp
.X_op
== O_constant
)
849 exp
.X_add_number
&= 255;
852 exp
.X_add_number
&= 65535;
856 /* Perhaps we should disallow .byte and .hword with
857 a non constant expression that will require relocation. */
861 while (*input_line_pointer
++ == ',');
863 input_line_pointer
--; /* Put terminator back into stream. */
864 demand_empty_rest_of_line ();
867 /* Handle .ascii, .asciz, .string */
869 tic4x_stringer (int append_zero
)
878 if (*input_line_pointer
== '"')
880 input_line_pointer
++;
881 while (is_a_char (c
= next_char_of_string ()))
883 tic4x_emit_char (c
, 1);
889 tic4x_emit_char (c
, 1);
893 know (input_line_pointer
[-1] == '\"');
899 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
900 if (exp
.X_op
!= O_constant
)
902 as_bad (_("Non-constant symbols not allowed\n"));
905 exp
.X_add_number
&= 255; /* Limit numeber to 8-bit */
910 while (*input_line_pointer
++ == ',');
912 /* Fill out the rest of the expression with 0's to fill up a full word */
914 tic4x_emit_char (0, 4-(bytes
&0x3));
916 input_line_pointer
--; /* Put terminator back into stream. */
917 demand_empty_rest_of_line ();
920 /* .eval expression, symbol */
922 tic4x_eval (int x ATTRIBUTE_UNUSED
)
930 tic4x_expression_abs (input_line_pointer
, &value
);
931 if (*input_line_pointer
++ != ',')
933 as_bad (_("Symbol missing\n"));
936 c
= get_symbol_name (&name
); /* Get terminator. */
937 tic4x_insert_sym (name
, value
);
938 (void) restore_line_pointer (c
);
939 demand_empty_rest_of_line ();
942 /* Reset local labels. */
944 tic4x_newblock (int x ATTRIBUTE_UNUSED
)
946 dollar_label_clear ();
949 /* .sect "section-name" [, value] */
950 /* .sect ["]section-name[:subsection-name]["] [, value] */
952 tic4x_sect (int x ATTRIBUTE_UNUSED
)
961 if (*input_line_pointer
== '"')
962 input_line_pointer
++;
963 c
= get_symbol_name (§ion_name
); /* Get terminator. */
965 c
= * ++ input_line_pointer
;
966 input_line_pointer
++; /* Skip null symbol terminator. */
967 name
= xmalloc (input_line_pointer
- section_name
+ 1);
968 strcpy (name
, section_name
);
970 /* TI C from version 5.0 allows a section name to contain a
971 subsection name as well. The subsection name is separated by a
972 ':' from the section name. Currently we scan the subsection
974 Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>. */
978 c
= get_symbol_name (&subname
); /* Get terminator. */
980 c
= * ++ input_line_pointer
;
981 input_line_pointer
++; /* Skip null symbol terminator. */
982 as_warn (_(".sect: subsection name ignored"));
985 /* We might still have a '"' to discard, but the character after a
986 symbol name will be overwritten with a \0 by get_symbol_name()
991 tic4x_expression_abs (input_line_pointer
, &num
);
992 else if (*input_line_pointer
== ',')
995 tic4x_expression_abs (++input_line_pointer
, &num
);
1000 seg
= subseg_new (name
, num
);
1001 if (line_label
!= NULL
)
1003 S_SET_SEGMENT (line_label
, seg
);
1004 symbol_set_frag (line_label
, frag_now
);
1007 if (bfd_get_section_flags (stdoutput
, seg
) == SEC_NO_FLAGS
)
1009 if (!bfd_set_section_flags (stdoutput
, seg
, SEC_DATA
))
1010 as_warn (_("Error setting flags for \"%s\": %s"), name
,
1011 bfd_errmsg (bfd_get_error ()));
1014 /* If the last character overwritten by get_symbol_name() was an
1015 end-of-line, we must restore it or the end of the line will not be
1016 recognised and scanning extends into the next line, stopping with
1017 an error (blame Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>
1018 if this is not true). */
1019 if (is_end_of_line
[(unsigned char) c
])
1020 *(--input_line_pointer
) = c
;
1022 demand_empty_rest_of_line ();
1025 /* symbol[:] .set value or .set symbol, value */
1027 tic4x_set (int x ATTRIBUTE_UNUSED
)
1032 if ((symbolP
= line_label
) == NULL
)
1037 c
= get_symbol_name (&name
); /* Get terminator. */
1039 c
= * ++ input_line_pointer
;
1042 as_bad (_(".set syntax invalid\n"));
1043 ignore_rest_of_line ();
1046 ++input_line_pointer
;
1047 symbolP
= symbol_find_or_make (name
);
1050 symbol_table_insert (symbolP
);
1052 pseudo_set (symbolP
);
1053 demand_empty_rest_of_line ();
1056 /* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
1058 tic4x_usect (int x ATTRIBUTE_UNUSED
)
1064 offsetT size
, alignment_flag
;
1066 subsegT current_subseg
;
1068 current_seg
= now_seg
; /* save current seg. */
1069 current_subseg
= now_subseg
; /* save current subseg. */
1072 if (*input_line_pointer
== '"')
1073 input_line_pointer
++;
1074 c
= get_symbol_name (§ion_name
); /* Get terminator. */
1076 c
= * ++ input_line_pointer
;
1077 input_line_pointer
++; /* Skip null symbol terminator. */
1078 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1079 strcpy (name
, section_name
);
1082 input_line_pointer
=
1083 tic4x_expression_abs (input_line_pointer
, &size
);
1084 else if (*input_line_pointer
== ',')
1086 input_line_pointer
=
1087 tic4x_expression_abs (++input_line_pointer
, &size
);
1092 /* Read a possibly present third argument (alignment flag) [VK]. */
1093 if (*input_line_pointer
== ',')
1095 input_line_pointer
=
1096 tic4x_expression_abs (++input_line_pointer
, &alignment_flag
);
1101 as_warn (_(".usect: non-zero alignment flag ignored"));
1103 seg
= subseg_new (name
, 0);
1104 if (line_label
!= NULL
)
1106 S_SET_SEGMENT (line_label
, seg
);
1107 symbol_set_frag (line_label
, frag_now
);
1108 S_SET_VALUE (line_label
, frag_now_fix ());
1110 seg_info (seg
)->bss
= 1; /* Uninitialised data. */
1111 if (!bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
))
1112 as_warn (_("Error setting flags for \"%s\": %s"), name
,
1113 bfd_errmsg (bfd_get_error ()));
1114 tic4x_seg_alloc (name
, seg
, size
, line_label
);
1116 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1117 S_SET_STORAGE_CLASS (line_label
, C_STAT
);
1119 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
1120 demand_empty_rest_of_line ();
1123 /* .version cpu-version. */
1125 tic4x_version (int x ATTRIBUTE_UNUSED
)
1129 input_line_pointer
=
1130 tic4x_expression_abs (input_line_pointer
, &temp
);
1131 if (!IS_CPU_TIC3X (temp
) && !IS_CPU_TIC4X (temp
))
1132 as_bad (_("This assembler does not support processor generation %ld"),
1135 if (tic4x_cpu
&& temp
!= (offsetT
) tic4x_cpu
)
1136 as_warn (_("Changing processor generation on fly not supported..."));
1138 demand_empty_rest_of_line ();
1142 tic4x_init_regtable (void)
1146 for (i
= 0; i
< tic3x_num_registers
; i
++)
1147 tic4x_insert_reg (tic3x_registers
[i
].name
,
1148 tic3x_registers
[i
].regno
);
1150 if (IS_CPU_TIC4X (tic4x_cpu
))
1152 /* Add additional Tic4x registers, overriding some C3x ones. */
1153 for (i
= 0; i
< tic4x_num_registers
; i
++)
1154 tic4x_insert_reg (tic4x_registers
[i
].name
,
1155 tic4x_registers
[i
].regno
);
1160 tic4x_init_symbols (void)
1162 /* The TI tools accept case insensitive versions of these symbols,
1167 .TMS320xx 30,31,32,40,or 44 set according to -v flag
1168 .C3X or .C3x 1 or 0 1 if -v30,-v31,or -v32
1169 .C30 1 or 0 1 if -v30
1170 .C31 1 or 0 1 if -v31
1171 .C32 1 or 0 1 if -v32
1172 .C4X or .C4x 1 or 0 1 if -v40, or -v44
1173 .C40 1 or 0 1 if -v40
1174 .C44 1 or 0 1 if -v44
1176 .REGPARM 1 or 0 1 if -mr option used
1177 .BIGMODEL 1 or 0 1 if -mb option used
1179 These symbols are currently supported but will be removed in a
1181 .TMS320C30 1 or 0 1 if -v30,-v31,or -v32
1182 .TMS320C31 1 or 0 1 if -v31
1183 .TMS320C32 1 or 0 1 if -v32
1184 .TMS320C40 1 or 0 1 if -v40, or -v44
1185 .TMS320C44 1 or 0 1 if -v44
1187 Source: TI: TMS320C3x/C4x Assembly Language Tools User's Guide,
1188 1997, SPRU035C, p. 3-17/3-18. */
1189 tic4x_insert_sym (".REGPARM", tic4x_reg_args
);
1190 tic4x_insert_sym (".MEMPARM", !tic4x_reg_args
);
1191 tic4x_insert_sym (".BIGMODEL", tic4x_big_model
);
1192 tic4x_insert_sym (".C30INTERRUPT", 0);
1193 tic4x_insert_sym (".TMS320xx", tic4x_cpu
== 0 ? 40 : tic4x_cpu
);
1194 tic4x_insert_sym (".C3X", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1195 tic4x_insert_sym (".C3x", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1196 tic4x_insert_sym (".C4X", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1197 tic4x_insert_sym (".C4x", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1198 /* Do we need to have the following symbols also in lower case? */
1199 tic4x_insert_sym (".TMS320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1200 tic4x_insert_sym (".tms320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1201 tic4x_insert_sym (".TMS320C31", tic4x_cpu
== 31);
1202 tic4x_insert_sym (".tms320C31", tic4x_cpu
== 31);
1203 tic4x_insert_sym (".TMS320C32", tic4x_cpu
== 32);
1204 tic4x_insert_sym (".tms320C32", tic4x_cpu
== 32);
1205 tic4x_insert_sym (".TMS320C33", tic4x_cpu
== 33);
1206 tic4x_insert_sym (".tms320C33", tic4x_cpu
== 33);
1207 tic4x_insert_sym (".TMS320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1208 tic4x_insert_sym (".tms320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1209 tic4x_insert_sym (".TMS320C44", tic4x_cpu
== 44);
1210 tic4x_insert_sym (".tms320C44", tic4x_cpu
== 44);
1211 tic4x_insert_sym (".TMX320C40", 0); /* C40 first pass silicon ? */
1212 tic4x_insert_sym (".tmx320C40", 0);
1215 /* Insert a new instruction template into hash table. */
1217 tic4x_inst_insert (const tic4x_inst_t
*inst
)
1219 static char prev_name
[16];
1220 const char *retval
= NULL
;
1222 /* Only insert the first name if have several similar entries. */
1223 if (!strcmp (inst
->name
, prev_name
) || inst
->name
[0] == '\0')
1226 retval
= hash_insert (tic4x_op_hash
, inst
->name
, (void *) inst
);
1228 fprintf (stderr
, "internal error: can't hash `%s': %s\n",
1229 inst
->name
, retval
);
1231 strcpy (prev_name
, inst
->name
);
1232 return retval
== NULL
;
1235 /* Make a new instruction template. */
1236 static tic4x_inst_t
*
1237 tic4x_inst_make (const char *name
, unsigned long opcode
, const char *args
)
1239 static tic4x_inst_t
*insts
= NULL
;
1240 static char *names
= NULL
;
1241 static int iindex
= 0;
1245 /* Allocate memory to store name strings. */
1246 names
= (char *) xmalloc (sizeof (char) * 8192);
1247 /* Allocate memory for additional insts. */
1248 insts
= (tic4x_inst_t
*)
1249 xmalloc (sizeof (tic4x_inst_t
) * 1024);
1251 insts
[iindex
].name
= names
;
1252 insts
[iindex
].opcode
= opcode
;
1253 insts
[iindex
].opmask
= 0xffffffff;
1254 insts
[iindex
].args
= args
;
1262 return &insts
[iindex
- 1];
1265 /* Add instruction template, creating dynamic templates as required. */
1267 tic4x_inst_add (const tic4x_inst_t
*insts
)
1269 const char *s
= insts
->name
;
1277 /* We do not care about INSNs that is not a part of our
1279 if ((insts
->oplevel
& tic4x_oplevel
) == 0)
1288 /* Dynamically create all the conditional insts. */
1289 for (i
= 0; i
< tic4x_num_conds
; i
++)
1293 const char *c
= tic4x_conds
[i
].name
;
1303 /* If instruction found then have already processed it. */
1304 if (hash_find (tic4x_op_hash
, name
))
1309 inst
= tic4x_inst_make (name
, insts
[k
].opcode
+
1310 (tic4x_conds
[i
].cond
<<
1311 (*s
== 'B' ? 16 : 23)),
1313 if (k
== 0) /* Save strcmp() with following func. */
1314 ok
&= tic4x_inst_insert (inst
);
1317 while (!strcmp (insts
->name
,
1324 return tic4x_inst_insert (insts
);
1334 /* This function is called once, at assembler startup time. It should
1335 set up all the tables, etc., that the MD part of the assembler will
1343 /* Setup the proper opcode level according to the
1344 commandline parameters */
1345 tic4x_oplevel
= OP_C3X
;
1347 if ( IS_CPU_TIC4X(tic4x_cpu
) )
1348 tic4x_oplevel
|= OP_C4X
;
1350 if ( ( tic4x_cpu
== 31 && tic4x_revision
>= 6)
1351 || (tic4x_cpu
== 32 && tic4x_revision
>= 2)
1352 || (tic4x_cpu
== 33)
1354 tic4x_oplevel
|= OP_ENH
;
1356 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1357 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1358 || (tic4x_cpu
== 32)
1360 tic4x_oplevel
|= OP_LPWR
;
1362 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1363 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1364 || (tic4x_cpu
== 32)
1365 || (tic4x_cpu
== 33)
1366 || (tic4x_cpu
== 40 && tic4x_revision
>= 5)
1367 || (tic4x_cpu
== 44)
1369 tic4x_oplevel
|= OP_IDLE2
;
1371 /* Create hash table for mnemonics. */
1372 tic4x_op_hash
= hash_new ();
1374 /* Create hash table for asg pseudo. */
1375 tic4x_asg_hash
= hash_new ();
1377 /* Add mnemonics to hash table, expanding conditional mnemonics on fly. */
1378 for (i
= 0; i
< tic4x_num_insts
; i
++)
1379 ok
&= tic4x_inst_add (tic4x_insts
+ i
);
1381 /* Create dummy inst to avoid errors accessing end of table. */
1382 tic4x_inst_make ("", 0, "");
1385 as_fatal ("Broken assembler. No assembly attempted.");
1387 /* Add registers to symbol table. */
1388 tic4x_init_regtable ();
1390 /* Add predefined symbols to symbol table. */
1391 tic4x_init_symbols ();
1397 bfd_set_arch_mach (stdoutput
, bfd_arch_tic4x
,
1398 IS_CPU_TIC4X (tic4x_cpu
) ? bfd_mach_tic4x
: bfd_mach_tic3x
);
1402 tic4x_indirect_parse (tic4x_operand_t
*operand
,
1403 const tic4x_indirect_t
*indirect
)
1405 const char *n
= indirect
->name
;
1406 char *s
= input_line_pointer
;
1416 case 'a': /* Need to match aux register. */
1418 #ifdef TIC4X_ALT_SYNTAX
1422 while (ISALNUM (*s
))
1425 if (!(symbolP
= symbol_find (name
)))
1428 if (S_GET_SEGMENT (symbolP
) != reg_section
)
1431 operand
->aregno
= S_GET_VALUE (symbolP
);
1432 if (operand
->aregno
>= REG_AR0
&& operand
->aregno
<= REG_AR7
)
1435 as_bad (_("Auxiliary register AR0--AR7 required for indirect"));
1438 case 'd': /* Need to match constant for disp. */
1439 #ifdef TIC4X_ALT_SYNTAX
1440 if (*s
== '%') /* expr() will die if we don't skip this. */
1443 s
= tic4x_expression (s
, &operand
->expr
);
1444 if (operand
->expr
.X_op
!= O_constant
)
1446 operand
->disp
= operand
->expr
.X_add_number
;
1447 if (operand
->disp
< 0 || operand
->disp
> 255)
1449 as_bad (_("Bad displacement %d (require 0--255)\n"),
1455 case 'y': /* Need to match IR0. */
1456 case 'z': /* Need to match IR1. */
1457 #ifdef TIC4X_ALT_SYNTAX
1461 s
= tic4x_expression (s
, &operand
->expr
);
1462 if (operand
->expr
.X_op
!= O_register
)
1464 if (operand
->expr
.X_add_number
!= REG_IR0
1465 && operand
->expr
.X_add_number
!= REG_IR1
)
1467 as_bad (_("Index register IR0,IR1 required for displacement"));
1471 if (*n
== 'y' && operand
->expr
.X_add_number
== REG_IR0
)
1473 if (*n
== 'z' && operand
->expr
.X_add_number
== REG_IR1
)
1478 if (*s
!= '(') /* No displacement, assume to be 1. */
1489 if (TOLOWER (*s
) != *n
)
1494 if (*s
!= ' ' && *s
!= ',' && *s
!= '\0')
1496 input_line_pointer
= s
;
1501 tic4x_operand_parse (char *s
, tic4x_operand_t
*operand
)
1506 expressionS
*exp
= &operand
->expr
;
1507 char *save
= input_line_pointer
;
1510 struct hash_entry
*entry
= NULL
;
1512 input_line_pointer
= s
;
1515 c
= get_symbol_name (&str
); /* Get terminator. */
1516 new_pointer
= input_line_pointer
;
1517 if (strlen (str
) && (entry
= hash_find (tic4x_asg_hash
, str
)) != NULL
)
1519 (void) restore_line_pointer (c
);
1520 input_line_pointer
= (char *) entry
;
1524 (void) restore_line_pointer (c
);
1525 input_line_pointer
= str
;
1528 operand
->mode
= M_UNKNOWN
;
1529 switch (*input_line_pointer
)
1531 #ifdef TIC4X_ALT_SYNTAX
1533 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1534 if (exp
->X_op
!= O_register
)
1535 as_bad (_("Expecting a register name"));
1536 operand
->mode
= M_REGISTER
;
1540 /* Denotes high 16 bits. */
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
)
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 .hi.foo, ar0 */
1556 /* WARNING : The TI C40 assembler cannot do this. */
1557 else if (exp
->X_op
== O_symbol
)
1559 operand
->mode
= M_HI
;
1564 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1565 if (exp
->X_op
== O_constant
)
1566 operand
->mode
= M_IMMED
;
1567 else if (exp
->X_op
== O_big
)
1569 if (exp
->X_add_number
> 0)
1570 as_bad (_("Number too large")); /* bignum required. */
1573 tic4x_gen_to_words (generic_floating_point_number
,
1574 operand
->fwords
, S_PRECISION
);
1575 operand
->mode
= M_IMMED_F
;
1578 /* Allow ori foo, ar0 to be equivalent to ldi .lo.foo, ar0 */
1579 /* WARNING : The TI C40 assembler cannot do this. */
1580 else if (exp
->X_op
== O_symbol
)
1582 operand
->mode
= M_IMMED
;
1587 as_bad (_("Expecting a constant value"));
1592 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1593 if (exp
->X_op
!= O_constant
&& exp
->X_op
!= O_symbol
)
1594 as_bad (_("Bad direct addressing construct %s"), s
);
1595 if (exp
->X_op
== O_constant
)
1597 if (exp
->X_add_number
< 0)
1598 as_bad (_("Direct value of %ld is not suitable"),
1599 (long) exp
->X_add_number
);
1601 operand
->mode
= M_DIRECT
;
1606 for (i
= 0; i
< tic4x_num_indirects
; i
++)
1607 if ((ret
= tic4x_indirect_parse (operand
, &tic4x_indirects
[i
])))
1611 if (i
< tic4x_num_indirects
)
1613 operand
->mode
= M_INDIRECT
;
1614 /* Indirect addressing mode number. */
1615 operand
->expr
.X_add_number
= tic4x_indirects
[i
].modn
;
1616 /* Convert *+ARn(0) to *ARn etc. Maybe we should
1617 squeal about silly ones? */
1618 if (operand
->expr
.X_add_number
< 0x08 && !operand
->disp
)
1619 operand
->expr
.X_add_number
= 0x18;
1622 as_bad (_("Unknown indirect addressing mode"));
1626 operand
->mode
= M_IMMED
; /* Assume immediate. */
1627 str
= input_line_pointer
;
1628 input_line_pointer
= tic4x_expression (input_line_pointer
, exp
);
1629 if (exp
->X_op
== O_register
)
1631 know (exp
->X_add_symbol
== 0);
1632 know (exp
->X_op_symbol
== 0);
1633 operand
->mode
= M_REGISTER
;
1636 else if (exp
->X_op
== O_big
)
1638 if (exp
->X_add_number
> 0)
1639 as_bad (_("Number too large")); /* bignum required. */
1642 tic4x_gen_to_words (generic_floating_point_number
,
1643 operand
->fwords
, S_PRECISION
);
1644 operand
->mode
= M_IMMED_F
;
1648 #ifdef TIC4X_ALT_SYNTAX
1649 /* Allow ldi foo, ar0 to be equivalent to ldi @foo, ar0. */
1650 else if (exp
->X_op
== O_symbol
)
1652 operand
->mode
= M_DIRECT
;
1658 new_pointer
= input_line_pointer
;
1659 input_line_pointer
= save
;
1664 tic4x_operands_match (tic4x_inst_t
*inst
, tic4x_insn_t
*tinsn
, int check
)
1666 const char *args
= inst
->args
;
1667 unsigned long opcode
= inst
->opcode
;
1668 int num_operands
= tinsn
->num_operands
;
1669 tic4x_operand_t
*operand
= tinsn
->operands
;
1670 expressionS
*exp
= &operand
->expr
;
1674 /* Build the opcode, checking as we go to make sure that the
1677 If an operand matches, we modify insn or opcode appropriately,
1678 and do a "continue". If an operand fails to match, we "break". */
1680 tinsn
->nchars
= 4; /* Instructions always 4 bytes. */
1681 tinsn
->reloc
= NO_RELOC
;
1686 tinsn
->opcode
= opcode
;
1687 return num_operands
== 0;
1695 case '\0': /* End of args. */
1696 if (num_operands
== 1)
1698 tinsn
->opcode
= opcode
;
1701 break; /* Too many operands. */
1703 case '#': /* This is only used for ldp. */
1704 if (operand
->mode
!= M_DIRECT
&& operand
->mode
!= M_IMMED
)
1706 /* While this looks like a direct addressing mode, we actually
1707 use an immediate mode form of ldiu or ldpk instruction. */
1708 if (exp
->X_op
== O_constant
)
1710 if( ( IS_CPU_TIC4X (tic4x_cpu
) && exp
->X_add_number
<= 65535 )
1711 || ( IS_CPU_TIC3X (tic4x_cpu
) && exp
->X_add_number
<= 255 ) )
1713 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1719 as_bad (_("Immediate value of %ld is too large for ldf"),
1720 (long) exp
->X_add_number
);
1725 else if (exp
->X_op
== O_symbol
)
1727 tinsn
->reloc
= BFD_RELOC_HI16
;
1731 break; /* Not direct (dp) addressing. */
1733 case '@': /* direct. */
1734 if (operand
->mode
!= M_DIRECT
)
1736 if (exp
->X_op
== O_constant
)
1738 /* Store only the 16 LSBs of the number. */
1739 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1742 else if (exp
->X_op
== O_symbol
)
1744 tinsn
->reloc
= BFD_RELOC_LO16
;
1748 break; /* Not direct addressing. */
1751 if (operand
->mode
!= M_REGISTER
)
1753 reg
= exp
->X_add_number
;
1754 if (reg
>= REG_AR0
&& reg
<= REG_AR7
)
1755 INSERTU (opcode
, reg
- REG_AR0
, 24, 22);
1759 as_bad (_("Destination register must be ARn"));
1764 case 'B': /* Unsigned integer immediate. */
1765 /* Allow br label or br @label. */
1766 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
1768 if (exp
->X_op
== O_constant
)
1770 if (exp
->X_add_number
< (1 << 24))
1772 INSERTU (opcode
, exp
->X_add_number
, 23, 0);
1778 as_bad (_("Immediate value of %ld is too large"),
1779 (long) exp
->X_add_number
);
1784 if (IS_CPU_TIC4X (tic4x_cpu
))
1786 tinsn
->reloc
= BFD_RELOC_24_PCREL
;
1791 tinsn
->reloc
= BFD_RELOC_24
;
1798 if (!IS_CPU_TIC4X (tic4x_cpu
))
1800 if (operand
->mode
!= M_INDIRECT
)
1802 /* Require either *+ARn(disp) or *ARn. */
1803 if (operand
->expr
.X_add_number
!= 0
1804 && operand
->expr
.X_add_number
!= 0x18)
1807 as_bad (_("Invalid indirect addressing mode"));
1811 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1812 INSERTU (opcode
, operand
->disp
, 7, 3);
1816 if (!(operand
->mode
== M_REGISTER
))
1818 INSERTU (opcode
, exp
->X_add_number
, 7, 0);
1822 if (!(operand
->mode
== M_REGISTER
))
1824 reg
= exp
->X_add_number
;
1825 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1826 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1827 INSERTU (opcode
, reg
, 7, 0);
1831 as_bad (_("Register must be Rn"));
1837 if (operand
->mode
!= M_IMMED_F
1838 && !(operand
->mode
== M_IMMED
&& exp
->X_op
== O_constant
))
1841 if (operand
->mode
!= M_IMMED_F
)
1843 /* OK, we 've got something like cmpf 0, r0
1844 Why can't they stick in a bloody decimal point ?! */
1847 /* Create floating point number string. */
1848 sprintf (string
, "%d.0", (int) exp
->X_add_number
);
1849 tic4x_atof (string
, 's', operand
->fwords
);
1852 INSERTU (opcode
, operand
->fwords
[0], 15, 0);
1856 if (operand
->mode
!= M_REGISTER
)
1858 INSERTU (opcode
, exp
->X_add_number
, 15, 8);
1862 if (operand
->mode
!= M_REGISTER
)
1864 reg
= exp
->X_add_number
;
1865 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1866 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1867 INSERTU (opcode
, reg
, 15, 8);
1871 as_bad (_("Register must be Rn"));
1877 if (operand
->mode
!= M_REGISTER
)
1879 reg
= exp
->X_add_number
;
1880 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1881 INSERTU (opcode
, reg
- REG_R0
, 18, 16);
1885 as_bad (_("Register must be R0--R7"));
1891 if ( operand
->mode
== M_REGISTER
1892 && tic4x_oplevel
& OP_ENH
)
1894 reg
= exp
->X_add_number
;
1895 INSERTU (opcode
, reg
, 4, 0);
1896 INSERTU (opcode
, 7, 7, 5);
1902 if (operand
->mode
!= M_INDIRECT
)
1904 if (operand
->disp
!= 0 && operand
->disp
!= 1)
1906 if (IS_CPU_TIC4X (tic4x_cpu
))
1909 as_bad (_("Invalid indirect addressing mode displacement %d"),
1914 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1915 INSERTU (opcode
, operand
->expr
.X_add_number
, 7, 3);
1919 if ( operand
->mode
== M_REGISTER
1920 && tic4x_oplevel
& OP_ENH
)
1922 reg
= exp
->X_add_number
;
1923 INSERTU (opcode
, reg
, 12, 8);
1924 INSERTU (opcode
, 7, 15, 13);
1930 if (operand
->mode
!= M_INDIRECT
)
1932 if (operand
->disp
!= 0 && operand
->disp
!= 1)
1934 if (IS_CPU_TIC4X (tic4x_cpu
))
1937 as_bad (_("Invalid indirect addressing mode displacement %d"),
1942 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
1943 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
1947 if (operand
->mode
!= M_REGISTER
)
1949 reg
= exp
->X_add_number
;
1950 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1951 INSERTU (opcode
, reg
- REG_R0
, 21, 19);
1955 as_bad (_("Register must be R0--R7"));
1961 if (operand
->mode
!= M_REGISTER
)
1963 reg
= exp
->X_add_number
;
1964 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1965 INSERTU (opcode
, reg
- REG_R0
, 24, 22);
1969 as_bad (_("Register must be R0--R7"));
1975 if (operand
->mode
!= M_REGISTER
)
1977 reg
= exp
->X_add_number
;
1978 if (reg
== REG_R2
|| reg
== REG_R3
)
1979 INSERTU (opcode
, reg
- REG_R2
, 22, 22);
1983 as_bad (_("Destination register must be R2 or R3"));
1989 if (operand
->mode
!= M_REGISTER
)
1991 reg
= exp
->X_add_number
;
1992 if (reg
== REG_R0
|| reg
== REG_R1
)
1993 INSERTU (opcode
, reg
- REG_R0
, 23, 23);
1997 as_bad (_("Destination register must be R0 or R1"));
2003 if (!IS_CPU_TIC4X (tic4x_cpu
))
2005 if (operand
->mode
!= M_INDIRECT
)
2007 /* Require either *+ARn(disp) or *ARn. */
2008 if (operand
->expr
.X_add_number
!= 0
2009 && operand
->expr
.X_add_number
!= 0x18)
2012 as_bad (_("Invalid indirect addressing mode"));
2016 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2017 INSERTU (opcode
, operand
->disp
, 15, 11);
2020 case 'P': /* PC relative displacement. */
2021 /* Allow br label or br @label. */
2022 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
2024 if (exp
->X_op
== O_constant
)
2026 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 32767)
2028 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2034 as_bad (_("Displacement value of %ld is too large"),
2035 (long) exp
->X_add_number
);
2040 tinsn
->reloc
= BFD_RELOC_16_PCREL
;
2046 if (operand
->mode
!= M_REGISTER
)
2048 reg
= exp
->X_add_number
;
2049 INSERTU (opcode
, reg
, 15, 0);
2053 if (operand
->mode
!= M_REGISTER
)
2055 reg
= exp
->X_add_number
;
2056 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2057 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2058 INSERTU (opcode
, reg
, 15, 0);
2062 as_bad (_("Register must be Rn"));
2068 if (operand
->mode
!= M_REGISTER
)
2070 reg
= exp
->X_add_number
;
2071 INSERTU (opcode
, reg
, 20, 16);
2075 if (operand
->mode
!= M_REGISTER
)
2077 reg
= exp
->X_add_number
;
2078 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2079 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2080 INSERTU (opcode
, reg
, 20, 16);
2084 as_bad (_("Register must be Rn"));
2089 case 'S': /* Short immediate int. */
2090 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2092 if (exp
->X_op
== O_big
)
2095 as_bad (_("Floating point number not valid in expression"));
2099 if (exp
->X_op
== O_constant
)
2101 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 65535)
2103 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2109 as_bad (_("Signed immediate value %ld too large"),
2110 (long) exp
->X_add_number
);
2115 else if (exp
->X_op
== O_symbol
)
2117 if (operand
->mode
== M_HI
)
2119 tinsn
->reloc
= BFD_RELOC_HI16
;
2123 tinsn
->reloc
= BFD_RELOC_LO16
;
2128 /* Handle cases like ldi foo - $, ar0 where foo
2129 is a forward reference. Perhaps we should check
2130 for X_op == O_symbol and disallow things like
2132 tinsn
->reloc
= BFD_RELOC_16
;
2136 case 'T': /* 5-bit immediate value for tic4x stik. */
2137 if (!IS_CPU_TIC4X (tic4x_cpu
))
2139 if (operand
->mode
!= M_IMMED
)
2141 if (exp
->X_op
== O_constant
)
2143 if (exp
->X_add_number
< 16 && exp
->X_add_number
>= -16)
2145 INSERTS (opcode
, exp
->X_add_number
, 20, 16);
2151 as_bad (_("Immediate value of %ld is too large"),
2152 (long) exp
->X_add_number
);
2157 break; /* No relocations allowed. */
2159 case 'U': /* Unsigned integer immediate. */
2160 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2162 if (exp
->X_op
== O_constant
)
2164 if (exp
->X_add_number
< (1 << 16) && exp
->X_add_number
>= 0)
2166 INSERTU (opcode
, exp
->X_add_number
, 15, 0);
2172 as_bad (_("Unsigned immediate value %ld too large"),
2173 (long) exp
->X_add_number
);
2178 else if (exp
->X_op
== O_symbol
)
2180 if (operand
->mode
== M_HI
)
2181 tinsn
->reloc
= BFD_RELOC_HI16
;
2183 tinsn
->reloc
= BFD_RELOC_LO16
;
2188 tinsn
->reloc
= BFD_RELOC_16
;
2192 case 'V': /* Trap numbers (immediate field). */
2193 if (operand
->mode
!= M_IMMED
)
2195 if (exp
->X_op
== O_constant
)
2197 if (exp
->X_add_number
< 512 && IS_CPU_TIC4X (tic4x_cpu
))
2199 INSERTU (opcode
, exp
->X_add_number
, 8, 0);
2202 else if (exp
->X_add_number
< 32 && IS_CPU_TIC3X (tic4x_cpu
))
2204 INSERTU (opcode
, exp
->X_add_number
| 0x20, 4, 0);
2210 as_bad (_("Immediate value of %ld is too large"),
2211 (long) exp
->X_add_number
);
2216 break; /* No relocations allowed. */
2218 case 'W': /* Short immediate int (0--7). */
2219 if (!IS_CPU_TIC4X (tic4x_cpu
))
2221 if (operand
->mode
!= M_IMMED
)
2223 if (exp
->X_op
== O_big
)
2226 as_bad (_("Floating point number not valid in expression"));
2230 if (exp
->X_op
== O_constant
)
2232 if (exp
->X_add_number
>= -256 && exp
->X_add_number
<= 127)
2234 INSERTS (opcode
, exp
->X_add_number
, 7, 0);
2240 as_bad (_("Immediate value %ld too large"),
2241 (long) exp
->X_add_number
);
2246 tinsn
->reloc
= BFD_RELOC_16
;
2250 case 'X': /* Expansion register for tic4x. */
2251 if (operand
->mode
!= M_REGISTER
)
2253 reg
= exp
->X_add_number
;
2254 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2255 INSERTU (opcode
, reg
- REG_IVTP
, 4, 0);
2259 as_bad (_("Register must be ivtp or tvtp"));
2264 case 'Y': /* Address register for tic4x lda. */
2265 if (operand
->mode
!= M_REGISTER
)
2267 reg
= exp
->X_add_number
;
2268 if (reg
>= REG_AR0
&& reg
<= REG_SP
)
2269 INSERTU (opcode
, reg
, 20, 16);
2273 as_bad (_("Register must be address register"));
2278 case 'Z': /* Expansion register for tic4x. */
2279 if (operand
->mode
!= M_REGISTER
)
2281 reg
= exp
->X_add_number
;
2282 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2283 INSERTU (opcode
, reg
- REG_IVTP
, 20, 16);
2287 as_bad (_("Register must be ivtp or tvtp"));
2293 if (operand
->mode
!= M_INDIRECT
)
2295 INSERTS (opcode
, operand
->disp
, 7, 0);
2296 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2297 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
2300 case '|': /* treat as `,' if have ldi_ldi form. */
2301 if (tinsn
->parallel
)
2303 if (--num_operands
< 0)
2304 break; /* Too few operands. */
2306 if (operand
->mode
!= M_PARALLEL
)
2311 case ',': /* Another operand. */
2312 if (--num_operands
< 0)
2313 break; /* Too few operands. */
2315 exp
= &operand
->expr
;
2318 case ';': /* Another optional operand. */
2319 if (num_operands
== 1 || operand
[1].mode
== M_PARALLEL
)
2321 if (--num_operands
< 0)
2322 break; /* Too few operands. */
2324 exp
= &operand
->expr
;
2335 tic4x_insn_check (tic4x_insn_t
*tinsn
)
2338 if (!strcmp (tinsn
->name
, "lda"))
2340 if (tinsn
->num_operands
< 2 || tinsn
->num_operands
> 2)
2341 as_fatal ("Illegal internal LDA insn definition");
2343 if (tinsn
->operands
[0].mode
== M_REGISTER
2344 && tinsn
->operands
[1].mode
== M_REGISTER
2345 && tinsn
->operands
[0].expr
.X_add_number
== tinsn
->operands
[1].expr
.X_add_number
)
2346 as_bad (_("Source and destination register should not be equal"));
2348 else if (!strcmp (tinsn
->name
, "ldi_ldi")
2349 || !strcmp (tinsn
->name
, "ldi1_ldi2")
2350 || !strcmp (tinsn
->name
, "ldi2_ldi1")
2351 || !strcmp (tinsn
->name
, "ldf_ldf")
2352 || !strcmp (tinsn
->name
, "ldf1_ldf2")
2353 || !strcmp (tinsn
->name
, "ldf2_ldf1") )
2355 if (tinsn
->num_operands
< 4 || tinsn
->num_operands
> 5)
2356 as_fatal ("Illegal internal %s insn definition", tinsn
->name
);
2358 if (tinsn
->operands
[1].mode
== M_REGISTER
2359 && tinsn
->operands
[tinsn
->num_operands
-1].mode
== M_REGISTER
2360 && tinsn
->operands
[1].expr
.X_add_number
== tinsn
->operands
[tinsn
->num_operands
-1].expr
.X_add_number
)
2361 as_warn (_("Equal parallell destination registers, one result will be discarded"));
2366 tic4x_insn_output (tic4x_insn_t
*tinsn
)
2370 /* Grab another fragment for opcode. */
2371 dst
= frag_more (tinsn
->nchars
);
2373 /* Put out opcode word as a series of bytes in little endian order. */
2374 md_number_to_chars (dst
, tinsn
->opcode
, tinsn
->nchars
);
2376 /* Put out the symbol-dependent stuff. */
2377 if (tinsn
->reloc
!= NO_RELOC
)
2379 /* Where is the offset into the fragment for this instruction. */
2380 fix_new_exp (frag_now
,
2381 dst
- frag_now
->fr_literal
, /* where */
2382 tinsn
->nchars
, /* size */
2389 /* Parse the operands. */
2391 tic4x_operands_parse (char *s
, tic4x_operand_t
*operands
, int num_operands
)
2394 return num_operands
;
2397 s
= tic4x_operand_parse (s
, &operands
[num_operands
++]);
2398 while (num_operands
< TIC4X_OPERANDS_MAX
&& *s
++ == ',');
2400 if (num_operands
> TIC4X_OPERANDS_MAX
)
2402 as_bad (_("Too many operands scanned"));
2405 return num_operands
;
2408 /* Assemble a single instruction. Its label has already been handled
2409 by the generic front end. We just parse mnemonic and operands, and
2410 produce the bytes of data and relocation. */
2412 md_assemble (char *str
)
2419 tic4x_inst_t
*inst
; /* Instruction template. */
2420 tic4x_inst_t
*first_inst
;
2422 /* Scan for parallel operators */
2426 while (*s
&& *s
!= '|')
2429 if (*s
&& s
[1]=='|')
2433 as_bad (_("Parallel opcode cannot contain more than two instructions"));
2439 /* Lets take care of the first part of the parallel insn */
2444 /* .. and let the second run though here */
2448 if (str
&& insn
->parallel
)
2450 /* Find mnemonic (second part of parallel instruction). */
2452 /* Skip past instruction mnemonic. */
2453 while (*s
&& *s
!= ' ')
2455 if (*s
) /* Null terminate for hash_find. */
2456 *s
++ = '\0'; /* and skip past null. */
2457 len
= strlen (insn
->name
);
2458 snprintf (insn
->name
+ len
, TIC4X_NAME_MAX
- len
, "_%s", str
);
2460 insn
->operands
[insn
->num_operands
++].mode
= M_PARALLEL
;
2462 if ((i
= tic4x_operands_parse
2463 (s
, insn
->operands
, insn
->num_operands
)) < 0)
2469 insn
->num_operands
= i
;
2475 if ((insn
->inst
= (struct tic4x_inst
*)
2476 hash_find (tic4x_op_hash
, insn
->name
)) == NULL
)
2478 as_bad (_("Unknown opcode `%s'."), insn
->name
);
2488 ok
= tic4x_operands_match (inst
, insn
, 1);
2495 } while (!ok
&& !strcmp (inst
->name
, inst
[1].name
) && inst
++);
2499 tic4x_insn_check (insn
);
2500 tic4x_insn_output (insn
);
2505 tic4x_operands_match (first_inst
, insn
, 0);
2506 as_bad (_("Invalid operands for %s"), insn
->name
);
2509 as_bad (_("Invalid instruction %s"), insn
->name
);
2514 /* Find mnemonic. */
2516 while (*s
&& *s
!= ' ') /* Skip past instruction mnemonic. */
2518 if (*s
) /* Null terminate for hash_find. */
2519 *s
++ = '\0'; /* and skip past null. */
2520 strncpy (insn
->name
, str
, TIC4X_NAME_MAX
- 1);
2521 insn
->name
[TIC4X_NAME_MAX
- 1] = '\0';
2523 if ((i
= tic4x_operands_parse (s
, insn
->operands
, 0)) < 0)
2525 insn
->inst
= NULL
; /* Flag that error occurred. */
2530 insn
->num_operands
= i
;
2539 tic4x_cleanup (void)
2545 /* Turn a string in input_line_pointer into a floating point constant
2546 of type type, and store the appropriate bytes in *litP. The number
2547 of chars emitted is stored in *sizeP. An error message is
2548 returned, or NULL on OK. */
2551 md_atof (int type
, char *litP
, int *sizeP
)
2555 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2556 LITTLENUM_TYPE
*wordP
;
2561 case 's': /* .single */
2567 case 'd': /* .double */
2569 case 'f': /* .float */
2572 prec
= 2; /* 1 32-bit word */
2575 case 'i': /* .ieee */
2579 type
= 'f'; /* Rewrite type to be usable by atof_ieee(). */
2582 case 'e': /* .ldouble */
2584 prec
= 4; /* 2 32-bit words */
2590 return _("Unrecognized or unsupported floating point constant");
2594 t
= atof_ieee (input_line_pointer
, type
, words
);
2596 t
= tic4x_atof (input_line_pointer
, type
, words
);
2598 input_line_pointer
= t
;
2599 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
2601 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
2602 little endian byte order. */
2603 /* SES: However it is required to put the words (32-bits) out in the
2604 correct order, hence we write 2 and 2 littlenums in little endian
2605 order, while we keep the original order on successive words. */
2606 for (wordP
= words
; wordP
<(words
+prec
) ; wordP
+=2)
2608 if (wordP
< (words
+ prec
- 1)) /* Dump wordP[1] (if we have one). */
2610 md_number_to_chars (litP
, (valueT
) (wordP
[1]),
2611 sizeof (LITTLENUM_TYPE
));
2612 litP
+= sizeof (LITTLENUM_TYPE
);
2616 md_number_to_chars (litP
, (valueT
) (wordP
[0]),
2617 sizeof (LITTLENUM_TYPE
));
2618 litP
+= sizeof (LITTLENUM_TYPE
);
2624 md_apply_fix (fixS
*fixP
, valueT
*value
, segT seg ATTRIBUTE_UNUSED
)
2626 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
2627 valueT val
= *value
;
2629 switch (fixP
->fx_r_type
)
2631 case BFD_RELOC_HI16
:
2635 case BFD_RELOC_LO16
:
2642 switch (fixP
->fx_r_type
)
2647 case BFD_RELOC_24_PCREL
:
2650 case BFD_RELOC_16_PCREL
:
2651 case BFD_RELOC_LO16
:
2652 case BFD_RELOC_HI16
:
2659 as_bad (_("Bad relocation type: 0x%02x"), fixP
->fx_r_type
);
2663 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0) fixP
->fx_done
= 1;
2666 /* Should never be called for tic4x. */
2668 md_convert_frag (bfd
*headers ATTRIBUTE_UNUSED
,
2669 segT sec ATTRIBUTE_UNUSED
,
2670 fragS
*fragP ATTRIBUTE_UNUSED
)
2672 as_fatal ("md_convert_frag");
2675 /* Should never be called for tic4x. */
2677 md_create_short_jump (char *ptr ATTRIBUTE_UNUSED
,
2678 addressT from_addr ATTRIBUTE_UNUSED
,
2679 addressT to_addr ATTRIBUTE_UNUSED
,
2680 fragS
*frag ATTRIBUTE_UNUSED
,
2681 symbolS
*to_symbol ATTRIBUTE_UNUSED
)
2683 as_fatal ("md_create_short_jmp\n");
2686 /* Should never be called for tic4x. */
2688 md_create_long_jump (char *ptr ATTRIBUTE_UNUSED
,
2689 addressT from_addr ATTRIBUTE_UNUSED
,
2690 addressT to_addr ATTRIBUTE_UNUSED
,
2691 fragS
*frag ATTRIBUTE_UNUSED
,
2692 symbolS
*to_symbol ATTRIBUTE_UNUSED
)
2694 as_fatal ("md_create_long_jump\n");
2697 /* Should never be called for tic4x. */
2699 md_estimate_size_before_relax (fragS
*fragP ATTRIBUTE_UNUSED
,
2700 segT segtype ATTRIBUTE_UNUSED
)
2702 as_fatal ("md_estimate_size_before_relax\n");
2708 md_parse_option (int c
, const char *arg
)
2712 case OPTION_CPU
: /* cpu brand */
2713 if (TOLOWER (*arg
) == 'c')
2715 tic4x_cpu
= atoi (arg
);
2716 if (!IS_CPU_TIC3X (tic4x_cpu
) && !IS_CPU_TIC4X (tic4x_cpu
))
2717 as_warn (_("Unsupported processor generation %d"), tic4x_cpu
);
2720 case OPTION_REV
: /* cpu revision */
2721 tic4x_revision
= atoi (arg
);
2725 as_warn (_("Option -b is depreciated, please use -mbig"));
2726 case OPTION_BIG
: /* big model */
2727 tic4x_big_model
= 1;
2731 as_warn (_("Option -p is depreciated, please use -mmemparm"));
2732 case OPTION_MEMPARM
: /* push args */
2737 as_warn (_("Option -r is depreciated, please use -mregparm"));
2738 case OPTION_REGPARM
: /* register args */
2743 as_warn (_("Option -s is depreciated, please use -msmall"));
2744 case OPTION_SMALL
: /* small model */
2745 tic4x_big_model
= 0;
2752 case OPTION_LOWPOWER
:
2756 case OPTION_ENHANCED
:
2768 md_show_usage (FILE *stream
)
2771 _("\nTIC4X options:\n"
2772 " -mcpu=CPU -mCPU select architecture variant. CPU can be:\n"
2774 " 31 - TMS320C31, TMS320LC31\n"
2776 " 33 - TMS320VC33\n"
2779 " -mrev=REV set cpu hardware revision (integer numbers).\n"
2780 " Combinations of -mcpu and -mrev will enable/disable\n"
2781 " the appropriate options (-midle2, -mlowpower and\n"
2782 " -menhanced) according to the selected type\n"
2783 " -mbig select big memory model\n"
2784 " -msmall select small memory model (default)\n"
2785 " -mregparm select register parameters (default)\n"
2786 " -mmemparm select memory parameters\n"
2787 " -midle2 enable IDLE2 support\n"
2788 " -mlowpower enable LOPOWER and MAXSPEED support\n"
2789 " -menhanced enable enhanced opcode support\n"));
2792 /* This is called when a line is unrecognized. This is used to handle
2793 definitions of TI C3x tools style local labels $n where n is a single
2796 tic4x_unrecognized_line (int c
)
2801 if (c
!= '$' || ! ISDIGIT (input_line_pointer
[0]))
2804 s
= input_line_pointer
;
2806 /* Let's allow multiple digit local labels. */
2808 while (ISDIGIT (*s
))
2810 lab
= lab
* 10 + *s
- '0';
2814 if (dollar_label_defined (lab
))
2816 as_bad (_("Label \"$%d\" redefined"), lab
);
2820 define_dollar_label (lab
);
2821 colon (dollar_label_name (lab
, 0));
2822 input_line_pointer
= s
+ 1;
2827 /* Handle local labels peculiar to us referred to in an expression. */
2829 md_undefined_symbol (char *name
)
2831 /* Look for local labels of the form $n. */
2832 if (name
[0] == '$' && ISDIGIT (name
[1]))
2838 while (ISDIGIT ((unsigned char) *s
))
2840 lab
= lab
* 10 + *s
- '0';
2843 if (dollar_label_defined (lab
))
2845 name
= dollar_label_name (lab
, 0);
2846 symbolP
= symbol_find (name
);
2850 name
= dollar_label_name (lab
, 1);
2851 symbolP
= symbol_find_or_make (name
);
2859 /* Parse an operand that is machine-specific. */
2861 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
2865 /* Round up a section size to the appropriate boundary---do we need this? */
2867 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
2869 return size
; /* Byte (i.e., 32-bit) alignment is fine? */
2873 tic4x_pc_offset (unsigned int op
)
2875 /* Determine the PC offset for a C[34]x instruction.
2876 This could be simplified using some boolean algebra
2877 but at the expense of readability. */
2881 case 0x62: /* call (C4x) */
2882 case 0x64: /* rptb (C4x) */
2884 case 0x61: /* brd */
2885 case 0x63: /* laj */
2886 case 0x65: /* rptbd (C4x) */
2888 case 0x66: /* swi */
2895 switch ((op
& 0xffe00000) >> 20)
2897 case 0x6a0: /* bB */
2898 case 0x720: /* callB */
2899 case 0x740: /* trapB */
2902 case 0x6a2: /* bBd */
2903 case 0x6a6: /* bBat */
2904 case 0x6aa: /* bBaf */
2905 case 0x722: /* lajB */
2906 case 0x748: /* latB */
2907 case 0x798: /* rptbd */
2914 switch ((op
& 0xfe200000) >> 20)
2916 case 0x6e0: /* dbB */
2919 case 0x6e2: /* dbBd */
2929 /* Exactly what point is a PC-relative offset relative TO?
2930 With the C3x we have the following:
2931 DBcond, Bcond disp + PC + 1 => PC
2932 DBcondD, BcondD disp + PC + 3 => PC
2935 md_pcrel_from (fixS
*fixP
)
2940 buf
= (unsigned char *) fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2941 op
= (buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
2943 return ((fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) >> 2) +
2944 tic4x_pc_offset (op
);
2947 /* Fill the alignment area with NOP's on .text, unless fill-data
2950 tic4x_do_align (int alignment
,
2955 /* Because we are talking lwords, not bytes, adjust alignment to do words */
2958 if (alignment
!= 0 && !need_pass_2
)
2962 if (subseg_text_p (now_seg
))
2966 md_number_to_chars (nop
, TIC_NOP_OPCODE
, 4);
2967 frag_align_pattern (alignment
, nop
, sizeof (nop
), max
);
2970 frag_align (alignment
, 0, max
);
2973 frag_align (alignment
, *fill
, max
);
2975 frag_align_pattern (alignment
, fill
, len
, max
);
2978 /* Return 1 to skip the default alignment function */
2982 /* Look for and remove parallel instruction operator ||. */
2984 tic4x_start_line (void)
2986 char *s
= input_line_pointer
;
2990 /* If parallel instruction prefix found at start of line, skip it. */
2991 if (*input_line_pointer
== '|' && input_line_pointer
[1] == '|')
2996 input_line_pointer
++;
2997 *input_line_pointer
= ' ';
2998 /* So line counters get bumped. */
2999 input_line_pointer
[-1] = '\n';
3004 /* Write out the previous insn here */
3007 input_line_pointer
= s
;
3012 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixP
)
3016 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
3018 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
3019 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
3020 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
3021 reloc
->address
/= OCTETS_PER_BYTE
;
3022 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
3023 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
3025 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3026 _("Reloc %d not supported by object file format"),
3027 (int) fixP
->fx_r_type
);
3031 if (fixP
->fx_r_type
== BFD_RELOC_HI16
)
3032 reloc
->addend
= fixP
->fx_offset
;
3034 reloc
->addend
= fixP
->fx_addnumber
;