1 /**
2  * Various global symbols.
3  *
4  * Compiler implementation of the
5  * $(LINK2 http://www.dlang.org, D programming language).
6  *
7  * Copyright:   Copyright (C) 1984-1995 by Symantec
8  *              Copyright (C) 2000-2020 by The D Language Foundation, All Rights Reserved
9  * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)
10  * License:     $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
11  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/backend/cg.c, backend/cg.d)
12  */
13 
14 module dmd.backend.cg;
15 
16 import dmd.backend.cdef;
17 import dmd.backend.cc;
18 import dmd.backend.global;
19 import dmd.backend.code;
20 import dmd.backend.code_x86;
21 import dmd.backend.type;
22 
23 extern (C++):
24 
25 ///////////////////// GLOBALS /////////////////////
26 
27 __gshared
28 {
29 targ_size_t     framehandleroffset;     // offset of C++ frame handler
30 targ_size_t     localgotoffset; // offset of where localgot refers to
31 
32 int cseg = CODE;                // current code segment
33                                 // (negative values mean it is the negative
34                                 // of the public name index of a COMDAT)
35 
36 /* Stack offsets        */
37 targ_size_t localsize;          /* amt subtracted from SP for local vars */
38 
39 /* The following are initialized for the 8088. cod3_set32() or cod3_set64()
40  * will change them as appropriate.
41  */
42 int     BPRM = 6;               /* R/M value for [BP] or [EBP]          */
43 regm_t  fregsaved;              // mask of registers saved across function calls
44 
45 regm_t  FLOATREGS = FLOATREGS_16;
46 regm_t  FLOATREGS2 = FLOATREGS2_16;
47 regm_t  DOUBLEREGS = DOUBLEREGS_16;
48 
49 Symbol *localgot;               // reference to GOT for this function
50 Symbol *tls_get_addr_sym;       // function __tls_get_addr
51 
52 int TARGET_STACKALIGN = 2;      // default for 16 bit code
53 int STACKALIGN = 2;             // varies for each function
54 
55 
56 /// Is fl data?
57 bool[FLMAX] datafl =
58 () {
59     bool[FLMAX] datafl;
60     foreach (fl; [ FLdata,FLudata,FLreg,FLpseudo,FLauto,FLfast,FLpara,FLextern,
61                    FLcs,FLfltreg,FLallocatmp,FLdatseg,FLtlsdata,FLbprel,
62                    FLstack,FLregsave,FLfuncarg,
63                    FLndp, FLfardata,
64                  ])
65     {
66         datafl[fl] = true;
67     }
68     return datafl;
69 } ();
70 
71 
72 /// Is fl on the stack?
73 bool[FLMAX] stackfl =
74 () {
75     bool[FLMAX] stackfl;
76     foreach (fl; [ FLauto,FLfast,FLpara,FLcs,FLfltreg,FLallocatmp,FLbprel,FLstack,FLregsave,
77                    FLfuncarg,
78                    FLndp,
79                  ])
80     {
81         stackfl[fl] = true;
82     }
83     return stackfl;
84 } ();
85 
86 /// What segment register is associated with it?
87 ubyte[FLMAX] segfl =
88 () {
89     ubyte[FLMAX] segfl;
90 
91     // Segment registers
92     enum ES = 0;
93     enum CS = 1;
94     enum SS = 2;
95     enum DS = 3;
96     enum NO = ubyte.max;        // no register
97 
98     foreach (fl, ref seg; segfl)
99     {
100         switch (fl)
101         {
102             case 0:              seg = NO;  break;
103             case FLconst:        seg = NO;  break;
104             case FLoper:         seg = NO;  break;
105             case FLfunc:         seg = CS;  break;
106             case FLdata:         seg = DS;  break;
107             case FLudata:        seg = DS;  break;
108             case FLreg:          seg = NO;  break;
109             case FLpseudo:       seg = NO;  break;
110             case FLauto:         seg = SS;  break;
111             case FLfast:         seg = SS;  break;
112             case FLstack:        seg = SS;  break;
113             case FLbprel:        seg = SS;  break;
114             case FLpara:         seg = SS;  break;
115             case FLextern:       seg = DS;  break;
116             case FLcode:         seg = CS;  break;
117             case FLblock:        seg = CS;  break;
118             case FLblockoff:     seg = CS;  break;
119             case FLcs:           seg = SS;  break;
120             case FLregsave:      seg = SS;  break;
121             case FLndp:          seg = SS;  break;
122             case FLswitch:       seg = NO;  break;
123             case FLfltreg:       seg = SS;  break;
124             case FLoffset:       seg = NO;  break;
125             case FLfardata:      seg = NO;  break;
126             case FLcsdata:       seg = CS;  break;
127             case FLdatseg:       seg = DS;  break;
128             case FLctor:         seg = NO;  break;
129             case FLdtor:         seg = NO;  break;
130             case FLdsymbol:      seg = NO;  break;
131             case FLgot:          seg = NO;  break;
132             case FLgotoff:       seg = NO;  break;
133             case FLtlsdata:      seg = NO;  break;
134             case FLlocalsize:    seg = NO;  break;
135             case FLframehandler: seg = NO;  break;
136             case FLasm:          seg = NO;  break;
137             case FLallocatmp:    seg = SS;  break;
138             case FLfuncarg:      seg = SS;  break;
139 
140             default:
141                 assert(0);
142         }
143     }
144 
145     return segfl;
146 } ();
147 
148 /// Is fl in the symbol table?
149 bool[FLMAX] flinsymtab =
150 () {
151     bool[FLMAX] flinsymtab;
152     foreach (fl; [ FLdata,FLudata,FLreg,FLpseudo,FLauto,FLfast,FLpara,FLextern,FLfunc,
153                    FLtlsdata,FLbprel,FLstack,
154                    FLfardata,FLcsdata,
155                  ])
156     {
157         flinsymtab[fl] = true;
158     }
159     return flinsymtab;
160 } ();
161 
162 }