1 /* tc-tic4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
2 Copyright (C) 1997,1998, 2002, 2003, 2005, 2006, 2007
3 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"
51 #include "opcode/tic4x.h"
55 /* OK, we accept a syntax similar to the other well known C30
56 assembly tools. With TIC4X_ALT_SYNTAX defined we are more
57 flexible, allowing a more Unix-like syntax: `%' in front of
58 register names, `#' in front of immediate constants, and
59 not requiring `@' in front of direct addresses. */
61 #define TIC4X_ALT_SYNTAX
63 /* Equal to MAX_PRECISION in atof-ieee.c. */
64 #define MAX_LITTLENUMS 6 /* (12 bytes) */
66 /* Handle of the inst mnemonic hash table. */
67 static struct hash_control
*tic4x_op_hash
= NULL
;
69 /* Handle asg pseudo. */
70 static struct hash_control
*tic4x_asg_hash
= NULL
;
72 static unsigned int tic4x_cpu
= 0; /* Default to TMS320C40. */
73 static unsigned int tic4x_revision
= 0; /* CPU revision */
74 static unsigned int tic4x_idle2
= 0; /* Idle2 support */
75 static unsigned int tic4x_lowpower
= 0; /* Lowpower support */
76 static unsigned int tic4x_enhanced
= 0; /* Enhanced opcode support */
77 static unsigned int tic4x_big_model
= 0; /* Default to small memory model. */
78 static unsigned int tic4x_reg_args
= 0; /* Default to args passed on stack. */
79 static unsigned long tic4x_oplevel
= 0; /* Opcode level */
81 #define OPTION_CPU 'm'
82 #define OPTION_BIG (OPTION_MD_BASE + 1)
83 #define OPTION_SMALL (OPTION_MD_BASE + 2)
84 #define OPTION_MEMPARM (OPTION_MD_BASE + 3)
85 #define OPTION_REGPARM (OPTION_MD_BASE + 4)
86 #define OPTION_IDLE2 (OPTION_MD_BASE + 5)
87 #define OPTION_LOWPOWER (OPTION_MD_BASE + 6)
88 #define OPTION_ENHANCED (OPTION_MD_BASE + 7)
89 #define OPTION_REV (OPTION_MD_BASE + 8)
91 CONST
char *md_shortopts
= "bm:prs";
92 struct option md_longopts
[] =
94 { "mcpu", required_argument
, NULL
, OPTION_CPU
},
95 { "mdsp", required_argument
, NULL
, OPTION_CPU
},
96 { "mbig", no_argument
, NULL
, OPTION_BIG
},
97 { "msmall", no_argument
, NULL
, OPTION_SMALL
},
98 { "mmemparm", no_argument
, NULL
, OPTION_MEMPARM
},
99 { "mregparm", no_argument
, NULL
, OPTION_REGPARM
},
100 { "midle2", no_argument
, NULL
, OPTION_IDLE2
},
101 { "mlowpower", no_argument
, NULL
, OPTION_LOWPOWER
},
102 { "menhanced", no_argument
, NULL
, OPTION_ENHANCED
},
103 { "mrev", required_argument
, NULL
, OPTION_REV
},
104 { NULL
, no_argument
, NULL
, 0 }
107 size_t md_longopts_size
= sizeof (md_longopts
);
112 M_UNKNOWN
, M_IMMED
, M_DIRECT
, M_REGISTER
, M_INDIRECT
,
113 M_IMMED_F
, M_PARALLEL
, M_HI
117 typedef struct tic4x_operand
119 tic4x_addr_mode_t mode
; /* Addressing mode. */
120 expressionS expr
; /* Expression. */
121 int disp
; /* Displacement for indirect addressing. */
122 int aregno
; /* Aux. register number. */
123 LITTLENUM_TYPE fwords
[MAX_LITTLENUMS
]; /* Float immed. number. */
127 typedef struct tic4x_insn
129 char name
[TIC4X_NAME_MAX
]; /* Mnemonic of instruction. */
130 unsigned int in_use
; /* True if in_use. */
131 unsigned int parallel
; /* True if parallel instruction. */
132 unsigned int nchars
; /* This is always 4 for the C30. */
133 unsigned long opcode
; /* Opcode number. */
134 expressionS exp
; /* Expression required for relocation. */
135 int reloc
; /* Relocation type required. */
136 int pcrel
; /* True if relocation PC relative. */
137 char *pname
; /* Name of instruction in parallel. */
138 unsigned int num_operands
; /* Number of operands in total. */
139 tic4x_inst_t
*inst
; /* Pointer to first template. */
140 tic4x_operand_t operands
[TIC4X_OPERANDS_MAX
];
144 static tic4x_insn_t the_insn
; /* Info about our instruction. */
145 static tic4x_insn_t
*insn
= &the_insn
;
147 static int tic4x_gen_to_words
148 PARAMS ((FLONUM_TYPE
, LITTLENUM_TYPE
*, int ));
149 static char *tic4x_atof
150 PARAMS ((char *, char, LITTLENUM_TYPE
* ));
151 static void tic4x_insert_reg
152 PARAMS ((char *, int ));
153 static void tic4x_insert_sym
154 PARAMS ((char *, int ));
155 static char *tic4x_expression
156 PARAMS ((char *, expressionS
*));
157 static char *tic4x_expression_abs
158 PARAMS ((char *, offsetT
*));
159 static void tic4x_emit_char
160 PARAMS ((char, int));
161 static void tic4x_seg_alloc
162 PARAMS ((char *, segT
, int, symbolS
*));
163 static void tic4x_asg
165 static void tic4x_bss
167 static void tic4x_globl
169 static void tic4x_cons
171 static void tic4x_stringer
173 static void tic4x_eval
175 static void tic4x_newblock
177 static void tic4x_sect
179 static void tic4x_set
181 static void tic4x_usect
183 static void tic4x_version
185 static void tic4x_init_regtable
187 static void tic4x_init_symbols
189 static int tic4x_inst_insert
190 PARAMS ((tic4x_inst_t
*));
191 static tic4x_inst_t
*tic4x_inst_make
192 PARAMS ((char *, unsigned long, char *));
193 static int tic4x_inst_add
194 PARAMS ((tic4x_inst_t
*));
197 static int tic4x_indirect_parse
198 PARAMS ((tic4x_operand_t
*, const tic4x_indirect_t
*));
199 static char *tic4x_operand_parse
200 PARAMS ((char *, tic4x_operand_t
*));
201 static int tic4x_operands_match
202 PARAMS ((tic4x_inst_t
*, tic4x_insn_t
*, int));
203 static void tic4x_insn_check
204 PARAMS ((tic4x_insn_t
*));
205 static void tic4x_insn_output
206 PARAMS ((tic4x_insn_t
*));
207 static int tic4x_operands_parse
208 PARAMS ((char *, tic4x_operand_t
*, int ));
211 int tic4x_unrecognized_line
213 static int tic4x_pc_offset
214 PARAMS ((unsigned int));
216 PARAMS ((int, const char *, int, int));
217 void tic4x_start_line
219 arelent
*tc_gen_reloc
220 PARAMS ((asection
*, fixS
*));
226 {"align", s_align_bytes
, 32},
227 {"ascii", tic4x_stringer
, 1},
228 {"asciz", tic4x_stringer
, 0},
229 {"asg", tic4x_asg
, 0},
230 {"block", s_space
, 4},
231 {"byte", tic4x_cons
, 1},
232 {"bss", tic4x_bss
, 0},
233 {"copy", s_include
, 0},
234 {"def", tic4x_globl
, 0},
235 {"equ", tic4x_set
, 0},
236 {"eval", tic4x_eval
, 0},
237 {"global", tic4x_globl
, 0},
238 {"globl", tic4x_globl
, 0},
239 {"hword", tic4x_cons
, 2},
240 {"ieee", float_cons
, 'i'},
241 {"int", tic4x_cons
, 4}, /* .int allocates 4 bytes. */
242 {"ldouble", float_cons
, 'e'},
243 {"newblock", tic4x_newblock
, 0},
244 {"ref", s_ignore
, 0}, /* All undefined treated as external. */
245 {"set", tic4x_set
, 0},
246 {"sect", tic4x_sect
, 1}, /* Define named section. */
247 {"space", s_space
, 4},
248 {"string", tic4x_stringer
, 0},
249 {"usect", tic4x_usect
, 0}, /* Reserve space in uninit. named sect. */
250 {"version", tic4x_version
, 0},
251 {"word", tic4x_cons
, 4}, /* .word allocates 4 bytes. */
252 {"xdef", tic4x_globl
, 0},
256 int md_short_jump_size
= 4;
257 int md_long_jump_size
= 4;
259 /* This array holds the chars that always start a comment. If the
260 pre-processor is disabled, these aren't very useful. */
261 #ifdef TIC4X_ALT_SYNTAX
262 const char comment_chars
[] = ";!";
264 const char comment_chars
[] = ";";
267 /* This array holds the chars that only start a comment at the beginning of
268 a line. If the line seems to have the form '# 123 filename'
269 .line and .file directives will appear in the pre-processed output.
270 Note that input_file.c hand checks for '#' at the beginning of the
271 first line of the input file. This is because the compiler outputs
272 #NO_APP at the beginning of its output.
273 Also note that comments like this one will always work. */
274 const char line_comment_chars
[] = "#*";
276 /* We needed an unused char for line separation to work around the
277 lack of macros, using sed and such. */
278 const char line_separator_chars
[] = "&";
280 /* Chars that can be used to separate mant from exp in floating point nums. */
281 const char EXP_CHARS
[] = "eE";
283 /* Chars that mean this number is a floating point constant. */
286 const char FLT_CHARS
[] = "fFilsS";
288 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
289 changed in read.c. Ideally it shouldn't have to know about it at
290 all, but nothing is ideal around here. */
292 /* Flonums returned here. */
293 extern FLONUM_TYPE generic_floating_point_number
;
295 /* Precision in LittleNums. */
296 #define MAX_PRECISION (4) /* Its a bit overkill for us, but the code
298 #define S_PRECISION (1) /* Short float constants 16-bit. */
299 #define F_PRECISION (2) /* Float and double types 32-bit. */
300 #define E_PRECISION (4) /* Extended precision, 64-bit (real 40-bit). */
303 /* Turn generic_floating_point_number into a real short/float/double. */
305 tic4x_gen_to_words (flonum
, words
, precision
)
307 LITTLENUM_TYPE
*words
;
310 int return_value
= 0;
311 LITTLENUM_TYPE
*p
; /* Littlenum pointer. */
312 int mantissa_bits
; /* Bits in mantissa field. */
313 int exponent_bits
; /* Bits in exponent field. */
315 unsigned int sone
; /* Scaled one. */
316 unsigned int sfract
; /* Scaled fraction. */
317 unsigned int smant
; /* Scaled mantissa. */
319 unsigned int mover
; /* Mantissa overflow bits */
320 unsigned int rbit
; /* Round bit. */
321 int shift
; /* Shift count. */
323 /* NOTE: Svein Seldal <Svein@dev.seldal.com>
324 The code in this function is altered slightly to support floats
325 with 31-bits mantissas, thus the documentation below may be a
326 little bit inaccurate.
328 By Michael P. Hayes <m.hayes@elec.canterbury.ac.nz>
329 Here is how a generic floating point number is stored using
330 flonums (an extension of bignums) where p is a pointer to an
333 For example 2e-3 is stored with exp = -4 and
340 with low = &bits[2], high = &bits[5], and leader = &bits[5].
342 This number can be written as
343 0x0083126e978d4fde.00000000 * 65536**-4 or
344 0x0.0083126e978d4fde * 65536**0 or
345 0x0.83126e978d4fde * 2**-8 = 2e-3
347 Note that low points to the 65536**0 littlenum (bits[2]) and
348 leader points to the most significant non-zero littlenum
351 TMS320C3X floating point numbers are a bit of a strange beast.
352 The 32-bit flavour has the 8 MSBs representing the exponent in
353 twos complement format (-128 to +127). There is then a sign bit
354 followed by 23 bits of mantissa. The mantissa is expressed in
355 twos complement format with the binary point after the most
356 significant non sign bit. The bit after the binary point is
357 suppressed since it is the complement of the sign bit. The
358 effective mantissa is thus 24 bits. Zero is represented by an
361 The 16-bit flavour has the 4 MSBs representing the exponent in
362 twos complement format (-8 to +7). There is then a sign bit
363 followed by 11 bits of mantissa. The mantissa is expressed in
364 twos complement format with the binary point after the most
365 significant non sign bit. The bit after the binary point is
366 suppressed since it is the complement of the sign bit. The
367 effective mantissa is thus 12 bits. Zero is represented by an
368 exponent of -8. For example,
370 number norm mant m x e s i fraction f
371 +0.500 => 1.00000000000 -1 -1 0 1 .00000000000 (1 + 0) * 2^(-1)
372 +0.999 => 1.11111111111 -1 -1 0 1 .11111111111 (1 + 0.99) * 2^(-1)
373 +1.000 => 1.00000000000 0 0 0 1 .00000000000 (1 + 0) * 2^(0)
374 +1.500 => 1.10000000000 0 0 0 1 .10000000000 (1 + 0.5) * 2^(0)
375 +1.999 => 1.11111111111 0 0 0 1 .11111111111 (1 + 0.9) * 2^(0)
376 +2.000 => 1.00000000000 1 1 0 1 .00000000000 (1 + 0) * 2^(1)
377 +4.000 => 1.00000000000 2 2 0 1 .00000000000 (1 + 0) * 2^(2)
378 -0.500 => 1.00000000000 -1 -1 1 0 .10000000000 (-2 + 0) * 2^(-2)
379 -1.000 => 1.00000000000 0 -1 1 0 .00000000000 (-2 + 0) * 2^(-1)
380 -1.500 => 1.10000000000 0 0 1 0 .10000000000 (-2 + 0.5) * 2^(0)
381 -1.999 => 1.11111111111 0 0 1 0 .00000000001 (-2 + 0.11) * 2^(0)
382 -2.000 => 1.00000000000 1 1 1 0 .00000000000 (-2 + 0) * 2^(0)
383 -4.000 => 1.00000000000 2 1 1 0 .00000000000 (-2 + 0) * 2^(1)
385 where e is the exponent, s is the sign bit, i is the implied bit,
386 and f is the fraction stored in the mantissa field.
388 num = (1 + f) * 2^x = m * 2^e if s = 0
389 num = (-2 + f) * 2^x = -m * 2^e if s = 1
390 where 0 <= f < 1.0 and 1.0 <= m < 2.0
392 The fraction (f) and exponent (e) fields for the TMS320C3X format
393 can be derived from the normalised mantissa (m) and exponent (x) using:
395 f = m - 1, e = x if s = 0
396 f = 2 - m, e = x if s = 1 and m != 1.0
397 f = 0, e = x - 1 if s = 1 and m = 1.0
398 f = 0, e = -8 if m = 0
401 OK, the other issue we have to consider is rounding since the
402 mantissa has a much higher potential precision than what we can
403 represent. To do this we add half the smallest storable fraction.
404 We then have to renormalise the number to allow for overflow.
406 To convert a generic flonum into a TMS320C3X floating point
407 number, here's what we try to do....
409 The first thing is to generate a normalised mantissa (m) where
410 1.0 <= m < 2 and to convert the exponent from base 16 to base 2.
411 We desire the binary point to be placed after the most significant
412 non zero bit. This process is done in two steps: firstly, the
413 littlenum with the most significant non zero bit is located (this
414 is done for us since leader points to this littlenum) and the
415 binary point (which is currently after the LSB of the littlenum
416 pointed to by low) is moved to before the MSB of the littlenum
417 pointed to by leader. This requires the exponent to be adjusted
418 by leader - low + 1. In the earlier example, the new exponent is
419 thus -4 + (5 - 2 + 1) = 0 (base 65536). We now need to convert
420 the exponent to base 2 by multiplying the exponent by 16 (log2
421 65536). The exponent base 2 is thus also zero.
423 The second step is to hunt for the most significant non zero bit
424 in the leader littlenum. We do this by left shifting a copy of
425 the leader littlenum until bit 16 is set (0x10000) and counting
426 the number of shifts, S, required. The number of shifts then has to
427 be added to correct the exponent (base 2). For our example, this
428 will require 9 shifts and thus our normalised exponent (base 2) is
429 0 + 9 = 9. Note that the worst case scenario is when the leader
430 littlenum is 1, thus requiring 16 shifts.
432 We now have to left shift the other littlenums by the same amount,
433 propagating the shifted bits into the more significant littlenums.
434 To save a lot of unnecessary shifting we only have to consider
435 two or three littlenums, since the greatest number of mantissa
436 bits required is 24 + 1 rounding bit. While two littlenums
437 provide 32 bits of precision, the most significant littlenum
438 may only contain a single significant bit and thus an extra
439 littlenum is required.
441 Denoting the number of bits in the fraction field as F, we require
442 G = F + 2 bits (one extra bit is for rounding, the other gets
443 suppressed). Say we required S shifts to find the most
444 significant bit in the leader littlenum, the number of left shifts
445 required to move this bit into bit position G - 1 is L = G + S - 17.
446 Note that this shift count may be negative for the short floating
447 point flavour (where F = 11 and thus G = 13 and potentially S < 3).
448 If L > 0 we have to shunt the next littlenum into position. Bit
449 15 (the MSB) of the next littlenum needs to get moved into position
450 L - 1 (If L > 15 we need all the bits of this littlenum and
451 some more from the next one.). We subtract 16 from L and use this
452 as the left shift count; the resultant value we or with the
453 previous result. If L > 0, we repeat this operation. */
455 if (precision
!= S_PRECISION
)
457 if (precision
== E_PRECISION
)
458 words
[2] = words
[3] = 0x0000;
460 /* 0.0e0 or NaN seen. */
461 if (flonum
.low
> flonum
.leader
/* = 0.0e0 */
462 || flonum
.sign
== 0) /* = NaN */
465 as_bad ("Nan, using zero.");
470 if (flonum
.sign
== 'P')
472 /* +INF: Replace with maximum float. */
473 if (precision
== S_PRECISION
)
480 if (precision
== E_PRECISION
)
487 else if (flonum
.sign
== 'N')
489 /* -INF: Replace with maximum float. */
490 if (precision
== S_PRECISION
)
494 if (precision
== E_PRECISION
)
499 exponent
= (flonum
.exponent
+ flonum
.leader
- flonum
.low
+ 1) * 16;
501 if (!(tmp
= *flonum
.leader
))
502 abort (); /* Hmmm. */
503 shift
= 0; /* Find position of first sig. bit. */
506 exponent
-= (16 - shift
); /* Adjust exponent. */
508 if (precision
== S_PRECISION
) /* Allow 1 rounding bit. */
513 else if(precision
== F_PRECISION
)
518 else /* E_PRECISION */
524 shift
= mantissa_bits
- shift
;
529 /* Store the mantissa data into smant and the roundbit into rbit */
530 for (p
= flonum
.leader
; p
>= flonum
.low
&& shift
> -16; p
--)
532 tmp
= shift
>= 0 ? *p
<< shift
: *p
>> -shift
;
533 rbit
= shift
< 0 ? ((*p
>> (-shift
-1)) & 0x1) : 0;
538 /* OK, we've got our scaled mantissa so let's round it up */
541 /* If the mantissa is going to overflow when added, lets store
542 the extra bit in mover. -- A special case exists when
543 mantissa_bits is 31 (E_PRECISION). Then the first test cannot
544 be trusted, as result is host-dependent, thus the second
546 if( smant
== ((unsigned)(1<<(mantissa_bits
+1))-1)
547 || smant
== (unsigned)-1 ) /* This is to catch E_PRECISION cases */
552 /* Get the scaled one value */
553 sone
= (1 << (mantissa_bits
));
555 /* The number may be unnormalised so renormalise it... */
559 smant
|= sone
; /* Insert the bit from mover into smant */
563 /* The binary point is now between bit positions 11 and 10 or 23 and 22,
564 i.e., between mantissa_bits - 1 and mantissa_bits - 2 and the
565 bit at mantissa_bits - 1 should be set. */
567 abort (); /* Ooops. */
569 if (flonum
.sign
== '+')
570 sfract
= smant
- sone
; /* smant - 1.0. */
573 /* This seems to work. */
581 sfract
= -smant
& (sone
-1); /* 2.0 - smant. */
583 sfract
|= sone
; /* Insert sign bit. */
586 if (abs (exponent
) >= (1 << (exponent_bits
- 1)))
587 as_bad ("Cannot represent exponent in %d bits", exponent_bits
);
589 /* Force exponent to fit in desired field width. */
590 exponent
&= (1 << (exponent_bits
)) - 1;
592 if (precision
== E_PRECISION
)
594 /* Map the float part first (100% equal format as F_PRECISION) */
595 words
[0] = exponent
<< (mantissa_bits
+1-24);
596 words
[0] |= sfract
>> 24;
597 words
[1] = sfract
>> 8;
599 /* Map the mantissa in the next */
600 words
[2] = sfract
>> 16;
601 words
[3] = sfract
& 0xffff;
605 /* Insert the exponent data into the word */
606 sfract
|= exponent
<< (mantissa_bits
+1);
608 if (precision
== S_PRECISION
)
612 words
[0] = sfract
>> 16;
613 words
[1] = sfract
& 0xffff;
620 /* Returns pointer past text consumed. */
622 tic4x_atof (str
, what_kind
, words
)
625 LITTLENUM_TYPE
*words
;
627 /* Extra bits for zeroed low-order bits. The 1st MAX_PRECISION are
628 zeroed, the last contain flonum bits. */
629 static LITTLENUM_TYPE bits
[MAX_PRECISION
+ MAX_PRECISION
+ GUARD
];
631 /* Number of 16-bit words in the format. */
633 FLONUM_TYPE save_gen_flonum
;
635 /* We have to save the generic_floating_point_number because it
636 contains storage allocation about the array of LITTLENUMs where
637 the value is actually stored. We will allocate our own array of
638 littlenums below, but have to restore the global one on exit. */
639 save_gen_flonum
= generic_floating_point_number
;
642 generic_floating_point_number
.low
= bits
+ MAX_PRECISION
;
643 generic_floating_point_number
.high
= NULL
;
644 generic_floating_point_number
.leader
= NULL
;
645 generic_floating_point_number
.exponent
= 0;
646 generic_floating_point_number
.sign
= '\0';
648 /* Use more LittleNums than seems necessary: the highest flonum may
649 have 15 leading 0 bits, so could be useless. */
651 memset (bits
, '\0', sizeof (LITTLENUM_TYPE
) * MAX_PRECISION
);
657 precision
= S_PRECISION
;
664 precision
= F_PRECISION
;
669 precision
= E_PRECISION
;
673 as_bad ("Invalid floating point number");
677 generic_floating_point_number
.high
678 = generic_floating_point_number
.low
+ precision
- 1 + GUARD
;
680 if (atof_generic (&return_value
, ".", EXP_CHARS
,
681 &generic_floating_point_number
))
683 as_bad ("Invalid floating point number");
687 tic4x_gen_to_words (generic_floating_point_number
,
690 /* Restore the generic_floating_point_number's storage alloc (and
692 generic_floating_point_number
= save_gen_flonum
;
698 tic4x_insert_reg (regname
, regnum
)
705 symbol_table_insert (symbol_new (regname
, reg_section
, (valueT
) regnum
,
706 &zero_address_frag
));
707 for (i
= 0; regname
[i
]; i
++)
708 buf
[i
] = ISLOWER (regname
[i
]) ? TOUPPER (regname
[i
]) : regname
[i
];
711 symbol_table_insert (symbol_new (buf
, reg_section
, (valueT
) regnum
,
712 &zero_address_frag
));
716 tic4x_insert_sym (symname
, value
)
722 symbolP
= symbol_new (symname
, absolute_section
,
723 (valueT
) value
, &zero_address_frag
);
724 SF_SET_LOCAL (symbolP
);
725 symbol_table_insert (symbolP
);
729 tic4x_expression (str
, exp
)
736 t
= input_line_pointer
; /* Save line pointer. */
737 input_line_pointer
= str
;
739 s
= input_line_pointer
;
740 input_line_pointer
= t
; /* Restore line pointer. */
741 return s
; /* Return pointer to where parsing stopped. */
745 tic4x_expression_abs (str
, value
)
752 t
= input_line_pointer
; /* Save line pointer. */
753 input_line_pointer
= str
;
754 *value
= get_absolute_expression ();
755 s
= input_line_pointer
;
756 input_line_pointer
= t
; /* Restore line pointer. */
761 tic4x_emit_char (c
,b
)
767 exp
.X_op
= O_constant
;
768 exp
.X_add_number
= c
;
773 tic4x_seg_alloc (name
, seg
, size
, symbolP
)
774 char *name ATTRIBUTE_UNUSED
;
775 segT seg ATTRIBUTE_UNUSED
;
779 /* Note that the size is in words
780 so we multiply it by 4 to get the number of bytes to allocate. */
782 /* If we have symbol: .usect ".fred", size etc.,
783 the symbol needs to point to the first location reserved
790 p
= frag_var (rs_fill
, 1, 1, (relax_substateT
) 0,
792 size
* OCTETS_PER_BYTE
, (char *) 0);
797 /* .asg ["]character-string["], symbol */
800 int x ATTRIBUTE_UNUSED
;
808 str
= input_line_pointer
;
810 /* Skip string expression. */
811 while (*input_line_pointer
!= ',' && *input_line_pointer
)
812 input_line_pointer
++;
813 if (*input_line_pointer
!= ',')
815 as_bad ("Comma expected\n");
818 *input_line_pointer
++ = '\0';
819 name
= input_line_pointer
;
820 c
= get_symbol_end (); /* Get terminator. */
821 tmp
= xmalloc (strlen (str
) + 1);
824 tmp
= xmalloc (strlen (name
) + 1);
827 if (hash_find (tic4x_asg_hash
, name
))
828 hash_replace (tic4x_asg_hash
, name
, (PTR
) str
);
830 hash_insert (tic4x_asg_hash
, name
, (PTR
) str
);
831 *input_line_pointer
= c
;
832 demand_empty_rest_of_line ();
835 /* .bss symbol, size */
838 int x ATTRIBUTE_UNUSED
;
845 subsegT current_subseg
;
848 current_seg
= now_seg
; /* Save current seg. */
849 current_subseg
= now_subseg
; /* Save current subseg. */
852 name
= input_line_pointer
;
853 c
= get_symbol_end (); /* Get terminator. */
856 as_bad (".bss size argument missing\n");
861 tic4x_expression_abs (++input_line_pointer
, &size
);
864 as_bad (".bss size %ld < 0!", (long) size
);
867 subseg_set (bss_section
, 0);
868 symbolP
= symbol_find_or_make (name
);
870 if (S_GET_SEGMENT (symbolP
) == bss_section
)
871 symbol_get_frag (symbolP
)->fr_symbol
= 0;
873 symbol_set_frag (symbolP
, frag_now
);
875 p
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
,
876 size
* OCTETS_PER_BYTE
, (char *) 0);
877 *p
= 0; /* Fill char. */
879 S_SET_SEGMENT (symbolP
, bss_section
);
881 /* The symbol may already have been created with a preceding
882 ".globl" directive -- be careful not to step on storage class
883 in that case. Otherwise, set it to static. */
884 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
885 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
887 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
888 demand_empty_rest_of_line ();
893 int ignore ATTRIBUTE_UNUSED
;
901 name
= input_line_pointer
;
902 c
= get_symbol_end ();
903 symbolP
= symbol_find_or_make (name
);
904 *input_line_pointer
= c
;
906 S_SET_STORAGE_CLASS (symbolP
, C_EXT
);
909 input_line_pointer
++;
911 if (*input_line_pointer
== '\n')
917 demand_empty_rest_of_line ();
920 /* Handle .byte, .word. .int, .long */
925 register unsigned int c
;
929 if (*input_line_pointer
== '"')
931 input_line_pointer
++;
932 while (is_a_char (c
= next_char_of_string ()))
933 tic4x_emit_char (c
, 4);
934 know (input_line_pointer
[-1] == '\"');
940 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
941 if (exp
.X_op
== O_constant
)
946 exp
.X_add_number
&= 255;
949 exp
.X_add_number
&= 65535;
953 /* Perhaps we should disallow .byte and .hword with
954 a non constant expression that will require relocation. */
958 while (*input_line_pointer
++ == ',');
960 input_line_pointer
--; /* Put terminator back into stream. */
961 demand_empty_rest_of_line ();
964 /* Handle .ascii, .asciz, .string */
966 tic4x_stringer (append_zero
)
967 int append_zero
; /*ex: bytes */
970 register unsigned int c
;
976 if (*input_line_pointer
== '"')
978 input_line_pointer
++;
979 while (is_a_char (c
= next_char_of_string ()))
981 tic4x_emit_char (c
, 1);
987 tic4x_emit_char (c
, 1);
991 know (input_line_pointer
[-1] == '\"');
997 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
998 if (exp
.X_op
!= O_constant
)
1000 as_bad("Non-constant symbols not allowed\n");
1003 exp
.X_add_number
&= 255; /* Limit numeber to 8-bit */
1004 emit_expr (&exp
, 1);
1008 while (*input_line_pointer
++ == ',');
1010 /* Fill out the rest of the expression with 0's to fill up a full word */
1012 tic4x_emit_char (0, 4-(bytes
&0x3));
1014 input_line_pointer
--; /* Put terminator back into stream. */
1015 demand_empty_rest_of_line ();
1018 /* .eval expression, symbol */
1021 int x ATTRIBUTE_UNUSED
;
1028 input_line_pointer
=
1029 tic4x_expression_abs (input_line_pointer
, &value
);
1030 if (*input_line_pointer
++ != ',')
1032 as_bad ("Symbol missing\n");
1035 name
= input_line_pointer
;
1036 c
= get_symbol_end (); /* Get terminator. */
1037 demand_empty_rest_of_line ();
1038 tic4x_insert_sym (name
, value
);
1041 /* Reset local labels. */
1044 int x ATTRIBUTE_UNUSED
;
1046 dollar_label_clear ();
1049 /* .sect "section-name" [, value] */
1050 /* .sect ["]section-name[:subsection-name]["] [, value] */
1053 int x ATTRIBUTE_UNUSED
;
1057 char *subsection_name
;
1063 if (*input_line_pointer
== '"')
1064 input_line_pointer
++;
1065 section_name
= input_line_pointer
;
1066 c
= get_symbol_end (); /* Get terminator. */
1067 input_line_pointer
++; /* Skip null symbol terminator. */
1068 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1069 strcpy (name
, section_name
);
1071 /* TI C from version 5.0 allows a section name to contain a
1072 subsection name as well. The subsection name is separated by a
1073 ':' from the section name. Currently we scan the subsection
1074 name and discard it.
1075 Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>. */
1078 subsection_name
= input_line_pointer
;
1079 c
= get_symbol_end (); /* Get terminator. */
1080 input_line_pointer
++; /* Skip null symbol terminator. */
1081 as_warn (".sect: subsection name ignored");
1084 /* We might still have a '"' to discard, but the character after a
1085 symbol name will be overwritten with a \0 by get_symbol_end()
1089 input_line_pointer
=
1090 tic4x_expression_abs (input_line_pointer
, &num
);
1091 else if (*input_line_pointer
== ',')
1093 input_line_pointer
=
1094 tic4x_expression_abs (++input_line_pointer
, &num
);
1099 seg
= subseg_new (name
, num
);
1100 if (line_label
!= NULL
)
1102 S_SET_SEGMENT (line_label
, seg
);
1103 symbol_set_frag (line_label
, frag_now
);
1106 if (bfd_get_section_flags (stdoutput
, seg
) == SEC_NO_FLAGS
)
1108 if (!bfd_set_section_flags (stdoutput
, seg
, SEC_DATA
))
1109 as_warn ("Error setting flags for \"%s\": %s", name
,
1110 bfd_errmsg (bfd_get_error ()));
1113 /* If the last character overwritten by get_symbol_end() was an
1114 end-of-line, we must restore it or the end of the line will not be
1115 recognised and scanning extends into the next line, stopping with
1116 an error (blame Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>
1117 if this is not true). */
1118 if (is_end_of_line
[(unsigned char) c
])
1119 *(--input_line_pointer
) = c
;
1121 demand_empty_rest_of_line ();
1124 /* symbol[:] .set value or .set symbol, value */
1127 int x ATTRIBUTE_UNUSED
;
1132 if ((symbolP
= line_label
) == NULL
)
1137 name
= input_line_pointer
;
1138 c
= get_symbol_end (); /* Get terminator. */
1141 as_bad (".set syntax invalid\n");
1142 ignore_rest_of_line ();
1145 ++input_line_pointer
;
1146 symbolP
= symbol_find_or_make (name
);
1149 symbol_table_insert (symbolP
);
1151 pseudo_set (symbolP
);
1152 demand_empty_rest_of_line ();
1155 /* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
1158 int x ATTRIBUTE_UNUSED
;
1164 offsetT size
, alignment_flag
;
1166 subsegT current_subseg
;
1168 current_seg
= now_seg
; /* save current seg. */
1169 current_subseg
= now_subseg
; /* save current subseg. */
1172 if (*input_line_pointer
== '"')
1173 input_line_pointer
++;
1174 section_name
= input_line_pointer
;
1175 c
= get_symbol_end (); /* Get terminator. */
1176 input_line_pointer
++; /* Skip null symbol terminator. */
1177 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1178 strcpy (name
, section_name
);
1181 input_line_pointer
=
1182 tic4x_expression_abs (input_line_pointer
, &size
);
1183 else if (*input_line_pointer
== ',')
1185 input_line_pointer
=
1186 tic4x_expression_abs (++input_line_pointer
, &size
);
1191 /* Read a possibly present third argument (alignment flag) [VK]. */
1192 if (*input_line_pointer
== ',')
1194 input_line_pointer
=
1195 tic4x_expression_abs (++input_line_pointer
, &alignment_flag
);
1200 as_warn (".usect: non-zero alignment flag ignored");
1202 seg
= subseg_new (name
, 0);
1203 if (line_label
!= NULL
)
1205 S_SET_SEGMENT (line_label
, seg
);
1206 symbol_set_frag (line_label
, frag_now
);
1207 S_SET_VALUE (line_label
, frag_now_fix ());
1209 seg_info (seg
)->bss
= 1; /* Uninitialised data. */
1210 if (!bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
))
1211 as_warn ("Error setting flags for \"%s\": %s", name
,
1212 bfd_errmsg (bfd_get_error ()));
1213 tic4x_seg_alloc (name
, seg
, size
, line_label
);
1215 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1216 S_SET_STORAGE_CLASS (line_label
, C_STAT
);
1218 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
1219 demand_empty_rest_of_line ();
1222 /* .version cpu-version. */
1225 int x ATTRIBUTE_UNUSED
;
1229 input_line_pointer
=
1230 tic4x_expression_abs (input_line_pointer
, &temp
);
1231 if (!IS_CPU_TIC3X (temp
) && !IS_CPU_TIC4X (temp
))
1232 as_bad ("This assembler does not support processor generation %ld",
1235 if (tic4x_cpu
&& temp
!= (offsetT
) tic4x_cpu
)
1236 as_warn ("Changing processor generation on fly not supported...");
1238 demand_empty_rest_of_line ();
1242 tic4x_init_regtable ()
1246 for (i
= 0; i
< tic3x_num_registers
; i
++)
1247 tic4x_insert_reg (tic3x_registers
[i
].name
,
1248 tic3x_registers
[i
].regno
);
1250 if (IS_CPU_TIC4X (tic4x_cpu
))
1252 /* Add additional Tic4x registers, overriding some C3x ones. */
1253 for (i
= 0; i
< tic4x_num_registers
; i
++)
1254 tic4x_insert_reg (tic4x_registers
[i
].name
,
1255 tic4x_registers
[i
].regno
);
1260 tic4x_init_symbols ()
1262 /* The TI tools accept case insensitive versions of these symbols,
1267 .TMS320xx 30,31,32,40,or 44 set according to -v flag
1268 .C3X or .C3x 1 or 0 1 if -v30,-v31,or -v32
1269 .C30 1 or 0 1 if -v30
1270 .C31 1 or 0 1 if -v31
1271 .C32 1 or 0 1 if -v32
1272 .C4X or .C4x 1 or 0 1 if -v40, or -v44
1273 .C40 1 or 0 1 if -v40
1274 .C44 1 or 0 1 if -v44
1276 .REGPARM 1 or 0 1 if -mr option used
1277 .BIGMODEL 1 or 0 1 if -mb option used
1279 These symbols are currently supported but will be removed in a
1281 .TMS320C30 1 or 0 1 if -v30,-v31,or -v32
1282 .TMS320C31 1 or 0 1 if -v31
1283 .TMS320C32 1 or 0 1 if -v32
1284 .TMS320C40 1 or 0 1 if -v40, or -v44
1285 .TMS320C44 1 or 0 1 if -v44
1287 Source: TI: TMS320C3x/C4x Assembly Language Tools User's Guide,
1288 1997, SPRU035C, p. 3-17/3-18. */
1289 tic4x_insert_sym (".REGPARM", tic4x_reg_args
);
1290 tic4x_insert_sym (".MEMPARM", !tic4x_reg_args
);
1291 tic4x_insert_sym (".BIGMODEL", tic4x_big_model
);
1292 tic4x_insert_sym (".C30INTERRUPT", 0);
1293 tic4x_insert_sym (".TMS320xx", tic4x_cpu
== 0 ? 40 : tic4x_cpu
);
1294 tic4x_insert_sym (".C3X", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1295 tic4x_insert_sym (".C3x", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1296 tic4x_insert_sym (".C4X", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1297 tic4x_insert_sym (".C4x", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1298 /* Do we need to have the following symbols also in lower case? */
1299 tic4x_insert_sym (".TMS320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1300 tic4x_insert_sym (".tms320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1301 tic4x_insert_sym (".TMS320C31", tic4x_cpu
== 31);
1302 tic4x_insert_sym (".tms320C31", tic4x_cpu
== 31);
1303 tic4x_insert_sym (".TMS320C32", tic4x_cpu
== 32);
1304 tic4x_insert_sym (".tms320C32", tic4x_cpu
== 32);
1305 tic4x_insert_sym (".TMS320C33", tic4x_cpu
== 33);
1306 tic4x_insert_sym (".tms320C33", tic4x_cpu
== 33);
1307 tic4x_insert_sym (".TMS320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1308 tic4x_insert_sym (".tms320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1309 tic4x_insert_sym (".TMS320C44", tic4x_cpu
== 44);
1310 tic4x_insert_sym (".tms320C44", tic4x_cpu
== 44);
1311 tic4x_insert_sym (".TMX320C40", 0); /* C40 first pass silicon ? */
1312 tic4x_insert_sym (".tmx320C40", 0);
1315 /* Insert a new instruction template into hash table. */
1317 tic4x_inst_insert (inst
)
1320 static char prev_name
[16];
1321 const char *retval
= NULL
;
1323 /* Only insert the first name if have several similar entries. */
1324 if (!strcmp (inst
->name
, prev_name
) || inst
->name
[0] == '\0')
1327 retval
= hash_insert (tic4x_op_hash
, inst
->name
, (PTR
) inst
);
1329 fprintf (stderr
, "internal error: can't hash `%s': %s\n",
1330 inst
->name
, retval
);
1332 strcpy (prev_name
, inst
->name
);
1333 return retval
== NULL
;
1336 /* Make a new instruction template. */
1337 static tic4x_inst_t
*
1338 tic4x_inst_make (name
, opcode
, args
)
1340 unsigned long opcode
;
1343 static tic4x_inst_t
*insts
= NULL
;
1344 static char *names
= NULL
;
1345 static int index
= 0;
1349 /* Allocate memory to store name strings. */
1350 names
= (char *) xmalloc (sizeof (char) * 8192);
1351 /* Allocate memory for additional insts. */
1352 insts
= (tic4x_inst_t
*)
1353 xmalloc (sizeof (tic4x_inst_t
) * 1024);
1355 insts
[index
].name
= names
;
1356 insts
[index
].opcode
= opcode
;
1357 insts
[index
].opmask
= 0xffffffff;
1358 insts
[index
].args
= args
;
1366 return &insts
[index
- 1];
1369 /* Add instruction template, creating dynamic templates as required. */
1371 tic4x_inst_add (insts
)
1372 tic4x_inst_t
*insts
;
1374 char *s
= insts
->name
;
1382 /* We do not care about INSNs that is not a part of our
1384 if (!insts
->oplevel
& tic4x_oplevel
)
1393 /* Dynamically create all the conditional insts. */
1394 for (i
= 0; i
< tic4x_num_conds
; i
++)
1398 char *c
= tic4x_conds
[i
].name
;
1408 /* If instruction found then have already processed it. */
1409 if (hash_find (tic4x_op_hash
, name
))
1414 inst
= tic4x_inst_make (name
, insts
[k
].opcode
+
1415 (tic4x_conds
[i
].cond
<<
1416 (*s
== 'B' ? 16 : 23)),
1418 if (k
== 0) /* Save strcmp() with following func. */
1419 ok
&= tic4x_inst_insert (inst
);
1422 while (!strcmp (insts
->name
,
1429 return tic4x_inst_insert (insts
);
1439 /* This function is called once, at assembler startup time. It should
1440 set up all the tables, etc., that the MD part of the assembler will
1448 /* Setup the proper opcode level according to the
1449 commandline parameters */
1450 tic4x_oplevel
= OP_C3X
;
1452 if ( IS_CPU_TIC4X(tic4x_cpu
) )
1453 tic4x_oplevel
|= OP_C4X
;
1455 if ( ( tic4x_cpu
== 31 && tic4x_revision
>= 6)
1456 || (tic4x_cpu
== 32 && tic4x_revision
>= 2)
1457 || (tic4x_cpu
== 33)
1459 tic4x_oplevel
|= OP_ENH
;
1461 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1462 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1463 || (tic4x_cpu
== 32)
1465 tic4x_oplevel
|= OP_LPWR
;
1467 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1468 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1469 || (tic4x_cpu
== 32)
1470 || (tic4x_cpu
== 33)
1471 || (tic4x_cpu
== 40 && tic4x_revision
>= 5)
1472 || (tic4x_cpu
== 44)
1474 tic4x_oplevel
|= OP_IDLE2
;
1476 /* Create hash table for mnemonics. */
1477 tic4x_op_hash
= hash_new ();
1479 /* Create hash table for asg pseudo. */
1480 tic4x_asg_hash
= hash_new ();
1482 /* Add mnemonics to hash table, expanding conditional mnemonics on fly. */
1483 for (i
= 0; i
< tic4x_num_insts
; i
++)
1484 ok
&= tic4x_inst_add ((void *) &tic4x_insts
[i
]);
1486 /* Create dummy inst to avoid errors accessing end of table. */
1487 tic4x_inst_make ("", 0, "");
1490 as_fatal ("Broken assembler. No assembly attempted.");
1492 /* Add registers to symbol table. */
1493 tic4x_init_regtable ();
1495 /* Add predefined symbols to symbol table. */
1496 tic4x_init_symbols ();
1502 bfd_set_arch_mach (stdoutput
, bfd_arch_tic4x
,
1503 IS_CPU_TIC4X (tic4x_cpu
) ? bfd_mach_tic4x
: bfd_mach_tic3x
);
1507 tic4x_indirect_parse (operand
, indirect
)
1508 tic4x_operand_t
*operand
;
1509 const tic4x_indirect_t
*indirect
;
1511 char *n
= indirect
->name
;
1512 char *s
= input_line_pointer
;
1522 case 'a': /* Need to match aux register. */
1524 #ifdef TIC4X_ALT_SYNTAX
1528 while (ISALNUM (*s
))
1531 if (!(symbolP
= symbol_find (name
)))
1534 if (S_GET_SEGMENT (symbolP
) != reg_section
)
1537 operand
->aregno
= S_GET_VALUE (symbolP
);
1538 if (operand
->aregno
>= REG_AR0
&& operand
->aregno
<= REG_AR7
)
1541 as_bad ("Auxiliary register AR0--AR7 required for indirect");
1544 case 'd': /* Need to match constant for disp. */
1545 #ifdef TIC4X_ALT_SYNTAX
1546 if (*s
== '%') /* expr() will die if we don't skip this. */
1549 s
= tic4x_expression (s
, &operand
->expr
);
1550 if (operand
->expr
.X_op
!= O_constant
)
1552 operand
->disp
= operand
->expr
.X_add_number
;
1553 if (operand
->disp
< 0 || operand
->disp
> 255)
1555 as_bad ("Bad displacement %d (require 0--255)\n",
1561 case 'y': /* Need to match IR0. */
1562 case 'z': /* Need to match IR1. */
1563 #ifdef TIC4X_ALT_SYNTAX
1567 s
= tic4x_expression (s
, &operand
->expr
);
1568 if (operand
->expr
.X_op
!= O_register
)
1570 if (operand
->expr
.X_add_number
!= REG_IR0
1571 && operand
->expr
.X_add_number
!= REG_IR1
)
1573 as_bad ("Index register IR0,IR1 required for displacement");
1577 if (*n
== 'y' && operand
->expr
.X_add_number
== REG_IR0
)
1579 if (*n
== 'z' && operand
->expr
.X_add_number
== REG_IR1
)
1584 if (*s
!= '(') /* No displacement, assume to be 1. */
1595 if (TOLOWER (*s
) != *n
)
1600 if (*s
!= ' ' && *s
!= ',' && *s
!= '\0')
1602 input_line_pointer
= s
;
1607 tic4x_operand_parse (s
, operand
)
1609 tic4x_operand_t
*operand
;
1614 expressionS
*exp
= &operand
->expr
;
1615 char *save
= input_line_pointer
;
1618 struct hash_entry
*entry
= NULL
;
1620 input_line_pointer
= s
;
1623 str
= input_line_pointer
;
1624 c
= get_symbol_end (); /* Get terminator. */
1625 new = input_line_pointer
;
1626 if (strlen (str
) && (entry
= hash_find (tic4x_asg_hash
, str
)) != NULL
)
1628 *input_line_pointer
= c
;
1629 input_line_pointer
= (char *) entry
;
1633 *input_line_pointer
= c
;
1634 input_line_pointer
= str
;
1637 operand
->mode
= M_UNKNOWN
;
1638 switch (*input_line_pointer
)
1640 #ifdef TIC4X_ALT_SYNTAX
1642 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1643 if (exp
->X_op
!= O_register
)
1644 as_bad ("Expecting a register name");
1645 operand
->mode
= M_REGISTER
;
1649 /* Denotes high 16 bits. */
1650 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1651 if (exp
->X_op
== O_constant
)
1652 operand
->mode
= M_IMMED
;
1653 else if (exp
->X_op
== O_big
)
1655 if (exp
->X_add_number
)
1656 as_bad ("Number too large"); /* bignum required */
1659 tic4x_gen_to_words (generic_floating_point_number
,
1660 operand
->fwords
, S_PRECISION
);
1661 operand
->mode
= M_IMMED_F
;
1664 /* Allow ori ^foo, ar0 to be equivalent to ldi .hi.foo, ar0 */
1665 /* WARNING : The TI C40 assembler cannot do this. */
1666 else if (exp
->X_op
== O_symbol
)
1668 operand
->mode
= M_HI
;
1673 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1674 if (exp
->X_op
== O_constant
)
1675 operand
->mode
= M_IMMED
;
1676 else if (exp
->X_op
== O_big
)
1678 if (exp
->X_add_number
> 0)
1679 as_bad ("Number too large"); /* bignum required. */
1682 tic4x_gen_to_words (generic_floating_point_number
,
1683 operand
->fwords
, S_PRECISION
);
1684 operand
->mode
= M_IMMED_F
;
1687 /* Allow ori foo, ar0 to be equivalent to ldi .lo.foo, ar0 */
1688 /* WARNING : The TI C40 assembler cannot do this. */
1689 else if (exp
->X_op
== O_symbol
)
1691 operand
->mode
= M_IMMED
;
1696 as_bad ("Expecting a constant value");
1701 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1702 if (exp
->X_op
!= O_constant
&& exp
->X_op
!= O_symbol
)
1703 as_bad ("Bad direct addressing construct %s", s
);
1704 if (exp
->X_op
== O_constant
)
1706 if (exp
->X_add_number
< 0)
1707 as_bad ("Direct value of %ld is not suitable",
1708 (long) exp
->X_add_number
);
1710 operand
->mode
= M_DIRECT
;
1715 for (i
= 0; i
< tic4x_num_indirects
; i
++)
1716 if ((ret
= tic4x_indirect_parse (operand
, &tic4x_indirects
[i
])))
1720 if (i
< tic4x_num_indirects
)
1722 operand
->mode
= M_INDIRECT
;
1723 /* Indirect addressing mode number. */
1724 operand
->expr
.X_add_number
= tic4x_indirects
[i
].modn
;
1725 /* Convert *+ARn(0) to *ARn etc. Maybe we should
1726 squeal about silly ones? */
1727 if (operand
->expr
.X_add_number
< 0x08 && !operand
->disp
)
1728 operand
->expr
.X_add_number
= 0x18;
1731 as_bad ("Unknown indirect addressing mode");
1735 operand
->mode
= M_IMMED
; /* Assume immediate. */
1736 str
= input_line_pointer
;
1737 input_line_pointer
= tic4x_expression (input_line_pointer
, exp
);
1738 if (exp
->X_op
== O_register
)
1740 know (exp
->X_add_symbol
== 0);
1741 know (exp
->X_op_symbol
== 0);
1742 operand
->mode
= M_REGISTER
;
1745 else if (exp
->X_op
== O_big
)
1747 if (exp
->X_add_number
> 0)
1748 as_bad ("Number too large"); /* bignum required. */
1751 tic4x_gen_to_words (generic_floating_point_number
,
1752 operand
->fwords
, S_PRECISION
);
1753 operand
->mode
= M_IMMED_F
;
1757 #ifdef TIC4X_ALT_SYNTAX
1758 /* Allow ldi foo, ar0 to be equivalent to ldi @foo, ar0. */
1759 else if (exp
->X_op
== O_symbol
)
1761 operand
->mode
= M_DIRECT
;
1767 new = input_line_pointer
;
1768 input_line_pointer
= save
;
1773 tic4x_operands_match (inst
, insn
, check
)
1778 const char *args
= inst
->args
;
1779 unsigned long opcode
= inst
->opcode
;
1780 int num_operands
= insn
->num_operands
;
1781 tic4x_operand_t
*operand
= insn
->operands
;
1782 expressionS
*exp
= &operand
->expr
;
1786 /* Build the opcode, checking as we go to make sure that the
1789 If an operand matches, we modify insn or opcode appropriately,
1790 and do a "continue". If an operand fails to match, we "break". */
1792 insn
->nchars
= 4; /* Instructions always 4 bytes. */
1793 insn
->reloc
= NO_RELOC
;
1798 insn
->opcode
= opcode
;
1799 return num_operands
== 0;
1807 case '\0': /* End of args. */
1808 if (num_operands
== 1)
1810 insn
->opcode
= opcode
;
1813 break; /* Too many operands. */
1815 case '#': /* This is only used for ldp. */
1816 if (operand
->mode
!= M_DIRECT
&& operand
->mode
!= M_IMMED
)
1818 /* While this looks like a direct addressing mode, we actually
1819 use an immediate mode form of ldiu or ldpk instruction. */
1820 if (exp
->X_op
== O_constant
)
1822 if( ( IS_CPU_TIC4X (tic4x_cpu
) && exp
->X_add_number
<= 65535 )
1823 || ( IS_CPU_TIC3X (tic4x_cpu
) && exp
->X_add_number
<= 255 ) )
1825 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1831 as_bad ("Immediate value of %ld is too large for ldf",
1832 (long) exp
->X_add_number
);
1837 else if (exp
->X_op
== O_symbol
)
1839 insn
->reloc
= BFD_RELOC_HI16
;
1843 break; /* Not direct (dp) addressing. */
1845 case '@': /* direct. */
1846 if (operand
->mode
!= M_DIRECT
)
1848 if (exp
->X_op
== O_constant
)
1850 /* Store only the 16 LSBs of the number. */
1851 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1854 else if (exp
->X_op
== O_symbol
)
1856 insn
->reloc
= BFD_RELOC_LO16
;
1860 break; /* Not direct addressing. */
1863 if (operand
->mode
!= M_REGISTER
)
1865 reg
= exp
->X_add_number
;
1866 if (reg
>= REG_AR0
&& reg
<= REG_AR7
)
1867 INSERTU (opcode
, reg
- REG_AR0
, 24, 22);
1871 as_bad ("Destination register must be ARn");
1876 case 'B': /* Unsigned integer immediate. */
1877 /* Allow br label or br @label. */
1878 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
1880 if (exp
->X_op
== O_constant
)
1882 if (exp
->X_add_number
< (1 << 24))
1884 INSERTU (opcode
, exp
->X_add_number
, 23, 0);
1890 as_bad ("Immediate value of %ld is too large",
1891 (long) exp
->X_add_number
);
1896 if (IS_CPU_TIC4X (tic4x_cpu
))
1898 insn
->reloc
= BFD_RELOC_24_PCREL
;
1903 insn
->reloc
= BFD_RELOC_24
;
1910 if (!IS_CPU_TIC4X (tic4x_cpu
))
1912 if (operand
->mode
!= M_INDIRECT
)
1914 /* Require either *+ARn(disp) or *ARn. */
1915 if (operand
->expr
.X_add_number
!= 0
1916 && operand
->expr
.X_add_number
!= 0x18)
1919 as_bad ("Invalid indirect addressing mode");
1923 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1924 INSERTU (opcode
, operand
->disp
, 7, 3);
1928 if (!(operand
->mode
== M_REGISTER
))
1930 INSERTU (opcode
, exp
->X_add_number
, 7, 0);
1934 if (!(operand
->mode
== M_REGISTER
))
1936 reg
= exp
->X_add_number
;
1937 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1938 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1939 INSERTU (opcode
, reg
, 7, 0);
1943 as_bad ("Register must be Rn");
1949 if (operand
->mode
!= M_IMMED_F
1950 && !(operand
->mode
== M_IMMED
&& exp
->X_op
== O_constant
))
1953 if (operand
->mode
!= M_IMMED_F
)
1955 /* OK, we 've got something like cmpf 0, r0
1956 Why can't they stick in a bloody decimal point ?! */
1959 /* Create floating point number string. */
1960 sprintf (string
, "%d.0", (int) exp
->X_add_number
);
1961 tic4x_atof (string
, 's', operand
->fwords
);
1964 INSERTU (opcode
, operand
->fwords
[0], 15, 0);
1968 if (operand
->mode
!= M_REGISTER
)
1970 INSERTU (opcode
, exp
->X_add_number
, 15, 8);
1974 if (operand
->mode
!= M_REGISTER
)
1976 reg
= exp
->X_add_number
;
1977 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1978 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1979 INSERTU (opcode
, reg
, 15, 8);
1983 as_bad ("Register must be Rn");
1989 if (operand
->mode
!= M_REGISTER
)
1991 reg
= exp
->X_add_number
;
1992 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1993 INSERTU (opcode
, reg
- REG_R0
, 18, 16);
1997 as_bad ("Register must be R0--R7");
2003 if ( operand
->mode
== M_REGISTER
2004 && tic4x_oplevel
& OP_ENH
)
2006 reg
= exp
->X_add_number
;
2007 INSERTU (opcode
, reg
, 4, 0);
2008 INSERTU (opcode
, 7, 7, 5);
2014 if (operand
->mode
!= M_INDIRECT
)
2016 if (operand
->disp
!= 0 && operand
->disp
!= 1)
2018 if (IS_CPU_TIC4X (tic4x_cpu
))
2021 as_bad ("Invalid indirect addressing mode displacement %d",
2026 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
2027 INSERTU (opcode
, operand
->expr
.X_add_number
, 7, 3);
2031 if ( operand
->mode
== M_REGISTER
2032 && tic4x_oplevel
& OP_ENH
)
2034 reg
= exp
->X_add_number
;
2035 INSERTU (opcode
, reg
, 12, 8);
2036 INSERTU (opcode
, 7, 15, 13);
2042 if (operand
->mode
!= M_INDIRECT
)
2044 if (operand
->disp
!= 0 && operand
->disp
!= 1)
2046 if (IS_CPU_TIC4X (tic4x_cpu
))
2049 as_bad ("Invalid indirect addressing mode displacement %d",
2054 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2055 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
2059 if (operand
->mode
!= M_REGISTER
)
2061 reg
= exp
->X_add_number
;
2062 if (reg
>= REG_R0
&& reg
<= REG_R7
)
2063 INSERTU (opcode
, reg
- REG_R0
, 21, 19);
2067 as_bad ("Register must be R0--R7");
2073 if (operand
->mode
!= M_REGISTER
)
2075 reg
= exp
->X_add_number
;
2076 if (reg
>= REG_R0
&& reg
<= REG_R7
)
2077 INSERTU (opcode
, reg
- REG_R0
, 24, 22);
2081 as_bad ("Register must be R0--R7");
2087 if (operand
->mode
!= M_REGISTER
)
2089 reg
= exp
->X_add_number
;
2090 if (reg
== REG_R2
|| reg
== REG_R3
)
2091 INSERTU (opcode
, reg
- REG_R2
, 22, 22);
2095 as_bad ("Destination register must be R2 or R3");
2101 if (operand
->mode
!= M_REGISTER
)
2103 reg
= exp
->X_add_number
;
2104 if (reg
== REG_R0
|| reg
== REG_R1
)
2105 INSERTU (opcode
, reg
- REG_R0
, 23, 23);
2109 as_bad ("Destination register must be R0 or R1");
2115 if (!IS_CPU_TIC4X (tic4x_cpu
))
2117 if (operand
->mode
!= M_INDIRECT
)
2119 /* Require either *+ARn(disp) or *ARn. */
2120 if (operand
->expr
.X_add_number
!= 0
2121 && operand
->expr
.X_add_number
!= 0x18)
2124 as_bad ("Invalid indirect addressing mode");
2128 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2129 INSERTU (opcode
, operand
->disp
, 15, 11);
2132 case 'P': /* PC relative displacement. */
2133 /* Allow br label or br @label. */
2134 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
2136 if (exp
->X_op
== O_constant
)
2138 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 32767)
2140 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2146 as_bad ("Displacement value of %ld is too large",
2147 (long) exp
->X_add_number
);
2152 insn
->reloc
= BFD_RELOC_16_PCREL
;
2158 if (operand
->mode
!= M_REGISTER
)
2160 reg
= exp
->X_add_number
;
2161 INSERTU (opcode
, reg
, 15, 0);
2165 if (operand
->mode
!= M_REGISTER
)
2167 reg
= exp
->X_add_number
;
2168 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2169 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2170 INSERTU (opcode
, reg
, 15, 0);
2174 as_bad ("Register must be Rn");
2180 if (operand
->mode
!= M_REGISTER
)
2182 reg
= exp
->X_add_number
;
2183 INSERTU (opcode
, reg
, 20, 16);
2187 if (operand
->mode
!= M_REGISTER
)
2189 reg
= exp
->X_add_number
;
2190 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2191 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2192 INSERTU (opcode
, reg
, 20, 16);
2196 as_bad ("Register must be Rn");
2201 case 'S': /* Short immediate int. */
2202 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2204 if (exp
->X_op
== O_big
)
2207 as_bad ("Floating point number not valid in expression");
2211 if (exp
->X_op
== O_constant
)
2213 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 65535)
2215 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2221 as_bad ("Signed immediate value %ld too large",
2222 (long) exp
->X_add_number
);
2227 else if (exp
->X_op
== O_symbol
)
2229 if (operand
->mode
== M_HI
)
2231 insn
->reloc
= BFD_RELOC_HI16
;
2235 insn
->reloc
= BFD_RELOC_LO16
;
2240 /* Handle cases like ldi foo - $, ar0 where foo
2241 is a forward reference. Perhaps we should check
2242 for X_op == O_symbol and disallow things like
2244 insn
->reloc
= BFD_RELOC_16
;
2248 case 'T': /* 5-bit immediate value for tic4x stik. */
2249 if (!IS_CPU_TIC4X (tic4x_cpu
))
2251 if (operand
->mode
!= M_IMMED
)
2253 if (exp
->X_op
== O_constant
)
2255 if (exp
->X_add_number
< 16 && exp
->X_add_number
>= -16)
2257 INSERTS (opcode
, exp
->X_add_number
, 20, 16);
2263 as_bad ("Immediate value of %ld is too large",
2264 (long) exp
->X_add_number
);
2269 break; /* No relocations allowed. */
2271 case 'U': /* Unsigned integer immediate. */
2272 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2274 if (exp
->X_op
== O_constant
)
2276 if (exp
->X_add_number
< (1 << 16) && exp
->X_add_number
>= 0)
2278 INSERTU (opcode
, exp
->X_add_number
, 15, 0);
2284 as_bad ("Unsigned immediate value %ld too large",
2285 (long) exp
->X_add_number
);
2290 else if (exp
->X_op
== O_symbol
)
2292 if (operand
->mode
== M_HI
)
2293 insn
->reloc
= BFD_RELOC_HI16
;
2295 insn
->reloc
= BFD_RELOC_LO16
;
2300 insn
->reloc
= BFD_RELOC_16
;
2304 case 'V': /* Trap numbers (immediate field). */
2305 if (operand
->mode
!= M_IMMED
)
2307 if (exp
->X_op
== O_constant
)
2309 if (exp
->X_add_number
< 512 && IS_CPU_TIC4X (tic4x_cpu
))
2311 INSERTU (opcode
, exp
->X_add_number
, 8, 0);
2314 else if (exp
->X_add_number
< 32 && IS_CPU_TIC3X (tic4x_cpu
))
2316 INSERTU (opcode
, exp
->X_add_number
| 0x20, 4, 0);
2322 as_bad ("Immediate value of %ld is too large",
2323 (long) exp
->X_add_number
);
2328 break; /* No relocations allowed. */
2330 case 'W': /* Short immediate int (0--7). */
2331 if (!IS_CPU_TIC4X (tic4x_cpu
))
2333 if (operand
->mode
!= M_IMMED
)
2335 if (exp
->X_op
== O_big
)
2338 as_bad ("Floating point number not valid in expression");
2342 if (exp
->X_op
== O_constant
)
2344 if (exp
->X_add_number
>= -256 && exp
->X_add_number
<= 127)
2346 INSERTS (opcode
, exp
->X_add_number
, 7, 0);
2352 as_bad ("Immediate value %ld too large",
2353 (long) exp
->X_add_number
);
2358 insn
->reloc
= BFD_RELOC_16
;
2362 case 'X': /* Expansion register for tic4x. */
2363 if (operand
->mode
!= M_REGISTER
)
2365 reg
= exp
->X_add_number
;
2366 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2367 INSERTU (opcode
, reg
- REG_IVTP
, 4, 0);
2371 as_bad ("Register must be ivtp or tvtp");
2376 case 'Y': /* Address register for tic4x lda. */
2377 if (operand
->mode
!= M_REGISTER
)
2379 reg
= exp
->X_add_number
;
2380 if (reg
>= REG_AR0
&& reg
<= REG_SP
)
2381 INSERTU (opcode
, reg
, 20, 16);
2385 as_bad ("Register must be address register");
2390 case 'Z': /* Expansion register for tic4x. */
2391 if (operand
->mode
!= M_REGISTER
)
2393 reg
= exp
->X_add_number
;
2394 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2395 INSERTU (opcode
, reg
- REG_IVTP
, 20, 16);
2399 as_bad ("Register must be ivtp or tvtp");
2405 if (operand
->mode
!= M_INDIRECT
)
2407 INSERTS (opcode
, operand
->disp
, 7, 0);
2408 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2409 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
2412 case '|': /* treat as `,' if have ldi_ldi form. */
2415 if (--num_operands
< 0)
2416 break; /* Too few operands. */
2418 if (operand
->mode
!= M_PARALLEL
)
2423 case ',': /* Another operand. */
2424 if (--num_operands
< 0)
2425 break; /* Too few operands. */
2427 exp
= &operand
->expr
;
2430 case ';': /* Another optional operand. */
2431 if (num_operands
== 1 || operand
[1].mode
== M_PARALLEL
)
2433 if (--num_operands
< 0)
2434 break; /* Too few operands. */
2436 exp
= &operand
->expr
;
2447 tic4x_insn_check (insn
)
2451 if (!strcmp(insn
->name
, "lda"))
2453 if (insn
->num_operands
< 2 || insn
->num_operands
> 2)
2454 as_fatal ("Illegal internal LDA insn definition");
2456 if ( insn
->operands
[0].mode
== M_REGISTER
2457 && insn
->operands
[1].mode
== M_REGISTER
2458 && insn
->operands
[0].expr
.X_add_number
== insn
->operands
[1].expr
.X_add_number
)
2459 as_bad ("Source and destination register should not be equal");
2461 else if( !strcmp(insn
->name
, "ldi_ldi")
2462 || !strcmp(insn
->name
, "ldi1_ldi2")
2463 || !strcmp(insn
->name
, "ldi2_ldi1")
2464 || !strcmp(insn
->name
, "ldf_ldf")
2465 || !strcmp(insn
->name
, "ldf1_ldf2")
2466 || !strcmp(insn
->name
, "ldf2_ldf1") )
2468 if ( insn
->num_operands
< 4 && insn
->num_operands
> 5 )
2469 as_fatal ("Illegal internal %s insn definition", insn
->name
);
2471 if ( insn
->operands
[1].mode
== M_REGISTER
2472 && insn
->operands
[insn
->num_operands
-1].mode
== M_REGISTER
2473 && insn
->operands
[1].expr
.X_add_number
== insn
->operands
[insn
->num_operands
-1].expr
.X_add_number
)
2474 as_warn ("Equal parallell destination registers, one result will be discarded");
2479 tic4x_insn_output (insn
)
2484 /* Grab another fragment for opcode. */
2485 dst
= frag_more (insn
->nchars
);
2487 /* Put out opcode word as a series of bytes in little endian order. */
2488 md_number_to_chars (dst
, insn
->opcode
, insn
->nchars
);
2490 /* Put out the symbol-dependent stuff. */
2491 if (insn
->reloc
!= NO_RELOC
)
2493 /* Where is the offset into the fragment for this instruction. */
2494 fix_new_exp (frag_now
,
2495 dst
- frag_now
->fr_literal
, /* where */
2496 insn
->nchars
, /* size */
2503 /* Parse the operands. */
2505 tic4x_operands_parse (s
, operands
, num_operands
)
2507 tic4x_operand_t
*operands
;
2511 return num_operands
;
2514 s
= tic4x_operand_parse (s
, &operands
[num_operands
++]);
2515 while (num_operands
< TIC4X_OPERANDS_MAX
&& *s
++ == ',');
2517 if (num_operands
> TIC4X_OPERANDS_MAX
)
2519 as_bad ("Too many operands scanned");
2522 return num_operands
;
2525 /* Assemble a single instruction. Its label has already been handled
2526 by the generic front end. We just parse mnemonic and operands, and
2527 produce the bytes of data and relocation. */
2536 tic4x_inst_t
*inst
; /* Instruction template. */
2537 tic4x_inst_t
*first_inst
;
2539 /* Scan for parallel operators */
2543 while (*s
&& *s
!= '|')
2546 if (*s
&& s
[1]=='|')
2550 as_bad ("Parallel opcode cannot contain more than two instructions");
2556 /* Lets take care of the first part of the parallel insn */
2561 /* .. and let the second run though here */
2565 if (str
&& insn
->parallel
)
2567 /* Find mnemonic (second part of parallel instruction). */
2569 /* Skip past instruction mnemonic. */
2570 while (*s
&& *s
!= ' ')
2572 if (*s
) /* Null terminate for hash_find. */
2573 *s
++ = '\0'; /* and skip past null. */
2574 strcat (insn
->name
, "_");
2575 strncat (insn
->name
, str
, TIC4X_NAME_MAX
- strlen (insn
->name
));
2577 insn
->operands
[insn
->num_operands
++].mode
= M_PARALLEL
;
2579 if ((i
= tic4x_operands_parse
2580 (s
, insn
->operands
, insn
->num_operands
)) < 0)
2586 insn
->num_operands
= i
;
2592 if ((insn
->inst
= (struct tic4x_inst
*)
2593 hash_find (tic4x_op_hash
, insn
->name
)) == NULL
)
2595 as_bad ("Unknown opcode `%s'.", insn
->name
);
2605 ok
= tic4x_operands_match (inst
, insn
, 1);
2612 } while (!ok
&& !strcmp (inst
->name
, inst
[1].name
) && inst
++);
2616 tic4x_insn_check (insn
);
2617 tic4x_insn_output (insn
);
2622 tic4x_operands_match (first_inst
, insn
, 0);
2623 as_bad ("Invalid operands for %s", insn
->name
);
2626 as_bad ("Invalid instruction %s", insn
->name
);
2631 /* Find mnemonic. */
2633 while (*s
&& *s
!= ' ') /* Skip past instruction mnemonic. */
2635 if (*s
) /* Null terminate for hash_find. */
2636 *s
++ = '\0'; /* and skip past null. */
2637 strncpy (insn
->name
, str
, TIC4X_NAME_MAX
- 3);
2639 if ((i
= tic4x_operands_parse (s
, insn
->operands
, 0)) < 0)
2641 insn
->inst
= NULL
; /* Flag that error occurred. */
2646 insn
->num_operands
= i
;
2661 /* Turn a string in input_line_pointer into a floating point constant
2662 of type type, and store the appropriate bytes in *litP. The number
2663 of LITTLENUMS emitted is stored in *sizeP. An error message is
2664 returned, or NULL on OK. */
2667 md_atof (type
, litP
, sizeP
)
2674 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2675 LITTLENUM_TYPE
*wordP
;
2680 case 's': /* .single */
2686 case 'd': /* .double */
2688 case 'f': /* .float or .single */
2691 prec
= 2; /* 1 32-bit word */
2694 case 'i': /* .ieee */
2698 type
= 'f'; /* Rewrite type to be usable by atof_ieee() */
2701 case 'e': /* .ldouble */
2703 prec
= 4; /* 2 32-bit words */
2709 return "Bad call to md_atof()";
2713 t
= atof_ieee (input_line_pointer
, type
, words
);
2715 t
= tic4x_atof (input_line_pointer
, type
, words
);
2717 input_line_pointer
= t
;
2718 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
2720 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
2721 little endian byte order. */
2722 /* SES: However it is required to put the words (32-bits) out in the
2723 correct order, hence we write 2 and 2 littlenums in little endian
2724 order, while we keep the original order on successive words. */
2725 for(wordP
= words
; wordP
<(words
+prec
) ; wordP
+=2)
2727 if (wordP
<(words
+prec
-1)) /* Dump wordP[1] (if we have one) */
2729 md_number_to_chars (litP
, (valueT
) (wordP
[1]),
2730 sizeof (LITTLENUM_TYPE
));
2731 litP
+= sizeof (LITTLENUM_TYPE
);
2735 md_number_to_chars (litP
, (valueT
) (wordP
[0]),
2736 sizeof (LITTLENUM_TYPE
));
2737 litP
+= sizeof (LITTLENUM_TYPE
);
2743 md_apply_fix (fixP
, value
, seg
)
2746 segT seg ATTRIBUTE_UNUSED
;
2748 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
2749 valueT val
= *value
;
2751 switch (fixP
->fx_r_type
)
2753 case BFD_RELOC_HI16
:
2757 case BFD_RELOC_LO16
:
2764 switch (fixP
->fx_r_type
)
2769 case BFD_RELOC_24_PCREL
:
2772 case BFD_RELOC_16_PCREL
:
2773 case BFD_RELOC_LO16
:
2774 case BFD_RELOC_HI16
:
2781 as_bad ("Bad relocation type: 0x%02x", fixP
->fx_r_type
);
2785 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0) fixP
->fx_done
= 1;
2788 /* Should never be called for tic4x. */
2790 md_convert_frag (headers
, sec
, fragP
)
2791 bfd
*headers ATTRIBUTE_UNUSED
;
2792 segT sec ATTRIBUTE_UNUSED
;
2793 fragS
*fragP ATTRIBUTE_UNUSED
;
2795 as_fatal ("md_convert_frag");
2798 /* Should never be called for tic4x. */
2800 md_create_short_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
2801 char *ptr ATTRIBUTE_UNUSED
;
2802 addressT from_addr ATTRIBUTE_UNUSED
;
2803 addressT to_addr ATTRIBUTE_UNUSED
;
2804 fragS
*frag ATTRIBUTE_UNUSED
;
2805 symbolS
*to_symbol ATTRIBUTE_UNUSED
;
2807 as_fatal ("md_create_short_jmp\n");
2810 /* Should never be called for tic4x. */
2812 md_create_long_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
2813 char *ptr ATTRIBUTE_UNUSED
;
2814 addressT from_addr ATTRIBUTE_UNUSED
;
2815 addressT to_addr ATTRIBUTE_UNUSED
;
2816 fragS
*frag ATTRIBUTE_UNUSED
;
2817 symbolS
*to_symbol ATTRIBUTE_UNUSED
;
2819 as_fatal ("md_create_long_jump\n");
2822 /* Should never be called for tic4x. */
2824 md_estimate_size_before_relax (fragP
, segtype
)
2825 register fragS
*fragP ATTRIBUTE_UNUSED
;
2826 segT segtype ATTRIBUTE_UNUSED
;
2828 as_fatal ("md_estimate_size_before_relax\n");
2834 md_parse_option (c
, arg
)
2840 case OPTION_CPU
: /* cpu brand */
2841 if (TOLOWER (*arg
) == 'c')
2843 tic4x_cpu
= atoi (arg
);
2844 if (!IS_CPU_TIC3X (tic4x_cpu
) && !IS_CPU_TIC4X (tic4x_cpu
))
2845 as_warn ("Unsupported processor generation %d", tic4x_cpu
);
2848 case OPTION_REV
: /* cpu revision */
2849 tic4x_revision
= atoi (arg
);
2853 as_warn ("Option -b is depreciated, please use -mbig");
2854 case OPTION_BIG
: /* big model */
2855 tic4x_big_model
= 1;
2859 as_warn ("Option -p is depreciated, please use -mmemparm");
2860 case OPTION_MEMPARM
: /* push args */
2865 as_warn ("Option -r is depreciated, please use -mregparm");
2866 case OPTION_REGPARM
: /* register args */
2871 as_warn ("Option -s is depreciated, please use -msmall");
2872 case OPTION_SMALL
: /* small model */
2873 tic4x_big_model
= 0;
2880 case OPTION_LOWPOWER
:
2884 case OPTION_ENHANCED
:
2896 md_show_usage (stream
)
2900 _("\nTIC4X options:\n"
2901 " -mcpu=CPU -mCPU select architecture variant. CPU can be:\n"
2903 " 31 - TMS320C31, TMS320LC31\n"
2905 " 33 - TMS320VC33\n"
2908 " -mrev=REV set cpu hardware revision (integer numbers).\n"
2909 " Combinations of -mcpu and -mrev will enable/disable\n"
2910 " the appropriate options (-midle2, -mlowpower and\n"
2911 " -menhanced) according to the selected type\n"
2912 " -mbig select big memory model\n"
2913 " -msmall select small memory model (default)\n"
2914 " -mregparm select register parameters (default)\n"
2915 " -mmemparm select memory parameters\n"
2916 " -midle2 enable IDLE2 support\n"
2917 " -mlowpower enable LOPOWER and MAXSPEED support\n"
2918 " -menhanced enable enhanced opcode support\n"));
2921 /* This is called when a line is unrecognized. This is used to handle
2922 definitions of TI C3x tools style local labels $n where n is a single
2925 tic4x_unrecognized_line (c
)
2931 if (c
!= '$' || ! ISDIGIT (input_line_pointer
[0]))
2934 s
= input_line_pointer
;
2936 /* Let's allow multiple digit local labels. */
2938 while (ISDIGIT (*s
))
2940 lab
= lab
* 10 + *s
- '0';
2944 if (dollar_label_defined (lab
))
2946 as_bad ("Label \"$%d\" redefined", lab
);
2950 define_dollar_label (lab
);
2951 colon (dollar_label_name (lab
, 0));
2952 input_line_pointer
= s
+ 1;
2957 /* Handle local labels peculiar to us referred to in an expression. */
2959 md_undefined_symbol (name
)
2962 /* Look for local labels of the form $n. */
2963 if (name
[0] == '$' && ISDIGIT (name
[1]))
2969 while (ISDIGIT ((unsigned char) *s
))
2971 lab
= lab
* 10 + *s
- '0';
2974 if (dollar_label_defined (lab
))
2976 name
= dollar_label_name (lab
, 0);
2977 symbolP
= symbol_find (name
);
2981 name
= dollar_label_name (lab
, 1);
2982 symbolP
= symbol_find_or_make (name
);
2990 /* Parse an operand that is machine-specific. */
2992 md_operand (expressionP
)
2993 expressionS
*expressionP ATTRIBUTE_UNUSED
;
2997 /* Round up a section size to the appropriate boundary---do we need this? */
2999 md_section_align (segment
, size
)
3000 segT segment ATTRIBUTE_UNUSED
;
3003 return size
; /* Byte (i.e., 32-bit) alignment is fine? */
3007 tic4x_pc_offset (op
)
3010 /* Determine the PC offset for a C[34]x instruction.
3011 This could be simplified using some boolean algebra
3012 but at the expense of readability. */
3016 case 0x62: /* call (C4x) */
3017 case 0x64: /* rptb (C4x) */
3019 case 0x61: /* brd */
3020 case 0x63: /* laj */
3021 case 0x65: /* rptbd (C4x) */
3023 case 0x66: /* swi */
3030 switch ((op
& 0xffe00000) >> 20)
3032 case 0x6a0: /* bB */
3033 case 0x720: /* callB */
3034 case 0x740: /* trapB */
3037 case 0x6a2: /* bBd */
3038 case 0x6a6: /* bBat */
3039 case 0x6aa: /* bBaf */
3040 case 0x722: /* lajB */
3041 case 0x748: /* latB */
3042 case 0x798: /* rptbd */
3049 switch ((op
& 0xfe200000) >> 20)
3051 case 0x6e0: /* dbB */
3054 case 0x6e2: /* dbBd */
3064 /* Exactly what point is a PC-relative offset relative TO?
3065 With the C3x we have the following:
3066 DBcond, Bcond disp + PC + 1 => PC
3067 DBcondD, BcondD disp + PC + 3 => PC
3070 md_pcrel_from (fixP
)
3076 buf
= (unsigned char *) fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
3077 op
= (buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
3079 return ((fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) >> 2) +
3080 tic4x_pc_offset (op
);
3083 /* Fill the alignment area with NOP's on .text, unless fill-data
3086 tic4x_do_align (alignment
, fill
, len
, max
)
3087 int alignment ATTRIBUTE_UNUSED
;
3088 const char *fill ATTRIBUTE_UNUSED
;
3089 int len ATTRIBUTE_UNUSED
;
3090 int max ATTRIBUTE_UNUSED
;
3092 unsigned long nop
= TIC_NOP_OPCODE
;
3094 /* Because we are talking lwords, not bytes, adjust alignment to do words */
3097 if (alignment
!= 0 && !need_pass_2
)
3101 /*if (subseg_text_p (now_seg))*/ /* FIXME: doesn't work for .text for some reason */
3102 frag_align_pattern( alignment
, (const char *)&nop
, sizeof(nop
), max
);
3105 frag_align (alignment, 0, max);*/
3108 frag_align (alignment
, *fill
, max
);
3110 frag_align_pattern (alignment
, fill
, len
, max
);
3113 /* Return 1 to skip the default alignment function */
3117 /* Look for and remove parallel instruction operator ||. */
3121 char *s
= input_line_pointer
;
3125 /* If parallel instruction prefix found at start of line, skip it. */
3126 if (*input_line_pointer
== '|' && input_line_pointer
[1] == '|')
3131 input_line_pointer
++;
3132 *input_line_pointer
= ' ';
3133 /* So line counters get bumped. */
3134 input_line_pointer
[-1] = '\n';
3139 /* Write out the previous insn here */
3142 input_line_pointer
= s
;
3147 tc_gen_reloc (seg
, fixP
)
3148 asection
*seg ATTRIBUTE_UNUSED
;
3153 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
3155 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
3156 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
3157 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
3158 reloc
->address
/= OCTETS_PER_BYTE
;
3159 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
3160 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
3162 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3163 "Reloc %d not supported by object file format",
3164 (int) fixP
->fx_r_type
);
3168 if (fixP
->fx_r_type
== BFD_RELOC_HI16
)
3169 reloc
->addend
= fixP
->fx_offset
;
3171 reloc
->addend
= fixP
->fx_addnumber
;