205 lines
6.2 KiB
ArmAsm
205 lines
6.2 KiB
ArmAsm
|
/**
|
||
|
*** Copyright (C) 1996-97 Intel Corporation. All rights reserved.
|
||
|
***
|
||
|
*** The information and source code contained herein is the exclusive
|
||
|
*** property of Intel Corporation and may not be disclosed, examined
|
||
|
*** or reproduced in whole or in part without explicit written authorization
|
||
|
*** from the company.
|
||
|
**/
|
||
|
|
||
|
// TITLE("Context Conversion")
|
||
|
//++
|
||
|
//
|
||
|
// Module Name:
|
||
|
//
|
||
|
// convctx.s
|
||
|
//
|
||
|
// Abstract:
|
||
|
//
|
||
|
// This module implements the code necessary to convert or assign
|
||
|
// the user to kernel transition context to or from iA mode context.
|
||
|
//
|
||
|
// Author:
|
||
|
//
|
||
|
// Edward G. Chron (echron) 01-Apr-1996
|
||
|
//
|
||
|
// Environment:
|
||
|
//
|
||
|
// Kernel mode only.
|
||
|
//
|
||
|
// Revision History:
|
||
|
//
|
||
|
//
|
||
|
//--
|
||
|
|
||
|
#include "ksia64.h"
|
||
|
|
||
|
.file "convctx.s"
|
||
|
|
||
|
//++
|
||
|
//
|
||
|
// VOID
|
||
|
// RtlEmFpToIaFpContext (
|
||
|
// IN PCONTEXT ContextEM,
|
||
|
// IN OUT UCHAR *iAFpArea
|
||
|
// )
|
||
|
//
|
||
|
// Routine Description:
|
||
|
//
|
||
|
// This function takes the values stored for the EM FP registers which
|
||
|
// map the iA mode FP registers and copies them (in iA mode 10 byte
|
||
|
// format) to the targeted 80 byte iA mode FP register context area.
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// ContextEM (a0) - Pointer to the EM mode Context which contain the FP registers.
|
||
|
// iAFpArea(a1) - Pointer to area to store 8 * 10 byte iA mode FP regs.
|
||
|
//
|
||
|
// Return Value:
|
||
|
//
|
||
|
// None.
|
||
|
//
|
||
|
// N.B. The format iA mode FP registers is 80 bits and will not change.
|
||
|
//
|
||
|
//--
|
||
|
|
||
|
LEAF_ENTRY(RtlEmFpToIaFpContext)
|
||
|
|
||
|
add t5 = -8, r0 // Need to convert 8 EM mode FP Regs
|
||
|
|
||
|
cvtEmFp:
|
||
|
|
||
|
ldfe ft0 = [a0], 16 // Get EM FP reg mapping iA FP reg
|
||
|
add t4 = -4, r0 // Need to store 2 bytes 4 times
|
||
|
;;
|
||
|
|
||
|
getf.sig t2 = ft0 // floating-point reg significand
|
||
|
getf.exp t3 = ft0 // floating-point sign & exponent
|
||
|
;;
|
||
|
|
||
|
stIaFpReg:
|
||
|
|
||
|
st2 [a1] = t2, 2 // save 2 bytes of significand
|
||
|
extr.u t2 = t2, 16, 48 // shift to the next two bytes
|
||
|
adds t4 = 0x1, t4 // bump loop count
|
||
|
;;
|
||
|
|
||
|
cmp.lt p6, p0 = t4, r0 // done?
|
||
|
(p6) br.cond.dpnt.few stIaFpReg // no, store the next two bytes
|
||
|
|
||
|
adds t5 = 0x1, t5 // bump loop count
|
||
|
add t4 = 0, t3 // copy of exponent and sign
|
||
|
;;
|
||
|
extr.u t4 = t4, 2, 62 // get the sign in bit 15
|
||
|
;;
|
||
|
|
||
|
cmp.lt p6, p7 = t5, r0 // done?
|
||
|
dep t3 = t3, t4, 0, 15 // just first 16 bits of exponent
|
||
|
;;
|
||
|
|
||
|
st2 [a1] = t3, 2 // save sign and iA exponent
|
||
|
(p6) br.cond.dpnt.few cvtEmFp // no, process the next register
|
||
|
(p7) br.ret.sptk brp
|
||
|
;;
|
||
|
|
||
|
LEAF_EXIT(RtlEmFpToIaFpContext)
|
||
|
|
||
|
//++
|
||
|
//
|
||
|
// VOID
|
||
|
// RtlIaFpToEmFpContext (
|
||
|
// IN UCHAR *iAFpArea,
|
||
|
// IN OUT PCONTEXT ContextEM,
|
||
|
// IN OUT FLOAT128 *FpWorkArea
|
||
|
// )
|
||
|
//
|
||
|
// Routine Description:
|
||
|
//
|
||
|
// This function takes the values stored for the EM FP registers which
|
||
|
// map the iA mode FP registers and copies them (in iA mode 10 byte
|
||
|
// format) to the targeted 80 byte iA mode FP register context area.
|
||
|
//
|
||
|
// Arguments:
|
||
|
//
|
||
|
// ContextEM (a0) - Pointer to the EM mode Context registers that map iA mode FP regs.
|
||
|
// iAFpArea(a1) - Pointer to area to store 8 * 10 byte iA mode FP regs.
|
||
|
// alignedFp(a2) - FLOAT128 work area (aligned on 16 byte boundry).
|
||
|
//
|
||
|
// Return Value:
|
||
|
//
|
||
|
// None.
|
||
|
//
|
||
|
// N.B. The format iA mode FP registers is 80 bits and will not change.
|
||
|
//
|
||
|
//--
|
||
|
|
||
|
LEAF_ENTRY(RtlIaFpToEmFpContext)
|
||
|
|
||
|
add t0 = 8, a0 // iA Fp Save Area Pointer
|
||
|
add t5 = -8, r0 // Need to convert 8 iA mode FP Regs
|
||
|
;;
|
||
|
|
||
|
cvtIaFp:
|
||
|
add t8 = -4, r0 // Need to load 2 bytes 4 times
|
||
|
ld2 t3 = [t0], -2 // load exponent and sign
|
||
|
;;
|
||
|
add t4 = 0, t3 // copy of exponent and sign
|
||
|
;;
|
||
|
|
||
|
add t2 = 0, r0
|
||
|
extr.u t4 = t4, 15, 49 // get the sign in bit 17
|
||
|
;;
|
||
|
dep t3 = t4, t3, 17, 1 // just first 16 bits of exponent
|
||
|
|
||
|
|
||
|
ldIaFpReg:
|
||
|
ld2 t6 = [t0], -2 // load 2 bytes of significand
|
||
|
adds t8 = 0x1, t8 // bump loop count
|
||
|
;;
|
||
|
or t2 = t2, t6 // retain until complete
|
||
|
|
||
|
cmp.lt p6, p0 = t8, r0 // done?
|
||
|
;;
|
||
|
(p6) dep.z t2 = t2, 16, 48 // no, shift to the next two bytes
|
||
|
(p6) br.cond.dpnt.few ldIaFpReg // no, get next two bytes
|
||
|
;;
|
||
|
|
||
|
add t8 = -4, r0 // Need to store 2 bytes 4 times
|
||
|
mov t7 = a2 // get address of aligned save area
|
||
|
;;
|
||
|
|
||
|
alignIaFp:
|
||
|
st2 [t7] = t2, 2 // save 2 bytes of significand
|
||
|
extr.u t2 = t2, 16, 48 // shift to the next two bytes
|
||
|
adds t8 = 0x1, t8 // bump loop count
|
||
|
;;
|
||
|
|
||
|
cmp.lt p6, p0 = t8, r0 // done?
|
||
|
add t6 = 0, t3 // copy of exponent and sign
|
||
|
(p6) br.cond.dpnt.few alignIaFp // maybe
|
||
|
;;
|
||
|
|
||
|
nop.m 0
|
||
|
extr.u t6 = t6, 2, 62 // get the sign in bit 15
|
||
|
;;
|
||
|
dep t3 = t3, t6, 0, 15 // just first 15 bits of exponent
|
||
|
;;
|
||
|
|
||
|
st2 [t7] = t3, 2 // save sign and iA exponent
|
||
|
ldfe ft0 = [a2]
|
||
|
adds t5 = 0x1, t5 // bump loop count
|
||
|
;;
|
||
|
|
||
|
stfe [a1] = ft0, CxFltT3 - CxFltT2 // Store value into EM FP Context
|
||
|
cmp.lt p6, p7 = t5, r0 // done?
|
||
|
;;
|
||
|
(p6) add t2 = 0, r0 // no, reset significand for next
|
||
|
|
||
|
(p6) add t0 = 20, t0 // no, starting at the high end
|
||
|
(p6) br.cond.dpnt.few cvtIaFp // no, get next context record
|
||
|
(p7) br.ret.sptk brp
|
||
|
;;
|
||
|
|
||
|
LEAF_EXIT(RtlIaFpToEmFpContext)
|
||
|
|