1 /**
2  * Compiler implementation of the
3  * $(LINK2 http://www.dlang.org, D programming language).
4  *
5  * Copyright:   Copyright (C) 1985-1995 by Symantec
6  *              Copyright (c) 1999-2016 by Digital Mars, All Rights Reserved
7  * Authors:     $(LINK2 http://www.digitalmars.com, Walter Bright)
8  * License:     backendlicense.txt
9  * Source:      $(DMDSRC backend/_el.d)
10  */
11 
12 module ddmd.backend.el;
13 
14 import ddmd.backend.cdef;
15 import ddmd.backend.cc;
16 import ddmd.backend.type;
17 
18 import ddmd.backend.cc : Symbol;
19 
20 extern (C++):
21 @nogc:
22 nothrow:
23 
24 /* Routines to handle elems.                            */
25 
26 alias ubyte eflags_t;
27 enum
28 {
29     EFLAGS_variadic = 1,   // variadic function call
30 }
31 
32 alias uint pef_flags_t;
33 enum
34 {
35     PEFnotlvalue    = 1,       // although elem may look like
36                                // an lvalue, it isn't
37     PEFtemplate_id  = 0x10,    // symbol is a template-id
38     PEFparentheses  = 0x20,    // expression was within ()
39     PEFaddrmem      = 0x40,    // address of member
40     PEFdependent    = 0x80,    // value-dependent
41     PEFmember       = 0x100,   // was a class member access
42 }
43 
44 alias ubyte nflags_t;
45 enum
46 {
47     NFLli     = 1,     // loop invariant
48     NFLnogoal = 2,     // evaluate elem for side effects only
49     NFLassign = 8,     // unambiguous assignment elem
50     NFLaecp   = 0x10,  // AE or CP or VBE expression
51     NFLdelcse = 0x40,  // this is not the generating CSE
52     NFLtouns  = 0x80,  // relational operator was changed from signed to unsigned
53 }
54 
55 /******************************************
56  * Elems:
57  *      Elems are the basic tree element. They can be either
58  *      terminal elems (leaves), unary elems (left subtree exists)
59  *      or binary elems (left and right subtrees exist).
60  */
61 
62 struct elem
63 {
64     debug ushort      id;
65     enum IDelem = 0x4C45;   // 'EL'
66     //elem_debug(e) assert((e)->id == IDelem)
67 
68     ubyte Eoper;        // operator (OPxxxx)
69     ubyte Ecount;       // # of parents of this elem - 1,
70                         // always 0 until CSE elimination is done
71     eflags_t Eflags;
72 
73     eve EV;             // variants for each type of elem
74     union
75     {
76         // PARSER
77         struct
78         {
79             pef_flags_t PEFflags;
80             Symbol* Emember;       // if PEFmember, this is the member
81         }
82 
83         // OPTIMIZER
84         struct
85         {
86             tym_t Ety;         // data type (TYxxxx)
87             uint Eexp;         // index into expnod[]
88 
89             // These flags are all temporary markers, used once and then
90             // thrown away.
91             nflags_t Nflags;   // NFLxxx
92 
93             // MARS
94             ubyte Ejty;        // original Mars type
95         }
96 
97         // CODGEN
98         struct
99         {
100             // Ety2: Must be in same position as Ety!
101             tym_t Ety2;        // data type (TYxxxx)
102             ubyte Ecomsub;     // number of remaining references to
103                                // this common subexp (used to determine
104                                // first, intermediate, and last references
105                                // to a CSE)
106         }
107     }
108 
109     type *ET;            // pointer to type of elem if TYstruct | TYarray
110     Srcpos Esrcpos;      // source file position
111 }
112 
113 version (MARS)
114     tym_t typemask(elem* e) { return e.Ety; }
115 else
116     tym_t typemask(elem* e) { return PARSER ? e.ET.Tty : e.Ety; }
117 
118 //FL el_fl(elem *e) { return cast(FL)e.EV.Vsym.Sfl; }
119 
120 //#define Eoffset         EV.sp.Voffset
121 //#define Esymnum         EV.sp.Vsymnum
122 
123 //#define list_elem(list) ((elem *) list_ptr(list))
124 //#define list_setelem(list,ptr) list_ptr(list) = (elem *)(ptr)
125 //#define cnst(e) ((e)->Eoper == OPconst) /* Determine if elem is a constant */
126 //#define E1        EV.eop.Eleft          /* left child                   */
127 //#define E2        EV.eop.Eright         /* right child                  */
128 //#define Erd       EV.sp.spu.Erd         // reaching definition
129 
130 void el_init();
131 void el_reset();
132 void el_term();
133 elem *el_calloc();
134 void el_free(elem *);
135 elem *el_combine(elem *,elem *);
136 elem *el_param(elem *,elem *);
137 elem *el_params(elem *, ...);
138 elem *el_params(void **args, int length);
139 elem *el_combines(void **args, int length);
140 int el_nparams(elem *e);
141 void el_paramArray(elem ***parray, elem *e);
142 elem *el_pair(tym_t, elem *, elem *);
143 void el_copy(elem *,elem *);
144 elem *el_alloctmp(tym_t);
145 elem *el_selecte1(elem *);
146 elem *el_selecte2(elem *);
147 elem *el_copytree(elem *);
148 void   el_replace_sym(elem *e,Symbol *s1,Symbol *s2);
149 elem *el_scancommas(elem *);
150 int el_countCommas(elem *);
151 int el_sideeffect(elem *);
152 int el_depends(elem *ea,elem *eb);
153 targ_llong el_tolongt(elem *);
154 targ_llong el_tolong(elem *);
155 int el_allbits(elem *,int);
156 int el_signx32(elem *);
157 targ_ldouble el_toldouble(elem *);
158 void el_toconst(elem *);
159 elem *el_same(elem **);
160 elem *el_copytotmp(elem **);
161 int el_match(elem *,elem *);
162 int el_match2(elem *,elem *);
163 int el_match3(elem *,elem *);
164 int el_match4(elem *,elem *);
165 int el_match5(elem *,elem *);
166 
167 int el_appears(elem *e,Symbol *s);
168 Symbol *el_basesym(elem *e);
169 int el_anydef(elem *ed, elem *e);
170 elem *el_bint(uint,type *,elem *,elem *);
171 elem *el_unat(uint,type *,elem *);
172 elem *el_bin(uint,tym_t,elem *,elem *);
173 elem *el_una(uint,tym_t,elem *);
174 elem *el_longt(type *,targ_llong);
175 Symbol *el_alloc_localgot();
176 elem *el_var(Symbol *);
177 elem *el_settype(elem *,type *);
178 elem *el_typesize(type *);
179 elem *el_ptr(Symbol *);
180 void el_replace_sym(elem *e,Symbol *s1,Symbol *s2);
181 elem *el_ptr_offset(Symbol *s,targ_size_t offset);
182 void el_replacesym(elem *,Symbol *,Symbol *);
183 elem *el_nelems(type *);
184 
185 elem *el_long(tym_t,targ_llong);
186 
187 int ERTOL(elem *);
188 int el_noreturn(elem *);
189 //elem *el_dctor(elem *e,void *decl);
190 //elem *el_ddtor(elem *e,void *decl);
191 elem *el_ctor_dtor(elem *ec, elem *ed, elem **pedtor);
192 elem *el_ctor(elem *ector,elem *e,Symbol *sdtor);
193 elem *el_dtor(elem *edtor,elem *e);
194 elem *el_zero(type *t);
195 elem *el_const(tym_t, eve *);
196 elem *el_test(tym_t, eve *);
197 elem ** el_parent(elem *,elem **);
198 
199 //#ifdef DEBUG
200 //void el_check(elem *);
201 //#else
202 //#define el_check(e)     ((void)0)
203 //#endif
204 
205 elem *el_convfloat(elem *);
206 elem *el_convstring(elem *);
207 elem *el_convert(elem *e);
208 int el_isdependent(elem *);
209 uint el_alignsize(elem *);
210 
211 size_t el_opN(elem *e, uint op);
212 void el_opArray(elem ***parray, elem *e, uint op);
213 void el_opFree(elem *e, uint op);
214 elem *el_opCombine(elem **args, size_t length, uint op, uint ty);
215 
216 void elem_print(elem *);
217 void elem_print_const(elem *);
218 void el_hydrate(elem **);
219 void el_dehydrate(elem **);
220 
221