mirror of https://github.com/lianthony/NT4.0
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.
240 lines
7.4 KiB
240 lines
7.4 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:
|
|
//
|
|
//--
|
|
|
|
#include "ksmips.h"
|
|
|
|
//
|
|
// Define global variables.
|
|
//
|
|
|
|
.sdata
|
|
TimeIncrementReciprocal: //
|
|
.dword 0xa7c5ac471b478424 //
|
|
|
|
TimeIncrementShiftCount: //
|
|
.word 0x10 //
|
|
|
|
SBTTL("Compute Timer Table Index 32-bit")
|
|
//++
|
|
//
|
|
// ULONG
|
|
// ComputeTimerTableIndex32 (
|
|
// IN LARGE_INTEGER Interval,
|
|
// IN LARGE_INTEGER CurrentTime,
|
|
// IN PLONGLONG DueTime
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function compute 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 (a0, a1) - Supplies the relative time at which the timer is
|
|
// to expire.
|
|
//
|
|
// CurrentTime (a2, a3) - Supplies the current interrupt time.
|
|
//
|
|
// DueTime (10(sp)) - Supplies a pointer to a large iunteger that receives
|
|
// the due time.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// The time table index is returned as the function value and the due
|
|
// time is stored in the timer object.
|
|
//
|
|
//--
|
|
|
|
LEAF_ENTRY(ComputeTimerTableIndex32)
|
|
|
|
subu t0,a2,a0 // subtract low parts
|
|
subu t1,a3,a1 // subtract high part
|
|
sltu t2,a2,a0 // generate borrow from high part
|
|
subu t1,t1,t2 // subtract borrow
|
|
lw a0,4 * 4(sp) // get address of timer object
|
|
lw a1,TimeIncrementReciprocal // get low part of magic dividor
|
|
lw t2,TimeIncrementReciprocal + 4 // get high part of magic divisor
|
|
lbu v0,TimeIncrementShiftCount // get shift count
|
|
sw t0,0(a0) // set due time of timer object
|
|
sw t1,4(a0) //
|
|
|
|
//
|
|
// Compute low 32-bits of dividend times low 32-bits of divisor.
|
|
//
|
|
|
|
multu t0,a1 //
|
|
mfhi t3 // save high 32-bits of product
|
|
|
|
//
|
|
// Compute low 32-bits of dividend time high 32-bits of divisor.
|
|
//
|
|
|
|
multu t0,t2 //
|
|
mflo t4 // save low 32-bits of product
|
|
mfhi t5 // save high 32-bits of product
|
|
|
|
//
|
|
// Compute high 32-bits of dividend times low 32-bits of divisor.
|
|
//
|
|
|
|
multu t1,a1 //
|
|
mflo t6 // save low 32-bits of product
|
|
mfhi t7 // save high 32-bits of product
|
|
|
|
//
|
|
// Compute high 32-bits of dividend times high 32-bits of divisor.
|
|
//
|
|
|
|
multu t1,t2 //
|
|
mflo t8 // save low 32-bits of product
|
|
mfhi t9 // save high 32-bits of product
|
|
|
|
//
|
|
// Add partial results to form high 64-bits of result.
|
|
//
|
|
|
|
addu t0,t3,t4 //
|
|
sltu t1,t0,t4 // generate carry
|
|
addu t0,t0,t6 //
|
|
sltu t2,t0,t6 // generate carry
|
|
addu t2,t1,t2 // combine carries
|
|
addu t1,t2,t5 //
|
|
sltu t2,t1,t5 // generate carry
|
|
addu t1,t1,t7 //
|
|
sltu t3,t1,t7 // generate carry
|
|
addu t2,t2,t3 // combine carries
|
|
addu t1,t1,t8 //
|
|
sltu t3,t1,t8 // generate carry
|
|
addu t2,t2,t3 // combine carries
|
|
addu t2,t2,t9 //
|
|
|
|
//
|
|
// Right shift the result by the specified shift count.
|
|
//
|
|
// N.B. It is assumed that the shift count is less than 32-bits and not zero.
|
|
//
|
|
|
|
li v1,32 // compute left shift count
|
|
subu v1,v1,v0 //
|
|
srl t0,t1,v0 // shift low half right count bits
|
|
sll t2,t2,v1 // isolate shifted out bits of high half
|
|
or t0,t0,t2 // combine bits for low half of result
|
|
and v0,t0,TIMER_TABLE_SIZE - 1 // compute index value
|
|
j ra // return
|
|
|
|
.end ComputeTimerTableIndex32
|
|
|
|
SBTTL("Compute Timer Table Index 64-bit")
|
|
//++
|
|
//
|
|
// ULONG
|
|
// ComputeTimerTableIndex64 (
|
|
// IN LARGE_INTEGER Interval,
|
|
// IN LARGE_INTEGER CurrentTime,
|
|
// IN PLONGLONG Duetime
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function compute 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 (a0, a1) - Supplies the relative time at which the timer is
|
|
// to expire.
|
|
//
|
|
// CurrentTime (a2, a3) - Supplies the current interrupt time.
|
|
//
|
|
// DueTime (10(sp)) - Supplies a pointer to a large iunteger that receives
|
|
// the due time.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// The time table index is returned as the function value and the due
|
|
// time is stored in the timer object.
|
|
//
|
|
//--
|
|
|
|
LEAF_ENTRY(ComputeTimerTableIndex64)
|
|
|
|
subu t0,a2,a0 // subtract low parts
|
|
subu t1,a3,a1 // subtract high parts
|
|
sltu t2,a2,a0 // generate borrow from high part
|
|
subu t1,t1,t2 // subtract borrow
|
|
lw a0,4 * 4(sp) // get address of timer object
|
|
ld t2,TimeIncrementReciprocal // get 64-bit magic divisor
|
|
dsll t0,t0,32 // isolate low 32-bits of due time
|
|
dsrl t0,t0,32 //
|
|
dsll t1,t1,32 // isolate high 32-bits of due time
|
|
or t3,t1,t0 // merge low and high parts of due time
|
|
sd t3,0(a0) // set due time of timer object
|
|
|
|
//
|
|
// Compute the product of the due time with the magic divisor.
|
|
//
|
|
|
|
dmultu t2,t3 // compute 128-bit product
|
|
lbu v1,TimeIncrementShiftCount // get shift count
|
|
mfhi v0 // get high 32-bits of product
|
|
|
|
//
|
|
// Right shift the result by the specified shift count and isolate the timer
|
|
// table index.
|
|
//
|
|
|
|
dsrl v0,v0,v1 // shift low half right count bits
|
|
and v0,v0,TIMER_TABLE_SIZE - 1 // compute index value
|
|
j ra // return
|
|
|
|
.end ComputeTimerTableIndex64
|