Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20160305154936

Diff

Diff from 1.96 to:

Annotations

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

Annotated File View

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