1 /* tc-tic4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
2 Copyright (C) 1997-2019 Free Software Foundation, Inc.
4 Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to
20 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
21 Boston, MA 02110-1301, USA. */
26 o .align cannot handle fill-data-width larger than 0xFF/8-bits. It
27 should be possible to define a 32-bits pattern.
29 o .align: Implement a 'bu' insn if the number of nop's exceeds 4
30 within the align frag. if(fragsize>4words) insert bu fragend+1
33 o .usect if has symbol on previous line not implemented
35 o .sym, .eos, .stag, .etag, .member not implemented
37 o Evaluation of constant floating point expressions (expr.c needs
40 o Support 'abc' constants (that is 0x616263). */
43 #include "safe-ctype.h"
44 #include "opcode/tic4x.h"
47 /* OK, we accept a syntax similar to the other well known C30
48 assembly tools. With TIC4X_ALT_SYNTAX defined we are more
49 flexible, allowing a more Unix-like syntax: `%' in front of
50 register names, `#' in front of immediate constants, and
51 not requiring `@' in front of direct addresses. */
53 #define TIC4X_ALT_SYNTAX
55 /* Handle of the inst mnemonic hash table. */
56 static struct hash_control
*tic4x_op_hash
= NULL
;
58 /* Handle asg pseudo. */
59 static struct hash_control
*tic4x_asg_hash
= NULL
;
61 static unsigned int tic4x_cpu
= 0; /* Default to TMS320C40. */
62 static unsigned int tic4x_revision
= 0; /* CPU revision */
63 static unsigned int tic4x_idle2
= 0; /* Idle2 support */
64 static unsigned int tic4x_lowpower
= 0; /* Lowpower support */
65 static unsigned int tic4x_enhanced
= 0; /* Enhanced opcode support */
66 static unsigned int tic4x_big_model
= 0; /* Default to small memory model. */
67 static unsigned int tic4x_reg_args
= 0; /* Default to args passed on stack. */
68 static unsigned long tic4x_oplevel
= 0; /* Opcode level */
70 #define OPTION_CPU 'm'
71 #define OPTION_BIG (OPTION_MD_BASE + 1)
72 #define OPTION_SMALL (OPTION_MD_BASE + 2)
73 #define OPTION_MEMPARM (OPTION_MD_BASE + 3)
74 #define OPTION_REGPARM (OPTION_MD_BASE + 4)
75 #define OPTION_IDLE2 (OPTION_MD_BASE + 5)
76 #define OPTION_LOWPOWER (OPTION_MD_BASE + 6)
77 #define OPTION_ENHANCED (OPTION_MD_BASE + 7)
78 #define OPTION_REV (OPTION_MD_BASE + 8)
80 const char *md_shortopts
= "bm:prs";
81 struct option md_longopts
[] =
83 { "mcpu", required_argument
, NULL
, OPTION_CPU
},
84 { "mdsp", required_argument
, NULL
, OPTION_CPU
},
85 { "mbig", no_argument
, NULL
, OPTION_BIG
},
86 { "msmall", no_argument
, NULL
, OPTION_SMALL
},
87 { "mmemparm", no_argument
, NULL
, OPTION_MEMPARM
},
88 { "mregparm", no_argument
, NULL
, OPTION_REGPARM
},
89 { "midle2", no_argument
, NULL
, OPTION_IDLE2
},
90 { "mlowpower", no_argument
, NULL
, OPTION_LOWPOWER
},
91 { "menhanced", no_argument
, NULL
, OPTION_ENHANCED
},
92 { "mrev", required_argument
, NULL
, OPTION_REV
},
93 { NULL
, no_argument
, NULL
, 0 }
96 size_t md_longopts_size
= sizeof (md_longopts
);
101 M_UNKNOWN
, M_IMMED
, M_DIRECT
, M_REGISTER
, M_INDIRECT
,
102 M_IMMED_F
, M_PARALLEL
, M_HI
106 typedef struct tic4x_operand
108 tic4x_addr_mode_t mode
; /* Addressing mode. */
109 expressionS expr
; /* Expression. */
110 int disp
; /* Displacement for indirect addressing. */
111 int aregno
; /* Aux. register number. */
112 LITTLENUM_TYPE fwords
[MAX_LITTLENUMS
]; /* Float immed. number. */
116 typedef struct tic4x_insn
118 char name
[TIC4X_NAME_MAX
]; /* Mnemonic of instruction. */
119 unsigned int in_use
; /* True if in_use. */
120 unsigned int parallel
; /* True if parallel instruction. */
121 unsigned int nchars
; /* This is always 4 for the C30. */
122 unsigned long opcode
; /* Opcode number. */
123 expressionS exp
; /* Expression required for relocation. */
124 /* Relocation type required. */
125 bfd_reloc_code_real_type reloc
;
126 int pcrel
; /* True if relocation PC relative. */
127 char *pname
; /* Name of instruction in parallel. */
128 unsigned int num_operands
; /* Number of operands in total. */
129 tic4x_inst_t
*inst
; /* Pointer to first template. */
130 tic4x_operand_t operands
[TIC4X_OPERANDS_MAX
];
134 static tic4x_insn_t the_insn
; /* Info about our instruction. */
135 static tic4x_insn_t
*insn
= &the_insn
;
137 static void tic4x_asg (int);
138 static void tic4x_bss (int);
139 static void tic4x_globl (int);
140 static void tic4x_cons (int);
141 static void tic4x_stringer (int);
142 static void tic4x_eval (int);
143 static void tic4x_newblock (int);
144 static void tic4x_sect (int);
145 static void tic4x_set (int);
146 static void tic4x_usect (int);
147 static void tic4x_version (int);
153 {"align", s_align_bytes
, 32},
154 {"ascii", tic4x_stringer
, 1},
155 {"asciz", tic4x_stringer
, 0},
156 {"asg", tic4x_asg
, 0},
157 {"block", s_space
, 4},
158 {"byte", tic4x_cons
, 1},
159 {"bss", tic4x_bss
, 0},
160 {"copy", s_include
, 0},
161 {"def", tic4x_globl
, 0},
162 {"equ", tic4x_set
, 0},
163 {"eval", tic4x_eval
, 0},
164 {"global", tic4x_globl
, 0},
165 {"globl", tic4x_globl
, 0},
166 {"hword", tic4x_cons
, 2},
167 {"ieee", float_cons
, 'i'},
168 {"int", tic4x_cons
, 4}, /* .int allocates 4 bytes. */
169 {"ldouble", float_cons
, 'e'},
170 {"newblock", tic4x_newblock
, 0},
171 {"ref", s_ignore
, 0}, /* All undefined treated as external. */
172 {"set", tic4x_set
, 0},
173 {"sect", tic4x_sect
, 1}, /* Define named section. */
174 {"space", s_space
, 4},
175 {"string", tic4x_stringer
, 0},
176 {"usect", tic4x_usect
, 0}, /* Reserve space in uninit. named sect. */
177 {"version", tic4x_version
, 0},
178 {"word", tic4x_cons
, 4}, /* .word allocates 4 bytes. */
179 {"xdef", tic4x_globl
, 0},
183 int md_short_jump_size
= 4;
184 int md_long_jump_size
= 4;
186 /* This array holds the chars that always start a comment. If the
187 pre-processor is disabled, these aren't very useful. */
188 #ifdef TIC4X_ALT_SYNTAX
189 const char comment_chars
[] = ";!";
191 const char comment_chars
[] = ";";
194 /* This array holds the chars that only start a comment at the beginning of
195 a line. If the line seems to have the form '# 123 filename'
196 .line and .file directives will appear in the pre-processed output.
197 Note that input_file.c hand checks for '#' at the beginning of the
198 first line of the input file. This is because the compiler outputs
199 #NO_APP at the beginning of its output.
200 Also note that comments like this one will always work. */
201 const char line_comment_chars
[] = "#*";
203 /* We needed an unused char for line separation to work around the
204 lack of macros, using sed and such. */
205 const char line_separator_chars
[] = "&";
207 /* Chars that can be used to separate mant from exp in floating point nums. */
208 const char EXP_CHARS
[] = "eE";
210 /* Chars that mean this number is a floating point constant. */
213 const char FLT_CHARS
[] = "fFilsS";
215 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
216 changed in read.c. Ideally it shouldn't have to know about it at
217 all, but nothing is ideal around here. */
219 /* Flonums returned here. */
220 extern FLONUM_TYPE generic_floating_point_number
;
222 /* Precision in LittleNums. */
223 #define MAX_PRECISION (4) /* It's a bit overkill for us, but the code
225 #define S_PRECISION (1) /* Short float constants 16-bit. */
226 #define F_PRECISION (2) /* Float and double types 32-bit. */
227 #define E_PRECISION (4) /* Extended precision, 64-bit (real 40-bit). */
230 /* Turn generic_floating_point_number into a real short/float/double. */
232 tic4x_gen_to_words (FLONUM_TYPE flonum
, LITTLENUM_TYPE
*words
, int precision
)
234 int return_value
= 0;
235 LITTLENUM_TYPE
*p
; /* Littlenum pointer. */
236 int mantissa_bits
; /* Bits in mantissa field. */
237 int exponent_bits
; /* Bits in exponent field. */
239 unsigned int sone
; /* Scaled one. */
240 unsigned int sfract
; /* Scaled fraction. */
241 unsigned int smant
; /* Scaled mantissa. */
243 unsigned int mover
; /* Mantissa overflow bits */
244 unsigned int rbit
; /* Round bit. */
245 int shift
; /* Shift count. */
247 /* NOTE: Svein Seldal <Svein@dev.seldal.com>
248 The code in this function is altered slightly to support floats
249 with 31-bits mantissas, thus the documentation below may be a
250 little bit inaccurate.
252 By Michael P. Hayes <m.hayes@elec.canterbury.ac.nz>
253 Here is how a generic floating point number is stored using
254 flonums (an extension of bignums) where p is a pointer to an
257 For example 2e-3 is stored with exp = -4 and
264 with low = &bits[2], high = &bits[5], and leader = &bits[5].
266 This number can be written as
267 0x0083126e978d4fde.00000000 * 65536**-4 or
268 0x0.0083126e978d4fde * 65536**0 or
269 0x0.83126e978d4fde * 2**-8 = 2e-3
271 Note that low points to the 65536**0 littlenum (bits[2]) and
272 leader points to the most significant non-zero littlenum
275 TMS320C3X floating point numbers are a bit of a strange beast.
276 The 32-bit flavour has the 8 MSBs representing the exponent in
277 twos complement format (-128 to +127). There is then a sign bit
278 followed by 23 bits of mantissa. The mantissa is expressed in
279 twos complement format with the binary point after the most
280 significant non sign bit. The bit after the binary point is
281 suppressed since it is the complement of the sign bit. The
282 effective mantissa is thus 24 bits. Zero is represented by an
285 The 16-bit flavour has the 4 MSBs representing the exponent in
286 twos complement format (-8 to +7). There is then a sign bit
287 followed by 11 bits of mantissa. The mantissa is expressed in
288 twos complement format with the binary point after the most
289 significant non sign bit. The bit after the binary point is
290 suppressed since it is the complement of the sign bit. The
291 effective mantissa is thus 12 bits. Zero is represented by an
292 exponent of -8. For example,
294 number norm mant m x e s i fraction f
295 +0.500 => 1.00000000000 -1 -1 0 1 .00000000000 (1 + 0) * 2^(-1)
296 +0.999 => 1.11111111111 -1 -1 0 1 .11111111111 (1 + 0.99) * 2^(-1)
297 +1.000 => 1.00000000000 0 0 0 1 .00000000000 (1 + 0) * 2^(0)
298 +1.500 => 1.10000000000 0 0 0 1 .10000000000 (1 + 0.5) * 2^(0)
299 +1.999 => 1.11111111111 0 0 0 1 .11111111111 (1 + 0.9) * 2^(0)
300 +2.000 => 1.00000000000 1 1 0 1 .00000000000 (1 + 0) * 2^(1)
301 +4.000 => 1.00000000000 2 2 0 1 .00000000000 (1 + 0) * 2^(2)
302 -0.500 => 1.00000000000 -1 -1 1 0 .10000000000 (-2 + 0) * 2^(-2)
303 -1.000 => 1.00000000000 0 -1 1 0 .00000000000 (-2 + 0) * 2^(-1)
304 -1.500 => 1.10000000000 0 0 1 0 .10000000000 (-2 + 0.5) * 2^(0)
305 -1.999 => 1.11111111111 0 0 1 0 .00000000001 (-2 + 0.11) * 2^(0)
306 -2.000 => 1.00000000000 1 1 1 0 .00000000000 (-2 + 0) * 2^(0)
307 -4.000 => 1.00000000000 2 1 1 0 .00000000000 (-2 + 0) * 2^(1)
309 where e is the exponent, s is the sign bit, i is the implied bit,
310 and f is the fraction stored in the mantissa field.
312 num = (1 + f) * 2^x = m * 2^e if s = 0
313 num = (-2 + f) * 2^x = -m * 2^e if s = 1
314 where 0 <= f < 1.0 and 1.0 <= m < 2.0
316 The fraction (f) and exponent (e) fields for the TMS320C3X format
317 can be derived from the normalised mantissa (m) and exponent (x) using:
319 f = m - 1, e = x if s = 0
320 f = 2 - m, e = x if s = 1 and m != 1.0
321 f = 0, e = x - 1 if s = 1 and m = 1.0
322 f = 0, e = -8 if m = 0
325 OK, the other issue we have to consider is rounding since the
326 mantissa has a much higher potential precision than what we can
327 represent. To do this we add half the smallest storable fraction.
328 We then have to renormalise the number to allow for overflow.
330 To convert a generic flonum into a TMS320C3X floating point
331 number, here's what we try to do....
333 The first thing is to generate a normalised mantissa (m) where
334 1.0 <= m < 2 and to convert the exponent from base 16 to base 2.
335 We desire the binary point to be placed after the most significant
336 non zero bit. This process is done in two steps: firstly, the
337 littlenum with the most significant non zero bit is located (this
338 is done for us since leader points to this littlenum) and the
339 binary point (which is currently after the LSB of the littlenum
340 pointed to by low) is moved to before the MSB of the littlenum
341 pointed to by leader. This requires the exponent to be adjusted
342 by leader - low + 1. In the earlier example, the new exponent is
343 thus -4 + (5 - 2 + 1) = 0 (base 65536). We now need to convert
344 the exponent to base 2 by multiplying the exponent by 16 (log2
345 65536). The exponent base 2 is thus also zero.
347 The second step is to hunt for the most significant non zero bit
348 in the leader littlenum. We do this by left shifting a copy of
349 the leader littlenum until bit 16 is set (0x10000) and counting
350 the number of shifts, S, required. The number of shifts then has to
351 be added to correct the exponent (base 2). For our example, this
352 will require 9 shifts and thus our normalised exponent (base 2) is
353 0 + 9 = 9. Note that the worst case scenario is when the leader
354 littlenum is 1, thus requiring 16 shifts.
356 We now have to left shift the other littlenums by the same amount,
357 propagating the shifted bits into the more significant littlenums.
358 To save a lot of unnecessary shifting we only have to consider
359 two or three littlenums, since the greatest number of mantissa
360 bits required is 24 + 1 rounding bit. While two littlenums
361 provide 32 bits of precision, the most significant littlenum
362 may only contain a single significant bit and thus an extra
363 littlenum is required.
365 Denoting the number of bits in the fraction field as F, we require
366 G = F + 2 bits (one extra bit is for rounding, the other gets
367 suppressed). Say we required S shifts to find the most
368 significant bit in the leader littlenum, the number of left shifts
369 required to move this bit into bit position G - 1 is L = G + S - 17.
370 Note that this shift count may be negative for the short floating
371 point flavour (where F = 11 and thus G = 13 and potentially S < 3).
372 If L > 0 we have to shunt the next littlenum into position. Bit
373 15 (the MSB) of the next littlenum needs to get moved into position
374 L - 1 (If L > 15 we need all the bits of this littlenum and
375 some more from the next one.). We subtract 16 from L and use this
376 as the left shift count; the resultant value we or with the
377 previous result. If L > 0, we repeat this operation. */
379 if (precision
!= S_PRECISION
)
381 if (precision
== E_PRECISION
)
382 words
[2] = words
[3] = 0x0000;
384 /* 0.0e0 or NaN seen. */
385 if (flonum
.low
> flonum
.leader
/* = 0.0e0 */
386 || flonum
.sign
== 0) /* = NaN */
389 as_bad (_("Nan, using zero."));
394 if (flonum
.sign
== 'P')
396 /* +INF: Replace with maximum float. */
397 if (precision
== S_PRECISION
)
404 if (precision
== E_PRECISION
)
411 else if (flonum
.sign
== 'N')
413 /* -INF: Replace with maximum float. */
414 if (precision
== S_PRECISION
)
418 if (precision
== E_PRECISION
)
423 exponent
= (flonum
.exponent
+ flonum
.leader
- flonum
.low
+ 1) * 16;
425 if (!(tmp
= *flonum
.leader
))
426 abort (); /* Hmmm. */
427 shift
= 0; /* Find position of first sig. bit. */
430 exponent
-= (16 - shift
); /* Adjust exponent. */
432 if (precision
== S_PRECISION
) /* Allow 1 rounding bit. */
437 else if(precision
== F_PRECISION
)
442 else /* E_PRECISION */
448 shift
= mantissa_bits
- shift
;
453 /* Store the mantissa data into smant and the roundbit into rbit */
454 for (p
= flonum
.leader
; p
>= flonum
.low
&& shift
> -16; p
--)
456 tmp
= shift
>= 0 ? *p
<< shift
: *p
>> -shift
;
457 rbit
= shift
< 0 ? ((*p
>> (-shift
-1)) & 0x1) : 0;
462 /* OK, we've got our scaled mantissa so let's round it up */
465 /* If the mantissa is going to overflow when added, lets store
466 the extra bit in mover. -- A special case exists when
467 mantissa_bits is 31 (E_PRECISION). Then the first test cannot
468 be trusted, as result is host-dependent, thus the second
470 if( smant
== ((unsigned)(1<<(mantissa_bits
+1))-1)
471 || smant
== (unsigned)-1 ) /* This is to catch E_PRECISION cases */
476 /* Get the scaled one value */
477 sone
= (1 << (mantissa_bits
));
479 /* The number may be unnormalised so renormalise it... */
483 smant
|= sone
; /* Insert the bit from mover into smant */
487 /* The binary point is now between bit positions 11 and 10 or 23 and 22,
488 i.e., between mantissa_bits - 1 and mantissa_bits - 2 and the
489 bit at mantissa_bits - 1 should be set. */
491 abort (); /* Ooops. */
493 if (flonum
.sign
== '+')
494 sfract
= smant
- sone
; /* smant - 1.0. */
497 /* This seems to work. */
505 sfract
= -smant
& (sone
-1); /* 2.0 - smant. */
507 sfract
|= sone
; /* Insert sign bit. */
510 if (abs (exponent
) >= (1 << (exponent_bits
- 1)))
511 as_bad (_("Cannot represent exponent in %d bits"), exponent_bits
);
513 /* Force exponent to fit in desired field width. */
514 exponent
&= (1 << (exponent_bits
)) - 1;
516 if (precision
== E_PRECISION
)
518 /* Map the float part first (100% equal format as F_PRECISION) */
519 words
[0] = exponent
<< (mantissa_bits
+1-24);
520 words
[0] |= sfract
>> 24;
521 words
[1] = sfract
>> 8;
523 /* Map the mantissa in the next */
524 words
[2] = sfract
>> 16;
525 words
[3] = sfract
& 0xffff;
529 /* Insert the exponent data into the word */
530 sfract
|= exponent
<< (mantissa_bits
+1);
532 if (precision
== S_PRECISION
)
536 words
[0] = sfract
>> 16;
537 words
[1] = sfract
& 0xffff;
544 /* Returns pointer past text consumed. */
546 tic4x_atof (char *str
, char what_kind
, LITTLENUM_TYPE
*words
)
548 /* Extra bits for zeroed low-order bits. The 1st MAX_PRECISION are
549 zeroed, the last contain flonum bits. */
550 static LITTLENUM_TYPE bits
[MAX_PRECISION
+ MAX_PRECISION
+ GUARD
];
552 /* Number of 16-bit words in the format. */
554 FLONUM_TYPE save_gen_flonum
;
556 /* We have to save the generic_floating_point_number because it
557 contains storage allocation about the array of LITTLENUMs where
558 the value is actually stored. We will allocate our own array of
559 littlenums below, but have to restore the global one on exit. */
560 save_gen_flonum
= generic_floating_point_number
;
563 generic_floating_point_number
.low
= bits
+ MAX_PRECISION
;
564 generic_floating_point_number
.high
= NULL
;
565 generic_floating_point_number
.leader
= NULL
;
566 generic_floating_point_number
.exponent
= 0;
567 generic_floating_point_number
.sign
= '\0';
569 /* Use more LittleNums than seems necessary: the highest flonum may
570 have 15 leading 0 bits, so could be useless. */
572 memset (bits
, '\0', sizeof (LITTLENUM_TYPE
) * MAX_PRECISION
);
578 precision
= S_PRECISION
;
585 precision
= F_PRECISION
;
590 precision
= E_PRECISION
;
594 as_bad (_("Invalid floating point number"));
598 generic_floating_point_number
.high
599 = generic_floating_point_number
.low
+ precision
- 1 + GUARD
;
601 if (atof_generic (&return_value
, ".", EXP_CHARS
,
602 &generic_floating_point_number
))
604 as_bad (_("Invalid floating point number"));
608 tic4x_gen_to_words (generic_floating_point_number
,
611 /* Restore the generic_floating_point_number's storage alloc (and
613 generic_floating_point_number
= save_gen_flonum
;
619 tic4x_insert_reg (const char *regname
, int regnum
)
624 symbol_table_insert (symbol_new (regname
, reg_section
, (valueT
) regnum
,
625 &zero_address_frag
));
626 for (i
= 0; regname
[i
]; i
++)
627 buf
[i
] = ISLOWER (regname
[i
]) ? TOUPPER (regname
[i
]) : regname
[i
];
630 symbol_table_insert (symbol_new (buf
, reg_section
, (valueT
) regnum
,
631 &zero_address_frag
));
635 tic4x_insert_sym (const char *symname
, int value
)
639 symbolP
= symbol_new (symname
, absolute_section
,
640 (valueT
) value
, &zero_address_frag
);
641 SF_SET_LOCAL (symbolP
);
642 symbol_table_insert (symbolP
);
646 tic4x_expression (char *str
, expressionS
*exp
)
651 t
= input_line_pointer
; /* Save line pointer. */
652 input_line_pointer
= str
;
654 s
= input_line_pointer
;
655 input_line_pointer
= t
; /* Restore line pointer. */
656 return s
; /* Return pointer to where parsing stopped. */
660 tic4x_expression_abs (char *str
, offsetT
*value
)
665 t
= input_line_pointer
; /* Save line pointer. */
666 input_line_pointer
= str
;
667 *value
= get_absolute_expression ();
668 s
= input_line_pointer
;
669 input_line_pointer
= t
; /* Restore line pointer. */
674 tic4x_emit_char (char c
, int b
)
678 exp
.X_op
= O_constant
;
679 exp
.X_add_number
= c
;
684 tic4x_seg_alloc (char *name ATTRIBUTE_UNUSED
,
685 segT seg ATTRIBUTE_UNUSED
,
689 /* Note that the size is in words
690 so we multiply it by 4 to get the number of bytes to allocate. */
692 /* If we have symbol: .usect ".fred", size etc.,
693 the symbol needs to point to the first location reserved
700 p
= frag_var (rs_fill
, 1, 1, (relax_substateT
) 0,
702 size
* OCTETS_PER_BYTE
, (char *) 0);
707 /* .asg ["]character-string["], symbol */
709 tic4x_asg (int x ATTRIBUTE_UNUSED
)
716 str
= input_line_pointer
;
718 /* Skip string expression. */
719 while (*input_line_pointer
!= ',' && *input_line_pointer
)
720 input_line_pointer
++;
721 if (*input_line_pointer
!= ',')
723 as_bad (_("Comma expected\n"));
726 *input_line_pointer
++ = '\0';
727 c
= get_symbol_name (&name
); /* Get terminator. */
729 name
= xstrdup (name
);
730 if (hash_find (tic4x_asg_hash
, name
))
731 hash_replace (tic4x_asg_hash
, name
, (void *) str
);
733 hash_insert (tic4x_asg_hash
, name
, (void *) str
);
734 (void) restore_line_pointer (c
);
735 demand_empty_rest_of_line ();
738 /* .bss symbol, size */
740 tic4x_bss (int x ATTRIBUTE_UNUSED
)
747 subsegT current_subseg
;
750 current_seg
= now_seg
; /* Save current seg. */
751 current_subseg
= now_subseg
; /* Save current subseg. */
754 c
= get_symbol_name (&name
); /* Get terminator. */
756 c
= * ++ input_line_pointer
;
759 as_bad (_(".bss size argument missing\n"));
764 tic4x_expression_abs (++input_line_pointer
, &size
);
767 as_bad (_(".bss size %ld < 0!"), (long) size
);
770 subseg_set (bss_section
, 0);
771 symbolP
= symbol_find_or_make (name
);
773 if (S_GET_SEGMENT (symbolP
) == bss_section
)
774 symbol_get_frag (symbolP
)->fr_symbol
= 0;
776 symbol_set_frag (symbolP
, frag_now
);
778 p
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
,
779 size
* OCTETS_PER_BYTE
, (char *) 0);
780 *p
= 0; /* Fill char. */
782 S_SET_SEGMENT (symbolP
, bss_section
);
784 /* The symbol may already have been created with a preceding
785 ".globl" directive -- be careful not to step on storage class
786 in that case. Otherwise, set it to static. */
787 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
788 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
790 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
791 demand_empty_rest_of_line ();
795 tic4x_globl (int ignore ATTRIBUTE_UNUSED
)
803 c
= get_symbol_name (&name
);
804 symbolP
= symbol_find_or_make (name
);
805 *input_line_pointer
= c
;
806 SKIP_WHITESPACE_AFTER_NAME ();
807 S_SET_STORAGE_CLASS (symbolP
, C_EXT
);
808 S_SET_EXTERNAL (symbolP
);
811 input_line_pointer
++;
813 if (*input_line_pointer
== '\n')
819 demand_empty_rest_of_line ();
822 /* Handle .byte, .word. .int, .long */
824 tic4x_cons (int bytes
)
830 if (*input_line_pointer
== '"')
832 input_line_pointer
++;
833 while (is_a_char (c
= next_char_of_string ()))
834 tic4x_emit_char (c
, 4);
835 know (input_line_pointer
[-1] == '\"');
841 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
842 if (exp
.X_op
== O_constant
)
847 exp
.X_add_number
&= 255;
850 exp
.X_add_number
&= 65535;
854 /* Perhaps we should disallow .byte and .hword with
855 a non constant expression that will require relocation. */
859 while (*input_line_pointer
++ == ',');
861 input_line_pointer
--; /* Put terminator back into stream. */
862 demand_empty_rest_of_line ();
865 /* Handle .ascii, .asciz, .string */
867 tic4x_stringer (int append_zero
)
876 if (*input_line_pointer
== '"')
878 input_line_pointer
++;
879 while (is_a_char (c
= next_char_of_string ()))
881 tic4x_emit_char (c
, 1);
887 tic4x_emit_char (c
, 1);
891 know (input_line_pointer
[-1] == '\"');
897 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
898 if (exp
.X_op
!= O_constant
)
900 as_bad (_("Non-constant symbols not allowed\n"));
903 exp
.X_add_number
&= 255; /* Limit number to 8-bit */
908 while (*input_line_pointer
++ == ',');
910 /* Fill out the rest of the expression with 0's to fill up a full word */
912 tic4x_emit_char (0, 4-(bytes
&0x3));
914 input_line_pointer
--; /* Put terminator back into stream. */
915 demand_empty_rest_of_line ();
918 /* .eval expression, symbol */
920 tic4x_eval (int x ATTRIBUTE_UNUSED
)
928 tic4x_expression_abs (input_line_pointer
, &value
);
929 if (*input_line_pointer
++ != ',')
931 as_bad (_("Symbol missing\n"));
934 c
= get_symbol_name (&name
); /* Get terminator. */
935 tic4x_insert_sym (name
, value
);
936 (void) restore_line_pointer (c
);
937 demand_empty_rest_of_line ();
940 /* Reset local labels. */
942 tic4x_newblock (int x ATTRIBUTE_UNUSED
)
944 dollar_label_clear ();
947 /* .sect "section-name" [, value] */
948 /* .sect ["]section-name[:subsection-name]["] [, value] */
950 tic4x_sect (int x ATTRIBUTE_UNUSED
)
959 if (*input_line_pointer
== '"')
960 input_line_pointer
++;
961 c
= get_symbol_name (§ion_name
); /* Get terminator. */
963 c
= * ++ input_line_pointer
;
964 input_line_pointer
++; /* Skip null symbol terminator. */
965 name
= xstrdup (section_name
);
967 /* TI C from version 5.0 allows a section name to contain a
968 subsection name as well. The subsection name is separated by a
969 ':' from the section name. Currently we scan the subsection
971 Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>. */
975 c
= get_symbol_name (&subname
); /* Get terminator. */
977 c
= * ++ input_line_pointer
;
978 input_line_pointer
++; /* Skip null symbol terminator. */
979 as_warn (_(".sect: subsection name ignored"));
982 /* We might still have a '"' to discard, but the character after a
983 symbol name will be overwritten with a \0 by get_symbol_name()
988 tic4x_expression_abs (input_line_pointer
, &num
);
989 else if (*input_line_pointer
== ',')
992 tic4x_expression_abs (++input_line_pointer
, &num
);
997 seg
= subseg_new (name
, num
);
998 if (line_label
!= NULL
)
1000 S_SET_SEGMENT (line_label
, seg
);
1001 symbol_set_frag (line_label
, frag_now
);
1004 if (bfd_section_flags (seg
) == SEC_NO_FLAGS
)
1006 if (!bfd_set_section_flags (seg
, SEC_DATA
))
1007 as_warn (_("Error setting flags for \"%s\": %s"), name
,
1008 bfd_errmsg (bfd_get_error ()));
1011 /* If the last character overwritten by get_symbol_name() was an
1012 end-of-line, we must restore it or the end of the line will not be
1013 recognised and scanning extends into the next line, stopping with
1014 an error (blame Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>
1015 if this is not true). */
1016 if (is_end_of_line
[(unsigned char) c
])
1017 *(--input_line_pointer
) = c
;
1019 demand_empty_rest_of_line ();
1022 /* symbol[:] .set value or .set symbol, value */
1024 tic4x_set (int x ATTRIBUTE_UNUSED
)
1029 if ((symbolP
= line_label
) == NULL
)
1034 c
= get_symbol_name (&name
); /* Get terminator. */
1036 c
= * ++ input_line_pointer
;
1039 as_bad (_(".set syntax invalid\n"));
1040 ignore_rest_of_line ();
1043 ++input_line_pointer
;
1044 symbolP
= symbol_find_or_make (name
);
1047 symbol_table_insert (symbolP
);
1049 pseudo_set (symbolP
);
1050 demand_empty_rest_of_line ();
1053 /* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
1055 tic4x_usect (int x ATTRIBUTE_UNUSED
)
1061 offsetT size
, alignment_flag
;
1063 subsegT current_subseg
;
1065 current_seg
= now_seg
; /* save current seg. */
1066 current_subseg
= now_subseg
; /* save current subseg. */
1069 if (*input_line_pointer
== '"')
1070 input_line_pointer
++;
1071 c
= get_symbol_name (§ion_name
); /* Get terminator. */
1073 c
= * ++ input_line_pointer
;
1074 input_line_pointer
++; /* Skip null symbol terminator. */
1075 name
= xstrdup (section_name
);
1078 input_line_pointer
=
1079 tic4x_expression_abs (input_line_pointer
, &size
);
1080 else if (*input_line_pointer
== ',')
1082 input_line_pointer
=
1083 tic4x_expression_abs (++input_line_pointer
, &size
);
1088 /* Read a possibly present third argument (alignment flag) [VK]. */
1089 if (*input_line_pointer
== ',')
1091 input_line_pointer
=
1092 tic4x_expression_abs (++input_line_pointer
, &alignment_flag
);
1097 as_warn (_(".usect: non-zero alignment flag ignored"));
1099 seg
= subseg_new (name
, 0);
1100 if (line_label
!= NULL
)
1102 S_SET_SEGMENT (line_label
, seg
);
1103 symbol_set_frag (line_label
, frag_now
);
1104 S_SET_VALUE (line_label
, frag_now_fix ());
1106 seg_info (seg
)->bss
= 1; /* Uninitialised data. */
1107 if (!bfd_set_section_flags (seg
, SEC_ALLOC
))
1108 as_warn (_("Error setting flags for \"%s\": %s"), name
,
1109 bfd_errmsg (bfd_get_error ()));
1110 tic4x_seg_alloc (name
, seg
, size
, line_label
);
1112 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1113 S_SET_STORAGE_CLASS (line_label
, C_STAT
);
1115 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
1116 demand_empty_rest_of_line ();
1119 /* .version cpu-version. */
1121 tic4x_version (int x ATTRIBUTE_UNUSED
)
1125 input_line_pointer
=
1126 tic4x_expression_abs (input_line_pointer
, &temp
);
1127 if (!IS_CPU_TIC3X (temp
) && !IS_CPU_TIC4X (temp
))
1128 as_bad (_("This assembler does not support processor generation %ld"),
1131 if (tic4x_cpu
&& temp
!= (offsetT
) tic4x_cpu
)
1132 as_warn (_("Changing processor generation on fly not supported..."));
1134 demand_empty_rest_of_line ();
1138 tic4x_init_regtable (void)
1142 for (i
= 0; i
< tic3x_num_registers
; i
++)
1143 tic4x_insert_reg (tic3x_registers
[i
].name
,
1144 tic3x_registers
[i
].regno
);
1146 if (IS_CPU_TIC4X (tic4x_cpu
))
1148 /* Add additional Tic4x registers, overriding some C3x ones. */
1149 for (i
= 0; i
< tic4x_num_registers
; i
++)
1150 tic4x_insert_reg (tic4x_registers
[i
].name
,
1151 tic4x_registers
[i
].regno
);
1156 tic4x_init_symbols (void)
1158 /* The TI tools accept case insensitive versions of these symbols,
1163 .TMS320xx 30,31,32,40,or 44 set according to -v flag
1164 .C3X or .C3x 1 or 0 1 if -v30,-v31,or -v32
1165 .C30 1 or 0 1 if -v30
1166 .C31 1 or 0 1 if -v31
1167 .C32 1 or 0 1 if -v32
1168 .C4X or .C4x 1 or 0 1 if -v40, or -v44
1169 .C40 1 or 0 1 if -v40
1170 .C44 1 or 0 1 if -v44
1172 .REGPARM 1 or 0 1 if -mr option used
1173 .BIGMODEL 1 or 0 1 if -mb option used
1175 These symbols are currently supported but will be removed in a
1177 .TMS320C30 1 or 0 1 if -v30,-v31,or -v32
1178 .TMS320C31 1 or 0 1 if -v31
1179 .TMS320C32 1 or 0 1 if -v32
1180 .TMS320C40 1 or 0 1 if -v40, or -v44
1181 .TMS320C44 1 or 0 1 if -v44
1183 Source: TI: TMS320C3x/C4x Assembly Language Tools User's Guide,
1184 1997, SPRU035C, p. 3-17/3-18. */
1185 tic4x_insert_sym (".REGPARM", tic4x_reg_args
);
1186 tic4x_insert_sym (".MEMPARM", !tic4x_reg_args
);
1187 tic4x_insert_sym (".BIGMODEL", tic4x_big_model
);
1188 tic4x_insert_sym (".C30INTERRUPT", 0);
1189 tic4x_insert_sym (".TMS320xx", tic4x_cpu
== 0 ? 40 : tic4x_cpu
);
1190 tic4x_insert_sym (".C3X", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1191 tic4x_insert_sym (".C3x", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1192 tic4x_insert_sym (".C4X", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1193 tic4x_insert_sym (".C4x", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1194 /* Do we need to have the following symbols also in lower case? */
1195 tic4x_insert_sym (".TMS320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1196 tic4x_insert_sym (".tms320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1197 tic4x_insert_sym (".TMS320C31", tic4x_cpu
== 31);
1198 tic4x_insert_sym (".tms320C31", tic4x_cpu
== 31);
1199 tic4x_insert_sym (".TMS320C32", tic4x_cpu
== 32);
1200 tic4x_insert_sym (".tms320C32", tic4x_cpu
== 32);
1201 tic4x_insert_sym (".TMS320C33", tic4x_cpu
== 33);
1202 tic4x_insert_sym (".tms320C33", tic4x_cpu
== 33);
1203 tic4x_insert_sym (".TMS320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1204 tic4x_insert_sym (".tms320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1205 tic4x_insert_sym (".TMS320C44", tic4x_cpu
== 44);
1206 tic4x_insert_sym (".tms320C44", tic4x_cpu
== 44);
1207 tic4x_insert_sym (".TMX320C40", 0); /* C40 first pass silicon ? */
1208 tic4x_insert_sym (".tmx320C40", 0);
1211 /* Insert a new instruction template into hash table. */
1213 tic4x_inst_insert (const tic4x_inst_t
*inst
)
1215 static char prev_name
[16];
1216 const char *retval
= NULL
;
1218 /* Only insert the first name if have several similar entries. */
1219 if (!strcmp (inst
->name
, prev_name
) || inst
->name
[0] == '\0')
1222 retval
= hash_insert (tic4x_op_hash
, inst
->name
, (void *) inst
);
1224 fprintf (stderr
, "internal error: can't hash `%s': %s\n",
1225 inst
->name
, retval
);
1227 strcpy (prev_name
, inst
->name
);
1228 return retval
== NULL
;
1231 /* Make a new instruction template. */
1232 static tic4x_inst_t
*
1233 tic4x_inst_make (const char *name
, unsigned long opcode
, const char *args
)
1235 static tic4x_inst_t
*insts
= NULL
;
1236 static char *names
= NULL
;
1237 static int iindex
= 0;
1241 /* Allocate memory to store name strings. */
1242 names
= XNEWVEC (char, 8192);
1243 /* Allocate memory for additional insts. */
1244 insts
= XNEWVEC (tic4x_inst_t
, 1024);
1246 insts
[iindex
].name
= names
;
1247 insts
[iindex
].opcode
= opcode
;
1248 insts
[iindex
].opmask
= 0xffffffff;
1249 insts
[iindex
].args
= args
;
1257 return &insts
[iindex
- 1];
1260 /* Add instruction template, creating dynamic templates as required. */
1262 tic4x_inst_add (const tic4x_inst_t
*insts
)
1264 const char *s
= insts
->name
;
1272 /* We do not care about INSNs that is not a part of our
1274 if ((insts
->oplevel
& tic4x_oplevel
) == 0)
1283 /* Dynamically create all the conditional insts. */
1284 for (i
= 0; i
< tic4x_num_conds
; i
++)
1288 const char *c
= tic4x_conds
[i
].name
;
1298 /* If instruction found then have already processed it. */
1299 if (hash_find (tic4x_op_hash
, name
))
1304 inst
= tic4x_inst_make (name
, insts
[k
].opcode
+
1305 (tic4x_conds
[i
].cond
<<
1306 (*s
== 'B' ? 16 : 23)),
1308 if (k
== 0) /* Save strcmp() with following func. */
1309 ok
&= tic4x_inst_insert (inst
);
1312 while (!strcmp (insts
->name
,
1319 return tic4x_inst_insert (insts
);
1329 /* This function is called once, at assembler startup time. It should
1330 set up all the tables, etc., that the MD part of the assembler will
1338 /* Setup the proper opcode level according to the
1339 commandline parameters */
1340 tic4x_oplevel
= OP_C3X
;
1342 if ( IS_CPU_TIC4X(tic4x_cpu
) )
1343 tic4x_oplevel
|= OP_C4X
;
1345 if ( ( tic4x_cpu
== 31 && tic4x_revision
>= 6)
1346 || (tic4x_cpu
== 32 && tic4x_revision
>= 2)
1347 || (tic4x_cpu
== 33)
1349 tic4x_oplevel
|= OP_ENH
;
1351 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1352 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1353 || (tic4x_cpu
== 32)
1355 tic4x_oplevel
|= OP_LPWR
;
1357 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1358 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1359 || (tic4x_cpu
== 32)
1360 || (tic4x_cpu
== 33)
1361 || (tic4x_cpu
== 40 && tic4x_revision
>= 5)
1362 || (tic4x_cpu
== 44)
1364 tic4x_oplevel
|= OP_IDLE2
;
1366 /* Create hash table for mnemonics. */
1367 tic4x_op_hash
= hash_new ();
1369 /* Create hash table for asg pseudo. */
1370 tic4x_asg_hash
= hash_new ();
1372 /* Add mnemonics to hash table, expanding conditional mnemonics on fly. */
1373 for (i
= 0; i
< tic4x_num_insts
; i
++)
1374 ok
&= tic4x_inst_add (tic4x_insts
+ i
);
1376 /* Create dummy inst to avoid errors accessing end of table. */
1377 tic4x_inst_make ("", 0, "");
1380 as_fatal ("Broken assembler. No assembly attempted.");
1382 /* Add registers to symbol table. */
1383 tic4x_init_regtable ();
1385 /* Add predefined symbols to symbol table. */
1386 tic4x_init_symbols ();
1392 bfd_set_arch_mach (stdoutput
, bfd_arch_tic4x
,
1393 IS_CPU_TIC4X (tic4x_cpu
) ? bfd_mach_tic4x
: bfd_mach_tic3x
);
1397 tic4x_indirect_parse (tic4x_operand_t
*operand
,
1398 const tic4x_indirect_t
*indirect
)
1400 const char *n
= indirect
->name
;
1401 char *s
= input_line_pointer
;
1411 case 'a': /* Need to match aux register. */
1413 #ifdef TIC4X_ALT_SYNTAX
1417 while (ISALNUM (*s
))
1420 if (!(symbolP
= symbol_find (name
)))
1423 if (S_GET_SEGMENT (symbolP
) != reg_section
)
1426 operand
->aregno
= S_GET_VALUE (symbolP
);
1427 if (operand
->aregno
>= REG_AR0
&& operand
->aregno
<= REG_AR7
)
1430 as_bad (_("Auxiliary register AR0--AR7 required for indirect"));
1433 case 'd': /* Need to match constant for disp. */
1434 #ifdef TIC4X_ALT_SYNTAX
1435 if (*s
== '%') /* expr() will die if we don't skip this. */
1438 s
= tic4x_expression (s
, &operand
->expr
);
1439 if (operand
->expr
.X_op
!= O_constant
)
1441 operand
->disp
= operand
->expr
.X_add_number
;
1442 if (operand
->disp
< 0 || operand
->disp
> 255)
1444 as_bad (_("Bad displacement %d (require 0--255)\n"),
1450 case 'y': /* Need to match IR0. */
1451 case 'z': /* Need to match IR1. */
1452 #ifdef TIC4X_ALT_SYNTAX
1456 s
= tic4x_expression (s
, &operand
->expr
);
1457 if (operand
->expr
.X_op
!= O_register
)
1459 if (operand
->expr
.X_add_number
!= REG_IR0
1460 && operand
->expr
.X_add_number
!= REG_IR1
)
1462 as_bad (_("Index register IR0,IR1 required for displacement"));
1466 if (*n
== 'y' && operand
->expr
.X_add_number
== REG_IR0
)
1468 if (*n
== 'z' && operand
->expr
.X_add_number
== REG_IR1
)
1473 if (*s
!= '(') /* No displacement, assume to be 1. */
1484 if (TOLOWER (*s
) != *n
)
1489 if (*s
!= ' ' && *s
!= ',' && *s
!= '\0')
1491 input_line_pointer
= s
;
1496 tic4x_operand_parse (char *s
, tic4x_operand_t
*operand
)
1501 expressionS
*exp
= &operand
->expr
;
1502 char *save
= input_line_pointer
;
1505 struct hash_entry
*entry
= NULL
;
1507 input_line_pointer
= s
;
1510 c
= get_symbol_name (&str
); /* Get terminator. */
1511 new_pointer
= input_line_pointer
;
1512 if (strlen (str
) && (entry
= hash_find (tic4x_asg_hash
, str
)) != NULL
)
1514 (void) restore_line_pointer (c
);
1515 input_line_pointer
= (char *) entry
;
1519 (void) restore_line_pointer (c
);
1520 input_line_pointer
= str
;
1523 operand
->mode
= M_UNKNOWN
;
1524 switch (*input_line_pointer
)
1526 #ifdef TIC4X_ALT_SYNTAX
1528 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1529 if (exp
->X_op
!= O_register
)
1530 as_bad (_("Expecting a register name"));
1531 operand
->mode
= M_REGISTER
;
1535 /* Denotes high 16 bits. */
1536 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1537 if (exp
->X_op
== O_constant
)
1538 operand
->mode
= M_IMMED
;
1539 else if (exp
->X_op
== O_big
)
1541 if (exp
->X_add_number
)
1542 as_bad (_("Number too large")); /* bignum required */
1545 tic4x_gen_to_words (generic_floating_point_number
,
1546 operand
->fwords
, S_PRECISION
);
1547 operand
->mode
= M_IMMED_F
;
1550 /* Allow ori ^foo, ar0 to be equivalent to ldi .hi.foo, ar0 */
1551 /* WARNING : The TI C40 assembler cannot do this. */
1552 else if (exp
->X_op
== O_symbol
)
1553 operand
->mode
= M_HI
;
1555 as_bad (_("Expecting a constant value"));
1559 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1560 if (exp
->X_op
== O_constant
)
1561 operand
->mode
= M_IMMED
;
1562 else if (exp
->X_op
== O_big
)
1564 if (exp
->X_add_number
> 0)
1565 as_bad (_("Number too large")); /* bignum required. */
1568 tic4x_gen_to_words (generic_floating_point_number
,
1569 operand
->fwords
, S_PRECISION
);
1570 operand
->mode
= M_IMMED_F
;
1573 /* Allow ori foo, ar0 to be equivalent to ldi .lo.foo, ar0 */
1574 /* WARNING : The TI C40 assembler cannot do this. */
1575 else if (exp
->X_op
== O_symbol
)
1576 operand
->mode
= M_IMMED
;
1578 as_bad (_("Expecting a constant value"));
1584 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1585 if (exp
->X_op
!= O_constant
&& exp
->X_op
!= O_symbol
)
1586 as_bad (_("Bad direct addressing construct %s"), s
);
1587 if (exp
->X_op
== O_constant
)
1589 if (exp
->X_add_number
< 0)
1590 as_bad (_("Direct value of %ld is not suitable"),
1591 (long) exp
->X_add_number
);
1593 operand
->mode
= M_DIRECT
;
1598 for (i
= 0; i
< tic4x_num_indirects
; i
++)
1599 if ((ret
= tic4x_indirect_parse (operand
, &tic4x_indirects
[i
])))
1603 if (i
< tic4x_num_indirects
)
1605 operand
->mode
= M_INDIRECT
;
1606 /* Indirect addressing mode number. */
1607 operand
->expr
.X_add_number
= tic4x_indirects
[i
].modn
;
1608 /* Convert *+ARn(0) to *ARn etc. Maybe we should
1609 squeal about silly ones? */
1610 if (operand
->expr
.X_add_number
< 0x08 && !operand
->disp
)
1611 operand
->expr
.X_add_number
= 0x18;
1614 as_bad (_("Unknown indirect addressing mode"));
1618 operand
->mode
= M_IMMED
; /* Assume immediate. */
1619 str
= input_line_pointer
;
1620 input_line_pointer
= tic4x_expression (input_line_pointer
, exp
);
1621 if (exp
->X_op
== O_register
)
1623 know (exp
->X_add_symbol
== 0);
1624 know (exp
->X_op_symbol
== 0);
1625 operand
->mode
= M_REGISTER
;
1628 else if (exp
->X_op
== O_big
)
1630 if (exp
->X_add_number
> 0)
1631 as_bad (_("Number too large")); /* bignum required. */
1634 tic4x_gen_to_words (generic_floating_point_number
,
1635 operand
->fwords
, S_PRECISION
);
1636 operand
->mode
= M_IMMED_F
;
1640 #ifdef TIC4X_ALT_SYNTAX
1641 /* Allow ldi foo, ar0 to be equivalent to ldi @foo, ar0. */
1642 else if (exp
->X_op
== O_symbol
)
1644 operand
->mode
= M_DIRECT
;
1650 new_pointer
= input_line_pointer
;
1651 input_line_pointer
= save
;
1656 tic4x_operands_match (tic4x_inst_t
*inst
, tic4x_insn_t
*tinsn
, int check
)
1658 const char *args
= inst
->args
;
1659 unsigned long opcode
= inst
->opcode
;
1660 int num_operands
= tinsn
->num_operands
;
1661 tic4x_operand_t
*operand
= tinsn
->operands
;
1662 expressionS
*exp
= &operand
->expr
;
1666 /* Build the opcode, checking as we go to make sure that the
1669 If an operand matches, we modify insn or opcode appropriately,
1670 and do a "continue". If an operand fails to match, we "break". */
1672 tinsn
->nchars
= 4; /* Instructions always 4 bytes. */
1673 tinsn
->reloc
= NO_RELOC
;
1678 tinsn
->opcode
= opcode
;
1679 return num_operands
== 0;
1687 case '\0': /* End of args. */
1688 if (num_operands
== 1)
1690 tinsn
->opcode
= opcode
;
1693 break; /* Too many operands. */
1695 case '#': /* This is only used for ldp. */
1696 if (operand
->mode
!= M_DIRECT
&& operand
->mode
!= M_IMMED
)
1698 /* While this looks like a direct addressing mode, we actually
1699 use an immediate mode form of ldiu or ldpk instruction. */
1700 if (exp
->X_op
== O_constant
)
1702 if( ( IS_CPU_TIC4X (tic4x_cpu
) && exp
->X_add_number
<= 65535 )
1703 || ( IS_CPU_TIC3X (tic4x_cpu
) && exp
->X_add_number
<= 255 ) )
1705 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1711 as_bad (_("Immediate value of %ld is too large for ldf"),
1712 (long) exp
->X_add_number
);
1717 else if (exp
->X_op
== O_symbol
)
1719 tinsn
->reloc
= BFD_RELOC_HI16
;
1723 break; /* Not direct (dp) addressing. */
1725 case '@': /* direct. */
1726 if (operand
->mode
!= M_DIRECT
)
1728 if (exp
->X_op
== O_constant
)
1730 /* Store only the 16 LSBs of the number. */
1731 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1734 else if (exp
->X_op
== O_symbol
)
1736 tinsn
->reloc
= BFD_RELOC_LO16
;
1740 break; /* Not direct addressing. */
1743 if (operand
->mode
!= M_REGISTER
)
1745 reg
= exp
->X_add_number
;
1746 if (reg
>= REG_AR0
&& reg
<= REG_AR7
)
1747 INSERTU (opcode
, reg
- REG_AR0
, 24, 22);
1751 as_bad (_("Destination register must be ARn"));
1756 case 'B': /* Unsigned integer immediate. */
1757 /* Allow br label or br @label. */
1758 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
1760 if (exp
->X_op
== O_constant
)
1762 if (exp
->X_add_number
< (1 << 24))
1764 INSERTU (opcode
, exp
->X_add_number
, 23, 0);
1770 as_bad (_("Immediate value of %ld is too large"),
1771 (long) exp
->X_add_number
);
1776 if (IS_CPU_TIC4X (tic4x_cpu
))
1778 tinsn
->reloc
= BFD_RELOC_24_PCREL
;
1783 tinsn
->reloc
= BFD_RELOC_24
;
1790 if (!IS_CPU_TIC4X (tic4x_cpu
))
1792 if (operand
->mode
!= M_INDIRECT
)
1794 /* Require either *+ARn(disp) or *ARn. */
1795 if (operand
->expr
.X_add_number
!= 0
1796 && operand
->expr
.X_add_number
!= 0x18)
1799 as_bad (_("Invalid indirect addressing mode"));
1803 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1804 INSERTU (opcode
, operand
->disp
, 7, 3);
1808 if (!(operand
->mode
== M_REGISTER
))
1810 INSERTU (opcode
, exp
->X_add_number
, 7, 0);
1814 if (!(operand
->mode
== M_REGISTER
))
1816 reg
= exp
->X_add_number
;
1817 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1818 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1819 INSERTU (opcode
, reg
, 7, 0);
1823 as_bad (_("Register must be Rn"));
1829 if (operand
->mode
!= M_IMMED_F
1830 && !(operand
->mode
== M_IMMED
&& exp
->X_op
== O_constant
))
1833 if (operand
->mode
!= M_IMMED_F
)
1835 /* OK, we 've got something like cmpf 0, r0
1836 Why can't they stick in a bloody decimal point ?! */
1839 /* Create floating point number string. */
1840 sprintf (string
, "%d.0", (int) exp
->X_add_number
);
1841 tic4x_atof (string
, 's', operand
->fwords
);
1844 INSERTU (opcode
, operand
->fwords
[0], 15, 0);
1848 if (operand
->mode
!= M_REGISTER
)
1850 INSERTU (opcode
, exp
->X_add_number
, 15, 8);
1854 if (operand
->mode
!= M_REGISTER
)
1856 reg
= exp
->X_add_number
;
1857 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1858 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1859 INSERTU (opcode
, reg
, 15, 8);
1863 as_bad (_("Register must be Rn"));
1869 if (operand
->mode
!= M_REGISTER
)
1871 reg
= exp
->X_add_number
;
1872 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1873 INSERTU (opcode
, reg
- REG_R0
, 18, 16);
1877 as_bad (_("Register must be R0--R7"));
1883 if ( operand
->mode
== M_REGISTER
1884 && tic4x_oplevel
& OP_ENH
)
1886 reg
= exp
->X_add_number
;
1887 INSERTU (opcode
, reg
, 4, 0);
1888 INSERTU (opcode
, 7, 7, 5);
1894 if (operand
->mode
!= M_INDIRECT
)
1896 if (operand
->disp
!= 0 && operand
->disp
!= 1)
1898 if (IS_CPU_TIC4X (tic4x_cpu
))
1901 as_bad (_("Invalid indirect addressing mode displacement %d"),
1906 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1907 INSERTU (opcode
, operand
->expr
.X_add_number
, 7, 3);
1911 if ( operand
->mode
== M_REGISTER
1912 && tic4x_oplevel
& OP_ENH
)
1914 reg
= exp
->X_add_number
;
1915 INSERTU (opcode
, reg
, 12, 8);
1916 INSERTU (opcode
, 7, 15, 13);
1922 if (operand
->mode
!= M_INDIRECT
)
1924 if (operand
->disp
!= 0 && operand
->disp
!= 1)
1926 if (IS_CPU_TIC4X (tic4x_cpu
))
1929 as_bad (_("Invalid indirect addressing mode displacement %d"),
1934 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
1935 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
1939 if (operand
->mode
!= M_REGISTER
)
1941 reg
= exp
->X_add_number
;
1942 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1943 INSERTU (opcode
, reg
- REG_R0
, 21, 19);
1947 as_bad (_("Register must be R0--R7"));
1953 if (operand
->mode
!= M_REGISTER
)
1955 reg
= exp
->X_add_number
;
1956 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1957 INSERTU (opcode
, reg
- REG_R0
, 24, 22);
1961 as_bad (_("Register must be R0--R7"));
1967 if (operand
->mode
!= M_REGISTER
)
1969 reg
= exp
->X_add_number
;
1970 if (reg
== REG_R2
|| reg
== REG_R3
)
1971 INSERTU (opcode
, reg
- REG_R2
, 22, 22);
1975 as_bad (_("Destination register must be R2 or R3"));
1981 if (operand
->mode
!= M_REGISTER
)
1983 reg
= exp
->X_add_number
;
1984 if (reg
== REG_R0
|| reg
== REG_R1
)
1985 INSERTU (opcode
, reg
- REG_R0
, 23, 23);
1989 as_bad (_("Destination register must be R0 or R1"));
1995 if (!IS_CPU_TIC4X (tic4x_cpu
))
1997 if (operand
->mode
!= M_INDIRECT
)
1999 /* Require either *+ARn(disp) or *ARn. */
2000 if (operand
->expr
.X_add_number
!= 0
2001 && operand
->expr
.X_add_number
!= 0x18)
2004 as_bad (_("Invalid indirect addressing mode"));
2008 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2009 INSERTU (opcode
, operand
->disp
, 15, 11);
2012 case 'P': /* PC relative displacement. */
2013 /* Allow br label or br @label. */
2014 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
2016 if (exp
->X_op
== O_constant
)
2018 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 32767)
2020 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2026 as_bad (_("Displacement value of %ld is too large"),
2027 (long) exp
->X_add_number
);
2032 tinsn
->reloc
= BFD_RELOC_16_PCREL
;
2038 if (operand
->mode
!= M_REGISTER
)
2040 reg
= exp
->X_add_number
;
2041 INSERTU (opcode
, reg
, 15, 0);
2045 if (operand
->mode
!= M_REGISTER
)
2047 reg
= exp
->X_add_number
;
2048 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2049 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2050 INSERTU (opcode
, reg
, 15, 0);
2054 as_bad (_("Register must be Rn"));
2060 if (operand
->mode
!= M_REGISTER
)
2062 reg
= exp
->X_add_number
;
2063 INSERTU (opcode
, reg
, 20, 16);
2067 if (operand
->mode
!= M_REGISTER
)
2069 reg
= exp
->X_add_number
;
2070 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2071 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2072 INSERTU (opcode
, reg
, 20, 16);
2076 as_bad (_("Register must be Rn"));
2081 case 'S': /* Short immediate int. */
2082 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2084 if (exp
->X_op
== O_big
)
2087 as_bad (_("Floating point number not valid in expression"));
2091 if (exp
->X_op
== O_constant
)
2093 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 65535)
2095 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2101 as_bad (_("Signed immediate value %ld too large"),
2102 (long) exp
->X_add_number
);
2107 else if (exp
->X_op
== O_symbol
)
2109 if (operand
->mode
== M_HI
)
2111 tinsn
->reloc
= BFD_RELOC_HI16
;
2115 tinsn
->reloc
= BFD_RELOC_LO16
;
2120 /* Handle cases like ldi foo - $, ar0 where foo
2121 is a forward reference. Perhaps we should check
2122 for X_op == O_symbol and disallow things like
2124 tinsn
->reloc
= BFD_RELOC_16
;
2128 case 'T': /* 5-bit immediate value for tic4x stik. */
2129 if (!IS_CPU_TIC4X (tic4x_cpu
))
2131 if (operand
->mode
!= M_IMMED
)
2133 if (exp
->X_op
== O_constant
)
2135 if (exp
->X_add_number
< 16 && exp
->X_add_number
>= -16)
2137 INSERTS (opcode
, exp
->X_add_number
, 20, 16);
2143 as_bad (_("Immediate value of %ld is too large"),
2144 (long) exp
->X_add_number
);
2149 break; /* No relocations allowed. */
2151 case 'U': /* Unsigned integer immediate. */
2152 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2154 if (exp
->X_op
== O_constant
)
2156 if (exp
->X_add_number
< (1 << 16) && exp
->X_add_number
>= 0)
2158 INSERTU (opcode
, exp
->X_add_number
, 15, 0);
2164 as_bad (_("Unsigned immediate value %ld too large"),
2165 (long) exp
->X_add_number
);
2170 else if (exp
->X_op
== O_symbol
)
2172 if (operand
->mode
== M_HI
)
2173 tinsn
->reloc
= BFD_RELOC_HI16
;
2175 tinsn
->reloc
= BFD_RELOC_LO16
;
2180 tinsn
->reloc
= BFD_RELOC_16
;
2184 case 'V': /* Trap numbers (immediate field). */
2185 if (operand
->mode
!= M_IMMED
)
2187 if (exp
->X_op
== O_constant
)
2189 if (exp
->X_add_number
< 512 && IS_CPU_TIC4X (tic4x_cpu
))
2191 INSERTU (opcode
, exp
->X_add_number
, 8, 0);
2194 else if (exp
->X_add_number
< 32 && IS_CPU_TIC3X (tic4x_cpu
))
2196 INSERTU (opcode
, exp
->X_add_number
| 0x20, 4, 0);
2202 as_bad (_("Immediate value of %ld is too large"),
2203 (long) exp
->X_add_number
);
2208 break; /* No relocations allowed. */
2210 case 'W': /* Short immediate int (0--7). */
2211 if (!IS_CPU_TIC4X (tic4x_cpu
))
2213 if (operand
->mode
!= M_IMMED
)
2215 if (exp
->X_op
== O_big
)
2218 as_bad (_("Floating point number not valid in expression"));
2222 if (exp
->X_op
== O_constant
)
2224 if (exp
->X_add_number
>= -256 && exp
->X_add_number
<= 127)
2226 INSERTS (opcode
, exp
->X_add_number
, 7, 0);
2232 as_bad (_("Immediate value %ld too large"),
2233 (long) exp
->X_add_number
);
2238 tinsn
->reloc
= BFD_RELOC_16
;
2242 case 'X': /* Expansion register for tic4x. */
2243 if (operand
->mode
!= M_REGISTER
)
2245 reg
= exp
->X_add_number
;
2246 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2247 INSERTU (opcode
, reg
- REG_IVTP
, 4, 0);
2251 as_bad (_("Register must be ivtp or tvtp"));
2256 case 'Y': /* Address register for tic4x lda. */
2257 if (operand
->mode
!= M_REGISTER
)
2259 reg
= exp
->X_add_number
;
2260 if (reg
>= REG_AR0
&& reg
<= REG_SP
)
2261 INSERTU (opcode
, reg
, 20, 16);
2265 as_bad (_("Register must be address register"));
2270 case 'Z': /* Expansion register for tic4x. */
2271 if (operand
->mode
!= M_REGISTER
)
2273 reg
= exp
->X_add_number
;
2274 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2275 INSERTU (opcode
, reg
- REG_IVTP
, 20, 16);
2279 as_bad (_("Register must be ivtp or tvtp"));
2285 if (operand
->mode
!= M_INDIRECT
)
2287 INSERTS (opcode
, operand
->disp
, 7, 0);
2288 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2289 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
2292 case '|': /* treat as `,' if have ldi_ldi form. */
2293 if (tinsn
->parallel
)
2295 if (--num_operands
< 0)
2296 break; /* Too few operands. */
2298 if (operand
->mode
!= M_PARALLEL
)
2303 case ',': /* Another operand. */
2304 if (--num_operands
< 0)
2305 break; /* Too few operands. */
2307 exp
= &operand
->expr
;
2310 case ';': /* Another optional operand. */
2311 if (num_operands
== 1 || operand
[1].mode
== M_PARALLEL
)
2313 if (--num_operands
< 0)
2314 break; /* Too few operands. */
2316 exp
= &operand
->expr
;
2327 tic4x_insn_check (tic4x_insn_t
*tinsn
)
2330 if (!strcmp (tinsn
->name
, "lda"))
2332 if (tinsn
->num_operands
< 2 || tinsn
->num_operands
> 2)
2333 as_fatal ("Illegal internal LDA insn definition");
2335 if (tinsn
->operands
[0].mode
== M_REGISTER
2336 && tinsn
->operands
[1].mode
== M_REGISTER
2337 && tinsn
->operands
[0].expr
.X_add_number
== tinsn
->operands
[1].expr
.X_add_number
)
2338 as_bad (_("Source and destination register should not be equal"));
2340 else if (!strcmp (tinsn
->name
, "ldi_ldi")
2341 || !strcmp (tinsn
->name
, "ldi1_ldi2")
2342 || !strcmp (tinsn
->name
, "ldi2_ldi1")
2343 || !strcmp (tinsn
->name
, "ldf_ldf")
2344 || !strcmp (tinsn
->name
, "ldf1_ldf2")
2345 || !strcmp (tinsn
->name
, "ldf2_ldf1") )
2347 if (tinsn
->num_operands
< 4 || tinsn
->num_operands
> 5)
2348 as_fatal ("Illegal internal %s insn definition", tinsn
->name
);
2350 if (tinsn
->operands
[1].mode
== M_REGISTER
2351 && tinsn
->operands
[tinsn
->num_operands
-1].mode
== M_REGISTER
2352 && tinsn
->operands
[1].expr
.X_add_number
== tinsn
->operands
[tinsn
->num_operands
-1].expr
.X_add_number
)
2353 as_warn (_("Equal parallel destination registers, one result will be discarded"));
2358 tic4x_insn_output (tic4x_insn_t
*tinsn
)
2362 /* Grab another fragment for opcode. */
2363 dst
= frag_more (tinsn
->nchars
);
2365 /* Put out opcode word as a series of bytes in little endian order. */
2366 md_number_to_chars (dst
, tinsn
->opcode
, tinsn
->nchars
);
2368 /* Put out the symbol-dependent stuff. */
2369 if (tinsn
->reloc
!= NO_RELOC
)
2371 /* Where is the offset into the fragment for this instruction. */
2372 fix_new_exp (frag_now
,
2373 dst
- frag_now
->fr_literal
, /* where */
2374 tinsn
->nchars
, /* size */
2381 /* Parse the operands. */
2383 tic4x_operands_parse (char *s
, tic4x_operand_t
*operands
, int num_operands
)
2386 return num_operands
;
2389 s
= tic4x_operand_parse (s
, &operands
[num_operands
++]);
2390 while (num_operands
< TIC4X_OPERANDS_MAX
&& *s
++ == ',');
2392 if (num_operands
> TIC4X_OPERANDS_MAX
)
2394 as_bad (_("Too many operands scanned"));
2397 return num_operands
;
2400 /* Assemble a single instruction. Its label has already been handled
2401 by the generic front end. We just parse mnemonic and operands, and
2402 produce the bytes of data and relocation. */
2404 md_assemble (char *str
)
2411 tic4x_inst_t
*inst
; /* Instruction template. */
2412 tic4x_inst_t
*first_inst
;
2414 /* Scan for parallel operators */
2418 while (*s
&& *s
!= '|')
2421 if (*s
&& s
[1]=='|')
2425 as_bad (_("Parallel opcode cannot contain more than two instructions"));
2431 /* Lets take care of the first part of the parallel insn */
2436 /* .. and let the second run though here */
2440 if (str
&& insn
->parallel
)
2442 /* Find mnemonic (second part of parallel instruction). */
2444 /* Skip past instruction mnemonic. */
2445 while (*s
&& *s
!= ' ')
2447 if (*s
) /* Null terminate for hash_find. */
2448 *s
++ = '\0'; /* and skip past null. */
2449 len
= strlen (insn
->name
);
2450 snprintf (insn
->name
+ len
, TIC4X_NAME_MAX
- len
, "_%s", str
);
2452 insn
->operands
[insn
->num_operands
++].mode
= M_PARALLEL
;
2454 if ((i
= tic4x_operands_parse
2455 (s
, insn
->operands
, insn
->num_operands
)) < 0)
2461 insn
->num_operands
= i
;
2467 if ((insn
->inst
= (struct tic4x_inst
*)
2468 hash_find (tic4x_op_hash
, insn
->name
)) == NULL
)
2470 as_bad (_("Unknown opcode `%s'."), insn
->name
);
2480 ok
= tic4x_operands_match (inst
, insn
, 1);
2488 while (!ok
&& !strcmp (inst
->name
, inst
[1].name
) && inst
++);
2492 tic4x_insn_check (insn
);
2493 tic4x_insn_output (insn
);
2498 tic4x_operands_match (first_inst
, insn
, 0);
2499 as_bad (_("Invalid operands for %s"), insn
->name
);
2502 as_bad (_("Invalid instruction %s"), insn
->name
);
2507 /* Find mnemonic. */
2509 while (*s
&& *s
!= ' ') /* Skip past instruction mnemonic. */
2511 if (*s
) /* Null terminate for hash_find. */
2512 *s
++ = '\0'; /* and skip past null. */
2513 strncpy (insn
->name
, str
, TIC4X_NAME_MAX
- 1);
2514 insn
->name
[TIC4X_NAME_MAX
- 1] = '\0';
2516 if ((i
= tic4x_operands_parse (s
, insn
->operands
, 0)) < 0)
2518 insn
->inst
= NULL
; /* Flag that error occurred. */
2523 insn
->num_operands
= i
;
2532 tic4x_cleanup (void)
2538 /* Turn a string in input_line_pointer into a floating point constant
2539 of type type, and store the appropriate bytes in *litP. The number
2540 of chars emitted is stored in *sizeP. An error message is
2541 returned, or NULL on OK. */
2544 md_atof (int type
, char *litP
, int *sizeP
)
2548 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2549 LITTLENUM_TYPE
*wordP
;
2554 case 's': /* .single */
2560 case 'd': /* .double */
2562 case 'f': /* .float */
2565 prec
= 2; /* 1 32-bit word */
2568 case 'i': /* .ieee */
2572 type
= 'f'; /* Rewrite type to be usable by atof_ieee(). */
2575 case 'e': /* .ldouble */
2577 prec
= 4; /* 2 32-bit words */
2583 return _("Unrecognized or unsupported floating point constant");
2587 t
= atof_ieee (input_line_pointer
, type
, words
);
2589 t
= tic4x_atof (input_line_pointer
, type
, words
);
2591 input_line_pointer
= t
;
2592 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
2594 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
2595 little endian byte order. */
2596 /* SES: However it is required to put the words (32-bits) out in the
2597 correct order, hence we write 2 and 2 littlenums in little endian
2598 order, while we keep the original order on successive words. */
2599 for (wordP
= words
; wordP
<(words
+prec
) ; wordP
+=2)
2601 if (wordP
< (words
+ prec
- 1)) /* Dump wordP[1] (if we have one). */
2603 md_number_to_chars (litP
, (valueT
) (wordP
[1]),
2604 sizeof (LITTLENUM_TYPE
));
2605 litP
+= sizeof (LITTLENUM_TYPE
);
2609 md_number_to_chars (litP
, (valueT
) (wordP
[0]),
2610 sizeof (LITTLENUM_TYPE
));
2611 litP
+= sizeof (LITTLENUM_TYPE
);
2617 md_apply_fix (fixS
*fixP
, valueT
*value
, segT seg ATTRIBUTE_UNUSED
)
2619 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
2620 valueT val
= *value
;
2622 switch (fixP
->fx_r_type
)
2624 case BFD_RELOC_HI16
:
2628 case BFD_RELOC_LO16
:
2635 switch (fixP
->fx_r_type
)
2641 case BFD_RELOC_24_PCREL
:
2645 case BFD_RELOC_16_PCREL
:
2646 case BFD_RELOC_LO16
:
2647 case BFD_RELOC_HI16
:
2654 as_bad (_("Bad relocation type: 0x%02x"), fixP
->fx_r_type
);
2658 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0) fixP
->fx_done
= 1;
2661 /* Should never be called for tic4x. */
2663 md_convert_frag (bfd
*headers ATTRIBUTE_UNUSED
,
2664 segT sec ATTRIBUTE_UNUSED
,
2665 fragS
*fragP ATTRIBUTE_UNUSED
)
2667 as_fatal ("md_convert_frag");
2670 /* Should never be called for tic4x. */
2672 md_create_short_jump (char *ptr ATTRIBUTE_UNUSED
,
2673 addressT from_addr ATTRIBUTE_UNUSED
,
2674 addressT to_addr ATTRIBUTE_UNUSED
,
2675 fragS
*frag ATTRIBUTE_UNUSED
,
2676 symbolS
*to_symbol ATTRIBUTE_UNUSED
)
2678 as_fatal ("md_create_short_jmp\n");
2681 /* Should never be called for tic4x. */
2683 md_create_long_jump (char *ptr ATTRIBUTE_UNUSED
,
2684 addressT from_addr ATTRIBUTE_UNUSED
,
2685 addressT to_addr ATTRIBUTE_UNUSED
,
2686 fragS
*frag ATTRIBUTE_UNUSED
,
2687 symbolS
*to_symbol ATTRIBUTE_UNUSED
)
2689 as_fatal ("md_create_long_jump\n");
2692 /* Should never be called for tic4x. */
2694 md_estimate_size_before_relax (fragS
*fragP ATTRIBUTE_UNUSED
,
2695 segT segtype ATTRIBUTE_UNUSED
)
2697 as_fatal ("md_estimate_size_before_relax\n");
2703 md_parse_option (int c
, const char *arg
)
2707 case OPTION_CPU
: /* cpu brand */
2708 if (TOLOWER (*arg
) == 'c')
2710 tic4x_cpu
= atoi (arg
);
2711 if (!IS_CPU_TIC3X (tic4x_cpu
) && !IS_CPU_TIC4X (tic4x_cpu
))
2712 as_warn (_("Unsupported processor generation %d"), tic4x_cpu
);
2715 case OPTION_REV
: /* cpu revision */
2716 tic4x_revision
= atoi (arg
);
2720 as_warn (_("Option -b is depreciated, please use -mbig"));
2722 case OPTION_BIG
: /* big model */
2723 tic4x_big_model
= 1;
2727 as_warn (_("Option -p is depreciated, please use -mmemparm"));
2729 case OPTION_MEMPARM
: /* push args */
2734 as_warn (_("Option -r is depreciated, please use -mregparm"));
2736 case OPTION_REGPARM
: /* register args */
2741 as_warn (_("Option -s is depreciated, please use -msmall"));
2743 case OPTION_SMALL
: /* small model */
2744 tic4x_big_model
= 0;
2751 case OPTION_LOWPOWER
:
2755 case OPTION_ENHANCED
:
2767 md_show_usage (FILE *stream
)
2770 _("\nTIC4X options:\n"
2771 " -mcpu=CPU -mCPU select architecture variant. CPU can be:\n"
2773 " 31 - TMS320C31, TMS320LC31\n"
2775 " 33 - TMS320VC33\n"
2778 " -mrev=REV set cpu hardware revision (integer numbers).\n"
2779 " Combinations of -mcpu and -mrev will enable/disable\n"
2780 " the appropriate options (-midle2, -mlowpower and\n"
2781 " -menhanced) according to the selected type\n"
2782 " -mbig select big memory model\n"
2783 " -msmall select small memory model (default)\n"
2784 " -mregparm select register parameters (default)\n"
2785 " -mmemparm select memory parameters\n"
2786 " -midle2 enable IDLE2 support\n"
2787 " -mlowpower enable LOPOWER and MAXSPEED support\n"
2788 " -menhanced enable enhanced opcode support\n"));
2791 /* This is called when a line is unrecognized. This is used to handle
2792 definitions of TI C3x tools style local labels $n where n is a single
2795 tic4x_unrecognized_line (int c
)
2800 if (c
!= '$' || ! ISDIGIT (input_line_pointer
[0]))
2803 s
= input_line_pointer
;
2805 /* Let's allow multiple digit local labels. */
2807 while (ISDIGIT (*s
))
2809 lab
= lab
* 10 + *s
- '0';
2813 if (dollar_label_defined (lab
))
2815 as_bad (_("Label \"$%d\" redefined"), lab
);
2819 define_dollar_label (lab
);
2820 colon (dollar_label_name (lab
, 0));
2821 input_line_pointer
= s
+ 1;
2826 /* Handle local labels peculiar to us referred to in an expression. */
2828 md_undefined_symbol (char *name
)
2830 /* Look for local labels of the form $n. */
2831 if (name
[0] == '$' && ISDIGIT (name
[1]))
2837 while (ISDIGIT ((unsigned char) *s
))
2839 lab
= lab
* 10 + *s
- '0';
2842 if (dollar_label_defined (lab
))
2844 name
= dollar_label_name (lab
, 0);
2845 symbolP
= symbol_find (name
);
2849 name
= dollar_label_name (lab
, 1);
2850 symbolP
= symbol_find_or_make (name
);
2858 /* Parse an operand that is machine-specific. */
2860 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
2864 /* Round up a section size to the appropriate boundary---do we need this? */
2866 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
2868 return size
; /* Byte (i.e., 32-bit) alignment is fine? */
2872 tic4x_pc_offset (unsigned int op
)
2874 /* Determine the PC offset for a C[34]x instruction.
2875 This could be simplified using some boolean algebra
2876 but at the expense of readability. */
2880 case 0x62: /* call (C4x) */
2881 case 0x64: /* rptb (C4x) */
2883 case 0x61: /* brd */
2884 case 0x63: /* laj */
2885 case 0x65: /* rptbd (C4x) */
2887 case 0x66: /* swi */
2894 switch ((op
& 0xffe00000) >> 20)
2896 case 0x6a0: /* bB */
2897 case 0x720: /* callB */
2898 case 0x740: /* trapB */
2901 case 0x6a2: /* bBd */
2902 case 0x6a6: /* bBat */
2903 case 0x6aa: /* bBaf */
2904 case 0x722: /* lajB */
2905 case 0x748: /* latB */
2906 case 0x798: /* rptbd */
2913 switch ((op
& 0xfe200000) >> 20)
2915 case 0x6e0: /* dbB */
2918 case 0x6e2: /* dbBd */
2928 /* Exactly what point is a PC-relative offset relative TO?
2929 With the C3x we have the following:
2930 DBcond, Bcond disp + PC + 1 => PC
2931 DBcondD, BcondD disp + PC + 3 => PC
2934 md_pcrel_from (fixS
*fixP
)
2939 buf
= (unsigned char *) fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2940 op
= (buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
2942 return ((fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) >> 2) +
2943 tic4x_pc_offset (op
);
2946 /* Fill the alignment area with NOP's on .text, unless fill-data
2949 tic4x_do_align (int alignment
,
2954 /* Because we are talking lwords, not bytes, adjust alignment to do words */
2957 if (alignment
!= 0 && !need_pass_2
)
2961 if (subseg_text_p (now_seg
))
2965 md_number_to_chars (nop
, TIC_NOP_OPCODE
, 4);
2966 frag_align_pattern (alignment
, nop
, sizeof (nop
), max
);
2969 frag_align (alignment
, 0, max
);
2972 frag_align (alignment
, *fill
, max
);
2974 frag_align_pattern (alignment
, fill
, len
, max
);
2977 /* Return 1 to skip the default alignment function */
2981 /* Look for and remove parallel instruction operator ||. */
2983 tic4x_start_line (void)
2985 char *s
= input_line_pointer
;
2989 /* If parallel instruction prefix found at start of line, skip it. */
2990 if (*input_line_pointer
== '|' && input_line_pointer
[1] == '|')
2995 input_line_pointer
++;
2996 *input_line_pointer
= ' ';
2997 /* So line counters get bumped. */
2998 input_line_pointer
[-1] = '\n';
3003 /* Write out the previous insn here */
3006 input_line_pointer
= s
;
3011 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixP
)
3015 reloc
= XNEW (arelent
);
3017 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
3018 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
3019 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
3020 reloc
->address
/= OCTETS_PER_BYTE
;
3021 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
3022 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
3024 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3025 _("Reloc %d not supported by object file format"),
3026 (int) fixP
->fx_r_type
);
3030 if (fixP
->fx_r_type
== BFD_RELOC_HI16
)
3031 reloc
->addend
= fixP
->fx_offset
;
3033 reloc
->addend
= fixP
->fx_addnumber
;