1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5#if defined(_TARGET_XARCH_)
6
7/************************************************************************/
8/* Public inline informational methods */
9/************************************************************************/
10
11public:
12inline static bool isGeneralRegister(regNumber reg)
13{
14 return (reg <= REG_INT_LAST);
15}
16
17inline static bool isFloatReg(regNumber reg)
18{
19 return (reg >= REG_FP_FIRST && reg <= REG_FP_LAST);
20}
21
22inline static bool isDoubleReg(regNumber reg)
23{
24 return isFloatReg(reg);
25}
26
27/************************************************************************/
28/* Routines that compute the size of / encode instructions */
29/************************************************************************/
30
31// code_t is a type used to accumulate bits of opcode + prefixes. On amd64, it must be 64 bits
32// to support the REX prefixes. On both x86 and amd64, it must be 64 bits to support AVX, with
33// its 3-byte VEX prefix.
34typedef unsigned __int64 code_t;
35
36struct CnsVal
37{
38 ssize_t cnsVal;
39 bool cnsReloc;
40};
41
42UNATIVE_OFFSET emitInsSize(code_t code);
43UNATIVE_OFFSET emitInsSizeRM(instruction ins);
44UNATIVE_OFFSET emitInsSizeSV(code_t code, int var, int dsp);
45UNATIVE_OFFSET emitInsSizeSV(instrDesc* id, code_t code, int var, int dsp);
46UNATIVE_OFFSET emitInsSizeSV(instrDesc* id, code_t code, int var, int dsp, int val);
47UNATIVE_OFFSET emitInsSizeRR(instruction ins, regNumber reg1, regNumber reg2, emitAttr attr);
48UNATIVE_OFFSET emitInsSizeAM(instrDesc* id, code_t code);
49UNATIVE_OFFSET emitInsSizeAM(instrDesc* id, code_t code, int val);
50UNATIVE_OFFSET emitInsSizeCV(instrDesc* id, code_t code);
51UNATIVE_OFFSET emitInsSizeCV(instrDesc* id, code_t code, int val);
52
53BYTE* emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc = nullptr);
54BYTE* emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc = nullptr);
55BYTE* emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc = nullptr);
56
57BYTE* emitOutputR(BYTE* dst, instrDesc* id);
58BYTE* emitOutputRI(BYTE* dst, instrDesc* id);
59BYTE* emitOutputRR(BYTE* dst, instrDesc* id);
60BYTE* emitOutputIV(BYTE* dst, instrDesc* id);
61
62BYTE* emitOutputRRR(BYTE* dst, instrDesc* id);
63
64BYTE* emitOutputLJ(BYTE* dst, instrDesc* id);
65
66unsigned emitOutputRexOrVexPrefixIfNeeded(instruction ins, BYTE* dst, code_t& code);
67unsigned emitGetRexPrefixSize(instruction ins);
68unsigned emitGetVexPrefixSize(instruction ins, emitAttr attr);
69unsigned emitGetPrefixSize(code_t code);
70unsigned emitGetVexPrefixAdjustedSize(instruction ins, emitAttr attr, code_t code);
71
72unsigned insEncodeReg012(instruction ins, regNumber reg, emitAttr size, code_t* code);
73unsigned insEncodeReg345(instruction ins, regNumber reg, emitAttr size, code_t* code);
74code_t insEncodeReg3456(instruction ins, regNumber reg, emitAttr size, code_t code);
75unsigned insEncodeRegSIB(instruction ins, regNumber reg, code_t* code);
76
77code_t insEncodeMRreg(instruction ins, code_t code);
78code_t insEncodeRMreg(instruction ins, code_t code);
79code_t insEncodeMRreg(instruction ins, regNumber reg, emitAttr size, code_t code);
80code_t insEncodeRRIb(instruction ins, regNumber reg, emitAttr size);
81code_t insEncodeOpreg(instruction ins, regNumber reg, emitAttr size);
82
83unsigned insSSval(unsigned scale);
84
85bool IsAVXInstruction(instruction ins);
86code_t insEncodeMIreg(instruction ins, regNumber reg, emitAttr size, code_t code);
87
88code_t AddRexWPrefix(instruction ins, code_t code);
89code_t AddRexRPrefix(instruction ins, code_t code);
90code_t AddRexXPrefix(instruction ins, code_t code);
91code_t AddRexBPrefix(instruction ins, code_t code);
92code_t AddRexPrefix(instruction ins, code_t code);
93
94bool EncodedBySSE38orSSE3A(instruction ins);
95bool Is4ByteSSEInstruction(instruction ins);
96
97bool hasRexPrefix(code_t code)
98{
99#ifdef _TARGET_AMD64_
100 const code_t REX_PREFIX_MASK = 0xFF00000000LL;
101 return (code & REX_PREFIX_MASK) != 0;
102#else // !_TARGET_AMD64_
103 return false;
104#endif // !_TARGET_AMD64_
105}
106
107// 3-byte VEX prefix starts with byte 0xC4
108#define VEX_PREFIX_MASK_3BYTE 0xFF000000000000ULL
109#define VEX_PREFIX_CODE_3BYTE 0xC4000000000000ULL
110
111bool TakesVexPrefix(instruction ins);
112
113// Returns true if the instruction encoding already contains VEX prefix
114bool hasVexPrefix(code_t code)
115{
116 return (code & VEX_PREFIX_MASK_3BYTE) == VEX_PREFIX_CODE_3BYTE;
117}
118code_t AddVexPrefix(instruction ins, code_t code, emitAttr attr);
119code_t AddVexPrefixIfNeeded(instruction ins, code_t code, emitAttr size)
120{
121 if (TakesVexPrefix(ins))
122 {
123 code = AddVexPrefix(ins, code, size);
124 }
125 return code;
126}
127code_t AddVexPrefixIfNeededAndNotPresent(instruction ins, code_t code, emitAttr size)
128{
129 if (TakesVexPrefix(ins) && !hasVexPrefix(code))
130 {
131 code = AddVexPrefix(ins, code, size);
132 }
133 return code;
134}
135
136bool useVEXEncodings;
137bool UseVEXEncoding()
138{
139 return useVEXEncodings;
140}
141void SetUseVEXEncoding(bool value)
142{
143 useVEXEncodings = value;
144}
145
146bool containsAVXInstruction = false;
147bool ContainsAVX()
148{
149 return containsAVXInstruction;
150}
151void SetContainsAVX(bool value)
152{
153 containsAVXInstruction = value;
154}
155
156bool contains256bitAVXInstruction = false;
157bool Contains256bitAVX()
158{
159 return contains256bitAVXInstruction;
160}
161void SetContains256bitAVX(bool value)
162{
163 contains256bitAVXInstruction = value;
164}
165
166bool IsDstDstSrcAVXInstruction(instruction ins);
167bool IsDstSrcSrcAVXInstruction(instruction ins);
168bool IsThreeOperandAVXInstruction(instruction ins)
169{
170 return (IsDstDstSrcAVXInstruction(ins) || IsDstSrcSrcAVXInstruction(ins));
171}
172bool isAvxBlendv(instruction ins)
173{
174 return ins == INS_vblendvps || ins == INS_vblendvpd || ins == INS_vpblendvb;
175}
176bool isSse41Blendv(instruction ins)
177{
178 return ins == INS_blendvps || ins == INS_blendvpd || ins == INS_pblendvb;
179}
180bool isPrefetch(instruction ins)
181{
182 return (ins == INS_prefetcht0) || (ins == INS_prefetcht1) || (ins == INS_prefetcht2) || (ins == INS_prefetchnta);
183}
184
185/************************************************************************/
186/* Debug-only routines to display instructions */
187/************************************************************************/
188
189#ifdef DEBUG
190
191const char* emitFPregName(unsigned reg, bool varName = true);
192
193void emitDispReloc(ssize_t value);
194void emitDispAddrMode(instrDesc* id, bool noDetail = false);
195void emitDispShift(instruction ins, int cnt = 0);
196
197void emitDispIns(instrDesc* id,
198 bool isNew,
199 bool doffs,
200 bool asmfm,
201 unsigned offs = 0,
202 BYTE* code = nullptr,
203 size_t sz = 0,
204 insGroup* ig = nullptr);
205
206const char* emitXMMregName(unsigned reg);
207const char* emitYMMregName(unsigned reg);
208
209#endif
210
211/************************************************************************/
212/* Private members that deal with target-dependent instr. descriptors */
213/************************************************************************/
214
215private:
216void emitSetAmdDisp(instrDescAmd* id, ssize_t dsp);
217instrDesc* emitNewInstrAmd(emitAttr attr, ssize_t dsp);
218instrDesc* emitNewInstrAmdCns(emitAttr attr, ssize_t dsp, int cns);
219
220instrDesc* emitNewInstrCallDir(int argCnt,
221 VARSET_VALARG_TP GCvars,
222 regMaskTP gcrefRegs,
223 regMaskTP byrefRegs,
224 emitAttr retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize));
225
226instrDesc* emitNewInstrCallInd(int argCnt,
227 ssize_t disp,
228 VARSET_VALARG_TP GCvars,
229 regMaskTP gcrefRegs,
230 regMaskTP byrefRegs,
231 emitAttr retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize));
232
233void emitGetInsCns(instrDesc* id, CnsVal* cv);
234ssize_t emitGetInsAmdCns(instrDesc* id, CnsVal* cv);
235void emitGetInsDcmCns(instrDesc* id, CnsVal* cv);
236ssize_t emitGetInsAmdAny(instrDesc* id);
237
238/************************************************************************/
239/* Private helpers for instruction output */
240/************************************************************************/
241
242private:
243insFormat emitInsModeFormat(instruction ins, insFormat base, insFormat FPld, insFormat FPst);
244
245bool emitVerifyEncodable(instruction ins, emitAttr size, regNumber reg1, regNumber reg2 = REG_NA);
246
247bool emitInsCanOnlyWriteSSE2OrAVXReg(instrDesc* id);
248
249#if FEATURE_FIXED_OUT_ARGS
250void emitAdjustStackDepthPushPop(instruction ins)
251{
252}
253void emitAdjustStackDepth(instruction ins, ssize_t val)
254{
255}
256#else // !FEATURE_FIXED_OUT_ARGS
257void emitAdjustStackDepthPushPop(instruction ins);
258void emitAdjustStackDepth(instruction ins, ssize_t val);
259#endif // !FEATURE_FIXED_OUT_ARGS
260
261/*****************************************************************************
262*
263* Convert between an index scale in bytes to a smaller encoding used for
264* storage in instruction descriptors.
265*/
266
267inline emitter::opSize emitEncodeScale(size_t scale)
268{
269 assert(scale == 1 || scale == 2 || scale == 4 || scale == 8);
270
271 return emitSizeEncode[scale - 1];
272}
273
274inline emitAttr emitDecodeScale(unsigned ensz)
275{
276 assert(ensz < 4);
277
278 return emitter::emitSizeDecode[ensz];
279}
280
281/************************************************************************/
282/* The public entry points to output instructions */
283/************************************************************************/
284
285public:
286void emitLoopAlign();
287
288void emitIns(instruction ins);
289
290void emitIns(instruction ins, emitAttr attr);
291
292void emitInsRMW(instruction inst, emitAttr attr, GenTreeStoreInd* storeInd, GenTree* src);
293
294void emitInsRMW(instruction inst, emitAttr attr, GenTreeStoreInd* storeInd);
295
296void emitIns_Nop(unsigned size);
297
298void emitIns_I(instruction ins, emitAttr attr, int val);
299
300void emitIns_R(instruction ins, emitAttr attr, regNumber reg);
301
302void emitIns_C(instruction ins, emitAttr attr, CORINFO_FIELD_HANDLE fdlHnd, int offs);
303
304void emitIns_R_I(instruction ins, emitAttr attr, regNumber reg, ssize_t val);
305
306void emitIns_R_R(instruction ins, emitAttr attr, regNumber reg1, regNumber reg2);
307
308void emitIns_R_R_I(instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, int ival);
309
310void emitIns_AR(instruction ins, emitAttr attr, regNumber base, int offs);
311
312void emitIns_AR_R_R(instruction ins, emitAttr attr, regNumber op2Reg, regNumber op3Reg, regNumber base, int offs);
313
314void emitIns_R_A(instruction ins, emitAttr attr, regNumber reg1, GenTreeIndir* indir);
315
316void emitIns_R_A_I(instruction ins, emitAttr attr, regNumber reg1, GenTreeIndir* indir, int ival);
317
318void emitIns_R_AR_I(instruction ins, emitAttr attr, regNumber reg1, regNumber base, int offs, int ival);
319
320void emitIns_R_C_I(instruction ins, emitAttr attr, regNumber reg1, CORINFO_FIELD_HANDLE fldHnd, int offs, int ival);
321
322void emitIns_R_S_I(instruction ins, emitAttr attr, regNumber reg1, int varx, int offs, int ival);
323
324void emitIns_R_R_A(instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, GenTreeIndir* indir);
325
326void emitIns_R_R_AR(instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, regNumber base, int offs);
327
328void emitIns_R_AR_R(instruction ins,
329 emitAttr attr,
330 regNumber reg1,
331 regNumber reg2,
332 regNumber base,
333 regNumber index,
334 int scale,
335 int offs);
336
337void emitIns_R_R_C(
338 instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, CORINFO_FIELD_HANDLE fldHnd, int offs);
339
340void emitIns_R_R_S(instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, int varx, int offs);
341
342void emitIns_R_R_R(instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, regNumber reg3);
343
344void emitIns_R_R_A_I(
345 instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, GenTreeIndir* indir, int ival, insFormat fmt);
346void emitIns_R_R_AR_I(
347 instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, regNumber base, int offs, int ival);
348void emitIns_AR_R_I(instruction ins, emitAttr attr, regNumber base, int disp, regNumber ireg, int ival);
349
350void emitIns_R_R_C_I(
351 instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, CORINFO_FIELD_HANDLE fldHnd, int offs, int ival);
352
353void emitIns_R_R_R_I(instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, regNumber reg3, int ival);
354
355void emitIns_R_R_S_I(instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, int varx, int offs, int ival);
356
357void emitIns_R_R_A_R(
358 instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op3Reg, GenTreeIndir* indir);
359
360void emitIns_R_R_AR_R(
361 instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op3Reg, regNumber base, int offs);
362
363void emitIns_R_R_C_R(instruction ins,
364 emitAttr attr,
365 regNumber targetReg,
366 regNumber op1Reg,
367 regNumber op3Reg,
368 CORINFO_FIELD_HANDLE fldHnd,
369 int offs);
370
371void emitIns_R_R_S_R(
372 instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op3Reg, int varx, int offs);
373
374void emitIns_R_R_R_R(instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, regNumber reg3, regNumber reg4);
375
376void emitIns_S(instruction ins, emitAttr attr, int varx, int offs);
377
378void emitIns_S_R(instruction ins, emitAttr attr, regNumber ireg, int varx, int offs);
379
380void emitIns_R_S(instruction ins, emitAttr attr, regNumber ireg, int varx, int offs);
381
382void emitIns_S_I(instruction ins, emitAttr attr, int varx, int offs, int val);
383
384void emitIns_R_C(instruction ins, emitAttr attr, regNumber reg, CORINFO_FIELD_HANDLE fldHnd, int offs);
385
386void emitIns_C_R(instruction ins, emitAttr attr, CORINFO_FIELD_HANDLE fldHnd, regNumber reg, int offs);
387
388void emitIns_C_I(instruction ins, emitAttr attr, CORINFO_FIELD_HANDLE fdlHnd, int offs, int val);
389
390void emitIns_IJ(emitAttr attr, regNumber reg, unsigned base);
391
392void emitIns_J_S(instruction ins, emitAttr attr, BasicBlock* dst, int varx, int offs);
393
394void emitIns_R_L(instruction ins, emitAttr attr, BasicBlock* dst, regNumber reg);
395
396void emitIns_R_D(instruction ins, emitAttr attr, unsigned offs, regNumber reg);
397
398void emitIns_I_AR(instruction ins, emitAttr attr, int val, regNumber reg, int offs);
399
400void emitIns_I_AI(instruction ins, emitAttr attr, int val, ssize_t disp);
401
402void emitIns_R_AR(instruction ins, emitAttr attr, regNumber ireg, regNumber reg, int offs);
403
404void emitIns_R_AI(instruction ins, emitAttr attr, regNumber ireg, ssize_t disp);
405
406void emitIns_AR_R(instruction ins, emitAttr attr, regNumber ireg, regNumber reg, int offs);
407
408void emitIns_AI_R(instruction ins, emitAttr attr, regNumber ireg, ssize_t disp);
409
410void emitIns_I_ARR(instruction ins, emitAttr attr, int val, regNumber reg, regNumber rg2, int disp);
411
412void emitIns_R_ARR(instruction ins, emitAttr attr, regNumber ireg, regNumber reg, regNumber rg2, int disp);
413
414void emitIns_ARR_R(instruction ins, emitAttr attr, regNumber ireg, regNumber reg, regNumber rg2, int disp);
415
416void emitIns_I_ARX(instruction ins, emitAttr attr, int val, regNumber reg, regNumber rg2, unsigned mul, int disp);
417
418void emitIns_R_ARX(
419 instruction ins, emitAttr attr, regNumber ireg, regNumber reg, regNumber rg2, unsigned mul, int disp);
420
421void emitIns_ARX_R(
422 instruction ins, emitAttr attr, regNumber ireg, regNumber reg, regNumber rg2, unsigned mul, int disp);
423
424void emitIns_I_AX(instruction ins, emitAttr attr, int val, regNumber reg, unsigned mul, int disp);
425
426void emitIns_R_AX(instruction ins, emitAttr attr, regNumber ireg, regNumber reg, unsigned mul, int disp);
427
428void emitIns_AX_R(instruction ins, emitAttr attr, regNumber ireg, regNumber reg, unsigned mul, int disp);
429
430#ifdef FEATURE_HW_INTRINSICS
431void emitIns_SIMD_R_R_I(instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, int ival);
432
433void emitIns_SIMD_R_R_A(instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, GenTreeIndir* indir);
434void emitIns_SIMD_R_R_AR(instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber base);
435void emitIns_SIMD_R_R_C(
436 instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, CORINFO_FIELD_HANDLE fldHnd, int offs);
437void emitIns_SIMD_R_R_R(instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg);
438void emitIns_SIMD_R_R_S(instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, int varx, int offs);
439
440void emitIns_SIMD_R_R_A_I(
441 instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, GenTreeIndir* indir, int ival);
442void emitIns_SIMD_R_R_AR_I(
443 instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber base, int ival);
444void emitIns_SIMD_R_R_C_I(instruction ins,
445 emitAttr attr,
446 regNumber targetReg,
447 regNumber op1Reg,
448 CORINFO_FIELD_HANDLE fldHnd,
449 int offs,
450 int ival);
451void emitIns_SIMD_R_R_R_I(
452 instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, int ival);
453void emitIns_SIMD_R_R_S_I(
454 instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, int varx, int offs, int ival);
455
456void emitIns_SIMD_R_R_R_A(
457 instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, GenTreeIndir* indir);
458void emitIns_SIMD_R_R_R_AR(
459 instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, regNumber base);
460void emitIns_SIMD_R_R_R_C(instruction ins,
461 emitAttr attr,
462 regNumber targetReg,
463 regNumber op1Reg,
464 regNumber op2Reg,
465 CORINFO_FIELD_HANDLE fldHnd,
466 int offs);
467void emitIns_SIMD_R_R_R_R(
468 instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, regNumber op3Reg);
469void emitIns_SIMD_R_R_R_S(
470 instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, int varx, int offs);
471
472void emitIns_SIMD_R_R_A_R(
473 instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, GenTreeIndir* indir);
474void emitIns_SIMD_R_R_AR_R(
475 instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, regNumber base);
476void emitIns_SIMD_R_R_C_R(instruction ins,
477 emitAttr attr,
478 regNumber targetReg,
479 regNumber op1Reg,
480 regNumber op2Reg,
481 CORINFO_FIELD_HANDLE fldHnd,
482 int offs);
483void emitIns_SIMD_R_R_S_R(
484 instruction ins, emitAttr attr, regNumber targetReg, regNumber op1Reg, regNumber op2Reg, int varx, int offs);
485#endif // FEATURE_HW_INTRINSICS
486
487enum EmitCallType
488{
489 EC_FUNC_TOKEN, // Direct call to a helper/static/nonvirtual/global method
490 EC_FUNC_TOKEN_INDIR, // Indirect call to a helper/static/nonvirtual/global method
491 EC_FUNC_ADDR, // Direct call to an absolute address
492
493 EC_FUNC_VIRTUAL, // Call to a virtual method (using the vtable)
494 EC_INDIR_R, // Indirect call via register
495 EC_INDIR_SR, // Indirect call via stack-reference (local var)
496 EC_INDIR_C, // Indirect call via static class var
497 EC_INDIR_ARD, // Indirect call via an addressing mode
498
499 EC_COUNT
500};
501
502// clang-format off
503void emitIns_Call(EmitCallType callType,
504 CORINFO_METHOD_HANDLE methHnd,
505 INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo) // used to report call sites to the EE
506 void* addr,
507 ssize_t argSize,
508 emitAttr retSize
509 MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
510 VARSET_VALARG_TP ptrVars,
511 regMaskTP gcrefRegs,
512 regMaskTP byrefRegs,
513 IL_OFFSETX ilOffset = BAD_IL_OFFSET,
514 regNumber ireg = REG_NA,
515 regNumber xreg = REG_NA,
516 unsigned xmul = 0,
517 ssize_t disp = 0,
518 bool isJump = false);
519// clang-format on
520
521#ifdef _TARGET_AMD64_
522// Is the last instruction emitted a call instruction?
523bool emitIsLastInsCall();
524
525// Insert a NOP at the end of the the current instruction group if the last emitted instruction was a 'call',
526// because the next instruction group will be an epilog.
527void emitOutputPreEpilogNOP();
528#endif // _TARGET_AMD64_
529
530/*****************************************************************************
531 *
532 * Given a jump, return true if it's a conditional jump.
533 */
534
535inline bool emitIsCondJump(instrDesc* jmp)
536{
537 instruction ins = jmp->idIns();
538
539 assert(jmp->idInsFmt() == IF_LABEL);
540
541 return (ins != INS_call && ins != INS_jmp);
542}
543
544/*****************************************************************************
545 *
546 * Given a jump, return true if it's an unconditional jump.
547 */
548
549inline bool emitIsUncondJump(instrDesc* jmp)
550{
551 instruction ins = jmp->idIns();
552
553 assert(jmp->idInsFmt() == IF_LABEL);
554
555 return (ins == INS_jmp);
556}
557
558#endif // _TARGET_XARCH_
559