1 /*
2  * Copyright (c) 1994-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 SYMTAB_H_
19 #define SYMTAB_H_
20 
21 /** \file
22  *  \brief symbol table for Fortran backend
23  */
24 
25 #include "global.h"
26 #include <stdarg.h>
27 
28 /* clang-format off */
29 .OC
30 
31 .ST
32 /* the following macro depends on stype ordering */
33 #define ST_ISVAR(s) ((s) >= ST_VAR && (s) <= ST_UNION)
34 
35 .TY
36 
37 #define DT_FLOAT DT_REAL
38 #define TY_FLOAT TY_REAL
39 #define DT_CPTR DT_ADDR
40 
41 #define DTY(d) (stb.dt.stg_base[d])
42 
43 /* for fast DT checking -- define table indexed by TY_ */
44 extern short dttypes[TY_MAX+1];
45 .TA
46 
47 #define DDTG(dt) (DTY(dt) == TY_ARRAY ? DTY(dt+1) : dt)
48 #define DTYG(dt) (DTY(dt) == TY_ARRAY ? DTY(DTY(dt+1)) : DTY(dt))
49 
50 #define DT_ISINT(dt)	(dttypes[DTY(dt)]&_TY_INT)
51 #define DT_ISREAL(dt)	(dttypes[DTY(dt)]&_TY_REAL)
52 #define DT_ISCMPLX(dt)	(dttypes[DTY(dt)]&_TY_CMPLX)
53 #define DT_ISNUMERIC(dt) (dttypes[DTY(dt)]&(_TY_INT|_TY_REAL|_TY_CMPLX))
54 #define DT_ISBASIC(dt)	(dttypes[DTY(dt)]&_TY_BASIC)
55 #define DT_ISUNSIGNED(dt) (dttypes[DTY(dt)]&_TY_UNSIGNED)
56 #define DT_ISSCALAR(dt)	(dttypes[DTY(dt)]&_TY_SCALAR)
57 #define DT_ISVEC(dt)	(dttypes[DTY(dt)]&_TY_VEC)
58 #define DT_ISLOG(dt)	(dttypes[DTY(dt)]&_TY_LOG)
59 #define DT_ISWORD(dt)	(dttypes[DTY(dt)]&_TY_WORD)
60 #define DT_ISDWORD(dt)	(dttypes[DTY(dt)]&_TY_DWORD)
61 #define DT_ISVECT(dt)   (dttypes[DTY(dt)]&_TY_VECT)
62 
63 #define TY_ISINT(t)	(dttypes[t]&_TY_INT)
64 #define TY_ISREAL(t)	(dttypes[t]&_TY_REAL)
65 #define TY_ISCMPLX(t)	(dttypes[t]&_TY_CMPLX)
66 #define TY_ISNUMERIC(t)	(dttypes[t]&(_TY_INT|_TY_REAL|_TY_CMPLX))
67 #define TY_ISBASIC(t)	(dttypes[t]&_TY_BASIC)
68 #define TY_ISUNSIGNED(t) (dttypes[t]&_TY_UNSIGNED)
69 #define TY_ISSCALAR(t)	(dttypes[t]&_TY_SCALAR)
70 #define TY_ISLOG(t)	(dttypes[t]&_TY_LOG)
71 #define TY_ISVEC(t)	(dttypes[t]&_TY_VEC)
72 #define TY_ISWORD(t)	(dttypes[t]&_TY_WORD)
73 #define TY_ISDWORD(t)	(dttypes[t]&_TY_DWORD)
74 #define TY_ISVECT(t)    (dttypes[t]&_TY_VECT)
75 
76 #define TY_VECT_MAXLEN 16
77 
78 #define ALIGN(addr, a) ((addr + a) & ~(a))
79 #define ALIGN_AUTO(addr, a) ((addr) & ~(a))
80 
81 .Sc
82 
83 #define SC_AUTO SC_LOCAL
84 #define SC_ISCMBLK(p)  (p == SC_CMBLK)
85 
86 .SE
87 
88 /* redo & add a few macros when BIGOBJects are allowed.
89  * The value of the CONVAL2 field is 'assumed' to be a 32-bit;
90  * the offset of an address constant is 64-bit.
91  */
92 
93 #undef CONVAL2G
94 #undef CONVAL2P
95 #undef CMEMLG
96 #undef CMEMLP
97 #undef DEFLABG
98 #undef DEFLABP
99 #undef ENDLINEG
100 #undef ENDLINEP
101 #undef FUNCLINEG
102 #undef FUNCLINEP
103 #undef GSAMEG
104 #undef GSAMEP
105 #undef ILMG
106 #undef ILMP
107 #define CONVAL2G(s)   (INT)(( stb.stg_base)[s].w14)
108 #define CONVAL2P(s,v) (INT)(( stb.stg_base)[s].w14 = (v))
109 #define CMEMLG(s)   (INT)(( stb.stg_base)[s].w14)
110 #define CMEMLP(s,v) (INT)(( stb.stg_base)[s].w14 = (v))
111 #define DEFLABG(s)   (INT)(( stb.stg_base)[s].w14)
112 #define DEFLABP(s,v) (INT)(( stb.stg_base)[s].w14 = (v))
113 #define ENDLINEG(s)   (INT)(( stb.stg_base)[s].w14)
114 #define ENDLINEP(s,v) (INT)(( stb.stg_base)[s].w14 = (v))
115 #define FUNCLINEG(s)   (INT)(( stb.stg_base)[s].w14)
116 #define FUNCLINEP(s,v) (INT)(( stb.stg_base)[s].w14 = (v))
117 #define GSAMEG(s)   (INT)(( stb.stg_base)[s].w14)
118 #define GSAMEP(s,v) (INT)(( stb.stg_base)[s].w14 = (v))
119 #define ILMG(s)   (INT)(( stb.stg_base)[s].w14)
120 #define ILMP(s,v) (INT)(( stb.stg_base)[s].w14 = (v))
121 
122 #undef ORIGDUMMYG
123 #undef ORIGDUMMYP
124 #define ORIGDUMMYG(s)   (INT)(( stb.stg_base)[s].w32)
125 #define ORIGDUMMYP(s,v) (INT)(( stb.stg_base)[s].w32 = (v))
126 
127 #undef GREALG
128 #undef GREALP
129 #undef SFDSCG
130 #undef SFDSCP
131 #define GREALG(s)   (INT)(( stb.stg_base)[s].w10)
132 #define GREALP(s,v) (INT)(( stb.stg_base)[s].w10 = (v))
133 #define SFDSCG(s)   (INT)(( stb.stg_base)[s].w10)
134 #define SFDSCP(s,v) (INT)(( stb.stg_base)[s].w10 = (v))
135 
136 /* overloaded macros accessing shared fields */
137 
138 #define ACONOFFG(s)   (( stb.stg_base)[s].w14)
139 #define ACONOFFP(s,v) (( stb.stg_base)[s].w14 = (v))
140 #define PARAMVALG(s)   (( stb.stg_base)[s].w15)
141 #define PARAMVALP(s,v) (( stb.stg_base)[s].w15 = (v))
142 #define DLLG(s)       b3G(s)
143 #define DLLP(s,v)     b3P(s,v)
144 #define PDALN_EXPLICIT_0 0xf
145 #define PDALNG(s)     ((b4G(s)&0x0f) == PDALN_EXPLICIT_0 ? 0 : (b4G(s)&0x0f))
146 #define PDALNP(s,v)   b4P(s, (b4G(s)&0xf0) | ((v) == 0 ? PDALN_EXPLICIT_0 : (v)))
147 #define PDALN_IS_DEFAULT(s) ((b4G(s)&0x0f) == 0)
148 #ifdef PGF90
149 #define CUDAG(s)      b4G(s)
150 #define CUDAP(s,v)    b4P(s,v)
151 #define CUDA_HOST		0x01
152 #define CUDA_DEVICE		0x02
153 #define CUDA_GLOBAL		0x04
154 #define CUDA_BUILTIN		0x08
155 #define CUDA_GRID		0x10
156 #define CUDA_CONSTRUCTOR	0x20
157 #define CUDA_STUB		0x40
158  /* b4G and b4P can only be up to 0xFF */
159 #endif
160 
161 #define SYMNAME(p)        (stb.n_base + NMPTRG(p))
162 #define SYMNAMEG(p, buff, len)    len = NMLENG(p); strncpy(buff,SYMNAME(p),len)
163 #define LOCAL_SYMNAME(p) local_sname(SYMNAME(p))
164 #define RFCNTI(s) (++RFCNTG(s))
165 #define RFCNTD(s) (--RFCNTG(s))
166 #define RETADJG(s)      (( stb.stg_base)[s].w10)
167 #define RETADJP(s,v)    (( stb.stg_base)[s].w10 = (v))
168 #define XREFLKG(s)      (( stb.stg_base)[s].w16)
169 #define XREFLKP(s,v)    (( stb.stg_base)[s].w16 = (v))
170 #define NOSYM ((SPTR)1)
171 
172 typedef enum etls_levels {
173     ETLS_PROCESS,
174     ETLS_TASK,
175     ETLS_THREAD,
176     ETLS_OMP,
177     /* Insert HLS here ?*/
178     ETLS_NUM_LEVELS
179 } etls_levels;
180 
181 #define IS_TLS(s) (TLSG(s) || ETLSG(s))
182 #define IS_THREAD_TLS(s) (THREADG(s) &&   IS_TLS(s))
183 #define IS_THREAD_TP(s)  (THREADG(s) && (!IS_TLS(s)))
184 #define IS_TLS_WRAPPER(sptr) (0)
185 #define IS_TLS_GETTER(sptr) IS_TLS(sptr)
186 
187 #define CMPLXFUNC_C XBIT(49, 0x40000000)
188 
189 #define DLL_NONE   0x0
190 #define DLL_EXPORT 0x1
191 #define DLL_IMPORT 0x2
192 
193 typedef struct ADSC {
194   int   numdim;
195   int   scheck;
196   int   zbase;
197   SPTR  sdsc;
198   ILM_T *ilmp;
199   struct {
200     SPTR mlpyr;
201     SPTR lwbd;
202     SPTR upbd;
203   } b[1];
204 } ADSC;
205 
206 #define AD_DPTR(dtype) ((ADSC *)(aux.arrdsc_base+DTY((dtype)+2)))
207 #define AD_PTR(sptr) ((ADSC *) (aux.arrdsc_base + DTY(DTYPEG(sptr)+2)))
208 #define AD_NUMDIM(p)  ((p)->numdim)
209 #define AD_SCHECK(p) ((p)->scheck)
210 #define AD_ZBASE(p)  ((p)->zbase)
211 #define AD_SDSC(p)   ((p)->sdsc)
212 #define AD_ILMP(p)   ((p)->ilmp)
213 #define AD_MLPYR(p, i) ((p)->b[i].mlpyr)
214 #define AD_LWBD(p, i)  ((p)->b[i].lwbd)
215 #define AD_UPBD(p, i)  ((p)->b[i].upbd)
216 #define AD_NUMELM(p)  ((p)->b[AD_NUMDIM(p)].mlpyr)
217 
218 typedef struct ENTRY {
219   ISZ_T  stack_addr; /* available address on run-time stack  */
220   SPTR   ent_save;	/* sptr:
221                          * o  n10 - to cc array to hold saved ar's and
222                          *    excstat
223                          * o  x86 - to cc scalar if multiple entries.
224                          */
225   short  first_dr;	/* first data reg used as global  */
226   short           first_ar;	/* first address reg used as global  */
227   short           first_sp;	/* first float reg used as global  */
228   short           first_dp;	/* first double reg used as global  */
229   int             auto_array; /* static array used for auto vars, else 0 */
230   int             ret_var;   	/* sym of return value if passed as arg */
231   int             memarg_ptr; /* sym where memarg ptr is saved upon entry */
232   int             gr_area;    /* sym of where to save global regs */
233   INT             flags;	/* misc. target dependent flags */
234   char           *arasgn;	/* local ar (base pointer) ARASGN records */
235   char           *regset;	/* target dependent register set info */
236   char           *argset;	/* target dependent register set info */
237   SPTR            display;    /* sptr to an internal procedure's display
238                                * (i.e., the host procedure's stack frame).
239                                */
240   SPTR         uplevel;    /* sptr to an outlined function contains
241                             * addresses of uplevel variables /
242                             */
243   int             cgr;	/* index into the simplfied call graph info */
244   int     launch_maxthread, launch_minctasm;
245                         /* launch_bounds for CUDA Fortran. 0 means not set. */
246 } ENTRY;
247 
248 typedef struct NMLDSC {
249     int   sptr;
250     int   next;
251     int   lineno;
252 } NMLDSC;
253 
254 #define NML_SPTR(i)   aux.nml_base[i].sptr
255 #define NML_NEXT(i)   aux.nml_base[i].next
256 #define NML_LINENO(i) aux.nml_base[i].lineno
257 
258 /*****  Symbol List Item  *****/
259 
260 typedef struct SYMI {
261     int   sptr;
262     int   next;
263 } SYMI;
264 
265 #define SYMI_SPTR(i) aux.symi_base[i].sptr
266 #define SYMI_NEXT(i) aux.symi_base[i].next
267 
268 
269 typedef struct DVL {
270     int    sptr;
271     INT    conval;
272 } DVL;
273 
274 #define DVL_SPTR(i)   aux.dvl_base[i].sptr
275 #define DVL_CONVAL(i) aux.dvl_base[i].conval
276 
277 typedef struct AUX {
278    int    *dpdsc_base;
279    int     dpdsc_size;
280    int     dpdsc_avl;
281    int    *arrdsc_base;
282    int     arrdsc_size;
283    int     arrdsc_avl;
284    ENTRY  *entry_base;
285    int     entry_size;
286    int     entry_avail;
287    ENTRY  *curr_entry;
288    int     strdesc;
289    NMLDSC *nml_base;
290    int     nml_size;
291    int     nml_avl;
292    DVL    *dvl_base;
293    int     dvl_size;
294    int     dvl_avl;
295    SYMI   *symi_base;
296    int     symi_size;
297    int     symi_avl;
298    INT    *vcon_base;
299    int     vcon_size;
300    int     vcon_avl;
301    int     parregs;      /* Number of parallel regions  */
302    INT    *parsyms_base; /* Symbols in parallel regions */
303    int     parsyms_size;
304    int     parsyms_avl;
305    int     vtypes[TY_MAX+1][TY_VECT_MAXLEN];
306 } AUX;
307 
308 #define VCON_CONVAL(i) aux.vcon_base[i]
309 
310 #include "symacc.h"
311 
312 /*   symbol table data declarations:  */
313 
314 extern AUX aux;
315 
316 /* pointer-sized integer */
317 
318 #define __POINT_T DT_INT8
319 
320 /*  declarations required to access switch statement or computed goto lists: */
321 
322 typedef struct SWEL {
323     INT  val;
324     SPTR clabel;
325     int  next;
326 } SWEL;
327 
328 extern SWEL *switch_base;
329 
330 /**
331    \brief ...
332  */
333 ISZ_T get_isz_cval(int con);
334 
335 /**
336    \brief ...
337  */
338 char *getprint(int sptr);
339 
340 /**
341    \brief ...
342  */
343 char *parmprint(int sptr);
344 
345 /**
346    \brief Add a new symbol with same name as an existing symbol
347    \param oldsptr symbol to duplicate
348  */
349 SPTR adddupsym(SPTR oldsptr);
350 
351 /**
352    \brief Add a new symbol with given name
353    \param name  the symbol's name
354  */
355 SPTR addnewsym(const char *name);
356 
357 /**
358    \brief ...
359  */
360 int add_symitem(int sptr, int nxt);
361 
362 /**
363    \brief ...
364  */
365 int dbg_symdentry(int sptr);
366 
367 /**
368    \brief Create (or possibly reuse) a compiler created symbol whose name is of
369    the form . <pfx> dddd where dddd is the decimal representation of n.
370  */
371 SPTR getccssym(char *pfx, int n, SYMTYPE stype);
372 
373 /**
374    \brief Similar to getccssym, but storage class is an argument. Calls
375    getccssym if the storage class is not private; if private, a 'p' is appended
376    to the name.
377  */
378 SPTR getccssym_sc(char *pfx, int n, SYMTYPE stype, SC_KIND sc);
379 
380 /**
381    \brief ...
382  */
383 SPTR getccsym_copy(SPTR oldsptr);
384 
385 /**
386    \brief create (or possibly reuse) a compiler created symbol whose name is of
387    the form . <letter> dddd where dddd is the decimal representation of n.
388  */
389 SPTR getccsym(int letter, int n, SYMTYPE stype);
390 
391 /**
392    \brief Similar to getccsym, but storage class is an argument. Calls
393    getccsym if the storage class is not private; if private, a 'p' is
394    appended to the name.
395  */
396 SPTR getccsym_sc(int letter, int n, SYMTYPE stype, SC_KIND sc);
397 
398 /**
399    \brief Create (or possibly reuse) a compiler created temporary where the
400    caller constructs the name and passes the storage class as an argument.
401  */
402 SPTR getcctemp_sc(char *name, SYMTYPE stype, SC_KIND sc);
403 
404 /**
405    \brief ...
406  */
407 int get_entry_item(void);
408 
409 /**
410    \brief ...
411  */
412 SPTR getlab(void);
413 
414 /**
415    \brief Create (never reuse) a compiler created symbol whose name is of the
416    form . <letter> dddd where dddd is the decimal representation of n.
417  */
418 SPTR getnewccsym(int letter, int n, SYMTYPE stype);
419 
420 /**
421    \brief ...
422  */
423 SPTR get_semaphore(void);
424 
425 /**
426    \brief Enter character constant into symbol table
427    \param value is the character string value
428    \param length is the length of character string
429    \return a pointer to the character constant in the symbol table.
430 
431    If the constant was already in the table, returns a pointer to the existing
432    entry instead.
433  */
434 SPTR getstring(char *value, int length);
435 
436 /**
437    \brief Similar to getstring except the character string is null terminated
438  */
439 SPTR getntstring(char *value);
440 
441 SPTR getstringaddr(SPTR sptr);
442 
443 /**
444    \brief ...
445  */
446 int get_vcon0(DTYPE dtype);
447 
448 /**
449    \brief ...
450  */
451 int get_vcon1(DTYPE dtype);
452 
453 /**
454    \brief ...
455  */
456 SPTR get_vcon(INT *value, DTYPE dtype);
457 
458 /**
459    \brief get a vector constant of a zero which suits the element type
460  */
461 int get_vconm0(DTYPE dtype);
462 
463 /**
464    \brief ...
465  */
466 SPTR get_vcon_scalar(INT sclr, DTYPE dtype);
467 
468 /**
469    \brief ...
470  */
471 SPTR insert_sym_first(SPTR first);
472 
473 /**
474    \brief ...
475  */
476 SPTR insert_sym(SPTR first);
477 
478 /**
479    \brief ...
480  */
481 SPTR mk_prototype(const char *name, const char *attr, DTYPE resdt, int nargs,
482                   ...);
483 
484 /**
485    \brief ...
486  */
487 SPTR mk_prototype_llvm(const char *name, const char *attr, DTYPE resdt,
488                        int nargs, ...);
489 
490 /**
491    \brief ...
492  */
493 INT sign_extend(INT val, int width);
494 
495 /**
496    \brief ...
497  */
498 int tr_conval2g(char *fn, int ln, int s);
499 
500 /**
501    \brief ...
502  */
503 int tr_conval2p(char *fn, int ln, int s, int v);
504 
505 /**
506    \brief ...
507  */
508 SPTR get_acon3(SPTR sym, ISZ_T off, DTYPE dtype);
509 
510 /**
511    \brief ...
512  */
513 SPTR get_acon(SPTR sym, ISZ_T off);
514 
515 /**
516    \brief ...
517  */
518 SPTR getcon(INT *value, DTYPE dtype);
519 
520 /**
521    \brief ...
522  */
523 SPTR getsymbol(const char *name);
524 
525 /**
526    \brief ...
527  */
528 SPTR getsym(const char *name, int olength);
529 
530 /**
531    \brief ...
532  */
533 SPTR mkfunc(const char *nmptr);
534 
535 /**
536    \brief ...
537  */
538 void dmp_socs(int sptr, FILE *file);
539 
540 /**
541    \brief ...
542  */
543 void implicit_int(DTYPE default_int);
544 
545 /**
546    \brief Change settings for implicit variable types, character lengths
547    \param firstc   characters delimiting range
548    \param lastc    characters delimiting range
549    \param dtype    new value assigned to range
550  */
551 void newimplicit(int firstc, int lastc, DTYPE dtype);
552 
553 /**
554    \brief ...
555  */
556 void pop_scope(void);
557 
558 /**
559    \brief ...
560  */
561 void pop_sym(int sptr);
562 
563 /**
564    \brief ...
565  */
566 void reapply_implicit(void);
567 
568 /**
569    \brief ...
570  */
571 void setimplicit(int sptr);
572 
573 /**
574    \brief ...
575  */
576 void symdentry(FILE *file, int sptr);
577 
578 /**
579    \brief ...
580  */
581 void symdmp(FILE *dfil, bool full);
582 
583 /**
584    \brief ...
585  */
586 void sym_init(void);
587 
588 #ifdef __cplusplus
589 // FIXME - these are hacks to allow addition on DTYPEs
590 inline DTYPE operator+=(DTYPE d, int c)
591 {
592   return static_cast<DTYPE>(static_cast<int>(d) + c);
593 }
594 
595 inline int operator+(DTYPE d, int c)
596 {
597   return static_cast<int>(d) + c;
598 }
599 #endif
600 
601 #endif
602