ef3aa6c97a688e00e3ba39ad5d647baf9479c3c9
[gcc.git] / libgcc / config / rl78 / trampoline.S
1 /* libgcc routines for RL78
2 Copyright (C) 2011
3 Free Software Foundation, Inc.
4 Contributed by Red Hat.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published
10 by the Free Software Foundation; either version 3, or (at your
11 option) any later version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 License for more details.
17
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
21
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
26
27 /* RL78 Trampoline support
28
29 Since the RL78's RAM is not in the first 64k, we cannot "just" use a
30 function pointer to point to a trampoline on the stack. So, we
31 create N fixed trampolines that read from an array, and allocate
32 them as needed.
33
34 */
35
36 r8 = 0xffef0
37 r10 = 0xffef2
38 r14 = 0xffef6
39
40 .data
41 .p2align 1
42 trampoline_array:
43
44 .macro stub n
45
46 .text
47 trampoline_\n:
48 .type trampoline_\n, @function
49 movw ax, !trampoline_chain_\n
50 movw r14, ax
51 movw ax, !trampoline_addr_\n
52 br ax
53 .size trampoline_\n, .-trampoline_\n
54
55 .data
56 trampoline_frame_\n:
57 .short 0
58 trampoline_stub_\n:
59 .short trampoline_\n
60 trampoline_chain_\n:
61 .short 0
62 trampoline_addr_\n:
63 .short 0
64
65 #define TO_FRAME 0
66 #define TO_STUB 2
67 #define TO_CHAIN 4
68 #define TO_ADDR 6
69 #define TO_SIZE 8
70
71 .endm
72
73 stub 0
74 stub 1
75 stub 2
76 stub 3
77 stub 4
78 stub 5
79
80 trampoline_array_end:
81
82 /* Given the function pointer in R8 and the static chain
83 pointer in R10, allocate a trampoline and return its address in
84 R8. */
85
86 .text
87 .global ___trampoline_init
88 .type ___trampoline_init, @function
89 ___trampoline_init:
90
91 movw hl, #trampoline_array
92 1:
93 movw ax, [hl + TO_ADDR]
94 cmpw ax, #0
95 bz $2f
96
97 movw ax, hl
98 addw ax, #TO_SIZE
99 movw hl, ax
100 cmpw ax, #trampoline_array_end
101 bnz $1b
102 brk ; no more slots?
103
104 2: movw ax, r8
105 movw [hl + TO_ADDR], ax
106 movw ax, r10
107 movw [hl + TO_CHAIN], ax
108 movw ax, sp
109 movw [hl + TO_FRAME], ax
110
111 movw ax, [hl + TO_STUB]
112 movw r8, ax
113
114 ret
115 .size ___trampoline_init, . - ___trampoline_init
116
117 .global ___trampoline_uninit
118 .type ___trampoline_uninit, @function
119 ___trampoline_uninit:
120 movw hl, #trampoline_array
121 movw ax, sp
122 movw bc, ax
123 1:
124 movw ax, [hl + TO_FRAME]
125 cmpw ax, bc
126 bc $2f
127
128 clrw ax
129 movw [hl + TO_ADDR], ax
130
131 2:
132 movw ax, hl
133 addw ax, #TO_SIZE
134 movw hl, ax
135 cmpw ax, #trampoline_array_end
136 bnz $1b
137
138 ret
139 .size ___trampoline_uninit, . - ___trampoline_uninit