From 09fee89d6b753af6ebca6fb7a493f918e8dbacd7 Mon Sep 17 00:00:00 2001 From: Florian Krohm Date: Sat, 2 Feb 2013 22:58:25 +0000 Subject: [PATCH] s390: It is not necessary to save/restore the link register when making a helper call. The link register needs to be saved when switching between valgrind and client code and the dispatcher code already does that. Julian suggested this change when he merged the COMEM branch. This saves between 6% and 13% of insns on the perf bucket. Runtime difference is within noise margin. git-svn-id: svn://svn.valgrind.org/vex/trunk@2676 --- VEX/priv/host_s390_defs.c | 12 ------------ VEX/pub/libvex_s390x_common.h | 15 +++++++-------- 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/VEX/priv/host_s390_defs.c b/VEX/priv/host_s390_defs.c index 7b716a026d..1ff90cdd1e 100644 --- a/VEX/priv/host_s390_defs.c +++ b/VEX/priv/host_s390_defs.c @@ -8396,16 +8396,6 @@ s390_insn_helper_call_emit(UChar *buf, const s390_insn *insn) /* Stash away the client's FPC register because the helper might change it. */ buf = s390_emit_STFPC(buf, S390_REGNO_STACK_POINTER, S390_OFFSET_SAVED_FPC_C); - /* Before we can call the helper, we need to save the link register, - because the BASR will overwrite it. We cannot use a register for that. - (a) Volatile registers will be modified by the helper. - (b) For saved registers the client code assumes that they have not - changed after the function returns. So we cannot use it to store - the link register. - In the dispatcher, before calling the client code, we have arranged for - a location on the stack for this purpose. See dispatch-s390x-linux.S. */ - buf = s390_emit_STG(buf, S390_REGNO_LINK_REGISTER, 0, // save LR - S390_REGNO_STACK_POINTER, S390_OFFSET_SAVED_LR, 0); buf = s390_emit_BASR(buf, S390_REGNO_LINK_REGISTER, 1); // call helper /* Move the return value to the destination register */ @@ -8414,8 +8404,6 @@ s390_insn_helper_call_emit(UChar *buf, const s390_insn *insn) S390_REGNO_RETURN_VALUE); } - buf = s390_emit_LG(buf, S390_REGNO_LINK_REGISTER, 0, // restore LR - S390_REGNO_STACK_POINTER, S390_OFFSET_SAVED_LR, 0); buf = s390_emit_LFPC(buf, S390_REGNO_STACK_POINTER, // restore FPC S390_OFFSET_SAVED_FPC_C); diff --git a/VEX/pub/libvex_s390x_common.h b/VEX/pub/libvex_s390x_common.h index 0a8f44297d..221c9aa545 100644 --- a/VEX/pub/libvex_s390x_common.h +++ b/VEX/pub/libvex_s390x_common.h @@ -51,27 +51,26 @@ /*--- Offsets in the stack frame allocated by the dispatcher ---*/ /*--------------------------------------------------------------*/ +/* Dispatcher will save 8 FPRs at offsets 160 + 0 ... 160 + 56 */ + /* Where the dispatcher saves the r2 contents. */ -#define S390_OFFSET_SAVED_R2 160+96 +#define S390_OFFSET_SAVED_R2 160+80 /* Where client's FPC register is saved. */ -#define S390_OFFSET_SAVED_FPC_C 160+88 +#define S390_OFFSET_SAVED_FPC_C 160+72 /* Where valgrind's FPC register is saved. */ -#define S390_OFFSET_SAVED_FPC_V 160+80 - -/* Where client code will save the link register before calling a helper. */ -#define S390_OFFSET_SAVED_LR 160+72 +#define S390_OFFSET_SAVED_FPC_V 160+64 /* Size of frame allocated by VG_(disp_run_translations) Need size for 8 FPRs - + 2 GPRs (SAVED_LR, and SAVED_R2) + + 1 GPR (SAVED_R2) + 2 FPCs (SAVED_FPC_C and SAVED_FPC_V). Additionally, we need a standard frame for helper functions being called from client code. (See figure 1-16 in zSeries ABI) */ -#define S390_INNERLOOP_FRAME_SIZE ((8+2+2)*8 + 160) +#define S390_INNERLOOP_FRAME_SIZE ((8+1+2)*8 + 160) /*--------------------------------------------------------------*/ -- 2.47.2