1 /* tc-tic4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
2 Copyright (C) 1997,1998, 2002, 2003, 2005, 2006, 2007, 2008
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 (const tic4x_inst_t
*);
190 static tic4x_inst_t
*tic4x_inst_make
191 PARAMS ((char *, unsigned long, char *));
192 static int tic4x_inst_add (const tic4x_inst_t
*);
195 static int tic4x_indirect_parse
196 PARAMS ((tic4x_operand_t
*, const tic4x_indirect_t
*));
197 static char *tic4x_operand_parse
198 PARAMS ((char *, tic4x_operand_t
*));
199 static int tic4x_operands_match
200 PARAMS ((tic4x_inst_t
*, tic4x_insn_t
*, int));
201 static void tic4x_insn_check
202 PARAMS ((tic4x_insn_t
*));
203 static void tic4x_insn_output
204 PARAMS ((tic4x_insn_t
*));
205 static int tic4x_operands_parse
206 PARAMS ((char *, tic4x_operand_t
*, int ));
209 int tic4x_unrecognized_line
211 static int tic4x_pc_offset
212 PARAMS ((unsigned int));
214 PARAMS ((int, const char *, int, int));
215 void tic4x_start_line
217 arelent
*tc_gen_reloc
218 PARAMS ((asection
*, fixS
*));
224 {"align", s_align_bytes
, 32},
225 {"ascii", tic4x_stringer
, 1},
226 {"asciz", tic4x_stringer
, 0},
227 {"asg", tic4x_asg
, 0},
228 {"block", s_space
, 4},
229 {"byte", tic4x_cons
, 1},
230 {"bss", tic4x_bss
, 0},
231 {"copy", s_include
, 0},
232 {"def", tic4x_globl
, 0},
233 {"equ", tic4x_set
, 0},
234 {"eval", tic4x_eval
, 0},
235 {"global", tic4x_globl
, 0},
236 {"globl", tic4x_globl
, 0},
237 {"hword", tic4x_cons
, 2},
238 {"ieee", float_cons
, 'i'},
239 {"int", tic4x_cons
, 4}, /* .int allocates 4 bytes. */
240 {"ldouble", float_cons
, 'e'},
241 {"newblock", tic4x_newblock
, 0},
242 {"ref", s_ignore
, 0}, /* All undefined treated as external. */
243 {"set", tic4x_set
, 0},
244 {"sect", tic4x_sect
, 1}, /* Define named section. */
245 {"space", s_space
, 4},
246 {"string", tic4x_stringer
, 0},
247 {"usect", tic4x_usect
, 0}, /* Reserve space in uninit. named sect. */
248 {"version", tic4x_version
, 0},
249 {"word", tic4x_cons
, 4}, /* .word allocates 4 bytes. */
250 {"xdef", tic4x_globl
, 0},
254 int md_short_jump_size
= 4;
255 int md_long_jump_size
= 4;
257 /* This array holds the chars that always start a comment. If the
258 pre-processor is disabled, these aren't very useful. */
259 #ifdef TIC4X_ALT_SYNTAX
260 const char comment_chars
[] = ";!";
262 const char comment_chars
[] = ";";
265 /* This array holds the chars that only start a comment at the beginning of
266 a line. If the line seems to have the form '# 123 filename'
267 .line and .file directives will appear in the pre-processed output.
268 Note that input_file.c hand checks for '#' at the beginning of the
269 first line of the input file. This is because the compiler outputs
270 #NO_APP at the beginning of its output.
271 Also note that comments like this one will always work. */
272 const char line_comment_chars
[] = "#*";
274 /* We needed an unused char for line separation to work around the
275 lack of macros, using sed and such. */
276 const char line_separator_chars
[] = "&";
278 /* Chars that can be used to separate mant from exp in floating point nums. */
279 const char EXP_CHARS
[] = "eE";
281 /* Chars that mean this number is a floating point constant. */
284 const char FLT_CHARS
[] = "fFilsS";
286 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
287 changed in read.c. Ideally it shouldn't have to know about it at
288 all, but nothing is ideal around here. */
290 /* Flonums returned here. */
291 extern FLONUM_TYPE generic_floating_point_number
;
293 /* Precision in LittleNums. */
294 #define MAX_PRECISION (4) /* Its a bit overkill for us, but the code
296 #define S_PRECISION (1) /* Short float constants 16-bit. */
297 #define F_PRECISION (2) /* Float and double types 32-bit. */
298 #define E_PRECISION (4) /* Extended precision, 64-bit (real 40-bit). */
301 /* Turn generic_floating_point_number into a real short/float/double. */
303 tic4x_gen_to_words (flonum
, words
, precision
)
305 LITTLENUM_TYPE
*words
;
308 int return_value
= 0;
309 LITTLENUM_TYPE
*p
; /* Littlenum pointer. */
310 int mantissa_bits
; /* Bits in mantissa field. */
311 int exponent_bits
; /* Bits in exponent field. */
313 unsigned int sone
; /* Scaled one. */
314 unsigned int sfract
; /* Scaled fraction. */
315 unsigned int smant
; /* Scaled mantissa. */
317 unsigned int mover
; /* Mantissa overflow bits */
318 unsigned int rbit
; /* Round bit. */
319 int shift
; /* Shift count. */
321 /* NOTE: Svein Seldal <Svein@dev.seldal.com>
322 The code in this function is altered slightly to support floats
323 with 31-bits mantissas, thus the documentation below may be a
324 little bit inaccurate.
326 By Michael P. Hayes <m.hayes@elec.canterbury.ac.nz>
327 Here is how a generic floating point number is stored using
328 flonums (an extension of bignums) where p is a pointer to an
331 For example 2e-3 is stored with exp = -4 and
338 with low = &bits[2], high = &bits[5], and leader = &bits[5].
340 This number can be written as
341 0x0083126e978d4fde.00000000 * 65536**-4 or
342 0x0.0083126e978d4fde * 65536**0 or
343 0x0.83126e978d4fde * 2**-8 = 2e-3
345 Note that low points to the 65536**0 littlenum (bits[2]) and
346 leader points to the most significant non-zero littlenum
349 TMS320C3X floating point numbers are a bit of a strange beast.
350 The 32-bit flavour has the 8 MSBs representing the exponent in
351 twos complement format (-128 to +127). There is then a sign bit
352 followed by 23 bits of mantissa. The mantissa is expressed in
353 twos complement format with the binary point after the most
354 significant non sign bit. The bit after the binary point is
355 suppressed since it is the complement of the sign bit. The
356 effective mantissa is thus 24 bits. Zero is represented by an
359 The 16-bit flavour has the 4 MSBs representing the exponent in
360 twos complement format (-8 to +7). There is then a sign bit
361 followed by 11 bits of mantissa. The mantissa is expressed in
362 twos complement format with the binary point after the most
363 significant non sign bit. The bit after the binary point is
364 suppressed since it is the complement of the sign bit. The
365 effective mantissa is thus 12 bits. Zero is represented by an
366 exponent of -8. For example,
368 number norm mant m x e s i fraction f
369 +0.500 => 1.00000000000 -1 -1 0 1 .00000000000 (1 + 0) * 2^(-1)
370 +0.999 => 1.11111111111 -1 -1 0 1 .11111111111 (1 + 0.99) * 2^(-1)
371 +1.000 => 1.00000000000 0 0 0 1 .00000000000 (1 + 0) * 2^(0)
372 +1.500 => 1.10000000000 0 0 0 1 .10000000000 (1 + 0.5) * 2^(0)
373 +1.999 => 1.11111111111 0 0 0 1 .11111111111 (1 + 0.9) * 2^(0)
374 +2.000 => 1.00000000000 1 1 0 1 .00000000000 (1 + 0) * 2^(1)
375 +4.000 => 1.00000000000 2 2 0 1 .00000000000 (1 + 0) * 2^(2)
376 -0.500 => 1.00000000000 -1 -1 1 0 .10000000000 (-2 + 0) * 2^(-2)
377 -1.000 => 1.00000000000 0 -1 1 0 .00000000000 (-2 + 0) * 2^(-1)
378 -1.500 => 1.10000000000 0 0 1 0 .10000000000 (-2 + 0.5) * 2^(0)
379 -1.999 => 1.11111111111 0 0 1 0 .00000000001 (-2 + 0.11) * 2^(0)
380 -2.000 => 1.00000000000 1 1 1 0 .00000000000 (-2 + 0) * 2^(0)
381 -4.000 => 1.00000000000 2 1 1 0 .00000000000 (-2 + 0) * 2^(1)
383 where e is the exponent, s is the sign bit, i is the implied bit,
384 and f is the fraction stored in the mantissa field.
386 num = (1 + f) * 2^x = m * 2^e if s = 0
387 num = (-2 + f) * 2^x = -m * 2^e if s = 1
388 where 0 <= f < 1.0 and 1.0 <= m < 2.0
390 The fraction (f) and exponent (e) fields for the TMS320C3X format
391 can be derived from the normalised mantissa (m) and exponent (x) using:
393 f = m - 1, e = x if s = 0
394 f = 2 - m, e = x if s = 1 and m != 1.0
395 f = 0, e = x - 1 if s = 1 and m = 1.0
396 f = 0, e = -8 if m = 0
399 OK, the other issue we have to consider is rounding since the
400 mantissa has a much higher potential precision than what we can
401 represent. To do this we add half the smallest storable fraction.
402 We then have to renormalise the number to allow for overflow.
404 To convert a generic flonum into a TMS320C3X floating point
405 number, here's what we try to do....
407 The first thing is to generate a normalised mantissa (m) where
408 1.0 <= m < 2 and to convert the exponent from base 16 to base 2.
409 We desire the binary point to be placed after the most significant
410 non zero bit. This process is done in two steps: firstly, the
411 littlenum with the most significant non zero bit is located (this
412 is done for us since leader points to this littlenum) and the
413 binary point (which is currently after the LSB of the littlenum
414 pointed to by low) is moved to before the MSB of the littlenum
415 pointed to by leader. This requires the exponent to be adjusted
416 by leader - low + 1. In the earlier example, the new exponent is
417 thus -4 + (5 - 2 + 1) = 0 (base 65536). We now need to convert
418 the exponent to base 2 by multiplying the exponent by 16 (log2
419 65536). The exponent base 2 is thus also zero.
421 The second step is to hunt for the most significant non zero bit
422 in the leader littlenum. We do this by left shifting a copy of
423 the leader littlenum until bit 16 is set (0x10000) and counting
424 the number of shifts, S, required. The number of shifts then has to
425 be added to correct the exponent (base 2). For our example, this
426 will require 9 shifts and thus our normalised exponent (base 2) is
427 0 + 9 = 9. Note that the worst case scenario is when the leader
428 littlenum is 1, thus requiring 16 shifts.
430 We now have to left shift the other littlenums by the same amount,
431 propagating the shifted bits into the more significant littlenums.
432 To save a lot of unnecessary shifting we only have to consider
433 two or three littlenums, since the greatest number of mantissa
434 bits required is 24 + 1 rounding bit. While two littlenums
435 provide 32 bits of precision, the most significant littlenum
436 may only contain a single significant bit and thus an extra
437 littlenum is required.
439 Denoting the number of bits in the fraction field as F, we require
440 G = F + 2 bits (one extra bit is for rounding, the other gets
441 suppressed). Say we required S shifts to find the most
442 significant bit in the leader littlenum, the number of left shifts
443 required to move this bit into bit position G - 1 is L = G + S - 17.
444 Note that this shift count may be negative for the short floating
445 point flavour (where F = 11 and thus G = 13 and potentially S < 3).
446 If L > 0 we have to shunt the next littlenum into position. Bit
447 15 (the MSB) of the next littlenum needs to get moved into position
448 L - 1 (If L > 15 we need all the bits of this littlenum and
449 some more from the next one.). We subtract 16 from L and use this
450 as the left shift count; the resultant value we or with the
451 previous result. If L > 0, we repeat this operation. */
453 if (precision
!= S_PRECISION
)
455 if (precision
== E_PRECISION
)
456 words
[2] = words
[3] = 0x0000;
458 /* 0.0e0 or NaN seen. */
459 if (flonum
.low
> flonum
.leader
/* = 0.0e0 */
460 || flonum
.sign
== 0) /* = NaN */
463 as_bad ("Nan, using zero.");
468 if (flonum
.sign
== 'P')
470 /* +INF: Replace with maximum float. */
471 if (precision
== S_PRECISION
)
478 if (precision
== E_PRECISION
)
485 else if (flonum
.sign
== 'N')
487 /* -INF: Replace with maximum float. */
488 if (precision
== S_PRECISION
)
492 if (precision
== E_PRECISION
)
497 exponent
= (flonum
.exponent
+ flonum
.leader
- flonum
.low
+ 1) * 16;
499 if (!(tmp
= *flonum
.leader
))
500 abort (); /* Hmmm. */
501 shift
= 0; /* Find position of first sig. bit. */
504 exponent
-= (16 - shift
); /* Adjust exponent. */
506 if (precision
== S_PRECISION
) /* Allow 1 rounding bit. */
511 else if(precision
== F_PRECISION
)
516 else /* E_PRECISION */
522 shift
= mantissa_bits
- shift
;
527 /* Store the mantissa data into smant and the roundbit into rbit */
528 for (p
= flonum
.leader
; p
>= flonum
.low
&& shift
> -16; p
--)
530 tmp
= shift
>= 0 ? *p
<< shift
: *p
>> -shift
;
531 rbit
= shift
< 0 ? ((*p
>> (-shift
-1)) & 0x1) : 0;
536 /* OK, we've got our scaled mantissa so let's round it up */
539 /* If the mantissa is going to overflow when added, lets store
540 the extra bit in mover. -- A special case exists when
541 mantissa_bits is 31 (E_PRECISION). Then the first test cannot
542 be trusted, as result is host-dependent, thus the second
544 if( smant
== ((unsigned)(1<<(mantissa_bits
+1))-1)
545 || smant
== (unsigned)-1 ) /* This is to catch E_PRECISION cases */
550 /* Get the scaled one value */
551 sone
= (1 << (mantissa_bits
));
553 /* The number may be unnormalised so renormalise it... */
557 smant
|= sone
; /* Insert the bit from mover into smant */
561 /* The binary point is now between bit positions 11 and 10 or 23 and 22,
562 i.e., between mantissa_bits - 1 and mantissa_bits - 2 and the
563 bit at mantissa_bits - 1 should be set. */
565 abort (); /* Ooops. */
567 if (flonum
.sign
== '+')
568 sfract
= smant
- sone
; /* smant - 1.0. */
571 /* This seems to work. */
579 sfract
= -smant
& (sone
-1); /* 2.0 - smant. */
581 sfract
|= sone
; /* Insert sign bit. */
584 if (abs (exponent
) >= (1 << (exponent_bits
- 1)))
585 as_bad ("Cannot represent exponent in %d bits", exponent_bits
);
587 /* Force exponent to fit in desired field width. */
588 exponent
&= (1 << (exponent_bits
)) - 1;
590 if (precision
== E_PRECISION
)
592 /* Map the float part first (100% equal format as F_PRECISION) */
593 words
[0] = exponent
<< (mantissa_bits
+1-24);
594 words
[0] |= sfract
>> 24;
595 words
[1] = sfract
>> 8;
597 /* Map the mantissa in the next */
598 words
[2] = sfract
>> 16;
599 words
[3] = sfract
& 0xffff;
603 /* Insert the exponent data into the word */
604 sfract
|= exponent
<< (mantissa_bits
+1);
606 if (precision
== S_PRECISION
)
610 words
[0] = sfract
>> 16;
611 words
[1] = sfract
& 0xffff;
618 /* Returns pointer past text consumed. */
620 tic4x_atof (str
, what_kind
, words
)
623 LITTLENUM_TYPE
*words
;
625 /* Extra bits for zeroed low-order bits. The 1st MAX_PRECISION are
626 zeroed, the last contain flonum bits. */
627 static LITTLENUM_TYPE bits
[MAX_PRECISION
+ MAX_PRECISION
+ GUARD
];
629 /* Number of 16-bit words in the format. */
631 FLONUM_TYPE save_gen_flonum
;
633 /* We have to save the generic_floating_point_number because it
634 contains storage allocation about the array of LITTLENUMs where
635 the value is actually stored. We will allocate our own array of
636 littlenums below, but have to restore the global one on exit. */
637 save_gen_flonum
= generic_floating_point_number
;
640 generic_floating_point_number
.low
= bits
+ MAX_PRECISION
;
641 generic_floating_point_number
.high
= NULL
;
642 generic_floating_point_number
.leader
= NULL
;
643 generic_floating_point_number
.exponent
= 0;
644 generic_floating_point_number
.sign
= '\0';
646 /* Use more LittleNums than seems necessary: the highest flonum may
647 have 15 leading 0 bits, so could be useless. */
649 memset (bits
, '\0', sizeof (LITTLENUM_TYPE
) * MAX_PRECISION
);
655 precision
= S_PRECISION
;
662 precision
= F_PRECISION
;
667 precision
= E_PRECISION
;
671 as_bad ("Invalid floating point number");
675 generic_floating_point_number
.high
676 = generic_floating_point_number
.low
+ precision
- 1 + GUARD
;
678 if (atof_generic (&return_value
, ".", EXP_CHARS
,
679 &generic_floating_point_number
))
681 as_bad ("Invalid floating point number");
685 tic4x_gen_to_words (generic_floating_point_number
,
688 /* Restore the generic_floating_point_number's storage alloc (and
690 generic_floating_point_number
= save_gen_flonum
;
696 tic4x_insert_reg (regname
, regnum
)
703 symbol_table_insert (symbol_new (regname
, reg_section
, (valueT
) regnum
,
704 &zero_address_frag
));
705 for (i
= 0; regname
[i
]; i
++)
706 buf
[i
] = ISLOWER (regname
[i
]) ? TOUPPER (regname
[i
]) : regname
[i
];
709 symbol_table_insert (symbol_new (buf
, reg_section
, (valueT
) regnum
,
710 &zero_address_frag
));
714 tic4x_insert_sym (symname
, value
)
720 symbolP
= symbol_new (symname
, absolute_section
,
721 (valueT
) value
, &zero_address_frag
);
722 SF_SET_LOCAL (symbolP
);
723 symbol_table_insert (symbolP
);
727 tic4x_expression (str
, exp
)
734 t
= input_line_pointer
; /* Save line pointer. */
735 input_line_pointer
= str
;
737 s
= input_line_pointer
;
738 input_line_pointer
= t
; /* Restore line pointer. */
739 return s
; /* Return pointer to where parsing stopped. */
743 tic4x_expression_abs (str
, value
)
750 t
= input_line_pointer
; /* Save line pointer. */
751 input_line_pointer
= str
;
752 *value
= get_absolute_expression ();
753 s
= input_line_pointer
;
754 input_line_pointer
= t
; /* Restore line pointer. */
759 tic4x_emit_char (c
,b
)
765 exp
.X_op
= O_constant
;
766 exp
.X_add_number
= c
;
771 tic4x_seg_alloc (name
, seg
, size
, symbolP
)
772 char *name ATTRIBUTE_UNUSED
;
773 segT seg ATTRIBUTE_UNUSED
;
777 /* Note that the size is in words
778 so we multiply it by 4 to get the number of bytes to allocate. */
780 /* If we have symbol: .usect ".fred", size etc.,
781 the symbol needs to point to the first location reserved
788 p
= frag_var (rs_fill
, 1, 1, (relax_substateT
) 0,
790 size
* OCTETS_PER_BYTE
, (char *) 0);
795 /* .asg ["]character-string["], symbol */
798 int x ATTRIBUTE_UNUSED
;
806 str
= input_line_pointer
;
808 /* Skip string expression. */
809 while (*input_line_pointer
!= ',' && *input_line_pointer
)
810 input_line_pointer
++;
811 if (*input_line_pointer
!= ',')
813 as_bad ("Comma expected\n");
816 *input_line_pointer
++ = '\0';
817 name
= input_line_pointer
;
818 c
= get_symbol_end (); /* Get terminator. */
819 tmp
= xmalloc (strlen (str
) + 1);
822 tmp
= xmalloc (strlen (name
) + 1);
825 if (hash_find (tic4x_asg_hash
, name
))
826 hash_replace (tic4x_asg_hash
, name
, (PTR
) str
);
828 hash_insert (tic4x_asg_hash
, name
, (PTR
) str
);
829 *input_line_pointer
= c
;
830 demand_empty_rest_of_line ();
833 /* .bss symbol, size */
836 int x ATTRIBUTE_UNUSED
;
843 subsegT current_subseg
;
846 current_seg
= now_seg
; /* Save current seg. */
847 current_subseg
= now_subseg
; /* Save current subseg. */
850 name
= input_line_pointer
;
851 c
= get_symbol_end (); /* Get terminator. */
854 as_bad (".bss size argument missing\n");
859 tic4x_expression_abs (++input_line_pointer
, &size
);
862 as_bad (".bss size %ld < 0!", (long) size
);
865 subseg_set (bss_section
, 0);
866 symbolP
= symbol_find_or_make (name
);
868 if (S_GET_SEGMENT (symbolP
) == bss_section
)
869 symbol_get_frag (symbolP
)->fr_symbol
= 0;
871 symbol_set_frag (symbolP
, frag_now
);
873 p
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
,
874 size
* OCTETS_PER_BYTE
, (char *) 0);
875 *p
= 0; /* Fill char. */
877 S_SET_SEGMENT (symbolP
, bss_section
);
879 /* The symbol may already have been created with a preceding
880 ".globl" directive -- be careful not to step on storage class
881 in that case. Otherwise, set it to static. */
882 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
883 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
885 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
886 demand_empty_rest_of_line ();
891 int ignore ATTRIBUTE_UNUSED
;
899 name
= input_line_pointer
;
900 c
= get_symbol_end ();
901 symbolP
= symbol_find_or_make (name
);
902 *input_line_pointer
= c
;
904 S_SET_STORAGE_CLASS (symbolP
, C_EXT
);
907 input_line_pointer
++;
909 if (*input_line_pointer
== '\n')
915 demand_empty_rest_of_line ();
918 /* Handle .byte, .word. .int, .long */
923 register unsigned int c
;
927 if (*input_line_pointer
== '"')
929 input_line_pointer
++;
930 while (is_a_char (c
= next_char_of_string ()))
931 tic4x_emit_char (c
, 4);
932 know (input_line_pointer
[-1] == '\"');
938 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
939 if (exp
.X_op
== O_constant
)
944 exp
.X_add_number
&= 255;
947 exp
.X_add_number
&= 65535;
951 /* Perhaps we should disallow .byte and .hword with
952 a non constant expression that will require relocation. */
956 while (*input_line_pointer
++ == ',');
958 input_line_pointer
--; /* Put terminator back into stream. */
959 demand_empty_rest_of_line ();
962 /* Handle .ascii, .asciz, .string */
964 tic4x_stringer (append_zero
)
965 int append_zero
; /*ex: bytes */
968 register unsigned int c
;
974 if (*input_line_pointer
== '"')
976 input_line_pointer
++;
977 while (is_a_char (c
= next_char_of_string ()))
979 tic4x_emit_char (c
, 1);
985 tic4x_emit_char (c
, 1);
989 know (input_line_pointer
[-1] == '\"');
995 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
996 if (exp
.X_op
!= O_constant
)
998 as_bad("Non-constant symbols not allowed\n");
1001 exp
.X_add_number
&= 255; /* Limit numeber to 8-bit */
1002 emit_expr (&exp
, 1);
1006 while (*input_line_pointer
++ == ',');
1008 /* Fill out the rest of the expression with 0's to fill up a full word */
1010 tic4x_emit_char (0, 4-(bytes
&0x3));
1012 input_line_pointer
--; /* Put terminator back into stream. */
1013 demand_empty_rest_of_line ();
1016 /* .eval expression, symbol */
1019 int x ATTRIBUTE_UNUSED
;
1026 input_line_pointer
=
1027 tic4x_expression_abs (input_line_pointer
, &value
);
1028 if (*input_line_pointer
++ != ',')
1030 as_bad ("Symbol missing\n");
1033 name
= input_line_pointer
;
1034 c
= get_symbol_end (); /* Get terminator. */
1035 demand_empty_rest_of_line ();
1036 tic4x_insert_sym (name
, value
);
1039 /* Reset local labels. */
1042 int x ATTRIBUTE_UNUSED
;
1044 dollar_label_clear ();
1047 /* .sect "section-name" [, value] */
1048 /* .sect ["]section-name[:subsection-name]["] [, value] */
1051 int x ATTRIBUTE_UNUSED
;
1055 char *subsection_name
;
1061 if (*input_line_pointer
== '"')
1062 input_line_pointer
++;
1063 section_name
= input_line_pointer
;
1064 c
= get_symbol_end (); /* Get terminator. */
1065 input_line_pointer
++; /* Skip null symbol terminator. */
1066 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1067 strcpy (name
, section_name
);
1069 /* TI C from version 5.0 allows a section name to contain a
1070 subsection name as well. The subsection name is separated by a
1071 ':' from the section name. Currently we scan the subsection
1072 name and discard it.
1073 Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>. */
1076 subsection_name
= input_line_pointer
;
1077 c
= get_symbol_end (); /* Get terminator. */
1078 input_line_pointer
++; /* Skip null symbol terminator. */
1079 as_warn (".sect: subsection name ignored");
1082 /* We might still have a '"' to discard, but the character after a
1083 symbol name will be overwritten with a \0 by get_symbol_end()
1087 input_line_pointer
=
1088 tic4x_expression_abs (input_line_pointer
, &num
);
1089 else if (*input_line_pointer
== ',')
1091 input_line_pointer
=
1092 tic4x_expression_abs (++input_line_pointer
, &num
);
1097 seg
= subseg_new (name
, num
);
1098 if (line_label
!= NULL
)
1100 S_SET_SEGMENT (line_label
, seg
);
1101 symbol_set_frag (line_label
, frag_now
);
1104 if (bfd_get_section_flags (stdoutput
, seg
) == SEC_NO_FLAGS
)
1106 if (!bfd_set_section_flags (stdoutput
, seg
, SEC_DATA
))
1107 as_warn ("Error setting flags for \"%s\": %s", name
,
1108 bfd_errmsg (bfd_get_error ()));
1111 /* If the last character overwritten by get_symbol_end() was an
1112 end-of-line, we must restore it or the end of the line will not be
1113 recognised and scanning extends into the next line, stopping with
1114 an error (blame Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>
1115 if this is not true). */
1116 if (is_end_of_line
[(unsigned char) c
])
1117 *(--input_line_pointer
) = c
;
1119 demand_empty_rest_of_line ();
1122 /* symbol[:] .set value or .set symbol, value */
1125 int x ATTRIBUTE_UNUSED
;
1130 if ((symbolP
= line_label
) == NULL
)
1135 name
= input_line_pointer
;
1136 c
= get_symbol_end (); /* Get terminator. */
1139 as_bad (".set syntax invalid\n");
1140 ignore_rest_of_line ();
1143 ++input_line_pointer
;
1144 symbolP
= symbol_find_or_make (name
);
1147 symbol_table_insert (symbolP
);
1149 pseudo_set (symbolP
);
1150 demand_empty_rest_of_line ();
1153 /* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
1156 int x ATTRIBUTE_UNUSED
;
1162 offsetT size
, alignment_flag
;
1164 subsegT current_subseg
;
1166 current_seg
= now_seg
; /* save current seg. */
1167 current_subseg
= now_subseg
; /* save current subseg. */
1170 if (*input_line_pointer
== '"')
1171 input_line_pointer
++;
1172 section_name
= input_line_pointer
;
1173 c
= get_symbol_end (); /* Get terminator. */
1174 input_line_pointer
++; /* Skip null symbol terminator. */
1175 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1176 strcpy (name
, section_name
);
1179 input_line_pointer
=
1180 tic4x_expression_abs (input_line_pointer
, &size
);
1181 else if (*input_line_pointer
== ',')
1183 input_line_pointer
=
1184 tic4x_expression_abs (++input_line_pointer
, &size
);
1189 /* Read a possibly present third argument (alignment flag) [VK]. */
1190 if (*input_line_pointer
== ',')
1192 input_line_pointer
=
1193 tic4x_expression_abs (++input_line_pointer
, &alignment_flag
);
1198 as_warn (".usect: non-zero alignment flag ignored");
1200 seg
= subseg_new (name
, 0);
1201 if (line_label
!= NULL
)
1203 S_SET_SEGMENT (line_label
, seg
);
1204 symbol_set_frag (line_label
, frag_now
);
1205 S_SET_VALUE (line_label
, frag_now_fix ());
1207 seg_info (seg
)->bss
= 1; /* Uninitialised data. */
1208 if (!bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
))
1209 as_warn ("Error setting flags for \"%s\": %s", name
,
1210 bfd_errmsg (bfd_get_error ()));
1211 tic4x_seg_alloc (name
, seg
, size
, line_label
);
1213 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1214 S_SET_STORAGE_CLASS (line_label
, C_STAT
);
1216 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
1217 demand_empty_rest_of_line ();
1220 /* .version cpu-version. */
1223 int x ATTRIBUTE_UNUSED
;
1227 input_line_pointer
=
1228 tic4x_expression_abs (input_line_pointer
, &temp
);
1229 if (!IS_CPU_TIC3X (temp
) && !IS_CPU_TIC4X (temp
))
1230 as_bad ("This assembler does not support processor generation %ld",
1233 if (tic4x_cpu
&& temp
!= (offsetT
) tic4x_cpu
)
1234 as_warn ("Changing processor generation on fly not supported...");
1236 demand_empty_rest_of_line ();
1240 tic4x_init_regtable ()
1244 for (i
= 0; i
< tic3x_num_registers
; i
++)
1245 tic4x_insert_reg (tic3x_registers
[i
].name
,
1246 tic3x_registers
[i
].regno
);
1248 if (IS_CPU_TIC4X (tic4x_cpu
))
1250 /* Add additional Tic4x registers, overriding some C3x ones. */
1251 for (i
= 0; i
< tic4x_num_registers
; i
++)
1252 tic4x_insert_reg (tic4x_registers
[i
].name
,
1253 tic4x_registers
[i
].regno
);
1258 tic4x_init_symbols ()
1260 /* The TI tools accept case insensitive versions of these symbols,
1265 .TMS320xx 30,31,32,40,or 44 set according to -v flag
1266 .C3X or .C3x 1 or 0 1 if -v30,-v31,or -v32
1267 .C30 1 or 0 1 if -v30
1268 .C31 1 or 0 1 if -v31
1269 .C32 1 or 0 1 if -v32
1270 .C4X or .C4x 1 or 0 1 if -v40, or -v44
1271 .C40 1 or 0 1 if -v40
1272 .C44 1 or 0 1 if -v44
1274 .REGPARM 1 or 0 1 if -mr option used
1275 .BIGMODEL 1 or 0 1 if -mb option used
1277 These symbols are currently supported but will be removed in a
1279 .TMS320C30 1 or 0 1 if -v30,-v31,or -v32
1280 .TMS320C31 1 or 0 1 if -v31
1281 .TMS320C32 1 or 0 1 if -v32
1282 .TMS320C40 1 or 0 1 if -v40, or -v44
1283 .TMS320C44 1 or 0 1 if -v44
1285 Source: TI: TMS320C3x/C4x Assembly Language Tools User's Guide,
1286 1997, SPRU035C, p. 3-17/3-18. */
1287 tic4x_insert_sym (".REGPARM", tic4x_reg_args
);
1288 tic4x_insert_sym (".MEMPARM", !tic4x_reg_args
);
1289 tic4x_insert_sym (".BIGMODEL", tic4x_big_model
);
1290 tic4x_insert_sym (".C30INTERRUPT", 0);
1291 tic4x_insert_sym (".TMS320xx", tic4x_cpu
== 0 ? 40 : tic4x_cpu
);
1292 tic4x_insert_sym (".C3X", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1293 tic4x_insert_sym (".C3x", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1294 tic4x_insert_sym (".C4X", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1295 tic4x_insert_sym (".C4x", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1296 /* Do we need to have the following symbols also in lower case? */
1297 tic4x_insert_sym (".TMS320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1298 tic4x_insert_sym (".tms320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1299 tic4x_insert_sym (".TMS320C31", tic4x_cpu
== 31);
1300 tic4x_insert_sym (".tms320C31", tic4x_cpu
== 31);
1301 tic4x_insert_sym (".TMS320C32", tic4x_cpu
== 32);
1302 tic4x_insert_sym (".tms320C32", tic4x_cpu
== 32);
1303 tic4x_insert_sym (".TMS320C33", tic4x_cpu
== 33);
1304 tic4x_insert_sym (".tms320C33", tic4x_cpu
== 33);
1305 tic4x_insert_sym (".TMS320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1306 tic4x_insert_sym (".tms320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1307 tic4x_insert_sym (".TMS320C44", tic4x_cpu
== 44);
1308 tic4x_insert_sym (".tms320C44", tic4x_cpu
== 44);
1309 tic4x_insert_sym (".TMX320C40", 0); /* C40 first pass silicon ? */
1310 tic4x_insert_sym (".tmx320C40", 0);
1313 /* Insert a new instruction template into hash table. */
1315 tic4x_inst_insert (const tic4x_inst_t
*inst
)
1317 static char prev_name
[16];
1318 const char *retval
= NULL
;
1320 /* Only insert the first name if have several similar entries. */
1321 if (!strcmp (inst
->name
, prev_name
) || inst
->name
[0] == '\0')
1324 retval
= hash_insert (tic4x_op_hash
, inst
->name
, (PTR
) inst
);
1326 fprintf (stderr
, "internal error: can't hash `%s': %s\n",
1327 inst
->name
, retval
);
1329 strcpy (prev_name
, inst
->name
);
1330 return retval
== NULL
;
1333 /* Make a new instruction template. */
1334 static tic4x_inst_t
*
1335 tic4x_inst_make (name
, opcode
, args
)
1337 unsigned long opcode
;
1340 static tic4x_inst_t
*insts
= NULL
;
1341 static char *names
= NULL
;
1342 static int index
= 0;
1346 /* Allocate memory to store name strings. */
1347 names
= (char *) xmalloc (sizeof (char) * 8192);
1348 /* Allocate memory for additional insts. */
1349 insts
= (tic4x_inst_t
*)
1350 xmalloc (sizeof (tic4x_inst_t
) * 1024);
1352 insts
[index
].name
= names
;
1353 insts
[index
].opcode
= opcode
;
1354 insts
[index
].opmask
= 0xffffffff;
1355 insts
[index
].args
= args
;
1363 return &insts
[index
- 1];
1366 /* Add instruction template, creating dynamic templates as required. */
1368 tic4x_inst_add (const tic4x_inst_t
*insts
)
1370 char *s
= insts
->name
;
1378 /* We do not care about INSNs that is not a part of our
1380 if (!insts
->oplevel
& tic4x_oplevel
)
1389 /* Dynamically create all the conditional insts. */
1390 for (i
= 0; i
< tic4x_num_conds
; i
++)
1394 char *c
= tic4x_conds
[i
].name
;
1404 /* If instruction found then have already processed it. */
1405 if (hash_find (tic4x_op_hash
, name
))
1410 inst
= tic4x_inst_make (name
, insts
[k
].opcode
+
1411 (tic4x_conds
[i
].cond
<<
1412 (*s
== 'B' ? 16 : 23)),
1414 if (k
== 0) /* Save strcmp() with following func. */
1415 ok
&= tic4x_inst_insert (inst
);
1418 while (!strcmp (insts
->name
,
1425 return tic4x_inst_insert (insts
);
1435 /* This function is called once, at assembler startup time. It should
1436 set up all the tables, etc., that the MD part of the assembler will
1444 /* Setup the proper opcode level according to the
1445 commandline parameters */
1446 tic4x_oplevel
= OP_C3X
;
1448 if ( IS_CPU_TIC4X(tic4x_cpu
) )
1449 tic4x_oplevel
|= OP_C4X
;
1451 if ( ( tic4x_cpu
== 31 && tic4x_revision
>= 6)
1452 || (tic4x_cpu
== 32 && tic4x_revision
>= 2)
1453 || (tic4x_cpu
== 33)
1455 tic4x_oplevel
|= OP_ENH
;
1457 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1458 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1459 || (tic4x_cpu
== 32)
1461 tic4x_oplevel
|= OP_LPWR
;
1463 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1464 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1465 || (tic4x_cpu
== 32)
1466 || (tic4x_cpu
== 33)
1467 || (tic4x_cpu
== 40 && tic4x_revision
>= 5)
1468 || (tic4x_cpu
== 44)
1470 tic4x_oplevel
|= OP_IDLE2
;
1472 /* Create hash table for mnemonics. */
1473 tic4x_op_hash
= hash_new ();
1475 /* Create hash table for asg pseudo. */
1476 tic4x_asg_hash
= hash_new ();
1478 /* Add mnemonics to hash table, expanding conditional mnemonics on fly. */
1479 for (i
= 0; i
< tic4x_num_insts
; i
++)
1480 ok
&= tic4x_inst_add (tic4x_insts
+ i
);
1482 /* Create dummy inst to avoid errors accessing end of table. */
1483 tic4x_inst_make ("", 0, "");
1486 as_fatal ("Broken assembler. No assembly attempted.");
1488 /* Add registers to symbol table. */
1489 tic4x_init_regtable ();
1491 /* Add predefined symbols to symbol table. */
1492 tic4x_init_symbols ();
1498 bfd_set_arch_mach (stdoutput
, bfd_arch_tic4x
,
1499 IS_CPU_TIC4X (tic4x_cpu
) ? bfd_mach_tic4x
: bfd_mach_tic3x
);
1503 tic4x_indirect_parse (operand
, indirect
)
1504 tic4x_operand_t
*operand
;
1505 const tic4x_indirect_t
*indirect
;
1507 char *n
= indirect
->name
;
1508 char *s
= input_line_pointer
;
1518 case 'a': /* Need to match aux register. */
1520 #ifdef TIC4X_ALT_SYNTAX
1524 while (ISALNUM (*s
))
1527 if (!(symbolP
= symbol_find (name
)))
1530 if (S_GET_SEGMENT (symbolP
) != reg_section
)
1533 operand
->aregno
= S_GET_VALUE (symbolP
);
1534 if (operand
->aregno
>= REG_AR0
&& operand
->aregno
<= REG_AR7
)
1537 as_bad ("Auxiliary register AR0--AR7 required for indirect");
1540 case 'd': /* Need to match constant for disp. */
1541 #ifdef TIC4X_ALT_SYNTAX
1542 if (*s
== '%') /* expr() will die if we don't skip this. */
1545 s
= tic4x_expression (s
, &operand
->expr
);
1546 if (operand
->expr
.X_op
!= O_constant
)
1548 operand
->disp
= operand
->expr
.X_add_number
;
1549 if (operand
->disp
< 0 || operand
->disp
> 255)
1551 as_bad ("Bad displacement %d (require 0--255)\n",
1557 case 'y': /* Need to match IR0. */
1558 case 'z': /* Need to match IR1. */
1559 #ifdef TIC4X_ALT_SYNTAX
1563 s
= tic4x_expression (s
, &operand
->expr
);
1564 if (operand
->expr
.X_op
!= O_register
)
1566 if (operand
->expr
.X_add_number
!= REG_IR0
1567 && operand
->expr
.X_add_number
!= REG_IR1
)
1569 as_bad ("Index register IR0,IR1 required for displacement");
1573 if (*n
== 'y' && operand
->expr
.X_add_number
== REG_IR0
)
1575 if (*n
== 'z' && operand
->expr
.X_add_number
== REG_IR1
)
1580 if (*s
!= '(') /* No displacement, assume to be 1. */
1591 if (TOLOWER (*s
) != *n
)
1596 if (*s
!= ' ' && *s
!= ',' && *s
!= '\0')
1598 input_line_pointer
= s
;
1603 tic4x_operand_parse (s
, operand
)
1605 tic4x_operand_t
*operand
;
1610 expressionS
*exp
= &operand
->expr
;
1611 char *save
= input_line_pointer
;
1614 struct hash_entry
*entry
= NULL
;
1616 input_line_pointer
= s
;
1619 str
= input_line_pointer
;
1620 c
= get_symbol_end (); /* Get terminator. */
1621 new = input_line_pointer
;
1622 if (strlen (str
) && (entry
= hash_find (tic4x_asg_hash
, str
)) != NULL
)
1624 *input_line_pointer
= c
;
1625 input_line_pointer
= (char *) entry
;
1629 *input_line_pointer
= c
;
1630 input_line_pointer
= str
;
1633 operand
->mode
= M_UNKNOWN
;
1634 switch (*input_line_pointer
)
1636 #ifdef TIC4X_ALT_SYNTAX
1638 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1639 if (exp
->X_op
!= O_register
)
1640 as_bad ("Expecting a register name");
1641 operand
->mode
= M_REGISTER
;
1645 /* Denotes high 16 bits. */
1646 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1647 if (exp
->X_op
== O_constant
)
1648 operand
->mode
= M_IMMED
;
1649 else if (exp
->X_op
== O_big
)
1651 if (exp
->X_add_number
)
1652 as_bad ("Number too large"); /* bignum required */
1655 tic4x_gen_to_words (generic_floating_point_number
,
1656 operand
->fwords
, S_PRECISION
);
1657 operand
->mode
= M_IMMED_F
;
1660 /* Allow ori ^foo, ar0 to be equivalent to ldi .hi.foo, ar0 */
1661 /* WARNING : The TI C40 assembler cannot do this. */
1662 else if (exp
->X_op
== O_symbol
)
1664 operand
->mode
= M_HI
;
1669 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1670 if (exp
->X_op
== O_constant
)
1671 operand
->mode
= M_IMMED
;
1672 else if (exp
->X_op
== O_big
)
1674 if (exp
->X_add_number
> 0)
1675 as_bad ("Number too large"); /* bignum required. */
1678 tic4x_gen_to_words (generic_floating_point_number
,
1679 operand
->fwords
, S_PRECISION
);
1680 operand
->mode
= M_IMMED_F
;
1683 /* Allow ori foo, ar0 to be equivalent to ldi .lo.foo, ar0 */
1684 /* WARNING : The TI C40 assembler cannot do this. */
1685 else if (exp
->X_op
== O_symbol
)
1687 operand
->mode
= M_IMMED
;
1692 as_bad ("Expecting a constant value");
1697 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1698 if (exp
->X_op
!= O_constant
&& exp
->X_op
!= O_symbol
)
1699 as_bad ("Bad direct addressing construct %s", s
);
1700 if (exp
->X_op
== O_constant
)
1702 if (exp
->X_add_number
< 0)
1703 as_bad ("Direct value of %ld is not suitable",
1704 (long) exp
->X_add_number
);
1706 operand
->mode
= M_DIRECT
;
1711 for (i
= 0; i
< tic4x_num_indirects
; i
++)
1712 if ((ret
= tic4x_indirect_parse (operand
, &tic4x_indirects
[i
])))
1716 if (i
< tic4x_num_indirects
)
1718 operand
->mode
= M_INDIRECT
;
1719 /* Indirect addressing mode number. */
1720 operand
->expr
.X_add_number
= tic4x_indirects
[i
].modn
;
1721 /* Convert *+ARn(0) to *ARn etc. Maybe we should
1722 squeal about silly ones? */
1723 if (operand
->expr
.X_add_number
< 0x08 && !operand
->disp
)
1724 operand
->expr
.X_add_number
= 0x18;
1727 as_bad ("Unknown indirect addressing mode");
1731 operand
->mode
= M_IMMED
; /* Assume immediate. */
1732 str
= input_line_pointer
;
1733 input_line_pointer
= tic4x_expression (input_line_pointer
, exp
);
1734 if (exp
->X_op
== O_register
)
1736 know (exp
->X_add_symbol
== 0);
1737 know (exp
->X_op_symbol
== 0);
1738 operand
->mode
= M_REGISTER
;
1741 else if (exp
->X_op
== O_big
)
1743 if (exp
->X_add_number
> 0)
1744 as_bad ("Number too large"); /* bignum required. */
1747 tic4x_gen_to_words (generic_floating_point_number
,
1748 operand
->fwords
, S_PRECISION
);
1749 operand
->mode
= M_IMMED_F
;
1753 #ifdef TIC4X_ALT_SYNTAX
1754 /* Allow ldi foo, ar0 to be equivalent to ldi @foo, ar0. */
1755 else if (exp
->X_op
== O_symbol
)
1757 operand
->mode
= M_DIRECT
;
1763 new = input_line_pointer
;
1764 input_line_pointer
= save
;
1769 tic4x_operands_match (inst
, insn
, check
)
1774 const char *args
= inst
->args
;
1775 unsigned long opcode
= inst
->opcode
;
1776 int num_operands
= insn
->num_operands
;
1777 tic4x_operand_t
*operand
= insn
->operands
;
1778 expressionS
*exp
= &operand
->expr
;
1782 /* Build the opcode, checking as we go to make sure that the
1785 If an operand matches, we modify insn or opcode appropriately,
1786 and do a "continue". If an operand fails to match, we "break". */
1788 insn
->nchars
= 4; /* Instructions always 4 bytes. */
1789 insn
->reloc
= NO_RELOC
;
1794 insn
->opcode
= opcode
;
1795 return num_operands
== 0;
1803 case '\0': /* End of args. */
1804 if (num_operands
== 1)
1806 insn
->opcode
= opcode
;
1809 break; /* Too many operands. */
1811 case '#': /* This is only used for ldp. */
1812 if (operand
->mode
!= M_DIRECT
&& operand
->mode
!= M_IMMED
)
1814 /* While this looks like a direct addressing mode, we actually
1815 use an immediate mode form of ldiu or ldpk instruction. */
1816 if (exp
->X_op
== O_constant
)
1818 if( ( IS_CPU_TIC4X (tic4x_cpu
) && exp
->X_add_number
<= 65535 )
1819 || ( IS_CPU_TIC3X (tic4x_cpu
) && exp
->X_add_number
<= 255 ) )
1821 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1827 as_bad ("Immediate value of %ld is too large for ldf",
1828 (long) exp
->X_add_number
);
1833 else if (exp
->X_op
== O_symbol
)
1835 insn
->reloc
= BFD_RELOC_HI16
;
1839 break; /* Not direct (dp) addressing. */
1841 case '@': /* direct. */
1842 if (operand
->mode
!= M_DIRECT
)
1844 if (exp
->X_op
== O_constant
)
1846 /* Store only the 16 LSBs of the number. */
1847 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1850 else if (exp
->X_op
== O_symbol
)
1852 insn
->reloc
= BFD_RELOC_LO16
;
1856 break; /* Not direct addressing. */
1859 if (operand
->mode
!= M_REGISTER
)
1861 reg
= exp
->X_add_number
;
1862 if (reg
>= REG_AR0
&& reg
<= REG_AR7
)
1863 INSERTU (opcode
, reg
- REG_AR0
, 24, 22);
1867 as_bad ("Destination register must be ARn");
1872 case 'B': /* Unsigned integer immediate. */
1873 /* Allow br label or br @label. */
1874 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
1876 if (exp
->X_op
== O_constant
)
1878 if (exp
->X_add_number
< (1 << 24))
1880 INSERTU (opcode
, exp
->X_add_number
, 23, 0);
1886 as_bad ("Immediate value of %ld is too large",
1887 (long) exp
->X_add_number
);
1892 if (IS_CPU_TIC4X (tic4x_cpu
))
1894 insn
->reloc
= BFD_RELOC_24_PCREL
;
1899 insn
->reloc
= BFD_RELOC_24
;
1906 if (!IS_CPU_TIC4X (tic4x_cpu
))
1908 if (operand
->mode
!= M_INDIRECT
)
1910 /* Require either *+ARn(disp) or *ARn. */
1911 if (operand
->expr
.X_add_number
!= 0
1912 && operand
->expr
.X_add_number
!= 0x18)
1915 as_bad ("Invalid indirect addressing mode");
1919 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1920 INSERTU (opcode
, operand
->disp
, 7, 3);
1924 if (!(operand
->mode
== M_REGISTER
))
1926 INSERTU (opcode
, exp
->X_add_number
, 7, 0);
1930 if (!(operand
->mode
== M_REGISTER
))
1932 reg
= exp
->X_add_number
;
1933 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1934 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1935 INSERTU (opcode
, reg
, 7, 0);
1939 as_bad ("Register must be Rn");
1945 if (operand
->mode
!= M_IMMED_F
1946 && !(operand
->mode
== M_IMMED
&& exp
->X_op
== O_constant
))
1949 if (operand
->mode
!= M_IMMED_F
)
1951 /* OK, we 've got something like cmpf 0, r0
1952 Why can't they stick in a bloody decimal point ?! */
1955 /* Create floating point number string. */
1956 sprintf (string
, "%d.0", (int) exp
->X_add_number
);
1957 tic4x_atof (string
, 's', operand
->fwords
);
1960 INSERTU (opcode
, operand
->fwords
[0], 15, 0);
1964 if (operand
->mode
!= M_REGISTER
)
1966 INSERTU (opcode
, exp
->X_add_number
, 15, 8);
1970 if (operand
->mode
!= M_REGISTER
)
1972 reg
= exp
->X_add_number
;
1973 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1974 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1975 INSERTU (opcode
, reg
, 15, 8);
1979 as_bad ("Register must be Rn");
1985 if (operand
->mode
!= M_REGISTER
)
1987 reg
= exp
->X_add_number
;
1988 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1989 INSERTU (opcode
, reg
- REG_R0
, 18, 16);
1993 as_bad ("Register must be R0--R7");
1999 if ( operand
->mode
== M_REGISTER
2000 && tic4x_oplevel
& OP_ENH
)
2002 reg
= exp
->X_add_number
;
2003 INSERTU (opcode
, reg
, 4, 0);
2004 INSERTU (opcode
, 7, 7, 5);
2010 if (operand
->mode
!= M_INDIRECT
)
2012 if (operand
->disp
!= 0 && operand
->disp
!= 1)
2014 if (IS_CPU_TIC4X (tic4x_cpu
))
2017 as_bad ("Invalid indirect addressing mode displacement %d",
2022 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
2023 INSERTU (opcode
, operand
->expr
.X_add_number
, 7, 3);
2027 if ( operand
->mode
== M_REGISTER
2028 && tic4x_oplevel
& OP_ENH
)
2030 reg
= exp
->X_add_number
;
2031 INSERTU (opcode
, reg
, 12, 8);
2032 INSERTU (opcode
, 7, 15, 13);
2038 if (operand
->mode
!= M_INDIRECT
)
2040 if (operand
->disp
!= 0 && operand
->disp
!= 1)
2042 if (IS_CPU_TIC4X (tic4x_cpu
))
2045 as_bad ("Invalid indirect addressing mode displacement %d",
2050 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2051 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
2055 if (operand
->mode
!= M_REGISTER
)
2057 reg
= exp
->X_add_number
;
2058 if (reg
>= REG_R0
&& reg
<= REG_R7
)
2059 INSERTU (opcode
, reg
- REG_R0
, 21, 19);
2063 as_bad ("Register must be R0--R7");
2069 if (operand
->mode
!= M_REGISTER
)
2071 reg
= exp
->X_add_number
;
2072 if (reg
>= REG_R0
&& reg
<= REG_R7
)
2073 INSERTU (opcode
, reg
- REG_R0
, 24, 22);
2077 as_bad ("Register must be R0--R7");
2083 if (operand
->mode
!= M_REGISTER
)
2085 reg
= exp
->X_add_number
;
2086 if (reg
== REG_R2
|| reg
== REG_R3
)
2087 INSERTU (opcode
, reg
- REG_R2
, 22, 22);
2091 as_bad ("Destination register must be R2 or R3");
2097 if (operand
->mode
!= M_REGISTER
)
2099 reg
= exp
->X_add_number
;
2100 if (reg
== REG_R0
|| reg
== REG_R1
)
2101 INSERTU (opcode
, reg
- REG_R0
, 23, 23);
2105 as_bad ("Destination register must be R0 or R1");
2111 if (!IS_CPU_TIC4X (tic4x_cpu
))
2113 if (operand
->mode
!= M_INDIRECT
)
2115 /* Require either *+ARn(disp) or *ARn. */
2116 if (operand
->expr
.X_add_number
!= 0
2117 && operand
->expr
.X_add_number
!= 0x18)
2120 as_bad ("Invalid indirect addressing mode");
2124 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2125 INSERTU (opcode
, operand
->disp
, 15, 11);
2128 case 'P': /* PC relative displacement. */
2129 /* Allow br label or br @label. */
2130 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
2132 if (exp
->X_op
== O_constant
)
2134 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 32767)
2136 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2142 as_bad ("Displacement value of %ld is too large",
2143 (long) exp
->X_add_number
);
2148 insn
->reloc
= BFD_RELOC_16_PCREL
;
2154 if (operand
->mode
!= M_REGISTER
)
2156 reg
= exp
->X_add_number
;
2157 INSERTU (opcode
, reg
, 15, 0);
2161 if (operand
->mode
!= M_REGISTER
)
2163 reg
= exp
->X_add_number
;
2164 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2165 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2166 INSERTU (opcode
, reg
, 15, 0);
2170 as_bad ("Register must be Rn");
2176 if (operand
->mode
!= M_REGISTER
)
2178 reg
= exp
->X_add_number
;
2179 INSERTU (opcode
, reg
, 20, 16);
2183 if (operand
->mode
!= M_REGISTER
)
2185 reg
= exp
->X_add_number
;
2186 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2187 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2188 INSERTU (opcode
, reg
, 20, 16);
2192 as_bad ("Register must be Rn");
2197 case 'S': /* Short immediate int. */
2198 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2200 if (exp
->X_op
== O_big
)
2203 as_bad ("Floating point number not valid in expression");
2207 if (exp
->X_op
== O_constant
)
2209 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 65535)
2211 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2217 as_bad ("Signed immediate value %ld too large",
2218 (long) exp
->X_add_number
);
2223 else if (exp
->X_op
== O_symbol
)
2225 if (operand
->mode
== M_HI
)
2227 insn
->reloc
= BFD_RELOC_HI16
;
2231 insn
->reloc
= BFD_RELOC_LO16
;
2236 /* Handle cases like ldi foo - $, ar0 where foo
2237 is a forward reference. Perhaps we should check
2238 for X_op == O_symbol and disallow things like
2240 insn
->reloc
= BFD_RELOC_16
;
2244 case 'T': /* 5-bit immediate value for tic4x stik. */
2245 if (!IS_CPU_TIC4X (tic4x_cpu
))
2247 if (operand
->mode
!= M_IMMED
)
2249 if (exp
->X_op
== O_constant
)
2251 if (exp
->X_add_number
< 16 && exp
->X_add_number
>= -16)
2253 INSERTS (opcode
, exp
->X_add_number
, 20, 16);
2259 as_bad ("Immediate value of %ld is too large",
2260 (long) exp
->X_add_number
);
2265 break; /* No relocations allowed. */
2267 case 'U': /* Unsigned integer immediate. */
2268 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2270 if (exp
->X_op
== O_constant
)
2272 if (exp
->X_add_number
< (1 << 16) && exp
->X_add_number
>= 0)
2274 INSERTU (opcode
, exp
->X_add_number
, 15, 0);
2280 as_bad ("Unsigned immediate value %ld too large",
2281 (long) exp
->X_add_number
);
2286 else if (exp
->X_op
== O_symbol
)
2288 if (operand
->mode
== M_HI
)
2289 insn
->reloc
= BFD_RELOC_HI16
;
2291 insn
->reloc
= BFD_RELOC_LO16
;
2296 insn
->reloc
= BFD_RELOC_16
;
2300 case 'V': /* Trap numbers (immediate field). */
2301 if (operand
->mode
!= M_IMMED
)
2303 if (exp
->X_op
== O_constant
)
2305 if (exp
->X_add_number
< 512 && IS_CPU_TIC4X (tic4x_cpu
))
2307 INSERTU (opcode
, exp
->X_add_number
, 8, 0);
2310 else if (exp
->X_add_number
< 32 && IS_CPU_TIC3X (tic4x_cpu
))
2312 INSERTU (opcode
, exp
->X_add_number
| 0x20, 4, 0);
2318 as_bad ("Immediate value of %ld is too large",
2319 (long) exp
->X_add_number
);
2324 break; /* No relocations allowed. */
2326 case 'W': /* Short immediate int (0--7). */
2327 if (!IS_CPU_TIC4X (tic4x_cpu
))
2329 if (operand
->mode
!= M_IMMED
)
2331 if (exp
->X_op
== O_big
)
2334 as_bad ("Floating point number not valid in expression");
2338 if (exp
->X_op
== O_constant
)
2340 if (exp
->X_add_number
>= -256 && exp
->X_add_number
<= 127)
2342 INSERTS (opcode
, exp
->X_add_number
, 7, 0);
2348 as_bad ("Immediate value %ld too large",
2349 (long) exp
->X_add_number
);
2354 insn
->reloc
= BFD_RELOC_16
;
2358 case 'X': /* Expansion register for tic4x. */
2359 if (operand
->mode
!= M_REGISTER
)
2361 reg
= exp
->X_add_number
;
2362 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2363 INSERTU (opcode
, reg
- REG_IVTP
, 4, 0);
2367 as_bad ("Register must be ivtp or tvtp");
2372 case 'Y': /* Address register for tic4x lda. */
2373 if (operand
->mode
!= M_REGISTER
)
2375 reg
= exp
->X_add_number
;
2376 if (reg
>= REG_AR0
&& reg
<= REG_SP
)
2377 INSERTU (opcode
, reg
, 20, 16);
2381 as_bad ("Register must be address register");
2386 case 'Z': /* Expansion register for tic4x. */
2387 if (operand
->mode
!= M_REGISTER
)
2389 reg
= exp
->X_add_number
;
2390 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2391 INSERTU (opcode
, reg
- REG_IVTP
, 20, 16);
2395 as_bad ("Register must be ivtp or tvtp");
2401 if (operand
->mode
!= M_INDIRECT
)
2403 INSERTS (opcode
, operand
->disp
, 7, 0);
2404 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2405 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
2408 case '|': /* treat as `,' if have ldi_ldi form. */
2411 if (--num_operands
< 0)
2412 break; /* Too few operands. */
2414 if (operand
->mode
!= M_PARALLEL
)
2419 case ',': /* Another operand. */
2420 if (--num_operands
< 0)
2421 break; /* Too few operands. */
2423 exp
= &operand
->expr
;
2426 case ';': /* Another optional operand. */
2427 if (num_operands
== 1 || operand
[1].mode
== M_PARALLEL
)
2429 if (--num_operands
< 0)
2430 break; /* Too few operands. */
2432 exp
= &operand
->expr
;
2443 tic4x_insn_check (insn
)
2447 if (!strcmp(insn
->name
, "lda"))
2449 if (insn
->num_operands
< 2 || insn
->num_operands
> 2)
2450 as_fatal ("Illegal internal LDA insn definition");
2452 if ( insn
->operands
[0].mode
== M_REGISTER
2453 && insn
->operands
[1].mode
== M_REGISTER
2454 && insn
->operands
[0].expr
.X_add_number
== insn
->operands
[1].expr
.X_add_number
)
2455 as_bad ("Source and destination register should not be equal");
2457 else if( !strcmp(insn
->name
, "ldi_ldi")
2458 || !strcmp(insn
->name
, "ldi1_ldi2")
2459 || !strcmp(insn
->name
, "ldi2_ldi1")
2460 || !strcmp(insn
->name
, "ldf_ldf")
2461 || !strcmp(insn
->name
, "ldf1_ldf2")
2462 || !strcmp(insn
->name
, "ldf2_ldf1") )
2464 if ( insn
->num_operands
< 4 && insn
->num_operands
> 5 )
2465 as_fatal ("Illegal internal %s insn definition", insn
->name
);
2467 if ( insn
->operands
[1].mode
== M_REGISTER
2468 && insn
->operands
[insn
->num_operands
-1].mode
== M_REGISTER
2469 && insn
->operands
[1].expr
.X_add_number
== insn
->operands
[insn
->num_operands
-1].expr
.X_add_number
)
2470 as_warn ("Equal parallell destination registers, one result will be discarded");
2475 tic4x_insn_output (insn
)
2480 /* Grab another fragment for opcode. */
2481 dst
= frag_more (insn
->nchars
);
2483 /* Put out opcode word as a series of bytes in little endian order. */
2484 md_number_to_chars (dst
, insn
->opcode
, insn
->nchars
);
2486 /* Put out the symbol-dependent stuff. */
2487 if (insn
->reloc
!= NO_RELOC
)
2489 /* Where is the offset into the fragment for this instruction. */
2490 fix_new_exp (frag_now
,
2491 dst
- frag_now
->fr_literal
, /* where */
2492 insn
->nchars
, /* size */
2499 /* Parse the operands. */
2501 tic4x_operands_parse (s
, operands
, num_operands
)
2503 tic4x_operand_t
*operands
;
2507 return num_operands
;
2510 s
= tic4x_operand_parse (s
, &operands
[num_operands
++]);
2511 while (num_operands
< TIC4X_OPERANDS_MAX
&& *s
++ == ',');
2513 if (num_operands
> TIC4X_OPERANDS_MAX
)
2515 as_bad ("Too many operands scanned");
2518 return num_operands
;
2521 /* Assemble a single instruction. Its label has already been handled
2522 by the generic front end. We just parse mnemonic and operands, and
2523 produce the bytes of data and relocation. */
2532 tic4x_inst_t
*inst
; /* Instruction template. */
2533 tic4x_inst_t
*first_inst
;
2535 /* Scan for parallel operators */
2539 while (*s
&& *s
!= '|')
2542 if (*s
&& s
[1]=='|')
2546 as_bad ("Parallel opcode cannot contain more than two instructions");
2552 /* Lets take care of the first part of the parallel insn */
2557 /* .. and let the second run though here */
2561 if (str
&& insn
->parallel
)
2563 /* Find mnemonic (second part of parallel instruction). */
2565 /* Skip past instruction mnemonic. */
2566 while (*s
&& *s
!= ' ')
2568 if (*s
) /* Null terminate for hash_find. */
2569 *s
++ = '\0'; /* and skip past null. */
2570 strcat (insn
->name
, "_");
2571 strncat (insn
->name
, str
, TIC4X_NAME_MAX
- strlen (insn
->name
));
2573 insn
->operands
[insn
->num_operands
++].mode
= M_PARALLEL
;
2575 if ((i
= tic4x_operands_parse
2576 (s
, insn
->operands
, insn
->num_operands
)) < 0)
2582 insn
->num_operands
= i
;
2588 if ((insn
->inst
= (struct tic4x_inst
*)
2589 hash_find (tic4x_op_hash
, insn
->name
)) == NULL
)
2591 as_bad ("Unknown opcode `%s'.", insn
->name
);
2601 ok
= tic4x_operands_match (inst
, insn
, 1);
2608 } while (!ok
&& !strcmp (inst
->name
, inst
[1].name
) && inst
++);
2612 tic4x_insn_check (insn
);
2613 tic4x_insn_output (insn
);
2618 tic4x_operands_match (first_inst
, insn
, 0);
2619 as_bad ("Invalid operands for %s", insn
->name
);
2622 as_bad ("Invalid instruction %s", insn
->name
);
2627 /* Find mnemonic. */
2629 while (*s
&& *s
!= ' ') /* Skip past instruction mnemonic. */
2631 if (*s
) /* Null terminate for hash_find. */
2632 *s
++ = '\0'; /* and skip past null. */
2633 strncpy (insn
->name
, str
, TIC4X_NAME_MAX
- 3);
2635 if ((i
= tic4x_operands_parse (s
, insn
->operands
, 0)) < 0)
2637 insn
->inst
= NULL
; /* Flag that error occurred. */
2642 insn
->num_operands
= i
;
2657 /* Turn a string in input_line_pointer into a floating point constant
2658 of type type, and store the appropriate bytes in *litP. The number
2659 of chars emitted is stored in *sizeP. An error message is
2660 returned, or NULL on OK. */
2663 md_atof (int type
, char *litP
, int *sizeP
)
2667 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2668 LITTLENUM_TYPE
*wordP
;
2673 case 's': /* .single */
2679 case 'd': /* .double */
2681 case 'f': /* .float */
2684 prec
= 2; /* 1 32-bit word */
2687 case 'i': /* .ieee */
2691 type
= 'f'; /* Rewrite type to be usable by atof_ieee(). */
2694 case 'e': /* .ldouble */
2696 prec
= 4; /* 2 32-bit words */
2702 return _("Unrecognized or unsupported floating point constant");
2706 t
= atof_ieee (input_line_pointer
, type
, words
);
2708 t
= tic4x_atof (input_line_pointer
, type
, words
);
2710 input_line_pointer
= t
;
2711 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
2713 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
2714 little endian byte order. */
2715 /* SES: However it is required to put the words (32-bits) out in the
2716 correct order, hence we write 2 and 2 littlenums in little endian
2717 order, while we keep the original order on successive words. */
2718 for (wordP
= words
; wordP
<(words
+prec
) ; wordP
+=2)
2720 if (wordP
< (words
+ prec
- 1)) /* Dump wordP[1] (if we have one). */
2722 md_number_to_chars (litP
, (valueT
) (wordP
[1]),
2723 sizeof (LITTLENUM_TYPE
));
2724 litP
+= sizeof (LITTLENUM_TYPE
);
2728 md_number_to_chars (litP
, (valueT
) (wordP
[0]),
2729 sizeof (LITTLENUM_TYPE
));
2730 litP
+= sizeof (LITTLENUM_TYPE
);
2736 md_apply_fix (fixP
, value
, seg
)
2739 segT seg ATTRIBUTE_UNUSED
;
2741 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
2742 valueT val
= *value
;
2744 switch (fixP
->fx_r_type
)
2746 case BFD_RELOC_HI16
:
2750 case BFD_RELOC_LO16
:
2757 switch (fixP
->fx_r_type
)
2762 case BFD_RELOC_24_PCREL
:
2765 case BFD_RELOC_16_PCREL
:
2766 case BFD_RELOC_LO16
:
2767 case BFD_RELOC_HI16
:
2774 as_bad ("Bad relocation type: 0x%02x", fixP
->fx_r_type
);
2778 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0) fixP
->fx_done
= 1;
2781 /* Should never be called for tic4x. */
2783 md_convert_frag (headers
, sec
, fragP
)
2784 bfd
*headers ATTRIBUTE_UNUSED
;
2785 segT sec ATTRIBUTE_UNUSED
;
2786 fragS
*fragP ATTRIBUTE_UNUSED
;
2788 as_fatal ("md_convert_frag");
2791 /* Should never be called for tic4x. */
2793 md_create_short_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
2794 char *ptr ATTRIBUTE_UNUSED
;
2795 addressT from_addr ATTRIBUTE_UNUSED
;
2796 addressT to_addr ATTRIBUTE_UNUSED
;
2797 fragS
*frag ATTRIBUTE_UNUSED
;
2798 symbolS
*to_symbol ATTRIBUTE_UNUSED
;
2800 as_fatal ("md_create_short_jmp\n");
2803 /* Should never be called for tic4x. */
2805 md_create_long_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
2806 char *ptr ATTRIBUTE_UNUSED
;
2807 addressT from_addr ATTRIBUTE_UNUSED
;
2808 addressT to_addr ATTRIBUTE_UNUSED
;
2809 fragS
*frag ATTRIBUTE_UNUSED
;
2810 symbolS
*to_symbol ATTRIBUTE_UNUSED
;
2812 as_fatal ("md_create_long_jump\n");
2815 /* Should never be called for tic4x. */
2817 md_estimate_size_before_relax (fragP
, segtype
)
2818 register fragS
*fragP ATTRIBUTE_UNUSED
;
2819 segT segtype ATTRIBUTE_UNUSED
;
2821 as_fatal ("md_estimate_size_before_relax\n");
2827 md_parse_option (c
, arg
)
2833 case OPTION_CPU
: /* cpu brand */
2834 if (TOLOWER (*arg
) == 'c')
2836 tic4x_cpu
= atoi (arg
);
2837 if (!IS_CPU_TIC3X (tic4x_cpu
) && !IS_CPU_TIC4X (tic4x_cpu
))
2838 as_warn ("Unsupported processor generation %d", tic4x_cpu
);
2841 case OPTION_REV
: /* cpu revision */
2842 tic4x_revision
= atoi (arg
);
2846 as_warn ("Option -b is depreciated, please use -mbig");
2847 case OPTION_BIG
: /* big model */
2848 tic4x_big_model
= 1;
2852 as_warn ("Option -p is depreciated, please use -mmemparm");
2853 case OPTION_MEMPARM
: /* push args */
2858 as_warn ("Option -r is depreciated, please use -mregparm");
2859 case OPTION_REGPARM
: /* register args */
2864 as_warn ("Option -s is depreciated, please use -msmall");
2865 case OPTION_SMALL
: /* small model */
2866 tic4x_big_model
= 0;
2873 case OPTION_LOWPOWER
:
2877 case OPTION_ENHANCED
:
2889 md_show_usage (stream
)
2893 _("\nTIC4X options:\n"
2894 " -mcpu=CPU -mCPU select architecture variant. CPU can be:\n"
2896 " 31 - TMS320C31, TMS320LC31\n"
2898 " 33 - TMS320VC33\n"
2901 " -mrev=REV set cpu hardware revision (integer numbers).\n"
2902 " Combinations of -mcpu and -mrev will enable/disable\n"
2903 " the appropriate options (-midle2, -mlowpower and\n"
2904 " -menhanced) according to the selected type\n"
2905 " -mbig select big memory model\n"
2906 " -msmall select small memory model (default)\n"
2907 " -mregparm select register parameters (default)\n"
2908 " -mmemparm select memory parameters\n"
2909 " -midle2 enable IDLE2 support\n"
2910 " -mlowpower enable LOPOWER and MAXSPEED support\n"
2911 " -menhanced enable enhanced opcode support\n"));
2914 /* This is called when a line is unrecognized. This is used to handle
2915 definitions of TI C3x tools style local labels $n where n is a single
2918 tic4x_unrecognized_line (c
)
2924 if (c
!= '$' || ! ISDIGIT (input_line_pointer
[0]))
2927 s
= input_line_pointer
;
2929 /* Let's allow multiple digit local labels. */
2931 while (ISDIGIT (*s
))
2933 lab
= lab
* 10 + *s
- '0';
2937 if (dollar_label_defined (lab
))
2939 as_bad ("Label \"$%d\" redefined", lab
);
2943 define_dollar_label (lab
);
2944 colon (dollar_label_name (lab
, 0));
2945 input_line_pointer
= s
+ 1;
2950 /* Handle local labels peculiar to us referred to in an expression. */
2952 md_undefined_symbol (name
)
2955 /* Look for local labels of the form $n. */
2956 if (name
[0] == '$' && ISDIGIT (name
[1]))
2962 while (ISDIGIT ((unsigned char) *s
))
2964 lab
= lab
* 10 + *s
- '0';
2967 if (dollar_label_defined (lab
))
2969 name
= dollar_label_name (lab
, 0);
2970 symbolP
= symbol_find (name
);
2974 name
= dollar_label_name (lab
, 1);
2975 symbolP
= symbol_find_or_make (name
);
2983 /* Parse an operand that is machine-specific. */
2985 md_operand (expressionP
)
2986 expressionS
*expressionP ATTRIBUTE_UNUSED
;
2990 /* Round up a section size to the appropriate boundary---do we need this? */
2992 md_section_align (segment
, size
)
2993 segT segment ATTRIBUTE_UNUSED
;
2996 return size
; /* Byte (i.e., 32-bit) alignment is fine? */
3000 tic4x_pc_offset (op
)
3003 /* Determine the PC offset for a C[34]x instruction.
3004 This could be simplified using some boolean algebra
3005 but at the expense of readability. */
3009 case 0x62: /* call (C4x) */
3010 case 0x64: /* rptb (C4x) */
3012 case 0x61: /* brd */
3013 case 0x63: /* laj */
3014 case 0x65: /* rptbd (C4x) */
3016 case 0x66: /* swi */
3023 switch ((op
& 0xffe00000) >> 20)
3025 case 0x6a0: /* bB */
3026 case 0x720: /* callB */
3027 case 0x740: /* trapB */
3030 case 0x6a2: /* bBd */
3031 case 0x6a6: /* bBat */
3032 case 0x6aa: /* bBaf */
3033 case 0x722: /* lajB */
3034 case 0x748: /* latB */
3035 case 0x798: /* rptbd */
3042 switch ((op
& 0xfe200000) >> 20)
3044 case 0x6e0: /* dbB */
3047 case 0x6e2: /* dbBd */
3057 /* Exactly what point is a PC-relative offset relative TO?
3058 With the C3x we have the following:
3059 DBcond, Bcond disp + PC + 1 => PC
3060 DBcondD, BcondD disp + PC + 3 => PC
3063 md_pcrel_from (fixP
)
3069 buf
= (unsigned char *) fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
3070 op
= (buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
3072 return ((fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) >> 2) +
3073 tic4x_pc_offset (op
);
3076 /* Fill the alignment area with NOP's on .text, unless fill-data
3079 tic4x_do_align (alignment
, fill
, len
, max
)
3080 int alignment ATTRIBUTE_UNUSED
;
3081 const char *fill ATTRIBUTE_UNUSED
;
3082 int len ATTRIBUTE_UNUSED
;
3083 int max ATTRIBUTE_UNUSED
;
3085 unsigned long nop
= TIC_NOP_OPCODE
;
3087 /* Because we are talking lwords, not bytes, adjust alignment to do words */
3090 if (alignment
!= 0 && !need_pass_2
)
3094 /*if (subseg_text_p (now_seg))*/ /* FIXME: doesn't work for .text for some reason */
3095 frag_align_pattern( alignment
, (const char *)&nop
, sizeof(nop
), max
);
3098 frag_align (alignment, 0, max);*/
3101 frag_align (alignment
, *fill
, max
);
3103 frag_align_pattern (alignment
, fill
, len
, max
);
3106 /* Return 1 to skip the default alignment function */
3110 /* Look for and remove parallel instruction operator ||. */
3114 char *s
= input_line_pointer
;
3118 /* If parallel instruction prefix found at start of line, skip it. */
3119 if (*input_line_pointer
== '|' && input_line_pointer
[1] == '|')
3124 input_line_pointer
++;
3125 *input_line_pointer
= ' ';
3126 /* So line counters get bumped. */
3127 input_line_pointer
[-1] = '\n';
3132 /* Write out the previous insn here */
3135 input_line_pointer
= s
;
3140 tc_gen_reloc (seg
, fixP
)
3141 asection
*seg ATTRIBUTE_UNUSED
;
3146 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
3148 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
3149 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
3150 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
3151 reloc
->address
/= OCTETS_PER_BYTE
;
3152 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
3153 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
3155 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3156 "Reloc %d not supported by object file format",
3157 (int) fixP
->fx_r_type
);
3161 if (fixP
->fx_r_type
== BFD_RELOC_HI16
)
3162 reloc
->addend
= fixP
->fx_offset
;
3164 reloc
->addend
= fixP
->fx_addnumber
;