[ARM/Linux] Set R2R_INDIRECT_PARAM before R2R call (#12952)
authorJonghyun Park <parjong@gmail.com>
Mon, 31 Jul 2017 18:17:47 +0000 (03:17 +0900)
committerBruce Forstall <brucefo@microsoft.com>
Mon, 31 Jul 2017 18:17:47 +0000 (11:17 -0700)
* Set R2R_INDIRECT_PARAM before R2R call

* Revise code formatting

* Preserve R2R_INDIRECT_PARAM across R2R call

* Fix format error

* Attempt to fix x86/Windows build error

* 2nd attempt to fix x86/Windows build error

* Revise RA to reserve R2R_INDIRECT_PARAM reg

* Fix format error

src/jit/codegenlegacy.cpp
src/jit/regalloc.cpp

index b84c30b..bb2a415 100644 (file)
@@ -19440,6 +19440,7 @@ regMaskTP CodeGen::genCodeForCall(GenTreeCall* call, bool valUsed)
                         break;
 
                         case IAT_PVALUE:
+                        {
                             //------------------------------------------------------
                             // Non-virtual direct calls to addresses accessed by
                             // a single indirection.
@@ -19448,10 +19449,28 @@ regMaskTP CodeGen::genCodeForCall(GenTreeCall* call, bool valUsed)
                             // Load the address into a register, load indirect and call  through a register
                             CLANG_FORMAT_COMMENT_ANCHOR;
 #if CPU_LOAD_STORE_ARCH
-                            indCallReg = regSet.rsGrabReg(RBM_ALLINT); // Grab an available register to use for the CALL
-                                                                       // indirection
+                            regMaskTP indCallMask = RBM_ALLINT;
+
+#ifdef FEATURE_READYTORUN_COMPILER
+                            if (call->IsR2RRelativeIndir())
+                            {
+                                indCallMask &= ~RBM_R2R_INDIRECT_PARAM;
+                            }
+#endif // FEATURE_READYTORUN_COMPILER
+
+                            // Grab an available register to use for the CALL indirection
+                            indCallReg = regSet.rsGrabReg(indCallMask);
 
                             instGen_Set_Reg_To_Imm(EA_HANDLE_CNS_RELOC, indCallReg, (ssize_t)addr);
+
+#ifdef FEATURE_READYTORUN_COMPILER
+                            if (call->IsR2RRelativeIndir())
+                            {
+                                noway_assert(regSet.rsRegMaskCanGrab() & RBM_R2R_INDIRECT_PARAM);
+                                getEmitter()->emitIns_R_R(INS_mov, EA_PTRSIZE, REG_R2R_INDIRECT_PARAM, indCallReg);
+                            }
+#endif // FEATURE_READYTORUN_COMPILER
+
                             getEmitter()->emitIns_R_R_I(INS_ldr, EA_PTRSIZE, indCallReg, indCallReg, 0);
                             regTracker.rsTrackRegTrash(indCallReg);
 
@@ -19471,7 +19490,8 @@ regMaskTP CodeGen::genCodeForCall(GenTreeCall* call, bool valUsed)
                                                        REG_NA, 0, 0, // xreg, xmul, disp
                                                        false,        /* isJump */
                                                        emitter::emitNoGChelper(helperNum));
-                            break;
+                        }
+                        break;
 
                         case IAT_PPVALUE:
                         {
index f9aa344..e522c00 100644 (file)
@@ -4835,6 +4835,17 @@ regMaskTP Compiler::rpPredictTreeRegUse(GenTreePtr   tree,
             }
             assert(list == NULL);
 
+#ifdef LEGACY_BACKEND
+#if CPU_LOAD_STORE_ARCH
+#ifdef FEATURE_READYTORUN_COMPILER
+            if (tree->gtCall.IsR2RRelativeIndir())
+            {
+                tree->gtUsedRegs |= RBM_R2R_INDIRECT_PARAM;
+            }
+#endif // FEATURE_READYTORUN_COMPILER
+#endif // CPU_LOAD_STORE_ARCH
+#endif // LEGACY_BACKEND
+
             regMaskTP callAddrMask;
             callAddrMask = RBM_NONE;
 #if CPU_LOAD_STORE_ARCH