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
9.0 KiB
240 lines
9.0 KiB
// TITLE("Compute Checksum")
|
|
//++
|
|
//
|
|
// Copyright (c) 1992 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
//
|
|
// chksum.s
|
|
//
|
|
// Abstract:
|
|
//
|
|
// This module implement a function to compute the checksum of a buffer.
|
|
//
|
|
// Author:
|
|
//
|
|
// David N. Cutler (davec) 27-Jan-1992
|
|
//
|
|
// Environment:
|
|
//
|
|
// User mode.
|
|
//
|
|
// Revision History:
|
|
//
|
|
//--
|
|
|
|
#include "ksmips.h"
|
|
|
|
SBTTL("Compute Checksum")
|
|
//++
|
|
//
|
|
// USHORT
|
|
// ChkSum (
|
|
// IN ULONG Checksum,
|
|
// IN PUSHORT Source,
|
|
// IN ULONG Length
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function computes the checksum of the specified buffer.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Checksum (a0) - Supplies the initial checksum value.
|
|
//
|
|
// Source (a1) - Supplies a pointer to the buffer that is checksumed.
|
|
//
|
|
// Length (a2) - Supplies the length of the buffer in words.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// The computed checksum is returned as the function value.
|
|
//
|
|
//--
|
|
|
|
LEAF_ENTRY(ChkSum)
|
|
|
|
sll a2,a2,1 // convert length to bytes
|
|
|
|
//
|
|
// Compute the checksum in 8-byte blocks.
|
|
//
|
|
|
|
.set noreorder
|
|
.set at
|
|
10: and t0,a2,8 - 1 // isolate residual bytes
|
|
subu t9,a2,t0 // subtract out residual bytes
|
|
beq zero,t9,60f // if eq, no 8-byte blocks
|
|
addu t8,a1,t9 // compute ending block address
|
|
move a2,t0 // set residual number of bytes
|
|
and v0,t9,1 << 3 // check for initial 8-byte block
|
|
beq zero,v0,20f // if eq, no 8-byte block
|
|
and v0,t9,1 << 4 // check for initial 16-byte block
|
|
lhu t0,0(a1) // load 8-byte block
|
|
lhu t1,2(a1) //
|
|
lhu t2,4(a1) //
|
|
lhu t3,6(a1) //
|
|
addu a1,a1,8 // advance source address
|
|
addu a0,a0,t0 // compute 8-byte checksum
|
|
addu a0,a0,t1 //
|
|
addu a0,a0,t2 //
|
|
beq t8,a1,60f // if eq, end of block
|
|
addu a0,a0,t3 //
|
|
20: beq zero,v0,30f // if eq, no 16-byte block
|
|
and v0,t9,1 << 5 // check for initial 32-byte block
|
|
lhu t0,0(a1) // load 16-byte data block
|
|
lhu t1,2(a1) //
|
|
lhu t2,4(a1) //
|
|
lhu t3,6(a1) //
|
|
lhu t4,8(a1) //
|
|
lhu t5,10(a1) //
|
|
lhu t6,12(a1) //
|
|
lhu t7,14(a1) //
|
|
addu a1,a1,16 // advance source address
|
|
addu a0,a0,t0 // compute 16-byte block checksum
|
|
addu a0,a0,t1 //
|
|
addu a0,a0,t2 //
|
|
addu a0,a0,t3 //
|
|
addu a0,a0,t4 //
|
|
addu a0,a0,t5 //
|
|
addu a0,a0,t6 //
|
|
beq t8,a1,60f // if eq, end of block
|
|
addu a0,a0,t7 //
|
|
30: beq zero,v0,50f // if eq, no 32-byte block
|
|
lhu t0,0(a1) // load 16-byte data block
|
|
lhu t1,2(a1) //
|
|
lhu t2,4(a1) //
|
|
lhu t3,6(a1) //
|
|
lhu t4,8(a1) //
|
|
lhu t5,10(a1) //
|
|
lhu t6,12(a1) //
|
|
lhu t7,14(a1) //
|
|
addu a0,a0,t0 // compute 16-byte block checksum
|
|
addu a0,a0,t1 //
|
|
addu a0,a0,t2 //
|
|
addu a0,a0,t3 //
|
|
addu a0,a0,t4 //
|
|
addu a0,a0,t5 //
|
|
addu a0,a0,t6 //
|
|
addu a0,a0,t7 //
|
|
lhu t0,16(a1) // load 16-byte data block
|
|
lhu t1,18(a1) //
|
|
lhu t2,20(a1) //
|
|
lhu t3,22(a1) //
|
|
lhu t4,24(a1) //
|
|
lhu t5,26(a1) //
|
|
lhu t6,28(a1) //
|
|
lhu t7,30(a1) //
|
|
addu a0,a0,t0 // compute 16-byte block checksum
|
|
addu a0,a0,t1 //
|
|
addu a0,a0,t2 //
|
|
addu a0,a0,t3 //
|
|
addu a0,a0,t4 //
|
|
addu a0,a0,t5 //
|
|
addu a0,a0,t6 //
|
|
addu a1,a1,32 // advance source address
|
|
beq t8,a1,60f // if eq, end of block
|
|
addu a0,a0,t7 //
|
|
40: lhu t0,0(a1) // load 16-byte data block
|
|
50: lhu t1,2(a1) //
|
|
lhu t2,4(a1) //
|
|
lhu t3,6(a1) //
|
|
lhu t4,8(a1) //
|
|
lhu t5,10(a1) //
|
|
lhu t6,12(a1) //
|
|
lhu t7,14(a1) //
|
|
addu a0,a0,t0 // compute 16-byte block checksum
|
|
addu a0,a0,t1 //
|
|
addu a0,a0,t2 //
|
|
addu a0,a0,t3 //
|
|
addu a0,a0,t4 //
|
|
addu a0,a0,t5 //
|
|
addu a0,a0,t6 //
|
|
addu a0,a0,t7 //
|
|
lhu t0,16(a1) // load 16-byte data block
|
|
lhu t1,18(a1) //
|
|
lhu t2,20(a1) //
|
|
lhu t3,22(a1) //
|
|
lhu t4,24(a1) //
|
|
lhu t5,26(a1) //
|
|
lhu t6,28(a1) //
|
|
lhu t7,30(a1) //
|
|
addu a0,a0,t0 // compute 16-byte block checksum
|
|
addu a0,a0,t1 //
|
|
addu a0,a0,t2 //
|
|
addu a0,a0,t3 //
|
|
addu a0,a0,t4 //
|
|
addu a0,a0,t5 //
|
|
addu a0,a0,t6 //
|
|
addu a0,a0,t7 //
|
|
lhu t0,32(a1) // load 16-byte data block
|
|
lhu t1,34(a1) //
|
|
lhu t2,36(a1) //
|
|
lhu t3,38(a1) //
|
|
lhu t4,40(a1) //
|
|
lhu t5,42(a1) //
|
|
lhu t6,44(a1) //
|
|
lhu t7,46(a1) //
|
|
addu a0,a0,t0 // compute 16-byte block checksum
|
|
addu a0,a0,t1 //
|
|
addu a0,a0,t2 //
|
|
addu a0,a0,t3 //
|
|
addu a0,a0,t4 //
|
|
addu a0,a0,t5 //
|
|
addu a0,a0,t6 //
|
|
addu a0,a0,t7 //
|
|
lhu t0,48(a1) // load 16-byte data block
|
|
lhu t1,50(a1) //
|
|
lhu t2,52(a1) //
|
|
lhu t3,54(a1) //
|
|
lhu t4,56(a1) //
|
|
lhu t5,58(a1) //
|
|
lhu t6,60(a1) //
|
|
lhu t7,62(a1) //
|
|
addu a0,a0,t0 // compute 16-byte block checksum
|
|
addu a0,a0,t1 //
|
|
addu a0,a0,t2 //
|
|
addu a0,a0,t3 //
|
|
addu a0,a0,t4 //
|
|
addu a0,a0,t5 //
|
|
addu a0,a0,t6 //
|
|
addu a0,a0,t7 //
|
|
srl t0,a0,16 // isolate carry bits
|
|
and t1,a0,0xffff // isolate sum bits
|
|
addu a1,a1,64 // advance source address
|
|
bne t8,a1,40b // if ne, not end of block
|
|
addu a0,t0,t1 // add sum bits to carry bits
|
|
|
|
.set at
|
|
.set reorder
|
|
|
|
//
|
|
// Compute the checksum of in 2-byte blocks.
|
|
//
|
|
|
|
60: addu t8,a1,a2 // compute ending block address
|
|
beq zero,a2,80f // if eq, no bytes to zero
|
|
|
|
.set noreorder
|
|
.set noat
|
|
70: lhu t0,0(a1) // compute checksum of 2-byte block
|
|
addu a1,a1,2 // advance source address
|
|
bne t8,a1,70b // if ne, more 2-byte blocks
|
|
addu a0,a0,t0 //
|
|
.set at
|
|
.set reorder
|
|
|
|
//
|
|
// Fold checksum into 16-bits.
|
|
//
|
|
|
|
80: srl v0,a0,16 // isolate carry bits
|
|
and a0,a0,0xffff // isolate sum bits
|
|
addu v0,v0,a0 // add sum bits to carry bits
|
|
srl a0,v0,16 // isolate possible carry bit
|
|
add v0,v0,a0 // add carry bit
|
|
and v0,v0,0xffff // isolate sum bits
|
|
j ra // return
|
|
|
|
.end ChkSum
|