Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20090524084331

Diff

Diff from 1.7 to:

Annotations

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

Annotated File View

ragge
1.7
1 /*      $Id: code.c,v 1.7 2009/05/24 08:43:31 ragge Exp $       */
mickey
1.1
2 /*
3  * Copyright (c) 2008 Michael Shalayeff
4  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30
31 # include "pass1.h"
32
33 NODE *funarg(NODE *, int *);
34 int argreg(TWORDint *);
35
36 int lastloc = -1;
37
38 /*
39  * Define everything needed to print out some data (or text).
40  * This means segment, alignment, visibility, etc.
41  */
42 void
43 defloc(struct symtab *sp)
44 {
45         extern char *nextsect;
46         static char *loctbl[] = { "text""data""section .rodata" };
ragge
1.6
47         int weak = 0;
48         char *name = NULL;
mickey
1.1
49         TWORD t;
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(tsp->squal)) ? RDATA : DATA;
58 #ifdef TLS
59         if (sp->sflags & STLS) {
60                 if (s != DATA)
61                         cerror("non-data symbol in tls section");
62                 nextsect = ".tdata";
63         }
64 #endif
ragge
1.6
65 #ifdef GCC_COMPAT
66         {
67                 struct gcc_attrib *ga;
68
69                 if ((ga = gcc_get_attr(sp->ssueGCC_ATYP_SECTION)) != NULL)
70                         nextsect = ga->a1.sarg;
71                 if ((ga = gcc_get_attr(sp->ssueGCC_ATYP_WEAK)) != NULL)
72                         weak = 1;
73         }
74 #endif
75
mickey
1.1
76         if (nextsect) {
77                 printf("        .section %s\n"nextsect);
78                 nextsect = NULL;
79                 s = -1;
80         } else if (s != lastloc)
81                 printf("        .%s\n"loctbl[s]);
82         lastloc = s;
83         while (ISARY(t))
84                 t = DECREF(t);
ragge
1.3
85         s = ISFTN(t) ? ALINT : talign(tsp->ssue);
86         if (s > ALCHAR)
87                 printf("        .align %d\n"s/ALCHAR);
ragge
1.6
88         if (weak || sp->sclass == EXTDEF || sp->slevel == 0 || ISFTN(t))
89                 if ((name = sp->soname) == NULL)
90                         name = exname(sp->sname);
91         if (weak)
92                 printf("        .weak %s\n"name);
93         else if (sp->sclass == EXTDEF)
94                 printf("        .globl %s\n"name);
mickey
1.1
95         if (ISFTN(t))
ragge
1.6
96                 printf("\t.type %s,@function\n"name);
mickey
1.1
97         if (sp->slevel == 0)
ragge
1.6
98                 printf("%s:\n"name);
mickey
1.1
99         else
100                 printf(LABFMT ":\n"sp->soffset);
101 }
102
103 /*
104  * code for the end of a function
105  * deals with struct return here
106  */
107 void
108 efcode()
109 {
110         extern int gotnr;
111         NODE *p, *q;
112
113         gotnr = 0;      /* new number for next fun */
114         if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
115                 return;
116         /* Create struct assignment */
117         q = block(OREGNILNILPTR+STRTY0cftnsp->ssue);
ragge
1.5
118         q->n_rval = RBP;
mickey
1.1
119         q->n_lval = 8/* return buffer offset */
120         q = buildtree(UMULqNIL);
121         p = block(REGNILNILPTR+STRTY0cftnsp->ssue);
122         p = buildtree(UMULpNIL);
123         p = buildtree(ASSIGNqp);
124         ecomp(p);
125 }
126
127 /*
128  * code for the beginning of a function; a is an array of
129  * indices in symtab for the arguments; n is the number
130  */
131 void
gmcgarry
1.4
132 bfcode(struct symtab **spint cnt)
mickey
1.1
133 {
134         extern int gotnr;
gmcgarry
1.4
135         NODE *n, *p, *q;
136         int ik;
mickey
1.1
137
138         if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
139                 /* Function returns struct, adjust arg offset */
140                 for (i = 0i < cnti++) 
141                         sp[i]->soffset += SZPOINT(LONG);
142         }
143
144         if (kflag) {
145                 /* Put ebx in temporary */
146                 n = block(REGNILNILINT0MKSUE(INT));
ragge
1.5
147                 n->n_rval = RBX;
mickey
1.1
148                 p = tempnode(0INT0MKSUE(INT));
149                 gotnr = regno(p);
150                 ecomp(buildtree(ASSIGNpn));
151         }
152
153         /* recalculate the arg offset and create TEMP moves */
gmcgarry
1.4
154         for (k = 0i = 0i < cnti++) {
mickey
1.1
155
gmcgarry
1.4
156                 if (sp[i] == NULL)
157                         continue;
158
159                 if (k < 6) {
160                         p = tempnode(0sp[i]->stypesp[i]->sdfsp[i]->ssue);
161                         q = block(REGNILNILsp[i]->stypesp[i]->sdfsp[i]->ssue);
162                         q->n_rval = argreg(sp[i]->stype, &k);
mickey
1.1
163                         p = buildtree(ASSIGNpq);
gmcgarry
1.4
164                         sp[i]->soffset = regno(p->n_left);
165                         sp[i]->sflags |= STNODE;
mickey
1.1
166                         ecomp(p);
167                 } else {
gmcgarry
1.4
168                         sp[i]->soffset += SZLONG * k;
mickey
1.1
169                         if (xtemps) {
170                                 /* put stack args in temps if optimizing */
gmcgarry
1.4
171                                 p = tempnode(0sp[i]->stypesp[i]->sdfsp[i]->ssue);
mickey
1.1
172                                 p = buildtree(ASSIGNpbuildtree(NAME00));
gmcgarry
1.4
173                                 sp[i]->soffset = regno(p->n_left);
174                                 sp[i]->sflags |= STNODE;
mickey
1.1
175                                 ecomp(p);
176                         }
177                 }
178         }
179 }
180
181
182 /*
183  * by now, the automatics and register variables are allocated
184  */
185 void
186 bccode()
187 {
188         SETOFF(autooffSZINT);
189 }
190
191 /* called just before final exit */
192 /* flag is 1 if errors, 0 if none */
193 void
194 ejobcode(int flag )
195 {
196 #define _MKSTR(x) #x
197 #define MKSTR(x) _MKSTR(x)
198 #define OS MKSTR(TARGOS)
199         printf("\t.ident \"PCC: %s (%s)\"\n\t.end\n"PACKAGE_STRINGOS);
200 }
201
202 void
203 bjobcode()
204 {
205 }
206
207 static const int argregsi[] = { RDIRSIRDXRCXR09R08 };
208
209 int
210 argreg(TWORD tint *n)   
211 {
212         switch (t) {
213         case FLOAT:
214         case DOUBLE:
215         case LDOUBLE:
gmcgarry
1.4
216                 /* return FR6 - *n - 2; */
217                 cerror("argreg");
218                 return 0;
mickey
1.1
219         case LONGLONG:
220         case ULONGLONG:
221                 /* TODO */;
222         default:
223                 return argregsi[(*n)++];
224         }
225 }
226
ragge
1.7
227 static NODE *
228 movtoreg(NODE *pint rno)
mickey
1.1
229 {
230         NODE *r;
231
ragge
1.7
232         r = block(REGNILNILp->n_type00);
233         regno(r) = rno;
234         return clocal(buildtree(ASSIGNrp));
235 }  
236
237 static int nssengpr;
238 enum { INTEGER = 1INTMEMSSESSEMEMX87STRREGSTRMEM };
239
240 /*
241  * AMD64 parameter classification.
242  */
243 static int
244 argtyp(NODE *p)
245 {
246         TWORD t = p->n_type;
247         int cl = 0;
248
249         if (t <= ULONG) {
250                 cl = ngpr < 6 ? INTEGER : INTMEM;
251         } else if (t == FLOAT || t == DOUBLE) {
252                 cl = nsse < 4 ? SSE : SSEMEM;
253         } else if (t == LDOUBLE) {
254                 cl = X87/* XXX */
255         } else if (t == STRTY) {
256                 if (tsize(tp->n_dfp->n_sue) > 4*SZLONG)
257                         cl = STRMEM;
258                 else
259                         cerror("clasif");
260         } else
261                 cerror("FIXME: classify");
262         return cl;
263 }
264
265 static void
266 argput(NODE *p)
267 {
268         NODE *q;
269         int typr;
mickey
1.1
270
ragge
1.7
271         /* first arg may be struct return pointer */
272         /* XXX - check if varargs; setup al */
273         switch (typ = argtyp(p)) {
274         case INTEGER:
275         case SSE:
276                 q = talloc();
277                 *q = *p;
278                 if (typ == SSE)
279                         r = XMM0 + nsse++;
280                 else
281                         r = argregsi[ngpr++];
282                 q = movtoreg(qr);
283                 *p = *q;
284                 nfree(q);
285                 break;
286         case X87:
287                 cerror("no long double yet");
288                 break;
289         case STRMEM:
290                 /* Struct moved to memory */
291         case STRREG:
292                 /* Struct in registers */
293         default:
294                 cerror("struct argument");
mickey
1.1
295         }
ragge
1.7
296 }
mickey
1.1
297
298
299 /*
300  * Called with a function call with arguments as argument.
301  * This is done early in buildtree() and only done once.
302  * Returns p.
303  */
304 NODE *
305 funcode(NODE *p)
306 {
307
ragge
1.7
308         nsse = ngpr = 0;
309         listf(p->n_rightargput);
mickey
1.1
310         return p;
311 }
312
313 /*
314  * return the alignment of field of type t
315  */
316 int
317 fldal(unsigned int t)
318 {
319         uerror("illegal field type");
320         return(ALINT);
321 }
322
323 /* fix up type of field p */
324 void
325 fldty(struct symtab *p)
326 {
327 }
328
329 /*
330  * XXX - fix genswitch.
331  */
332 int
333 mygenswitch(int numTWORD typestruct swents **pint n)
334 {
335         return 0;
336 }
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-10-31 23:57 +0100