One more question along the lines of the FIXEDBIN limits option.
If I'm understanding things correctly - a LIMITS(FIXEDBIN(63,63)) option indicates that the compiler's intermediate values can be 63-bits and the maximum declared precision is 63 bits.
If I have this example code:
test:proc options(main);
dcl left fixed bin(31);
dcl right fixed bin(31);
dcl res fixed bin(31);
left = 5;
right = 6;
res = (left+right)*2;
display('res is ' || res);
end;
compiled with LIMITS(FIXEDBIN(63,63)) (in a 31-bit environment) - it produces this assembly:
000011 | * res = (left+right)*2;
000068 5800 D0B0 000011 | L r0,LEFT(,r13,176)
00006C 1E01 000011 | ALR r0,r1
00006E 8900 0001 000011 | SLL r0,1
000072 5000 D0B8 000011 | ST r0,RES(,r13,184)
It seems to be exactly the same code as compiled with the default setting of LIMITS(FIXEDBIN(31,63)).
With LIMITS(FIXEDBIN(63,63)) - I would have expected the addition to produce a temporary with precision (32,0) (since the size can be more than 32.)
I would then expect the multiplication to produce a result with precision (38,0) (following the rules for FIXED BIN(32,0) * FIXED BIN(1,0).)
So.. I thought there would be 64-bit arithmetic to evaluate this... but - it's all done in 32-bit instructions.
Am I missing something here?
The reason I ask is that if I do a 64-bit compilation (using the LP(64) option) with LIMITS(FIXEDBIN(63)), I see this code:
000011 | * res = (left+right)*2;
00001E E300 48C0 0014 000011 | LGF r0,LEFT(,r4,2240)
000024 E360 48C4 0014 000011 | LGF r6,RIGHT(,r4,2244)
00002A B90A 0006 000011 | ALGR r0,r6
00002E EB00 0001 000D 000011 | SLLG r0,r0,1
000034 B914 0000 000011 | LGFR r0,r0
000038 5000 48C8 000011 | ST r0,RES(,r4,2248)
where it is clear the compiler is evaluating the intermediate results as 64-bit values. To really add to this story, if I _don't_ use the LIMITS(FIXEDBIN(63)) option, I see this code for an LP(64) compilation:
000011 | * res = (left+right)*2;
00001E E300 48C0 0014 000011 | LGF r0,LEFT(,r4,2240)
000024 E360 48C4 0014 000011 | LGF r6,RIGHT(,r4,2244)
00002A B90A 0006 000011 | ALGR r0,r6
00002E EB00 0001 000D 000011 | SLLG r0,r0,1
000034 5000 48C8 000011 | ST r0,RES(,r4,2248)
(note the missing LGFR instruction in the FIXEDBIN(31) situation.)
This seems to suggest that for LP(64), FIXEDBIN(63) does cause the compiler to use 64-bit intermediate values and FIXEDBIN(31) causes the compiler to use 31-bit intermediate values.
But - the same doesn't appear to be true for a 31-bit (non-LP(64)) compilation.
Is there some other (undocumented?) restriction to compiler temporaries when compiling in 32-bit mode with LIMITS(FIXEDBIN(63)) - is LIMITS(FIXEDBIN(63)) only supported in a 64-bit compilation perhaps? Or.. is something else going on here?
- Thanks! -
- Dave
tdr