* add p cc
[mascara-docs.git] / compilers / pcc / pcc-1.0.0 / arch / sparc64 / local.c
blob6c3206dc4c50f59a9da8886a4ac249e5ec0a0931
1 /*
2 * Copyright (c) 2008 David Crawshaw <david@zentus.com>
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include "pass1.h"
19 NODE *
20 clocal(NODE *p)
22 struct symtab *sp;
23 int op;
24 NODE *r, *l;
26 op = p->n_op;
27 sp = p->n_sp;
28 l = p->n_left;
29 r = p->n_right;
31 #ifdef PCC_DEBUG
32 if (xdebug) {
33 printf("clocal in: %p, %s\n", p, copst(op));
34 fwalk(p, eprint, 0);
36 #endif
38 switch (op) {
40 case NAME:
41 if (sp->sclass == PARAM || sp->sclass == AUTO) {
43 * Use a fake structure reference to
44 * write out frame pointer offsets.
46 l = block(REG, NIL, NIL, PTR+STRTY, 0, 0);
47 l->n_lval = 0;
48 l->n_rval = FP;
49 r = p;
50 p = stref(block(STREF, l, r, 0, 0, 0));
52 break;
53 case PCONV: /* Remove what PCONVs we can. */
54 if (l->n_op == SCONV)
55 break;
57 if (l->n_op == ICON || (ISPTR(p->n_type) && ISPTR(l->n_type))) {
58 l->n_type = p->n_type;
59 l->n_qual = p->n_qual;
60 l->n_df = p->n_df;
61 l->n_ap = p->n_ap;
62 nfree(p);
63 p = l;
65 break;
67 case SCONV:
68 /* Remove redundant conversions. */
69 if ((p->n_type & TMASK) == 0 && (l->n_type & TMASK) == 0 &&
70 btattr[p->n_type].atypsz == btattr[l->n_type].atypsz &&
71 p->n_type != FLOAT && p->n_type != DOUBLE &&
72 l->n_type != FLOAT && l->n_type != DOUBLE &&
73 l->n_type != DOUBLE && p->n_type != LDOUBLE) {
74 if (l->n_op == NAME || l->n_op == UMUL ||
75 l->n_op == TEMP) {
76 l->n_type = p->n_type;
77 nfree(p);
78 p = l;
79 break;
83 /* Convert floating point to int before to char or short. */
84 if ((l->n_type == FLOAT || l->n_type == DOUBLE || l->n_type == LDOUBLE)
85 && (DEUNSIGN(p->n_type) == CHAR || DEUNSIGN(p->n_type) == SHORT)) {
86 p = block(SCONV, p, NIL, p->n_type, p->n_df, p->n_ap);
87 p->n_left->n_type = INT;
88 break;
91 /* Transform constants now. */
92 if (l->n_op != ICON)
93 break;
95 if (ISPTR(p->n_type)) {
96 l->n_type = p->n_type;
97 nfree(p);
98 p = l;
99 break;
102 switch (p->n_type) {
103 case BOOL: l->n_lval = (l->n_lval != 0); break;
104 case CHAR: l->n_lval = (char)l->n_lval; break;
105 case UCHAR: l->n_lval = l->n_lval & 0377; break;
106 case SHORT: l->n_lval = (short)l->n_lval; break;
107 case USHORT: l->n_lval = l->n_lval & 0177777; break;
108 case UNSIGNED: l->n_lval = l->n_lval & 0xffffffff; break;
109 case INT: l->n_lval = (int)l->n_lval; break;
110 case ULONG:
111 case ULONGLONG: l->n_lval = l->n_lval; break;
112 case LONG:
113 case LONGLONG: l->n_lval = (long long)l->n_lval; break;
114 case FLOAT:
115 case DOUBLE:
116 case LDOUBLE:
117 l->n_op = FCON;
118 l->n_dcon = l->n_lval;
119 break;
120 case VOID:
121 break;
122 default:
123 cerror("sconv type unknown %d", p->n_type);
126 l->n_type = p->n_type;
127 nfree(p);
128 p = l;
129 break;
131 case PMCONV:
132 case PVCONV:
133 if (r->n_op != ICON)
134 cerror("converting bad type");
135 nfree(p);
136 p = buildtree(op == PMCONV ? MUL : DIV, l, r);
137 break;
139 case FORCE:
140 /* Put attached value into the return register. */
141 p->n_op = ASSIGN;
142 p->n_right = p->n_left;
143 p->n_left = block(REG, NIL, NIL, p->n_type, 0, MKAP(INT));
144 p->n_left->n_rval = RETREG_PRE(p->n_type);
145 break;
148 #ifdef PCC_DEBUG
149 if (xdebug) {
150 printf("clocal out: %p, %s\n", p, copst(op));
151 fwalk(p, eprint, 0);
153 #endif
155 return p;
158 void
159 myp2tree(NODE *p)
161 struct symtab *sp;
163 if (p->n_op != FCON)
164 return;
166 sp = tmpalloc(sizeof(struct symtab));
167 sp->sclass = STATIC;
168 sp->slevel = 1;
169 sp->soffset = getlab();
170 sp->sflags = 0;
171 sp->stype = p->n_type;
172 sp->squal = (CON >> TSHIFT);
174 defloc(sp);
175 ninval(0, btattr[p->n_type].atypsz, p);
177 p->n_op = NAME;
178 p->n_lval = 0;
179 p->n_sp = sp;
183 andable(NODE *p)
185 return 1;
188 void
189 cendarg()
191 autooff = AUTOINIT;
195 cisreg(TWORD t)
197 /* SPARCv9 registers are all 64-bits wide. */
198 return 1;
201 NODE *
202 offcon(OFFSZ off, TWORD t, union dimfun *d, struct attr *ap)
204 return bcon(off / SZCHAR);
207 void
208 spalloc(NODE *t, NODE *p, OFFSZ off)
212 void
213 instring(struct symtab *sp)
215 char *s, *str;
217 defloc(sp);
218 str = sp->sname;
220 printf("\t.ascii \"");
221 for (s = str; *s != 0; ) {
222 if (*s++ == '\\')
223 esccon(&s);
224 if (s - str > 60) {
225 fwrite(str, 1, s - str, stdout);
226 printf("\"\n\t.ascii \"");
227 str = s;
230 fwrite(str, 1, s - str, stdout);
231 printf("\\0\"\n");
234 void
235 zbits(OFFSZ off, int fsz)
239 void
240 infld(CONSZ off, int fsz, CONSZ val)
244 void
245 ninval(CONSZ off, int fsz, NODE *p)
247 TWORD t;
248 struct symtab *sp;
249 union { float f; double d; int i; long long l; } u;
251 t = p->n_type;
252 sp = p->n_sp;
254 if (ISPTR(t))
255 t = LONGLONG;
257 if (p->n_op != ICON && p->n_op != FCON)
258 cerror("ninval: not a constant");
259 if (p->n_op == ICON && sp != NULL && DEUNSIGN(t) != LONGLONG)
260 cerror("ninval: not constant");
262 switch (t) {
263 case CHAR:
264 case UCHAR:
265 printf("\t.byte %d\n", (int)p->n_lval & 0xff);
266 break;
267 case SHORT:
268 case USHORT:
269 printf("\t.half %d\n", (int)p->n_lval &0xffff);
270 break;
271 case BOOL:
272 p->n_lval = (p->n_lval != 0); /* FALLTHROUGH */
273 case INT:
274 case UNSIGNED:
275 printf("\t.long " CONFMT "\n", p->n_lval);
276 break;
277 case LONG:
278 case ULONG:
279 case LONGLONG:
280 case ULONGLONG:
281 printf("\t.xword %lld", p->n_lval);
282 if (sp != 0) {
283 if (sp->sclass == STATIC && sp->slevel > 0)
284 printf("+" LABFMT, sp->soffset);
285 else
286 printf("+%s", sp->soname ?
287 sp->soname : exname(sp->sname));
289 printf("\n");
290 break;
291 case FLOAT:
292 u.f = (float)p->n_dcon;
293 printf("\t.long %d\n", u.i);
294 break;
295 case DOUBLE:
296 u.d = (double)p->n_dcon;
297 printf("\t.xword %lld\n", u.l);
298 break;
302 char *
303 exname(char *p)
305 return p ? p : "";
308 TWORD
309 ctype(TWORD type)
311 return type;
314 void
315 calldec(NODE *p, NODE *q)
319 void
320 extdec(struct symtab *q)
324 void
325 defzero(struct symtab *sp)
327 int off = (tsize(sp->stype, sp->sdf, sp->sap) + SZCHAR - 1) / SZCHAR;
328 printf("\t.comm ");
329 if (sp->slevel == 0)
330 printf("%s,%d\n", sp->soname ? sp->soname : exname(sp->sname), off);
331 else
332 printf(LABFMT ",%d\n", sp->soffset, off);
336 mypragma(char *str)
338 return 0;
341 void
342 fixdef(struct symtab *sp)
346 void
347 pass1_lastchance(struct interpass *ip)