1 /*
2  * Copyright (c) 2002-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 /** \file
19  * \brief Assembler module
20  *
21  * Define those functions and data items which are defined in the assembler
22  * module, assem.c, and exported to other modules of the compiler.  (X86 and
23  * Hammer targets)
24 */
25 
26 /* ---------- Functions and data used by the Code Generator: ------ */
27 
28 extern char *comment_char;
29 
30 char *getsname(SPTR);
31 char *getsname2(int);
32 void sym_is_refd(SPTR);
33 
34 extern void assem_init(void);
35 /*  called when processing of user function is begun by the CG */
36 
37 extern void assem_begin_func(int func_sptr);
38 /*  called when ready to begin emitting code for the function, also
39     at each Fortran ENTRY. */
40 
41 extern void assem_pc(int func_sptr, int arg1_offset, int base_reg);
42 /*  called after entry code generated - generates precision control
43     instructions, if needed.
44     arg1_offset - offset from base_reg to arguments argc and argv.
45     base_reg - stack pointer or frame pointer register.
46     The values of the last two arguments are only used when
47     PGC && I386 && WINNT  */
48 
49 extern void assem_mxcsr(int func_sptr);
50 /*  called immediately after assem_pc(), to generate SIMD
51     control instructions.  */
52 
53 extern void assem_user_entry(int label_sptr, int lineno, int firstline);
54 /*  called after all entry code has been emitted (when an ENLAB block
55     is encountered).  Indicates the end of the entry code and the
56     point where user debugger breakpoints are set.  */
57 
58 extern void assem_emit_line(int findex, int lineno);
59 extern void assem_emit_file_line(int findex, int lineno);
60 /*  called just before emitting code for each basic block  */
61 
62 extern void assem_end_func(int func_sptr);
63 /*  called after emitting all code, including exit code  */
64 
65 extern void assem_data(void);
66 /*  called after assem_end_func()  */
67 
68 extern void assem_end(void);
69 /*  called after assem_data()  */
70 
71 /* profiling support; these 3 functions are called IFF flg.profile: */
72 
73 void prof_rouent(int func_sptr);
74 /*  called immediately after assem_mxcsr() (after emitting the
75     entry code for a function)      */
76 
77 void prof_linent(int lineno, int loop_flag, int blocknum);
78 /*  called after assem_emit_line(), before emitting the machine
79     instructions for a block.  Called only if line profiling is
80     requested (flg.profile == 2) and unix-style profiling is not
81     requested (xbit(119, 2)).
82     Not called if this is an entry block.
83     loop_flag - TRUE if this block is the head of a loop.
84     blocknum  - bih number of this block    */
85 
86 void prof_rouret(void);
87 /*  called just before emitting the exit code for a function.
88     Not called if unix-style profiling is requested.        */
89 
90 extern int get_private_size(void);
91 
92 extern void add_init_routine(char *initroutine);
93 /* Create a .init section to call an initialization function */
94 
95 void create_static_base(int name);
96 
97 #define STR_SEC 0
98 #define RO_SEC 1
99 #define DATA_SEC 2
100 #define TEXT_SEC 3
101 #define INIT_SEC 4
102 #define DRECTVE_SEC 5
103 #define PDATA_SEC 6
104 #define XDATA_SEC 7
105 #define TRACE_SEC 8
106 #define BSS_SEC 9
107 #define GXX_EH_SEC 10
108 /* gnu linkonce.t : weak text */
109 /* LNK_T_SEC : gcc version 3.99 and below */
110 /* LNK_T_SEC4 : gcc version 4.0  and above */
111 #define LNK_T_SEC 11
112 /* gnu linkonce.d weak comdata data*/
113 #define LNK_D_SEC 12
114 /* gnu linkonce.r  weak readonly text for jump tables*/
115 #define LNK_R_SEC 13
116 /* gnu older version use ".section .rodata" for jump tables */
117 /* c++ IA64_ABI  weak rodata for virtual tables */
118 #define RO_DATA_WEAK_SEC 14
119 /* c++ IA64_ABI  weak bss for static init variables in template classes */
120 #define DATA_WEAK_SEC 15
121 #define BSS_WEAK_SEC 16
122 #define RO_DATA_SEC 17
123 #define NVIDIA_FATBIN_SEC 18
124 #define NVIDIA_MODULEID_SEC 19
125 #define NVIDIA_RELFATBIN_SEC 20
126 #define NVIDIA_OLDFATBIN_SEC 21
127 #define GNU_NAMED_SEC 22
128 #define OMP_OFFLOAD_SEC 23
129 
130 #define HAS_TLS_SECTIONS 1
131 
132 #if defined(HAS_TLS_SECTIONS)
133 /* .tdata or .tbss for thread local storage */
134 #define TDATA_SEC 23
135 #define TBSS_SEC 24
136 #define TDATA_WEAK_SEC 25
137 #define TBSS_WEAK_SEC 26
138 #define DATA_SECG(sptr) (IS_TLS(sptr) ? TDATA_SEC : DATA_SEC)
139 #define BSS_SECG(sptr) (IS_TLS(sptr) ? TBSS_SEC : BSS_SEC)
140 #else
141 #define TDATA_SEC DATA_SEC
142 #define TBSS_SEC BSS_SEC
143 #define TDATA_WEAK_SEC DATA_WEAK_SEC
144 #define TBSS_WEAK_SEC BSS_WEAK_SEC
145 #define DATA_SECG(sptr) DATA_SEC
146 #define BSS_SECG(sptr) BSS_SEC
147 #endif
148 
149 #if !defined(TARGET_OSX)
150 #define ULABPFX ".L"
151 #else
152 #define ULABPFX "L."
153 #endif
154 
155 extern char *comment_char;
156 extern char *immed_char;
157 extern char *labpfx;
158 
159 #define EMIT_INSTR_EXT(op, ext, op1, op2) emit_instr(#op #ext, op1, op2)
160 
161 /* Conceptually part of assem.c, these filter functions are defined in
162    cgassem.c because C and Fortran have separate assem.c files.         */
163 
164 extern void emit_instr(const char *, const char *, const char *);
165 /*	emit instruction to assembly file */
166 
167 extern void emit_label(char *);
168 /*	output a label to assembly file */
169 
170 extern char *hex(int num, int pad);
171 /*  returns a string with num formatted as a hex number padded
172     by pad (set pad to 0 if no padding is required) */
173 
174 extern char *imm(int num);
175 /*  returns a string with num formatted as an immediate */
176 
177 extern char *imm_isz(ISZ_T);
178 /*  returns a string with num, possibly > MAX_INT, formatted as an
179     immediate */
180 
181 extern char *imm_hex(int num, int pad);
182 /*  returns a string with num formatted as an immediate hex
183     number padded by pad zeroes   */
184 
185 extern char *mem(char *r);
186 /*  returns a string with r formatted for memory indirection */
187 
188 extern char *sib(char *base, char *idx, int ss);
189 /*  returns a string in the appropriate scale-index-base (SIB)
190     format */
191 
192 extern void create_static_name(char *name, int usestatic, int num);
193 
194 #define EMIT_VZEROUPPER                                             \
195   {                                                                 \
196     if (!XBIT(164, 0x100000) &&                                     \
197         (XBIT(164, 0x2000000) || !TEST_FEATURE(FEATURE_SIMD128)) && \
198         mach.feature[FEATURE_AVX])                                  \
199       emit_instr("vzeroupper", NULL, NULL);                         \
200   }
201 
202 #define ASM_VZEROUPPER                                              \
203   {                                                                 \
204     if (!XBIT(164, 0x100000) &&                                     \
205         (XBIT(164, 0x2000000) || !TEST_FEATURE(FEATURE_SIMD128)) && \
206         mach.feature[FEATURE_AVX])                                  \
207       fprintf(ASMFIL, "\tvzeroupper\n");                            \
208   }
209