public Varnode subtract(Varnode val1, Varnode val2, ContextEvaluator evaluator) {
		if (val1 == null || val2 == null) {
			return null;
		}

		// degenerate case, don't need to know the value
		if (val1.equals(val2)) {
			if (isBadAddress(val1)) {
				return val1;
			}
			int size = val1.getSize();
			size = size > 0 ? size : 1; // turning into constant, make sure has a size
			return createVarnode(0, addrFactory.getConstantSpace().getSpaceID(), size);
		}
		int spaceID = val1.getSpace();
		long valbase = 0;
		if (isConstant(val1)) {
			valbase = val1.getOffset();
			if (!isSuspectConstant(val1)) {
				spaceID = val2.getSpace();
			}
		}
		else if (isRegister(val1)) {
			Register reg = trans.getRegister(val1);
			if (reg == null) {
				return null;
			}
			spaceID = getAddressSpace(reg.getName(),reg.getBitLength());
			valbase = 0;
		}
		else if (isSymbolicSpace(spaceID)) {
			Instruction instr = getCurrentInstruction(currentAddress);
			valbase = val1.getOffset();
			if (evaluator != null) {
				Long uval = evaluator.unknownValue(this, instr, val1);
				if (uval != null) {
					valbase = uval.longValue();
					return add(createConstantVarnode(valbase, val1.getSize()), val2, evaluator);
				}
			}
		}
		else {
			return null;
		}
		Long val2Const = getConstant(val2, null);
		if (val2Const == null) {
			return null;
		}
		long result = (valbase - val2Const) &
			(0xffffffffffffffffL >>> ((8 - val1.getSize()) * 8));
		return createVarnode(result, spaceID, val1.getSize());
	}
Subtract two varnodes to get a new value
This could create a new space and return a varnode pointed into that space

@param val1 first value
@param val2 second value
@return varnode that could be a constant, or an offset into a space
Ghidra/Features/Base/src/main/java/ghidra/program/util/VarnodeContext.java