Change immobile space free pointers to alien vars
[sbcl.git] / src / runtime / hppa-assem.S
blob7d851dc689243939efff9e0ae3a55a00f99bc761
1 #ifdef __ELF__
2 // Mark the object as not requiring an executable stack.
3 .section .note.GNU-stack,"",%progbits
4 #endif
6 #define LANGUAGE_ASSEMBLY
8 #include "sbcl.h"
9 #include "lispregs.h"
10 #include "genesis/closure.h"
11 #include "genesis/fdefn.h"
12 #include "genesis/simple-fun.h"
13 #include "genesis/return-pc.h"
14 #include "genesis/static-symbols.h"
15 #include "genesis/funcallable-instance.h"
17         .level  2.0
18         .text
20         .import $global$,data
21         .import $$dyncall,MILLICODE
22         .import foreign_function_call_active,data
23         .import current_control_stack_pointer,data
24         .import current_control_frame_pointer,data
25         .import current_binding_stack_pointer,data
26         .import dynamic_space_free_pointer,data
27 /*      .import return_from_lisp_function,data */
31  * Call-into-lisp
32  */
34         .export call_into_lisp
35 call_into_lisp:
36         .proc
37         .callinfo entry_gr=18,save_rp
38         .entry
39         /* %arg0=function, %arg1=cfp, %arg2=nargs */
41         stw     %rp,-0x14(%sr0,%sp)
42         stwm    %r3,0x40(%sr0,%sp)
43         stw     %r4,-0x3c(%sr0,%sp)
44         stw     %r5,-0x38(%sr0,%sp)
45         stw     %r6,-0x34(%sr0,%sp)
46         stw     %r7,-0x30(%sr0,%sp)
47         stw     %r8,-0x2c(%sr0,%sp)
48         stw     %r9,-0x28(%sr0,%sp)
49         stw     %r10,-0x24(%sr0,%sp)
50         stw     %r11,-0x20(%sr0,%sp)
51         stw     %r12,-0x1c(%sr0,%sp)
52         stw     %r13,-0x18(%sr0,%sp)
53         stw     %r14,-0x14(%sr0,%sp)
54         stw     %r15,-0x10(%sr0,%sp)
55         stw     %r16,-0xc(%sr0,%sp)
56         stw     %r17,-0x8(%sr0,%sp)
57         stw     %r18,-0x4(%sr0,%sp)
59         /* Clear the descriptor regs, moving in args as approporate. */
60         copy    %r0,reg_CODE
61         copy    %r0,reg_FDEFN
62         copy    %arg0,reg_LEXENV
63         zdep    %arg2,29,30,reg_NARGS
64         copy    %r0,reg_OCFP
65         copy    %r0,reg_LRA
66         copy    %r0,reg_A0
67         copy    %r0,reg_A1
68         copy    %r0,reg_A2
69         copy    %r0,reg_A3
70         copy    %r0,reg_A4
71         copy    %r0,reg_A5
72         copy    %r0,reg_L0
73         copy    %r0,reg_L1
74         copy    %r0,reg_L2
76         /* Establish NIL. */
77         ldil    L%NIL,reg_NULL
78         ldo     R%NIL(reg_NULL),reg_NULL
80         /* Turn on pseudo-atomic. */
81         ldo     4(%r0),reg_ALLOC
83         /* No longer in foreign function call land. */
84         addil   L%foreign_function_call_active-$global$,%dp
85         stw     %r0,R%foreign_function_call_active-$global$(0,%r1)
87         /* Load lisp state. */
88         addil   L%dynamic_space_free_pointer-$global$,%dp
89         ldw     R%dynamic_space_free_pointer-$global$(0,%r1),%r1
90         add     reg_ALLOC,%r1,reg_ALLOC
91         addil   L%current_binding_stack_pointer-$global$,%dp
92         ldw     R%current_binding_stack_pointer-$global$(0,%r1),reg_BSP
93         addil   L%current_control_stack_pointer-$global$,%dp
94         ldw     R%current_control_stack_pointer-$global$(0,%r1),reg_CSP
95         addil   L%current_control_frame_pointer-$global$,%dp
96         ldw     R%current_control_frame_pointer-$global$(0,%r1),reg_OCFP
97         copy    %arg1,reg_CFP
99         /* End of pseudo-atomic. */
100         addit,od        -4,reg_ALLOC,reg_ALLOC
102         /* Establish lisp arguments. */
103         ldw     0(reg_CFP),reg_A0
104         ldw     4(reg_CFP),reg_A1
105         ldw     8(reg_CFP),reg_A2
106         ldw     12(reg_CFP),reg_A3
107         ldw     16(reg_CFP),reg_A4
108         ldw     20(reg_CFP),reg_A5
110         /* Calculate the LRA. */
111   ldil  L%lra-RETURN_PC_RETURN_POINT_OFFSET,reg_LRA
112   ldo R%lra-RETURN_PC_RETURN_POINT_OFFSET(reg_LRA),reg_LRA
114         /* Indirect the closure */
115         ldw     CLOSURE_FUN_OFFSET(0,reg_LEXENV),reg_CODE
116   addi  SIMPLE_FUN_CODE_OFFSET,reg_CODE,reg_LIP
118 #ifdef LISP_FEATURE_HPUX
119   /*  Get the stub address, ie assembly-routine return-from-lisp */
120   addil   L%return_from_lisp_stub-$global$,%dp
121   ldw     R%return_from_lisp_stub-$global$(0,%r1),reg_NL0
122   be,n  0(%sr5,reg_NL0)
123 #else
124   be,n  0(%sr5,reg_LIP)
125 #endif
127         break   0,0
129         .align  8
130 lra:
131   nop /* a few nops because we dont know where we land */
132   nop /* the return convention would govern this */
133   nop
134   nop
136         /* Copy CFP (%r4) into someplace else and restore r4. */
137         copy    reg_CFP,reg_NL1
138   ldw -0x3c(0,%sp),%r4
140         /* Copy the return value. */
141         copy    reg_A0,%ret0
143         /* Turn on pseudo-atomic. */
144         addi    4,reg_ALLOC,reg_ALLOC
146         /* Store the lisp state. */
147         copy    reg_ALLOC,reg_NL0
148         depi    0,31,3,reg_NL0
149         addil   L%dynamic_space_free_pointer-$global$,%dp
150         stw     reg_NL0,R%dynamic_space_free_pointer-$global$(0,%r1)
151         addil   L%current_binding_stack_pointer-$global$,%dp
152         stw     reg_BSP,R%current_binding_stack_pointer-$global$(0,%r1)
153         addil   L%current_control_stack_pointer-$global$,%dp
154         stw     reg_CSP,R%current_control_stack_pointer-$global$(0,%r1)
155         addil   L%current_control_frame_pointer-$global$,%dp
156         stw     reg_NL1,R%current_control_frame_pointer-$global$(0,%r1)
158         /* Back in C land.  [CSP is just a handy non-zero value.] */
159         addil   L%foreign_function_call_active-$global$,%dp
160         stw     reg_CSP,R%foreign_function_call_active-$global$(0,%r1)
162         /* Turn off pseudo-atomic and check for traps. */
163         addit,od        -4,reg_ALLOC,reg_ALLOC
165         ldw     -0x54(%sr0,%sp),%rp
166         ldw     -0x4(%sr0,%sp),%r18
167         ldw     -0x8(%sr0,%sp),%r17
168         ldw     -0xc(%sr0,%sp),%r16
169         ldw     -0x10(%sr0,%sp),%r15
170         ldw     -0x14(%sr0,%sp),%r14
171         ldw     -0x18(%sr0,%sp),%r13
172         ldw     -0x1c(%sr0,%sp),%r12
173         ldw     -0x20(%sr0,%sp),%r11
174         ldw     -0x24(%sr0,%sp),%r10
175         ldw     -0x28(%sr0,%sp),%r9
176         ldw     -0x2c(%sr0,%sp),%r8
177         ldw     -0x30(%sr0,%sp),%r7
178         ldw     -0x34(%sr0,%sp),%r6
179         ldw     -0x38(%sr0,%sp),%r5
180         ldw     -0x3c(%sr0,%sp),%r4
181         bv      %r0(%rp)
182         ldwm    -0x40(%sr0,%sp),%r3
184         /* And thats all. */
185         .exit
186         .procend
190  * Call-into-C
191  */
193         .export call_into_c
194 call_into_c:
195         /* Set up a lisp stack frame. */
196         copy    reg_CFP, reg_OCFP
197         copy    reg_CSP, reg_CFP
198         addi    32, reg_CSP, reg_CSP
199         stw     reg_OCFP, 0(0,reg_CFP) ; save old cfp
200         stw     reg_CFP, 4(0,reg_CFP)  ; save old csp
201         /* convert raw return PC into a fixnum PC-offset, because we dont
202            have ahold of an lra object */
203         sub     reg_LIP, reg_CODE, reg_NL5
204         addi    3-OTHER_POINTER_LOWTAG, reg_NL5, reg_NL5
205         stw     reg_NL5, 8(0,reg_CFP)
206         stw     reg_CODE, 0xc(0,reg_CFP)
208         /* set pseudo-atomic flag */
209         addi    4, reg_ALLOC, reg_ALLOC
211         /* Store the lisp state. */
212         copy    reg_ALLOC,reg_NL5
213         depi    0,31,3,reg_NL5
214         addil   L%dynamic_space_free_pointer-$global$,%dp
215         stw     reg_NL5,R%dynamic_space_free_pointer-$global$(0,%r1)
216         addil   L%current_binding_stack_pointer-$global$,%dp
217         stw     reg_BSP,R%current_binding_stack_pointer-$global$(0,%r1)
218         addil   L%current_control_stack_pointer-$global$,%dp
219         stw     reg_CSP,R%current_control_stack_pointer-$global$(0,%r1)
220         addil   L%current_control_frame_pointer-$global$,%dp
221         stw     reg_CFP,R%current_control_frame_pointer-$global$(0,%r1)
223         /* Back in C land.  [CSP is just a handy non-zero value.] */
224         addil   L%foreign_function_call_active-$global$,%dp
225         stw     reg_CSP,R%foreign_function_call_active-$global$(0,%r1)
227         /* Turn off pseudo-atomic and check for traps. */
228         addit,od        -4,reg_ALLOC,reg_ALLOC
230         /* in order to be able to call incrementally linked (ld -A) functions,
231            we have to do some mild trickery here */
232         copy reg_CFUNC, %r22
233         bl      $$dyncall,%r31
234         copy    %r31, %r2
235 call_into_c_return:
236         /* Clear the callee saves descriptor regs. */
237         copy    %r0, reg_A5
238         copy    %r0, reg_L0
239         copy    %r0, reg_L1
240         copy    %r0, reg_L2
242         /* Turn on pseudo-atomic. */
243         ldi     4, reg_ALLOC
245         /* Turn off foreign function call. */
246         addil   L%foreign_function_call_active-$global$,%dp
247         stw     %r0,R%foreign_function_call_active-$global$(0,%r1)
249         /* Load ALLOC. */
250         addil   L%dynamic_space_free_pointer-$global$,%dp
251         ldw     R%dynamic_space_free_pointer-$global$(0,%r1),%r1
252         add     reg_ALLOC,%r1,reg_ALLOC
254         /* We don't need to load OCFP, CFP, CSP, or BSP because they are
255          * in caller saves registers.
256          */
258         /* End of pseudo-atomic. */
259         addit,od        -4,reg_ALLOC,reg_ALLOC
261         /* Restore CODE.  Even though it is in a callee saves register
262          * it might have been GC'ed.
263          */
264         ldw     0xc(0,reg_CFP), reg_CODE
266         /* Restore the return pc. */
267         ldw     8(0,reg_CFP), reg_NL0
268         addi    OTHER_POINTER_LOWTAG-3, reg_NL0, reg_NL0
270         addi    -3, reg_NL0, reg_NL0
271         ldi OTHER_POINTER_LOWTAG, reg_NL1
272         sub     reg_NL0, reg_NL1, reg_NL0
274         add     reg_CODE, reg_NL0, reg_LIP
276         /* Pop the lisp stack frame, and back we go. */
277         ldw     4(0,reg_CFP), reg_CSP
278         ldw     0(0,reg_CFP), reg_OCFP
279         copy    reg_OCFP, reg_CFP
280         be      0(5,reg_LIP)
281         nop
285  * Stuff to sanctify a block of memory for execution.
286  */
288         .EXPORT sanctify_for_execution
289 sanctify_for_execution:
290         .proc
291         .callinfo
292         .entry
293         /* %arg0=start addr, %arg1=length in bytes */
294         add     %arg0,%arg1,%arg1
295         copy    %arg0,%arg2
296         ldo     -1(%arg1),%arg1
297         depi    0,31,5,%arg0
298         depi    0,31,5,%arg1
299         ldsid   (%arg0),%r1
300         mtsp    %r1,%sr1
301         ldi     32,%r1                  ; bytes per cache line
302         /* parisc 1.1 and 2.0 manuals say to flush the dcache, SYNC,
303          * flush the icache, SYNC again, and burn seven instructions
304          * before executing modified code. */
305 sanctify_loop:
306         comb,<  %arg0,%arg1,sanctify_loop
307         fdc,m   %r1(%sr1,%arg0)
308         sync
309 sanctify_loop_2:
310         comb,<  %arg2,%arg1,sanctify_loop_2
311         fic,m   %r1(%sr1,%arg2)
312         sync
314         bv      %r0(%rp)
315         nop
317         .exit
318         .procend
322  * Core saving/restoring support
323  */
325         .export call_on_stack
326 call_on_stack:
327         /* %arg0 = fn to invoke, %arg1 = new stack base */
329         /* Compute the new stack pointer. */
330         addi    64,%arg1,%sp
332         /* Zero out the previous stack pointer. */
333         stw     %r0,-4(0,%sp)
335         /* Invoke the function. */
336         ble     0(4,%arg0)
337         copy    %r31, %r2
339         /* Flame out. */
340         break   0,0
342         .export save_state
343 save_state:
344         .proc
345         .callinfo entry_gr=18,entry_fr=21,save_rp,calls
346         .entry
348         stw     %rp,-0x14(%sr0,%sp)
349         fstds,ma        %fr12,8(%sr0,%sp)
350         fstds,ma        %fr13,8(%sr0,%sp)
351         fstds,ma        %fr14,8(%sr0,%sp)
352         fstds,ma        %fr15,8(%sr0,%sp)
353         fstds,ma        %fr16,8(%sr0,%sp)
354         fstds,ma        %fr17,8(%sr0,%sp)
355         fstds,ma        %fr18,8(%sr0,%sp)
356         fstds,ma        %fr19,8(%sr0,%sp)
357         fstds,ma        %fr20,8(%sr0,%sp)
358         fstds,ma        %fr21,8(%sr0,%sp)
359         stwm    %r3,0x70(%sr0,%sp)
360         stw     %r4,-0x6c(%sr0,%sp)
361         stw     %r5,-0x68(%sr0,%sp)
362         stw     %r6,-0x64(%sr0,%sp)
363         stw     %r7,-0x60(%sr0,%sp)
364         stw     %r8,-0x5c(%sr0,%sp)
365         stw     %r9,-0x58(%sr0,%sp)
366         stw     %r10,-0x54(%sr0,%sp)
367         stw     %r11,-0x50(%sr0,%sp)
368         stw     %r12,-0x4c(%sr0,%sp)
369         stw     %r13,-0x48(%sr0,%sp)
370         stw     %r14,-0x44(%sr0,%sp)
371         stw     %r15,-0x40(%sr0,%sp)
372         stw     %r16,-0x3c(%sr0,%sp)
373         stw     %r17,-0x38(%sr0,%sp)
374         stw     %r18,-0x34(%sr0,%sp)
377         /* Remember the function we want to invoke */
378         copy    %arg0,%r19
380         /* Pass the new stack pointer in as %arg0 */
381         copy    %sp,%arg0
383         /* Leave %arg1 as %arg1. */
385         /* do the call. */
386         ble     0(4,%r19)
387         copy    %r31, %r2
389         .export _restore_state
390 _restore_state:
392         ldw     -0xd4(%sr0,%sp),%rp
393         ldw     -0x34(%sr0,%sp),%r18
394         ldw     -0x38(%sr0,%sp),%r17
395         ldw     -0x3c(%sr0,%sp),%r16
396         ldw     -0x40(%sr0,%sp),%r15
397         ldw     -0x44(%sr0,%sp),%r14
398         ldw     -0x48(%sr0,%sp),%r13
399         ldw     -0x4c(%sr0,%sp),%r12
400         ldw     -0x50(%sr0,%sp),%r11
401         ldw     -0x54(%sr0,%sp),%r10
402         ldw     -0x58(%sr0,%sp),%r9
403         ldw     -0x5c(%sr0,%sp),%r8
404         ldw     -0x60(%sr0,%sp),%r7
405         ldw     -0x64(%sr0,%sp),%r6
406         ldw     -0x68(%sr0,%sp),%r5
407         ldw     -0x6c(%sr0,%sp),%r4
408         ldwm    -0x70(%sr0,%sp),%r3
409         fldds,mb        -8(%sr0,%sp),%fr21
410         fldds,mb        -8(%sr0,%sp),%fr20
411         fldds,mb        -8(%sr0,%sp),%fr19
412         fldds,mb        -8(%sr0,%sp),%fr18
413         fldds,mb        -8(%sr0,%sp),%fr17
414         fldds,mb        -8(%sr0,%sp),%fr16
415         fldds,mb        -8(%sr0,%sp),%fr15
416         fldds,mb        -8(%sr0,%sp),%fr14
417         fldds,mb        -8(%sr0,%sp),%fr13
418         bv      %r0(%rp)
419         fldds,mb        -8(%sr0,%sp),%fr12
422         .exit
423         .procend
425         .export restore_state
426 restore_state:
427         .proc
428         .callinfo
429         copy    %arg0,%sp
430         b       _restore_state
431         copy    %arg1,%ret0
432         .procend
436 /* FIX, add support for singlestep
437         break   trap_SingleStepBreakpoint,0
438         break   trap_SingleStepBreakpoint,0
440         .export SingleStepTraps
441 SingleStepTraps:
443 /* Missing !! NOT
444         there's a break 0,0 in the new version here!!!
448  * For an explanation of the magic involved in function-end
449  * breakpoints, see the implementation in ppc-assem.S.
450  */
452         .align  8
453         .export fun_end_breakpoint_guts
454 fun_end_breakpoint_guts:
455         .word   RETURN_PC_WIDETAG + 0x600
456         /* multiple value return point -- just jump to trap. */
457         b,n     fun_end_breakpoint_trap
458         /* single value return point -- convert to multiple w/ n=1 */
459         copy    reg_CSP, reg_OCFP
460         addi    4, reg_CSP, reg_CSP
461         addi    4, %r0, reg_NARGS
462         copy    reg_NULL, reg_A1
463         copy    reg_NULL, reg_A2
464         copy    reg_NULL, reg_A3
465         copy    reg_NULL, reg_A4
466         copy    reg_NULL, reg_A5
468         .export fun_end_breakpoint_trap
469 fun_end_breakpoint_trap:
470         break   trap_FunEndBreakpoint,0
471         b,n     fun_end_breakpoint_trap
473         .export fun_end_breakpoint_end
474 fun_end_breakpoint_end: