1 /*	$Id: local.c,v 1.34 2011/06/23 13:41:25 ragge Exp $	*/
2 
3 /*
4  * Copyright (c) 2008 David Crawshaw <david@zentus.com>
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include "pass1.h"
20 
21 NODE *
clocal(NODE * p)22 clocal(NODE *p)
23 {
24 	struct symtab *sp;
25 	int op;
26 	NODE *r, *l;
27 
28 	op = p->n_op;
29 	sp = p->n_sp;
30 	l  = p->n_left;
31 	r  = p->n_right;
32 
33 #ifdef PCC_DEBUG
34 	if (xdebug) {
35 		printf("clocal in: %p, %s\n", p, copst(op));
36 		fwalk(p, eprint, 0);
37 	}
38 #endif
39 
40 	switch (op) {
41 
42 	case NAME:
43 		if (sp->sclass == PARAM || sp->sclass == AUTO) {
44 			/*
45 			 * Use a fake structure reference to
46 			 * write out frame pointer offsets.
47 			 */
48 			l = block(REG, NIL, NIL, PTR+STRTY, 0, 0);
49 			l->n_lval = 0;
50 			l->n_rval = FP;
51 			r = p;
52 			p = stref(block(STREF, l, r, 0, 0, 0));
53 		}
54 		break;
55 	case PCONV: /* Remove what PCONVs we can. */
56 		if (l->n_op == SCONV)
57 			break;
58 
59 		if (l->n_op == ICON || (ISPTR(p->n_type) && ISPTR(l->n_type))) {
60 			l->n_type = p->n_type;
61 			l->n_qual = p->n_qual;
62 			l->n_df = p->n_df;
63 			l->n_ap = p->n_ap;
64 			nfree(p);
65 			p = l;
66 		}
67 		break;
68 
69 	case SCONV:
70         /* Remove redundant conversions. */
71 		if ((p->n_type & TMASK) == 0 && (l->n_type & TMASK) == 0 &&
72 		    tsize(p->n_type, p->n_df, p->n_ap) ==
73 		    tsize(l->n_type, l->n_df, l->n_ap) &&
74 		    p->n_type != FLOAT && p->n_type != DOUBLE &&
75 		    l->n_type != FLOAT && l->n_type != DOUBLE &&
76 		    l->n_type != DOUBLE && p->n_type != LDOUBLE) {
77 			if (l->n_op == NAME || l->n_op == UMUL ||
78 			    l->n_op == TEMP) {
79 				l->n_type = p->n_type;
80 				nfree(p);
81 				p = l;
82 				break;
83 			}
84 		}
85 
86         /* Convert floating point to int before to char or short. */
87         if ((l->n_type == FLOAT || l->n_type == DOUBLE || l->n_type == LDOUBLE)
88             && (DEUNSIGN(p->n_type) == CHAR || DEUNSIGN(p->n_type) == SHORT)) {
89             p = block(SCONV, p, NIL, p->n_type, p->n_df, p->n_ap);
90             p->n_left->n_type = INT;
91             break;
92         }
93 
94         /* Transform constants now. */
95 		if (l->n_op != ICON)
96 			break;
97 
98 		if (ISPTR(p->n_type)) {
99 			l->n_type = p->n_type;
100 			nfree(p);
101 			p = l;
102 			break;
103 		}
104 
105 		switch (p->n_type) {
106 		case BOOL:      l->n_lval = (l->n_lval != 0); break;
107 		case CHAR:      l->n_lval = (char)l->n_lval; break;
108 		case UCHAR:     l->n_lval = l->n_lval & 0377; break;
109 		case SHORT:     l->n_lval = (short)l->n_lval; break;
110 		case USHORT:    l->n_lval = l->n_lval & 0177777; break;
111 		case UNSIGNED:  l->n_lval = l->n_lval & 0xffffffff; break;
112 		case INT:       l->n_lval = (int)l->n_lval; break;
113 		case ULONG:
114 		case ULONGLONG: l->n_lval = l->n_lval; break;
115 		case LONG:
116 		case LONGLONG:	l->n_lval = (long long)l->n_lval; break;
117 		case FLOAT:
118 		case DOUBLE:
119 		case LDOUBLE:
120 			l->n_op = FCON;
121 			l->n_dcon = l->n_lval;
122 			break;
123 		case VOID:
124 			break;
125 		default:
126 			cerror("sconv type unknown %d", p->n_type);
127 		}
128 
129 		l->n_type = p->n_type;
130 		nfree(p);
131 		p = l;
132 		break;
133 
134 	case FORCE:
135 		/* Put attached value into the return register. */
136 		p->n_op = ASSIGN;
137 		p->n_right = p->n_left;
138 		p->n_left = block(REG, NIL, NIL, p->n_type, 0, 0);
139 		p->n_left->n_rval = RETREG_PRE(p->n_type);
140 		break;
141 	}
142 
143 #ifdef PCC_DEBUG
144 	if (xdebug) {
145 		printf("clocal out: %p, %s\n", p, copst(op));
146 		fwalk(p, eprint, 0);
147 	}
148 #endif
149 
150 	return p;
151 }
152 
153 void
myp2tree(NODE * p)154 myp2tree(NODE *p)
155 {
156 	struct symtab *sp;
157 
158 	if (p->n_op != FCON)
159 		return;
160 
161 	sp = tmpalloc(sizeof(struct symtab));
162 	sp->sclass = STATIC;
163 	sp->slevel = 1;
164 	sp->soffset = getlab();
165 	sp->sflags = 0;
166 	sp->stype = p->n_type;
167 	sp->squal = (CON >> TSHIFT);
168 
169 	defloc(sp);
170 	ninval(0, tsize(p->n_type, p->n_df, p->n_ap), p);
171 
172 	p->n_op = NAME;
173 	p->n_lval = 0;
174 	p->n_sp = sp;
175 }
176 
177 int
andable(NODE * p)178 andable(NODE *p)
179 {
180 	return 1;
181 }
182 
183 int
cisreg(TWORD t)184 cisreg(TWORD t)
185 {
186 	/* SPARCv9 registers are all 64-bits wide. */
187 	return 1;
188 }
189 
190 void
spalloc(NODE * t,NODE * p,OFFSZ off)191 spalloc(NODE *t, NODE *p, OFFSZ off)
192 {
193 	cerror("spalloc");
194 }
195 
196 int
ninval(CONSZ off,int fsz,NODE * p)197 ninval(CONSZ off, int fsz, NODE *p)
198 {
199 	union { float f; double d; int i; long long l; } u;
200 
201 	switch (p->n_type) {
202 	case FLOAT:
203 		u.f = (float)p->n_dcon;
204 		printf("\t.long %d\n", u.i);
205 		break;
206 	case DOUBLE:
207 		u.d = (double)p->n_dcon;
208 		printf("\t.xword %lld\n", u.l);
209 		break;
210 	default:
211 		return 0;
212 	}
213 	return 1;
214 }
215 
216 char *
exname(char * p)217 exname(char *p)
218 {
219 	return p ? p : "";
220 }
221 
222 TWORD
ctype(TWORD type)223 ctype(TWORD type)
224 {
225 	switch (BTYPE(type)) {
226 	case LONGLONG:
227 		MODTYPE(type,LONG);
228 		break;
229 	case ULONGLONG:
230 		MODTYPE(type,ULONG);
231 
232 	}
233 	return type;
234 }
235 
236 void
calldec(NODE * p,NODE * q)237 calldec(NODE *p, NODE *q)
238 {
239 }
240 
241 void
extdec(struct symtab * q)242 extdec(struct symtab *q)
243 {
244 }
245 
246 void
defzero(struct symtab * sp)247 defzero(struct symtab *sp)
248 {
249 	int off;
250 	char *name;
251 
252 	if ((name = sp->soname) == NULL)
253 		name = exname(sp->sname);
254 	off = tsize(sp->stype, sp->sdf, sp->sap);
255 	SETOFF(off,SZCHAR);
256 	off /= SZCHAR;
257 
258 	if (sp->sclass == STATIC)
259 		printf("\t.local %s\n", name);
260 	if (sp->slevel == 0)
261 		printf("\t.comm %s,%d\n", name, off);
262 	else
263 		printf("\t.comm " LABFMT ",%d\n", sp->soffset, off);
264 }
265 
266 int
mypragma(char * str)267 mypragma(char *str)
268 {
269 	return 0;
270 }
271 
272 void
fixdef(struct symtab * sp)273 fixdef(struct symtab *sp)
274 {
275 }
276 
277 void
pass1_lastchance(struct interpass * ip)278 pass1_lastchance(struct interpass *ip)
279 {
280 }
281 
282