=================================================================== Index: gas/config/tc-arm.c --- gas/config/tc-arm.c (revision 38) +++ gas/config/tc-arm.c (revision 39) @@ -4307,6 +4307,9 @@ #define OP_CPSF 060 /* CPS flags */ #define OP_ENDI 061 /* Endianness specifier */ #define OP_PSR 062 /* CPSR/SPSR mask for msr */ +#define OP_REGLST 063 /* ARM register list */ +#define OP_VRSLST 064 /* VFP single-precision register list */ +#define OP_VRDLST 065 /* VFP double-precision register list */ /* This-or-that operands. All have bit 7 set. */ #define OP_RR_EX 100 /* ARM register or expression */ @@ -4357,6 +4360,7 @@ parse_operands (char *str, const char *pattern) { int i; + int val; unsigned const char *p = pattern; #define po_char_or_fail(chr) do { \ @@ -4365,30 +4369,29 @@ } while (0) #define po_reg_or_fail(regtype) do { \ - int reg_ = reg_required_here (&str, -1, regtype); \ - if (reg_ == FAIL) \ + val = reg_required_here (&str, -1, regtype); \ + if (val == FAIL) \ { \ inst.error = _(reg_expected_msgs[regtype]); \ return FAIL; \ } \ - inst.operands[i].reg = reg_; \ + inst.operands[i].reg = val; \ inst.operands[i].isreg = 1; \ } while (0) #define po_reg_or_goto(regtype, label) do { \ - int reg_ = arm_reg_parse (&str, regtype); \ - if (reg_ == FAIL) \ + val = arm_reg_parse (&str, regtype); \ + if (val == FAIL) \ goto label; \ \ - inst.operands[i].reg = reg_; \ + inst.operands[i].reg = val; \ inst.operands[i].isreg = 1; \ } while (0) #define po_imm_or_fail(min, max, popt) do { \ - int imm_; \ - if (immediate_required_here (&str, &imm_, min, max, popt) == FAIL) \ + if (immediate_required_here (&str, &val, min, max, popt) == FAIL) \ return FAIL; \ - inst.operands[i].imm = imm_; \ + inst.operands[i].imm = val; \ } while (0) /* Check for a no-operand instruction, or an instruction with only @@ -4534,15 +4537,15 @@ return FAIL; if (inst.reloc.exp.X_op == O_symbol) { - int reloc = parse_reloc (&str); - if (reloc == -1) + val = parse_reloc (&str); + if (val == -1) { inst.error = _("unrecognized relocation suffix"); return FAIL; } - else if (reloc != BFD_RELOC_UNUSED) + else if (val != BFD_RELOC_UNUSED) { - inst.operands[i].imm = reloc; + inst.operands[i].imm = val; inst.operands[i].hasreloc = 1; } } @@ -4572,14 +4575,13 @@ po_reg_or_fail (REG_TYPE_FN); else { - int reg_; str++; - reg_ = fpa_immediate (&str); - if (reg_ == FAIL) + val = fpa_immediate (&str); + if (val == FAIL) return FAIL; /* FPA immediates are encoded as registers 8-15. fpa_immediate has already applied the offset. */ - inst.operands[i].reg = reg_; + inst.operands[i].reg = val; inst.operands[i].isreg = 1; } break; @@ -4601,14 +4603,24 @@ break; case OP_(PSR): - { - int psrmask = parse_psr (&str); - if (psrmask == FAIL) - return FAIL; - inst.operands[i].imm = psrmask; - } + if ((val = parse_psr (&str)) == FAIL) + return FAIL; + inst.operands[i].imm = val; break; + case OP_(VRSLST): + val = vfp_parse_reg_list (&str, &inst.operands[i].reg, 0); + goto vfp_reglist; + + case OP_(VRDLST): + val = vfp_parse_reg_list (&str, &inst.operands[i].reg, 1); + + vfp_reglist: + if (val == FAIL) + return FAIL; + inst.operands[i].imm = val; + break; + default: as_fatal ("unhandled operand code %03o", *p); } @@ -7133,23 +7145,17 @@ static void do_vfp_reg2_from_sp2 (char * str) { - int reg; - - reg_or_fail (&str, 12, REG_TYPE_RN); - comma_or_fail (&str); - - reg_or_fail (&str, 16, REG_TYPE_RN); - comma_or_fail (&str); - - /* We require exactly two consecutive SP registers. */ - if (vfp_parse_reg_list (&str, ®, 0) != 2) + if (parse_operands (str, OPERANDS3(RR,RR,VRSLST))) + return; + if (inst.operands[2].imm != 2) { - if (! inst.error) - inst.error = _("only two consecutive VFP SP registers allowed here"); + inst.error = _("only two consecutive VFP SP registers allowed here"); + return; } - vfp_sp_encode_reg (reg, VFP_REG_Sm); - end_of_line (str); + inst.instruction |= (inst.operands[0].reg << 12); + inst.instruction |= (inst.operands[1].reg << 16); + vfp_sp_encode_reg (inst.operands[2].reg, VFP_REG_Sm); } static void @@ -7165,22 +7171,17 @@ static void do_vfp_sp2_from_reg2 (char * str) { - int reg; - - /* We require exactly two consecutive SP registers. */ - if (vfp_parse_reg_list (&str, ®, 0) != 2) + if (parse_operands (str, OPERANDS3(VRSLST,RR,RR))) + return; + if (inst.operands[0].imm != 2) { - if (! inst.error) - inst.error = _("only two consecutive VFP SP registers allowed here"); + inst.error = _("only two consecutive VFP SP registers allowed here"); + return; } - vfp_sp_encode_reg (reg, VFP_REG_Sm); - comma_or_fail (&str); - reg_or_fail (&str, 12, REG_TYPE_RN); - comma_or_fail (&str); - - reg_or_fail (&str, 16, REG_TYPE_RN); - end_of_line (str); + vfp_sp_encode_reg (inst.operands[0].reg, VFP_REG_Sm); + inst.instruction |= (inst.operands[1].reg << 12); + inst.instruction |= (inst.operands[2].reg << 16); } static void @@ -7273,62 +7274,44 @@ static void vfp_sp_ldstm (char * str, enum vfp_ldstm_type ldstm_type) { - int count; - int reg; - - reg_or_fail (&str, 16, REG_TYPE_RN); - - if (*str == '!') - { - inst.instruction |= WRITE_BACK; - str++; - } + if (parse_operands (str, OPERANDS2(RRw,VRSLST))) + return; + if (inst.operands[0].writeback) + inst.instruction |= WRITE_BACK; else if (ldstm_type != VFP_LDSTMIA) { inst.error = _("this addressing mode requires base-register writeback"); return; } - comma_or_fail (&str); - - if ((count = vfp_parse_reg_list (&str, ®, 0)) == FAIL) - return; - end_of_line (str); - - vfp_sp_encode_reg (reg, VFP_REG_Sd); - inst.instruction |= count; + inst.instruction |= inst.operands[0].reg << 16; + vfp_sp_encode_reg (inst.operands[1].reg, VFP_REG_Sd); + inst.instruction |= inst.operands[1].imm; } static void vfp_dp_ldstm (char * str, enum vfp_ldstm_type ldstm_type) { int count; - int reg; - reg_or_fail (&str, 16, REG_TYPE_RN); - - if (*str == '!') - { - inst.instruction |= WRITE_BACK; - str++; - } + if (parse_operands (str, OPERANDS2(RRw,VRDLST))) + return; + if (inst.operands[0].writeback) + inst.instruction |= WRITE_BACK; else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX) { inst.error = _("this addressing mode requires base-register writeback"); return; } - comma_or_fail (&str); + inst.instruction |= inst.operands[0].reg << 16; + inst.instruction |= inst.operands[1].reg << 12; - if ((count = vfp_parse_reg_list (&str, ®, 1)) == FAIL) - return; - - count <<= 1; + count = inst.operands[1].imm << 1; if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX) count += 1; - inst.instruction |= (reg << 12) | count; - end_of_line (str); + inst.instruction |= count; } static void