* as/z80/z80mch.c: fixed bug #1704376: missing as-z80 errors
[fw/sdcc] / doc / builtins.txt
1 /* This document is meant for developers */
2
3 Implementation details of "builtin" functions in SDCC. 
4 Built in functions are target/port specific and are defined in src/<arch>/main.c. 
5 Here is a layout of the builtin structure (port.h).
6
7 Front-End
8 ---------
9
10 #define MAX_BUILTIN_ARGS        16
11 /* definition of builtin functions */
12 typedef struct builtins
13 {
14     char *name ;                /* name of builtin function */
15     char *rtype;                /* return type as string : see typefromStr */
16     int  nParms;                /* number of parms : max 8 */
17     char *parm_types[MAX_BUILTIN_ARGS]; /* each parm type as string : see typeFromStr */
18 } builtins ;
19
20 The port structure contains a pointer to a table of the builtin functions. Example of the
21 builtin function table.
22
23 static builtins __ds390_builtins[] = {
24     { "__builtin_memcpy_x2x","v",3,{"cx*","cx*","i"}}, /* void __builtin_memcpy_x2x (xdata char *,xdata char *,int) */
25     { "__builtin_memcpy_c2x","v",3,{"cx*","cp*","i"}}, /* void __builtin_memcpy_c2x (xdata char *,code  char *,int) */
26     { NULL , NULL,0, {NULL}}                           /* mark end of table */
27 };    
28
29 Here the function names are prefixed with "__builtin" this is not a requirement, standard C
30 library functions can also be defined in this table by a particular port to generate more
31 efficient code .
32
33 Function "initBuiltIns" in SDCCsymt.c is invoked to initialize the symbol table with the
34 builtin functions. The return type & the parameter types are specified as encoded strings. 
35 Function "typeFromStr" parses this encoded string and translates them into sym_link . 
36
37 /*-----------------------------------------------------------------*/
38 /* typeFromStr - create a typechain from an encoded string         */
39 /* basic types -        'c' - char                                 */
40 /*                      's' - short                                */
41 /*                      'i' - int                                  */
42 /*                      'l' - long                                 */
43 /*                      'f' - float                                */
44 /*                      'v' - void                                 */
45 /*                      '*' - pointer - default (GPOINTER)         */
46 /* modifiers -          'u' - unsigned                             */
47 /* pointer modifiers -  'g' - generic                              */
48 /*                      'x' - xdata                                */
49 /*                      'p' - code                                 */
50 /*                      'd' - data                                 */                     
51 /*                      'F' - FUNCTION                             */                     
52 /* examples : "ig*" - generic int *                                */
53 /*            "cx*" - char xdata *                                 */
54 /*            "ui" -  unsigned int                                 */
55 /*-----------------------------------------------------------------*/
56
57 So much for the front-end issues.
58
59 iCode - implications.
60 ---------------------
61
62 Intermediate code (iCode) will ALWAYS generate a SEND for parameters of a builtin function with
63 a special flag (ic->builtinSEND) set. This eliminates the need for special processing for different
64 memory models and --stack-auto option. All optimizations remain untouched. Example of intermediate code
65 generated for builtin
66
67 void memcpy(xdata char *d,xdata char *s)
68 {
69     __builtin_memcpy_x2x(d,s+10,10);
70 }
71 iTemp0 [k2 lr3:12 so:0]{ ia0 re1 rm0 nos0 ru0}{xdata char xdata * }{ sir@ _memcpy_d_1_1}[_memcpy_d_1_1] = recv 
72 iTemp2 [k7 lr4:12 so:0]{ ia0 re0 rm0 nos0 ru0}{xdata char xdata * }[r5 r6 r7 ] 
73        := _memcpy_PARM_2 [k6 lr0:0 so:0]{ ia0 re0 rm0 nos0 ru0}{xdata char xdata * }
74 iTemp3 [k8 lr5:8 so:0]{ ia0 re0 rm0 nos0 ru0}{xdata char xdata * }[r0 r1 r2 ] = 
75        iTemp2 [k7 lr4:12 so:0]{ ia0 re0 rm0 nos0 ru0}{xdata char xdata * }[r5 r6 r7 ] + 0xa {literal unsigned char}
76 send iTemp0 [k2 lr3:12 so:0]{ ia0 re1 rm0 nos0 ru0}{xdata char xdata * }{ sir@ _memcpy_d_1_1}[_memcpy_d_1_1]
77 send iTemp3 [k8 lr5:8 so:0]{ ia0 re0 rm0 nos0 ru0}{xdata char xdata * }[r0 r1 r2 ]
78 send 0xa {literal int}
79 iTemp4 [k9 lr9:9 so:0]{ ia0 re0 rm0 nos0 ru1}{void} = 
80        call ___builtin_memcpy_x2x [k4 lr0:0 so:0]{ ia0 re0 rm0 nos0 ru0}{void function __builtin__}
81
82
83 Backend/Code generation for builtin functions.
84 ----------------------------------------------
85
86 When a SEND icode with the ic->builtinSEND flag is detected by the code generator, it should go
87 into builtin function processing mode. E.g.
88
89         case SEND:
90           if (ic->builtinSEND) genBuiltIn(ic);
91           else addSet (&_G.sendSet, ic);
92           break;
93
94 SDCCicode.c contains a port/target independent routine (getBuiltinParms) which goes thru the 
95 iCodes (starting from the first SEND (with builtinSEND set)) and returns the parameters and number 
96 of parameters in an array, example. NOTE the function "getBuiltinParms" also marks the iCodes
97 as "generated" .
98
99 /*-----------------------------------------------------------------*/
100 /* genBuiltIn - calls the appropriate function to  generating code */
101 /* for a built in function                                         */
102 /*-----------------------------------------------------------------*/
103 static void genBuiltIn (iCode *ic)
104 {
105     operand *bi_parms[MAX_BUILTIN_ARGS];
106     int nbi_parms;
107     iCode *bi_iCode;
108     symbol *bif;
109
110     /* get all the arguments for a built in function */
111     bi_iCode = getBuiltinParms(ic,&nbi_parms,bi_parms);
112
113     /* which function is it */
114     bif = OP_SYMBOL(IC_LEFT(bi_iCode));
115     if (strcmp(bif->name,"__builtin_memcpy_x2x")==0) {
116         genMemcpyX2X(bi_iCode,nbi_parms,bi_parms,0);
117     } else if (strcmp(bif->name,"__builtin_memcpy_c2x")==0) {
118         genMemcpyX2X(bi_iCode,nbi_parms,bi_parms,1);
119     } else {
120         werror(E_INTERNAL_ERROR,"unknown builtin function encountered\n");
121         return ;
122     }
123     return ;    
124 }
125
126