ISET : Integer Compare And Set

Format:

SPA 5.0:
        {@{!}Pg}   ISET{.bval}.cmp{.fmt}{.X}       Rd{.CC}, Ra, Sb          {&req_6}   {?sched}   ;   
        {@{!}Pg}   ISET{.bval}.cmp{.fmt}{.X}.bop   Rd{.CC}, Ra, Sb, {!}Pp   {&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

Description:

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.

Examples:

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;

Back to Index of Instructions