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
