root/trunk/src/msc.c

Revision 768, 9.9 kB (checked in by walter, 1 year ago)

more 64

  • Property svn:eol-style set to native
Line 
1 // Compiler implementation of the D programming language
2 // Copyright (c) 1999-2010 by Digital Mars
3 // All Rights Reserved
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
9
10 #include        <stdio.h>
11 #include        <string.h>
12 #include        <stddef.h>
13
14 #include        "mars.h"
15
16 #include        "cc.h"
17 #include        "global.h"
18 #include        "parser.h"
19 #include        "oper.h"
20 #include        "code.h"
21 #include        "type.h"
22 #include        "dt.h"
23 #include        "cgcv.h"
24
25 static char __file__[] = __FILE__;      /* for tassert.h                */
26 #include        "tassert.h"
27
28 extern Global global;
29 extern int REALSIZE;
30
31 Config config;
32 Configv configv;
33
34 struct Environment;
35
36 /**************************************
37  * Initialize config variables.
38  */
39
40 void out_config_init()
41 {
42     //printf("out_config_init()\n");
43     Param *params = &global.params;
44
45     if (!config.target_cpu)
46     {   config.target_cpu = TARGET_PentiumPro;
47         config.target_scheduler = config.target_cpu;
48     }
49     config.fulltypes = CVNONE;
50     config.inline8087 = 1;
51     config.memmodel = 0;
52     config.flags |= CFGuchar;   // make sure TYchar is unsigned
53 #if TARGET_WINDOS
54     if (params->isX86_64)
55         config.exe = EX_WIN64;
56     else
57         config.exe = EX_NT;
58
59     // Win32 eh
60     config.flags2 |= CFG2seh;
61
62     if (params->run)
63         config.wflags |= WFexe;         // EXE file only optimizations
64     else if (params->link && !global.params.deffile)
65         config.wflags |= WFexe;         // EXE file only optimizations
66     else if (params->exefile)           // if writing out EXE file
67     {   size_t len = strlen(params->exefile);
68         if (len >= 4 && stricmp(params->exefile + len - 3, "exe") == 0)
69             config.wflags |= WFexe;
70     }
71     config.flags4 |= CFG4underscore;
72 #endif
73 #if TARGET_LINUX
74     if (params->isX86_64)
75         config.exe = EX_LINUX64;
76     else
77         config.exe = EX_LINUX;
78     config.flags |= CFGnoebp;
79     config.flags |= CFGalwaysframe;
80     if (params->pic)
81         config.flags3 |= CFG3pic;
82 #endif
83 #if TARGET_OSX
84     if (params->isX86_64)
85         config.exe = EX_OSX64;
86     else
87         config.exe = EX_OSX;
88     config.flags |= CFGnoebp;
89     config.flags |= CFGalwaysframe;
90     if (params->pic)
91         config.flags3 |= CFG3pic;
92 #endif
93 #if TARGET_FREEBSD
94     if (params->isX86_64)
95         config.exe = EX_FREEBSD64;
96     else
97         config.exe = EX_FREEBSD;
98     config.flags |= CFGnoebp;
99     config.flags |= CFGalwaysframe;
100     if (params->pic)
101         config.flags3 |= CFG3pic;
102 #endif
103 #if TARGET_SOLARIS
104     if (params->isX86_64)
105         config.exe = EX_SOLARIS64;
106     else
107         config.exe = EX_SOLARIS;
108     config.flags |= CFGnoebp;
109     config.flags |= CFGalwaysframe;
110     if (params->pic)
111         config.flags3 |= CFG3pic;
112 #endif
113     config.flags2 |= CFG2nodeflib;      // no default library
114     config.flags3 |= CFG3eseqds;
115 #if 0
116     if (env->getEEcontext()->EEcompile != 2)
117         config.flags4 |= CFG4allcomdat;
118     if (env->nochecks())
119         config.flags4 |= CFG4nochecks;  // no runtime checking
120 #elif TARGET_OSX
121 #else
122     config.flags4 |= CFG4allcomdat;
123 #endif
124     if (params->trace)
125         config.flags |= CFGtrace;       // turn on profiler
126     if (params->nofloat)
127         config.flags3 |= CFG3wkfloat;
128
129     configv.verbose = params->verbose;
130
131     if (params->optimize)
132         go_flag((char *)"-o");
133
134     if (params->symdebug)
135     {
136 #if ELFOBJ || MACHOBJ
137         configv.addlinenumbers = 1;
138         config.fulltypes = (params->symdebug == 1) ? CVDWARF_D : CVDWARF_C;
139 #endif
140 #if OMFOBJ
141         configv.addlinenumbers = 1;
142         config.fulltypes = CV4;
143 #endif
144         if (!params->optimize)
145             config.flags |= CFGalwaysframe;
146     }
147     else
148     {
149         configv.addlinenumbers = 0;
150         config.fulltypes = CVNONE;
151         //config.flags &= ~CFGalwaysframe;
152     }
153
154     if (params->isX86_64)
155     {
156         util_set64();
157         cod3_set64();
158     }
159     else
160     {
161         util_set386();
162         cod3_set386();
163     }
164
165     rtlsym_init();
166
167 #ifdef DEBUG
168     debugb = params->debugb;
169     debugc = params->debugc;
170     debugf = params->debugf;
171     debugr = params->debugr;
172     debugw = params->debugw;
173     debugx = params->debugx;
174     debugy = params->debugy;
175 #endif
176 }
177
178 /*******************************
179  * Redo tables from 8086/286 to 386/486.
180  */
181
182 void util_set386()
183 {   int i;
184
185 //    if (I32)
186     {
187         _tyrelax[TYenum] = TYlong;
188         _tyrelax[TYint]  = TYlong;
189         _tyrelax[TYuint] = TYlong;
190
191         tyequiv[TYint] = TYlong;
192         tyequiv[TYuint] = TYulong;
193
194         for (i = 0; i < 0x100; i += 0x40)
195         {   tysize[TYenum + i] = LONGSIZE;
196             tysize[TYint  + i] = LONGSIZE;
197             tysize[TYuint + i] = LONGSIZE;
198             tysize[TYjhandle + i] = LONGSIZE;
199             tysize[TYnptr + i] = LONGSIZE;
200             tysize[TYsptr + i] = LONGSIZE;
201             tysize[TYcptr + i] = LONGSIZE;
202             tysize[TYnref + i] = LONGSIZE;
203             tysize[TYfptr + i] = 6;
204             tysize[TYvptr + i] = 6;
205             tysize[TYfref + i] = 6;
206         }
207
208         for (i = 0; i < 0x100; i += 0x40)
209         {   tyalignsize[TYenum + i] = LONGSIZE;
210             tyalignsize[TYint  + i] = LONGSIZE;
211             tyalignsize[TYuint + i] = LONGSIZE;
212             tyalignsize[TYnullptr + i] = LONGSIZE;
213             tyalignsize[TYnptr + i] = LONGSIZE;
214             tyalignsize[TYsptr + i] = LONGSIZE;
215             tyalignsize[TYcptr + i] = LONGSIZE;
216             tyalignsize[TYnref + i] = LONGSIZE;
217         }
218     }
219 }
220
221 /*******************************
222  * Redo tables from 8086/286 to I64.
223  */
224
225 void util_set64()
226 {   int i;
227
228     {
229         _tyrelax[TYenum] = TYlong;
230         _tyrelax[TYint]  = TYlong;
231         _tyrelax[TYuint] = TYlong;
232
233         tyequiv[TYint] = TYlong;
234         tyequiv[TYuint] = TYulong;
235
236         for (i = 0; i < 0x100; i += 0x40)
237         {   tysize[TYenum + i] = LONGSIZE;
238             tysize[TYint  + i] = LONGSIZE;
239             tysize[TYuint + i] = LONGSIZE;
240             tysize[TYnptr + i] = 8;
241             tysize[TYsptr + i] = 8;
242             tysize[TYcptr + i] = 8;
243             tysize[TYnref + i] = 8;
244             tysize[TYfptr + i] = 10;    // NOTE: There are codgen test that check
245             tysize[TYvptr + i] = 10;    // tysize[x] == tysize[TYfptr] so don't set
246             tysize[TYfref + i] = 10;    // tysize[TYfptr] to tysize[TYnptr]
247             tysize[TYldouble + i] = REALSIZE;
248             tysize[TYildouble + i] = REALSIZE;
249             tysize[TYcldouble + i] = 2 * REALSIZE;
250
251             tyalignsize[TYenum + i] = LONGSIZE;
252             tyalignsize[TYint  + i] = LONGSIZE;
253             tyalignsize[TYuint + i] = LONGSIZE;
254             tyalignsize[TYnullptr + i] = 8;
255             tyalignsize[TYnptr + i] = 8;
256             tyalignsize[TYsptr + i] = 8;
257             tyalignsize[TYcptr + i] = 8;
258             tyalignsize[TYnref + i] = 8;
259             tyalignsize[TYfptr + i] = 8;
260             tyalignsize[TYvptr + i] = 8;
261             tyalignsize[TYfref + i] = 8;
262 #if TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS
263             tyalignsize[TYldouble + i] = 16;
264             tyalignsize[TYildouble + i] = 16;
265             tyalignsize[TYcldouble + i] = 16;
266 #else
267             assert(0);
268 #endif
269             tytab[TYjfunc + i] &= ~TYFLpascal;  // set so caller cleans the stack (as in C)
270         }
271     }
272
273     TYptrdiff = TYllong;
274     TYsize = TYullong;
275     TYsize_t = TYullong;
276 }
277
278 /***********************************
279  * Return aligned 'offset' if it is of size 'size'.
280  */
281
282 targ_size_t align(targ_size_t size, targ_size_t offset)
283 {
284     switch (size)
285     {
286         case 1:
287             break;
288         case 2:
289         case 4:
290         case 8:
291             offset = (offset + size - 1) & ~(size - 1);
292             break;
293         default:
294             if (size >= 16)
295                 offset = (offset + 15) & ~15;
296             else
297                 offset = (offset + REGSIZE - 1) & ~(REGSIZE - 1);
298             break;
299     }
300     return offset;
301 }
302
303 /*******************************
304  * Get size of ty
305  */
306
307 targ_size_t size(tym_t ty)
308 {
309     int sz = (tybasic(ty) == TYvoid) ? 1 : tysize(ty);
310 #ifdef DEBUG
311     if (sz == -1)
312         WRTYxx(ty);
313 #endif
314     assert(sz!= -1);
315     return sz;
316 }
317
318 /*******************************
319  * Replace (e) with ((stmp = e),stmp)
320  */
321
322 elem *exp2_copytotemp(elem *e)
323 {
324     //printf("exp2_copytotemp()\n");
325     elem_debug(e);
326     Symbol *stmp = symbol_genauto(e);
327     elem *eeq = el_bin(OPeq,e->Ety,el_var(stmp),e);
328     elem *er = el_bin(OPcomma,e->Ety,eeq,el_var(stmp));
329     if (tybasic(e->Ety) == TYstruct || tybasic(e->Ety) == TYarray)
330     {
331         eeq->Eoper = OPstreq;
332         eeq->ET = e->ET;
333         eeq->E1->ET = e->ET;
334         er->ET = e->ET;
335         er->E2->ET = e->ET;
336     }
337     return er;
338 }
339
340 /****************************
341  * Generate symbol of type ty at DATA:offset
342  */
343
344 symbol *symboldata(targ_size_t offset,tym_t ty)
345 {
346     symbol *s = symbol_generate(SClocstat, type_fake(ty));
347     s->Sfl = FLdata;
348     s->Soffset = offset;
349     s->Sseg = DATA;
350     symbol_keep(s);             // keep around
351     return s;
352 }
353
354 /************************************
355  * Add symbol to slist.
356  */
357
358 static list_t slist;
359
360 void slist_add(Symbol *s)
361 {
362     list_prepend(&slist,s);
363 }
364
365 /*************************************
366  */
367
368 void slist_reset()
369 {
370     //printf("slist_reset()\n");
371     for (list_t sl = slist; sl; sl = list_next(sl))
372     {   Symbol *s = list_symbol(sl);
373
374 #if MACHOBJ
375         s->Soffset = 0;
376 #endif
377         s->Sxtrnnum = 0;
378         s->Stypidx = 0;
379         s->Sflags &= ~(STRoutdef | SFLweak);
380         if (s->Sclass == SCglobal || s->Sclass == SCcomdat ||
381             s->Sfl == FLudata || s->Sclass == SCstatic)
382         {   s->Sclass = SCextern;
383             s->Sfl = FLextern;
384         }
385     }
386 }
387
388
389 /**************************************
390  */
391
392 void backend_init()
393 {
394     ph_init();
395     block_init();
396     type_init();
397
398     fregsaved = I64 ? mBP | mBX | mR12 | mR13 | mR14 | mR15 | mES : mES | mBP | mBX | mSI | mDI;
399 }
400
401 void backend_term()
402 {
403 }
Note: See TracBrowser for help on using the browser.