Ejemplo n.º 1
0
void genbinaryswitch(SNODE *stmt, struct cases *cs)
{
    AMODE *ap1;
	int size = natural_size(stmt->exp);
    InitRegs();
    ap1 = gen_expr_external(stmt->exp, FALSE, F_DREG, BESZ_DWORD);
    gather_cases(stmt->s1,cs,FALSE);
    qsort(cs->ptrs,cs->count, sizeof(cs->ptrs[0]), size < 0 ? sortcmpsigned : sortcmpunsigned);
    bingen(0, (cs->count) / 2, cs->count, ap1, cs, size);
}
Ejemplo n.º 2
0
void genxswitch(STATEMENT *stmt, SYMBOL *funcsp)
/*
 *      analyze and generate best switch statement.
 */
{
    int oldbreak, i;
    struct cases cs;
    IMODE *ap, *ap3;

#ifdef USE_LONGLONG
    ULLONG_TYPE a = 1;
#endif
    oldbreak = breaklab;
    breaklab = stmt->breaklabel;
    memset(&cs,0,sizeof(cs));
#ifndef USE_LONGLONG
    cs.top = INT_MIN;
    cs.bottom = INT_MAX;
#else
    cs.top = (a << 63); /* LLONG_MIN*/
    cs.bottom = cs.top - 1; /* LLONG_MAX*/
#endif
    count_cases(stmt->cases,&cs) ;
    cs.top++;
    ap3 = gen_expr(funcsp, stmt->select, F_VOL | F_NOVALUE, ISZ_UINT);
    ap = LookupLoadTemp(NULL, ap3);
    if (ap != ap3)
    {
        IMODE *barrier;
        if (stmt->select->isatomic)
        {
            barrier = doatomicFence(funcsp, stmt->select, NULL);
        }
        gen_icode(i_assn, ap, ap3, NULL);
        if (stmt->select->isatomic)
        {
            doatomicFence(funcsp, stmt->select, barrier);
        }
    }
    gen_icode2(i_coswitch, make_immed(ISZ_NONE,cs.count), ap, make_immed(ISZ_NONE,cs.top - cs.bottom), stmt->label);
    gather_cases(stmt->cases,&cs);
    qsort(cs.ptrs, cs.count, sizeof(cs.ptrs[0]), gcs_compare);
    for (i = 0; i < cs.count; i++)
    {
        gen_icode2(i_swbranch,0,make_immed(ISZ_NONE,cs.ptrs[i].id),0,cs.ptrs[i].label);
    }
    breaklab = oldbreak;
}
Ejemplo n.º 3
0
//-------------------------------------------------------------------------
void gather_cases(SNODE *stmt, struct cases *cs, int compact)
{
    if (!cs->ptrs) {
        global_flag++;
        if (compact) {
            unsigned i;
            cs->ptrs = xalloc((cs->top - cs->bottom) * sizeof(struct caseptrs));
            for (i = 0; i < cs->top-cs->bottom; i++)
			{
                cs->ptrs[i].label = cs->deflab;
			}
        } else
            cs->ptrs = xalloc((cs->count) * sizeof(struct caseptrs));
        global_flag--;
    }
    while (stmt)
    {
        switch(stmt->stype) {        
             case st_tryblock:
                break;
            case st_throw:
                break;
            case st_return:
            case st_expr:
                break;
            case st_while:
            case st_do:
                gather_cases(stmt->s1,cs,compact);
                break;
            case st_for:
                gather_cases(stmt->s1,cs,compact);
                break;
            case st_if:
                gather_cases(stmt->s1,cs,compact);
                gather_cases(stmt->s2,cs,compact);
                break;
            case st_switch:
                break;
            case st_block:
                gather_cases(stmt->exp,cs,compact);
                break;
            case st_asm:
                break;
            case st_case:
                if (stmt->s2)
                 /* default case */
                {
                    cs->diddef = TRUE;
                    stmt->label = (SNODE*)cs->deflab;
                }
                else
                {
                    if (compact) {
                        cs->ptrs[stmt->switchid - cs->bottom].label = nextlabel;
                        stmt->label = (SNODE*)nextlabel++;
                    } else {
                        cs->ptrs[cs->tablepos].label = nextlabel;
                        cs->ptrs[cs->tablepos].binlabel =  - 1;
                        cs->ptrs[cs->tablepos++].id = stmt->switchid;
                        stmt->label = (SNODE*)nextlabel++;
                    }
                }
                break;
        }
        stmt = stmt->next;
    }
}