Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20121022085148

Diff

Diff from 1.4 to:

Annotations

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

Annotated File View

plunky
1.4
1 /*      $Id: builtins.c,v 1.4 2012/10/22 08:51:48 plunky 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
29 #ifndef MIN
30 #define MIN(a,b) (((a)<(b))?(a):(b))
31 #endif
32 #ifndef MAX
33 #define MAX(a,b) (((a)>(b))?(a):(b))
34 #endif
35
36 #ifndef NO_C_BUILTINS
ragge
1.3
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.3
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
52         t = tempnode(0VOID|PTR00);
53         u = tempnode(regno(t), VOID|PTR00);
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.3
64 builtin_constant_p(const struct bitable *btNODE *a)
ragge
1.1
65 {
66         void putjops(NODE *pvoid *arg);
ragge
1.3
67         NODE *f;
ragge
1.1
68         int isconst;
69
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);
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.3
83 builtin_expect(const struct bitable *btNODE *a)
ragge
1.1
84 {
ragge
1.3
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.3
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 {
115                 t = tempnode(0a->n_typea->n_dfa->n_ap);
116                 tmp1 = regno(t);
117                 p = buildtree(ASSIGNta);
118
119                 t = tempnode(tmp1a->n_typea->n_dfa->n_ap);
120                 shift = (int)tsize(a->n_typea->n_dfa->n_ap) - 1;
121                 q = buildtree(RStbcon(shift));
122
123                 t2 = tempnode(0a->n_typea->n_dfa->n_ap);
124                 tmp2 = regno(t2);
125                 q = buildtree(ASSIGNt2q);
126
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);
130                 r = buildtree(MINUSbuildtree(ERtt2), t3);
131
132                 p = buildtree(COMOPpbuildtree(COMOPqr));
133         }
134
135         return p;
136 }
137
138 #define cmop(x,y) buildtree(COMOP, x, y)
139 #define lblnod(l) nlabel(l)
140
141 #ifndef TARGET_CXZ
142 /*
143  * Find number of beginning 0's in a word of type t.
144  * t should be deunsigned.
145  */
146 static NODE *
ragge
1.3
147 builtin_cxz(NODE *aTWORD tint isclz)
ragge
1.1
148 {
149         NODE *t101, *t102;
150         NODE *rn, *p;
151         int l15l16l17;
152         int sz;
153
154         t = ctype(t);
155         sz = (int)tsize(t00);
156
157         t101 = tempnode(0INT00);
158         t102 = tempnode(0t00);
159         l15 = getlab();
160         l16 = getlab();
161         l17 = getlab();
162         rn = buildtree(ASSIGNccopy(t102), a);
163         rn = cmop(rnbuildtree(ASSIGNccopy(t101), bcon(0)));
164         rn = cmop(rnlblnod(l16));
165
166         p = buildtree(CBRANCHbuildtree(GEccopy(t101), bcon(sz)), bcon(l15));
167         rn = cmop(rnp);
168         if (isclz) {
169                 p = buildtree(CBRANCH,
170                     buildtree(GEccopy(t102), bcon(0)), bcon(l17));
171         } else {
172                 p = buildtree(CBRANCH,
173                     buildtree(EQbuildtree(ANDccopy(t102), bcon(1)),
174                     bcon(0)), bcon(l17));
175         }
176         rn = cmop(rnp);
177
178         rn = cmop(rnblock(GOTObcon(l15), NILINT00));
179
180         rn = cmop(rnlblnod(l17));
181         rn = cmop(rnbuildtree(isclz ? LSEQ : RSEQ , t102bcon(1)));
182
183         rn = cmop(rnbuildtree(INCRccopy(t101), bcon(1)));
184
185         rn = cmop(rnblock(GOTObcon(l16), NILINT00));
186         rn = cmop(rnlblnod(l15));
187         return cmop(rnt101);
188 }
189
190 static NODE *
ragge
1.3
191 builtin_clz(const struct bitable *btNODE *a)
ragge
1.1
192 {
ragge
1.3
193         return builtin_cxz(aINT1);
ragge
1.1
194 }
195
196 static NODE *
ragge
1.3
197 builtin_clzl(const struct bitable *btNODE *a)
ragge
1.1
198 {
ragge
1.3
199         return builtin_cxz(aLONG1);
ragge
1.1
200 }
201
202 static NODE *
ragge
1.3
203 builtin_clzll(const struct bitable *btNODE *a)
ragge
1.1
204 {
ragge
1.3
205         return builtin_cxz(aLONGLONG1);
ragge
1.1
206 }
207
208 static NODE *
ragge
1.3
209 builtin_ctz(const struct bitable *btNODE *a)
ragge
1.1
210 {
ragge
1.3
211         return builtin_cxz(aINT0);
ragge
1.1
212 }
213
214 static NODE *
ragge
1.3
215 builtin_ctzl(const struct bitable *btNODE *a)
ragge
1.1
216 {
ragge
1.3
217         return builtin_cxz(aLONG0);
ragge
1.1
218 }
219
220 static NODE *
ragge
1.3
221 builtin_ctzll(const struct bitable *btNODE *a)
ragge
1.1
222 {
ragge
1.3
223         return builtin_cxz(aLONGLONG0);
ragge
1.1
224 }
225 #endif
226
227 #ifndef TARGET_FFS
228 /*
229  * Find number of beginning 0's in a word of type t.
230  * t should be deunsigned.
231  */
232 static NODE *
ragge
1.3
233 builtin_ff(NODE *aTWORD t)
ragge
1.1
234 {
235         NODE *t101, *t102;
236         NODE *rn, *p;
237         int l15l16l17;
238         int sz;
239
240         t = ctype(t);
241         sz = (int)tsize(t00)+1;
242
243         t101 = tempnode(0INT00);
244         t102 = tempnode(0t00);
245         l15 = getlab();
246         l16 = getlab();
247         l17 = getlab();
248         rn = buildtree(ASSIGNccopy(t101), bcon(0));
249         rn = cmop(rnbuildtree(ASSIGNccopy(t102), a));
250
251         p = buildtree(CBRANCHbuildtree(EQccopy(t102), bcon(0)), bcon(l15));
252         rn = cmop(rnp);
253
254         rn = cmop(rnbuildtree(INCRccopy(t101), bcon(1)));
255
256         rn = cmop(rnlblnod(l16));
257
258         p = buildtree(CBRANCHbuildtree(GEccopy(t101), bcon(sz)), bcon(l15));
259         rn = cmop(rnp);
260
261         p = buildtree(CBRANCH,
262             buildtree(EQbuildtree(ANDccopy(t102), bcon(1)),
263             bcon(0)), bcon(l17));
264         rn = cmop(rnp);
265
266         rn = cmop(rnblock(GOTObcon(l15), NILINT00));
267
268         rn = cmop(rnlblnod(l17));
269         rn = cmop(rnbuildtree(RSEQt102bcon(1)));
270
271         rn = cmop(rnbuildtree(INCRccopy(t101), bcon(1)));
272
273         rn = cmop(rnblock(GOTObcon(l16), NILINT00));
274         rn = cmop(rnlblnod(l15));
275         return cmop(rnt101);
276 }
277
278 static NODE *
ragge
1.3
279 builtin_ffs(const struct bitable *btNODE *a)
ragge
1.1
280 {
ragge
1.3
281         return builtin_ff(aINT);
ragge
1.1
282 }
283
284 static NODE *
ragge
1.3
285 builtin_ffsl(const struct bitable *btNODE *a)
ragge
1.1
286 {
ragge
1.3
287         return builtin_ff(aLONG);
ragge
1.1
288 }
289
290 static NODE *
ragge
1.3
291 builtin_ffsll(const struct bitable *btNODE *a)
ragge
1.1
292 {
ragge
1.3
293         return builtin_ff(aLONGLONG);
ragge
1.1
294 }
295 #endif
296
297 /*
298  * Get size of object, if possible.
299  * Currently does nothing,
300  */
301 static NODE *
ragge
1.3
302 builtin_object_size(const struct bitable *btNODE *a)
ragge
1.1
303 {
plunky
1.2
304         CONSZ v = icons(a->n_right);
ragge
1.3
305         NODE *f;
306
ragge
1.1
307         if (v < 0 || v > 3)
308                 uerror("arg2 must be between 0 and 3");
309
ragge
1.3
310         f = buildtree(COMOPa->n_leftxbcon(v < 2 ? -1 : 0NULLbt->rt));
ragge
1.1
311         nfree(a);
312         return f;
313 }
314
315 #ifndef TARGET_STDARGS
316 static NODE *
ragge
1.3
317 builtin_stdarg_start(const struct bitable *btNODE *a)
ragge
1.1
318 {
319         NODE *p, *q;
320         int sz;
321
322         /* must first deal with argument size; use int size */
323         p = a->n_right;
324         if (p->n_type < INT) {
325                 sz = (int)(SZINT/tsize(p->n_typep->n_dfp->n_ap));
326         } else
327                 sz = 1;
328
329         /* do the real job */
330         p = buildtree(ADDROFpNIL); /* address of last arg */
331 #ifdef BACKAUTO
332         p = optim(buildtree(PLUSpbcon(sz))); /* add one to it (next arg) */
333 #else
334         p = optim(buildtree(MINUSpbcon(sz))); /* add one to it (next arg) */
335 #endif
336         q = block(NAMENILNILPTR+VOID00); /* create cast node */
337         q = buildtree(CASTqp); /* cast to void * (for assignment) */
338         p = q->n_right;
339         nfree(q->n_left);
340         nfree(q);
341         p = buildtree(ASSIGNa->n_leftp); /* assign to ap */
342         nfree(a);
343         return p;
344 }
345
346 static NODE *
ragge
1.3
347 builtin_va_arg(const struct bitable *btNODE *a)
ragge
1.1
348 {
349         NODE *p, *q, *r, *rv;
350         int sznodnum;
351
352         /* create a copy to a temp node of current ap */
353         p = ccopy(a->n_left);
354         q = tempnode(0p->n_typep->n_dfp->n_ap);
355         nodnum = regno(q);
356         rv = buildtree(ASSIGNqp);
357
358         r = a->n_right;
359         sz = (int)tsize(r->n_typer->n_dfr->n_ap)/SZCHAR;
360         /* add one to ap */
361 #ifdef BACKAUTO
362         rv = buildtree(COMOPrv , buildtree(PLUSEQa->n_leftbcon(sz)));
363 #else
364 #error fix wrong eval order in builtin_va_arg
365         ecomp(buildtree(MINUSEQa->n_leftbcon(sz)));
366 #endif
367
368         nfree(a->n_right);
369         nfree(a);
370         r = tempnode(nodnumINCREF(r->n_type), r->n_dfr->n_ap);
371         return buildtree(COMOPrvbuildtree(UMULrNIL));
372
373 }
374
375 static NODE *
ragge
1.3
376 builtin_va_end(const struct bitable *btNODE *a)
ragge
1.1
377 {
378         tfree(a);
379         return bcon(0); /* nothing */
380 }
381
382 static NODE *
ragge
1.3
383 builtin_va_copy(const struct bitable *btNODE *a)
ragge
1.1
384 {
ragge
1.3
385         NODE *f;
386
ragge
1.1
387         f = buildtree(ASSIGNa->n_lefta->n_right);
388         nfree(a);
389         return f;
390 }
391 #endif /* TARGET_STDARGS */
392
393 /*
394  * For unimplemented "builtin" functions, try to invoke the
395  * non-builtin name
396  */
397 static NODE *
ragge
1.3
398 binhelp(NODE *aTWORD rtchar *n)
ragge
1.1
399 {
ragge
1.3
400         NODE *f = block(NAMENILNILINT00);
401
ragge
1.1
402         f->n_sp = lookup(addname(n), SNORMAL);
403         if (f->n_sp->sclass == SNULL) {
404                 f->n_sp->sclass = EXTERN;
405                 f->n_sp->stype = INCREF(rt)+(FTN-PTR);
406         }
407         f->n_type = f->n_sp->stype;
408         f = clocal(f);
409         return buildtree(CALLfa);
410 }
411
412 static NODE *
ragge
1.3
413 builtin_unimp(const struct bitable *btNODE *a)
ragge
1.1
414 {
ragge
1.3
415         return binhelp(abt->rt, &bt->name[10]);
ragge
1.1
416 }
417
418 #if 0
419 static NODE *
420 builtin_unimp_f(NODE *fNODE *aTWORD rt)
421 {
422         return binhelp(fartf->n_sp->sname);
423 }
424 #endif
425
426 #ifndef TARGET_PREFETCH
427 static NODE *
ragge
1.3
428 builtin_prefetch(const struct bitable *btNODE *a)
ragge
1.1
429 {
430         tfree(a);
431         return bcon(0);
432 }
433 #endif
434
435 #ifndef TARGET_ISMATH
436 /*
437  * Handle the builtin macros for the math functions is*
438  * To get something that is be somewhat generic assume that 
439  * isnan() is a real function and that cast of a NaN type 
440  * to double will still be a NaN.
441  */
442 static NODE *
443 mtisnan(NODE *p)
444 {
445
ragge
1.3
446         return binhelp(cast(ccopy(p), DOUBLE0), INT"isnan");
ragge
1.1
447 }
448
449 static TWORD
450 mtcheck(NODE *p)
451 {
452         TWORD t1 = p->n_left->n_typet2 = p->n_right->n_type;
453
454         if ((t1 >= FLOAT && t1 <= LDOUBLE) ||
455             (t2 >= FLOAT && t2 <= LDOUBLE))
456                 return MAX(t1t2);
457         return 0;
458 }
459
460 static NODE *
ragge
1.3
461 builtin_isunordered(const struct bitable *btNODE *a)
ragge
1.1
462 {
463         NODE *p;
464
465         if (mtcheck(a) == 0)
466                 return bcon(0);
467
468         p = buildtree(ORORmtisnan(a->n_left), mtisnan(a->n_right));
469         tfree(a);
470         return p;
471 }
472 static NODE *
ragge
1.3
473 builtin_isany(NODE *aTWORD rtint cmpt)
ragge
1.1
474 {
475         NODE *p, *q;
476         TWORD t;
477
478         if ((t = mtcheck(a)) == 0)
479                 return bcon(0);
480         p = buildtree(ORORmtisnan(a->n_left), mtisnan(a->n_right));
481         p = buildtree(NOTpNIL);
482         q = buildtree(cmptcast(ccopy(a->n_left), t0),
483             cast(ccopy(a->n_right), t0));
484         p = buildtree(ANDANDpq);
485         tfree(a);
486         return p;
487 }
488 static NODE *
ragge
1.3
489 builtin_isgreater(const struct bitable *btNODE *a)
ragge
1.1
490 {
ragge
1.3
491         return builtin_isany(abt->rtGT);
ragge
1.1
492 }
493 static NODE *
ragge
1.3
494 builtin_isgreaterequal(const struct bitable *btNODE *a)
ragge
1.1
495 {
ragge
1.3
496         return builtin_isany(abt->rtGE);
ragge
1.1
497 }
498 static NODE *
ragge
1.3
499 builtin_isless(const struct bitable *btNODE *a)
ragge
1.1
500 {
ragge
1.3
501         return builtin_isany(abt->rtLT);
ragge
1.1
502 }
503 static NODE *
ragge
1.3
504 builtin_islessequal(const struct bitable *btNODE *a)
ragge
1.1
505 {
ragge
1.3
506         return builtin_isany(abt->rtLE);
ragge
1.1
507 }
508 static NODE *
ragge
1.3
509 builtin_islessgreater(const struct bitable *btNODE *a)
ragge
1.1
510 {
511         NODE *p, *q, *r;
512         TWORD t;
513
514         if ((t = mtcheck(a)) == 0)
515                 return bcon(0);
516         p = buildtree(ORORmtisnan(a->n_left), mtisnan(a->n_right));
517         p = buildtree(NOTpNIL);
518         q = buildtree(GTcast(ccopy(a->n_left), t0),
519             cast(ccopy(a->n_right), t0));
520         r = buildtree(LTcast(ccopy(a->n_left), t0),
521             cast(ccopy(a->n_right), t0));
522         q = buildtree(ORORqr);
523         p = buildtree(ANDANDpq);
524         tfree(a);
525         return p;
526 }
527 #endif
528
529 /*
530  * Math-specific builtins that expands to constants.
531  * Versins here is for IEEE FP, vax needs its own versions.
532  */
533 #if TARGET_ENDIAN == TARGET_LE
plunky
1.4
534 static const unsigned char vFLOAT[] = { 000x800x7f };
535 static const unsigned char vDOUBLE[] = { 0000000xf00x7f };
ragge
1.1
536 #ifdef LDBL_128
plunky
1.4
537 static const unsigned char vLDOUBLE[] = { 0,0,0,0,0,0,00000000x800xff0x7f };
ragge
1.1
538 #else /* LDBL_80 */
plunky
1.4
539 static const unsigned char vLDOUBLE[] = { 00000000x800xff0x7f };
ragge
1.1
540 #endif
plunky
1.4
541 static const unsigned char nFLOAT[] = { 000xc00x7f };
542 static const unsigned char nDOUBLE[] = { 0000000xf80x7f };
ragge
1.1
543 #ifdef LDBL_128
plunky
1.4
544 static const unsigned char nLDOUBLE[] = { 0,0,0,0,0,0,0,0000000xc00xff0x7f };
ragge
1.1
545 #else /* LDBL_80 */
plunky
1.4
546 static const unsigned char nLDOUBLE[] = { 00000000xc00xff0x7f00 };
ragge
1.1
547 #endif
548 #else
plunky
1.4
549 static const unsigned char vFLOAT[] = { 0x7f0x8000 };
550 static const unsigned char vDOUBLE[] = { 0x7f0xf0000000 };
ragge
1.1
551 #ifdef LDBL_128
plunky
1.4
552 static const unsigned char vLDOUBLE[] = { 0x7f0xff0x800000000,0,0,0,0,0,0 };
ragge
1.1
553 #else /* LDBL_80 */
plunky
1.4
554 static const unsigned char vLDOUBLE[] = { 0x7f0xff0x800000000 };
ragge
1.1
555 #endif
plunky
1.4
556 static const unsigned char nFLOAT[] = { 0x7f0xc000 };
557 static const unsigned char nDOUBLE[] = { 0x7f0xf8000000 };
ragge
1.1
558 #ifdef LDBL_128
plunky
1.4
559 static const unsigned char nLDOUBLE[] = { 0x7f0xff0xc00000000,0,0,0,0,0,0 };
ragge
1.1
560 #else /* LDBL_80 */
plunky
1.4
561 static const unsigned char nLDOUBLE[] = { 0x7f0xff0xc00000000 };
ragge
1.1
562 #endif
563 #endif
564
565 #define VALX(typ,TYP) {                                         \
566         typ d;                                                  \
567         int x;                                                  \
ragge
1.3
568         NODE *f;                                                \
ragge
1.1
569         x = MIN(sizeof(n ## TYP), sizeof(d));                   \
570         memcpy(&dv ## TYPx);                                \
571         f = block(FCONNILNILTYPNULL0);        \
572         f->n_dcon = d;                                          \
573         return f;                                               \
574 }
575
576 static NODE *
ragge
1.3
577 builtin_huge_valf(const struct bitable *btNODE *aVALX(float,FLOAT)
ragge
1.1
578 static NODE *
ragge
1.3
579 builtin_huge_val(const struct bitable *btNODE *aVALX(double,DOUBLE)
ragge
1.1
580 static NODE *
ragge
1.3
581 builtin_huge_vall(const struct bitable *btNODE *aVALX(long double,LDOUBLE)
ragge
1.1
582
583 #define builtin_inff    builtin_huge_valf
584 #define builtin_inf     builtin_huge_val
585 #define builtin_infl    builtin_huge_vall
586
587 /*
588  * Return NANs, if reasonable.
589  */
590 static NODE *
ragge
1.3
591 builtin_nanx(const struct bitable *btNODE *a)
592 {
593         if (a == NULL || a->n_op == CM) {
594                 uerror("%s bad argument"bt->name);
595                 a = bcon(0);
596         } else if (a->n_op == STRING && *a->n_name == '\0') {
597                 a->n_op = FCON;
598                 a->n_type = bt->rt;
599                 memcpy(&a->n_dconnLDOUBLEsizeof(a->n_dcon));
600         } else
601                 a = binhelp(eve(a), bt->rt, &bt->name[10]);
602         return a;
603 }
ragge
1.1
604
605 /*
606  * Target defines, to implement target versions of the generic builtins
607  */
608 #ifndef TARGET_MEMCMP
609 #define builtin_memcmp builtin_unimp
610 #endif
611 #ifndef TARGET_MEMCPY
612 #define builtin_memcpy builtin_unimp
613 #endif
614 #ifndef TARGET_MEMPCPY
615 #define builtin_mempcpy builtin_unimp
616 #endif
617 #ifndef TARGET_MEMSET
618 #define builtin_memset builtin_unimp
619 #endif
620
621 /* Reasonable type of size_t */
622 #ifndef SIZET
623 #if SZINT == SZSHORT
624 #define SIZET UNSIGNED
625 #elif SZLONG > SZINT
626 #define SIZET ULONG
627 #else
628 #define SIZET UNSIGNED
629 #endif
630 #endif
631
632 static TWORD memcpyt[] = { VOID|PTRVOID|PTRSIZETINT };
633 static TWORD memsett[] = { VOID|PTRINTSIZETINT };
634 static TWORD allocat[] = { SIZET };
635 static TWORD expectt[] = { LONGLONG };
636 static TWORD strcmpt[] = { CHAR|PTRCHAR|PTR };
637 static TWORD strcpyt[] = { CHAR|PTRCHAR|PTRINT };
638 static TWORD strncpyt[] = { CHAR|PTRCHAR|PTRSIZETINT };
639 static TWORD strchrt[] = { CHAR|PTRINT };
640 static TWORD strcspnt[] = { CHAR|PTRCHAR|PTR };
641 static TWORD strspnt[] = { CHAR|PTRCHAR|PTR };
642 static TWORD strpbrkt[] = { CHAR|PTRCHAR|PTR };
643 static TWORD nant[] = { CHAR|PTR };
644 static TWORD bitt[] = { UNSIGNED };
645 static TWORD bitlt[] = { ULONG };
646 static TWORD bitllt[] = { ULONGLONG };
ragge
1.3
647 static TWORD abst[] = { INT };
ragge
1.1
648
ragge
1.3
649 static const struct bitable bitable[] = {
650         { "__builtin___memcpy_chk"builtin_unimp04memcpytVOID|PTR },
651         { "__builtin___mempcpy_chk"builtin_unimp04memcpytVOID|PTR },
652         { "__builtin___memmove_chk"builtin_unimp04memcpytVOID|PTR },
653         { "__builtin___memset_chk"builtin_unimp04memsettVOID|PTR },
654
655         { "__builtin___strcat_chk"builtin_unimp03strcpytCHAR|PTR },
656         { "__builtin___strcpy_chk"builtin_unimp03strcpytCHAR|PTR },
657         { "__builtin___strncat_chk"builtin_unimp04strncpyt,CHAR|PTR },
658         { "__builtin___strncpy_chk"builtin_unimp04strncpyt,CHAR|PTR },
659
660         { "__builtin___printf_chk"builtin_unimpBTNOPROTO, -10INT },
661         { "__builtin___fprintf_chk"builtin_unimpBTNOPROTO, -10INT },
662         { "__builtin___sprintf_chk"builtin_unimpBTNOPROTO, -10INT },
663         { "__builtin___snprintf_chk"builtin_unimpBTNOPROTO, -10INT },
664         { "__builtin___vprintf_chk"builtin_unimpBTNOPROTO, -10INT },
665         { "__builtin___vfprintf_chk"builtin_unimpBTNOPROTO, -10INT },
666         { "__builtin___vsprintf_chk"builtin_unimpBTNOPROTO, -10INT },
667         { "__builtin___vsnprintf_chk"builtin_unimpBTNOPROTO, -10INT },
668
669         { "__builtin_alloca"builtin_alloca01allocatVOID|PTR },
670         { "__builtin_abs"builtin_abs01abstINT },
671         { "__builtin_clz"builtin_clz01bittINT },
672         { "__builtin_clzl"builtin_clzl01bitltINT },
673         { "__builtin_clzll"builtin_clzll01bitlltINT },
674         { "__builtin_ctz"builtin_ctz01bittINT },
675         { "__builtin_ctzl"builtin_ctzl01bitltINT },
676         { "__builtin_ctzll"builtin_ctzll01bitlltINT },
677         { "__builtin_ffs"builtin_ffs01bittINT },
678         { "__builtin_ffsl"builtin_ffsl01bitltINT },
679         { "__builtin_ffsll"builtin_ffsll01bitlltINT },
680         { "__builtin_popcount"builtin_unimp01bittUNSIGNED },
681         { "__builtin_popcountl"builtin_unimp01bitltULONG },
682         { "__builtin_popcountll"builtin_unimp01bitlltULONGLONG },
683
684         { "__builtin_constant_p"builtin_constant_p010INT },
685         { "__builtin_expect"builtin_expect02expecttLONG },
686         { "__builtin_memcmp"builtin_memcmp03memcpytINT },
687         { "__builtin_memcpy"builtin_memcpy03memcpytVOID|PTR },
688         { "__builtin_mempcpy"builtin_mempcpy03memcpytVOID|PTR },
689         { "__builtin_memset"builtin_memset03memsettVOID|PTR },
690         { "__builtin_huge_valf"builtin_huge_valf000FLOAT },
691         { "__builtin_huge_val"builtin_huge_val000DOUBLE },
692         { "__builtin_huge_vall"builtin_huge_vall000LDOUBLE },
693         { "__builtin_inff"builtin_inff000FLOAT },
694         { "__builtin_inf"builtin_inf000DOUBLE },
695         { "__builtin_infl"builtin_infl000LDOUBLE },
696         { "__builtin_isgreater"builtin_isgreater02NULLINT },
697         { "__builtin_isgreaterequal"builtin_isgreaterequal02NULLINT },
698         { "__builtin_isless"builtin_isless02NULLINT },
699         { "__builtin_islessequal"builtin_islessequal02NULLINT },
700         { "__builtin_islessgreater"builtin_islessgreater02NULLINT },
701         { "__builtin_isunordered"builtin_isunordered02NULLINT },
702         { "__builtin_nanf"builtin_nanxBTNOEVE1nantFLOAT },
703         { "__builtin_nan"builtin_nanxBTNOEVE1nantDOUBLE },
704         { "__builtin_nanl"builtin_nanxBTNOEVE1nantLDOUBLE },
705         { "__builtin_object_size"builtin_object_size02memsettSIZET },
706         { "__builtin_prefetch"builtin_prefetch01memsettVOID },
707         { "__builtin_strcmp"builtin_unimp02strcmptINT },
708         { "__builtin_strcpy"builtin_unimp02strcpytCHAR|PTR },
709         { "__builtin_stpcpy"builtin_unimp02strcpytCHAR|PTR },
710         { "__builtin_strchr"builtin_unimp02strchrtCHAR|PTR },
711         { "__builtin_strlen"builtin_unimp01strcmptSIZET },
712         { "__builtin_strrchr"builtin_unimp02strchrtCHAR|PTR },
713         { "__builtin_strncpy"builtin_unimp03strncpytCHAR|PTR },
714         { "__builtin_strncat"builtin_unimp03strncpytCHAR|PTR },
715         { "__builtin_strcspn"builtin_unimp02strcspntSIZET },
716         { "__builtin_strspn"builtin_unimp02strspntSIZET },
717         { "__builtin_strstr"builtin_unimp02strcmptCHAR|PTR },
718         { "__builtin_strpbrk"builtin_unimp02strpbrktCHAR|PTR },
ragge
1.1
719 #ifndef TARGET_STDARGS
ragge
1.3
720         { "__builtin_stdarg_start"builtin_stdarg_start020VOID },
721         { "__builtin_va_start"builtin_stdarg_start020VOID },
722         { "__builtin_va_arg"builtin_va_argBTNORVAL|BTNOPROTO200 },
723         { "__builtin_va_end"builtin_va_end010VOID },
724         { "__builtin_va_copy"builtin_va_copy020VOID },
ragge
1.1
725 #endif
726 #ifdef TARGET_BUILTINS
727         TARGET_BUILTINS
728 #endif
729 };
730
731 /*
732  * Check and cast arguments for builtins.
733  */
734 static int
735 acnt(NODE *aint nargTWORD *tp)
736 {
737         NODE *q;
738         TWORD t;
739
740         if (a == NIL)
741                 return narg;
742         for (; a->n_op == CMa = a->n_leftnarg--) {
743                 if (tp == NULL)
744                         continue;
745                 q = a->n_right;
746                 t = ctype(tp[narg-1]);
747                 if (q->n_type == t)
748                         continue;
749                 a->n_right = ccast(qt0NULL0);
750         }
751
752         /* Last arg is ugly to deal with */
ragge
1.3
753         if (narg == 1 && tp != NULL && a->n_type != tp[0]) {
ragge
1.1
754                 q = talloc();
755                 *q = *a;
756                 q = ccast(qctype(tp[0]), 0NULL0);
757                 *a = *q;
758                 nfree(q);
759         }
760         return narg != 1;
761 }
762
763 NODE *
ragge
1.3
764 builtin_check(struct symtab *spNODE *a)
ragge
1.1
765 {
766         const struct bitable *bt;
767
ragge
1.3
768         if (sp->soffset < 0 ||
769             sp->soffset >= (int)(sizeof(bitable)/sizeof(bitable[0])))
770                 cerror("builtin_check");
771
772         bt = &bitable[sp->soffset];
773         if ((bt->flags & BTNOEVE) == 0)
774                 a = eve(a);
775         if (((bt->flags & BTNOPROTO) == 0) && acnt(abt->nargbt->tp)) {
776                 uerror("wrong argument count to %s"bt->name);
777                 return bcon(0);
ragge
1.1
778         }
ragge
1.3
779         return (*bt->fun)(bta);
ragge
1.1
780 }
781
ragge
1.3
782 /*
783  * Put all builtin functions into the global symbol table.
784  */
785 void
786 builtin_init()
ragge
1.1
787 {
ragge
1.3
788         const struct bitable *bt;
789         NODE *p = block(TYPE00000);
790         struct symtab *sp;
ragge
1.1
791         int i;
792
793         for (i = 0i < (int)(sizeof(bitable)/sizeof(bitable[0])); i++) {
ragge
1.3
794                 bt = &bitable[i];
795                 sp = lookup(addname(bt->name), 0);
796                 if (bt->rt == 0 && (bt->flags & BTNORVAL) == 0)
797                         cerror("function '%s' has no return type"bt->name);
798                 p->n_type = INCREF(bt->rt) + (FTN-PTR);
799                 p->n_sp = sp;
800                 defid(pEXTDEF);
801                 sp->soffset = i;
802                 sp->sflags |= SBUILTIN;
ragge
1.1
803         }
ragge
1.3
804         nfree(p);
ragge
1.1
805 }
806 #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-07-10 01:32 +0200