From 1217102f2cd028df972170ee0c79d510b62381e7 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Mon, 7 Oct 1996 22:59:04 +0000 Subject: [PATCH] * config/tc-mn10300.h (pre_defined_registers) Remove. (system_registers, cc_names): Likewise. (address_registers, data_registers, other_registers): New register arrays. (register_name, system_register_name, cc_name): Remove. (mn10300_reloc_prefix): Likewise. (data_register_name): New function. (address_register_name, other_register_name): Likewise. (md_assemble): Rough cut at parsing operands. Remove lots of unwanted code. (md_apply_fix3): Disable for now. Checkpointing today's Matsushita work. --- gas/ChangeLog | 14 ++ gas/config/tc-mn10300.c | 417 +++++++++++++++++++++------------------- 2 files changed, 238 insertions(+), 193 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index f027ff23bf2..4b767feae18 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,17 @@ +Mon Oct 7 16:53:23 1996 Jeffrey A Law (law@cygnus.com) + + * config/tc-mn10300.h (pre_defined_registers) Remove. + (system_registers, cc_names): Likewise. + (address_registers, data_registers, other_registers): New register + arrays. + (register_name, system_register_name, cc_name): Remove. + (mn10300_reloc_prefix): Likewise. + (data_register_name): New function. + (address_register_name, other_register_name): Likewise. + (md_assemble): Rough cut at parsing operands. Remove lots of + unwanted code. + (md_apply_fix3): Disable for now. + Mon Oct 7 11:38:34 1996 Andreas Schwab * config/tc-m68k.c (select_control_regs): New function, extracted diff --git a/gas/config/tc-mn10300.c b/gas/config/tc-mn10300.c index c928a86c338..e64fc230f0b 100644 --- a/gas/config/tc-mn10300.c +++ b/gas/config/tc-mn10300.c @@ -61,7 +61,6 @@ static int reg_name_search PARAMS ((const struct reg_name *, int, const char *)) static boolean register_name PARAMS ((expressionS *expressionP)); static boolean system_register_name PARAMS ((expressionS *expressionP)); static boolean cc_name PARAMS ((expressionS *expressionP)); -static bfd_reloc_code_real_type mn10300_reloc_prefix PARAMS ((void)); /* fixups */ @@ -91,85 +90,31 @@ const pseudo_typeS md_pseudo_table[] = static struct hash_control *mn10300_hash; /* This table is sorted. Suitable for searching by a binary search. */ -static const struct reg_name pre_defined_registers[] = +static const struct reg_name data_registers[] = { - { "ep", 30 }, /* ep - element ptr */ - { "gp", 4 }, /* gp - global ptr */ - { "lp", 31 }, /* lp - link ptr */ - { "r0", 0 }, - { "r1", 1 }, - { "r10", 10 }, - { "r11", 11 }, - { "r12", 12 }, - { "r13", 13 }, - { "r14", 14 }, - { "r15", 15 }, - { "r16", 16 }, - { "r17", 17 }, - { "r18", 18 }, - { "r19", 19 }, - { "r2", 2 }, - { "r20", 20 }, - { "r21", 21 }, - { "r22", 22 }, - { "r23", 23 }, - { "r24", 24 }, - { "r25", 25 }, - { "r26", 26 }, - { "r27", 27 }, - { "r28", 28 }, - { "r29", 29 }, - { "r3", 3 }, - { "r30", 30 }, - { "r31", 31 }, - { "r4", 4 }, - { "r5", 5 }, - { "r6", 6 }, - { "r7", 7 }, - { "r8", 8 }, - { "r9", 9 }, - { "sp", 3 }, /* sp - stack ptr */ - { "tp", 5 }, /* tp - text ptr */ - { "zero", 0 }, + { "d0", 0 }, + { "d1", 1 }, + { "d2", 2 }, + { "d3", 3 }, }; -#define REG_NAME_CNT (sizeof(pre_defined_registers) / sizeof(struct reg_name)) +#define DATA_REG_NAME_CNT (sizeof(data_registers) / sizeof(struct reg_name)) - -static const struct reg_name system_registers[] = +static const struct reg_name address_registers[] = { - { "eipc", 0 }, - { "eipsw", 1 }, - { "fepc", 2 }, - { "fepsw", 3 }, - { "ecr", 4 }, - { "psw", 5 }, + { "a0", 0 }, + { "a1", 1 }, + { "a2", 2 }, + { "a3", 3 }, }; -#define SYSREG_NAME_CNT (sizeof(system_registers) / sizeof(struct reg_name)) +#define ADDRESS_REG_NAME_CNT (sizeof(address_registers) / sizeof(struct reg_name)) -static const struct reg_name cc_names[] = +static const struct reg_name other_registers[] = { - { "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 }, + { "mdr", 0 }, + { "psw", 0 }, + { "sp", 0 }, }; -#define CC_NAME_CNT (sizeof(cc_names) / sizeof(struct reg_name)) +#define OTHER_REG_NAME_CNT (sizeof(other_registers) / sizeof(struct reg_name)) /* reg_name_search does a binary search of the given register table to see if "name" is a valid regiter name. Returns the register @@ -214,7 +159,7 @@ reg_name_search (regs, regcount, name) * its original state. */ static boolean -register_name (expressionP) +data_register_name (expressionP) expressionS *expressionP; { int reg_number; @@ -226,7 +171,7 @@ register_name (expressionP) start = name = input_line_pointer; c = get_symbol_end (); - reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT, name); + reg_number = reg_name_search (data_registers, DATA_REG_NAME_CNT, name); /* look to see if it's in the register table */ if (reg_number >= 0) @@ -249,7 +194,7 @@ register_name (expressionP) } } -/* Summary of system_register_name(). +/* Summary of register_name(). * * in: Input_line_pointer points to 1st char of operand. * @@ -260,7 +205,7 @@ register_name (expressionP) * its original state. */ static boolean -system_register_name (expressionP) +address_register_name (expressionP) expressionS *expressionP; { int reg_number; @@ -272,7 +217,7 @@ system_register_name (expressionP) start = name = input_line_pointer; c = get_symbol_end (); - reg_number = reg_name_search (system_registers, SYSREG_NAME_CNT, name); + reg_number = reg_name_search (address_registers, ADDRESS_REG_NAME_CNT, name); /* look to see if it's in the register table */ if (reg_number >= 0) @@ -295,7 +240,7 @@ system_register_name (expressionP) } } -/* Summary of cc_name(). +/* Summary of register_name(). * * in: Input_line_pointer points to 1st char of operand. * @@ -306,7 +251,7 @@ system_register_name (expressionP) * its original state. */ static boolean -cc_name (expressionP) +other_register_name (expressionP) expressionS *expressionP; { int reg_number; @@ -318,12 +263,12 @@ cc_name (expressionP) start = name = input_line_pointer; c = get_symbol_end (); - reg_number = reg_name_search (cc_names, CC_NAME_CNT, name); + reg_number = reg_name_search (other_registers, OTHER_REG_NAME_CNT, name); /* look to see if it's in the register table */ if (reg_number >= 0) { - expressionP->X_op = O_constant; + expressionP->X_op = O_register; expressionP->X_add_number = reg_number; /* make the rest nice */ @@ -450,30 +395,6 @@ md_begin () } } -static bfd_reloc_code_real_type -mn10300_reloc_prefix() -{ - if (strncmp(input_line_pointer, "hi0(", 4) == 0) - { - input_line_pointer += 4; - return BFD_RELOC_HI16; - } - if (strncmp(input_line_pointer, "hi(", 3) == 0) - { - input_line_pointer += 3; - return BFD_RELOC_HI16_S; - } - if (strncmp (input_line_pointer, "lo(", 3) == 0) - { - input_line_pointer += 3; - return BFD_RELOC_LO16; - } - - /* FIXME: implement sda, tda, zda here */ - - return BFD_RELOC_UNUSED; -} - void md_assemble (str) char *str; @@ -512,15 +433,19 @@ md_assemble (str) for(;;) { const char *errmsg = NULL; + int op_idx; + int parens = 0; + char *hold; fc = 0; match = 0; next_opindex = 0; insn = opcode->opcode; - for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++) + for (op_idx = 1, opindex_ptr = opcode->operands; + *opindex_ptr != 0; + opindex_ptr++, op_idx++) { const struct mn10300_operand *operand; - char *hold; expressionS ex; if (next_opindex == 0) @@ -542,55 +467,101 @@ md_assemble (str) hold = input_line_pointer; input_line_pointer = str; - - /* lo(), hi(), hi0(), etc... */ - if ((reloc = mn10300_reloc_prefix()) != BFD_RELOC_UNUSED) +#if 1 + if (*str == '(') + { + str++; + input_line_pointer++; + parens++; + } +#endif + /* See if we can match the operands. */ + if (operand->flags & MN10300_OPERAND_DREG) { - expression(&ex); - - if (*input_line_pointer++ != ')') + if (!data_register_name (&ex)) { - errmsg = "syntax error: expected `)'"; + input_line_pointer = hold; + str = hold; goto error; } - - if (ex.X_op == O_constant) + } + else if (operand->flags & MN10300_OPERAND_AREG) + { + if (!address_register_name (&ex)) { - switch (reloc) - { - case BFD_RELOC_LO16: - ex.X_add_number &= 0xffff; - break; - - case BFD_RELOC_HI16: - ex.X_add_number = ((ex.X_add_number >> 16) & 0xffff); - break; - - case BFD_RELOC_HI16_S: - ex.X_add_number = ((ex.X_add_number >> 16) & 0xffff) - + ((ex.X_add_number >> 15) & 1); - break; - - default: - break; - } - - insn = mn10300_insert_operand (insn, operand, ex.X_add_number, - (char *) NULL, 0); + input_line_pointer = hold; + str = hold; + goto error; } - else + } + else if (operand->flags & MN10300_OPERAND_SP) + { + char *start = input_line_pointer; + char c = get_symbol_end (); + + if (strcmp (start, "sp") != 0) + { + *input_line_pointer = c; + input_line_pointer = hold; + str = hold; + goto error; + } + *input_line_pointer = c; + goto keep_going; + } + else if (operand->flags & MN10300_OPERAND_PSW) + { + char *start = input_line_pointer; + char c = get_symbol_end (); + + if (strcmp (start, "psw") != 0) { - if (fc > MAX_INSN_FIXUPS) - as_fatal ("too many fixups"); + *input_line_pointer = c; + input_line_pointer = hold; + str = hold; + goto error; + } + *input_line_pointer = c; + goto keep_going; + } + else if (operand->flags & MN10300_OPERAND_MDR) + { + char *start = input_line_pointer; + char c = get_symbol_end (); - fixups[fc].exp = ex; - fixups[fc].opindex = *opindex_ptr; - fixups[fc].reloc = reloc; - fc++; + if (strcmp (start, "mdr") != 0) + { + *input_line_pointer = c; + input_line_pointer = hold; + str = hold; + goto error; } + *input_line_pointer = c; + goto keep_going; + } + else if (data_register_name (&ex)) + { + input_line_pointer = hold; + str = hold; + goto error; + } + else if (address_register_name (&ex)) + { + input_line_pointer = hold; + str = hold; + goto error; + } + else if (other_register_name (&ex)) + { + input_line_pointer = hold; + str = hold; + goto error; } else { + expression (&ex); + } + switch (ex.X_op) { case O_illegal: @@ -600,17 +571,44 @@ md_assemble (str) errmsg = "missing operand"; goto error; case O_register: + if (operand->flags & (MN10300_OPERAND_DREG + | MN10300_OPERAND_AREG) == 0) + { + input_line_pointer = hold; + str = hold; + goto error; + } insn = mn10300_insert_operand (insn, operand, ex.X_add_number, (char *) NULL, 0); break; case O_constant: + /* If this operand can be promoted, and it doesn't + fit into the allocated bitfield for this insn, + then promote it (ie this opcode does not match). */ + if (operand->flags & MN10300_OPERAND_PROMOTE + && ! check_operand (insn, operand, ex.X_add_number)) + { + input_line_pointer = hold; + str = hold; + goto error; + } + insn = mn10300_insert_operand (insn, operand, ex.X_add_number, (char *) NULL, 0); break; default: + /* If this operand can be promoted, then this opcode didn't + match since we can't know if it needed promotion! */ + if (operand->flags & MN10300_OPERAND_PROMOTE) + { + input_line_pointer = hold; + str = hold; + goto error; + } + /* We need to generate a fixup for this expression. */ if (fc >= MAX_INSN_FIXUPS) as_fatal ("too many fixups"); @@ -621,15 +619,26 @@ md_assemble (str) break; } - } - +keep_going: str = input_line_pointer; input_line_pointer = hold; while (*str == ' ' || *str == ',' || *str == '[' || *str == ']') ++str; + + if (*str == ')') + { + str++; + parens--; + } + } + if (parens == 0 && *str != ',') + match = 1; + else + { + input_line_pointer = hold; + str = hold; } - match = 1; error: if (match == 0) @@ -655,57 +664,38 @@ md_assemble (str) input_line_pointer = str; - /* Write out the instruction. + /* XXX */ + if (opcode->format == 1) + size = 1; - Four byte insns have an opcode with the two high bits on. */ - if ((insn & 0x0600) == 0x0600) - size = 4; - else + if (opcode->format == 2 || opcode->format == 6) size = 2; - f = frag_more (size); - md_number_to_chars (f, insn, size); - /* Create any fixups. At this point we do not use a - bfd_reloc_code_real_type, but instead just use the - BFD_RELOC_UNUSED plus the operand index. This lets us easily - handle fixups for any operand type, although that is admittedly - not a very exciting feature. We pick a BFD reloc type in - md_apply_fix. */ - for (i = 0; i < fc; i++) - { - const struct mn10300_operand *operand; + if (opcode->format == 3 || opcode->format == 7) + size = 3; - operand = &mn10300_operands[fixups[i].opindex]; - if (fixups[i].reloc != BFD_RELOC_UNUSED) - { - reloc_howto_type *reloc_howto = bfd_reloc_type_lookup (stdoutput, fixups[i].reloc); - int size; - int offset; - fixS *fixP; + if (opcode->format == 4) + size = 5; - if (!reloc_howto) - abort(); - - size = bfd_get_reloc_size (reloc_howto); - offset = 4 - size; + if (opcode->format == 5) + size = 7; - if (size < 1 || size > 4) - abort(); + if (opcode->format == 8) + size = 4; - fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset, size, - &fixups[i].exp, - reloc_howto->pc_relative, - fixups[i].reloc); - } - else - { - fix_new_exp (frag_now, f - frag_now->fr_literal, 4, - &fixups[i].exp, - 1 /* FIXME: MN10300_OPERAND_RELATIVE ??? */, - ((bfd_reloc_code_real_type) - (fixups[i].opindex + (int) BFD_RELOC_UNUSED))); - } - } + if (opcode->format == 9) + size = 6; + + if (opcode->format == 10) + size = 8; + + + /* Write out the instruction. */ + + f = frag_more (size); + if (size > 4) + size = 4; + md_number_to_chars (f, insn, size); } @@ -762,6 +752,9 @@ md_apply_fix3 (fixp, valuep, seg) valueT value; char *where; + fixp->fx_done = 1; + return 0; + if (fixp->fx_addsy == (symbolS *) NULL) { value = *valuep; @@ -841,7 +834,6 @@ md_apply_fix3 (fixp, valuep, seg) return 1; } - /* Insert an operand value into an instruction. */ static unsigned long @@ -852,11 +844,17 @@ mn10300_insert_operand (insn, operand, val, file, line) char *file; unsigned int line; { - if (operand->bits != 16) + if (operand->bits != 32) { long min, max; offsetT test; + if ((operand->flags & MN10300_OPERAND_SIGNED) != 0) + { + max = (1 << (operand->bits - 1)) - 1; + min = - (1 << (operand->bits - 1)); + } + else { max = (1 << operand->bits) - 1; min = 0; @@ -882,3 +880,36 @@ mn10300_insert_operand (insn, operand, val, file, line) insn |= (((long) val & ((1 << operand->bits) - 1)) << operand->shift); return insn; } + +static unsigned long +check_operand (insn, operand, val) + unsigned long insn; + const struct mn10300_operand *operand; + offsetT val; +{ + if (operand->bits != 32) + { + long min, max; + offsetT test; + + if ((operand->flags & MN10300_OPERAND_SIGNED) != 0) + { + max = (1 << (operand->bits - 1)) - 1; + min = - (1 << (operand->bits - 1)); + } + else + { + max = (1 << operand->bits) - 1; + min = 0; + } + + test = val; + + + if (test < (offsetT) min || test > (offsetT) max) + return 0; + else + return 1; + } + return 1; +} -- 2.30.2