Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | \ ========== Copyright Header Begin ========================================== |
2 | \ | |
3 | \ Hypervisor Software File: fentry9.fth | |
4 | \ | |
5 | \ Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
6 | \ | |
7 | \ - Do no alter or remove copyright notices | |
8 | \ | |
9 | \ - Redistribution and use of this software in source and binary forms, with | |
10 | \ or without modification, are permitted provided that the following | |
11 | \ conditions are met: | |
12 | \ | |
13 | \ - Redistribution of source code must retain the above copyright notice, | |
14 | \ this list of conditions and the following disclaimer. | |
15 | \ | |
16 | \ - Redistribution in binary form must reproduce the above copyright notice, | |
17 | \ this list of conditions and the following disclaimer in the | |
18 | \ documentation and/or other materials provided with the distribution. | |
19 | \ | |
20 | \ Neither the name of Sun Microsystems, Inc. or the names of contributors | |
21 | \ may be used to endorse or promote products derived from this software | |
22 | \ without specific prior written permission. | |
23 | \ | |
24 | \ This software is provided "AS IS," without a warranty of any kind. | |
25 | \ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, | |
26 | \ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A | |
27 | \ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN | |
28 | \ MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR | |
29 | \ ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
30 | \ DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN | |
31 | \ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR | |
32 | \ FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE | |
33 | \ DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, | |
34 | \ ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF | |
35 | \ SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
36 | \ | |
37 | \ You acknowledge that this software is not designed, licensed or | |
38 | \ intended for use in the design, construction, operation or maintenance of | |
39 | \ any nuclear facility. | |
40 | \ | |
41 | \ ========== Copyright Header End ============================================ | |
42 | id: @(#)fentry9.fth 1.9 07/06/05 | |
43 | copyright: Copyright 2007 Sun Microsystems, Inc. All Rights Reserved | |
44 | copyright: Use is subject to license terms. | |
45 | ||
46 | \ Processor-dependent code to establish the proper machine state when | |
47 | \ Forth is called from C. This is used by the "make-c-entry" routine | |
48 | \ in makecentry.fth. These files are separate because the "make-c-entry" | |
49 | \ routine is a compilation word which is somewhat different between the | |
50 | \ metacompiler environment and the native compilation environment. | |
51 | ||
52 | \ The implementation might be easier if Forth used the local registers for | |
53 | \ its pointers, instead of the global registers. The outs could be | |
54 | \ used for scratch registers instead of the locals. | |
55 | ||
56 | decimal | |
57 | ||
58 | headerless | |
59 | code return-to-c ( -- ) | |
60 | tos %i0 move \ Return value (if any) | |
61 | ||
62 | \ We don't want to depend on the data | |
63 | \ stack pointer being the same, because | |
64 | \ the routine may have left a return value | |
65 | \ on the stack. | |
66 | %o6 V9_SP_BIAS d# 16 na+ sp nget | |
67 | ||
68 | \ Restore these in case of multiple levels of cross-language calls; | |
69 | \ if the Forth word that was just executed called a C subroutine, | |
70 | \ then saved-sp and saved-rp could have been changed. | |
71 | ||
72 | sp 'user saved-sp nput | |
73 | rp 'user saved-rp nput | |
74 | ||
75 | \ Restore the Globals | |
76 | ||
77 | %o6 V9_SP_BIAS d# 17 na+ %g1 nget | |
78 | %o6 V9_SP_BIAS d# 18 na+ %g2 nget | |
79 | %o6 V9_SP_BIAS d# 19 na+ %g3 nget | |
80 | %o6 V9_SP_BIAS d# 20 na+ %g4 nget | |
81 | %o6 V9_SP_BIAS d# 21 na+ %g5 nget | |
82 | %o6 V9_SP_BIAS d# 22 na+ %g6 nget | |
83 | %o6 V9_SP_BIAS d# 23 na+ %g7 nget | |
84 | ||
85 | %i7 8 %g0 jmpl | |
86 | %g0 0 %g0 restore | |
87 | end-code | |
88 | ||
89 | \ This is used in only one place -- the implementation of the op_release | |
90 | \ ROMvec entry. It pops a call frame and returns to the caller's caller. | |
91 | \ This is a special-purpose hack used to implement "kill a process from | |
92 | \ it's childs stack" | |
93 | ||
94 | code double-return-to-c ( -- ) | |
95 | ||
96 | \ We don't want to depend on the data | |
97 | \ stack pointer being the same, because | |
98 | \ the routine may have left a return value | |
99 | \ on the stack. | |
100 | %o6 V9_SP_BIAS d# 16 na+ sp nget | |
101 | ||
102 | \ Restore these in case of multiple levels of cross-language calls; | |
103 | \ if the Forth word that was just executed called a C subroutine, | |
104 | \ then saved-sp and saved-rp could have been changed. | |
105 | ||
106 | sp 'user saved-sp nput | |
107 | rp 'user saved-rp nput | |
108 | ||
109 | \ Restore the Globals | |
110 | ||
111 | %o6 V9_SP_BIAS d# 17 na+ %g1 nget | |
112 | %o6 V9_SP_BIAS d# 18 na+ %g2 nget | |
113 | %o6 V9_SP_BIAS d# 19 na+ %g3 nget | |
114 | %o6 V9_SP_BIAS d# 20 na+ %g4 nget | |
115 | %o6 V9_SP_BIAS d# 21 na+ %g5 nget | |
116 | %o6 V9_SP_BIAS d# 22 na+ %g6 nget | |
117 | %o6 V9_SP_BIAS d# 23 na+ %g7 nget | |
118 | ||
119 | %g0 0 %g0 restore \ Remove the caller's stack frame | |
120 | ||
121 | %i7 8 %g0 jmpl \ Return to the caller's caller | |
122 | %g0 0 %g0 restore | |
123 | end-code | |
124 | ||
125 | \ We get here from a Forth C-entry stub, which in turn was called from a | |
126 | \ C subroutine call. The entry stub did a "save", then called forth-entry. | |
127 | \ The IP will be set to the location following the delay slot of the call. | |
128 | \ The "save" allocated enough space for saving the window registers (16 x 8), | |
129 | \ plus the globals (8 x 8), plus space for 2 Forth stacks (64+64). | |
130 | ||
131 | \ We have a fresh set of local registers as a result of the save. | |
132 | ||
133 | \ The arguments are in the caller's "out" registers, which are our "in" | |
134 | \ registers after we do the "save", which also gets us a fresh set of locals. | |
135 | \ | |
136 | \ %o0 = UP | |
137 | \ %o1 = BASE | |
138 | \ %o2 = SP | |
139 | \ %o3 = RP | |
140 | \ %o4 = IP | |
141 | label forth-entry | |
142 | ||
143 | \ Save the globals on the stack | |
144 | %g1 %o6 V9_SP_BIAS d# 17 na+ nput | |
145 | %g2 %o6 V9_SP_BIAS d# 18 na+ nput | |
146 | %g3 %o6 V9_SP_BIAS d# 19 na+ nput | |
147 | %g4 %o6 V9_SP_BIAS d# 20 na+ nput | |
148 | %g5 %o6 V9_SP_BIAS d# 21 na+ nput | |
149 | %g6 %o6 V9_SP_BIAS d# 22 na+ nput | |
150 | %g7 %o6 V9_SP_BIAS d# 23 na+ nput | |
151 | ||
152 | \ Establish a Forth execution environment by setting the values of | |
153 | \ the Forth virtual machine registers base, up, ip, rp, and sp. | |
154 | ||
155 | \ Set the interpret pointer to the word this Forth entry is to execute | |
156 | ||
157 | [ifexist] saved-sp | |
158 | spc 8 %o4 add | |
159 | ||
160 | \ Set the base register | |
161 | ||
162 | dictionary-size ( offset ) | |
163 | here 8 + call \ address of next instruction in spc | |
164 | ( offset ) base set \ relative address of current instruction | |
165 | spc base base sub \ subtract them to find the base address | |
166 | ||
167 | \ Set the user pointer | |
168 | ||
169 | 'body main-task tos set \ Allow the exception handler to find the | |
170 | base tos %o0 add | |
171 | %o0 6 %o2 lduh \ main user area in the "constant" main-task | |
172 | %o0 4 up lduh \ main user area in the "constant" main-task | |
173 | up h# 10 up sllx | |
174 | up %o2 up or | |
175 | ||
176 | \ Set the stack pointers | |
177 | ||
178 | 'user saved-sp %o2 nget \ Establish the Return Stack | |
179 | %o2 %o6 V9_SP_BIAS d# 16 na+ nput \ For restoring saved-sp upon return | |
180 | 'user saved-rp %o3 nget \ Establish the Parameter Stack | |
181 | %o3 %o6 V9_SP_BIAS d# 24 na+ nput \ For restoring saved-rp upon return | |
182 | ||
183 | \ To make Forth re-entrant, we allocate space on the stacks in case | |
184 | \ Forth gets called again by an interrupt handler. | |
185 | ||
186 | %o2 h# 40 /n* %l0 sub \ Allocate some space on the Parameter Stack | |
187 | %l0 'user saved-sp nput | |
188 | ||
189 | %o3 h# 40 /n* %l0 sub \ Allocate some space on the Return Stack | |
190 | %l0 'user saved-rp nput | |
191 | ||
192 | up %o0 move | |
193 | base %o1 move | |
194 | [then] | |
195 | ||
196 | \ Pass up to 6 subroutine arguments to Forth | |
197 | %o2 5 /n* %o2 sub | |
198 | ||
199 | %i0 tos move | |
200 | %i1 %o2 0 /n* nput | |
201 | %i2 %o2 1 /n* nput | |
202 | %i3 %o2 2 /n* nput | |
203 | %i4 %o2 3 /n* nput | |
204 | %i5 %o2 4 /n* nput | |
205 | ||
206 | \ Now we can blow away our in regs | |
207 | %o0 up move | |
208 | %o1 base move | |
209 | %o2 sp move | |
210 | %o3 rp move | |
211 | %o4 ip move | |
212 | ||
213 | c; | |
214 | ||
215 | \ Align adr so that the data segment will start at the right place. | |
216 | \ Depending on the machine architecture, the Sun loader aligns the | |
217 | \ data segment on a particular boundary. For the SPARC, the alignment | |
218 | \ boundary is a doubleword (8 bytes). | |
219 | : align-data ( adr -- aligned-adr ) 7 + -8 and ; | |
220 | ||
221 | d# 16 /n* ( window registers ) 8 /n* ( global registers ) + /n + ( rp ) | |
222 | h# 40 round-up | |
223 | negate constant /entry-frame | |
224 | ||
225 | headers |