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