diff options
Diffstat (limited to 'meta/packages/gcc/gcc-3.3.4/arm-ldm.dpatch')
| -rw-r--r-- | meta/packages/gcc/gcc-3.3.4/arm-ldm.dpatch | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/meta/packages/gcc/gcc-3.3.4/arm-ldm.dpatch b/meta/packages/gcc/gcc-3.3.4/arm-ldm.dpatch new file mode 100644 index 0000000000..561624f39c --- /dev/null +++ b/meta/packages/gcc/gcc-3.3.4/arm-ldm.dpatch | |||
| @@ -0,0 +1,148 @@ | |||
| 1 | #! /bin/sh -e | ||
| 2 | |||
| 3 | src=gcc | ||
| 4 | if [ $# -eq 3 -a "$2" = '-d' ]; then | ||
| 5 | pdir="-d $3" | ||
| 6 | src=$3/gcc | ||
| 7 | elif [ $# -ne 1 ]; then | ||
| 8 | echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" | ||
| 9 | exit 1 | ||
| 10 | fi | ||
| 11 | case "$1" in | ||
| 12 | -patch) | ||
| 13 | patch $pdir -f --no-backup-if-mismatch -p0 --fuzz 10 < $0 | ||
| 14 | ;; | ||
| 15 | -unpatch) | ||
| 16 | patch $pdir -f --no-backup-if-mismatch -R -p0 --fuzz 10 < $0 | ||
| 17 | ;; | ||
| 18 | *) | ||
| 19 | echo >&2 "`basename $0`: script expects -patch|-unpatch as argument" | ||
| 20 | exit 1 | ||
| 21 | esac | ||
| 22 | exit 0 | ||
| 23 | |||
| 24 | # DP: try harder to avoid ldm in function epilogues | ||
| 25 | |||
| 26 | --- gcc/config/arm/arm.c Fri Mar 5 18:49:42 2004 | ||
| 27 | +++ gcc/config/arm/arm.c Fri Mar 5 16:00:21 2004 | ||
| 28 | @@ -7598,6 +7629,26 @@ | ||
| 29 | return_used_this_function = 0; | ||
| 30 | } | ||
| 31 | |||
| 32 | +/* Return the number (counting from 0) of | ||
| 33 | + the least significant set bit in MASK. */ | ||
| 34 | + | ||
| 35 | +#ifdef __GNUC__ | ||
| 36 | +inline | ||
| 37 | +#endif | ||
| 38 | +static int | ||
| 39 | +number_of_first_bit_set (mask) | ||
| 40 | + int mask; | ||
| 41 | +{ | ||
| 42 | + int bit; | ||
| 43 | + | ||
| 44 | + for (bit = 0; | ||
| 45 | + (mask & (1 << bit)) == 0; | ||
| 46 | + ++bit) | ||
| 47 | + continue; | ||
| 48 | + | ||
| 49 | + return bit; | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | const char * | ||
| 53 | arm_output_epilogue (really_return) | ||
| 54 | int really_return; | ||
| 55 | @@ -7788,27 +7839,47 @@ | ||
| 56 | saved_regs_mask |= (1 << PC_REGNUM); | ||
| 57 | } | ||
| 58 | |||
| 59 | - /* Load the registers off the stack. If we only have one register | ||
| 60 | - to load use the LDR instruction - it is faster. */ | ||
| 61 | - if (saved_regs_mask == (1 << LR_REGNUM)) | ||
| 62 | - { | ||
| 63 | - /* The exception handler ignores the LR, so we do | ||
| 64 | - not really need to load it off the stack. */ | ||
| 65 | - if (eh_ofs) | ||
| 66 | - asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM); | ||
| 67 | - else | ||
| 68 | - asm_fprintf (f, "\tldr\t%r, [%r], #4\n", LR_REGNUM, SP_REGNUM); | ||
| 69 | - } | ||
| 70 | - else if (saved_regs_mask) | ||
| 71 | + if (saved_regs_mask) | ||
| 72 | { | ||
| 73 | - if (saved_regs_mask & (1 << SP_REGNUM)) | ||
| 74 | - /* Note - write back to the stack register is not enabled | ||
| 75 | - (ie "ldmfd sp!..."). We know that the stack pointer is | ||
| 76 | - in the list of registers and if we add writeback the | ||
| 77 | - instruction becomes UNPREDICTABLE. */ | ||
| 78 | - print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask); | ||
| 79 | + /* Load the registers off the stack. If we only have one register | ||
| 80 | + to load use the LDR instruction - it is faster. */ | ||
| 81 | + if (bit_count (saved_regs_mask) == 1) | ||
| 82 | + { | ||
| 83 | + int reg = number_of_first_bit_set (saved_regs_mask); | ||
| 84 | + | ||
| 85 | + switch (reg) | ||
| 86 | + { | ||
| 87 | + case SP_REGNUM: | ||
| 88 | + /* Mustn't use base writeback when loading SP. */ | ||
| 89 | + asm_fprintf (f, "\tldr\t%r, [%r]\n", SP_REGNUM, SP_REGNUM); | ||
| 90 | + break; | ||
| 91 | + | ||
| 92 | + case LR_REGNUM: | ||
| 93 | + if (eh_ofs) | ||
| 94 | + { | ||
| 95 | + /* The exception handler ignores the LR, so we do | ||
| 96 | + not really need to load it off the stack. */ | ||
| 97 | + asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM); | ||
| 98 | + break; | ||
| 99 | + } | ||
| 100 | + /* else fall through */ | ||
| 101 | + | ||
| 102 | + default: | ||
| 103 | + asm_fprintf (f, "\tldr\t%r, [%r], #4\n", reg, SP_REGNUM); | ||
| 104 | + break; | ||
| 105 | + } | ||
| 106 | + } | ||
| 107 | else | ||
| 108 | - print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask); | ||
| 109 | + { | ||
| 110 | + if (saved_regs_mask & (1 << SP_REGNUM)) | ||
| 111 | + /* Note - write back to the stack register is not enabled | ||
| 112 | + (ie "ldmfd sp!..."). We know that the stack pointer is | ||
| 113 | + in the list of registers and if we add writeback the | ||
| 114 | + instruction becomes UNPREDICTABLE. */ | ||
| 115 | + print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask); | ||
| 116 | + else | ||
| 117 | + print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask); | ||
| 118 | + } | ||
| 119 | } | ||
| 120 | |||
| 121 | if (current_function_pretend_args_size) | ||
| 122 | @@ -9610,26 +9677,6 @@ | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | -/* Return the number (counting from 0) of | ||
| 127 | - the least significant set bit in MASK. */ | ||
| 128 | - | ||
| 129 | -#ifdef __GNUC__ | ||
| 130 | -inline | ||
| 131 | -#endif | ||
| 132 | -static int | ||
| 133 | -number_of_first_bit_set (mask) | ||
| 134 | - int mask; | ||
| 135 | -{ | ||
| 136 | - int bit; | ||
| 137 | - | ||
| 138 | - for (bit = 0; | ||
| 139 | - (mask & (1 << bit)) == 0; | ||
| 140 | - ++bit) | ||
| 141 | - continue; | ||
| 142 | - | ||
| 143 | - return bit; | ||
| 144 | -} | ||
| 145 | - | ||
| 146 | /* Generate code to return from a thumb function. | ||
| 147 | If 'reg_containing_return_addr' is -1, then the return address is | ||
| 148 | actually on the stack, at the stack pointer. */ | ||
