1 /* tc-moxie.c -- Assemble code for moxie
3 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
20 Boston, MA 02110-1301, USA. */
22 /* Contributed by Anthony Green <green@moxielogic.com>. */
25 #include "safe-ctype.h"
26 #include "opcode/moxie.h"
27 #include "elf/moxie.h"
29 extern const moxie_opc_info_t moxie_opc_info
[128];
31 const char comment_chars
[] = "#";
32 const char line_separator_chars
[] = ";";
33 const char line_comment_chars
[] = "#";
35 static int pending_reloc
;
36 static struct hash_control
*opcode_hash_control
;
38 const pseudo_typeS md_pseudo_table
[] =
43 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
44 const char EXP_CHARS
[] = "eE";
47 md_operand (expressionS
*op
__attribute__((unused
)))
52 /* This function is called once, at assembler startup time. It sets
53 up the hash table with all the opcodes in it, and also initializes
54 some aliases for compatibility with other assemblers. */
60 const moxie_opc_info_t
*opcode
;
61 opcode_hash_control
= hash_new ();
63 /* Insert names into hash table. */
64 for (count
= 0, opcode
= moxie_form1_opc_info
; count
++ < 64; opcode
++)
65 hash_insert (opcode_hash_control
, opcode
->name
, (char *) opcode
);
67 for (count
= 0, opcode
= moxie_form2_opc_info
; count
++ < 4; opcode
++)
68 hash_insert (opcode_hash_control
, opcode
->name
, (char *) opcode
);
70 for (count
= 0, opcode
= moxie_form3_opc_info
; count
++ < 4; opcode
++)
71 hash_insert (opcode_hash_control
, opcode
->name
, (char *) opcode
);
73 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, 0);
76 /* Parse an expression and then restore the input line pointer. */
79 parse_exp_save_ilp (char *s
, expressionS
*op
)
81 char *save
= input_line_pointer
;
83 input_line_pointer
= s
;
85 s
= input_line_pointer
;
86 input_line_pointer
= save
;
91 parse_register_operand (char **ptr
)
98 as_bad ("expecting register");
99 ignore_rest_of_line ();
102 if (s
[1] == 'f' && s
[2] == 'p')
107 if (s
[1] == 's' && s
[2] == 'p')
115 if ((reg
< 0) || (reg
> 9))
117 as_bad ("illegal register number");
118 ignore_rest_of_line ();
124 if ((r2
>= 0) && (r2
<= 3))
133 as_bad ("illegal register number");
134 ignore_rest_of_line ();
143 /* This is the guts of the machine-dependent assembler. STR points to
144 a machine dependent instruction. This function is supposed to emit
145 the frags/bytes it assembles to. */
148 md_assemble (char *str
)
153 moxie_opc_info_t
*opcode
;
157 unsigned short iword
= 0;
161 /* Drop leading whitespace. */
165 /* Find the op code end. */
168 *op_end
&& !is_end_of_line
[*op_end
& 0xff] && *op_end
!= ' ';
176 as_bad (_("can't find opcode "));
177 opcode
= (moxie_opc_info_t
*) hash_find (opcode_hash_control
, op_start
);
182 as_bad (_("unknown opcode %s"), op_start
);
188 switch (opcode
->itype
)
191 iword
= (1<<15) | (opcode
->opcode
<< 12);
192 while (ISSPACE (*op_end
))
197 reg
= parse_register_operand (&op_end
);
200 as_warn ("expecting comma delimeted register operands");
202 op_end
= parse_exp_save_ilp (op_end
, &arg
);
203 fix_new_exp (frag_now
,
204 ((p
+1) - frag_now
->fr_literal
),
212 iword
= opcode
->opcode
<< 8;
213 while (ISSPACE (*op_end
))
217 dest
= parse_register_operand (&op_end
);
219 as_warn ("expecting comma delimeted register operands");
221 src
= parse_register_operand (&op_end
);
222 iword
+= (dest
<< 4) + src
;
223 while (ISSPACE (*op_end
))
226 as_warn ("extra stuff on line ignored");
230 iword
= opcode
->opcode
<< 8;
231 while (ISSPACE (*op_end
))
238 regnum
= parse_register_operand (&op_end
);
239 while (ISSPACE (*op_end
))
242 iword
+= (regnum
<< 4);
246 as_bad ("expecting comma delimited operands");
247 ignore_rest_of_line ();
252 op_end
= parse_exp_save_ilp (op_end
, &arg
);
253 where
= frag_more (4);
254 fix_new_exp (frag_now
,
255 (where
- frag_now
->fr_literal
),
264 iword
= opcode
->opcode
<< 8;
265 while (ISSPACE (*op_end
))
271 op_end
= parse_exp_save_ilp (op_end
, &arg
);
272 where
= frag_more (4);
273 fix_new_exp (frag_now
,
274 (where
- frag_now
->fr_literal
),
282 iword
= opcode
->opcode
<< 8;
283 while (ISSPACE (*op_end
))
286 as_warn ("extra stuff on line ignored");
289 iword
= opcode
->opcode
<< 8;
290 while (ISSPACE (*op_end
))
294 reg
= parse_register_operand (&op_end
);
295 while (ISSPACE (*op_end
))
298 as_warn ("extra stuff on line ignored");
303 iword
= opcode
->opcode
<< 8;
304 while (ISSPACE (*op_end
))
308 a
= parse_register_operand (&op_end
);
310 as_warn ("expecting comma delimeted register operands");
314 as_bad ("expecting indirect register `($rA)'");
315 ignore_rest_of_line ();
319 b
= parse_register_operand (&op_end
);
322 as_bad ("missing closing parenthesis");
323 ignore_rest_of_line ();
327 iword
+= (a
<< 4) + b
;
328 while (ISSPACE (*op_end
))
331 as_warn ("extra stuff on line ignored");
335 iword
= opcode
->opcode
<< 8;
336 while (ISSPACE (*op_end
))
342 as_bad ("expecting indirect register `($rA)'");
343 ignore_rest_of_line ();
347 a
= parse_register_operand (&op_end
);
350 as_bad ("missing closing parenthesis");
351 ignore_rest_of_line ();
356 as_warn ("expecting comma delimeted register operands");
358 b
= parse_register_operand (&op_end
);
359 iword
+= (a
<< 4) + b
;
360 while (ISSPACE (*op_end
))
363 as_warn ("extra stuff on line ignored");
367 iword
= opcode
->opcode
<< 8;
368 while (ISSPACE (*op_end
))
375 op_end
= parse_exp_save_ilp (op_end
, &arg
);
376 where
= frag_more (4);
377 fix_new_exp (frag_now
,
378 (where
- frag_now
->fr_literal
),
386 as_bad ("expecting comma delimited operands");
387 ignore_rest_of_line ();
392 a
= parse_register_operand (&op_end
);
393 while (ISSPACE (*op_end
))
396 as_warn ("extra stuff on line ignored");
402 iword
= opcode
->opcode
<< 8;
403 while (ISSPACE (*op_end
))
410 a
= parse_register_operand (&op_end
);
411 while (ISSPACE (*op_end
))
416 as_bad ("expecting comma delimited operands");
417 ignore_rest_of_line ();
422 op_end
= parse_exp_save_ilp (op_end
, &arg
);
423 offset
= frag_more (4);
424 fix_new_exp (frag_now
,
425 (offset
- frag_now
->fr_literal
),
433 as_bad ("expecting indirect register `($rX)'");
434 ignore_rest_of_line ();
438 b
= parse_register_operand (&op_end
);
441 as_bad ("missing closing parenthesis");
442 ignore_rest_of_line ();
447 while (ISSPACE (*op_end
))
450 as_warn ("extra stuff on line ignored");
452 iword
+= (a
<< 4) + b
;
456 iword
= opcode
->opcode
<< 8;
457 while (ISSPACE (*op_end
))
464 op_end
= parse_exp_save_ilp (op_end
, &arg
);
465 offset
= frag_more (4);
466 fix_new_exp (frag_now
,
467 (offset
- frag_now
->fr_literal
),
475 as_bad ("expecting indirect register `($rX)'");
476 ignore_rest_of_line ();
480 a
= parse_register_operand (&op_end
);
483 as_bad ("missing closing parenthesis");
484 ignore_rest_of_line ();
491 as_bad ("expecting comma delimited operands");
492 ignore_rest_of_line ();
497 b
= parse_register_operand (&op_end
);
498 while (ISSPACE (*op_end
))
501 while (ISSPACE (*op_end
))
504 as_warn ("extra stuff on line ignored");
506 iword
+= (a
<< 4) + b
;
510 iword
= opcode
->opcode
<< 12;
511 while (ISSPACE (*op_end
))
514 as_warn ("extra stuff on line ignored");
520 md_number_to_chars (p
, iword
, 2);
522 while (ISSPACE (*op_end
))
526 as_warn ("extra stuff on line ignored");
529 as_bad ("Something forgot to clean up\n");
532 /* Turn a string in input_line_pointer into a floating point constant
533 of type type, and store the appropriate bytes in *LITP. The number
534 of LITTLENUMS emitted is stored in *SIZEP . An error message is
535 returned, or NULL on OK. */
538 md_atof (int type
, char *litP
, int *sizeP
)
541 LITTLENUM_TYPE words
[4];
557 return _("bad call to md_atof");
560 t
= atof_ieee (input_line_pointer
, type
, words
);
562 input_line_pointer
= t
;
566 for (i
= prec
- 1; i
>= 0; i
--)
568 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
575 const char *md_shortopts
= "";
577 struct option md_longopts
[] =
579 {NULL
, no_argument
, NULL
, 0}
581 size_t md_longopts_size
= sizeof (md_longopts
);
583 /* We have no target specific options yet, so these next
584 two functions are empty. */
586 md_parse_option (int c ATTRIBUTE_UNUSED
, char *arg ATTRIBUTE_UNUSED
)
592 md_show_usage (FILE *stream ATTRIBUTE_UNUSED
)
596 /* Apply a fixup to the object file. */
599 md_apply_fix (fixS
*fixP ATTRIBUTE_UNUSED
, valueT
* valP ATTRIBUTE_UNUSED
, segT seg ATTRIBUTE_UNUSED
)
601 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
608 switch (fixP
->fx_r_type
)
630 if (max
!= 0 && (val
< min
|| val
> max
))
631 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("offset out of range"));
633 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0)
637 /* Put number into target byte order (big endian). */
640 md_number_to_chars (char *ptr
, valueT use
, int nbytes
)
642 number_to_chars_bigendian (ptr
, use
, nbytes
);
645 /* Generate a machine-dependent relocation. */
647 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixP
)
650 bfd_reloc_code_real_type code
;
652 switch (fixP
->fx_r_type
)
655 code
= fixP
->fx_r_type
;
658 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
659 _("Semantics error. This type of operand can not be relocated, it must be an assembly-time constant"));
663 relP
= xmalloc (sizeof (arelent
));
665 relP
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
666 *relP
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
667 relP
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
669 relP
->addend
= fixP
->fx_offset
;
671 /* This is the standard place for KLUDGEs to work around bugs in
672 bfd_install_relocation (first such note in the documentation
673 appears with binutils-2.8).
675 That function bfd_install_relocation does the wrong thing with
676 putting stuff into the addend of a reloc (it should stay out) for a
677 weak symbol. The really bad thing is that it adds the
678 "segment-relative offset" of the symbol into the reloc. In this
679 case, the reloc should instead be relative to the symbol with no
680 other offset than the assembly code shows; and since the symbol is
681 weak, any local definition should be ignored until link time (or
683 To wit: weaksym+42 should be weaksym+42 in the reloc,
684 not weaksym+(offset_from_segment_of_local_weaksym_definition)
686 To "work around" this, we subtract the segment-relative offset of
687 "known" weak symbols. This evens out the extra offset.
689 That happens for a.out but not for ELF, since for ELF,
690 bfd_install_relocation uses the "special function" field of the
691 howto, and does not execute the code that needs to be undone. */
693 if (OUTPUT_FLAVOR
== bfd_target_aout_flavour
694 && fixP
->fx_addsy
&& S_IS_WEAK (fixP
->fx_addsy
)
695 && ! bfd_is_und_section (S_GET_SEGMENT (fixP
->fx_addsy
)))
697 relP
->addend
-= S_GET_VALUE (fixP
->fx_addsy
);
700 relP
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
705 name
= S_GET_NAME (fixP
->fx_addsy
);
707 name
= _("<unknown>");
708 as_fatal (_("Cannot generate relocation type for symbol %s, code %s"),
709 name
, bfd_get_reloc_code_name (code
));
715 /* Decide from what point a pc-relative relocation is relative to,
716 relative to the pc-relative fixup. Er, relatively speaking. */
718 md_pcrel_from (fixS
*fixP
)
720 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
722 fprintf (stderr
, "md_pcrel_from 0x%d\n", fixP
->fx_r_type
);
724 switch (fixP
->fx_r_type
)