lib1funcs.S 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /* libgcc routines for R8C/M16C/M32C
  2. Copyright (C) 2005-2015 Free Software Foundation, Inc.
  3. Contributed by Red Hat.
  4. This file is part of GCC.
  5. GCC is free software; you can redistribute it and/or modify it
  6. under the terms of the GNU General Public License as published
  7. by the Free Software Foundation; either version 3, or (at your
  8. option) any later version.
  9. GCC is distributed in the hope that it will be useful, but WITHOUT
  10. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  11. or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  12. License for more details.
  13. Under Section 7 of GPL version 3, you are granted additional
  14. permissions described in the GCC Runtime Library Exception, version
  15. 3.1, as published by the Free Software Foundation.
  16. You should have received a copy of the GNU General Public License and
  17. a copy of the GCC Runtime Library Exception along with this program;
  18. see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. <http://www.gnu.org/licenses/>. */
  20. #if defined(__r8c_cpu__) || defined(__m16c_cpu__)
  21. #define A16
  22. #define A(n,w) n
  23. #define W w
  24. #else
  25. #define A24
  26. #define A(n,w) w
  27. #define W l
  28. #endif
  29. #ifdef L__m32c_memregs
  30. /* Warning: these memory locations are used as a register bank. They
  31. *must* end up consecutive in any final executable, so you may *not*
  32. use the otherwise obvious ".comm" directive to allocate space for
  33. them. */
  34. .bss
  35. .global mem0
  36. mem0: .space 1
  37. .global mem1
  38. mem1: .space 1
  39. .global mem2
  40. mem2: .space 1
  41. .global mem3
  42. mem3: .space 1
  43. .global mem4
  44. mem4: .space 1
  45. .global mem5
  46. mem5: .space 1
  47. .global mem6
  48. mem6: .space 1
  49. .global mem7
  50. mem7: .space 1
  51. .global mem8
  52. mem8: .space 1
  53. .global mem9
  54. mem9: .space 1
  55. .global mem10
  56. mem10: .space 1
  57. .global mem11
  58. mem11: .space 1
  59. .global mem12
  60. mem12: .space 1
  61. .global mem13
  62. mem13: .space 1
  63. .global mem14
  64. mem14: .space 1
  65. .global mem15
  66. mem15: .space 1
  67. #endif
  68. #ifdef L__m32c_eh_return
  69. .text
  70. .global __m32c_eh_return
  71. __m32c_eh_return:
  72. /* At this point, r0 has the stack adjustment, r1r3 has the
  73. address to return to. The stack looks like this:
  74. old_ra
  75. old_fp
  76. <- unwound sp
  77. ...
  78. fb
  79. through
  80. r0
  81. <- sp
  82. What we need to do is restore all the registers, update the
  83. stack, and return to the right place.
  84. */
  85. stc sp,a0
  86. add.W A(#16,#24),a0
  87. /* a0 points to the current stack, just above the register
  88. save areas */
  89. mov.w a0,a1
  90. exts.w r0
  91. sub.W A(r0,r2r0),a1
  92. sub.W A(#3,#4),a1
  93. /* a1 points to the new stack. */
  94. /* This is for the "rts" below. */
  95. mov.w r1,[a1]
  96. #ifdef A16
  97. mov.w r2,r1
  98. mov.b r1l,2[a1]
  99. #else
  100. mov.w r2,2[a1]
  101. #endif
  102. /* This is for the "popc sp" below. */
  103. mov.W a1,[a0]
  104. popm r0,r1,r2,r3,a0,a1,sb,fb
  105. popc sp
  106. rts
  107. #endif
  108. /* SImode arguments for SI foo(SI,SI) functions. */
  109. #ifdef A16
  110. #define SAL 5[fb]
  111. #define SAH 7[fb]
  112. #define SBL 9[fb]
  113. #define SBH 11[fb]
  114. #else
  115. #define SAL 8[fb]
  116. #define SAH 10[fb]
  117. #define SBL 12[fb]
  118. #define SBH 14[fb]
  119. #endif
  120. #ifdef L__m32c_mulsi3
  121. .text
  122. .global ___mulsi3
  123. ___mulsi3:
  124. enter #0
  125. push.w r2
  126. mov.w SAL,r0
  127. mulu.w SBL,r0 /* writes to r2r0 */
  128. mov.w r0,mem0
  129. mov.w r2,mem2
  130. mov.w SAL,r0
  131. mulu.w SBH,r0 /* writes to r2r0 */
  132. add.w r0,mem2
  133. mov.w SAH,r0
  134. mulu.w SBL,r0 /* writes to r2r0 */
  135. add.w r0,mem2
  136. pop.w r2
  137. exitd
  138. #endif
  139. #ifdef L__m32c_cmpsi2
  140. .text
  141. .global ___cmpsi2
  142. ___cmpsi2:
  143. enter #0
  144. cmp.w SBH,SAH
  145. jgt cmpsi_gt
  146. jlt cmpsi_lt
  147. cmp.w SBL,SAL
  148. jgt cmpsi_gt
  149. jlt cmpsi_lt
  150. mov.w #1,r0
  151. exitd
  152. cmpsi_gt:
  153. mov.w #2,r0
  154. exitd
  155. cmpsi_lt:
  156. mov.w #0,r0
  157. exitd
  158. #endif
  159. #ifdef L__m32c_ucmpsi2
  160. .text
  161. .global ___ucmpsi2
  162. ___ucmpsi2:
  163. enter #0
  164. cmp.w SBH,SAH
  165. jgtu cmpsi_gt
  166. jltu cmpsi_lt
  167. cmp.w SBL,SAL
  168. jgtu cmpsi_gt
  169. jltu cmpsi_lt
  170. mov.w #1,r0
  171. exitd
  172. cmpsi_gt:
  173. mov.w #2,r0
  174. exitd
  175. cmpsi_lt:
  176. mov.w #0,r0
  177. exitd
  178. #endif
  179. #ifdef L__m32c_jsri16
  180. .text
  181. #ifdef A16
  182. .global m32c_jsri16
  183. m32c_jsri16:
  184. add.w #-1, sp
  185. /* Read the address (16 bits) and return address (24 bits) off
  186. the stack. */
  187. mov.w 4[sp], r0
  188. mov.w 1[sp], r3
  189. mov.b 3[sp], a0 /* This zero-extends, so the high byte has
  190. zero in it. */
  191. /* Write the return address, then new address, to the stack. */
  192. mov.w a0, 1[sp] /* Just to get the zero in 2[sp]. */
  193. mov.w r0, 0[sp]
  194. mov.w r3, 3[sp]
  195. mov.b a0, 5[sp]
  196. /* This "returns" to the target address, leaving the pending
  197. return address on the stack. */
  198. rts
  199. #endif
  200. #endif