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
),
263 iword
= opcode
->opcode
<< 8;
264 while (ISSPACE (*op_end
))
270 op_end
= parse_exp_save_ilp (op_end
, &arg
);
271 where
= frag_more (4);
272 fix_new_exp (frag_now
,
273 (where
- frag_now
->fr_literal
),
281 iword
= opcode
->opcode
<< 8;
282 while (ISSPACE (*op_end
))
285 as_warn ("extra stuff on line ignored");
288 iword
= opcode
->opcode
<< 8;
289 while (ISSPACE (*op_end
))
293 reg
= parse_register_operand (&op_end
);
294 while (ISSPACE (*op_end
))
297 as_warn ("extra stuff on line ignored");
302 iword
= opcode
->opcode
<< 8;
303 while (ISSPACE (*op_end
))
307 a
= parse_register_operand (&op_end
);
309 as_warn ("expecting comma delimeted register operands");
313 as_bad ("expecting indirect register `($rA)'");
314 ignore_rest_of_line ();
318 b
= parse_register_operand (&op_end
);
321 as_bad ("missing closing parenthesis");
322 ignore_rest_of_line ();
326 iword
+= (a
<< 4) + b
;
327 while (ISSPACE (*op_end
))
330 as_warn ("extra stuff on line ignored");
334 iword
= opcode
->opcode
<< 8;
335 while (ISSPACE (*op_end
))
341 as_bad ("expecting indirect register `($rA)'");
342 ignore_rest_of_line ();
346 a
= parse_register_operand (&op_end
);
349 as_bad ("missing closing parenthesis");
350 ignore_rest_of_line ();
355 as_warn ("expecting comma delimeted register operands");
357 b
= parse_register_operand (&op_end
);
358 iword
+= (a
<< 4) + b
;
359 while (ISSPACE (*op_end
))
362 as_warn ("extra stuff on line ignored");
366 iword
= opcode
->opcode
<< 8;
367 while (ISSPACE (*op_end
))
374 op_end
= parse_exp_save_ilp (op_end
, &arg
);
375 where
= frag_more (4);
376 fix_new_exp (frag_now
,
377 (where
- frag_now
->fr_literal
),
385 as_bad ("expecting comma delimited operands");
386 ignore_rest_of_line ();
391 a
= parse_register_operand (&op_end
);
392 while (ISSPACE (*op_end
))
395 as_warn ("extra stuff on line ignored");
401 iword
= opcode
->opcode
<< 8;
402 while (ISSPACE (*op_end
))
409 a
= parse_register_operand (&op_end
);
410 while (ISSPACE (*op_end
))
415 as_bad ("expecting comma delimited operands");
416 ignore_rest_of_line ();
421 op_end
= parse_exp_save_ilp (op_end
, &arg
);
422 offset
= frag_more (4);
423 fix_new_exp (frag_now
,
424 (offset
- frag_now
->fr_literal
),
432 as_bad ("expecting indirect register `($rX)'");
433 ignore_rest_of_line ();
437 b
= parse_register_operand (&op_end
);
440 as_bad ("missing closing parenthesis");
441 ignore_rest_of_line ();
446 while (ISSPACE (*op_end
))
449 as_warn ("extra stuff on line ignored");
451 iword
+= (a
<< 4) + b
;
455 iword
= opcode
->opcode
<< 8;
456 while (ISSPACE (*op_end
))
463 op_end
= parse_exp_save_ilp (op_end
, &arg
);
464 offset
= frag_more (4);
465 fix_new_exp (frag_now
,
466 (offset
- frag_now
->fr_literal
),
474 as_bad ("expecting indirect register `($rX)'");
475 ignore_rest_of_line ();
479 a
= parse_register_operand (&op_end
);
482 as_bad ("missing closing parenthesis");
483 ignore_rest_of_line ();
490 as_bad ("expecting comma delimited operands");
491 ignore_rest_of_line ();
496 b
= parse_register_operand (&op_end
);
497 while (ISSPACE (*op_end
))
500 while (ISSPACE (*op_end
))
503 as_warn ("extra stuff on line ignored");
505 iword
+= (a
<< 4) + b
;
509 iword
= opcode
->opcode
<< 12;
510 while (ISSPACE (*op_end
))
513 as_warn ("extra stuff on line ignored");
519 md_number_to_chars (p
, iword
, 2);
521 while (ISSPACE (*op_end
))
525 as_warn ("extra stuff on line ignored");
528 as_bad ("Something forgot to clean up\n");
531 /* Turn a string in input_line_pointer into a floating point constant
532 of type type, and store the appropriate bytes in *LITP. The number
533 of LITTLENUMS emitted is stored in *SIZEP . An error message is
534 returned, or NULL on OK. */
537 md_atof (int type
, char *litP
, int *sizeP
)
540 LITTLENUM_TYPE words
[4];
556 return _("bad call to md_atof");
559 t
= atof_ieee (input_line_pointer
, type
, words
);
561 input_line_pointer
= t
;
565 for (i
= prec
- 1; i
>= 0; i
--)
567 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
574 const char *md_shortopts
= "";
576 struct option md_longopts
[] =
578 {NULL
, no_argument
, NULL
, 0}
580 size_t md_longopts_size
= sizeof (md_longopts
);
582 /* We have no target specific options yet, so these next
583 two functions are empty. */
585 md_parse_option (int c ATTRIBUTE_UNUSED
, char *arg ATTRIBUTE_UNUSED
)
591 md_show_usage (FILE *stream ATTRIBUTE_UNUSED
)
595 /* Apply a fixup to the object file. */
598 md_apply_fix (fixS
*fixP ATTRIBUTE_UNUSED
, valueT
* valP ATTRIBUTE_UNUSED
, segT seg ATTRIBUTE_UNUSED
)
600 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
607 switch (fixP
->fx_r_type
)
629 if (max
!= 0 && (val
< min
|| val
> max
))
630 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, _("offset out of range"));
632 if (fixP
->fx_addsy
== NULL
&& fixP
->fx_pcrel
== 0)
636 /* Put number into target byte order (big endian). */
639 md_number_to_chars (char *ptr
, valueT use
, int nbytes
)
641 number_to_chars_bigendian (ptr
, use
, nbytes
);
644 /* Generate a machine-dependent relocation. */
646 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixP
)
649 bfd_reloc_code_real_type code
;
651 switch (fixP
->fx_r_type
)
654 code
= fixP
->fx_r_type
;
657 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
658 _("Semantics error. This type of operand can not be relocated, it must be an assembly-time constant"));
662 relP
= xmalloc (sizeof (arelent
));
664 relP
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
665 *relP
->sym_ptr_ptr
= symbol_get_bfdsym (fixP
->fx_addsy
);
666 relP
->address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
668 relP
->addend
= fixP
->fx_offset
;
670 /* This is the standard place for KLUDGEs to work around bugs in
671 bfd_install_relocation (first such note in the documentation
672 appears with binutils-2.8).
674 That function bfd_install_relocation does the wrong thing with
675 putting stuff into the addend of a reloc (it should stay out) for a
676 weak symbol. The really bad thing is that it adds the
677 "segment-relative offset" of the symbol into the reloc. In this
678 case, the reloc should instead be relative to the symbol with no
679 other offset than the assembly code shows; and since the symbol is
680 weak, any local definition should be ignored until link time (or
682 To wit: weaksym+42 should be weaksym+42 in the reloc,
683 not weaksym+(offset_from_segment_of_local_weaksym_definition)
685 To "work around" this, we subtract the segment-relative offset of
686 "known" weak symbols. This evens out the extra offset.
688 That happens for a.out but not for ELF, since for ELF,
689 bfd_install_relocation uses the "special function" field of the
690 howto, and does not execute the code that needs to be undone. */
692 if (OUTPUT_FLAVOR
== bfd_target_aout_flavour
693 && fixP
->fx_addsy
&& S_IS_WEAK (fixP
->fx_addsy
)
694 && ! bfd_is_und_section (S_GET_SEGMENT (fixP
->fx_addsy
)))
696 relP
->addend
-= S_GET_VALUE (fixP
->fx_addsy
);
699 relP
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
704 name
= S_GET_NAME (fixP
->fx_addsy
);
706 name
= _("<unknown>");
707 as_fatal (_("Cannot generate relocation type for symbol %s, code %s"),
708 name
, bfd_get_reloc_code_name (code
));
714 /* Decide from what point a pc-relative relocation is relative to,
715 relative to the pc-relative fixup. Er, relatively speaking. */
717 md_pcrel_from (fixS
*fixP
)
719 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
721 fprintf (stderr
, "md_pcrel_from 0x%d\n", fixP
->fx_r_type
);
723 switch (fixP
->fx_r_type
)