1
/* tc-moxie.c -- Assemble code for moxie
2
Copyright (C) 2009-2014 Free Software Foundation, Inc.
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 3, 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, 51 Franklin Street - Fifth Floor,
19
Boston, MA 02110-1301, USA. */
21
/* Contributed by Anthony Green <green@moxielogic.com>. */
24
#include "safe-ctype.h"
25
#include "opcode/moxie.h"
26
#include "elf/moxie.h"
28
extern const moxie_opc_info_t moxie_opc_info[128];
30
const char comment_chars[] = "#";
31
const char line_separator_chars[] = ";";
32
const char line_comment_chars[] = "#";
34
static int pending_reloc;
35
static struct hash_control *opcode_hash_control;
37
const pseudo_typeS md_pseudo_table[] =
42
const char FLT_CHARS[] = "rRsSfFdDxXpP";
43
const char EXP_CHARS[] = "eE";
45
static valueT md_chars_to_number (char * buf, int n);
48
extern int target_big_endian;
51
md_operand (expressionS *op __attribute__((unused)))
56
/* This function is called once, at assembler startup time. It sets
57
up the hash table with all the opcodes in it, and also initializes
58
some aliases for compatibility with other assemblers. */
64
const moxie_opc_info_t *opcode;
65
opcode_hash_control = hash_new ();
67
/* Insert names into hash table. */
68
for (count = 0, opcode = moxie_form1_opc_info; count++ < 64; opcode++)
69
hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
71
for (count = 0, opcode = moxie_form2_opc_info; count++ < 4; opcode++)
72
hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
74
for (count = 0, opcode = moxie_form3_opc_info; count++ < 10; opcode++)
75
hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
77
target_big_endian = TARGET_BYTES_BIG_ENDIAN;
79
bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
82
/* Parse an expression and then restore the input line pointer. */
85
parse_exp_save_ilp (char *s, expressionS *op)
87
char *save = input_line_pointer;
89
input_line_pointer = s;
91
s = input_line_pointer;
92
input_line_pointer = save;
97
parse_register_operand (char **ptr)
104
as_bad (_("expecting register"));
105
ignore_rest_of_line ();
108
if (s[1] == 'f' && s[2] == 'p')
113
if (s[1] == 's' && s[2] == 'p')
121
if ((reg < 0) || (reg > 9))
123
as_bad (_("illegal register number"));
124
ignore_rest_of_line ();
130
if ((r2 >= 0) && (r2 <= 3))
139
as_bad (_("illegal register number"));
140
ignore_rest_of_line ();
149
/* This is the guts of the machine-dependent assembler. STR points to
150
a machine dependent instruction. This function is supposed to emit
151
the frags/bytes it assembles to. */
154
md_assemble (char *str)
159
moxie_opc_info_t *opcode;
163
unsigned short iword = 0;
167
/* Drop leading whitespace. */
171
/* Find the op code end. */
174
*op_end && !is_end_of_line[*op_end & 0xff] && *op_end != ' ';
182
as_bad (_("can't find opcode "));
183
opcode = (moxie_opc_info_t *) hash_find (opcode_hash_control, op_start);
188
as_bad (_("unknown opcode %s"), op_start);
194
switch (opcode->itype)
197
iword = (1<<15) | (opcode->opcode << 12);
198
while (ISSPACE (*op_end))
203
reg = parse_register_operand (&op_end);
206
as_warn (_("expecting comma delimited register operands"));
208
op_end = parse_exp_save_ilp (op_end, &arg);
209
fix_new_exp (frag_now,
210
((p + (target_big_endian ? 1 : 0)) - frag_now->fr_literal),
218
iword = opcode->opcode << 8;
219
while (ISSPACE (*op_end))
223
dest = parse_register_operand (&op_end);
225
as_warn (_("expecting comma delimited register operands"));
227
src = parse_register_operand (&op_end);
228
iword += (dest << 4) + src;
229
while (ISSPACE (*op_end))
232
as_warn (_("extra stuff on line ignored"));
236
iword = opcode->opcode << 8;
237
while (ISSPACE (*op_end))
244
regnum = parse_register_operand (&op_end);
245
while (ISSPACE (*op_end))
248
iword += (regnum << 4);
252
as_bad (_("expecting comma delimited operands"));
253
ignore_rest_of_line ();
258
op_end = parse_exp_save_ilp (op_end, &arg);
259
where = frag_more (4);
260
fix_new_exp (frag_now,
261
(where - frag_now->fr_literal),
270
iword = opcode->opcode << 8;
271
while (ISSPACE (*op_end))
277
op_end = parse_exp_save_ilp (op_end, &arg);
278
where = frag_more (4);
279
fix_new_exp (frag_now,
280
(where - frag_now->fr_literal),
288
iword = opcode->opcode << 8;
289
while (ISSPACE (*op_end))
292
as_warn (_("extra stuff on line ignored"));
295
iword = opcode->opcode << 8;
296
while (ISSPACE (*op_end))
300
reg = parse_register_operand (&op_end);
301
while (ISSPACE (*op_end))
304
as_warn (_("extra stuff on line ignored"));
309
iword = opcode->opcode << 8;
310
while (ISSPACE (*op_end))
314
a = parse_register_operand (&op_end);
316
as_warn (_("expecting comma delimited register operands"));
320
as_bad (_("expecting indirect register `($rA)'"));
321
ignore_rest_of_line ();
325
b = parse_register_operand (&op_end);
328
as_bad (_("missing closing parenthesis"));
329
ignore_rest_of_line ();
333
iword += (a << 4) + b;
334
while (ISSPACE (*op_end))
337
as_warn (_("extra stuff on line ignored"));
341
iword = opcode->opcode << 8;
342
while (ISSPACE (*op_end))
348
as_bad (_("expecting indirect register `($rA)'"));
349
ignore_rest_of_line ();
353
a = parse_register_operand (&op_end);
356
as_bad (_("missing closing parenthesis"));
357
ignore_rest_of_line ();
362
as_warn (_("expecting comma delimited register operands"));
364
b = parse_register_operand (&op_end);
365
iword += (a << 4) + b;
366
while (ISSPACE (*op_end))
369
as_warn (_("extra stuff on line ignored"));
373
iword = opcode->opcode << 8;
374
while (ISSPACE (*op_end))
381
op_end = parse_exp_save_ilp (op_end, &arg);
382
where = frag_more (4);
383
fix_new_exp (frag_now,
384
(where - frag_now->fr_literal),
392
as_bad (_("expecting comma delimited operands"));
393
ignore_rest_of_line ();
398
a = parse_register_operand (&op_end);
399
while (ISSPACE (*op_end))
402
as_warn (_("extra stuff on line ignored"));
408
iword = opcode->opcode << 8;
409
while (ISSPACE (*op_end))
416
a = parse_register_operand (&op_end);
417
while (ISSPACE (*op_end))
422
as_bad (_("expecting comma delimited operands"));
423
ignore_rest_of_line ();
428
op_end = parse_exp_save_ilp (op_end, &arg);
429
offset = frag_more (4);
430
fix_new_exp (frag_now,
431
(offset - frag_now->fr_literal),
439
as_bad (_("expecting indirect register `($rX)'"));
440
ignore_rest_of_line ();
444
b = parse_register_operand (&op_end);
447
as_bad (_("missing closing parenthesis"));
448
ignore_rest_of_line ();
453
while (ISSPACE (*op_end))
456
as_warn (_("extra stuff on line ignored"));
458
iword += (a << 4) + b;
462
iword = opcode->opcode << 8;
463
while (ISSPACE (*op_end))
470
op_end = parse_exp_save_ilp (op_end, &arg);
471
offset = frag_more (4);
472
fix_new_exp (frag_now,
473
(offset - frag_now->fr_literal),
481
as_bad (_("expecting indirect register `($rX)'"));
482
ignore_rest_of_line ();
486
a = parse_register_operand (&op_end);
489
as_bad (_("missing closing parenthesis"));
490
ignore_rest_of_line ();
497
as_bad (_("expecting comma delimited operands"));
498
ignore_rest_of_line ();
503
b = parse_register_operand (&op_end);
504
while (ISSPACE (*op_end))
507
while (ISSPACE (*op_end))
510
as_warn (_("extra stuff on line ignored"));
512
iword += (a << 4) + b;
516
iword = opcode->opcode << 12;
517
while (ISSPACE (*op_end))
520
as_warn (_("extra stuff on line ignored"));
523
iword = (3<<14) | (opcode->opcode << 10);
524
while (ISSPACE (*op_end))
529
op_end = parse_exp_save_ilp (op_end, &arg);
530
fix_new_exp (frag_now,
531
(p - frag_now->fr_literal),
535
BFD_RELOC_MOXIE_10_PCREL);
542
md_number_to_chars (p, iword, 2);
544
while (ISSPACE (*op_end))
548
as_warn (_("extra stuff on line ignored"));
551
as_bad (_("Something forgot to clean up\n"));
554
/* Turn a string in input_line_pointer into a floating point constant
555
of type type, and store the appropriate bytes in *LITP. The number
556
of LITTLENUMS emitted is stored in *SIZEP . An error message is
557
returned, or NULL on OK. */
560
md_atof (int type, char *litP, int *sizeP)
563
LITTLENUM_TYPE words[4];
579
return _("bad call to md_atof");
582
t = atof_ieee (input_line_pointer, type, words);
584
input_line_pointer = t;
588
for (i = prec - 1; i >= 0; i--)
590
md_number_to_chars (litP, (valueT) words[i], 2);
599
OPTION_EB = OPTION_MD_BASE,
603
struct option md_longopts[] =
605
{ "EB", no_argument, NULL, OPTION_EB},
606
{ "EL", no_argument, NULL, OPTION_EL},
607
{ NULL, no_argument, NULL, 0}
610
size_t md_longopts_size = sizeof (md_longopts);
612
const char *md_shortopts = "";
615
md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
620
target_big_endian = 1;
623
target_big_endian = 0;
633
md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
635
fprintf (stream, _("\
636
-EB assemble for a big endian system (default)\n\
637
-EL assemble for a little endian system\n"));
640
/* Apply a fixup to the object file. */
643
md_apply_fix (fixS *fixP ATTRIBUTE_UNUSED,
644
valueT * valP ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED)
646
char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
652
switch (fixP->fx_r_type)
655
if (target_big_endian)
673
if (target_big_endian)
690
case BFD_RELOC_MOXIE_10_PCREL:
693
if (val < -1024 || val > 1022)
694
as_bad_where (fixP->fx_file, fixP->fx_line,
695
_("pcrel too far BFD_RELOC_MOXIE_10"));
696
/* 11 bit offset even numbered, so we remove right bit. */
698
newval = md_chars_to_number (buf, 2);
699
newval |= val & 0x03ff;
700
md_number_to_chars (buf, newval, 2);
707
if (max != 0 && (val < min || val > max))
708
as_bad_where (fixP->fx_file, fixP->fx_line, _("offset out of range"));
710
if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
714
/* Put number into target byte order. */
717
md_number_to_chars (char * ptr, valueT use, int nbytes)
719
if (target_big_endian)
720
number_to_chars_bigendian (ptr, use, nbytes);
722
number_to_chars_littleendian (ptr, use, nbytes);
725
/* Convert from target byte order to host byte order. */
728
md_chars_to_number (char * buf, int n)
731
unsigned char * where = (unsigned char *) buf;
733
if (target_big_endian)
738
result |= (*where++ & 255);
746
result |= (where[n] & 255);
753
/* Generate a machine-dependent relocation. */
755
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
758
bfd_reloc_code_real_type code;
760
switch (fixP->fx_r_type)
763
code = fixP->fx_r_type;
765
case BFD_RELOC_MOXIE_10_PCREL:
766
code = fixP->fx_r_type;
769
as_bad_where (fixP->fx_file, fixP->fx_line,
770
_("Semantics error. This type of operand can not be relocated, it must be an assembly-time constant"));
774
relP = xmalloc (sizeof (arelent));
775
gas_assert (relP != 0);
776
relP->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
777
*relP->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
778
relP->address = fixP->fx_frag->fr_address + fixP->fx_where;
780
relP->addend = fixP->fx_offset;
782
/* This is the standard place for KLUDGEs to work around bugs in
783
bfd_install_relocation (first such note in the documentation
784
appears with binutils-2.8).
786
That function bfd_install_relocation does the wrong thing with
787
putting stuff into the addend of a reloc (it should stay out) for a
788
weak symbol. The really bad thing is that it adds the
789
"segment-relative offset" of the symbol into the reloc. In this
790
case, the reloc should instead be relative to the symbol with no
791
other offset than the assembly code shows; and since the symbol is
792
weak, any local definition should be ignored until link time (or
794
To wit: weaksym+42 should be weaksym+42 in the reloc,
795
not weaksym+(offset_from_segment_of_local_weaksym_definition)
797
To "work around" this, we subtract the segment-relative offset of
798
"known" weak symbols. This evens out the extra offset.
800
That happens for a.out but not for ELF, since for ELF,
801
bfd_install_relocation uses the "special function" field of the
802
howto, and does not execute the code that needs to be undone. */
804
if (OUTPUT_FLAVOR == bfd_target_aout_flavour
805
&& fixP->fx_addsy && S_IS_WEAK (fixP->fx_addsy)
806
&& ! bfd_is_und_section (S_GET_SEGMENT (fixP->fx_addsy)))
808
relP->addend -= S_GET_VALUE (fixP->fx_addsy);
811
relP->howto = bfd_reloc_type_lookup (stdoutput, code);
816
name = S_GET_NAME (fixP->fx_addsy);
818
name = _("<unknown>");
819
as_fatal (_("Cannot generate relocation type for symbol %s, code %s"),
820
name, bfd_get_reloc_code_name (code));
826
/* Decide from what point a pc-relative relocation is relative to,
827
relative to the pc-relative fixup. Er, relatively speaking. */
829
md_pcrel_from (fixS *fixP)
831
valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
833
switch (fixP->fx_r_type)
837
case BFD_RELOC_MOXIE_10_PCREL:
838
/* Offset is from the end of the instruction. */