Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20030806211620

Diff

Diff from 1.3 to:

Annotations

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

Annotated File View

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