Search code examples
javax86intelcarryflag

Calculating Carry Flag


I am writing an x86 interpreter in Java and have a Python script that tests my implementations of x86 instructions against its real counterparts using NASM. According to this test all flags are set correctly, besides the carry flag. The interesting part is:

long result;
    switch (op) {
    case ADD:
        result = Math.abs(x) + Math.abs(y);
        if (result > U_MAX)
            registers.carry_flag = true;
        else
            registers.carry_flag = false;
        break;

where U_MAX is 4294967295L (all 32 bits set).
All answers that I found didn't realize that carry and overflow are two different things. So, how can I implement the carry flag correctly in Java?


Solution

  • All this absolute value business is unnecessary and frankly confusing and it has the edge-case that Math.abs(Integer.MIN_VALUE) is negative (not that weird when you get down to it, but it doesn't look like this code expects it), you can calculate the carry in simpler ways .

    For example using the old "result is unsigned less than one operand". The result is of course just x + y (as int), signedness is irrelevant to addition. Then with Java 8, you can use Integer.compareUnsigned, otherwise you can use this identity:

    x <u y = (x ^ Integer.MIN_VALUE) <s (y ^ Integer.MIN_VALUE)
    

    where <u and <s are unsigned less than and signed less than, respectively.

    You could also calculate (x & 0xffffffffL) + (y & 0xffffffffL) and use it for both the result (cast to int) and the carry flag (the 33th bit).