By: Wilco (Wilco.Dijkstra.delete@this.ntlworld.com), February 25, 2013 5:24 pm
Room: Moderated Discussions
EduardoS (no.delete@this.spam.com) on February 25, 2013 1:06 pm wrote:
> Wilco (Wilco.Dijkstra.delete@this.ntlworld.com) on February 25, 2013 7:36 am wrote:
> > Well it is useful for add in the same way it is useful for any other
> > operation. Programmers just tend to compare with zero a lot.
>
> I almost never compare the result of an ADD with zero, by the semantics
> of the operation this isnt very common or meaningful.
Well then you'll be surprised to hear that there are more adds/subs followed by a beq/bne than all logical operations combined...
> > Note if you really believe in condition codes, even loads should set the Z flag since ldr;
> > cmp #0; beq/bne is extremely common (of course I prefer Thumb-2 cbz/cbnz instead).
>
> That's true.
>
> > For those you'd need additional instructions, just like add with carry.
>
> So...
> 1) Add and set carry;
> 2) Add and set overflow;
> 3) Add with carry and set carry;
> 4) Sub and set borrow;
> 5) Sub and set overflow;
> 6) Sub with borrow and set borrow;
>
> Quite a lot opcode space, no?
You might not need (1) or (3). However ALU instructions don't take much opcode space. If encoding space were a concern, you wouldn't have mvn, orn, teq, cmn or tst on ARM for example (these are rarely used).
> > For floating point you always use a compare first.
>
> No, when you care about not getting meaningless results you may check wheter each operation didn't
> resulted in overflow or NaN, it is not very pratical to compare the output of each result.
You're talking about the cumulative exception flags, right? Those are completely separate and not directly usable by branches like a normal condition code. ARM has around 7 such flags. They are pretty much completely useless so remain unused. With FP you only need to check the final result to check whether it is meaningless or not.
> > As long as you stay with C/C++ then you would not see overflow checks even if they
> > were used in the source. For Java/C# things are different of course, but even then
> > the number of overflow checks is small compared to the number of additions.
>
> It is not so much about the language but about the target market, when processing transactions
> it is ok if 2 billion + 3 billion = 5 billion, it is not ok if it results in an overflow exception,
> but at least your results still consistent, the transaction fail, the application don't, and it
> is completly inacceptable if the result is 705,032,704, that's what I am saying, some apps check
> for overflow way too often, it is a requirement for them, C/C++ just make it harder.
The point is that the overflow check will be different in different languages. If you write it explicitly in C then it doesn't matter if the hardware doesn't support a branch on overflow operation - as it won't be used anyway (yes some cases could be peepholed, but typical programmers write such checks in the most horrible and inefficient way that that is unlikely in general unfortunately).
> Finally, my opinion about flags is, if you are going to use them, use
> a full set of them, a single flag doesn't bring so much benefits.
If going all-out on flags, what about a flag for all-ones, top 16/24-bits zero (or same-sign as bit 15/23), even/odd, parity etc. Half/quarter carry? Just where do you stop?
Wilco
> Wilco (Wilco.Dijkstra.delete@this.ntlworld.com) on February 25, 2013 7:36 am wrote:
> > Well it is useful for add in the same way it is useful for any other
> > operation. Programmers just tend to compare with zero a lot.
>
> I almost never compare the result of an ADD with zero, by the semantics
> of the operation this isnt very common or meaningful.
Well then you'll be surprised to hear that there are more adds/subs followed by a beq/bne than all logical operations combined...
> > Note if you really believe in condition codes, even loads should set the Z flag since ldr;
> > cmp #0; beq/bne is extremely common (of course I prefer Thumb-2 cbz/cbnz instead).
>
> That's true.
>
> > For those you'd need additional instructions, just like add with carry.
>
> So...
> 1) Add and set carry;
> 2) Add and set overflow;
> 3) Add with carry and set carry;
> 4) Sub and set borrow;
> 5) Sub and set overflow;
> 6) Sub with borrow and set borrow;
>
> Quite a lot opcode space, no?
You might not need (1) or (3). However ALU instructions don't take much opcode space. If encoding space were a concern, you wouldn't have mvn, orn, teq, cmn or tst on ARM for example (these are rarely used).
> > For floating point you always use a compare first.
>
> No, when you care about not getting meaningless results you may check wheter each operation didn't
> resulted in overflow or NaN, it is not very pratical to compare the output of each result.
You're talking about the cumulative exception flags, right? Those are completely separate and not directly usable by branches like a normal condition code. ARM has around 7 such flags. They are pretty much completely useless so remain unused. With FP you only need to check the final result to check whether it is meaningless or not.
> > As long as you stay with C/C++ then you would not see overflow checks even if they
> > were used in the source. For Java/C# things are different of course, but even then
> > the number of overflow checks is small compared to the number of additions.
>
> It is not so much about the language but about the target market, when processing transactions
> it is ok if 2 billion + 3 billion = 5 billion, it is not ok if it results in an overflow exception,
> but at least your results still consistent, the transaction fail, the application don't, and it
> is completly inacceptable if the result is 705,032,704, that's what I am saying, some apps check
> for overflow way too often, it is a requirement for them, C/C++ just make it harder.
The point is that the overflow check will be different in different languages. If you write it explicitly in C then it doesn't matter if the hardware doesn't support a branch on overflow operation - as it won't be used anyway (yes some cases could be peepholed, but typical programmers write such checks in the most horrible and inefficient way that that is unlikely in general unfortunately).
> Finally, my opinion about flags is, if you are going to use them, use
> a full set of them, a single flag doesn't bring so much benefits.
If going all-out on flags, what about a flag for all-ones, top 16/24-bits zero (or same-sign as bit 15/23), even/odd, parity etc. Half/quarter carry? Just where do you stop?
Wilco