// 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