diff options
author | Egor Chesakov <Egor.Chesakov@microsoft.com> | 2018-08-03 12:35:33 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-03 12:35:33 -0700 |
commit | f6e2b9c3b311f58497ccfc337e5925a95a2d008a (patch) | |
tree | 5c54edfe6ed76e63d21680b4bbcf5629ade90c5b /src/jit | |
parent | d1c6a938e0f641f978fceb7834314ac6dba14adb (diff) | |
download | coreclr-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.h | 2 | ||||
-rw-r--r-- | src/jit/codegenarm.cpp | 2 | ||||
-rw-r--r-- | src/jit/codegencommon.cpp | 6 | ||||
-rw-r--r-- | src/jit/emit.cpp | 13 | ||||
-rw-r--r-- | src/jit/emit.h | 54 | ||||
-rw-r--r-- | src/jit/emitarm.cpp | 197 | ||||
-rw-r--r-- | src/jit/emitarm.h | 13 | ||||
-rw-r--r-- | src/jit/emitarm64.cpp | 21 | ||||
-rw-r--r-- | src/jit/emitarm64.h | 7 | ||||
-rw-r--r-- | src/jit/emitfmtsarm.h | 3 | ||||
-rw-r--r-- | src/jit/instrsarm.h | 26 | ||||
-rw-r--r-- | src/jit/target.h | 7 |
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_ |