X'7A120000' is 1 million * 4096 / 2.

There are 0x1000 TOD units in a microsecond; 1 million * 0x1000 in a second.
So if you use 64 bit arithmetic, there is nothing wrong with:

stck -= TOD_EPOC_OFFSET;   // 1900 to 1970 offset: 0x7D91048BCA000000L
long epoc_secs = stck / SECS_PER_TOD_UNIT;    // 0x1000 * 1000000;

or in assembler I think it would be:

    LG      R3,STCK
    SG     R3,TOD_EPOC_OFF             XL8'7D91048BCA000000'
    DSG   R2,SECS_PER_TOD_UNIT  FD'4096000000'
    STG   R3,EPOC_SECS


Kirk Wolf
Dovetailed Technologies
http://dovetail.com

On Thu, Jul 20, 2017 at 3:10 PM, Tony Harminc <[email protected]> wrote:

> On 20 July 2017 at 13:11, Kirk Wolf <[email protected]> wrote:
>
> > I'm actually writing this in Java (to 64-bit java "long" epoch seconds,
> > from both STCK and STCKE inputs), but the sample IBM assembler code
> > initially puzzled me.
>
> I must admit I remain confused by both the sample code and its comments.
> The the notion of "seconds per tod unit" is an odd one. This is a very
> small number (about 0.000000000244140625), and it makes little sense to be
> dividing anything by it. And certainly the constant EPOCST DC X'7A120000'
> isn't it.
>
> This is code I wrote in 1999 to do this. I must also admit I had not
> considered that the Unix representation was signed, and so it doubtless
> produces incorrect output for input dates between 2038 and 2042. But of
> course any code does so by definition, so it's a matter of which failure
> mode you prefer.
>
> I like to think this is easy to read and understand. I think of the
> algorithm this way:
>
> Convert the TOD value into microseconds since Jan 1 1900. Why? Because it's
> trivial and fast, it well fits the architected definition of the TOD clock
> (bit 51 - 1 uS), and it guarantees that this intermediate value does not
> have its high bit on.
>
> Subtract the (constant) difference in microseconds between Jan 1 1900 and
> Jan 1 1970. I hand calculated this by thinking (70 years * 365 days/year =
> 25550 days, + (70/4)-1 [-1 because 1900 was not a leap year] = 16 leap days
> ) = 25566 days ) * 1440 min/day *60 seconds/minute = 2208902400 seconds *
> 1000000 = 2208902400000000 microseconds. I hope I was right...
>
> So here's my old code:
>          STCK  WORK_DWORD
>          LM    R14,R15,WORK_DWORD  TOD CLOCK UNITS
>          SRDL  R14,12            MICROSECONDS SINCE JAN 1, 1900
>          SL    R15,=FL8'2208902400000000'+4 - RIGHT HALF
>          BC    11,*+6            BRANCH ON NO BORROW
>          BCTR  R14,R0             -1 FOR BORROW
>          SL    R14,=FL8'2208902400000000' - LEFT HALF
>          D     R14,=F'1000000'    SECONDS SINCE JAN 1, 1970
>
> As others have pointed out, using the 32-bit registers and checking for
> borrow would be strange for code written in 2017, but of course it still
> works. Using a G register with the appropriate G Load, Shift, and Subtract
> would eliminate 3 instructions.
>
> > - good assembler programmer
> > - XLC/C++ compiler
> > - IBM sample code in a manual
> > - bad assembler programmer
>
> Heh - a colleague is writing his first ever, very simple, TSO command. The
> "IBM sample code in a manual" has meant it's taken him about a week more
> than it should've.
>
> Tony H.
>
> ----------------------------------------------------------------------
> For IBM-MAIN subscribe / signoff / archive access instructions,
> send email to [email protected] with the message: INFO IBM-MAIN
>

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN

Reply via email to