Just commenting on one thing: > It is again there for the case of an overflow which has resulted in a > negative zero > but I can't think why it is not preceded by a branch on condition for the > overflow > value in the Condition Code.
Do I interpret what you are saying as "I get the need for the ZAP, but couldn't they have saved the ZAP if no overflow by branching around it if no overflow?" If so, I think the answer is because branches are expensive in the brave new world of caches and so forth. It's probably generally cheaper to do the zap -- seeing as how you already have the data in write cache -- than to screw up the pipeline with a branch. Just my slightly informed guess. Charles -----Original Message----- From: IBM Mainframe Discussion List [mailto:IBM-MAIN@LISTSERV.UA.EDU] On Behalf Of Bill Woodger Sent: Saturday, February 06, 2016 5:30 PM To: IBM-MAIN@LISTSERV.UA.EDU Subject: COBOL Code Gened for MOVE COMP-3 S9(9) to S9(8) Posting this to replace a post I made, by accident only in the google-something part of the list. Some editing, and additional examples. MOVE PICS9-9 TO PICS9-8 D204 3010 3028 MVC 16(5,3),40(3) PICS9-8 PICS9-9 940F 3010 NI 16(3),X'0F' PICS9-8 F844 3010 3010 ZAP 16(5,3),16(5,3) PICS9-8 PICS9-8 MOVE PICS9-11 TO PICS9-9 F844 3028 3019 ZAP 40(5,3),25(5,3) PICS9-9 PICS9-11+1 MOVE PICS9-9-2 TO PICS9-9 D204 3028 3030 MVC 40(5,3),48(3) PICS9-9 PICS9-9-2 MOVE PICS9-8-2 TO PICS9-8 D204 3010 3020 MVC 16(5,3),32(3) PICS9-8 PICS9-8-2 Firstly, it is an Enterprise COBOL thing. From the "Enterprise COBOL for z/OS, Version 3.4, Compiler and Runtime Migration Guide" (that's the first one that came up, I'd suspect it is repeated in other Migration Guide): "For example, Enterprise COBOL will not generate a negative zero result, while OS/VS COBOL could" It pre-dates Enterprise COBOL, and is introduced in VS COBOL II, due to NUMPROC. Prior to COBOL II, all references to packed-decimal data involved decimal instructions. With COBOL II, plain MVC and CLC area weapons of choice, where possible/meaningful, over ZAP and CLC. The decimal compare, CP, treats postive and negative zero as equal (treats them as zero). CLC does not (as it doesn't know they are packed-decimal). The "no negative zero" does not seem to be documented in anything to do with COBOL II that I can find, and from the standard documentation set for COBOL only appears in the Migration guides. Enterprise COBOL has to ensure that a negative zero can never be a result of a statement. There is no action in Enterprise COBOL that can result in a negative zero (except see the list at the bottom). >From the POP for any decimal instruction which can cause an overflow: "In the absence of overflow, the sign of a zero result is made positive. If overflow occurs, a zero result is given the sign of the second operand but with the preferred sign code." A decimal instruction can't, except for overflow, produce a negative zero. COBOL doesn't mind overflow. It is part of the language that a larger field going to a smaller field is simply truncated. Prior to COBOL II, with decimal instructions for packed-decimal fields, where unproblematic overflow occured which happened to create a negative zero, it didn't matter since a negative zero in a decimal instruction is just zero anyway. Now the actual generated code. Defining one field with 11 digits, two with nine and two with eight: 1. MOVE PICS9-9 TO PICS9-8 D204 3010 3028 MVC 16(5,3),40(3) PICS9-8 PICS9-9 940F 3010 NI 16(3),X'0F' PICS9-8 F844 3010 3010 ZAP 16(5,3),16(5,3) PICS9-8 PICS9-8 2. MOVE PICS9-11 TO PICS9-9 F844 3028 3019 ZAP 40(5,3),25(5,3) PICS9-9 PICS9-11+1 3. MOVE PICS9-9-2 TO PICS9-9 D204 3028 3030 MVC 40(5,3),48(3) PICS9-9 PICS9-9-2 4. MOVE PICS9-8-2 TO PICS9-8 D204 3010 3020 MVC 16(5,3),32(3) PICS9-8 PICS9-8-2 In 2, a longer field is the source, and ZAP is used, and if the trunction of the longer field happened to logically yield a negative zero, the ZAP would present the result as a positive zero. If an MVC had been used, offset by one byte, a ZAP-to-itself would have been needed to ensure the positive zero if that had resulted in a negative zero. So cut to the chase, and just ZAP. In 3, with two fields of the same size and an odd number of digits, an MVC is possible and a ZAP not needed because there can be no truncation resulting in a potential negative zero. There is a presumption that the source field is valid (not negative zero already). 4 is similar to 3, just with an even number of digits. There is the same presumption as in 3, and a further presumption that the leading nybble can only be zero. Now number 1, the original code in the question: The MVC does nothing with packed-decimal signs, it is just copying a lump of data. The NI is indeed effecting truncation (nothing to do with compiler option TRUNC in Enterprise COBOL, although a compiler option of the same name, many years ago, was involved in that). Source is a nine-digit-in-five-bytes. The code shown will ensure that the 8-digit-in-five-bytes receiving field will have a zero in the high-order nybble. What about the ZAP? It is due to the potential for a negative-zero in the data in the source field, which Enterprise COBOL must prevent from infecting the result. If the source field was -900000000, then the MVC followed by the NI would yield negative zero. So follow the MVC/NI with a ZAP. You can't just ZAP then NI, because the potential -900000000 would become the forbidden negative zero. The ZAP after a decimal add, subtract, multiply or divide is interesting. It is again there for the case of an overflow which has resulted in a negative zero but I can't think why it is not preceded by a branch on condition for the overflow value in the Condition Code. Other points raised in the discussion: Non-preferred signs going into ZAP (or any decimal instruction) will come out as preferred signs (C or D). Looking at other code generated with NUMPROC(NOPFD) may well show a number of ZAPs-to-itself to rectify the sign for comparisons, for instance. If the source has an invalid sign (0-9) a S0C7 will ensue. If the source has a non-preferred sign, a preferred sign, equivalent, of course, will be produced. If the source is a negative zero, a positive zero will be produced, allowing a CLC to be used, accurately, for comparisons for equality for packed-decimal fields. The code generated, in isolation at least, is not affected by compiler option OPT, because it is an Enterprise COBOL thing. If it were not done, you get the chance of a negative zero. There is absolutely no difference in the procedure code generated by OPT(STD) and OPT(FULL). The only "extra" in OPT(FULL) is the identification and removal from the object of unreferenced storage items. If there are unused fields in WORKING-STORAGE or LOCAL-STORAGE, the object will be smaller. With Enterprise COBOL V5, which has three levels of optimsation (0, 1 and 2, and yes, even 0 does some optimisations, clever, eh?) the FULL part of OPT up to V4 is replaced by a new option, STGOPT. Given all the above, what is the potential for any field containing a negative zero? Date external to the program (file, DB, LINKAGE SECTION, message, whatever), careless use of REDEFINES, careless use of group MOVEs. So something to be aware of. ---------------------------------------------------------------------- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN