diff options
Diffstat (limited to 'recipes/binutils/files/binutils-crunch.patch')
-rw-r--r-- | recipes/binutils/files/binutils-crunch.patch | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/recipes/binutils/files/binutils-crunch.patch b/recipes/binutils/files/binutils-crunch.patch new file mode 100644 index 0000000000..79771aad2c --- /dev/null +++ b/recipes/binutils/files/binutils-crunch.patch @@ -0,0 +1,163 @@ +--- binutils-2.18-original/gas/config/tc-arm.c 2007-05-18 13:45:49.000000000 +1000 ++++ binutils-2.18/gas/config/tc-arm.c 2008-04-03 12:38:28.000000000 +1000 +@@ -3573,6 +3575,140 @@ + ignore_rest_of_line (); + } + ++/* Parse a directive saving Maverick Crunch double registers. */ ++ ++static void ++s_arm_unwind_save_mvd (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_MVD); ++ ++ if (reg == FAIL) ++ { ++ as_bad (_(reg_expected_msgs[REG_TYPE_MVD])); ++ 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_MVD); ++ if (hi_reg == FAIL) ++ { ++ as_bad (_(reg_expected_msgs[REG_TYPE_MVD])); ++ 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) == 0xd8) ++ { ++ 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 (reg == 9) ++ { ++ /* Short form. */ ++ op = 0xd8 | (hi_reg - 10); ++ add_unwind_opcode (op, 1); ++ } ++ else ++ { ++ /* Long form. */ ++ op = 0xde00 | ((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_MVD: s_arm_unwind_save_mvd (); 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,MVD), REGSET(mvf,MVF), REGSET(mvd,MVD), REGSET(mvfx,MVFX), REGSET(mvdx,MVDX), ++ REGSET(MV,MVD), 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), |