1 /**
2  * Configures and initializes the backend.
3  *
4  * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
5  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
6  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/dmsc.d, _dmsc.d)
8  * Documentation:  https://dlang.org/phobos/dmd_dmsc.html
9  * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/dmsc.d
10  */
11 
12 module dmd.dmsc;
13 
14 import core.stdc.stdio;
15 import core.stdc.string;
16 import core.stdc.stddef;
17 
18 extern (C++):
19 
20 import dmd.globals;
21 import dmd.dclass;
22 import dmd.dmdparams;
23 import dmd.dmodule;
24 import dmd.mtype;
25 import dmd.target;
26 
27 import dmd.root.filename;
28 
29 import dmd.backend.cc;
30 import dmd.backend.cdef;
31 import dmd.backend.global;
32 import dmd.backend.ty;
33 import dmd.backend.type;
34 
35 extern (C) void out_config_init(
36         int model,      // 32: 32 bit code
37                         // 64: 64 bit code
38                         // Windows: bit 0 set to generate MS-COFF instead of OMF
39         bool exe,       // true: exe file
40                         // false: dll or shared library (generate PIC code)
41         bool trace,     // add profiling code
42         bool nofloat,   // do not pull in floating point code
43         bool vasm,      // print generated assembler for each function
44         bool verbose,   // verbose compile
45         bool optimize,  // optimize code
46         int symdebug,   // add symbolic debug information
47                         // 1: D
48                         // 2: fake it with C symbolic debug info
49         bool alwaysframe,       // always create standard function frame
50         bool stackstomp,        // add stack stomping code
51         ubyte avx,              // use AVX instruction set (0, 1, 2)
52         PIC pic,                // kind of position independent code
53         bool useModuleInfo,     // implement ModuleInfo
54         bool useTypeInfo,       // implement TypeInfo
55         bool useExceptions,     // implement exception handling
56         ubyte dwarf,            // DWARF version used
57         string _version,        // Compiler version
58         exefmt_t exefmt,        // Executable file format
59         bool generatedMain      // a main entrypoint is generated
60         );
61 
62 void out_config_debug(
63         bool debugb,
64         bool debugc,
65         bool debugf,
66         bool debugr,
67         bool debugw,
68         bool debugx,
69         bool debugy
70     );
71 
72 /**************************************
73  * Initialize config variables.
74  */
75 
76 void backend_init()
77 {
78     //printf("out_config_init()\n");
79     Param *params = &global.params;
80     exefmt_t exfmt;
81     switch (target.os)
82     {
83         case Target.OS.Windows: exfmt = target.is64bit ? EX_WIN64 : EX_WIN32;       break;
84         case Target.OS.linux:   exfmt = target.is64bit ? EX_LINUX64 : EX_LINUX;     break;
85         case Target.OS.OSX:     exfmt = target.is64bit ? EX_OSX64 : EX_OSX;         break;
86         case Target.OS.FreeBSD: exfmt = target.is64bit ? EX_FREEBSD64 : EX_FREEBSD; break;
87         case Target.OS.OpenBSD: exfmt = target.is64bit ? EX_OPENBSD64 : EX_OPENBSD; break;
88         case Target.OS.Solaris: exfmt = target.is64bit ? EX_SOLARIS64 : EX_SOLARIS; break;
89         case Target.OS.DragonFlyBSD: exfmt = EX_DRAGONFLYBSD64; break;
90         default: assert(0);
91     }
92 
93     bool exe;
94     if (driverParams.dll || driverParams.pic != PIC.fixed)
95     {
96     }
97     else if (params.run)
98         exe = true;         // EXE file only optimizations
99     else if (driverParams.link && !params.deffile)
100         exe = true;         // EXE file only optimizations
101     else if (params.exefile.length &&
102              params.exefile.length >= 4 &&
103              FileName.equals(FileName.ext(params.exefile), "exe"))
104         exe = true;         // if writing out EXE file
105 
106     out_config_init(
107         (target.is64bit ? 64 : 32) | (target.objectFormat() == Target.ObjectFormat.coff ? 1 : 0),
108         exe,
109         false, //params.trace,
110         driverParams.nofloat,
111         driverParams.vasm,
112         params.verbose,
113         driverParams.optimize,
114         driverParams.symdebug,
115         driverParams.alwaysframe,
116         driverParams.stackstomp,
117         target.cpu >= CPU.avx2 ? 2 : target.cpu >= CPU.avx ? 1 : 0,
118         driverParams.pic,
119         params.useModuleInfo && Module.moduleinfo,
120         params.useTypeInfo && Type.dtypeinfo,
121         params.useExceptions && ClassDeclaration.throwable,
122         driverParams.dwarf,
123         global.versionString(),
124         exfmt,
125         params.addMain
126     );
127 
128     out_config_debug(
129         driverParams.debugb,
130         driverParams.debugc,
131         driverParams.debugf,
132         driverParams.debugr,
133         false,
134         driverParams.debugx,
135         driverParams.debugy
136     );
137 }
138 
139 
140 /***********************************
141  * Return aligned 'offset' if it is of size 'size'.
142  */
143 
144 targ_size_t _align(targ_size_t size, targ_size_t offset)
145 {
146     switch (size)
147     {
148         case 1:
149             break;
150         case 2:
151         case 4:
152         case 8:
153         case 16:
154         case 32:
155         case 64:
156             offset = (offset + size - 1) & ~(size - 1);
157             break;
158         default:
159             if (size >= 16)
160                 offset = (offset + 15) & ~15;
161             else
162                 offset = (offset + _tysize[TYnptr] - 1) & ~(_tysize[TYnptr] - 1);
163             break;
164     }
165     return offset;
166 }
167 
168 
169 /*******************************
170  * Get size of ty
171  */
172 
173 targ_size_t size(tym_t ty)
174 {
175     int sz = (tybasic(ty) == TYvoid) ? 1 : tysize(ty);
176     debug
177     {
178         if (sz == -1)
179             printf("ty: %s\n", tym_str(ty));
180     }
181     assert(sz!= -1);
182     return sz;
183 }
184 
185 /****************************
186  * Generate symbol of type ty at DATA:offset
187  */
188 
189 Symbol *symboldata(targ_size_t offset,tym_t ty)
190 {
191     Symbol *s = symbol_generate(SC.locstat, type_fake(ty));
192     s.Sfl = FLdata;
193     s.Soffset = offset;
194     s.Stype.Tmangle = mTYman_sys; // writes symbol unmodified in Obj::mangle
195     symbol_keep(s);               // keep around
196     return s;
197 }
198 
199 /**************************************
200  */
201 
202 void backend_term()
203 {
204 }