Opened 2 years ago

#335 new defect

PL/I addbitno builtin function generates incorrect code

Reported by: Gary Dixon Owned by: Eric Swenson
Priority: major Milestone:
Component: Standard Library Version: MR12.8
Keywords: Cc:

Description

Code generated by the addbitno function fails to load the pointer to be adjusted before adding a bit offset.
The assembler listing for a statement using addbitno is shown below.

          else P_arg_info.address = addbitno ( P_arg_info.address,
                                               P_arg_info.array_extent.element_offset *
                                                (P_arg_info.element.selected - P_arg_info.array_extent.lbound) );

007737  aa  3 00104 3521 20   epp2      pr3|68,*            P_arg_info.address
007740  aa  3 00114 3361 00   lcq       pr3|76              P_arg_info.selected
007741  aa   000044 7770 00   llr       36
007742  aa   000044 7330 00   lrs       36
007743  aa  3 00107 0331 00   adl       pr3|71              P_arg_info.lbound
007744  aa   000000 5330 00   negl      0
007745  aa  6 00100 7571 00   staq      pr6|64
007746  aa  3 00111 2361 00   ldq       pr3|73              P_arg_info.element_offset
007747  aa  6 00100 3521 00   epp2      pr6|64
007750  aa  0 00671 7001 00   tsx0      pr0|441             mpfx2
007751  aa  2 00000 5035 06   abd       pr2|0,ql
007752  aa  3 00104 2521 00   spri2     pr3|68              P_arg_info.address

Notice that pr2 gets loaded by the first instruction, but later gets reused by the multiply operation in the second argument to the addbitno function. It never gets reloaded, so an address associated with the multiple gets stored into the P_arg_info.address value.

An avoidance for this problem is shown below. The avoidance moves calculation of the bit offset into a separate statement stored in a new variable. This variable is then used as the bit offset addition in the addbitno builtin.

     2121   dcl  bit_offset             fixed bin(24);
      ...
          else do;

                                                            STATEMENT 1 ON LINE 2145
               bit_offset =  P_arg_info.array_extent.element_offset *
                            (P_arg_info.element.selected - P_arg_info.array_extent.lbound);

007737  aa  3 00114 3361 00   lcq       pr3|76              P_arg_info.selected
007740  aa   000044 7770 00   llr       36
007741  aa   000044 7330 00   lrs       36
007742  aa  3 00107 0331 00   adl       pr3|71              P_arg_info.lbound
007743  aa   000000 5330 00   negl      0
007744  aa  6 00102 7571 00   staq      pr6|66
007745  aa  3 00111 2361 00   ldq       pr3|73              P_arg_info.element_offset
007746  aa  6 00102 3521 00   epp2      pr6|66
007747  aa  0 00671 7001 00   tsx0      pr0|441             mpfx2
007750  aa  6 00100 7561 00   stq       pr6|64              bit_offset
                                                            STATEMENT 1 ON LINE 2147
               P_arg_info.address = addbitno ( P_arg_info.address, bit_offset );

007751  aa  3 00104 3521 20   epp2      pr3|68,*            P_arg_info.address
007752  aa  2 00000 5035 06   abd       pr2|0,ql
007753  aa  3 00104 2521 00   spri2     pr3|68              P_arg_info.address
                                                            STATEMENT 1 ON LINE 2148
               end;

Change History (0)

Note: See TracTickets for help on using tickets.