@Override
	protected AssemblyResolution solveLeftSide(AbstractAssemblyResolutionFactory<?, ?> factory,
			PatternExpression lexp, MaskedLong rval, MaskedLong goal, Map<String, Long> vals,
			AssemblyResolvedPatterns cur, Set<SolverHint> hints, String description)
			throws NeedsBackfillException, SolverException {
		// Try the usual case first
		ResultTracker tracker = new ResultTracker();
		AssemblyResolution sol = tracker.trySolverFunc(() -> {
			return super.solveLeftSide(factory, lexp, rval, goal, vals, cur, hints, description);
		});
		if (sol != null) {
			return sol;
		}

		if (hints.contains(DefaultSolverHint.GUESSING_REPETITION)) {
			return tracker.returnBest(rval, goal);
		}

		// Handle case of using multiplication for repeating fields
		int unksToRight = Long.numberOfTrailingZeros(goal.msk);
		int unksToLeft = Long.numberOfLeadingZeros(goal.msk);
		int numBitsKnown = Long.SIZE - unksToRight - unksToLeft;
		if (Long.bitCount(goal.msk) == numBitsKnown) { // All bits counted
			Set<SolverHint> hintsWithRepetition =
				SolverHint.with(hints, DefaultSolverHint.GUESSING_REPETITION);
			// Assume right truncation
			// Need to fill all bits to the right in order to divide
			int reps = (unksToRight + numBitsKnown - 1) / numBitsKnown;
			long repMsk = goal.msk;
			long repVal = goal.val;

			for (int i = 0; i < reps; i++) {
				repMsk = (repMsk >>> numBitsKnown) | repMsk;
				repVal = (repVal >>> numBitsKnown) | repVal;
			}
			if (reps > 0) {
				MaskedLong repRightGoal = MaskedLong.fromMaskAndValue(repMsk, repVal);
				sol = tracker.trySolverFunc(() -> {
					return tryRep(factory, lexp, rval, repRightGoal, goal, vals, cur,
						hintsWithRepetition,
						description);
				});
				if (sol != null) {
					return sol;
				}
			}

			// Assume right and left truncation
			// Fill value bits all the way to left, then try adding one mask bit at a time
			reps = (unksToLeft + numBitsKnown - 1) / numBitsKnown;
			for (int i = 0; i < reps; i++) {
				repVal = (repVal << numBitsKnown) | repVal;
			}
			for (int i = unksToLeft - 1; i >= 0; i--) {
				repMsk = -1L >>> i;
				MaskedLong repLeftGoal = MaskedLong.fromMaskAndValue(repMsk, repVal);
				sol = tracker.trySolverFunc(() -> {
					return tryRep(factory, lexp, rval, repLeftGoal, goal, vals, cur,
						hintsWithRepetition, description);
				});
				if (sol != null) {
					return sol;
				}
			}
		}
		return tracker.returnBest(rval, goal);
	}
Solves expressions of the form {@code A * B}
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/app/plugin/assembler/sleigh/expr/MultExpressionSolver.java