From 32e340f2d132e58eb1a8da8be1b07f90a63f2c84 Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Tue, 17 May 2011 16:18:36 +0000 Subject: [PATCH] s390x: provide clock instructions like STCK s390x provides user space accessible instructions to get the HW time (e.g. via store clock STCK). while userspace programs should use gettimeofday and friends to cope with ntp/system time etc, a lot of programs still make use of STCK. valgrind should implement these instruction. (Christian Borntraeger and Divya Vyas) git-svn-id: svn://svn.valgrind.org/vex/trunk@2152 --- VEX/priv/guest_s390_defs.h | 3 ++ VEX/priv/guest_s390_helpers.c | 43 +++++++++++++++++++++++++ VEX/priv/guest_s390_toIR.c | 60 +++++++++++++++++++++++++++++++++-- 3 files changed, 103 insertions(+), 3 deletions(-) diff --git a/VEX/priv/guest_s390_defs.h b/VEX/priv/guest_s390_defs.h index dae1f443ff..630d3e0aa3 100644 --- a/VEX/priv/guest_s390_defs.h +++ b/VEX/priv/guest_s390_defs.h @@ -80,6 +80,9 @@ UInt s390_decode_and_irgen(UChar *, UInt, DisResult *); /*--- Dirty Helper functions. ---*/ /*------------------------------------------------------------*/ void s390x_dirtyhelper_EX(ULong torun); +ULong s390x_dirtyhelper_STCK(ULong *addr); +ULong s390x_dirtyhelper_STCKF(ULong *addr); +ULong s390x_dirtyhelper_STCKE(ULong *addr); /*------------------------------------------------------------*/ /*--- IR generators for special opcodes. ---*/ diff --git a/VEX/priv/guest_s390_helpers.c b/VEX/priv/guest_s390_helpers.c index f782501545..05f194c6cd 100644 --- a/VEX/priv/guest_s390_helpers.c +++ b/VEX/priv/guest_s390_helpers.c @@ -234,6 +234,49 @@ s390x_dirtyhelper_EX(ULong torun) last_execute_target = torun; } + +/*------------------------------------------------------------*/ +/*--- Dirty helper for Clock instructions ---*/ +/*------------------------------------------------------------*/ +#if defined(VGA_s390x) +ULong s390x_dirtyhelper_STCK(ULong *addr) +{ + int cc; + + asm volatile("stck %0\n" + "ipm %1\n" + "srl %1,28\n" + : "+Q" (*addr), "=d" (cc) : : "cc"); + return cc; +} + +ULong s390x_dirtyhelper_STCKE(ULong *addr) +{ + int cc; + + asm volatile("stcke %0\n" + "ipm %1\n" + "srl %1,28\n" + : "+Q" (*addr), "=d" (cc) : : "cc"); + return cc; +} + +ULong s390x_dirtyhelper_STCKF(ULong *addr) +{ + int cc; + + asm volatile(".insn s,0xb27c0000,%0\n" + "ipm %1\n" + "srl %1,28\n" + : "+Q" (*addr), "=d" (cc) : : "cc"); + return cc; +} +#else +ULong s390x_dirtyhelper_STCK(ULong *addr) {return 3;} +ULong s390x_dirtyhelper_STCKF(ULong *addr) {return 3;} +ULong s390x_dirtyhelper_STCKE(ULong *addr) {return 3;} +#endif /* VGA_s390x */ + /*------------------------------------------------------------*/ /*--- Helper for condition code. ---*/ /*------------------------------------------------------------*/ diff --git a/VEX/priv/guest_s390_toIR.c b/VEX/priv/guest_s390_toIR.c index 7200069fc1..15d1a7da4e 100644 --- a/VEX/priv/guest_s390_toIR.c +++ b/VEX/priv/guest_s390_toIR.c @@ -10498,6 +10498,60 @@ s390_irgen_FLOGR(UChar r1, UChar r2) return "flogr"; } +static HChar * +s390_irgen_STCK(IRTemp op2addr) +{ + IRDirty *d; + IRTemp cc = newTemp(Ity_I64); + + d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK", + &s390x_dirtyhelper_STCK, + mkIRExprVec_1(mkexpr(op2addr))); + d->mFx = Ifx_Write; + d->mAddr = mkexpr(op2addr); + d->mSize = 8; + stmt(IRStmt_Dirty(d)); + s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), + mkexpr(cc), mkU64(0), mkU64(0)); + return "stck"; +} + +static HChar * +s390_irgen_STCKF(IRTemp op2addr) +{ + IRDirty *d; + IRTemp cc = newTemp(Ity_I64); + + d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF", + &s390x_dirtyhelper_STCKF, + mkIRExprVec_1(mkexpr(op2addr))); + d->mFx = Ifx_Write; + d->mAddr = mkexpr(op2addr); + d->mSize = 8; + stmt(IRStmt_Dirty(d)); + s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), + mkexpr(cc), mkU64(0), mkU64(0)); + return "stckf"; +} + +static HChar * +s390_irgen_STCKE(IRTemp op2addr) +{ + IRDirty *d; + IRTemp cc = newTemp(Ity_I64); + + d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE", + &s390x_dirtyhelper_STCKE, + mkIRExprVec_1(mkexpr(op2addr))); + d->mFx = Ifx_Write; + d->mAddr = mkexpr(op2addr); + d->mSize = 16; + stmt(IRStmt_Dirty(d)); + s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), + mkexpr(cc), mkU64(0), mkU64(0)); + return "stcke"; +} + /*------------------------------------------------------------*/ /*--- Build IR for special instructions ---*/ /*------------------------------------------------------------*/ @@ -10844,7 +10898,7 @@ s390_decode_4byte_and_irgen(UChar *bytes) goto ok; case 0xb202: /* STIDP */ goto unimplemented; case 0xb204: /* SCK */ goto unimplemented; - case 0xb205: /* STCK */ goto unimplemented; + case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);goto ok; case 0xb206: /* SCKC */ goto unimplemented; case 0xb207: /* STCKC */ goto unimplemented; case 0xb208: /* SPT */ goto unimplemented; @@ -10921,9 +10975,9 @@ s390_decode_4byte_and_irgen(UChar *bytes) case 0xb274: /* SIGA */ goto unimplemented; case 0xb276: /* XSCH */ goto unimplemented; case 0xb277: /* RP */ goto unimplemented; - case 0xb278: /* STCKE */ goto unimplemented; + case 0xb278: s390_format_S_RD(s390_irgen_STCKE, ovl.fmt.S.b2, ovl.fmt.S.d2);goto ok; case 0xb279: /* SACF */ goto unimplemented; - case 0xb27c: /* STCKF */ goto unimplemented; + case 0xb27c: s390_format_S_RD(s390_irgen_STCKF, ovl.fmt.S.b2, ovl.fmt.S.d2);goto ok; case 0xb27d: /* STSI */ goto unimplemented; case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2); goto ok; -- 2.47.2