1 /*
2 * Copyright (c) 1994-2019, 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 ILI_H_
19 #define ILI_H_
20
21 /**
22 \file
23 \brief ILI header file - x86-64 version.
24 */
25
26 #ifndef ILITP_UTIL /* don't include if building ilitp utility prog*/
27 #include "global.h"
28 #include "symtab.h"
29 #include "iliatt.h" /* defines ILI_OP */
30 #else
31 typedef unsigned short ILI_OP;
32 #endif
33
34 #include "atomic_common.h"
35
36 #ifndef MAX_OPNDS
37 #define MAX_OPNDS 5 /* Max number of operands for an ili */
38 #endif
39
40 /***** ILI Declarations *****/
41
42 typedef struct {
43 ILI_OP opc;
44 /* practically all hosts will insert 2 bytes of padding here. */
45 int hshlnk;
46 int count;
47 int visit;
48 int alt;
49 int opnd[MAX_OPNDS];
50 int vlist; /* linked list of ILI visited by a traversal */
51 int tndx;
52 int tndx2;
53 int lili; /* CG: set to the ILI's linear ILI. This field must be 0
54 * on entry to function 'schedule()'. */
55 } ILI;
56
57 typedef struct {
58 STG_MEMBERS(ILI);
59 } ILIB;
60
61 extern ILIB ilib;
62
63 #define ILI_REPL(i) ilib.stg_base[i].count
64 #define ILI_OPC(i) ((ILI_OP)ilib.stg_base[i].opc)
65 #define ILI_OPCP(i, j) ilib.stg_base[i].opc = (j)
66 #define ILI_HSHLNK(i) ilib.stg_base[i].hshlnk
67 #define ILI_VISIT(i) ilib.stg_base[i].visit
68 #define ILI_ALT(i) ilib.stg_base[i].alt
69 #define ILI_COUNT(i) ilib.stg_base[i].count
70 #define ILI_RAT(i) ilib.stg_base[i].count
71 #define ILI_OPND(i, opn) ilib.stg_base[i].opnd[(opn)-1]
72 #define ILI_VLIST(i) ilib.stg_base[i].vlist
73 #define ILI_TNDX(i) ilib.stg_base[i].tndx
74 #define ILI_TNDX2(i) ilib.stg_base[i].tndx2
75 #define ILI_LILI(i) ilib.stg_base[i].lili
76
77 #ifndef ILITP_UTIL
78 #ifdef __cplusplus
ILI_SymOPND(int i,int opn)79 inline SPTR ILI_SymOPND(int i, int opn) {
80 return static_cast<SPTR>(ILI_OPND(i, opn));
81 }
82
ILI_DTyOPND(int i,int opn)83 inline DTYPE ILI_DTyOPND(int i, int opn) {
84 return static_cast<DTYPE>(ILI_OPND(i, opn));
85 }
86 #else
87 #define ILI_SymOPND ILI_OPND
88 #define ILI_DTyOPND ILI_OPND
89 #endif
90 #endif
91
92 /***** ILI Attributes Declarations *****/
93
94 typedef struct {
95 char *name; /* ili name */
96 char *opcod; /* machine instruction mnemonic (CG only) */
97 short oprs; /* number of operands */
98 unsigned short attr; /* AT attributes. e.g. cse, dom, -
99 * Field size (right to left):
100 * 4 -- IL_TYPE
101 * 1 -- IL_COMM
102 * 5 -- IL_RES
103 * 2 -- IL_DOM/CSEG
104 * 1 -- IL_SSENME
105 * 1 -- IL_VECT
106 * ------------------
107 * 14 -- total
108 */
109 /* x86-64 code generator info:
110 */
111 unsigned notCG : 1;
112 unsigned CGonly : 1;
113 unsigned notAILI : 1;
114 unsigned terminal : 1;
115 unsigned move : 1;
116 unsigned memdest : 1;
117 unsigned ccarith : 1;
118 unsigned cclogical : 1;
119 unsigned ccmod : 1;
120 unsigned shiftop : 1;
121 unsigned memarg : 1;
122 unsigned ssedp : 1;
123 unsigned ssest : 1;
124 unsigned conditional_branch : 1;
125 unsigned sse_avx : 1; /* ILI can generate SSE or AVX instructions */
126 unsigned avx_only : 1; /* ILI can only generate AVX instructions */
127 unsigned avx_special : 1; /* AVX version is a special case */
128 unsigned avx3_special : 1; /* AVX3 version is a special case */
129 unsigned asm_special : 1;
130 unsigned asm_nop : 1;
131 unsigned accel : 1;
132
133 unsigned short replaceby;
134 char size; /* can be 'b', 'w', 'l', 'q' or 'y', or 0 if unspecified */
135
136 char oprflag[MAX_OPNDS]; /* ILIO_ type of each opnd. See IL_OPRFLAG */
137 } ILIINFO;
138
139 extern ILIINFO ilis[];
140
141 typedef enum ILIO_KIND {
142 ILIO_NULL = 0,
143 ILIO_SYM = 1,
144 ILIO_STC = 4,
145 ILIO_OFF = 5,
146 ILIO_NME = 6,
147 ILIO_IR = 7,
148 ILIO_HP = 8,
149 ILIO_SP = 9,
150 ILIO_DP = 10,
151 ILIO_CS = 11,
152 ILIO_CD = 12,
153 ILIO_AR = 13,
154 ILIO_KR = 14,
155 ILIO_XMM = 15, /* xmm register number */
156 ILIO_X87 = 16,
157 ILIO_DOUBLEDOUBLE = 17,
158 ILIO_FLOAT128 = 18,
159 ILIO_LNK = 19,
160 ILIO_IRLNK = 20,
161 ILIO_HPLNK = 21,
162 ILIO_SPLNK = 22,
163 ILIO_DPLNK = 23,
164 ILIO_ARLNK = 24,
165 ILIO_KRLNK = 25,
166 ILIO_QPLNK = 26,
167 ILIO_CSLNK = 27,
168 ILIO_CDLNK = 28,
169 ILIO_CQLNK = 29,
170 ILIO_128LNK = 30,
171 ILIO_256LNK = 31,
172 ILIO_512LNK = 32,
173 ILIO_X87LNK = 33,
174 ILIO_DOUBLEDOUBLELNK = 34,
175 ILIO_FLOAT128LNK = 35
176 } ILIO_KIND;
177
178 #define ILIO_MAX 35
179 #define ILIO_ISLINK(n) ((n) >= ILIO_IRLNK)
180
181 /* Reflexive defines */
182 #define ILIO_NULL ILIO_NULL
183 #define ILIO_SYM ILIO_SYM
184 #define ILIO_STC ILIO_STC
185 #define ILIO_OFF ILIO_OFF
186 #define ILIO_NME ILIO_NME
187 #define ILIO_IR ILIO_IR
188 #define ILIO_HP ILIO_HP
189 #define ILIO_SP ILIO_SP
190 #define ILIO_DP ILIO_DP
191 #define ILIO_CS ILIO_CS
192 #define ILIO_CD ILIO_CD
193 #define ILIO_AR ILIO_AR
194 #define ILIO_KR ILIO_KR
195 #define ILIO_XMM ILIO_XMM
196 #define ILIO_X87 ILIO_X87
197 #define ILIO_DOUBLEDOUBLE ILIO_DOUBLEDOUBLE
198 #define ILIO_FLOAT128 ILIO_FLOAT128
199 #define ILIO_LNK ILIO_LNK
200 #define ILIO_IRLNK ILIO_IRLNK
201 #define ILIO_HPLNK ILIO_HPLNK
202 #define ILIO_SPLNK ILIO_SPLNK
203 #define ILIO_DPLNK ILIO_DPLNK
204 #define ILIO_ARLNK ILIO_ARLNK
205 #define ILIO_KRLNK ILIO_KRLNK
206 #define ILIO_QPLNK ILIO_QPLNK
207 #define ILIO_CSLNK ILIO_CSLNK
208 #define ILIO_CDLNK ILIO_CDLNK
209 #define ILIO_CQLNK ILIO_CQLNK
210 #define ILIO_128LNK ILIO_128LNK
211 #define ILIO_256LNK ILIO_256LNK
212 #define ILIO_512LNK ILIO_512LNK
213 #define ILIO_X87LNK ILIO_X87LNK
214 #define ILIO_DOUBLEDOUBLELNK ILIO_DOUBLEDOUBLELNK
215 #define ILIO_FLOAT128LNK ILIO_FLOAT128LNK
216
217 /* ILIINFO.attr field definitions. */
218 #define ILIA_NULL 0
219
220 #define ILIA_COMM 1 /* comm field */
221
222 /* result type field */
223 typedef enum ILIA_RESULT {
224 ILIA_TRM = 0,
225 ILIA_LNK = 1,
226 ILIA_IR = 2,
227 ILIA_HP = 3,
228 ILIA_SP = 4,
229 ILIA_DP = 5,
230 ILIA_AR = 6,
231 ILIA_KR = 7,
232 ILIA_CC = 8,
233 ILIA_FCC = 9,
234 ILIA_QP = 10,
235 ILIA_CS = 11,
236 ILIA_CD = 12,
237 ILIA_CQ = 13,
238 ILIA_128 = 14,
239 ILIA_256 = 15,
240 ILIA_512 = 16,
241 ILIA_X87 = 17,
242 ILIA_DOUBLEDOUBLE = 18,
243 ILIA_FLOAT128 = 19
244 } ILIA_RESULT;
245
246 #define ILIA_MAX 19
247
248 /* Reflexive defines */
249 #define ILIA_TRM ILIA_TRM
250 #define ILIA_LNK ILIA_LNK
251 #define ILIA_IR ILIA_IR
252 #define ILIA_HP ILIA_HP
253 #define ILIA_SP ILIA_SP
254 #define ILIA_DP ILIA_DP
255 #define ILIA_AR ILIA_AR
256 #define ILIA_KR ILIA_KR
257 #define ILIA_CC ILIA_CC
258 #define ILIA_FCC ILIA_FCC
259 #define ILIA_QP ILIA_QP
260 #define ILIA_CS ILIA_CS
261 #define ILIA_CD ILIA_CD
262 #define ILIA_CQ ILIA_CQ
263 #define ILIA_128 ILIA_128
264 #define ILIA_256 ILIA_256
265 #define ILIA_512 ILIA_512
266 #define ILIA_X87 ILIA_X87
267 #define ILIA_DOUBLEDOUBLE ILIA_DOUBLEDOUBLE
268 #define ILIA_FLOAT128 ILIA_FLOAT128
269
270 #define ILIA_DOM 1 /* dom/cse field */
271 #define ILIA_CSE 2
272
273 /* Macros use the IL_RES(opc) as a value */
274 #define ILIA_ISIR(t) ((t) == ILIA_IR)
275 #define ILIA_ISSP(t) ((t) == ILIA_SP)
276 #define ILIA_ISDP(t) ((t) == ILIA_DP)
277 #define ILIA_ISAR(t) ((t) == ILIA_AR)
278 #define ILIA_ISKR(t) ((t) == ILIA_KR)
279 #define ILIA_ISCS(t) ((t) == ILIA_CS)
280 #define ILIA_ISCD(t) ((t) == ILIA_CD)
281
282 /* operand type: ILIO_... e.g. ILIO_DPLNK */
283
284 #ifdef __cplusplus
IL_OPRFLAG(ILI_OP opcode,int opn)285 inline ILIO_KIND IL_OPRFLAG(ILI_OP opcode, int opn) {
286 return static_cast<ILIO_KIND>(ilis[opcode].oprflag[opn - 1]);
287 }
288 #else
289 #define IL_OPRFLAG(opcode, opn) (ilis[opcode].oprflag[opn - 1])
290 #endif
291
292 #define IL_OPRS(opc) (ilis[opc].oprs)
293 #define IL_NAME(opc) (ilis[opc].name)
294 #define IL_MNEMONIC(opc) (ilis[opc].opcod)
295 #define IL_ISLINK(i, opn) (IL_OPRFLAG(i, opn) >= ILIO_LNK)
296
297 #define IL_COMM(i) ((ilis[i].attr >> 4) & 0x1) /* Yields ILIA_COMM or 0 */
298 #define IL_RES(i) \
299 ((ILIA_RESULT)((ilis[i].attr >> 5) & 0x1f)) /* Yields ILIA_TRM..ILIA_AR */
300 #define IL_LNK(i) ((ilis[i].attr >> 5) & 0x1f) /* Yields ILIA_LNK or 0 */
301 #define IL_DOM(i) ((ilis[i].attr >> 10) & 0x3) /* Yields ILIA_DOM or 0 */
302 #define IL_CSEG(i) ((ilis[i].attr >> 10) & 0x3) /* Yields ILIA_CSE or 0 */
303 #define IL_IATYPE(i) ((ilis[i].attr >> 10) & 0x3) /* ILIA_DOM, ILIA_CSE or 0*/
304 #define IL_SSENME(i) ((ilis[i].attr >> 12) & 0x1) /* Yields 1 or 0 */
305 #define IL_VECT(i) ((ilis[i].attr >> 13) & 0x1) /* Yields 1 or 0 */
306 /* Can this operation have a memory fence? */
307 #define IL_HAS_FENCE(i) (((ilis[i].attr >> 14) & 3) != 0)
308 /* Is this operation an IL_ATOMICRMWx? */
309 #define IL_IS_ATOMICRMW(i) (((ilis[i].attr >> 14) & 0x3) == 2)
310 /* Is this operation an IL_CMPXCHGx? */
311 #define IL_IS_CMPXCHG(i) (((ilis[i].attr >> 14) & 0x3) == 3)
312 /* Does this operation perform an atomic update?
313 IL_OPND(2) is the address of the operand to be updated. */
314 #define IL_IS_ATOMIC_UPDATE(i) (((ilis[i].attr >> 14) & 0x3) >= 2)
315
316 typedef enum ILTY_KIND {
317 ILTY_NULL = 0,
318 ILTY_ARTH = 1,
319 ILTY_BRANCH = 2,
320 ILTY_CONS = 3,
321 ILTY_DEFINE = 4,
322 ILTY_LOAD = 5,
323 ILTY_MOVE = 6,
324 ILTY_OTHER = 7,
325 ILTY_PROC = 8,
326 ILTY_STORE = 9,
327 ILTY_PLOAD = 10,
328 ILTY_PSTORE = 11
329 } ILTY_KIND;
330
331 /* *** operation type: ILTY_... e.g. ILTY_ARTH */
332 #define IL_TYPE(idx) ((ILTY_KIND)(ilis[(idx)].attr & 0xf))
333
334 /* Reflexive defines for values inspected by #ifdef. */
335 #define ILTY_PLOAD ILTY_PLOAD
336 #define ILTY_PSTORE ILTY_PSTORE
337
338 /* Standard offsets for various register set references. */
339 #define IR_OFFSET 0
340 #define SP_OFFSET 1
341 #define DP_OFFSET 2
342 #define AR_OFFSET 3
343
344 /***** Values of conditions in relationals *****/
345
346 typedef enum CC_RELATION {
347 CC_None,
348 CC_EQ = 1,
349 CC_NE = 2,
350 CC_LT = 3,
351 CC_GE = 4,
352 CC_LE = 5,
353 CC_GT = 6,
354 CC_NOTEQ = 7,
355 CC_NOTNE = 8,
356 CC_NOTLT = 9,
357 CC_NOTGE = 10,
358 CC_NOTLE = 11,
359 CC_NOTGT = 12,
360 /* CC values are sometimes negated to denote IEEE floating-point relations.
361 The -12 here is a "strut" to ensure that the enum's underlying integral
362 type is signed. */
363 CC_IEEE_NOTGT = -12
364 } CC_RELATION;
365
366 /* Let subsequent headers know that CC_RELATION is available. */
367 #define CC_RELATION_IS_DEFINED 1
368
369 #define NEW_FMA /* ...to generate FMA3 or FMA4 instructions */
370
371 /* The following flags are used in the 'stc' operand of an FMATYPE
372 * ILI to describe an FMA instruction. The FMA operation is:
373 * dest = <sign> (factor1 * factor2) <addop> term
374 */
375 #define FMA_MINUS_PROD 1 /* if set <sign> is -, otherwise it's + */
376 #define FMA_MINUS_TERM 2 /* if set <addop> is -, otherwise it's + */
377 #define FMA_DEST_IS_FACTOR1 4 /* used for FMA3 */
378 #define FMA_DEST_IS_TERM 8 /* used for FMA3 & packed reduction FMAs */
379 #define FMA_MEMOP_IS_FACTOR2 0x10 /* used for [DS]FMA and P[DS]FMA ILIs */
380 #define FMA_MEMOP_IS_TERM 0x20 /* " " " " " " */
381 #define FMA_GEN_FMA3_132 0x40
382 #define FMA_GEN_FMA3_213 0x80
383 #define FMA_GEN_FMA3_231 0x100
384 #define FMA_GEN_FMA4 0x200
385
386 /********************************************************************
387 * JHM (7 April 2014): The following #define is necessary for
388 * compiling comp.shared/llvm/src/llvect.c. Delete it when possible.
389 *******************************************************************/
390 #define FMA_DEST_IS_SRC1 FMA_DEST_IS_FACTOR1
391
392 /* The following flags are used in the 'stc' operand of VEXTRACT and
393 * VINSERT ILIs to specify which 'vextract...' or 'vinsert...'
394 * instruction to use.
395 */
396 #define SUF_f128 0x10 /* only used in AVX instructions */
397 #define SUF_f32x4 0x20 /* " " " AVX3 " " */
398 #define SUF_f32x8 0x40 /* " " " " " " */
399 #define SUF_f64x2 0x80 /* " " " " " " */
400 #define SUF_f64x4 0x100 /* " " " " " " */
401 #define SUF_i128 0x200 /* " " " AVX2 " " */
402 #define SUF_i32x4 0x400 /* " " " AVX3 " " */
403 #define SUF_i32x8 0x800 /* " " " " " " */
404 #define SUF_i64x2 0x1000 /* " " " " " " */
405 #define SUF_i64x4 0x2000 /* " " " " " " */
406
407 #ifdef __cplusplus
MSZ_ILI_OPND(int i,int opn)408 inline MSZ MSZ_ILI_OPND(int i, int opn) {
409 return static_cast<MSZ>(ILI_OPND(i, opn));
410 }
411 #else
412 #define MSZ_ILI_OPND ILI_OPND
413 #endif
414
415 #define MSZ_TO_BYTES \
416 { \
417 1 /* SBYTE */, 2 /* SHWORD */, 4 /* SWORD */, 8 /* SLWORD */, \
418 1 /* UBYTE */, 2 /* UHWORD */, 4 /* UWORD */, 8 /* ULWORD */, \
419 0 /* 0x08 */, 2 /* FHALF */, 4 /* FWORD */, 8 /* FLWORD */, \
420 0 /* 0x0c */, 0 /* 0x0d */, 0 /* 0x0e */, 8 /* I8 */, \
421 0 /* 0x10 */, 0 /* 0x11 */, 0 /* 0x12 */, 8 /* PTR */, \
422 0 /* 0x14 */, 0 /* 0x15 */, 16 /* F10 */, 16 /* F16 */, \
423 0 /* 0x18 */, 0 /* 0x19 */, 32 /* F32 */, 16 /* F8x2 */, \
424 0 /* 0x1c */, 0 /* 0x1d */, 0 /* 0x1e */, 0 /* 0x1f */ \
425 }
426
427 /* Reflexive defines for values that are inspected by preprocessor directives */
428 #define MSZ_F10 MSZ_F10
429 #define MSZ_I8 MSZ_I8
430 #define MSZ_SLWORD MSZ_SLWORD
431 #define MSZ_ULWORD MSZ_ULWORD
432 #define MSZ_UWORD MSZ_UWORD
433
434 /* Synonyms (beware conflicting case values) */
435 #define MSZ_WORD MSZ_SWORD
436 #define MSZ_BYTE MSZ_UBYTE
437 #define MSZ_F4 MSZ_FWORD
438 #define MSZ_F8 MSZ_FLWORD
439 #define MSZ_DBLE MSZ_FLWORD
440 #define MSZ_DFLWORD MSZ_FLWORD
441 #define MSZ_DSLWORD MSZ_SLWORD
442
443 typedef struct {
444 unsigned int latency; /* ST | LD | R/R | R/M */
445 unsigned int attrs; /* ST | LD | R/M | R/R */
446 } SCHINFO;
447
448 #define P_FADD 0x01
449 #define P_FMUL 0x02
450 #define P_FST 0x04
451 #define DEC_DIR 0x10
452 #define DEC_DBL 0x20
453 #define DEC_VEC 0x40
454
455 #define ST_SHIFT 24
456 #define LD_SHIFT 16
457 #define RM_SHIFT 8
458 #define RR_SHIFT 0
459
460 #define SCH_ATTR(i) (schinfo[(i)].attrs)
461 #define SCH_LAT(i) (schinfo[(i)].latency)
462
463 /* ---------------------------------------------------------------------- */
464
465 #ifndef ILITP_UTIL
466 extern bool share_proc_ili; /* defd in iliutil.c */
467 extern bool share_qjsr_ili; /* defd in iliutil.c */
468
469 /* declare external functions iliutil.c, unless building ilitp utility prog */
470
471 #define XBIT_NEW_MATH_NAMES XBIT(164, 0x800000)
472
473 /* The following macro is for experimenting with the new method for certain
474 * complex operations/intrinsics -- when complete, just drop _CMPLX from the
475 * use(s).
476 */
477 #define XBIT_NEW_MATH_NAMES_CMPLX (XBIT_NEW_MATH_NAMES && XBIT(26,1))
478
479 #define XBIT_NEW_RELAXEDMATH XBIT(15, 0x400)
480
481 #define XBIT_VECTORABI_FOR_SCALAR XBIT(26,2)
482
483 /***** ILT, BIH, NME declarations *****/
484 #include "ilt.h"
485 #include "bih.h"
486 #include "nme.h"
487
488 /***** Atomic Operation Encodings *****/
489
490 /* Extract MSZ from an int that is a MSZ operand or an encoded ATOMIC_INFO.
491 This functionality is handy for extracting the MSZ from an instruction
492 that might be a plain load/store or atomic/load/store. */
493 #define ILI_MSZ_FROM_STC(x) ((MSZ)(x)&0xFF)
494
495 /* Get MSZ of an IL_LD or IL_ATOMICLDx instruction */
496 #define ILI_MSZ_OF_LD(ilix) (ILI_MSZ_FROM_STC(ILI_OPND((ilix), 3)))
497
498 /* Get MSZ of an IL_ST, IL_STHP, IL_STSP, IL_STDP, or IL_ATOMICSTx instruction */
499 #define ILI_MSZ_OF_ST(ilix) (ILI_MSZ_FROM_STC(ILI_OPND((ilix), 4)))
500
501 #include "iliutil.h"
502
503 #ifdef __cplusplus
GetILI_MSZ_OF_Load(int ilix)504 inline MSZ GetILI_MSZ_OF_Load(int ilix) {
505 return static_cast<MSZ>(ILI_MSZ_OF_LD(ilix));
506 }
507 #undef ILI_MSZ_OF_LD
508 #define ILI_MSZ_OF_LD GetILI_MSZ_OF_Load
GetILI_MSZ_OF_Store(int ilix)509 inline MSZ GetILI_MSZ_OF_Store(int ilix) {
510 return static_cast<MSZ>(ILI_MSZ_OF_ST(ilix));
511 }
512 #undef ILI_MSZ_OF_ST
513 #define ILI_MSZ_OF_ST GetILI_MSZ_OF_Store
514 #endif
515
516 #endif /* !ILITP_UTIL */
517
518 #endif /* ILI_H_ */
519