X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fassembly%2Fx86-64%2Farith.lisp;h=684d16e150d79b2938b5b6283e5f003facc4b213;hb=ee5629ee974ee8ce7a1cb245a99e94f8943ffd90;hp=d47b7206d698b1db3137e683a6bea40b9c022eff;hpb=d95f1e6476aa63695e018a7769a1ae9e002fca36;p=sbcl.git diff --git a/src/assembly/x86-64/arith.lisp b/src/assembly/x86-64/arith.lisp index d47b720..684d16e 100644 --- a/src/assembly/x86-64/arith.lisp +++ b/src/assembly/x86-64/arith.lisp @@ -36,17 +36,16 @@ (inst jmp :nz DO-STATIC-FUN) ; no - do generic ,@body - (inst clc) + (inst clc) ; single-value return (inst ret) DO-STATIC-FUN - (inst pop rax) + ;; Same as: (inst enter (* n-word-bytes 1)) (inst push rbp-tn) - (inst lea - rbp-tn - (make-ea :qword :base rsp-tn :disp n-word-bytes)) - (inst sub rsp-tn (fixnumize 2)) - (inst push rax) ; callers return addr + (inst mov rbp-tn rsp-tn) + (inst sub rsp-tn (* n-word-bytes 1)) + (inst push (make-ea :qword :base rbp-tn + :disp (frame-byte-offset return-pc-save-offset))) (inst mov rcx (fixnumize 2)) ; arg count (inst jmp (make-ea :qword @@ -54,12 +53,16 @@ (static-fun-offset ',(symbolicate "TWO-ARG-" fun)))))))) + #.` (define-generic-arith-routine (+ 10) (move res x) (inst add res y) (inst jmp :no OKAY) - (inst rcr res 1) ; carry has correct sign - (inst sar res 2) ; remove type bits + ;; Unbox the overflowed result, recovering the correct sign from + ;; the carry flag, then re-box as a bignum. + (inst rcr res 1) + ,@(when (> n-fixnum-tag-bits 1) ; don't shift by 0 + '((inst sar res (1- n-fixnum-tag-bits)))) (move rcx res) @@ -68,13 +71,17 @@ OKAY) + #.` (define-generic-arith-routine (- 10) (move res x) (inst sub res y) (inst jmp :no OKAY) + ;; Unbox the overflowed result, recovering the correct sign from + ;; the carry flag, then re-box as a bignum. (inst cmc) ; carry has correct sign now (inst rcr res 1) - (inst sar res 2) ; remove type bits + ,@(when (> n-fixnum-tag-bits 1) ; don't shift by 0 + '((inst sar res (1- n-fixnum-tag-bits)))) (move rcx res) @@ -127,11 +134,11 @@ (inst test x fixnum-tag-mask) (inst jmp :z FIXNUM) - (inst pop rax) (inst push rbp-tn) - (inst lea rbp-tn (make-ea :qword :base rsp-tn :disp n-word-bytes)) - (inst sub rsp-tn (fixnumize 2)) - (inst push rax) + (inst mov rbp-tn rsp-tn) + (inst sub rsp-tn (* n-word-bytes 1)) + (inst push (make-ea :qword :base rbp-tn + :disp (frame-byte-offset return-pc-save-offset))) (inst mov rcx (fixnumize 1)) ; arg count (inst jmp (make-ea :qword :disp (+ nil-value (static-fun-offset '%negate)))) @@ -163,19 +170,24 @@ (inst mov rcx x) (inst or rcx y) (inst test rcx fixnum-tag-mask) - (inst jmp :nz DO-STATIC-FUN) + (inst jmp :nz DO-STATIC-FUN) ; are both fixnums? (inst cmp x y) (inst ret) DO-STATIC-FUN - (move rcx rsp-tn) - (inst sub rsp-tn (fixnumize 3)) - (inst mov (make-ea :qword - :base rcx - :disp (fixnumize -1)) + (inst sub rsp-tn (* n-word-bytes 3)) + (inst mov (make-ea :qword :base rsp-tn + :disp (frame-byte-offset + (+ sp->fp-offset + -3 + ocfp-save-offset))) rbp-tn) - (move rbp-tn rcx) + (inst lea rbp-tn (make-ea :qword :base rsp-tn + :disp (frame-byte-offset + (+ sp->fp-offset + -3 + ocfp-save-offset)))) (inst mov rcx (fixnumize 2)) (inst call (make-ea :qword :disp (+ nil-value @@ -234,13 +246,18 @@ (inst ret) DO-STATIC-FUN - (move rcx rsp-tn) - (inst sub rsp-tn (fixnumize 3)) - (inst mov (make-ea :qword - :base rcx - :disp (fixnumize -1)) + (inst sub rsp-tn (* n-word-bytes 3)) + (inst mov (make-ea :qword :base rsp-tn + :disp (frame-byte-offset + (+ sp->fp-offset + -3 + ocfp-save-offset))) rbp-tn) - (move rbp-tn rcx) + (inst lea rbp-tn (make-ea :qword :base rsp-tn + :disp (frame-byte-offset + (+ sp->fp-offset + -3 + ocfp-save-offset)))) (inst mov rcx (fixnumize 2)) (inst call (make-ea :qword :disp (+ nil-value (static-fun-offset 'eql)))) @@ -291,13 +308,19 @@ (inst ret) DO-STATIC-FUN - (move rcx rsp-tn) - (inst sub rsp-tn (fixnumize 3)) - (inst mov (make-ea :qword - :base rcx - :disp (fixnumize -1)) + (inst sub rsp-tn (* n-word-bytes 3)) + (inst mov (make-ea :qword :base rsp-tn + :disp (frame-byte-offset + (+ sp->fp-offset + -3 + ocfp-save-offset))) rbp-tn) - (move rbp-tn rcx) + (inst lea rbp-tn (make-ea :qword :base rsp-tn + :disp (frame-byte-offset + (+ sp->fp-offset + -3 + ocfp-save-offset)))) + (inst mov rcx (fixnumize 2)) (inst call (make-ea :qword :disp (+ nil-value (static-fun-offset 'two-arg-=))))