From: Andy 'Krazy' Glew on
On 6/19/2010 12:50 PM, Niels J�rgen Kruse wrote:
> Andy 'Krazy' Glew<ag-news(a)patten-glew.net> wrote:
>
>> Unfortunately, there are several different types of integer overflow.
>> E.g. the overflow conditions for each of the following are different
>>
>> unsigned + unsigned
>> signed + signed
>> signed + unsigned
>
> Are you talking about D or some other language that is not C?

D is a language that espouses thrwing exceptions for errors.

But, I am not talking languages. I do not mean "unsigned" and "signed" as C datatypes. I a talking about generic
arithmetic. Languages should embed rules that model arithmetic, not vice versa.

What I mean, in longhand, is something like

"When two N bit numbers, for any N, are both interpreted as unsigned numbers, then overflow is` reported if there is any
carry out of the most significant bit (for add). Or, if the calculation is performed in infinite (unsigned) precision,
if the infinite precision result changes in value when truncated to N bits."

Similarly for the othedrs.



From: nmm1 on
In article <885boqFa10U1(a)mid.individual.net>,
Andrew Reilly <areilly---(a)bigpond.net.au> wrote:
>On Sat, 19 Jun 2010 21:29:17 +0100, nmm1 wrote:
>> In article <1jkcsdg.28nffa169emgN%nospam(a)ab-katrinedal.dk>,
>> =?ISO-8859-1?Q?Niels_J=F8rgen_Kruse?= <nospam(a)ab-katrinedal.dk> wrote:
>>>Andy 'Krazy' Glew <ag-news(a)patten-glew.net> wrote:
>>>
>>>> Unfortunately, there are several different types of integer overflow.
>>>> E.g. the overflow conditions for each of the following are different
>>>>
>>>> unsigned + unsigned
>>>> signed + signed
>>>> signed + unsigned
>>>
>>>Are you talking about D or some other language that is not C?
>>
>> He doesn't need to. They're all different in C.
>
>No, the last one doesn't exist (as a different kind of add) in C: it's an
>implicit type conversion (to unsigned, usually, because apparently it's
>more important to preserve the positive range than the negative) followed
>by an unsigned add. ...

It's still different :-) Your description of what happens assumes
thet the integers have the same conversion rank - the situation is
a lot more complicated when they don't (see C99 6.3.1.8).

>The reference to C is interesting, because I've recently had the
>experience of encountering a C compiler that actively thwarted the usual
>idiom for signed overflow detection. That is something like:
>
>where x and y are int:
>if (y >= 0) { if (x + y < x) signed_overflow(); } else { if (x + y > x)
>signed_underflow(); }
>
>The compiler in question (can't remember whether it was a recent gcc or
>one of the ARM compilers) came up with this beauty:
>
>warning: assuming signed overflow does not occur when assuming that (X +
>c) < X is always false
>
>Apparently wording in the C standard lets them do that.

Well, yes, of course. So does Fortran and most comparable languages.
On a better implementation, you would get a run-time error, of course.

> The "best"
>alternative I've found so far is to use extra arithmetic precision.
>Quite a small value of "best". When even addition requires the use of in-
>line assembly to produce useful results, the language is dead.

Eh? That code's erroneous - wrong, buggy, defective. You shouldn't
write code that overflows in C or Fortran. End of story. Sorry,
but that is the situation, both de jure and de facto. Even ignoring
that, it relies on C90 semantics, and C99 is incompatible - you need
to do the following to generate the code that you expect:

if (y >= 0) { if ((<integer type>)(x + y) < x) signed_overflow(); }
else { if ((<integer type>)(x + y) > x) signed_underflow(); }

Also, that's a trivial example. I give a slightly more complicated
one in my arithmetic course, and point out that undetected overflow
can cause ANY effect once you enable serious levels of optimisation.

Sorry, but ....


Regards,
Nick Maclaren.
From: nedbrek on
Hello all,

"Brett Davis" <ggtgp(a)yahoo.com> wrote in message
news:ggtgp-E06A37.15294419062010(a)news.isp.giganews.com...
> In article <hvi9bp$1v7$1(a)news.eternal-september.org>,
> "nedbrek" <nedbrek(a)yahoo.com> wrote:
>> The advantage CISC has is that the uop sequence looks like:
>> ld tmp = [r2]
>> add r1 += tmp
>>
>> Since tmp is not an architected register, it does not have to be
>> preserved
>> for an interrupt, or seen past the use in add (it is known dead). Thus,
>> it
>> can exist strictly in the bypass network (it is not allocated a rename
>> register, it is not visible to later instructions [does not participate
>> in
>> renaming], and has no architected effects at retirement).
>>
>> The RISC sequence will always be (ld r3 = [r2]; add r1 += r3). r3 is
>> live
>> out, and must be architecturally visible. You can smash ops together,
>> giving you r3,r1 = load-op [r2] + r1
>>
>> You can't say just "need an extra write port" unless you have a simple 5
>> stage pipeline. In a modern machine, this means extra decode bits (in
>> the
>> scheduler and ROB), extra RAT ports, extra complexity come retirement
>> time
>> (do you allow every instruction to update two entries in the retirement
>> register table?)
>
> I forgot that on both PowerPC and x86 the Load Unit has its own register
> write port, so you do have an extra write port, and I assume that on x86
> the Load Unit is involved in the Add from Memory, if only for the bypass
> data.

Is there an arch where load does not produce a reg result?

> So the real savings is having the Add instruction issue the [r2] register
> read instead of a r3 register read, saving an issue slot and cycle?

- There is a saving in your internal instruction format (uop encoding):
the X86 fused uop has {op, dst, src} while the fused RISC has {op, dst1,
dst2, src}

- This impacts the renamer, the X86 has one dest per uop, while the RISC has
two. Every dest in rename equates to one write port (assuming a table based
renamer, like the RAT in P6).

- It also impacts retirement. At retirement time, you must update the
architected registers (usual implementations are an architected register
file [P6] or a architected rename map [P4]). Either way, that is another
write port...

Ned


From: nedbrek on
Hello all,

"Andy 'Krazy' Glew" <ag-news(a)patten-glew.net> wrote in message
news:4C1DA045.1020507(a)patten-glew.net...
> On 6/19/2010 5:23 AM, nedbrek wrote:
>
>> The advantage CISC has is that the uop sequence looks like:
>> ld tmp = [r2]
>> add r1 += tmp
>>
>> Since tmp is not an architected register, it does not have to be
>> preserved
>> for an interrupt, or seen past the use in add (it is known dead). Thus,
>> it
>> can exist strictly in the bypass network (it is not allocated a rename
>> register, it is not visible to later instructions [does not participate
>> in
>> renaming], and has no architected effects at retirement).
>
> Anecdote: at Intel Mike Haertel and I thought that AMD K7 was taking
> advantage
> of this, to get an effectively larger instruction window. Intel was not.
> When we moved to AMD, we learned that they were not. Perhaps now they
> are.

A lot of innovation at Intel is driven by paranoia about what AMD might be
doing. That is a good thing.

If only the Itanium guys had been more paranoid. They predicted IBM would
ship parts with lower performance over time!

Ned


From: Andrew Reilly on
On Sun, 20 Jun 2010 06:34:32 -0500, nedbrek wrote:

> Is there an arch where load does not produce a reg result?

"Is" is perhaps too strong a qualifier, but certainly Vax, 32x32, PDP-11
and others of that ilk had arbitrary addressing modes available for all
operands, only one flavor of which was "register". So memory sources and
memory destinations were possible. Not that you would necessarily call
those "load" instructions, I suppose...

Cheers,

--
Andrew