mirror of
https://github.com/mirror/tinycc.git
synced 2025-02-04 06:30:10 +08:00
gcase() clean up
remove tail recursion, simplify
This commit is contained in:
parent
7dddd65b46
commit
7bd30a488a
65
tccgen.c
65
tccgen.c
@ -4906,35 +4906,9 @@ static int gcase(struct case_t **base, int len, int case_reg, int *bsym)
|
|||||||
{
|
{
|
||||||
struct case_t *p;
|
struct case_t *p;
|
||||||
int e;
|
int e;
|
||||||
if (len <= 4) {
|
while (len > 4) {
|
||||||
while (len--) {
|
/* binary search */
|
||||||
p = *base++;
|
|
||||||
vseti(case_reg, 0);
|
|
||||||
vdup();
|
|
||||||
vpushi(p->v2);
|
|
||||||
if (p->v1 == p->v2) {
|
|
||||||
gen_op(TOK_EQ);
|
|
||||||
gtst_addr(0, p->sym);
|
|
||||||
case_reg = gv(RC_INT);
|
|
||||||
vpop();
|
|
||||||
} else {
|
|
||||||
gen_op(TOK_LE);
|
|
||||||
e = gtst(1, 0);
|
|
||||||
case_reg = gv(RC_INT);
|
|
||||||
vpop();
|
|
||||||
vseti(case_reg, 0);
|
|
||||||
vdup();
|
|
||||||
vpushi(p->v1);
|
|
||||||
gen_op(TOK_GE);
|
|
||||||
gtst_addr(0, p->sym);
|
|
||||||
case_reg = gv(RC_INT);
|
|
||||||
vpop();
|
|
||||||
gsym(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
p = base[len/2];
|
p = base[len/2];
|
||||||
/* mid */
|
|
||||||
vseti(case_reg, 0);
|
vseti(case_reg, 0);
|
||||||
vdup();
|
vdup();
|
||||||
vpushi(p->v2);
|
vpushi(p->v2);
|
||||||
@ -4946,19 +4920,43 @@ static int gcase(struct case_t **base, int len, int case_reg, int *bsym)
|
|||||||
vdup();
|
vdup();
|
||||||
vpushi(p->v1);
|
vpushi(p->v1);
|
||||||
gen_op(TOK_GE);
|
gen_op(TOK_GE);
|
||||||
gtst_addr(0, p->sym);
|
gtst_addr(0, p->sym); /* v1 <= x <= v2 */
|
||||||
case_reg = gv(RC_INT);
|
case_reg = gv(RC_INT);
|
||||||
vpop();
|
vpop();
|
||||||
/* left */
|
/* x < v1 */
|
||||||
case_reg = gcase(base, len/2, case_reg, bsym);
|
case_reg = gcase(base, len/2, case_reg, bsym);
|
||||||
if (cur_switch->def_sym)
|
if (cur_switch->def_sym)
|
||||||
gjmp_addr(cur_switch->def_sym);
|
gjmp_addr(cur_switch->def_sym);
|
||||||
else
|
else
|
||||||
*bsym = gjmp(*bsym);
|
*bsym = gjmp(*bsym);
|
||||||
/* right */
|
/* x > v2 */
|
||||||
gsym(e);
|
gsym(e);
|
||||||
e = len/2 + 1;
|
e = len/2 + 1;
|
||||||
case_reg = gcase(base + e, len - e, case_reg, bsym);
|
base += e; len -= e;
|
||||||
|
}
|
||||||
|
/* linear scan */
|
||||||
|
while (len--) {
|
||||||
|
p = *base++;
|
||||||
|
vseti(case_reg, 0);
|
||||||
|
vdup();
|
||||||
|
vpushi(p->v2);
|
||||||
|
if (p->v1 == p->v2) {
|
||||||
|
gen_op(TOK_EQ);
|
||||||
|
gtst_addr(0, p->sym);
|
||||||
|
} else {
|
||||||
|
gen_op(TOK_LE);
|
||||||
|
e = gtst(1, 0);
|
||||||
|
case_reg = gv(RC_INT);
|
||||||
|
vpop();
|
||||||
|
vseti(case_reg, 0);
|
||||||
|
vdup();
|
||||||
|
vpushi(p->v1);
|
||||||
|
gen_op(TOK_GE);
|
||||||
|
gtst_addr(0, p->sym);
|
||||||
|
gsym(e);
|
||||||
|
}
|
||||||
|
case_reg = gv(RC_INT);
|
||||||
|
vpop();
|
||||||
}
|
}
|
||||||
return case_reg;
|
return case_reg;
|
||||||
}
|
}
|
||||||
@ -5245,7 +5243,8 @@ static void block(int *bsym, int *csym, int is_expr)
|
|||||||
b = gjmp(0); /* jump to first case */
|
b = gjmp(0); /* jump to first case */
|
||||||
sw.p = NULL; sw.n = 0; sw.def_sym = 0;
|
sw.p = NULL; sw.n = 0; sw.def_sym = 0;
|
||||||
saved = cur_switch;
|
saved = cur_switch;
|
||||||
cur_switch = &sw; block(&a, csym, 0);
|
cur_switch = &sw;
|
||||||
|
block(&a, csym, 0);
|
||||||
a = gjmp(a); /* add implicit break */
|
a = gjmp(a); /* add implicit break */
|
||||||
/* case lookup */
|
/* case lookup */
|
||||||
gsym(b);
|
gsym(b);
|
||||||
|
Loading…
Reference in New Issue
Block a user