1 /* tc-c4x.c -- Assemble for the Texas Instruments TMS320C[34]x.
2 Copyright (C) 1997,1998, 2002 Free Software Foundation.
4 Contributed by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
6 This file is part of GAS, the GNU Assembler.
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)
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.
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. */
26 o .align cannot handle fill-data-width larger than 0xFF/8-bits. It
27 should be possible to define a 32-bits pattern.
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)
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
38 o .usect if has symbol on previous line not implemented
40 o .sym, .eos, .stag, .etag, .member not implemented
42 o Evaluation of constant floating point expressions (expr.c needs
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.
49 o Support 'abc' constants?
51 o Support new opcodes and implement a silicon version switch (maybe
54 o Disallow non-float registers in float instructions.
56 o Make sure the source and destination register is NOT equal when
57 the C4X LDA insn is used (arg mode Q,Y)
59 o Merge the C3x op-table and the c4x op-table, and adhere to the
60 last argument when parsing the hash.
67 #include "opcode/tic4x.h"
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. */
79 #define C4X_ALT_SYNTAX
81 /* Equal to MAX_PRECISION in atof-ieee.c. */
82 #define MAX_LITTLENUMS 6 /* (12 bytes) */
84 /* Handle of the inst mnemonic hash table. */
85 static struct hash_control
*c4x_op_hash
= NULL
;
87 /* Handle asg pseudo. */
88 static struct hash_control
*c4x_asg_hash
= NULL
;
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. */
96 M_UNKNOWN
, M_IMMED
, M_DIRECT
, M_REGISTER
, M_INDIRECT
,
97 M_IMMED_F
, M_PARALLEL
, M_HI
101 typedef struct c4x_operand
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. */
111 typedef struct c4x_insn
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
];
128 static c4x_insn_t the_insn
; /* Info about our instruction. */
129 static c4x_insn_t
*insn
= &the_insn
;
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
*));
151 static void c4x_globl
155 static void c4x_stringer
159 static void c4x_newblock
165 static void c4x_usect
167 static void c4x_version
169 static void c4x_init_regtable
171 static void c4x_init_symbols
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
*));
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 ));
198 PARAMS ((int, char *, int *));
200 PARAMS ((fixS
*, valueT
*, segT
));
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
));
210 PARAMS ((int, char *));
213 int c4x_unrecognized_line
215 symbolS
*md_undefined_symbol
218 PARAMS ((expressionS
*));
219 valueT md_section_align
220 PARAMS ((segT
, valueT
));
221 static int c4x_pc_offset
222 PARAMS ((unsigned int));
226 PARAMS ((int, const char *, int, int));
229 arelent
*tc_gen_reloc
230 PARAMS ((asection
*, fixS
*));
236 {"align", s_align_bytes
, 32},
237 {"ascii", c4x_stringer
, 1},
238 {"asciz", c4x_stringer
, 0},
240 {"block", s_space
, 4},
241 {"byte", c4x_cons
, 1},
243 {"copy", s_include
, 0},
244 {"def", c4x_globl
, 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. */
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},
266 int md_short_jump_size
= 4;
267 int md_long_jump_size
= 4;
268 const int md_reloc_size
= RELSZ
; /* Coff headers. */
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
[] = ";!";
275 const char comment_chars
[] = ";";
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
[] = "#*";
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
[] = "&";
291 /* Chars that can be used to separate mant from exp in floating point nums. */
292 const char EXP_CHARS
[] = "eE";
294 /* Chars that mean this number is a floating point constant. */
297 const char FLT_CHARS
[] = "fFilsS";
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. */
303 /* Flonums returned here. */
304 extern FLONUM_TYPE generic_floating_point_number
;
306 /* Precision in LittleNums. */
307 #define MAX_PRECISION (4) /* Its a bit overkill for us, but the code
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). */
314 /* Turn generic_floating_point_number into a real short/float/double. */
316 c4x_gen_to_words (flonum
, words
, precision
)
318 LITTLENUM_TYPE
*words
;
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. */
326 unsigned int sone
; /* Scaled one. */
327 unsigned int sfract
; /* Scaled fraction. */
328 unsigned int smant
; /* Scaled mantissa. */
330 unsigned int mover
; /* Mantissa overflow bits */
331 unsigned int rbit
; /* Round bit. */
332 int shift
; /* Shift count. */
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.
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
344 For example 2e-3 is stored with exp = -4 and
351 with low = &bits[2], high = &bits[5], and leader = &bits[5].
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
358 Note that low points to the 65536**0 littlenum (bits[2]) and
359 leader points to the most significant non-zero littlenum
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
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,
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)
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.
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
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:
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
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.
417 To convert a generic flonum into a TMS320C3X floating point
418 number, here's what we try to do....
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.
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.
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.
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. */
466 if (precision
!= S_PRECISION
)
468 if (precision
== E_PRECISION
)
469 words
[2] = words
[3] = 0x0000;
471 /* 0.0e0 or NaN seen. */
472 if (flonum
.low
> flonum
.leader
/* = 0.0e0 */
473 || flonum
.sign
== 0) /* = NaN */
476 as_bad ("Nan, using zero.");
481 if (flonum
.sign
== 'P')
483 /* +INF: Replace with maximum float. */
484 if (precision
== S_PRECISION
)
491 if (precision
== E_PRECISION
)
498 else if (flonum
.sign
== 'N')
500 /* -INF: Replace with maximum float. */
501 if (precision
== S_PRECISION
)
505 if (precision
== E_PRECISION
)
510 exponent
= (flonum
.exponent
+ flonum
.leader
- flonum
.low
+ 1) * 16;
512 if (!(tmp
= *flonum
.leader
))
513 abort (); /* Hmmm. */
514 shift
= 0; /* Find position of first sig. bit. */
517 exponent
-= (16 - shift
); /* Adjust exponent. */
519 if (precision
== S_PRECISION
) /* Allow 1 rounding bit. */
524 else if(precision
== F_PRECISION
)
529 else /* E_PRECISION */
535 shift
= mantissa_bits
- shift
;
540 /* Store the mantissa data into smant and the roundbit into rbit */
541 for (p
= flonum
.leader
; p
>= flonum
.low
&& shift
> -16; p
--)
543 tmp
= shift
>= 0 ? *p
<< shift
: *p
>> -shift
;
544 rbit
= shift
< 0 ? ((*p
>> (-shift
-1)) & 0x1) : 0;
549 /* OK, we've got our scaled mantissa so let's round it up */
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
557 if( smant
== ((unsigned)(1<<(mantissa_bits
+1))-1)
558 || smant
== (unsigned)-1 ) /* This is to catch E_PRECISION cases */
563 /* Get the scaled one value */
564 sone
= (1 << (mantissa_bits
));
566 /* The number may be unnormalised so renormalise it... */
570 smant
|= sone
; /* Insert the bit from mover into smant */
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. */
578 abort (); /* Ooops. */
580 if (flonum
.sign
== '+')
581 sfract
= smant
- sone
; /* smant - 1.0. */
584 /* This seems to work. */
592 sfract
= -smant
& (sone
-1); /* 2.0 - smant. */
594 sfract
|= sone
; /* Insert sign bit. */
597 if (abs (exponent
) >= (1 << (exponent_bits
- 1)))
598 as_bad ("Cannot represent exponent in %d bits", exponent_bits
);
600 /* Force exponent to fit in desired field width. */
601 exponent
&= (1 << (exponent_bits
)) - 1;
603 if (precision
== E_PRECISION
)
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;
610 /* Map the mantissa in the next */
611 words
[2] = sfract
>> 16;
612 words
[3] = sfract
& 0xffff;
616 /* Insert the exponent data into the word */
617 sfract
|= exponent
<< (mantissa_bits
+1);
619 if (precision
== S_PRECISION
)
623 words
[0] = sfract
>> 16;
624 words
[1] = sfract
& 0xffff;
631 /* Returns pointer past text consumed. */
633 c4x_atof (str
, what_kind
, words
)
636 LITTLENUM_TYPE
*words
;
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
];
642 /* Number of 16-bit words in the format. */
644 FLONUM_TYPE save_gen_flonum
;
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
;
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';
659 /* Use more LittleNums than seems necessary: the highest flonum may
660 have 15 leading 0 bits, so could be useless. */
662 memset (bits
, '\0', sizeof (LITTLENUM_TYPE
) * MAX_PRECISION
);
668 precision
= S_PRECISION
;
675 precision
= F_PRECISION
;
680 precision
= E_PRECISION
;
684 as_bad ("Invalid floating point number");
688 generic_floating_point_number
.high
689 = generic_floating_point_number
.low
+ precision
- 1 + GUARD
;
691 if (atof_generic (&return_value
, ".", EXP_CHARS
,
692 &generic_floating_point_number
))
694 as_bad ("Invalid floating point number");
698 c4x_gen_to_words (generic_floating_point_number
,
701 /* Restore the generic_floating_point_number's storage alloc (and
703 generic_floating_point_number
= save_gen_flonum
;
709 c4x_insert_reg (regname
, regnum
)
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
];
722 symbol_table_insert (symbol_new (buf
, reg_section
, (valueT
) regnum
,
723 &zero_address_frag
));
727 c4x_insert_sym (symname
, value
)
733 symbolP
= symbol_new (symname
, absolute_section
,
734 (valueT
) value
, &zero_address_frag
);
735 SF_SET_LOCAL (symbolP
);
736 symbol_table_insert (symbolP
);
740 c4x_expression (str
, exp
)
747 t
= input_line_pointer
; /* Save line pointer. */
748 input_line_pointer
= str
;
750 s
= input_line_pointer
;
751 input_line_pointer
= t
; /* Restore line pointer. */
752 return s
; /* Return pointer to where parsing stopped. */
756 c4x_expression_abs (str
, value
)
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. */
778 exp
.X_op
= O_constant
;
779 exp
.X_add_number
= c
;
784 c4x_seg_alloc (name
, seg
, size
, symbolP
)
785 char *name ATTRIBUTE_UNUSED
;
786 segT seg ATTRIBUTE_UNUSED
;
790 /* Note that the size is in words
791 so we multiply it by 4 to get the number of bytes to allocate. */
793 /* If we have symbol: .usect ".fred", size etc.,
794 the symbol needs to point to the first location reserved
801 p
= frag_var (rs_fill
, 1, 1, (relax_substateT
) 0,
803 size
* OCTETS_PER_BYTE
, (char *) 0);
808 /* .asg ["]character-string["], symbol */
811 int x ATTRIBUTE_UNUSED
;
819 str
= input_line_pointer
;
821 /* Skip string expression. */
822 while (*input_line_pointer
!= ',' && *input_line_pointer
)
823 input_line_pointer
++;
824 if (*input_line_pointer
!= ',')
826 as_bad ("Comma expected\n");
829 *input_line_pointer
++ = '\0';
830 name
= input_line_pointer
;
831 c
= get_symbol_end (); /* Get terminator. */
832 tmp
= xmalloc (strlen (str
) + 1);
835 tmp
= xmalloc (strlen (name
) + 1);
838 if (hash_find (c4x_asg_hash
, name
))
839 hash_replace (c4x_asg_hash
, name
, (PTR
) str
);
841 hash_insert (c4x_asg_hash
, name
, (PTR
) str
);
842 *input_line_pointer
= c
;
843 demand_empty_rest_of_line ();
846 /* .bss symbol, size */
849 int x ATTRIBUTE_UNUSED
;
856 subsegT current_subseg
;
859 current_seg
= now_seg
; /* Save current seg. */
860 current_subseg
= now_subseg
; /* Save current subseg. */
863 name
= input_line_pointer
;
864 c
= get_symbol_end (); /* Get terminator. */
867 as_bad (".bss size argument missing\n");
872 c4x_expression_abs (++input_line_pointer
, &size
);
875 as_bad (".bss size %d < 0!", size
);
878 subseg_set (bss_section
, 0);
879 symbolP
= symbol_find_or_make (name
);
881 if (S_GET_SEGMENT (symbolP
) == bss_section
)
882 symbol_get_frag (symbolP
)->fr_symbol
= 0;
884 symbol_set_frag (symbolP
, frag_now
);
886 p
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
,
887 size
* OCTETS_PER_BYTE
, (char *) 0);
888 *p
= 0; /* Fill char. */
890 S_SET_SEGMENT (symbolP
, bss_section
);
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
);
898 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
899 demand_empty_rest_of_line ();
904 int ignore ATTRIBUTE_UNUSED
;
912 name
= input_line_pointer
;
913 c
= get_symbol_end ();
914 symbolP
= symbol_find_or_make (name
);
915 *input_line_pointer
= c
;
917 S_SET_STORAGE_CLASS (symbolP
, C_EXT
);
920 input_line_pointer
++;
922 if (*input_line_pointer
== '\n')
928 demand_empty_rest_of_line ();
931 /* Handle .byte, .word. .int, .long */
936 register unsigned int c
;
940 if (*input_line_pointer
== '"')
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] == '\"');
951 input_line_pointer
= c4x_expression (input_line_pointer
, &exp
);
952 if (exp
.X_op
== O_constant
)
957 exp
.X_add_number
&= 255;
960 exp
.X_add_number
&= 65535;
964 /* Perhaps we should disallow .byte and .hword with
965 a non constant expression that will require relocation. */
969 while (*input_line_pointer
++ == ',');
971 input_line_pointer
--; /* Put terminator back into stream. */
972 demand_empty_rest_of_line ();
975 /* Handle .ascii, .asciz, .string */
977 c4x_stringer (append_zero
)
978 int append_zero
; /*ex: bytes */
981 register unsigned int c
;
987 if (*input_line_pointer
== '"')
989 input_line_pointer
++;
990 while (is_a_char (c
= next_char_of_string ()))
992 c4x_emit_char (c
, 1);
998 c4x_emit_char (c
, 1);
1002 know (input_line_pointer
[-1] == '\"');
1008 input_line_pointer
= c4x_expression (input_line_pointer
, &exp
);
1009 if (exp
.X_op
!= O_constant
)
1011 as_bad("Non-constant symbols not allowed\n");
1014 exp
.X_add_number
&= 255; /* Limit numeber to 8-bit */
1015 emit_expr (&exp
, 1);
1019 while (*input_line_pointer
++ == ',');
1021 /* Fill out the rest of the expression with 0's to fill up a full word */
1023 c4x_emit_char (0, 4-(bytes
&0x3));
1025 input_line_pointer
--; /* Put terminator back into stream. */
1026 demand_empty_rest_of_line ();
1029 /* .eval expression, symbol */
1032 int x ATTRIBUTE_UNUSED
;
1039 input_line_pointer
=
1040 c4x_expression_abs (input_line_pointer
, &value
);
1041 if (*input_line_pointer
++ != ',')
1043 as_bad ("Symbol missing\n");
1046 name
= input_line_pointer
;
1047 c
= get_symbol_end (); /* Get terminator. */
1048 demand_empty_rest_of_line ();
1049 c4x_insert_sym (name
, value
);
1052 /* Reset local labels. */
1055 int x ATTRIBUTE_UNUSED
;
1057 dollar_label_clear ();
1060 /* .sect "section-name" [, value] */
1061 /* .sect ["]section-name[:subsection-name]["] [, value] */
1064 int x ATTRIBUTE_UNUSED
;
1068 char *subsection_name
;
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
);
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>. */
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");
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()
1100 input_line_pointer
=
1101 c4x_expression_abs (input_line_pointer
, &num
);
1102 else if (*input_line_pointer
== ',')
1104 input_line_pointer
=
1105 c4x_expression_abs (++input_line_pointer
, &num
);
1110 seg
= subseg_new (name
, num
);
1111 if (line_label
!= NULL
)
1113 S_SET_SEGMENT (line_label
, seg
);
1114 symbol_set_frag (line_label
, frag_now
);
1117 if (bfd_get_section_flags (stdoutput
, seg
) == SEC_NO_FLAGS
)
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 ()));
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
;
1132 demand_empty_rest_of_line ();
1135 /* symbol[:] .set value or .set symbol, value */
1138 int x ATTRIBUTE_UNUSED
;
1143 if ((symbolP
= line_label
) == NULL
)
1148 name
= input_line_pointer
;
1149 c
= get_symbol_end (); /* Get terminator. */
1152 as_bad (".set syntax invalid\n");
1153 ignore_rest_of_line ();
1156 symbolP
= symbol_find_or_make (name
);
1159 symbol_table_insert (symbolP
);
1161 pseudo_set (symbolP
);
1162 demand_empty_rest_of_line ();
1165 /* [symbol] .usect ["]section-name["], size-in-words [, alignment-flag] */
1168 int x ATTRIBUTE_UNUSED
;
1174 int size
, alignment_flag
;
1176 subsegT current_subseg
;
1178 current_seg
= now_seg
; /* save current seg. */
1179 current_subseg
= now_subseg
; /* save current subseg. */
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
);
1191 input_line_pointer
=
1192 c4x_expression_abs (input_line_pointer
, &size
);
1193 else if (*input_line_pointer
== ',')
1195 input_line_pointer
=
1196 c4x_expression_abs (++input_line_pointer
, &size
);
1201 /* Read a possibly present third argument (alignment flag) [VK]. */
1202 if (*input_line_pointer
== ',')
1204 input_line_pointer
=
1205 c4x_expression_abs (++input_line_pointer
, &alignment_flag
);
1210 as_warn (".usect: non-zero alignment flag ignored");
1212 seg
= subseg_new (name
, 0);
1213 if (line_label
!= NULL
)
1215 S_SET_SEGMENT (line_label
, seg
);
1216 symbol_set_frag (line_label
, frag_now
);
1217 S_SET_VALUE (line_label
, frag_now_fix ());
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
);
1225 if (S_GET_STORAGE_CLASS (line_label
) != C_EXT
)
1226 S_SET_STORAGE_CLASS (line_label
, C_STAT
);
1228 subseg_set (current_seg
, current_subseg
); /* Restore current seg. */
1229 demand_empty_rest_of_line ();
1232 /* .version cpu-version. */
1235 int x ATTRIBUTE_UNUSED
;
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",
1245 if (c4x_cpu
&& temp
!= c4x_cpu
)
1246 as_warn ("Changing processor generation on fly not supported...\n");
1248 demand_empty_rest_of_line ();
1252 c4x_init_regtable ()
1256 for (i
= 0; i
< c3x_num_registers
; i
++)
1257 c4x_insert_reg (c3x_registers
[i
].name
,
1258 c3x_registers
[i
].regno
);
1260 if (IS_CPU_C4X (c4x_cpu
))
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
);
1272 /* The TI tools accept case insensitive versions of these symbols,
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
1286 .REGPARM 1 or 0 1 if -mr option used
1287 .BIGMODEL 1 or 0 1 if -mb option used
1289 These symbols are currently supported but will be removed in a
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
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);
1325 /* Insert a new instruction template into hash table. */
1327 c4x_inst_insert (inst
)
1330 static char prev_name
[16];
1331 const char *retval
= NULL
;
1333 /* Only insert the first name if have several similar entries. */
1334 if (!strcmp (inst
->name
, prev_name
) || inst
->name
[0] == '\0')
1337 retval
= hash_insert (c4x_op_hash
, inst
->name
, (PTR
) inst
);
1339 fprintf (stderr
, "internal error: can't hash `%s': %s\n",
1340 inst
->name
, retval
);
1342 strcpy (prev_name
, inst
->name
);
1343 return retval
== NULL
;
1346 /* Make a new instruction template. */
1348 c4x_inst_make (name
, opcode
, args
)
1350 unsigned long opcode
;
1353 static c4x_inst_t
*insts
= NULL
;
1354 static char *names
= NULL
;
1355 static int index
= 0;
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);
1365 insts
[index
].name
= names
;
1366 insts
[index
].opcode
= opcode
;
1367 insts
[index
].opmask
= 0xffffffff;
1368 insts
[index
].args
= args
;
1376 return &insts
[index
- 1];
1379 /* Add instruction template, creating dynamic templates as required. */
1381 c4x_inst_add (insts
)
1384 char *s
= insts
->name
;
1398 /* Dynamically create all the conditional insts. */
1399 for (i
= 0; i
< num_conds
; i
++)
1403 char *c
= c4x_conds
[i
].name
;
1413 /* If instruction found then have already processed it. */
1414 if (hash_find (c4x_op_hash
, name
))
1419 inst
= c4x_inst_make (name
, insts
[k
].opcode
+
1420 (c4x_conds
[i
].cond
<<
1421 (*s
== 'B' ? 16 : 23)),
1423 if (k
== 0) /* Save strcmp() with following func. */
1424 ok
&= c4x_inst_insert (inst
);
1427 while (!strcmp (insts
->name
,
1434 return c4x_inst_insert (insts
);
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
1453 /* Create hash table for mnemonics. */
1454 c4x_op_hash
= hash_new ();
1456 /* Create hash table for asg pseudo. */
1457 c4x_asg_hash
= hash_new ();
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
]);
1463 if (IS_CPU_C4X (c4x_cpu
))
1465 for (i
= 0; i
< c4x_num_insts
; i
++)
1466 ok
&= c4x_inst_add ((void *) &c4x_insts
[i
]);
1469 /* Create dummy inst to avoid errors accessing end of table. */
1470 c4x_inst_make ("", 0, "");
1473 as_fatal ("Broken assembler. No assembly attempted.");
1475 /* Add registers to symbol table. */
1476 c4x_init_regtable ();
1478 /* Add predefined symbols to symbol table. */
1479 c4x_init_symbols ();
1485 bfd_set_arch_mach (stdoutput
, bfd_arch_tic4x
,
1486 IS_CPU_C4X (c4x_cpu
) ? bfd_mach_c4x
: bfd_mach_c3x
);
1490 c4x_indirect_parse (operand
, indirect
)
1491 c4x_operand_t
*operand
;
1492 const c4x_indirect_t
*indirect
;
1494 char *n
= indirect
->name
;
1495 char *s
= input_line_pointer
;
1505 case 'a': /* Need to match aux register. */
1507 #ifdef C4X_ALT_SYNTAX
1511 while (isalnum (*s
))
1514 if (!(symbolP
= symbol_find (name
)))
1517 if (S_GET_SEGMENT (symbolP
) != reg_section
)
1520 operand
->aregno
= S_GET_VALUE (symbolP
);
1521 if (operand
->aregno
>= REG_AR0
&& operand
->aregno
<= REG_AR7
)
1524 as_bad ("Auxiliary register AR0--AR7 required for indirect");
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. */
1532 s
= c4x_expression (s
, &operand
->expr
);
1533 if (operand
->expr
.X_op
!= O_constant
)
1535 operand
->disp
= operand
->expr
.X_add_number
;
1536 if (operand
->disp
< 0 || operand
->disp
> 255)
1538 as_bad ("Bad displacement %d (require 0--255)\n",
1544 case 'y': /* Need to match IR0. */
1545 case 'z': /* Need to match IR1. */
1546 #ifdef C4X_ALT_SYNTAX
1550 s
= c4x_expression (s
, &operand
->expr
);
1551 if (operand
->expr
.X_op
!= O_register
)
1553 if (operand
->expr
.X_add_number
!= REG_IR0
1554 && operand
->expr
.X_add_number
!= REG_IR1
)
1556 as_bad ("Index register IR0,IR1 required for displacement");
1560 if (*n
== 'y' && operand
->expr
.X_add_number
== REG_IR0
)
1562 if (*n
== 'z' && operand
->expr
.X_add_number
== REG_IR1
)
1567 if (*s
!= '(') /* No displacement, assume to be 1. */
1578 if (tolower (*s
) != *n
)
1583 if (*s
!= ' ' && *s
!= ',' && *s
!= '\0')
1585 input_line_pointer
= s
;
1590 c4x_operand_parse (s
, operand
)
1592 c4x_operand_t
*operand
;
1597 expressionS
*exp
= &operand
->expr
;
1598 char *save
= input_line_pointer
;
1601 struct hash_entry
*entry
= NULL
;
1603 input_line_pointer
= s
;
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
)
1611 *input_line_pointer
= c
;
1612 input_line_pointer
= (char *) entry
;
1616 *input_line_pointer
= c
;
1617 input_line_pointer
= str
;
1620 operand
->mode
= M_UNKNOWN
;
1621 switch (*input_line_pointer
)
1623 #ifdef C4X_ALT_SYNTAX
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
;
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
)
1638 if (exp
->X_add_number
)
1639 as_bad ("Number too large"); /* bignum required */
1642 c4x_gen_to_words (generic_floating_point_number
,
1643 operand
->fwords
, S_PRECISION
);
1644 operand
->mode
= M_IMMED_F
;
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
)
1651 operand
->mode
= M_HI
;
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
)
1661 if (exp
->X_add_number
> 0)
1662 as_bad ("Number too large"); /* bignum required. */
1665 c4x_gen_to_words (generic_floating_point_number
,
1666 operand
->fwords
, S_PRECISION
);
1667 operand
->mode
= M_IMMED_F
;
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
)
1674 operand
->mode
= M_IMMED
;
1679 as_bad ("Expecting a constant value");
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
)
1689 if (exp
->X_add_number
< 0)
1690 as_bad ("Direct value of %ld is not suitable",
1691 (long) exp
->X_add_number
);
1693 operand
->mode
= M_DIRECT
;
1698 for (i
= 0; i
< num_indirects
; i
++)
1699 if ((ret
= c4x_indirect_parse (operand
, &c4x_indirects
[i
])))
1703 if (i
< num_indirects
)
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;
1714 as_bad ("Unknown indirect addressing mode");
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
)
1723 know (exp
->X_add_symbol
== 0);
1724 know (exp
->X_op_symbol
== 0);
1725 operand
->mode
= M_REGISTER
;
1728 else if (exp
->X_op
== O_big
)
1730 if (exp
->X_add_number
> 0)
1731 as_bad ("Number too large"); /* bignum required. */
1734 c4x_gen_to_words (generic_floating_point_number
,
1735 operand
->fwords
, S_PRECISION
);
1736 operand
->mode
= M_IMMED_F
;
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
)
1744 operand
->mode
= M_DIRECT
;
1750 new = input_line_pointer
;
1751 input_line_pointer
= save
;
1756 c4x_operands_match (inst
, insn
)
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
;
1768 /* Build the opcode, checking as we go to make sure that the
1771 If an operand matches, we modify insn or opcode appropriately,
1772 and do a "continue". If an operand fails to match, we "break". */
1774 insn
->nchars
= 4; /* Instructions always 4 bytes. */
1775 insn
->reloc
= NO_RELOC
;
1780 insn
->opcode
= opcode
;
1781 return num_operands
== 0;
1789 case '\0': /* End of args. */
1790 if (num_operands
== 1)
1792 insn
->opcode
= opcode
;
1795 break; /* Too many operands. */
1797 case '#': /* This is only used for ldp. */
1798 if (operand
->mode
!= M_DIRECT
&& operand
->mode
!= M_IMMED
)
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
)
1804 if( ( IS_CPU_C4X (c4x_cpu
) && exp
->X_add_number
<= 65535 )
1805 || ( IS_CPU_C3X (c4x_cpu
) && exp
->X_add_number
<= 255 ) )
1807 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1812 as_bad ("LDF's immediate value of %ld is too large",
1813 (long) exp
->X_add_number
);
1818 else if (exp
->X_op
== O_symbol
)
1820 insn
->reloc
= BFD_RELOC_HI16
;
1824 break; /* Not direct (dp) addressing. */
1826 case '@': /* direct. */
1827 if (operand
->mode
!= M_DIRECT
)
1829 if (exp
->X_op
== O_constant
)
1831 if(exp
->X_add_number
<= 65535)
1833 /* Store only the 16 LSBs of the number. */
1834 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
1839 as_bad ("Direct value of %ld is too large",
1840 (long) exp
->X_add_number
);
1845 else if (exp
->X_op
== O_symbol
)
1847 insn
->reloc
= BFD_RELOC_LO16
;
1851 break; /* Not direct addressing. */
1854 if (operand
->mode
!= M_REGISTER
)
1856 reg
= exp
->X_add_number
;
1857 if (reg
>= REG_AR0
&& reg
<= REG_AR7
)
1858 INSERTU (opcode
, reg
- REG_AR0
, 24, 22);
1861 as_bad ("Destination register must be ARn");
1866 case 'B': /* Unsigned integer immediate. */
1867 /* Allow br label or br @label. */
1868 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
1870 if (exp
->X_op
== O_constant
)
1872 if (exp
->X_add_number
< (1 << 24))
1874 INSERTU (opcode
, exp
->X_add_number
, 23, 0);
1879 as_bad ("Immediate value of %ld is too large",
1880 (long) exp
->X_add_number
);
1885 if (IS_CPU_C4X (c4x_cpu
))
1887 insn
->reloc
= BFD_RELOC_24_PCREL
;
1892 insn
->reloc
= BFD_RELOC_24
;
1899 if (!IS_CPU_C4X (c4x_cpu
))
1901 if (operand
->mode
!= M_INDIRECT
)
1903 /* Require either *+ARn(disp) or *ARn. */
1904 if (operand
->expr
.X_add_number
!= 0
1905 && operand
->expr
.X_add_number
!= 0x18)
1907 as_bad ("Invalid indirect addressing mode");
1911 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
1912 INSERTU (opcode
, operand
->disp
, 7, 3);
1916 if (!(operand
->mode
== M_REGISTER
))
1918 INSERTU (opcode
, exp
->X_add_number
, 7, 0);
1922 if (!(operand
->mode
== M_REGISTER
))
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);
1930 as_bad ("Register must be Rn");
1936 if (operand
->mode
!= M_IMMED_F
1937 && !(operand
->mode
== M_IMMED
&& exp
->X_op
== O_constant
))
1940 if (operand
->mode
!= M_IMMED_F
)
1942 /* OK, we 've got something like cmpf 0, r0
1943 Why can't they stick in a bloody decimal point ?! */
1946 /* Create floating point number string. */
1947 sprintf (string
, "%d.0", (int) exp
->X_add_number
);
1948 c4x_atof (string
, 's', operand
->fwords
);
1951 INSERTU (opcode
, operand
->fwords
[0], 15, 0);
1955 if (operand
->mode
!= M_REGISTER
)
1957 INSERTU (opcode
, exp
->X_add_number
, 15, 8);
1961 if (operand
->mode
!= M_REGISTER
)
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);
1969 as_bad ("Register must be Rn");
1975 if (operand
->mode
!= M_REGISTER
)
1977 reg
= exp
->X_add_number
;
1978 if (reg
>= REG_R0
&& reg
<= REG_R7
)
1979 INSERTU (opcode
, reg
- REG_R0
, 18, 16);
1982 as_bad ("Register must be R0--R7");
1988 if (operand
->mode
!= M_INDIRECT
)
1990 if (operand
->disp
!= 0 && operand
->disp
!= 1)
1992 if (IS_CPU_C4X (c4x_cpu
))
1994 as_bad ("Invalid indirect addressing mode displacement %d",
1999 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 2, 0);
2000 INSERTU (opcode
, operand
->expr
.X_add_number
, 7, 3);
2004 if (operand
->mode
!= M_INDIRECT
)
2006 if (operand
->disp
!= 0 && operand
->disp
!= 1)
2008 if (IS_CPU_C4X (c4x_cpu
))
2010 as_bad ("Invalid indirect addressing mode displacement %d",
2015 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2016 INSERTU (opcode
, operand
->expr
.X_add_number
, 15, 11);
2020 if (operand
->mode
!= M_REGISTER
)
2022 reg
= exp
->X_add_number
;
2023 if (reg
>= REG_R0
&& reg
<= REG_R7
)
2024 INSERTU (opcode
, reg
- REG_R0
, 21, 19);
2027 as_bad ("Register must be R0--R7");
2033 if (operand
->mode
!= M_REGISTER
)
2035 reg
= exp
->X_add_number
;
2036 if (reg
>= REG_R0
&& reg
<= REG_R7
)
2037 INSERTU (opcode
, reg
- REG_R0
, 24, 22);
2040 as_bad ("Register must be R0--R7");
2046 if (operand
->mode
!= M_REGISTER
)
2048 reg
= exp
->X_add_number
;
2049 if (reg
== REG_R2
|| reg
== REG_R3
)
2050 INSERTU (opcode
, reg
- REG_R2
, 22, 22);
2053 as_bad ("Destination register must be R2 or R3");
2059 if (operand
->mode
!= M_REGISTER
)
2061 reg
= exp
->X_add_number
;
2062 if (reg
== REG_R0
|| reg
== REG_R1
)
2063 INSERTU (opcode
, reg
- REG_R0
, 23, 23);
2066 as_bad ("Destination register must be R0 or R1");
2072 if (!IS_CPU_C4X (c4x_cpu
))
2074 if (operand
->mode
!= M_INDIRECT
)
2076 /* Require either *+ARn(disp) or *ARn. */
2077 if (operand
->expr
.X_add_number
!= 0
2078 && operand
->expr
.X_add_number
!= 0x18)
2080 as_bad ("Invalid indirect addressing mode");
2084 INSERTU (opcode
, operand
->aregno
- REG_AR0
, 10, 8);
2085 INSERTU (opcode
, operand
->disp
, 15, 11);
2088 case 'P': /* PC relative displacement. */
2089 /* Allow br label or br @label. */
2090 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_DIRECT
)
2092 if (exp
->X_op
== O_constant
)
2094 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 32767)
2096 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2101 as_bad ("Displacement value of %ld is too large",
2102 (long) exp
->X_add_number
);
2107 insn
->reloc
= BFD_RELOC_16_PCREL
;
2113 if (operand
->mode
!= M_REGISTER
)
2115 reg
= exp
->X_add_number
;
2116 INSERTU (opcode
, reg
, 15, 0);
2120 if (operand
->mode
!= M_REGISTER
)
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);
2128 as_bad ("Register must be Rn");
2134 if (operand
->mode
!= M_REGISTER
)
2136 reg
= exp
->X_add_number
;
2137 INSERTU (opcode
, reg
, 20, 16);
2141 if (operand
->mode
!= M_REGISTER
)
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);
2149 as_bad ("Register must be Rn");
2154 case 'S': /* Short immediate int. */
2155 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2157 if (exp
->X_op
== O_big
)
2159 as_bad ("Floating point number not valid in expression");
2163 if (exp
->X_op
== O_constant
)
2165 if (exp
->X_add_number
>= -32768 && exp
->X_add_number
<= 65535)
2167 INSERTS (opcode
, exp
->X_add_number
, 15, 0);
2172 as_bad ("Signed immediate value %ld too large",
2173 (long) exp
->X_add_number
);
2178 else if (exp
->X_op
== O_symbol
)
2180 if (operand
->mode
== M_HI
)
2182 insn
->reloc
= BFD_RELOC_HI16
;
2186 insn
->reloc
= BFD_RELOC_LO16
;
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
2195 insn
->reloc
= BFD_RELOC_16
;
2199 case 'T': /* 5-bit immediate value for c4x stik. */
2200 if (!IS_CPU_C4X (c4x_cpu
))
2202 if (operand
->mode
!= M_IMMED
)
2204 if (exp
->X_op
== O_constant
)
2206 if (exp
->X_add_number
< 16 && exp
->X_add_number
>= -16)
2208 INSERTS (opcode
, exp
->X_add_number
, 20, 16);
2213 as_bad ("Immediate value of %ld is too large",
2214 (long) exp
->X_add_number
);
2219 break; /* No relocations allowed. */
2221 case 'U': /* Unsigned integer immediate. */
2222 if (operand
->mode
!= M_IMMED
&& operand
->mode
!= M_HI
)
2224 if (exp
->X_op
== O_constant
)
2226 if (exp
->X_add_number
< (1 << 16) && exp
->X_add_number
>= 0)
2228 INSERTU (opcode
, exp
->X_add_number
, 15, 0);
2233 as_bad ("Unsigned immediate value %ld too large",
2234 (long) exp
->X_add_number
);
2239 else if (exp
->X_op
== O_symbol
)
2241 if (operand
->mode
== M_HI
)
2242 insn
->reloc
= BFD_RELOC_HI16
;
2244 insn
->reloc
= BFD_RELOC_LO16
;
2249 insn
->reloc
= BFD_RELOC_16
;
2253 case 'V': /* Trap numbers (immediate field). */
2254 if (operand
->mode
!= M_IMMED
)
2256 if (exp
->X_op
== O_constant
)
2258 if (exp
->X_add_number
< 512 && IS_CPU_C4X (c4x_cpu
))
2260 INSERTU (opcode
, exp
->X_add_number
, 8, 0);
2263 else if (exp
->X_add_number
< 32 && IS_CPU_C3X (c4x_cpu
))
2265 INSERTU (opcode
, exp
->X_add_number
| 0x20, 4, 0);
2270 as_bad ("Immediate value of %ld is too large",
2271 (long) exp
->X_add_number
);
2276 break; /* No relocations allowed. */
2278 case 'W': /* Short immediate int (0--7). */
2279 if (!IS_CPU_C4X (c4x_cpu
))
2281 if (operand
->mode
!= M_IMMED
)
2283 if (exp
->X_op
== O_big
)
2285 as_bad ("Floating point number not valid in expression");
2289 if (exp
->X_op
== O_constant
)
2291 if (exp
->X_add_number
>= -256 && exp
->X_add_number
<= 127)
2293 INSERTS (opcode
, exp
->X_add_number
, 7, 0);
2298 as_bad ("Immediate value %ld too large",
2299 (long) exp
->X_add_number
);
2304 insn
->reloc
= BFD_RELOC_16
;
2308 case 'X': /* Expansion register for c4x. */
2309 if (operand
->mode
!= M_REGISTER
)
2311 reg
= exp
->X_add_number
;
2312 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2313 INSERTU (opcode
, reg
- REG_IVTP
, 4, 0);
2316 as_bad ("Register must be ivtp or tvtp");
2321 case 'Y': /* Address register for c4x lda. */
2322 if (operand
->mode
!= M_REGISTER
)
2324 reg
= exp
->X_add_number
;
2325 if (reg
>= REG_AR0
&& reg
<= REG_SP
)
2326 INSERTU (opcode
, reg
, 20, 16);
2329 as_bad ("Register must be address register");
2334 case 'Z': /* Expansion register for c4x. */
2335 if (operand
->mode
!= M_REGISTER
)
2337 reg
= exp
->X_add_number
;
2338 if (reg
>= REG_IVTP
&& reg
<= REG_TVTP
)
2339 INSERTU (opcode
, reg
- REG_IVTP
, 20, 16);
2342 as_bad ("Register must be ivtp or tvtp");
2348 if (operand
->mode
!= M_INDIRECT
)
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);
2355 case '|': /* treat as `,' if have ldi_ldi form. */
2358 if (--num_operands
< 0)
2359 break; /* Too few operands. */
2361 if (operand
->mode
!= M_PARALLEL
)
2366 case ',': /* Another operand. */
2367 if (--num_operands
< 0)
2368 break; /* Too few operands. */
2370 exp
= &operand
->expr
;
2373 case ';': /* Another optional operand. */
2374 if (num_operands
== 1 || operand
[1].mode
== M_PARALLEL
)
2376 if (--num_operands
< 0)
2377 break; /* Too few operands. */
2379 exp
= &operand
->expr
;
2390 c4x_insn_output (insn
)
2395 /* Grab another fragment for opcode. */
2396 dst
= frag_more (insn
->nchars
);
2398 /* Put out opcode word as a series of bytes in little endian order. */
2399 md_number_to_chars (dst
, insn
->opcode
, insn
->nchars
);
2401 /* Put out the symbol-dependent stuff. */
2402 if (insn
->reloc
!= NO_RELOC
)
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 */
2414 /* Parse the operands. */
2416 c4x_operands_parse (s
, operands
, num_operands
)
2418 c4x_operand_t
*operands
;
2422 return num_operands
;
2425 s
= c4x_operand_parse (s
, &operands
[num_operands
++]);
2426 while (num_operands
< C4X_OPERANDS_MAX
&& *s
++ == ',');
2428 if (num_operands
> C4X_OPERANDS_MAX
)
2430 as_bad ("Too many operands scanned");
2433 return num_operands
;
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. */
2447 c4x_inst_t
*inst
; /* Instruction template. */
2449 if (str
&& insn
->parallel
)
2453 /* Find mnemonic (second part of parallel instruction). */
2455 /* Skip past instruction mnemonic. */
2456 while (*s
&& *s
!= ' ' && *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
));
2464 /* Kludge to overcome problems with scrubber removing
2465 space between mnemonic and indirect operand (starting with *)
2466 on second line of parallel instruction. */
2470 insn
->operands
[insn
->num_operands
++].mode
= M_PARALLEL
;
2472 if ((i
= c4x_operands_parse
2473 (s
, insn
->operands
, insn
->num_operands
)) < 0)
2479 insn
->num_operands
= i
;
2485 if ((insn
->inst
= (struct c4x_inst
*)
2486 hash_find (c4x_op_hash
, insn
->name
)) == NULL
)
2488 as_bad ("Unknown opcode `%s'.", insn
->name
);
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. */
2504 ok
= c4x_operands_match (inst
, insn
);
2505 while (!ok
&& !strcmp (inst
->name
, inst
[1].name
) && inst
++);
2508 c4x_insn_output (insn
);
2510 as_bad ("Invalid operands for %s", insn
->name
);
2512 as_bad ("Invalid instruction %s", insn
->name
);
2517 /* Find mnemonic. */
2519 while (*s
&& *s
!= ' ') /* Skip past instruction mnemonic. */
2521 if (*s
) /* Null terminate for hash_find. */
2522 *s
++ = '\0'; /* and skip past null. */
2523 strncpy (insn
->name
, str
, C4X_NAME_MAX
- 3);
2525 if ((i
= c4x_operands_parse (s
, insn
->operands
, 0)) < 0)
2527 insn
->inst
= NULL
; /* Flag that error occured. */
2532 insn
->num_operands
= i
;
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. */
2553 md_atof (type
, litP
, sizeP
)
2560 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2561 LITTLENUM_TYPE
*wordP
;
2566 case 's': /* .single */
2572 case 'd': /* .double */
2574 case 'f': /* .float or .single */
2577 prec
= 2; /* 1 32-bit word */
2580 case 'i': /* .ieee */
2584 type
= 'f'; /* Rewrite type to be usable by atof_ieee() */
2587 case 'e': /* .ldouble */
2589 prec
= 4; /* 2 32-bit words */
2595 return "Bad call to md_atof()";
2599 t
= atof_ieee (input_line_pointer
, type
, words
);
2601 t
= c4x_atof (input_line_pointer
, type
, words
);
2603 input_line_pointer
= t
;
2604 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
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)
2613 if (wordP
<(words
+prec
-1)) /* Dump wordP[1] (if we have one) */
2615 md_number_to_chars (litP
, (valueT
) (wordP
[1]),
2616 sizeof (LITTLENUM_TYPE
));
2617 litP
+= sizeof (LITTLENUM_TYPE
);
2621 md_number_to_chars (litP
, (valueT
) (wordP
[0]),
2622 sizeof (LITTLENUM_TYPE
));
2623 litP
+= sizeof (LITTLENUM_TYPE
);
2629 md_apply_fix3 (fixP
, value
, seg
)
2632 segT seg ATTRIBUTE_UNUSED
;
2634 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
2635 valueT val
= *value
;
2637 switch (fixP
->fx_r_type
)
2639 case BFD_RELOC_HI16
:
2643 case BFD_RELOC_LO16
:
2650 switch (fixP
->fx_r_type
)
2655 case BFD_RELOC_24_PCREL
:
2658 case BFD_RELOC_16_PCREL
:
2659 case BFD_RELOC_LO16
:
2660 case BFD_RELOC_HI16
:
2667 as_bad ("Bad relocation type: 0x%02x", fixP
->fx_r_type
);
2671 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0) fixP
->fx_done
= 1;
2674 /* Should never be called for c4x. */
2676 md_convert_frag (headers
, sec
, fragP
)
2677 bfd
*headers ATTRIBUTE_UNUSED
;
2678 segT sec ATTRIBUTE_UNUSED
;
2679 fragS
*fragP ATTRIBUTE_UNUSED
;
2681 as_fatal ("md_convert_frag");
2684 /* Should never be called for c4x. */
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
;
2693 as_fatal ("md_create_short_jmp\n");
2696 /* Should never be called for c4x. */
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
;
2705 as_fatal ("md_create_long_jump\n");
2708 /* Should never be called for c4x. */
2710 md_estimate_size_before_relax (fragP
, segtype
)
2711 register fragS
*fragP ATTRIBUTE_UNUSED
;
2712 segT segtype ATTRIBUTE_UNUSED
;
2714 as_fatal ("md_estimate_size_before_relax\n");
2718 CONST
char *md_shortopts
= "bm:prs";
2719 struct option md_longopts
[] =
2721 {NULL
, no_argument
, NULL
, 0}
2724 size_t md_longopts_size
= sizeof (md_longopts
);
2727 md_parse_option (c
, arg
)
2733 case 'b': /* big model */
2736 case 'm': /* -m[c][34]x */
2737 if (tolower (*arg
) == 'c')
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
);
2743 case 'p': /* push args */
2746 case 'r': /* register args */
2749 case 's': /* small model */
2760 md_show_usage (stream
)
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",
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
2778 c4x_unrecognized_line (c
)
2784 if (c
!= '$' || !isdigit (input_line_pointer
[0]))
2787 s
= input_line_pointer
;
2789 /* Let's allow multiple digit local labels. */
2791 while (isdigit (*s
))
2793 lab
= lab
* 10 + *s
- '0';
2797 if (dollar_label_defined (lab
))
2799 as_bad ("Label \"$%d\" redefined", lab
);
2803 define_dollar_label (lab
);
2804 colon (dollar_label_name (lab
, 0));
2805 input_line_pointer
= s
+ 1;
2810 /* Handle local labels peculiar to us referred to in an expression. */
2812 md_undefined_symbol (name
)
2815 /* Look for local labels of the form $n. */
2816 if (name
[0] == '$' && isdigit (name
[1]))
2822 while (isdigit ((unsigned char) *s
))
2824 lab
= lab
* 10 + *s
- '0';
2827 if (dollar_label_defined (lab
))
2829 name
= dollar_label_name (lab
, 0);
2830 symbolP
= symbol_find (name
);
2834 name
= dollar_label_name (lab
, 1);
2835 symbolP
= symbol_find_or_make (name
);
2843 /* Parse an operand that is machine-specific. */
2845 md_operand (expressionP
)
2846 expressionS
*expressionP ATTRIBUTE_UNUSED
;
2850 /* Round up a section size to the appropriate boundary---do we need this? */
2852 md_section_align (segment
, size
)
2853 segT segment ATTRIBUTE_UNUSED
;
2856 return size
; /* Byte (i.e., 32-bit) alignment is fine? */
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. */
2869 case 0x62: /* call (C4x) */
2870 case 0x64: /* rptb (C4x) */
2872 case 0x61: /* brd */
2873 case 0x63: /* laj */
2874 case 0x65: /* rptbd (C4x) */
2876 case 0x66: /* swi */
2883 switch ((op
& 0xffe00000) >> 20)
2885 case 0x6a0: /* bB */
2886 case 0x720: /* callB */
2887 case 0x740: /* trapB */
2890 case 0x6a2: /* bBd */
2891 case 0x6a6: /* bBat */
2892 case 0x6aa: /* bBaf */
2893 case 0x722: /* lajB */
2894 case 0x748: /* latB */
2895 case 0x798: /* rptbd */
2902 switch ((op
& 0xfe200000) >> 20)
2904 case 0x6e0: /* dbB */
2907 case 0x6e2: /* dbBd */
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
2923 md_pcrel_from (fixP
)
2926 unsigned char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
2929 op
= (buf
[3] << 24) | (buf
[2] << 16) | (buf
[1] << 8) | buf
[0];
2931 return ((fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) >> 2) +
2935 /* Fill the alignment area with NOP's on .text, unless fill-data
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
;
2944 unsigned long nop
= NOP_OPCODE
;
2946 /* Because we are talking lwords, not bytes, adjust aligment to do words */
2949 if (alignment
!= 0 && !need_pass_2
)
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
);
2957 frag_align (alignment, 0, max);*/
2960 frag_align (alignment
, *fill
, max
);
2962 frag_align_pattern (alignment
, fill
, len
, max
);
2965 /* Return 1 to skip the default aligment function */
2969 /* Look for and remove parallel instruction operator ||. */
2973 char *s
= input_line_pointer
;
2977 /* If parallel instruction prefix found at start of line, skip it. */
2978 if (*input_line_pointer
== '|' && input_line_pointer
[1] == '|')
2983 input_line_pointer
+= 2;
2984 /* So line counters get bumped. */
2985 input_line_pointer
[-1] = '\n';
2992 input_line_pointer
= s
;
2997 tc_gen_reloc (seg
, fixP
)
2998 asection
*seg ATTRIBUTE_UNUSED
;
3003 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
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
)
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
);
3018 if (fixP
->fx_r_type
== BFD_RELOC_HI16
)
3019 reloc
->addend
= fixP
->fx_offset
;
3021 reloc
->addend
= fixP
->fx_addnumber
;