@Override
	public JitType generateBinOpRunCode(JitCodeGenerator gen, JitIntCarryOp op, JitBlock block,
			JitType lType, JitType rType, MethodVisitor rv) {
		rType = TypeConversions.forceUniformZExt(rType, lType, rv);
		switch (rType) {
			case IntJitType(int size) when size == Integer.BYTES -> {
				// [l,l,r]
				rv.visitInsn(IADD);
				// [l,sum]
				rv.visitInsn(SWAP); // spare an LDC,XOR
				// [sum,l]
				rv.visitMethodInsn(INVOKESTATIC, NAME_INTEGER, "compareUnsigned",
					MDESC_INTEGER__COMPARE_UNSIGNED, false);
				// [cmpU(sum,l)] sum < l iff sign bit is 1
				rv.visitLdcInsn(31);
				rv.visitInsn(IUSHR);
				return IntJitType.I1;
			}
			case IntJitType(int size) -> {
				// Just add and extract the carry bit
				rv.visitInsn(IADD);
				rv.visitLdcInsn(size * Byte.SIZE);
				rv.visitInsn(ISHR);
				rv.visitLdcInsn(1);
				rv.visitInsn(IAND);
				return IntJitType.I1;
			}
			case LongJitType(int size) when size == Long.BYTES -> {
				// [l:LONG,l:LONG,r:LONG]
				rv.visitInsn(LADD);
				// [l:LONG,sum:LONG]
				rv.visitInsn(DUP2_X2);
				rv.visitInsn(POP2);
				// [sum:LONG,l:LONG]
				rv.visitMethodInsn(INVOKESTATIC, NAME_LONG, "compareUnsigned",
					MDESC_LONG__COMPARE_UNSIGNED, false);
				// [cmpU(sum,l):INT] sum < l iff sign bit is 1
				rv.visitLdcInsn(31);
				rv.visitInsn(IUSHR);
				return IntJitType.I1;
			}
			case LongJitType(int size) -> {
				// Just add and extract the carry bit
				rv.visitInsn(LADD);
				rv.visitLdcInsn(size * Byte.SIZE);
				rv.visitInsn(LSHR);
				rv.visitInsn(L2I);
				// TODO: This mask may not be necessary
				rv.visitLdcInsn(1);
				rv.visitInsn(IAND);
				return IntJitType.I1;
			}
			case MpIntJitType t when t.size() == lType.size() -> {
				generateMpIntCarry(gen, t, rv);
				return IntJitType.I1;
			}
			case MpIntJitType t -> {
				return TODO("MpInt of differing sizes");
			}
			default -> throw new AssertionError();
		}
	}
There are two strategies to use here depending on whether or not there's room to capture
the carry bit. If there's not room, we have to compare the sum to one of the input
operands. If the sum is less, then we can conclude there was a carry. For that strategy,
we will need to keep a copy of the left operand, so duplicate it.

On the other hand, if there is room to capture the carry, we can just add the two
operands and extract the carry bit. There is no need to duplicate the left operand.
Ghidra/Framework/Emulation/src/main/java/ghidra/pcode/emu/jit/gen/op/IntCarryOpGen.java