Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20090522121959

Diff

Diff from 1.6 to:

Annotations

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

Annotated File View

ragge
1.6
1 /*      $Id: code.c,v 1.6 2009/05/22 12:19:59 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
ragge
1.6
103 #if 0
104 /*
105  * AMD64 parameter classification.
106  */
107 classify(NODE *p)
108 {
109         TWORD t = p->n_type;
110         int cl = 0;
111
112         if (t <= ULONGLONG) {
113                 cl = INTEGER;
114         } else if (t == FLOAT || t == DOUBLE) {
115                 cl = SSE;
116         } else if (t == LDOUBLE) {
117                 cl = LDB;
118         } else if (t == STRTY) {
119                 if (tsize(tp->n_dfp->n_sue) > 4*SZLONG)
120                         cl = MEM;
121                 else
122                         cerror("clasif");
123         } else
124                 cerror("FIXME: classify");
125         return cl;
126 }
127 #endif
128
mickey
1.1
129 /*
130  * code for the end of a function
131  * deals with struct return here
132  */
133 void
134 efcode()
135 {
136         extern int gotnr;
137         NODE *p, *q;
138
139         gotnr = 0;      /* new number for next fun */
140         if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
141                 return;
142         /* Create struct assignment */
143         q = block(OREGNILNILPTR+STRTY0cftnsp->ssue);
ragge
1.5
144         q->n_rval = RBP;
mickey
1.1
145         q->n_lval = 8/* return buffer offset */
146         q = buildtree(UMULqNIL);
147         p = block(REGNILNILPTR+STRTY0cftnsp->ssue);
148         p = buildtree(UMULpNIL);
149         p = buildtree(ASSIGNqp);
150         ecomp(p);
151 }
152
153 /*
154  * code for the beginning of a function; a is an array of
155  * indices in symtab for the arguments; n is the number
156  */
157 void
gmcgarry
1.4
158 bfcode(struct symtab **spint cnt)
mickey
1.1
159 {
160         extern int gotnr;
gmcgarry
1.4
161         NODE *n, *p, *q;
162         int ik;
mickey
1.1
163
164         if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
165                 /* Function returns struct, adjust arg offset */
166                 for (i = 0i < cnti++) 
167                         sp[i]->soffset += SZPOINT(LONG);
168         }
169
170         if (kflag) {
171                 /* Put ebx in temporary */
172                 n = block(REGNILNILINT0MKSUE(INT));
ragge
1.5
173                 n->n_rval = RBX;
mickey
1.1
174                 p = tempnode(0INT0MKSUE(INT));
175                 gotnr = regno(p);
176                 ecomp(buildtree(ASSIGNpn));
177         }
178
179         /* recalculate the arg offset and create TEMP moves */
gmcgarry
1.4
180         for (k = 0i = 0i < cnti++) {
mickey
1.1
181
gmcgarry
1.4
182                 if (sp[i] == NULL)
183                         continue;
184
185                 if (k < 6) {
186                         p = tempnode(0sp[i]->stypesp[i]->sdfsp[i]->ssue);
187                         q = block(REGNILNILsp[i]->stypesp[i]->sdfsp[i]->ssue);
188                         q->n_rval = argreg(sp[i]->stype, &k);
mickey
1.1
189                         p = buildtree(ASSIGNpq);
gmcgarry
1.4
190                         sp[i]->soffset = regno(p->n_left);
191                         sp[i]->sflags |= STNODE;
mickey
1.1
192                         ecomp(p);
193                 } else {
gmcgarry
1.4
194                         sp[i]->soffset += SZLONG * k;
mickey
1.1
195                         if (xtemps) {
196                                 /* put stack args in temps if optimizing */
gmcgarry
1.4
197                                 p = tempnode(0sp[i]->stypesp[i]->sdfsp[i]->ssue);
mickey
1.1
198                                 p = buildtree(ASSIGNpbuildtree(NAME00));
gmcgarry
1.4
199                                 sp[i]->soffset = regno(p->n_left);
200                                 sp[i]->sflags |= STNODE;
mickey
1.1
201                                 ecomp(p);
202                         }
203                 }
204         }
205 }
206
207
208 /*
209  * by now, the automatics and register variables are allocated
210  */
211 void
212 bccode()
213 {
214         SETOFF(autooffSZINT);
215 }
216
217 /* called just before final exit */
218 /* flag is 1 if errors, 0 if none */
219 void
220 ejobcode(int flag )
221 {
222 #define _MKSTR(x) #x
223 #define MKSTR(x) _MKSTR(x)
224 #define OS MKSTR(TARGOS)
225         printf("\t.ident \"PCC: %s (%s)\"\n\t.end\n"PACKAGE_STRINGOS);
226 }
227
228 void
229 bjobcode()
230 {
231 }
232
233 static const int argregsi[] = { RDIRSIRDXRCXR09R08 };
234
235 int
236 argreg(TWORD tint *n)   
237 {
238         switch (t) {
239         case FLOAT:
240         case DOUBLE:
241         case LDOUBLE:
gmcgarry
1.4
242                 /* return FR6 - *n - 2; */
243                 cerror("argreg");
244                 return 0;
mickey
1.1
245         case LONGLONG:
246         case ULONGLONG:
247                 /* TODO */;
248         default:
249                 return argregsi[(*n)++];
250         }
251 }
252
253 NODE *
254 funarg(NODE *pint *n)
255 {
256         NODE *r;
257
258         if (p->n_op == CM) {
259                 p->n_left = funarg(p->n_leftn);
260                 p->n_right = funarg(p->n_rightn);
261                 return p;
262         }
263
264         if (*n >= 6) {
ragge
1.6
265                 (*n)++;
mickey
1.1
266                 r = block(OREGNILNILp->n_type|PTR0,
267                     MKSUE(p->n_type|PTR));
268                 r->n_rval = RBP;
269                 r->n_lval = 16 + (*n - 6) * 8;
270         } else {
271                 r = block(REGNILNILp->n_type00);
272                 r->n_lval = 0;
273                 r->n_rval = argreg(p->n_typen);
274         }
275         p = block(ASSIGNrpp->n_type00);
276         clocal(p);
277
278         return p;
279 }  
280
281 /*
282  * Called with a function call with arguments as argument.
283  * This is done early in buildtree() and only done once.
284  * Returns p.
285  */
286 NODE *
287 funcode(NODE *p)
288 {
289         extern int gotnr;
290         NODE *r, *l;
291         int n = 0;
292
293         p->n_right = funarg(p->n_right, &n);
294
ragge
1.6
295         /* clear al at the end if varargs.  Do it always for now. */
296         l = block(REGNILNILINT0MKSUE(INT));
297         l->n_rval = RAX;
298         l = buildtree(ASSIGNlbcon(0));
299         if (p->n_right->n_op != CM) {
300                 p->n_right = block(CMlp->n_rightINT0MKSUE(INT));
301         } else {
302                 for (r = p->n_rightr->n_left->n_op == CMr = r->n_left)
303                         ;
304                 r->n_left = block(CMlr->n_leftINT0MKSUE(INT));
305         }
306
mickey
1.1
307         if (kflag == 0)
308                 return p;
309         /* Create an ASSIGN node for ebx */
310         l = block(REGNILNILINT0MKSUE(INT));
ragge
1.5
311         l->n_rval = RBX;
mickey
1.1
312         l = buildtree(ASSIGNltempnode(gotnrINT0MKSUE(INT)));
313         if (p->n_right->n_op != CM) {
314                 p->n_right = block(CMlp->n_rightINT0MKSUE(INT));
315         } else {
316                 for (r = p->n_rightr->n_left->n_op == CMr = r->n_left)
317                         ;
318                 r->n_left = block(CMlr->n_leftINT0MKSUE(INT));
319         }
320         return p;
321 }
322
323 /*
324  * return the alignment of field of type t
325  */
326 int
327 fldal(unsigned int t)
328 {
329         uerror("illegal field type");
330         return(ALINT);
331 }
332
333 /* fix up type of field p */
334 void
335 fldty(struct symtab *p)
336 {
337 }
338
339 /*
340  * XXX - fix genswitch.
341  */
342 int
343 mygenswitch(int numTWORD typestruct swents **pint n)
344 {
345         return 0;
346 }
FishEye: Open Source License registered to PCC.
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-12-18 06:48 +0100