Shouldn't that be: =B('0000','1000','1100','1110','1111') ?
Excluding the zero length handling, I've already come across the
requirement to load 1-8 byte sign or unsigned integers.
I wrote a macro to do it, it does some extra stuff but in it's simplest
form, generates:

*        R06 = address of source, R02 = length of source
         TM    FLAG,SIGNED        Q. Signed numeric?
         JO    @0076GA            Y. Use first half of jump table
         AGHI  R02,8              Unsigned uses second half of table
@0076GA  DS    0H
         AGHI  R02,-1             Make length zero relative
         SLL   R02,2              Times 4 for jump table offset
         LLGT  R02,@0076GB(R02)   Jump target for field length
         BR    R02                Branch to appropriate LOAD code
@0076GB  DC    0A
         DC    A(@0076S1)         Signed, length 1
         DC    A(@0076S2)         Signed, halfword
         DC    A(@0076S3)         Signed, length 3
         DC    A(@0076S4)         Signed, fullword
         DC    A(@0076S5)         Signed, length 5
         DC    A(@0076S6)         Signed, length 6
         DC    A(@0076S7)         Signed, length 7
         DC    A(@0076U8)         Signed, doubleword (same as unsigned)
         DC    A(@0076U1)         Unsigned, length 1
         DC    A(@0076U2)         Unsigned, halfword
         DC    A(@0076U3)         Unsigned, length 3
         DC    A(@0076U4)         Unsigned, fullword
         DC    A(@0076U5)         Unsigned, length 5
         DC    A(@0076U6)         Unsigned, length 6
         DC    A(@0076U7)         Unsigned, length 7
         DC    A(@0076U8)         Unsigned, doubleword
@0076S1  DS    0H                 Length 1
         LGB   R00,0(,R06)        Load byte, with sign extension
         J     @0076GC
@0076S2  DS    0H                 Length 2 (halfword)
         LGH   R00,0(,R06)        Load halfword, with sign extension
         J     @0076GC
@0076S3  DS    0H                 Length 3
         ICMH  R00,B'1110',0(R06) Insert 3 bytes into top of high word
         SRAG  R00,R00,40         Shift down to low order 3 bytes
         J     @0076GC
@0076S4  DS    0H                 Length 4 (fullword)
         LGF   R00,0(,R06)        Load fullword, with sign extension
         J     @0076GC
@0076S5  DS    0H                 Length 5
         LBH   R00,0(,R06)        Load first byte into high word
         L     R00,1(,R06)        Load remaining fullword into low word
         J     @0076GC
@0076S6  DS    0H                 Length 6
         LHH   R00,0(,R06)        Load first halfword into high word
         L     R00,2(,R06)        Load remaining fullword into low word
         J     @0076GC
@0076S7  DS    0H                 Length 7
         ICMH  R00,B'1110',0(R06) Insert first 3 bytes into high word
         SRAG  R00,R00,8          Shift down to bottom of word
         L     R00,3(,R06)        Load remaining fullword into low word
         J     @0076GC
@0076U1  DS    0H                 Length 1
         LLGC  R00,0(,R06)        Load byte into low-order byte
         J     @0076GC
@0076U2  DS    0H                 Length 2 (halfword)
         LLGH  R00,0(,R06)        Load logical halfword
         J     @0076GC
@0076U3  DS    0H                 Length 3
         SLGR  R00,R00            Zero 8 bytes of LOAD register
         ICM   R00,B'0111',0(R06) Load 3-bytes
         J     @0076GC
@0076U4  DS    0H                 Length 4 (fullword)
         LLGF  R00,0(,R06)        Load fullword
         J     @0076GC
@0076U5  DS    0H                 Length 5
         LLCH  R00,0(,R06)        Load 1st byte into high word
         L     R00,1(,R06)        Load remaining fullword into low word
         J     @0076GC
@0076U6  DS    0H                 Length 6
         LLHH  R00,0(,R06)        Load first halfword into high word
         L     R00,2(,R06)        Load remaining fullword into low word
         J     @0076GC
@0076U7  DS    0H                 Length 7
         NIHH  R00,X'00FF'        Zero top byte of LOAD register
         ICMH  R00,B'0111',0(R06) Insert first 3 bytes into high word
         L     R00,3(,R06)        Load remaining fullword into low word
         J     @0076GC
@0076U8  DS    0H                 Length 8 (doubleword)
         LG    R00,0(,R06)        Load all 8 bytes into register
@0076GC  DS    0H

Robert Ngan
CSC financial Services Group

IBM Mainframe Assembler List <[email protected]> wrote on
2015/06/16 17:54:44:

> From: Tony Harminc <[email protected]>
> To: [email protected]
> Date: 2015/06/16 17:56
> Subject: Elegant code to extract length+data fields? A small challenge.
> Sent by: IBM Mainframe Assembler List <[email protected]>
>
> 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