/* Altera Nios II assembler.
- Copyright (C) 2012-2015 Free Software Foundation, Inc.
+ Copyright (C) 2012-2016 Free Software Foundation, Inc.
Contributed by Nigel Gray (ngray@altera.com).
Contributed by Mentor Graphics, Inc.
do not generate warnings. */
bfd_boolean noat;
- /* .set nobreak -> nobreak = 1 allows assembly code to use ba,bt without
+ /* .set nobreak -> nobreak = 1 allows assembly code to use ba,bt without
warning.
.set break -> nobreak = 0, assembly code using ba,bt warns. */
bfd_boolean nobreak;
/* Constant bits masked into insn_code for self-check mode. */
unsigned long constant_bits;
-
+
/* Pointer to the relevant bit of the opcode table. */
const struct nios2_opcode *insn_nios2_opcode;
/* After parsing ptrs to the tokens in the instruction fill this array
static void
s_nios2_set (int equiv)
{
- char *directive = input_line_pointer;
- char delim = get_symbol_end ();
+ char *save = input_line_pointer;
+ char *directive;
+ char delim = get_symbol_name (&directive);
char *endline = input_line_pointer;
- *endline = delim;
+
+ (void) restore_line_pointer (delim);
/* We only want to handle ".set XXX" if the
user has tried ".set XXX, YYY" they are not
trying a directive. This prevents
us from polluting the name space. */
SKIP_WHITESPACE ();
- if (is_end_of_line[(unsigned char) *input_line_pointer])
+ if (is_end_of_line[(unsigned char) *input_line_pointer])
{
bfd_boolean done = TRUE;
*endline = 0;
-
+
if (!strcmp (directive, "noat"))
nios2_as_options.noat = TRUE;
else if (!strcmp (directive, "at"))
nios2_as_options.relax = relax_all;
else
done = FALSE;
-
+
if (done)
{
*endline = delim;
}
/* If we fall through to here, either we have ".set XXX, YYY"
- or we have ".set XXX" where XXX is unknown or we have
+ or we have ".set XXX" where XXX is unknown or we have
a syntax error. */
- input_line_pointer = directive;
- *endline = delim;
+ input_line_pointer = save;
s_set (equiv);
}
Nios II PC-relative branch instructions only support 16-bit offsets.
And, there's no good way to add a 32-bit constant to the PC without
using two registers.
-
+
To deal with this, for the pc-relative relaxation mode we convert
br label
into a series of 16-bit adds, like:
16-bit CDX branch instructions are relaxed first into equivalent
32-bit branches and then the above transformations are applied
- if necessary.
+ if necessary.
*/
md_number_to_chars (buffer, op, 4);
fragp->fr_fix += 4;
buffer += 4;
-
+
/* We need to know whether the offset is positive or negative. */
target += S_GET_VALUE (symbolp);
offset = target - fragp->fr_address - fragp->fr_fix;
= ((fixP->fx_frag->fr_address + fixP->fx_where) & 0xf0000000);
range_max = range_min + 0x0fffffff;
address = fixup | range_min;
-
+
as_bad_where (fixP->fx_file, fixP->fx_line,
_("call target address 0x%08x out of range 0x%08x to 0x%08x"),
address, range_min, range_max);
if (fixP->fx_r_type == BFD_RELOC_64)
{
/* We may reach here due to .8byte directives, but we never output
- BFD_RELOC_64; it must be resolved. */
+ BFD_RELOC_64; it must be resolved. */
if (fixP->fx_addsy != NULL)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("cannot create 64-bit relocation"));
/* The various nios2_assemble_* functions call this
function to generate an expression from a string representing an expression.
It then tries to evaluate the expression, and if it can, returns its value.
- If not, it creates a new nios2_insn_relocS and stores the expression and
+ If not, it creates a new nios2_insn_relocS and stores the expression and
reloc_type for future use. */
static unsigned long
nios2_assemble_expression (const char *exprstr,
{
reloc_type = nios2_special_reloc[i].reloc_type;
exprstr += strlen (nios2_special_reloc[i].string) + 1;
-
+
/* %lo and %hiadj have different meanings for PC-relative
expressions. */
if (pcrel)
if (reloc_type == BFD_RELOC_NIOS2_HIADJ16)
reloc_type = BFD_RELOC_NIOS2_PCREL_HA;
}
-
+
break;
}
/* Control register index. */
-static void
+static void
nios2_assemble_arg_c (const char *token, nios2_insn_infoS *insn)
{
struct nios2_reg *reg = nios2_parse_reg (token, REG_CONTROL);
}
/* Destination register. */
-static void
+static void
nios2_assemble_arg_d (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* Source register 1. */
-static void
+static void
nios2_assemble_arg_s (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* Source register 2. */
-static void
+static void
nios2_assemble_arg_t (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* Destination register w/3-bit encoding. */
-static void
+static void
nios2_assemble_arg_D (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
int reg = nios2_assemble_reg3 (token);
-
+
switch (op->format)
{
case iw_T1I7_type:
}
/* Source register w/3-bit encoding. */
-static void
+static void
nios2_assemble_arg_S (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
int reg = nios2_assemble_reg3 (token);
-
+
switch (op->format)
{
case iw_T1I7_type:
}
/* Source register 2 w/3-bit encoding. */
-static void
+static void
nios2_assemble_arg_T (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
int reg = nios2_assemble_reg3 (token);
-
+
switch (op->format)
{
case iw_T2I4_type:
}
/* 16-bit signed immediate. */
-static void
+static void
nios2_assemble_arg_i (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* 12-bit signed immediate. */
-static void
+static void
nios2_assemble_arg_I (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* 16-bit unsigned immediate. */
-static void
+static void
nios2_assemble_arg_u (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* 7-bit unsigned immediate with 2-bit shift. */
-static void
+static void
nios2_assemble_arg_U (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* 5-bit unsigned immediate with 2-bit shift. */
-static void
+static void
nios2_assemble_arg_V (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* 4-bit unsigned immediate with 2-bit shift. */
-static void
+static void
nios2_assemble_arg_W (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
insn->constant_bits |= SET_IW_T2I4_IMM4 (val >> 2);
break;
case iw_L5I4X1_type:
- /* This argument is optional for push.n/pop.n, and defaults to
+ /* This argument is optional for push.n/pop.n, and defaults to
zero if unspecified. */
if (token == NULL)
return;
}
/* 4-bit unsigned immediate with 1-bit shift. */
-static void
+static void
nios2_assemble_arg_X (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* 4-bit unsigned immediate without shift. */
-static void
+static void
nios2_assemble_arg_Y (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
/* 16-bit signed immediate address offset. */
-static void
+static void
nios2_assemble_arg_o (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* 10-bit signed address offset with 1-bit shift. */
-static void
+static void
nios2_assemble_arg_O (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* 7-bit signed address offset with 1-bit shift. */
-static void
+static void
nios2_assemble_arg_P (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* 5-bit unsigned immediate. */
-static void
+static void
nios2_assemble_arg_j (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* Second 5-bit unsigned immediate field. */
-static void
+static void
nios2_assemble_arg_k (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* 8-bit unsigned immediate. */
-static void
+static void
nios2_assemble_arg_l (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* 26-bit unsigned immediate. */
-static void
+static void
nios2_assemble_arg_m (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* 6-bit unsigned immediate with no shifting. */
-static void
+static void
nios2_assemble_arg_M (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* 6-bit unsigned immediate with 2-bit shift. */
-static void
+static void
nios2_assemble_arg_N (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
/* Encoded enumeration for addi.n/subi.n. */
-static void
+static void
nios2_assemble_arg_e (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* Encoded enumeration for slli.n/srli.n. */
-static void
+static void
nios2_assemble_arg_f (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* Encoded enumeration for andi.n. */
-static void
+static void
nios2_assemble_arg_g (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* Encoded enumeration for movi.n. */
-static void
+static void
nios2_assemble_arg_h (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
}
/* Encoded REGMASK for ldwm/stwm or push.n/pop.n. */
-static void
+static void
nios2_assemble_arg_R (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
insn->insn_code |= SET_IW_L5I4X1_CS (1);
}
break;
-
+
default:
bad_opcode (op);
}
}
/* Base register for ldwm/stwm. */
-static void
+static void
nios2_assemble_arg_B (const char *token, nios2_insn_infoS *insn)
{
const struct nios2_opcode *op = insn->insn_nios2_opcode;
switch (op->format)
{
case iw_F1X4L17_type:
- /* For ldwm, check to see if the base register is already inside the
+ /* For ldwm, check to see if the base register is already inside the
register list. */
if (op->match == MATCH_R2_LDWM
&& (nios2_reglist_mask & (1 << reg->index)))
case 'c':
nios2_assemble_arg_c (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'd':
nios2_assemble_arg_d (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 's':
nios2_assemble_arg_s (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 't':
nios2_assemble_arg_t (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'D':
nios2_assemble_arg_D (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'S':
nios2_assemble_arg_S (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'T':
nios2_assemble_arg_T (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'i':
nios2_assemble_arg_i (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'I':
nios2_assemble_arg_I (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'u':
nios2_assemble_arg_u (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'U':
nios2_assemble_arg_U (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'V':
nios2_assemble_arg_V (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'W':
nios2_assemble_arg_W (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'X':
nios2_assemble_arg_X (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'Y':
nios2_assemble_arg_Y (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'o':
nios2_assemble_arg_o (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'O':
nios2_assemble_arg_O (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'P':
nios2_assemble_arg_P (insn->insn_tokens[tokidx++], insn);
break;
case 'j':
nios2_assemble_arg_j (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'k':
nios2_assemble_arg_k (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'l':
nios2_assemble_arg_l (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'm':
nios2_assemble_arg_m (insn->insn_tokens[tokidx++], insn);
break;
case 'e':
nios2_assemble_arg_e (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'f':
nios2_assemble_arg_f (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'g':
nios2_assemble_arg_g (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'h':
nios2_assemble_arg_h (insn->insn_tokens[tokidx++], insn);
break;
-
+
case 'R':
nios2_assemble_arg_R (insn->insn_tokens[tokidx++], insn);
break;
break;
}
- /* Perform argument checking. */
+ /* Perform argument checking. */
nios2_check_assembly (insn->insn_code | insn->constant_bits,
insn->insn_tokens[tokidx]);
}
nios2_consume_arg (char *argstr, const char *parsestr)
{
char *temp;
-
+
switch (*parsestr)
{
case 'c':
case 'h':
case 'M':
case 'N':
-
+
/* We can't have %hi, %lo or %hiadj here. */
if (*argstr == '%')
as_bad (_("badly formed expression near %s"), argstr);
p = argstr;
i = 0;
bfd_boolean terminate = FALSE;
-
+
/* This rest of this function is it too fragile and it mostly works,
therefore special case this one. */
if (*parsestr == 0 && argstr != 0)
parsed_args[0] = NULL;
return;
}
-
+
while (p != NULL && !terminate && i < NIOS2_MAX_INSN_TOKENS)
{
parsed_args[i] = nios2_consume_arg (p, parsestr);
parsed_args[i + 1] = NULL;
}
-/* This function inserts the string insert num times in the array
+/* This function inserts the string insert num times in the array
parsed_args, starting at the index start. */
static void
nios2_insert_arg (char **parsed_args, const char *insert, int num,
output_insn (nios2_insn_infoS *insn)
{
char *f;
- nios2_insn_relocS *reloc;
+ nios2_insn_relocS *reloc;
f = frag_more (insn->insn_nios2_opcode->size);
/* This allocates enough space for the instruction
and puts it in the current frag. */
and puts it in the current frag. */
char *f = frag_more (8);
nios2_insn_relocS *reloc = insn->insn_reloc;
- unsigned long reg, code;
+ unsigned long reg, code = 0;
const struct nios2_opcode *op = insn->insn_nios2_opcode;
/* If the reloc is NULL, there was an error assembling the movia. */
/* The following functions are called by machine-independent parts of
the assembler. */
int
-md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
+md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
{
switch (c)
{
break;
}
- /* Create and fill a hashtable for the Nios II opcodes, registers and
+ /* Create and fill a hashtable for the Nios II opcodes, registers and
arguments. */
nios2_opcode_hash = hash_new ();
nios2_reg_hash = hash_new ();
void
md_assemble (char *op_str)
{
- char *argstr;
+ char *argstr;
char *op_strdup = NULL;
unsigned long saved_pinfo = 0;
nios2_insn_infoS thisinsn;
nios2_parse_args (insn, argstr, insn->insn_nios2_opcode->args_test,
(char **) &insn->insn_tokens[1]);
- /* We need to preserve the MOVIA macro as this is clobbered by
+ /* We need to preserve the MOVIA macro as this is clobbered by
translate_pseudo_insn. */
if (insn->insn_nios2_opcode->pinfo == NIOS2_INSN_MACRO_MOVIA)
saved_pinfo = NIOS2_INSN_MACRO_MOVIA;
- /* If the instruction is an pseudo-instruction, we want to replace it
+ /* If the instruction is an pseudo-instruction, we want to replace it
with its real equivalent, and then continue. */
if ((insn->insn_nios2_opcode->pinfo & NIOS2_INSN_MACRO)
== NIOS2_INSN_MACRO)