summaryrefslogtreecommitdiff
path: root/libgcc/config/rl78/trampoline.S
blob: 59d429eb589ffcfac7f13610aa2a86c06e00637b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/* libgcc routines for RL78
   Copyright (C) 2011-2013 Free Software Foundation, Inc.
   Contributed by Red Hat.

   This file is part of GCC.

   GCC is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published
   by the Free Software Foundation; either version 3, or (at your
   option) any later version.

   GCC is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
   License for more details.

   Under Section 7 of GPL version 3, you are granted additional
   permissions described in the GCC Runtime Library Exception, version
   3.1, as published by the Free Software Foundation.

   You should have received a copy of the GNU General Public License and
   a copy of the GCC Runtime Library Exception along with this program;
   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
   <http://www.gnu.org/licenses/>.  */

/* RL78 Trampoline support

  Since the RL78's RAM is not in the first 64k, we cannot "just" use a
  function pointer to point to a trampoline on the stack.  So, we
  create N fixed trampolines that read from an array, and allocate
  them as needed.

*/

#include "vregs.h"

	.data
	.p2align	1
trampoline_array:

	.macro stub n

	.text
trampoline_\n:
        .type   trampoline_\n, @function
	movw	ax, !trampoline_chain_\n
	movw	r14, ax
	movw	ax, !trampoline_addr_\n
	br	ax
	.size	trampoline_\n, .-trampoline_\n

	.data
trampoline_frame_\n:
	.short	0
trampoline_stub_\n:
	.short	trampoline_\n
trampoline_chain_\n:
	.short	0
trampoline_addr_\n:
	.short	0

#define TO_FRAME 0
#define TO_STUB  2
#define TO_CHAIN 4
#define TO_ADDR  6
#define TO_SIZE  8

	.endm

	stub	0
	stub	1
	stub	2
	stub	3
	stub	4
	stub	5

trampoline_array_end:

/* Given the function pointer in R8 and the static chain
   pointer in R10, allocate a trampoline and return its address in
   R8. */

	.text
	.global ___trampoline_init
        .type   ___trampoline_init, @function
___trampoline_init:

	movw	hl, #trampoline_array
1:
	movw	ax, [hl + TO_ADDR]
	cmpw	ax, #0
	bz	$2f

	movw	ax, hl
	addw	ax, #TO_SIZE
	movw	hl, ax
	cmpw	ax, #trampoline_array_end
	bnz	$1b
	brk			; no more slots?

2:	movw	ax, r8
	movw	[hl + TO_ADDR], ax
	movw	ax, r10
	movw	[hl + TO_CHAIN], ax
	movw	ax, sp
	movw	[hl + TO_FRAME], ax

	movw	ax, [hl + TO_STUB]
	movw	r8, ax

	ret
	.size	___trampoline_init, . - ___trampoline_init

	.global	___trampoline_uninit
        .type   ___trampoline_uninit, @function
___trampoline_uninit:
	movw	hl, #trampoline_array
	movw	ax, sp
	movw	bc, ax
1:
	movw	ax, [hl + TO_FRAME]
	cmpw	ax, bc
	bc	$2f

	clrw	ax
	movw	[hl + TO_ADDR], ax

2:
	movw	ax, hl
	addw	ax, #TO_SIZE
	movw	hl, ax
	cmpw	ax, #trampoline_array_end
	bnz	$1b

	ret
	.size	___trampoline_uninit, . - ___trampoline_uninit