diff options
Diffstat (limited to 'translate/grt/config/sparc.S')
-rw-r--r-- | translate/grt/config/sparc.S | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/translate/grt/config/sparc.S b/translate/grt/config/sparc.S new file mode 100644 index 0000000..698d49e --- /dev/null +++ b/translate/grt/config/sparc.S @@ -0,0 +1,134 @@ +/* GRT stack implementation for x86. + Copyright (C) 2002, 2003, 2004, 2005 Tristan Gingold. + + GHDL 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 2, or (at your option) any later + version. + + GHDL 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. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ + .file "sparc.S" + + .section ".text" + + /* Stack structure is: + +4 : cur_length + +0 : cur_sp + -4 : return address + -8 : process function to be executed + -12: function argument + ... + -72: %sp + */ + + /* Function called to loop on the process. */ + .align 4 + .type grt_stack_loop,#function +grt_stack_loop: + ld [%sp + 64], %o1 + jmpl %o1 + 0, %o7 + ld [%sp + 68], %o0 + ba grt_stack_loop + nop + .size grt_stack_loop, . - grt_stack_loop + + /* function Stack_Create (Func : Address; Arg : Address) + return Stack_Type; */ + .align 4 + .global grt_stack_create + .type grt_stack_create,#function +grt_stack_create: + /* Standard prologue. */ + save %sp,-80,%sp + + /* Allocate the stack, and exit in case of failure */ + call grt_stack_allocate + nop + cmp %o0, 0 + be .Ldone + nop + + /* Note: %o0 contains the address of the stack_context. This is + also the top of the stack. */ + + /* Prepare stack. */ + + /* The return function. */ + sethi %hi(grt_stack_loop - 8), %l2 + or %lo(grt_stack_loop - 8), %l2, %l2 + + /* Create a frame for grt_stack_loop. */ + sub %o0, (64 + 8), %l1 + + /* The function to be executed. */ + st %i0, [%l1 + 64] + /* The argument. */ + st %i1, [%l1 + 68] + + /* Create a frame for grt_stack_switch. */ + sub %l1, 64, %l0 + + /* Save frame pointer. */ + st %l1, [%l0 + 56] + /* Save return address. */ + st %l2, [%l0 + 60] + + /* Save stack pointer. */ + st %l0, [%o0] + +.Ldone: + ret + restore %o0, %g0, %o0 + .size grt_stack_create,. - grt_stack_create + + + .align 4 + .global grt_stack_switch + /* Arguments: TO, FROM. + Both are pointers to a stack_context. */ + .type grt_stack_switch,#function +grt_stack_switch: + /* Standard prologue. */ + save %sp,-80,%sp + + /* Flush and invalidate windows. + It is not clear wether the current window is saved or not, + therefore, I assume it is not. + */ + ta 3 + + /* Only IN registers %fp and %i7 (return address) must be saved. + Of course, I could use std/ldd, but it is not as clear + */ + /* Save current frame pointer. */ + st %fp, [%sp + 56] + /* Save return address. */ + st %i7, [%sp + 60] + + /* Save stack pointer. */ + st %sp, [%i1] + + /* Load stack pointer. */ + ld [%i0], %sp + + /* Load return address. */ + ld [%sp + 60], %i7 + /* Load frame pointer. */ + ld [%sp + 56], %fp + + /* Return. */ + ret + restore + .size grt_stack_switch, . - grt_stack_switch + + + .ident "Written by T.Gingold" |