Initial revision
[sbcl.git] / src / compiler / x86 / subprim.lisp
1 ;;;; linkage information for standard static functions, and
2 ;;;; miscellaneous VOPs
3
4 ;;;; This software is part of the SBCL system. See the README file for
5 ;;;; more information.
6 ;;;;
7 ;;;; This software is derived from the CMU CL system, which was
8 ;;;; written at Carnegie Mellon University and released into the
9 ;;;; public domain. The software is in the public domain and is
10 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
11 ;;;; files for more information.
12
13 (in-package "SB!VM")
14
15 (file-comment
16  "$Header$")
17 \f
18 ;;;; LENGTH
19
20 (define-vop (length/list)
21   (:translate length)
22   (:args (object :scs (descriptor-reg control-stack) :target ptr))
23   (:arg-types list)
24   (:temporary (:sc unsigned-reg :offset eax-offset) eax)
25   (:temporary (:sc descriptor-reg :from (:argument 0)) ptr)
26   (:results (count :scs (any-reg)))
27   (:result-types positive-fixnum)
28   (:policy :fast-safe)
29   (:vop-var vop)
30   (:save-p :compute-only)
31   (:generator 40
32     ;; Move OBJECT into a temp we can bash on, and initialize the count.
33     (move ptr object)
34     (inst xor count count)
35     ;; If we are starting with NIL, then it's real easy.
36     (inst cmp ptr *nil-value*)
37     (inst jmp :e done)
38     ;; Note: we don't have to test to see whether the original argument is a
39     ;; list, because this is a :fast-safe vop.
40     LOOP
41     ;; Get the CDR and boost the count.
42     (loadw ptr ptr cons-cdr-slot list-pointer-type)
43     (inst add count (fixnumize 1))
44     ;; If we hit NIL, then we are done.
45     (inst cmp ptr *nil-value*)
46     (inst jmp :e done)
47     ;; Otherwise, check to see whether we hit the end of a dotted list. If
48     ;; not, loop back for more.
49     (move eax ptr)
50     (inst and al-tn lowtag-mask)
51     (inst cmp al-tn list-pointer-type)
52     (inst jmp :e loop)
53     ;; It's dotted all right. Flame out.
54     (error-call vop object-not-list-error ptr)
55     ;; We be done.
56     DONE))
57
58 (define-vop (fast-length/list)
59   (:translate length)
60   (:args (object :scs (descriptor-reg control-stack) :target ptr))
61   (:arg-types list)
62   (:temporary (:sc descriptor-reg :from (:argument 0)) ptr)
63   (:results (count :scs (any-reg)))
64   (:result-types positive-fixnum)
65   (:policy :fast)
66   (:vop-var vop)
67   (:save-p :compute-only)
68   (:generator 30
69     ;; Get a copy of OBJECT in a register we can bash on, and
70     ;; initialize COUNT.
71     (move ptr object)
72     (inst xor count count)
73     ;; If we are starting with NIL, we be done.
74     (inst cmp ptr *nil-value*)
75     (inst jmp :e done)
76     ;; Indirect the next cons cell, and boost the count.
77     LOOP
78     (loadw ptr ptr cons-cdr-slot list-pointer-type)
79     (inst add count (fixnumize 1))
80     ;; If we aren't done, go back for more.
81     (inst cmp ptr *nil-value*)
82     (inst jmp :ne loop)
83     DONE))
84
85 (define-static-function length (object) :translate length)