From cfa0355f88de28bf980b7e14ff9f29d02b108f8f Mon Sep 17 00:00:00 2001 From: Juho Snellman Date: Sun, 6 Feb 2005 05:58:40 +0000 Subject: [PATCH] 0.8.19.16: Various x86-64 improvements. * Fix some SB-ALIEN:INT / SB-ALIEN:INTEGER confusion in tests. (Patch by Vincent Arkesteijn on sbcl-devel, "Re: x86-64 (aka AMD64, EMT-64) support" on 2005-02-05). * Align the stack to 16-byte boundaries for c-calls, as required by the ABI. (Patch by Cheuksan Edward Wang). * Omit unneccessary rex-prefix on indirect JMP. (Patch by Cheuksan Edward Wang). * Disassembler improvements. (Patch by Cheuksan Edward Wang). --- NEWS | 8 ++++++++ src/compiler/x86-64/c-call.lisp | 6 ++++-- src/compiler/x86-64/insts.lisp | 27 +++++++++++++++++++++------ tests/alien.impure.lisp | 4 ++-- version.lisp-expr | 2 +- 5 files changed, 36 insertions(+), 11 deletions(-) diff --git a/NEWS b/NEWS index 947145f..e98bb1e 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,14 @@ changes in sbcl-0.8.20 (0.9alpha.0?) relative to sbcl-0.8.19: ";" and "#|") are more forgiving to encoding errors; they will STYLE-WARN and then attempt to resync the stream at a character boundary. (thanks to Teemu Kalvas) + * fixed some bugs in the x86-64 port: + ** Negative short int return values from c-calls are sign-extended + correctly. + ** The stack is aligned to 16-bytes for c-calls, as required by + the ABI. (thanks to Cheuksan Wang) + ** The disassembler understands more x86-64. (thanks to Cheuksan Wang) + ** The regression tests use SB-ALIEN:INT instead of SB-ALIEN:INTEGER + for enums. (thanks to Vincent Arkesteijn) * fixed some bugs revealed by Paul Dietz' test suite: ** Space, Tab, Linefeed, Return and Page have the invalid secondary constituent character trait. diff --git a/src/compiler/x86-64/c-call.lisp b/src/compiler/x86-64/c-call.lisp index 05235ba..99b1525 100644 --- a/src/compiler/x86-64/c-call.lisp +++ b/src/compiler/x86-64/c-call.lisp @@ -267,15 +267,17 @@ (:generator 0 (aver (location= result rsp-tn)) (unless (zerop amount) - (let ((delta (logandc2 (+ amount 3) 3))) + (let ((delta (logandc2 (+ amount 7) 7))) (inst sub rsp-tn delta))) + ;; C stack must be 16 byte aligned + (inst and rsp-tn #xfffffff0) (move result rsp-tn))) (define-vop (dealloc-number-stack-space) (:info amount) (:generator 0 (unless (zerop amount) - (let ((delta (logandc2 (+ amount 3) 3))) + (let ((delta (logandc2 (+ amount 7) 7))) (inst add rsp-tn delta))))) (define-vop (alloc-alien-stack-space) diff --git a/src/compiler/x86-64/insts.lisp b/src/compiler/x86-64/insts.lisp index da67010..86c1c0e 100644 --- a/src/compiler/x86-64/insts.lisp +++ b/src/compiler/x86-64/insts.lisp @@ -1,5 +1,5 @@ -;;;; that part of the description of the x86 instruction set (for -;;;; 80386 and above) which can live on the cross-compilation host +;;;; that part of the description of the x86-64 instruction set +;;;; which can live on the cross-compilation host ;;;; This software is part of the SBCL system. See the README file for ;;;; more information. @@ -304,6 +304,16 @@ *default-address-size*)) dstate))) +(sb!disassem:define-arg-type imm-data-upto-dword + :prefilter (lambda (value dstate) + (declare (ignore value)) ; always nil anyway + (let ((width (width-bits + (or (sb!disassem:dstate-get-prop dstate 'width) + *default-address-size*)))) + (if (= width 64) + (sb!disassem:read-signed-suffix 32 dstate) + (sb!disassem:read-suffix width dstate))))) + (sb!disassem:define-arg-type signed-imm-data :prefilter (lambda (value dstate) (declare (ignore value)) ; always nil anyway @@ -470,7 +480,7 @@ :include 'rex-simple :default-printer '(:name :tab accum ", " imm)) - (imm :type 'imm-data)) + (imm :type 'imm-data-upto-dword)) (sb!disassem:define-instruction-format (reg-no-width 8 :default-printer '(:name :tab reg)) @@ -604,7 +614,7 @@ :default-printer '(:name :tab reg/mem ", " imm)) (reg/mem :type 'sized-rex-reg/mem) - (imm :type 'imm-data)) + (imm :type 'imm-data-upto-dword)) ;;; Same as reg/mem, but with using the accumulator in the default printer (sb!disassem:define-instruction-format @@ -1199,7 +1209,8 @@ (:printer rex-reg-reg/mem-dir ((op #b100010))) ;; immediate to register/memory (:printer reg/mem-imm ((op '(#b1100011 #b000)))) - (:printer rex-reg/mem-imm ((op '(#b1100011 #b000)))) + ;; doesn't work for 8-bit register yet + (:printer rex-reg/mem-imm ((op '(#b11000111 #b000)))) (:emitter (let ((size (matching-operand-size dst src))) @@ -1377,6 +1388,8 @@ (:printer reg-no-width ((op #b10010)) '(:name :tab accum ", " reg)) ;; Register/Memory with Register. (:printer reg-reg/mem ((op #b1000011))) + ;; doesn't work for 8-bit register yet + (:printer rex-reg-reg/mem ((op #b10000111))) (:emitter (let ((size (matching-operand-size operand1 operand2))) (maybe-emit-operand-size-prefix segment size) @@ -2155,7 +2168,9 @@ (t (unless (or (ea-p where) (tn-p where)) (error "don't know what to do with ~A" where)) - (maybe-emit-rex-for-ea segment where nil) + ;; near jump defaults to 64 bit + ;; w-bit in rex prefix is unnecessary + (maybe-emit-rex-for-ea segment where nil :operand-size :dword) (emit-byte segment #b11111111) (emit-ea segment where #b100))))) diff --git a/tests/alien.impure.lisp b/tests/alien.impure.lisp index 6cd9807..d4365d3 100644 --- a/tests/alien.impure.lisp +++ b/tests/alien.impure.lisp @@ -97,7 +97,7 @@ (define-alien-type enum.2 (enum nil (zero 0) (one 1) (two 2) (three 3) (four 4) (five 5) (six 6) (seven 7) (eight 8) (nine 9))) -(with-alien ((integer-array (array integer 3))) +(with-alien ((integer-array (array int 3))) (let ((enum-array (cast integer-array (array enum.2 3)))) (setf (deref enum-array 0) 'three (deref enum-array 1) 'four) @@ -107,7 +107,7 @@ ;; The code that is used for mapping from integers to symbols depends on the ;; `density' of the set of used integers, so test with a sparse set as well. (define-alien-type enum.3 (enum nil (zero 0) (one 1) (k-one 1001) (k-two 1002))) -(with-alien ((integer-array (array integer 3))) +(with-alien ((integer-array (array int 3))) (let ((enum-array (cast integer-array (array enum.3 3)))) (setf (deref enum-array 0) 'one (deref enum-array 1) 'k-one) diff --git a/version.lisp-expr b/version.lisp-expr index b2bb4e6..7ab83d2 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"0.8.19.15" +"0.8.19.16" -- 1.7.10.4