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;
|