:type (unsigned-byte 64))
(!def-primitive-type fixnum (any-reg signed-reg)
:type (signed-byte #.(1+ sb!vm:n-positive-fixnum-bits)))
-;; x86-64 needs a signed-byte-32 for proper handling of c-call return values.
-#!+#.(cl:if (cl:= sb!vm::n-machine-word-bits 32) '(and) '(or x86-64))
+#!+#.(cl:if (cl:= sb!vm::n-machine-word-bits 32) '(and) '(or))
(!def-primitive-type signed-byte-32 (signed-reg descriptor-reg)
:type (signed-byte 32))
#!+#.(cl:if (cl:= sb!vm::n-machine-word-bits 64) '(and) '(or))
(setf (result-state-num-results state) (1+ num-results))
(multiple-value-bind (ptype reg-sc)
(if (alien-integer-type-signed type)
- (values (if (= (sb!alien::alien-integer-type-bits type) 32)
- 'signed-byte-32
- 'signed-byte-64)
- 'signed-reg)
+ (values 'signed-byte-64 'signed-reg)
(values 'unsigned-byte-64 'unsigned-reg))
(my-make-wired-tn ptype reg-sc (result-reg-offset num-results)))))
+(define-alien-type-method (integer :naturalize-gen) (type alien)
+ (if (and (alien-integer-type-signed type)
+ (<= (alien-type-bits type) 32))
+ `(sign-extend ,alien)
+ alien))
+
(define-alien-type-method (system-area-pointer :result-tn) (type state)
(declare (ignore type))
(let ((num-results (result-state-num-results state)))
,@(new-args))))))
(sb!c::give-up-ir1-transform))))
+;;; The ABI specifies that signed short/int's are returned as 32-bit
+;;; values. Negative values need to be sign-extended to 64-bits (done
+;;; in a :NATURALIZE-GEN alien-type-method).
+(defknown sign-extend (fixnum) fixnum (foldable flushable movable))
-
+(define-vop (sign-extend)
+ (:translate sign-extend)
+ (:policy :fast-safe)
+ (:args (val :scs (any-reg)))
+ (:arg-types fixnum)
+ (:results (res :scs (any-reg)))
+ (:result-types fixnum)
+ (:generator 1
+ (inst movsxd res
+ (make-random-tn :kind :normal
+ :sc (sc-or-lose 'dword-reg)
+ :offset (tn-offset val)))))
+
+(defun sign-extend (x)
+ (if (logbitp 31 x)
+ (dpb x (byte 32 0) -1)
+ (ldb (byte 32 0) x)))
(define-vop (foreign-symbol-address)
(:translate foreign-symbol-address)
(:temporary (:sc unsigned-reg :offset rax-offset :to :result) rax)
(:temporary (:sc unsigned-reg :offset rcx-offset
:from :eval :to :result) rcx)
+ (:ignore results)
(:vop-var vop)
(:save-p t)
(:generator 0
(inst call function)
;; To give the debugger a clue. XX not really internal-error?
(note-this-location vop :internal-error)
- ;; Sign-extend s-b-32 return values.
- (dolist (res (if (listp results)
- results
- (list results)))
- (let ((tn (tn-ref-tn res)))
- (when (eq (sb!c::tn-primitive-type tn)
- (primitive-type-or-lose 'signed-byte-32))
- (inst movsxd tn (make-random-tn :kind :normal
- :sc (sc-or-lose 'dword-reg)
- :offset (tn-offset tn))))))
;; FLOAT15 needs to contain FP zero in Lispland
(inst xor rcx rcx)
(inst movd (make-random-tn :kind :normal
echo 'int summish(int x, int y) { return 1 + x + y; }' > $testfilestem.c
echo 'int numberish = 42;' >> $testfilestem.c
echo 'int nummish(int x) { return numberish + x; }' >> $testfilestem.c
+echo 'short negative_short() { return -1; }' >> $testfilestem.c
+echo 'int negative_int() { return -2; }' >> $testfilestem.c
+echo 'long negative_long() { return -3; }' >> $testfilestem.c
build_so $testfilestem
echo 'int foo = 13;' > $testfilestem-b.c
(define-alien-variable "foo" int)
(define-alien-routine "bar" int)
+ (define-alien-routine "negative_short" short)
+ (define-alien-routine "negative_int" int)
+ (define-alien-routine "negative_long" long)
+
;; Test that loading an object file didn't screw up our records
;; of variables visible in runtime. (This was a bug until
;; Nikodemus Siivola's patch in sbcl-0.8.5.50.)
(assert (= 13 numberish))
(assert (= 14 (nummish 1)))
+ (assert (= -1 (negative-short)))
+ (assert (= -2 (negative-int)))
+ (assert (= -3 (negative-long)))
+
(print :stage-1)
;; test realoading object file with new definitions