| 1 | --- gcc-3.4.0/gcc/config/arm/arm.c.arm-ldm 2004-02-27 09:51:05.000000000 -0500 |
| 2 | +++ gcc-3.4.0/gcc/config/arm/arm.c 2004-04-24 18:16:25.000000000 -0400 |
| 3 | @@ -8520,6 +8520,26 @@ |
| 4 | return_used_this_function = 0; |
| 5 | } |
| 6 | |
| 7 | +/* Return the number (counting from 0) of |
| 8 | + the least significant set bit in MASK. */ |
| 9 | + |
| 10 | +#ifdef __GNUC__ |
| 11 | +inline |
| 12 | +#endif |
| 13 | +static int |
| 14 | +number_of_first_bit_set (mask) |
| 15 | + int mask; |
| 16 | +{ |
| 17 | + int bit; |
| 18 | + |
| 19 | + for (bit = 0; |
| 20 | + (mask & (1 << bit)) == 0; |
| 21 | + ++bit) |
| 22 | + continue; |
| 23 | + |
| 24 | + return bit; |
| 25 | +} |
| 26 | + |
| 27 | const char * |
| 28 | arm_output_epilogue (rtx sibling) |
| 29 | { |
| 30 | @@ -8753,27 +8773,47 @@ |
| 31 | saved_regs_mask |= (1 << PC_REGNUM); |
| 32 | } |
| 33 | |
| 34 | - /* Load the registers off the stack. If we only have one register |
| 35 | - to load use the LDR instruction - it is faster. */ |
| 36 | - if (saved_regs_mask == (1 << LR_REGNUM)) |
| 37 | - { |
| 38 | - /* The exception handler ignores the LR, so we do |
| 39 | - not really need to load it off the stack. */ |
| 40 | - if (eh_ofs) |
| 41 | - asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM); |
| 42 | - else |
| 43 | - asm_fprintf (f, "\tldr\t%r, [%r], #4\n", LR_REGNUM, SP_REGNUM); |
| 44 | - } |
| 45 | - else if (saved_regs_mask) |
| 46 | + if (saved_regs_mask) |
| 47 | { |
| 48 | - if (saved_regs_mask & (1 << SP_REGNUM)) |
| 49 | - /* Note - write back to the stack register is not enabled |
| 50 | - (ie "ldmfd sp!..."). We know that the stack pointer is |
| 51 | - in the list of registers and if we add writeback the |
| 52 | - instruction becomes UNPREDICTABLE. */ |
| 53 | - print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask); |
| 54 | + /* Load the registers off the stack. If we only have one register |
| 55 | + to load use the LDR instruction - it is faster. */ |
| 56 | + if (bit_count (saved_regs_mask) == 1) |
| 57 | + { |
| 58 | + int reg = number_of_first_bit_set (saved_regs_mask); |
| 59 | + |
| 60 | + switch (reg) |
| 61 | + { |
| 62 | + case SP_REGNUM: |
| 63 | + /* Mustn't use base writeback when loading SP. */ |
| 64 | + asm_fprintf (f, "\tldr\t%r, [%r]\n", SP_REGNUM, SP_REGNUM); |
| 65 | + break; |
| 66 | + |
| 67 | + case LR_REGNUM: |
| 68 | + if (eh_ofs) |
| 69 | + { |
| 70 | + /* The exception handler ignores the LR, so we do |
| 71 | + not really need to load it off the stack. */ |
| 72 | + asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM); |
| 73 | + break; |
| 74 | + } |
| 75 | + /* else fall through */ |
| 76 | + |
| 77 | + default: |
| 78 | + asm_fprintf (f, "\tldr\t%r, [%r], #4\n", reg, SP_REGNUM); |
| 79 | + break; |
| 80 | + } |
| 81 | + } |
| 82 | else |
| 83 | - print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask); |
| 84 | + { |
| 85 | + if (saved_regs_mask & (1 << SP_REGNUM)) |
| 86 | + /* Note - write back to the stack register is not enabled |
| 87 | + (ie "ldmfd sp!..."). We know that the stack pointer is |
| 88 | + in the list of registers and if we add writeback the |
| 89 | + instruction becomes UNPREDICTABLE. */ |
| 90 | + print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask); |
| 91 | + else |
| 92 | + print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask); |
| 93 | + } |
| 94 | } |
| 95 | |
| 96 | if (current_function_pretend_args_size) |
| 97 | @@ -11401,22 +11441,6 @@ |
| 98 | } |
| 99 | } |
| 100 | |
| 101 | -/* Return the number (counting from 0) of |
| 102 | - the least significant set bit in MASK. */ |
| 103 | - |
| 104 | -inline static int |
| 105 | -number_of_first_bit_set (int mask) |
| 106 | -{ |
| 107 | - int bit; |
| 108 | - |
| 109 | - for (bit = 0; |
| 110 | - (mask & (1 << bit)) == 0; |
| 111 | - ++bit) |
| 112 | - continue; |
| 113 | - |
| 114 | - return bit; |
| 115 | -} |
| 116 | - |
| 117 | /* Generate code to return from a thumb function. |
| 118 | If 'reg_containing_return_addr' is -1, then the return address is |
| 119 | actually on the stack, at the stack pointer. */ |
| 120 | |