Right Charles.   SECS_PER_TOD_UNIT is an bad (inverted) name.

Kirk Wolf
Dovetailed Technologies
http://dovetail.com

On Thu, Jul 20, 2017 at 3:53 PM, Kirk Wolf <[email protected]> wrote:

> 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 <(409)%20600-0000>'
>     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
>> <(220)%20890-2400> 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