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