Example #1
0
void bingen(int lower, int avg, int higher,AMODE *ap1, int deflab, int size,long * switchids,int * switchlabels,int *switchbinlabels)
{
	AMODE *ap2 = make_immed(switchids[avg]);
	AMODE *ap3 = make_label(switchlabels[avg]);
	if (switchbinlabels[avg] != -1)
		gen_label(switchbinlabels[avg]);
	gen_code(op_cmp,4,ap1,ap2);
	gen_code(op_je,0,ap3,0);
	if (avg == lower) {
		ap3 = make_label(deflab);
		gen_code(op_jmp,0,ap3,0);
	}
	else {
		int avg1 = (lower + avg)/2;
		int avg2 = (higher + avg+1)/2;
		if (avg+1 < higher) 
			ap3 = make_label(switchbinlabels[avg2]=nextlabel++);
		else
			ap3 = make_label(deflab);
		if (size < 0)
			gen_code(op_jg,0,ap3,0);
		else
			gen_code(op_ja,0,ap3,0);
		bingen(lower,avg1,avg,ap1,deflab,size,switchids,switchlabels,switchbinlabels);
		if (avg+1 < higher)
			bingen(avg+1,avg2,higher,ap1,deflab,size,switchids,switchlabels,switchbinlabels);
	}
}
Example #2
0
void bingen(int lower, int avg, int higher, AMODE *ap1, struct cases *cs, int size)
{
    AMODE *ap2 = make_immed(cs->ptrs[avg].id);
    AMODE *ap3 = make_label(cs->ptrs[avg].label);
    if (cs->ptrs[avg].binlabel !=  - 1)
        gen_label(cs->ptrs[avg].binlabel);
    gen_coden(op_cmp, size, ap1, ap2);
    gen_code(op_je, ap3, 0);
    if (avg == lower)
    {
        if (cs->deflab < 0)
            cs->deflab = nextlabel++;
        ap3 = make_label(cs->deflab);
        gen_code(op_jmp, ap3, 0);
    }
    else
    {
        int avg1 = (lower + avg) / 2;
        int avg2 = (higher + avg + 1) / 2;
        if (avg + 1 < higher)
            ap3 = make_label(cs->ptrs[avg2].binlabel = nextlabel++);
        else
            ap3 = make_label(cs->deflab);
        if (size < 0)
            gen_code(op_jg, ap3, 0);
        else
            gen_code(op_ja, ap3, 0);
        bingen(lower, avg1, avg, ap1, cs, size);
        if (avg + 1 < higher)
            bingen(avg + 1, avg2, higher, ap1, cs, size);
    }
}
Example #3
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);
}
Example #4
0
void genbinaryswitch(SNODE *stmt, int deflab)
{
	int curlab, i=0,j,size = natural_size(stmt->exp);
	AMODE *ap1;
  long switchbottom=gswitchbottom, switchcount=gswitchcount;
  long switchtop=gswitchtop;
  int *switchlabels=0;
  long *switchids=0;
  int *switchbinlabels=0;
	curlab = nextlabel++;
  initstack();
  ap1 = gen_expr(stmt->exp,F_DREG,4);
	global_flag++;
		switchlabels = xalloc((switchcount) * sizeof(int));
		switchbinlabels = xalloc((switchcount) * sizeof(int));
		switchids = xalloc((switchcount) * sizeof(long));
	global_flag--;
	stmt = stmt->s1;
	while (stmt) {
                if( stmt->s2 )          /* default case ? */
                        {
                        stmt->label = (SNODE *) deflab;
												diddef = TRUE;
                        }
                else
                        {
												switchlabels[i] = curlab;
												switchbinlabels[i] = -1;
												switchids[i++] = (int)stmt->label;
												stmt->label = (SNODE *)curlab;
                        }
                if( stmt->next != 0 )
                        curlab = nextlabel++;
                stmt = stmt->next;
                }
	for (i=0; i < switchcount; i++)
		for (j=i+1; j < switchcount; j++)
			if (switchids[j] < switchids[i]) {
				int temp = switchids[i];
				switchids[i] = switchids[j];
				switchids[j] = temp;
				temp = switchlabels[i];
				switchlabels[i] = switchlabels[j];
				switchlabels[j] = temp;
			}
	bingen(0,(switchcount)/2,switchcount,ap1,deflab,size,switchids,switchlabels,switchbinlabels);
	freeop(ap1);
}