From 3d3724acc01a7b6562bcd3721ff5eaea3b7ff200 Mon Sep 17 00:00:00 2001 From: wlott <wlott> Date: Sat, 24 Nov 1990 07:50:34 +0000 Subject: [PATCH] Initial revision --- ldb/sparc-assem.s | 418 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 418 insertions(+) create mode 100644 ldb/sparc-assem.s diff --git a/ldb/sparc-assem.s b/ldb/sparc-assem.s new file mode 100644 index 000000000..9720c3d0a --- /dev/null +++ b/ldb/sparc-assem.s @@ -0,0 +1,418 @@ + +#include <machine/asm_linkage.h> +#include <machine/psl.h> + +#define LANGUAGE_ASSEMBLY +#include "lispregs.h" +#include "lisp.h" +#include "globals.h" + +#define load(sym, reg) \ + sethi %hi(NAME(sym)), reg; ld [reg+%lo(NAME(sym))], reg +#define store(reg, sym) \ + sethi %hi(NAME(sym)), L0; st reg, [L0+%lo(NAME(sym))] + + + .seg "text" + .global NAME(call_into_lisp) +NAME(call_into_lisp): + save %sp, -(SA(MINFRAME)+SA(4)), %sp + + /* Save the return address. */ + st %i7, [%fp-4] + + /* Clear the descriptor regs. */ + mov ZERO, A0 + mov ZERO, A1 + mov ZERO, A2 + mov ZERO, A3 + mov ZERO, A4 + mov ZERO, A5 + mov ZERO, OCFP + mov ZERO, LRA + mov ZERO, L2 + mov ZERO, CODE + + /* Establish NIL */ + set NIL, NULLREG + + /* No longer in foreign function call. */ + /* Note: the atomic flag should still be set. */ + sethi %hi(NAME(foreign_function_call_active)), NL0 + st ZERO, [NL0+%lo(NAME(foreign_function_call_active))] + + /* Load the rest of lisp state. */ + load(current_dynamic_space_free_pointer, ALLOC) + load(current_binding_stack_pointer, BSP) + load(current_control_stack_pointer, CSP) + load(current_control_frame_pointer, OCFP) + + /* No longer atomic. */ + sethi %hi(PSEUDO_ATOMIC_ATOMIC+SYMBOL_VALUE_OFFSET), NL0 + st ZERO, [NL0+%lo(PSEUDO_ATOMIC_ATOMIC+SYMBOL_VALUE_OFFSET)] + + /* Were we interrupted? */ + sethi %hi(PSEUDO_ATOMIC_INTERRUPTED+SYMBOL_VALUE_OFFSET), NL0 + ld [NL0+%lo(PSEUDO_ATOMIC_INTERRUPTED+SYMBOL_VALUE_OFFSET)], NL0 + tst NL0 + beq 1f + nop + + /* Yep, we were. */ + unimp trap_PendingInterrupt +1: + + /* Pass in the args. */ + /* Note: CNAME and LEXENV already hold the correct values. */ + mov %i2, CFP + sll %i3, 2, NARGS + ld [CFP+0], A0 + ld [CFP+4], A1 + ld [CFP+8], A2 + ld [CFP+12], A3 + ld [CFP+16], A4 + ld [CFP+20], A5 + + /* Calculate LRA */ + set lra + type_OtherPointer, LRA + + /* Indirect closure */ + ld [LEXENV+CLOSURE_FUNCTION_OFFSET], CODE + + jmp CODE+FUNCTION_HEADER_CODE_OFFSET + nop + + .align 8 +lra: + .word type_ReturnPcHeader + + /* Blow off any extra values. */ + mov OCFP, CSP + nop + + /* Return the one value. */ + mov A0, %i0 + + /* Turn on pseudo_atomic */ + set 1, NL1 + sethi %hi(PSEUDO_ATOMIC_ATOMIC+SYMBOL_VALUE_OFFSET), L0 + st NL1, [L0+%lo(PSEUDO_ATOMIC_ATOMIC+SYMBOL_VALUE_OFFSET)] + + /* Store LISP state */ + store(ALLOC,current_dynamic_space_free_pointer) + store(BSP,current_binding_stack_pointer) + store(CSP,current_control_stack_pointer) + store(CFP,current_control_frame_pointer) + + /* No longer in Lisp. */ + store(NL1,foreign_function_call_active) + + /* Were we interrupted? */ + sethi %hi(PSEUDO_ATOMIC_INTERRUPTED+SYMBOL_VALUE_OFFSET), L0 + ld [L0+%lo(PSEUDO_ATOMIC_INTERRUPTED+SYMBOL_VALUE_OFFSET)], L0 + tst L0 + beq 1f + nop + + /* Yep, we were. */ + unimp trap_PendingInterrupt +1: + + /* Back to C we go. */ + ld [%fp-4], %i7 + ret + restore + + + + .global _call_into_c +_call_into_c: + /* Build a lisp stack frame */ + mov CFP, OCFP + mov CSP, CFP + add CSP, 32, CSP + st OCFP, [CFP] + st LIP, [CFP+4] + st CODE, [CFP+8] + + /* Turn on pseudo-atomic. */ + set 1, NL1 + sethi %hi(PSEUDO_ATOMIC_ATOMIC+SYMBOL_VALUE_OFFSET), L0 + st NL1, [L0+%lo(PSEUDO_ATOMIC_ATOMIC+SYMBOL_VALUE_OFFSET)] + + /* Store LISP state */ + store(ALLOC,current_dynamic_space_free_pointer) + store(BSP,current_binding_stack_pointer) + store(CSP,current_control_stack_pointer) + store(CFP,current_control_frame_pointer) + + /* No longer in Lisp. */ + store(NL1,foreign_function_call_active) + + /* Were we interrupted? */ + sethi %hi(PSEUDO_ATOMIC_INTERRUPTED+SYMBOL_VALUE_OFFSET), L0 + ld [L0+%lo(PSEUDO_ATOMIC_INTERRUPTED+SYMBOL_VALUE_OFFSET)], L0 + tst L0 + beq 1f + nop + + /* Yep, we were. */ + unimp trap_PendingInterrupt +1: + + /* Into C we go. */ + call CFUNC + nop + + /* Re-establish NIL */ + set NIL, NULLREG + + /* No longer in foreign function call. */ + /* Note: the atomic flag should still be set. */ + sethi %hi(NAME(foreign_function_call_active)), NL1 + st ZERO, [NL1+%lo(NAME(foreign_function_call_active))] + + /* Load the rest of lisp state. */ + load(current_dynamic_space_free_pointer, ALLOC) + load(current_binding_stack_pointer, BSP) + load(current_control_stack_pointer, CSP) + load(current_control_frame_pointer, CFP) + + /* No longer atomic. */ + sethi %hi(PSEUDO_ATOMIC_ATOMIC+SYMBOL_VALUE_OFFSET), NL1 + st ZERO, [NL1+%lo(PSEUDO_ATOMIC_ATOMIC+SYMBOL_VALUE_OFFSET)] + + /* Were we interrupted? */ + sethi %hi(PSEUDO_ATOMIC_INTERRUPTED+SYMBOL_VALUE_OFFSET), NL1 + ld [NL1+%lo(PSEUDO_ATOMIC_INTERRUPTED+SYMBOL_VALUE_OFFSET)], NL1 + tst NL1 + beq 1f + nop + + /* Yep, we were. */ + unimp trap_PendingInterrupt +1: + + /* Reset the lisp stack. */ + /* Note: OCFP is in one of the locals, it gets preserved across C. */ + mov CFP, CSP + mov OCFP, CFP + + /* And back into lisp. */ + ret + nop + + + + + .global _undefined_tramp + .align 8 + .byte 0 +_undefined_tramp: + .byte 0, 0, type_FunctionHeader + .word _undefined_tramp + .word NIL + .word NIL + .word NIL + + unimp trap_Error + + +/****************************************************************\ + +We need our own version of sigtramp. + +\****************************************************************/ + + .global __sigtramp, __sigfunc +__sigtramp: + ! + ! On entry sp points to: + ! 0 - 63: window save area + ! 64: signal number + ! 68: signal code + ! 72: pointer to sigcontext + ! 76: addr parameter + ! + ! A sigcontext looks like: + ! 00: on signal stack flag + ! 04: old signal mask + ! 08: old sp + ! 12: old pc + ! 16: old npc + ! 20: old psr + ! 24: old g1 + ! 28: old o0 + ! + ! Out sigcontext has the following added: + ! 32: regs[32] + ! 160: fpregs[32] + ! 288: y + ! 292: fsr + ! + ! After we allocate space for the new sigcontext, the stack looks like: + ! < window save area, etc > + ! SCOFF: start of generic sigcontext. + ! IREGSOFF: start of lisp sigcontext. + ! SIGNUM: signal number + ! CODE: signal code + ! OSCP: pointer to orig sigcontext + ! ADDR: addr parameter (which isn't supplied by the kernel) + +#define SCOFF SA(MINFRAME) +#define IREGSOFF SCOFF+32 +#define FPREGSOFF IREGSOFF+(32*4) +#define YOFF FPREGSOFF+(32*4) +#define FSROFF YOFF+4 +#define SCSIZE SA(32+(32*4)+(32*4)+4+4) +#define SIGNUMOFF SCOFF+SCSIZE +#define CODEOFF SCOFF+SCSIZE+4 +#define ADDROFF SCOFF+SCSIZE+12 +#define OSCOFF ADDROFF + + ! Allocate space for our sigcontext. + sub %sp, SCSIZE+SA(MINFRAME)-64, %sp + + ! Save integer registers. + ! Note: the globals and outs are good, but the locals and ins have + ! been trashed. But luckly, they have been saved on the stack. + ! So we need to extract the saved stack pointer from the sigcontext + ! to determine where they are. + std %0, [%sp+IREGSOFF] + std %2, [%sp+IREGSOFF+8] + std %4, [%sp+IREGSOFF+16] + std %6, [%sp+IREGSOFF+24] + std %o0, [%sp+IREGSOFF+32] + ld [%sp + OSCOFF+8], %o0 + std %o2, [%sp+IREGSOFF+40] + std %o4, [%sp+IREGSOFF+48] + st %o0, [%sp+IREGSOFF+56] + st %o7, [%sp+IREGSOFF+60] + + ldd [%o0], %16 + ldd [%o0+8], %18 + ldd [%o0+16], %20 + ldd [%o0+24], %22 + ldd [%o0+32], %24 + ldd [%o0+40], %26 + ldd [%o0+48], %28 + ldd [%o0+56], %30 + std %16, [%sp+IREGSOFF+64] + std %18, [%sp+IREGSOFF+72] + std %20, [%sp+IREGSOFF+80] + std %22, [%sp+IREGSOFF+88] + std %24, [%sp+IREGSOFF+96] + std %26, [%sp+IREGSOFF+104] + std %28, [%sp+IREGSOFF+112] + std %30, [%sp+IREGSOFF+120] + + ! Copy the original sigcontext down to our sigcontext. + ld [%sp + OSCOFF], %l0 + ld [%sp + OSCOFF+4], %l1 + ld [%sp + OSCOFF+8], %l2 + ld [%sp + OSCOFF+12], %l3 + ld [%sp + OSCOFF+16], %l4 + ld [%sp + OSCOFF+20], %l5 + ld [%sp + OSCOFF+24], %l6 + ld [%sp + OSCOFF+28], %l7 + std %l0, [%sp+SCOFF] + std %l2, [%sp+SCOFF+8] + std %l4, [%sp+SCOFF+16] + std %l6, [%sp+SCOFF+24] + + ! Check to see if we need to save the fp regs. + set PSR_EF, %l0 + mov %y, %l2 ! save y + btst %l0, %l5 ! is FPU enabled? + bz 1f ! if not skip FPU save + st %l2, [%sp + YOFF] + + std %f0, [%sp + FPREGSOFF+(0*4)] ! save all fpu registers. + std %f2, [%sp + FPREGSOFF+(2*4)] + std %f4, [%sp + FPREGSOFF+(4*4)] + std %f6, [%sp + FPREGSOFF+(6*4)] + std %f8, [%sp + FPREGSOFF+(8*4)] + std %f10, [%sp + FPREGSOFF+(10*4)] + std %f12, [%sp + FPREGSOFF+(12*4)] + std %f14, [%sp + FPREGSOFF+(14*4)] + std %f16, [%sp + FPREGSOFF+(16*4)] + std %f18, [%sp + FPREGSOFF+(18*4)] + std %f20, [%sp + FPREGSOFF+(20*4)] + std %f22, [%sp + FPREGSOFF+(22*4)] + std %f24, [%sp + FPREGSOFF+(24*4)] + std %f26, [%sp + FPREGSOFF+(26*4)] + std %f28, [%sp + FPREGSOFF+(28*4)] + std %f30, [%sp + FPREGSOFF+(30*4)] + st %fsr, [%sp + FSROFF] ! save old fsr +1: + + ld [%sp + SIGNUMOFF], %o0 ! get signal number + set __sigfunc, %g1 ! get array of function ptrs + sll %o0, 2, %g2 ! scale signal number for index + ld [%g1 + %g2], %g1 ! get func + ld [%sp + CODEOFF], %o1 ! get code + add %sp, SCOFF, %o2 ! compute scp + call %g1 ! (*_sigfunc[sig])(sig,code,scp,addr) + ld [%sp + ADDROFF], %o3 ! get addr + + ! Recompute scp, and call into _sigreturn + add %sp, SCOFF, %o0 + + + .global _sigreturn +_sigreturn: + ! Move values we can't restore directory into real sigcontext. + ld [%o0+32+(4*1)], %l0 ! g1 + ld [%o0+32+(4*8)], %l1 ! o0 + ld [%o0+32+(4*14)], %l2 ! sp + st %l0, [%o0+24] + st %l1, [%o0+28] + st %l2, [%o0+8] + + ld [%o0 + 20], %l2 ! get psr + set PSR_EF, %l0 + ld [%o0 + 288], %l1 ! restore y + btst %l0, %l2 ! is FPU enabled? + bz 2f ! if not skip FPU restore + mov %l1, %y + + ldd [%o0 + 160+(0*4)], %f0 ! restore all fpu registers. + ldd [%o0 + 160+(2*4)], %f2 + ldd [%o0 + 160+(4*4)], %f4 + ldd [%o0 + 160+(6*4)], %f6 + ldd [%o0 + 160+(8*4)], %f8 + ldd [%o0 + 160+(10*4)], %f10 + ldd [%o0 + 160+(12*4)], %f12 + ldd [%o0 + 160+(14*4)], %f14 + ldd [%o0 + 160+(16*4)], %f16 + ldd [%o0 + 160+(18*4)], %f18 + ldd [%o0 + 160+(20*4)], %f20 + ldd [%o0 + 160+(22*4)], %f22 + ldd [%o0 + 160+(24*4)], %f24 + ldd [%o0 + 160+(26*4)], %f26 + ldd [%o0 + 160+(28*4)], %f28 + ldd [%o0 + 160+(30*4)], %f30 + ld [%o0 + 160+(32*4)], %fsr ! restore old fsr +2: + + ! Restore the integer regs. + ldd [%o0 + 32+(2*4)], %2 + ldd [%o0 + 32+(4*4)], %4 + ldd [%o0 + 32+(6*4)], %6 + ld [%o0 + 32+(9*4)], %9 + ldd [%o0 + 32+(10*4)], %10 + ldd [%o0 + 32+(12*4)], %12 + ld [%o0 + 32+(15*4)], %15 + ldd [%o0 + 32+(16*4)], %16 + ldd [%o0 + 32+(18*4)], %18 + ldd [%o0 + 32+(20*4)], %20 + ldd [%o0 + 32+(22*4)], %22 + ldd [%o0 + 32+(24*4)], %24 + ldd [%o0 + 32+(26*4)], %26 + ldd [%o0 + 32+(28*4)], %28 + ldd [%o0 + 32+(30*4)], %30 + + set 139, %g1 ! sigcleanup system call + t 0 + unimp 0 ! just in case it returns + /*NOTREACHED*/ -- GitLab