Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20120422210740

Diff

Diff from 1.37 to:

Annotations

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

Annotated File View

plunky
1.37
1 /*      $Id: local.c,v 1.37 2012/04/22 21:07:40 plunky Exp $    */
mickey
1.10
2 /*      $OpenBSD: local.c,v 1.2 2007/11/18 17:39:55 ragge Exp $ */
mickey
1.1
3
4 /*
5  * Copyright (c) 2007 Michael Shalayeff
6  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30
31 #include "pass1.h"
32 #include "pass2.h"
33
34 /*      this file contains code which is dependent on the target machine */
35
mickey
1.27
36 #define IALLOC(sz)      (isinlining ? permalloc(sz) : tmpalloc(sz))
37
mickey
1.18
38 struct symtab *makememcpy(void);
mickey
1.27
39 char *section2string(char *, int);
mickey
1.18
40
mickey
1.1
41 /* clocal() is called to do local transformations on
42  * an expression tree preparitory to its being
43  * written out in intermediate code.
44  *
45  * the major essential job is rewriting the
46  * automatic variables and arguments in terms of
47  * REG and OREG nodes
48  * conversion ops which are not necessary are also clobbered here
49  * in addition, any special features (such as rewriting
50  * exclusive or) are easily handled here as well
51  */
52 NODE *
53 clocal(NODE *p)
54 {
mickey
1.18
55         register struct symtab *q, *sp;
mickey
1.5
56         register NODE *r, *l, *s;
mickey
1.1
57         register int omrn;
ragge
1.25
58         char *chname[16], *n;
mickey
1.1
59         TWORD t;
60
61 #ifdef PCC_DEBUG
62         if (xdebug) {
63                 printf("clocal: %p\n"p);
64                 fwalk(peprint0);
65         }
66 #endif
mickey
1.10
67         switch (o = p->n_op) {
mickey
1.1
68
69         case NAME:
70                 if ((q = p->n_sp) == NULL)
71                         break;  /* Nothing to care about */
72
73                 switch (q->sclass) {
74
75                 case PARAM:
76                         /* first four integral args are in regs */
77                         rn = (q->soffset >> 5) - 8;
78                         if (rn < 4) {
79                                 r = block(REGNILNILp->n_type00);
80                                 r->n_lval = 0;
81                                 switch (p->n_type) {
82                                 case FLOAT:
mickey
1.10
83                                         r->n_rval = FR7L - rn;
mickey
1.1
84                                         break;
85                                 case DOUBLE:
86                                 case LDOUBLE:
mickey
1.10
87                                         r->n_rval = FR6 - rn;
mickey
1.1
88                                         break;
89                                 case LONGLONG:
90                                 case ULONGLONG:
91                                         r->n_rval = AD1 - rn / 2;
92                                         break;
93                                 default:
94                                         r->n_rval = ARG0 - rn;
95                                 }
96                                 r->n_sue = p->n_sue;
97                                 p->n_sue = NULL;
98                                 nfree(p);
99                                 p = r;
100                                 break;
101                         }
102                         /* FALLTHROUGH */
103
104                 case AUTO:
105                         /* fake up a structure reference */
106                         r = block(REGNILNILPTR+STRTY00);
107                         r->n_lval = 0;
108                         r->n_rval = FPREG;
109                         p = stref(block(STREFrp000));
110                         break;
111
112                 case REGISTER:
113                         p->n_op = REG;
114                         p->n_lval = 0;
115                         p->n_rval = q->soffset;
116                         break;
117
118                 case STATIC:
119                 case EXTERN:
mickey
1.20
120                         if (p->n_sp->sflags & SSTRING)
121                                 break;
122
ragge
1.25
123                         n = p->n_sp->soname ? p->n_sp->soname : p->n_sp->sname;
124                         if (strncmp(n"__builtin"9) == 0)
mickey
1.19
125                                 break;
126
mickey
1.1
127                         l = block(REGNILNILINT00);
128                         l->n_lval = 0;
129                         l->n_rval = R1;
130                         l = block(ASSIGNlpINT00);
stefan
1.12
131                         r = xbcon(0p->n_spINT);
mickey
1.1
132                         p = block(UMUL,
133                             block(PLUSlrINT00),
mickey
1.8
134                             NILp->n_typep->n_dfp->n_sue);
mickey
1.1
135                         break;
136                 }
137                 break;
138
139         case ADDROF:
mickey
1.21
140                 l = p->n_left;
141                 if (!l->n_sp)
142                         break;
143
144                 if (l->n_sp->sclass != EXTERN &&
145                     l->n_sp->sclass != STATIC &&
146                     l->n_sp->sclass != USTATIC &&
147                     l->n_sp->sclass != EXTDEF)
mickey
1.1
148                         break;
149
150                 l = block(REGNILNILINT00);
151                 l->n_lval = 0;
152                 l->n_rval = R1;
mickey
1.10
153                 l = block(ASSIGNlp->n_leftINT00);
stefan
1.12
154                 r = xbcon(0p->n_left->n_spINT);
mickey
1.10
155                 l = block(PLUSlrp->n_typep->n_dfp->n_sue);
156                 nfree(p);
157                 p = l;
mickey
1.1
158                 break;
159
160         case CBRANCH:
161                 l = p->n_left;
162
163                 /*
ragge
1.22
164                  * Remove unnecessary conversion ops.
mickey
1.1
165                  */
166                 if (clogop(l->n_op) && l->n_left->n_op == SCONV) {
167                         if (coptype(l->n_op) != BITYPE)
168                                 break;
169                         if (l->n_right->n_op == ICON) {
170                                 r = l->n_left->n_left;
171                                 if (r->n_type >= FLOAT && r->n_type <= LDOUBLE)
172                                         break;
173                                 /* Type must be correct */
174                                 t = r->n_type;
175                                 nfree(l->n_left);
176                                 l->n_left = r;
177                                 l->n_type = t;
178                                 l->n_right->n_type = t;
179                         }
180                 }
181                 break;
182
183         case PCONV:
184                 /* Remove redundant PCONV's. Be careful */
185                 l = p->n_left;
186                 if (l->n_op == ICON) {
187                         l->n_lval = (unsigned)l->n_lval;
188                         goto delp;
189                 }
mickey
1.27
190                 if (l->n_type < INT || l->n_type == LONGLONG ||
mickey
1.1
191                     l->n_type == ULONGLONG) {
192                         /* float etc? */
ragge
1.29
193                         p->n_left = block(SCONVlNILUNSIGNED00);
mickey
1.1
194                         break;
195                 }
196                 /* if left is SCONV, cannot remove */
197                 if (l->n_op == SCONV)
198                         break;
199
200                 /* avoid ADDROF TEMP */
201                 if (l->n_op == ADDROF && l->n_left->n_op == TEMP)
202                         break;
203
204                 /* if conversion to another pointer type, just remove */
205                 if (p->n_type > BTMASK && l->n_type > BTMASK)
206                         goto delp;
207                 break;
208
209         delp:   l->n_type = p->n_type;
210                 l->n_qual = p->n_qual;
211                 l->n_df = p->n_df;
212                 l->n_sue = p->n_sue;
213                 nfree(p);
214                 p = l;
215                 break;
mickey
1.27
216
mickey
1.1
217         case SCONV:
218                 l = p->n_left;
219
220                 if (p->n_type == l->n_type) {
221                         nfree(p);
222                         p = l;
223                         break;
224                 }
225
226                 if ((p->n_type & TMASK) == 0 && (l->n_type & TMASK) == 0 &&
227                     btdims[p->n_type].suesize == btdims[l->n_type].suesize) {
228                         if (p->n_type != FLOAT && p->n_type != DOUBLE &&
229                             l->n_type != FLOAT && l->n_type != DOUBLE &&
230                             l->n_type != LDOUBLE && p->n_type != LDOUBLE) {
231                                 if (l->n_op == UMUL || l->n_op == TEMP ||
232                                     l->n_op == NAME) {
233                                         l->n_type = p->n_type;
234                                         nfree(p);
235                                         p = l;
236                                         break;
237                                 }
238                         }
239                 }
240
241                 if (DEUNSIGN(p->n_type) == INT && DEUNSIGN(l->n_type) == INT &&
242                     coptype(l->n_op) == BITYPE) {
243                         l->n_type = p->n_type;
244                         nfree(p);
245                         p = l;
246                         break;
247                 }
248
249                 o = l->n_op;
250                 m = p->n_type;
251
252                 if (o == ICON) {
253                         CONSZ val = l->n_lval;
254
255                         if (!ISPTR(m)) /* Pointers don't need to be conv'd */
256                             switch (m) {
257                         case BOOL:
258                                 l->n_lval = l->n_lval != 0;
259                                 break;
260                         case CHAR:
261                                 l->n_lval = (char)val;
262                                 break;
263                         case UCHAR:
264                                 l->n_lval = val & 0377;
265                                 break;
266                         case SHORT:
267                                 l->n_lval = (short)val;
268                                 break;
269                         case USHORT:
270                                 l->n_lval = val & 0177777;
271                                 break;
272                         case ULONG:
273                         case UNSIGNED:
274                                 l->n_lval = val & 0xffffffff;
275                                 break;
276                         case LONG:
277                         case INT:
278                                 l->n_lval = (int)val;
279                                 break;
280                         case LONGLONG:
281                                 l->n_lval = (long long)val;
282                                 break;
283                         case ULONGLONG:
284                                 l->n_lval = val;
285                                 break;
286                         case VOID:
287                                 break;
288                         case LDOUBLE:
289                         case DOUBLE:
290                         case FLOAT:
291                                 l->n_op = FCON;
292                                 l->n_dcon = val;
293                                 break;
294                         default:
295                                 cerror("unknown type %d"m);
296                         }
297                         l->n_type = m;
ragge
1.29
298                         l->n_sue = 0;
mickey
1.1
299                         nfree(p);
300                         return l;
mickey
1.16
301                 } else if (l->n_op == FCON) {
302                         l->n_lval = l->n_dcon;
303                         l->n_sp = NULL;
304                         l->n_op = ICON;
305                         l->n_type = m;
ragge
1.29
306                         l->n_sue = 0;
mickey
1.16
307                         nfree(p);
308                         return clocal(l);
mickey
1.1
309                 }
mickey
1.16
310
mickey
1.1
311                 if (DEUNSIGN(p->n_type) == SHORT &&
312                     DEUNSIGN(l->n_type) == SHORT) {
313                         nfree(p);
314                         p = l;
315                 }
316                 if ((p->n_type == CHAR || p->n_type == UCHAR ||
317                     p->n_type == SHORT || p->n_type == USHORT) &&
318                     (l->n_type == FLOAT || l->n_type == DOUBLE ||
319                     l->n_type == LDOUBLE)) {
320                         p = block(SCONVpNILp->n_typep->n_dfp->n_sue);
321                         p->n_left->n_type = INT;
322                         break;
323                 }
324                 break;
325
326         case MOD:
327         case DIV:
328                 if (o == DIV && p->n_type != CHAR && p->n_type != SHORT)
329                         break;
330                 if (o == MOD && p->n_type != CHAR && p->n_type != SHORT)
331                         break;
332                 /* make it an int division by inserting conversions */
ragge
1.29
333                 p->n_left = block(SCONVp->n_leftNILINT00);
334                 p->n_right = block(SCONVp->n_rightNILINT00);
335                 p = block(SCONVpNILp->n_type00);
mickey
1.1
336                 p->n_left->n_type = INT;
337                 break;
338
mickey
1.5
339         case LS:
340         case RS:
341                 /* shift count must be in an int */
342                 if (p->n_right->n_op == ICON || p->n_right->n_lval <= 32)
343                         break;  /* do not do anything */
344                 if (p->n_right->n_type != INT || p->n_right->n_lval > 32)
ragge
1.29
345                         p->n_right = block(SCONVp->n_rightNILINT00);
mickey
1.5
346                 break;
347
348 #if 0
349         case FLD:
350                 /* already rewritten (in ASSIGN) */
351                 if (p->n_left->n_op == TEMP)
352                         break;
353
354                 r = tempnode(0p->n_typep->n_dfp->n_sue);
355                 l = block(ASSIGNrp->n_leftp->n_typep->n_dfp->n_sue);
356                 p->n_left = tcopy(r);
357                 p = block(COMOPlpp->n_typep->n_dfp->n_sue);
358                 break;
359 #endif
360
mickey
1.1
361         case FORCE:
362                 /* put return value in return reg */
363                 p->n_op = ASSIGN;
364                 p->n_right = p->n_left;
mickey
1.5
365                 p->n_left = block(REGNILNILp->n_typep->n_dfp->n_sue);
mickey
1.27
366                 p->n_left->n_rval = p->n_left->n_type == BOOL ?
mickey
1.1
367                     RETREG(CHAR) : RETREG(p->n_type);
mickey
1.5
368                 if (p->n_right->n_op != FLD)
369                         break;
mickey
1.1
370                 break;
371
mickey
1.5
372         case ASSIGN:
mickey
1.9
373                 r = p->n_right;
374                 l = p->n_left;
375
376                 /* rewrite ICON#0 into %r0 */
377                 if (r->n_op == ICON && r->n_lval == 0 &&
378                     (l->n_op == REG || l->n_op == OREG)) {
379                         r->n_op = REG;
380                         r->n_rval = R0;
381                 }
382
383                 /* rewrite FCON#0 into %fr0 */
384                 if (r->n_op == FCON && r->n_lval == 0 && l->n_op == REG) {
385                         r->n_op = REG;
386                         r->n_rval = r->n_type == FLOATFR0L : FR0;
387                 }
388
mickey
1.5
389                 if (p->n_left->n_op != FLD)
390                         break;
mickey
1.10
391
mickey
1.5
392                 r = tempnode(0l->n_typel->n_dfl->n_sue);
393                 p = block(COMOP,
394                     block(ASSIGNrl->n_leftl->n_typel->n_dfl->n_sue),
395                     pp->n_typep->n_dfp->n_sue);
396                 s = tcopy(l->n_left);
397                 p = block(COMOPp,
398                     block(ASSIGNstcopy(r), l->n_typel->n_dfl->n_sue),
399                     p->n_typep->n_dfp->n_sue);
400                 l->n_left = tcopy(r);
mickey
1.1
401                 break;
mickey
1.18
402
403         case STASG:
404                 /* memcpy(left, right, size) */
405                 sp = makememcpy();
406                 l = p->n_left;
407                 /* guess struct return */
408                 if (l->n_op == NAME && ISFTN(l->n_sp->stype)) {
ragge
1.29
409                         l = block(REGNILNILVOID|PTR00);
mickey
1.18
410                         l->n_lval = 0;
411                         l->n_rval = RET0;
412                 } else if (l->n_op == UMUL)
413                         l = tcopy(l->n_left);
414                 else if (l->n_op == NAME)
ragge
1.29
415                         l = block(ADDROF,tcopy(l),NIL,PTR|STRTY,0,0);
mickey
1.18
416                 l = block(CALLblock(ADDROF,
ragge
1.29
417                     (s = block(NAMENILNILFTN00)),
418                     NILPTR|FTN00),
mickey
1.18
419                     block(CMblock(CMltcopy(p->n_right),
ragge
1.29
420                     STRTY|PTR00),
421                     (r = block(ICONNILNILINT00)), 000),
422                     INT00);
mickey
1.18
423                 r->n_lval = p->n_sue->suesize/SZCHAR;
424                 s->n_sp = sp;
425                 s->n_df = s->n_sp->sdf;
426                 defid(sEXTERN);
427                 tfree(p);
428                 p = l;
429                 p->n_left = clocal(p->n_left);
430                 p->n_right = clocal(p->n_right);
431                 calldec(p->n_leftp->n_right);
432                 funcode(p);
433                 break;
434
435         case STARG:
436                 /* arg = memcpy(argN-size, src, size) */
437                 sp = makememcpy();
438                 l = block(CALLblock(ADDROF,
ragge
1.29
439                     (s = block(NAMENILNILFTN00)),NIL,0,0,0),
mickey
1.18
440                     block(CMblock(CMtcopy(p), tcopy(p->n_left), 000),
ragge
1.29
441                     (r = block(ICONNILNILINT00)), 000),
442                     INT00);
mickey
1.18
443                 r->n_lval = p->n_sue->suesize/SZCHAR;
444                 s->n_sp = sp;
445                 s->n_df = s->n_sp->sdf;
446                 defid(sEXTERN);
447                 tfree(p);
448                 p = l;
449                 p->n_left = clocal(p->n_left);
450                 calldec(p->n_leftp->n_right);
451                 funcode(p);
452                 break;
453
454         case STCALL:
455         case CALL:
456                 for (r = p->n_rightr->n_op == CMr = r->n_left) {
457                         if (r->n_right->n_op == ASSIGN &&
458                             r->n_right->n_right->n_op == CALL) {
459                                 s = r->n_right->n_right;
460                                 l = tempnode(0s->n_types->n_dfs->n_sue);
461                                 ecode(buildtree(ASSIGNls));
462                                 r->n_right->n_right = tcopy(l);
463                         }
464                         if (r->n_left->n_op == ASSIGN &&
465                             r->n_left->n_right->n_op == CALL) {
466                                 s = r->n_left->n_right;
467                                 l = tempnode(0s->n_types->n_dfs->n_sue);
468                                 ecode(buildtree(ASSIGNls));
469                                 r->n_left->n_right = tcopy(l);
470                         }
471                 }
472                 break;
mickey
1.1
473         }
mickey
1.11
474
475         /* second pass - rewrite long ops */
476         switch (o) {
477         case DIV:
478         case MOD:
479         case MUL:
480         case RS:
481         case LS:
482                 if (!(p->n_type == LONGLONG || p->n_type == ULONGLONG) ||
483                     !((o == DIV || o == MOD || o == MUL) &&
484                       p->n_type < FLOAT))
485                         break;
486                 if (o == DIV && p->n_type == ULONGLONGch = "udiv";
487                 else if (o == DIVch = "div";
488                 else if (o == MULch = "mul";
489                 else if (o == MOD && p->n_type == ULONGLONGch = "umod";
490                 else if (o == MODch = "mod";
491                 else if (o == RS && p->n_type == ULONGLONGch = "lshr";
492                 else if (o == RSch = "ashr";
493                 else if (o == LSch = "ashl";
494                 else break;
495                 snprintf(namesizeof(name), "__%sdi3"ch);
496                 p->n_right = block(CMp->n_leftp->n_right000);
497                 p->n_left = block(ADDROF,
ragge
1.29
498                     block(NAMENILNILFTN00), NILPTR|FTN00);
mickey
1.11
499                 p->n_left->n_left->n_sp = lookup(addname(name), 0);
500                 defid(p->n_left->n_leftEXTERN);
501                 p->n_left = clocal(p->n_left);
mickey
1.14
502                 calldec(p->n_leftp->n_right);
mickey
1.11
503                 p->n_op = CALL;
504                 funcode(p);
505                 break;
506         }
507
mickey
1.1
508 #ifdef PCC_DEBUG
509         if (xdebug) {
510                 printf("clocal end: %p\n"p);
511                 fwalk(peprint0);
512         }
513 #endif
514         return(p);
515 }
516
mickey
1.18
517 struct symtab *
plunky
1.37
518 makememcpy(void)
mickey
1.18
519 {
520         NODE *memcpy, *args, *t, *u;
521         struct symtab *sp;
522
523         /* TODO check that it's a func proto */
524         if ((sp = lookup(addname("memcpy"), SNORMAL)))
525                 return sp;
526
ragge
1.29
527         memcpy = block(NAMENILNIL000);
mickey
1.18
528         memcpy->n_sp = sp = lookup(addname("memcpy"), SNORMAL);
529         defid(memcpyEXTERN);
530
531         args = block(CMblock(CM,
ragge
1.29
532             block(NAMENILNILVOID|PTR00),
533             block(NAMENILNILVOID|PTR00), 000),
534             block(NAMENILNILLONG00), 000);
mickey
1.18
535
536         tymerge(t = block(TYPENILNILVOID|PTR00),
537             (u = block(UMULblock(CALLmemcpyargsLONG00),
538             NILLONG00)));
539         tfree(t);
540         tfree(u);
541
542         return sp;
543 }
544
mickey
1.1
545 void
546 myp2tree(NODE *p)
547 {
ragge
1.24
548         struct symtab *sp;
mickey
1.18
549         int o = p->n_op;
ragge
1.13
550
mickey
1.27
551         if (o != FCON)
ragge
1.13
552                 return;
553
554         /* Write float constants to memory */
555         /* Should be volontary per architecture */
mickey
1.27
556
mickey
1.17
557 #if 0
ragge
1.13
558         setloc1(RDATA);
559         defalign(p->n_type == FLOAT ? ALFLOAT : p->n_type == DOUBLE ?
560             ALDOUBLE : ALLDOUBLE );
mickey
1.27
561         deflab1(i = getlab());
mickey
1.17
562 #endif
ragge
1.24
563         sp = inlalloc(sizeof(struct symtab));
564         sp->sclass = STATIC;
ragge
1.29
565         sp->ssue = 0;
ragge
1.24
566         sp->slevel = 1/* fake numeric label */
567         sp->soffset = getlab();
568         sp->sflags = 0;
569         sp->stype = p->n_type;
570         sp->squal = (CON >> TSHIFT);
mickey
1.17
571
ragge
1.24
572         defloc(sp);
ragge
1.13
573         ninval(0btdims[p->n_type].suesizep);
ragge
1.24
574
ragge
1.13
575         p->n_op = NAME;
mickey
1.27
576         p->n_lval = 0;
ragge
1.24
577         p->n_sp = sp;
ragge
1.13
578
mickey
1.1
579 }
580
581 /*ARGSUSED*/
582 int
583 andable(NODE *p)
584 {
585         return(1);  /* all names can have & taken on them */
586 }
587
588 /*
mickey
1.10
589  * Return 1 if a variable of type "t" is OK to put in register.
mickey
1.1
590  */
591 int
592 cisreg(TWORD t)
593 {
594         return 1;
595 }
596
597 /*
598  * Allocate off bits on the stack.  p is a tree that when evaluated
599  * is the multiply count for off, t is a storeable node where to write
600  * the allocated address.
601  */
602 void
603 spalloc(NODE *tNODE *pOFFSZ off)
604 {
605         NODE *sp;
606
607         p = buildtree(MULpbcon(off/SZCHAR)); /* XXX word alignment? */
608
609         /* sub the size from sp */
ragge
1.29
610         sp = block(REGNILNILp->n_type00);
mickey
1.1
611         sp->n_lval = 0;
612         sp->n_rval = STKREG;
613         ecomp(buildtree(PLUSEQspp));
614
615         /* save the address of sp */
616         sp = block(REGNILNILPTR+INTt->n_dft->n_sue);
617         sp->n_lval = 0;
618         sp->n_rval = STKREG;
619         t->n_type = sp->n_type;
620         ecomp(buildtree(ASSIGNtsp)); /* Emit! */
621
622 }
623
624 /*
625  * print out a constant node, may be associated with a label.
626  * Do not free the node after use.
627  * off is bit offset from the beginning of the aggregate
628  * fsz is the number of bits this is referring to
mickey
1.5
629  *
630  * XXX this relies on the host fp numbers representation
mickey
1.1
631  */
ragge
1.32
632 int
mickey
1.1
633 ninval(CONSZ offint fszNODE *p)
634 {
635         union { float fdouble dlong double lint i[3]; } u;
636         struct symtab *q;
637         TWORD t;
638         int i;
639
640         t = p->n_type;
641         if (t > BTMASK)
ragge
1.32
642                 p->n_type = t = INT/* pointer */
mickey
1.1
643
644         if (p->n_op == ICON && p->n_sp != NULL && DEUNSIGN(t) != INT)
645                 uerror("element not constant");
646
647         switch (t) {
648         case LONGLONG:
649         case ULONGLONG:
650                 i = (p->n_lval >> 32);
651                 p->n_lval &= 0xffffffff;
652                 p->n_type = INT;
653                 ninval(off32p);
654                 p->n_lval = i;
655                 ninval(off+3232p);
656                 break;
657         case INT:
658         case UNSIGNED:
659                 printf("\t.long 0x%x", (int)p->n_lval);
660                 if ((q = p->n_sp) != NULL) {
ragge
1.24
661                         if ((q->sclass == STATIC && q->slevel > 0)) {
mickey
1.1
662                                 printf("+" LABFMTq->soffset);
663                         } else
ragge
1.25
664                                 printf("+%s",
665                                     q->soname ? q->soname : exname(q->sname));
mickey
1.1
666                 }
667                 printf("\n");
668                 break;
669         case LDOUBLE:
670         case DOUBLE:
671                 u.d = (double)p->n_dcon;
672                 printf("\t.long\t0x%x,0x%x\n"u.i[0], u.i[1]);
673                 break;
674         case FLOAT:
675                 u.f = (float)p->n_dcon;
676                 printf("\t.long\t0x%x\n"u.i[0]);
677                 break;
678         default:
ragge
1.32
679                 return 0;
mickey
1.1
680         }
ragge
1.32
681         return 1;
mickey
1.1
682 }
683
684 /* make a name look like an external name in the local machine */
685 char *
686 exname(char *p)
687 {
688         if (p == NULL)
689                 return "";
690         return p;
691 }
692
693 /*
694  * map types which are not defined on the local machine
695  */
696 TWORD
697 ctype(TWORD type)
698 {
699         switch (BTYPE(type)) {
700         case LONG:
701                 MODTYPE(type,INT);
702                 break;
703
704         case ULONG:
705                 MODTYPE(type,UNSIGNED);
706         }
707
708         return (type);
709 }
710
711 void
mickey
1.27
712 calldec(NODE *fNODE *a)
mickey
1.1
713 {
mickey
1.14
714         struct symtab *q;
715         if (f->n_op == UMUL && f->n_left->n_op == PLUS &&
716             f->n_left->n_right->n_op == ICON)
717                 q = f->n_left->n_right->n_sp;
718         else if (f->n_op == PLUS && f->n_right->n_op == ICON)
719                 q = f->n_right->n_sp;
720         else {
721                 fwalk(feprint0);
722                 cerror("unknown function");
723                 return;
724         }
725
ragge
1.25
726         printf("\t.import\t%s,code\n"q->soname ? q->soname : exname(q->sname));
mickey
1.1
727 }
728
729 void
730 extdec(struct symtab *q)
731 {
ragge
1.25
732         printf("\t.import\t%s,data\n"q->soname ? q->soname : exname(q->sname));
mickey
1.1
733 }
734
735 /* make a common declaration for id, if reasonable */
736 void
mickey
1.17
737 defzero(struct symtab *sp)
mickey
1.1
738 {
739         int off;
740
mickey
1.17
741         off = tsize(sp->stypesp->sdfsp->ssue);
742         off = (off + (SZCHAR - 1)) / SZCHAR;
743         printf("\t.%scomm\t"sp->sclass == STATIC ? "l" : "");
744         if (sp->slevel == 0)
ragge
1.25
745                 printf("%s,0%o\n"sp->soname ? sp->soname : exname(sp->sname), off);
mickey
1.1
746         else
mickey
1.17
747                 printf(LABFMT ",0%o\n"sp->soffsetoff);
mickey
1.1
748 }
749
mickey
1.27
750 char *
751 section2string(char *nameint len)
752 {
753         char *s;
754         int n;
755
756         if (strncmp(name"link_set"8) == 0) {
757                 const char *postfix = ",\"aw\",@progbits";
758                 n = len + strlen(postfix) + 1;
759                 s = IALLOC(n);
760                 strlcpy(snamen);
761                 strlcat(spostfixn);
762                 return s;
763         }
764
765         return newstring(namelen);
766 }
767
mickey
1.17
768 char *nextsect;
mickey
1.27
769 char *alias;
770 int constructor;
771 int destructor;
mickey
1.1
772
mickey
1.17
773 #define SSECTION        010000
mickey
1.1
774
ragge
1.15
775 /*
776  * Give target the opportunity of handling pragmas.
777  */
778 int
ragge
1.28
779 mypragma(char *str)
ragge
1.15
780 {
ragge
1.28
781         char *a2 = pragtok(NULL);
782
783         if (strcmp(str"constructor") == 0 || strcmp(str"init") == 0) {
mickey
1.27
784                 constructor = 1;
785                 return 1;
786         }
ragge
1.28
787         if (strcmp(str"destructor") == 0 || strcmp(str"fini") == 0) {
mickey
1.27
788                 destructor = 1;
789                 return 1;
790         }
ragge
1.28
791         if (strcmp(str"section") == 0 && a2 != NULL) {
792                 nextsect = section2string(a2strlen(a2));
mickey
1.27
793                 return 1;
794         }
ragge
1.28
795         if (strcmp(str"alias") == 0 && a2 != NULL) {
796                 alias = tmpstrdup(a2);
mickey
1.27
797                 return 1;
798         }
799         return 0;
mickey
1.17
800 }
ragge
1.15
801
802 /*
803  * Called when a identifier has been declared, to give target last word.
804  */
805 void
806 fixdef(struct symtab *sp)
807 {
mickey
1.27
808         if (alias != NULL && (sp->sclass != PARAM)) {
809                 printf("\t.globl %s\n%s = %s\n"exname(sp->soname),
810                     exname(sp->soname), exname(alias));
811                 alias = NULL;
812         }
813         if ((constructor || destructor) && (sp->sclass != PARAM)) {
814                 printf("\t.section .%ctors,\"aw\",@progbits\n"
815                     "\t.p2align 2\n\t.long %s\n\t.previous\n",
816                     constructor ? 'c' : 'd'exname(sp->sname));
817                 constructor = destructor = 0;
818         }
ragge
1.15
819 }
820
gmcgarry
1.23
821 void
822 pass1_lastchance(struct interpass *ip)
823 {
824 }
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-31 19:38 +0100