diff options
author | Richard Henderson <rth@twiddle.net> | 2013-09-06 09:48:08 -0700 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2015-02-03 12:06:37 -0800 |
commit | e30a9d3fea58c356000ce328421fe65e03143bb1 (patch) | |
tree | 8e91b4d35f39409b2051f012f267702eb46f3ffd /target-s390x | |
parent | 8612c935831647c193281992738f96292428b9e6 (diff) |
target-s390: Implement EPSW
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-s390x')
-rw-r--r-- | target-s390x/insn-data.def | 2 | ||||
-rw-r--r-- | target-s390x/translate.c | 18 |
2 files changed, 20 insertions, 0 deletions
diff --git a/target-s390x/insn-data.def b/target-s390x/insn-data.def index 42b99b2746..859cfba8a0 100644 --- a/target-s390x/insn-data.def +++ b/target-s390x/insn-data.def @@ -287,6 +287,8 @@ C(0xb24f, EAR, RRE, Z, 0, 0, new, r1_32, ear, 0) /* EXTRACT FPC */ C(0xb38c, EFPC, RRE, Z, 0, 0, new, r1_32, efpc, 0) +/* EXTRACT PSW */ + C(0xb98d, EPSW, RRE, Z, 0, 0, 0, 0, epsw, 0) /* FIND LEFTMOST ONE */ C(0xb983, FLOGR, RRE, EI, 0, r2_o, r1_P, 0, flogr, 0) diff --git a/target-s390x/translate.c b/target-s390x/translate.c index 1338bb5a34..97137c99cf 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -2051,6 +2051,24 @@ static ExitStatus op_efpc(DisasContext *s, DisasOps *o) return NO_EXIT; } +static ExitStatus op_epsw(DisasContext *s, DisasOps *o) +{ + int r1 = get_field(s->fields, r1); + int r2 = get_field(s->fields, r2); + TCGv_i64 t = tcg_temp_new_i64(); + + /* Note the "subsequently" in the PoO, which implies a defined result + if r1 == r2. Thus we cannot defer these writes to an output hook. */ + tcg_gen_shri_i64(t, psw_mask, 32); + store_reg32_i64(r1, t); + if (r2 != 0) { + store_reg32_i64(r2, psw_mask); + } + + tcg_temp_free_i64(t); + return NO_EXIT; +} + static ExitStatus op_ex(DisasContext *s, DisasOps *o) { /* ??? Perhaps a better way to implement EXECUTE is to set a bit in |