1 /* tc-tic4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
2 Copyright (C) 1997,1998, 2002, 2003, 2005 Free Software Foundation.
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 2, 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 fills all section with NOP's when used regardless if has
30 been used in .text or .data. (However the .align is primarily
31 intended used in .text sections. If you require something else,
32 use .align <size>,0x00)
34 o .align: Implement a 'bu' insn if the number of nop's exceeds 4
35 within the align frag. if(fragsize>4words) insert bu fragend+1
38 o .usect if has symbol on previous line not implemented
40 o .sym, .eos, .stag, .etag, .member not implemented
42 o Evaluation of constant floating point expressions (expr.c needs
45 o Support 'abc' constants (that is 0x616263)
49 #include "safe-ctype.h"
51 #include "opcode/tic4x.h"
57 /* OK, we accept a syntax similar to the other well known C30
58 assembly tools. With TIC4X_ALT_SYNTAX defined we are more
59 flexible, allowing a more Unix-like syntax: `%' in front of
60 register names, `#' in front of immediate constants, and
61 not requiring `@' in front of direct addresses. */
63 #define TIC4X_ALT_SYNTAX
65 /* Equal to MAX_PRECISION in atof-ieee.c. */
66 #define MAX_LITTLENUMS 6 /* (12 bytes) */
68 /* Handle of the inst mnemonic hash table. */
69 static struct hash_control
*tic4x_op_hash
= NULL
;
71 /* Handle asg pseudo. */
72 static struct hash_control
*tic4x_asg_hash
= NULL
;
74 static unsigned int tic4x_cpu
= 0; /* Default to TMS320C40. */
75 static unsigned int tic4x_revision
= 0; /* CPU revision */
76 static unsigned int tic4x_idle2
= 0; /* Idle2 support */
77 static unsigned int tic4x_lowpower
= 0; /* Lowpower support */
78 static unsigned int tic4x_enhanced
= 0; /* Enhanced opcode support */
79 static unsigned int tic4x_big_model
= 0; /* Default to small memory model. */
80 static unsigned int tic4x_reg_args
= 0; /* Default to args passed on stack. */
81 static unsigned long tic4x_oplevel
= 0; /* Opcode level */
83 #define OPTION_CPU 'm'
84 #define OPTION_BIG (OPTION_MD_BASE + 1)
85 #define OPTION_SMALL (OPTION_MD_BASE + 2)
86 #define OPTION_MEMPARM (OPTION_MD_BASE + 3)
87 #define OPTION_REGPARM (OPTION_MD_BASE + 4)
88 #define OPTION_IDLE2 (OPTION_MD_BASE + 5)
89 #define OPTION_LOWPOWER (OPTION_MD_BASE + 6)
90 #define OPTION_ENHANCED (OPTION_MD_BASE + 7)
91 #define OPTION_REV (OPTION_MD_BASE + 8)
93 CONST
char *md_shortopts
= "bm:prs";
94 struct option md_longopts
[] =
96 { "mcpu", required_argument
, NULL
, OPTION_CPU
},
97 { "mdsp", required_argument
, NULL
, OPTION_CPU
},
98 { "mbig", no_argument
, NULL
, OPTION_BIG
},
99 { "msmall", no_argument
, NULL
, OPTION_SMALL
},
100 { "mmemparm", no_argument
, NULL
, OPTION_MEMPARM
},
101 { "mregparm", no_argument
, NULL
, OPTION_REGPARM
},
102 { "midle2", no_argument
, NULL
, OPTION_IDLE2
},
103 { "mlowpower", no_argument
, NULL
, OPTION_LOWPOWER
},
104 { "menhanced", no_argument
, NULL
, OPTION_ENHANCED
},
105 { "mrev", required_argument
, NULL
, OPTION_REV
},
106 { NULL
, no_argument
, NULL
, 0 }
109 size_t md_longopts_size
= sizeof (md_longopts
);
114 M_UNKNOWN
, M_IMMED
, M_DIRECT
, M_REGISTER
, M_INDIRECT
,
115 M_IMMED_F
, M_PARALLEL
, M_HI
119 typedef struct tic4x_operand
121 tic4x_addr_mode_t mode
; /* Addressing mode. */
122 expressionS expr
; /* Expression. */
123 int disp
; /* Displacement for indirect addressing. */
124 int aregno
; /* Aux. register number. */
125 LITTLENUM_TYPE fwords
[MAX_LITTLENUMS
]; /* Float immed. number. */
129 typedef struct tic4x_insn
131 char name
[TIC4X_NAME_MAX
]; /* Mnemonic of instruction. */
132 unsigned int in_use
; /* True if in_use. */
133 unsigned int parallel
; /* True if parallel instruction. */
134 unsigned int nchars
; /* This is always 4 for the C30. */
135 unsigned long opcode
; /* Opcode number. */
136 expressionS exp
; /* Expression required for relocation. */
137 int reloc
; /* Relocation type required. */
138 int pcrel
; /* True if relocation PC relative. */
139 char *pname
; /* Name of instruction in parallel. */
140 unsigned int num_operands
; /* Number of operands in total. */
141 tic4x_inst_t
*inst
; /* Pointer to first template. */
142 tic4x_operand_t operands
[TIC4X_OPERANDS_MAX
];
146 static tic4x_insn_t the_insn
; /* Info about our instruction. */
147 static tic4x_insn_t
*insn
= &the_insn
;
149 static int tic4x_gen_to_words
150 PARAMS ((FLONUM_TYPE
, LITTLENUM_TYPE
*, int ));
151 static char *tic4x_atof
152 PARAMS ((char *, char, LITTLENUM_TYPE
* ));
153 static void tic4x_insert_reg
154 PARAMS ((char *, int ));
155 static void tic4x_insert_sym
156 PARAMS ((char *, int ));
157 static char *tic4x_expression
158 PARAMS ((char *, expressionS
*));
159 static char *tic4x_expression_abs
160 PARAMS ((char *, offsetT
*));
161 static void tic4x_emit_char
162 PARAMS ((char, int));
163 static void tic4x_seg_alloc
164 PARAMS ((char *, segT
, int, symbolS
*));
165 static void tic4x_asg
167 static void tic4x_bss
169 static void tic4x_globl
171 static void tic4x_cons
173 static void tic4x_stringer
175 static void tic4x_eval
177 static void tic4x_newblock
179 static void tic4x_sect
181 static void tic4x_set
183 static void tic4x_usect
185 static void tic4x_version
187 static void tic4x_init_regtable
189 static void tic4x_init_symbols
191 static int tic4x_inst_insert
192 PARAMS ((tic4x_inst_t
*));
193 static tic4x_inst_t
*tic4x_inst_make
194 PARAMS ((char *, unsigned long, char *));
195 static int tic4x_inst_add
196 PARAMS ((tic4x_inst_t
*));
199 static int tic4x_indirect_parse
200 PARAMS ((tic4x_operand_t
*, const tic4x_indirect_t
*));
201 static char *tic4x_operand_parse
202 PARAMS ((char *, tic4x_operand_t
*));
203 static int tic4x_operands_match
204 PARAMS ((tic4x_inst_t
*, tic4x_insn_t
*, int));
205 static void tic4x_insn_check
206 PARAMS ((tic4x_insn_t
*));
207 static void tic4x_insn_output
208 PARAMS ((tic4x_insn_t
*));
209 static int tic4x_operands_parse
210 PARAMS ((char *, tic4x_operand_t
*, int ));
213 int tic4x_unrecognized_line
215 static int tic4x_pc_offset
216 PARAMS ((unsigned int));
218 PARAMS ((int, const char *, int, int));
219 void tic4x_start_line
221 arelent
*tc_gen_reloc
222 PARAMS ((asection
*, fixS
*));
228 {"align", s_align_bytes
, 32},
229 {"ascii", tic4x_stringer
, 1},
230 {"asciz", tic4x_stringer
, 0},
231 {"asg", tic4x_asg
, 0},
232 {"block", s_space
, 4},
233 {"byte", tic4x_cons
, 1},
234 {"bss", tic4x_bss
, 0},
235 {"copy", s_include
, 0},
236 {"def", tic4x_globl
, 0},
237 {"equ", tic4x_set
, 0},
238 {"eval", tic4x_eval
, 0},
239 {"global", tic4x_globl
, 0},
240 {"globl", tic4x_globl
, 0},
241 {"hword", tic4x_cons
, 2},
242 {"ieee", float_cons
, 'i'},
243 {"int", tic4x_cons
, 4}, /* .int allocates 4 bytes. */
244 {"ldouble", float_cons
, 'e'},
245 {"newblock", tic4x_newblock
, 0},
246 {"ref", s_ignore
, 0}, /* All undefined treated as external. */
247 {"set", tic4x_set
, 0},
248 {"sect", tic4x_sect
, 1}, /* Define named section. */
249 {"space", s_space
, 4},
250 {"string", tic4x_stringer
, 0},
251 {"usect", tic4x_usect
, 0}, /* Reserve space in uninit. named sect. */
252 {"version", tic4x_version
, 0},
253 {"word", tic4x_cons
, 4}, /* .word allocates 4 bytes. */
254 {"xdef", tic4x_globl
, 0},
258 int md_short_jump_size
= 4;
259 int md_long_jump_size
= 4;
261 /* This array holds the chars that always start a comment. If the
262 pre-processor is disabled, these aren't very useful. */
263 #ifdef TIC4X_ALT_SYNTAX
264 const char comment_chars
[] = ";!";
266 const char comment_chars
[] = ";";
269 /* This array holds the chars that only start a comment at the beginning of
270 a line. If the line seems to have the form '# 123 filename'
271 .line and .file directives will appear in the pre-processed output.
272 Note that input_file.c hand checks for '#' at the beginning of the
273 first line of the input file. This is because the compiler outputs
274 #NO_APP at the beginning of its output.
275 Also note that comments like this one will always work. */
276 const char line_comment_chars
[] = "#*";
278 /* We needed an unused char for line separation to work around the
279 lack of macros, using sed and such. */
280 const char line_separator_chars
[] = "&";
282 /* Chars that can be used to separate mant from exp in floating point nums. */
283 const char EXP_CHARS
[] = "eE";
285 /* Chars that mean this number is a floating point constant. */
288 const char FLT_CHARS
[] = "fFilsS";
290 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
291 changed in read.c. Ideally it shouldn't have to know about it at
292 all, but nothing is ideal around here. */
294 /* Flonums returned here. */
295 extern FLONUM_TYPE generic_floating_point_number
;
297 /* Precision in LittleNums. */
298 #define MAX_PRECISION (4) /* Its a bit overkill for us, but the code
300 #define S_PRECISION (1) /* Short float constants 16-bit. */
301 #define F_PRECISION (2) /* Float and double types 32-bit. */
302 #define E_PRECISION (4) /* Extended precision, 64-bit (real 40-bit). */
305 /* Turn generic_floating_point_number into a real short/float/double. */
307 tic4x_gen_to_words (flonum
, words
, precision
)
309 LITTLENUM_TYPE
*words
;
312 int return_value
= 0;
313 LITTLENUM_TYPE
*p
; /* Littlenum pointer. */
314 int mantissa_bits
; /* Bits in mantissa field. */
315 int exponent_bits
; /* Bits in exponent field. */
317 unsigned int sone
; /* Scaled one. */
318 unsigned int sfract
; /* Scaled fraction. */
319 unsigned int smant
; /* Scaled mantissa. */
321 unsigned int mover
; /* Mantissa overflow bits */
322 unsigned int rbit
; /* Round bit. */
323 int shift
; /* Shift count. */
325 /* NOTE: Svein Seldal <Svein@dev.seldal.com>
326 The code in this function is altered slightly to support floats
327 with 31-bits mantissas, thus the documentation below may be a
328 little bit inaccurate.
330 By Michael P. Hayes <m.hayes@elec.canterbury.ac.nz>
331 Here is how a generic floating point number is stored using
332 flonums (an extension of bignums) where p is a pointer to an
335 For example 2e-3 is stored with exp = -4 and
342 with low = &bits[2], high = &bits[5], and leader = &bits[5].
344 This number can be written as
345 0x0083126e978d4fde.00000000 * 65536**-4 or
346 0x0.0083126e978d4fde * 65536**0 or
347 0x0.83126e978d4fde * 2**-8 = 2e-3
349 Note that low points to the 65536**0 littlenum (bits[2]) and
350 leader points to the most significant non-zero littlenum
353 TMS320C3X floating point numbers are a bit of a strange beast.
354 The 32-bit flavour has the 8 MSBs representing the exponent in
355 twos complement format (-128 to +127). There is then a sign bit
356 followed by 23 bits of mantissa. The mantissa is expressed in
357 twos complement format with the binary point after the most
358 significant non sign bit. The bit after the binary point is
359 suppressed since it is the complement of the sign bit. The
360 effective mantissa is thus 24 bits. Zero is represented by an
363 The 16-bit flavour has the 4 MSBs representing the exponent in
364 twos complement format (-8 to +7). There is then a sign bit
365 followed by 11 bits of mantissa. The mantissa is expressed in
366 twos complement format with the binary point after the most
367 significant non sign bit. The bit after the binary point is
368 suppressed since it is the complement of the sign bit. The
369 effective mantissa is thus 12 bits. Zero is represented by an
370 exponent of -8. For example,
372 number norm mant m x e s i fraction f
373 +0.500 => 1.00000000000 -1 -1 0 1 .00000000000 (1 + 0) * 2^(-1)
374 +0.999 => 1.11111111111 -1 -1 0 1 .11111111111 (1 + 0.99) * 2^(-1)
375 +1.000 => 1.00000000000 0 0 0 1 .00000000000 (1 + 0) * 2^(0)
376 +1.500 => 1.10000000000 0 0 0 1 .10000000000 (1 + 0.5) * 2^(0)
377 +1.999 => 1.11111111111 0 0 0 1 .11111111111 (1 + 0.9) * 2^(0)
378 +2.000 => 1.00000000000 1 1 0 1 .00000000000 (1 + 0) * 2^(1)
379 +4.000 => 1.00000000000 2 2 0 1 .00000000000 (1 + 0) * 2^(2)
380 -0.500 => 1.00000000000 -1 -1 1 0 .10000000000 (-2 + 0) * 2^(-2)
381 -1.000 => 1.00000000000 0 -1 1 0 .00000000000 (-2 + 0) * 2^(-1)
382 -1.500 => 1.10000000000 0 0 1 0 .10000000000 (-2 + 0.5) * 2^(0)
383 -1.999 => 1.11111111111 0 0 1 0 .00000000001 (-2 + 0.11) * 2^(0)
384 -2.000 => 1.00000000000 1 1 1 0 .00000000000 (-2 + 0) * 2^(0)
385 -4.000 => 1.00000000000 2 1 1 0 .00000000000 (-2 + 0) * 2^(1)
387 where e is the exponent, s is the sign bit, i is the implied bit,
388 and f is the fraction stored in the mantissa field.
390 num = (1 + f) * 2^x = m * 2^e if s = 0
391 num = (-2 + f) * 2^x = -m * 2^e if s = 1
392 where 0 <= f < 1.0 and 1.0 <= m < 2.0
394 The fraction (f) and exponent (e) fields for the TMS320C3X format
395 can be derived from the normalised mantissa (m) and exponent (x) using:
397 f = m - 1, e = x if s = 0
398 f = 2 - m, e = x if s = 1 and m != 1.0
399 f = 0, e = x - 1 if s = 1 and m = 1.0
400 f = 0, e = -8 if m = 0
403 OK, the other issue we have to consider is rounding since the
404 mantissa has a much higher potential precision than what we can
405 represent. To do this we add half the smallest storable fraction.
406 We then have to renormalise the number to allow for overflow.
408 To convert a generic flonum into a TMS320C3X floating point
409 number, here's what we try to do....
411 The first thing is to generate a normalised mantissa (m) where
412 1.0 <= m < 2 and to convert the exponent from base 16 to base 2.
413 We desire the binary point to be placed after the most significant
414 non zero bit. This process is done in two steps: firstly, the
415 littlenum with the most significant non zero bit is located (this
416 is done for us since leader points to this littlenum) and the
417 binary point (which is currently after the LSB of the littlenum
418 pointed to by low) is moved to before the MSB of the littlenum
419 pointed to by leader. This requires the exponent to be adjusted
420 by leader - low + 1. In the earlier example, the new exponent is
421 thus -4 + (5 - 2 + 1) = 0 (base 65536). We now need to convert
422 the exponent to base 2 by multiplying the exponent by 16 (log2
423 65536). The exponent base 2 is thus also zero.
425 The second step is to hunt for the most significant non zero bit
426 in the leader littlenum. We do this by left shifting a copy of
427 the leader littlenum until bit 16 is set (0x10000) and counting
428 the number of shifts, S, required. The number of shifts then has to
429 be added to correct the exponent (base 2). For our example, this
430 will require 9 shifts and thus our normalised exponent (base 2) is
431 0 + 9 = 9. Note that the worst case scenario is when the leader
432 littlenum is 1, thus requiring 16 shifts.
434 We now have to left shift the other littlenums by the same amount,
435 propagating the shifted bits into the more significant littlenums.
436 To save a lot of unnecessary shifting we only have to consider
437 two or three littlenums, since the greatest number of mantissa
438 bits required is 24 + 1 rounding bit. While two littlenums
439 provide 32 bits of precision, the most significant littlenum
440 may only contain a single significant bit and thus an extra
441 littlenum is required.
443 Denoting the number of bits in the fraction field as F, we require
444 G = F + 2 bits (one extra bit is for rounding, the other gets
445 suppressed). Say we required S shifts to find the most
446 significant bit in the leader littlenum, the number of left shifts
447 required to move this bit into bit position G - 1 is L = G + S - 17.
448 Note that this shift count may be negative for the short floating
449 point flavour (where F = 11 and thus G = 13 and potentially S < 3).
450 If L > 0 we have to shunt the next littlenum into position. Bit
451 15 (the MSB) of the next littlenum needs to get moved into position
452 L - 1 (If L > 15 we need all the bits of this littlenum and
453 some more from the next one.). We subtract 16 from L and use this
454 as the left shift count; the resultant value we or with the
455 previous result. If L > 0, we repeat this operation. */
457 if (precision
!= S_PRECISION
)
459 if (precision
== E_PRECISION
)
460 words
[2] = words
[3] = 0x0000;
462 /* 0.0e0 or NaN seen. */
463 if (flonum
.low
> flonum
.leader
/* = 0.0e0 */
464 || flonum
.sign
== 0) /* = NaN */
467 as_bad ("Nan, using zero.");
472 if (flonum
.sign
== 'P')
474 /* +INF: Replace with maximum float. */
475 if (precision
== S_PRECISION
)
482 if (precision
== E_PRECISION
)
489 else if (flonum
.sign
== 'N')
491 /* -INF: Replace with maximum float. */
492 if (precision
== S_PRECISION
)
496 if (precision
== E_PRECISION
)
501 exponent
= (flonum
.exponent
+ flonum
.leader
- flonum
.low
+ 1) * 16;
503 if (!(tmp
= *flonum
.leader
))
504 abort (); /* Hmmm. */
505 shift
= 0; /* Find position of first sig. bit. */
508 exponent
-= (16 - shift
); /* Adjust exponent. */
510 if (precision
== S_PRECISION
) /* Allow 1 rounding bit. */
515 else if(precision
== F_PRECISION
)
520 else /* E_PRECISION */
526 shift
= mantissa_bits
- shift
;
531 /* Store the mantissa data into smant and the roundbit into rbit */
532 for (p
= flonum
.leader
; p
>= flonum
.low
&& shift
> -16; p
--)
534 tmp
= shift
>= 0 ? *p
<< shift
: *p
>> -shift
;
535 rbit
= shift
< 0 ? ((*p
>> (-shift
-1)) & 0x1) : 0;
540 /* OK, we've got our scaled mantissa so let's round it up */
543 /* If the mantissa is going to overflow when added, lets store
544 the extra bit in mover. -- A special case exists when
545 mantissa_bits is 31 (E_PRECISION). Then the first test cannot
546 be trusted, as result is host-dependent, thus the second
548 if( smant
== ((unsigned)(1<<(mantissa_bits
+1))-1)
549 || smant
== (unsigned)-1 ) /* This is to catch E_PRECISION cases */
554 /* Get the scaled one value */
555 sone
= (1 << (mantissa_bits
));
557 /* The number may be unnormalised so renormalise it... */
561 smant
|= sone
; /* Insert the bit from mover into smant */
565 /* The binary point is now between bit positions 11 and 10 or 23 and 22,
566 i.e., between mantissa_bits - 1 and mantissa_bits - 2 and the
567 bit at mantissa_bits - 1 should be set. */
569 abort (); /* Ooops. */
571 if (flonum
.sign
== '+')
572 sfract
= smant
- sone
; /* smant - 1.0. */
575 /* This seems to work. */
583 sfract
= -smant
& (sone
-1); /* 2.0 - smant. */
585 sfract
|= sone
; /* Insert sign bit. */
588 if (abs (exponent
) >= (1 << (exponent_bits
- 1)))
589 as_bad ("Cannot represent exponent in %d bits", exponent_bits
);
591 /* Force exponent to fit in desired field width. */
592 exponent
&= (1 << (exponent_bits
)) - 1;
594 if (precision
== E_PRECISION
)
596 /* Map the float part first (100% equal format as F_PRECISION) */
597 words
[0] = exponent
<< (mantissa_bits
+1-24);
598 words
[0] |= sfract
>> 24;
599 words
[1] = sfract
>> 8;
601 /* Map the mantissa in the next */
602 words
[2] = sfract
>> 16;
603 words
[3] = sfract
& 0xffff;
607 /* Insert the exponent data into the word */
608 sfract
|= exponent
<< (mantissa_bits
+1);
610 if (precision
== S_PRECISION
)
614 words
[0] = sfract
>> 16;
615 words
[1] = sfract
& 0xffff;
622 /* Returns pointer past text consumed. */
624 tic4x_atof (str
, what_kind
, words
)
627 LITTLENUM_TYPE
*words
;
629 /* Extra bits for zeroed low-order bits. The 1st MAX_PRECISION are
630 zeroed, the last contain flonum bits. */
631 static LITTLENUM_TYPE bits
[MAX_PRECISION
+ MAX_PRECISION
+ GUARD
];
633 /* Number of 16-bit words in the format. */
635 FLONUM_TYPE save_gen_flonum
;
637 /* We have to save the generic_floating_point_number because it
638 contains storage allocation about the array of LITTLENUMs where
639 the value is actually stored. We will allocate our own array of
640 littlenums below, but have to restore the global one on exit. */
641 save_gen_flonum
= generic_floating_point_number
;
644 generic_floating_point_number
.low
= bits
+ MAX_PRECISION
;
645 generic_floating_point_number
.high
= NULL
;
646 generic_floating_point_number
.leader
= NULL
;
647 generic_floating_point_number
.exponent
= 0;
648 generic_floating_point_number
.sign
= '\0';
650 /* Use more LittleNums than seems necessary: the highest flonum may
651 have 15 leading 0 bits, so could be useless. */
653 memset (bits
, '\0', sizeof (LITTLENUM_TYPE
) * MAX_PRECISION
);
659 precision
= S_PRECISION
;
666 precision
= F_PRECISION
;
671 precision
= E_PRECISION
;
675 as_bad ("Invalid floating point number");
679 generic_floating_point_number
.high
680 = generic_floating_point_number
.low
+ precision
- 1 + GUARD
;
682 if (atof_generic (&return_value
, ".", EXP_CHARS
,
683 &generic_floating_point_number
))
685 as_bad ("Invalid floating point number");
689 tic4x_gen_to_words (generic_floating_point_number
,
692 /* Restore the generic_floating_point_number's storage alloc (and
694 generic_floating_point_number
= save_gen_flonum
;
700 tic4x_insert_reg (regname
, regnum
)
707 symbol_table_insert (symbol_new (regname
, reg_section
, (valueT
) regnum
,
708 &zero_address_frag
));
709 for (i
= 0; regname
[i
]; i
++)
710 buf
[i
] = ISLOWER (regname
[i
]) ? TOUPPER (regname
[i
]) : regname
[i
];
713 symbol_table_insert (symbol_new (buf
, reg_section
, (valueT
) regnum
,
714 &zero_address_frag
));
718 tic4x_insert_sym (symname
, value
)
724 symbolP
= symbol_new (symname
, absolute_section
,
725 (valueT
) value
, &zero_address_frag
);
726 SF_SET_LOCAL (symbolP
);
727 symbol_table_insert (symbolP
);
731 tic4x_expression (str
, exp
)
738 t
= input_line_pointer
; /* Save line pointer. */
739 input_line_pointer
= str
;
741 s
= input_line_pointer
;
742 input_line_pointer
= t
; /* Restore line pointer. */
743 return s
; /* Return pointer to where parsing stopped. */
747 tic4x_expression_abs (str
, value
)
754 t
= input_line_pointer
; /* Save line pointer. */
755 input_line_pointer
= str
;
756 *value
= get_absolute_expression ();
757 s
= input_line_pointer
;
758 input_line_pointer
= t
; /* Restore line pointer. */
763 tic4x_emit_char (c
,b
)
769 exp
.X_op
= O_constant
;
770 exp
.X_add_number
= c
;
775 tic4x_seg_alloc (name
, seg
, size
, symbolP
)
776 char *name ATTRIBUTE_UNUSED
;
777 segT seg ATTRIBUTE_UNUSED
;
781 /* Note that the size is in words
782 so we multiply it by 4 to get the number of bytes to allocate. */
784 /* If we have symbol: .usect ".fred", size etc.,
785 the symbol needs to point to the first location reserved
792 p
= frag_var (rs_fill
, 1, 1, (relax_substateT
) 0,
794 size
* OCTETS_PER_BYTE
, (char *) 0);
799 /* .asg ["]character-string["], symbol */
802 int x ATTRIBUTE_UNUSED
;
810 str
= input_line_pointer
;
812 /* Skip string expression. */
813 while (*input_line_pointer
!= ',' && *input_line_pointer
)
814 input_line_pointer
++;
815 if (*input_line_pointer
!= ',')
817 as_bad ("Comma expected\n");
820 *input_line_pointer
++ = '\0';
821 name
= input_line_pointer
;
822 c
= get_symbol_end (); /* Get terminator. */
823 tmp
= xmalloc (strlen (str
) + 1);
826 tmp
= xmalloc (strlen (name
) + 1);
829 if (hash_find (tic4x_asg_hash
, name
))
830 hash_replace (tic4x_asg_hash
, name
, (PTR
) str
);
832 hash_insert (tic4x_asg_hash
, name
, (PTR
) str
);
833 *input_line_pointer
= c
;
834 demand_empty_rest_of_line ();
837 /* .bss symbol, size */
840 int x ATTRIBUTE_UNUSED
;
847 subsegT current_subseg
;
850 current_seg
= now_seg
; /* Save current seg. */
851 current_subseg
= now_subseg
; /* Save current subseg. */
854 name
= input_line_pointer
;
855 c
= get_symbol_end (); /* Get terminator. */
858 as_bad (".bss size argument missing\n");
863 tic4x_expression_abs (++input_line_pointer
, &size
);
866 as_bad (".bss size %ld < 0!", (long) size
);
869 subseg_set (bss_section
, 0);
870 symbolP
= symbol_find_or_make (name
);
872 if (S_GET_SEGMENT (symbolP
) == bss_section
)
873 symbol_get_frag (symbolP
)->fr_symbol
= 0;
875 symbol_set_frag (symbolP
, frag_now
);
877 p
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
,
878 size
* OCTETS_PER_BYTE
, (char *) 0);
879 *p
= 0; /* Fill char. */
881 S_SET_SEGMENT (symbolP
, bss_section
);
883 /* The symbol may already have been created with a preceding
884 ".globl" directive -- be careful not to step on storage class
885 in that case. Otherwise, set it to static. */
886 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
887 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
889 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
890 demand_empty_rest_of_line ();
895 int ignore ATTRIBUTE_UNUSED
;
903 name
= input_line_pointer
;
904 c
= get_symbol_end ();
905 symbolP
= symbol_find_or_make (name
);
906 *input_line_pointer
= c
;
908 S_SET_STORAGE_CLASS (symbolP
, C_EXT
);
911 input_line_pointer
++;
913 if (*input_line_pointer
== '\n')
919 demand_empty_rest_of_line ();
922 /* Handle .byte, .word. .int, .long */
927 register unsigned int c
;
931 if (*input_line_pointer
== '"')
933 input_line_pointer
++;
934 while (is_a_char (c
= next_char_of_string ()))
935 tic4x_emit_char (c
, 4);
936 know (input_line_pointer
[-1] == '\"');
942 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
943 if (exp
.X_op
== O_constant
)
948 exp
.X_add_number
&= 255;
951 exp
.X_add_number
&= 65535;
955 /* Perhaps we should disallow .byte and .hword with
956 a non constant expression that will require relocation. */
960 while (*input_line_pointer
++ == ',');
962 input_line_pointer
--; /* Put terminator back into stream. */
963 demand_empty_rest_of_line ();
966 /* Handle .ascii, .asciz, .string */
968 tic4x_stringer (append_zero
)
969 int append_zero
; /*ex: bytes */
972 register unsigned int c
;
978 if (*input_line_pointer
== '"')
980 input_line_pointer
++;
981 while (is_a_char (c
= next_char_of_string ()))
983 tic4x_emit_char (c
, 1);
989 tic4x_emit_char (c
, 1);
993 know (input_line_pointer
[-1] == '\"');
999 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
1000 if (exp
.X_op
!= O_constant
)
1002 as_bad("Non-constant symbols not allowed\n");
1005 exp
.X_add_number
&= 255; /* Limit numeber to 8-bit */
1006 emit_expr (&exp
, 1);
1010 while (*input_line_pointer
++ == ',');
1012 /* Fill out the rest of the expression with 0's to fill up a full word */
1014 tic4x_emit_char (0, 4-(bytes
&0x3));
1016 input_line_pointer
--; /* Put terminator back into stream. */
1017 demand_empty_rest_of_line ();
1020 /* .eval expression, symbol */
1023 int x ATTRIBUTE_UNUSED
;
1030 input_line_pointer
=
1031 tic4x_expression_abs (input_line_pointer
, &value
);
1032 if (*input_line_pointer
++ != ',')
1034 as_bad ("Symbol missing\n");
1037 name
= input_line_pointer
;
1038 c
= get_symbol_end (); /* Get terminator. */
1039 demand_empty_rest_of_line ();
1040 tic4x_insert_sym (name
, value
);
1043 /* Reset local labels. */
1046 int x ATTRIBUTE_UNUSED
;
1048 dollar_label_clear ();
1051 /* .sect "section-name" [, value] */
1052 /* .sect ["]section-name[:subsection-name]["] [, value] */
1055 int x ATTRIBUTE_UNUSED
;
1059 char *subsection_name
;
1065 if (*input_line_pointer
== '"')
1066 input_line_pointer
++;
1067 section_name
= input_line_pointer
;
1068 c
= get_symbol_end (); /* Get terminator. */
1069 input_line_pointer
++; /* Skip null symbol terminator. */
1070 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1071 strcpy (name
, section_name
);
1073 /* TI C from version 5.0 allows a section name to contain a
1074 subsection name as well. The subsection name is separated by a
1075 ':' from the section name. Currently we scan the subsection
1076 name and discard it.
1077 Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>. */
1080 subsection_name
= input_line_pointer
;
1081 c
= get_symbol_end (); /* Get terminator. */
1082 input_line_pointer
++; /* Skip null symbol terminator. */
1083 as_warn (".sect: subsection name ignored");
1086 /* We might still have a '"' to discard, but the character after a
1087 symbol name will be overwritten with a \0 by get_symbol_end()
1091 input_line_pointer
=
1092 tic4x_expression_abs (input_line_pointer
, &num
);
1093 else if (*input_line_pointer
== ',')
1095 input_line_pointer
=
1096 tic4x_expression_abs (++input_line_pointer
, &num
);
1101 seg
= subseg_new (name
, num
);
1102 if (line_label
!= NULL
)
1104 S_SET_SEGMENT (line_label
, seg
);
1105 symbol_set_frag (line_label
, frag_now
);
1108 if (bfd_get_section_flags (stdoutput
, seg
) == SEC_NO_FLAGS
)
1110 if (!bfd_set_section_flags (stdoutput
, seg
, SEC_DATA
))
1111 as_warn ("Error setting flags for \"%s\": %s", name
,
1112 bfd_errmsg (bfd_get_error ()));
1115 /* If the last character overwritten by get_symbol_end() was an
1116 end-of-line, we must restore it or the end of the line will not be
1117 recognised and scanning extends into the next line, stopping with
1118 an error (blame Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>
1119 if this is not true). */
1120 if (is_end_of_line
[(unsigned char) c
])
1121 *(--input_line_pointer
) = c
;
1123 demand_empty_rest_of_line ();
1126 /* symbol[:] .set value or .set symbol, value */
1129 int x ATTRIBUTE_UNUSED
;
1134 if ((symbolP
= line_label
) == NULL
)
1139 name
= input_line_pointer
;
1140 c
= get_symbol_end (); /* Get terminator. */
1143 as_bad (".set syntax invalid\n");
1144 ignore_rest_of_line ();
1147 ++input_line_pointer
;
1148 symbolP
= symbol_find_or_make (name
);
1151 symbol_table_insert (symbolP
);
1153 pseudo_set (symbolP
);
1154 demand_empty_rest_of_line ();
1157 /* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
1160 int x ATTRIBUTE_UNUSED
;
1166 offsetT size
, alignment_flag
;
1168 subsegT current_subseg
;
1170 current_seg
= now_seg
; /* save current seg. */
1171 current_subseg
= now_subseg
; /* save current subseg. */
1174 if (*input_line_pointer
== '"')
1175 input_line_pointer
++;
1176 section_name
= input_line_pointer
;
1177 c
= get_symbol_end (); /* Get terminator. */
1178 input_line_pointer
++; /* Skip null symbol terminator. */
1179 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1180 strcpy (name
, section_name
);
1183 input_line_pointer
=
1184 tic4x_expression_abs (input_line_pointer
, &size
);
1185 else if (*input_line_pointer
== ',')
1187 input_line_pointer
=
1188 tic4x_expression_abs (++input_line_pointer
, &size
);
1193 /* Read a possibly present third argument (alignment flag) [VK]. */
1194 if (*input_line_pointer
== ',')
1196 input_line_pointer
=
1197 tic4x_expression_abs (++input_line_pointer
, &alignment_flag
);
1202 as_warn (".usect: non-zero alignment flag ignored");
1204 seg
= subseg_new (name
, 0);
1205 if (line_label
!= NULL
)
1207 S_SET_SEGMENT (line_label
, seg
);
1208 symbol_set_frag (line_label
, frag_now
);
1209 S_SET_VALUE (line_label
, frag_now_fix ());
1211 seg_info (seg
)->bss
= 1; /* Uninitialised data. */
1212 if (!bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
))
1213 as_warn ("Error setting flags for \"%s\": %s", name
,
1214 bfd_errmsg (bfd_get_error ()));
1215 tic4x_seg_alloc (name
, seg
, size
, line_label
);
1217 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1218 S_SET_STORAGE_CLASS (line_label
, C_STAT
);
1220 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
1221 demand_empty_rest_of_line ();
1224 /* .version cpu-version. */
1227 int x ATTRIBUTE_UNUSED
;
1231 input_line_pointer
=
1232 tic4x_expression_abs (input_line_pointer
, &temp
);
1233 if (!IS_CPU_TIC3X (temp
) && !IS_CPU_TIC4X (temp
))
1234 as_bad ("This assembler does not support processor generation %ld",
1237 if (tic4x_cpu
&& temp
!= (offsetT
) tic4x_cpu
)
1238 as_warn ("Changing processor generation on fly not supported...");
1240 demand_empty_rest_of_line ();
1244 tic4x_init_regtable ()
1248 for (i
= 0; i
< tic3x_num_registers
; i
++)
1249 tic4x_insert_reg (tic3x_registers
[i
].name
,
1250 tic3x_registers
[i
].regno
);
1252 if (IS_CPU_TIC4X (tic4x_cpu
))
1254 /* Add additional Tic4x registers, overriding some C3x ones. */
1255 for (i
= 0; i
< tic4x_num_registers
; i
++)
1256 tic4x_insert_reg (tic4x_registers
[i
].name
,
1257 tic4x_registers
[i
].regno
);
1262 tic4x_init_symbols ()
1264 /* The TI tools accept case insensitive versions of these symbols,
1269 .TMS320xx 30,31,32,40,or 44 set according to -v flag
1270 .C3X or .C3x 1 or 0 1 if -v30,-v31,or -v32
1271 .C30 1 or 0 1 if -v30
1272 .C31 1 or 0 1 if -v31
1273 .C32 1 or 0 1 if -v32
1274 .C4X or .C4x 1 or 0 1 if -v40, or -v44
1275 .C40 1 or 0 1 if -v40
1276 .C44 1 or 0 1 if -v44
1278 .REGPARM 1 or 0 1 if -mr option used
1279 .BIGMODEL 1 or 0 1 if -mb option used
1281 These symbols are currently supported but will be removed in a
1283 .TMS320C30 1 or 0 1 if -v30,-v31,or -v32
1284 .TMS320C31 1 or 0 1 if -v31
1285 .TMS320C32 1 or 0 1 if -v32
1286 .TMS320C40 1 or 0 1 if -v40, or -v44
1287 .TMS320C44 1 or 0 1 if -v44
1289 Source: TI: TMS320C3x/C4x Assembly Language Tools User's Guide,
1290 1997, SPRU035C, p. 3-17/3-18. */
1291 tic4x_insert_sym (".REGPARM", tic4x_reg_args
);
1292 tic4x_insert_sym (".MEMPARM", !tic4x_reg_args
);
1293 tic4x_insert_sym (".BIGMODEL", tic4x_big_model
);
1294 tic4x_insert_sym (".C30INTERRUPT", 0);
1295 tic4x_insert_sym (".TMS320xx", tic4x_cpu
== 0 ? 40 : tic4x_cpu
);
1296 tic4x_insert_sym (".C3X", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1297 tic4x_insert_sym (".C3x", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1298 tic4x_insert_sym (".C4X", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1299 tic4x_insert_sym (".C4x", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1300 /* Do we need to have the following symbols also in lower case? */
1301 tic4x_insert_sym (".TMS320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1302 tic4x_insert_sym (".tms320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1303 tic4x_insert_sym (".TMS320C31", tic4x_cpu
== 31);
1304 tic4x_insert_sym (".tms320C31", tic4x_cpu
== 31);
1305 tic4x_insert_sym (".TMS320C32", tic4x_cpu
== 32);
1306 tic4x_insert_sym (".tms320C32", tic4x_cpu
== 32);
1307 tic4x_insert_sym (".TMS320C33", tic4x_cpu
== 33);
1308 tic4x_insert_sym (".tms320C33", tic4x_cpu
== 33);
1309 tic4x_insert_sym (".TMS320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1310 tic4x_insert_sym (".tms320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1311 tic4x_insert_sym (".TMS320C44", tic4x_cpu
== 44);
1312 tic4x_insert_sym (".tms320C44", tic4x_cpu
== 44);
1313 tic4x_insert_sym (".TMX320C40", 0); /* C40 first pass silicon ? */
1314 tic4x_insert_sym (".tmx320C40", 0);
1317 /* Insert a new instruction template into hash table. */
1319 tic4x_inst_insert (inst
)
1322 static char prev_name
[16];
1323 const char *retval
= NULL
;
1325 /* Only insert the first name if have several similar entries. */
1326 if (!strcmp (inst
->name
, prev_name
) || inst
->name
[0] == '\0')
1329 retval
= hash_insert (tic4x_op_hash
, inst
->name
, (PTR
) inst
);
1331 fprintf (stderr
, "internal error: can't hash `%s': %s\n",
1332 inst
->name
, retval
);
1334 strcpy (prev_name
, inst
->name
);
1335 return retval
== NULL
;
1338 /* Make a new instruction template. */
1339 static tic4x_inst_t
*
1340 tic4x_inst_make (name
, opcode
, args
)
1342 unsigned long opcode
;
1345 static tic4x_inst_t
*insts
= NULL
;
1346 static char *names
= NULL
;
1347 static int index
= 0;
1351 /* Allocate memory to store name strings. */
1352 names
= (char *) xmalloc (sizeof (char) * 8192);
1353 /* Allocate memory for additional insts. */
1354 insts
= (tic4x_inst_t
*)
1355 xmalloc (sizeof (tic4x_inst_t
) * 1024);
1357 insts
[index
].name
= names
;
1358 insts
[index
].opcode
= opcode
;
1359 insts
[index
].opmask
= 0xffffffff;
1360 insts
[index
].args
= args
;
1368 return &insts
[index
- 1];
1371 /* Add instruction template, creating dynamic templates as required. */
1373 tic4x_inst_add (insts
)
1374 tic4x_inst_t
*insts
;
1376 char *s
= insts
->name
;
1384 /* We do not care about INSNs that is not a part of our
1386 if (!insts
->oplevel
& tic4x_oplevel
)
1395 /* Dynamically create all the conditional insts. */
1396 for (i
= 0; i
< tic4x_num_conds
; i
++)
1400 char *c
= tic4x_conds
[i
].name
;
1410 /* If instruction found then have already processed it. */
1411 if (hash_find (tic4x_op_hash
, name
))
1416 inst
= tic4x_inst_make (name
, insts
[k
].opcode
+
1417 (tic4x_conds
[i
].cond
<<
1418 (*s
== 'B' ? 16 : 23)),
1420 if (k
== 0) /* Save strcmp() with following func. */
1421 ok
&= tic4x_inst_insert (inst
);
1424 while (!strcmp (insts
->name
,
1431 return tic4x_inst_insert (insts
);
1441 /* This function is called once, at assembler startup time. It should
1442 set up all the tables, etc., that the MD part of the assembler will
1450 /* Setup the proper opcode level according to the
1451 commandline parameters */
1452 tic4x_oplevel
= OP_C3X
;
1454 if ( IS_CPU_TIC4X(tic4x_cpu
) )
1455 tic4x_oplevel
|= OP_C4X
;
1457 if ( ( tic4x_cpu
== 31 && tic4x_revision
>= 6)
1458 || (tic4x_cpu
== 32 && tic4x_revision
>= 2)
1459 || (tic4x_cpu
== 33)
1461 tic4x_oplevel
|= OP_ENH
;
1463 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1464 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1465 || (tic4x_cpu
== 32)
1467 tic4x_oplevel
|= OP_LPWR
;
1469 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1470 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1471 || (tic4x_cpu
== 32)
1472 || (tic4x_cpu
== 33)
1473 || (tic4x_cpu
== 40 && tic4x_revision
>= 5)
1474 || (tic4x_cpu
== 44)
1476 tic4x_oplevel
|= OP_IDLE2
;
1478 /* Create hash table for mnemonics. */
1479 tic4x_op_hash
= hash_new ();
1481 /* Create hash table for asg pseudo. */
1482 tic4x_asg_hash
= hash_new ();
1484 /* Add mnemonics to hash table, expanding conditional mnemonics on fly. */
1485 for (i
= 0; i
< tic4x_num_insts
; i
++)
1486 ok
&= tic4x_inst_add ((void *) &tic4x_insts
[i
]);
1488 /* Create dummy inst to avoid errors accessing end of table. */
1489 tic4x_inst_make ("", 0, "");
1492 as_fatal ("Broken assembler. No assembly attempted.");
1494 /* Add registers to symbol table. */
1495 tic4x_init_regtable ();
1497 /* Add predefined symbols to symbol table. */
1498 tic4x_init_symbols ();
1504 bfd_set_arch_mach (stdoutput
, bfd_arch_tic4x
,
1505 IS_CPU_TIC4X (tic4x_cpu
) ? bfd_mach_tic4x
: bfd_mach_tic3x
);
1509 tic4x_indirect_parse (operand
, indirect
)
1510 tic4x_operand_t
*operand
;
1511 const tic4x_indirect_t
*indirect
;
1513 char *n
= indirect
->name
;
1514 char *s
= input_line_pointer
;
1524 case 'a': /* Need to match aux register. */
1526 #ifdef TIC4X_ALT_SYNTAX
1530 while (ISALNUM (*s
))
1533 if (!(symbolP
= symbol_find (name
)))
1536 if (S_GET_SEGMENT (symbolP
) != reg_section
)
1539 operand
->aregno
= S_GET_VALUE (symbolP
);
1540 if (operand
->aregno
>= REG_AR0
&& operand
->aregno
<= REG_AR7
)
1543 as_bad ("Auxiliary register AR0--AR7 required for indirect");
1546 case 'd': /* Need to match constant for disp. */
1547 #ifdef TIC4X_ALT_SYNTAX
1548 if (*s
== '%') /* expr() will die if we don't skip this. */
1551 s
= tic4x_expression (s
, &operand
->expr
);
1552 if (operand
->expr
.X_op
!= O_constant
)
1554 operand
->disp
= operand
->expr
.X_add_number
;
1555 if (operand
->disp
< 0 || operand
->disp
> 255)
1557 as_bad ("Bad displacement %d (require 0--255)\n",
1563 case 'y': /* Need to match IR0. */
1564 case 'z': /* Need to match IR1. */
1565 #ifdef TIC4X_ALT_SYNTAX
1569 s
= tic4x_expression (s
, &operand
->expr
);
1570 if (operand
->expr
.X_op
!= O_register
)
1572 if (operand
->expr
.X_add_number
!= REG_IR0
1573 && operand
->expr
.X_add_number
!= REG_IR1
)
1575 as_bad ("Index register IR0,IR1 required for displacement");
1579 if (*n
== 'y' && operand
->expr
.X_add_number
== REG_IR0
)
1581 if (*n
== 'z' && operand
->expr
.X_add_number
== REG_IR1
)
1586 if (*s
!= '(') /* No displacement, assume to be 1. */
1597 if (TOLOWER (*s
) != *n
)
1602 if (*s
!= ' ' && *s
!= ',' && *s
!= '\0')
1604 input_line_pointer
= s
;
1609 tic4x_operand_parse (s
, operand
)
1611 tic4x_operand_t
*operand
;
1616 expressionS
*exp
= &operand
->expr
;
1617 char *save
= input_line_pointer
;
1620 struct hash_entry
*entry
= NULL
;
1622 input_line_pointer
= s
;
1625 str
= input_line_pointer
;
1626 c
= get_symbol_end (); /* Get terminator. */
1627 new = input_line_pointer
;
1628 if (strlen (str
) && (entry
= hash_find (tic4x_asg_hash
, str
)) != NULL
)
1630 *input_line_pointer
= c
;
1631 input_line_pointer
= (char *) entry
;
1635 *input_line_pointer
= c
;
1636 input_line_pointer
= str
;
1639 operand
->mode
= M_UNKNOWN
;
1640 switch (*input_line_pointer
)
1642 #ifdef TIC4X_ALT_SYNTAX
1644 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1645 if (exp
->X_op
!= O_register
)
1646 as_bad ("Expecting a register name");
1647 operand
->mode
= M_REGISTER
;
1651 /* Denotes high 16 bits. */
1652 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1653 if (exp
->X_op
== O_constant
)
1654 operand
->mode
= M_IMMED
;
1655 else if (exp
->X_op
== O_big
)
1657 if (exp
->X_add_number
)
1658 as_bad ("Number too large"); /* bignum required */
1661 tic4x_gen_to_words (generic_floating_point_number
,
1662 operand
->fwords
, S_PRECISION
);
1663 operand
->mode
= M_IMMED_F
;
1666 /* Allow ori ^foo, ar0 to be equivalent to ldi .hi.foo, ar0 */
1667 /* WARNING : The TI C40 assembler cannot do this. */
1668 else if (exp
->X_op
== O_symbol
)
1670 operand
->mode
= M_HI
;
1675 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1676 if (exp
->X_op
== O_constant
)
1677 operand
->mode
= M_IMMED
;
1678 else if (exp
->X_op
== O_big
)
1680 if (exp
->X_add_number
> 0)
1681 as_bad ("Number too large"); /* bignum required. */
1684 tic4x_gen_to_words (generic_floating_point_number
,
1685 operand
->fwords
, S_PRECISION
);
1686 operand
->mode
= M_IMMED_F
;
1689 /* Allow ori foo, ar0 to be equivalent to ldi .lo.foo, ar0 */
1690 /* WARNING : The TI C40 assembler cannot do this. */
1691 else if (exp
->X_op
== O_symbol
)
1693 operand
->mode
= M_IMMED
;
1698 as_bad ("Expecting a constant value");
1703 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1704 if (exp
->X_op
!= O_constant
&& exp
->X_op
!= O_symbol
)
1705 as_bad ("Bad direct addressing construct %s", s
);
1706 if (exp
->X_op
== O_constant
)
1708 if (exp
->X_add_number
< 0)
1709 as_bad ("Direct value of %ld is not suitable",
1710 (long) exp
->X_add_number
);
1712 operand
->mode
= M_DIRECT
;
1717 for (i
= 0; i
< tic4x_num_indirects
; i
++)
1718 if ((ret
= tic4x_indirect_parse (operand
, &tic4x_indirects
[i
])))
1722 if (i
< tic4x_num_indirects
)
1724 operand
->mode
= M_INDIRECT
;
1725 /* Indirect addressing mode number. */
1726 operand
->expr
.X_add_number
= tic4x_indirects
[i
].modn
;
1727 /* Convert *+ARn(0) to *ARn etc. Maybe we should
1728 squeal about silly ones? */
1729 if (operand
->expr
.X_add_number
< 0x08 && !operand
->disp
)
1730 operand
->expr
.X_add_number
= 0x18;
1733 as_bad ("Unknown indirect addressing mode");
1737 operand
->mode
= M_IMMED
; /* Assume immediate. */
1738 str
= input_line_pointer
;
1739 input_line_pointer
= tic4x_expression (input_line_pointer
, exp
);
1740 if (exp
->X_op
== O_register
)
1742 know (exp
->X_add_symbol
== 0);
1743 know (exp
->X_op_symbol
== 0);
1744 operand
->mode
= M_REGISTER
;
1747 else if (exp
->X_op
== O_big
)
1749 if (exp
->X_add_number
> 0)
1750 as_bad ("Number too large"); /* bignum required. */
1753 tic4x_gen_to_words (generic_floating_point_number
,
1754 operand
->fwords
, S_PRECISION
);
1755 operand
->mode
= M_IMMED_F
;
1759 #ifdef TIC4X_ALT_SYNTAX
1760 /* Allow ldi foo, ar0 to be equivalent to ldi @foo, ar0. */
1761 else if (exp
->X_op
== O_symbol
)
1763 operand
->mode
= M_DIRECT
;
1769 new = input_line_pointer
;
1770 input_line_pointer
= save
;
1775 tic4x_operands_match (inst
, insn
, check
)
1780 const char *args
= inst
->args
;
1781 unsigned long opcode
= inst
->opcode
;
1782 int num_operands
= insn
->num_operands
;
1783 tic4x_operand_t
*operand
= insn
->operands
;
1784 expressionS
*exp
= &operand
->expr
;
1788 /* Build the opcode, checking as we go to make sure that the
1791 If an operand matches, we modify insn or opcode appropriately,
1792 and do a "continue". If an operand fails to match, we "break". */
1794 insn
->nchars
= 4; /* Instructions always 4 bytes. */
1795 insn
->reloc
= NO_RELOC
;
1800 insn
->opcode
= opcode
;
1801 return num_operands
== 0;
1809 case '\0': /* End of args. */
1810 if (num_operands
== 1)
1812 insn
->opcode
= opcode
;
1815 break; /* Too many operands. */
1817 case '#': /* This is only used for ldp. */
1818 if (operand
->mode
!= M_DIRECT
&& operand
->mode
!= M_IMMED
)
1820 /* While this looks like a direct addressing mode, we actually
1821 use an immediate mode form of ldiu or ldpk instruction. */
1822 if (exp
->X_op
== O_constant
)
1824 if( ( IS_CPU_TIC4X (tic4x_cpu
) && exp
->X_add_number
<= 65535 )
1825 || ( IS_CPU_TIC3X (tic4x_cpu
) && exp
->X_add_number
<= 255 ) )
1827 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1833 as_bad ("Immediate value of %ld is too large for ldf",
1834 (long) exp
->X_add_number
);
1839 else if (exp
->X_op
== O_symbol
)
1841 insn
->reloc
= BFD_RELOC_HI16
;
1845 break; /* Not direct (dp) addressing. */
1847 case '@': /* direct. */
1848 if (operand
->mode
!= M_DIRECT
)
1850 if (exp
->X_op
== O_constant
)
1852 /* Store only the 16 LSBs of the number. */
1853 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1856 else if (exp
->X_op
== O_symbol
)
1858 insn
->reloc
= BFD_RELOC_LO16
;
1862 break; /* Not direct addressing. */
1865 if (operand
->mode
!= M_REGISTER
)
1867 reg
= exp
->X_add_number
;
1868 if (reg
>= REG_AR0
&& reg
<= REG_AR7
)
1869 INSERTU (opcode
, reg
- REG_AR0
, 24, 22);
1873 as_bad ("Destination register must be ARn");
1878 case 'B': /* Unsigned integer immediate. */
1879 /* Allow br label or br @label. */
1880 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
1882 if (exp
->X_op
== O_constant
)
1884 if (exp
->X_add_number
< (1 << 24))
1886 INSERTU (opcode
, exp
->X_add_number
, 23, 0);
1892 as_bad ("Immediate value of %ld is too large",
1893 (long) exp
->X_add_number
);
1898 if (IS_CPU_TIC4X (tic4x_cpu
))
1900 insn
->reloc
= BFD_RELOC_24_PCREL
;
1905 insn
->reloc
= BFD_RELOC_24
;
1912 if (!IS_CPU_TIC4X (tic4x_cpu
))
1914 if (operand
->mode
!= M_INDIRECT
)
1916 /* Require either *+ARn(disp) or *ARn. */
1917 if (operand
->expr
.X_add_number
!= 0
1918 && operand
->expr
.X_add_number
!= 0x18)
1921 as_bad ("Invalid indirect addressing mode");
1925 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1926 INSERTU (opcode
, operand
->disp
, 7, 3);
1930 if (!(operand
->mode
== M_REGISTER
))
1932 INSERTU (opcode
, exp
->X_add_number
, 7, 0);
1936 if (!(operand
->mode
== M_REGISTER
))
1938 reg
= exp
->X_add_number
;
1939 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1940 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1941 INSERTU (opcode
, reg
, 7, 0);
1945 as_bad ("Register must be Rn");
1951 if (operand
->mode
!= M_IMMED_F
1952 && !(operand
->mode
== M_IMMED
&& exp
->X_op
== O_constant
))
1955 if (operand
->mode
!= M_IMMED_F
)
1957 /* OK, we 've got something like cmpf 0, r0
1958 Why can't they stick in a bloody decimal point ?! */
1961 /* Create floating point number string. */
1962 sprintf (string
, "%d.0", (int) exp
->X_add_number
);
1963 tic4x_atof (string
, 's', operand
->fwords
);
1966 INSERTU (opcode
, operand
->fwords
[0], 15, 0);
1970 if (operand
->mode
!= M_REGISTER
)
1972 INSERTU (opcode
, exp
->X_add_number
, 15, 8);
1976 if (operand
->mode
!= M_REGISTER
)
1978 reg
= exp
->X_add_number
;
1979 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1980 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1981 INSERTU (opcode
, reg
, 15, 8);
1985 as_bad ("Register must be Rn");
1991 if (operand
->mode
!= M_REGISTER
)
1993 reg
= exp
->X_add_number
;
1994 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1995 INSERTU (opcode
, reg
- REG_R0
, 18, 16);
1999 as_bad ("Register must be R0--R7");
2005 if ( operand
->mode
== M_REGISTER
2006 && tic4x_oplevel
& OP_ENH
)
2008 reg
= exp
->X_add_number
;
2009 INSERTU (opcode
, reg
, 4, 0);
2010 INSERTU (opcode
, 7, 7, 5);
2016 if (operand
->mode
!= M_INDIRECT
)
2018 if (operand
->disp
!= 0 && operand
->disp
!= 1)
2020 if (IS_CPU_TIC4X (tic4x_cpu
))
2023 as_bad ("Invalid indirect addressing mode displacement %d",
2028 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
2029 INSERTU (opcode
, operand
->expr
.X_add_number
, 7, 3);
2033 if ( operand
->mode
== M_REGISTER
2034 && tic4x_oplevel
& OP_ENH
)
2036 reg
= exp
->X_add_number
;
2037 INSERTU (opcode
, reg
, 12, 8);
2038 INSERTU (opcode
, 7, 15, 13);
2044 if (operand
->mode
!= M_INDIRECT
)
2046 if (operand
->disp
!= 0 && operand
->disp
!= 1)
2048 if (IS_CPU_TIC4X (tic4x_cpu
))
2051 as_bad ("Invalid indirect addressing mode displacement %d",
2056 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2057 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
2061 if (operand
->mode
!= M_REGISTER
)
2063 reg
= exp
->X_add_number
;
2064 if (reg
>= REG_R0
&& reg
<= REG_R7
)
2065 INSERTU (opcode
, reg
- REG_R0
, 21, 19);
2069 as_bad ("Register must be R0--R7");
2075 if (operand
->mode
!= M_REGISTER
)
2077 reg
= exp
->X_add_number
;
2078 if (reg
>= REG_R0
&& reg
<= REG_R7
)
2079 INSERTU (opcode
, reg
- REG_R0
, 24, 22);
2083 as_bad ("Register must be R0--R7");
2089 if (operand
->mode
!= M_REGISTER
)
2091 reg
= exp
->X_add_number
;
2092 if (reg
== REG_R2
|| reg
== REG_R3
)
2093 INSERTU (opcode
, reg
- REG_R2
, 22, 22);
2097 as_bad ("Destination register must be R2 or R3");
2103 if (operand
->mode
!= M_REGISTER
)
2105 reg
= exp
->X_add_number
;
2106 if (reg
== REG_R0
|| reg
== REG_R1
)
2107 INSERTU (opcode
, reg
- REG_R0
, 23, 23);
2111 as_bad ("Destination register must be R0 or R1");
2117 if (!IS_CPU_TIC4X (tic4x_cpu
))
2119 if (operand
->mode
!= M_INDIRECT
)
2121 /* Require either *+ARn(disp) or *ARn. */
2122 if (operand
->expr
.X_add_number
!= 0
2123 && operand
->expr
.X_add_number
!= 0x18)
2126 as_bad ("Invalid indirect addressing mode");
2130 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2131 INSERTU (opcode
, operand
->disp
, 15, 11);
2134 case 'P': /* PC relative displacement. */
2135 /* Allow br label or br @label. */
2136 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
2138 if (exp
->X_op
== O_constant
)
2140 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 32767)
2142 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2148 as_bad ("Displacement value of %ld is too large",
2149 (long) exp
->X_add_number
);
2154 insn
->reloc
= BFD_RELOC_16_PCREL
;
2160 if (operand
->mode
!= M_REGISTER
)
2162 reg
= exp
->X_add_number
;
2163 INSERTU (opcode
, reg
, 15, 0);
2167 if (operand
->mode
!= M_REGISTER
)
2169 reg
= exp
->X_add_number
;
2170 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2171 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2172 INSERTU (opcode
, reg
, 15, 0);
2176 as_bad ("Register must be Rn");
2182 if (operand
->mode
!= M_REGISTER
)
2184 reg
= exp
->X_add_number
;
2185 INSERTU (opcode
, reg
, 20, 16);
2189 if (operand
->mode
!= M_REGISTER
)
2191 reg
= exp
->X_add_number
;
2192 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2193 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2194 INSERTU (opcode
, reg
, 20, 16);
2198 as_bad ("Register must be Rn");
2203 case 'S': /* Short immediate int. */
2204 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2206 if (exp
->X_op
== O_big
)
2209 as_bad ("Floating point number not valid in expression");
2213 if (exp
->X_op
== O_constant
)
2215 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 65535)
2217 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2223 as_bad ("Signed immediate value %ld too large",
2224 (long) exp
->X_add_number
);
2229 else if (exp
->X_op
== O_symbol
)
2231 if (operand
->mode
== M_HI
)
2233 insn
->reloc
= BFD_RELOC_HI16
;
2237 insn
->reloc
= BFD_RELOC_LO16
;
2242 /* Handle cases like ldi foo - $, ar0 where foo
2243 is a forward reference. Perhaps we should check
2244 for X_op == O_symbol and disallow things like
2246 insn
->reloc
= BFD_RELOC_16
;
2250 case 'T': /* 5-bit immediate value for tic4x stik. */
2251 if (!IS_CPU_TIC4X (tic4x_cpu
))
2253 if (operand
->mode
!= M_IMMED
)
2255 if (exp
->X_op
== O_constant
)
2257 if (exp
->X_add_number
< 16 && exp
->X_add_number
>= -16)
2259 INSERTS (opcode
, exp
->X_add_number
, 20, 16);
2265 as_bad ("Immediate value of %ld is too large",
2266 (long) exp
->X_add_number
);
2271 break; /* No relocations allowed. */
2273 case 'U': /* Unsigned integer immediate. */
2274 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2276 if (exp
->X_op
== O_constant
)
2278 if (exp
->X_add_number
< (1 << 16) && exp
->X_add_number
>= 0)
2280 INSERTU (opcode
, exp
->X_add_number
, 15, 0);
2286 as_bad ("Unsigned immediate value %ld too large",
2287 (long) exp
->X_add_number
);
2292 else if (exp
->X_op
== O_symbol
)
2294 if (operand
->mode
== M_HI
)
2295 insn
->reloc
= BFD_RELOC_HI16
;
2297 insn
->reloc
= BFD_RELOC_LO16
;
2302 insn
->reloc
= BFD_RELOC_16
;
2306 case 'V': /* Trap numbers (immediate field). */
2307 if (operand
->mode
!= M_IMMED
)
2309 if (exp
->X_op
== O_constant
)
2311 if (exp
->X_add_number
< 512 && IS_CPU_TIC4X (tic4x_cpu
))
2313 INSERTU (opcode
, exp
->X_add_number
, 8, 0);
2316 else if (exp
->X_add_number
< 32 && IS_CPU_TIC3X (tic4x_cpu
))
2318 INSERTU (opcode
, exp
->X_add_number
| 0x20, 4, 0);
2324 as_bad ("Immediate value of %ld is too large",
2325 (long) exp
->X_add_number
);
2330 break; /* No relocations allowed. */
2332 case 'W': /* Short immediate int (0--7). */
2333 if (!IS_CPU_TIC4X (tic4x_cpu
))
2335 if (operand
->mode
!= M_IMMED
)
2337 if (exp
->X_op
== O_big
)
2340 as_bad ("Floating point number not valid in expression");
2344 if (exp
->X_op
== O_constant
)
2346 if (exp
->X_add_number
>= -256 && exp
->X_add_number
<= 127)
2348 INSERTS (opcode
, exp
->X_add_number
, 7, 0);
2354 as_bad ("Immediate value %ld too large",
2355 (long) exp
->X_add_number
);
2360 insn
->reloc
= BFD_RELOC_16
;
2364 case 'X': /* Expansion register for tic4x. */
2365 if (operand
->mode
!= M_REGISTER
)
2367 reg
= exp
->X_add_number
;
2368 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2369 INSERTU (opcode
, reg
- REG_IVTP
, 4, 0);
2373 as_bad ("Register must be ivtp or tvtp");
2378 case 'Y': /* Address register for tic4x lda. */
2379 if (operand
->mode
!= M_REGISTER
)
2381 reg
= exp
->X_add_number
;
2382 if (reg
>= REG_AR0
&& reg
<= REG_SP
)
2383 INSERTU (opcode
, reg
, 20, 16);
2387 as_bad ("Register must be address register");
2392 case 'Z': /* Expansion register for tic4x. */
2393 if (operand
->mode
!= M_REGISTER
)
2395 reg
= exp
->X_add_number
;
2396 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2397 INSERTU (opcode
, reg
- REG_IVTP
, 20, 16);
2401 as_bad ("Register must be ivtp or tvtp");
2407 if (operand
->mode
!= M_INDIRECT
)
2409 INSERTS (opcode
, operand
->disp
, 7, 0);
2410 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2411 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
2414 case '|': /* treat as `,' if have ldi_ldi form. */
2417 if (--num_operands
< 0)
2418 break; /* Too few operands. */
2420 if (operand
->mode
!= M_PARALLEL
)
2425 case ',': /* Another operand. */
2426 if (--num_operands
< 0)
2427 break; /* Too few operands. */
2429 exp
= &operand
->expr
;
2432 case ';': /* Another optional operand. */
2433 if (num_operands
== 1 || operand
[1].mode
== M_PARALLEL
)
2435 if (--num_operands
< 0)
2436 break; /* Too few operands. */
2438 exp
= &operand
->expr
;
2449 tic4x_insn_check (insn
)
2453 if (!strcmp(insn
->name
, "lda"))
2455 if (insn
->num_operands
< 2 || insn
->num_operands
> 2)
2456 as_fatal ("Illegal internal LDA insn definition");
2458 if ( insn
->operands
[0].mode
== M_REGISTER
2459 && insn
->operands
[1].mode
== M_REGISTER
2460 && insn
->operands
[0].expr
.X_add_number
== insn
->operands
[1].expr
.X_add_number
)
2461 as_bad ("Source and destination register should not be equal");
2463 else if( !strcmp(insn
->name
, "ldi_ldi")
2464 || !strcmp(insn
->name
, "ldi1_ldi2")
2465 || !strcmp(insn
->name
, "ldi2_ldi1")
2466 || !strcmp(insn
->name
, "ldf_ldf")
2467 || !strcmp(insn
->name
, "ldf1_ldf2")
2468 || !strcmp(insn
->name
, "ldf2_ldf1") )
2470 if ( insn
->num_operands
< 4 && insn
->num_operands
> 5 )
2471 as_fatal ("Illegal internal %s insn definition", insn
->name
);
2473 if ( insn
->operands
[1].mode
== M_REGISTER
2474 && insn
->operands
[insn
->num_operands
-1].mode
== M_REGISTER
2475 && insn
->operands
[1].expr
.X_add_number
== insn
->operands
[insn
->num_operands
-1].expr
.X_add_number
)
2476 as_warn ("Equal parallell destination registers, one result will be discarded");
2481 tic4x_insn_output (insn
)
2486 /* Grab another fragment for opcode. */
2487 dst
= frag_more (insn
->nchars
);
2489 /* Put out opcode word as a series of bytes in little endian order. */
2490 md_number_to_chars (dst
, insn
->opcode
, insn
->nchars
);
2492 /* Put out the symbol-dependent stuff. */
2493 if (insn
->reloc
!= NO_RELOC
)
2495 /* Where is the offset into the fragment for this instruction. */
2496 fix_new_exp (frag_now
,
2497 dst
- frag_now
->fr_literal
, /* where */
2498 insn
->nchars
, /* size */
2505 /* Parse the operands. */
2507 tic4x_operands_parse (s
, operands
, num_operands
)
2509 tic4x_operand_t
*operands
;
2513 return num_operands
;
2516 s
= tic4x_operand_parse (s
, &operands
[num_operands
++]);
2517 while (num_operands
< TIC4X_OPERANDS_MAX
&& *s
++ == ',');
2519 if (num_operands
> TIC4X_OPERANDS_MAX
)
2521 as_bad ("Too many operands scanned");
2524 return num_operands
;
2527 /* Assemble a single instruction. Its label has already been handled
2528 by the generic front end. We just parse mnemonic and operands, and
2529 produce the bytes of data and relocation. */
2538 tic4x_inst_t
*inst
; /* Instruction template. */
2539 tic4x_inst_t
*first_inst
;
2541 /* Scan for parallel operators */
2545 while (*s
&& *s
!= '|')
2548 if (*s
&& s
[1]=='|')
2552 as_bad ("Parallel opcode cannot contain more than two instructions");
2558 /* Lets take care of the first part of the parallel insn */
2563 /* .. and let the second run though here */
2567 if (str
&& insn
->parallel
)
2569 /* Find mnemonic (second part of parallel instruction). */
2571 /* Skip past instruction mnemonic. */
2572 while (*s
&& *s
!= ' ')
2574 if (*s
) /* Null terminate for hash_find. */
2575 *s
++ = '\0'; /* and skip past null. */
2576 strcat (insn
->name
, "_");
2577 strncat (insn
->name
, str
, TIC4X_NAME_MAX
- strlen (insn
->name
));
2579 insn
->operands
[insn
->num_operands
++].mode
= M_PARALLEL
;
2581 if ((i
= tic4x_operands_parse
2582 (s
, insn
->operands
, insn
->num_operands
)) < 0)
2588 insn
->num_operands
= i
;
2594 if ((insn
->inst
= (struct tic4x_inst
*)
2595 hash_find (tic4x_op_hash
, insn
->name
)) == NULL
)
2597 as_bad ("Unknown opcode `%s'.", insn
->name
);
2607 ok
= tic4x_operands_match (inst
, insn
, 1);
2614 } while (!ok
&& !strcmp (inst
->name
, inst
[1].name
) && inst
++);
2618 tic4x_insn_check (insn
);
2619 tic4x_insn_output (insn
);
2624 tic4x_operands_match (first_inst
, insn
, 0);
2625 as_bad ("Invalid operands for %s", insn
->name
);
2628 as_bad ("Invalid instruction %s", insn
->name
);
2633 /* Find mnemonic. */
2635 while (*s
&& *s
!= ' ') /* Skip past instruction mnemonic. */
2637 if (*s
) /* Null terminate for hash_find. */
2638 *s
++ = '\0'; /* and skip past null. */
2639 strncpy (insn
->name
, str
, TIC4X_NAME_MAX
- 3);
2641 if ((i
= tic4x_operands_parse (s
, insn
->operands
, 0)) < 0)
2643 insn
->inst
= NULL
; /* Flag that error occured. */
2648 insn
->num_operands
= i
;
2663 /* Turn a string in input_line_pointer into a floating point constant
2664 of type type, and store the appropriate bytes in *litP. The number
2665 of LITTLENUMS emitted is stored in *sizeP. An error message is
2666 returned, or NULL on OK. */
2669 md_atof (type
, litP
, sizeP
)
2676 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2677 LITTLENUM_TYPE
*wordP
;
2682 case 's': /* .single */
2688 case 'd': /* .double */
2690 case 'f': /* .float or .single */
2693 prec
= 2; /* 1 32-bit word */
2696 case 'i': /* .ieee */
2700 type
= 'f'; /* Rewrite type to be usable by atof_ieee() */
2703 case 'e': /* .ldouble */
2705 prec
= 4; /* 2 32-bit words */
2711 return "Bad call to md_atof()";
2715 t
= atof_ieee (input_line_pointer
, type
, words
);
2717 t
= tic4x_atof (input_line_pointer
, type
, words
);
2719 input_line_pointer
= t
;
2720 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
2722 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
2723 little endian byte order. */
2724 /* SES: However it is required to put the words (32-bits) out in the
2725 correct order, hence we write 2 and 2 littlenums in little endian
2726 order, while we keep the original order on successive words. */
2727 for(wordP
= words
; wordP
<(words
+prec
) ; wordP
+=2)
2729 if (wordP
<(words
+prec
-1)) /* Dump wordP[1] (if we have one) */
2731 md_number_to_chars (litP
, (valueT
) (wordP
[1]),
2732 sizeof (LITTLENUM_TYPE
));
2733 litP
+= sizeof (LITTLENUM_TYPE
);
2737 md_number_to_chars (litP
, (valueT
) (wordP
[0]),
2738 sizeof (LITTLENUM_TYPE
));
2739 litP
+= sizeof (LITTLENUM_TYPE
);
2745 md_apply_fix (fixP
, value
, seg
)
2748 segT seg ATTRIBUTE_UNUSED
;
2750 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
2751 valueT val
= *value
;
2753 switch (fixP
->fx_r_type
)
2755 case BFD_RELOC_HI16
:
2759 case BFD_RELOC_LO16
:
2766 switch (fixP
->fx_r_type
)
2771 case BFD_RELOC_24_PCREL
:
2774 case BFD_RELOC_16_PCREL
:
2775 case BFD_RELOC_LO16
:
2776 case BFD_RELOC_HI16
:
2783 as_bad ("Bad relocation type: 0x%02x", fixP
->fx_r_type
);
2787 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0) fixP
->fx_done
= 1;
2790 /* Should never be called for tic4x. */
2792 md_convert_frag (headers
, sec
, fragP
)
2793 bfd
*headers ATTRIBUTE_UNUSED
;
2794 segT sec ATTRIBUTE_UNUSED
;
2795 fragS
*fragP ATTRIBUTE_UNUSED
;
2797 as_fatal ("md_convert_frag");
2800 /* Should never be called for tic4x. */
2802 md_create_short_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
2803 char *ptr ATTRIBUTE_UNUSED
;
2804 addressT from_addr ATTRIBUTE_UNUSED
;
2805 addressT to_addr ATTRIBUTE_UNUSED
;
2806 fragS
*frag ATTRIBUTE_UNUSED
;
2807 symbolS
*to_symbol ATTRIBUTE_UNUSED
;
2809 as_fatal ("md_create_short_jmp\n");
2812 /* Should never be called for tic4x. */
2814 md_create_long_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
2815 char *ptr ATTRIBUTE_UNUSED
;
2816 addressT from_addr ATTRIBUTE_UNUSED
;
2817 addressT to_addr ATTRIBUTE_UNUSED
;
2818 fragS
*frag ATTRIBUTE_UNUSED
;
2819 symbolS
*to_symbol ATTRIBUTE_UNUSED
;
2821 as_fatal ("md_create_long_jump\n");
2824 /* Should never be called for tic4x. */
2826 md_estimate_size_before_relax (fragP
, segtype
)
2827 register fragS
*fragP ATTRIBUTE_UNUSED
;
2828 segT segtype ATTRIBUTE_UNUSED
;
2830 as_fatal ("md_estimate_size_before_relax\n");
2836 md_parse_option (c
, arg
)
2842 case OPTION_CPU
: /* cpu brand */
2843 if (TOLOWER (*arg
) == 'c')
2845 tic4x_cpu
= atoi (arg
);
2846 if (!IS_CPU_TIC3X (tic4x_cpu
) && !IS_CPU_TIC4X (tic4x_cpu
))
2847 as_warn ("Unsupported processor generation %d", tic4x_cpu
);
2850 case OPTION_REV
: /* cpu revision */
2851 tic4x_revision
= atoi (arg
);
2855 as_warn ("Option -b is depreciated, please use -mbig");
2856 case OPTION_BIG
: /* big model */
2857 tic4x_big_model
= 1;
2861 as_warn ("Option -p is depreciated, please use -mmemparm");
2862 case OPTION_MEMPARM
: /* push args */
2867 as_warn ("Option -r is depreciated, please use -mregparm");
2868 case OPTION_REGPARM
: /* register args */
2873 as_warn ("Option -s is depreciated, please use -msmall");
2874 case OPTION_SMALL
: /* small model */
2875 tic4x_big_model
= 0;
2882 case OPTION_LOWPOWER
:
2886 case OPTION_ENHANCED
:
2898 md_show_usage (stream
)
2902 _("\nTIC4X options:\n"
2903 " -mcpu=CPU -mCPU select architecture variant. CPU can be:\n"
2905 " 31 - TMS320C31, TMS320LC31\n"
2907 " 33 - TMS320VC33\n"
2910 " -mrev=REV set cpu hardware revision (integer numbers).\n"
2911 " Combinations of -mcpu and -mrev will enable/disable\n"
2912 " the appropriate options (-midle2, -mlowpower and\n"
2913 " -menhanced) according to the selected type\n"
2914 " -mbig select big memory model\n"
2915 " -msmall select small memory model (default)\n"
2916 " -mregparm select register parameters (default)\n"
2917 " -mmemparm select memory parameters\n"
2918 " -midle2 enable IDLE2 support\n"
2919 " -mlowpower enable LOPOWER and MAXSPEED support\n"
2920 " -menhanced enable enhanced opcode support\n"));
2923 /* This is called when a line is unrecognized. This is used to handle
2924 definitions of TI C3x tools style local labels $n where n is a single
2927 tic4x_unrecognized_line (c
)
2933 if (c
!= '$' || ! ISDIGIT (input_line_pointer
[0]))
2936 s
= input_line_pointer
;
2938 /* Let's allow multiple digit local labels. */
2940 while (ISDIGIT (*s
))
2942 lab
= lab
* 10 + *s
- '0';
2946 if (dollar_label_defined (lab
))
2948 as_bad ("Label \"$%d\" redefined", lab
);
2952 define_dollar_label (lab
);
2953 colon (dollar_label_name (lab
, 0));
2954 input_line_pointer
= s
+ 1;
2959 /* Handle local labels peculiar to us referred to in an expression. */
2961 md_undefined_symbol (name
)
2964 /* Look for local labels of the form $n. */
2965 if (name
[0] == '$' && ISDIGIT (name
[1]))
2971 while (ISDIGIT ((unsigned char) *s
))
2973 lab
= lab
* 10 + *s
- '0';
2976 if (dollar_label_defined (lab
))
2978 name
= dollar_label_name (lab
, 0);
2979 symbolP
= symbol_find (name
);
2983 name
= dollar_label_name (lab
, 1);
2984 symbolP
= symbol_find_or_make (name
);
2992 /* Parse an operand that is machine-specific. */
2994 md_operand (expressionP
)
2995 expressionS
*expressionP ATTRIBUTE_UNUSED
;
2999 /* Round up a section size to the appropriate boundary---do we need this? */
3001 md_section_align (segment
, size
)
3002 segT segment ATTRIBUTE_UNUSED
;
3005 return size
; /* Byte (i.e., 32-bit) alignment is fine? */
3009 tic4x_pc_offset (op
)
3012 /* Determine the PC offset for a C[34]x instruction.
3013 This could be simplified using some boolean algebra
3014 but at the expense of readability. */
3018 case 0x62: /* call (C4x) */
3019 case 0x64: /* rptb (C4x) */
3021 case 0x61: /* brd */
3022 case 0x63: /* laj */
3023 case 0x65: /* rptbd (C4x) */
3025 case 0x66: /* swi */
3032 switch ((op
& 0xffe00000) >> 20)
3034 case 0x6a0: /* bB */
3035 case 0x720: /* callB */
3036 case 0x740: /* trapB */
3039 case 0x6a2: /* bBd */
3040 case 0x6a6: /* bBat */
3041 case 0x6aa: /* bBaf */
3042 case 0x722: /* lajB */
3043 case 0x748: /* latB */
3044 case 0x798: /* rptbd */
3051 switch ((op
& 0xfe200000) >> 20)
3053 case 0x6e0: /* dbB */
3056 case 0x6e2: /* dbBd */
3066 /* Exactly what point is a PC-relative offset relative TO?
3067 With the C3x we have the following:
3068 DBcond, Bcond disp + PC + 1 => PC
3069 DBcondD, BcondD disp + PC + 3 => PC
3072 md_pcrel_from (fixP
)
3078 buf
= (unsigned char *) fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
3079 op
= (buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
3081 return ((fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) >> 2) +
3082 tic4x_pc_offset (op
);
3085 /* Fill the alignment area with NOP's on .text, unless fill-data
3088 tic4x_do_align (alignment
, fill
, len
, max
)
3089 int alignment ATTRIBUTE_UNUSED
;
3090 const char *fill ATTRIBUTE_UNUSED
;
3091 int len ATTRIBUTE_UNUSED
;
3092 int max ATTRIBUTE_UNUSED
;
3094 unsigned long nop
= TIC_NOP_OPCODE
;
3096 /* Because we are talking lwords, not bytes, adjust alignment to do words */
3099 if (alignment
!= 0 && !need_pass_2
)
3103 /*if (subseg_text_p (now_seg))*/ /* FIXME: doesn't work for .text for some reason */
3104 frag_align_pattern( alignment
, (const char *)&nop
, sizeof(nop
), max
);
3107 frag_align (alignment, 0, max);*/
3110 frag_align (alignment
, *fill
, max
);
3112 frag_align_pattern (alignment
, fill
, len
, max
);
3115 /* Return 1 to skip the default alignment function */
3119 /* Look for and remove parallel instruction operator ||. */
3123 char *s
= input_line_pointer
;
3127 /* If parallel instruction prefix found at start of line, skip it. */
3128 if (*input_line_pointer
== '|' && input_line_pointer
[1] == '|')
3133 input_line_pointer
++;
3134 *input_line_pointer
= ' ';
3135 /* So line counters get bumped. */
3136 input_line_pointer
[-1] = '\n';
3141 /* Write out the previous insn here */
3144 input_line_pointer
= s
;
3149 tc_gen_reloc (seg
, fixP
)
3150 asection
*seg ATTRIBUTE_UNUSED
;
3155 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
3157 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
3158 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
3159 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
3160 reloc
->address
/= OCTETS_PER_BYTE
;
3161 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
3162 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
3164 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3165 "Reloc %d not supported by object file format",
3166 (int) fixP
->fx_r_type
);
3170 if (fixP
->fx_r_type
== BFD_RELOC_HI16
)
3171 reloc
->addend
= fixP
->fx_offset
;
3173 reloc
->addend
= fixP
->fx_addnumber
;