summaryrefslogtreecommitdiff
path: root/src/jit
diff options
context:
space:
mode:
authorEgor Chesakov <Egor.Chesakov@microsoft.com>2018-08-03 12:35:33 -0700
committerGitHub <noreply@github.com>2018-08-03 12:35:33 -0700
commitf6e2b9c3b311f58497ccfc337e5925a95a2d008a (patch)
tree5c54edfe6ed76e63d21680b4bbcf5629ade90c5b /src/jit
parentd1c6a938e0f641f978fceb7834314ac6dba14adb (diff)
downloadcoreclr-f6e2b9c3b311f58497ccfc337e5925a95a2d008a.tar.gz
coreclr-f6e2b9c3b311f58497ccfc337e5925a95a2d008a.tar.bz2
coreclr-f6e2b9c3b311f58497ccfc337e5925a95a2d008a.zip
Handle MovRelocatableImmediate on ARM32 as a special case (IF_T2_N3) (#19013)
* Add IF_T2_N3 instruction form and make this a specific case of IF_T2_N when EA_IS_RELOC(attr) is true * Move "movw/movt reg,relocatableImm" case to function emitIns_MovRelocatableImmediate * Introduce new instruction descriptor instrDescReloc * Delete unused CnsVal from ARM32 and ARM64 emitters * Introduce target_ssize_t and use this type for non-relocatable constants
Diffstat (limited to 'src/jit')
-rw-r--r--src/jit/codegen.h2
-rw-r--r--src/jit/codegenarm.cpp2
-rw-r--r--src/jit/codegencommon.cpp6
-rw-r--r--src/jit/emit.cpp13
-rw-r--r--src/jit/emit.h54
-rw-r--r--src/jit/emitarm.cpp197
-rw-r--r--src/jit/emitarm.h13
-rw-r--r--src/jit/emitarm64.cpp21
-rw-r--r--src/jit/emitarm64.h7
-rw-r--r--src/jit/emitfmtsarm.h3
-rw-r--r--src/jit/instrsarm.h26
-rw-r--r--src/jit/target.h7
12 files changed, 226 insertions, 125 deletions
diff --git a/src/jit/codegen.h b/src/jit/codegen.h
index fbc79effa5..c00afb4c21 100644
--- a/src/jit/codegen.h
+++ b/src/jit/codegen.h
@@ -330,7 +330,7 @@ protected:
void genMov32RelocatableDisplacement(BasicBlock* block, regNumber reg);
void genMov32RelocatableDataLabel(unsigned value, regNumber reg);
- void genMov32RelocatableImmediate(emitAttr size, size_t value, regNumber reg);
+ void genMov32RelocatableImmediate(emitAttr size, BYTE* addr, regNumber reg);
bool genUsedPopToReturn; // True if we use the pop into PC to return,
// False if we didn't and must branch to LR to return.
diff --git a/src/jit/codegenarm.cpp b/src/jit/codegenarm.cpp
index 85d3e370cd..45616c72c8 100644
--- a/src/jit/codegenarm.cpp
+++ b/src/jit/codegenarm.cpp
@@ -78,7 +78,7 @@ void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size, regNumber reg, ssize_t imm,
if (EA_IS_RELOC(size))
{
- genMov32RelocatableImmediate(size, imm, reg);
+ genMov32RelocatableImmediate(size, (BYTE*)imm, reg);
}
else if (imm == 0)
{
diff --git a/src/jit/codegencommon.cpp b/src/jit/codegencommon.cpp
index 8572f288ca..4968990ab9 100644
--- a/src/jit/codegencommon.cpp
+++ b/src/jit/codegencommon.cpp
@@ -5684,12 +5684,12 @@ void CodeGen::genMov32RelocatableDataLabel(unsigned value, regNumber reg)
*
* Move of relocatable immediate to register
*/
-void CodeGen::genMov32RelocatableImmediate(emitAttr size, size_t value, regNumber reg)
+void CodeGen::genMov32RelocatableImmediate(emitAttr size, BYTE* addr, regNumber reg)
{
_ASSERTE(EA_IS_RELOC(size));
- getEmitter()->emitIns_R_I(INS_movw, size, reg, value);
- getEmitter()->emitIns_R_I(INS_movt, size, reg, value);
+ getEmitter()->emitIns_MovRelocatableImmediate(INS_movw, size, reg, addr);
+ getEmitter()->emitIns_MovRelocatableImmediate(INS_movt, size, reg, addr);
if (compiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_RELATIVE_CODE_RELOCS))
{
diff --git a/src/jit/emit.cpp b/src/jit/emit.cpp
index 748e1c3c00..96b8770ec9 100644
--- a/src/jit/emit.cpp
+++ b/src/jit/emit.cpp
@@ -2150,7 +2150,7 @@ const emitAttr emitter::emitSizeDecode[emitter::OPSZ_COUNT] = {EA_1BYTE, EA_2BYT
* a displacement and a constant.
*/
-emitter::instrDesc* emitter::emitNewInstrCnsDsp(emitAttr size, ssize_t cns, int dsp)
+emitter::instrDesc* emitter::emitNewInstrCnsDsp(emitAttr size, target_ssize_t cns, int dsp)
{
if (dsp == 0)
{
@@ -6697,7 +6697,7 @@ void emitter::emitNxtIG(bool emitAdd)
* emitGetInsSC: Get the instruction's constant value.
*/
-ssize_t emitter::emitGetInsSC(instrDesc* id)
+target_ssize_t emitter::emitGetInsSC(instrDesc* id)
{
#ifdef _TARGET_ARM_ // should it be _TARGET_ARMARCH_? Why do we need this? Note that on ARM64 we store scaled immediates
// for some formats
@@ -6734,6 +6734,15 @@ ssize_t emitter::emitGetInsSC(instrDesc* id)
}
}
+#ifdef _TARGET_ARM_
+
+BYTE* emitter::emitGetInsRelocValue(instrDesc* id)
+{
+ return ((instrDescReloc*)id)->idrRelocVal;
+}
+
+#endif // _TARGET_ARM_
+
/*****************************************************************************/
#if EMIT_TRACK_STACK_DEPTH
/*****************************************************************************
diff --git a/src/jit/emit.h b/src/jit/emit.h
index 03f4d42cf1..fcab878de3 100644
--- a/src/jit/emit.h
+++ b/src/jit/emit.h
@@ -1241,18 +1241,18 @@ protected:
struct instrDescCns : instrDesc // large const
{
- ssize_t idcCnsVal;
+ target_ssize_t idcCnsVal;
};
struct instrDescDsp : instrDesc // large displacement
{
- ssize_t iddDspVal;
+ target_ssize_t iddDspVal;
};
struct instrDescCnsDsp : instrDesc // large cons + disp
{
- ssize_t iddcCnsVal;
- int iddcDspVal;
+ target_ssize_t iddcCnsVal;
+ int iddcDspVal;
};
#ifdef _TARGET_XARCH_
@@ -1301,6 +1301,17 @@ protected:
#endif // MULTIREG_HAS_SECOND_GC_RET
};
+#ifdef _TARGET_ARM_
+
+ struct instrDescReloc : instrDesc
+ {
+ BYTE* idrRelocVal;
+ };
+
+ BYTE* emitGetInsRelocValue(instrDesc* id);
+
+#endif // _TARGET_ARM_
+
insUpdateModes emitInsUpdateMode(instruction ins);
insFormat emitInsModeFormat(instruction ins, insFormat base);
@@ -1326,7 +1337,7 @@ protected:
#endif // _TARGET_XARCH_
- ssize_t emitGetInsSC(instrDesc* id);
+ target_ssize_t emitGetInsSC(instrDesc* id);
unsigned emitInsCount;
/************************************************************************/
@@ -1813,10 +1824,13 @@ private:
instrDesc* emitNewInstrSmall(emitAttr attr);
instrDesc* emitNewInstr(emitAttr attr = EA_4BYTE);
- instrDesc* emitNewInstrSC(emitAttr attr, ssize_t cns);
- instrDesc* emitNewInstrCns(emitAttr attr, ssize_t cns);
- instrDesc* emitNewInstrDsp(emitAttr attr, ssize_t dsp);
- instrDesc* emitNewInstrCnsDsp(emitAttr attr, ssize_t cns, int dsp);
+ instrDesc* emitNewInstrSC(emitAttr attr, target_ssize_t cns);
+ instrDesc* emitNewInstrCns(emitAttr attr, target_ssize_t cns);
+ instrDesc* emitNewInstrDsp(emitAttr attr, target_ssize_t dsp);
+ instrDesc* emitNewInstrCnsDsp(emitAttr attr, target_ssize_t cns, int dsp);
+#ifdef _TARGET_ARM_
+ instrDesc* emitNewInstrReloc(emitAttr attr, BYTE* addr);
+#endif // _TARGET_ARM_
instrDescJmp* emitNewInstrJmp();
#if !defined(_TARGET_ARM64_)
@@ -2287,7 +2301,7 @@ inline emitter::instrDescLbl* emitter::emitNewInstrLbl()
}
#endif // !_TARGET_ARM64_
-inline emitter::instrDesc* emitter::emitNewInstrDsp(emitAttr attr, ssize_t dsp)
+inline emitter::instrDesc* emitter::emitNewInstrDsp(emitAttr attr, target_ssize_t dsp)
{
if (dsp == 0)
{
@@ -2322,7 +2336,7 @@ inline emitter::instrDesc* emitter::emitNewInstrDsp(emitAttr attr, ssize_t dsp)
* Note that this very similar to emitter::emitNewInstrSC(), except it never
* allocates a small descriptor.
*/
-inline emitter::instrDesc* emitter::emitNewInstrCns(emitAttr attr, ssize_t cns)
+inline emitter::instrDesc* emitter::emitNewInstrCns(emitAttr attr, target_ssize_t cns)
{
if (instrDesc::fitsInSmallCns(cns))
{
@@ -2385,7 +2399,7 @@ inline size_t emitter::emitGetInstrDescSize(const instrDesc* id)
* emitNewInstrCns() always allocates at least sizeof(instrDesc).
*/
-inline emitter::instrDesc* emitter::emitNewInstrSC(emitAttr attr, ssize_t cns)
+inline emitter::instrDesc* emitter::emitNewInstrSC(emitAttr attr, target_ssize_t cns)
{
instrDesc* id;
@@ -2428,6 +2442,22 @@ inline size_t emitter::emitGetInstrDescSizeSC(const instrDesc* id)
}
}
+#ifdef _TARGET_ARM_
+
+inline emitter::instrDesc* emitter::emitNewInstrReloc(emitAttr attr, BYTE* addr)
+{
+ assert(EA_IS_RELOC(attr));
+
+ instrDescReloc* id = (instrDescReloc*)emitAllocInstr(sizeof(instrDescReloc), attr);
+ assert(id->idIsReloc());
+
+ id->idrRelocVal = addr;
+
+ return id;
+}
+
+#endif // _TARGET_ARM_
+
#ifdef _TARGET_XARCH_
/*****************************************************************************
diff --git a/src/jit/emitarm.cpp b/src/jit/emitarm.cpp
index b32b974e23..8a6cde4b85 100644
--- a/src/jit/emitarm.cpp
+++ b/src/jit/emitarm.cpp
@@ -137,6 +137,12 @@ size_t emitter::emitSizeOfInsDsc(instrDesc* id)
break;
}
+ if (id->idInsFmt() == IF_T2_N3)
+ {
+ assert((id->idIns() == INS_movw) || (id->idIns() == INS_movt));
+ return sizeof(instrDescReloc);
+ }
+
if (id->idIsLargeCns())
{
if (id->idIsLargeDsp())
@@ -372,6 +378,7 @@ void emitter::emitInsSanityCheck(instrDesc* id)
case IF_T2_N: // T2_N .....i......iiii .iiiddddiiiiiiii R1 imm16
assert(isGeneralRegister(id->idReg1()));
+ assert(!id->idIsReloc());
break;
case IF_T2_N2: // T2_N2 .....i......iiii .iiiddddiiiiiiii R1 imm16
@@ -379,6 +386,11 @@ void emitter::emitInsSanityCheck(instrDesc* id)
assert((size_t)emitGetInsSC(id) < emitDataSize());
break;
+ case IF_T2_N3: // T2_N3 .....i......iiii .iiiddddiiiiiiii R1 imm16
+ assert(isGeneralRegister(id->idReg1()));
+ assert(id->idIsReloc());
+ break;
+
case IF_T2_I1: // T2_I1 ................ rrrrrrrrrrrrrrrr imm16
assert(emitGetInsSC(id) < 0x10000);
break;
@@ -541,6 +553,7 @@ bool emitter::emitInsMayWriteToGCReg(instrDesc* id)
case IF_T2_N:
case IF_T2_N1:
case IF_T2_N2:
+ case IF_T2_N3:
case IF_T2_VFP3:
case IF_T2_VFP2:
case IF_T2_VLDST:
@@ -899,12 +912,12 @@ emitter::code_t emitter::emitInsCode(instruction ins, insFormat fmt)
const static insFormat formatEncode5B[5] = { IF_T1_E, IF_T1_D0, IF_T1_J0, IF_T2_L2, IF_T2_C8 };
const static insFormat formatEncode4A[4] = { IF_T1_E, IF_T1_C, IF_T2_C4, IF_T2_C2 };
const static insFormat formatEncode4B[4] = { IF_T2_K2, IF_T2_H2, IF_T2_C7, IF_T2_K3 };
+ const static insFormat formatEncode4C[4] = { IF_T2_N, IF_T2_N1, IF_T2_N2, IF_T2_N3 };
const static insFormat formatEncode3A[3] = { IF_T1_E, IF_T2_C0, IF_T2_L0 };
const static insFormat formatEncode3B[3] = { IF_T1_E, IF_T2_C8, IF_T2_L2 };
const static insFormat formatEncode3C[3] = { IF_T1_E, IF_T2_C1, IF_T2_L1 };
const static insFormat formatEncode3D[3] = { IF_T1_L1, IF_T2_E2, IF_T2_I1 };
- const static insFormat formatEncode3E[3] = { IF_T2_N, IF_T2_N1, IF_T2_N2 };
- const static insFormat formatEncode3F[3] = { IF_T1_M, IF_T2_J2, IF_T2_J3 };
+ const static insFormat formatEncode3E[3] = { IF_T1_M, IF_T2_J2, IF_T2_J3 };
const static insFormat formatEncode2A[2] = { IF_T1_K, IF_T2_J1 };
const static insFormat formatEncode2B[2] = { IF_T1_D1, IF_T1_D2 };
const static insFormat formatEncode2C[2] = { IF_T1_D2, IF_T2_J3 };
@@ -1009,6 +1022,17 @@ emitter::code_t emitter::emitInsCode(instruction ins, insFormat fmt)
}
break;
+ case IF_EN4C:
+ for (index = 0; index < 4; index++)
+ {
+ if (fmt == formatEncode4C[index])
+ {
+ found = true;
+ break;
+ }
+ }
+ break;
+
case IF_EN3A:
for (index = 0; index < 3; index++)
{
@@ -1060,16 +1084,6 @@ emitter::code_t emitter::emitInsCode(instruction ins, insFormat fmt)
}
}
break;
- case IF_EN3F:
- for (index = 0; index < 3; index++)
- {
- if (fmt == formatEncode3F[index])
- {
- found = true;
- break;
- }
- }
- break;
case IF_EN2A:
for (index = 0; index < 2; index++)
@@ -1471,7 +1485,7 @@ void emitter::emitIns(instruction ins)
* Add an instruction with a single immediate value.
*/
-void emitter::emitIns_I(instruction ins, emitAttr attr, ssize_t imm)
+void emitter::emitIns_I(instruction ins, emitAttr attr, target_ssize_t imm)
{
insFormat fmt = IF_NONE;
bool hasLR = false;
@@ -1671,7 +1685,7 @@ void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg)
*/
void emitter::emitIns_R_I(
- instruction ins, emitAttr attr, regNumber reg, ssize_t imm, insFlags flags /* = INS_FLAGS_DONT_CARE */)
+ instruction ins, emitAttr attr, regNumber reg, target_ssize_t imm, insFlags flags /* = INS_FLAGS_DONT_CARE */)
{
insFormat fmt = IF_NONE;
@@ -1857,11 +1871,13 @@ void emitter::emitIns_R_I(
case INS_movw:
case INS_movt:
+ assert(!EA_IS_RELOC(attr));
assert(insDoesNotSetFlags(flags));
- sf = INS_FLAGS_NOT_SET;
- if ((imm & 0x0000ffff) == imm || EA_IS_RELOC(attr))
+
+ if ((imm & 0x0000ffff) == imm)
{
fmt = IF_T2_N;
+ sf = INS_FLAGS_NOT_SET;
}
else
{
@@ -1973,6 +1989,27 @@ void emitter::emitIns_R_I(
appendToCurIG(id);
}
+void emitter::emitIns_MovRelocatableImmediate(instruction ins, emitAttr attr, regNumber reg, BYTE* addr)
+{
+ assert(EA_IS_RELOC(attr));
+ assert((ins == INS_movw) || (ins == INS_movt));
+
+ insFormat fmt = IF_T2_N3;
+ insFlags sf = INS_FLAGS_NOT_SET;
+
+ instrDesc* id = emitNewInstrReloc(attr, addr);
+ insSize isz = emitInsSize(fmt);
+
+ id->idIns(ins);
+ id->idInsFmt(fmt);
+ id->idInsSize(isz);
+ id->idInsFlags(sf);
+ id->idReg1(reg);
+
+ dispIns(id);
+ appendToCurIG(id);
+}
+
/*****************************************************************************
*
* Add an instruction referencing two registers
@@ -4906,6 +4943,24 @@ inline unsigned insEncodeBitFieldImm(int imm)
/*****************************************************************************
*
+ * Returns an encoding for the immediate use by MOV/MOVW Thumb-2 encodings
+ */
+
+inline unsigned insEncodeImmT2_Mov(int imm)
+{
+ unsigned result;
+
+ assert((imm & 0x0000ffff) == imm);
+ result = (imm & 0x00ff);
+ result |= ((imm & 0x0700) << 4);
+ result |= ((imm & 0x0800) << 15);
+ result |= ((imm & 0xf000) << 4);
+
+ return result;
+}
+
+/*****************************************************************************
+ *
* Unscales the immediate based on the operand size in 'size'
*/
/*static*/ int emitter::insUnscaleImm(int imm, emitAttr size)
@@ -5501,9 +5556,9 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
case IF_T1_B: // T1_B ........cccc.... cond
{
assert(id->idGCref() == GCT_NONE);
- ssize_t condcode = emitGetInsSC(id);
- dst = emitOutputIT(dst, ins, fmt, condcode);
- sz = SMALL_IDSC_SIZE;
+ target_ssize_t condcode = emitGetInsSC(id);
+ dst = emitOutputIT(dst, ins, fmt, condcode);
+ sz = SMALL_IDSC_SIZE;
}
break;
#endif // FEATURE_ITINSTRUCTION
@@ -5921,53 +5976,74 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
dst += emitOutput_Thumb2Instr(dst, code);
break;
- case IF_T2_N: // T2_N .....i......iiii .iiiddddiiiiiiii R1 imm16
- case IF_T2_N2: // T2_N2 .....i......iiii .iiiddddiiiiiiii R1 imm16
+ case IF_T2_N: // T2_N .....i......iiii .iiiddddiiiiiiii R1 imm16
sz = emitGetInstrDescSizeSC(id);
code = emitInsCode(ins, fmt);
code |= insEncodeRegT2_D(id->idReg1());
imm = emitGetInsSC(id);
- if (fmt == IF_T2_N2)
+ if (id->idIsLclVar())
{
- assert(!id->idIsLclVar());
- assert((ins == INS_movw) || (ins == INS_movt));
- imm += (size_t)emitConsBlock;
- if (!id->idIsCnsReloc() && !id->idIsDspReloc())
+ if (ins == INS_movw)
{
- goto SPLIT_IMM;
+ imm &= 0xffff;
+ }
+ else
+ {
+ assert(ins == INS_movt);
+ imm = (imm >> 16) & 0xffff;
}
}
- else if (id->idIsLclVar())
+
+ assert(!id->idIsReloc());
+ code |= insEncodeImmT2_Mov(imm);
+ dst += emitOutput_Thumb2Instr(dst, code);
+ break;
+
+ case IF_T2_N2: // T2_N2 .....i......iiii .iiiddddiiiiiiii R1 imm16
+ sz = emitGetInstrDescSizeSC(id);
+ code = emitInsCode(ins, fmt);
+ code |= insEncodeRegT2_D(id->idReg1());
+ imm = emitGetInsSC(id);
+ addr = emitConsBlock + imm;
+ if (!id->idIsReloc())
{
- SPLIT_IMM:
+ assert(sizeof(size_t) == sizeof(target_size_t));
+ imm = (target_size_t)addr;
if (ins == INS_movw)
{
imm &= 0xffff;
}
else
{
+ assert(ins == INS_movt);
imm = (imm >> 16) & 0xffff;
}
- }
-
- if (id->idIsCnsReloc() || id->idIsDspReloc())
- {
- assert((ins == INS_movt) || (ins == INS_movw));
+ code |= insEncodeImmT2_Mov(imm);
dst += emitOutput_Thumb2Instr(dst, code);
- if ((ins == INS_movt) && emitComp->info.compMatchedVM)
- emitHandlePCRelativeMov32((void*)(dst - 8), (void*)imm);
}
else
{
- assert((imm & 0x0000ffff) == imm);
- code |= (imm & 0x00ff);
- code |= ((imm & 0x0700) << 4);
- code |= ((imm & 0x0800) << 15);
- code |= ((imm & 0xf000) << 4);
+ assert((ins == INS_movt) || (ins == INS_movw));
dst += emitOutput_Thumb2Instr(dst, code);
+ if ((ins == INS_movt) && emitComp->info.compMatchedVM)
+ emitHandlePCRelativeMov32((void*)(dst - 8), addr);
}
break;
+ case IF_T2_N3: // T2_N3 .....i......iiii .iiiddddiiiiiiii R1 imm16
+ sz = sizeof(instrDescReloc);
+ code = emitInsCode(ins, fmt);
+ code |= insEncodeRegT2_D(id->idReg1());
+
+ assert((ins == INS_movt) || (ins == INS_movw));
+ assert(id->idIsReloc());
+
+ addr = emitGetInsRelocValue(id);
+ dst += emitOutput_Thumb2Instr(dst, code);
+ if ((ins == INS_movt) && emitComp->info.compMatchedVM)
+ emitHandlePCRelativeMov32((void*)(dst - 8), addr);
+ break;
+
case IF_T2_VFP3:
// these are the binary operators
// d = n - m
@@ -6466,6 +6542,15 @@ void emitter::emitDispImm(int imm, bool addComma, bool alwaysHex /* =false */)
/*****************************************************************************
*
+ * Display a relocatable immediate value
+ */
+void emitter::emitDispReloc(BYTE* addr)
+{
+ printf("0x%p", dspPtr(addr));
+}
+
+/*****************************************************************************
+ *
* Display an arm condition for the IT instructions
*/
void emitter::emitDispCond(int cond)
@@ -6861,21 +6946,23 @@ void emitter::emitDispInsHelp(
case IF_T1_J0: // Reg, Imm
case IF_T2_L1:
case IF_T2_L2:
+ emitDispReg(id->idReg1(), attr, true);
+ imm = emitGetInsSC(id);
+ emitDispImm(imm, false, false);
+ break;
+
case IF_T2_N:
emitDispReg(id->idReg1(), attr, true);
imm = emitGetInsSC(id);
- if (fmt == IF_T2_N)
- {
- if (emitComp->opts.disDiffable)
- imm = 0xD1FF;
- if (id->idIsCnsReloc() || id->idIsDspReloc())
- {
- if (emitComp->opts.disDiffable)
- imm = 0xD1FFAB1E;
- printf("%s RELOC ", (id->idIns() == INS_movw) ? "LOW" : "HIGH");
- }
- }
- emitDispImm(imm, false, (fmt == IF_T2_N));
+ if (emitComp->opts.disDiffable)
+ imm = 0xD1FF;
+ emitDispImm(imm, false, true);
+ break;
+
+ case IF_T2_N3:
+ emitDispReg(id->idReg1(), attr, true);
+ printf("%s RELOC ", (id->idIns() == INS_movw) ? "LOW" : "HIGH");
+ emitDispReloc(emitGetInsRelocValue(id));
break;
case IF_T2_N2:
@@ -7650,7 +7737,7 @@ regNumber emitter::emitInsBinary(instruction ins, emitAttr attr, GenTree* dst, G
if (intConst)
{
- emitIns_R_I(ins, attr, dst->gtRegNum, intConst->IconValue());
+ emitIns_R_I(ins, attr, dst->gtRegNum, (target_ssize_t)intConst->IconValue());
return dst->gtRegNum;
}
else
@@ -7737,7 +7824,7 @@ regNumber emitter::emitInsTernary(instruction ins, emitAttr attr, GenTree* dst,
if (intConst != nullptr)
{
- emitIns_R_R_I(ins, attr, dst->gtRegNum, nonIntReg->gtRegNum, intConst->IconValue(), flags);
+ emitIns_R_R_I(ins, attr, dst->gtRegNum, nonIntReg->gtRegNum, (target_ssize_t)intConst->IconValue(), flags);
}
else
{
diff --git a/src/jit/emitarm.h b/src/jit/emitarm.h
index 702588a8c1..98d562a84e 100644
--- a/src/jit/emitarm.h
+++ b/src/jit/emitarm.h
@@ -12,12 +12,6 @@ typedef unsigned int code_t;
/* Routines that compute the size of / encode instructions */
/************************************************************************/
-struct CnsVal
-{
- int cnsVal;
- bool cnsReloc;
-};
-
insSize emitInsSize(insFormat insFmt);
#ifdef FEATURE_ITINSTRUCTION
@@ -38,6 +32,7 @@ static unsigned emitOutput_Thumb2Instr(BYTE* dst, code_t code);
void emitDispInst(instruction ins, insFlags flags);
void emitDispImm(int imm, bool addComma, bool alwaysHex = false);
+void emitDispReloc(BYTE* addr);
void emitDispCond(int cond);
void emitDispShiftOpts(insOpts opt);
void emitDispRegmask(int imm, bool encodedPC_LR);
@@ -221,11 +216,13 @@ static bool emitIns_valid_imm_for_vldst_offset(int imm);
void emitIns(instruction ins);
-void emitIns_I(instruction ins, emitAttr attr, ssize_t imm);
+void emitIns_I(instruction ins, emitAttr attr, target_ssize_t imm);
void emitIns_R(instruction ins, emitAttr attr, regNumber reg);
-void emitIns_R_I(instruction ins, emitAttr attr, regNumber reg, ssize_t imm, insFlags flags = INS_FLAGS_DONT_CARE);
+void emitIns_R_I(
+ instruction ins, emitAttr attr, regNumber reg, target_ssize_t imm, insFlags flags = INS_FLAGS_DONT_CARE);
+void emitIns_MovRelocatableImmediate(instruction ins, emitAttr attr, regNumber reg, BYTE* addr);
void emitIns_R_R(instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, insFlags flags = INS_FLAGS_DONT_CARE);
diff --git a/src/jit/emitarm64.cpp b/src/jit/emitarm64.cpp
index fed3b5d8a5..f0955f557f 100644
--- a/src/jit/emitarm64.cpp
+++ b/src/jit/emitarm64.cpp
@@ -10258,27 +10258,6 @@ void emitter::emitDispInst(instruction ins)
/*****************************************************************************
*
- * Display an reloc value
- * If we are formatting for an assembly listing don't print the hex value
- * since it will prevent us from doing assembly diffs
- */
-void emitter::emitDispReloc(int value, bool addComma)
-{
- if (emitComp->opts.disAsm)
- {
- printf("(reloc)");
- }
- else
- {
- printf("(reloc 0x%x)", dspPtr(value));
- }
-
- if (addComma)
- printf(", ");
-}
-
-/*****************************************************************************
- *
* Display an immediate value
*/
void emitter::emitDispImm(ssize_t imm, bool addComma, bool alwaysHex /* =false */)
diff --git a/src/jit/emitarm64.h b/src/jit/emitarm64.h
index 1b03dffd14..bf22738d32 100644
--- a/src/jit/emitarm64.h
+++ b/src/jit/emitarm64.h
@@ -16,12 +16,6 @@ static bool strictArmAsm;
/* Routines that compute the size of / encode instructions */
/************************************************************************/
-struct CnsVal
-{
- ssize_t cnsVal;
- bool cnsReloc;
-};
-
#ifdef DEBUG
/************************************************************************/
@@ -32,7 +26,6 @@ const char* emitFPregName(unsigned reg, bool varName = true);
const char* emitVectorRegName(regNumber reg);
void emitDispInst(instruction ins);
-void emitDispReloc(int value, bool addComma);
void emitDispImm(ssize_t imm, bool addComma, bool alwaysHex = false);
void emitDispFloatZero();
void emitDispFloatImm(ssize_t imm8);
diff --git a/src/jit/emitfmtsarm.h b/src/jit/emitfmtsarm.h
index bc7492003a..1adc8cc8c3 100644
--- a/src/jit/emitfmtsarm.h
+++ b/src/jit/emitfmtsarm.h
@@ -57,12 +57,12 @@ IF_DEF(EN5A, IS_NONE, NONE) // Instruction has 5 possib
IF_DEF(EN5B, IS_NONE, NONE) // Instruction has 5 possible encoding types, type B
IF_DEF(EN4A, IS_NONE, NONE) // Instruction has 4 possible encoding types, type A
IF_DEF(EN4B, IS_NONE, NONE) // Instruction has 4 possible encoding types, type B
+IF_DEF(EN4C, IS_NONE, NONE) // Instruction has 4 possible encoding types, type C
IF_DEF(EN3A, IS_NONE, NONE) // Instruction has 3 possible encoding types, type A
IF_DEF(EN3B, IS_NONE, NONE) // Instruction has 3 possible encoding types, type B
IF_DEF(EN3C, IS_NONE, NONE) // Instruction has 3 possible encoding types, type C
IF_DEF(EN3D, IS_NONE, NONE) // Instruction has 3 possible encoding types, type D
IF_DEF(EN3E, IS_NONE, NONE) // Instruction has 3 possible encoding types, type E
-IF_DEF(EN3F, IS_NONE, NONE) // Instruction has 3 possible encoding types, type F
IF_DEF(EN2A, IS_NONE, NONE) // Instruction has 2 possible encoding types, type A
IF_DEF(EN2B, IS_NONE, NONE) // Instruction has 2 possible encoding types, type B
IF_DEF(EN2C, IS_NONE, NONE) // Instruction has 2 possible encoding types, type C
@@ -136,6 +136,7 @@ IF_DEF(T2_M1, IS_NONE, LBL ) // T2_M1 .....i..........
IF_DEF(T2_N, IS_NONE, NONE) // T2_N .....i......iiii .iiiddddiiiiiiii R1 imm16 ; movw/movt
IF_DEF(T2_N1, IS_NONE, JMP) // T2_N1 .....i......iiii .iiiddddiiiiiiii R1 imm16 ; movw/movt of a code address
IF_DEF(T2_N2, IS_NONE, NONE) // T2_N2 .....i......iiii .iiiddddiiiiiiii R1 imm16 ; movw/movt of a data address
+IF_DEF(T2_N3, IS_NONE, NONE) // T2_N3 .....i......iiii .iiiddddiiiiiiii R1 imm16 ; movw/movt (relocatable imm)
IF_DEF(T2_VLDST, IS_NONE, NONE) // T2_VLDST 11101101UD0Lnnnn dddd101Ziiiiiiii D1 R2 imm(+-1020)
IF_DEF(T2_VFP2, IS_NONE, NONE) // T2_VFP2 111011101D110--- dddd101Z--M0mmmm D1 D2
IF_DEF(T2_VFP3, IS_NONE, NONE) // T2_VFP3 11101110-D--nnnn dddd101ZN-M0mmmm D1 D2 D3
diff --git a/src/jit/instrsarm.h b/src/jit/instrsarm.h
index 297cea92a8..88ef98a57f 100644
--- a/src/jit/instrsarm.h
+++ b/src/jit/instrsarm.h
@@ -205,6 +205,19 @@ INST4(pli, "pli", 0,LD, IF_EN4B, 0xF990F000, 0xF910FC00, 0xF910F000, 0
// pli [PC+-i12] T2_K3 11111001U0011111 1111iiiiiiiiiiii F91F F000 imm(+-4095)
#endif // FEATURE_PLI_INSTRUCTION
+// enum name FP LD/ST Rd,i16 Rd,i16 Rd,i16 Rd,i16
+// T2_N T2_N1 T2_N2 T2_N3
+INST4(movt, "movt", 0, 0, IF_EN4C, 0xF2C00000,0xF2C00000,0xF2C00000,0xF2C00000)
+ // Rd,i16 T2_N 11110i101100iiii 0iiiddddiiiiiiii F2C0 0000 imm(0-65535)
+ // Rd,i16 T2_N1 11110i101100iiii 0iiiddddiiiiiiii F2C0 0000 imm(0-65535)
+ // Rd,i16 T2_N2 11110i101100iiii 0iiiddddiiiiiiii F2C0 0000 imm(0-65535)
+ // Rd,i16 T2_N3 11110i101100iiii 0iiiddddiiiiiiii F2C0 0000 imm(0-65535)
+INST4(movw, "movw", 0, 0, IF_EN4C, 0xF2400000,0xF2400000,0xF2400000,0xF2400000)
+ // Rd,+i16 T2_N 11110i100100iiii 0iiiddddiiiiiiii F240 0000 imm(0-65535)
+ // Rd,+i16 T2_N1 11110i100100iiii 0iiiddddiiiiiiii F240 0000 imm(0-65535)
+ // Rd,+i16 T2_N2 11110i100100iiii 0iiiddddiiiiiiii F240 0000 imm(0-65535)
+ // Rd,+i16 T2_N3 11110i100100iiii 0iiiddddiiiiiiii F240 0000 imm(0-65535)
+
// enum name FP LD/ST Rdn, Rm Rd,Rn,Rm,sh Rd,Rn,i12
// T1_E T2_C0 T2_L0
INST3(and, "and", 0, 0, IF_EN3A, 0x4000, 0xEA000000, 0xF0000000)
@@ -271,20 +284,9 @@ INST3(pop, "pop", 0, 0, IF_EN3D, 0xBC00, 0xF85D0B04, 0xE8BD0000)
// pop rT T2_E2 1111100001011101 tttt101100000100 F85D 0B04
// pop <reglist16> T2_I1 1110100010111101 PM0rrrrrrrrrrrrr E8BD 0000
-// enum name FP LD/ST Rd,i16 Rd,i16 Rd,i16
-// T2_N T2_N1 T2_N2
-INST3(movt, "movt", 0, 0, IF_EN3E, 0xF2C00000,0xF2C00000,0xF2C00000)
- // Rd,i16 T2_N 11110i101100iiii 0iiiddddiiiiiiii F2C0 0000 imm(0-65535)
- // Rd,i16 T2_N1 11110i101100iiii 0iiiddddiiiiiiii F2C0 0000 imm(0-65535)
- // Rd,i16 T2_N2 11110i101100iiii 0iiiddddiiiiiiii F2C0 0000 imm(0-65535)
-INST3(movw, "movw", 0, 0, IF_EN3E, 0xF2400000,0xF2400000,0xF2400000)
- // Rd,+i16 T2_N 11110i100100iiii 0iiiddddiiiiiiii F240 0000 imm(0-65535)
- // Rd,+i16 T2_N1 11110i100100iiii 0iiiddddiiiiiiii F240 0000 imm(0-65535)
- // Rd,+i16 T2_N2 11110i100100iiii 0iiiddddiiiiiiii F240 0000 imm(0-65535)
-
// enum name FP LD/ST PC+-imm11 PC+-imm24 PC+-imm24
// T1_M T2_J2 T2_J3
-INST3(b, "b", 0, 0, IF_EN3F, 0xE000, 0xF0009000, 0xF0009000)
+INST3(b, "b", 0, 0, IF_EN3E, 0xE000, 0xF0009000, 0xF0009000)
// b PC+-i11 T1_M 11100iiiiiiiiiii E000 imm(-2048..2046)
// b PC+-i24 T2_J2 11110Siiiiiiiiii 10j1jiiiiiiiiiii F000 9000 imm(-16777216..16777214) (intra-procedure offset)
// b PC+-i24 T2_J3 11110Siiiiiiiiii 10j1jiiiiiiiiiii F000 9000 imm(-16777216..16777214) (inter-procedure offset)
diff --git a/src/jit/target.h b/src/jit/target.h
index 6cdbe4bd32..c9437f9721 100644
--- a/src/jit/target.h
+++ b/src/jit/target.h
@@ -1984,11 +1984,14 @@ C_ASSERT((RBM_INT_CALLEE_SAVED & RBM_FPBASE) == RBM_NONE);
#ifdef _TARGET_64BIT_
typedef unsigned __int64 target_size_t;
-#else
+typedef __int64 target_ssize_t;
+#else // !_TARGET_64BIT_
typedef unsigned int target_size_t;
-#endif
+typedef int target_ssize_t;
+#endif // !_TARGET_64BIT_
C_ASSERT(sizeof(target_size_t) == TARGET_POINTER_SIZE);
+C_ASSERT(sizeof(target_ssize_t) == TARGET_POINTER_SIZE);
/*****************************************************************************/
#endif // _TARGET_H_