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. */
26 /* Needed by opcode/dvp.h. */
28 #include "opcode/dvp.h"
37 /* Value of VIF `nop' instruction. */
40 #define MIN(a,b) ((a) < (b) ? (a) : (b))
42 /* Compute DMA operand index number of OP. */
43 #define DMA_OPERAND_INDEX(op) ((op) - dma_operands)
45 /* Our local label prefix. */
46 #define LOCAL_LABEL_PREFIX ".L"
47 /* Label prefix for end markers used in autocounts. */
48 #define END_LABEL_PREFIX ".L.end."
49 /* Label to use for unique labels. */
50 #define UNIQUE_LABEL_PREFIX ".L.dvptmp."
51 /* Prefix for mips version of labels defined in vu code.
52 Note that symbols that begin with '$' are local symbols
53 on mips targets, so we can't begin it with '$'. */
54 #define VU_LABEL_PREFIX "_$"
55 /* Prefix for symbols at start of vu overlays, in r5900 space. */
56 #define VUOVERLAY_START_PREFIX "__start_"
58 static long parse_float
PARAMS ((char **, const char **));
59 static symbolS
* create_label
PARAMS ((const char *, const char *));
60 static symbolS
* create_colon_label
PARAMS ((int, const char *, const char *));
61 static char * unique_name
PARAMS ((const char *));
62 static char * vuoverlay_section_name
PARAMS ((symbolS
*));
63 static void create_vuoverlay_section
PARAMS ((const char *, symbolS
*,
64 symbolS
*, symbolS
*));
65 static symbolS
* compute_mpgloc
PARAMS ((symbolS
*, symbolS
*, symbolS
*));
66 static int compute_nloop
PARAMS ((gif_type
, int, int));
67 static void check_nloop
PARAMS ((gif_type
, int, int, int,
68 char *, unsigned int));
69 static long eval_expr
PARAMS ((dvp_cpu
, int, int, const char *, ...));
70 static long parse_dma_addr_autocount ();
71 static void inline_dma_data
PARAMS ((int, DVP_INSN
*));
72 static void setup_dma_autocount
PARAMS ((const char *, DVP_INSN
*, int));
74 static void insert_operand
75 PARAMS ((dvp_cpu
, const dvp_opcode
*, const dvp_operand
*, int,
76 DVP_INSN
*, offsetT
, const char **));
77 static void insert_operand_final
78 PARAMS ((dvp_cpu
, const dvp_operand
*, int,
79 DVP_INSN
*, offsetT
, char *, unsigned int));
81 static void insert_mpg_marker
PARAMS ((unsigned long));
82 static void insert_unpack_marker
PARAMS ((unsigned long));
83 static int insert_file
PARAMS ((const char *,
84 void (*) PARAMS ((unsigned long)),
87 static int vif_insn_type
PARAMS ((char));
88 static int vif_length_value
PARAMS ((char, int, int, int));
89 static void install_vif_length
PARAMS ((char *, int));
91 const char comment_chars
[] = ";";
92 const char line_comment_chars
[] = "#";
93 const char line_separator_chars
[] = "!";
94 const char EXP_CHARS
[] = "eE";
95 const char FLT_CHARS
[] = "dD";
97 /* Current assembler state.
98 Instructions like mpg and direct are followed by a restricted set of
99 instructions. In the case of a '*' length argument an end marker must
100 be provided. (e.g. mpg is followed by vu insns until a .EndMpg is
103 Allowed state transitions:
104 ASM_INIT <--> ASM_MPG
105 ASM_DIRECT <--> ASM_GIF
106 ASM_UNPACK <--> ASM_GIF
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.
116 ASM_INIT
, ASM_DIRECT
, ASM_MPG
, ASM_UNPACK
, ASM_VU
, ASM_GIF
, ASM_MAX
119 /* We need to maintain a stack of the current and previous status to handle
120 such things as "direct ...; gifpacked ... ; .endgif ; .enddirect". */
121 #define MAX_STATE_DEPTH 2
122 static asm_state asm_state_stack
[MAX_STATE_DEPTH
];
123 /* Current state's index in the stack. */
124 static int cur_state_level
;
125 /* Macro to fetch the current state. */
126 #define CUR_ASM_STATE (asm_state_stack[cur_state_level])
128 /* Functions to push/pop the state stack. */
129 static void push_asm_state
PARAMS ((asm_state
));
130 static void pop_asm_state
PARAMS ((int));
131 static void set_asm_state
PARAMS ((asm_state
, const char *));
133 /* Set to non-zero if any non-vu insn seen.
134 Used to control type of relocations emitted. */
135 static int non_vu_insn_seen_p
= 0;
137 /* Current cpu (machine variant) type state.
138 We copy the mips16 way of recording what the current machine type is in
139 the code. A label is created whenever necessary and has an "other" value
140 the denotes the machine type. */
141 static dvp_cpu cur_cpu
;
142 /* Record the current mach type. */
143 static void record_mach
PARAMS ((dvp_cpu
, int));
144 /* Force emission of mach type label at next insn.
145 This isn't static as TC_START_LABEL uses it. */
146 int force_mach_label
PARAMS ((void));
147 /* Given a dvp_cpu value, return the STO_DVP value to use. */
148 static int cpu_sto
PARAMS ((dvp_cpu
, const char **));
150 /* Nonzero if inside .DmaData. */
151 static int dma_data_state
= 0;
152 /* Label of .DmaData (internally generated for inline data). */
153 static const char *dma_data_name
;
155 /* Variable length VIF insn support. */
156 /* Label at start of insn's data. */
157 static symbolS
*vif_data_start
;
158 /* Label at end of insn's data. */
159 static symbolS
*vif_data_end
;
161 /* Special symbol $.mpgloc. The value is in bytes.
162 This value is kept absolute, for simplicity. */
163 static symbolS
*mpgloc_sym
;
165 /* Handle of the current vu overlay section. */
166 static segT vuoverlay_section
;
168 /* The overlay table section is a table mapping lma's to vma's. */
169 static segT vuoverlay_table_section
;
170 /* String table to record section names in the overlay table. */
171 static segT vuoverlay_string_section
;
173 /* Table to map vu space labels to their overlay sections.
174 Labels in vu space are first put in the ABS section to simplify
175 PC relative branch calculations (s1 - s2 isn't supported if they're
176 in different sections). Before the file is written out the labels
177 are moved to their overlay section. */
178 typedef struct ovlysym
{
179 struct ovlysym
*next
;
183 static ovlysymS
*ovlysym_table
;
185 /* GIF insn support. */
187 static int gif_insn_type
;
188 /* Name of label of insn's data. */
189 static const char *gif_data_name
;
190 /* Pointer to frag of insn. */
191 static fragS
*gif_insn_frag
;
192 /* Pointer to current gif insn in gif_insn_frag. */
193 static char *gif_insn_frag_loc
;
194 /* The length value specified in the insn, or -1 if '*'. */
195 static int gif_user_value
;
197 /* Count of vu insns seen since the last mpg.
198 Set to -1 to disable automatic mpg insertion. */
201 /* Non-zero if packing vif instructions in dma tags. */
202 static int dma_pack_vif_p
;
204 /* Non-zero if dma insns are to be included in the output.
205 This is the default, but writing "if (! no_dma)" is klunky. */
206 static int output_dma
= 1;
207 /* Non-zero if vif insns are to be included in the output. */
208 static int output_vif
= 1;
210 /* Current opcode/operand for use by md_operand. */
211 static const dvp_opcode
*cur_opcode
;
212 static const dvp_operand
*cur_operand
;
214 /* Options for the `caller' argument to s_endmpg. */
215 typedef enum { ENDMPG_USER
, ENDMPG_INTERNAL
, ENDMPG_MIDDLE
} endmpg_caller
;
217 /* Relaxation support. */
219 #define RELAX_DIRECT 2
220 /* vu insns aren't relaxed, but they use machine dependent frags so we
221 must handle them during relaxation */
223 #define RELAX_ENCODE(type, growth) (10 + (growth))
224 #define RELAX_GROWTH(state) ((state) - 10)
225 /* Return non-zero if STATE represents a relaxed state. */
226 #define RELAX_DONE_P(state) ((state) >= 10)
228 const char *md_shortopts
= "";
230 struct option md_longopts
[] =
232 #define OPTION_NO_DMA (OPTION_MD_BASE + 1)
233 { "no-dma", no_argument
, NULL
, OPTION_NO_DMA
},
234 #define OPTION_NO_DMA_VIF (OPTION_NO_DMA + 1)
235 { "no-dma-vif", no_argument
, NULL
, OPTION_NO_DMA_VIF
},
237 {NULL
, no_argument
, NULL
, 0}
239 size_t md_longopts_size
= sizeof(md_longopts
);
242 md_parse_option (c
, arg
)
251 case OPTION_NO_DMA_VIF
:
262 md_show_usage (stream
)
267 -no-dma do not include DMA instructions in the output\n\
268 -no-dma-vif do not include DMA or VIF instructions in the output\n\
272 static void s_dmadata
PARAMS ((int));
273 static void s_enddmadata
PARAMS ((int));
274 static void s_dmapackvif
PARAMS ((int));
275 static void s_enddirect
PARAMS ((int));
276 static void s_endmpg
PARAMS ((int));
277 static void s_endunpack
PARAMS ((int));
278 static void s_endgif
PARAMS ((int));
279 static void s_vu
PARAMS ((int));
280 static void s_dvp_func
PARAMS ((int));
282 /* The target specific pseudo-ops which we support. */
283 const pseudo_typeS md_pseudo_table
[] =
286 { "quad", cons
, 16 },
287 { "dmadata", s_dmadata
, 0 },
288 { "dmapackvif", s_dmapackvif
, 0 },
289 { "enddirect", s_enddirect
, 0 },
290 { "enddmadata", s_enddmadata
, 0 },
291 { "endmpg", s_endmpg
, ENDMPG_USER
},
292 { "endunpack", s_endunpack
, 0 },
293 { "endgif", s_endgif
, 0 },
295 /* We need to intercept .func/.endfunc so that we can prepend _$.
296 ??? Not sure this is right though as _$foo is the lma version. */
297 { "func", s_dvp_func
, 0 },
298 { "endfunc", s_dvp_func
, 1 },
305 /* Initialize the opcode tables.
306 This involves computing the hash chains. */
307 dvp_opcode_init_tables (0);
309 /* Force a mach type label for the first insn. */
312 /* Initialize the parsing state. */
313 set_asm_state (ASM_INIT
, NULL
);
315 /* Pack vif insns in dma tags by default. */
318 /* Disable automatic mpg insertion. */
321 /* Initialize $.mpgloc. */
322 mpgloc_sym
= expr_build_uconstant (0);
324 /* Create the vu overlay table section. */
326 /* Must preserve the current seg/subseg. It is the initial one. */
327 segT orig_seg
= now_seg
;
328 subsegT orig_subseg
= now_subseg
;
330 vuoverlay_table_section
= subseg_new (SHNAME_DVP_OVERLAY_TABLE
, 0);
331 record_alignment (now_seg
, 2);
332 vuoverlay_string_section
= subseg_new (SHNAME_DVP_OVERLAY_STRTAB
, 0);
333 /* Ensure first byte in executable is zero. So what if we waste
335 FRAG_APPEND_1_CHAR (0);
337 subseg_set (orig_seg
, orig_subseg
);
340 /* Set the type of the output file to r5900. */
341 bfd_set_arch_mach (stdoutput
, bfd_arch_mips
, 5900);
344 /* We need to keep a list of fixups. We can't simply generate them as
345 we go, because that would require us to first create the frag, and
346 that would screw up references to ``.''. */
350 /* the cpu this fixup is associated with */
352 /* index into `dvp_operands' */
354 /* byte offset from beginning of instruction */
356 /* user specified value [when there is one] */
358 /* wl,cl values, only used with unpack insn */
366 static int fixup_count
;
367 static struct dvp_fixup fixups
[MAX_FIXUPS
];
369 /* Given a cpu type and operand number, return a temporary reloc type
370 for use in generating the fixup that encodes the cpu type and operand. */
371 static int encode_fixup_reloc_type
PARAMS ((dvp_cpu
, int));
372 /* Given an encoded fixup reloc type, decode it into cpu and operand. */
373 static void decode_fixup_reloc_type
PARAMS ((int, dvp_cpu
*,
374 const dvp_operand
**));
376 static void assemble_dma
PARAMS ((char *));
377 static void assemble_gif
PARAMS ((char *));
378 static void assemble_vif
PARAMS ((char *));
379 static void assemble_vu
PARAMS ((char *));
380 static const dvp_opcode
* assemble_vu_insn
PARAMS ((dvp_cpu
,
384 static const dvp_opcode
* assemble_one_insn
PARAMS ((dvp_cpu
,
388 char **, DVP_INSN
*));
390 /* Main entry point for assembling an instruction. */
396 /* Skip leading white space. */
397 while (isspace (*str
))
400 /* After a gif tag, no insns can appear until a .endgif is seen. */
401 if (CUR_ASM_STATE
== ASM_GIF
)
403 as_bad ("missing .endgif");
405 /* We still parse the instruction. */
408 if (CUR_ASM_STATE
== ASM_INIT
)
410 if (strncasecmp (str
, "dma", 3) == 0)
412 else if (strncasecmp (str
, "gif", 3) == 0)
416 non_vu_insn_seen_p
= 1;
418 else if (CUR_ASM_STATE
== ASM_DIRECT
419 || CUR_ASM_STATE
== ASM_UNPACK
)
422 non_vu_insn_seen_p
= 1;
424 else if (CUR_ASM_STATE
== ASM_VU
425 || CUR_ASM_STATE
== ASM_MPG
)
428 as_fatal ("internal error: unknown parse state");
431 /* Subroutine of md_assemble to assemble DMA instructions. */
437 DVP_INSN insn_buf
[2];
438 /* Insn's length, in 32 bit words. */
440 /* Pointer to allocated frag. */
443 const dvp_opcode
*opcode
;
447 /* Do an implicit alignment to a 16 byte boundary.
448 Do it now so that inline dma data labels are at the right place. */
449 /* ??? One can certainly argue all this implicit alignment is
450 questionable. The thing is assembler programming is all that will
451 mostly likely ever be done and not doing so forces an extra [and
452 arguably unnecessary] burden on the programmer. */
453 frag_align (4, 0, 0);
454 record_alignment (now_seg
, 4);
457 /* This is the DMA tag. */
461 opcode
= assemble_one_insn (DVP_DMA
,
462 dma_opcode_lookup_asm (str
), dma_operands
,
463 0, 0, &str
, insn_buf
);
469 record_mach (DVP_DMA
, 0);
473 /* Write out the DMA instruction. */
474 for (i
= 0; i
< 2; ++i
)
475 md_number_to_chars (f
+ i
* 4, insn_buf
[i
], 4);
477 /* Create any fixups. */
478 /* FIXME: It might eventually be possible to combine all the various
479 copies of this bit of code. */
480 for (i
= 0; i
< fixup_count
; ++i
)
482 int op_type
, reloc_type
, offset
;
483 const dvp_operand
*operand
;
485 /* Create a fixup for this operand.
486 At this point we do not use a bfd_reloc_code_real_type for
487 operands residing in the insn, but instead just use the
488 operand index. This lets us easily handle fixups for any
489 operand type, although that is admittedly not a very exciting
490 feature. We pick a BFD reloc type in md_apply_fix. */
492 op_type
= fixups
[i
].opindex
;
493 offset
= fixups
[i
].offset
;
494 reloc_type
= encode_fixup_reloc_type (DVP_DMA
, op_type
);
495 operand
= &dma_operands
[op_type
];
496 fix_new_exp (frag_now
, f
+ offset
- frag_now
->fr_literal
, 4,
498 (operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0,
499 (bfd_reloc_code_real_type
) reloc_type
);
502 /* The upper two words are vif insns. */
503 record_mach (DVP_VIF
, 0);
505 /* If not doing dma/vif packing, fill out the insn with vif nops.
506 ??? We take advantage of the fact that the default fill value of zero
507 is the vifnop insn. This occurs for example when handling mpg
508 alignment. It also occurs when one dma tag immediately follows the
510 if (! dma_pack_vif_p
)
513 md_number_to_chars (f
+ 0, VIFNOP
, 4);
514 md_number_to_chars (f
+ 4, VIFNOP
, 4);
518 /* Subroutine of md_assemble to assemble VIF instructions. */
524 /* Space for the instruction.
525 The variable length insns can require much more space than this.
526 It is allocated later, when we know we have such an insn. */
527 DVP_INSN insn_buf
[5];
528 /* Insn's length, in 32 bit words. */
530 /* Pointer to allocated frag. */
533 const dvp_opcode
*opcode
;
535 /* Name of file to read data from. */
537 /* Length in 32 bit words. */
539 /* Macro expansion, if there is one. */
542 /* First check for macros. */
543 macstr
= dvp_expand_macro (vif_macros
, vif_macro_count
, str
);
546 /* The macro may expand into several insns (delimited with '\n'),
548 char * next
= macstr
;
551 char *p
= strchr (next
, '\n');
555 next
= p
? p
+ 1 : 0;
562 opcode
= assemble_one_insn (DVP_VIF
,
563 vif_opcode_lookup_asm (str
), vif_operands
,
564 0, 0, &str
, insn_buf
);
568 if (opcode
->flags
& VIF_OPCODE_LENVAR
)
569 len
= 1; /* actual data follows later */
570 else if (opcode
->flags
& VIF_OPCODE_LEN2
)
572 else if (opcode
->flags
& VIF_OPCODE_LEN5
)
577 /* We still have to switch modes (if mpg for example) so we can't exit
582 /* Record the mach before doing the alignment so that we properly
583 disassemble any inserted vifnop's. For mpg and direct insns
584 force the recording of the mach type for the next insn. The data
585 will switch the mach type and we want to ensure it's switched
588 if (opcode
->flags
& (VIF_OPCODE_MPG
| VIF_OPCODE_DIRECT
))
589 record_mach (DVP_VIF
, 1);
591 record_mach (DVP_VIF
, 0);
593 /* For variable length instructions record a fixup that is the symbol
594 marking the end of the data. eval_expr will queue the fixup
595 which will then be emitted later. */
596 if (opcode
->flags
& VIF_OPCODE_LENVAR
)
600 asprintf (&name
, "%s%s", LOCAL_LABEL_PREFIX
,
601 unique_name ("varlen"));
602 vif_data_end
= symbol_new (name
, now_seg
, 0, 0);
603 symbol_table_insert (vif_data_end
);
604 fixups
[fixup_count
].cpu
= DVP_VIF
;
605 fixups
[fixup_count
].exp
.X_op
= O_symbol
;
606 fixups
[fixup_count
].exp
.X_add_symbol
= vif_data_end
;
607 fixups
[fixup_count
].exp
.X_add_number
= 0;
608 fixups
[fixup_count
].opindex
= vif_operand_datalen_special
;
609 fixups
[fixup_count
].offset
= 0;
611 /* See what the user specified. */
612 vif_get_var_data (&file
, &data_len
);
615 fixups
[fixup_count
].user_value
= data_len
;
616 /* Get the wl,cl values. Only useful for the unpack insn but
617 it doesn't hurt to always record them. */
618 vif_get_wl_cl (&wl
, &cl
);
619 fixups
[fixup_count
].wl
= wl
;
620 fixups
[fixup_count
].cl
= cl
;
624 /* Obtain space in which to store the instruction. */
626 if (opcode
->flags
& VIF_OPCODE_MPG
)
628 /* The data must be aligned on a 64 bit boundary (so the mpg insn
629 comes just before that 64 bit boundary).
630 Do this by putting the mpg insn in a relaxable fragment
631 with a symbol that marks the beginning of the aligned data. */
633 /* Ensure relaxable fragments are in their own fragment.
634 Otherwise md_apply_fix3 mishandles fixups to insns earlier
635 in the fragment (because we set fr_opcode for the `mpg' insn
636 because it can move in the fragment). */
637 frag_wane (frag_now
);
640 /* One could combine the previous two lines with the following.
641 They're not for clarity: keep separate the actions being
644 /* This dance with frag_grow is so we can record frag_now in
645 insn_frag. frag_var always changes frag_now. We must allocate
646 the maximal amount of space we need so there's room to move
647 the insn in the frag during relaxation. */
649 /* Allocate space for the fixed part. */
651 insn_frag
= frag_now
;
653 frag_var (rs_machine_dependent
,
655 0, /* variable part is empty at present */
656 RELAX_MPG
, /* subtype */
657 NULL
, /* no symbol */
661 frag_align (3, 0, 0);
662 record_alignment (now_seg
, 3);
664 /* Put a symbol at the start of data. The relaxation code uses
665 this to figure out how many bytes to insert. $.mpgloc
666 calculations use it. The disassembler uses it. The overlay
667 tracking table uses it.
669 Create an overlay section. */
671 int mpgloc
= vif_get_mpgloc ();
672 const char * section_name
;
674 /* Update $.mpgloc if explicitly set.
675 Otherwise just use the current value. */
678 /* The value is recorded in bytes, mpgloc is in dwords. */
679 mpgloc_sym
= expr_build_uconstant (mpgloc
* 8);
682 section_name
= vuoverlay_section_name (mpgloc_sym
);
683 vif_data_start
= create_colon_label (STO_DVP_VU
,
684 VUOVERLAY_START_PREFIX
,
686 insn_frag
->fr_symbol
= vif_data_start
;
688 create_vuoverlay_section (section_name
, mpgloc_sym
,
689 vif_data_start
, vif_data_end
);
692 else if (opcode
->flags
& VIF_OPCODE_DIRECT
)
694 /* The data must be aligned on a 128 bit boundary (so the direct insn
695 comes just before that 128 bit boundary).
696 Do this by putting the direct insn in a relaxable fragment.
697 with a symbol that marks the beginning of the aligned data. */
699 /* Ensure relaxable fragments are in their own fragment.
700 Otherwise md_apply_fix3 mishandles fixups to insns earlier
701 in the fragment (because we set fr_opcode for the `direct' insn
702 because it can move in the fragment). */
703 frag_wane (frag_now
);
706 /* One could combine the previous two lines with the following.
707 They're not for clarity: keep separate the actions being
710 /* This dance with frag_grow is so we can record frag_now in
711 insn_frag. frag_var always changes frag_now. We must allocate
712 the maximal amount of space we need so there's room to move
713 the insn in the frag during relaxation. */
715 /* Allocate space for the fixed part. */
717 insn_frag
= frag_now
;
719 frag_var (rs_machine_dependent
,
721 0, /* variable part is empty at present */
722 RELAX_DIRECT
, /* subtype */
723 NULL
, /* no symbol */
727 frag_align (4, 0, 0);
728 record_alignment (now_seg
, 4);
730 /* Put a symbol at the start of data. The relaxation code uses
731 this to figure out how many bytes to insert. */
732 vif_data_start
= create_colon_label (0, LOCAL_LABEL_PREFIX
,
733 unique_name ("direct"));
734 insn_frag
->fr_symbol
= vif_data_start
;
736 else if (opcode
->flags
& VIF_OPCODE_UNPACK
)
738 f
= frag_more (len
* 4);
739 insn_frag
= frag_now
;
740 /* Put a symbol at the start of data. $.unpackloc calculations
742 /* ??? $.unpackloc is gone. Is this also used for data length
744 vif_data_start
= create_colon_label (STO_DVP_VIF
, LOCAL_LABEL_PREFIX
,
745 unique_name ("unpack"));
749 /* Reminder: it is important to fetch enough space in one call to
750 `frag_more'. We use (f - frag_now->fr_literal) to compute where
751 we are and we don't want frag_now to change between calls. */
752 f
= frag_more (len
* 4);
753 insn_frag
= frag_now
;
756 /* Write out the instruction. */
757 for (i
= 0; i
< len
; ++i
)
758 md_number_to_chars (f
+ i
* 4, insn_buf
[i
], 4);
760 /* Create any fixups. */
761 /* FIXME: It might eventually be possible to combine all the various
762 copies of this bit of code. */
763 for (i
= 0; i
< fixup_count
; ++i
)
765 int op_type
, reloc_type
, offset
;
766 const dvp_operand
*operand
;
769 /* Create a fixup for this operand.
770 At this point we do not use a bfd_reloc_code_real_type for
771 operands residing in the insn, but instead just use the
772 operand index. This lets us easily handle fixups for any
773 operand type, although that is admittedly not a very exciting
774 feature. We pick a BFD reloc type in md_apply_fix. */
776 op_type
= fixups
[i
].opindex
;
777 offset
= fixups
[i
].offset
;
778 reloc_type
= encode_fixup_reloc_type (DVP_VIF
, op_type
);
779 operand
= &vif_operands
[op_type
];
780 fixP
= fix_new_exp (insn_frag
, f
+ offset
- insn_frag
->fr_literal
, 4,
782 (operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0,
783 (bfd_reloc_code_real_type
) reloc_type
);
784 fixP
->tc_fix_data
.user_value
= fixups
[i
].user_value
;
785 fixP
->tc_fix_data
.wl
= fixups
[i
].wl
;
786 fixP
->tc_fix_data
.cl
= fixups
[i
].cl
;
788 /* Set fx_tcbit so other parts of the code know this fixup is for
794 /* Handle variable length insns. */
796 if (opcode
->flags
& VIF_OPCODE_LENVAR
)
798 /* See what the user specified. */
799 vif_get_var_data (&file
, &data_len
);
805 /* The handling for each of mpg,direct,unpack is basically the same:
806 - emit a label to set the mach type for the data we're inserting
807 - switch to the new assembler state
809 - call the `end' handler */
811 if (opcode
->flags
& VIF_OPCODE_MPG
)
813 record_mach (DVP_VUUP
, 1);
814 set_asm_state (ASM_MPG
, "mpg");
815 byte_len
= insert_file (file
, insert_mpg_marker
, 0, 256 * 8);
816 s_endmpg (ENDMPG_INTERNAL
);
818 else if (opcode
->flags
& VIF_OPCODE_DIRECT
)
820 record_mach (DVP_GIF
, 1);
821 set_asm_state (ASM_DIRECT
, "direct");
822 byte_len
= insert_file (file
, NULL
, 0, 0);
825 else if (opcode
->flags
& VIF_OPCODE_UNPACK
)
827 int max_len
= 0; /*unpack_max_byte_len (insn_buf[0]);*/
828 set_asm_state (ASM_UNPACK
, "unpack");
829 byte_len
= insert_file (file
, NULL
/*insert_unpack_marker*/,
830 insn_buf
[0], max_len
);
834 as_fatal ("internal error: unknown cpu type for variable length vif insn");
836 else /* file == NULL */
838 /* data_len == -1 means the value must be computed from
841 as_bad ("invalid data length");
843 if (output_vif
&& data_len
!= -1)
844 install_vif_length (f
, data_len
);
846 if (opcode
->flags
& VIF_OPCODE_MPG
)
848 set_asm_state (ASM_MPG
, "mpg");
849 /* Enable automatic mpg insertion every 256 insns. */
852 else if (opcode
->flags
& VIF_OPCODE_DIRECT
)
853 set_asm_state (ASM_DIRECT
, "direct");
854 else if (opcode
->flags
& VIF_OPCODE_UNPACK
)
855 set_asm_state (ASM_UNPACK
, "unpack");
860 /* Subroutine of md_assemble to assemble GIF instructions.
861 We assume CUR_ASM_STATE is one of ASM_{INIT,DIRECT,UNPACK}. */
867 DVP_INSN insn_buf
[4];
868 const dvp_opcode
*opcode
;
872 insn_buf
[0] = insn_buf
[1] = insn_buf
[2] = insn_buf
[3] = 0;
874 opcode
= assemble_one_insn (DVP_GIF
,
875 gif_opcode_lookup_asm (str
), gif_operands
,
876 0, 0, &str
, insn_buf
);
880 /* Do an implicit alignment to a 16 byte boundary. */
881 frag_align (4, 0, 0);
882 record_alignment (now_seg
, 4);
884 /* Insert a label so we can compute the number of quadwords when the
885 .endgif is seen. This is put before the mach type label because gif
886 insns are followed by data and we don't want the disassembler to try
887 to disassemble them as mips insns (since it uses the st_other field)
888 of the closest label to choose the mach type and since we don't have
889 a special st_other value for "data". */
890 gif_data_name
= S_GET_NAME (create_colon_label (0, LOCAL_LABEL_PREFIX
,
891 unique_name ("gifdata")));
893 record_mach (DVP_GIF
, 1);
895 gif_insn_frag_loc
= f
= frag_more (16);
896 gif_insn_frag
= frag_now
;
897 for (i
= 0; i
< 4; ++i
)
898 md_number_to_chars (f
+ i
* 4, insn_buf
[i
], 4);
900 /* Record the type of the gif tag so we know how to compute nloop
902 if (strcmp (opcode
->mnemonic
, "gifpacked") == 0)
903 gif_insn_type
= GIF_PACKED
;
904 else if (strcmp (opcode
->mnemonic
, "gifreglist") == 0)
905 gif_insn_type
= GIF_REGLIST
;
906 else if (strcmp (opcode
->mnemonic
, "gifimage") == 0)
907 gif_insn_type
= GIF_IMAGE
;
910 push_asm_state (ASM_GIF
);
913 /* Subroutine of md_assemble to assemble VU instructions. */
921 const dvp_opcode
*opcode
;
922 /* The lower instruction has the lower address so insns[0] = lower insn,
923 insns[1] = upper insn. */
927 /* Handle automatic mpg insertion if enabled. */
928 if (CUR_ASM_STATE
== ASM_MPG
930 insert_mpg_marker (0);
932 /* Do an implicit alignment to a 8 byte boundary. */
933 frag_align (3, 0, 0);
934 record_alignment (now_seg
, 3);
936 record_mach (DVP_VUUP
, 0);
938 #ifdef VERTICAL_BAR_SEPARATOR
939 char *p
= strchr (str
, '|');
943 as_bad ("lower instruction missing");
948 opcode
= assemble_one_insn (DVP_VUUP
,
949 vu_upper_opcode_lookup_asm (str
), vu_operands
,
950 0, 4, &str
, &insns
[1]);
954 opcode
= assemble_one_insn (DVP_VUUP
,
955 vu_upper_opcode_lookup_asm (str
), vu_operands
,
956 0, 4, &str
, &insns
[1]);
959 /* Don't assemble next one if we couldn't assemble the first. */
965 as_bad ("lower instruction missing");
969 /* Assemble the lower insn.
970 Pass `fixup_count' for `init_fixup_count' so that we don't clobber
971 any fixups the upper insn had. */
972 opcode
= assemble_one_insn (DVP_VULO
,
973 vu_lower_opcode_lookup_asm (str
), vu_operands
,
974 fixup_count
, 0, &str
, &insns
[0]);
978 /* If there were fixups and we're inside mpg, create a machine dependent
979 fragment so that we can record the current value of $.mpgloc in fr_symbol.
980 Reminder: it is important to fetch enough space in one call to
981 `frag_more'. We use (f - frag_now->fr_literal) to compute where
982 we are and we don't want frag_now to change between calls. */
984 && CUR_ASM_STATE
== ASM_MPG
)
986 symbolS
* cur_mpgloc
;
988 /* Ensure we get a new frag. */
989 frag_wane (frag_now
);
992 /* Compute the current $.mpgloc. */
993 cur_mpgloc
= compute_mpgloc (mpgloc_sym
, vif_data_start
,
996 /* We need to use frag_now afterwards, so we can't just call frag_var.
997 Instead we use frag_more and save the value of frag_now in
1000 insn_frag
= frag_now
;
1001 /* Turn the frag into a machine dependent frag. */
1002 frag_variant (rs_machine_dependent
,
1004 0, /* no variable part */
1005 RELAX_VU
, /* subtype */
1006 cur_mpgloc
, /* $.mpgloc */
1013 insn_frag
= frag_now
;
1016 /* Write out the instructions. */
1017 md_number_to_chars (f
, insns
[0], 4);
1018 md_number_to_chars (f
+ 4, insns
[1], 4);
1020 /* Create any fixups. */
1021 for (i
= 0; i
< fixup_count
; ++i
)
1023 int op_type
, reloc_type
;
1024 const dvp_operand
*operand
;
1027 /* Create a fixup for this operand.
1028 At this point we do not use a bfd_reloc_code_real_type for
1029 operands residing in the insn, but instead just use the
1030 operand index. This lets us easily handle fixups for any
1031 operand type, although that is admittedly not a very exciting
1032 feature. We pick a BFD reloc type in md_apply_fix. */
1034 cpu
= fixups
[i
].cpu
;
1035 op_type
= fixups
[i
].opindex
;
1036 reloc_type
= encode_fixup_reloc_type (cpu
, op_type
);
1037 operand
= &vu_operands
[op_type
];
1039 /* Branch operands inside mpg have to be handled specially.
1040 We want a pc relative relocation in a section different from our own.
1041 See the br-2.s dejagnu testcase for a good example. */
1042 if (CUR_ASM_STATE
== ASM_MPG
1043 && (operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0)
1045 symbolS
*e1
,*e2
,*diff_expr
;
1047 /* For "br foo" we want "foo - (. + 8)". */
1048 e1
= expr_build_binary (O_add
, insn_frag
->fr_symbol
,
1049 expr_build_uconstant (8));
1050 e2
= make_expr_symbol (&fixups
[i
].exp
);
1051 diff_expr
= expr_build_binary (O_subtract
, e2
, e1
);
1052 fixups
[i
].exp
.X_op
= O_symbol
;
1053 fixups
[i
].exp
.X_add_symbol
= diff_expr
;
1054 fixups
[i
].exp
.X_add_number
= 0;
1057 fix_new_exp (insn_frag
, f
+ fixups
[i
].offset
- insn_frag
->fr_literal
, 4,
1059 CUR_ASM_STATE
== ASM_MPG
/* pcrel */
1061 : (operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0,
1062 (bfd_reloc_code_real_type
) reloc_type
);
1065 /* If this was the "loi" pseudo-insn, we need to set the `i' bit. */
1066 if (strcmp (opcode
->mnemonic
, "loi") == 0)
1069 /* Increment the vu insn counter.
1070 If get reach 256 we need to insert an `mpg'. */
1074 /* Assemble one instruction at *PSTR.
1075 CPU indicates what component we're assembling for.
1076 The assembled instruction is stored in INSN_BUF.
1077 OPCODE is a pointer to the head of the hash chain.
1078 INIT_FIXUP_COUNT is the initial value for `fixup_count'.
1079 It exists to allow the fixups for multiple calls to this insn to be
1080 queued up before actually emitting them.
1081 *PSTR is updated to point passed the parsed instruction.
1083 If the insn is successfully parsed the result is a pointer to the opcode
1084 entry that successfully matched and *PSTR is updated to point passed
1085 the parsed insn. If an error occurs the result is NULL and *PSTR is left
1086 at some random point in the string (??? may wish to leave it pointing where
1087 the error occured). */
1089 static const dvp_opcode
*
1090 assemble_one_insn (cpu
, opcode
, operand_table
, init_fixup_count
, fixup_offset
,
1093 const dvp_opcode
*opcode
;
1094 const dvp_operand
*operand_table
;
1095 int init_fixup_count
;
1102 /* Keep looking until we find a match. */
1104 start
= str
= *pstr
;
1105 for ( ; opcode
!= NULL
; opcode
= DVP_OPCODE_NEXT_ASM (opcode
))
1107 int past_opcode_p
, num_suffixes
;
1108 const unsigned char *syn
;
1110 /* Ensure the mnemonic part matches. */
1111 for (str
= start
, syn
= opcode
->mnemonic
; *syn
!= '\0'; ++str
, ++syn
)
1112 if (tolower (*str
) != tolower (*syn
))
1117 /* Scan the syntax string. If it doesn't match, try the next one. */
1119 dvp_opcode_init_parse ();
1120 insn_buf
[opcode
->opcode_word
] = opcode
->value
;
1121 fixup_count
= init_fixup_count
;
1125 /* We don't check for (*str != '\0') here because we want to parse
1126 any trailing fake arguments in the syntax string. */
1127 for (/*str = start, */ syn
= opcode
->syntax
; *syn
!= '\0'; )
1130 const dvp_operand
*operand
;
1134 /* Non operand chars must match exactly.
1135 Operand chars that are letters are not part of symbols
1136 and are case insensitive. */
1139 if (tolower (*str
) == tolower (*syn
))
1151 /* We have a suffix or an operand. Pick out any modifiers. */
1153 index
= DVP_OPERAND_INDEX (*syn
);
1154 while (DVP_MOD_P (operand_table
[index
].flags
))
1156 mods
|= operand_table
[index
].flags
& DVP_MOD_BITS
;
1158 index
= DVP_OPERAND_INDEX (*syn
);
1160 operand
= operand_table
+ index
;
1162 if (operand
->flags
& DVP_OPERAND_FAKE
)
1166 if (operand
->flags
& DVP_OPERAND_DMA_INLINE
)
1168 inline_dma_data ((mods
& DVP_OPERAND_AUTOCOUNT
) != 0,
1177 value
= (*operand
->parse
) (opcode
, operand
, mods
,
1182 if (operand
->insert
)
1185 (*operand
->insert
) (opcode
, operand
, mods
, insn_buf
,
1186 (offsetT
) value
, &errmsg
);
1187 /* If we get an error, go on to try the next insn. */
1195 /* Are we finished with suffixes? */
1200 if (!(operand
->flags
& DVP_OPERAND_SUFFIX
))
1201 as_fatal ("internal error: bad opcode table, missing suffix flag");
1203 /* Parse the suffix. If we're at a space in the input string
1204 there are no more suffixes. Suffix parse routines must be
1205 prepared to deal with this. */
1207 suf_value
= (*operand
->parse
) (opcode
, operand
, mods
, &str
,
1211 /* This can happen, for example, in ARC's in "blle foo" and
1212 we're currently using the template "b%q%.n %j". The "bl"
1213 insn occurs later in the table so "lle" isn't an illegal
1218 /* Insert the suffix's value into the insn. */
1219 insert_operand (cpu
, opcode
, operand
, mods
, insn_buf
,
1220 (offsetT
) suf_value
, &errmsg
);
1226 /* This is an operand, either a register or an expression of
1231 if (operand
->flags
& DVP_OPERAND_SUFFIX
)
1232 as_fatal ("internal error: bad opcode table, suffix wrong");
1234 /* Is there anything left to parse?
1235 We don't check for this at the top because we want to parse
1236 any trailing fake arguments in the syntax string. */
1237 /* ??? This doesn't allow operands with a legal value of "". */
1241 /* Parse the operand. */
1242 if (operand
->flags
& DVP_OPERAND_FLOAT
)
1245 value
= parse_float (&str
, &errmsg
);
1249 else if ((operand
->flags
& DVP_OPERAND_DMA_ADDR
)
1250 && (mods
& DVP_OPERAND_AUTOCOUNT
))
1253 value
= parse_dma_addr_autocount (opcode
, operand
, mods
,
1254 insn_buf
, &str
, &errmsg
);
1260 char *origstr
,*hold
;
1263 /* First see if there is a special parser. */
1268 value
= (*operand
->parse
) (opcode
, operand
, mods
,
1274 /* If there wasn't a special parser, or there was and it
1275 left the input stream unchanged, use the general
1276 expression parser. */
1279 hold
= input_line_pointer
;
1280 input_line_pointer
= str
;
1281 /* Set cur_{opcode,operand} for md_operand. */
1282 cur_opcode
= opcode
;
1283 cur_operand
= operand
;
1286 str
= input_line_pointer
;
1287 input_line_pointer
= hold
;
1289 if (exp
.X_op
== O_illegal
1290 || exp
.X_op
== O_absent
)
1292 else if (exp
.X_op
== O_constant
)
1293 value
= exp
.X_add_number
;
1294 else if (exp
.X_op
== O_register
)
1295 as_fatal ("internal error: got O_register");
1298 /* We need to generate a fixup for this expression. */
1299 if (fixup_count
>= MAX_FIXUPS
)
1300 as_fatal ("internal error: too many fixups");
1301 fixups
[fixup_count
].cpu
= cpu
;
1302 fixups
[fixup_count
].exp
= exp
;
1303 fixups
[fixup_count
].opindex
= index
;
1304 /* FIXME: Revisit. Do we really need operand->word?
1305 The endianness of a 128 bit DMAtag is rather
1306 twisted. How about defining word 0 as the word with
1307 the lowest address and basing operand-shift off that.
1308 operand->word could then be deleted. */
1309 fixups
[fixup_count
].offset
= fixup_offset
;
1310 if (operand
->word
!= 0)
1311 fixups
[fixup_count
].offset
+= operand
->word
* 4;
1313 fixups
[fixup_count
].offset
+= (operand
->shift
/ 32) * 4;
1320 /* Insert the register or expression into the instruction. */
1322 insert_operand (cpu
, opcode
, operand
, mods
, insn_buf
,
1323 (offsetT
) value
, &errmsg
);
1324 if (errmsg
!= (const char *) NULL
)
1330 /* If we're at the end of the syntax string, we're done. */
1335 /* For the moment we assume a valid `str' can only contain blanks
1336 now. IE: We needn't try again with a longer version of the
1337 insn and it is assumed that longer versions of insns appear
1338 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
1340 while (isspace (*str
))
1344 #ifndef VERTICAL_BAR_SEPARATOR
1348 as_bad ("junk at end of line: `%s'", str
);
1350 /* It's now up to the caller to emit the instruction and any
1356 /* Try the next entry. */
1359 as_bad ("bad instruction `%s'", start
);
1363 /* Given a dvp cpu type, return it's STO_DVP value.
1364 The label prefix to use is stored in *PNAME. */
1367 cpu_sto (cpu
, pname
)
1373 case DVP_DMA
: *pname
= ".dma."; return STO_DVP_DMA
;
1374 case DVP_VIF
: *pname
= ".vif."; return STO_DVP_VIF
;
1375 case DVP_GIF
: *pname
= ".gif."; return STO_DVP_GIF
;
1376 case DVP_VUUP
: *pname
= ".vu."; return STO_DVP_VU
;
1381 /* Record the current mach type in the object file.
1382 If FORCE_NEXT_P is non-zero, force a label to be emitted the next time
1383 we're called. This is useful for variable length instructions that can
1384 have labels embedded within them. */
1387 record_mach (cpu
, force_next_p
)
1398 sto
= cpu_sto (cpu
, &name
);
1400 label
= create_colon_label (sto
, "", unique_name (name
));
1403 cur_cpu
= DVP_UNKNOWN
;
1408 /* Force emission of mach type label at next insn.
1409 This isn't static as TC_START_LABEL uses it.
1410 The result is the value of TC_START_LABEL. */
1415 cur_cpu
= DVP_UNKNOWN
;
1419 /* Push the current parsing state to NEW_STATE. */
1422 push_asm_state (new_state
)
1423 asm_state new_state
;
1425 asm_state cur_state
= CUR_ASM_STATE
;
1428 if (cur_state_level
== MAX_STATE_DEPTH
)
1429 as_fatal ("internal error: unexpected state push");
1430 asm_state_stack
[cur_state_level
] = new_state
;
1433 /* TOP_OK_P is non-zero if it's ok that we're at the top of the stack.
1434 If so we reset the state to ASM_INIT. */
1437 pop_asm_state (top_ok_p
)
1440 if (cur_state_level
== 0)
1443 as_fatal ("internal error: unexpected state pop");
1444 CUR_ASM_STATE
= ASM_INIT
;
1450 /* Set the top level assembler state. */
1453 set_asm_state (state
, insn_name
)
1455 const char *insn_name
;
1459 if (CUR_ASM_STATE
!= ASM_INIT
)
1460 as_bad ("illegal place for `%s' instruction", insn_name
);
1462 cur_state_level
= 0;
1463 CUR_ASM_STATE
= state
;
1467 md_operand (expressionP
)
1468 expressionS
*expressionP
;
1470 /* Check if this is a '*' for mpgloc. */
1472 && (cur_opcode
->flags
& VIF_OPCODE_MPG
) != 0
1473 && (cur_operand
->flags
& DVP_OPERAND_VU_ADDRESS
) != 0
1474 && *input_line_pointer
== '*')
1476 expressionP
->X_op
= O_symbol
;
1477 expressionP
->X_add_symbol
= mpgloc_sym
;
1478 expressionP
->X_add_number
= 0;
1480 /* Advance over the '*'. */
1481 ++input_line_pointer
;
1487 md_section_align (segment
, size
)
1491 int align
= bfd_get_section_alignment (stdoutput
, segment
);
1492 return ((size
+ (1 << align
) - 1) & (-1 << align
));
1496 md_undefined_symbol (name
)
1502 /* Called after parsing the file via md_after_pass_hook. */
1505 dvp_after_pass_hook ()
1507 /* If doing dma packing, ensure the last dma tag is filled out. */
1510 /* Nothing to do as vifnops are zero and frag_align at beginning
1511 of dmatag is all we need. */
1514 #if 0 /* ??? Doesn't work unless we keep track of the nested include file
1516 /* Check for missing .EndMpg, and supply one if necessary. */
1517 if (CUR_ASM_STATE
== ASM_MPG
)
1518 s_endmpg (ENDMPG_INTERNAL
);
1519 else if (CUR_ASM_STATE
== ASM_DIRECT
)
1521 else if (CUR_ASM_STATE
== ASM_UNPACK
)
1526 /* Called via tc_frob_label when a label is defined. */
1529 dvp_frob_label (sym
)
1532 const char * name
= S_GET_NAME (sym
);
1534 /* All labels in vu code must be specially marked for the disassembler.
1535 The disassembler ignores all previous information at each new label
1536 (that has a higher address than the last one). */
1537 if (CUR_ASM_STATE
== ASM_MPG
1538 || CUR_ASM_STATE
== ASM_VU
)
1539 S_SET_OTHER (sym
, STO_DVP_VU
);
1541 /* If inside an mpg, move vu space labels to their own section and create
1542 the corresponding _$ version in normal space. */
1544 if (CUR_ASM_STATE
== ASM_MPG
1545 /* Only do this special processing for user specified symbols.
1546 Not sure how we can distinguish them other than by some prefix. */
1547 && *name
!= '.' && *name
!= '$'
1548 /* Check for recursive invocation creating the _$name. */
1549 && strncmp (name
, VU_LABEL_PREFIX
, sizeof (VU_LABEL_PREFIX
) - 1) != 0
1550 /* -gstabs creates FAKE_LABEL_NAME labels. There's probably a better
1552 && ! S_IS_LOCAL (sym
))
1554 /* Move this symbol to the vu overlay. */
1555 symbolS
* cur_mpgloc
= compute_mpgloc (mpgloc_sym
, vif_data_start
,
1557 #if 0 /* Don't do this now, leave in ABS and then move to overlay
1558 section before file is written. */
1559 S_SET_SEGMENT (sym
, vuoverlay_section
);
1561 /* Record the overlay section this symbol is in. */
1563 ovlysymS
*p
= (ovlysymS
*) xmalloc (sizeof (ovlysymS
));
1564 p
->next
= ovlysym_table
;
1565 p
->sec
= vuoverlay_section
;
1569 S_SET_SEGMENT (sym
, expr_section
);
1571 sym
->sy_value
= cur_mpgloc
->sy_value
;
1572 sym
->sy_frag
= &zero_address_frag
;
1574 /* Create the _$ symbol in normal space. */
1575 create_colon_label (STO_DVP_VU
, VU_LABEL_PREFIX
, name
);
1579 /* Move vu space symbols into their overlay sections.
1580 Called via tc_frob_file. */
1587 for (p
= ovlysym_table
; p
; p
= p
->next
)
1589 /* See the comment near tc_frob_file in write.c.
1590 We are responsible for updating sym->bsym->value. */
1591 S_SET_SEGMENT (p
->sym
, p
->sec
);
1592 /* Adjust for the section's vma. */
1593 /* FIXME: bfd doesn't get this right, it adds the section vma
1594 back in (in elf.c:swap_out_syms). As a workaround the
1595 section vma is assumed to be zero. Of course, there might
1596 not be a point in setting it to non-zero anyway. */
1597 p
->sym
->bsym
->value
-= bfd_get_section_vma (stdoutput
, p
->sec
);
1601 /* mpg/direct alignment is handled via relaxation */
1603 /* Return an initial guess of the length by which a fragment must grow to
1604 hold a branch to reach its destination.
1605 Also updates fr_type/fr_subtype as necessary.
1607 Called just before doing relaxation.
1608 Any symbol that is now undefined will not become defined.
1609 The guess for fr_var is ACTUALLY the growth beyond fr_fix.
1610 Whatever we do to grow fr_fix or fr_var contributes to our returned value.
1611 Although it may not be explicit in the frag, pretend fr_var starts with a
1615 md_estimate_size_before_relax (fragP
, segment
)
1619 /* Our initial estimate is always 0. */
1623 /* Perform the relaxation.
1624 STRETCH is the amount the start of the frag has already been shifted by.
1625 All we have to do is figure out how many bytes we need to insert to
1626 get to the recorded symbol (which is at the required alignment).
1627 This function is also called for machine dependent vu insn frags.
1628 In this case the growth is always 0. */
1631 dvp_relax_frag (fragP
, stretch
)
1635 /* Address of variable part. */
1636 long address
= fragP
->fr_address
+ fragP
->fr_fix
;
1637 /* Symbol marking start of data. */
1638 symbolS
* symbolP
= fragP
->fr_symbol
;
1639 /* Address of the symbol. */
1643 /* subtype >= 10 means "done" */
1644 if (RELAX_DONE_P (fragP
->fr_subtype
))
1648 if (fragP
->fr_subtype
== RELAX_VU
)
1650 fragP
->fr_subtype
= RELAX_ENCODE (RELAX_VU
, 0);
1654 target
= S_GET_VALUE (symbolP
) + symbolP
->sy_frag
->fr_address
;
1656 if (fragP
->fr_subtype
== RELAX_MPG
)
1658 /* The frag the symbol is in hasn't been relaxed yet so any .org
1659 adjustments haven't been applied to it. We know the symbol
1660 is the address of the next frag so adjust target by stretch. */
1662 growth
= target
- address
;
1664 as_fatal ("internal error: bad mpg alignment handling");
1665 fragP
->fr_subtype
= RELAX_ENCODE (RELAX_MPG
, growth
);
1669 if (fragP
->fr_subtype
== RELAX_DIRECT
)
1671 /* The frag the symbol is in hasn't been relaxed yet so any .org
1672 adjustments haven't been applied to it. We know the symbol
1673 is the address of the next frag so adjust target by stretch. */
1675 growth
= target
- address
;
1677 as_fatal ("internal error: bad direct alignment handling");
1678 fragP
->fr_subtype
= RELAX_ENCODE (RELAX_DIRECT
, growth
);
1682 as_fatal ("internal error: unknown fr_subtype");
1685 /* *fragP has been relaxed to its final size, and now needs to have
1686 the bytes inside it modified to conform to the new size.
1688 Called after relaxation is finished.
1689 fragP->fr_type == rs_machine_dependent.
1690 fragP->fr_subtype is the subtype of what the address relaxed to. */
1693 md_convert_frag (abfd
, sec
, fragP
)
1698 int growth
= RELAX_GROWTH (fragP
->fr_subtype
);
1700 fragP
->fr_fix
+= growth
;
1704 /* We had to grow this fragment. Shift the mpg/direct insn to the end
1705 (so it abuts the following data). */
1706 DVP_INSN insn
= bfd_getl32 (fragP
->fr_opcode
);
1707 md_number_to_chars (fragP
->fr_opcode
, VIFNOP
, 4);
1709 md_number_to_chars (fragP
->fr_opcode
+ 4, VIFNOP
, 4);
1711 md_number_to_chars (fragP
->fr_opcode
+ 8, VIFNOP
, 4);
1712 md_number_to_chars (fragP
->fr_literal
+ fragP
->fr_fix
- 4, insn
, 4);
1714 /* Adjust fr_opcode so md_apply_fix3 works with the right bytes. */
1715 fragP
->fr_opcode
+= growth
;
1719 /* Functions concerning relocs. */
1721 /* Spacing between each cpu type's operand numbers.
1722 Should be at least as big as any operand table. */
1723 #define RELOC_SPACING 256
1725 /* Given a cpu type and operand number, return a temporary reloc type
1726 for use in generating the fixup that encodes the cpu type and operand
1730 encode_fixup_reloc_type (cpu
, opnum
)
1734 return (int) BFD_RELOC_UNUSED
+ ((int) cpu
* RELOC_SPACING
) + opnum
;
1737 /* Given a fixup reloc type, decode it into cpu type and operand. */
1740 decode_fixup_reloc_type (fixup_reloc
, cpuP
, operandP
)
1743 const dvp_operand
**operandP
;
1745 dvp_cpu cpu
= (fixup_reloc
- (int) BFD_RELOC_UNUSED
) / RELOC_SPACING
;
1746 int opnum
= (fixup_reloc
- (int) BFD_RELOC_UNUSED
) % RELOC_SPACING
;
1751 case DVP_VUUP
: *operandP
= &vu_operands
[opnum
]; break;
1752 case DVP_VULO
: *operandP
= &vu_operands
[opnum
]; break;
1753 case DVP_DMA
: *operandP
= &dma_operands
[opnum
]; break;
1754 case DVP_VIF
: *operandP
= &vif_operands
[opnum
]; break;
1755 case DVP_GIF
: *operandP
= &gif_operands
[opnum
]; break;
1756 default : as_fatal ("internal error: bad fixup encoding");
1760 /* The location from which a PC relative jump should be calculated,
1761 given a PC relative reloc. */
1764 md_pcrel_from_section (fixP
, sec
)
1768 if (fixP
->fx_addsy
!= (symbolS
*) NULL
1769 && (! S_IS_DEFINED (fixP
->fx_addsy
)
1770 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
1772 /* If fx_tcbit is set this is for a vif insn and thus should never
1773 happen in correct code. */
1774 /* ??? The error message could be a bit more descriptive. */
1776 as_bad ("unable to compute length of vif insn");
1777 /* The symbol is undefined (or is defined but not in this section).
1778 Let the linker figure it out. +8: branch offsets are relative to the
1783 /* If fx_tcbit is set, this is a vif end-of-variable-length-insn marker.
1784 In this case the offset is relative to the start of data.
1785 Otherwise we assume this is a vu branch. In this case
1786 offsets are calculated based on the address of the next insn. */
1789 /* As a further refinement, if fr_opcode is NULL this is `unpack'
1790 which doesn't involve any relaxing. */
1791 if (fixP
->fx_frag
->fr_opcode
== NULL
)
1792 return fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ 4;
1794 return fixP
->fx_frag
->fr_address
+ fixP
->fx_frag
->fr_fix
;
1797 return ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
) & -8L) + 8;
1800 /* Apply a fixup to the object code. This is called for all the
1801 fixups we generated by calls to fix_new_exp. At this point all symbol
1802 values should be fully resolved, and we attempt to completely resolve the
1803 reloc. If we can not do that, we determine the correct reloc code and put
1804 it back in the fixup. */
1807 md_apply_fix3 (fixP
, valueP
, seg
)
1812 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1815 /* FIXME FIXME FIXME: The value we are passed in *valueP includes
1816 the symbol values. Since we are using BFD_ASSEMBLER, if we are
1817 doing this relocation the code in write.c is going to call
1818 bfd_perform_relocation, which is also going to use the symbol
1819 value. That means that if the reloc is fully resolved we want to
1820 use *valueP since bfd_perform_relocation is not being used.
1821 However, if the reloc is not fully resolved we do not want to use
1822 *valueP, and must use fx_offset instead. However, if the reloc
1823 is PC relative, we do want to use *valueP since it includes the
1824 result of md_pcrel_from. This is confusing. */
1826 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
1831 else if (fixP
->fx_pcrel
)
1837 value
= fixP
->fx_offset
;
1838 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
1840 if (S_GET_SEGMENT (fixP
->fx_subsy
) == absolute_section
)
1841 value
-= S_GET_VALUE (fixP
->fx_subsy
);
1844 /* We can't actually support subtracting a symbol. */
1845 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1846 "expression too complex");
1851 /* Check for dvp operands. These are indicated with a reloc value
1852 >= BFD_RELOC_UNUSED. */
1854 if ((int) fixP
->fx_r_type
>= (int) BFD_RELOC_UNUSED
)
1857 const dvp_operand
*operand
;
1859 fragS
*fragP
= fixP
->fx_frag
;
1861 /* If this was a relaxable insn, the opcode may have moved. Find it. */
1862 if (fragP
->fr_opcode
!= NULL
)
1863 where
= fragP
->fr_opcode
;
1865 decode_fixup_reloc_type ((int) fixP
->fx_r_type
,
1868 /* For variable length vif insn data lengths, validate the user specified
1869 value or install the computed value in the instruction. */
1871 && (operand
- vif_operands
) == vif_operand_datalen_special
)
1873 int insn_type
= vif_insn_type (where
[3]);
1874 value
= vif_length_value (where
[3],
1875 fixP
->tc_fix_data
.wl
, fixP
->tc_fix_data
.cl
,
1877 if (fixP
->tc_fix_data
.user_value
!= -1)
1879 /* We can't do this for unpack insns with wl > cl. */
1880 if ((insn_type
!= VIF_OPCODE_UNPACK
1881 || (fixP
->tc_fix_data
.wl
<= fixP
->tc_fix_data
.cl
))
1882 && fixP
->tc_fix_data
.user_value
!= value
)
1883 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
1884 "specified length value doesn't match computed value");
1885 /* Don't override the user specified value. */
1891 install_vif_length (where
, value
);
1898 /* For the gif nloop operand, if it was specified by the user ensure
1899 it matches the value we computed. */
1901 && (operand
- gif_operands
) == gif_operand_nloop
)
1903 value
= compute_nloop (fixP
->tc_fix_data
.type
,
1904 fixP
->tc_fix_data
.nregs
,
1906 if (fixP
->tc_fix_data
.user_value
!= -1)
1908 check_nloop (fixP
->tc_fix_data
.type
,
1909 fixP
->tc_fix_data
.nregs
,
1910 fixP
->tc_fix_data
.user_value
,
1912 fixP
->fx_file
, fixP
->fx_line
);
1913 /* Don't override the user specified value. */
1919 /* ??? It might be cleaner to not do this at all here (when ! fx_done)
1920 and leave it to bfd_install_relocation. */
1921 if ((operand
->flags
& DVP_OPERAND_RELOC_U15_S3
) != 0)
1923 else if ((operand
->flags
& DVP_OPERAND_RELOC_11_S4
) != 0)
1926 /* Fetch the instruction, insert the fully resolved operand
1927 value, and stuff the instruction back again. The fixup is recorded
1928 at the appropriate word so pass DVP_MOD_THIS_WORD so any offset
1929 specified in the tables is ignored. */
1930 insn
= bfd_getl32 ((unsigned char *) where
);
1931 insert_operand_final (cpu
, operand
, DVP_MOD_THIS_WORD
, &insn
,
1932 (offsetT
) value
, fixP
->fx_file
, fixP
->fx_line
);
1933 bfd_putl32 ((bfd_vma
) insn
, (unsigned char *) where
);
1935 /* If this is mpgloc/unpackloc, we're done. */
1936 if (operand
->flags
& (DVP_OPERAND_VU_ADDRESS
| DVP_OPERAND_UNPACK_ADDRESS
))
1941 /* Nothing else to do here. */
1945 /* Determine a BFD reloc value based on the operand information.
1946 We are only prepared to turn a few of the operands into relocs. */
1947 if ((operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0)
1949 assert (operand
->bits
== 11
1950 && operand
->shift
== 0);
1952 /* The fixup isn't recorded as a pc relative branch to some label.
1953 Instead a complicated expression is used to compute the desired
1954 value. Well, that didn't work and we have to emit a reloc.
1955 Things are tricky because the result we want is the difference
1956 of two addresses in a section potentially different from the one
1957 the reloc is in. Ugh.
1958 The solution is to emit two relocs, one that adds the target
1959 address and one that subtracts the source address + 8 (the
1960 linker will perform the byte->dword conversion).
1961 This is rather complicated and rather than risk breaking
1962 existing code we fall back on the old way if the file only
1963 contains vu code. In this case the file is intended to
1964 be fully linked with other vu code and thus we have a normal
1965 situation where the relocation directly corresponds to the
1968 if (non_vu_insn_seen_p
)
1970 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1971 "can't handle mpg loaded vu code with branch relocations");
1977 fixP
->fx_r_type
= BFD_RELOC_MIPS_DVP_11_PCREL
;
1980 else if ((operand
->flags
& DVP_OPERAND_DMA_ADDR
) != 0
1981 || (operand
->flags
& DVP_OPERAND_DMA_NEXT
) != 0)
1983 assert (operand
->bits
== 27
1984 && operand
->shift
== 4);
1985 fixP
->fx_r_type
= BFD_RELOC_MIPS_DVP_27_S4
;
1987 else if ((operand
->flags
& DVP_OPERAND_RELOC_11_S4
) != 0)
1989 assert (operand
->bits
== 11
1990 && operand
->shift
== 0);
1991 fixP
->fx_r_type
= BFD_RELOC_MIPS_DVP_11_S4
;
1992 /* ??? bfd_install_relocation will duplicate what we've done to
1993 install the addend, so tell it not to. This is an instance
1994 where setting partial_inplace to true has some use. */
1997 else if ((operand
->flags
& DVP_OPERAND_RELOC_U15_S3
) != 0)
1999 assert (operand
->bits
== 15
2000 && operand
->shift
== 0);
2001 fixP
->fx_r_type
= BFD_RELOC_MIPS_DVP_U15_S3
;
2002 /* ??? bfd_install_relocation will duplicate what we've done to
2003 install the addend, so tell it not to. This is an instance
2004 where setting partial_inplace to true has some use. */
2009 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2010 "unresolved expression that must be resolved");
2015 else if (fixP
->fx_done
)
2017 /* We're finished with this fixup. Install it because
2018 bfd_install_relocation won't be called to do it. */
2019 switch (fixP
->fx_r_type
)
2022 md_number_to_chars (where
, value
, 1);
2025 md_number_to_chars (where
, value
, 2);
2028 md_number_to_chars (where
, value
, 4);
2031 md_number_to_chars (where
, value
, 8);
2034 as_fatal ("internal error: unexpected fixup");
2039 /* bfd_install_relocation will be called to finish things up. */
2042 /* Tuck `value' away for use by tc_gen_reloc.
2043 See the comment describing fx_addnumber in write.h. */
2044 fixP
->fx_addnumber
= value
;
2049 /* Translate internal representation of relocation info to BFD target
2053 tc_gen_reloc (section
, fixP
)
2059 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
2061 reloc
->sym_ptr_ptr
= &fixP
->fx_addsy
->bsym
;
2062 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
2063 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
2064 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
2066 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2067 "internal error: can't export reloc type %d (`%s')",
2068 fixP
->fx_r_type
, bfd_get_reloc_code_name (fixP
->fx_r_type
));
2072 assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
2074 reloc
->addend
= fixP
->fx_addnumber
;
2079 /* Write a value out to the object file, using the appropriate endianness. */
2082 md_number_to_chars (buf
, val
, n
)
2087 if (target_big_endian
)
2088 number_to_chars_bigendian (buf
, val
, n
);
2090 number_to_chars_littleendian (buf
, val
, n
);
2093 /* Turn a string in input_line_pointer into a floating point constant of type
2094 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
2095 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
2098 /* Equal to MAX_PRECISION in atof-ieee.c */
2099 #define MAX_LITTLENUMS 6
2102 md_atof (type
, litP
, sizeP
)
2108 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2109 LITTLENUM_TYPE
*wordP
;
2129 /* FIXME: Some targets allow other format chars for bigger sizes here. */
2133 return "Bad call to md_atof()";
2136 t
= atof_ieee (input_line_pointer
, type
, words
);
2138 input_line_pointer
= t
;
2139 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
2141 if (target_big_endian
)
2143 for (i
= 0; i
< prec
; i
++)
2145 md_number_to_chars (litP
, (valueT
) words
[i
], sizeof (LITTLENUM_TYPE
));
2146 litP
+= sizeof (LITTLENUM_TYPE
);
2151 for (i
= prec
- 1; i
>= 0; i
--)
2153 md_number_to_chars (litP
, (valueT
) words
[i
], sizeof (LITTLENUM_TYPE
));
2154 litP
+= sizeof (LITTLENUM_TYPE
);
2161 /* Miscellaneous utilities. */
2163 /* Parse a 32 bit floating point number.
2164 The result is those 32 bits as an integer. */
2167 parse_float (pstr
, errmsg
)
2169 const char **errmsg
;
2171 if ((*pstr
)[0] == '0'
2172 && ((*pstr
)[1] == 'x' || (*pstr
)[1] == 'X'))
2176 value
= strtol (*pstr
, pstr
, 16);
2181 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2182 *pstr
= atof_ieee (*pstr
, 'f', words
);
2183 return (words
[0] << 16) | words
[1];
2187 /* Scan a symbol and return a pointer to one past the end. */
2189 #define issymchar(ch) (isalnum(ch) || ch == '_')
2194 while (*sym
&& issymchar (*sym
))
2199 /* Evaluate an expression for an operand.
2200 The result is the value of the expression if it can be evaluated,
2201 or 0 if it cannot (say because some symbols haven't been defined yet)
2202 in which case a fixup is queued.
2204 If OPINDEX is 0, don't queue any fixups, just return 0. */
2208 eval_expr (dvp_cpu cpu
, int opindex
, int offset
, const char *fmt
, ...)
2210 eval_expr (cpu
, opindex
, offset
, fmt
, va_alist
)
2219 char *str
,*save_input
;
2227 vasprintf (&str
, fmt
, ap
);
2230 save_input
= input_line_pointer
;
2231 input_line_pointer
= str
;
2233 input_line_pointer
= save_input
;
2235 if (exp
.X_op
== O_constant
)
2236 value
= exp
.X_add_number
;
2241 fixups
[fixup_count
].cpu
= cpu
;
2242 fixups
[fixup_count
].exp
= exp
;
2243 fixups
[fixup_count
].opindex
= opindex
;
2244 fixups
[fixup_count
].offset
= offset
;
2245 fixups
[fixup_count
].user_value
= -1;
2246 fixups
[fixup_count
].wl
= -1;
2247 fixups
[fixup_count
].cl
= -1;
2255 /* Create a label named by concatenating PREFIX to NAME. */
2258 create_label (prefix
, name
)
2259 const char *prefix
, *name
;
2261 int namelen
= strlen (name
);
2262 int prefixlen
= strlen (prefix
);
2266 fullname
= xmalloc (prefixlen
+ namelen
+ 1);
2267 strcpy (fullname
, prefix
);
2268 strcat (fullname
, name
);
2269 result
= symbol_find_or_make (fullname
);
2274 /* Create a label named by concatenating PREFIX to NAME,
2275 and define it as `.'.
2276 STO, if non-zero, is the st_other value to assign to this label.
2277 If STO is zero `cur_cpu', call force_mach_label to force record_mach to
2278 emit a cpu label. Otherwise the disassembler gets confused. */
2281 create_colon_label (sto
, prefix
, name
)
2283 const char *prefix
, *name
;
2285 int namelen
= strlen (name
);
2286 int prefixlen
= strlen (prefix
);
2290 fullname
= xmalloc (prefixlen
+ namelen
+ 1);
2291 strcpy (fullname
, prefix
);
2292 strcat (fullname
, name
);
2293 result
= colon (fullname
);
2295 S_SET_OTHER (result
, sto
);
2297 force_mach_label ();
2302 /* Return a malloc'd string useful in creating unique labels.
2303 PREFIX is the prefix to use or NULL if we're to pick one. */
2306 unique_name (prefix
)
2313 prefix
= UNIQUE_LABEL_PREFIX
;
2314 asprintf (&result
, "%s%d", prefix
, counter
);
2321 /* Return the name of the overlay section.
2322 It must be unique among all overlays in the executable. */
2325 vuoverlay_section_name (addr
)
2330 unsigned int lineno
;
2331 unsigned int fileno
;
2332 /* One mpg may actually result in several, counter keeps track of this. */
2335 as_where (&file
, &lineno
);
2336 for (fileno
= 0; *file
; ++file
)
2337 fileno
= (fileno
<< 1) + *file
;
2338 if (addr
->sy_value
.X_op
== O_constant
)
2339 asprintf (§ion_name
, "%s.0x%x.%u.%u.%d", SHNAME_DVP_OVERLAY_PREFIX
,
2340 (int) S_GET_VALUE (addr
), fileno
, lineno
, counter
);
2342 asprintf (§ion_name
, "%s.unknvma.%u.%u.%d", SHNAME_DVP_OVERLAY_PREFIX
,
2343 fileno
, lineno
, counter
);
2345 return section_name
;
2348 /* Create a shadow section for VU code that starts at ADDR in vu space.
2349 START_LABEL and END_LABEL, if non-NULL, are symbols marking the start and
2350 end of the section. If NULL, no overlay tracking information is output. */
2353 create_vuoverlay_section (section_name
, addr
, start_label
, end_label
)
2354 const char *section_name
;
2355 /* Remember, expressions are recorded as symbols. */
2357 symbolS
*start_label
, *end_label
;
2359 /* Must preserve the current seg/subseg. */
2360 segT orig_seg
= now_seg
;
2361 subsegT orig_subseg
= now_subseg
;
2363 /* Create and get handle of a vu overlay section. All vu symbols go here.
2364 The section name must be unique in the entire executable.
2365 We achieve this by encoding the source file name and file number. Ick.
2366 ??? A cleaner way would be if mpg took a new argument that named the
2368 vuoverlay_section
= subseg_new (section_name
, 0);
2369 bfd_set_section_flags (stdoutput
, vuoverlay_section
, SEC_CODE
);
2370 /* There's no point in setting the section vma as we can't get the linker
2371 to preserve it. But what the heck ... It might be useful to the
2373 #if 0 /* FIXME: bfd's elf.c:swap_out_syms always emits symbol values with
2374 the section vma added in so we can't do this. */
2375 if (addr
->sy_value
.X_op
== O_constant
)
2376 bfd_set_section_vma (stdoutput
, vuoverlay_section
, S_GET_VALUE (addr
));
2378 /* The size of the section won't be known until we see the .endmpg,
2379 but we can compute it from the start and end labels. */
2380 /* FIXME: This causes the section to occupy space in the file. */
2382 frag_var (rs_space
, 1, 1, (relax_substateT
) 0,
2383 expr_build_binary (O_subtract
, end_label
, start_label
),
2384 (offsetT
) 0, (char *) 0);
2386 /* Create a symbol marking the start of the section. */
2387 begin_label
= create_colon_label (STO_DVP_VU
, "__start_", section_name
);
2390 #if 0 /* already done */
2391 /* Initialize $.mpgloc. */
2392 mpgloc_sym
= expr_build_uconstant (addr
);
2395 #if 0 /* $.mpgloc is kept in the ABS section. */
2396 S_SET_SEGMENT (mpgloc_sym
, vuoverlay_section
);
2399 /* Add an entry to the vu overlay table. */
2404 symbolS
* name_label
;
2406 /* Put the section name in the overlay string table. */
2408 subseg_set (vuoverlay_string_section
, 0);
2409 name_label
= create_colon_label (0, LOCAL_LABEL_PREFIX
,
2410 unique_name ("secstr"));
2411 /* FIXME: should be a utility to do this. */
2412 for (p
= section_name
; *p
; ++p
)
2413 FRAG_APPEND_1_CHAR (*p
);
2414 FRAG_APPEND_1_CHAR (0);
2416 subseg_set (vuoverlay_table_section
, 0);
2418 /* FIXME: should be a utility to do these. */
2419 /* Offset into string table. */
2420 exp
.X_op
= O_symbol
;
2421 exp
.X_add_symbol
= name_label
;
2422 exp
.X_add_number
= 0;
2423 emit_expr (&exp
, 4);
2425 /* The section's lma. */
2426 exp
.X_op
= O_symbol
;
2427 exp
.X_add_symbol
= start_label
;
2428 exp
.X_add_number
= 0;
2429 emit_expr (&exp
, 4);
2431 /* The section's vma. */
2432 exp
.X_op
= O_symbol
;
2433 exp
.X_add_symbol
= addr
;
2434 exp
.X_add_number
= 0;
2435 emit_expr (&exp
, 4);
2438 /* Restore the original seg/subseg. */
2439 subseg_set (orig_seg
, orig_subseg
);
2442 /* Compute a value for $.mpgloc given a symbol at the start of a chunk
2443 of code, the $.mpgloc value for the start, and a symbol at the end
2444 of the chunk of code. */
2447 compute_mpgloc (startloc
, startsym
, endsym
)
2454 s
= expr_build_binary (O_subtract
, endsym
, startsym
);
2455 s
= expr_build_binary (O_add
, startloc
, s
);
2459 /* Compute a value for nloop. */
2462 compute_nloop (type
, nregs
, bytes
)
2471 /* We can't compute a value if no regs were specified and there is a
2472 non-zero amount of data. Just set to something useful, a warning
2473 will be issued later. */
2476 computed_nloop
= (bytes
>> 4) / nregs
;
2481 computed_nloop
= (bytes
>> 3) / nregs
;
2484 computed_nloop
= bytes
>> 4;
2488 return computed_nloop
;
2491 /* Issue a warning if the user specified nloop value doesn't match the
2495 check_nloop (type
, nregs
, user_nloop
, computed_nloop
, file
, line
)
2497 int nregs
,user_nloop
,computed_nloop
;
2501 if (user_nloop
!= computed_nloop
)
2502 as_warn_where (file
, line
, "nloop value does not match amount of data");
2505 /* Compute the auto-count value for a DMA tag.
2506 INLINE_P is non-zero if the dma data is inline. */
2509 setup_dma_autocount (name
, insn_buf
, inline_p
)
2518 /* -1: The count is the number of following quadwords, so skip the one
2519 containing the dma tag. */
2520 count
= eval_expr (DVP_DMA
, dma_operand_count
, 0,
2521 "((%s%s - %s) >> 4) - 1", END_LABEL_PREFIX
, name
, name
);
2525 /* We don't want to subtract 1 here as the begin and end labels
2526 properly surround the data we want to compute the length of. */
2527 count
= eval_expr (DVP_DMA
, dma_operand_count
, 0,
2528 "(%s%s - %s) >> 4", END_LABEL_PREFIX
, name
, name
);
2531 /* Store the count field. */
2532 insn_buf
[0] &= 0xffff0000;
2533 insn_buf
[0] |= count
& 0x0000ffff;
2536 /* Record that inline data follows. */
2539 inline_dma_data (autocount_p
, insn_buf
)
2543 if (dma_data_state
!= 0 )
2545 as_bad ("DmaData blocks cannot be nested.");
2553 dma_data_name
= S_GET_NAME (create_colon_label (0, "", unique_name (NULL
)));
2554 setup_dma_autocount (dma_data_name
, insn_buf
, 1);
2560 /* Compute the auto-count value for a DMA tag with out-of-line data. */
2563 parse_dma_addr_autocount (opcode
, operand
, mods
, insn_buf
, pstr
, errmsg
)
2564 const dvp_opcode
*opcode
;
2565 const dvp_operand
*operand
;
2569 const char **errmsg
;
2571 char *start
= *pstr
;
2574 /* Data reference must be a .DmaData label. */
2575 symbolS
*label
, *label2
, *endlabel
;
2580 if (! is_name_beginner (*start
))
2582 *errmsg
= "invalid .DmaData label";
2587 end
= scan_symbol (name
);
2590 label
= symbol_find_or_make (name
);
2593 /* Use the same prefix as vu labels here. */
2594 label2
= create_label (VU_LABEL_PREFIX
, name
);
2595 endlabel
= create_label (END_LABEL_PREFIX
, name
);
2597 retval
= eval_expr (DVP_DMA
, dma_operand_addr
, 4, name
);
2599 setup_dma_autocount (name
, insn_buf
, 0);
2605 /* Compute the type of vif insn of IBYTE.
2606 IBYTE is the msb of the insn.
2607 This is only used for mpg,direct,unpack insns.
2608 The result is one of VIF_OPCODE_{DIRECT,DIRECTHL,MPG,UNPACK}. */
2611 vif_insn_type (ibyte
)
2614 switch (ibyte
& 0x70)
2617 return (ibyte
& 1) ? VIF_OPCODE_DIRECTHL
: VIF_OPCODE_DIRECT
;
2619 return VIF_OPCODE_MPG
;
2622 return VIF_OPCODE_UNPACK
;
2624 as_fatal ("internal error: bad call to vif_insn_type");
2628 /* Return the length value to insert in a VIF instruction whose upper
2629 byte is IBYTE and whose data length is BYTES.
2630 WL,CL are used for unpack insns and are the stcycl values in effect.
2631 This does not do the max -> 0 conversion. */
2634 vif_length_value (ibyte
, wl
, cl
, bytes
)
2639 switch (ibyte
& 0x70)
2641 case 0x50 : /* direct */
2642 /* ??? Worry about data /= 16 cuts off? */
2644 case 0x40 : /* mpg */
2645 /* ??? Worry about data /= 8 cuts off? */
2647 case 0x60 : /* unpack */
2649 return vif_unpack_len_value (ibyte
& 15, wl
, cl
, bytes
);
2651 as_fatal ("internal error: bad call to vif_length_value");
2655 /* Install length LEN in the vif insn at BUF.
2656 LEN is the actual value to store, except that the max->0 conversion
2657 hasn't been done (we do it).
2658 The bytes in BUF are in target order. */
2661 install_vif_length (buf
, len
)
2665 unsigned char ibyte
= buf
[3];
2667 if ((ibyte
& 0x70) == 0x40)
2671 as_bad ("`mpg' data length must be between 1 and 256");
2672 buf
[2] = len
== 256 ? 0 : len
;
2674 else if ((ibyte
& 0x70) == 0x50)
2676 /* direct/directhl */
2678 as_bad ("`direct' data length must be between 1 and 65536");
2679 len
= len
== 65536 ? 0 : len
;
2683 else if ((ibyte
& 0x60) == 0x60)
2686 /* len == -1 means wl,cl are unknown and thus we can't compute
2690 as_bad ("missing `stcycle', can't compute length of `unpack' insn");
2693 if (len
< 0 || len
> 256)
2694 as_bad ("`unpack' data length must be between 0 and 256");
2695 /* 256 is recorded as 0 in the insn */
2696 len
= len
== 256 ? 0 : len
;
2700 as_fatal ("internal error: bad call to install_vif_length");
2703 /* Finish off the current set of mpg insns, and start a new set.
2704 The IGNORE arg exists because insert_unpack_marker uses it and both
2705 of these functions are passed to insert_file. */
2708 insert_mpg_marker (ignore
)
2709 unsigned long ignore
;
2711 s_endmpg (ENDMPG_MIDDLE
);
2712 /* mpgloc is updated by s_endmpg. */
2713 md_assemble ("mpg *,*");
2714 /* Record the cpu type in case we're in the middle of reading binary
2716 record_mach (DVP_VUUP
, 0);
2719 /* Finish off the current unpack insn and start a new one.
2720 INSN0 is the first word of the insn and is used to figure out what
2721 kind of unpack insn it is. */
2724 insert_unpack_marker (insn0
)
2725 unsigned long insn0
;
2729 /* Insert a file into the output.
2730 The -I arg passed to GAS is used to specify where to find the file.
2731 INSERT_MARKER if non-NULL is called every SIZE bytes with an argument of
2732 INSERT_MARKER_ARG. This is used by the mpg insn to insert mpg's every 256
2733 insns and by the unpack insn.
2734 The result is the number of bytes inserted.
2735 If an error occurs an error message is printed and zero is returned. */
2738 insert_file (file
, insert_marker
, insert_marker_arg
, size
)
2740 void (*insert_marker
) PARAMS ((unsigned long));
2741 unsigned long insert_marker_arg
;
2746 int i
, n
, total
, left_before_marker
;
2749 path
= xmalloc (strlen (file
) + include_dir_maxlen
+ 5 /*slop*/);
2751 for (i
= 0; i
< include_dir_count
; i
++)
2753 strcpy (path
, include_dirs
[i
]);
2755 strcat (path
, file
);
2756 if ((f
= fopen (path
, FOPEN_RB
)) != NULL
)
2761 f
= fopen (file
, FOPEN_RB
);
2764 as_bad ("unable to read file `%s'", file
);
2769 left_before_marker
= 0;
2773 bytes
= MIN (size
- left_before_marker
, sizeof (buf
));
2775 bytes
= sizeof (buf
);
2776 n
= fread (buf
, 1, bytes
, f
);
2779 char *fr
= frag_more (n
);
2780 memcpy (fr
, buf
, n
);
2784 left_before_marker
+= n
;
2785 if (left_before_marker
> size
)
2786 as_fatal ("internal error: file insertion sanity checky failed");
2787 if (left_before_marker
== size
)
2789 (*insert_marker
) (insert_marker_arg
);
2790 left_before_marker
= 0;
2797 /* We assume the file is smaller than 2^31 bytes.
2798 Ok, we shouldn't make any assumptions. */
2802 /* Insert an operand value into an instruction. */
2805 insert_operand (cpu
, opcode
, operand
, mods
, insn_buf
, val
, errmsg
)
2807 const dvp_opcode
*opcode
;
2808 const dvp_operand
*operand
;
2812 const char **errmsg
;
2814 if (operand
->insert
)
2816 (*operand
->insert
) (opcode
, operand
, mods
, insn_buf
, (long) val
, errmsg
);
2820 /* We currently assume a field does not cross a word boundary. */
2821 int shift
= ((mods
& DVP_MOD_THIS_WORD
)
2822 ? (operand
->shift
& 31)
2824 /* FIXME: revisit */
2825 if (operand
->word
== 0)
2827 int word
= (mods
& DVP_MOD_THIS_WORD
) ? 0 : (shift
/ 32);
2828 if (operand
->bits
== 32)
2829 insn_buf
[word
] = val
;
2833 insn_buf
[word
] |= ((long) val
& ((1 << operand
->bits
) - 1)) << shift
;
2838 int word
= (mods
& DVP_MOD_THIS_WORD
) ? 0 : operand
->word
;
2839 if (operand
->bits
== 32)
2840 insn_buf
[word
] = val
;
2843 long temp
= (long) val
& ((1 << operand
->bits
) - 1);
2844 insn_buf
[word
] |= temp
<< operand
->shift
;
2850 /* Insert an operand's final value into an instruction.
2851 Here we can give warning messages about operand values if we want to. */
2854 insert_operand_final (cpu
, operand
, mods
, insn_buf
, val
, file
, line
)
2856 const dvp_operand
*operand
;
2863 if (operand
->bits
!= 32)
2865 offsetT min
, max
, test
;
2867 /* ??? This test belongs more properly in the insert handler. */
2868 if ((operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0)
2872 if (file
== (char *) NULL
)
2873 as_warn ("branch to misaligned address");
2875 as_warn_where (file
, line
, "branch to misaligned address");
2879 /* ??? This test belongs more properly in the insert handler. */
2880 else if ((operand
->flags
& DVP_OPERAND_VU_ADDRESS
) != 0)
2884 if (file
== (char *) NULL
)
2885 as_warn ("misaligned vu address");
2887 as_warn_where (file
, line
, "misaligned vu address");
2892 if ((operand
->flags
& DVP_OPERAND_SIGNED
) != 0)
2894 if ((operand
->flags
& DVP_OPERAND_SIGNOPT
) != 0)
2895 max
= (1 << operand
->bits
) - 1;
2897 max
= (1 << (operand
->bits
- 1)) - 1;
2898 min
= - (1 << (operand
->bits
- 1));
2902 max
= (1 << operand
->bits
) - 1;
2906 if ((operand
->flags
& DVP_OPERAND_NEGATIVE
) != 0)
2911 if (test
< (offsetT
) min
|| test
> (offsetT
) max
)
2914 "operand out of range (%s not between %ld and %ld)";
2917 sprint_value (buf
, test
);
2918 if (file
== (char *) NULL
)
2919 as_warn (err
, buf
, min
, max
);
2921 as_warn_where (file
, line
, err
, buf
, min
, max
);
2926 const char *errmsg
= NULL
;
2927 insert_operand (cpu
, NULL
, operand
, mods
, insn_buf
, val
, &errmsg
);
2929 as_warn_where (file
, line
, errmsg
);
2933 /* DVP pseudo ops. */
2943 if (dma_data_state
!= 0)
2945 as_bad ("DmaData blocks cannot be nested.");
2946 ignore_rest_of_line ();
2951 SKIP_WHITESPACE (); /* Leading whitespace is part of operand. */
2952 name
= input_line_pointer
;
2954 if (!is_name_beginner (*name
))
2956 as_bad ("invalid identifier for \".DmaData\"");
2957 ignore_rest_of_line ();
2961 /* Do an implicit alignment to a 16 byte boundary. */
2962 frag_align (4, 0, 0);
2963 record_alignment (now_seg
, 4);
2965 c
= get_symbol_end ();
2966 line_label
= colon (name
); /* user-defined label */
2967 dma_data_name
= S_GET_NAME (line_label
);
2968 *input_line_pointer
= c
;
2970 /* Force emission of a machine type label for the next insn. */
2971 force_mach_label ();
2973 demand_empty_rest_of_line ();
2977 s_enddmadata (ignore
)
2980 if (dma_data_state
!= 1)
2982 as_warn (".EndDmaData encountered outside a DmaData block -- ignored.");
2983 ignore_rest_of_line ();
2987 demand_empty_rest_of_line ();
2989 /* If count provided, verify it is correct. */
2992 /* Fill the data out to a multiple of 16 bytes. */
2993 /* FIXME: Are the fill contents right? */
2994 frag_align (4, 0, 0);
2996 /* "label" points to beginning of block.
2997 Create a name for the final label like _$<name>. */
2999 create_colon_label (0, END_LABEL_PREFIX
, dma_data_name
);
3003 s_dmapackvif (ignore
)
3006 /* Syntax: .dmapackvif 0|1 */
3008 /* Leading whitespace is part of operand. */
3010 switch (*input_line_pointer
++)
3019 as_bad ("illegal argument to `.dmapackvif'");
3021 demand_empty_rest_of_line ();
3024 /* INTERNAL_P is non-zero if invoked internally by this file rather than
3025 by the user. In this case we don't touch the input stream. */
3028 s_enddirect (internal_p
)
3031 if (CUR_ASM_STATE
!= ASM_DIRECT
)
3033 as_bad ("`.enddirect' has no matching `direct' instruction");
3037 /* Record in the end data symbol the current location. */
3038 if (now_seg
!= S_GET_SEGMENT (vif_data_end
))
3039 as_bad (".enddirect in different section");
3040 vif_data_end
->sy_frag
= frag_now
;
3041 S_SET_VALUE (vif_data_end
, (valueT
) frag_now_fix ());
3045 /* Needn't be reset, but to catch bugs it is. */
3046 vif_data_end
= NULL
;
3049 demand_empty_rest_of_line ();
3052 /* CALLER denotes who's calling us.
3053 If ENDMPG_USER then .endmpg was found in the input stream.
3054 If ENDMPG_INTERNAL then we've been invoked to finish off file insertion.
3055 If ENDMPG_MIDDLE then we've been invoked in the middle of a long stretch
3062 if (CUR_ASM_STATE
!= ASM_MPG
)
3064 as_bad ("`.endmpg' has no matching `mpg' instruction");
3068 /* Record in the end data symbol the current location. */
3069 if (now_seg
!= S_GET_SEGMENT (vif_data_end
))
3070 as_bad (".endmpg in different section");
3071 vif_data_end
->sy_frag
= frag_now
;
3072 S_SET_VALUE (vif_data_end
, (valueT
) frag_now_fix ());
3075 We have to leave the old value alone as it may be used in fixups
3076 already recorded. Since compute_mpgloc allocates a new symbol for the
3077 result we're ok. The new value is the old value plus the number of
3078 double words in this chunk. */
3079 mpgloc_sym
= compute_mpgloc (mpgloc_sym
, vif_data_start
, vif_data_end
);
3083 /* Needn't be reset, but to catch bugs it is. */
3084 vif_data_end
= NULL
;
3086 /* Reset the vu insn counter. */
3087 if (caller
!= ENDMPG_MIDDLE
)
3090 if (caller
== ENDMPG_USER
)
3091 demand_empty_rest_of_line ();
3094 /* INTERNAL_P is non-zero if invoked internally by this file rather than
3095 by the user. In this case we don't touch the input stream. */
3098 s_endunpack (internal_p
)
3101 if (CUR_ASM_STATE
!= ASM_UNPACK
)
3103 as_bad ("`.endunpack' has no matching `unpack' instruction");
3107 /* Record in the end data symbol the current location. */
3108 /* ??? $.unpackloc is gone. Is this also used for data length
3110 if (now_seg
!= S_GET_SEGMENT (vif_data_end
))
3111 as_bad (".endunpack in different section");
3112 vif_data_end
->sy_frag
= frag_now
;
3113 S_SET_VALUE (vif_data_end
, (valueT
) frag_now_fix ());
3115 /* Round up to next word boundary. */
3116 frag_align (2, 0, 0);
3120 /* Needn't be reset, but to catch bugs it is. */
3121 vif_data_end
= NULL
;
3124 demand_empty_rest_of_line ();
3132 int specified_nloop
= gif_nloop ();
3134 int nregs
= gif_nregs ();
3138 as_where (&file
, &line
);
3140 if (CUR_ASM_STATE
!= ASM_GIF
)
3142 as_bad (".endgif doesn't follow a gif tag");
3147 /* Fill out to proper boundary.
3148 ??? This may cause eval_expr to always queue a fixup. So be it. */
3149 switch (gif_insn_type
)
3151 case GIF_PACKED
: frag_align (4, 0, 0); break;
3152 case GIF_REGLIST
: frag_align (3, 0, 0); break;
3153 case GIF_IMAGE
: frag_align (4, 0, 0); break;
3156 /* The -16 is because the `gif_data_name' label is emitted at the
3157 start of the gif tag. If we're in a different frag from the one we
3158 started with, this can't be computed until much later. To cope we queue
3159 a fixup and deal with it then.
3160 ??? The other way to handle this is by having expr() compute "syma - symb"
3161 when they're in different fragments but the difference is constant.
3162 Not sure how much of a slowdown that will introduce though. */
3164 bytes
= eval_expr (DVP_GIF
, gif_operand_nloop
, 0, ". - %s - 16", gif_data_name
);
3166 /* Compute a value for nloop if we can. */
3168 if (fixup_count
== 0)
3170 computed_nloop
= compute_nloop (gif_insn_type
, nregs
, bytes
);
3172 /* If the user specified nloop, verify it. */
3173 if (specified_nloop
!= -1)
3174 check_nloop (gif_insn_type
, nregs
,
3175 specified_nloop
, computed_nloop
,
3179 /* If computation of nloop can't be done yet, queue a fixup and do it later.
3180 Otherwise validate nloop if specified or write the computed value into
3183 if (fixup_count
!= 0)
3185 /* FIXME: It might eventually be possible to combine all the various
3186 copies of this bit of code. */
3187 int op_type
, reloc_type
, offset
;
3188 const dvp_operand
*operand
;
3191 op_type
= fixups
[0].opindex
;
3192 offset
= fixups
[0].offset
;
3193 reloc_type
= encode_fixup_reloc_type (DVP_GIF
, op_type
);
3194 operand
= &gif_operands
[op_type
];
3195 fix
= fix_new_exp (gif_insn_frag
,
3196 (gif_insn_frag_loc
+ offset
3197 - gif_insn_frag
->fr_literal
),
3198 4, &fixups
[0].exp
, 0,
3199 (bfd_reloc_code_real_type
) reloc_type
);
3200 /* Record user specified value so we can test it when we compute the
3202 fix
->tc_fix_data
.type
= gif_insn_type
;
3203 fix
->tc_fix_data
.nregs
= nregs
;
3204 fix
->tc_fix_data
.user_value
= specified_nloop
;
3206 else if (specified_nloop
!= -1)
3207 ; /* nothing to do */
3210 DVP_INSN insn
= bfd_getl32 (gif_insn_frag_loc
);
3211 insert_operand_final (DVP_GIF
, &gif_operands
[gif_operand_nloop
],
3212 DVP_MOD_THIS_WORD
, &insn
,
3213 (offsetT
) computed_nloop
, file
, line
);
3214 bfd_putl32 ((bfd_vma
) insn
, gif_insn_frag_loc
);
3217 /* These needn't be reset, but to catch bugs they are. */
3218 gif_data_name
= NULL
;
3219 gif_insn_frag
= NULL
;
3220 gif_insn_frag_loc
= NULL
;
3222 demand_empty_rest_of_line ();
3229 /* If in MPG state and the user requests to change to VU state,
3230 leave the state as MPG. This happens when we see an mpg followed
3231 by a .include that has .vu. Note that no attempt is made to support
3232 an include depth > 1 for this case. */
3233 if (CUR_ASM_STATE
== ASM_MPG
)
3236 /* We need to set up things for $.mpgloc calculations. */
3237 /* FIXME: May need to check that we're not clobbering currently
3238 in use versions of these. Also need to worry about which section
3239 the .vu is issued in. On the other hand, ".vu" isn't intended
3240 to be supported everywhere. */
3241 vif_data_start
= expr_build_dot ();
3242 mpgloc_sym
= expr_build_uconstant (0);
3244 create_vuoverlay_section (vuoverlay_section_name (NULL
), mpgloc_sym
,
3248 set_asm_state (ASM_VU
, ".vu");
3250 demand_empty_rest_of_line ();
3253 /* Same as read.c:s_func except prepend VU_LABEL_PREFIX by default. */
3259 do_s_func (end_p
, VU_LABEL_PREFIX
);