/* libgcc routines for RL78 Copyright (C) 2011-2014 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 . */ /* 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