1 /**
2  * Various global symbols.
3  *
4  * Compiler implementation of the
5  * $(LINK2 https://www.dlang.org, D programming language).
6  *
7  * Copyright:   Copyright (C) 1984-1995 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/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 = datafl_init;
58 extern (D) private enum datafl_init =
59 () {
60     bool[FLMAX] datafl;
61     foreach (fl; [ FLdata,FLudata,FLreg,FLpseudo,FLauto,FLfast,FLpara,FLextern,
62                    FLcs,FLfltreg,FLallocatmp,FLdatseg,FLtlsdata,FLbprel,
63                    FLstack,FLregsave,FLfuncarg,
64                    FLndp, FLfardata,
65                  ])
66     {
67         datafl[fl] = true;
68     }
69     return datafl;
70 } ();
71 
72 
73 /// Is fl on the stack?
74 bool[FLMAX] stackfl = stackfl_init;
75 extern (D) private enum stackfl_init =
76 () {
77     bool[FLMAX] stackfl;
78     foreach (fl; [ FLauto,FLfast,FLpara,FLcs,FLfltreg,FLallocatmp,FLbprel,FLstack,FLregsave,
79                    FLfuncarg,
80                    FLndp,
81                  ])
82     {
83         stackfl[fl] = true;
84     }
85     return stackfl;
86 } ();
87 
88 /// What segment register is associated with it?
89 ubyte[FLMAX] segfl = segfl_init;
90 extern (D) private enum segfl_init =
91 () {
92     ubyte[FLMAX] segfl;
93 
94     // Segment registers
95     enum ES = 0;
96     enum CS = 1;
97     enum SS = 2;
98     enum DS = 3;
99     enum NO = ubyte.max;        // no register
100 
101     foreach (fl, ref seg; segfl)
102     {
103         switch (fl)
104         {
105             case 0:              seg = NO;  break;
106             case FLconst:        seg = NO;  break;
107             case FLoper:         seg = NO;  break;
108             case FLfunc:         seg = CS;  break;
109             case FLdata:         seg = DS;  break;
110             case FLudata:        seg = DS;  break;
111             case FLreg:          seg = NO;  break;
112             case FLpseudo:       seg = NO;  break;
113             case FLauto:         seg = SS;  break;
114             case FLfast:         seg = SS;  break;
115             case FLstack:        seg = SS;  break;
116             case FLbprel:        seg = SS;  break;
117             case FLpara:         seg = SS;  break;
118             case FLextern:       seg = DS;  break;
119             case FLcode:         seg = CS;  break;
120             case FLblock:        seg = CS;  break;
121             case FLblockoff:     seg = CS;  break;
122             case FLcs:           seg = SS;  break;
123             case FLregsave:      seg = SS;  break;
124             case FLndp:          seg = SS;  break;
125             case FLswitch:       seg = NO;  break;
126             case FLfltreg:       seg = SS;  break;
127             case FLoffset:       seg = NO;  break;
128             case FLfardata:      seg = NO;  break;
129             case FLcsdata:       seg = CS;  break;
130             case FLdatseg:       seg = DS;  break;
131             case FLctor:         seg = NO;  break;
132             case FLdtor:         seg = NO;  break;
133             case FLdsymbol:      seg = NO;  break;
134             case FLgot:          seg = NO;  break;
135             case FLgotoff:       seg = NO;  break;
136             case FLtlsdata:      seg = NO;  break;
137             case FLlocalsize:    seg = NO;  break;
138             case FLframehandler: seg = NO;  break;
139             case FLasm:          seg = NO;  break;
140             case FLallocatmp:    seg = SS;  break;
141             case FLfuncarg:      seg = SS;  break;
142 
143             default:
144                 assert(0);
145         }
146     }
147 
148     return segfl;
149 } ();
150 
151 /// Is fl in the symbol table?
152 bool[FLMAX] flinsymtab = flinsymtab_init;
153 extern (D) private enum flinsymtab_init =
154 () {
155     bool[FLMAX] flinsymtab;
156     foreach (fl; [ FLdata,FLudata,FLreg,FLpseudo,FLauto,FLfast,FLpara,FLextern,FLfunc,
157                    FLtlsdata,FLbprel,FLstack,
158                    FLfardata,FLcsdata,
159                  ])
160     {
161         flinsymtab[fl] = true;
162     }
163     return flinsymtab;
164 } ();
165 
166 }