diff --git a/compiler/backend/x86-64/codegen.lisp b/compiler/backend/x86-64/codegen.lisp index f504137f0..da3510588 100644 --- a/compiler/backend/x86-64/codegen.lisp +++ b/compiler/backend/x86-64/codegen.lisp @@ -148,7 +148,7 @@ for i from 0 for elt across *current-frame-layout* do (when (not (zerop elt)) - (emit `(lap:mov64 (:stack ,i) nil))))) + (emit `(lap:mov64 (:stack ,i) :r14))))) (emit-gc-info :incoming-arguments :rcx) (ir:do-instructions (inst-or-label backend-function) (emit-debug-info (gethash inst-or-label debug-map '()) *spill-locations*) @@ -177,51 +177,52 @@ (defmethod emit-lap (backend-function (instruction ir:argument-setup-instruction) uses defs) ;; Check the argument count. - (let ((args-ok (mezzano.lap:make-label :args-ok))) - (flet ((emit-arg-error () - ;; If this is a closure, then it must have been invoked using - ;; the closure calling convention and the closure object will - ;; still be in RBX. For non-closures, reconstruct the function - ;; object and put that in RBX. - (when (not (c:lambda-information-environment-arg (ir::ast backend-function))) - (emit `(lap:lea64 :rbx (:rip (+ (- entry-point 16) ,sys.int::+tag-object+))))) - ;; Tail call through to RAISE-INVALID-ARGUMENT-ERROR, leaving - ;; the arguments in place. - (emit `(lap:leave) - `(:gc :no-frame :incoming-arguments :rcx :layout #*0) - `(lap:jmp (:named-call sys.int::raise-invalid-argument-error)) - args-ok) - (emit-gc-info :incoming-arguments :rcx))) - (cond ((ir:argument-setup-rest instruction) - ;; If there are no required parameters, then don't generate a lower-bound check. - (when (ir:argument-setup-required instruction) - ;; Minimum number of arguments. + (unless (zerop (getf (mezzano.compiler::ast-optimize (mezzano.compiler.backend::ast backend-function)) 'safety 3)) + (let ((args-ok (mezzano.lap:make-label :args-ok))) + (flet ((emit-arg-error () + ;; If this is a closure, then it must have been invoked using + ;; the closure calling convention and the closure object will + ;; still be in RBX. For non-closures, reconstruct the function + ;; object and put that in RBX. + (when (not (c:lambda-information-environment-arg (ir::ast backend-function))) + (emit `(lap:lea64 :rbx (:rip (+ (- entry-point 16) ,sys.int::+tag-object+))))) + ;; Tail call through to RAISE-INVALID-ARGUMENT-ERROR, leaving + ;; the arguments in place. + (emit `(lap:leave) + `(:gc :no-frame :incoming-arguments :rcx :layout #*0) + `(lap:jmp (:named-call sys.int::raise-invalid-argument-error)) + args-ok) + (emit-gc-info :incoming-arguments :rcx))) + (cond ((ir:argument-setup-rest instruction) + ;; If there are no required parameters, then don't generate a lower-bound check. + (when (ir:argument-setup-required instruction) + ;; Minimum number of arguments. + (emit `(lap:cmp32 :ecx ,(c::fixnum-to-raw (length (ir:argument-setup-required instruction)))) + `(lap:jnl ,args-ok)) + (emit-arg-error))) + ((and (ir:argument-setup-required instruction) + (ir:argument-setup-optional instruction)) + ;; A range. + (emit `(lap:mov32 :eax :ecx) + `(lap:sub32 :eax ,(c::fixnum-to-raw (length (ir:argument-setup-required instruction)))) + `(lap:cmp32 :eax ,(c::fixnum-to-raw (length (ir:argument-setup-optional instruction)))) + `(lap:jna ,args-ok)) + (emit-arg-error)) + ((ir:argument-setup-optional instruction) + ;; Maximum number of arguments. + (emit `(lap:cmp32 :ecx ,(c::fixnum-to-raw (length (ir:argument-setup-optional instruction)))) + `(lap:jna ,args-ok)) + (emit-arg-error)) + ((ir:argument-setup-required instruction) + ;; Exact number of arguments. (emit `(lap:cmp32 :ecx ,(c::fixnum-to-raw (length (ir:argument-setup-required instruction)))) - `(lap:jnl ,args-ok)) - (emit-arg-error))) - ((and (ir:argument-setup-required instruction) - (ir:argument-setup-optional instruction)) - ;; A range. - (emit `(lap:mov32 :eax :ecx) - `(lap:sub32 :eax ,(c::fixnum-to-raw (length (ir:argument-setup-required instruction)))) - `(lap:cmp32 :eax ,(c::fixnum-to-raw (length (ir:argument-setup-optional instruction)))) - `(lap:jna ,args-ok)) - (emit-arg-error)) - ((ir:argument-setup-optional instruction) - ;; Maximum number of arguments. - (emit `(lap:cmp32 :ecx ,(c::fixnum-to-raw (length (ir:argument-setup-optional instruction)))) - `(lap:jna ,args-ok)) - (emit-arg-error)) - ((ir:argument-setup-required instruction) - ;; Exact number of arguments. - (emit `(lap:cmp32 :ecx ,(c::fixnum-to-raw (length (ir:argument-setup-required instruction)))) - `(lap:je ,args-ok)) - (emit-arg-error)) - ;; No arguments - (t - (emit `(lap:test32 :ecx :ecx) - `(lap:jz ,args-ok)) - (emit-arg-error))))) + `(lap:je ,args-ok)) + (emit-arg-error)) + ;; No arguments + (t + (emit `(lap:test32 :ecx :ecx) + `(lap:jz ,args-ok)) + (emit-arg-error)))))) ;; Spill count. (flet ((usedp (reg) (or (typep reg 'mezzano.compiler.backend.register-allocator::physical-register) @@ -253,14 +254,14 @@ (cond ((typep opt 'ir:virtual-register) ;; Load from stack. (when (usedp opt) - (emit `(lap:mov64 :r13 nil) + (emit `(lap:mov64 :r13 :r14) `(lap:cmov64nle :r13 (:rbp ,(* (+ stack-argument-index 2) 8))) `(lap:mov64 ,(effective-address opt) :r13))) (incf stack-argument-index)) (t ;; Load into register. (when (usedp opt) - (emit `(lap:cmov64le ,opt (:constant nil)))))))) + (emit `(lap:cmov64le ,opt :r14))))))) ;; &rest generation. (when (and (ir:argument-setup-rest instruction) (usedp (ir:argument-setup-rest instruction))) @@ -288,7 +289,7 @@ ;; be used later. (emit-gc-info :incoming-arguments saved-argument-count) ;; The cons cells are allocated in one single chunk. - (emit `(lap:mov64 :r13 nil)) + (emit `(lap:mov64 :r13 :r14)) ;; Remove required/optional arguments from the count. ;; If negative or zero, the &REST list is empty. (cond ((zerop regular-argument-count) @@ -324,7 +325,7 @@ (emit `(lap:sub64 :rdx ,(c::fixnum-to-raw 1))) (emit `(lap:ja ,rest-clear-loop-head)) ;; Set the cdr of the final cons to NIL. - (emit `(lap:mov64 (:rdi -8) nil)) + (emit `(lap:mov64 (:rdi -8) :r14)) ;; Create the DX root object for the vector. (emit `(lap:lea64 :rax (:rsp ,sys.int::+tag-dx-root-object+))) (emit `(lap:mov64 (:stack ,rest-dx-root) :rax)) @@ -650,7 +651,7 @@ do (emit `(:d64/le (- ,(resolve-label target) ,jump-table)))))) (defmethod emit-lap (backend-function (instruction ir:branch-instruction) uses defs) - (emit `(lap:cmp64 ,(ir:branch-value instruction) nil)) + (emit `(lap:cmp64 ,(ir:branch-value instruction) :r14)) (emit-branch backend-function instruction 'lap:jne @@ -870,7 +871,7 @@ ;; stack pointer will always be below the live/not-yet-flushed roots. (emit `(lap:mov64 :rdx (:rax 24))) ; rbp (dolist (dx-root (gethash region *dx-root-visibility*)) - (emit `(lap:mov64 (:rdx ,(- (* (1+ dx-root) 8))) nil))) + (emit `(lap:mov64 (:rdx ,(- (* (1+ dx-root) 8))) :r14))) (if multiple-values-p (emit-gc-info :block-or-tagbody-thunk :rax :multiple-values 0) (emit-gc-info :block-or-tagbody-thunk :rax)) @@ -930,7 +931,7 @@ (emit `(lap:jmp ,save-done)) ;; Slow path (emit full-save) - (emit `(lap:mov64 (:stack ,(+ register-only-area 0)) nil)) + (emit `(lap:mov64 (:stack ,(+ register-only-area 0)) :r14)) ;; Allocate an appropriately sized DX simple vector. ;; Add one for the header, then round the count up to an even number. (emit `(lap:lea64 :rax (:rcx ,(c::fixnum-to-raw 2)))) @@ -996,7 +997,7 @@ (full-restore (mezzano.lap:make-label :values-full-restore)) (restore-done (mezzano.lap:make-label :values-restore-done))) ;; See if the fast register path was used. - (emit `(lap:cmp64 (:stack ,(+ register-only-area 0)) nil)) + (emit `(lap:cmp64 (:stack ,(+ register-only-area 0)) :r14)) (emit `(lap:je ,full-restore)) (emit `(lap:mov64 :rcx (:stack ,(+ register-only-area 0)))) (emit `(lap:mov64 :r8 (:stack ,(+ register-only-area 1)))) @@ -1016,10 +1017,10 @@ (emit-gc-info :multiple-values 0) (emit restore-done) ;; Kill the dx root, restore the old stack pointer, and wipe the register area - (emit `(lap:mov64 (:stack ,sv-save-area) nil)) + (emit `(lap:mov64 (:stack ,sv-save-area) :r14)) (emit `(lap:mov64 :rsp (:stack ,saved-stack-pointer))) (dotimes (i 6) - (emit `(lap:mov64 (:stack ,(+ register-only-area i)) nil))))) + (emit `(lap:mov64 (:stack ,(+ register-only-area i)) :r14))))) (defmethod emit-lap (backend-function (instruction ir:forget-multiple-instruction) uses defs) (let* ((save-data (gethash (ir:forget-multiple-context instruction) *saved-multiple-values*)) @@ -1027,10 +1028,10 @@ (saved-stack-pointer (second save-data)) (register-only-area (third save-data))) ;; Kill the dx root, restore the old stack pointer, and wipe the register area - (emit `(lap:mov64 (:stack ,sv-save-area) nil)) + (emit `(lap:mov64 (:stack ,sv-save-area) :r14)) (emit `(lap:mov64 :rsp (:stack ,saved-stack-pointer))) (dotimes (i 6) - (emit `(lap:mov64 (:stack ,(+ register-only-area i)) nil))))) + (emit `(lap:mov64 (:stack ,(+ register-only-area i)) :r14))))) (defmethod emit-lap (backend-function (instruction ir:multiple-value-bind-instruction) uses defs) (loop @@ -1041,9 +1042,9 @@ (cond (regs (let ((reg (pop regs))) (emit `(lap:cmp64 :rcx ,(c::fixnum-to-raw i)) - `(lap:cmov64le ,reg (:constant nil))))) + `(lap:cmov64le ,reg :r14)))) (t - (emit `(lap:mov64 :r13 nil) + (emit `(lap:mov64 :r13 :r14) `(lap:cmp64 :rcx ,(c::fixnum-to-raw i)) `(lap:gs) `(lap:cmov64nle :r13 (,(+ (- 8 sys.int::+tag-object+) @@ -1054,7 +1055,7 @@ (defmethod emit-lap (backend-function (instruction ir:values-instruction) uses defs) (cond ((endp (ir:values-values instruction)) - (emit `(lap:mov64 :r8 nil) + (emit `(lap:mov64 :r8 :r14) `(lap:xor32 :ecx :ecx))) (t (emit `(lap:mov32 :ecx ,(c::fixnum-to-raw (min 5 (length (ir:values-values instruction)))))) @@ -1082,9 +1083,9 @@ (emit `(lap:mov64 (:stack ,(+ slots 3)) ,(logior (ash 3 sys.int::+object-data-shift+) (ash (ir:push-special-stack-tag instruction) sys.int::+object-type-shift+))) - `(lap:mov64 (:stack ,(+ slots 2)) nil) - `(lap:mov64 (:stack ,(+ slots 1)) nil) - `(lap:mov64 (:stack ,(+ slots 0)) nil)) + `(lap:mov64 (:stack ,(+ slots 2)) :r14) + `(lap:mov64 (:stack ,(+ slots 1)) :r14) + `(lap:mov64 (:stack ,(+ slots 0)) :r14)) ;; Store bits. (emit `(lap:mov64 (:stack ,(+ slots 1)) ,(ir:push-special-stack-a-value instruction)) `(lap:mov64 (:stack ,(+ slots 0)) ,(ir:push-special-stack-b-value instruction))) @@ -1137,7 +1138,7 @@ `(lap:mov64 :rbx (:object nil ,mezzano.supervisor::+thread-special-stack-pointer+)) `(lap:mov64 :r13 (:object :rbx 1)) `(lap:mov64 :rax (:object :rbx 2)) - `(lap:mov64 (:object :r13 0 :rax ,(/ 8 (ash 1 sys.int::+n-fixnum-bits+))) nil) + `(lap:mov64 (:object :r13 0 :rax ,(/ 8 (ash 1 sys.int::+n-fixnum-bits+))) :r14) `(lap:mov64 :rbx (:object :rbx 0)) `(lap:gs) `(lap:mov64 (:object nil ,mezzano.supervisor::+thread-special-stack-pointer+) :rbx))) diff --git a/compiler/backend/x86-64/number.lisp b/compiler/backend/x86-64/number.lisp index 64be7d1f7..dbaa2ced1 100644 --- a/compiler/backend/x86-64/number.lisp +++ b/compiler/backend/x86-64/number.lisp @@ -1292,12 +1292,12 @@ :opcode 'lap:cmov64p :result temp-result2 :lhs temp-result1 - :rhs `(:constant nil))) + :rhs :r14)) (emit (make-instance 'x86-fake-three-operand-instruction :opcode 'lap:cmov64ne :result result :lhs temp-result2 - :rhs `(:constant nil))))) + :rhs :r14)))) (t (let ((lhs-unboxed (make-instance 'ir:virtual-register :kind :single-float)) (rhs-unboxed (make-instance 'ir:virtual-register :kind :single-float)) @@ -1321,12 +1321,12 @@ :opcode 'lap:cmov64p :result temp-result2 :lhs temp-result1 - :rhs `(:constant nil))) + :rhs :r14)) (emit (make-instance 'x86-fake-three-operand-instruction :opcode 'lap:cmov64ne :result result :lhs temp-result2 - :rhs `(:constant nil))))))) + :rhs :r14)))))) (define-builtin sys.int::%%truncate-single-float ((value) result) (let ((value-unboxed (make-instance 'ir:virtual-register :kind :single-float)) @@ -1525,12 +1525,12 @@ :opcode 'lap:cmov64p :result temp-result2 :lhs temp-result1 - :rhs `(:constant nil))) + :rhs :r14)) (emit (make-instance 'x86-fake-three-operand-instruction :opcode 'lap:cmov64ne :result result :lhs temp-result2 - :rhs `(:constant nil))))) + :rhs :r14)))) (t (let ((lhs-unboxed (make-instance 'ir:virtual-register :kind :double-float)) (rhs-unboxed (make-instance 'ir:virtual-register :kind :double-float)) @@ -1554,12 +1554,12 @@ :opcode 'lap:cmov64p :result temp-result2 :lhs temp-result1 - :rhs `(:constant nil))) + :rhs :r14)) (emit (make-instance 'x86-fake-three-operand-instruction :opcode 'lap:cmov64ne :result result :lhs temp-result2 - :rhs `(:constant nil))))))) + :rhs :r14)))))) (define-builtin sys.int::%%truncate-double-float ((value) result) (let ((value-unboxed (make-instance 'ir:virtual-register :kind :double-float)) diff --git a/compiler/backend/x86-64/object.lisp b/compiler/backend/x86-64/object.lisp index 5f2b3b3ae..bec0aec1a 100644 --- a/compiler/backend/x86-64/object.lisp +++ b/compiler/backend/x86-64/object.lisp @@ -205,7 +205,7 @@ (cond ((constant-value-p rhs '(eql nil)) (emit (make-instance 'x86-instruction :opcode 'lap:cmp64 - :operands (list lhs nil) + :operands (list lhs :r14) :inputs (list lhs) :outputs '()))) ((constant-value-p rhs '(eql t)) diff --git a/supervisor/thread.lisp b/supervisor/thread.lisp index 6f67b93e6..f51d3b07d 100644 --- a/supervisor/thread.lisp +++ b/supervisor/thread.lisp @@ -506,7 +506,7 @@ Interrupts must be off and the global thread lock must be held." (thread-state-r11 thread) 0 (thread-state-r12 thread) 0 (thread-state-r13 thread) 0 - (thread-state-r14 thread) 0 + (thread-state-r14-value thread) nil (thread-state-r15 thread) 0)) (setf (thread-full-save-p thread) t (thread-state thread) :runnable) @@ -667,7 +667,7 @@ not and WAIT-P is false." (thread-state-r11 thread) 0 (thread-state-r12 thread) 0 (thread-state-r13 thread) 0 - (thread-state-r14 thread) 0 + (thread-state-r14-value thread) nil (thread-state-r15 thread) 0)) ;; Remove the thread from any potential run queue it may be on. (when (and (not (eql priority :idle)) diff --git a/supervisor/x86-64/cpu.lisp b/supervisor/x86-64/cpu.lisp index f33abe76c..2a03b4805 100644 --- a/supervisor/x86-64/cpu.lisp +++ b/supervisor/x86-64/cpu.lisp @@ -645,6 +645,8 @@ TLB shootdown must be protected by the VM lock." (sys.lap-x86:xor32 :ebp :ebp) ;; No arguments (sys.lap-x86:xor32 :ecx :ecx) + ;; Initialize the nil register. + (sys.lap-x86:mov64 :r14 nil) (sys.lap-x86:lea64 :rax (:object :rax #.sys.int::+fref-code+)) (sys.lap-x86:jmp :rax) (:align 16) diff --git a/supervisor/x86-64/thread.lisp b/supervisor/x86-64/thread.lisp index 847d5a676..50dfff908 100644 --- a/supervisor/x86-64/thread.lisp +++ b/supervisor/x86-64/thread.lisp @@ -16,7 +16,7 @@ (sys.lap-x86:mov64 :rsp :r8) (sys.lap-x86:mov64 :rbp :r9) (sys.lap-x86:xor32 :ecx :ecx) - (sys.lap-x86:mov64 :r8 nil) + (sys.lap-x86:mov64 :r8 :r14) (sys.lap-x86:sti) (:gc :no-frame :layout #*0) (sys.lap-x86:ret)) @@ -85,7 +85,7 @@ (:gc :no-frame :layout #*0) ;; No value return. (sys.lap-x86:xor32 :ecx :ecx) - (sys.lap-x86:mov64 :r8 nil) + (sys.lap-x86:mov64 :r8 :r14) ;; Return, restoring RIP. (sys.lap-x86:ret)) @@ -139,6 +139,7 @@ (thread-state-r11-value thread) nil (thread-state-r12-value thread) nil (thread-state-r13-value thread) nil + (thread-state-r14-value thread) nil (thread-state-rip thread) (sys.int::%object-ref-unsigned-byte-64 #'%%full-save-return-thunk sys.int::+function-entry-point+) @@ -230,6 +231,7 @@ (thread-state-r11-value thread) nil (thread-state-r12-value thread) nil (thread-state-r13-value thread) nil + (thread-state-r14-value thread) nil (thread-state-cs thread) #x08 (thread-state-ss thread) #x00 (thread-state-rflags thread) #x202 diff --git a/tools/cold-generator2/x86-64.lisp b/tools/cold-generator2/x86-64.lisp index 2a4b6e6d0..04995d6b0 100644 --- a/tools/cold-generator2/x86-64.lisp +++ b/tools/cold-generator2/x86-64.lisp @@ -153,7 +153,7 @@ (lap:mov64 :r13 (:function ,handler))) (if error-code-p '((lap:lea64 :r9 (:rax :rax))) ; Convert error code to fixnum. - '((lap:mov32 :r9d nil))) ; Nothing interesting + '((lap:mov32 :r9d :r14d))) ; Nothing interesting '((lap:jmp interrupt-common)))) (defun create-user-interrupt-isr (index) diff --git a/tools/disk-header.bin b/tools/disk-header.bin index da3195601..ca23b906e 100644 Binary files a/tools/disk-header.bin and b/tools/disk-header.bin differ diff --git a/tools/kboot/cdkboot.img b/tools/kboot/cdkboot.img index cf3382177..03b079ffe 100644 Binary files a/tools/kboot/cdkboot.img and b/tools/kboot/cdkboot.img differ diff --git a/tools/kboot/kboot-bios.elf b/tools/kboot/kboot-bios.elf index 719c35c1f..7f79cadec 100755 Binary files a/tools/kboot/kboot-bios.elf and b/tools/kboot/kboot-bios.elf differ diff --git a/tools/kboot/kboot.bin b/tools/kboot/kboot.bin index 6a601cb93..1febc17cc 100755 Binary files a/tools/kboot/kboot.bin and b/tools/kboot/kboot.bin differ diff --git a/tools/kboot/kbootx64.efi b/tools/kboot/kbootx64.efi index 4494ff68a..313f2a80f 100755 Binary files a/tools/kboot/kbootx64.efi and b/tools/kboot/kbootx64.efi differ diff --git a/tools/kboot/old-kboot.bin b/tools/kboot/old-kboot.bin new file mode 100755 index 000000000..6a601cb93 Binary files /dev/null and b/tools/kboot/old-kboot.bin differ diff --git a/tools/kboot/old-kbootx64.efi b/tools/kboot/old-kbootx64.efi new file mode 100755 index 000000000..4494ff68a Binary files /dev/null and b/tools/kboot/old-kbootx64.efi differ diff --git a/tools/kboot/pxekboot.img b/tools/kboot/pxekboot.img index 8932b91ca..86e13f4fd 100644 Binary files a/tools/kboot/pxekboot.img and b/tools/kboot/pxekboot.img differ