Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20040518142937

Diff

Diff from 1.8 to:

Annotations

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

Annotated File View

ragge
1.8
1 /*      $Id: local.c,v 1.8 2004/05/18 14:29:37 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
ragge
1.8
89         case CBRANCH:
90                 l = p->n_left;
91
92                 /*
93                  * Remove unneccessary conversion ops.
94                  */
95                 if (l->n_left->n_op == SCONV) {
96                         if (l->n_right->n_op == ICON) {
97                                 r = l->n_left->n_left;
98                                 nfree(l->n_left);
99                                 l->n_left = r;
100                         } else if (l->n_right->n_op == SCONV &&
101                             l->n_left->n_type == l->n_right->n_type) {
102                                 r = l->n_left->n_left;
103                                 nfree(l->n_left);
104                                 l->n_left = r;
105                                 r = l->n_right->n_left;
106                                 nfree(l->n_right);
107                                 l->n_right = r;
108                         }
109                 }
110                 break;
111
ragge
1.1
112         case PCONV:
ragge
1.2
113                 ml = p->n_left->n_type;
ragge
1.1
114                 l = p->n_left;
115                 if ((ml == CHAR || ml == UCHAR || ml == SHORT || ml == USHORT)
116                     && l->n_op != ICON)
117                         break;
118                 l->n_type = p->n_type;
119                 l->n_qual = p->n_qual;
120                 l->n_df = p->n_df;
121                 l->n_sue = p->n_sue;
122                 nfree(p);
123                 p = l;
124                 break;
125
126         case SCONV:
127                 l = p->n_left;
ragge
1.4
128
129                 if ((p->n_type & TMASK) == 0 && (l->n_type & TMASK) == 0 &&
130                     btdim[p->n_type] == btdim[l->n_type]) {
131                         if (p->n_type != FLOAT && p->n_type != DOUBLE &&
132                             l->n_type != FLOAT && l->n_type != DOUBLE) {
133                                 nfree(p);
134                                 return l;
135                         }
ragge
1.6
136                 }
137
138                 if ((p->n_type == INT || p->n_type == UNSIGNED) &&
139                     ISPTR(l->n_type)) {
140                         nfree(p);
141                         return l;
ragge
1.4
142                 }
143
ragge
1.3
144                 o = l->n_op;
ragge
1.4
145                 m = p->n_type;
ragge
1.1
146
147                 if (o == ICON) {
148                         CONSZ val = l->n_lval;
149
150                         switch (m) {
151                         case CHAR:
152                                 l->n_lval = (char)val;
153                                 break;
154                         case UCHAR:
155                                 l->n_lval = val & 0377;
156                                 break;
157                         case USHORT:
158                                 l->n_lval = (short)val;
159                                 break;
160                         case SHORT:
161                                 l->n_lval = val & 0177777;
162                                 break;
163                         case UNSIGNED:
164                                 l->n_lval = val & 0xffffffff;
165                                 break;
166                         case ENUMTY:
167                         case MOETY:
168                         case INT:
169                                 l->n_lval = (int)val;
170                                 break;
171                         case LONGLONG:
172                                 l->n_lval = (long long)val;
173                         case ULONGLONG:
174                                 l->n_lval = val;
175                                 break;
176                         case VOID:
177                                 break;
178                         case DOUBLE:
179                         case FLOAT:
180                                 l->n_op = FCON;
181                                 l->n_dcon = val;
182                                 break;
183                         default:
184                                 cerror("unknown type %d"m);
185                         }
186                         l->n_type = m;
187                         nfree(p);
188                         return l;
189                 }
190                 break;
191
192         case PMCONV:
193         case PVCONV:
194                 ifp->n_right->n_op != ICON ) cerror"bad conversion"0);
195                 nfree(p);
196                 return(buildtree(o==PMCONV?MUL:DIVp->n_leftp->n_right));
197
198         }
199
200         return(p);
201 }
202
203 void
204 myp2tree(NODE *p)
205 {
206 }
207
208 /*ARGSUSED*/
209 int
210 andable(NODE *p)
211 {
212         return(1);  /* all names can have & taken on them */
213 }
214
215 /*
216  * at the end of the arguments of a ftn, set the automatic offset
217  */
218 void
219 cendarg()
220 {
221         autooff = AUTOINIT;
222 }
223
224 /*
225  * is an automatic variable of type t OK for a register variable
226  * Everything is trusted to be in register here.
227  */
228 int
229 cisreg(TWORD t)
230 {
231         return(1);
232 }
233
234 /*
235  * return a node, for structure references, which is suitable for
236  * being added to a pointer of type t, in order to be off bits offset
237  * into a structure
238  * t, d, and s are the type, dimension offset, and sizeoffset
239  * For pdp10, return the type-specific index number which calculation
240  * is based on its size. For example, short a[3] would return 3.
241  * Be careful about only handling first-level pointers, the following
242  * indirections must be fullword.
243  */
244 NODE *
245 offcon(OFFSZ offTWORD tunion dimfun *dstruct suedef *sue)
246 {
247         register NODE *p;
248
249         if (xdebug)
250                 printf("offcon: OFFSZ %lld type %x dim %p siz %d\n",
251                     offtdsue->suesize);
252
253         p = bcon(0);
254         p->n_lval = off/SZCHAR/* Default */
255         return(p);
256 }
257
258 /*
259  * Allocate off bits on the stack.  p is a tree that when evaluated
260  * is the multiply count for off, t is a NAME node where to write
261  * the allocated address.
262  */
263 void
264 spalloc(NODE *tNODE *pOFFSZ off)
265 {
266         NODE *sp;
267
268         if ((off % SZINT) == 0)
269                 p =  buildtree(MULpbcon(off/SZINT));
270         else if ((off % SZSHORT) == 0) {
271                 p = buildtree(MULpbcon(off/SZSHORT));
272                 p = buildtree(PLUSpbcon(1));
273                 p = buildtree(RSpbcon(1));
274         } else if ((off % SZCHAR) == 0) {
275                 p = buildtree(MULpbcon(off/SZCHAR));
276                 p = buildtree(PLUSpbcon(3));
277                 p = buildtree(RSpbcon(2));
278         } else
279                 cerror("roundsp");
280
281         /* save the address of sp */
282         sp = block(REGNILNILPTR+INTt->n_dft->n_sue);
283         sp->n_lval = 0;
284         sp->n_rval = STKREG;
285         t->n_type = sp->n_type;
286         ecomp(buildtree(ASSIGNtsp)); /* Emit! */
287
288         /* add the size to sp */
289         sp = block(REGNILNILp->n_type00);
290         sp->n_lval = 0;
291         sp->n_rval = STKREG;
292         ecomp(buildtree(PLUSEQspp));
293 }
294
295 static int inwd;        /* current bit offsed in word */
296 static CONSZ word;      /* word being built from fields */
297
298 /*
299  * Generate initialization code for assigning a constant c
300  * to a field of width sz
301  * we assume that the proper alignment has been obtained
302  * inoff is updated to have the proper final value
303  * we also assume sz  < SZINT
304  */
305 void
306 incode(NODE *pint sz)
307 {
308         inoff += sz;
309         if ((sz + inwd) > SZINT)
310                 cerror("incode: field > int");
311
312         word |= ((unsigned)(p->n_lval<<(32-sz))) >> (32-sz-inwd);
313
314         inwd += sz;
315         if (inoff % SZINT == 0) {
ragge
1.5
316                 printf("        .long 0x%llx\n"word);
ragge
1.1
317                 word = inwd = 0;
318         }
319         tfree(p);
320 }
321
322 /* output code to initialize space of size sz to the value d */
323 /* the proper alignment has been obtained */
324 /* inoff is updated to have the proper final value */
325 /* on the target machine, write it out in octal! */
326 void
327 fincode(NODE *pint sz)
328 {
329         double d = p->n_dcon;
330
331         if(!nerrors)
332                 printf("        %s      0%c%.20e\n",
333                     sz == SZDOUBLE ? ".double" : ".float",
334                 sz == SZDOUBLE ? 'd' : 'f'd);
335         inoff += sz;
336 }
337
338 void
339 cinit(NODE *pint sz)
340 {
341         NODE *l;
342
343         /*
344          * as a favor (?) to people who want to write
345          *     int i = 9600/134.5;
346          * we will, under the proper circumstances, do
347          * a coercion here.
348          */
349         switch (p->n_type) {
350         case INT:
351         case UNSIGNED:
352                 l = p->n_left;
353                 if (l->n_op != SCONV || l->n_left->n_op != FCON)
354                         break;
355                 nfree(l);
356                 l = l->n_left;
357                 l->n_lval = (long)(l->n_dcon);
358                 l->n_sp = NULL;
359                 l->n_op = ICON;
360                 l->n_type = INT;
361                 p->n_left = l;
362                 break;
363         }
364         /* arrange for the initialization of p into a space of size sz */
365         /* the proper alignment has been opbtained */
366         /* inoff is updated to have the proper final value */
367         ecodep );
368         inoff += sz;
369 }
370
371 /*
372  * define n bits of zeros in a vfd
373  */
374 void
375 vfdzero(int n)
376 {
377         inoff += n;
378         inwd += n;
379         if (inoff%ALINT ==0) {
380                 printf("        .long 0%llo\n"word);
381                 word = inwd = 0;
382         }
383 }
384
385 /* make a name look like an external name in the local machine */
386 char *
387 exname(char *p)
388 {
389         if (p == NULL)
390                 return "";
391         return p;
392 }
393
394 /*
395  * map types which are not defined on the local machine
396  */
397 int
398 ctype(TWORD type)
399 {
400         switch (BTYPE(type)) {
401         case LONG:
402                 MODTYPE(type,INT);
403                 break;
404
405         case ULONG:
406                 MODTYPE(type,UNSIGNED);
407         }
408         return (type);
409 }
410
411 /* curid is a variable which is defined but
412  * is not initialized (and not a function );
413  * This routine returns the stroage class for an uninitialized declaration
414  */
415 int
416 noinit()
417 {
418         return(EXTERN);
419 }
420
421 /* make a common declaration for id, if reasonable */
422 void
423 commdec(struct symtab *q)
424 {
425         int off;
426
427         off = tsize(q->stypeq->sdfq->ssue);
ragge
1.8
428         off = (off+(SZCHAR-1))/SZCHAR;
ragge
1.7
429 #ifdef GCC_COMPAT
430         printf("        .comm %s,0%o\n"gcc_findname(q), off);
431 #else
ragge
1.1
432         printf("        .comm %s,0%o\n"exname(q->sname), off);
ragge
1.7
433 #endif
ragge
1.1
434 }
435
436 /* make a local common declaration for id, if reasonable */
437 void
438 lcommdec(struct symtab *q)
439 {
440         int off;
441
442         off = tsize(q->stypeq->sdfq->ssue);
ragge
1.8
443         off = (off+(SZCHAR-1))/SZCHAR;
ragge
1.1
444         if (q->slevel == 0)
ragge
1.7
445 #ifdef GCC_COMPAT
446                 printf("        .lcomm %s,0%o\n"gcc_findname(q), off);
447 #else
ragge
1.1
448                 printf("        .lcomm %s,0%o\n"exname(q->sname), off);
ragge
1.7
449 #endif
ragge
1.1
450         else
451                 printf("        .lcomm " LABFMT ",0%o\n"q->soffsetoff);
452 }
453
454 /*
455  * Debugger code - ignore.
456  */
457 void
458 prcstab(int a)
459 {
460 }
461
462 void
463 pfstab(char *a)
464 {
465 }
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-07-11 03:10 +0200