SAA 011100 ..... ..... 00000 00000 011000 @saa
SAAD 011100 ..... ..... 00000 00000 011001 @saa
+&zcb base
+ZCB 011100 base:5 00000 00000 1110- 011111 &zcb
+
&lx base index rd
@lx ...... base:5 index:5 rd:5 ...... ..... &lx
LWX 011111 ..... ..... ..... 00000 001010 @lx
TRANS(SAA, trans_saa, MO_32);
TRANS(SAAD, trans_saa, MO_64);
+
+static bool trans_ZCB(DisasContext *ctx, arg_ZCB *a)
+{
+ TCGv_i64 addr = tcg_temp_new_i64();
+ TCGv_i64 line = tcg_temp_new_i64();
+ TCGv_i128 zero128 = tcg_zero_i128();
+ const MemOp mop = mo_endian(ctx) | MO_128 | MO_ATOM_NONE;
+
+ gen_base_offset_addr(ctx, addr, a->base, 0);
+
+ /*
+ * QEMU models ZCB/ZCBT as zeroing the containing 128-byte cache line
+ * in guest memory.
+ */
+ tcg_gen_andi_i64(line, addr, ~0x7fULL);
+
+ for (int i = 0; i < 8; i++) {
+ TCGv_i64 slot = tcg_temp_new_i64();
+
+ tcg_gen_addi_i64(slot, line, i * 16);
+ tcg_gen_qemu_st_i128(zero128, slot, ctx->mem_idx, mop);
+ }
+
+ return true;
+}