|
From: <sv...@va...> - 2011-05-17 16:18:43
|
Author: sewardj
Date: 2011-05-17 17:18:36 +0100 (Tue, 17 May 2011)
New Revision: 2152
Log:
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 <bor...@de...> and Divya Vyas)
Modified:
trunk/priv/guest_s390_defs.h
trunk/priv/guest_s390_helpers.c
trunk/priv/guest_s390_toIR.c
Modified: trunk/priv/guest_s390_defs.h
===================================================================
--- trunk/priv/guest_s390_defs.h 2011-05-11 14:17:35 UTC (rev 2151)
+++ trunk/priv/guest_s390_defs.h 2011-05-17 16:18:36 UTC (rev 2152)
@@ -80,6 +80,9 @@
/*--- 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. ---*/
Modified: trunk/priv/guest_s390_helpers.c
===================================================================
--- trunk/priv/guest_s390_helpers.c 2011-05-11 14:17:35 UTC (rev 2151)
+++ trunk/priv/guest_s390_helpers.c 2011-05-17 16:18:36 UTC (rev 2152)
@@ -234,7 +234,50 @@
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. ---*/
/*------------------------------------------------------------*/
Modified: trunk/priv/guest_s390_toIR.c
===================================================================
--- trunk/priv/guest_s390_toIR.c 2011-05-11 14:17:35 UTC (rev 2151)
+++ trunk/priv/guest_s390_toIR.c 2011-05-17 16:18:36 UTC (rev 2152)
@@ -10498,6 +10498,60 @@
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 @@
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 @@
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;
|