From: MitchAlsup on
Works great on signed arithmetic, blows wind on unsigned arithmetic,
and other useful programming mechanisms.

Do you really want to take an interrupt on a piece of code that looks
like:

int extract( int container, int size, int offset )
{
return (container << (32-offset-size)) >> (32-size);
}

Would you still want to take an interrupt if the function was:

int extract( int container, unsigned size, unsigned offset )
{
return (container << (32-offset-size)) >> (32-size);
}

You can get rid of the overflow problem if:

unsigned extract( unsigned container, unsigned size, unsigned offset )
{
return (container >> offset) & ~(~0 << size);
}

But here, you cannot get a signed field extractded from an unsigned
container without a lot of type-punning.

From: glen herrmannsfeldt on
MitchAlsup(a)aol.com wrote:

> Works great on signed arithmetic, blows wind on unsigned arithmetic,
> and other useful programming mechanisms.

(snip of C code examples)

Note that S/360, a machine that does have such an interrupt
(controllable with a user supplied mask), has both signed
and unsigned add and subtract instructions. AL (add logical)
does not generate a fixed overflow exception.

The main reason for the two instructions is that the
condition codes are different, as needed for unsigned
or multiple precision arithmetic, but also the different
exceptions allowed.

To continue the discussion, if exponent underflow is disabled
the register is set to zero. If enabled, the wrapped exponent
is stored and the interrupt routine can use it.

The significance exception comes from subtracting floating point
numbers when all significant bits are lost. I have never seen it
used, especially as the common way to zero a floating point
register is to subtract it from itself. As to the OP, though,
that is one place where the logical result is used to generate
an interrupt.

-- glen

From: andrewspencers on
Nick Maclaren wrote:
>> Are there any CPU architectures which tie the overflow flag to an
>> interrupt, so that programs don't have to put a flag test and
>> conditional branch after each arithmetic operation in order to avoid
>> modular arithmetic?
> Many, even today,
Which ones?

>> And similarly, are there any architectures which tie the output of a
>> logic function (hardwired or programmable) of the bits of a register or
>> combination of registers to an interrupt, in order to provide
>> interrupt-based loop termination and interrupt-based pattern matching?
> after decades of the ghastly approach to eliminating
> overflow errors by eliminating overflow detection. But, switch it on,
> and you will find an awfully high proportion of compiled code, run-time
> systems and libraries fall over horribly.
I'm a bit confused here; if the overflow flag can be tied to an
interrupt, and a program isn't explictly written to use that feature,
then turning the feature on and then running the program will cause the
program to fall over horribly if it experiences an overflow,
_regardless_ of whether the program was just ignoring the overflow flag
(which is the wrong thing to do if there's a possibility of overflow)
or actually checking the overflow flag and taking an appropriate course
of action. I'm talking not about using the interrupt-on-overflow
feature as an error checking mechanism, but as an optimization.
The program would have to be written explicitly to use the feature,
i.e. turn the feature on _itself_, and install its own interrupt
handler. The idea is that if the program is expecting to do a whole lot
of overflow-prone operations, e.g. bignum arithmetic
(infinite-precision integer arithmetic), it can install an interrupt
handler to examine the interrupted process and handle overflows, thus
allowing the main program to omit the "test overflow flag - conditional
branch past overflow hander - handle overflow" postscript which is
otherwise necessary after every overflowable operation.

> Not that I know of. It is an old idea, but I don't know if it was
> ever implemented in hardware. God alone knows why not, because it
> is an obviously useful facility (e.g. for C assert) and needs next
> to no hardware to implement it.
Well yes C assert would be another use, and array bounds checking.
But again I'm talking about using the feature as an optimization, not
as an error checking mechanism. E.g. instead of the standard "compare
loop counter register - conditional branch out of loop - increment loop
register - unconditional branch to beginning of loop" postscript at the
end of a loop, a program could instead simply use "increment loop
register - unconditional branch to beginning of loop" after setting an
interrupt to be triggered when the loop counter register reaches some
value, with the interrupt handler used to jump out of the loop.
And for linear searching, instead of the standard "load memory -
compare to test register - conditional branch out of loop - compare
loop counter register - conditional branch out of loop - increment loop
register - unconditional branch to beginning of loop", the program
could set an interrupt to be triggered when either the loop counter
register reaches some value or the test register matches some value,
thus allowing the actual loop to be simply "load memory - increment
loop register - unconditional branch to beginning of loop".

On an architecture with virtual memory, the interrupt handler address
could be vectored through the page tables the same way as normal
process memory, thus allowing processes to install and use their own
private interrupt handlers without interfering with or having to rely
on the operating system.

As it's clear that both Intel and AMD are willing to add useful
hardware features at the request of software developers (witness MMX
and variants, and now Vanderpool and Pacifica) even if those features
require substantial effort to implement, the only explanation for the
lack of interrupt-based overflow, loop termination, and pattern
matching, which would be simple to implement, is that no significant
software developers have requested these features.
Perhaps they've simply not paid any attention to the potential for such
optimization, and are under the delusion that branch prediction and
speculative execution subsume the interrupt-based optimizations?

From: glen herrmannsfeldt on
andrewspencers(a)yahoo.com wrote:
(snip)

> Well yes C assert would be another use, and array bounds checking.
> But again I'm talking about using the feature as an optimization, not
> as an error checking mechanism. E.g. instead of the standard "compare
> loop counter register - conditional branch out of loop - increment loop
> register - unconditional branch to beginning of loop" postscript at the
> end of a loop, a program could instead simply use "increment loop
> register - unconditional branch to beginning of loop" after setting an
> interrupt to be triggered when the loop counter register reaches some
> value, with the interrupt handler used to jump out of the loop.

Consider what the advantage would be. Unconditional branch is nice,
but mainly because the processor knows it is unconditional. A predicted
conditional branch should be about as good. The 360/91, a machine
designed before the cache was invented (on the 360/85), had a special
loop mode buffer. A backward branch within some number of doublewords
would enter loop mode where instruction fetch would stop (they were
in the buffer) and the branch was assumed taken (for prefetching).

It seems that in ESA/390 processors BXH is predicted as not taken,
and BXLE is predicted as taken. These instructions are often
used in test at the top and test at the bottom loops, respectively,
though there is no requirement that they be used that way.

It seems, then, with a cache and good branch prediction there
is nothing to be gained by using interrupts to exit the loop.

> And for linear searching, instead of the standard "load memory -
> compare to test register - conditional branch out of loop - compare
> loop counter register - conditional branch out of loop - increment loop
> register - unconditional branch to beginning of loop", the program
> could set an interrupt to be triggered when either the loop counter
> register reaches some value or the test register matches some value,
> thus allowing the actual loop to be simply "load memory - increment
> loop register - unconditional branch to beginning of loop".

Even better, offer special instructions for searching.
It is, then, a microcode loops that should be even better, and
no interrupt is required.

> On an architecture with virtual memory, the interrupt handler address
> could be vectored through the page tables the same way as normal
> process memory, thus allowing processes to install and use their own
> private interrupt handlers without interfering with or having to rely
> on the operating system.

This would require some extra changes to handle interrupts in user
state, but it could make some sense.

(snip)

Consider the IBM mainframe SIE instruction, Start Interpretive
Execution. It is used for virtual machines, somewhat similar to the
virtual86 mode on intel chips. SIE executes instructions as
described in some control block until it needs supervisor help,
such as for a privileged instruction. It then goes to the
instruction following SIE, no interrupt overhead, no context
switch other than that internal to SIE, nothing else.

Instead of interrupt exit for a loop why not an instruction to
enter loop mode specifying where to go when the loop is done,
and then an unconditional loop. A special loop exiting
instruction or condition would then trigger the previously
specified exit. You might even have a way to indicate early
that the loop was about to finish to give the processor time
to start prefetching and decoding outside the loop.

-- glen

From: andrewspencers on
glen herrmannsfeldt wrote:
> Instead of interrupt exit for a loop why not an instruction to
> enter loop mode specifying where to go when the loop is done,
> and then an unconditional loop.
Yes; this is for example the instruction sequence "install usermode
interrupt handler at address y" and "trigger usermode interrupt when
register X is zero" followed by the loop itself. Address y is the
instruction immediately following the loop, and at that address is an
instruction to pop the return address (pushed by the processor when
invoking the interrupt handler) and throw it away, and then the program
continues onward at that point.

> A special loop exiting
> instruction or condition would then trigger the previously
> specified exit.
Well a special condition, yes: for example, when register X is zero.
But a special instruction inside the loop? That's called "comparison
followed by conditional branch", which is exactly what we're trying to
avoid!

My argument is essentially this:
Interrupt-triggered events are better than polling-triggered events,
assuming that the cost of setting up the interrupt is less than the
total cost of all the polling repetitions.
Compare-and-branch inside a loop is a poll of the loop-exiting
condition.
Thus for a high-repetition loop, an interrupt-triggered exit is better
than a compare-and-branch exit.