0.pre7.20:
[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 \f
15 ;;;; LENGTH
16
17 (define-vop (length/list)
18   (:translate length)
19   (:args (object :scs (descriptor-reg control-stack) :target ptr))
20   (:arg-types list)
21   (:temporary (:sc unsigned-reg :offset eax-offset) eax)
22   (:temporary (:sc descriptor-reg :from (:argument 0)) ptr)
23   (:results (count :scs (any-reg)))
24   (:result-types positive-fixnum)
25   (:policy :fast-safe)
26   (:vop-var vop)
27   (:save-p :compute-only)
28   (:generator 40
29     ;; Move OBJECT into a temp we can bash on, and initialize the count.
30     (move ptr object)
31     (inst xor count count)
32     ;; If we are starting with NIL, then it's really easy.
33     (inst cmp ptr nil-value)
34     (inst jmp :e done)
35     ;; Note: we don't have to test to see whether the original argument is a
36     ;; list, because this is a :fast-safe vop.
37     LOOP
38     ;; Get the CDR and boost the count.
39     (loadw ptr ptr cons-cdr-slot list-pointer-type)
40     (inst add count (fixnumize 1))
41     ;; If we hit NIL, then we are done.
42     (inst cmp ptr nil-value)
43     (inst jmp :e done)
44     ;; Otherwise, check to see whether we hit the end of a dotted list. If
45     ;; not, loop back for more.
46     (move eax ptr)
47     (inst and al-tn lowtag-mask)
48     (inst cmp al-tn list-pointer-type)
49     (inst jmp :e loop)
50     ;; It's dotted all right. Flame out.
51     (error-call vop object-not-list-error ptr)
52     ;; We be done.
53     DONE))
54
55 (define-vop (fast-length/list)
56   (:translate length)
57   (:args (object :scs (descriptor-reg control-stack) :target ptr))
58   (:arg-types list)
59   (:temporary (:sc descriptor-reg :from (:argument 0)) ptr)
60   (:results (count :scs (any-reg)))
61   (:result-types positive-fixnum)
62   (:policy :fast)
63   (:vop-var vop)
64   (:save-p :compute-only)
65   (:generator 30
66     ;; Get a copy of OBJECT in a register we can bash on, and
67     ;; initialize COUNT.
68     (move ptr object)
69     (inst xor count count)
70     ;; If we are starting with NIL, we be done.
71     (inst cmp ptr nil-value)
72     (inst jmp :e done)
73     ;; Indirect the next cons cell, and boost the count.
74     LOOP
75     (loadw ptr ptr cons-cdr-slot list-pointer-type)
76     (inst add count (fixnumize 1))
77     ;; If we aren't done, go back for more.
78     (inst cmp ptr nil-value)
79     (inst jmp :ne loop)
80     DONE))
81
82 (define-static-function length (object) :translate length)