1 /* tc-tic4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
2 Copyright (C) 1997-2014 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"
48 /* OK, we accept a syntax similar to the other well known C30
49 assembly tools. With TIC4X_ALT_SYNTAX defined we are more
50 flexible, allowing a more Unix-like syntax: `%' in front of
51 register names, `#' in front of immediate constants, and
52 not requiring `@' in front of direct addresses. */
54 #define TIC4X_ALT_SYNTAX
56 /* Equal to MAX_PRECISION in atof-ieee.c. */
57 #define MAX_LITTLENUMS 6 /* (12 bytes) */
59 /* Handle of the inst mnemonic hash table. */
60 static struct hash_control
*tic4x_op_hash
= NULL
;
62 /* Handle asg pseudo. */
63 static struct hash_control
*tic4x_asg_hash
= NULL
;
65 static unsigned int tic4x_cpu
= 0; /* Default to TMS320C40. */
66 static unsigned int tic4x_revision
= 0; /* CPU revision */
67 static unsigned int tic4x_idle2
= 0; /* Idle2 support */
68 static unsigned int tic4x_lowpower
= 0; /* Lowpower support */
69 static unsigned int tic4x_enhanced
= 0; /* Enhanced opcode support */
70 static unsigned int tic4x_big_model
= 0; /* Default to small memory model. */
71 static unsigned int tic4x_reg_args
= 0; /* Default to args passed on stack. */
72 static unsigned long tic4x_oplevel
= 0; /* Opcode level */
74 #define OPTION_CPU 'm'
75 #define OPTION_BIG (OPTION_MD_BASE + 1)
76 #define OPTION_SMALL (OPTION_MD_BASE + 2)
77 #define OPTION_MEMPARM (OPTION_MD_BASE + 3)
78 #define OPTION_REGPARM (OPTION_MD_BASE + 4)
79 #define OPTION_IDLE2 (OPTION_MD_BASE + 5)
80 #define OPTION_LOWPOWER (OPTION_MD_BASE + 6)
81 #define OPTION_ENHANCED (OPTION_MD_BASE + 7)
82 #define OPTION_REV (OPTION_MD_BASE + 8)
84 const char *md_shortopts
= "bm:prs";
85 struct option md_longopts
[] =
87 { "mcpu", required_argument
, NULL
, OPTION_CPU
},
88 { "mdsp", required_argument
, NULL
, OPTION_CPU
},
89 { "mbig", no_argument
, NULL
, OPTION_BIG
},
90 { "msmall", no_argument
, NULL
, OPTION_SMALL
},
91 { "mmemparm", no_argument
, NULL
, OPTION_MEMPARM
},
92 { "mregparm", no_argument
, NULL
, OPTION_REGPARM
},
93 { "midle2", no_argument
, NULL
, OPTION_IDLE2
},
94 { "mlowpower", no_argument
, NULL
, OPTION_LOWPOWER
},
95 { "menhanced", no_argument
, NULL
, OPTION_ENHANCED
},
96 { "mrev", required_argument
, NULL
, OPTION_REV
},
97 { NULL
, no_argument
, NULL
, 0 }
100 size_t md_longopts_size
= sizeof (md_longopts
);
105 M_UNKNOWN
, M_IMMED
, M_DIRECT
, M_REGISTER
, M_INDIRECT
,
106 M_IMMED_F
, M_PARALLEL
, M_HI
110 typedef struct tic4x_operand
112 tic4x_addr_mode_t mode
; /* Addressing mode. */
113 expressionS expr
; /* Expression. */
114 int disp
; /* Displacement for indirect addressing. */
115 int aregno
; /* Aux. register number. */
116 LITTLENUM_TYPE fwords
[MAX_LITTLENUMS
]; /* Float immed. number. */
120 typedef struct tic4x_insn
122 char name
[TIC4X_NAME_MAX
]; /* Mnemonic of instruction. */
123 unsigned int in_use
; /* True if in_use. */
124 unsigned int parallel
; /* True if parallel instruction. */
125 unsigned int nchars
; /* This is always 4 for the C30. */
126 unsigned long opcode
; /* Opcode number. */
127 expressionS exp
; /* Expression required for relocation. */
128 int reloc
; /* Relocation type required. */
129 int pcrel
; /* True if relocation PC relative. */
130 char *pname
; /* Name of instruction in parallel. */
131 unsigned int num_operands
; /* Number of operands in total. */
132 tic4x_inst_t
*inst
; /* Pointer to first template. */
133 tic4x_operand_t operands
[TIC4X_OPERANDS_MAX
];
137 static tic4x_insn_t the_insn
; /* Info about our instruction. */
138 static tic4x_insn_t
*insn
= &the_insn
;
140 static void tic4x_asg (int);
141 static void tic4x_bss (int);
142 static void tic4x_globl (int);
143 static void tic4x_cons (int);
144 static void tic4x_stringer (int);
145 static void tic4x_eval (int);
146 static void tic4x_newblock (int);
147 static void tic4x_sect (int);
148 static void tic4x_set (int);
149 static void tic4x_usect (int);
150 static void tic4x_version (int);
156 {"align", s_align_bytes
, 32},
157 {"ascii", tic4x_stringer
, 1},
158 {"asciz", tic4x_stringer
, 0},
159 {"asg", tic4x_asg
, 0},
160 {"block", s_space
, 4},
161 {"byte", tic4x_cons
, 1},
162 {"bss", tic4x_bss
, 0},
163 {"copy", s_include
, 0},
164 {"def", tic4x_globl
, 0},
165 {"equ", tic4x_set
, 0},
166 {"eval", tic4x_eval
, 0},
167 {"global", tic4x_globl
, 0},
168 {"globl", tic4x_globl
, 0},
169 {"hword", tic4x_cons
, 2},
170 {"ieee", float_cons
, 'i'},
171 {"int", tic4x_cons
, 4}, /* .int allocates 4 bytes. */
172 {"ldouble", float_cons
, 'e'},
173 {"newblock", tic4x_newblock
, 0},
174 {"ref", s_ignore
, 0}, /* All undefined treated as external. */
175 {"set", tic4x_set
, 0},
176 {"sect", tic4x_sect
, 1}, /* Define named section. */
177 {"space", s_space
, 4},
178 {"string", tic4x_stringer
, 0},
179 {"usect", tic4x_usect
, 0}, /* Reserve space in uninit. named sect. */
180 {"version", tic4x_version
, 0},
181 {"word", tic4x_cons
, 4}, /* .word allocates 4 bytes. */
182 {"xdef", tic4x_globl
, 0},
186 int md_short_jump_size
= 4;
187 int md_long_jump_size
= 4;
189 /* This array holds the chars that always start a comment. If the
190 pre-processor is disabled, these aren't very useful. */
191 #ifdef TIC4X_ALT_SYNTAX
192 const char comment_chars
[] = ";!";
194 const char comment_chars
[] = ";";
197 /* This array holds the chars that only start a comment at the beginning of
198 a line. If the line seems to have the form '# 123 filename'
199 .line and .file directives will appear in the pre-processed output.
200 Note that input_file.c hand checks for '#' at the beginning of the
201 first line of the input file. This is because the compiler outputs
202 #NO_APP at the beginning of its output.
203 Also note that comments like this one will always work. */
204 const char line_comment_chars
[] = "#*";
206 /* We needed an unused char for line separation to work around the
207 lack of macros, using sed and such. */
208 const char line_separator_chars
[] = "&";
210 /* Chars that can be used to separate mant from exp in floating point nums. */
211 const char EXP_CHARS
[] = "eE";
213 /* Chars that mean this number is a floating point constant. */
216 const char FLT_CHARS
[] = "fFilsS";
218 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
219 changed in read.c. Ideally it shouldn't have to know about it at
220 all, but nothing is ideal around here. */
222 /* Flonums returned here. */
223 extern FLONUM_TYPE generic_floating_point_number
;
225 /* Precision in LittleNums. */
226 #define MAX_PRECISION (4) /* Its a bit overkill for us, but the code
228 #define S_PRECISION (1) /* Short float constants 16-bit. */
229 #define F_PRECISION (2) /* Float and double types 32-bit. */
230 #define E_PRECISION (4) /* Extended precision, 64-bit (real 40-bit). */
233 /* Turn generic_floating_point_number into a real short/float/double. */
235 tic4x_gen_to_words (FLONUM_TYPE flonum
, LITTLENUM_TYPE
*words
, int precision
)
237 int return_value
= 0;
238 LITTLENUM_TYPE
*p
; /* Littlenum pointer. */
239 int mantissa_bits
; /* Bits in mantissa field. */
240 int exponent_bits
; /* Bits in exponent field. */
242 unsigned int sone
; /* Scaled one. */
243 unsigned int sfract
; /* Scaled fraction. */
244 unsigned int smant
; /* Scaled mantissa. */
246 unsigned int mover
; /* Mantissa overflow bits */
247 unsigned int rbit
; /* Round bit. */
248 int shift
; /* Shift count. */
250 /* NOTE: Svein Seldal <Svein@dev.seldal.com>
251 The code in this function is altered slightly to support floats
252 with 31-bits mantissas, thus the documentation below may be a
253 little bit inaccurate.
255 By Michael P. Hayes <m.hayes@elec.canterbury.ac.nz>
256 Here is how a generic floating point number is stored using
257 flonums (an extension of bignums) where p is a pointer to an
260 For example 2e-3 is stored with exp = -4 and
267 with low = &bits[2], high = &bits[5], and leader = &bits[5].
269 This number can be written as
270 0x0083126e978d4fde.00000000 * 65536**-4 or
271 0x0.0083126e978d4fde * 65536**0 or
272 0x0.83126e978d4fde * 2**-8 = 2e-3
274 Note that low points to the 65536**0 littlenum (bits[2]) and
275 leader points to the most significant non-zero littlenum
278 TMS320C3X floating point numbers are a bit of a strange beast.
279 The 32-bit flavour has the 8 MSBs representing the exponent in
280 twos complement format (-128 to +127). There is then a sign bit
281 followed by 23 bits of mantissa. The mantissa is expressed in
282 twos complement format with the binary point after the most
283 significant non sign bit. The bit after the binary point is
284 suppressed since it is the complement of the sign bit. The
285 effective mantissa is thus 24 bits. Zero is represented by an
288 The 16-bit flavour has the 4 MSBs representing the exponent in
289 twos complement format (-8 to +7). There is then a sign bit
290 followed by 11 bits of mantissa. The mantissa is expressed in
291 twos complement format with the binary point after the most
292 significant non sign bit. The bit after the binary point is
293 suppressed since it is the complement of the sign bit. The
294 effective mantissa is thus 12 bits. Zero is represented by an
295 exponent of -8. For example,
297 number norm mant m x e s i fraction f
298 +0.500 => 1.00000000000 -1 -1 0 1 .00000000000 (1 + 0) * 2^(-1)
299 +0.999 => 1.11111111111 -1 -1 0 1 .11111111111 (1 + 0.99) * 2^(-1)
300 +1.000 => 1.00000000000 0 0 0 1 .00000000000 (1 + 0) * 2^(0)
301 +1.500 => 1.10000000000 0 0 0 1 .10000000000 (1 + 0.5) * 2^(0)
302 +1.999 => 1.11111111111 0 0 0 1 .11111111111 (1 + 0.9) * 2^(0)
303 +2.000 => 1.00000000000 1 1 0 1 .00000000000 (1 + 0) * 2^(1)
304 +4.000 => 1.00000000000 2 2 0 1 .00000000000 (1 + 0) * 2^(2)
305 -0.500 => 1.00000000000 -1 -1 1 0 .10000000000 (-2 + 0) * 2^(-2)
306 -1.000 => 1.00000000000 0 -1 1 0 .00000000000 (-2 + 0) * 2^(-1)
307 -1.500 => 1.10000000000 0 0 1 0 .10000000000 (-2 + 0.5) * 2^(0)
308 -1.999 => 1.11111111111 0 0 1 0 .00000000001 (-2 + 0.11) * 2^(0)
309 -2.000 => 1.00000000000 1 1 1 0 .00000000000 (-2 + 0) * 2^(0)
310 -4.000 => 1.00000000000 2 1 1 0 .00000000000 (-2 + 0) * 2^(1)
312 where e is the exponent, s is the sign bit, i is the implied bit,
313 and f is the fraction stored in the mantissa field.
315 num = (1 + f) * 2^x = m * 2^e if s = 0
316 num = (-2 + f) * 2^x = -m * 2^e if s = 1
317 where 0 <= f < 1.0 and 1.0 <= m < 2.0
319 The fraction (f) and exponent (e) fields for the TMS320C3X format
320 can be derived from the normalised mantissa (m) and exponent (x) using:
322 f = m - 1, e = x if s = 0
323 f = 2 - m, e = x if s = 1 and m != 1.0
324 f = 0, e = x - 1 if s = 1 and m = 1.0
325 f = 0, e = -8 if m = 0
328 OK, the other issue we have to consider is rounding since the
329 mantissa has a much higher potential precision than what we can
330 represent. To do this we add half the smallest storable fraction.
331 We then have to renormalise the number to allow for overflow.
333 To convert a generic flonum into a TMS320C3X floating point
334 number, here's what we try to do....
336 The first thing is to generate a normalised mantissa (m) where
337 1.0 <= m < 2 and to convert the exponent from base 16 to base 2.
338 We desire the binary point to be placed after the most significant
339 non zero bit. This process is done in two steps: firstly, the
340 littlenum with the most significant non zero bit is located (this
341 is done for us since leader points to this littlenum) and the
342 binary point (which is currently after the LSB of the littlenum
343 pointed to by low) is moved to before the MSB of the littlenum
344 pointed to by leader. This requires the exponent to be adjusted
345 by leader - low + 1. In the earlier example, the new exponent is
346 thus -4 + (5 - 2 + 1) = 0 (base 65536). We now need to convert
347 the exponent to base 2 by multiplying the exponent by 16 (log2
348 65536). The exponent base 2 is thus also zero.
350 The second step is to hunt for the most significant non zero bit
351 in the leader littlenum. We do this by left shifting a copy of
352 the leader littlenum until bit 16 is set (0x10000) and counting
353 the number of shifts, S, required. The number of shifts then has to
354 be added to correct the exponent (base 2). For our example, this
355 will require 9 shifts and thus our normalised exponent (base 2) is
356 0 + 9 = 9. Note that the worst case scenario is when the leader
357 littlenum is 1, thus requiring 16 shifts.
359 We now have to left shift the other littlenums by the same amount,
360 propagating the shifted bits into the more significant littlenums.
361 To save a lot of unnecessary shifting we only have to consider
362 two or three littlenums, since the greatest number of mantissa
363 bits required is 24 + 1 rounding bit. While two littlenums
364 provide 32 bits of precision, the most significant littlenum
365 may only contain a single significant bit and thus an extra
366 littlenum is required.
368 Denoting the number of bits in the fraction field as F, we require
369 G = F + 2 bits (one extra bit is for rounding, the other gets
370 suppressed). Say we required S shifts to find the most
371 significant bit in the leader littlenum, the number of left shifts
372 required to move this bit into bit position G - 1 is L = G + S - 17.
373 Note that this shift count may be negative for the short floating
374 point flavour (where F = 11 and thus G = 13 and potentially S < 3).
375 If L > 0 we have to shunt the next littlenum into position. Bit
376 15 (the MSB) of the next littlenum needs to get moved into position
377 L - 1 (If L > 15 we need all the bits of this littlenum and
378 some more from the next one.). We subtract 16 from L and use this
379 as the left shift count; the resultant value we or with the
380 previous result. If L > 0, we repeat this operation. */
382 if (precision
!= S_PRECISION
)
384 if (precision
== E_PRECISION
)
385 words
[2] = words
[3] = 0x0000;
387 /* 0.0e0 or NaN seen. */
388 if (flonum
.low
> flonum
.leader
/* = 0.0e0 */
389 || flonum
.sign
== 0) /* = NaN */
392 as_bad (_("Nan, using zero."));
397 if (flonum
.sign
== 'P')
399 /* +INF: Replace with maximum float. */
400 if (precision
== S_PRECISION
)
407 if (precision
== E_PRECISION
)
414 else if (flonum
.sign
== 'N')
416 /* -INF: Replace with maximum float. */
417 if (precision
== S_PRECISION
)
421 if (precision
== E_PRECISION
)
426 exponent
= (flonum
.exponent
+ flonum
.leader
- flonum
.low
+ 1) * 16;
428 if (!(tmp
= *flonum
.leader
))
429 abort (); /* Hmmm. */
430 shift
= 0; /* Find position of first sig. bit. */
433 exponent
-= (16 - shift
); /* Adjust exponent. */
435 if (precision
== S_PRECISION
) /* Allow 1 rounding bit. */
440 else if(precision
== F_PRECISION
)
445 else /* E_PRECISION */
451 shift
= mantissa_bits
- shift
;
456 /* Store the mantissa data into smant and the roundbit into rbit */
457 for (p
= flonum
.leader
; p
>= flonum
.low
&& shift
> -16; p
--)
459 tmp
= shift
>= 0 ? *p
<< shift
: *p
>> -shift
;
460 rbit
= shift
< 0 ? ((*p
>> (-shift
-1)) & 0x1) : 0;
465 /* OK, we've got our scaled mantissa so let's round it up */
468 /* If the mantissa is going to overflow when added, lets store
469 the extra bit in mover. -- A special case exists when
470 mantissa_bits is 31 (E_PRECISION). Then the first test cannot
471 be trusted, as result is host-dependent, thus the second
473 if( smant
== ((unsigned)(1<<(mantissa_bits
+1))-1)
474 || smant
== (unsigned)-1 ) /* This is to catch E_PRECISION cases */
479 /* Get the scaled one value */
480 sone
= (1 << (mantissa_bits
));
482 /* The number may be unnormalised so renormalise it... */
486 smant
|= sone
; /* Insert the bit from mover into smant */
490 /* The binary point is now between bit positions 11 and 10 or 23 and 22,
491 i.e., between mantissa_bits - 1 and mantissa_bits - 2 and the
492 bit at mantissa_bits - 1 should be set. */
494 abort (); /* Ooops. */
496 if (flonum
.sign
== '+')
497 sfract
= smant
- sone
; /* smant - 1.0. */
500 /* This seems to work. */
508 sfract
= -smant
& (sone
-1); /* 2.0 - smant. */
510 sfract
|= sone
; /* Insert sign bit. */
513 if (abs (exponent
) >= (1 << (exponent_bits
- 1)))
514 as_bad (_("Cannot represent exponent in %d bits"), exponent_bits
);
516 /* Force exponent to fit in desired field width. */
517 exponent
&= (1 << (exponent_bits
)) - 1;
519 if (precision
== E_PRECISION
)
521 /* Map the float part first (100% equal format as F_PRECISION) */
522 words
[0] = exponent
<< (mantissa_bits
+1-24);
523 words
[0] |= sfract
>> 24;
524 words
[1] = sfract
>> 8;
526 /* Map the mantissa in the next */
527 words
[2] = sfract
>> 16;
528 words
[3] = sfract
& 0xffff;
532 /* Insert the exponent data into the word */
533 sfract
|= exponent
<< (mantissa_bits
+1);
535 if (precision
== S_PRECISION
)
539 words
[0] = sfract
>> 16;
540 words
[1] = sfract
& 0xffff;
547 /* Returns pointer past text consumed. */
549 tic4x_atof (char *str
, char what_kind
, LITTLENUM_TYPE
*words
)
551 /* Extra bits for zeroed low-order bits. The 1st MAX_PRECISION are
552 zeroed, the last contain flonum bits. */
553 static LITTLENUM_TYPE bits
[MAX_PRECISION
+ MAX_PRECISION
+ GUARD
];
555 /* Number of 16-bit words in the format. */
557 FLONUM_TYPE save_gen_flonum
;
559 /* We have to save the generic_floating_point_number because it
560 contains storage allocation about the array of LITTLENUMs where
561 the value is actually stored. We will allocate our own array of
562 littlenums below, but have to restore the global one on exit. */
563 save_gen_flonum
= generic_floating_point_number
;
566 generic_floating_point_number
.low
= bits
+ MAX_PRECISION
;
567 generic_floating_point_number
.high
= NULL
;
568 generic_floating_point_number
.leader
= NULL
;
569 generic_floating_point_number
.exponent
= 0;
570 generic_floating_point_number
.sign
= '\0';
572 /* Use more LittleNums than seems necessary: the highest flonum may
573 have 15 leading 0 bits, so could be useless. */
575 memset (bits
, '\0', sizeof (LITTLENUM_TYPE
) * MAX_PRECISION
);
581 precision
= S_PRECISION
;
588 precision
= F_PRECISION
;
593 precision
= E_PRECISION
;
597 as_bad (_("Invalid floating point number"));
601 generic_floating_point_number
.high
602 = generic_floating_point_number
.low
+ precision
- 1 + GUARD
;
604 if (atof_generic (&return_value
, ".", EXP_CHARS
,
605 &generic_floating_point_number
))
607 as_bad (_("Invalid floating point number"));
611 tic4x_gen_to_words (generic_floating_point_number
,
614 /* Restore the generic_floating_point_number's storage alloc (and
616 generic_floating_point_number
= save_gen_flonum
;
622 tic4x_insert_reg (char *regname
, int regnum
)
627 symbol_table_insert (symbol_new (regname
, reg_section
, (valueT
) regnum
,
628 &zero_address_frag
));
629 for (i
= 0; regname
[i
]; i
++)
630 buf
[i
] = ISLOWER (regname
[i
]) ? TOUPPER (regname
[i
]) : regname
[i
];
633 symbol_table_insert (symbol_new (buf
, reg_section
, (valueT
) regnum
,
634 &zero_address_frag
));
638 tic4x_insert_sym (char *symname
, int value
)
642 symbolP
= symbol_new (symname
, absolute_section
,
643 (valueT
) value
, &zero_address_frag
);
644 SF_SET_LOCAL (symbolP
);
645 symbol_table_insert (symbolP
);
649 tic4x_expression (char *str
, expressionS
*exp
)
654 t
= input_line_pointer
; /* Save line pointer. */
655 input_line_pointer
= str
;
657 s
= input_line_pointer
;
658 input_line_pointer
= t
; /* Restore line pointer. */
659 return s
; /* Return pointer to where parsing stopped. */
663 tic4x_expression_abs (char *str
, offsetT
*value
)
668 t
= input_line_pointer
; /* Save line pointer. */
669 input_line_pointer
= str
;
670 *value
= get_absolute_expression ();
671 s
= input_line_pointer
;
672 input_line_pointer
= t
; /* Restore line pointer. */
677 tic4x_emit_char (char c
, int b
)
681 exp
.X_op
= O_constant
;
682 exp
.X_add_number
= c
;
687 tic4x_seg_alloc (char *name ATTRIBUTE_UNUSED
,
688 segT seg ATTRIBUTE_UNUSED
,
692 /* Note that the size is in words
693 so we multiply it by 4 to get the number of bytes to allocate. */
695 /* If we have symbol: .usect ".fred", size etc.,
696 the symbol needs to point to the first location reserved
703 p
= frag_var (rs_fill
, 1, 1, (relax_substateT
) 0,
705 size
* OCTETS_PER_BYTE
, (char *) 0);
710 /* .asg ["]character-string["], symbol */
712 tic4x_asg (int x ATTRIBUTE_UNUSED
)
720 str
= input_line_pointer
;
722 /* Skip string expression. */
723 while (*input_line_pointer
!= ',' && *input_line_pointer
)
724 input_line_pointer
++;
725 if (*input_line_pointer
!= ',')
727 as_bad (_("Comma expected\n"));
730 *input_line_pointer
++ = '\0';
731 name
= input_line_pointer
;
732 c
= get_symbol_end (); /* Get terminator. */
733 tmp
= xmalloc (strlen (str
) + 1);
736 tmp
= xmalloc (strlen (name
) + 1);
739 if (hash_find (tic4x_asg_hash
, name
))
740 hash_replace (tic4x_asg_hash
, name
, (void *) str
);
742 hash_insert (tic4x_asg_hash
, name
, (void *) str
);
743 *input_line_pointer
= c
;
744 demand_empty_rest_of_line ();
747 /* .bss symbol, size */
749 tic4x_bss (int x ATTRIBUTE_UNUSED
)
756 subsegT current_subseg
;
759 current_seg
= now_seg
; /* Save current seg. */
760 current_subseg
= now_subseg
; /* Save current subseg. */
763 name
= input_line_pointer
;
764 c
= get_symbol_end (); /* Get terminator. */
767 as_bad (_(".bss size argument missing\n"));
772 tic4x_expression_abs (++input_line_pointer
, &size
);
775 as_bad (_(".bss size %ld < 0!"), (long) size
);
778 subseg_set (bss_section
, 0);
779 symbolP
= symbol_find_or_make (name
);
781 if (S_GET_SEGMENT (symbolP
) == bss_section
)
782 symbol_get_frag (symbolP
)->fr_symbol
= 0;
784 symbol_set_frag (symbolP
, frag_now
);
786 p
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
,
787 size
* OCTETS_PER_BYTE
, (char *) 0);
788 *p
= 0; /* Fill char. */
790 S_SET_SEGMENT (symbolP
, bss_section
);
792 /* The symbol may already have been created with a preceding
793 ".globl" directive -- be careful not to step on storage class
794 in that case. Otherwise, set it to static. */
795 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
796 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
798 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
799 demand_empty_rest_of_line ();
803 tic4x_globl (int ignore ATTRIBUTE_UNUSED
)
811 name
= input_line_pointer
;
812 c
= get_symbol_end ();
813 symbolP
= symbol_find_or_make (name
);
814 *input_line_pointer
= c
;
816 S_SET_STORAGE_CLASS (symbolP
, C_EXT
);
817 S_SET_EXTERNAL (symbolP
);
820 input_line_pointer
++;
822 if (*input_line_pointer
== '\n')
828 demand_empty_rest_of_line ();
831 /* Handle .byte, .word. .int, .long */
833 tic4x_cons (int bytes
)
835 register unsigned int c
;
839 if (*input_line_pointer
== '"')
841 input_line_pointer
++;
842 while (is_a_char (c
= next_char_of_string ()))
843 tic4x_emit_char (c
, 4);
844 know (input_line_pointer
[-1] == '\"');
850 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
851 if (exp
.X_op
== O_constant
)
856 exp
.X_add_number
&= 255;
859 exp
.X_add_number
&= 65535;
863 /* Perhaps we should disallow .byte and .hword with
864 a non constant expression that will require relocation. */
868 while (*input_line_pointer
++ == ',');
870 input_line_pointer
--; /* Put terminator back into stream. */
871 demand_empty_rest_of_line ();
874 /* Handle .ascii, .asciz, .string */
876 tic4x_stringer (int append_zero
)
879 register unsigned int c
;
885 if (*input_line_pointer
== '"')
887 input_line_pointer
++;
888 while (is_a_char (c
= next_char_of_string ()))
890 tic4x_emit_char (c
, 1);
896 tic4x_emit_char (c
, 1);
900 know (input_line_pointer
[-1] == '\"');
906 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
907 if (exp
.X_op
!= O_constant
)
909 as_bad (_("Non-constant symbols not allowed\n"));
912 exp
.X_add_number
&= 255; /* Limit numeber to 8-bit */
917 while (*input_line_pointer
++ == ',');
919 /* Fill out the rest of the expression with 0's to fill up a full word */
921 tic4x_emit_char (0, 4-(bytes
&0x3));
923 input_line_pointer
--; /* Put terminator back into stream. */
924 demand_empty_rest_of_line ();
927 /* .eval expression, symbol */
929 tic4x_eval (int x ATTRIBUTE_UNUSED
)
937 tic4x_expression_abs (input_line_pointer
, &value
);
938 if (*input_line_pointer
++ != ',')
940 as_bad (_("Symbol missing\n"));
943 name
= input_line_pointer
;
944 c
= get_symbol_end (); /* Get terminator. */
945 tic4x_insert_sym (name
, value
);
946 *input_line_pointer
++ = c
;
947 demand_empty_rest_of_line ();
950 /* Reset local labels. */
952 tic4x_newblock (int x ATTRIBUTE_UNUSED
)
954 dollar_label_clear ();
957 /* .sect "section-name" [, value] */
958 /* .sect ["]section-name[:subsection-name]["] [, value] */
960 tic4x_sect (int x ATTRIBUTE_UNUSED
)
969 if (*input_line_pointer
== '"')
970 input_line_pointer
++;
971 section_name
= input_line_pointer
;
972 c
= get_symbol_end (); /* Get terminator. */
973 input_line_pointer
++; /* Skip null symbol terminator. */
974 name
= xmalloc (input_line_pointer
- section_name
+ 1);
975 strcpy (name
, section_name
);
977 /* TI C from version 5.0 allows a section name to contain a
978 subsection name as well. The subsection name is separated by a
979 ':' from the section name. Currently we scan the subsection
981 Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>. */
984 c
= get_symbol_end (); /* Get terminator. */
985 input_line_pointer
++; /* Skip null symbol terminator. */
986 as_warn (_(".sect: subsection name ignored"));
989 /* We might still have a '"' to discard, but the character after a
990 symbol name will be overwritten with a \0 by get_symbol_end()
995 tic4x_expression_abs (input_line_pointer
, &num
);
996 else if (*input_line_pointer
== ',')
999 tic4x_expression_abs (++input_line_pointer
, &num
);
1004 seg
= subseg_new (name
, num
);
1005 if (line_label
!= NULL
)
1007 S_SET_SEGMENT (line_label
, seg
);
1008 symbol_set_frag (line_label
, frag_now
);
1011 if (bfd_get_section_flags (stdoutput
, seg
) == SEC_NO_FLAGS
)
1013 if (!bfd_set_section_flags (stdoutput
, seg
, SEC_DATA
))
1014 as_warn (_("Error setting flags for \"%s\": %s"), name
,
1015 bfd_errmsg (bfd_get_error ()));
1018 /* If the last character overwritten by get_symbol_end() was an
1019 end-of-line, we must restore it or the end of the line will not be
1020 recognised and scanning extends into the next line, stopping with
1021 an error (blame Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>
1022 if this is not true). */
1023 if (is_end_of_line
[(unsigned char) c
])
1024 *(--input_line_pointer
) = c
;
1026 demand_empty_rest_of_line ();
1029 /* symbol[:] .set value or .set symbol, value */
1031 tic4x_set (int x ATTRIBUTE_UNUSED
)
1036 if ((symbolP
= line_label
) == NULL
)
1041 name
= input_line_pointer
;
1042 c
= get_symbol_end (); /* Get terminator. */
1045 as_bad (_(".set syntax invalid\n"));
1046 ignore_rest_of_line ();
1049 ++input_line_pointer
;
1050 symbolP
= symbol_find_or_make (name
);
1053 symbol_table_insert (symbolP
);
1055 pseudo_set (symbolP
);
1056 demand_empty_rest_of_line ();
1059 /* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
1061 tic4x_usect (int x ATTRIBUTE_UNUSED
)
1067 offsetT size
, alignment_flag
;
1069 subsegT current_subseg
;
1071 current_seg
= now_seg
; /* save current seg. */
1072 current_subseg
= now_subseg
; /* save current subseg. */
1075 if (*input_line_pointer
== '"')
1076 input_line_pointer
++;
1077 section_name
= input_line_pointer
;
1078 c
= get_symbol_end (); /* Get terminator. */
1079 input_line_pointer
++; /* Skip null symbol terminator. */
1080 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1081 strcpy (name
, section_name
);
1084 input_line_pointer
=
1085 tic4x_expression_abs (input_line_pointer
, &size
);
1086 else if (*input_line_pointer
== ',')
1088 input_line_pointer
=
1089 tic4x_expression_abs (++input_line_pointer
, &size
);
1094 /* Read a possibly present third argument (alignment flag) [VK]. */
1095 if (*input_line_pointer
== ',')
1097 input_line_pointer
=
1098 tic4x_expression_abs (++input_line_pointer
, &alignment_flag
);
1103 as_warn (_(".usect: non-zero alignment flag ignored"));
1105 seg
= subseg_new (name
, 0);
1106 if (line_label
!= NULL
)
1108 S_SET_SEGMENT (line_label
, seg
);
1109 symbol_set_frag (line_label
, frag_now
);
1110 S_SET_VALUE (line_label
, frag_now_fix ());
1112 seg_info (seg
)->bss
= 1; /* Uninitialised data. */
1113 if (!bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
))
1114 as_warn (_("Error setting flags for \"%s\": %s"), name
,
1115 bfd_errmsg (bfd_get_error ()));
1116 tic4x_seg_alloc (name
, seg
, size
, line_label
);
1118 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1119 S_SET_STORAGE_CLASS (line_label
, C_STAT
);
1121 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
1122 demand_empty_rest_of_line ();
1125 /* .version cpu-version. */
1127 tic4x_version (int x ATTRIBUTE_UNUSED
)
1131 input_line_pointer
=
1132 tic4x_expression_abs (input_line_pointer
, &temp
);
1133 if (!IS_CPU_TIC3X (temp
) && !IS_CPU_TIC4X (temp
))
1134 as_bad (_("This assembler does not support processor generation %ld"),
1137 if (tic4x_cpu
&& temp
!= (offsetT
) tic4x_cpu
)
1138 as_warn (_("Changing processor generation on fly not supported..."));
1140 demand_empty_rest_of_line ();
1144 tic4x_init_regtable (void)
1148 for (i
= 0; i
< tic3x_num_registers
; i
++)
1149 tic4x_insert_reg (tic3x_registers
[i
].name
,
1150 tic3x_registers
[i
].regno
);
1152 if (IS_CPU_TIC4X (tic4x_cpu
))
1154 /* Add additional Tic4x registers, overriding some C3x ones. */
1155 for (i
= 0; i
< tic4x_num_registers
; i
++)
1156 tic4x_insert_reg (tic4x_registers
[i
].name
,
1157 tic4x_registers
[i
].regno
);
1162 tic4x_init_symbols (void)
1164 /* The TI tools accept case insensitive versions of these symbols,
1169 .TMS320xx 30,31,32,40,or 44 set according to -v flag
1170 .C3X or .C3x 1 or 0 1 if -v30,-v31,or -v32
1171 .C30 1 or 0 1 if -v30
1172 .C31 1 or 0 1 if -v31
1173 .C32 1 or 0 1 if -v32
1174 .C4X or .C4x 1 or 0 1 if -v40, or -v44
1175 .C40 1 or 0 1 if -v40
1176 .C44 1 or 0 1 if -v44
1178 .REGPARM 1 or 0 1 if -mr option used
1179 .BIGMODEL 1 or 0 1 if -mb option used
1181 These symbols are currently supported but will be removed in a
1183 .TMS320C30 1 or 0 1 if -v30,-v31,or -v32
1184 .TMS320C31 1 or 0 1 if -v31
1185 .TMS320C32 1 or 0 1 if -v32
1186 .TMS320C40 1 or 0 1 if -v40, or -v44
1187 .TMS320C44 1 or 0 1 if -v44
1189 Source: TI: TMS320C3x/C4x Assembly Language Tools User's Guide,
1190 1997, SPRU035C, p. 3-17/3-18. */
1191 tic4x_insert_sym (".REGPARM", tic4x_reg_args
);
1192 tic4x_insert_sym (".MEMPARM", !tic4x_reg_args
);
1193 tic4x_insert_sym (".BIGMODEL", tic4x_big_model
);
1194 tic4x_insert_sym (".C30INTERRUPT", 0);
1195 tic4x_insert_sym (".TMS320xx", tic4x_cpu
== 0 ? 40 : tic4x_cpu
);
1196 tic4x_insert_sym (".C3X", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1197 tic4x_insert_sym (".C3x", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1198 tic4x_insert_sym (".C4X", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1199 tic4x_insert_sym (".C4x", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1200 /* Do we need to have the following symbols also in lower case? */
1201 tic4x_insert_sym (".TMS320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1202 tic4x_insert_sym (".tms320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1203 tic4x_insert_sym (".TMS320C31", tic4x_cpu
== 31);
1204 tic4x_insert_sym (".tms320C31", tic4x_cpu
== 31);
1205 tic4x_insert_sym (".TMS320C32", tic4x_cpu
== 32);
1206 tic4x_insert_sym (".tms320C32", tic4x_cpu
== 32);
1207 tic4x_insert_sym (".TMS320C33", tic4x_cpu
== 33);
1208 tic4x_insert_sym (".tms320C33", tic4x_cpu
== 33);
1209 tic4x_insert_sym (".TMS320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1210 tic4x_insert_sym (".tms320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1211 tic4x_insert_sym (".TMS320C44", tic4x_cpu
== 44);
1212 tic4x_insert_sym (".tms320C44", tic4x_cpu
== 44);
1213 tic4x_insert_sym (".TMX320C40", 0); /* C40 first pass silicon ? */
1214 tic4x_insert_sym (".tmx320C40", 0);
1217 /* Insert a new instruction template into hash table. */
1219 tic4x_inst_insert (const tic4x_inst_t
*inst
)
1221 static char prev_name
[16];
1222 const char *retval
= NULL
;
1224 /* Only insert the first name if have several similar entries. */
1225 if (!strcmp (inst
->name
, prev_name
) || inst
->name
[0] == '\0')
1228 retval
= hash_insert (tic4x_op_hash
, inst
->name
, (void *) inst
);
1230 fprintf (stderr
, "internal error: can't hash `%s': %s\n",
1231 inst
->name
, retval
);
1233 strcpy (prev_name
, inst
->name
);
1234 return retval
== NULL
;
1237 /* Make a new instruction template. */
1238 static tic4x_inst_t
*
1239 tic4x_inst_make (char *name
, unsigned long opcode
, char *args
)
1241 static tic4x_inst_t
*insts
= NULL
;
1242 static char *names
= NULL
;
1243 static int iindex
= 0;
1247 /* Allocate memory to store name strings. */
1248 names
= (char *) xmalloc (sizeof (char) * 8192);
1249 /* Allocate memory for additional insts. */
1250 insts
= (tic4x_inst_t
*)
1251 xmalloc (sizeof (tic4x_inst_t
) * 1024);
1253 insts
[iindex
].name
= names
;
1254 insts
[iindex
].opcode
= opcode
;
1255 insts
[iindex
].opmask
= 0xffffffff;
1256 insts
[iindex
].args
= args
;
1264 return &insts
[iindex
- 1];
1267 /* Add instruction template, creating dynamic templates as required. */
1269 tic4x_inst_add (const tic4x_inst_t
*insts
)
1271 char *s
= insts
->name
;
1279 /* We do not care about INSNs that is not a part of our
1281 if ((insts
->oplevel
& tic4x_oplevel
) == 0)
1290 /* Dynamically create all the conditional insts. */
1291 for (i
= 0; i
< tic4x_num_conds
; i
++)
1295 char *c
= tic4x_conds
[i
].name
;
1305 /* If instruction found then have already processed it. */
1306 if (hash_find (tic4x_op_hash
, name
))
1311 inst
= tic4x_inst_make (name
, insts
[k
].opcode
+
1312 (tic4x_conds
[i
].cond
<<
1313 (*s
== 'B' ? 16 : 23)),
1315 if (k
== 0) /* Save strcmp() with following func. */
1316 ok
&= tic4x_inst_insert (inst
);
1319 while (!strcmp (insts
->name
,
1326 return tic4x_inst_insert (insts
);
1336 /* This function is called once, at assembler startup time. It should
1337 set up all the tables, etc., that the MD part of the assembler will
1345 /* Setup the proper opcode level according to the
1346 commandline parameters */
1347 tic4x_oplevel
= OP_C3X
;
1349 if ( IS_CPU_TIC4X(tic4x_cpu
) )
1350 tic4x_oplevel
|= OP_C4X
;
1352 if ( ( tic4x_cpu
== 31 && tic4x_revision
>= 6)
1353 || (tic4x_cpu
== 32 && tic4x_revision
>= 2)
1354 || (tic4x_cpu
== 33)
1356 tic4x_oplevel
|= OP_ENH
;
1358 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1359 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1360 || (tic4x_cpu
== 32)
1362 tic4x_oplevel
|= OP_LPWR
;
1364 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1365 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1366 || (tic4x_cpu
== 32)
1367 || (tic4x_cpu
== 33)
1368 || (tic4x_cpu
== 40 && tic4x_revision
>= 5)
1369 || (tic4x_cpu
== 44)
1371 tic4x_oplevel
|= OP_IDLE2
;
1373 /* Create hash table for mnemonics. */
1374 tic4x_op_hash
= hash_new ();
1376 /* Create hash table for asg pseudo. */
1377 tic4x_asg_hash
= hash_new ();
1379 /* Add mnemonics to hash table, expanding conditional mnemonics on fly. */
1380 for (i
= 0; i
< tic4x_num_insts
; i
++)
1381 ok
&= tic4x_inst_add (tic4x_insts
+ i
);
1383 /* Create dummy inst to avoid errors accessing end of table. */
1384 tic4x_inst_make ("", 0, "");
1387 as_fatal ("Broken assembler. No assembly attempted.");
1389 /* Add registers to symbol table. */
1390 tic4x_init_regtable ();
1392 /* Add predefined symbols to symbol table. */
1393 tic4x_init_symbols ();
1399 bfd_set_arch_mach (stdoutput
, bfd_arch_tic4x
,
1400 IS_CPU_TIC4X (tic4x_cpu
) ? bfd_mach_tic4x
: bfd_mach_tic3x
);
1404 tic4x_indirect_parse (tic4x_operand_t
*operand
,
1405 const tic4x_indirect_t
*indirect
)
1407 char *n
= indirect
->name
;
1408 char *s
= input_line_pointer
;
1418 case 'a': /* Need to match aux register. */
1420 #ifdef TIC4X_ALT_SYNTAX
1424 while (ISALNUM (*s
))
1427 if (!(symbolP
= symbol_find (name
)))
1430 if (S_GET_SEGMENT (symbolP
) != reg_section
)
1433 operand
->aregno
= S_GET_VALUE (symbolP
);
1434 if (operand
->aregno
>= REG_AR0
&& operand
->aregno
<= REG_AR7
)
1437 as_bad (_("Auxiliary register AR0--AR7 required for indirect"));
1440 case 'd': /* Need to match constant for disp. */
1441 #ifdef TIC4X_ALT_SYNTAX
1442 if (*s
== '%') /* expr() will die if we don't skip this. */
1445 s
= tic4x_expression (s
, &operand
->expr
);
1446 if (operand
->expr
.X_op
!= O_constant
)
1448 operand
->disp
= operand
->expr
.X_add_number
;
1449 if (operand
->disp
< 0 || operand
->disp
> 255)
1451 as_bad (_("Bad displacement %d (require 0--255)\n"),
1457 case 'y': /* Need to match IR0. */
1458 case 'z': /* Need to match IR1. */
1459 #ifdef TIC4X_ALT_SYNTAX
1463 s
= tic4x_expression (s
, &operand
->expr
);
1464 if (operand
->expr
.X_op
!= O_register
)
1466 if (operand
->expr
.X_add_number
!= REG_IR0
1467 && operand
->expr
.X_add_number
!= REG_IR1
)
1469 as_bad (_("Index register IR0,IR1 required for displacement"));
1473 if (*n
== 'y' && operand
->expr
.X_add_number
== REG_IR0
)
1475 if (*n
== 'z' && operand
->expr
.X_add_number
== REG_IR1
)
1480 if (*s
!= '(') /* No displacement, assume to be 1. */
1491 if (TOLOWER (*s
) != *n
)
1496 if (*s
!= ' ' && *s
!= ',' && *s
!= '\0')
1498 input_line_pointer
= s
;
1503 tic4x_operand_parse (char *s
, tic4x_operand_t
*operand
)
1508 expressionS
*exp
= &operand
->expr
;
1509 char *save
= input_line_pointer
;
1512 struct hash_entry
*entry
= NULL
;
1514 input_line_pointer
= s
;
1517 str
= input_line_pointer
;
1518 c
= get_symbol_end (); /* Get terminator. */
1519 new_pointer
= input_line_pointer
;
1520 if (strlen (str
) && (entry
= hash_find (tic4x_asg_hash
, str
)) != NULL
)
1522 *input_line_pointer
= c
;
1523 input_line_pointer
= (char *) entry
;
1527 *input_line_pointer
= c
;
1528 input_line_pointer
= str
;
1531 operand
->mode
= M_UNKNOWN
;
1532 switch (*input_line_pointer
)
1534 #ifdef TIC4X_ALT_SYNTAX
1536 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1537 if (exp
->X_op
!= O_register
)
1538 as_bad (_("Expecting a register name"));
1539 operand
->mode
= M_REGISTER
;
1543 /* Denotes high 16 bits. */
1544 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1545 if (exp
->X_op
== O_constant
)
1546 operand
->mode
= M_IMMED
;
1547 else if (exp
->X_op
== O_big
)
1549 if (exp
->X_add_number
)
1550 as_bad (_("Number too large")); /* bignum required */
1553 tic4x_gen_to_words (generic_floating_point_number
,
1554 operand
->fwords
, S_PRECISION
);
1555 operand
->mode
= M_IMMED_F
;
1558 /* Allow ori ^foo, ar0 to be equivalent to ldi .hi.foo, ar0 */
1559 /* WARNING : The TI C40 assembler cannot do this. */
1560 else if (exp
->X_op
== O_symbol
)
1562 operand
->mode
= M_HI
;
1567 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1568 if (exp
->X_op
== O_constant
)
1569 operand
->mode
= M_IMMED
;
1570 else if (exp
->X_op
== O_big
)
1572 if (exp
->X_add_number
> 0)
1573 as_bad (_("Number too large")); /* bignum required. */
1576 tic4x_gen_to_words (generic_floating_point_number
,
1577 operand
->fwords
, S_PRECISION
);
1578 operand
->mode
= M_IMMED_F
;
1581 /* Allow ori foo, ar0 to be equivalent to ldi .lo.foo, ar0 */
1582 /* WARNING : The TI C40 assembler cannot do this. */
1583 else if (exp
->X_op
== O_symbol
)
1585 operand
->mode
= M_IMMED
;
1590 as_bad (_("Expecting a constant value"));
1595 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1596 if (exp
->X_op
!= O_constant
&& exp
->X_op
!= O_symbol
)
1597 as_bad (_("Bad direct addressing construct %s"), s
);
1598 if (exp
->X_op
== O_constant
)
1600 if (exp
->X_add_number
< 0)
1601 as_bad (_("Direct value of %ld is not suitable"),
1602 (long) exp
->X_add_number
);
1604 operand
->mode
= M_DIRECT
;
1609 for (i
= 0; i
< tic4x_num_indirects
; i
++)
1610 if ((ret
= tic4x_indirect_parse (operand
, &tic4x_indirects
[i
])))
1614 if (i
< tic4x_num_indirects
)
1616 operand
->mode
= M_INDIRECT
;
1617 /* Indirect addressing mode number. */
1618 operand
->expr
.X_add_number
= tic4x_indirects
[i
].modn
;
1619 /* Convert *+ARn(0) to *ARn etc. Maybe we should
1620 squeal about silly ones? */
1621 if (operand
->expr
.X_add_number
< 0x08 && !operand
->disp
)
1622 operand
->expr
.X_add_number
= 0x18;
1625 as_bad (_("Unknown indirect addressing mode"));
1629 operand
->mode
= M_IMMED
; /* Assume immediate. */
1630 str
= input_line_pointer
;
1631 input_line_pointer
= tic4x_expression (input_line_pointer
, exp
);
1632 if (exp
->X_op
== O_register
)
1634 know (exp
->X_add_symbol
== 0);
1635 know (exp
->X_op_symbol
== 0);
1636 operand
->mode
= M_REGISTER
;
1639 else if (exp
->X_op
== O_big
)
1641 if (exp
->X_add_number
> 0)
1642 as_bad (_("Number too large")); /* bignum required. */
1645 tic4x_gen_to_words (generic_floating_point_number
,
1646 operand
->fwords
, S_PRECISION
);
1647 operand
->mode
= M_IMMED_F
;
1651 #ifdef TIC4X_ALT_SYNTAX
1652 /* Allow ldi foo, ar0 to be equivalent to ldi @foo, ar0. */
1653 else if (exp
->X_op
== O_symbol
)
1655 operand
->mode
= M_DIRECT
;
1661 new_pointer
= input_line_pointer
;
1662 input_line_pointer
= save
;
1667 tic4x_operands_match (tic4x_inst_t
*inst
, tic4x_insn_t
*tinsn
, int check
)
1669 const char *args
= inst
->args
;
1670 unsigned long opcode
= inst
->opcode
;
1671 int num_operands
= tinsn
->num_operands
;
1672 tic4x_operand_t
*operand
= tinsn
->operands
;
1673 expressionS
*exp
= &operand
->expr
;
1677 /* Build the opcode, checking as we go to make sure that the
1680 If an operand matches, we modify insn or opcode appropriately,
1681 and do a "continue". If an operand fails to match, we "break". */
1683 tinsn
->nchars
= 4; /* Instructions always 4 bytes. */
1684 tinsn
->reloc
= NO_RELOC
;
1689 tinsn
->opcode
= opcode
;
1690 return num_operands
== 0;
1698 case '\0': /* End of args. */
1699 if (num_operands
== 1)
1701 tinsn
->opcode
= opcode
;
1704 break; /* Too many operands. */
1706 case '#': /* This is only used for ldp. */
1707 if (operand
->mode
!= M_DIRECT
&& operand
->mode
!= M_IMMED
)
1709 /* While this looks like a direct addressing mode, we actually
1710 use an immediate mode form of ldiu or ldpk instruction. */
1711 if (exp
->X_op
== O_constant
)
1713 if( ( IS_CPU_TIC4X (tic4x_cpu
) && exp
->X_add_number
<= 65535 )
1714 || ( IS_CPU_TIC3X (tic4x_cpu
) && exp
->X_add_number
<= 255 ) )
1716 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1722 as_bad (_("Immediate value of %ld is too large for ldf"),
1723 (long) exp
->X_add_number
);
1728 else if (exp
->X_op
== O_symbol
)
1730 tinsn
->reloc
= BFD_RELOC_HI16
;
1734 break; /* Not direct (dp) addressing. */
1736 case '@': /* direct. */
1737 if (operand
->mode
!= M_DIRECT
)
1739 if (exp
->X_op
== O_constant
)
1741 /* Store only the 16 LSBs of the number. */
1742 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1745 else if (exp
->X_op
== O_symbol
)
1747 tinsn
->reloc
= BFD_RELOC_LO16
;
1751 break; /* Not direct addressing. */
1754 if (operand
->mode
!= M_REGISTER
)
1756 reg
= exp
->X_add_number
;
1757 if (reg
>= REG_AR0
&& reg
<= REG_AR7
)
1758 INSERTU (opcode
, reg
- REG_AR0
, 24, 22);
1762 as_bad (_("Destination register must be ARn"));
1767 case 'B': /* Unsigned integer immediate. */
1768 /* Allow br label or br @label. */
1769 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
1771 if (exp
->X_op
== O_constant
)
1773 if (exp
->X_add_number
< (1 << 24))
1775 INSERTU (opcode
, exp
->X_add_number
, 23, 0);
1781 as_bad (_("Immediate value of %ld is too large"),
1782 (long) exp
->X_add_number
);
1787 if (IS_CPU_TIC4X (tic4x_cpu
))
1789 tinsn
->reloc
= BFD_RELOC_24_PCREL
;
1794 tinsn
->reloc
= BFD_RELOC_24
;
1801 if (!IS_CPU_TIC4X (tic4x_cpu
))
1803 if (operand
->mode
!= M_INDIRECT
)
1805 /* Require either *+ARn(disp) or *ARn. */
1806 if (operand
->expr
.X_add_number
!= 0
1807 && operand
->expr
.X_add_number
!= 0x18)
1810 as_bad (_("Invalid indirect addressing mode"));
1814 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1815 INSERTU (opcode
, operand
->disp
, 7, 3);
1819 if (!(operand
->mode
== M_REGISTER
))
1821 INSERTU (opcode
, exp
->X_add_number
, 7, 0);
1825 if (!(operand
->mode
== M_REGISTER
))
1827 reg
= exp
->X_add_number
;
1828 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1829 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1830 INSERTU (opcode
, reg
, 7, 0);
1834 as_bad (_("Register must be Rn"));
1840 if (operand
->mode
!= M_IMMED_F
1841 && !(operand
->mode
== M_IMMED
&& exp
->X_op
== O_constant
))
1844 if (operand
->mode
!= M_IMMED_F
)
1846 /* OK, we 've got something like cmpf 0, r0
1847 Why can't they stick in a bloody decimal point ?! */
1850 /* Create floating point number string. */
1851 sprintf (string
, "%d.0", (int) exp
->X_add_number
);
1852 tic4x_atof (string
, 's', operand
->fwords
);
1855 INSERTU (opcode
, operand
->fwords
[0], 15, 0);
1859 if (operand
->mode
!= M_REGISTER
)
1861 INSERTU (opcode
, exp
->X_add_number
, 15, 8);
1865 if (operand
->mode
!= M_REGISTER
)
1867 reg
= exp
->X_add_number
;
1868 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1869 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1870 INSERTU (opcode
, reg
, 15, 8);
1874 as_bad (_("Register must be Rn"));
1880 if (operand
->mode
!= M_REGISTER
)
1882 reg
= exp
->X_add_number
;
1883 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1884 INSERTU (opcode
, reg
- REG_R0
, 18, 16);
1888 as_bad (_("Register must be R0--R7"));
1894 if ( operand
->mode
== M_REGISTER
1895 && tic4x_oplevel
& OP_ENH
)
1897 reg
= exp
->X_add_number
;
1898 INSERTU (opcode
, reg
, 4, 0);
1899 INSERTU (opcode
, 7, 7, 5);
1905 if (operand
->mode
!= M_INDIRECT
)
1907 if (operand
->disp
!= 0 && operand
->disp
!= 1)
1909 if (IS_CPU_TIC4X (tic4x_cpu
))
1912 as_bad (_("Invalid indirect addressing mode displacement %d"),
1917 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1918 INSERTU (opcode
, operand
->expr
.X_add_number
, 7, 3);
1922 if ( operand
->mode
== M_REGISTER
1923 && tic4x_oplevel
& OP_ENH
)
1925 reg
= exp
->X_add_number
;
1926 INSERTU (opcode
, reg
, 12, 8);
1927 INSERTU (opcode
, 7, 15, 13);
1933 if (operand
->mode
!= M_INDIRECT
)
1935 if (operand
->disp
!= 0 && operand
->disp
!= 1)
1937 if (IS_CPU_TIC4X (tic4x_cpu
))
1940 as_bad (_("Invalid indirect addressing mode displacement %d"),
1945 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
1946 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
1950 if (operand
->mode
!= M_REGISTER
)
1952 reg
= exp
->X_add_number
;
1953 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1954 INSERTU (opcode
, reg
- REG_R0
, 21, 19);
1958 as_bad (_("Register must be R0--R7"));
1964 if (operand
->mode
!= M_REGISTER
)
1966 reg
= exp
->X_add_number
;
1967 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1968 INSERTU (opcode
, reg
- REG_R0
, 24, 22);
1972 as_bad (_("Register must be R0--R7"));
1978 if (operand
->mode
!= M_REGISTER
)
1980 reg
= exp
->X_add_number
;
1981 if (reg
== REG_R2
|| reg
== REG_R3
)
1982 INSERTU (opcode
, reg
- REG_R2
, 22, 22);
1986 as_bad (_("Destination register must be R2 or R3"));
1992 if (operand
->mode
!= M_REGISTER
)
1994 reg
= exp
->X_add_number
;
1995 if (reg
== REG_R0
|| reg
== REG_R1
)
1996 INSERTU (opcode
, reg
- REG_R0
, 23, 23);
2000 as_bad (_("Destination register must be R0 or R1"));
2006 if (!IS_CPU_TIC4X (tic4x_cpu
))
2008 if (operand
->mode
!= M_INDIRECT
)
2010 /* Require either *+ARn(disp) or *ARn. */
2011 if (operand
->expr
.X_add_number
!= 0
2012 && operand
->expr
.X_add_number
!= 0x18)
2015 as_bad (_("Invalid indirect addressing mode"));
2019 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2020 INSERTU (opcode
, operand
->disp
, 15, 11);
2023 case 'P': /* PC relative displacement. */
2024 /* Allow br label or br @label. */
2025 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
2027 if (exp
->X_op
== O_constant
)
2029 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 32767)
2031 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2037 as_bad (_("Displacement value of %ld is too large"),
2038 (long) exp
->X_add_number
);
2043 tinsn
->reloc
= BFD_RELOC_16_PCREL
;
2049 if (operand
->mode
!= M_REGISTER
)
2051 reg
= exp
->X_add_number
;
2052 INSERTU (opcode
, reg
, 15, 0);
2056 if (operand
->mode
!= M_REGISTER
)
2058 reg
= exp
->X_add_number
;
2059 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2060 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2061 INSERTU (opcode
, reg
, 15, 0);
2065 as_bad (_("Register must be Rn"));
2071 if (operand
->mode
!= M_REGISTER
)
2073 reg
= exp
->X_add_number
;
2074 INSERTU (opcode
, reg
, 20, 16);
2078 if (operand
->mode
!= M_REGISTER
)
2080 reg
= exp
->X_add_number
;
2081 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2082 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2083 INSERTU (opcode
, reg
, 20, 16);
2087 as_bad (_("Register must be Rn"));
2092 case 'S': /* Short immediate int. */
2093 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2095 if (exp
->X_op
== O_big
)
2098 as_bad (_("Floating point number not valid in expression"));
2102 if (exp
->X_op
== O_constant
)
2104 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 65535)
2106 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2112 as_bad (_("Signed immediate value %ld too large"),
2113 (long) exp
->X_add_number
);
2118 else if (exp
->X_op
== O_symbol
)
2120 if (operand
->mode
== M_HI
)
2122 tinsn
->reloc
= BFD_RELOC_HI16
;
2126 tinsn
->reloc
= BFD_RELOC_LO16
;
2131 /* Handle cases like ldi foo - $, ar0 where foo
2132 is a forward reference. Perhaps we should check
2133 for X_op == O_symbol and disallow things like
2135 tinsn
->reloc
= BFD_RELOC_16
;
2139 case 'T': /* 5-bit immediate value for tic4x stik. */
2140 if (!IS_CPU_TIC4X (tic4x_cpu
))
2142 if (operand
->mode
!= M_IMMED
)
2144 if (exp
->X_op
== O_constant
)
2146 if (exp
->X_add_number
< 16 && exp
->X_add_number
>= -16)
2148 INSERTS (opcode
, exp
->X_add_number
, 20, 16);
2154 as_bad (_("Immediate value of %ld is too large"),
2155 (long) exp
->X_add_number
);
2160 break; /* No relocations allowed. */
2162 case 'U': /* Unsigned integer immediate. */
2163 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2165 if (exp
->X_op
== O_constant
)
2167 if (exp
->X_add_number
< (1 << 16) && exp
->X_add_number
>= 0)
2169 INSERTU (opcode
, exp
->X_add_number
, 15, 0);
2175 as_bad (_("Unsigned immediate value %ld too large"),
2176 (long) exp
->X_add_number
);
2181 else if (exp
->X_op
== O_symbol
)
2183 if (operand
->mode
== M_HI
)
2184 tinsn
->reloc
= BFD_RELOC_HI16
;
2186 tinsn
->reloc
= BFD_RELOC_LO16
;
2191 tinsn
->reloc
= BFD_RELOC_16
;
2195 case 'V': /* Trap numbers (immediate field). */
2196 if (operand
->mode
!= M_IMMED
)
2198 if (exp
->X_op
== O_constant
)
2200 if (exp
->X_add_number
< 512 && IS_CPU_TIC4X (tic4x_cpu
))
2202 INSERTU (opcode
, exp
->X_add_number
, 8, 0);
2205 else if (exp
->X_add_number
< 32 && IS_CPU_TIC3X (tic4x_cpu
))
2207 INSERTU (opcode
, exp
->X_add_number
| 0x20, 4, 0);
2213 as_bad (_("Immediate value of %ld is too large"),
2214 (long) exp
->X_add_number
);
2219 break; /* No relocations allowed. */
2221 case 'W': /* Short immediate int (0--7). */
2222 if (!IS_CPU_TIC4X (tic4x_cpu
))
2224 if (operand
->mode
!= M_IMMED
)
2226 if (exp
->X_op
== O_big
)
2229 as_bad (_("Floating point number not valid in expression"));
2233 if (exp
->X_op
== O_constant
)
2235 if (exp
->X_add_number
>= -256 && exp
->X_add_number
<= 127)
2237 INSERTS (opcode
, exp
->X_add_number
, 7, 0);
2243 as_bad (_("Immediate value %ld too large"),
2244 (long) exp
->X_add_number
);
2249 tinsn
->reloc
= BFD_RELOC_16
;
2253 case 'X': /* Expansion register for tic4x. */
2254 if (operand
->mode
!= M_REGISTER
)
2256 reg
= exp
->X_add_number
;
2257 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2258 INSERTU (opcode
, reg
- REG_IVTP
, 4, 0);
2262 as_bad (_("Register must be ivtp or tvtp"));
2267 case 'Y': /* Address register for tic4x lda. */
2268 if (operand
->mode
!= M_REGISTER
)
2270 reg
= exp
->X_add_number
;
2271 if (reg
>= REG_AR0
&& reg
<= REG_SP
)
2272 INSERTU (opcode
, reg
, 20, 16);
2276 as_bad (_("Register must be address register"));
2281 case 'Z': /* Expansion register for tic4x. */
2282 if (operand
->mode
!= M_REGISTER
)
2284 reg
= exp
->X_add_number
;
2285 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2286 INSERTU (opcode
, reg
- REG_IVTP
, 20, 16);
2290 as_bad (_("Register must be ivtp or tvtp"));
2296 if (operand
->mode
!= M_INDIRECT
)
2298 INSERTS (opcode
, operand
->disp
, 7, 0);
2299 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2300 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
2303 case '|': /* treat as `,' if have ldi_ldi form. */
2304 if (tinsn
->parallel
)
2306 if (--num_operands
< 0)
2307 break; /* Too few operands. */
2309 if (operand
->mode
!= M_PARALLEL
)
2314 case ',': /* Another operand. */
2315 if (--num_operands
< 0)
2316 break; /* Too few operands. */
2318 exp
= &operand
->expr
;
2321 case ';': /* Another optional operand. */
2322 if (num_operands
== 1 || operand
[1].mode
== M_PARALLEL
)
2324 if (--num_operands
< 0)
2325 break; /* Too few operands. */
2327 exp
= &operand
->expr
;
2338 tic4x_insn_check (tic4x_insn_t
*tinsn
)
2341 if (!strcmp (tinsn
->name
, "lda"))
2343 if (tinsn
->num_operands
< 2 || tinsn
->num_operands
> 2)
2344 as_fatal ("Illegal internal LDA insn definition");
2346 if (tinsn
->operands
[0].mode
== M_REGISTER
2347 && tinsn
->operands
[1].mode
== M_REGISTER
2348 && tinsn
->operands
[0].expr
.X_add_number
== tinsn
->operands
[1].expr
.X_add_number
)
2349 as_bad (_("Source and destination register should not be equal"));
2351 else if (!strcmp (tinsn
->name
, "ldi_ldi")
2352 || !strcmp (tinsn
->name
, "ldi1_ldi2")
2353 || !strcmp (tinsn
->name
, "ldi2_ldi1")
2354 || !strcmp (tinsn
->name
, "ldf_ldf")
2355 || !strcmp (tinsn
->name
, "ldf1_ldf2")
2356 || !strcmp (tinsn
->name
, "ldf2_ldf1") )
2358 if (tinsn
->num_operands
< 4 && tinsn
->num_operands
> 5 )
2359 as_fatal ("Illegal internal %s insn definition", tinsn
->name
);
2361 if (tinsn
->operands
[1].mode
== M_REGISTER
2362 && tinsn
->operands
[tinsn
->num_operands
-1].mode
== M_REGISTER
2363 && tinsn
->operands
[1].expr
.X_add_number
== tinsn
->operands
[tinsn
->num_operands
-1].expr
.X_add_number
)
2364 as_warn (_("Equal parallell destination registers, one result will be discarded"));
2369 tic4x_insn_output (tic4x_insn_t
*tinsn
)
2373 /* Grab another fragment for opcode. */
2374 dst
= frag_more (tinsn
->nchars
);
2376 /* Put out opcode word as a series of bytes in little endian order. */
2377 md_number_to_chars (dst
, tinsn
->opcode
, tinsn
->nchars
);
2379 /* Put out the symbol-dependent stuff. */
2380 if (tinsn
->reloc
!= NO_RELOC
)
2382 /* Where is the offset into the fragment for this instruction. */
2383 fix_new_exp (frag_now
,
2384 dst
- frag_now
->fr_literal
, /* where */
2385 tinsn
->nchars
, /* size */
2392 /* Parse the operands. */
2394 tic4x_operands_parse (char *s
, tic4x_operand_t
*operands
, int num_operands
)
2397 return num_operands
;
2400 s
= tic4x_operand_parse (s
, &operands
[num_operands
++]);
2401 while (num_operands
< TIC4X_OPERANDS_MAX
&& *s
++ == ',');
2403 if (num_operands
> TIC4X_OPERANDS_MAX
)
2405 as_bad (_("Too many operands scanned"));
2408 return num_operands
;
2411 /* Assemble a single instruction. Its label has already been handled
2412 by the generic front end. We just parse mnemonic and operands, and
2413 produce the bytes of data and relocation. */
2415 md_assemble (char *str
)
2421 tic4x_inst_t
*inst
; /* Instruction template. */
2422 tic4x_inst_t
*first_inst
;
2424 /* Scan for parallel operators */
2428 while (*s
&& *s
!= '|')
2431 if (*s
&& s
[1]=='|')
2435 as_bad (_("Parallel opcode cannot contain more than two instructions"));
2441 /* Lets take care of the first part of the parallel insn */
2446 /* .. and let the second run though here */
2450 if (str
&& insn
->parallel
)
2452 /* Find mnemonic (second part of parallel instruction). */
2454 /* Skip past instruction mnemonic. */
2455 while (*s
&& *s
!= ' ')
2457 if (*s
) /* Null terminate for hash_find. */
2458 *s
++ = '\0'; /* and skip past null. */
2459 strcat (insn
->name
, "_");
2460 strncat (insn
->name
, str
, TIC4X_NAME_MAX
- strlen (insn
->name
));
2462 insn
->operands
[insn
->num_operands
++].mode
= M_PARALLEL
;
2464 if ((i
= tic4x_operands_parse
2465 (s
, insn
->operands
, insn
->num_operands
)) < 0)
2471 insn
->num_operands
= i
;
2477 if ((insn
->inst
= (struct tic4x_inst
*)
2478 hash_find (tic4x_op_hash
, insn
->name
)) == NULL
)
2480 as_bad (_("Unknown opcode `%s'."), insn
->name
);
2490 ok
= tic4x_operands_match (inst
, insn
, 1);
2497 } while (!ok
&& !strcmp (inst
->name
, inst
[1].name
) && inst
++);
2501 tic4x_insn_check (insn
);
2502 tic4x_insn_output (insn
);
2507 tic4x_operands_match (first_inst
, insn
, 0);
2508 as_bad (_("Invalid operands for %s"), insn
->name
);
2511 as_bad (_("Invalid instruction %s"), insn
->name
);
2516 /* Find mnemonic. */
2518 while (*s
&& *s
!= ' ') /* Skip past instruction mnemonic. */
2520 if (*s
) /* Null terminate for hash_find. */
2521 *s
++ = '\0'; /* and skip past null. */
2522 strncpy (insn
->name
, str
, TIC4X_NAME_MAX
- 3);
2524 if ((i
= tic4x_operands_parse (s
, insn
->operands
, 0)) < 0)
2526 insn
->inst
= NULL
; /* Flag that error occurred. */
2531 insn
->num_operands
= i
;
2540 tic4x_cleanup (void)
2546 /* Turn a string in input_line_pointer into a floating point constant
2547 of type type, and store the appropriate bytes in *litP. The number
2548 of chars emitted is stored in *sizeP. An error message is
2549 returned, or NULL on OK. */
2552 md_atof (int type
, char *litP
, int *sizeP
)
2556 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2557 LITTLENUM_TYPE
*wordP
;
2562 case 's': /* .single */
2568 case 'd': /* .double */
2570 case 'f': /* .float */
2573 prec
= 2; /* 1 32-bit word */
2576 case 'i': /* .ieee */
2580 type
= 'f'; /* Rewrite type to be usable by atof_ieee(). */
2583 case 'e': /* .ldouble */
2585 prec
= 4; /* 2 32-bit words */
2591 return _("Unrecognized or unsupported floating point constant");
2595 t
= atof_ieee (input_line_pointer
, type
, words
);
2597 t
= tic4x_atof (input_line_pointer
, type
, words
);
2599 input_line_pointer
= t
;
2600 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
2602 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
2603 little endian byte order. */
2604 /* SES: However it is required to put the words (32-bits) out in the
2605 correct order, hence we write 2 and 2 littlenums in little endian
2606 order, while we keep the original order on successive words. */
2607 for (wordP
= words
; wordP
<(words
+prec
) ; wordP
+=2)
2609 if (wordP
< (words
+ prec
- 1)) /* Dump wordP[1] (if we have one). */
2611 md_number_to_chars (litP
, (valueT
) (wordP
[1]),
2612 sizeof (LITTLENUM_TYPE
));
2613 litP
+= sizeof (LITTLENUM_TYPE
);
2617 md_number_to_chars (litP
, (valueT
) (wordP
[0]),
2618 sizeof (LITTLENUM_TYPE
));
2619 litP
+= sizeof (LITTLENUM_TYPE
);
2625 md_apply_fix (fixS
*fixP
, valueT
*value
, segT seg ATTRIBUTE_UNUSED
)
2627 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
2628 valueT val
= *value
;
2630 switch (fixP
->fx_r_type
)
2632 case BFD_RELOC_HI16
:
2636 case BFD_RELOC_LO16
:
2643 switch (fixP
->fx_r_type
)
2648 case BFD_RELOC_24_PCREL
:
2651 case BFD_RELOC_16_PCREL
:
2652 case BFD_RELOC_LO16
:
2653 case BFD_RELOC_HI16
:
2660 as_bad (_("Bad relocation type: 0x%02x"), fixP
->fx_r_type
);
2664 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0) fixP
->fx_done
= 1;
2667 /* Should never be called for tic4x. */
2669 md_convert_frag (bfd
*headers ATTRIBUTE_UNUSED
,
2670 segT sec ATTRIBUTE_UNUSED
,
2671 fragS
*fragP ATTRIBUTE_UNUSED
)
2673 as_fatal ("md_convert_frag");
2676 /* Should never be called for tic4x. */
2678 md_create_short_jump (char *ptr ATTRIBUTE_UNUSED
,
2679 addressT from_addr ATTRIBUTE_UNUSED
,
2680 addressT to_addr ATTRIBUTE_UNUSED
,
2681 fragS
*frag ATTRIBUTE_UNUSED
,
2682 symbolS
*to_symbol ATTRIBUTE_UNUSED
)
2684 as_fatal ("md_create_short_jmp\n");
2687 /* Should never be called for tic4x. */
2689 md_create_long_jump (char *ptr ATTRIBUTE_UNUSED
,
2690 addressT from_addr ATTRIBUTE_UNUSED
,
2691 addressT to_addr ATTRIBUTE_UNUSED
,
2692 fragS
*frag ATTRIBUTE_UNUSED
,
2693 symbolS
*to_symbol ATTRIBUTE_UNUSED
)
2695 as_fatal ("md_create_long_jump\n");
2698 /* Should never be called for tic4x. */
2700 md_estimate_size_before_relax (fragS
*fragP ATTRIBUTE_UNUSED
,
2701 segT segtype ATTRIBUTE_UNUSED
)
2703 as_fatal ("md_estimate_size_before_relax\n");
2709 md_parse_option (int c
, char *arg
)
2713 case OPTION_CPU
: /* cpu brand */
2714 if (TOLOWER (*arg
) == 'c')
2716 tic4x_cpu
= atoi (arg
);
2717 if (!IS_CPU_TIC3X (tic4x_cpu
) && !IS_CPU_TIC4X (tic4x_cpu
))
2718 as_warn (_("Unsupported processor generation %d"), tic4x_cpu
);
2721 case OPTION_REV
: /* cpu revision */
2722 tic4x_revision
= atoi (arg
);
2726 as_warn (_("Option -b is depreciated, please use -mbig"));
2727 case OPTION_BIG
: /* big model */
2728 tic4x_big_model
= 1;
2732 as_warn (_("Option -p is depreciated, please use -mmemparm"));
2733 case OPTION_MEMPARM
: /* push args */
2738 as_warn (_("Option -r is depreciated, please use -mregparm"));
2739 case OPTION_REGPARM
: /* register args */
2744 as_warn (_("Option -s is depreciated, please use -msmall"));
2745 case OPTION_SMALL
: /* small model */
2746 tic4x_big_model
= 0;
2753 case OPTION_LOWPOWER
:
2757 case OPTION_ENHANCED
:
2769 md_show_usage (FILE *stream
)
2772 _("\nTIC4X options:\n"
2773 " -mcpu=CPU -mCPU select architecture variant. CPU can be:\n"
2775 " 31 - TMS320C31, TMS320LC31\n"
2777 " 33 - TMS320VC33\n"
2780 " -mrev=REV set cpu hardware revision (integer numbers).\n"
2781 " Combinations of -mcpu and -mrev will enable/disable\n"
2782 " the appropriate options (-midle2, -mlowpower and\n"
2783 " -menhanced) according to the selected type\n"
2784 " -mbig select big memory model\n"
2785 " -msmall select small memory model (default)\n"
2786 " -mregparm select register parameters (default)\n"
2787 " -mmemparm select memory parameters\n"
2788 " -midle2 enable IDLE2 support\n"
2789 " -mlowpower enable LOPOWER and MAXSPEED support\n"
2790 " -menhanced enable enhanced opcode support\n"));
2793 /* This is called when a line is unrecognized. This is used to handle
2794 definitions of TI C3x tools style local labels $n where n is a single
2797 tic4x_unrecognized_line (int c
)
2802 if (c
!= '$' || ! ISDIGIT (input_line_pointer
[0]))
2805 s
= input_line_pointer
;
2807 /* Let's allow multiple digit local labels. */
2809 while (ISDIGIT (*s
))
2811 lab
= lab
* 10 + *s
- '0';
2815 if (dollar_label_defined (lab
))
2817 as_bad (_("Label \"$%d\" redefined"), lab
);
2821 define_dollar_label (lab
);
2822 colon (dollar_label_name (lab
, 0));
2823 input_line_pointer
= s
+ 1;
2828 /* Handle local labels peculiar to us referred to in an expression. */
2830 md_undefined_symbol (char *name
)
2832 /* Look for local labels of the form $n. */
2833 if (name
[0] == '$' && ISDIGIT (name
[1]))
2839 while (ISDIGIT ((unsigned char) *s
))
2841 lab
= lab
* 10 + *s
- '0';
2844 if (dollar_label_defined (lab
))
2846 name
= dollar_label_name (lab
, 0);
2847 symbolP
= symbol_find (name
);
2851 name
= dollar_label_name (lab
, 1);
2852 symbolP
= symbol_find_or_make (name
);
2860 /* Parse an operand that is machine-specific. */
2862 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
2866 /* Round up a section size to the appropriate boundary---do we need this? */
2868 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
2870 return size
; /* Byte (i.e., 32-bit) alignment is fine? */
2874 tic4x_pc_offset (unsigned int op
)
2876 /* Determine the PC offset for a C[34]x instruction.
2877 This could be simplified using some boolean algebra
2878 but at the expense of readability. */
2882 case 0x62: /* call (C4x) */
2883 case 0x64: /* rptb (C4x) */
2885 case 0x61: /* brd */
2886 case 0x63: /* laj */
2887 case 0x65: /* rptbd (C4x) */
2889 case 0x66: /* swi */
2896 switch ((op
& 0xffe00000) >> 20)
2898 case 0x6a0: /* bB */
2899 case 0x720: /* callB */
2900 case 0x740: /* trapB */
2903 case 0x6a2: /* bBd */
2904 case 0x6a6: /* bBat */
2905 case 0x6aa: /* bBaf */
2906 case 0x722: /* lajB */
2907 case 0x748: /* latB */
2908 case 0x798: /* rptbd */
2915 switch ((op
& 0xfe200000) >> 20)
2917 case 0x6e0: /* dbB */
2920 case 0x6e2: /* dbBd */
2930 /* Exactly what point is a PC-relative offset relative TO?
2931 With the C3x we have the following:
2932 DBcond, Bcond disp + PC + 1 => PC
2933 DBcondD, BcondD disp + PC + 3 => PC
2936 md_pcrel_from (fixS
*fixP
)
2941 buf
= (unsigned char *) fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2942 op
= (buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
2944 return ((fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) >> 2) +
2945 tic4x_pc_offset (op
);
2948 /* Fill the alignment area with NOP's on .text, unless fill-data
2951 tic4x_do_align (int alignment
,
2956 /* Because we are talking lwords, not bytes, adjust alignment to do words */
2959 if (alignment
!= 0 && !need_pass_2
)
2963 if (subseg_text_p (now_seg
))
2967 md_number_to_chars (nop
, TIC_NOP_OPCODE
, 4);
2968 frag_align_pattern (alignment
, nop
, sizeof (nop
), max
);
2971 frag_align (alignment
, 0, max
);
2974 frag_align (alignment
, *fill
, max
);
2976 frag_align_pattern (alignment
, fill
, len
, max
);
2979 /* Return 1 to skip the default alignment function */
2983 /* Look for and remove parallel instruction operator ||. */
2985 tic4x_start_line (void)
2987 char *s
= input_line_pointer
;
2991 /* If parallel instruction prefix found at start of line, skip it. */
2992 if (*input_line_pointer
== '|' && input_line_pointer
[1] == '|')
2997 input_line_pointer
++;
2998 *input_line_pointer
= ' ';
2999 /* So line counters get bumped. */
3000 input_line_pointer
[-1] = '\n';
3005 /* Write out the previous insn here */
3008 input_line_pointer
= s
;
3013 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixP
)
3017 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
3019 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
3020 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
3021 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
3022 reloc
->address
/= OCTETS_PER_BYTE
;
3023 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
3024 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
3026 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3027 _("Reloc %d not supported by object file format"),
3028 (int) fixP
->fx_r_type
);
3032 if (fixP
->fx_r_type
== BFD_RELOC_HI16
)
3033 reloc
->addend
= fixP
->fx_offset
;
3035 reloc
->addend
= fixP
->fx_addnumber
;