From: Christophe R. <cr...@us...> - 2004-07-27 17:56:45
|
Update of /cvsroot/sbcl/sbcl/src/compiler/x86 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14330/src/compiler/x86 Modified Files: insts.lisp type-vops.lisp Log Message: 0.8.13.7: Just for fun: implement the Intel prefetch instructions, and conditionally use (one of) them in typetag checking ... no, it doesn't make anything noticeably faster; why do you ask? Index: insts.lisp =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/compiler/x86/insts.lisp,v retrieving revision 1.30 retrieving revision 1.31 diff -u -d -r1.30 -r1.31 --- insts.lisp 15 Apr 2004 17:47:13 -0000 1.30 +++ insts.lisp 27 Jul 2004 17:56:35 -0000 1.31 @@ -615,6 +615,14 @@ (disp :field (byte 16 8)) (level :field (byte 8 24))) +(sb!disassem:define-instruction-format (prefetch 24 + :default-printer + '(:name ", " reg/mem)) + (prefix :field (byte 8 0) :value #b00001111) + (op :field (byte 8 8) :value #b00011000) + (reg/mem :fields (list (byte 2 22) (byte 3 16)) :type 'byte-reg/mem) + (reg :field (byte 3 19) :type 'reg)) + ;;; Single byte instruction with an immediate byte argument. (sb!disassem:define-instruction-format (byte-imm 16 :default-printer '(:name :tab code)) @@ -1840,6 +1848,43 @@ (:emitter (emit-byte segment #b11001001))) +;;;; prefetch +(define-instruction prefetchnta (segment ea) + (:printer prefetch ((op #b00011000) (reg #b000))) + (:emitter + (aver (typep ea 'ea)) + (aver (eq :byte (ea-size ea))) + (emit-byte segment #b00001111) + (emit-byte segment #b00011000) + (emit-ea segment ea #b000))) + +(define-instruction prefetcht0 (segment ea) + (:printer prefetch ((op #b00011000) (reg #b001))) + (:emitter + (aver (typep ea 'ea)) + (aver (eq :byte (ea-size ea))) + (emit-byte segment #b00001111) + (emit-byte segment #b00011000) + (emit-ea segment ea #b001))) + +(define-instruction prefetcht1 (segment ea) + (:printer prefetch ((op #b00011000) (reg #b010))) + (:emitter + (aver (typep ea 'ea)) + (aver (eq :byte (ea-size ea))) + (emit-byte segment #b00001111) + (emit-byte segment #b00011000) + (emit-ea segment ea #b010))) + +(define-instruction prefetcht2 (segment ea) + (:printer prefetch ((op #b00011000) (reg #b011))) + (:emitter + (aver (typep ea 'ea)) + (aver (eq :byte (ea-size ea))) + (emit-byte segment #b00001111) + (emit-byte segment #b00011000) + (emit-ea segment ea #b011))) + ;;;; interrupt instructions (defun snarf-error-junk (sap offset &optional length-only) Index: type-vops.lisp =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/compiler/x86/type-vops.lisp,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- type-vops.lisp 1 Mar 2004 23:22:26 -0000 1.16 +++ type-vops.lisp 27 Jul 2004 17:56:35 -0000 1.17 @@ -62,6 +62,14 @@ (unless al-loaded (move eax-tn value) (inst and al-tn lowtag-mask)) + ;; FIXME: another 'optimization' which doesn't appear to work: + ;; prefetching the hypothetically pointed-to version should help, + ;; but this is in fact non-ideal in plenty of ways: we emit way too + ;; many of these prefetch instructions; pointed-to objects are very + ;; often in the cache anyway; etc. etc. Still, as proof-of-concept, + ;; not too bad. -- CSR, 2004-07-27 + (when (member :prefetch *backend-subfeatures*) + (inst prefetchnta (make-ea :byte :base value :disp (- lowtag)))) (inst cmp al-tn lowtag) (inst jmp (if not-p :ne :e) target)) |