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 
24 ///////////////////// GLOBALS /////////////////////
25 
26 __gshared
27 {
28 targ_size_t     framehandleroffset;     // offset of C++ frame handler
29 targ_size_t     localgotoffset; // offset of where localgot refers to
30 
31 int cseg = CODE;                // current code segment
32                                 // (negative values mean it is the negative
33                                 // of the public name index of a COMDAT)
34 
35 /* Stack offsets        */
36 targ_size_t localsize;          /* amt subtracted from SP for local vars */
37 
38 /* The following are initialized for the 8088. cod3_set32() or cod3_set64()
39  * will change them as appropriate.
40  */
41 int     BPRM = 6;               /* R/M value for [BP] or [EBP]          */
42 regm_t  fregsaved;              // mask of registers saved across function calls
43 
44 regm_t  FLOATREGS = FLOATREGS_16;
45 regm_t  FLOATREGS2 = FLOATREGS2_16;
46 regm_t  DOUBLEREGS = DOUBLEREGS_16;
47 
48 Symbol *localgot;               // reference to GOT for this function
49 Symbol *tls_get_addr_sym;       // function __tls_get_addr
50 
51 int TARGET_STACKALIGN = 2;      // default for 16 bit code
52 int STACKALIGN = 2;             // varies for each function
53 
54 
55 /// Is fl data?
56 bool[FLMAX] datafl = datafl_init;
57 extern (D) private enum datafl_init =
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 = stackfl_init;
74 extern (D) private enum stackfl_init =
75 () {
76     bool[FLMAX] stackfl;
77     foreach (fl; [ FLauto,FLfast,FLpara,FLcs,FLfltreg,FLallocatmp,FLbprel,FLstack,FLregsave,
78                    FLfuncarg,
79                    FLndp,
80                  ])
81     {
82         stackfl[fl] = true;
83     }
84     return stackfl;
85 } ();
86 
87 /// What segment register is associated with it?
88 ubyte[FLMAX] segfl = segfl_init;
89 extern (D) private enum segfl_init =
90 () {
91     ubyte[FLMAX] segfl;
92 
93     // Segment registers
94     enum ES = 0;
95     enum CS = 1;
96     enum SS = 2;
97     enum DS = 3;
98     enum NO = ubyte.max;        // no register
99 
100     foreach (fl, ref seg; segfl)
101     {
102         switch (fl)
103         {
104             case 0:              seg = NO;  break;
105             case FLconst:        seg = NO;  break;
106             case FLoper:         seg = NO;  break;
107             case FLfunc:         seg = CS;  break;
108             case FLdata:         seg = DS;  break;
109             case FLudata:        seg = DS;  break;
110             case FLreg:          seg = NO;  break;
111             case FLpseudo:       seg = NO;  break;
112             case FLauto:         seg = SS;  break;
113             case FLfast:         seg = SS;  break;
114             case FLstack:        seg = SS;  break;
115             case FLbprel:        seg = SS;  break;
116             case FLpara:         seg = SS;  break;
117             case FLextern:       seg = DS;  break;
118             case FLcode:         seg = CS;  break;
119             case FLblock:        seg = CS;  break;
120             case FLblockoff:     seg = CS;  break;
121             case FLcs:           seg = SS;  break;
122             case FLregsave:      seg = SS;  break;
123             case FLndp:          seg = SS;  break;
124             case FLswitch:       seg = NO;  break;
125             case FLfltreg:       seg = SS;  break;
126             case FLoffset:       seg = NO;  break;
127             case FLfardata:      seg = NO;  break;
128             case FLcsdata:       seg = CS;  break;
129             case FLdatseg:       seg = DS;  break;
130             case FLctor:         seg = NO;  break;
131             case FLdtor:         seg = NO;  break;
132             case FLdsymbol:      seg = NO;  break;
133             case FLgot:          seg = NO;  break;
134             case FLgotoff:       seg = NO;  break;
135             case FLtlsdata:      seg = NO;  break;
136             case FLlocalsize:    seg = NO;  break;
137             case FLframehandler: seg = NO;  break;
138             case FLasm:          seg = NO;  break;
139             case FLallocatmp:    seg = SS;  break;
140             case FLfuncarg:      seg = SS;  break;
141 
142             default:
143                 assert(0);
144         }
145     }
146 
147     return segfl;
148 } ();
149 
150 /// Is fl in the symbol table?
151 bool[FLMAX] flinsymtab = flinsymtab_init;
152 extern (D) private enum flinsymtab_init =
153 () {
154     bool[FLMAX] flinsymtab;
155     foreach (fl; [ FLdata,FLudata,FLreg,FLpseudo,FLauto,FLfast,FLpara,FLextern,FLfunc,
156                    FLtlsdata,FLbprel,FLstack,
157                    FLfardata,FLcsdata,
158                  ])
159     {
160         flinsymtab[fl] = true;
161     }
162     return flinsymtab;
163 } ();
164 
165 }