private AddressTable getAddressTable(Program program, Instruction instr, int opIndex,
			Address target, TaskMonitor monitor) {
		FlowType ftype = instr.getFlowType();

		// if this is a computed jump or call, with just 1 address operand, it can't be a jump/call table
		if (((ftype.isJump() || ftype.isCall()) && ftype.isComputed())) {
			if (instr.getNumOperands() == 1 && instr.getAddress(0) != null) {
				return null;
			}
		}
		AddressTable table =
			AddressTable.getEntry(program, target, monitor, true, MINIMUM_POTENTIAL_TABLE_SIZE,
				switchTableAlignment, 0, AddressTable.MINIMUM_SAFE_ADDRESS, relocationGuideEnabled);
		if (table != null) {
			Reference[] refs = instr.getOperandReferences(opIndex);
			for (Reference ref : refs) {
				if (ref.isOffsetReference()) {
					OffsetReference oref = (OffsetReference) ref;
					if (oref.getOffset() < -4) {
						table.setNegativeTable(true);
					}
				}
			}
			return table;
		}

		if (!switchTableEnabled || !((ftype.isJump() || ftype.isCall()) && ftype.isComputed())) {
			return null;
		}

		Object opObjects[] = instr.getOpObjects(opIndex);
		// figure out the multiple away
		long entryLen = 0;
		for (Object opObject : opObjects) {
			if (opObject instanceof Scalar) {
				Scalar sc = (Scalar) opObject;
				long value = sc.getUnsignedValue();
				if (value == 4 || value == 2 || value == 8) {
					entryLen = value;
					break;
				}
			}
		}
		if (entryLen == 0) {
			return null;
		}

//		 look for a negative offset table
		AddressTable lastGoodTable = null;
		Address negAddr = null;
		int i;
		for (i = 0; i < MAX_NEG_ENTRIES; i++) {
			try {
				negAddr = target.subtractNoWrap((i + 3) * entryLen);
			}
			catch (AddressOverflowException e) {
				break;
			}

			// if there is an instruction at the offset
			if (program.getListing().getInstructionContaining(negAddr) != null) {
				break;
			}

			AddressTable negTable = AddressTable.getEntry(program, negAddr, monitor, false, 3,
				switchTableAlignment, 0, AddressTable.MINIMUM_SAFE_ADDRESS, relocationGuideEnabled);
			if (negTable == null) {
				break;
			}
			lastGoodTable = negTable;
			negTable.setNegativeTable(true);
		}
		if (i == MAX_NEG_ENTRIES) {
			return null;
		}

		if (lastGoodTable != null) {
			instr.removeOperandReference(opIndex, target);
			program.getReferenceManager()
					.addOffsetMemReference(instr.getMinAddress(), lastGoodTable.getTopAddress(),
						false, -((i + 3) * entryLen), RefType.DATA, SourceType.ANALYSIS, opIndex);
		}

		return lastGoodTable;
	}
Check for any jumps to Externals (manufactured labels).
Any externals directly jumped to should be looked at as a call.

Note: this shouldn't affect jumps in thunks, but beware...
@param monitor
@throws CancelledException
Ghidra/Features/Base/src/main/java/ghidra/app/plugin/core/analysis/OperandReferenceAnalyzer.java