PSIGNB/PSIGNW/PSIGND

Packed SIGN

Opcodes

Hex Mnemonic Encoding Long Mode Legacy Mode Description
66 0F 38 0A /r PSIGND xmm1, xmm2/m128 A Valid Valid Negate/zero/preserve packed doubleword integers in xmm1 depending on the corresponding sign in xmm2/m128.
0F 38 0A /r PSIGND mm1, mm2/m64 A Valid Valid Negate/zero/preserve packed doubleword integers in mm1 depending on the corresponding sign in mm2/m128.
66 0F 38 09 /r PSIGNW xmm1, xmm2/m128 A Valid Valid Negate/zero/preserve packed word integers in xmm1 depending on the corresponding sign in xmm2/m128.
0F 38 09 /r PSIGNW mm1, mm2/m64 A Valid Valid Negate/zero/preserve packed word integers in mm1 depending on the corresponding sign in mm2/m128.
66 0F 38 08 /r PSIGNB xmm1, xmm2/m128 A Valid Valid Negate/zero/preserve packed byte integers in xmm1 depending on the corresponding sign in xmm2/m128.
0F 38 08 /r PSIGNB mm1, mm2/m64 A Valid Valid Negate/zero/preserve packed byte integers in mm1 depending on the corresponding sign in mm2/m64

Instruction Operand Encoding

Op/En Operand 0 Operand 1 Operand 2 Operand 3
A NA NA ModRM:r/m (r) ModRM:reg (r, w)

Description

PSIGNB/PSIGNW/PSIGND negates each data element of the destination operand (the first operand) if the signed integer value of the corresponding data element in the source operand (the second operand) is less than zero. If the signed integer value of a data element in the source operand is positive, the corresponding data element in the destination operand is unchanged. If a data element in the source operand is zero, the corresponding data element in the destination operand is set to zero.

PSIGNB operates on signed bytes. PSIGNW operates on 16-bit signed words. PSIGND operates on signed 32-bit integers. Both operands can be MMX register or XMM registers. When the source operand is a 128bit memory operand, the operand must be aligned on a 16-byte boundary or a general-protection exception (#GP) will be generated.

In 64-bit mode, use the REX prefix to access additional registers.

Pseudo Code

(* PSIGNB with 64 bit operands: *)
IF (SRC[7:0] < 0)
	DEST[7:0] = Neg(DEST[7:0])
ELSE
	IF (SRC[7:0] = 0)
		DEST[7:0] = 0
	ELSE
		IF (SRC[7:0] > 0)
			DEST[7:0] = DEST[7:0]
		FI;
	FI;
FI;
(* Repeat operation for 2nd through 7th bytes *)
IF (SRC[63:56] < 0)
	DEST[63:56] = Neg(DEST[63:56])
ELSE
	IF (SRC[63:56] = 0)
		DEST[63:56] = 0
	ELSE
		IF (SRC[63:56] > 0)
			DEST[63:56] = DEST[63:56]
		FI;
	FI;
FI;
(* PSIGNB with 128 bit operands: *)
IF (SRC[7:0] < 0)
	DEST[7:0] = Neg(DEST[7:0])
ELSE
	IF (SRC[7:0] = 0)
		DEST[7:0] = 0
	ELSE
		IF (SRC[7:0] > 0)
			DEST[7:0] = DEST[7:0]
		FI;
	FI;
FI;
(* Repeat operation for 2nd through 15th bytes *)
IF (SRC[127:120] < 0)
	DEST[127:120] = Neg(DEST[127:120])
ELSE
	IF (SRC[127:120] = 0)
		DEST[127:120] = 0
	ELSE
		IF (SRC[127:120] > 0)
			DEST[127:120] = DEST[127:120]
		FI;
	FI;
FI;
(* PSIGNW with 64 bit operands: *)
IF (SRC[15:0] < 0)
	DEST[15:0] = Neg(DEST[15:0])
ELSE
	IF (SRC[15:0] = 0)
		DEST[15:0] = 0
	ELSE
		IF (SRC[15:0] > 0)
			DEST[15:0] = DEST[15:0]
		FI;
	FI;
FI;
(* Repeat operation for 2nd through 3rd words *)
IF (SRC[63:48] < 0)
	DEST[63:48] = Neg(DEST[63:48])
ELSE
	IF (SRC[63:48] = 0)
		DEST[63:48] = 0
	ELSE
		IF (SRC[63:48] > 0)
			DEST[63:48] = DEST[63:48]
		FI;
	FI;
FI;
(* PSIGNW with 128 bit operands: *)
IF (SRC[15:0] < 0)
	DEST[15:0] = Neg(DEST[15:0])
ELSE
	IF (SRC[15:0] = 0)
		DEST[15:0] = 0
	ELSE
		IF (SRC[15:0] > 0)
			DEST[15:0] = DEST[15:0]
		FI;
	FI;
FI;
(* Repeat operation for 2nd through 7th words *)
IF (SRC[127:112] < 0)
	DEST[127:112] = Neg(DEST[127:112])
ELSE
	IF (SRC[127:112] = 0)
		DEST[127:112] = 0
	ELSE
		IF (SRC[127:112] > 0)
			DEST[127:112] = DEST[127:112]
		FI;
	FI;
FI;
(* PSIGND with 64 bit operands: *)
IF (SRC[31:0] < 0)
	DEST[31:0] = Neg(DEST[31:0])
ELSE
	IF (SRC[31:0] = 0)
		DEST[31:0] = 0
	ELSE
		IF (SRC[31:0] > 0)
			DEST[31:0] = DEST[31:0]
			IF (SRC[63:32] < 0)
				DEST[63:32] = Neg(DEST[63:32])
			ELSE
				IF (SRC[63:32] = 0)
					DEST[63:32] = 0
				ELSE
					IF (SRC[63:32] > 0)
						DEST[63:32] = DEST[63:32]
					FI;
				FI;
			FI;
		FI;
	FI;
FI;
(* PSIGND with 128 bit operands: *)
IF (SRC[31:0] < 0)
	DEST[31:0] = Neg(DEST[31:0])
ELSE
	IF (SRC[31:0] = 0)
		DEST[31:0] = 0
	ELSE
		IF (SRC[31:0] > 0)
			DEST[31:0] = DEST[31:0]
		FI;
	FI;
FI;
(* Repeat operation for 2nd through 3rd double words *)
IF (SRC[127:96] < 0)
	DEST[127:96] = Neg(DEST[127:96])
ELSE
	IF (SRC[127:96] = 0)
		DEST[127:96] = 0
	ELSE
		IF (SRC[127:96] > 0)
		FI;
	FI;
FI;

Flags Affected

None. Numeric Exceptions None.

Exceptions

Numeric Exceptions

None.

64-Bit Mode Exceptions

Exception Description
#AC(0) (64-bit operations only) If alignment checking is enabled and an unaligned memory reference is made while the current privilege level is 3.
#PF(fault-code) If a page fault occurs.
#MF (64-bit operations only) If there is a pending x87 FPU exception.
#NM If CR0.TS[bit 3] = 1.
#UD If CR0.EM[bit 2] = 1. (128-bit operations only) If CR4.OSFXSR[bit 9] = 0. If CPUID.01H:ECX.SSSE3[bit 9] = 0. If the LOCK prefix is used.
#GP(0) If the memory address is in a non-canonical form. (128-bit operations only) If memory operand is not aligned on a 16-byte boundary, regardless of segment.
#SS(0) If a memory address referencing the SS segment is in a non-canonical form.

Compatibility Mode Exceptions

Same as for protected mode exceptions.

Virtual-8086 Mode Exceptions

Exception Description
#AC(0) (64-bit operations only) If alignment checking is enabled and unaligned memory reference is made.
#PF(fault-code) If a page fault occurs.
Same exceptions as in real address mode.

Real-Address Mode Exceptions

Exception Description
#MF (64-bit operations only) If there is a pending x87 FPU exception.
#NM If TS bit in CR0 is set.
#UD (128-bit operations only) If CR0.EM = 1. If CR4.OSFXSR(bit 9) = 0. If CPUID.SSSE3(ECX bit 9) = 0. If the LOCK prefix is used.
#GP(0) If any part of the operand lies outside of the effective address space from 0 to 0FFFFH. (128-bit operations only) If not aligned on 16-byte boundary, regardless of segment.

Protected Mode Exceptions

Exception Description
#AC(0) (64-bit operations only) If alignment checking is enabled and unaligned memory reference is made while the current privilege level is 3.
#MF (64-bit operations only) If there is a pending x87 FPU exception.
#NM If TS bit in CR0 is set.
#UD If CR0.EM = 1. (128-bit operations only) If CR4.OSFXSR(bit 9) = 0. If CPUID.SSSE3(ECX bit 9) = 0. If the LOCK prefix is used.
#PF(fault-code) If a page fault occurs.
#SS(0) If a memory operand effective address is outside the SS segment limit.
#GP(0) If a memory operand effective address is outside the CS, DS, ES, FS or GS segments. (128-bit operations only) If not aligned on 16-byte boundary, regardless of segment.