17 assert(ncbuf < nelem(cbuf));
27 if(regsused == 0xffff){
28 error("out of registers");
31 v = regsused + 1 & ~regsused;
34 if((u8int)v == 0) {v >>= 8; n += 8;}
35 if((v & 0xf) == 0) {v >>= 4; n += 4;}
36 if((v & 3) == 0) {v >>= 2; n += 2;}
43 assert((regsused & 1<<n) != 0);
51 s = (s & 0x5555555555555555ULL) + (s >> 1 & 0x5555555555555555ULL);
52 s = (s & 0x3333333333333333ULL) + (s >> 2 & 0x3333333333333333ULL);
53 s = (s & 0x0F0F0F0F0F0F0F0FULL) + (s >> 4 & 0x0F0F0F0F0F0F0F0FULL);
54 s = (s & 0x00FF00FF00FF00FFULL) + (s >> 8 & 0x00FF00FF00FF00FFULL);
55 s = (s & 0x0000FFFF0000FFFFULL) + (s >> 16 & 0x0000FFFF0000FFFFULL);
56 return (u32int)s + (u32int)(s >> 32);
67 i = popcount(val ^ val - 1) - 1;
68 x = val << 54 - i >> 54;
71 emit(DTE_LDI << 24 | (x & 0x3ff) << 14 | i << 8 | r);
73 emit(DTE_XORI << 24 | (x & 0x3ff) << 14 | i << 8 | r);
79 static int egen(Node *);
82 condgen(Node *n, int invert, int truelab)
86 if(n->type != OBIN) goto other;
88 case OPEQ: op = DTE_SEQ; goto cmp;
89 case OPNE: op = DTE_SNE; goto cmp;
90 case OPLT: op = DTE_SLT; goto cmp;
91 case OPLE: op = DTE_SLE;
96 emit(DTE(op ^ 1, r2, r1, truelab));
98 emit(DTE(op, r1, r2, truelab));
104 if(invert ^ n->op == OPLOR){
105 condgen(n->n1, invert, truelab);
106 condgen(n->n2, invert, truelab);
109 condgen(n->n1, !invert, l1);
110 condgen(n->n2, invert, truelab);
117 emit(DTE(DTE_BNE ^ invert, r1, 0, truelab));
124 condvgen(Node *n, int invert)
129 return condvgen(n->n1, !invert);
130 if(n->type != OBIN) goto other;
132 case OPEQ: op = DTE_SEQ; goto cmp;
133 case OPNE: op = DTE_SNE; goto cmp;
134 case OPLT: op = DTE_SLT; goto cmp;
135 case OPLE: op = DTE_SLE;
138 return egen(node(OBIN, op ^ 1, n->n2, n->n1));
142 if(invert ^ n->op == OPLOR){
145 condgen(n->n1, invert, l1);
146 r = condvgen(n->n2, invert);
147 emit(DTE(DTE_BEQ, 0, 0, l2));
149 emit(DTE(DTE_LDI, 0, 1<<6, r));
155 condgen(n->n1, invert, l1);
156 r = condvgen(n->n2, invert);
157 emit(DTE(DTE_BEQ, 0, 0, l2));
159 emit(DTE(DTE_LDI, 0, 0<<6, r));
166 emit(DTE(DTE_SNE ^ invert, r, 0, r));
174 int r1, r2, rt, l1, l2, op;
176 switch(/*nodetype*/n->type){
178 return constenc(n->num);
180 switch(n->sym->type){
183 emit(DTE(DTE_LDV, n->sym->idx, rt, 0));
185 default: sysfatal("egen: unknown symbol type %d", n->sym->type); return 0;
188 switch(/*oper*/n->op){
191 return condvgen(n, 0);
192 case OPADD: op = DTE_ADD; break;
193 case OPSUB: op = DTE_SUB; break;
194 case OPMUL: op = DTE_MUL; break;
195 case OPDIV: op = n->typ->sign ? DTE_SDIV : DTE_UDIV; break;
196 case OPMOD: op = n->typ->sign ? DTE_SMOD : DTE_UMOD; break;
197 case OPAND: op = DTE_AND; break;
198 case OPOR: op = DTE_OR; break;
199 case OPXOR: op = DTE_XOR; break;
200 case OPLSH: op = DTE_LSL; break;
201 case OPRSH: op = n->typ->sign ? DTE_ASR : DTE_LSR; break;
202 case OPEQ: op = DTE_SEQ; break;
203 case OPNE: op = DTE_SNE; break;
204 case OPLT: op = DTE_SLT; break;
205 case OPLE: op = DTE_SLE; break;
206 case OPXNOR: op = DTE_XNOR; break;
207 default: sysfatal("egen: unknown op %d", n->op); return 0;
214 emit(DTE(op, r1, r2, rt));
219 condgen(n->n1, 1, l1);
221 emit(DTE(DTE_BEQ, 0, 0, l2));
225 emit(DTE(DTE_OR, 0, r2, r1));
229 return condvgen(n, 0);
231 switch(n->typ->type){
234 emit(DTE(n->typ->sign ? DTE_SXT : DTE_ZXT, r1, n->typ->size * 8, r1));
239 sysfatal("egen: don't know how to cast %τ to %τ", n->n1->typ, n->typ);
243 default: sysfatal("egen: unknown type %α", n->type); return 0;
257 emit(DTE(DTE_RET, r, 0, 0));
259 for(i = 0; i < ncbuf; i++)
260 if((cbuf[i] >> 24 & 0xf0) == 0x30){
261 t = labtab[cbuf[i] & 0xff];
262 assert((uint)(t - i - 1) < 0x100);
263 cbuf[i] = cbuf[i] & 0xffffff00 | t - i - 1;
266 ep = emalloc(sizeof(DTExpr) + ncbuf * sizeof(u32int));
268 ep->b = (void *)(ep + 1);
269 memcpy(ep->b, cbuf, ncbuf * sizeof(u32int));
274 tracegen(Node *n, DTActGr *g, int *recoff)
276 switch(/*nodetype*/n->type){
282 n->n1 = tracegen(n->n1, g, recoff);
283 n->n2 = tracegen(n->n2, g, recoff);
286 n->n1 = tracegen(n->n1, g, recoff);
289 n->n1 = tracegen(n->n1, g, recoff);
290 n->n2 = tracegen(n->n2, g, recoff);
291 n->n3 = tracegen(n->n3, g, recoff);
294 n->n1 = tracegen(n->n1, g, recoff);
297 switch(n->typ->type){
299 actgradd(g, (DTAct){ACTTRACE, codegen(n->n1), n->typ->size, noagg});
302 actgradd(g, (DTAct){ACTTRACESTR, codegen(n->n1), n->typ->size, noagg});
305 sysfatal("tracegen: don't know how to record %τ", n->typ);
308 *recoff += n->typ->size;
310 default: sysfatal("tracegen: unknown type %α", n->type); return nil;