Well, it's rather quiet around here...

A common storage format for elements in database rows and the like is a
fixed-length length field, followed by the data. Often there is an overall
length at the start, followed by repeated length/value pairs, and of course
there are other variations, including variable-length length fields. For
example, RACF returns data with repeated {4-byte unaligned length, data}
fields. In this case the data type is not encoded inline, but has to be
known by reference to an external database template.

So in the case of character data, it's very easy to use either MVCL or an
executed MVC to extract the length, perhaps store it locally, copy the
data, and increment the pointer in the row to the next length field. I like
MVCL for this despite its perhaps worse performance, because it's elegant;
everything is updated and ready to go for the next field by the MVCL
itself.

In the case of integer data, in RACF's case the length can be 0, 1, 2, 3,
or 4, depending on the actual data value. In most cases one wants to store
this locally in a fullword, suitably zero extended on the left, rather than
in a variable length field. It seems to me the logical instruction to use
is ICM, varying the mask based on the length field. But what's a method
that is the right balance between easy to read and understand at a glance,
and efficient in instruction count, required setup, and even execution
time? I've usually used an executed ICM with a literal table to translate
length to mask - something like:

         L     R15,0(,Rn)                 Get length (Rn -> current length
field)
         SR    R1,R1                      Prepare for ICM/default value
         IC    R15,=X'000103070F'(R15)    Map length to mask
Do_ICM   ICM   R1,*-*,4(R14)              This can/should be out of line
instead
         EX    R15,Do_ICM
         ST    R1,Local_integer
         LA    Rn,4(Rlen,Rn)              -> next length field

and of course this can be repeated or looped. Perhaps it looks nicer as
=AL1(0,1,3,7,15), or even =B('0000','0001','0011','0111','1111).

The challenges:

1) Improve on this snippet (elegance, efficiency, readability) for the case
above where the integers are always unsigned and 0-4 bytes. It doesn't have
to use ICM.

2) Mark a missing (0-length) integer as different from one with a *value *of
0. Possibly set it to -1.

3) Make it work for signed (2's complement) integers of the above lengths
so the result is a 2's complement fullword.

4) Extend it to work for length up to 8 bytes, storing the result in a
doubleword. (Hmmm... no ICMG instruction.)

Have fun...

Tony H.

Reply via email to