diff options
author | Alexander Graf <agraf@suse.de> | 2015-05-08 03:07:53 +0200 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2015-05-13 14:48:54 +0200 |
commit | 57af7289f276ce70b65f2fbb4981833f04264aac (patch) | |
tree | c53e9238921496facd3c3a07535f523e9a1281af /target-s390x/translate.c | |
parent | 13f67dd5825a7dfd7a4904a5fb0cf0a3f95d2d45 (diff) |
s390x: Add interlocked access facility 1 instructions
We're currently missing all instructions defined by the "interlocked-access
facility 1" which is part of zEC12. This patch implements all of them except
for LPD and LPDG.
Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-s390x/translate.c')
-rw-r--r-- | target-s390x/translate.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/target-s390x/translate.c b/target-s390x/translate.c index fa3e334e4f..80e3a545e4 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 { @@ -4065,6 +4066,22 @@ 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) +{ + /* XXX release reservation */ + tcg_gen_qemu_st32(o->out, o->addr1, get_mem_index(s)); + store_reg32_i64(get_field(f, r1), o->in2); +} +#define SPEC_wout_m2_32_r1_atomic 0 + +static void wout_m2_64_r1_atomic(DisasContext *s, DisasFields *f, DisasOps *o) +{ + /* XXX release reservation */ + tcg_gen_qemu_st64(o->out, o->addr1, get_mem_index(s)); + store_reg(get_field(f, r1), o->in2); +} +#define SPEC_wout_m2_64_r1_atomic 0 + /* ====================================================================== */ /* The "INput 1" generators. These load the first operand to an insn. */ @@ -4486,6 +4503,24 @@ 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 */ + in1_la2(s, f, o); + o->in2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld32s(o->in2, o->addr1, get_mem_index(s)); +} +#define SPEC_in2_m2_32s_atomic 0 + +static void in2_m2_64_atomic(DisasContext *s, DisasFields *f, DisasOps *o) +{ + /* XXX should reserve the address */ + in1_la2(s, f, o); + o->in2 = tcg_temp_new_i64(); + tcg_gen_qemu_ld64(o->in2, o->addr1, get_mem_index(s)); +} +#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)); |