xref: /plan9/sys/src/cmd/ql/span.c (revision 9b943567965ba040fd275927fbe088656eb8ce4f)
1 #include	"l.h"
2 
3 void
4 span(void)
5 {
6 	Prog *p;
7 	Sym *setext;
8 	Optab *o;
9 	int m;
10 	long c;
11 
12 	if(debug['v'])
13 		Bprint(&bso, "%5.2f span\n", cputime());
14 	Bflush(&bso);
15 	c = INITTEXT;
16 	for(p = firstp; p != P; p = p->link) {
17 		p->pc = c;
18 		o = oplook(p);
19 		m = o->size;
20 		if(m == 0) {
21 			if(p->as == ATEXT) {
22 				curtext = p;
23 				autosize = p->to.offset + 4;
24 				if(p->from3.type == D_CONST) {
25 					if(p->from3.offset & 3)
26 						diag("illegal origin\n%P", p);
27 					if(c > p->from3.offset)
28 						diag("passed origin (#%lux)\n%P", c, p);
29 					else
30 						c = p->from3.offset;
31 					p->pc = c;
32 				}
33 				if(p->from.sym != S)
34 					p->from.sym->value = c;
35 				continue;
36 			}
37 			if(p->as != ANOP)
38 				diag("zero-width instruction\n%P", p);
39 			continue;
40 		}
41 		c += m;
42 	}
43 	c = rnd(c, 4);
44 
45 	setext = lookup("etext", 0);
46 	if(setext != S) {
47 		setext->value = c;
48 		textsize = c - INITTEXT;
49 	}
50 	if(INITRND)
51 		INITDAT = rnd(c, INITRND);
52 	if(debug['v'])
53 		Bprint(&bso, "tsize = %lux\n", textsize);
54 	Bflush(&bso);
55 }
56 
57 void
58 xdefine(char *p, int t, long v)
59 {
60 	Sym *s;
61 
62 	s = lookup(p, 0);
63 	if(s->type == 0 || s->type == SXREF) {
64 		s->type = t;
65 		s->value = v;
66 	}
67 }
68 
69 long
70 regoff(Adr *a)
71 {
72 
73 	offset = 0;
74 	aclass(a);
75 	return offset;
76 }
77 
78 int
79 aclass(Adr *a)
80 {
81 	Sym *s;
82 	int t;
83 
84 	switch(a->type) {
85 	case D_NONE:
86 		return C_NONE;
87 
88 	case D_REG:
89 		return C_REG;
90 
91 	case D_FREG:
92 		return C_FREG;
93 
94 	case D_CREG:
95 		return C_CREG;
96 
97 	case D_SPR:
98 		if(a->offset == D_LR)
99 			return C_LR;
100 		if(a->offset == D_XER)
101 			return C_XER;
102 		if(a->offset == D_CTR)
103 			return C_CTR;
104 		return C_SPR;
105 
106 	case D_SREG:
107 		return C_SREG;
108 
109 	case D_FPSCR:
110 		return C_FPSCR;
111 
112 	case D_MSR:
113 		return C_MSR;
114 
115 	case D_OREG:
116 		switch(a->name) {
117 		case D_EXTERN:
118 		case D_STATIC:
119 			if(a->sym == S)
120 				break;
121 			t = a->sym->type;
122 			if(t == 0 || t == SXREF) {
123 				diag("undefined external: %s in %s",
124 					a->sym->name, TNAME);
125 				a->sym->type = SDATA;
126 			}
127 			offset = a->sym->value + a->offset - BIG;
128 			if(offset >= -BIG && offset < BIG)
129 				return C_SEXT;
130 			return C_LEXT;
131 		case D_AUTO:
132 			offset = autosize + a->offset;
133 			if(offset >= -BIG && offset < BIG)
134 				return C_SAUTO;
135 			return C_LAUTO;
136 
137 		case D_PARAM:
138 			offset = autosize + a->offset + 4L;
139 			if(offset >= -BIG && offset < BIG)
140 				return C_SAUTO;
141 			return C_LAUTO;
142 		case D_NONE:
143 			offset = a->offset;
144 			if(offset == 0)
145 				return C_ZOREG;
146 			if(offset >= -BIG && offset < BIG)
147 				return C_SOREG;
148 			return C_LOREG;
149 		}
150 		return C_GOK;
151 
152 	case D_OPT:
153 		offset = a->offset & 31L;
154 		if(a->name == D_NONE)
155 			return C_SCON;
156 		return C_GOK;
157 
158 	case D_CONST:
159 		switch(a->name) {
160 
161 		case D_NONE:
162 			offset = a->offset;
163 		consize:
164 			if(offset >= 0) {
165 				if(offset <= 0x7fff)
166 					return C_SCON;
167 				if(offset <= 0xffff)
168 					return C_ANDCON;
169 				if((offset & 0xffff) == 0)
170 					return C_UCON;
171 				return C_LCON;
172 			}
173 			if(offset >= -0x8000)
174 				return C_ADDCON;
175 			if((offset & 0xffff) == 0)
176 				return C_UCON;
177 			return C_LCON;
178 
179 		case D_EXTERN:
180 		case D_STATIC:
181 			s = a->sym;
182 			if(s == S)
183 				break;
184 			t = s->type;
185 			if(t == 0 || t == SXREF) {
186 				diag("undefined external: %s in %s",
187 					s->name, TNAME);
188 				s->type = SDATA;
189 			}
190 			if(s->type == STEXT || s->type == SLEAF) {
191 				offset = s->value + a->offset;
192 				return C_LCON;
193 			}
194 			if(s->type == SCONST) {
195 				offset = s->value + a->offset;
196 				goto consize;
197 			}
198 			offset = s->value + a->offset - BIG;
199 			if(offset >= -BIG && offset < BIG && offset != 0)
200 				return C_SECON;
201 			offset = s->value + a->offset + INITDAT;
202 /* not sure why this barfs */
203 return C_LCON;
204 			if(offset == 0)
205 				return C_ZCON;
206 			if(offset >= -0x8000 && offset <= 0xffff)
207 				return C_SCON;
208 			if((offset & 0xffff) == 0)
209 				return C_UCON;
210 			return C_LCON;
211 
212 		case D_AUTO:
213 			offset = autosize + a->offset;
214 			if(offset >= -BIG && offset < BIG)
215 				return C_SACON;
216 			return C_LACON;
217 
218 		case D_PARAM:
219 			offset = autosize + a->offset + 4L;
220 			if(offset >= -BIG && offset < BIG)
221 				return C_SACON;
222 			return C_LACON;
223 		}
224 		return C_GOK;
225 
226 	case D_BRANCH:
227 		return C_SBRA;
228 	}
229 	return C_GOK;
230 }
231 
232 Optab*
233 oplook(Prog *p)
234 {
235 	int a1, a2, a3, a4, r;
236 	char *c1, *c3, *c4;
237 	Optab *o, *e;
238 
239 	a1 = p->optab;
240 	if(a1)
241 		return optab+(a1-1);
242 	a1 = p->from.class;
243 	if(a1 == 0) {
244 		a1 = aclass(&p->from) + 1;
245 		p->from.class = a1;
246 	}
247 	a1--;
248 	a3 = p->from3.class;
249 	if(a3 == 0) {
250 		a3 = aclass(&p->from3) + 1;
251 		p->from3.class = a3;
252 	}
253 	a3--;
254 	a4 = p->to.class;
255 	if(a4 == 0) {
256 		a4 = aclass(&p->to) + 1;
257 		p->to.class = a4;
258 	}
259 	a4--;
260 	a2 = C_NONE;
261 	if(p->reg != NREG)
262 		a2 = C_REG;
263 	r = p->as;
264 	o = oprange[r].start;
265 	if(o == 0)
266 		o = oprange[r].stop; /* just generate an error */
267 	e = oprange[r].stop;
268 	c1 = xcmp[a1];
269 	c3 = xcmp[a3];
270 	c4 = xcmp[a4];
271 	for(; o<e; o++)
272 		if(o->a2 == a2)
273 		if(c1[o->a1])
274 		if(c3[o->a3])
275 		if(c4[o->a4]) {
276 			p->optab = (o-optab)+1;
277 			return o;
278 		}
279 	diag("illegal combination %A %R %R %R %R",
280 		p->as, a1, a2, a3, a4);
281 	if(1||!debug['a'])
282 		prasm(p);
283 	if(o == 0)
284 		errorexit();
285 	return o;
286 }
287 
288 int
289 cmp(int a, int b)
290 {
291 
292 	if(a == b)
293 		return 1;
294 	switch(a) {
295 	case C_LCON:
296 		if(b == C_ZCON || b == C_SCON || b == C_UCON || b == C_ADDCON || b == C_ANDCON)
297 			return 1;
298 		break;
299 	case C_ADDCON:
300 		if(b == C_ZCON || b == C_SCON)
301 			return 1;
302 		break;
303 	case C_ANDCON:
304 		if(b == C_ZCON || b == C_SCON)
305 			return 1;
306 		break;
307 	case C_SPR:
308 		if(b == C_LR || b == C_XER || b == C_CTR)
309 			return 1;
310 		break;
311 	case C_UCON:
312 		if(b == C_ZCON)
313 			return 1;
314 		break;
315 	case C_SCON:
316 		if(b == C_ZCON)
317 			return 1;
318 		break;
319 	case C_LACON:
320 		if(b == C_SACON)
321 			return 1;
322 		break;
323 	case C_LBRA:
324 		if(b == C_SBRA)
325 			return 1;
326 		break;
327 	case C_LEXT:
328 		if(b == C_SEXT)
329 			return 1;
330 		break;
331 	case C_LAUTO:
332 		if(b == C_SAUTO)
333 			return 1;
334 		break;
335 	case C_REG:
336 		if(b == C_ZCON)
337 			return 1;
338 		break;
339 	case C_LOREG:
340 		if(b == C_ZOREG || b == C_SOREG)
341 			return 1;
342 		break;
343 	case C_SOREG:
344 		if(b == C_ZOREG)
345 			return 1;
346 		break;
347 
348 	case C_ANY:
349 		return 1;
350 	}
351 	return 0;
352 }
353 
354 int
355 ocmp(void *a1, void *a2)
356 {
357 	Optab *p1, *p2;
358 	int n;
359 
360 	p1 = a1;
361 	p2 = a2;
362 	n = p1->as - p2->as;
363 	if(n)
364 		return n;
365 	n = p1->a1 - p2->a1;
366 	if(n)
367 		return n;
368 	n = p1->a2 - p2->a2;
369 	if(n)
370 		return n;
371 	n = p1->a3 - p2->a3;
372 	if(n)
373 		return n;
374 	n = p1->a4 - p2->a4;
375 	if(n)
376 		return n;
377 	return 0;
378 }
379 
380 void
381 buildop(void)
382 {
383 	int i, n, r;
384 
385 	for(i=0; i<C_NCLASS; i++)
386 		for(n=0; n<C_NCLASS; n++)
387 			xcmp[i][n] = cmp(n, i);
388 	for(n=0; optab[n].as != AXXX; n++)
389 		;
390 	qsort(optab, n, sizeof(optab[0]), ocmp);
391 	for(i=0; i<n; i++) {
392 		r = optab[i].as;
393 		oprange[r].start = optab+i;
394 		while(optab[i].as == r)
395 			i++;
396 		oprange[r].stop = optab+i;
397 		i--;
398 
399 		switch(r)
400 		{
401 		default:
402 			diag("unknown op in build: %A", r);
403 			errorexit();
404 		case ADCBF:	/* unary indexed: op (b+a); op (b) */
405 			oprange[ADCBI] = oprange[r];
406 			oprange[ADCBST] = oprange[r];
407 			oprange[ADCBT] = oprange[r];
408 			oprange[ADCBTST] = oprange[r];
409 			oprange[ADCBZ] = oprange[r];
410 			oprange[AICBI] = oprange[r];
411 			break;
412 		case AECOWX:	/* indexed store: op s,(b+a); op s,(b) */
413 			oprange[ASTWCCC] = oprange[r];
414 			break;
415 		case AREM:	/* macro */
416 			oprange[AREMCC] = oprange[r];
417 			oprange[AREMV] = oprange[r];
418 			oprange[AREMVCC] = oprange[r];
419 			oprange[AREMU] = oprange[r];
420 			oprange[AREMUCC] = oprange[r];
421 			oprange[AREMUV] = oprange[r];
422 			oprange[AREMUVCC] = oprange[r];
423 			break;
424 		case ADIVW:	/* op Rb[,Ra],Rd */
425 			oprange[AMULHW] = oprange[r];
426 			oprange[AMULHWCC] = oprange[r];
427 			oprange[AMULHWU] = oprange[r];
428 			oprange[AMULHWUCC] = oprange[r];
429 			oprange[AMULLWCC] = oprange[r];
430 			oprange[AMULLWVCC] = oprange[r];
431 			oprange[AMULLWV] = oprange[r];
432 			oprange[ADIVWCC] = oprange[r];
433 			oprange[ADIVWV] = oprange[r];
434 			oprange[ADIVWVCC] = oprange[r];
435 			oprange[ADIVWU] = oprange[r];
436 			oprange[ADIVWUCC] = oprange[r];
437 			oprange[ADIVWUV] = oprange[r];
438 			oprange[ADIVWUVCC] = oprange[r];
439 			oprange[AADDCC] = oprange[r];
440 			oprange[AADDCV] = oprange[r];
441 			oprange[AADDCVCC] = oprange[r];
442 			oprange[AADDV] = oprange[r];
443 			oprange[AADDVCC] = oprange[r];
444 			oprange[AADDE] = oprange[r];
445 			oprange[AADDECC] = oprange[r];
446 			oprange[AADDEV] = oprange[r];
447 			oprange[AADDEVCC] = oprange[r];
448 			oprange[ACRAND] = oprange[r];
449 			oprange[ACRANDN] = oprange[r];
450 			oprange[ACREQV] = oprange[r];
451 			oprange[ACRNAND] = oprange[r];
452 			oprange[ACRNOR] = oprange[r];
453 			oprange[ACROR] = oprange[r];
454 			oprange[ACRORN] = oprange[r];
455 			oprange[ACRXOR] = oprange[r];
456 			break;
457 /* floating point move *//*
458 			oprange[AFMR] = oprange[r];
459 			oprange[AFMRCC] = oprange[r];
460 */
461 /**/
462 		case AMOVBZ:	/* lbz, stz, rlwm(r/r), lhz, lha, stz, and x variants */
463 			oprange[AMOVH] = oprange[r];
464 			oprange[AMOVHZ] = oprange[r];
465 			break;
466 		case AMOVBZU:	/* lbz[x]u, stb[x]u, lhz[x]u, lha[x]u, sth[u]x */
467 			oprange[AMOVHU] = oprange[r];
468 			oprange[AMOVHZU] = oprange[r];
469 			oprange[AMOVWU] = oprange[r];
470 			oprange[AMOVMW] = oprange[r];
471 			break;
472 		case AAND:	/* logical op Rb,Rs,Ra; no literal */
473 			oprange[AANDN] = oprange[r];
474 			oprange[AANDNCC] = oprange[r];
475 			oprange[AEQV] = oprange[r];
476 			oprange[AEQVCC] = oprange[r];
477 			oprange[ANAND] = oprange[r];
478 			oprange[ANANDCC] = oprange[r];
479 			oprange[ANOR] = oprange[r];
480 			oprange[ANORCC] = oprange[r];
481 			oprange[AORCC] = oprange[r];
482 			oprange[AORN] = oprange[r];
483 			oprange[AORNCC] = oprange[r];
484 			oprange[AXORCC] = oprange[r];
485 			break;
486 		case AADDME:	/* op Ra, Rd */
487 			oprange[AADDMECC] = oprange[r];
488 			oprange[AADDMEV] = oprange[r];
489 			oprange[AADDMEVCC] = oprange[r];
490 			oprange[AADDZE] = oprange[r];
491 			oprange[AADDZECC] = oprange[r];
492 			oprange[AADDZEV] = oprange[r];
493 			oprange[AADDZEVCC] = oprange[r];
494 			oprange[ASUBME] = oprange[r];
495 			oprange[ASUBMECC] = oprange[r];
496 			oprange[ASUBMEV] = oprange[r];
497 			oprange[ASUBMEVCC] = oprange[r];
498 			oprange[ASUBZE] = oprange[r];
499 			oprange[ASUBZECC] = oprange[r];
500 			oprange[ASUBZEV] = oprange[r];
501 			oprange[ASUBZEVCC] = oprange[r];
502 			break;
503 		case AADDC:
504 			oprange[AADDCCC] = oprange[r];
505 			break;
506 		case ABEQ:
507 			oprange[ABGE] = oprange[r];
508 			oprange[ABGT] = oprange[r];
509 			oprange[ABLE] = oprange[r];
510 			oprange[ABLT] = oprange[r];
511 			oprange[ABNE] = oprange[r];
512 			oprange[ABVC] = oprange[r];
513 			oprange[ABVS] = oprange[r];
514 			break;
515 		case ABR:
516 			oprange[ABL] = oprange[r];
517 			break;
518 		case ABC:
519 			oprange[ABCL] = oprange[r];
520 			break;
521 		case AEXTSB:	/* op Rs, Ra */
522 			oprange[AEXTSBCC] = oprange[r];
523 			oprange[AEXTSH] = oprange[r];
524 			oprange[AEXTSHCC] = oprange[r];
525 			oprange[ACNTLZW] = oprange[r];
526 			oprange[ACNTLZWCC] = oprange[r];
527 			break;
528 		case AFABS:	/* fop [s,]d */
529 			oprange[AFABSCC] = oprange[r];
530 			oprange[AFNABS] = oprange[r];
531 			oprange[AFNABSCC] = oprange[r];
532 			oprange[AFNEG] = oprange[r];
533 			oprange[AFNEGCC] = oprange[r];
534 			oprange[AFRSP] = oprange[r];
535 			oprange[AFRSPCC] = oprange[r];
536 			oprange[AFCTIW] = oprange[r];
537 			oprange[AFCTIWCC] = oprange[r];
538 			oprange[AFCTIWZ] = oprange[r];
539 			oprange[AFCTIWZCC] = oprange[r];
540 			break;
541 		case AFADD:
542 			oprange[AFADDS] = oprange[r];
543 			oprange[AFADDCC] = oprange[r];
544 			oprange[AFADDSCC] = oprange[r];
545 			oprange[AFDIV] = oprange[r];
546 			oprange[AFDIVS] = oprange[r];
547 			oprange[AFDIVCC] = oprange[r];
548 			oprange[AFDIVSCC] = oprange[r];
549 			oprange[AFSUB] = oprange[r];
550 			oprange[AFSUBS] = oprange[r];
551 			oprange[AFSUBCC] = oprange[r];
552 			oprange[AFSUBSCC] = oprange[r];
553 			break;
554 		case AFMADD:
555 			oprange[AFMADDCC] = oprange[r];
556 			oprange[AFMADDS] = oprange[r];
557 			oprange[AFMADDSCC] = oprange[r];
558 			oprange[AFMSUB] = oprange[r];
559 			oprange[AFMSUBCC] = oprange[r];
560 			oprange[AFMSUBS] = oprange[r];
561 			oprange[AFMSUBSCC] = oprange[r];
562 			oprange[AFNMADD] = oprange[r];
563 			oprange[AFNMADDCC] = oprange[r];
564 			oprange[AFNMADDS] = oprange[r];
565 			oprange[AFNMADDSCC] = oprange[r];
566 			oprange[AFNMSUB] = oprange[r];
567 			oprange[AFNMSUBCC] = oprange[r];
568 			oprange[AFNMSUBS] = oprange[r];
569 			oprange[AFNMSUBSCC] = oprange[r];
570 			break;
571 		case AFMUL:
572 			oprange[AFMULS] = oprange[r];
573 			oprange[AFMULCC] = oprange[r];
574 			oprange[AFMULSCC] = oprange[r];
575 			break;
576 		case AFCMPO:
577 			oprange[AFCMPU] = oprange[r];
578 			break;
579 		case AMTFSB0:
580 			oprange[AMTFSB0CC] = oprange[r];
581 			oprange[AMTFSB1] = oprange[r];
582 			oprange[AMTFSB1CC] = oprange[r];
583 			break;
584 		case ANEG:	/* op [Ra,] Rd */
585 			oprange[ANEGCC] = oprange[r];
586 			oprange[ANEGV] = oprange[r];
587 			oprange[ANEGVCC] = oprange[r];
588 			break;
589 		case AOR:	/* or/xor Rb,Rs,Ra; ori/xori $uimm,Rs,Ra; oris/xoris $uimm,Rs,Ra */
590 			oprange[AXOR] = oprange[r];
591 			break;
592 		case ASLW:
593 			oprange[ASLWCC] = oprange[r];
594 			oprange[ASRW] = oprange[r];
595 			oprange[ASRWCC] = oprange[r];
596 			break;
597 		case ASRAW:	/* sraw Rb,Rs,Ra; srawi sh,Rs,Ra */
598 			oprange[ASRAWCC] = oprange[r];
599 			break;
600 		case ASUB:	/* SUB Ra,Rb,Rd => subf Rd,ra,rb */
601 			oprange[ASUB] = oprange[r];
602 			oprange[ASUBCC] = oprange[r];
603 			oprange[ASUBV] = oprange[r];
604 			oprange[ASUBVCC] = oprange[r];
605 			oprange[ASUBCCC] = oprange[r];
606 			oprange[ASUBCV] = oprange[r];
607 			oprange[ASUBCVCC] = oprange[r];
608 			oprange[ASUBE] = oprange[r];
609 			oprange[ASUBECC] = oprange[r];
610 			oprange[ASUBEV] = oprange[r];
611 			oprange[ASUBEVCC] = oprange[r];
612 			break;
613 		case ASYNC:
614 			oprange[AISYNC] = oprange[r];
615 			break;
616 		case ARLWMI:
617 			oprange[ARLWMICC] = oprange[r];
618 			oprange[ARLWNM] = oprange[r];
619 			oprange[ARLWNMCC] = oprange[r];
620 			break;
621 		case AFMOVD:
622 			oprange[AFMOVDCC] = oprange[r];
623 			oprange[AFMOVDU] = oprange[r];
624 			oprange[AFMOVS] = oprange[r];
625 			oprange[AFMOVSU] = oprange[r];
626 			break;
627 		case AECIWX:
628 			oprange[ALWAR] = oprange[r];
629 			break;
630 		case ASYSCALL:	/* just the op; flow of control */
631 			oprange[ARFI] = oprange[r];
632 			break;
633 		case AMOVHBR:
634 			oprange[AMOVWBR] = oprange[r];
635 			break;
636 		case AADD:
637 		case AANDCC:	/* and. Rb,Rs,Ra; andi. $uimm,Rs,Ra; andis. $uimm,Rs,Ra */
638 		case ACMP:
639 		case ACMPU:
640 		case AEIEIO:
641 		case ALSW:
642 		case AMOVB:	/* macro: move byte with sign extension */
643 		case AMOVBU:	/* macro: move byte with sign extension & update */
644 		case AMOVW:
645 		case AMOVFL:
646 		case AMULLW:	/* op $s[,r2],r3; op r1[,r2],r3; no cc/v */
647 		case ASUBC:	/* op r1,$s,r3; op r1[,r2],r3 */
648 		case ASTSW:
649 		case ATLBIE:
650 		case ATW:
651 		case AWORD:
652 		case ANOP:
653 		case ATEXT:
654 			break;
655 		}
656 	}
657 }
658