NT4/private/ntos/lpc/ppc/lpcmove.s
2020-09-30 17:12:29 +02:00

160 lines
4.9 KiB
ArmAsm
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// TITLE("LPC Move Message Support")
//++
//
// Copyright (c) 1990 Microsoft Corporation
//
// Module Name:
//
// lpcmove.s
//
// Abstract:
//
// This module implements functions to support the efficient movement of
// LPC Message blocks
//
// Author:
//
// Chuck Bauman (cbauman@vnet.ibm.com) 20-Mar-1993
//
// Environment:
//
// Kernel mode only.
//
// Revision History:
//
// July 5th, 1994 plj@vnet.ibm.com slight performance optimization
// and updated C code to be correct
// again (I think).
//
// N.B. Structures of type PPORT_MESSAGE are assumed to be 8 byte aligned.
//
//--
#include "ksppc.h"
// SBTTL("Move Message")
//++
//
// VOID
// LpcpMoveMessage (
// OUT PPORT_MESSAGE DstMsg
// IN PPORT_MESSAGE SrcMsg
// IN PUCHAR SrcMsgData
// IN ULONG MsgType OPTIONAL,
// IN PCLIENT_ID ClientId OPTIONAL
// )
//
// Routine Description:
//
// This function moves an LPC message block and optionally sets the message
// type and client id to the specified values.
//
// Arguments:
//
// DstMsg (r.3) - Supplies a pointer to the destination message.
//
// SrcMsg (r.4) - Supplies a pointer to the source message.
//
// SrcMsgData (r.5) - Supplies a pointer to the source message data to
// copy to destination.
//
// MsgType (r.6) - If non-zero, then store in type field of the
// destination message.
//
// ClientId (r.7) - If non-NULL, then points to a ClientId to copy to
// the destination message.
//
// Return Value:
//
// None
//
//--
// The following is a possible C implementation of this routine, shown for
// (hopefully) clarity.
//--
// VOID
// LpcpMoveMessage (
// OUT PULONG DstMsg PPORT_MESSAGE
// IN PULONG SrcMsg PPORT_MESSAGE
// IN PULONG SrcMsgData PUCHAR
// IN ULONG MsgType OPTIONAL,
// IN PULONG ClientId OPTIONAL PCLIENT_ID
// )
// {
// ULONG NumberWords;
//
// *DstMsg++ = NumberWords = *SrcMsg++;
// NumberWords = (NumberWords + 3) >> 2;
// if (MsgType != 0) {
// *DstMsg++ = (*SrcMsg++ & 0xffff0000) | (MsgType & 0xffff);
// } else {
// *DstMsg++ = *SrcMsg++;
// }
// if (ClientId == NULL) {
// *DstMsg++ = *SrcMsg++;
// *DstMsg++ = *SrcMsg++;
// } else {
// *DstMsg++ = *ClientId++;
// *DstMsg++ = *ClientId;
// SrcMsg += 2;
// }
// *DstMsg++ = *SrcMsg++;
// *DstMsg++ = *SrcMsg++;
// while (NumberWords--) {
// *DstMsg++ = *SrcMsgData++;
// }
// }
LEAF_ENTRY(LpcpMoveMessage)
lwz r.10,0(r.4) // load first longword of source
cmpwi cr.1,r.6,0 // message type specified?
cmpwi cr.6,r.7,0 // client id specified?
subi r.5,r.5,4 // Prepare for lwzu in copymsg loop
lwz r.8,4(r.4) // load second longword of source
addi r.9,r.10,3 // round length to 4-byte multiple
rlwinm. r.11,r.9,29,0x1fff // get number of quadwords
lfd f.0,16(r.4) // get message id and view size
beq cr.1,nomsgtype // if eq, message type not specified
rlwimi r.8,r.6, 0, 0xffff // insert specified message type
nomsgtype:
stw r.10,0(r.3) // store first longword of destination
stw r.8,4(r.3) // store second longword of destination
beq cr.6,noclientid// if eq, client id not specified
lwz r.10,0(r.7) // load first longword of client id
lwz r.8,4(r.7) // load second longword if client id
b storeclient //
noclientid:
lwz r.10,8(r.4) // get third longword of source
lwz r.8,12(r.4) // get fourth longword of source
storeclient:
mtcrf 0x01,r.9 // set cr bit 29 if odd number longwords
stw r.10,8(r.3) // store client id (first half)
stw r.8,12(r.3) // (second half)
stfdu f.0,16(r.3) // store message id and view size
//
// At this point, the next byte to be stored in the destination (if any)
// goes at (r.3) + 8.
//
beq cr.0,noquad // if 0 length, no quadwords
mtctr r.11 // set count register with loop count
copymsg:
lwz r.10,4(r.5) // get longword of source
lwzu r.11,8(r.5) // get longword of source
stwu r.10,8(r.3) // store next longword of destination
stw r.11,4(r.3) // store next longword of destination
bdnz copymsg // if nz, more longwords to move
noquad:
bflr 29 // return if no odd longword to move
lwz r.10,4(r.5) // get last longword
stw r.10,8(r.3) // store last longword
LEAF_EXIT(LpcpMoveMessage) // return