SPA 5.0:
{@{!}Pg}
ISET{.bval}.cmp{.fmt}{.X}
Rd{.CC}, Ra, Sb
{&req_6}
{?sched}
;
.bval: { .BM*, .BF } Boolean mask or Boolean float value set in Rd, default is .BM .cmp: { .F, .LT, .EQ, .LE, .GT, .NE, .GE, .T } Unsigned and signed comparisons { .LO, .LS, .HI, .HS, } Unsigned comparisons only .fmt: { .U32, .S32* } Default compare format is signed .S32, except unsigned .LO, .LS, .HI, .HS where the default compare format is .U32. The assembler throws a syntax error if signed format .S32 is explicitly combined with an unsigned comparison test. .X Extended precision compare .bop: { .AND, .OR, .XOR } Boolean op with predicate {!}Pp .CC: Write condition codes ISET allows for source operand Sb: Rb 32-bit register c[ImmU05][ImmU16] 32-bit constant with immediate slot and byte address ImmS20 32-bit sign-extended 20-bit immediate
{@{!}Pg}
ISET{.bval}.cmp{.fmt}{.X}.bop
Rd{.CC}, Ra, Sb, {!}Pp
{&req_6}
{?sched}
;
ISET{.bval}.cmp.bop compares register Ra and source operand Sb with integer comparison operation .cmp, combines the Boolean comparison result with predicate operand {!}Pp using Boolean operation .bop, and sets destination register Rd to integer ~0x0 or floating point 1.0f if the comparison is true, otherwise it sets Rd to 0. The Boolean operation .bop may be .AND, .OR, or .XOR, corresponding to C Boolean operations &, |, and ^.
if (.BM) Rd = ( (Ra .cmp Sb) .bop {!}Pp )? 0xFFFF_FFFF: 0; // SET Boolean mask all 1s or all 0s if (.BF) Rd = ( (Ra .cmp Sb) .bop {!}Pp )? 0x3F80_0000: 0; // SET Boolean float FP32 1.0f or 0.0f
One potential usage is for nested conditions, with an inner comparison of Ra vs. Sb, conditioned on an outer predicate Pp.
The simple instruction format without .bop {!}Pp assembles as .AND PT, effectively creating the following behavior:
if (.BM) Rd = (Ra .cmp Sb)? 0xFFFF_FFFF: 0; // Set Boolean mask all 1s or all 0s if (.BF) Rd = (Ra .cmp Sb)? 0x3F80_0000: 0; // Set Boolean float FP32 1.0f or 0.0f
Extended integer compare suffix .cmp{.fmt}.X compares Ra and Sb by subtracting Ra - Sb with a borrow from the condition code carry flag CC.CF, i.e. by computing Ra + ~Sb + CC.CF, comparing that with zero, and considering the condition code zero flag CC.ZF set by a prior subtraction.
for a table of the extended precision comparison modes. ISET.cmp.X may follow a sequence of IADD and IADD.X instructions that perform an extended-precision (multi-word) subtraction, thereby completing the most-significant word of an extended-precision comparison. ISET.cmp.X determines whether the extended .cmp.X comparison test is zero by ANDing the extended compare difference zero-ness with the prior condition code zero flag CC.ZF.
ISET.LT R8, R1, R2; // R8 = (R1.S32 < R2.S32)? ~0x0: 0; // default .BM format, .S32 format ISET.BM.LT.S32 R8, R1, R2; // identical instruction with explicit Boolean mask and signed format ISET.LO R8, R1, R2; // R8 = (R1.U32 < R2.U32)? ~0x0: 0; .LO => default unsigned format ISET.LT.U32 R8, R1, R2; // identical instruction with explicit unsigned format ISET.BM.LT RZ.CC, R1, R2; // CC.SF = (R1.S32 < R2.S32); CC.ZF = !(R1.S32 < R2.S32); CC.OF = CC.CF = 0; ISET.EQ R8, R1, c[1][0x44]; // R8 = (R1 == c[1][0x44])? ~0x0: 0; ISET.LT.AND R8, R1, R2, !P3; // R8 = ((R1.S32 < R2.S32) & !P3)? ~0x0: 0; // compare extended 64-bit signed integers [R1,R0].S64 <= [R3,R2].S64 IADD RZ.CC, R0, -R2; // subtract low word R0 - R2, CC.CF = carry-out, CC.ZF = zero-sum ISET.LE.S32.X R8, R1, R3; // high word extended compare (R1 <=.X R3) does extended subtract: // diff = (R1 + ~R3 + CC.CF); // R8 = ((diff < 0) || ((diff == 0) && CC.ZF))? ~0x0: 0;