1#include <scc/scc.h>23#include "cc2.h"45static Node *6assignnode(Type *tp, Node *lhs, Node *rhs)7{8 Node *np;910 np = node(OASSIG);11 np->type = *tp;12 np->left = lhs;13 np->right = rhs;14 return sethi(np);15}1617static Node *18branchnode(Node *cond, Symbol *sym)19{20 Node *np;21 int op = cond ? OBRANCH : OJMP;2223 np = node(op);24 np->op = op;25 np->left = sethi(cond);26 np->u.sym = sym;27 sym->refcnt++;2829 return np;30}3132static Node *33boolean(Node *cond, Symbol *strue, Symbol *sfalse)34{35 Symbol *label;36 Node *p, *l = cond->left, *r = cond->right;3738 switch (cond->op) {39 case ONEG:40 l = boolean(l, sfalse, strue);41 break;42 case OAND:43 label = newlabel();44 l = boolean(l, label, sfalse);45 prestmt(labelstmt(NULL, label));46 r = boolean(r, strue, sfalse);47 break;48 case OOR:49 label = newlabel();50 l = boolean(l, strue, label);51 prestmt(labelstmt(NULL, label));52 r = boolean(r, strue, sfalse);53 break;54 default:55 prestmt(branchnode(cond, strue));56 prestmt(branchnode(NULL, sfalse));57 return NULL;58 }5960 cond->left = l;61 cond->right = r;62 return cond;63}6465Node *66logicexpr(Node *np)67{68 Node *tmpvar, *p, *zero, *one;69 Type *tp = &np->type;70 Symbol *strue, *sfalse, *phi, *tmpsym;7172 strue = newlabel();73 sfalse = newlabel();74 phi = newlabel();7576 boolean(np, strue, sfalse);7778 tmpvar = tmpnode(tp, NULL);79 tmpsym = tmpvar->u.sym;80 zero = constnode(NULL, 0, tp);81 one = constnode(NULL, 1, tp);8283 p = assignnode(tp, tmpnode(tp, tmpsym), one);84 prestmt(labelstmt(p, strue));8586 prestmt(branchnode(NULL, phi));8788 p = assignnode(tp, tmpnode(tp, tmpsym), zero);89 prestmt(labelstmt(p, sfalse));9091 prestmt(labelstmt(NULL, phi));9293 return sethi(tmpvar);94}9596static void97comma(Node *np)98{99 if (np->op != OCOMMA) {100 prestmt(sethi(np));101 } else {102 comma(np->left);103 prestmt(sethi(np->right));104 delnode(np);105 }106}107108static Node *109ternary(Node *np)110{111 Type *tp;112 Node *tmpvar, *colon, *p;113 Symbol *tmpsym, *strue, *sfalse, *phi;114115 strue = newlabel();116 sfalse = newlabel();117 phi = newlabel();118 boolean(np->left, strue, sfalse);119120 tp = &np->type;121 colon = np->right;122 tmpvar = tmpnode(tp, NULL);123 tmpsym = tmpvar->u.sym;124125 prestmt(labelstmt(NULL, strue));126 p = assignnode(tp, tmpnode(tp, tmpsym), sethi(colon->left));127 prestmt(p);128 prestmt(branchnode(NULL, phi));129130 prestmt(labelstmt(NULL, sfalse));131 p = assignnode(tp, tmpnode(tp, tmpsym), sethi(colon->right));132 prestmt(p);133134 prestmt(labelstmt(NULL, phi));135136 return sethi(tmpvar);137}138139static Node *140replace(Node *what, Node *with)141{142 Node *prev, *next;143 Symbol *label;144145 label = what->label;146 next = what->next, prev = what->prev;147148 *what = *with;149 delnode(with);150 what->next = next, what->prev = prev;151 what->label = label;152153 return sethi(what);154}155156Node *157sethi(Node *np)158{159 int op;160 Node *next, *l, *r;161162 if (!np)163 return np;164165 np->complex = 0;166 np->address = 0;167168 switch (np->op) {169 case OBSWITCH:170 np = swtch(np);171 break;172 case OBRANCH:173 next = np->next;174 if (!next->label)175 labelstmt(next, NULL);176177 op = np->left->op;178 if (op != ONEG && op != OOR && op != OAND) {179 sethi(np->left);180 return np;181 }182183 boolean(np->left, np->u.sym, next->label);184 np->u.sym->refcnt--;185 return NULL;186 case OCOMMA:187 r = np->right;188 comma(np->left);189 return replace(np, r);190 case OASK:191 return replace(np, ternary(np));192 case ONEG:193 case OAND:194 case OOR:195 return replace(np, logicexpr(np));196 default:197 np = tsethi(np);198 break;199 }200201 l = np->left;202 r = np->right;203204 if (np->address > 10)205 return np;206 if (l)207 np->complex = l->complex;208 if (r) {209 int d = np->complex - r->complex;210211 if (d == 0)212 ++np->complex;213 else if (d < 0)214 np->complex = r->complex;215 }216 if (np->complex == 0)217 ++np->complex;218219 return np;220}221222static Node *223presethi(Node *np)224{225 /* just in case ... */226 savelabel();227 return sethi(np);228}229230void231genaddr(void)232{233 apply(presethi);234 PRTREE("after sethi");235}