Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20090530153516

Diff

Diff from 1.10 to:

Annotations

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

Annotated File View

ragge
1.10
1 /*      $Id: code.c,v 1.10 2009/05/30 15:35:16 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.9
33 static int nssengprnrsp;
ragge
1.8
34 enum { INTEGER = 1INTMEMSSESSEMEMX87STRREGSTRMEM };
ragge
1.10
35 static const int argregsi[] = { RDIRSIRDXRCXR08R09 };
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 */
ragge
1.9
149         nsse = ngpr = 0;
150         nrsp = ARGINIT;
ragge
1.8
151         for (i = 0i < cnti++) {
152                 sp = s[i];
153
154                 if (sp == NULL)
155                         continue/* XXX when happens this? */
156
157                 switch (typ = argtyp(sp->stypesp->sdfsp->ssue)) {
158                 case INTEGER:
159                 case SSE:
160                         if (typ == SSE)
161                                 rno = XMM0 + nsse++;
162                         else
163                                 rno = argregsi[ngpr++];
164                         r = block(REGNILNILsp->stypesp->sdfsp->ssue);
165                         regno(r) = rno;
166                         p = tempnode(0sp->stypesp->sdfsp->ssue);
167                         sp->soffset = regno(p);
168                         sp->sflags |= STNODE;
169                         ecomp(buildtree(ASSIGNpr));
170                         break;
ragge
1.9
171
172                 case INTMEM:
173                         sp->soffset = nrsp;
174                         nrsp += SZLONG;
175                         if (xtemps) {
176                                 p = tempnode(0sp->stypesp->sdfsp->ssue);
177                                 p = buildtree(ASSIGNpnametree(sp));
178                                 sp->soffset = regno(p->n_left);
179                                 sp->sflags |= STNODE;
180                                 ecomp(p);
181                         }
182                         break;
183
ragge
1.8
184                 default:
ragge
1.9
185                         cerror("bfcode: %d"typ);
mickey
1.1
186                 }
187         }
188 }
189
190
191 /*
192  * by now, the automatics and register variables are allocated
193  */
194 void
195 bccode()
196 {
197         SETOFF(autooffSZINT);
198 }
199
200 /* called just before final exit */
201 /* flag is 1 if errors, 0 if none */
202 void
203 ejobcode(int flag )
204 {
205 #define _MKSTR(x) #x
206 #define MKSTR(x) _MKSTR(x)
207 #define OS MKSTR(TARGOS)
208         printf("\t.ident \"PCC: %s (%s)\"\n\t.end\n"PACKAGE_STRINGOS);
209 }
210
211 void
212 bjobcode()
213 {
214 }
215
ragge
1.7
216 static NODE *
217 movtoreg(NODE *pint rno)
mickey
1.1
218 {
219         NODE *r;
220
ragge
1.9
221         r = block(REGNILNILp->n_typep->n_dfp->n_sue);
ragge
1.7
222         regno(r) = rno;
223         return clocal(buildtree(ASSIGNrp));
224 }  
225
ragge
1.9
226 static NODE *
227 movtomem(NODE *pint off)
228 {
229         struct symtab s;
230         NODE *r, *l;
231
232         s.stype = p->n_type;
233         s.sdf = p->n_df;
234         s.ssue = p->n_sue;
235         s.soffset = off;
236
237         l = block(REGNILNILPTR+STRTY00);
238         l->n_lval = 0;
239         regno(l) = STKREG;
240
241         r = block(NAMENILNILp->n_typep->n_dfp->n_sue);
242         r->n_sp = &s;
243         r = stref(block(STREFlr000));
244
245         return clocal(buildtree(ASSIGNrp));
246 }  
247
ragge
1.7
248
249 /*
250  * AMD64 parameter classification.
251  */
252 static int
ragge
1.8
253 argtyp(TWORD tunion dimfun *dfstruct suedef *sue)
ragge
1.7
254 {
255         int cl = 0;
256
ragge
1.9
257         if (t <= ULONG || ISPTR(t)) {
ragge
1.7
258                 cl = ngpr < 6 ? INTEGER : INTMEM;
259         } else if (t == FLOAT || t == DOUBLE) {
ragge
1.8
260                 cl = nsse < 8 ? SSE : SSEMEM;
ragge
1.7
261         } else if (t == LDOUBLE) {
262                 cl = X87/* XXX */
263         } else if (t == STRTY) {
ragge
1.8
264                 if (tsize(tdfsue) > 4*SZLONG)
ragge
1.7
265                         cl = STRMEM;
266                 else
267                         cerror("clasif");
268         } else
269                 cerror("FIXME: classify");
270         return cl;
271 }
272
273 static void
274 argput(NODE *p)
275 {
276         NODE *q;
277         int typr;
mickey
1.1
278
ragge
1.7
279         /* first arg may be struct return pointer */
280         /* XXX - check if varargs; setup al */
ragge
1.8
281         switch (typ = argtyp(p->n_typep->n_dfp->n_sue)) {
ragge
1.7
282         case INTEGER:
283         case SSE:
284                 q = talloc();
285                 *q = *p;
286                 if (typ == SSE)
287                         r = XMM0 + nsse++;
288                 else
289                         r = argregsi[ngpr++];
290                 q = movtoreg(qr);
291                 *p = *q;
292                 nfree(q);
293                 break;
294         case X87:
295                 cerror("no long double yet");
296                 break;
ragge
1.9
297
298         case INTMEM:
299                 q = talloc();
300                 *q = *p;
301                 r = nrsp;
302                 nrsp += SZLONG;
303                 q = movtomem(qr);
304                 *p = *q;
305                 nfree(q);
306                 break;
307
ragge
1.7
308         case STRMEM:
309                 /* Struct moved to memory */
310         case STRREG:
311                 /* Struct in registers */
312         default:
ragge
1.9
313                 cerror("argument %d"typ);
mickey
1.1
314         }
ragge
1.7
315 }
mickey
1.1
316
317
318 /*
319  * Called with a function call with arguments as argument.
320  * This is done early in buildtree() and only done once.
321  * Returns p.
322  */
323 NODE *
324 funcode(NODE *p)
325 {
ragge
1.8
326         NODE *l, *r;
mickey
1.1
327
ragge
1.9
328         nsse = ngpr = nrsp = 0;
ragge
1.7
329         listf(p->n_rightargput);
ragge
1.8
330
331         /* Always emit number of SSE regs used */
332         l = movtoreg(bcon(nsse), RAX);
333         if (p->n_right->n_op != CM) {
334                 p->n_right = block(CMlp->n_rightINT0MKSUE(INT));
335         } else {
336                 for (r = p->n_rightr->n_left->n_op == CMr = r->n_left)
337                         ;
338                 r->n_left = block(CMlr->n_leftINT0MKSUE(INT));
339         }
mickey
1.1
340         return p;
341 }
342
343 /*
344  * return the alignment of field of type t
345  */
346 int
347 fldal(unsigned int t)
348 {
349         uerror("illegal field type");
350         return(ALINT);
351 }
352
353 /* fix up type of field p */
354 void
355 fldty(struct symtab *p)
356 {
357 }
358
359 /*
360  * XXX - fix genswitch.
361  */
362 int
363 mygenswitch(int numTWORD typestruct swents **pint n)
364 {
365         return 0;
366 }
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 15:28 +0100