void Merced_Encoder::ipf_cmp()

in vm/vmcore/src/util/ipf/code_emit/merced.cpp [930:1064]


void Merced_Encoder::ipf_cmp(Int_Comp_Rel xcr, Compare_Extension cx, unsigned xp1, unsigned xp2, unsigned xr2, unsigned xr3, bool cmp4, unsigned pred)
{
    unsigned x2, tb = 0, ta = 0, c = 0;
    unsigned opcode=0, p1=xp1, p2=xp2, r2=xr2, r3=xr3;
    Int_Comp_Rel cr;

    if (cx==cmp_none || cx==cmp_unc)
    {
        switch (xcr)
        {   //switch predicates
        case icmp_ne:
        case icmp_ge:
        case icmp_geu:
        case icmp_le:
        case icmp_leu:
            p1 = xp2; p2 = xp1; break;
	    default: break;
        }
        switch (xcr)
        {   // switch registers
        case icmp_le:
        case icmp_gt:
        case icmp_leu:
        case icmp_gtu:
            r2 = xr3;
            r3 = xr2;
            break;
	    default: break;
        }
        switch (xcr)
        {   // reassign cr
        case icmp_lt:
        case icmp_le:
        case icmp_gt:
        case icmp_ge:
            cr = icmp_lt;
            opcode = 0xC;
            break;
        case icmp_ltu:
        case icmp_leu:
        case icmp_gtu:
        case icmp_geu:
            cr = icmp_ltu;
            opcode = 0xD;
            break;
        case icmp_eq:
        case icmp_ne:
            cr = icmp_eq;
            opcode = 0xE;
            break;
        default:
            assert(0); // compare type not covered
        }
        switch (cx)
        {   // assign bits
        case cmp_none:
            tb = 0; ta = 0; c = 0; break;
        case cmp_unc:
            tb = 0; ta = 0; c = 1; break;
        default:
            assert(0);
        }
    }
    else if (cx==cmp_and || cx==cmp_or || cx==cmp_or_andcm) // parallel compares
    {
        cr = xcr;
        if (r3==0 && (xcr!=icmp_eq && xcr!=icmp_ne))
        {   // if r3 is register 0 then switch
            assert(r2!=0); // compare zero with zero?
            switch (xcr)
            {
            case icmp_lt:
                cr = icmp_gt; 
                break;
            case icmp_le:
                cr = icmp_ge; 
                break;
            case icmp_gt:
                cr = icmp_lt; 
                break;
            case icmp_ge:
                cr = icmp_le; 
                break;
	    default: assert(0);
            }
            // switch registers
            r2 = xr3;
            r3 = xr2;
        }
        switch (cx)
        {   // assign opcode
        case cmp_and:
            opcode = 0xC;
            break;
        case cmp_or:
            opcode = 0xD;
            break;
        case cmp_or_andcm:
            opcode = 0xE;
            break;
        default:
            assert(0); // compare type not covered
        }
        switch (cr)
        {   // assign bits
        case icmp_eq:
            tb = 0; ta = 1; c = 0; break;
        case icmp_ne:
            tb = 0; ta = 1; c = 1; break;
        case icmp_gt:
            tb = 1; ta = 0; c = 0; break;
        case icmp_le:
            tb = 1; ta = 0; c = 1; break;
        case icmp_ge:
            tb = 1; ta = 1; c = 0; break;
        case icmp_lt:
            tb = 1; ta = 1; c = 1; break;
        default:
            assert(0);
        }
    }
    else
        assert(0);
    if (cmp4)
        x2 = 1;
    else
        x2 = 0;
    assert(opcode);
    encode( // 21.2.2
        opc_enc.A6_A7(opcode, tb, x2, ta, c), 
        0,
        reg_enc.P2_P1_R3_R2(p2, p1, r3, r2),
        pred
        );
}