1 /* tc-tic4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
2 Copyright (C) 1997,1998, 2002, 2003, 2005, 2006, 2007, 2008, 2009
3 Free Software Foundation. Inc.
5 Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
7 This file is part of GAS, the GNU Assembler.
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to
21 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
22 Boston, MA 02110-1301, USA. */
27 o .align cannot handle fill-data-width larger than 0xFF/8-bits. It
28 should be possible to define a 32-bits pattern.
30 o .align fills all section with NOP's when used regardless if has
31 been used in .text or .data. (However the .align is primarily
32 intended used in .text sections. If you require something else,
33 use .align <size>,0x00)
35 o .align: Implement a 'bu' insn if the number of nop's exceeds 4
36 within the align frag. if(fragsize>4words) insert bu fragend+1
39 o .usect if has symbol on previous line not implemented
41 o .sym, .eos, .stag, .etag, .member not implemented
43 o Evaluation of constant floating point expressions (expr.c needs
46 o Support 'abc' constants (that is 0x616263)
49 #include "safe-ctype.h"
51 #include "opcode/tic4x.h"
55 /* OK, we accept a syntax similar to the other well known C30
56 assembly tools. With TIC4X_ALT_SYNTAX defined we are more
57 flexible, allowing a more Unix-like syntax: `%' in front of
58 register names, `#' in front of immediate constants, and
59 not requiring `@' in front of direct addresses. */
61 #define TIC4X_ALT_SYNTAX
63 /* Equal to MAX_PRECISION in atof-ieee.c. */
64 #define MAX_LITTLENUMS 6 /* (12 bytes) */
66 /* Handle of the inst mnemonic hash table. */
67 static struct hash_control
*tic4x_op_hash
= NULL
;
69 /* Handle asg pseudo. */
70 static struct hash_control
*tic4x_asg_hash
= NULL
;
72 static unsigned int tic4x_cpu
= 0; /* Default to TMS320C40. */
73 static unsigned int tic4x_revision
= 0; /* CPU revision */
74 static unsigned int tic4x_idle2
= 0; /* Idle2 support */
75 static unsigned int tic4x_lowpower
= 0; /* Lowpower support */
76 static unsigned int tic4x_enhanced
= 0; /* Enhanced opcode support */
77 static unsigned int tic4x_big_model
= 0; /* Default to small memory model. */
78 static unsigned int tic4x_reg_args
= 0; /* Default to args passed on stack. */
79 static unsigned long tic4x_oplevel
= 0; /* Opcode level */
81 #define OPTION_CPU 'm'
82 #define OPTION_BIG (OPTION_MD_BASE + 1)
83 #define OPTION_SMALL (OPTION_MD_BASE + 2)
84 #define OPTION_MEMPARM (OPTION_MD_BASE + 3)
85 #define OPTION_REGPARM (OPTION_MD_BASE + 4)
86 #define OPTION_IDLE2 (OPTION_MD_BASE + 5)
87 #define OPTION_LOWPOWER (OPTION_MD_BASE + 6)
88 #define OPTION_ENHANCED (OPTION_MD_BASE + 7)
89 #define OPTION_REV (OPTION_MD_BASE + 8)
91 CONST
char *md_shortopts
= "bm:prs";
92 struct option md_longopts
[] =
94 { "mcpu", required_argument
, NULL
, OPTION_CPU
},
95 { "mdsp", required_argument
, NULL
, OPTION_CPU
},
96 { "mbig", no_argument
, NULL
, OPTION_BIG
},
97 { "msmall", no_argument
, NULL
, OPTION_SMALL
},
98 { "mmemparm", no_argument
, NULL
, OPTION_MEMPARM
},
99 { "mregparm", no_argument
, NULL
, OPTION_REGPARM
},
100 { "midle2", no_argument
, NULL
, OPTION_IDLE2
},
101 { "mlowpower", no_argument
, NULL
, OPTION_LOWPOWER
},
102 { "menhanced", no_argument
, NULL
, OPTION_ENHANCED
},
103 { "mrev", required_argument
, NULL
, OPTION_REV
},
104 { NULL
, no_argument
, NULL
, 0 }
107 size_t md_longopts_size
= sizeof (md_longopts
);
112 M_UNKNOWN
, M_IMMED
, M_DIRECT
, M_REGISTER
, M_INDIRECT
,
113 M_IMMED_F
, M_PARALLEL
, M_HI
117 typedef struct tic4x_operand
119 tic4x_addr_mode_t mode
; /* Addressing mode. */
120 expressionS expr
; /* Expression. */
121 int disp
; /* Displacement for indirect addressing. */
122 int aregno
; /* Aux. register number. */
123 LITTLENUM_TYPE fwords
[MAX_LITTLENUMS
]; /* Float immed. number. */
127 typedef struct tic4x_insn
129 char name
[TIC4X_NAME_MAX
]; /* Mnemonic of instruction. */
130 unsigned int in_use
; /* True if in_use. */
131 unsigned int parallel
; /* True if parallel instruction. */
132 unsigned int nchars
; /* This is always 4 for the C30. */
133 unsigned long opcode
; /* Opcode number. */
134 expressionS exp
; /* Expression required for relocation. */
135 int reloc
; /* Relocation type required. */
136 int pcrel
; /* True if relocation PC relative. */
137 char *pname
; /* Name of instruction in parallel. */
138 unsigned int num_operands
; /* Number of operands in total. */
139 tic4x_inst_t
*inst
; /* Pointer to first template. */
140 tic4x_operand_t operands
[TIC4X_OPERANDS_MAX
];
144 static tic4x_insn_t the_insn
; /* Info about our instruction. */
145 static tic4x_insn_t
*insn
= &the_insn
;
147 static void tic4x_asg (int);
148 static void tic4x_bss (int);
149 static void tic4x_globl (int);
150 static void tic4x_cons (int);
151 static void tic4x_stringer (int);
152 static void tic4x_eval (int);
153 static void tic4x_newblock (int);
154 static void tic4x_sect (int);
155 static void tic4x_set (int);
156 static void tic4x_usect (int);
157 static void tic4x_version (int);
163 {"align", s_align_bytes
, 32},
164 {"ascii", tic4x_stringer
, 1},
165 {"asciz", tic4x_stringer
, 0},
166 {"asg", tic4x_asg
, 0},
167 {"block", s_space
, 4},
168 {"byte", tic4x_cons
, 1},
169 {"bss", tic4x_bss
, 0},
170 {"copy", s_include
, 0},
171 {"def", tic4x_globl
, 0},
172 {"equ", tic4x_set
, 0},
173 {"eval", tic4x_eval
, 0},
174 {"global", tic4x_globl
, 0},
175 {"globl", tic4x_globl
, 0},
176 {"hword", tic4x_cons
, 2},
177 {"ieee", float_cons
, 'i'},
178 {"int", tic4x_cons
, 4}, /* .int allocates 4 bytes. */
179 {"ldouble", float_cons
, 'e'},
180 {"newblock", tic4x_newblock
, 0},
181 {"ref", s_ignore
, 0}, /* All undefined treated as external. */
182 {"set", tic4x_set
, 0},
183 {"sect", tic4x_sect
, 1}, /* Define named section. */
184 {"space", s_space
, 4},
185 {"string", tic4x_stringer
, 0},
186 {"usect", tic4x_usect
, 0}, /* Reserve space in uninit. named sect. */
187 {"version", tic4x_version
, 0},
188 {"word", tic4x_cons
, 4}, /* .word allocates 4 bytes. */
189 {"xdef", tic4x_globl
, 0},
193 int md_short_jump_size
= 4;
194 int md_long_jump_size
= 4;
196 /* This array holds the chars that always start a comment. If the
197 pre-processor is disabled, these aren't very useful. */
198 #ifdef TIC4X_ALT_SYNTAX
199 const char comment_chars
[] = ";!";
201 const char comment_chars
[] = ";";
204 /* This array holds the chars that only start a comment at the beginning of
205 a line. If the line seems to have the form '# 123 filename'
206 .line and .file directives will appear in the pre-processed output.
207 Note that input_file.c hand checks for '#' at the beginning of the
208 first line of the input file. This is because the compiler outputs
209 #NO_APP at the beginning of its output.
210 Also note that comments like this one will always work. */
211 const char line_comment_chars
[] = "#*";
213 /* We needed an unused char for line separation to work around the
214 lack of macros, using sed and such. */
215 const char line_separator_chars
[] = "&";
217 /* Chars that can be used to separate mant from exp in floating point nums. */
218 const char EXP_CHARS
[] = "eE";
220 /* Chars that mean this number is a floating point constant. */
223 const char FLT_CHARS
[] = "fFilsS";
225 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
226 changed in read.c. Ideally it shouldn't have to know about it at
227 all, but nothing is ideal around here. */
229 /* Flonums returned here. */
230 extern FLONUM_TYPE generic_floating_point_number
;
232 /* Precision in LittleNums. */
233 #define MAX_PRECISION (4) /* Its a bit overkill for us, but the code
235 #define S_PRECISION (1) /* Short float constants 16-bit. */
236 #define F_PRECISION (2) /* Float and double types 32-bit. */
237 #define E_PRECISION (4) /* Extended precision, 64-bit (real 40-bit). */
240 /* Turn generic_floating_point_number into a real short/float/double. */
242 tic4x_gen_to_words (FLONUM_TYPE flonum
, LITTLENUM_TYPE
*words
, int precision
)
244 int return_value
= 0;
245 LITTLENUM_TYPE
*p
; /* Littlenum pointer. */
246 int mantissa_bits
; /* Bits in mantissa field. */
247 int exponent_bits
; /* Bits in exponent field. */
249 unsigned int sone
; /* Scaled one. */
250 unsigned int sfract
; /* Scaled fraction. */
251 unsigned int smant
; /* Scaled mantissa. */
253 unsigned int mover
; /* Mantissa overflow bits */
254 unsigned int rbit
; /* Round bit. */
255 int shift
; /* Shift count. */
257 /* NOTE: Svein Seldal <Svein@dev.seldal.com>
258 The code in this function is altered slightly to support floats
259 with 31-bits mantissas, thus the documentation below may be a
260 little bit inaccurate.
262 By Michael P. Hayes <m.hayes@elec.canterbury.ac.nz>
263 Here is how a generic floating point number is stored using
264 flonums (an extension of bignums) where p is a pointer to an
267 For example 2e-3 is stored with exp = -4 and
274 with low = &bits[2], high = &bits[5], and leader = &bits[5].
276 This number can be written as
277 0x0083126e978d4fde.00000000 * 65536**-4 or
278 0x0.0083126e978d4fde * 65536**0 or
279 0x0.83126e978d4fde * 2**-8 = 2e-3
281 Note that low points to the 65536**0 littlenum (bits[2]) and
282 leader points to the most significant non-zero littlenum
285 TMS320C3X floating point numbers are a bit of a strange beast.
286 The 32-bit flavour has the 8 MSBs representing the exponent in
287 twos complement format (-128 to +127). There is then a sign bit
288 followed by 23 bits of mantissa. The mantissa is expressed in
289 twos complement format with the binary point after the most
290 significant non sign bit. The bit after the binary point is
291 suppressed since it is the complement of the sign bit. The
292 effective mantissa is thus 24 bits. Zero is represented by an
295 The 16-bit flavour has the 4 MSBs representing the exponent in
296 twos complement format (-8 to +7). There is then a sign bit
297 followed by 11 bits of mantissa. The mantissa is expressed in
298 twos complement format with the binary point after the most
299 significant non sign bit. The bit after the binary point is
300 suppressed since it is the complement of the sign bit. The
301 effective mantissa is thus 12 bits. Zero is represented by an
302 exponent of -8. For example,
304 number norm mant m x e s i fraction f
305 +0.500 => 1.00000000000 -1 -1 0 1 .00000000000 (1 + 0) * 2^(-1)
306 +0.999 => 1.11111111111 -1 -1 0 1 .11111111111 (1 + 0.99) * 2^(-1)
307 +1.000 => 1.00000000000 0 0 0 1 .00000000000 (1 + 0) * 2^(0)
308 +1.500 => 1.10000000000 0 0 0 1 .10000000000 (1 + 0.5) * 2^(0)
309 +1.999 => 1.11111111111 0 0 0 1 .11111111111 (1 + 0.9) * 2^(0)
310 +2.000 => 1.00000000000 1 1 0 1 .00000000000 (1 + 0) * 2^(1)
311 +4.000 => 1.00000000000 2 2 0 1 .00000000000 (1 + 0) * 2^(2)
312 -0.500 => 1.00000000000 -1 -1 1 0 .10000000000 (-2 + 0) * 2^(-2)
313 -1.000 => 1.00000000000 0 -1 1 0 .00000000000 (-2 + 0) * 2^(-1)
314 -1.500 => 1.10000000000 0 0 1 0 .10000000000 (-2 + 0.5) * 2^(0)
315 -1.999 => 1.11111111111 0 0 1 0 .00000000001 (-2 + 0.11) * 2^(0)
316 -2.000 => 1.00000000000 1 1 1 0 .00000000000 (-2 + 0) * 2^(0)
317 -4.000 => 1.00000000000 2 1 1 0 .00000000000 (-2 + 0) * 2^(1)
319 where e is the exponent, s is the sign bit, i is the implied bit,
320 and f is the fraction stored in the mantissa field.
322 num = (1 + f) * 2^x = m * 2^e if s = 0
323 num = (-2 + f) * 2^x = -m * 2^e if s = 1
324 where 0 <= f < 1.0 and 1.0 <= m < 2.0
326 The fraction (f) and exponent (e) fields for the TMS320C3X format
327 can be derived from the normalised mantissa (m) and exponent (x) using:
329 f = m - 1, e = x if s = 0
330 f = 2 - m, e = x if s = 1 and m != 1.0
331 f = 0, e = x - 1 if s = 1 and m = 1.0
332 f = 0, e = -8 if m = 0
335 OK, the other issue we have to consider is rounding since the
336 mantissa has a much higher potential precision than what we can
337 represent. To do this we add half the smallest storable fraction.
338 We then have to renormalise the number to allow for overflow.
340 To convert a generic flonum into a TMS320C3X floating point
341 number, here's what we try to do....
343 The first thing is to generate a normalised mantissa (m) where
344 1.0 <= m < 2 and to convert the exponent from base 16 to base 2.
345 We desire the binary point to be placed after the most significant
346 non zero bit. This process is done in two steps: firstly, the
347 littlenum with the most significant non zero bit is located (this
348 is done for us since leader points to this littlenum) and the
349 binary point (which is currently after the LSB of the littlenum
350 pointed to by low) is moved to before the MSB of the littlenum
351 pointed to by leader. This requires the exponent to be adjusted
352 by leader - low + 1. In the earlier example, the new exponent is
353 thus -4 + (5 - 2 + 1) = 0 (base 65536). We now need to convert
354 the exponent to base 2 by multiplying the exponent by 16 (log2
355 65536). The exponent base 2 is thus also zero.
357 The second step is to hunt for the most significant non zero bit
358 in the leader littlenum. We do this by left shifting a copy of
359 the leader littlenum until bit 16 is set (0x10000) and counting
360 the number of shifts, S, required. The number of shifts then has to
361 be added to correct the exponent (base 2). For our example, this
362 will require 9 shifts and thus our normalised exponent (base 2) is
363 0 + 9 = 9. Note that the worst case scenario is when the leader
364 littlenum is 1, thus requiring 16 shifts.
366 We now have to left shift the other littlenums by the same amount,
367 propagating the shifted bits into the more significant littlenums.
368 To save a lot of unnecessary shifting we only have to consider
369 two or three littlenums, since the greatest number of mantissa
370 bits required is 24 + 1 rounding bit. While two littlenums
371 provide 32 bits of precision, the most significant littlenum
372 may only contain a single significant bit and thus an extra
373 littlenum is required.
375 Denoting the number of bits in the fraction field as F, we require
376 G = F + 2 bits (one extra bit is for rounding, the other gets
377 suppressed). Say we required S shifts to find the most
378 significant bit in the leader littlenum, the number of left shifts
379 required to move this bit into bit position G - 1 is L = G + S - 17.
380 Note that this shift count may be negative for the short floating
381 point flavour (where F = 11 and thus G = 13 and potentially S < 3).
382 If L > 0 we have to shunt the next littlenum into position. Bit
383 15 (the MSB) of the next littlenum needs to get moved into position
384 L - 1 (If L > 15 we need all the bits of this littlenum and
385 some more from the next one.). We subtract 16 from L and use this
386 as the left shift count; the resultant value we or with the
387 previous result. If L > 0, we repeat this operation. */
389 if (precision
!= S_PRECISION
)
391 if (precision
== E_PRECISION
)
392 words
[2] = words
[3] = 0x0000;
394 /* 0.0e0 or NaN seen. */
395 if (flonum
.low
> flonum
.leader
/* = 0.0e0 */
396 || flonum
.sign
== 0) /* = NaN */
399 as_bad (_("Nan, using zero."));
404 if (flonum
.sign
== 'P')
406 /* +INF: Replace with maximum float. */
407 if (precision
== S_PRECISION
)
414 if (precision
== E_PRECISION
)
421 else if (flonum
.sign
== 'N')
423 /* -INF: Replace with maximum float. */
424 if (precision
== S_PRECISION
)
428 if (precision
== E_PRECISION
)
433 exponent
= (flonum
.exponent
+ flonum
.leader
- flonum
.low
+ 1) * 16;
435 if (!(tmp
= *flonum
.leader
))
436 abort (); /* Hmmm. */
437 shift
= 0; /* Find position of first sig. bit. */
440 exponent
-= (16 - shift
); /* Adjust exponent. */
442 if (precision
== S_PRECISION
) /* Allow 1 rounding bit. */
447 else if(precision
== F_PRECISION
)
452 else /* E_PRECISION */
458 shift
= mantissa_bits
- shift
;
463 /* Store the mantissa data into smant and the roundbit into rbit */
464 for (p
= flonum
.leader
; p
>= flonum
.low
&& shift
> -16; p
--)
466 tmp
= shift
>= 0 ? *p
<< shift
: *p
>> -shift
;
467 rbit
= shift
< 0 ? ((*p
>> (-shift
-1)) & 0x1) : 0;
472 /* OK, we've got our scaled mantissa so let's round it up */
475 /* If the mantissa is going to overflow when added, lets store
476 the extra bit in mover. -- A special case exists when
477 mantissa_bits is 31 (E_PRECISION). Then the first test cannot
478 be trusted, as result is host-dependent, thus the second
480 if( smant
== ((unsigned)(1<<(mantissa_bits
+1))-1)
481 || smant
== (unsigned)-1 ) /* This is to catch E_PRECISION cases */
486 /* Get the scaled one value */
487 sone
= (1 << (mantissa_bits
));
489 /* The number may be unnormalised so renormalise it... */
493 smant
|= sone
; /* Insert the bit from mover into smant */
497 /* The binary point is now between bit positions 11 and 10 or 23 and 22,
498 i.e., between mantissa_bits - 1 and mantissa_bits - 2 and the
499 bit at mantissa_bits - 1 should be set. */
501 abort (); /* Ooops. */
503 if (flonum
.sign
== '+')
504 sfract
= smant
- sone
; /* smant - 1.0. */
507 /* This seems to work. */
515 sfract
= -smant
& (sone
-1); /* 2.0 - smant. */
517 sfract
|= sone
; /* Insert sign bit. */
520 if (abs (exponent
) >= (1 << (exponent_bits
- 1)))
521 as_bad (_("Cannot represent exponent in %d bits"), exponent_bits
);
523 /* Force exponent to fit in desired field width. */
524 exponent
&= (1 << (exponent_bits
)) - 1;
526 if (precision
== E_PRECISION
)
528 /* Map the float part first (100% equal format as F_PRECISION) */
529 words
[0] = exponent
<< (mantissa_bits
+1-24);
530 words
[0] |= sfract
>> 24;
531 words
[1] = sfract
>> 8;
533 /* Map the mantissa in the next */
534 words
[2] = sfract
>> 16;
535 words
[3] = sfract
& 0xffff;
539 /* Insert the exponent data into the word */
540 sfract
|= exponent
<< (mantissa_bits
+1);
542 if (precision
== S_PRECISION
)
546 words
[0] = sfract
>> 16;
547 words
[1] = sfract
& 0xffff;
554 /* Returns pointer past text consumed. */
556 tic4x_atof (char *str
, char what_kind
, LITTLENUM_TYPE
*words
)
558 /* Extra bits for zeroed low-order bits. The 1st MAX_PRECISION are
559 zeroed, the last contain flonum bits. */
560 static LITTLENUM_TYPE bits
[MAX_PRECISION
+ MAX_PRECISION
+ GUARD
];
562 /* Number of 16-bit words in the format. */
564 FLONUM_TYPE save_gen_flonum
;
566 /* We have to save the generic_floating_point_number because it
567 contains storage allocation about the array of LITTLENUMs where
568 the value is actually stored. We will allocate our own array of
569 littlenums below, but have to restore the global one on exit. */
570 save_gen_flonum
= generic_floating_point_number
;
573 generic_floating_point_number
.low
= bits
+ MAX_PRECISION
;
574 generic_floating_point_number
.high
= NULL
;
575 generic_floating_point_number
.leader
= NULL
;
576 generic_floating_point_number
.exponent
= 0;
577 generic_floating_point_number
.sign
= '\0';
579 /* Use more LittleNums than seems necessary: the highest flonum may
580 have 15 leading 0 bits, so could be useless. */
582 memset (bits
, '\0', sizeof (LITTLENUM_TYPE
) * MAX_PRECISION
);
588 precision
= S_PRECISION
;
595 precision
= F_PRECISION
;
600 precision
= E_PRECISION
;
604 as_bad (_("Invalid floating point number"));
608 generic_floating_point_number
.high
609 = generic_floating_point_number
.low
+ precision
- 1 + GUARD
;
611 if (atof_generic (&return_value
, ".", EXP_CHARS
,
612 &generic_floating_point_number
))
614 as_bad (_("Invalid floating point number"));
618 tic4x_gen_to_words (generic_floating_point_number
,
621 /* Restore the generic_floating_point_number's storage alloc (and
623 generic_floating_point_number
= save_gen_flonum
;
629 tic4x_insert_reg (char *regname
, int regnum
)
634 symbol_table_insert (symbol_new (regname
, reg_section
, (valueT
) regnum
,
635 &zero_address_frag
));
636 for (i
= 0; regname
[i
]; i
++)
637 buf
[i
] = ISLOWER (regname
[i
]) ? TOUPPER (regname
[i
]) : regname
[i
];
640 symbol_table_insert (symbol_new (buf
, reg_section
, (valueT
) regnum
,
641 &zero_address_frag
));
645 tic4x_insert_sym (char *symname
, int value
)
649 symbolP
= symbol_new (symname
, absolute_section
,
650 (valueT
) value
, &zero_address_frag
);
651 SF_SET_LOCAL (symbolP
);
652 symbol_table_insert (symbolP
);
656 tic4x_expression (char *str
, expressionS
*exp
)
661 t
= input_line_pointer
; /* Save line pointer. */
662 input_line_pointer
= str
;
664 s
= input_line_pointer
;
665 input_line_pointer
= t
; /* Restore line pointer. */
666 return s
; /* Return pointer to where parsing stopped. */
670 tic4x_expression_abs (char *str
, offsetT
*value
)
675 t
= input_line_pointer
; /* Save line pointer. */
676 input_line_pointer
= str
;
677 *value
= get_absolute_expression ();
678 s
= input_line_pointer
;
679 input_line_pointer
= t
; /* Restore line pointer. */
684 tic4x_emit_char (char c
, int b
)
688 exp
.X_op
= O_constant
;
689 exp
.X_add_number
= c
;
694 tic4x_seg_alloc (char *name ATTRIBUTE_UNUSED
,
695 segT seg ATTRIBUTE_UNUSED
,
699 /* Note that the size is in words
700 so we multiply it by 4 to get the number of bytes to allocate. */
702 /* If we have symbol: .usect ".fred", size etc.,
703 the symbol needs to point to the first location reserved
710 p
= frag_var (rs_fill
, 1, 1, (relax_substateT
) 0,
712 size
* OCTETS_PER_BYTE
, (char *) 0);
717 /* .asg ["]character-string["], symbol */
719 tic4x_asg (int x ATTRIBUTE_UNUSED
)
727 str
= input_line_pointer
;
729 /* Skip string expression. */
730 while (*input_line_pointer
!= ',' && *input_line_pointer
)
731 input_line_pointer
++;
732 if (*input_line_pointer
!= ',')
734 as_bad (_("Comma expected\n"));
737 *input_line_pointer
++ = '\0';
738 name
= input_line_pointer
;
739 c
= get_symbol_end (); /* Get terminator. */
740 tmp
= xmalloc (strlen (str
) + 1);
743 tmp
= xmalloc (strlen (name
) + 1);
746 if (hash_find (tic4x_asg_hash
, name
))
747 hash_replace (tic4x_asg_hash
, name
, (void *) str
);
749 hash_insert (tic4x_asg_hash
, name
, (void *) str
);
750 *input_line_pointer
= c
;
751 demand_empty_rest_of_line ();
754 /* .bss symbol, size */
756 tic4x_bss (int x ATTRIBUTE_UNUSED
)
763 subsegT current_subseg
;
766 current_seg
= now_seg
; /* Save current seg. */
767 current_subseg
= now_subseg
; /* Save current subseg. */
770 name
= input_line_pointer
;
771 c
= get_symbol_end (); /* Get terminator. */
774 as_bad (_(".bss size argument missing\n"));
779 tic4x_expression_abs (++input_line_pointer
, &size
);
782 as_bad (_(".bss size %ld < 0!"), (long) size
);
785 subseg_set (bss_section
, 0);
786 symbolP
= symbol_find_or_make (name
);
788 if (S_GET_SEGMENT (symbolP
) == bss_section
)
789 symbol_get_frag (symbolP
)->fr_symbol
= 0;
791 symbol_set_frag (symbolP
, frag_now
);
793 p
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
,
794 size
* OCTETS_PER_BYTE
, (char *) 0);
795 *p
= 0; /* Fill char. */
797 S_SET_SEGMENT (symbolP
, bss_section
);
799 /* The symbol may already have been created with a preceding
800 ".globl" directive -- be careful not to step on storage class
801 in that case. Otherwise, set it to static. */
802 if (S_GET_STORAGE_CLASS (symbolP
) != C_EXT
)
803 S_SET_STORAGE_CLASS (symbolP
, C_STAT
);
805 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
806 demand_empty_rest_of_line ();
810 tic4x_globl (int ignore ATTRIBUTE_UNUSED
)
818 name
= input_line_pointer
;
819 c
= get_symbol_end ();
820 symbolP
= symbol_find_or_make (name
);
821 *input_line_pointer
= c
;
823 S_SET_STORAGE_CLASS (symbolP
, C_EXT
);
824 S_SET_EXTERNAL (symbolP
);
827 input_line_pointer
++;
829 if (*input_line_pointer
== '\n')
835 demand_empty_rest_of_line ();
838 /* Handle .byte, .word. .int, .long */
840 tic4x_cons (int bytes
)
842 register unsigned int c
;
846 if (*input_line_pointer
== '"')
848 input_line_pointer
++;
849 while (is_a_char (c
= next_char_of_string ()))
850 tic4x_emit_char (c
, 4);
851 know (input_line_pointer
[-1] == '\"');
857 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
858 if (exp
.X_op
== O_constant
)
863 exp
.X_add_number
&= 255;
866 exp
.X_add_number
&= 65535;
870 /* Perhaps we should disallow .byte and .hword with
871 a non constant expression that will require relocation. */
875 while (*input_line_pointer
++ == ',');
877 input_line_pointer
--; /* Put terminator back into stream. */
878 demand_empty_rest_of_line ();
881 /* Handle .ascii, .asciz, .string */
883 tic4x_stringer (int append_zero
)
886 register unsigned int c
;
892 if (*input_line_pointer
== '"')
894 input_line_pointer
++;
895 while (is_a_char (c
= next_char_of_string ()))
897 tic4x_emit_char (c
, 1);
903 tic4x_emit_char (c
, 1);
907 know (input_line_pointer
[-1] == '\"');
913 input_line_pointer
= tic4x_expression (input_line_pointer
, &exp
);
914 if (exp
.X_op
!= O_constant
)
916 as_bad (_("Non-constant symbols not allowed\n"));
919 exp
.X_add_number
&= 255; /* Limit numeber to 8-bit */
924 while (*input_line_pointer
++ == ',');
926 /* Fill out the rest of the expression with 0's to fill up a full word */
928 tic4x_emit_char (0, 4-(bytes
&0x3));
930 input_line_pointer
--; /* Put terminator back into stream. */
931 demand_empty_rest_of_line ();
934 /* .eval expression, symbol */
936 tic4x_eval (int x ATTRIBUTE_UNUSED
)
944 tic4x_expression_abs (input_line_pointer
, &value
);
945 if (*input_line_pointer
++ != ',')
947 as_bad (_("Symbol missing\n"));
950 name
= input_line_pointer
;
951 c
= get_symbol_end (); /* Get terminator. */
952 demand_empty_rest_of_line ();
953 tic4x_insert_sym (name
, value
);
956 /* Reset local labels. */
958 tic4x_newblock (int x ATTRIBUTE_UNUSED
)
960 dollar_label_clear ();
963 /* .sect "section-name" [, value] */
964 /* .sect ["]section-name[:subsection-name]["] [, value] */
966 tic4x_sect (int x ATTRIBUTE_UNUSED
)
970 char *subsection_name
;
976 if (*input_line_pointer
== '"')
977 input_line_pointer
++;
978 section_name
= input_line_pointer
;
979 c
= get_symbol_end (); /* Get terminator. */
980 input_line_pointer
++; /* Skip null symbol terminator. */
981 name
= xmalloc (input_line_pointer
- section_name
+ 1);
982 strcpy (name
, section_name
);
984 /* TI C from version 5.0 allows a section name to contain a
985 subsection name as well. The subsection name is separated by a
986 ':' from the section name. Currently we scan the subsection
988 Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>. */
991 subsection_name
= input_line_pointer
;
992 c
= get_symbol_end (); /* Get terminator. */
993 input_line_pointer
++; /* Skip null symbol terminator. */
994 as_warn (_(".sect: subsection name ignored"));
997 /* We might still have a '"' to discard, but the character after a
998 symbol name will be overwritten with a \0 by get_symbol_end()
1002 input_line_pointer
=
1003 tic4x_expression_abs (input_line_pointer
, &num
);
1004 else if (*input_line_pointer
== ',')
1006 input_line_pointer
=
1007 tic4x_expression_abs (++input_line_pointer
, &num
);
1012 seg
= subseg_new (name
, num
);
1013 if (line_label
!= NULL
)
1015 S_SET_SEGMENT (line_label
, seg
);
1016 symbol_set_frag (line_label
, frag_now
);
1019 if (bfd_get_section_flags (stdoutput
, seg
) == SEC_NO_FLAGS
)
1021 if (!bfd_set_section_flags (stdoutput
, seg
, SEC_DATA
))
1022 as_warn (_("Error setting flags for \"%s\": %s"), name
,
1023 bfd_errmsg (bfd_get_error ()));
1026 /* If the last character overwritten by get_symbol_end() was an
1027 end-of-line, we must restore it or the end of the line will not be
1028 recognised and scanning extends into the next line, stopping with
1029 an error (blame Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>
1030 if this is not true). */
1031 if (is_end_of_line
[(unsigned char) c
])
1032 *(--input_line_pointer
) = c
;
1034 demand_empty_rest_of_line ();
1037 /* symbol[:] .set value or .set symbol, value */
1039 tic4x_set (int x ATTRIBUTE_UNUSED
)
1044 if ((symbolP
= line_label
) == NULL
)
1049 name
= input_line_pointer
;
1050 c
= get_symbol_end (); /* Get terminator. */
1053 as_bad (_(".set syntax invalid\n"));
1054 ignore_rest_of_line ();
1057 ++input_line_pointer
;
1058 symbolP
= symbol_find_or_make (name
);
1061 symbol_table_insert (symbolP
);
1063 pseudo_set (symbolP
);
1064 demand_empty_rest_of_line ();
1067 /* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
1069 tic4x_usect (int x ATTRIBUTE_UNUSED
)
1075 offsetT size
, alignment_flag
;
1077 subsegT current_subseg
;
1079 current_seg
= now_seg
; /* save current seg. */
1080 current_subseg
= now_subseg
; /* save current subseg. */
1083 if (*input_line_pointer
== '"')
1084 input_line_pointer
++;
1085 section_name
= input_line_pointer
;
1086 c
= get_symbol_end (); /* Get terminator. */
1087 input_line_pointer
++; /* Skip null symbol terminator. */
1088 name
= xmalloc (input_line_pointer
- section_name
+ 1);
1089 strcpy (name
, section_name
);
1092 input_line_pointer
=
1093 tic4x_expression_abs (input_line_pointer
, &size
);
1094 else if (*input_line_pointer
== ',')
1096 input_line_pointer
=
1097 tic4x_expression_abs (++input_line_pointer
, &size
);
1102 /* Read a possibly present third argument (alignment flag) [VK]. */
1103 if (*input_line_pointer
== ',')
1105 input_line_pointer
=
1106 tic4x_expression_abs (++input_line_pointer
, &alignment_flag
);
1111 as_warn (_(".usect: non-zero alignment flag ignored"));
1113 seg
= subseg_new (name
, 0);
1114 if (line_label
!= NULL
)
1116 S_SET_SEGMENT (line_label
, seg
);
1117 symbol_set_frag (line_label
, frag_now
);
1118 S_SET_VALUE (line_label
, frag_now_fix ());
1120 seg_info (seg
)->bss
= 1; /* Uninitialised data. */
1121 if (!bfd_set_section_flags (stdoutput
, seg
, SEC_ALLOC
))
1122 as_warn (_("Error setting flags for \"%s\": %s"), name
,
1123 bfd_errmsg (bfd_get_error ()));
1124 tic4x_seg_alloc (name
, seg
, size
, line_label
);
1126 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1127 S_SET_STORAGE_CLASS (line_label
, C_STAT
);
1129 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
1130 demand_empty_rest_of_line ();
1133 /* .version cpu-version. */
1135 tic4x_version (int x ATTRIBUTE_UNUSED
)
1139 input_line_pointer
=
1140 tic4x_expression_abs (input_line_pointer
, &temp
);
1141 if (!IS_CPU_TIC3X (temp
) && !IS_CPU_TIC4X (temp
))
1142 as_bad (_("This assembler does not support processor generation %ld"),
1145 if (tic4x_cpu
&& temp
!= (offsetT
) tic4x_cpu
)
1146 as_warn (_("Changing processor generation on fly not supported..."));
1148 demand_empty_rest_of_line ();
1152 tic4x_init_regtable (void)
1156 for (i
= 0; i
< tic3x_num_registers
; i
++)
1157 tic4x_insert_reg (tic3x_registers
[i
].name
,
1158 tic3x_registers
[i
].regno
);
1160 if (IS_CPU_TIC4X (tic4x_cpu
))
1162 /* Add additional Tic4x registers, overriding some C3x ones. */
1163 for (i
= 0; i
< tic4x_num_registers
; i
++)
1164 tic4x_insert_reg (tic4x_registers
[i
].name
,
1165 tic4x_registers
[i
].regno
);
1170 tic4x_init_symbols (void)
1172 /* The TI tools accept case insensitive versions of these symbols,
1177 .TMS320xx 30,31,32,40,or 44 set according to -v flag
1178 .C3X or .C3x 1 or 0 1 if -v30,-v31,or -v32
1179 .C30 1 or 0 1 if -v30
1180 .C31 1 or 0 1 if -v31
1181 .C32 1 or 0 1 if -v32
1182 .C4X or .C4x 1 or 0 1 if -v40, or -v44
1183 .C40 1 or 0 1 if -v40
1184 .C44 1 or 0 1 if -v44
1186 .REGPARM 1 or 0 1 if -mr option used
1187 .BIGMODEL 1 or 0 1 if -mb option used
1189 These symbols are currently supported but will be removed in a
1191 .TMS320C30 1 or 0 1 if -v30,-v31,or -v32
1192 .TMS320C31 1 or 0 1 if -v31
1193 .TMS320C32 1 or 0 1 if -v32
1194 .TMS320C40 1 or 0 1 if -v40, or -v44
1195 .TMS320C44 1 or 0 1 if -v44
1197 Source: TI: TMS320C3x/C4x Assembly Language Tools User's Guide,
1198 1997, SPRU035C, p. 3-17/3-18. */
1199 tic4x_insert_sym (".REGPARM", tic4x_reg_args
);
1200 tic4x_insert_sym (".MEMPARM", !tic4x_reg_args
);
1201 tic4x_insert_sym (".BIGMODEL", tic4x_big_model
);
1202 tic4x_insert_sym (".C30INTERRUPT", 0);
1203 tic4x_insert_sym (".TMS320xx", tic4x_cpu
== 0 ? 40 : tic4x_cpu
);
1204 tic4x_insert_sym (".C3X", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1205 tic4x_insert_sym (".C3x", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1206 tic4x_insert_sym (".C4X", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1207 tic4x_insert_sym (".C4x", tic4x_cpu
== 0 || tic4x_cpu
== 40 || tic4x_cpu
== 44);
1208 /* Do we need to have the following symbols also in lower case? */
1209 tic4x_insert_sym (".TMS320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1210 tic4x_insert_sym (".tms320C30", tic4x_cpu
== 30 || tic4x_cpu
== 31 || tic4x_cpu
== 32 || tic4x_cpu
== 33);
1211 tic4x_insert_sym (".TMS320C31", tic4x_cpu
== 31);
1212 tic4x_insert_sym (".tms320C31", tic4x_cpu
== 31);
1213 tic4x_insert_sym (".TMS320C32", tic4x_cpu
== 32);
1214 tic4x_insert_sym (".tms320C32", tic4x_cpu
== 32);
1215 tic4x_insert_sym (".TMS320C33", tic4x_cpu
== 33);
1216 tic4x_insert_sym (".tms320C33", tic4x_cpu
== 33);
1217 tic4x_insert_sym (".TMS320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1218 tic4x_insert_sym (".tms320C40", tic4x_cpu
== 40 || tic4x_cpu
== 44 || tic4x_cpu
== 0);
1219 tic4x_insert_sym (".TMS320C44", tic4x_cpu
== 44);
1220 tic4x_insert_sym (".tms320C44", tic4x_cpu
== 44);
1221 tic4x_insert_sym (".TMX320C40", 0); /* C40 first pass silicon ? */
1222 tic4x_insert_sym (".tmx320C40", 0);
1225 /* Insert a new instruction template into hash table. */
1227 tic4x_inst_insert (const tic4x_inst_t
*inst
)
1229 static char prev_name
[16];
1230 const char *retval
= NULL
;
1232 /* Only insert the first name if have several similar entries. */
1233 if (!strcmp (inst
->name
, prev_name
) || inst
->name
[0] == '\0')
1236 retval
= hash_insert (tic4x_op_hash
, inst
->name
, (void *) inst
);
1238 fprintf (stderr
, "internal error: can't hash `%s': %s\n",
1239 inst
->name
, retval
);
1241 strcpy (prev_name
, inst
->name
);
1242 return retval
== NULL
;
1245 /* Make a new instruction template. */
1246 static tic4x_inst_t
*
1247 tic4x_inst_make (char *name
, unsigned long opcode
, char *args
)
1249 static tic4x_inst_t
*insts
= NULL
;
1250 static char *names
= NULL
;
1251 static int iindex
= 0;
1255 /* Allocate memory to store name strings. */
1256 names
= (char *) xmalloc (sizeof (char) * 8192);
1257 /* Allocate memory for additional insts. */
1258 insts
= (tic4x_inst_t
*)
1259 xmalloc (sizeof (tic4x_inst_t
) * 1024);
1261 insts
[iindex
].name
= names
;
1262 insts
[iindex
].opcode
= opcode
;
1263 insts
[iindex
].opmask
= 0xffffffff;
1264 insts
[iindex
].args
= args
;
1272 return &insts
[iindex
- 1];
1275 /* Add instruction template, creating dynamic templates as required. */
1277 tic4x_inst_add (const tic4x_inst_t
*insts
)
1279 char *s
= insts
->name
;
1287 /* We do not care about INSNs that is not a part of our
1289 if ((insts
->oplevel
& tic4x_oplevel
) == 0)
1298 /* Dynamically create all the conditional insts. */
1299 for (i
= 0; i
< tic4x_num_conds
; i
++)
1303 char *c
= tic4x_conds
[i
].name
;
1313 /* If instruction found then have already processed it. */
1314 if (hash_find (tic4x_op_hash
, name
))
1319 inst
= tic4x_inst_make (name
, insts
[k
].opcode
+
1320 (tic4x_conds
[i
].cond
<<
1321 (*s
== 'B' ? 16 : 23)),
1323 if (k
== 0) /* Save strcmp() with following func. */
1324 ok
&= tic4x_inst_insert (inst
);
1327 while (!strcmp (insts
->name
,
1334 return tic4x_inst_insert (insts
);
1344 /* This function is called once, at assembler startup time. It should
1345 set up all the tables, etc., that the MD part of the assembler will
1353 /* Setup the proper opcode level according to the
1354 commandline parameters */
1355 tic4x_oplevel
= OP_C3X
;
1357 if ( IS_CPU_TIC4X(tic4x_cpu
) )
1358 tic4x_oplevel
|= OP_C4X
;
1360 if ( ( tic4x_cpu
== 31 && tic4x_revision
>= 6)
1361 || (tic4x_cpu
== 32 && tic4x_revision
>= 2)
1362 || (tic4x_cpu
== 33)
1364 tic4x_oplevel
|= OP_ENH
;
1366 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1367 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1368 || (tic4x_cpu
== 32)
1370 tic4x_oplevel
|= OP_LPWR
;
1372 if ( ( tic4x_cpu
== 30 && tic4x_revision
>= 7)
1373 || (tic4x_cpu
== 31 && tic4x_revision
>= 5)
1374 || (tic4x_cpu
== 32)
1375 || (tic4x_cpu
== 33)
1376 || (tic4x_cpu
== 40 && tic4x_revision
>= 5)
1377 || (tic4x_cpu
== 44)
1379 tic4x_oplevel
|= OP_IDLE2
;
1381 /* Create hash table for mnemonics. */
1382 tic4x_op_hash
= hash_new ();
1384 /* Create hash table for asg pseudo. */
1385 tic4x_asg_hash
= hash_new ();
1387 /* Add mnemonics to hash table, expanding conditional mnemonics on fly. */
1388 for (i
= 0; i
< tic4x_num_insts
; i
++)
1389 ok
&= tic4x_inst_add (tic4x_insts
+ i
);
1391 /* Create dummy inst to avoid errors accessing end of table. */
1392 tic4x_inst_make ("", 0, "");
1395 as_fatal ("Broken assembler. No assembly attempted.");
1397 /* Add registers to symbol table. */
1398 tic4x_init_regtable ();
1400 /* Add predefined symbols to symbol table. */
1401 tic4x_init_symbols ();
1407 bfd_set_arch_mach (stdoutput
, bfd_arch_tic4x
,
1408 IS_CPU_TIC4X (tic4x_cpu
) ? bfd_mach_tic4x
: bfd_mach_tic3x
);
1412 tic4x_indirect_parse (tic4x_operand_t
*operand
,
1413 const tic4x_indirect_t
*indirect
)
1415 char *n
= indirect
->name
;
1416 char *s
= input_line_pointer
;
1426 case 'a': /* Need to match aux register. */
1428 #ifdef TIC4X_ALT_SYNTAX
1432 while (ISALNUM (*s
))
1435 if (!(symbolP
= symbol_find (name
)))
1438 if (S_GET_SEGMENT (symbolP
) != reg_section
)
1441 operand
->aregno
= S_GET_VALUE (symbolP
);
1442 if (operand
->aregno
>= REG_AR0
&& operand
->aregno
<= REG_AR7
)
1445 as_bad (_("Auxiliary register AR0--AR7 required for indirect"));
1448 case 'd': /* Need to match constant for disp. */
1449 #ifdef TIC4X_ALT_SYNTAX
1450 if (*s
== '%') /* expr() will die if we don't skip this. */
1453 s
= tic4x_expression (s
, &operand
->expr
);
1454 if (operand
->expr
.X_op
!= O_constant
)
1456 operand
->disp
= operand
->expr
.X_add_number
;
1457 if (operand
->disp
< 0 || operand
->disp
> 255)
1459 as_bad (_("Bad displacement %d (require 0--255)\n"),
1465 case 'y': /* Need to match IR0. */
1466 case 'z': /* Need to match IR1. */
1467 #ifdef TIC4X_ALT_SYNTAX
1471 s
= tic4x_expression (s
, &operand
->expr
);
1472 if (operand
->expr
.X_op
!= O_register
)
1474 if (operand
->expr
.X_add_number
!= REG_IR0
1475 && operand
->expr
.X_add_number
!= REG_IR1
)
1477 as_bad (_("Index register IR0,IR1 required for displacement"));
1481 if (*n
== 'y' && operand
->expr
.X_add_number
== REG_IR0
)
1483 if (*n
== 'z' && operand
->expr
.X_add_number
== REG_IR1
)
1488 if (*s
!= '(') /* No displacement, assume to be 1. */
1499 if (TOLOWER (*s
) != *n
)
1504 if (*s
!= ' ' && *s
!= ',' && *s
!= '\0')
1506 input_line_pointer
= s
;
1511 tic4x_operand_parse (char *s
, tic4x_operand_t
*operand
)
1516 expressionS
*exp
= &operand
->expr
;
1517 char *save
= input_line_pointer
;
1520 struct hash_entry
*entry
= NULL
;
1522 input_line_pointer
= s
;
1525 str
= input_line_pointer
;
1526 c
= get_symbol_end (); /* Get terminator. */
1527 new_pointer
= input_line_pointer
;
1528 if (strlen (str
) && (entry
= hash_find (tic4x_asg_hash
, str
)) != NULL
)
1530 *input_line_pointer
= c
;
1531 input_line_pointer
= (char *) entry
;
1535 *input_line_pointer
= c
;
1536 input_line_pointer
= str
;
1539 operand
->mode
= M_UNKNOWN
;
1540 switch (*input_line_pointer
)
1542 #ifdef TIC4X_ALT_SYNTAX
1544 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1545 if (exp
->X_op
!= O_register
)
1546 as_bad (_("Expecting a register name"));
1547 operand
->mode
= M_REGISTER
;
1551 /* Denotes high 16 bits. */
1552 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1553 if (exp
->X_op
== O_constant
)
1554 operand
->mode
= M_IMMED
;
1555 else if (exp
->X_op
== O_big
)
1557 if (exp
->X_add_number
)
1558 as_bad (_("Number too large")); /* bignum required */
1561 tic4x_gen_to_words (generic_floating_point_number
,
1562 operand
->fwords
, S_PRECISION
);
1563 operand
->mode
= M_IMMED_F
;
1566 /* Allow ori ^foo, ar0 to be equivalent to ldi .hi.foo, ar0 */
1567 /* WARNING : The TI C40 assembler cannot do this. */
1568 else if (exp
->X_op
== O_symbol
)
1570 operand
->mode
= M_HI
;
1575 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1576 if (exp
->X_op
== O_constant
)
1577 operand
->mode
= M_IMMED
;
1578 else if (exp
->X_op
== O_big
)
1580 if (exp
->X_add_number
> 0)
1581 as_bad (_("Number too large")); /* bignum required. */
1584 tic4x_gen_to_words (generic_floating_point_number
,
1585 operand
->fwords
, S_PRECISION
);
1586 operand
->mode
= M_IMMED_F
;
1589 /* Allow ori foo, ar0 to be equivalent to ldi .lo.foo, ar0 */
1590 /* WARNING : The TI C40 assembler cannot do this. */
1591 else if (exp
->X_op
== O_symbol
)
1593 operand
->mode
= M_IMMED
;
1598 as_bad (_("Expecting a constant value"));
1603 input_line_pointer
= tic4x_expression (++input_line_pointer
, exp
);
1604 if (exp
->X_op
!= O_constant
&& exp
->X_op
!= O_symbol
)
1605 as_bad (_("Bad direct addressing construct %s"), s
);
1606 if (exp
->X_op
== O_constant
)
1608 if (exp
->X_add_number
< 0)
1609 as_bad (_("Direct value of %ld is not suitable"),
1610 (long) exp
->X_add_number
);
1612 operand
->mode
= M_DIRECT
;
1617 for (i
= 0; i
< tic4x_num_indirects
; i
++)
1618 if ((ret
= tic4x_indirect_parse (operand
, &tic4x_indirects
[i
])))
1622 if (i
< tic4x_num_indirects
)
1624 operand
->mode
= M_INDIRECT
;
1625 /* Indirect addressing mode number. */
1626 operand
->expr
.X_add_number
= tic4x_indirects
[i
].modn
;
1627 /* Convert *+ARn(0) to *ARn etc. Maybe we should
1628 squeal about silly ones? */
1629 if (operand
->expr
.X_add_number
< 0x08 && !operand
->disp
)
1630 operand
->expr
.X_add_number
= 0x18;
1633 as_bad (_("Unknown indirect addressing mode"));
1637 operand
->mode
= M_IMMED
; /* Assume immediate. */
1638 str
= input_line_pointer
;
1639 input_line_pointer
= tic4x_expression (input_line_pointer
, exp
);
1640 if (exp
->X_op
== O_register
)
1642 know (exp
->X_add_symbol
== 0);
1643 know (exp
->X_op_symbol
== 0);
1644 operand
->mode
= M_REGISTER
;
1647 else if (exp
->X_op
== O_big
)
1649 if (exp
->X_add_number
> 0)
1650 as_bad (_("Number too large")); /* bignum required. */
1653 tic4x_gen_to_words (generic_floating_point_number
,
1654 operand
->fwords
, S_PRECISION
);
1655 operand
->mode
= M_IMMED_F
;
1659 #ifdef TIC4X_ALT_SYNTAX
1660 /* Allow ldi foo, ar0 to be equivalent to ldi @foo, ar0. */
1661 else if (exp
->X_op
== O_symbol
)
1663 operand
->mode
= M_DIRECT
;
1669 new_pointer
= input_line_pointer
;
1670 input_line_pointer
= save
;
1675 tic4x_operands_match (tic4x_inst_t
*inst
, tic4x_insn_t
*tinsn
, int check
)
1677 const char *args
= inst
->args
;
1678 unsigned long opcode
= inst
->opcode
;
1679 int num_operands
= tinsn
->num_operands
;
1680 tic4x_operand_t
*operand
= tinsn
->operands
;
1681 expressionS
*exp
= &operand
->expr
;
1685 /* Build the opcode, checking as we go to make sure that the
1688 If an operand matches, we modify insn or opcode appropriately,
1689 and do a "continue". If an operand fails to match, we "break". */
1691 tinsn
->nchars
= 4; /* Instructions always 4 bytes. */
1692 tinsn
->reloc
= NO_RELOC
;
1697 tinsn
->opcode
= opcode
;
1698 return num_operands
== 0;
1706 case '\0': /* End of args. */
1707 if (num_operands
== 1)
1709 tinsn
->opcode
= opcode
;
1712 break; /* Too many operands. */
1714 case '#': /* This is only used for ldp. */
1715 if (operand
->mode
!= M_DIRECT
&& operand
->mode
!= M_IMMED
)
1717 /* While this looks like a direct addressing mode, we actually
1718 use an immediate mode form of ldiu or ldpk instruction. */
1719 if (exp
->X_op
== O_constant
)
1721 if( ( IS_CPU_TIC4X (tic4x_cpu
) && exp
->X_add_number
<= 65535 )
1722 || ( IS_CPU_TIC3X (tic4x_cpu
) && exp
->X_add_number
<= 255 ) )
1724 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1730 as_bad (_("Immediate value of %ld is too large for ldf"),
1731 (long) exp
->X_add_number
);
1736 else if (exp
->X_op
== O_symbol
)
1738 tinsn
->reloc
= BFD_RELOC_HI16
;
1742 break; /* Not direct (dp) addressing. */
1744 case '@': /* direct. */
1745 if (operand
->mode
!= M_DIRECT
)
1747 if (exp
->X_op
== O_constant
)
1749 /* Store only the 16 LSBs of the number. */
1750 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1753 else if (exp
->X_op
== O_symbol
)
1755 tinsn
->reloc
= BFD_RELOC_LO16
;
1759 break; /* Not direct addressing. */
1762 if (operand
->mode
!= M_REGISTER
)
1764 reg
= exp
->X_add_number
;
1765 if (reg
>= REG_AR0
&& reg
<= REG_AR7
)
1766 INSERTU (opcode
, reg
- REG_AR0
, 24, 22);
1770 as_bad (_("Destination register must be ARn"));
1775 case 'B': /* Unsigned integer immediate. */
1776 /* Allow br label or br @label. */
1777 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
1779 if (exp
->X_op
== O_constant
)
1781 if (exp
->X_add_number
< (1 << 24))
1783 INSERTU (opcode
, exp
->X_add_number
, 23, 0);
1789 as_bad (_("Immediate value of %ld is too large"),
1790 (long) exp
->X_add_number
);
1795 if (IS_CPU_TIC4X (tic4x_cpu
))
1797 tinsn
->reloc
= BFD_RELOC_24_PCREL
;
1802 tinsn
->reloc
= BFD_RELOC_24
;
1809 if (!IS_CPU_TIC4X (tic4x_cpu
))
1811 if (operand
->mode
!= M_INDIRECT
)
1813 /* Require either *+ARn(disp) or *ARn. */
1814 if (operand
->expr
.X_add_number
!= 0
1815 && operand
->expr
.X_add_number
!= 0x18)
1818 as_bad (_("Invalid indirect addressing mode"));
1822 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1823 INSERTU (opcode
, operand
->disp
, 7, 3);
1827 if (!(operand
->mode
== M_REGISTER
))
1829 INSERTU (opcode
, exp
->X_add_number
, 7, 0);
1833 if (!(operand
->mode
== M_REGISTER
))
1835 reg
= exp
->X_add_number
;
1836 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1837 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1838 INSERTU (opcode
, reg
, 7, 0);
1842 as_bad (_("Register must be Rn"));
1848 if (operand
->mode
!= M_IMMED_F
1849 && !(operand
->mode
== M_IMMED
&& exp
->X_op
== O_constant
))
1852 if (operand
->mode
!= M_IMMED_F
)
1854 /* OK, we 've got something like cmpf 0, r0
1855 Why can't they stick in a bloody decimal point ?! */
1858 /* Create floating point number string. */
1859 sprintf (string
, "%d.0", (int) exp
->X_add_number
);
1860 tic4x_atof (string
, 's', operand
->fwords
);
1863 INSERTU (opcode
, operand
->fwords
[0], 15, 0);
1867 if (operand
->mode
!= M_REGISTER
)
1869 INSERTU (opcode
, exp
->X_add_number
, 15, 8);
1873 if (operand
->mode
!= M_REGISTER
)
1875 reg
= exp
->X_add_number
;
1876 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
1877 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
1878 INSERTU (opcode
, reg
, 15, 8);
1882 as_bad (_("Register must be Rn"));
1888 if (operand
->mode
!= M_REGISTER
)
1890 reg
= exp
->X_add_number
;
1891 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1892 INSERTU (opcode
, reg
- REG_R0
, 18, 16);
1896 as_bad (_("Register must be R0--R7"));
1902 if ( operand
->mode
== M_REGISTER
1903 && tic4x_oplevel
& OP_ENH
)
1905 reg
= exp
->X_add_number
;
1906 INSERTU (opcode
, reg
, 4, 0);
1907 INSERTU (opcode
, 7, 7, 5);
1913 if (operand
->mode
!= M_INDIRECT
)
1915 if (operand
->disp
!= 0 && operand
->disp
!= 1)
1917 if (IS_CPU_TIC4X (tic4x_cpu
))
1920 as_bad (_("Invalid indirect addressing mode displacement %d"),
1925 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1926 INSERTU (opcode
, operand
->expr
.X_add_number
, 7, 3);
1930 if ( operand
->mode
== M_REGISTER
1931 && tic4x_oplevel
& OP_ENH
)
1933 reg
= exp
->X_add_number
;
1934 INSERTU (opcode
, reg
, 12, 8);
1935 INSERTU (opcode
, 7, 15, 13);
1941 if (operand
->mode
!= M_INDIRECT
)
1943 if (operand
->disp
!= 0 && operand
->disp
!= 1)
1945 if (IS_CPU_TIC4X (tic4x_cpu
))
1948 as_bad (_("Invalid indirect addressing mode displacement %d"),
1953 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
1954 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
1958 if (operand
->mode
!= M_REGISTER
)
1960 reg
= exp
->X_add_number
;
1961 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1962 INSERTU (opcode
, reg
- REG_R0
, 21, 19);
1966 as_bad (_("Register must be R0--R7"));
1972 if (operand
->mode
!= M_REGISTER
)
1974 reg
= exp
->X_add_number
;
1975 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1976 INSERTU (opcode
, reg
- REG_R0
, 24, 22);
1980 as_bad (_("Register must be R0--R7"));
1986 if (operand
->mode
!= M_REGISTER
)
1988 reg
= exp
->X_add_number
;
1989 if (reg
== REG_R2
|| reg
== REG_R3
)
1990 INSERTU (opcode
, reg
- REG_R2
, 22, 22);
1994 as_bad (_("Destination register must be R2 or R3"));
2000 if (operand
->mode
!= M_REGISTER
)
2002 reg
= exp
->X_add_number
;
2003 if (reg
== REG_R0
|| reg
== REG_R1
)
2004 INSERTU (opcode
, reg
- REG_R0
, 23, 23);
2008 as_bad (_("Destination register must be R0 or R1"));
2014 if (!IS_CPU_TIC4X (tic4x_cpu
))
2016 if (operand
->mode
!= M_INDIRECT
)
2018 /* Require either *+ARn(disp) or *ARn. */
2019 if (operand
->expr
.X_add_number
!= 0
2020 && operand
->expr
.X_add_number
!= 0x18)
2023 as_bad (_("Invalid indirect addressing mode"));
2027 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2028 INSERTU (opcode
, operand
->disp
, 15, 11);
2031 case 'P': /* PC relative displacement. */
2032 /* Allow br label or br @label. */
2033 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
2035 if (exp
->X_op
== O_constant
)
2037 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 32767)
2039 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2045 as_bad (_("Displacement value of %ld is too large"),
2046 (long) exp
->X_add_number
);
2051 tinsn
->reloc
= BFD_RELOC_16_PCREL
;
2057 if (operand
->mode
!= M_REGISTER
)
2059 reg
= exp
->X_add_number
;
2060 INSERTU (opcode
, reg
, 15, 0);
2064 if (operand
->mode
!= M_REGISTER
)
2066 reg
= exp
->X_add_number
;
2067 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2068 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2069 INSERTU (opcode
, reg
, 15, 0);
2073 as_bad (_("Register must be Rn"));
2079 if (operand
->mode
!= M_REGISTER
)
2081 reg
= exp
->X_add_number
;
2082 INSERTU (opcode
, reg
, 20, 16);
2086 if (operand
->mode
!= M_REGISTER
)
2088 reg
= exp
->X_add_number
;
2089 if ( (reg
>= REG_R0
&& reg
<= REG_R7
)
2090 || (IS_CPU_TIC4X (tic4x_cpu
) && reg
>= REG_R8
&& reg
<= REG_R11
) )
2091 INSERTU (opcode
, reg
, 20, 16);
2095 as_bad (_("Register must be Rn"));
2100 case 'S': /* Short immediate int. */
2101 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2103 if (exp
->X_op
== O_big
)
2106 as_bad (_("Floating point number not valid in expression"));
2110 if (exp
->X_op
== O_constant
)
2112 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 65535)
2114 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2120 as_bad (_("Signed immediate value %ld too large"),
2121 (long) exp
->X_add_number
);
2126 else if (exp
->X_op
== O_symbol
)
2128 if (operand
->mode
== M_HI
)
2130 tinsn
->reloc
= BFD_RELOC_HI16
;
2134 tinsn
->reloc
= BFD_RELOC_LO16
;
2139 /* Handle cases like ldi foo - $, ar0 where foo
2140 is a forward reference. Perhaps we should check
2141 for X_op == O_symbol and disallow things like
2143 tinsn
->reloc
= BFD_RELOC_16
;
2147 case 'T': /* 5-bit immediate value for tic4x stik. */
2148 if (!IS_CPU_TIC4X (tic4x_cpu
))
2150 if (operand
->mode
!= M_IMMED
)
2152 if (exp
->X_op
== O_constant
)
2154 if (exp
->X_add_number
< 16 && exp
->X_add_number
>= -16)
2156 INSERTS (opcode
, exp
->X_add_number
, 20, 16);
2162 as_bad (_("Immediate value of %ld is too large"),
2163 (long) exp
->X_add_number
);
2168 break; /* No relocations allowed. */
2170 case 'U': /* Unsigned integer immediate. */
2171 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2173 if (exp
->X_op
== O_constant
)
2175 if (exp
->X_add_number
< (1 << 16) && exp
->X_add_number
>= 0)
2177 INSERTU (opcode
, exp
->X_add_number
, 15, 0);
2183 as_bad (_("Unsigned immediate value %ld too large"),
2184 (long) exp
->X_add_number
);
2189 else if (exp
->X_op
== O_symbol
)
2191 if (operand
->mode
== M_HI
)
2192 tinsn
->reloc
= BFD_RELOC_HI16
;
2194 tinsn
->reloc
= BFD_RELOC_LO16
;
2199 tinsn
->reloc
= BFD_RELOC_16
;
2203 case 'V': /* Trap numbers (immediate field). */
2204 if (operand
->mode
!= M_IMMED
)
2206 if (exp
->X_op
== O_constant
)
2208 if (exp
->X_add_number
< 512 && IS_CPU_TIC4X (tic4x_cpu
))
2210 INSERTU (opcode
, exp
->X_add_number
, 8, 0);
2213 else if (exp
->X_add_number
< 32 && IS_CPU_TIC3X (tic4x_cpu
))
2215 INSERTU (opcode
, exp
->X_add_number
| 0x20, 4, 0);
2221 as_bad (_("Immediate value of %ld is too large"),
2222 (long) exp
->X_add_number
);
2227 break; /* No relocations allowed. */
2229 case 'W': /* Short immediate int (0--7). */
2230 if (!IS_CPU_TIC4X (tic4x_cpu
))
2232 if (operand
->mode
!= M_IMMED
)
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
>= -256 && exp
->X_add_number
<= 127)
2245 INSERTS (opcode
, exp
->X_add_number
, 7, 0);
2251 as_bad (_("Immediate value %ld too large"),
2252 (long) exp
->X_add_number
);
2257 tinsn
->reloc
= BFD_RELOC_16
;
2261 case 'X': /* Expansion register for tic4x. */
2262 if (operand
->mode
!= M_REGISTER
)
2264 reg
= exp
->X_add_number
;
2265 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2266 INSERTU (opcode
, reg
- REG_IVTP
, 4, 0);
2270 as_bad (_("Register must be ivtp or tvtp"));
2275 case 'Y': /* Address register for tic4x lda. */
2276 if (operand
->mode
!= M_REGISTER
)
2278 reg
= exp
->X_add_number
;
2279 if (reg
>= REG_AR0
&& reg
<= REG_SP
)
2280 INSERTU (opcode
, reg
, 20, 16);
2284 as_bad (_("Register must be address register"));
2289 case 'Z': /* Expansion register for tic4x. */
2290 if (operand
->mode
!= M_REGISTER
)
2292 reg
= exp
->X_add_number
;
2293 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2294 INSERTU (opcode
, reg
- REG_IVTP
, 20, 16);
2298 as_bad (_("Register must be ivtp or tvtp"));
2304 if (operand
->mode
!= M_INDIRECT
)
2306 INSERTS (opcode
, operand
->disp
, 7, 0);
2307 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2308 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
2311 case '|': /* treat as `,' if have ldi_ldi form. */
2312 if (tinsn
->parallel
)
2314 if (--num_operands
< 0)
2315 break; /* Too few operands. */
2317 if (operand
->mode
!= M_PARALLEL
)
2322 case ',': /* Another operand. */
2323 if (--num_operands
< 0)
2324 break; /* Too few operands. */
2326 exp
= &operand
->expr
;
2329 case ';': /* Another optional operand. */
2330 if (num_operands
== 1 || operand
[1].mode
== M_PARALLEL
)
2332 if (--num_operands
< 0)
2333 break; /* Too few operands. */
2335 exp
= &operand
->expr
;
2346 tic4x_insn_check (tic4x_insn_t
*tinsn
)
2349 if (!strcmp (tinsn
->name
, "lda"))
2351 if (tinsn
->num_operands
< 2 || tinsn
->num_operands
> 2)
2352 as_fatal ("Illegal internal LDA insn definition");
2354 if (tinsn
->operands
[0].mode
== M_REGISTER
2355 && tinsn
->operands
[1].mode
== M_REGISTER
2356 && tinsn
->operands
[0].expr
.X_add_number
== tinsn
->operands
[1].expr
.X_add_number
)
2357 as_bad (_("Source and destination register should not be equal"));
2359 else if (!strcmp (tinsn
->name
, "ldi_ldi")
2360 || !strcmp (tinsn
->name
, "ldi1_ldi2")
2361 || !strcmp (tinsn
->name
, "ldi2_ldi1")
2362 || !strcmp (tinsn
->name
, "ldf_ldf")
2363 || !strcmp (tinsn
->name
, "ldf1_ldf2")
2364 || !strcmp (tinsn
->name
, "ldf2_ldf1") )
2366 if (tinsn
->num_operands
< 4 && tinsn
->num_operands
> 5 )
2367 as_fatal ("Illegal internal %s insn definition", tinsn
->name
);
2369 if (tinsn
->operands
[1].mode
== M_REGISTER
2370 && tinsn
->operands
[tinsn
->num_operands
-1].mode
== M_REGISTER
2371 && tinsn
->operands
[1].expr
.X_add_number
== tinsn
->operands
[tinsn
->num_operands
-1].expr
.X_add_number
)
2372 as_warn (_("Equal parallell destination registers, one result will be discarded"));
2377 tic4x_insn_output (tic4x_insn_t
*tinsn
)
2381 /* Grab another fragment for opcode. */
2382 dst
= frag_more (tinsn
->nchars
);
2384 /* Put out opcode word as a series of bytes in little endian order. */
2385 md_number_to_chars (dst
, tinsn
->opcode
, tinsn
->nchars
);
2387 /* Put out the symbol-dependent stuff. */
2388 if (tinsn
->reloc
!= NO_RELOC
)
2390 /* Where is the offset into the fragment for this instruction. */
2391 fix_new_exp (frag_now
,
2392 dst
- frag_now
->fr_literal
, /* where */
2393 tinsn
->nchars
, /* size */
2400 /* Parse the operands. */
2402 tic4x_operands_parse (char *s
, tic4x_operand_t
*operands
, int num_operands
)
2405 return num_operands
;
2408 s
= tic4x_operand_parse (s
, &operands
[num_operands
++]);
2409 while (num_operands
< TIC4X_OPERANDS_MAX
&& *s
++ == ',');
2411 if (num_operands
> TIC4X_OPERANDS_MAX
)
2413 as_bad (_("Too many operands scanned"));
2416 return num_operands
;
2419 /* Assemble a single instruction. Its label has already been handled
2420 by the generic front end. We just parse mnemonic and operands, and
2421 produce the bytes of data and relocation. */
2423 md_assemble (char *str
)
2429 tic4x_inst_t
*inst
; /* Instruction template. */
2430 tic4x_inst_t
*first_inst
;
2432 /* Scan for parallel operators */
2436 while (*s
&& *s
!= '|')
2439 if (*s
&& s
[1]=='|')
2443 as_bad (_("Parallel opcode cannot contain more than two instructions"));
2449 /* Lets take care of the first part of the parallel insn */
2454 /* .. and let the second run though here */
2458 if (str
&& insn
->parallel
)
2460 /* Find mnemonic (second part of parallel instruction). */
2462 /* Skip past instruction mnemonic. */
2463 while (*s
&& *s
!= ' ')
2465 if (*s
) /* Null terminate for hash_find. */
2466 *s
++ = '\0'; /* and skip past null. */
2467 strcat (insn
->name
, "_");
2468 strncat (insn
->name
, str
, TIC4X_NAME_MAX
- strlen (insn
->name
));
2470 insn
->operands
[insn
->num_operands
++].mode
= M_PARALLEL
;
2472 if ((i
= tic4x_operands_parse
2473 (s
, insn
->operands
, insn
->num_operands
)) < 0)
2479 insn
->num_operands
= i
;
2485 if ((insn
->inst
= (struct tic4x_inst
*)
2486 hash_find (tic4x_op_hash
, insn
->name
)) == NULL
)
2488 as_bad (_("Unknown opcode `%s'."), insn
->name
);
2498 ok
= tic4x_operands_match (inst
, insn
, 1);
2505 } while (!ok
&& !strcmp (inst
->name
, inst
[1].name
) && inst
++);
2509 tic4x_insn_check (insn
);
2510 tic4x_insn_output (insn
);
2515 tic4x_operands_match (first_inst
, insn
, 0);
2516 as_bad (_("Invalid operands for %s"), insn
->name
);
2519 as_bad (_("Invalid instruction %s"), insn
->name
);
2524 /* Find mnemonic. */
2526 while (*s
&& *s
!= ' ') /* Skip past instruction mnemonic. */
2528 if (*s
) /* Null terminate for hash_find. */
2529 *s
++ = '\0'; /* and skip past null. */
2530 strncpy (insn
->name
, str
, TIC4X_NAME_MAX
- 3);
2532 if ((i
= tic4x_operands_parse (s
, insn
->operands
, 0)) < 0)
2534 insn
->inst
= NULL
; /* Flag that error occurred. */
2539 insn
->num_operands
= i
;
2548 tic4x_cleanup (void)
2554 /* Turn a string in input_line_pointer into a floating point constant
2555 of type type, and store the appropriate bytes in *litP. The number
2556 of chars emitted is stored in *sizeP. An error message is
2557 returned, or NULL on OK. */
2560 md_atof (int type
, char *litP
, int *sizeP
)
2564 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2565 LITTLENUM_TYPE
*wordP
;
2570 case 's': /* .single */
2576 case 'd': /* .double */
2578 case 'f': /* .float */
2581 prec
= 2; /* 1 32-bit word */
2584 case 'i': /* .ieee */
2588 type
= 'f'; /* Rewrite type to be usable by atof_ieee(). */
2591 case 'e': /* .ldouble */
2593 prec
= 4; /* 2 32-bit words */
2599 return _("Unrecognized or unsupported floating point constant");
2603 t
= atof_ieee (input_line_pointer
, type
, words
);
2605 t
= tic4x_atof (input_line_pointer
, type
, words
);
2607 input_line_pointer
= t
;
2608 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
2610 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
2611 little endian byte order. */
2612 /* SES: However it is required to put the words (32-bits) out in the
2613 correct order, hence we write 2 and 2 littlenums in little endian
2614 order, while we keep the original order on successive words. */
2615 for (wordP
= words
; wordP
<(words
+prec
) ; wordP
+=2)
2617 if (wordP
< (words
+ prec
- 1)) /* Dump wordP[1] (if we have one). */
2619 md_number_to_chars (litP
, (valueT
) (wordP
[1]),
2620 sizeof (LITTLENUM_TYPE
));
2621 litP
+= sizeof (LITTLENUM_TYPE
);
2625 md_number_to_chars (litP
, (valueT
) (wordP
[0]),
2626 sizeof (LITTLENUM_TYPE
));
2627 litP
+= sizeof (LITTLENUM_TYPE
);
2633 md_apply_fix (fixS
*fixP
, valueT
*value
, segT seg ATTRIBUTE_UNUSED
)
2635 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
2636 valueT val
= *value
;
2638 switch (fixP
->fx_r_type
)
2640 case BFD_RELOC_HI16
:
2644 case BFD_RELOC_LO16
:
2651 switch (fixP
->fx_r_type
)
2656 case BFD_RELOC_24_PCREL
:
2659 case BFD_RELOC_16_PCREL
:
2660 case BFD_RELOC_LO16
:
2661 case BFD_RELOC_HI16
:
2668 as_bad (_("Bad relocation type: 0x%02x"), fixP
->fx_r_type
);
2672 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0) fixP
->fx_done
= 1;
2675 /* Should never be called for tic4x. */
2677 md_convert_frag (bfd
*headers ATTRIBUTE_UNUSED
,
2678 segT sec ATTRIBUTE_UNUSED
,
2679 fragS
*fragP ATTRIBUTE_UNUSED
)
2681 as_fatal ("md_convert_frag");
2684 /* Should never be called for tic4x. */
2686 md_create_short_jump (char *ptr ATTRIBUTE_UNUSED
,
2687 addressT from_addr ATTRIBUTE_UNUSED
,
2688 addressT to_addr ATTRIBUTE_UNUSED
,
2689 fragS
*frag ATTRIBUTE_UNUSED
,
2690 symbolS
*to_symbol ATTRIBUTE_UNUSED
)
2692 as_fatal ("md_create_short_jmp\n");
2695 /* Should never be called for tic4x. */
2697 md_create_long_jump (char *ptr ATTRIBUTE_UNUSED
,
2698 addressT from_addr ATTRIBUTE_UNUSED
,
2699 addressT to_addr ATTRIBUTE_UNUSED
,
2700 fragS
*frag ATTRIBUTE_UNUSED
,
2701 symbolS
*to_symbol ATTRIBUTE_UNUSED
)
2703 as_fatal ("md_create_long_jump\n");
2706 /* Should never be called for tic4x. */
2708 md_estimate_size_before_relax (fragS
*fragP ATTRIBUTE_UNUSED
,
2709 segT segtype ATTRIBUTE_UNUSED
)
2711 as_fatal ("md_estimate_size_before_relax\n");
2717 md_parse_option (int c
, char *arg
)
2721 case OPTION_CPU
: /* cpu brand */
2722 if (TOLOWER (*arg
) == 'c')
2724 tic4x_cpu
= atoi (arg
);
2725 if (!IS_CPU_TIC3X (tic4x_cpu
) && !IS_CPU_TIC4X (tic4x_cpu
))
2726 as_warn (_("Unsupported processor generation %d"), tic4x_cpu
);
2729 case OPTION_REV
: /* cpu revision */
2730 tic4x_revision
= atoi (arg
);
2734 as_warn (_("Option -b is depreciated, please use -mbig"));
2735 case OPTION_BIG
: /* big model */
2736 tic4x_big_model
= 1;
2740 as_warn (_("Option -p is depreciated, please use -mmemparm"));
2741 case OPTION_MEMPARM
: /* push args */
2746 as_warn (_("Option -r is depreciated, please use -mregparm"));
2747 case OPTION_REGPARM
: /* register args */
2752 as_warn (_("Option -s is depreciated, please use -msmall"));
2753 case OPTION_SMALL
: /* small model */
2754 tic4x_big_model
= 0;
2761 case OPTION_LOWPOWER
:
2765 case OPTION_ENHANCED
:
2777 md_show_usage (FILE *stream
)
2780 _("\nTIC4X options:\n"
2781 " -mcpu=CPU -mCPU select architecture variant. CPU can be:\n"
2783 " 31 - TMS320C31, TMS320LC31\n"
2785 " 33 - TMS320VC33\n"
2788 " -mrev=REV set cpu hardware revision (integer numbers).\n"
2789 " Combinations of -mcpu and -mrev will enable/disable\n"
2790 " the appropriate options (-midle2, -mlowpower and\n"
2791 " -menhanced) according to the selected type\n"
2792 " -mbig select big memory model\n"
2793 " -msmall select small memory model (default)\n"
2794 " -mregparm select register parameters (default)\n"
2795 " -mmemparm select memory parameters\n"
2796 " -midle2 enable IDLE2 support\n"
2797 " -mlowpower enable LOPOWER and MAXSPEED support\n"
2798 " -menhanced enable enhanced opcode support\n"));
2801 /* This is called when a line is unrecognized. This is used to handle
2802 definitions of TI C3x tools style local labels $n where n is a single
2805 tic4x_unrecognized_line (int c
)
2810 if (c
!= '$' || ! ISDIGIT (input_line_pointer
[0]))
2813 s
= input_line_pointer
;
2815 /* Let's allow multiple digit local labels. */
2817 while (ISDIGIT (*s
))
2819 lab
= lab
* 10 + *s
- '0';
2823 if (dollar_label_defined (lab
))
2825 as_bad (_("Label \"$%d\" redefined"), lab
);
2829 define_dollar_label (lab
);
2830 colon (dollar_label_name (lab
, 0));
2831 input_line_pointer
= s
+ 1;
2836 /* Handle local labels peculiar to us referred to in an expression. */
2838 md_undefined_symbol (char *name
)
2840 /* Look for local labels of the form $n. */
2841 if (name
[0] == '$' && ISDIGIT (name
[1]))
2847 while (ISDIGIT ((unsigned char) *s
))
2849 lab
= lab
* 10 + *s
- '0';
2852 if (dollar_label_defined (lab
))
2854 name
= dollar_label_name (lab
, 0);
2855 symbolP
= symbol_find (name
);
2859 name
= dollar_label_name (lab
, 1);
2860 symbolP
= symbol_find_or_make (name
);
2868 /* Parse an operand that is machine-specific. */
2870 md_operand (expressionS
*expressionP ATTRIBUTE_UNUSED
)
2874 /* Round up a section size to the appropriate boundary---do we need this? */
2876 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
2878 return size
; /* Byte (i.e., 32-bit) alignment is fine? */
2882 tic4x_pc_offset (unsigned int op
)
2884 /* Determine the PC offset for a C[34]x instruction.
2885 This could be simplified using some boolean algebra
2886 but at the expense of readability. */
2890 case 0x62: /* call (C4x) */
2891 case 0x64: /* rptb (C4x) */
2893 case 0x61: /* brd */
2894 case 0x63: /* laj */
2895 case 0x65: /* rptbd (C4x) */
2897 case 0x66: /* swi */
2904 switch ((op
& 0xffe00000) >> 20)
2906 case 0x6a0: /* bB */
2907 case 0x720: /* callB */
2908 case 0x740: /* trapB */
2911 case 0x6a2: /* bBd */
2912 case 0x6a6: /* bBat */
2913 case 0x6aa: /* bBaf */
2914 case 0x722: /* lajB */
2915 case 0x748: /* latB */
2916 case 0x798: /* rptbd */
2923 switch ((op
& 0xfe200000) >> 20)
2925 case 0x6e0: /* dbB */
2928 case 0x6e2: /* dbBd */
2938 /* Exactly what point is a PC-relative offset relative TO?
2939 With the C3x we have the following:
2940 DBcond, Bcond disp + PC + 1 => PC
2941 DBcondD, BcondD disp + PC + 3 => PC
2944 md_pcrel_from (fixS
*fixP
)
2949 buf
= (unsigned char *) fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2950 op
= (buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
2952 return ((fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) >> 2) +
2953 tic4x_pc_offset (op
);
2956 /* Fill the alignment area with NOP's on .text, unless fill-data
2959 tic4x_do_align (int alignment ATTRIBUTE_UNUSED
,
2960 const char *fill ATTRIBUTE_UNUSED
,
2961 int len ATTRIBUTE_UNUSED
,
2962 int max ATTRIBUTE_UNUSED
)
2964 unsigned long nop
= TIC_NOP_OPCODE
;
2966 /* Because we are talking lwords, not bytes, adjust alignment to do words */
2969 if (alignment
!= 0 && !need_pass_2
)
2973 /*if (subseg_text_p (now_seg))*/ /* FIXME: doesn't work for .text for some reason */
2974 frag_align_pattern( alignment
, (const char *)&nop
, sizeof(nop
), max
);
2977 frag_align (alignment, 0, max);*/
2980 frag_align (alignment
, *fill
, max
);
2982 frag_align_pattern (alignment
, fill
, len
, max
);
2985 /* Return 1 to skip the default alignment function */
2989 /* Look for and remove parallel instruction operator ||. */
2991 tic4x_start_line (void)
2993 char *s
= input_line_pointer
;
2997 /* If parallel instruction prefix found at start of line, skip it. */
2998 if (*input_line_pointer
== '|' && input_line_pointer
[1] == '|')
3003 input_line_pointer
++;
3004 *input_line_pointer
= ' ';
3005 /* So line counters get bumped. */
3006 input_line_pointer
[-1] = '\n';
3011 /* Write out the previous insn here */
3014 input_line_pointer
= s
;
3019 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixP
)
3023 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
3025 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
3026 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
3027 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
3028 reloc
->address
/= OCTETS_PER_BYTE
;
3029 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
3030 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
3032 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3033 _("Reloc %d not supported by object file format"),
3034 (int) fixP
->fx_r_type
);
3038 if (fixP
->fx_r_type
== BFD_RELOC_HI16
)
3039 reloc
->addend
= fixP
->fx_offset
;
3041 reloc
->addend
= fixP
->fx_addnumber
;