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