diff --git a/src/dmd/backend/backconfig.d b/src/dmd/backend/backconfig.d index cf46a0abe3e7..1f0af98576f8 100644 --- a/src/dmd/backend/backconfig.d +++ b/src/dmd/backend/backconfig.d @@ -30,11 +30,31 @@ version (MARS) void ph_init(); } +/// Bit decoding of the TargetOS (copied from `dmd.globals : TargetOS` +enum TargetOS : ubyte +{ + /* These are mutually exclusive; one and only one is set. + * Match spelling and casing of corresponding version identifiers + */ + linux = 1, + Windows = 2, + OSX = 4, + OpenBSD = 8, + FreeBSD = 0x10, + Solaris = 0x20, + DragonFlyBSD = 0x40, + + // Combination masks + all = linux | Windows | OSX | FreeBSD | Solaris | DragonFlyBSD, + Posix = linux | OSX | FreeBSD | Solaris | DragonFlyBSD, +} + /************************************** * Initialize configuration variables. */ extern (C) void out_config_init( + TargetOS target, // Target operating system, matches `dmd.globals : TargetOS` int model, // 32: 32 bit code // 64: 64 bit code // Windows: set bit 0 to generate MS-COFF instead of OMF @@ -74,177 +94,185 @@ version (MARS) tytab[TYchar] |= TYFLuns; bool mscoff = model & 1; model &= 32 | 64; -static if (TARGET_WINDOS) -{ - if (model == 64) - { config.exe = EX_WIN64; - config.fpxmmregs = true; - config.avx = avx; - config.ehmethod = useExceptions ? EHmethod.EH_DM : EHmethod.EH_NONE; - - config.flags |= CFGnoebp; // test suite fails without this - //config.flags |= CFGalwaysframe; - config.flags |= CFGromable; // put switch tables in code segment - config.objfmt = OBJ_MSCOFF; - } - else + if (target == TargetOS.Windows) { - config.exe = EX_WIN32; - config.ehmethod = useExceptions ? EHmethod.EH_WIN32 : EHmethod.EH_NONE; - config.objfmt = mscoff ? OBJ_MSCOFF : OBJ_OMF; - } + if (model == 64) + { + config.exe = EX_WIN64; + config.fpxmmregs = true; + config.avx = avx; + config.ehmethod = useExceptions ? EHmethod.EH_DM : EHmethod.EH_NONE; - if (exe) - config.wflags |= WFexe; // EXE file only optimizations - config.flags4 |= CFG4underscore; -} -static if (TARGET_LINUX) -{ - config.fpxmmregs = true; - config.avx = avx; - if (model == 64) - { config.exe = EX_LINUX64; - config.ehmethod = useExceptions ? EHmethod.EH_DWARF : EHmethod.EH_NONE; - } - else - { - config.exe = EX_LINUX; - config.ehmethod = useExceptions ? EHmethod.EH_DWARF : EHmethod.EH_NONE; - if (!exe) + config.flags |= CFGnoebp; // test suite fails without this + //config.flags |= CFGalwaysframe; config.flags |= CFGromable; // put switch tables in code segment + config.objfmt = OBJ_MSCOFF; + } + else + { + config.exe = EX_WIN32; + config.ehmethod = useExceptions ? EHmethod.EH_WIN32 : EHmethod.EH_NONE; + config.objfmt = mscoff ? OBJ_MSCOFF : OBJ_OMF; + } + + if (exe) + config.wflags |= WFexe; // EXE file only optimizations + config.flags4 |= CFG4underscore; } - config.flags |= CFGnoebp; - switch (pic) + else if (target == TargetOS.linux) { - case 0: // PIC.fixed - break; + config.fpxmmregs = true; + config.avx = avx; + if (model == 64) + { + config.exe = EX_LINUX64; + config.ehmethod = useExceptions ? EHmethod.EH_DWARF : EHmethod.EH_NONE; + } + else + { + config.exe = EX_LINUX; + config.ehmethod = useExceptions ? EHmethod.EH_DWARF : EHmethod.EH_NONE; + if (!exe) + config.flags |= CFGromable; // put switch tables in code segment + } + config.flags |= CFGnoebp; + switch (pic) + { + case 0: // PIC.fixed + break; - case 1: // PIC.pic - config.flags3 |= CFG3pic; - break; + case 1: // PIC.pic + config.flags3 |= CFG3pic; + break; - case 2: // PIC.pie - config.flags3 |= CFG3pic | CFG3pie; - break; + case 2: // PIC.pie + config.flags3 |= CFG3pic | CFG3pie; + break; - default: - assert(0); - } - if (symdebug) - config.flags |= CFGalwaysframe; + default: + assert(0); + } + if (symdebug) + config.flags |= CFGalwaysframe; - config.objfmt = OBJ_ELF; -} -static if (TARGET_OSX) -{ - config.fpxmmregs = true; - config.avx = avx; - if (model == 64) - { config.exe = EX_OSX64; - config.ehmethod = useExceptions ? EHmethod.EH_DWARF : EHmethod.EH_NONE; - } - else - { - config.exe = EX_OSX; - config.ehmethod = useExceptions ? EHmethod.EH_DWARF : EHmethod.EH_NONE; + config.objfmt = OBJ_ELF; } - config.flags |= CFGnoebp; - if (!exe) + else if (target == TargetOS.OSX) { - config.flags3 |= CFG3pic; - if (model == 64) - config.flags |= CFGalwaysframe; // autotester fails without this - // https://issues.dlang.org/show_bug.cgi?id=21042 - } - if (symdebug) - config.flags |= CFGalwaysframe; - config.flags |= CFGromable; // put switch tables in code segment - config.objfmt = OBJ_MACH; -} -static if (TARGET_FREEBSD) -{ - if (model == 64) - { config.exe = EX_FREEBSD64; - config.ehmethod = useExceptions ? EHmethod.EH_DWARF : EHmethod.EH_NONE; config.fpxmmregs = true; config.avx = avx; + if (model == 64) + { + config.exe = EX_OSX64; + config.ehmethod = useExceptions ? EHmethod.EH_DWARF : EHmethod.EH_NONE; + } + else + { + config.exe = EX_OSX; + config.ehmethod = useExceptions ? EHmethod.EH_DWARF : EHmethod.EH_NONE; + } + config.flags |= CFGnoebp; + if (!exe) + { + config.flags3 |= CFG3pic; + if (model == 64) + config.flags |= CFGalwaysframe; // autotester fails without this + // https://issues.dlang.org/show_bug.cgi?id=21042 + } + if (symdebug) + config.flags |= CFGalwaysframe; + config.flags |= CFGromable; // put switch tables in code segment + config.objfmt = OBJ_MACH; } - else + else if (target == TargetOS.FreeBSD) { - config.exe = EX_FREEBSD; - config.ehmethod = useExceptions ? EHmethod.EH_DWARF : EHmethod.EH_NONE; + if (model == 64) + { + config.exe = EX_FREEBSD64; + config.ehmethod = useExceptions ? EHmethod.EH_DWARF : EHmethod.EH_NONE; + config.fpxmmregs = true; + config.avx = avx; + } + else + { + config.exe = EX_FREEBSD; + config.ehmethod = useExceptions ? EHmethod.EH_DWARF : EHmethod.EH_NONE; + if (!exe) + config.flags |= CFGromable; // put switch tables in code segment + } + config.flags |= CFGnoebp; if (!exe) - config.flags |= CFGromable; // put switch tables in code segment + { + config.flags3 |= CFG3pic; + } + if (symdebug) + config.flags |= CFGalwaysframe; + config.objfmt = OBJ_ELF; } - config.flags |= CFGnoebp; - if (!exe) + else if (target == TargetOS.OpenBSD) { - config.flags3 |= CFG3pic; - } - if (symdebug) + if (model == 64) + { + config.exe = EX_OPENBSD64; + config.fpxmmregs = true; + config.avx = avx; + } + else + { + config.exe = EX_OPENBSD; + if (!exe) + config.flags |= CFGromable; // put switch tables in code segment + } + config.flags |= CFGnoebp; config.flags |= CFGalwaysframe; - config.objfmt = OBJ_ELF; -} -static if (TARGET_OPENBSD) -{ - if (model == 64) - { config.exe = EX_OPENBSD64; - config.fpxmmregs = true; - config.avx = avx; - } - else - { - config.exe = EX_OPENBSD; if (!exe) - config.flags |= CFGromable; // put switch tables in code segment - } - config.flags |= CFGnoebp; - config.flags |= CFGalwaysframe; - if (!exe) - config.flags3 |= CFG3pic; - config.objfmt = OBJ_ELF; - config.ehmethod = useExceptions ? EHmethod.EH_DM : EHmethod.EH_NONE; -} -static if (TARGET_DRAGONFLYBSD) -{ - if (model == 64) - { config.exe = EX_DRAGONFLYBSD64; - config.ehmethod = useExceptions ? EHmethod.EH_DWARF : EHmethod.EH_NONE; - config.fpxmmregs = true; - config.avx = avx; - } - else - { - assert(0); // Only 64-bit supported on DragonFlyBSD + config.flags3 |= CFG3pic; + config.objfmt = OBJ_ELF; + config.ehmethod = useExceptions ? EHmethod.EH_DM : EHmethod.EH_NONE; } - config.flags |= CFGnoebp; - if (!exe) + else if (target == TargetOS.DragonFlyBSD) { - config.flags3 |= CFG3pic; - config.flags |= CFGalwaysframe; // PIC needs a frame for TLS fixups - } - config.objfmt = OBJ_ELF; -} -static if (TARGET_SOLARIS) -{ - if (model == 64) - { config.exe = EX_SOLARIS64; - config.fpxmmregs = true; - config.avx = avx; + if (model == 64) + { + config.exe = EX_DRAGONFLYBSD64; + config.ehmethod = useExceptions ? EHmethod.EH_DWARF : EHmethod.EH_NONE; + config.fpxmmregs = true; + config.avx = avx; + } + else + { + assert(0); // Only 64-bit supported on DragonFlyBSD + } + config.flags |= CFGnoebp; + if (!exe) + { + config.flags3 |= CFG3pic; + config.flags |= CFGalwaysframe; // PIC needs a frame for TLS fixups + } + config.objfmt = OBJ_ELF; } - else + else if (target == TargetOS.Solaris) { - config.exe = EX_SOLARIS; + if (model == 64) + { + config.exe = EX_SOLARIS64; + config.fpxmmregs = true; + config.avx = avx; + } + else + { + config.exe = EX_SOLARIS; + if (!exe) + config.flags |= CFGromable; // put switch tables in code segment + } + config.flags |= CFGnoebp; + config.flags |= CFGalwaysframe; if (!exe) - config.flags |= CFGromable; // put switch tables in code segment + config.flags3 |= CFG3pic; + config.objfmt = OBJ_ELF; + config.ehmethod = useExceptions ? EHmethod.EH_DM : EHmethod.EH_NONE; } - config.flags |= CFGnoebp; - config.flags |= CFGalwaysframe; - if (!exe) - config.flags3 |= CFG3pic; - config.objfmt = OBJ_ELF; - config.ehmethod = useExceptions ? EHmethod.EH_DM : EHmethod.EH_NONE; -} + config.flags2 |= CFG2nodeflib; // no default library config.flags3 |= CFG3eseqds; static if (0) @@ -254,13 +282,10 @@ static if (0) if (env.nochecks()) config.flags4 |= CFG4nochecks; // no runtime checking } -else static if (TARGET_OSX) -{ -} -else -{ - config.flags4 |= CFG4allcomdat; -} + + if (target != TargetOS.OSX) + config.flags4 |= CFG4allcomdat; + if (trace) config.flags |= CFGtrace; // turn on profiler if (nofloat) @@ -316,15 +341,14 @@ static if (SYMDEB_CODEVIEW) block_init(); cod3_setdefault(); + util_set(model == 64, target); if (model == 64) { - util_set64(); type_init(); cod3_set64(); } else { - util_set32(); type_init(); cod3_set32(); } @@ -360,26 +384,11 @@ void out_config_debug( } -/************************************* - */ - -void util_set16() -{ - // The default is 16 bits - _tysize[TYldouble] = 10; - _tysize[TYildouble] = 10; - _tysize[TYcldouble] = 20; - - _tyalignsize[TYldouble] = 2; - _tyalignsize[TYildouble] = 2; - _tyalignsize[TYcldouble] = 2; -} - /******************************* - * Redo tables from 8086/286 to 386/486. + * Redo tables from 8086/286 to 386/486 or I64 */ -void util_set32() +void util_set(bool is64Bits, TargetOS target) { _tyrelax[TYenum] = TYlong; _tyrelax[TYint] = TYlong; @@ -391,162 +400,71 @@ void util_set32() _tysize[TYenum] = LONGSIZE; _tysize[TYint ] = LONGSIZE; _tysize[TYuint] = LONGSIZE; - _tysize[TYnullptr] = LONGSIZE; - _tysize[TYnptr] = LONGSIZE; - _tysize[TYnref] = LONGSIZE; -static if (TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_DRAGONFLYBSD || TARGET_SOLARIS) -{ - _tysize[TYldouble] = 12; - _tysize[TYildouble] = 12; - _tysize[TYcldouble] = 24; -} -else static if (TARGET_OSX) -{ - _tysize[TYldouble] = 16; - _tysize[TYildouble] = 16; - _tysize[TYcldouble] = 32; -} -else static if (TARGET_WINDOS) -{ - _tysize[TYldouble] = 10; - _tysize[TYildouble] = 10; - _tysize[TYcldouble] = 20; -} -else -{ - assert(0); -} - _tysize[TYsptr] = LONGSIZE; - _tysize[TYcptr] = LONGSIZE; - _tysize[TYfptr] = 6; // NOTE: There are codgen test that check - _tysize[TYvptr] = 6; // _tysize[x] == _tysize[TYfptr] so don't set - _tysize[TYfref] = 6; // _tysize[TYfptr] to _tysize[TYnptr] + + _tysize[TYnullptr] = is64Bits ? 8 : LONGSIZE; + _tysize[TYnptr] = is64Bits ? 8 : LONGSIZE; + _tysize[TYnref] = is64Bits ? 8 : LONGSIZE; + + if (target & TargetOS.Posix) + { + _tysize[TYldouble] = is64Bits ? 16 : 12; + _tysize[TYildouble] = is64Bits ? 16 : 12; + _tysize[TYcldouble] = is64Bits ? 32 : 24; + } + else if (target == TargetOS.Windows) + { + _tysize[TYldouble] = 10; + _tysize[TYildouble] = 10; + _tysize[TYcldouble] = 20; + } + else + assert(0); + + _tysize[TYsptr] = is64Bits ? 8 : LONGSIZE; + _tysize[TYcptr] = is64Bits ? 8 : LONGSIZE; + _tysize[TYfptr] = is64Bits ? 10 : 6; // NOTE: There are codgen test that check + _tysize[TYvptr] = is64Bits ? 10 : 6; // _tysize[x] == _tysize[TYfptr] so don't set + _tysize[TYfref] = is64Bits ? 10 : 6; // _tysize[TYfptr] to _tysize[TYnptr] _tyalignsize[TYenum] = LONGSIZE; _tyalignsize[TYint ] = LONGSIZE; _tyalignsize[TYuint] = LONGSIZE; - _tyalignsize[TYnullptr] = LONGSIZE; - _tyalignsize[TYnref] = LONGSIZE; - _tyalignsize[TYnptr] = LONGSIZE; -static if (TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_DRAGONFLYBSD || TARGET_SOLARIS) -{ - _tyalignsize[TYldouble] = 4; - _tyalignsize[TYildouble] = 4; - _tyalignsize[TYcldouble] = 4; -} -else static if (TARGET_OSX) -{ - _tyalignsize[TYldouble] = 16; - _tyalignsize[TYildouble] = 16; - _tyalignsize[TYcldouble] = 16; -} -else static if (TARGET_WINDOS) -{ - _tyalignsize[TYldouble] = 2; - _tyalignsize[TYildouble] = 2; - _tyalignsize[TYcldouble] = 2; -} -else -{ - assert(0); -} - _tyalignsize[TYsptr] = LONGSIZE; - _tyalignsize[TYcptr] = LONGSIZE; - _tyalignsize[TYfptr] = LONGSIZE; // NOTE: There are codgen test that check - _tyalignsize[TYvptr] = LONGSIZE; // _tysize[x] == _tysize[TYfptr] so don't set - _tyalignsize[TYfref] = LONGSIZE; // _tysize[TYfptr] to _tysize[TYnptr] - _tysize[TYimmutPtr] = _tysize[TYnptr]; - _tysize[TYsharePtr] = _tysize[TYnptr]; - _tysize[TYrestrictPtr] = _tysize[TYnptr]; - _tysize[TYfgPtr] = _tysize[TYnptr]; - _tyalignsize[TYimmutPtr] = _tyalignsize[TYnptr]; - _tyalignsize[TYsharePtr] = _tyalignsize[TYnptr]; - _tyalignsize[TYrestrictPtr] = _tyalignsize[TYnptr]; - _tyalignsize[TYfgPtr] = _tyalignsize[TYnptr]; -} + _tyalignsize[TYnullptr] = is64Bits ? 8 : LONGSIZE; + _tyalignsize[TYnptr] = is64Bits ? 8 : LONGSIZE; + _tyalignsize[TYnref] = is64Bits ? 8 : LONGSIZE; -/******************************* - * Redo tables from 8086/286 to I64. - */ - -void util_set64() -{ - _tyrelax[TYenum] = TYlong; - _tyrelax[TYint] = TYlong; - _tyrelax[TYuint] = TYlong; + if (target & TargetOS.Posix) + { + _tyalignsize[TYldouble] = is64Bits ? 16 : 4; + _tyalignsize[TYildouble] = is64Bits ? 16 : 4; + _tyalignsize[TYcldouble] = is64Bits ? 16 : 4; + } + else if (target == TargetOS.Windows) + { + _tyalignsize[TYldouble] = 2; + _tyalignsize[TYildouble] = 2; + _tyalignsize[TYcldouble] = 2; + } + else + assert(0); - tyequiv[TYint] = TYlong; - tyequiv[TYuint] = TYulong; + _tyalignsize[TYsptr] = is64Bits ? 8 : LONGSIZE; + _tyalignsize[TYcptr] = is64Bits ? 8 : LONGSIZE; + _tyalignsize[TYfptr] = is64Bits ? 8 : LONGSIZE; // NOTE: There are codgen test that check + _tyalignsize[TYvptr] = is64Bits ? 8 : LONGSIZE; // _tysize[x] == _tysize[TYfptr] so don't set + _tyalignsize[TYfref] = is64Bits ? 8 : LONGSIZE; // _tysize[TYfptr] to _tysize[TYnptr] - _tysize[TYenum] = LONGSIZE; - _tysize[TYint ] = LONGSIZE; - _tysize[TYuint] = LONGSIZE; - _tysize[TYnullptr] = 8; - _tysize[TYnptr] = 8; - _tysize[TYnref] = 8; -static if (TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_DRAGONFLYBSD || TARGET_SOLARIS || TARGET_OSX) -{ - _tysize[TYldouble] = 16; - _tysize[TYildouble] = 16; - _tysize[TYcldouble] = 32; -} -else static if (TARGET_WINDOS) -{ - _tysize[TYldouble] = 10; - _tysize[TYildouble] = 10; - _tysize[TYcldouble] = 20; -} -else -{ - assert(0); -} - _tysize[TYsptr] = 8; - _tysize[TYcptr] = 8; - _tysize[TYfptr] = 10; // NOTE: There are codgen test that check - _tysize[TYvptr] = 10; // _tysize[x] == _tysize[TYfptr] so don't set - _tysize[TYfref] = 10; // _tysize[TYfptr] to _tysize[TYnptr] + if (is64Bits) + { + tytab[TYjfunc] &= ~TYFLpascal; // set so caller cleans the stack (as in C) - _tyalignsize[TYenum] = LONGSIZE; - _tyalignsize[TYint ] = LONGSIZE; - _tyalignsize[TYuint] = LONGSIZE; - _tyalignsize[TYnullptr] = 8; - _tyalignsize[TYnptr] = 8; - _tyalignsize[TYnref] = 8; -static if (TARGET_LINUX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_DRAGONFLYBSD || TARGET_SOLARIS) -{ - _tyalignsize[TYldouble] = 16; - _tyalignsize[TYildouble] = 16; - _tyalignsize[TYcldouble] = 16; -} -else static if (TARGET_OSX) -{ - _tyalignsize[TYldouble] = 16; - _tyalignsize[TYildouble] = 16; - _tyalignsize[TYcldouble] = 16; -} -else static if (TARGET_WINDOS) -{ - _tyalignsize[TYldouble] = 2; - _tyalignsize[TYildouble] = 2; - _tyalignsize[TYcldouble] = 2; -} -else -{ - assert(0); -} - _tyalignsize[TYsptr] = 8; - _tyalignsize[TYcptr] = 8; - _tyalignsize[TYfptr] = 8; - _tyalignsize[TYvptr] = 8; - _tyalignsize[TYfref] = 8; - tytab[TYjfunc] &= ~TYFLpascal; // set so caller cleans the stack (as in C) - - TYptrdiff = TYllong; - TYsize = TYullong; - TYsize_t = TYullong; - TYdelegate = TYcent; - TYdarray = TYucent; + TYptrdiff = TYllong; + TYsize = TYullong; + TYsize_t = TYullong; + TYdelegate = TYcent; + TYdarray = TYucent; + } _tysize[TYimmutPtr] = _tysize[TYnptr]; _tysize[TYsharePtr] = _tysize[TYnptr]; @@ -557,4 +475,3 @@ else _tyalignsize[TYrestrictPtr] = _tyalignsize[TYnptr]; _tyalignsize[TYfgPtr] = _tyalignsize[TYnptr]; } - diff --git a/src/dmd/backend/global.d b/src/dmd/backend/global.d index 946e6386909d..a2714865ec9c 100644 --- a/src/dmd/backend/global.d +++ b/src/dmd/backend/global.d @@ -133,9 +133,6 @@ void util_assert(const(char)*, int); //#endif void util_progress(); -void util_set16(); -void util_set32(); -void util_set64(); int ispow2(uint64_t); version (Posix) diff --git a/src/dmd/dmsc.d b/src/dmd/dmsc.d index 79d72a95436b..9271f50bb9c1 100644 --- a/src/dmd/dmsc.d +++ b/src/dmd/dmsc.d @@ -32,6 +32,7 @@ import dmd.backend.ty; import dmd.backend.type; extern (C) void out_config_init( + TargetOS target, // Target operating system, matches `dmd.globals : TargetOS` int model, // 32: 32 bit code // 64: 64 bit code // Windows: bit 0 set to generate MS-COFF instead of OMF @@ -87,6 +88,7 @@ void backend_init() exe = true; // if writing out EXE file out_config_init( + params.targetOS, (params.is64bit ? 64 : 32) | (params.mscoff ? 1 : 0), exe, false, //params.trace,