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); }