Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20040525155236

Diff

Diff from 1.9 to:

Annotations

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

Annotated File View

ragge
1.9
1 /*      $Id: local.c,v 1.9 2004/05/25 15:52:36 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  */
227 int
228 cisreg(TWORD t)
229 {
ragge
1.9
230         if (t == LONGLONG || t == ULONGLONG)
231                 return 0/* XXX - fix reg assignment in pftn.c */
ragge
1.1
232         return(1);
233 }
234
235 /*
236  * return a node, for structure references, which is suitable for
237  * being added to a pointer of type t, in order to be off bits offset
238  * into a structure
239  * t, d, and s are the type, dimension offset, and sizeoffset
240  * For pdp10, return the type-specific index number which calculation
241  * is based on its size. For example, short a[3] would return 3.
242  * Be careful about only handling first-level pointers, the following
243  * indirections must be fullword.
244  */
245 NODE *
246 offcon(OFFSZ offTWORD tunion dimfun *dstruct suedef *sue)
247 {
248         register NODE *p;
249
250         if (xdebug)
251                 printf("offcon: OFFSZ %lld type %x dim %p siz %d\n",
252                     offtdsue->suesize);
253
254         p = bcon(0);
255         p->n_lval = off/SZCHAR/* Default */
256         return(p);
257 }
258
259 /*
260  * Allocate off bits on the stack.  p is a tree that when evaluated
261  * is the multiply count for off, t is a NAME node where to write
262  * the allocated address.
263  */
264 void
265 spalloc(NODE *tNODE *pOFFSZ off)
266 {
267         NODE *sp;
268
269         if ((off % SZINT) == 0)
270                 p =  buildtree(MULpbcon(off/SZINT));
271         else if ((off % SZSHORT) == 0) {
272                 p = buildtree(MULpbcon(off/SZSHORT));
273                 p = buildtree(PLUSpbcon(1));
274                 p = buildtree(RSpbcon(1));
275         } else if ((off % SZCHAR) == 0) {
276                 p = buildtree(MULpbcon(off/SZCHAR));
277                 p = buildtree(PLUSpbcon(3));
278                 p = buildtree(RSpbcon(2));
279         } else
280                 cerror("roundsp");
281
282         /* save the address of sp */
283         sp = block(REGNILNILPTR+INTt->n_dft->n_sue);
284         sp->n_lval = 0;
285         sp->n_rval = STKREG;
286         t->n_type = sp->n_type;
287         ecomp(buildtree(ASSIGNtsp)); /* Emit! */
288
289         /* add the size to sp */
290         sp = block(REGNILNILp->n_type00);
291         sp->n_lval = 0;
292         sp->n_rval = STKREG;
293         ecomp(buildtree(PLUSEQspp));
294 }
295
296 static int inwd;        /* current bit offsed in word */
297 static CONSZ word;      /* word being built from fields */
298
299 /*
300  * Generate initialization code for assigning a constant c
301  * to a field of width sz
302  * we assume that the proper alignment has been obtained
303  * inoff is updated to have the proper final value
304  * we also assume sz  < SZINT
305  */
306 void
307 incode(NODE *pint sz)
308 {
309         inoff += sz;
310         if ((sz + inwd) > SZINT)
311                 cerror("incode: field > int");
312
313         word |= ((unsigned)(p->n_lval<<(32-sz))) >> (32-sz-inwd);
314
315         inwd += sz;
316         if (inoff % SZINT == 0) {
ragge
1.5
317                 printf("        .long 0x%llx\n"word);
ragge
1.1
318                 word = inwd = 0;
319         }
320         tfree(p);
321 }
322
323 /* output code to initialize space of size sz to the value d */
324 /* the proper alignment has been obtained */
325 /* inoff is updated to have the proper final value */
326 /* on the target machine, write it out in octal! */
327 void
328 fincode(NODE *pint sz)
329 {
330         double d = p->n_dcon;
331
332         if(!nerrors)
333                 printf("        %s      0%c%.20e\n",
334                     sz == SZDOUBLE ? ".double" : ".float",
335                 sz == SZDOUBLE ? 'd' : 'f'd);
336         inoff += sz;
337 }
338
339 void
340 cinit(NODE *pint sz)
341 {
342         NODE *l;
343
344         /*
345          * as a favor (?) to people who want to write
346          *     int i = 9600/134.5;
347          * we will, under the proper circumstances, do
348          * a coercion here.
349          */
350         switch (p->n_type) {
351         case INT:
352         case UNSIGNED:
353                 l = p->n_left;
354                 if (l->n_op != SCONV || l->n_left->n_op != FCON)
355                         break;
356                 nfree(l);
357                 l = l->n_left;
358                 l->n_lval = (long)(l->n_dcon);
359                 l->n_sp = NULL;
360                 l->n_op = ICON;
361                 l->n_type = INT;
362                 p->n_left = l;
363                 break;
364         }
365         /* arrange for the initialization of p into a space of size sz */
366         /* the proper alignment has been opbtained */
367         /* inoff is updated to have the proper final value */
368         ecodep );
369         inoff += sz;
370 }
371
372 /*
373  * define n bits of zeros in a vfd
374  */
375 void
376 vfdzero(int n)
377 {
378         inoff += n;
379         inwd += n;
380         if (inoff%ALINT ==0) {
381                 printf("        .long 0%llo\n"word);
382                 word = inwd = 0;
383         }
384 }
385
386 /* make a name look like an external name in the local machine */
387 char *
388 exname(char *p)
389 {
390         if (p == NULL)
391                 return "";
392         return p;
393 }
394
395 /*
396  * map types which are not defined on the local machine
397  */
398 int
399 ctype(TWORD type)
400 {
401         switch (BTYPE(type)) {
402         case LONG:
403                 MODTYPE(type,INT);
404                 break;
405
406         case ULONG:
407                 MODTYPE(type,UNSIGNED);
408         }
409         return (type);
410 }
411
412 /* curid is a variable which is defined but
413  * is not initialized (and not a function );
414  * This routine returns the stroage class for an uninitialized declaration
415  */
416 int
417 noinit()
418 {
419         return(EXTERN);
420 }
421
422 /* make a common declaration for id, if reasonable */
423 void
424 commdec(struct symtab *q)
425 {
426         int off;
427
428         off = tsize(q->stypeq->sdfq->ssue);
ragge
1.8
429         off = (off+(SZCHAR-1))/SZCHAR;
ragge
1.7
430 #ifdef GCC_COMPAT
431         printf("        .comm %s,0%o\n"gcc_findname(q), off);
432 #else
ragge
1.1
433         printf("        .comm %s,0%o\n"exname(q->sname), off);
ragge
1.7
434 #endif
ragge
1.1
435 }
436
437 /* make a local common declaration for id, if reasonable */
438 void
439 lcommdec(struct symtab *q)
440 {
441         int off;
442
443         off = tsize(q->stypeq->sdfq->ssue);
ragge
1.8
444         off = (off+(SZCHAR-1))/SZCHAR;
ragge
1.1
445         if (q->slevel == 0)
ragge
1.7
446 #ifdef GCC_COMPAT
447                 printf("        .lcomm %s,0%o\n"gcc_findname(q), off);
448 #else
ragge
1.1
449                 printf("        .lcomm %s,0%o\n"exname(q->sname), off);
ragge
1.7
450 #endif
ragge
1.1
451         else
452                 printf("        .lcomm " LABFMT ",0%o\n"q->soffsetoff);
453 }
454
455 /*
456  * Debugger code - ignore.
457  */
458 void
459 prcstab(int a)
460 {
461 }
462
463 void
464 pfstab(char *a)
465 {
466 }
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-08-27 21:00 +0200