Investigation of the carry result of MOVS and friends

Raise your hand if you've ever thought about what MOVS,MOVD and MOVI write to the carry flag!

Nobody? meh.

The Propeller Manual has the incredibly helpful description "---", yet the concise truth table shows the carry sometimes getting set. However, I cannot deduce it's meaning from that. I've also looked at GEAR's code, but it's author doesn't have any idea, either. So i had to go deeper: The P1V verilog code. There, I found the truth: MOVS, MOVD and MOVI, as one would expect, share a lot of logic with JMPRET. For these four instructions, the carry generation logic selects the carry output from the adder, which is configured to calculate D-S. Thus, the carry is simply that: unsigned D<S
I've run some tests, which seem to support this claim.

So now we know what MOVS, MOVD and MOVI do. However, what was that about JMPRET? JMPRET's manual entry states that:
The C flag is set (1) unless PC+1 equals 0; very unlikely since it would require the JMPRET to be executed from the top of cog RAM
($1FF; special purpose register VSCL).
According to the Verilog AND my tests, this is very very wrong. Parallax should consider updating the manual to state the carry results of the four instructions I talked about and to change the remark on JMPRET to
The Z flag is cleared (0) unless PC+1 equals 0; very unlikely since it would require the JMPRET to be executed from the top of cog RAM
($1FF; special purpose register VSCL).

Comments

  • 1 Comment sorted by Date Added Votes
  • For most of the instructions the Z flag is set when the result is zero. I think the carry is actually the unsigned value1<value2. The code that I use for jmpret in spinsim is
                cflag = ((uint32_t)value1) < ((uint32_t)value2);
                result = (value1 & 0xfffffe00) | ((pc + 1) & 0x1ff);
                zflag = (result == 0);
    
    So both the C and Z flags depend on the 32-bit values of value1 and value2.
Sign In or Register to comment.