summaryrefslogtreecommitdiff
path: root/patches/gcc/3.4.6/150-arm-ldm.patch
diff options
context:
space:
mode:
authorYann E. MORIN" <yann.morin.1998@anciens.enib.fr>2008-07-28 21:32:33 (GMT)
committerYann E. MORIN" <yann.morin.1998@anciens.enib.fr>2008-07-28 21:32:33 (GMT)
commit6317df47791e1e35b78dc69a636445dbc22d5c21 (patch)
tree5134392c237e9aed62c1b6f7d5620340db781262 /patches/gcc/3.4.6/150-arm-ldm.patch
parent3bf3f54ed10aec366066d796186eea63c4169ad2 (diff)
Fourth step at renaming patches: renumber all patches with a 10-step.
Diffstat (limited to 'patches/gcc/3.4.6/150-arm-ldm.patch')
-rw-r--r--patches/gcc/3.4.6/150-arm-ldm.patch120
1 files changed, 120 insertions, 0 deletions
diff --git a/patches/gcc/3.4.6/150-arm-ldm.patch b/patches/gcc/3.4.6/150-arm-ldm.patch
new file mode 100644
index 0000000..18ea493
--- /dev/null
+++ b/patches/gcc/3.4.6/150-arm-ldm.patch
@@ -0,0 +1,120 @@
+diff -durN gcc-3.4.6.orig/gcc/config/arm/arm.c gcc-3.4.6/gcc/config/arm/arm.c
+--- gcc-3.4.6.orig/gcc/config/arm/arm.c 2007-08-15 22:56:20.000000000 +0200
++++ gcc-3.4.6/gcc/config/arm/arm.c 2007-08-15 22:56:20.000000000 +0200
+@@ -8524,6 +8524,26 @@
+ return_used_this_function = 0;
+ }
+
++/* Return the number (counting from 0) of
++ the least significant set bit in MASK. */
++
++#ifdef __GNUC__
++inline
++#endif
++static int
++number_of_first_bit_set (mask)
++ int mask;
++{
++ int bit;
++
++ for (bit = 0;
++ (mask & (1 << bit)) == 0;
++ ++bit)
++ continue;
++
++ return bit;
++}
++
+ const char *
+ arm_output_epilogue (rtx sibling)
+ {
+@@ -8757,27 +8777,47 @@
+ saved_regs_mask |= (1 << PC_REGNUM);
+ }
+
+- /* Load the registers off the stack. If we only have one register
+- to load use the LDR instruction - it is faster. */
+- if (saved_regs_mask == (1 << LR_REGNUM))
+- {
+- /* The exception handler ignores the LR, so we do
+- not really need to load it off the stack. */
+- if (eh_ofs)
+- asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM);
+- else
+- asm_fprintf (f, "\tldr\t%r, [%r], #4\n", LR_REGNUM, SP_REGNUM);
+- }
+- else if (saved_regs_mask)
++ if (saved_regs_mask)
+ {
+- if (saved_regs_mask & (1 << SP_REGNUM))
+- /* Note - write back to the stack register is not enabled
+- (ie "ldmfd sp!..."). We know that the stack pointer is
+- in the list of registers and if we add writeback the
+- instruction becomes UNPREDICTABLE. */
+- print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask);
++ /* Load the registers off the stack. If we only have one register
++ to load use the LDR instruction - it is faster. */
++ if (bit_count (saved_regs_mask) == 1)
++ {
++ int reg = number_of_first_bit_set (saved_regs_mask);
++
++ switch (reg)
++ {
++ case SP_REGNUM:
++ /* Mustn't use base writeback when loading SP. */
++ asm_fprintf (f, "\tldr\t%r, [%r]\n", SP_REGNUM, SP_REGNUM);
++ break;
++
++ case LR_REGNUM:
++ if (eh_ofs)
++ {
++ /* The exception handler ignores the LR, so we do
++ not really need to load it off the stack. */
++ asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM);
++ break;
++ }
++ /* else fall through */
++
++ default:
++ asm_fprintf (f, "\tldr\t%r, [%r], #4\n", reg, SP_REGNUM);
++ break;
++ }
++ }
+ else
+- print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask);
++ {
++ if (saved_regs_mask & (1 << SP_REGNUM))
++ /* Note - write back to the stack register is not enabled
++ (ie "ldmfd sp!..."). We know that the stack pointer is
++ in the list of registers and if we add writeback the
++ instruction becomes UNPREDICTABLE. */
++ print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask);
++ else
++ print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask);
++ }
+ }
+
+ if (current_function_pretend_args_size)
+@@ -11405,22 +11445,6 @@
+ }
+ }
+
+-/* Return the number (counting from 0) of
+- the least significant set bit in MASK. */
+-
+-inline static int
+-number_of_first_bit_set (int mask)
+-{
+- int bit;
+-
+- for (bit = 0;
+- (mask & (1 << bit)) == 0;
+- ++bit)
+- continue;
+-
+- return bit;
+-}
+-
+ /* Generate code to return from a thumb function.
+ If 'reg_containing_return_addr' is -1, then the return address is
+ actually on the stack, at the stack pointer. */