Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20090524132013

Diff

Diff from 1.8 to:

Annotations

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

Annotated File View

ragge
1.8
1 /*      $Id: code.c,v 1.8 2009/05/24 13:20:13 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
ragge
1.8
33 static int nssengpr;
34 enum { INTEGER = 1INTMEMSSESSEMEMX87STRREGSTRMEM };
35 static const int argregsi[] = { RDIRSIRDXRCXR09R08 };
mickey
1.1
36
37 int lastloc = -1;
38
ragge
1.8
39 static int argtyp(TWORD tunion dimfun *dfstruct suedef *sue);
40
mickey
1.1
41 /*
42  * Define everything needed to print out some data (or text).
43  * This means segment, alignment, visibility, etc.
44  */
45 void
46 defloc(struct symtab *sp)
47 {
48         extern char *nextsect;
49         static char *loctbl[] = { "text""data""section .rodata" };
ragge
1.6
50         int weak = 0;
51         char *name = NULL;
mickey
1.1
52         TWORD t;
53         int s;
54
55         if (sp == NULL) {
56                 lastloc = -1;
57                 return;
58         }
59         t = sp->stype;
60         s = ISFTN(t) ? PROG : ISCON(cqual(tsp->squal)) ? RDATA : DATA;
61 #ifdef TLS
62         if (sp->sflags & STLS) {
63                 if (s != DATA)
64                         cerror("non-data symbol in tls section");
65                 nextsect = ".tdata";
66         }
67 #endif
ragge
1.6
68 #ifdef GCC_COMPAT
69         {
70                 struct gcc_attrib *ga;
71
72                 if ((ga = gcc_get_attr(sp->ssueGCC_ATYP_SECTION)) != NULL)
73                         nextsect = ga->a1.sarg;
74                 if ((ga = gcc_get_attr(sp->ssueGCC_ATYP_WEAK)) != NULL)
75                         weak = 1;
76         }
77 #endif
78
mickey
1.1
79         if (nextsect) {
80                 printf("        .section %s\n"nextsect);
81                 nextsect = NULL;
82                 s = -1;
83         } else if (s != lastloc)
84                 printf("        .%s\n"loctbl[s]);
85         lastloc = s;
86         while (ISARY(t))
87                 t = DECREF(t);
ragge
1.3
88         s = ISFTN(t) ? ALINT : talign(tsp->ssue);
89         if (s > ALCHAR)
90                 printf("        .align %d\n"s/ALCHAR);
ragge
1.6
91         if (weak || sp->sclass == EXTDEF || sp->slevel == 0 || ISFTN(t))
92                 if ((name = sp->soname) == NULL)
93                         name = exname(sp->sname);
94         if (weak)
95                 printf("        .weak %s\n"name);
96         else if (sp->sclass == EXTDEF)
97                 printf("        .globl %s\n"name);
mickey
1.1
98         if (ISFTN(t))
ragge
1.6
99                 printf("\t.type %s,@function\n"name);
mickey
1.1
100         if (sp->slevel == 0)
ragge
1.6
101                 printf("%s:\n"name);
mickey
1.1
102         else
103                 printf(LABFMT ":\n"sp->soffset);
104 }
105
106 /*
107  * code for the end of a function
108  * deals with struct return here
109  */
110 void
111 efcode()
112 {
113         extern int gotnr;
114         NODE *p, *q;
115
116         gotnr = 0;      /* new number for next fun */
117         if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
118                 return;
119         /* Create struct assignment */
120         q = block(OREGNILNILPTR+STRTY0cftnsp->ssue);
ragge
1.5
121         q->n_rval = RBP;
mickey
1.1
122         q->n_lval = 8/* return buffer offset */
123         q = buildtree(UMULqNIL);
124         p = block(REGNILNILPTR+STRTY0cftnsp->ssue);
125         p = buildtree(UMULpNIL);
126         p = buildtree(ASSIGNqp);
127         ecomp(p);
128 }
129
130 /*
131  * code for the beginning of a function; a is an array of
132  * indices in symtab for the arguments; n is the number
133  */
134 void
ragge
1.8
135 bfcode(struct symtab **sint cnt)
mickey
1.1
136 {
ragge
1.8
137         struct symtab *sp;
138         NODE *p, *r;
139         int irnotyp;
mickey
1.1
140
141         if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
142                 /* Function returns struct, adjust arg offset */
143                 for (i = 0i < cnti++) 
ragge
1.8
144                         s[i]->soffset += SZPOINT(LONG);
mickey
1.1
145         }
146
147         /* recalculate the arg offset and create TEMP moves */
ragge
1.8
148         /* Always do this for reg, even if not optimizing, to free arg regs */
149         for (i = 0i < cnti++) {
150                 sp = s[i];
151
152                 if (sp == NULL)
153                         continue/* XXX when happens this? */
154
155                 switch (typ = argtyp(sp->stypesp->sdfsp->ssue)) {
156                 case INTEGER:
157                 case SSE:
158                         if (typ == SSE)
159                                 rno = XMM0 + nsse++;
160                         else
161                                 rno = argregsi[ngpr++];
162                         r = block(REGNILNILsp->stypesp->sdfsp->ssue);
163                         regno(r) = rno;
164                         p = tempnode(0sp->stypesp->sdfsp->ssue);
165                         sp->soffset = regno(p);
166                         sp->sflags |= STNODE;
167                         ecomp(buildtree(ASSIGNpr));
168                         break;
169                 default:
170                         cerror("bfcode");
mickey
1.1
171                 }
172         }
173 }
174
175
176 /*
177  * by now, the automatics and register variables are allocated
178  */
179 void
180 bccode()
181 {
182         SETOFF(autooffSZINT);
183 }
184
185 /* called just before final exit */
186 /* flag is 1 if errors, 0 if none */
187 void
188 ejobcode(int flag )
189 {
190 #define _MKSTR(x) #x
191 #define MKSTR(x) _MKSTR(x)
192 #define OS MKSTR(TARGOS)
193         printf("\t.ident \"PCC: %s (%s)\"\n\t.end\n"PACKAGE_STRINGOS);
194 }
195
196 void
197 bjobcode()
198 {
199 }
200
ragge
1.7
201 static NODE *
202 movtoreg(NODE *pint rno)
mickey
1.1
203 {
204         NODE *r;
205
ragge
1.7
206         r = block(REGNILNILp->n_type00);
207         regno(r) = rno;
208         return clocal(buildtree(ASSIGNrp));
209 }  
210
211
212 /*
213  * AMD64 parameter classification.
214  */
215 static int
ragge
1.8
216 argtyp(TWORD tunion dimfun *dfstruct suedef *sue)
ragge
1.7
217 {
218         int cl = 0;
219
220         if (t <= ULONG) {
221                 cl = ngpr < 6 ? INTEGER : INTMEM;
222         } else if (t == FLOAT || t == DOUBLE) {
ragge
1.8
223                 cl = nsse < 8 ? SSE : SSEMEM;
ragge
1.7
224         } else if (t == LDOUBLE) {
225                 cl = X87/* XXX */
226         } else if (t == STRTY) {
ragge
1.8
227                 if (tsize(tdfsue) > 4*SZLONG)
ragge
1.7
228                         cl = STRMEM;
229                 else
230                         cerror("clasif");
231         } else
232                 cerror("FIXME: classify");
233         return cl;
234 }
235
236 static void
237 argput(NODE *p)
238 {
239         NODE *q;
240         int typr;
mickey
1.1
241
ragge
1.7
242         /* first arg may be struct return pointer */
243         /* XXX - check if varargs; setup al */
ragge
1.8
244         switch (typ = argtyp(p->n_typep->n_dfp->n_sue)) {
ragge
1.7
245         case INTEGER:
246         case SSE:
247                 q = talloc();
248                 *q = *p;
249                 if (typ == SSE)
250                         r = XMM0 + nsse++;
251                 else
252                         r = argregsi[ngpr++];
253                 q = movtoreg(qr);
254                 *p = *q;
255                 nfree(q);
256                 break;
257         case X87:
258                 cerror("no long double yet");
259                 break;
260         case STRMEM:
261                 /* Struct moved to memory */
262         case STRREG:
263                 /* Struct in registers */
264         default:
265                 cerror("struct argument");
mickey
1.1
266         }
ragge
1.7
267 }
mickey
1.1
268
269
270 /*
271  * Called with a function call with arguments as argument.
272  * This is done early in buildtree() and only done once.
273  * Returns p.
274  */
275 NODE *
276 funcode(NODE *p)
277 {
ragge
1.8
278         NODE *l, *r;
mickey
1.1
279
ragge
1.7
280         nsse = ngpr = 0;
281         listf(p->n_rightargput);
ragge
1.8
282
283         /* Always emit number of SSE regs used */
284         l = movtoreg(bcon(nsse), RAX);
285         if (p->n_right->n_op != CM) {
286                 p->n_right = block(CMlp->n_rightINT0MKSUE(INT));
287         } else {
288                 for (r = p->n_rightr->n_left->n_op == CMr = r->n_left)
289                         ;
290                 r->n_left = block(CMlr->n_leftINT0MKSUE(INT));
291         }
mickey
1.1
292         return p;
293 }
294
295 /*
296  * return the alignment of field of type t
297  */
298 int
299 fldal(unsigned int t)
300 {
301         uerror("illegal field type");
302         return(ALINT);
303 }
304
305 /* fix up type of field p */
306 void
307 fldty(struct symtab *p)
308 {
309 }
310
311 /*
312  * XXX - fix genswitch.
313  */
314 int
315 mygenswitch(int numTWORD typestruct swents **pint n)
316 {
317         return 0;
318 }
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-03 06:56 +0200