(asm_state): New state ASM_GIF.
[deliverable/binutils-gdb.git] / gas / config / tc-dvp.c
1 /* tc-dvp.c -- Assembler for the DVP
2 Copyright (C) 1997, 1998 Free Software Foundation.
3
4 This file is part of GAS, the GNU Assembler.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21 #include <stdio.h>
22 #include <ctype.h>
23
24 #include "sysdep.h"
25 #include "as.h"
26 #include "subsegs.h"
27 /* Needed by opcode/dvp.h. */
28 #include "dis-asm.h"
29 #include "opcode/dvp.h"
30 #include "elf/mips.h"
31
32 #ifdef USE_STDARG
33 #include <stdarg.h>
34 #else
35 #include <varargs.h>
36 #endif
37
38 /* Compute DMA operand index number of OP. */
39 #define DMA_OPERAND_INDEX(op) ((op) - dma_operands)
40
41 /* Our local label prefix. */
42 #define LOCAL_LABEL_PREFIX ".L"
43 /* Label prefix for end markers used in autocounts. */
44 #define END_LABEL_PREFIX ".L.end."
45
46 static long parse_float PARAMS ((char **, const char **));
47 static struct symbol * create_label PARAMS ((const char *, const char *));
48 static struct symbol * create_colon_label PARAMS ((const char *, const char *));
49 static char * unique_name PARAMS ((void));
50 static long eval_expr PARAMS ((int, int, const char *, ...));
51 static long parse_dma_addr_autocount ();
52 static void inline_dma_data PARAMS ((int, DVP_INSN *));
53 static void setup_autocount PARAMS ((const char *, DVP_INSN *));
54
55 static void insert_operand
56 PARAMS ((dvp_cpu, const dvp_opcode *, const dvp_operand *, int,
57 DVP_INSN *, offsetT, const char **));
58 static void insert_operand_final
59 PARAMS ((dvp_cpu, const dvp_operand *, int,
60 DVP_INSN *, offsetT, char *, unsigned int));
61
62 static int insert_file PARAMS ((const char *));
63
64 static int cur_vif_insn_length PARAMS ((void));
65 static void install_vif_length PARAMS ((char *, int));
66
67 const char comment_chars[] = ";";
68 const char line_comment_chars[] = "#";
69 const char line_separator_chars[] = "!";
70 const char EXP_CHARS[] = "eE";
71 const char FLT_CHARS[] = "dD";
72
73 /* Current assembler state.
74 Instructions like mpg and direct are followed by a restricted set of
75 instructions. In the case of a '*' length argument an end marker must
76 be provided. (e.g. mpg is followed by vu insns until a .EndMpg is
77 seen). */
78 typedef enum {
79 ASM_INIT, ASM_MPG, ASM_DIRECT, ASM_UNPACK, ASM_VU, ASM_GIF
80 } asm_state;
81 static asm_state cur_asm_state = ASM_INIT;
82
83 /* Nonzero if inside .DmaData. */
84 static int dma_data_state = 0;
85 /* Label of .DmaData (internally generated for inline data). */
86 static const char *dma_data_name;
87
88 /* Type of gif tag. */
89 static gif_type gif_insn_type;
90 /* Name of label of current gif<foo> insn's data. */
91 static const char *gif_data_name;
92 /* Pointer to current gif insn in fragment. */
93 static char *gif_insn_frag;
94
95 /* For variable length instructions, pointer to the initial frag
96 and pointer into that frag. These only hold valid values if
97 cur_asm_state is one of ASM_MPG, ASM_DIRECT, ASM_UNPACK. */
98 static fragS *cur_varlen_frag;
99 static char *cur_varlen_insn;
100 /* The length value specified in the insn, or -1 if '*'. */
101 static int cur_varlen_value;
102
103 /* Non-zero if packing vif instructions in dma tags. */
104 static int dma_pack_vif_p;
105
106 /* Non-zero if dma insns are to be included in the output.
107 This is the default, but writing "if (! no_dma)" is klunky. */
108 static int output_dma = 1;
109 /* Non-zero if vif insns are to be included in the output. */
110 static int output_vif = 1;
111 \f
112 const char *md_shortopts = "";
113
114 struct option md_longopts[] =
115 {
116 #define OPTION_NO_DMA (OPTION_MD_BASE + 1)
117 { "no-dma", no_argument, NULL, OPTION_NO_DMA },
118 #define OPTION_NO_DMA_VIF (OPTION_NO_DMA + 1)
119 { "no-dma-vif", no_argument, NULL, OPTION_NO_DMA_VIF },
120
121 {NULL, no_argument, NULL, 0}
122 };
123 size_t md_longopts_size = sizeof(md_longopts);
124
125 int
126 md_parse_option (c, arg)
127 int c;
128 char *arg;
129 {
130 switch (c)
131 {
132 case OPTION_NO_DMA :
133 output_dma = 0;
134 break;
135 case OPTION_NO_DMA_VIF :
136 output_dma = 0;
137 output_vif = 0;
138 break;
139 default :
140 return 0;
141 }
142 return 1;
143 }
144
145 void
146 md_show_usage (stream)
147 FILE *stream;
148 {
149 fprintf (stream, "\
150 DVP options:\n\
151 -no-dma do not include DMA instructions in the output\n\
152 -no-dma-vif do not include DMA or VIF instructions in the output\n\
153 ");
154 }
155
156 /* Set by md_assemble for use by dvp_fill_insn. */
157 static subsegT prev_subseg;
158 static segT prev_seg;
159
160 static void s_dmadata PARAMS ((int));
161 static void s_enddmadata PARAMS ((int));
162 static void s_dmapackvif PARAMS ((int));
163 static void s_enddirect PARAMS ((int));
164 static void s_endgif PARAMS ((int));
165 static void s_endmpg PARAMS ((int));
166 static void s_endunpack PARAMS ((int));
167 static void s_state PARAMS ((int));
168
169 /* The target specific pseudo-ops which we support. */
170 const pseudo_typeS md_pseudo_table[] =
171 {
172 { "word", cons, 4 },
173 { "dmadata", s_dmadata, 0 },
174 { "dmapackvif", s_dmapackvif, 0 },
175 { "enddirect", s_enddirect, 0 },
176 { "enddmadata", s_enddmadata, 0 },
177 { "endgif", s_endgif, 0 },
178 { "endmpg", s_endmpg, 0 },
179 { "endunpack", s_endunpack, 0 },
180 /* .vu added to simplify debugging and creation of input files */
181 { "vu", s_state, ASM_VU },
182 { NULL, NULL, 0 }
183 };
184 \f
185 void
186 md_begin ()
187 {
188 flagword applicable;
189 segT seg;
190 subsegT subseg;
191
192 /* Save the current subseg so we can restore it [it's the default one and
193 we don't want the initial section to be .sbss. */
194 seg = now_seg;
195 subseg = now_subseg;
196
197 subseg_set (seg, subseg);
198
199 /* Initialize the opcode tables.
200 This involves computing the hash chains. */
201 dvp_opcode_init_tables (0);
202
203 cur_asm_state = ASM_INIT;
204 dma_pack_vif_p = 0;
205 }
206 \f
207 /* We need to keep a list of fixups. We can't simply generate them as
208 we go, because that would require us to first create the frag, and
209 that would screw up references to ``.''. */
210
211 struct dvp_fixup
212 {
213 /* index into `dvp_operands' */
214 int opindex;
215 /* byte offset from beginning of instruction */
216 int offset;
217 expressionS exp;
218 };
219
220 #define MAX_FIXUPS 5
221
222 static int fixup_count;
223 static struct dvp_fixup fixups[MAX_FIXUPS];
224
225 /* Given a cpu type and operand number, return a temporary reloc type
226 for use in generating the fixup that encodes the cpu type and operand. */
227 static int encode_fixup_reloc_type PARAMS ((dvp_cpu, int));
228 /* Given an encoded fixup reloc type, decode it into cpu and operand. */
229 static void decode_fixup_reloc_type PARAMS ((int, dvp_cpu *,
230 const dvp_operand **));
231
232 static void assemble_dma PARAMS ((char *));
233 static void assemble_gif PARAMS ((char *));
234 static void assemble_vif PARAMS ((char *));
235 static void assemble_vu PARAMS ((char *));
236 static const dvp_opcode * assemble_vu_insn PARAMS ((dvp_cpu,
237 const dvp_opcode *,
238 const dvp_operand *,
239 char **, char *));
240 static const dvp_opcode * assemble_one_insn PARAMS ((dvp_cpu,
241 const dvp_opcode *,
242 const dvp_operand *,
243 char **, DVP_INSN *));
244
245 /* Main entry point for assembling an instruction. */
246
247 void
248 md_assemble (str)
249 char *str;
250 {
251 /* Skip leading white space. */
252 while (isspace (*str))
253 str++;
254
255 /* After a gif tag, no insns can appear until a .endgif is seen. */
256 if (cur_asm_state == ASM_GIF)
257 {
258 as_bad ("missing .endgif");
259 cur_asm_state = ASM_INIT;
260 }
261
262 if (cur_asm_state == ASM_INIT)
263 {
264 if (strncasecmp (str, "dma", 3) == 0)
265 assemble_dma (str);
266 else if (strncasecmp (str, "gif", 3) == 0)
267 assemble_gif (str);
268 else
269 assemble_vif (str);
270 }
271 else if (cur_asm_state == ASM_DIRECT)
272 assemble_gif (str);
273 else if (cur_asm_state == ASM_VU
274 || cur_asm_state == ASM_MPG)
275 assemble_vu (str);
276 else
277 as_fatal ("unknown parse state");
278 }
279
280 /* Subroutine of md_assemble to assemble DMA instructions. */
281
282 static void
283 assemble_dma (str)
284 char *str;
285 {
286 DVP_INSN insn_buf[4];
287 /* Insn's length, in 32 bit words. */
288 int len;
289 /* Pointer to allocated frag. */
290 char *f;
291 int i;
292 const dvp_opcode *opcode;
293
294 /* Fill the first two words with VIF NOPs.
295 They may be over-written later if DmaPackPke is on.
296 initialize the remainder with zeros. */
297 insn_buf[0] = 0;
298 insn_buf[1] = 0;
299 insn_buf[2] = 0;
300 insn_buf[3] = 0;
301
302 opcode = assemble_one_insn (DVP_DMA,
303 dma_opcode_lookup_asm (str), dma_operands,
304 &str, insn_buf);
305 if (opcode == NULL)
306 return;
307 if (!output_dma)
308 return;
309
310 /* Do an implicit alignment to a 16 byte boundary. */
311 frag_align (4, 0, 0);
312 record_alignment (now_seg, 4);
313
314 len = 4;
315 f = frag_more (len * 4);
316
317 /* Write out the DMA instruction. */
318 for (i = 0; i < len; ++i)
319 md_number_to_chars (f + i * 4, insn_buf[i], 4);
320
321 /* Create any fixups. */
322 /* FIXME: It might eventually be possible to combine all the various
323 copies of this bit of code. */
324 for (i = 0; i < fixup_count; ++i)
325 {
326 int op_type, reloc_type, offset;
327 const dvp_operand *operand;
328
329 /* Create a fixup for this operand.
330 At this point we do not use a bfd_reloc_code_real_type for
331 operands residing in the insn, but instead just use the
332 operand index. This lets us easily handle fixups for any
333 operand type, although that is admittedly not a very exciting
334 feature. We pick a BFD reloc type in md_apply_fix. */
335
336 op_type = fixups[i].opindex;
337 offset = fixups[i].offset;
338 reloc_type = encode_fixup_reloc_type (DVP_DMA, op_type);
339 operand = &dma_operands[op_type];
340 fix_new_exp (frag_now, f + offset - frag_now->fr_literal, 4,
341 &fixups[i].exp,
342 (operand->flags & DVP_OPERAND_RELATIVE_BRANCH) != 0,
343 (bfd_reloc_code_real_type) reloc_type);
344 }
345 }
346
347 /* Subroutine of md_assemble to assemble VIF instructions. */
348
349 static void
350 assemble_vif (str)
351 char *str;
352 {
353 /* Space for the instruction.
354 The variable length insns can require much more space than this.
355 It is allocated later, when we know we have such an insn. */
356 DVP_INSN insn_buf[5];
357 /* Insn's length, in 32 bit words. */
358 int len;
359 /* Pointer to allocated frag. */
360 char *f;
361 int i;
362 const dvp_opcode *opcode;
363
364 opcode = assemble_one_insn (DVP_VIF,
365 vif_opcode_lookup_asm (str), vif_operands,
366 &str, insn_buf);
367 if (opcode == NULL)
368 return;
369
370 if (opcode->flags & VIF_OPCODE_LENVAR)
371 len = 1; /* actual data follows later */
372 else if (opcode->flags & VIF_OPCODE_LEN2)
373 len = 2;
374 else if (opcode->flags & VIF_OPCODE_LEN5)
375 len = 5;
376 else
377 len = 1;
378
379 /* We still have to switch modes (if mpg for example) so we can't exit
380 early if -no-vif. */
381 if (output_vif)
382 {
383 /* Reminder: it is important to fetch enough space in one call to
384 `frag_more'. We use (f - frag_now->fr_literal) to compute where
385 we are and we don't want frag_now to change between calls. */
386 f = frag_more (len * 4);
387
388 /* Write out the instruction. */
389 for (i = 0; i < len; ++i)
390 md_number_to_chars (f + i * 4, insn_buf[i], 4);
391
392 /* Create any fixups. */
393 /* FIXME: It might eventually be possible to combine all the various
394 copies of this bit of code. */
395 for (i = 0; i < fixup_count; ++i)
396 {
397 int op_type, reloc_type, offset;
398 const dvp_operand *operand;
399
400 /* Create a fixup for this operand.
401 At this point we do not use a bfd_reloc_code_real_type for
402 operands residing in the insn, but instead just use the
403 operand index. This lets us easily handle fixups for any
404 operand type, although that is admittedly not a very exciting
405 feature. We pick a BFD reloc type in md_apply_fix. */
406
407 op_type = fixups[i].opindex;
408 offset = fixups[i].offset;
409 reloc_type = encode_fixup_reloc_type (DVP_VIF, op_type);
410 operand = &vif_operands[op_type];
411 fix_new_exp (frag_now, f + offset - frag_now->fr_literal, 4,
412 &fixups[i].exp,
413 (operand->flags & DVP_OPERAND_RELATIVE_BRANCH) != 0,
414 (bfd_reloc_code_real_type) reloc_type);
415 }
416 }
417
418 /* Handle variable length insns. */
419
420 if (opcode->flags & VIF_OPCODE_LENVAR)
421 {
422 /* Name of file to read data from. */
423 char *file;
424 /* Length in 32 bit words. */
425 int data_len;
426
427 file = NULL;
428 data_len = 0;
429 vif_get_var_data (&file, &data_len);
430 if (file)
431 {
432 int byte_len = insert_file (file);
433 if (output_vif)
434 install_vif_length (f, byte_len);
435 /* Update $.MpgLoc. */
436 vif_set_mpgloc (vif_get_mpgloc () + byte_len);
437 }
438 else
439 {
440 /* data_len == -1 means the value must be computed from
441 the data. */
442 if (data_len == 0 || data_len < -2)
443 as_bad ("invalid data length");
444 cur_varlen_frag = frag_now;
445 cur_varlen_insn = f;
446 cur_varlen_value = data_len;
447 if (opcode->flags & VIF_OPCODE_MPG)
448 cur_asm_state = ASM_MPG;
449 else if (opcode->flags & VIF_OPCODE_DIRECT)
450 cur_asm_state = ASM_DIRECT;
451 else if (opcode->flags & VIF_OPCODE_UNPACK)
452 cur_asm_state = ASM_UNPACK;
453 }
454 }
455 }
456
457 /* Subroutine of md_assemble to assemble GIF instructions. */
458
459 static void
460 assemble_gif (str)
461 char *str;
462 {
463 DVP_INSN insn_buf[4];
464 const dvp_opcode *opcode;
465 char *f;
466 int i;
467
468 insn_buf[0] = insn_buf[1] = insn_buf[2] = insn_buf[3] = 0;
469
470 opcode = assemble_one_insn (DVP_GIF,
471 gif_opcode_lookup_asm (str), gif_operands,
472 &str, insn_buf);
473 if (opcode == NULL)
474 return;
475
476 /* Do an implicit alignment to a 16 byte boundary. */
477 frag_align (4, 0, 0);
478 record_alignment (now_seg, 4);
479
480 gif_insn_frag = f = frag_more (16);
481 for (i = 0; i < 4; ++i)
482 md_number_to_chars (f + i * 4, insn_buf[i], 4);
483
484 /* Insert a label so we can compute the number of quadwords when the
485 .endgif is seen. */
486 gif_data_name = S_GET_NAME (create_colon_label ("", unique_name ()));
487
488 /* Record the type of the gif tag so we know how to compute nloop
489 in s_endgif. */
490 if (strcmp (opcode->mnemonic, "gifpacked") == 0)
491 gif_insn_type = GIF_PACKED;
492 else if (strcmp (opcode->mnemonic, "gifreglist") == 0)
493 gif_insn_type = GIF_REGLIST;
494 else if (strcmp (opcode->mnemonic, "gifimage") == 0)
495 gif_insn_type = GIF_IMAGE;
496 else
497 abort ();
498 cur_asm_state = ASM_GIF;
499 }
500
501 /* Subroutine of md_assemble to assemble VU instructions. */
502
503 static void
504 assemble_vu (str)
505 char *str;
506 {
507 /* The lower instruction has the lower address.
508 Handle this by grabbing 8 bytes now, and then filling each word
509 as appropriate. */
510 char *f = frag_more (8);
511 const dvp_opcode *opcode;
512
513 #ifdef VERTICAL_BAR_SEPARATOR
514 char *p = strchr (str, '|');
515
516 if (p == NULL)
517 {
518 as_bad ("lower slot missing in `%s'", str);
519 return;
520 }
521
522 *p = 0;
523 opcode = assemble_vu_insn (DVP_VUUP,
524 vu_upper_opcode_lookup_asm (str), vu_operands,
525 &str, f + 4);
526 *p = '|';
527 str = p + 1;
528 #else
529 opcode = assemble_vu_insn (DVP_VUUP,
530 vu_upper_opcode_lookup_asm (str), vu_operands,
531 &str, f + 4);
532 #endif
533
534 /* Don't assemble next one if we couldn't assemble the first. */
535 if (opcode == NULL)
536 return;
537 opcode = assemble_vu_insn (DVP_VULO,
538 vu_lower_opcode_lookup_asm (str), vu_operands,
539 &str, f);
540 /* If this was the "loi" pseudo-insn, we need to set the `i' bit. */
541 if (opcode != NULL)
542 {
543 if (strcmp (opcode->mnemonic, "loi") == 0)
544 f[7] |= 0x80;
545 }
546 }
547
548 static const dvp_opcode *
549 assemble_vu_insn (cpu, opcode, operand_table, pstr, buf)
550 dvp_cpu cpu;
551 const dvp_opcode *opcode;
552 const dvp_operand *operand_table;
553 char **pstr;
554 char *buf;
555 {
556 int i;
557 DVP_INSN insn;
558
559 opcode = assemble_one_insn (cpu, opcode, operand_table, pstr, &insn);
560 if (opcode == NULL)
561 return NULL;
562
563 /* Write out the instruction.
564 Reminder: it is important to fetch enough space in one call to
565 `frag_more'. We use (f - frag_now->fr_literal) to compute where
566 we are and we don't want frag_now to change between calls. */
567 md_number_to_chars (buf, insn, 4);
568
569 /* Create any fixups. */
570 for (i = 0; i < fixup_count; ++i)
571 {
572 int op_type, reloc_type;
573 const dvp_operand *operand;
574
575 /* Create a fixup for this operand.
576 At this point we do not use a bfd_reloc_code_real_type for
577 operands residing in the insn, but instead just use the
578 operand index. This lets us easily handle fixups for any
579 operand type, although that is admittedly not a very exciting
580 feature. We pick a BFD reloc type in md_apply_fix. */
581
582 op_type = fixups[i].opindex;
583 reloc_type = encode_fixup_reloc_type (cpu, op_type);
584 operand = &vu_operands[op_type];
585 fix_new_exp (frag_now, buf - frag_now->fr_literal, 4,
586 &fixups[i].exp,
587 (operand->flags & DVP_OPERAND_RELATIVE_BRANCH) != 0,
588 (bfd_reloc_code_real_type) reloc_type);
589 }
590
591 /* All done. */
592 return opcode;
593 }
594
595 /* Assemble one instruction at *PSTR.
596 CPU indicates what component we're assembling for.
597 The assembled instruction is stored in INSN_BUF.
598 OPCODE is a pointer to the head of the hash chain.
599
600 *PSTR is updated to point passed the parsed instruction.
601
602 If the insn is successfully parsed the result is a pointer to the opcode
603 entry that successfully matched and *PSTR is updated to point passed
604 the parsed insn. If an error occurs the result is NULL and *PSTR is left
605 at some random point in the string (??? may wish to leave it pointing where
606 the error occured). */
607
608 static const dvp_opcode *
609 assemble_one_insn (cpu, opcode, operand_table, pstr, insn_buf)
610 dvp_cpu cpu;
611 const dvp_opcode *opcode;
612 const dvp_operand *operand_table;
613 char **pstr;
614 DVP_INSN *insn_buf;
615 {
616 char *start, *str;
617
618 /* Keep looking until we find a match. */
619
620 start = str = *pstr;
621 for ( ; opcode != NULL; opcode = DVP_OPCODE_NEXT_ASM (opcode))
622 {
623 int past_opcode_p, num_suffixes;
624 const unsigned char *syn;
625
626 /* Ensure the mnemonic part matches. */
627 for (str = start, syn = opcode->mnemonic; *syn != '\0'; ++str, ++syn)
628 if (tolower (*str) != tolower (*syn))
629 break;
630 if (*syn != '\0')
631 continue;
632
633 /* Scan the syntax string. If it doesn't match, try the next one. */
634
635 dvp_opcode_init_parse ();
636 insn_buf[opcode->opcode_word] = opcode->value;
637 fixup_count = 0;
638 past_opcode_p = 0;
639 num_suffixes = 0;
640
641 /* We don't check for (*str != '\0') here because we want to parse
642 any trailing fake arguments in the syntax string. */
643 for (/*str = start, */ syn = opcode->syntax; *syn != '\0'; )
644 {
645 int mods,index;
646 const dvp_operand *operand;
647 const char *errmsg;
648
649 /* Non operand chars must match exactly.
650 Operand chars that are letters are not part of symbols
651 and are case insensitive. */
652 if (*syn < 128)
653 {
654 if (tolower (*str) == tolower (*syn))
655 {
656 if (*syn == ' ')
657 past_opcode_p = 1;
658 ++syn;
659 ++str;
660 }
661 else
662 break;
663 continue;
664 }
665
666 /* We have a suffix or an operand. Pick out any modifiers. */
667 mods = 0;
668 index = DVP_OPERAND_INDEX (*syn);
669 while (DVP_MOD_P (operand_table[index].flags))
670 {
671 mods |= operand_table[index].flags & DVP_MOD_BITS;
672 ++syn;
673 index = DVP_OPERAND_INDEX (*syn);
674 }
675 operand = operand_table + index;
676
677 if (operand->flags & DVP_OPERAND_FAKE)
678 {
679 long value = 0;
680
681 if (operand->flags & DVP_OPERAND_DMA_INLINE)
682 {
683 inline_dma_data ((mods & DVP_OPERAND_AUTOCOUNT) != 0,
684 insn_buf);
685 ++syn;
686 continue;
687 }
688
689 if (operand->parse)
690 {
691 errmsg = NULL;
692 value = (*operand->parse) (opcode, operand, mods,
693 &str, &errmsg);
694 if (errmsg)
695 break;
696 }
697 if (operand->insert)
698 {
699 errmsg = NULL;
700 (*operand->insert) (opcode, operand, mods, insn_buf,
701 (offsetT) value, &errmsg);
702 /* If we get an error, go on to try the next insn. */
703 if (errmsg)
704 break;
705 }
706 ++syn;
707 }
708 /* Are we finished with suffixes? */
709 else if (!past_opcode_p)
710 {
711 long suf_value;
712
713 if (!(operand->flags & DVP_OPERAND_SUFFIX))
714 as_fatal ("bad opcode table, missing suffix flag");
715
716 /* If we're at a space in the input string, we want to skip the
717 remaining suffixes. There may be some fake ones though, so
718 just go on to try the next one. */
719 if (*str == ' ')
720 {
721 ++syn;
722 continue;
723 }
724
725 /* Parse the suffix. */
726 errmsg = NULL;
727 suf_value = (*operand->parse) (opcode, operand, mods, &str,
728 &errmsg);
729 if (errmsg)
730 {
731 /* This can happen, for example, in ARC's in "blle foo" and
732 we're currently using the template "b%q%.n %j". The "bl"
733 insn occurs later in the table so "lle" isn't an illegal
734 suffix. */
735 break;
736 }
737
738 /* Insert the suffix's value into the insn. */
739 insert_operand (cpu, opcode, operand, mods, insn_buf,
740 (offsetT) suf_value, &errmsg);
741
742 ++syn;
743 }
744 else
745 /* This is an operand, either a register or an expression of
746 some kind. */
747 {
748 char c;
749 char *hold;
750 long value = 0;
751 expressionS exp;
752
753 if (operand->flags & DVP_OPERAND_SUFFIX)
754 as_fatal ("bad opcode table, suffix wrong");
755
756 /* Is there anything left to parse?
757 We don't check for this at the top because we want to parse
758 any trailing fake arguments in the syntax string. */
759 /* ??? This doesn't allow operands with a legal value of "". */
760 if (*str == '\0')
761 break;
762
763 /* Parse the operand. */
764 if (operand->flags & DVP_OPERAND_FLOAT)
765 {
766 errmsg = 0;
767 value = parse_float (&str, &errmsg);
768 if (errmsg)
769 break;
770 }
771 else if ((operand->flags & DVP_OPERAND_DMA_ADDR)
772 && (mods & DVP_OPERAND_AUTOCOUNT))
773 {
774 errmsg = 0;
775 value = parse_dma_addr_autocount (opcode, operand, mods,
776 insn_buf, &str, &errmsg);
777 if (errmsg)
778 break;
779 }
780 else if (operand->parse)
781 {
782 errmsg = NULL;
783 value = (*operand->parse) (opcode, operand, mods,
784 &str, &errmsg);
785 if (errmsg)
786 break;
787 }
788 else
789 {
790 hold = input_line_pointer;
791 input_line_pointer = str;
792 expression (&exp);
793 str = input_line_pointer;
794 input_line_pointer = hold;
795
796 if (exp.X_op == O_illegal
797 || exp.X_op == O_absent)
798 break;
799 else if (exp.X_op == O_constant)
800 value = exp.X_add_number;
801 else if (exp.X_op == O_register)
802 as_fatal ("got O_register");
803 else
804 {
805 /* We need to generate a fixup for this expression. */
806 if (fixup_count >= MAX_FIXUPS)
807 as_fatal ("too many fixups");
808 fixups[fixup_count].exp = exp;
809 fixups[fixup_count].opindex = index;
810 /* FIXME: Revisit. Do we really need operand->word?
811 The endianness of a 128 bit DMAtag is rather
812 twisted. How about defining word 0 as the word with
813 the lowest address and basing operand-shift off that.
814 operand->word could then be deleted. */
815 if (operand->word != 0)
816 fixups[fixup_count].offset = operand->word * 4;
817 else
818 fixups[fixup_count].offset = (operand->shift / 32) * 4;
819 ++fixup_count;
820 value = 0;
821 }
822 }
823
824 /* Insert the register or expression into the instruction. */
825 errmsg = NULL;
826 insert_operand (cpu, opcode, operand, mods, insn_buf,
827 (offsetT) value, &errmsg);
828 if (errmsg != (const char *) NULL)
829 break;
830
831 ++syn;
832 }
833 }
834
835 /* If we're at the end of the syntax string, we're done. */
836 if (*syn == '\0')
837 {
838 int i;
839
840 /* For the moment we assume a valid `str' can only contain blanks
841 now. IE: We needn't try again with a longer version of the
842 insn and it is assumed that longer versions of insns appear
843 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
844
845 while (isspace (*str))
846 ++str;
847
848 if (*str != '\0'
849 #ifndef VERTICAL_BAR_SEPARATOR
850 && cpu != DVP_VUUP
851 #endif
852 )
853 as_bad ("junk at end of line: `%s'", str);
854
855 /* It's now up to the caller to emit the instruction and any
856 relocations. */
857 *pstr = str;
858 return opcode;
859 }
860
861 /* Try the next entry. */
862 }
863
864 as_bad ("bad instruction `%s'", start);
865 return 0;
866 }
867
868 void
869 md_operand (expressionP)
870 expressionS *expressionP;
871 {
872 }
873
874 valueT
875 md_section_align (segment, size)
876 segT segment;
877 valueT size;
878 {
879 int align = bfd_get_section_alignment (stdoutput, segment);
880 return ((size + (1 << align) - 1) & (-1 << align));
881 }
882
883 symbolS *
884 md_undefined_symbol (name)
885 char *name;
886 {
887 return 0;
888 }
889
890 /* Called after parsing the file via md_after_pass_hook. */
891
892 void
893 dvp_parse_done ()
894 {
895 #if 0 /* ??? Doesn't work unless we keep track of the nested include file
896 level. */
897 /* Check for missing .EndMpg, and supply one if necessary. */
898 if (cur_asm_state == ASM_MPG)
899 s_endmpg (0);
900 else if (cur_asm_state == ASM_DIRECT)
901 s_enddirect (0);
902 else if (cur_asm_state == ASM_UNPACK)
903 s_endunpack (0);
904 #endif
905 }
906 \f
907 /* Functions concerning relocs. */
908
909 /* Spacing between each cpu type's operand numbers.
910 Should be at least as bit as any operand table. */
911 #define RELOC_SPACING 256
912
913 /* Given a cpu type and operand number, return a temporary reloc type
914 for use in generating the fixup that encodes the cpu type and operand
915 number. */
916
917 static int
918 encode_fixup_reloc_type (cpu, opnum)
919 dvp_cpu cpu;
920 int opnum;
921 {
922 return (int) BFD_RELOC_UNUSED + ((int) cpu * RELOC_SPACING) + opnum;
923 }
924
925 /* Given a fixup reloc type, decode it into cpu type and operand. */
926
927 static void
928 decode_fixup_reloc_type (fixup_reloc, cpuP, operandP)
929 int fixup_reloc;
930 dvp_cpu *cpuP;
931 const dvp_operand **operandP;
932 {
933 dvp_cpu cpu = (fixup_reloc - (int) BFD_RELOC_UNUSED) / RELOC_SPACING;
934 int opnum = (fixup_reloc - (int) BFD_RELOC_UNUSED) % RELOC_SPACING;
935
936 *cpuP = cpu;
937 switch (cpu)
938 {
939 case DVP_VUUP : *operandP = &vu_operands[opnum]; break;
940 case DVP_VULO : *operandP = &vu_operands[opnum]; break;
941 case DVP_DMA : *operandP = &dma_operands[opnum]; break;
942 case DVP_VIF : *operandP = &vif_operands[opnum]; break;
943 case DVP_GIF : *operandP = &gif_operands[opnum]; break;
944 default : as_fatal ("bad fixup encoding");
945 }
946 }
947
948 /* Given a fixup reloc type, return a pointer to the operand
949
950 /* The location from which a PC relative jump should be calculated,
951 given a PC relative reloc. */
952
953 long
954 md_pcrel_from_section (fixP, sec)
955 fixS *fixP;
956 segT sec;
957 {
958 if (fixP->fx_addsy != (symbolS *) NULL
959 && (! S_IS_DEFINED (fixP->fx_addsy)
960 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
961 {
962 /* The symbol is undefined (or is defined but not in this section).
963 Let the linker figure it out. +8: branch offsets are relative to the
964 delay slot. */
965 return 8;
966 }
967
968 /* We assume this is a vu branch.
969 Offsets are calculated based on the address of the next insn. */
970 return ((fixP->fx_frag->fr_address + fixP->fx_where) & -8L) + 8;
971 }
972
973 /* Apply a fixup to the object code. This is called for all the
974 fixups we generated by calls to fix_new_exp. At this point all symbol
975 values should be fully resolved, and we attempt to completely resolve the
976 reloc. If we can not do that, we determine the correct reloc code and put
977 it back in the fixup. */
978
979 int
980 md_apply_fix3 (fixP, valueP, seg)
981 fixS *fixP;
982 valueT *valueP;
983 segT seg;
984 {
985 char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
986 valueT value;
987
988 /* FIXME FIXME FIXME: The value we are passed in *valueP includes
989 the symbol values. Since we are using BFD_ASSEMBLER, if we are
990 doing this relocation the code in write.c is going to call
991 bfd_perform_relocation, which is also going to use the symbol
992 value. That means that if the reloc is fully resolved we want to
993 use *valueP since bfd_perform_relocation is not being used.
994 However, if the reloc is not fully resolved we do not want to use
995 *valueP, and must use fx_offset instead. However, if the reloc
996 is PC relative, we do want to use *valueP since it includes the
997 result of md_pcrel_from. This is confusing. */
998
999 if (fixP->fx_addsy == (symbolS *) NULL)
1000 {
1001 value = *valueP;
1002 fixP->fx_done = 1;
1003 }
1004 else if (fixP->fx_pcrel)
1005 {
1006 value = *valueP;
1007 }
1008 else
1009 {
1010 value = fixP->fx_offset;
1011 if (fixP->fx_subsy != (symbolS *) NULL)
1012 {
1013 if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)
1014 value -= S_GET_VALUE (fixP->fx_subsy);
1015 else
1016 {
1017 /* We can't actually support subtracting a symbol. */
1018 as_bad_where (fixP->fx_file, fixP->fx_line,
1019 "expression too complex");
1020 }
1021 }
1022 }
1023
1024 /* Check for dvp operands. These are indicated with a reloc value
1025 >= BFD_RELOC_UNUSED. */
1026
1027 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
1028 {
1029 dvp_cpu cpu;
1030 const dvp_operand *operand;
1031 DVP_INSN insn;
1032
1033 decode_fixup_reloc_type ((int) fixP->fx_r_type,
1034 & cpu, & operand);
1035
1036 /* Fetch the instruction, insert the fully resolved operand
1037 value, and stuff the instruction back again. The fixup is recorded
1038 at the appropriate word so pass DVP_MOD_THIS_WORD so any offset
1039 specified in the tables is ignored. */
1040 insn = bfd_getl32 ((unsigned char *) where);
1041 insert_operand_final (cpu, operand, DVP_MOD_THIS_WORD, &insn,
1042 (offsetT) value, fixP->fx_file, fixP->fx_line);
1043 bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
1044
1045 if (fixP->fx_done)
1046 {
1047 /* Nothing else to do here. */
1048 return 1;
1049 }
1050
1051 /* Determine a BFD reloc value based on the operand information.
1052 We are only prepared to turn a few of the operands into relocs. */
1053 /* FIXME: This test is a hack. */
1054 if ((operand->flags & DVP_OPERAND_RELATIVE_BRANCH) != 0)
1055 {
1056 assert (operand->bits == 11
1057 && operand->shift == 0);
1058 fixP->fx_r_type = BFD_RELOC_MIPS_DVP_11_PCREL;
1059 }
1060 else if ((operand->flags & DVP_OPERAND_DMA_ADDR) != 0
1061 || (operand->flags & DVP_OPERAND_DMA_NEXT) != 0)
1062 {
1063 assert (operand->bits == 27
1064 && operand->shift == 4);
1065 fixP->fx_r_type = BFD_RELOC_MIPS_DVP_27_S4;
1066 }
1067 else
1068 {
1069 as_bad_where (fixP->fx_file, fixP->fx_line,
1070 "unresolved expression that must be resolved");
1071 fixP->fx_done = 1;
1072 return 1;
1073 }
1074 }
1075 else
1076 {
1077 switch (fixP->fx_r_type)
1078 {
1079 case BFD_RELOC_8:
1080 md_number_to_chars (where, value, 1);
1081 break;
1082 case BFD_RELOC_16:
1083 md_number_to_chars (where, value, 2);
1084 break;
1085 case BFD_RELOC_32:
1086 md_number_to_chars (where, value, 4);
1087 break;
1088 default:
1089 abort ();
1090 }
1091 }
1092
1093 fixP->fx_addnumber = value;
1094
1095 return 1;
1096 }
1097
1098 /* Translate internal representation of relocation info to BFD target
1099 format. */
1100
1101 arelent *
1102 tc_gen_reloc (section, fixP)
1103 asection *section;
1104 fixS *fixP;
1105 {
1106 arelent *reloc;
1107
1108 reloc = (arelent *) xmalloc (sizeof (arelent));
1109
1110 reloc->sym_ptr_ptr = &fixP->fx_addsy->bsym;
1111 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
1112 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
1113 if (reloc->howto == (reloc_howto_type *) NULL)
1114 {
1115 as_bad_where (fixP->fx_file, fixP->fx_line,
1116 "internal error: can't export reloc type %d (`%s')",
1117 fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type));
1118 return NULL;
1119 }
1120
1121 assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
1122
1123 reloc->addend = fixP->fx_addnumber;
1124
1125 return reloc;
1126 }
1127 \f
1128 /* Write a value out to the object file, using the appropriate endianness. */
1129
1130 void
1131 md_number_to_chars (buf, val, n)
1132 char *buf;
1133 valueT val;
1134 int n;
1135 {
1136 if (target_big_endian)
1137 number_to_chars_bigendian (buf, val, n);
1138 else
1139 number_to_chars_littleendian (buf, val, n);
1140 }
1141
1142 /* Turn a string in input_line_pointer into a floating point constant of type
1143 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1144 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
1145 */
1146
1147 /* Equal to MAX_PRECISION in atof-ieee.c */
1148 #define MAX_LITTLENUMS 6
1149
1150 char *
1151 md_atof (type, litP, sizeP)
1152 char type;
1153 char *litP;
1154 int *sizeP;
1155 {
1156 int i,prec;
1157 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1158 LITTLENUM_TYPE *wordP;
1159 char *t;
1160 char *atof_ieee ();
1161
1162 switch (type)
1163 {
1164 case 'f':
1165 case 'F':
1166 case 's':
1167 case 'S':
1168 prec = 2;
1169 break;
1170
1171 case 'd':
1172 case 'D':
1173 case 'r':
1174 case 'R':
1175 prec = 4;
1176 break;
1177
1178 /* FIXME: Some targets allow other format chars for bigger sizes here. */
1179
1180 default:
1181 *sizeP = 0;
1182 return "Bad call to md_atof()";
1183 }
1184
1185 t = atof_ieee (input_line_pointer, type, words);
1186 if (t)
1187 input_line_pointer = t;
1188 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1189
1190 if (target_big_endian)
1191 {
1192 for (i = 0; i < prec; i++)
1193 {
1194 md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE));
1195 litP += sizeof (LITTLENUM_TYPE);
1196 }
1197 }
1198 else
1199 {
1200 for (i = prec - 1; i >= 0; i--)
1201 {
1202 md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE));
1203 litP += sizeof (LITTLENUM_TYPE);
1204 }
1205 }
1206
1207 return 0;
1208 }
1209 \f
1210 /* Miscellaneous utilities. */
1211
1212 /* Parse a 32 bit floating point number.
1213 The result is those 32 bits as an integer. */
1214
1215 static long
1216 parse_float (pstr, errmsg)
1217 char **pstr;
1218 const char **errmsg;
1219 {
1220 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1221 char *p;
1222
1223 p = atof_ieee (*pstr, 'f', words);
1224 *pstr = p;
1225 return (words[0] << 16) | words[1];
1226 }
1227
1228 /* Scan a symbol and return a pointer to one past the end. */
1229
1230 #define issymchar(ch) (isalnum(ch) || ch == '_')
1231 static char *
1232 scan_symbol (sym)
1233 char *sym;
1234 {
1235 while (*sym && issymchar (*sym))
1236 ++sym;
1237 return sym;
1238 }
1239
1240 /* Evaluate an expression.
1241 The result is the value of the expression if it can be evaluated,
1242 or 0 if it cannot (say because some symbols haven't been defined yet)
1243 in which case a fixup is queued.
1244
1245 If OPINDEX is 0, don't queue any fixups, just return 0. */
1246
1247 static long
1248 #ifdef USE_STDARG
1249 eval_expr (int opindex, int offset, const char *fmt, ...)
1250 #else
1251 eval_expr (opindex, offset, fmt, va_alist)
1252 int opindex,offset;
1253 const char *fmt;
1254 va_dcl
1255 #endif
1256 {
1257 long value;
1258 va_list ap;
1259 char *str,*save_input;
1260 expressionS exp;
1261
1262 #ifdef USE_STDARG
1263 va_start (ap, fmt);
1264 #else
1265 va_start (ap);
1266 #endif
1267 vasprintf (&str, fmt, ap);
1268 va_end (ap);
1269
1270 save_input = input_line_pointer;
1271 input_line_pointer = str;
1272 expression (&exp);
1273 input_line_pointer = save_input;
1274 free (str);
1275 if (exp.X_op == O_constant)
1276 value = exp.X_add_number;
1277 else
1278 {
1279 if (opindex != 0)
1280 {
1281 fixups[fixup_count].exp = exp;
1282 fixups[fixup_count].opindex = opindex;
1283 fixups[fixup_count].offset = offset;
1284 ++fixup_count;
1285 }
1286 value = 0;
1287 }
1288 return value;
1289 }
1290
1291 /* Create a label named by concatenating PREFIX to NAME. */
1292
1293 static struct symbol *
1294 create_label (prefix, name)
1295 const char *prefix, *name;
1296 {
1297 int namelen = strlen (name);
1298 int prefixlen = strlen (prefix);
1299 char *fullname;
1300 struct symbol *result;
1301
1302 fullname = xmalloc (prefixlen + namelen + 1);
1303 strcpy (fullname, prefix);
1304 strcat (fullname, name);
1305 result = symbol_find_or_make (fullname);
1306 free (fullname);
1307 return result;
1308 }
1309
1310 /* Create a label named by concatenating PREFIX to NAME,
1311 and define it as `.'. */
1312
1313 static struct symbol *
1314 create_colon_label (prefix, name)
1315 const char *prefix, *name;
1316 {
1317 int namelen = strlen (name);
1318 int prefixlen = strlen (prefix);
1319 char *fullname;
1320 struct symbol *result;
1321
1322 fullname = xmalloc (prefixlen + namelen + 1);
1323 strcpy (fullname, prefix);
1324 strcat (fullname, name);
1325 result = colon (fullname);
1326 free (fullname);
1327 return result;
1328 }
1329
1330 /* Return a malloc'd string useful in creating unique labels. */
1331 /* ??? Presumably such a routine already exists somewhere
1332 [but a first pass at finding it didn't turn up anything]. */
1333
1334 static char *
1335 unique_name ()
1336 {
1337 static int counter;
1338 char *result;
1339
1340 asprintf (&result, "dvptmp%d", counter);
1341 ++counter;
1342 return result;
1343 }
1344 \f
1345 /* Compute the auto-count value for a DMA tag. */
1346
1347 static void
1348 setup_autocount (name, insn_buf)
1349 const char *name;
1350 DVP_INSN *insn_buf;
1351 {
1352 long count;
1353
1354 count = eval_expr (dma_operand_count, 12,
1355 "(%s%s - %s) >> 4", END_LABEL_PREFIX, name, name);
1356 /* count is in quadwords */
1357 count /= 16;
1358
1359 /* Store the count field. */
1360 insn_buf[3] &= 0xffff0000;
1361 insn_buf[3] |= count & 0x0000ffff;
1362 }
1363
1364 /* Record that inline data follows. */
1365
1366 static void
1367 inline_dma_data (autocount_p, insn_buf)
1368 int autocount_p;
1369 DVP_INSN *insn_buf;
1370 {
1371 if (dma_data_state != 0 )
1372 {
1373 as_bad ("DmaData blocks cannot be nested.");
1374 return;
1375 }
1376
1377 dma_data_state = 1;
1378
1379 if (autocount_p)
1380 {
1381 dma_data_name = S_GET_NAME (create_colon_label ("", unique_name ()));
1382 setup_autocount (dma_data_name, insn_buf);
1383 }
1384 else
1385 dma_data_name = 0;
1386 }
1387
1388 /* Compute the auto-count value for a DMA tag with out-of-line data. */
1389
1390 static long
1391 parse_dma_addr_autocount (opcode, operand, mods, insn_buf, pstr, errmsg)
1392 const dvp_opcode *opcode;
1393 const dvp_operand *operand;
1394 int mods;
1395 DVP_INSN *insn_buf;
1396 char **pstr;
1397 const char **errmsg;
1398 {
1399 char *start = *pstr;
1400 char *end = start;
1401 long retval;
1402 /* Data reference must be a .DmaData label. */
1403 struct symbol *label, *label2, *endlabel;
1404 const char *name;
1405 char c;
1406
1407 label = label2 = 0;
1408 if (! is_name_beginner (*start))
1409 {
1410 *errmsg = "invalid .DmaData label";
1411 return 0;
1412 }
1413
1414 name = start;
1415 end = scan_symbol (name);
1416 c = *end;
1417 *end = 0;
1418 label = symbol_find_or_make (name);
1419 *end = c;
1420
1421 label2 = create_label ("_$", name);
1422 endlabel = create_label (END_LABEL_PREFIX, name);
1423
1424 retval = eval_expr (dma_operand_addr, 8, name);
1425
1426 setup_autocount (name, insn_buf);
1427
1428 *pstr = end;
1429 return retval;
1430 }
1431 \f
1432 /* Return length in bytes of the variable length VIF insn
1433 currently being assembled. */
1434
1435 static int
1436 cur_vif_insn_length ()
1437 {
1438 int byte_len;
1439 fragS *f;
1440
1441 if (cur_varlen_frag == frag_now)
1442 byte_len = frag_more (0) - cur_varlen_insn - 4; /* -4 for mpg itself */
1443 else
1444 {
1445 byte_len = (cur_varlen_frag->fr_fix + cur_varlen_frag->fr_offset -
1446 (cur_varlen_insn - cur_varlen_frag->fr_literal)) - 4;
1447 for (f = cur_varlen_frag->fr_next; f != frag_now; f = f->fr_next)
1448 byte_len += f->fr_fix + f->fr_offset;
1449 byte_len += frag_now_fix ();
1450 }
1451
1452 return byte_len;
1453 }
1454
1455 /* Install length LEN, in bytes, in the vif insn at BUF.
1456 The bytes in BUF are in target order. */
1457
1458 static void
1459 install_vif_length (buf, len)
1460 char *buf;
1461 int len;
1462 {
1463 char cmd = buf[3];
1464
1465 if ((cmd & 0x70) == 0x40)
1466 {
1467 /* mpg */
1468 len /= 4;
1469 /* ??? Worry about data /= 4 cuts off? */
1470 if (len > 256)
1471 as_bad ("`mpg' data length must be between 1 and 256");
1472 buf[2] = len == 256 ? 0 : len;
1473 }
1474 else if ((cmd & 0x70) == 0x50)
1475 {
1476 /* direct/directhl */
1477 /* ??? Worry about data /= 16 cuts off? */
1478 len /= 16;
1479 if (len > 65536)
1480 as_bad ("`direct' data length must be between 1 and 65536");
1481 len = len == 65536 ? 0 : len;
1482 buf[0] = len;
1483 buf[1] = len >> 8;
1484 }
1485 else if ((cmd & 0x60) == 0x60)
1486 {
1487 /* unpack */
1488 /* FIXME */
1489 }
1490 else
1491 as_fatal ("bad call to install_vif_length");
1492 }
1493
1494 /* Insert a file into the output.
1495 -I is used to specify where to find the file.
1496 The result is the number of bytes inserted.
1497 If an error occurs an error message is printed and zero is returned. */
1498
1499 static int
1500 insert_file (file)
1501 const char *file;
1502 {
1503 FILE *f;
1504 char buf[256];
1505 int i, n, total;
1506 char *path;
1507
1508 path = xmalloc (strlen (file) + include_dir_maxlen + 5 /*slop*/);
1509 f = NULL;
1510 for (i = 0; i < include_dir_count; i++)
1511 {
1512 strcpy (path, include_dirs[i]);
1513 strcat (path, "/");
1514 strcat (path, file);
1515 if ((f = fopen (path, FOPEN_RB)) != NULL)
1516 break;
1517 }
1518 free (path);
1519 if (f == NULL)
1520 f = fopen (file, FOPEN_RB);
1521 if (f == NULL)
1522 {
1523 as_bad ("unable to read file `%s'", file);
1524 return 0;
1525 }
1526
1527 total = 0;
1528 do {
1529 n = fread (buf, 1, sizeof (buf), f);
1530 if (n > 0)
1531 {
1532 char *fr = frag_more (n);
1533 memcpy (fr, buf, n);
1534 total += n;
1535 }
1536 } while (n > 0);
1537
1538 fclose (f);
1539 /* We assume the file is smaller than 2^31 bytes.
1540 Ok, we shouldn't make any assumptions. Later. */
1541 return total;
1542 }
1543
1544 /* Insert an operand value into an instruction. */
1545
1546 static void
1547 insert_operand (cpu, opcode, operand, mods, insn_buf, val, errmsg)
1548 dvp_cpu cpu;
1549 const dvp_opcode *opcode;
1550 const dvp_operand *operand;
1551 int mods;
1552 DVP_INSN *insn_buf;
1553 offsetT val;
1554 const char **errmsg;
1555 {
1556 if (operand->insert)
1557 {
1558 (*operand->insert) (opcode, operand, mods, insn_buf, (long) val, errmsg);
1559 }
1560 else
1561 {
1562 /* We currently assume a field does not cross a word boundary. */
1563 int shift = ((mods & DVP_MOD_THIS_WORD)
1564 ? (operand->shift & 31)
1565 : operand->shift);
1566 /* FIXME: revisit */
1567 if (operand->word == 0)
1568 {
1569 int word = (mods & DVP_MOD_THIS_WORD) ? 0 : (shift / 32);
1570 if (operand->bits == 32)
1571 insn_buf[word] = val;
1572 else
1573 {
1574 shift = shift % 32;
1575 insn_buf[word] |= ((long) val & ((1 << operand->bits) - 1)) << shift;
1576 }
1577 }
1578 else
1579 {
1580 int word = (mods & DVP_MOD_THIS_WORD) ? 0 : operand->word;
1581 if (operand->bits == 32)
1582 insn_buf[word] = val;
1583 else
1584 {
1585 long temp = (long) val & ((1 << operand->bits) - 1);
1586 insn_buf[word] |= temp << operand->shift;
1587 }
1588 }
1589 }
1590 }
1591
1592 /* Insert an operand's final value into an instruction.
1593 Here we can give warning messages about operand values if we want to. */
1594
1595 static void
1596 insert_operand_final (cpu, operand, mods, insn_buf, val, file, line)
1597 dvp_cpu cpu;
1598 const dvp_operand *operand;
1599 int mods;
1600 DVP_INSN *insn_buf;
1601 offsetT val;
1602 char *file;
1603 unsigned int line;
1604 {
1605 if (operand->bits != 32)
1606 {
1607 offsetT min, max, test;
1608
1609 if ((operand->flags & DVP_OPERAND_RELATIVE_BRANCH) != 0)
1610 {
1611 if ((val & 7) != 0)
1612 {
1613 if (file == (char *) NULL)
1614 as_warn ("branch to misaligned address");
1615 else
1616 as_warn_where (file, line, "branch to misaligned address");
1617 }
1618 val >>= 3;
1619 }
1620
1621 if ((operand->flags & DVP_OPERAND_SIGNED) != 0)
1622 {
1623 if ((operand->flags & DVP_OPERAND_SIGNOPT) != 0)
1624 max = (1 << operand->bits) - 1;
1625 else
1626 max = (1 << (operand->bits - 1)) - 1;
1627 min = - (1 << (operand->bits - 1));
1628 }
1629 else
1630 {
1631 max = (1 << operand->bits) - 1;
1632 min = 0;
1633 }
1634
1635 if ((operand->flags & DVP_OPERAND_NEGATIVE) != 0)
1636 test = - val;
1637 else
1638 test = val;
1639
1640 if (test < (offsetT) min || test > (offsetT) max)
1641 {
1642 const char *err =
1643 "operand out of range (%s not between %ld and %ld)";
1644 char buf[100];
1645
1646 sprint_value (buf, test);
1647 if (file == (char *) NULL)
1648 as_warn (err, buf, min, max);
1649 else
1650 as_warn_where (file, line, err, buf, min, max);
1651 }
1652 }
1653
1654 {
1655 const char *errmsg = NULL;
1656 insert_operand (cpu, NULL, operand, mods, insn_buf, val, &errmsg);
1657 if (errmsg != NULL)
1658 as_warn_where (file, line, errmsg);
1659 }
1660 }
1661 \f
1662 /* DVP pseudo ops. */
1663
1664 static void
1665 s_dmadata (ignore)
1666 int ignore;
1667 {
1668 char *name, c;
1669
1670 dma_data_name = 0;
1671
1672 if (dma_data_state != 0)
1673 {
1674 as_bad ("DmaData blocks cannot be nested.");
1675 ignore_rest_of_line ();
1676 return;
1677 }
1678 dma_data_state = 1;
1679
1680 SKIP_WHITESPACE (); /* Leading whitespace is part of operand. */
1681 name = input_line_pointer;
1682
1683 if (!is_name_beginner (*name))
1684 {
1685 as_bad ("invalid identifier for \".DmaData\"");
1686 ignore_rest_of_line ();
1687 return;
1688 }
1689
1690 c = get_symbol_end ();
1691 line_label = colon (name); /* user-defined label */
1692 dma_data_name = S_GET_NAME (line_label);
1693 *input_line_pointer = c;
1694
1695 demand_empty_rest_of_line ();
1696 }
1697
1698 static void
1699 s_enddmadata (ignore)
1700 int ignore;
1701 {
1702 if (dma_data_state != 1)
1703 {
1704 as_warn (".EndDmaData encountered outside a DmaData block -- ignored.");
1705 ignore_rest_of_line ();
1706 dma_data_name = 0;
1707 }
1708 dma_data_state = 0;
1709 demand_empty_rest_of_line ();
1710
1711 /* "label" points to beginning of block.
1712 Create a name for the final label like _$<name>. */
1713 if (dma_data_name)
1714 {
1715 /* Fill the data out to a multiple of 16 bytes. */
1716 /* FIXME: Does the fill contents matter? */
1717 frag_align (4, 0, 0);
1718 create_colon_label (END_LABEL_PREFIX, dma_data_name);
1719 }
1720 }
1721
1722 static void
1723 s_dmapackvif (ignore)
1724 int ignore;
1725 {
1726 /* Syntax: .dmapackvif 0|1 */
1727 struct symbol *label; /* Points to symbol */
1728 char *name; /* points to name of symbol */
1729
1730 /* Leading whitespace is part of operand. */
1731 SKIP_WHITESPACE ();
1732 switch (*input_line_pointer++)
1733 {
1734 case '0':
1735 dma_pack_vif_p = 0;
1736 break;
1737 case '1':
1738 dma_pack_vif_p = 1;
1739 break;
1740 default:
1741 as_bad ("illegal argument to `.DmaPackPke'");
1742 }
1743 demand_empty_rest_of_line ();
1744 }
1745
1746 static void
1747 s_enddirect (ignore)
1748 int ignore;
1749 {
1750 int byte_len;
1751
1752 if (cur_asm_state != ASM_DIRECT)
1753 {
1754 as_bad ("`.enddirect' has no matching `direct' instruction");
1755 return;
1756 }
1757
1758 byte_len = cur_vif_insn_length ();
1759 if (cur_varlen_value != -1
1760 && cur_varlen_value * 16 != byte_len)
1761 as_warn ("length in `direct' instruction does not match length of data");
1762 if (output_vif)
1763 install_vif_length (cur_varlen_insn, byte_len);
1764
1765 cur_asm_state = ASM_INIT;
1766
1767 /* These needn't be reset, but to catch bugs they are. */
1768 cur_varlen_frag = NULL;
1769 cur_varlen_insn = NULL;
1770 cur_varlen_value = 0;
1771
1772 demand_empty_rest_of_line ();
1773 }
1774
1775 static void
1776 s_endgif (ignore)
1777 int ignore;
1778 {
1779 long count;
1780 int nloop = gif_nloop ();
1781
1782 if (cur_asm_state != ASM_GIF)
1783 {
1784 as_bad (".endgif doesn't follow a gif tag");
1785 return;
1786 }
1787 cur_asm_state = ASM_INIT;
1788
1789 if (gif_insn_type == GIF_PACKED)
1790 count = eval_expr (0, 0, "(. - %s) >> 4", gif_data_name);
1791 else
1792 count = eval_expr (0, 0, "(. - %s) >> 3", gif_data_name);
1793
1794 if (count < 0
1795 || fixup_count != 0)
1796 {
1797 as_bad ("bad data count");
1798 return;
1799 }
1800
1801 /* Validate nloop if specified. Otherwise write the computed value into
1802 the insn. */
1803 if (nloop != -1)
1804 {
1805 int ok_p;
1806
1807 switch (gif_insn_type)
1808 {
1809 case GIF_PACKED :
1810 case GIF_REGLIST :
1811 ok_p = count == nloop * gif_nregs ();
1812 break;
1813 case GIF_IMAGE :
1814 ok_p = count == nloop;
1815 break;
1816 }
1817 if (! ok_p)
1818 {
1819 as_bad ("nloop value does not match size of data");
1820 return;
1821 }
1822 }
1823 else
1824 {
1825 DVP_INSN insn = bfd_getl32 (gif_insn_frag + 12);
1826 char *file;
1827 unsigned int line;
1828 as_where (&file, &line);
1829 insert_operand_final (DVP_GIF, &gif_operands[gif_operand_nloop],
1830 DVP_MOD_THIS_WORD, &insn,
1831 (offsetT) nloop, file, line);
1832 bfd_putl32 ((bfd_vma) insn, gif_insn_frag + 12);
1833 }
1834
1835 gif_data_name = NULL;
1836 demand_empty_rest_of_line ();
1837 }
1838
1839 static void
1840 s_endmpg (ignore)
1841 int ignore;
1842 {
1843 int byte_len;
1844
1845 if (cur_asm_state != ASM_MPG)
1846 {
1847 as_bad ("`.endmpg' has no matching `mpg' instruction");
1848 return;
1849 }
1850
1851 byte_len = cur_vif_insn_length ();
1852 if (cur_varlen_value != -1
1853 && cur_varlen_value * 8 != byte_len)
1854 as_warn ("length in `mpg' instruction does not match length of data");
1855 if (output_vif)
1856 install_vif_length (cur_varlen_insn, byte_len);
1857
1858 cur_asm_state = ASM_INIT;
1859
1860 /* These needn't be reset, but to catch bugs they are. */
1861 cur_varlen_frag = NULL;
1862 cur_varlen_insn = NULL;
1863 cur_varlen_value = 0;
1864
1865 /* Update $.MpgLoc. */
1866 vif_set_mpgloc (vif_get_mpgloc () + byte_len);
1867
1868 demand_empty_rest_of_line ();
1869 }
1870
1871 static void
1872 s_endunpack (ignore)
1873 int ignore;
1874 {
1875 int byte_len;
1876
1877 if (cur_asm_state != ASM_UNPACK)
1878 {
1879 as_bad ("`.endunpack' has no matching `unpack' instruction");
1880 return;
1881 }
1882
1883 byte_len = cur_vif_insn_length ();
1884 #if 0 /* unpack doesn't support prespecifying a length */
1885 if (cur_varlen_value * 16 != bytelen)
1886 as_warn ("length in `direct' instruction does not match length of data");
1887 #endif
1888 if (output_vif)
1889 install_vif_length (cur_varlen_insn, byte_len);
1890
1891 cur_asm_state = ASM_INIT;
1892
1893 /* These needn't be reset, but to catch bugs they are. */
1894 cur_varlen_frag = NULL;
1895 cur_varlen_insn = NULL;
1896 cur_varlen_value = 0;
1897
1898 /* Update $.UnpackLoc. */
1899 vif_set_unpackloc (vif_get_unpackloc () + byte_len);
1900
1901 demand_empty_rest_of_line ();
1902 }
1903
1904 static void
1905 s_state (state)
1906 int state;
1907 {
1908 /* If in MPG state and the user requests to change to VU state,
1909 leave the state as MPG. This happens when we see an mpg followed
1910 by a .include that has .vu. */
1911 if (cur_asm_state == ASM_MPG && state == ASM_VU)
1912 return;
1913
1914 cur_asm_state = state;
1915
1916 demand_empty_rest_of_line ();
1917 }
This page took 0.074392 seconds and 4 git commands to generate.