=================================================================== Index: gas/config/tc-arm.c --- gas/config/tc-arm.c (revision 9) +++ gas/config/tc-arm.c (revision 10) @@ -481,13 +481,6 @@ {"SPSR_cxsf", FALSE, PSR_c | PSR_x | PSR_s | PSR_f}, }; -enum wreg_type - { - IWMMXT_REG_WR = 0, - IWMMXT_REG_WC = 1, - IWMMXT_REG_WCG - }; - enum iwmmxt_insn_type { check_rd, @@ -1275,11 +1268,11 @@ /* Generic register parser. CCP points to what should be the beginning of a register name. If it is indeed a valid register - name, of type TYPE, return the associated register number. If it - is not, return FAIL. Does not issue diagnostics. */ + name, advance CCP over it and return the reg_entry structure; + otherwise return NULL. Does not issue diagnostics. */ -static int -arm_reg_parse (char **ccp, enum arm_reg_type type) +static struct reg_entry * +arm_reg_parse_multi (char **ccp) { char *start = *ccp; char *p; @@ -1297,7 +1290,7 @@ p = start; if (!ISALPHA (*p) || !is_name_beginner (*p)) - return FAIL; + return NULL; do p++; @@ -1305,13 +1298,29 @@ reg = (struct reg_entry *) hash_find_n (arm_reg_hsh, start, p - start); - if (!reg || reg->type != type) - return FAIL; + if (!reg) + return NULL; *ccp = p; - return reg->number; + return reg; } +/* As above, but the register must be of type TYPE, and the return + value is the register number or NULL. */ + +static int +arm_reg_parse (char **ccp, enum arm_reg_type type) +{ + char *start = *ccp; + struct reg_entry *reg = arm_reg_parse_multi (ccp); + + if (reg && reg->type == type) + return reg->number; + + *ccp = start; + return FAIL; +} + /* A standard register must be given at this point. SHIFT is the place to put it in inst.instruction. Restores input start point on error. Returns the reg#, or FAIL. */ @@ -1512,44 +1521,21 @@ Returns the reg#, or FAIL. */ static int -wreg_required_here (char **str, int shift, enum wreg_type reg_type) +wreg_required_here (char **str, int shift, enum arm_reg_type regtype) { int reg; - switch (reg_type) + if ((reg = arm_reg_parse (str, regtype)) == FAIL) { - case IWMMXT_REG_WR: - if ((reg = arm_reg_parse (str, REG_TYPE_MMXWR)) == FAIL) - { - inst.error = gettext (reg_expected_msgs[REG_TYPE_MMXWR]); - return FAIL; - } - break; - - case IWMMXT_REG_WC: - if ((reg = arm_reg_parse (str, REG_TYPE_MMXWC)) == FAIL) - { - inst.error = gettext (reg_expected_msgs[REG_TYPE_MMXWC]); - return FAIL; - } - break; - - case IWMMXT_REG_WCG: - if ((reg = arm_reg_parse (str, REG_TYPE_MMXWCG)) == FAIL) - { - inst.error = gettext (reg_expected_msgs[REG_TYPE_MMXWCG]); - return FAIL; - } - break; - - default: - abort (); + inst.error = gettext (reg_expected_msgs[regtype]); + return FAIL; } - - if (shift >= 0) - inst.instruction |= reg << shift; - - return reg; + else + { + if (shift >= 0) + inst.instruction |= reg << shift; + return reg; + } } /* A register must be given at this point. @@ -1562,43 +1548,27 @@ static int mav_reg_required_here (char ** str, int shift, enum arm_reg_type regtype) { - int reg; + struct reg_entry *reg; char *start = *str; - if ((reg = arm_reg_parse (str, regtype)) != FAIL) + reg = arm_reg_parse_multi (str); + if (!reg + || (reg->type != regtype + /* Accept generic coprocessor register if applicable. */ + && (reg->type != REG_TYPE_CN || (regtype != REG_TYPE_MVF + && regtype != REG_TYPE_MVD + && regtype != REG_TYPE_MVFX + && regtype != REG_TYPE_MVDX)))) { - if (shift >= 0) - inst.instruction |= reg << shift; - - return reg; - } - - /* Restore the start point. */ - *str = start; - - /* Try generic coprocessor name if applicable. */ - if (regtype == REG_TYPE_MVF || - regtype == REG_TYPE_MVD || - regtype == REG_TYPE_MVFX || - regtype == REG_TYPE_MVDX) - { - if ((reg = arm_reg_parse (str, REG_TYPE_CN)) != FAIL) - { - if (shift >= 0) - inst.instruction |= reg << shift; - - return reg; - } - - /* Restore the start point. */ + inst.error = gettext (reg_expected_msgs[regtype]); *str = start; + return FAIL; } - /* In the few cases where we might be able to accept something else - this error can be overridden. */ - inst.error = gettext (reg_expected_msgs[regtype]); + if (shift >= 0) + inst.instruction |= reg->number << shift; - return FAIL; + return reg->number; } /* Expects *str -> the characters "acc0", possibly with leading blanks. @@ -4522,59 +4492,50 @@ static void s_arm_unwind_save (int ignored ATTRIBUTE_UNUSED) { - char *saved_ptr; - int reg; + char *peek; + struct reg_entry *reg; + bfd_boolean had_brace = FALSE; /* Figure out what sort of save we have. */ - SKIP_WHITESPACE (); - saved_ptr = input_line_pointer; + peek = input_line_pointer; + skip_whitespace (peek); - reg = arm_reg_parse (&input_line_pointer, REG_TYPE_FN); - if (reg != FAIL) + if (*peek == '{') { - s_arm_unwind_save_fpa (reg); - return; + had_brace = TRUE; + peek++; } - if (*input_line_pointer == '{') - input_line_pointer++; + reg = arm_reg_parse_multi (&peek); - SKIP_WHITESPACE (); - - reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN); - if (reg != FAIL) + if (!reg) { - input_line_pointer = saved_ptr; - s_arm_unwind_save_core (); + as_bad (_("register expected")); + ignore_rest_of_line (); return; } - reg = arm_reg_parse (&input_line_pointer, REG_TYPE_DN); - if (reg != FAIL) + switch (reg->type) { - input_line_pointer = saved_ptr; - s_arm_unwind_save_vfp (); + case REG_TYPE_FN: + if (had_brace) + { + as_bad (_("FPA .unwind_save does not take a register list")); + ignore_rest_of_line (); + return; + } + s_arm_unwind_save_fpa (reg->number); return; - } - reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWR); - if (reg != FAIL) - { - input_line_pointer = saved_ptr; - s_arm_unwind_save_mmxwr (); - return; - } + case REG_TYPE_RN: s_arm_unwind_save_core (); return; + case REG_TYPE_DN: s_arm_unwind_save_vfp (); return; + case REG_TYPE_MMXWR: s_arm_unwind_save_mmxwr (); return; + case REG_TYPE_MMXWCG: s_arm_unwind_save_mmxwcg (); return; - reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWCG); - if (reg != FAIL) - { - input_line_pointer = saved_ptr; - s_arm_unwind_save_mmxwcg (); - return; + default: + as_bad (_(".unwind_save does not support this kind of register")); + ignore_rest_of_line (); } - - /* TODO: Maverick registers. */ - as_bad (_("unrecognised register")); } @@ -8741,37 +8702,37 @@ break; case check_wr: - if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL) + if ((wreg_required_here (&str, 0, REG_TYPE_MMXWR)) == FAIL) return FAIL; break; case check_wrwr: - if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL + if ((wreg_required_here (&str, 12, REG_TYPE_MMXWR) == FAIL || skip_past_comma (&str) == FAIL - || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL)) + || wreg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL)) return FAIL; break; case check_wrwrwr: - if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL + if ((wreg_required_here (&str, 12, REG_TYPE_MMXWR) == FAIL || skip_past_comma (&str) == FAIL - || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL + || wreg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL || skip_past_comma (&str) == FAIL - || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL)) + || wreg_required_here (&str, 0, REG_TYPE_MMXWR) == FAIL)) return FAIL; break; case check_wrwrwcg: - if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL + if ((wreg_required_here (&str, 12, REG_TYPE_MMXWR) == FAIL || skip_past_comma (&str) == FAIL - || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL + || wreg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL || skip_past_comma (&str) == FAIL - || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL)) + || wreg_required_here (&str, 0, REG_TYPE_MMXWCG) == FAIL)) return FAIL; break; case check_tbcst: - if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL + if ((wreg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL || skip_past_comma (&str) == FAIL || reg_required_here (&str, 12, FALSE) == FAIL)) return FAIL; @@ -8780,12 +8741,12 @@ case check_tmovmsk: if ((reg_required_here (&str, 12, FALSE) == FAIL || skip_past_comma (&str) == FAIL - || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL)) + || wreg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL)) return FAIL; break; case check_tmia: - if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL + if ((wreg_required_here (&str, 5, REG_TYPE_MMXWR) == FAIL || skip_past_comma (&str) == FAIL || reg_required_here (&str, 0, FALSE) == FAIL || skip_past_comma (&str) == FAIL @@ -8794,7 +8755,7 @@ break; case check_tmcrr: - if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL + if ((wreg_required_here (&str, 0, REG_TYPE_MMXWR) == FAIL || skip_past_comma (&str) == FAIL || reg_required_here (&str, 12, FALSE) == FAIL || skip_past_comma (&str) == FAIL @@ -8807,12 +8768,12 @@ || skip_past_comma (&str) == FAIL || reg_required_here (&str, 16, FALSE) == FAIL || skip_past_comma (&str) == FAIL - || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL)) + || wreg_required_here (&str, 0, REG_TYPE_MMXWR) == FAIL)) return FAIL; break; case check_tmcr: - if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL + if ((wreg_required_here (&str, 16, REG_TYPE_MMXWC) == FAIL || skip_past_comma (&str) == FAIL || reg_required_here (&str, 12, FALSE) == FAIL)) return FAIL; @@ -8821,12 +8782,12 @@ case check_tmrc: if ((reg_required_here (&str, 12, FALSE) == FAIL || skip_past_comma (&str) == FAIL - || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL)) + || wreg_required_here (&str, 16, REG_TYPE_MMXWC) == FAIL)) return FAIL; break; case check_tinsr: - if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL + if ((wreg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL || skip_past_comma (&str) == FAIL || reg_required_here (&str, 12, FALSE) == FAIL || skip_past_comma (&str) == FAIL)) @@ -8840,11 +8801,11 @@ break; case check_waligni: - if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL + if ((wreg_required_here (&str, 12, REG_TYPE_MMXWR) == FAIL || skip_past_comma (&str) == FAIL - || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL + || wreg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL || skip_past_comma (&str) == FAIL - || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL + || wreg_required_here (&str, 0, REG_TYPE_MMXWR) == FAIL || skip_past_comma (&str) == FAIL)) return FAIL; break; @@ -8852,15 +8813,15 @@ case check_textrm: if ((reg_required_here (&str, 12, FALSE) == FAIL || skip_past_comma (&str) == FAIL - || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL + || wreg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL || skip_past_comma (&str) == FAIL)) return FAIL; break; case check_wshufh: - if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL + if ((wreg_required_here (&str, 12, REG_TYPE_MMXWR) == FAIL || skip_past_comma (&str) == FAIL - || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL + || wreg_required_here (&str, 16, REG_TYPE_MMXWR) == FAIL || skip_past_comma (&str) == FAIL)) return FAIL; break; @@ -8894,7 +8855,7 @@ skip_whitespace (str); - if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR)) == FAIL + if ((reg = wreg_required_here (&str, 12, REG_TYPE_MMXWR)) == FAIL || skip_past_comma (& str) == FAIL || cp_byte_address_required_here (&str) == FAIL) { @@ -9028,10 +8989,10 @@ skip_whitespace (str); - if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR)) == FAIL) + if ((reg = wreg_required_here (&str, 12, REG_TYPE_MMXWR)) == FAIL) { inst.error = 0; - if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WC)) == FAIL) + if ((reg = wreg_required_here (&str, 12, REG_TYPE_MMXWC)) == FAIL) return; if ((inst.instruction & COND_MASK) != COND_ALWAYS)