/* tc-i960.c - All the i80960-specific stuff
- Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2005, 2006
- Free Software Foundation, Inc.
+ Copyright (C) 1989-2017 Free Software Foundation, Inc.
This file is part of GAS.
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,
#include "as.h"
#include "safe-ctype.h"
-#include "obstack.h"
#include "opcode/i960.h"
operands. */
static const struct
{
- char *reg_name;
+ const char *reg_name;
int reg_num;
}
regnames[] =
'abase' (indirect addressing) registers. */
static const struct
{
- char *areg_name;
+ const char *areg_name;
int areg_num;
}
aregs[] =
of branches taken/not-taken for later input to a utility that will
set the branch prediction bits of the instructions in accordance with
the behavior observed. (Note that the KX series does not have
- brach-prediction.)
+ branch-prediction.)
The instrumentation consists of:
/* Name of the table of pointers to branches. A local (i.e.,
non-external) symbol. */
-static void ctrl_fmt (char *, long, int);
+static void ctrl_fmt (const char *, long, int);
\f
void
string is not consumed in the evaluation -- tolerate no dangling junk! */
static void
-parse_expr (char *textP, /* Text of expression to be parsed. */
+parse_expr (const char *textP, /* Text of expression to be parsed. */
expressionS *expP) /* Where to put the results of parsing. */
{
char *save_in; /* Save global here. */
else
{
save_in = input_line_pointer; /* Save global. */
- input_line_pointer = textP; /* Make parser work for us. */
+ input_line_pointer = (char *) textP; /* Make parser work for us. */
(void) expression (expP);
if ((size_t) (input_line_pointer - textP) != strlen (textP))
address displacement is greater than 13 bits. */
static void
-get_cdisp (char *dispP, /* Displacement as specified in source instruction. */
- char *ifmtP, /* "COBR" or "CTRL" (for use in error message). */
+get_cdisp (const char *dispP, /* Displacement as specified in source instruction. */
+ const char *ifmtP, /* "COBR" or "CTRL" (for use in error message). */
long instr, /* Instruction needing the displacement. */
int numbits, /* # bits of displacement (13 for COBR, 24 for CTRL). */
int var_frag,/* 1 if varying length code fragment should be emitted;
0 if an address fix should be emitted. */
- int callj) /* 1 if callj relocation should be done; else 0. */
+ int callj) /* 1 if callj relocation should be done; else 0. */
{
expressionS e; /* Parsed expression. */
fixS *fixP; /* Structure describing needed address fix. */
{
case O_illegal:
as_bad (_("expression syntax error"));
+ break;
case O_symbol:
if (S_GET_SEGMENT (e.X_add_symbol) == now_seg
}
/* get_ispec: parse a memory operand for an index specification
-
+
Here, an "index specification" is taken to be anything surrounded
by square brackets and NOT followed by anything else.
static char *
get_ispec (char *textP) /* Pointer to memory operand from source instruction, no white space. */
-
+
{
/* Points to start of index specification. */
char *start;
regnum = *intP;
*p = '\0'; /* Discard register spec. */
if (regnum == IPREL)
- /* We have to specialcase ip-rel mode. */
+ /* We have to special-case ip-rel mode. */
iprel_flag = 1;
else
{
case I_BIT:
/* Treat missing displacement as displacement of 0. */
mode |= D_BIT;
- /* Fall into next case. */
+ /* Fall through. */
case D_BIT | A_BIT | I_BIT:
case D_BIT | I_BIT:
/* Set MEMB bit in mode, and OR in mode bits. */
char opdesc; /* Operand descriptor byte. */
memS instr; /* Description of binary to be output. */
char *outP; /* Where the binary was output to. */
- expressionS expr; /* Parsed expression. */
+ expressionS exp; /* Parsed expression. */
/* ->description of deferred address fixup. */
fixS *fixP;
/* Parse the displacement; this must be done before emitting the
opcode, in case it is an expression using `.'. */
- parse_expr (instr.e, &expr);
+ parse_expr (instr.e, &exp);
/* Output opcode. */
outP = emit (instr.opcode);
return;
/* Process the displacement. */
- switch (expr.X_op)
+ switch (exp.X_op)
{
case O_illegal:
as_bad (_("expression syntax error"));
case O_constant:
if (instr.disp == 32)
- (void) emit (offs (expr)); /* Output displacement. */
+ (void) emit (offs (exp)); /* Output displacement. */
else
{
/* 12-bit displacement. */
- if (offs (expr) & ~0xfff)
+ if (offs (exp) & ~0xfff)
{
/* Won't fit in 12 bits: convert already-output
instruction to MEMB format, output
displacement. */
mema_to_memb (outP);
- (void) emit (offs (expr));
+ (void) emit (offs (exp));
}
else
{
/* WILL fit in 12 bits: OR into opcode and
overwrite the binary we already put out. */
- instr.opcode |= offs (expr);
+ instr.opcode |= offs (exp);
md_number_to_chars (outP, instr.opcode, 4);
}
}
outP = emit ((long) 0);
fixP = fix_new_exp (frag_now,
outP - frag_now->fr_literal,
- 4, & expr, 0, NO_RELOC);
+ 4, &exp, 0, NO_RELOC);
/* Steve's linker relaxing hack. Mark this 32-bit relocation as
being in the instruction stream, specifically as part of a callx
instruction. */
{
default:
/* We're dependent on one or more symbols -- use "lda". */
- arg[0] = "lda";
+ arg[0] = (char *) "lda";
break;
case O_constant:
ldconst 64,<reg> -> shlo 8,3,<reg>
ldconst -1,<reg> -> subo 1,0,<reg>
ldconst -31,<reg> -> subo 31,0,<reg>
-
+
Anything else becomes:
lda xxx,<reg>. */
n = offs (e);
if ((0 <= n) && (n <= 31))
- arg[0] = "mov";
+ arg[0] = (char *) "mov";
else if ((-31 <= n) && (n <= -1))
{
- arg[0] = "subo";
+ arg[0] = (char *) "subo";
arg[3] = arg[2];
sprintf (buf, "%d", -n);
arg[1] = buf;
- arg[2] = "0";
+ arg[2] = (char *) "0";
}
else if ((32 <= n) && (n <= 62))
{
- arg[0] = "addo";
+ arg[0] = (char *) "addo";
arg[3] = arg[2];
- arg[1] = "31";
+ arg[1] = (char *) "31";
sprintf (buf, "%d", n - 31);
arg[2] = buf;
}
else if ((shift = shift_ok (n)) != 0)
{
- arg[0] = "shlo";
+ arg[0] = (char *) "shlo";
arg[3] = arg[2];
sprintf (buf, "%d", shift);
arg[1] = buf;
arg[2] = buf2;
}
else
- arg[0] = "lda";
+ arg[0] = (char *) "lda";
break;
case O_illegal:
n = 1;
args[1] = p;
- /* Squeze blanks out by moving non-blanks toward start of string.
+ /* Squeeze blanks out by moving non-blanks toward start of string.
Isolate operands, whenever comma is found. */
to = p;
while (*p != '\0')
}
static void
-ctrl_fmt (char *targP, /* Pointer to text of lone operand (if any). */
+ctrl_fmt (const char *targP, /* Pointer to text of lone operand (if any). */
long opcode, /* Template of instruction. */
int num_ops) /* Number of operands. */
{
if (!oP || !targ_has_iclass (oP->iclass))
as_bad (_("invalid opcode, \"%s\"."), args[0]);
else if (n_ops != oP->num_ops)
- as_bad (_("improper number of operands. expecting %d, got %d"),
+ as_bad (_("improper number of operands. Expecting %d, got %d"),
oP->num_ops, n_ops);
else
{
break;
case REG:
if (branch_predict)
- as_warn (bp_error_msg);
+ as_warn ("%s", bp_error_msg);
reg_fmt (args, oP);
break;
case MEM1:
if (args[0][0] == 'c' && args[0][1] == 'a')
{
if (branch_predict)
- as_warn (bp_error_msg);
+ as_warn ("%s", bp_error_msg);
mem_fmt (args, oP, 1);
break;
}
+ /* Fall through. */
case MEM2:
case MEM4:
case MEM8:
case MEM12:
case MEM16:
if (branch_predict)
- as_warn (bp_error_msg);
+ as_warn ("%s", bp_error_msg);
mem_fmt (args, oP, 0);
break;
case CALLJ:
if (branch_predict)
- as_warn (bp_error_msg);
+ as_warn ("%s", bp_error_msg);
/* Output opcode & set up "fixup" (relocation); flag
relocation as 'callj' type. */
know (oP->num_ops == 1);
number_to_chars_littleendian (buf, value, n);
}
-#define MAX_LITTLENUMS 6
-#define LNUM_SIZE sizeof (LITTLENUM_TYPE)
-
-/* md_atof: convert ascii to floating point
-
- Turn a string at input_line_pointer into a floating point constant of type
- 'type', and store the appropriate bytes at *litP. The number of LITTLENUMS
- emitted is returned at 'sizeP'. An error message is returned, or a pointer
- to an empty message if OK.
-
- Note we call the i386 floating point routine, rather than complicating
- things with more files or symbolic links. */
-
-char *
+const char *
md_atof (int type, char *litP, int *sizeP)
{
- LITTLENUM_TYPE words[MAX_LITTLENUMS];
- LITTLENUM_TYPE *wordP;
- int prec;
- char *t;
-
- switch (type)
- {
- case 'f':
- case 'F':
- prec = 2;
- break;
-
- case 'd':
- case 'D':
- prec = 4;
- break;
-
- case 't':
- case 'T':
- prec = 5;
- type = 'x'; /* That's what atof_ieee() understands. */
- break;
-
- default:
- *sizeP = 0;
- return _("Bad call to md_atof()");
- }
-
- t = atof_ieee (input_line_pointer, type, words);
- if (t)
- input_line_pointer = t;
-
- *sizeP = prec * LNUM_SIZE;
-
- /* Output the LITTLENUMs in REVERSE order in accord with i80960
- word-order. (Dunno why atof_ieee doesn't do it in the right
- order in the first place -- probably because it's a hack of
- atof_m68k.) */
- for (wordP = words + prec - 1; prec--;)
- {
- md_number_to_chars (litP, (long) (*wordP--), LNUM_SIZE);
- litP += sizeof (LITTLENUM_TYPE);
- }
-
- return 0;
+ return ieee_md_atof (type, litP, sizeP, FALSE);
}
static void
{
/* Put bit field into instruction and write back in target
* byte order. */
- val &= ~(-1 << (int) numbits); /* Clear unused sign bits. */
+ val &= ~(-(1 << (int) numbits)); /* Clear unused sign bits. */
instr |= val;
md_number_to_chars (instrP, instr, 4);
}
struct tabentry
{
- char *flag;
+ const char *flag;
int arch;
};
static const struct tabentry arch_tab[] =
};
int
-md_parse_option (int c, char *arg)
+md_parse_option (int c, const char *arg)
{
switch (c)
{
case 'A':
{
const struct tabentry *tp;
- char *p = arg;
+ const char *p = arg;
for (tp = arch_tab; tp->flag != NULL; tp++)
if (!strcmp (p, tp->flag))
char buf[20];
/* Where the binary was output to. */
char *p;
- /* Pointer to description of deferred address fixup. */
- fixS *fixP;
if (!instrument_branches)
return;
{
sprintf (buf, "%s%d", BR_LABEL_BASE, i);
p = emit (0);
- fixP = fix_new (frag_now,
- p - frag_now->fr_literal,
- 4, symbol_find (buf), 0, 0, NO_RELOC);
+ fix_new (frag_now,
+ p - frag_now->fr_literal,
+ 4, symbol_find (buf), 0, 0, NO_RELOC);
}
}
passed fixup structure. */
int
-reloc_callj (fixS *fixP) /* Relocation that can be done at assembly time. */
+reloc_callj (fixS *fixP) /* Relocation that can be done at assembly time. */
{
/* Points to the binary for the instruction being relocated. */
char *where;
char *name;
char c;
- name = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (&name);
if (strcasecmp (name, "little") == 0)
;
else if (strcasecmp (name, "big") == 0)
else
as_warn (_("ignoring unrecognized .endian type `%s'"), name);
- *input_line_pointer = c;
+ (void) restore_line_pointer (c);
demand_empty_rest_of_line ();
}
int align;
align = bfd_get_section_alignment (stdoutput, seg);
- return (addr + (1 << align) - 1) & (-1 << align);
+ return (addr + (1 << align) - 1) & -(1 << align);
}
extern int coff_flags;
{
arelent * reloc;
- reloc = xmalloc (sizeof (arelent));
+ reloc = XNEW (arelent);
/* HACK: Is this right? */
fixP->fx_r_type = tc_bfd_fix2rtype (fixP);
if (reloc->howto == NULL)
{
as_bad_where (fixP->fx_file, fixP->fx_line,
- "internal error: can't export reloc type %d (`%s')",
+ _("internal error: can't export reloc type %d (`%s')"),
fixP->fx_r_type,
bfd_get_reloc_code_name (fixP->fx_r_type));
return NULL;
}
- assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
+ gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
- reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+ reloc->sym_ptr_ptr = XNEW (asymbol *);
*reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
reloc->addend = fixP->fx_addnumber;