From 1b8b84be82ebb9fb86ddd5159c7a36067ee27257 Mon Sep 17 00:00:00 2001 From: Raymond Toy <toy.raymond@gmail.com> Date: Tue, 1 Dec 2015 21:41:49 -0800 Subject: [PATCH] Handle large (fixed) shift amounts for the digit shifters. Make the vops handle the case when the known constant shift amount is so large that the result is a known value. Plus, the instructions have a fixed immediate argument size and the amount is taken mod 32 which would produce the wrong result if the actual shift amount were used. --- src/compiler/x86/arith.lisp | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/compiler/x86/arith.lisp b/src/compiler/x86/arith.lisp index c01faf07f..13c04250a 100644 --- a/src/compiler/x86/arith.lisp +++ b/src/compiler/x86/arith.lisp @@ -1459,29 +1459,48 @@ (move ecx count) (inst sar result :cl)) (immediate - (inst sar result (tn-value count)))))) + (let ((amount (tn-value count))) + ;; If the amount is greater than 31, it's the same as + ;; shifting by 31, leaving just the sign bit. + (inst sar result (if (>= amount vm:word-bits) + (1- vm:word-bits) + amount))))))) (define-vop (digit-lshr digit-ashr) (:translate bignum::%digit-logical-shift-right) (:generator 2 - (move result digit) (sc-case count (unsigned-reg + (move result digit) (move ecx count) (inst shr result :cl)) (immediate - (inst shr result (tn-value count)))))) + (let ((amount (tn-value count))) + ;; If the amount is greater than 31, the result is 0 because + ;; all the bits get shifted right and out. + (cond ((>= amount vm:word-bits) + (inst mov result 0)) + (t + (move result digit) + (inst shr result count)))))))) (define-vop (digit-ashl digit-ashr) (:translate bignum::%ashl) (:generator 2 - (move result digit) (sc-case count (unsigned-reg + (move result digit) (move ecx count) (inst shl result :cl)) (immediate - (inst shl result (tn-value count)))))) + (let ((amount (tn-value count))) + ;; If the amount is greater than 31, the result is 0 because + ;; all the bits get shifted left and out. + (cond ((>= amount vm:word-bits) + (inst mov result 0)) + (t + (move result digit) + (inst shl result amount)))))))) ;;;; Static functions. -- GitLab