1/*
2            Copyright Martin Husemann 2013.
3   Distributed under the Boost Software License, Version 1.0.
4      (See accompanying file LICENSE_1_0.txt or copy at
5          http://www.boost.org/LICENSE_1_0.txt)
6*/
7
8/*******************************************************************
9 *                                                                 *
10 *  -------------------------------------------------------------  *
11 *  |  Offset (in 4 or 8 byte units) | Content                  |  *
12 *  -------------------------------------------------------------  *
13 *  | 0                              | %sp                      |  *
14 *  -------------------------------------------------------------  *
15 *  | 1                              | %pc                      |  *
16 *  -------------------------------------------------------------  *
17 *  | 2                              | %i7 (return address)     |  *
18 *  -------------------------------------------------------------  *
19 *  | 3                              | %g1                      |  *
20 *  -------------------------------------------------------------  *
21 *  | 4                              | %g2                      |  *
22 *  -------------------------------------------------------------  *
23 *  | 5                              | %g3                      |  *
24 *  -------------------------------------------------------------  *
25 *  | 6                              | %g6                      |  *
26 *  -------------------------------------------------------------  *
27 *  | 7                              | %g7                      |  *
28 *  -------------------------------------------------------------  *
29 *    The local and in registers are stored on the stack.          *
30 *******************************************************************/
31
32#define	OFF(N)	(4*(N))
33#define	CCFSZ	96
34#define	FC_SZ	176
35#define	FC_stK	168		// offsetof(fcontext_t, fc_stack)
36#define	FC_FPU	0		// offsetof(fcontext_t, fc_fp)
37#define	FC_FSR	128		// offsetof(fcontext_t, fc_fp.fp_fsr)
38#define	FC_GREG	136		// offsetof(fcontext_t, fc_greg)
39#define	BLOCK_SIZE 8
40
41.text
42.globl make_fcontext
43.align 4
44.type make_fcontext,@function
45// fcontext_t *
46// make_fcontext( void * sp, std::size_t size, void (* fn)( intptr_t) )
47make_fcontext:
48    save %sp, -CCFSZ, %sp
49    // %i0 initial stack pointer
50    // %i1 stack size limit
51    // %i2 function pointer for context start function
52
53    sub %i0, FC_SZ, %i4			// allocate fcontext_t at on the new stack and keep pointer as return value
54    andn %i4, BLOCK_SIZE-1, %i5		// force block ops usable alignement and keep pointer to fcontext in %i5
55
56    st %i0, [%i5+FC_stK+OFF(0)]		// save fs_stack.sp
57    st %i1, [%i5+FC_stK+OFF(1)]		// save fs_stack.size
58    sub %i5, CCFSZ, %o1   		// leave space for one register window
59    st %o1, [%i5+FC_GREG+OFF(0)]	// save new stack pointer
60    st %i2, [%i5+FC_GREG+OFF(1)]	// save new %pc (function pointer)
61    st %g1, [%i5+FC_GREG+OFF(3)]
62    st %g2, [%i5+FC_GREG+OFF(4)]
63    st %g3, [%i5+FC_GREG+OFF(5)]
64    st %g6, [%i5+FC_GREG+OFF(6)]
65    st %g7, [%i5+FC_GREG+OFF(7)]
66
67    // synthesize "return address": jump to finish
68    mov %i7, %l0
692:  call 3f
70     nop
713:  add finish-2b-8, %o7, %i4
72    st %i4, [%i5+FC_GREG+OFF(2)]
73
74    ret
75    restore %g0, %i5, %o0	// return fcontext_t
76
77finish:
78    mov %g0, %o0
79    call _exit
80     nop
81
82.size make_fcontext,.-make_fcontext
83
84/* Mark that we don't need executable stack.  */
85.section .note.GNU-stack,"",%progbits
86