1 /* tc-dvp.c -- Assembler for the DVP
2 Copyright (C) 1997, 1998 Free Software Foundation.
4 This file is part of GAS, the GNU Assembler.
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)
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.
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. */
27 /* Needed by opcode/dvp.h. */
29 #include "opcode/dvp.h"
38 /* Value of VIF `nop' instruction. */
41 #define MIN(a,b) ((a) < (b) ? (a) : (b))
43 /* Compute DMA operand index number of OP. */
44 #define DMA_OPERAND_INDEX(op) ((op) - dma_operands)
46 /* Our local label prefix. */
47 #define LOCAL_LABEL_PREFIX ".L"
48 /* Label prefix for end markers used in autocounts. */
49 #define END_LABEL_PREFIX ".L.end."
50 /* Label to use for unique labels. */
51 #define UNIQUE_LABEL_PREFIX ".L.dvptmp."
53 static long parse_float
PARAMS ((char **, const char **));
54 static symbolS
* create_label
PARAMS ((const char *, const char *));
55 static symbolS
* create_colon_label
PARAMS ((int, const char *, const char *));
56 static char * unique_name
PARAMS ((const char *));
57 static int compute_nloop
PARAMS ((gif_type
, int, int));
58 static void check_nloop
PARAMS ((gif_type
, int, int, int,
59 char *, unsigned int));
60 static long eval_expr
PARAMS ((int, int, const char *, ...));
61 static long parse_dma_addr_autocount ();
62 static void inline_dma_data
PARAMS ((int, DVP_INSN
*));
63 static void setup_dma_autocount
PARAMS ((const char *, DVP_INSN
*, int));
65 static void insert_operand
66 PARAMS ((dvp_cpu
, const dvp_opcode
*, const dvp_operand
*, int,
67 DVP_INSN
*, offsetT
, const char **));
68 static void insert_operand_final
69 PARAMS ((dvp_cpu
, const dvp_operand
*, int,
70 DVP_INSN
*, offsetT
, char *, unsigned int));
72 static void insert_mpg_marker
PARAMS ((unsigned long));
73 static void insert_unpack_marker
PARAMS ((unsigned long));
74 static int insert_file
PARAMS ((const char *,
75 void (*) PARAMS ((unsigned long)),
78 static int vif_length_value
PARAMS ((int, int, int, int));
79 static void install_vif_length
PARAMS ((char *, int));
81 const char comment_chars
[] = ";";
82 const char line_comment_chars
[] = "#";
83 const char line_separator_chars
[] = "!";
84 const char EXP_CHARS
[] = "eE";
85 const char FLT_CHARS
[] = "dD";
87 /* Current assembler state.
88 Instructions like mpg and direct are followed by a restricted set of
89 instructions. In the case of a '*' length argument an end marker must
90 be provided. (e.g. mpg is followed by vu insns until a .EndMpg is
93 Allowed state transitions:
101 ASM_INIT
, ASM_DIRECT
, ASM_MPG
, ASM_UNPACK
, ASM_VU
, ASM_GIF
104 /* We need to maintain a stack of the current and previous status to handle
105 such things as "direct ...; gifpacked ... ; .endgif ; .enddirect". */
106 #define MAX_STATE_DEPTH 2
107 static asm_state asm_state_stack
[MAX_STATE_DEPTH
];
108 /* Current state's index in the stack. */
109 static int cur_state_index
;
110 /* Macro to fetch the current state. */
111 #define CUR_ASM_STATE (asm_state_stack[cur_state_index])
113 /* Functions to push/pop the state stack. */
114 static void push_asm_state
PARAMS ((asm_state
));
115 static void pop_asm_state
PARAMS ((int));
116 static void set_asm_state
PARAMS ((asm_state
));
118 /* Current cpu (machine variant) type state.
119 We copy the mips16 way of recording what the current machine type is in
120 the code. A label is created whenever necessary and has an "other" value
121 the denotes the machine type. */
122 static dvp_cpu cur_cpu
;
123 /* Record the current mach type. */
124 static void record_mach
PARAMS ((dvp_cpu
, int));
125 /* Force emission of mach type label at next insn.
126 This isn't static as TC_START_LABEL uses it. */
127 int force_mach_label
PARAMS ((void));
128 /* Given a dvp_cpu value, return the STO_DVP value to use. */
129 static int cpu_sto
PARAMS ((dvp_cpu
, const char **));
131 /* Nonzero if inside .DmaData. */
132 static int dma_data_state
= 0;
133 /* Label of .DmaData (internally generated for inline data). */
134 static const char *dma_data_name
;
136 /* Variable length VIF insn support. */
137 /* Label at start of insn's data. */
138 static symbolS
*vif_data_start
;
139 /* Label at end of insn's data. */
140 static symbolS
*vif_data_end
;
142 /* Special symbol $.mpgloc. */
143 static symbolS
*mpgloc_sym
;
144 /* Special symbol $.unpackloc. */
145 static symbolS
*unpackloc_sym
;
147 /* GIF insn support. */
149 static int gif_insn_type
;
150 /* Name of label of insn's data. */
151 static const char *gif_data_name
;
152 /* Pointer to frag of insn. */
153 static fragS
*gif_insn_frag
;
154 /* Pointer to current gif insn in gif_insn_frag. */
155 static char *gif_insn_frag_loc
;
156 /* The length value specified in the insn, or -1 if '*'. */
157 static int gif_user_value
;
159 /* Count of vu insns seen since the last mpg.
160 Set to -1 to disable automatic mpg insertion. */
163 /* Non-zero if packing vif instructions in dma tags. */
164 static int dma_pack_vif_p
;
166 /* Non-zero if dma insns are to be included in the output.
167 This is the default, but writing "if (! no_dma)" is klunky. */
168 static int output_dma
= 1;
169 /* Non-zero if vif insns are to be included in the output. */
170 static int output_vif
= 1;
172 /* Current opcode/operand for use by md_operand. */
173 static const dvp_opcode
*cur_opcode
;
174 static const dvp_operand
*cur_operand
;
176 /* Options for the `caller' argument to s_endmpg. */
177 typedef enum { ENDMPG_USER
, ENDMPG_INTERNAL
, ENDMPG_MIDDLE
} endmpg_caller
;
179 const char *md_shortopts
= "";
181 struct option md_longopts
[] =
183 #define OPTION_NO_DMA (OPTION_MD_BASE + 1)
184 { "no-dma", no_argument
, NULL
, OPTION_NO_DMA
},
185 #define OPTION_NO_DMA_VIF (OPTION_NO_DMA + 1)
186 { "no-dma-vif", no_argument
, NULL
, OPTION_NO_DMA_VIF
},
188 {NULL
, no_argument
, NULL
, 0}
190 size_t md_longopts_size
= sizeof(md_longopts
);
193 md_parse_option (c
, arg
)
202 case OPTION_NO_DMA_VIF
:
213 md_show_usage (stream
)
218 -no-dma do not include DMA instructions in the output\n\
219 -no-dma-vif do not include DMA or VIF instructions in the output\n\
223 /* Set by md_assemble for use by dvp_fill_insn. */
224 static subsegT prev_subseg
;
225 static segT prev_seg
;
227 static void s_dmadata
PARAMS ((int));
228 static void s_enddmadata
PARAMS ((int));
229 static void s_dmapackvif
PARAMS ((int));
230 static void s_enddirect
PARAMS ((int));
231 static void s_endmpg
PARAMS ((int));
232 static void s_endunpack
PARAMS ((int));
233 static void s_endgif
PARAMS ((int));
234 static void s_state
PARAMS ((int));
236 /* The target specific pseudo-ops which we support. */
237 const pseudo_typeS md_pseudo_table
[] =
240 { "quad", cons
, 16 },
241 { "dmadata", s_dmadata
, 0 },
242 { "dmapackvif", s_dmapackvif
, 0 },
243 { "enddirect", s_enddirect
, 0 },
244 { "enddmadata", s_enddmadata
, 0 },
245 { "endmpg", s_endmpg
, ENDMPG_USER
},
246 { "endunpack", s_endunpack
, 0 },
247 { "endgif", s_endgif
, 0 },
248 { "vu", s_state
, ASM_VU
},
255 /* Initialize the opcode tables.
256 This involves computing the hash chains. */
257 dvp_opcode_init_tables (0);
259 /* Force a mach type label for the first insn. */
262 /* Initialize the parsing state. */
264 set_asm_state (ASM_INIT
);
266 /* Pack vif insns in dma tags by default. */
269 /* Disable automatic mpg insertion. */
272 /* Create special symbols. */
273 mpgloc_sym
= expr_build_uconstant (0);
274 unpackloc_sym
= expr_build_uconstant (0);
277 /* We need to keep a list of fixups. We can't simply generate them as
278 we go, because that would require us to first create the frag, and
279 that would screw up references to ``.''. */
283 /* index into `dvp_operands' */
285 /* byte offset from beginning of instruction */
287 /* user specified value [when there is one] */
289 /* wl,cl values, only used with unpack insn */
297 static int fixup_count
;
298 static struct dvp_fixup fixups
[MAX_FIXUPS
];
300 /* Given a cpu type and operand number, return a temporary reloc type
301 for use in generating the fixup that encodes the cpu type and operand. */
302 static int encode_fixup_reloc_type
PARAMS ((dvp_cpu
, int));
303 /* Given an encoded fixup reloc type, decode it into cpu and operand. */
304 static void decode_fixup_reloc_type
PARAMS ((int, dvp_cpu
*,
305 const dvp_operand
**));
307 static void assemble_dma
PARAMS ((char *));
308 static void assemble_gif
PARAMS ((char *));
309 static void assemble_vif
PARAMS ((char *));
310 static void assemble_vu
PARAMS ((char *));
311 static const dvp_opcode
* assemble_vu_insn
PARAMS ((dvp_cpu
,
315 static const dvp_opcode
* assemble_one_insn
PARAMS ((dvp_cpu
,
318 char **, DVP_INSN
*));
320 /* Main entry point for assembling an instruction. */
326 /* Skip leading white space. */
327 while (isspace (*str
))
330 /* After a gif tag, no insns can appear until a .endgif is seen. */
331 if (CUR_ASM_STATE
== ASM_GIF
)
333 as_bad ("missing .endgif");
336 /* Ditto for unpack. */
337 if (CUR_ASM_STATE
== ASM_UNPACK
)
339 as_bad ("missing .endunpack");
342 #if 0 /* this doesn't work of course as gif insns may follow */
343 /* Ditto for direct. */
344 if (CUR_ASM_STATE
== ASM_DIRECT
)
346 as_bad ("missing .enddirect");
351 if (CUR_ASM_STATE
== ASM_INIT
)
353 if (strncasecmp (str
, "dma", 3) == 0)
355 else if (strncasecmp (str
, "gif", 3) == 0)
360 else if (CUR_ASM_STATE
== ASM_DIRECT
)
362 else if (CUR_ASM_STATE
== ASM_VU
363 || CUR_ASM_STATE
== ASM_MPG
)
366 as_fatal ("internal error: unknown parse state");
369 /* Subroutine of md_assemble to assemble DMA instructions. */
375 DVP_INSN insn_buf
[2];
376 /* Insn's length, in 32 bit words. */
378 /* Pointer to allocated frag. */
381 const dvp_opcode
*opcode
;
385 /* Do an implicit alignment to a 16 byte boundary.
386 Do it now so that inline dma data labels are at the right place. */
387 /* ??? One can certainly argue all this implicit alignment is
388 questionable. The thing is assembler programming is all that will
389 mostly likely ever be done and not doing so forces an extra [and
390 arguably unnecessary] burden on the programmer. */
391 frag_align (4, 0, 0);
392 record_alignment (now_seg
, 4);
395 /* This is the DMA tag. */
399 opcode
= assemble_one_insn (DVP_DMA
,
400 dma_opcode_lookup_asm (str
), dma_operands
,
407 record_mach (DVP_DMA
, 0);
411 /* Write out the DMA instruction. */
412 for (i
= 0; i
< 2; ++i
)
413 md_number_to_chars (f
+ i
* 4, insn_buf
[i
], 4);
415 /* Create any fixups. */
416 /* FIXME: It might eventually be possible to combine all the various
417 copies of this bit of code. */
418 for (i
= 0; i
< fixup_count
; ++i
)
420 int op_type
, reloc_type
, offset
;
421 const dvp_operand
*operand
;
423 /* Create a fixup for this operand.
424 At this point we do not use a bfd_reloc_code_real_type for
425 operands residing in the insn, but instead just use the
426 operand index. This lets us easily handle fixups for any
427 operand type, although that is admittedly not a very exciting
428 feature. We pick a BFD reloc type in md_apply_fix. */
430 op_type
= fixups
[i
].opindex
;
431 offset
= fixups
[i
].offset
;
432 reloc_type
= encode_fixup_reloc_type (DVP_DMA
, op_type
);
433 operand
= &dma_operands
[op_type
];
434 fix_new_exp (frag_now
, f
+ offset
- frag_now
->fr_literal
, 4,
436 (operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0,
437 (bfd_reloc_code_real_type
) reloc_type
);
440 /* The upper two words are vif insns. */
441 record_mach (DVP_VIF
, 0);
443 /* If not doing dma/vif packing, fill out the insn with vif nops.
444 ??? We take advantage of the fact that the default fill value of zero
445 is the vifnop insn. This occurs for example when handling mpg
446 alignment. It also occurs when one dma tag immediately follows the
448 if (! dma_pack_vif_p
)
451 md_number_to_chars (f
+ 0, VIFNOP
, 4);
452 md_number_to_chars (f
+ 4, VIFNOP
, 4);
456 /* Subroutine of md_assemble to assemble VIF instructions. */
462 /* Space for the instruction.
463 The variable length insns can require much more space than this.
464 It is allocated later, when we know we have such an insn. */
465 DVP_INSN insn_buf
[5];
466 /* Insn's length, in 32 bit words. */
468 /* Pointer to allocated frag. */
471 const dvp_opcode
*opcode
;
473 /* Name of file to read data from. */
475 /* Length in 32 bit words. */
477 /* Macro expansion, if there is one. */
480 /* First check for macros. */
481 macstr
= dvp_expand_macro (vif_macros
, vif_macro_count
, str
);
484 /* The macro may expand into several insns (delimited with '\n'),
486 char * next
= macstr
;
489 char *p
= strchr (next
, '\n');
493 next
= p
? p
+ 1 : 0;
500 opcode
= assemble_one_insn (DVP_VIF
,
501 vif_opcode_lookup_asm (str
), vif_operands
,
506 if (opcode
->flags
& VIF_OPCODE_LENVAR
)
507 len
= 1; /* actual data follows later */
508 else if (opcode
->flags
& VIF_OPCODE_LEN2
)
510 else if (opcode
->flags
& VIF_OPCODE_LEN5
)
515 /* We still have to switch modes (if mpg for example) so we can't exit
520 /* Record the mach before doing the alignment so that we properly
521 disassemble any inserted vifnop's. For mpg and direct insns
522 force the recording of the mach type for the next insn. The data
523 will switch the mach type and we want to ensure it's switched
526 if (opcode
->flags
& (VIF_OPCODE_MPG
| VIF_OPCODE_DIRECT
))
527 record_mach (DVP_VIF
, 1);
529 record_mach (DVP_VIF
, 0);
531 /* For variable length instructions record a fixup that is the symbol
532 marking the end of the data. eval_expr will queue the fixup
533 which will then be emitted later. */
534 if (opcode
->flags
& VIF_OPCODE_LENVAR
)
538 asprintf (&name
, "%s%s", LOCAL_LABEL_PREFIX
,
539 unique_name ("varlen"));
540 vif_data_end
= symbol_new (name
, now_seg
, 0, 0);
541 symbol_table_insert (vif_data_end
);
542 fixups
[fixup_count
].exp
.X_op
= O_symbol
;
543 fixups
[fixup_count
].exp
.X_add_symbol
= vif_data_end
;
544 fixups
[fixup_count
].exp
.X_add_number
= 0;
545 fixups
[fixup_count
].opindex
= vif_operand_datalen_special
;
546 fixups
[fixup_count
].offset
= 0;
548 /* See what the user specified. */
549 vif_get_var_data (&file
, &data_len
);
552 fixups
[fixup_count
].user_value
= data_len
;
553 /* Get the wl,cl values. Only useful for the unpack insn but
554 it doesn't hurt to always record them. */
555 vif_get_wl_cl (&wl
, &cl
);
556 fixups
[fixup_count
].wl
= wl
;
557 fixups
[fixup_count
].cl
= cl
;
561 /* Obtain space in which to store the instruction. */
563 if (opcode
->flags
& VIF_OPCODE_MPG
)
565 /* The data must be aligned on a 64 bit boundary (so the mpg insn
566 comes just before that 64 bit boundary).
567 Do this by putting the mpg insn in a relaxable fragment
568 with a symbol that marks the beginning of the aligned data. */
570 /* Ensure relaxable fragments are in their own fragment.
571 Otherwise md_apply_fix3 mishandles fixups to insns earlier
572 in the fragment (because we set fr_opcode for the `mpg' insn
573 because it can move in the fragment). */
574 frag_wane (frag_now
);
577 /* This dance with frag_grow is to ensure the variable part and
578 fixed part are in the same fragment. */
580 /* Allocate space for the fixed part. */
582 insn_frag
= frag_now
;
584 frag_var (rs_machine_dependent
,
586 0, /* variable part already allocated */
588 NULL
, /* no symbol */
592 frag_align (3, 0, 0);
593 record_alignment (now_seg
, 3);
595 /* Put a symbol at the start of data. The relaxation code uses
596 this to figure out how many bytes to insert. $.mpgloc
597 calculations also use it. */
598 vif_data_start
= create_colon_label (STO_DVP_VU
, LOCAL_LABEL_PREFIX
,
599 unique_name ("mpg"));
600 insn_frag
->fr_symbol
= vif_data_start
;
602 /* Get the value of mpgloc. If it wasn't '*' update $.mpgloc. */
604 int mpgloc
= vif_get_mpgloc ();
607 mpgloc_sym
->sy_value
.X_op
= O_constant
;
608 mpgloc_sym
->sy_value
.X_add_number
= mpgloc
;
609 mpgloc_sym
->sy_value
.X_unsigned
= 1;
613 else if (opcode
->flags
& VIF_OPCODE_DIRECT
)
615 /* The data must be aligned on a 128 bit boundary (so the direct insn
616 comes just before that 128 bit boundary).
617 Do this by putting the direct insn in a relaxable fragment.
618 with a symbol that marks the beginning of the aligned data. */
620 /* Ensure relaxable fragments are in their own fragment.
621 Otherwise md_apply_fix3 mishandles fixups to insns earlier
622 in the fragment (because we set fr_opcode for the `direct' insn
623 because it can move in the fragment). */
624 frag_wane (frag_now
);
627 /* This dance with frag_grow is to ensure the variable part and
628 fixed part are in the same fragment. */
630 /* Allocate space for the fixed part. */
632 insn_frag
= frag_now
;
634 frag_var (rs_machine_dependent
,
636 0, /* variable part already allocated */
638 NULL
, /* no symbol */
642 frag_align (4, 0, 0);
643 record_alignment (now_seg
, 4);
645 /* Put a symbol at the start of data. The relaxation code uses
646 this to figure out how many bytes to insert. */
647 vif_data_start
= create_colon_label (0, LOCAL_LABEL_PREFIX
,
648 unique_name ("direct"));
649 insn_frag
->fr_symbol
= vif_data_start
;
651 else if (opcode
->flags
& VIF_OPCODE_UNPACK
)
653 f
= frag_more (len
* 4);
654 insn_frag
= frag_now
;
655 /* Put a symbol at the start of data. $.unpackloc calculations
657 vif_data_start
= create_colon_label (STO_DVP_VIF
, LOCAL_LABEL_PREFIX
,
658 unique_name ("unpack"));
660 /* Get the value of unpackloc. If it wasn't '*' update
663 int unpackloc
= vif_get_unpackloc ();
666 unpackloc_sym
->sy_value
.X_op
= O_constant
;
667 unpackloc_sym
->sy_value
.X_add_number
= unpackloc
;
668 unpackloc_sym
->sy_value
.X_unsigned
= 1;
674 /* Reminder: it is important to fetch enough space in one call to
675 `frag_more'. We use (f - frag_now->fr_literal) to compute where
676 we are and we don't want frag_now to change between calls. */
677 f
= frag_more (len
* 4);
678 insn_frag
= frag_now
;
681 /* Write out the instruction. */
682 for (i
= 0; i
< len
; ++i
)
683 md_number_to_chars (f
+ i
* 4, insn_buf
[i
], 4);
685 /* Create any fixups. */
686 /* FIXME: It might eventually be possible to combine all the various
687 copies of this bit of code. */
688 for (i
= 0; i
< fixup_count
; ++i
)
690 int op_type
, reloc_type
, offset
;
691 const dvp_operand
*operand
;
694 /* Create a fixup for this operand.
695 At this point we do not use a bfd_reloc_code_real_type for
696 operands residing in the insn, but instead just use the
697 operand index. This lets us easily handle fixups for any
698 operand type, although that is admittedly not a very exciting
699 feature. We pick a BFD reloc type in md_apply_fix. */
701 op_type
= fixups
[i
].opindex
;
702 offset
= fixups
[i
].offset
;
703 reloc_type
= encode_fixup_reloc_type (DVP_VIF
, op_type
);
704 operand
= &vif_operands
[op_type
];
705 fixP
= fix_new_exp (insn_frag
, f
+ offset
- insn_frag
->fr_literal
, 4,
707 (operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0,
708 (bfd_reloc_code_real_type
) reloc_type
);
709 fixP
->tc_fix_data
.user_value
= fixups
[i
].user_value
;
710 fixP
->tc_fix_data
.wl
= fixups
[i
].wl
;
711 fixP
->tc_fix_data
.cl
= fixups
[i
].cl
;
713 /* Set fx_tcbit so other parts of the code know this fixup is for
719 /* Handle variable length insns. */
721 if (opcode
->flags
& VIF_OPCODE_LENVAR
)
723 /* See what the user specified. */
724 vif_get_var_data (&file
, &data_len
);
730 /* The handling for each of mpg,direct,unpack is basically the same:
731 - emit a label to set the mach type for the data we're inserting
732 - switch to the new assembler state
734 - call the `end' handler */
736 if (opcode
->flags
& VIF_OPCODE_MPG
)
738 record_mach (DVP_VUUP
, 1);
739 set_asm_state (ASM_MPG
);
740 byte_len
= insert_file (file
, insert_mpg_marker
, 0, 256 * 8);
741 s_endmpg (ENDMPG_INTERNAL
);
743 else if (opcode
->flags
& VIF_OPCODE_DIRECT
)
745 record_mach (DVP_GIF
, 1);
746 set_asm_state (ASM_DIRECT
);
747 byte_len
= insert_file (file
, NULL
, 0, 0);
750 else if (opcode
->flags
& VIF_OPCODE_UNPACK
)
752 int max_len
= 0; /*unpack_max_byte_len (insn_buf[0]);*/
753 set_asm_state (ASM_UNPACK
);
754 byte_len
= insert_file (file
, NULL
/*insert_unpack_marker*/,
755 insn_buf
[0], max_len
);
759 as_fatal ("internal error: unknown cpu type for variable length vif insn");
761 else /* file == NULL */
763 /* data_len == -1 means the value must be computed from
766 as_bad ("invalid data length");
768 if (output_vif
&& data_len
!= -1)
769 install_vif_length (f
, data_len
);
771 if (opcode
->flags
& VIF_OPCODE_MPG
)
773 set_asm_state (ASM_MPG
);
774 /* Enable automatic mpg insertion every 256 insns. */
777 else if (opcode
->flags
& VIF_OPCODE_DIRECT
)
778 set_asm_state (ASM_DIRECT
);
779 else if (opcode
->flags
& VIF_OPCODE_UNPACK
)
780 set_asm_state (ASM_UNPACK
);
785 /* Subroutine of md_assemble to assemble GIF instructions. */
791 DVP_INSN insn_buf
[4];
792 const dvp_opcode
*opcode
;
796 insn_buf
[0] = insn_buf
[1] = insn_buf
[2] = insn_buf
[3] = 0;
798 opcode
= assemble_one_insn (DVP_GIF
,
799 gif_opcode_lookup_asm (str
), gif_operands
,
804 /* Do an implicit alignment to a 16 byte boundary. */
805 frag_align (4, 0, 0);
806 record_alignment (now_seg
, 4);
808 /* Insert a label so we can compute the number of quadwords when the
809 .endgif is seen. This is put before the mach type label because gif
810 insns are followed by data and we don't want the disassembler to try
811 to disassemble them as mips insns (since it uses the st_other field)
812 of the closest label to choose the mach type and since we don't have
813 a special st_other value for "data". */
814 gif_data_name
= S_GET_NAME (create_colon_label (0, LOCAL_LABEL_PREFIX
,
815 unique_name ("gifdata")));
817 record_mach (DVP_GIF
, 1);
819 gif_insn_frag_loc
= f
= frag_more (16);
820 gif_insn_frag
= frag_now
;
821 for (i
= 0; i
< 4; ++i
)
822 md_number_to_chars (f
+ i
* 4, insn_buf
[i
], 4);
824 /* Record the type of the gif tag so we know how to compute nloop
826 if (strcmp (opcode
->mnemonic
, "gifpacked") == 0)
827 gif_insn_type
= GIF_PACKED
;
828 else if (strcmp (opcode
->mnemonic
, "gifreglist") == 0)
829 gif_insn_type
= GIF_REGLIST
;
830 else if (strcmp (opcode
->mnemonic
, "gifimage") == 0)
831 gif_insn_type
= GIF_IMAGE
;
834 push_asm_state (ASM_GIF
);
837 /* Subroutine of md_assemble to assemble VU instructions. */
844 const dvp_opcode
*opcode
;
846 /* Handle automatic mpg insertion if enabled. */
847 if (CUR_ASM_STATE
== ASM_MPG
849 insert_mpg_marker (0);
851 /* Do an implicit alignment to a 8 byte boundary. */
852 frag_align (3, 0, 0);
853 record_alignment (now_seg
, 3);
855 record_mach (DVP_VUUP
, 0);
857 /* The lower instruction has the lower address.
858 Handle this by grabbing 8 bytes now, and then filling each word
862 #ifdef VERTICAL_BAR_SEPARATOR
863 char *p
= strchr (str
, '|');
867 as_bad ("lower slot missing in `%s'", str
);
872 opcode
= assemble_vu_insn (DVP_VUUP
,
873 vu_upper_opcode_lookup_asm (str
), vu_operands
,
878 opcode
= assemble_vu_insn (DVP_VUUP
,
879 vu_upper_opcode_lookup_asm (str
), vu_operands
,
883 /* Don't assemble next one if we couldn't assemble the first. */
886 opcode
= assemble_vu_insn (DVP_VULO
,
887 vu_lower_opcode_lookup_asm (str
), vu_operands
,
889 /* If this was the "loi" pseudo-insn, we need to set the `i' bit. */
892 if (strcmp (opcode
->mnemonic
, "loi") == 0)
896 /* Increment the vu insn counter.
897 If get reach 256 we need to insert an `mpg'. */
901 static const dvp_opcode
*
902 assemble_vu_insn (cpu
, opcode
, operand_table
, pstr
, buf
)
904 const dvp_opcode
*opcode
;
905 const dvp_operand
*operand_table
;
912 opcode
= assemble_one_insn (cpu
, opcode
, operand_table
, pstr
, &insn
);
916 /* Write out the instruction.
917 Reminder: it is important to fetch enough space in one call to
918 `frag_more'. We use (f - frag_now->fr_literal) to compute where
919 we are and we don't want frag_now to change between calls. */
920 md_number_to_chars (buf
, insn
, 4);
922 /* Create any fixups. */
923 for (i
= 0; i
< fixup_count
; ++i
)
925 int op_type
, reloc_type
;
926 const dvp_operand
*operand
;
928 /* Create a fixup for this operand.
929 At this point we do not use a bfd_reloc_code_real_type for
930 operands residing in the insn, but instead just use the
931 operand index. This lets us easily handle fixups for any
932 operand type, although that is admittedly not a very exciting
933 feature. We pick a BFD reloc type in md_apply_fix. */
935 op_type
= fixups
[i
].opindex
;
936 reloc_type
= encode_fixup_reloc_type (cpu
, op_type
);
937 operand
= &vu_operands
[op_type
];
938 fix_new_exp (frag_now
, buf
- frag_now
->fr_literal
, 4,
940 (operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0,
941 (bfd_reloc_code_real_type
) reloc_type
);
948 /* Assemble one instruction at *PSTR.
949 CPU indicates what component we're assembling for.
950 The assembled instruction is stored in INSN_BUF.
951 OPCODE is a pointer to the head of the hash chain.
953 *PSTR is updated to point passed the parsed instruction.
955 If the insn is successfully parsed the result is a pointer to the opcode
956 entry that successfully matched and *PSTR is updated to point passed
957 the parsed insn. If an error occurs the result is NULL and *PSTR is left
958 at some random point in the string (??? may wish to leave it pointing where
959 the error occured). */
961 static const dvp_opcode
*
962 assemble_one_insn (cpu
, opcode
, operand_table
, pstr
, insn_buf
)
964 const dvp_opcode
*opcode
;
965 const dvp_operand
*operand_table
;
971 /* Keep looking until we find a match. */
974 for ( ; opcode
!= NULL
; opcode
= DVP_OPCODE_NEXT_ASM (opcode
))
976 int past_opcode_p
, num_suffixes
;
977 const unsigned char *syn
;
979 /* Ensure the mnemonic part matches. */
980 for (str
= start
, syn
= opcode
->mnemonic
; *syn
!= '\0'; ++str
, ++syn
)
981 if (tolower (*str
) != tolower (*syn
))
986 /* Scan the syntax string. If it doesn't match, try the next one. */
988 dvp_opcode_init_parse ();
989 insn_buf
[opcode
->opcode_word
] = opcode
->value
;
994 /* We don't check for (*str != '\0') here because we want to parse
995 any trailing fake arguments in the syntax string. */
996 for (/*str = start, */ syn
= opcode
->syntax
; *syn
!= '\0'; )
999 const dvp_operand
*operand
;
1003 /* Non operand chars must match exactly.
1004 Operand chars that are letters are not part of symbols
1005 and are case insensitive. */
1008 if (tolower (*str
) == tolower (*syn
))
1020 /* We have a suffix or an operand. Pick out any modifiers. */
1022 index
= DVP_OPERAND_INDEX (*syn
);
1023 while (DVP_MOD_P (operand_table
[index
].flags
))
1025 mods
|= operand_table
[index
].flags
& DVP_MOD_BITS
;
1027 index
= DVP_OPERAND_INDEX (*syn
);
1029 operand
= operand_table
+ index
;
1031 if (operand
->flags
& DVP_OPERAND_FAKE
)
1035 if (operand
->flags
& DVP_OPERAND_DMA_INLINE
)
1037 inline_dma_data ((mods
& DVP_OPERAND_AUTOCOUNT
) != 0,
1046 value
= (*operand
->parse
) (opcode
, operand
, mods
,
1051 if (operand
->insert
)
1054 (*operand
->insert
) (opcode
, operand
, mods
, insn_buf
,
1055 (offsetT
) value
, &errmsg
);
1056 /* If we get an error, go on to try the next insn. */
1064 /* Are we finished with suffixes? */
1069 if (!(operand
->flags
& DVP_OPERAND_SUFFIX
))
1070 as_fatal ("internal error: bad opcode table, missing suffix flag");
1072 /* If we're at a space in the input string, we want to skip the
1073 remaining suffixes. There may be some fake ones though, so
1074 just go on to try the next one. */
1081 /* Parse the suffix. */
1083 suf_value
= (*operand
->parse
) (opcode
, operand
, mods
, &str
,
1087 /* This can happen, for example, in ARC's in "blle foo" and
1088 we're currently using the template "b%q%.n %j". The "bl"
1089 insn occurs later in the table so "lle" isn't an illegal
1094 /* Insert the suffix's value into the insn. */
1095 insert_operand (cpu
, opcode
, operand
, mods
, insn_buf
,
1096 (offsetT
) suf_value
, &errmsg
);
1102 /* This is an operand, either a register or an expression of
1107 if (operand
->flags
& DVP_OPERAND_SUFFIX
)
1108 as_fatal ("internal error: bad opcode table, suffix wrong");
1110 /* Is there anything left to parse?
1111 We don't check for this at the top because we want to parse
1112 any trailing fake arguments in the syntax string. */
1113 /* ??? This doesn't allow operands with a legal value of "". */
1117 /* Parse the operand. */
1118 if (operand
->flags
& DVP_OPERAND_FLOAT
)
1121 value
= parse_float (&str
, &errmsg
);
1125 else if ((operand
->flags
& DVP_OPERAND_DMA_ADDR
)
1126 && (mods
& DVP_OPERAND_AUTOCOUNT
))
1129 value
= parse_dma_addr_autocount (opcode
, operand
, mods
,
1130 insn_buf
, &str
, &errmsg
);
1136 char *origstr
,*hold
;
1139 /* First see if there is a special parser. */
1144 value
= (*operand
->parse
) (opcode
, operand
, mods
,
1150 /* If there wasn't a special parser, or there was and it
1151 left the input stream unchanged, use the general
1152 expression parser. */
1155 hold
= input_line_pointer
;
1156 input_line_pointer
= str
;
1157 /* Set cur_{opcode,operand} for md_operand. */
1158 cur_opcode
= opcode
;
1159 cur_operand
= operand
;
1162 str
= input_line_pointer
;
1163 input_line_pointer
= hold
;
1165 if (exp
.X_op
== O_illegal
1166 || exp
.X_op
== O_absent
)
1168 else if (exp
.X_op
== O_constant
)
1169 value
= exp
.X_add_number
;
1170 else if (exp
.X_op
== O_register
)
1171 as_fatal ("internal error: got O_register");
1174 /* We need to generate a fixup for this expression. */
1175 if (fixup_count
>= MAX_FIXUPS
)
1176 as_fatal ("internal error: too many fixups");
1177 fixups
[fixup_count
].exp
= exp
;
1178 fixups
[fixup_count
].opindex
= index
;
1179 /* FIXME: Revisit. Do we really need operand->word?
1180 The endianness of a 128 bit DMAtag is rather
1181 twisted. How about defining word 0 as the word with
1182 the lowest address and basing operand-shift off that.
1183 operand->word could then be deleted. */
1184 if (operand
->word
!= 0)
1185 fixups
[fixup_count
].offset
= operand
->word
* 4;
1187 fixups
[fixup_count
].offset
= (operand
->shift
/ 32) * 4;
1194 /* Insert the register or expression into the instruction. */
1196 insert_operand (cpu
, opcode
, operand
, mods
, insn_buf
,
1197 (offsetT
) value
, &errmsg
);
1198 if (errmsg
!= (const char *) NULL
)
1204 /* If we're at the end of the syntax string, we're done. */
1209 /* For the moment we assume a valid `str' can only contain blanks
1210 now. IE: We needn't try again with a longer version of the
1211 insn and it is assumed that longer versions of insns appear
1212 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
1214 while (isspace (*str
))
1218 #ifndef VERTICAL_BAR_SEPARATOR
1222 as_bad ("junk at end of line: `%s'", str
);
1224 /* It's now up to the caller to emit the instruction and any
1230 /* Try the next entry. */
1233 as_bad ("bad instruction `%s'", start
);
1237 /* Given a dvp cpu type, return it's STO_DVP value.
1238 The label prefix to use is stored in *PNAME. */
1241 cpu_sto (cpu
, pname
)
1247 case DVP_DMA
: *pname
= ".dma."; return STO_DVP_DMA
;
1248 case DVP_VIF
: *pname
= ".vif."; return STO_DVP_VIF
;
1249 case DVP_GIF
: *pname
= ".gif."; return STO_DVP_GIF
;
1250 case DVP_VUUP
: *pname
= ".vu."; return STO_DVP_VU
;
1255 /* Record the current mach type in the object file.
1256 If FORCE_NEXT_P is non-zero, force a label to be emitted the next time
1257 we're called. This is useful for variable length instructions that can
1258 have labels embedded within them. */
1261 record_mach (cpu
, force_next_p
)
1272 sto
= cpu_sto (cpu
, &name
);
1274 label
= create_colon_label (sto
, "", unique_name (name
));
1277 cur_cpu
= DVP_UNKNOWN
;
1282 /* Force emission of mach type label at next insn.
1283 This isn't static as TC_START_LABEL uses it.
1284 The result is the value of TC_START_LABEL. */
1289 cur_cpu
= DVP_UNKNOWN
;
1293 /* Push/pop the current parsing state. */
1296 push_asm_state (new_state
)
1297 asm_state new_state
;
1300 if (cur_state_index
== MAX_STATE_DEPTH
)
1301 as_fatal ("internal error: unexpected state push");
1302 asm_state_stack
[cur_state_index
] = new_state
;
1305 /* TOP_OK_P is non-zero if it's ok that we're at the top of the stack.
1306 This happens if there are errors in the assembler code.
1307 We just reset the stack to its "init" state. */
1310 pop_asm_state (top_ok_p
)
1313 if (cur_state_index
== 0)
1316 asm_state_stack
[cur_state_index
] = ASM_INIT
;
1318 as_fatal ("internal error: unexpected state pop");
1325 set_asm_state (state
)
1328 CUR_ASM_STATE
= state
;
1332 md_operand (expressionP
)
1333 expressionS
*expressionP
;
1335 /* Check if this is a '*' for mpgloc. */
1337 && (cur_opcode
->flags
& VIF_OPCODE_MPG
) != 0
1338 && (cur_operand
->flags
& DVP_OPERAND_VU_ADDRESS
) != 0
1339 && *input_line_pointer
== '*')
1341 expressionP
->X_op
= O_symbol
;
1342 expressionP
->X_add_symbol
= mpgloc_sym
;
1343 expressionP
->X_add_number
= 0;
1345 /* Advance over the '*'. */
1346 ++input_line_pointer
;
1348 /* Check if this is a '*' for unpackloc. */
1350 && (cur_opcode
->flags
& VIF_OPCODE_UNPACK
) != 0
1351 && (cur_operand
->flags
& DVP_OPERAND_UNPACK_ADDRESS
) != 0
1352 && *input_line_pointer
== '*')
1354 expressionP
->X_op
= O_symbol
;
1355 expressionP
->X_add_symbol
= unpackloc_sym
;
1356 expressionP
->X_add_number
= 0;
1358 /* Advance over the '*'. */
1359 ++input_line_pointer
;
1364 md_section_align (segment
, size
)
1368 int align
= bfd_get_section_alignment (stdoutput
, segment
);
1369 return ((size
+ (1 << align
) - 1) & (-1 << align
));
1373 md_undefined_symbol (name
)
1379 /* Called after parsing the file via md_after_pass_hook. */
1382 dvp_after_pass_hook ()
1384 /* If doing dma packing, ensure the last dma tag is filled out. */
1387 /* Nothing to do as vifnops are zero and frag_align at beginning
1388 of dmatag is all we need. */
1391 #if 0 /* ??? Doesn't work unless we keep track of the nested include file
1393 /* Check for missing .EndMpg, and supply one if necessary. */
1394 if (CUR_ASM_STATE
== ASM_MPG
)
1395 s_endmpg (ENDMPG_INTERNAL
);
1396 else if (CUR_ASM_STATE
== ASM_DIRECT
)
1398 else if (CUR_ASM_STATE
== ASM_UNPACK
)
1403 /* Called when a label is defined via tc_frob_label. */
1406 dvp_frob_label (sym
)
1409 /* All labels in vu code must be specially marked for the disassembler.
1410 The disassembler ignores all previous information at each new label
1411 (that has a higher address than the last one). */
1412 if (CUR_ASM_STATE
== ASM_MPG
1413 || CUR_ASM_STATE
== ASM_VU
)
1414 S_SET_OTHER (sym
, STO_DVP_VU
);
1417 /* mpg/direct alignment is handled via relaxation */
1419 /* Return an initial guess of the length by which a fragment must grow to
1420 hold a branch to reach its destination.
1421 Also updates fr_type/fr_subtype as necessary.
1423 Called just before doing relaxation.
1424 Any symbol that is now undefined will not become defined.
1425 The guess for fr_var is ACTUALLY the growth beyond fr_fix.
1426 Whatever we do to grow fr_fix or fr_var contributes to our returned value.
1427 Although it may not be explicit in the frag, pretend fr_var starts with a
1431 md_estimate_size_before_relax (fragP
, segment
)
1435 /* Our initial estimate is always 0. */
1439 /* Perform the relaxation.
1440 All we have to do is figure out how many bytes we need to insert to
1441 get to the recorded symbol (which is at the required alignment). */
1444 dvp_relax_frag (fragP
, stretch
)
1448 /* Address of variable part. */
1449 long address
= fragP
->fr_address
+ fragP
->fr_fix
;
1450 /* Symbol marking start of data. */
1451 symbolS
* symbolP
= fragP
->fr_symbol
;
1452 /* Address of the symbol. */
1453 long target
= S_GET_VALUE (symbolP
) + symbolP
->sy_frag
->fr_address
;
1456 /* subtype >= 10 means "done" */
1457 if (fragP
->fr_subtype
>= 10)
1460 /* subtype 1 = mpg */
1461 if (fragP
->fr_subtype
== 1)
1463 growth
= target
- address
;
1465 as_fatal ("internal error: bad mpg alignment handling");
1466 fragP
->fr_subtype
= 10 + growth
;
1470 /* subtype 2 = direct */
1471 if (fragP
->fr_subtype
== 2)
1473 growth
= target
- address
;
1475 as_fatal ("internal error: bad direct alignment handling");
1476 fragP
->fr_subtype
= 10 + growth
;
1480 as_fatal ("internal error: unknown fr_subtype");
1483 /* *fragP has been relaxed to its final size, and now needs to have
1484 the bytes inside it modified to conform to the new size.
1486 Called after relaxation is finished.
1487 fragP->fr_type == rs_machine_dependent.
1488 fragP->fr_subtype is the subtype of what the address relaxed to. */
1491 md_convert_frag (abfd
, sec
, fragP
)
1496 int growth
= fragP
->fr_subtype
- 10;
1498 fragP
->fr_fix
+= growth
;
1502 /* We had to grow this fragment. Shift the mpg/direct insn to the end
1503 (so it abuts the following data). */
1504 DVP_INSN insn
= bfd_getl32 (fragP
->fr_opcode
);
1505 md_number_to_chars (fragP
->fr_opcode
, VIFNOP
, 4);
1507 md_number_to_chars (fragP
->fr_opcode
, VIFNOP
, 8);
1508 md_number_to_chars (fragP
->fr_literal
+ fragP
->fr_fix
- 4, insn
, 4);
1510 /* Adjust fr_opcode so md_apply_fix3 works with the right bytes. */
1511 fragP
->fr_opcode
+= growth
;
1515 /* Functions concerning relocs. */
1517 /* Spacing between each cpu type's operand numbers.
1518 Should be at least as big as any operand table. */
1519 #define RELOC_SPACING 256
1521 /* Given a cpu type and operand number, return a temporary reloc type
1522 for use in generating the fixup that encodes the cpu type and operand
1526 encode_fixup_reloc_type (cpu
, opnum
)
1530 return (int) BFD_RELOC_UNUSED
+ ((int) cpu
* RELOC_SPACING
) + opnum
;
1533 /* Given a fixup reloc type, decode it into cpu type and operand. */
1536 decode_fixup_reloc_type (fixup_reloc
, cpuP
, operandP
)
1539 const dvp_operand
**operandP
;
1541 dvp_cpu cpu
= (fixup_reloc
- (int) BFD_RELOC_UNUSED
) / RELOC_SPACING
;
1542 int opnum
= (fixup_reloc
- (int) BFD_RELOC_UNUSED
) % RELOC_SPACING
;
1547 case DVP_VUUP
: *operandP
= &vu_operands
[opnum
]; break;
1548 case DVP_VULO
: *operandP
= &vu_operands
[opnum
]; break;
1549 case DVP_DMA
: *operandP
= &dma_operands
[opnum
]; break;
1550 case DVP_VIF
: *operandP
= &vif_operands
[opnum
]; break;
1551 case DVP_GIF
: *operandP
= &gif_operands
[opnum
]; break;
1552 default : as_fatal ("internal error: bad fixup encoding");
1556 /* Given a fixup reloc type, return a pointer to the operand
1558 /* The location from which a PC relative jump should be calculated,
1559 given a PC relative reloc. */
1562 md_pcrel_from_section (fixP
, sec
)
1566 if (fixP
->fx_addsy
!= (symbolS
*) NULL
1567 && (! S_IS_DEFINED (fixP
->fx_addsy
)
1568 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
1570 /* If fx_tcbit is set this is for a vif insn and thus should never
1571 happen in correct code. */
1572 /* ??? The error message could be a bit more descriptive. */
1574 as_bad ("unable to compute length of vif insn");
1575 /* The symbol is undefined (or is defined but not in this section).
1576 Let the linker figure it out. +8: branch offsets are relative to the
1581 /* If fx_tcbit is set, this is a vif end-of-variable-length-insn marker.
1582 In this case the offset is relative to the start of data.
1583 Otherwise we assume this is a vu branch. In this case
1584 offsets are calculated based on the address of the next insn. */
1587 /* As a further refinement, if fr_opcode is NULL this is `unpack'
1588 which doesn't involve any relaxing. */
1589 if (fixP
->fx_frag
->fr_opcode
== NULL
)
1590 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ 4;
1592 return fixP
->fx_frag
->fr_address
+ fixP
->fx_frag
->fr_fix
;
1595 return ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
) & -8L) + 8;
1598 /* Apply a fixup to the object code. This is called for all the
1599 fixups we generated by calls to fix_new_exp. At this point all symbol
1600 values should be fully resolved, and we attempt to completely resolve the
1601 reloc. If we can not do that, we determine the correct reloc code and put
1602 it back in the fixup. */
1605 md_apply_fix3 (fixP
, valueP
, seg
)
1610 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1613 /* FIXME FIXME FIXME: The value we are passed in *valueP includes
1614 the symbol values. Since we are using BFD_ASSEMBLER, if we are
1615 doing this relocation the code in write.c is going to call
1616 bfd_perform_relocation, which is also going to use the symbol
1617 value. That means that if the reloc is fully resolved we want to
1618 use *valueP since bfd_perform_relocation is not being used.
1619 However, if the reloc is not fully resolved we do not want to use
1620 *valueP, and must use fx_offset instead. However, if the reloc
1621 is PC relative, we do want to use *valueP since it includes the
1622 result of md_pcrel_from. This is confusing. */
1624 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
1629 else if (fixP
->fx_pcrel
)
1635 value
= fixP
->fx_offset
;
1636 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
1638 if (S_GET_SEGMENT (fixP
->fx_subsy
) == absolute_section
)
1639 value
-= S_GET_VALUE (fixP
->fx_subsy
);
1642 /* We can't actually support subtracting a symbol. */
1643 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1644 "expression too complex");
1649 /* Check for dvp operands. These are indicated with a reloc value
1650 >= BFD_RELOC_UNUSED. */
1652 if ((int) fixP
->fx_r_type
>= (int) BFD_RELOC_UNUSED
)
1655 const dvp_operand
*operand
;
1657 fragS
*fragP
= fixP
->fx_frag
;
1659 /* If this was a relaxable insn, the opcode may have moved. Find it. */
1660 if (fragP
->fr_opcode
!= NULL
)
1661 where
= fragP
->fr_opcode
;
1663 decode_fixup_reloc_type ((int) fixP
->fx_r_type
,
1666 /* For variable length vif insn data lengths, validate the user specified
1667 value or install the computed value in the instruction. */
1669 && (operand
- vif_operands
) == vif_operand_datalen_special
)
1671 value
= vif_length_value (where
[3],
1672 fixP
->tc_fix_data
.wl
, fixP
->tc_fix_data
.cl
,
1674 if (fixP
->tc_fix_data
.user_value
!= -1)
1676 if (fixP
->tc_fix_data
.user_value
!= value
)
1677 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
1678 "specified length value doesn't match computed value");
1679 /* Don't override the user specified value. */
1685 install_vif_length (where
, value
);
1692 /* For the gif nloop operand, if it was specified by the user ensure
1693 it matches the value we computed. */
1695 && (operand
- gif_operands
) == gif_operand_nloop
)
1697 value
= compute_nloop (fixP
->tc_fix_data
.type
,
1698 fixP
->tc_fix_data
.nregs
,
1700 if (fixP
->tc_fix_data
.user_value
!= -1)
1702 check_nloop (fixP
->tc_fix_data
.type
,
1703 fixP
->tc_fix_data
.nregs
,
1704 fixP
->tc_fix_data
.user_value
,
1706 fixP
->fx_file
, fixP
->fx_line
);
1707 /* Don't override the user specified value. */
1713 /* Fetch the instruction, insert the fully resolved operand
1714 value, and stuff the instruction back again. The fixup is recorded
1715 at the appropriate word so pass DVP_MOD_THIS_WORD so any offset
1716 specified in the tables is ignored. */
1717 insn
= bfd_getl32 ((unsigned char *) where
);
1718 insert_operand_final (cpu
, operand
, DVP_MOD_THIS_WORD
, &insn
,
1719 (offsetT
) value
, fixP
->fx_file
, fixP
->fx_line
);
1720 bfd_putl32 ((bfd_vma
) insn
, (unsigned char *) where
);
1722 /* If this is mpgloc/unpackloc, we're done. */
1723 if (operand
->flags
& (DVP_OPERAND_VU_ADDRESS
| DVP_OPERAND_UNPACK_ADDRESS
))
1728 /* Nothing else to do here. */
1732 /* Determine a BFD reloc value based on the operand information.
1733 We are only prepared to turn a few of the operands into relocs. */
1734 /* FIXME: This test is a hack. */
1735 if ((operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0)
1737 assert (operand
->bits
== 11
1738 && operand
->shift
== 0);
1739 fixP
->fx_r_type
= BFD_RELOC_MIPS_DVP_11_PCREL
;
1741 else if ((operand
->flags
& DVP_OPERAND_DMA_ADDR
) != 0
1742 || (operand
->flags
& DVP_OPERAND_DMA_NEXT
) != 0)
1744 assert (operand
->bits
== 27
1745 && operand
->shift
== 4);
1746 fixP
->fx_r_type
= BFD_RELOC_MIPS_DVP_27_S4
;
1750 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1751 "unresolved expression that must be resolved");
1758 switch (fixP
->fx_r_type
)
1761 md_number_to_chars (where
, value
, 1);
1764 md_number_to_chars (where
, value
, 2);
1767 md_number_to_chars (where
, value
, 4);
1770 as_fatal ("internal error: unexpected fixup");
1774 fixP
->fx_addnumber
= value
;
1779 /* Translate internal representation of relocation info to BFD target
1783 tc_gen_reloc (section
, fixP
)
1789 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1791 reloc
->sym_ptr_ptr
= &fixP
->fx_addsy
->bsym
;
1792 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
1793 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
1794 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
1796 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1797 "internal error: can't export reloc type %d (`%s')",
1798 fixP
->fx_r_type
, bfd_get_reloc_code_name (fixP
->fx_r_type
));
1802 assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1804 reloc
->addend
= fixP
->fx_addnumber
;
1809 /* Write a value out to the object file, using the appropriate endianness. */
1812 md_number_to_chars (buf
, val
, n
)
1817 if (target_big_endian
)
1818 number_to_chars_bigendian (buf
, val
, n
);
1820 number_to_chars_littleendian (buf
, val
, n
);
1823 /* Turn a string in input_line_pointer into a floating point constant of type
1824 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1825 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
1828 /* Equal to MAX_PRECISION in atof-ieee.c */
1829 #define MAX_LITTLENUMS 6
1832 md_atof (type
, litP
, sizeP
)
1838 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1839 LITTLENUM_TYPE
*wordP
;
1859 /* FIXME: Some targets allow other format chars for bigger sizes here. */
1863 return "Bad call to md_atof()";
1866 t
= atof_ieee (input_line_pointer
, type
, words
);
1868 input_line_pointer
= t
;
1869 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1871 if (target_big_endian
)
1873 for (i
= 0; i
< prec
; i
++)
1875 md_number_to_chars (litP
, (valueT
) words
[i
], sizeof (LITTLENUM_TYPE
));
1876 litP
+= sizeof (LITTLENUM_TYPE
);
1881 for (i
= prec
- 1; i
>= 0; i
--)
1883 md_number_to_chars (litP
, (valueT
) words
[i
], sizeof (LITTLENUM_TYPE
));
1884 litP
+= sizeof (LITTLENUM_TYPE
);
1891 /* Miscellaneous utilities. */
1893 /* Parse a 32 bit floating point number.
1894 The result is those 32 bits as an integer. */
1897 parse_float (pstr
, errmsg
)
1899 const char **errmsg
;
1901 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1904 p
= atof_ieee (*pstr
, 'f', words
);
1906 return (words
[0] << 16) | words
[1];
1909 /* Scan a symbol and return a pointer to one past the end. */
1911 #define issymchar(ch) (isalnum(ch) || ch == '_')
1916 while (*sym
&& issymchar (*sym
))
1921 /* Evaluate an expression for an operand.
1922 The result is the value of the expression if it can be evaluated,
1923 or 0 if it cannot (say because some symbols haven't been defined yet)
1924 in which case a fixup is queued.
1926 If OPINDEX is 0, don't queue any fixups, just return 0. */
1930 eval_expr (int opindex
, int offset
, const char *fmt
, ...)
1932 eval_expr (opindex
, offset
, fmt
, va_alist
)
1940 char *str
,*save_input
;
1948 vasprintf (&str
, fmt
, ap
);
1951 save_input
= input_line_pointer
;
1952 input_line_pointer
= str
;
1954 input_line_pointer
= save_input
;
1956 if (exp
.X_op
== O_constant
)
1957 value
= exp
.X_add_number
;
1962 fixups
[fixup_count
].exp
= exp
;
1963 fixups
[fixup_count
].opindex
= opindex
;
1964 fixups
[fixup_count
].offset
= offset
;
1965 fixups
[fixup_count
].user_value
= -1;
1966 fixups
[fixup_count
].wl
= -1;
1967 fixups
[fixup_count
].cl
= -1;
1975 /* Create a label named by concatenating PREFIX to NAME. */
1978 create_label (prefix
, name
)
1979 const char *prefix
, *name
;
1981 int namelen
= strlen (name
);
1982 int prefixlen
= strlen (prefix
);
1986 fullname
= xmalloc (prefixlen
+ namelen
+ 1);
1987 strcpy (fullname
, prefix
);
1988 strcat (fullname
, name
);
1989 result
= symbol_find_or_make (fullname
);
1994 /* Create a label named by concatenating PREFIX to NAME,
1995 and define it as `.'.
1996 STO, if non-zero, is the st_other value to assign to this label.
1997 If STO is zero `cur_cpu', call force_mach_label to force record_mach to
1998 emit a cpu label. Otherwise the disassembler gets confused. */
2001 create_colon_label (sto
, prefix
, name
)
2003 const char *prefix
, *name
;
2005 int namelen
= strlen (name
);
2006 int prefixlen
= strlen (prefix
);
2010 fullname
= xmalloc (prefixlen
+ namelen
+ 1);
2011 strcpy (fullname
, prefix
);
2012 strcat (fullname
, name
);
2013 result
= colon (fullname
);
2015 S_SET_OTHER (result
, sto
);
2017 force_mach_label ();
2022 /* Return a malloc'd string useful in creating unique labels.
2023 PREFIX is the prefix to use or NULL if we're to pick one. */
2026 unique_name (prefix
)
2033 prefix
= UNIQUE_LABEL_PREFIX
;
2034 asprintf (&result
, "%s%d", prefix
, counter
);
2039 /* Compute a value for nloop. */
2042 compute_nloop (type
, nregs
, bytes
)
2051 /* We can't compute a value if no regs were specified and there is a
2052 non-zero amount of data. Just set to something useful, a warning
2053 will be issued later. */
2056 computed_nloop
= (bytes
>> 4) / nregs
;
2061 computed_nloop
= (bytes
>> 3) / nregs
;
2064 computed_nloop
= bytes
>> 4;
2068 return computed_nloop
;
2071 /* Issue a warning if the user specified nloop value doesn't match the
2075 check_nloop (type
, nregs
, user_nloop
, computed_nloop
, file
, line
)
2077 int nregs
,user_nloop
,computed_nloop
;
2081 if (user_nloop
!= computed_nloop
)
2082 as_warn_where (file
, line
, "nloop value does not match amount of data");
2085 /* Compute the auto-count value for a DMA tag.
2086 INLINE_P is non-zero if the dma data is inline. */
2089 setup_dma_autocount (name
, insn_buf
, inline_p
)
2098 /* -1: The count is the number of following quadwords, so skip the one
2099 containing the dma tag. */
2100 count
= eval_expr (dma_operand_count
, 0,
2101 "((%s%s - %s) >> 4) - 1", END_LABEL_PREFIX
, name
, name
);
2105 /* We don't want to subtract 1 here as the begin and end labels
2106 properly surround the data we want to compute the length of. */
2107 count
= eval_expr (dma_operand_count
, 0,
2108 "(%s%s - %s) >> 4", END_LABEL_PREFIX
, name
, name
);
2111 /* Store the count field. */
2112 insn_buf
[0] &= 0xffff0000;
2113 insn_buf
[0] |= count
& 0x0000ffff;
2116 /* Record that inline data follows. */
2119 inline_dma_data (autocount_p
, insn_buf
)
2123 if (dma_data_state
!= 0 )
2125 as_bad ("DmaData blocks cannot be nested.");
2133 dma_data_name
= S_GET_NAME (create_colon_label (0, "", unique_name (NULL
)));
2134 setup_dma_autocount (dma_data_name
, insn_buf
, 1);
2140 /* Compute the auto-count value for a DMA tag with out-of-line data. */
2143 parse_dma_addr_autocount (opcode
, operand
, mods
, insn_buf
, pstr
, errmsg
)
2144 const dvp_opcode
*opcode
;
2145 const dvp_operand
*operand
;
2149 const char **errmsg
;
2151 char *start
= *pstr
;
2154 /* Data reference must be a .DmaData label. */
2155 symbolS
*label
, *label2
, *endlabel
;
2160 if (! is_name_beginner (*start
))
2162 *errmsg
= "invalid .DmaData label";
2167 end
= scan_symbol (name
);
2170 label
= symbol_find_or_make (name
);
2173 label2
= create_label ("_$", name
);
2174 endlabel
= create_label (END_LABEL_PREFIX
, name
);
2176 retval
= eval_expr (dma_operand_addr
, 4, name
);
2178 setup_dma_autocount (name
, insn_buf
, 0);
2184 /* Return the length value to insert in a VIF instruction whose upper
2185 byte is CMD and whose data length is BYTES.
2186 WL,CL are used for unpack insns and are the stcycl values in effect.
2187 This does not do the max -> 0 conversion. */
2190 vif_length_value (cmd
, wl
, cl
, bytes
)
2197 case 0x50 : /* direct */
2198 /* ??? Worry about data /= 16 cuts off? */
2200 case 0x40 : /* mpg */
2201 /* ??? Worry about data /= 8 cuts off? */
2203 case 0x60 : /* unpack */
2205 return vif_unpack_len_value (cmd
& 15, wl
, cl
, bytes
);
2207 as_fatal ("internal error: bad call to vif_length_value");
2211 /* Install length LEN in the vif insn at BUF.
2212 LEN is the actual value to store, except that the max->0 conversion
2213 hasn't been done (we do it).
2214 The bytes in BUF are in target order. */
2217 install_vif_length (buf
, len
)
2221 unsigned char cmd
= buf
[3];
2223 if ((cmd
& 0x70) == 0x40)
2227 as_bad ("`mpg' data length must be between 1 and 256");
2228 buf
[2] = len
== 256 ? 0 : len
;
2230 else if ((cmd
& 0x70) == 0x50)
2232 /* direct/directhl */
2234 as_bad ("`direct' data length must be between 1 and 65536");
2235 len
= len
== 65536 ? 0 : len
;
2239 else if ((cmd
& 0x60) == 0x60)
2242 /* len == -1 means wl,cl are unknown and thus we can't compute
2246 as_bad ("missing `stcycle', can't compute length of `unpack' insn");
2249 if (len
< 0 || len
> 256)
2250 as_bad ("`unpack' data length must be between 0 and 256");
2251 /* 256 is recorded as 0 in the insn */
2252 len
= len
== 256 ? 0 : len
;
2256 as_fatal ("internal error: bad call to install_vif_length");
2259 /* Finish off the current set of mpg insns, and start a new set.
2260 The IGNORE arg exists because insert_unpack_marker uses it and both
2261 of these functions are passed to insert_file. */
2264 insert_mpg_marker (ignore
)
2265 unsigned long ignore
;
2267 s_endmpg (ENDMPG_MIDDLE
);
2268 /* mpgloc is updated by s_endmpg. */
2269 md_assemble ("mpg *,*");
2270 /* Record the cpu type in case we're in the middle of reading binary
2272 record_mach (DVP_VUUP
, 0);
2275 /* Finish off the current unpack insn and start a new one.
2276 INSN0 is the first word of the insn and is used to figure out what
2277 kind of unpack insn it is. */
2280 insert_unpack_marker (insn0
)
2281 unsigned long insn0
;
2285 /* Insert a file into the output.
2286 The -I arg passed to GAS is used to specify where to find the file.
2287 INSERT_MARKER if non-NULL is called every SIZE bytes with an argument of
2288 INSERT_MARKER_ARG. This is used by the mpg insn to insert mpg's every 256
2289 insns and by the unpack insn.
2290 The result is the number of bytes inserted.
2291 If an error occurs an error message is printed and zero is returned. */
2294 insert_file (file
, insert_marker
, insert_marker_arg
, size
)
2296 void (*insert_marker
) PARAMS ((unsigned long));
2297 unsigned long insert_marker_arg
;
2302 int i
, n
, total
, left_before_marker
;
2305 path
= xmalloc (strlen (file
) + include_dir_maxlen
+ 5 /*slop*/);
2307 for (i
= 0; i
< include_dir_count
; i
++)
2309 strcpy (path
, include_dirs
[i
]);
2311 strcat (path
, file
);
2312 if ((f
= fopen (path
, FOPEN_RB
)) != NULL
)
2317 f
= fopen (file
, FOPEN_RB
);
2320 as_bad ("unable to read file `%s'", file
);
2325 left_before_marker
= 0;
2329 bytes
= MIN (size
- left_before_marker
, sizeof (buf
));
2331 bytes
= sizeof (buf
);
2332 n
= fread (buf
, 1, bytes
, f
);
2335 char *fr
= frag_more (n
);
2336 memcpy (fr
, buf
, n
);
2340 left_before_marker
+= n
;
2341 if (left_before_marker
> size
)
2342 as_fatal ("internal error: file insertion sanity checky failed");
2343 if (left_before_marker
== size
)
2345 (*insert_marker
) (insert_marker_arg
);
2346 left_before_marker
= 0;
2353 /* We assume the file is smaller than 2^31 bytes.
2354 Ok, we shouldn't make any assumptions. */
2358 /* Insert an operand value into an instruction. */
2361 insert_operand (cpu
, opcode
, operand
, mods
, insn_buf
, val
, errmsg
)
2363 const dvp_opcode
*opcode
;
2364 const dvp_operand
*operand
;
2368 const char **errmsg
;
2370 if (operand
->insert
)
2372 (*operand
->insert
) (opcode
, operand
, mods
, insn_buf
, (long) val
, errmsg
);
2376 /* We currently assume a field does not cross a word boundary. */
2377 int shift
= ((mods
& DVP_MOD_THIS_WORD
)
2378 ? (operand
->shift
& 31)
2380 /* FIXME: revisit */
2381 if (operand
->word
== 0)
2383 int word
= (mods
& DVP_MOD_THIS_WORD
) ? 0 : (shift
/ 32);
2384 if (operand
->bits
== 32)
2385 insn_buf
[word
] = val
;
2389 insn_buf
[word
] |= ((long) val
& ((1 << operand
->bits
) - 1)) << shift
;
2394 int word
= (mods
& DVP_MOD_THIS_WORD
) ? 0 : operand
->word
;
2395 if (operand
->bits
== 32)
2396 insn_buf
[word
] = val
;
2399 long temp
= (long) val
& ((1 << operand
->bits
) - 1);
2400 insn_buf
[word
] |= temp
<< operand
->shift
;
2406 /* Insert an operand's final value into an instruction.
2407 Here we can give warning messages about operand values if we want to. */
2410 insert_operand_final (cpu
, operand
, mods
, insn_buf
, val
, file
, line
)
2412 const dvp_operand
*operand
;
2419 if (operand
->bits
!= 32)
2421 offsetT min
, max
, test
;
2423 if ((operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0)
2427 if (file
== (char *) NULL
)
2428 as_warn ("branch to misaligned address");
2430 as_warn_where (file
, line
, "branch to misaligned address");
2435 if ((operand
->flags
& DVP_OPERAND_SIGNED
) != 0)
2437 if ((operand
->flags
& DVP_OPERAND_SIGNOPT
) != 0)
2438 max
= (1 << operand
->bits
) - 1;
2440 max
= (1 << (operand
->bits
- 1)) - 1;
2441 min
= - (1 << (operand
->bits
- 1));
2445 max
= (1 << operand
->bits
) - 1;
2449 if ((operand
->flags
& DVP_OPERAND_NEGATIVE
) != 0)
2454 if (test
< (offsetT
) min
|| test
> (offsetT
) max
)
2457 "operand out of range (%s not between %ld and %ld)";
2460 sprint_value (buf
, test
);
2461 if (file
== (char *) NULL
)
2462 as_warn (err
, buf
, min
, max
);
2464 as_warn_where (file
, line
, err
, buf
, min
, max
);
2469 const char *errmsg
= NULL
;
2470 insert_operand (cpu
, NULL
, operand
, mods
, insn_buf
, val
, &errmsg
);
2472 as_warn_where (file
, line
, errmsg
);
2476 /* DVP pseudo ops. */
2486 if (dma_data_state
!= 0)
2488 as_bad ("DmaData blocks cannot be nested.");
2489 ignore_rest_of_line ();
2494 SKIP_WHITESPACE (); /* Leading whitespace is part of operand. */
2495 name
= input_line_pointer
;
2497 if (!is_name_beginner (*name
))
2499 as_bad ("invalid identifier for \".DmaData\"");
2500 ignore_rest_of_line ();
2504 /* Do an implicit alignment to a 16 byte boundary. */
2505 frag_align (4, 0, 0);
2506 record_alignment (now_seg
, 4);
2508 c
= get_symbol_end ();
2509 line_label
= colon (name
); /* user-defined label */
2510 dma_data_name
= S_GET_NAME (line_label
);
2511 *input_line_pointer
= c
;
2513 /* Force emission of a machine type label for the next insn. */
2514 force_mach_label ();
2516 demand_empty_rest_of_line ();
2520 s_enddmadata (ignore
)
2523 if (dma_data_state
!= 1)
2525 as_warn (".EndDmaData encountered outside a DmaData block -- ignored.");
2526 ignore_rest_of_line ();
2530 demand_empty_rest_of_line ();
2532 /* If count provided, verify it is correct. */
2535 /* Fill the data out to a multiple of 16 bytes. */
2536 /* FIXME: Are the fill contents right? */
2537 frag_align (4, 0, 0);
2539 /* "label" points to beginning of block.
2540 Create a name for the final label like _$<name>. */
2542 create_colon_label (0, END_LABEL_PREFIX
, dma_data_name
);
2546 s_dmapackvif (ignore
)
2549 /* Syntax: .dmapackvif 0|1 */
2551 /* Leading whitespace is part of operand. */
2553 switch (*input_line_pointer
++)
2562 as_bad ("illegal argument to `.dmapackvif'");
2564 demand_empty_rest_of_line ();
2567 /* INTERNAL_P is non-zero if invoked internally by this file rather than
2568 by the user. In this case we don't touch the input stream. */
2571 s_enddirect (internal_p
)
2574 if (CUR_ASM_STATE
!= ASM_DIRECT
)
2576 as_bad ("`.enddirect' has no matching `direct' instruction");
2580 /* Record in the end data symbol the current location. */
2581 if (now_seg
!= S_GET_SEGMENT (vif_data_end
))
2582 as_bad (".enddirect in different section");
2583 vif_data_end
->sy_frag
= frag_now
;
2584 S_SET_VALUE (vif_data_end
, (valueT
) frag_now_fix ());
2586 set_asm_state (ASM_INIT
);
2588 /* Needn't be reset, but to catch bugs it is. */
2589 vif_data_end
= NULL
;
2592 demand_empty_rest_of_line ();
2595 /* CALLER denotes who's calling us.
2596 If ENDMPG_USER then .endmpg was found in the input stream.
2597 If ENDMPG_INTERNAL then we've been invoked to finish off file insertion.
2598 If ENDMPG_MIDDLE then we've been invoked in the middle of a long stretch
2605 if (CUR_ASM_STATE
!= ASM_MPG
)
2607 as_bad ("`.endmpg' has no matching `mpg' instruction");
2611 /* Record in the end data symbol the current location. */
2612 if (now_seg
!= S_GET_SEGMENT (vif_data_end
))
2613 as_bad (".endmpg in different section");
2614 vif_data_end
->sy_frag
= frag_now
;
2615 S_SET_VALUE (vif_data_end
, (valueT
) frag_now_fix ());
2618 We have to leave the old value alone as it may be used in fixups
2619 already recorded. The new value is the old value plus the number of
2620 double words in this chunk. */
2623 s
= expr_build_binary (O_subtract
, vif_data_end
, vif_data_start
);
2624 s
= expr_build_binary (O_divide
, s
, expr_build_uconstant (8));
2625 mpgloc_sym
= expr_build_binary (O_add
, mpgloc_sym
, s
);
2628 set_asm_state (ASM_INIT
);
2630 /* Needn't be reset, but to catch bugs it is. */
2631 vif_data_end
= NULL
;
2633 /* Reset the vu insn counter. */
2634 if (caller
!= ENDMPG_MIDDLE
)
2637 if (caller
== ENDMPG_USER
)
2638 demand_empty_rest_of_line ();
2641 /* INTERNAL_P is non-zero if invoked internally by this file rather than
2642 by the user. In this case we don't touch the input stream. */
2645 s_endunpack (internal_p
)
2648 if (CUR_ASM_STATE
!= ASM_UNPACK
)
2650 as_bad ("`.endunpack' has no matching `unpack' instruction");
2654 /* Record in the end data symbol the current location. */
2655 if (now_seg
!= S_GET_SEGMENT (vif_data_end
))
2656 as_bad (".endunpack in different section");
2657 vif_data_end
->sy_frag
= frag_now
;
2658 S_SET_VALUE (vif_data_end
, (valueT
) frag_now_fix ());
2660 /* Update $.UnpackLoc. */
2663 s
= expr_build_binary (O_subtract
, vif_data_end
, vif_data_start
);
2664 /* Round up to next quadword boundary. */
2665 /* FIXME: This isn't correct, the size of the input data is not the
2666 size of the output data. Someone else can fix this. */
2667 s
= expr_build_binary (O_add
, s
, expr_build_uconstant (15));
2668 s
= expr_build_binary (O_divide
, s
, expr_build_uconstant (16));
2669 unpackloc_sym
= expr_build_binary (O_add
, unpackloc_sym
, s
);
2672 /* Round up to next word boundary. */
2673 frag_align (2, 0, 0);
2675 set_asm_state (ASM_INIT
);
2677 /* Needn't be reset, but to catch bugs it is. */
2678 vif_data_end
= NULL
;
2681 demand_empty_rest_of_line ();
2689 int specified_nloop
= gif_nloop ();
2691 int nregs
= gif_nregs ();
2695 as_where (&file
, &line
);
2697 if (CUR_ASM_STATE
!= ASM_GIF
)
2699 as_bad (".endgif doesn't follow a gif tag");
2704 /* Fill out to proper boundary.
2705 ??? This may cause eval_expr to always queue a fixup. So be it. */
2706 switch (gif_insn_type
)
2708 case GIF_PACKED
: frag_align (4, 0, 0); break;
2709 case GIF_REGLIST
: frag_align (3, 0, 0); break;
2710 case GIF_IMAGE
: frag_align (4, 0, 0); break;
2713 /* The -16 is because the `gif_data_name' label is emitted at the
2714 start of the gif tag. If we're in a different frag from the one we
2715 started with, this can't be computed until much later. To cope we queue
2716 a fixup and deal with it then.
2717 ??? The other way to handle this is by having expr() compute "syma - symb"
2718 when they're in different fragments but the difference is constant.
2719 Not sure how much of a slowdown that will introduce though. */
2721 bytes
= eval_expr (gif_operand_nloop
, 0, ". - %s - 16", gif_data_name
);
2723 /* Compute a value for nloop if we can. */
2725 if (fixup_count
== 0)
2727 computed_nloop
= compute_nloop (gif_insn_type
, nregs
, bytes
);
2729 /* If the user specified nloop, verify it. */
2730 if (specified_nloop
!= -1)
2731 check_nloop (gif_insn_type
, nregs
,
2732 specified_nloop
, computed_nloop
,
2736 /* If computation of nloop can't be done yet, queue a fixup and do it later.
2737 Otherwise validate nloop if specified or write the computed value into
2740 if (fixup_count
!= 0)
2742 /* FIXME: It might eventually be possible to combine all the various
2743 copies of this bit of code. */
2744 int op_type
, reloc_type
, offset
;
2745 const dvp_operand
*operand
;
2748 op_type
= fixups
[0].opindex
;
2749 offset
= fixups
[0].offset
;
2750 reloc_type
= encode_fixup_reloc_type (DVP_GIF
, op_type
);
2751 operand
= &gif_operands
[op_type
];
2752 fix
= fix_new_exp (gif_insn_frag
,
2753 (gif_insn_frag_loc
+ offset
2754 - gif_insn_frag
->fr_literal
),
2755 4, &fixups
[0].exp
, 0,
2756 (bfd_reloc_code_real_type
) reloc_type
);
2757 /* Record user specified value so we can test it when we compute the
2759 fix
->tc_fix_data
.type
= gif_insn_type
;
2760 fix
->tc_fix_data
.nregs
= nregs
;
2761 fix
->tc_fix_data
.user_value
= specified_nloop
;
2763 else if (specified_nloop
!= -1)
2764 ; /* nothing to do */
2767 DVP_INSN insn
= bfd_getl32 (gif_insn_frag_loc
);
2768 insert_operand_final (DVP_GIF
, &gif_operands
[gif_operand_nloop
],
2769 DVP_MOD_THIS_WORD
, &insn
,
2770 (offsetT
) computed_nloop
, file
, line
);
2771 bfd_putl32 ((bfd_vma
) insn
, gif_insn_frag_loc
);
2774 /* These needn't be reset, but to catch bugs they are. */
2775 gif_data_name
= NULL
;
2776 gif_insn_frag
= NULL
;
2777 gif_insn_frag_loc
= NULL
;
2779 demand_empty_rest_of_line ();
2786 /* If in MPG state and the user requests to change to VU state,
2787 leave the state as MPG. This happens when we see an mpg followed
2788 by a .include that has .vu. */
2789 if (CUR_ASM_STATE
== ASM_MPG
&& state
== ASM_VU
)
2792 set_asm_state (state
);
2794 demand_empty_rest_of_line ();