swtch.c (2104B)
1 #include <limits.h> 2 #include <stdlib.h> 3 4 #include <scc/scc.h> 5 6 #include "cc2.h" 7 8 static Swtch *list; 9 10 static Node * 11 swtch_if(Node *np) 12 { 13 Type *tp; 14 Swtch *swt; 15 Node **cases, **bp, *tmpvar, *p; 16 17 swt = np->u.swtch; 18 tp = &np->left->type; 19 20 tmpvar = tmpnode(tp, NULL); 21 np->type = *tp; 22 np->right = np->left; 23 np->left = tmpvar; 24 np->op = OASSIG; 25 np->u.subop = 0; 26 27 cases = swt->cases; 28 for (bp = cases; bp < &cases[swt->nr]; ++bp) { 29 Node *eq, *tmp = tmpnode(tp, tmpvar->u.sym); 30 31 p = *bp; 32 eq = node(OEQ); 33 eq->type = *tp; 34 eq->left = p->left; 35 eq->right = tmp; 36 *bp = NULL; 37 38 p->left = eq; 39 p->op = OBRANCH; 40 addstmt(p); 41 } 42 p = swtchdefault(swt); 43 p->op = OJMP; 44 addstmt(p); 45 46 free(cases); 47 swt->cases = NULL; 48 49 return sethi(np); 50 } 51 52 static Node * 53 swtch_dir(Node *np, TINT min, TINT max) 54 { 55 int i; 56 TINT cur, nval; 57 Swtch *swt; 58 Symbol *tbl; 59 Node *p, *def, **cases; 60 61 tbl = getsym(TMPSYM); 62 tbl->kind = SLOCAL; 63 tbl->type = ptrtype; 64 tbl->type.flags |= INITF; 65 defglobal(tbl); 66 67 swt = np->u.swtch; 68 cases = swt->cases; 69 70 def = swtchdefault(swt); 71 def->type = ptrtype; 72 def->op = OLABEL; 73 74 i = 0; 75 p = NULL; 76 for (cur = min; cur <= max; ++cur) { 77 if (!p && i < swt->nr) { 78 p = cases[i++]; 79 p->type = ptrtype; 80 p->op = OLABEL; 81 nval = p->left->u.i; 82 } 83 if (p && nval == cur) { 84 data(p); 85 p = NULL; 86 } else { 87 data(def); 88 } 89 } 90 endinit(); 91 92 return np; 93 } 94 95 Node * 96 swtch(Node *np) 97 { 98 Swtch *swt; 99 int n; 100 TINT min, max, range; 101 102 swt = np->u.swtch; 103 min = swt->min; 104 max = swt->max; 105 range = max - min + 1; 106 n = swt->nr; 107 108 if (n < mach.swtchif) 109 return swtch_if(np); 110 return swtch_dir(np, min, max); 111 } 112 113 Node * 114 swtchdefault(Swtch *swt) 115 { 116 Node *np; 117 118 np = swt->defnode; 119 if (!np) 120 np = swt->eswtch; 121 return np; 122 } 123 124 Swtch * 125 newswtch(Swtch *swt) 126 { 127 Swtch *p = xmalloc(sizeof(*p)); 128 129 *p = *swt; 130 p->next = list; 131 return list = p; 132 } 133 134 void 135 cleanswtch(void) 136 { 137 Swtch *p, *next; 138 Node **bp, **cases; 139 140 for (p = list; p; p = next) { 141 next = p->next; 142 cases = p->cases; 143 if (cases) { 144 for (bp = cases; bp < &cases[p->nr]; ++p) 145 deltree(*bp); 146 free(cases); 147 } 148 free(p); 149 } 150 }