140 lines
2.9 KiB
ArmAsm
140 lines
2.9 KiB
ArmAsm
/* libgcc routines for RL78
|
|
Copyright (C) 2011
|
|
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.
|
|
|
|
*/
|
|
|
|
r8 = 0xffef0
|
|
r10 = 0xffef2
|
|
r14 = 0xffef6
|
|
|
|
.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
|