FreeBSD/contrib/ntp/libntp/ntp_calendar.c
/*
 *---------------------------------------------------------------------
 * Split a 64bit seconds value into elapsed days in 'res.hi' and
 * elapsed seconds since midnight in 'res.lo' using explicit floor
 * division. This function happily accepts negative time values as
 * timestamps before the respective epoch start.
 *---------------------------------------------------------------------
 */
Split a 64bit seconds value into elapsed days in 'res.hi' and
elapsed seconds since midnight in 'res.lo' using explicit floor
division. This function happily accepts negative time values as
timestamps before the respective epoch start.
Split a 64bit seconds value into elapsed days in ' res . hi ' and elapsed seconds since midnight in ' res . lo ' using explicit floor division . This function happily accepts negative time values as timestamps before the respective epoch start .
ntpcal_split
ntpcal_daysplit(
	const vint64 *ts
	)
{
	ntpcal_split res;
	uint32_t Q;
#   if defined(HAVE_INT64)
	if (ts->q_s < 0)
		Q = ~(uint32_t)(~ts->Q_s / SECSPERDAY);
	else
		Q = (uint32_t)(ts->Q_s / SECSPERDAY);
#   else
	uint32_t ah, al, sflag, A;
	sflag = int32_sflag(ts->d_s.hi);
	ah = sflag ^ ts->D_s.hi;
	al = sflag ^ ts->D_s.lo;
	A = ah >> 19;
	if (A >= 675)
		A = (A % 675u);
	A = (A << 19) | (ah & 0x0007FFFFu);
	A = (A <<  3) | (al >> 29);
	Q = A / 675u;
	A = A % 675u;
	A = (A << 22) | ((al >> 7) & 0x003FFFFFu);
	Q = (Q << 22) | (A / 675u);
	Q ^= sflag;
#   endif
	res.hi = uint32_2cpl_to_int32(Q);
	res.lo = ts->D_s.lo - Q * SECSPERDAY;
	return res;
}
ntpcal_split ntpcal_daysplit ( const vint64 * ts ) { ntpcal_split res ; uint32_t Q ; #   if defined ( HAVE_INT64 ) if ( ts -> q_s < 0 ) Q = ~ ( uint32_t ) ( ~ ts -> Q_s / SECSPERDAY ) ; else Q = ( uint32_t ) ( ts -> Q_s / SECSPERDAY ) ; #   else uint32_t ah , al , sflag , A ; sflag = int32_sflag ( ts -> d_s . hi ) ; ah = sflag ^ ts -> D_s . hi ; al = sflag ^ ts -> D_s . lo ; A = ah >> 19 ; if ( A >= 675 ) A = ( A % 675u ) ; A = ( A << 19 ) | ( ah & 0x0007FFFFu ) ; A = ( A << 3 ) | ( al >> 29 ) ; Q = A / 675u ; A = A % 675u ; A = ( A << 22 ) | ( ( al >> 7 ) & 0x003FFFFFu ) ; Q = ( Q << 22 ) | ( A / 675u ) ; Q ^= sflag ; #   endif res . hi = uint32_2cpl_to_int32 ( Q ) ; res . lo = ts -> D_s . lo - Q * SECSPERDAY ; return res ; }
Split a 64bit seconds value into elapsed days in 'res.hi' and
 elapsed seconds since midnight in 'res.lo' using explicit floor
 division.
Split a 64bit seconds value into elapsed days in ' res . hi ' and elapsed seconds since midnight in ' res . lo ' using explicit floor division .
/* Manual floor division by SECSPERDAY. This uses the one's
	 * complement trick, too, but without an extra flag value: The
	 * flag would be 64bit, and that's a bit of overkill on a 32bit
	 * target that has to use a register pair for a 64bit number.
	 */ /* get operand into ah/al (either ts or ts' one's complement,
	 * for later floor division)
	 */ /* Since 86400 == 128*675 we can drop the least 7 bits and
	 * divide by 675 instead of 86400. Then the maximum remainder
	 * after each devision step is 674, and we need 10 bits for
	 * that. So in the next step we can shift in 22 bits from the
	 * numerator.
	 *
	 * Therefore we load the accu with the top 13 bits (51..63) in
	 * the first shot. We don't have to remember the quotient -- it
	 * would be shifted out anyway.
	 */ /* Now assemble the remainder with bits 29..50 from the
	 * numerator and divide. This creates the upper ten bits of the
	 * quotient. (Well, the top 22 bits of a 44bit result. But that
	 * will be truncated to 32 bits anyway.)
	 */ /* Now assemble the remainder with bits 7..28 from the numerator
	 * and do a final division step.
	 */ /* The last 7 bits get simply dropped, as they have no affect on
	 * the quotient when dividing by 86400.
	 */ /* apply sign correction and calculate the true floor
	 * remainder.
	 */