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"
31 static long parse_dma_ild_autocount ();
32 static long parse_dma_ptr_autocount ();
34 static void insert_operand
35 PARAMS ((dvp_cpu
, const dvp_opcode
*, const dvp_operand
*, int,
36 DVP_INSN
*, offsetT
, const char **));
37 static void insert_operand_final
38 PARAMS ((dvp_cpu
, const dvp_operand
*, int,
39 DVP_INSN
*, offsetT
, char *, unsigned int));
41 static int insert_file
PARAMS ((const char *));
43 static int cur_vif_insn_length
PARAMS ((void));
44 static void install_vif_length
PARAMS ((char *, int));
46 const char comment_chars
[] = ";";
47 const char line_comment_chars
[] = "#";
48 const char line_separator_chars
[] = "!";
49 const char EXP_CHARS
[] = "eE";
50 const char FLT_CHARS
[] = "dD";
52 /* Current assembler state.
53 Instructions like mpg and direct are followed by a restricted set of
54 instructions. In the case of a '*' length argument an end marker must
55 be provided. (e.g. mpg is followed by vu insns until a .EndMpg is
58 ASM_INIT
, ASM_MPG
, ASM_DIRECT
, ASM_UNPACK
, ASM_GIF
, ASM_VU
60 static asm_state cur_asm_state
= ASM_INIT
;
62 /* For variable length instructions, pointer to the initial frag
63 and pointer into that frag. These only hold valid values if
64 cur_asm_state is one of ASM_MPG, ASM_DIRECT, ASM_UNPACK. */
65 static fragS
*cur_varlen_frag
;
66 static char *cur_varlen_insn
;
67 /* The length value specified in the insn, or -1 if '*'. */
68 static int cur_varlen_value
;
70 /* Non-zero if packing vif instructions in dma tags. */
71 static int dma_pack_vif_p
;
73 /* Non-zero if dma insns are to be included in the output.
74 This is the default, but writing "if (! no_dma)" is klunky. */
75 static int output_dma
= 1;
76 /* Non-zero if vif insns are to be included in the output. */
77 static int output_vif
= 1;
79 const char *md_shortopts
= "";
81 struct option md_longopts
[] =
83 #define OPTION_NO_DMA (OPTION_MD_BASE + 1)
84 { "no-dma", no_argument
, NULL
, OPTION_NO_DMA
},
85 #define OPTION_NO_DMA_VIF (OPTION_NO_DMA + 1)
86 { "no-dma-vif", no_argument
, NULL
, OPTION_NO_DMA_VIF
},
88 {NULL
, no_argument
, NULL
, 0}
90 size_t md_longopts_size
= sizeof(md_longopts
);
93 md_parse_option (c
, arg
)
102 case OPTION_NO_DMA_VIF
:
113 md_show_usage (stream
)
118 -no-dma do not include DMA instructions in the output\n\
119 -no-dma-vif do not include DMA or VIF instructions in the output\n\
123 /* Set by md_assemble for use by dvp_fill_insn. */
124 static subsegT prev_subseg
;
125 static segT prev_seg
;
127 static void s_dmadata
PARAMS ((int));
128 static void s_dmadata_implied
PARAMS ((int));
129 static void s_enddmadata
PARAMS ((int));
130 static void s_dmapackvif
PARAMS ((int));
131 static void s_enddirect
PARAMS ((int));
132 static void s_endgif
PARAMS ((int));
133 static void s_endmpg
PARAMS ((int));
134 static void s_endunpack
PARAMS ((int));
135 static void s_state
PARAMS ((int));
137 /* The target specific pseudo-ops which we support. */
138 const pseudo_typeS md_pseudo_table
[] =
140 { "dmadata", s_dmadata
, 0 },
141 { "dmapackvif", s_dmapackvif
, 0 },
142 { "enddirect", s_enddirect
, 0 },
143 { "enddmadata", s_enddmadata
, 0 },
144 { "endgif", s_endgif
, 0 },
145 { "endmpg", s_endmpg
, 0 },
146 { "endunpack", s_endunpack
, 0 },
147 /* .vu,.gif added to simplify debugging */
148 { "vu", s_state
, ASM_VU
},
149 { "gif", s_state
, ASM_GIF
},
160 /* Save the current subseg so we can restore it [it's the default one and
161 we don't want the initial section to be .sbss. */
165 subseg_set (seg
, subseg
);
167 /* Initialize the opcode tables.
168 This involves computing the hash chains. */
169 dvp_opcode_init_tables (0);
171 cur_asm_state
= ASM_INIT
;
175 /* We need to keep a list of fixups. We can't simply generate them as
176 we go, because that would require us to first create the frag, and
177 that would screw up references to ``.''. */
181 /* index into `dvp_operands' */
183 /* byte offset from beginning of instruction */
190 static int fixup_count
;
191 static struct dvp_fixup fixups
[MAX_FIXUPS
];
193 /* Given a cpu type and operand number, return a temporary reloc type
194 for use in generating the fixup that encodes the cpu type and operand. */
195 static int encode_fixup_reloc_type
PARAMS ((dvp_cpu
, int));
196 /* Given an encoded fixup reloc type, decode it into cpu and operand. */
197 static void decode_fixup_reloc_type
PARAMS ((int, dvp_cpu
*,
198 const dvp_operand
**));
200 static void assemble_dma
PARAMS ((char *));
201 static void assemble_gif
PARAMS ((char *));
202 static void assemble_vif
PARAMS ((char *));
203 static void assemble_vu
PARAMS ((char *));
204 static const dvp_opcode
* assemble_vu_insn
PARAMS ((dvp_cpu
,
208 static const dvp_opcode
* assemble_one_insn
PARAMS ((dvp_cpu
,
211 char **, DVP_INSN
*));
213 /* Main entry point for assembling an instruction. */
219 /* Skip leading white space. */
220 while (isspace (*str
))
223 if (cur_asm_state
== ASM_INIT
)
225 if (strncasecmp (str
, "dma", 3) == 0)
230 else if (cur_asm_state
== ASM_GIF
)
232 else if (cur_asm_state
== ASM_VU
233 || cur_asm_state
== ASM_MPG
)
236 as_fatal ("unknown parse state");
239 /* Subroutine of md_assemble to assemble DMA instructions. */
245 DVP_INSN insn_buf
[4];
246 int len
; /* Insn's length, in 32 bit words. */
247 char *f
; /* Pointer to allocated frag. */
249 const dvp_opcode
*opcode
;
252 Fill the first two words with VIF NOPs.
253 They may be over-written later if DmaPackPke is on.
254 initialize the remainder with zeros.
261 opcode
= assemble_one_insn (DVP_DMA
,
262 dma_opcode_lookup_asm (str
), dma_operands
,
264 if( opcode
== NULL
) return;
265 if( !output_dma
) return;
268 f
= frag_more( len
* 4);
270 /* Write out the VIF / DMA instructions. */
271 for( i
= 0; i
< len
; ++i
)
272 md_number_to_chars( f
+ i
* 4, insn_buf
[i
], 4);
274 /* Create any fixups. */
275 /* FIXME: It might eventually be possible to combine all the various
276 copies of this bit of code. */
277 for( i
= 0; i
< fixup_count
; ++i
)
279 int op_type
, reloc_type
, offset
;
280 const dvp_operand
*operand
;
284 Create a fixup for this operand.
285 At this point we do not use a bfd_reloc_code_real_type for
286 operands residing in the insn, but instead just use the
287 operand index. This lets us easily handle fixups for any
288 operand type, although that is admittedly not a very exciting
289 feature. We pick a BFD reloc type in md_apply_fix.
292 op_type
= fixups
[i
].opindex
;
293 offset
= fixups
[i
].offset
;
294 reloc_type
= encode_fixup_reloc_type (DVP_VIF
, op_type
);
295 operand
= &vif_operands
[op_type
];
296 fix_new_exp (frag_now
, f
+ offset
- frag_now
->fr_literal
, 4,
298 (operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0,
299 (bfd_reloc_code_real_type
) reloc_type
);
304 /* Subroutine of md_assemble to assemble VIF instructions. */
310 /* Space for the instruction.
311 The variable length insns can require much more space than this.
312 It is allocated later, when we know we have such an insn. */
313 DVP_INSN insn_buf
[5];
314 /* Insn's length, in 32 bit words. */
316 /* Pointer to allocated frag. */
319 const dvp_opcode
*opcode
;
321 opcode
= assemble_one_insn (DVP_VIF
,
322 vif_opcode_lookup_asm (str
), vif_operands
,
327 if (opcode
->flags
& VIF_OPCODE_LENVAR
)
328 len
= 1; /* actual data follows later */
329 else if (opcode
->flags
& VIF_OPCODE_LEN2
)
331 else if (opcode
->flags
& VIF_OPCODE_LEN5
)
336 /* We still have to switch modes (if mpg for example) so we can't exit
340 /* Reminder: it is important to fetch enough space in one call to
341 `frag_more'. We use (f - frag_now->fr_literal) to compute where
342 we are and we don't want frag_now to change between calls. */
343 f
= frag_more (len
* 4);
345 /* Write out the instruction. */
346 for (i
= 0; i
< len
; ++i
)
347 md_number_to_chars (f
+ i
* 4, insn_buf
[i
], 4);
349 /* Create any fixups. */
350 /* FIXME: It might eventually be possible to combine all the various
351 copies of this bit of code. */
352 for (i
= 0; i
< fixup_count
; ++i
)
354 int op_type
, reloc_type
, offset
;
355 const dvp_operand
*operand
;
357 /* Create a fixup for this operand.
358 At this point we do not use a bfd_reloc_code_real_type for
359 operands residing in the insn, but instead just use the
360 operand index. This lets us easily handle fixups for any
361 operand type, although that is admittedly not a very exciting
362 feature. We pick a BFD reloc type in md_apply_fix. */
364 op_type
= fixups
[i
].opindex
;
365 offset
= fixups
[i
].offset
;
366 reloc_type
= encode_fixup_reloc_type (DVP_VIF
, op_type
);
367 operand
= &vif_operands
[op_type
];
368 fix_new_exp (frag_now
, f
+ offset
- frag_now
->fr_literal
, 4,
370 (operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0,
371 (bfd_reloc_code_real_type
) reloc_type
);
375 /* Handle variable length insns. */
377 if (opcode
->flags
& VIF_OPCODE_LENVAR
)
379 /* Name of file to read data from. */
381 /* Length in 32 bit words. */
386 vif_get_var_data (&file
, &data_len
);
389 int byte_len
= insert_file (file
);
391 install_vif_length (f
, byte_len
);
392 /* Update $.MpgLoc. */
393 vif_set_mpgloc (vif_get_mpgloc () + byte_len
);
397 /* data_len == -1 means the value must be computed from
399 if (data_len
== 0 || data_len
< -2)
400 as_bad ("invalid data length");
401 cur_varlen_frag
= frag_now
;
403 cur_varlen_value
= data_len
;
404 if (opcode
->flags
& VIF_OPCODE_MPG
)
405 cur_asm_state
= ASM_MPG
;
406 else if (opcode
->flags
& VIF_OPCODE_DIRECT
)
407 cur_asm_state
= ASM_DIRECT
;
408 else if (opcode
->flags
& VIF_OPCODE_UNPACK
)
409 cur_asm_state
= ASM_UNPACK
;
414 /* Subroutine of md_assemble to assemble GIF instructions. */
420 DVP_INSN insn_buf
[4];
421 const dvp_opcode
*opcode
;
423 opcode
= assemble_one_insn (DVP_GIF
,
424 gif_opcode_lookup_asm (str
), gif_operands
,
430 /* Subroutine of md_assemble to assemble VU instructions. */
436 /* The lower instruction has the lower address.
437 Handle this by grabbing 8 bytes now, and then filling each word
439 char *f
= frag_more (8);
440 const dvp_opcode
*opcode
;
442 #ifdef VERTICAL_BAR_SEPARATOR
443 char *p
= strchr (str
, '|');
447 as_bad ("lower slot missing in `%s'", str
);
452 opcode
= assemble_vu_insn (DVP_VUUP
,
453 vu_upper_opcode_lookup_asm (str
), vu_operands
,
459 assemble_vu_insn (DVP_VULO
,
460 vu_lower_opcode_lookup_asm (str
), vu_operands
,
463 opcode
= assemble_vu_insn (DVP_VUUP
,
464 vu_upper_opcode_lookup_asm (str
), vu_operands
,
466 /* Don't assemble next one if we couldn't assemble the first. */
468 assemble_vu_insn (DVP_VULO
,
469 vu_lower_opcode_lookup_asm (str
), vu_operands
,
474 static const dvp_opcode
*
475 assemble_vu_insn (cpu
, opcode
, operand_table
, pstr
, buf
)
477 const dvp_opcode
*opcode
;
478 const dvp_operand
*operand_table
;
485 opcode
= assemble_one_insn (cpu
, opcode
, operand_table
, pstr
, &insn
);
489 /* Write out the instruction.
490 Reminder: it is important to fetch enough space in one call to
491 `frag_more'. We use (f - frag_now->fr_literal) to compute where
492 we are and we don't want frag_now to change between calls. */
493 md_number_to_chars (buf
, insn
, 4);
495 /* Create any fixups. */
496 for (i
= 0; i
< fixup_count
; ++i
)
498 int op_type
, reloc_type
;
499 const dvp_operand
*operand
;
501 /* Create a fixup for this operand.
502 At this point we do not use a bfd_reloc_code_real_type for
503 operands residing in the insn, but instead just use the
504 operand index. This lets us easily handle fixups for any
505 operand type, although that is admittedly not a very exciting
506 feature. We pick a BFD reloc type in md_apply_fix. */
508 op_type
= fixups
[i
].opindex
;
509 reloc_type
= encode_fixup_reloc_type (cpu
, op_type
);
510 operand
= &vu_operands
[op_type
];
511 fix_new_exp (frag_now
, buf
- frag_now
->fr_literal
, 4,
513 (operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0,
514 (bfd_reloc_code_real_type
) reloc_type
);
521 /* Assemble one instruction at *PSTR.
522 CPU indicates what component we're assembling for.
523 The assembled instruction is stored in INSN_BUF.
524 OPCODE is a pointer to the head of the hash chain.
526 *PSTR is updated to point passed the parsed instruction.
528 If the insn is successfully parsed the result is a pointer to the opcode
529 entry that successfully matched and *PSTR is updated to point passed
530 the parsed insn. If an error occurs the result is NULL and *PSTR is left
531 at some random point in the string (??? may wish to leave it pointing where
532 the error occured). */
534 static const dvp_opcode
*
535 assemble_one_insn (cpu
, opcode
, operand_table
, pstr
, insn_buf
)
537 const dvp_opcode
*opcode
;
538 const dvp_operand
*operand_table
;
544 /* Keep looking until we find a match. */
547 for ( ; opcode
!= NULL
; opcode
= DVP_OPCODE_NEXT_ASM (opcode
))
549 int past_opcode_p
, num_suffixes
, num_operands
;
550 const unsigned char *syn
;
552 /* Ensure the mnemonic part matches. */
553 for (str
= start
, syn
= opcode
->mnemonic
; *syn
!= '\0'; ++str
, ++syn
)
554 if (tolower (*str
) != tolower (*syn
))
559 /* Scan the syntax string. If it doesn't match, try the next one. */
561 dvp_opcode_init_parse ();
562 insn_buf
[ opcode
->opcode_word
] = opcode
->value
;
568 /* We don't check for (*str != '\0') here because we want to parse
569 any trailing fake arguments in the syntax string. */
570 for (/*str = start, */ syn
= opcode
->syntax
; *syn
!= '\0'; )
573 const dvp_operand
*operand
;
576 /* Non operand chars must match exactly.
577 Operand chars that are letters are not part of symbols
578 and are case insensitive. */
581 if (tolower (*str
) == tolower (*syn
))
593 /* We have a suffix or an operand. Pick out any modifiers. */
595 index
= DVP_OPERAND_INDEX (*syn
);
596 while (DVP_MOD_P (operand_table
[index
].flags
))
598 mods
|= operand_table
[index
].flags
& DVP_MOD_BITS
;
600 index
= DVP_OPERAND_INDEX (*syn
);
602 operand
= operand_table
+ index
;
604 if (operand
->flags
& DVP_OPERAND_FAKE
)
609 (*operand
->insert
) (opcode
, operand
, mods
, insn_buf
, 0,
611 /* If we get an error, go on to try the next insn. */
617 /* Are we finished with suffixes? */
618 else if (!past_opcode_p
)
625 if (!(operand
->flags
& DVP_OPERAND_SUFFIX
))
626 as_fatal ("bad opcode table, missing suffix flag");
628 /* If we're at a space in the input string, we want to skip the
629 remaining suffixes. There may be some fake ones though, so
630 just go on to try the next one. */
639 /* Pick the suffix out and parse it. */
640 /* ??? Hmmm ... there may not be any need to nul-terminate the
641 string, and it may in fact complicate things. */
642 for (t
= (*s
== '.' || *s
== '/' || *s
== '[') ? s
+ 1 : s
;
643 *t
&& (isalnum (*t
) || *t
== ']');
649 suf_value
= (*operand
->parse
) (opcode
, operand
, mods
, &s
,
654 /* This can happen, for example, in ARC's in "blle foo" and
655 we're currently using the template "b%q%.n %j". The "bl"
656 insn occurs later in the table so "lle" isn't an illegal
661 /* Insert the suffix's value into the insn. */
662 insert_operand (cpu
, opcode
, operand
, mods
, insn_buf
,
663 (offsetT
) suf_value
, &errmsg
);
665 /* FIXME: For suffixes that have a null "" value,
666 this next line is wrong as we will skip over something
667 we're not supposed to. */
672 /* This is an operand, either a register or an expression of
680 if (operand
->flags
& DVP_OPERAND_SUFFIX
)
681 as_fatal ("bad opcode table, suffix wrong");
683 #if 0 /* commas are in the syntax string now */
684 /* If this is not the first, there must be a comma. */
685 if (num_operands
> 0)
693 if( operand
->flags
& DVP_OPERAND_DMA_ILD
)
695 s_dmadata_implied( 0);
700 /* Is there anything left to parse?
701 We don't check for this at the top because we want to parse
702 any trailing fake arguments in the syntax string. */
703 /* ??? This doesn't allow operands with a legal value of "". */
707 /* Parse the operand. */
708 if( operand
->flags
& DVP_OPERAND_DMA_ILD_AUTOCOUNT
)
711 value
= parse_dma_ild_autocount( opcode
, operand
, mods
, insn_buf
, &str
, &errmsg
);
714 else if( operand
->flags
& DVP_OPERAND_DMA_PTR_AUTOCOUNT
)
717 value
= parse_dma_ptr_autocount( opcode
, operand
, mods
, insn_buf
, &str
, &errmsg
);
720 else if (operand
->parse
)
723 value
= (*operand
->parse
) (opcode
, operand
, mods
,
730 hold
= input_line_pointer
;
731 input_line_pointer
= str
;
733 str
= input_line_pointer
;
734 input_line_pointer
= hold
;
736 if (exp
.X_op
== O_illegal
737 || exp
.X_op
== O_absent
)
739 else if (exp
.X_op
== O_constant
)
740 value
= exp
.X_add_number
;
741 else if (exp
.X_op
== O_register
)
742 as_fatal ("got O_register");
745 /* We need to generate a fixup for this expression. */
746 if (fixup_count
>= MAX_FIXUPS
)
747 as_fatal ("too many fixups");
748 fixups
[fixup_count
].exp
= exp
;
749 fixups
[fixup_count
].opindex
= index
;
750 fixups
[fixup_count
].offset
= (operand
->shift
/ 32) * 4;
756 /* Insert the register or expression into the instruction. */
758 insert_operand (cpu
, opcode
, operand
, mods
, insn_buf
,
759 (offsetT
) value
, &errmsg
);
760 if (errmsg
!= (const char *) NULL
)
768 /* If we're at the end of the syntax string, we're done. */
773 /* For the moment we assume a valid `str' can only contain blanks
774 now. IE: We needn't try again with a longer version of the
775 insn and it is assumed that longer versions of insns appear
776 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
778 while (isspace (*str
))
782 #ifndef VERTICAL_BAR_SEPARATOR
786 as_bad ("junk at end of line: `%s'", str
);
788 /* It's now up to the caller to emit the instruction and any
794 /* Try the next entry. */
797 as_bad ("bad instruction `%s'", start
);
802 md_operand (expressionP
)
803 expressionS
*expressionP
;
808 md_section_align (segment
, size
)
812 int align
= bfd_get_section_alignment (stdoutput
, segment
);
813 return ((size
+ (1 << align
) - 1) & (-1 << align
));
817 md_undefined_symbol (name
)
823 /* Called after parsing the file via md_after_pass_hook. */
828 /* Check for missing .EndMpg, and supply one if necessary. */
829 if (cur_asm_state
== ASM_MPG
)
831 else if (cur_asm_state
== ASM_DIRECT
)
833 else if (cur_asm_state
== ASM_UNPACK
)
837 /* Functions concerning relocs. */
839 /* Spacing between each cpu type's operand numbers.
840 Should be at least as bit as any operand table. */
841 #define RELOC_SPACING 256
843 /* Given a cpu type and operand number, return a temporary reloc type
844 for use in generating the fixup that encodes the cpu type and operand
848 encode_fixup_reloc_type (cpu
, opnum
)
852 return (int) BFD_RELOC_UNUSED
+ ((int) cpu
* RELOC_SPACING
) + opnum
;
855 /* Given a fixup reloc type, decode it into cpu type and operand. */
858 decode_fixup_reloc_type (fixup_reloc
, cpuP
, operandP
)
861 const dvp_operand
**operandP
;
863 dvp_cpu cpu
= (fixup_reloc
- (int) BFD_RELOC_UNUSED
) / RELOC_SPACING
;
864 int opnum
= (fixup_reloc
- (int) BFD_RELOC_UNUSED
) % RELOC_SPACING
;
869 case DVP_VUUP
: *operandP
= &vu_operands
[opnum
]; break;
870 case DVP_VULO
: *operandP
= &vu_operands
[opnum
]; break;
871 case DVP_DMA
: *operandP
= &dma_operands
[opnum
]; break;
872 case DVP_VIF
: *operandP
= &vif_operands
[opnum
]; break;
873 case DVP_GIF
: *operandP
= &gif_operands
[opnum
]; break;
874 default : as_fatal ("bad fixup encoding");
878 /* Given a fixup reloc type, return a pointer to the operand
880 /* The location from which a PC relative jump should be calculated,
881 given a PC relative reloc. */
884 md_pcrel_from_section (fixP
, sec
)
888 if (fixP
->fx_addsy
!= (symbolS
*) NULL
889 && (! S_IS_DEFINED (fixP
->fx_addsy
)
890 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
892 /* The symbol is undefined (or is defined but not in this section).
893 Let the linker figure it out. +8: branch offsets are relative to the
898 /* We assume this is a vu branch.
899 Offsets are calculated based on the address of the next insn. */
900 return ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
) & -8L) + 8;
903 /* Apply a fixup to the object code. This is called for all the
904 fixups we generated by calls to fix_new_exp. At this point all symbol
905 values should be fully resolved, and we attempt to completely resolve the
906 reloc. If we can not do that, we determine the correct reloc code and put
907 it back in the fixup. */
910 md_apply_fix3 (fixP
, valueP
, seg
)
915 char *where
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
918 /* FIXME FIXME FIXME: The value we are passed in *valueP includes
919 the symbol values. Since we are using BFD_ASSEMBLER, if we are
920 doing this relocation the code in write.c is going to call
921 bfd_perform_relocation, which is also going to use the symbol
922 value. That means that if the reloc is fully resolved we want to
923 use *valueP since bfd_perform_relocation is not being used.
924 However, if the reloc is not fully resolved we do not want to use
925 *valueP, and must use fx_offset instead. However, if the reloc
926 is PC relative, we do want to use *valueP since it includes the
927 result of md_pcrel_from. This is confusing. */
929 if (fixP
->fx_addsy
== (symbolS
*) NULL
)
934 else if (fixP
->fx_pcrel
)
940 value
= fixP
->fx_offset
;
941 if (fixP
->fx_subsy
!= (symbolS
*) NULL
)
943 if (S_GET_SEGMENT (fixP
->fx_subsy
) == absolute_section
)
944 value
-= S_GET_VALUE (fixP
->fx_subsy
);
947 /* We can't actually support subtracting a symbol. */
948 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
949 "expression too complex");
954 /* Check for dvp operand's. These are indicated with a reloc value
955 >= BFD_RELOC_UNUSED. */
957 if ((int) fixP
->fx_r_type
>= (int) BFD_RELOC_UNUSED
)
960 const dvp_operand
*operand
;
963 decode_fixup_reloc_type ((int) fixP
->fx_r_type
,
966 /* Fetch the instruction, insert the fully resolved operand
967 value, and stuff the instruction back again. */
968 insn
= bfd_getl32 ((unsigned char *) where
);
969 insert_operand_final (cpu
, operand
, DVP_MOD_THIS_WORD
, &insn
,
970 (offsetT
) value
, fixP
->fx_file
, fixP
->fx_line
);
971 bfd_putl32 ((bfd_vma
) insn
, (unsigned char *) where
);
975 /* Nothing else to do here. */
979 /* Determine a BFD reloc value based on the operand information.
980 We are only prepared to turn a few of the operands into relocs. */
981 /* FIXME: This test is a hack. */
982 if ((operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0)
984 assert ((operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0
985 && operand
->bits
== 11
986 && operand
->shift
== 0);
987 fixP
->fx_r_type
= BFD_RELOC_MIPS_DVP_11_PCREL
;
991 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
992 "unresolved expression that must be resolved");
999 switch (fixP
->fx_r_type
)
1002 md_number_to_chars (where
, value
, 1);
1005 md_number_to_chars (where
, value
, 2);
1008 md_number_to_chars (where
, value
, 4);
1015 fixP
->fx_addnumber
= value
;
1020 /* Translate internal representation of relocation info to BFD target
1024 tc_gen_reloc (section
, fixP
)
1030 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1032 reloc
->sym_ptr_ptr
= &fixP
->fx_addsy
->bsym
;
1033 reloc
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
1034 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
1035 if (reloc
->howto
== (reloc_howto_type
*) NULL
)
1037 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1038 "internal error: can't export reloc type %d (`%s')",
1039 fixP
->fx_r_type
, bfd_get_reloc_code_name (fixP
->fx_r_type
));
1043 assert (!fixP
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1045 reloc
->addend
= fixP
->fx_addnumber
;
1050 /* Write a value out to the object file, using the appropriate endianness. */
1053 md_number_to_chars (buf
, val
, n
)
1058 if (target_big_endian
)
1059 number_to_chars_bigendian (buf
, val
, n
);
1061 number_to_chars_littleendian (buf
, val
, n
);
1064 /* Turn a string in input_line_pointer into a floating point constant of type
1065 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1066 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
1069 /* Equal to MAX_PRECISION in atof-ieee.c */
1070 #define MAX_LITTLENUMS 6
1073 md_atof (type
, litP
, sizeP
)
1079 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1080 LITTLENUM_TYPE
*wordP
;
1100 /* FIXME: Some targets allow other format chars for bigger sizes here. */
1104 return "Bad call to md_atof()";
1107 t
= atof_ieee (input_line_pointer
, type
, words
);
1109 input_line_pointer
= t
;
1110 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1112 if (target_big_endian
)
1114 for (i
= 0; i
< prec
; i
++)
1116 md_number_to_chars (litP
, (valueT
) words
[i
], sizeof (LITTLENUM_TYPE
));
1117 litP
+= sizeof (LITTLENUM_TYPE
);
1122 for (i
= prec
- 1; i
>= 0; i
--)
1124 md_number_to_chars (litP
, (valueT
) words
[i
], sizeof (LITTLENUM_TYPE
));
1125 litP
+= sizeof (LITTLENUM_TYPE
);
1133 Compute the auto-count value for a DMA tag with inline data.
1136 parse_dma_ild_autocount( opcode
, operand
, mods
, insn_buf
, pstr
, errmsg
)
1137 const dvp_opcode
*opcode
;
1138 const dvp_operand
*operand
;
1142 const char **errmsg
;
1144 char *start
= *pstr
;
1149 /* FIXME: unfinished */
1150 evaluate the operand as an expression
1151 store the value to the count field
1152 compute the length as _$EndDma
-.
1159 /* Scan a symbol and return a pointer to one past the end. */
1160 #define issymchar(ch) (isalnum(ch) || ch == '_')
1165 while( *sym
&& issymchar( *sym
))
1171 Compute the auto-count value for a DMA tag with out-of-line data.
1174 parse_dma_ptr_autocount( opcode
, operand
, mods
, insn_buf
, pstr
, errmsg
)
1175 const dvp_opcode
*opcode
;
1176 const dvp_operand
*operand
;
1180 const char **errmsg
;
1182 char *start
= *pstr
;
1186 /* Data reference must be a .DmaData label. */
1187 struct symbol
*label
, *label2
;
1194 if( is_name_beginner( *start
) )
1198 end
= scan_symbol( start
);
1201 label
= symbol_find( start
);
1206 name
= S_GET_NAME( label
);
1207 len
= strlen( name
) + 1;
1208 name2
= xmalloc( len
+ 2);
1211 memcpy( name2
+2, name
, len
); /* copy original name & \0 */
1212 label2
= symbol_find( name2
);
1215 if( label
== 0 || label2
== 0 )
1217 *errmsg
= "2nd operand must be a .DmaData label";
1221 /* The second operand's value is the value of "symbol". */
1222 retval
= S_GET_VALUE( label
);
1224 /* The computed count value is val(symbol2) - val(symbol). */
1225 count
= S_GET_VALUE( label2
) - retval
;
1227 /* Store the count field. */
1228 count
&= 0x0000ffff;
1229 insn_buf
[ 4] &= 0xffff0000;
1230 insn_buf
[ 4] |= count
& 0x0000ffff;
1236 /* Return length in bytes of the variable length VIF insn
1237 currently being assembled. */
1240 cur_vif_insn_length ()
1245 if (cur_varlen_frag
== frag_now
)
1246 byte_len
= frag_more (0) - cur_varlen_insn
- 4; /* -4 for mpg itself */
1249 byte_len
= (cur_varlen_frag
->fr_fix
+ cur_varlen_frag
->fr_offset
-
1250 (cur_varlen_insn
- cur_varlen_frag
->fr_literal
)) - 4;
1251 for (f
= cur_varlen_frag
->fr_next
; f
!= frag_now
; f
= f
->fr_next
)
1252 byte_len
+= f
->fr_fix
+ f
->fr_offset
;
1253 byte_len
+= frag_now_fix ();
1259 /* Install length LEN, in bytes, in the vif insn at BUF.
1260 The bytes in BUF are in target order. */
1263 install_vif_length (buf
, len
)
1269 if ((cmd
& 0x70) == 0x40)
1273 /* ??? Worry about data /= 4 cuts off? */
1275 as_bad ("`mpg' data length must be between 1 and 256");
1276 buf
[2] = len
== 256 ? 0 : len
;
1278 else if ((cmd
& 0x70) == 0x50)
1280 /* direct/directhl */
1281 /* ??? Worry about data /= 16 cuts off? */
1284 as_bad ("`direct' data length must be between 1 and 65536");
1285 len
= len
== 65536 ? 0 : len
;
1289 else if ((cmd
& 0x60) == 0x60)
1295 as_fatal ("bad call to install_vif_length");
1298 /* Insert a file into the output.
1299 -I is used to specify where to find the file.
1300 The result is the number of bytes inserted.
1301 If an error occurs an error message is printed and zero is returned. */
1312 path
= xmalloc (strlen (file
) + include_dir_maxlen
+ 5 /*slop*/);
1314 for (i
= 0; i
< include_dir_count
; i
++)
1316 strcpy (path
, include_dirs
[i
]);
1318 strcat (path
, file
);
1319 if ((f
= fopen (path
, FOPEN_RB
)) != NULL
)
1324 f
= fopen (file
, FOPEN_RB
);
1327 as_bad ("unable to read file `%s'", file
);
1333 n
= fread (buf
, 1, sizeof (buf
), f
);
1336 char *fr
= frag_more (n
);
1337 memcpy (fr
, buf
, n
);
1343 /* We assume the file is smaller than 2^31 bytes.
1344 Ok, we shouldn't make any assumptions. Later. */
1348 /* Insert an operand value into an instruction. */
1351 insert_operand (cpu
, opcode
, operand
, mods
, insn_buf
, val
, errmsg
)
1353 const dvp_opcode
*opcode
;
1354 const dvp_operand
*operand
;
1358 const char **errmsg
;
1360 if (operand
->insert
)
1362 (*operand
->insert
) (opcode
, operand
, mods
, insn_buf
, (long) val
, errmsg
);
1366 #if 0 /* FIXME: revisit */
1367 /* We currently assume a field does not cross a word boundary. */
1368 int shift
= ((mods
& DVP_MOD_THIS_WORD
)
1369 ? (operand
->shift
& 31)
1371 DVP_INSN
*p
= insn_buf
+ (shift
/ 32);
1372 if (operand
->bits
== 32)
1377 *p
|= ((long) val
& ((1 << operand
->bits
) - 1)) << shift
;
1380 /* We currently assume a field does not cross a word boundary. */
1381 if (operand
->bits
== 32)
1382 insn_buf
[ operand
->word
] = val
;
1385 long temp
= (long) val
& ((1 << operand
->bits
) - 1);
1386 insn_buf
[ operand
->word
] |= temp
<< operand
->shift
;
1392 /* Insert an operand's final value into an instruction.
1393 Here we can give warning messages about operand values if we want to. */
1396 insert_operand_final (cpu
, operand
, mods
, insn_buf
, val
, file
, line
)
1398 const dvp_operand
*operand
;
1405 if (operand
->bits
!= 32)
1407 offsetT min
, max
, test
;
1409 if ((operand
->flags
& DVP_OPERAND_RELATIVE_BRANCH
) != 0)
1413 if (file
== (char *) NULL
)
1414 as_warn ("branch to misaligned address");
1416 as_warn_where (file
, line
, "branch to misaligned address");
1421 if ((operand
->flags
& DVP_OPERAND_SIGNED
) != 0)
1423 if ((operand
->flags
& DVP_OPERAND_SIGNOPT
) != 0)
1424 max
= (1 << operand
->bits
) - 1;
1426 max
= (1 << (operand
->bits
- 1)) - 1;
1427 min
= - (1 << (operand
->bits
- 1));
1431 max
= (1 << operand
->bits
) - 1;
1435 if ((operand
->flags
& DVP_OPERAND_NEGATIVE
) != 0)
1440 if (test
< (offsetT
) min
|| test
> (offsetT
) max
)
1443 "operand out of range (%s not between %ld and %ld)";
1446 sprint_value (buf
, test
);
1447 if (file
== (char *) NULL
)
1448 as_warn (err
, buf
, min
, max
);
1450 as_warn_where (file
, line
, err
, buf
, min
, max
);
1455 const char *errmsg
= NULL
;
1456 insert_operand (cpu
, NULL
, operand
, mods
, insn_buf
, val
, &errmsg
);
1458 as_warn_where (file
, line
, errmsg
);
1462 static short dmadata_state
= 0;
1463 static const char *dmadata_name
;
1465 /* Non-zero if .DmaData was implied by a real (non-pseudo) opcode. */
1466 static int implied_dmadata_p
= 0;
1469 s_dmadata_implied( ignore
)
1472 if( dmadata_state
!= 0 )
1474 as_bad( "DmaData blocks cannot be nested.");
1488 if( dmadata_state
!= 0 )
1490 as_bad( "DmaData blocks cannot be nested.");
1491 ignore_rest_of_line();
1496 SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */
1497 name
= input_line_pointer
;
1499 if( !is_name_beginner( *name
) )
1501 as_bad( "invalid identifier for \".DmaData\"");
1502 obstack_1grow( &cond_obstack
, 0); /*FIXME what is this for?*/
1503 ignore_rest_of_line();
1507 c
= get_symbol_end();
1508 line_label
= colon( name
); /* user-defined label */
1509 dmadata_name
= line_label
->bsym
->name
;
1510 *input_line_pointer
= c
;
1512 demand_empty_rest_of_line();
1516 s_enddmadata( ignore
)
1519 if( dmadata_state
!= 1)
1521 as_warn( ".EndDmaData encountered outside a DmaData block -- ignored.");
1522 ignore_rest_of_line();
1526 demand_empty_rest_of_line();
1529 * "label" points to beginning of block
1530 * Create a name for the final label like _$<name>
1536 temp
= strlen( dmadata_name
) + 1;
1537 name
= xmalloc( temp
+ 2);
1540 memcpy( name
+2, dmadata_name
, temp
); /* copy original name & \0 */
1547 s_dmapackvif( ignore
)
1550 /* Syntax: .dmapackvif 0|1 */
1551 struct symbol
*label
; /* Points to symbol */
1552 char *name
; /* points to name of symbol */
1554 SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */
1555 switch( *input_line_pointer
++ )
1564 as_bad( "illegal argument to `.DmaPackPke'");
1566 demand_empty_rest_of_line();
1570 s_enddirect (ignore
)
1575 if (cur_asm_state
!= ASM_DIRECT
)
1577 as_bad ("`.enddirect' has no matching `direct' instruction");
1581 byte_len
= cur_vif_insn_length ();
1582 if (cur_varlen_value
!= -1
1583 && cur_varlen_value
* 16 != byte_len
)
1584 as_warn ("length in `direct' instruction does not match length of data");
1586 install_vif_length (cur_varlen_insn
, byte_len
);
1588 cur_asm_state
= ASM_INIT
;
1590 /* These needn't be reset, but to catch bugs they are. */
1591 cur_varlen_frag
= NULL
;
1592 cur_varlen_insn
= NULL
;
1593 cur_varlen_value
= 0;
1602 if (cur_asm_state
!= ASM_MPG
)
1604 as_bad ("`.endmpg' has no matching `mpg' instruction");
1608 byte_len
= cur_vif_insn_length ();
1609 if (cur_varlen_value
!= -1
1610 && cur_varlen_value
* 8 != byte_len
)
1611 as_warn ("length in `mpg' instruction does not match length of data");
1613 install_vif_length (cur_varlen_insn
, byte_len
);
1615 cur_asm_state
= ASM_INIT
;
1617 /* These needn't be reset, but to catch bugs they are. */
1618 cur_varlen_frag
= NULL
;
1619 cur_varlen_insn
= NULL
;
1620 cur_varlen_value
= 0;
1622 /* Update $.MpgLoc. */
1623 vif_set_mpgloc (vif_get_mpgloc () + byte_len
);
1627 s_endunpack (ignore
)
1632 if (cur_asm_state
!= ASM_UNPACK
)
1634 as_bad ("`.endunpack' has no matching `unpack' instruction");
1638 byte_len
= cur_vif_insn_length ();
1639 #if 0 /* unpack doesn't support prespecifying a length */
1640 if (cur_varlen_value
* 16 != bytelen
)
1641 as_warn ("length in `direct' instruction does not match length of data");
1644 install_vif_length (cur_varlen_insn
, byte_len
);
1646 cur_asm_state
= ASM_INIT
;
1648 /* These needn't be reset, but to catch bugs they are. */
1649 cur_varlen_frag
= NULL
;
1650 cur_varlen_insn
= NULL
;
1651 cur_varlen_value
= 0;
1653 /* Update $.UnpackLoc. */
1654 vif_set_unpackloc (vif_get_unpackloc () + byte_len
);
1661 cur_asm_state
= state
;
1670 /* Parse a DMA data spec which can be either of '*' or a quad word count. */
1673 parse_dma_count( pstr
, errmsg
)
1675 const char **errmsg
;
1684 /* -1 is a special marker to caller to tell it the count is to be
1685 computed from the data. */
1690 if( exp
.X_op
== O_illegal
1691 || exp
.X_op
== O_absent
)
1693 else if( exp
.X_op
== O_constant
)
1694 value
= exp
.X_add_number
;
1695 else if( exp
.X_op
== O_register
)
1696 as_fatal( "got O_register");
1699 /* We need to generate a fixup for this expression. */
1700 if( fixup_count
>= MAX_FIXUPS
)
1701 as_fatal( "too many fixups");
1702 fixups
[fixup_count
].exp
= exp
;
1703 fixups
[fixup_count
].opindex
= 0 /*FIXME*/;
1704 fixups
[fixup_count
].offset
= 0 /*FIXME*/;
1709 if( isdigit( *str
) ) /* ????????needs to accept an expression*/
1712 while( *str
&& *str
!= ',' )
1716 *errmsg
= "invalid dma count";
1719 count
= atoi (start
);
1724 *errmsg
= "invalid dma count";