Last visit was: Wed Mar 26, 2025 6:48 pm
It is currently Wed Mar 26, 2025 6:48 pm



 [ 5 posts ] 
 Status flags as register metadata? 
Author Message

Joined: Fri Jan 19, 2024 1:06 pm
Posts: 14
I've had this idea nagging in my head for a long time, ever since the '90s probably. (I'm a software guy, BTW)

Many instruction set architectures (M68K, x86, ARM32, ARM64...) have an architectural Status flag register with the four classic flags: (N)egative, (Z)ero, o(V)erflow and (C)arry representing the status of the last instruction.
Combinations of N and Z with V or C express the comparison operators < <= > >= == != for signed and unsigned values respectively.
Other architectures instead store a result from a comparison as a boolean 0 or 1 in either special predicate registers (Itanium, ARM SVE, AVX-512) or in general purpose registers (MIPS and RISC-V).
Predicates has been hailed as being easier to implement but conditional instructions would need to take a predicate as a source register. RISC-V (and probably MIPS before it) has been criticised for not having a Carry flag, instead requiring it to be calculated using additional instructions if you'd need it.
RISC architectures with status flags (ARM64, PPC) tend to have separate versions of some instructions that set and don't set the status flags register.

As a third option, how about storing the status flags resulting from an instruction as meta-data bits tagged to the instruction's destination register itself?
Actually, you would only need to store two of the four flags: V and C, as N and Z could be inferred from the register's value. In other words, a 32-bit register would store 34 bits: 32 data bits, V and C.
You would not need to specify special predicate registers.
There is no reason to have separate instructions that set/don't set status flags: you could let every instruction that has a result set them. Code that tests for Z or N could just use a register directly without a separate compare.

Is there any existing CPU's instruction set architecture that does it this way? (hobbyist, or one that got made in silicon?)
I don't know much about microarchitecture, but I suspect that perhaps some core for an ISA that uses flags could work like this internally.

Are there any immediate drawbacks with a scheme such as this?


Mon Aug 05, 2024 5:59 pm

Joined: Wed Jan 09, 2013 6:54 pm
Posts: 1814
As I understand it - though I'm not an expert - the evolution of tactics different from the status register is driven by wanting to make aggressive microarchitectures: pipelined, superscalar, speculative, out of order, predecoded micro-ops. When the number of physical registers is enormously greater than the number of architectural registers, it becomes a burden to have some bits of global state.

I'm not sure if this helps at all to answer the question!


Tue Aug 06, 2024 6:07 am

Joined: Sat Feb 02, 2013 9:40 am
Posts: 2262
Location: Canada
An issue to resolve with having metadata associated with a register is how and whether to save and restore the metadata along with the register value. Another piece of meta data that may be useful is a flag indicating if a pointer value is in the register.

It may be wasteful to have carry and overflow for every register since these status are rarely used. I like the PowerPC idea of having multiple condition code registers. Only a handful are needed and they contain only a few bits.

The My66000 discussed on comp.arch has an interesting way of dealing with carry. I believe it is passed along in pipeline registers where it is needed.

_________________
Robert Finch http://www.finitron.ca


Wed Aug 07, 2024 3:49 am WWW

Joined: Fri Jan 19, 2024 1:06 pm
Posts: 14
robfinch wrote:
An issue to resolve with having metadata associated with a register is how and whether to save and restore the metadata along with the register value.

Most ISAs with flags have an instruction way to test a condition code and get a 0 or 1 in a register from it. SETcc (x86), CINC (ARM). Otherwise people seem to get by without instructions for loading/storing flags..

Edit: Excuse me, I understand now that you meant how to save/restore registers at context switches. I suppose they could be aliased to a control register. With 2 bits in 32 GPRs they would fit in a 64-bit register.
Spilled registers would be stripped of its flags, with filling just being regular loads -- which would naturally clear V and C.

jmp_bufs (setjmp/longjmp) should not contain register values. The C standard does not require variables not declared `volatile` to be preserved, but I think they should all be — on the stack, with the state of the last function call, not the last setjmp call. It is a non-local jump, not a checkpoint mechanism.

robfinch wrote:
Another piece of meta data that may be useful is a flag indicating if a pointer value is in the register.

I think such a segregation could belong in the front-end, and not in the register file.
Either have architectural address registers (like M68K) or make the register rename logic segregate pointers from data.

I'm otherwise a fan of capability machines, like CHERI where a pointer has access rights and bounds, and those would be even larger and therefore probably best stored in separate physical registers anyway.

robfinch wrote:
The My66000 discussed on comp.arch has an interesting way of dealing with carry. I believe it is passed along in pipeline registers where it is needed.

I've followed Mitch Alsup's posts there. I don't recall that the handling of the flag itself would be different than on other architectures, only that there is a "The next instruction uses Carry" instruction. I haven't seen how you would express the difference between "set carry" and "use and set carry" though.

BTW, the My 66000 has yet another way to handle conditions. The CMP instruction writes a bitfield to the destination register with a bit per condition code (LT, GT, etc.)


Wed Aug 07, 2024 5:53 am

Joined: Mon Oct 07, 2019 2:41 am
Posts: 743
Findecanor wrote:
robfinch wrote:
An issue to resolve with having metadata associated with a register is how and whether to save and restore the metadata along with the register value.

Most ISAs with flags have an instruction way to test a condition code and get a 0 or 1 in a register from it. SETcc (x86), CINC (ARM). Otherwise people seem to get by without instructions for loading/storing flags..

Edit: Excuse me, I understand now that you meant how to save/restore registers at context switches. I suppose they could be aliased to a control register. With 2 bits in 32 GPRs they would fit in a 64-bit register.
Spilled registers would be stripped of its flags, with filling just being regular loads -- which would naturally clear V and C.

jmp_bufs (setjmp/longjmp) should not contain register values. The C standard does not require variables not declared `volatile` to be preserved, but I think they should all be — on the stack, with the state of the last function call, not the last setjmp call. It is a non-local jump, not a checkpoint mechanism.

robfinch wrote:
Another piece of meta data that may be useful is a flag indicating if a pointer value is in the register.

I think such a segregation could belong in the front-end, and not in the register file.
Either have architectural address registers (like M68K) or make the register rename logic segregate pointers from data.

I'm otherwise a fan of capability machines, like CHERI where a pointer has access rights and bounds, and those would be even larger and therefore probably best stored in separate physical registers anyway.

robfinch wrote:
The My66000 discussed on comp.arch has an interesting way of dealing with carry. I believe it is passed along in pipeline registers where it is needed.

I've followed Mitch Alsup's posts there. I don't recall that the handling of the flag itself would be different than on other architectures, only that there is a "The next instruction uses Carry" instruction. I haven't seen how you would express the difference between "set carry" and "use and set carry" though.

BTW, the My 66000 has yet another way to handle conditions. The CMP instruction writes a bitfield to the destination register with a bit per condition code (LT, GT, etc.)

As a side note
my computer designs don't have flags, just a link (carry) bit raw from the alu.
ADD/ADC sets the carry bit. ADX (add index ) has no effect on the carry.

A problem here I think is because flags are used for three diffrent things, and often a error trap.
A) carry/borrow flags for large data or sign extending. Take adc for example, the flags need to move around with the adc operation.The 68000 is special here.
B)carry/sign and over flow for branching or setting a boolean result. They need to be out early for testing
or logical results.
C) floating point errors,
A status register would only need to keep 3 sets of flags for a irq service trap.


Fri Aug 23, 2024 7:30 am
 [ 5 posts ] 

Who is online

Users browsing this forum: CCBot and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software