1. Integer Arithmetic#
1.1. dp4a#
Compute the dot product of four pairs of bytes from two 32-bit operands, and add a 32-bit accumulator.
Syntax:
dp4a.signedness<.dsat>.type dst, src0, src1, src2 .signedness = { .ss, .us, .su, .uu } .type = { .32b } - dst is a 32-bit register - src0, src1, src2 can be 32-bit registers or immediates
Restrictions
qualifier
.dsatmust not be specified when qualifier.signednessis.uu
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Semantics:
src2_signed = .signedness == .us || .signedness == .ss
src1_signed = .signedness == .su || .signedness == .ss
if (src1_signed) {
src1_0 = sign_extend(src1[7:0], 32)
src1_1 = sign_extend(src1[15:8], 32)
src1_2 = sign_extend(src1[23:16], 32)
src1_3 = sign_extend(src1[31:24], 32)
} else {
src1_0 = zero_extend(src1[7:0], 32)
src1_1 = zero_extend(src1[15:8], 32)
src1_2 = zero_extend(src1[23:16], 32)
src1_3 = zero_extend(src1[31:24], 32)
}
if (src2_signed) {
src2_0 = sign_extend(src2[7:0], 32)
src2_1 = sign_extend(src2[15:8], 32)
src2_2 = sign_extend(src2[23:16], 32)
src2_3 = sign_extend(src2[31:24], 32)
} else {
src2_0 = zero_extend(src2[7:0], 32)
src2_1 = zero_extend(src2[15:8], 32)
src2_2 = zero_extend(src2[23:16], 32)
src2_3 = zero_extend(src2[31:24], 32)
}
dst = src0 + src1_0*src2_0 + src1_1*src2_1 + src1_2*src2_2 + src1_3*src2_3
Notes:
Enabling saturation via .dsat qualifier clamps the final result to between
the min/max values representable by signed 32-bit integer. The addition of the
results of the multiplications cannot overflow, but the addition of src0
can cause overflow and therefore obeys the saturation control.
Examples:
.reg .32b %dst, %src0, %src1, %src2;
// src0, src1, and src2 are treated as unsigned
dp4a.uu.32b %dst, %src0, %src1, %src2;
// src1 is treated as signed, src2 as unsigned
dp4a.su.32b %dst, %src0, %src1, %src2;
// src0, src1, and src2 are treated as signed with saturation
dp4a.ss.dsat.32b %dst, %src0, %src1, %src2;
1.2. iabs#
Compute the absolute value of an integer.
Syntax:
iabs.type dst, src0 .type = { .16b, .32b, .64b } - dst is a register - src0 can be a register or an immediate * src0 is interpreted as signed integer.
Restrictions
bitwidth of
dstandsrc0must match the bitwidth of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Semantics:
default#dst = |src0|
Examples:
.reg .32b %dst, %src0;
// absolute value of a 32-bit element
iabs.32b %dst, %src0;
1.3. iadd#
Add two integer values.
Syntax:
iadd<.dsat>.type dst, src0, src1 .type = { .16b, .32b, .64b } - dst is a register - src0, src1 can be registers or immediates * src0, src1 are interpreted as signed integers.
Restrictions
bitwidth of
dst,src0, andsrc1must match the bitwidth of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
packed:
iadd<.dsat>.type dst, src0, src1 .type = { .8bx4, .16bx2 } - dst, src0, src1 are packed registers * src0, src1 are interpreted as signed integers.
Restrictions
element count and bitwidth of
dst,src0andsrc1must match definitions of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Semantics:
.type == .16bx2#dst[15:0] = src0[15:0] + src1[15:0]
dst[31:16] = src0[31:16] + src1[31:16]
.type == .8bx4#dst[7:0] = src0[7:0] + src1[7:0]
dst[15:8] = src0[15:8] + src1[15:8]
dst[23:16] = src0[23:16] + src1[23:16]
dst[31:24] = src0[31:24] + src1[31:24]
default#dst = src0 + src1
Notes:
Enabling the .dsat qualifier clamps the final result to the minimum and
maximum values representable by a signed integer of the element bitwidth of
the specified .type.
Examples:
.reg .32b %dst, %src0, %src1;
// addition of 32-bit elements
iadd.32b %dst, %src0, %src1;
// element-wise addition of 4x8-bit packed values
.reg .v4.8b %dst_4x8, %src0_4x8, %src1_4x8;
iadd.8bx4 %dst_4x8, %src0_4x8, %src1_4x8;
// element-wise addition of 2x16-bit packed values
.reg .v2.16b %dst_packed, %src0_packed, %src1_packed;
iadd.16bx2 %dst_packed, %src0_packed, %src1_packed;
1.4. ineg#
Negate an integer value.
Syntax:
ineg.type dst, src0 .type = { .16b, .32b, .64b } - dst is a register - src0 can be a register or an immediate * src0 is interpreted as signed integer.
Restrictions
bitwidth of
dstandsrc0must match the bitwidth of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Semantics:
dst = -src0
Examples:
.reg .32b %dst, %src0;
// negate 32-bit element
ineg.32b %dst, %src0;
1.5. isub#
Subtract two integer values.
Syntax:
isub<.dsat>.type dst, src0, src1 .type = { .16b, .32b, .64b } - dst is a register - src0, src1 can be registers or immediates * src0, src1 are interpreted as signed integers.
Restrictions
bitwidth of
dst,src0, andsrc1must match the bitwidth of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
packed:
isub<.dsat>.type dst, src0, src1 .type = { .16bx2 } - dst, src0, src1 are 2x16-bit vector registers * src0, src1 are interpreted as signed integers.
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Semantics:
.type == .16bx2#dst[15:0] = src0[15:0] - src1[15:0]
dst[31:16] = src0[31:16] - src1[31:16]
default#dst = src0 - src1
Notes:
Enabling the .dsat qualifier clamps the final result to the minimum and
maximum values representable by a signed integer of the element bitwidth of
the specified .type.
Examples:
.reg .32b %dst, %src0, %src1;
// subtraction of 32-bit elements
isub.32b %dst, %src0, %src1;
// element-wise subtraction of 2x16-bit packed values
.reg .v2.16b %dst_packed, %src0_packed, %src1_packed;
isub.16bx2 %dst_packed, %src0_packed, %src1_packed;
1.6. sdiv#
Divide two signed integers.
Syntax:
sdiv<.output>.type dst, src0, src1 .output = { .quo, .rem } .type = { .16b, .32b, .64b } - dst is a register - src0, src1 can be registers or immediates * src0, src1 are interpreted as signed integers.
Restrictions
bitwidth of
dst,src0, andsrc1must match the bitwidth of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Notes:
Division by zero is undefined behavior.
Examples:
.reg .32b %dst, %src0, %src1;
// compute quotent from 32-bit signed integer division
sdiv.quo.32b %dst, %src0, %src1;
// compute remainder from 32-bit signed integer division
sdiv.rem.32b %dst, %src0, %src1;
1.7. smad#
Multiply and add signed integers.
Widening signed multiply-add:
smad.precision.type dst, src0, src1, src2 .precision = { .full } .type = { .16b, .32b } - dst is a register - src0, src1, src2 can be registers or immediates * src0, src1, src2 are interpreted as signed integers.
Restrictions
bitwidth of
src0andsrc1must match the bitwidth of.typebitwidth of
dstandsrc2must be twice the bitwidth of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Signed multiply-add:
smad.type dst, src0, src1, src2 .type = { .16b, .32b, .64b } - dst is a register - src0, src1, src2 can be registers or immediates * src0, src1, src2 are interpreted as signed integers.
Restrictions
bitwidth of
dst,src0,src1, andsrc2must match the bitwidth of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
packed:
smad.type dst, src0, src1, src2 .type = { .16bx2 } - dst, src0, src1, src2 are 2x16-bit vector registers * src0, src1, src2 are interpreted as signed integers.
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Semantics:
.precision == .full#src0_extend = sign_extend(src0, bitwidth(.type)*2)
src1_extend = sign_extend(src1, bitwidth(.type)*2)
dst = src0_extend * src1_extend + src2
.type == .16bx2#dst[15:0] = src0[15:0] * src1[15:0] + src2[15:0]
dst[31:16] = src0[31:16] * src1[31:16] + src2[31:16]
default#dst = src0 * src1 + src2
Examples:
.reg .32b %dst, %src0, %src1, %src2;
.reg .64b %dst64, %src64;
// signed multiply and add 32-bit elements
smad.32b %dst, %src0, %src1, %src2;
// signed multiply and add 32-bit elements with full precision
smad.full.32b %dst64, %src0, %src1, %src64;
// element-wise signed multiply and add of 2x16-bit packed values
.reg .v2.16b %dst_packed, %src0_packed, %src1_packed, %src2_packed;
smad.16bx2 %dst_packed, %src0_packed, %src1_packed, %src2_packed;
1.8. smax#
Find the maximum of two signed integers.
Syntax:
smax.type dst, src0, src1 .type = { .16b, .32b, .64b } - dst is a register - src0, src1 can be registers or immediates * src0, src1 are interpreted as signed integers.
Restrictions
bitwidth of
dst,src0, andsrc1must match the bitwidth of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
packed:
smax.type dst, src0, src1 .type = { .8bx4, .16bx2 } - dst, src0, src1 are packed registers * src0, src1 are interpreted as signed integers.
Restrictions
element count and bitwidth of
dst,src0andsrc1must match definitions of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Semantics:
.type == .16bx2#dst[15:0] = src0[15:0] > src1[15:0] ? src0[15:0] : src1[15:0]
dst[31:16] = src0[31:16] > src1[31:16] ? src0[31:16] : src1[31:16]
.type == .8bx4#dst[7:0] = src0[7:0] > src1[7:0] ? src0[7:0] : src1[7:0]
dst[15:8] = src0[15:8] > src1[15:8] ? src0[15:8] : src1[15:8]
dst[23:16] = src0[23:16] > src1[23:16] ? src0[23:16] : src1[23:16]
dst[31:24] = src0[31:24] > src1[31:24] ? src0[31:24] : src1[31:24]
default#dst = src0 > src1 ? src0 : src1
Examples:
.reg .32b %dst, %src0, %src1;
// maximum element from 2 signed 32-bit elements
smax.32b %dst, %src0, %src1;
// element-wise maximum of 2x16-bit packed values
.reg .v2.16b %dst_packed, %src0_packed, %src1_packed;
smax.16bx2 %dst_packed, %src0_packed, %src1_packed;
// element-wise maximum of 4x8-bit packed values
.reg .v4.8b %dst_4x8, %src0_4x8, %src1_4x8;
smax.8bx4 %dst_4x8, %src0_4x8, %src1_4x8;
1.9. smin#
Find the minimum of two signed integers.
Syntax:
smin.type dst, src0, src1 .type = { .16b, .32b, .64b } - dst is a register - src0, src1 can be registers or immediates * src0, src1 are interpreted as signed integers.
Restrictions
bitwidth of
dst,src0, andsrc1must match the bitwidth of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
packed:
smin.type dst, src0, src1 .type = { .8bx4, .16bx2 } - dst, src0, src1 are packed registers * src0, src1 are interpreted as signed integers.
Restrictions
element count and bitwidth of
dst,src0andsrc1must match definitions of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Semantics:
.type == .16bx2#dst[15:0] = src0[15:0] < src1[15:0] ? src0[15:0] : src1[15:0]
dst[31:16] = src0[31:16] < src1[31:16] ? src0[31:16] : src1[31:16]
.type == .8bx4#dst[7:0] = src0[7:0] < src1[7:0] ? src0[7:0] : src1[7:0]
dst[15:8] = src0[15:8] < src1[15:8] ? src0[15:8] : src1[15:8]
dst[23:16] = src0[23:16] < src1[23:16] ? src0[23:16] : src1[23:16]
dst[31:24] = src0[31:24] < src1[31:24] ? src0[31:24] : src1[31:24]
default#dst = src0 < src1 ? src0 : src1
Examples:
.reg .32b %dst, %src0, %src1;
// minimum element from 2 signed 32-bit elements
smin.32b %dst, %src0, %src1;
// element-wise minimum of 2x16-bit packed values
.reg .v2.16b %dst_packed, %src0_packed, %src1_packed;
smin.16bx2 %dst_packed, %src0_packed, %src1_packed;
// element-wise minimum of 4x8-bit packed values
.reg .v4.8b %dst_4x8, %src0_4x8, %src1_4x8;
smin.8bx4 %dst_4x8, %src0_4x8, %src1_4x8;
1.10. smul#
Multiply two signed integers.
Widening signed multiply:
smul.precision.type dst, src0, src1 .precision = { .full } .type = { .16b, .32b } - dst is a register - src0, src1 can be registers or immediates * src0, src1 are interpreted as signed integers.
Restrictions
bitwidth of
src0andsrc1must match the bitwidth of.typebitwidth of
dstmust be twice the bitwidth of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Signed multiply:
smul.type dst, src0, src1 .type = { .16b, .32b, .64b } - dst is a register - src0, src1 can be registers or immediates * src0, src1 are interpreted as signed integers.
Restrictions
bitwidth of
dst,src0, andsrc1must match the bitwidth of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
packed:
smul.type dst, src0, src1 .type = { .16bx2 } - dst, src0, src1 are 2x16-bit vector registers * src0, src1 are interpreted as signed integers.
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Semantics:
.precision == .full#src0_extend = sign_extend(src0, bitwidth(.type)*2)
src1_extend = sign_extend(src1, bitwidth(.type)*2)
dst = src0_extend * src1_extend
.type == .16bx2#dst[15:0] = src0[15:0] * src1[15:0]
dst[31:16] = src0[31:16] * src1[31:16]
default#dst = src0 * src1
Examples:
.reg .32b %dst, %src0, %src1;
.reg .64b %dst64;
// signed multiply 32-bit elements
smul.32b %dst, %src0, %src1;
// signed multiply 32-bit elements with full precision
smul.full.32b %dst64, %src0, %src1;
// element-wise signed multiply of 2x16-bit packed values
.reg .v2.16b %dst_packed, %src0_packed, %src1_packed;
smul.16bx2 %dst_packed, %src0_packed, %src1_packed;
1.11. uaddc#
Add unsigned integers with carry.
Add with carry-in:
uaddc.ci.type dst, src0, src1, carry-in .type = { .32b } - dst is a 32-bit register - src0, src1 can be 32-bit registers or immediates - carry-in is a predicate register * src0, src1 are interpreted as unsigned integers.
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Add with carry-out:
uaddc.co.type dst, carry-out, src0, src1 .type = { .32b } - dst is a 32-bit register - carry-out is a predicate register - src0, src1 can be 32-bit registers or immediates * src0, src1 are interpreted as unsigned integers.
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Add with carry-in and carry-out:
uaddc.ci.co.type dst, carry-out, src0, src1, carry-in .type = { .32b } - dst is a 32-bit register - carry-out, carry-in are predicate registers - src0, src1 can be 32-bit registers or immediates * src0, src1 are interpreted as unsigned integers.
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Semantics:
if ('.ci' is set)
dst = src0 + src1 + carry-in
else
dst = src0 + src1
if ('.co' is set)
carry-out = 1 if the result overflows uint32, 0 otherwise
Examples:
.reg .32b %dst, %src0, %src1;
.pred %pin, %pout;
// add two 32-bit unsigned values with carry-out
uaddc.co.32b %dst, %pout, %src0, %src1;
// add two 32-bit unsigned values with carry-in
uaddc.ci.32b %dst, %src0, %src1, %pin;
.reg .64b %dst, %src0, %src1;
.reg .v2.32b %dst_vec, %src0_vec, %src1_vec;
.pred %p0;
// unpack 64-bit operands into 32-bit halves (.x = low, .y = high)
mov.64b %src0_vec.xy, %src0;
mov.64b %src1_vec.xy, %src1;
// add low 32-bit halves with carry-out
uaddc.co.32b %dst_vec.x, %p0, %src0_vec.x, %src1_vec.x;
// add high 32-bit halves with carry-in
uaddc.ci.32b %dst_vec.y, %src0_vec.y, %src1_vec.y, %p0;
// pack 32-bit halves back into 64-bit result
mov.64b %dst, %dst_vec.xy;
1.12. udiv#
Divide two unsigned integers.
Syntax:
udiv<.output>.type dst, src0, src1 .output = { .quo, .rem } .type = { .16b, .32b, .64b } - dst is a register - src0, src1 can be registers or immediates * src0, src1 are interpreted as unsigned integers.
Restrictions
bitwidth of
dst,src0, andsrc1must match the bitwidth of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Notes:
Division by zero is undefined behavior.
Examples:
.reg .32b %dst, %src0, %src1;
// compute quotent from 32-bit unsigned integer division
udiv.quo.32b %dst, %src0, %src1;
// compute remainder from 32-bit unsigned integer division
udiv.rem.32b %dst, %src0, %src1;
1.13. umad#
Multiply and add unsigned integers.
Widening unsigned multiply-add:
umad.precision.type dst, src0, src1, src2 .precision = { .full } .type = { .16b, .32b } - dst is a register - src0, src1, src2 can be registers or immediates * src0, src1, src2 are interpreted as unsigned integers.
Restrictions
bitwidth of
src0andsrc1must match the bitwidth of.typebitwidth of
dstandsrc2must be twice the bitwidth of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Unsigned multiply-add:
umad.type dst, src0, src1, src2 .type = { .16b, .32b, .64b } - dst is a register - src0, src1, src2 can be registers or immediates * src0, src1, src2 are interpreted as unsigned integers.
Restrictions
bitwidth of
dst,src0,src1, andsrc2must match the bitwidth of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Semantics:
.precision == .full#src0_extend = zero_extend(src0, bitwidth(.type)*2)
src1_extend = zero_extend(src1, bitwidth(.type)*2)
dst = src0_extend * src1_extend + src2
default#dst = src0 * src1 + src2
Examples:
.reg .32b %dst, %src0, %src1, %src2;
.reg .64b %dst64, %src64;
// unsigned multiply and add 32-bit elements
umad.32b %dst, %src0, %src1, %src2;
// unsigned multiply and add 32-bit elements with full precision
umad.full.32b %dst64, %src0, %src1, %src64;
1.14. umax#
Find the maximum of two unsigned integers.
Syntax:
umax.type dst, src0, src1 .type = { .16b, .32b, .64b } - dst is a register - src0, src1 can be registers or immediates * src0, src1 are interpreted as unsigned integers.
Restrictions
bitwidth of
dst,src0, andsrc1must match the bitwidth of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
packed:
umax.type dst, src0, src1 .type = { .16bx2 } - dst, src0, src1 are 2x16-bit vector registers * src0, src1 are interpreted as unsigned integers.
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Semantics:
.type == .16bx2#dst[15:0] = src0[15:0] > src1[15:0] ? src0[15:0] : src1[15:0]
dst[31:16] = src0[31:16] > src1[31:16] ? src0[31:16] : src1[31:16]
default#dst = src0 > src1 ? src0 : src1
Examples:
.reg .32b %dst, %src0, %src1;
// maximum element from 2 unsigned 32-bit elements
umax.32b %dst, %src0, %src1;
// element-wise maximum of 2x16-bit packed values
.reg .v2.16b %dst_packed, %src0_packed, %src1_packed;
umax.16bx2 %dst_packed, %src0_packed, %src1_packed;
1.15. umin#
Find the minimum of two unsigned integers.
Syntax:
umin.type dst, src0, src1 .type = { .16b, .32b, .64b } - dst is a register - src0, src1 can be registers or immediates * src0, src1 are interpreted as unsigned integers.
Restrictions
bitwidth of
dst,src0, andsrc1must match the bitwidth of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
packed:
umin.type dst, src0, src1 .type = { .16bx2 } - dst, src0, src1 are 2x16-bit vector registers * src0, src1 are interpreted as unsigned integers.
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Semantics:
.type == .16bx2#dst[15:0] = src0[15:0] < src1[15:0] ? src0[15:0] : src1[15:0]
dst[31:16] = src0[31:16] < src1[31:16] ? src0[31:16] : src1[31:16]
default#dst = src0 < src1 ? src0 : src1
Examples:
.reg .32b %dst, %src0, %src1;
// minimum element from 2 unsigned 32-bit elements
umin.32b %dst, %src0, %src1;
// element-wise minimum of 2x16-bit packed values
.reg .v2.16b %dst_packed, %src0_packed, %src1_packed;
umin.16bx2 %dst_packed, %src0_packed, %src1_packed;
1.16. umul#
Multiply two unsigned integers.
Widening unsigned multiply:
umul.precision.type dst, src0, src1 .precision = { .full } .type = { .16b, .32b } - dst is a register - src0, src1 can be registers or immediates * src0, src1 are interpreted as unsigned integers.
Restrictions
bitwidth of
src0andsrc1must match the bitwidth of.typebitwidth of
dstmust be twice the bitwidth of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Unsigned multiply:
umul.type dst, src0, src1 .type = { .16b, .32b, .64b } - dst is a register - src0, src1 can be registers or immediates * src0, src1 are interpreted as unsigned integers.
Restrictions
bitwidth of
dst,src0, andsrc1must match the bitwidth of.type
PISA Notes
introduced in PISA version 0.1
requires PISA target 100 or compatible
Semantics:
.precision == .full#src0_extend = zero_extend(src0, bitwidth(.type)*2)
src1_extend = zero_extend(src1, bitwidth(.type)*2)
dst = src0_extend * src1_extend
default#dst = src0 * src1
Examples:
.reg .32b %dst, %src0, %src1;
.reg .64b %dst64;
// unsigned multiply 32-bit elements
umul.32b %dst, %src0, %src1;
// unsigned multiply 32-bit elements with full precision
umul.full.32b %dst64, %src0, %src1;