Handle MovRelocatableImmediate on ARM32 as a special case (IF_T2_N3) (#19013)
authorEgor Chesakov <Egor.Chesakov@microsoft.com>
Fri, 3 Aug 2018 19:35:33 +0000 (12:35 -0700)
committerGitHub <noreply@github.com>
Fri, 3 Aug 2018 19:35:33 +0000 (12:35 -0700)
* 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

12 files changed:
src/jit/codegen.h
src/jit/codegenarm.cpp
src/jit/codegencommon.cpp
src/jit/emit.cpp
src/jit/emit.h
src/jit/emitarm.cpp
src/jit/emitarm.h
src/jit/emitarm64.cpp
src/jit/emitarm64.h
src/jit/emitfmtsarm.h
src/jit/instrsarm.h
src/jit/target.h

index fbc79ef..c00afb4 100644 (file)
@@ -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.
index 85d3e37..45616c7 100644 (file)
@@ -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)
     {
index 8572f28..4968990 100644 (file)
@@ -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))
     {
index 748e1c3..96b8770 100644 (file)
@@ -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
 /*****************************************************************************
index 03f4d42..fcab878 100644 (file)
@@ -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_
 
 /*****************************************************************************
index b32b974..8a6cde4 100644 (file)
@@ -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
     {
index 702588a..98d562a 100644 (file)
@@ -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);
 
index fed3b5d..f0955f5 100644 (file)
@@ -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 */)
index 1b03dff..bf22738 100644 (file)
@@ -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);
index bc74920..1adc8cc 100644 (file)
@@ -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
index 297cea9..88ef98a 100644 (file)
@@ -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)
index 6cdbe4b..c9437f9 100644 (file)
@@ -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_