add valignd, valigndq
diff --git a/gen/gen_avx512.cpp b/gen/gen_avx512.cpp
index c498b6f..b13cf37 100644
--- a/gen/gen_avx512.cpp
+++ b/gen/gen_avx512.cpp
@@ -157,6 +157,25 @@
 	}
 }
 
+void putX_X_XM_IMM()
+{
+	const struct Tbl {
+		uint8 code;
+		const char *name;
+		int type;
+		bool hasIMM;
+	} tbl[] = {
+		{ 0x03, "valignd", T_EVEX | T_MUST_EVEX | T_66 | T_0F3A | T_EW0 | T_YMM, true },
+		{ 0x03, "valignq", T_EVEX | T_MUST_EVEX | T_66 | T_0F3A | T_EW1 | T_YMM, true }
+	};
+	for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) {
+		const Tbl *p = &tbl[i];
+		std::string type = type2String(p->type);
+		printf("void %s(const Xmm& x1, const Xmm& x2, const Operand& op%s) { opAVX_X_X_XM(x1, x2, op, %s, 0x%02X%s); }\n"
+			, p->name, p->hasIMM ? ", uint8 imm" : "", type.c_str(), p->code, p->hasIMM ? ", imm" : "");
+	}
+}
+
 int main()
 {
 	puts("#ifndef XBYAK_DISABLE_AVX512");
@@ -164,5 +183,6 @@
 	putVcmp();
 	putX_XM();
 	putM_X();
+	putX_X_XM_IMM();
 	puts("#endif");
 }
diff --git a/test/make_nm.cpp b/test/make_nm.cpp
index 7ecc893..10a8261 100644
--- a/test/make_nm.cpp
+++ b/test/make_nm.cpp
@@ -2632,6 +2632,19 @@
 		put("vmovshdup", _ZMM, _ZMM);
 		put("vmovsldup", _ZMM, _ZMM);
 
+
+		{
+			const char *tbl[] = {
+				"valignd",
+				"valignq",
+			};
+			for (size_t i = 0; i < NUM_OF_ARRAY(tbl); i++) {
+				const char *name = tbl[i];
+				put(name, XMM_KZ, _XMM, _XMM | MEM, IMM);
+				put(name, _YMM3, _YMM3, _YMM3, IMM);
+				put(name, _ZMM, _ZMM, _ZMM, IMM);
+			}
+		}
 		{
 			const char tbl[][16] = {
 				"vmovhpd",
diff --git a/xbyak/xbyak_avx512.h b/xbyak/xbyak_avx512.h
index 1d13486..f521ae1 100644
--- a/xbyak/xbyak_avx512.h
+++ b/xbyak/xbyak_avx512.h
@@ -80,4 +80,6 @@
 void vmovdqu16(const Address& addr, const Xmm& x) { opAVX_X_XM_IMM(x, addr, T_0F | T_F2 | T_EW1 | T_YMM | T_EVEX | T_ER_X | T_ER_Y | T_ER_Z | T_MUST_EVEX, 0x7F); }
 void vmovdqu32(const Address& addr, const Xmm& x) { opAVX_X_XM_IMM(x, addr, T_0F | T_F3 | T_EW0 | T_YMM | T_EVEX | T_ER_X | T_ER_Y | T_ER_Z | T_MUST_EVEX, 0x7F); }
 void vmovdqu64(const Address& addr, const Xmm& x) { opAVX_X_XM_IMM(x, addr, T_0F | T_F3 | T_EW1 | T_YMM | T_EVEX | T_ER_X | T_ER_Y | T_ER_Z | T_MUST_EVEX, 0x7F); }
+void valignd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_0F3A | T_66 | T_EW0 | T_YMM | T_EVEX | T_MUST_EVEX, 0x03, imm); }
+void valignq(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_0F3A | T_66 | T_EW1 | T_YMM | T_EVEX | T_MUST_EVEX, 0x03, imm); }
 #endif