Remove uses of ctype.h
[deliverable/binutils-gdb.git] / gas / config / tc-tic4x.c
1 /* tc-tic4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
2 Copyright (C) 1997,1998, 2002, 2003 Free Software Foundation.
3
4 Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
5
6 This file is part of GAS, the GNU Assembler.
7
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
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.
17
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
22 /*
23 TODOs:
24 ------
25
26 o .align cannot handle fill-data-width larger than 0xFF/8-bits. It
27 should be possible to define a 32-bits pattern.
28
29 o .align fills all section with NOP's when used regardless if has
30 been used in .text or .data. (However the .align is primarely
31 intended used in .text sections. If you require something else,
32 use .align <size>,0x00)
33
34 o .align: Implement a 'bu' insn if the number of nop's exeeds 4
35 within the align frag. if(fragsize>4words) insert bu fragend+1
36 first.
37
38 o .usect if has symbol on previous line not implemented
39
40 o .sym, .eos, .stag, .etag, .member not implemented
41
42 o Evaluation of constant floating point expressions (expr.c needs
43 work!)
44
45 o Support 'abc' constants (that is 0x616263)
46 */
47
48 #include <stdio.h>
49 #include "safe-ctype.h"
50 #include "as.h"
51 #include "opcode/tic4x.h"
52 #include "subsegs.h"
53 #include "obstack.h"
54 #include "symbols.h"
55 #include "listing.h"
56
57 /* OK, we accept a syntax similar to the other well known C30
58 assembly tools. With TIC4X_ALT_SYNTAX defined we are more
59 flexible, allowing a more Unix-like syntax: `%' in front of
60 register names, `#' in front of immediate constants, and
61 not requiring `@' in front of direct addresses. */
62
63 #define TIC4X_ALT_SYNTAX
64
65 /* Equal to MAX_PRECISION in atof-ieee.c. */
66 #define MAX_LITTLENUMS 6 /* (12 bytes) */
67
68 /* Handle of the inst mnemonic hash table. */
69 static struct hash_control *tic4x_op_hash = NULL;
70
71 /* Handle asg pseudo. */
72 static struct hash_control *tic4x_asg_hash = NULL;
73
74 static unsigned int tic4x_cpu = 0; /* Default to TMS320C40. */
75 static unsigned int tic4x_revision = 0; /* CPU revision */
76 static unsigned int tic4x_idle2 = 0; /* Idle2 support */
77 static unsigned int tic4x_lowpower = 0; /* Lowpower support */
78 static unsigned int tic4x_enhanced = 0; /* Enhanced opcode support */
79 static unsigned int tic4x_big_model = 0; /* Default to small memory model. */
80 static unsigned int tic4x_reg_args = 0; /* Default to args passed on stack. */
81 static unsigned long tic4x_oplevel = 0; /* Opcode level */
82
83 #define OPTION_CPU 'm'
84 #define OPTION_BIG (OPTION_MD_BASE + 1)
85 #define OPTION_SMALL (OPTION_MD_BASE + 2)
86 #define OPTION_MEMPARM (OPTION_MD_BASE + 3)
87 #define OPTION_REGPARM (OPTION_MD_BASE + 4)
88 #define OPTION_IDLE2 (OPTION_MD_BASE + 5)
89 #define OPTION_LOWPOWER (OPTION_MD_BASE + 6)
90 #define OPTION_ENHANCED (OPTION_MD_BASE + 7)
91 #define OPTION_REV (OPTION_MD_BASE + 8)
92
93 CONST char *md_shortopts = "bm:prs";
94 struct option md_longopts[] =
95 {
96 { "mcpu", required_argument, NULL, OPTION_CPU },
97 { "mdsp", required_argument, NULL, OPTION_CPU },
98 { "mbig", no_argument, NULL, OPTION_BIG },
99 { "msmall", no_argument, NULL, OPTION_SMALL },
100 { "mmemparm", no_argument, NULL, OPTION_MEMPARM },
101 { "mregparm", no_argument, NULL, OPTION_REGPARM },
102 { "midle2", no_argument, NULL, OPTION_IDLE2 },
103 { "mlowpower", no_argument, NULL, OPTION_LOWPOWER },
104 { "menhanced", no_argument, NULL, OPTION_ENHANCED },
105 { "mrev", required_argument, NULL, OPTION_REV },
106 { NULL, no_argument, NULL, 0 }
107 };
108
109 size_t md_longopts_size = sizeof (md_longopts);
110
111
112 typedef enum
113 {
114 M_UNKNOWN, M_IMMED, M_DIRECT, M_REGISTER, M_INDIRECT,
115 M_IMMED_F, M_PARALLEL, M_HI
116 }
117 tic4x_addr_mode_t;
118
119 typedef struct tic4x_operand
120 {
121 tic4x_addr_mode_t mode; /* Addressing mode. */
122 expressionS expr; /* Expression. */
123 int disp; /* Displacement for indirect addressing. */
124 int aregno; /* Aux. register number. */
125 LITTLENUM_TYPE fwords[MAX_LITTLENUMS]; /* Float immed. number. */
126 }
127 tic4x_operand_t;
128
129 typedef struct tic4x_insn
130 {
131 char name[TIC4X_NAME_MAX]; /* Mnemonic of instruction. */
132 unsigned int in_use; /* True if in_use. */
133 unsigned int parallel; /* True if parallel instruction. */
134 unsigned int nchars; /* This is always 4 for the C30. */
135 unsigned long opcode; /* Opcode number. */
136 expressionS exp; /* Expression required for relocation. */
137 int reloc; /* Relocation type required. */
138 int pcrel; /* True if relocation PC relative. */
139 char *pname; /* Name of instruction in parallel. */
140 unsigned int num_operands; /* Number of operands in total. */
141 tic4x_inst_t *inst; /* Pointer to first template. */
142 tic4x_operand_t operands[TIC4X_OPERANDS_MAX];
143 }
144 tic4x_insn_t;
145
146 static tic4x_insn_t the_insn; /* Info about our instruction. */
147 static tic4x_insn_t *insn = &the_insn;
148
149 static int tic4x_gen_to_words
150 PARAMS ((FLONUM_TYPE, LITTLENUM_TYPE *, int ));
151 static char *tic4x_atof
152 PARAMS ((char *, char, LITTLENUM_TYPE * ));
153 static void tic4x_insert_reg
154 PARAMS ((char *, int ));
155 static void tic4x_insert_sym
156 PARAMS ((char *, int ));
157 static char *tic4x_expression
158 PARAMS ((char *, expressionS *));
159 static char *tic4x_expression_abs
160 PARAMS ((char *, int *));
161 static void tic4x_emit_char
162 PARAMS ((char, int));
163 static void tic4x_seg_alloc
164 PARAMS ((char *, segT, int, symbolS *));
165 static void tic4x_asg
166 PARAMS ((int));
167 static void tic4x_bss
168 PARAMS ((int));
169 static void tic4x_globl
170 PARAMS ((int));
171 static void tic4x_cons
172 PARAMS ((int));
173 static void tic4x_stringer
174 PARAMS ((int));
175 static void tic4x_eval
176 PARAMS ((int));
177 static void tic4x_newblock
178 PARAMS ((int));
179 static void tic4x_sect
180 PARAMS ((int));
181 static void tic4x_set
182 PARAMS ((int));
183 static void tic4x_usect
184 PARAMS ((int));
185 static void tic4x_version
186 PARAMS ((int));
187 static void tic4x_init_regtable
188 PARAMS ((void));
189 static void tic4x_init_symbols
190 PARAMS ((void));
191 static int tic4x_inst_insert
192 PARAMS ((tic4x_inst_t *));
193 static tic4x_inst_t *tic4x_inst_make
194 PARAMS ((char *, unsigned long, char *));
195 static int tic4x_inst_add
196 PARAMS ((tic4x_inst_t *));
197 void md_begin
198 PARAMS ((void));
199 void tic4x_end
200 PARAMS ((void));
201 static int tic4x_indirect_parse
202 PARAMS ((tic4x_operand_t *, const tic4x_indirect_t *));
203 static char *tic4x_operand_parse
204 PARAMS ((char *, tic4x_operand_t *));
205 static int tic4x_operands_match
206 PARAMS ((tic4x_inst_t *, tic4x_insn_t *, int));
207 static void tic4x_insn_check
208 PARAMS ((tic4x_insn_t *));
209 static void tic4x_insn_output
210 PARAMS ((tic4x_insn_t *));
211 static int tic4x_operands_parse
212 PARAMS ((char *, tic4x_operand_t *, int ));
213 void md_assemble
214 PARAMS ((char *));
215 void tic4x_cleanup
216 PARAMS ((void));
217 char *md_atof
218 PARAMS ((int, char *, int *));
219 void md_apply_fix3
220 PARAMS ((fixS *, valueT *, segT ));
221 void md_convert_frag
222 PARAMS ((bfd *, segT, fragS *));
223 void md_create_short_jump
224 PARAMS ((char *, addressT, addressT, fragS *, symbolS *));
225 void md_create_long_jump
226 PARAMS ((char *, addressT, addressT, fragS *, symbolS *));
227 int md_estimate_size_before_relax
228 PARAMS ((register fragS *, segT));
229 int md_parse_option
230 PARAMS ((int, char *));
231 void md_show_usage
232 PARAMS ((FILE *));
233 int tic4x_unrecognized_line
234 PARAMS ((int));
235 symbolS *md_undefined_symbol
236 PARAMS ((char *));
237 void md_operand
238 PARAMS ((expressionS *));
239 valueT md_section_align
240 PARAMS ((segT, valueT));
241 static int tic4x_pc_offset
242 PARAMS ((unsigned int));
243 long md_pcrel_from
244 PARAMS ((fixS *));
245 int tic4x_do_align
246 PARAMS ((int, const char *, int, int));
247 void tic4x_start_line
248 PARAMS ((void));
249 arelent *tc_gen_reloc
250 PARAMS ((asection *, fixS *));
251
252
253 const pseudo_typeS
254 md_pseudo_table[] =
255 {
256 {"align", s_align_bytes, 32},
257 {"ascii", tic4x_stringer, 1},
258 {"asciz", tic4x_stringer, 0},
259 {"asg", tic4x_asg, 0},
260 {"block", s_space, 4},
261 {"byte", tic4x_cons, 1},
262 {"bss", tic4x_bss, 0},
263 {"copy", s_include, 0},
264 {"def", tic4x_globl, 0},
265 {"equ", tic4x_set, 0},
266 {"eval", tic4x_eval, 0},
267 {"global", tic4x_globl, 0},
268 {"globl", tic4x_globl, 0},
269 {"hword", tic4x_cons, 2},
270 {"ieee", float_cons, 'i'},
271 {"int", tic4x_cons, 4}, /* .int allocates 4 bytes. */
272 {"ldouble", float_cons, 'e'},
273 {"newblock", tic4x_newblock, 0},
274 {"ref", s_ignore, 0}, /* All undefined treated as external. */
275 {"set", tic4x_set, 0},
276 {"sect", tic4x_sect, 1}, /* Define named section. */
277 {"space", s_space, 4},
278 {"string", tic4x_stringer, 0},
279 {"usect", tic4x_usect, 0}, /* Reserve space in uninit. named sect. */
280 {"version", tic4x_version, 0},
281 {"word", tic4x_cons, 4}, /* .word allocates 4 bytes. */
282 {"xdef", tic4x_globl, 0},
283 {NULL, 0, 0},
284 };
285
286 int md_short_jump_size = 4;
287 int md_long_jump_size = 4;
288 const int md_reloc_size = RELSZ; /* Coff headers. */
289
290 /* This array holds the chars that always start a comment. If the
291 pre-processor is disabled, these aren't very useful. */
292 #ifdef TIC4X_ALT_SYNTAX
293 const char comment_chars[] = ";!";
294 #else
295 const char comment_chars[] = ";";
296 #endif
297
298 /* This array holds the chars that only start a comment at the beginning of
299 a line. If the line seems to have the form '# 123 filename'
300 .line and .file directives will appear in the pre-processed output.
301 Note that input_file.c hand checks for '#' at the beginning of the
302 first line of the input file. This is because the compiler outputs
303 #NO_APP at the beginning of its output.
304 Also note that comments like this one will always work. */
305 const char line_comment_chars[] = "#*";
306
307 /* We needed an unused char for line separation to work around the
308 lack of macros, using sed and such. */
309 const char line_separator_chars[] = "&";
310
311 /* Chars that can be used to separate mant from exp in floating point nums. */
312 const char EXP_CHARS[] = "eE";
313
314 /* Chars that mean this number is a floating point constant. */
315 /* As in 0f12.456 */
316 /* or 0d1.2345e12 */
317 const char FLT_CHARS[] = "fFilsS";
318
319 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
320 changed in read.c. Ideally it shouldn't have to know about it at
321 all, but nothing is ideal around here. */
322
323 /* Flonums returned here. */
324 extern FLONUM_TYPE generic_floating_point_number;
325
326 /* Precision in LittleNums. */
327 #define MAX_PRECISION (4) /* Its a bit overkill for us, but the code
328 reqires it... */
329 #define S_PRECISION (1) /* Short float constants 16-bit. */
330 #define F_PRECISION (2) /* Float and double types 32-bit. */
331 #define E_PRECISION (4) /* Extended precision, 64-bit (real 40-bit). */
332 #define GUARD (2)
333
334 /* Turn generic_floating_point_number into a real short/float/double. */
335 static int
336 tic4x_gen_to_words (flonum, words, precision)
337 FLONUM_TYPE flonum;
338 LITTLENUM_TYPE *words;
339 int precision;
340 {
341 int return_value = 0;
342 LITTLENUM_TYPE *p; /* Littlenum pointer. */
343 int mantissa_bits; /* Bits in mantissa field. */
344 int exponent_bits; /* Bits in exponent field. */
345 int exponent;
346 unsigned int sone; /* Scaled one. */
347 unsigned int sfract; /* Scaled fraction. */
348 unsigned int smant; /* Scaled mantissa. */
349 unsigned int tmp;
350 unsigned int mover; /* Mantissa overflow bits */
351 unsigned int rbit; /* Round bit. */
352 int shift; /* Shift count. */
353
354 /* NOTE: Svein Seldal <Svein.Seldal@solidas.com>
355 The code in this function is altered slightly to support floats
356 with 31-bits mantissas, thus the documentation below may be a
357 little bit inaccurate.
358
359 By Michael P. Hayes <m.hayes@elec.canterbury.ac.nz>
360 Here is how a generic floating point number is stored using
361 flonums (an extension of bignums) where p is a pointer to an
362 array of LITTLENUMs.
363
364 For example 2e-3 is stored with exp = -4 and
365 bits[0] = 0x0000
366 bits[1] = 0x0000
367 bits[2] = 0x4fde
368 bits[3] = 0x978d
369 bits[4] = 0x126e
370 bits[5] = 0x0083
371 with low = &bits[2], high = &bits[5], and leader = &bits[5].
372
373 This number can be written as
374 0x0083126e978d4fde.00000000 * 65536**-4 or
375 0x0.0083126e978d4fde * 65536**0 or
376 0x0.83126e978d4fde * 2**-8 = 2e-3
377
378 Note that low points to the 65536**0 littlenum (bits[2]) and
379 leader points to the most significant non-zero littlenum
380 (bits[5]).
381
382 TMS320C3X floating point numbers are a bit of a strange beast.
383 The 32-bit flavour has the 8 MSBs representing the exponent in
384 twos complement format (-128 to +127). There is then a sign bit
385 followed by 23 bits of mantissa. The mantissa is expressed in
386 twos complement format with the binary point after the most
387 significant non sign bit. The bit after the binary point is
388 suppressed since it is the complement of the sign bit. The
389 effective mantissa is thus 24 bits. Zero is represented by an
390 exponent of -128.
391
392 The 16-bit flavour has the 4 MSBs representing the exponent in
393 twos complement format (-8 to +7). There is then a sign bit
394 followed by 11 bits of mantissa. The mantissa is expressed in
395 twos complement format with the binary point after the most
396 significant non sign bit. The bit after the binary point is
397 suppressed since it is the complement of the sign bit. The
398 effective mantissa is thus 12 bits. Zero is represented by an
399 exponent of -8. For example,
400
401 number norm mant m x e s i fraction f
402 +0.500 => 1.00000000000 -1 -1 0 1 .00000000000 (1 + 0) * 2^(-1)
403 +0.999 => 1.11111111111 -1 -1 0 1 .11111111111 (1 + 0.99) * 2^(-1)
404 +1.000 => 1.00000000000 0 0 0 1 .00000000000 (1 + 0) * 2^(0)
405 +1.500 => 1.10000000000 0 0 0 1 .10000000000 (1 + 0.5) * 2^(0)
406 +1.999 => 1.11111111111 0 0 0 1 .11111111111 (1 + 0.9) * 2^(0)
407 +2.000 => 1.00000000000 1 1 0 1 .00000000000 (1 + 0) * 2^(1)
408 +4.000 => 1.00000000000 2 2 0 1 .00000000000 (1 + 0) * 2^(2)
409 -0.500 => 1.00000000000 -1 -1 1 0 .10000000000 (-2 + 0) * 2^(-2)
410 -1.000 => 1.00000000000 0 -1 1 0 .00000000000 (-2 + 0) * 2^(-1)
411 -1.500 => 1.10000000000 0 0 1 0 .10000000000 (-2 + 0.5) * 2^(0)
412 -1.999 => 1.11111111111 0 0 1 0 .00000000001 (-2 + 0.11) * 2^(0)
413 -2.000 => 1.00000000000 1 1 1 0 .00000000000 (-2 + 0) * 2^(0)
414 -4.000 => 1.00000000000 2 1 1 0 .00000000000 (-2 + 0) * 2^(1)
415
416 where e is the exponent, s is the sign bit, i is the implied bit,
417 and f is the fraction stored in the mantissa field.
418
419 num = (1 + f) * 2^x = m * 2^e if s = 0
420 num = (-2 + f) * 2^x = -m * 2^e if s = 1
421 where 0 <= f < 1.0 and 1.0 <= m < 2.0
422
423 The fraction (f) and exponent (e) fields for the TMS320C3X format
424 can be derived from the normalised mantissa (m) and exponent (x) using:
425
426 f = m - 1, e = x if s = 0
427 f = 2 - m, e = x if s = 1 and m != 1.0
428 f = 0, e = x - 1 if s = 1 and m = 1.0
429 f = 0, e = -8 if m = 0
430
431
432 OK, the other issue we have to consider is rounding since the
433 mantissa has a much higher potential precision than what we can
434 represent. To do this we add half the smallest storable fraction.
435 We then have to renormalise the number to allow for overflow.
436
437 To convert a generic flonum into a TMS320C3X floating point
438 number, here's what we try to do....
439
440 The first thing is to generate a normalised mantissa (m) where
441 1.0 <= m < 2 and to convert the exponent from base 16 to base 2.
442 We desire the binary point to be placed after the most significant
443 non zero bit. This process is done in two steps: firstly, the
444 littlenum with the most significant non zero bit is located (this
445 is done for us since leader points to this littlenum) and the
446 binary point (which is currently after the LSB of the littlenum
447 pointed to by low) is moved to before the MSB of the littlenum
448 pointed to by leader. This requires the exponent to be adjusted
449 by leader - low + 1. In the earlier example, the new exponent is
450 thus -4 + (5 - 2 + 1) = 0 (base 65536). We now need to convert
451 the exponent to base 2 by multiplying the exponent by 16 (log2
452 65536). The exponent base 2 is thus also zero.
453
454 The second step is to hunt for the most significant non zero bit
455 in the leader littlenum. We do this by left shifting a copy of
456 the leader littlenum until bit 16 is set (0x10000) and counting
457 the number of shifts, S, required. The number of shifts then has to
458 be added to correct the exponent (base 2). For our example, this
459 will require 9 shifts and thus our normalised exponent (base 2) is
460 0 + 9 = 9. Note that the worst case scenario is when the leader
461 littlenum is 1, thus requiring 16 shifts.
462
463 We now have to left shift the other littlenums by the same amount,
464 propagating the shifted bits into the more significant littlenums.
465 To save a lot of unecessary shifting we only have to consider
466 two or three littlenums, since the greatest number of mantissa
467 bits required is 24 + 1 rounding bit. While two littlenums
468 provide 32 bits of precision, the most significant littlenum
469 may only contain a single significant bit and thus an extra
470 littlenum is required.
471
472 Denoting the number of bits in the fraction field as F, we require
473 G = F + 2 bits (one extra bit is for rounding, the other gets
474 suppressed). Say we required S shifts to find the most
475 significant bit in the leader littlenum, the number of left shifts
476 required to move this bit into bit position G - 1 is L = G + S - 17.
477 Note that this shift count may be negative for the short floating
478 point flavour (where F = 11 and thus G = 13 and potentially S < 3).
479 If L > 0 we have to shunt the next littlenum into position. Bit
480 15 (the MSB) of the next littlenum needs to get moved into position
481 L - 1 (If L > 15 we need all the bits of this littlenum and
482 some more from the next one.). We subtract 16 from L and use this
483 as the left shift count; the resultant value we or with the
484 previous result. If L > 0, we repeat this operation. */
485
486 if (precision != S_PRECISION)
487 words[1] = 0x0000;
488 if (precision == E_PRECISION)
489 words[2] = words[3] = 0x0000;
490
491 /* 0.0e0 or NaN seen. */
492 if (flonum.low > flonum.leader /* = 0.0e0 */
493 || flonum.sign == 0) /* = NaN */
494 {
495 if(flonum.sign == 0)
496 as_bad ("Nan, using zero.");
497 words[0] = 0x8000;
498 return return_value;
499 }
500
501 if (flonum.sign == 'P')
502 {
503 /* +INF: Replace with maximum float. */
504 if (precision == S_PRECISION)
505 words[0] = 0x77ff;
506 else
507 {
508 words[0] = 0x7f7f;
509 words[1] = 0xffff;
510 }
511 if (precision == E_PRECISION)
512 {
513 words[2] = 0x7fff;
514 words[3] = 0xffff;
515 }
516 return return_value;
517 }
518 else if (flonum.sign == 'N')
519 {
520 /* -INF: Replace with maximum float. */
521 if (precision == S_PRECISION)
522 words[0] = 0x7800;
523 else
524 words[0] = 0x7f80;
525 if (precision == E_PRECISION)
526 words[2] = 0x8000;
527 return return_value;
528 }
529
530 exponent = (flonum.exponent + flonum.leader - flonum.low + 1) * 16;
531
532 if (!(tmp = *flonum.leader))
533 abort (); /* Hmmm. */
534 shift = 0; /* Find position of first sig. bit. */
535 while (tmp >>= 1)
536 shift++;
537 exponent -= (16 - shift); /* Adjust exponent. */
538
539 if (precision == S_PRECISION) /* Allow 1 rounding bit. */
540 {
541 exponent_bits = 4;
542 mantissa_bits = 11;
543 }
544 else if(precision == F_PRECISION)
545 {
546 exponent_bits = 8;
547 mantissa_bits = 23;
548 }
549 else /* E_PRECISION */
550 {
551 exponent_bits = 8;
552 mantissa_bits = 31;
553 }
554
555 shift = mantissa_bits - shift;
556
557 smant = 0;
558 mover = 0;
559 rbit = 0;
560 /* Store the mantissa data into smant and the roundbit into rbit */
561 for (p = flonum.leader; p >= flonum.low && shift > -16; p--)
562 {
563 tmp = shift >= 0 ? *p << shift : *p >> -shift;
564 rbit = shift < 0 ? ((*p >> (-shift-1)) & 0x1) : 0;
565 smant |= tmp;
566 shift -= 16;
567 }
568
569 /* OK, we've got our scaled mantissa so let's round it up */
570 if(rbit)
571 {
572 /* If the mantissa is going to overflow when added, lets store
573 the extra bit in mover. -- A special case exists when
574 mantissa_bits is 31 (E_PRECISION). Then the first test cannot
575 be trusted, as result is host-dependent, thus the second
576 test. */
577 if( smant == ((unsigned)(1<<(mantissa_bits+1))-1)
578 || smant == (unsigned)-1 ) /* This is to catch E_PRECISION cases */
579 mover=1;
580 smant++;
581 }
582
583 /* Get the scaled one value */
584 sone = (1 << (mantissa_bits));
585
586 /* The number may be unnormalised so renormalise it... */
587 if(mover)
588 {
589 smant >>= 1;
590 smant |= sone; /* Insert the bit from mover into smant */
591 exponent++;
592 }
593
594 /* The binary point is now between bit positions 11 and 10 or 23 and 22,
595 i.e., between mantissa_bits - 1 and mantissa_bits - 2 and the
596 bit at mantissa_bits - 1 should be set. */
597 if (!(sone&smant))
598 abort (); /* Ooops. */
599
600 if (flonum.sign == '+')
601 sfract = smant - sone; /* smant - 1.0. */
602 else
603 {
604 /* This seems to work. */
605 if (smant == sone)
606 {
607 exponent--;
608 sfract = 0;
609 }
610 else
611 {
612 sfract = -smant & (sone-1); /* 2.0 - smant. */
613 }
614 sfract |= sone; /* Insert sign bit. */
615 }
616
617 if (abs (exponent) >= (1 << (exponent_bits - 1)))
618 as_bad ("Cannot represent exponent in %d bits", exponent_bits);
619
620 /* Force exponent to fit in desired field width. */
621 exponent &= (1 << (exponent_bits)) - 1;
622
623 if (precision == E_PRECISION)
624 {
625 /* Map the float part first (100% equal format as F_PRECISION) */
626 words[0] = exponent << (mantissa_bits+1-24);
627 words[0] |= sfract >> 24;
628 words[1] = sfract >> 8;
629
630 /* Map the mantissa in the next */
631 words[2] = sfract >> 16;
632 words[3] = sfract & 0xffff;
633 }
634 else
635 {
636 /* Insert the exponent data into the word */
637 sfract |= exponent << (mantissa_bits+1);
638
639 if (precision == S_PRECISION)
640 words[0] = sfract;
641 else
642 {
643 words[0] = sfract >> 16;
644 words[1] = sfract & 0xffff;
645 }
646 }
647
648 return return_value;
649 }
650
651 /* Returns pointer past text consumed. */
652 static char *
653 tic4x_atof (str, what_kind, words)
654 char *str;
655 char what_kind;
656 LITTLENUM_TYPE *words;
657 {
658 /* Extra bits for zeroed low-order bits. The 1st MAX_PRECISION are
659 zeroed, the last contain flonum bits. */
660 static LITTLENUM_TYPE bits[MAX_PRECISION + MAX_PRECISION + GUARD];
661 char *return_value;
662 /* Number of 16-bit words in the format. */
663 int precision;
664 FLONUM_TYPE save_gen_flonum;
665
666 /* We have to save the generic_floating_point_number because it
667 contains storage allocation about the array of LITTLENUMs where
668 the value is actually stored. We will allocate our own array of
669 littlenums below, but have to restore the global one on exit. */
670 save_gen_flonum = generic_floating_point_number;
671
672 return_value = str;
673 generic_floating_point_number.low = bits + MAX_PRECISION;
674 generic_floating_point_number.high = NULL;
675 generic_floating_point_number.leader = NULL;
676 generic_floating_point_number.exponent = 0;
677 generic_floating_point_number.sign = '\0';
678
679 /* Use more LittleNums than seems necessary: the highest flonum may
680 have 15 leading 0 bits, so could be useless. */
681
682 memset (bits, '\0', sizeof (LITTLENUM_TYPE) * MAX_PRECISION);
683
684 switch (what_kind)
685 {
686 case 's':
687 case 'S':
688 precision = S_PRECISION;
689 break;
690
691 case 'd':
692 case 'D':
693 case 'f':
694 case 'F':
695 precision = F_PRECISION;
696 break;
697
698 case 'E':
699 case 'e':
700 precision = E_PRECISION;
701 break;
702
703 default:
704 as_bad ("Invalid floating point number");
705 return (NULL);
706 }
707
708 generic_floating_point_number.high
709 = generic_floating_point_number.low + precision - 1 + GUARD;
710
711 if (atof_generic (&return_value, ".", EXP_CHARS,
712 &generic_floating_point_number))
713 {
714 as_bad ("Invalid floating point number");
715 return (NULL);
716 }
717
718 tic4x_gen_to_words (generic_floating_point_number,
719 words, precision);
720
721 /* Restore the generic_floating_point_number's storage alloc (and
722 everything else). */
723 generic_floating_point_number = save_gen_flonum;
724
725 return return_value;
726 }
727
728 static void
729 tic4x_insert_reg (regname, regnum)
730 char *regname;
731 int regnum;
732 {
733 char buf[32];
734 int i;
735
736 symbol_table_insert (symbol_new (regname, reg_section, (valueT) regnum,
737 &zero_address_frag));
738 for (i = 0; regname[i]; i++)
739 buf[i] = islower (regname[i]) ? TOUPPER (regname[i]) : regname[i];
740 buf[i] = '\0';
741
742 symbol_table_insert (symbol_new (buf, reg_section, (valueT) regnum,
743 &zero_address_frag));
744 }
745
746 static void
747 tic4x_insert_sym (symname, value)
748 char *symname;
749 int value;
750 {
751 symbolS *symbolP;
752
753 symbolP = symbol_new (symname, absolute_section,
754 (valueT) value, &zero_address_frag);
755 SF_SET_LOCAL (symbolP);
756 symbol_table_insert (symbolP);
757 }
758
759 static char *
760 tic4x_expression (str, exp)
761 char *str;
762 expressionS *exp;
763 {
764 char *s;
765 char *t;
766
767 t = input_line_pointer; /* Save line pointer. */
768 input_line_pointer = str;
769 expression (exp);
770 s = input_line_pointer;
771 input_line_pointer = t; /* Restore line pointer. */
772 return s; /* Return pointer to where parsing stopped. */
773 }
774
775 static char *
776 tic4x_expression_abs (str, value)
777 char *str;
778 int *value;
779 {
780 char *s;
781 char *t;
782
783 t = input_line_pointer; /* Save line pointer. */
784 input_line_pointer = str;
785 *value = get_absolute_expression ();
786 s = input_line_pointer;
787 input_line_pointer = t; /* Restore line pointer. */
788 return s;
789 }
790
791 static void
792 tic4x_emit_char (c,b)
793 char c;
794 int b;
795 {
796 expressionS exp;
797
798 exp.X_op = O_constant;
799 exp.X_add_number = c;
800 emit_expr (&exp, b);
801 }
802
803 static void
804 tic4x_seg_alloc (name, seg, size, symbolP)
805 char *name ATTRIBUTE_UNUSED;
806 segT seg ATTRIBUTE_UNUSED;
807 int size;
808 symbolS *symbolP;
809 {
810 /* Note that the size is in words
811 so we multiply it by 4 to get the number of bytes to allocate. */
812
813 /* If we have symbol: .usect ".fred", size etc.,
814 the symbol needs to point to the first location reserved
815 by the pseudo op. */
816
817 if (size)
818 {
819 char *p;
820
821 p = frag_var (rs_fill, 1, 1, (relax_substateT) 0,
822 (symbolS *) symbolP,
823 size * OCTETS_PER_BYTE, (char *) 0);
824 *p = 0;
825 }
826 }
827
828 /* .asg ["]character-string["], symbol */
829 static void
830 tic4x_asg (x)
831 int x ATTRIBUTE_UNUSED;
832 {
833 char c;
834 char *name;
835 char *str;
836 char *tmp;
837
838 SKIP_WHITESPACE ();
839 str = input_line_pointer;
840
841 /* Skip string expression. */
842 while (*input_line_pointer != ',' && *input_line_pointer)
843 input_line_pointer++;
844 if (*input_line_pointer != ',')
845 {
846 as_bad ("Comma expected\n");
847 return;
848 }
849 *input_line_pointer++ = '\0';
850 name = input_line_pointer;
851 c = get_symbol_end (); /* Get terminator. */
852 tmp = xmalloc (strlen (str) + 1);
853 strcpy (tmp, str);
854 str = tmp;
855 tmp = xmalloc (strlen (name) + 1);
856 strcpy (tmp, name);
857 name = tmp;
858 if (hash_find (tic4x_asg_hash, name))
859 hash_replace (tic4x_asg_hash, name, (PTR) str);
860 else
861 hash_insert (tic4x_asg_hash, name, (PTR) str);
862 *input_line_pointer = c;
863 demand_empty_rest_of_line ();
864 }
865
866 /* .bss symbol, size */
867 static void
868 tic4x_bss (x)
869 int x ATTRIBUTE_UNUSED;
870 {
871 char c;
872 char *name;
873 char *p;
874 int size;
875 segT current_seg;
876 subsegT current_subseg;
877 symbolS *symbolP;
878
879 current_seg = now_seg; /* Save current seg. */
880 current_subseg = now_subseg; /* Save current subseg. */
881
882 SKIP_WHITESPACE ();
883 name = input_line_pointer;
884 c = get_symbol_end (); /* Get terminator. */
885 if (c != ',')
886 {
887 as_bad (".bss size argument missing\n");
888 return;
889 }
890
891 input_line_pointer =
892 tic4x_expression_abs (++input_line_pointer, &size);
893 if (size < 0)
894 {
895 as_bad (".bss size %d < 0!", size);
896 return;
897 }
898 subseg_set (bss_section, 0);
899 symbolP = symbol_find_or_make (name);
900
901 if (S_GET_SEGMENT (symbolP) == bss_section)
902 symbol_get_frag (symbolP)->fr_symbol = 0;
903
904 symbol_set_frag (symbolP, frag_now);
905
906 p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
907 size * OCTETS_PER_BYTE, (char *) 0);
908 *p = 0; /* Fill char. */
909
910 S_SET_SEGMENT (symbolP, bss_section);
911
912 /* The symbol may already have been created with a preceding
913 ".globl" directive -- be careful not to step on storage class
914 in that case. Otherwise, set it to static. */
915 if (S_GET_STORAGE_CLASS (symbolP) != C_EXT)
916 S_SET_STORAGE_CLASS (symbolP, C_STAT);
917
918 subseg_set (current_seg, current_subseg); /* Restore current seg. */
919 demand_empty_rest_of_line ();
920 }
921
922 static void
923 tic4x_globl (ignore)
924 int ignore ATTRIBUTE_UNUSED;
925 {
926 char *name;
927 int c;
928 symbolS *symbolP;
929
930 do
931 {
932 name = input_line_pointer;
933 c = get_symbol_end ();
934 symbolP = symbol_find_or_make (name);
935 *input_line_pointer = c;
936 SKIP_WHITESPACE ();
937 S_SET_STORAGE_CLASS (symbolP, C_EXT);
938 if (c == ',')
939 {
940 input_line_pointer++;
941 SKIP_WHITESPACE ();
942 if (*input_line_pointer == '\n')
943 c = '\n';
944 }
945 }
946 while (c == ',');
947
948 demand_empty_rest_of_line ();
949 }
950
951 /* Handle .byte, .word. .int, .long */
952 static void
953 tic4x_cons (bytes)
954 int bytes;
955 {
956 register unsigned int c;
957 do
958 {
959 SKIP_WHITESPACE ();
960 if (*input_line_pointer == '"')
961 {
962 input_line_pointer++;
963 while (is_a_char (c = next_char_of_string ()))
964 tic4x_emit_char (c, 4);
965 know (input_line_pointer[-1] == '\"');
966 }
967 else
968 {
969 expressionS exp;
970
971 input_line_pointer = tic4x_expression (input_line_pointer, &exp);
972 if (exp.X_op == O_constant)
973 {
974 switch (bytes)
975 {
976 case 1:
977 exp.X_add_number &= 255;
978 break;
979 case 2:
980 exp.X_add_number &= 65535;
981 break;
982 }
983 }
984 /* Perhaps we should disallow .byte and .hword with
985 a non constant expression that will require relocation. */
986 emit_expr (&exp, 4);
987 }
988 }
989 while (*input_line_pointer++ == ',');
990
991 input_line_pointer--; /* Put terminator back into stream. */
992 demand_empty_rest_of_line ();
993 }
994
995 /* Handle .ascii, .asciz, .string */
996 static void
997 tic4x_stringer (append_zero)
998 int append_zero; /*ex: bytes */
999 {
1000 int bytes;
1001 register unsigned int c;
1002
1003 bytes = 0;
1004 do
1005 {
1006 SKIP_WHITESPACE ();
1007 if (*input_line_pointer == '"')
1008 {
1009 input_line_pointer++;
1010 while (is_a_char (c = next_char_of_string ()))
1011 {
1012 tic4x_emit_char (c, 1);
1013 bytes++;
1014 }
1015
1016 if (append_zero)
1017 {
1018 tic4x_emit_char (c, 1);
1019 bytes++;
1020 }
1021
1022 know (input_line_pointer[-1] == '\"');
1023 }
1024 else
1025 {
1026 expressionS exp;
1027
1028 input_line_pointer = tic4x_expression (input_line_pointer, &exp);
1029 if (exp.X_op != O_constant)
1030 {
1031 as_bad("Non-constant symbols not allowed\n");
1032 return;
1033 }
1034 exp.X_add_number &= 255; /* Limit numeber to 8-bit */
1035 emit_expr (&exp, 1);
1036 bytes++;
1037 }
1038 }
1039 while (*input_line_pointer++ == ',');
1040
1041 /* Fill out the rest of the expression with 0's to fill up a full word */
1042 if ( bytes&0x3 )
1043 tic4x_emit_char (0, 4-(bytes&0x3));
1044
1045 input_line_pointer--; /* Put terminator back into stream. */
1046 demand_empty_rest_of_line ();
1047 }
1048
1049 /* .eval expression, symbol */
1050 static void
1051 tic4x_eval (x)
1052 int x ATTRIBUTE_UNUSED;
1053 {
1054 char c;
1055 int value;
1056 char *name;
1057
1058 SKIP_WHITESPACE ();
1059 input_line_pointer =
1060 tic4x_expression_abs (input_line_pointer, &value);
1061 if (*input_line_pointer++ != ',')
1062 {
1063 as_bad ("Symbol missing\n");
1064 return;
1065 }
1066 name = input_line_pointer;
1067 c = get_symbol_end (); /* Get terminator. */
1068 demand_empty_rest_of_line ();
1069 tic4x_insert_sym (name, value);
1070 }
1071
1072 /* Reset local labels. */
1073 static void
1074 tic4x_newblock (x)
1075 int x ATTRIBUTE_UNUSED;
1076 {
1077 dollar_label_clear ();
1078 }
1079
1080 /* .sect "section-name" [, value] */
1081 /* .sect ["]section-name[:subsection-name]["] [, value] */
1082 static void
1083 tic4x_sect (x)
1084 int x ATTRIBUTE_UNUSED;
1085 {
1086 char c;
1087 char *section_name;
1088 char *subsection_name;
1089 char *name;
1090 segT seg;
1091 int num;
1092
1093 SKIP_WHITESPACE ();
1094 if (*input_line_pointer == '"')
1095 input_line_pointer++;
1096 section_name = input_line_pointer;
1097 c = get_symbol_end (); /* Get terminator. */
1098 input_line_pointer++; /* Skip null symbol terminator. */
1099 name = xmalloc (input_line_pointer - section_name + 1);
1100 strcpy (name, section_name);
1101
1102 /* TI C from version 5.0 allows a section name to contain a
1103 subsection name as well. The subsection name is separated by a
1104 ':' from the section name. Currently we scan the subsection
1105 name and discard it.
1106 Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>. */
1107 if (c == ':')
1108 {
1109 subsection_name = input_line_pointer;
1110 c = get_symbol_end (); /* Get terminator. */
1111 input_line_pointer++; /* Skip null symbol terminator. */
1112 as_warn (".sect: subsection name ignored");
1113 }
1114
1115 /* We might still have a '"' to discard, but the character after a
1116 symbol name will be overwritten with a \0 by get_symbol_end()
1117 [VK]. */
1118
1119 if (c == ',')
1120 input_line_pointer =
1121 tic4x_expression_abs (input_line_pointer, &num);
1122 else if (*input_line_pointer == ',')
1123 {
1124 input_line_pointer =
1125 tic4x_expression_abs (++input_line_pointer, &num);
1126 }
1127 else
1128 num = 0;
1129
1130 seg = subseg_new (name, num);
1131 if (line_label != NULL)
1132 {
1133 S_SET_SEGMENT (line_label, seg);
1134 symbol_set_frag (line_label, frag_now);
1135 }
1136
1137 if (bfd_get_section_flags (stdoutput, seg) == SEC_NO_FLAGS)
1138 {
1139 if (!bfd_set_section_flags (stdoutput, seg, SEC_DATA))
1140 as_warn ("Error setting flags for \"%s\": %s", name,
1141 bfd_errmsg (bfd_get_error ()));
1142 }
1143
1144 /* If the last character overwritten by get_symbol_end() was an
1145 end-of-line, we must restore it or the end of the line will not be
1146 recognised and scanning extends into the next line, stopping with
1147 an error (blame Volker Kuhlmann <v.kuhlmann@elec.canterbury.ac.nz>
1148 if this is not true). */
1149 if (is_end_of_line[(unsigned char) c])
1150 *(--input_line_pointer) = c;
1151
1152 demand_empty_rest_of_line ();
1153 }
1154
1155 /* symbol[:] .set value or .set symbol, value */
1156 static void
1157 tic4x_set (x)
1158 int x ATTRIBUTE_UNUSED;
1159 {
1160 symbolS *symbolP;
1161
1162 SKIP_WHITESPACE ();
1163 if ((symbolP = line_label) == NULL)
1164 {
1165 char c;
1166 char *name;
1167
1168 name = input_line_pointer;
1169 c = get_symbol_end (); /* Get terminator. */
1170 if (c != ',')
1171 {
1172 as_bad (".set syntax invalid\n");
1173 ignore_rest_of_line ();
1174 return;
1175 }
1176 symbolP = symbol_find_or_make (name);
1177 }
1178 else
1179 symbol_table_insert (symbolP);
1180
1181 pseudo_set (symbolP);
1182 demand_empty_rest_of_line ();
1183 }
1184
1185 /* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
1186 static void
1187 tic4x_usect (x)
1188 int x ATTRIBUTE_UNUSED;
1189 {
1190 char c;
1191 char *name;
1192 char *section_name;
1193 segT seg;
1194 int size, alignment_flag;
1195 segT current_seg;
1196 subsegT current_subseg;
1197
1198 current_seg = now_seg; /* save current seg. */
1199 current_subseg = now_subseg; /* save current subseg. */
1200
1201 SKIP_WHITESPACE ();
1202 if (*input_line_pointer == '"')
1203 input_line_pointer++;
1204 section_name = input_line_pointer;
1205 c = get_symbol_end (); /* Get terminator. */
1206 input_line_pointer++; /* Skip null symbol terminator. */
1207 name = xmalloc (input_line_pointer - section_name + 1);
1208 strcpy (name, section_name);
1209
1210 if (c == ',')
1211 input_line_pointer =
1212 tic4x_expression_abs (input_line_pointer, &size);
1213 else if (*input_line_pointer == ',')
1214 {
1215 input_line_pointer =
1216 tic4x_expression_abs (++input_line_pointer, &size);
1217 }
1218 else
1219 size = 0;
1220
1221 /* Read a possibly present third argument (alignment flag) [VK]. */
1222 if (*input_line_pointer == ',')
1223 {
1224 input_line_pointer =
1225 tic4x_expression_abs (++input_line_pointer, &alignment_flag);
1226 }
1227 else
1228 alignment_flag = 0;
1229 if (alignment_flag)
1230 as_warn (".usect: non-zero alignment flag ignored");
1231
1232 seg = subseg_new (name, 0);
1233 if (line_label != NULL)
1234 {
1235 S_SET_SEGMENT (line_label, seg);
1236 symbol_set_frag (line_label, frag_now);
1237 S_SET_VALUE (line_label, frag_now_fix ());
1238 }
1239 seg_info (seg)->bss = 1; /* Uninitialised data. */
1240 if (!bfd_set_section_flags (stdoutput, seg, SEC_ALLOC))
1241 as_warn ("Error setting flags for \"%s\": %s", name,
1242 bfd_errmsg (bfd_get_error ()));
1243 tic4x_seg_alloc (name, seg, size, line_label);
1244
1245 if (S_GET_STORAGE_CLASS (line_label) != C_EXT)
1246 S_SET_STORAGE_CLASS (line_label, C_STAT);
1247
1248 subseg_set (current_seg, current_subseg); /* Restore current seg. */
1249 demand_empty_rest_of_line ();
1250 }
1251
1252 /* .version cpu-version. */
1253 static void
1254 tic4x_version (x)
1255 int x ATTRIBUTE_UNUSED;
1256 {
1257 unsigned int temp;
1258
1259 input_line_pointer =
1260 tic4x_expression_abs (input_line_pointer, &temp);
1261 if (!IS_CPU_TIC3X (temp) && !IS_CPU_TIC4X (temp))
1262 as_bad ("This assembler does not support processor generation %d",
1263 temp);
1264
1265 if (tic4x_cpu && temp != tic4x_cpu)
1266 as_warn ("Changing processor generation on fly not supported...");
1267 tic4x_cpu = temp;
1268 demand_empty_rest_of_line ();
1269 }
1270
1271 static void
1272 tic4x_init_regtable ()
1273 {
1274 unsigned int i;
1275
1276 for (i = 0; i < tic3x_num_registers; i++)
1277 tic4x_insert_reg (tic3x_registers[i].name,
1278 tic3x_registers[i].regno);
1279
1280 if (IS_CPU_TIC4X (tic4x_cpu))
1281 {
1282 /* Add additional Tic4x registers, overriding some C3x ones. */
1283 for (i = 0; i < tic4x_num_registers; i++)
1284 tic4x_insert_reg (tic4x_registers[i].name,
1285 tic4x_registers[i].regno);
1286 }
1287 }
1288
1289 static void
1290 tic4x_init_symbols ()
1291 {
1292 /* The TI tools accept case insensitive versions of these symbols,
1293 we don't !
1294
1295 For TI C/Asm 5.0
1296
1297 .TMS320xx 30,31,32,40,or 44 set according to -v flag
1298 .C3X or .C3x 1 or 0 1 if -v30,-v31,or -v32
1299 .C30 1 or 0 1 if -v30
1300 .C31 1 or 0 1 if -v31
1301 .C32 1 or 0 1 if -v32
1302 .C4X or .C4x 1 or 0 1 if -v40, or -v44
1303 .C40 1 or 0 1 if -v40
1304 .C44 1 or 0 1 if -v44
1305
1306 .REGPARM 1 or 0 1 if -mr option used
1307 .BIGMODEL 1 or 0 1 if -mb option used
1308
1309 These symbols are currently supported but will be removed in a
1310 later version:
1311 .TMS320C30 1 or 0 1 if -v30,-v31,or -v32
1312 .TMS320C31 1 or 0 1 if -v31
1313 .TMS320C32 1 or 0 1 if -v32
1314 .TMS320C40 1 or 0 1 if -v40, or -v44
1315 .TMS320C44 1 or 0 1 if -v44
1316
1317 Source: TI: TMS320C3x/C4x Assembly Language Tools User's Guide,
1318 1997, SPRU035C, p. 3-17/3-18. */
1319 tic4x_insert_sym (".REGPARM", tic4x_reg_args);
1320 tic4x_insert_sym (".MEMPARM", !tic4x_reg_args);
1321 tic4x_insert_sym (".BIGMODEL", tic4x_big_model);
1322 tic4x_insert_sym (".C30INTERRUPT", 0);
1323 tic4x_insert_sym (".TMS320xx", tic4x_cpu == 0 ? 40 : tic4x_cpu);
1324 tic4x_insert_sym (".C3X", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1325 tic4x_insert_sym (".C3x", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1326 tic4x_insert_sym (".C4X", tic4x_cpu == 0 || tic4x_cpu == 40 || tic4x_cpu == 44);
1327 tic4x_insert_sym (".C4x", tic4x_cpu == 0 || tic4x_cpu == 40 || tic4x_cpu == 44);
1328 /* Do we need to have the following symbols also in lower case? */
1329 tic4x_insert_sym (".TMS320C30", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1330 tic4x_insert_sym (".tms320C30", tic4x_cpu == 30 || tic4x_cpu == 31 || tic4x_cpu == 32 || tic4x_cpu == 33);
1331 tic4x_insert_sym (".TMS320C31", tic4x_cpu == 31);
1332 tic4x_insert_sym (".tms320C31", tic4x_cpu == 31);
1333 tic4x_insert_sym (".TMS320C32", tic4x_cpu == 32);
1334 tic4x_insert_sym (".tms320C32", tic4x_cpu == 32);
1335 tic4x_insert_sym (".TMS320C33", tic4x_cpu == 33);
1336 tic4x_insert_sym (".tms320C33", tic4x_cpu == 33);
1337 tic4x_insert_sym (".TMS320C40", tic4x_cpu == 40 || tic4x_cpu == 44 || tic4x_cpu == 0);
1338 tic4x_insert_sym (".tms320C40", tic4x_cpu == 40 || tic4x_cpu == 44 || tic4x_cpu == 0);
1339 tic4x_insert_sym (".TMS320C44", tic4x_cpu == 44);
1340 tic4x_insert_sym (".tms320C44", tic4x_cpu == 44);
1341 tic4x_insert_sym (".TMX320C40", 0); /* C40 first pass silicon ? */
1342 tic4x_insert_sym (".tmx320C40", 0);
1343 }
1344
1345 /* Insert a new instruction template into hash table. */
1346 static int
1347 tic4x_inst_insert (inst)
1348 tic4x_inst_t *inst;
1349 {
1350 static char prev_name[16];
1351 const char *retval = NULL;
1352
1353 /* Only insert the first name if have several similar entries. */
1354 if (!strcmp (inst->name, prev_name) || inst->name[0] == '\0')
1355 return 1;
1356
1357 retval = hash_insert (tic4x_op_hash, inst->name, (PTR) inst);
1358 if (retval != NULL)
1359 fprintf (stderr, "internal error: can't hash `%s': %s\n",
1360 inst->name, retval);
1361 else
1362 strcpy (prev_name, inst->name);
1363 return retval == NULL;
1364 }
1365
1366 /* Make a new instruction template. */
1367 static tic4x_inst_t *
1368 tic4x_inst_make (name, opcode, args)
1369 char *name;
1370 unsigned long opcode;
1371 char *args;
1372 {
1373 static tic4x_inst_t *insts = NULL;
1374 static char *names = NULL;
1375 static int index = 0;
1376
1377 if (insts == NULL)
1378 {
1379 /* Allocate memory to store name strings. */
1380 names = (char *) xmalloc (sizeof (char) * 8192);
1381 /* Allocate memory for additional insts. */
1382 insts = (tic4x_inst_t *)
1383 xmalloc (sizeof (tic4x_inst_t) * 1024);
1384 }
1385 insts[index].name = names;
1386 insts[index].opcode = opcode;
1387 insts[index].opmask = 0xffffffff;
1388 insts[index].args = args;
1389 index++;
1390
1391 do
1392 *names++ = *name++;
1393 while (*name);
1394 *names++ = '\0';
1395
1396 return &insts[index - 1];
1397 }
1398
1399 /* Add instruction template, creating dynamic templates as required. */
1400 static int
1401 tic4x_inst_add (insts)
1402 tic4x_inst_t *insts;
1403 {
1404 char *s = insts->name;
1405 char *d;
1406 unsigned int i;
1407 int ok = 1;
1408 char name[16];
1409
1410 d = name;
1411
1412 /* We do not care about INSNs that is not a part of our
1413 oplevel setting */
1414 if (!insts->oplevel & tic4x_oplevel)
1415 return ok;
1416
1417 while (1)
1418 {
1419 switch (*s)
1420 {
1421 case 'B':
1422 case 'C':
1423 /* Dynamically create all the conditional insts. */
1424 for (i = 0; i < tic4x_num_conds; i++)
1425 {
1426 tic4x_inst_t *inst;
1427 int k = 0;
1428 char *c = tic4x_conds[i].name;
1429 char *e = d;
1430
1431 while (*c)
1432 *e++ = *c++;
1433 c = s + 1;
1434 while (*c)
1435 *e++ = *c++;
1436 *e = '\0';
1437
1438 /* If instruction found then have already processed it. */
1439 if (hash_find (tic4x_op_hash, name))
1440 return 1;
1441
1442 do
1443 {
1444 inst = tic4x_inst_make (name, insts[k].opcode +
1445 (tic4x_conds[i].cond <<
1446 (*s == 'B' ? 16 : 23)),
1447 insts[k].args);
1448 if (k == 0) /* Save strcmp() with following func. */
1449 ok &= tic4x_inst_insert (inst);
1450 k++;
1451 }
1452 while (!strcmp (insts->name,
1453 insts[k].name));
1454 }
1455 return ok;
1456 break;
1457
1458 case '\0':
1459 return tic4x_inst_insert (insts);
1460 break;
1461
1462 default:
1463 *d++ = *s++;
1464 break;
1465 }
1466 }
1467 }
1468
1469 /* This function is called once, at assembler startup time. It should
1470 set up all the tables, etc., that the MD part of the assembler will
1471 need. */
1472 void
1473 md_begin ()
1474 {
1475 int ok = 1;
1476 unsigned int i;
1477
1478 /* Setup the proper opcode level according to the
1479 commandline parameters */
1480 tic4x_oplevel = OP_C3X;
1481
1482 if ( IS_CPU_TIC4X(tic4x_cpu) )
1483 tic4x_oplevel |= OP_C4X;
1484
1485 if ( ( tic4x_cpu == 31 && tic4x_revision >= 6)
1486 || (tic4x_cpu == 32 && tic4x_revision >= 2)
1487 || (tic4x_cpu == 33)
1488 || tic4x_enhanced )
1489 tic4x_oplevel |= OP_ENH;
1490
1491 if ( ( tic4x_cpu == 30 && tic4x_revision >= 7)
1492 || (tic4x_cpu == 31 && tic4x_revision >= 5)
1493 || (tic4x_cpu == 32)
1494 || tic4x_lowpower )
1495 tic4x_oplevel |= OP_LPWR;
1496
1497 if ( ( tic4x_cpu == 30 && tic4x_revision >= 7)
1498 || (tic4x_cpu == 31 && tic4x_revision >= 5)
1499 || (tic4x_cpu == 32)
1500 || (tic4x_cpu == 33)
1501 || (tic4x_cpu == 40 && tic4x_revision >= 5)
1502 || (tic4x_cpu == 44)
1503 || tic4x_idle2 )
1504 tic4x_oplevel |= OP_IDLE2;
1505
1506 /* Create hash table for mnemonics. */
1507 tic4x_op_hash = hash_new ();
1508
1509 /* Create hash table for asg pseudo. */
1510 tic4x_asg_hash = hash_new ();
1511
1512 /* Add mnemonics to hash table, expanding conditional mnemonics on fly. */
1513 for (i = 0; i < tic4x_num_insts; i++)
1514 ok &= tic4x_inst_add ((void *) &tic4x_insts[i]);
1515
1516 /* Create dummy inst to avoid errors accessing end of table. */
1517 tic4x_inst_make ("", 0, "");
1518
1519 if (!ok)
1520 as_fatal ("Broken assembler. No assembly attempted.");
1521
1522 /* Add registers to symbol table. */
1523 tic4x_init_regtable ();
1524
1525 /* Add predefined symbols to symbol table. */
1526 tic4x_init_symbols ();
1527 }
1528
1529 void
1530 tic4x_end ()
1531 {
1532 bfd_set_arch_mach (stdoutput, bfd_arch_tic4x,
1533 IS_CPU_TIC4X (tic4x_cpu) ? bfd_mach_tic4x : bfd_mach_tic3x);
1534 }
1535
1536 static int
1537 tic4x_indirect_parse (operand, indirect)
1538 tic4x_operand_t *operand;
1539 const tic4x_indirect_t *indirect;
1540 {
1541 char *n = indirect->name;
1542 char *s = input_line_pointer;
1543 char *b;
1544 symbolS *symbolP;
1545 char name[32];
1546
1547 operand->disp = 0;
1548 for (; *n; n++)
1549 {
1550 switch (*n)
1551 {
1552 case 'a': /* Need to match aux register. */
1553 b = name;
1554 #ifdef TIC4X_ALT_SYNTAX
1555 if (*s == '%')
1556 s++;
1557 #endif
1558 while (ISALNUM (*s))
1559 *b++ = *s++;
1560 *b++ = '\0';
1561 if (!(symbolP = symbol_find (name)))
1562 return 0;
1563
1564 if (S_GET_SEGMENT (symbolP) != reg_section)
1565 return 0;
1566
1567 operand->aregno = S_GET_VALUE (symbolP);
1568 if (operand->aregno >= REG_AR0 && operand->aregno <= REG_AR7)
1569 break;
1570
1571 as_bad ("Auxiliary register AR0--AR7 required for indirect");
1572 return -1;
1573
1574 case 'd': /* Need to match constant for disp. */
1575 #ifdef TIC4X_ALT_SYNTAX
1576 if (*s == '%') /* expr() will die if we don't skip this. */
1577 s++;
1578 #endif
1579 s = tic4x_expression (s, &operand->expr);
1580 if (operand->expr.X_op != O_constant)
1581 return 0;
1582 operand->disp = operand->expr.X_add_number;
1583 if (operand->disp < 0 || operand->disp > 255)
1584 {
1585 as_bad ("Bad displacement %d (require 0--255)\n",
1586 operand->disp);
1587 return -1;
1588 }
1589 break;
1590
1591 case 'y': /* Need to match IR0. */
1592 case 'z': /* Need to match IR1. */
1593 #ifdef TIC4X_ALT_SYNTAX
1594 if (*s == '%')
1595 s++;
1596 #endif
1597 s = tic4x_expression (s, &operand->expr);
1598 if (operand->expr.X_op != O_register)
1599 return 0;
1600 if (operand->expr.X_add_number != REG_IR0
1601 && operand->expr.X_add_number != REG_IR1)
1602 {
1603 as_bad ("Index register IR0,IR1 required for displacement");
1604 return -1;
1605 }
1606
1607 if (*n == 'y' && operand->expr.X_add_number == REG_IR0)
1608 break;
1609 if (*n == 'z' && operand->expr.X_add_number == REG_IR1)
1610 break;
1611 return 0;
1612
1613 case '(':
1614 if (*s != '(') /* No displacement, assume to be 1. */
1615 {
1616 operand->disp = 1;
1617 while (*n != ')')
1618 n++;
1619 }
1620 else
1621 s++;
1622 break;
1623
1624 default:
1625 if (TOLOWER (*s) != *n)
1626 return 0;
1627 s++;
1628 }
1629 }
1630 if (*s != ' ' && *s != ',' && *s != '\0')
1631 return 0;
1632 input_line_pointer = s;
1633 return 1;
1634 }
1635
1636 static char *
1637 tic4x_operand_parse (s, operand)
1638 char *s;
1639 tic4x_operand_t *operand;
1640 {
1641 unsigned int i;
1642 char c;
1643 int ret;
1644 expressionS *exp = &operand->expr;
1645 char *save = input_line_pointer;
1646 char *str;
1647 char *new;
1648 struct hash_entry *entry = NULL;
1649
1650 input_line_pointer = s;
1651 SKIP_WHITESPACE ();
1652
1653 str = input_line_pointer;
1654 c = get_symbol_end (); /* Get terminator. */
1655 new = input_line_pointer;
1656 if (strlen (str) && (entry = hash_find (tic4x_asg_hash, str)) != NULL)
1657 {
1658 *input_line_pointer = c;
1659 input_line_pointer = (char *) entry;
1660 }
1661 else
1662 {
1663 *input_line_pointer = c;
1664 input_line_pointer = str;
1665 }
1666
1667 operand->mode = M_UNKNOWN;
1668 switch (*input_line_pointer)
1669 {
1670 #ifdef TIC4X_ALT_SYNTAX
1671 case '%':
1672 input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1673 if (exp->X_op != O_register)
1674 as_bad ("Expecting a register name");
1675 operand->mode = M_REGISTER;
1676 break;
1677
1678 case '^':
1679 /* Denotes high 16 bits. */
1680 input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1681 if (exp->X_op == O_constant)
1682 operand->mode = M_IMMED;
1683 else if (exp->X_op == O_big)
1684 {
1685 if (exp->X_add_number)
1686 as_bad ("Number too large"); /* bignum required */
1687 else
1688 {
1689 tic4x_gen_to_words (generic_floating_point_number,
1690 operand->fwords, S_PRECISION);
1691 operand->mode = M_IMMED_F;
1692 }
1693 }
1694 /* Allow ori ^foo, ar0 to be equivalent to ldi .hi.foo, ar0 */
1695 /* WARNING : The TI C40 assembler cannot do this. */
1696 else if (exp->X_op == O_symbol)
1697 {
1698 operand->mode = M_HI;
1699 break;
1700 }
1701
1702 case '#':
1703 input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1704 if (exp->X_op == O_constant)
1705 operand->mode = M_IMMED;
1706 else if (exp->X_op == O_big)
1707 {
1708 if (exp->X_add_number > 0)
1709 as_bad ("Number too large"); /* bignum required. */
1710 else
1711 {
1712 tic4x_gen_to_words (generic_floating_point_number,
1713 operand->fwords, S_PRECISION);
1714 operand->mode = M_IMMED_F;
1715 }
1716 }
1717 /* Allow ori foo, ar0 to be equivalent to ldi .lo.foo, ar0 */
1718 /* WARNING : The TI C40 assembler cannot do this. */
1719 else if (exp->X_op == O_symbol)
1720 {
1721 operand->mode = M_IMMED;
1722 break;
1723 }
1724
1725 else
1726 as_bad ("Expecting a constant value");
1727 break;
1728 case '\\':
1729 #endif
1730 case '@':
1731 input_line_pointer = tic4x_expression (++input_line_pointer, exp);
1732 if (exp->X_op != O_constant && exp->X_op != O_symbol)
1733 as_bad ("Bad direct addressing construct %s", s);
1734 if (exp->X_op == O_constant)
1735 {
1736 if (exp->X_add_number < 0)
1737 as_bad ("Direct value of %ld is not suitable",
1738 (long) exp->X_add_number);
1739 }
1740 operand->mode = M_DIRECT;
1741 break;
1742
1743 case '*':
1744 ret = -1;
1745 for (i = 0; i < tic4x_num_indirects; i++)
1746 if ((ret = tic4x_indirect_parse (operand, &tic4x_indirects[i])))
1747 break;
1748 if (ret < 0)
1749 break;
1750 if (i < tic4x_num_indirects)
1751 {
1752 operand->mode = M_INDIRECT;
1753 /* Indirect addressing mode number. */
1754 operand->expr.X_add_number = tic4x_indirects[i].modn;
1755 /* Convert *+ARn(0) to *ARn etc. Maybe we should
1756 squeal about silly ones? */
1757 if (operand->expr.X_add_number < 0x08 && !operand->disp)
1758 operand->expr.X_add_number = 0x18;
1759 }
1760 else
1761 as_bad ("Unknown indirect addressing mode");
1762 break;
1763
1764 default:
1765 operand->mode = M_IMMED; /* Assume immediate. */
1766 str = input_line_pointer;
1767 input_line_pointer = tic4x_expression (input_line_pointer, exp);
1768 if (exp->X_op == O_register)
1769 {
1770 know (exp->X_add_symbol == 0);
1771 know (exp->X_op_symbol == 0);
1772 operand->mode = M_REGISTER;
1773 break;
1774 }
1775 else if (exp->X_op == O_big)
1776 {
1777 if (exp->X_add_number > 0)
1778 as_bad ("Number too large"); /* bignum required. */
1779 else
1780 {
1781 tic4x_gen_to_words (generic_floating_point_number,
1782 operand->fwords, S_PRECISION);
1783 operand->mode = M_IMMED_F;
1784 }
1785 break;
1786 }
1787 #ifdef TIC4X_ALT_SYNTAX
1788 /* Allow ldi foo, ar0 to be equivalent to ldi @foo, ar0. */
1789 else if (exp->X_op == O_symbol)
1790 {
1791 operand->mode = M_DIRECT;
1792 break;
1793 }
1794 #endif
1795 }
1796 if (entry == NULL)
1797 new = input_line_pointer;
1798 input_line_pointer = save;
1799 return new;
1800 }
1801
1802 static int
1803 tic4x_operands_match (inst, insn, check)
1804 tic4x_inst_t *inst;
1805 tic4x_insn_t *insn;
1806 int check;
1807 {
1808 const char *args = inst->args;
1809 unsigned long opcode = inst->opcode;
1810 int num_operands = insn->num_operands;
1811 tic4x_operand_t *operand = insn->operands;
1812 expressionS *exp = &operand->expr;
1813 int ret = 1;
1814 int reg;
1815
1816 /* Build the opcode, checking as we go to make sure that the
1817 operands match.
1818
1819 If an operand matches, we modify insn or opcode appropriately,
1820 and do a "continue". If an operand fails to match, we "break". */
1821
1822 insn->nchars = 4; /* Instructions always 4 bytes. */
1823 insn->reloc = NO_RELOC;
1824 insn->pcrel = 0;
1825
1826 if (*args == '\0')
1827 {
1828 insn->opcode = opcode;
1829 return num_operands == 0;
1830 }
1831
1832 for (;; ++args)
1833 {
1834 switch (*args)
1835 {
1836
1837 case '\0': /* End of args. */
1838 if (num_operands == 1)
1839 {
1840 insn->opcode = opcode;
1841 return ret;
1842 }
1843 break; /* Too many operands. */
1844
1845 case '#': /* This is only used for ldp. */
1846 if (operand->mode != M_DIRECT && operand->mode != M_IMMED)
1847 break;
1848 /* While this looks like a direct addressing mode, we actually
1849 use an immediate mode form of ldiu or ldpk instruction. */
1850 if (exp->X_op == O_constant)
1851 {
1852 if( ( IS_CPU_TIC4X (tic4x_cpu) && exp->X_add_number <= 65535 )
1853 || ( IS_CPU_TIC3X (tic4x_cpu) && exp->X_add_number <= 255 ) )
1854 {
1855 INSERTS (opcode, exp->X_add_number, 15, 0);
1856 continue;
1857 }
1858 else
1859 {
1860 if (!check)
1861 as_bad ("Immediate value of %ld is too large for ldf",
1862 (long) exp->X_add_number);
1863 ret = -1;
1864 continue;
1865 }
1866 }
1867 else if (exp->X_op == O_symbol)
1868 {
1869 insn->reloc = BFD_RELOC_HI16;
1870 insn->exp = *exp;
1871 continue;
1872 }
1873 break; /* Not direct (dp) addressing. */
1874
1875 case '@': /* direct. */
1876 if (operand->mode != M_DIRECT)
1877 break;
1878 if (exp->X_op == O_constant)
1879 {
1880 /* Store only the 16 LSBs of the number. */
1881 INSERTS (opcode, exp->X_add_number, 15, 0);
1882 continue;
1883 }
1884 else if (exp->X_op == O_symbol)
1885 {
1886 insn->reloc = BFD_RELOC_LO16;
1887 insn->exp = *exp;
1888 continue;
1889 }
1890 break; /* Not direct addressing. */
1891
1892 case 'A':
1893 if (operand->mode != M_REGISTER)
1894 break;
1895 reg = exp->X_add_number;
1896 if (reg >= REG_AR0 && reg <= REG_AR7)
1897 INSERTU (opcode, reg - REG_AR0, 24, 22);
1898 else
1899 {
1900 if (!check)
1901 as_bad ("Destination register must be ARn");
1902 ret = -1;
1903 }
1904 continue;
1905
1906 case 'B': /* Unsigned integer immediate. */
1907 /* Allow br label or br @label. */
1908 if (operand->mode != M_IMMED && operand->mode != M_DIRECT)
1909 break;
1910 if (exp->X_op == O_constant)
1911 {
1912 if (exp->X_add_number < (1 << 24))
1913 {
1914 INSERTU (opcode, exp->X_add_number, 23, 0);
1915 continue;
1916 }
1917 else
1918 {
1919 if (!check)
1920 as_bad ("Immediate value of %ld is too large",
1921 (long) exp->X_add_number);
1922 ret = -1;
1923 continue;
1924 }
1925 }
1926 if (IS_CPU_TIC4X (tic4x_cpu))
1927 {
1928 insn->reloc = BFD_RELOC_24_PCREL;
1929 insn->pcrel = 1;
1930 }
1931 else
1932 {
1933 insn->reloc = BFD_RELOC_24;
1934 insn->pcrel = 0;
1935 }
1936 insn->exp = *exp;
1937 continue;
1938
1939 case 'C':
1940 if (!IS_CPU_TIC4X (tic4x_cpu))
1941 break;
1942 if (operand->mode != M_INDIRECT)
1943 break;
1944 /* Require either *+ARn(disp) or *ARn. */
1945 if (operand->expr.X_add_number != 0
1946 && operand->expr.X_add_number != 0x18)
1947 {
1948 if (!check)
1949 as_bad ("Invalid indirect addressing mode");
1950 ret = -1;
1951 continue;
1952 }
1953 INSERTU (opcode, operand->aregno - REG_AR0, 2, 0);
1954 INSERTU (opcode, operand->disp, 7, 3);
1955 continue;
1956
1957 case 'E':
1958 if (!(operand->mode == M_REGISTER))
1959 break;
1960 INSERTU (opcode, exp->X_add_number, 7, 0);
1961 continue;
1962
1963 case 'e':
1964 if (!(operand->mode == M_REGISTER))
1965 break;
1966 reg = exp->X_add_number;
1967 if ( (reg >= REG_R0 && reg <= REG_R7)
1968 || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
1969 INSERTU (opcode, reg, 7, 0);
1970 else
1971 {
1972 if (!check)
1973 as_bad ("Register must be Rn");
1974 ret = -1;
1975 }
1976 continue;
1977
1978 case 'F':
1979 if (operand->mode != M_IMMED_F
1980 && !(operand->mode == M_IMMED && exp->X_op == O_constant))
1981 break;
1982
1983 if (operand->mode != M_IMMED_F)
1984 {
1985 /* OK, we 've got something like cmpf 0, r0
1986 Why can't they stick in a bloody decimal point ?! */
1987 char string[16];
1988
1989 /* Create floating point number string. */
1990 sprintf (string, "%d.0", (int) exp->X_add_number);
1991 tic4x_atof (string, 's', operand->fwords);
1992 }
1993
1994 INSERTU (opcode, operand->fwords[0], 15, 0);
1995 continue;
1996
1997 case 'G':
1998 if (operand->mode != M_REGISTER)
1999 break;
2000 INSERTU (opcode, exp->X_add_number, 15, 8);
2001 continue;
2002
2003 case 'g':
2004 if (operand->mode != M_REGISTER)
2005 break;
2006 reg = exp->X_add_number;
2007 if ( (reg >= REG_R0 && reg <= REG_R7)
2008 || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
2009 INSERTU (opcode, reg, 15, 8);
2010 else
2011 {
2012 if (!check)
2013 as_bad ("Register must be Rn");
2014 ret = -1;
2015 }
2016 continue;
2017
2018 case 'H':
2019 if (operand->mode != M_REGISTER)
2020 break;
2021 reg = exp->X_add_number;
2022 if (reg >= REG_R0 && reg <= REG_R7)
2023 INSERTU (opcode, reg - REG_R0, 18, 16);
2024 else
2025 {
2026 if (!check)
2027 as_bad ("Register must be R0--R7");
2028 ret = -1;
2029 }
2030 continue;
2031
2032 case 'i':
2033 if ( operand->mode == M_REGISTER
2034 && tic4x_oplevel & OP_ENH )
2035 {
2036 reg = exp->X_add_number;
2037 INSERTU (opcode, reg, 4, 0);
2038 INSERTU (opcode, 7, 7, 5);
2039 continue;
2040 }
2041 /* Fallthrough */
2042
2043 case 'I':
2044 if (operand->mode != M_INDIRECT)
2045 break;
2046 if (operand->disp != 0 && operand->disp != 1)
2047 {
2048 if (IS_CPU_TIC4X (tic4x_cpu))
2049 break;
2050 if (!check)
2051 as_bad ("Invalid indirect addressing mode displacement %d",
2052 operand->disp);
2053 ret = -1;
2054 continue;
2055 }
2056 INSERTU (opcode, operand->aregno - REG_AR0, 2, 0);
2057 INSERTU (opcode, operand->expr.X_add_number, 7, 3);
2058 continue;
2059
2060 case 'j':
2061 if ( operand->mode == M_REGISTER
2062 && tic4x_oplevel & OP_ENH )
2063 {
2064 reg = exp->X_add_number;
2065 INSERTU (opcode, reg, 12, 8);
2066 INSERTU (opcode, 7, 15, 13);
2067 continue;
2068 }
2069 /* Fallthrough */
2070
2071 case 'J':
2072 if (operand->mode != M_INDIRECT)
2073 break;
2074 if (operand->disp != 0 && operand->disp != 1)
2075 {
2076 if (IS_CPU_TIC4X (tic4x_cpu))
2077 break;
2078 if (!check)
2079 as_bad ("Invalid indirect addressing mode displacement %d",
2080 operand->disp);
2081 ret = -1;
2082 continue;
2083 }
2084 INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
2085 INSERTU (opcode, operand->expr.X_add_number, 15, 11);
2086 continue;
2087
2088 case 'K':
2089 if (operand->mode != M_REGISTER)
2090 break;
2091 reg = exp->X_add_number;
2092 if (reg >= REG_R0 && reg <= REG_R7)
2093 INSERTU (opcode, reg - REG_R0, 21, 19);
2094 else
2095 {
2096 if (!check)
2097 as_bad ("Register must be R0--R7");
2098 ret = -1;
2099 }
2100 continue;
2101
2102 case 'L':
2103 if (operand->mode != M_REGISTER)
2104 break;
2105 reg = exp->X_add_number;
2106 if (reg >= REG_R0 && reg <= REG_R7)
2107 INSERTU (opcode, reg - REG_R0, 24, 22);
2108 else
2109 {
2110 if (!check)
2111 as_bad ("Register must be R0--R7");
2112 ret = -1;
2113 }
2114 continue;
2115
2116 case 'M':
2117 if (operand->mode != M_REGISTER)
2118 break;
2119 reg = exp->X_add_number;
2120 if (reg == REG_R2 || reg == REG_R3)
2121 INSERTU (opcode, reg - REG_R2, 22, 22);
2122 else
2123 {
2124 if (!check)
2125 as_bad ("Destination register must be R2 or R3");
2126 ret = -1;
2127 }
2128 continue;
2129
2130 case 'N':
2131 if (operand->mode != M_REGISTER)
2132 break;
2133 reg = exp->X_add_number;
2134 if (reg == REG_R0 || reg == REG_R1)
2135 INSERTU (opcode, reg - REG_R0, 23, 23);
2136 else
2137 {
2138 if (!check)
2139 as_bad ("Destination register must be R0 or R1");
2140 ret = -1;
2141 }
2142 continue;
2143
2144 case 'O':
2145 if (!IS_CPU_TIC4X (tic4x_cpu))
2146 break;
2147 if (operand->mode != M_INDIRECT)
2148 break;
2149 /* Require either *+ARn(disp) or *ARn. */
2150 if (operand->expr.X_add_number != 0
2151 && operand->expr.X_add_number != 0x18)
2152 {
2153 if (!check)
2154 as_bad ("Invalid indirect addressing mode");
2155 ret = -1;
2156 continue;
2157 }
2158 INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
2159 INSERTU (opcode, operand->disp, 15, 11);
2160 continue;
2161
2162 case 'P': /* PC relative displacement. */
2163 /* Allow br label or br @label. */
2164 if (operand->mode != M_IMMED && operand->mode != M_DIRECT)
2165 break;
2166 if (exp->X_op == O_constant)
2167 {
2168 if (exp->X_add_number >= -32768 && exp->X_add_number <= 32767)
2169 {
2170 INSERTS (opcode, exp->X_add_number, 15, 0);
2171 continue;
2172 }
2173 else
2174 {
2175 if (!check)
2176 as_bad ("Displacement value of %ld is too large",
2177 (long) exp->X_add_number);
2178 ret = -1;
2179 continue;
2180 }
2181 }
2182 insn->reloc = BFD_RELOC_16_PCREL;
2183 insn->pcrel = 1;
2184 insn->exp = *exp;
2185 continue;
2186
2187 case 'Q':
2188 if (operand->mode != M_REGISTER)
2189 break;
2190 reg = exp->X_add_number;
2191 INSERTU (opcode, reg, 15, 0);
2192 continue;
2193
2194 case 'q':
2195 if (operand->mode != M_REGISTER)
2196 break;
2197 reg = exp->X_add_number;
2198 if ( (reg >= REG_R0 && reg <= REG_R7)
2199 || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
2200 INSERTU (opcode, reg, 15, 0);
2201 else
2202 {
2203 if (!check)
2204 as_bad ("Register must be Rn");
2205 ret = -1;
2206 }
2207 continue;
2208
2209 case 'R':
2210 if (operand->mode != M_REGISTER)
2211 break;
2212 reg = exp->X_add_number;
2213 INSERTU (opcode, reg, 20, 16);
2214 continue;
2215
2216 case 'r':
2217 if (operand->mode != M_REGISTER)
2218 break;
2219 reg = exp->X_add_number;
2220 if ( (reg >= REG_R0 && reg <= REG_R7)
2221 || (IS_CPU_TIC4X (tic4x_cpu) && reg >= REG_R8 && reg <= REG_R11) )
2222 INSERTU (opcode, reg, 20, 16);
2223 else
2224 {
2225 if (!check)
2226 as_bad ("Register must be Rn");
2227 ret = -1;
2228 }
2229 continue;
2230
2231 case 'S': /* Short immediate int. */
2232 if (operand->mode != M_IMMED && operand->mode != M_HI)
2233 break;
2234 if (exp->X_op == O_big)
2235 {
2236 if (!check)
2237 as_bad ("Floating point number not valid in expression");
2238 ret = -1;
2239 continue;
2240 }
2241 if (exp->X_op == O_constant)
2242 {
2243 if (exp->X_add_number >= -32768 && exp->X_add_number <= 65535)
2244 {
2245 INSERTS (opcode, exp->X_add_number, 15, 0);
2246 continue;
2247 }
2248 else
2249 {
2250 if (!check)
2251 as_bad ("Signed immediate value %ld too large",
2252 (long) exp->X_add_number);
2253 ret = -1;
2254 continue;
2255 }
2256 }
2257 else if (exp->X_op == O_symbol)
2258 {
2259 if (operand->mode == M_HI)
2260 {
2261 insn->reloc = BFD_RELOC_HI16;
2262 }
2263 else
2264 {
2265 insn->reloc = BFD_RELOC_LO16;
2266 }
2267 insn->exp = *exp;
2268 continue;
2269 }
2270 /* Handle cases like ldi foo - $, ar0 where foo
2271 is a forward reference. Perhaps we should check
2272 for X_op == O_symbol and disallow things like
2273 ldi foo, ar0. */
2274 insn->reloc = BFD_RELOC_16;
2275 insn->exp = *exp;
2276 continue;
2277
2278 case 'T': /* 5-bit immediate value for tic4x stik. */
2279 if (!IS_CPU_TIC4X (tic4x_cpu))
2280 break;
2281 if (operand->mode != M_IMMED)
2282 break;
2283 if (exp->X_op == O_constant)
2284 {
2285 if (exp->X_add_number < 16 && exp->X_add_number >= -16)
2286 {
2287 INSERTS (opcode, exp->X_add_number, 20, 16);
2288 continue;
2289 }
2290 else
2291 {
2292 if (!check)
2293 as_bad ("Immediate value of %ld is too large",
2294 (long) exp->X_add_number);
2295 ret = -1;
2296 continue;
2297 }
2298 }
2299 break; /* No relocations allowed. */
2300
2301 case 'U': /* Unsigned integer immediate. */
2302 if (operand->mode != M_IMMED && operand->mode != M_HI)
2303 break;
2304 if (exp->X_op == O_constant)
2305 {
2306 if (exp->X_add_number < (1 << 16) && exp->X_add_number >= 0)
2307 {
2308 INSERTU (opcode, exp->X_add_number, 15, 0);
2309 continue;
2310 }
2311 else
2312 {
2313 if (!check)
2314 as_bad ("Unsigned immediate value %ld too large",
2315 (long) exp->X_add_number);
2316 ret = -1;
2317 continue;
2318 }
2319 }
2320 else if (exp->X_op == O_symbol)
2321 {
2322 if (operand->mode == M_HI)
2323 insn->reloc = BFD_RELOC_HI16;
2324 else
2325 insn->reloc = BFD_RELOC_LO16;
2326
2327 insn->exp = *exp;
2328 continue;
2329 }
2330 insn->reloc = BFD_RELOC_16;
2331 insn->exp = *exp;
2332 continue;
2333
2334 case 'V': /* Trap numbers (immediate field). */
2335 if (operand->mode != M_IMMED)
2336 break;
2337 if (exp->X_op == O_constant)
2338 {
2339 if (exp->X_add_number < 512 && IS_CPU_TIC4X (tic4x_cpu))
2340 {
2341 INSERTU (opcode, exp->X_add_number, 8, 0);
2342 continue;
2343 }
2344 else if (exp->X_add_number < 32 && IS_CPU_TIC3X (tic4x_cpu))
2345 {
2346 INSERTU (opcode, exp->X_add_number | 0x20, 4, 0);
2347 continue;
2348 }
2349 else
2350 {
2351 if (!check)
2352 as_bad ("Immediate value of %ld is too large",
2353 (long) exp->X_add_number);
2354 ret = -1;
2355 continue;
2356 }
2357 }
2358 break; /* No relocations allowed. */
2359
2360 case 'W': /* Short immediate int (0--7). */
2361 if (!IS_CPU_TIC4X (tic4x_cpu))
2362 break;
2363 if (operand->mode != M_IMMED)
2364 break;
2365 if (exp->X_op == O_big)
2366 {
2367 if (!check)
2368 as_bad ("Floating point number not valid in expression");
2369 ret = -1;
2370 continue;
2371 }
2372 if (exp->X_op == O_constant)
2373 {
2374 if (exp->X_add_number >= -256 && exp->X_add_number <= 127)
2375 {
2376 INSERTS (opcode, exp->X_add_number, 7, 0);
2377 continue;
2378 }
2379 else
2380 {
2381 if (!check)
2382 as_bad ("Immediate value %ld too large",
2383 (long) exp->X_add_number);
2384 ret = -1;
2385 continue;
2386 }
2387 }
2388 insn->reloc = BFD_RELOC_16;
2389 insn->exp = *exp;
2390 continue;
2391
2392 case 'X': /* Expansion register for tic4x. */
2393 if (operand->mode != M_REGISTER)
2394 break;
2395 reg = exp->X_add_number;
2396 if (reg >= REG_IVTP && reg <= REG_TVTP)
2397 INSERTU (opcode, reg - REG_IVTP, 4, 0);
2398 else
2399 {
2400 if (!check)
2401 as_bad ("Register must be ivtp or tvtp");
2402 ret = -1;
2403 }
2404 continue;
2405
2406 case 'Y': /* Address register for tic4x lda. */
2407 if (operand->mode != M_REGISTER)
2408 break;
2409 reg = exp->X_add_number;
2410 if (reg >= REG_AR0 && reg <= REG_SP)
2411 INSERTU (opcode, reg, 20, 16);
2412 else
2413 {
2414 if (!check)
2415 as_bad ("Register must be address register");
2416 ret = -1;
2417 }
2418 continue;
2419
2420 case 'Z': /* Expansion register for tic4x. */
2421 if (operand->mode != M_REGISTER)
2422 break;
2423 reg = exp->X_add_number;
2424 if (reg >= REG_IVTP && reg <= REG_TVTP)
2425 INSERTU (opcode, reg - REG_IVTP, 20, 16);
2426 else
2427 {
2428 if (!check)
2429 as_bad ("Register must be ivtp or tvtp");
2430 ret = -1;
2431 }
2432 continue;
2433
2434 case '*':
2435 if (operand->mode != M_INDIRECT)
2436 break;
2437 INSERTS (opcode, operand->disp, 7, 0);
2438 INSERTU (opcode, operand->aregno - REG_AR0, 10, 8);
2439 INSERTU (opcode, operand->expr.X_add_number, 15, 11);
2440 continue;
2441
2442 case '|': /* treat as `,' if have ldi_ldi form. */
2443 if (insn->parallel)
2444 {
2445 if (--num_operands < 0)
2446 break; /* Too few operands. */
2447 operand++;
2448 if (operand->mode != M_PARALLEL)
2449 break;
2450 }
2451 /* Fall through. */
2452
2453 case ',': /* Another operand. */
2454 if (--num_operands < 0)
2455 break; /* Too few operands. */
2456 operand++;
2457 exp = &operand->expr;
2458 continue;
2459
2460 case ';': /* Another optional operand. */
2461 if (num_operands == 1 || operand[1].mode == M_PARALLEL)
2462 continue;
2463 if (--num_operands < 0)
2464 break; /* Too few operands. */
2465 operand++;
2466 exp = &operand->expr;
2467 continue;
2468
2469 default:
2470 BAD_CASE (*args);
2471 }
2472 return 0;
2473 }
2474 }
2475
2476 static void
2477 tic4x_insn_check (insn)
2478 tic4x_insn_t *insn;
2479 {
2480
2481 if (!strcmp(insn->name, "lda"))
2482 {
2483 if (insn->num_operands < 2 || insn->num_operands > 2)
2484 as_fatal ("Illegal internal LDA insn definition");
2485
2486 if ( insn->operands[0].mode == M_REGISTER
2487 && insn->operands[1].mode == M_REGISTER
2488 && insn->operands[0].expr.X_add_number == insn->operands[1].expr.X_add_number )
2489 as_bad ("Source and destination register should not be equal");
2490 }
2491 else if( !strcmp(insn->name, "ldi_ldi")
2492 || !strcmp(insn->name, "ldi1_ldi2")
2493 || !strcmp(insn->name, "ldi2_ldi1")
2494 || !strcmp(insn->name, "ldf_ldf")
2495 || !strcmp(insn->name, "ldf1_ldf2")
2496 || !strcmp(insn->name, "ldf2_ldf1") )
2497 {
2498 if ( insn->num_operands < 4 && insn->num_operands > 5 )
2499 as_fatal ("Illegal internal %s insn definition", insn->name);
2500
2501 if ( insn->operands[1].mode == M_REGISTER
2502 && insn->operands[insn->num_operands-1].mode == M_REGISTER
2503 && insn->operands[1].expr.X_add_number == insn->operands[insn->num_operands-1].expr.X_add_number )
2504 as_warn ("Equal parallell destination registers, one result will be discarded");
2505 }
2506 }
2507
2508 static void
2509 tic4x_insn_output (insn)
2510 tic4x_insn_t *insn;
2511 {
2512 char *dst;
2513
2514 /* Grab another fragment for opcode. */
2515 dst = frag_more (insn->nchars);
2516
2517 /* Put out opcode word as a series of bytes in little endian order. */
2518 md_number_to_chars (dst, insn->opcode, insn->nchars);
2519
2520 /* Put out the symbol-dependent stuff. */
2521 if (insn->reloc != NO_RELOC)
2522 {
2523 /* Where is the offset into the fragment for this instruction. */
2524 fix_new_exp (frag_now,
2525 dst - frag_now->fr_literal, /* where */
2526 insn->nchars, /* size */
2527 &insn->exp,
2528 insn->pcrel,
2529 insn->reloc);
2530 }
2531 }
2532
2533 /* Parse the operands. */
2534 int
2535 tic4x_operands_parse (s, operands, num_operands)
2536 char *s;
2537 tic4x_operand_t *operands;
2538 int num_operands;
2539 {
2540 if (!*s)
2541 return num_operands;
2542
2543 do
2544 s = tic4x_operand_parse (s, &operands[num_operands++]);
2545 while (num_operands < TIC4X_OPERANDS_MAX && *s++ == ',');
2546
2547 if (num_operands > TIC4X_OPERANDS_MAX)
2548 {
2549 as_bad ("Too many operands scanned");
2550 return -1;
2551 }
2552 return num_operands;
2553 }
2554
2555 /* Assemble a single instruction. Its label has already been handled
2556 by the generic front end. We just parse mnemonic and operands, and
2557 produce the bytes of data and relocation. */
2558 void
2559 md_assemble (str)
2560 char *str;
2561 {
2562 int ok = 0;
2563 char *s;
2564 int i;
2565 int parsed = 0;
2566 tic4x_inst_t *inst; /* Instruction template. */
2567 tic4x_inst_t *first_inst;
2568
2569 /* Scan for parallel operators */
2570 if (str)
2571 {
2572 s = str;
2573 while (*s && *s != '|')
2574 s++;
2575
2576 if (*s && s[1]=='|')
2577 {
2578 if(insn->parallel)
2579 {
2580 as_bad ("Parallel opcode cannot contain more than two instructions");
2581 insn->parallel = 0;
2582 insn->in_use = 0;
2583 return;
2584 }
2585
2586 /* Lets take care of the first part of the parallel insn */
2587 *s++ = 0;
2588 md_assemble(str);
2589 insn->parallel = 1;
2590 str = ++s;
2591 /* .. and let the second run though here */
2592 }
2593 }
2594
2595 if (str && insn->parallel)
2596 {
2597 /* Find mnemonic (second part of parallel instruction). */
2598 s = str;
2599 /* Skip past instruction mnemonic. */
2600 while (*s && *s != ' ')
2601 s++;
2602 if (*s) /* Null terminate for hash_find. */
2603 *s++ = '\0'; /* and skip past null. */
2604 strcat (insn->name, "_");
2605 strncat (insn->name, str, TIC4X_NAME_MAX - strlen (insn->name));
2606
2607 insn->operands[insn->num_operands++].mode = M_PARALLEL;
2608
2609 if ((i = tic4x_operands_parse
2610 (s, insn->operands, insn->num_operands)) < 0)
2611 {
2612 insn->parallel = 0;
2613 insn->in_use = 0;
2614 return;
2615 }
2616 insn->num_operands = i;
2617 parsed = 1;
2618 }
2619
2620 if (insn->in_use)
2621 {
2622 if ((insn->inst = (struct tic4x_inst *)
2623 hash_find (tic4x_op_hash, insn->name)) == NULL)
2624 {
2625 as_bad ("Unknown opcode `%s'.", insn->name);
2626 insn->parallel = 0;
2627 insn->in_use = 0;
2628 return;
2629 }
2630
2631 inst = insn->inst;
2632 first_inst = NULL;
2633 do
2634 {
2635 ok = tic4x_operands_match (inst, insn, 1);
2636 if (ok < 0)
2637 {
2638 if (!first_inst)
2639 first_inst = inst;
2640 ok = 0;
2641 }
2642 } while (!ok && !strcmp (inst->name, inst[1].name) && inst++);
2643
2644 if (ok > 0)
2645 {
2646 tic4x_insn_check (insn);
2647 tic4x_insn_output (insn);
2648 }
2649 else if (!ok)
2650 {
2651 if (first_inst)
2652 tic4x_operands_match (first_inst, insn, 0);
2653 as_bad ("Invalid operands for %s", insn->name);
2654 }
2655 else
2656 as_bad ("Invalid instruction %s", insn->name);
2657 }
2658
2659 if (str && !parsed)
2660 {
2661 /* Find mnemonic. */
2662 s = str;
2663 while (*s && *s != ' ') /* Skip past instruction mnemonic. */
2664 s++;
2665 if (*s) /* Null terminate for hash_find. */
2666 *s++ = '\0'; /* and skip past null. */
2667 strncpy (insn->name, str, TIC4X_NAME_MAX - 3);
2668
2669 if ((i = tic4x_operands_parse (s, insn->operands, 0)) < 0)
2670 {
2671 insn->inst = NULL; /* Flag that error occured. */
2672 insn->parallel = 0;
2673 insn->in_use = 0;
2674 return;
2675 }
2676 insn->num_operands = i;
2677 insn->in_use = 1;
2678 }
2679 else
2680 insn->in_use = 0;
2681 insn->parallel = 0;
2682 }
2683
2684 void
2685 tic4x_cleanup ()
2686 {
2687 if (insn->in_use)
2688 md_assemble (NULL);
2689 }
2690
2691 /* Turn a string in input_line_pointer into a floating point constant
2692 of type type, and store the appropriate bytes in *litP. The number
2693 of LITTLENUMS emitted is stored in *sizeP. An error message is
2694 returned, or NULL on OK. */
2695
2696 char *
2697 md_atof (type, litP, sizeP)
2698 int type;
2699 char *litP;
2700 int *sizeP;
2701 {
2702 int prec;
2703 int ieee;
2704 LITTLENUM_TYPE words[MAX_LITTLENUMS];
2705 LITTLENUM_TYPE *wordP;
2706 unsigned char *t;
2707
2708 switch (type)
2709 {
2710 case 's': /* .single */
2711 case 'S':
2712 ieee = 0;
2713 prec = 1;
2714 break;
2715
2716 case 'd': /* .double */
2717 case 'D':
2718 case 'f': /* .float or .single */
2719 case 'F':
2720 ieee = 0;
2721 prec = 2; /* 1 32-bit word */
2722 break;
2723
2724 case 'i': /* .ieee */
2725 case 'I':
2726 prec = 2;
2727 ieee = 1;
2728 type = 'f'; /* Rewrite type to be usable by atof_ieee() */
2729 break;
2730
2731 case 'e': /* .ldouble */
2732 case 'E':
2733 prec = 4; /* 2 32-bit words */
2734 ieee = 0;
2735 break;
2736
2737 default:
2738 *sizeP = 0;
2739 return "Bad call to md_atof()";
2740 }
2741
2742 if (ieee)
2743 t = atof_ieee (input_line_pointer, type, words);
2744 else
2745 t = tic4x_atof (input_line_pointer, type, words);
2746 if (t)
2747 input_line_pointer = t;
2748 *sizeP = prec * sizeof (LITTLENUM_TYPE);
2749 t = litP;
2750 /* This loops outputs the LITTLENUMs in REVERSE order; in accord with
2751 little endian byte order. */
2752 /* SES: However it is required to put the words (32-bits) out in the
2753 correct order, hence we write 2 and 2 littlenums in little endian
2754 order, while we keep the original order on successive words. */
2755 for(wordP = words; wordP<(words+prec) ; wordP+=2)
2756 {
2757 if (wordP<(words+prec-1)) /* Dump wordP[1] (if we have one) */
2758 {
2759 md_number_to_chars (litP, (valueT) (wordP[1]),
2760 sizeof (LITTLENUM_TYPE));
2761 litP += sizeof (LITTLENUM_TYPE);
2762 }
2763
2764 /* Dump wordP[0] */
2765 md_number_to_chars (litP, (valueT) (wordP[0]),
2766 sizeof (LITTLENUM_TYPE));
2767 litP += sizeof (LITTLENUM_TYPE);
2768 }
2769 return 0;
2770 }
2771
2772 void
2773 md_apply_fix3 (fixP, value, seg)
2774 fixS *fixP;
2775 valueT *value;
2776 segT seg ATTRIBUTE_UNUSED;
2777 {
2778 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
2779 valueT val = *value;
2780
2781 switch (fixP->fx_r_type)
2782 {
2783 case BFD_RELOC_HI16:
2784 val >>= 16;
2785 break;
2786
2787 case BFD_RELOC_LO16:
2788 val &= 0xffff;
2789 break;
2790 default:
2791 break;
2792 }
2793
2794 switch (fixP->fx_r_type)
2795 {
2796 case BFD_RELOC_32:
2797 buf[3] = val >> 24;
2798 case BFD_RELOC_24:
2799 case BFD_RELOC_24_PCREL:
2800 buf[2] = val >> 16;
2801 case BFD_RELOC_16:
2802 case BFD_RELOC_16_PCREL:
2803 case BFD_RELOC_LO16:
2804 case BFD_RELOC_HI16:
2805 buf[1] = val >> 8;
2806 buf[0] = val;
2807 break;
2808
2809 case NO_RELOC:
2810 default:
2811 as_bad ("Bad relocation type: 0x%02x", fixP->fx_r_type);
2812 break;
2813 }
2814
2815 if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0) fixP->fx_done = 1;
2816 }
2817
2818 /* Should never be called for tic4x. */
2819 void
2820 md_convert_frag (headers, sec, fragP)
2821 bfd *headers ATTRIBUTE_UNUSED;
2822 segT sec ATTRIBUTE_UNUSED;
2823 fragS *fragP ATTRIBUTE_UNUSED;
2824 {
2825 as_fatal ("md_convert_frag");
2826 }
2827
2828 /* Should never be called for tic4x. */
2829 void
2830 md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
2831 char *ptr ATTRIBUTE_UNUSED;
2832 addressT from_addr ATTRIBUTE_UNUSED;
2833 addressT to_addr ATTRIBUTE_UNUSED;
2834 fragS *frag ATTRIBUTE_UNUSED;
2835 symbolS *to_symbol ATTRIBUTE_UNUSED;
2836 {
2837 as_fatal ("md_create_short_jmp\n");
2838 }
2839
2840 /* Should never be called for tic4x. */
2841 void
2842 md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
2843 char *ptr ATTRIBUTE_UNUSED;
2844 addressT from_addr ATTRIBUTE_UNUSED;
2845 addressT to_addr ATTRIBUTE_UNUSED;
2846 fragS *frag ATTRIBUTE_UNUSED;
2847 symbolS *to_symbol ATTRIBUTE_UNUSED;
2848 {
2849 as_fatal ("md_create_long_jump\n");
2850 }
2851
2852 /* Should never be called for tic4x. */
2853 int
2854 md_estimate_size_before_relax (fragP, segtype)
2855 register fragS *fragP ATTRIBUTE_UNUSED;
2856 segT segtype ATTRIBUTE_UNUSED;
2857 {
2858 as_fatal ("md_estimate_size_before_relax\n");
2859 return 0;
2860 }
2861
2862
2863 int
2864 md_parse_option (c, arg)
2865 int c;
2866 char *arg;
2867 {
2868 switch (c)
2869 {
2870 case OPTION_CPU: /* cpu brand */
2871 if (TOLOWER (*arg) == 'c')
2872 arg++;
2873 tic4x_cpu = atoi (arg);
2874 if (!IS_CPU_TIC3X (tic4x_cpu) && !IS_CPU_TIC4X (tic4x_cpu))
2875 as_warn ("Unsupported processor generation %d", tic4x_cpu);
2876 break;
2877
2878 case OPTION_REV: /* cpu revision */
2879 tic4x_revision = atoi (arg);
2880 break;
2881
2882 case 'b':
2883 as_warn ("Option -b is depreciated, please use -mbig");
2884 case OPTION_BIG: /* big model */
2885 tic4x_big_model = 1;
2886 break;
2887
2888 case 'p':
2889 as_warn ("Option -p is depreciated, please use -mmemparm");
2890 case OPTION_MEMPARM: /* push args */
2891 tic4x_reg_args = 0;
2892 break;
2893
2894 case 'r':
2895 as_warn ("Option -r is depreciated, please use -mregparm");
2896 case OPTION_REGPARM: /* register args */
2897 tic4x_reg_args = 1;
2898 break;
2899
2900 case 's':
2901 as_warn ("Option -s is depreciated, please use -msmall");
2902 case OPTION_SMALL: /* small model */
2903 tic4x_big_model = 0;
2904 break;
2905
2906 case OPTION_IDLE2:
2907 tic4x_idle2 = 1;
2908 break;
2909
2910 case OPTION_LOWPOWER:
2911 tic4x_lowpower = 1;
2912 break;
2913
2914 case OPTION_ENHANCED:
2915 tic4x_enhanced = 1;
2916 break;
2917
2918 default:
2919 return 0;
2920 }
2921
2922 return 1;
2923 }
2924
2925 void
2926 md_show_usage (stream)
2927 FILE *stream;
2928 {
2929 fprintf (stream,
2930 _("\nTIC4X options:\n"
2931 " -mcpu=CPU -mCPU select architecture variant. CPU can be:\n"
2932 " 30 - TMS320C30\n"
2933 " 31 - TMS320C31, TMS320LC31\n"
2934 " 32 - TMS320C32\n"
2935 " 33 - TMS320VC33\n"
2936 " 40 - TMS320C40\n"
2937 " 44 - TMS320C44\n"
2938 " -mrev=REV set cpu hardware revision (integer numbers).\n"
2939 " Combinations of -mcpu and -mrev will enable/disable\n"
2940 " the appropriate options (-midle2, -mlowpower and\n"
2941 " -menhanced) according to the selected type\n"
2942 " -mbig select big memory model\n"
2943 " -msmall select small memory model (default)\n"
2944 " -mregparm select register parameters (default)\n"
2945 " -mmemparm select memory parameters\n"
2946 " -midle2 enable IDLE2 support\n"
2947 " -mlowpower enable LOPOWER and MAXSPEED support\n"
2948 " -menhanced enable enhanced opcode support\n"));
2949 }
2950
2951 /* This is called when a line is unrecognized. This is used to handle
2952 definitions of TI C3x tools style local labels $n where n is a single
2953 decimal digit. */
2954 int
2955 tic4x_unrecognized_line (c)
2956 int c;
2957 {
2958 int lab;
2959 char *s;
2960
2961 if (c != '$' || ! ISDIGIT (input_line_pointer[0]))
2962 return 0;
2963
2964 s = input_line_pointer;
2965
2966 /* Let's allow multiple digit local labels. */
2967 lab = 0;
2968 while (ISDIGIT (*s))
2969 {
2970 lab = lab * 10 + *s - '0';
2971 s++;
2972 }
2973
2974 if (dollar_label_defined (lab))
2975 {
2976 as_bad ("Label \"$%d\" redefined", lab);
2977 return 0;
2978 }
2979
2980 define_dollar_label (lab);
2981 colon (dollar_label_name (lab, 0));
2982 input_line_pointer = s + 1;
2983
2984 return 1;
2985 }
2986
2987 /* Handle local labels peculiar to us referred to in an expression. */
2988 symbolS *
2989 md_undefined_symbol (name)
2990 char *name;
2991 {
2992 /* Look for local labels of the form $n. */
2993 if (name[0] == '$' && ISDIGIT (name[1]))
2994 {
2995 symbolS *symbolP;
2996 char *s = name + 1;
2997 int lab = 0;
2998
2999 while (ISDIGIT ((unsigned char) *s))
3000 {
3001 lab = lab * 10 + *s - '0';
3002 s++;
3003 }
3004 if (dollar_label_defined (lab))
3005 {
3006 name = dollar_label_name (lab, 0);
3007 symbolP = symbol_find (name);
3008 }
3009 else
3010 {
3011 name = dollar_label_name (lab, 1);
3012 symbolP = symbol_find_or_make (name);
3013 }
3014
3015 return symbolP;
3016 }
3017 return NULL;
3018 }
3019
3020 /* Parse an operand that is machine-specific. */
3021 void
3022 md_operand (expressionP)
3023 expressionS *expressionP ATTRIBUTE_UNUSED;
3024 {
3025 }
3026
3027 /* Round up a section size to the appropriate boundary---do we need this? */
3028 valueT
3029 md_section_align (segment, size)
3030 segT segment ATTRIBUTE_UNUSED;
3031 valueT size;
3032 {
3033 return size; /* Byte (i.e., 32-bit) alignment is fine? */
3034 }
3035
3036 static int
3037 tic4x_pc_offset (op)
3038 unsigned int op;
3039 {
3040 /* Determine the PC offset for a C[34]x instruction.
3041 This could be simplified using some boolean algebra
3042 but at the expense of readability. */
3043 switch (op >> 24)
3044 {
3045 case 0x60: /* br */
3046 case 0x62: /* call (C4x) */
3047 case 0x64: /* rptb (C4x) */
3048 return 1;
3049 case 0x61: /* brd */
3050 case 0x63: /* laj */
3051 case 0x65: /* rptbd (C4x) */
3052 return 3;
3053 case 0x66: /* swi */
3054 case 0x67:
3055 return 0;
3056 default:
3057 break;
3058 }
3059
3060 switch ((op & 0xffe00000) >> 20)
3061 {
3062 case 0x6a0: /* bB */
3063 case 0x720: /* callB */
3064 case 0x740: /* trapB */
3065 return 1;
3066
3067 case 0x6a2: /* bBd */
3068 case 0x6a6: /* bBat */
3069 case 0x6aa: /* bBaf */
3070 case 0x722: /* lajB */
3071 case 0x748: /* latB */
3072 case 0x798: /* rptbd */
3073 return 3;
3074
3075 default:
3076 break;
3077 }
3078
3079 switch ((op & 0xfe200000) >> 20)
3080 {
3081 case 0x6e0: /* dbB */
3082 return 1;
3083
3084 case 0x6e2: /* dbBd */
3085 return 3;
3086
3087 default:
3088 break;
3089 }
3090
3091 return 0;
3092 }
3093
3094 /* Exactly what point is a PC-relative offset relative TO?
3095 With the C3x we have the following:
3096 DBcond, Bcond disp + PC + 1 => PC
3097 DBcondD, BcondD disp + PC + 3 => PC
3098 */
3099 long
3100 md_pcrel_from (fixP)
3101 fixS *fixP;
3102 {
3103 unsigned char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
3104 unsigned int op;
3105
3106 op = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
3107
3108 return ((fixP->fx_where + fixP->fx_frag->fr_address) >> 2) +
3109 tic4x_pc_offset (op);
3110 }
3111
3112 /* Fill the alignment area with NOP's on .text, unless fill-data
3113 was specified. */
3114 int
3115 tic4x_do_align (alignment, fill, len, max)
3116 int alignment ATTRIBUTE_UNUSED;
3117 const char *fill ATTRIBUTE_UNUSED;
3118 int len ATTRIBUTE_UNUSED;
3119 int max ATTRIBUTE_UNUSED;
3120 {
3121 unsigned long nop = NOP_OPCODE;
3122
3123 /* Because we are talking lwords, not bytes, adjust aligment to do words */
3124 alignment += 2;
3125
3126 if (alignment != 0 && !need_pass_2)
3127 {
3128 if (fill == NULL)
3129 {
3130 /*if (subseg_text_p (now_seg))*/ /* FIXME: doesnt work for .text for some reason */
3131 frag_align_pattern( alignment, (const char *)&nop, sizeof(nop), max);
3132 return 1;
3133 /*else
3134 frag_align (alignment, 0, max);*/
3135 }
3136 else if (len <= 1)
3137 frag_align (alignment, *fill, max);
3138 else
3139 frag_align_pattern (alignment, fill, len, max);
3140 }
3141
3142 /* Return 1 to skip the default aligment function */
3143 return 1;
3144 }
3145
3146 /* Look for and remove parallel instruction operator ||. */
3147 void
3148 tic4x_start_line ()
3149 {
3150 char *s = input_line_pointer;
3151
3152 SKIP_WHITESPACE ();
3153
3154 /* If parallel instruction prefix found at start of line, skip it. */
3155 if (*input_line_pointer == '|' && input_line_pointer[1] == '|')
3156 {
3157 if (insn->in_use)
3158 {
3159 insn->parallel = 1;
3160 input_line_pointer ++;
3161 *input_line_pointer = ' ';
3162 /* So line counters get bumped. */
3163 input_line_pointer[-1] = '\n';
3164 }
3165 }
3166 else
3167 {
3168 /* Write out the previous insn here */
3169 if (insn->in_use)
3170 md_assemble (NULL);
3171 input_line_pointer = s;
3172 }
3173 }
3174
3175 arelent *
3176 tc_gen_reloc (seg, fixP)
3177 asection *seg ATTRIBUTE_UNUSED;
3178 fixS *fixP;
3179 {
3180 arelent *reloc;
3181
3182 reloc = (arelent *) xmalloc (sizeof (arelent));
3183
3184 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
3185 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
3186 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
3187 reloc->address /= OCTETS_PER_BYTE;
3188 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
3189 if (reloc->howto == (reloc_howto_type *) NULL)
3190 {
3191 as_bad_where (fixP->fx_file, fixP->fx_line,
3192 "Reloc %d not supported by object file format",
3193 (int) fixP->fx_r_type);
3194 return NULL;
3195 }
3196
3197 if (fixP->fx_r_type == BFD_RELOC_HI16)
3198 reloc->addend = fixP->fx_offset;
3199 else
3200 reloc->addend = fixP->fx_addnumber;
3201
3202 return reloc;
3203 }
This page took 0.094008 seconds and 4 git commands to generate.