+ (define-regular-sse-inst cvttpd2dq #x66 #xe6)
+ (define-regular-sse-inst cvttps2dq #xf3 #x5b)
+ ;; moves
+ (define-regular-sse-inst movntdq #x66 #xe7)
+ (define-regular-sse-inst movntpd #x66 #x2b)
+ (define-regular-sse-inst movntps nil #x2b)
+ ;; integer
+ (define-regular-sse-inst packsswb #x66 #x63)
+ (define-regular-sse-inst packssdw #x66 #x6b)
+ (define-regular-sse-inst punpckhbw #x66 #x68)
+ (define-regular-sse-inst punpckhwd #x66 #x69)
+ (define-regular-sse-inst punpckhdq #x66 #x6a)
+ (define-regular-sse-inst punpckhqdq #x66 #x6d)
+ (define-regular-sse-inst punpcklbw #x66 #x60)
+ (define-regular-sse-inst punpcklwd #x66 #x61)
+ (define-regular-sse-inst punpckldq #x66 #x62)
+ (define-regular-sse-inst punpcklqdq #x66 #x6c))
+
+(macrolet ((define-xmm-shuffle-sse-inst (name prefix opcode)
+ `(define-instruction ,name (segment dst src pattern)
+ ,@(if prefix
+ `((:printer ext-xmm-xmm/mem-imm ; suboptimal
+ ((prefix ,prefix) (op ,opcode)))
+ (:printer ext-rex-xmm-xmm/mem-imm
+ ((prefix ,prefix) (op ,opcode))))
+ `((:printer xmm-xmm/mem-imm ((op ,opcode)))
+ (:printer rex-xmm-xmm/mem-imm ((op ,opcode)))))
+ (:emitter
+ (aver (typep pattern '(unsigned-byte 8)))
+ (emit-regular-sse-inst segment dst src ,prefix ,opcode)
+ (emit-byte segment pattern)))))
+ (define-xmm-shuffle-sse-inst pshufd #x66 #x70)
+ (define-xmm-shuffle-sse-inst pshufhw #xf3 #x70)
+ (define-xmm-shuffle-sse-inst pshuflw #xf2 #x70)
+ (define-xmm-shuffle-sse-inst shufpd #x66 #xc6)
+ (define-xmm-shuffle-sse-inst shufps nil #xc6))
+
+;; MASKMOVDQU (dst is DS:RDI)
+(define-instruction maskmovdqu (segment src mask)
+ (:printer ext-xmm-xmm/mem
+ ((prefix #x66) (op #xf7)))
+ (:printer ext-rex-xmm-xmm/mem
+ ((prefix #x66) (op #xf7)))
+ (:emitter
+ (aver (xmm-register-p src))
+ (aver (xmm-register-p mask))
+ (emit-regular-sse-inst segment src mask #x66 #xf7)))
+
+(macrolet ((define-xmm-comparison-sse-inst (name prefix opcode &optional name-prefix name-suffix)
+ (let ((printer (when name-prefix
+ `'(,name-prefix cc ,name-suffix :tab reg ", " reg/mem))))
+ `(define-instruction ,name (segment op x y)
+ ,@(if prefix
+ `((:printer ext-xmm-xmm/mem-cmp
+ ((prefix ,prefix) (op ,opcode))
+ ,@(and printer `(,printer)))
+ (:printer ext-rex-xmm-xmm/mem-cmp
+ ((prefix ,prefix) (op ,opcode))
+ ,@(and printer `(,printer))))
+ `((:printer xmm-xmm/mem-cmp ((op ,opcode))
+ ,@(and printer `(,printer)))
+ (:printer rex-xmm-xmm/mem-cmp ((op ,opcode))
+ ,@(and printer `(,printer)))))
+ (:emitter
+ (let ((code (position op *sse-conditions*)))
+ (aver code)
+ (emit-regular-sse-inst segment x y ,prefix ,opcode)
+ (emit-byte segment code)))))))
+ (define-xmm-comparison-sse-inst cmppd #x66 #xc2 "CMP" "PD")
+ (define-xmm-comparison-sse-inst cmpps nil #xc2 "CMP" "PS")
+ (define-xmm-comparison-sse-inst cmpsd #xf2 #xc2 "CMP" "SD")
+ (define-xmm-comparison-sse-inst cmpss #xf3 #xc2 "CMP" "SS"))