* config/tc-dvp.c (assemble_vif): 0 is a valid length value (= max+1).
[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 /* Value of VIF `nop' instruction. */
39 #define VIFNOP 0
40
41 #define MIN(a,b) ((a) < (b) ? (a) : (b))
42
43 /* Compute DMA operand index number of OP. */
44 #define DMA_OPERAND_INDEX(op) ((op) - dma_operands)
45
46 /* Our local label prefix. */
47 #define LOCAL_LABEL_PREFIX ".L"
48 /* Label prefix for end markers used in autocounts. */
49 #define END_LABEL_PREFIX ".L.end."
50 /* Label to use for unique labels. */
51 #define UNIQUE_LABEL_PREFIX ".L.dvptmp."
52
53 static long parse_float PARAMS ((char **, const char **));
54 static symbolS * create_label PARAMS ((const char *, const char *));
55 static symbolS * create_colon_label PARAMS ((int, const char *, const char *));
56 static char * unique_name PARAMS ((const char *));
57 static int compute_nloop PARAMS ((gif_type, int, int));
58 static void check_nloop PARAMS ((gif_type, int, int, int,
59 char *, unsigned int));
60 static long eval_expr PARAMS ((int, int, const char *, ...));
61 static long parse_dma_addr_autocount ();
62 static void inline_dma_data PARAMS ((int, DVP_INSN *));
63 static void setup_dma_autocount PARAMS ((const char *, DVP_INSN *, int));
64
65 static void insert_operand
66 PARAMS ((dvp_cpu, const dvp_opcode *, const dvp_operand *, int,
67 DVP_INSN *, offsetT, const char **));
68 static void insert_operand_final
69 PARAMS ((dvp_cpu, const dvp_operand *, int,
70 DVP_INSN *, offsetT, char *, unsigned int));
71
72 static void insert_mpg_marker PARAMS ((unsigned long));
73 static void insert_unpack_marker PARAMS ((unsigned long));
74 static int insert_file PARAMS ((const char *,
75 void (*) PARAMS ((unsigned long)),
76 unsigned long, int));
77
78 static int vif_length_value PARAMS ((int, int, int, int));
79 static void install_vif_length PARAMS ((char *, int));
80
81 const char comment_chars[] = ";";
82 const char line_comment_chars[] = "#";
83 const char line_separator_chars[] = "!";
84 const char EXP_CHARS[] = "eE";
85 const char FLT_CHARS[] = "dD";
86 \f
87 /* Current assembler state.
88 Instructions like mpg and direct are followed by a restricted set of
89 instructions. In the case of a '*' length argument an end marker must
90 be provided. (e.g. mpg is followed by vu insns until a .EndMpg is
91 seen).
92
93 Allowed state transitions:
94 ASM_INIT -> ASM_MPG
95 ASM_DIRECT -> ASM_GIF
96 ASM_UNPACK
97 ASM_VU
98 */
99
100 typedef enum {
101 ASM_INIT, ASM_DIRECT, ASM_MPG, ASM_UNPACK, ASM_VU, ASM_GIF
102 } asm_state;
103
104 /* We need to maintain a stack of the current and previous status to handle
105 such things as "direct ...; gifpacked ... ; .endgif ; .enddirect". */
106 #define MAX_STATE_DEPTH 2
107 static asm_state asm_state_stack[MAX_STATE_DEPTH];
108 /* Current state's index in the stack. */
109 static int cur_state_index;
110 /* Macro to fetch the current state. */
111 #define CUR_ASM_STATE (asm_state_stack[cur_state_index])
112
113 /* Functions to push/pop the state stack. */
114 static void push_asm_state PARAMS ((asm_state));
115 static void pop_asm_state PARAMS ((int));
116 static void set_asm_state PARAMS ((asm_state));
117 \f
118 /* Current cpu (machine variant) type state.
119 We copy the mips16 way of recording what the current machine type is in
120 the code. A label is created whenever necessary and has an "other" value
121 the denotes the machine type. */
122 static dvp_cpu cur_cpu;
123 /* Record the current mach type. */
124 static void record_mach PARAMS ((dvp_cpu, int));
125 /* Force emission of mach type label at next insn.
126 This isn't static as TC_START_LABEL uses it. */
127 int force_mach_label PARAMS ((void));
128 /* Given a dvp_cpu value, return the STO_DVP value to use. */
129 static int cpu_sto PARAMS ((dvp_cpu, const char **));
130
131 /* Nonzero if inside .DmaData. */
132 static int dma_data_state = 0;
133 /* Label of .DmaData (internally generated for inline data). */
134 static const char *dma_data_name;
135
136 /* Variable length VIF insn support. */
137 /* Label at start of insn's data. */
138 static symbolS *vif_data_start;
139 /* Label at end of insn's data. */
140 static symbolS *vif_data_end;
141
142 /* Special symbol $.mpgloc. */
143 static symbolS *mpgloc_sym;
144 /* Special symbol $.unpackloc. */
145 static symbolS *unpackloc_sym;
146
147 /* GIF insn support. */
148 /* Type of insn. */
149 static int gif_insn_type;
150 /* Name of label of insn's data. */
151 static const char *gif_data_name;
152 /* Pointer to frag of insn. */
153 static fragS *gif_insn_frag;
154 /* Pointer to current gif insn in gif_insn_frag. */
155 static char *gif_insn_frag_loc;
156 /* The length value specified in the insn, or -1 if '*'. */
157 static int gif_user_value;
158
159 /* Count of vu insns seen since the last mpg.
160 Set to -1 to disable automatic mpg insertion. */
161 static int vu_count;
162
163 /* Non-zero if packing vif instructions in dma tags. */
164 static int dma_pack_vif_p;
165
166 /* Non-zero if dma insns are to be included in the output.
167 This is the default, but writing "if (! no_dma)" is klunky. */
168 static int output_dma = 1;
169 /* Non-zero if vif insns are to be included in the output. */
170 static int output_vif = 1;
171
172 /* Current opcode/operand for use by md_operand. */
173 static const dvp_opcode *cur_opcode;
174 static const dvp_operand *cur_operand;
175
176 /* Options for the `caller' argument to s_endmpg. */
177 typedef enum { ENDMPG_USER, ENDMPG_INTERNAL, ENDMPG_MIDDLE } endmpg_caller;
178 \f
179 const char *md_shortopts = "";
180
181 struct option md_longopts[] =
182 {
183 #define OPTION_NO_DMA (OPTION_MD_BASE + 1)
184 { "no-dma", no_argument, NULL, OPTION_NO_DMA },
185 #define OPTION_NO_DMA_VIF (OPTION_NO_DMA + 1)
186 { "no-dma-vif", no_argument, NULL, OPTION_NO_DMA_VIF },
187
188 {NULL, no_argument, NULL, 0}
189 };
190 size_t md_longopts_size = sizeof(md_longopts);
191
192 int
193 md_parse_option (c, arg)
194 int c;
195 char *arg;
196 {
197 switch (c)
198 {
199 case OPTION_NO_DMA :
200 output_dma = 0;
201 break;
202 case OPTION_NO_DMA_VIF :
203 output_dma = 0;
204 output_vif = 0;
205 break;
206 default :
207 return 0;
208 }
209 return 1;
210 }
211
212 void
213 md_show_usage (stream)
214 FILE *stream;
215 {
216 fprintf (stream, "\
217 DVP options:\n\
218 -no-dma do not include DMA instructions in the output\n\
219 -no-dma-vif do not include DMA or VIF instructions in the output\n\
220 ");
221 }
222
223 /* Set by md_assemble for use by dvp_fill_insn. */
224 static subsegT prev_subseg;
225 static segT prev_seg;
226
227 static void s_dmadata PARAMS ((int));
228 static void s_enddmadata PARAMS ((int));
229 static void s_dmapackvif PARAMS ((int));
230 static void s_enddirect PARAMS ((int));
231 static void s_endmpg PARAMS ((int));
232 static void s_endunpack PARAMS ((int));
233 static void s_endgif PARAMS ((int));
234 static void s_state PARAMS ((int));
235
236 /* The target specific pseudo-ops which we support. */
237 const pseudo_typeS md_pseudo_table[] =
238 {
239 { "word", cons, 4 },
240 { "quad", cons, 16 },
241 { "dmadata", s_dmadata, 0 },
242 { "dmapackvif", s_dmapackvif, 0 },
243 { "enddirect", s_enddirect, 0 },
244 { "enddmadata", s_enddmadata, 0 },
245 { "endmpg", s_endmpg, ENDMPG_USER },
246 { "endunpack", s_endunpack, 0 },
247 { "endgif", s_endgif, 0 },
248 { "vu", s_state, ASM_VU },
249 { NULL, NULL, 0 }
250 };
251 \f
252 void
253 md_begin ()
254 {
255 /* Initialize the opcode tables.
256 This involves computing the hash chains. */
257 dvp_opcode_init_tables (0);
258
259 /* Force a mach type label for the first insn. */
260 force_mach_label ();
261
262 /* Initialize the parsing state. */
263 cur_state_index = 0;
264 set_asm_state (ASM_INIT);
265
266 /* Pack vif insns in dma tags by default. */
267 dma_pack_vif_p = 1;
268
269 /* Disable automatic mpg insertion. */
270 vu_count = -1;
271
272 /* Create special symbols. */
273 mpgloc_sym = expr_build_uconstant (0);
274 unpackloc_sym = expr_build_uconstant (0);
275 }
276 \f
277 /* We need to keep a list of fixups. We can't simply generate them as
278 we go, because that would require us to first create the frag, and
279 that would screw up references to ``.''. */
280
281 struct dvp_fixup
282 {
283 /* index into `dvp_operands' */
284 int opindex;
285 /* byte offset from beginning of instruction */
286 int offset;
287 /* user specified value [when there is one] */
288 int user_value;
289 /* wl,cl values, only used with unpack insn */
290 short wl,cl;
291 /* the expression */
292 expressionS exp;
293 };
294
295 #define MAX_FIXUPS 5
296
297 static int fixup_count;
298 static struct dvp_fixup fixups[MAX_FIXUPS];
299
300 /* Given a cpu type and operand number, return a temporary reloc type
301 for use in generating the fixup that encodes the cpu type and operand. */
302 static int encode_fixup_reloc_type PARAMS ((dvp_cpu, int));
303 /* Given an encoded fixup reloc type, decode it into cpu and operand. */
304 static void decode_fixup_reloc_type PARAMS ((int, dvp_cpu *,
305 const dvp_operand **));
306
307 static void assemble_dma PARAMS ((char *));
308 static void assemble_gif PARAMS ((char *));
309 static void assemble_vif PARAMS ((char *));
310 static void assemble_vu PARAMS ((char *));
311 static const dvp_opcode * assemble_vu_insn PARAMS ((dvp_cpu,
312 const dvp_opcode *,
313 const dvp_operand *,
314 char **, char *));
315 static const dvp_opcode * assemble_one_insn PARAMS ((dvp_cpu,
316 const dvp_opcode *,
317 const dvp_operand *,
318 char **, DVP_INSN *));
319
320 /* Main entry point for assembling an instruction. */
321
322 void
323 md_assemble (str)
324 char *str;
325 {
326 /* Skip leading white space. */
327 while (isspace (*str))
328 str++;
329
330 /* After a gif tag, no insns can appear until a .endgif is seen. */
331 if (CUR_ASM_STATE == ASM_GIF)
332 {
333 as_bad ("missing .endgif");
334 pop_asm_state (1);
335 }
336 /* Ditto for unpack. */
337 if (CUR_ASM_STATE == ASM_UNPACK)
338 {
339 as_bad ("missing .endunpack");
340 pop_asm_state (1);
341 }
342 #if 0 /* this doesn't work of course as gif insns may follow */
343 /* Ditto for direct. */
344 if (CUR_ASM_STATE == ASM_DIRECT)
345 {
346 as_bad ("missing .enddirect");
347 pop_asm_state (1);
348 }
349 #endif
350
351 if (CUR_ASM_STATE == ASM_INIT)
352 {
353 if (strncasecmp (str, "dma", 3) == 0)
354 assemble_dma (str);
355 else if (strncasecmp (str, "gif", 3) == 0)
356 assemble_gif (str);
357 else
358 assemble_vif (str);
359 }
360 else if (CUR_ASM_STATE == ASM_DIRECT)
361 assemble_gif (str);
362 else if (CUR_ASM_STATE == ASM_VU
363 || CUR_ASM_STATE == ASM_MPG)
364 assemble_vu (str);
365 else
366 as_fatal ("internal error: unknown parse state");
367 }
368
369 /* Subroutine of md_assemble to assemble DMA instructions. */
370
371 static void
372 assemble_dma (str)
373 char *str;
374 {
375 DVP_INSN insn_buf[2];
376 /* Insn's length, in 32 bit words. */
377 int len;
378 /* Pointer to allocated frag. */
379 char *f;
380 int i;
381 const dvp_opcode *opcode;
382
383 if (output_dma)
384 {
385 /* Do an implicit alignment to a 16 byte boundary.
386 Do it now so that inline dma data labels are at the right place. */
387 /* ??? One can certainly argue all this implicit alignment is
388 questionable. The thing is assembler programming is all that will
389 mostly likely ever be done and not doing so forces an extra [and
390 arguably unnecessary] burden on the programmer. */
391 frag_align (4, 0, 0);
392 record_alignment (now_seg, 4);
393 }
394
395 /* This is the DMA tag. */
396 insn_buf[0] = 0;
397 insn_buf[1] = 0;
398
399 opcode = assemble_one_insn (DVP_DMA,
400 dma_opcode_lookup_asm (str), dma_operands,
401 &str, insn_buf);
402 if (opcode == NULL)
403 return;
404 if (!output_dma)
405 return;
406
407 record_mach (DVP_DMA, 0);
408
409 f = frag_more (8);
410
411 /* Write out the DMA instruction. */
412 for (i = 0; i < 2; ++i)
413 md_number_to_chars (f + i * 4, insn_buf[i], 4);
414
415 /* Create any fixups. */
416 /* FIXME: It might eventually be possible to combine all the various
417 copies of this bit of code. */
418 for (i = 0; i < fixup_count; ++i)
419 {
420 int op_type, reloc_type, offset;
421 const dvp_operand *operand;
422
423 /* Create a fixup for this operand.
424 At this point we do not use a bfd_reloc_code_real_type for
425 operands residing in the insn, but instead just use the
426 operand index. This lets us easily handle fixups for any
427 operand type, although that is admittedly not a very exciting
428 feature. We pick a BFD reloc type in md_apply_fix. */
429
430 op_type = fixups[i].opindex;
431 offset = fixups[i].offset;
432 reloc_type = encode_fixup_reloc_type (DVP_DMA, op_type);
433 operand = &dma_operands[op_type];
434 fix_new_exp (frag_now, f + offset - frag_now->fr_literal, 4,
435 &fixups[i].exp,
436 (operand->flags & DVP_OPERAND_RELATIVE_BRANCH) != 0,
437 (bfd_reloc_code_real_type) reloc_type);
438 }
439
440 /* The upper two words are vif insns. */
441 record_mach (DVP_VIF, 0);
442
443 /* If not doing dma/vif packing, fill out the insn with vif nops.
444 ??? We take advantage of the fact that the default fill value of zero
445 is the vifnop insn. This occurs for example when handling mpg
446 alignment. It also occurs when one dma tag immediately follows the
447 previous one. */
448 if (! dma_pack_vif_p)
449 {
450 f = frag_more (8);
451 md_number_to_chars (f + 0, VIFNOP, 4);
452 md_number_to_chars (f + 4, VIFNOP, 4);
453 }
454 }
455
456 /* Subroutine of md_assemble to assemble VIF instructions. */
457
458 static void
459 assemble_vif (str)
460 char *str;
461 {
462 /* Space for the instruction.
463 The variable length insns can require much more space than this.
464 It is allocated later, when we know we have such an insn. */
465 DVP_INSN insn_buf[5];
466 /* Insn's length, in 32 bit words. */
467 int len;
468 /* Pointer to allocated frag. */
469 char *f;
470 int i,wl,cl;
471 const dvp_opcode *opcode;
472 fragS * insn_frag;
473 /* Name of file to read data from. */
474 const char *file;
475 /* Length in 32 bit words. */
476 int data_len;
477 /* Macro expansion, if there is one. */
478 char * macstr;
479
480 /* First check for macros. */
481 macstr = dvp_expand_macro (vif_macros, vif_macro_count, str);
482 if (macstr)
483 {
484 /* The macro may expand into several insns (delimited with '\n'),
485 so loop. */
486 char * next = macstr;
487 do
488 {
489 char *p = strchr (next, '\n');
490 if (p)
491 *p = 0;
492 assemble_vif (next);
493 next = p ? p + 1 : 0;
494 }
495 while (next);
496 free (macstr);
497 return;
498 }
499
500 opcode = assemble_one_insn (DVP_VIF,
501 vif_opcode_lookup_asm (str), vif_operands,
502 &str, insn_buf);
503 if (opcode == NULL)
504 return;
505
506 if (opcode->flags & VIF_OPCODE_LENVAR)
507 len = 1; /* actual data follows later */
508 else if (opcode->flags & VIF_OPCODE_LEN2)
509 len = 2;
510 else if (opcode->flags & VIF_OPCODE_LEN5)
511 len = 5;
512 else
513 len = 1;
514
515 /* We still have to switch modes (if mpg for example) so we can't exit
516 early if -no-vif. */
517
518 if (output_vif)
519 {
520 /* Record the mach before doing the alignment so that we properly
521 disassemble any inserted vifnop's. For mpg and direct insns
522 force the recording of the mach type for the next insn. The data
523 will switch the mach type and we want to ensure it's switched
524 back. */
525
526 if (opcode->flags & (VIF_OPCODE_MPG | VIF_OPCODE_DIRECT))
527 record_mach (DVP_VIF, 1);
528 else
529 record_mach (DVP_VIF, 0);
530
531 /* For variable length instructions record a fixup that is the symbol
532 marking the end of the data. eval_expr will queue the fixup
533 which will then be emitted later. */
534 if (opcode->flags & VIF_OPCODE_LENVAR)
535 {
536 char *name;
537
538 asprintf (&name, "%s%s", LOCAL_LABEL_PREFIX,
539 unique_name ("varlen"));
540 vif_data_end = symbol_new (name, now_seg, 0, 0);
541 symbol_table_insert (vif_data_end);
542 fixups[fixup_count].exp.X_op = O_symbol;
543 fixups[fixup_count].exp.X_add_symbol = vif_data_end;
544 fixups[fixup_count].exp.X_add_number = 0;
545 fixups[fixup_count].opindex = vif_operand_datalen_special;
546 fixups[fixup_count].offset = 0;
547
548 /* See what the user specified. */
549 vif_get_var_data (&file, &data_len);
550 if (file)
551 data_len = -1;
552 fixups[fixup_count].user_value = data_len;
553 /* Get the wl,cl values. Only useful for the unpack insn but
554 it doesn't hurt to always record them. */
555 vif_get_wl_cl (&wl, &cl);
556 fixups[fixup_count].wl = wl;
557 fixups[fixup_count].cl = cl;
558 ++fixup_count;
559 }
560
561 /* Obtain space in which to store the instruction. */
562
563 if (opcode->flags & VIF_OPCODE_MPG)
564 {
565 /* The data must be aligned on a 64 bit boundary (so the mpg insn
566 comes just before that 64 bit boundary).
567 Do this by putting the mpg insn in a relaxable fragment
568 with a symbol that marks the beginning of the aligned data. */
569
570 /* Ensure relaxable fragments are in their own fragment.
571 Otherwise md_apply_fix3 mishandles fixups to insns earlier
572 in the fragment (because we set fr_opcode for the `mpg' insn
573 because it can move in the fragment). */
574 frag_wane (frag_now);
575 frag_new (0);
576
577 /* This dance with frag_grow is to ensure the variable part and
578 fixed part are in the same fragment. */
579 frag_grow (8);
580 /* Allocate space for the fixed part. */
581 f = frag_more (4);
582 insn_frag = frag_now;
583
584 frag_var (rs_machine_dependent,
585 4, /* max chars */
586 0, /* variable part already allocated */
587 1, /* subtype */
588 NULL, /* no symbol */
589 0, /* offset */
590 f); /* opcode */
591
592 frag_align (3, 0, 0);
593 record_alignment (now_seg, 3);
594
595 /* Put a symbol at the start of data. The relaxation code uses
596 this to figure out how many bytes to insert. $.mpgloc
597 calculations also use it. */
598 vif_data_start = create_colon_label (STO_DVP_VU, LOCAL_LABEL_PREFIX,
599 unique_name ("mpg"));
600 insn_frag->fr_symbol = vif_data_start;
601
602 /* Get the value of mpgloc. If it wasn't '*' update $.mpgloc. */
603 {
604 int mpgloc = vif_get_mpgloc ();
605 if (mpgloc != -1)
606 {
607 mpgloc_sym->sy_value.X_op = O_constant;
608 mpgloc_sym->sy_value.X_add_number = mpgloc;
609 mpgloc_sym->sy_value.X_unsigned = 1;
610 }
611 }
612 }
613 else if (opcode->flags & VIF_OPCODE_DIRECT)
614 {
615 /* The data must be aligned on a 128 bit boundary (so the direct insn
616 comes just before that 128 bit boundary).
617 Do this by putting the direct insn in a relaxable fragment.
618 with a symbol that marks the beginning of the aligned data. */
619
620 /* Ensure relaxable fragments are in their own fragment.
621 Otherwise md_apply_fix3 mishandles fixups to insns earlier
622 in the fragment (because we set fr_opcode for the `direct' insn
623 because it can move in the fragment). */
624 frag_wane (frag_now);
625 frag_new (0);
626
627 /* This dance with frag_grow is to ensure the variable part and
628 fixed part are in the same fragment. */
629 frag_grow (16);
630 /* Allocate space for the fixed part. */
631 f = frag_more (4);
632 insn_frag = frag_now;
633
634 frag_var (rs_machine_dependent,
635 12, /* max chars */
636 0, /* variable part already allocated */
637 2, /* subtype */
638 NULL, /* no symbol */
639 0, /* offset */
640 f); /* opcode */
641
642 frag_align (4, 0, 0);
643 record_alignment (now_seg, 4);
644
645 /* Put a symbol at the start of data. The relaxation code uses
646 this to figure out how many bytes to insert. */
647 vif_data_start = create_colon_label (0, LOCAL_LABEL_PREFIX,
648 unique_name ("direct"));
649 insn_frag->fr_symbol = vif_data_start;
650 }
651 else if (opcode->flags & VIF_OPCODE_UNPACK)
652 {
653 f = frag_more (len * 4);
654 insn_frag = frag_now;
655 /* Put a symbol at the start of data. $.unpackloc calculations
656 use it. */
657 vif_data_start = create_colon_label (STO_DVP_VIF, LOCAL_LABEL_PREFIX,
658 unique_name ("unpack"));
659
660 /* Get the value of unpackloc. If it wasn't '*' update
661 $.unpackloc. */
662 {
663 int unpackloc = vif_get_unpackloc ();
664 if (unpackloc != -1)
665 {
666 unpackloc_sym->sy_value.X_op = O_constant;
667 unpackloc_sym->sy_value.X_add_number = unpackloc;
668 unpackloc_sym->sy_value.X_unsigned = 1;
669 }
670 }
671 }
672 else
673 {
674 /* Reminder: it is important to fetch enough space in one call to
675 `frag_more'. We use (f - frag_now->fr_literal) to compute where
676 we are and we don't want frag_now to change between calls. */
677 f = frag_more (len * 4);
678 insn_frag = frag_now;
679 }
680
681 /* Write out the instruction. */
682 for (i = 0; i < len; ++i)
683 md_number_to_chars (f + i * 4, insn_buf[i], 4);
684
685 /* Create any fixups. */
686 /* FIXME: It might eventually be possible to combine all the various
687 copies of this bit of code. */
688 for (i = 0; i < fixup_count; ++i)
689 {
690 int op_type, reloc_type, offset;
691 const dvp_operand *operand;
692 fixS *fixP;
693
694 /* Create a fixup for this operand.
695 At this point we do not use a bfd_reloc_code_real_type for
696 operands residing in the insn, but instead just use the
697 operand index. This lets us easily handle fixups for any
698 operand type, although that is admittedly not a very exciting
699 feature. We pick a BFD reloc type in md_apply_fix. */
700
701 op_type = fixups[i].opindex;
702 offset = fixups[i].offset;
703 reloc_type = encode_fixup_reloc_type (DVP_VIF, op_type);
704 operand = &vif_operands[op_type];
705 fixP = fix_new_exp (insn_frag, f + offset - insn_frag->fr_literal, 4,
706 &fixups[i].exp,
707 (operand->flags & DVP_OPERAND_RELATIVE_BRANCH) != 0,
708 (bfd_reloc_code_real_type) reloc_type);
709 fixP->tc_fix_data.user_value = fixups[i].user_value;
710 fixP->tc_fix_data.wl = fixups[i].wl;
711 fixP->tc_fix_data.cl = fixups[i].cl;
712
713 /* Set fx_tcbit so other parts of the code know this fixup is for
714 a vif insn. */
715 fixP->fx_tcbit = 1;
716 }
717 }
718
719 /* Handle variable length insns. */
720
721 if (opcode->flags & VIF_OPCODE_LENVAR)
722 {
723 /* See what the user specified. */
724 vif_get_var_data (&file, &data_len);
725
726 if (file)
727 {
728 int byte_len;
729
730 /* The handling for each of mpg,direct,unpack is basically the same:
731 - emit a label to set the mach type for the data we're inserting
732 - switch to the new assembler state
733 - insert the file
734 - call the `end' handler */
735
736 if (opcode->flags & VIF_OPCODE_MPG)
737 {
738 record_mach (DVP_VUUP, 1);
739 set_asm_state (ASM_MPG);
740 byte_len = insert_file (file, insert_mpg_marker, 0, 256 * 8);
741 s_endmpg (ENDMPG_INTERNAL);
742 }
743 else if (opcode->flags & VIF_OPCODE_DIRECT)
744 {
745 record_mach (DVP_GIF, 1);
746 set_asm_state (ASM_DIRECT);
747 byte_len = insert_file (file, NULL, 0, 0);
748 s_enddirect (1);
749 }
750 else if (opcode->flags & VIF_OPCODE_UNPACK)
751 {
752 int max_len = 0; /*unpack_max_byte_len (insn_buf[0]);*/
753 set_asm_state (ASM_UNPACK);
754 byte_len = insert_file (file, NULL /*insert_unpack_marker*/,
755 insn_buf[0], max_len);
756 s_endunpack (1);
757 }
758 else
759 as_fatal ("internal error: unknown cpu type for variable length vif insn");
760 }
761 else /* file == NULL */
762 {
763 /* data_len == -1 means the value must be computed from
764 the data. */
765 if (data_len <= -2)
766 as_bad ("invalid data length");
767
768 if (output_vif && data_len != -1)
769 install_vif_length (f, data_len);
770
771 if (opcode->flags & VIF_OPCODE_MPG)
772 {
773 set_asm_state (ASM_MPG);
774 /* Enable automatic mpg insertion every 256 insns. */
775 vu_count = 0;
776 }
777 else if (opcode->flags & VIF_OPCODE_DIRECT)
778 set_asm_state (ASM_DIRECT);
779 else if (opcode->flags & VIF_OPCODE_UNPACK)
780 set_asm_state (ASM_UNPACK);
781 }
782 }
783 }
784
785 /* Subroutine of md_assemble to assemble GIF instructions. */
786
787 static void
788 assemble_gif (str)
789 char *str;
790 {
791 DVP_INSN insn_buf[4];
792 const dvp_opcode *opcode;
793 char *f;
794 int i;
795
796 insn_buf[0] = insn_buf[1] = insn_buf[2] = insn_buf[3] = 0;
797
798 opcode = assemble_one_insn (DVP_GIF,
799 gif_opcode_lookup_asm (str), gif_operands,
800 &str, insn_buf);
801 if (opcode == NULL)
802 return;
803
804 /* Do an implicit alignment to a 16 byte boundary. */
805 frag_align (4, 0, 0);
806 record_alignment (now_seg, 4);
807
808 /* Insert a label so we can compute the number of quadwords when the
809 .endgif is seen. This is put before the mach type label because gif
810 insns are followed by data and we don't want the disassembler to try
811 to disassemble them as mips insns (since it uses the st_other field)
812 of the closest label to choose the mach type and since we don't have
813 a special st_other value for "data". */
814 gif_data_name = S_GET_NAME (create_colon_label (0, LOCAL_LABEL_PREFIX,
815 unique_name ("gifdata")));
816
817 record_mach (DVP_GIF, 1);
818
819 gif_insn_frag_loc = f = frag_more (16);
820 gif_insn_frag = frag_now;
821 for (i = 0; i < 4; ++i)
822 md_number_to_chars (f + i * 4, insn_buf[i], 4);
823
824 /* Record the type of the gif tag so we know how to compute nloop
825 in s_endgif. */
826 if (strcmp (opcode->mnemonic, "gifpacked") == 0)
827 gif_insn_type = GIF_PACKED;
828 else if (strcmp (opcode->mnemonic, "gifreglist") == 0)
829 gif_insn_type = GIF_REGLIST;
830 else if (strcmp (opcode->mnemonic, "gifimage") == 0)
831 gif_insn_type = GIF_IMAGE;
832 else
833 abort ();
834 push_asm_state (ASM_GIF);
835 }
836
837 /* Subroutine of md_assemble to assemble VU instructions. */
838
839 static void
840 assemble_vu (str)
841 char *str;
842 {
843 char *f;
844 const dvp_opcode *opcode;
845
846 /* Handle automatic mpg insertion if enabled. */
847 if (CUR_ASM_STATE == ASM_MPG
848 && vu_count == 256)
849 insert_mpg_marker (0);
850
851 /* Do an implicit alignment to a 8 byte boundary. */
852 frag_align (3, 0, 0);
853 record_alignment (now_seg, 3);
854
855 record_mach (DVP_VUUP, 0);
856
857 /* The lower instruction has the lower address.
858 Handle this by grabbing 8 bytes now, and then filling each word
859 as appropriate. */
860 f = frag_more (8);
861
862 #ifdef VERTICAL_BAR_SEPARATOR
863 char *p = strchr (str, '|');
864
865 if (p == NULL)
866 {
867 as_bad ("lower slot missing in `%s'", str);
868 return;
869 }
870
871 *p = 0;
872 opcode = assemble_vu_insn (DVP_VUUP,
873 vu_upper_opcode_lookup_asm (str), vu_operands,
874 &str, f + 4);
875 *p = '|';
876 str = p + 1;
877 #else
878 opcode = assemble_vu_insn (DVP_VUUP,
879 vu_upper_opcode_lookup_asm (str), vu_operands,
880 &str, f + 4);
881 #endif
882
883 /* Don't assemble next one if we couldn't assemble the first. */
884 if (opcode == NULL)
885 return;
886 opcode = assemble_vu_insn (DVP_VULO,
887 vu_lower_opcode_lookup_asm (str), vu_operands,
888 &str, f);
889 /* If this was the "loi" pseudo-insn, we need to set the `i' bit. */
890 if (opcode != NULL)
891 {
892 if (strcmp (opcode->mnemonic, "loi") == 0)
893 f[7] |= 0x80;
894 }
895
896 /* Increment the vu insn counter.
897 If get reach 256 we need to insert an `mpg'. */
898 ++vu_count;
899 }
900
901 static const dvp_opcode *
902 assemble_vu_insn (cpu, opcode, operand_table, pstr, buf)
903 dvp_cpu cpu;
904 const dvp_opcode *opcode;
905 const dvp_operand *operand_table;
906 char **pstr;
907 char *buf;
908 {
909 int i;
910 DVP_INSN insn;
911
912 opcode = assemble_one_insn (cpu, opcode, operand_table, pstr, &insn);
913 if (opcode == NULL)
914 return NULL;
915
916 /* Write out the instruction.
917 Reminder: it is important to fetch enough space in one call to
918 `frag_more'. We use (f - frag_now->fr_literal) to compute where
919 we are and we don't want frag_now to change between calls. */
920 md_number_to_chars (buf, insn, 4);
921
922 /* Create any fixups. */
923 for (i = 0; i < fixup_count; ++i)
924 {
925 int op_type, reloc_type;
926 const dvp_operand *operand;
927
928 /* Create a fixup for this operand.
929 At this point we do not use a bfd_reloc_code_real_type for
930 operands residing in the insn, but instead just use the
931 operand index. This lets us easily handle fixups for any
932 operand type, although that is admittedly not a very exciting
933 feature. We pick a BFD reloc type in md_apply_fix. */
934
935 op_type = fixups[i].opindex;
936 reloc_type = encode_fixup_reloc_type (cpu, op_type);
937 operand = &vu_operands[op_type];
938 fix_new_exp (frag_now, buf - frag_now->fr_literal, 4,
939 &fixups[i].exp,
940 (operand->flags & DVP_OPERAND_RELATIVE_BRANCH) != 0,
941 (bfd_reloc_code_real_type) reloc_type);
942 }
943
944 /* All done. */
945 return opcode;
946 }
947
948 /* Assemble one instruction at *PSTR.
949 CPU indicates what component we're assembling for.
950 The assembled instruction is stored in INSN_BUF.
951 OPCODE is a pointer to the head of the hash chain.
952
953 *PSTR is updated to point passed the parsed instruction.
954
955 If the insn is successfully parsed the result is a pointer to the opcode
956 entry that successfully matched and *PSTR is updated to point passed
957 the parsed insn. If an error occurs the result is NULL and *PSTR is left
958 at some random point in the string (??? may wish to leave it pointing where
959 the error occured). */
960
961 static const dvp_opcode *
962 assemble_one_insn (cpu, opcode, operand_table, pstr, insn_buf)
963 dvp_cpu cpu;
964 const dvp_opcode *opcode;
965 const dvp_operand *operand_table;
966 char **pstr;
967 DVP_INSN *insn_buf;
968 {
969 char *start, *str;
970
971 /* Keep looking until we find a match. */
972
973 start = str = *pstr;
974 for ( ; opcode != NULL; opcode = DVP_OPCODE_NEXT_ASM (opcode))
975 {
976 int past_opcode_p, num_suffixes;
977 const unsigned char *syn;
978
979 /* Ensure the mnemonic part matches. */
980 for (str = start, syn = opcode->mnemonic; *syn != '\0'; ++str, ++syn)
981 if (tolower (*str) != tolower (*syn))
982 break;
983 if (*syn != '\0')
984 continue;
985
986 /* Scan the syntax string. If it doesn't match, try the next one. */
987
988 dvp_opcode_init_parse ();
989 insn_buf[opcode->opcode_word] = opcode->value;
990 fixup_count = 0;
991 past_opcode_p = 0;
992 num_suffixes = 0;
993
994 /* We don't check for (*str != '\0') here because we want to parse
995 any trailing fake arguments in the syntax string. */
996 for (/*str = start, */ syn = opcode->syntax; *syn != '\0'; )
997 {
998 int mods,index;
999 const dvp_operand *operand;
1000 const char *errmsg;
1001 long value;
1002
1003 /* Non operand chars must match exactly.
1004 Operand chars that are letters are not part of symbols
1005 and are case insensitive. */
1006 if (*syn < 128)
1007 {
1008 if (tolower (*str) == tolower (*syn))
1009 {
1010 if (*syn == ' ')
1011 past_opcode_p = 1;
1012 ++syn;
1013 ++str;
1014 }
1015 else
1016 break;
1017 continue;
1018 }
1019
1020 /* We have a suffix or an operand. Pick out any modifiers. */
1021 mods = 0;
1022 index = DVP_OPERAND_INDEX (*syn);
1023 while (DVP_MOD_P (operand_table[index].flags))
1024 {
1025 mods |= operand_table[index].flags & DVP_MOD_BITS;
1026 ++syn;
1027 index = DVP_OPERAND_INDEX (*syn);
1028 }
1029 operand = operand_table + index;
1030
1031 if (operand->flags & DVP_OPERAND_FAKE)
1032 {
1033 long value = 0;
1034
1035 if (operand->flags & DVP_OPERAND_DMA_INLINE)
1036 {
1037 inline_dma_data ((mods & DVP_OPERAND_AUTOCOUNT) != 0,
1038 insn_buf);
1039 ++syn;
1040 continue;
1041 }
1042
1043 if (operand->parse)
1044 {
1045 errmsg = NULL;
1046 value = (*operand->parse) (opcode, operand, mods,
1047 &str, &errmsg);
1048 if (errmsg)
1049 break;
1050 }
1051 if (operand->insert)
1052 {
1053 errmsg = NULL;
1054 (*operand->insert) (opcode, operand, mods, insn_buf,
1055 (offsetT) value, &errmsg);
1056 /* If we get an error, go on to try the next insn. */
1057 if (errmsg)
1058 break;
1059 }
1060 ++syn;
1061 continue;
1062 }
1063
1064 /* Are we finished with suffixes? */
1065 if (!past_opcode_p)
1066 {
1067 long suf_value;
1068
1069 if (!(operand->flags & DVP_OPERAND_SUFFIX))
1070 as_fatal ("internal error: bad opcode table, missing suffix flag");
1071
1072 /* If we're at a space in the input string, we want to skip the
1073 remaining suffixes. There may be some fake ones though, so
1074 just go on to try the next one. */
1075 if (*str == ' ')
1076 {
1077 ++syn;
1078 continue;
1079 }
1080
1081 /* Parse the suffix. */
1082 errmsg = NULL;
1083 suf_value = (*operand->parse) (opcode, operand, mods, &str,
1084 &errmsg);
1085 if (errmsg)
1086 {
1087 /* This can happen, for example, in ARC's in "blle foo" and
1088 we're currently using the template "b%q%.n %j". The "bl"
1089 insn occurs later in the table so "lle" isn't an illegal
1090 suffix. */
1091 break;
1092 }
1093
1094 /* Insert the suffix's value into the insn. */
1095 insert_operand (cpu, opcode, operand, mods, insn_buf,
1096 (offsetT) suf_value, &errmsg);
1097
1098 ++syn;
1099 continue;
1100 }
1101
1102 /* This is an operand, either a register or an expression of
1103 some kind. */
1104
1105 value = 0;
1106
1107 if (operand->flags & DVP_OPERAND_SUFFIX)
1108 as_fatal ("internal error: bad opcode table, suffix wrong");
1109
1110 /* Is there anything left to parse?
1111 We don't check for this at the top because we want to parse
1112 any trailing fake arguments in the syntax string. */
1113 /* ??? This doesn't allow operands with a legal value of "". */
1114 if (*str == '\0')
1115 break;
1116
1117 /* Parse the operand. */
1118 if (operand->flags & DVP_OPERAND_FLOAT)
1119 {
1120 errmsg = 0;
1121 value = parse_float (&str, &errmsg);
1122 if (errmsg)
1123 break;
1124 }
1125 else if ((operand->flags & DVP_OPERAND_DMA_ADDR)
1126 && (mods & DVP_OPERAND_AUTOCOUNT))
1127 {
1128 errmsg = 0;
1129 value = parse_dma_addr_autocount (opcode, operand, mods,
1130 insn_buf, &str, &errmsg);
1131 if (errmsg)
1132 break;
1133 }
1134 else
1135 {
1136 char *origstr,*hold;
1137 expressionS exp;
1138
1139 /* First see if there is a special parser. */
1140 origstr = str;
1141 if (operand->parse)
1142 {
1143 errmsg = NULL;
1144 value = (*operand->parse) (opcode, operand, mods,
1145 &str, &errmsg);
1146 if (errmsg)
1147 break;
1148 }
1149
1150 /* If there wasn't a special parser, or there was and it
1151 left the input stream unchanged, use the general
1152 expression parser. */
1153 if (str == origstr)
1154 {
1155 hold = input_line_pointer;
1156 input_line_pointer = str;
1157 /* Set cur_{opcode,operand} for md_operand. */
1158 cur_opcode = opcode;
1159 cur_operand = operand;
1160 expression (&exp);
1161 cur_opcode = NULL;
1162 str = input_line_pointer;
1163 input_line_pointer = hold;
1164
1165 if (exp.X_op == O_illegal
1166 || exp.X_op == O_absent)
1167 break;
1168 else if (exp.X_op == O_constant)
1169 value = exp.X_add_number;
1170 else if (exp.X_op == O_register)
1171 as_fatal ("internal error: got O_register");
1172 else
1173 {
1174 /* We need to generate a fixup for this expression. */
1175 if (fixup_count >= MAX_FIXUPS)
1176 as_fatal ("internal error: too many fixups");
1177 fixups[fixup_count].exp = exp;
1178 fixups[fixup_count].opindex = index;
1179 /* FIXME: Revisit. Do we really need operand->word?
1180 The endianness of a 128 bit DMAtag is rather
1181 twisted. How about defining word 0 as the word with
1182 the lowest address and basing operand-shift off that.
1183 operand->word could then be deleted. */
1184 if (operand->word != 0)
1185 fixups[fixup_count].offset = operand->word * 4;
1186 else
1187 fixups[fixup_count].offset = (operand->shift / 32) * 4;
1188 ++fixup_count;
1189 value = 0;
1190 }
1191 }
1192 }
1193
1194 /* Insert the register or expression into the instruction. */
1195 errmsg = NULL;
1196 insert_operand (cpu, opcode, operand, mods, insn_buf,
1197 (offsetT) value, &errmsg);
1198 if (errmsg != (const char *) NULL)
1199 break;
1200
1201 ++syn;
1202 }
1203
1204 /* If we're at the end of the syntax string, we're done. */
1205 if (*syn == '\0')
1206 {
1207 int i;
1208
1209 /* For the moment we assume a valid `str' can only contain blanks
1210 now. IE: We needn't try again with a longer version of the
1211 insn and it is assumed that longer versions of insns appear
1212 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
1213
1214 while (isspace (*str))
1215 ++str;
1216
1217 if (*str != '\0'
1218 #ifndef VERTICAL_BAR_SEPARATOR
1219 && cpu != DVP_VUUP
1220 #endif
1221 )
1222 as_bad ("junk at end of line: `%s'", str);
1223
1224 /* It's now up to the caller to emit the instruction and any
1225 relocations. */
1226 *pstr = str;
1227 return opcode;
1228 }
1229
1230 /* Try the next entry. */
1231 }
1232
1233 as_bad ("bad instruction `%s'", start);
1234 return 0;
1235 }
1236 \f
1237 /* Given a dvp cpu type, return it's STO_DVP value.
1238 The label prefix to use is stored in *PNAME. */
1239
1240 static int
1241 cpu_sto (cpu, pname)
1242 dvp_cpu cpu;
1243 const char **pname;
1244 {
1245 switch (cpu)
1246 {
1247 case DVP_DMA : *pname = ".dma."; return STO_DVP_DMA;
1248 case DVP_VIF : *pname = ".vif."; return STO_DVP_VIF;
1249 case DVP_GIF : *pname = ".gif."; return STO_DVP_GIF;
1250 case DVP_VUUP : *pname = ".vu."; return STO_DVP_VU;
1251 }
1252 abort ();
1253 }
1254
1255 /* Record the current mach type in the object file.
1256 If FORCE_NEXT_P is non-zero, force a label to be emitted the next time
1257 we're called. This is useful for variable length instructions that can
1258 have labels embedded within them. */
1259
1260 static void
1261 record_mach (cpu, force_next_p)
1262 dvp_cpu cpu;
1263 int force_next_p;
1264 {
1265 symbolS *label;
1266 const char *name;
1267 int sto;
1268
1269 if (cpu == cur_cpu)
1270 return;
1271
1272 sto = cpu_sto (cpu, &name);
1273
1274 label = create_colon_label (sto, "", unique_name (name));
1275
1276 if (force_next_p)
1277 cur_cpu = DVP_UNKNOWN;
1278 else
1279 cur_cpu = cpu;
1280 }
1281
1282 /* Force emission of mach type label at next insn.
1283 This isn't static as TC_START_LABEL uses it.
1284 The result is the value of TC_START_LABEL. */
1285
1286 int
1287 force_mach_label ()
1288 {
1289 cur_cpu = DVP_UNKNOWN;
1290 return 1;
1291 }
1292
1293 /* Push/pop the current parsing state. */
1294
1295 static void
1296 push_asm_state (new_state)
1297 asm_state new_state;
1298 {
1299 ++cur_state_index;
1300 if (cur_state_index == MAX_STATE_DEPTH)
1301 as_fatal ("internal error: unexpected state push");
1302 asm_state_stack[cur_state_index] = new_state;
1303 }
1304
1305 /* TOP_OK_P is non-zero if it's ok that we're at the top of the stack.
1306 This happens if there are errors in the assembler code.
1307 We just reset the stack to its "init" state. */
1308
1309 static void
1310 pop_asm_state (top_ok_p)
1311 int top_ok_p;
1312 {
1313 if (cur_state_index == 0)
1314 {
1315 if (top_ok_p)
1316 asm_state_stack[cur_state_index] = ASM_INIT;
1317 else
1318 as_fatal ("internal error: unexpected state pop");
1319 }
1320 else
1321 --cur_state_index;
1322 }
1323
1324 static void
1325 set_asm_state (state)
1326 asm_state state;
1327 {
1328 CUR_ASM_STATE = state;
1329 }
1330 \f
1331 void
1332 md_operand (expressionP)
1333 expressionS *expressionP;
1334 {
1335 /* Check if this is a '*' for mpgloc. */
1336 if (cur_opcode
1337 && (cur_opcode->flags & VIF_OPCODE_MPG) != 0
1338 && (cur_operand->flags & DVP_OPERAND_VU_ADDRESS) != 0
1339 && *input_line_pointer == '*')
1340 {
1341 expressionP->X_op = O_symbol;
1342 expressionP->X_add_symbol = mpgloc_sym;
1343 expressionP->X_add_number = 0;
1344
1345 /* Advance over the '*'. */
1346 ++input_line_pointer;
1347 }
1348 /* Check if this is a '*' for unpackloc. */
1349 else if (cur_opcode
1350 && (cur_opcode->flags & VIF_OPCODE_UNPACK) != 0
1351 && (cur_operand->flags & DVP_OPERAND_UNPACK_ADDRESS) != 0
1352 && *input_line_pointer == '*')
1353 {
1354 expressionP->X_op = O_symbol;
1355 expressionP->X_add_symbol = unpackloc_sym;
1356 expressionP->X_add_number = 0;
1357
1358 /* Advance over the '*'. */
1359 ++input_line_pointer;
1360 }
1361 }
1362
1363 valueT
1364 md_section_align (segment, size)
1365 segT segment;
1366 valueT size;
1367 {
1368 int align = bfd_get_section_alignment (stdoutput, segment);
1369 return ((size + (1 << align) - 1) & (-1 << align));
1370 }
1371
1372 symbolS *
1373 md_undefined_symbol (name)
1374 char *name;
1375 {
1376 return 0;
1377 }
1378
1379 /* Called after parsing the file via md_after_pass_hook. */
1380
1381 void
1382 dvp_after_pass_hook ()
1383 {
1384 /* If doing dma packing, ensure the last dma tag is filled out. */
1385 if (dma_pack_vif_p)
1386 {
1387 /* Nothing to do as vifnops are zero and frag_align at beginning
1388 of dmatag is all we need. */
1389 }
1390
1391 #if 0 /* ??? Doesn't work unless we keep track of the nested include file
1392 level. */
1393 /* Check for missing .EndMpg, and supply one if necessary. */
1394 if (CUR_ASM_STATE == ASM_MPG)
1395 s_endmpg (ENDMPG_INTERNAL);
1396 else if (CUR_ASM_STATE == ASM_DIRECT)
1397 s_enddirect (0);
1398 else if (CUR_ASM_STATE == ASM_UNPACK)
1399 s_endunpack (0);
1400 #endif
1401 }
1402
1403 /* Called when a label is defined via tc_frob_label. */
1404
1405 void
1406 dvp_frob_label (sym)
1407 symbolS *sym;
1408 {
1409 /* All labels in vu code must be specially marked for the disassembler.
1410 The disassembler ignores all previous information at each new label
1411 (that has a higher address than the last one). */
1412 if (CUR_ASM_STATE == ASM_MPG
1413 || CUR_ASM_STATE == ASM_VU)
1414 S_SET_OTHER (sym, STO_DVP_VU);
1415 }
1416 \f
1417 /* mpg/direct alignment is handled via relaxation */
1418
1419 /* Return an initial guess of the length by which a fragment must grow to
1420 hold a branch to reach its destination.
1421 Also updates fr_type/fr_subtype as necessary.
1422
1423 Called just before doing relaxation.
1424 Any symbol that is now undefined will not become defined.
1425 The guess for fr_var is ACTUALLY the growth beyond fr_fix.
1426 Whatever we do to grow fr_fix or fr_var contributes to our returned value.
1427 Although it may not be explicit in the frag, pretend fr_var starts with a
1428 0 value. */
1429
1430 int
1431 md_estimate_size_before_relax (fragP, segment)
1432 fragS * fragP;
1433 segT segment;
1434 {
1435 /* Our initial estimate is always 0. */
1436 return 0;
1437 }
1438
1439 /* Perform the relaxation.
1440 All we have to do is figure out how many bytes we need to insert to
1441 get to the recorded symbol (which is at the required alignment). */
1442
1443 long
1444 dvp_relax_frag (fragP, stretch)
1445 fragS * fragP;
1446 long stretch;
1447 {
1448 /* Address of variable part. */
1449 long address = fragP->fr_address + fragP->fr_fix;
1450 /* Symbol marking start of data. */
1451 symbolS * symbolP = fragP->fr_symbol;
1452 /* Address of the symbol. */
1453 long target = S_GET_VALUE (symbolP) + symbolP->sy_frag->fr_address;
1454 long growth;
1455
1456 /* subtype >= 10 means "done" */
1457 if (fragP->fr_subtype >= 10)
1458 return 0;
1459
1460 /* subtype 1 = mpg */
1461 if (fragP->fr_subtype == 1)
1462 {
1463 growth = target - address;
1464 if (growth < 0)
1465 as_fatal ("internal error: bad mpg alignment handling");
1466 fragP->fr_subtype = 10 + growth;
1467 return growth;
1468 }
1469
1470 /* subtype 2 = direct */
1471 if (fragP->fr_subtype == 2)
1472 {
1473 growth = target - address;
1474 if (growth < 0)
1475 as_fatal ("internal error: bad direct alignment handling");
1476 fragP->fr_subtype = 10 + growth;
1477 return growth;
1478 }
1479
1480 as_fatal ("internal error: unknown fr_subtype");
1481 }
1482
1483 /* *fragP has been relaxed to its final size, and now needs to have
1484 the bytes inside it modified to conform to the new size.
1485
1486 Called after relaxation is finished.
1487 fragP->fr_type == rs_machine_dependent.
1488 fragP->fr_subtype is the subtype of what the address relaxed to. */
1489
1490 void
1491 md_convert_frag (abfd, sec, fragP)
1492 bfd * abfd;
1493 segT sec;
1494 fragS * fragP;
1495 {
1496 int growth = fragP->fr_subtype - 10;
1497
1498 fragP->fr_fix += growth;
1499
1500 if (growth != 0)
1501 {
1502 /* We had to grow this fragment. Shift the mpg/direct insn to the end
1503 (so it abuts the following data). */
1504 DVP_INSN insn = bfd_getl32 (fragP->fr_opcode);
1505 md_number_to_chars (fragP->fr_opcode, VIFNOP, 4);
1506 if (growth > 8)
1507 md_number_to_chars (fragP->fr_opcode, VIFNOP, 8);
1508 md_number_to_chars (fragP->fr_literal + fragP->fr_fix - 4, insn, 4);
1509
1510 /* Adjust fr_opcode so md_apply_fix3 works with the right bytes. */
1511 fragP->fr_opcode += growth;
1512 }
1513 }
1514 \f
1515 /* Functions concerning relocs. */
1516
1517 /* Spacing between each cpu type's operand numbers.
1518 Should be at least as big as any operand table. */
1519 #define RELOC_SPACING 256
1520
1521 /* Given a cpu type and operand number, return a temporary reloc type
1522 for use in generating the fixup that encodes the cpu type and operand
1523 number. */
1524
1525 static int
1526 encode_fixup_reloc_type (cpu, opnum)
1527 dvp_cpu cpu;
1528 int opnum;
1529 {
1530 return (int) BFD_RELOC_UNUSED + ((int) cpu * RELOC_SPACING) + opnum;
1531 }
1532
1533 /* Given a fixup reloc type, decode it into cpu type and operand. */
1534
1535 static void
1536 decode_fixup_reloc_type (fixup_reloc, cpuP, operandP)
1537 int fixup_reloc;
1538 dvp_cpu *cpuP;
1539 const dvp_operand **operandP;
1540 {
1541 dvp_cpu cpu = (fixup_reloc - (int) BFD_RELOC_UNUSED) / RELOC_SPACING;
1542 int opnum = (fixup_reloc - (int) BFD_RELOC_UNUSED) % RELOC_SPACING;
1543
1544 *cpuP = cpu;
1545 switch (cpu)
1546 {
1547 case DVP_VUUP : *operandP = &vu_operands[opnum]; break;
1548 case DVP_VULO : *operandP = &vu_operands[opnum]; break;
1549 case DVP_DMA : *operandP = &dma_operands[opnum]; break;
1550 case DVP_VIF : *operandP = &vif_operands[opnum]; break;
1551 case DVP_GIF : *operandP = &gif_operands[opnum]; break;
1552 default : as_fatal ("internal error: bad fixup encoding");
1553 }
1554 }
1555
1556 /* Given a fixup reloc type, return a pointer to the operand
1557
1558 /* The location from which a PC relative jump should be calculated,
1559 given a PC relative reloc. */
1560
1561 long
1562 md_pcrel_from_section (fixP, sec)
1563 fixS *fixP;
1564 segT sec;
1565 {
1566 if (fixP->fx_addsy != (symbolS *) NULL
1567 && (! S_IS_DEFINED (fixP->fx_addsy)
1568 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
1569 {
1570 /* If fx_tcbit is set this is for a vif insn and thus should never
1571 happen in correct code. */
1572 /* ??? The error message could be a bit more descriptive. */
1573 if (fixP->fx_tcbit)
1574 as_bad ("unable to compute length of vif insn");
1575 /* The symbol is undefined (or is defined but not in this section).
1576 Let the linker figure it out. +8: branch offsets are relative to the
1577 delay slot. */
1578 return 8;
1579 }
1580
1581 /* If fx_tcbit is set, this is a vif end-of-variable-length-insn marker.
1582 In this case the offset is relative to the start of data.
1583 Otherwise we assume this is a vu branch. In this case
1584 offsets are calculated based on the address of the next insn. */
1585 if (fixP->fx_tcbit)
1586 {
1587 /* As a further refinement, if fr_opcode is NULL this is `unpack'
1588 which doesn't involve any relaxing. */
1589 if (fixP->fx_frag->fr_opcode == NULL)
1590 return fixP->fx_frag->fr_address + fixP->fx_where + 4;
1591 else
1592 return fixP->fx_frag->fr_address + fixP->fx_frag->fr_fix;
1593 }
1594 else
1595 return ((fixP->fx_frag->fr_address + fixP->fx_where) & -8L) + 8;
1596 }
1597
1598 /* Apply a fixup to the object code. This is called for all the
1599 fixups we generated by calls to fix_new_exp. At this point all symbol
1600 values should be fully resolved, and we attempt to completely resolve the
1601 reloc. If we can not do that, we determine the correct reloc code and put
1602 it back in the fixup. */
1603
1604 int
1605 md_apply_fix3 (fixP, valueP, seg)
1606 fixS *fixP;
1607 valueT *valueP;
1608 segT seg;
1609 {
1610 char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
1611 valueT value;
1612
1613 /* FIXME FIXME FIXME: The value we are passed in *valueP includes
1614 the symbol values. Since we are using BFD_ASSEMBLER, if we are
1615 doing this relocation the code in write.c is going to call
1616 bfd_perform_relocation, which is also going to use the symbol
1617 value. That means that if the reloc is fully resolved we want to
1618 use *valueP since bfd_perform_relocation is not being used.
1619 However, if the reloc is not fully resolved we do not want to use
1620 *valueP, and must use fx_offset instead. However, if the reloc
1621 is PC relative, we do want to use *valueP since it includes the
1622 result of md_pcrel_from. This is confusing. */
1623
1624 if (fixP->fx_addsy == (symbolS *) NULL)
1625 {
1626 value = *valueP;
1627 fixP->fx_done = 1;
1628 }
1629 else if (fixP->fx_pcrel)
1630 {
1631 value = *valueP;
1632 }
1633 else
1634 {
1635 value = fixP->fx_offset;
1636 if (fixP->fx_subsy != (symbolS *) NULL)
1637 {
1638 if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)
1639 value -= S_GET_VALUE (fixP->fx_subsy);
1640 else
1641 {
1642 /* We can't actually support subtracting a symbol. */
1643 as_bad_where (fixP->fx_file, fixP->fx_line,
1644 "expression too complex");
1645 }
1646 }
1647 }
1648
1649 /* Check for dvp operands. These are indicated with a reloc value
1650 >= BFD_RELOC_UNUSED. */
1651
1652 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
1653 {
1654 dvp_cpu cpu;
1655 const dvp_operand *operand;
1656 DVP_INSN insn;
1657 fragS *fragP = fixP->fx_frag;
1658
1659 /* If this was a relaxable insn, the opcode may have moved. Find it. */
1660 if (fragP->fr_opcode != NULL)
1661 where = fragP->fr_opcode;
1662
1663 decode_fixup_reloc_type ((int) fixP->fx_r_type,
1664 & cpu, & operand);
1665
1666 /* For variable length vif insn data lengths, validate the user specified
1667 value or install the computed value in the instruction. */
1668 if (cpu == DVP_VIF
1669 && (operand - vif_operands) == vif_operand_datalen_special)
1670 {
1671 value = vif_length_value (where[3],
1672 fixP->tc_fix_data.wl, fixP->tc_fix_data.cl,
1673 value);
1674 if (fixP->tc_fix_data.user_value != -1)
1675 {
1676 if (fixP->tc_fix_data.user_value != value)
1677 as_warn_where (fixP->fx_file, fixP->fx_line,
1678 "specified length value doesn't match computed value");
1679 /* Don't override the user specified value. */
1680 }
1681 else
1682 {
1683 if (output_vif)
1684 {
1685 install_vif_length (where, value);
1686 }
1687 }
1688 fixP->fx_done = 1;
1689 return 1;
1690 }
1691
1692 /* For the gif nloop operand, if it was specified by the user ensure
1693 it matches the value we computed. */
1694 if (cpu == DVP_GIF
1695 && (operand - gif_operands) == gif_operand_nloop)
1696 {
1697 value = compute_nloop (fixP->tc_fix_data.type,
1698 fixP->tc_fix_data.nregs,
1699 value);
1700 if (fixP->tc_fix_data.user_value != -1)
1701 {
1702 check_nloop (fixP->tc_fix_data.type,
1703 fixP->tc_fix_data.nregs,
1704 fixP->tc_fix_data.user_value,
1705 value,
1706 fixP->fx_file, fixP->fx_line);
1707 /* Don't override the user specified value. */
1708 fixP->fx_done = 1;
1709 return 1;
1710 }
1711 }
1712
1713 /* Fetch the instruction, insert the fully resolved operand
1714 value, and stuff the instruction back again. The fixup is recorded
1715 at the appropriate word so pass DVP_MOD_THIS_WORD so any offset
1716 specified in the tables is ignored. */
1717 insn = bfd_getl32 ((unsigned char *) where);
1718 insert_operand_final (cpu, operand, DVP_MOD_THIS_WORD, &insn,
1719 (offsetT) value, fixP->fx_file, fixP->fx_line);
1720 bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
1721
1722 /* If this is mpgloc/unpackloc, we're done. */
1723 if (operand->flags & (DVP_OPERAND_VU_ADDRESS | DVP_OPERAND_UNPACK_ADDRESS))
1724 fixP->fx_done = 1;
1725
1726 if (fixP->fx_done)
1727 {
1728 /* Nothing else to do here. */
1729 return 1;
1730 }
1731
1732 /* Determine a BFD reloc value based on the operand information.
1733 We are only prepared to turn a few of the operands into relocs. */
1734 /* FIXME: This test is a hack. */
1735 if ((operand->flags & DVP_OPERAND_RELATIVE_BRANCH) != 0)
1736 {
1737 assert (operand->bits == 11
1738 && operand->shift == 0);
1739 fixP->fx_r_type = BFD_RELOC_MIPS_DVP_11_PCREL;
1740 }
1741 else if ((operand->flags & DVP_OPERAND_DMA_ADDR) != 0
1742 || (operand->flags & DVP_OPERAND_DMA_NEXT) != 0)
1743 {
1744 assert (operand->bits == 27
1745 && operand->shift == 4);
1746 fixP->fx_r_type = BFD_RELOC_MIPS_DVP_27_S4;
1747 }
1748 else
1749 {
1750 as_bad_where (fixP->fx_file, fixP->fx_line,
1751 "unresolved expression that must be resolved");
1752 fixP->fx_done = 1;
1753 return 1;
1754 }
1755 }
1756 else
1757 {
1758 switch (fixP->fx_r_type)
1759 {
1760 case BFD_RELOC_8:
1761 md_number_to_chars (where, value, 1);
1762 break;
1763 case BFD_RELOC_16:
1764 md_number_to_chars (where, value, 2);
1765 break;
1766 case BFD_RELOC_32:
1767 md_number_to_chars (where, value, 4);
1768 break;
1769 default:
1770 as_fatal ("internal error: unexpected fixup");
1771 }
1772 }
1773
1774 fixP->fx_addnumber = value;
1775
1776 return 1;
1777 }
1778
1779 /* Translate internal representation of relocation info to BFD target
1780 format. */
1781
1782 arelent *
1783 tc_gen_reloc (section, fixP)
1784 asection *section;
1785 fixS *fixP;
1786 {
1787 arelent *reloc;
1788
1789 reloc = (arelent *) xmalloc (sizeof (arelent));
1790
1791 reloc->sym_ptr_ptr = &fixP->fx_addsy->bsym;
1792 reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
1793 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
1794 if (reloc->howto == (reloc_howto_type *) NULL)
1795 {
1796 as_bad_where (fixP->fx_file, fixP->fx_line,
1797 "internal error: can't export reloc type %d (`%s')",
1798 fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type));
1799 return NULL;
1800 }
1801
1802 assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
1803
1804 reloc->addend = fixP->fx_addnumber;
1805
1806 return reloc;
1807 }
1808 \f
1809 /* Write a value out to the object file, using the appropriate endianness. */
1810
1811 void
1812 md_number_to_chars (buf, val, n)
1813 char *buf;
1814 valueT val;
1815 int n;
1816 {
1817 if (target_big_endian)
1818 number_to_chars_bigendian (buf, val, n);
1819 else
1820 number_to_chars_littleendian (buf, val, n);
1821 }
1822
1823 /* Turn a string in input_line_pointer into a floating point constant of type
1824 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1825 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
1826 */
1827
1828 /* Equal to MAX_PRECISION in atof-ieee.c */
1829 #define MAX_LITTLENUMS 6
1830
1831 char *
1832 md_atof (type, litP, sizeP)
1833 char type;
1834 char *litP;
1835 int *sizeP;
1836 {
1837 int i,prec;
1838 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1839 LITTLENUM_TYPE *wordP;
1840 char *t;
1841 char *atof_ieee ();
1842
1843 switch (type)
1844 {
1845 case 'f':
1846 case 'F':
1847 case 's':
1848 case 'S':
1849 prec = 2;
1850 break;
1851
1852 case 'd':
1853 case 'D':
1854 case 'r':
1855 case 'R':
1856 prec = 4;
1857 break;
1858
1859 /* FIXME: Some targets allow other format chars for bigger sizes here. */
1860
1861 default:
1862 *sizeP = 0;
1863 return "Bad call to md_atof()";
1864 }
1865
1866 t = atof_ieee (input_line_pointer, type, words);
1867 if (t)
1868 input_line_pointer = t;
1869 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1870
1871 if (target_big_endian)
1872 {
1873 for (i = 0; i < prec; i++)
1874 {
1875 md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE));
1876 litP += sizeof (LITTLENUM_TYPE);
1877 }
1878 }
1879 else
1880 {
1881 for (i = prec - 1; i >= 0; i--)
1882 {
1883 md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE));
1884 litP += sizeof (LITTLENUM_TYPE);
1885 }
1886 }
1887
1888 return 0;
1889 }
1890 \f
1891 /* Miscellaneous utilities. */
1892
1893 /* Parse a 32 bit floating point number.
1894 The result is those 32 bits as an integer. */
1895
1896 static long
1897 parse_float (pstr, errmsg)
1898 char **pstr;
1899 const char **errmsg;
1900 {
1901 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1902 char *p;
1903
1904 p = atof_ieee (*pstr, 'f', words);
1905 *pstr = p;
1906 return (words[0] << 16) | words[1];
1907 }
1908
1909 /* Scan a symbol and return a pointer to one past the end. */
1910
1911 #define issymchar(ch) (isalnum(ch) || ch == '_')
1912 static char *
1913 scan_symbol (sym)
1914 char *sym;
1915 {
1916 while (*sym && issymchar (*sym))
1917 ++sym;
1918 return sym;
1919 }
1920
1921 /* Evaluate an expression for an operand.
1922 The result is the value of the expression if it can be evaluated,
1923 or 0 if it cannot (say because some symbols haven't been defined yet)
1924 in which case a fixup is queued.
1925
1926 If OPINDEX is 0, don't queue any fixups, just return 0. */
1927
1928 static long
1929 #ifdef USE_STDARG
1930 eval_expr (int opindex, int offset, const char *fmt, ...)
1931 #else
1932 eval_expr (opindex, offset, fmt, va_alist)
1933 int opindex,offset;
1934 const char *fmt;
1935 va_dcl
1936 #endif
1937 {
1938 long value;
1939 va_list ap;
1940 char *str,*save_input;
1941 expressionS exp;
1942
1943 #ifdef USE_STDARG
1944 va_start (ap, fmt);
1945 #else
1946 va_start (ap);
1947 #endif
1948 vasprintf (&str, fmt, ap);
1949 va_end (ap);
1950
1951 save_input = input_line_pointer;
1952 input_line_pointer = str;
1953 expression (&exp);
1954 input_line_pointer = save_input;
1955 free (str);
1956 if (exp.X_op == O_constant)
1957 value = exp.X_add_number;
1958 else
1959 {
1960 if (opindex != 0)
1961 {
1962 fixups[fixup_count].exp = exp;
1963 fixups[fixup_count].opindex = opindex;
1964 fixups[fixup_count].offset = offset;
1965 fixups[fixup_count].user_value = -1;
1966 fixups[fixup_count].wl = -1;
1967 fixups[fixup_count].cl = -1;
1968 ++fixup_count;
1969 }
1970 value = 0;
1971 }
1972 return value;
1973 }
1974
1975 /* Create a label named by concatenating PREFIX to NAME. */
1976
1977 static symbolS *
1978 create_label (prefix, name)
1979 const char *prefix, *name;
1980 {
1981 int namelen = strlen (name);
1982 int prefixlen = strlen (prefix);
1983 char *fullname;
1984 symbolS *result;
1985
1986 fullname = xmalloc (prefixlen + namelen + 1);
1987 strcpy (fullname, prefix);
1988 strcat (fullname, name);
1989 result = symbol_find_or_make (fullname);
1990 free (fullname);
1991 return result;
1992 }
1993
1994 /* Create a label named by concatenating PREFIX to NAME,
1995 and define it as `.'.
1996 STO, if non-zero, is the st_other value to assign to this label.
1997 If STO is zero `cur_cpu', call force_mach_label to force record_mach to
1998 emit a cpu label. Otherwise the disassembler gets confused. */
1999
2000 static symbolS *
2001 create_colon_label (sto, prefix, name)
2002 int sto;
2003 const char *prefix, *name;
2004 {
2005 int namelen = strlen (name);
2006 int prefixlen = strlen (prefix);
2007 char *fullname;
2008 symbolS *result;
2009
2010 fullname = xmalloc (prefixlen + namelen + 1);
2011 strcpy (fullname, prefix);
2012 strcat (fullname, name);
2013 result = colon (fullname);
2014 if (sto)
2015 S_SET_OTHER (result, sto);
2016 else
2017 force_mach_label ();
2018 free (fullname);
2019 return result;
2020 }
2021
2022 /* Return a malloc'd string useful in creating unique labels.
2023 PREFIX is the prefix to use or NULL if we're to pick one. */
2024
2025 static char *
2026 unique_name (prefix)
2027 const char *prefix;
2028 {
2029 static int counter;
2030 char *result;
2031
2032 if (prefix == NULL)
2033 prefix = UNIQUE_LABEL_PREFIX;
2034 asprintf (&result, "%s%d", prefix, counter);
2035 ++counter;
2036 return result;
2037 }
2038 \f
2039 /* Compute a value for nloop. */
2040
2041 static int
2042 compute_nloop (type, nregs, bytes)
2043 gif_type type;
2044 int nregs, bytes;
2045 {
2046 int computed_nloop;
2047
2048 switch (type)
2049 {
2050 case GIF_PACKED :
2051 /* We can't compute a value if no regs were specified and there is a
2052 non-zero amount of data. Just set to something useful, a warning
2053 will be issued later. */
2054 if (nregs == 0)
2055 nregs = 1;
2056 computed_nloop = (bytes >> 4) / nregs;
2057 break;
2058 case GIF_REGLIST :
2059 if (nregs == 0)
2060 nregs = 1;
2061 computed_nloop = (bytes >> 3) / nregs;
2062 break;
2063 case GIF_IMAGE :
2064 computed_nloop = bytes >> 4;
2065 break;
2066 }
2067
2068 return computed_nloop;
2069 }
2070
2071 /* Issue a warning if the user specified nloop value doesn't match the
2072 computed value. */
2073
2074 static void
2075 check_nloop (type, nregs, user_nloop, computed_nloop, file, line)
2076 gif_type type;
2077 int nregs,user_nloop,computed_nloop;
2078 char *file;
2079 unsigned int line;
2080 {
2081 if (user_nloop != computed_nloop)
2082 as_warn_where (file, line, "nloop value does not match amount of data");
2083 }
2084 \f
2085 /* Compute the auto-count value for a DMA tag.
2086 INLINE_P is non-zero if the dma data is inline. */
2087
2088 static void
2089 setup_dma_autocount (name, insn_buf, inline_p)
2090 const char *name;
2091 DVP_INSN *insn_buf;
2092 int inline_p;
2093 {
2094 long count;
2095
2096 if (inline_p)
2097 {
2098 /* -1: The count is the number of following quadwords, so skip the one
2099 containing the dma tag. */
2100 count = eval_expr (dma_operand_count, 0,
2101 "((%s%s - %s) >> 4) - 1", END_LABEL_PREFIX, name, name);
2102 }
2103 else
2104 {
2105 /* We don't want to subtract 1 here as the begin and end labels
2106 properly surround the data we want to compute the length of. */
2107 count = eval_expr (dma_operand_count, 0,
2108 "(%s%s - %s) >> 4", END_LABEL_PREFIX, name, name);
2109 }
2110
2111 /* Store the count field. */
2112 insn_buf[0] &= 0xffff0000;
2113 insn_buf[0] |= count & 0x0000ffff;
2114 }
2115
2116 /* Record that inline data follows. */
2117
2118 static void
2119 inline_dma_data (autocount_p, insn_buf)
2120 int autocount_p;
2121 DVP_INSN *insn_buf;
2122 {
2123 if (dma_data_state != 0 )
2124 {
2125 as_bad ("DmaData blocks cannot be nested.");
2126 return;
2127 }
2128
2129 dma_data_state = 1;
2130
2131 if (autocount_p)
2132 {
2133 dma_data_name = S_GET_NAME (create_colon_label (0, "", unique_name (NULL)));
2134 setup_dma_autocount (dma_data_name, insn_buf, 1);
2135 }
2136 else
2137 dma_data_name = 0;
2138 }
2139
2140 /* Compute the auto-count value for a DMA tag with out-of-line data. */
2141
2142 static long
2143 parse_dma_addr_autocount (opcode, operand, mods, insn_buf, pstr, errmsg)
2144 const dvp_opcode *opcode;
2145 const dvp_operand *operand;
2146 int mods;
2147 DVP_INSN *insn_buf;
2148 char **pstr;
2149 const char **errmsg;
2150 {
2151 char *start = *pstr;
2152 char *end = start;
2153 long retval;
2154 /* Data reference must be a .DmaData label. */
2155 symbolS *label, *label2, *endlabel;
2156 const char *name;
2157 char c;
2158
2159 label = label2 = 0;
2160 if (! is_name_beginner (*start))
2161 {
2162 *errmsg = "invalid .DmaData label";
2163 return 0;
2164 }
2165
2166 name = start;
2167 end = scan_symbol (name);
2168 c = *end;
2169 *end = 0;
2170 label = symbol_find_or_make (name);
2171 *end = c;
2172
2173 label2 = create_label ("_$", name);
2174 endlabel = create_label (END_LABEL_PREFIX, name);
2175
2176 retval = eval_expr (dma_operand_addr, 4, name);
2177
2178 setup_dma_autocount (name, insn_buf, 0);
2179
2180 *pstr = end;
2181 return retval;
2182 }
2183 \f
2184 /* Return the length value to insert in a VIF instruction whose upper
2185 byte is CMD and whose data length is BYTES.
2186 WL,CL are used for unpack insns and are the stcycl values in effect.
2187 This does not do the max -> 0 conversion. */
2188
2189 static int
2190 vif_length_value (cmd, wl, cl, bytes)
2191 int cmd;
2192 int wl,cl;
2193 int bytes;
2194 {
2195 switch (cmd & 0x70)
2196 {
2197 case 0x50 : /* direct */
2198 /* ??? Worry about data /= 16 cuts off? */
2199 return bytes / 16;
2200 case 0x40 : /* mpg */
2201 /* ??? Worry about data /= 8 cuts off? */
2202 return bytes / 8;
2203 case 0x60 : /* unpack */
2204 case 0x70 :
2205 return vif_unpack_len_value (cmd & 15, wl, cl, bytes);
2206 default :
2207 as_fatal ("internal error: bad call to vif_length_value");
2208 }
2209 }
2210
2211 /* Install length LEN in the vif insn at BUF.
2212 LEN is the actual value to store, except that the max->0 conversion
2213 hasn't been done (we do it).
2214 The bytes in BUF are in target order. */
2215
2216 static void
2217 install_vif_length (buf, len)
2218 char *buf;
2219 int len;
2220 {
2221 unsigned char cmd = buf[3];
2222
2223 if ((cmd & 0x70) == 0x40)
2224 {
2225 /* mpg */
2226 if (len > 256)
2227 as_bad ("`mpg' data length must be between 1 and 256");
2228 buf[2] = len == 256 ? 0 : len;
2229 }
2230 else if ((cmd & 0x70) == 0x50)
2231 {
2232 /* direct/directhl */
2233 if (len > 65536)
2234 as_bad ("`direct' data length must be between 1 and 65536");
2235 len = len == 65536 ? 0 : len;
2236 buf[0] = len;
2237 buf[1] = len >> 8;
2238 }
2239 else if ((cmd & 0x60) == 0x60)
2240 {
2241 /* unpack */
2242 /* len == -1 means wl,cl are unknown and thus we can't compute
2243 a useful value */
2244 if (len == -1)
2245 {
2246 as_bad ("missing `stcycle', can't compute length of `unpack' insn");
2247 len = 1;
2248 }
2249 if (len < 0 || len > 256)
2250 as_bad ("`unpack' data length must be between 0 and 256");
2251 /* 256 is recorded as 0 in the insn */
2252 len = len == 256 ? 0 : len;
2253 buf[2] = len;
2254 }
2255 else
2256 as_fatal ("internal error: bad call to install_vif_length");
2257 }
2258
2259 /* Finish off the current set of mpg insns, and start a new set.
2260 The IGNORE arg exists because insert_unpack_marker uses it and both
2261 of these functions are passed to insert_file. */
2262
2263 static void
2264 insert_mpg_marker (ignore)
2265 unsigned long ignore;
2266 {
2267 s_endmpg (ENDMPG_MIDDLE);
2268 /* mpgloc is updated by s_endmpg. */
2269 md_assemble ("mpg *,*");
2270 /* Record the cpu type in case we're in the middle of reading binary
2271 data. */
2272 record_mach (DVP_VUUP, 0);
2273 }
2274
2275 /* Finish off the current unpack insn and start a new one.
2276 INSN0 is the first word of the insn and is used to figure out what
2277 kind of unpack insn it is. */
2278
2279 static void
2280 insert_unpack_marker (insn0)
2281 unsigned long insn0;
2282 {
2283 }
2284
2285 /* Insert a file into the output.
2286 The -I arg passed to GAS is used to specify where to find the file.
2287 INSERT_MARKER if non-NULL is called every SIZE bytes with an argument of
2288 INSERT_MARKER_ARG. This is used by the mpg insn to insert mpg's every 256
2289 insns and by the unpack insn.
2290 The result is the number of bytes inserted.
2291 If an error occurs an error message is printed and zero is returned. */
2292
2293 static int
2294 insert_file (file, insert_marker, insert_marker_arg, size)
2295 const char *file;
2296 void (*insert_marker) PARAMS ((unsigned long));
2297 unsigned long insert_marker_arg;
2298 int size;
2299 {
2300 FILE *f;
2301 char buf[256];
2302 int i, n, total, left_before_marker;
2303 char *path;
2304
2305 path = xmalloc (strlen (file) + include_dir_maxlen + 5 /*slop*/);
2306 f = NULL;
2307 for (i = 0; i < include_dir_count; i++)
2308 {
2309 strcpy (path, include_dirs[i]);
2310 strcat (path, "/");
2311 strcat (path, file);
2312 if ((f = fopen (path, FOPEN_RB)) != NULL)
2313 break;
2314 }
2315 free (path);
2316 if (f == NULL)
2317 f = fopen (file, FOPEN_RB);
2318 if (f == NULL)
2319 {
2320 as_bad ("unable to read file `%s'", file);
2321 return 0;
2322 }
2323
2324 total = 0;
2325 left_before_marker = 0;
2326 do {
2327 int bytes;
2328 if (insert_marker)
2329 bytes = MIN (size - left_before_marker, sizeof (buf));
2330 else
2331 bytes = sizeof (buf);
2332 n = fread (buf, 1, bytes, f);
2333 if (n > 0)
2334 {
2335 char *fr = frag_more (n);
2336 memcpy (fr, buf, n);
2337 total += n;
2338 if (insert_marker)
2339 {
2340 left_before_marker += n;
2341 if (left_before_marker > size)
2342 as_fatal ("internal error: file insertion sanity checky failed");
2343 if (left_before_marker == size)
2344 {
2345 (*insert_marker) (insert_marker_arg);
2346 left_before_marker = 0;
2347 }
2348 }
2349 }
2350 } while (n > 0);
2351
2352 fclose (f);
2353 /* We assume the file is smaller than 2^31 bytes.
2354 Ok, we shouldn't make any assumptions. */
2355 return total;
2356 }
2357
2358 /* Insert an operand value into an instruction. */
2359
2360 static void
2361 insert_operand (cpu, opcode, operand, mods, insn_buf, val, errmsg)
2362 dvp_cpu cpu;
2363 const dvp_opcode *opcode;
2364 const dvp_operand *operand;
2365 int mods;
2366 DVP_INSN *insn_buf;
2367 offsetT val;
2368 const char **errmsg;
2369 {
2370 if (operand->insert)
2371 {
2372 (*operand->insert) (opcode, operand, mods, insn_buf, (long) val, errmsg);
2373 }
2374 else
2375 {
2376 /* We currently assume a field does not cross a word boundary. */
2377 int shift = ((mods & DVP_MOD_THIS_WORD)
2378 ? (operand->shift & 31)
2379 : operand->shift);
2380 /* FIXME: revisit */
2381 if (operand->word == 0)
2382 {
2383 int word = (mods & DVP_MOD_THIS_WORD) ? 0 : (shift / 32);
2384 if (operand->bits == 32)
2385 insn_buf[word] = val;
2386 else
2387 {
2388 shift = shift % 32;
2389 insn_buf[word] |= ((long) val & ((1 << operand->bits) - 1)) << shift;
2390 }
2391 }
2392 else
2393 {
2394 int word = (mods & DVP_MOD_THIS_WORD) ? 0 : operand->word;
2395 if (operand->bits == 32)
2396 insn_buf[word] = val;
2397 else
2398 {
2399 long temp = (long) val & ((1 << operand->bits) - 1);
2400 insn_buf[word] |= temp << operand->shift;
2401 }
2402 }
2403 }
2404 }
2405
2406 /* Insert an operand's final value into an instruction.
2407 Here we can give warning messages about operand values if we want to. */
2408
2409 static void
2410 insert_operand_final (cpu, operand, mods, insn_buf, val, file, line)
2411 dvp_cpu cpu;
2412 const dvp_operand *operand;
2413 int mods;
2414 DVP_INSN *insn_buf;
2415 offsetT val;
2416 char *file;
2417 unsigned int line;
2418 {
2419 if (operand->bits != 32)
2420 {
2421 offsetT min, max, test;
2422
2423 if ((operand->flags & DVP_OPERAND_RELATIVE_BRANCH) != 0)
2424 {
2425 if ((val & 7) != 0)
2426 {
2427 if (file == (char *) NULL)
2428 as_warn ("branch to misaligned address");
2429 else
2430 as_warn_where (file, line, "branch to misaligned address");
2431 }
2432 val >>= 3;
2433 }
2434
2435 if ((operand->flags & DVP_OPERAND_SIGNED) != 0)
2436 {
2437 if ((operand->flags & DVP_OPERAND_SIGNOPT) != 0)
2438 max = (1 << operand->bits) - 1;
2439 else
2440 max = (1 << (operand->bits - 1)) - 1;
2441 min = - (1 << (operand->bits - 1));
2442 }
2443 else
2444 {
2445 max = (1 << operand->bits) - 1;
2446 min = 0;
2447 }
2448
2449 if ((operand->flags & DVP_OPERAND_NEGATIVE) != 0)
2450 test = - val;
2451 else
2452 test = val;
2453
2454 if (test < (offsetT) min || test > (offsetT) max)
2455 {
2456 const char *err =
2457 "operand out of range (%s not between %ld and %ld)";
2458 char buf[100];
2459
2460 sprint_value (buf, test);
2461 if (file == (char *) NULL)
2462 as_warn (err, buf, min, max);
2463 else
2464 as_warn_where (file, line, err, buf, min, max);
2465 }
2466 }
2467
2468 {
2469 const char *errmsg = NULL;
2470 insert_operand (cpu, NULL, operand, mods, insn_buf, val, &errmsg);
2471 if (errmsg != NULL)
2472 as_warn_where (file, line, errmsg);
2473 }
2474 }
2475 \f
2476 /* DVP pseudo ops. */
2477
2478 static void
2479 s_dmadata (ignore)
2480 int ignore;
2481 {
2482 char *name, c;
2483
2484 dma_data_name = 0;
2485
2486 if (dma_data_state != 0)
2487 {
2488 as_bad ("DmaData blocks cannot be nested.");
2489 ignore_rest_of_line ();
2490 return;
2491 }
2492 dma_data_state = 1;
2493
2494 SKIP_WHITESPACE (); /* Leading whitespace is part of operand. */
2495 name = input_line_pointer;
2496
2497 if (!is_name_beginner (*name))
2498 {
2499 as_bad ("invalid identifier for \".DmaData\"");
2500 ignore_rest_of_line ();
2501 return;
2502 }
2503
2504 /* Do an implicit alignment to a 16 byte boundary. */
2505 frag_align (4, 0, 0);
2506 record_alignment (now_seg, 4);
2507
2508 c = get_symbol_end ();
2509 line_label = colon (name); /* user-defined label */
2510 dma_data_name = S_GET_NAME (line_label);
2511 *input_line_pointer = c;
2512
2513 /* Force emission of a machine type label for the next insn. */
2514 force_mach_label ();
2515
2516 demand_empty_rest_of_line ();
2517 }
2518
2519 static void
2520 s_enddmadata (ignore)
2521 int ignore;
2522 {
2523 if (dma_data_state != 1)
2524 {
2525 as_warn (".EndDmaData encountered outside a DmaData block -- ignored.");
2526 ignore_rest_of_line ();
2527 dma_data_name = 0;
2528 }
2529 dma_data_state = 0;
2530 demand_empty_rest_of_line ();
2531
2532 /* If count provided, verify it is correct. */
2533 /* ... */
2534
2535 /* Fill the data out to a multiple of 16 bytes. */
2536 /* FIXME: Are the fill contents right? */
2537 frag_align (4, 0, 0);
2538
2539 /* "label" points to beginning of block.
2540 Create a name for the final label like _$<name>. */
2541 if (dma_data_name)
2542 create_colon_label (0, END_LABEL_PREFIX, dma_data_name);
2543 }
2544
2545 static void
2546 s_dmapackvif (ignore)
2547 int ignore;
2548 {
2549 /* Syntax: .dmapackvif 0|1 */
2550
2551 /* Leading whitespace is part of operand. */
2552 SKIP_WHITESPACE ();
2553 switch (*input_line_pointer++)
2554 {
2555 case '0':
2556 dma_pack_vif_p = 0;
2557 break;
2558 case '1':
2559 dma_pack_vif_p = 1;
2560 break;
2561 default:
2562 as_bad ("illegal argument to `.dmapackvif'");
2563 }
2564 demand_empty_rest_of_line ();
2565 }
2566
2567 /* INTERNAL_P is non-zero if invoked internally by this file rather than
2568 by the user. In this case we don't touch the input stream. */
2569
2570 static void
2571 s_enddirect (internal_p)
2572 int internal_p;
2573 {
2574 if (CUR_ASM_STATE != ASM_DIRECT)
2575 {
2576 as_bad ("`.enddirect' has no matching `direct' instruction");
2577 return;
2578 }
2579
2580 /* Record in the end data symbol the current location. */
2581 if (now_seg != S_GET_SEGMENT (vif_data_end))
2582 as_bad (".enddirect in different section");
2583 vif_data_end->sy_frag = frag_now;
2584 S_SET_VALUE (vif_data_end, (valueT) frag_now_fix ());
2585
2586 set_asm_state (ASM_INIT);
2587
2588 /* Needn't be reset, but to catch bugs it is. */
2589 vif_data_end = NULL;
2590
2591 if (! internal_p)
2592 demand_empty_rest_of_line ();
2593 }
2594
2595 /* CALLER denotes who's calling us.
2596 If ENDMPG_USER then .endmpg was found in the input stream.
2597 If ENDMPG_INTERNAL then we've been invoked to finish off file insertion.
2598 If ENDMPG_MIDDLE then we've been invoked in the middle of a long stretch
2599 of vu code. */
2600
2601 static void
2602 s_endmpg (caller)
2603 int caller;
2604 {
2605 if (CUR_ASM_STATE != ASM_MPG)
2606 {
2607 as_bad ("`.endmpg' has no matching `mpg' instruction");
2608 return;
2609 }
2610
2611 /* Record in the end data symbol the current location. */
2612 if (now_seg != S_GET_SEGMENT (vif_data_end))
2613 as_bad (".endmpg in different section");
2614 vif_data_end->sy_frag = frag_now;
2615 S_SET_VALUE (vif_data_end, (valueT) frag_now_fix ());
2616
2617 /* Update $.mpgloc.
2618 We have to leave the old value alone as it may be used in fixups
2619 already recorded. The new value is the old value plus the number of
2620 double words in this chunk. */
2621 {
2622 symbolS *s;
2623 s = expr_build_binary (O_subtract, vif_data_end, vif_data_start);
2624 s = expr_build_binary (O_divide, s, expr_build_uconstant (8));
2625 mpgloc_sym = expr_build_binary (O_add, mpgloc_sym, s);
2626 }
2627
2628 set_asm_state (ASM_INIT);
2629
2630 /* Needn't be reset, but to catch bugs it is. */
2631 vif_data_end = NULL;
2632
2633 /* Reset the vu insn counter. */
2634 if (caller != ENDMPG_MIDDLE)
2635 vu_count = -1;
2636
2637 if (caller == ENDMPG_USER)
2638 demand_empty_rest_of_line ();
2639 }
2640
2641 /* INTERNAL_P is non-zero if invoked internally by this file rather than
2642 by the user. In this case we don't touch the input stream. */
2643
2644 static void
2645 s_endunpack (internal_p)
2646 int internal_p;
2647 {
2648 if (CUR_ASM_STATE != ASM_UNPACK)
2649 {
2650 as_bad ("`.endunpack' has no matching `unpack' instruction");
2651 return;
2652 }
2653
2654 /* Record in the end data symbol the current location. */
2655 if (now_seg != S_GET_SEGMENT (vif_data_end))
2656 as_bad (".endunpack in different section");
2657 vif_data_end->sy_frag = frag_now;
2658 S_SET_VALUE (vif_data_end, (valueT) frag_now_fix ());
2659
2660 /* Update $.UnpackLoc. */
2661 {
2662 symbolS *s;
2663 s = expr_build_binary (O_subtract, vif_data_end, vif_data_start);
2664 /* Round up to next quadword boundary. */
2665 /* FIXME: This isn't correct, the size of the input data is not the
2666 size of the output data. Someone else can fix this. */
2667 s = expr_build_binary (O_add, s, expr_build_uconstant (15));
2668 s = expr_build_binary (O_divide, s, expr_build_uconstant (16));
2669 unpackloc_sym = expr_build_binary (O_add, unpackloc_sym, s);
2670 }
2671
2672 /* Round up to next word boundary. */
2673 frag_align (2, 0, 0);
2674
2675 set_asm_state (ASM_INIT);
2676
2677 /* Needn't be reset, but to catch bugs it is. */
2678 vif_data_end = NULL;
2679
2680 if (! internal_p)
2681 demand_empty_rest_of_line ();
2682 }
2683
2684 static void
2685 s_endgif (ignore)
2686 int ignore;
2687 {
2688 int bytes;
2689 int specified_nloop = gif_nloop ();
2690 int computed_nloop;
2691 int nregs = gif_nregs ();
2692 char *file;
2693 unsigned int line;
2694
2695 as_where (&file, &line);
2696
2697 if (CUR_ASM_STATE != ASM_GIF)
2698 {
2699 as_bad (".endgif doesn't follow a gif tag");
2700 return;
2701 }
2702 pop_asm_state (0);
2703
2704 /* Fill out to proper boundary.
2705 ??? This may cause eval_expr to always queue a fixup. So be it. */
2706 switch (gif_insn_type)
2707 {
2708 case GIF_PACKED : frag_align (4, 0, 0); break;
2709 case GIF_REGLIST : frag_align (3, 0, 0); break;
2710 case GIF_IMAGE : frag_align (4, 0, 0); break;
2711 }
2712
2713 /* The -16 is because the `gif_data_name' label is emitted at the
2714 start of the gif tag. If we're in a different frag from the one we
2715 started with, this can't be computed until much later. To cope we queue
2716 a fixup and deal with it then.
2717 ??? The other way to handle this is by having expr() compute "syma - symb"
2718 when they're in different fragments but the difference is constant.
2719 Not sure how much of a slowdown that will introduce though. */
2720 fixup_count = 0;
2721 bytes = eval_expr (gif_operand_nloop, 0, ". - %s - 16", gif_data_name);
2722
2723 /* Compute a value for nloop if we can. */
2724
2725 if (fixup_count == 0)
2726 {
2727 computed_nloop = compute_nloop (gif_insn_type, nregs, bytes);
2728
2729 /* If the user specified nloop, verify it. */
2730 if (specified_nloop != -1)
2731 check_nloop (gif_insn_type, nregs,
2732 specified_nloop, computed_nloop,
2733 file, line);
2734 }
2735
2736 /* If computation of nloop can't be done yet, queue a fixup and do it later.
2737 Otherwise validate nloop if specified or write the computed value into
2738 the insn. */
2739
2740 if (fixup_count != 0)
2741 {
2742 /* FIXME: It might eventually be possible to combine all the various
2743 copies of this bit of code. */
2744 int op_type, reloc_type, offset;
2745 const dvp_operand *operand;
2746 fixS *fix;
2747
2748 op_type = fixups[0].opindex;
2749 offset = fixups[0].offset;
2750 reloc_type = encode_fixup_reloc_type (DVP_GIF, op_type);
2751 operand = &gif_operands[op_type];
2752 fix = fix_new_exp (gif_insn_frag,
2753 (gif_insn_frag_loc + offset
2754 - gif_insn_frag->fr_literal),
2755 4, &fixups[0].exp, 0,
2756 (bfd_reloc_code_real_type) reloc_type);
2757 /* Record user specified value so we can test it when we compute the
2758 actual value. */
2759 fix->tc_fix_data.type = gif_insn_type;
2760 fix->tc_fix_data.nregs = nregs;
2761 fix->tc_fix_data.user_value = specified_nloop;
2762 }
2763 else if (specified_nloop != -1)
2764 ; /* nothing to do */
2765 else
2766 {
2767 DVP_INSN insn = bfd_getl32 (gif_insn_frag_loc);
2768 insert_operand_final (DVP_GIF, &gif_operands[gif_operand_nloop],
2769 DVP_MOD_THIS_WORD, &insn,
2770 (offsetT) computed_nloop, file, line);
2771 bfd_putl32 ((bfd_vma) insn, gif_insn_frag_loc);
2772 }
2773
2774 /* These needn't be reset, but to catch bugs they are. */
2775 gif_data_name = NULL;
2776 gif_insn_frag = NULL;
2777 gif_insn_frag_loc = NULL;
2778
2779 demand_empty_rest_of_line ();
2780 }
2781
2782 static void
2783 s_state (state)
2784 int state;
2785 {
2786 /* If in MPG state and the user requests to change to VU state,
2787 leave the state as MPG. This happens when we see an mpg followed
2788 by a .include that has .vu. */
2789 if (CUR_ASM_STATE == ASM_MPG && state == ASM_VU)
2790 return;
2791
2792 set_asm_state (state);
2793
2794 demand_empty_rest_of_line ();
2795 }
This page took 0.087401 seconds and 4 git commands to generate.