Never versions of the linux kernel need this instruction, so let's add it to the tcg frontend.
Signed-off-by: Bastian Koppelmann <kbast...@mail.uni-paderborn.de> --- target-s390x/insn-data.def | 3 ++- target-s390x/translate.c | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/target-s390x/insn-data.def b/target-s390x/insn-data.def index 4d2feb6..338d510 100644 --- a/target-s390x/insn-data.def +++ b/target-s390x/insn-data.def @@ -287,7 +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, new, r1_32, 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 dbf1993..539a794 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -2051,6 +2051,25 @@ static ExitStatus op_efpc(DisasContext *s, DisasOps *o) return NO_EXIT; } +static ExitStatus op_epsw(DisasContext *s, DisasOps *o) +{ + TCGv tmp = tcg_temp_new(); + int r1 = get_field(s->fields, r1); + int r2 = get_field(s->fields, r2); + + tcg_gen_shli_tl(tmp, psw_mask, 32); + tcg_gen_andi_tl(regs[r1], regs[r1], ~0xffffffffull); + tcg_gen_or_tl(regs[r1], regs[r1], tmp); + + if (r2 != 0) { + tcg_gen_andi_tl(tmp, psw_mask, ~0xffffffffull); + tcg_gen_andi_tl(regs[r2], regs[r2], ~0xffffffffull); + tcg_gen_or_tl(regs[r2], regs[r2], tmp); + } + tcg_temp_free(tmp); + return NO_EXIT; +} + static ExitStatus op_ex(DisasContext *s, DisasOps *o) { /* ??? Perhaps a better way to implement EXECUTE is to set a bit in -- 2.1.3