yann@339: diff -durN gcc-3.4.6.orig/gcc/config/arm/arm.c gcc-3.4.6/gcc/config/arm/arm.c yann@339: --- gcc-3.4.6.orig/gcc/config/arm/arm.c 2007-08-15 22:56:20.000000000 +0200 yann@339: +++ gcc-3.4.6/gcc/config/arm/arm.c 2007-08-15 22:56:20.000000000 +0200 yann@339: @@ -8524,6 +8524,26 @@ yann@339: return_used_this_function = 0; yann@339: } yann@339: yann@339: +/* Return the number (counting from 0) of yann@339: + the least significant set bit in MASK. */ yann@339: + yann@339: +#ifdef __GNUC__ yann@339: +inline yann@339: +#endif yann@339: +static int yann@339: +number_of_first_bit_set (mask) yann@339: + int mask; yann@339: +{ yann@339: + int bit; yann@339: + yann@339: + for (bit = 0; yann@339: + (mask & (1 << bit)) == 0; yann@339: + ++bit) yann@339: + continue; yann@339: + yann@339: + return bit; yann@339: +} yann@339: + yann@339: const char * yann@339: arm_output_epilogue (rtx sibling) yann@339: { yann@339: @@ -8757,27 +8777,47 @@ yann@339: saved_regs_mask |= (1 << PC_REGNUM); yann@339: } yann@339: yann@339: - /* Load the registers off the stack. If we only have one register yann@339: - to load use the LDR instruction - it is faster. */ yann@339: - if (saved_regs_mask == (1 << LR_REGNUM)) yann@339: - { yann@339: - /* The exception handler ignores the LR, so we do yann@339: - not really need to load it off the stack. */ yann@339: - if (eh_ofs) yann@339: - asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM); yann@339: - else yann@339: - asm_fprintf (f, "\tldr\t%r, [%r], #4\n", LR_REGNUM, SP_REGNUM); yann@339: - } yann@339: - else if (saved_regs_mask) yann@339: + if (saved_regs_mask) yann@339: { yann@339: - if (saved_regs_mask & (1 << SP_REGNUM)) yann@339: - /* Note - write back to the stack register is not enabled yann@339: - (ie "ldmfd sp!..."). We know that the stack pointer is yann@339: - in the list of registers and if we add writeback the yann@339: - instruction becomes UNPREDICTABLE. */ yann@339: - print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask); yann@339: + /* Load the registers off the stack. If we only have one register yann@339: + to load use the LDR instruction - it is faster. */ yann@339: + if (bit_count (saved_regs_mask) == 1) yann@339: + { yann@339: + int reg = number_of_first_bit_set (saved_regs_mask); yann@339: + yann@339: + switch (reg) yann@339: + { yann@339: + case SP_REGNUM: yann@339: + /* Mustn't use base writeback when loading SP. */ yann@339: + asm_fprintf (f, "\tldr\t%r, [%r]\n", SP_REGNUM, SP_REGNUM); yann@339: + break; yann@339: + yann@339: + case LR_REGNUM: yann@339: + if (eh_ofs) yann@339: + { yann@339: + /* The exception handler ignores the LR, so we do yann@339: + not really need to load it off the stack. */ yann@339: + asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM); yann@339: + break; yann@339: + } yann@339: + /* else fall through */ yann@339: + yann@339: + default: yann@339: + asm_fprintf (f, "\tldr\t%r, [%r], #4\n", reg, SP_REGNUM); yann@339: + break; yann@339: + } yann@339: + } yann@339: else yann@339: - print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask); yann@339: + { yann@339: + if (saved_regs_mask & (1 << SP_REGNUM)) yann@339: + /* Note - write back to the stack register is not enabled yann@339: + (ie "ldmfd sp!..."). We know that the stack pointer is yann@339: + in the list of registers and if we add writeback the yann@339: + instruction becomes UNPREDICTABLE. */ yann@339: + print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask); yann@339: + else yann@339: + print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask); yann@339: + } yann@339: } yann@339: yann@339: if (current_function_pretend_args_size) yann@339: @@ -11405,22 +11445,6 @@ yann@339: } yann@339: } yann@339: yann@339: -/* Return the number (counting from 0) of yann@339: - the least significant set bit in MASK. */ yann@339: - yann@339: -inline static int yann@339: -number_of_first_bit_set (int mask) yann@339: -{ yann@339: - int bit; yann@339: - yann@339: - for (bit = 0; yann@339: - (mask & (1 << bit)) == 0; yann@339: - ++bit) yann@339: - continue; yann@339: - yann@339: - return bit; yann@339: -} yann@339: - yann@339: /* Generate code to return from a thumb function. yann@339: If 'reg_containing_return_addr' is -1, then the return address is yann@339: actually on the stack, at the stack pointer. */