source: mainline/uspace/app/pcc/arch/m16c/code.c@ a837544

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a837544 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: 7.3 KB
Line 
1/* $Id: code.c,v 1.20 2008/07/29 13:25:58 ragge Exp $ */
2/*
3 * Copyright (c) 2003 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 "pass1.h"
31
32/*
33 * cause the alignment to become a multiple of n
34 */
35void
36defalign(int n)
37{
38#if 0
39 char *s;
40
41 n /= SZCHAR;
42 if (lastloc == PROG || n == 1)
43 return;
44 s = (isinlining ? permalloc(40) : tmpalloc(40));
45 sprintf(s, ".align %d", n);
46 send_passt(IP_ASM, s);
47#endif
48}
49
50/*
51 * define the current location as the name p->soname
52 */
53void
54defnam(struct symtab *p)
55{
56 char *c = p->soname;
57
58 if (p->sclass == EXTDEF)
59 printf(" PUBLIC %s\n", c);
60 printf("%s:\n", c);
61}
62
63
64/*
65 * code for the end of a function
66 * deals with struct return here
67 */
68void
69efcode()
70{
71 NODE *p, *q;
72 int sz;
73
74 if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
75 return;
76 /* address of return struct is in eax */
77 /* create a call to memcpy() */
78 /* will get the result in eax */
79 p = block(REG, NIL, NIL, CHAR+PTR, 0, MKSUE(CHAR+PTR));
80 p->n_rval = R0;
81 q = block(OREG, NIL, NIL, CHAR+PTR, 0, MKSUE(CHAR+PTR));
82 q->n_rval = FB;
83 q->n_lval = 8; /* return buffer offset */
84 p = block(CM, q, p, INT, 0, MKSUE(INT));
85 sz = (tsize(STRTY, cftnsp->sdf, cftnsp->ssue)+SZCHAR-1)/SZCHAR;
86 p = block(CM, p, bcon(sz), INT, 0, MKSUE(INT));
87 p->n_right->n_name = "";
88 p = block(CALL, bcon(0), p, CHAR+PTR, 0, MKSUE(CHAR+PTR));
89 p->n_left->n_name = "memcpy";
90 send_passt(IP_NODE, p);
91}
92
93/*
94 * helper for bfcode() to put register arguments on stack.
95 */
96static void
97argmove(struct symtab *s, int regno)
98{
99 NODE *p, *r;
100
101 s->sclass = AUTO;
102 s->soffset = NOOFFSET;
103 oalloc(s, &autooff);
104 p = nametree(s);
105 r = bcon(0);
106 r->n_op = REG;
107 r->n_rval = regno;
108 r->n_type = p->n_type;
109 r->n_sue = p->n_sue;
110 r->n_df = p->n_df;
111 ecode(buildtree(ASSIGN, p, r));
112}
113
114/*
115 * code for the beginning of a function; a is an array of
116 * indices in symtab for the arguments; n is the number
117 * On m16k, space is allocated on stack for register arguments,
118 * arguments are moved to the stack and symtab is updated accordingly.
119 */
120void
121bfcode(struct symtab **a, int n)
122{
123 struct symtab *s;
124 int i, r0l, r0h, a0, r2, sz, hasch, stk;
125 int argoff = ARGINIT;
126
127 if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
128 /* Function returns struct, adjust arg offset */
129 for (i = 0; i < n; i++)
130 a[i]->soffset += SZPOINT(INT);
131 }
132 /* first check if there are 1-byte parameters */
133 for (hasch = i = 0; i < n && i < 6; i++)
134 if (DEUNSIGN(a[i]->stype) == CHAR)
135 hasch = 1;
136
137 stk = r0l = r0h = a0 = r2 = 0;
138 for (i = 0; i < n; i++) {
139 s = a[i];
140 sz = tsize(s->stype, s->sdf, s->ssue);
141 if (ISPTR(s->stype) && ISFTN(DECREF(s->stype)))
142 sz = SZLONG; /* function pointers are always 32 */
143 if (stk == 0)
144 switch (sz) {
145 case SZCHAR:
146 if (r0l) {
147 if (r0h)
148 break;
149 argmove(s, 1);
150 r0h = 1;
151 } else {
152 argmove(s, 0);
153 r0l = 1;
154 }
155 continue;
156
157 case SZINT:
158 if (s->stype > BTMASK) {
159 /* is a pointer */
160 if (a0) {
161 if (r0l || hasch) {
162 if (r2)
163 break;
164 argmove(s, R2);
165 r2 = 1;
166 } else {
167 argmove(s, R0);
168 r0l = r0h = 1;
169 }
170 } else {
171 argmove(s, A0);
172 a0 = 1;
173 }
174 } else if (r0l || hasch) {
175 if (r2) {
176 if (a0)
177 break;
178 argmove(s, A0);
179 a0 = 1;
180 } else {
181 argmove(s, R2);
182 r2 = 1;
183 }
184 } else {
185 argmove(s, R0);
186 r0l = r0h = 1;
187 }
188 continue;
189 case SZLONG:
190 if (r0l||r0h||r2)
191 break;
192 argmove(s, R0);
193 r0l = r0h = r2 = 1;
194 continue;
195
196 default:
197 break;
198 }
199 stk = 1;
200 s->soffset = argoff;
201 argoff += sz;
202 }
203}
204
205/*
206 * Add a symbol to an internal list printed out at the end.
207 */
208void addsym(struct symtab *);
209static struct symlst {
210 struct symlst *next;
211 struct symtab *sp;
212} *sympole;
213
214void
215addsym(struct symtab *q)
216{
217 struct symlst *w = sympole;
218
219 if (q == NULL)
220 return;
221
222 while (w) {
223 if (q == w->sp)
224 return; /* exists */
225 w = w->next;
226 }
227 w = permalloc(sizeof(struct symlst));
228 w->sp = q;
229 w->next = sympole;
230 sympole = w;
231}
232
233/*
234 * by now, the automatics and register variables are allocated
235 */
236void
237bccode()
238{
239}
240
241struct caps {
242 char *cap, *stat;
243} caps[] = {
244 { "__64bit_doubles", "Disabled" },
245 { "__calling_convention", "Normal" },
246 { "__constant_data", "near" },
247 { "__data_alignment", "2" },
248 { "__data_model", "near" },
249 { "__processor", "M16C" },
250 { "__rt_version", "1" },
251 { "__variable_data", "near" },
252 { NULL, NULL },
253};
254/*
255 * Called before parsing begins.
256 */
257void
258bjobcode()
259{
260 struct caps *c;
261
262 printf(" NAME gurka.c\n"); /* Don't have the name */
263 for (c = caps; c->cap; c++)
264 printf(" RTMODEL \"%s\", \"%s\"\n", c->cap, c->stat);
265 //printf(" RSEG CODE:CODE:REORDER:NOROOT(0)\n");
266}
267
268/* called just before final exit */
269/* flag is 1 if errors, 0 if none */
270void
271ejobcode(int flag )
272{
273 struct symlst *w = sympole;
274
275 for (w = sympole; w; w = w->next) {
276 if (w->sp->sclass != EXTERN)
277 continue;
278 printf(" EXTERN %s\n", w->sp->soname);
279 }
280
281 printf(" END\n");
282}
283
284/*
285 * Print character t at position i in one string, until t == -1.
286 * Locctr & label is already defined.
287 */
288void
289bycode(int t, int i)
290{
291 static int lastoctal = 0;
292
293 /* put byte i+1 in a string */
294
295 if (t < 0) {
296 if (i != 0)
297 puts("\"");
298 } else {
299 if (i == 0)
300 printf("\t.ascii \"");
301 if (t == '\\' || t == '"') {
302 lastoctal = 0;
303 putchar('\\');
304 putchar(t);
305 } else if (t < 040 || t >= 0177) {
306 lastoctal++;
307 printf("\\%o",t);
308 } else if (lastoctal && '0' <= t && t <= '9') {
309 lastoctal = 0;
310 printf("\"\n\t.ascii \"%c", t);
311 } else {
312 lastoctal = 0;
313 putchar(t);
314 }
315 }
316}
317
318/*
319 * return the alignment of field of type t
320 */
321int
322fldal(unsigned int t)
323{
324 uerror("illegal field type");
325 return(ALINT);
326}
327
328/* fix up type of field p */
329void
330fldty(struct symtab *p)
331{
332}
333
334/*
335 * XXX - fix genswitch.
336 */
337int
338mygenswitch(int num, TWORD type, struct swents **p, int n)
339{
340 return 0;
341}
342/*
343 * Called with a function call with arguments as argument.
344 * This is done early in buildtree() and only done once.
345 */
346NODE *
347funcode(NODE *p)
348{
349 return p;
350}
Note: See TracBrowser for help on using the repository browser.