+ (define-regular-sse-inst cvttpd2dq #x66 #xe6)
+ (define-regular-sse-inst cvttps2dq #xf3 #x5b)
+ ;; integer
+ (define-regular-sse-inst packsswb #x66 #x63)
+ (define-regular-sse-inst packssdw #x66 #x6b)
+ (define-regular-sse-inst packuswb #x66 #x67)
+ (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 n-bits radix)
+ (let ((shuffle-pattern
+ (intern (format nil "SSE-SHUFFLE-PATTERN-~D-~D"
+ n-bits radix))))
+ `(define-instruction ,name (segment dst src pattern)
+ (:printer-list
+ ',(sse-inst-printer-list
+ 'xmm-xmm/mem prefix opcode
+ :more-fields `((imm nil :type ,shuffle-pattern))
+ :printer '(:name :tab reg ", " reg/mem ", " imm)))
+
+ (:emitter
+ (aver (typep pattern '(unsigned-byte ,n-bits)))
+ (emit-regular-sse-inst segment dst src ,prefix ,opcode
+ :remaining-bytes 1)
+ (emit-byte segment pattern))))))
+ (define-xmm-shuffle-sse-inst pshufd #x66 #x70 8 4)
+ (define-xmm-shuffle-sse-inst pshufhw #xf3 #x70 8 4)
+ (define-xmm-shuffle-sse-inst pshuflw #xf2 #x70 8 4)
+ (define-xmm-shuffle-sse-inst shufpd #x66 #xc6 2 2)
+ (define-xmm-shuffle-sse-inst shufps nil #xc6 8 4))
+
+;; MASKMOVDQU (dst is DS:RDI)
+(define-instruction maskmovdqu (segment src mask)
+ (:printer-list
+ (sse-inst-printer-list 'xmm-xmm/mem #x66 #xf7))
+ (:emitter
+ (aver (xmm-register-p src))
+ (aver (xmm-register-p mask))
+ (emit-regular-sse-inst segment src mask #x66 #xf7)))
+
+(macrolet ((define-comparison-sse-inst (name prefix opcode
+ name-prefix name-suffix)
+ `(define-instruction ,name (segment op x y)
+ (:printer-list
+ ',(sse-inst-printer-list
+ 'xmm-xmm/mem prefix opcode
+ :more-fields '((imm nil :type sse-condition-code))
+ :printer `(,name-prefix imm ,name-suffix
+ :tab reg ", " reg/mem)))
+ (:emitter
+ (let ((code (position op *sse-conditions*)))
+ (aver code)
+ (emit-regular-sse-inst segment x y ,prefix ,opcode
+ :remaining-bytes 1)
+ (emit-byte segment code))))))
+ (define-comparison-sse-inst cmppd #x66 #xc2 "CMP" "PD")
+ (define-comparison-sse-inst cmpps nil #xc2 "CMP" "PS")
+ (define-comparison-sse-inst cmpsd #xf2 #xc2 "CMP" "SD")
+ (define-comparison-sse-inst cmpss #xf3 #xc2 "CMP" "SS"))