source: mainline/uspace/app/pcc/arch/nova/local2.c@ 6037308

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 6037308 was a7de7182, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 14 years ago

Added pcc source tree (contents of pcc-1.0.0.tgz)

  • Property mode set to 100644
File size: 10.4 KB
Line 
1/* $Id: local2.c,v 1.7 2008/11/01 08:29:37 mickey Exp $ */
2/*
3 * Copyright (c) 2006 Anders Magnusson (ragge@ludd.luth.se).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29
30# include "pass2.h"
31# include <ctype.h>
32# include <string.h>
33
34void acon(NODE *p);
35int argsize(NODE *p);
36
37void
38deflab(int label)
39{
40 printf(LABFMT ":\n", label);
41}
42
43static int prolnum;
44static struct ldq {
45 struct ldq *next;
46 int val;
47 int lab;
48 char *name;
49} *ldq;
50
51
52void
53prologue(struct interpass_prolog *ipp)
54{
55 int i, j;
56
57 for (j = i = 0; i < MAXREGS; i++)
58 if (TESTBIT(ipp->ipp_regs, i))
59 j++;
60
61 printf(".LP%d: .word 0%o\n", prolnum, j);
62 if (ipp->ipp_vis)
63 printf(" .globl %s\n", ipp->ipp_name);
64 printf("%s:\n", ipp->ipp_name);
65 printf(" sta 3,@40\n"); /* save ret pc on stack */
66 printf(" lda 2,.LP%d-.,1\n", prolnum);
67 printf(" jsr @45\n");
68 prolnum++;
69}
70
71void
72eoftn(struct interpass_prolog *ipp)
73{
74 int i, j;
75
76 if (ipp->ipp_ip.ip_lbl == 0)
77 return; /* no code needs to be generated */
78
79 /* return from function code */
80 for (j = i = 0; i < MAXREGS; i++)
81 if (TESTBIT(ipp->ipp_regs, i))
82 j++;
83 printf(" lda 2,.LP%d-.,1\n", prolnum);
84 printf(" jmp @46\n");
85 printf(".LP%d: .word 0%o\n", prolnum, j);
86 prolnum++;
87 while (ldq) {
88 printf(".LP%d: .word 0%o", ldq->lab, ldq->val);
89 if (ldq->name && *ldq->name)
90 printf("+%s", ldq->name);
91 printf("\n");
92 ldq = ldq->next;
93 }
94}
95
96/*
97 * add/sub/...
98 *
99 * Param given:
100 */
101void
102hopcode(int f, int o)
103{
104 char *str = 0;
105
106 switch (o) {
107 case PLUS:
108 str = "add";
109 break;
110 case MINUS:
111 str = "sub";
112 break;
113 case AND:
114 str = "and";
115 break;
116 case OR:
117 cerror("hopcode OR");
118 break;
119 case ER:
120 cerror("hopcode xor");
121 str = "xor";
122 break;
123 default:
124 comperr("hopcode2: %d", o);
125 str = 0; /* XXX gcc */
126 }
127 printf("%s%c", str, f);
128}
129
130#if 0
131/*
132 * Return type size in bytes. Used by R2REGS, arg 2 to offset().
133 */
134int
135tlen(p) NODE *p;
136{
137 switch(p->n_type) {
138 case CHAR:
139 case UCHAR:
140 return(1);
141
142 case SHORT:
143 case USHORT:
144 return(SZSHORT/SZCHAR);
145
146 case DOUBLE:
147 return(SZDOUBLE/SZCHAR);
148
149 case INT:
150 case UNSIGNED:
151 case LONG:
152 case ULONG:
153 return(SZINT/SZCHAR);
154
155 case LONGLONG:
156 case ULONGLONG:
157 return SZLONGLONG/SZCHAR;
158
159 default:
160 if (!ISPTR(p->n_type))
161 comperr("tlen type %d not pointer");
162 return SZPOINT(p->n_type)/SZCHAR;
163 }
164}
165#endif
166
167int
168fldexpand(NODE *p, int cookie, char **cp)
169{
170 return 0;
171}
172
173#if 0
174/*
175 * Assign to a bitfield.
176 * Clumsy at least, but what to do?
177 */
178static void
179bfasg(NODE *p)
180{
181 NODE *fn = p->n_left;
182 int shift = UPKFOFF(fn->n_rval);
183 int fsz = UPKFSZ(fn->n_rval);
184 int andval, tch = 0;
185
186 /* get instruction size */
187 switch (p->n_type) {
188 case CHAR: case UCHAR: tch = 'b'; break;
189 case SHORT: case USHORT: tch = 'w'; break;
190 case INT: case UNSIGNED: tch = 'l'; break;
191 default: comperr("bfasg");
192 }
193
194 /* put src into a temporary reg */
195 fprintf(stdout, " mov%c ", tch);
196 adrput(stdout, getlr(p, 'R'));
197 fprintf(stdout, ",");
198 adrput(stdout, getlr(p, '1'));
199 fprintf(stdout, "\n");
200
201 /* AND away the bits from dest */
202 andval = ~(((1 << fsz) - 1) << shift);
203 fprintf(stdout, " and%c $%d,", tch, andval);
204 adrput(stdout, fn->n_left);
205 fprintf(stdout, "\n");
206
207 /* AND away unwanted bits from src */
208 andval = ((1 << fsz) - 1);
209 fprintf(stdout, " and%c $%d,", tch, andval);
210 adrput(stdout, getlr(p, '1'));
211 fprintf(stdout, "\n");
212
213 /* SHIFT left src number of bits */
214 if (shift) {
215 fprintf(stdout, " sal%c $%d,", tch, shift);
216 adrput(stdout, getlr(p, '1'));
217 fprintf(stdout, "\n");
218 }
219
220 /* OR in src to dest */
221 fprintf(stdout, " or%c ", tch);
222 adrput(stdout, getlr(p, '1'));
223 fprintf(stdout, ",");
224 adrput(stdout, fn->n_left);
225 fprintf(stdout, "\n");
226}
227#endif
228
229#if 0
230/*
231 * Push a structure on stack as argument.
232 * the scratch registers are already free here
233 */
234static void
235starg(NODE *p)
236{
237 FILE *fp = stdout;
238
239 fprintf(fp, " subl $%d,%%esp\n", p->n_stsize);
240 fprintf(fp, " pushl $%d\n", p->n_stsize);
241 expand(p, 0, " pushl AL\n");
242 expand(p, 0, " leal 8(%esp),A1\n");
243 expand(p, 0, " pushl A1\n");
244 fprintf(fp, " call memcpy\n");
245 fprintf(fp, " addl $12,%%esp\n");
246}
247#endif
248
249void
250zzzcode(NODE *p, int c)
251{
252 struct ldq *ld;
253
254 switch (c) {
255 case 'A': /* print out a skip ending if any numbers in queue */
256 if (ldq == NULL)
257 return;
258 printf(",skp\n.LP%d: .word 0%o", ldq->lab, ldq->val);
259 if (ldq->name && *ldq->name)
260 printf("+%s", ldq->name);
261 printf("\n");
262 ldq = ldq->next;
263 break;
264
265 case 'B': /* print a label for later load */
266 ld = tmpalloc(sizeof(struct ldq));
267 ld->val = p->n_lval;
268 ld->name = p->n_name;
269 ld->lab = prolnum++;
270 ld->next = ldq;
271 ldq = ld;
272 printf(".LP%d-.", ld->lab);
273 break;
274
275 case 'C': /* fix reference to external variable via indirection */
276 zzzcode(p->n_left, 'B');
277 break;
278
279 case 'D': /* fix reference to external variable via indirection */
280 zzzcode(p, 'B');
281 break;
282
283 default:
284 comperr("zzzcode %c", c);
285 }
286}
287
288/*ARGSUSED*/
289int
290rewfld(NODE *p)
291{
292 return(1);
293}
294
295int canaddr(NODE *);
296int
297canaddr(NODE *p)
298{
299 int o = p->n_op;
300
301 if (o==NAME || o==REG || o==ICON || o==OREG ||
302 (o==UMUL && shumul(p->n_left, SOREG)))
303 return(1);
304 return(0);
305}
306
307/*
308 * Does the bitfield shape match?
309 */
310int
311flshape(NODE *p)
312{
313 int o = p->n_op;
314
315cerror("flshape");
316 if (o == OREG || o == REG || o == NAME)
317 return SRDIR; /* Direct match */
318 if (o == UMUL && shumul(p->n_left, SOREG))
319 return SROREG; /* Convert into oreg */
320 return SRREG; /* put it into a register */
321}
322
323/* INTEMP shapes must not contain any temporary registers */
324/* XXX should this go away now? */
325int
326shtemp(NODE *p)
327{
328 return 0;
329#if 0
330 int r;
331
332 if (p->n_op == STARG )
333 p = p->n_left;
334
335 switch (p->n_op) {
336 case REG:
337 return (!istreg(p->n_rval));
338
339 case OREG:
340 r = p->n_rval;
341 if (R2TEST(r)) {
342 if (istreg(R2UPK1(r)))
343 return(0);
344 r = R2UPK2(r);
345 }
346 return (!istreg(r));
347
348 case UMUL:
349 p = p->n_left;
350 return (p->n_op != UMUL && shtemp(p));
351 }
352
353 if (optype(p->n_op) != LTYPE)
354 return(0);
355 return(1);
356#endif
357}
358
359void
360adrcon(CONSZ val)
361{
362 printf("$" CONFMT, val);
363}
364
365/*
366 * Conput should only be used by e2print on Nova.
367 */
368void
369conput(FILE *fp, NODE *p)
370{
371 int val = p->n_lval;
372
373 switch (p->n_op) {
374 case ICON:
375 if (p->n_name[0] != '\0') {
376 fprintf(fp, "%s", p->n_name);
377 if (val)
378 fprintf(fp, "+%d", val);
379 } else
380 fprintf(fp, "%d", val);
381 return;
382
383 default:
384 comperr("illegal conput, p %p", p);
385 }
386}
387
388/*ARGSUSED*/
389void
390insput(NODE *p)
391{
392 comperr("insput");
393}
394
395/*
396 * Write out the upper address, like the upper register of a 2-register
397 * reference, or the next memory location.
398 */
399void
400upput(NODE *p, int size)
401{
402comperr("upput");
403#if 0
404 size /= SZCHAR;
405 switch (p->n_op) {
406 case REG:
407 fprintf(stdout, "%%%s", &rnames[p->n_rval][3]);
408 break;
409
410 case NAME:
411 case OREG:
412 p->n_lval += size;
413 adrput(stdout, p);
414 p->n_lval -= size;
415 break;
416 case ICON:
417 fprintf(stdout, "$" CONFMT, p->n_lval >> 32);
418 break;
419 default:
420 comperr("upput bad op %d size %d", p->n_op, size);
421 }
422#endif
423}
424
425void
426adrput(FILE *io, NODE *p)
427{
428 /* output an address, with offsets, from p */
429
430 if (p->n_op == FLD)
431 p = p->n_left;
432
433 switch (p->n_op) {
434
435 case NAME:
436 if (p->n_name[0] != '\0')
437 fputs(p->n_name, io);
438 if (p->n_lval != 0)
439 fprintf(io, "+" CONFMT, p->n_lval);
440 return;
441
442 case OREG:
443 printf("%d,%s", (int)p->n_lval, rnames[p->n_rval]);
444 return;
445
446 case ICON:
447 /* addressable value of the constant */
448 fputc('$', io);
449 conput(io, p);
450 return;
451
452 case MOVE:
453 case REG:
454 switch (p->n_type) {
455 case LONGLONG:
456 case ULONGLONG:
457 fprintf(io, "%%%c%c%c", rnames[p->n_rval][0],
458 rnames[p->n_rval][1], rnames[p->n_rval][2]);
459 break;
460 case SHORT:
461 case USHORT:
462 fprintf(io, "%%%s", &rnames[p->n_rval][2]);
463 break;
464 default:
465 fprintf(io, "%s", rnames[p->n_rval]);
466 }
467 return;
468
469 default:
470 comperr("illegal address, op %d, node %p", p->n_op, p);
471 return;
472
473 }
474}
475
476/* printf conditional and unconditional branches */
477void
478cbgen(int o, int lab)
479{
480 comperr("cbgen");
481}
482
483void
484myreader(struct interpass *ipole)
485{
486 if (x2debug)
487 printip(ipole);
488}
489
490void
491mycanon(NODE *p)
492{
493}
494
495void
496myoptim(struct interpass *ip)
497{
498}
499
500void
501rmove(int s, int d, TWORD t)
502{
503 comperr("rmove");
504}
505
506/*
507 * For class c, find worst-case displacement of the number of
508 * registers in the array r[] indexed by class.
509 * Return true if we always can find a color.
510 */
511int
512COLORMAP(int c, int *r)
513{
514 int num;
515
516 switch (c) {
517 case CLASSA:
518 num = r[CLASSB] + r[CLASSA];
519 return num < 4;
520 case CLASSB:
521 num = r[CLASSB] + r[CLASSA];
522 return num < 2;
523 case CLASSC:
524 return r[CLASSC] < CREGCNT;
525 case CLASSD:
526 return r[CLASSD] < DREGCNT;
527 }
528 return 0; /* XXX gcc */
529}
530
531char *rnames[] = {
532 "0", "1", "2", "3",
533 "050", "051", "052", "053", "054", "055", "056", "057",
534 "060", "061", "062", "063", "064", "065", "066", "067",
535 "070", "071", "072", "073", "074", "075", "076", "077",
536 "041", "040"
537};
538
539/*
540 * Return a class suitable for a specific type.
541 */
542int
543gclass(TWORD t)
544{
545 return CLASSA;
546}
547
548/*
549 * Calculate argument sizes.
550 */
551void
552lastcall(NODE *p)
553{
554}
555
556/*
557 * Special shapes.
558 */
559int
560special(NODE *p, int shape)
561{
562 return SRNOPE;
563}
564
565/*
566 * Target-dependent command-line options.
567 */
568void
569mflags(char *str)
570{
571}
572/*
573 * Do something target-dependent for xasm arguments.
574 * Supposed to find target-specific constraints and rewrite them.
575 */
576int
577myxasm(struct interpass *ip, NODE *p)
578{
579 return 0;
580}
Note: See TracBrowser for help on using the repository browser.