1 /**
2  * Configuration enums/variables for different targets
3  *
4  * Compiler implementation of the
5  * $(LINK2 https://www.dlang.org, D programming language).
6  *
7  * Copyright:   Copyright (C) 1985-1998 by Symantec
8  *              Copyright (C) 2000-2023 by The D Language Foundation, All Rights Reserved
9  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
10  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
11  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/cdef.d, backend/_cdef.d)
12  */
13 
14 module dmd.backend.cdef;
15 
16 // Online documentation: https://dlang.org/phobos/dmd_backend_cdef.html
17 
18 import dmd.common.int128;
19 
20 import dmd.backend.cc: Classsym, Symbol, param_t, config;
21 import dmd.backend.el;
22 import dmd.backend.ty : I32;
23 import dmd.backend.global : REGSIZE;
24 
25 import dmd.backend.dlist;
26 
27 @nogc:
28 nothrow:
29 @safe:
30 
31 enum VERSION = "9.00.0";        // for banner and imbedding in .OBJ file
32 enum VERSIONHEX = "0x900";      // for __DMC__ macro
33 enum VERSIONINT = 0x900;        // for precompiled headers and DLL version
34 
35 extern (D) template xversion(string s)
36 {
37     enum xversion = mixin(`{ version (` ~ s ~ `) return true; else return false; }`)();
38 }
39 
40 enum TARGET_LINUX   = xversion!`linux`;
41 enum TARGET_OSX     = xversion!`OSX`;
42 enum TARGET_FREEBSD = xversion!`FreeBSD`;
43 enum TARGET_OPENBSD = xversion!`OpenBSD`;
44 enum TARGET_SOLARIS = xversion!`Solaris`;
45 enum TARGET_WINDOS  = xversion!`Windows`;
46 enum TARGET_DRAGONFLYBSD  = xversion!`DragonFlyBSD`;
47 
48 //
49 //      Attributes
50 //
51 
52 //      Types of attributes
53 enum
54 {
55     ATTR_LINKMOD    = 1,     // link modifier
56     ATTR_TYPEMOD    = 2,     // basic type modifier
57     ATTR_FUNCINFO   = 4,     // function information
58     ATTR_DATAINFO   = 8,     // data information
59     ATTR_TRANSU     = 0x10,  // transparent union
60     ATTR_IGNORED    = 0x20,  // attribute can be ignored
61     ATTR_WARNING    = 0x40,  // attribute was ignored
62     ATTR_SEGMENT    = 0x80,  // segment secified
63 }
64 
65 //      attribute location in code
66 enum
67 {
68     ALOC_DECSTART   = 1,   // start of declaration
69     ALOC_SYMDEF     = 2,   // symbol defined
70     ALOC_PARAM      = 4,   // follows function parameter
71     ALOC_FUNC       = 8,   // follows function declaration
72 }
73 
74 //#define ATTR_LINK_MODIFIERS (mTYconst|mTYvolatile|mTYcdecl|mTYstdcall)
75 //#define ATTR_CAN_IGNORE(a) (((a) & (ATTR_LINKMOD|ATTR_TYPEMOD|ATTR_FUNCINFO|ATTR_DATAINFO|ATTR_TRANSU)) == 0)
76 //#define LNX_CHECK_ATTRIBUTES(a,x) assert(((a) & ~(x|ATTR_IGNORED|ATTR_WARNING)) == 0)
77 
78 version (_WINDLL)
79     enum SUFFIX = "nd";
80 else version (_WIN64)
81     enum SUFFIX = "a";
82 else version (Win32)
83     enum SUFFIX = "n";
84 else
85     enum SUFFIX = "";
86 
87 // Generate cleanup code
88 enum TERMCODE = 0;
89 
90 // C++ Language Features
91 enum ANGLE_BRACKET_HACK = 0;       // >> means two template arglist closes
92 
93 // C/C++ Language Features
94 enum IMPLIED_PRAGMA_ONCE = 1;       // include guards count as #pragma once
95 enum bool HEADER_LIST = true;
96 
97 // Support generating code for 16 bit memory models
98 enum SIXTEENBIT = false;
99 
100 /* Set for supporting the FLAT memory model.
101  * This is not quite the same as !SIXTEENBIT, as one could
102  * have near/far with 32 bit code.
103  */
104 enum TARGET_SEGMENTED = false;
105 
106 // NT structured exception handling
107 //      0: no support
108 //      1: old style
109 //      2: new style
110 enum NTEXCEPTIONS = 2;
111 
112 // For Shared Code Base
113 //#if _WINDLL
114 //#define dbg_printf dll_printf
115 //#else
116 //#define dbg_printf printf
117 //#endif
118 
119 //#ifndef ERRSTREAM
120 //#define ERRSTREAM stdout
121 //#endif
122 //#define err_printf printf
123 //#define err_vprintf vfprintf
124 //#define err_fputc fputc
125 //#define dbg_fputc fputc
126 //#define LF '\n'
127 //#define LF_STR "\n"
128 //#define CR '\r'
129 //#define ANSI        config.ansi_c
130 //#define ANSI_STRICT config.ansi_c
131 //#define ANSI_RELAX  config.ansi_c
132 //#define TRIGRAPHS   ANSI
133 //#define T80x86(x)       x
134 
135 // For Share MEM_ macros - default to mem_xxx package
136 // PH           precompiled header
137 // PARF         parser, life of function
138 // PARC         parser, life of compilation
139 // BEF          back end, function
140 // BEC          back end, compilation
141 
142 // If we can use 386 instruction set (possible in 16 bit code)
143 //#define I386 (config.target_cpu >= TARGET_80386)
144 
145 // If we are generating 32 bit code
146 //#if MARS
147 //#define I16     0               // no 16 bit code for D
148 //#define I32     (NPTRSIZE == 4)
149 //#define I64     (NPTRSIZE == 8) // 1 if generating 64 bit code
150 //#else
151 //#define I16     (NPTRSIZE == 2)
152 //#define I32     (NPTRSIZE == 4)
153 //#define I64     (NPTRSIZE == 8) // 1 if generating 64 bit code
154 //#endif
155 
156 /**********************************
157  * Limits & machine dependent stuff.
158  */
159 
160 /* Define stuff that's different between VAX and IBMPC.
161  * HOSTBYTESWAPPED      TRUE if on the host machine the bytes are
162  *                      swapped (TRUE for 6809, 68000, FALSE for 8088
163  *                      and VAX).
164  */
165 
166 
167 enum EXIT_BREAK = 255;     // aborted compile with ^C
168 
169 /* Take advantage of machines that can store a word, lsb first  */
170 //#if _M_I86              // if Intel processor
171 //#define TOWORD(ptr,val) (*(unsigned short *)(ptr) = (unsigned short)(val))
172 //#define TOLONG(ptr,val) (*(unsigned *)(ptr) = (unsigned)(val))
173 //#else
174 //#define TOWORD(ptr,val) (((ptr)[0] = (unsigned char)(val)),\
175 //                         ((ptr)[1] = (unsigned char)((val) >> 8)))
176 //#define TOLONG(ptr,val) (((ptr)[0] = (unsigned char)(val)),\
177 //                         ((ptr)[1] = (unsigned char)((val) >> 8)),\
178 //                         ((ptr)[2] = (unsigned char)((val) >> 16)),\
179 //                         ((ptr)[3] = (unsigned char)((val) >> 24)))
180 //#endif
181 //
182 //#define TOOFFSET(a,b)   (I32 ? TOLONG(a,b) : TOWORD(a,b))
183 
184 /***************************
185  * Target machine data types as they appear on the host.
186  */
187 
188 alias targ_char = byte;
189 alias targ_uchar = ubyte;
190 alias targ_schar = byte;
191 alias targ_short = short;
192 alias targ_ushort= ushort;
193 alias targ_long = int;
194 alias targ_ulong = uint;
195 alias targ_llong = long;
196 alias targ_ullong = ulong;
197 alias targ_float = float;
198 alias targ_double = double;
199 public import dmd.root.longdouble : targ_ldouble = longdouble;
200 
201 // Extract most significant register from constant
202 ulong MSREG(ulong p) { return (REGSIZE == 2) ? p >> 16 : ((targ_llong.sizeof == 8) ? p >> 32 : 0); }
203 
204 alias targ_int = int;
205 alias targ_uns = uint;
206 
207 /* Sizes of base data types in bytes */
208 enum
209 {
210     CHARSIZE       = 1,
211     SHORTSIZE      = 2,
212     WCHARSIZE      = 2,       // 2 for WIN32, 4 for linux/OSX/FreeBSD/OpenBSD/DragonFlyBSD/Solaris
213     LONGSIZE       = 4,
214     LLONGSIZE      = 8,
215     CENTSIZE       = 16,
216     FLOATSIZE      = 4,
217     DOUBLESIZE     = 8,
218     TMAXSIZE       = 16,      // largest size a constant can be
219 }
220 
221 enum REGMASK = 0xFFFF;
222 
223 // targ_llong is also used to store host pointers, so it should have at least their size
224 
225 // 64 bit support
226 alias targ_ptrdiff_t = long;   // ptrdiff_t for target machine
227 alias targ_size_t    = ulong;  // size_t for the target machine
228 
229 
230 enum
231 {
232     Smodel = 0,        // 64k code, 64k data, or flat model
233     Mmodel = 1,        // large code, 64k data
234     Cmodel = 2,        // 64k code, large data
235     Lmodel = 3,        // large code, large data
236     Vmodel = 4,        // large code, large data, vcm
237 }
238 
239 enum MEMMODELS = 1; // number of memory models
240 
241 /* Segments     */
242 enum
243 {
244     CODE      = 1,     // code segment
245     DATA      = 2,     // initialized data
246     CDATA     = 3,     // constant data
247     UDATA     = 4,     // uninitialized data
248     CDATAREL  = 5,     // constant data with relocs
249     UNKNOWN   = -1,    // unknown segment
250     DGROUPIDX = 1,     // group index of DGROUP
251 }
252 
253 enum REGMAX = 29;      // registers are numbered 0..10
254 
255 alias tym_t = uint;    // data type big enough for type masks
256 
257 /**********************************
258  * Configuration
259  */
260 
261 /* Linkage type         */
262 enum linkage_t
263 {
264     LINK_C,                     /* C style                              */
265     LINK_CPP,                   /* C++ style                            */
266     LINK_PASCAL,                /* Pascal style                         */
267     LINK_FORTRAN,
268     LINK_SYSCALL,
269     LINK_STDCALL,
270     LINK_D,                     // D code
271     LINK_MAXDIM                 /* array dimension                      */
272 }
273 
274 /**********************************
275  * Exception handling method
276  */
277 
278 enum EHmethod
279 {
280     EH_NONE,                    // no exception handling
281     EH_SEH,                     // SEH __try, __except, __finally only
282     EH_WIN32,                   // Win32 SEH
283     EH_WIN64,                   // Win64 SEH (not supported yet)
284     EH_DM,                      // Digital Mars method
285     EH_DWARF,                   // Dwarf method
286 }
287 
288 // CPU target
289 alias cpu_target_t = byte;
290 enum
291 {
292     TARGET_8086             = 0,
293     TARGET_80286            = 2,
294     TARGET_80386            = 3,
295     TARGET_80486            = 4,
296     TARGET_Pentium          = 5,
297     TARGET_PentiumMMX       = 6,
298     TARGET_PentiumPro       = 7,
299     TARGET_PentiumII        = 8,
300 }
301 
302 // Symbolic debug info
303 alias symbolic_debug_t = byte;
304 enum
305 {
306     CVNONE    = 0,           // No symbolic info
307     CVOLD     = 1,           // Codeview 1 symbolic info
308     CV4       = 2,           // Codeview 4 symbolic info
309     CVSYM     = 3,           // Symantec format
310     CVTDB     = 4,           // Symantec format written to file
311     CVDWARF_C = 5,           // Dwarf in C format
312     CVDWARF_D = 6,           // Dwarf in D format
313     CVSTABS   = 7,           // Elf Stabs in C format
314     CV8       = 8,           // Codeview 8 symbolic info
315 }
316 
317 // Windows code gen flags
318 alias windows_flags_t = uint;
319 enum
320 {
321     WFwindows    = 1,      // generating code for Windows app or DLL
322     WFdll        = 2,      // generating code for Windows DLL
323     WFincbp      = 4,      // mark far stack frame with inc BP / dec BP
324     WFloadds     = 8,      // assume __loadds for all functions
325     WFexpdef     = 0x10,   // generate export definition records for
326                            // exported functions
327     WFss         = 0x20,   // load DS from SS
328     WFreduced    = 0x40,   // skip DS load for non-exported functions
329     WFdgroup     = 0x80,   // load DS from DGROUP
330     WFexport     = 0x100,  // assume __export for all far functions
331     WFds         = 0x200,  // load DS from DS
332     WFmacros     = 0x400,  // define predefined windows macros
333     WFssneds     = 0x800,  // SS != DS
334     WFthunk      = 0x1000, // use fixups instead of direct ref to CS
335     WFsaveds     = 0x2000, // use push/pop DS for far functions
336     WFdsnedgroup = 0x4000, // DS != DGROUP
337     WFexe        = 0x8000, // generating code for Windows EXE
338 }
339 
340 // Object file format
341 alias objfmt_t = uint;
342 enum
343 {
344     OBJ_OMF         = 1,
345     OBJ_MSCOFF      = 2,
346     OBJ_ELF         = 4,
347     OBJ_MACH        = 8,
348 }
349 
350 // Executable file format
351 alias exefmt_t = uint;
352 enum
353 {
354     EX_DOSX         = 1,       // DOSX 386 program
355     EX_ZPM          = 2,       // ZPM 286 program
356     EX_RATIONAL     = 4,       // RATIONAL 286 program
357     EX_PHARLAP      = 8,       // PHARLAP 386 program
358     EX_COM          = 0x10,    // MSDOS .COM program
359     EX_OS2          = 0x40,    // OS/2 2.0 32 bit program
360     EX_OS1          = 0x80,    // OS/2 1.x 16 bit program
361     EX_WIN32        = 0x100,
362     EX_MZ           = 0x200,   // MSDOS real mode program
363     EX_LINUX        = 0x2000,
364     EX_WIN64        = 0x4000,  // AMD64 and Windows (64 bit mode)
365     EX_LINUX64      = 0x8000,  // AMD64 and Linux (64 bit mode)
366     EX_OSX          = 0x10000,
367     EX_OSX64        = 0x20000,
368     EX_FREEBSD      = 0x40000,
369     EX_FREEBSD64    = 0x80000,
370     EX_SOLARIS      = 0x100000,
371     EX_SOLARIS64    = 0x200000,
372     EX_OPENBSD      = 0x400000,
373     EX_OPENBSD64    = 0x800000,
374     EX_DRAGONFLYBSD64 = 0x1000000,
375 }
376 
377 // All of them
378 enum exefmt_t EX_all =
379     EX_DOSX      |
380     EX_ZPM       |
381     EX_RATIONAL  |
382     EX_PHARLAP   |
383     EX_COM       |
384     EX_OS2       |
385     EX_OS1       |
386     EX_WIN32     |
387     EX_MZ        |
388     EX_LINUX     |
389     EX_WIN64     |
390     EX_LINUX64   |
391     EX_OSX       |
392     EX_OSX64     |
393     EX_FREEBSD   |
394     EX_FREEBSD64 |
395     EX_SOLARIS   |
396     EX_SOLARIS64 |
397     EX_OPENBSD   |
398     EX_OPENBSD64 |
399     EX_DRAGONFLYBSD64;
400 
401 // All segmented memory models
402 enum exefmt_t EX_segmented = EX_DOSX | EX_ZPM | EX_RATIONAL | EX_PHARLAP |
403                         EX_COM | EX_OS1 | EX_MZ;
404 
405 // All flat memory models (no segment registers)
406 enum exefmt_t EX_flat = EX_OS2 | EX_WIN32 | EX_WIN64 | EX_posix;
407 
408 // All DOS executable types
409 enum exefmt_t EX_dos =  EX_DOSX | EX_ZPM | EX_RATIONAL | EX_PHARLAP |
410                          EX_COM | EX_MZ;
411 
412 // Windows and DOS executable types
413 enum exefmt_t EX_windos = EX_dos | EX_OS1 | EX_OS2 | EX_WIN32 | EX_WIN64;
414 
415 // All POSIX systems
416 enum exefmt_t EX_posix = EX_LINUX   | EX_LINUX64   |
417                          EX_OSX     | EX_OSX64     |
418                          EX_FREEBSD | EX_FREEBSD64 |
419                          EX_SOLARIS | EX_SOLARIS64 |
420                          EX_OPENBSD | EX_OPENBSD64 |
421                          EX_DRAGONFLYBSD64;
422 
423 // All 16 bit targets
424 enum exefmt_t EX_16 = EX_ZPM | EX_RATIONAL | EX_COM | EX_OS1 | EX_MZ;
425 
426 // All 32 bit targets
427 enum exefmt_t EX_32 = EX_DOSX | EX_OS2 | EX_PHARLAP |
428                 EX_WIN32   |
429                 EX_LINUX   |
430                 EX_OSX     |
431                 EX_FREEBSD |
432                 EX_SOLARIS |
433                 EX_OPENBSD;
434 
435 // All 64 bit targets
436 enum exefmt_t EX_64 =
437                 EX_WIN64     |
438                 EX_LINUX64   |
439                 EX_OSX64     |
440                 EX_FREEBSD64 |
441                 EX_SOLARIS64 |
442                 EX_OPENBSD64 |
443                 EX_DRAGONFLYBSD64;
444 
445 // Constraints
446 static assert(EX_all == (EX_segmented ^ EX_flat));
447 static assert(EX_all == (EX_16 ^ EX_32 ^ EX_64));
448 static assert(EX_all == (EX_windos ^ EX_posix));
449 
450 alias config_flags_t = uint;
451 enum
452 {
453     CFGuchar        = 1,       // chars are unsigned
454     CFGsegs         = 2,       // new code seg for each far func
455     CFGtrace        = 4,       // output trace functions
456     CFGglobal       = 8,       // make all static functions global
457     CFGstack        = 0x10,    // add stack overflow checking
458     CFGalwaysframe  = 0x20,    // always generate stack frame
459     CFGnoebp        = 0x40,    // do not use EBP as general purpose register
460     CFGromable      = 0x80,    // put switch tables in code segment
461     CFGeasyomf      = 0x100,   // generate Pharlap Easy-OMF format
462     CFGfarvtbls     = 0x200,   // store vtables in far segments
463     CFGnoinlines    = 0x400,   // do not inline functions
464     CFGnowarning    = 0x800,   // disable warnings
465 }
466 
467 alias config_flags2_t = uint;
468 enum
469 {
470     CFG2comdat      = 1,       // use initialized common blocks
471     CFG2nodeflib    = 2,       // no default library imbedded in OBJ file
472     CFG2browse      = 4,       // generate browse records
473     CFG2dyntyping   = 8,       // generate dynamic typing information
474     CFG2fulltypes   = 0x10,    // don't optimize CV4 class info
475     CFG2warniserr   = 0x20,    // treat warnings as errors
476     CFG2phauto      = 0x40,    // automatic precompiled headers
477     CFG2phuse       = 0x80,    // use precompiled headers
478     CFG2phgen       = 0x100,   // generate precompiled header
479     CFG2once        = 0x200,   // only include header files once
480     CFG2hdrdebug    = 0x400,   // generate debug info for header
481     CFG2phautoy     = 0x800,   // fast build precompiled headers
482     CFG2noobj       = 0x1000,  // we are not generating a .OBJ file
483     CFG2noerrmax    = 0x2000,  // no error count maximum
484     CFG2expand      = 0x4000,  // expanded output to list file
485     CFG2stomp       = 0x8000,  // enable stack stomping code
486     CFG2gms         = 0x10000, // optimize debug symbols for microsoft debuggers
487     CFG2genmain     = 0x20000, // main entrypoint is generated
488 }
489 
490 alias config_flags3_t = uint;
491 enum
492 {
493     CFG3ju          = 1,       // char == unsigned char
494     CFG3eh          = 2,       // generate exception handling stuff
495     CFG3strcod      = 4,       // strings are placed in code segment
496     CFG3eseqds      = 8,       // ES == DS at all times
497     CFG3ptrchk      = 0x10,    // generate pointer validation code
498     CFG3strictproto = 0x20,    // strict prototyping
499     CFG3autoproto   = 0x40,    // auto prototyping
500     CFG3rtti        = 0x80,    // add RTTI support
501     CFG3relax       = 0x100,   // relaxed type checking (C only)
502     CFG3cpp         = 0x200,   // C++ compile
503     CFG3igninc      = 0x400,   // ignore standard include directory
504     CFG3mars        = 0x800,   // use mars libs and headers
505     CFG3nofar       = 0x1000,  // ignore __far and __huge keywords
506     CFG3noline      = 0x2000,  // do not output #line directives
507     CFG3comment     = 0x4000,  // leave comments in preprocessed output
508     CFG3cppcomment  = 0x8000,  // allow C++ style comments
509     CFG3wkfloat     = 0x10000, // make floating point references weak externs
510     CFG3digraphs    = 0x20000, // support ANSI C++ digraphs
511     CFG3semirelax   = 0x40000, // moderate relaxed type checking (non-Windows targets)
512     CFG3pic         = 0x80000, // position independent code
513     CFG3pie         = 0x10_0000, // position independent executable (CFG3pic also set)
514     CFG3ibt         = 0x20_0000, // indirect branch tracking
515 }
516 
517 alias config_flags4_t = uint;
518 enum
519 {
520     CFG4speed            = 1,          // optimized for speed
521     CFG4space            = 2,          // optimized for space
522     CFG4allcomdat        = 4,          // place all functions in COMDATs
523     CFG4fastfloat        = 8,          // fast floating point (-ff)
524     CFG4fdivcall         = 0x10,       // make function call for FDIV opcodes
525     CFG4tempinst         = 0x20,       // instantiate templates for undefined functions
526     CFG4oldstdmangle     = 0x40,       // do stdcall mangling without @
527     CFG4pascal           = 0x80,       // default to pascal linkage
528     CFG4stdcall          = 0x100,      // default to std calling convention
529     CFG4cacheph          = 0x200,      // cache precompiled headers in memory
530     CFG4alternate        = 0x400,      // if alternate digraph tokens
531     CFG4bool             = 0x800,      // support 'bool' as basic type
532     CFG4wchar_t          = 0x1000,     // support 'wchar_t' as basic type
533     CFG4notempexp        = 0x2000,     // no instantiation of template functions
534     CFG4anew             = 0x4000,     // allow operator new[] and delete[] overloading
535     CFG4oldtmangle       = 0x8000,     // use old template name mangling
536     CFG4dllrtl           = 0x10000,    // link with DLL RTL
537     CFG4noemptybaseopt   = 0x20000,    // turn off empty base class optimization
538     CFG4nowchar_t        = 0x40000,    // use unsigned short name mangling for wchar_t
539     CFG4forscope         = 0x80000,    // new C++ for scoping rules
540     CFG4warnccast        = 0x100000,   // warn about C style casts
541     CFG4adl              = 0x200000,   // argument dependent lookup
542     CFG4enumoverload     = 0x400000,   // enum overloading
543     CFG4implicitfromvoid = 0x800000,   // allow implicit cast from void* to T*
544     CFG4dependent        = 0x1000000,  // dependent / non-dependent lookup
545     CFG4wchar_is_long    = 0x2000000,  // wchar_t is 4 bytes
546     CFG4underscore       = 0x4000000,  // prepend _ for C mangling
547 }
548 
549 enum config_flags4_t CFG4optimized  = CFG4speed | CFG4space;
550 enum config_flags4_t CFG4stackalign = CFG4speed;       // align stack to 8 bytes
551 
552 alias config_flags5_t = uint;
553 enum
554 {
555     CFG5debug       = 1,      // compile in __debug code
556     CFG5in          = 2,      // compile in __in code
557     CFG5out         = 4,      // compile in __out code
558     CFG5invariant   = 8,      // compile in __invariant code
559 }
560 
561 /* CFGX: flags ignored in precompiled headers
562  * CFGY: flags copied from precompiled headers into current config
563  */
564 enum config_flags_t CFGX   = CFGnowarning;
565 enum config_flags2_t CFGX2 = CFG2warniserr | CFG2phuse | CFG2phgen | CFG2phauto |
566                              CFG2once | CFG2hdrdebug | CFG2noobj | CFG2noerrmax |
567                              CFG2expand | CFG2nodeflib | CFG2stomp | CFG2gms;
568 enum config_flags3_t CFGX3 = CFG3strcod | CFG3ptrchk;
569 enum config_flags4_t CFGX4 = CFG4optimized | CFG4fastfloat | CFG4fdivcall |
570                              CFG4tempinst | CFG4cacheph | CFG4notempexp |
571                              CFG4stackalign | CFG4dependent;
572 
573 enum config_flags4_t CFGY4 = CFG4nowchar_t | CFG4noemptybaseopt | CFG4adl |
574                              CFG4enumoverload | CFG4implicitfromvoid |
575                              CFG4wchar_is_long | CFG4underscore;
576 
577 // Configuration flags for HTOD executable
578 alias htod_flags_t = uint;
579 enum
580 {
581     HTODFinclude    = 1,      // -hi drill down into #include files
582     HTODFsysinclude = 2,      // -hs drill down into system #include files
583     HTODFtypedef    = 4,      // -ht drill down into typedefs
584     HTODFcdecl      = 8,      // -hc skip C declarations as comments
585 }
586 
587 // This part of the configuration is saved in the precompiled header for use
588 // in comparing to make sure it hasn't changed.
589 
590 struct Config
591 {
592     char language;              // 'C' = C, 'D' = C++
593     string _version;            /// Compiler version
594     char[3] exetype;            // distinguish exe types so PH
595                                 // files are distinct (= SUFFIX)
596 
597     cpu_target_t target_cpu;       // instruction selection
598     cpu_target_t target_scheduler; // instruction scheduling (normally same as selection)
599 
600     short versionint;           // intermediate file version (= VERSIONINT)
601     int defstructalign;         // struct alignment specified by command line
602     short hxversion;            // HX version number
603     symbolic_debug_t fulltypes; // format of symbolic debug info
604 
605     windows_flags_t wflags;     // flags for Windows code generation
606 
607     bool fpxmmregs;             // use XMM registers for floating point
608     ubyte avx;                  // use AVX instruction set (0, 1, 2)
609     ubyte inline8087;           /* 0:   emulator
610                                    1:   IEEE 754 inline 8087 code
611                                    2:   fast inline 8087 code
612                                  */
613     short memmodel;             // 0:S,X,N,F, 1:M, 2:C, 3:L, 4:V
614     objfmt_t objfmt;            // target object format
615     exefmt_t exe;               // target operating system
616 
617     config_flags_t  flags;
618     config_flags2_t flags2;
619     config_flags3_t flags3;
620     config_flags4_t flags4;
621     config_flags5_t flags5;
622 
623     htod_flags_t htodFlags;     // configuration for htod
624     ubyte ansi_c;               // strict ANSI C
625                                 // 89 for ANSI C89, 99 for ANSI C99
626     ubyte asian_char;           // 0: normal, 1: Japanese, 2: Chinese
627                                 // and Taiwanese, 3: Korean
628     uint threshold;             // data larger than threshold is assumed to
629                                 // be far (16 bit models only)
630                                 // if threshold == THRESHMAX, all data defaults
631                                 // to near
632     linkage_t linkage;          // default function call linkage
633     EHmethod ehmethod;          // exception handling method
634     bool useModuleInfo;         // implement ModuleInfo
635     bool useTypeInfo;           // implement TypeInfo
636     bool useExceptions;         // implement exception handling
637     ubyte dwarf;                // DWARF version
638 }
639 
640 enum THRESHMAX = 0xFFFF;
641 
642 // Language for error messages
643 enum LANG
644 {
645     english,
646     german,
647     french,
648     japanese,
649 }
650 
651 // Configuration that is not saved in precompiled header
652 
653 struct Configv
654 {
655     ubyte addlinenumbers;       // put line number info in .OBJ file
656     ubyte vasm;                 // print generated assembler for each function
657     ubyte verbose;              // 0: compile quietly (no messages)
658                                 // 1: show progress to DLL (default)
659                                 // 2: full verbosity
660     char* csegname;             // code segment name
661     char* deflibname;           // default library name
662     LANG language;              // message language
663     int errmax;                 // max error count
664 }
665 
666 alias reg_t = ubyte;            // register number
667 alias regm_t = uint;            // Register mask type
668 struct immed_t
669 {
670     targ_size_t[REGMAX] value;  // immediate values in registers
671     regm_t mval;                // Mask of which values in regimmed.value[] are valid
672 }
673 
674 
675 struct cse_t
676 {
677     elem*[REGMAX] value;        // expression values in registers
678     regm_t mval;                // mask of which values in value[] are valid
679     regm_t mops;                // subset of mval that contain common subs that need
680                                 // to be stored in csextab[] if they are destroyed
681 }
682 
683 struct con_t
684 {
685     cse_t cse;                  // CSEs in registers
686     immed_t immed;              // immediate values in registers
687     regm_t mvar;                // mask of register variables
688     regm_t mpvar;               // mask of SCfastpar, SCshadowreg register variables
689     regm_t indexregs;           // !=0 if more than 1 uncommitted index register
690     regm_t used;                // mask of registers used
691     regm_t params;              // mask of registers which still contain register
692                                 // function parameters
693 }
694 
695 /*********************************
696  * Bootstrap complex types.
697  */
698 
699 import dmd.backend.bcomplex;
700 
701 /*********************************
702  * Union of all data types. Storage allocated must be the right
703  * size of the data on the TARGET, not the host.
704  */
705 
706 union eve
707 {
708         targ_char       Vchar;
709         targ_schar      Vschar;
710         targ_uchar      Vuchar;
711         targ_short      Vshort;
712         targ_ushort     Vushort;
713         targ_int        Vint;
714         targ_uns        Vuns;
715         targ_long       Vlong;
716         targ_ulong      Vulong;
717         targ_llong      Vllong;
718         targ_ullong     Vullong;
719         Cent            Vcent;
720         targ_float      Vfloat;
721         targ_double     Vdouble;
722         targ_ldouble    Vldouble;
723         Complex_f       Vcfloat;   // 2x float
724         Complex_d       Vcdouble;  // 2x double
725         Complex_ld      Vcldouble; // 2x long double
726         targ_size_t     Vpointer;
727         targ_ptrdiff_t  Vptrdiff;
728         targ_uchar      Vreg;   // register number for OPreg elems
729 
730         // 16 byte vector types
731         targ_float[4]   Vfloat4;   // float[4]
732         targ_double[2]  Vdouble2;  // double[2]
733         targ_schar[16]  Vschar16;  // byte[16]
734         targ_uchar[16]  Vuchar16;  // ubyte[16]
735         targ_short[8]   Vshort8;   // short[8]
736         targ_ushort[8]  Vushort8;  // ushort[8]
737         targ_long[4]    Vlong4;    // int[4]
738         targ_ulong[4]   Vulong4;   // uint[4]
739         targ_llong[2]   Vllong2;   // long[2]
740         targ_ullong[2]  Vullong2;  // ulong[2]
741 
742         // 32 byte vector types
743         targ_float[8]   Vfloat8;   // float[8]
744         targ_double[4]  Vdouble4;  // double[4]
745         targ_schar[32]  Vschar32;  // byte[32]
746         targ_uchar[32]  Vuchar32;  // ubyte[32]
747         targ_short[16]  Vshort16;  // short[16]
748         targ_ushort[16] Vushort16; // ushort[16]
749         targ_long[8]    Vlong8;    // int[8]
750         targ_ulong[8]   Vulong8;   // uint[8]
751         targ_llong[4]   Vllong4;   // long[4]
752         targ_ullong[4]  Vullong4;  // ulong[4]
753 
754         struct                  // 48 bit 386 far pointer
755         {   targ_long   Voff;
756             targ_ushort Vseg;
757         }
758         struct
759         {
760             targ_size_t Voffset;// offset from symbol
761             Symbol *Vsym;       // pointer to symbol table
762             union
763             {
764                 param_t* Vtal;  // template-argument-list for SCfunctempl,
765                                 // used only to transmit it to cpp_overload()
766                 LIST* Erd;      // OPvar: reaching definitions
767             }
768         }
769         struct
770         {
771             targ_size_t Voffset2;// member pointer offset
772             Classsym* Vsym2;    // struct tag
773             elem* ethis;        // OPrelconst: 'this' for member pointer
774         }
775         struct
776         {
777             targ_size_t Voffset3;// offset from string
778             char* Vstring;      // pointer to string (OPstring or OPasm)
779             size_t Vstrlen;     // length of string
780         }
781         struct
782         {
783             elem* E1;           // left child for unary & binary nodes
784             elem* E2;           // right child for binary nodes
785             Symbol* Edtor;      // OPctor: destructor
786         }
787         struct
788         {
789             elem* Eleft2;       // left child for OPddtor
790             void* Edecl;        // VarDeclaration being constructed
791         }                       // OPdctor,OPddtor
792 }                               // variants for each type of elem
793 
794 // Symbols
795 
796 //#ifdef DEBUG
797 //#define IDSYMBOL        IDsymbol,
798 //#else
799 //#define IDSYMBOL
800 //#endif
801 
802 alias SYMFLGS = uint;
803 
804 
805 /**********************************
806  * Storage classes
807  */
808 enum SC : ubyte
809 {
810     unde,           /// undefined
811     auto_,          /// automatic (stack)
812     static_,        /// statically allocated
813     thread,         /// thread local
814     extern_,        /// external
815     register,       /// registered variable
816     pseudo,         /// pseudo register variable
817     global,         /// top level global definition
818     comdat,         /// initialized common block
819     parameter,      /// function parameter
820     regpar,         /// function register parameter
821     fastpar,        /// function parameter passed in register
822     shadowreg,      /// function parameter passed in register, shadowed on stack
823     typedef_,       /// type definition
824     explicit,       /// explicit
825     mutable,        /// mutable
826     label,          /// goto label
827     struct_,        /// struct/class/union tag name
828     enum_,          /// enum tag name
829     field,          /// bit field of struct or union
830     const_,         /// constant integer
831     member,         /// member of struct or union
832     anon,           /// member of anonymous union
833     inline,         /// for inline functions
834     sinline,        /// for static inline functions
835     einline,        /// for extern inline functions
836     overload,       /// for overloaded function names
837     friend,         /// friend of a class
838     virtual,        /// virtual function
839     locstat,        /// static, but local to a function
840     template_,      /// class template
841     functempl,      /// function template
842     ftexpspec,      /// function template explicit specialization
843     linkage,        /// function linkage symbol
844     public_,        /// generate a pubdef for this
845     comdef,         /// uninitialized common block
846     bprel,          /// variable at fixed offset from frame pointer
847     namespace,      /// namespace
848     alias_,         /// alias to another symbol
849     funcalias,      /// alias to another function symbol
850     memalias,       /// alias to base class member
851     stack,          /// offset from stack pointer (not frame pointer)
852     adl,            /// list of ADL symbols for overloading
853 }
854 
855 enum SCMAX = SC.max + 1;
856 
857 int ClassInline(int c) { return c == SC.inline || c == SC.sinline || c == SC.einline; }
858 int SymInline(Symbol* s) { return ClassInline(s.Sclass); }