remove tail recursion, simplify
Unified · Split
| @@ -4906,35 +4906,9 @@ static int gcase(struct case_t **base, int len, int case_reg, int *bsym) · 4905 unmodified lines | |||
| 4906 | { | 4906 | { |
| 4907 | struct case_t *p; | 4907 | struct case_t *p; |
| 4908 | int e; | 4908 | int e; |
| 4909 | if (len <= 4) { | 4909 | while (len > 4) { |
| 4910 | while (len--) { | 4910 | /* binary search */ |
| 4911 | p = *base++; | ||
| 4912 | vseti(case_reg, 0); | ||
| 4913 | vdup(); | ||
| 4914 | vpushi(p->v2); | ||
| 4915 | if (p->v1 == p->v2) { | ||
| 4916 | gen_op(TOK_EQ); | ||
| 4917 | gtst_addr(0, p->sym); | ||
| 4918 | case_reg = gv(RC_INT); | ||
| 4919 | vpop(); | ||
| 4920 | } else { | ||
| 4921 | gen_op(TOK_LE); | ||
| 4922 | e = gtst(1, 0); | ||
| 4923 | case_reg = gv(RC_INT); | ||
| 4924 | vpop(); | ||
| 4925 | vseti(case_reg, 0); | ||
| 4926 | vdup(); | ||
| 4927 | vpushi(p->v1); | ||
| 4928 | gen_op(TOK_GE); | ||
| 4929 | gtst_addr(0, p->sym); | ||
| 4930 | case_reg = gv(RC_INT); | ||
| 4931 | vpop(); | ||
| 4932 | gsym(e); | ||
| 4933 | } | ||
| 4934 | } | ||
| 4935 | } else { | ||
| 4936 | p = base[len/2]; | 4911 | p = base[len/2]; |
| 4937 | /* mid */ | ||
| 4938 | vseti(case_reg, 0); | 4912 | vseti(case_reg, 0); |
| 4939 | vdup(); | 4913 | vdup(); |
| 4940 | vpushi(p->v2); | 4914 | vpushi(p->v2); |
| @@ -4946,19 +4920,43 @@ static int gcase(struct case_t **base, int len, int case_reg, int *bsym) · 5 unmodified lines | |||
| 4946 | vdup(); | 4920 | vdup(); |
| 4947 | vpushi(p->v1); | 4921 | vpushi(p->v1); |
| 4948 | gen_op(TOK_GE); | 4922 | gen_op(TOK_GE); |
| 4949 | gtst_addr(0, p->sym); | 4923 | gtst_addr(0, p->sym); /* v1 <= x <= v2 */ |
| 4950 | case_reg = gv(RC_INT); | 4924 | case_reg = gv(RC_INT); |
| 4951 | vpop(); | 4925 | vpop(); |
| 4952 | /* left */ | 4926 | /* x < v1 */ |
| 4953 | case_reg = gcase(base, len/2, case_reg, bsym); | 4927 | case_reg = gcase(base, len/2, case_reg, bsym); |
| 4954 | if (cur_switch->def_sym) | 4928 | if (cur_switch->def_sym) |
| 4955 | gjmp_addr(cur_switch->def_sym); | 4929 | gjmp_addr(cur_switch->def_sym); |
| 4956 | else | 4930 | else |
| 4957 | *bsym = gjmp(*bsym); | 4931 | *bsym = gjmp(*bsym); |
| 4958 | /* right */ | 4932 | /* x > v2 */ |
| 4959 | gsym(e); | 4933 | gsym(e); |
| 4960 | e = len/2 + 1; | 4934 | e = len/2 + 1; |
| 4961 | case_reg = gcase(base + e, len - e, case_reg, bsym); | 4935 | base += e; len -= e; |
| 4936 | } | ||
| 4937 | /* linear scan */ | ||
| 4938 | while (len--) { | ||
| 4939 | p = *base++; | ||
| 4940 | vseti(case_reg, 0); | ||
| 4941 | vdup(); | ||
| 4942 | vpushi(p->v2); | ||
| 4943 | if (p->v1 == p->v2) { | ||
| 4944 | gen_op(TOK_EQ); | ||
| 4945 | gtst_addr(0, p->sym); | ||
| 4946 | } else { | ||
| 4947 | gen_op(TOK_LE); | ||
| 4948 | e = gtst(1, 0); | ||
| 4949 | case_reg = gv(RC_INT); | ||
| 4950 | vpop(); | ||
| 4951 | vseti(case_reg, 0); | ||
| 4952 | vdup(); | ||
| 4953 | vpushi(p->v1); | ||
| 4954 | gen_op(TOK_GE); | ||
| 4955 | gtst_addr(0, p->sym); | ||
| 4956 | gsym(e); | ||
| 4957 | } | ||
| 4958 | case_reg = gv(RC_INT); | ||
| 4959 | vpop(); | ||
| 4962 | } | 4960 | } |
| 4963 | return case_reg; | 4961 | return case_reg; |
| 4964 | } | 4962 | } |
| @@ -5245,7 +5243,8 @@ static void block(int *bsym, int *csym, int is_expr) · 280 unmodified lines | |||
| 5245 | b = gjmp(0); /* jump to first case */ | 5243 | b = gjmp(0); /* jump to first case */ |
| 5246 | sw.p = NULL; sw.n = 0; sw.def_sym = 0; | 5244 | sw.p = NULL; sw.n = 0; sw.def_sym = 0; |
| 5247 | saved = cur_switch; | 5245 | saved = cur_switch; |
| 5248 | cur_switch = &sw; block(&a, csym, 0); | 5246 | cur_switch = &sw; |
| 5247 | block(&a, csym, 0); | ||
| 5249 | a = gjmp(a); /* add implicit break */ | 5248 | a = gjmp(a); /* add implicit break */ |
| 5250 | /* case lookup */ | 5249 | /* case lookup */ |
| 5251 | gsym(b); | 5250 | gsym(b); |