Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20121028135928

Diff

Diff from 1.76 to:

Annotations

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

Annotated File View

ragge
1.76
1 /*      $Id: local.c,v 1.76 2012/10/28 13:59:28 ragge Exp $     */
mickey
1.1
2 /*
3  * Copyright (c) 2008 Michael Shalayeff
4  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28
29 #include "pass1.h"
30
31 /*      this file contains code which is dependent on the target machine */
32
33 /*
34  * Check if a constant is too large for a type.
35  */
plunky
1.48
36 #ifdef notyet
mickey
1.1
37 static int
38 toolarge(TWORD tCONSZ con)
39 {
40         U_CONSZ ucon = con;
41
42         switch (t) {
43         case ULONG:
44         case LONG:
45         case ULONGLONG:
46         case LONGLONG:
47                 break/* cannot be too large */
48 #define SCHK(i) case i: if (con > MAX_##i || con < MIN_##i) return 1; break
49 #define UCHK(i) case i: if (ucon > MAX_##i) return 1; break
50         SCHK(INT);
51         SCHK(SHORT);
52         case BOOL:
53         SCHK(CHAR);
54         UCHK(UNSIGNED);
55         UCHK(USHORT);
56         UCHK(UCHAR);
57         default:
58                 cerror("toolarge");
59         }
60         return 0;
61 }
plunky
1.48
62 #endif
mickey
1.1
63
64 #define IALLOC(sz)      (isinlining ? permalloc(sz) : tmpalloc(sz))
65
66 /*
67  * Make a symtab entry for PIC use.
68  */
69 static struct symtab *
70 picsymtab(char *pchar *schar *s2)
71 {
72         struct symtab *sp = IALLOC(sizeof(struct symtab));
73         size_t len = strlen(p) + strlen(s) + strlen(s2) + 1;
ragge
1.22
74
mickey
1.1
75         sp->sname = sp->soname = IALLOC(len);
76         strlcpy(sp->sonameplen);
77         strlcat(sp->sonameslen);
78         strlcat(sp->sonames2len);
79         sp->sclass = EXTERN;
80         sp->sflags = sp->slevel = 0;
81         return sp;
82 }
83
84 int gotnr/* tempnum for GOT register */
85 int argstacksize;
86
87 /*
ragge
1.22
88  * Create a reference for an extern variable or function.
mickey
1.1
89  */
90 static NODE *
91 picext(NODE *p)
92 {
gmcgarry
1.50
93 #if defined(ELFABI)
94
ragge
1.76
95         struct attr *ga;
ragge
1.9
96         NODE *q;
mickey
1.1
97         struct symtab *sp;
ragge
1.64
98         char *c;
ragge
1.22
99
100         if (p->n_sp->sflags & SBEENHERE)
101                 return p;
ragge
1.76
102         if ((ga = attr_find(p->n_sp->sapGCC_ATYP_VISIBILITY)) &&
103             strcmp(ga->sarg(0), "hidden") == 0)
104                 return p/* no GOT reference */
mickey
1.1
105
ragge
1.31
106         c = p->n_sp->soname ? p->n_sp->soname : exname(p->n_sp->sname);
ragge
1.64
107         sp = picsymtab(""c"@GOTPCREL");
108         sp->sflags |= SBEENHERE;
ragge
1.18
109         q = block(NAMENILNILINCREF(p->n_type), p->n_dfp->n_ap);
ragge
1.9
110         q->n_sp = sp;
ragge
1.18
111         q = block(UMULq0p->n_typep->n_dfp->n_ap);
ragge
1.9
112         q->n_sp = sp;
mickey
1.1
113         nfree(p);
114         return q;
gmcgarry
1.50
115
116 #elif defined(MACHOABI)
117
118         return p;
119
120 #endif
mickey
1.1
121 }
122
ragge
1.27
123 static NODE *
124 cmop(NODE *lNODE *r)
125 {
ragge
1.45
126         return block(CMlrINT00);
ragge
1.27
127 }
128
129 static NODE *
130 mkx(char *sNODE *p)
131 {
ragge
1.45
132         p = block(XARGpNILINT00);
ragge
1.27
133         p->n_name = s;
134         return p;
135 }
136
137 static char *
138 mk3str(char *s1char *s2char *s3)
139 {
140         int len = strlen(s1) + strlen(s2) + strlen(s3) + 1;
141         char *sd;
142
ragge
1.39
143         sd = inlalloc(len);
ragge
1.27
144         strlcpy(sds1len);
145         strlcat(sds2len);
146         strlcat(sds3len);
147         return sd;
148 }
mickey
1.1
149
150 /*
151  * Create a reference for a TLS variable.
ragge
1.27
152  * This is the "General dynamic" version.
mickey
1.1
153  */
154 static NODE *
155 tlspic(NODE *p)
156 {
ragge
1.27
157         NODE *q, *r, *s;
158         char *s1, *s2;
mickey
1.1
159
160         /*
ragge
1.27
161          * .byte   0x66
162          * leaq x@TLSGD(%rip),%rdi
163          * .word   0x6666
164          * rex64
165          * call __tls_get_addr@PLT
mickey
1.1
166          */
167
ragge
1.27
168         /* Need the .byte stuff around.  Why? */
169         /* Use inline assembler */
170         q = mkx("%rdx"bcon(0));
171         q = cmop(qmkx("%rcx"bcon(0)));
172         q = cmop(qmkx("%rsi"bcon(0)));
173         q = cmop(qmkx("%rdi"bcon(0)));
174         q = cmop(qmkx("%r8"bcon(0)));
175         q = cmop(qmkx("%r9"bcon(0)));
176         q = cmop(qmkx("%r10"bcon(0)));
177         q = cmop(qmkx("%r11"bcon(0)));
178
179         s = ccopy(r = tempnode(0INCREF(p->n_type), p->n_dfp->n_ap));
180         r = mkx("=a"r);
ragge
1.45
181         r = block(XASMrqINT00);
ragge
1.27
182
183         /* Create the magic string */
184         s1 = ".byte 0x66\n\tleaq ";
185         s2 = "@TLSGD(%%rip),%%rdi\n"
186             "\t.word 0x6666\n\trex64\n\tcall __tls_get_addr@PLT";
187         if (p->n_sp->soname == NULL)
188                 p->n_sp->soname = p->n_sp->sname;
189         r->n_name = mk3str(s1p->n_sp->sonames2);
190
191         r = block(COMOPrsINCREF(p->n_type), p->n_dfp->n_ap);
192         r = buildtree(UMULrNIL);
193         tfree(p);
194         return r;
mickey
1.1
195 }
196
ragge
1.27
197 /*
198  * The "initial exec" tls model.
199  */
mickey
1.1
200 static NODE *
ragge
1.27
201 tlsinitialexec(NODE *p)
mickey
1.1
202 {
ragge
1.27
203         NODE *q, *r, *s;
204         char *s1, *s2;
mickey
1.1
205
ragge
1.27
206         /*
207          * movq %fs:0,%rax
208          * addq x@GOTTPOFF(%rip),%rax
209          */
210
211         q = bcon(0);
212         q->n_type = STRTY;
mickey
1.1
213
ragge
1.27
214         s = ccopy(r = tempnode(0INCREF(p->n_type), p->n_dfp->n_ap));
215         r = mkx("=r"r);
ragge
1.45
216         r = block(XASMrqINT00);
ragge
1.27
217
218         s1 = "movq %%fs:0,%0\n\taddq ";
219         s2 = "@GOTTPOFF(%%rip),%0";
220         if (p->n_sp->soname == NULL)
221                 p->n_sp->soname = p->n_sp->sname;
222         r->n_name = mk3str(s1p->n_sp->sonames2);
223
224         r = block(COMOPrsINCREF(p->n_type), p->n_dfp->n_ap);
225         r = buildtree(UMULrNIL);
226         tfree(p);
227         return r;
mickey
1.1
228 }
229
230 static NODE *
231 tlsref(NODE *p)
232 {
ragge
1.27
233         struct symtab *sp = p->n_sp;
234         struct attr *ga;
235         char *c;
236
237         if ((ga = attr_find(sp->sapGCC_ATYP_TLSMODEL)) != NULL) {
238                 c = ga->sarg(0);
239                 if (strcmp(c"initial-exec") == 0)
240                         return tlsinitialexec(p);
241                 else if (strcmp(c"global-dynamic") == 0)
242                         ;
243                 else
244                         werror("unsupported tls model '%s'"c);
245         }
246         return tlspic(p);
mickey
1.1
247 }
248
249 /* clocal() is called to do local transformations on
250  * an expression tree preparitory to its being
251  * written out in intermediate code.
252  *
253  * the major essential job is rewriting the
254  * automatic variables and arguments in terms of
255  * REG and OREG nodes
256  * conversion ops which are not necessary are also clobbered here
257  * in addition, any special features (such as rewriting
258  * exclusive or) are easily handled here as well
259  */
260 NODE *
261 clocal(NODE *p)
262 {
263
264         register struct symtab *q;
265         register NODE *r, *l;
266         register int o;
267         register int m;
268         TWORD t;
269
270 #ifdef PCC_DEBUG
271         if (xdebug) {
272                 printf("clocal: %p\n"p);
273                 fwalk(peprint0);
274         }
275 #endif
276         switcho = p->n_op ){
277
278         case NAME:
279                 if ((q = p->n_sp) == NULL)
280                         return p/* Nothing to care about */
281
282                 switch (q->sclass) {
283
284                 case PARAM:
285                 case AUTO:
286                         /* fake up a structure reference */
287                         r = block(REGNILNILPTR+STRTY00);
288                         r->n_lval = 0;
289                         r->n_rval = FPREG;
290                         p = stref(block(STREFrp000));
291                         break;
292
293                 case USTATIC:
294                         if (kflag == 0)
295                                 break;
296                         /* FALLTHROUGH */
297                 case STATIC:
298 #ifdef TLS
299                         if (q->sflags & STLS) {
300                                 p = tlsref(p);
301                                 break;
302                         }
303 #endif
304                         break;
305
306                 case REGISTER:
307                         p->n_op = REG;
308                         p->n_lval = 0;
309                         p->n_rval = q->soffset;
310                         break;
311
312                 case EXTERN:
313                 case EXTDEF:
314                         if (q->sflags & STLS) {
315                                 p = tlsref(p);
316                                 break;
317                         }
ragge
1.51
318                         if (kflag == 0 || statinit)
mickey
1.1
319                                 break;
320                         if (blevel > 0)
321                                 p = picext(p);
322                         break;
323                 }
324                 break;
325
ragge
1.24
326         case UCALL:
327         case USTCALL:
328                 /* For now, always clear eax */
ragge
1.45
329                 l = block(REGNILNILINT00);
ragge
1.24
330                 regno(l) = RAX;
331                 p->n_right = clocal(buildtree(ASSIGNlbcon(0)));
332                 p->n_op -= (UCALL-CALL);
ragge
1.7
333                 break;
334
mickey
1.1
335         case SCONV:
ragge
1.15
336                 /* Special-case shifts */
337                 if (p->n_type == LONG && (l = p->n_left)->n_op == LS && 
338                     l->n_type == INT && l->n_right->n_op == ICON) {
339                         p->n_left = l->n_left;
340                         p = buildtree(LSpl->n_right);
341                         nfree(l);
342                         break;
343                 }
344
mickey
1.1
345                 l = p->n_left;
346
ragge
1.5
347                 /* Float conversions may need extra casts */
ragge
1.37
348                 if (p->n_type == FLOAT || p->n_type == DOUBLE ||
349                     p->n_type == LDOUBLE) {
ragge
1.41
350                         if (l->n_type < INT || l->n_type == BOOL) {
ragge
1.5
351                                 p->n_left = block(SCONVlNIL,
352                                     ISUNSIGNED(l->n_type) ? UNSIGNED : INT,
ragge
1.18
353                                     l->n_dfl->n_ap);
ragge
1.5
354                                 break;
355                         }
356                 }
357
mickey
1.1
358                 if (p->n_type == l->n_type) {
359                         nfree(p);
360                         return l;
361                 }
362
363                 if ((p->n_type & TMASK) == 0 && (l->n_type & TMASK) == 0 &&
ragge
1.45
364                     tsize(p->n_typep->n_dfp->n_ap) ==
365                     tsize(l->n_typel->n_dfl->n_ap)) {
mickey
1.1
366                         if (p->n_type != FLOAT && p->n_type != DOUBLE &&
367                             l->n_type != FLOAT && l->n_type != DOUBLE &&
368                             l->n_type != LDOUBLE && p->n_type != LDOUBLE) {
369                                 if (l->n_op == NAME || l->n_op == UMUL ||
370                                     l->n_op == TEMP) {
371                                         l->n_type = p->n_type;
372                                         nfree(p);
373                                         return l;
374                                 }
375                         }
376                 }
377
378                 if (DEUNSIGN(p->n_type) == INT && DEUNSIGN(l->n_type) == INT &&
ragge
1.42
379                     coptype(l->n_op) == BITYPE && l->n_op != COMOP &&
380                     l->n_op != QUEST) {
mickey
1.1
381                         l->n_type = p->n_type;
382                         nfree(p);
383                         return l;
384                 }
385
386                 o = l->n_op;
387                 m = p->n_type;
388
389                 if (o == ICON) {
390                         CONSZ val = l->n_lval;
391
392                         if (!ISPTR(m)) /* Pointers don't need to be conv'd */
393                             switch (m) {
394                         case BOOL:
ragge
1.30
395                                 l->n_lval = nncon(l) ? (l->n_lval != 0) : 1;
396                                 l->n_sp = NULL;
mickey
1.1
397                                 break;
398                         case CHAR:
399                                 l->n_lval = (char)val;
400                                 break;
401                         case UCHAR:
402                                 l->n_lval = val & 0377;
403                                 break;
404                         case SHORT:
405                                 l->n_lval = (short)val;
406                                 break;
407                         case USHORT:
408                                 l->n_lval = val & 0177777;
409                                 break;
410                         case UNSIGNED:
411                                 l->n_lval = val & 0xffffffff;
412                                 break;
413                         case INT:
414                                 l->n_lval = (int)val;
415                                 break;
416                         case LONG:
417                         case LONGLONG:
418                                 l->n_lval = (long long)val;
419                                 break;
420                         case ULONG:
421                         case ULONGLONG:
422                                 l->n_lval = val;
423                                 break;
424                         case VOID:
425                                 break;
426                         case LDOUBLE:
427                         case DOUBLE:
428                         case FLOAT:
429                                 l->n_op = FCON;
430                                 l->n_dcon = val;
431                                 break;
432                         default:
433                                 cerror("unknown type %d"m);
434                         }
435                         l->n_type = m;
ragge
1.45
436                         l->n_ap = NULL;
mickey
1.1
437                         nfree(p);
438                         return l;
439                 } else if (l->n_op == FCON) {
ragge
1.29
440                         if (p->n_type == BOOL)
441                                 l->n_lval = l->n_dcon != 0.0;
442                         else
443                                 l->n_lval = l->n_dcon;
mickey
1.1
444                         l->n_sp = NULL;
445                         l->n_op = ICON;
446                         l->n_type = m;
ragge
1.45
447                         l->n_ap = NULL;
mickey
1.1
448                         nfree(p);
449                         return clocal(l);
450                 }
451                 if ((p->n_type == CHAR || p->n_type == UCHAR ||
452                     p->n_type == SHORT || p->n_type == USHORT) &&
453                     (l->n_type == FLOAT || l->n_type == DOUBLE ||
454                     l->n_type == LDOUBLE)) {
ragge
1.18
455                         p = block(SCONVpNILp->n_typep->n_dfp->n_ap);
mickey
1.1
456                         p->n_left->n_type = INT;
457                         return p;
458                 }
459                 break;
460
461         case MOD:
462         case DIV:
463                 if (o == DIV && p->n_type != CHAR && p->n_type != SHORT)
464                         break;
465                 if (o == MOD && p->n_type != CHAR && p->n_type != SHORT)
466                         break;
467                 /* make it an int division by inserting conversions */
ragge
1.52
468                 p->n_left = makety(p->n_leftINT000);
469                 p->n_right = makety(p->n_rightINT000);
470                 p = makety(pp->n_type000);
mickey
1.1
471                 p->n_left->n_type = INT;
472                 break;
473
474         case FORCE:
475                 /* put return value in return reg */
476                 p->n_op = ASSIGN;
477                 p->n_right = p->n_left;
ragge
1.45
478                 p->n_left = block(REGNILNILp->n_type00);
ragge
1.34
479                 t = p->n_type;
480                 if (ISITY(t))
481                         t = t - (FIMAG-FLOAT);
mickey
1.1
482                 p->n_left->n_rval = p->n_left->n_type == BOOL ? 
ragge
1.34
483                     RETREG(CHAR) : RETREG(t);
mickey
1.1
484                 break;
485
486         case LS:
487         case RS:
ragge
1.15
488                 /* shift count must be in a char */
mickey
1.1
489                 if (p->n_right->n_type == CHAR || p->n_right->n_type == UCHAR)
490                         break;
ragge
1.52
491                 p->n_right = makety(p->n_rightCHAR000);
mickey
1.1
492                 break;
493         }
494 #ifdef PCC_DEBUG
495         if (xdebug) {
496                 printf("clocal end: %p\n"p);
497                 fwalk(peprint0);
498         }
499 #endif
500         return(p);
501 }
502
503 void
504 myp2tree(NODE *p)
505 {
ragge
1.28
506         struct symtab *spsps;
507         static int dblxorfltxor;
mickey
1.1
508
ragge
1.28
509         if (p->n_op == UMINUS && (p->n_type == FLOAT || p->n_type == DOUBLE)) {
510                 /* Store xor code for sign change */
511                 if (dblxor == 0) {
512                         dblxor = getlab();
513                         fltxor = getlab();
514                         sps.stype = LDOUBLE;
515                         sps.squal = CON >> TSHIFT;
516                         sps.sflags = sps.sclass = 0;
517                         sps.sname = sps.soname = "";
518                         sps.slevel = 1;
ragge
1.45
519                         sps.sap = NULL;
ragge
1.28
520                         sps.soffset = dblxor;
ragge
1.59
521                         locctr(DATA, &sps);
ragge
1.28
522                         defloc(&sps);
523                         printf("\t.long 0,0x80000000,0,0\n");
524                         printf(LABFMT ":\n"fltxor);
525                         printf("\t.long 0x80000000,0,0,0\n");
526                 }
527                 p->n_label = p->n_type == FLOAT ? fltxor : dblxor;
528                 return;
529         }
ragge
1.64
530         if (kflag && (cdope(p->n_op) & CALLFLG) && p->n_left->n_op == NAME) {
531                 /* Convert @GOTPCREL to @PLT */
532                 char *s;
533
534                 sp = p->n_left->n_sp;
535                 if ((s = strstr(sp->sname"@GOTPCREL")) != NULL) {
plunky
1.74
536                         memcpy(s"@PLT"sizeof("@PLT"));
ragge
1.64
537                         p->n_left->n_op = ICON;
538                 }
539                 return;
540         }
mickey
1.1
541         if (p->n_op != FCON)
542                 return;
543
ragge
1.66
544 #ifdef mach_amd64
545         {
plunky
1.70
546                 /* Do not lose negative zeros */
ragge
1.69
547                 long double *d = &p->n_dcon;
548                 long long *llp = (long long *)d;
ragge
1.66
549                 short *ssp = (short *)&llp[1];
550                 if (*llp == 0 && *ssp == 0)
551                         return;
552         }
553 #else
554 #error fixme
555 #endif
ragge
1.65
556
ragge
1.22
557         /* XXX should let float constants follow */
mickey
1.1
558         sp = IALLOC(sizeof(struct symtab));
559         sp->sclass = STATIC;
ragge
1.45
560         sp->sap = NULL;
mickey
1.1
561         sp->slevel = 1/* fake numeric label */
562         sp->soffset = getlab();
563         sp->sflags = 0;
564         sp->stype = p->n_type;
565         sp->squal = (CON >> TSHIFT);
gmcgarry
1.49
566         sp->sname = sp->soname = NULL;
mickey
1.1
567
ragge
1.59
568         locctr(DATAsp);
mickey
1.1
569         defloc(sp);
ragge
1.18
570         ninval(0tsize(sp->stypesp->sdfsp->sap), p);
mickey
1.1
571
572         p->n_op = NAME;
573         p->n_lval = 0;
574         p->n_sp = sp;
575 }
576
ragge
1.22
577 /*
578  * Convert ADDROF NAME to ICON?
579  */
mickey
1.1
580 int
581 andable(NODE *p)
582 {
ragge
1.67
583 #ifdef notdef
584         /* shared libraries cannot have direct referenced static syms */
ragge
1.22
585         if (p->n_sp->sclass == STATIC || p->n_sp->sclass == USTATIC)
ragge
1.64
586                 return 1;
ragge
1.67
587 #endif
ragge
1.64
588         return !kflag;
mickey
1.1
589 }
590
591 /*
592  * Return 1 if a variable of type type is OK to put in register.
593  */
594 int
595 cisreg(TWORD t)
596 {
ragge
1.14
597         if (t == LDOUBLE)
598                 return 0;
mickey
1.1
599         return 1;
600 }
601
602 /*
603  * Allocate off bits on the stack.  p is a tree that when evaluated
604  * is the multiply count for off, t is a storeable node where to write
605  * the allocated address.
606  */
607 void
608 spalloc(NODE *tNODE *pOFFSZ off)
609 {
610         NODE *sp;
611
ragge
1.20
612         p = buildtree(MULpbcon(off/SZCHAR));
613         p = buildtree(PLUSpbcon(30));
614         p = buildtree(ANDpxbcon(-16NULLLONG));
mickey
1.1
615
616         /* sub the size from sp */
ragge
1.45
617         sp = block(REGNILNILp->n_type00);
mickey
1.1
618         sp->n_lval = 0;
619         sp->n_rval = STKREG;
620         ecomp(buildtree(MINUSEQspp));
621
622         /* save the address of sp */
ragge
1.22
623         sp = block(REGNILNILPTR+LONGt->n_dft->n_ap);
mickey
1.1
624         sp->n_lval = 0;
625         sp->n_rval = STKREG;
626         t->n_type = sp->n_type;
627         ecomp(buildtree(ASSIGNtsp)); /* Emit! */
628
629 }
630
631 /*
632  * print out a constant node, may be associated with a label.
633  * Do not free the node after use.
634  * off is bit offset from the beginning of the aggregate
635  * fsz is the number of bits this is referring to
636  */
ragge
1.55
637 int
mickey
1.1
638 ninval(CONSZ offint fszNODE *p)
639 {
640         union { float fdouble dlong double lint i[3]; } u;
641
ragge
1.55
642         switch (p->n_type) {
mickey
1.1
643         case LDOUBLE:
644                 u.i[2] = 0;
645                 u.l = (long double)p->n_dcon;
646 #if defined(HOST_BIG_ENDIAN)
647                 /* XXX probably broken on most hosts */
ragge
1.36
648                 printf("\t.long\t0x%x,0x%x,0x%x,0\n"u.i[2], u.i[1], u.i[0]);
mickey
1.1
649 #else
ragge
1.36
650                 printf("\t.long\t0x%x,0x%x,0x%x,0\n"u.i[0], u.i[1], u.i[2]);
mickey
1.1
651 #endif
652                 break;
653         case DOUBLE:
654                 u.d = (double)p->n_dcon;
655 #if defined(HOST_BIG_ENDIAN)
656                 printf("\t.long\t0x%x,0x%x\n"u.i[1], u.i[0]);
657 #else
658                 printf("\t.long\t0x%x,0x%x\n"u.i[0], u.i[1]);
659 #endif
660                 break;
661         case FLOAT:
662                 u.f = (float)p->n_dcon;
663                 printf("\t.long\t0x%x\n"u.i[0]);
664                 break;
665         default:
ragge
1.55
666                 return 0;
mickey
1.1
667         }
ragge
1.55
668         return 1;
mickey
1.1
669 }
670
671 /* make a name look like an external name in the local machine */
672 char *
673 exname(char *p)
674 {
ragge
1.31
675 #ifdef MACHOABI
676
677 #define NCHNAM  256
678         static char text[NCHNAM+1];
679         int i;
680
681         if (p == NULL)
682                 return "";
683
684         text[0] = '_';
685         for (i=1; *p && i<NCHNAM; ++i)
686                 text[i] = *p++;
687
688         text[i] = '\0';
689         text[NCHNAM] = '\0';  /* truncate */
690
691         return (text);
692 #else
mickey
1.1
693         return (p == NULL ? "" : p);
ragge
1.31
694 #endif
mickey
1.1
695 }
696
697 /*
698  * map types which are not defined on the local machine
699  */
700 TWORD
701 ctype(TWORD type)
702 {
703         switch (BTYPE(type)) {
ragge
1.5
704         case LONGLONG:
mickey
1.1
705                 MODTYPE(type,LONG);
706                 break;
707
ragge
1.5
708         case ULONGLONG:
mickey
1.1
709                 MODTYPE(type,ULONG);
710
711         }
712         return (type);
713 }
714
715 void
716 calldec(NODE *pNODE *q
717 {
718 }
719
720 void
721 extdec(struct symtab *q)
722 {
723 }
724
725 /* make a common declaration for id, if reasonable */
726 void
727 defzero(struct symtab *sp)
728 {
ragge
1.58
729         int offal;
ragge
1.11
730         char *name;
mickey
1.1
731
ragge
1.11
732         if ((name = sp->soname) == NULL)
733                 name = exname(sp->sname);
ragge
1.18
734         off = tsize(sp->stypesp->sdfsp->sap);
ragge
1.58
735         SETOFF(off,SZCHAR);
736         off /= SZCHAR;
737         al = talign(sp->stypesp->sap)/SZCHAR;
738
ragge
1.60
739         if (sp->sclass == STATIC) {
740                 if (sp->slevel == 0) {
741                         printf("\t.local %s\n"name);
742                 } else
743                         printf("\t.local " LABFMT "\n"sp->soffset);
744         }
ragge
1.5
745         if (sp->slevel == 0) {
ragge
1.60
746                 printf("\t.comm %s,0%o,%d\n"nameoffal);
ragge
1.5
747         } else
ragge
1.60
748                 printf("\t.comm " LABFMT ",0%o,%d\n"sp->soffsetoffal);
mickey
1.1
749 }
750
751 static char *
plunky
1.73
752 section2string(char *name)
mickey
1.1
753 {
plunky
1.73
754         int len = strlen(name);
mickey
1.1
755
756         if (strncmp(name"link_set"8) == 0) {
plunky
1.73
757                 const char postfix[] = ",\"aw\",@progbits";
758                 char *s;
759
760                 s = IALLOC(len + sizeof(postfix));
761                 memcpy(snamelen);
762                 memcpy(s + lenpostfixsizeof(postfix));
mickey
1.1
763                 return s;
764         }
765
766         return newstring(namelen);
767 }
768
769 char *nextsect;
770 static int gottls;
771 static char *alias;
772 static int constructor;
773 static int destructor;
774
775 /*
776  * Give target the opportunity of handling pragmas.
777  */
778 int
ragge
1.38
779 mypragma(char *str)
mickey
1.1
780 {
ragge
1.38
781         char *a2 = pragtok(NULL);
782
783         if (strcmp(str"tls") == 0 && a2 == NULL) {
mickey
1.1
784                 gottls = 1;
785                 return 1;
786         }
ragge
1.38
787         if (strcmp(str"constructor") == 0 || strcmp(str"init") == 0) {
mickey
1.1
788                 constructor = 1;
789                 return 1;
790         }
ragge
1.38
791         if (strcmp(str"destructor") == 0 || strcmp(str"fini") == 0) {
mickey
1.1
792                 destructor = 1;
793                 return 1;
794         }
ragge
1.38
795         if (strcmp(str"section") == 0 && a2 != NULL) {
plunky
1.73
796                 nextsect = section2string(a2);
mickey
1.1
797                 return 1;
798         }
ragge
1.38
799         if (strcmp(str"alias") == 0 && a2 != NULL) {
800                 alias = tmpstrdup(a2);
mickey
1.1
801                 return 1;
802         }
803
804         return 0;
805 }
806
807 /*
808  * Called when a identifier has been declared.
809  */
810 void
811 fixdef(struct symtab *sp)
812 {
ragge
1.18
813         struct attr *ga;
ragge
1.22
814
mickey
1.1
815         /* may have sanity checks here */
816         if (gottls)
817                 sp->sflags |= STLS;
818         gottls = 0;
ragge
1.27
819
ragge
1.17
820 #ifdef HAVE_WEAKREF
821         /* not many as'es have this directive */
ragge
1.18
822         if ((ga = gcc_get_attr(sp->sapGCC_ATYP_WEAKREF)) != NULL) {
ragge
1.17
823                 char *wr = ga->a1.sarg;
824                 char *sn = sp->soname ? sp->soname : sp->sname;
825                 if (wr == NULL) {
ragge
1.18
826                         if ((ga = gcc_get_attr(sp->sapGCC_ATYP_ALIAS))) {
ragge
1.17
827                                 wr = ga->a1.sarg;
828                         }
829                 }
830                 if (wr == NULL)
831                         printf("\t.weak %s\n"sn);
832                 else
833                         printf("\t.weakref %s,%s\n"snwr);
834         } else
835 #endif
ragge
1.18
836                if ((ga = attr_find(sp->sapGCC_ATYP_ALIAS)) != NULL) {
837                 char *an = ga->sarg(0);
ragge
1.16
838                 char *sn = sp->soname ? sp->soname : sp->sname;
839                 char *v;
840
ragge
1.18
841                 v = attr_find(sp->sapGCC_ATYP_WEAK) ? "weak" : "globl";
ragge
1.16
842                 printf("\t.%s %s\n"vsn);
843                 printf("\t.set %s,%s\n"snan);
844         }
mickey
1.1
845         if (alias != NULL && (sp->sclass != PARAM)) {
846                 printf("\t.globl %s\n"exname(sp->soname));
847                 printf("%s = "exname(sp->soname));
848                 printf("%s\n"exname(alias));
849                 alias = NULL;
850         }
851         if ((constructor || destructor) && (sp->sclass != PARAM)) {
ragge
1.10
852                 NODE *p = talloc();
853
854                 p->n_op = NAME;
855                 p->n_sp =
856                   (struct symtab *)(constructor ? "constructor" : "destructor");
ragge
1.18
857                 sp->sap = attr_add(sp->sapgcc_attr_parse(p));
mickey
1.1
858                 constructor = destructor = 0;
859         }
860 }
861
862 void
863 pass1_lastchance(struct interpass *ip)
864 {
865 }
FishEye: Open Source License registered to PCC.
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-12-29 11:57 +0100