Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20140606070442

Diff

Diff from 1.52 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/cc/ccom/builtins.c

Annotated File View

ragge
1.52
1 /*      $Id: builtins.c,v 1.52 2014/06/06 07:04:42 ragge Exp $  */
ragge
1.1
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 # include "pass1.h"
28
ragge
1.2
29 #ifndef MIN
30 #define MIN(a,b) (((a)<(b))?(a):(b))
31 #endif
ragge
1.18
32 #ifndef MAX
33 #define MAX(a,b) (((a)>(b))?(a):(b))
34 #endif
ragge
1.1
35
36 #ifndef NO_C_BUILTINS
ragge
1.36
37
ragge
1.1
38 /*
39  * replace an alloca function with direct allocation on stack.
40  * return a destination temp node.
41  */
42 static NODE *
ragge
1.36
43 builtin_alloca(const struct bitable *btNODE *a)
ragge
1.1
44 {
45         NODE *t, *u;
46
47 #ifdef notyet
48         if (xnobuiltins)
49                 return NULL;
50 #endif
51
ragge
1.22
52         t = tempnode(0VOID|PTR00);
53         u = tempnode(regno(t), VOID|PTR00);
ragge
1.1
54         spalloc(taSZCHAR);
55         return u;
56 }
57
58 /*
59  * Determine if a value is known to be constant at compile-time and
60  * hence that PCC can perform constant-folding on expressions involving
61  * that value.
62  */
63 static NODE *
ragge
1.36
64 builtin_constant_p(const struct bitable *btNODE *a)
ragge
1.1
65 {
ragge
1.17
66         void putjops(NODE *pvoid *arg);
ragge
1.36
67         NODE *f;
ragge
1.17
68         int isconst;
ragge
1.1
69
ragge
1.17
70         walkf(aputjops0);
71         for (f = af->n_op == COMOPf = f->n_right)
72                 ;
73         isconst = nncon(f);
74         tfree(a);
75         return bcon(isconst);
ragge
1.1
76 }
77
78 /*
79  * Hint to the compiler whether this expression will evaluate true or false.
80  * Just ignored for now.
81  */
82 static NODE *
ragge
1.36
83 builtin_expect(const struct bitable *btNODE *a)
ragge
1.1
84 {
ragge
1.36
85         NODE *f;
ragge
1.1
86
87         if (a && a->n_op == CM) {
88                 tfree(a->n_right);
89                 f = a->n_left;
90                 nfree(a);
91                 a = f;
92         }
93
94         return a;
95 }
96
97 /*
98  * Take integer absolute value.
99  * Simply does: ((((x)>>(8*sizeof(x)-1))^(x))-((x)>>(8*sizeof(x)-1)))
100  */
101 static NODE *
ragge
1.36
102 builtin_abs(const struct bitable *btNODE *a)
ragge
1.1
103 {
104         NODE *p, *q, *r, *t, *t2, *t3;
105         int tmp1tmp2shift;
106
107         if (a->n_type != INT)
108                 a = cast(aINT0);
109
110         if (a->n_op == ICON) {
111                 if (a->n_lval < 0)
112                         a->n_lval = -a->n_lval;
113                 p = a;
114         } else {
ragge
1.7
115                 t = tempnode(0a->n_typea->n_dfa->n_ap);
ragge
1.1
116                 tmp1 = regno(t);
117                 p = buildtree(ASSIGNta);
118
ragge
1.7
119                 t = tempnode(tmp1a->n_typea->n_dfa->n_ap);
120                 shift = (int)tsize(a->n_typea->n_dfa->n_ap) - 1;
ragge
1.1
121                 q = buildtree(RStbcon(shift));
122
ragge
1.7
123                 t2 = tempnode(0a->n_typea->n_dfa->n_ap);
ragge
1.1
124                 tmp2 = regno(t2);
125                 q = buildtree(ASSIGNt2q);
126
ragge
1.7
127                 t = tempnode(tmp1a->n_typea->n_dfa->n_ap);
128                 t2 = tempnode(tmp2a->n_typea->n_dfa->n_ap);
129                 t3 = tempnode(tmp2a->n_typea->n_dfa->n_ap);
ragge
1.1
130                 r = buildtree(MINUSbuildtree(ERtt2), t3);
131
132                 p = buildtree(COMOPpbuildtree(COMOPqr));
133         }
134
135         return p;
136 }
137
ragge
1.30
138 #define cmop(x,y) buildtree(COMOP, x, y)
ragge
1.31
139 #define lblnod(l) nlabel(l)
ragge
1.30
140
ragge
1.48
141 #ifndef TARGET_BSWAP
142 static NODE *
143 builtin_bswap16(const struct bitable *btNODE *a)
144 {
145         NODE *f, *t1, *t2;
146
147         t1 = buildtree(LSbuildtree(ANDccopy(a), bcon(255)), bcon(8));
148         t2 = buildtree(ANDbuildtree(RSabcon(8)), bcon(255));
149         f = buildtree(ORt1t2);
150         return f;
151 }
152
153 static NODE *
154 builtin_bswap32(const struct bitable *btNODE *a)
155 {
156         NODE *f, *t1, *t2, *t3, *t4;
157
158         t1 = buildtree(LSbuildtree(ANDccopy(a), bcon(255)), bcon(24));
159         t2 = buildtree(LSbuildtree(ANDccopy(a), bcon(255 << 8)), bcon(8));
160         t3 = buildtree(ANDbuildtree(RSccopy(a), bcon(8)), bcon(255 << 8));
161         t4 = buildtree(ANDbuildtree(RSabcon(24)), bcon(255));
162         f = buildtree(ORbuildtree(ORt1t2), buildtree(ORt3t4));
163         return f;
164 }
165
166 static NODE *
167 builtin_bswap64(const struct bitable *btNODE *a)
168 {
169         NODE *f, *t1, *t2, *t3, *t4, *t5, *t6, *t7, *t8;
170
171 #define X(x) xbcon(x, NULL, ctype(ULONGLONG))
172         t1 = buildtree(LSbuildtree(ANDccopy(a), X(255)), bcon(56));
173         t2 = buildtree(LSbuildtree(ANDccopy(a), X(255 << 8)), bcon(40));
174         t3 = buildtree(LSbuildtree(ANDccopy(a), X(255 << 16)), bcon(24));
175         t4 = buildtree(LSbuildtree(ANDccopy(a), X(255 << 24)), bcon(8));
176         t5 = buildtree(ANDbuildtree(RSccopy(a), bcon(8)), X(255 << 24));
177         t6 = buildtree(ANDbuildtree(RSccopy(a), bcon(24)), X(255 << 16));
178         t7 = buildtree(ANDbuildtree(RSccopy(a), bcon(40)), X(255 << 8));
179         t8 = buildtree(ANDbuildtree(RSabcon(56)), X(255));
180         f = buildtree(OR,
181             buildtree(ORbuildtree(ORt1t2), buildtree(ORt3t4)),
182             buildtree(ORbuildtree(ORt5t6), buildtree(ORt7t8)));
183         return f;
184 #undef X
185 }
186
187 #endif
188
ragge
1.30
189 #ifndef TARGET_CXZ
190 /*
191  * Find number of beginning 0's in a word of type t.
192  * t should be deunsigned.
193  */
194 static NODE *
ragge
1.36
195 builtin_cxz(NODE *aTWORD tint isclz)
ragge
1.30
196 {
197         NODE *t101, *t102;
198         NODE *rn, *p;
199         int l15l16l17;
200         int sz;
201
202         t = ctype(t);
203         sz = (int)tsize(t00);
204
205         t101 = tempnode(0INT00);
206         t102 = tempnode(0t00);
207         l15 = getlab();
208         l16 = getlab();
209         l17 = getlab();
210         rn = buildtree(ASSIGNccopy(t102), a);
211         rn = cmop(rnbuildtree(ASSIGNccopy(t101), bcon(0)));
212         rn = cmop(rnlblnod(l16));
213
214         p = buildtree(CBRANCHbuildtree(GEccopy(t101), bcon(sz)), bcon(l15));
215         rn = cmop(rnp);
216         if (isclz) {
217                 p = buildtree(CBRANCH,
218                     buildtree(GEccopy(t102), bcon(0)), bcon(l17));
219         } else {
220                 p = buildtree(CBRANCH,
221                     buildtree(EQbuildtree(ANDccopy(t102), bcon(1)),
222                     bcon(0)), bcon(l17));
223         }
224         rn = cmop(rnp);
225
226         rn = cmop(rnblock(GOTObcon(l15), NILINT00));
227
228         rn = cmop(rnlblnod(l17));
229         rn = cmop(rnbuildtree(isclz ? LSEQ : RSEQ , t102bcon(1)));
230
231         rn = cmop(rnbuildtree(INCRccopy(t101), bcon(1)));
232
233         rn = cmop(rnblock(GOTObcon(l16), NILINT00));
234         rn = cmop(rnlblnod(l15));
235         return cmop(rnt101);
236 }
237
238 static NODE *
ragge
1.36
239 builtin_clz(const struct bitable *btNODE *a)
ragge
1.30
240 {
ragge
1.36
241         return builtin_cxz(aINT1);
ragge
1.30
242 }
243
244 static NODE *
ragge
1.36
245 builtin_clzl(const struct bitable *btNODE *a)
ragge
1.30
246 {
ragge
1.36
247         return builtin_cxz(aLONG1);
ragge
1.30
248 }
249
250 static NODE *
ragge
1.36
251 builtin_clzll(const struct bitable *btNODE *a)
ragge
1.30
252 {
ragge
1.36
253         return builtin_cxz(aLONGLONG1);
ragge
1.30
254 }
255
256 static NODE *
ragge
1.36
257 builtin_ctz(const struct bitable *btNODE *a)
ragge
1.30
258 {
ragge
1.36
259         return builtin_cxz(aINT0);
ragge
1.30
260 }
261
262 static NODE *
ragge
1.36
263 builtin_ctzl(const struct bitable *btNODE *a)
ragge
1.30
264 {
ragge
1.36
265         return builtin_cxz(aLONG0);
ragge
1.30
266 }
267
268 static NODE *
ragge
1.36
269 builtin_ctzll(const struct bitable *btNODE *a)
ragge
1.30
270 {
ragge
1.36
271         return builtin_cxz(aLONGLONG0);
ragge
1.30
272 }
273 #endif
274
ragge
1.43
275 #ifndef TARGET_ERA
276 static NODE *
277 builtin_era(const struct bitable *btNODE *a)
278 {
279         return a;       /* Just pass through */
280 }
281 #endif
282
ragge
1.30
283 #ifndef TARGET_FFS
284 /*
285  * Find number of beginning 0's in a word of type t.
286  * t should be deunsigned.
287  */
288 static NODE *
ragge
1.36
289 builtin_ff(NODE *aTWORD t)
ragge
1.30
290 {
291         NODE *t101, *t102;
292         NODE *rn, *p;
293         int l15l16l17;
294         int sz;
295
296         t = ctype(t);
297         sz = (int)tsize(t00)+1;
298
299         t101 = tempnode(0INT00);
300         t102 = tempnode(0t00);
301         l15 = getlab();
302         l16 = getlab();
303         l17 = getlab();
304         rn = buildtree(ASSIGNccopy(t101), bcon(0));
305         rn = cmop(rnbuildtree(ASSIGNccopy(t102), a));
306
307         p = buildtree(CBRANCHbuildtree(EQccopy(t102), bcon(0)), bcon(l15));
308         rn = cmop(rnp);
309
310         rn = cmop(rnbuildtree(INCRccopy(t101), bcon(1)));
311
312         rn = cmop(rnlblnod(l16));
313
314         p = buildtree(CBRANCHbuildtree(GEccopy(t101), bcon(sz)), bcon(l15));
315         rn = cmop(rnp);
316
317         p = buildtree(CBRANCH,
318             buildtree(EQbuildtree(ANDccopy(t102), bcon(1)),
319             bcon(0)), bcon(l17));
320         rn = cmop(rnp);
321
322         rn = cmop(rnblock(GOTObcon(l15), NILINT00));
323
324         rn = cmop(rnlblnod(l17));
325         rn = cmop(rnbuildtree(RSEQt102bcon(1)));
326
327         rn = cmop(rnbuildtree(INCRccopy(t101), bcon(1)));
328
329         rn = cmop(rnblock(GOTObcon(l16), NILINT00));
330         rn = cmop(rnlblnod(l15));
331         return cmop(rnt101);
332 }
333
334 static NODE *
ragge
1.36
335 builtin_ffs(const struct bitable *btNODE *a)
ragge
1.30
336 {
ragge
1.36
337         return builtin_ff(aINT);
ragge
1.30
338 }
339
340 static NODE *
ragge
1.36
341 builtin_ffsl(const struct bitable *btNODE *a)
ragge
1.30
342 {
ragge
1.36
343         return builtin_ff(aLONG);
ragge
1.30
344 }
345
346 static NODE *
ragge
1.36
347 builtin_ffsll(const struct bitable *btNODE *a)
ragge
1.30
348 {
ragge
1.36
349         return builtin_ff(aLONGLONG);
ragge
1.30
350 }
351 #endif
352
ragge
1.11
353 /*
354  * Get size of object, if possible.
355  * Currently does nothing,
356  */
357 static NODE *
ragge
1.36
358 builtin_object_size(const struct bitable *btNODE *a)
ragge
1.11
359 {
plunky
1.35
360         CONSZ v = icons(a->n_right);
ragge
1.36
361         NODE *f;
362
ragge
1.11
363         if (v < 0 || v > 3)
364                 uerror("arg2 must be between 0 and 3");
ragge
1.14
365
ragge
1.36
366         f = buildtree(COMOPa->n_leftxbcon(v < 2 ? -1 : 0NULLbt->rt));
ragge
1.11
367         nfree(a);
ragge
1.14
368         return f;
ragge
1.11
369 }
370
ragge
1.1
371 #ifndef TARGET_STDARGS
372 static NODE *
ragge
1.37
373 builtin_stdarg_start(const struct bitable *btNODE *a)
ragge
1.1
374 {
375         NODE *p, *q;
376         int sz;
377
378         /* must first deal with argument size; use int size */
379         p = a->n_right;
380         if (p->n_type < INT) {
ragge
1.7
381                 sz = (int)(SZINT/tsize(p->n_typep->n_dfp->n_ap));
ragge
1.1
382         } else
383                 sz = 1;
384
385         /* do the real job */
386         p = buildtree(ADDROFpNIL); /* address of last arg */
387 #ifdef BACKAUTO
388         p = optim(buildtree(PLUSpbcon(sz))); /* add one to it (next arg) */
389 #else
390         p = optim(buildtree(MINUSpbcon(sz))); /* add one to it (next arg) */
391 #endif
392         q = block(NAMENILNILPTR+VOID00); /* create cast node */
393         q = buildtree(CASTqp); /* cast to void * (for assignment) */
394         p = q->n_right;
395         nfree(q->n_left);
396         nfree(q);
397         p = buildtree(ASSIGNa->n_leftp); /* assign to ap */
398         nfree(a);
399         return p;
400 }
401
402 static NODE *
ragge
1.37
403 builtin_va_arg(const struct bitable *btNODE *a)
ragge
1.1
404 {
405         NODE *p, *q, *r, *rv;
406         int sznodnum;
407
408         /* create a copy to a temp node of current ap */
409         p = ccopy(a->n_left);
ragge
1.7
410         q = tempnode(0p->n_typep->n_dfp->n_ap);
ragge
1.1
411         nodnum = regno(q);
412         rv = buildtree(ASSIGNqp);
413
414         r = a->n_right;
ragge
1.7
415         sz = (int)tsize(r->n_typer->n_dfr->n_ap)/SZCHAR;
ragge
1.1
416         /* add one to ap */
417 #ifdef BACKAUTO
418         rv = buildtree(COMOPrv , buildtree(PLUSEQa->n_leftbcon(sz)));
419 #else
420 #error fix wrong eval order in builtin_va_arg
421         ecomp(buildtree(MINUSEQa->n_leftbcon(sz)));
422 #endif
423
424         nfree(a->n_right);
425         nfree(a);
ragge
1.7
426         r = tempnode(nodnumINCREF(r->n_type), r->n_dfr->n_ap);
ragge
1.1
427         return buildtree(COMOPrvbuildtree(UMULrNIL));
428
429 }
430
431 static NODE *
ragge
1.37
432 builtin_va_end(const struct bitable *btNODE *a)
ragge
1.1
433 {
434         tfree(a);
435         return bcon(0); /* nothing */
436 }
437
438 static NODE *
ragge
1.37
439 builtin_va_copy(const struct bitable *btNODE *a)
ragge
1.1
440 {
ragge
1.37
441         NODE *f;
442
ragge
1.1
443         f = buildtree(ASSIGNa->n_lefta->n_right);
444         nfree(a);
445         return f;
446 }
447 #endif /* TARGET_STDARGS */
448
ragge
1.2
449 /*
450  * For unimplemented "builtin" functions, try to invoke the
451  * non-builtin name
452  */
453 static NODE *
ragge
1.36
454 binhelp(NODE *aTWORD rtchar *n)
ragge
1.2
455 {
ragge
1.36
456         NODE *f = block(NAMENILNILINT00);
ragge
1.52
457         int oblvl = blevel;
ragge
1.36
458
ragge
1.52
459         blevel = 0;
ragge
1.13
460         f->n_sp = lookup(addname(n), SNORMAL);
ragge
1.52
461         blevel = oblvl;
ragge
1.13
462         if (f->n_sp->sclass == SNULL) {
463                 f->n_sp->sclass = EXTERN;
464                 f->n_sp->stype = INCREF(rt)+(FTN-PTR);
ragge
1.52
465                 f->n_sp->sdf = permalloc(sizeof(union dimfun));
466                 f->n_sp->sdf->dfun = NULL;
ragge
1.13
467         }
468         f->n_type = f->n_sp->stype;
ragge
1.6
469         f = clocal(f);
ragge
1.2
470         return buildtree(CALLfa);
471 }
472
ragge
1.16
473 static NODE *
ragge
1.36
474 builtin_unimp(const struct bitable *btNODE *a)
ragge
1.16
475 {
ragge
1.36
476         return binhelp(abt->rt, &bt->name[10]);
ragge
1.16
477 }
478
ragge
1.30
479 #if 0
ragge
1.16
480 static NODE *
481 builtin_unimp_f(NODE *fNODE *aTWORD rt)
482 {
483         return binhelp(fartf->n_sp->sname);
484 }
ragge
1.30
485 #endif
ragge
1.16
486
ragge
1.29
487 #ifndef TARGET_PREFETCH
488 static NODE *
ragge
1.36
489 builtin_prefetch(const struct bitable *btNODE *a)
ragge
1.29
490 {
491         tfree(a);
492         return bcon(0);
493 }
494 #endif
495
ragge
1.18
496 #ifndef TARGET_ISMATH
497 /*
498  * Handle the builtin macros for the math functions is*
499  * To get something that is be somewhat generic assume that 
500  * isnan() is a real function and that cast of a NaN type 
501  * to double will still be a NaN.
502  */
503 static NODE *
504 mtisnan(NODE *p)
505 {
506
ragge
1.36
507         return binhelp(cast(ccopy(p), DOUBLE0), INT"isnan");
ragge
1.18
508 }
509
510 static TWORD
511 mtcheck(NODE *p)
512 {
513         TWORD t1 = p->n_left->n_typet2 = p->n_right->n_type;
514
515         if ((t1 >= FLOAT && t1 <= LDOUBLE) ||
516             (t2 >= FLOAT && t2 <= LDOUBLE))
517                 return MAX(t1t2);
518         return 0;
519 }
520
521 static NODE *
ragge
1.36
522 builtin_isunordered(const struct bitable *btNODE *a)
ragge
1.18
523 {
524         NODE *p;
525
526         if (mtcheck(a) == 0)
527                 return bcon(0);
528
529         p = buildtree(ORORmtisnan(a->n_left), mtisnan(a->n_right));
530         tfree(a);
531         return p;
532 }
533 static NODE *
ragge
1.36
534 builtin_isany(NODE *aTWORD rtint cmpt)
ragge
1.18
535 {
536         NODE *p, *q;
537         TWORD t;
538
539         if ((t = mtcheck(a)) == 0)
540                 return bcon(0);
541         p = buildtree(ORORmtisnan(a->n_left), mtisnan(a->n_right));
542         p = buildtree(NOTpNIL);
543         q = buildtree(cmptcast(ccopy(a->n_left), t0),
544             cast(ccopy(a->n_right), t0));
545         p = buildtree(ANDANDpq);
546         tfree(a);
547         return p;
548 }
549 static NODE *
ragge
1.36
550 builtin_isgreater(const struct bitable *btNODE *a)
ragge
1.18
551 {
ragge
1.36
552         return builtin_isany(abt->rtGT);
ragge
1.18
553 }
554 static NODE *
ragge
1.36
555 builtin_isgreaterequal(const struct bitable *btNODE *a)
ragge
1.18
556 {
ragge
1.36
557         return builtin_isany(abt->rtGE);
ragge
1.18
558 }
559 static NODE *
ragge
1.36
560 builtin_isless(const struct bitable *btNODE *a)
ragge
1.18
561 {
ragge
1.36
562         return builtin_isany(abt->rtLT);
ragge
1.18
563 }
564 static NODE *
ragge
1.36
565 builtin_islessequal(const struct bitable *btNODE *a)
ragge
1.18
566 {
ragge
1.36
567         return builtin_isany(abt->rtLE);
ragge
1.18
568 }
569 static NODE *
ragge
1.36
570 builtin_islessgreater(const struct bitable *btNODE *a)
ragge
1.18
571 {
572         NODE *p, *q, *r;
573         TWORD t;
574
575         if ((t = mtcheck(a)) == 0)
576                 return bcon(0);
577         p = buildtree(ORORmtisnan(a->n_left), mtisnan(a->n_right));
578         p = buildtree(NOTpNIL);
579         q = buildtree(GTcast(ccopy(a->n_left), t0),
580             cast(ccopy(a->n_right), t0));
581         r = buildtree(LTcast(ccopy(a->n_left), t0),
582             cast(ccopy(a->n_right), t0));
583         q = buildtree(ORORqr);
584         p = buildtree(ANDANDpq);
585         tfree(a);
586         return p;
587 }
588 #endif
589
ragge
1.2
590 /*
591  * Math-specific builtins that expands to constants.
plunky
1.50
592  * Versions here are for IEEE FP, vax needs its own versions.
ragge
1.2
593  */
ragge
1.26
594 #if TARGET_ENDIAN == TARGET_LE
plunky
1.46
595 static const unsigned char vFLOAT[] = { 000x800x7f };
596 static const unsigned char vDOUBLE[] = { 0000000xf00x7f };
ragge
1.2
597 #ifdef LDBL_128
plunky
1.46
598 static const unsigned char vLDOUBLE[] = { 0,0,0,0,0,0,00000000x800xff0x7f };
ragge
1.2
599 #else /* LDBL_80 */
plunky
1.46
600 static const unsigned char vLDOUBLE[] = { 00000000x800xff0x7f,0,0,0,0,0,0 };
ragge
1.2
601 #endif
plunky
1.46
602 static const unsigned char nFLOAT[] = { 000xc00x7f };
603 static const unsigned char nDOUBLE[] = { 0000000xf80x7f };
ragge
1.2
604 #ifdef LDBL_128
plunky
1.46
605 static const unsigned char nLDOUBLE[] = { 0,0,0,0,0,0,0,0000000xc00xff0x7f };
ragge
1.2
606 #else /* LDBL_80 */
plunky
1.46
607 static const unsigned char nLDOUBLE[] = { 00000000xc00xff0x7f,0,0,0,0,0,0 };
ragge
1.2
608 #endif
609 #else
plunky
1.46
610 static const unsigned char vFLOAT[] = { 0x7f0x8000 };
611 static const unsigned char vDOUBLE[] = { 0x7f0xf0000000 };
ragge
1.2
612 #ifdef LDBL_128
plunky
1.46
613 static const unsigned char vLDOUBLE[] = { 0x7f0xff0x800000000,0,0,0,0,0,0 };
ragge
1.2
614 #else /* LDBL_80 */
plunky
1.46
615 static const unsigned char vLDOUBLE[] = { 0x7f0xff0x800000000,0,0,0,0,0,0 };
ragge
1.2
616 #endif
plunky
1.46
617 static const unsigned char nFLOAT[] = { 0x7f0xc000 };
618 static const unsigned char nDOUBLE[] = { 0x7f0xf8000000 };
ragge
1.2
619 #ifdef LDBL_128
plunky
1.46
620 static const unsigned char nLDOUBLE[] = { 0x7f0xff0xc00000000,0,0,0,0,0,0 };
ragge
1.2
621 #else /* LDBL_80 */
plunky
1.46
622 static const unsigned char nLDOUBLE[] = { 0x7f0xff0xc00000000,0,0,0,0,0,0 };
ragge
1.2
623 #endif
624 #endif
625
626 #define VALX(typ,TYP) {                                         \
627         typ d;                                                  \
628         int x;                                                  \
ragge
1.36
629         NODE *f;                                                \
ragge
1.2
630         x = MIN(sizeof(n ## TYP), sizeof(d));                   \
631         memcpy(&dv ## TYPx);                                \
ragge
1.22
632         f = block(FCONNILNILTYPNULL0);        \
ragge
1.2
633         f->n_dcon = d;                                          \
634         return f;                                               \
635 }
636
637 static NODE *
ragge
1.36
638 builtin_huge_valf(const struct bitable *btNODE *aVALX(float,FLOAT)
ragge
1.2
639 static NODE *
ragge
1.36
640 builtin_huge_val(const struct bitable *btNODE *aVALX(double,DOUBLE)
ragge
1.2
641 static NODE *
ragge
1.36
642 builtin_huge_vall(const struct bitable *btNODE *aVALX(long double,LDOUBLE)
ragge
1.2
643
644 #define builtin_inff    builtin_huge_valf
645 #define builtin_inf     builtin_huge_val
646 #define builtin_infl    builtin_huge_vall
647
648 /*
649  * Return NANs, if reasonable.
650  */
651 static NODE *
ragge
1.36
652 builtin_nanx(const struct bitable *btNODE *a)
653 {
ragge
1.40
654
ragge
1.36
655         if (a == NULL || a->n_op == CM) {
656                 uerror("%s bad argument"bt->name);
657                 a = bcon(0);
658         } else if (a->n_op == STRING && *a->n_name == '\0') {
659                 a->n_op = FCON;
660                 a->n_type = bt->rt;
ragge
1.40
661                 if (sizeof(nLDOUBLE) < sizeof(a->n_dcon))
662                         cerror("nLDOUBLE too small");
ragge
1.36
663                 memcpy(&a->n_dconnLDOUBLEsizeof(a->n_dcon));
664         } else
665                 a = binhelp(eve(a), bt->rt, &bt->name[10]);
666         return a;
667 }
ragge
1.2
668
ragge
1.44
669 #ifndef NO_COMPLEX
670 static NODE *
671 builtin_cir(const struct bitable *btNODE *a)
672 {
673         char *n;
674
675         if (a == NIL || a->n_op == CM) {
676                 uerror("wrong argument count to %s"bt->name);
677                 return bcon(0);
678         }
679
680         n = addname(bt->name[1] == 'r' ? "__real" : "__imag");
681         return cast(structref(aDOTn), bt->rt0);
682 }
683
684 #endif
685
ragge
1.2
686 /*
687  * Target defines, to implement target versions of the generic builtins
688  */
ragge
1.21
689 #ifndef TARGET_MEMCMP
690 #define builtin_memcmp builtin_unimp
691 #endif
ragge
1.2
692 #ifndef TARGET_MEMCPY
693 #define builtin_memcpy builtin_unimp
694 #endif
plunky
1.34
695 #ifndef TARGET_MEMPCPY
696 #define builtin_mempcpy builtin_unimp
697 #endif
ragge
1.2
698 #ifndef TARGET_MEMSET
699 #define builtin_memset builtin_unimp
700 #endif
701
702 /* Reasonable type of size_t */
703 #ifndef SIZET
704 #if SZINT == SZSHORT
705 #define SIZET UNSIGNED
706 #elif SZLONG > SZINT
707 #define SIZET ULONG
708 #else
709 #define SIZET UNSIGNED
710 #endif
711 #endif
712
ragge
1.12
713 static TWORD memcpyt[] = { VOID|PTRVOID|PTRSIZETINT };
714 static TWORD memsett[] = { VOID|PTRINTSIZETINT };
ragge
1.2
715 static TWORD allocat[] = { SIZET };
716 static TWORD expectt[] = { LONGLONG };
ragge
1.8
717 static TWORD strcmpt[] = { CHAR|PTRCHAR|PTR };
ragge
1.12
718 static TWORD strcpyt[] = { CHAR|PTRCHAR|PTRINT };
719 static TWORD strncpyt[] = { CHAR|PTRCHAR|PTRSIZETINT };
ragge
1.9
720 static TWORD strchrt[] = { CHAR|PTRINT };
gmcgarry
1.19
721 static TWORD strcspnt[] = { CHAR|PTRCHAR|PTR };
gmcgarry
1.23
722 static TWORD strspnt[] = { CHAR|PTRCHAR|PTR };
gmcgarry
1.24
723 static TWORD strpbrkt[] = { CHAR|PTRCHAR|PTR };
ragge
1.2
724 static TWORD nant[] = { CHAR|PTR };
ragge
1.16
725 static TWORD bitt[] = { UNSIGNED };
ragge
1.48
726 static TWORD bsw16t[] = { USHORT };
ragge
1.16
727 static TWORD bitlt[] = { ULONG };
ragge
1.30
728 static TWORD bitllt[] = { ULONGLONG };
ragge
1.36
729 static TWORD abst[] = { INT };
plunky
1.51
730 static TWORD fmaxft[] = { FLOATFLOAT };
731 static TWORD fmaxt[] = { DOUBLEDOUBLE };
732 static TWORD fmaxlt[] = { LDOUBLELDOUBLE };
733 static TWORD scalbnft[] = { FLOATINT };
734 static TWORD scalbnt[] = { DOUBLEINT };
735 static TWORD scalbnlt[] = { LDOUBLEINT };
ragge
1.2
736
ragge
1.36
737 static const struct bitable bitable[] = {
ragge
1.41
738         /* gnu universe only */
739         { "alloca"builtin_allocaBTGNUONLY1allocatVOID|PTR },
740
ragge
1.44
741 #ifndef NO_COMPLEX
742         /* builtins for complex operations */
743         { "crealf"builtin_cirBTNOPROTO10FLOAT },
744         { "creal"builtin_cirBTNOPROTO10DOUBLE },
745         { "creall"builtin_cirBTNOPROTO10LDOUBLE },
746         { "cimagf"builtin_cirBTNOPROTO10FLOAT },
747         { "cimag"builtin_cirBTNOPROTO10DOUBLE },
748         { "cimagl"builtin_cirBTNOPROTO10LDOUBLE },
749 #endif
ragge
1.41
750         /* always existing builtins */
ragge
1.36
751         { "__builtin___memcpy_chk"builtin_unimp04memcpytVOID|PTR },
752         { "__builtin___mempcpy_chk"builtin_unimp04memcpytVOID|PTR },
753         { "__builtin___memmove_chk"builtin_unimp04memcpytVOID|PTR },
754         { "__builtin___memset_chk"builtin_unimp04memsettVOID|PTR },
755
756         { "__builtin___strcat_chk"builtin_unimp03strcpytCHAR|PTR },
757         { "__builtin___strcpy_chk"builtin_unimp03strcpytCHAR|PTR },
plunky
1.47
758         { "__builtin___stpcpy_chk"builtin_unimp03strcpytCHAR|PTR },
ragge
1.36
759         { "__builtin___strncat_chk"builtin_unimp04strncpyt,CHAR|PTR },
760         { "__builtin___strncpy_chk"builtin_unimp04strncpyt,CHAR|PTR },
plunky
1.47
761         { "__builtin___stpncpy_chk"builtin_unimp04strncpyt,CHAR|PTR },
ragge
1.36
762
763         { "__builtin___printf_chk"builtin_unimpBTNOPROTO, -10INT },
764         { "__builtin___fprintf_chk"builtin_unimpBTNOPROTO, -10INT },
765         { "__builtin___sprintf_chk"builtin_unimpBTNOPROTO, -10INT },
766         { "__builtin___snprintf_chk"builtin_unimpBTNOPROTO, -10INT },
767         { "__builtin___vprintf_chk"builtin_unimpBTNOPROTO, -10INT },
768         { "__builtin___vfprintf_chk"builtin_unimpBTNOPROTO, -10INT },
769         { "__builtin___vsprintf_chk"builtin_unimpBTNOPROTO, -10INT },
770         { "__builtin___vsnprintf_chk"builtin_unimpBTNOPROTO, -10INT },
771
772         { "__builtin_alloca"builtin_alloca01allocatVOID|PTR },
773         { "__builtin_abs"builtin_abs01abstINT },
ragge
1.48
774         { "__builtin_bswap16"builtin_bswap1601bsw16tUSHORT },
775         { "__builtin_bswap32"builtin_bswap3201bittUNSIGNED },
776         { "__builtin_bswap64"builtin_bswap6401bitlltULONGLONG },
ragge
1.36
777         { "__builtin_clz"builtin_clz01bittINT },
778         { "__builtin_clzl"builtin_clzl01bitltINT },
779         { "__builtin_clzll"builtin_clzll01bitlltINT },
780         { "__builtin_ctz"builtin_ctz01bittINT },
781         { "__builtin_ctzl"builtin_ctzl01bitltINT },
782         { "__builtin_ctzll"builtin_ctzll01bitlltINT },
ragge
1.43
783         { "__builtin_extract_return_addr"builtin_era01memcpytVOID|PTR },
ragge
1.36
784         { "__builtin_ffs"builtin_ffs01bittINT },
785         { "__builtin_ffsl"builtin_ffsl01bitltINT },
786         { "__builtin_ffsll"builtin_ffsll01bitlltINT },
787         { "__builtin_popcount"builtin_unimp01bittUNSIGNED },
788         { "__builtin_popcountl"builtin_unimp01bitltULONG },
789         { "__builtin_popcountll"builtin_unimp01bitlltULONGLONG },
790
791         { "__builtin_constant_p"builtin_constant_p010INT },
plunky
1.51
792         { "__builtin_copysignf"builtin_unimp02fmaxftFLOAT },
793         { "__builtin_copysign"builtin_unimp02fmaxtDOUBLE },
794         { "__builtin_copysignl"builtin_unimp02fmaxltLDOUBLE },
ragge
1.36
795         { "__builtin_expect"builtin_expect02expecttLONG },
796         { "__builtin_memcmp"builtin_memcmp03memcpytINT },
797         { "__builtin_memcpy"builtin_memcpy03memcpytVOID|PTR },
798         { "__builtin_mempcpy"builtin_mempcpy03memcpytVOID|PTR },
799         { "__builtin_memset"builtin_memset03memsettVOID|PTR },
plunky
1.51
800         { "__builtin_fabsf"builtin_unimp01fmaxftFLOAT },
801         { "__builtin_fabs"builtin_unimp01fmaxtDOUBLE },
802         { "__builtin_fabsl"builtin_unimp01fmaxltLDOUBLE },
803         { "__builtin_fmaxf"builtin_unimp02fmaxftFLOAT },
804         { "__builtin_fmax"builtin_unimp02fmaxtDOUBLE },
805         { "__builtin_fmaxl"builtin_unimp02fmaxltLDOUBLE },
ragge
1.36
806         { "__builtin_huge_valf"builtin_huge_valf000FLOAT },
807         { "__builtin_huge_val"builtin_huge_val000DOUBLE },
808         { "__builtin_huge_vall"builtin_huge_vall000LDOUBLE },
809         { "__builtin_inff"builtin_inff000FLOAT },
810         { "__builtin_inf"builtin_inf000DOUBLE },
811         { "__builtin_infl"builtin_infl000LDOUBLE },
812         { "__builtin_isgreater"builtin_isgreater02NULLINT },
813         { "__builtin_isgreaterequal"builtin_isgreaterequal02NULLINT },
plunky
1.51
814         { "__builtin_isinff"builtin_unimp01fmaxftINT },
815         { "__builtin_isinf"builtin_unimp01fmaxtINT },
816         { "__builtin_isinfl"builtin_unimp01fmaxltINT },
ragge
1.36
817         { "__builtin_isless"builtin_isless02NULLINT },
818         { "__builtin_islessequal"builtin_islessequal02NULLINT },
819         { "__builtin_islessgreater"builtin_islessgreater02NULLINT },
plunky
1.51
820         { "__builtin_isnanf"builtin_unimp01fmaxftINT },
821         { "__builtin_isnan"builtin_unimp01fmaxtINT },
822         { "__builtin_isnanl"builtin_unimp01fmaxltINT },
ragge
1.36
823         { "__builtin_isunordered"builtin_isunordered02NULLINT },
plunky
1.51
824         { "__builtin_logbf"builtin_unimp01fmaxftFLOAT },
825         { "__builtin_logb"builtin_unimp01fmaxtDOUBLE },
826         { "__builtin_logbl"builtin_unimp01fmaxltLDOUBLE },
ragge
1.36
827         { "__builtin_nanf"builtin_nanxBTNOEVE1nantFLOAT },
828         { "__builtin_nan"builtin_nanxBTNOEVE1nantDOUBLE },
829         { "__builtin_nanl"builtin_nanxBTNOEVE1nantLDOUBLE },
830         { "__builtin_object_size"builtin_object_size02memsettSIZET },
831         { "__builtin_prefetch"builtin_prefetch01memsettVOID },
plunky
1.51
832         { "__builtin_scalbnf"builtin_unimp02scalbnftFLOAT },
833         { "__builtin_scalbn"builtin_unimp02scalbntDOUBLE },
834         { "__builtin_scalbnl"builtin_unimp02scalbnltLDOUBLE },
ragge
1.36
835         { "__builtin_strcmp"builtin_unimp02strcmptINT },
836         { "__builtin_strcpy"builtin_unimp02strcpytCHAR|PTR },
837         { "__builtin_stpcpy"builtin_unimp02strcpytCHAR|PTR },
838         { "__builtin_strchr"builtin_unimp02strchrtCHAR|PTR },
839         { "__builtin_strlen"builtin_unimp01strcmptSIZET },
840         { "__builtin_strrchr"builtin_unimp02strchrtCHAR|PTR },
841         { "__builtin_strncpy"builtin_unimp03strncpytCHAR|PTR },
842         { "__builtin_strncat"builtin_unimp03strncpytCHAR|PTR },
843         { "__builtin_strcspn"builtin_unimp02strcspntSIZET },
844         { "__builtin_strspn"builtin_unimp02strspntSIZET },
845         { "__builtin_strstr"builtin_unimp02strcmptCHAR|PTR },
846         { "__builtin_strpbrk"builtin_unimp02strpbrktCHAR|PTR },
ragge
1.1
847 #ifndef TARGET_STDARGS
ragge
1.37
848         { "__builtin_stdarg_start"builtin_stdarg_start020VOID },
849         { "__builtin_va_start"builtin_stdarg_start020VOID },
850         { "__builtin_va_arg"builtin_va_argBTNORVAL|BTNOPROTO200 },
851         { "__builtin_va_end"builtin_va_end010VOID },
852         { "__builtin_va_copy"builtin_va_copy020VOID },
ragge
1.1
853 #endif
ragge
1.43
854         { "__builtin_dwarf_cfa"builtin_cfa000VOID|PTR },
855         { "__builtin_frame_address",
856             builtin_frame_address01bittVOID|PTR },
857         { "__builtin_return_address",
858             builtin_return_address01bittVOID|PTR },
ragge
1.1
859 #ifdef TARGET_BUILTINS
860         TARGET_BUILTINS
861 #endif
862 };
863
ragge
1.2
864 /*
865  * Check and cast arguments for builtins.
866  */
ragge
1.1
867 static int
ragge
1.2
868 acnt(NODE *aint nargTWORD *tp)
ragge
1.1
869 {
ragge
1.2
870         NODE *q;
871         TWORD t;
872
ragge
1.1
873         if (a == NIL)
874                 return narg;
ragge
1.2
875         for (; a->n_op == CMa = a->n_leftnarg--) {
876                 if (tp == NULL)
877                         continue;
878                 q = a->n_right;
ragge
1.28
879                 t = ctype(tp[narg-1]);
ragge
1.2
880                 if (q->n_type == t)
881                         continue;
ragge
1.22
882                 a->n_right = ccast(qt0NULL0);
ragge
1.2
883         }
884
885         /* Last arg is ugly to deal with */
ragge
1.36
886         if (narg == 1 && tp != NULL && a->n_type != tp[0]) {
ragge
1.2
887                 q = talloc();
888                 *q = *a;
ragge
1.28
889                 q = ccast(qctype(tp[0]), 0NULL0);
ragge
1.2
890                 *a = *q;
891                 nfree(q);
892         }
ragge
1.1
893         return narg != 1;
894 }
895
896 NODE *
ragge
1.36
897 builtin_check(struct symtab *spNODE *a)
ragge
1.1
898 {
ragge
1.4
899         const struct bitable *bt;
ragge
1.36
900
901         if (sp->soffset < 0 ||
902             sp->soffset >= (int)(sizeof(bitable)/sizeof(bitable[0])))
903                 cerror("builtin_check");
904
905         bt = &bitable[sp->soffset];
ragge
1.38
906         if ((bt->flags & BTNOEVE) == 0 && a != NIL)
ragge
1.36
907                 a = eve(a);
908         if (((bt->flags & BTNOPROTO) == 0) && acnt(abt->nargbt->tp)) {
909                 uerror("wrong argument count to %s"bt->name);
910                 return bcon(0);
911         }
912         return (*bt->fun)(bta);
913 }
914
915 /*
916  * Put all builtin functions into the global symbol table.
917  */
918 void
919 builtin_init()
920 {
921         const struct bitable *bt;
922         NODE *p = block(TYPE00000);
923         struct symtab *sp;
ragge
1.39
924         int id_debug;
ragge
1.1
925
ragge
1.39
926         d_debug = ddebug;
927         ddebug = 0;
ragge
1.1
928         for (i = 0i < (int)(sizeof(bitable)/sizeof(bitable[0])); i++) {
ragge
1.2
929                 bt = &bitable[i];
ragge
1.41
930                 if ((bt->flags & BTGNUONLY) && xgnu99 == 0 && xgnu89 == 0)
931                         continue/* not in c99 universe, at least for now */
ragge
1.36
932                 sp = lookup(addname(bt->name), 0);
933                 if (bt->rt == 0 && (bt->flags & BTNORVAL) == 0)
934                         cerror("function '%s' has no return type"bt->name);
935                 p->n_type = INCREF(bt->rt) + (FTN-PTR);
ragge
1.42
936                 p->n_df = memset(permalloc(sizeof(union dimfun)), 0,
937                     sizeof(union dimfun));
ragge
1.36
938                 p->n_sp = sp;
ragge
1.45
939                 defid(pEXTERN);
ragge
1.36
940                 sp->soffset = i;
941                 sp->sflags |= SBUILTIN;
ragge
1.1
942         }
ragge
1.36
943         nfree(p);
ragge
1.39
944         ddebug = d_debug;
ragge
1.1
945 }
946 #endif
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-09-01 20:42 +0200