/* tc-i370.c -- Assembler for the IBM 360/370/390 instruction set.
Loosely based on the ppc files by Linas Vepstas <linas@linas.org> 1998, 99
- Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 1994-2017 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
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,
similarities between HLASM and the MRI assemblers, such as section
names, lack of leading . in pseudo-ops, DC and DS, etc. */
-#include <stdio.h>
#include "as.h"
#include "safe-ctype.h"
#include "subsegs.h"
/* Structure to hold information about predefined registers. */
struct pd_reg
{
- char *name;
+ const char *name;
int value;
};
reg_number = get_single_number ();
else
{
- c = get_symbol_end ();
+ c = get_symbol_name (&name);
reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT, name);
/* Put back the delimiting char. */
- *input_line_pointer = c;
+ (void) restore_line_pointer (c);
}
/* If numeric, make sure its not out of bounds. */
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)
{
#endif
else
{
- as_bad ("invalid switch -m%s", arg);
+ as_bad (_("invalid switch -m%s"), arg);
return 0;
}
break;
retval = hash_insert (i370_hash, op->name, (void *) op);
if (retval != (const char *) NULL)
{
- as_bad ("Internal assembler error for instruction %s", op->name);
+ as_bad (_("Internal assembler error for instruction %s"), op->name);
dup_insn = TRUE;
}
}
retval = hash_insert (i370_macro_hash, macro->name, (void *) macro);
if (retval != (const char *) NULL)
{
- as_bad ("Internal assembler error for macro %s", macro->name);
+ as_bad (_("Internal assembler error for macro %s"), macro->name);
dup_insn = TRUE;
}
}
{
struct map_bfd
{
- char *string;
+ const char *string;
int length;
bfd_reloc_code_real_type reloc;
};
|| ptr->reloc == BFD_RELOC_LO16_GOTOFF
|| ptr->reloc == BFD_RELOC_HI16_GOTOFF
|| ptr->reloc == BFD_RELOC_HI16_S_GOTOFF))
- as_warn ("identifier+constant@got means identifier@got+constant");
+ as_warn (_("identifier+constant@got means identifier@got+constant"));
/* Now check for identifier@suffix+constant */
if (*str == '-' || *str == '+')
int size = bfd_get_reloc_size (reloc_howto);
if (size > nbytes)
- as_bad ("%s relocations do not fit in %d bytes\n", reloc_howto->name, nbytes);
+ as_bad (_("%s relocations do not fit in %d bytes\n"),
+ reloc_howto->name, nbytes);
else
{
char *p = frag_more ((int) nbytes);
int nbytes=0;
expressionS exp;
char type=0;
+ char * clse;
if (is_it_end_of_statement ())
{
nbytes = 8;
break;
default:
- as_bad ("unsupported DC type");
+ as_bad (_("unsupported DC type"));
return;
}
/* Get rid of pesky quotes. */
if ('\'' == *input_line_pointer)
{
- char * close;
-
++input_line_pointer;
- close = strchr (input_line_pointer, '\'');
- if (close)
- *close= ' ';
+ clse = strchr (input_line_pointer, '\'');
+ if (clse)
+ *clse= ' ';
else
- as_bad ("missing end-quote");
+ as_bad (_("missing end-quote"));
}
if ('\"' == *input_line_pointer)
{
- char * close;
-
++input_line_pointer;
- close = strchr (input_line_pointer, '\"');
- if (close)
- *close= ' ';
+ clse = strchr (input_line_pointer, '\"');
+ if (clse)
+ *clse= ' ';
else
- as_bad ("missing end-quote");
+ as_bad (_("missing end-quote"));
}
switch (type)
emit_expr (&exp, nbytes);
break;
case 'E': /* 32-bit */
+ type = 'f';
+ /* Fall through. */
case 'D': /* 64-bit */
md_atof (type, tmp, &nbytes);
p = frag_more (nbytes);
memcpy (p, tmp, nbytes);
break;
default:
- as_bad ("unsupported DC type");
+ as_bad (_("unsupported DC type"));
return;
}
alignment = 3;
break;
default:
- as_bad ("unsupported alignment");
+ as_bad (_("unsupported alignment"));
return;
}
frag_align (alignment, 0, 0);
record_alignment (now_seg, alignment);
}
else
- as_bad ("this DS form not yet supported");
+ as_bad (_("this DS form not yet supported"));
}
/* Solaris pseudo op to change to the .rodata section. */
char *pfrag;
int align2;
- name = input_line_pointer;
- c = get_symbol_end ();
+ c = get_symbol_name (&name);
/* Just after name is now '\0'. */
p = input_line_pointer;
- *p = c;
+ (void) restore_line_pointer (c);
SKIP_WHITESPACE ();
if (*input_line_pointer != ',')
{
- as_bad ("Expected comma after symbol-name: rest of line ignored.");
+ as_bad (_("Expected comma after symbol-name: rest of line ignored."));
ignore_rest_of_line ();
return;
}
input_line_pointer++;
if ((size = get_absolute_expression ()) < 0)
{
- as_warn (".COMMon length (%ld.) <0! Ignored.", (long) size);
+ as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size);
ignore_rest_of_line ();
return;
}
align = get_absolute_expression ();
if (align <= 0)
{
- as_warn ("ignoring bad alignment");
+ as_warn (_("ignoring bad alignment"));
align = 8;
}
}
if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
{
- as_bad ("Ignoring attempt to re-define symbol `%s'.",
+ as_bad (_("Ignoring attempt to re-define symbol `%s'."),
S_GET_NAME (symbolP));
ignore_rest_of_line ();
return;
if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
{
- as_bad ("Length of .lcomm \"%s\" is already %ld. Not changed to %ld.",
+ as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
S_GET_NAME (symbolP),
(long) S_GET_VALUE (symbolP),
(long) size);
;
if (align != 1)
{
- as_bad ("Common alignment not a power of 2");
+ as_bad (_("Common alignment not a power of 2"));
ignore_rest_of_line ();
return;
}
waste space padding out to alignments. The four pointers
longlong_poolP, word_poolP, etc. point to a symbol labeling the
start of each pool part.
-
+
lit_pool_num increments from zero to infinity and uniquely id's
-- its used to generate the *_poolP symbol name. */
exx->X_add_number += baseaddr->X_add_number;
}
else
- as_bad ("Missing or bad .using directive");
+ as_bad (_("Missing or bad .using directive"));
}
/* Add an expression to the literal pool. */
if (lit_count == next_literal_pool_place) /* new entry */
{
if (next_literal_pool_place > MAX_LITERAL_POOL_SIZE)
- as_bad ("Literal Pool Overflow");
+ as_bad (_("Literal Pool Overflow"));
literals[next_literal_pool_place].exp = *exx;
literals[next_literal_pool_place].size = sz;
}
/* i370_addr_offset() will convert operand expressions
- that appear to be absolute into thier base-register
+ that appear to be absolute into their base-register
relative form. These expressions come in two types:
(1) of the form "* + const" * where "*" means
expression (exp);
/* We use a simple string name to collapse together
- multiple refrences to the same address literal. */
+ multiple references to the same address literal. */
name_len = strcspn (sym_name, ", ");
delim = *(sym_name + name_len);
*(sym_name + name_len) = 0x0;
/* Get rid of pesky quotes. */
if ('\'' == *input_line_pointer)
{
- char * close;
+ char * clse;
+
++input_line_pointer;
- close = strchr (input_line_pointer, '\'');
- if (close)
- *close= ' ';
+ clse = strchr (input_line_pointer, '\'');
+ if (clse)
+ *clse= ' ';
else
- as_bad ("missing end-quote");
+ as_bad (_("missing end-quote"));
}
if ('\"' == *input_line_pointer)
{
- char * close;
+ char * clse;
+
++input_line_pointer;
- close = strchr (input_line_pointer, '\"');
- if (close)
- *close= ' ';
+ clse = strchr (input_line_pointer, '\"');
+ if (clse)
+ *clse= ' ';
else
- as_bad ("missing end-quote");
+ as_bad (_("missing end-quote"));
}
if (('X' == name[0]) || ('E' == name[0]) || ('D' == name[0]))
{
/* O_big occurs when more than 4 bytes worth gets parsed. */
if ((exp->X_op != O_constant) && (exp->X_op != O_big))
{
- as_bad ("expression not a constant");
+ as_bad (_("expression not a constant"));
return FALSE;
}
add_to_lit_pool (exp, 0x0, cons_len);
break;
default:
- as_bad ("Unknown/unsupported address literal type");
+ as_bad (_("Unknown/unsupported address literal type"));
return FALSE;
}
if (strncmp (now_seg->name, ".text", 5))
{
if (i370_other_section == undefined_section)
- as_bad (".ltorg without prior .using in section %s",
+ as_bad (_(".ltorg without prior .using in section %s"),
now_seg->name);
if (i370_other_section != now_seg)
- as_bad (".ltorg in section %s paired to .using in section %s",
+ as_bad (_(".ltorg in section %s paired to .using in section %s"),
now_seg->name, i370_other_section->name);
}
else if (2 == biggest_literal_size) biggest_align = 1;
else if (4 == biggest_literal_size) biggest_align = 2;
else if (8 == biggest_literal_size) biggest_align = 3;
- else as_bad ("bad alignment of %d bytes in literal pool", biggest_literal_size);
+ else as_bad (_("bad alignment of %d bytes in literal pool"), biggest_literal_size);
if (0 == biggest_align) biggest_align = 1;
/* Align pool for short, word, double word accesses. */
case 1:
current_poolP = byte_poolP; break;
default:
- as_bad ("bad literal size\n");
+ as_bad (_("bad literal size\n"));
}
if (NULL == current_poolP)
continue;
if (O_constant != baseaddr.X_op
&& O_symbol != baseaddr.X_op
&& O_uminus != baseaddr.X_op)
- as_bad (".using: base address expression illegal or too complex");
+ as_bad (_(".using: base address expression illegal or too complex"));
if (*input_line_pointer != '\0') ++input_line_pointer;
if (0 == strncmp (now_seg->name, ".text", 5))
{
if (iregno != i370_using_text_regno)
- as_bad ("droping register %d in section %s does not match using register %d",
+ as_bad (_("droping register %d in section %s does not match using register %d"),
iregno, now_seg->name, i370_using_text_regno);
i370_using_text_regno = -1;
else
{
if (iregno != i370_using_other_regno)
- as_bad ("droping register %d in section %s does not match using register %d",
+ as_bad (_("droping register %d in section %s does not match using register %d"),
iregno, now_seg->name, i370_using_other_regno);
if (i370_other_section != now_seg)
- as_bad ("droping register %d in section %s previously used in section %s",
+ as_bad (_("droping register %d in section %s previously used in section %s"),
iregno, now_seg->name, i370_other_section->name);
i370_using_other_regno = -1;
if (count != macro->operands)
{
- as_bad ("wrong number of operands");
+ as_bad (_("wrong number of operands"));
return;
}
}
/* Put the string together. */
- complete = s = alloca (len + 1);
+ complete = s = XNEWVEC (char, len + 1);
format = macro->format;
while (*format != '\0')
{
/* Assemble the constructed instruction. */
md_assemble (complete);
+ free (complete);
}
/* This routine is called for each instruction to be assembled. */
void
md_assemble (char *str)
{
- char *s, *opcode_str;
+ char *s;
const struct i370_opcode *opcode;
i370_insn_t insn;
const unsigned char *opindex_ptr;
;
if (*s != '\0')
*s++ = '\0';
- opcode_str = str;
/* Look up the opcode in the hash table. */
opcode = (const struct i370_opcode *) hash_find (i370_hash, str);
{
const struct i370_macro *macro;
- assert (i370_macro_hash);
+ gas_assert (i370_macro_hash);
macro = (const struct i370_macro *) hash_find (i370_macro_hash, str);
if (macro == (const struct i370_macro *) NULL)
- as_bad ("Unrecognized opcode: `%s'", str);
+ as_bad (_("Unrecognized opcode: `%s'"), str);
else
i370_macro (s, macro);
for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++)
{
const struct i370_operand *operand;
- const char *errmsg;
char *hold;
expressionS ex;
operand = &i370_operands[*opindex_ptr];
- errmsg = NULL;
/* If this is an index operand, and we are skipping it,
just insert a zero. */
basereg = i370_using_other_regno;
}
if (0 > basereg)
- as_bad ("not using any base register");
+ as_bad (_("not using any base register"));
insn = i370_insert_operand (insn, operand, basereg);
continue;
}
if (! register_name (&ex))
- as_bad ("expecting a register for operand %d",
+ as_bad (_("expecting a register for operand %d"),
(int) (opindex_ptr - opcode->operands + 1));
}
ex.X_add_number --;
if (ex.X_op == O_illegal)
- as_bad ("illegal operand");
+ as_bad (_("illegal operand"));
else if (ex.X_op == O_absent)
- as_bad ("missing operand");
+ as_bad (_("missing operand"));
else if (ex.X_op == O_register)
insn = i370_insert_operand (insn, operand, ex.X_add_number);
else if (ex.X_op == O_constant)
++str;
if (*str != '\0')
- as_bad ("junk at end of line: `%s'", str);
+ as_bad (_("junk at end of line: `%s'"), str);
/* Write out the instruction. */
f = frag_more (opcode->len);
else
{
/* Not used --- don't have any 8 byte instructions. */
- as_bad ("Internal Error: bad instruction length");
+ as_bad (_("Internal Error: bad instruction length"));
md_number_to_chars ((f + 4), insn.i[1], opcode->len -4);
}
}
}
}
\f
-/* 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 *
+const char *
md_atof (int type, char *litp, int *sizep)
{
- int prec;
- LITTLENUM_TYPE words[4];
- char *t;
- int i;
-
- switch (type)
- {
- case 'f':
- case 'E':
- type = 'f';
- prec = 2;
- break;
-
- case 'd':
- case 'D':
- type = 'd';
- prec = 4;
- break;
-
- default:
- *sizep = 0;
- return "bad call to md_atof";
- }
-
/* 360/370/390 have two float formats: an old, funky 360 single-precision
- * format, and the ieee format. Support only the ieee format. */
- t = atof_ieee (input_line_pointer, type, words);
- if (t)
- input_line_pointer = t;
-
- *sizep = prec * 2;
-
- for (i = 0; i < prec; i++)
- {
- md_number_to_chars (litp, (valueT) words[i], 2);
- litp += 2;
- }
-
- return NULL;
+ format, and the ieee format. Support only the ieee format. */
+ return ieee_md_atof (type, litp, sizep, TRUE);
}
/* Write a value out to the object file, using the appropriate
{
int align = bfd_get_section_alignment (stdoutput, seg);
- return (addr + (1 << align) - 1) & (-1 << align);
+ return (addr + (1 << align) - 1) & -(1 << align);
}
/* We don't have any form of relaxing. */
any operands that need relocation. Due to the 12-bit naturew of
i370 addressing, this would be unusual. */
{
- char *sfile;
+ const char *sfile;
unsigned int sline;
/* Use expr_symbol_where to see if this is an expression
{
arelent *reloc;
- reloc = xmalloc (sizeof (arelent));
+ reloc = XNEW (arelent);
- 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->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
{ NULL, NULL, 0 }
};
-