|
|
// TITLE("Alignment emulation") //++ // // // Copyright (c) 1992 Digital Equipment Corporation // // Module Name: // // align.s // // Abstract: // // This module implements the code to complete unaligned access // emulation. // // Author: // // Joe Notarangelo 14-May-1992 // // Environment: // // Kernel mode only. // // Revision History: // //--
#include "ksalpha.h"
//++ // // UQUAD // KiEmulateLoadLong( // IN PULONG UnalignedAddress // ) // // Routine Description: // // This routine returns the longword value stored at the unaligned // address passed in UnalignedAddress. // // Arguments: // // UnalignedAddress(a0) - Supplies a pointer to long data value. // // Return Value: // // The longword value at the address pointed to by UnalignedAddress. // //--
LEAF_ENTRY(KiEmulateLoadLong)
ldq_u t0, 0(a0) // get 1st quadword ldq_u v0, 3(a0) // get 2nd quadword
extll t0, a0, t0 // extract bytes from low quadword extlh v0, a0, v0 // extract bytes from high quadword bis v0, t0, v0 // v0 = longword
addl v0, zero, v0 // insure canonical longword form
ret zero, (ra) // return
.end KiEmulateLoadLong
//++ // // UQUAD // KiEmulateLoadQuad( // IN PUQUAD UnalignedAddress // ) // // Routine Description: // // This routine returns the quadword value stored at the unaligned // address passed in UnalignedAddress. // // Arguments: // // UnalignedAddress(a0) - Supplies a pointer to quad data value. // // Return Value: // // The quadword value at the address pointed to by UnalignedAddress. // //--
LEAF_ENTRY(KiEmulateLoadQuad)
ldq_u t0, 0(a0) // get 1st quadword ldq_u v0, 7(a0) // get 2nd quadword
extql t0, a0, t0 // extract bytes from low quadword extqh v0, a0, v0 // extract bytes from high quadword bis v0, t0, v0 // v0 = longword
ret zero, (ra) // return
.end KiEmulateLoadQuad
//++ // // VOID // KiEmulateStoreLong( // IN PULONG UnalignedAddress // IN UQUAD Data // ) // // Routine Description: // // This routine stores the longword in Data to the UnalignedAddress. // // Arguments: // // UnalignedAddress(a0) - Supplies a pointer to longword destination. // Data(a1) - Supplies data value to store. // // Return Value: // // None. // //--
LEAF_ENTRY(KiEmulateStoreLong)
ldq_u t0, 0(a0) // get 1st quadword ldq_u t1, 3(a0) // get 2nd quadword
inslh a1, a0, t2 // get bytes for high quadword insll a1, a0, t3 // get bytes for low quadword
msklh t1, a0, t1 // clear corresponding bytes mskll t0, a0, t0 // clear corresponding bytes
bis t1, t2, t1 // merge in bytes for high qw bis t0, t3, t0 // merge in bytes for low qw
stq_u t1, 3(a0) // must store high first in case stq_u t0, 0(a0) // address was actually aligned
ret zero, (ra) // return
.end KiEmulateStoreLong
//++ // // VOID // KiEmulateStoreQuad( // IN PUQUAD UnalignedAddress // IN UQUAD Data // ) // // Routine Description: // // This routine stores the quadword in Data to the UnalignedAddress. // // Arguments: // // UnalignedAddress(a0) - Supplies a pointer to quadword destination. // Data(a1) - Supplies the data value to store. // // Return Value: // // None. // //--
LEAF_ENTRY(KiEmulateStoreQuad)
ldq_u t0, 0(a0) // get 1st quadword ldq_u t1, 7(a0) // get 2nd quadword
insqh a1, a0, t2 // get bytes for high quadword insql a1, a0, t3 // get bytes for low quadword
mskqh t1, a0, t1 // clear corresponding bytes mskql t0, a0, t0 // clear corresponding bytes
bis t1, t2, t1 // merge in bytes for high qw bis t0, t3, t0 // merge in bytes for low qw
stq_u t1, 7(a0) // must store high first in case stq_u t0, 0(a0) // address was actually aligned
ret zero, (ra) // return
.end KiEmulateStoreQuad
//++ // // UQUAD // KiEmulateLoadFloatIEEESingle( // IN PULONG UnalignedAddress // ) // // Routine Description: // // This routine returns the IEEE Single value stored at the unaligned // address passed in UnalignedAddress. // // N.B. The value is returned as the memory format T-formatted // interpretation of the read S-format value. // // Arguments: // // UnalignedAddress(a0) - Supplies a pointer to float single data. // // Return Value: // // The single float value at the address pointed to by UnalignedAddress. // //--
.struct 0 FlTemp: .space 8 // temporary memory .space 8 // filler for alignment FlFrameLength: // length of stack frame
NESTED_ENTRY(KiEmulateLoadFloatIEEESingle, FlFrameLength, zero) lda sp, -FlFrameLength(sp) // allocate temp space PROLOGUE_END
// // get the value into an integer register //
ldq_u t0, 0(a0) // get 1st quadword ldq_u v0, 3(a0) // get 2nd quadword
extll t0, a0, t0 // extract bytes from low quadword extlh v0, a0, v0 // extract bytes from high quadword bis v0, t0, v0 // v0 = longword
// // v0 now is S memory format, however return from exception // sequence will restore floating registers as T memory format // convert v0 to T memory format
stl v0, FlTemp(sp) // store bytes, S-mem-format lds f0, FlTemp(sp) // now S-reg-format stt f0, FlTemp(sp) // write as T-mem-format ldq v0, FlTemp(sp) // return as T-mem_format
lda sp, FlFrameLength(sp) // deallocate stack frame
ret zero, (ra) // return
.end KiEmulateLoadFloatIEEESingle
//++ // // UQUAD // KiEmulateLoadFloatIEEEDouble( // IN PUQUAD UnalignedAddress // ) // // Routine Description: // // This routine returns the quadword value stored at the unaligned // address passed in UnalignedAddress. // // Arguments: // // UnalignedAddress(a0) - Supplies a pointer to double float data value. // // Return Value: // // The double float value at the address pointed to by UnalignedAddress. // //--
LEAF_ENTRY(KiEmulateLoadFloatIEEEDouble)
ldq_u t0, 0(a0) // get 1st quadword ldq_u v0, 7(a0) // get 2nd quadword
extql t0, a0, t0 // extract bytes from low quadword extqh v0, a0, v0 // extract bytes from high quadword bis v0, t0, v0 // v0 = longword
ret zero, (ra) // return
.end KiEmulateLoadFloatIEEEDouble
//++ // // VOID // KiEmulateStoreFloatIEEESingle( // IN PULONG UnalignedAddress // IN UQUAD Data // ) // // Routine Description: // // This routine stores the float value in Data to the UnalignedAddress. // // Arguments: // // UnalignedAddress(a0) - Supplies a pointer to float destination. // Data(a1) - Supplies the data value to store. // // Return Value: // // None. // //--
.struct 0 FsTemp: .space 8 // temporary memory .space 8 // filler for alignment FsFrameLength: // length of stack frame
NESTED_ENTRY(KiEmulateStoreFloatIEEESingle, FsFrameLength, zero) lda sp, -FsFrameLength(sp) // allocate stack space PROLOGUE_END
// // a1 is an integer version of the T-memory format // convert it to integer version of S-memory format //
stq a1, FsTemp(sp) // store bytes, T-mem-format ldt f10, FsTemp(sp) // load back in now in S-reg-format sts f10, FsTemp(sp) // now in S-mem-format ldl a1, FsTemp(sp) // now integer version of S-mem
// // now problem is just to store an unaligned longword //
ldq_u t0, 0(a0) // get 1st quadword ldq_u t1, 3(a0) // get 2nd quadword
inslh a1, a0, t2 // get bytes for high quadword insll a1, a0, t3 // get bytes for low quadword
msklh t1, a0, t1 // clear corresponding bytes mskll t0, a0, t0 // clear corresponding bytes
bis t1, t2, t1 // merge in bytes for high qw bis t0, t3, t0 // merge in bytes for low qw
stq_u t1, 3(a0) // must store high first in case stq_u t0, 0(a0) // was actually aligned
lda sp, FsFrameLength(sp) // restore stack frame
ret zero, (ra) // return
.end KiEmulateStoreFloatIEEESingle
//++ // // VOID // KiEmulateStoreFloatIEEEDouble( // IN PUQUAD UnalignedAddress // IN UQUAD Data // ) // // Routine Description: // // This routine stores the quadword in Data to the UnalignedAddress. // // Arguments: // // UnalignedAddress(a0) - Supplies a pointer to double float destination. // Data(a1) - Supplies the data value to store. // // Return Value: // // None. // //--
LEAF_ENTRY(KiEmulateStoreFloatIEEEDouble)
ldq_u t0, 0(a0) // get 1st quadword ldq_u t1, 7(a0) // get 2nd quadword
insqh a1, a0, t2 // get bytes for high quadword insql a1, a0, t3 // get bytes for low quadword
mskqh t1, a0, t1 // clear corresponding bytes mskql t0, a0, t0 // clear corresponding bytes
bis t1, t2, t1 // merge in bytes for high qw bis t0, t3, t0 // merge in bytes for low qw
stq_u t1, 7(a0) // must store high first in case stq_u t0, 0(a0) // was actually aligned
ret zero, (ra) // return
.end KiEmulateStoreFloatIEEEDouble
|