@Override
	protected AssemblyResolution solveTwoSided(AbstractAssemblyResolutionFactory<?, ?> factory,
			OrExpression exp, MaskedLong goal, Map<String, Long> vals, AssemblyResolvedPatterns cur,
			Set<SolverHint> hints, String description)
			throws NeedsBackfillException, SolverException {
		try {
			return tryCatenationExpression(factory, exp, goal, vals, cur, hints, description);
		}
		catch (Exception e) {
			dbg.println("while solving: " + goal + "=:" + exp);
			dbg.println(e.getMessage());
		}

		try {
			return tryCircularShiftExpression(factory, exp, goal, vals, cur, hints, description);
		}
		catch (Exception e) {
			dbg.println("while solving: " + goal + "=:" + exp);
			dbg.println(e.getMessage());
		}

		Map<ExpressionMatcher<?>, PatternExpression> match = MATCHERS.neqConst.match(exp);
		if (match != null) {
			long value = MATCHERS.val.get(match).getValue();
			PatternValue field = MATCHERS.fld.get(match);
			// Solve for equals, then either return that, or forbid it, depending on goal
			AssemblyResolution solution = solver.solve(factory, field, MaskedLong.fromLong(value),
				vals, cur, hints, description);
			if (goal.equals(MaskedLong.fromMaskAndValue(0, 1))) {
				return solution;
			}
			if (goal.equals(MaskedLong.fromMaskAndValue(1, 1))) {
				if (solution.isError()) {
					return factory.nop(description);
				}
				if (solution.isBackfill()) {
					throw new AssertionError();
				}
				AssemblyResolvedPatterns forbidden = (AssemblyResolvedPatterns) solution;
				forbidden = forbidden.withDescription("Solved 'not equals'");
				AssemblyResolvedPatterns rp = factory.nop(description);
				return rp.withForbids(Set.of(forbidden));
			}
		}

		throw new SolverException("Could not solve two-sided OR");
	}
Solves expressions of the form {@code A | B}
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/OrExpressionSolver.java