public static FlowType getDefaultFlowType(Instruction instr, Address toAddr,
			boolean allowComputedFlowType) {

		if (!toAddr.isMemoryAddress() && !toAddr.isExternalAddress()) {
			throw new IllegalArgumentException("Unsupported toAddr address space type");
		}

		FlowType flowType = null;
		boolean simpleFlow =
			(instr.getFlowType() != RefType.INVALID && instr.getDefaultFlows().length <= 1);
		if (simpleFlow) {
			// only use default if simple flow
			flowType = getDefaultJumpOrCallFlowType(instr);
		}

		if (flowType != null && (!flowType.isComputed() || allowComputedFlowType)) {
			return flowType;
		}

		if (simpleFlow || toAddr.isExternalAddress()) {
			// Don't bother looking if not complex flow or address is external
			return null;
		}

		// Assumption - it is assumed that any complex flow type is due to the presence of
		// multiple conditional flows.  Does not handle use of constant offsets since
		// language should be using Address locations for all flow pcode!

		// TODO: Verify that above assumption is valid !!

		PcodeOp[] pcodeOps = instr.getPcode();
		for (PcodeOp op : pcodeOps) {
			int opcode = op.getOpcode();
			if (opcode == PcodeOp.CBRANCH || opcode == PcodeOp.BRANCH) {
				if (op.getInput(0).getAddress().equals(toAddr)) {
					return RefType.CONDITIONAL_JUMP;
				}
			}
			else if (opcode == PcodeOp.CALL) {
				if (op.getInput(0).getAddress().equals(toAddr)) {
					return RefType.CONDITIONAL_CALL;
				}
			}
		}

		if (flowType == null && allowComputedFlowType) {
			flowType = getDefaultComputedFlowType(instr);
		}
		return flowType;
	}
Determine default FlowType for a specified instruction and flow destination toAddr.
@param instr instruction
@param toAddr flow destination address
@param allowComputedFlowType if true and an absolute flow type is not found
a computed flow type will be returned if only one exists.
@return FlowType or null if unable to determine
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/symbol/RefTypeFactory.java