1 /*
2 * Copyright (c) 1993-2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 #ifndef EXPAND_H_
19 #define EXPAND_H_
20
21 /** \file
22 * \brief various definitions for the expand module
23 */
24
25 #include "gbldefs.h"
26 #include "global.h"
27 #include "symtab.h"
28 #include "ilmtp.h"
29 #include <stdint.h>
30
31 /* DEBUG-controlled -q stuff */
32
33 #define EXPDBG(x, y) (DEBUG && DBGBIT(x, y))
34
35 /* storage allocation macros */
36
37 #define EXP_ALLOC(stgb, dt, sz) \
38 { \
39 NEW(stgb.stg_base, dt, sz); \
40 stgb.stg_size = sz; \
41 }
42
43 #define EXP_MORE(stb, dt, nsz) \
44 { \
45 stb.stg_base = \
46 (dt *)sccrelal((char *)stb.stg_base, ((BIGUINT64)((nsz) * sizeof(dt)))); \
47 stb.stg_size = nsz; \
48 }
49
50 #define EXP_NEED(stb, dt, nsz) \
51 if (stb.stg_avail > stb.stg_size) \
52 EXP_MORE(stb, dt, nsz);
53
54 #define EXP_FREE(stb) FREE(stb.stg_base)
55
56 #ifndef FE90
57
58 /***** expander's view of the ILMs *****/
59
60 typedef struct ILM {
61 ILM_T opc;
62 ILM_T opnd[1];
63 } ILM;
64
65 #define ILM_OPND(i, opn) ((i)->opnd[opn - 1])
66
67 #ifdef __cplusplus
68 /* clang-format off */
ILM_OPC(const ILM * ilm)69 inline ILM_OP ILM_OPC(const ILM *ilm) {
70 return static_cast<ILM_OP>(ilm->opc);
71 }
72
SetILM_OPC(ILM * ilm,ILM_OP opc)73 inline void SetILM_OPC(ILM *ilm, ILM_OP opc) {
74 ilm->opc = opc;
75 }
76
ILM_SymOPND(const ILM * ilm,int opn)77 inline SPTR ILM_SymOPND(const ILM *ilm, int opn) {
78 return static_cast<SPTR>(ILM_OPND(ilm, opn));
79 }
80
ILM_DTyOPND(const ILM * ilm,int opn)81 inline DTYPE ILM_DTyOPND(const ILM *ilm, int opn) {
82 return static_cast<DTYPE>(ILM_OPND(ilm, opn));
83 }
84 /* clang-format on */
85 #else
86 #define ILM_OPC(i) ((i)->opc)
87 #define SetILM_OPC(i,j) ((i)->opc = (j))
88 #define ILM_SymOPND ILM_OPND
89 #define ILM_DTyOPND ILM_OPND
90 #endif
91
92 /*
93 * ILM Auxillary Area Declarations - Used to accumulate information about
94 * ILMs while being expanded. There is an item for each ILM. Each item in
95 * this area is indexed by the ILM index; since the ILM index is just an
96 * offset from the beginning of the ILM area, there will be items in the aux
97 * area that are not used.
98 */
99 typedef struct {
100 int w1;
101 int w2;
102 int w3;
103 int w4;
104 int w5;
105 int w6;
106 int w7;
107 int w8;
108 } ILM_AUX;
109
110 #define ILM_TEMP(i) (expb.temps[i])
111
112 #define ILI_OF(i) (expb.ilmb.stg_base[i].w1)
113 #define NME_OF(i) (expb.ilmb.stg_base[i].w2)
114 #define SCALE_OF(i) (expb.ilmb.stg_base[i].w4)
115
116 #define ILM_RESULT(i) (expb.ilmb.stg_base[i].w1)
117 #define ILM_NME(i) (expb.ilmb.stg_base[i].w2)
118 #define ILM_BLOCK(i) (expb.ilmb.stg_base[i].w3)
119 #define ILM_SCALE(i) (expb.ilmb.stg_base[i].w4)
120
121 #define ILM_RRESULT(i) ILM_RESULT(i)
122 #define ILM_IRESULT(i) (expb.ilmb.stg_base[i].w7)
123
124 /* RESTYPE is used to indicate result type */
125 #define ILM_RESTYPE(i) (expb.ilmb.stg_base[i].w6)
126 #define ILM_ISCMPLX 1
127 #define ILM_ISDCMPLX 2
128 #define ILM_ISCHAR 3
129 #define ILM_ISI8 4
130 #define ILM_ISX87CMPLX 5
131 #define ILM_ISDOUBLEDOUBLECMPLX 6
132 #define ILM_ISFLOAT128CMPLX 7
133
134 /* character stuff */
135 #define ILM_MXLEN(i) (expb.ilmb.stg_base[i].w5)
136 #define ILM_CLEN(i) (expb.ilmb.stg_base[i].w7)
137
138 /* this is used to tell whether an operand was
139 * directly expanded for this parent ILM, or some other */
140 #define ILM_EXPANDED_FOR(i) (expb.ilmb.stg_base[i].w8)
141
142 #define DOREG1 (flg.opt == 1 && !XBIT(8, 0x8))
143 #define ADDRCAND(a, b) if (DOREG1) { exp_rcand((a), (b)); }
144
145 /* FTN string stuff */
146
147 #define STR_AREA 6
148
149 /** \brief string descriptor */
150 typedef struct _str {
151 char aisvar; /**< string address is variable if TRUE */
152 char liscon; /**< string length is constant */
153 char dtype; /**< TY_CHAR or TY_NCHAR */
154 int aval; /**< address symptr or ili */
155 int lval; /**< string length or ili */
156 int cnt; /**< # items this list */
157 int tempnum; /**< temp # for this var */
158 struct _str *next; /**< next strdesc */
159 } STRDESC;
160
161 /* data common to expander module */
162
163 typedef struct {
164 int temps[9]; /* ili index temp area during expand */
165 struct {
166 ILM_AUX *stg_base;
167 int stg_size;
168 } ilmb;
169 union {
170 uint16_t wd;
171 struct {
172 unsigned waitlbl : 1; /* waiting for a LABEL ILM */
173 unsigned noblock : 1; /* no block has been created */
174 unsigned excstat : 1; /* excstat was changed */
175 unsigned dbgline : 1; /* blocks are to be debugged */
176 unsigned callfg : 1; /* function calls an external */
177 unsigned sdscunsafe : 1; /* call might mod descriptor */
178 unsigned noheader : 1; /* no entry header written (ftn) */
179 } bits;
180 } flags;
181 int nilms; /* number of (short) words in the ILM block */
182 int curlin; /* line number of the current ILI block */
183 int curbih; /* index of BIH of the current ILT block */
184 int curilt; /* index of the current (last) ILT */
185 int saveili; /* ILI (a JMP) not yet added to the block */
186 SPTR retlbl; /* ST index to the current return label */
187 int retcnt; /* decimal number for the current rtn label */
188 int swtcnt; /* decimal number for the last switch array */
189 int arglist; /* ST index of the current argument list */
190 struct {
191 short next; /* decimal # for the next arglist */
192 short start; /* start # for arglists in a function */
193 short max; /* max "next" # for arglists in a func. */
194 } arglcnt;
195 int uicmp; /* symbol table index of uicmp function */
196 int gentmps; /* general temps */
197 bool qjsr_flag; /* qjsr present in the function/subprogram */
198 bool intr_flag; /* intrinsic present in the function/subprogram*/
199 int isguarded; /* increment when encounter DOBEGNZ */
200 INT ilm_words; /* # of ilm words in the current ili block */
201 INT ilm_thresh; /* if ilm_words > ilm_thresh, break block */
202 SC_KIND sc; /* storage class used for expander-created
203 * temporaries (SC_LOCAL, SC_PRIVATE).
204 */
205 int lcpu2; /* temporary for the current function's
206 * value of mp_lcpu2().
207 */
208 int lcpu3; /* temporary for the current function's
209 * value of mp_lcpu3().
210 */
211 int ncpus2; /* temporary for the current function's
212 * value of mp_ncpus2().
213 */
214 int chartmps; /* character temps */
215 int chardtmps; /* char descriptor temps */
216 STRDESC *str_base; /* string descriptor list */
217 int str_size;
218 int str_avail;
219 int logcjmp; /* compare & branch ili for logical values:
220 * default is IL_LCJMPZ (odd/even test); -x 125 8
221 * implies IL_ICJMPZ (zero/non-zero test).
222 * initialized by exp_init().
223 */
224 SPTR aret_tmp; /* temporary for the alternate return value */
225 int clobber_ir; /* gcc-asm clobber list (iregs) info */
226 int clobber_pr; /* gcc-asm clobber list (pregs) info */
227 SPTR mxcsr_tmp; /* temporary for the value of the mxcsr */
228 int implicitdataregions;
229 DTYPE charlen_dtype;
230 } EXP;
231
232 extern EXP expb;
233
234 #define CHARLEN_64BIT (XBIT(68,1) || XBIT(68,0x20))
235
236 #ifdef EXPANDER_DECLARE_INTERNAL
237 /* Routines internal to the expander that should not be declared
238 as part of the public interface. */
239
240 #define expand_throw_point(ilix, dtype, ili_st) \
241 (DEBUG_ASSERT(0, "throw points supported only for C++"), (ilix))
242 #endif /* EXPANDER_DECLARE_INTERNAL */
243
244 #endif /* ifndef FE90 */
245
246 /**
247 \brief ...
248 */
249 int expand(void);
250
251 #ifndef FE90
252 /**
253 \brief ...
254 */
255 int exp_mac(ILM_OP opc, ILM *ilmp, int curilm);
256 #endif
257
258 /**
259 \brief ...
260 */
261 int getThreadPrivateTp(int sptr);
262
263 /**
264 \brief ...
265 */
266 int llGetThreadprivateAddr(int sptr);
267
268 #ifndef FE90
269 /**
270 \brief ...
271 */
272 int optional_missing_ilm(ILM *ilmpin);
273 #endif
274
275 /**
276 \brief ...
277 */
278 int optional_missing(int nme);
279
280 /**
281 \brief ...
282 */
283 int optional_present(int nme);
284
285 /**
286 \brief ...
287 */
288 void ds_init(void);
289
290 /**
291 \brief ...
292 */
293 void eval_ilm(int ilmx);
294
295 /**
296 \brief ...
297 */
298 void exp_cleanup(void);
299
300 /**
301 \brief ...
302 */
303 void exp_estmt(int ilix);
304
305 /**
306 \brief ...
307 */
308 void exp_init(void);
309
310 /**
311 \brief ...
312 */
313 void exp_label(SPTR lbl);
314
315 #ifndef FE90
316 /**
317 \brief ...
318 */
319 void exp_load(ILM_OP opc, ILM *ilmp, int curilm);
320
321 /**
322 \brief ...
323 */
324 void exp_pure(SPTR extsym, int nargs, ILM *ilmp, int curilm);
325
326 /**
327 \brief ...
328 */
329 void exp_ref(ILM_OP opc, ILM *ilmp, int curilm);
330
331 /**
332 \brief ...
333 */
334 void exp_store(ILM_OP opc, ILM *ilmp, int curilm);
335 #endif
336
337 /**
338 \brief ...
339 */
340 void ll_set_new_threadprivate(int oldsptr);
341
342 /**
343 \brief ...
344 */
345 void ref_threadprivate(int cmsym, int *addr, int *nm);
346
347 /**
348 \brief ...
349 */
350 void ref_threadprivate_var(int cmsym, int *addr, int *nm, int mark);
351
352 #ifndef FE90
353 /**
354 \brief ...
355 */
356 void replace_by_one(ILM_OP opc, ILM *ilmp, int curilm);
357
358 /**
359 \brief ...
360 */
361 void replace_by_zero(ILM_OP opc, ILM *ilmp, int curilm);
362 #endif
363
364 /**
365 \brief ...
366 */
367 void set_assn(int nme);
368
369 #endif
370