0.pre8.33
[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 "./signal.h"
22 #include "os.h"
23 #include "arch.h"
24 #include "globals.h"
25 #include "interrupt.h"
26 #include "interr.h"
27 #include "lispregs.h"
28 #include "sbcl.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 size_t os_vm_page_size;
40
41 struct thread *arch_os_get_current_thread() {
42     return all_threads;
43 }
44 struct thread *arch_os_thread_init() {
45     return 1;                   /* success */
46 }
47 struct thread *arch_os_thread_cleanup() {
48     return 1;                   /* success */
49 }
50
51 os_context_register_t   *
52 os_context_register_addr(os_context_t *context, int offset)
53 {
54     return &((context->uc_mcontext.regs)->gpr[offset]);
55 }
56
57 os_context_register_t *
58 os_context_pc_addr(os_context_t *context)
59 {
60     return &((context->uc_mcontext.regs)->nip);
61 }
62
63 os_context_register_t *
64 os_context_lr_addr(os_context_t *context)
65 {
66     return &((context->uc_mcontext.regs)->link);
67 }
68
69 sigset_t *
70 os_context_sigmask_addr(os_context_t *context)
71 {
72     return &context->uc_sigmask;
73 }
74
75 unsigned long
76 os_context_fp_control(os_context_t *context)
77 {
78     /* So this may look like nice, well behaved code. However, closer
79        inspection reveals that gpr is simply the general purpose
80        registers, and PT_FPSCR is an offset that is larger than 32
81        (the number of ppc registers), but that happens to get the
82        right answer. -- CSR, 2002-07-11 */
83     return context->uc_mcontext.regs->gpr[PT_FPSCR]; 
84 }
85
86 void 
87 os_restore_fp_control(os_context_t *context)
88 {
89     unsigned long control;
90     
91     control = os_context_fp_control(context) & 
92       /* FIXME: Should we preserve the user's requested rounding mode?
93
94          Note that doing 
95
96          ~(FLOAT_STICKY_BITS_MASK | FLOAT_EXCEPTIONS_BYTE_MASK)
97
98          here leads to infinite SIGFPE for invalid operations, as
99          there are bits in the control register that need to be
100          cleared that are let through by that mask. -- CSR, 2002-07-16 */
101       FLOAT_TRAPS_BYTE_MASK;
102     
103     /* FIXME: Shoot me now.
104        
105        Hardcoded nastiness: the "0"s below refer to the first floating
106        point registers -- we should let gcc deal with that. The 8(31)
107        refers to the position on the stack, less one, of control (we
108        need for control to be the high word of the double loaded by
109        lfd; how do I know that r31 contains the stack? I don't, I'm
110        just guessing. The 255, on the other hand, is a valid constant
111        -- it says "move everything in the upper word into the floating
112        point control register. -- CSR, 2002-07-16 */
113     asm ("stw %0, 12(31); lfd 0, 8(31); mtfsf 255, 0" : : "r" (control) : "r31");
114 }
115
116 void 
117 os_flush_icache(os_vm_address_t address, os_vm_size_t length)
118 {
119     /* see ppc-arch.c */
120     ppc_flush_icache(address,length);
121 }
122