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