Paul Gilmartin wrote:

On Sat, 12 Sep 2020 07:35:00 -0400, Thomas David Rivers wrote:
ADD UNSIGNED doesn't trigger the FIXED OVERFLOW exception, while
SIGNED operations do.  Since C doesn't want FIXED OVERFLOW exceptions,
(almost) all of the arithmetic calculations should be done with unsigned
arithmetic in case the exception is accidently enabled in the CPU.

But for ( signed __int128 ) would it be proper to use a signed add for
only the most significant part in order to set the overflow condition
properly?

"C" implementations with which I'm familiar all require that fixed
point overflow trapping be disabled by mask.  Do you know of an
exception?

We have had situations where the a) the exception is undesired,
b) the exception was accidently enabled and c) things "blew up"
in an undisirable way.   So, we prefer to generate code that does not
allow for the exception.

I believe the Standard says that in case of an overflow with
signed operands either (I'm not sure which) the result has an
implementation-dependent value or the effect is implementation-
dependent (e.g. it might throw a signal.)  I favor strict checking,
thus signal on fixed point overflow.

The standard says that integer overflow is an undefined
behaviour - which means you cannot make any assumptions
about what happens in that case.   The order doesn't matter.
An implementation is free to provide a definition for the situation,
but a C programmer cannot portably count on any behavior.  Many
C optimizers take advantage of that quality (particular when the
result is then used in pointer arithmetic) to make several desirable
optimizations.

Undefined behavior is different than implementation-defined in the
C standard; it's a subtle but important difference.

(The C99 standard actually cites this very issue as an example
of "undefined behavior".)

So - it _is_ "legal" for an integer overflow to cause any behavior
at all - which would include some kind of "event" (like a FIXED OVERFLOW
EXCEPTION) that may or may-not be turned into a signal, or it could
blow-up the machine.   But, the programmer should not depend on
any particular result when the standard says "undefined behavior".

Having said all that, it is "customary" for C implementations to not
cause any kind of exception/signal/interrupt for integer overflow.
Such an event would be a violation of what we (here) call POLA,
"Principle Of Least Astonishment".    That is, we try to make things happen
the way that would be the least astonishing for a typical C/C++
programmer... albeit it might be astonishing to a mainframe programmer.
I suppose it's a matter of perspective.

I'll also note that the recent IBM implemetation went that way for PL/I,
although I don't know if the code the compiler generates prefers
non-exception instructions or simply assumes the FIXED POINT OVERFLOW
exception is not enabled...


For multi-precision subtract, the subtrahend must be complemented
and the least significant parts added with the CC carry forced ON
previously.  What's the best way to do that?  SPM?

Here is the code for 128-bit signed/unsigned integer
subtraction (where 'a' and 'b' are incoming parameters) and
we take advantage of the more recent z/Arch instructions:

* ***      return a - b;
        LMG   2,3,4(1)
        L     15,0(0,1)
        SLG   3,28(0,1)
        SLBG  2,20(0,1)
        STMG  2,3,96(13)
        MVC   0(16,15),96(13)

In the 32-bit situation, using only 370 instructions, the sequences
break-down into several 64-bit subtractions, which further break
down into 32-bit subtrations, so you get this kind of code (note
the BC's which branch around an extra subtactions of 1).
* *
        L     15,0(0,1)
* ***      return a - b;
        LM    2,5,4(1)
        SL    5,32(0,1)
        BC  3,@@gen_label0
        SL    4,@lit_147_0
        BC  3,@@gen_label0
        SL    3,@lit_147_0
        BC  3,@@gen_label0
        SL    2,@lit_147_0
@@gen_label0 DS 0H
        SL    4,28(0,1)
        BC  3,@@gen_label1
        SL    3,@lit_147_0
        BC  3,@@gen_label1
        SL    2,@lit_147_0
@@gen_label1 DS 0H
        SL    3,24(0,1)
        BC  3,@@gen_label2
        SL    2,@lit_147_0
@@gen_label2 DS 0H
        SL    2,20(0,1)
        STM   2,5,95(13)
        MVC   0(16,15),95(13)
...
@lit_147_0 DC  F'1' 0x00000001


No SPM is needed, just do the operation in a different order.



   - Dave R -


--
[email protected]                        Work: (919) 676-0847
Get your mainframe programming tools at http://www.dignus.com

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN

Reply via email to