private static Varnode simplifyWithIntAndMask(SequenceNumber seq, Varnode varnode,
			long andMask, AddressFactory addrFactory, TaskMonitor monitor)
			throws CancelledException {
		monitor.checkCancelled();
		if (!(varnode instanceof VarnodeOperation)) {
			if (varnode.isConstant()) {
				return new Varnode(addrFactory.getConstantAddress(andMask & varnode.getOffset()),
					varnode.getSize());
			}
			// Can't be simplified
			return null;
		}
		VarnodeOperation op = (VarnodeOperation) varnode;

// TODO: Check -1 andMask

		PcodeOp pcodeOp = op.getPCodeOp();
		int opcode = pcodeOp.getOpcode();

		if (isBooleanOutputOperation(op)) {
			if ((andMask & 1) == 0) {
				return new Varnode(addrFactory.getConstantAddress(0), op.getSize());
			}
		}
		else if (opcode == PcodeOp.INT_AND) {
			Varnode[] values = op.getInputValues();
			Varnode v0 = simplifyWithIntAndMask(seq, values[0], andMask, addrFactory, monitor);
			Varnode v1 = simplifyWithIntAndMask(seq, values[1], andMask, addrFactory, monitor);
			if (v0 == null && v1 == null) {
				op.setSimplified(true);
				return null;
			}
			if (v0 != null) {
				values[0] = v0;
			}
			if (v1 != null) {
				values[1] = v1;
			}

// TODO: Handle double-AND with constants !!

			return simplify(pcodeOp, values, addrFactory, monitor);
		}
		else if (opcode == PcodeOp.INT_OR || opcode == PcodeOp.INT_XOR) {
			Varnode[] values = op.getInputValues();
			Varnode v0 = simplifyWithIntAndMask(seq, values[0], andMask, addrFactory, monitor);
			Varnode v1 = simplifyWithIntAndMask(seq, values[1], andMask, addrFactory, monitor);
			if (v0 == null && v1 == null) {
				op.setSimplified(true);
				return null;
			}
			if (v0 != null) {
				values[0] = v0;
			}
			if (v1 != null) {
				values[1] = v1;
			}
			return simplify(pcodeOp, values, addrFactory, monitor);
		}
		else if (opcode == PcodeOp.INT_LEFT) {
			Varnode[] leftValues = op.getInputValues();
			if (leftValues[1].isConstant() && (leftValues[0] instanceof VarnodeOperation)) {
				int leftShift = (int) leftValues[1].getOffset();
				VarnodeOperation shiftedOp = (VarnodeOperation) leftValues[0];
				long shiftedMask = VALUE_MASK[shiftedOp.getSize()] & (andMask >>> leftShift);
				if (shiftedMask == 0) {
					// shifted value output masked out
					return new Varnode(addrFactory.getConstantAddress(0), op.getSize());
				}
				Varnode modifiedOp =
					simplifyWithIntAndMask(seq, shiftedOp, shiftedMask, addrFactory, monitor);
				if (modifiedOp != null) {
					leftValues[0] = modifiedOp;
					return simplify(pcodeOp, leftValues, addrFactory, monitor);
				}
			}
		}
		else if (opcode == PcodeOp.INT_RIGHT) {
			Varnode[] rightValues = op.getInputValues();
			if (rightValues[1].isConstant() && (rightValues[0] instanceof VarnodeOperation)) {
				int rightShift = (int) rightValues[1].getOffset();
				VarnodeOperation shiftedOp = (VarnodeOperation) rightValues[0];
				long shiftedMask = VALUE_MASK[shiftedOp.getSize()] & (andMask << rightShift);
				if (shiftedMask == 0) {
					// shifted value output masked out
					return new Varnode(addrFactory.getConstantAddress(0), op.getSize());
				}
				Varnode modifiedOp =
					simplifyWithIntAndMask(seq, shiftedOp, shiftedMask, addrFactory, monitor);
				if (modifiedOp != null) {
					rightValues[0] = modifiedOp;
					return simplify(pcodeOp, rightValues, addrFactory, monitor);
				}
			}
		}
		else if (opcode == PcodeOp.SUBPIECE) {
			Varnode[] spValues = op.getInputValues();
			int shift = (int) spValues[1].getOffset() * 8;
			long modifiedMask = (VALUE_MASK[spValues[0].getSize()] & (andMask >> shift) << shift);
			if (modifiedMask == 0) {
				// shifted value output masked out
				return new Varnode(addrFactory.getConstantAddress(0), op.getSize());
			}
			Varnode shiftedOp =
				simplifyWithIntAndMask(seq, spValues[0], modifiedMask, addrFactory, monitor);
			if (shiftedOp != null) {
				spValues[0] = shiftedOp;
				return simplify(pcodeOp, spValues, addrFactory, monitor);
			}
		}
		else if (opcode == PcodeOp.INT_ZEXT) {
			Varnode[] inValues = op.getInputValues();
			long modifiedMask = VALUE_MASK[inValues[0].getSize()] & andMask;
			if (modifiedMask == 0) {
				// Extended value output masked out
				return new Varnode(addrFactory.getConstantAddress(0), op.getSize());
			}
			Varnode extendedOp =
				simplifyWithIntAndMask(seq, inValues[0], modifiedMask, addrFactory, monitor);
			if (extendedOp != null) {
				inValues[0] = extendedOp;
				return simplify(pcodeOp, inValues, addrFactory, monitor);
			}
		}
		else if (opcode == PcodeOp.INT_ADD) {
			// assume constant has already been placed in second input
			Varnode[] values = op.getInputValues();
			Varnode v0 = values[0];
			Varnode v1 = values[1];
			if (v1.isConstant() && (v0 instanceof VarnodeOperation)) {
				// check for add which would not have carry into masked area and would result in 
				// either one of the operands
				if ((v1.getOffset() & ~andMask) == 0) {
					Varnode checkVn =
						simplifyWithIntAndMask(seq, v0, andMask, addrFactory, monitor);
					if (checkVn != null && checkVn.isConstant() && checkVn.getOffset() == 0) {
						return v1;
					}
				}
				else if ((v1.getOffset() & andMask) == 0) {
					VarnodeOperation vop = (VarnodeOperation) v0;
					return simplify(vop.getPCodeOp(), vop.getInputValues(), addrFactory, monitor);
				}
			}
		}
		op.setSimplified(true);
		return null;
	}
Simplify specified varnode base upon specified andMask.
@param seq
@param varnode
@param andMask
@return simplified varnode or null if simplification failed
Ghidra/Features/Base/src/main/java/ghidra/util/state/ResultsState.java