Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems with C & V flags when using the SUBS instruction #4

Open
4dvpitts opened this issue Jun 8, 2022 · 1 comment · May be fixed by #6
Open

Problems with C & V flags when using the SUBS instruction #4

4dvpitts opened this issue Jun 8, 2022 · 1 comment · May be fixed by #6

Comments

@4dvpitts
Copy link

4dvpitts commented Jun 8, 2022

Hi,
I have encountered issues that arise from the setting of the C and V flags when trying to use conditional branches (B.HI and B.LE)

The sequence
movz x1, #36
movz x2, #54
subs x5, x1, x2
b.LE lse
does not work properly. The V flag is set but 36-54 = -18 is not a signed overflow.

The sequence
movz x1, #54
movz x2, #36
subx x5, x1, x2
b.GT gtr
does not work properly as 54-36=18 does not set the carry bit as it should.

In the setVflag(long result, long op1, long op2) {
replacing

with
Vflag = (((long) op1 & 0x80000000L) == ((long) op2 & 0x80000000L)) && ((long) result != (long)op1;
may work but I don't have the experience with GWT projects to rebuild.

I haven't had a chance to figure the issue with setting the C flag in the other scenario.

Thanks,
Dave

@Ayilay
Copy link

Ayilay commented Sep 27, 2022

I have observed a similar issue as well, and it applies to ADDS as well. My issue is the C flag not being set under certain circumstances, whereas the expected behavior dictates that it should.

The issue occurs when the dest register is the same as one of the src registers. For example:

# Example 1: assume the following register values:
# x0: (-1, 64 bit) 0xFFFFFFFF_FFFFFFFF
# x1: (3, 64 bit) 0x3

# Correctly sets the C flag to 1
ADDS  x2, x1, x0
# Example 2: assume same register values as example 1 above

# INCORRECTLY does not set the C flag
ADDS  x0, x1, x0

I believe the culprit to be the following function:

// File src/.../client/cpu/CPU.java
private void ADDS(int destReg, int op1Reg, int op2Reg) {
    long result = registerFile[op1Reg] + registerFile[op2Reg];
    if (destReg == XZR) {
        cpuLog.append("Ignored attempted assignment to XZR. \n");
    } else {
        registerFile[destReg] = result;
        cpuLog.append("ADDS \t X" + destReg + ", X" + op1Reg + ", X" + op2Reg + "\n");
    }
    ADDSetFlags(result, registerFile[op1Reg], registerFile[op2Reg]);
    cpuLog.append("Set flags + \n");
}

Note the ADDSetFlags function call: It uses the new modified register values rather than the original register values. This is different from the behavior on real ARM Silicon (Apple M1); on the real silicon, the C flag gets set in both examples I illustrated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants