[Git][cmucl/cmucl][sparc64-dev] Add more sparc64 files.
Raymond Toy
rtoy at common-lisp.net
Sat Dec 17 05:59:28 UTC 2016
Raymond Toy pushed to branch sparc64-dev at cmucl / cmucl
Commits:
314541e9 by Raymond Toy at 2016-12-16T21:59:14-08:00
Add more sparc64 files.
Config.sparc64_sunc and sparc64-assem.S are straight copies of the
corresponding sparc files.
- - - - -
2 changed files:
- + src/lisp/Config.sparc64_sunc
- + src/lisp/sparc64-assem.S
Changes:
=====================================
src/lisp/Config.sparc64_sunc
=====================================
--- /dev/null
+++ b/src/lisp/Config.sparc64_sunc
@@ -0,0 +1,31 @@
+# -*- Mode: makefile -*-
+
+# Build cmucl using Sun C compiler. We assume cc is Sun's C compiler.
+# If you don't have it, why are you using this Config anyway? You're
+# on your own if you use this Config without Sun C compiler available.
+
+include Config.sparc_common
+
+# For v8plus support (allows 64-bit integer support on V9
+# architectures), uncomment the definitions for CC_V8PLUS and
+# AS_V8PLUS. The -Wa,xarch=v8plus option tells the assembler to
+# accept v8plus instructions and generate a v8plus object files and
+# executable.
+#
+# However, we should also make sure the binary is marked as v8plus by
+# enabling AS_V8PLUS whenever we have the :sparc-v9 *feature* enabled
+# because we really are a v8plus application by using some of the v9
+# instructions, even if we don't use the 64-bit registers.
+
+ifdef FEATURE_SPARC_V9
+# For SunStudio 11, use -xarch=v8plus. For SunStudio 12, that is
+# deprecated; use -m32 -xarch=sparc.
+CC_V8PLUS = -xarch=sparc
+AS_V8PLUS = -xarch=sparc
+endif
+
+ASSEM_SRC = sparcv9-assem.S
+CFLAGS += -xlibmieee -O
+DEPEND_FLAGS = -xM
+ASFLAGS = $(AS_V8PLUS)
+OS_LINK_FLAGS = -M /usr/lib/ld/map.noexstk
=====================================
src/lisp/sparc64-assem.S
=====================================
--- /dev/null
+++ b/src/lisp/sparc64-assem.S
@@ -0,0 +1,565 @@
+
+#ifdef SOLARIS
+#define _ASM
+#include <sys/asm_linkage.h>
+#include <sys/psw.h>
+#include <sys/trap.h>
+#ifdef __STDC__
+#define FUNCDEF(x) .type x, \#function
+#else
+#define FUNCDEF(x) .type x, #function
+#endif
+#else
+#endif
+
+#define LANGUAGE_ASSEMBLY
+#include "lispregs.h"
+#include "internals.h"
+#include "globals.h"
+
+#define load(sym, reg) \
+ sethi %hi(sym), reg; ld [reg+%lo(sym)], reg
+#define store(reg, sym) \
+ sethi %hi(sym), reg_L0; st reg, [reg_L0+%lo(sym)]
+
+/*
+ * Our frame size needs to be large enough to hold our window,
+ * the structure return pointer, and some temp space. The temp space
+ * is to hold the 64-bit %o registers that might be converted to %i
+ * registers. A task switch will will not preserve all 64 bits of the
+ * %i registers, so we need to save our %o registers before entering C.
+ * Since %o0 and %o1 contain the return results, we do not have to save
+ * these.
+ */
+#ifdef v8plus
+#define FRAMESIZE (SA(WINDOWSIZE+4 + 6*8))
+#else
+#define FRAMESIZE (SA(MINFRAME))
+#endif
+ .seg "text"
+ .global call_into_lisp
+ FUNCDEF(call_into_lisp)
+call_into_lisp:
+ save %sp, -FRAMESIZE, %sp
+ /* Flush all of C's register windows to the stack. */
+ ta ST_FLUSH_WINDOWS
+
+ /* Save the return address. */
+ st %i7, [%fp-4]
+
+ /* Clear the descriptor regs. (See sparc/vm.lisp) */
+ mov reg_ZERO, reg_A0
+ mov reg_ZERO, reg_A1
+ mov reg_ZERO, reg_A2
+ mov reg_ZERO, reg_A3
+ mov reg_ZERO, reg_A4
+ mov reg_ZERO, reg_A5
+ mov reg_ZERO, reg_OCFP
+ mov reg_ZERO, reg_LRA
+ mov reg_ZERO, reg_CODE
+
+ /* Establish NIL */
+ set NIL, reg_NIL
+
+ /* Set the pseudo-atomic flag. */
+ set pseudo_atomic_Value, reg_ALLOC
+
+ /* Turn off foreign function call. */
+ sethi %hi(foreign_function_call_active), reg_NL0
+ st reg_ZERO, [reg_NL0+%lo(foreign_function_call_active)]
+
+ /* Load the rest of lisp state. */
+ load(current_dynamic_space_free_pointer, reg_NL0)
+ add reg_NL0, reg_ALLOC, reg_ALLOC
+ load(current_binding_stack_pointer, reg_BSP)
+ load(current_control_stack_pointer, reg_CSP)
+ load(current_control_frame_pointer, reg_OCFP)
+
+ /* No longer atomic, and check for interrupt. */
+ andn reg_ALLOC, pseudo_atomic_Value, reg_ALLOC
+ andcc reg_ALLOC, pseudo_atomic_InterruptedValue, reg_ZERO
+ tne trap_PseudoAtomic
+
+ /* Pass in the args. */
+ sll %i2, 2, reg_NARGS
+ mov %i1, reg_CFP
+ mov %i0, reg_LEXENV
+ ld [reg_CFP+0], reg_A0
+ ld [reg_CFP+4], reg_A1
+ ld [reg_CFP+8], reg_A2
+ ld [reg_CFP+12], reg_A3
+ ld [reg_CFP+16], reg_A4
+ ld [reg_CFP+20], reg_A5
+
+ /* Calculate LRA */
+ set lra + type_OtherPointer, reg_LRA
+
+ /* Indirect closure */
+ ld [reg_LEXENV+CLOSURE_FUNCTION_OFFSET], reg_CODE
+
+ jmp reg_CODE+FUNCTION_CODE_OFFSET
+ nop
+
+ .align 8
+lra:
+ .word type_ReturnPcHeader
+
+ /* Blow off any extra values. */
+ mov reg_OCFP, reg_CSP
+ nop
+
+ /* Return the one value. */
+ mov reg_A0, %i0
+
+ /* Turn on pseudo_atomic */
+ or reg_ALLOC, pseudo_atomic_Value, reg_ALLOC
+
+ /* Store LISP state */
+ andn reg_ALLOC, lowtag_Mask, reg_NL1
+ store(reg_NL1,current_dynamic_space_free_pointer)
+ store(reg_BSP,current_binding_stack_pointer)
+ store(reg_CSP,current_control_stack_pointer)
+ store(reg_CFP,current_control_frame_pointer)
+
+ /* No longer in Lisp. */
+ store(reg_NL1,foreign_function_call_active)
+
+ /* Were we interrupted? */
+ andn reg_ALLOC, pseudo_atomic_Value, reg_ALLOC
+ andcc reg_ALLOC, pseudo_atomic_InterruptedValue, reg_ZERO
+ tne trap_PseudoAtomic
+
+ /* Back to C we go. */
+ ld [%sp+FRAMESIZE-4], %i7
+ ret
+ restore %sp, FRAMESIZE, %sp
+ SET_SIZE(call_into_lisp)
+
+
+
+ .global call_into_c
+ FUNCDEF(call_into_c)
+call_into_c:
+#ifdef v8plus
+ stx %o2, [%fp - 8 - 1*8]
+ stx %o3, [%fp - 8 - 2*8]
+ stx %o4, [%fp - 8 - 3*8]
+ stx %o5, [%fp - 8 - 4*8]
+ stx %o6, [%fp - 8 - 5*8]
+ stx %o7, [%fp - 8 - 6*8]
+#endif
+ /* Build a lisp stack frame */
+ mov reg_CFP, reg_OCFP
+ mov reg_CSP, reg_CFP
+ add reg_CSP, 32, reg_CSP
+ st reg_OCFP, [reg_CFP]
+ st reg_CODE, [reg_CFP+8]
+
+ /* Turn on pseudo-atomic. */
+ or reg_ALLOC, pseudo_atomic_Value, reg_ALLOC
+
+ /* Convert the return address to an offset and save it on the stack. */
+ sub reg_LIP, reg_CODE, reg_L0
+ add reg_L0, type_OtherPointer, reg_L0
+ st reg_L0, [reg_CFP+4]
+
+ /* Store LISP state */
+ store(reg_BSP,current_binding_stack_pointer)
+ store(reg_CSP,current_control_stack_pointer)
+ store(reg_CFP,current_control_frame_pointer)
+
+ /* Use reg_CFP as a work register, and restore it */
+ andn reg_ALLOC, lowtag_Mask, reg_CFP
+ store(reg_CFP,current_dynamic_space_free_pointer)
+ load(current_control_frame_pointer, reg_CFP)
+
+ /* No longer in Lisp. */
+ store(reg_CSP,foreign_function_call_active)
+
+ /* Were we interrupted? */
+ andn reg_ALLOC, pseudo_atomic_Value, reg_ALLOC
+ andcc reg_ALLOC, pseudo_atomic_InterruptedValue, reg_ZERO
+ tne trap_PseudoAtomic
+
+ /* Into C we go. */
+ call reg_CFUNC
+ nop
+
+ /*
+ * Note: C calling conventions (32-bit) say that %o0 and %o1
+ * are used to return function results. In particular 64-bit
+ * results are in %o0 (hi) and %o1 (low).
+ */
+
+ /* Re-establish NIL */
+ set NIL, reg_NIL
+
+ /* Atomic. */
+ set pseudo_atomic_Value, reg_ALLOC
+
+ /* No longer in foreign function call. */
+ sethi %hi(foreign_function_call_active), reg_NL2
+ st reg_ZERO, [reg_NL2+%lo(foreign_function_call_active)]
+
+ /* Load the rest of lisp state. */
+ load(current_dynamic_space_free_pointer, reg_NL2)
+ add reg_NL2, reg_ALLOC, reg_ALLOC
+ load(current_binding_stack_pointer, reg_BSP)
+ load(current_control_stack_pointer, reg_CSP)
+ load(current_control_frame_pointer, reg_CFP)
+
+ /* Get the return address back. */
+ ld [reg_CFP+4], reg_LIP
+ ld [reg_CFP+8], reg_CODE
+ add reg_LIP, reg_CODE, reg_LIP
+ sub reg_LIP, type_OtherPointer, reg_LIP
+
+ /* No longer atomic. */
+ andn reg_ALLOC, pseudo_atomic_Value, reg_ALLOC
+ andcc reg_ALLOC, pseudo_atomic_InterruptedValue, reg_ZERO
+ tne trap_PseudoAtomic
+
+ /* Reset the lisp stack. */
+ /* Note: OCFP is in one of the locals, it gets preserved across C. */
+ mov reg_CFP, reg_CSP
+ mov reg_OCFP, reg_CFP
+
+#ifdef v8plus
+ ldx [%fp - 8 - 1*8], %o2
+ ldx [%fp - 8 - 2*8], %o3
+ ldx [%fp - 8 - 3*8], %o4
+ ldx [%fp - 8 - 4*8], %o5
+ ldx [%fp - 8 - 5*8], %o6
+ ldx [%fp - 8 - 6*8], %o7
+#endif
+ /* And back into lisp. */
+ ret
+ nop
+
+ SET_SIZE(call_into_c)
+
+#if 0
+/* undefined_tramp and closure_tramp are now Lisp assembly routines.
+ * so we don't need these anymore. Leave them here for a bit so
+ * we can look at the "real" versions for a while. But eventually,
+ * remove these.
+ */
+ .global _undefined_tramp
+ FUNCDEF(_undefined_tramp)
+ .align 8
+ .byte 0
+_undefined_tramp:
+ .byte 0, 0, type_FunctionHeader
+ .word _undefined_tramp
+ .word NIL
+ .word NIL
+ .word NIL
+ .word NIL
+
+ b 1f
+ unimp trap_Cerror
+ /* Number of argument bytes */
+ .byte 4
+ .byte UNDEFINED_SYMBOL_ERROR
+ /* Escape to create 16bit number from following two bytes,
+ in little-endian order */
+ .byte 254
+ /* SC_OFFSET(sc_DescriptorReg,reg_FDEFN) */
+ .byte SC_OFFSET_LO(sc_DescriptorReg,reg_FDEFN_NUM)
+ .byte SC_OFFSET_HI(sc_DescriptorReg,reg_FDEFN_NUM)
+
+ .align 4
+1:
+ ld [reg_FDEFN+FDEFN_RAW_ADDR_OFFSET], reg_CODE
+ jmp reg_CODE+FUNCTION_CODE_OFFSET
+ nop
+ SET_SIZE(_undefined_tramp)
+
+ .global _closure_tramp
+ FUNCDEF(_closure_tramp)
+ .align 8
+ .byte 0
+_closure_tramp:
+ .byte 0, 0, type_FunctionHeader
+ .word _closure_tramp
+ .word NIL
+ .word NIL
+ .word NIL
+ .word NIL
+
+ ld [reg_FDEFN+FDEFN_FUNCTION_OFFSET], reg_LEXENV
+ ld [reg_LEXENV+CLOSURE_FUNCTION_OFFSET], reg_CODE
+ jmp reg_CODE+FUNCTION_CODE_OFFSET
+ nop
+ SET_SIZE(_closure_tramp)
+#endif
+
+
+/*
+ * Function-end breakpoint magic.
+ */
+
+ .text
+ .align 8
+ .global function_end_breakpoint_guts
+function_end_breakpoint_guts:
+ .word type_ReturnPcHeader
+ b 1f
+ nop
+ mov reg_CSP, reg_OCFP
+ add 4, reg_CSP, reg_CSP
+ mov 4, reg_NARGS
+ mov reg_NIL, reg_A1
+ mov reg_NIL, reg_A2
+ mov reg_NIL, reg_A3
+ mov reg_NIL, reg_A4
+ mov reg_NIL, reg_A5
+1:
+
+ .global function_end_breakpoint_trap
+function_end_breakpoint_trap:
+ unimp trap_FunctionEndBreakpoint
+ b 1b
+ nop
+
+ .global function_end_breakpoint_end
+function_end_breakpoint_end:
+
+ .global flush_icache
+ FUNCDEF(flush_icache)
+flush_icache:
+ add %o0,%o1,%o2
+1: iflush %o0 ! flush instruction cache
+ add %o0,8,%o0
+ cmp %o0,%o2
+ blt 1b
+ nop
+ retl ! return from leaf routine
+ nop
+ SET_SIZE(flush_icache)
+
+ .global do_pending_interrupt
+ FUNCDEF(do_pending_interrupt)
+do_pending_interrupt:
+ unimp trap_PendingInterrupt
+ retl
+ nop
+ SET_SIZE(do_pending_interrupt)
+
+#ifdef trap_DynamicSpaceOverflowError
+ .global do_dynamic_space_overflow_error
+ FUNCDEF(do_dynamic_space_overflow_error)
+do_dynamic_space_overflow_error:
+ unimp trap_DynamicSpaceOverflowError
+ retl
+ nop
+ SET_SIZE(do_dynamic_space_overflow_error)
+#endif
+
+#ifdef trap_DynamicSpaceOverflowWarning
+ .global do_dynamic_space_overflow_warning
+ FUNCDEF(do_dynamic_space_overflow_warning)
+do_dynamic_space_overflow_warning:
+ unimp trap_DynamicSpaceOverflowWarning
+ retl
+ nop
+ SET_SIZE(do_dynamic_space_overflow_warning)
+#endif
+
+#ifdef LINKAGE_TABLE
+/*
+ * Call into C code to resolve a linkage entry.
+ *
+ * We get here by Lisp calling call_into_c with an address of the
+ * desired function which is contained in the register reg_CFUNC (aka
+ * %i4, aka %r28). This is the address of the entry in the linkage
+ * table, which is what we need to figure out what function we really
+ * wanted.
+ *
+ * Note that because we get here from call_into_c, all necessary live
+ * registers have been saved, including FP registers. Hence, no need
+ * to save them.
+ */
+ .global lazy_resolve_linkage
+ .global resolve_linkage_tramp
+ FUNCDEF(resolve_linkage_tramp)
+resolve_linkage_tramp:
+ /*
+ * At this point, all of the global %g registers have been
+ * saved by call_into_c, so we can use them as temps. %g2,
+ * aka reg_NIL, aka null-tn is a good choice. reg_L0 contains
+ * the address of the jmpl instruction in the linkage jump
+ * table. (See sparc-arch.c.)
+ */
+
+ mov reg_L0, reg_NIL
+
+ /*
+ * New stack frame so the %o regs become %i. We can't touch
+ * the original %o because they contain the parameters to the
+ * function!
+ */
+ save %sp, -FRAMESIZE, %sp
+
+ /* %g2 tells where we came from in the linkage table */
+ call lazy_resolve_linkage
+ mov reg_NIL, %o0 ! in the delay slot
+
+ mov %o0, reg_NIL
+ restore %sp, FRAMESIZE, %sp
+
+ /* And away we go! */
+ jmp reg_NIL
+ nop
+
+ SET_SIZE(resolve_linkage_tramp)
+
+ .global undefined_foreign_symbol_trap
+ FUNCDEF(undefined_foreign_symbol_trap)
+/*
+ * When we get called, %o0 contains the address of the data_vector object
+ * which is a string naming the bad symbol.
+ */
+undefined_foreign_symbol_trap:
+ /*
+ Need to restore all the global registers with the Lisp values that
+ were saved away in call_into_c. (This routine is only called from
+ os_link_one_symbol, which is called from resolve_linkage_tramp, which
+ is called from call_into_c.)
+
+ The global registers are volatile across function calls, so who
+ knows what values have been they contain now!
+
+ */
+
+ load(current_dynamic_space_free_pointer, reg_ALLOC)
+ load(current_binding_stack_pointer, reg_BSP)
+ load(current_control_stack_pointer, reg_CSP)
+ load(current_control_frame_pointer, reg_CFP)
+
+ set NIL, reg_NIL
+
+ mov %o0, reg_A0
+ unimp trap_Error
+ .byte 4 /* Number of argument bytes */
+ .byte UNDEFINED_FOREIGN_SYMBOL_ERROR
+ /* Escape to create 16bit number from following two bytes, in
+ little-endian order */
+ .byte 254
+ .byte SC_OFFSET_LO(sc_DescriptorReg, reg_A0_NUM)
+ .byte SC_OFFSET_HI(sc_DescriptorReg, reg_A0_NUM)
+ .align 4
+
+#endif
+/*
+ * Save the FPU state. %o0 contains a pointer to where we can
+ * store our state.
+ */
+
+/*
+ * Note we only save the 16 double-float registers (which saves
+ * the 32 single-float values too, I think). If we're compiling for
+ * a sparc v9, the Lisp code can actually use all 32 double-float
+ * registers. For later.
+ */
+ .global fpu_save
+ FUNCDEF(fpu_save)
+fpu_save:
+ std %f0, [%o0 + 4*0]
+ std %f2, [%o0 + 4*2]
+ std %f4, [%o0 + 4*4]
+ std %f6, [%o0 + 4*6]
+ std %f8, [%o0 + 4*8]
+ std %f10, [%o0 + 4*10]
+ std %f12, [%o0 + 4*12]
+ std %f14, [%o0 + 4*14]
+ std %f16, [%o0 + 4*16]
+ std %f18, [%o0 + 4*18]
+ std %f20, [%o0 + 4*20]
+ std %f22, [%o0 + 4*22]
+ std %f24, [%o0 + 4*24]
+ std %f26, [%o0 + 4*26]
+ std %f28, [%o0 + 4*28]
+ std %f30, [%o0 + 4*30]
+#ifdef FEATURE_SPARC_V9
+ std %f32, [%o0 + 4*32]
+ std %f34, [%o0 + 4*34]
+ std %f36, [%o0 + 4*36]
+ std %f38, [%o0 + 4*38]
+ std %f40, [%o0 + 4*40]
+ std %f42, [%o0 + 4*42]
+ std %f44, [%o0 + 4*44]
+ std %f46, [%o0 + 4*46]
+ std %f48, [%o0 + 4*48]
+ std %f50, [%o0 + 4*50]
+ std %f52, [%o0 + 4*52]
+ std %f54, [%o0 + 4*54]
+ std %f56, [%o0 + 4*56]
+ std %f58, [%o0 + 4*58]
+ std %f60, [%o0 + 4*60]
+ std %f62, [%o0 + 4*62]
+ st %fsr, [%o0 + 4*64]
+#else
+ st %fsr, [%o0 + 4*32]
+#endif
+ retl
+ nop
+ SET_SIZE(fpu_save)
+
+ .global fpu_restore
+ FUNCDEF(fpu_restore)
+fpu_restore:
+ ldd [%o0 + 4*0], %f0
+ ldd [%o0 + 4*2], %f2
+ ldd [%o0 + 4*4], %f4
+ ldd [%o0 + 4*6], %f6
+ ldd [%o0 + 4*8], %f8
+ ldd [%o0 + 4*10], %f10
+ ldd [%o0 + 4*12], %f12
+ ldd [%o0 + 4*14], %f14
+ ldd [%o0 + 4*16], %f16
+ ldd [%o0 + 4*18], %f18
+ ldd [%o0 + 4*20], %f20
+ ldd [%o0 + 4*22], %f22
+ ldd [%o0 + 4*24], %f24
+ ldd [%o0 + 4*26], %f26
+ ldd [%o0 + 4*28], %f28
+ ldd [%o0 + 4*30], %f30
+#ifdef FEATURE_SPARC_V9
+ ldd [%o0 + 4*32], %f32
+ ldd [%o0 + 4*34], %f34
+ ldd [%o0 + 4*36], %f36
+ ldd [%o0 + 4*38], %f38
+ ldd [%o0 + 4*40], %f40
+ ldd [%o0 + 4*42], %f42
+ ldd [%o0 + 4*44], %f44
+ ldd [%o0 + 4*46], %f46
+ ldd [%o0 + 4*48], %f48
+ ldd [%o0 + 4*50], %f50
+ ldd [%o0 + 4*52], %f52
+ ldd [%o0 + 4*54], %f54
+ ldd [%o0 + 4*56], %f56
+ ldd [%o0 + 4*58], %f58
+ ldd [%o0 + 4*60], %f60
+ ldd [%o0 + 4*62], %f62
+ ld [%o0 + 4*64], %fsr
+#else
+ ld [%o0 + 4*32], %fsr
+#endif
+ retl
+ nop
+ SET_SIZE(fpu_restore)
+
+ .global save_context
+ FUNCDEF(save_context)
+save_context:
+ ta ST_FLUSH_WINDOWS ! flush register windows
+ retl ! return from leaf routine
+ nop
+ SET_SIZE(save_context)
+/*
+ * Local variables:
+ * tab-width: 8
+ * End:
+ */
+
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/commit/314541e9622792aefdecbce2f53762e307f2b42c
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/cmucl-cvs/attachments/20161217/6176719d/attachment-0001.html>
More information about the cmucl-cvs
mailing list