Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Enable ETW_EBP_FRAMED flag on System V systems.
Browse files Browse the repository at this point in the history
Enable the ETW_EBP_FRAMED flag on System V systems to allow for using
frame pointer (RBP) for mostly all functions.
The change includes:
1. Removing RBP from all the lists of registers that the RA uses to assign
to tmps/vars/etc.
2. Enable generation of unwind info for pushing of REG_FPBASE even if not included in callee-save list
of registers.
3 Fixed a conservative assert - for System V systems stack offset for reg
passed argument can be 0 or even positive.
  • Loading branch information
LLITCHEV committed Mar 16, 2015
1 parent 6ccf4e2 commit 9cea5fe
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 22 deletions.
12 changes: 6 additions & 6 deletions src/jit/codegencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4835,11 +4835,12 @@ void CodeGen::genCheckUseBlockInit()
}

#ifdef _TARGET_XARCH_
// If we're going to use "REP STOS", remember that we will trash EDI
// For fastcall we will have to save ECX, EAX
// so reserve two extra callee saved
// This is better than pushing eax, ecx, because we in the later
// we will mess up already computed offsets on the stack (for ESP frames)
/* If we're going to use "REP STOS", remember that we will trash EDI */
/* For fastcall we will have to save ECX, EAX
* so reserve two extra callee saved
* This is better than pushing eax, ecx, because we in the later
* we will mess up already computed offsets on the stack (for ESP frames)
*/

regSet.rsSetRegsModified(RBM_EDI);

Expand Down Expand Up @@ -5168,7 +5169,6 @@ void CodeGen::genPushCalleeSavedRegisters()
offset += 2 * REGSIZE_BYTES;
}
}

if (frameType == 1)
{
getEmitter()->emitIns_R_R(INS_mov, EA_PTRSIZE, REG_FPBASE, REG_SPBASE);
Expand Down
7 changes: 7 additions & 0 deletions src/jit/emitxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1721,7 +1721,14 @@ UNATIVE_OFFSET emitter::emitInsSizeSV(size_t code, int var, int dsp)
#endif
{
// Dev10 804810 - failing this assert can lead to bad codegen and runtime crashes
#ifdef UNIX_AMD64_ABI
LclVarDsc* varDsc = emitComp->lvaTable + var;
bool isRegPassedArg = varDsc->lvIsParam && varDsc->lvIsRegArg;
// Register passed args could have a stack offset of 0.
noway_assert((int)offs < 0 || isRegPassedArg);
#else // !UNIX_AMD64_ABI
noway_assert((int)offs < 0);
#endif // !UNIX_AMD64_ABI
}


Expand Down
92 changes: 77 additions & 15 deletions src/jit/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -667,8 +667,7 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#ifndef UNIX_AMD64_ABI
#define ETW_EBP_FRAMED 0 // if 1 we cannot use EBP as a scratch register and must create EBP based frames for most methods
#else // UNIX_AMD64_ABI
// TODO-Amd64-Unis: Enable Frame Pointer chaining for most methods when uniwinding and the rest is implemented. Set the following to 1.
#define ETW_EBP_FRAMED 0 // if 1 we cannot use EBP as a scratch register and must create EBP based frames for most methods
#define ETW_EBP_FRAMED 1 // if 1 we cannot use EBP as a scratch register and must create EBP based frames for most methods
#endif // UNIX_AMD64_ABI
#define FEATURE_FP_REGALLOC 0 // Enabled if RegAlloc is used to enregister Floating Point LclVars
#define CSE_CONSTS 1 // Enable if we want to CSE constants
Expand Down Expand Up @@ -723,71 +722,134 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits

#define RBM_ALLINT (RBM_INT_CALLEE_SAVED | RBM_INT_CALLEE_TRASH)
#ifndef UNIX_AMD64_ABI
#if !ETW_EBP_FRAMED
#define RBM_LOWINT (RBM_EAX|RBM_ECX|RBM_EBX|RBM_EBP|RBM_ESI|RBM_EDI)
#else // ETW_EBP_FRAMED
#define RBM_LOWINT (RBM_EAX|RBM_ECX|RBM_EBX|RBM_ESI|RBM_EDI)
#endif // ETW_EBP_FRAMED
#else // UNIX_AMD64_ABI
#if !ETW_EBP_FRAMED
#define RBM_LOWINT (RBM_EAX|RBM_RDI|RBM_RSI|RBM_EDX|RBM_ECX|RBM_EBX|RBM_EBP)
#else // ETW_EBP_FRAMED
#define RBM_LOWINT (RBM_EAX|RBM_RDI|RBM_RSI|RBM_EDX|RBM_ECX|RBM_EBX)
#endif // ETW_EBP_FRAMED
#endif // UNIX_AMD64_ABI

#if 0
#if !ETW_EBP_FRAMED
#define REG_VAR_ORDER REG_EAX,REG_EDX,REG_ECX,REG_ESI,REG_EDI,REG_EBX,REG_EBP, \
REG_R8,REG_R9,REG_R10,REG_R11,REG_R14,REG_R15,REG_R12,REG_R13
#else // ETW_EBP_FRAMED
#define REG_VAR_ORDER REG_EAX,REG_EDX,REG_ECX,REG_ESI,REG_EDI,REG_EBX, \
REG_R8,REG_R9,REG_R10,REG_R11,REG_R14,REG_R15,REG_R12,REG_R13
#endif // ETW_EBP_FRAMED

#else
// TEMPORARY ORDER TO AVOID CALLEE-SAVES
// TODO-CQ: Review this and set appropriately
#ifndef UNIX_AMD64_ABI
#if !ETW_EBP_FRAMED
#define REG_VAR_ORDER REG_EAX,REG_EDX,REG_ECX, \
REG_R8,REG_R9,REG_R10,REG_R11, \
REG_ESI,REG_EDI,REG_EBX,REG_EBP, \
REG_R14,REG_R15,REG_R12,REG_R13
#else // ETW_EBP_FRAMED
#define REG_VAR_ORDER REG_EAX,REG_EDX,REG_ECX, \
REG_R8,REG_R9,REG_R10,REG_R11, \
REG_ESI,REG_EDI,REG_EBX, \
REG_R14,REG_R15,REG_R12,REG_R13
#endif // ETW_EBP_FRAMED
#else // UNIX_AMD64_ABI
#if !ETW_EBP_FRAMED
#define REG_VAR_ORDER \
REG_EAX, REG_EDI, REG_ESI, \
REG_EDX, REG_ECX, REG_R8, REG_R9, \
REG_R10, REG_R11, REG_EBX, REG_EBP, \
REG_R14, REG_R15, REG_R12, REG_R13
REG_EAX,REG_EDI,REG_ESI, \
REG_EDX,REG_ECX,REG_R8,REG_R9, \
REG_R10,REG_R11,REG_EBX,REG_EBP, \
REG_R14,REG_R15,REG_R12,REG_R13
#else // ETW_EBP_FRAMED
#define REG_VAR_ORDER \
REG_EAX,REG_EDI,REG_ESI, \
REG_EDX,REG_ECX,REG_R8,REG_R9, \
REG_R10,REG_R11,REG_EBX, \
REG_R14,REG_R15,REG_R12,REG_R13
#endif // ETW_EBP_FRAMED
#endif // UNIX_AMD64_ABI
#endif

#define REG_VAR_ORDER_FLT REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3, REG_XMM4, REG_XMM5, REG_XMM6, REG_XMM7, REG_XMM8, REG_XMM9, REG_XMM10, REG_XMM11, REG_XMM12, REG_XMM13, REG_XMM14, REG_XMM15

#define MAX_VAR_ORDER_SIZE 15
#define REG_VAR_ORDER_FLT REG_XMM0,REG_XMM1,REG_XMM2,REG_XMM3,REG_XMM4,REG_XMM5,REG_XMM6,REG_XMM7,REG_XMM8,REG_XMM9,REG_XMM10,REG_XMM11,REG_XMM12,REG_XMM13,REG_XMM14,REG_XMM15

#ifndef UNIX_AMD64_ABI
#if !ETW_EBP_FRAMED
#define MAX_VAR_ORDER_SIZE 15
#define REG_TMP_ORDER REG_EAX,REG_EDX,REG_ECX,REG_EBX,REG_ESI,REG_EDI,REG_EBP, \
REG_R8, REG_R9, REG_R10, REG_R11, REG_R14, REG_R15, REG_R12, REG_R13
REG_R8,REG_R9,REG_R10,REG_R11,REG_R14,REG_R15,REG_R12,REG_R13
#else // ETW_EBP_FRAMED
#define MAX_VAR_ORDER_SIZE 14
#define REG_TMP_ORDER REG_EAX,REG_EDX,REG_ECX,REG_EBX,REG_ESI,REG_EDI, \
REG_R8,REG_R9,REG_R10,REG_R11,REG_R14,REG_R15,REG_R12,REG_R13
#endif // ETW_EBP_FRAMED

#else // UNIX_AMD64_ABI
#if !ETW_EBP_FRAMED
#define REG_TMP_ORDER REG_EAX,REG_EDI,REG_ESI,REG_EDX,REG_ECX,REG_EBX,REG_EBP, \
REG_R8, REG_R9, REG_R10, REG_R11, REG_R14, REG_R15, REG_R12, REG_R13
REG_R8,REG_R9,REG_R10,REG_R11,REG_R14,REG_R15,REG_R12,REG_R13
#else // ETW_EBP_FRAMED
#define REG_TMP_ORDER REG_EAX,REG_EDI,REG_ESI,REG_EDX,REG_ECX,REG_EBX, \
REG_R8,REG_R9,REG_R10,REG_R11,REG_R14,REG_R15,REG_R12,REG_R13
#endif // ETW_EBP_FRAMED

#endif // UNIX_AMD64_ABI

#define REG_TMP_ORDER_COUNT 15
#ifndef UNIX_AMD64_ABI
#if !ETW_EBP_FRAMED
#define REG_TMP_ORDER_COUNT 15
#define REG_PREDICT_ORDER REG_EAX,REG_EDX,REG_ECX,REG_EBX,REG_ESI,REG_EDI,REG_EBP, \
REG_R8,REG_R9,REG_R10,REG_R11,REG_R14,REG_R15,REG_R12,REG_R13

#define CNT_CALLEE_SAVED (8)
#else // ETW_EBP_FRAMED
#define REG_TMP_ORDER_COUNT 14
#define REG_PREDICT_ORDER REG_EAX,REG_EDX,REG_ECX,REG_EBX,REG_ESI,REG_EDI, \
REG_R8,REG_R9,REG_R10,REG_R11,REG_R14,REG_R15,REG_R12,REG_R13
#define CNT_CALLEE_SAVED (7)
#endif // ETW_EBP_FRAMED

#define CNT_CALLEE_TRASH (7)
#define CNT_CALLEE_ENREG (CNT_CALLEE_SAVED)

#define CNT_CALLEE_SAVED_FLOAT (10)
#define CNT_CALLEE_TRASH_FLOAT (6)

#if !ETW_EBP_FRAMED
#define REG_CALLEE_SAVED_ORDER REG_EBX,REG_ESI,REG_EDI,REG_EBP,REG_R12,REG_R13,REG_R14,REG_R15
#define RBM_CALLEE_SAVED_ORDER RBM_EBX,RBM_ESI,RBM_EDI,RBM_EBP,RBM_R12,RBM_R13,RBM_R14,RBM_R15
#else // ETW_EBP_FRAMED
#define REG_CALLEE_SAVED_ORDER REG_EBX,REG_ESI,REG_EDI,REG_R12,REG_R13,REG_R14,REG_R15
#define RBM_CALLEE_SAVED_ORDER RBM_EBX,RBM_ESI,RBM_EDI,RBM_R12,RBM_R13,RBM_R14,RBM_R15
#endif // ETW_EBP_FRAMED
#define CALLEE_SAVED_REG_MAXSZ (CNT_CALLEE_SAVED*REGSIZE_BYTES) // RBX, RSI, RDI, RBP, R12, R13, R14, R15
#else // UNIX_AMD64_ABI
#if !ETW_EBP_FRAMED
#define REG_PREDICT_ORDER REG_EAX, REG_EDI, REG_ESI, REG_EDX, REG_ECX, REG_EBX, REG_EBP, \
REG_R8, REG_R9, REG_R10, REG_R11, REG_R14, REG_R15, REG_R12, REG_R13

REG_R8,REG_R9,REG_R10,REG_R11,REG_R14,REG_R15,REG_R12,REG_R13
#define CNT_CALLEE_SAVED (6)
#else // ETW_EBP_FRAMED
#define REG_PREDICT_ORDER REG_EAX, REG_EDI, REG_ESI, REG_EDX, REG_ECX, REG_EBX, \
REG_R8,REG_R9,REG_R10,REG_R11,REG_R14,REG_R15,REG_R12,REG_R13
#define CNT_CALLEE_SAVED (5)
#endif // ETW_EBP_FRAMED
#define CNT_CALLEE_TRASH (9)
#define CNT_CALLEE_ENREG (CNT_CALLEE_SAVED)

#define CNT_CALLEE_SAVED_FLOAT (0)
#define CNT_CALLEE_TRASH_FLOAT (16)

#if !ETW_EBP_FRAMED
#define REG_CALLEE_SAVED_ORDER REG_EBX,REG_EBP,REG_R12,REG_R13,REG_R14,REG_R15
#define RBM_CALLEE_SAVED_ORDER RBM_EBX,RBM_EBP,RBM_R12,RBM_R13,RBM_R14,RBM_R15
#else // ETW_EBP_FRAMED
#define REG_CALLEE_SAVED_ORDER REG_EBX,REG_R12,REG_R13,REG_R14,REG_R15
#define RBM_CALLEE_SAVED_ORDER RBM_EBX,RBM_R12,RBM_R13,RBM_R14,RBM_R15
#endif // ETW_EBP_FRAMED
#define CALLEE_SAVED_REG_MAXSZ (CNT_CALLEE_SAVED*REGSIZE_BYTES) // RBX, RBP, R12, R13, R14, R15
#endif // UNIX_AMD64_ABI

Expand Down
10 changes: 9 additions & 1 deletion src/jit/unwindamd64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,15 @@ void Compiler::unwindPush(regNumber reg)
unsigned int cbProlog = unwindGetCurrentOffset(func);
noway_assert((BYTE)cbProlog == cbProlog);
code->CodeOffset = (BYTE)cbProlog;
if (RBM_CALLEE_SAVED & genRegMask(reg))
if (RBM_CALLEE_SAVED & genRegMask(reg)
#if ETW_EBP_FRAMED
// In case of ETW_EBP_FRAMED defined the REG_FPBASE (RBP)
// is excluded from the callee-save register list.
// Make sure the register gets PUSH unwind info in this case,
// since it is pushed as a frame register.
|| (reg == REG_FPBASE)
#endif // ETW_EBP_FRAMED
)
{
code->UnwindOp = UWOP_PUSH_NONVOL;
code->OpInfo = (BYTE)reg;
Expand Down

0 comments on commit 9cea5fe

Please sign in to comment.