X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fx86-64%2Fmacros.lisp;h=2883d289e8a487d710508c51ef592f0f4cd873a3;hb=a3d4610158f227d53cb5eac287dd2661e975fc70;hp=801c905da76b1ec4ee29b82014f9c5dc01806e56;hpb=a3caf3155958590af9614705770358c0c8bdd8a8;p=sbcl.git diff --git a/src/compiler/x86-64/macros.lisp b/src/compiler/x86-64/macros.lisp index 801c905..2883d28 100644 --- a/src/compiler/x86-64/macros.lisp +++ b/src/compiler/x86-64/macros.lisp @@ -1,4 +1,4 @@ -;;;; a bunch of handy macros for the x86 +;;;; a bunch of handy macros for x86-64 ;;;; This software is part of the SBCL system. See the README file for ;;;; more information. @@ -13,21 +13,31 @@ ;;;; instruction-like macros -(defmacro move (dst src) +;;; This used to be a macro (and still is on the other platforms) but +;;; the support for SC-dependent move instructions needed here makes +;;; that expand into so large an expression that the resulting code +;;; bloat is not justifiable. +(defun move (dst src) #!+sb-doc "Move SRC into DST unless they are location=." - (once-only ((n-dst dst) - (n-src src)) - `(unless (location= ,n-dst ,n-src) - (sc-case ,n-dst - ((single-reg complex-single-reg) - (aver (xmm-register-p ,n-src)) - (inst movaps ,n-dst ,n-src)) - ((double-reg complex-double-reg) - (aver (xmm-register-p ,n-src)) - (inst movapd ,n-dst ,n-src)) - (t - (inst mov ,n-dst ,n-src)))))) + (unless (location= dst src) + (sc-case dst + ((single-reg complex-single-reg) + (aver (xmm-register-p src)) + (inst movaps dst src)) + ((double-reg complex-double-reg) + (aver (xmm-register-p src)) + (inst movapd dst src)) + #!+sb-simd-pack + ((int-sse-reg sse-reg) + (aver (xmm-register-p src)) + (inst movdqa dst src)) + #!+sb-simd-pack + ((single-sse-reg double-sse-reg) + (aver (xmm-register-p src)) + (inst movaps dst src)) + (t + (inst mov dst src))))) (defmacro make-ea-for-object-slot (ptr slot lowtag) `(make-ea :qword :base ,ptr :disp (- (* ,slot n-word-bytes) ,lowtag))) @@ -51,6 +61,14 @@ (defmacro popw (ptr &optional (slot 0) (lowtag 0)) `(inst pop (make-ea-for-object-slot ,ptr ,slot ,lowtag))) + +(defun call-indirect (offset) + (typecase offset + ((signed-byte 32) + (inst call (make-ea :qword :disp offset))) + (t + (inst mov temp-reg-tn offset) + (inst call (make-ea :qword :base temp-reg-tn))))) ;;;; macros to generate useful values @@ -120,10 +138,10 @@ (n-offset offset)) (ecase *backend-byte-order* (:little-endian - `(inst mov ,n-target + `(inst movzx ,n-target (make-ea :byte :base ,n-source :disp ,n-offset))) (:big-endian - `(inst mov ,n-target + `(inst movzx ,n-target (make-ea :byte :base ,n-source :disp (+ ,n-offset (1- n-word-bytes)))))))) @@ -297,8 +315,15 @@ :disp (* n-word-bytes thread-pseudo-atomic-bits-slot)) 0)) +#!+sb-safepoint +(defun emit-safepoint () + (inst test al-tn (make-ea :byte :disp sb!vm::gc-safepoint-page-addr))) + #!+sb-thread (defmacro pseudo-atomic (&rest forms) + #!+sb-safepoint-strictly + `(progn ,@forms (emit-safepoint)) + #!-sb-safepoint-strictly (with-unique-names (label) `(let ((,label (gen-label))) (inst mov (make-ea :qword @@ -314,7 +339,13 @@ ;; if PAI was set, interrupts were disabled at the same time ;; using the process signal mask. (inst break pending-interrupt-trap) - (emit-label ,label)))) + (emit-label ,label) + #!+sb-safepoint + ;; In this case, when allocation thinks a GC should be done, it + ;; does not mark PA as interrupted, but schedules a safepoint + ;; trap instead. Let's take the opportunity to trigger that + ;; safepoint right now. + (emit-safepoint)))) #!-sb-thread @@ -529,7 +560,7 @@ Useful for e.g. foreign calls where another thread may trigger collection." (if objects (let ((pins (make-gensym-list (length objects))) - (wpo (gensym "WITH-PINNED-OBJECTS-THUNK"))) + (wpo (sb!xc:gensym "WITH-PINNED-OBJECTS-THUNK"))) ;; BODY is stuffed in a function to preserve the lexical ;; environment. `(flet ((,wpo () (progn ,@body)))