From 2a8aae5ef5fc4f241355fd919fa9f5b6dab24865 Mon Sep 17 00:00:00 2001 From: Mikhail Skvortcov Date: Mon, 6 Feb 2017 17:46:17 +0300 Subject: [PATCH] RyuJIT/ARM32: Enable P/Invoke lowering. Commit migrated from https://github.com/dotnet/coreclr/commit/af94355b2ba32c4baa8b76c2e57d81322f1780d8 --- src/coreclr/src/jit/codegenarm.cpp | 8 +++++++- src/coreclr/src/jit/lower.cpp | 17 +++++++++++------ src/coreclr/src/jit/lsra.cpp | 4 +++- src/coreclr/src/jit/lsraarm.cpp | 16 +++++++++++++++- src/coreclr/src/jit/morph.cpp | 8 +++++--- src/coreclr/src/jit/target.h | 2 +- 6 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/coreclr/src/jit/codegenarm.cpp b/src/coreclr/src/jit/codegenarm.cpp index 236a865..c24359f 100644 --- a/src/coreclr/src/jit/codegenarm.cpp +++ b/src/coreclr/src/jit/codegenarm.cpp @@ -1513,7 +1513,13 @@ void CodeGen::genCallInstruction(GenTreePtr node) } else { - if (varTypeIsFloating(returnType)) + if (call->IsHelperCall(compiler, CORINFO_HELP_INIT_PINVOKE_FRAME)) + { + // The CORINFO_HELP_INIT_PINVOKE_FRAME helper uses a custom calling convention that returns with + // TCB in REG_PINVOKE_TCB. fgMorphCall() sets the correct argument registers. + returnReg = REG_PINVOKE_TCB; + } + else if (varTypeIsFloating(returnType)) { returnReg = REG_FLOATRET; } diff --git a/src/coreclr/src/jit/lower.cpp b/src/coreclr/src/jit/lower.cpp index 33931c6..d271b42 100644 --- a/src/coreclr/src/jit/lower.cpp +++ b/src/coreclr/src/jit/lower.cpp @@ -2840,11 +2840,11 @@ void Lowering::InsertPInvokeMethodProlog() // for x86, don't pass the secretArg. CLANG_FORMAT_COMMENT_ANCHOR; -#ifdef _TARGET_X86_ +#if defined(_TARGET_X86_) || defined(_TARGET_ARM_) GenTreeArgList* argList = comp->gtNewArgList(frameAddr); -#else // !_TARGET_X86_ +#else GenTreeArgList* argList = comp->gtNewArgList(frameAddr, PhysReg(REG_SECRET_STUB_PARAM)); -#endif // !_TARGET_X86_ +#endif GenTree* call = comp->gtNewHelperCallNode(CORINFO_HELP_INIT_PINVOKE_FRAME, TYP_I_IMPL, 0, argList); @@ -2865,8 +2865,9 @@ void Lowering::InsertPInvokeMethodProlog() firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, store)); DISPTREERANGE(firstBlockRange, store); -#ifndef _TARGET_X86_ // For x86, this step is done at the call site (due to stack pointer not being static in the - // function). +#if !defined(_TARGET_X86_) && !defined(_TARGET_ARM_) + // For x86, this step is done at the call site (due to stack pointer not being static in the function). + // For arm32, CallSiteSP is set up by the call to CORINFO_HELP_INIT_PINVOKE_FRAME. // -------------------------------------------------------- // InlinedCallFrame.m_pCallSiteSP = @RSP; @@ -2878,7 +2879,10 @@ void Lowering::InsertPInvokeMethodProlog() firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, storeSP)); DISPTREERANGE(firstBlockRange, storeSP); -#endif // !_TARGET_X86_ +#endif // !defined(_TARGET_X86_) && !defined(_TARGET_ARM_) + +#if !defined(_TARGET_ARM_) + // For arm32, CalleeSavedFP is set up by the call to CORINFO_HELP_INIT_PINVOKE_FRAME. // -------------------------------------------------------- // InlinedCallFrame.m_pCalleeSavedEBP = @RBP; @@ -2890,6 +2894,7 @@ void Lowering::InsertPInvokeMethodProlog() firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, storeFP)); DISPTREERANGE(firstBlockRange, storeFP); +#endif // !defined(_TARGET_ARM_) // -------------------------------------------------------- // On 32-bit targets, CORINFO_HELP_INIT_PINVOKE_FRAME initializes the PInvoke frame and then pushes it onto diff --git a/src/coreclr/src/jit/lsra.cpp b/src/coreclr/src/jit/lsra.cpp index 2d317a7..a431019 100644 --- a/src/coreclr/src/jit/lsra.cpp +++ b/src/coreclr/src/jit/lsra.cpp @@ -2758,6 +2758,8 @@ regMaskTP LinearScan::getKillSetForNode(GenTree* tree) needFloatTmpForFPCall = true; } } +#endif // _TARGET_X86_ +#if defined(_TARGET_X86_) || defined(_TARGET_ARM_) if (tree->IsHelperCall()) { GenTreeCall* call = tree->AsCall(); @@ -2765,7 +2767,7 @@ regMaskTP LinearScan::getKillSetForNode(GenTree* tree) killMask = compiler->compHelperCallKillSet(helpFunc); } else -#endif // _TARGET_X86_ +#endif // defined(_TARGET_X86_) || defined(_TARGET_ARM_) { // if there is no FP used, we can ignore the FP kills if (compiler->compFloatingPointUsed) diff --git a/src/coreclr/src/jit/lsraarm.cpp b/src/coreclr/src/jit/lsraarm.cpp index ac06bbe..875d0a8 100644 --- a/src/coreclr/src/jit/lsraarm.cpp +++ b/src/coreclr/src/jit/lsraarm.cpp @@ -398,7 +398,13 @@ void Lowering::TreeNodeInfoInitCall(GenTreeCall* call) RegisterType registerType = call->TypeGet(); // Set destination candidates for return value of the call. - if (hasMultiRegRetVal) + if (call->IsHelperCall(compiler, CORINFO_HELP_INIT_PINVOKE_FRAME)) + { + // The ARM CORINFO_HELP_INIT_PINVOKE_FRAME helper uses a custom calling convention that returns with + // TCB in REG_PINVOKE_TCB. fgMorphCall() sets the correct argument registers. + info->setDstCandidates(l, RBM_PINVOKE_TCB); + } + else if (hasMultiRegRetVal) { assert(retTypeDesc != nullptr); info->setDstCandidates(l, retTypeDesc->GetABIReturnRegs()); @@ -850,6 +856,13 @@ void Lowering::TreeNodeInfoInit(GenTree* tree) CheckImmedAndMakeContained(tree, tree->gtOp.gtOp2); break; + case GT_RETURNTRAP: + // this just turns into a compare of its child with an int + // + a conditional call + info->srcCount = 1; + info->dstCount = 0; + break; + case GT_MUL: if (tree->gtOverflow()) { @@ -1074,6 +1087,7 @@ void Lowering::TreeNodeInfoInit(GenTree* tree) case GT_PUTARG_REG: case GT_PUTARG_STK: case GT_LABEL: + case GT_PINVOKE_PROLOG: info->dstCount = tree->IsValue() ? 1 : 0; if (kind & (GTK_CONST | GTK_LEAF)) { diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index cac0ee8..7fe7ee9 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -2881,9 +2881,9 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode) CLANG_FORMAT_COMMENT_ANCHOR; #if !defined(LEGACY_BACKEND) -#if defined(_TARGET_X86_) - // The x86 CORINFO_HELP_INIT_PINVOKE_FRAME helper has a custom calling convention. Set the argument registers - // correctly here. +#if defined(_TARGET_X86_) || defined(_TARGET_ARM_) + // The x86 and arm32 CORINFO_HELP_INIT_PINVOKE_FRAME helpers has a custom calling convention. + // Set the argument registers correctly here. if (call->IsHelperCall(this, CORINFO_HELP_INIT_PINVOKE_FRAME)) { GenTreeArgList* args = call->gtCallArgs; @@ -2891,6 +2891,8 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode) assert(arg1 != nullptr); nonStandardArgs.Add(arg1, REG_PINVOKE_FRAME); } +#endif // defined(_TARGET_X86_) || defined(_TARGET_ARM_) +#if defined(_TARGET_X86_) // The x86 shift helpers have custom calling conventions and expect the lo part of the long to be in EAX and the // hi part to be in EDX. This sets the argument registers up correctly. else if (call->IsHelperCall(this, CORINFO_HELP_LLSH) || call->IsHelperCall(this, CORINFO_HELP_LRSH) || diff --git a/src/coreclr/src/jit/target.h b/src/coreclr/src/jit/target.h index be2de57..2cee2c8 100644 --- a/src/coreclr/src/jit/target.h +++ b/src/coreclr/src/jit/target.h @@ -1446,7 +1446,7 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits #define RBM_STOP_FOR_GC_TRASH (RBM_CALLEE_TRASH & ~(RBM_FLOATRET | RBM_INTRET)) // The registers trashed by the CORINFO_HELP_INIT_PINVOKE_FRAME helper. - #define RBM_INIT_PINVOKE_FRAME_TRASH RBM_CALLEE_TRASH + #define RBM_INIT_PINVOKE_FRAME_TRASH (RBM_CALLEE_TRASH | RBM_PINVOKE_TCB | RBM_PINVOKE_SCRATCH) #define REG_FPBASE REG_R11 #define RBM_FPBASE RBM_R11 -- 2.7.4