D(0xa507, NILL, RI_a, Z, r1_o, i2_16u, r1, 0, andi, 0, 0x1000)
D(0x9400, NI, SI, Z, la1, i2_8u, new, 0, ni, nz64, MO_UB)
D(0xeb54, NIY, SIY, LD, la1, i2_8u, new, 0, ni, nz64, MO_UB)
+/* AND WITH COMPLEMENT */
+ C(0xb9f5, NCRK, RRF_a, MIE3, r2, r3, new, r1_32, andc, nz32)
+ C(0xb9e5, NCGRK, RRF_a, MIE3, r2, r3, r1, 0, andc, nz64)
/* BRANCH AND LINK */
C(0x0500, BALR, RR_a, Z, 0, r2_nz, r1, 0, bal, 0)
C(0xeb8e, MVCLU, RSY_a, E2, 0, a2, 0, 0, mvclu, 0)
/* MOVE NUMERICS */
C(0xd100, MVN, SS_a, Z, la1, a2, 0, 0, mvn, 0)
+/* MOVE RIGHT TO LEFT */
+ C(0xe50a, MVCRL, SSE, MIE3, la1, a2, 0, 0, mvcrl, 0)
/* MOVE PAGE */
C(0xb254, MVPG, RRE, Z, 0, 0, 0, 0, mvpg, 0)
/* MOVE STRING */
F(0xed0f, MSEB, RXF, Z, e1, m2_32u, new, e1, mseb, 0, IF_BFP)
F(0xed1f, MSDB, RXF, Z, f1, m2_64, new, f1, msdb, 0, IF_BFP)
+/* NAND */
+ C(0xb974, NNRK, RRF_a, MIE3, r2, r3, new, r1_32, nand, nz32)
+ C(0xb964, NNGRK, RRF_a, MIE3, r2, r3, r1, 0, nand, nz64)
+/* NOR */
+ C(0xb976, NORK, RRF_a, MIE3, r2, r3, new, r1_32, nor, nz32)
+ C(0xb966, NOGRK, RRF_a, MIE3, r2, r3, r1, 0, nor, nz64)
+/* NOT EXCLUSIVE OR */
+ C(0xb977, NXRK, RRF_a, MIE3, r2, r3, new, r1_32, nxor, nz32)
+ C(0xb967, NXGRK, RRF_a, MIE3, r2, r3, r1, 0, nxor, nz64)
+
/* OR */
C(0x1600, OR, RR_a, Z, r1, r2, new, r1_32, or, nz32)
C(0xb9f6, ORK, RRF_a, DO, r2, r3, new, r1_32, or, nz32)
D(0xa50b, OILL, RI_a, Z, r1_o, i2_16u, r1, 0, ori, 0, 0x1000)
D(0x9600, OI, SI, Z, la1, i2_8u, new, 0, oi, nz64, MO_UB)
D(0xeb56, OIY, SIY, LD, la1, i2_8u, new, 0, oi, nz64, MO_UB)
+/* OR WITH COMPLEMENT */
+ C(0xb975, OCRK, RRF_a, MIE3, r2, r3, new, r1_32, orc, nz32)
+ C(0xb965, OCGRK, RRF_a, MIE3, r2, r3, r1, 0, orc, nz64)
/* PACK */
/* Really format SS_b, but we pack both lengths into one argument
/* PACK UNICODE */
C(0xe100, PKU, SS_f, E2, la1, a2, 0, 0, pku, 0)
+/* POPULATION COUNT */
+ C(0xb9e1, POPCNT, RRF_c, PC, 0, r2_o, r1, 0, popcnt, nz64)
+
/* PREFETCH */
/* Implemented as nops of course. */
C(0xe336, PFD, RXY_b, GIE, 0, 0, 0, 0, 0, 0)
/* Implemented as nop of course. */
C(0xb2e8, PPA, RRF_c, PPA, 0, 0, 0, 0, 0, 0)
-/* POPULATION COUNT */
- C(0xb9e1, POPCNT, RRE, PC, 0, r2_o, r1, 0, popcnt, nz64)
-
/* ROTATE LEFT SINGLE LOGICAL */
C(0xeb1d, RLL, RSY_a, Z, r3_o, sh, new, r1_32, rll32, 0)
C(0xeb1c, RLLG, RSY_a, Z, r3_o, sh, r1, 0, rll64, 0)
/* SEARCH STRING UNICODE */
C(0xb9be, SRSTU, RRE, ETF3, 0, 0, 0, 0, srstu, 0)
+/* SELECT */
+ C(0xb9f0, SELR, RRF_a, MIE3, r3, r2, new, r1_32, loc, 0)
+ C(0xb9e3, SELGR, RRF_a, MIE3, r3, r2, r1, 0, loc, 0)
+/* SELECT HIGH */
+ C(0xb9c0, SELFHR, RRF_a, MIE3, r3_sr32, r2_sr32, new, r1_32h, loc, 0)
+
/* SET ACCESS */
C(0xb24e, SAR, RRE, Z, 0, r2_o, 0, 0, sar, 0)
/* SET ADDRESSING MODE */
return DISAS_NEXT;
}
+static DisasJumpType op_andc(DisasContext *s, DisasOps *o)
+{
+ tcg_gen_andc_i64(o->out, o->in1, o->in2);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_orc(DisasContext *s, DisasOps *o)
+{
+ tcg_gen_orc_i64(o->out, o->in1, o->in2);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_nand(DisasContext *s, DisasOps *o)
+{
+ tcg_gen_nand_i64(o->out, o->in1, o->in2);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_nor(DisasContext *s, DisasOps *o)
+{
+ tcg_gen_nor_i64(o->out, o->in1, o->in2);
+ return DISAS_NEXT;
+}
+
+static DisasJumpType op_nxor(DisasContext *s, DisasOps *o)
+{
+ tcg_gen_eqv_i64(o->out, o->in1, o->in2);
+ return DISAS_NEXT;
+}
+
static DisasJumpType op_ni(DisasContext *s, DisasOps *o)
{
o->in1 = tcg_temp_new_i64();
{
DisasCompare c;
- disas_jcc(s, &c, get_field(s, m3));
+ if (have_field(s, m3)) {
+ /* LOAD * ON CONDITION */
+ disas_jcc(s, &c, get_field(s, m3));
+ } else {
+ /* SELECT */
+ disas_jcc(s, &c, get_field(s, m4));
+ }
if (c.is_64) {
tcg_gen_movcond_i64(c.cond, o->out, c.u.s64.a, c.u.s64.b,
return DISAS_NEXT;
}
+static DisasJumpType op_mvcrl(DisasContext *s, DisasOps *o)
+{
+ gen_helper_mvcrl(cpu_env, regs[0], o->addr1, o->in2);
+ return DISAS_NEXT;
+}
+
static DisasJumpType op_mvcin(DisasContext *s, DisasOps *o)
{
TCGv_i32 l = tcg_const_i32(get_field(s, l1));
static DisasJumpType op_popcnt(DisasContext *s, DisasOps *o)
{
- gen_helper_popcnt(o->out, o->in2);
+ const uint8_t m3 = get_field(s, m3);
+
+ if ((m3 & 8) && s390_has_feat(S390_FEAT_MISC_INSTRUCTION_EXT3)) {
+ tcg_gen_ctpop_i64(o->out, o->in2);
+ } else {
+ gen_helper_popcnt(o->out, o->in2);
+ }
return DISAS_NEXT;
}
}
#define SPEC_in1_r3_D32 SPEC_r3_even
+static void in1_r3_sr32(DisasContext *s, DisasOps *o)
+{
+ o->in1 = tcg_temp_new_i64();
+ tcg_gen_shri_i64(o->in1, regs[get_field(s, r3)], 32);
+}
+#define SPEC_in1_r3_sr32 0
+
static void in1_e1(DisasContext *s, DisasOps *o)
{
o->in1 = load_freg32_i64(get_field(s, r1));
#define FAC_V S390_FEAT_VECTOR /* vector facility */
#define FAC_VE S390_FEAT_VECTOR_ENH /* vector enhancements facility 1 */
#define FAC_MIE2 S390_FEAT_MISC_INSTRUCTION_EXT2 /* miscellaneous-instruction-extensions facility 2 */
+#define FAC_MIE3 S390_FEAT_MISC_INSTRUCTION_EXT3 /* miscellaneous-instruction-extensions facility 3 */
static const DisasInsn insn_info[] = {
#include "insn-data.def"