private void createVariableStorageReference(Instruction instruction,
			VarnodeContext varnodeContext, TaskMonitor monitor, PrototypeModel conv, VariableStorage storage,
			DataType dataType, long callOffset) {
		
		Address lastSetAddr;
		BigInteger bval;
		
		// TODO: need to handle memory
		// TODO: need to handle multi-piece variables and re-assemble
		//
		
		if (storage.isStackStorage()) {
			if (conv == null) {
				return;
			}
			Varnode sVnode = storage.getFirstVarnode();
			
			// translate the variable relative to the current stackpointer symbolic value
			Varnode stackVarnode = varnodeContext.getStackVarnode();
			Varnode stackVal = varnodeContext.getValue(stackVarnode, null);
			if (stackVal == null) {
				return;
			}
			Varnode realSPVarnode = varnodeContext.createVarnode(stackVal.getOffset() + sVnode.getOffset(),
					stackVal.getSpace(), sVnode.getAddress().getAddressSpace().getPointerSize());
			
			Varnode value = null;
			value = varnodeContext.getValue(realSPVarnode,evaluator);
			if (value == null) {
				return;
			}

			if (!varnodeContext.isConstant(value)) {
				return;
			}
			bval = BigInteger.valueOf(value.getOffset());
			
			lastSetAddr = varnodeContext.getLastSetLocation(realSPVarnode, bval);
			
			// TODO: What if last set location is in a delayslot?
		}
		else if (storage.isRegisterStorage()) {
			// TODO: need to handle compound register storage (e.g., two registers
			// used)
			Register reg = storage.getRegister();
	
			// RegisterValue rval =
			// context.getRegisterValue(reg,instruction.getMinAddress());
			RegisterValue rval = varnodeContext.getRegisterValue(reg);
			if (rval == null || !rval.hasValue()) {
				return;
			}
			
			reg = rval.getRegister();
			bval = rval.getUnsignedValue();
			lastSetAddr = varnodeContext.getLastSetLocation(reg, bval);
			// if instruction has a delay slot, carefully check the location of the
			// lastSetAddr Value
			// to make sure it matches. If it doesn't, use this instruction
			if (lastSetAddr != null && instruction.getPrototype().hasDelaySlots()) {
				RegisterValue lastRval = varnodeContext.getRegisterValue(reg, lastSetAddr);
				if (lastRval == null || !lastRval.hasAnyValue() || !lastRval.equals(rval)) {
					lastSetAddr = instruction.getMaxAddress();
				}
			}
			
		}
		else {
			return;
		}
		
		makeVariableStorageReference(storage, instruction, varnodeContext, monitor, callOffset, dataType, lastSetAddr, bval);
	}
check if the offset is large enough to possibly be an address
    It shouldn't be smaller than +- MIN_BOUNDS
@param offset assumed relative to another register
@return true if it could be an address
Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java