0.9.2.42:
[sbcl.git] / src / runtime / ppc-linux-os.c
1 /*
2  * This is the IBM/Motorola/Apple/whoever Linux incarnation of
3  * arch-dependent OS-dependent routines. See also "linux-os.c".  */
4
5 /*
6  * This software is part of the SBCL system. See the README file for
7  * more information.
8  *
9  * This software is derived from the CMU CL system, which was
10  * written at Carnegie Mellon University and released into the
11  * public domain. The software is in the public domain and is
12  * provided with absolutely no warranty. See the COPYING and CREDITS
13  * files for more information.
14  */
15
16 /* These header files were lifted wholesale from linux-os.c, some may
17  * be redundant. -- Dan Barlow ca. 2001-05-01 */
18 #include <stdio.h>
19 #include <sys/param.h>
20 #include <sys/file.h>
21 #include "sbcl.h"
22 #include "./signal.h"
23 #include "os.h"
24 #include "arch.h"
25 #include "globals.h"
26 #include "interrupt.h"
27 #include "interr.h"
28 #include "lispregs.h"
29 #include <sys/socket.h>
30 #include <sys/utsname.h>
31
32 #include <sys/types.h>
33 #include <signal.h>
34 #include <sys/time.h>
35 #include <sys/stat.h>
36 #include <unistd.h>
37
38 #include "validate.h"
39 #include "ppc-linux-mcontext.h"
40
41 size_t os_vm_page_size;
42
43 int arch_os_thread_init(struct thread *thread) {
44     return 1;                   /* success */
45 }
46 int arch_os_thread_cleanup(struct thread *thread) {
47     return 1;                   /* success */
48 }
49
50 os_context_register_t   *
51 os_context_register_addr(os_context_t *context, int offset)
52 {
53 #if defined(GLIBC231_STYLE_UCONTEXT)
54     return &((context->uc_mcontext.regs)->gpr[offset]);
55 #elif defined(GLIBC232_STYLE_UCONTEXT)
56     return &((context->uc_mcontext.uc_regs->gregs)[offset]);
57 #endif
58 }
59
60 os_context_register_t *
61 os_context_pc_addr(os_context_t *context)
62 {
63 #if defined(GLIBC231_STYLE_UCONTEXT)
64     return &((context->uc_mcontext.regs)->nip);
65 #elif defined(GLIBC232_STYLE_UCONTEXT)
66     return &((context->uc_mcontext.uc_regs->gregs)[PT_NIP]);
67 #endif
68 }
69
70 os_context_register_t *
71 os_context_lr_addr(os_context_t *context)
72 {
73 #if defined(GLIBC231_STYLE_UCONTEXT)
74     return &((context->uc_mcontext.regs)->link);
75 #elif defined(GLIBC232_STYLE_UCONTEXT)
76     return &((context->uc_mcontext.uc_regs->gregs)[PT_LNK]);
77 #endif
78 }
79
80 sigset_t *
81 os_context_sigmask_addr(os_context_t *context)
82 {
83 #if defined(GLIBC231_STYLE_UCONTEXT)
84     return &context->uc_sigmask;
85 #elif defined(GLIBC232_STYLE_UCONTEXT)
86     return &context->uc_sigmask;
87 #endif
88 }
89
90 unsigned long
91 os_context_fp_control(os_context_t *context)
92 {
93     /* So this may look like nice, well behaved code. However, closer
94        inspection reveals that gpr is simply the general purpose
95        registers, and PT_FPSCR is an offset that is larger than 32
96        (the number of ppc registers), but that happens to get the
97        right answer. -- CSR, 2002-07-11 */
98 #if defined(GLIBC231_STYLE_UCONTEXT)
99     return context->uc_mcontext.regs->gpr[PT_FPSCR];
100 #elif defined(GLIBC232_STYLE_UCONTEXT)
101     return context->uc_mcontext.uc_regs->gregs[PT_FPSCR];
102 #endif
103 }
104
105 void
106 os_restore_fp_control(os_context_t *context)
107 {
108     unsigned long control;
109     double d;
110
111     control = os_context_fp_control(context) &
112         /* FIXME: Should we preserve the user's requested rounding mode?
113
114         Note that doing
115
116         ~(FLOAT_STICKY_BITS_MASK | FLOAT_EXCEPTIONS_BYTE_MASK)
117
118         here leads to infinite SIGFPE for invalid operations, as
119         there are bits in the control register that need to be
120         cleared that are let through by that mask. -- CSR, 2002-07-16 */
121
122         FLOAT_TRAPS_BYTE_MASK;
123
124     d = *((double *) &control);
125     /* Hmp.  Apparently the following doesn't work either:
126
127     asm volatile ("mtfsf 0xff,%0" : : "f" (d));
128
129     causing segfaults at the first GC.
130     */
131 }
132
133 void
134 os_flush_icache(os_vm_address_t address, os_vm_size_t length)
135 {
136     /* see ppc-arch.c */
137     ppc_flush_icache(address,length);
138 }
139