@Override
	public AssemblyResolution solve(AbstractAssemblyResolutionFactory<?, ?> factory,
			T exp, MaskedLong goal, Map<String, Long> vals, AssemblyResolvedPatterns cur,
			Set<SolverHint> hints, String description) throws NeedsBackfillException {
		MaskedLong lval = solver.getValue(exp.getLeft(), vals, cur);
		MaskedLong rval = solver.getValue(exp.getRight(), vals, cur);

		if (lval != null && !lval.isFullyDefined()) {
			if (!lval.isFullyUndefined()) {
				dbg.println("Partially-defined left value for binary solver: " + lval);
			}
			lval = null;
		}
		if (rval != null && !rval.isFullyDefined()) {
			if (!rval.isFullyUndefined()) {
				dbg.println("Partially-defined right value for binary solver: " + rval);
			}
			rval = null;
		}

		try {
			if (lval != null && rval != null) {
				MaskedLong cval = compute(lval, rval);
				return ConstantValueSolver.checkConstAgrees(factory, cval, goal, description);
			}
			else if (lval != null) {
				return solveRightSide(factory, exp.getRight(), lval, goal, vals, cur, hints,
					description);
			}
			else if (rval != null) {
				return solveLeftSide(factory, exp.getLeft(), rval, goal, vals, cur, hints,
					description);
			}
			else {
				// Each solver may provide a strategy for solving expression where both sides are
				// variable, e.g., two fields being concatenated via OR.
				return solveTwoSided(factory, exp, goal, vals, cur, hints, description);
			}
		}
		catch (NeedsBackfillException e) {
			throw e;
		}
		catch (SolverException e) {
			return factory.newErrorBuilder().error(e.getMessage()).description(description).build();
		}
		catch (AssertionError e) {
			dbg.println("While solving: " + exp + " (" + description + ")");
			throw e;
		}
	}
A solver that handles expressions of the form {@code A [OP] B}

@param <T> the type of expression solved (the operator)
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/AbstractBinaryExpressionSolver.java