Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

175 lines
5.5 KiB

// TITLE("Compute Timer Table Index")
//++
//
// Copyright (c) 1993 Microsoft Corporation
//
// Module Name:
//
// timindex.s
//
// Abstract:
//
// This module implements the code necessary to compute the timer table
// index for a timer.
//
// Author:
//
// David N. Cutler (davec) 17-May-1993
//
// Environment:
//
// Kernel mode only.
//
// Revision History:
//
// Sep 19, 1993 plj Conversion to IBM PowerPC
//
//--
#include "ksppc.h"
//
// Define external vsriables that can be addressed using GP.
//
.extern KiTimeIncrementReciprocal
.extern KiTimeIncrementShiftCount
SBTTL("Compute Timer Table Index")
//++
//
// ULONG
// KiComputeTimerTableIndex (
// IN LARGE_INTEGER Interval,
// IN LARGE_INTEGER CurrentTime,
// IN PKTIMER Timer
// )
//
// Routine Description:
//
// This function computes the timer table index for the specified timer
// object and stores the due time in the timer object.
//
// N.B. The interval parameter is guaranteed to be negative since it is
// expressed as relative time.
//
// The formula for due time calculation is:
//
// Due Time = Current time - Interval
//
// The formula for the index calculation is:
//
// Index = (Due Time / Maximum Time) & (Table Size - 1)
//
// The due time division is performed using reciprocal multiplication.
//
// Arguments:
//
// Interval (r.3, r.4) - Supplies the relative time at which the timer is
// to expire.
//
// CurrentTime (r.5, r.6) - Supplies the current interrupt time.
//
// Timer (r.7) - Supplies a pointer to a dispatch object of type timer.
//
// Return Value:
//
// The time table index is returned as the function value and the due
// time is stored in the timer object.
//
//--
LEAF_ENTRY(KiComputeTimerTableIndex)
// Get addresses of KiTimeIncrementReciprocal and KiTimeIncrementShiftCounter
lwz r.11, [toc]KiTimeIncrementReciprocal(r.toc)
lwz r.10, [toc]KiTimeIncrementShiftCount(r.toc)
lwz r.12, 4(r.11) // get high part of magic divisor
lwz r.11, 0(r.11) // get low part of magic divisor
// Calculate DueTime = CurrentTime - Interval, result in {r.3,r.4}
subfc r.3, r.3, r.5 // subtract low parts (with carry)
subfe r.4, r.4, r.6 // subtract high parts (using carry)
lbz r.10, 0(r.10) // get shift count
stw r.3, TiDueTime(r.7) // set due time of timer object
stw r.4, TiDueTime+4(r.7)
//
// Compute low 32-bits of dividend times low 32-bits of divisor.
//
mulhwu r.0, r.3, r.11
//
// Compute low 32-bits of dividend times high 32-bits of divisor.
//
mullw r.6, r.3, r.12 // low 32-bits to r.6
mulhwu r.7, r.3, r.12 // high 32-bits to r.7
//
// Compute high 32-bits of dividend times low 32-bits of divisor.
//
mullw r.8, r.4, r.11 // low 32-bits to r.8
mulhwu r.9, r.4, r.11 // high 32-bits to r.9
//
// Compute high 32-bits of dividend times high 32-bits of divisor.
//
mullw r.3, r.4, r.12 // low 32-bits to r.3
mulhwu r.4, r.4, r.12 // high 32-bits to r.4
//
// On the grounds that I can't do more than double precision arithmetic
// without visual aids, I will attempt to draw a picture of what is
// going on here,.... my apologies to those who don't need the pic.
//
//
// _________________________________________________________________
// | | | | |
// | | | Due Time Low * Recip Low |
// | | | r.0 - |
// |---------------------------------------------------------------|
// | | Due Time Low * Recip High | |
// | | r.7 r.6 | |
// |------------------------------------------------ |
// | | Due Time High * Recip Low | |
// | | r.9 r.8 | |
// |------------------------------------------------ |
// | Due Time High * Recip High | | |
// | r.4 r.3 | | |
// |---------------------------------------------------------------|
// | | | | |
// | x | y | z | |
// |----------------------------------------------------------------
//
//
// Add partial results to form high 64-bits of result.
//
// (add 3 low parts together (r.0, r.6 and r.8) generating carries.
// the carries are added to the sum of the high parts (r.7, r.9 and r.3),
// the sum of the low parts is discarded).
//
addc r.0, r.6, r.0 // z = r.0 + r.6
adde r.7, r.9, r.7 // y = r.7 + r.9 + carry from z
addze r.4, r.4 // x += carry from y
addc r.0, r.8, r.0 // z += r.8
adde r.3, r.3, r.7 // y += r.3 + carry from z
addze r.4, r.4 // x += carry from y
//
// Combine low part of x with high part of y
//
// N.B. It is assumed that the shift count is less than 32-bits and not zero.
//
subfic r.11, r.10, 32 // compute left shift count
srw r.3, r.3, r.10 // get high part of low part
slw r.4, r.4, r.11 // get low part of high word
or r.3, r.4, r.3 // combine upper low and lower high
rlwinm r.3, r.3, 0, TIMER_TABLE_SIZE - 1
LEAF_EXIT(KiComputeTimerTableIndex)