public static RefType getDefaultStackRefType(CodeUnit cu, int opIndex) {

		if (!(cu instanceof Instruction)) {
			return RefType.DATA;
		}

		Instruction instr = (Instruction) cu;

		Object[] objs = instr.getOpObjects(opIndex);
		Scalar s = null;
		int scalarSize = 0;
		Register r = null;
		for (Object obj : objs) {
			if (obj instanceof Register) {
				if (r != null) {
					return RefType.DATA; // can't handle more than one register
				}
				r = (Register) obj;
			}
			else if (obj instanceof Scalar) {
				if (s != null) {
					return RefType.DATA; // can't handle more than one scalar
				}
				s = (Scalar) obj;
				scalarSize = s.bitLength() >> 3;
			}
		}
		if (r == null) {
			return RefType.DATA;
		}

		RefType refType = RefType.DATA;
		PcodeOp[] instrOps = instr.getPcode(true);

		Address stackOffsetAddr = null;
		if (s == null) {
			stackOffsetAddr = r.getAddress();
		}
		else {
			PcodeOp[] opOps = instr.getPcode(opIndex);
			for (PcodeOp op : opOps) {
				int opCode = op.getOpcode();
				Varnode[] inputs = op.getInputs();
				// Handle register w/ scalar case
				if (opCode == PcodeOp.INT_ADD || opCode == PcodeOp.INT_SUB) {
					int matchCnt = 0;
					for (int i = 0; i < inputs.length; i++) {
						Varnode input = inputs[i];
						Address addr = input.getAddress();
						// INT_SUB input order must be Register,Scalar
						if ((opCode == PcodeOp.INT_ADD || i == 0) && input.isRegister() &&
							addr.equals(r.getAddress())) {
							++matchCnt;
						}
						else if ((opCode == PcodeOp.INT_ADD || i == 1) && input.isConstant()) {
							int size = input.getSize();
							long value = s == null ? 0 : s.getValue();
							if (size >= scalarSize && size <= 8 &&
								addr.getOffset() == (value & MASKS[size])) {
								++matchCnt;
							}
						}
					}
					if (matchCnt == 2) {
						stackOffsetAddr = op.getOutput().getAddress();
						refType = getLoadStoreRefType(instrOps, 0, stackOffsetAddr, refType);
						break;
					}
				}
			}
		}

		if (stackOffsetAddr != null) {
			HashSet<Address> addrs = new HashSet<>();
			addrs.add(stackOffsetAddr);
			for (int opSeq = 0; opSeq < instrOps.length; opSeq++) {
				PcodeOp op = instrOps[opSeq];
				int opCode = op.getOpcode();
				Varnode[] inputs = op.getInputs();
				if (opCode == PcodeOp.COPY || opCode == PcodeOp.INT_ZEXT) {
					if (addrs.contains(inputs[0].getAddress())) {
						RefType rt = getLoadStoreRefType(instrOps, opSeq + 1,
							op.getOutput().getAddress(), refType);
						if (rt == RefType.READ) {
							if (refType == RefType.WRITE) {
								return RefType.READ_WRITE;
							}
							refType = rt;
						}
						else if (rt == RefType.WRITE) {
							if (refType == RefType.READ) {
								return RefType.READ_WRITE;
							}
							refType = rt;
						}
					}
				}
			}
		}

		return refType;
	}
Get the default register data RefType for the specified code-unit/opIndex and register
@param cu the code unit to get the default stack ref type.
@param opIndex the operand index.
@return the default register datat refType.
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/symbol/RefTypeFactory.java