1 /*
2  * Copyright (c) 2015-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 LLASSEM_H_
19 #define LLASSEM_H_
20 
21 #include "gbldefs.h"
22 #include "global.h"
23 #include "symtab.h"
24 #include "llutil.h"
25 
26 typedef struct DTLIST {
27   LL_Type *lltype;
28   int byval;
29 
30   /* XXX: sptr needs to go away, since fortran sptrs are only relevant for
31    * the function being compiled.  This is for homing
32    * (process_formal_arguments) support.  Which should only be called when
33    * this sptr data is valid.
34    */
35   SPTR sptr;
36   struct DTLIST *tail;
37   struct DTLIST *next;
38 } DTLIST;
39 
40 typedef struct uplevelpair {
41   int oldsptr;  /* sptr from ilm file */
42   SPTR newsptr; /* newsptr - from symbolxref[oldsptr] */
43   int newmem;   /* sptr member of struct for newsptr */
44 } UPLEVEL_PAIR;
45 
46 #define STACK_CAN_BE_32_BYTE_ALIGNED (aux.curr_entry->flags & 0x200)
47 #define ENFORCE_32_BYTE_STACK_ALIGNMENT (aux.curr_entry->flags |= 0x400)
48 
49 #define IS_STABS (XBIT(120, 0x20))
50 #define ASMFIL gbl.asmfil
51 
52 /** general length suitable for creating names from a symbol name during
53     assembly, e.g., 1 for null, 3 for extra '_' , * 4 for @### with mscall */
54 #define MXIDLN (3 * MAXIDLEN + 10)
55 
56 /**
57  * structure to represent items being dinit'd -- used to generate
58  * a sorted list of dinit items for a given common block or local
59  * variable.
60  */
61 typedef struct DSRT {
62   SPTR sptr;         ///< sym being init'd (could be structure)
63   ISZ_T offset;      ///< byte offset of item init'd
64   int sectionindex;  ///< Fortran - section index
65   long filepos;      ///< Fortran dinit file position for item's dinit(s)
66   int func_count;    ///< Fortran save/restore func_count
67   DTYPE dtype;       ///< used for C
68   int len;           ///< used for C - character
69   ISZ_T conval;      ///< used for C
70   struct DSRT *next; ///< next in list (sorted in ascending offset)
71   struct DSRT *ladd; ///< item last added - not used in C
72 } DSRT;
73 
74 char *get_local_overlap_var(void);
75 char *put_next_member(char *ptr);
76 ISZ_T put_skip(ISZ_T old, ISZ_T New);
77 
78 /*
79  * macros to get and put DSRT pointers in symbol table entry - this
80  * uses the XREF field
81  */
82 #define DSRTG(s) ((DSRT *)get_getitem_p(XREFLKG(s)))
83 #define DSRTP(s, v) XREFLKP(s, put_getitem_p(v))
84 
85 #define GET_DSRT (DSRT *)getitem(2, sizeof(DSRT))
86 
87 /* structures and routines to process assembler globals for the entire file */
88 
89 #define AG_HASHSZ 19
90 #define AG_SIZE(s) agb.s_base[s].size
91 #define AG_ALIGN(s) agb.s_base[s].align
92 #define AG_DSIZE(s) agb.s_base[s].dsize
93 #define AG_SYMLK(s) agb.s_base[s].symlk
94 #define AG_HASHLK(s) agb.s_base[s].hashlk
95 #define AG_NMPTR(s) agb.s_base[s].nmptr
96 #define AG_TYPENMPTR(s) agb.s_base[s].type_nmptr
97 #define AG_OLDNMPTR(s) agb.s_base[s].old_nmptr
98 #define AG_TYPEDESC(s) agb.s_base[s].typedesc /* Boolean */
99 #define AG_STYPE(s) agb.s_base[s].stype
100 #define AG_RET_LLTYPE(s) agb.s_base[s].ret_lltype
101 #define AG_LLTYPE(s) agb.s_base[s].lltype
102 #define AG_DTYPE(s) agb.s_base[s].dtype
103 #define AG_DTYPESC(s) agb.s_base[s].dtypesc
104 #define AG_SC(s) agb.s_base[s].sc /* Storage class */
105 #define AG_ALLOC(s) agb.s_base[s].alloc
106 #define AG_REF(s) agb.s_base[s].ref
107 #define AG_DEFD(s) agb.s_base[s].defd
108 #define AG_DEVICE(s) agb.s_base[s].device
109 #define AG_ISMOD(s) agb.s_base[s].ismod
110 #define AG_ISTLS(s) agb.s_base[s].istls
111 #define AG_NEEDMOD(s) agb.s_base[s].needmod
112 #define AG_ISCTOR(s) agb.s_base[s].ctor
113 #define AG_ISIFACE(s) agb.s_base[s].iface
114 #define AG_FINAL(s) agb.s_base[s].final
115 #define AG_UPLEVEL_AVL(s) agb.s_base[s].uplevel_avl
116 #define AG_UPLEVEL_SZ(s) agb.s_base[s].uplevel_sz
117 #define AG_UPLEVELPTR(s) agb.s_base[s].uplist
118 #define AG_UPLEVEL_OLD(s, i) agb.s_base[s].uplist[i].oldsptr
119 #define AG_UPLEVEL_NEW(s, i) agb.s_base[s].uplist[i].newsptr
120 #define AG_UPLEVEL_MEM(s, i) agb.s_base[s].uplist[i].newmem
121 #define AG_DLL(s) agb.s_base[s].dll
122 #define AG_NAME(s) agb.n_base + agb.s_base[s].nmptr
123 #define AG_TYPENAME(s) agb.n_base + agb.s_base[s].type_nmptr
124 #define AG_OLDNAME(s) agb.n_base + agb.s_base[s].old_nmptr
125 #define AG_ARGDTLIST(s) agb.s_base[s].argdtlist
126 #define AG_ARGDTLIST_LENGTH(s) agb.s_base[s].n_argdtlist
127 #define AG_ARGDTLIST_IS_VALID(s) agb.s_base[s].argdtlist_is_set
128 #define AG_OBJTODBGLIST(s) agb.s_base[s].cmblk_mem_mdnode_list
129 
130 #define FPTR_HASHLK(s) fptr_local.s_base[s].hashlk
131 #define FPTR_IFACENMPTR(s) fptr_local.s_base[s].ifacenmptr
132 #define FPTR_IFACENM(s) fptr_local.n_base + fptr_local.s_base[s].ifacenmptr
133 #define FPTR_NMPTR(s) fptr_local.s_base[s].nmptr
134 #define FPTR_NAME(s) fptr_local.n_base + fptr_local.s_base[s].nmptr
135 #define FPTR_SYMLK(s) fptr_local.s_base[s].symlk
136 
137 LL_Value *gen_ptr_offset_val(int, LL_Type *, char *);
138 
139 /**
140    \brief llassem global symbol table entries
141  */
142 typedef struct {
143   ISZ_T size;  /**< max size of common block in file
144                   if entry/proc, 1 => defd, 0 => proc */
145   ISZ_T dsize; /**< size of common block when init'd */
146   INT nmptr;
147   INT type_nmptr;  /**< Used for external function */
148   INT farg_nmptr;  /**< make all function that is not defined in same file
149                       vararg with first argument specified if any */
150   INT old_nmptr;   /**< Used for interface to keep original function name */
151   INT align;       /**< alignment for BIND(C) variables */
152   int symlk;       /**< used to link ST_CMBLK and ST_PROC */
153   SPTR hashlk;     /**< hash collision field */
154   int dtype;       /**< used for keep track dtype which is created for static/
155                       bss area (only for AGL ag-local) */
156   int dtypesc;     /**< dtype scope */
157   int n_argdtlist; /**< Number of items in argdtlist */
158   bool argdtlist_is_set; /**< Argdtlist has built, perhaps with 0 args */
159   char stype;            /**< ST_ of global */
160   char sc;               /**< SC_ of global */
161   char alloc;            /**< ALLOCATABLE flag */
162   char dll;              /**< DLL_NONE, DLL_EXPORT, DLL_IMPORT */
163   LL_Type *lltype;       /**< LLVM representation of the ag symbol */
164   LL_Type *ret_lltype;   /**< If this is a func this is the return type */
165   DTLIST *argdtlist;     /**< linked listed of argument lltype */
166   LL_ObjToDbgList *cmblk_mem_mdnode_list; ///< linked listed of cmem mdnode
167   int uplevel_avl;
168   int uplevel_sz;
169   UPLEVEL_PAIR *uplist; /**< uplevel list for internal procecure */
170   unsigned ref : 1;     /**< ST_PROC is referenced */
171   unsigned defd : 1;    /**< module ST_CMBLK is defined in file */
172   unsigned device : 1;  /**< CUDA device routine */
173   unsigned ismod : 1;
174   unsigned needmod : 1;
175   unsigned ctor : 1;     /**< set if this routine has attribute constructor */
176   unsigned typedesc : 1; /**< set if this variable is a type descriptor */
177   unsigned iface : 1;    /**< set if this is part of interface */
178   unsigned final : 1;    /**< set if this is final table */
179   unsigned istls : 1;    /**< set if this is TLS */
180 } AG;
181 
182 /**
183    \brief storage allocation structure for assem's symtab
184  */
185 typedef struct AGB_t {
186   AG *s_base;   /**< pointer to table of common block nodes */
187   int s_size;   /**< size of CM table */
188   int s_avl;    /**< currently available entry */
189   char *n_base; /**< pointer to names space */
190   int n_size;
191   int n_avl;
192   SPTR hashtb[AG_HASHSZ];
193 } AGB_t;
194 
195 extern AGB_t agb;
196 
197 /** similar to AG struct but smaller */
198 typedef struct {
199   INT nmptr;
200   INT ifacenmptr;
201   int hashlk;
202   int symlk;
203 } FPTRSYM;
204 
205 /** storage for function pointer */
206 typedef struct fptr_local_t {
207   FPTRSYM *s_base;
208   int s_size;
209   int s_avl;
210   char *n_base; /* pointer to names space */
211   int n_size;
212   int n_avl;
213   int hashtb[AG_HASHSZ];
214 } fptr_local_t;
215 
216 extern fptr_local_t fptr_local;
217 
218 extern DSRT *lcl_inits;          /* head list of DSRT's for local variables */
219 extern DSRT *section_inits;      /* head list of DSRT's for initialized
220                                            variables in named sections */
221 extern DSRT *extern_inits;       /* head list of DSRT's for BIND(C) module
222                                            variables */
223 extern char static_name[MXIDLN]; /* name of STATIC area for a function */
224 extern int first_data;
225 
226 struct sec_t {
227   const char *name;
228   int align;
229 };
230 
231 /* ag entries */
232 extern int ag_cmblks;  /* list of common blocks in file */
233 extern int ag_procs;   /* list of procs in file */
234 extern int ag_other;   /* list of other externals in file */
235 extern int ag_global;  /* list of symbols that need to be declared
236                                  global */
237 extern int ag_typedef; /* list of derived type that need to be
238                                  declared  */
239 extern int ag_static;  /* keep name and type of static */
240 extern int ag_intrin;  /* intrinsic list generated by the bridge and
241                                  has no sptr */
242 extern int ag_local;   /* dummy arguments which is a subroutine -
243                                  need its signature and type */
244 extern int ag_funcptr; /* list of function pointer - should be a member
245                                  of user defined type. Currently keep both
246                                  LOCAL(any?) and STATIC in same list */
247 
248 void put_i32(int);
249 void put_string_n(char *, ISZ_T, int);
250 void put_short(int);
251 void put_int4(INT);
252 
253 #if defined(TARGET_LLVM_X8664) || defined(TARGET_LLVM_POWER) || defined(TARGET_LLVM_ARM64)
254 #define DIR_LONG_SIZE 64
255 #else
256 #define DIR_LONG_SIZE 32
257 #endif
258 
259 #define MAXARGLEN 256
260 
261 void ll_override_type_string(LL_Type *llt, const char *str);
262 int alignment(DTYPE);
263 int add_member_for_llvm(int, int, DTYPE, ISZ_T);
264 LL_Type *update_llvm_typedef(DTYPE dtype, int sptr, int rank);
265 int llvm_get_unique_sym(void);
266 void align_func(void);
267 void put_global(char *name);
268 void put_func_name(int sptr);
269 void put_type(int sptr);
270 void init_huge_tlb(void);
271 void init_flushz(void);
272 void init_daz(void);
273 void init_ktrap(void);
274 ISZ_T get_socptr_offset(int);
275 #if defined(PG0CL)
276 #define llassem_end_func(ignore1, arg2) assem_end_func(arg2)
277 #else
278 #define llassem_end_func(arg1, arg2) lldbg_function_end(arg1, arg2)
279 #endif
280 
281 LL_Type *make_generic_dummy_lltype(void);
282 LL_Type *get_local_overlap_vartype(void);
283 
284 #ifdef OMP_OFFLOAD_LLVM
285 /**
286    \brief ...
287  */
288 void ompaccel_write_sharedvars(void);
289 #endif
290 
291 /**
292    \brief ...
293  */
294 bool get_byval_from_argdtlist(const char *argdtlist);
295 
296 /**
297    \brief ...
298  */
299 bool has_typedef_ag(int gblsym);
300 
301 /**
302    \brief ...
303  */
304 bool is_llvmag_entry(int gblsym);
305 
306 /**
307    \brief ...
308  */
309 bool is_llvmag_iface(int gblsym);
310 
311 /**
312    \brief ...
313  */
314 bool is_typedesc_defd(SPTR sptr);
315 
316 /**
317    \brief ...
318  */
319 char *getaddrdebug(SPTR sptr);
320 
321 /**
322    \brief ...
323  */
324 char *get_ag_name(int gblsym);
325 
326 /**
327    \brief ...
328  */
329 char *get_ag_typename(int gblsym);
330 
331 /**
332    \brief ...
333  */
334 char *get_argdtlist(int gblsym);
335 
336 /**
337    \brief return external name for procedure
338  */
339 char *getextfuncname(SPTR sptr);
340 
341 /**
342    \brief ...
343  */
344 char *get_llvm_name(SPTR sptr);
345 
346 /**
347    \brief ...
348  */
349 char *get_main_progname(void);
350 
351 /**
352    \brief ...
353  */
354 char *get_next_argdtlist(char *argdtlist);
355 
356 /**
357    \brief ...
358  */
359 char *getsname(SPTR sptr);
360 
361 /**
362    \brief ...
363  */
364 char *get_string_constant(int sptr);
365 
366 /**
367    \brief ...
368  */
369 DTYPE get_ftn_typedesc_dtype(SPTR sptr);
370 
371 /**
372    \brief ...
373  */
374 int add_ag_typename(int gblsym, const char *typeName);
375 
376 /**
377    \brief ...
378  */
379 SPTR find_ag(const char *ag_name);
380 
381 /**
382    \brief ...
383  */
384 int find_funcptr_name(SPTR sptr);
385 
386 /**
387    \brief ...
388  */
389 int get_ag_argdtlist_length(int gblsym);
390 
391 /**
392    \brief ...
393  */
394 SPTR get_ag(SPTR sptr);
395 
396 /**
397    \brief ...
398  */
399 int get_bss_addr(void);
400 
401 /**
402    \brief ...
403  */
404 SPTR get_dummy_ag(SPTR sptr);
405 
406 /**
407    \brief ...
408  */
409 int get_hollerith_size(int sptr);
410 
411 /**
412    \brief ...
413  */
414 SPTR get_intrin_ag(char *ag_name, DTYPE dtype);
415 
416 /**
417    \brief ...
418  */
419 SPTR get_llvm_funcptr_ag(SPTR sptr, const char *ag_name);
420 
421 /**
422    \brief ...
423  */
424 int get_private_size(void);
425 
426 /**
427    \brief ...
428  */
429 SPTR get_sptr_from_argdtlist(char *argdtlist);
430 
431 /**
432    \brief ...
433  */
434 int get_sptr_uplevel_address(int sptr);
435 
436 /**
437    \brief ...
438  */
439 int get_stack_size(void);
440 
441 /**
442    \brief ...
443  */
444 SPTR get_typedef_ag(char *ag_name, char *typeName);
445 
446 /**
447    \brief ...
448  */
449 int get_uplevel_address_size(void);
450 
451 /**
452    \brief ...
453  */
454 int has_valid_ag_argdtlist(int gblsym);
455 
456 /**
457    \brief determine if the address represented by \p syma, an address constant,
458    is cache aligned.
459  */
460 int is_cache_aligned(SPTR syma);
461 
462 /**
463    \brief ...
464  */
465 int ll_shallow_copy_uplevel(SPTR hostsptr, SPTR olsptr);
466 
467 /**
468    Return the AG number associated to the local sptr value:
469    1) Search local-fnptr-table of function pointers
470    2) Get the ag name from (1)
471    3) Get the gblsym using the ag name from (2)
472    4) Return the AG gblsym from (3)
473  */
474 SPTR local_funcptr_sptr_to_gblsym(SPTR sptr);
475 
476 /**
477    \brief ...
478  */
479 DTYPE make_uplevel_arg_struct(void);
480 
481 /**
482    \brief the 32-byte alignment of the address constant \p acon_sptr
483    \param acon_sptr
484    \return the alignment or -1 if it's unknown.
485  */
486 int runtime_32_byte_alignment(SPTR acon_sptr);
487 
488 /**
489    \brief determine the alignment of the address represented by syma, an address
490    constant, within a cache-aligned container
491 
492    \return -1 if unknown or the byte boundary of the address
493 
494    For example, given a single precision quantity and a container which is
495    16-byte aligned the following values are possible:
496    \li 0   aligned with the beginning of the container.
497    \li 4   multiple of 4 bytes from the beginning of the container.
498    \li 8   multiple of 8 bytes from the beginning of the container.
499    \li 12  multiple of 12 bytes from the beginning of the container.
500  */
501 int runtime_alignment(SPTR syma);
502 
503 /**
504    \brief ...
505  */
506 LL_ObjToDbgList **llassem_get_objtodbg_list(SPTR sptr);
507 
508 /**
509    \brief ...
510  */
511 LL_Type *get_ag_lltype(int gblsym);
512 
513 /**
514    \brief ...
515  */
516 LL_Type *get_ag_return_lltype(int gblsym);
517 
518 /**
519    \brief ...
520  */
521 LL_Type *get_lltype_from_argdtlist(char *argdtlist);
522 
523 /**
524    \brief ...
525  */
526 unsigned align_of_var(SPTR sptr);
527 
528 /**
529    If arg_num in [1-n] where 1 is the first argument passed and the function
530    contains n arguments.  If arg_num is 0, the function's return value.
531 
532    Called by build_routine_parameters()
533  */
534 void addag_llvm_argdtlist(SPTR gblsym, int arg_num, SPTR arg_sptr,
535                           LL_Type *lltype);
536 
537 /**
538    \brief ...
539  */
540 void add_aguplevel_oldsptr(void);
541 
542 /**
543    \brief ...
544  */
545 void _add_llvm_uplevel_symbol(int oldsptr);
546 
547 /**
548    \brief ...
549  */
550 void add_uplevel_to_host(int *ptr, int cnt);
551 
552 /**
553    \brief ...
554  */
555 void arg_is_refd(int sptr);
556 
557 /**
558    \brief ...
559  */
560 void assem_begin_func(SPTR sptr);
561 
562 /**
563    \brief ...
564  */
565 void assemble_end(void);
566 
567 /**
568    \brief ...
569  */
570 void assemble_init(int argc, char *argv[], char *cmdline);
571 
572 /**
573    \brief ...
574  */
575 void assemble(void);
576 
577 /**
578    \brief ...
579  */
580 void assem_data(void);
581 
582 /**
583    \brief ...
584  */
585 void assem_dinit(void);
586 
587 /**
588    \brief ...
589  */
590 void assem_emit_align(int n);
591 
592 /**
593    \brief ...
594  */
595 void assem_emit_file_line(int findex, int lineno);
596 
597 /**
598    \brief ...
599  */
600 void assem_emit_line(int findex, int lineno);
601 
602 /**
603    \brief ...
604  */
605 void assem_end(void);
606 
607 /**
608    \brief ...
609  */
610 void assem_init(void);
611 
612 /**
613    \brief ...
614  */
615 void assem_put_linux_trace(int sptr);
616 
617 /**
618    \brief ...
619  */
620 void create_static_base(int num);
621 
622 /**
623    \brief ...
624  */
625 void create_static_name(char *name, int usestatic, int num);
626 
627 /**
628    \brief ...
629  */
630 void deleteag_llvm_argdtlist(int gblsym);
631 
632 /**
633    \brief ...
634  */
635 void fix_equiv_locals(SPTR loc_list, ISZ_T loc_addr);
636 
637 /**
638    \brief ...
639  */
640 void fix_equiv_statics(SPTR loc_list, ISZ_T loc_addr, bool dinitflg);
641 
642 /**
643    \brief ...
644  */
645 void fix_private_sym(int sptr);
646 
647 /**
648    \brief ...
649  */
650 void _fixup_llvm_uplevel_symbol(void);
651 
652 /**
653    \brief ...
654  */
655 void hostsym_is_refd(SPTR sptr);
656 
657 /**
658    \brief ...
659  */
660 void llvm_funcptr_store(SPTR sptr, char *ag_name);
661 
662 /**
663    \brief ...
664  */
665 void load_uplevel_addresses(SPTR display_temp);
666 
667 /**
668    \brief ...
669  */
670 void put_fstr(SPTR sptr, int add_null);
671 
672 /**
673    \brief ...
674  */
675 void put_section(int sect);
676 
677 /**
678    \brief ...
679  */
680 void set_ag_argdtlist_is_valid(int gblsym);
681 
682 /**
683    \brief ...
684  */
685 void set_ag_lltype(int gblsym, LL_Type *llt);
686 
687 /**
688    \brief ...
689  */
690 void set_ag_return_lltype(int gblsym, LL_Type *llt);
691 
692 /**
693    \brief ...
694  */
695 void set_bss_addr(int size);
696 
697 /**
698    \brief ...
699  */
700 void set_llvmag_entry(int gblsym);
701 
702 /**
703    \brief ...
704  */
705 void set_llvm_iface_oldname(int gblsym, char *nm);
706 
707 /**
708    \brief ...
709  */
710 void set_private_size(ISZ_T sz);
711 
712 /**
713    \brief ...
714  */
715 void sym_is_refd(SPTR sptr);
716 
717 /**
718    \brief Writes libomptarget related initialization.
719  */
720 void write_libomtparget(void);
721 
722 #endif
723