Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20040516110801

Diff

Diff from 1.7 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/arch/i386/local.c

Annotated File View

ragge
1.7
1 /*      $Id: local.c,v 1.7 2004/05/16 11:08:01 ragge Exp $      */
ragge
1.1
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29
30 # include "pass1.h"
31
32 /*      this file contains code which is dependent on the target machine */
33
34 NODE *
35 clocal(NODE *p)
36 {
37         /* this is called to do local transformations on
38            an expression tree preparitory to its being
39            written out in intermediate code.
40         */
41
42         /* the major essential job is rewriting the
43            automatic variables and arguments in terms of
44            REG and OREG nodes */
45         /* conversion ops which are not necessary are also clobbered here */
46         /* in addition, any special features (such as rewriting
47            exclusive or) are easily handled here as well */
48
49         register struct symtab *q;
ragge
1.2
50         register NODE *r, *l;
ragge
1.1
51         register int o;
52         register int mml;
53
54         switcho = p->n_op ){
55
56         case NAME:
57                 if ((q = p->n_sp) == NULL)
58                         return p/* Nothing to care about */
59
60                 switch (q->sclass) {
61
62                 case PARAM:
63                 case AUTO:
64                         /* fake up a structure reference */
65                         r = block(REGNILNILPTR+STRTY00);
66                         r->n_lval = 0;
67                         r->n_rval = FPREG;
68                         p = stref(block(STREFrp000));
69                         break;
70
71                 case STATIC:
72                         if (q->slevel == 0)
73                                 break;
74                         p->n_lval = 0;
75                         p->n_sp = q;
76                         if ((q->sflags & SLABEL) == 0)
77                                 cerror("STATIC");
78                         break;
79
80                 case REGISTER:
81                         p->n_op = REG;
82                         p->n_lval = 0;
83                         p->n_rval = q->soffset;
84                         break;
85
86                         }
87                 break;
88
89         case PCONV:
ragge
1.2
90                 ml = p->n_left->n_type;
ragge
1.1
91                 l = p->n_left;
92                 if ((ml == CHAR || ml == UCHAR || ml == SHORT || ml == USHORT)
93                     && l->n_op != ICON)
94                         break;
95                 l->n_type = p->n_type;
96                 l->n_qual = p->n_qual;
97                 l->n_df = p->n_df;
98                 l->n_sue = p->n_sue;
99                 nfree(p);
100                 p = l;
101                 break;
102
103         case SCONV:
104                 l = p->n_left;
ragge
1.4
105
106                 if ((p->n_type & TMASK) == 0 && (l->n_type & TMASK) == 0 &&
107                     btdim[p->n_type] == btdim[l->n_type]) {
108                         if (p->n_type != FLOAT && p->n_type != DOUBLE &&
109                             l->n_type != FLOAT && l->n_type != DOUBLE) {
110                                 nfree(p);
111                                 return l;
112                         }
ragge
1.6
113                 }
114
115                 if ((p->n_type == INT || p->n_type == UNSIGNED) &&
116                     ISPTR(l->n_type)) {
117                         nfree(p);
118                         return l;
ragge
1.4
119                 }
120
ragge
1.3
121                 o = l->n_op;
ragge
1.4
122                 m = p->n_type;
ragge
1.1
123
124                 if (o == ICON) {
125                         CONSZ val = l->n_lval;
126
127                         switch (m) {
128                         case CHAR:
129                                 l->n_lval = (char)val;
130                                 break;
131                         case UCHAR:
132                                 l->n_lval = val & 0377;
133                                 break;
134                         case USHORT:
135                                 l->n_lval = (short)val;
136                                 break;
137                         case SHORT:
138                                 l->n_lval = val & 0177777;
139                                 break;
140                         case UNSIGNED:
141                                 l->n_lval = val & 0xffffffff;
142                                 break;
143                         case ENUMTY:
144                         case MOETY:
145                         case INT:
146                                 l->n_lval = (int)val;
147                                 break;
148                         case LONGLONG:
149                                 l->n_lval = (long long)val;
150                         case ULONGLONG:
151                                 l->n_lval = val;
152                                 break;
153                         case VOID:
154                                 break;
155                         case DOUBLE:
156                         case FLOAT:
157                                 l->n_op = FCON;
158                                 l->n_dcon = val;
159                                 break;
160                         default:
161                                 cerror("unknown type %d"m);
162                         }
163                         l->n_type = m;
164                         nfree(p);
165                         return l;
166                 }
167                 break;
168
169         case PMCONV:
170         case PVCONV:
171                 ifp->n_right->n_op != ICON ) cerror"bad conversion"0);
172                 nfree(p);
173                 return(buildtree(o==PMCONV?MUL:DIVp->n_leftp->n_right));
174
175         }
176
177         return(p);
178 }
179
180 void
181 myp2tree(NODE *p)
182 {
183 }
184
185 /*ARGSUSED*/
186 int
187 andable(NODE *p)
188 {
189         return(1);  /* all names can have & taken on them */
190 }
191
192 /*
193  * at the end of the arguments of a ftn, set the automatic offset
194  */
195 void
196 cendarg()
197 {
198         autooff = AUTOINIT;
199 }
200
201 /*
202  * is an automatic variable of type t OK for a register variable
203  * Everything is trusted to be in register here.
204  */
205 int
206 cisreg(TWORD t)
207 {
208         return(1);
209 }
210
211 /*
212  * return a node, for structure references, which is suitable for
213  * being added to a pointer of type t, in order to be off bits offset
214  * into a structure
215  * t, d, and s are the type, dimension offset, and sizeoffset
216  * For pdp10, return the type-specific index number which calculation
217  * is based on its size. For example, short a[3] would return 3.
218  * Be careful about only handling first-level pointers, the following
219  * indirections must be fullword.
220  */
221 NODE *
222 offcon(OFFSZ offTWORD tunion dimfun *dstruct suedef *sue)
223 {
224         register NODE *p;
225
226         if (xdebug)
227                 printf("offcon: OFFSZ %lld type %x dim %p siz %d\n",
228                     offtdsue->suesize);
229
230         p = bcon(0);
231         p->n_lval = off/SZCHAR/* Default */
232         return(p);
233 }
234
235 /*
236  * Allocate off bits on the stack.  p is a tree that when evaluated
237  * is the multiply count for off, t is a NAME node where to write
238  * the allocated address.
239  */
240 void
241 spalloc(NODE *tNODE *pOFFSZ off)
242 {
243         NODE *sp;
244
245         if ((off % SZINT) == 0)
246                 p =  buildtree(MULpbcon(off/SZINT));
247         else if ((off % SZSHORT) == 0) {
248                 p = buildtree(MULpbcon(off/SZSHORT));
249                 p = buildtree(PLUSpbcon(1));
250                 p = buildtree(RSpbcon(1));
251         } else if ((off % SZCHAR) == 0) {
252                 p = buildtree(MULpbcon(off/SZCHAR));
253                 p = buildtree(PLUSpbcon(3));
254                 p = buildtree(RSpbcon(2));
255         } else
256                 cerror("roundsp");
257
258         /* save the address of sp */
259         sp = block(REGNILNILPTR+INTt->n_dft->n_sue);
260         sp->n_lval = 0;
261         sp->n_rval = STKREG;
262         t->n_type = sp->n_type;
263         ecomp(buildtree(ASSIGNtsp)); /* Emit! */
264
265         /* add the size to sp */
266         sp = block(REGNILNILp->n_type00);
267         sp->n_lval = 0;
268         sp->n_rval = STKREG;
269         ecomp(buildtree(PLUSEQspp));
270 }
271
272 static int inwd;        /* current bit offsed in word */
273 static CONSZ word;      /* word being built from fields */
274
275 /*
276  * Generate initialization code for assigning a constant c
277  * to a field of width sz
278  * we assume that the proper alignment has been obtained
279  * inoff is updated to have the proper final value
280  * we also assume sz  < SZINT
281  */
282 void
283 incode(NODE *pint sz)
284 {
285         inoff += sz;
286         if ((sz + inwd) > SZINT)
287                 cerror("incode: field > int");
288
289         word |= ((unsigned)(p->n_lval<<(32-sz))) >> (32-sz-inwd);
290
291         inwd += sz;
292         if (inoff % SZINT == 0) {
ragge
1.5
293                 printf("        .long 0x%llx\n"word);
ragge
1.1
294                 word = inwd = 0;
295         }
296         tfree(p);
297 }
298
299 /* output code to initialize space of size sz to the value d */
300 /* the proper alignment has been obtained */
301 /* inoff is updated to have the proper final value */
302 /* on the target machine, write it out in octal! */
303 void
304 fincode(NODE *pint sz)
305 {
306         double d = p->n_dcon;
307
308         if(!nerrors)
309                 printf("        %s      0%c%.20e\n",
310                     sz == SZDOUBLE ? ".double" : ".float",
311                 sz == SZDOUBLE ? 'd' : 'f'd);
312         inoff += sz;
313 }
314
315 void
316 cinit(NODE *pint sz)
317 {
318         NODE *l;
319
320         /*
321          * as a favor (?) to people who want to write
322          *     int i = 9600/134.5;
323          * we will, under the proper circumstances, do
324          * a coercion here.
325          */
326         switch (p->n_type) {
327         case INT:
328         case UNSIGNED:
329                 l = p->n_left;
330                 if (l->n_op != SCONV || l->n_left->n_op != FCON)
331                         break;
332                 nfree(l);
333                 l = l->n_left;
334                 l->n_lval = (long)(l->n_dcon);
335                 l->n_sp = NULL;
336                 l->n_op = ICON;
337                 l->n_type = INT;
338                 p->n_left = l;
339                 break;
340         }
341         /* arrange for the initialization of p into a space of size sz */
342         /* the proper alignment has been opbtained */
343         /* inoff is updated to have the proper final value */
344         ecodep );
345         inoff += sz;
346 }
347
348 /*
349  * define n bits of zeros in a vfd
350  */
351 void
352 vfdzero(int n)
353 {
354         inoff += n;
355         inwd += n;
356         if (inoff%ALINT ==0) {
357                 printf("        .long 0%llo\n"word);
358                 word = inwd = 0;
359         }
360 }
361
362 /* make a name look like an external name in the local machine */
363 char *
364 exname(char *p)
365 {
366         if (p == NULL)
367                 return "";
368         return p;
369 }
370
371 /*
372  * map types which are not defined on the local machine
373  */
374 int
375 ctype(TWORD type)
376 {
377         switch (BTYPE(type)) {
378         case LONG:
379                 MODTYPE(type,INT);
380                 break;
381
382         case ULONG:
383                 MODTYPE(type,UNSIGNED);
384         }
385         return (type);
386 }
387
388 /* curid is a variable which is defined but
389  * is not initialized (and not a function );
390  * This routine returns the stroage class for an uninitialized declaration
391  */
392 int
393 noinit()
394 {
395         return(EXTERN);
396 }
397
398 /* make a common declaration for id, if reasonable */
399 void
400 commdec(struct symtab *q)
401 {
402         int off;
403
404         off = tsize(q->stypeq->sdfq->ssue);
405         off = (off+(SZINT-1))/SZINT;
ragge
1.7
406 #ifdef GCC_COMPAT
407         printf("        .comm %s,0%o\n"gcc_findname(q), off);
408 #else
ragge
1.1
409         printf("        .comm %s,0%o\n"exname(q->sname), off);
ragge
1.7
410 #endif
ragge
1.1
411 }
412
413 /* make a local common declaration for id, if reasonable */
414 void
415 lcommdec(struct symtab *q)
416 {
417         int off;
418
419         off = tsize(q->stypeq->sdfq->ssue);
420         off = (off+(SZINT-1))/SZINT;
421         if (q->slevel == 0)
ragge
1.7
422 #ifdef GCC_COMPAT
423                 printf("        .lcomm %s,0%o\n"gcc_findname(q), off);
424 #else
ragge
1.1
425                 printf("        .lcomm %s,0%o\n"exname(q->sname), off);
ragge
1.7
426 #endif
ragge
1.1
427         else
428                 printf("        .lcomm " LABFMT ",0%o\n"q->soffsetoff);
429 }
430
431 /*
432  * Debugger code - ignore.
433  */
434 void
435 prcstab(int a)
436 {
437 }
438
439 void
440 pfstab(char *a)
441 {
442 }
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-01 23:10 +0200