Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20071209180057

Diff

Diff from 1.65 to:

Annotations

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

Annotated File View

ragge
1.65
1 /*      $Id: local.c,v 1.65 2007/12/09 18:00:57 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
ragge
1.48
30 #include "pass1.h"
ragge
1.1
31
ragge
1.60
32 /*      this file contains code which is dependent on the target machine */
33
ragge
1.57
34 /*
35  * Check if a constant is too large for a type.
36  */
37 static int
38 toolarge(TWORD tCONSZ con)
39 {
40         U_CONSZ ucon = con;
41
42         switch (t) {
43         case ULONGLONG:
44         case LONGLONG:
45                 break/* cannot be too large */
46 #define SCHK(i) case i: if (con > MAX_##i || con < MIN_##i) return 1; break
47 #define UCHK(i) case i: if (ucon > MAX_##i) return 1; break
48         SCHK(INT);
49         SCHK(SHORT);
otto
1.58
50         case BOOL:
ragge
1.57
51         SCHK(CHAR);
52         UCHK(UNSIGNED);
53         UCHK(USHORT);
54         UCHK(UCHAR);
55         default:
56                 cerror("toolarge");
57         }
58         return 0;
59 }
60
ragge
1.60
61 #define IALLOC(sz)      (isinlining ? permalloc(sz) : tmpalloc(sz))
62 /*
63  * Make a symtab entry for PIC use.
64  */
65 static struct symtab *
66 picsymtab(char *schar *s2)
67 {
68         struct symtab *sp = IALLOC(sizeof(struct symtab));
69         size_t len = strlen(s) + strlen(s2) + 1;
70         
71         sp->sname = IALLOC(len);
72         strlcpy(sp->snameslen);
73         strlcat(sp->snames2len);
74         sp->sclass = EXTERN;
ragge
1.64
75         sp->sflags = sp->slevel = 0;
ragge
1.60
76         return sp;
77 }
78
79 int gotnr/* tempnum for GOT register */
80 /*
81  * Create a reference for an extern variable.
82  */
83 static NODE *
84 picext(NODE *p)
85 {
86         NODE *q, *r;
87
88         q = tempnode(gotnrPTR|VOID0MKSUE(VOID));
89         r = bcon(0);
ragge
1.64
90         r->n_sp = picsymtab(gcc_findname(p->n_sp), "@GOT");
ragge
1.60
91         q = buildtree(PLUSqr);
92         q = block(UMULq0PTR|VOID0MKSUE(VOID));
93         q = block(UMULq0p->n_typep->n_dfp->n_sue);
ragge
1.65
94         q->n_sp = p->n_sp/* for init */
ragge
1.60
95         nfree(p);
96         return q;
97 }
98
99 /*
100  * Create a reference for a static variable.
101  */
102 static NODE *
103 picstatic(NODE *p)
104 {
105         NODE *q, *r;
106
107         q = tempnode(gotnrPTR|VOID0MKSUE(VOID));
108         r = bcon(0);
ragge
1.65
109         if (p->n_sp->slevel > 0 || p->n_sp->sclass == ILABEL) {
ragge
1.60
110                 char buf[32];
111                 snprintf(buf32LABFMT, (int)p->n_sp->soffset);
112                 r->n_sp = picsymtab(buf"@GOTOFF");
113         } else
ragge
1.64
114                 r->n_sp = picsymtab(gcc_findname(p->n_sp), "@GOTOFF");
115         r->n_sp->sclass = STATIC;
116         r->n_sp->stype = p->n_sp->stype;
ragge
1.60
117         q = buildtree(PLUSqr);
118         q = block(UMULq0p->n_typep->n_dfp->n_sue);
ragge
1.65
119         q->n_sp = p->n_sp/* for init */
ragge
1.60
120         nfree(p);
121         return q;
122 }
ragge
1.1
123
ragge
1.48
124 /* clocal() is called to do local transformations on
125  * an expression tree preparitory to its being
126  * written out in intermediate code.
127  *
128  * the major essential job is rewriting the
129  * automatic variables and arguments in terms of
130  * REG and OREG nodes
131  * conversion ops which are not necessary are also clobbered here
132  * in addition, any special features (such as rewriting
133  * exclusive or) are easily handled here as well
134  */
ragge
1.1
135 NODE *
136 clocal(NODE *p)
137 {
138
139         register struct symtab *q;
ragge
1.2
140         register NODE *r, *l;
ragge
1.1
141         register int o;
ragge
1.40
142         register int m;
ragge
1.19
143         TWORD t;
ragge
1.1
144
ragge
1.54
145 #ifdef PCC_DEBUG
146         if (xdebug) {
147                 printf("clocal: %p\n"p);
148                 fwalk(peprint0);
149         }
150 #endif
ragge
1.1
151         switcho = p->n_op ){
152
153         case NAME:
154                 if ((q = p->n_sp) == NULL)
155                         return p/* Nothing to care about */
156
157                 switch (q->sclass) {
158
159                 case PARAM:
160                 case AUTO:
161                         /* fake up a structure reference */
162                         r = block(REGNILNILPTR+STRTY00);
163                         r->n_lval = 0;
164                         r->n_rval = FPREG;
165                         p = stref(block(STREFrp000));
166                         break;
167
ragge
1.65
168                 case USTATIC:
169                         if (kflag == 0)
170                                 break;
171                         /* FALLTHROUGH */
ragge
1.1
172                 case STATIC:
ragge
1.60
173                         if (kflag == 0) {
174                                 if (q->slevel == 0)
175                                         break;
176                                 p->n_lval = 0;
ragge
1.64
177                         } else if (blevel > 0)
ragge
1.60
178                                 p = picstatic(p);
ragge
1.1
179                         break;
180
181                 case REGISTER:
182                         p->n_op = REG;
183                         p->n_lval = 0;
184                         p->n_rval = q->soffset;
185                         break;
186
ragge
1.60
187                 case EXTERN:
188                 case EXTDEF:
189                         if (kflag == 0)
190                                 break;
ragge
1.64
191                         if (blevel > 0)
ragge
1.60
192                                 p = picext(p);
193                         break;
ragge
1.65
194
195                 case ILABEL:
196                         if (kflag && blevel)
197                                 p = picstatic(p);
198                         break;
ragge
1.60
199                 }
ragge
1.1
200                 break;
201
ragge
1.65
202         case ADDROF:
203                 if (kflag == 0 || blevel == 0)
204                         break;
205                 /* char arrays may end up here */
206                 l = p->n_left;
207                 if (l->n_op != NAME ||
208                     (l->n_type != ARY+CHAR && l->n_type != ARY+WCHAR_TYPE))
209                         break;
210                 l = p;
211                 p = picstatic(p->n_left);
212                 nfree(l);
213                 if (p->n_op != UMUL)
214                         cerror("ADDROF error");
215                 l = p;
216                 p = p->n_left;
217                 nfree(l);
218                 break;
219
ragge
1.62
220         case UCALL:
221         case USTCALL:
ragge
1.60
222                 if (kflag == 0)
223                         break;
ragge
1.62
224                 /* Change to CALL node with ebx as argument */
225                 l = block(REGNILNILINT0MKSUE(INT));
226                 l->n_rval = EBX;
227                 p->n_right = buildtree(ASSIGNl,
228                     tempnode(gotnrINT0MKSUE(INT)));
229                 p->n_op -= (UCALL-CALL);
ragge
1.10
230                 break;
ragge
1.64
231
ragge
1.8
232         case CBRANCH:
233                 l = p->n_left;
234
235                 /*
236                  * Remove unneccessary conversion ops.
237                  */
ragge
1.10
238                 if (clogop(l->n_op) && l->n_left->n_op == SCONV) {
ragge
1.12
239                         if (coptype(l->n_op) != BITYPE)
240                                 break;
ragge
1.8
241                         if (l->n_right->n_op == ICON) {
242                                 r = l->n_left->n_left;
ragge
1.24
243                                 if (r->n_type >= FLOAT && r->n_type <= LDOUBLE)
244                                         break;
ragge
1.59
245                                 if (ISPTR(r->n_type))
246                                         break/* no opt for pointers */
ragge
1.57
247                                 if (toolarge(r->n_typel->n_right->n_lval))
248                                         break;
ragge
1.18
249                                 /* Type must be correct */
ragge
1.19
250                                 t = r->n_type;
ragge
1.8
251                                 nfree(l->n_left);
252                                 l->n_left = r;
ragge
1.19
253                                 l->n_type = t;
254                                 l->n_right->n_type = t;
ragge
1.17
255                         }
ragge
1.8
256                 }
257                 break;
258
ragge
1.1
259         case PCONV:
ragge
1.40
260                 /* Remove redundant PCONV's. Be careful */
ragge
1.1
261                 l = p->n_left;
ragge
1.40
262                 if (l->n_op == ICON) {
263                         l->n_lval = (unsigned)l->n_lval;
264                         goto delp;
265                 }
266                 if (l->n_type < INT || l->n_type == LONGLONG || 
267                     l->n_type == ULONGLONG) {
268                         /* float etc? */
269                         p->n_left = block(SCONVlNIL,
270                             UNSIGNED0MKSUE(UNSIGNED));
271                         break;
272                 }
273                 /* if left is SCONV, cannot remove */
274                 if (l->n_op == SCONV)
ragge
1.1
275                         break;
ragge
1.54
276
277                 /* avoid ADDROF TEMP */
278                 if (l->n_op == ADDROF && l->n_left->n_op == TEMP)
279                         break;
280
ragge
1.40
281                 /* if conversion to another pointer type, just remove */
282                 if (p->n_type > BTMASK && l->n_type > BTMASK)
283                         goto delp;
284                 break;
285
286         delp:   l->n_type = p->n_type;
ragge
1.1
287                 l->n_qual = p->n_qual;
288                 l->n_df = p->n_df;
289                 l->n_sue = p->n_sue;
290                 nfree(p);
291                 p = l;
292                 break;
ragge
1.40
293                 
ragge
1.1
294         case SCONV:
295                 l = p->n_left;
ragge
1.4
296
ragge
1.25
297                 if (p->n_type == l->n_type) {
298                         nfree(p);
299                         return l;
300                 }
301
ragge
1.4
302                 if ((p->n_type & TMASK) == 0 && (l->n_type & TMASK) == 0 &&
pj
1.30
303                     btdims[p->n_type].suesize == btdims[l->n_type].suesize) {
ragge
1.4
304                         if (p->n_type != FLOAT && p->n_type != DOUBLE &&
ragge
1.15
305                             l->n_type != FLOAT && l->n_type != DOUBLE &&
306                             l->n_type != LDOUBLE && p->n_type != LDOUBLE) {
ragge
1.41
307                                 if (l->n_op == NAME || l->n_op == UMUL ||
308                                     l->n_op == TEMP) {
ragge
1.15
309                                         l->n_type = p->n_type;
310                                         nfree(p);
311                                         return l;
312                                 }
ragge
1.4
313                         }
ragge
1.6
314                 }
315
ragge
1.42
316                 if (DEUNSIGN(p->n_type) == INT && DEUNSIGN(l->n_type) == INT &&
317                     coptype(l->n_op) == BITYPE) {
318                         l->n_type = p->n_type;
319                         nfree(p);
320                         return l;
321                 }
322
ragge
1.3
323                 o = l->n_op;
ragge
1.4
324                 m = p->n_type;
ragge
1.1
325
326                 if (o == ICON) {
327                         CONSZ val = l->n_lval;
328
ragge
1.29
329                         if (!ISPTR(m)) /* Pointers don't need to be conv'd */
330                             switch (m) {
ragge
1.52
331                         case BOOL:
332                                 l->n_lval = l->n_lval != 0;
333                                 break;
ragge
1.1
334                         case CHAR:
335                                 l->n_lval = (char)val;
336                                 break;
337                         case UCHAR:
338                                 l->n_lval = val & 0377;
339                                 break;
ragge
1.15
340                         case SHORT:
ragge
1.1
341                                 l->n_lval = (short)val;
342                                 break;
ragge
1.15
343                         case USHORT:
ragge
1.1
344                                 l->n_lval = val & 0177777;
345                                 break;
ragge
1.15
346                         case ULONG:
ragge
1.1
347                         case UNSIGNED:
348                                 l->n_lval = val & 0xffffffff;
349                                 break;
ragge
1.15
350                         case LONG:
ragge
1.1
351                         case INT:
352                                 l->n_lval = (int)val;
353                                 break;
354                         case LONGLONG:
355                                 l->n_lval = (long long)val;
ragge
1.15
356                                 break;
ragge
1.1
357                         case ULONGLONG:
358                                 l->n_lval = val;
359                                 break;
360                         case VOID:
361                                 break;
ragge
1.14
362                         case LDOUBLE:
ragge
1.1
363                         case DOUBLE:
364                         case FLOAT:
365                                 l->n_op = FCON;
366                                 l->n_dcon = val;
367                                 break;
368                         default:
369                                 cerror("unknown type %d"m);
370                         }
371                         l->n_type = m;
ragge
1.44
372                         l->n_sue = MKSUE(m);
ragge
1.1
373                         nfree(p);
374                         return l;
375                 }
ragge
1.17
376                 if (DEUNSIGN(p->n_type) == SHORT &&
377                     DEUNSIGN(l->n_type) == SHORT) {
378                         nfree(p);
379                         p = l;
380                 }
ragge
1.36
381                 if ((p->n_type == CHAR || p->n_type == UCHAR ||
382                     p->n_type == SHORT || p->n_type == USHORT) &&
383                     (l->n_type == FLOAT || l->n_type == DOUBLE ||
384                     l->n_type == LDOUBLE)) {
385                         p = block(SCONVpNILp->n_typep->n_dfp->n_sue);
386                         p->n_left->n_type = INT;
387                         return p;
388                 }
ragge
1.1
389                 break;
390
ragge
1.15
391         case MOD:
392         case DIV:
393                 if (o == DIV && p->n_type != CHAR && p->n_type != SHORT)
394                         break;
ragge
1.16
395                 if (o == MOD && p->n_type != CHAR && p->n_type != SHORT)
ragge
1.15
396                         break;
397                 /* make it an int division by inserting conversions */
398                 p->n_left = block(SCONVp->n_leftNILINT0MKSUE(INT));
399                 p->n_right = block(SCONVp->n_rightNILINT0MKSUE(INT));
400                 p = block(SCONVpNILp->n_type0MKSUE(p->n_type));
401                 p->n_left->n_type = INT;
402                 break;
403
ragge
1.1
404         case PMCONV:
405         case PVCONV:
406                 ifp->n_right->n_op != ICON ) cerror"bad conversion"0);
407                 nfree(p);
408                 return(buildtree(o==PMCONV?MUL:DIVp->n_leftp->n_right));
409
ragge
1.31
410         case FORCE:
ragge
1.32
411                 /* put return value in return reg */
412                 p->n_op = ASSIGN;
413                 p->n_right = p->n_left;
414                 p->n_left = block(REGNILNILp->n_type0MKSUE(INT));
ragge
1.53
415                 p->n_left->n_rval = p->n_left->n_type == BOOL ? 
416                     RETREG(CHAR) : RETREG(p->n_type);
ragge
1.31
417                 break;
ragge
1.39
418
419         case LS:
420         case RS:
421                 /* shift count must be in a char
422                  * unless longlong, where it must be int */
423                 if (p->n_right->n_op == ICON)
424                         break/* do not do anything */
425                 if (p->n_type == LONGLONG || p->n_type == ULONGLONG) {
426                         if (p->n_right->n_type != INT)
427                                 p->n_right = block(SCONVp->n_rightNIL,
428                                     INT0MKSUE(INT));
429                         break;
430                 }
431                 if (p->n_right->n_type == CHAR || p->n_right->n_type == UCHAR)
432                         break;
433                 p->n_right = block(SCONVp->n_rightNIL,
434                     CHAR0MKSUE(CHAR));
435                 break;
ragge
1.1
436         }
ragge
1.54
437 #ifdef PCC_DEBUG
438         if (xdebug) {
439                 printf("clocal end: %p\n"p);
440                 fwalk(peprint0);
441         }
442 #endif
ragge
1.1
443         return(p);
444 }
445
ragge
1.64
446 /*
447  * Change CALL references to either direct (static) or PLT.
448  */
449 static void
450 fixnames(NODE *p)
451 {
452         struct symtab *sp;
ragge
1.65
453         struct suedef *sue;
ragge
1.64
454         NODE *q;
455         char *c;
456         int isu;
457
458         if ((cdope(p->n_op) & CALLFLG) == 0)
459                 return;
460         isu = 0;
461         q = p->n_left;
ragge
1.65
462         sue = q->n_sue;
ragge
1.64
463         if (q->n_op == UMUL)
464                 q = q->n_leftisu = 1;
465         if (q->n_op == PLUS && q->n_left->n_op == TEMP &&
466             q->n_right->n_op == ICON) {
467                 sp = q->n_right->n_sp;
468
ragge
1.65
469                 if (sp == NULL)
470                         return/* nothing to do */
ragge
1.64
471                 if (sp->sclass == STATIC && !ISFTN(sp->stype))
472                         return/* function pointer */
473
474                 if (sp->sclass != STATIC && sp->sclass != EXTERN &&
475                     sp->sclass != EXTDEF)
476                         cerror("fixnames");
477
478                 if ((c = strstr(sp->sname"@GOT")) == NULL)
479                         cerror("fixnames2");
480                 if (isu) {
481                         memcpy(c"@PLT"sizeof("@PLT"));
482                 } else
483                         *c = 0;
484                 nfree(q->n_left);
485                 q = q->n_right;
486                 if (isu)
487                         nfree(p->n_left->n_left);
488                 nfree(p->n_left);
489                 p->n_left = q;
ragge
1.65
490                 q->n_sue = sue;
ragge
1.64
491         }
492 }
493
ragge
1.1
494 void
495 myp2tree(NODE *p)
496 {
ragge
1.64
497         if (kflag)
498                 walkf(pfixnames);
ragge
1.1
499 }
500
501 /*ARGSUSED*/
502 int
503 andable(NODE *p)
504 {
ragge
1.64
505         return(1);      /* all names can have & taken on them */
ragge
1.1
506 }
507
508 /*
509  * at the end of the arguments of a ftn, set the automatic offset
510  */
511 void
512 cendarg()
513 {
514         autooff = AUTOINIT;
515 }
516
517 /*
ragge
1.36
518  * Return 1 if a variable of type type is OK to put in register.
519  */
520 int
521 cisreg(TWORD t)
522 {
523         if (t == FLOAT || t == DOUBLE || t == LDOUBLE)
524                 return 0/* not yet */
525         return 1;
526 }
527
528 /*
ragge
1.1
529  * return a node, for structure references, which is suitable for
530  * being added to a pointer of type t, in order to be off bits offset
531  * into a structure
532  * t, d, and s are the type, dimension offset, and sizeoffset
533  * For pdp10, return the type-specific index number which calculation
534  * is based on its size. For example, short a[3] would return 3.
535  * Be careful about only handling first-level pointers, the following
536  * indirections must be fullword.
537  */
538 NODE *
539 offcon(OFFSZ offTWORD tunion dimfun *dstruct suedef *sue)
540 {
541         register NODE *p;
542
543         if (xdebug)
544                 printf("offcon: OFFSZ %lld type %x dim %p siz %d\n",
545                     offtdsue->suesize);
546
547         p = bcon(0);
548         p->n_lval = off/SZCHAR/* Default */
549         return(p);
550 }
551
552 /*
553  * Allocate off bits on the stack.  p is a tree that when evaluated
ragge
1.45
554  * is the multiply count for off, t is a storeable node where to write
ragge
1.1
555  * the allocated address.
556  */
557 void
558 spalloc(NODE *tNODE *pOFFSZ off)
559 {
560         NODE *sp;
561
ragge
1.45
562         p = buildtree(MULpbcon(off/SZCHAR)); /* XXX word alignment? */
563
564         /* sub the size from sp */
ragge
1.55
565         sp = block(REGNILNILp->n_type0MKSUE(INT));
ragge
1.45
566         sp->n_lval = 0;
567         sp->n_rval = STKREG;
568         ecomp(buildtree(MINUSEQspp));
ragge
1.1
569
570         /* save the address of sp */
571         sp = block(REGNILNILPTR+INTt->n_dft->n_sue);
572         sp->n_lval = 0;
573         sp->n_rval = STKREG;
574         t->n_type = sp->n_type;
575         ecomp(buildtree(ASSIGNtsp)); /* Emit! */
576
577 }
578
ragge
1.49
579 #if 0
ragge
1.48
580 /*
581  * Print out an integer constant of size size.
582  * can only be sizes <= SZINT.
583  */
ragge
1.47
584 void
585 indata(CONSZ valint size)
586 {
587         switch (size) {
588         case SZCHAR:
589                 printf("\t.byte %d\n", (int)val & 0xff);
590                 break;
591         case SZSHORT:
592                 printf("\t.word %d\n", (int)val & 0xffff);
593                 break;
594         case SZINT:
595                 printf("\t.long %d\n", (int)val & 0xffffffff);
596                 break;
597         default:
598                 cerror("indata");
599         }
600 }
ragge
1.49
601 #endif
ragge
1.47
602
ragge
1.1
603 /*
ragge
1.48
604  * Print out a string of characters.
605  * Assume that the assembler understands C-style escape
606  * sequences.  Location is already set.
607  */
608 void
609 instring(char *str)
610 {
611         char *s;
612
mickey
1.61
613         /* be kind to assemblers and avoid long strings */
ragge
1.48
614         printf("\t.ascii \"");
ragge
1.51
615         for (s = str; *s != 0; ) {
616                 if (*s++ == '\\') {
ragge
1.48
617                         (void)esccon(&s);
ragge
1.51
618                 }
ragge
1.48
619                 if (s - str > 64) {
620                         fwrite(str1s - strstdout);
621                         printf("\"\n\t.ascii \"");
622                         str = s;
623                 }
624         }
625         fwrite(str1s - strstdout);
626         printf("\\0\"\n");
627 }
628
ragge
1.49
629 static int inbitsinval;
630
631 /*
632  * set fsz bits in sequence to zero.
633  */
634 void
635 zbits(OFFSZ offint fsz)
636 {
637         int m;
638
639         if (idebug)
ragge
1.51
640                 printf("zbits off %lld, fsz %d inbits %d\n"offfszinbits);
ragge
1.49
641         if ((m = (inbits % SZCHAR))) {
642                 m = SZCHAR - m;
643                 if (fsz < m) {
ragge
1.51
644                         inbits += fsz;
ragge
1.49
645                         return;
646                 } else {
647                         fsz -= m;
648                         printf("\t.byte %d\n"inval);
649                         inval = inbits = 0;
650                 }
651         }
652         if (fsz >= SZCHAR) {
653                 printf("\t.zero %d\n"fsz/SZCHAR);
ragge
1.51
654                 fsz -= (fsz/SZCHAR) * SZCHAR;
ragge
1.49
655         }
656         if (fsz) {
657                 inval = 0;
658                 inbits = fsz;
659         }
660 }
661
662 /*
663  * Initialize a bitfield.
664  */
665 void
666 infld(CONSZ offint fszCONSZ val)
667 {
668         if (idebug)
ragge
1.51
669                 printf("infld off %lld, fsz %d, val %lld inbits %d\n",
670                     offfszvalinbits);
ragge
1.56
671         val &= ((CONSZ)1 << fsz)-1;
ragge
1.49
672         while (fsz + inbits >= SZCHAR) {
673                 inval |= (val << inbits);
674                 printf("\t.byte %d\n"inval & 255);
675                 fsz -= (SZCHAR - inbits);
676                 val >>= (SZCHAR - inbits);
677                 inval = inbits = 0;
678         }
ragge
1.51
679         if (fsz) {
680                 inval |= (val << inbits);
681                 inbits += fsz;
682         }
ragge
1.49
683 }
684
ragge
1.48
685 /*
ragge
1.46
686  * print out a constant node, may be associated with a label.
687  * Do not free the node after use.
ragge
1.49
688  * off is bit offset from the beginning of the aggregate
689  * fsz is the number of bits this is referring to
ragge
1.21
690  */
691 void
ragge
1.49
692 ninval(CONSZ offint fszNODE *p)
ragge
1.21
693 {
ragge
1.46
694         union { float fdouble dlong double lint i[3]; } u;
ragge
1.24
695         struct symtab *q;
ragge
1.64
696         char *c;
ragge
1.23
697         TWORD t;
ragge
1.46
698         int i;
ragge
1.23
699
700         t = p->n_type;
701         if (t > BTMASK)
702                 t = INT/* pointer */
703
ragge
1.65
704         while (p->n_op == SCONV || p->n_op == PCONV) {
705                 NODE *l = p->n_left;
706                 l->n_type = p->n_type;
707                 p = l;
708         }
709
ragge
1.64
710         if (kflag && (p->n_op == PLUS || p->n_op == UMUL)) {
711                 if (p->n_op == UMUL)
712                         p = p->n_left;
713                 p = p->n_right;
714                 q = p->n_sp;
715                 if ((c = strstr(q->sname"@GOT")) != NULL)
716                         *c = 0/* ignore GOT ref here */
717         }
ragge
1.46
718         if (p->n_op != ICON && p->n_op != FCON)
ragge
1.40
719                 cerror("ninval: init node not constant");
720
ragge
1.49
721         if (p->n_op == ICON && p->n_sp != NULL && DEUNSIGN(t) != INT)
ragge
1.46
722                 uerror("element not constant");
723
ragge
1.23
724         switch (t) {
ragge
1.21
725         case LONGLONG:
726         case ULONGLONG:
ragge
1.46
727                 i = (p->n_lval >> 32);
728                 p->n_lval &= 0xffffffff;
ragge
1.51
729                 p->n_type = INT;
ragge
1.49
730                 ninval(off32p);
ragge
1.46
731                 p->n_lval = i;
ragge
1.49
732                 ninval(off+3232p);
ragge
1.21
733                 break;
734         case INT:
735         case UNSIGNED:
736                 printf("\t.long 0x%x", (int)p->n_lval);
ragge
1.24
737                 if ((q = p->n_sp) != NULL) {
738                         if ((q->sclass == STATIC && q->slevel > 0) ||
739                             q->sclass == ILABEL) {
740                                 printf("+" LABFMTq->soffset);
ragge
1.21
741                         } else
ragge
1.24
742                                 printf("+%s"exname(q->sname));
ragge
1.21
743                 }
744                 printf("\n");
745                 break;
ragge
1.46
746         case SHORT:
747         case USHORT:
748                 printf("\t.short 0x%x\n", (int)p->n_lval & 0xffff);
749                 break;
ragge
1.52
750         case BOOL:
751                 if (p->n_lval > 1)
752                         p->n_lval = p->n_lval != 0;
753                 /* FALLTHROUGH */
ragge
1.46
754         case CHAR:
755         case UCHAR:
ragge
1.50
756                 printf("\t.byte %d\n", (int)p->n_lval & 0xff);
ragge
1.46
757                 break;
758         case LDOUBLE:
759                 u.i[2] = 0;
760                 u.l = (long double)p->n_dcon;
761                 printf("\t.long\t0x%x,0x%x,0x%x\n"u.i[0], u.i[1], u.i[2]);
762                 break;
763         case DOUBLE:
764                 u.d = (double)p->n_dcon;
765                 printf("\t.long\t0x%x,0x%x\n"u.i[0], u.i[1]);
766                 break;
767         case FLOAT:
768                 u.f = (float)p->n_dcon;
769                 printf("\t.long\t0x%x\n"u.i[0]);
770                 break;
ragge
1.21
771         default:
772                 cerror("ninval");
773         }
774 }
775
ragge
1.46
776 #if 0
ragge
1.21
777 /*
ragge
1.17
778  * print out an integer.
ragge
1.1
779  */
780 void
ragge
1.17
781 inval(CONSZ word)
ragge
1.1
782 {
ragge
1.17
783         word &= 0xffffffff;
784         printf("        .long 0x%llx\n"word);
ragge
1.1
785 }
786
ragge
1.17
787 /* output code to initialize a floating point value */
ragge
1.1
788 /* the proper alignment has been obtained */
789 void
ragge
1.17
790 finval(NODE *p)
ragge
1.1
791 {
ragge
1.43
792         union { float fdouble dlong double lint i[3]; } u;
793
ragge
1.17
794         switch (p->n_type) {
795         case LDOUBLE:
ragge
1.43
796                 u.i[2] = 0;
797                 u.l = (long double)p->n_dcon;
798                 printf("\t.long\t0x%x,0x%x,0x%x\n"u.i[0], u.i[1], u.i[2]);
ragge
1.14
799                 break;
ragge
1.17
800         case DOUBLE:
ragge
1.43
801                 u.d = (double)p->n_dcon;
802                 printf("\t.long\t0x%x,0x%x\n"u.i[0], u.i[1]);
ragge
1.14
803                 break;
ragge
1.17
804         case FLOAT:
ragge
1.43
805                 u.f = (float)p->n_dcon;
806                 printf("\t.long\t0x%x\n"u.i[0]);
ragge
1.14
807                 break;
808         }
ragge
1.1
809 }
ragge
1.46
810 #endif
ragge
1.1
811
812 /* make a name look like an external name in the local machine */
813 char *
814 exname(char *p)
815 {
816         if (p == NULL)
817                 return "";
818         return p;
819 }
820
821 /*
822  * map types which are not defined on the local machine
823  */
ragge
1.15
824 TWORD
ragge
1.1
825 ctype(TWORD type)
826 {
827         switch (BTYPE(type)) {
828         case LONG:
829                 MODTYPE(type,INT);
830                 break;
831
832         case ULONG:
833                 MODTYPE(type,UNSIGNED);
ragge
1.13
834
ragge
1.1
835         }
836         return (type);
837 }
838
pj
1.30
839 void
840 calldec(NODE *pNODE *q
841 {
842 }
843
844 void
845 extdec(struct symtab *q)
846 {
847 }
848
ragge
1.1
849 /* make a common declaration for id, if reasonable */
850 void
851 commdec(struct symtab *q)
852 {
853         int off;
854
855         off = tsize(q->stypeq->sdfq->ssue);
ragge
1.8
856         off = (off+(SZCHAR-1))/SZCHAR;
ragge
1.7
857 #ifdef GCC_COMPAT
858         printf("        .comm %s,0%o\n"gcc_findname(q), off);
859 #else
ragge
1.1
860         printf("        .comm %s,0%o\n"exname(q->sname), off);
ragge
1.7
861 #endif
ragge
1.1
862 }
863
864 /* make a local common declaration for id, if reasonable */
865 void
866 lcommdec(struct symtab *q)
867 {
868         int off;
869
870         off = tsize(q->stypeq->sdfq->ssue);
ragge
1.8
871         off = (off+(SZCHAR-1))/SZCHAR;
ragge
1.1
872         if (q->slevel == 0)
ragge
1.7
873 #ifdef GCC_COMPAT
874                 printf("        .lcomm %s,0%o\n"gcc_findname(q), off);
875 #else
ragge
1.1
876                 printf("        .lcomm %s,0%o\n"exname(q->sname), off);
ragge
1.7
877 #endif
ragge
1.1
878         else
879                 printf("        .lcomm " LABFMT ",0%o\n"q->soffsetoff);
880 }
ragge
1.22
881
882 /*
883  * print a (non-prog) label.
884  */
885 void
886 deflab1(int label)
887 {
888         printf(LABFMT ":\n"label);
889 }
890
ragge
1.28
891 static char *loctbl[] = { "text""data""section .rodata""section .rodata" };
ragge
1.27
892
ragge
1.23
893 void
894 setloc1(int locc)
895 {
896         if (locc == lastloc)
897                 return;
898         lastloc = locc;
ragge
1.27
899         printf("        .%s\n"loctbl[locc]);
ragge
1.23
900 }
ragge
1.48
901
ragge
1.49
902 #if 0
ragge
1.48
903 int
904 ftoint(NODE *pCONSZ **c)
905 {
906         static CONSZ cc[3];
907         union { float fdouble dlong double lint i[3]; } u;
908         int n;
909
910         switch (p->n_type) {
911         case LDOUBLE:
912                 u.i[2] = 0;
913                 u.l = (long double)p->n_dcon;
914                 n = SZLDOUBLE;
915                 break;
916         case DOUBLE:
917                 u.d = (double)p->n_dcon;
918                 n = SZDOUBLE;
919                 break;
920         case FLOAT:
921                 u.f = (float)p->n_dcon;
922                 n = SZFLOAT;
923                 break;
924         }
925         cc[0] = u.i[0];
926         cc[1] = u.i[1];
927         cc[2] = u.i[2];
928         *c = cc;
929         return n;
930 }
ragge
1.49
931 #endif
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-02 21:06 +0200