Initial revision
[sbcl.git] / src / compiler / x86 / char.lisp
1 ;;;; x86 definition of character operations
2
3 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; more information.
5 ;;;;
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
11
12 (in-package "SB!VM")
13
14 (file-comment
15  "$Header$")
16 \f
17 ;;;; moves and coercions
18
19 ;;; Move a tagged char to an untagged representation.
20 (define-vop (move-to-base-char)
21   (:args (x :scs (any-reg control-stack) :target al))
22   (:temporary (:sc byte-reg :offset al-offset
23                    :from (:argument 0) :to (:eval 0)) al)
24   (:ignore al)
25   (:temporary (:sc byte-reg :offset ah-offset :target y
26                    :from (:argument 0) :to (:result 0)) ah)
27   (:results (y :scs (base-char-reg base-char-stack)))
28   (:note "character untagging")
29   (:generator 1
30     (move eax-tn x)
31     (move y ah)))
32 (define-move-vop move-to-base-char :move
33   (any-reg control-stack) (base-char-reg base-char-stack))
34
35 ;;; Move an untagged char to a tagged representation.
36 (define-vop (move-from-base-char)
37   (:args (x :scs (base-char-reg base-char-stack) :target ah))
38   (:temporary (:sc byte-reg :offset al-offset :target y
39                    :from (:argument 0) :to (:result 0)) al)
40   (:temporary (:sc byte-reg :offset ah-offset
41                    :from (:argument 0) :to (:result 0)) ah)
42   (:results (y :scs (any-reg descriptor-reg control-stack)))
43   (:note "character tagging")
44   (:generator 1
45     (move ah x)                         ; Maybe move char byte.
46     (inst mov al base-char-type)        ; x86 to type bits
47     (inst and eax-tn #xffff)            ; Remove any junk bits.
48     (move y eax-tn)))
49 (define-move-vop move-from-base-char :move
50   (base-char-reg base-char-stack) (any-reg descriptor-reg control-stack))
51
52 ;;; Move untagged base-char values.
53 (define-vop (base-char-move)
54   (:args (x :target y
55             :scs (base-char-reg)
56             :load-if (not (location= x y))))
57   (:results (y :scs (base-char-reg base-char-stack)
58                :load-if (not (location= x y))))
59   (:note "character move")
60   (:effects)
61   (:affected)
62   (:generator 0
63     (move y x)))
64 (define-move-vop base-char-move :move
65   (base-char-reg) (base-char-reg base-char-stack))
66
67 ;;; Move untagged base-char arguments/return-values.
68 (define-vop (move-base-char-argument)
69   (:args (x :target y
70             :scs (base-char-reg))
71          (fp :scs (any-reg)
72              :load-if (not (sc-is y base-char-reg))))
73   (:results (y))
74   (:note "character arg move")
75   (:generator 0
76     (sc-case y
77       (base-char-reg
78        (move y x))
79       (base-char-stack
80        (inst mov
81              (make-ea :byte :base fp :disp (- (* (1+ (tn-offset y)) 4)))
82              x)))))
83 (define-move-vop move-base-char-argument :move-argument
84   (any-reg base-char-reg) (base-char-reg))
85
86 ;;; Use standard MOVE-ARGUMENT + coercion to move an untagged base-char
87 ;;; to a descriptor passing location.
88 (define-move-vop move-argument :move-argument
89   (base-char-reg) (any-reg descriptor-reg))
90 \f
91 ;;;; other operations
92
93 (define-vop (char-code)
94   (:translate char-code)
95   (:policy :fast-safe)
96   (:args (ch :scs (base-char-reg base-char-stack)))
97   (:arg-types base-char)
98   (:results (res :scs (unsigned-reg)))
99   (:result-types positive-fixnum)
100   (:generator 1
101     (inst movzx res ch)))
102
103 (define-vop (code-char)
104   (:translate code-char)
105   (:policy :fast-safe)
106   (:args (code :scs (unsigned-reg unsigned-stack) :target eax))
107   (:arg-types positive-fixnum)
108   (:temporary (:sc unsigned-reg :offset eax-offset :target res
109                    :from (:argument 0) :to (:result 0))
110               eax)
111   (:results (res :scs (base-char-reg)))
112   (:result-types base-char)
113   (:generator 1
114     (move eax code)
115     (move res al-tn)))
116 \f
117 ;;; comparison of BASE-CHARs
118 (define-vop (base-char-compare)
119   (:args (x :scs (base-char-reg base-char-stack))
120          (y :scs (base-char-reg)
121             :load-if (not (and (sc-is x base-char-reg)
122                                (sc-is y base-char-stack)))))
123   (:arg-types base-char base-char)
124   (:conditional)
125   (:info target not-p)
126   (:policy :fast-safe)
127   (:note "inline comparison")
128   (:variant-vars condition not-condition)
129   (:generator 3
130     (inst cmp x y)
131     (inst jmp (if not-p not-condition condition) target)))
132
133 (define-vop (fast-char=/base-char base-char-compare)
134   (:translate char=)
135   (:variant :e :ne))
136
137 (define-vop (fast-char</base-char base-char-compare)
138   (:translate char<)
139   (:variant :b :nb))
140
141 (define-vop (fast-char>/base-char base-char-compare)
142   (:translate char>)
143   (:variant :a :na))