@@ -5639,9 +5639,7 @@ void Compiler::lvaFixVirtualFrameOffsets()
56395639#endif 
56405640
56415641    //  The delta to be added to virtual offset to adjust it relative to frame pointer or SP
5642-     int  delta            = 0 ;
5643-     int  frameLocalsDelta = 0 ;
5644-     int  frameBoundary    = 0 ;
5642+     int  delta = 0 ;
56455643
56465644#ifdef  TARGET_XARCH
56475645    delta += REGSIZE_BYTES; //  pushed PC (return address) for x86/x64
@@ -5666,25 +5664,7 @@ void Compiler::lvaFixVirtualFrameOffsets()
56665664        //  We set FP to be after LR, FP
56675665        delta += 2  * REGSIZE_BYTES;
56685666    }
5669- #elif  defined(TARGET_ARM64)
5670-     else 
5671-     {
5672-         //  FP is used.
5673-         delta += codeGen->genTotalFrameSize () - codeGen->genSPtoFPdelta ();
5674- 
5675-         //  If we placed FP/LR at the bottom of the frame we need to shift all the variables
5676-         //  on the new frame to account for it. See lvaAssignVirtualFrameOffsetsToLocals.
5677-         if  (!codeGen->IsSaveFpLrWithAllCalleeSavedRegisters ())
5678-         {
5679-             //  We set FP to be after LR, FP
5680-             frameLocalsDelta = 2  * REGSIZE_BYTES;
5681-             frameBoundary    = opts.IsOSR () ? -info.compPatchpointInfo ->TotalFrameSize () : 0 ;
5682-             if  (info.compIsVarArgs )
5683-                 frameBoundary -= MAX_REG_ARG * REGSIZE_BYTES;
5684-         }
5685-         JITDUMP (" --- delta bump %d for FP frame, %d inside frame for FP/LR relocation\n " 
5686-     }
5687- #elif  defined(TARGET_AMD64)
5667+ #elif  defined(TARGET_AMD64) || defined(TARGET_ARM64)
56885668    else 
56895669    {
56905670        //  FP is used.
@@ -5752,7 +5732,7 @@ void Compiler::lvaFixVirtualFrameOffsets()
57525732
57535733#if  defined(TARGET_X86)
57545734            //  On x86, we set the stack offset for a promoted field
5755-             //  to match a struct parameter in lvaAssignFrameOffsetsToPromotedStructs .
5735+             //  to match a struct parameter in lvAssignFrameOffsetsToPromotedStructs .
57565736            if  ((!varDsc->lvIsParam  || parentvarDsc->lvIsParam ) && promotionType == PROMOTION_TYPE_DEPENDENT)
57575737#else 
57585738            if  (!varDsc->lvIsParam  && promotionType == PROMOTION_TYPE_DEPENDENT)
@@ -5772,23 +5752,15 @@ void Compiler::lvaFixVirtualFrameOffsets()
57725752
57735753        if  (doAssignStkOffs)
57745754        {
5775-             int  localDelta = delta;
5776- 
5777-             if  (frameLocalsDelta != 0  && varDsc->GetStackOffset () < frameBoundary)
5778-             {
5779-                 localDelta += frameLocalsDelta;
5780-             }
5781- 
5782-             JITDUMP (" -- V%02u was %d, now %d\n " GetStackOffset (),
5783-                     varDsc->GetStackOffset () + localDelta);
5784-             varDsc->SetStackOffset (varDsc->GetStackOffset () + localDelta);
5755+             JITDUMP (" -- V%02u was %d, now %d\n " GetStackOffset (), varDsc->GetStackOffset () + delta);
5756+             varDsc->SetStackOffset (varDsc->GetStackOffset () + delta);
57855757
57865758#if  DOUBLE_ALIGN
57875759            if  (genDoubleAlign () && !codeGen->isFramePointerUsed ())
57885760            {
57895761                if  (varDsc->lvFramePointerBased )
57905762                {
5791-                     varDsc->SetStackOffset (varDsc->GetStackOffset () - localDelta );
5763+                     varDsc->SetStackOffset (varDsc->GetStackOffset () - delta );
57925764
57935765                    //  We need to re-adjust the offsets of the parameters so they are EBP
57945766                    //  relative rather than stack/frame pointer relative
@@ -5810,13 +5782,9 @@ void Compiler::lvaFixVirtualFrameOffsets()
58105782    assert (codeGen->regSet .tmpAllFree ());
58115783    for  (TempDsc* temp = codeGen->regSet .tmpListBeg (); temp != nullptr ; temp = codeGen->regSet .tmpListNxt (temp))
58125784    {
5813-         temp->tdAdjustTempOffs (delta + frameLocalsDelta );
5785+         temp->tdAdjustTempOffs (delta);
58145786    }
58155787
5816-     if  (lvaCachedGenericContextArgOffs < frameBoundary)
5817-     {
5818-         lvaCachedGenericContextArgOffs += frameLocalsDelta;
5819-     }
58205788    lvaCachedGenericContextArgOffs += delta;
58215789
58225790#if  FEATURE_FIXED_OUT_ARGS
@@ -6072,6 +6040,30 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
60726040        codeGen->setFramePointerUsed (codeGen->isFramePointerRequired ());
60736041    }
60746042
6043+ #ifdef  TARGET_ARM64
6044+     //  Decide where to save FP and LR registers. We store FP/LR registers at the bottom of the frame if there is
6045+     //  a frame pointer used (so we get positive offsets from the frame pointer to access locals), but not if we
6046+     //  need a GS cookie AND localloc is used, since we need the GS cookie to protect the saved return value,
6047+     //  and also the saved frame pointer. See CodeGen::genPushCalleeSavedRegisters() for more details about the
6048+     //  frame types. Since saving FP/LR at high addresses is a relatively rare case, force using it during stress.
6049+     //  (It should be legal to use these frame types for every frame).
6050+ 
6051+     if  (opts.compJitSaveFpLrWithCalleeSavedRegisters  == 0 )
6052+     {
6053+         //  Default configuration
6054+         codeGen->SetSaveFpLrWithAllCalleeSavedRegisters ((getNeedsGSSecurityCookie () && compLocallocUsed) ||
6055+                                                         opts.compDbgEnC  || compStressCompile (STRESS_GENERIC_VARN, 20 ));
6056+     }
6057+     else  if  (opts.compJitSaveFpLrWithCalleeSavedRegisters  == 1 )
6058+     {
6059+         codeGen->SetSaveFpLrWithAllCalleeSavedRegisters (false ); //  Disable using new frames
6060+     }
6061+     else  if  ((opts.compJitSaveFpLrWithCalleeSavedRegisters  == 2 ) || (opts.compJitSaveFpLrWithCalleeSavedRegisters  == 3 ))
6062+     {
6063+         codeGen->SetSaveFpLrWithAllCalleeSavedRegisters (true ); //  Force using new frames
6064+     }
6065+ #endif  //  TARGET_ARM64
6066+ 
60756067#ifdef  TARGET_XARCH
60766068    //  On x86/amd64, the return address has already been pushed by the call instruction in the caller.
60776069    stkOffs -= TARGET_POINTER_SIZE; //  return address;
@@ -6120,13 +6112,9 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
61206112#endif  //  !TARGET_ARM
61216113
61226114#ifdef  TARGET_ARM64
6123-     //  If the frame pointer is used, then we'll save FP/LR either at the bottom of the stack
6124-     //  or at the top of the stack depending on frame type. We make the decision after assigning
6125-     //  the variables on the frame and then fix up the offsets in lvaFixVirtualFrameOffsets.
6126-     //  For now, we proceed as if FP/LR were saved with the callee registers. If we later
6127-     //  decide to move the FP/LR to the bottom of the frame it shifts all the assigned
6128-     //  variables and temporaries by 16 bytes. The largest alignment we currently make is 16
6129-     //  bytes for SIMD.
6115+     //  If the frame pointer is used, then we'll save FP/LR at the bottom of the stack.
6116+     //  Otherwise, we won't store FP, and we'll store LR at the top, with the other callee-save
6117+     //  registers (if any).
61306118
61316119    int  initialStkOffs = 0 ;
61326120    if  (info.compIsVarArgs )
@@ -6137,7 +6125,17 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
61376125        stkOffs -= initialStkOffs;
61386126    }
61396127
6140-     stkOffs -= compCalleeRegsPushed * REGSIZE_BYTES;
6128+     if  (codeGen->IsSaveFpLrWithAllCalleeSavedRegisters () || !isFramePointerUsed ()) //  Note that currently we always have
6129+                                                                                    //  a frame pointer
6130+     {
6131+         stkOffs -= compCalleeRegsPushed * REGSIZE_BYTES;
6132+     }
6133+     else 
6134+     {
6135+         //  Subtract off FP and LR.
6136+         assert (compCalleeRegsPushed >= 2 );
6137+         stkOffs -= (compCalleeRegsPushed - 2 ) * REGSIZE_BYTES;
6138+     }
61416139
61426140#elif  defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
61436141
@@ -6807,6 +6805,15 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
68076805    }
68086806#endif  //  TARGET_AMD64
68096807
6808+ #ifdef  TARGET_ARM64
6809+     if  (!codeGen->IsSaveFpLrWithAllCalleeSavedRegisters () && isFramePointerUsed ()) //  Note that currently we always have
6810+                                                                                    //  a frame pointer
6811+     {
6812+         //  Create space for saving FP and LR.
6813+         stkOffs -= 2  * REGSIZE_BYTES;
6814+     }
6815+ #endif  //  TARGET_ARM64
6816+ 
68106817#if  FEATURE_FIXED_OUT_ARGS
68116818    if  (lvaOutgoingArgSpaceSize > 0 )
68126819    {
@@ -6844,44 +6851,6 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
68446851
68456852    noway_assert (compLclFrameSize + originalFrameSize ==
68466853                 (unsigned )-(stkOffs + (pushedCount * (int )TARGET_POINTER_SIZE)));
6847- 
6848- #ifdef  TARGET_ARM64
6849-     //  Decide where to save FP and LR registers. We store FP/LR registers at the bottom of the frame if there is
6850-     //  a frame pointer used (so we get positive offsets from the frame pointer to access locals), but not if we
6851-     //  need a GS cookie AND localloc is used, since we need the GS cookie to protect the saved return value,
6852-     //  and also the saved frame pointer. See CodeGen::genPushCalleeSavedRegisters() for more details about the
6853-     //  frame types. Since saving FP/LR at high addresses is a relatively rare case, force using it during stress.
6854-     //  (It should be legal to use these frame types for every frame).
6855-     // 
6856-     //  For Apple NativeAOT ABI we try to save the FP/LR registers on top to get canonical frame layout that can
6857-     //  be represented with compact unwinding information. In order to maintain code quality we only do it when
6858-     //  we can use SP-based addressing (!isFramePointerRequired) through lvaFrameAddress optimization, or if the
6859-     //  whole frame is small enough that the negative FP-based addressing can address the whole frame.
6860- 
6861-     if  (opts.compJitSaveFpLrWithCalleeSavedRegisters  == 0 )
6862-     {
6863-         if  (IsTargetAbi (CORINFO_NATIVEAOT_ABI) && TargetOS::IsApplePlatform &&
6864-             (!codeGen->isFramePointerRequired () || codeGen->genTotalFrameSize () < 0x100 ))
6865-         {
6866-             codeGen->SetSaveFpLrWithAllCalleeSavedRegisters (true );
6867-         }
6868-         else 
6869-         {
6870-             //  Default configuration
6871-             codeGen->SetSaveFpLrWithAllCalleeSavedRegisters ((getNeedsGSSecurityCookie () && compLocallocUsed) ||
6872-                                                             opts.compDbgEnC  ||
6873-                                                             compStressCompile (Compiler::STRESS_GENERIC_VARN, 20 ));
6874-         }
6875-     }
6876-     else  if  (opts.compJitSaveFpLrWithCalleeSavedRegisters  == 1 )
6877-     {
6878-         codeGen->SetSaveFpLrWithAllCalleeSavedRegisters (false ); //  Disable using new frames
6879-     }
6880-     else  if  ((opts.compJitSaveFpLrWithCalleeSavedRegisters  == 2 ) || (opts.compJitSaveFpLrWithCalleeSavedRegisters  == 3 ))
6881-     {
6882-         codeGen->SetSaveFpLrWithAllCalleeSavedRegisters (true ); //  Force using new frames
6883-     }
6884- #endif  //  TARGET_ARM64
68856854}
68866855
68876856// ------------------------------------------------------------------------
0 commit comments