Re: Unexpected C code
The behavior of LCR, LNR and LPR have not changed since the introduction of the S/360. Here are some quotes from GA22-6821 "IBM System/360 Principles of Operation:" For LCR: "An overflow condition occurs when the maximum negative number is complemented; the number remains unchanged." For LNR: "The operation complements positive numbers; negative numbers remain unchanged. The number zero remains unchanged." For LPR: "An overflow condition occurs when the maximum negative number is complemented; the number remains unchanged." The description of the behavior of these instructions as found in SA22-7832 "z/Architecture Principles of Operation" when the operands are both the same size (both are 32-bits or both are 64-bits) matches the S/360 behavior. For LCGFR and LPGFR the first operand is 64-bits and the second operand is 32-bits. These instructions process the maximum 32-bit negative number without recognizing an overflow, i.e., the maximum negative 32-bit number can be complemented and represented correctly as a 64-bit result.
Re: Unexpected C code
- Original Message - From: "Paul Gilmartin" <0014e0e4a59b-dmarc-requ...@listserv.uga.edu> To: Sent: Wednesday, April 27, 2022 10:53 AM Subject: Re: Unexpected C code On Apr 26, 2022, at 17:30:26, Peter Relson wrote: Apologies if this was mentioned, since I am only now getting around to reading some of this thread: Bernd wrote (and others had similar) LPR: if the register contains 0x8000, IMO the result will be zero RTM. The value is unchanged. (and overflow), so you're right ... this will lead to a zero result. No, the value is unchanged. IMO, the overflow > will be ignored. RTM. Somewhat later in this thread, Thomas David Rivers averred that LPR Of 0x8000 results in 0x8000. That's almost correct. The value is unchanged. The puzzling sequence of instructions was LPR; LCR; SLR 31 to set a char variable on a nonzero operand. This works correctly (and I'll trust the C compliers) only if both LPR and LCR result in 0x8000, or at least some nonzero result. RTM. The value is unchanged. --- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus
Re: Unexpected C code
From: "Peter Relson" Sent: Wednesday, April 27, 2022 9:30 AM Apologies if this was mentioned, since I am only now getting around to reading some of this thread: Bernd wrote (and others had similar) LPR: if the register contains 0x8000, IMO the result will be zero (and overflow), so you're right ... this will lead to a zero result. IMO, the overflow will be ignored. If the mask bit is zero, there will be no interrupt. The overflow CC will be zset. If the mask bit is 1, an overflow interrupt will occur. The question is about "will be ignored". Do you know that it will truly be ignored? See above. If the mask bit is 1, the interrupt will occur. Can you be certain that the program mask bit is not on which, if on, would cause the overflow to program-check? If running under LE with ESPIE protection, might that program mask be on? z/OS itself cannot make such an assumption in many paths (in an SVC path, it might be able to because the SVC new PSW has 0's for the program mask; in a PC path, it cannot because the PC instruction does not change the program mask so the routine would have to do so). Thus this nice trick to avoid compares and branches is not, in general, usable within the OS. --- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus
Re: Unexpected C code
My assumption is that these instructions are, or at least were, implemented in hardware gates, so these "boundary conditions" are likely to be mechanistic in nature rather then implemented via "if it's a funny number then do this different thing" programming. We sat down the other day and confirmed, to our own minds at least, that that's the case for LCR. Ian On 27 Apr 2022, 15:08, at 15:08, Martin Ward wrote: >On 27/04/2022 01:53, Paul Gilmartin wrote: >> This works correctly (and I'll >> trust the C compliers) only if both LPR and LCR result in 0x8000, >> or at least some nonzero result. > >If you want to define "LPR" as "make the result a positive number >with the same absolute value as the original", then there is no >defined result for LPR on 0x8000 because the positive value >has no representation in 32 bit two's complement. > >LPR can more reasonably be defined as "if the value is already >positive, >do nothing, otherwise take the complement". > >LCR is defined as "flip all the bits and add one, ignoring overflow". >With this definition, LCR of 0x8000 is indeed 0x8000. > >John von Neumann suggested use of two's complement binary >representation >in his 1945 "First Draft of a Report on the EDVAC proposal for an >electronic stored-program digital computer". > >Mathematically, two's complement can be defined by two rules: > >(1) Arithmetic operations for signed values are the same >as for unsigned values. So -1 is represented as 0x >since adding one to this value using unsigned arithmetic >gives the result of 0x (-1 can be defined as >"the number which gives a result of zero when you add 1 to it"). > >(2) All numbers with the top bit set are negative, >and the rest are positive or zero. >This rule defines the boundary between negative and positive >numbers, and means that 0x8000 is negative and is the >lowest negative number (since if you subtract one from it, >the top bit flips and you get 0x7FFF which is therefore >the largest positive number). > >So this explains why both LPR and LCR of 0x8000 >result in 0x8000. > >-- > Martin > >Dr Martin Ward | Email: mar...@gkc.org.uk | http://www.gkc.org.uk >G.K.Chesterton site: http://www.gkc.org.uk/gkc | Erdos number: 4
Re: Unexpected C code
Gil wrote: Somewhat later in this thread, Thomas David Rivers averred that LPR Of 0x8000 results in 0x8000. The puzzling sequence of instructions was LPR; LCR; SLR 31 to set a char variable on a nonzero operand. This works correctly (and I'll trust the C compliers) only if both LPR and LCR result in 0x8000, or at least some nonzero result. It is true that LPR of 0x8000 does result in 0x8000. As does LCR of 0x8000. If I have this right: Overflow processing for these instructions depends on the "fixed point overflow" bit in the PSW program mask. The "only if" is true only when the program mask does not have that bit on.. It is false if the program mask does have the bit on because the overflow results in a program interrupt. If a program interrupt were to occur, only if there were appropriate recovery in place that accepted this and retried silently to the next instruction could we consider that the program continues as expected. Peter Relson z/OS Core Technology Design
Re: Unexpected C code
On 27/04/2022 01:53, Paul Gilmartin wrote: This works correctly (and I'll trust the C compliers) only if both LPR and LCR result in 0x8000, or at least some nonzero result. If you want to define "LPR" as "make the result a positive number with the same absolute value as the original", then there is no defined result for LPR on 0x8000 because the positive value has no representation in 32 bit two's complement. LPR can more reasonably be defined as "if the value is already positive, do nothing, otherwise take the complement". LCR is defined as "flip all the bits and add one, ignoring overflow". With this definition, LCR of 0x8000 is indeed 0x8000. John von Neumann suggested use of two's complement binary representation in his 1945 "First Draft of a Report on the EDVAC proposal for an electronic stored-program digital computer". Mathematically, two's complement can be defined by two rules: (1) Arithmetic operations for signed values are the same as for unsigned values. So -1 is represented as 0x since adding one to this value using unsigned arithmetic gives the result of 0x (-1 can be defined as "the number which gives a result of zero when you add 1 to it"). (2) All numbers with the top bit set are negative, and the rest are positive or zero. This rule defines the boundary between negative and positive numbers, and means that 0x8000 is negative and is the lowest negative number (since if you subtract one from it, the top bit flips and you get 0x7FFF which is therefore the largest positive number). So this explains why both LPR and LCR of 0x8000 result in 0x8000. -- Martin Dr Martin Ward | Email: mar...@gkc.org.uk | http://www.gkc.org.uk G.K.Chesterton site: http://www.gkc.org.uk/gkc | Erdos number: 4