Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:gmcgarry:20090521093459

Diff

Diff from 1.4 to:

Annotations

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

Annotated File View

gmcgarry
1.4
1 /*      $Id: code.c,v 1.4 2009/05/21 09:34:59 gmcgarry 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);
ragge
1.3
72         s = ISFTN(t) ? ALINT : talign(tsp->ssue);
73         if (s > ALCHAR)
74                 printf("        .align %d\n"s/ALCHAR);
mickey
1.1
75         if (sp->sclass == EXTDEF)
76                 printf("        .globl %s\n"exname(sp->soname));
77         if (ISFTN(t))
78                 printf("\t.type %s,@function\n"exname(sp->soname));
79         if (sp->slevel == 0)
80                 printf("%s:\n"exname(sp->soname));
81         else
82                 printf(LABFMT ":\n"sp->soffset);
83 }
84
85 /*
86  * code for the end of a function
87  * deals with struct return here
88  */
89 void
90 efcode()
91 {
92         extern int gotnr;
93         NODE *p, *q;
94
95         gotnr = 0;      /* new number for next fun */
96         if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
97                 return;
98         /* Create struct assignment */
99         q = block(OREGNILNILPTR+STRTY0cftnsp->ssue);
100         q->n_rval = EBP;
101         q->n_lval = 8/* return buffer offset */
102         q = buildtree(UMULqNIL);
103         p = block(REGNILNILPTR+STRTY0cftnsp->ssue);
104         p = buildtree(UMULpNIL);
105         p = buildtree(ASSIGNqp);
106         ecomp(p);
107 }
108
109 /*
110  * code for the beginning of a function; a is an array of
111  * indices in symtab for the arguments; n is the number
112  */
113 void
gmcgarry
1.4
114 bfcode(struct symtab **spint cnt)
mickey
1.1
115 {
116         extern int gotnr;
gmcgarry
1.4
117         NODE *n, *p, *q;
118         int ik;
mickey
1.1
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 */
gmcgarry
1.4
136         for (k = 0i = 0i < cnti++) {
mickey
1.1
137
gmcgarry
1.4
138                 if (sp[i] == NULL)
139                         continue;
140
141                 if (k < 6) {
142                         p = tempnode(0sp[i]->stypesp[i]->sdfsp[i]->ssue);
143                         q = block(REGNILNILsp[i]->stypesp[i]->sdfsp[i]->ssue);
144                         q->n_rval = argreg(sp[i]->stype, &k);
mickey
1.1
145                         p = buildtree(ASSIGNpq);
gmcgarry
1.4
146                         sp[i]->soffset = regno(p->n_left);
147                         sp[i]->sflags |= STNODE;
mickey
1.1
148                         ecomp(p);
149                 } else {
gmcgarry
1.4
150                         sp[i]->soffset += SZLONG * k;
mickey
1.1
151                         if (xtemps) {
152                                 /* put stack args in temps if optimizing */
gmcgarry
1.4
153                                 p = tempnode(0sp[i]->stypesp[i]->sdfsp[i]->ssue);
mickey
1.1
154                                 p = buildtree(ASSIGNpbuildtree(NAME00));
gmcgarry
1.4
155                                 sp[i]->soffset = regno(p->n_left);
156                                 sp[i]->sflags |= STNODE;
mickey
1.1
157                                 ecomp(p);
158                         }
159                 }
160         }
161 }
162
163
164 /*
165  * by now, the automatics and register variables are allocated
166  */
167 void
168 bccode()
169 {
170         SETOFF(autooffSZINT);
171 }
172
173 /* called just before final exit */
174 /* flag is 1 if errors, 0 if none */
175 void
176 ejobcode(int flag )
177 {
178 #define _MKSTR(x) #x
179 #define MKSTR(x) _MKSTR(x)
180 #define OS MKSTR(TARGOS)
181         printf("\t.ident \"PCC: %s (%s)\"\n\t.end\n"PACKAGE_STRINGOS);
182 }
183
184 void
185 bjobcode()
186 {
187 }
188
189 static const int argregsi[] = { RDIRSIRDXRCXR09R08 };
190
191 int
192 argreg(TWORD tint *n)   
193 {
194         switch (t) {
195         case FLOAT:
196         case DOUBLE:
197         case LDOUBLE:
gmcgarry
1.4
198                 /* return FR6 - *n - 2; */
199                 cerror("argreg");
200                 return 0;
mickey
1.1
201         case LONGLONG:
202         case ULONGLONG:
203                 /* TODO */;
204         default:
205                 return argregsi[(*n)++];
206         }
207 }
208
209 NODE *
210 funarg(NODE *pint *n)
211 {
212         NODE *r;
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-29 05:35 +0100