Add really simple xilinx_dff peepopt
diff --git a/passes/pmgen/Makefile.inc b/passes/pmgen/Makefile.inc
index 145d2eb..a4d9d42 100644
--- a/passes/pmgen/Makefile.inc
+++ b/passes/pmgen/Makefile.inc
@@ -45,3 +45,9 @@
 OBJS += passes/pmgen/xilinx_srl.o
 passes/pmgen/xilinx_srl.o: passes/pmgen/xilinx_srl_pm.h
 $(eval $(call add_extra_objs,passes/pmgen/xilinx_srl_pm.h))
+
+# --------------------------------------
+
+OBJS += passes/pmgen/xilinx_dff.o
+passes/pmgen/xilinx_dff.o: passes/pmgen/xilinx_dff_pm.h
+$(eval $(call add_extra_objs,passes/pmgen/xilinx_dff_pm.h))
diff --git a/passes/pmgen/xilinx_dff.cc b/passes/pmgen/xilinx_dff.cc
new file mode 100644
index 0000000..bf0c735
--- /dev/null
+++ b/passes/pmgen/xilinx_dff.cc
@@ -0,0 +1,62 @@
+/*
+ *  yosys -- Yosys Open SYnthesis Suite
+ *
+ *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
+ *                2019  Eddie Hung    <eddie@fpgeh.com>
+ *
+ *  Permission to use, copy, modify, and/or distribute this software for any
+ *  purpose with or without fee is hereby granted, provided that the above
+ *  copyright notice and this permission notice appear in all copies.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include "kernel/yosys.h"
+#include "kernel/sigtools.h"
+
+USING_YOSYS_NAMESPACE
+PRIVATE_NAMESPACE_BEGIN
+
+#include "passes/pmgen/xilinx_dff_pm.h"
+
+struct XilinxDffPass : public Pass {
+	XilinxDffPass() : Pass("xilinx_dff", "Xilinx: TODO") { }
+	void help() YS_OVERRIDE
+	{
+		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
+		log("\n");
+		log("    xilinx_dff [options] [selection]\n");
+		log("\n");
+		log("TODO\n");
+		log("\n");
+	}
+	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+	{
+		log_header(design, "Executing XILINX_DFF pass (TODO).\n");
+
+		size_t argidx;
+		for (argidx = 1; argidx < args.size(); argidx++)
+		{
+			// if (args[argidx] == "-singleton") {
+			// 	singleton_mode = true;
+			// 	continue;
+			// }
+			break;
+		}
+		extra_args(args, argidx, design);
+
+		for (auto module : design->selected_modules()) {
+			xilinx_dff_pm pm(module, module->selected_cells());
+			pm.run_xilinx_dff();
+		}
+	}
+} XilinxDffPass;
+
+PRIVATE_NAMESPACE_END
diff --git a/passes/pmgen/xilinx_dff.pmg b/passes/pmgen/xilinx_dff.pmg
new file mode 100644
index 0000000..0b97af8
--- /dev/null
+++ b/passes/pmgen/xilinx_dff.pmg
@@ -0,0 +1,25 @@
+pattern xilinx_dff
+
+match fd
+	select fd->type.in(\FDRE)
+	select port(fd, \R).is_fully_zero()
+endmatch
+
+match lut
+	select lut->type.in(\LUT2)
+	index <SigSpec> port(lut, \O) === port(fd, \D)
+endmatch
+
+code
+	if (lut->type == \LUT2) {
+		if (param(lut, \INIT) == Const::from_string("0100")) {
+			fd->setPort(\D, port(lut, \I0));
+			fd->setPort(\R, port(lut, \I1));
+		}
+		else if (param(lut, \INIT) == Const::from_string("0010")) {
+			fd->setPort(\R, port(lut, \I0));
+			fd->setPort(\D, port(lut, \I1));
+		}
+	}
+	else log_abort();
+endcode