mirror of https://gitee.com/openkylin/qemu.git
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>
This commit is contained in:
parent
13f67dd582
commit
57af7289f2
|
@ -359,6 +359,21 @@
|
||||||
C(0xe371, LAY, RXY_a, LD, 0, a2, 0, r1, mov2, 0)
|
C(0xe371, LAY, RXY_a, LD, 0, a2, 0, r1, mov2, 0)
|
||||||
/* LOAD ADDRESS RELATIVE LONG */
|
/* LOAD ADDRESS RELATIVE LONG */
|
||||||
C(0xc000, LARL, RIL_b, Z, 0, ri2, 0, r1, mov2, 0)
|
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 ADD LOGICAL */
|
||||||
|
C(0xebfa, LAAL, RSY_a, ILA, r3_32s, m2_32s_atomic, new, m2_32_r1_atomic, add, addu32)
|
||||||
|
C(0xebea, LAALG, RSY_a, ILA, r3, m2_64_atomic, new, m2_64_r1_atomic, add, addu64)
|
||||||
|
/* LOAD AND AND */
|
||||||
|
C(0xebf4, LAN, RSY_a, ILA, r3_32s, m2_32s_atomic, new, m2_32_r1_atomic, and, nz32)
|
||||||
|
C(0xebe4, LANG, RSY_a, ILA, r3, m2_64_atomic, new, m2_64_r1_atomic, and, nz64)
|
||||||
|
/* LOAD AND EXCLUSIVE OR */
|
||||||
|
C(0xebf7, LAX, RSY_a, ILA, r3_32s, m2_32s_atomic, new, m2_32_r1_atomic, xor, nz32)
|
||||||
|
C(0xebe7, LAXG, RSY_a, ILA, r3, m2_64_atomic, new, m2_64_r1_atomic, xor, nz64)
|
||||||
|
/* LOAD AND OR */
|
||||||
|
C(0xebf6, LAO, RSY_a, ILA, r3_32s, m2_32s_atomic, new, m2_32_r1_atomic, or, nz32)
|
||||||
|
C(0xebe6, LAOG, RSY_a, ILA, r3, m2_64_atomic, new, m2_64_r1_atomic, or, nz64)
|
||||||
/* LOAD AND TEST */
|
/* LOAD AND TEST */
|
||||||
C(0x1200, LTR, RR_a, Z, 0, r2_o, 0, cond_r1r2_32, mov2, s32)
|
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)
|
C(0xb902, LTGR, RRE, Z, 0, r2_o, 0, r1, mov2, s64)
|
||||||
|
@ -438,6 +453,7 @@
|
||||||
C(0xb9e2, LOCGR, RRF_c, LOC, r1, r2, r1, 0, loc, 0)
|
C(0xb9e2, LOCGR, RRF_c, LOC, r1, r2, r1, 0, loc, 0)
|
||||||
C(0xebf2, LOC, RSY_b, LOC, r1, m2_32u, new, r1_32, loc, 0)
|
C(0xebf2, LOC, RSY_b, LOC, r1, m2_32u, new, r1_32, loc, 0)
|
||||||
C(0xebe2, LOCG, RSY_b, LOC, r1, m2_64, r1, 0, loc, 0)
|
C(0xebe2, LOCG, RSY_b, LOC, r1, m2_64, r1, 0, loc, 0)
|
||||||
|
/* LOAD PAIR DISJOINT TODO */
|
||||||
/* LOAD POSITIVE */
|
/* LOAD POSITIVE */
|
||||||
C(0x1000, LPR, RR_a, Z, 0, r2_32s, new, r1_32, abs, abs32)
|
C(0x1000, LPR, RR_a, Z, 0, r2_32s, new, r1_32, abs, abs32)
|
||||||
C(0xb900, LPGR, RRE, Z, 0, r2, r1, 0, abs, abs64)
|
C(0xb900, LPGR, RRE, Z, 0, r2, r1, 0, abs, abs64)
|
||||||
|
|
|
@ -1118,6 +1118,7 @@ typedef enum DisasFacility {
|
||||||
FAC_PC, /* population count */
|
FAC_PC, /* population count */
|
||||||
FAC_SCF, /* store clock fast */
|
FAC_SCF, /* store clock fast */
|
||||||
FAC_SFLE, /* store facility list extended */
|
FAC_SFLE, /* store facility list extended */
|
||||||
|
FAC_ILA, /* interlocked access facility 1 */
|
||||||
} DisasFacility;
|
} DisasFacility;
|
||||||
|
|
||||||
struct DisasInsn {
|
struct DisasInsn {
|
||||||
|
@ -4065,6 +4066,22 @@ static void wout_m2_32(DisasContext *s, DisasFields *f, DisasOps *o)
|
||||||
}
|
}
|
||||||
#define SPEC_wout_m2_32 0
|
#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. */
|
/* 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
|
#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)
|
static void in2_i2(DisasContext *s, DisasFields *f, DisasOps *o)
|
||||||
{
|
{
|
||||||
o->in2 = tcg_const_i64(get_field(f, i2));
|
o->in2 = tcg_const_i64(get_field(f, i2));
|
||||||
|
|
Loading…
Reference in New Issue