summaryrefslogtreecommitdiff
path: root/src/jit/emitxarch.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/jit/emitxarch.h')
-rw-r--r--src/jit/emitxarch.h118
1 files changed, 82 insertions, 36 deletions
diff --git a/src/jit/emitxarch.h b/src/jit/emitxarch.h
index dfd7e6ec50..98256cdaa7 100644
--- a/src/jit/emitxarch.h
+++ b/src/jit/emitxarch.h
@@ -28,6 +28,15 @@ inline static bool isDoubleReg(regNumber reg)
/* Routines that compute the size of / encode instructions */
/************************************************************************/
+// code_t is a type used to accumulate bits of opcode + prefixes. On amd64, it must be 64 bits
+// to support the REX prefixes. On both x86 and amd64, it must be 64 bits to support AVX, with
+// its 3-byte VEX prefix. For legacy backend (which doesn't support AVX), leave it as size_t.
+#if defined(LEGACY_BACKEND)
+typedef size_t code_t;
+#else // !defined(LEGACY_BACKEND)
+typedef unsigned __int64 code_t;
+#endif // !defined(LEGACY_BACKEND)
+
struct CnsVal
{
ssize_t cnsVal;
@@ -36,19 +45,19 @@ struct CnsVal
#endif
};
-UNATIVE_OFFSET emitInsSize(size_t code);
+UNATIVE_OFFSET emitInsSize(code_t code);
UNATIVE_OFFSET emitInsSizeRM(instruction ins);
-UNATIVE_OFFSET emitInsSizeSV(size_t code, int var, int dsp);
+UNATIVE_OFFSET emitInsSizeSV(code_t code, int var, int dsp);
UNATIVE_OFFSET emitInsSizeSV(instrDesc* id, int var, int dsp, int val);
UNATIVE_OFFSET emitInsSizeRR(instruction ins, regNumber reg1, regNumber reg2, emitAttr attr);
-UNATIVE_OFFSET emitInsSizeAM(instrDesc* id, size_t code);
-UNATIVE_OFFSET emitInsSizeAM(instrDesc* id, size_t code, int val);
-UNATIVE_OFFSET emitInsSizeCV(instrDesc* id, size_t code);
-UNATIVE_OFFSET emitInsSizeCV(instrDesc* id, size_t code, int val);
+UNATIVE_OFFSET emitInsSizeAM(instrDesc* id, code_t code);
+UNATIVE_OFFSET emitInsSizeAM(instrDesc* id, code_t code, int val);
+UNATIVE_OFFSET emitInsSizeCV(instrDesc* id, code_t code);
+UNATIVE_OFFSET emitInsSizeCV(instrDesc* id, code_t code, int val);
-BYTE* emitOutputAM(BYTE* dst, instrDesc* id, size_t code, CnsVal* addc = nullptr);
-BYTE* emitOutputSV(BYTE* dst, instrDesc* id, size_t code, CnsVal* addc = nullptr);
-BYTE* emitOutputCV(BYTE* dst, instrDesc* id, size_t code, CnsVal* addc = nullptr);
+BYTE* emitOutputAM(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc = nullptr);
+BYTE* emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc = nullptr);
+BYTE* emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc = nullptr);
BYTE* emitOutputR(BYTE* dst, instrDesc* id);
BYTE* emitOutputRI(BYTE* dst, instrDesc* id);
@@ -61,42 +70,60 @@ BYTE* emitOutputRRR(BYTE* dst, instrDesc* id);
BYTE* emitOutputLJ(BYTE* dst, instrDesc* id);
-unsigned emitOutputRexOrVexPrefixIfNeeded(instruction ins, BYTE* dst, size_t& code);
+unsigned emitOutputRexOrVexPrefixIfNeeded(instruction ins, BYTE* dst, code_t& code);
unsigned emitGetRexPrefixSize(instruction ins);
unsigned emitGetVexPrefixSize(instruction ins, emitAttr attr);
-unsigned emitGetPrefixSize(size_t code);
-unsigned emitGetVexPrefixAdjustedSize(instruction ins, emitAttr attr, size_t code);
+unsigned emitGetPrefixSize(code_t code);
+unsigned emitGetVexPrefixAdjustedSize(instruction ins, emitAttr attr, code_t code);
+
+unsigned insEncodeReg012(instruction ins, regNumber reg, emitAttr size, code_t* code);
+unsigned insEncodeReg345(instruction ins, regNumber reg, emitAttr size, code_t* code);
+code_t insEncodeReg3456(instruction ins, regNumber reg, emitAttr size, code_t code);
+unsigned insEncodeRegSIB(instruction ins, regNumber reg, code_t* code);
-unsigned insEncodeReg345(instruction ins, regNumber reg, emitAttr size, size_t* code);
-unsigned insEncodeReg012(instruction ins, regNumber reg, emitAttr size, size_t* code);
-size_t insEncodeReg3456(instruction ins, regNumber reg, emitAttr size, size_t code);
-unsigned insEncodeRegSIB(instruction ins, regNumber reg, size_t* code);
+code_t insEncodeMRreg(instruction ins, code_t code);
+code_t insEncodeRMreg(instruction ins, code_t code);
+code_t insEncodeMRreg(instruction ins, regNumber reg, emitAttr size, code_t code);
+code_t insEncodeRRIb(instruction ins, regNumber reg, emitAttr size);
+code_t insEncodeOpreg(instruction ins, regNumber reg, emitAttr size);
-size_t insEncodeMRreg(instruction ins, size_t code);
-size_t insEncodeMRreg(instruction ins, regNumber reg, emitAttr size, size_t code);
-size_t insEncodeRRIb(instruction ins, regNumber reg, emitAttr size);
-size_t insEncodeOpreg(instruction ins, regNumber reg, emitAttr size);
+unsigned insSSval(unsigned scale);
bool IsAVXInstruction(instruction ins);
-size_t insEncodeMIreg(instruction ins, regNumber reg, emitAttr size, size_t code);
+code_t insEncodeMIreg(instruction ins, regNumber reg, emitAttr size, code_t code);
-size_t AddRexWPrefix(instruction ins, size_t code);
-size_t AddRexRPrefix(instruction ins, size_t code);
-size_t AddRexXPrefix(instruction ins, size_t code);
-size_t AddRexBPrefix(instruction ins, size_t code);
-size_t AddRexPrefix(instruction ins, size_t code);
+code_t AddRexWPrefix(instruction ins, code_t code);
+code_t AddRexRPrefix(instruction ins, code_t code);
+code_t AddRexXPrefix(instruction ins, code_t code);
+code_t AddRexBPrefix(instruction ins, code_t code);
+code_t AddRexPrefix(instruction ins, code_t code);
+
+bool useSSE3_4Encodings;
+bool UseSSE3_4()
+{
+ return useSSE3_4Encodings;
+}
+void SetUseSSE3_4(bool value)
+{
+ useSSE3_4Encodings = value;
+}
+bool Is4ByteSSE4Instruction(instruction ins);
#ifdef FEATURE_AVX_SUPPORT
+
// 3-byte VEX prefix starts with byte 0xC4
-#define VEX_PREFIX_MASK_3BYTE 0xC4000000000000LL
+#define VEX_PREFIX_MASK_3BYTE 0xFF000000000000ULL
+#define VEX_PREFIX_CODE_3BYTE 0xC4000000000000ULL
+
bool TakesVexPrefix(instruction ins);
+
// Returns true if the instruction encoding already contains VEX prefix
-bool hasVexPrefix(size_t code)
+bool hasVexPrefix(code_t code)
{
- return (code & VEX_PREFIX_MASK_3BYTE) != 0;
+ return (code & VEX_PREFIX_MASK_3BYTE) == VEX_PREFIX_CODE_3BYTE;
}
-size_t AddVexPrefix(instruction ins, size_t code, emitAttr attr);
-size_t AddVexPrefixIfNeeded(instruction ins, size_t code, emitAttr size)
+code_t AddVexPrefix(instruction ins, code_t code, emitAttr attr);
+code_t AddVexPrefixIfNeeded(instruction ins, code_t code, emitAttr size)
{
if (TakesVexPrefix(ins))
{
@@ -104,7 +131,7 @@ size_t AddVexPrefixIfNeeded(instruction ins, size_t code, emitAttr size)
}
return code;
}
-size_t AddVexPrefixIfNeededAndNotPresent(instruction ins, size_t code, emitAttr size)
+code_t AddVexPrefixIfNeededAndNotPresent(instruction ins, code_t code, emitAttr size)
{
if (TakesVexPrefix(ins) && !hasVexPrefix(code))
{
@@ -112,6 +139,7 @@ size_t AddVexPrefixIfNeededAndNotPresent(instruction ins, size_t code, emitAttr
}
return code;
}
+
bool useAVXEncodings;
bool UseAVX()
{
@@ -121,18 +149,20 @@ void SetUseAVX(bool value)
{
useAVXEncodings = value;
}
+
bool IsThreeOperandBinaryAVXInstruction(instruction ins);
bool IsThreeOperandMoveAVXInstruction(instruction ins);
bool IsThreeOperandAVXInstruction(instruction ins)
{
return (IsThreeOperandBinaryAVXInstruction(ins) || IsThreeOperandMoveAVXInstruction(ins));
}
+bool Is4ByteAVXInstruction(instruction ins);
#else // !FEATURE_AVX_SUPPORT
-bool UseAVX()
+bool UseAVX()
{
return false;
}
-bool hasVexPrefix(size_t code)
+bool hasVexPrefix(code_t code)
{
return false;
}
@@ -148,15 +178,19 @@ bool IsThreeOperandAVXInstruction(instruction ins)
{
return false;
}
+bool Is4ByteAVXInstruction(instruction ins)
+{
+ return false;
+}
bool TakesVexPrefix(instruction ins)
{
return false;
}
-size_t AddVexPrefixIfNeeded(instruction ins, size_t code, emitAttr attr)
+code_t AddVexPrefixIfNeeded(instruction ins, code_t code, emitAttr attr)
{
return code;
}
-size_t AddVexPrefixIfNeededAndNotPresent(instruction ins, size_t code, emitAttr size)
+code_t AddVexPrefixIfNeededAndNotPresent(instruction ins, code_t code, emitAttr size)
{
return code;
}
@@ -226,6 +260,18 @@ bool emitVerifyEncodable(instruction ins, emitAttr size, regNumber reg1, regNumb
bool emitInsCanOnlyWriteSSE2OrAVXReg(instrDesc* id);
+#if FEATURE_FIXED_OUT_ARGS
+void emitAdjustStackDepthPushPop(instruction ins)
+{
+}
+void emitAdjustStackDepth(instruction ins, ssize_t val)
+{
+}
+#else // !FEATURE_FIXED_OUT_ARGS
+void emitAdjustStackDepthPushPop(instruction ins);
+void emitAdjustStackDepth(instruction ins, ssize_t val);
+#endif // !FEATURE_FIXED_OUT_ARGS
+
/*****************************************************************************
*
* Convert between an index scale in bytes to a smaller encoding used for