@Override
	public TaintVec binaryOp(int opcode, int sizeout, int sizein1, TaintVec in1,
			int sizein2, TaintVec in2) {
		switch (opcode) {
			case PcodeOp.BOOL_AND:
			case PcodeOp.BOOL_OR:
			case PcodeOp.BOOL_XOR:
			case PcodeOp.INT_AND:
			case PcodeOp.INT_OR:
			case PcodeOp.INT_XOR:
				return in1.zipUnion(in2);
			case PcodeOp.INT_ADD:
			case PcodeOp.INT_SUB: {
				TaintVec temp = in1.zipUnion(in2);
				return temp.setCascade(endian.isBigEndian());
			}
			case PcodeOp.PIECE: {
				TaintVec temp = in1.extended(sizeout, endian.isBigEndian(), false);
				temp.setShifted(endian.isBigEndian() ? -sizein2 : sizein2, ShiftMode.UNBOUNDED);
				return temp.set(endian.isBigEndian() ? sizeout - sizein2 : 0, in2);
			}
			default: {
				TaintVec temp = in1.zipUnion(in2);
				return temp.setCopies(temp.union());
			}
		}
	}
{@inheritDoc}

<p>
For bitwise operations, we pair-wise union corresponding elements of the two input taint
vectors. For integer add and subtract, we do the same, but account for the carry bits
possibly cascading into bytes of higher significance. For {@link PcodeOp#PIECE}, we perform
the analog as on concrete state, since the operand sizes are constant. For all others, we
must consider that every output byte is potentially affected by any or all bytes of both
input operands. Thus, we union and broadcast.
Ghidra/Debug/TaintAnalysis/src/main/java/ghidra/pcode/emu/taint/TaintPcodeArithmetic.java