1 /* tc-tic4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
2 Copyright (C) 1997,1998, 2002, 2003 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, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, 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 primarely
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 exeeds 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 *, int *));
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
*));
201 static int tic4x_indirect_parse
202 PARAMS ((tic4x_operand_t
*, const tic4x_indirect_t
*));
203 static char *tic4x_operand_parse
204 PARAMS ((char *, tic4x_operand_t
*));
205 static int tic4x_operands_match
206 PARAMS ((tic4x_inst_t
*, tic4x_insn_t
*, int));
207 static void tic4x_insn_check
208 PARAMS ((tic4x_insn_t
*));
209 static void tic4x_insn_output
210 PARAMS ((tic4x_insn_t
*));
211 static int tic4x_operands_parse
212 PARAMS ((char *, tic4x_operand_t
*, int ));
218 PARAMS ((int, char *, int *));
220 PARAMS ((fixS
*, valueT
*, segT
));
222 PARAMS ((bfd
*, segT
, fragS
*));
223 void md_create_short_jump
224 PARAMS ((char *, addressT
, addressT
, fragS
*, symbolS
*));
225 void md_create_long_jump
226 PARAMS ((char *, addressT
, addressT
, fragS
*, symbolS
*));
227 int md_estimate_size_before_relax
228 PARAMS ((register fragS
*, segT
));
230 PARAMS ((int, char *));
233 int tic4x_unrecognized_line
235 symbolS
*md_undefined_symbol
238 PARAMS ((expressionS
*));
239 valueT md_section_align
240 PARAMS ((segT
, valueT
));
241 static int tic4x_pc_offset
242 PARAMS ((unsigned int));
246 PARAMS ((int, const char *, int, int));
247 void tic4x_start_line
249 arelent
*tc_gen_reloc
250 PARAMS ((asection
*, fixS
*));
256 {"align", s_align_bytes
, 32},
257 {"ascii", tic4x_stringer
, 1},
258 {"asciz", tic4x_stringer
, 0},
259 {"asg", tic4x_asg
, 0},
260 {"block", s_space
, 4},
261 {"byte", tic4x_cons
, 1},
262 {"bss", tic4x_bss
, 0},
263 {"copy", s_include
, 0},
264 {"def", tic4x_globl
, 0},
265 {"equ", tic4x_set
, 0},
266 {"eval", tic4x_eval
, 0},
267 {"global", tic4x_globl
, 0},
268 {"globl", tic4x_globl
, 0},
269 {"hword", tic4x_cons
, 2},
270 {"ieee", float_cons
, 'i'},
271 {"int", tic4x_cons
, 4}, /* .int allocates 4 bytes. */
272 {"ldouble", float_cons
, 'e'},
273 {"newblock", tic4x_newblock
, 0},
274 {"ref", s_ignore
, 0}, /* All undefined treated as external. */
275 {"set", tic4x_set
, 0},
276 {"sect", tic4x_sect
, 1}, /* Define named section. */
277 {"space", s_space
, 4},
278 {"string", tic4x_stringer
, 0},
279 {"usect", tic4x_usect
, 0}, /* Reserve space in uninit. named sect. */
280 {"version", tic4x_version
, 0},
281 {"word", tic4x_cons
, 4}, /* .word allocates 4 bytes. */
282 {"xdef", tic4x_globl
, 0},
286 int md_short_jump_size
= 4;
287 int md_long_jump_size
= 4;
288 const int md_reloc_size
= RELSZ
; /* Coff headers. */
290 /* This array holds the chars that always start a comment. If the
291 pre-processor is disabled, these aren't very useful. */
292 #ifdef TIC4X_ALT_SYNTAX
293 const char comment_chars
[] = ";!";
295 const char comment_chars
[] = ";";
298 /* This array holds the chars that only start a comment at the beginning of
299 a line. If the line seems to have the form '# 123 filename'
300 .line and .file directives will appear in the pre-processed output.
301 Note that input_file.c hand checks for '#' at the beginning of the
302 first line of the input file. This is because the compiler outputs
303 #NO_APP at the beginning of its output.
304 Also note that comments like this one will always work. */
305 const char line_comment_chars
[] = "#*";
307 /* We needed an unused char for line separation to work around the
308 lack of macros, using sed and such. */
309 const char line_separator_chars
[] = "&";
311 /* Chars that can be used to separate mant from exp in floating point nums. */
312 const char EXP_CHARS
[] = "eE";
314 /* Chars that mean this number is a floating point constant. */
317 const char FLT_CHARS
[] = "fFilsS";
319 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
320 changed in read.c. Ideally it shouldn't have to know about it at
321 all, but nothing is ideal around here. */
323 /* Flonums returned here. */
324 extern FLONUM_TYPE generic_floating_point_number
;
326 /* Precision in LittleNums. */
327 #define MAX_PRECISION (4) /* Its a bit overkill for us, but the code
329 #define S_PRECISION (1) /* Short float constants 16-bit. */
330 #define F_PRECISION (2) /* Float and double types 32-bit. */
331 #define E_PRECISION (4) /* Extended precision, 64-bit (real 40-bit). */
334 /* Turn generic_floating_point_number into a real short/float/double. */
336 tic4x_gen_to_words (flonum
, words
, precision
)
338 LITTLENUM_TYPE
*words
;
341 int return_value
= 0;
342 LITTLENUM_TYPE
*p
; /* Littlenum pointer. */
343 int mantissa_bits
; /* Bits in mantissa field. */
344 int exponent_bits
; /* Bits in exponent field. */
346 unsigned int sone
; /* Scaled one. */
347 unsigned int sfract
; /* Scaled fraction. */
348 unsigned int smant
; /* Scaled mantissa. */
350 unsigned int mover
; /* Mantissa overflow bits */
351 unsigned int rbit
; /* Round bit. */
352 int shift
; /* Shift count. */
354 /* NOTE: Svein Seldal <Svein.Seldal@solidas.com>
355 The code in this function is altered slightly to support floats
356 with 31-bits mantissas, thus the documentation below may be a
357 little bit inaccurate.
359 By Michael P. Hayes <m.hayes@elec.canterbury.ac.nz>
360 Here is how a generic floating point number is stored using
361 flonums (an extension of bignums) where p is a pointer to an
364 For example 2e-3 is stored with exp = -4 and
371 with low = &bits[2], high = &bits[5], and leader = &bits[5].
373 This number can be written as
374 0x0083126e978d4fde.00000000 * 65536**-4 or
375 0x0.0083126e978d4fde * 65536**0 or
376 0x0.83126e978d4fde * 2**-8 = 2e-3
378 Note that low points to the 65536**0 littlenum (bits[2]) and
379 leader points to the most significant non-zero littlenum
382 TMS320C3X floating point numbers are a bit of a strange beast.
383 The 32-bit flavour has the 8 MSBs representing the exponent in
384 twos complement format (-128 to +127). There is then a sign bit
385 followed by 23 bits of mantissa. The mantissa is expressed in
386 twos complement format with the binary point after the most
387 significant non sign bit. The bit after the binary point is
388 suppressed since it is the complement of the sign bit. The
389 effective mantissa is thus 24 bits. Zero is represented by an
392 The 16-bit flavour has the 4 MSBs representing the exponent in
393 twos complement format (-8 to +7). There is then a sign bit
394 followed by 11 bits of mantissa. The mantissa is expressed in
395 twos complement format with the binary point after the most
396 significant non sign bit. The bit after the binary point is
397 suppressed since it is the complement of the sign bit. The
398 effective mantissa is thus 12 bits. Zero is represented by an
399 exponent of -8. For example,
401 number norm mant m x e s i fraction f
402 +0.500 => 1.00000000000 -1 -1 0 1 .00000000000 (1 + 0) * 2^(-1)
403 +0.999 => 1.11111111111 -1 -1 0 1 .11111111111 (1 + 0.99) * 2^(-1)
404 +1.000 => 1.00000000000 0 0 0 1 .00000000000 (1 + 0) * 2^(0)
405 +1.500 => 1.10000000000 0 0 0 1 .10000000000 (1 + 0.5) * 2^(0)
406 +1.999 => 1.11111111111 0 0 0 1 .11111111111 (1 + 0.9) * 2^(0)
407 +2.000 => 1.00000000000 1 1 0 1 .00000000000 (1 + 0) * 2^(1)
408 +4.000 => 1.00000000000 2 2 0 1 .00000000000 (1 + 0) * 2^(2)
409 -0.500 => 1.00000000000 -1 -1 1 0 .10000000000 (-2 + 0) * 2^(-2)
410 -1.000 => 1.00000000000 0 -1 1 0 .00000000000 (-2 + 0) * 2^(-1)
411 -1.500 => 1.10000000000 0 0 1 0 .10000000000 (-2 + 0.5) * 2^(0)
412 -1.999 => 1.11111111111 0 0 1 0 .00000000001 (-2 + 0.11) * 2^(0)
413 -2.000 => 1.00000000000 1 1 1 0 .00000000000 (-2 + 0) * 2^(0)
414 -4.000 => 1.00000000000 2 1 1 0 .00000000000 (-2 + 0) * 2^(1)
416 where e is the exponent, s is the sign bit, i is the implied bit,
417 and f is the fraction stored in the mantissa field.
419 num = (1 + f) * 2^x = m * 2^e if s = 0
420 num = (-2 + f) * 2^x = -m * 2^e if s = 1
421 where 0 <= f < 1.0 and 1.0 <= m < 2.0
423 The fraction (f) and exponent (e) fields for the TMS320C3X format
424 can be derived from the normalised mantissa (m) and exponent (x) using:
426 f = m - 1, e = x if s = 0
427 f = 2 - m, e = x if s = 1 and m != 1.0
428 f = 0, e = x - 1 if s = 1 and m = 1.0
429 f = 0, e = -8 if m = 0
432 OK, the other issue we have to consider is rounding since the
433 mantissa has a much higher potential precision than what we can
434 represent. To do this we add half the smallest storable fraction.
435 We then have to renormalise the number to allow for overflow.
437 To convert a generic flonum into a TMS320C3X floating point
438 number, here's what we try to do....
440 The first thing is to generate a normalised mantissa (m) where
441 1.0 <= m < 2 and to convert the exponent from base 16 to base 2.
442 We desire the binary point to be placed after the most significant
443 non zero bit. This process is done in two steps: firstly, the
444 littlenum with the most significant non zero bit is located (this
445 is done for us since leader points to this littlenum) and the
446 binary point (which is currently after the LSB of the littlenum
447 pointed to by low) is moved to before the MSB of the littlenum
448 pointed to by leader. This requires the exponent to be adjusted
449 by leader - low + 1. In the earlier example, the new exponent is
450 thus -4 + (5 - 2 + 1) = 0 (base 65536). We now need to convert
451 the exponent to base 2 by multiplying the exponent by 16 (log2
452 65536). The exponent base 2 is thus also zero.
454 The second step is to hunt for the most significant non zero bit
455 in the leader littlenum. We do this by left shifting a copy of
456 the leader littlenum until bit 16 is set (0x10000) and counting
457 the number of shifts, S, required. The number of shifts then has to
458 be added to correct the exponent (base 2). For our example, this
459 will require 9 shifts and thus our normalised exponent (base 2) is
460 0 + 9 = 9. Note that the worst case scenario is when the leader
461 littlenum is 1, thus requiring 16 shifts.
463 We now have to left shift the other littlenums by the same amount,
464 propagating the shifted bits into the more significant littlenums.
465 To save a lot of unecessary shifting we only have to consider
466 two or three littlenums, since the greatest number of mantissa
467 bits required is 24 + 1 rounding bit. While two littlenums
468 provide 32 bits of precision, the most significant littlenum
469 may only contain a single significant bit and thus an extra
470 littlenum is required.
472 Denoting the number of bits in the fraction field as F, we require
473 G = F + 2 bits (one extra bit is for rounding, the other gets
474 suppressed). Say we required S shifts to find the most
475 significant bit in the leader littlenum, the number of left shifts
476 required to move this bit into bit position G - 1 is L = G + S - 17.
477 Note that this shift count may be negative for the short floating
478 point flavour (where F = 11 and thus G = 13 and potentially S < 3).
479 If L > 0 we have to shunt the next littlenum into position. Bit
480 15 (the MSB) of the next littlenum needs to get moved into position
481 L - 1 (If L > 15 we need all the bits of this littlenum and
482 some more from the next one.). We subtract 16 from L and use this
483 as the left shift count; the resultant value we or with the
484 previous result. If L > 0, we repeat this operation. */
486 if (precision
!= S_PRECISION
)
488 if (precision
== E_PRECISION
)
489 words
[2] = words
[3] = 0x0000;
491 /* 0.0e0 or NaN seen. */
492 if (flonum
.low
> flonum
.leader
/* = 0.0e0 */
493 || flonum
.sign
== 0) /* = NaN */
496 as_bad ("Nan, using zero.");
501 if (flonum
.sign
== 'P')
503 /* +INF: Replace with maximum float. */
504 if (precision
== S_PRECISION
)
511 if (precision
== E_PRECISION
)
518 else if (flonum
.sign
== 'N')
520 /* -INF: Replace with maximum float. */
521 if (precision
== S_PRECISION
)
525 if (precision
== E_PRECISION
)
530 exponent
= (flonum
.exponent
+ flonum
.leader
- flonum
.low
+ 1) * 16;
532 if (!(tmp
= *flonum
.leader
))
533 abort (); /* Hmmm. */
534 shift
= 0; /* Find position of first sig. bit. */
537 exponent
-= (16 - shift
); /* Adjust exponent. */
539 if (precision
== S_PRECISION
) /* Allow 1 rounding bit. */
544 else if(precision
== F_PRECISION
)
549 else /* E_PRECISION */
555 shift
= mantissa_bits
- shift
;
560 /* Store the mantissa data into smant and the roundbit into rbit */
561 for (p
= flonum
.leader
; p
>= flonum
.low
&& shift
> -16; p
--)
563 tmp
= shift
>= 0 ? *p
<< shift
: *p
>> -shift
;
564 rbit
= shift
< 0 ? ((*p
>> (-shift
-1)) & 0x1) : 0;
569 /* OK, we've got our scaled mantissa so let's round it up */
572 /* If the mantissa is going to overflow when added, lets store
573 the extra bit in mover. -- A special case exists when
574 mantissa_bits is 31 (E_PRECISION). Then the first test cannot
575 be trusted, as result is host-dependent, thus the second
577 if( smant
== ((unsigned)(1<<(mantissa_bits
+1))-1)
578 || smant
== (unsigned)-1 ) /* This is to catch E_PRECISION cases */
583 /* Get the scaled one value */
584 sone
= (1 << (mantissa_bits
));
586 /* The number may be unnormalised so renormalise it... */
590 smant
|= sone
; /* Insert the bit from mover into smant */
594 /* The binary point is now between bit positions 11 and 10 or 23 and 22,
595 i.e., between mantissa_bits - 1 and mantissa_bits - 2 and the
596 bit at mantissa_bits - 1 should be set. */
598 abort (); /* Ooops. */
600 if (flonum
.sign
== '+')
601 sfract
= smant
- sone
; /* smant - 1.0. */
604 /* This seems to work. */
612 sfract
= -smant
& (sone
-1); /* 2.0 - smant. */
614 sfract
|= sone
; /* Insert sign bit. */
617 if (abs (exponent
) >= (1 << (exponent_bits
- 1)))
618 as_bad ("Cannot represent exponent in %d bits", exponent_bits
);
620 /* Force exponent to fit in desired field width. */
621 exponent
&= (1 << (exponent_bits
)) - 1;
623 if (precision
== E_PRECISION
)
625 /* Map the float part first (100% equal format as F_PRECISION) */
626 words
[0] = exponent
<< (mantissa_bits
+1-24);
627 words
[0] |= sfract
>> 24;
628 words
[1] = sfract
>> 8;
630 /* Map the mantissa in the next */
631 words
[2] = sfract
>> 16;
632 words
[3] = sfract
& 0xffff;
636 /* Insert the exponent data into the word */
637 sfract
|= exponent
<< (mantissa_bits
+1);
639 if (precision
== S_PRECISION
)
643 words
[0] = sfract
>> 16;
644 words
[1] = sfract
& 0xffff;
651 /* Returns pointer past text consumed. */
653 tic4x_atof (str
, what_kind
, words
)
656 LITTLENUM_TYPE
*words
;
658 /* Extra bits for zeroed low-order bits. The 1st MAX_PRECISION are
659 zeroed, the last contain flonum bits. */
660 static LITTLENUM_TYPE bits
[MAX_PRECISION
+ MAX_PRECISION
+ GUARD
];
662 /* Number of 16-bit words in the format. */
664 FLONUM_TYPE save_gen_flonum
;
666 /* We have to save the generic_floating_point_number because it
667 contains storage allocation about the array of LITTLENUMs where
668 the value is actually stored. We will allocate our own array of
669 littlenums below, but have to restore the global one on exit. */
670 save_gen_flonum
= generic_floating_point_number
;
673 generic_floating_point_number
.low
= bits
+ MAX_PRECISION
;
674 generic_floating_point_number
.high
= NULL
;
675 generic_floating_point_number
.leader
= NULL
;
676 generic_floating_point_number
.exponent
= 0;
677 generic_floating_point_number
.sign
= '\0';
679 /* Use more LittleNums than seems necessary: the highest flonum may
680 have 15 leading 0 bits, so could be useless. */
682 memset (bits
, '\0', sizeof (LITTLENUM_TYPE
) * MAX_PRECISION
);
688 precision
= S_PRECISION
;
695 precision
= F_PRECISION
;
700 precision
= E_PRECISION
;
704 as_bad ("Invalid floating point number");
708 generic_floating_point_number
.high
709 = generic_floating_point_number
.low
+ precision
- 1 + GUARD
;
711 if (atof_generic (&return_value
, ".", EXP_CHARS
,
712 &generic_floating_point_number
))
714 as_bad ("Invalid floating point number");
718 tic4x_gen_to_words (generic_floating_point_number
,
721 /* Restore the generic_floating_point_number's storage alloc (and
723 generic_floating_point_number
= save_gen_flonum
;
729 tic4x_insert_reg (regname
, regnum
)
736 symbol_table_insert (symbol_new (regname
, reg_section
, (valueT
) regnum
,
737 &zero_address_frag
));
738 for (i
= 0; regname
[i
]; i
++)
739 buf
[i
] = islower (regname
[i
]) ? TOUPPER (regname
[i
]) : regname
[i
];
742 symbol_table_insert (symbol_new (buf
, reg_section
, (valueT
) regnum
,
743 &zero_address_frag
));
747 tic4x_insert_sym (symname
, value
)
753 symbolP
= symbol_new (symname
, absolute_section
,
754 (valueT
) value
, &zero_address_frag
);
755 SF_SET_LOCAL (symbolP
);
756 symbol_table_insert (symbolP
);
760 tic4x_expression (str
, exp
)
767 t
= input_line_pointer
; /* Save line pointer. */
768 input_line_pointer
= str
;
770 s
= input_line_pointer
;
771 input_line_pointer
= t
; /* Restore line pointer. */
772 return s
; /* Return pointer to where parsing stopped. */
776 tic4x_expression_abs (str
, value
)
783 t
= input_line_pointer
; /* Save line pointer. */
784 input_line_pointer
= str
;
785 *value
= get_absolute_expression ();
786 s
= input_line_pointer
;
787 input_line_pointer
= t
; /* Restore line pointer. */
792 tic4x_emit_char (c
,b
)
798 exp
.X_op
= O_constant
;
799 exp
.X_add_number
= c
;
804 tic4x_seg_alloc (name
, seg
, size
, symbolP
)
805 char *name ATTRIBUTE_UNUSED
;
806 segT seg ATTRIBUTE_UNUSED
;
810 /* Note that the size is in words
811 so we multiply it by 4 to get the number of bytes to allocate. */
813 /* If we have symbol: .usect ".fred", size etc.,
814 the symbol needs to point to the first location reserved
821 p
= frag_var (rs_fill
, 1, 1, (relax_substateT
) 0,
823 size
* OCTETS_PER_BYTE
, (char *) 0);
828 /* .asg ["]character-string["], symbol */
831 int x ATTRIBUTE_UNUSED
;
839 str
= input_line_pointer
;
841 /* Skip string expression. */
842 while (*input_line_pointer
!= ',' && *input_line_pointer
)
843 input_line_pointer
++;
844 if (*input_line_pointer
!= ',')
846 as_bad ("Comma expected\n");
849 *input_line_pointer
++ = '\0';
850 name
= input_line_pointer
;
851 c
= get_symbol_end (); /* Get terminator. */
852 tmp
= xmalloc (strlen (str
) + 1);
855 tmp
= xmalloc (strlen (name
) + 1);
858 if (hash_find (tic4x_asg_hash
, name
))
859 hash_replace (tic4x_asg_hash
, name
, (PTR
) str
);
861 hash_insert (tic4x_asg_hash
, name
, (PTR
) str
);
862 *input_line_pointer
= c
;
863 demand_empty_rest_of_line ();
866 /* .bss symbol, size */
869 int x ATTRIBUTE_UNUSED
;
876 subsegT current_subseg
;
879 current_seg
= now_seg
; /* Save current seg. */
880 current_subseg
= now_subseg
; /* Save current subseg. */
883 name
= input_line_pointer
;
884 c
= get_symbol_end (); /* Get terminator. */
887 as_bad (".bss size argument missing\n");
892 tic4x_expression_abs (++input_line_pointer
, &size
);
895 as_bad (".bss size %d < 0!", size
);
898 subseg_set (bss_section
, 0);
899 symbolP
= symbol_find_or_make (name
);
901 if (S_GET_SEGMENT (symbolP
) == bss_section
)
902 symbol_get_frag (symbolP
)->fr_symbol
= 0;
904 symbol_set_frag (symbolP
, frag_now
);
906 p
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
,
907 size
* OCTETS_PER_BYTE
, (char *) 0);
908 *p
= 0; /* Fill char. */
910 S_SET_SEGMENT (symbolP
, bss_section
);
912 /* The symbol may already have been created with a preceding
913 ".globl" directive -- be careful not to step on storage class
914 in that case. Otherwise, set it to static. */
915 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
916 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
918 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
919 demand_empty_rest_of_line ();
924 int ignore ATTRIBUTE_UNUSED
;
932 name
= input_line_pointer
;
933 c
= get_symbol_end ();
934 symbolP
= symbol_find_or_make (name
);
935 *input_line_pointer
= c
;
937 S_SET_STORAGE_CLASS (symbolP
, C_EXT
);
940 input_line_pointer
++;
942 if (*input_line_pointer
== '\n')
948 demand_empty_rest_of_line ();
951 /* Handle .byte, .word. .int, .long */
956 register unsigned int c
;
960 if (*input_line_pointer
== '"')
962 input_line_pointer
++;
963 while (is_a_char (c
= next_char_of_string ()))
964 tic4x_emit_char (c
, 4);
965 know (input_line_pointer
[-1] == '\"');
971 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
972 if (exp
.X_op
== O_constant
)
977 exp
.X_add_number
&= 255;
980 exp
.X_add_number
&= 65535;
984 /* Perhaps we should disallow .byte and .hword with
985 a non constant expression that will require relocation. */
989 while (*input_line_pointer
++ == ',');
991 input_line_pointer
--; /* Put terminator back into stream. */
992 demand_empty_rest_of_line ();
995 /* Handle .ascii, .asciz, .string */
997 tic4x_stringer (append_zero
)
998 int append_zero
; /*ex: bytes */
1001 register unsigned int c
;
1007 if (*input_line_pointer
== '"')
1009 input_line_pointer
++;
1010 while (is_a_char (c
= next_char_of_string ()))
1012 tic4x_emit_char (c
, 1);
1018 tic4x_emit_char (c
, 1);
1022 know (input_line_pointer
[-1] == '\"');
1028 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
1029 if (exp
.X_op
!= O_constant
)
1031 as_bad("Non-constant symbols not allowed\n");
1034 exp
.X_add_number
&= 255; /* Limit numeber to 8-bit */
1035 emit_expr (&exp
, 1);
1039 while (*input_line_pointer
++ == ',');
1041 /* Fill out the rest of the expression with 0's to fill up a full word */
1043 tic4x_emit_char (0, 4-(bytes
&0x3));
1045 input_line_pointer
--; /* Put terminator back into stream. */
1046 demand_empty_rest_of_line ();
1049 /* .eval expression, symbol */
1052 int x ATTRIBUTE_UNUSED
;
1059 input_line_pointer
=
1060 tic4x_expression_abs (input_line_pointer
, &value
);
1061 if (*input_line_pointer
++ != ',')
1063 as_bad ("Symbol missing\n");
1066 name
= input_line_pointer
;
1067 c
= get_symbol_end (); /* Get terminator. */
1068 demand_empty_rest_of_line ();
1069 tic4x_insert_sym (name
, value
);
1072 /* Reset local labels. */
1075 int x ATTRIBUTE_UNUSED
;
1077 dollar_label_clear ();
1080 /* .sect "section-name" [, value] */
1081 /* .sect ["]section-name[:subsection-name]["] [, value] */
1084 int x ATTRIBUTE_UNUSED
;
1088 char *subsection_name
;
1094 if (*input_line_pointer
== '"')
1095 input_line_pointer
++;
1096 section_name
= input_line_pointer
;
1097 c
= get_symbol_end (); /* Get terminator. */
1098 input_line_pointer
++; /* Skip null symbol terminator. */
1099 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1100 strcpy (name
, section_name
);
1102 /* TI C from version 5.0 allows a section name to contain a
1103 subsection name as well. The subsection name is separated by a
1104 ':' from the section name. Currently we scan the subsection
1105 name and discard it.
1106 Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>. */
1109 subsection_name
= input_line_pointer
;
1110 c
= get_symbol_end (); /* Get terminator. */
1111 input_line_pointer
++; /* Skip null symbol terminator. */
1112 as_warn (".sect: subsection name ignored");
1115 /* We might still have a '"' to discard, but the character after a
1116 symbol name will be overwritten with a \0 by get_symbol_end()
1120 input_line_pointer
=
1121 tic4x_expression_abs (input_line_pointer
, &num
);
1122 else if (*input_line_pointer
== ',')
1124 input_line_pointer
=
1125 tic4x_expression_abs (++input_line_pointer
, &num
);
1130 seg
= subseg_new (name
, num
);
1131 if (line_label
!= NULL
)
1133 S_SET_SEGMENT (line_label
, seg
);
1134 symbol_set_frag (line_label
, frag_now
);
1137 if (bfd_get_section_flags (stdoutput
, seg
) == SEC_NO_FLAGS
)
1139 if (!bfd_set_section_flags (stdoutput
, seg
, SEC_DATA
))
1140 as_warn ("Error setting flags for \"%s\": %s", name
,
1141 bfd_errmsg (bfd_get_error ()));
1144 /* If the last character overwritten by get_symbol_end() was an
1145 end-of-line, we must restore it or the end of the line will not be
1146 recognised and scanning extends into the next line, stopping with
1147 an error (blame Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>
1148 if this is not true). */
1149 if (is_end_of_line
[(unsigned char) c
])
1150 *(--input_line_pointer
) = c
;
1152 demand_empty_rest_of_line ();
1155 /* symbol[:] .set value or .set symbol, value */
1158 int x ATTRIBUTE_UNUSED
;
1163 if ((symbolP
= line_label
) == NULL
)
1168 name
= input_line_pointer
;
1169 c
= get_symbol_end (); /* Get terminator. */
1172 as_bad (".set syntax invalid\n");
1173 ignore_rest_of_line ();
1176 symbolP
= symbol_find_or_make (name
);
1179 symbol_table_insert (symbolP
);
1181 pseudo_set (symbolP
);
1182 demand_empty_rest_of_line ();
1185 /* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
1188 int x ATTRIBUTE_UNUSED
;
1194 int size
, alignment_flag
;
1196 subsegT current_subseg
;
1198 current_seg
= now_seg
; /* save current seg. */
1199 current_subseg
= now_subseg
; /* save current subseg. */
1202 if (*input_line_pointer
== '"')
1203 input_line_pointer
++;
1204 section_name
= input_line_pointer
;
1205 c
= get_symbol_end (); /* Get terminator. */
1206 input_line_pointer
++; /* Skip null symbol terminator. */
1207 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1208 strcpy (name
, section_name
);
1211 input_line_pointer
=
1212 tic4x_expression_abs (input_line_pointer
, &size
);
1213 else if (*input_line_pointer
== ',')
1215 input_line_pointer
=
1216 tic4x_expression_abs (++input_line_pointer
, &size
);
1221 /* Read a possibly present third argument (alignment flag) [VK]. */
1222 if (*input_line_pointer
== ',')
1224 input_line_pointer
=
1225 tic4x_expression_abs (++input_line_pointer
, &alignment_flag
);
1230 as_warn (".usect: non-zero alignment flag ignored");
1232 seg
= subseg_new (name
, 0);
1233 if (line_label
!= NULL
)
1235 S_SET_SEGMENT (line_label
, seg
);
1236 symbol_set_frag (line_label
, frag_now
);
1237 S_SET_VALUE (line_label
, frag_now_fix ());
1239 seg_info (seg
)->bss
= 1; /* Uninitialised data. */
1240 if (!bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
))
1241 as_warn ("Error setting flags for \"%s\": %s", name
,
1242 bfd_errmsg (bfd_get_error ()));
1243 tic4x_seg_alloc (name
, seg
, size
, line_label
);
1245 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1246 S_SET_STORAGE_CLASS (line_label
, C_STAT
);
1248 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
1249 demand_empty_rest_of_line ();
1252 /* .version cpu-version. */
1255 int x ATTRIBUTE_UNUSED
;
1259 input_line_pointer
=
1260 tic4x_expression_abs (input_line_pointer
, &temp
);
1261 if (!IS_CPU_TIC3X (temp
) && !IS_CPU_TIC4X (temp
))
1262 as_bad ("This assembler does not support processor generation %d",
1265 if (tic4x_cpu
&& temp
!= tic4x_cpu
)
1266 as_warn ("Changing processor generation on fly not supported...");
1268 demand_empty_rest_of_line ();
1272 tic4x_init_regtable ()
1276 for (i
= 0; i
< tic3x_num_registers
; i
++)
1277 tic4x_insert_reg (tic3x_registers
[i
].name
,
1278 tic3x_registers
[i
].regno
);
1280 if (IS_CPU_TIC4X (tic4x_cpu
))
1282 /* Add additional Tic4x registers, overriding some C3x ones. */
1283 for (i
= 0; i
< tic4x_num_registers
; i
++)
1284 tic4x_insert_reg (tic4x_registers
[i
].name
,
1285 tic4x_registers
[i
].regno
);
1290 tic4x_init_symbols ()
1292 /* The TI tools accept case insensitive versions of these symbols,
1297 .TMS320xx 30,31,32,40,or 44 set according to -v flag
1298 .C3X or .C3x 1 or 0 1 if -v30,-v31,or -v32
1299 .C30 1 or 0 1 if -v30
1300 .C31 1 or 0 1 if -v31
1301 .C32 1 or 0 1 if -v32
1302 .C4X or .C4x 1 or 0 1 if -v40, or -v44
1303 .C40 1 or 0 1 if -v40
1304 .C44 1 or 0 1 if -v44
1306 .REGPARM 1 or 0 1 if -mr option used
1307 .BIGMODEL 1 or 0 1 if -mb option used
1309 These symbols are currently supported but will be removed in a
1311 .TMS320C30 1 or 0 1 if -v30,-v31,or -v32
1312 .TMS320C31 1 or 0 1 if -v31
1313 .TMS320C32 1 or 0 1 if -v32
1314 .TMS320C40 1 or 0 1 if -v40, or -v44
1315 .TMS320C44 1 or 0 1 if -v44
1317 Source: TI: TMS320C3x/C4x Assembly Language Tools User's Guide,
1318 1997, SPRU035C, p. 3-17/3-18. */
1319 tic4x_insert_sym (".REGPARM", tic4x_reg_args
);
1320 tic4x_insert_sym (".MEMPARM", !tic4x_reg_args
);
1321 tic4x_insert_sym (".BIGMODEL", tic4x_big_model
);
1322 tic4x_insert_sym (".C30INTERRUPT", 0);
1323 tic4x_insert_sym (".TMS320xx", tic4x_cpu
== 0 ? 40 : tic4x_cpu
);
1324 tic4x_insert_sym (".C3X", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1325 tic4x_insert_sym (".C3x", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1326 tic4x_insert_sym (".C4X", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1327 tic4x_insert_sym (".C4x", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1328 /* Do we need to have the following symbols also in lower case? */
1329 tic4x_insert_sym (".TMS320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1330 tic4x_insert_sym (".tms320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1331 tic4x_insert_sym (".TMS320C31", tic4x_cpu
== 31);
1332 tic4x_insert_sym (".tms320C31", tic4x_cpu
== 31);
1333 tic4x_insert_sym (".TMS320C32", tic4x_cpu
== 32);
1334 tic4x_insert_sym (".tms320C32", tic4x_cpu
== 32);
1335 tic4x_insert_sym (".TMS320C33", tic4x_cpu
== 33);
1336 tic4x_insert_sym (".tms320C33", tic4x_cpu
== 33);
1337 tic4x_insert_sym (".TMS320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1338 tic4x_insert_sym (".tms320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1339 tic4x_insert_sym (".TMS320C44", tic4x_cpu
== 44);
1340 tic4x_insert_sym (".tms320C44", tic4x_cpu
== 44);
1341 tic4x_insert_sym (".TMX320C40", 0); /* C40 first pass silicon ? */
1342 tic4x_insert_sym (".tmx320C40", 0);
1345 /* Insert a new instruction template into hash table. */
1347 tic4x_inst_insert (inst
)
1350 static char prev_name
[16];
1351 const char *retval
= NULL
;
1353 /* Only insert the first name if have several similar entries. */
1354 if (!strcmp (inst
->name
, prev_name
) || inst
->name
[0] == '\0')
1357 retval
= hash_insert (tic4x_op_hash
, inst
->name
, (PTR
) inst
);
1359 fprintf (stderr
, "internal error: can't hash `%s': %s\n",
1360 inst
->name
, retval
);
1362 strcpy (prev_name
, inst
->name
);
1363 return retval
== NULL
;
1366 /* Make a new instruction template. */
1367 static tic4x_inst_t
*
1368 tic4x_inst_make (name
, opcode
, args
)
1370 unsigned long opcode
;
1373 static tic4x_inst_t
*insts
= NULL
;
1374 static char *names
= NULL
;
1375 static int index
= 0;
1379 /* Allocate memory to store name strings. */
1380 names
= (char *) xmalloc (sizeof (char) * 8192);
1381 /* Allocate memory for additional insts. */
1382 insts
= (tic4x_inst_t
*)
1383 xmalloc (sizeof (tic4x_inst_t
) * 1024);
1385 insts
[index
].name
= names
;
1386 insts
[index
].opcode
= opcode
;
1387 insts
[index
].opmask
= 0xffffffff;
1388 insts
[index
].args
= args
;
1396 return &insts
[index
- 1];
1399 /* Add instruction template, creating dynamic templates as required. */
1401 tic4x_inst_add (insts
)
1402 tic4x_inst_t
*insts
;
1404 char *s
= insts
->name
;
1412 /* We do not care about INSNs that is not a part of our
1414 if (!insts
->oplevel
& tic4x_oplevel
)
1423 /* Dynamically create all the conditional insts. */
1424 for (i
= 0; i
< tic4x_num_conds
; i
++)
1428 char *c
= tic4x_conds
[i
].name
;
1438 /* If instruction found then have already processed it. */
1439 if (hash_find (tic4x_op_hash
, name
))
1444 inst
= tic4x_inst_make (name
, insts
[k
].opcode
+
1445 (tic4x_conds
[i
].cond
<<
1446 (*s
== 'B' ? 16 : 23)),
1448 if (k
== 0) /* Save strcmp() with following func. */
1449 ok
&= tic4x_inst_insert (inst
);
1452 while (!strcmp (insts
->name
,
1459 return tic4x_inst_insert (insts
);
1469 /* This function is called once, at assembler startup time. It should
1470 set up all the tables, etc., that the MD part of the assembler will
1478 /* Setup the proper opcode level according to the
1479 commandline parameters */
1480 tic4x_oplevel
= OP_C3X
;
1482 if ( IS_CPU_TIC4X(tic4x_cpu
) )
1483 tic4x_oplevel
|= OP_C4X
;
1485 if ( ( tic4x_cpu
== 31 && tic4x_revision
>= 6)
1486 || (tic4x_cpu
== 32 && tic4x_revision
>= 2)
1487 || (tic4x_cpu
== 33)
1489 tic4x_oplevel
|= OP_ENH
;
1491 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1492 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1493 || (tic4x_cpu
== 32)
1495 tic4x_oplevel
|= OP_LPWR
;
1497 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1498 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1499 || (tic4x_cpu
== 32)
1500 || (tic4x_cpu
== 33)
1501 || (tic4x_cpu
== 40 && tic4x_revision
>= 5)
1502 || (tic4x_cpu
== 44)
1504 tic4x_oplevel
|= OP_IDLE2
;
1506 /* Create hash table for mnemonics. */
1507 tic4x_op_hash
= hash_new ();
1509 /* Create hash table for asg pseudo. */
1510 tic4x_asg_hash
= hash_new ();
1512 /* Add mnemonics to hash table, expanding conditional mnemonics on fly. */
1513 for (i
= 0; i
< tic4x_num_insts
; i
++)
1514 ok
&= tic4x_inst_add ((void *) &tic4x_insts
[i
]);
1516 /* Create dummy inst to avoid errors accessing end of table. */
1517 tic4x_inst_make ("", 0, "");
1520 as_fatal ("Broken assembler. No assembly attempted.");
1522 /* Add registers to symbol table. */
1523 tic4x_init_regtable ();
1525 /* Add predefined symbols to symbol table. */
1526 tic4x_init_symbols ();
1532 bfd_set_arch_mach (stdoutput
, bfd_arch_tic4x
,
1533 IS_CPU_TIC4X (tic4x_cpu
) ? bfd_mach_tic4x
: bfd_mach_tic3x
);
1537 tic4x_indirect_parse (operand
, indirect
)
1538 tic4x_operand_t
*operand
;
1539 const tic4x_indirect_t
*indirect
;
1541 char *n
= indirect
->name
;
1542 char *s
= input_line_pointer
;
1552 case 'a': /* Need to match aux register. */
1554 #ifdef TIC4X_ALT_SYNTAX
1558 while (ISALNUM (*s
))
1561 if (!(symbolP
= symbol_find (name
)))
1564 if (S_GET_SEGMENT (symbolP
) != reg_section
)
1567 operand
->aregno
= S_GET_VALUE (symbolP
);
1568 if (operand
->aregno
>= REG_AR0
&& operand
->aregno
<= REG_AR7
)
1571 as_bad ("Auxiliary register AR0--AR7 required for indirect");
1574 case 'd': /* Need to match constant for disp. */
1575 #ifdef TIC4X_ALT_SYNTAX
1576 if (*s
== '%') /* expr() will die if we don't skip this. */
1579 s
= tic4x_expression (s
, &operand
->expr
);
1580 if (operand
->expr
.X_op
!= O_constant
)
1582 operand
->disp
= operand
->expr
.X_add_number
;
1583 if (operand
->disp
< 0 || operand
->disp
> 255)
1585 as_bad ("Bad displacement %d (require 0--255)\n",
1591 case 'y': /* Need to match IR0. */
1592 case 'z': /* Need to match IR1. */
1593 #ifdef TIC4X_ALT_SYNTAX
1597 s
= tic4x_expression (s
, &operand
->expr
);
1598 if (operand
->expr
.X_op
!= O_register
)
1600 if (operand
->expr
.X_add_number
!= REG_IR0
1601 && operand
->expr
.X_add_number
!= REG_IR1
)
1603 as_bad ("Index register IR0,IR1 required for displacement");
1607 if (*n
== 'y' && operand
->expr
.X_add_number
== REG_IR0
)
1609 if (*n
== 'z' && operand
->expr
.X_add_number
== REG_IR1
)
1614 if (*s
!= '(') /* No displacement, assume to be 1. */
1625 if (TOLOWER (*s
) != *n
)
1630 if (*s
!= ' ' && *s
!= ',' && *s
!= '\0')
1632 input_line_pointer
= s
;
1637 tic4x_operand_parse (s
, operand
)
1639 tic4x_operand_t
*operand
;
1644 expressionS
*exp
= &operand
->expr
;
1645 char *save
= input_line_pointer
;
1648 struct hash_entry
*entry
= NULL
;
1650 input_line_pointer
= s
;
1653 str
= input_line_pointer
;
1654 c
= get_symbol_end (); /* Get terminator. */
1655 new = input_line_pointer
;
1656 if (strlen (str
) && (entry
= hash_find (tic4x_asg_hash
, str
)) != NULL
)
1658 *input_line_pointer
= c
;
1659 input_line_pointer
= (char *) entry
;
1663 *input_line_pointer
= c
;
1664 input_line_pointer
= str
;
1667 operand
->mode
= M_UNKNOWN
;
1668 switch (*input_line_pointer
)
1670 #ifdef TIC4X_ALT_SYNTAX
1672 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1673 if (exp
->X_op
!= O_register
)
1674 as_bad ("Expecting a register name");
1675 operand
->mode
= M_REGISTER
;
1679 /* Denotes high 16 bits. */
1680 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1681 if (exp
->X_op
== O_constant
)
1682 operand
->mode
= M_IMMED
;
1683 else if (exp
->X_op
== O_big
)
1685 if (exp
->X_add_number
)
1686 as_bad ("Number too large"); /* bignum required */
1689 tic4x_gen_to_words (generic_floating_point_number
,
1690 operand
->fwords
, S_PRECISION
);
1691 operand
->mode
= M_IMMED_F
;
1694 /* Allow ori ^foo, ar0 to be equivalent to ldi .hi.foo, ar0 */
1695 /* WARNING : The TI C40 assembler cannot do this. */
1696 else if (exp
->X_op
== O_symbol
)
1698 operand
->mode
= M_HI
;
1703 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1704 if (exp
->X_op
== O_constant
)
1705 operand
->mode
= M_IMMED
;
1706 else if (exp
->X_op
== O_big
)
1708 if (exp
->X_add_number
> 0)
1709 as_bad ("Number too large"); /* bignum required. */
1712 tic4x_gen_to_words (generic_floating_point_number
,
1713 operand
->fwords
, S_PRECISION
);
1714 operand
->mode
= M_IMMED_F
;
1717 /* Allow ori foo, ar0 to be equivalent to ldi .lo.foo, ar0 */
1718 /* WARNING : The TI C40 assembler cannot do this. */
1719 else if (exp
->X_op
== O_symbol
)
1721 operand
->mode
= M_IMMED
;
1726 as_bad ("Expecting a constant value");
1731 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1732 if (exp
->X_op
!= O_constant
&& exp
->X_op
!= O_symbol
)
1733 as_bad ("Bad direct addressing construct %s", s
);
1734 if (exp
->X_op
== O_constant
)
1736 if (exp
->X_add_number
< 0)
1737 as_bad ("Direct value of %ld is not suitable",
1738 (long) exp
->X_add_number
);
1740 operand
->mode
= M_DIRECT
;
1745 for (i
= 0; i
< tic4x_num_indirects
; i
++)
1746 if ((ret
= tic4x_indirect_parse (operand
, &tic4x_indirects
[i
])))
1750 if (i
< tic4x_num_indirects
)
1752 operand
->mode
= M_INDIRECT
;
1753 /* Indirect addressing mode number. */
1754 operand
->expr
.X_add_number
= tic4x_indirects
[i
].modn
;
1755 /* Convert *+ARn(0) to *ARn etc. Maybe we should
1756 squeal about silly ones? */
1757 if (operand
->expr
.X_add_number
< 0x08 && !operand
->disp
)
1758 operand
->expr
.X_add_number
= 0x18;
1761 as_bad ("Unknown indirect addressing mode");
1765 operand
->mode
= M_IMMED
; /* Assume immediate. */
1766 str
= input_line_pointer
;
1767 input_line_pointer
= tic4x_expression (input_line_pointer
, exp
);
1768 if (exp
->X_op
== O_register
)
1770 know (exp
->X_add_symbol
== 0);
1771 know (exp
->X_op_symbol
== 0);
1772 operand
->mode
= M_REGISTER
;
1775 else if (exp
->X_op
== O_big
)
1777 if (exp
->X_add_number
> 0)
1778 as_bad ("Number too large"); /* bignum required. */
1781 tic4x_gen_to_words (generic_floating_point_number
,
1782 operand
->fwords
, S_PRECISION
);
1783 operand
->mode
= M_IMMED_F
;
1787 #ifdef TIC4X_ALT_SYNTAX
1788 /* Allow ldi foo, ar0 to be equivalent to ldi @foo, ar0. */
1789 else if (exp
->X_op
== O_symbol
)
1791 operand
->mode
= M_DIRECT
;
1797 new = input_line_pointer
;
1798 input_line_pointer
= save
;
1803 tic4x_operands_match (inst
, insn
, check
)
1808 const char *args
= inst
->args
;
1809 unsigned long opcode
= inst
->opcode
;
1810 int num_operands
= insn
->num_operands
;
1811 tic4x_operand_t
*operand
= insn
->operands
;
1812 expressionS
*exp
= &operand
->expr
;
1816 /* Build the opcode, checking as we go to make sure that the
1819 If an operand matches, we modify insn or opcode appropriately,
1820 and do a "continue". If an operand fails to match, we "break". */
1822 insn
->nchars
= 4; /* Instructions always 4 bytes. */
1823 insn
->reloc
= NO_RELOC
;
1828 insn
->opcode
= opcode
;
1829 return num_operands
== 0;
1837 case '\0': /* End of args. */
1838 if (num_operands
== 1)
1840 insn
->opcode
= opcode
;
1843 break; /* Too many operands. */
1845 case '#': /* This is only used for ldp. */
1846 if (operand
->mode
!= M_DIRECT
&& operand
->mode
!= M_IMMED
)
1848 /* While this looks like a direct addressing mode, we actually
1849 use an immediate mode form of ldiu or ldpk instruction. */
1850 if (exp
->X_op
== O_constant
)
1852 if( ( IS_CPU_TIC4X (tic4x_cpu
) && exp
->X_add_number
<= 65535 )
1853 || ( IS_CPU_TIC3X (tic4x_cpu
) && exp
->X_add_number
<= 255 ) )
1855 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1861 as_bad ("Immediate value of %ld is too large for ldf",
1862 (long) exp
->X_add_number
);
1867 else if (exp
->X_op
== O_symbol
)
1869 insn
->reloc
= BFD_RELOC_HI16
;
1873 break; /* Not direct (dp) addressing. */
1875 case '@': /* direct. */
1876 if (operand
->mode
!= M_DIRECT
)
1878 if (exp
->X_op
== O_constant
)
1880 /* Store only the 16 LSBs of the number. */
1881 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1884 else if (exp
->X_op
== O_symbol
)
1886 insn
->reloc
= BFD_RELOC_LO16
;
1890 break; /* Not direct addressing. */
1893 if (operand
->mode
!= M_REGISTER
)
1895 reg
= exp
->X_add_number
;
1896 if (reg
>= REG_AR0
&& reg
<= REG_AR7
)
1897 INSERTU (opcode
, reg
- REG_AR0
, 24, 22);
1901 as_bad ("Destination register must be ARn");
1906 case 'B': /* Unsigned integer immediate. */
1907 /* Allow br label or br @label. */
1908 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
1910 if (exp
->X_op
== O_constant
)
1912 if (exp
->X_add_number
< (1 << 24))
1914 INSERTU (opcode
, exp
->X_add_number
, 23, 0);
1920 as_bad ("Immediate value of %ld is too large",
1921 (long) exp
->X_add_number
);
1926 if (IS_CPU_TIC4X (tic4x_cpu
))
1928 insn
->reloc
= BFD_RELOC_24_PCREL
;
1933 insn
->reloc
= BFD_RELOC_24
;
1940 if (!IS_CPU_TIC4X (tic4x_cpu
))
1942 if (operand
->mode
!= M_INDIRECT
)
1944 /* Require either *+ARn(disp) or *ARn. */
1945 if (operand
->expr
.X_add_number
!= 0
1946 && operand
->expr
.X_add_number
!= 0x18)
1949 as_bad ("Invalid indirect addressing mode");
1953 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1954 INSERTU (opcode
, operand
->disp
, 7, 3);
1958 if (!(operand
->mode
== M_REGISTER
))
1960 INSERTU (opcode
, exp
->X_add_number
, 7, 0);
1964 if (!(operand
->mode
== M_REGISTER
))
1966 reg
= exp
->X_add_number
;
1967 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1968 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1969 INSERTU (opcode
, reg
, 7, 0);
1973 as_bad ("Register must be Rn");
1979 if (operand
->mode
!= M_IMMED_F
1980 && !(operand
->mode
== M_IMMED
&& exp
->X_op
== O_constant
))
1983 if (operand
->mode
!= M_IMMED_F
)
1985 /* OK, we 've got something like cmpf 0, r0
1986 Why can't they stick in a bloody decimal point ?! */
1989 /* Create floating point number string. */
1990 sprintf (string
, "%d.0", (int) exp
->X_add_number
);
1991 tic4x_atof (string
, 's', operand
->fwords
);
1994 INSERTU (opcode
, operand
->fwords
[0], 15, 0);
1998 if (operand
->mode
!= M_REGISTER
)
2000 INSERTU (opcode
, exp
->X_add_number
, 15, 8);
2004 if (operand
->mode
!= M_REGISTER
)
2006 reg
= exp
->X_add_number
;
2007 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2008 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2009 INSERTU (opcode
, reg
, 15, 8);
2013 as_bad ("Register must be Rn");
2019 if (operand
->mode
!= M_REGISTER
)
2021 reg
= exp
->X_add_number
;
2022 if (reg
>= REG_R0
&& reg
<= REG_R7
)
2023 INSERTU (opcode
, reg
- REG_R0
, 18, 16);
2027 as_bad ("Register must be R0--R7");
2033 if ( operand
->mode
== M_REGISTER
2034 && tic4x_oplevel
& OP_ENH
)
2036 reg
= exp
->X_add_number
;
2037 INSERTU (opcode
, reg
, 4, 0);
2038 INSERTU (opcode
, 7, 7, 5);
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
, 2, 0);
2057 INSERTU (opcode
, operand
->expr
.X_add_number
, 7, 3);
2061 if ( operand
->mode
== M_REGISTER
2062 && tic4x_oplevel
& OP_ENH
)
2064 reg
= exp
->X_add_number
;
2065 INSERTU (opcode
, reg
, 12, 8);
2066 INSERTU (opcode
, 7, 15, 13);
2072 if (operand
->mode
!= M_INDIRECT
)
2074 if (operand
->disp
!= 0 && operand
->disp
!= 1)
2076 if (IS_CPU_TIC4X (tic4x_cpu
))
2079 as_bad ("Invalid indirect addressing mode displacement %d",
2084 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2085 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
2089 if (operand
->mode
!= M_REGISTER
)
2091 reg
= exp
->X_add_number
;
2092 if (reg
>= REG_R0
&& reg
<= REG_R7
)
2093 INSERTU (opcode
, reg
- REG_R0
, 21, 19);
2097 as_bad ("Register must be R0--R7");
2103 if (operand
->mode
!= M_REGISTER
)
2105 reg
= exp
->X_add_number
;
2106 if (reg
>= REG_R0
&& reg
<= REG_R7
)
2107 INSERTU (opcode
, reg
- REG_R0
, 24, 22);
2111 as_bad ("Register must be R0--R7");
2117 if (operand
->mode
!= M_REGISTER
)
2119 reg
= exp
->X_add_number
;
2120 if (reg
== REG_R2
|| reg
== REG_R3
)
2121 INSERTU (opcode
, reg
- REG_R2
, 22, 22);
2125 as_bad ("Destination register must be R2 or R3");
2131 if (operand
->mode
!= M_REGISTER
)
2133 reg
= exp
->X_add_number
;
2134 if (reg
== REG_R0
|| reg
== REG_R1
)
2135 INSERTU (opcode
, reg
- REG_R0
, 23, 23);
2139 as_bad ("Destination register must be R0 or R1");
2145 if (!IS_CPU_TIC4X (tic4x_cpu
))
2147 if (operand
->mode
!= M_INDIRECT
)
2149 /* Require either *+ARn(disp) or *ARn. */
2150 if (operand
->expr
.X_add_number
!= 0
2151 && operand
->expr
.X_add_number
!= 0x18)
2154 as_bad ("Invalid indirect addressing mode");
2158 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2159 INSERTU (opcode
, operand
->disp
, 15, 11);
2162 case 'P': /* PC relative displacement. */
2163 /* Allow br label or br @label. */
2164 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
2166 if (exp
->X_op
== O_constant
)
2168 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 32767)
2170 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2176 as_bad ("Displacement value of %ld is too large",
2177 (long) exp
->X_add_number
);
2182 insn
->reloc
= BFD_RELOC_16_PCREL
;
2188 if (operand
->mode
!= M_REGISTER
)
2190 reg
= exp
->X_add_number
;
2191 INSERTU (opcode
, reg
, 15, 0);
2195 if (operand
->mode
!= M_REGISTER
)
2197 reg
= exp
->X_add_number
;
2198 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2199 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2200 INSERTU (opcode
, reg
, 15, 0);
2204 as_bad ("Register must be Rn");
2210 if (operand
->mode
!= M_REGISTER
)
2212 reg
= exp
->X_add_number
;
2213 INSERTU (opcode
, reg
, 20, 16);
2217 if (operand
->mode
!= M_REGISTER
)
2219 reg
= exp
->X_add_number
;
2220 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2221 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2222 INSERTU (opcode
, reg
, 20, 16);
2226 as_bad ("Register must be Rn");
2231 case 'S': /* Short immediate int. */
2232 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2234 if (exp
->X_op
== O_big
)
2237 as_bad ("Floating point number not valid in expression");
2241 if (exp
->X_op
== O_constant
)
2243 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 65535)
2245 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2251 as_bad ("Signed immediate value %ld too large",
2252 (long) exp
->X_add_number
);
2257 else if (exp
->X_op
== O_symbol
)
2259 if (operand
->mode
== M_HI
)
2261 insn
->reloc
= BFD_RELOC_HI16
;
2265 insn
->reloc
= BFD_RELOC_LO16
;
2270 /* Handle cases like ldi foo - $, ar0 where foo
2271 is a forward reference. Perhaps we should check
2272 for X_op == O_symbol and disallow things like
2274 insn
->reloc
= BFD_RELOC_16
;
2278 case 'T': /* 5-bit immediate value for tic4x stik. */
2279 if (!IS_CPU_TIC4X (tic4x_cpu
))
2281 if (operand
->mode
!= M_IMMED
)
2283 if (exp
->X_op
== O_constant
)
2285 if (exp
->X_add_number
< 16 && exp
->X_add_number
>= -16)
2287 INSERTS (opcode
, exp
->X_add_number
, 20, 16);
2293 as_bad ("Immediate value of %ld is too large",
2294 (long) exp
->X_add_number
);
2299 break; /* No relocations allowed. */
2301 case 'U': /* Unsigned integer immediate. */
2302 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2304 if (exp
->X_op
== O_constant
)
2306 if (exp
->X_add_number
< (1 << 16) && exp
->X_add_number
>= 0)
2308 INSERTU (opcode
, exp
->X_add_number
, 15, 0);
2314 as_bad ("Unsigned immediate value %ld too large",
2315 (long) exp
->X_add_number
);
2320 else if (exp
->X_op
== O_symbol
)
2322 if (operand
->mode
== M_HI
)
2323 insn
->reloc
= BFD_RELOC_HI16
;
2325 insn
->reloc
= BFD_RELOC_LO16
;
2330 insn
->reloc
= BFD_RELOC_16
;
2334 case 'V': /* Trap numbers (immediate field). */
2335 if (operand
->mode
!= M_IMMED
)
2337 if (exp
->X_op
== O_constant
)
2339 if (exp
->X_add_number
< 512 && IS_CPU_TIC4X (tic4x_cpu
))
2341 INSERTU (opcode
, exp
->X_add_number
, 8, 0);
2344 else if (exp
->X_add_number
< 32 && IS_CPU_TIC3X (tic4x_cpu
))
2346 INSERTU (opcode
, exp
->X_add_number
| 0x20, 4, 0);
2352 as_bad ("Immediate value of %ld is too large",
2353 (long) exp
->X_add_number
);
2358 break; /* No relocations allowed. */
2360 case 'W': /* Short immediate int (0--7). */
2361 if (!IS_CPU_TIC4X (tic4x_cpu
))
2363 if (operand
->mode
!= M_IMMED
)
2365 if (exp
->X_op
== O_big
)
2368 as_bad ("Floating point number not valid in expression");
2372 if (exp
->X_op
== O_constant
)
2374 if (exp
->X_add_number
>= -256 && exp
->X_add_number
<= 127)
2376 INSERTS (opcode
, exp
->X_add_number
, 7, 0);
2382 as_bad ("Immediate value %ld too large",
2383 (long) exp
->X_add_number
);
2388 insn
->reloc
= BFD_RELOC_16
;
2392 case 'X': /* 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
, 4, 0);
2401 as_bad ("Register must be ivtp or tvtp");
2406 case 'Y': /* Address register for tic4x lda. */
2407 if (operand
->mode
!= M_REGISTER
)
2409 reg
= exp
->X_add_number
;
2410 if (reg
>= REG_AR0
&& reg
<= REG_SP
)
2411 INSERTU (opcode
, reg
, 20, 16);
2415 as_bad ("Register must be address register");
2420 case 'Z': /* Expansion register for tic4x. */
2421 if (operand
->mode
!= M_REGISTER
)
2423 reg
= exp
->X_add_number
;
2424 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2425 INSERTU (opcode
, reg
- REG_IVTP
, 20, 16);
2429 as_bad ("Register must be ivtp or tvtp");
2435 if (operand
->mode
!= M_INDIRECT
)
2437 INSERTS (opcode
, operand
->disp
, 7, 0);
2438 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2439 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
2442 case '|': /* treat as `,' if have ldi_ldi form. */
2445 if (--num_operands
< 0)
2446 break; /* Too few operands. */
2448 if (operand
->mode
!= M_PARALLEL
)
2453 case ',': /* Another operand. */
2454 if (--num_operands
< 0)
2455 break; /* Too few operands. */
2457 exp
= &operand
->expr
;
2460 case ';': /* Another optional operand. */
2461 if (num_operands
== 1 || operand
[1].mode
== M_PARALLEL
)
2463 if (--num_operands
< 0)
2464 break; /* Too few operands. */
2466 exp
= &operand
->expr
;
2477 tic4x_insn_check (insn
)
2481 if (!strcmp(insn
->name
, "lda"))
2483 if (insn
->num_operands
< 2 || insn
->num_operands
> 2)
2484 as_fatal ("Illegal internal LDA insn definition");
2486 if ( insn
->operands
[0].mode
== M_REGISTER
2487 && insn
->operands
[1].mode
== M_REGISTER
2488 && insn
->operands
[0].expr
.X_add_number
== insn
->operands
[1].expr
.X_add_number
)
2489 as_bad ("Source and destination register should not be equal");
2491 else if( !strcmp(insn
->name
, "ldi_ldi")
2492 || !strcmp(insn
->name
, "ldi1_ldi2")
2493 || !strcmp(insn
->name
, "ldi2_ldi1")
2494 || !strcmp(insn
->name
, "ldf_ldf")
2495 || !strcmp(insn
->name
, "ldf1_ldf2")
2496 || !strcmp(insn
->name
, "ldf2_ldf1") )
2498 if ( insn
->num_operands
< 4 && insn
->num_operands
> 5 )
2499 as_fatal ("Illegal internal %s insn definition", insn
->name
);
2501 if ( insn
->operands
[1].mode
== M_REGISTER
2502 && insn
->operands
[insn
->num_operands
-1].mode
== M_REGISTER
2503 && insn
->operands
[1].expr
.X_add_number
== insn
->operands
[insn
->num_operands
-1].expr
.X_add_number
)
2504 as_warn ("Equal parallell destination registers, one result will be discarded");
2509 tic4x_insn_output (insn
)
2514 /* Grab another fragment for opcode. */
2515 dst
= frag_more (insn
->nchars
);
2517 /* Put out opcode word as a series of bytes in little endian order. */
2518 md_number_to_chars (dst
, insn
->opcode
, insn
->nchars
);
2520 /* Put out the symbol-dependent stuff. */
2521 if (insn
->reloc
!= NO_RELOC
)
2523 /* Where is the offset into the fragment for this instruction. */
2524 fix_new_exp (frag_now
,
2525 dst
- frag_now
->fr_literal
, /* where */
2526 insn
->nchars
, /* size */
2533 /* Parse the operands. */
2535 tic4x_operands_parse (s
, operands
, num_operands
)
2537 tic4x_operand_t
*operands
;
2541 return num_operands
;
2544 s
= tic4x_operand_parse (s
, &operands
[num_operands
++]);
2545 while (num_operands
< TIC4X_OPERANDS_MAX
&& *s
++ == ',');
2547 if (num_operands
> TIC4X_OPERANDS_MAX
)
2549 as_bad ("Too many operands scanned");
2552 return num_operands
;
2555 /* Assemble a single instruction. Its label has already been handled
2556 by the generic front end. We just parse mnemonic and operands, and
2557 produce the bytes of data and relocation. */
2566 tic4x_inst_t
*inst
; /* Instruction template. */
2567 tic4x_inst_t
*first_inst
;
2569 /* Scan for parallel operators */
2573 while (*s
&& *s
!= '|')
2576 if (*s
&& s
[1]=='|')
2580 as_bad ("Parallel opcode cannot contain more than two instructions");
2586 /* Lets take care of the first part of the parallel insn */
2591 /* .. and let the second run though here */
2595 if (str
&& insn
->parallel
)
2597 /* Find mnemonic (second part of parallel instruction). */
2599 /* Skip past instruction mnemonic. */
2600 while (*s
&& *s
!= ' ')
2602 if (*s
) /* Null terminate for hash_find. */
2603 *s
++ = '\0'; /* and skip past null. */
2604 strcat (insn
->name
, "_");
2605 strncat (insn
->name
, str
, TIC4X_NAME_MAX
- strlen (insn
->name
));
2607 insn
->operands
[insn
->num_operands
++].mode
= M_PARALLEL
;
2609 if ((i
= tic4x_operands_parse
2610 (s
, insn
->operands
, insn
->num_operands
)) < 0)
2616 insn
->num_operands
= i
;
2622 if ((insn
->inst
= (struct tic4x_inst
*)
2623 hash_find (tic4x_op_hash
, insn
->name
)) == NULL
)
2625 as_bad ("Unknown opcode `%s'.", insn
->name
);
2635 ok
= tic4x_operands_match (inst
, insn
, 1);
2642 } while (!ok
&& !strcmp (inst
->name
, inst
[1].name
) && inst
++);
2646 tic4x_insn_check (insn
);
2647 tic4x_insn_output (insn
);
2652 tic4x_operands_match (first_inst
, insn
, 0);
2653 as_bad ("Invalid operands for %s", insn
->name
);
2656 as_bad ("Invalid instruction %s", insn
->name
);
2661 /* Find mnemonic. */
2663 while (*s
&& *s
!= ' ') /* Skip past instruction mnemonic. */
2665 if (*s
) /* Null terminate for hash_find. */
2666 *s
++ = '\0'; /* and skip past null. */
2667 strncpy (insn
->name
, str
, TIC4X_NAME_MAX
- 3);
2669 if ((i
= tic4x_operands_parse (s
, insn
->operands
, 0)) < 0)
2671 insn
->inst
= NULL
; /* Flag that error occured. */
2676 insn
->num_operands
= i
;
2691 /* Turn a string in input_line_pointer into a floating point constant
2692 of type type, and store the appropriate bytes in *litP. The number
2693 of LITTLENUMS emitted is stored in *sizeP. An error message is
2694 returned, or NULL on OK. */
2697 md_atof (type
, litP
, sizeP
)
2704 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2705 LITTLENUM_TYPE
*wordP
;
2710 case 's': /* .single */
2716 case 'd': /* .double */
2718 case 'f': /* .float or .single */
2721 prec
= 2; /* 1 32-bit word */
2724 case 'i': /* .ieee */
2728 type
= 'f'; /* Rewrite type to be usable by atof_ieee() */
2731 case 'e': /* .ldouble */
2733 prec
= 4; /* 2 32-bit words */
2739 return "Bad call to md_atof()";
2743 t
= atof_ieee (input_line_pointer
, type
, words
);
2745 t
= tic4x_atof (input_line_pointer
, type
, words
);
2747 input_line_pointer
= t
;
2748 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
2750 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
2751 little endian byte order. */
2752 /* SES: However it is required to put the words (32-bits) out in the
2753 correct order, hence we write 2 and 2 littlenums in little endian
2754 order, while we keep the original order on successive words. */
2755 for(wordP
= words
; wordP
<(words
+prec
) ; wordP
+=2)
2757 if (wordP
<(words
+prec
-1)) /* Dump wordP[1] (if we have one) */
2759 md_number_to_chars (litP
, (valueT
) (wordP
[1]),
2760 sizeof (LITTLENUM_TYPE
));
2761 litP
+= sizeof (LITTLENUM_TYPE
);
2765 md_number_to_chars (litP
, (valueT
) (wordP
[0]),
2766 sizeof (LITTLENUM_TYPE
));
2767 litP
+= sizeof (LITTLENUM_TYPE
);
2773 md_apply_fix3 (fixP
, value
, seg
)
2776 segT seg ATTRIBUTE_UNUSED
;
2778 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
2779 valueT val
= *value
;
2781 switch (fixP
->fx_r_type
)
2783 case BFD_RELOC_HI16
:
2787 case BFD_RELOC_LO16
:
2794 switch (fixP
->fx_r_type
)
2799 case BFD_RELOC_24_PCREL
:
2802 case BFD_RELOC_16_PCREL
:
2803 case BFD_RELOC_LO16
:
2804 case BFD_RELOC_HI16
:
2811 as_bad ("Bad relocation type: 0x%02x", fixP
->fx_r_type
);
2815 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0) fixP
->fx_done
= 1;
2818 /* Should never be called for tic4x. */
2820 md_convert_frag (headers
, sec
, fragP
)
2821 bfd
*headers ATTRIBUTE_UNUSED
;
2822 segT sec ATTRIBUTE_UNUSED
;
2823 fragS
*fragP ATTRIBUTE_UNUSED
;
2825 as_fatal ("md_convert_frag");
2828 /* Should never be called for tic4x. */
2830 md_create_short_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
2831 char *ptr ATTRIBUTE_UNUSED
;
2832 addressT from_addr ATTRIBUTE_UNUSED
;
2833 addressT to_addr ATTRIBUTE_UNUSED
;
2834 fragS
*frag ATTRIBUTE_UNUSED
;
2835 symbolS
*to_symbol ATTRIBUTE_UNUSED
;
2837 as_fatal ("md_create_short_jmp\n");
2840 /* Should never be called for tic4x. */
2842 md_create_long_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
2843 char *ptr ATTRIBUTE_UNUSED
;
2844 addressT from_addr ATTRIBUTE_UNUSED
;
2845 addressT to_addr ATTRIBUTE_UNUSED
;
2846 fragS
*frag ATTRIBUTE_UNUSED
;
2847 symbolS
*to_symbol ATTRIBUTE_UNUSED
;
2849 as_fatal ("md_create_long_jump\n");
2852 /* Should never be called for tic4x. */
2854 md_estimate_size_before_relax (fragP
, segtype
)
2855 register fragS
*fragP ATTRIBUTE_UNUSED
;
2856 segT segtype ATTRIBUTE_UNUSED
;
2858 as_fatal ("md_estimate_size_before_relax\n");
2864 md_parse_option (c
, arg
)
2870 case OPTION_CPU
: /* cpu brand */
2871 if (TOLOWER (*arg
) == 'c')
2873 tic4x_cpu
= atoi (arg
);
2874 if (!IS_CPU_TIC3X (tic4x_cpu
) && !IS_CPU_TIC4X (tic4x_cpu
))
2875 as_warn ("Unsupported processor generation %d", tic4x_cpu
);
2878 case OPTION_REV
: /* cpu revision */
2879 tic4x_revision
= atoi (arg
);
2883 as_warn ("Option -b is depreciated, please use -mbig");
2884 case OPTION_BIG
: /* big model */
2885 tic4x_big_model
= 1;
2889 as_warn ("Option -p is depreciated, please use -mmemparm");
2890 case OPTION_MEMPARM
: /* push args */
2895 as_warn ("Option -r is depreciated, please use -mregparm");
2896 case OPTION_REGPARM
: /* register args */
2901 as_warn ("Option -s is depreciated, please use -msmall");
2902 case OPTION_SMALL
: /* small model */
2903 tic4x_big_model
= 0;
2910 case OPTION_LOWPOWER
:
2914 case OPTION_ENHANCED
:
2926 md_show_usage (stream
)
2930 _("\nTIC4X options:\n"
2931 " -mcpu=CPU -mCPU select architecture variant. CPU can be:\n"
2933 " 31 - TMS320C31, TMS320LC31\n"
2935 " 33 - TMS320VC33\n"
2938 " -mrev=REV set cpu hardware revision (integer numbers).\n"
2939 " Combinations of -mcpu and -mrev will enable/disable\n"
2940 " the appropriate options (-midle2, -mlowpower and\n"
2941 " -menhanced) according to the selected type\n"
2942 " -mbig select big memory model\n"
2943 " -msmall select small memory model (default)\n"
2944 " -mregparm select register parameters (default)\n"
2945 " -mmemparm select memory parameters\n"
2946 " -midle2 enable IDLE2 support\n"
2947 " -mlowpower enable LOPOWER and MAXSPEED support\n"
2948 " -menhanced enable enhanced opcode support\n"));
2951 /* This is called when a line is unrecognized. This is used to handle
2952 definitions of TI C3x tools style local labels $n where n is a single
2955 tic4x_unrecognized_line (c
)
2961 if (c
!= '$' || ! ISDIGIT (input_line_pointer
[0]))
2964 s
= input_line_pointer
;
2966 /* Let's allow multiple digit local labels. */
2968 while (ISDIGIT (*s
))
2970 lab
= lab
* 10 + *s
- '0';
2974 if (dollar_label_defined (lab
))
2976 as_bad ("Label \"$%d\" redefined", lab
);
2980 define_dollar_label (lab
);
2981 colon (dollar_label_name (lab
, 0));
2982 input_line_pointer
= s
+ 1;
2987 /* Handle local labels peculiar to us referred to in an expression. */
2989 md_undefined_symbol (name
)
2992 /* Look for local labels of the form $n. */
2993 if (name
[0] == '$' && ISDIGIT (name
[1]))
2999 while (ISDIGIT ((unsigned char) *s
))
3001 lab
= lab
* 10 + *s
- '0';
3004 if (dollar_label_defined (lab
))
3006 name
= dollar_label_name (lab
, 0);
3007 symbolP
= symbol_find (name
);
3011 name
= dollar_label_name (lab
, 1);
3012 symbolP
= symbol_find_or_make (name
);
3020 /* Parse an operand that is machine-specific. */
3022 md_operand (expressionP
)
3023 expressionS
*expressionP ATTRIBUTE_UNUSED
;
3027 /* Round up a section size to the appropriate boundary---do we need this? */
3029 md_section_align (segment
, size
)
3030 segT segment ATTRIBUTE_UNUSED
;
3033 return size
; /* Byte (i.e., 32-bit) alignment is fine? */
3037 tic4x_pc_offset (op
)
3040 /* Determine the PC offset for a C[34]x instruction.
3041 This could be simplified using some boolean algebra
3042 but at the expense of readability. */
3046 case 0x62: /* call (C4x) */
3047 case 0x64: /* rptb (C4x) */
3049 case 0x61: /* brd */
3050 case 0x63: /* laj */
3051 case 0x65: /* rptbd (C4x) */
3053 case 0x66: /* swi */
3060 switch ((op
& 0xffe00000) >> 20)
3062 case 0x6a0: /* bB */
3063 case 0x720: /* callB */
3064 case 0x740: /* trapB */
3067 case 0x6a2: /* bBd */
3068 case 0x6a6: /* bBat */
3069 case 0x6aa: /* bBaf */
3070 case 0x722: /* lajB */
3071 case 0x748: /* latB */
3072 case 0x798: /* rptbd */
3079 switch ((op
& 0xfe200000) >> 20)
3081 case 0x6e0: /* dbB */
3084 case 0x6e2: /* dbBd */
3094 /* Exactly what point is a PC-relative offset relative TO?
3095 With the C3x we have the following:
3096 DBcond, Bcond disp + PC + 1 => PC
3097 DBcondD, BcondD disp + PC + 3 => PC
3100 md_pcrel_from (fixP
)
3103 unsigned char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
3106 op
= (buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
3108 return ((fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) >> 2) +
3109 tic4x_pc_offset (op
);
3112 /* Fill the alignment area with NOP's on .text, unless fill-data
3115 tic4x_do_align (alignment
, fill
, len
, max
)
3116 int alignment ATTRIBUTE_UNUSED
;
3117 const char *fill ATTRIBUTE_UNUSED
;
3118 int len ATTRIBUTE_UNUSED
;
3119 int max ATTRIBUTE_UNUSED
;
3121 unsigned long nop
= NOP_OPCODE
;
3123 /* Because we are talking lwords, not bytes, adjust aligment to do words */
3126 if (alignment
!= 0 && !need_pass_2
)
3130 /*if (subseg_text_p (now_seg))*/ /* FIXME: doesnt work for .text for some reason */
3131 frag_align_pattern( alignment
, (const char *)&nop
, sizeof(nop
), max
);
3134 frag_align (alignment, 0, max);*/
3137 frag_align (alignment
, *fill
, max
);
3139 frag_align_pattern (alignment
, fill
, len
, max
);
3142 /* Return 1 to skip the default aligment function */
3146 /* Look for and remove parallel instruction operator ||. */
3150 char *s
= input_line_pointer
;
3154 /* If parallel instruction prefix found at start of line, skip it. */
3155 if (*input_line_pointer
== '|' && input_line_pointer
[1] == '|')
3160 input_line_pointer
++;
3161 *input_line_pointer
= ' ';
3162 /* So line counters get bumped. */
3163 input_line_pointer
[-1] = '\n';
3168 /* Write out the previous insn here */
3171 input_line_pointer
= s
;
3176 tc_gen_reloc (seg
, fixP
)
3177 asection
*seg ATTRIBUTE_UNUSED
;
3182 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
3184 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
3185 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
3186 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
3187 reloc
->address
/= OCTETS_PER_BYTE
;
3188 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
3189 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
3191 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3192 "Reloc %d not supported by object file format",
3193 (int) fixP
->fx_r_type
);
3197 if (fixP
->fx_r_type
== BFD_RELOC_HI16
)
3198 reloc
->addend
= fixP
->fx_offset
;
3200 reloc
->addend
= fixP
->fx_addnumber
;