-; (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
- (:emitter
- (cond ((typep dst 'tn)
- (emit-byte segment #xf3)
- (maybe-emit-rex-for-ea segment src dst)
- (emit-byte segment #x0f)
- (emit-byte segment #x7e)
- (emit-ea segment src (reg-tn-encoding dst)))
- (t
- (emit-byte segment #x66)
- (maybe-emit-rex-for-ea segment dst src)
- (emit-byte segment #x0f)
- (emit-byte segment #xd6)
- (emit-ea segment dst (reg-tn-encoding src))))))
-
-(define-instruction xorpd (segment dst src)
-; (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
- (:emitter
- (emit-byte segment #x66)
- (maybe-emit-rex-for-ea segment src dst)
- (emit-byte segment #x0f)
- (emit-byte segment #x57)
- (emit-ea segment src (reg-tn-encoding dst))))
-
-(define-instruction xorps (segment dst src)
-; (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
- (:emitter
- (maybe-emit-rex-for-ea segment src dst)
- (emit-byte segment #x0f)
- (emit-byte segment #x57)
- (emit-ea segment src (reg-tn-encoding dst))))
-
-(define-instruction cvtsd2si (segment dst src)
-; (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
- (:emitter
- (emit-byte segment #xf2)
- (maybe-emit-rex-for-ea segment src dst :operand-size :qword)
- (emit-byte segment #x0f)
- (emit-byte segment #x2d)
- (emit-ea segment src (reg-tn-encoding dst))))
-
-(define-instruction cvtsd2ss (segment dst src)
-; (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
- (:emitter
- (emit-byte segment #xf2)
- (maybe-emit-rex-for-ea segment src dst)
- (emit-byte segment #x0f)
- (emit-byte segment #x5a)
- (emit-ea segment src (reg-tn-encoding dst))))
-
-(define-instruction cvtss2si (segment dst src)
-; (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
- (:emitter
- (emit-byte segment #xf3)
- (maybe-emit-rex-for-ea segment src dst :operand-size :qword)
- (emit-byte segment #x0f)
- (emit-byte segment #x2d)
- (emit-ea segment src (reg-tn-encoding dst))))
-
-(define-instruction cvtss2sd (segment dst src)
-; (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
- (:emitter
- (emit-byte segment #xf3)
- (maybe-emit-rex-for-ea segment src dst)
- (emit-byte segment #x0f)
- (emit-byte segment #x5a)
- (emit-ea segment src (reg-tn-encoding dst))))
-
-(define-instruction cvtsi2ss (segment dst src)
-; (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
- (:emitter
- (emit-byte segment #xf3)
- (maybe-emit-rex-for-ea segment src dst)
- (emit-byte segment #x0f)
- (emit-byte segment #x2a)
- (emit-ea segment src (reg-tn-encoding dst))))
-
-(define-instruction cvtsi2sd (segment dst src)
-; (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
- (:emitter
- (emit-byte segment #xf2)
- (maybe-emit-rex-for-ea segment src dst)
- (emit-byte segment #x0f)
- (emit-byte segment #x2a)
- (emit-ea segment src (reg-tn-encoding dst))))
-
-(define-instruction cvtdq2pd (segment dst src)
-; (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
- (:emitter
- (emit-byte segment #xf3)
- (maybe-emit-rex-for-ea segment src dst)
- (emit-byte segment #x0f)
- (emit-byte segment #xe6)
- (emit-ea segment src (reg-tn-encoding dst))))
-
-(define-instruction cvtdq2ps (segment dst src)
-; (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
- (:emitter
- (maybe-emit-rex-for-ea segment src dst)
- (emit-byte segment #x0f)
- (emit-byte segment #x5b)
- (emit-ea segment src (reg-tn-encoding dst))))
-
-;; CVTTSD2SI CVTTSS2SI
-
-(define-instruction cvttsd2si (segment dst src)
-; (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
- (:emitter
- (emit-byte segment #xf2)
- (maybe-emit-rex-for-ea segment src dst :operand-size :qword)
- (emit-byte segment #x0f)
- (emit-byte segment #x2c)
- (emit-ea segment src (reg-tn-encoding dst))))
-
-(define-instruction cvttss2si (segment dst src)
-; (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
- (:emitter
- (emit-byte segment #xf3)
- (maybe-emit-rex-for-ea segment src dst :operand-size :qword)
- (emit-byte segment #x0f)
- (emit-byte segment #x2c)
- (emit-ea segment src (reg-tn-encoding dst))))
-
-(define-instruction addsd (segment dst src)
-; (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
- (:emitter
- (emit-byte segment #xf2)
- (maybe-emit-rex-for-ea segment src dst)
- (emit-byte segment #x0f)
- (emit-byte segment #x58)
- (emit-ea segment src (reg-tn-encoding dst))))
-
-(define-instruction addss (segment dst src)
-; (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
- (:emitter
- (emit-byte segment #xf3)
- (maybe-emit-rex-for-ea segment src dst)
- (emit-byte segment #x0f)
- (emit-byte segment #x58)
- (emit-ea segment src (reg-tn-encoding dst))))
-
-(define-instruction divsd (segment dst src)
-; (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
- (:emitter
- (emit-byte segment #xf2)
- (maybe-emit-rex-for-ea segment src dst)
- (emit-byte segment #x0f)
- (emit-byte segment #x5e)
- (emit-ea segment src (reg-tn-encoding dst))))
-
-(define-instruction divss (segment dst src)
-; (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
- (:emitter
- (emit-byte segment #xf3)
- (maybe-emit-rex-for-ea segment src dst)
- (emit-byte segment #x0f)
- (emit-byte segment #x5e)
- (emit-ea segment src (reg-tn-encoding dst))))
-
-(define-instruction mulsd (segment dst src)
-; (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
- (:emitter
- (emit-byte segment #xf2)
- (maybe-emit-rex-for-ea segment src dst)
- (emit-byte segment #x0f)
- (emit-byte segment #x59)
- (emit-ea segment src (reg-tn-encoding dst))))
-
-(define-instruction mulss (segment dst src)
-; (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
- (:emitter
- (emit-byte segment #xf3)
- (maybe-emit-rex-for-ea segment src dst)
- (emit-byte segment #x0f)
- (emit-byte segment #x59)
- (emit-ea segment src (reg-tn-encoding dst))))
-
-(define-instruction subsd (segment dst src)
-; (:printer reg-reg/mem ((op #x10) (width 1))) ;wrong
+ (:printer ext-xmm-xmm/mem ((prefix #xf3) (op #x7e)))
+ (:printer ext-rex-xmm-xmm/mem ((prefix #xf3) (op #x7e)))
+ (:printer ext-xmm-xmm/mem ((prefix #x66) (op #xd6))
+ '(:name :tab reg/mem ", " reg))
+ (:printer ext-rex-xmm-xmm/mem ((prefix #x66) (op #xd6))
+ '(:name :tab reg/mem ", " reg))
+ (:emitter
+ (cond ((xmm-register-p dst)
+ (emit-sse-inst segment dst src #xf3 #x7e
+ :operand-size :do-not-set))
+ (t
+ (aver (xmm-register-p src))
+ (emit-sse-inst segment src dst #x66 #xd6
+ :operand-size :do-not-set)))))
+
+;;; Instructions having an XMM register as the destination operand
+;;; and a general-purpose register or a memory location as the source
+;;; operand. The operand size is calculated from the source operand.
+
+;;; MOVD - Move a 32- or 64-bit value from a general-purpose register or
+;;; a memory location to the low order 32 or 64 bits of an XMM register
+;;; with zero extension or vice versa.
+;;; We do not support the MMX version of this instruction.
+(define-instruction movd (segment dst src)
+ (:printer ext-xmm-reg/mem ((prefix #x66) (op #x6e)))
+ (:printer ext-rex-xmm-reg/mem ((prefix #x66) (op #x6e)))
+ (:printer ext-xmm-reg/mem ((prefix #x66) (op #x7e))
+ '(:name :tab reg/mem ", " reg))
+ (:printer ext-rex-xmm-reg/mem ((prefix #x66) (op #x7e))
+ '(:name :tab reg/mem ", " reg))
+ (:emitter
+ (cond ((xmm-register-p dst)
+ (emit-sse-inst segment dst src #x66 #x6e))
+ (t
+ (aver (xmm-register-p src))
+ (emit-sse-inst segment src dst #x66 #x7e)))))
+
+(macrolet ((define-integer-source-sse-inst (name prefix opcode)
+ `(define-instruction ,name (segment dst src)
+ (:printer ext-xmm-reg/mem ((prefix ,prefix) (op ,opcode)))
+ (:printer ext-rex-xmm-reg/mem ((prefix ,prefix) (op ,opcode)))
+ (:emitter
+ (aver (xmm-register-p dst))
+ (let ((src-size (operand-size src)))
+ (aver (or (eq src-size :qword) (eq src-size :dword))))
+ (emit-sse-inst segment dst src ,prefix ,opcode)))))
+ (define-integer-source-sse-inst cvtsi2sd #xf2 #x2a)
+ (define-integer-source-sse-inst cvtsi2ss #xf3 #x2a))
+
+;;; Instructions having a general-purpose register as the destination
+;;; operand and an XMM register or a memory location as the source
+;;; operand. The operand size is calculated from the destination
+;;; operand.
+
+(macrolet ((define-gpr-destination-sse-inst (name prefix opcode)
+ `(define-instruction ,name (segment dst src)
+ (:printer ext-reg-xmm/mem ((prefix ,prefix) (op ,opcode)))
+ (:printer ext-rex-reg-xmm/mem ((prefix ,prefix) (op ,opcode)))
+ (:emitter
+ (aver (register-p dst))
+ (let ((dst-size (operand-size dst)))
+ (aver (or (eq dst-size :qword) (eq dst-size :dword)))
+ (emit-sse-inst segment dst src ,prefix ,opcode
+ :operand-size dst-size))))))
+ (define-gpr-destination-sse-inst cvtsd2si #xf2 #x2d)
+ (define-gpr-destination-sse-inst cvtss2si #xf3 #x2d)
+ (define-gpr-destination-sse-inst cvttsd2si #xf2 #x2c)
+ (define-gpr-destination-sse-inst cvttss2si #xf3 #x2c))
+
+;;; Other SSE instructions
+
+(define-instruction ldmxcsr (segment src)