1 /*-------------------------------------------------------------------------
2   SDCCglobl.h - global macros etc required by all files
3 
4   Copyright (C) 1998, Sandeep Dutta . sandeep.dutta@usa.net
5 
6   This program is free software; you can redistribute it and/or modify it
7   under the terms of the GNU General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10 
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15 
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 -------------------------------------------------------------------------*/
20 
21 #ifndef SDCCGLOBL_H
22 #define SDCCGLOBL_H
23 
24 #include <memory.h>
25 #include <stdlib.h>
26 #include <setjmp.h>
27 #include <stdio.h>
28 
29 # ifndef __cplusplus
30 #  include <stdbool.h>
31 # endif
32 
33 # ifndef TRUE
34 #   define TRUE     true
35 # endif
36 # ifndef FALSE
37 #   define FALSE    false
38 # endif
39 
40 #include "SDCCset.h"
41 
42 
43 /*
44  * Define host port dependant constants etc.
45  */
46 
47 #define UNIX_DIR_SEPARATOR_CHAR    '/'
48 
49 #if defined(__BORLANDC__) || defined(_MSC_VER)
50 # define STRCASECMP   stricmp
51 # define STRNCASECMP  strnicmp
52 #else
53 # define STRCASECMP   strcasecmp
54 # define STRNCASECMP  strncasecmp
55 #endif
56 
57 #if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__) || defined (__CYGWIN__)
58 
59 # ifndef HAVE_DOS_BASED_FILE_SYSTEM
60 #   define HAVE_DOS_BASED_FILE_SYSTEM 1
61 # endif
62 
63 # define IS_DIR_SEPARATOR(c)    ((c) == DIR_SEPARATOR_CHAR || (c) == UNIX_DIR_SEPARATOR_CHAR)
64 /* Note that IS_ABSOLUTE_PATH accepts d:foo as well, although it is
65    only semi-absolute.  This is because the users of IS_ABSOLUTE_PATH
66    want to know whether to prepend the current working directory to
67    a file name, which should not be done with a name like d:foo.  */
68 # define IS_ABSOLUTE_PATH(f)    (IS_DIR_SEPARATOR((f)[0]) || (((f)[0]) && ((f)[1] == ':')))
69 # define FILENAME_CMP(s1, s2)   STRCASECMP(s1, s2)
70 
71 #else  /* not DOSish */
72 
73 # define IS_DIR_SEPARATOR(c)    ((c) == DIR_SEPARATOR_CHAR)
74 # define IS_ABSOLUTE_PATH(f)    (IS_DIR_SEPARATOR((f)[0]))
75 # define FILENAME_CMP(s1, s2)   strcmp(s1, s2)
76 
77 #endif /* not DOSish */
78 
79 #ifdef WIN32
80 # define NATIVE_WIN32           1
81 # ifndef __MINGW32__
82 #   define  PATH_MAX  _MAX_PATH
83 # endif
84 #endif
85 
86 #ifdef HAVE_CONFIG_H
87 # include "config.h"
88 #elif defined(_WIN32) && !defined(__MINGW32__)
89 # include "sdcc_vc.h"
90 #else
91 # include "sdccconf.h"
92 #endif
93 
94 #include "SDCCerr.h"
95 
96 #define SPACE ' '
97 
98 #include <limits.h>             /* PATH_MAX                  */
99 #if !defined(PATH_MAX) || (PATH_MAX < 2048)
100 # undef PATH_MAX
101 # define PATH_MAX     2048      /* define a reasonable value */
102 #endif
103 
104 #define MAX_REG_PARMS 1
105 
106 /* C++ doesn't like min and max macros */
107 #ifndef __cplusplus
108 # ifndef max
109 #   define max(a,b)   (a > b ? a : b)
110 # endif
111 # ifndef min
112 #   define min(a,b)   (a < b ? a : b)
113 # endif
114 #endif /* __cplusplus */
115 
116 #ifndef THROWS
117 # define THROWS
118 # define THROW_NONE  0
119 # define THROW_SRC   1
120 # define THROW_DEST  2
121 # define THROW_BOTH  3
122 #endif
123 
124 /* sizes in bytes  */
125 #define BOOLSIZE      port->s.char_size
126 #define CHARSIZE      port->s.char_size
127 #define SHORTSIZE     port->s.short_size
128 #define INTSIZE       port->s.int_size
129 #define LONGSIZE      port->s.long_size
130 #define LONGLONGSIZE  port->s.longlong_size
131 #define NEARPTRSIZE   port->s.near_ptr_size
132 #define FARPTRSIZE    port->s.far_ptr_size
133 #define GPTRSIZE      port->s.ptr_size
134 #define FUNCPTRSIZE   port->s.funcptr_size
135 #define BFUNCPTRSIZE  port->s.banked_funcptr_size
136 #define BITSIZE       port->s.bit_size
137 #define FLOATSIZE     port->s.float_size
138 
139 #define INITIAL_INLINEASM (4 * 1024)
140 #define DEFPOOLSTACK(type,size)     \
141     type       *type##Pool        ; \
142     type *type##FreeStack [size]  ; \
143     int   type##StackPtr = 0      ;
144 
145 #define PUSH(x,y)   x##FreeStack[x##StackPtr++] = y
146 #define PEEK(x)     x##FreeStack[x##StackPtr - 1]
147 #define POP(type)   type##FreeStack[--type##StackPtr]
148 /* #define POP(x)    (x##StackPtr ? x##FreeStack[--x##StackPtr] :       \
149    (assert(x##StackPtr),0)) */
150 #ifdef UNIX
151 #define EMPTY(x)        (x##StackPtr <= 1 ? 1 : 0)
152 #else
153 #define EMPTY(x)        (x##StackPtr == 0 ? 1 : 0)
154 #endif
155 
156 
157 #define COPYTYPE(start,end,from)  (end = getSpec (start = from))
158 
159 
160 /* general purpose stack related macros */
161 #define STACK_DCL(stack, type, size)                                \
162         typedef type t_##stack;                                     \
163         t_##stack stack[size];                                      \
164         t_##stack (*p_##stack) = stack - 1;
165 
166 #define STACK_EMPTY(stack)     ((p_##stack) < stack)
167 #define STACK_FULL(stack)      ((p_##stack) >= (stack +             \
168                                 sizeof(stack) / sizeof(*stack) - 1) )
169 
170 #define STACK_PUSH_(stack, x)  (*++p_##stack = (x))
171 #define STACK_POP_(stack)      (*p_##stack--)
172 
173 #define STACK_PUSH(stack, x)   (STACK_FULL(stack)                   \
174                                ? (STACK_ERR(1, stack), *p_##stack)  \
175                                : STACK_PUSH_(stack,x)               )
176 
177 #define STACK_POP(stack)       (STACK_EMPTY(stack)                  \
178                                ? (STACK_ERR(-1, stack), *stack)     \
179                                : STACK_POP_(stack)                  )
180 
181 #define STACK_PEEK(stack)      (STACK_EMPTY(stack)                  \
182                                ? (STACK_ERR(0, stack), *stack)      \
183                                : *p_##stack                         )
184 
185 #define STACK_ERR(o, stack)    (fatal(1, E_STACK_VIOLATION, #stack, \
186                                        (o < 0)                      \
187                                        ? "underflow"                \
188                                        : (o > 0)                    \
189                                          ? "overflow"               \
190                                          : "empty"))
191 
192 /* for semantically partitioned nest level values */
193 #define LEVEL_UNIT      65536
194 #define SUBLEVEL_UNIT   1
195 
196 /* optimization options */
197 struct optimize
198   {
199     int global_cse;
200     int ptrArithmetic;
201     int label1;
202     int label2;
203     int label3;
204     int label4;
205     int loopInvariant;
206     int loopInduction;
207     int noLoopReverse;
208     int codeSpeed;
209     int codeSize;
210     int lospre;
211     int allow_unsafe_read;
212     int noStdLibCall;
213   };
214 
215 /** Build model.
216     Used in options.model.A bit each as port.supported_models is an OR
217     of these.
218 */
219 enum
220   {
221     NO_MODEL = 0,     /* no model applicable */
222     MODEL_SMALL = 1,
223     MODEL_COMPACT = 2,
224     MODEL_MEDIUM = 4,
225     MODEL_LARGE = 8,
226     MODEL_FLAT24 = 16,
227 //  MODEL_PAGE0 = 32, /* disabled, was for the xa51 port */
228     MODEL_HUGE = 64   /* for banked support */
229   };
230 
231 /* overlay segment name and the functions
232    that belong to it. used by pragma overlay */
233 typedef struct {
234     char *osname;       /* overlay segment name */
235     int  nfuncs;        /* number of functions in this overlay */
236     char *funcs[128];   /* function name that belong to this */
237 } olay;
238 
239 enum
240   {
241     NO_DEPENDENCY_FILE_OPT = 0,
242     SYSTEM_DEPENDENCY_FILE_OPT = 1,
243     USER_DEPENDENCY_FILE_OPT = 2
244   };
245 
246 /* other command line options */
247 /*
248  * cloneOptions function in SDCC.lex should be updated every time
249  * a new set is added to the options structure!
250  */
251 struct options
252   {
253     int model;                  /* see MODEL_* defines above */
254     int stackAuto;              /* Stack Automatic  */
255     int useXstack;              /* use Xternal Stack */
256     int stack10bit;             /* use 10 bit stack (flat24 model only) */
257     int dump_ast;               /* dump front-end tree before lowering to iCode */
258     int dump_i_code;            /* dump iCode at various stages */
259     int dump_graphs;            /* Dump graphs in .dot format (control-flow, conflict, etc) */
260     int cc_only;                /* compile only flag              */
261     int intlong_rent;           /* integer & long support routines reentrant */
262     int float_rent;             /* floating point routines are reentrant */
263     int out_fmt;                /* 0 = undefined, 'i' = intel Hex format, 's' = motorola S19 format, 'E' = elf format, 'Z' = gb format */
264     int cyclomatic;             /* print cyclomatic information */
265     int noOverlay;              /* don't overlay local variables & parameters */
266     int xram_movc;              /* use movc instead of movx to read xram (mcs51) */
267     int nopeep;                 /* no peep hole optimization */
268     int asmpeep;                /* pass inline assembler thru peep hole */
269     int peepReturn;             /* enable peephole optimization for return instructions */
270     int debug;                  /* generate extra debug info */
271     int c1mode;                 /* Act like c1 - no pre-proc, asm or link */
272     char *peep_file;            /* additional rules for peep hole */
273     int nostdlib;               /* Don't use standard lib files */
274     int nostdinc;               /* Don't use standard include files */
275     int noRegParams;            /* Disable passing some parameters in registers */
276     int verbose;                /* Show what the compiler is doing */
277     int lessPedantic;           /* disable some warnings */
278     int profile;                /* Turn on extra profiling information */
279     int omitFramePtr;           /* Turn off the frame pointer. */
280     int useAccelerator;         /* use ds390 Arithmetic Accelerator */
281     int noiv;                   /* do not generate irq vector table entries */
282     int all_callee_saves;       /* callee saves for all functions */
283     int stack_probe;            /* insert call to function __stack_probe */
284     int tini_libid;             /* library ID for TINI */
285     int protect_sp_update;      /* DS390 - will disable interrupts during ESP:SP updates */
286     int parms_in_bank1;         /* DS390 - use reg bank1 to pass parameters */
287     int stack_size;             /* MCS51/DS390 - Tells the linker to allocate this space for stack */
288     int no_pack_iram;           /* MCS51/DS390 - Deprecated: Tells the linker not to pack variables in internal ram */
289     int acall_ajmp;             /* MCS51 - Use acall/ajmp instead of lcall/ljmp */
290     int no_ret_without_call;    /* MCS51 - Do not use ret independent of acall/lcall */
291     int use_non_free;           /* Search / include non-free licensed libraries and header files */
292     /* starting address of the segments */
293     int xstack_loc;             /* initial location of external stack */
294     int stack_loc;              /* initial value of internal stack pointer */
295     int xdata_loc;              /* xternal ram starts at address */
296     int data_loc;               /* interram start location       */
297     int idata_loc;              /* indirect address space        */
298     int code_loc;               /* code location start           */
299     int iram_size;              /* internal ram size (used only for error checking) */
300     int xram_size;              /* external ram size (used only for error checking) */
301     bool xram_size_set;         /* since xram_size=0 is a possibility */
302     int code_size;              /* code size (used only for error checking) */
303     int verboseExec;            /* show what we are doing */
304     int noXinitOpt;             /* don't optimize initialized xdata */
305     int noCcodeInAsm;           /* hide c-code from asm */
306     int iCodeInAsm;             /* show i-code in asm */
307     int noPeepComments;         /* hide peephole optimizer comments */
308     int verboseAsm;             /* include comments generated with gen.c */
309     int printSearchDirs;        /* display the directories in the compiler's search path */
310     int vc_err_style;           /* errors and warnings are compatible with Micro$oft visual studio */
311     int use_stdout;             /* send errors to stdout instead of stderr */
312     int no_std_crt0;            /* for the z80/gbz80 do not link default crt0.o*/
313     int std_c95;                /* enable C95 keywords/constructs */
314     int std_c99;                /* enable C99 keywords/constructs */
315     int std_c11;                /* enable C11 keywords/constructs */
316     int std_c2x;                /* enable C2X keywords/constructs */
317     int std_sdcc;               /* enable SDCC extensions to C */
318     int dollars_in_ident;       /* zero means dollar signs are punctuation */
319     int signed_char;            /* use signed for char without signed/unsigned modifier */
320     char *code_seg;             /* segment name to use instead of CSEG */
321     char *const_seg;            /* segment name to use instead of CONST */
322     char *data_seg;             /* segment name to use instead of DATA */
323     int dependencyFileOpt;      /* write dependencies to given file */
324     /* sets */
325     set *calleeSavesSet;        /* list of functions using callee save */
326     set *excludeRegsSet;        /* registers excluded from saving */
327 /*  set *olaysSet;               * not implemented yet: overlay segments used in #pragma OVERLAY */
328     int max_allocs_per_node;    /* Maximum number of allocations / combinations considered at each node in the tree-decomposition based algorithms */
329     bool noOptsdccInAsm;        /* Do not emit .optsdcc in asm */
330     bool oldralloc;             /* Use old register allocator */
331   };
332 
333 /* forward definition for variables accessed globally */
334 extern int noAssemble;          /* no assembly, stop after code generation */
335 extern char *yytext;
336 extern char *lexFilename;       /* lex idea of current file name */
337 extern int lexLineno;           /* lex idea of line number of the current file */
338 extern const char *fullSrcFileName; /* full name for the source file; */
339                                 /* can be NULL while linking without compiling */
340 extern const char *fullDstFileName; /* full name for the output file; */
341                                 /* only given by -o, otherwise NULL */
342 extern const char *dstFileName; /* destination file name without extension */
343 extern const char *moduleName;  /* module name is source file without path and extension */
344                                 /* can be NULL while linking without compiling */
345 extern int seqPointNo;          /* current sequence point */
346 extern FILE *yyin;              /* */
347 extern FILE *asmFile;           /* assembly output file */
348 extern FILE *cdbFile;           /* debugger symbol file */
349 extern long NestLevel;          /* NestLevel                 SDCC.y */
350 extern int stackPtr;            /* stack pointer             SDCC.y */
351 extern int xstackPtr;           /* external stack pointer    SDCC.y */
352 extern int reentrant;           /* /X flag has been sent     SDCC.y */
353 extern char buffer[PATH_MAX * 2];/* general buffer           SDCCmain.c */
354 extern int currRegBank;         /* register bank being used  SDCCgens.c */
355 extern int RegBankUsed[4];      /* JCF: register banks used  SDCCmain.c */
356 extern int BitBankUsed;         /* MB: overlayable bit bank  SDCCmain.c */
357 extern struct symbol *currFunc; /* current function    SDCCgens.c */
358 extern long cNestLevel;         /* block nest level  SDCCval.c */
359 extern int blockNo;             /* maximum sequential block number */
360 extern int currBlockno;         /* sequential block number */
361 extern struct optimize optimize;
362 extern struct options options;
363 extern unsigned maxInterrupts;
364 extern int ignoreTypedefType;
365 
366 /* Visible from SDCCmain.c */
367 extern set *preArgvSet;
368 extern set *relFilesSet;
369 extern set *libFilesSet;
370 extern set *libPathsSet;
371 extern set *libDirsSet;         /* list of lib search directories */
372 
373 void setParseWithComma (set **, const char *);
374 
375 /** An assert() macro that will go out through sdcc's error
376     system.
377 */
378 #define wassertl(a,s)   (void)((a) ? 0 : \
379         (werror (E_INTERNAL_ERROR, __FILE__, __LINE__, s), 0))
380 
381 #define wassert(a)    wassertl(a,"code generator internal error")
382 
383 enum {
384   DUMP_RAW0 = 1,
385   DUMP_RAW1,
386   DUMP_CSE,
387   DUMP_DFLOW,
388   DUMP_GCSE,
389   DUMP_DEADCODE,
390   DUMP_LOOP,
391   DUMP_LOOPG,
392   DUMP_LOOPD,
393   DUMP_RANGE,
394   DUMP_PACK,
395   DUMP_RASSGN,
396   DUMP_LRANGE,
397   DUMP_LOSPRE,
398   DUMP_CUSTOM /* For temporary dump points */
399 };
400 
401 struct _dumpFiles {
402   int id;
403   char *ext;
404   FILE *filePtr;
405 };
406 
407 extern struct _dumpFiles dumpFiles[];
408 
409 /* Define well known filenos if the system does not define them.  */
410 #ifndef STDIN_FILENO
411 # define STDIN_FILENO   0
412 #endif
413 #ifndef STDOUT_FILENO
414 # define STDOUT_FILENO  1
415 #endif
416 #ifndef STDERR_FILENO
417 # define STDERR_FILENO  2
418 #endif
419 
420 #endif
421