static struct hash_control *v850_hash;
/* Structure to hold information about predefined registers. */
-struct pd_reg
+struct reg_name
{
- char *name;
+ const char *name;
int value;
};
-
-/* an expressionS only has one register type, so we fake it */
-/* by setting high bits to indicate type */
-#define REGISTER_MASK 0xFF
-
-/* The table is sorted. Suitable for searching by a binary search. */
-static const struct pd_reg pre_defined_registers[] =
+/* This table is sorted. Suitable for searching by a binary search. */
+static const struct reg_name pre_defined_registers[] =
{
{ "ep", 30 }, /* ep - element ptr */
{ "gp", 4 }, /* gp - global ptr */
{ "tp", 5 }, /* tp - text ptr */
{ "zero", 0 },
};
-#define REG_NAME_CNT (sizeof(pre_defined_registers) / sizeof(struct pd_reg))
+#define REG_NAME_CNT (sizeof(pre_defined_registers) / sizeof(struct reg_name))
+
+
+static const struct reg_name system_registers[] =
+{
+ { "eipc", 0 },
+ { "eipsw", 1 },
+ { "fepc", 2 },
+ { "fepsw", 3 },
+ { "ecr", 4 },
+ { "psw", 5 },
+};
+
+static const struct reg_name cc_names[] =
+{
+ { "c", 0x1 },
+ { "ge", 0xe },
+ { "gt", 0xf },
+ { "h", 0xb },
+ { "l", 0x1 },
+ { "le", 0x7 },
+ { "lt", 0x6 },
+ { "n", 0x4 },
+ { "nc", 0x9 },
+ { "nh", 0x3 },
+ { "nl", 0x9 },
+ { "ns", 0xc },
+ { "nv", 0x8 },
+ { "nz", 0xa },
+ { "p", 0xc },
+ { "s", 0x4 },
+ { "sa", 0xd },
+ { "t", 0x5 },
+ { "v", 0x0 },
+ { "z", 0x2 },
+};
/* reg_name_search does a binary search of the pre_defined_registers
array to see if "name" is a valid regiter name. Returns the register
}
-/* get_operands parses a string of operands and returns and array of
- expressions. */
-static int
-get_operands (exp)
- expressionS exp[];
-{
- char *p = input_line_pointer;
- int numops = 0;
-
- while (*p)
- {
- while (*p == ' ' || *p == '\t' || *p == ',')
- p++;
- if (*p==0 || *p=='\n' || *p=='\r')
- break;
-
- /* skip trailing parens */
- if (*p == ')' || *p == ']')
- {
- p++;
- continue;
- }
-
- if (*p == '[')
- {
- p++;
- input_line_pointer = p;
- register_name(&exp[numops]);
- }
- else if (strncmp(p, "lo(", 3) == 0)
- {
- p += 3;
- input_line_pointer = p;
- expression(&exp[numops]);
- }
- else if (strncmp(p, "hi(", 3) == 0)
- {
- p += 3;
- input_line_pointer = p;
- expression(&exp[numops]);
- }
- else
- {
- input_line_pointer = p;
- if (!register_name(&exp[numops]))
- expression(&exp[numops]);
- }
-
- p = input_line_pointer;
- numops++;
- }
-
- input_line_pointer = p;
-
- exp[numops].X_op = 0;
- return (numops);
-}
-
-
-
void
md_assemble (str)
char *str;
input_line_pointer = str;
- /* get all the operands and save them as expressions */
- numops = get_operands (myops);
-
- /* now search the opcode table for one with operands that matches
- what we've got */
- match = 0;
- while (!match)
+ for(;;)
{
- match = 1;
- for (i = 0; opcode->operands[i]; i++)
+ const char *errmsg = NULL;
+
+ fc = 0;
+ match = 0;
+ next_opindex = 0;
+ for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++)
{
- int flags = v850_operands[opcode->operands[i]].flags;
- int X_op = myops[i].X_op;
- int num = myops[i].X_add_number;
+ const struct v850_operand *operand;
+ char *hold;
+ expressionS ex;
+ char endc;
- if (X_op == 0)
+ if (next_opindex == 0)
{
- match = 0;
- break;
+ operand = &v850_operands[*opindex_ptr];
+ }
+ else
+ {
+ operand = &v850_operands[next_opindex];
+ next_opindex = 0;
}
- if (flags & OPERAND_REG)
+ errmsg = NULL;
+
+ while (*str == ' ' || *str == ',' || *str == '[' || *str == ']')
+ ++str;
+
+ /* Gather the operand. */
+ hold = input_line_pointer;
+ input_line_pointer = str;
+
+ if ((operand->flags & V850_OPERAND_REG) != 0)
{
- if (X_op != O_register)
+ if (!register_name(&ex))
{
- match = 0;
- break;
+ errmsg = "invalid register name";
+ goto error;
}
}
- }
+ else if (strncmp(input_line_pointer, "lo(", 3) == 0)
+ {
+ input_line_pointer += 3;
+ expression(&ex);
- /* we're only done if the operands matched so far AND there are
- no more to check. */
- if (match && myops[i].X_op == 0)
- break;
-
- next_opcode = opcode + 1;
- if (next_opcode->opcode == 0)
- break;
- if (strcmp (next_opcode->name, opcode->name))
- break;
- opcode = next_opcode;
- }
+ if (*input_line_pointer++ != ')')
+ {
+ errmsg = "syntax error: expected `)'";
+ goto error;
+ }
+
+ if (ex.X_op == O_constant)
+ ex.X_add_number &= 0xffff;
+ else
+ {
+ if (fc > MAX_INSN_FIXUPS)
+ as_fatal ("too many fixups");
+
+ fixups[fc].exp = ex;
+ fixups[fc].opindex = *opindex_ptr;
+ fixups[fc].reloc = BFD_RELOC_LO16;
+ fc++;
+ }
+ }
+ else if (strncmp(input_line_pointer, "hi(", 3) == 0)
+ {
+ input_line_pointer += 3;
+ expression(&ex);
- if (!match)
- {
- as_bad ("Unrecognized operands");
- return;
- }
+ if (*input_line_pointer++ != ')')
+ {
+ errmsg = "syntax error: expected `)'";
+ goto error;
+ }
+
+ if (ex.X_op == O_constant)
+ ex.X_add_number = (ex.X_add_number >> 16) & 0xffff;
+ else
+ {
+ if (fc > MAX_INSN_FIXUPS)
+ as_fatal ("too many fixups");
+
+ fixups[fc].exp = ex;
+ fixups[fc].opindex = *opindex_ptr;
+ fixups[fc].reloc = BFD_RELOC_HI16;
+ fc++;
+ }
+ }
+ else
+ {
+ expression(&ex);
+ }
- insn = opcode->opcode;
+ str = input_line_pointer;
+ input_line_pointer = hold;
-#if 0
+ switch (ex.X_op)
+ {
+ case O_illegal:
+ errmsg = "illegal operand";
+ goto error;
+ case O_absent:
+ errmsg = "missing operand";
+ goto error;
+ case O_register:
+ if ((operand->flags & V850_OPERAND_REG) == 0)
+ {
+ errmsg = "invalid operand";
+ goto error;
+ }
+
+ insn = v850_insert_operand (insn, operand, ex.X_add_number,
+ (char *) NULL, 0);
+ break;
+
+ case O_constant:
+ insn = v850_insert_operand (insn, operand, ex.X_add_number,
+ (char *) NULL, 0);
+ break;
+
+ default:
+ /* We need to generate a fixup for this expression. */
+ if (fc >= MAX_INSN_FIXUPS)
+ as_fatal ("too many fixups");
+ fixups[fc].exp = ex;
+ fixups[fc].opindex = *opindex_ptr;
+ fixups[fc].reloc = BFD_RELOC_UNUSED;
+ ++fc;
+ break;
+ }
+
+ while (*str == ' ' || *str == ',' || *str == '[' || *str == ']')
+ ++str;
+ }
+ match = 1;
+
+ error:
+ if (match == 0)
+ {
+ next_opcode = opcode + 1;
+ if (next_opcode->opcode != 0 && !strcmp(next_opcode->name, opcode->name))
+ {
+ opcode = next_opcode;
+ continue;
+ }
+
+ as_bad ("%s", errmsg);
+ return;
+ }
+ break;
+ }
+
while (isspace (*str))
++str;
if (*str != '\0')
as_bad ("junk at end of line: `%s'", str);
-#endif
+
+ input_line_pointer = str;
/* Write out the instruction. */
if ((insn & 0x0600) == 0x0600)
long min, max;
offsetT test;
-#if 0
- if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
+ if ((operand->flags & V850_OPERAND_SIGNED) != 0)
{
+#if 0
if ((operand->flags & PPC_OPERAND_SIGNOPT) != 0
&& ppc_size == PPC_OPCODE_32)
max = (1 << operand->bits) - 1;
else
+#endif
max = (1 << (operand->bits - 1)) - 1;
min = - (1 << (operand->bits - 1));
}
else
-#endif
{
max = (1 << operand->bits) - 1;
min = 0;