Raymond Toy pushed to branch sparc64-dev at cmucl / cmucl
Commits:
-
794b815a
by Raymond Toy at 2017-01-17T20:33:48-08:00
-
155b792b
by Raymond Toy at 2017-01-17T20:34:36-08:00
-
87731e87
by Raymond Toy at 2017-01-17T20:35:03-08:00
-
67a3752d
by Raymond Toy at 2017-01-18T19:29:29-08:00
-
3f4030a7
by Raymond Toy at 2017-01-18T20:50:48-08:00
-
06617844
by Raymond Toy at 2017-01-18T20:53:28-08:00
8 changed files:
- src/compiler/backend.lisp
- src/compiler/meta-vmdef.lisp
- src/compiler/sparc64/call.lisp
- src/compiler/sparc64/insts.lisp
- src/compiler/sparc64/move.lisp
- src/compiler/sparc64/parms.lisp
- src/lisp/solaris-os.c
- src/lisp/sparc-arch.c
Changes:
... | ... | @@ -114,6 +114,24 @@ |
114 | 114 |
(backend-support-routines *target-backend*))
|
115 | 115 |
#',local-name))))
|
116 | 116 |
|
117 |
+(defmacro def-vm-support-routine (name ll &body body)
|
|
118 |
+ (unless (member (intern (string name) (find-package "C"))
|
|
119 |
+ vm-support-routines)
|
|
120 |
+ (warn (intl:gettext "Unknown VM support routine: ~A") name))
|
|
121 |
+ (let ((local-name (symbolicate (backend-name *target-backend*) "-" name)))
|
|
122 |
+ `(progn
|
|
123 |
+ (defun ,local-name
|
|
124 |
+ ,ll
|
|
125 |
+ (macrolet ((vm::emit-not-implemented ()
|
|
126 |
+ `(vm::not-implemented ,',local-name)))
|
|
127 |
+ ,@body))
|
|
128 |
+ (setf (,(intern (concatenate 'simple-string
|
|
129 |
+ "VM-SUPPORT-ROUTINES-"
|
|
130 |
+ (string name))
|
|
131 |
+ (find-package "C"))
|
|
132 |
+ (backend-support-routines *target-backend*))
|
|
133 |
+ #',local-name))))
|
|
134 |
+ |
|
117 | 135 |
|
118 | 136 |
|
119 | 137 |
;;;; The backend structure.
|
... | ... | @@ -937,8 +937,10 @@ |
937 | 937 |
,@(binds))
|
938 | 938 |
(declare (ignore ,@(vop-parse-ignores parse)))
|
939 | 939 |
,@(loads)
|
940 |
- (new-assem:assemble (*code-segment* ,n-vop)
|
|
941 |
- ,@(vop-parse-body parse))
|
|
940 |
+ (macrolet ((vm::emit-not-implemented ()
|
|
941 |
+ `(vm::not-implemented ,',(vop-parse-name parse))))
|
|
942 |
+ (new-assem:assemble (*code-segment* ,n-vop)
|
|
943 |
+ ,@(vop-parse-body parse)))
|
|
942 | 944 |
,@(saves))))))
|
943 | 945 |
|
944 | 946 |
|
... | ... | @@ -179,6 +179,9 @@ |
179 | 179 |
(dotimes (i (1- vm:function-code-offset))
|
180 | 180 |
(inst word 0)
|
181 | 181 |
(inst word 0))
|
182 |
+ |
|
183 |
+ (emit-not-implemented)
|
|
184 |
+ |
|
182 | 185 |
;; The start of the actual code.
|
183 | 186 |
;; Fix CODE, cause the function object was passed in.
|
184 | 187 |
(inst compute-code-from-fn code-tn code-tn start-lab temp)
|
... | ... | @@ -1534,6 +1534,31 @@ about function addresses and register values.") |
1534 | 1534 |
(sc-offsets)
|
1535 | 1535 |
(lengths))))))))
|
1536 | 1536 |
|
1537 |
+(defun snarf-not-implemented-name (stream dstate)
|
|
1538 |
+ (let* ((sap (disassem:dstate-segment-sap dstate))
|
|
1539 |
+ (offset (disassem:dstate-next-offs dstate))
|
|
1540 |
+ (branch-inst (sys:sap-ref-32 sap offset)))
|
|
1541 |
+ ;; sap + offset should point to the branch instruction after the
|
|
1542 |
+ ;; illtrap (unimp) instruction. Make sure it's an unconditional
|
|
1543 |
+ ;; branch instrution.
|
|
1544 |
+ #+nil
|
|
1545 |
+ (unless (= (ldb (byte 8 24) branch-inst) #xea)
|
|
1546 |
+ (return-from snarf-not-implemented-name ""))
|
|
1547 |
+ ;; From the offset in the branch instruction, compute the max
|
|
1548 |
+ ;; length of the string that was encoded.
|
|
1549 |
+ (let ((max-length (+ (ash (ldb (byte 24 0) branch-inst) 2) 4)))
|
|
1550 |
+ ;; Skip the branch instruction
|
|
1551 |
+ (incf offset 4)
|
|
1552 |
+ ;; Print each following byte until max-length is reached or we
|
|
1553 |
+ ;; get a 0 byte.
|
|
1554 |
+ (with-output-to-string (s)
|
|
1555 |
+ (do* ((k 0 (+ k 1))
|
|
1556 |
+ (octet (sys:sap-ref-8 sap (+ offset k))
|
|
1557 |
+ (sys:sap-ref-8 sap (+ offset k))))
|
|
1558 |
+ ((or (>= k max-length)
|
|
1559 |
+ (zerop octet)))
|
|
1560 |
+ (write-char (code-char octet) s))))))
|
|
1561 |
+ |
|
1537 | 1562 |
(defun unimp-control (chunk inst stream dstate)
|
1538 | 1563 |
(declare (ignore inst))
|
1539 | 1564 |
(flet ((nt (x) (if stream (disassem:note x dstate))))
|
... | ... | @@ -1556,6 +1581,10 @@ about function addresses and register values.") |
1556 | 1581 |
(nt "Function end breakpoint trap"))
|
1557 | 1582 |
(#.vm:object-not-instance-trap
|
1558 | 1583 |
(nt "Object not instance trap"))
|
1584 |
+ (#.vm::not-implemented-trap
|
|
1585 |
+ (nt (concatenate 'string
|
|
1586 |
+ "Not-implemented trap: "
|
|
1587 |
+ (snarf-not-implemented-name stream dstate))))
|
|
1559 | 1588 |
)))
|
1560 | 1589 |
|
1561 | 1590 |
(eval-when (compile load eval)
|
... | ... | @@ -2252,6 +2281,26 @@ about function addresses and register values.") |
2252 | 2281 |
|
2253 | 2282 |
|
2254 | 2283 |
|
2284 |
+(defmacro not-implemented (&optional name)
|
|
2285 |
+ (let ((string (string name)))
|
|
2286 |
+ `(let ((length-label (gen-label)))
|
|
2287 |
+ (new-assem:without-scheduling ()
|
|
2288 |
+ (inst unimp not-implemented-trap)
|
|
2289 |
+ ;; NOTE: The branch offset helps estimate the length of the
|
|
2290 |
+ ;; string. The actual length of the string may be equal to the
|
|
2291 |
+ ;; displacement or it may be up to three bytes shorter at the
|
|
2292 |
+ ;; first trailing NUL byte. The string may or may not be
|
|
2293 |
+ ;; 0-terminated.
|
|
2294 |
+ (inst b length-label)
|
|
2295 |
+ (inst nop)
|
|
2296 |
+ ,@(map 'list #'(lambda (c)
|
|
2297 |
+ `(inst byte ,(char-code c)))
|
|
2298 |
+ string)
|
|
2299 |
+ ;; Append enough zeros to end on a word boundary.
|
|
2300 |
+ ,@(make-list (mod (- (length string)) 4)
|
|
2301 |
+ :initial-element '(inst byte 0))
|
|
2302 |
+ (emit-label length-label)))))
|
|
2303 |
+ |
|
2255 | 2304 |
;;;; Instructions for dumping data and header objects.
|
2256 | 2305 |
|
2257 | 2306 |
(define-instruction word (segment word)
|
... | ... | @@ -74,6 +74,7 @@ |
74 | 74 |
|
75 | 75 |
(define-move-function (store-stack 5) (vop x y)
|
76 | 76 |
((any-reg descriptor-reg) (control-stack))
|
77 |
+ (not-implemented "DEFINE-MOVE STORE-STACK")
|
|
77 | 78 |
(store-stack-tn y x))
|
78 | 79 |
|
79 | 80 |
(define-move-function (store-number-stack 5) (vop x y)
|
... | ... | @@ -243,6 +243,7 @@ |
243 | 243 |
after-breakpoint-trap allocation-trap
|
244 | 244 |
pseudo-atomic-trap
|
245 | 245 |
object-not-list-trap object-not-instance-trap
|
246 |
+ not-implemented-trap
|
|
246 | 247 |
trace-table-normal trace-table-call-site
|
247 | 248 |
trace-table-function-prologue trace-table-function-epilogue))
|
248 | 249 |
|
... | ... | @@ -263,10 +264,11 @@ |
263 | 264 |
dynamic-space-overflow-warning
|
264 | 265 |
#+heap-overflow-check
|
265 | 266 |
dynamic-space-overflow-error
|
267 |
+ not-implemented
|
|
266 | 268 |
)
|
267 | 269 |
|
268 | 270 |
;; Make sure this starts AFTER the last element of the above enum!
|
269 |
-(defenum (:prefix object-not- :suffix -trap :start 16)
|
|
271 |
+(defenum (:prefix object-not- :suffix -trap :start 20)
|
|
270 | 272 |
list
|
271 | 273 |
instance)
|
272 | 274 |
|
... | ... | @@ -315,7 +315,7 @@ long * |
315 | 315 |
solaris_register_address(struct ucontext *context, int reg)
|
316 | 316 |
{
|
317 | 317 |
if (reg == 0) {
|
318 |
- static int zero;
|
|
318 |
+ static long zero;
|
|
319 | 319 |
|
320 | 320 |
zero = 0;
|
321 | 321 |
|
... | ... | @@ -323,7 +323,7 @@ solaris_register_address(struct ucontext *context, int reg) |
323 | 323 |
} else if (reg < 16) {
|
324 | 324 |
return &context->uc_mcontext.gregs[reg + 3];
|
325 | 325 |
} else if (reg < 32) {
|
326 |
- int *sp = (int *) context->uc_mcontext.gregs[REG_SP];
|
|
326 |
+ long *sp = (long *) context->uc_mcontext.gregs[REG_SP];
|
|
327 | 327 |
|
328 | 328 |
return &sp[reg - 16];
|
329 | 329 |
} else
|
... | ... | @@ -510,6 +510,53 @@ sigill_handler(HANDLER_ARGS) |
510 | 510 |
os_context);
|
511 | 511 |
break;
|
512 | 512 |
#endif
|
513 |
+#ifdef trap_NotImplemented
|
|
514 |
+ case trap_NotImplemented:
|
|
515 |
+ {
|
|
516 |
+ /*
|
|
517 |
+ * Print out the name. The next instruction MUST be a
|
|
518 |
+ * branch immediate.
|
|
519 |
+ */
|
|
520 |
+ unsigned char *string;
|
|
521 |
+ int length;
|
|
522 |
+ |
|
523 |
+ /*
|
|
524 |
+ * Compute the maximum length of the string from the
|
|
525 |
+ * offset in the branch instruction. This code assumes
|
|
526 |
+ * a ba,pt instruction which has a 19-bit word offset in
|
|
527 |
+ * the low part of the instruction. Because branches
|
|
528 |
+ * have a delay slot, the string starts two words past
|
|
529 |
+ * the branch instruction.
|
|
530 |
+ */
|
|
531 |
+ string = (unsigned char *) &pc[3];
|
|
532 |
+ /*
|
|
533 |
+ * The offset is in 32-bit words, so subtract one for
|
|
534 |
+ * the instruction in the branch delay slot and scale up
|
|
535 |
+ * the offet to be in bytes.
|
|
536 |
+ */
|
|
537 |
+ length = 4 * ((pc[1] & 0x7FFFF) - 1);
|
|
538 |
+ |
|
539 |
+ while (string[length - 1] == '\0') {
|
|
540 |
+ --length;
|
|
541 |
+ }
|
|
542 |
+ |
|
543 |
+ /*
|
|
544 |
+ * Don't want to use NOT_IMPLEMENTED here because we
|
|
545 |
+ * don't actually want to abort. We want to continue,
|
|
546 |
+ * but print out a useful message.
|
|
547 |
+ */
|
|
548 |
+ printf("NOT-IMPLEMENTED: %p: \"%.*s\"\n", pc, length, string);
|
|
549 |
+ |
|
550 |
+ /*
|
|
551 |
+ * Skip over the illtrap instruction so if we can
|
|
552 |
+ * continue. This will execute the branch, skipping
|
|
553 |
+ * over the string too.
|
|
554 |
+ */
|
|
555 |
+ SC_PC(os_context) = (unsigned long) (pc + 1);
|
|
556 |
+
|
|
557 |
+ }
|
|
558 |
+ break;
|
|
559 |
+#endif
|
|
513 | 560 |
default:
|
514 | 561 |
interrupt_handle_now(signal, code, os_context);
|
515 | 562 |
break;
|