;;; Two byte instruction with an immediate byte argument.
;;;
(sb!disassem:define-instruction-format (word-imm 24
- :default-printer '(:name :tab code))
- (op :field (byte 16 0))
+ :default-printer '(:name :tab code))
+ (op :field (byte 16 0))
(code :field (byte 8 16)))
\f
(stack
;; Convert stack tns into an index off of EBP.
(let ((disp (- (* (1+ (tn-offset thing)) n-word-bytes))))
- (cond ((< -128 disp 127)
+ (cond ((<= -128 disp 127)
(emit-mod-reg-r/m-byte segment #b01 reg #b101)
(emit-byte segment disp))
(t
(t
(error "bogus operands for TEST: ~S and ~S" this that)))))))
+;;; Emit the most compact form of the test immediate instruction,
+;;; using an 8 bit test when the immediate is only 8 bits and the
+;;; value is one of the four low registers (eax, ebx, ecx, edx) or the
+;;; control stack.
+(defun emit-optimized-test-inst (x y)
+ (typecase y
+ ((unsigned-byte 7)
+ (let ((offset (tn-offset x)))
+ (cond ((and (sc-is x any-reg descriptor-reg)
+ (or (= offset eax-offset) (= offset ebx-offset)
+ (= offset ecx-offset) (= offset edx-offset)))
+ (inst test (make-random-tn :kind :normal
+ :sc (sc-or-lose 'byte-reg)
+ :offset offset)
+ y))
+ ((sc-is x control-stack)
+ (inst test (make-ea :byte :base ebp-tn
+ :disp (- (* (1+ offset) n-word-bytes)))
+ y))
+ (t
+ (inst test x y)))))
+ (t
+ (inst test x y))))
+
(define-instruction or (segment dst src)
(:printer-list
(arith-inst-printer-list #b001))
;; Lisp (with (DESCRIBE 'BYTE-IMM-CODE)) than to definitively deduce
;; from first principles whether it's defined in some way that genesis
;; can't grok.
- (case (byte-imm-code chunk dstate)
+ (case #!-darwin (byte-imm-code chunk dstate)
+ #!+darwin (word-imm-code chunk dstate)
(#.error-trap
(nt "error trap")
(sb!disassem:handle-break-args #'snarf-error-junk stream dstate))
(define-instruction break (segment code)
(:declare (type (unsigned-byte 8) code))
- #-darwin (:printer byte-imm ((op #b11001100)) '(:name :tab code)
+ #!-darwin (:printer byte-imm ((op #b11001100)) '(:name :tab code)
:control #'break-control)
- #+darwin (:printer word-imm ((op #b0000101100001111)) '(:name :tab code)
+ #!+darwin (:printer word-imm ((op #b0000101100001111)) '(:name :tab code)
:control #'break-control)
(:emitter
- #-darwin (emit-byte segment #b11001100)
+ #!-darwin (emit-byte segment #b11001100)
;; On darwin, trap handling via SIGTRAP is unreliable, therefore we
;; throw a sigill with 0x0b0f instead and check for this in the
;; SIGILL handler and pass it on to the sigtrap handler if
;; appropriate
- #+darwin (emit-word segment #b0000101100001111)
+ #!+darwin (emit-word segment #b0000101100001111)
(emit-byte segment code)))
(define-instruction int (segment number)