Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:mickey:20081210175930

Diff

Diff from 1.2 to:

Annotations

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

Annotated File View

mickey
1.2
1 /*      $Id: code.c,v 1.2 2008/12/10 17:59:30 mickey 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" };
47         TWORD t;
48         int s;
49
50         if (sp == NULL) {
51                 lastloc = -1;
52                 return;
53         }
54         t = sp->stype;
55         s = ISFTN(t) ? PROG : ISCON(cqual(tsp->squal)) ? RDATA : DATA;
56 #ifdef TLS
57         if (sp->sflags & STLS) {
58                 if (s != DATA)
59                         cerror("non-data symbol in tls section");
60                 nextsect = ".tdata";
61         }
62 #endif
63         if (nextsect) {
64                 printf("        .section %s\n"nextsect);
65                 nextsect = NULL;
66                 s = -1;
67         } else if (s != lastloc)
68                 printf("        .%s\n"loctbl[s]);
69         lastloc = s;
70         while (ISARY(t))
71                 t = DECREF(t);
mickey
1.2
72         if (sp->ssue->suealign > ALCHAR)
73                 printf("        .align %d\n"sp->ssue->suealign/ALCHAR);
mickey
1.1
74         if (sp->sclass == EXTDEF)
75                 printf("        .globl %s\n"exname(sp->soname));
76         if (ISFTN(t))
77                 printf("\t.type %s,@function\n"exname(sp->soname));
78         if (sp->slevel == 0)
79                 printf("%s:\n"exname(sp->soname));
80         else
81                 printf(LABFMT ":\n"sp->soffset);
82 }
83
84 /*
85  * code for the end of a function
86  * deals with struct return here
87  */
88 void
89 efcode()
90 {
91         extern int gotnr;
92         NODE *p, *q;
93
94         gotnr = 0;      /* new number for next fun */
95         if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
96                 return;
97         /* Create struct assignment */
98         q = block(OREGNILNILPTR+STRTY0cftnsp->ssue);
99         q->n_rval = EBP;
100         q->n_lval = 8/* return buffer offset */
101         q = buildtree(UMULqNIL);
102         p = block(REGNILNILPTR+STRTY0cftnsp->ssue);
103         p = buildtree(UMULpNIL);
104         p = buildtree(ASSIGNqp);
105         ecomp(p);
106 }
107
108 /*
109  * code for the beginning of a function; a is an array of
110  * indices in symtab for the arguments; n is the number
111  */
112 void
113 bfcode(struct symtab **aint cnt)
114 {
115         struct symtab *sp2;
116         extern int gotnr;
117         NODE *n, *p;
118         int i;
119
120         if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
121                 /* Function returns struct, adjust arg offset */
122                 for (i = 0i < cnti++) 
123                         sp[i]->soffset += SZPOINT(LONG);
124         }
125
126         if (kflag) {
127                 /* Put ebx in temporary */
128                 n = block(REGNILNILINT0MKSUE(INT));
129                 n->n_rval = EBX;
130                 p = tempnode(0INT0MKSUE(INT));
131                 gotnr = regno(p);
132                 ecomp(buildtree(ASSIGNpn));
133         }
134
135         /* recalculate the arg offset and create TEMP moves */
136         for (n = 0i = 0i < cnti++) {
137                 sp = a[i];
138
139                 if (n < 6) {
140                         p = tempnode(0sp->stypesp->sdfsp->ssue);
141                         q = block(REGNILNILsp->stypesp->sdfsp->ssue);
142                         q->n_rval = argreg(sp->stype, &n);
143                         p = buildtree(ASSIGNpq);
144                         sp->soffset = regno(p->n_left);
145                         sp->sflags |= STNODE;
146                         ecomp(p);
147                 } else {
148                         sp->soffset += SZLONG * n;
149                         if (xtemps) {
150                                 /* put stack args in temps if optimizing */
151                                 p = tempnode(0sp->stypesp->sdfsp->ssue);
152                                 p = buildtree(ASSIGNpbuildtree(NAME00));
153                                 sp->soffset = regno(p->n_left);
154                                 sp->sflags |= STNODE;
155                                 ecomp(p);
156                         }
157                 }
158         }
159 }
160
161
162 /*
163  * by now, the automatics and register variables are allocated
164  */
165 void
166 bccode()
167 {
168         SETOFF(autooffSZINT);
169 }
170
171 /* called just before final exit */
172 /* flag is 1 if errors, 0 if none */
173 void
174 ejobcode(int flag )
175 {
176         if (errors)
177                 return;
178
179 #define _MKSTR(x) #x
180 #define MKSTR(x) _MKSTR(x)
181 #define OS MKSTR(TARGOS)
182         printf("\t.ident \"PCC: %s (%s)\"\n\t.end\n"PACKAGE_STRINGOS);
183 }
184
185 void
186 bjobcode()
187 {
188 }
189
190 static const int argregsi[] = { RDIRSIRDXRCXR09R08 };
191
192 int
193 argreg(TWORD tint *n)   
194 {
195         switch (t) {
196         case FLOAT:
197         case DOUBLE:
198         case LDOUBLE:
199                 return FR6 - *n - 2;
200         case LONGLONG:
201         case ULONGLONG:
202                 /* TODO */;
203         default:
204                 return argregsi[(*n)++];
205         }
206 }
207
208 NODE *
209 funarg(NODE *pint *n)
210 {
211         NODE *r;
212         int sz;
213
214         if (p->n_op == CM) {
215                 p->n_left = funarg(p->n_leftn);
216                 p->n_right = funarg(p->n_rightn);
217                 return p;
218         }
219
220         if (*n >= 6) {
221                 *n++;
222                 r = block(OREGNILNILp->n_type|PTR0,
223                     MKSUE(p->n_type|PTR));
224                 r->n_rval = RBP;
225                 r->n_lval = 16 + (*n - 6) * 8;
226         } else {
227                 r = block(REGNILNILp->n_type00);
228                 r->n_lval = 0;
229                 r->n_rval = argreg(p->n_typen);
230         }
231         p = block(ASSIGNrpp->n_type00);
232         clocal(p);
233
234         return p;
235 }  
236
237 /*
238  * Called with a function call with arguments as argument.
239  * This is done early in buildtree() and only done once.
240  * Returns p.
241  */
242 NODE *
243 funcode(NODE *p)
244 {
245         extern int gotnr;
246         NODE *r, *l;
247         int n = 0;
248
249         p->n_right = funarg(p->n_right, &n);
250
251         if (kflag == 0)
252                 return p;
253         /* Create an ASSIGN node for ebx */
254         l = block(REGNILNILINT0MKSUE(INT));
255         l->n_rval = EBX;
256         l = buildtree(ASSIGNltempnode(gotnrINT0MKSUE(INT)));
257         if (p->n_right->n_op != CM) {
258                 p->n_right = block(CMlp->n_rightINT0MKSUE(INT));
259         } else {
260                 for (r = p->n_rightr->n_left->n_op == CMr = r->n_left)
261                         ;
262                 r->n_left = block(CMlr->n_leftINT0MKSUE(INT));
263         }
264         return p;
265 }
266
267 /*
268  * return the alignment of field of type t
269  */
270 int
271 fldal(unsigned int t)
272 {
273         uerror("illegal field type");
274         return(ALINT);
275 }
276
277 /* fix up type of field p */
278 void
279 fldty(struct symtab *p)
280 {
281 }
282
283 /*
284  * XXX - fix genswitch.
285  */
286 int
287 mygenswitch(int numTWORD typestruct swents **pint n)
288 {
289         return 0;
290 }
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-20 18:17 +0100