601-gcc34-arm-ldm.patch 3.3 KB

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