1 (in-package "SB-ROTATE-BYTE")
3 (define-vop (%
32bit-rotate-byte
/c
)
5 (:translate %unsigned-32-rotate-byte
)
6 (:note
"inline 32-bit constant rotation")
8 (:args
(integer :scs
(sb-vm::unsigned-reg
) :target res
))
9 (:arg-types
(:constant
(integer -
31 31)) sb-vm
::unsigned-byte-32
)
10 (:results
(res :scs
(sb-vm::unsigned-reg
)))
11 (:result-types sb-vm
::unsigned-byte-32
)
13 ;; the 0 case is an identity operation and should be
14 ;; DEFTRANSFORMed away.
15 (aver (not (= count
0)))
19 (inst ror res
(- count
)))))
21 (define-vop (%
32bit-rotate-byte-fixnum
/c
)
23 (:translate %unsigned-32-rotate-byte
)
24 (:note
"inline 32-bit constant rotation")
26 (:args
(integer :scs
(sb-vm::any-reg
) :target res
))
27 (:arg-types
(:constant
(integer -
31 31)) sb-vm
::positive-fixnum
)
28 (:results
(res :scs
(sb-vm::unsigned-reg
)))
29 (:result-types sb-vm
::unsigned-byte-32
)
31 (aver (not (= count
0)))
32 (inst mov res integer
)
34 ;; FIXME: all these 2s should be n-fixnum-tag-bits.
36 ((> count
2) (inst rol res
(- count
2)))
37 (t (inst ror res
(- 2 count
))))))
39 (macrolet ((def (name arg-type
)
42 (:translate %unsigned-32-rotate-byte
)
43 (:note
"inline 32-bit rotation")
44 (:args
(count :scs
(sb-vm::signed-reg
) :target ecx
)
45 (integer :scs
(sb-vm::unsigned-reg
) :target res
))
46 (:arg-types sb-vm
::tagged-num
,arg-type
)
47 (:temporary
(:sc sb-vm
::signed-reg
:offset sb-vm
::ecx-offset
)
49 (:results
(res :scs
(sb-vm::unsigned-reg
) :from
:load
))
50 (:result-types sb-vm
::unsigned-byte-32
)
52 (let ((label (gen-label))
64 (def %
32bit-rotate-byte sb-vm
::unsigned-byte-32
)
65 ;; FIXME: it's not entirely clear to me why we need this second
66 ;; definition -- or rather, why the compiler isn't smart enough to
67 ;; MOVE a POSITIVE-FIXNUM argument to an UNSIGNED-BYTE-32 argument,
68 ;; and then go from there. Still, not having it leads to scary
69 ;; compilation messages of the form:
71 ;; unable to do inline 32-bit constant rotation (cost 5) because:
72 ;; This shouldn't happen! Bug?
73 ;; argument types invalid
74 ;; argument primitive types:
75 ;; (SB-VM::POSITIVE-FIXNUM SB-VM::POSITIVE-FIXNUM)
77 ;; so better leave it in.
78 (def %
32bit-rotate-byte-fixnum sb-vm
::positive-fixnum
))