Whilst pondering our migration to Enterprise COBOL 5.2 I've come upon the
situation that our current compiler option for NUMPROC, the MIG option, is no
longer available. Now we have to decide if we wish to use the more compatible
option NOPFD or the better performing but possibly less compatible option PFD
(preferred!).
The (5.2) manual has the following to say:
NOPFD
Repairs signs on input. After repair is performed, the signs meet the criteria
for NUMPROC=PFD.
PFD
Optimizes the generated code, especially when a non-zero OPTIMIZE level is
specified. No explicit sign repair is performed. Note that NUMPROC=PFD has
stringent criteria to produce correct results. To use NUMPROC=PFD:
* The sign position of unsigned numeric items must be X'F'.
* The sign position of signed numeric items must be either X'C' if positive
or zero, or must be X'D' if negative.
* The sign position of separately signed numeric items must be either '+'
if positive or zero, or '-' if otherwise.
Elementary MOVE and arithmetic statements in Enterprise COBOL always generate
results with these preferred signs; however, group MOVEs and redefinitions
might produce nonconforming results. The numeric class test can be used for
verification. With NUMPROC=PFD, a numeric item fails the numeric class test if
the signs do not meet the preferred sign criteria.
Performance consideration: Using NUMPROC=PFD generates significantly more
efficient code for numeric comparisons. For most references to COMP-3 and
DISPLAY numeric data items, using NUMPROC=NOPFD generates extra code because of
sign "fix-up" processing. This extra code might also inhibit some other types
of optimizations. Before setting this option, consult with your application
programmers to determine the effect on the application program's output.
The COBOL 4.2 manual says this about MIG:
Use NUMPROC(MIG) to aid in migrating OS/VS COBOL programs to Enterprise COBOL.
When NUMPROC(MIG) is in effect, the following processing occurs:
* Preferred signs are created only on the output of MOVE statements and
arithmetic operations.
* No explicit sign repair is done on input.
* Some implicit sign repair might occur during conversion.
* Numeric comparisons are performed by a decimal comparison, not a logical
comparison.
Several questions:
- What is "on input" as described under NOPFD?
- Which allowed behavior of COBOL 5.2 is closer to MIG: NOPFD or PFD?
In order to answer the last question I've written the following program and
tested it with each of the 3 options supported by COBOL 4.2:
identification division.
program-id. numproc2.
data division.
working-storage section.
01 groups usage packed-decimal.
05 grp-1.
10 signed pic s9(3).
05 grp-2.
10 unsigned pic 9(3).
01 display-fields usage display.
05 disp-signed pic 9(3)+.
05 pic x value spaces.
05 disp-unsigned pic 9(3)+.
procedure division.
move -123 to signed
move grp-1 to grp-2
display signed space unsigned
move signed to disp-signed
move unsigned to disp-unsigned
display display-fields
if signed = unsigned
display 'equal'
else
display 'not equal'
end-if
if signed < unsigned
display 'signed lt unsigned'
else
display 'signed nlt unsigned'
end-if
if unsigned is numeric
display 'numeric'
else
display 'not numeric'
end-if
display signed space unsigned
move signed to disp-signed
move unsigned to disp-unsigned
display display-fields
goback.
end program numproc2.
NUMPROC(MIG)12L 12L
123- 123+
equal
signed nlt unsigned
not numeric
12L 12L
123- 123+
NUMPROC(NOPFD)12L 12L
123- 123+
not equal
signed lt unsigned
not numeric
12L 12L
123- 123+
NUMPROC(PFD)
12L 12L
123- 123+
equal
signed nlt unsigned
not numeric
12L 12L
123- 123+
The first thing to realize is that while the NOPFD behavior in a way "seems
more correct", is it really? Essentially this is invalid COBOL program, so I
imagine the COBOL standard doesn't say how it should work. But one simply
should not treat a signed field as an unsigned field, or vice versa, and expect
any particular behavior from it. My great (and perhaps greatly naive) hope is
that we do not have any programs that do anything remotely like this example.
This seems to me to show that PFD behavior is the same (in this case) as MIG,
while NOPFD does sign repair so that the sign is "massaged" so match the COBOL
PICTURE string. See the generated psuedo-assembler for each option:
MIG
000022 IF
0004CA GN=33 EQU *
0004CA 5820 912C L 2,300(0,9) BLW=0
0004CE F911 2000 2002 CP 0(2,2),2(2,2) SIGNED
UNSIGNED
0004D4 58B0 C008 L 11,8(0,12) PBL=1
0004D8 4770 B116 BC 7,278(0,11) GN=5(0004F2)
PFD
000022 IF
0004CA GN=33 EQU *
0004CA 5820 912C L 2,300(0,9) BLW=0
0004CE F911 2000 2002 CP 0(2,2),2(2,2) SIGNED
UNSIGNED
0004D4 58B0 C008 L 11,8(0,12) PBL=1
0004D8 4770 B116 BC 7,278(0,11) GN=5(0004F2)
NOPFD
000022 IF
0004CA GN=33 EQU *
0004CA 5820 912C L 2,300(0,9) BLW=0
0004CE D201 D100 2002 MVC 256(2,13),2(2) TS2=0
UNSIGNED
0004D4 960F D101 OI 257(13),X'0F' TS2=1
0004D8 F911 2000 D100 CP 0(2,2),256(2,13) SIGNED
TS2=0
0004DE 58B0 C008 L 11,8(0,12) PBL=1
0004E2 4770 B120 BC 7,288(0,11) GN=5(0004FC)
NOPFD has two extra instructions. One to move the field to a temporary field,
and another to force the sign to 'F' (unsigned). The compare (CP) is then done
against this "repaired" field.
The NUMERIC check generates the same code for all three options, and in all
cases this check returns false (which is correct because of the sign not
matching the picture).
Anyway, my takeaway from this is that MIG is at least closer to PFD than it is
to NOPFD, so it might be safe to go directly to PFD. But without knowing where
MIG differs from PFD I don't know what else to look for.
Any thoughts?
Thanks,
Frank Swarbrick
Applications Development Architect
Mainframe Applications Development
FirstBank - Lakewood, CO USA
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN