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";
46
static valueT md_chars_to_number (char * buf, int n);
49
extern int target_big_endian;
50
const char *moxie_target_format = DEFAULT_TARGET_FORMAT;
53
md_operand (expressionS *op __attribute__((unused)))
58
/* This function is called once, at assembler startup time. It sets
59
up the hash table with all the opcodes in it, and also initializes
60
some aliases for compatibility with other assemblers. */
66
const moxie_opc_info_t *opcode;
67
opcode_hash_control = hash_new ();
69
/* Insert names into hash table. */
70
for (count = 0, opcode = moxie_form1_opc_info; count++ < 64; opcode++)
71
hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
73
for (count = 0, opcode = moxie_form2_opc_info; count++ < 4; opcode++)
74
hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
76
for (count = 0, opcode = moxie_form3_opc_info; count++ < 10; opcode++)
77
hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
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;
621
moxie_target_format = "elf32-bigmoxie";
624
target_big_endian = 0;
625
moxie_target_format = "elf32-littlemoxie";
635
md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
637
fprintf (stream, _("\
638
-EB assemble for a big endian system (default)\n\
639
-EL assemble for a little endian system\n"));
642
/* Apply a fixup to the object file. */
645
md_apply_fix (fixS *fixP ATTRIBUTE_UNUSED,
646
valueT * valP ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED)
648
char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
654
switch (fixP->fx_r_type)
657
if (target_big_endian)
675
if (target_big_endian)
692
case BFD_RELOC_MOXIE_10_PCREL:
695
if (val < -1024 || val > 1022)
696
as_bad_where (fixP->fx_file, fixP->fx_line,
697
_("pcrel too far BFD_RELOC_MOXIE_10"));
698
/* 11 bit offset even numbered, so we remove right bit. */
700
newval = md_chars_to_number (buf, 2);
701
newval |= val & 0x03ff;
702
md_number_to_chars (buf, newval, 2);
709
if (max != 0 && (val < min || val > max))
710
as_bad_where (fixP->fx_file, fixP->fx_line, _("offset out of range"));
712
if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
716
/* Put number into target byte order. */
719
md_number_to_chars (char * ptr, valueT use, int nbytes)
721
if (target_big_endian)
722
number_to_chars_bigendian (ptr, use, nbytes);
724
number_to_chars_littleendian (ptr, use, nbytes);
727
/* Convert from target byte order to host byte order. */
730
md_chars_to_number (char * buf, int n)
733
unsigned char * where = (unsigned char *) buf;
735
if (target_big_endian)
740
result |= (*where++ & 255);
748
result |= (where[n] & 255);
755
/* Generate a machine-dependent relocation. */
757
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
760
bfd_reloc_code_real_type code;
762
switch (fixP->fx_r_type)
765
code = fixP->fx_r_type;
767
case BFD_RELOC_MOXIE_10_PCREL:
768
code = fixP->fx_r_type;
771
as_bad_where (fixP->fx_file, fixP->fx_line,
772
_("Semantics error. This type of operand can not be relocated, it must be an assembly-time constant"));
776
relP = xmalloc (sizeof (arelent));
777
gas_assert (relP != 0);
778
relP->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
779
*relP->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
780
relP->address = fixP->fx_frag->fr_address + fixP->fx_where;
782
relP->addend = fixP->fx_offset;
784
/* This is the standard place for KLUDGEs to work around bugs in
785
bfd_install_relocation (first such note in the documentation
786
appears with binutils-2.8).
788
That function bfd_install_relocation does the wrong thing with
789
putting stuff into the addend of a reloc (it should stay out) for a
790
weak symbol. The really bad thing is that it adds the
791
"segment-relative offset" of the symbol into the reloc. In this
792
case, the reloc should instead be relative to the symbol with no
793
other offset than the assembly code shows; and since the symbol is
794
weak, any local definition should be ignored until link time (or
796
To wit: weaksym+42 should be weaksym+42 in the reloc,
797
not weaksym+(offset_from_segment_of_local_weaksym_definition)
799
To "work around" this, we subtract the segment-relative offset of
800
"known" weak symbols. This evens out the extra offset.
802
That happens for a.out but not for ELF, since for ELF,
803
bfd_install_relocation uses the "special function" field of the
804
howto, and does not execute the code that needs to be undone. */
806
if (OUTPUT_FLAVOR == bfd_target_aout_flavour
807
&& fixP->fx_addsy && S_IS_WEAK (fixP->fx_addsy)
808
&& ! bfd_is_und_section (S_GET_SEGMENT (fixP->fx_addsy)))
810
relP->addend -= S_GET_VALUE (fixP->fx_addsy);
813
relP->howto = bfd_reloc_type_lookup (stdoutput, code);
818
name = S_GET_NAME (fixP->fx_addsy);
820
name = _("<unknown>");
821
as_fatal (_("Cannot generate relocation type for symbol %s, code %s"),
822
name, bfd_get_reloc_code_name (code));
828
/* Decide from what point a pc-relative relocation is relative to,
829
relative to the pc-relative fixup. Er, relatively speaking. */
831
md_pcrel_from (fixS *fixP)
833
valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
835
switch (fixP->fx_r_type)
839
case BFD_RELOC_MOXIE_10_PCREL:
840
/* Offset is from the end of the instruction. */