Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:gmcgarry:20071128022353

Diff

Diff from 1.7 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/arch/mips/code.c

Annotated File View

gmcgarry
1.7
1 /*      $Id: code.c,v 1.7 2007/11/28 02:23:53 gmcgarry Exp $    */
ragge
1.1
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 /*
31  * MIPS port by Jan Enoksson (janeno-1@student.ltu.se) and
32  * Simon Olsson (simols-1@student.ltu.se) 2005.
33  */
34
gmcgarry
1.7
35 #include <assert.h>
36 #include "pass1.h"
ragge
1.1
37
38 /*
39  * cause the alignment to become a multiple of n
40  * never called for text segment.
41  */
42 void
43 defalign(int n)
44 {
45         n /= SZCHAR;
46         if (n == 1)
47                 return;
gmcgarry
1.4
48         printf("\t.align %d\n"n);
ragge
1.1
49 }
50
51 /*
52  * define the current location as the name p->sname
53  * never called for text segment.
54  */
55 void
56 defnam(struct symtab *p)
57 {
58         char *c = p->sname;
59
60 #ifdef GCC_COMPAT
61         c = gcc_findname(p);
62 #endif
63         if (p->sclass == EXTDEF)
gmcgarry
1.4
64                 printf("\t.globl %s\n"c);
65 #ifdef USE_GAS
66         printf("\t.type %s,@object\n"c);
67         printf("\t.size %s," CONFMT "\n"ctsize(p->stypep->sdfp->ssue));
68 #endif
ragge
1.1
69         printf("%s:\n"c);
70 }
71
gmcgarry
1.7
72 static int rvnr;
73
ragge
1.1
74 /*
75  * code for the end of a function
76  * deals with struct return here
77  */
78 void
79 efcode()
80 {
gmcgarry
1.7
81         NODE *p, *q;
82         int tempnr;
83         int ty;
84
ragge
1.1
85         if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
86                 return;
gmcgarry
1.7
87
88         ty = cftnsp->stype - FTN;
89
90         q = block(REGNILNILINCREF(ty), 0cftnsp->ssue);
91         q->n_rval = V0;
92         p = tempnode(0INCREF(ty), 0cftnsp->ssue);
93         tempnr = p->n_lval;
94         p = buildtree(ASSIGNpq);
95         ecomp(p);
96
97         q = tempnode(tempnrINCREF(ty), 0cftnsp->ssue);
98         q = buildtree(UMULqNIL);
99
100         p = tempnode(rvnrINCREF(ty), 0cftnsp->ssue);
101         p = buildtree(UMULpNIL);
102
103         p = buildtree(ASSIGNpq);
104         ecomp(p);
105
106         q = tempnode(rvnrINCREF(ty), 0cftnsp->ssue);
107         p = block(REGNILNILINCREF(ty), 0cftnsp->ssue);
108         p->n_rval = V0;
109         p = buildtree(ASSIGNpq);
110         ecomp(p);
ragge
1.1
111 }
112
113 /*
114  * code for the beginning of a function; a is an array of
115  * indices in symtab for the arguments; n is the number
116  */
117 void
gmcgarry
1.4
118 bfcode(struct symtab **spint cnt)
ragge
1.1
119 {
gmcgarry
1.4
120         NODE *p, *q;
gmcgarry
1.7
121         int instart = 0;
122         int sztsz;
ragge
1.1
123
gmcgarry
1.7
124         /* assign hidden return structure to temporary */
ragge
1.1
125         if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
gmcgarry
1.7
126                 p = tempnode(0PTR+STRTY0cftnsp->ssue);
127                 rvnr = p->n_lval;
128                 q = block(REGNILNILPTR+STRTY0cftnsp->ssue);
129                 q->n_rval = A0 + start++;
130                 p = buildtree(ASSIGNpq);
131                 ecomp(p);
ragge
1.1
132         }
133
gmcgarry
1.4
134         /* recalculate the arg offset and create TEMP moves */
gmcgarry
1.7
135         for (n = starti = 0i < cnti++) {
136
137                 sz = tsize(sp[i]->stypesp[i]->sdfsp[i]->ssue) / SZINT;
138
139                 /* A structure argument */
140                 if (n < nargregs &&
141                     (sp[i]->stype == STRTY || sp[i]->stype == UNIONTY)) {
142                         tsz = sz > nargregs - n ? nargregs - n : sz;
143                         spname = sp[i];
144                         for (i = 0i < tszi++) {
145                                 q = block(REGNILNILINT0MKSUE(INT));
146                                 q->n_rval = A0 + n + i;
147                                 p = block(REGNILNILINT0MKSUE(INT));
148                                 p->n_rval = FP;
149                                 p = block(PLUSpbcon(ARGINIT/SZCHAR+(n+i)*4),
150                                     INT0MKSUE(INT));
151                                 p = block(UMULpNILINT0MKSUE(INT));
152                                 p = buildtree(ASSIGNpq);
153                                 ecomp(p);
154                         }
155                 } else if (n + sz <= nargregs) {
gmcgarry
1.4
156                         if (xtemps) {
157                                 p = tempnode(0sp[i]->stype,
158                                     sp[i]->sdfsp[i]->ssue);
159                                 spname = sp[i];
160                                 q = block(REGNILNIL,
161                                     sp[i]->stypesp[i]->sdfsp[i]->ssue);
gmcgarry
1.6
162                                 q->n_rval = sz == 2 ? A0A1 + n : A0 + n;
gmcgarry
1.4
163                                 p = buildtree(ASSIGNpq);
164                                 sp[i]->soffset = p->n_left->n_lval;
165                                 sp[i]->sflags |= STNODE;
166                         } else {
167                                 // sp[i]->soffset += ARGINIT;
168                                 spname = sp[i];
169                                 q = block(REGNILNIL,
170                                     sp[i]->stypesp[i]->sdfsp[i]->ssue);
gmcgarry
1.6
171                                 q->n_rval = sz == 2 ? A0A1 + n : A0 + n;
gmcgarry
1.4
172                                 p = buildtree(ASSIGNbuildtree(NAME00), q);
173                         }
174                         ecomp(p);
175                 } else {
176                         // sp[i]->soffset += ARGINIT;
177                         if (xtemps) {
178                                 /* put stack args in temps if optimizing */
179                                 spname = sp[i];
180                                 p = tempnode(0sp[i]->stype,
181                                     sp[i]->sdfsp[i]->ssue);
182                                 p = buildtree(ASSIGNpbuildtree(NAME00));
183                                 sp[i]->soffset = p->n_left->n_lval;
184                                 sp[i]->sflags |= STNODE;
185                                 ecomp(p);
186                         }
187                 
188                 }
gmcgarry
1.7
189                 n += sz;
gmcgarry
1.4
190         }
ragge
1.1
191
192 }
193
194
195 /*
196  * by now, the automatics and register variables are allocated
197  */
198 void
199 bccode()
200 {
201         SETOFF(autooffSZINT);
202 }
203
204 /* called just before final exit */
205 /* flag is 1 if errors, 0 if none */
206 void
207 ejobcode(int flag )
208 {
209 }
210
211 void
212 bjobcode()
213 {
gmcgarry
1.7
214         printf("\t.section .mdebug.abi32\n");
215         printf("\t.previous\n");
216         printf("\t.abicalls\n");
ragge
1.1
217 }
218
219 /*
220  * Print character t at position i in one string, until t == -1.
221  * Locctr & label is already defined.
222  */
223 void
224 bycode(int tint i)
225 {
gmcgarry
1.2
226         static int lastoctal = 0;
ragge
1.1
227
228         /* put byte i+1 in a string */
229
230         if (t < 0) {
231                 if (i != 0)
232                         puts("\"");
233         } else {
234                 if (i == 0)
gmcgarry
1.2
235                         printf("\t.asciiz \"");
236                 if (t == 0)
237                         return;
238                 else if (t == '\\' || t == '"') {
ragge
1.1
239                         lastoctal = 0;
240                         putchar('\\');
241                         putchar(t);
gmcgarry
1.2
242                 } else if (t == 012) {
243                         printf("\\n");
ragge
1.1
244                 } else if (t < 040 || t >= 0177) {
245                         lastoctal++;
246                         printf("\\%o",t);
247                 } else if (lastoctal && '0' <= t && t <= '9') {
248                         lastoctal = 0;
gmcgarry
1.2
249                         printf("\"\n\t.asciiz \"%c"t);
ragge
1.1
250                 } else {        
251                         lastoctal = 0;
252                         putchar(t);
253                 }
254         }
255 }
256
257 /*
258  * return the alignment of field of type t
259  */
260 int
261 fldal(unsigned int t)
262 {
263         uerror("illegal field type");
264         return(ALINT);
265 }
266
267 /* fix up type of field p */
268 void
269 fldty(struct symtab *p)
270 {
271 }
272
stefan
1.5
273 /*
ragge
1.1
274  * XXX - fix genswitch.
275  */
stefan
1.5
276 int
277 mygenswitch(int numTWORD typestruct swents **pint n)
ragge
1.1
278 {
stefan
1.5
279         return 0;
ragge
1.1
280 }
gmcgarry
1.4
281
282 static void
gmcgarry
1.7
283 moveargs(NODE **pint *regp)
gmcgarry
1.4
284 {
gmcgarry
1.7
285         NODE *r = *p;
286         NODE *t, *q;
287         int sztszn;
gmcgarry
1.4
288         int regnum;
289
290         if (r->n_op == CM) {
291                 moveargs(&r->n_leftregp);
gmcgarry
1.7
292                 p = &r->n_right;
gmcgarry
1.4
293                 r = r->n_right;
294         }
295
296         regnum = *regp;
gmcgarry
1.7
297         sz = tsize(r->n_typer->n_dfr->n_sue) / SZINT;
gmcgarry
1.4
298
gmcgarry
1.7
299         if (regnum <= A0 + nargregs && r->n_type == STRTY) {
300                 /* copy structure into registers */
301                 n = regnum - A0;
302                 tsz = sz > nargregs - n ? nargregs - n : sz;
303                 printf("[should copy %d words into registers]\n"tsz);
304
305                 while (tsz > 0) {
306                         q = block(REGNILNILINT0MKSUE(INT));
307                         q->n_rval = regnum + tsz;
308                         q = buildtree(ASSIGNqr);
309                         r = block(CMqNILINT0MKSUE(INT));
310                         tsz--;
311                 }
312                 t = r;
313
314         } else if (regnum + sz <= A0 + nargregs) {
gmcgarry
1.4
315                 t = block(REGNILNILr->n_typer->n_dfr->n_sue);
gmcgarry
1.6
316                 switch(r->n_type) {
317                 case DOUBLE:
318                 case LDOUBLE:
319                         t->n_rval = regnum + F0;
320                         break;
321                 case LONGLONG:
322                 case ULONGLONG:
323                         t->n_rval = regnum + A0A1;
324                         break;
325                 default:
326                         t->n_rval = regnum;
327                 }
gmcgarry
1.4
328                 t = buildtree(ASSIGNtr);
329         } else {
gmcgarry
1.7
330                 if (r->n_op == STARG)
331                         t = r;
332                 else
333                         t = block(FUNARGrNILr->n_typer->n_dfr->n_sue);
334         }
gmcgarry
1.4
335
gmcgarry
1.7
336         *p = t;
337         *regp += sz;
gmcgarry
1.4
338 }
339
ragge
1.3
340 /*
341  * Called with a function call with arguments as argument.
342  * This is done early in buildtree() and only done once.
343  */
344 NODE *
345 funcode(NODE *p)
346 {
gmcgarry
1.4
347         int regnum = A0;
gmcgarry
1.7
348         NODE *l, *r, *t, *q;
349         int ty;
350
351         l = p->n_left;
352         r = p->n_right;
353
354         ty = DECREF(l->n_type);
355         if (ty == STRTY+FTN || ty == UNIONTY+FTN) {
356                 ty = DECREF(l->n_type) - FTN;
357                 q = tempnode(0tyl->n_dfl->n_sue);
358                 q = buildtree(ADDROFqNIL);
359                 if (r->n_op != CM) {
360                         p->n_right = block(CMqrINCREF(ty),
361                             l->n_dfl->n_sue);
362                 } else {
363                         for (t = rt->n_left->n_op == CMt = t->n_left)
364                                 ;
365                         t->n_left = block(CMqt->n_leftINCREF(ty),
366                             l->n_dfl->n_sue);
367                 }
368         }
369
gmcgarry
1.4
370         moveargs(&p->n_right, &regnum);
ragge
1.3
371         return p;
372 }
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-09-02 16:04 +0200