1 /* tc-tic4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
2 Copyright (C) 1997,1998, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010,
3 2012 Free Software Foundation. Inc.
5 Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
7 This file is part of GAS, the GNU Assembler.
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to
21 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
22 Boston, MA 02110-1301, USA. */
27 o .align cannot handle fill-data-width larger than 0xFF/8-bits. It
28 should be possible to define a 32-bits pattern.
30 o .align fills all section with NOP's when used regardless if has
31 been used in .text or .data. (However the .align is primarily
32 intended used in .text sections. If you require something else,
33 use .align <size>,0x00)
35 o .align: Implement a 'bu' insn if the number of nop's exceeds 4
36 within the align frag. if(fragsize>4words) insert bu fragend+1
39 o .usect if has symbol on previous line not implemented
41 o .sym, .eos, .stag, .etag, .member not implemented
43 o Evaluation of constant floating point expressions (expr.c needs
46 o Support 'abc' constants (that is 0x616263). */
49 #include "safe-ctype.h"
50 #include "opcode/tic4x.h"
54 /* OK, we accept a syntax similar to the other well known C30
55 assembly tools. With TIC4X_ALT_SYNTAX defined we are more
56 flexible, allowing a more Unix-like syntax: `%' in front of
57 register names, `#' in front of immediate constants, and
58 not requiring `@' in front of direct addresses. */
60 #define TIC4X_ALT_SYNTAX
62 /* Equal to MAX_PRECISION in atof-ieee.c. */
63 #define MAX_LITTLENUMS 6 /* (12 bytes) */
65 /* Handle of the inst mnemonic hash table. */
66 static struct hash_control
*tic4x_op_hash
= NULL
;
68 /* Handle asg pseudo. */
69 static struct hash_control
*tic4x_asg_hash
= NULL
;
71 static unsigned int tic4x_cpu
= 0; /* Default to TMS320C40. */
72 static unsigned int tic4x_revision
= 0; /* CPU revision */
73 static unsigned int tic4x_idle2
= 0; /* Idle2 support */
74 static unsigned int tic4x_lowpower
= 0; /* Lowpower support */
75 static unsigned int tic4x_enhanced
= 0; /* Enhanced opcode support */
76 static unsigned int tic4x_big_model
= 0; /* Default to small memory model. */
77 static unsigned int tic4x_reg_args
= 0; /* Default to args passed on stack. */
78 static unsigned long tic4x_oplevel
= 0; /* Opcode level */
80 #define OPTION_CPU 'm'
81 #define OPTION_BIG (OPTION_MD_BASE + 1)
82 #define OPTION_SMALL (OPTION_MD_BASE + 2)
83 #define OPTION_MEMPARM (OPTION_MD_BASE + 3)
84 #define OPTION_REGPARM (OPTION_MD_BASE + 4)
85 #define OPTION_IDLE2 (OPTION_MD_BASE + 5)
86 #define OPTION_LOWPOWER (OPTION_MD_BASE + 6)
87 #define OPTION_ENHANCED (OPTION_MD_BASE + 7)
88 #define OPTION_REV (OPTION_MD_BASE + 8)
90 CONST
char *md_shortopts
= "bm:prs";
91 struct option md_longopts
[] =
93 { "mcpu", required_argument
, NULL
, OPTION_CPU
},
94 { "mdsp", required_argument
, NULL
, OPTION_CPU
},
95 { "mbig", no_argument
, NULL
, OPTION_BIG
},
96 { "msmall", no_argument
, NULL
, OPTION_SMALL
},
97 { "mmemparm", no_argument
, NULL
, OPTION_MEMPARM
},
98 { "mregparm", no_argument
, NULL
, OPTION_REGPARM
},
99 { "midle2", no_argument
, NULL
, OPTION_IDLE2
},
100 { "mlowpower", no_argument
, NULL
, OPTION_LOWPOWER
},
101 { "menhanced", no_argument
, NULL
, OPTION_ENHANCED
},
102 { "mrev", required_argument
, NULL
, OPTION_REV
},
103 { NULL
, no_argument
, NULL
, 0 }
106 size_t md_longopts_size
= sizeof (md_longopts
);
111 M_UNKNOWN
, M_IMMED
, M_DIRECT
, M_REGISTER
, M_INDIRECT
,
112 M_IMMED_F
, M_PARALLEL
, M_HI
116 typedef struct tic4x_operand
118 tic4x_addr_mode_t mode
; /* Addressing mode. */
119 expressionS expr
; /* Expression. */
120 int disp
; /* Displacement for indirect addressing. */
121 int aregno
; /* Aux. register number. */
122 LITTLENUM_TYPE fwords
[MAX_LITTLENUMS
]; /* Float immed. number. */
126 typedef struct tic4x_insn
128 char name
[TIC4X_NAME_MAX
]; /* Mnemonic of instruction. */
129 unsigned int in_use
; /* True if in_use. */
130 unsigned int parallel
; /* True if parallel instruction. */
131 unsigned int nchars
; /* This is always 4 for the C30. */
132 unsigned long opcode
; /* Opcode number. */
133 expressionS exp
; /* Expression required for relocation. */
134 int reloc
; /* Relocation type required. */
135 int pcrel
; /* True if relocation PC relative. */
136 char *pname
; /* Name of instruction in parallel. */
137 unsigned int num_operands
; /* Number of operands in total. */
138 tic4x_inst_t
*inst
; /* Pointer to first template. */
139 tic4x_operand_t operands
[TIC4X_OPERANDS_MAX
];
143 static tic4x_insn_t the_insn
; /* Info about our instruction. */
144 static tic4x_insn_t
*insn
= &the_insn
;
146 static void tic4x_asg (int);
147 static void tic4x_bss (int);
148 static void tic4x_globl (int);
149 static void tic4x_cons (int);
150 static void tic4x_stringer (int);
151 static void tic4x_eval (int);
152 static void tic4x_newblock (int);
153 static void tic4x_sect (int);
154 static void tic4x_set (int);
155 static void tic4x_usect (int);
156 static void tic4x_version (int);
162 {"align", s_align_bytes
, 32},
163 {"ascii", tic4x_stringer
, 1},
164 {"asciz", tic4x_stringer
, 0},
165 {"asg", tic4x_asg
, 0},
166 {"block", s_space
, 4},
167 {"byte", tic4x_cons
, 1},
168 {"bss", tic4x_bss
, 0},
169 {"copy", s_include
, 0},
170 {"def", tic4x_globl
, 0},
171 {"equ", tic4x_set
, 0},
172 {"eval", tic4x_eval
, 0},
173 {"global", tic4x_globl
, 0},
174 {"globl", tic4x_globl
, 0},
175 {"hword", tic4x_cons
, 2},
176 {"ieee", float_cons
, 'i'},
177 {"int", tic4x_cons
, 4}, /* .int allocates 4 bytes. */
178 {"ldouble", float_cons
, 'e'},
179 {"newblock", tic4x_newblock
, 0},
180 {"ref", s_ignore
, 0}, /* All undefined treated as external. */
181 {"set", tic4x_set
, 0},
182 {"sect", tic4x_sect
, 1}, /* Define named section. */
183 {"space", s_space
, 4},
184 {"string", tic4x_stringer
, 0},
185 {"usect", tic4x_usect
, 0}, /* Reserve space in uninit. named sect. */
186 {"version", tic4x_version
, 0},
187 {"word", tic4x_cons
, 4}, /* .word allocates 4 bytes. */
188 {"xdef", tic4x_globl
, 0},
192 int md_short_jump_size
= 4;
193 int md_long_jump_size
= 4;
195 /* This array holds the chars that always start a comment. If the
196 pre-processor is disabled, these aren't very useful. */
197 #ifdef TIC4X_ALT_SYNTAX
198 const char comment_chars
[] = ";!";
200 const char comment_chars
[] = ";";
203 /* This array holds the chars that only start a comment at the beginning of
204 a line. If the line seems to have the form '# 123 filename'
205 .line and .file directives will appear in the pre-processed output.
206 Note that input_file.c hand checks for '#' at the beginning of the
207 first line of the input file. This is because the compiler outputs
208 #NO_APP at the beginning of its output.
209 Also note that comments like this one will always work. */
210 const char line_comment_chars
[] = "#*";
212 /* We needed an unused char for line separation to work around the
213 lack of macros, using sed and such. */
214 const char line_separator_chars
[] = "&";
216 /* Chars that can be used to separate mant from exp in floating point nums. */
217 const char EXP_CHARS
[] = "eE";
219 /* Chars that mean this number is a floating point constant. */
222 const char FLT_CHARS
[] = "fFilsS";
224 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
225 changed in read.c. Ideally it shouldn't have to know about it at
226 all, but nothing is ideal around here. */
228 /* Flonums returned here. */
229 extern FLONUM_TYPE generic_floating_point_number
;
231 /* Precision in LittleNums. */
232 #define MAX_PRECISION (4) /* Its a bit overkill for us, but the code
234 #define S_PRECISION (1) /* Short float constants 16-bit. */
235 #define F_PRECISION (2) /* Float and double types 32-bit. */
236 #define E_PRECISION (4) /* Extended precision, 64-bit (real 40-bit). */
239 /* Turn generic_floating_point_number into a real short/float/double. */
241 tic4x_gen_to_words (FLONUM_TYPE flonum
, LITTLENUM_TYPE
*words
, int precision
)
243 int return_value
= 0;
244 LITTLENUM_TYPE
*p
; /* Littlenum pointer. */
245 int mantissa_bits
; /* Bits in mantissa field. */
246 int exponent_bits
; /* Bits in exponent field. */
248 unsigned int sone
; /* Scaled one. */
249 unsigned int sfract
; /* Scaled fraction. */
250 unsigned int smant
; /* Scaled mantissa. */
252 unsigned int mover
; /* Mantissa overflow bits */
253 unsigned int rbit
; /* Round bit. */
254 int shift
; /* Shift count. */
256 /* NOTE: Svein Seldal <Svein@dev.seldal.com>
257 The code in this function is altered slightly to support floats
258 with 31-bits mantissas, thus the documentation below may be a
259 little bit inaccurate.
261 By Michael P. Hayes <m.hayes@elec.canterbury.ac.nz>
262 Here is how a generic floating point number is stored using
263 flonums (an extension of bignums) where p is a pointer to an
266 For example 2e-3 is stored with exp = -4 and
273 with low = &bits[2], high = &bits[5], and leader = &bits[5].
275 This number can be written as
276 0x0083126e978d4fde.00000000 * 65536**-4 or
277 0x0.0083126e978d4fde * 65536**0 or
278 0x0.83126e978d4fde * 2**-8 = 2e-3
280 Note that low points to the 65536**0 littlenum (bits[2]) and
281 leader points to the most significant non-zero littlenum
284 TMS320C3X floating point numbers are a bit of a strange beast.
285 The 32-bit flavour has the 8 MSBs representing the exponent in
286 twos complement format (-128 to +127). There is then a sign bit
287 followed by 23 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 24 bits. Zero is represented by an
294 The 16-bit flavour has the 4 MSBs representing the exponent in
295 twos complement format (-8 to +7). There is then a sign bit
296 followed by 11 bits of mantissa. The mantissa is expressed in
297 twos complement format with the binary point after the most
298 significant non sign bit. The bit after the binary point is
299 suppressed since it is the complement of the sign bit. The
300 effective mantissa is thus 12 bits. Zero is represented by an
301 exponent of -8. For example,
303 number norm mant m x e s i fraction f
304 +0.500 => 1.00000000000 -1 -1 0 1 .00000000000 (1 + 0) * 2^(-1)
305 +0.999 => 1.11111111111 -1 -1 0 1 .11111111111 (1 + 0.99) * 2^(-1)
306 +1.000 => 1.00000000000 0 0 0 1 .00000000000 (1 + 0) * 2^(0)
307 +1.500 => 1.10000000000 0 0 0 1 .10000000000 (1 + 0.5) * 2^(0)
308 +1.999 => 1.11111111111 0 0 0 1 .11111111111 (1 + 0.9) * 2^(0)
309 +2.000 => 1.00000000000 1 1 0 1 .00000000000 (1 + 0) * 2^(1)
310 +4.000 => 1.00000000000 2 2 0 1 .00000000000 (1 + 0) * 2^(2)
311 -0.500 => 1.00000000000 -1 -1 1 0 .10000000000 (-2 + 0) * 2^(-2)
312 -1.000 => 1.00000000000 0 -1 1 0 .00000000000 (-2 + 0) * 2^(-1)
313 -1.500 => 1.10000000000 0 0 1 0 .10000000000 (-2 + 0.5) * 2^(0)
314 -1.999 => 1.11111111111 0 0 1 0 .00000000001 (-2 + 0.11) * 2^(0)
315 -2.000 => 1.00000000000 1 1 1 0 .00000000000 (-2 + 0) * 2^(0)
316 -4.000 => 1.00000000000 2 1 1 0 .00000000000 (-2 + 0) * 2^(1)
318 where e is the exponent, s is the sign bit, i is the implied bit,
319 and f is the fraction stored in the mantissa field.
321 num = (1 + f) * 2^x = m * 2^e if s = 0
322 num = (-2 + f) * 2^x = -m * 2^e if s = 1
323 where 0 <= f < 1.0 and 1.0 <= m < 2.0
325 The fraction (f) and exponent (e) fields for the TMS320C3X format
326 can be derived from the normalised mantissa (m) and exponent (x) using:
328 f = m - 1, e = x if s = 0
329 f = 2 - m, e = x if s = 1 and m != 1.0
330 f = 0, e = x - 1 if s = 1 and m = 1.0
331 f = 0, e = -8 if m = 0
334 OK, the other issue we have to consider is rounding since the
335 mantissa has a much higher potential precision than what we can
336 represent. To do this we add half the smallest storable fraction.
337 We then have to renormalise the number to allow for overflow.
339 To convert a generic flonum into a TMS320C3X floating point
340 number, here's what we try to do....
342 The first thing is to generate a normalised mantissa (m) where
343 1.0 <= m < 2 and to convert the exponent from base 16 to base 2.
344 We desire the binary point to be placed after the most significant
345 non zero bit. This process is done in two steps: firstly, the
346 littlenum with the most significant non zero bit is located (this
347 is done for us since leader points to this littlenum) and the
348 binary point (which is currently after the LSB of the littlenum
349 pointed to by low) is moved to before the MSB of the littlenum
350 pointed to by leader. This requires the exponent to be adjusted
351 by leader - low + 1. In the earlier example, the new exponent is
352 thus -4 + (5 - 2 + 1) = 0 (base 65536). We now need to convert
353 the exponent to base 2 by multiplying the exponent by 16 (log2
354 65536). The exponent base 2 is thus also zero.
356 The second step is to hunt for the most significant non zero bit
357 in the leader littlenum. We do this by left shifting a copy of
358 the leader littlenum until bit 16 is set (0x10000) and counting
359 the number of shifts, S, required. The number of shifts then has to
360 be added to correct the exponent (base 2). For our example, this
361 will require 9 shifts and thus our normalised exponent (base 2) is
362 0 + 9 = 9. Note that the worst case scenario is when the leader
363 littlenum is 1, thus requiring 16 shifts.
365 We now have to left shift the other littlenums by the same amount,
366 propagating the shifted bits into the more significant littlenums.
367 To save a lot of unnecessary shifting we only have to consider
368 two or three littlenums, since the greatest number of mantissa
369 bits required is 24 + 1 rounding bit. While two littlenums
370 provide 32 bits of precision, the most significant littlenum
371 may only contain a single significant bit and thus an extra
372 littlenum is required.
374 Denoting the number of bits in the fraction field as F, we require
375 G = F + 2 bits (one extra bit is for rounding, the other gets
376 suppressed). Say we required S shifts to find the most
377 significant bit in the leader littlenum, the number of left shifts
378 required to move this bit into bit position G - 1 is L = G + S - 17.
379 Note that this shift count may be negative for the short floating
380 point flavour (where F = 11 and thus G = 13 and potentially S < 3).
381 If L > 0 we have to shunt the next littlenum into position. Bit
382 15 (the MSB) of the next littlenum needs to get moved into position
383 L - 1 (If L > 15 we need all the bits of this littlenum and
384 some more from the next one.). We subtract 16 from L and use this
385 as the left shift count; the resultant value we or with the
386 previous result. If L > 0, we repeat this operation. */
388 if (precision
!= S_PRECISION
)
390 if (precision
== E_PRECISION
)
391 words
[2] = words
[3] = 0x0000;
393 /* 0.0e0 or NaN seen. */
394 if (flonum
.low
> flonum
.leader
/* = 0.0e0 */
395 || flonum
.sign
== 0) /* = NaN */
398 as_bad (_("Nan, using zero."));
403 if (flonum
.sign
== 'P')
405 /* +INF: Replace with maximum float. */
406 if (precision
== S_PRECISION
)
413 if (precision
== E_PRECISION
)
420 else if (flonum
.sign
== 'N')
422 /* -INF: Replace with maximum float. */
423 if (precision
== S_PRECISION
)
427 if (precision
== E_PRECISION
)
432 exponent
= (flonum
.exponent
+ flonum
.leader
- flonum
.low
+ 1) * 16;
434 if (!(tmp
= *flonum
.leader
))
435 abort (); /* Hmmm. */
436 shift
= 0; /* Find position of first sig. bit. */
439 exponent
-= (16 - shift
); /* Adjust exponent. */
441 if (precision
== S_PRECISION
) /* Allow 1 rounding bit. */
446 else if(precision
== F_PRECISION
)
451 else /* E_PRECISION */
457 shift
= mantissa_bits
- shift
;
462 /* Store the mantissa data into smant and the roundbit into rbit */
463 for (p
= flonum
.leader
; p
>= flonum
.low
&& shift
> -16; p
--)
465 tmp
= shift
>= 0 ? *p
<< shift
: *p
>> -shift
;
466 rbit
= shift
< 0 ? ((*p
>> (-shift
-1)) & 0x1) : 0;
471 /* OK, we've got our scaled mantissa so let's round it up */
474 /* If the mantissa is going to overflow when added, lets store
475 the extra bit in mover. -- A special case exists when
476 mantissa_bits is 31 (E_PRECISION). Then the first test cannot
477 be trusted, as result is host-dependent, thus the second
479 if( smant
== ((unsigned)(1<<(mantissa_bits
+1))-1)
480 || smant
== (unsigned)-1 ) /* This is to catch E_PRECISION cases */
485 /* Get the scaled one value */
486 sone
= (1 << (mantissa_bits
));
488 /* The number may be unnormalised so renormalise it... */
492 smant
|= sone
; /* Insert the bit from mover into smant */
496 /* The binary point is now between bit positions 11 and 10 or 23 and 22,
497 i.e., between mantissa_bits - 1 and mantissa_bits - 2 and the
498 bit at mantissa_bits - 1 should be set. */
500 abort (); /* Ooops. */
502 if (flonum
.sign
== '+')
503 sfract
= smant
- sone
; /* smant - 1.0. */
506 /* This seems to work. */
514 sfract
= -smant
& (sone
-1); /* 2.0 - smant. */
516 sfract
|= sone
; /* Insert sign bit. */
519 if (abs (exponent
) >= (1 << (exponent_bits
- 1)))
520 as_bad (_("Cannot represent exponent in %d bits"), exponent_bits
);
522 /* Force exponent to fit in desired field width. */
523 exponent
&= (1 << (exponent_bits
)) - 1;
525 if (precision
== E_PRECISION
)
527 /* Map the float part first (100% equal format as F_PRECISION) */
528 words
[0] = exponent
<< (mantissa_bits
+1-24);
529 words
[0] |= sfract
>> 24;
530 words
[1] = sfract
>> 8;
532 /* Map the mantissa in the next */
533 words
[2] = sfract
>> 16;
534 words
[3] = sfract
& 0xffff;
538 /* Insert the exponent data into the word */
539 sfract
|= exponent
<< (mantissa_bits
+1);
541 if (precision
== S_PRECISION
)
545 words
[0] = sfract
>> 16;
546 words
[1] = sfract
& 0xffff;
553 /* Returns pointer past text consumed. */
555 tic4x_atof (char *str
, char what_kind
, LITTLENUM_TYPE
*words
)
557 /* Extra bits for zeroed low-order bits. The 1st MAX_PRECISION are
558 zeroed, the last contain flonum bits. */
559 static LITTLENUM_TYPE bits
[MAX_PRECISION
+ MAX_PRECISION
+ GUARD
];
561 /* Number of 16-bit words in the format. */
563 FLONUM_TYPE save_gen_flonum
;
565 /* We have to save the generic_floating_point_number because it
566 contains storage allocation about the array of LITTLENUMs where
567 the value is actually stored. We will allocate our own array of
568 littlenums below, but have to restore the global one on exit. */
569 save_gen_flonum
= generic_floating_point_number
;
572 generic_floating_point_number
.low
= bits
+ MAX_PRECISION
;
573 generic_floating_point_number
.high
= NULL
;
574 generic_floating_point_number
.leader
= NULL
;
575 generic_floating_point_number
.exponent
= 0;
576 generic_floating_point_number
.sign
= '\0';
578 /* Use more LittleNums than seems necessary: the highest flonum may
579 have 15 leading 0 bits, so could be useless. */
581 memset (bits
, '\0', sizeof (LITTLENUM_TYPE
) * MAX_PRECISION
);
587 precision
= S_PRECISION
;
594 precision
= F_PRECISION
;
599 precision
= E_PRECISION
;
603 as_bad (_("Invalid floating point number"));
607 generic_floating_point_number
.high
608 = generic_floating_point_number
.low
+ precision
- 1 + GUARD
;
610 if (atof_generic (&return_value
, ".", EXP_CHARS
,
611 &generic_floating_point_number
))
613 as_bad (_("Invalid floating point number"));
617 tic4x_gen_to_words (generic_floating_point_number
,
620 /* Restore the generic_floating_point_number's storage alloc (and
622 generic_floating_point_number
= save_gen_flonum
;
628 tic4x_insert_reg (char *regname
, int regnum
)
633 symbol_table_insert (symbol_new (regname
, reg_section
, (valueT
) regnum
,
634 &zero_address_frag
));
635 for (i
= 0; regname
[i
]; i
++)
636 buf
[i
] = ISLOWER (regname
[i
]) ? TOUPPER (regname
[i
]) : regname
[i
];
639 symbol_table_insert (symbol_new (buf
, reg_section
, (valueT
) regnum
,
640 &zero_address_frag
));
644 tic4x_insert_sym (char *symname
, int value
)
648 symbolP
= symbol_new (symname
, absolute_section
,
649 (valueT
) value
, &zero_address_frag
);
650 SF_SET_LOCAL (symbolP
);
651 symbol_table_insert (symbolP
);
655 tic4x_expression (char *str
, expressionS
*exp
)
660 t
= input_line_pointer
; /* Save line pointer. */
661 input_line_pointer
= str
;
663 s
= input_line_pointer
;
664 input_line_pointer
= t
; /* Restore line pointer. */
665 return s
; /* Return pointer to where parsing stopped. */
669 tic4x_expression_abs (char *str
, offsetT
*value
)
674 t
= input_line_pointer
; /* Save line pointer. */
675 input_line_pointer
= str
;
676 *value
= get_absolute_expression ();
677 s
= input_line_pointer
;
678 input_line_pointer
= t
; /* Restore line pointer. */
683 tic4x_emit_char (char c
, int b
)
687 exp
.X_op
= O_constant
;
688 exp
.X_add_number
= c
;
693 tic4x_seg_alloc (char *name ATTRIBUTE_UNUSED
,
694 segT seg ATTRIBUTE_UNUSED
,
698 /* Note that the size is in words
699 so we multiply it by 4 to get the number of bytes to allocate. */
701 /* If we have symbol: .usect ".fred", size etc.,
702 the symbol needs to point to the first location reserved
709 p
= frag_var (rs_fill
, 1, 1, (relax_substateT
) 0,
711 size
* OCTETS_PER_BYTE
, (char *) 0);
716 /* .asg ["]character-string["], symbol */
718 tic4x_asg (int x ATTRIBUTE_UNUSED
)
726 str
= input_line_pointer
;
728 /* Skip string expression. */
729 while (*input_line_pointer
!= ',' && *input_line_pointer
)
730 input_line_pointer
++;
731 if (*input_line_pointer
!= ',')
733 as_bad (_("Comma expected\n"));
736 *input_line_pointer
++ = '\0';
737 name
= input_line_pointer
;
738 c
= get_symbol_end (); /* Get terminator. */
739 tmp
= xmalloc (strlen (str
) + 1);
742 tmp
= xmalloc (strlen (name
) + 1);
745 if (hash_find (tic4x_asg_hash
, name
))
746 hash_replace (tic4x_asg_hash
, name
, (void *) str
);
748 hash_insert (tic4x_asg_hash
, name
, (void *) str
);
749 *input_line_pointer
= c
;
750 demand_empty_rest_of_line ();
753 /* .bss symbol, size */
755 tic4x_bss (int x ATTRIBUTE_UNUSED
)
762 subsegT current_subseg
;
765 current_seg
= now_seg
; /* Save current seg. */
766 current_subseg
= now_subseg
; /* Save current subseg. */
769 name
= input_line_pointer
;
770 c
= get_symbol_end (); /* Get terminator. */
773 as_bad (_(".bss size argument missing\n"));
778 tic4x_expression_abs (++input_line_pointer
, &size
);
781 as_bad (_(".bss size %ld < 0!"), (long) size
);
784 subseg_set (bss_section
, 0);
785 symbolP
= symbol_find_or_make (name
);
787 if (S_GET_SEGMENT (symbolP
) == bss_section
)
788 symbol_get_frag (symbolP
)->fr_symbol
= 0;
790 symbol_set_frag (symbolP
, frag_now
);
792 p
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
,
793 size
* OCTETS_PER_BYTE
, (char *) 0);
794 *p
= 0; /* Fill char. */
796 S_SET_SEGMENT (symbolP
, bss_section
);
798 /* The symbol may already have been created with a preceding
799 ".globl" directive -- be careful not to step on storage class
800 in that case. Otherwise, set it to static. */
801 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
802 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
804 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
805 demand_empty_rest_of_line ();
809 tic4x_globl (int ignore ATTRIBUTE_UNUSED
)
817 name
= input_line_pointer
;
818 c
= get_symbol_end ();
819 symbolP
= symbol_find_or_make (name
);
820 *input_line_pointer
= c
;
822 S_SET_STORAGE_CLASS (symbolP
, C_EXT
);
823 S_SET_EXTERNAL (symbolP
);
826 input_line_pointer
++;
828 if (*input_line_pointer
== '\n')
834 demand_empty_rest_of_line ();
837 /* Handle .byte, .word. .int, .long */
839 tic4x_cons (int bytes
)
841 register unsigned int c
;
845 if (*input_line_pointer
== '"')
847 input_line_pointer
++;
848 while (is_a_char (c
= next_char_of_string ()))
849 tic4x_emit_char (c
, 4);
850 know (input_line_pointer
[-1] == '\"');
856 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
857 if (exp
.X_op
== O_constant
)
862 exp
.X_add_number
&= 255;
865 exp
.X_add_number
&= 65535;
869 /* Perhaps we should disallow .byte and .hword with
870 a non constant expression that will require relocation. */
874 while (*input_line_pointer
++ == ',');
876 input_line_pointer
--; /* Put terminator back into stream. */
877 demand_empty_rest_of_line ();
880 /* Handle .ascii, .asciz, .string */
882 tic4x_stringer (int append_zero
)
885 register unsigned int c
;
891 if (*input_line_pointer
== '"')
893 input_line_pointer
++;
894 while (is_a_char (c
= next_char_of_string ()))
896 tic4x_emit_char (c
, 1);
902 tic4x_emit_char (c
, 1);
906 know (input_line_pointer
[-1] == '\"');
912 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
913 if (exp
.X_op
!= O_constant
)
915 as_bad (_("Non-constant symbols not allowed\n"));
918 exp
.X_add_number
&= 255; /* Limit numeber to 8-bit */
923 while (*input_line_pointer
++ == ',');
925 /* Fill out the rest of the expression with 0's to fill up a full word */
927 tic4x_emit_char (0, 4-(bytes
&0x3));
929 input_line_pointer
--; /* Put terminator back into stream. */
930 demand_empty_rest_of_line ();
933 /* .eval expression, symbol */
935 tic4x_eval (int x ATTRIBUTE_UNUSED
)
943 tic4x_expression_abs (input_line_pointer
, &value
);
944 if (*input_line_pointer
++ != ',')
946 as_bad (_("Symbol missing\n"));
949 name
= input_line_pointer
;
950 c
= get_symbol_end (); /* Get terminator. */
951 tic4x_insert_sym (name
, value
);
952 *input_line_pointer
++ = c
;
953 demand_empty_rest_of_line ();
956 /* Reset local labels. */
958 tic4x_newblock (int x ATTRIBUTE_UNUSED
)
960 dollar_label_clear ();
963 /* .sect "section-name" [, value] */
964 /* .sect ["]section-name[:subsection-name]["] [, value] */
966 tic4x_sect (int x ATTRIBUTE_UNUSED
)
975 if (*input_line_pointer
== '"')
976 input_line_pointer
++;
977 section_name
= input_line_pointer
;
978 c
= get_symbol_end (); /* Get terminator. */
979 input_line_pointer
++; /* Skip null symbol terminator. */
980 name
= xmalloc (input_line_pointer
- section_name
+ 1);
981 strcpy (name
, section_name
);
983 /* TI C from version 5.0 allows a section name to contain a
984 subsection name as well. The subsection name is separated by a
985 ':' from the section name. Currently we scan the subsection
987 Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>. */
990 c
= get_symbol_end (); /* Get terminator. */
991 input_line_pointer
++; /* Skip null symbol terminator. */
992 as_warn (_(".sect: subsection name ignored"));
995 /* We might still have a '"' to discard, but the character after a
996 symbol name will be overwritten with a \0 by get_symbol_end()
1000 input_line_pointer
=
1001 tic4x_expression_abs (input_line_pointer
, &num
);
1002 else if (*input_line_pointer
== ',')
1004 input_line_pointer
=
1005 tic4x_expression_abs (++input_line_pointer
, &num
);
1010 seg
= subseg_new (name
, num
);
1011 if (line_label
!= NULL
)
1013 S_SET_SEGMENT (line_label
, seg
);
1014 symbol_set_frag (line_label
, frag_now
);
1017 if (bfd_get_section_flags (stdoutput
, seg
) == SEC_NO_FLAGS
)
1019 if (!bfd_set_section_flags (stdoutput
, seg
, SEC_DATA
))
1020 as_warn (_("Error setting flags for \"%s\": %s"), name
,
1021 bfd_errmsg (bfd_get_error ()));
1024 /* If the last character overwritten by get_symbol_end() was an
1025 end-of-line, we must restore it or the end of the line will not be
1026 recognised and scanning extends into the next line, stopping with
1027 an error (blame Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>
1028 if this is not true). */
1029 if (is_end_of_line
[(unsigned char) c
])
1030 *(--input_line_pointer
) = c
;
1032 demand_empty_rest_of_line ();
1035 /* symbol[:] .set value or .set symbol, value */
1037 tic4x_set (int x ATTRIBUTE_UNUSED
)
1042 if ((symbolP
= line_label
) == NULL
)
1047 name
= input_line_pointer
;
1048 c
= get_symbol_end (); /* Get terminator. */
1051 as_bad (_(".set syntax invalid\n"));
1052 ignore_rest_of_line ();
1055 ++input_line_pointer
;
1056 symbolP
= symbol_find_or_make (name
);
1059 symbol_table_insert (symbolP
);
1061 pseudo_set (symbolP
);
1062 demand_empty_rest_of_line ();
1065 /* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
1067 tic4x_usect (int x ATTRIBUTE_UNUSED
)
1073 offsetT size
, alignment_flag
;
1075 subsegT current_subseg
;
1077 current_seg
= now_seg
; /* save current seg. */
1078 current_subseg
= now_subseg
; /* save current subseg. */
1081 if (*input_line_pointer
== '"')
1082 input_line_pointer
++;
1083 section_name
= input_line_pointer
;
1084 c
= get_symbol_end (); /* Get terminator. */
1085 input_line_pointer
++; /* Skip null symbol terminator. */
1086 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1087 strcpy (name
, section_name
);
1090 input_line_pointer
=
1091 tic4x_expression_abs (input_line_pointer
, &size
);
1092 else if (*input_line_pointer
== ',')
1094 input_line_pointer
=
1095 tic4x_expression_abs (++input_line_pointer
, &size
);
1100 /* Read a possibly present third argument (alignment flag) [VK]. */
1101 if (*input_line_pointer
== ',')
1103 input_line_pointer
=
1104 tic4x_expression_abs (++input_line_pointer
, &alignment_flag
);
1109 as_warn (_(".usect: non-zero alignment flag ignored"));
1111 seg
= subseg_new (name
, 0);
1112 if (line_label
!= NULL
)
1114 S_SET_SEGMENT (line_label
, seg
);
1115 symbol_set_frag (line_label
, frag_now
);
1116 S_SET_VALUE (line_label
, frag_now_fix ());
1118 seg_info (seg
)->bss
= 1; /* Uninitialised data. */
1119 if (!bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
))
1120 as_warn (_("Error setting flags for \"%s\": %s"), name
,
1121 bfd_errmsg (bfd_get_error ()));
1122 tic4x_seg_alloc (name
, seg
, size
, line_label
);
1124 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1125 S_SET_STORAGE_CLASS (line_label
, C_STAT
);
1127 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
1128 demand_empty_rest_of_line ();
1131 /* .version cpu-version. */
1133 tic4x_version (int x ATTRIBUTE_UNUSED
)
1137 input_line_pointer
=
1138 tic4x_expression_abs (input_line_pointer
, &temp
);
1139 if (!IS_CPU_TIC3X (temp
) && !IS_CPU_TIC4X (temp
))
1140 as_bad (_("This assembler does not support processor generation %ld"),
1143 if (tic4x_cpu
&& temp
!= (offsetT
) tic4x_cpu
)
1144 as_warn (_("Changing processor generation on fly not supported..."));
1146 demand_empty_rest_of_line ();
1150 tic4x_init_regtable (void)
1154 for (i
= 0; i
< tic3x_num_registers
; i
++)
1155 tic4x_insert_reg (tic3x_registers
[i
].name
,
1156 tic3x_registers
[i
].regno
);
1158 if (IS_CPU_TIC4X (tic4x_cpu
))
1160 /* Add additional Tic4x registers, overriding some C3x ones. */
1161 for (i
= 0; i
< tic4x_num_registers
; i
++)
1162 tic4x_insert_reg (tic4x_registers
[i
].name
,
1163 tic4x_registers
[i
].regno
);
1168 tic4x_init_symbols (void)
1170 /* The TI tools accept case insensitive versions of these symbols,
1175 .TMS320xx 30,31,32,40,or 44 set according to -v flag
1176 .C3X or .C3x 1 or 0 1 if -v30,-v31,or -v32
1177 .C30 1 or 0 1 if -v30
1178 .C31 1 or 0 1 if -v31
1179 .C32 1 or 0 1 if -v32
1180 .C4X or .C4x 1 or 0 1 if -v40, or -v44
1181 .C40 1 or 0 1 if -v40
1182 .C44 1 or 0 1 if -v44
1184 .REGPARM 1 or 0 1 if -mr option used
1185 .BIGMODEL 1 or 0 1 if -mb option used
1187 These symbols are currently supported but will be removed in a
1189 .TMS320C30 1 or 0 1 if -v30,-v31,or -v32
1190 .TMS320C31 1 or 0 1 if -v31
1191 .TMS320C32 1 or 0 1 if -v32
1192 .TMS320C40 1 or 0 1 if -v40, or -v44
1193 .TMS320C44 1 or 0 1 if -v44
1195 Source: TI: TMS320C3x/C4x Assembly Language Tools User's Guide,
1196 1997, SPRU035C, p. 3-17/3-18. */
1197 tic4x_insert_sym (".REGPARM", tic4x_reg_args
);
1198 tic4x_insert_sym (".MEMPARM", !tic4x_reg_args
);
1199 tic4x_insert_sym (".BIGMODEL", tic4x_big_model
);
1200 tic4x_insert_sym (".C30INTERRUPT", 0);
1201 tic4x_insert_sym (".TMS320xx", tic4x_cpu
== 0 ? 40 : tic4x_cpu
);
1202 tic4x_insert_sym (".C3X", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1203 tic4x_insert_sym (".C3x", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1204 tic4x_insert_sym (".C4X", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1205 tic4x_insert_sym (".C4x", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1206 /* Do we need to have the following symbols also in lower case? */
1207 tic4x_insert_sym (".TMS320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1208 tic4x_insert_sym (".tms320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1209 tic4x_insert_sym (".TMS320C31", tic4x_cpu
== 31);
1210 tic4x_insert_sym (".tms320C31", tic4x_cpu
== 31);
1211 tic4x_insert_sym (".TMS320C32", tic4x_cpu
== 32);
1212 tic4x_insert_sym (".tms320C32", tic4x_cpu
== 32);
1213 tic4x_insert_sym (".TMS320C33", tic4x_cpu
== 33);
1214 tic4x_insert_sym (".tms320C33", tic4x_cpu
== 33);
1215 tic4x_insert_sym (".TMS320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1216 tic4x_insert_sym (".tms320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1217 tic4x_insert_sym (".TMS320C44", tic4x_cpu
== 44);
1218 tic4x_insert_sym (".tms320C44", tic4x_cpu
== 44);
1219 tic4x_insert_sym (".TMX320C40", 0); /* C40 first pass silicon ? */
1220 tic4x_insert_sym (".tmx320C40", 0);
1223 /* Insert a new instruction template into hash table. */
1225 tic4x_inst_insert (const tic4x_inst_t
*inst
)
1227 static char prev_name
[16];
1228 const char *retval
= NULL
;
1230 /* Only insert the first name if have several similar entries. */
1231 if (!strcmp (inst
->name
, prev_name
) || inst
->name
[0] == '\0')
1234 retval
= hash_insert (tic4x_op_hash
, inst
->name
, (void *) inst
);
1236 fprintf (stderr
, "internal error: can't hash `%s': %s\n",
1237 inst
->name
, retval
);
1239 strcpy (prev_name
, inst
->name
);
1240 return retval
== NULL
;
1243 /* Make a new instruction template. */
1244 static tic4x_inst_t
*
1245 tic4x_inst_make (char *name
, unsigned long opcode
, char *args
)
1247 static tic4x_inst_t
*insts
= NULL
;
1248 static char *names
= NULL
;
1249 static int iindex
= 0;
1253 /* Allocate memory to store name strings. */
1254 names
= (char *) xmalloc (sizeof (char) * 8192);
1255 /* Allocate memory for additional insts. */
1256 insts
= (tic4x_inst_t
*)
1257 xmalloc (sizeof (tic4x_inst_t
) * 1024);
1259 insts
[iindex
].name
= names
;
1260 insts
[iindex
].opcode
= opcode
;
1261 insts
[iindex
].opmask
= 0xffffffff;
1262 insts
[iindex
].args
= args
;
1270 return &insts
[iindex
- 1];
1273 /* Add instruction template, creating dynamic templates as required. */
1275 tic4x_inst_add (const tic4x_inst_t
*insts
)
1277 char *s
= insts
->name
;
1285 /* We do not care about INSNs that is not a part of our
1287 if ((insts
->oplevel
& tic4x_oplevel
) == 0)
1296 /* Dynamically create all the conditional insts. */
1297 for (i
= 0; i
< tic4x_num_conds
; i
++)
1301 char *c
= tic4x_conds
[i
].name
;
1311 /* If instruction found then have already processed it. */
1312 if (hash_find (tic4x_op_hash
, name
))
1317 inst
= tic4x_inst_make (name
, insts
[k
].opcode
+
1318 (tic4x_conds
[i
].cond
<<
1319 (*s
== 'B' ? 16 : 23)),
1321 if (k
== 0) /* Save strcmp() with following func. */
1322 ok
&= tic4x_inst_insert (inst
);
1325 while (!strcmp (insts
->name
,
1332 return tic4x_inst_insert (insts
);
1342 /* This function is called once, at assembler startup time. It should
1343 set up all the tables, etc., that the MD part of the assembler will
1351 /* Setup the proper opcode level according to the
1352 commandline parameters */
1353 tic4x_oplevel
= OP_C3X
;
1355 if ( IS_CPU_TIC4X(tic4x_cpu
) )
1356 tic4x_oplevel
|= OP_C4X
;
1358 if ( ( tic4x_cpu
== 31 && tic4x_revision
>= 6)
1359 || (tic4x_cpu
== 32 && tic4x_revision
>= 2)
1360 || (tic4x_cpu
== 33)
1362 tic4x_oplevel
|= OP_ENH
;
1364 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1365 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1366 || (tic4x_cpu
== 32)
1368 tic4x_oplevel
|= OP_LPWR
;
1370 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1371 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1372 || (tic4x_cpu
== 32)
1373 || (tic4x_cpu
== 33)
1374 || (tic4x_cpu
== 40 && tic4x_revision
>= 5)
1375 || (tic4x_cpu
== 44)
1377 tic4x_oplevel
|= OP_IDLE2
;
1379 /* Create hash table for mnemonics. */
1380 tic4x_op_hash
= hash_new ();
1382 /* Create hash table for asg pseudo. */
1383 tic4x_asg_hash
= hash_new ();
1385 /* Add mnemonics to hash table, expanding conditional mnemonics on fly. */
1386 for (i
= 0; i
< tic4x_num_insts
; i
++)
1387 ok
&= tic4x_inst_add (tic4x_insts
+ i
);
1389 /* Create dummy inst to avoid errors accessing end of table. */
1390 tic4x_inst_make ("", 0, "");
1393 as_fatal ("Broken assembler. No assembly attempted.");
1395 /* Add registers to symbol table. */
1396 tic4x_init_regtable ();
1398 /* Add predefined symbols to symbol table. */
1399 tic4x_init_symbols ();
1405 bfd_set_arch_mach (stdoutput
, bfd_arch_tic4x
,
1406 IS_CPU_TIC4X (tic4x_cpu
) ? bfd_mach_tic4x
: bfd_mach_tic3x
);
1410 tic4x_indirect_parse (tic4x_operand_t
*operand
,
1411 const tic4x_indirect_t
*indirect
)
1413 char *n
= indirect
->name
;
1414 char *s
= input_line_pointer
;
1424 case 'a': /* Need to match aux register. */
1426 #ifdef TIC4X_ALT_SYNTAX
1430 while (ISALNUM (*s
))
1433 if (!(symbolP
= symbol_find (name
)))
1436 if (S_GET_SEGMENT (symbolP
) != reg_section
)
1439 operand
->aregno
= S_GET_VALUE (symbolP
);
1440 if (operand
->aregno
>= REG_AR0
&& operand
->aregno
<= REG_AR7
)
1443 as_bad (_("Auxiliary register AR0--AR7 required for indirect"));
1446 case 'd': /* Need to match constant for disp. */
1447 #ifdef TIC4X_ALT_SYNTAX
1448 if (*s
== '%') /* expr() will die if we don't skip this. */
1451 s
= tic4x_expression (s
, &operand
->expr
);
1452 if (operand
->expr
.X_op
!= O_constant
)
1454 operand
->disp
= operand
->expr
.X_add_number
;
1455 if (operand
->disp
< 0 || operand
->disp
> 255)
1457 as_bad (_("Bad displacement %d (require 0--255)\n"),
1463 case 'y': /* Need to match IR0. */
1464 case 'z': /* Need to match IR1. */
1465 #ifdef TIC4X_ALT_SYNTAX
1469 s
= tic4x_expression (s
, &operand
->expr
);
1470 if (operand
->expr
.X_op
!= O_register
)
1472 if (operand
->expr
.X_add_number
!= REG_IR0
1473 && operand
->expr
.X_add_number
!= REG_IR1
)
1475 as_bad (_("Index register IR0,IR1 required for displacement"));
1479 if (*n
== 'y' && operand
->expr
.X_add_number
== REG_IR0
)
1481 if (*n
== 'z' && operand
->expr
.X_add_number
== REG_IR1
)
1486 if (*s
!= '(') /* No displacement, assume to be 1. */
1497 if (TOLOWER (*s
) != *n
)
1502 if (*s
!= ' ' && *s
!= ',' && *s
!= '\0')
1504 input_line_pointer
= s
;
1509 tic4x_operand_parse (char *s
, tic4x_operand_t
*operand
)
1514 expressionS
*exp
= &operand
->expr
;
1515 char *save
= input_line_pointer
;
1518 struct hash_entry
*entry
= NULL
;
1520 input_line_pointer
= s
;
1523 str
= input_line_pointer
;
1524 c
= get_symbol_end (); /* Get terminator. */
1525 new_pointer
= input_line_pointer
;
1526 if (strlen (str
) && (entry
= hash_find (tic4x_asg_hash
, str
)) != NULL
)
1528 *input_line_pointer
= c
;
1529 input_line_pointer
= (char *) entry
;
1533 *input_line_pointer
= c
;
1534 input_line_pointer
= str
;
1537 operand
->mode
= M_UNKNOWN
;
1538 switch (*input_line_pointer
)
1540 #ifdef TIC4X_ALT_SYNTAX
1542 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1543 if (exp
->X_op
!= O_register
)
1544 as_bad (_("Expecting a register name"));
1545 operand
->mode
= M_REGISTER
;
1549 /* Denotes high 16 bits. */
1550 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1551 if (exp
->X_op
== O_constant
)
1552 operand
->mode
= M_IMMED
;
1553 else if (exp
->X_op
== O_big
)
1555 if (exp
->X_add_number
)
1556 as_bad (_("Number too large")); /* bignum required */
1559 tic4x_gen_to_words (generic_floating_point_number
,
1560 operand
->fwords
, S_PRECISION
);
1561 operand
->mode
= M_IMMED_F
;
1564 /* Allow ori ^foo, ar0 to be equivalent to ldi .hi.foo, ar0 */
1565 /* WARNING : The TI C40 assembler cannot do this. */
1566 else if (exp
->X_op
== O_symbol
)
1568 operand
->mode
= M_HI
;
1573 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1574 if (exp
->X_op
== O_constant
)
1575 operand
->mode
= M_IMMED
;
1576 else if (exp
->X_op
== O_big
)
1578 if (exp
->X_add_number
> 0)
1579 as_bad (_("Number too large")); /* bignum required. */
1582 tic4x_gen_to_words (generic_floating_point_number
,
1583 operand
->fwords
, S_PRECISION
);
1584 operand
->mode
= M_IMMED_F
;
1587 /* Allow ori foo, ar0 to be equivalent to ldi .lo.foo, ar0 */
1588 /* WARNING : The TI C40 assembler cannot do this. */
1589 else if (exp
->X_op
== O_symbol
)
1591 operand
->mode
= M_IMMED
;
1596 as_bad (_("Expecting a constant value"));
1601 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1602 if (exp
->X_op
!= O_constant
&& exp
->X_op
!= O_symbol
)
1603 as_bad (_("Bad direct addressing construct %s"), s
);
1604 if (exp
->X_op
== O_constant
)
1606 if (exp
->X_add_number
< 0)
1607 as_bad (_("Direct value of %ld is not suitable"),
1608 (long) exp
->X_add_number
);
1610 operand
->mode
= M_DIRECT
;
1615 for (i
= 0; i
< tic4x_num_indirects
; i
++)
1616 if ((ret
= tic4x_indirect_parse (operand
, &tic4x_indirects
[i
])))
1620 if (i
< tic4x_num_indirects
)
1622 operand
->mode
= M_INDIRECT
;
1623 /* Indirect addressing mode number. */
1624 operand
->expr
.X_add_number
= tic4x_indirects
[i
].modn
;
1625 /* Convert *+ARn(0) to *ARn etc. Maybe we should
1626 squeal about silly ones? */
1627 if (operand
->expr
.X_add_number
< 0x08 && !operand
->disp
)
1628 operand
->expr
.X_add_number
= 0x18;
1631 as_bad (_("Unknown indirect addressing mode"));
1635 operand
->mode
= M_IMMED
; /* Assume immediate. */
1636 str
= input_line_pointer
;
1637 input_line_pointer
= tic4x_expression (input_line_pointer
, exp
);
1638 if (exp
->X_op
== O_register
)
1640 know (exp
->X_add_symbol
== 0);
1641 know (exp
->X_op_symbol
== 0);
1642 operand
->mode
= M_REGISTER
;
1645 else if (exp
->X_op
== O_big
)
1647 if (exp
->X_add_number
> 0)
1648 as_bad (_("Number too large")); /* bignum required. */
1651 tic4x_gen_to_words (generic_floating_point_number
,
1652 operand
->fwords
, S_PRECISION
);
1653 operand
->mode
= M_IMMED_F
;
1657 #ifdef TIC4X_ALT_SYNTAX
1658 /* Allow ldi foo, ar0 to be equivalent to ldi @foo, ar0. */
1659 else if (exp
->X_op
== O_symbol
)
1661 operand
->mode
= M_DIRECT
;
1667 new_pointer
= input_line_pointer
;
1668 input_line_pointer
= save
;
1673 tic4x_operands_match (tic4x_inst_t
*inst
, tic4x_insn_t
*tinsn
, int check
)
1675 const char *args
= inst
->args
;
1676 unsigned long opcode
= inst
->opcode
;
1677 int num_operands
= tinsn
->num_operands
;
1678 tic4x_operand_t
*operand
= tinsn
->operands
;
1679 expressionS
*exp
= &operand
->expr
;
1683 /* Build the opcode, checking as we go to make sure that the
1686 If an operand matches, we modify insn or opcode appropriately,
1687 and do a "continue". If an operand fails to match, we "break". */
1689 tinsn
->nchars
= 4; /* Instructions always 4 bytes. */
1690 tinsn
->reloc
= NO_RELOC
;
1695 tinsn
->opcode
= opcode
;
1696 return num_operands
== 0;
1704 case '\0': /* End of args. */
1705 if (num_operands
== 1)
1707 tinsn
->opcode
= opcode
;
1710 break; /* Too many operands. */
1712 case '#': /* This is only used for ldp. */
1713 if (operand
->mode
!= M_DIRECT
&& operand
->mode
!= M_IMMED
)
1715 /* While this looks like a direct addressing mode, we actually
1716 use an immediate mode form of ldiu or ldpk instruction. */
1717 if (exp
->X_op
== O_constant
)
1719 if( ( IS_CPU_TIC4X (tic4x_cpu
) && exp
->X_add_number
<= 65535 )
1720 || ( IS_CPU_TIC3X (tic4x_cpu
) && exp
->X_add_number
<= 255 ) )
1722 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1728 as_bad (_("Immediate value of %ld is too large for ldf"),
1729 (long) exp
->X_add_number
);
1734 else if (exp
->X_op
== O_symbol
)
1736 tinsn
->reloc
= BFD_RELOC_HI16
;
1740 break; /* Not direct (dp) addressing. */
1742 case '@': /* direct. */
1743 if (operand
->mode
!= M_DIRECT
)
1745 if (exp
->X_op
== O_constant
)
1747 /* Store only the 16 LSBs of the number. */
1748 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1751 else if (exp
->X_op
== O_symbol
)
1753 tinsn
->reloc
= BFD_RELOC_LO16
;
1757 break; /* Not direct addressing. */
1760 if (operand
->mode
!= M_REGISTER
)
1762 reg
= exp
->X_add_number
;
1763 if (reg
>= REG_AR0
&& reg
<= REG_AR7
)
1764 INSERTU (opcode
, reg
- REG_AR0
, 24, 22);
1768 as_bad (_("Destination register must be ARn"));
1773 case 'B': /* Unsigned integer immediate. */
1774 /* Allow br label or br @label. */
1775 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
1777 if (exp
->X_op
== O_constant
)
1779 if (exp
->X_add_number
< (1 << 24))
1781 INSERTU (opcode
, exp
->X_add_number
, 23, 0);
1787 as_bad (_("Immediate value of %ld is too large"),
1788 (long) exp
->X_add_number
);
1793 if (IS_CPU_TIC4X (tic4x_cpu
))
1795 tinsn
->reloc
= BFD_RELOC_24_PCREL
;
1800 tinsn
->reloc
= BFD_RELOC_24
;
1807 if (!IS_CPU_TIC4X (tic4x_cpu
))
1809 if (operand
->mode
!= M_INDIRECT
)
1811 /* Require either *+ARn(disp) or *ARn. */
1812 if (operand
->expr
.X_add_number
!= 0
1813 && operand
->expr
.X_add_number
!= 0x18)
1816 as_bad (_("Invalid indirect addressing mode"));
1820 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1821 INSERTU (opcode
, operand
->disp
, 7, 3);
1825 if (!(operand
->mode
== M_REGISTER
))
1827 INSERTU (opcode
, exp
->X_add_number
, 7, 0);
1831 if (!(operand
->mode
== M_REGISTER
))
1833 reg
= exp
->X_add_number
;
1834 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1835 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1836 INSERTU (opcode
, reg
, 7, 0);
1840 as_bad (_("Register must be Rn"));
1846 if (operand
->mode
!= M_IMMED_F
1847 && !(operand
->mode
== M_IMMED
&& exp
->X_op
== O_constant
))
1850 if (operand
->mode
!= M_IMMED_F
)
1852 /* OK, we 've got something like cmpf 0, r0
1853 Why can't they stick in a bloody decimal point ?! */
1856 /* Create floating point number string. */
1857 sprintf (string
, "%d.0", (int) exp
->X_add_number
);
1858 tic4x_atof (string
, 's', operand
->fwords
);
1861 INSERTU (opcode
, operand
->fwords
[0], 15, 0);
1865 if (operand
->mode
!= M_REGISTER
)
1867 INSERTU (opcode
, exp
->X_add_number
, 15, 8);
1871 if (operand
->mode
!= M_REGISTER
)
1873 reg
= exp
->X_add_number
;
1874 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1875 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1876 INSERTU (opcode
, reg
, 15, 8);
1880 as_bad (_("Register must be Rn"));
1886 if (operand
->mode
!= M_REGISTER
)
1888 reg
= exp
->X_add_number
;
1889 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1890 INSERTU (opcode
, reg
- REG_R0
, 18, 16);
1894 as_bad (_("Register must be R0--R7"));
1900 if ( operand
->mode
== M_REGISTER
1901 && tic4x_oplevel
& OP_ENH
)
1903 reg
= exp
->X_add_number
;
1904 INSERTU (opcode
, reg
, 4, 0);
1905 INSERTU (opcode
, 7, 7, 5);
1911 if (operand
->mode
!= M_INDIRECT
)
1913 if (operand
->disp
!= 0 && operand
->disp
!= 1)
1915 if (IS_CPU_TIC4X (tic4x_cpu
))
1918 as_bad (_("Invalid indirect addressing mode displacement %d"),
1923 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1924 INSERTU (opcode
, operand
->expr
.X_add_number
, 7, 3);
1928 if ( operand
->mode
== M_REGISTER
1929 && tic4x_oplevel
& OP_ENH
)
1931 reg
= exp
->X_add_number
;
1932 INSERTU (opcode
, reg
, 12, 8);
1933 INSERTU (opcode
, 7, 15, 13);
1939 if (operand
->mode
!= M_INDIRECT
)
1941 if (operand
->disp
!= 0 && operand
->disp
!= 1)
1943 if (IS_CPU_TIC4X (tic4x_cpu
))
1946 as_bad (_("Invalid indirect addressing mode displacement %d"),
1951 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
1952 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
1956 if (operand
->mode
!= M_REGISTER
)
1958 reg
= exp
->X_add_number
;
1959 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1960 INSERTU (opcode
, reg
- REG_R0
, 21, 19);
1964 as_bad (_("Register must be R0--R7"));
1970 if (operand
->mode
!= M_REGISTER
)
1972 reg
= exp
->X_add_number
;
1973 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1974 INSERTU (opcode
, reg
- REG_R0
, 24, 22);
1978 as_bad (_("Register must be R0--R7"));
1984 if (operand
->mode
!= M_REGISTER
)
1986 reg
= exp
->X_add_number
;
1987 if (reg
== REG_R2
|| reg
== REG_R3
)
1988 INSERTU (opcode
, reg
- REG_R2
, 22, 22);
1992 as_bad (_("Destination register must be R2 or R3"));
1998 if (operand
->mode
!= M_REGISTER
)
2000 reg
= exp
->X_add_number
;
2001 if (reg
== REG_R0
|| reg
== REG_R1
)
2002 INSERTU (opcode
, reg
- REG_R0
, 23, 23);
2006 as_bad (_("Destination register must be R0 or R1"));
2012 if (!IS_CPU_TIC4X (tic4x_cpu
))
2014 if (operand
->mode
!= M_INDIRECT
)
2016 /* Require either *+ARn(disp) or *ARn. */
2017 if (operand
->expr
.X_add_number
!= 0
2018 && operand
->expr
.X_add_number
!= 0x18)
2021 as_bad (_("Invalid indirect addressing mode"));
2025 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2026 INSERTU (opcode
, operand
->disp
, 15, 11);
2029 case 'P': /* PC relative displacement. */
2030 /* Allow br label or br @label. */
2031 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
2033 if (exp
->X_op
== O_constant
)
2035 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 32767)
2037 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2043 as_bad (_("Displacement value of %ld is too large"),
2044 (long) exp
->X_add_number
);
2049 tinsn
->reloc
= BFD_RELOC_16_PCREL
;
2055 if (operand
->mode
!= M_REGISTER
)
2057 reg
= exp
->X_add_number
;
2058 INSERTU (opcode
, reg
, 15, 0);
2062 if (operand
->mode
!= M_REGISTER
)
2064 reg
= exp
->X_add_number
;
2065 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2066 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2067 INSERTU (opcode
, reg
, 15, 0);
2071 as_bad (_("Register must be Rn"));
2077 if (operand
->mode
!= M_REGISTER
)
2079 reg
= exp
->X_add_number
;
2080 INSERTU (opcode
, reg
, 20, 16);
2084 if (operand
->mode
!= M_REGISTER
)
2086 reg
= exp
->X_add_number
;
2087 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2088 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2089 INSERTU (opcode
, reg
, 20, 16);
2093 as_bad (_("Register must be Rn"));
2098 case 'S': /* Short immediate int. */
2099 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2101 if (exp
->X_op
== O_big
)
2104 as_bad (_("Floating point number not valid in expression"));
2108 if (exp
->X_op
== O_constant
)
2110 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 65535)
2112 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2118 as_bad (_("Signed immediate value %ld too large"),
2119 (long) exp
->X_add_number
);
2124 else if (exp
->X_op
== O_symbol
)
2126 if (operand
->mode
== M_HI
)
2128 tinsn
->reloc
= BFD_RELOC_HI16
;
2132 tinsn
->reloc
= BFD_RELOC_LO16
;
2137 /* Handle cases like ldi foo - $, ar0 where foo
2138 is a forward reference. Perhaps we should check
2139 for X_op == O_symbol and disallow things like
2141 tinsn
->reloc
= BFD_RELOC_16
;
2145 case 'T': /* 5-bit immediate value for tic4x stik. */
2146 if (!IS_CPU_TIC4X (tic4x_cpu
))
2148 if (operand
->mode
!= M_IMMED
)
2150 if (exp
->X_op
== O_constant
)
2152 if (exp
->X_add_number
< 16 && exp
->X_add_number
>= -16)
2154 INSERTS (opcode
, exp
->X_add_number
, 20, 16);
2160 as_bad (_("Immediate value of %ld is too large"),
2161 (long) exp
->X_add_number
);
2166 break; /* No relocations allowed. */
2168 case 'U': /* Unsigned integer immediate. */
2169 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2171 if (exp
->X_op
== O_constant
)
2173 if (exp
->X_add_number
< (1 << 16) && exp
->X_add_number
>= 0)
2175 INSERTU (opcode
, exp
->X_add_number
, 15, 0);
2181 as_bad (_("Unsigned immediate value %ld too large"),
2182 (long) exp
->X_add_number
);
2187 else if (exp
->X_op
== O_symbol
)
2189 if (operand
->mode
== M_HI
)
2190 tinsn
->reloc
= BFD_RELOC_HI16
;
2192 tinsn
->reloc
= BFD_RELOC_LO16
;
2197 tinsn
->reloc
= BFD_RELOC_16
;
2201 case 'V': /* Trap numbers (immediate field). */
2202 if (operand
->mode
!= M_IMMED
)
2204 if (exp
->X_op
== O_constant
)
2206 if (exp
->X_add_number
< 512 && IS_CPU_TIC4X (tic4x_cpu
))
2208 INSERTU (opcode
, exp
->X_add_number
, 8, 0);
2211 else if (exp
->X_add_number
< 32 && IS_CPU_TIC3X (tic4x_cpu
))
2213 INSERTU (opcode
, exp
->X_add_number
| 0x20, 4, 0);
2219 as_bad (_("Immediate value of %ld is too large"),
2220 (long) exp
->X_add_number
);
2225 break; /* No relocations allowed. */
2227 case 'W': /* Short immediate int (0--7). */
2228 if (!IS_CPU_TIC4X (tic4x_cpu
))
2230 if (operand
->mode
!= M_IMMED
)
2232 if (exp
->X_op
== O_big
)
2235 as_bad (_("Floating point number not valid in expression"));
2239 if (exp
->X_op
== O_constant
)
2241 if (exp
->X_add_number
>= -256 && exp
->X_add_number
<= 127)
2243 INSERTS (opcode
, exp
->X_add_number
, 7, 0);
2249 as_bad (_("Immediate value %ld too large"),
2250 (long) exp
->X_add_number
);
2255 tinsn
->reloc
= BFD_RELOC_16
;
2259 case 'X': /* Expansion register for tic4x. */
2260 if (operand
->mode
!= M_REGISTER
)
2262 reg
= exp
->X_add_number
;
2263 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2264 INSERTU (opcode
, reg
- REG_IVTP
, 4, 0);
2268 as_bad (_("Register must be ivtp or tvtp"));
2273 case 'Y': /* Address register for tic4x lda. */
2274 if (operand
->mode
!= M_REGISTER
)
2276 reg
= exp
->X_add_number
;
2277 if (reg
>= REG_AR0
&& reg
<= REG_SP
)
2278 INSERTU (opcode
, reg
, 20, 16);
2282 as_bad (_("Register must be address register"));
2287 case 'Z': /* Expansion register for tic4x. */
2288 if (operand
->mode
!= M_REGISTER
)
2290 reg
= exp
->X_add_number
;
2291 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2292 INSERTU (opcode
, reg
- REG_IVTP
, 20, 16);
2296 as_bad (_("Register must be ivtp or tvtp"));
2302 if (operand
->mode
!= M_INDIRECT
)
2304 INSERTS (opcode
, operand
->disp
, 7, 0);
2305 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2306 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
2309 case '|': /* treat as `,' if have ldi_ldi form. */
2310 if (tinsn
->parallel
)
2312 if (--num_operands
< 0)
2313 break; /* Too few operands. */
2315 if (operand
->mode
!= M_PARALLEL
)
2320 case ',': /* Another operand. */
2321 if (--num_operands
< 0)
2322 break; /* Too few operands. */
2324 exp
= &operand
->expr
;
2327 case ';': /* Another optional operand. */
2328 if (num_operands
== 1 || operand
[1].mode
== M_PARALLEL
)
2330 if (--num_operands
< 0)
2331 break; /* Too few operands. */
2333 exp
= &operand
->expr
;
2344 tic4x_insn_check (tic4x_insn_t
*tinsn
)
2347 if (!strcmp (tinsn
->name
, "lda"))
2349 if (tinsn
->num_operands
< 2 || tinsn
->num_operands
> 2)
2350 as_fatal ("Illegal internal LDA insn definition");
2352 if (tinsn
->operands
[0].mode
== M_REGISTER
2353 && tinsn
->operands
[1].mode
== M_REGISTER
2354 && tinsn
->operands
[0].expr
.X_add_number
== tinsn
->operands
[1].expr
.X_add_number
)
2355 as_bad (_("Source and destination register should not be equal"));
2357 else if (!strcmp (tinsn
->name
, "ldi_ldi")
2358 || !strcmp (tinsn
->name
, "ldi1_ldi2")
2359 || !strcmp (tinsn
->name
, "ldi2_ldi1")
2360 || !strcmp (tinsn
->name
, "ldf_ldf")
2361 || !strcmp (tinsn
->name
, "ldf1_ldf2")
2362 || !strcmp (tinsn
->name
, "ldf2_ldf1") )
2364 if (tinsn
->num_operands
< 4 && tinsn
->num_operands
> 5 )
2365 as_fatal ("Illegal internal %s insn definition", tinsn
->name
);
2367 if (tinsn
->operands
[1].mode
== M_REGISTER
2368 && tinsn
->operands
[tinsn
->num_operands
-1].mode
== M_REGISTER
2369 && tinsn
->operands
[1].expr
.X_add_number
== tinsn
->operands
[tinsn
->num_operands
-1].expr
.X_add_number
)
2370 as_warn (_("Equal parallell destination registers, one result will be discarded"));
2375 tic4x_insn_output (tic4x_insn_t
*tinsn
)
2379 /* Grab another fragment for opcode. */
2380 dst
= frag_more (tinsn
->nchars
);
2382 /* Put out opcode word as a series of bytes in little endian order. */
2383 md_number_to_chars (dst
, tinsn
->opcode
, tinsn
->nchars
);
2385 /* Put out the symbol-dependent stuff. */
2386 if (tinsn
->reloc
!= NO_RELOC
)
2388 /* Where is the offset into the fragment for this instruction. */
2389 fix_new_exp (frag_now
,
2390 dst
- frag_now
->fr_literal
, /* where */
2391 tinsn
->nchars
, /* size */
2398 /* Parse the operands. */
2400 tic4x_operands_parse (char *s
, tic4x_operand_t
*operands
, int num_operands
)
2403 return num_operands
;
2406 s
= tic4x_operand_parse (s
, &operands
[num_operands
++]);
2407 while (num_operands
< TIC4X_OPERANDS_MAX
&& *s
++ == ',');
2409 if (num_operands
> TIC4X_OPERANDS_MAX
)
2411 as_bad (_("Too many operands scanned"));
2414 return num_operands
;
2417 /* Assemble a single instruction. Its label has already been handled
2418 by the generic front end. We just parse mnemonic and operands, and
2419 produce the bytes of data and relocation. */
2421 md_assemble (char *str
)
2427 tic4x_inst_t
*inst
; /* Instruction template. */
2428 tic4x_inst_t
*first_inst
;
2430 /* Scan for parallel operators */
2434 while (*s
&& *s
!= '|')
2437 if (*s
&& s
[1]=='|')
2441 as_bad (_("Parallel opcode cannot contain more than two instructions"));
2447 /* Lets take care of the first part of the parallel insn */
2452 /* .. and let the second run though here */
2456 if (str
&& insn
->parallel
)
2458 /* Find mnemonic (second part of parallel instruction). */
2460 /* Skip past instruction mnemonic. */
2461 while (*s
&& *s
!= ' ')
2463 if (*s
) /* Null terminate for hash_find. */
2464 *s
++ = '\0'; /* and skip past null. */
2465 strcat (insn
->name
, "_");
2466 strncat (insn
->name
, str
, TIC4X_NAME_MAX
- strlen (insn
->name
));
2468 insn
->operands
[insn
->num_operands
++].mode
= M_PARALLEL
;
2470 if ((i
= tic4x_operands_parse
2471 (s
, insn
->operands
, insn
->num_operands
)) < 0)
2477 insn
->num_operands
= i
;
2483 if ((insn
->inst
= (struct tic4x_inst
*)
2484 hash_find (tic4x_op_hash
, insn
->name
)) == NULL
)
2486 as_bad (_("Unknown opcode `%s'."), insn
->name
);
2496 ok
= tic4x_operands_match (inst
, insn
, 1);
2503 } while (!ok
&& !strcmp (inst
->name
, inst
[1].name
) && inst
++);
2507 tic4x_insn_check (insn
);
2508 tic4x_insn_output (insn
);
2513 tic4x_operands_match (first_inst
, insn
, 0);
2514 as_bad (_("Invalid operands for %s"), insn
->name
);
2517 as_bad (_("Invalid instruction %s"), insn
->name
);
2522 /* Find mnemonic. */
2524 while (*s
&& *s
!= ' ') /* Skip past instruction mnemonic. */
2526 if (*s
) /* Null terminate for hash_find. */
2527 *s
++ = '\0'; /* and skip past null. */
2528 strncpy (insn
->name
, str
, TIC4X_NAME_MAX
- 3);
2530 if ((i
= tic4x_operands_parse (s
, insn
->operands
, 0)) < 0)
2532 insn
->inst
= NULL
; /* Flag that error occurred. */
2537 insn
->num_operands
= i
;
2546 tic4x_cleanup (void)
2552 /* Turn a string in input_line_pointer into a floating point constant
2553 of type type, and store the appropriate bytes in *litP. The number
2554 of chars emitted is stored in *sizeP. An error message is
2555 returned, or NULL on OK. */
2558 md_atof (int type
, char *litP
, int *sizeP
)
2562 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2563 LITTLENUM_TYPE
*wordP
;
2568 case 's': /* .single */
2574 case 'd': /* .double */
2576 case 'f': /* .float */
2579 prec
= 2; /* 1 32-bit word */
2582 case 'i': /* .ieee */
2586 type
= 'f'; /* Rewrite type to be usable by atof_ieee(). */
2589 case 'e': /* .ldouble */
2591 prec
= 4; /* 2 32-bit words */
2597 return _("Unrecognized or unsupported floating point constant");
2601 t
= atof_ieee (input_line_pointer
, type
, words
);
2603 t
= tic4x_atof (input_line_pointer
, type
, words
);
2605 input_line_pointer
= t
;
2606 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
2608 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
2609 little endian byte order. */
2610 /* SES: However it is required to put the words (32-bits) out in the
2611 correct order, hence we write 2 and 2 littlenums in little endian
2612 order, while we keep the original order on successive words. */
2613 for (wordP
= words
; wordP
<(words
+prec
) ; wordP
+=2)
2615 if (wordP
< (words
+ prec
- 1)) /* Dump wordP[1] (if we have one). */
2617 md_number_to_chars (litP
, (valueT
) (wordP
[1]),
2618 sizeof (LITTLENUM_TYPE
));
2619 litP
+= sizeof (LITTLENUM_TYPE
);
2623 md_number_to_chars (litP
, (valueT
) (wordP
[0]),
2624 sizeof (LITTLENUM_TYPE
));
2625 litP
+= sizeof (LITTLENUM_TYPE
);
2631 md_apply_fix (fixS
*fixP
, valueT
*value
, segT seg ATTRIBUTE_UNUSED
)
2633 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
2634 valueT val
= *value
;
2636 switch (fixP
->fx_r_type
)
2638 case BFD_RELOC_HI16
:
2642 case BFD_RELOC_LO16
:
2649 switch (fixP
->fx_r_type
)
2654 case BFD_RELOC_24_PCREL
:
2657 case BFD_RELOC_16_PCREL
:
2658 case BFD_RELOC_LO16
:
2659 case BFD_RELOC_HI16
:
2666 as_bad (_("Bad relocation type: 0x%02x"), fixP
->fx_r_type
);
2670 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0) fixP
->fx_done
= 1;
2673 /* Should never be called for tic4x. */
2675 md_convert_frag (bfd
*headers ATTRIBUTE_UNUSED
,
2676 segT sec ATTRIBUTE_UNUSED
,
2677 fragS
*fragP ATTRIBUTE_UNUSED
)
2679 as_fatal ("md_convert_frag");
2682 /* Should never be called for tic4x. */
2684 md_create_short_jump (char *ptr ATTRIBUTE_UNUSED
,
2685 addressT from_addr ATTRIBUTE_UNUSED
,
2686 addressT to_addr ATTRIBUTE_UNUSED
,
2687 fragS
*frag ATTRIBUTE_UNUSED
,
2688 symbolS
*to_symbol ATTRIBUTE_UNUSED
)
2690 as_fatal ("md_create_short_jmp\n");
2693 /* Should never be called for tic4x. */
2695 md_create_long_jump (char *ptr ATTRIBUTE_UNUSED
,
2696 addressT from_addr ATTRIBUTE_UNUSED
,
2697 addressT to_addr ATTRIBUTE_UNUSED
,
2698 fragS
*frag ATTRIBUTE_UNUSED
,
2699 symbolS
*to_symbol ATTRIBUTE_UNUSED
)
2701 as_fatal ("md_create_long_jump\n");
2704 /* Should never be called for tic4x. */
2706 md_estimate_size_before_relax (fragS
*fragP ATTRIBUTE_UNUSED
,
2707 segT segtype ATTRIBUTE_UNUSED
)
2709 as_fatal ("md_estimate_size_before_relax\n");
2715 md_parse_option (int c
, char *arg
)
2719 case OPTION_CPU
: /* cpu brand */
2720 if (TOLOWER (*arg
) == 'c')
2722 tic4x_cpu
= atoi (arg
);
2723 if (!IS_CPU_TIC3X (tic4x_cpu
) && !IS_CPU_TIC4X (tic4x_cpu
))
2724 as_warn (_("Unsupported processor generation %d"), tic4x_cpu
);
2727 case OPTION_REV
: /* cpu revision */
2728 tic4x_revision
= atoi (arg
);
2732 as_warn (_("Option -b is depreciated, please use -mbig"));
2733 case OPTION_BIG
: /* big model */
2734 tic4x_big_model
= 1;
2738 as_warn (_("Option -p is depreciated, please use -mmemparm"));
2739 case OPTION_MEMPARM
: /* push args */
2744 as_warn (_("Option -r is depreciated, please use -mregparm"));
2745 case OPTION_REGPARM
: /* register args */
2750 as_warn (_("Option -s is depreciated, please use -msmall"));
2751 case OPTION_SMALL
: /* small model */
2752 tic4x_big_model
= 0;
2759 case OPTION_LOWPOWER
:
2763 case OPTION_ENHANCED
:
2775 md_show_usage (FILE *stream
)
2778 _("\nTIC4X options:\n"
2779 " -mcpu=CPU -mCPU select architecture variant. CPU can be:\n"
2781 " 31 - TMS320C31, TMS320LC31\n"
2783 " 33 - TMS320VC33\n"
2786 " -mrev=REV set cpu hardware revision (integer numbers).\n"
2787 " Combinations of -mcpu and -mrev will enable/disable\n"
2788 " the appropriate options (-midle2, -mlowpower and\n"
2789 " -menhanced) according to the selected type\n"
2790 " -mbig select big memory model\n"
2791 " -msmall select small memory model (default)\n"
2792 " -mregparm select register parameters (default)\n"
2793 " -mmemparm select memory parameters\n"
2794 " -midle2 enable IDLE2 support\n"
2795 " -mlowpower enable LOPOWER and MAXSPEED support\n"
2796 " -menhanced enable enhanced opcode support\n"));
2799 /* This is called when a line is unrecognized. This is used to handle
2800 definitions of TI C3x tools style local labels $n where n is a single
2803 tic4x_unrecognized_line (int c
)
2808 if (c
!= '$' || ! ISDIGIT (input_line_pointer
[0]))
2811 s
= input_line_pointer
;
2813 /* Let's allow multiple digit local labels. */
2815 while (ISDIGIT (*s
))
2817 lab
= lab
* 10 + *s
- '0';
2821 if (dollar_label_defined (lab
))
2823 as_bad (_("Label \"$%d\" redefined"), lab
);
2827 define_dollar_label (lab
);
2828 colon (dollar_label_name (lab
, 0));
2829 input_line_pointer
= s
+ 1;
2834 /* Handle local labels peculiar to us referred to in an expression. */
2836 md_undefined_symbol (char *name
)
2838 /* Look for local labels of the form $n. */
2839 if (name
[0] == '$' && ISDIGIT (name
[1]))
2845 while (ISDIGIT ((unsigned char) *s
))
2847 lab
= lab
* 10 + *s
- '0';
2850 if (dollar_label_defined (lab
))
2852 name
= dollar_label_name (lab
, 0);
2853 symbolP
= symbol_find (name
);
2857 name
= dollar_label_name (lab
, 1);
2858 symbolP
= symbol_find_or_make (name
);
2866 /* Parse an operand that is machine-specific. */
2868 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
2872 /* Round up a section size to the appropriate boundary---do we need this? */
2874 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
2876 return size
; /* Byte (i.e., 32-bit) alignment is fine? */
2880 tic4x_pc_offset (unsigned int op
)
2882 /* Determine the PC offset for a C[34]x instruction.
2883 This could be simplified using some boolean algebra
2884 but at the expense of readability. */
2888 case 0x62: /* call (C4x) */
2889 case 0x64: /* rptb (C4x) */
2891 case 0x61: /* brd */
2892 case 0x63: /* laj */
2893 case 0x65: /* rptbd (C4x) */
2895 case 0x66: /* swi */
2902 switch ((op
& 0xffe00000) >> 20)
2904 case 0x6a0: /* bB */
2905 case 0x720: /* callB */
2906 case 0x740: /* trapB */
2909 case 0x6a2: /* bBd */
2910 case 0x6a6: /* bBat */
2911 case 0x6aa: /* bBaf */
2912 case 0x722: /* lajB */
2913 case 0x748: /* latB */
2914 case 0x798: /* rptbd */
2921 switch ((op
& 0xfe200000) >> 20)
2923 case 0x6e0: /* dbB */
2926 case 0x6e2: /* dbBd */
2936 /* Exactly what point is a PC-relative offset relative TO?
2937 With the C3x we have the following:
2938 DBcond, Bcond disp + PC + 1 => PC
2939 DBcondD, BcondD disp + PC + 3 => PC
2942 md_pcrel_from (fixS
*fixP
)
2947 buf
= (unsigned char *) fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2948 op
= (buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
2950 return ((fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) >> 2) +
2951 tic4x_pc_offset (op
);
2954 /* Fill the alignment area with NOP's on .text, unless fill-data
2957 tic4x_do_align (int alignment
,
2962 /* Because we are talking lwords, not bytes, adjust alignment to do words */
2965 if (alignment
!= 0 && !need_pass_2
)
2969 /* FIXME: subseg_text_p tests SEC_CODE which isn't in allowed
2970 section flags. See bfd/coff-tic4x.c target vecs. */
2971 if (1 || subseg_text_p (now_seg
))
2975 md_number_to_chars (nop
, TIC_NOP_OPCODE
, 4);
2976 frag_align_pattern (alignment
, nop
, sizeof (nop
), max
);
2979 frag_align (alignment
, 0, max
);
2982 frag_align (alignment
, *fill
, max
);
2984 frag_align_pattern (alignment
, fill
, len
, max
);
2987 /* Return 1 to skip the default alignment function */
2991 /* Look for and remove parallel instruction operator ||. */
2993 tic4x_start_line (void)
2995 char *s
= input_line_pointer
;
2999 /* If parallel instruction prefix found at start of line, skip it. */
3000 if (*input_line_pointer
== '|' && input_line_pointer
[1] == '|')
3005 input_line_pointer
++;
3006 *input_line_pointer
= ' ';
3007 /* So line counters get bumped. */
3008 input_line_pointer
[-1] = '\n';
3013 /* Write out the previous insn here */
3016 input_line_pointer
= s
;
3021 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixP
)
3025 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
3027 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
3028 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
3029 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
3030 reloc
->address
/= OCTETS_PER_BYTE
;
3031 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
3032 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
3034 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3035 _("Reloc %d not supported by object file format"),
3036 (int) fixP
->fx_r_type
);
3040 if (fixP
->fx_r_type
== BFD_RELOC_HI16
)
3041 reloc
->addend
= fixP
->fx_offset
;
3043 reloc
->addend
= fixP
->fx_addnumber
;