/* tc-mcore.c -- Assemble code for M*Core
- Copyright 1999, 2000, 2001, 2002, 2003, 2005
- Free Software Foundation, Inc.
+ Copyright (C) 1999-2020 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
+ the Free Software Foundation; either version 3, or (at your option)
any later version.
GAS is distributed in the hope that it will be useful,
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
-#include <stdio.h>
#include "as.h"
-#include "bfd.h"
#include "subsegs.h"
#define DEFINE_TABLE
#include "../opcodes/mcore-opc.h"
#include "safe-ctype.h"
-#include <string.h>
#ifdef OBJ_ELF
#include "elf/mcore.h"
const char line_separator_chars[] = ";";
const char line_comment_chars[] = "#/";
-const int md_reloc_size = 8;
-
static int do_jsri2bsr = 0; /* Change here from 1 by Cruess 19 August 97. */
static int sifilter_mode = 0;
#define POOL_START_LABEL ".LS"
static void
-make_name (char * s, char * p, int n)
+make_name (char * s, const char * p, int n)
{
static const char hex[] = "0123456789ABCDEF";
kind == 2 means we just left a function
The dump_literals (1) call inserts a branch around the table, so
- we first look to see if its a situation where we won't have to
+ we first look to see if it's a situation where we won't have to
insert a branch (e.g., the previous instruction was an unconditional
branch).
occupy can be taken into account when deciding whether or not to
dump the current literal pool.
XXX - currently we do not cope with the .space and .dcb.d directives. */
- { "ascii", mcore_stringer, 0 },
- { "asciz", mcore_stringer, 1 },
+ { "ascii", mcore_stringer, 8 + 0 },
+ { "asciz", mcore_stringer, 8 + 1 },
{ "byte", mcore_cons, 1 },
{ "dc", mcore_cons, 2 },
{ "dc.b", mcore_cons, 1 },
{ "quad", mcore_cons, 8 },
{ "short", mcore_cons, 2 },
{ "single", mcore_float_cons, 'f'},
- { "string", mcore_stringer, 1 },
+ { "string", mcore_stringer, 8 + 1 },
{ "word", mcore_cons, 2 },
{ "fill", mcore_fill, 0 },
void
md_begin (void)
{
- const mcore_opcode_info * opcode;
- char * prev_name = "";
+ const char * prev_name = "";
+ unsigned int i;
opcode_hash_control = hash_new ();
/* Insert unique names into hash table. */
- for (opcode = mcore_table; opcode->name; opcode ++)
+ for (i = 0; i < ARRAY_SIZE (mcore_table); i++)
{
- if (! streq (prev_name, opcode->name))
+ if (! streq (prev_name, mcore_table[i].name))
{
- prev_name = opcode->name;
- hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
+ prev_name = mcore_table[i].name;
+ hash_insert (opcode_hash_control, mcore_table[i].name, (char *) &mcore_table[i]);
}
}
}
static struct Cregs
{
- char * name;
+ const char * name;
unsigned int crnum;
}
cregs[] =
char buf[10];
static struct psrmods
{
- char * name;
+ const char * name;
unsigned int value;
}
psrmods[] =
parse_exp (char * s, expressionS * e)
{
char * save;
- char * new;
+ char * new_pointer;
/* Skip whitespace. */
while (ISSPACE (* s))
if (e->X_op == O_absent)
as_bad (_("missing operand"));
- new = input_line_pointer;
+ new_pointer = input_line_pointer;
input_line_pointer = save;
- return new;
+ return new_pointer;
}
static int
unsigned min,
unsigned max)
{
- char * new;
+ char * new_pointer;
expressionS e;
- new = parse_exp (s, & e);
+ new_pointer = parse_exp (s, & e);
if (e.X_op == O_absent)
; /* An error message has already been emitted. */
* val = e.X_add_number;
- return new;
+ return new_pointer;
}
static char *
unsigned off;
unsigned isize;
expressionS e;
- char name[20];
+ char name[21];
/* Drop leading whitespace. */
while (ISSPACE (* str))
as_bad (_("M340 specific opcode used when assembling for M210"));
break;
}
- /* drop through... */
+ /* Fall through. */
case O2:
op_end = parse_reg (op_end + 1, & reg);
inst |= reg;
output[0] = INST_BYTE0 (inst);
output[1] = INST_BYTE1 (inst);
+#ifdef OBJ_ELF
+ dwarf2_emit_insn (2);
+#endif
check_literals (opcode->transfer, isize);
}
}
/* Various routines to kill one day. */
-/* Equal to MAX_PRECISION in atof-ieee.c. */
-#define MAX_LITTLENUMS 6
-
-/* Turn a string in input_line_pointer into a floating point constant of type
- type, and store the appropriate bytes in *litP. The number of LITTLENUMS
- emitted is stored in *sizeP. An error message is returned, or NULL on OK. */
-char *
-md_atof (int type, char * litP, int * sizeP)
+const char *
+md_atof (int type, char * litP, int * sizeP)
{
- int prec;
- LITTLENUM_TYPE words[MAX_LITTLENUMS];
- int i;
- char * t;
-
- switch (type)
- {
- case 'f':
- case 'F':
- case 's':
- case 'S':
- prec = 2;
- break;
-
- case 'd':
- case 'D':
- case 'r':
- case 'R':
- prec = 4;
- break;
-
- case 'x':
- case 'X':
- prec = 6;
- break;
-
- case 'p':
- case 'P':
- prec = 6;
- break;
-
- default:
- *sizeP = 0;
- return _("Bad call to MD_NTOF()");
- }
-
- t = atof_ieee (input_line_pointer, type, words);
-
- if (t)
- input_line_pointer = t;
-
- *sizeP = prec * sizeof (LITTLENUM_TYPE);
-
- if (! target_big_endian)
- {
- for (i = prec - 1; i >= 0; i--)
- {
- md_number_to_chars (litP, (valueT) words[i],
- sizeof (LITTLENUM_TYPE));
- litP += sizeof (LITTLENUM_TYPE);
- }
- }
- else
- for (i = 0; i < prec; i++)
- {
- md_number_to_chars (litP, (valueT) words[i],
- sizeof (LITTLENUM_TYPE));
- litP += sizeof (LITTLENUM_TYPE);
- }
-
- return 0;
+ return ieee_md_atof (type, litP, sizeP, target_big_endian);
}
\f
const char * md_shortopts = "";
size_t md_longopts_size = sizeof (md_longopts);
int
-md_parse_option (int c, char * arg)
+md_parse_option (int c, const char * arg)
{
switch (c)
{
case C (COND_JUMP, DISP32):
case C (COND_JUMP, UNDEF_WORD_DISP):
{
- /* A conditional branch wont fit into 12 bits so:
+ /* A conditional branch won't fit into 12 bits so:
b!cond 1f
jmpi 0f
.align 2
0: .long disp
1:
-
+
If the b!cond is 4 byte aligned, the literal which would
go at x+4 will also be aligned. */
int first_inst = fragP->fr_fix + fragP->fr_address;
segT segment ATTRIBUTE_UNUSED)
{
char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
- char * file = fixP->fx_file ? fixP->fx_file : _("unknown");
+ const char * file = fixP->fx_file ? fixP->fx_file : _("unknown");
const char * symname;
/* Note: use offsetT because it is signed, valueT is unsigned. */
offsetT val = *valP;
case BFD_RELOC_MCORE_PCREL_IMM11BY2:
if ((val & 1) != 0)
as_bad_where (file, fixP->fx_line,
- _("odd distance branch (0x%lx bytes)"), (long) val);
+ ngettext ("odd distance branch (0x%lx byte)",
+ "odd distance branch (0x%lx bytes)",
+ (long) val),
+ (long) val);
val /= 2;
if (((val & ~0x3ff) != 0) && ((val | 0x3ff) != -1))
as_bad_where (file, fixP->fx_line,
case BFD_RELOC_MCORE_PCREL_JSR_IMM11BY2:
/* Conditional linker map jsri to bsr. */
- /* If its a local target and close enough, fix it.
+ /* If it's a local target and close enough, fix it.
NB: >= -2k for backwards bsr; < 2k for forwards... */
if (fixP->fx_addsy == 0 && val >= -2048 && val < 2048)
{
void
md_operand (expressionS * expressionP)
{
- /* Ignore leading hash symbol, if poresent. */
+ /* Ignore leading hash symbol, if present. */
if (* input_line_pointer == '#')
{
input_line_pointer ++;
sized - maybe it will fix up */
fragP->fr_subtype = C (COND_JUMP, DISP12);
else if (fragP->fr_symbol)
- /* Its got a segment, but its not ours, so it will always be long. */
+ /* It's got a segment, but it's not ours, so it will always be long. */
fragP->fr_subtype = C (COND_JUMP, UNDEF_WORD_DISP);
else
/* We know the abs value. */
void
md_number_to_chars (char * ptr, valueT use, int nbytes)
{
- if (! target_big_endian)
- switch (nbytes)
- {
- case 4: ptr[3] = (use >> 24) & 0xff; /* Fall through. */
- case 3: ptr[2] = (use >> 16) & 0xff; /* Fall through. */
- case 2: ptr[1] = (use >> 8) & 0xff; /* Fall through. */
- case 1: ptr[0] = (use >> 0) & 0xff; break;
- default: abort ();
- }
+ if (target_big_endian)
+ number_to_chars_bigendian (ptr, use, nbytes);
else
- switch (nbytes)
- {
- case 4: *ptr++ = (use >> 24) & 0xff; /* Fall through. */
- case 3: *ptr++ = (use >> 16) & 0xff; /* Fall through. */
- case 2: *ptr++ = (use >> 8) & 0xff; /* Fall through. */
- case 1: *ptr++ = (use >> 0) & 0xff; break;
- default: abort ();
- }
+ number_to_chars_littleendian (ptr, use, nbytes);
}
/* Round up a section size to the appropriate boundary. */
|| (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
{
- assert (fixp->fx_size == 2); /* must be an insn */
+ gas_assert (fixp->fx_size == 2); /* must be an insn */
return fixp->fx_size;
}
#endif
code = fixp->fx_r_type;
as_bad (_("Can not do %d byte %srelocation"),
fixp->fx_size,
- fixp->fx_pcrel ? _("pc-relative") : "");
+ fixp->fx_pcrel ? _("pc-relative ") : "");
}
break;
}
- rel = xmalloc (sizeof (arelent));
- rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+ rel = XNEW (arelent);
+ rel->sym_ptr_ptr = XNEW (asymbol *);
*rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
/* Always pass the addend along! */
/* Set howto to a garbage value so that we can keep going. */
rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
- assert (rel->howto != NULL);
+ gas_assert (rel->howto != NULL);
}
return rel;