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 /* Compute DMA operand index number of OP. */
39 #define DMA_OPERAND_INDEX(op) ((op) - dma_operands)
41 /* Our local label prefix. */
42 #define LOCAL_LABEL_PREFIX ".L"
43 /* Label prefix for end markers used in autocounts. */
44 #define END_LABEL_PREFIX ".L.end."
46 static long parse_float
PARAMS ((char **, const char **));
47 static struct symbol
* create_label
PARAMS ((const char *, const char *));
48 static struct symbol
* create_colon_label
PARAMS ((const char *, const char *));
49 static char * unique_name
PARAMS ((void));
50 static long eval_expr
PARAMS ((int, int, const char *, ...));
51 static long parse_dma_addr_autocount ();
52 static void inline_dma_data
PARAMS ((int, DVP_INSN
*));
53 static void setup_autocount
PARAMS ((const char *, DVP_INSN
*));
55 static void insert_operand
56 PARAMS ((dvp_cpu
, const dvp_opcode
*, const dvp_operand
*, int,
57 DVP_INSN
*, offsetT
, const char **));
58 static void insert_operand_final
59 PARAMS ((dvp_cpu
, const dvp_operand
*, int,
60 DVP_INSN
*, offsetT
, char *, unsigned int));
62 static int insert_file
PARAMS ((const char *));
64 static int cur_vif_insn_length
PARAMS ((void));
65 static void install_vif_length
PARAMS ((char *, int));
67 const char comment_chars
[] = ";";
68 const char line_comment_chars
[] = "#";
69 const char line_separator_chars
[] = "!";
70 const char EXP_CHARS
[] = "eE";
71 const char FLT_CHARS
[] = "dD";
73 /* Current assembler state.
74 Instructions like mpg and direct are followed by a restricted set of
75 instructions. In the case of a '*' length argument an end marker must
76 be provided. (e.g. mpg is followed by vu insns until a .EndMpg is
79 ASM_INIT
, ASM_MPG
, ASM_DIRECT
, ASM_UNPACK
, ASM_VU
, ASM_GIF
81 static asm_state cur_asm_state
= ASM_INIT
;
83 /* Nonzero if inside .DmaData. */
84 static int dma_data_state
= 0;
85 /* Label of .DmaData (internally generated for inline data). */
86 static const char *dma_data_name
;
88 /* Type of gif tag. */
89 static gif_type gif_insn_type
;
90 /* Name of label of current gif<foo> insn's data. */
91 static const char *gif_data_name
;
92 /* Pointer to current gif insn in fragment. */
93 static char *gif_insn_frag
;
95 /* For variable length instructions, pointer to the initial frag
96 and pointer into that frag. These only hold valid values if
97 cur_asm_state is one of ASM_MPG, ASM_DIRECT, ASM_UNPACK. */
98 static fragS
*cur_varlen_frag
;
99 static char *cur_varlen_insn
;
100 /* The length value specified in the insn, or -1 if '*'. */
101 static int cur_varlen_value
;
103 /* Non-zero if packing vif instructions in dma tags. */
104 static int dma_pack_vif_p
;
106 /* Non-zero if dma insns are to be included in the output.
107 This is the default, but writing "if (! no_dma)" is klunky. */
108 static int output_dma
= 1;
109 /* Non-zero if vif insns are to be included in the output. */
110 static int output_vif
= 1;
112 const char *md_shortopts
= "";
114 struct option md_longopts
[] =
116 #define OPTION_NO_DMA (OPTION_MD_BASE + 1)
117 { "no-dma", no_argument
, NULL
, OPTION_NO_DMA
},
118 #define OPTION_NO_DMA_VIF (OPTION_NO_DMA + 1)
119 { "no-dma-vif", no_argument
, NULL
, OPTION_NO_DMA_VIF
},
121 {NULL
, no_argument
, NULL
, 0}
123 size_t md_longopts_size
= sizeof(md_longopts
);
126 md_parse_option (c
, arg
)
135 case OPTION_NO_DMA_VIF
:
146 md_show_usage (stream
)
151 -no-dma do not include DMA instructions in the output\n\
152 -no-dma-vif do not include DMA or VIF instructions in the output\n\
156 /* Set by md_assemble for use by dvp_fill_insn. */
157 static subsegT prev_subseg
;
158 static segT prev_seg
;
160 static void s_dmadata
PARAMS ((int));
161 static void s_enddmadata
PARAMS ((int));
162 static void s_dmapackvif
PARAMS ((int));
163 static void s_enddirect
PARAMS ((int));
164 static void s_endgif
PARAMS ((int));
165 static void s_endmpg
PARAMS ((int));
166 static void s_endunpack
PARAMS ((int));
167 static void s_state
PARAMS ((int));
169 /* The target specific pseudo-ops which we support. */
170 const pseudo_typeS md_pseudo_table
[] =
173 { "dmadata", s_dmadata
, 0 },
174 { "dmapackvif", s_dmapackvif
, 0 },
175 { "enddirect", s_enddirect
, 0 },
176 { "enddmadata", s_enddmadata
, 0 },
177 { "endgif", s_endgif
, 0 },
178 { "endmpg", s_endmpg
, 0 },
179 { "endunpack", s_endunpack
, 0 },
180 /* .vu added to simplify debugging and creation of input files */
181 { "vu", s_state
, ASM_VU
},
192 /* Save the current subseg so we can restore it [it's the default one and
193 we don't want the initial section to be .sbss. */
197 subseg_set (seg
, subseg
);
199 /* Initialize the opcode tables.
200 This involves computing the hash chains. */
201 dvp_opcode_init_tables (0);
203 cur_asm_state
= ASM_INIT
;
207 /* We need to keep a list of fixups. We can't simply generate them as
208 we go, because that would require us to first create the frag, and
209 that would screw up references to ``.''. */
213 /* index into `dvp_operands' */
215 /* byte offset from beginning of instruction */
222 static int fixup_count
;
223 static struct dvp_fixup fixups
[MAX_FIXUPS
];
225 /* Given a cpu type and operand number, return a temporary reloc type
226 for use in generating the fixup that encodes the cpu type and operand. */
227 static int encode_fixup_reloc_type
PARAMS ((dvp_cpu
, int));
228 /* Given an encoded fixup reloc type, decode it into cpu and operand. */
229 static void decode_fixup_reloc_type
PARAMS ((int, dvp_cpu
*,
230 const dvp_operand
**));
232 static void assemble_dma
PARAMS ((char *));
233 static void assemble_gif
PARAMS ((char *));
234 static void assemble_vif
PARAMS ((char *));
235 static void assemble_vu
PARAMS ((char *));
236 static const dvp_opcode
* assemble_vu_insn
PARAMS ((dvp_cpu
,
240 static const dvp_opcode
* assemble_one_insn
PARAMS ((dvp_cpu
,
243 char **, DVP_INSN
*));
245 /* Main entry point for assembling an instruction. */
251 /* Skip leading white space. */
252 while (isspace (*str
))
255 /* After a gif tag, no insns can appear until a .endgif is seen. */
256 if (cur_asm_state
== ASM_GIF
)
258 as_bad ("missing .endgif");
259 cur_asm_state
= ASM_INIT
;
262 if (cur_asm_state
== ASM_INIT
)
264 if (strncasecmp (str
, "dma", 3) == 0)
266 else if (strncasecmp (str
, "gif", 3) == 0)
271 else if (cur_asm_state
== ASM_DIRECT
)
273 else if (cur_asm_state
== ASM_VU
274 || cur_asm_state
== ASM_MPG
)
277 as_fatal ("unknown parse state");
280 /* Subroutine of md_assemble to assemble DMA instructions. */
286 DVP_INSN insn_buf
[4];
287 /* Insn's length, in 32 bit words. */
289 /* Pointer to allocated frag. */
292 const dvp_opcode
*opcode
;
294 /* Fill the first two words with VIF NOPs.
295 They may be over-written later if DmaPackPke is on.
296 initialize the remainder with zeros. */
302 opcode
= assemble_one_insn (DVP_DMA
,
303 dma_opcode_lookup_asm (str
), dma_operands
,
310 /* Do an implicit alignment to a 16 byte boundary. */
311 frag_align (4, 0, 0);
312 record_alignment (now_seg
, 4);
315 f
= frag_more (len
* 4);
317 /* Write out the DMA instruction. */
318 for (i
= 0; i
< len
; ++i
)
319 md_number_to_chars (f
+ i
* 4, insn_buf
[i
], 4);
321 /* Create any fixups. */
322 /* FIXME: It might eventually be possible to combine all the various
323 copies of this bit of code. */
324 for (i
= 0; i
< fixup_count
; ++i
)
326 int op_type
, reloc_type
, offset
;
327 const dvp_operand
*operand
;
329 /* Create a fixup for this operand.
330 At this point we do not use a bfd_reloc_code_real_type for
331 operands residing in the insn, but instead just use the
332 operand index. This lets us easily handle fixups for any
333 operand type, although that is admittedly not a very exciting
334 feature. We pick a BFD reloc type in md_apply_fix. */
336 op_type
= fixups
[i
].opindex
;
337 offset
= fixups
[i
].offset
;
338 reloc_type
= encode_fixup_reloc_type (DVP_DMA
, op_type
);
339 operand
= &dma_operands
[op_type
];
340 fix_new_exp (frag_now
, f
+ offset
- frag_now
->fr_literal
, 4,
342 (operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0,
343 (bfd_reloc_code_real_type
) reloc_type
);
347 /* Subroutine of md_assemble to assemble VIF instructions. */
353 /* Space for the instruction.
354 The variable length insns can require much more space than this.
355 It is allocated later, when we know we have such an insn. */
356 DVP_INSN insn_buf
[5];
357 /* Insn's length, in 32 bit words. */
359 /* Pointer to allocated frag. */
362 const dvp_opcode
*opcode
;
364 opcode
= assemble_one_insn (DVP_VIF
,
365 vif_opcode_lookup_asm (str
), vif_operands
,
370 if (opcode
->flags
& VIF_OPCODE_LENVAR
)
371 len
= 1; /* actual data follows later */
372 else if (opcode
->flags
& VIF_OPCODE_LEN2
)
374 else if (opcode
->flags
& VIF_OPCODE_LEN5
)
379 /* We still have to switch modes (if mpg for example) so we can't exit
383 /* Reminder: it is important to fetch enough space in one call to
384 `frag_more'. We use (f - frag_now->fr_literal) to compute where
385 we are and we don't want frag_now to change between calls. */
386 f
= frag_more (len
* 4);
388 /* Write out the instruction. */
389 for (i
= 0; i
< len
; ++i
)
390 md_number_to_chars (f
+ i
* 4, insn_buf
[i
], 4);
392 /* Create any fixups. */
393 /* FIXME: It might eventually be possible to combine all the various
394 copies of this bit of code. */
395 for (i
= 0; i
< fixup_count
; ++i
)
397 int op_type
, reloc_type
, offset
;
398 const dvp_operand
*operand
;
400 /* Create a fixup for this operand.
401 At this point we do not use a bfd_reloc_code_real_type for
402 operands residing in the insn, but instead just use the
403 operand index. This lets us easily handle fixups for any
404 operand type, although that is admittedly not a very exciting
405 feature. We pick a BFD reloc type in md_apply_fix. */
407 op_type
= fixups
[i
].opindex
;
408 offset
= fixups
[i
].offset
;
409 reloc_type
= encode_fixup_reloc_type (DVP_VIF
, op_type
);
410 operand
= &vif_operands
[op_type
];
411 fix_new_exp (frag_now
, f
+ offset
- frag_now
->fr_literal
, 4,
413 (operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0,
414 (bfd_reloc_code_real_type
) reloc_type
);
418 /* Handle variable length insns. */
420 if (opcode
->flags
& VIF_OPCODE_LENVAR
)
422 /* Name of file to read data from. */
424 /* Length in 32 bit words. */
429 vif_get_var_data (&file
, &data_len
);
432 int byte_len
= insert_file (file
);
434 install_vif_length (f
, byte_len
);
435 /* Update $.MpgLoc. */
436 vif_set_mpgloc (vif_get_mpgloc () + byte_len
);
440 /* data_len == -1 means the value must be computed from
442 if (data_len
== 0 || data_len
< -2)
443 as_bad ("invalid data length");
444 cur_varlen_frag
= frag_now
;
446 cur_varlen_value
= data_len
;
447 if (opcode
->flags
& VIF_OPCODE_MPG
)
448 cur_asm_state
= ASM_MPG
;
449 else if (opcode
->flags
& VIF_OPCODE_DIRECT
)
450 cur_asm_state
= ASM_DIRECT
;
451 else if (opcode
->flags
& VIF_OPCODE_UNPACK
)
452 cur_asm_state
= ASM_UNPACK
;
457 /* Subroutine of md_assemble to assemble GIF instructions. */
463 DVP_INSN insn_buf
[4];
464 const dvp_opcode
*opcode
;
468 insn_buf
[0] = insn_buf
[1] = insn_buf
[2] = insn_buf
[3] = 0;
470 opcode
= assemble_one_insn (DVP_GIF
,
471 gif_opcode_lookup_asm (str
), gif_operands
,
476 /* Do an implicit alignment to a 16 byte boundary. */
477 frag_align (4, 0, 0);
478 record_alignment (now_seg
, 4);
480 gif_insn_frag
= f
= frag_more (16);
481 for (i
= 0; i
< 4; ++i
)
482 md_number_to_chars (f
+ i
* 4, insn_buf
[i
], 4);
484 /* Insert a label so we can compute the number of quadwords when the
486 gif_data_name
= S_GET_NAME (create_colon_label ("", unique_name ()));
488 /* Record the type of the gif tag so we know how to compute nloop
490 if (strcmp (opcode
->mnemonic
, "gifpacked") == 0)
491 gif_insn_type
= GIF_PACKED
;
492 else if (strcmp (opcode
->mnemonic
, "gifreglist") == 0)
493 gif_insn_type
= GIF_REGLIST
;
494 else if (strcmp (opcode
->mnemonic
, "gifimage") == 0)
495 gif_insn_type
= GIF_IMAGE
;
498 cur_asm_state
= ASM_GIF
;
501 /* Subroutine of md_assemble to assemble VU instructions. */
507 /* The lower instruction has the lower address.
508 Handle this by grabbing 8 bytes now, and then filling each word
510 char *f
= frag_more (8);
511 const dvp_opcode
*opcode
;
513 #ifdef VERTICAL_BAR_SEPARATOR
514 char *p
= strchr (str
, '|');
518 as_bad ("lower slot missing in `%s'", str
);
523 opcode
= assemble_vu_insn (DVP_VUUP
,
524 vu_upper_opcode_lookup_asm (str
), vu_operands
,
529 opcode
= assemble_vu_insn (DVP_VUUP
,
530 vu_upper_opcode_lookup_asm (str
), vu_operands
,
534 /* Don't assemble next one if we couldn't assemble the first. */
537 opcode
= assemble_vu_insn (DVP_VULO
,
538 vu_lower_opcode_lookup_asm (str
), vu_operands
,
540 /* If this was the "loi" pseudo-insn, we need to set the `i' bit. */
543 if (strcmp (opcode
->mnemonic
, "loi") == 0)
548 static const dvp_opcode
*
549 assemble_vu_insn (cpu
, opcode
, operand_table
, pstr
, buf
)
551 const dvp_opcode
*opcode
;
552 const dvp_operand
*operand_table
;
559 opcode
= assemble_one_insn (cpu
, opcode
, operand_table
, pstr
, &insn
);
563 /* Write out the instruction.
564 Reminder: it is important to fetch enough space in one call to
565 `frag_more'. We use (f - frag_now->fr_literal) to compute where
566 we are and we don't want frag_now to change between calls. */
567 md_number_to_chars (buf
, insn
, 4);
569 /* Create any fixups. */
570 for (i
= 0; i
< fixup_count
; ++i
)
572 int op_type
, reloc_type
;
573 const dvp_operand
*operand
;
575 /* Create a fixup for this operand.
576 At this point we do not use a bfd_reloc_code_real_type for
577 operands residing in the insn, but instead just use the
578 operand index. This lets us easily handle fixups for any
579 operand type, although that is admittedly not a very exciting
580 feature. We pick a BFD reloc type in md_apply_fix. */
582 op_type
= fixups
[i
].opindex
;
583 reloc_type
= encode_fixup_reloc_type (cpu
, op_type
);
584 operand
= &vu_operands
[op_type
];
585 fix_new_exp (frag_now
, buf
- frag_now
->fr_literal
, 4,
587 (operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0,
588 (bfd_reloc_code_real_type
) reloc_type
);
595 /* Assemble one instruction at *PSTR.
596 CPU indicates what component we're assembling for.
597 The assembled instruction is stored in INSN_BUF.
598 OPCODE is a pointer to the head of the hash chain.
600 *PSTR is updated to point passed the parsed instruction.
602 If the insn is successfully parsed the result is a pointer to the opcode
603 entry that successfully matched and *PSTR is updated to point passed
604 the parsed insn. If an error occurs the result is NULL and *PSTR is left
605 at some random point in the string (??? may wish to leave it pointing where
606 the error occured). */
608 static const dvp_opcode
*
609 assemble_one_insn (cpu
, opcode
, operand_table
, pstr
, insn_buf
)
611 const dvp_opcode
*opcode
;
612 const dvp_operand
*operand_table
;
618 /* Keep looking until we find a match. */
621 for ( ; opcode
!= NULL
; opcode
= DVP_OPCODE_NEXT_ASM (opcode
))
623 int past_opcode_p
, num_suffixes
;
624 const unsigned char *syn
;
626 /* Ensure the mnemonic part matches. */
627 for (str
= start
, syn
= opcode
->mnemonic
; *syn
!= '\0'; ++str
, ++syn
)
628 if (tolower (*str
) != tolower (*syn
))
633 /* Scan the syntax string. If it doesn't match, try the next one. */
635 dvp_opcode_init_parse ();
636 insn_buf
[opcode
->opcode_word
] = opcode
->value
;
641 /* We don't check for (*str != '\0') here because we want to parse
642 any trailing fake arguments in the syntax string. */
643 for (/*str = start, */ syn
= opcode
->syntax
; *syn
!= '\0'; )
646 const dvp_operand
*operand
;
649 /* Non operand chars must match exactly.
650 Operand chars that are letters are not part of symbols
651 and are case insensitive. */
654 if (tolower (*str
) == tolower (*syn
))
666 /* We have a suffix or an operand. Pick out any modifiers. */
668 index
= DVP_OPERAND_INDEX (*syn
);
669 while (DVP_MOD_P (operand_table
[index
].flags
))
671 mods
|= operand_table
[index
].flags
& DVP_MOD_BITS
;
673 index
= DVP_OPERAND_INDEX (*syn
);
675 operand
= operand_table
+ index
;
677 if (operand
->flags
& DVP_OPERAND_FAKE
)
681 if (operand
->flags
& DVP_OPERAND_DMA_INLINE
)
683 inline_dma_data ((mods
& DVP_OPERAND_AUTOCOUNT
) != 0,
692 value
= (*operand
->parse
) (opcode
, operand
, mods
,
700 (*operand
->insert
) (opcode
, operand
, mods
, insn_buf
,
701 (offsetT
) value
, &errmsg
);
702 /* If we get an error, go on to try the next insn. */
708 /* Are we finished with suffixes? */
709 else if (!past_opcode_p
)
713 if (!(operand
->flags
& DVP_OPERAND_SUFFIX
))
714 as_fatal ("bad opcode table, missing suffix flag");
716 /* If we're at a space in the input string, we want to skip the
717 remaining suffixes. There may be some fake ones though, so
718 just go on to try the next one. */
725 /* Parse the suffix. */
727 suf_value
= (*operand
->parse
) (opcode
, operand
, mods
, &str
,
731 /* This can happen, for example, in ARC's in "blle foo" and
732 we're currently using the template "b%q%.n %j". The "bl"
733 insn occurs later in the table so "lle" isn't an illegal
738 /* Insert the suffix's value into the insn. */
739 insert_operand (cpu
, opcode
, operand
, mods
, insn_buf
,
740 (offsetT
) suf_value
, &errmsg
);
745 /* This is an operand, either a register or an expression of
753 if (operand
->flags
& DVP_OPERAND_SUFFIX
)
754 as_fatal ("bad opcode table, suffix wrong");
756 /* Is there anything left to parse?
757 We don't check for this at the top because we want to parse
758 any trailing fake arguments in the syntax string. */
759 /* ??? This doesn't allow operands with a legal value of "". */
763 /* Parse the operand. */
764 if (operand
->flags
& DVP_OPERAND_FLOAT
)
767 value
= parse_float (&str
, &errmsg
);
771 else if ((operand
->flags
& DVP_OPERAND_DMA_ADDR
)
772 && (mods
& DVP_OPERAND_AUTOCOUNT
))
775 value
= parse_dma_addr_autocount (opcode
, operand
, mods
,
776 insn_buf
, &str
, &errmsg
);
780 else if (operand
->parse
)
783 value
= (*operand
->parse
) (opcode
, operand
, mods
,
790 hold
= input_line_pointer
;
791 input_line_pointer
= str
;
793 str
= input_line_pointer
;
794 input_line_pointer
= hold
;
796 if (exp
.X_op
== O_illegal
797 || exp
.X_op
== O_absent
)
799 else if (exp
.X_op
== O_constant
)
800 value
= exp
.X_add_number
;
801 else if (exp
.X_op
== O_register
)
802 as_fatal ("got O_register");
805 /* We need to generate a fixup for this expression. */
806 if (fixup_count
>= MAX_FIXUPS
)
807 as_fatal ("too many fixups");
808 fixups
[fixup_count
].exp
= exp
;
809 fixups
[fixup_count
].opindex
= index
;
810 /* FIXME: Revisit. Do we really need operand->word?
811 The endianness of a 128 bit DMAtag is rather
812 twisted. How about defining word 0 as the word with
813 the lowest address and basing operand-shift off that.
814 operand->word could then be deleted. */
815 if (operand
->word
!= 0)
816 fixups
[fixup_count
].offset
= operand
->word
* 4;
818 fixups
[fixup_count
].offset
= (operand
->shift
/ 32) * 4;
824 /* Insert the register or expression into the instruction. */
826 insert_operand (cpu
, opcode
, operand
, mods
, insn_buf
,
827 (offsetT
) value
, &errmsg
);
828 if (errmsg
!= (const char *) NULL
)
835 /* If we're at the end of the syntax string, we're done. */
840 /* For the moment we assume a valid `str' can only contain blanks
841 now. IE: We needn't try again with a longer version of the
842 insn and it is assumed that longer versions of insns appear
843 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
845 while (isspace (*str
))
849 #ifndef VERTICAL_BAR_SEPARATOR
853 as_bad ("junk at end of line: `%s'", str
);
855 /* It's now up to the caller to emit the instruction and any
861 /* Try the next entry. */
864 as_bad ("bad instruction `%s'", start
);
869 md_operand (expressionP
)
870 expressionS
*expressionP
;
875 md_section_align (segment
, size
)
879 int align
= bfd_get_section_alignment (stdoutput
, segment
);
880 return ((size
+ (1 << align
) - 1) & (-1 << align
));
884 md_undefined_symbol (name
)
890 /* Called after parsing the file via md_after_pass_hook. */
895 #if 0 /* ??? Doesn't work unless we keep track of the nested include file
897 /* Check for missing .EndMpg, and supply one if necessary. */
898 if (cur_asm_state
== ASM_MPG
)
900 else if (cur_asm_state
== ASM_DIRECT
)
902 else if (cur_asm_state
== ASM_UNPACK
)
907 /* Functions concerning relocs. */
909 /* Spacing between each cpu type's operand numbers.
910 Should be at least as bit as any operand table. */
911 #define RELOC_SPACING 256
913 /* Given a cpu type and operand number, return a temporary reloc type
914 for use in generating the fixup that encodes the cpu type and operand
918 encode_fixup_reloc_type (cpu
, opnum
)
922 return (int) BFD_RELOC_UNUSED
+ ((int) cpu
* RELOC_SPACING
) + opnum
;
925 /* Given a fixup reloc type, decode it into cpu type and operand. */
928 decode_fixup_reloc_type (fixup_reloc
, cpuP
, operandP
)
931 const dvp_operand
**operandP
;
933 dvp_cpu cpu
= (fixup_reloc
- (int) BFD_RELOC_UNUSED
) / RELOC_SPACING
;
934 int opnum
= (fixup_reloc
- (int) BFD_RELOC_UNUSED
) % RELOC_SPACING
;
939 case DVP_VUUP
: *operandP
= &vu_operands
[opnum
]; break;
940 case DVP_VULO
: *operandP
= &vu_operands
[opnum
]; break;
941 case DVP_DMA
: *operandP
= &dma_operands
[opnum
]; break;
942 case DVP_VIF
: *operandP
= &vif_operands
[opnum
]; break;
943 case DVP_GIF
: *operandP
= &gif_operands
[opnum
]; break;
944 default : as_fatal ("bad fixup encoding");
948 /* Given a fixup reloc type, return a pointer to the operand
950 /* The location from which a PC relative jump should be calculated,
951 given a PC relative reloc. */
954 md_pcrel_from_section (fixP
, sec
)
958 if (fixP
->fx_addsy
!= (symbolS
*) NULL
959 && (! S_IS_DEFINED (fixP
->fx_addsy
)
960 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
962 /* The symbol is undefined (or is defined but not in this section).
963 Let the linker figure it out. +8: branch offsets are relative to the
968 /* We assume this is a vu branch.
969 Offsets are calculated based on the address of the next insn. */
970 return ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
) & -8L) + 8;
973 /* Apply a fixup to the object code. This is called for all the
974 fixups we generated by calls to fix_new_exp. At this point all symbol
975 values should be fully resolved, and we attempt to completely resolve the
976 reloc. If we can not do that, we determine the correct reloc code and put
977 it back in the fixup. */
980 md_apply_fix3 (fixP
, valueP
, seg
)
985 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
988 /* FIXME FIXME FIXME: The value we are passed in *valueP includes
989 the symbol values. Since we are using BFD_ASSEMBLER, if we are
990 doing this relocation the code in write.c is going to call
991 bfd_perform_relocation, which is also going to use the symbol
992 value. That means that if the reloc is fully resolved we want to
993 use *valueP since bfd_perform_relocation is not being used.
994 However, if the reloc is not fully resolved we do not want to use
995 *valueP, and must use fx_offset instead. However, if the reloc
996 is PC relative, we do want to use *valueP since it includes the
997 result of md_pcrel_from. This is confusing. */
999 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
1004 else if (fixP
->fx_pcrel
)
1010 value
= fixP
->fx_offset
;
1011 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
1013 if (S_GET_SEGMENT (fixP
->fx_subsy
) == absolute_section
)
1014 value
-= S_GET_VALUE (fixP
->fx_subsy
);
1017 /* We can't actually support subtracting a symbol. */
1018 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1019 "expression too complex");
1024 /* Check for dvp operands. These are indicated with a reloc value
1025 >= BFD_RELOC_UNUSED. */
1027 if ((int) fixP
->fx_r_type
>= (int) BFD_RELOC_UNUSED
)
1030 const dvp_operand
*operand
;
1033 decode_fixup_reloc_type ((int) fixP
->fx_r_type
,
1036 /* Fetch the instruction, insert the fully resolved operand
1037 value, and stuff the instruction back again. The fixup is recorded
1038 at the appropriate word so pass DVP_MOD_THIS_WORD so any offset
1039 specified in the tables is ignored. */
1040 insn
= bfd_getl32 ((unsigned char *) where
);
1041 insert_operand_final (cpu
, operand
, DVP_MOD_THIS_WORD
, &insn
,
1042 (offsetT
) value
, fixP
->fx_file
, fixP
->fx_line
);
1043 bfd_putl32 ((bfd_vma
) insn
, (unsigned char *) where
);
1047 /* Nothing else to do here. */
1051 /* Determine a BFD reloc value based on the operand information.
1052 We are only prepared to turn a few of the operands into relocs. */
1053 /* FIXME: This test is a hack. */
1054 if ((operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0)
1056 assert (operand
->bits
== 11
1057 && operand
->shift
== 0);
1058 fixP
->fx_r_type
= BFD_RELOC_MIPS_DVP_11_PCREL
;
1060 else if ((operand
->flags
& DVP_OPERAND_DMA_ADDR
) != 0
1061 || (operand
->flags
& DVP_OPERAND_DMA_NEXT
) != 0)
1063 assert (operand
->bits
== 27
1064 && operand
->shift
== 4);
1065 fixP
->fx_r_type
= BFD_RELOC_MIPS_DVP_27_S4
;
1069 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1070 "unresolved expression that must be resolved");
1077 switch (fixP
->fx_r_type
)
1080 md_number_to_chars (where
, value
, 1);
1083 md_number_to_chars (where
, value
, 2);
1086 md_number_to_chars (where
, value
, 4);
1093 fixP
->fx_addnumber
= value
;
1098 /* Translate internal representation of relocation info to BFD target
1102 tc_gen_reloc (section
, fixP
)
1108 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1110 reloc
->sym_ptr_ptr
= &fixP
->fx_addsy
->bsym
;
1111 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
1112 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
1113 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
1115 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1116 "internal error: can't export reloc type %d (`%s')",
1117 fixP
->fx_r_type
, bfd_get_reloc_code_name (fixP
->fx_r_type
));
1121 assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1123 reloc
->addend
= fixP
->fx_addnumber
;
1128 /* Write a value out to the object file, using the appropriate endianness. */
1131 md_number_to_chars (buf
, val
, n
)
1136 if (target_big_endian
)
1137 number_to_chars_bigendian (buf
, val
, n
);
1139 number_to_chars_littleendian (buf
, val
, n
);
1142 /* Turn a string in input_line_pointer into a floating point constant of type
1143 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1144 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
1147 /* Equal to MAX_PRECISION in atof-ieee.c */
1148 #define MAX_LITTLENUMS 6
1151 md_atof (type
, litP
, sizeP
)
1157 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1158 LITTLENUM_TYPE
*wordP
;
1178 /* FIXME: Some targets allow other format chars for bigger sizes here. */
1182 return "Bad call to md_atof()";
1185 t
= atof_ieee (input_line_pointer
, type
, words
);
1187 input_line_pointer
= t
;
1188 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1190 if (target_big_endian
)
1192 for (i
= 0; i
< prec
; i
++)
1194 md_number_to_chars (litP
, (valueT
) words
[i
], sizeof (LITTLENUM_TYPE
));
1195 litP
+= sizeof (LITTLENUM_TYPE
);
1200 for (i
= prec
- 1; i
>= 0; i
--)
1202 md_number_to_chars (litP
, (valueT
) words
[i
], sizeof (LITTLENUM_TYPE
));
1203 litP
+= sizeof (LITTLENUM_TYPE
);
1210 /* Miscellaneous utilities. */
1212 /* Parse a 32 bit floating point number.
1213 The result is those 32 bits as an integer. */
1216 parse_float (pstr
, errmsg
)
1218 const char **errmsg
;
1220 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1223 p
= atof_ieee (*pstr
, 'f', words
);
1225 return (words
[0] << 16) | words
[1];
1228 /* Scan a symbol and return a pointer to one past the end. */
1230 #define issymchar(ch) (isalnum(ch) || ch == '_')
1235 while (*sym
&& issymchar (*sym
))
1240 /* Evaluate an expression.
1241 The result is the value of the expression if it can be evaluated,
1242 or 0 if it cannot (say because some symbols haven't been defined yet)
1243 in which case a fixup is queued.
1245 If OPINDEX is 0, don't queue any fixups, just return 0. */
1249 eval_expr (int opindex
, int offset
, const char *fmt
, ...)
1251 eval_expr (opindex
, offset
, fmt
, va_alist
)
1259 char *str
,*save_input
;
1267 vasprintf (&str
, fmt
, ap
);
1270 save_input
= input_line_pointer
;
1271 input_line_pointer
= str
;
1273 input_line_pointer
= save_input
;
1275 if (exp
.X_op
== O_constant
)
1276 value
= exp
.X_add_number
;
1281 fixups
[fixup_count
].exp
= exp
;
1282 fixups
[fixup_count
].opindex
= opindex
;
1283 fixups
[fixup_count
].offset
= offset
;
1291 /* Create a label named by concatenating PREFIX to NAME. */
1293 static struct symbol
*
1294 create_label (prefix
, name
)
1295 const char *prefix
, *name
;
1297 int namelen
= strlen (name
);
1298 int prefixlen
= strlen (prefix
);
1300 struct symbol
*result
;
1302 fullname
= xmalloc (prefixlen
+ namelen
+ 1);
1303 strcpy (fullname
, prefix
);
1304 strcat (fullname
, name
);
1305 result
= symbol_find_or_make (fullname
);
1310 /* Create a label named by concatenating PREFIX to NAME,
1311 and define it as `.'. */
1313 static struct symbol
*
1314 create_colon_label (prefix
, name
)
1315 const char *prefix
, *name
;
1317 int namelen
= strlen (name
);
1318 int prefixlen
= strlen (prefix
);
1320 struct symbol
*result
;
1322 fullname
= xmalloc (prefixlen
+ namelen
+ 1);
1323 strcpy (fullname
, prefix
);
1324 strcat (fullname
, name
);
1325 result
= colon (fullname
);
1330 /* Return a malloc'd string useful in creating unique labels. */
1331 /* ??? Presumably such a routine already exists somewhere
1332 [but a first pass at finding it didn't turn up anything]. */
1340 asprintf (&result
, "dvptmp%d", counter
);
1345 /* Compute the auto-count value for a DMA tag. */
1348 setup_autocount (name
, insn_buf
)
1354 count
= eval_expr (dma_operand_count
, 12,
1355 "(%s%s - %s) >> 4", END_LABEL_PREFIX
, name
, name
);
1356 /* count is in quadwords */
1359 /* Store the count field. */
1360 insn_buf
[3] &= 0xffff0000;
1361 insn_buf
[3] |= count
& 0x0000ffff;
1364 /* Record that inline data follows. */
1367 inline_dma_data (autocount_p
, insn_buf
)
1371 if (dma_data_state
!= 0 )
1373 as_bad ("DmaData blocks cannot be nested.");
1381 dma_data_name
= S_GET_NAME (create_colon_label ("", unique_name ()));
1382 setup_autocount (dma_data_name
, insn_buf
);
1388 /* Compute the auto-count value for a DMA tag with out-of-line data. */
1391 parse_dma_addr_autocount (opcode
, operand
, mods
, insn_buf
, pstr
, errmsg
)
1392 const dvp_opcode
*opcode
;
1393 const dvp_operand
*operand
;
1397 const char **errmsg
;
1399 char *start
= *pstr
;
1402 /* Data reference must be a .DmaData label. */
1403 struct symbol
*label
, *label2
, *endlabel
;
1408 if (! is_name_beginner (*start
))
1410 *errmsg
= "invalid .DmaData label";
1415 end
= scan_symbol (name
);
1418 label
= symbol_find_or_make (name
);
1421 label2
= create_label ("_$", name
);
1422 endlabel
= create_label (END_LABEL_PREFIX
, name
);
1424 retval
= eval_expr (dma_operand_addr
, 8, name
);
1426 setup_autocount (name
, insn_buf
);
1432 /* Return length in bytes of the variable length VIF insn
1433 currently being assembled. */
1436 cur_vif_insn_length ()
1441 if (cur_varlen_frag
== frag_now
)
1442 byte_len
= frag_more (0) - cur_varlen_insn
- 4; /* -4 for mpg itself */
1445 byte_len
= (cur_varlen_frag
->fr_fix
+ cur_varlen_frag
->fr_offset
-
1446 (cur_varlen_insn
- cur_varlen_frag
->fr_literal
)) - 4;
1447 for (f
= cur_varlen_frag
->fr_next
; f
!= frag_now
; f
= f
->fr_next
)
1448 byte_len
+= f
->fr_fix
+ f
->fr_offset
;
1449 byte_len
+= frag_now_fix ();
1455 /* Install length LEN, in bytes, in the vif insn at BUF.
1456 The bytes in BUF are in target order. */
1459 install_vif_length (buf
, len
)
1465 if ((cmd
& 0x70) == 0x40)
1469 /* ??? Worry about data /= 4 cuts off? */
1471 as_bad ("`mpg' data length must be between 1 and 256");
1472 buf
[2] = len
== 256 ? 0 : len
;
1474 else if ((cmd
& 0x70) == 0x50)
1476 /* direct/directhl */
1477 /* ??? Worry about data /= 16 cuts off? */
1480 as_bad ("`direct' data length must be between 1 and 65536");
1481 len
= len
== 65536 ? 0 : len
;
1485 else if ((cmd
& 0x60) == 0x60)
1491 as_fatal ("bad call to install_vif_length");
1494 /* Insert a file into the output.
1495 -I is used to specify where to find the file.
1496 The result is the number of bytes inserted.
1497 If an error occurs an error message is printed and zero is returned. */
1508 path
= xmalloc (strlen (file
) + include_dir_maxlen
+ 5 /*slop*/);
1510 for (i
= 0; i
< include_dir_count
; i
++)
1512 strcpy (path
, include_dirs
[i
]);
1514 strcat (path
, file
);
1515 if ((f
= fopen (path
, FOPEN_RB
)) != NULL
)
1520 f
= fopen (file
, FOPEN_RB
);
1523 as_bad ("unable to read file `%s'", file
);
1529 n
= fread (buf
, 1, sizeof (buf
), f
);
1532 char *fr
= frag_more (n
);
1533 memcpy (fr
, buf
, n
);
1539 /* We assume the file is smaller than 2^31 bytes.
1540 Ok, we shouldn't make any assumptions. Later. */
1544 /* Insert an operand value into an instruction. */
1547 insert_operand (cpu
, opcode
, operand
, mods
, insn_buf
, val
, errmsg
)
1549 const dvp_opcode
*opcode
;
1550 const dvp_operand
*operand
;
1554 const char **errmsg
;
1556 if (operand
->insert
)
1558 (*operand
->insert
) (opcode
, operand
, mods
, insn_buf
, (long) val
, errmsg
);
1562 /* We currently assume a field does not cross a word boundary. */
1563 int shift
= ((mods
& DVP_MOD_THIS_WORD
)
1564 ? (operand
->shift
& 31)
1566 /* FIXME: revisit */
1567 if (operand
->word
== 0)
1569 int word
= (mods
& DVP_MOD_THIS_WORD
) ? 0 : (shift
/ 32);
1570 if (operand
->bits
== 32)
1571 insn_buf
[word
] = val
;
1575 insn_buf
[word
] |= ((long) val
& ((1 << operand
->bits
) - 1)) << shift
;
1580 int word
= (mods
& DVP_MOD_THIS_WORD
) ? 0 : operand
->word
;
1581 if (operand
->bits
== 32)
1582 insn_buf
[word
] = val
;
1585 long temp
= (long) val
& ((1 << operand
->bits
) - 1);
1586 insn_buf
[word
] |= temp
<< operand
->shift
;
1592 /* Insert an operand's final value into an instruction.
1593 Here we can give warning messages about operand values if we want to. */
1596 insert_operand_final (cpu
, operand
, mods
, insn_buf
, val
, file
, line
)
1598 const dvp_operand
*operand
;
1605 if (operand
->bits
!= 32)
1607 offsetT min
, max
, test
;
1609 if ((operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0)
1613 if (file
== (char *) NULL
)
1614 as_warn ("branch to misaligned address");
1616 as_warn_where (file
, line
, "branch to misaligned address");
1621 if ((operand
->flags
& DVP_OPERAND_SIGNED
) != 0)
1623 if ((operand
->flags
& DVP_OPERAND_SIGNOPT
) != 0)
1624 max
= (1 << operand
->bits
) - 1;
1626 max
= (1 << (operand
->bits
- 1)) - 1;
1627 min
= - (1 << (operand
->bits
- 1));
1631 max
= (1 << operand
->bits
) - 1;
1635 if ((operand
->flags
& DVP_OPERAND_NEGATIVE
) != 0)
1640 if (test
< (offsetT
) min
|| test
> (offsetT
) max
)
1643 "operand out of range (%s not between %ld and %ld)";
1646 sprint_value (buf
, test
);
1647 if (file
== (char *) NULL
)
1648 as_warn (err
, buf
, min
, max
);
1650 as_warn_where (file
, line
, err
, buf
, min
, max
);
1655 const char *errmsg
= NULL
;
1656 insert_operand (cpu
, NULL
, operand
, mods
, insn_buf
, val
, &errmsg
);
1658 as_warn_where (file
, line
, errmsg
);
1662 /* DVP pseudo ops. */
1672 if (dma_data_state
!= 0)
1674 as_bad ("DmaData blocks cannot be nested.");
1675 ignore_rest_of_line ();
1680 SKIP_WHITESPACE (); /* Leading whitespace is part of operand. */
1681 name
= input_line_pointer
;
1683 if (!is_name_beginner (*name
))
1685 as_bad ("invalid identifier for \".DmaData\"");
1686 ignore_rest_of_line ();
1690 c
= get_symbol_end ();
1691 line_label
= colon (name
); /* user-defined label */
1692 dma_data_name
= S_GET_NAME (line_label
);
1693 *input_line_pointer
= c
;
1695 demand_empty_rest_of_line ();
1699 s_enddmadata (ignore
)
1702 if (dma_data_state
!= 1)
1704 as_warn (".EndDmaData encountered outside a DmaData block -- ignored.");
1705 ignore_rest_of_line ();
1709 demand_empty_rest_of_line ();
1711 /* "label" points to beginning of block.
1712 Create a name for the final label like _$<name>. */
1715 /* Fill the data out to a multiple of 16 bytes. */
1716 /* FIXME: Does the fill contents matter? */
1717 frag_align (4, 0, 0);
1718 create_colon_label (END_LABEL_PREFIX
, dma_data_name
);
1723 s_dmapackvif (ignore
)
1726 /* Syntax: .dmapackvif 0|1 */
1727 struct symbol
*label
; /* Points to symbol */
1728 char *name
; /* points to name of symbol */
1730 /* Leading whitespace is part of operand. */
1732 switch (*input_line_pointer
++)
1741 as_bad ("illegal argument to `.DmaPackPke'");
1743 demand_empty_rest_of_line ();
1747 s_enddirect (ignore
)
1752 if (cur_asm_state
!= ASM_DIRECT
)
1754 as_bad ("`.enddirect' has no matching `direct' instruction");
1758 byte_len
= cur_vif_insn_length ();
1759 if (cur_varlen_value
!= -1
1760 && cur_varlen_value
* 16 != byte_len
)
1761 as_warn ("length in `direct' instruction does not match length of data");
1763 install_vif_length (cur_varlen_insn
, byte_len
);
1765 cur_asm_state
= ASM_INIT
;
1767 /* These needn't be reset, but to catch bugs they are. */
1768 cur_varlen_frag
= NULL
;
1769 cur_varlen_insn
= NULL
;
1770 cur_varlen_value
= 0;
1772 demand_empty_rest_of_line ();
1780 int nloop
= gif_nloop ();
1782 if (cur_asm_state
!= ASM_GIF
)
1784 as_bad (".endgif doesn't follow a gif tag");
1787 cur_asm_state
= ASM_INIT
;
1789 if (gif_insn_type
== GIF_PACKED
)
1790 count
= eval_expr (0, 0, "(. - %s) >> 4", gif_data_name
);
1792 count
= eval_expr (0, 0, "(. - %s) >> 3", gif_data_name
);
1795 || fixup_count
!= 0)
1797 as_bad ("bad data count");
1801 /* Validate nloop if specified. Otherwise write the computed value into
1807 switch (gif_insn_type
)
1811 ok_p
= count
== nloop
* gif_nregs ();
1814 ok_p
= count
== nloop
;
1819 as_bad ("nloop value does not match size of data");
1825 DVP_INSN insn
= bfd_getl32 (gif_insn_frag
+ 12);
1828 as_where (&file
, &line
);
1829 insert_operand_final (DVP_GIF
, &gif_operands
[gif_operand_nloop
],
1830 DVP_MOD_THIS_WORD
, &insn
,
1831 (offsetT
) nloop
, file
, line
);
1832 bfd_putl32 ((bfd_vma
) insn
, gif_insn_frag
+ 12);
1835 gif_data_name
= NULL
;
1836 demand_empty_rest_of_line ();
1845 if (cur_asm_state
!= ASM_MPG
)
1847 as_bad ("`.endmpg' has no matching `mpg' instruction");
1851 byte_len
= cur_vif_insn_length ();
1852 if (cur_varlen_value
!= -1
1853 && cur_varlen_value
* 8 != byte_len
)
1854 as_warn ("length in `mpg' instruction does not match length of data");
1856 install_vif_length (cur_varlen_insn
, byte_len
);
1858 cur_asm_state
= ASM_INIT
;
1860 /* These needn't be reset, but to catch bugs they are. */
1861 cur_varlen_frag
= NULL
;
1862 cur_varlen_insn
= NULL
;
1863 cur_varlen_value
= 0;
1865 /* Update $.MpgLoc. */
1866 vif_set_mpgloc (vif_get_mpgloc () + byte_len
);
1868 demand_empty_rest_of_line ();
1872 s_endunpack (ignore
)
1877 if (cur_asm_state
!= ASM_UNPACK
)
1879 as_bad ("`.endunpack' has no matching `unpack' instruction");
1883 byte_len
= cur_vif_insn_length ();
1884 #if 0 /* unpack doesn't support prespecifying a length */
1885 if (cur_varlen_value
* 16 != bytelen
)
1886 as_warn ("length in `direct' instruction does not match length of data");
1889 install_vif_length (cur_varlen_insn
, byte_len
);
1891 cur_asm_state
= ASM_INIT
;
1893 /* These needn't be reset, but to catch bugs they are. */
1894 cur_varlen_frag
= NULL
;
1895 cur_varlen_insn
= NULL
;
1896 cur_varlen_value
= 0;
1898 /* Update $.UnpackLoc. */
1899 vif_set_unpackloc (vif_get_unpackloc () + byte_len
);
1901 demand_empty_rest_of_line ();
1908 /* If in MPG state and the user requests to change to VU state,
1909 leave the state as MPG. This happens when we see an mpg followed
1910 by a .include that has .vu. */
1911 if (cur_asm_state
== ASM_MPG
&& state
== ASM_VU
)
1914 cur_asm_state
= state
;
1916 demand_empty_rest_of_line ();