* add p cc
[mascara-docs.git] / compilers / pcc / pcc-1.0.0 / arch / sparc64 / local2.c
blob85674ff02febb433085eca79f1c9b192f3a1fa3e
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"
18 #include "pass2.h"
21 char *
22 rnames[] = {
23 /* "\%g0", always zero, removed due to 31-element class limit */
24 "\%g1", "\%g2", "\%g3", "\%g4", "\%g5", "\%g6", "\%g7",
25 "\%o0", "\%o1", "\%o2", "\%o3", "\%o4", "\%o5", "\%o6", "\%o7",
26 "\%l0", "\%l1", "\%l2", "\%l3", "\%l4", "\%l5", "\%l6", "\%l7",
27 "\%i0", "\%i1", "\%i2", "\%i3", "\%i4", "\%i5", "\%i6", "\%i7",
29 "\%f0", "\%f1", "\%f2", "\%f3", "\%f4", "\%f5", "\%f6", "\%f7",
30 "\%f8", "\%f9", "\%f10", "\%f11", "\%f12", "\%f13", "\%f14", "\%f15",
31 "\%f16", "\%f17", "\%f18", "\%f19", "\%f20", "\%f21", "\%f22", "\%f23",
32 "\%f24", "\%f25", "\%f26", "\%f27", "\%f28", "\%f29", "\%f30",
33 /*, "\%f31" XXX removed due to 31-element class limit */
35 "\%f0", "\%f2", "\%f4", "\%f6", "\%f8", "\%f10", "\%f12", "\%f14",
36 "\%f16", "\%f18", "\%f20", "\%f22", "\%f24", "\%f26", "\%f28", "\%f30",
38 "\%sp", "\%fp",
41 void
42 deflab(int label)
44 printf(LABFMT ":\n", label);
47 void
48 prologue(struct interpass_prolog *ipp)
50 int i, stack;
52 stack = V9RESERVE + V9STEP(p2maxautooff);
54 for (i = ipp->ipp_regs[0]; i; i >>= 1)
55 if (i & 1)
56 stack += 16;
58 /* TODO printf("\t.proc %d\n"); */
59 if (ipp->ipp_vis)
60 printf("\t.global %s\n", ipp->ipp_name);
61 printf("\t.align 4\n");
62 printf("%s:\n", ipp->ipp_name);
63 if (SIMM13(stack))
64 printf("\tsave %%sp,-%d,%%sp\n", stack);
65 else {
66 printf("\tsetx -%d,%%g4,%%g1\n", stack);
67 printf("\tsave %%sp,%%g1,%%sp\n");
71 void
72 eoftn(struct interpass_prolog *ipp)
74 printf("\tret\n");
75 printf("\trestore\n");
76 printf("\t.type %s,#function\n", ipp->ipp_name);
77 printf("\t.size %s,(.-%s)\n", ipp->ipp_name, ipp->ipp_name);
80 void
81 hopcode(int f, int o)
83 char *str;
85 switch (o) {
86 case EQ: str = "brz"; break;
87 case NE: str = "brnz"; break;
88 case ULE:
89 case LE: str = "brlez"; break;
90 case ULT:
91 case LT: str = "brlz"; break;
92 case UGE:
93 case GE: str = "brgez"; break;
94 case UGT:
95 case GT: str = "brgz"; break;
96 case PLUS: str = "add"; break;
97 case MINUS: str = "sub"; break;
98 case AND: str = "and"; break;
99 case OR: str = "or"; break;
100 case ER: str = "xor"; break;
101 default:
102 comperr("unknown hopcode: %d (with %c)", o, f);
103 return;
106 printf("%s%c", str, f);
110 tlen(NODE *p)
112 switch (p->n_type) {
113 case CHAR:
114 case UCHAR:
115 return 1;
116 case SHORT:
117 case USHORT:
118 return (SZSHORT / SZCHAR);
119 case FLOAT:
120 return (SZFLOAT / SZCHAR);
121 case DOUBLE:
122 return (SZDOUBLE / SZCHAR);
123 case INT:
124 case UNSIGNED:
125 return (SZINT / SZCHAR);
126 case LONG:
127 case ULONG:
128 case LONGLONG:
129 case ULONGLONG:
130 return SZLONGLONG / SZCHAR;
131 default:
132 if (!ISPTR(p->n_type))
133 comperr("tlen type unknown: %d");
134 return SZPOINT(p->n_type) / SZCHAR;
138 void
139 zzzcode(NODE * p, int c)
141 char *str;
142 NODE *l, *r;
143 l = p->n_left;
144 r = p->n_right;
146 switch (c) {
148 case 'A': /* Add const. */
149 if (ISPTR(l->n_type) && l->n_rval == FP)
150 r->n_lval += V9BIAS;
152 if (SIMM13(r->n_lval))
153 expand(p, 0, "\tadd AL,AR,A1\t\t! add const\n");
154 else
155 expand(p, 0, "\tsetx AR,A3,A2\t\t! add const\n"
156 "\tadd AL,A2,A1\n");
157 break;
158 case 'B': /* Subtract const. */
159 if (ISPTR(l->n_type) && l->n_rval == FP)
160 r->n_lval -= V9BIAS;
162 if (SIMM13(r->n_lval))
163 expand(p, 0, "\tsub AL,AR,A1\t\t! subtract const\n");
164 else
165 expand(p, 0, "\tsetx AR,A3,A2\t\t! subtract const\n"
166 "\tsub AL,A2,A1\n");
167 break;
168 case 'C': /* Load constant to register. */
169 if (ISPTR(p->n_type))
170 expand(p, 0,
171 "\tsethi %h44(AL),A1\t\t! load label\n"
172 "\tor A1,%m44(AL),A1\n"
173 "\tsllx A1,12,A1\n"
174 "\tor A1,%l44(AL),A1\n");
175 else if (SIMM13(p->n_lval))
176 expand(p, 0, "\tor %g0,AL,A1\t\t\t! load const\n");
177 else
178 expand(p, 0, "\tsetx AL,A2,A1\t\t! load const\n");
179 break;
180 case 'F': /* Floating-point comparison, cf. hopcode(). */
181 switch (p->n_op) {
182 case EQ: str = "fbe"; break;
183 case NE: str = "fbne"; break;
184 case ULE:
185 case LE: str = "fbule"; break;
186 case ULT:
187 case LT: str = "fbul"; break;
188 case UGE:
189 case GE: str = "fbuge"; break;
190 case UGT:
191 case GT: str = "fbug"; break;
192 /* XXX
193 case PLUS: str = "add"; break;
194 case MINUS: str = "sub"; break;
195 case AND: str = "and"; break;
196 case OR: str = "or"; break;
197 case ER: str = "xor"; break;*/
198 default:
199 comperr("unknown float code: %d", p->n_op);
200 return;
202 printf(str);
203 break;
205 case 'Q': /* Structure assignment. */
206 /* TODO Check if p->n_stsize is small and use a few ldx's
207 to move the struct instead of memcpy. The equiv.
208 could be done on all the architectures. */
209 if (l->n_rval != O0)
210 printf("\tmov %s,%s\n", rnames[l->n_rval], rnames[O0]);
211 if (SIMM13(p->n_stsize))
212 printf("\tor %%g0,%d,%%o2\n", p->n_stsize);
213 else
214 printf("\tsetx %d,%%g1,%%o2\n", p->n_stsize);
215 printf("\tcall memcpy\t\t\t! struct assign (dest, src, len)\n");
216 printf("\tnop\n");
217 break;
218 default:
219 cerror("unknown zzzcode call: %c", c);
224 rewfld(NODE * p)
226 return (1);
230 fldexpand(NODE *p, int cookie, char **cp)
232 printf("XXX fldexpand called\n"); /* XXX */
233 return 1;
237 flshape(NODE * p)
239 return SRREG;
243 shtemp(NODE * p)
245 return 0;
249 void
250 adrcon(CONSZ val)
254 void
255 conput(FILE * fp, NODE * p)
257 if (p->n_op != ICON) {
258 comperr("conput got bad op: %s", copst(p->n_op));
259 return;
262 if (p->n_name[0] != '\0') {
263 fprintf(fp, "%s", p->n_name);
264 if (p->n_lval > 0)
265 fprintf(fp, "+");
266 if (p->n_lval)
267 fprintf(fp, CONFMT, p->n_lval);
268 } else
269 fprintf(fp, CONFMT, p->n_lval);
272 void
273 insput(NODE * p)
275 comperr("insput");
278 void
279 upput(NODE *p, int size)
281 comperr("upput");
284 void
285 adrput(FILE * io, NODE * p)
287 int64_t off;
289 if (p->n_op == FLD) {
290 printf("adrput a FLD\n");
291 p = p->n_left;
294 if (p->n_op == UMUL && p->n_right == 0)
295 p = p->n_left;
297 off = p->n_lval;
299 switch (p->n_op) {
300 case NAME:
301 if (p->n_name[0] != '\0')
302 fputs(p->n_name, io);
303 if (off > 0)
304 fprintf(io, "+");
305 if (off != 0)
306 fprintf(io, CONFMT, (long long int)off);
307 return;
308 case OREG:
309 fprintf(io, "%s", rnames[p->n_rval]);
310 if (p->n_rval == FP)
311 off += V9BIAS;
312 if (p->n_rval == SP)
313 off += V9BIAS + V9RESERVE;
314 if (off > 0)
315 fprintf(io, "+");
316 if (off)
317 fprintf(io, CONFMT, (CONSZ)off);
318 return;
319 case ICON:
320 /* addressable value of the constant */
321 conput(io, p);
322 return;
323 case REG:
324 fputs(rnames[p->n_rval], io);
325 return;
326 case FUNARG:
327 /* We do something odd and store the stack offset in n_rval. */
328 fprintf(io, "%d", V9BIAS + V9RESERVE + p->n_rval);
329 return;
330 default:
331 comperr("bad address, %s, node %p", copst(p->n_op), p);
332 return;
336 void
337 cbgen(int o, int lab)
341 void
342 myreader(struct interpass * ipole)
346 void
347 mycanon(NODE * p)
351 void
352 myoptim(struct interpass * ipole)
356 void
357 rmove(int s, int d, TWORD t)
359 printf("\t");
361 if (t == FLOAT) printf("fmovs");
362 else if (t == DOUBLE) printf("fmovd");
363 else printf("mov");
365 printf(" %s,%s\t\t\t! rmove()\n", rnames[s], rnames[d]);
369 gclass(TWORD t)
371 if (t == FLOAT)
372 return CLASSB;
373 if (t == DOUBLE)
374 return CLASSC;
375 return CLASSA;
378 void
379 lastcall(NODE *p)
384 special(NODE *p, int shape)
386 return SRNOPE;
389 void mflags(char *str)
394 COLORMAP(int c, int *r)
396 int num=0;
398 switch (c) {
399 case CLASSA:
400 num += r[CLASSA];
401 return num < 32;
402 case CLASSB:
403 num += r[CLASSB];
404 num += 2*r[CLASSC];
405 return num < 32;;
406 case CLASSC:
407 num += r[CLASSC];
408 num += 2*r[CLASSB];
409 return num < 17;
410 case CLASSD:
411 return 0;
412 default:
413 comperr("COLORMAP: unknown class: %d", c);
414 return 0;
418 * Do something target-dependent for xasm arguments.
419 * Supposed to find target-specific constraints and rewrite them.
422 myxasm(struct interpass *ip, NODE *p)
424 return 0;