diff --git a/passes/pmgen/xilinx_dsp.cc b/passes/pmgen/xilinx_dsp.cc
index b3d302071..7f51d29f6 100644
--- a/passes/pmgen/xilinx_dsp.cc
+++ b/passes/pmgen/xilinx_dsp.cc
@@ -39,7 +39,7 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
 	log("ffB:     %s\n", log_id(st.ffB, "--"));
 	log("dsp:     %s\n", log_id(st.dsp, "--"));
 	log("ffM:     %s\n", log_id(st.ffM, "--"));
-	log("addAB:   %s\n", log_id(st.addAB, "--"));
+	log("postAdd: %s\n", log_id(st.postAdd, "--"));
 	log("muxAB:   %s\n", log_id(st.muxAB, "--"));
 	log("ffP:     %s\n", log_id(st.ffP, "--"));
 	//log("muxP:  %s\n", log_id(st.muxP, "--"));
@@ -53,10 +53,10 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
 	SigSpec C = st.sigC;
 	SigSpec P = st.sigP;
 
-	if (st.addAB) {
-		log_assert(st.addAB->getParam("\\A_SIGNED").as_bool());
-		log_assert(st.addAB->getParam("\\B_SIGNED").as_bool());
-		log("  adder %s (%s)\n", log_id(st.addAB), log_id(st.addAB->type));
+	if (st.postAdd) {
+		log_assert(st.postAdd->getParam("\\A_SIGNED").as_bool());
+		log_assert(st.postAdd->getParam("\\B_SIGNED").as_bool());
+		log("  adder %s (%s)\n", log_id(st.postAdd), log_id(st.postAdd->type));
 
 		SigSpec &opmode = cell->connections_.at("\\OPMODE");
 		if (st.ffP && st.muxAB) {
@@ -72,7 +72,7 @@ void pack_xilinx_dsp(dict<SigBit, Cell*> &bit_to_driver, xilinx_dsp_pm &pm)
 		opmode[6] = State::S0;
 		opmode[5] = State::S1;
 
-		pm.autoremove(st.addAB);
+		pm.autoremove(st.postAdd);
 	}
 
 	if (st.clock != SigBit())
diff --git a/passes/pmgen/xilinx_dsp.pmg b/passes/pmgen/xilinx_dsp.pmg
index fdc3fa5e7..0aafc9e40 100644
--- a/passes/pmgen/xilinx_dsp.pmg
+++ b/passes/pmgen/xilinx_dsp.pmg
@@ -3,7 +3,8 @@ pattern xilinx_dsp
 state <SigBit> clock
 state <std::set<SigBit>> sigAset sigBset
 state <SigSpec> sigC sigM sigMused sigP sigPused
-state <Cell*> addAB muxAB
+state <Cell*> postAdd muxAB
+state <IdString> postAddAB
 
 match dsp
 	select dsp->type.in(\DSP48E1)
@@ -100,43 +101,25 @@ code clock sigM sigP
 	sigP = sigM;
 endcode
 
-match addA
-	select addA->type.in($add)
-	select param(addA, \A_SIGNED).as_bool() && param(addA, \B_SIGNED).as_bool()
-	select nusers(port(addA, \A)) == 2
-	//index <SigSpec> port(addA, \A) === sigP.extract(0, param(addA, \A_WIDTH).as_int()) // TODO: Why doesn't this work!?!
-	filter GetSize(port(addA, \A)) <= GetSize(sigP)
-	filter port(addA, \A) == sigP.extract(0, GetSize(port(addA, \A)))
-	filter nusers(sigP.extract_end(GetSize(port(addA, \A)))) <= 1
+match postAdd
+	// Ensure that Z mux is not already used
+	if port(dsp, \OPMODE).extract(4,3).is_fully_zero()
+
+	select postAdd->type.in($postAdd)
+	select param(postAdd, \A_SIGNED).as_bool() && param(postAdd, \B_SIGNED).as_bool()
+	choice <IdString> AB {\A, \B}
+	define <IdString> AB_WIDTH (AB == \A ? \A_WIDTH : \B_WIDTH)
+	select nusers(port(postAdd, AB)) == 2
+	filter GetSize(port(postAdd, AB)) <= GetSize(sigP)
+	filter port(postAdd, AB) == sigP.extract(0, GetSize(port(postAdd, AB)))
+	filter nusers(sigP.extract_end(GetSize(port(postAdd, AB)))) <= 1
+	set postAddAB AB
 	optional
 endmatch
 
-match addB
-	if !addA
-	select addB->type.in($add, $sub)
-	select param(addB, \A_SIGNED).as_bool() && param(addB, \B_SIGNED).as_bool()
-	index <int> nusers(port(addB, \B)) === 2
-	//index <SigSpec> port(addB, \B) === sigP.extract(0, param(addB, \B_WIDTH).as_int()) // TODO: Why doesn't this work!?!
-	filter GetSize(port(addB, \B)) <= GetSize(sigP)
-	filter port(addB, \B) == sigP.extract(0, GetSize(port(addB, \B)))
-	filter nusers(sigP.extract_end(GetSize(port(addB, \B)))) <= 1
-	optional
-endmatch
-
-code addAB sigC sigP
-	if (addA) {
-		addAB = addA;
-		sigC = port(addAB, \B);
-	}
-	if (addB) {
-		addAB = addB;
-		sigC = port(addAB, \A);
-	}
-	if (addAB) {
-		// Ensure that adder is not used
-		SigSpec opmodeZ = port(dsp, \OPMODE).extract(4,3);
-		if (!opmodeZ.is_fully_zero())
-			reject;
+code sigC sigP
+	if (postAdd) {
+		sigC = port(postAdd, postAddAB == \A ? \B : \A);
 
 		// TODO for DSP48E1, which will have sign extended inputs/outputs
 		//int natural_mul_width = GetSize(port(dsp, \A)) + GetSize(port(dsp, \B));
@@ -145,10 +128,10 @@ code addAB sigC sigP
 
 		//if ((actual_acc_width > actual_mul_width) && (natural_mul_width > actual_mul_width))
 		//	reject;
-		//if ((actual_acc_width != actual_mul_width) && (param(dsp, \A_SIGNED).as_bool() != param(addAB, \A_SIGNED).as_bool()))
+		//if ((actual_acc_width != actual_mul_width) && (param(dsp, \A_SIGNED).as_bool() != param(postAdd, \A_SIGNED).as_bool()))
 		//	reject;
 
-		sigP = port(addAB, \Y);
+		sigP = port(postAdd, \Y);
 	}
 endcode
 
@@ -190,7 +173,7 @@ code ffP sigP clock
 endcode
 
 match muxA
-	if addAB
+	if postAdd
 	select muxA->type.in($mux)
 	select nusers(port(muxA, \Y)) == 2
 	index <SigSpec> port(muxA, \A) === sigP
@@ -199,7 +182,7 @@ match muxA
 endmatch
 
 match muxB
-	if addAB
+	if postAdd
 	select muxB->type.in($mux)
 	select nusers(port(muxB, \Y)) == 2
 	index <SigSpec> port(muxB, \B) === sigP
@@ -217,7 +200,7 @@ code sigC muxAB
 		sigC = port(muxAB, \A);
 	}
 	if (muxAB) {
-		// Ensure that adder is not used
+		// Ensure that postAdder is not used
 		SigSpec opmodeZ = port(dsp, \OPMODE).extract(4,3);
 		if (!opmodeZ.is_fully_zero())
 			reject;