source: mainline/uspace/app/pcc/arch/hppa/code.c@ 423e5e87

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 423e5e87 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: 6.4 KB
Line 
1/* $OpenBSD: code.c,v 1.2 2007/11/22 15:06:43 stefan Exp $ */
2
3/*
4 * Copyright (c) 2007 Michael Shalayeff
5 * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31
32# include "pass1.h"
33
34NODE *funarg(NODE *, int *);
35int argreg(TWORD, int *);
36
37static const char *const loctbl[] = { "text", "data", "section .rodata" };
38
39/*
40 * Define everything needed to print out some data (or text).
41 * This means segment, alignment, visibility, etc.
42 */
43void
44defloc(struct symtab *sp)
45{
46 extern char *nextsect;
47 static int lastloc = -1;
48 TWORD t;
49 char *n;
50 int s;
51
52 if (sp == NULL) {
53 lastloc = -1;
54 return;
55 }
56 t = sp->stype;
57 s = ISFTN(t) ? PROG : ISCON(cqual(t, sp->squal)) ? RDATA : DATA;
58 if (nextsect) {
59 printf("\t.section %s\n", nextsect);
60 nextsect = NULL;
61 s = -1;
62 } else if (s != lastloc)
63 printf("\t.%s\n", loctbl[s]);
64 lastloc = s;
65 while (ISARY(t))
66 t = DECREF(t);
67 s = ISFTN(t) ? ALINT : talign(t, sp->ssue);
68 if (s > ALCHAR)
69 printf("\t.align\t%d\n", s / ALCHAR);
70 n = sp->soname ? sp->soname : sp->sname;
71 if (sp->sclass == EXTDEF)
72 printf("\t.export %s, %s\n", n,
73 ISFTN(t)? "code" : "data");
74 if (sp->slevel == 0)
75 printf("\t.type\t%s, @%s\n\t.label %s\n",
76 n, ISFTN(t)? "function" : "object", n);
77 else
78 printf("\t.type\t" LABFMT ", @%s\n\t.label\t" LABFMT "\n",
79 sp->soffset, ISFTN(t)? "function" : "object", sp->soffset);
80}
81
82/*
83 * code for the end of a function
84 * deals with struct return here
85 */
86void
87efcode()
88{
89 NODE *p, *q;
90 int sz;
91
92 if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
93 return;
94 /* address of return struct is in %ret0 */
95 /* create a call to memcpy() */
96 /* will get the result in %ret0 */
97 p = block(REG, NIL, NIL, CHAR+PTR, 0, MKSUE(CHAR+PTR));
98 p->n_rval = RET0;
99 q = block(OREG, NIL, NIL, CHAR+PTR, 0, MKSUE(CHAR+PTR));
100 q->n_rval = FP;
101 q->n_lval = 8; /* return buffer offset */
102 p = block(CM, q, p, INT, 0, MKSUE(INT));
103 sz = (tsize(STRTY, cftnsp->sdf, cftnsp->ssue)+SZCHAR-1)/SZCHAR;
104 p = block(CM, p, bcon(sz), INT, 0, MKSUE(INT));
105 p->n_right->n_name = "";
106 p = block(CALL, bcon(0), p, CHAR+PTR, 0, MKSUE(CHAR+PTR));
107 p->n_left->n_name = "memcpy";
108 p = clocal(p);
109 send_passt(IP_NODE, p);
110}
111
112int
113argreg(TWORD t, int *n)
114{
115 switch (t) {
116 case FLOAT:
117 return FR7L - 2 * (*n)++;
118 case DOUBLE:
119 case LDOUBLE:
120 *n += 2;
121 return FR6 - *n - 2;
122 case LONGLONG:
123 case ULONGLONG:
124 *n += 2;
125 return AD1 - (*n - 2) / 2;
126 default:
127 return ARG0 - (*n)++;
128 }
129}
130
131/*
132 * code for the beginning of a function; 'a' is an array of
133 * indices in symtab for the arguments; n is the number
134 */
135void
136bfcode(struct symtab **a, int cnt)
137{
138 struct symtab *sp;
139 NODE *p, *q;
140 int i, n, sz;
141
142 if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
143 /* Function returns struct, adjust arg offset */
144 for (i = 0; i < n; i++)
145 a[i]->soffset += SZPOINT(LONG);
146 }
147
148 /* recalculate the arg offset and create TEMP moves */
149 for (n = 0, i = 0; i < cnt; i++) {
150 sp = a[i];
151
152 sz = szty(sp->stype);
153 if (n % sz)
154 n++; /* XXX LDOUBLE */
155
156 if (n < 4) {
157 p = tempnode(0, sp->stype, sp->sdf, sp->ssue);
158 /* TODO p->n_left->n_lval = -(32 + n * 4); */
159 q = block(REG, NIL, NIL, sp->stype, sp->sdf, sp->ssue);
160 q->n_rval = argreg(sp->stype, &n);
161 p = buildtree(ASSIGN, p, q);
162 sp->soffset = regno(p->n_left);
163 sp->sflags |= STNODE;
164 ecomp(p);
165 } else {
166 sp->soffset += SZINT * n;
167 if (xtemps) {
168 /* put stack args in temps if optimizing */
169 p = tempnode(0, sp->stype, sp->sdf, sp->ssue);
170 p = buildtree(ASSIGN, p, buildtree(NAME, 0, 0));
171 sp->soffset = regno(p->n_left);
172 sp->sflags |= STNODE;
173 ecomp(p);
174 }
175 }
176 }
177}
178
179
180/*
181 * by now, the automatics and register variables are allocated
182 */
183void
184bccode()
185{
186 SETOFF(autooff, SZINT);
187}
188
189/* called just before final exit */
190/* flag is 1 if errors, 0 if none */
191void
192ejobcode(int errors)
193{
194 if (errors)
195 return;
196
197 printf("\t.end\n");
198}
199
200void
201bjobcode(void)
202{
203 printf("\t.level\t1.1\n"
204 "\t.import $global$, data\n"
205 "\t.import $$dyncall, millicode\n");
206}
207
208/*
209 * return the alignment of field of type t
210 */
211int
212fldal(unsigned int t)
213{
214 uerror("illegal field type");
215 return(ALINT);
216}
217
218/* fix up type of field p */
219void
220fldty(struct symtab *p)
221{
222}
223
224/*
225 * XXX - fix genswitch.
226 */
227int
228mygenswitch(int num, TWORD type, struct swents **p, int n)
229{
230 return 0;
231}
232
233NODE *
234funarg(NODE *p, int *n)
235{
236 NODE *r;
237 int sz;
238
239 if (p->n_op == CM) {
240 p->n_left = funarg(p->n_left, n);
241 p->n_right = funarg(p->n_right, n);
242 return p;
243 }
244
245 sz = szty(p->n_type);
246 if (*n % sz)
247 (*n)++; /* XXX LDOUBLE */
248
249 if (*n >= 4) {
250 *n += sz;
251 r = block(OREG, NIL, NIL, p->n_type|PTR, 0,
252 MKSUE(p->n_type|PTR));
253 r->n_rval = SP;
254 r->n_lval = -(32 + *n * 4);
255 } else {
256 r = block(REG, NIL, NIL, p->n_type, 0, 0);
257 r->n_lval = 0;
258 r->n_rval = argreg(p->n_type, n);
259 }
260 p = block(ASSIGN, r, p, p->n_type, 0, 0);
261 clocal(p);
262
263 return p;
264}
265
266/*
267 * Called with a function call with arguments as argument.
268 * This is done early in buildtree() and only done once.
269 */
270NODE *
271funcode(NODE *p)
272{
273 int n = 0;
274
275 p->n_right = funarg(p->n_right, &n);
276 return p;
277}
Note: See TracBrowser for help on using the repository browser.