--- /home/hwilliams/binutils-2.17.50.0.12-original/gas/config/tc-arm.c 2007-05-18 13:45:49.000000000 +1000 +++ binutils-2.17.50.0.12/gas/config/tc-arm.c 2007-05-18 13:44:48.000000000 +1000 @@ -451,6 +451,7 @@ REG_TYPE_NDQ, REG_TYPE_NSDQ, REG_TYPE_VFC, + REG_TYPE_MV, REG_TYPE_MVF, REG_TYPE_MVD, REG_TYPE_MVFX, @@ -1037,6 +1038,7 @@ /* Alternative syntaxes are accepted for a few register classes. */ switch (type) { + case REG_TYPE_MV: case REG_TYPE_MVF: case REG_TYPE_MVD: case REG_TYPE_MVFX: @@ -3573,6 +3575,140 @@ ignore_rest_of_line (); } +/* Parse a directive saving Maverick Crunch data registers. */ + +static void +s_arm_unwind_save_mv (void) +{ + int reg; + int hi_reg; + int i; + unsigned mask = 0; + valueT op; + + if (*input_line_pointer == '{') + input_line_pointer++; + + do + { + reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MV); + + if (reg == FAIL) + { + as_bad (_(reg_expected_msgs[REG_TYPE_MV])); + goto error; + } + + if (mask >> reg) + as_tsktsk (_("register list not in ascending order")); + mask |= 1 << reg; + + if (*input_line_pointer == '-') + { + input_line_pointer++; + hi_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MV); + if (hi_reg == FAIL) + { + as_bad (_(reg_expected_msgs[REG_TYPE_MV])); + goto error; + } + else if (reg >= hi_reg) + { + as_bad (_("bad register range")); + goto error; + } + for (; reg < hi_reg; reg++) + mask |= 1 << reg; + } + } + while (skip_past_comma (&input_line_pointer) != FAIL); + + if (*input_line_pointer == '}') + input_line_pointer++; + + demand_empty_rest_of_line (); + + /* Generate any deferred opcodes because we're going to be looking at + the list. */ + flush_pending_unwind (); + + for (i = 0; i < 16; i++) + { + if (mask & (1 << i)) + unwind.frame_size += 8; + } + + /* Attempt to combine with a previous opcode. We do this because gcc + likes to output separate unwind directives for a single block of + registers. */ + if (unwind.opcode_count > 0) + { + i = unwind.opcodes[unwind.opcode_count - 1]; + if ((i & 0xf8) == 0xc0) + { + i &= 7; + /* Only merge if the blocks are contiguous. */ + if (i < 6) + { + if ((mask & 0xfe00) == (1 << 9)) + { + mask |= ((1 << (i + 11)) - 1) & 0xfc00; + unwind.opcode_count--; + } + } + else if (i == 6 && unwind.opcode_count >= 2) + { + i = unwind.opcodes[unwind.opcode_count - 2]; + reg = i >> 4; + i &= 0xf; + + op = 0xffff << (reg - 1); + if (reg > 0 + && ((mask & op) == (1u << (reg - 1)))) + { + op = (1 << (reg + i + 1)) - 1; + op &= ~((1 << reg) - 1); + mask |= op; + unwind.opcode_count -= 2; + } + } + } + } + + hi_reg = 15; + /* We want to generate opcodes in the order the registers have been + saved, ie. descending order. */ + for (reg = 15; reg >= -1; reg--) + { + /* Save registers in blocks. */ + if (reg < 0 + || !(mask & (1 << reg))) + { + /* We found an unsaved reg. Generate opcodes to save the + preceeding block. */ + if (reg != hi_reg) + { + if (0) // (reg == 9) + { + /* Short form. */ + op = 0xc0 | (hi_reg - 10); + add_unwind_opcode (op, 1); + } + else + { + /* Long form. */ + op = 0xc600 | ((reg + 1) << 4) | ((hi_reg - reg) - 1); + add_unwind_opcode (op, 2); + } + } + hi_reg = reg - 1; + } + } + + return; +error: + ignore_rest_of_line (); +} /* Parse an unwind_save directive. If the argument is non-zero, this is a .vsave directive. */ @@ -3624,6 +3760,8 @@ case REG_TYPE_MMXWR: s_arm_unwind_save_mmxwr (); return; case REG_TYPE_MMXWCG: s_arm_unwind_save_mmxwcg (); return; + case REG_TYPE_MV: s_arm_unwind_save_mv (); return; + default: as_bad (_(".unwind_save does not support this kind of register")); ignore_rest_of_line (); @@ -14256,8 +14394,8 @@ REGDEF(FPSID,0,VFC), REGDEF(FPSCR,1,VFC), REGDEF(FPEXC,8,VFC), /* Maverick DSP coprocessor registers. */ - REGSET(mvf,MVF), REGSET(mvd,MVD), REGSET(mvfx,MVFX), REGSET(mvdx,MVDX), - REGSET(MVF,MVF), REGSET(MVD,MVD), REGSET(MVFX,MVFX), REGSET(MVDX,MVDX), + REGSET(mv,MV), REGSET(mvf,MVF), REGSET(mvd,MVD), REGSET(mvfx,MVFX), REGSET(mvdx,MVDX), + REGSET(MV,MV), REGSET(MVF,MVF), REGSET(MVD,MVD), REGSET(MVFX,MVFX), REGSET(MVDX,MVDX), REGNUM(mvax,0,MVAX), REGNUM(mvax,1,MVAX), REGNUM(mvax,2,MVAX), REGNUM(mvax,3,MVAX),