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