POP's setting of C and Z flags, I'd like it changed. Anyone use it?
evanh
Posts: 15,915
In the early days PUSH and POP for the small hardware stack was built around just storing addresses only. But it also saved and optionally restored the C and Z condition code flags.
About a year back, I think, that was changed to PUSHing an ordinary full 32 bits - no flag bits. And POP restores 32 bits, but with optionally the top two bits still replacing C and Z. It seems to be something of a leftover. I have my doubts as to whether anyone even wants that as a feature. Is condition flag setting via this method in use?
I'd like to have POP set the Z flag to indicate the popped value as being zero or not. EDIT: Looking at POPA/B instructions. Make it the same as those would be perfect.
About a year back, I think, that was changed to PUSHing an ordinary full 32 bits - no flag bits. And POP restores 32 bits, but with optionally the top two bits still replacing C and Z. It seems to be something of a leftover. I have my doubts as to whether anyone even wants that as a feature. Is condition flag setting via this method in use?
I'd like to have POP set the Z flag to indicate the popped value as being zero or not. EDIT: Looking at POPA/B instructions. Make it the same as those would be perfect.
Comments
It does still seem a slight oddity. Is this something worth straightening out anyway?
PUSHA/POPA/PUSHB/POPB handle C and Z as per the maths and logic instructions do. PUSH is the same.
POP is the odd one out.
But, still need to clear top two bits. Unless it's an address I guess...
I will change the Verilog for the respin.
Thanks for pointing this out. I had been coming from the CALL/RET paradigm and wasn't thinking about PUSH/POP normally.
'odd one out' is never a good thing.
Unless there is a compelling use case, it seems simpler to make all behave the same.
So that makes all POPs the same ?
and {WC/WZ/WCZ} control if the POP actually does modify C,Z ?
Correct.
Confirmation regarding the various RETx instructions, I note they have optional setting of C/Z flags. Does that mean flag restoring from stack is optional?
EDIT: What about the _RET_ case?
Correct for 'RET WCZ'
_RET_ affects C/Z per the associated instruction's rules.
Yes, you can effectively preserve C and/or Z through a CALL by ending the called routine with 'RET WC/WZ/WCZ'.
No flags mentioned so not preserved. I like the flag preservation.
That reads somewhat counter-intuitively.
In all other cases, WCZ takes what could be the current live C/Z values, and updates CZ.
In the RET case, is it the older values, that were stored on the call, that are placed in CZ.
If you leave off the WCZ, I presume the current subroutine C/Z values are returned instead.
Does that need a clearer syntax, like
RET RCZ for Restore CZ (or PCZ for pop CZ / preserve caller CZ)
ie that's a semantic change in assembler (alias), for clarity, not a verilog change.
It doesn't look so bad in the formatted source, eg:
That then requires the opposite default ?
I've just tested that idea Garry: CMPS is controlling the flags. _RET_ does nothing to them.
Because it is common to return boolean function results in C, I think that's the correct operation ?
- ie function controls C value, and ret does not pop anything.
I'm pretty certain, from what Gary has said just now, that his code assumes that _RET_ restores the calling C and Z flags.
It's funny, I hadn't been relying on preservation of condition codes in any of my code but had wanted it many times on the Propeller simply because conditional execution can so readily make use of such a feature. I've only realised, today, that the option is there at all.
Certainly back before C gained a native boolean type, it was less common, but because MCUs usually have opcodes for directly testing carry, it makes sense to not waste a register returning 1 or 0 - even more so on a 32b MCU with limited memory.
one example: http://www.keil.com/support/man/docs/c51/c51_ap_funcret.htm
Code speed upon exit testing would be a point I'd believe. But even there, most non-RISC architectures modify the flags on most opcodes, rapidly negating any speed advantage.
No, the point that garryj is making is that he wants the flags to be written by the last instruction in a routine and return without the need for a separate RET afterwards that would waste time and code. There is only instruction prefix available for _RET_ and it can't either restore the flags or leave them alone. How it is now is the best option.
Changing how POP handles the flags would have a detrimental affect in the following situation: if the POP pops a return address then the flags on entry to the routine will be lost. I think it would be good if we had instructions that could read and write the flags on the top of the stack in the TOS register directly and there is spare opcode bit in RCZR/RCZL.
Tony,
All popping instructions have optional wcz bit-fields. You only overwrite the flags you want. That doesn't change. The only actual change is the new meaning of Z when POP is setting the condition codes. EDIT: It will be the same as the other POPA/POPB instructions.
I should have tried reading the code I guess. CMPS only make sense as the last instruction when it's meant to set the flags.
I got POP to a better place though!
POP reg WC/WZ/WCZ
C = reg[31]
Z = (reg == 0)
RET WC/WZ/WCZ
C = reg[31]
Z = reg[30]
POPping a return address can give you value of C on entry to a routine, as before, but not entry Z. Just an observation.
You have to do:
TESTB popped_value,#30 wz