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