[v1,for-2.12,7/9] s390x/tcg: implement extract-CPU-time facility

Message ID 20171204140150.20483-8-david@redhat.com
State New
Headers show
Series
  • s390x/tcg: facilitites and instructions
Related show

Commit Message

David Hildenbrand Dec. 4, 2017, 2:01 p.m.
It only provies the EXTRACT CPU TIME instruction. We can reuse the stpt
helper, which calculates the CPU timer value.

As the instruction is not priviledged, but we don't have a CPU timer
value in case of linux user, we simply fake the CPU timer to be 0.

Signed-off-by: David Hildenbrand <david@redhat.com>
---
 target/s390x/cpu_models.c  |  1 +
 target/s390x/insn-data.def |  2 ++
 target/s390x/translate.c   | 36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 39 insertions(+)

Comments

Cornelia Huck Dec. 5, 2017, 3:14 p.m. | #1
On Mon,  4 Dec 2017 15:01:48 +0100
David Hildenbrand <david@redhat.com> wrote:

> It only provies the EXTRACT CPU TIME instruction. We can reuse the stpt

s/provies/provides/

> helper, which calculates the CPU timer value.
> 
> As the instruction is not priviledged, but we don't have a CPU timer

s/priviledged/privileged/

> value in case of linux user, we simply fake the CPU timer to be 0.

There's probably nothing else we could do.

> 
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
>  target/s390x/cpu_models.c  |  1 +
>  target/s390x/insn-data.def |  2 ++
>  target/s390x/translate.c   | 36 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 39 insertions(+)
David Hildenbrand Dec. 5, 2017, 4:28 p.m. | #2
On 05.12.2017 16:14, Cornelia Huck wrote:
> On Mon,  4 Dec 2017 15:01:48 +0100
> David Hildenbrand <david@redhat.com> wrote:
> 
>> It only provies the EXTRACT CPU TIME instruction. We can reuse the stpt
> 
> s/provies/provides/
> 
>> helper, which calculates the CPU timer value.
>>
>> As the instruction is not priviledged, but we don't have a CPU timer
> 
> s/priviledged/privileged/

Didn't checkpatch once check for possible spelling mistakes? (or only in
the kernel)? Thanks :)

> 
>> value in case of linux user, we simply fake the CPU timer to be 0.
> 
> There's probably nothing else we could do.

We could also setup and use a CPU timer, but I don't want to go down
that path right now :)

Patch

diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 94d24e423d..0be037eac1 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -834,6 +834,7 @@  static void add_qemu_cpu_model_features(S390FeatBitmap fbm)
         S390_FEAT_STORE_CLOCK_FAST,
         S390_FEAT_MOVE_WITH_OPTIONAL_SPEC,
         S390_FEAT_ETF3_ENH,
+        S390_FEAT_EXTRACT_CPU_TIME,
         S390_FEAT_COMPARE_AND_SWAP_AND_STORE,
         S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2,
         S390_FEAT_GENERAL_INSTRUCTIONS_EXT,
diff --git a/target/s390x/insn-data.def b/target/s390x/insn-data.def
index f7b66b0091..5e33bd27ff 100644
--- a/target/s390x/insn-data.def
+++ b/target/s390x/insn-data.def
@@ -369,6 +369,8 @@ 
     C(0xb24f, EAR,     RRE,   Z,   0, 0, new, r1_32, ear, 0)
 /* EXTRACT CPU ATTRIBUTE */
     C(0xeb4c, ECAG,    RSY_a, GIE, 0, a2, r1, 0, ecag, 0)
+/* EXTRACT CPU TIME */
+    C(0xc801, ECTG,    SSF,   ECT, 0, 0, 0, 0, ectg, 0)
 /* EXTRACT FPC */
     C(0xb38c, EFPC,    RRE,   Z,   0, 0, new, r1_32, efpc, 0)
 /* EXTRACT PSW */
diff --git a/target/s390x/translate.c b/target/s390x/translate.c
index 1e4079464a..e0f55fc8e9 100644
--- a/target/s390x/translate.c
+++ b/target/s390x/translate.c
@@ -3887,6 +3887,41 @@  static ExitStatus op_spm(DisasContext *s, DisasOps *o)
     return NO_EXIT;
 }
 
+static ExitStatus op_ectg(DisasContext *s, DisasOps *o)
+{
+    int b1 = get_field(s->fields, b1);
+    int d1 = get_field(s->fields, d1);
+    int b2 = get_field(s->fields, b2);
+    int d2 = get_field(s->fields, d2);
+    int r3 = get_field(s->fields, r3);
+    TCGv_i64 tmp = tcg_temp_new_i64();
+
+    /* fetch all operands first */
+    o->in1 = tcg_temp_new_i64();
+    tcg_gen_addi_i64(o->in1, regs[b1], d1);
+    o->in2 = tcg_temp_new_i64();
+    tcg_gen_addi_i64(o->in2, regs[b2], d2);
+    o->addr1 = get_address(s, 0, r3, 0);
+
+    /* load the third operand into r3 before modifying anything */
+    tcg_gen_qemu_ld64(regs[r3], o->addr1, get_mem_index(s));
+
+#ifndef CONFIG_USER_ONLY
+    /* subtract CPU timer from first operand and store in GR0 */
+    gen_helper_stpt(tmp, cpu_env);
+    tcg_gen_sub_i64(regs[0], o->in1, tmp);
+#else
+    /* we don't have a CPU timer, fake value 0 */
+    tcg_gen_mov_i64(regs[0], o->in1);
+#endif
+
+    /* store second operand in GR1 */
+    tcg_gen_mov_i64(regs[1], o->in2);
+
+    tcg_temp_free_i64(tmp);
+    return NO_EXIT;
+}
+
 #ifndef CONFIG_USER_ONLY
 static ExitStatus op_spka(DisasContext *s, DisasOps *o)
 {
@@ -5639,6 +5674,7 @@  enum DisasInsnEnum {
 #define FAC_MSA3        S390_FEAT_MSA_EXT_3 /* msa-extension-3 facility */
 #define FAC_MSA4        S390_FEAT_MSA_EXT_4 /* msa-extension-4 facility */
 #define FAC_MSA5        S390_FEAT_MSA_EXT_5 /* msa-extension-5 facility */
+#define FAC_ECT         S390_FEAT_EXTRACT_CPU_TIME
 
 static const DisasInsn insn_info[] = {
 #include "insn-data.def"