[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2] s390x: Add laa and laag instructions
From: |
Alexander Graf |
Subject: |
[Qemu-devel] [PATCH v2] s390x: Add laa and laag instructions |
Date: |
Tue, 12 May 2015 22:20:31 +0200 |
We're currently missing the laa and laag instructions in our emulation.
In fact, we're missing the complete "interlocked-access facility 1" which
is part of zEC12. However, I really only needed the laa instruction for now.
Signed-off-by: Alexander Graf <address@hidden>
---
This really should implement all the other atomic load&modify instructions,
but I'd like to make sure we have a smart scheme to implement them first.
v1 -> v2:
- move atomic specific bits into load/store helpers, leave actual op
as normal op we can reuse
---
target-s390x/insn-data.def | 3 +++
target-s390x/translate.c | 48 ++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 49 insertions(+), 2 deletions(-)
diff --git a/target-s390x/insn-data.def b/target-s390x/insn-data.def
index 48e979e..cd95035 100644
--- a/target-s390x/insn-data.def
+++ b/target-s390x/insn-data.def
@@ -359,6 +359,9 @@
C(0xe371, LAY, RXY_a, LD, 0, a2, 0, r1, mov2, 0)
/* LOAD ADDRESS RELATIVE LONG */
C(0xc000, LARL, RIL_b, Z, 0, ri2, 0, r1, mov2, 0)
+/* LOAD AND ADD */
+ C(0xebf8, LAA, RSY_a, ILA, r3_32s, m2_32s_atomic, new,
m2_32_r1_atomic, add, adds32)
+ C(0xebe8, LAAG, RSY_a, ILA, r3, m2_64_atomic, new, m2_64_r1_atomic,
add, adds64)
/* LOAD AND TEST */
C(0x1200, LTR, RR_a, Z, 0, r2_o, 0, cond_r1r2_32, mov2, s32)
C(0xb902, LTGR, RRE, Z, 0, r2_o, 0, r1, mov2, s64)
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index fa3e334..73f2de3 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -1118,6 +1118,7 @@ typedef enum DisasFacility {
FAC_PC, /* population count */
FAC_SCF, /* store clock fast */
FAC_SFLE, /* store facility list extended */
+ FAC_ILA, /* interlocked access facility 1 */
} DisasFacility;
struct DisasInsn {
@@ -1297,6 +1298,12 @@ static ExitStatus help_branch(DisasContext *s,
DisasCompare *c,
return ret;
}
+static TCGv_i64 get_a2(DisasContext *s, DisasFields *f)
+{
+ int x2 = have_field(f, x2) ? get_field(f, x2) : 0;
+ return get_address(s, x2, get_field(f, b2), get_field(f, d2));
+}
+
/* ====================================================================== */
/* The operations. These perform the bulk of the work for any insn,
usually after the operands have been loaded and output initialized. */
@@ -4065,6 +4072,30 @@ static void wout_m2_32(DisasContext *s, DisasFields *f,
DisasOps *o)
}
#define SPEC_wout_m2_32 0
+static void wout_m2_32_r1_atomic(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+ TCGv_i64 a2 = get_a2(s, f);
+
+ /* XXX release reservation */
+ tcg_gen_qemu_st32(o->out, a2, get_mem_index(s));
+ store_reg32_i64(get_field(f, r1), o->in2);
+
+ tcg_temp_free_i64(a2);
+}
+#define SPEC_wout_m2_32_r1_atomic 0
+
+static void wout_m2_64_r1_atomic(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+ TCGv_i64 a2 = get_a2(s, f);
+
+ /* XXX release reservation */
+ tcg_gen_qemu_st64(o->out, a2, get_mem_index(s));
+ store_reg(get_field(f, r1), o->in2);
+
+ tcg_temp_free_i64(a2);
+}
+#define SPEC_wout_m2_64_r1_atomic 0
+
/* ====================================================================== */
/* The "INput 1" generators. These load the first operand to an insn. */
@@ -4393,8 +4424,7 @@ static void in2_ra2(DisasContext *s, DisasFields *f,
DisasOps *o)
static void in2_a2(DisasContext *s, DisasFields *f, DisasOps *o)
{
- int x2 = have_field(f, x2) ? get_field(f, x2) : 0;
- o->in2 = get_address(s, x2, get_field(f, b2), get_field(f, d2));
+ o->in2 = get_a2(s, f);
}
#define SPEC_in2_a2 0
@@ -4486,6 +4516,20 @@ static void in2_mri2_64(DisasContext *s, DisasFields *f,
DisasOps *o)
}
#define SPEC_in2_mri2_64 0
+static void in2_m2_32s_atomic(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+ /* XXX should reserve the address */
+ in2_m2_32s(s, f, o);
+}
+#define SPEC_in2_m2_32s_atomic 0
+
+static void in2_m2_64_atomic(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+ /* XXX should reserve the address */
+ in2_m2_64(s, f, o);
+}
+#define SPEC_in2_m2_64_atomic 0
+
static void in2_i2(DisasContext *s, DisasFields *f, DisasOps *o)
{
o->in2 = tcg_const_i64(get_field(f, i2));
--
1.7.12.4
- [Qemu-devel] [PATCH v2] s390x: Add laa and laag instructions,
Alexander Graf <=