365fbb99a25110bd60979f9d6f4a8d540e761de0
[sbcl.git] / src / code / mips-vm.lisp
1 (in-package "SB!VM")
2 \f
3 (define-alien-type os-context-t (struct os-context-t-struct))
4 \f
5 ;;;; MACHINE-TYPE and MACHINE-VERSION
6
7 (defun machine-type ()
8   "Returns a string describing the type of the local machine."
9   "MIPS")
10
11 (defun machine-version ()
12   "Returns a string describing the version of the local machine."
13   #!+little-endian "little-endian"
14   #!-little-endian "big-endian")
15
16 \f
17 ;;;; FIXUP-CODE-OBJECT
18
19 (defun fixup-code-object (code offset value kind)
20   (unless (zerop (rem offset n-word-bytes))
21     (error "Unaligned instruction?  offset=#x~X." offset))
22   (sb!sys:without-gcing
23    (let ((sap (truly-the system-area-pointer
24                          (%primitive sb!c::code-instructions code))))
25      (ecase kind
26        (:jump
27         (assert (zerop (ash value -28)))
28         (setf (ldb (byte 26 0) (sap-ref-32 sap offset))
29               (ash value -2)))
30        (:lui
31         (setf (sap-ref-16 sap 
32                           #!+little-endian offset
33                           #!-little-endian (+ offset 2))
34               (+ (ash value -16)
35                  (if (logbitp 15 value) 1 0))))
36        (:addi
37         (setf (sap-ref-16 sap 
38                           #!+little-endian offset
39                           #!-little-endian (+ offset 2))
40               (ldb (byte 16 0) value)))))))
41
42 \f
43 (define-alien-routine ("os_context_pc_addr" context-pc-addr) (* unsigned-int)
44   (context (* os-context-t)))
45
46 (defun context-pc (context)
47   (declare (type (alien (* os-context-t)) context))
48   ;; KLUDGE: this sucks, and furthermore will break on either of (a)
49   ;; porting back to IRIX or (b) running on proper 64-bit support.
50   ;; Linux on the MIPS defines its registers in the sigcontext as
51   ;; 64-bit quantities ("unsigned long long"), presumably to be
52   ;; binary-compatible with 64-bit mode.  Since there appears not to
53   ;; be ALIEN support for 64-bit return values, we have to do the
54   ;; hacky pointer arithmetic thing.  -- CSR, 2002-09-01
55   (int-sap (deref (context-pc-addr context) 
56                   #!-little-endian 1
57                   ;; Untested
58                   #!+little-endian 0)))
59
60 (define-alien-routine ("os_context_register_addr" context-register-addr)
61   (* unsigned-int)
62   (context (* os-context-t))
63   (index int))
64
65 (define-alien-routine ("os_context_bd_cause" context-bd-cause-int)
66     (unsigned 32)
67   (context (* os-context-t)))
68
69 ;;; FIXME: Should this and CONTEXT-PC be INLINE to reduce consing?
70 ;;; (Are they used in anything time-critical, or just the debugger?)
71 (defun context-register (context index)
72   (declare (type (alien (* os-context-t)) context))
73   (deref (context-register-addr context index) 
74          #!-little-endian 1
75          #!+little-endian 0))
76
77 (defun %set-context-register (context index new)
78   (declare (type (alien (* os-context-t)) context))
79   (setf (deref (context-register-addr context index) 
80                #!-little-endian 1
81                #!+little-endian 0)
82         new))
83
84 #!+linux
85 ;;; For now.
86 (defun context-floating-point-modes (context)
87   (declare (ignore context))
88   (warn "stub CONTEXT-FLOATING-POINT-MODES")
89   0)
90
91 ;;;; Internal-error-arguments.
92
93 ;;; INTERNAL-ERROR-ARGUMENTS -- interface.
94 ;;;
95 ;;; Given the sigcontext, extract the internal error arguments from the
96 ;;; instruction stream.
97 ;;; 
98 (defun internal-error-args (context)
99   (declare (type (alien (* os-context-t)) context))
100   (/show0 "entering INTERNAL-ERROR-ARGS, CONTEXT=..")
101   (/hexstr context)
102   (let ((pc (context-pc context))
103         (cause (context-bd-cause-int context)))
104     (declare (type system-area-pointer pc))
105     (/show0 "got PC=..")
106     (/hexstr (sap-int pc))
107     ;; KLUDGE: This exposure of the branch delay mechanism hurts.
108     (when (logbitp 31 cause)
109       (setf pc (sap+ pc 4)))
110     (when (= (sap-ref-8 pc 4) 255)
111       (setf pc (sap+ pc 1)))
112     (/show0 "now PC=..")
113     (/hexstr (sap-int pc))
114     (let* ((length (sap-ref-8 pc 4))
115            (vector (make-array length :element-type '(unsigned-byte 8))))
116       (declare (type (unsigned-byte 8) length)
117                (type (simple-array (unsigned-byte 8) (*)) vector))
118       (/show0 "LENGTH,VECTOR,ERROR-NUMBER=..")
119       (/hexstr length)
120       (/hexstr vector)
121       (copy-from-system-area pc (* n-byte-bits 5)
122                              vector (* n-word-bits
123                                        vector-data-offset)
124                              (* length n-byte-bits))
125       (let* ((index 0)
126              (error-number (sb!c::read-var-integer vector index)))
127         (/hexstr error-number)
128         (collect ((sc-offsets))
129          (loop
130           (/show0 "INDEX=..")
131           (/hexstr index)
132           (when (>= index length)
133             (return))
134           (sc-offsets (sb!c::read-var-integer vector index)))
135          (values error-number (sc-offsets)))))))
136
137
138
139
140