mirror of
https://github.com/autc04/Retro68.git
synced 2024-11-24 07:31:32 +00:00
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
|