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