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