Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:gmcgarry:20110530034055

Diff

Diff from 1.25 to:

Annotations

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

Annotated File View

gmcgarry
1.25
1 /*      $Id: builtins.c,v 1.25 2011/05/30 03:45:53 gmcgarry 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
37 /*
38  * replace an alloca function with direct allocation on stack.
39  * return a destination temp node.
40  */
41 static NODE *
ragge
1.9
42 builtin_alloca(NODE *fNODE *aTWORD rt)
ragge
1.1
43 {
44         NODE *t, *u;
45
46 #ifdef notyet
47         if (xnobuiltins)
48                 return NULL;
49 #endif
50
ragge
1.22
51         t = tempnode(0VOID|PTR00);
52         u = tempnode(regno(t), VOID|PTR00);
ragge
1.1
53         spalloc(taSZCHAR);
54         tfree(f);
55         return u;
56 }
57
58 /*
59  * See if there is a goto in the tree.
60  * XXX this function is a hack for a flaw in handling of 
61  * compound expressions and inline functions and should not be 
62  * needed.
63  */
64 static int
65 hasgoto(NODE *p)
66 {
67         int o = coptype(p->n_op);
68
69         if (o == LTYPE)
70                 return 0;
71         if (p->n_op == GOTO)
72                 return 1;
73         if (o == UTYPE)
74                 return hasgoto(p->n_left);
75         if (hasgoto(p->n_left))
76                 return 1;
77         return hasgoto(p->n_right);
78 }
79
80 /*
81  * Determine if a value is known to be constant at compile-time and
82  * hence that PCC can perform constant-folding on expressions involving
83  * that value.
84  */
85 static NODE *
ragge
1.9
86 builtin_constant_p(NODE *fNODE *aTWORD rt)
ragge
1.1
87 {
ragge
1.17
88         void putjops(NODE *pvoid *arg);
89         int isconst;
ragge
1.1
90
91         tfree(f);
ragge
1.17
92         walkf(aputjops0);
93         for (f = af->n_op == COMOPf = f->n_right)
94                 ;
95         isconst = nncon(f);
96         tfree(a);
97         return bcon(isconst);
ragge
1.1
98 }
99
100 /*
101  * Hint to the compiler whether this expression will evaluate true or false.
102  * Just ignored for now.
103  */
104 static NODE *
ragge
1.9
105 builtin_expect(NODE *fNODE *aTWORD rt)
ragge
1.1
106 {
107
108         tfree(f);
109         if (a && a->n_op == CM) {
110                 tfree(a->n_right);
111                 f = a->n_left;
112                 nfree(a);
113                 a = f;
114         }
115
116         return a;
117 }
118
119 /*
120  * Take integer absolute value.
121  * Simply does: ((((x)>>(8*sizeof(x)-1))^(x))-((x)>>(8*sizeof(x)-1)))
122  */
123 static NODE *
ragge
1.9
124 builtin_abs(NODE *fNODE *aTWORD rt)
ragge
1.1
125 {
126         NODE *p, *q, *r, *t, *t2, *t3;
127         int tmp1tmp2shift;
128
129         if (a->n_type != INT)
130                 a = cast(aINT0);
131
132         tfree(f);
133
134         if (a->n_op == ICON) {
135                 if (a->n_lval < 0)
136                         a->n_lval = -a->n_lval;
137                 p = a;
138         } else {
ragge
1.7
139                 t = tempnode(0a->n_typea->n_dfa->n_ap);
ragge
1.1
140                 tmp1 = regno(t);
141                 p = buildtree(ASSIGNta);
142
ragge
1.7
143                 t = tempnode(tmp1a->n_typea->n_dfa->n_ap);
144                 shift = (int)tsize(a->n_typea->n_dfa->n_ap) - 1;
ragge
1.1
145                 q = buildtree(RStbcon(shift));
146
ragge
1.7
147                 t2 = tempnode(0a->n_typea->n_dfa->n_ap);
ragge
1.1
148                 tmp2 = regno(t2);
149                 q = buildtree(ASSIGNt2q);
150
ragge
1.7
151                 t = tempnode(tmp1a->n_typea->n_dfa->n_ap);
152                 t2 = tempnode(tmp2a->n_typea->n_dfa->n_ap);
153                 t3 = tempnode(tmp2a->n_typea->n_dfa->n_ap);
ragge
1.1
154                 r = buildtree(MINUSbuildtree(ERtt2), t3);
155
156                 p = buildtree(COMOPpbuildtree(COMOPqr));
157         }
158
159         return p;
160 }
161
ragge
1.11
162 /*
163  * Get size of object, if possible.
164  * Currently does nothing,
165  */
166 static NODE *
167 builtin_object_size(NODE *fNODE *aTWORD rt)
168 {
169         int v = icons(a->n_right);
170         if (v < 0 || v > 3)
171                 uerror("arg2 must be between 0 and 3");
ragge
1.14
172
173         tfree(f);
174         f = buildtree(COMOPa->n_leftxbcon(v < 2 ? -1 : 0NULLrt));
ragge
1.11
175         nfree(a);
ragge
1.14
176         return f;
ragge
1.11
177 }
178
ragge
1.1
179 #ifndef TARGET_STDARGS
180 static NODE *
ragge
1.9
181 builtin_stdarg_start(NODE *fNODE *aTWORD rt)
ragge
1.1
182 {
183         NODE *p, *q;
184         int sz;
185
186         /* must first deal with argument size; use int size */
187         p = a->n_right;
188         if (p->n_type < INT) {
ragge
1.7
189                 sz = (int)(SZINT/tsize(p->n_typep->n_dfp->n_ap));
ragge
1.1
190         } else
191                 sz = 1;
192
193         /* do the real job */
194         p = buildtree(ADDROFpNIL); /* address of last arg */
195 #ifdef BACKAUTO
196         p = optim(buildtree(PLUSpbcon(sz))); /* add one to it (next arg) */
197 #else
198         p = optim(buildtree(MINUSpbcon(sz))); /* add one to it (next arg) */
199 #endif
200         q = block(NAMENILNILPTR+VOID00); /* create cast node */
201         q = buildtree(CASTqp); /* cast to void * (for assignment) */
202         p = q->n_right;
203         nfree(q->n_left);
204         nfree(q);
205         p = buildtree(ASSIGNa->n_leftp); /* assign to ap */
206         tfree(f);
207         nfree(a);
208         return p;
209 }
210
211 static NODE *
ragge
1.9
212 builtin_va_arg(NODE *fNODE *aTWORD rt)
ragge
1.1
213 {
214         NODE *p, *q, *r, *rv;
215         int sznodnum;
216
217         /* create a copy to a temp node of current ap */
218         p = ccopy(a->n_left);
ragge
1.7
219         q = tempnode(0p->n_typep->n_dfp->n_ap);
ragge
1.1
220         nodnum = regno(q);
221         rv = buildtree(ASSIGNqp);
222
223         r = a->n_right;
ragge
1.7
224         sz = (int)tsize(r->n_typer->n_dfr->n_ap)/SZCHAR;
ragge
1.1
225         /* add one to ap */
226 #ifdef BACKAUTO
227         rv = buildtree(COMOPrv , buildtree(PLUSEQa->n_leftbcon(sz)));
228 #else
229 #error fix wrong eval order in builtin_va_arg
230         ecomp(buildtree(MINUSEQa->n_leftbcon(sz)));
231 #endif
232
233         nfree(a->n_right);
234         nfree(a);
235         nfree(f);
ragge
1.7
236         r = tempnode(nodnumINCREF(r->n_type), r->n_dfr->n_ap);
ragge
1.1
237         return buildtree(COMOPrvbuildtree(UMULrNIL));
238
239 }
240
241 static NODE *
ragge
1.9
242 builtin_va_end(NODE *fNODE *aTWORD rt)
ragge
1.1
243 {
244         tfree(f);
245         tfree(a);
246         return bcon(0); /* nothing */
247 }
248
249 static NODE *
ragge
1.9
250 builtin_va_copy(NODE *fNODE *aTWORD rt)
ragge
1.1
251 {
252         tfree(f);
253         f = buildtree(ASSIGNa->n_lefta->n_right);
254         nfree(a);
255         return f;
256 }
257 #endif /* TARGET_STDARGS */
258
ragge
1.2
259 /*
260  * For unimplemented "builtin" functions, try to invoke the
261  * non-builtin name
262  */
263 static NODE *
ragge
1.16
264 binhelp(NODE *fNODE *aTWORD rtchar *n)
ragge
1.2
265 {
ragge
1.13
266         f->n_sp = lookup(addname(n), SNORMAL);
267         if (f->n_sp->sclass == SNULL) {
268                 f->n_sp->sclass = EXTERN;
269                 f->n_sp->stype = INCREF(rt)+(FTN-PTR);
270         }
271         f->n_type = f->n_sp->stype;
ragge
1.6
272         f = clocal(f);
ragge
1.2
273         return buildtree(CALLfa);
274 }
275
ragge
1.16
276 static NODE *
277 builtin_unimp(NODE *fNODE *aTWORD rt)
278 {
279         char *n = f->n_sp->sname;
280
281         if (strncmp("__builtin_"n10) == 0)
282                 n += 10;
283         return binhelp(fartn);
284 }
285
286 static NODE *
287 builtin_unimp_f(NODE *fNODE *aTWORD rt)
288 {
289         return binhelp(fartf->n_sp->sname);
290 }
291
ragge
1.18
292 #ifndef TARGET_ISMATH
293 /*
294  * Handle the builtin macros for the math functions is*
295  * To get something that is be somewhat generic assume that 
296  * isnan() is a real function and that cast of a NaN type 
297  * to double will still be a NaN.
298  */
299 static NODE *
300 mtisnan(NODE *p)
301 {
ragge
1.22
302         NODE *q = block(NAMENILNILINT00);
ragge
1.18
303
304         return binhelp(qcast(ccopy(p), DOUBLE0), INT"isnan");
305 }
306
307 static TWORD
308 mtcheck(NODE *p)
309 {
310         TWORD t1 = p->n_left->n_typet2 = p->n_right->n_type;
311
312         if ((t1 >= FLOAT && t1 <= LDOUBLE) ||
313             (t2 >= FLOAT && t2 <= LDOUBLE))
314                 return MAX(t1t2);
315         return 0;
316 }
317
318 static NODE *
319 builtin_isunordered(NODE *fNODE *aTWORD rt)
320 {
321         NODE *p;
322
323         if (mtcheck(a) == 0)
324                 return bcon(0);
325
326         p = buildtree(ORORmtisnan(a->n_left), mtisnan(a->n_right));
327         tfree(f);
328         tfree(a);
329         return p;
330 }
331 static NODE *
332 builtin_isany(NODE *fNODE *aTWORD rtint cmpt)
333 {
334         NODE *p, *q;
335         TWORD t;
336
337         if ((t = mtcheck(a)) == 0)
338                 return bcon(0);
339         p = buildtree(ORORmtisnan(a->n_left), mtisnan(a->n_right));
340         p = buildtree(NOTpNIL);
341         q = buildtree(cmptcast(ccopy(a->n_left), t0),
342             cast(ccopy(a->n_right), t0));
343         p = buildtree(ANDANDpq);
344         tfree(f);
345         tfree(a);
346         return p;
347 }
348 static NODE *
349 builtin_isgreater(NODE *fNODE *aTWORD rt)
350 {
351         return builtin_isany(fartGT);
352 }
353 static NODE *
354 builtin_isgreaterequal(NODE *fNODE *aTWORD rt)
355 {
356         return builtin_isany(fartGE);
357 }
358 static NODE *
359 builtin_isless(NODE *fNODE *aTWORD rt)
360 {
361         return builtin_isany(fartLT);
362 }
363 static NODE *
364 builtin_islessequal(NODE *fNODE *aTWORD rt)
365 {
366         return builtin_isany(fartLE);
367 }
368 static NODE *
369 builtin_islessgreater(NODE *fNODE *aTWORD rt)
370 {
371         NODE *p, *q, *r;
372         TWORD t;
373
374         if ((t = mtcheck(a)) == 0)
375                 return bcon(0);
376         p = buildtree(ORORmtisnan(a->n_left), mtisnan(a->n_right));
377         p = buildtree(NOTpNIL);
378         q = buildtree(GTcast(ccopy(a->n_left), t0),
379             cast(ccopy(a->n_right), t0));
380         r = buildtree(LTcast(ccopy(a->n_left), t0),
381             cast(ccopy(a->n_right), t0));
382         q = buildtree(ORORqr);
383         p = buildtree(ANDANDpq);
384         tfree(f);
385         tfree(a);
386         return p;
387 }
388 #endif
389
ragge
1.2
390 /*
391  * Math-specific builtins that expands to constants.
392  * Versins here is for IEEE FP, vax needs its own versions.
393  */
394 #ifdef RTOLBYTES
395 static char vFLOAT[] = { 000x800x7f };
396 static char vDOUBLE[] = { 0000000xf00x7f };
397 #ifdef LDBL_128
398 static char vLDOUBLE[] = { 0,0,0,0,0,0,00000000x800xff0x7f };
399 #else /* LDBL_80 */
400 static char vLDOUBLE[] = { 00000000x800xff0x7f };
401 #endif
402 static char nFLOAT[] = { 000xc00x7f };
403 static char nDOUBLE[] = { 0000000xf80x7f };
404 #ifdef LDBL_128
405 static char nLDOUBLE[] = { 0,0,0,0,0,0,0,0000000xc00xff0x7f };
406 #else /* LDBL_80 */
407 static char nLDOUBLE[] = { 00000000xc00xff0x7f00 };
408 #endif
409 #else
410 static char vFLOAT[] = { 0x7f0x8000 };
411 static char vDOUBLE[] = { 0x7f0xf0000000 };
412 #ifdef LDBL_128
413 static char vLDOUBLE[] = { 0x7f0xff0x800000000,0,0,0,0,0,0 };
414 #else /* LDBL_80 */
415 static char vLDOUBLE[] = { 0x7f0xff0x800000000 };
416 #endif
417 static char nFLOAT[] = { 0x7f0xc000 };
418 static char nDOUBLE[] = { 0x7f0xf8000000 };
419 #ifdef LDBL_128
420 static char nLDOUBLE[] = { 0x7f0xff0xc00000000,0,0,0,0,0,0 };
421 #else /* LDBL_80 */
422 static char nLDOUBLE[] = { 0x7f0xff0xc00000000 };
423 #endif
424 #endif
425
426 #define VALX(typ,TYP) {                                         \
427         typ d;                                                  \
428         int x;                                                  \
429         x = MIN(sizeof(n ## TYP), sizeof(d));                   \
430         memcpy(&dv ## TYPx);                                \
431         nfree(f);                                               \
ragge
1.22
432         f = block(FCONNILNILTYPNULL0);        \
ragge
1.2
433         f->n_dcon = d;                                          \
434         return f;                                               \
435 }
436
437 static NODE *
ragge
1.9
438 builtin_huge_valf(NODE *fNODE *aTWORD rtVALX(float,FLOAT)
ragge
1.2
439 static NODE *
ragge
1.9
440 builtin_huge_val(NODE *fNODE *aTWORD rtVALX(double,DOUBLE)
ragge
1.2
441 static NODE *
ragge
1.9
442 builtin_huge_vall(NODE *fNODE *aTWORD rtVALX(long double,LDOUBLE)
ragge
1.2
443
444 #define builtin_inff    builtin_huge_valf
445 #define builtin_inf     builtin_huge_val
446 #define builtin_infl    builtin_huge_vall
447
ragge
1.15
448 #define NANX(typ,TYP) {                                                 \
449         typ d;                                                          \
450         int x;                                                          \
451         if ((a->n_op == ICON && a->n_sp && a->n_sp->sname[0] == '\0') ||\
452             (a->n_op == ADDROF && a->n_left->n_op == NAME &&            \
453              a->n_left->n_sp && a->n_left->n_sp->sname[0] == '\0')) {   \
454                 x = MIN(sizeof(n ## TYP), sizeof(d));                   \
455                 memcpy(&dn ## TYPx);                                \
456                 tfree(a); tfree(f);                                     \
ragge
1.22
457                 f = block(FCONNILNILTYPNULL0);        \
ragge
1.15
458                 f->n_dcon = d;                                          \
459                 return f;                                               \
460         }                                                               \
461         return buildtree(CALLfa);                                   \
ragge
1.2
462 }
463
464 /*
465  * Return NANs, if reasonable.
466  */
467 static NODE *
ragge
1.9
468 builtin_nanf(NODE *fNODE *aTWORD rtNANX(float,FLOAT)
ragge
1.2
469 static NODE *
ragge
1.9
470 builtin_nan(NODE *fNODE *aTWORD rtNANX(double,DOUBLE)
ragge
1.2
471 static NODE *
ragge
1.9
472 builtin_nanl(NODE *fNODE *aTWORD rtNANX(long double,LDOUBLE)
ragge
1.2
473
474 /*
475  * Target defines, to implement target versions of the generic builtins
476  */
ragge
1.21
477 #ifndef TARGET_MEMCMP
478 #define builtin_memcmp builtin_unimp
479 #endif
ragge
1.2
480 #ifndef TARGET_MEMCPY
481 #define builtin_memcpy builtin_unimp
482 #endif
483 #ifndef TARGET_MEMSET
484 #define builtin_memset builtin_unimp
485 #endif
486
487 /* Reasonable type of size_t */
488 #ifndef SIZET
489 #if SZINT == SZSHORT
490 #define SIZET UNSIGNED
491 #elif SZLONG > SZINT
492 #define SIZET ULONG
493 #else
494 #define SIZET UNSIGNED
495 #endif
496 #endif
497
ragge
1.12
498 static TWORD memcpyt[] = { VOID|PTRVOID|PTRSIZETINT };
499 static TWORD memsett[] = { VOID|PTRINTSIZETINT };
ragge
1.2
500 static TWORD allocat[] = { SIZET };
501 static TWORD expectt[] = { LONGLONG };
ragge
1.8
502 static TWORD strcmpt[] = { CHAR|PTRCHAR|PTR };
ragge
1.12
503 static TWORD strcpyt[] = { CHAR|PTRCHAR|PTRINT };
504 static TWORD strncpyt[] = { CHAR|PTRCHAR|PTRSIZETINT };
ragge
1.9
505 static TWORD strchrt[] = { CHAR|PTRINT };
gmcgarry
1.19
506 static TWORD strcspnt[] = { CHAR|PTRCHAR|PTR };
gmcgarry
1.23
507 static TWORD strspnt[] = { CHAR|PTRCHAR|PTR };
gmcgarry
1.24
508 static TWORD strpbrkt[] = { CHAR|PTRCHAR|PTR };
ragge
1.2
509 static TWORD nant[] = { CHAR|PTR };
ragge
1.16
510 static TWORD bitt[] = { UNSIGNED };
511 static TWORD bitlt[] = { ULONG };
ragge
1.21
512 static TWORD ffst[] = { INT };
ragge
1.2
513
ragge
1.4
514 static const struct bitable {
ragge
1.1
515         char *name;
ragge
1.9
516         NODE *(*fun)(NODE *fNODE *aTWORD);
ragge
1.1
517         int narg;
ragge
1.2
518         TWORD *tp;
ragge
1.9
519         TWORD rt;
ragge
1.1
520 bitable[] = {
ragge
1.13
521         { "__builtin___memcpy_chk"builtin_unimp4memcpytVOID|PTR },
522         { "__builtin___memmove_chk"builtin_unimp4memcpytVOID|PTR },
523         { "__builtin___memset_chk"builtin_unimp4memsettVOID|PTR },
524
525         { "__builtin___strcat_chk"builtin_unimp3strcpytCHAR|PTR },
526         { "__builtin___strcpy_chk"builtin_unimp3strcpytCHAR|PTR },
527         { "__builtin___strncat_chk"builtin_unimp4strncpyt,CHAR|PTR },
528         { "__builtin___strncpy_chk"builtin_unimp4strncpyt,CHAR|PTR },
529
530         { "__builtin___printf_chk"builtin_unimp, -10INT },
531         { "__builtin___fprintf_chk"builtin_unimp, -10INT },
532         { "__builtin___sprintf_chk"builtin_unimp, -10INT },
533         { "__builtin___snprintf_chk"builtin_unimp, -10INT },
534         { "__builtin___vprintf_chk"builtin_unimp, -10INT },
535         { "__builtin___vfprintf_chk"builtin_unimp, -10INT },
536         { "__builtin___vsprintf_chk"builtin_unimp, -10INT },
537         { "__builtin___vsnprintf_chk"builtin_unimp, -10INT },
ragge
1.12
538
ragge
1.2
539         { "__builtin_alloca"builtin_alloca1allocat },
ragge
1.16
540         { "__builtin_abs"builtin_abs1 },
541         { "__builtin_clz"builtin_unimp_f1bittINT },
542         { "__builtin_ctz"builtin_unimp_f1bittINT },
543         { "__builtin_clzl"builtin_unimp_f1bitltINT },
544         { "__builtin_ctzl"builtin_unimp_f1bitltINT },
ragge
1.21
545         { "__builtin_ffs"builtin_unimp1ffstINT },
ragge
1.16
546
ragge
1.1
547         { "__builtin_constant_p"builtin_constant_p1 },
ragge
1.2
548         { "__builtin_expect"builtin_expect2expectt },
ragge
1.21
549         { "__builtin_memcmp"builtin_memcmp3memcpytINT },
ragge
1.9
550         { "__builtin_memcpy"builtin_memcpy3memcpytVOID|PTR },
551         { "__builtin_memset"builtin_memset3memsettVOID|PTR },
ragge
1.2
552         { "__builtin_huge_valf"builtin_huge_valf0 },
553         { "__builtin_huge_val"builtin_huge_val0 },
554         { "__builtin_huge_vall"builtin_huge_vall0 },
555         { "__builtin_inff"builtin_inff0 },
556         { "__builtin_inf"builtin_inf0 },
557         { "__builtin_infl"builtin_infl0 },
ragge
1.18
558         { "__builtin_isgreater"builtin_isgreater2NULLINT },
559         { "__builtin_isgreaterequal"builtin_isgreaterequal2NULLINT },
560         { "__builtin_isless"builtin_isless2NULLINT },
561         { "__builtin_islessequal"builtin_islessequal2NULLINT },
562         { "__builtin_islessgreater"builtin_islessgreater2NULLINT },
563         { "__builtin_isunordered"builtin_isunordered2NULLINT },
ragge
1.15
564         { "__builtin_nanf"builtin_nanf1nantFLOAT },
565         { "__builtin_nan"builtin_nan1nantDOUBLE },
566         { "__builtin_nanl"builtin_nanl1nantLDOUBLE },
ragge
1.11
567         { "__builtin_object_size"builtin_object_size2memsettSIZET },
ragge
1.9
568         { "__builtin_strcmp"builtin_unimp2strcmptINT },
ragge
1.21
569         { "__builtin_strcpy"builtin_unimp2strcmptCHAR|PTR },
ragge
1.9
570         { "__builtin_strchr"builtin_unimp2strchrtCHAR|PTR },
ragge
1.21
571         { "__builtin_strlen"builtin_unimp1strcmptSIZET },
ragge
1.9
572         { "__builtin_strrchr"builtin_unimp2strchrtCHAR|PTR },
ragge
1.10
573         { "__builtin_strncpy"builtin_unimp3strncpytCHAR|PTR },
574         { "__builtin_strncat"builtin_unimp3strncpytCHAR|PTR },
ragge
1.20
575         { "__builtin_strcspn"builtin_unimp2strcspntSIZET },
gmcgarry
1.23
576         { "__builtin_strspn"builtin_unimp2strspntSIZET },
gmcgarry
1.24
577         { "__builtin_strpbrk"builtin_unimp2strpbrktCHAR|PTR },
ragge
1.1
578 #ifndef TARGET_STDARGS
579         { "__builtin_stdarg_start"builtin_stdarg_start2 },
580         { "__builtin_va_start"builtin_stdarg_start2 },
581         { "__builtin_va_arg"builtin_va_arg2 },
582         { "__builtin_va_end"builtin_va_end1 },
583         { "__builtin_va_copy"builtin_va_copy2 },
584 #endif
585 #ifdef TARGET_BUILTINS
586         TARGET_BUILTINS
587 #endif
588 };
589
ragge
1.2
590 /*
591  * Check and cast arguments for builtins.
592  */
ragge
1.1
593 static int
ragge
1.2
594 acnt(NODE *aint nargTWORD *tp)
ragge
1.1
595 {
ragge
1.2
596         NODE *q;
597         TWORD t;
598
ragge
1.1
599         if (a == NIL)
600                 return narg;
ragge
1.2
601         for (; a->n_op == CMa = a->n_leftnarg--) {
602                 if (tp == NULL)
603                         continue;
604                 q = a->n_right;
605                 t = tp[narg-1];
606                 if (q->n_type == t)
607                         continue;
ragge
1.22
608                 a->n_right = ccast(qt0NULL0);
ragge
1.2
609         }
610
611         /* Last arg is ugly to deal with */
ragge
1.4
612         if (narg == 1 && tp != NULL) {
ragge
1.2
613                 q = talloc();
614                 *q = *a;
ragge
1.22
615                 q = ccast(qtp[0], 0NULL0);
ragge
1.2
616                 *a = *q;
617                 nfree(q);
618         }
ragge
1.1
619         return narg != 1;
620 }
621
622 NODE *
623 builtin_check(NODE *fNODE *a)
624 {
ragge
1.4
625         const struct bitable *bt;
ragge
1.1
626         int i;
627
628         for (i = 0i < (int)(sizeof(bitable)/sizeof(bitable[0])); i++) {
ragge
1.2
629                 bt = &bitable[i];
630                 if (strcmp(bt->namef->n_sp->sname))
ragge
1.1
631                         continue;
ragge
1.2
632                 if (bt->narg >= 0 && acnt(abt->nargbt->tp)) {
633                         uerror("wrong argument count to %s"bt->name);
ragge
1.1
634                         return bcon(0);
635                 }
ragge
1.9
636                 return (*bt->fun)(fabt->rt);
ragge
1.1
637         }
638         return NIL;
639 }
640 #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-10-31 13:05 +0100