1 /* tc-tic4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
2 Copyright (C) 1997-2017 Free Software Foundation, Inc.
4 Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to
20 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
21 Boston, MA 02110-1301, USA. */
26 o .align cannot handle fill-data-width larger than 0xFF/8-bits. It
27 should be possible to define a 32-bits pattern.
29 o .align: Implement a 'bu' insn if the number of nop's exceeds 4
30 within the align frag. if(fragsize>4words) insert bu fragend+1
33 o .usect if has symbol on previous line not implemented
35 o .sym, .eos, .stag, .etag, .member not implemented
37 o Evaluation of constant floating point expressions (expr.c needs
40 o Support 'abc' constants (that is 0x616263). */
43 #include "safe-ctype.h"
44 #include "opcode/tic4x.h"
47 /* OK, we accept a syntax similar to the other well known C30
48 assembly tools. With TIC4X_ALT_SYNTAX defined we are more
49 flexible, allowing a more Unix-like syntax: `%' in front of
50 register names, `#' in front of immediate constants, and
51 not requiring `@' in front of direct addresses. */
53 #define TIC4X_ALT_SYNTAX
55 /* Equal to MAX_PRECISION in atof-ieee.c. */
56 #define MAX_LITTLENUMS 6 /* (12 bytes) */
58 /* Handle of the inst mnemonic hash table. */
59 static struct hash_control
*tic4x_op_hash
= NULL
;
61 /* Handle asg pseudo. */
62 static struct hash_control
*tic4x_asg_hash
= NULL
;
64 static unsigned int tic4x_cpu
= 0; /* Default to TMS320C40. */
65 static unsigned int tic4x_revision
= 0; /* CPU revision */
66 static unsigned int tic4x_idle2
= 0; /* Idle2 support */
67 static unsigned int tic4x_lowpower
= 0; /* Lowpower support */
68 static unsigned int tic4x_enhanced
= 0; /* Enhanced opcode support */
69 static unsigned int tic4x_big_model
= 0; /* Default to small memory model. */
70 static unsigned int tic4x_reg_args
= 0; /* Default to args passed on stack. */
71 static unsigned long tic4x_oplevel
= 0; /* Opcode level */
73 #define OPTION_CPU 'm'
74 #define OPTION_BIG (OPTION_MD_BASE + 1)
75 #define OPTION_SMALL (OPTION_MD_BASE + 2)
76 #define OPTION_MEMPARM (OPTION_MD_BASE + 3)
77 #define OPTION_REGPARM (OPTION_MD_BASE + 4)
78 #define OPTION_IDLE2 (OPTION_MD_BASE + 5)
79 #define OPTION_LOWPOWER (OPTION_MD_BASE + 6)
80 #define OPTION_ENHANCED (OPTION_MD_BASE + 7)
81 #define OPTION_REV (OPTION_MD_BASE + 8)
83 const char *md_shortopts
= "bm:prs";
84 struct option md_longopts
[] =
86 { "mcpu", required_argument
, NULL
, OPTION_CPU
},
87 { "mdsp", required_argument
, NULL
, OPTION_CPU
},
88 { "mbig", no_argument
, NULL
, OPTION_BIG
},
89 { "msmall", no_argument
, NULL
, OPTION_SMALL
},
90 { "mmemparm", no_argument
, NULL
, OPTION_MEMPARM
},
91 { "mregparm", no_argument
, NULL
, OPTION_REGPARM
},
92 { "midle2", no_argument
, NULL
, OPTION_IDLE2
},
93 { "mlowpower", no_argument
, NULL
, OPTION_LOWPOWER
},
94 { "menhanced", no_argument
, NULL
, OPTION_ENHANCED
},
95 { "mrev", required_argument
, NULL
, OPTION_REV
},
96 { NULL
, no_argument
, NULL
, 0 }
99 size_t md_longopts_size
= sizeof (md_longopts
);
104 M_UNKNOWN
, M_IMMED
, M_DIRECT
, M_REGISTER
, M_INDIRECT
,
105 M_IMMED_F
, M_PARALLEL
, M_HI
109 typedef struct tic4x_operand
111 tic4x_addr_mode_t mode
; /* Addressing mode. */
112 expressionS expr
; /* Expression. */
113 int disp
; /* Displacement for indirect addressing. */
114 int aregno
; /* Aux. register number. */
115 LITTLENUM_TYPE fwords
[MAX_LITTLENUMS
]; /* Float immed. number. */
119 typedef struct tic4x_insn
121 char name
[TIC4X_NAME_MAX
]; /* Mnemonic of instruction. */
122 unsigned int in_use
; /* True if in_use. */
123 unsigned int parallel
; /* True if parallel instruction. */
124 unsigned int nchars
; /* This is always 4 for the C30. */
125 unsigned long opcode
; /* Opcode number. */
126 expressionS exp
; /* Expression required for relocation. */
127 /* Relocation type required. */
128 bfd_reloc_code_real_type reloc
;
129 int pcrel
; /* True if relocation PC relative. */
130 char *pname
; /* Name of instruction in parallel. */
131 unsigned int num_operands
; /* Number of operands in total. */
132 tic4x_inst_t
*inst
; /* Pointer to first template. */
133 tic4x_operand_t operands
[TIC4X_OPERANDS_MAX
];
137 static tic4x_insn_t the_insn
; /* Info about our instruction. */
138 static tic4x_insn_t
*insn
= &the_insn
;
140 static void tic4x_asg (int);
141 static void tic4x_bss (int);
142 static void tic4x_globl (int);
143 static void tic4x_cons (int);
144 static void tic4x_stringer (int);
145 static void tic4x_eval (int);
146 static void tic4x_newblock (int);
147 static void tic4x_sect (int);
148 static void tic4x_set (int);
149 static void tic4x_usect (int);
150 static void tic4x_version (int);
156 {"align", s_align_bytes
, 32},
157 {"ascii", tic4x_stringer
, 1},
158 {"asciz", tic4x_stringer
, 0},
159 {"asg", tic4x_asg
, 0},
160 {"block", s_space
, 4},
161 {"byte", tic4x_cons
, 1},
162 {"bss", tic4x_bss
, 0},
163 {"copy", s_include
, 0},
164 {"def", tic4x_globl
, 0},
165 {"equ", tic4x_set
, 0},
166 {"eval", tic4x_eval
, 0},
167 {"global", tic4x_globl
, 0},
168 {"globl", tic4x_globl
, 0},
169 {"hword", tic4x_cons
, 2},
170 {"ieee", float_cons
, 'i'},
171 {"int", tic4x_cons
, 4}, /* .int allocates 4 bytes. */
172 {"ldouble", float_cons
, 'e'},
173 {"newblock", tic4x_newblock
, 0},
174 {"ref", s_ignore
, 0}, /* All undefined treated as external. */
175 {"set", tic4x_set
, 0},
176 {"sect", tic4x_sect
, 1}, /* Define named section. */
177 {"space", s_space
, 4},
178 {"string", tic4x_stringer
, 0},
179 {"usect", tic4x_usect
, 0}, /* Reserve space in uninit. named sect. */
180 {"version", tic4x_version
, 0},
181 {"word", tic4x_cons
, 4}, /* .word allocates 4 bytes. */
182 {"xdef", tic4x_globl
, 0},
186 int md_short_jump_size
= 4;
187 int md_long_jump_size
= 4;
189 /* This array holds the chars that always start a comment. If the
190 pre-processor is disabled, these aren't very useful. */
191 #ifdef TIC4X_ALT_SYNTAX
192 const char comment_chars
[] = ";!";
194 const char comment_chars
[] = ";";
197 /* This array holds the chars that only start a comment at the beginning of
198 a line. If the line seems to have the form '# 123 filename'
199 .line and .file directives will appear in the pre-processed output.
200 Note that input_file.c hand checks for '#' at the beginning of the
201 first line of the input file. This is because the compiler outputs
202 #NO_APP at the beginning of its output.
203 Also note that comments like this one will always work. */
204 const char line_comment_chars
[] = "#*";
206 /* We needed an unused char for line separation to work around the
207 lack of macros, using sed and such. */
208 const char line_separator_chars
[] = "&";
210 /* Chars that can be used to separate mant from exp in floating point nums. */
211 const char EXP_CHARS
[] = "eE";
213 /* Chars that mean this number is a floating point constant. */
216 const char FLT_CHARS
[] = "fFilsS";
218 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
219 changed in read.c. Ideally it shouldn't have to know about it at
220 all, but nothing is ideal around here. */
222 /* Flonums returned here. */
223 extern FLONUM_TYPE generic_floating_point_number
;
225 /* Precision in LittleNums. */
226 #define MAX_PRECISION (4) /* It's a bit overkill for us, but the code
228 #define S_PRECISION (1) /* Short float constants 16-bit. */
229 #define F_PRECISION (2) /* Float and double types 32-bit. */
230 #define E_PRECISION (4) /* Extended precision, 64-bit (real 40-bit). */
233 /* Turn generic_floating_point_number into a real short/float/double. */
235 tic4x_gen_to_words (FLONUM_TYPE flonum
, LITTLENUM_TYPE
*words
, int precision
)
237 int return_value
= 0;
238 LITTLENUM_TYPE
*p
; /* Littlenum pointer. */
239 int mantissa_bits
; /* Bits in mantissa field. */
240 int exponent_bits
; /* Bits in exponent field. */
242 unsigned int sone
; /* Scaled one. */
243 unsigned int sfract
; /* Scaled fraction. */
244 unsigned int smant
; /* Scaled mantissa. */
246 unsigned int mover
; /* Mantissa overflow bits */
247 unsigned int rbit
; /* Round bit. */
248 int shift
; /* Shift count. */
250 /* NOTE: Svein Seldal <Svein@dev.seldal.com>
251 The code in this function is altered slightly to support floats
252 with 31-bits mantissas, thus the documentation below may be a
253 little bit inaccurate.
255 By Michael P. Hayes <m.hayes@elec.canterbury.ac.nz>
256 Here is how a generic floating point number is stored using
257 flonums (an extension of bignums) where p is a pointer to an
260 For example 2e-3 is stored with exp = -4 and
267 with low = &bits[2], high = &bits[5], and leader = &bits[5].
269 This number can be written as
270 0x0083126e978d4fde.00000000 * 65536**-4 or
271 0x0.0083126e978d4fde * 65536**0 or
272 0x0.83126e978d4fde * 2**-8 = 2e-3
274 Note that low points to the 65536**0 littlenum (bits[2]) and
275 leader points to the most significant non-zero littlenum
278 TMS320C3X floating point numbers are a bit of a strange beast.
279 The 32-bit flavour has the 8 MSBs representing the exponent in
280 twos complement format (-128 to +127). There is then a sign bit
281 followed by 23 bits of mantissa. The mantissa is expressed in
282 twos complement format with the binary point after the most
283 significant non sign bit. The bit after the binary point is
284 suppressed since it is the complement of the sign bit. The
285 effective mantissa is thus 24 bits. Zero is represented by an
288 The 16-bit flavour has the 4 MSBs representing the exponent in
289 twos complement format (-8 to +7). There is then a sign bit
290 followed by 11 bits of mantissa. The mantissa is expressed in
291 twos complement format with the binary point after the most
292 significant non sign bit. The bit after the binary point is
293 suppressed since it is the complement of the sign bit. The
294 effective mantissa is thus 12 bits. Zero is represented by an
295 exponent of -8. For example,
297 number norm mant m x e s i fraction f
298 +0.500 => 1.00000000000 -1 -1 0 1 .00000000000 (1 + 0) * 2^(-1)
299 +0.999 => 1.11111111111 -1 -1 0 1 .11111111111 (1 + 0.99) * 2^(-1)
300 +1.000 => 1.00000000000 0 0 0 1 .00000000000 (1 + 0) * 2^(0)
301 +1.500 => 1.10000000000 0 0 0 1 .10000000000 (1 + 0.5) * 2^(0)
302 +1.999 => 1.11111111111 0 0 0 1 .11111111111 (1 + 0.9) * 2^(0)
303 +2.000 => 1.00000000000 1 1 0 1 .00000000000 (1 + 0) * 2^(1)
304 +4.000 => 1.00000000000 2 2 0 1 .00000000000 (1 + 0) * 2^(2)
305 -0.500 => 1.00000000000 -1 -1 1 0 .10000000000 (-2 + 0) * 2^(-2)
306 -1.000 => 1.00000000000 0 -1 1 0 .00000000000 (-2 + 0) * 2^(-1)
307 -1.500 => 1.10000000000 0 0 1 0 .10000000000 (-2 + 0.5) * 2^(0)
308 -1.999 => 1.11111111111 0 0 1 0 .00000000001 (-2 + 0.11) * 2^(0)
309 -2.000 => 1.00000000000 1 1 1 0 .00000000000 (-2 + 0) * 2^(0)
310 -4.000 => 1.00000000000 2 1 1 0 .00000000000 (-2 + 0) * 2^(1)
312 where e is the exponent, s is the sign bit, i is the implied bit,
313 and f is the fraction stored in the mantissa field.
315 num = (1 + f) * 2^x = m * 2^e if s = 0
316 num = (-2 + f) * 2^x = -m * 2^e if s = 1
317 where 0 <= f < 1.0 and 1.0 <= m < 2.0
319 The fraction (f) and exponent (e) fields for the TMS320C3X format
320 can be derived from the normalised mantissa (m) and exponent (x) using:
322 f = m - 1, e = x if s = 0
323 f = 2 - m, e = x if s = 1 and m != 1.0
324 f = 0, e = x - 1 if s = 1 and m = 1.0
325 f = 0, e = -8 if m = 0
328 OK, the other issue we have to consider is rounding since the
329 mantissa has a much higher potential precision than what we can
330 represent. To do this we add half the smallest storable fraction.
331 We then have to renormalise the number to allow for overflow.
333 To convert a generic flonum into a TMS320C3X floating point
334 number, here's what we try to do....
336 The first thing is to generate a normalised mantissa (m) where
337 1.0 <= m < 2 and to convert the exponent from base 16 to base 2.
338 We desire the binary point to be placed after the most significant
339 non zero bit. This process is done in two steps: firstly, the
340 littlenum with the most significant non zero bit is located (this
341 is done for us since leader points to this littlenum) and the
342 binary point (which is currently after the LSB of the littlenum
343 pointed to by low) is moved to before the MSB of the littlenum
344 pointed to by leader. This requires the exponent to be adjusted
345 by leader - low + 1. In the earlier example, the new exponent is
346 thus -4 + (5 - 2 + 1) = 0 (base 65536). We now need to convert
347 the exponent to base 2 by multiplying the exponent by 16 (log2
348 65536). The exponent base 2 is thus also zero.
350 The second step is to hunt for the most significant non zero bit
351 in the leader littlenum. We do this by left shifting a copy of
352 the leader littlenum until bit 16 is set (0x10000) and counting
353 the number of shifts, S, required. The number of shifts then has to
354 be added to correct the exponent (base 2). For our example, this
355 will require 9 shifts and thus our normalised exponent (base 2) is
356 0 + 9 = 9. Note that the worst case scenario is when the leader
357 littlenum is 1, thus requiring 16 shifts.
359 We now have to left shift the other littlenums by the same amount,
360 propagating the shifted bits into the more significant littlenums.
361 To save a lot of unnecessary shifting we only have to consider
362 two or three littlenums, since the greatest number of mantissa
363 bits required is 24 + 1 rounding bit. While two littlenums
364 provide 32 bits of precision, the most significant littlenum
365 may only contain a single significant bit and thus an extra
366 littlenum is required.
368 Denoting the number of bits in the fraction field as F, we require
369 G = F + 2 bits (one extra bit is for rounding, the other gets
370 suppressed). Say we required S shifts to find the most
371 significant bit in the leader littlenum, the number of left shifts
372 required to move this bit into bit position G - 1 is L = G + S - 17.
373 Note that this shift count may be negative for the short floating
374 point flavour (where F = 11 and thus G = 13 and potentially S < 3).
375 If L > 0 we have to shunt the next littlenum into position. Bit
376 15 (the MSB) of the next littlenum needs to get moved into position
377 L - 1 (If L > 15 we need all the bits of this littlenum and
378 some more from the next one.). We subtract 16 from L and use this
379 as the left shift count; the resultant value we or with the
380 previous result. If L > 0, we repeat this operation. */
382 if (precision
!= S_PRECISION
)
384 if (precision
== E_PRECISION
)
385 words
[2] = words
[3] = 0x0000;
387 /* 0.0e0 or NaN seen. */
388 if (flonum
.low
> flonum
.leader
/* = 0.0e0 */
389 || flonum
.sign
== 0) /* = NaN */
392 as_bad (_("Nan, using zero."));
397 if (flonum
.sign
== 'P')
399 /* +INF: Replace with maximum float. */
400 if (precision
== S_PRECISION
)
407 if (precision
== E_PRECISION
)
414 else if (flonum
.sign
== 'N')
416 /* -INF: Replace with maximum float. */
417 if (precision
== S_PRECISION
)
421 if (precision
== E_PRECISION
)
426 exponent
= (flonum
.exponent
+ flonum
.leader
- flonum
.low
+ 1) * 16;
428 if (!(tmp
= *flonum
.leader
))
429 abort (); /* Hmmm. */
430 shift
= 0; /* Find position of first sig. bit. */
433 exponent
-= (16 - shift
); /* Adjust exponent. */
435 if (precision
== S_PRECISION
) /* Allow 1 rounding bit. */
440 else if(precision
== F_PRECISION
)
445 else /* E_PRECISION */
451 shift
= mantissa_bits
- shift
;
456 /* Store the mantissa data into smant and the roundbit into rbit */
457 for (p
= flonum
.leader
; p
>= flonum
.low
&& shift
> -16; p
--)
459 tmp
= shift
>= 0 ? *p
<< shift
: *p
>> -shift
;
460 rbit
= shift
< 0 ? ((*p
>> (-shift
-1)) & 0x1) : 0;
465 /* OK, we've got our scaled mantissa so let's round it up */
468 /* If the mantissa is going to overflow when added, lets store
469 the extra bit in mover. -- A special case exists when
470 mantissa_bits is 31 (E_PRECISION). Then the first test cannot
471 be trusted, as result is host-dependent, thus the second
473 if( smant
== ((unsigned)(1<<(mantissa_bits
+1))-1)
474 || smant
== (unsigned)-1 ) /* This is to catch E_PRECISION cases */
479 /* Get the scaled one value */
480 sone
= (1 << (mantissa_bits
));
482 /* The number may be unnormalised so renormalise it... */
486 smant
|= sone
; /* Insert the bit from mover into smant */
490 /* The binary point is now between bit positions 11 and 10 or 23 and 22,
491 i.e., between mantissa_bits - 1 and mantissa_bits - 2 and the
492 bit at mantissa_bits - 1 should be set. */
494 abort (); /* Ooops. */
496 if (flonum
.sign
== '+')
497 sfract
= smant
- sone
; /* smant - 1.0. */
500 /* This seems to work. */
508 sfract
= -smant
& (sone
-1); /* 2.0 - smant. */
510 sfract
|= sone
; /* Insert sign bit. */
513 if (abs (exponent
) >= (1 << (exponent_bits
- 1)))
514 as_bad (_("Cannot represent exponent in %d bits"), exponent_bits
);
516 /* Force exponent to fit in desired field width. */
517 exponent
&= (1 << (exponent_bits
)) - 1;
519 if (precision
== E_PRECISION
)
521 /* Map the float part first (100% equal format as F_PRECISION) */
522 words
[0] = exponent
<< (mantissa_bits
+1-24);
523 words
[0] |= sfract
>> 24;
524 words
[1] = sfract
>> 8;
526 /* Map the mantissa in the next */
527 words
[2] = sfract
>> 16;
528 words
[3] = sfract
& 0xffff;
532 /* Insert the exponent data into the word */
533 sfract
|= exponent
<< (mantissa_bits
+1);
535 if (precision
== S_PRECISION
)
539 words
[0] = sfract
>> 16;
540 words
[1] = sfract
& 0xffff;
547 /* Returns pointer past text consumed. */
549 tic4x_atof (char *str
, char what_kind
, LITTLENUM_TYPE
*words
)
551 /* Extra bits for zeroed low-order bits. The 1st MAX_PRECISION are
552 zeroed, the last contain flonum bits. */
553 static LITTLENUM_TYPE bits
[MAX_PRECISION
+ MAX_PRECISION
+ GUARD
];
555 /* Number of 16-bit words in the format. */
557 FLONUM_TYPE save_gen_flonum
;
559 /* We have to save the generic_floating_point_number because it
560 contains storage allocation about the array of LITTLENUMs where
561 the value is actually stored. We will allocate our own array of
562 littlenums below, but have to restore the global one on exit. */
563 save_gen_flonum
= generic_floating_point_number
;
566 generic_floating_point_number
.low
= bits
+ MAX_PRECISION
;
567 generic_floating_point_number
.high
= NULL
;
568 generic_floating_point_number
.leader
= NULL
;
569 generic_floating_point_number
.exponent
= 0;
570 generic_floating_point_number
.sign
= '\0';
572 /* Use more LittleNums than seems necessary: the highest flonum may
573 have 15 leading 0 bits, so could be useless. */
575 memset (bits
, '\0', sizeof (LITTLENUM_TYPE
) * MAX_PRECISION
);
581 precision
= S_PRECISION
;
588 precision
= F_PRECISION
;
593 precision
= E_PRECISION
;
597 as_bad (_("Invalid floating point number"));
601 generic_floating_point_number
.high
602 = generic_floating_point_number
.low
+ precision
- 1 + GUARD
;
604 if (atof_generic (&return_value
, ".", EXP_CHARS
,
605 &generic_floating_point_number
))
607 as_bad (_("Invalid floating point number"));
611 tic4x_gen_to_words (generic_floating_point_number
,
614 /* Restore the generic_floating_point_number's storage alloc (and
616 generic_floating_point_number
= save_gen_flonum
;
622 tic4x_insert_reg (const char *regname
, int regnum
)
627 symbol_table_insert (symbol_new (regname
, reg_section
, (valueT
) regnum
,
628 &zero_address_frag
));
629 for (i
= 0; regname
[i
]; i
++)
630 buf
[i
] = ISLOWER (regname
[i
]) ? TOUPPER (regname
[i
]) : regname
[i
];
633 symbol_table_insert (symbol_new (buf
, reg_section
, (valueT
) regnum
,
634 &zero_address_frag
));
638 tic4x_insert_sym (const char *symname
, int value
)
642 symbolP
= symbol_new (symname
, absolute_section
,
643 (valueT
) value
, &zero_address_frag
);
644 SF_SET_LOCAL (symbolP
);
645 symbol_table_insert (symbolP
);
649 tic4x_expression (char *str
, expressionS
*exp
)
654 t
= input_line_pointer
; /* Save line pointer. */
655 input_line_pointer
= str
;
657 s
= input_line_pointer
;
658 input_line_pointer
= t
; /* Restore line pointer. */
659 return s
; /* Return pointer to where parsing stopped. */
663 tic4x_expression_abs (char *str
, offsetT
*value
)
668 t
= input_line_pointer
; /* Save line pointer. */
669 input_line_pointer
= str
;
670 *value
= get_absolute_expression ();
671 s
= input_line_pointer
;
672 input_line_pointer
= t
; /* Restore line pointer. */
677 tic4x_emit_char (char c
, int b
)
681 exp
.X_op
= O_constant
;
682 exp
.X_add_number
= c
;
687 tic4x_seg_alloc (char *name ATTRIBUTE_UNUSED
,
688 segT seg ATTRIBUTE_UNUSED
,
692 /* Note that the size is in words
693 so we multiply it by 4 to get the number of bytes to allocate. */
695 /* If we have symbol: .usect ".fred", size etc.,
696 the symbol needs to point to the first location reserved
703 p
= frag_var (rs_fill
, 1, 1, (relax_substateT
) 0,
705 size
* OCTETS_PER_BYTE
, (char *) 0);
710 /* .asg ["]character-string["], symbol */
712 tic4x_asg (int x ATTRIBUTE_UNUSED
)
719 str
= input_line_pointer
;
721 /* Skip string expression. */
722 while (*input_line_pointer
!= ',' && *input_line_pointer
)
723 input_line_pointer
++;
724 if (*input_line_pointer
!= ',')
726 as_bad (_("Comma expected\n"));
729 *input_line_pointer
++ = '\0';
730 c
= get_symbol_name (&name
); /* Get terminator. */
732 name
= xstrdup (name
);
733 if (hash_find (tic4x_asg_hash
, name
))
734 hash_replace (tic4x_asg_hash
, name
, (void *) str
);
736 hash_insert (tic4x_asg_hash
, name
, (void *) str
);
737 (void) restore_line_pointer (c
);
738 demand_empty_rest_of_line ();
741 /* .bss symbol, size */
743 tic4x_bss (int x ATTRIBUTE_UNUSED
)
750 subsegT current_subseg
;
753 current_seg
= now_seg
; /* Save current seg. */
754 current_subseg
= now_subseg
; /* Save current subseg. */
757 c
= get_symbol_name (&name
); /* Get terminator. */
759 c
= * ++ input_line_pointer
;
762 as_bad (_(".bss size argument missing\n"));
767 tic4x_expression_abs (++input_line_pointer
, &size
);
770 as_bad (_(".bss size %ld < 0!"), (long) size
);
773 subseg_set (bss_section
, 0);
774 symbolP
= symbol_find_or_make (name
);
776 if (S_GET_SEGMENT (symbolP
) == bss_section
)
777 symbol_get_frag (symbolP
)->fr_symbol
= 0;
779 symbol_set_frag (symbolP
, frag_now
);
781 p
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
,
782 size
* OCTETS_PER_BYTE
, (char *) 0);
783 *p
= 0; /* Fill char. */
785 S_SET_SEGMENT (symbolP
, bss_section
);
787 /* The symbol may already have been created with a preceding
788 ".globl" directive -- be careful not to step on storage class
789 in that case. Otherwise, set it to static. */
790 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
791 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
793 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
794 demand_empty_rest_of_line ();
798 tic4x_globl (int ignore ATTRIBUTE_UNUSED
)
806 c
= get_symbol_name (&name
);
807 symbolP
= symbol_find_or_make (name
);
808 *input_line_pointer
= c
;
809 SKIP_WHITESPACE_AFTER_NAME ();
810 S_SET_STORAGE_CLASS (symbolP
, C_EXT
);
811 S_SET_EXTERNAL (symbolP
);
814 input_line_pointer
++;
816 if (*input_line_pointer
== '\n')
822 demand_empty_rest_of_line ();
825 /* Handle .byte, .word. .int, .long */
827 tic4x_cons (int bytes
)
833 if (*input_line_pointer
== '"')
835 input_line_pointer
++;
836 while (is_a_char (c
= next_char_of_string ()))
837 tic4x_emit_char (c
, 4);
838 know (input_line_pointer
[-1] == '\"');
844 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
845 if (exp
.X_op
== O_constant
)
850 exp
.X_add_number
&= 255;
853 exp
.X_add_number
&= 65535;
857 /* Perhaps we should disallow .byte and .hword with
858 a non constant expression that will require relocation. */
862 while (*input_line_pointer
++ == ',');
864 input_line_pointer
--; /* Put terminator back into stream. */
865 demand_empty_rest_of_line ();
868 /* Handle .ascii, .asciz, .string */
870 tic4x_stringer (int append_zero
)
879 if (*input_line_pointer
== '"')
881 input_line_pointer
++;
882 while (is_a_char (c
= next_char_of_string ()))
884 tic4x_emit_char (c
, 1);
890 tic4x_emit_char (c
, 1);
894 know (input_line_pointer
[-1] == '\"');
900 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
901 if (exp
.X_op
!= O_constant
)
903 as_bad (_("Non-constant symbols not allowed\n"));
906 exp
.X_add_number
&= 255; /* Limit number to 8-bit */
911 while (*input_line_pointer
++ == ',');
913 /* Fill out the rest of the expression with 0's to fill up a full word */
915 tic4x_emit_char (0, 4-(bytes
&0x3));
917 input_line_pointer
--; /* Put terminator back into stream. */
918 demand_empty_rest_of_line ();
921 /* .eval expression, symbol */
923 tic4x_eval (int x ATTRIBUTE_UNUSED
)
931 tic4x_expression_abs (input_line_pointer
, &value
);
932 if (*input_line_pointer
++ != ',')
934 as_bad (_("Symbol missing\n"));
937 c
= get_symbol_name (&name
); /* Get terminator. */
938 tic4x_insert_sym (name
, value
);
939 (void) restore_line_pointer (c
);
940 demand_empty_rest_of_line ();
943 /* Reset local labels. */
945 tic4x_newblock (int x ATTRIBUTE_UNUSED
)
947 dollar_label_clear ();
950 /* .sect "section-name" [, value] */
951 /* .sect ["]section-name[:subsection-name]["] [, value] */
953 tic4x_sect (int x ATTRIBUTE_UNUSED
)
962 if (*input_line_pointer
== '"')
963 input_line_pointer
++;
964 c
= get_symbol_name (§ion_name
); /* Get terminator. */
966 c
= * ++ input_line_pointer
;
967 input_line_pointer
++; /* Skip null symbol terminator. */
968 name
= xstrdup (section_name
);
970 /* TI C from version 5.0 allows a section name to contain a
971 subsection name as well. The subsection name is separated by a
972 ':' from the section name. Currently we scan the subsection
974 Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>. */
978 c
= get_symbol_name (&subname
); /* Get terminator. */
980 c
= * ++ input_line_pointer
;
981 input_line_pointer
++; /* Skip null symbol terminator. */
982 as_warn (_(".sect: subsection name ignored"));
985 /* We might still have a '"' to discard, but the character after a
986 symbol name will be overwritten with a \0 by get_symbol_name()
991 tic4x_expression_abs (input_line_pointer
, &num
);
992 else if (*input_line_pointer
== ',')
995 tic4x_expression_abs (++input_line_pointer
, &num
);
1000 seg
= subseg_new (name
, num
);
1001 if (line_label
!= NULL
)
1003 S_SET_SEGMENT (line_label
, seg
);
1004 symbol_set_frag (line_label
, frag_now
);
1007 if (bfd_get_section_flags (stdoutput
, seg
) == SEC_NO_FLAGS
)
1009 if (!bfd_set_section_flags (stdoutput
, seg
, SEC_DATA
))
1010 as_warn (_("Error setting flags for \"%s\": %s"), name
,
1011 bfd_errmsg (bfd_get_error ()));
1014 /* If the last character overwritten by get_symbol_name() was an
1015 end-of-line, we must restore it or the end of the line will not be
1016 recognised and scanning extends into the next line, stopping with
1017 an error (blame Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>
1018 if this is not true). */
1019 if (is_end_of_line
[(unsigned char) c
])
1020 *(--input_line_pointer
) = c
;
1022 demand_empty_rest_of_line ();
1025 /* symbol[:] .set value or .set symbol, value */
1027 tic4x_set (int x ATTRIBUTE_UNUSED
)
1032 if ((symbolP
= line_label
) == NULL
)
1037 c
= get_symbol_name (&name
); /* Get terminator. */
1039 c
= * ++ input_line_pointer
;
1042 as_bad (_(".set syntax invalid\n"));
1043 ignore_rest_of_line ();
1046 ++input_line_pointer
;
1047 symbolP
= symbol_find_or_make (name
);
1050 symbol_table_insert (symbolP
);
1052 pseudo_set (symbolP
);
1053 demand_empty_rest_of_line ();
1056 /* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
1058 tic4x_usect (int x ATTRIBUTE_UNUSED
)
1064 offsetT size
, alignment_flag
;
1066 subsegT current_subseg
;
1068 current_seg
= now_seg
; /* save current seg. */
1069 current_subseg
= now_subseg
; /* save current subseg. */
1072 if (*input_line_pointer
== '"')
1073 input_line_pointer
++;
1074 c
= get_symbol_name (§ion_name
); /* Get terminator. */
1076 c
= * ++ input_line_pointer
;
1077 input_line_pointer
++; /* Skip null symbol terminator. */
1078 name
= xstrdup (section_name
);
1081 input_line_pointer
=
1082 tic4x_expression_abs (input_line_pointer
, &size
);
1083 else if (*input_line_pointer
== ',')
1085 input_line_pointer
=
1086 tic4x_expression_abs (++input_line_pointer
, &size
);
1091 /* Read a possibly present third argument (alignment flag) [VK]. */
1092 if (*input_line_pointer
== ',')
1094 input_line_pointer
=
1095 tic4x_expression_abs (++input_line_pointer
, &alignment_flag
);
1100 as_warn (_(".usect: non-zero alignment flag ignored"));
1102 seg
= subseg_new (name
, 0);
1103 if (line_label
!= NULL
)
1105 S_SET_SEGMENT (line_label
, seg
);
1106 symbol_set_frag (line_label
, frag_now
);
1107 S_SET_VALUE (line_label
, frag_now_fix ());
1109 seg_info (seg
)->bss
= 1; /* Uninitialised data. */
1110 if (!bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
))
1111 as_warn (_("Error setting flags for \"%s\": %s"), name
,
1112 bfd_errmsg (bfd_get_error ()));
1113 tic4x_seg_alloc (name
, seg
, size
, line_label
);
1115 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1116 S_SET_STORAGE_CLASS (line_label
, C_STAT
);
1118 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
1119 demand_empty_rest_of_line ();
1122 /* .version cpu-version. */
1124 tic4x_version (int x ATTRIBUTE_UNUSED
)
1128 input_line_pointer
=
1129 tic4x_expression_abs (input_line_pointer
, &temp
);
1130 if (!IS_CPU_TIC3X (temp
) && !IS_CPU_TIC4X (temp
))
1131 as_bad (_("This assembler does not support processor generation %ld"),
1134 if (tic4x_cpu
&& temp
!= (offsetT
) tic4x_cpu
)
1135 as_warn (_("Changing processor generation on fly not supported..."));
1137 demand_empty_rest_of_line ();
1141 tic4x_init_regtable (void)
1145 for (i
= 0; i
< tic3x_num_registers
; i
++)
1146 tic4x_insert_reg (tic3x_registers
[i
].name
,
1147 tic3x_registers
[i
].regno
);
1149 if (IS_CPU_TIC4X (tic4x_cpu
))
1151 /* Add additional Tic4x registers, overriding some C3x ones. */
1152 for (i
= 0; i
< tic4x_num_registers
; i
++)
1153 tic4x_insert_reg (tic4x_registers
[i
].name
,
1154 tic4x_registers
[i
].regno
);
1159 tic4x_init_symbols (void)
1161 /* The TI tools accept case insensitive versions of these symbols,
1166 .TMS320xx 30,31,32,40,or 44 set according to -v flag
1167 .C3X or .C3x 1 or 0 1 if -v30,-v31,or -v32
1168 .C30 1 or 0 1 if -v30
1169 .C31 1 or 0 1 if -v31
1170 .C32 1 or 0 1 if -v32
1171 .C4X or .C4x 1 or 0 1 if -v40, or -v44
1172 .C40 1 or 0 1 if -v40
1173 .C44 1 or 0 1 if -v44
1175 .REGPARM 1 or 0 1 if -mr option used
1176 .BIGMODEL 1 or 0 1 if -mb option used
1178 These symbols are currently supported but will be removed in a
1180 .TMS320C30 1 or 0 1 if -v30,-v31,or -v32
1181 .TMS320C31 1 or 0 1 if -v31
1182 .TMS320C32 1 or 0 1 if -v32
1183 .TMS320C40 1 or 0 1 if -v40, or -v44
1184 .TMS320C44 1 or 0 1 if -v44
1186 Source: TI: TMS320C3x/C4x Assembly Language Tools User's Guide,
1187 1997, SPRU035C, p. 3-17/3-18. */
1188 tic4x_insert_sym (".REGPARM", tic4x_reg_args
);
1189 tic4x_insert_sym (".MEMPARM", !tic4x_reg_args
);
1190 tic4x_insert_sym (".BIGMODEL", tic4x_big_model
);
1191 tic4x_insert_sym (".C30INTERRUPT", 0);
1192 tic4x_insert_sym (".TMS320xx", tic4x_cpu
== 0 ? 40 : tic4x_cpu
);
1193 tic4x_insert_sym (".C3X", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1194 tic4x_insert_sym (".C3x", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1195 tic4x_insert_sym (".C4X", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1196 tic4x_insert_sym (".C4x", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1197 /* Do we need to have the following symbols also in lower case? */
1198 tic4x_insert_sym (".TMS320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1199 tic4x_insert_sym (".tms320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1200 tic4x_insert_sym (".TMS320C31", tic4x_cpu
== 31);
1201 tic4x_insert_sym (".tms320C31", tic4x_cpu
== 31);
1202 tic4x_insert_sym (".TMS320C32", tic4x_cpu
== 32);
1203 tic4x_insert_sym (".tms320C32", tic4x_cpu
== 32);
1204 tic4x_insert_sym (".TMS320C33", tic4x_cpu
== 33);
1205 tic4x_insert_sym (".tms320C33", tic4x_cpu
== 33);
1206 tic4x_insert_sym (".TMS320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1207 tic4x_insert_sym (".tms320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1208 tic4x_insert_sym (".TMS320C44", tic4x_cpu
== 44);
1209 tic4x_insert_sym (".tms320C44", tic4x_cpu
== 44);
1210 tic4x_insert_sym (".TMX320C40", 0); /* C40 first pass silicon ? */
1211 tic4x_insert_sym (".tmx320C40", 0);
1214 /* Insert a new instruction template into hash table. */
1216 tic4x_inst_insert (const tic4x_inst_t
*inst
)
1218 static char prev_name
[16];
1219 const char *retval
= NULL
;
1221 /* Only insert the first name if have several similar entries. */
1222 if (!strcmp (inst
->name
, prev_name
) || inst
->name
[0] == '\0')
1225 retval
= hash_insert (tic4x_op_hash
, inst
->name
, (void *) inst
);
1227 fprintf (stderr
, "internal error: can't hash `%s': %s\n",
1228 inst
->name
, retval
);
1230 strcpy (prev_name
, inst
->name
);
1231 return retval
== NULL
;
1234 /* Make a new instruction template. */
1235 static tic4x_inst_t
*
1236 tic4x_inst_make (const char *name
, unsigned long opcode
, const char *args
)
1238 static tic4x_inst_t
*insts
= NULL
;
1239 static char *names
= NULL
;
1240 static int iindex
= 0;
1244 /* Allocate memory to store name strings. */
1245 names
= XNEWVEC (char, 8192);
1246 /* Allocate memory for additional insts. */
1247 insts
= XNEWVEC (tic4x_inst_t
, 1024);
1249 insts
[iindex
].name
= names
;
1250 insts
[iindex
].opcode
= opcode
;
1251 insts
[iindex
].opmask
= 0xffffffff;
1252 insts
[iindex
].args
= args
;
1260 return &insts
[iindex
- 1];
1263 /* Add instruction template, creating dynamic templates as required. */
1265 tic4x_inst_add (const tic4x_inst_t
*insts
)
1267 const char *s
= insts
->name
;
1275 /* We do not care about INSNs that is not a part of our
1277 if ((insts
->oplevel
& tic4x_oplevel
) == 0)
1286 /* Dynamically create all the conditional insts. */
1287 for (i
= 0; i
< tic4x_num_conds
; i
++)
1291 const char *c
= tic4x_conds
[i
].name
;
1301 /* If instruction found then have already processed it. */
1302 if (hash_find (tic4x_op_hash
, name
))
1307 inst
= tic4x_inst_make (name
, insts
[k
].opcode
+
1308 (tic4x_conds
[i
].cond
<<
1309 (*s
== 'B' ? 16 : 23)),
1311 if (k
== 0) /* Save strcmp() with following func. */
1312 ok
&= tic4x_inst_insert (inst
);
1315 while (!strcmp (insts
->name
,
1322 return tic4x_inst_insert (insts
);
1332 /* This function is called once, at assembler startup time. It should
1333 set up all the tables, etc., that the MD part of the assembler will
1341 /* Setup the proper opcode level according to the
1342 commandline parameters */
1343 tic4x_oplevel
= OP_C3X
;
1345 if ( IS_CPU_TIC4X(tic4x_cpu
) )
1346 tic4x_oplevel
|= OP_C4X
;
1348 if ( ( tic4x_cpu
== 31 && tic4x_revision
>= 6)
1349 || (tic4x_cpu
== 32 && tic4x_revision
>= 2)
1350 || (tic4x_cpu
== 33)
1352 tic4x_oplevel
|= OP_ENH
;
1354 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1355 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1356 || (tic4x_cpu
== 32)
1358 tic4x_oplevel
|= OP_LPWR
;
1360 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1361 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1362 || (tic4x_cpu
== 32)
1363 || (tic4x_cpu
== 33)
1364 || (tic4x_cpu
== 40 && tic4x_revision
>= 5)
1365 || (tic4x_cpu
== 44)
1367 tic4x_oplevel
|= OP_IDLE2
;
1369 /* Create hash table for mnemonics. */
1370 tic4x_op_hash
= hash_new ();
1372 /* Create hash table for asg pseudo. */
1373 tic4x_asg_hash
= hash_new ();
1375 /* Add mnemonics to hash table, expanding conditional mnemonics on fly. */
1376 for (i
= 0; i
< tic4x_num_insts
; i
++)
1377 ok
&= tic4x_inst_add (tic4x_insts
+ i
);
1379 /* Create dummy inst to avoid errors accessing end of table. */
1380 tic4x_inst_make ("", 0, "");
1383 as_fatal ("Broken assembler. No assembly attempted.");
1385 /* Add registers to symbol table. */
1386 tic4x_init_regtable ();
1388 /* Add predefined symbols to symbol table. */
1389 tic4x_init_symbols ();
1395 bfd_set_arch_mach (stdoutput
, bfd_arch_tic4x
,
1396 IS_CPU_TIC4X (tic4x_cpu
) ? bfd_mach_tic4x
: bfd_mach_tic3x
);
1400 tic4x_indirect_parse (tic4x_operand_t
*operand
,
1401 const tic4x_indirect_t
*indirect
)
1403 const char *n
= indirect
->name
;
1404 char *s
= input_line_pointer
;
1414 case 'a': /* Need to match aux register. */
1416 #ifdef TIC4X_ALT_SYNTAX
1420 while (ISALNUM (*s
))
1423 if (!(symbolP
= symbol_find (name
)))
1426 if (S_GET_SEGMENT (symbolP
) != reg_section
)
1429 operand
->aregno
= S_GET_VALUE (symbolP
);
1430 if (operand
->aregno
>= REG_AR0
&& operand
->aregno
<= REG_AR7
)
1433 as_bad (_("Auxiliary register AR0--AR7 required for indirect"));
1436 case 'd': /* Need to match constant for disp. */
1437 #ifdef TIC4X_ALT_SYNTAX
1438 if (*s
== '%') /* expr() will die if we don't skip this. */
1441 s
= tic4x_expression (s
, &operand
->expr
);
1442 if (operand
->expr
.X_op
!= O_constant
)
1444 operand
->disp
= operand
->expr
.X_add_number
;
1445 if (operand
->disp
< 0 || operand
->disp
> 255)
1447 as_bad (_("Bad displacement %d (require 0--255)\n"),
1453 case 'y': /* Need to match IR0. */
1454 case 'z': /* Need to match IR1. */
1455 #ifdef TIC4X_ALT_SYNTAX
1459 s
= tic4x_expression (s
, &operand
->expr
);
1460 if (operand
->expr
.X_op
!= O_register
)
1462 if (operand
->expr
.X_add_number
!= REG_IR0
1463 && operand
->expr
.X_add_number
!= REG_IR1
)
1465 as_bad (_("Index register IR0,IR1 required for displacement"));
1469 if (*n
== 'y' && operand
->expr
.X_add_number
== REG_IR0
)
1471 if (*n
== 'z' && operand
->expr
.X_add_number
== REG_IR1
)
1476 if (*s
!= '(') /* No displacement, assume to be 1. */
1487 if (TOLOWER (*s
) != *n
)
1492 if (*s
!= ' ' && *s
!= ',' && *s
!= '\0')
1494 input_line_pointer
= s
;
1499 tic4x_operand_parse (char *s
, tic4x_operand_t
*operand
)
1504 expressionS
*exp
= &operand
->expr
;
1505 char *save
= input_line_pointer
;
1508 struct hash_entry
*entry
= NULL
;
1510 input_line_pointer
= s
;
1513 c
= get_symbol_name (&str
); /* Get terminator. */
1514 new_pointer
= input_line_pointer
;
1515 if (strlen (str
) && (entry
= hash_find (tic4x_asg_hash
, str
)) != NULL
)
1517 (void) restore_line_pointer (c
);
1518 input_line_pointer
= (char *) entry
;
1522 (void) restore_line_pointer (c
);
1523 input_line_pointer
= str
;
1526 operand
->mode
= M_UNKNOWN
;
1527 switch (*input_line_pointer
)
1529 #ifdef TIC4X_ALT_SYNTAX
1531 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1532 if (exp
->X_op
!= O_register
)
1533 as_bad (_("Expecting a register name"));
1534 operand
->mode
= M_REGISTER
;
1538 /* Denotes high 16 bits. */
1539 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1540 if (exp
->X_op
== O_constant
)
1541 operand
->mode
= M_IMMED
;
1542 else if (exp
->X_op
== O_big
)
1544 if (exp
->X_add_number
)
1545 as_bad (_("Number too large")); /* bignum required */
1548 tic4x_gen_to_words (generic_floating_point_number
,
1549 operand
->fwords
, S_PRECISION
);
1550 operand
->mode
= M_IMMED_F
;
1553 /* Allow ori ^foo, ar0 to be equivalent to ldi .hi.foo, ar0 */
1554 /* WARNING : The TI C40 assembler cannot do this. */
1555 else if (exp
->X_op
== O_symbol
)
1556 operand
->mode
= M_HI
;
1558 as_bad (_("Expecting a constant value"));
1562 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1563 if (exp
->X_op
== O_constant
)
1564 operand
->mode
= M_IMMED
;
1565 else if (exp
->X_op
== O_big
)
1567 if (exp
->X_add_number
> 0)
1568 as_bad (_("Number too large")); /* bignum required. */
1571 tic4x_gen_to_words (generic_floating_point_number
,
1572 operand
->fwords
, S_PRECISION
);
1573 operand
->mode
= M_IMMED_F
;
1576 /* Allow ori foo, ar0 to be equivalent to ldi .lo.foo, ar0 */
1577 /* WARNING : The TI C40 assembler cannot do this. */
1578 else if (exp
->X_op
== O_symbol
)
1579 operand
->mode
= M_IMMED
;
1581 as_bad (_("Expecting a constant value"));
1587 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1588 if (exp
->X_op
!= O_constant
&& exp
->X_op
!= O_symbol
)
1589 as_bad (_("Bad direct addressing construct %s"), s
);
1590 if (exp
->X_op
== O_constant
)
1592 if (exp
->X_add_number
< 0)
1593 as_bad (_("Direct value of %ld is not suitable"),
1594 (long) exp
->X_add_number
);
1596 operand
->mode
= M_DIRECT
;
1601 for (i
= 0; i
< tic4x_num_indirects
; i
++)
1602 if ((ret
= tic4x_indirect_parse (operand
, &tic4x_indirects
[i
])))
1606 if (i
< tic4x_num_indirects
)
1608 operand
->mode
= M_INDIRECT
;
1609 /* Indirect addressing mode number. */
1610 operand
->expr
.X_add_number
= tic4x_indirects
[i
].modn
;
1611 /* Convert *+ARn(0) to *ARn etc. Maybe we should
1612 squeal about silly ones? */
1613 if (operand
->expr
.X_add_number
< 0x08 && !operand
->disp
)
1614 operand
->expr
.X_add_number
= 0x18;
1617 as_bad (_("Unknown indirect addressing mode"));
1621 operand
->mode
= M_IMMED
; /* Assume immediate. */
1622 str
= input_line_pointer
;
1623 input_line_pointer
= tic4x_expression (input_line_pointer
, exp
);
1624 if (exp
->X_op
== O_register
)
1626 know (exp
->X_add_symbol
== 0);
1627 know (exp
->X_op_symbol
== 0);
1628 operand
->mode
= M_REGISTER
;
1631 else if (exp
->X_op
== O_big
)
1633 if (exp
->X_add_number
> 0)
1634 as_bad (_("Number too large")); /* bignum required. */
1637 tic4x_gen_to_words (generic_floating_point_number
,
1638 operand
->fwords
, S_PRECISION
);
1639 operand
->mode
= M_IMMED_F
;
1643 #ifdef TIC4X_ALT_SYNTAX
1644 /* Allow ldi foo, ar0 to be equivalent to ldi @foo, ar0. */
1645 else if (exp
->X_op
== O_symbol
)
1647 operand
->mode
= M_DIRECT
;
1653 new_pointer
= input_line_pointer
;
1654 input_line_pointer
= save
;
1659 tic4x_operands_match (tic4x_inst_t
*inst
, tic4x_insn_t
*tinsn
, int check
)
1661 const char *args
= inst
->args
;
1662 unsigned long opcode
= inst
->opcode
;
1663 int num_operands
= tinsn
->num_operands
;
1664 tic4x_operand_t
*operand
= tinsn
->operands
;
1665 expressionS
*exp
= &operand
->expr
;
1669 /* Build the opcode, checking as we go to make sure that the
1672 If an operand matches, we modify insn or opcode appropriately,
1673 and do a "continue". If an operand fails to match, we "break". */
1675 tinsn
->nchars
= 4; /* Instructions always 4 bytes. */
1676 tinsn
->reloc
= NO_RELOC
;
1681 tinsn
->opcode
= opcode
;
1682 return num_operands
== 0;
1690 case '\0': /* End of args. */
1691 if (num_operands
== 1)
1693 tinsn
->opcode
= opcode
;
1696 break; /* Too many operands. */
1698 case '#': /* This is only used for ldp. */
1699 if (operand
->mode
!= M_DIRECT
&& operand
->mode
!= M_IMMED
)
1701 /* While this looks like a direct addressing mode, we actually
1702 use an immediate mode form of ldiu or ldpk instruction. */
1703 if (exp
->X_op
== O_constant
)
1705 if( ( IS_CPU_TIC4X (tic4x_cpu
) && exp
->X_add_number
<= 65535 )
1706 || ( IS_CPU_TIC3X (tic4x_cpu
) && exp
->X_add_number
<= 255 ) )
1708 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1714 as_bad (_("Immediate value of %ld is too large for ldf"),
1715 (long) exp
->X_add_number
);
1720 else if (exp
->X_op
== O_symbol
)
1722 tinsn
->reloc
= BFD_RELOC_HI16
;
1726 break; /* Not direct (dp) addressing. */
1728 case '@': /* direct. */
1729 if (operand
->mode
!= M_DIRECT
)
1731 if (exp
->X_op
== O_constant
)
1733 /* Store only the 16 LSBs of the number. */
1734 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1737 else if (exp
->X_op
== O_symbol
)
1739 tinsn
->reloc
= BFD_RELOC_LO16
;
1743 break; /* Not direct addressing. */
1746 if (operand
->mode
!= M_REGISTER
)
1748 reg
= exp
->X_add_number
;
1749 if (reg
>= REG_AR0
&& reg
<= REG_AR7
)
1750 INSERTU (opcode
, reg
- REG_AR0
, 24, 22);
1754 as_bad (_("Destination register must be ARn"));
1759 case 'B': /* Unsigned integer immediate. */
1760 /* Allow br label or br @label. */
1761 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
1763 if (exp
->X_op
== O_constant
)
1765 if (exp
->X_add_number
< (1 << 24))
1767 INSERTU (opcode
, exp
->X_add_number
, 23, 0);
1773 as_bad (_("Immediate value of %ld is too large"),
1774 (long) exp
->X_add_number
);
1779 if (IS_CPU_TIC4X (tic4x_cpu
))
1781 tinsn
->reloc
= BFD_RELOC_24_PCREL
;
1786 tinsn
->reloc
= BFD_RELOC_24
;
1793 if (!IS_CPU_TIC4X (tic4x_cpu
))
1795 if (operand
->mode
!= M_INDIRECT
)
1797 /* Require either *+ARn(disp) or *ARn. */
1798 if (operand
->expr
.X_add_number
!= 0
1799 && operand
->expr
.X_add_number
!= 0x18)
1802 as_bad (_("Invalid indirect addressing mode"));
1806 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1807 INSERTU (opcode
, operand
->disp
, 7, 3);
1811 if (!(operand
->mode
== M_REGISTER
))
1813 INSERTU (opcode
, exp
->X_add_number
, 7, 0);
1817 if (!(operand
->mode
== M_REGISTER
))
1819 reg
= exp
->X_add_number
;
1820 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1821 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1822 INSERTU (opcode
, reg
, 7, 0);
1826 as_bad (_("Register must be Rn"));
1832 if (operand
->mode
!= M_IMMED_F
1833 && !(operand
->mode
== M_IMMED
&& exp
->X_op
== O_constant
))
1836 if (operand
->mode
!= M_IMMED_F
)
1838 /* OK, we 've got something like cmpf 0, r0
1839 Why can't they stick in a bloody decimal point ?! */
1842 /* Create floating point number string. */
1843 sprintf (string
, "%d.0", (int) exp
->X_add_number
);
1844 tic4x_atof (string
, 's', operand
->fwords
);
1847 INSERTU (opcode
, operand
->fwords
[0], 15, 0);
1851 if (operand
->mode
!= M_REGISTER
)
1853 INSERTU (opcode
, exp
->X_add_number
, 15, 8);
1857 if (operand
->mode
!= M_REGISTER
)
1859 reg
= exp
->X_add_number
;
1860 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1861 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1862 INSERTU (opcode
, reg
, 15, 8);
1866 as_bad (_("Register must be Rn"));
1872 if (operand
->mode
!= M_REGISTER
)
1874 reg
= exp
->X_add_number
;
1875 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1876 INSERTU (opcode
, reg
- REG_R0
, 18, 16);
1880 as_bad (_("Register must be R0--R7"));
1886 if ( operand
->mode
== M_REGISTER
1887 && tic4x_oplevel
& OP_ENH
)
1889 reg
= exp
->X_add_number
;
1890 INSERTU (opcode
, reg
, 4, 0);
1891 INSERTU (opcode
, 7, 7, 5);
1897 if (operand
->mode
!= M_INDIRECT
)
1899 if (operand
->disp
!= 0 && operand
->disp
!= 1)
1901 if (IS_CPU_TIC4X (tic4x_cpu
))
1904 as_bad (_("Invalid indirect addressing mode displacement %d"),
1909 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1910 INSERTU (opcode
, operand
->expr
.X_add_number
, 7, 3);
1914 if ( operand
->mode
== M_REGISTER
1915 && tic4x_oplevel
& OP_ENH
)
1917 reg
= exp
->X_add_number
;
1918 INSERTU (opcode
, reg
, 12, 8);
1919 INSERTU (opcode
, 7, 15, 13);
1925 if (operand
->mode
!= M_INDIRECT
)
1927 if (operand
->disp
!= 0 && operand
->disp
!= 1)
1929 if (IS_CPU_TIC4X (tic4x_cpu
))
1932 as_bad (_("Invalid indirect addressing mode displacement %d"),
1937 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
1938 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
1942 if (operand
->mode
!= M_REGISTER
)
1944 reg
= exp
->X_add_number
;
1945 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1946 INSERTU (opcode
, reg
- REG_R0
, 21, 19);
1950 as_bad (_("Register must be R0--R7"));
1956 if (operand
->mode
!= M_REGISTER
)
1958 reg
= exp
->X_add_number
;
1959 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1960 INSERTU (opcode
, reg
- REG_R0
, 24, 22);
1964 as_bad (_("Register must be R0--R7"));
1970 if (operand
->mode
!= M_REGISTER
)
1972 reg
= exp
->X_add_number
;
1973 if (reg
== REG_R2
|| reg
== REG_R3
)
1974 INSERTU (opcode
, reg
- REG_R2
, 22, 22);
1978 as_bad (_("Destination register must be R2 or R3"));
1984 if (operand
->mode
!= M_REGISTER
)
1986 reg
= exp
->X_add_number
;
1987 if (reg
== REG_R0
|| reg
== REG_R1
)
1988 INSERTU (opcode
, reg
- REG_R0
, 23, 23);
1992 as_bad (_("Destination register must be R0 or R1"));
1998 if (!IS_CPU_TIC4X (tic4x_cpu
))
2000 if (operand
->mode
!= M_INDIRECT
)
2002 /* Require either *+ARn(disp) or *ARn. */
2003 if (operand
->expr
.X_add_number
!= 0
2004 && operand
->expr
.X_add_number
!= 0x18)
2007 as_bad (_("Invalid indirect addressing mode"));
2011 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2012 INSERTU (opcode
, operand
->disp
, 15, 11);
2015 case 'P': /* PC relative displacement. */
2016 /* Allow br label or br @label. */
2017 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
2019 if (exp
->X_op
== O_constant
)
2021 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 32767)
2023 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2029 as_bad (_("Displacement value of %ld is too large"),
2030 (long) exp
->X_add_number
);
2035 tinsn
->reloc
= BFD_RELOC_16_PCREL
;
2041 if (operand
->mode
!= M_REGISTER
)
2043 reg
= exp
->X_add_number
;
2044 INSERTU (opcode
, reg
, 15, 0);
2048 if (operand
->mode
!= M_REGISTER
)
2050 reg
= exp
->X_add_number
;
2051 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2052 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2053 INSERTU (opcode
, reg
, 15, 0);
2057 as_bad (_("Register must be Rn"));
2063 if (operand
->mode
!= M_REGISTER
)
2065 reg
= exp
->X_add_number
;
2066 INSERTU (opcode
, reg
, 20, 16);
2070 if (operand
->mode
!= M_REGISTER
)
2072 reg
= exp
->X_add_number
;
2073 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2074 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2075 INSERTU (opcode
, reg
, 20, 16);
2079 as_bad (_("Register must be Rn"));
2084 case 'S': /* Short immediate int. */
2085 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2087 if (exp
->X_op
== O_big
)
2090 as_bad (_("Floating point number not valid in expression"));
2094 if (exp
->X_op
== O_constant
)
2096 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 65535)
2098 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2104 as_bad (_("Signed immediate value %ld too large"),
2105 (long) exp
->X_add_number
);
2110 else if (exp
->X_op
== O_symbol
)
2112 if (operand
->mode
== M_HI
)
2114 tinsn
->reloc
= BFD_RELOC_HI16
;
2118 tinsn
->reloc
= BFD_RELOC_LO16
;
2123 /* Handle cases like ldi foo - $, ar0 where foo
2124 is a forward reference. Perhaps we should check
2125 for X_op == O_symbol and disallow things like
2127 tinsn
->reloc
= BFD_RELOC_16
;
2131 case 'T': /* 5-bit immediate value for tic4x stik. */
2132 if (!IS_CPU_TIC4X (tic4x_cpu
))
2134 if (operand
->mode
!= M_IMMED
)
2136 if (exp
->X_op
== O_constant
)
2138 if (exp
->X_add_number
< 16 && exp
->X_add_number
>= -16)
2140 INSERTS (opcode
, exp
->X_add_number
, 20, 16);
2146 as_bad (_("Immediate value of %ld is too large"),
2147 (long) exp
->X_add_number
);
2152 break; /* No relocations allowed. */
2154 case 'U': /* Unsigned integer immediate. */
2155 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2157 if (exp
->X_op
== O_constant
)
2159 if (exp
->X_add_number
< (1 << 16) && exp
->X_add_number
>= 0)
2161 INSERTU (opcode
, exp
->X_add_number
, 15, 0);
2167 as_bad (_("Unsigned immediate value %ld too large"),
2168 (long) exp
->X_add_number
);
2173 else if (exp
->X_op
== O_symbol
)
2175 if (operand
->mode
== M_HI
)
2176 tinsn
->reloc
= BFD_RELOC_HI16
;
2178 tinsn
->reloc
= BFD_RELOC_LO16
;
2183 tinsn
->reloc
= BFD_RELOC_16
;
2187 case 'V': /* Trap numbers (immediate field). */
2188 if (operand
->mode
!= M_IMMED
)
2190 if (exp
->X_op
== O_constant
)
2192 if (exp
->X_add_number
< 512 && IS_CPU_TIC4X (tic4x_cpu
))
2194 INSERTU (opcode
, exp
->X_add_number
, 8, 0);
2197 else if (exp
->X_add_number
< 32 && IS_CPU_TIC3X (tic4x_cpu
))
2199 INSERTU (opcode
, exp
->X_add_number
| 0x20, 4, 0);
2205 as_bad (_("Immediate value of %ld is too large"),
2206 (long) exp
->X_add_number
);
2211 break; /* No relocations allowed. */
2213 case 'W': /* Short immediate int (0--7). */
2214 if (!IS_CPU_TIC4X (tic4x_cpu
))
2216 if (operand
->mode
!= M_IMMED
)
2218 if (exp
->X_op
== O_big
)
2221 as_bad (_("Floating point number not valid in expression"));
2225 if (exp
->X_op
== O_constant
)
2227 if (exp
->X_add_number
>= -256 && exp
->X_add_number
<= 127)
2229 INSERTS (opcode
, exp
->X_add_number
, 7, 0);
2235 as_bad (_("Immediate value %ld too large"),
2236 (long) exp
->X_add_number
);
2241 tinsn
->reloc
= BFD_RELOC_16
;
2245 case 'X': /* Expansion register for tic4x. */
2246 if (operand
->mode
!= M_REGISTER
)
2248 reg
= exp
->X_add_number
;
2249 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2250 INSERTU (opcode
, reg
- REG_IVTP
, 4, 0);
2254 as_bad (_("Register must be ivtp or tvtp"));
2259 case 'Y': /* Address register for tic4x lda. */
2260 if (operand
->mode
!= M_REGISTER
)
2262 reg
= exp
->X_add_number
;
2263 if (reg
>= REG_AR0
&& reg
<= REG_SP
)
2264 INSERTU (opcode
, reg
, 20, 16);
2268 as_bad (_("Register must be address register"));
2273 case 'Z': /* Expansion register for tic4x. */
2274 if (operand
->mode
!= M_REGISTER
)
2276 reg
= exp
->X_add_number
;
2277 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2278 INSERTU (opcode
, reg
- REG_IVTP
, 20, 16);
2282 as_bad (_("Register must be ivtp or tvtp"));
2288 if (operand
->mode
!= M_INDIRECT
)
2290 INSERTS (opcode
, operand
->disp
, 7, 0);
2291 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2292 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
2295 case '|': /* treat as `,' if have ldi_ldi form. */
2296 if (tinsn
->parallel
)
2298 if (--num_operands
< 0)
2299 break; /* Too few operands. */
2301 if (operand
->mode
!= M_PARALLEL
)
2306 case ',': /* Another operand. */
2307 if (--num_operands
< 0)
2308 break; /* Too few operands. */
2310 exp
= &operand
->expr
;
2313 case ';': /* Another optional operand. */
2314 if (num_operands
== 1 || operand
[1].mode
== M_PARALLEL
)
2316 if (--num_operands
< 0)
2317 break; /* Too few operands. */
2319 exp
= &operand
->expr
;
2330 tic4x_insn_check (tic4x_insn_t
*tinsn
)
2333 if (!strcmp (tinsn
->name
, "lda"))
2335 if (tinsn
->num_operands
< 2 || tinsn
->num_operands
> 2)
2336 as_fatal ("Illegal internal LDA insn definition");
2338 if (tinsn
->operands
[0].mode
== M_REGISTER
2339 && tinsn
->operands
[1].mode
== M_REGISTER
2340 && tinsn
->operands
[0].expr
.X_add_number
== tinsn
->operands
[1].expr
.X_add_number
)
2341 as_bad (_("Source and destination register should not be equal"));
2343 else if (!strcmp (tinsn
->name
, "ldi_ldi")
2344 || !strcmp (tinsn
->name
, "ldi1_ldi2")
2345 || !strcmp (tinsn
->name
, "ldi2_ldi1")
2346 || !strcmp (tinsn
->name
, "ldf_ldf")
2347 || !strcmp (tinsn
->name
, "ldf1_ldf2")
2348 || !strcmp (tinsn
->name
, "ldf2_ldf1") )
2350 if (tinsn
->num_operands
< 4 || tinsn
->num_operands
> 5)
2351 as_fatal ("Illegal internal %s insn definition", tinsn
->name
);
2353 if (tinsn
->operands
[1].mode
== M_REGISTER
2354 && tinsn
->operands
[tinsn
->num_operands
-1].mode
== M_REGISTER
2355 && tinsn
->operands
[1].expr
.X_add_number
== tinsn
->operands
[tinsn
->num_operands
-1].expr
.X_add_number
)
2356 as_warn (_("Equal parallel destination registers, one result will be discarded"));
2361 tic4x_insn_output (tic4x_insn_t
*tinsn
)
2365 /* Grab another fragment for opcode. */
2366 dst
= frag_more (tinsn
->nchars
);
2368 /* Put out opcode word as a series of bytes in little endian order. */
2369 md_number_to_chars (dst
, tinsn
->opcode
, tinsn
->nchars
);
2371 /* Put out the symbol-dependent stuff. */
2372 if (tinsn
->reloc
!= NO_RELOC
)
2374 /* Where is the offset into the fragment for this instruction. */
2375 fix_new_exp (frag_now
,
2376 dst
- frag_now
->fr_literal
, /* where */
2377 tinsn
->nchars
, /* size */
2384 /* Parse the operands. */
2386 tic4x_operands_parse (char *s
, tic4x_operand_t
*operands
, int num_operands
)
2389 return num_operands
;
2392 s
= tic4x_operand_parse (s
, &operands
[num_operands
++]);
2393 while (num_operands
< TIC4X_OPERANDS_MAX
&& *s
++ == ',');
2395 if (num_operands
> TIC4X_OPERANDS_MAX
)
2397 as_bad (_("Too many operands scanned"));
2400 return num_operands
;
2403 /* Assemble a single instruction. Its label has already been handled
2404 by the generic front end. We just parse mnemonic and operands, and
2405 produce the bytes of data and relocation. */
2407 md_assemble (char *str
)
2414 tic4x_inst_t
*inst
; /* Instruction template. */
2415 tic4x_inst_t
*first_inst
;
2417 /* Scan for parallel operators */
2421 while (*s
&& *s
!= '|')
2424 if (*s
&& s
[1]=='|')
2428 as_bad (_("Parallel opcode cannot contain more than two instructions"));
2434 /* Lets take care of the first part of the parallel insn */
2439 /* .. and let the second run though here */
2443 if (str
&& insn
->parallel
)
2445 /* Find mnemonic (second part of parallel instruction). */
2447 /* Skip past instruction mnemonic. */
2448 while (*s
&& *s
!= ' ')
2450 if (*s
) /* Null terminate for hash_find. */
2451 *s
++ = '\0'; /* and skip past null. */
2452 len
= strlen (insn
->name
);
2453 snprintf (insn
->name
+ len
, TIC4X_NAME_MAX
- len
, "_%s", str
);
2455 insn
->operands
[insn
->num_operands
++].mode
= M_PARALLEL
;
2457 if ((i
= tic4x_operands_parse
2458 (s
, insn
->operands
, insn
->num_operands
)) < 0)
2464 insn
->num_operands
= i
;
2470 if ((insn
->inst
= (struct tic4x_inst
*)
2471 hash_find (tic4x_op_hash
, insn
->name
)) == NULL
)
2473 as_bad (_("Unknown opcode `%s'."), insn
->name
);
2483 ok
= tic4x_operands_match (inst
, insn
, 1);
2490 } while (!ok
&& !strcmp (inst
->name
, inst
[1].name
) && inst
++);
2494 tic4x_insn_check (insn
);
2495 tic4x_insn_output (insn
);
2500 tic4x_operands_match (first_inst
, insn
, 0);
2501 as_bad (_("Invalid operands for %s"), insn
->name
);
2504 as_bad (_("Invalid instruction %s"), insn
->name
);
2509 /* Find mnemonic. */
2511 while (*s
&& *s
!= ' ') /* Skip past instruction mnemonic. */
2513 if (*s
) /* Null terminate for hash_find. */
2514 *s
++ = '\0'; /* and skip past null. */
2515 strncpy (insn
->name
, str
, TIC4X_NAME_MAX
- 1);
2516 insn
->name
[TIC4X_NAME_MAX
- 1] = '\0';
2518 if ((i
= tic4x_operands_parse (s
, insn
->operands
, 0)) < 0)
2520 insn
->inst
= NULL
; /* Flag that error occurred. */
2525 insn
->num_operands
= i
;
2534 tic4x_cleanup (void)
2540 /* Turn a string in input_line_pointer into a floating point constant
2541 of type type, and store the appropriate bytes in *litP. The number
2542 of chars emitted is stored in *sizeP. An error message is
2543 returned, or NULL on OK. */
2546 md_atof (int type
, char *litP
, int *sizeP
)
2550 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2551 LITTLENUM_TYPE
*wordP
;
2556 case 's': /* .single */
2562 case 'd': /* .double */
2564 case 'f': /* .float */
2567 prec
= 2; /* 1 32-bit word */
2570 case 'i': /* .ieee */
2574 type
= 'f'; /* Rewrite type to be usable by atof_ieee(). */
2577 case 'e': /* .ldouble */
2579 prec
= 4; /* 2 32-bit words */
2585 return _("Unrecognized or unsupported floating point constant");
2589 t
= atof_ieee (input_line_pointer
, type
, words
);
2591 t
= tic4x_atof (input_line_pointer
, type
, words
);
2593 input_line_pointer
= t
;
2594 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
2596 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
2597 little endian byte order. */
2598 /* SES: However it is required to put the words (32-bits) out in the
2599 correct order, hence we write 2 and 2 littlenums in little endian
2600 order, while we keep the original order on successive words. */
2601 for (wordP
= words
; wordP
<(words
+prec
) ; wordP
+=2)
2603 if (wordP
< (words
+ prec
- 1)) /* Dump wordP[1] (if we have one). */
2605 md_number_to_chars (litP
, (valueT
) (wordP
[1]),
2606 sizeof (LITTLENUM_TYPE
));
2607 litP
+= sizeof (LITTLENUM_TYPE
);
2611 md_number_to_chars (litP
, (valueT
) (wordP
[0]),
2612 sizeof (LITTLENUM_TYPE
));
2613 litP
+= sizeof (LITTLENUM_TYPE
);
2619 md_apply_fix (fixS
*fixP
, valueT
*value
, segT seg ATTRIBUTE_UNUSED
)
2621 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
2622 valueT val
= *value
;
2624 switch (fixP
->fx_r_type
)
2626 case BFD_RELOC_HI16
:
2630 case BFD_RELOC_LO16
:
2637 switch (fixP
->fx_r_type
)
2643 case BFD_RELOC_24_PCREL
:
2647 case BFD_RELOC_16_PCREL
:
2648 case BFD_RELOC_LO16
:
2649 case BFD_RELOC_HI16
:
2656 as_bad (_("Bad relocation type: 0x%02x"), fixP
->fx_r_type
);
2660 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0) fixP
->fx_done
= 1;
2663 /* Should never be called for tic4x. */
2665 md_convert_frag (bfd
*headers ATTRIBUTE_UNUSED
,
2666 segT sec ATTRIBUTE_UNUSED
,
2667 fragS
*fragP ATTRIBUTE_UNUSED
)
2669 as_fatal ("md_convert_frag");
2672 /* Should never be called for tic4x. */
2674 md_create_short_jump (char *ptr ATTRIBUTE_UNUSED
,
2675 addressT from_addr ATTRIBUTE_UNUSED
,
2676 addressT to_addr ATTRIBUTE_UNUSED
,
2677 fragS
*frag ATTRIBUTE_UNUSED
,
2678 symbolS
*to_symbol ATTRIBUTE_UNUSED
)
2680 as_fatal ("md_create_short_jmp\n");
2683 /* Should never be called for tic4x. */
2685 md_create_long_jump (char *ptr ATTRIBUTE_UNUSED
,
2686 addressT from_addr ATTRIBUTE_UNUSED
,
2687 addressT to_addr ATTRIBUTE_UNUSED
,
2688 fragS
*frag ATTRIBUTE_UNUSED
,
2689 symbolS
*to_symbol ATTRIBUTE_UNUSED
)
2691 as_fatal ("md_create_long_jump\n");
2694 /* Should never be called for tic4x. */
2696 md_estimate_size_before_relax (fragS
*fragP ATTRIBUTE_UNUSED
,
2697 segT segtype ATTRIBUTE_UNUSED
)
2699 as_fatal ("md_estimate_size_before_relax\n");
2705 md_parse_option (int c
, const char *arg
)
2709 case OPTION_CPU
: /* cpu brand */
2710 if (TOLOWER (*arg
) == 'c')
2712 tic4x_cpu
= atoi (arg
);
2713 if (!IS_CPU_TIC3X (tic4x_cpu
) && !IS_CPU_TIC4X (tic4x_cpu
))
2714 as_warn (_("Unsupported processor generation %d"), tic4x_cpu
);
2717 case OPTION_REV
: /* cpu revision */
2718 tic4x_revision
= atoi (arg
);
2722 as_warn (_("Option -b is depreciated, please use -mbig"));
2724 case OPTION_BIG
: /* big model */
2725 tic4x_big_model
= 1;
2729 as_warn (_("Option -p is depreciated, please use -mmemparm"));
2731 case OPTION_MEMPARM
: /* push args */
2736 as_warn (_("Option -r is depreciated, please use -mregparm"));
2738 case OPTION_REGPARM
: /* register args */
2743 as_warn (_("Option -s is depreciated, please use -msmall"));
2745 case OPTION_SMALL
: /* small model */
2746 tic4x_big_model
= 0;
2753 case OPTION_LOWPOWER
:
2757 case OPTION_ENHANCED
:
2769 md_show_usage (FILE *stream
)
2772 _("\nTIC4X options:\n"
2773 " -mcpu=CPU -mCPU select architecture variant. CPU can be:\n"
2775 " 31 - TMS320C31, TMS320LC31\n"
2777 " 33 - TMS320VC33\n"
2780 " -mrev=REV set cpu hardware revision (integer numbers).\n"
2781 " Combinations of -mcpu and -mrev will enable/disable\n"
2782 " the appropriate options (-midle2, -mlowpower and\n"
2783 " -menhanced) according to the selected type\n"
2784 " -mbig select big memory model\n"
2785 " -msmall select small memory model (default)\n"
2786 " -mregparm select register parameters (default)\n"
2787 " -mmemparm select memory parameters\n"
2788 " -midle2 enable IDLE2 support\n"
2789 " -mlowpower enable LOPOWER and MAXSPEED support\n"
2790 " -menhanced enable enhanced opcode support\n"));
2793 /* This is called when a line is unrecognized. This is used to handle
2794 definitions of TI C3x tools style local labels $n where n is a single
2797 tic4x_unrecognized_line (int c
)
2802 if (c
!= '$' || ! ISDIGIT (input_line_pointer
[0]))
2805 s
= input_line_pointer
;
2807 /* Let's allow multiple digit local labels. */
2809 while (ISDIGIT (*s
))
2811 lab
= lab
* 10 + *s
- '0';
2815 if (dollar_label_defined (lab
))
2817 as_bad (_("Label \"$%d\" redefined"), lab
);
2821 define_dollar_label (lab
);
2822 colon (dollar_label_name (lab
, 0));
2823 input_line_pointer
= s
+ 1;
2828 /* Handle local labels peculiar to us referred to in an expression. */
2830 md_undefined_symbol (char *name
)
2832 /* Look for local labels of the form $n. */
2833 if (name
[0] == '$' && ISDIGIT (name
[1]))
2839 while (ISDIGIT ((unsigned char) *s
))
2841 lab
= lab
* 10 + *s
- '0';
2844 if (dollar_label_defined (lab
))
2846 name
= dollar_label_name (lab
, 0);
2847 symbolP
= symbol_find (name
);
2851 name
= dollar_label_name (lab
, 1);
2852 symbolP
= symbol_find_or_make (name
);
2860 /* Parse an operand that is machine-specific. */
2862 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
2866 /* Round up a section size to the appropriate boundary---do we need this? */
2868 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
2870 return size
; /* Byte (i.e., 32-bit) alignment is fine? */
2874 tic4x_pc_offset (unsigned int op
)
2876 /* Determine the PC offset for a C[34]x instruction.
2877 This could be simplified using some boolean algebra
2878 but at the expense of readability. */
2882 case 0x62: /* call (C4x) */
2883 case 0x64: /* rptb (C4x) */
2885 case 0x61: /* brd */
2886 case 0x63: /* laj */
2887 case 0x65: /* rptbd (C4x) */
2889 case 0x66: /* swi */
2896 switch ((op
& 0xffe00000) >> 20)
2898 case 0x6a0: /* bB */
2899 case 0x720: /* callB */
2900 case 0x740: /* trapB */
2903 case 0x6a2: /* bBd */
2904 case 0x6a6: /* bBat */
2905 case 0x6aa: /* bBaf */
2906 case 0x722: /* lajB */
2907 case 0x748: /* latB */
2908 case 0x798: /* rptbd */
2915 switch ((op
& 0xfe200000) >> 20)
2917 case 0x6e0: /* dbB */
2920 case 0x6e2: /* dbBd */
2930 /* Exactly what point is a PC-relative offset relative TO?
2931 With the C3x we have the following:
2932 DBcond, Bcond disp + PC + 1 => PC
2933 DBcondD, BcondD disp + PC + 3 => PC
2936 md_pcrel_from (fixS
*fixP
)
2941 buf
= (unsigned char *) fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2942 op
= (buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
2944 return ((fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) >> 2) +
2945 tic4x_pc_offset (op
);
2948 /* Fill the alignment area with NOP's on .text, unless fill-data
2951 tic4x_do_align (int alignment
,
2956 /* Because we are talking lwords, not bytes, adjust alignment to do words */
2959 if (alignment
!= 0 && !need_pass_2
)
2963 if (subseg_text_p (now_seg
))
2967 md_number_to_chars (nop
, TIC_NOP_OPCODE
, 4);
2968 frag_align_pattern (alignment
, nop
, sizeof (nop
), max
);
2971 frag_align (alignment
, 0, max
);
2974 frag_align (alignment
, *fill
, max
);
2976 frag_align_pattern (alignment
, fill
, len
, max
);
2979 /* Return 1 to skip the default alignment function */
2983 /* Look for and remove parallel instruction operator ||. */
2985 tic4x_start_line (void)
2987 char *s
= input_line_pointer
;
2991 /* If parallel instruction prefix found at start of line, skip it. */
2992 if (*input_line_pointer
== '|' && input_line_pointer
[1] == '|')
2997 input_line_pointer
++;
2998 *input_line_pointer
= ' ';
2999 /* So line counters get bumped. */
3000 input_line_pointer
[-1] = '\n';
3005 /* Write out the previous insn here */
3008 input_line_pointer
= s
;
3013 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixP
)
3017 reloc
= XNEW (arelent
);
3019 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
3020 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
3021 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
3022 reloc
->address
/= OCTETS_PER_BYTE
;
3023 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
3024 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
3026 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3027 _("Reloc %d not supported by object file format"),
3028 (int) fixP
->fx_r_type
);
3032 if (fixP
->fx_r_type
== BFD_RELOC_HI16
)
3033 reloc
->addend
= fixP
->fx_offset
;
3035 reloc
->addend
= fixP
->fx_addnumber
;