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