boolean processAndEmulatePCode(PcodeOp pcodeOp, ContextState currentState, TaskMonitor monitor)
			throws CancelledException, InlineCallException {

		SequenceNumber seq = pcodeOp.getSeqnum();
		currentState.setExitPoint(seq);

		Varnode[] inputs = pcodeOp.getInputs();
		Varnode output = pcodeOp.getOutput();
		Varnode[] values = new Varnode[inputs.length];
		for (int i = 0; i < inputs.length; i++) {
			values[i] = simplify(currentState.get(inputs[i], monitor), monitor);
			if (values[i] == null) {
				values[i] = inputs[i];
				checkInput(inputs[i]);
			}
			else if (output != null && inputs[i].isAddress() && values[i].isConstant()) {
				if (listing.getFunctionAt(inputs[i].getAddress()) != null) {
					externalThunkMap.put(values[i].getOffset(), inputs[i].getAddress());
				}
			}
		}

		if (analyzer != null) {
			for (Varnode input : inputs) {
				// TODO: Watch out for memory based registers - could produce lots of references
				// TODO: Should we ever include simplified input values which are addresses ?
				if (input.isAddress()) {
					int opIndex = findOpIndex(pcodeOp, input);
					analyzer.dataReference(pcodeOp, opIndex, input, RefType.READ, monitor);
				}
			}
			if (output != null && output.isAddress()) {
				int opIndex = findOpIndex(pcodeOp, output);
				analyzer.dataReference(pcodeOp, opIndex, output, RefType.WRITE, monitor);
			}
		}

		if (output != null && output.getSize() > 8) {
			// Can't perform constant propagation values larger than a long
			Varnode result = new VarnodeOperation(pcodeOp, values);
			checkAssignment(output, result, pcodeOp, monitor);
			currentState.store(output, result);
			return true; // flow instructions do not have output
		}

		Varnode result = null;
		if (pcodeOp.getOpcode() == PcodeOp.LOAD) {
			result = simplifyLoad(pcodeOp, values, currentState, monitor);
		}
		else {
			result = simplify(pcodeOp, values, addrFactory, monitor);
		}

		if (result instanceof VarnodeOperation) {
			if (!emulateOperation((VarnodeOperation) result, currentState, monitor)) {
				return false;
			}
		}

		if (output != null) {
			if (result == null) {
				throw new AssertException("Result should not be null");
				//result = new VarnodeOperation(pcodeOp, values);
			}
			checkAssignment(output, result, pcodeOp, monitor);
			currentState.store(output, result);
		}

		return true;
	}
Process an instruction pcode operation after performing simplification on the inputs and operation
@param pcodeOp
@param currentState
@param monitor task monitor
@return true if state can continue to be propagated, otherwise a new state is
required due to the processing of a branch operation.
@throws CancelledException
@throws InlineCallException
Ghidra/Features/Base/src/main/java/ghidra/util/state/ResultsState.java