Address flowArmThumb(Program program, Instruction instruction, VarnodeContext context,
			Address target, FlowType flowType, boolean addReference) {
		if (target == null) {
			return null;
		}
		long bxOffset = target.getOffset();
		long thumbMode = bxOffset & 0x1;

		Address addr = instruction.getMinAddress().getNewAddress(bxOffset & 0xfffffffe);

		Listing listing = program.getListing();

		if (flowType != null) {
			int opIndex = -1;
			for (int i = 0; i < instruction.getNumOperands(); i++) {
				int opType = instruction.getOperandType(i);
				// markup the program counter for any flow
				if ((opType & OperandType.REGISTER) != 0 || (opType & OperandType.DYNAMIC) != 0) {
					opIndex = i;
					break;
				}
			}

			if (addReference) {
				Reference[] refsFrom = instruction.getReferencesFrom();
				boolean foundRef = false;
				for (Reference element : refsFrom) {
					if (element.getToAddress().equals(addr)) {
						// reference already there, assume thumb bit propagated
						foundRef = true;
						break;
					}
				}
				if (!foundRef) {
					if (opIndex == -1) {
						instruction.addMnemonicReference(addr, flowType, SourceType.ANALYSIS);
					}
					else {
						instruction.addOperandReference(opIndex, addr, flowType,
							SourceType.ANALYSIS);
					}
				}
			}
		}

		if (tmodeRegister != null && listing.getUndefinedDataAt(addr) != null) {
			boolean inThumbMode = false;
			RegisterValue curvalue =
				context.getRegisterValue(tmodeRegister);
			if (curvalue != null && curvalue.hasValue()) {
				inThumbMode = (curvalue.getUnsignedValue().intValue() == 1);
			}
			// if the TB register is set, that trumps any mode we are tracking
			RegisterValue tbvalue = context.getRegisterValue(tbRegister);
			if (tbvalue != null && tbvalue.hasValue()) {
				inThumbMode = (tbvalue.getUnsignedValue().intValue() == 1);
			}
			else {
				// blx instruction on a direct address in ARM mode always goes to thumb mode
				if (instruction.getMnemonicString().equals("blx") || thumbMode != 0) {
					inThumbMode = true;
				}
			}
			BigInteger thumbModeValue = BigInteger.valueOf(inThumbMode ? 1 : 0);
			try {
				program.getProgramContext().setValue(tmodeRegister, addr, addr, thumbModeValue);
			}
			catch (ContextChangeException e) {
				Msg.error(this, "Unexpected Exception", e);
			}
			return addr;
		}

		// instruction already there
		return null;
	}
Disassemble at the specified target address and optionally create a mnemonic flow reference.
@param monitor
@param instruction flow from instruction
@param target disassembly address
@param flowType if not null a reference from the instruction mnemonic will be created to the specified
target address using this flowType.
@param addReference
Ghidra/Processors/ARM/src/main/java/ghidra/app/plugin/core/analysis/ArmAnalyzer.java