summaryrefslogtreecommitdiff
path: root/libgcc/config/rl78/trampoline.S
blob: 9ea8fc4a82bd05c50f79d5b034b0799ecf7014bd (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
/* libgcc routines for RL78
   Copyright (C) 2011-2015 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. */

START_FUNC ___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
END_FUNC ___trampoline_init


START_FUNC ___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
END_FUNC ___trampoline_uninit