📄 arith.lisp
字号:
(inst cmp divisor rem) (emit-label label-1) (inst b :gtu label-2) (inst sll quo 1) (inst add quo (if tagged (fixnumize 1) 1)) (inst sub rem divisor) (emit-label label-2)))))) (do-loop (if tagged 30 32))))(define-assembly-routine (positive-fixnum-truncate (:note "unsigned fixnum truncate") (:cost 45) (:translate truncate) (:policy :fast-safe) (:arg-types positive-fixnum positive-fixnum) (:result-types positive-fixnum positive-fixnum)) ((:arg dividend any-reg nl0-offset) (:arg divisor any-reg nl1-offset) (:res quo any-reg nl2-offset) (:res rem any-reg nl0-offset)) (let ((error (generate-error-code nil division-by-zero-error dividend divisor))) (inst cmp divisor) (inst b :eq error)) (move rem dividend) (emit-divide-loop divisor rem quo t))(define-assembly-routine (fixnum-truncate (:note "fixnum truncate") (:cost 50) (:policy :fast-safe) (:translate truncate) (:arg-types tagged-num tagged-num) (:result-types tagged-num tagged-num)) ((:arg dividend any-reg nl0-offset) (:arg divisor any-reg nl1-offset) (:res quo any-reg nl2-offset) (:res rem any-reg nl0-offset) (:temp quo-sign any-reg nl5-offset) (:temp rem-sign any-reg nargs-offset)) (let ((error (generate-error-code nil division-by-zero-error dividend divisor))) (inst cmp divisor) (inst b :eq error)) (inst xor quo-sign dividend divisor) (inst move rem-sign dividend) (let ((label (gen-label))) (inst cmp dividend) (inst ba :lt label) (inst neg dividend) (emit-label label)) (let ((label (gen-label))) (inst cmp divisor) (inst ba :lt label) (inst neg divisor) (emit-label label)) (move rem dividend) (emit-divide-loop divisor rem quo t) (let ((label (gen-label))) ;; If the quo-sign is negative, we need to negate quo. (inst cmp quo-sign) (inst ba :lt label) (inst neg quo) (emit-label label)) (let ((label (gen-label))) ;; If the rem-sign is negative, we need to negate rem. (inst cmp rem-sign) (inst ba :lt label) (inst neg rem) (emit-label label)))(define-assembly-routine (signed-truncate (:note "(signed-byte 32) truncate") (:cost 60) (:policy :fast-safe) (:translate truncate) (:arg-types signed-num signed-num) (:result-types signed-num signed-num)) ((:arg dividend signed-reg nl0-offset) (:arg divisor signed-reg nl1-offset) (:res quo signed-reg nl2-offset) (:res rem signed-reg nl0-offset) (:temp quo-sign signed-reg nl5-offset) (:temp rem-sign signed-reg nargs-offset)) (let ((error (generate-error-code nil division-by-zero-error dividend divisor))) (inst cmp divisor) (inst b :eq error)) (inst xor quo-sign dividend divisor) (inst move rem-sign dividend) (let ((label (gen-label))) (inst cmp dividend) (inst ba :lt label) (inst neg dividend) (emit-label label)) (let ((label (gen-label))) (inst cmp divisor) (inst ba :lt label) (inst neg divisor) (emit-label label)) (move rem dividend) (emit-divide-loop divisor rem quo nil) (let ((label (gen-label))) ;; If the quo-sign is negative, we need to negate quo. (inst cmp quo-sign) (inst ba :lt label) (inst neg quo) (emit-label label)) (let ((label (gen-label))) ;; If the rem-sign is negative, we need to negate rem. (inst cmp rem-sign) (inst ba :lt label) (inst neg rem) (emit-label label)));;;; Comparison(macrolet ((define-cond-assem-rtn (name translate static-fn cmp) `(define-assembly-routine (,name (:cost 10) (:return-style :full-call) (:policy :safe) (:translate ,translate) (:save-p t)) ((:arg x (descriptor-reg any-reg) a0-offset) (:arg y (descriptor-reg any-reg) a1-offset) (:res res descriptor-reg a0-offset) (:temp nargs any-reg nargs-offset) (:temp ocfp any-reg ocfp-offset)) (inst andcc zero-tn x fixnum-tag-mask) (inst b :ne DO-STATIC-FN) (inst andcc zero-tn y fixnum-tag-mask) (inst b :eq DO-COMPARE) (inst cmp x y) DO-STATIC-FN (inst ld code-tn null-tn (static-fun-offset ',static-fn)) (inst li nargs (fixnumize 2)) (inst move ocfp cfp-tn) (inst j code-tn (- (* simple-fun-code-offset n-word-bytes) fun-pointer-lowtag)) (inst move cfp-tn csp-tn) DO-COMPARE (inst b ,cmp done) (load-symbol res t) (inst move res null-tn) DONE))) (define-cond-assem-rtn generic-< < two-arg-< :lt) (define-cond-assem-rtn generic-<= <= two-arg-<= :le) (define-cond-assem-rtn generic-> > two-arg-> :gt) (define-cond-assem-rtn generic->= >= two-arg->= :ge))(define-assembly-routine (generic-eql (:cost 10) (:return-style :full-call) (:policy :safe) (:translate eql) (:save-p t)) ((:arg x (descriptor-reg any-reg) a0-offset) (:arg y (descriptor-reg any-reg) a1-offset) (:res res descriptor-reg a0-offset) (:temp lra descriptor-reg lra-offset) (:temp nargs any-reg nargs-offset) (:temp ocfp any-reg ocfp-offset)) (inst cmp x y) (inst b :eq RETURN-T) (inst andcc zero-tn x fixnum-tag-mask) (inst b :eq RETURN-NIL) (inst andcc zero-tn y fixnum-tag-mask) (inst b :ne DO-STATIC-FN) (inst nop) RETURN-NIL (inst move res null-tn) (lisp-return lra :offset 2) DO-STATIC-FN (inst ld code-tn null-tn (static-fun-offset 'eql)) (inst li nargs (fixnumize 2)) (inst move ocfp cfp-tn) (inst j code-tn (- (* simple-fun-code-offset n-word-bytes) fun-pointer-lowtag)) (inst move cfp-tn csp-tn) RETURN-T (load-symbol res t))(define-assembly-routine (generic-= (:cost 10) (:return-style :full-call) (:policy :safe) (:translate =) (:save-p t)) ((:arg x (descriptor-reg any-reg) a0-offset) (:arg y (descriptor-reg any-reg) a1-offset) (:res res descriptor-reg a0-offset) (:temp lra descriptor-reg lra-offset) (:temp nargs any-reg nargs-offset) (:temp ocfp any-reg ocfp-offset)) (inst andcc zero-tn x fixnum-tag-mask) (inst b :ne DO-STATIC-FN) (inst andcc zero-tn y fixnum-tag-mask) (inst b :ne DO-STATIC-FN) (inst cmp x y) (inst b :eq RETURN-T) (inst nop) (inst move res null-tn) (lisp-return lra :offset 2) DO-STATIC-FN (inst ld code-tn null-tn (static-fun-offset 'two-arg-=)) (inst li nargs (fixnumize 2)) (inst move ocfp cfp-tn) (inst j code-tn (- (* simple-fun-code-offset n-word-bytes) fun-pointer-lowtag)) (inst move cfp-tn csp-tn) RETURN-T (load-symbol res t))(define-assembly-routine (generic-/= (:cost 10) (:return-style :full-call) (:policy :safe) (:translate /=) (:save-p t)) ((:arg x (descriptor-reg any-reg) a0-offset) (:arg y (descriptor-reg any-reg) a1-offset) (:res res descriptor-reg a0-offset) (:temp lra descriptor-reg lra-offset) (:temp nargs any-reg nargs-offset) (:temp ocfp any-reg ocfp-offset)) (inst cmp x y) (inst b :eq RETURN-NIL) (inst andcc zero-tn x fixnum-tag-mask) (inst b :ne DO-STATIC-FN) (inst andcc zero-tn y fixnum-tag-mask) (inst b :ne DO-STATIC-FN) (inst nop) (load-symbol res t) (lisp-return lra :offset 2) DO-STATIC-FN (inst ld code-tn null-tn (static-fun-offset 'two-arg-/=)) (inst li nargs (fixnumize 2)) (inst move ocfp cfp-tn) (inst j code-tn (- (* simple-fun-code-offset n-word-bytes) fun-pointer-lowtag)) (inst move cfp-tn csp-tn) RETURN-NIL (inst move res null-tn))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -