protected AssemblyResolution solveLeftCircularShift(
			AbstractAssemblyResolutionFactory<?, ?> factory, PatternExpression expValue,
			PatternExpression expShift, int size, int dir, MaskedLong goal, Map<String, Long> vals,
			AssemblyResolvedPatterns cur, Set<SolverHint> hints, String description)
			throws NeedsBackfillException, SolverException {
		MaskedLong valValue = solver.getValue(expValue, vals, cur);
		MaskedLong valShift = solver.getValue(expShift, vals, cur);

		if (valValue != null && !valValue.isFullyDefined()) {
			if (!valValue.isFullyUndefined()) {
				dbg.println("Partially-defined f for left circular shift solver: " + valValue);
			}
			valValue = null;
		}
		if (valShift != null && valShift.isFullyDefined()) {
			if (!valShift.isFullyUndefined()) {
				dbg.println("Partially-defined g for left circular shift solver: " + valShift);
			}
			valShift = null;
		}

		if (valValue != null && valShift != null) {
			throw new AssertionError("Should not have constants when solving special forms");
		}
		else if (valValue != null) {
			return solver.solve(factory, expShift, computeCircShiftG(valValue, size, dir, goal),
				vals, cur, hints, description);
		}
		else if (valShift != null) {
			return solver.solve(factory, expValue, computeCircShiftF(valShift, size, dir, goal),
				vals, cur, hints, description);
		}

		// Oiy. Try guessing the shift amount, starting at 0
		if (hints.contains(DefaultSolverHint.GUESSING_CIRCULAR_SHIFT_AMOUNT)) {
			throw new SolverException("Already guessing circular shift amount. " +
				"Try to express a double-shift as a shift by sum.");
		}
		Set<SolverHint> hintsWithCircularShift =
			SolverHint.with(hints, DefaultSolverHint.GUESSING_CIRCULAR_SHIFT_AMOUNT);
		for (int shift = 0; shift < size; shift++) {
			try {
				MaskedLong reqShift = MaskedLong.fromLong(shift);
				MaskedLong reqValue = computeCircShiftF(reqShift, size, dir, goal);
				AssemblyResolution resValue = solver.solve(factory, expValue, reqValue, vals, cur,
					hintsWithCircularShift, description);
				if (resValue.isError()) {
					AssemblyResolvedError err = (AssemblyResolvedError) resValue;
					throw new SolverException("Solving f failed: " + err.getError());
				}
				AssemblyResolution resShift =
					solver.solve(factory, expShift, reqShift, vals, cur, hints, description);
				if (resShift.isError()) {
					AssemblyResolvedError err = (AssemblyResolvedError) resShift;
					throw new SolverException("Solving g failed: " + err.getError());
				}
				AssemblyResolvedPatterns solValue = (AssemblyResolvedPatterns) resValue;
				AssemblyResolvedPatterns solShift = (AssemblyResolvedPatterns) resShift;
				AssemblyResolvedPatterns sol = solValue.combine(solShift);
				if (sol == null) {
					throw new SolverException(
						"value and shift solutions conflict for shift=" + shift);
				}
				return sol;
			}
			catch (SolverException | UnsupportedOperationException e) {
				Msg.trace(this, "Shift of " + shift + " resulted in " + e);
				// try the next
			}
		}

		throw new SolverException(
			"Could not solve circular shift with variable bits and shift amount");
	}
Solves expressions of the form {@code A | B}
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/OrExpressionSolver.java