X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fx86%2Farith.lisp;h=7511b324ea13ab76a4a8cb93d46827ead4212859;hb=edf8d3701ba59bd9f0c1bd027f3179b98250cfd0;hp=1e86a0b1e3a29d2454d619268c0b4de8b5aed48e;hpb=804bd4d97228b8ddde6e5d9b4f0c75c889efd819;p=sbcl.git diff --git a/src/compiler/x86/arith.lisp b/src/compiler/x86/arith.lisp index 1e86a0b..7511b32 100644 --- a/src/compiler/x86/arith.lisp +++ b/src/compiler/x86/arith.lisp @@ -604,17 +604,20 @@ (inst lea result (make-ea :dword :index number :scale 8))) (t (move result number) - (cond ((plusp amount) - ;; We don't have to worry about overflow because of the - ;; result type restriction. - (inst shl result amount)) - (t - ;; If the amount is greater than 31, only shift by 31. We - ;; have to do this because the shift instructions only look - ;; at the low five bits of the result. - (inst sar result (min 31 (- amount))) - ;; Fixnum correction. - (inst and result (lognot fixnum-tag-mask)))))))) + (cond ((< -32 amount 32) + ;; this code is used both in ASH and ASH-SMOD30, so + ;; be careful + (if (plusp amount) + (inst shl result amount) + (progn + (inst sar result (- amount)) + (inst and result (lognot fixnum-tag-mask))))) + ((plusp amount) + (if (sc-is result any-reg) + (inst xor result result) + (inst mov result 0))) + (t (inst sar result 31) + (inst and result (lognot fixnum-tag-mask)))))))) (define-vop (fast-ash-left/fixnum=>fixnum) (:translate ash)