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