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.
226 lines
6.6 KiB
226 lines
6.6 KiB
// TITLE("Large Integer Arithmetic")
|
|
//++
|
|
//
|
|
// Copyright (c) 1990 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
//
|
|
// largeint.s
|
|
//
|
|
// Abstract:
|
|
//
|
|
// This module implements __int64 arithmetic helper routines for the MIPS Compiler.
|
|
//
|
|
//
|
|
// Author:
|
|
//
|
|
// David N. Cutler (davec) 18-Apr-1990
|
|
//
|
|
// Environment:
|
|
//
|
|
// Any mode.
|
|
//
|
|
// Revision History:
|
|
//
|
|
// This module is derived from largeint.s in ntos\rtl\mips\largeint.s
|
|
//
|
|
//--
|
|
|
|
#include "ksmips.h"
|
|
|
|
SBTTL("int64 Shift Left")
|
|
|
|
//++
|
|
//
|
|
// LARGE_INTEGER
|
|
// RtlLargeIntegerShiftLeft (
|
|
// IN LARGE_INTEGER LargeInteger,
|
|
// IN CCHAR ShiftCount
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function shifts a signed large integer left by an unsigned
|
|
// integer modulo 64 and returns the shifted signed large integer
|
|
// result.
|
|
//
|
|
// N.B. No test is made for significant bits shifted out of the result.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// LargeInteger (a0=LSW, a1=MSW) - Supplies the large integer to be shifted.
|
|
//
|
|
// ShiftCount (a2) - bits to shift
|
|
//
|
|
// Return Value:
|
|
//
|
|
// The large integer result is stored into (v0=LSW,v1=MSW).
|
|
//
|
|
//--
|
|
|
|
LEAF_ENTRY(__ll_lshift)
|
|
|
|
and a2,a2,0x3f // truncate shift count mod 64
|
|
|
|
//
|
|
// Left shift the operand by the specified shift count.
|
|
//
|
|
|
|
li t1,32 // compute right shift count
|
|
subu t1,t1,a2 //
|
|
bgtz t1,10f // if gtz, shift less that 32-bits
|
|
|
|
//
|
|
// Shift count is greater than or equal 32 bits - low half of result is zero,
|
|
// high half is the low half shifted left by remaining count.
|
|
//
|
|
|
|
sll v1,a0,a2 // set high half of result
|
|
move v0,zero // store low part of reuslt
|
|
j ra // return
|
|
|
|
//
|
|
// Shift count is less than 32-bits - high half of result is the high half
|
|
// of operand shifted left by count combined with the low half of the operand
|
|
// shifted right, low half of result is the low half shifted left.
|
|
//
|
|
|
|
10: move v0,a0 // set low half of result
|
|
sll v1,a1,a2 // shift high half left count bits
|
|
beq zero,a2,20f // if eq, no more shifts necessary
|
|
srl t0,v0,t1 // isolate shifted out bits of low half
|
|
sll v0,v0,a2 // shift low half left count bits
|
|
or v1,v1,t0 // combine bits for high half of result
|
|
20: j ra // return
|
|
|
|
.end __ll_rshift
|
|
|
|
SBTTL("int64 Logical Shift Right")
|
|
//++
|
|
//
|
|
// LARGE_INTEGER
|
|
// RtlLargeIntegerShiftRight (
|
|
// IN LARGE_INTEGER LargeInteger,
|
|
// IN CCHAR ShiftCount
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function shifts an unsigned large integer right by an unsigned
|
|
// integer modulo 64 and returns the shifted unsigned large integer
|
|
// result.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// LargeInteger (a0=LSW, a1=MSW) - Supplies the large integer to be shifted.
|
|
//
|
|
// ShiftCount (a2) - Supplies the right shift count.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// The large integer result is stored into (v0=LSW,v1=MSW).
|
|
//
|
|
//--
|
|
|
|
LEAF_ENTRY(__ull_rshift)
|
|
|
|
and a2,a2,0x3f // truncate shift count mod 64
|
|
|
|
//
|
|
// Right shift the operand by the specified shift count.
|
|
//
|
|
|
|
li t1,32 // compute left shift count
|
|
subu t1,t1,a2 //
|
|
bgtz t1,10f // if gtz, shift less that 32-bits
|
|
|
|
//
|
|
// Shift count is greater than or equal 32 bits - high half of result is
|
|
// zero, low half is the high half shifted right by remaining count.
|
|
//
|
|
|
|
srl v0,a1,a2 // set low half of result
|
|
move v1,zero // store high part of result
|
|
j ra // return
|
|
|
|
//
|
|
// Shift count is less than 32-bits - high half of result is the high half
|
|
// of operand shifted right by count, low half of result is the shifted out
|
|
// bits of the high half combined with the right shifted low half of the
|
|
// operand.
|
|
//
|
|
|
|
10: move v1,a1 // set high half of result
|
|
srl v0,a0,a2 // shift low half right count bits
|
|
beq zero,a2,20f // if eq, no more shifts necessary
|
|
sll t0,a1,t1 // isolate shifted out bits of high half
|
|
srl v1,a1,a2 // shift high half right count bits
|
|
or v0,v0,t0 // combine bits for low half of result
|
|
20: j ra // return
|
|
|
|
.end __ull_rshift
|
|
|
|
SBTTL("int64 Arithmetic Shift Right")
|
|
//++
|
|
//
|
|
// LARGE_INTEGER
|
|
// RtlLargeIntegerArithmeticShift (
|
|
// IN LARGE_INTEGER LargeInteger,
|
|
// IN CCHAR ShiftCount
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function shifts a signed large integer right by an unsigned
|
|
// integer modulo 64 and returns the shifted signed large integer
|
|
// result.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// LargeInteger (a0=LSW, a1=MSW) - Supplies the large integer to be shifted.
|
|
//
|
|
// ShiftCount (a2) - Supplies the right shift count.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// The large integer result is stored into (v0=LSW,v1=MSW).
|
|
//
|
|
//--
|
|
|
|
LEAF_ENTRY(__ll_rshift)
|
|
|
|
and a2,a2,0x3f // truncate shift count mod 64
|
|
|
|
//
|
|
// Right shift the operand by the specified shift count.
|
|
//
|
|
|
|
li t1,32 // compute left shift count
|
|
subu t1,t1,a2 //
|
|
bgtz t1,10f // if gtz, shift less that 32-bits
|
|
|
|
//
|
|
// Shift count is greater than or equal 32 bits - high half of result is
|
|
// bit63 sign-extended, low half is the high half shifted right by remaining count.
|
|
//
|
|
|
|
sra v0,a1,a2 // set low half of result
|
|
sra v1,a1,31 // set high half of result
|
|
j ra // return
|
|
|
|
//
|
|
// Shift count is less than 32-bits - high half of result is the high half
|
|
// of operand shifted right by count, low half of result is the shifted out
|
|
// bits of the high half combined with the right shifted low half of the
|
|
// operand.
|
|
//
|
|
|
|
10: move v1, a1 // set high half of result
|
|
srl v0,a0,a2 // shift low half right count bits
|
|
beq zero,a2,20f // if eq, no more shifts necessary
|
|
sll t0,a1,t1 // isolate shifted out bits of high half
|
|
sra v1,a1,a2 // shift high half right count bits
|
|
or v0,v0,t0 // combine bits for low half of result
|
|
20: j ra // return
|
|
|
|
.end __ll_rshift
|