1/*	Id: order.c,v 1.22 2014/06/01 11:35:02 ragge Exp 	*/
2/*	$NetBSD$	*/
3/*
4 * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 *    derived from this software without specific prior written permission
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30
31# include "pass2.h"
32# include <strings.h>
33
34int canaddr(NODE *);
35
36/*
37 * should the assignment op p be stored,
38 * given that it lies as the right operand of o
39 * (or the left, if o==UNARY MUL)
40 */
41/*
42void
43stoasg(NODE *p, int o)
44{
45	if (x2debug)
46		printf("stoasg(%p, %o)\n", p, o);
47}
48*/
49/* should we delay the INCR or DECR operation p */
50int
51deltest(NODE *p)
52{
53	return 0;
54}
55
56/*
57 * Check if p can be autoincremented.
58 * XXX - nothing can be autoincremented for now.
59 */
60int
61autoincr(NODE *p)
62{
63	return 0;
64}
65
66/* is it legal to make an OREG or NAME entry which has an
67 * offset of off, (from a register of r), if the
68 * resulting thing had type t */
69int
70notoff(TWORD t, int r, CONSZ off, char *cp)
71{
72	return(0);  /* YES */
73}
74
75/*
76 * Turn a UMUL-referenced node into OREG.
77 */
78int
79offstar(NODE *p, int shape)
80{
81	if (x2debug)
82		printf("offstar(%p)\n", p);
83
84	if( p->n_op == PLUS || p->n_op == MINUS ){
85		if( p->n_right->n_op == ICON ){
86			geninsn(p->n_left, INBREG);
87			p->n_su = -1;
88			return 1;
89		}
90	}
91	geninsn(p, INBREG);
92	return 0;
93}
94
95/*
96 * Shape matches for UMUL.  Cooperates with offstar().
97 */
98int
99shumul(NODE *p, int shape)
100{
101//	NODE *l = p->n_left;
102
103#ifdef PCC_DEBUG
104	if (x2debug) {
105		printf("shumul(%p)\n", p);
106		fwalk(p, e2print, 0);
107	}
108#endif
109	/* XXX - fix */
110
111	/* Can only generate OREG of BREGs (or FB) */
112	if (p->n_op == REG && (isbreg(p->n_rval) || p->n_rval == FB))
113		return SROREG;
114#if 0
115	if ((p->n_op == PLUS || p->n_op == MINUS) &&
116	    (l->n_op == REG && (isbreg(l->n_rval) || l->n_rval == FB)) &&
117	    p->n_right->n_op == ICON)
118		return SOREG;
119	return 0;
120#else
121	return SROREG;
122#endif
123}
124
125/*
126 * Rewrite increment/decrement operation.
127 */
128int
129setincr(NODE *p)
130{
131	if (x2debug)
132		printf("setincr(%p)\n", p);
133
134	return(0);
135}
136
137/*
138 * Rewrite operations on binary operators (like +, -, etc...).
139 * Called as a result of table lookup.
140 */
141int
142setbin(NODE *p)
143{
144
145	if (x2debug)
146		printf("setbin(%p)\n", p);
147	return 0;
148
149}
150
151/* setup for assignment operator */
152int
153setasg(NODE *p, int cookie)
154{
155	if (x2debug)
156		printf("setasg(%p)\n", p);
157	return(0);
158}
159
160/* setup for unary operator */
161int
162setuni(NODE *p, int cookie)
163{
164	return 0;
165}
166
167#if 0
168/*
169 * register allocation for instructions with special preferences.
170 */
171regcode
172regalloc(NODE *p, struct optab *q, int wantreg)
173{
174	regcode regc;
175
176	if (q->op == DIV || q->op == MOD) {
177		/*
178		 * 16-bit div.
179		 */
180		if (regblk[R0] & 1 || regblk[R2] & 1)
181			comperr("regalloc: needed regs inuse, node %p", p);
182		if (p->n_su & DORIGHT) {
183			regc = alloregs(p->n_right, A0);
184			if (REGNUM(regc) != A0) {
185				p->n_right = movenode(p->n_right, A0);
186				if ((p->n_su & RMASK) == ROREG) {
187					p->n_su &= ~RMASK;
188					p->n_su |= RREG;
189					p->n_right->n_su &= ~LMASK;
190					p->n_right->n_su |= LOREG;
191				}
192				freeregs(regc);
193				regblk[A0] |= 1;
194			}
195		}
196		regc = alloregs(p->n_left, R0);
197		if (REGNUM(regc) != R0) {
198			p->n_left = movenode(p->n_left, R0);
199			freeregs(regc);
200			regblk[R0] |= 1;
201		}
202		if ((p->n_su & RMASK) && !(p->n_su & DORIGHT)) {
203			regc = alloregs(p->n_right, A0);
204			if (REGNUM(regc) != A0) {
205				p->n_right = movenode(p->n_right, A0);
206				if ((p->n_su & RMASK) == ROREG) {
207					p->n_su &= ~RMASK;
208					p->n_su |= RREG;
209					p->n_right->n_su &= ~LMASK;
210					p->n_right->n_su |= LOREG;
211				}
212			}
213		}
214		regblk[A0] &= ~1;
215		regblk[R0] &= ~1;
216		regblk[R2] &= ~1;
217		if (q->op == DIV) {
218			MKREGC(regc, R0, 1);
219			regblk[R0] |= 1;
220		} else {
221			MKREGC(regc, R2, 1);
222			regblk[R2] |= 1;
223		}
224	} else
225		comperr("regalloc");
226	p->n_rall = REGNUM(regc);
227	return regc;
228}
229#endif
230
231/*
232 * Special handling of some instruction register allocation.
233 * - left is the register that left node wants.
234 * - right is the register that right node wants.
235 * - res is in which register the result will end up.
236 * - mask is registers that will be clobbered.
237 *
238 *  XXX - Fix this function
239 */
240struct rspecial *
241nspecial(struct optab *q)
242{
243    switch (q->op) {
244
245    case DIV:
246    case MOD:
247	if(q->ltype & (TINT|TSHORT)){
248	    static struct rspecial s[] = {
249		{ NRES, R0 }, { NRES, R2}, { 0 } };
250	    return s;
251	}
252	/*
253	else if(q->ltype & TCHAR) {
254	    static struct rspecial s[] = {
255		{ NRES, R0L }, { NRES, R0H}, { 0 } };
256	    return s;
257	    }*/
258	break;
259
260    case MUL:
261	/*
262	if(q->ltype & (TINT|TSHORT)){
263	    static struct rspecial s[] = {
264		{ NRES, R0 }, { NRES, R2}, { 0 } };
265	    return s;
266	    }*/
267	comperr("multiplication not implemented");
268	break;
269
270    default:
271	break;
272    }
273    comperr("nspecial entry %d", q - table);
274    return 0; /* XXX gcc */
275}
276
277
278/*
279 * Splitup a function call and give away its arguments first.
280 * Calling convention used ("normal" in IAR syntax) is:
281 * - 1-byte parameters in R0L if possible, otherwise in R0H.
282 * - 2-byte pointers in A0.
283 * - 2-byte non-pointers in R0 if no byte-size arguments are found in
284 *   in the first 6 bytes of parameters, otherwise R2 or at last A0.
285 * - 4-byte parameters in R2R0.
286 */
287void
288gencall(NODE *p, NODE *prev)
289{
290	NODE *n = 0; /* XXX gcc */
291	static int storearg(NODE *);
292	int o = p->n_op;
293	int ty = optype(o);
294
295	if (ty == LTYPE)
296		return;
297
298	switch (o) {
299	case CALL:
300		/* swap arguments on some hardop-converted insns */
301		/* Normal call, just push args and be done with it */
302		p->n_op = UCALL;
303//printf("call\n");
304		/* Check if left can be evaluated directly */
305		if (p->n_left->n_op == UMUL) {
306			TWORD t = p->n_left->n_type;
307			int k = (freetemp(szty(t)));
308			NODE *n = mklnode(OREG, k, FB, t);
309			NODE *q = tcopy(n);
310			pass2_compile(ipnode(mkbinode(ASSIGN, n, p->n_left,t)));
311			p->n_left = q;
312		}
313		gencall(p->n_left, p);
314		p->n_rval = storearg(p->n_right);
315//printf("end call\n");
316		break;
317
318	case UFORTCALL:
319	case FORTCALL:
320		comperr("FORTCALL");
321
322	case USTCALL:
323	case STCALL:
324		/*
325		 * Structure return.  Look at the node above
326		 * to decide about buffer address:
327		 * - FUNARG, allocate space on stack, don't remove.
328		 * - nothing, allocate space on stack and remove.
329		 * - STASG, get the address of the left side as arg.
330		 * - FORCE, this ends up in a return, get supplied addr.
331		 * (this is not pretty, but what to do?)
332		 */
333		if (prev == NULL || prev->n_op == FUNARG) {
334			/* Create nodes to generate stack space */
335			n = mkbinode(ASSIGN, mklnode(REG, 0, STKREG, INT),
336			    mkbinode(MINUS, mklnode(REG, 0, STKREG, INT),
337			    mklnode(ICON, p->n_stsize, 0, INT), INT), INT);
338//printf("stsize %d\n", p->n_stsize);
339			pass2_compile(ipnode(n));
340		} else if (prev->n_op == STASG) {
341			n = prev->n_left;
342			if (n->n_op == UMUL)
343				n = nfree(n);
344			else if (n->n_op == NAME) {
345				n->n_op = ICON; /* Constant reference */
346				n->n_type = INCREF(n->n_type);
347			} else
348				comperr("gencall stasg");
349		} else if (prev->n_op == FORCE) {
350			; /* do nothing here */
351		} else {
352			comperr("gencall bad op %d", prev->n_op);
353		}
354
355		/* Deal with standard arguments */
356		gencall(p->n_left, p);
357		if (o == STCALL) {
358			p->n_op = USTCALL;
359			p->n_rval = storearg(p->n_right);
360		} else
361			p->n_rval = 0;
362		/* push return struct address */
363		if (prev == NULL || prev->n_op == FUNARG) {
364			n = mklnode(REG, 0, STKREG, INT);
365			if (p->n_rval)
366				n = mkbinode(PLUS, n,
367				    mklnode(ICON, p->n_rval, 0, INT), INT);
368			pass2_compile(ipnode(mkunode(FUNARG, n, 0, INT)));
369			if (prev == NULL)
370				p->n_rval += p->n_stsize/4;
371		} else if (prev->n_op == FORCE) {
372			/* return value for this function */
373			n = mklnode(OREG, 8, FPREG, INT);
374			pass2_compile(ipnode(mkunode(FUNARG, n, 0, INT)));
375			p->n_rval++;
376		} else {
377			pass2_compile(ipnode(mkunode(FUNARG, n, 0, INT)));
378			n = p;
379			*prev = *p;
380			nfree(n);
381		}
382//printf("end stcall\n");
383		break;
384
385	default:
386		if (ty != UTYPE)
387			gencall(p->n_right, p);
388		gencall(p->n_left, p);
389		break;
390	}
391}
392
393/*
394 * Create separate node trees for function arguments.
395 * This is partly ticky, the strange calling convention
396 * may cause a bunch of code reorganization here.
397 */
398static int
399storearg(NODE *p)
400{
401	NODE *n, *q, **narry;
402	int nch, k, i, nn, rary[4];
403	int r0l, r0h, r2, a0, stk, sz;
404	TWORD t;
405	int maxrargs = 0;
406
407	if (p->n_op == CM)
408		maxrargs = p->n_stalign;
409
410	/* count the arguments */
411	for (i = 1, q = p; q->n_op == CM; q = q->n_left)
412		i++;
413	nn = i;
414
415	/* allocate array to store arguments */
416	narry = tmpalloc(sizeof(NODE *)*nn);
417
418	/* enter nodes into array */
419	for (q = p; q->n_op == CM; q = q->n_left)
420		narry[--i] = q->n_right;
421	narry[--i] = q;
422
423	/* free CM nodes */
424	for (q = p; q->n_op == CM; ) {
425		n = q->n_left;
426		nfree(q);
427		q = n;
428	}
429
430	/* count char args */
431	r0l = r0h = r2 = a0 = 0;
432	for (sz = nch = i = 0; i < nn && i < 6; i++) {
433		TWORD t = narry[i]->n_type;
434		if (sz >= 6)
435			break;
436		if (t == CHAR || t == UCHAR) {
437			nch++;
438			sz++;
439		} else if ((t >= SHORT && t <= UNSIGNED) ||
440		    t > BTMASK || t == FLOAT) {
441			sz += 2;
442		} else /* long, double */
443			sz += 4;
444
445	}
446
447	/*
448	 * Now the tricky part. The parameters that should be on stack
449	 * must be found and pushed first, then the register parameters.
450	 * For the latter, be sure that evaluating them do not use any
451	 * registers where argument values already are inserted.
452	 * XXX - function pointers?
453	 * XXX foo(long a, char b) ???
454	 */
455	for (stk = 0; stk < 4; stk++) {
456		TWORD t;
457
458		if (stk == nn)
459			break;
460		t = narry[stk]->n_type;
461		if (ISFTN(DECREF(t)))
462			t = LONG;
463		switch (t) {
464		case CHAR: case UCHAR:
465			if (r0l) {
466				if (r0h)
467					break;
468				rary[stk] = R2; /* char talk for 'R0H' */
469				r0h = 1;
470			} else {
471				rary[stk] = R0;
472				r0l = 1;
473			}
474			continue;
475
476		case INT: case UNSIGNED:
477			if (r0l || nch) {
478				if (r2) {
479					if (a0)
480						break;
481					rary[stk] = A0;
482					a0 = 1;
483				} else {
484					rary[stk] = R2;
485					r2 = 1;
486				}
487			} else {
488				rary[stk] = R0;
489				r0l = r0h = 1;
490			}
491			continue;
492
493		case LONG: case ULONG:
494			if (r0l || r2)
495				break;
496			rary[stk] = R0;
497			r0l = r0h = r2 = 1;
498			continue;
499
500		default:
501			if (ISPTR(narry[stk]->n_type) &&
502			    !ISFTN(DECREF(narry[stk]->n_type))) {
503				if (a0) {
504					if (r0l || nch) {
505						if (r2)
506							break;
507						rary[stk] = R2;
508						r2 = 1;
509					} else {
510						rary[stk] = R0;
511						r0l = r0h = 1;
512					}
513				} else {
514					rary[stk] = A0;
515					a0 = 1;
516				}
517				continue;
518			}
519			break;
520		}
521		break;
522	}
523
524	/*
525	 * The arguments that must be on stack are stk->nn args.
526	 * Argument 0->stk-1 should be put in the rary[] register.
527	 */
528	for (sz = 0, i = nn-1; i >= stk; i--) { /* first stack args */
529		NODE nod;
530		pass2_compile(ipnode(mkunode(FUNARG,
531		    narry[i], 0, narry[i]->n_type)));
532		nod.n_type = narry[i]->n_type;
533		sz += tlen(&nod);
534	}
535	/* if param cannot be addressed directly, evaluate and put on stack */
536	for (i = 0; i < stk; i++) {
537
538		if (canaddr(narry[i]))
539			continue;
540		t = narry[i]->n_type;
541		k = (freetemp(szty(t)));
542		n = mklnode(OREG, k, FB, t);
543		q = tcopy(n);
544		pass2_compile(ipnode(mkbinode(ASSIGN, n, narry[i], t)));
545		narry[i] = q;
546	}
547	/* move args to registers */
548	for (i = 0; i < stk; i++) {
549		t = narry[i]->n_type;
550		pass2_compile(ipnode(mkbinode(ASSIGN,
551		    mklnode(REG, 0, rary[i], t), narry[i], t)));
552	}
553	return sz;
554}
555
556/*
557 * Tell if a register can hold a specific datatype.
558 */
559#if 0
560int
561mayuse(int reg, TWORD type)
562{
563	return 1;  /* Everything is OK */
564}
565#endif
566
567#ifdef TAILCALL
568void
569mktailopt(struct interpass *ip1, struct interpass *ip2)
570{
571	extern int earlylab;
572	extern char *cftname;
573	char *fn;
574	NODE *p;
575
576	p = ip1->ip_node->n_left->n_left;
577	if (p->n_op == ICON) {
578		fn = p->n_name;
579		/* calling ourselves */
580		p = ip1->ip_node->n_left;
581		if (p->n_op == CALL) {
582			if (storearg(p->n_right))
583				comperr("too many args: fix mktailopt");
584			p->n_op = UCALL;
585		}
586		tfree(ip1->ip_node);
587		p = ip2->ip_node->n_left;
588		if (strcmp(fn, cftname)) {
589			/* Not us, must generate fake prologue */
590			ip1->type = IP_ASM;
591			ip1->ip_asm = "\tmov.w FB,SP\n\tpop.w FB\n";
592			pass2_compile(ip1);
593			p->n_lval = p->n_rval = 0;
594			p->n_name = fn;
595		} else
596			p->n_lval = earlylab;
597	} else {
598		pass2_compile(ip1);
599	}
600	pass2_compile(ip2);
601}
602#endif
603/*
604 * Set registers "live" at function calls (like arguments in registers).
605 * This is for liveness analysis of registers.
606 */
607int *
608livecall(NODE *p)
609{
610	static int r[1] = { -1 }; /* Terminate with -1 */
611
612	return &r[0];
613}
614
615/*
616 * Signal whether the instruction is acceptable for this target.
617 */
618int
619acceptable(struct optab *op)
620{
621	return 1;
622}
623