Commit 636765ec authored by Jeffrey Lee's avatar Jeffrey Lee
Browse files

Add initial version of VFPSupport module

Detail:
  Initial VFP/NEON support code for RISC OS. Features:
  * Basic detection code for determining VFP version. Should work OK on all architecture versions.
  * Provides code to perform VFP/NEON context switches
  * Context switches can be lazy or immediate
  * Context register dumps can be stored in user-allocated memory or memory allocated by VFPSupport
  * Basic APIs for examining contexts and reporting available hardware features
  * "FastAPI" that privileged code can use for context switching in order to avoid SWI call overheads
  Missing/unfinished features:
  * No VFP exception handler is present, so the module will refuse to run on anything but a VFPv3 system
  * Lazy context switching is simplistic, opting to activate the new context upon the first undefined instruction abort instead of checking to see if it was a VFP instruction that triggered the abort
  * No interface to allow debuggers to easily get their hands on a register dump following a crash
  * No code to automatically clean up contexts left behind by dying programs
  * Can't be used by FIQ handlers, or from code called by an FIQ handler
  * Currently uses an error base of 0!
  Other notes:
  * Doc/vfpversions contains some random notes about the different VFP/NEON versions
  * Test/test1,ffb is a BASIC program that tests most of the module's functionality
Admin:
  Tested on Iyonix & Beagleboard. Iyonix version exits correctly, while Beagleboard version passes all tests in the test1 script.
  Need to sort out proper error numbers, and translate the error messages.


Version 0.01. Not tagged
parent d9a85246
hdr/** gitlab-language=armasm linguist-language=armasm linguist-detectable=true
s/** gitlab-language=armasm linguist-language=armasm linguist-detectable=true
*,ffb gitlab-language=bbcbasic linguist-language=bbcbasic linguist-detectable=true
* VFP versions:
- VFPv1
- for ARMv5 somethingsomething?
- "VFP10 revision 0 silicion", ARM10200 (AN98)
- has FPSID 0x410000A0 (SW=0,fmt=0,SNG=0,arch=0,part=0,variant=&A,rev=0)
- contains bug in vector length when trap triggered!
- ARMv5 ARM p574+
- 32x32bit registers
- FPSID, FPSCR, FPEXC
- rest is implementation defined (FPINST, etc.)
- VFPv1xD - single precision only (plus signed/unsigned int)
- VFPv1D - single + double (plus signed/unsigned int)
- p597, FLDMX/FSTMX:
- "N double-precision registers are stored in at most 2N+1 words"
- must use "matching" LDM/STM - i.e. reload exactly same regs
- p598 - details of format word that may be used
- p602 - FPSID indicates storage format used
- FLDMX/FSTMX deprecation in ARMv6+ means we should just use F[LDM|STM][S|D] for VFPv2+ without caring about the data type in the register (see ARMv6 ARM, p880)
- VFPv2
- for ARMv5TE, 5TEJ, v6, v6K, v6T2 (and other obsoleted ARMv5 variants?)
- "VFP10 revision 1 (ARM10200E), VFP9-S" (AN98)
- VFP10 rev 1 has FPSID 0x410101A0 (SW=0,fmt=0,SNG=0,arch=1,part=1,variant=&A,rev=0)
- VFP9-S & VFP11 don't need support code iff using FtZ, default NaN, round-to-nearest, and exceptions disabled?
- VFP9-S FPSID = 0x410101A0
- VFP11 also uses VFPv2
- has MVFR0, MVFR1 in r1p0!
- but looks like some of the fields are different to the VFPv3 version
- FPSID = 0x410120Bx
- MVFR0 = 0x11111111
- MVFR1 = 0x00000000
- 16x64bit registers (i.e. 32x32bit)
- VFPv1 to VFPv2 changes (ARMv6 ARM p853):
- FMDRR, FMRRD, FMSRR, FMRRS
- default NaN
- input denormal trap/detection
- "changes to ftz"
- VFPv3
- for ARMv7-A/R
- VFPv3-D32
- 32x64bit registers (64x32)
- must be this variant if ASIMD implemented as well
- upper half of register file not accessible as 32bit!
- VFPv3-D16
- 16x64bit registers (32x32)
- is D32 if VFP present and CPACR b30 == 0
* ASIMD versions:
- ARMv7-A/R
- ASIMD present iff VFP present and CPACR b31 == 0?
- what if VFP not present?
- 32x64bit registers
- implies that MVFR0 3..0 must be 2 for ASIMD to be present?
- ASIMD integer only: MVFR1 = xx001xxx
- ASIMD int+single: MVFR1 = xx011xxx
- ASIMD int+single+half: MVFR1 = xx111xxx
* Since CPACR is only present on ARMv6+, ARMv6+ are the only architectures we can support VFP auto-detection on
* ASIMD + VFP combinations: (ARMv7 p52)
ASIMD VFP
none none
integer none
int+single single (with double load/store support)
int+single single+double
none single (with double load/store support)
none single+double
* Reported VFP variants:
- VFPv1xD
- VFPv1D
- VFPv2 (plus xD, as implied above?)
- VFPv3[U]-D16 (plus xD, as indicated by MVFR0)
- VFPv3[U]-D32 (plus xD, as indicated by MVFR0?)
- so the following attributes exist:
- VFP version (1,2,3)
- trapped exception support (U)
- register file size (16 or 32 x64)
- double support
- halfword support (not VFPv1 according to ARMv5 ARM?)
- short vector support (since it's gone in Cortex-A9)
- default NaN (VFPv1 always propagates according to FPSCR in ARMv5 ARM?)
- flush-to-zero
- single precision support
- rounding modes
- SQRT
- DIV
- need to indicate both the hardware availability & software availability
- easiest to just return the MVFR values?
- returning simulated values for VFPv1/v2
- or software-enhanced values if software support is acceptable
- however VFP11 uses its own special MVFR format that doesn't match VFPv3
* context initialisation
- ARMv5 ARM p608
FPSID: (ARMv5)
31..24 23 22..21 20 19..16 15..8 7..4 3..0
implementor SW format SNG arch part variant revision
implementor: 0x41 = ARM
SW: 0 = contains hardware
1 = pure software implementation
format: 00 = FSTMX/FLDMX standard format 1 (raw data)
01 = FSTMX/FLDMX standard format 2 (format word)
10 = reserved
11 = non-standard format
SNG: 0 = supports both single & double precision (VFPv1D)
1 = only single precision (VFPv1xD)
arch: 0 = VFPv1
part: implementation defined primary part number
variant: implementation defined variant
revision: implementation defined revision
CPACR: (ARMv7 ARM p1378) - only present in ARMv6+
bit 31 = ASEDIS = ASIMD disable:
VFP ASIMD value
yes no RAO/WI
no no UNK/SBZP
yes yes implementation defined whether supported or not
0 = doesn't cause ASIMD-only instructions to trap
1 = causes ASIMD-only instructions to trap
no yes unspecified
bit 30 = D32DIS = D16-D31 VFP disable
VFP value
no UNK/SBZP
D16 RAO/WI
D32 implementation defined whether supported or not
0 = doesn't cause VFPv3 D16-D31 accesses to trap
1 = causes VFPv3 D16-D31 accesses to trap
- bits 31 & 30 are shown as UNP/SBZP in ARMv6 ARM
FPSID: (ARMv7 p1552)
31..24 23 22..16 15..8 7..4 3..0
implementor SW subarchitecture part variant revision
implementor: 0x41 = ARM
other values same as MIDR
SW: 0 = contains hardware
1 = pure software implementation
subarch: 0000000 = VFPv1 with implementation defined subarch
0000001 = VFPv2 with common VFP subarch v1
0000010 = VFPv3+ with common VFP subarch v2. Has MVFR0/MVFR1
0000011 = VFPv3+ with null subarch. Has MVFR0/MVFR1
0000100 = VFPv3+ with common VFP subarch v3. Has MVFR0/MVFR1
1xxxxxx = non-ARM subarchitecture
other:
0100000 = VFPv1D with standard format 2
0010000 = VFPv1xD
0110000 = VFPv1xD with standard format 2
part: implementation defined primary part number
variant: implementation defined variant
revision: implementation defined revision
MVFR0:
- only contains details of stuff that's supported by hardware, not stuff which support code may implement instead
31..28 VFP rounding modes
0 = only round-to-nearest (except VCVT which always uses round-to-zero)
1 = all modes supported
27..24 VFP short vectors (aka FPSCR.LEN != 0)
0 = not supported
1 = supported
23..20 VFP SQRT
0 = not supported
1 = supported (iff single/doubles are supported, as appropriate)
19..16 VFP divide
0 = not supported
1 = supported (iff single/doubles are supported, as appropriate)
15..12 VFP exception trapping
0 = not supported (VFPv3)
1 = supported (VFPv3U, VFPv2, VFPv1?)
11..8 VFP double precision
0 = not supported
1 = supported, VFPv2
2 = supported, VFPv3 (double-precision constant load, double<->fixed conversion)
- FSQRTD only supported if SQRT field is 1
- FDIVD only supported if DIV field is 1
- double<->single conversion only supported if single precision field nonzero
7..4 VFP single precision
0 = not supported
1 = supported, VFPv2
2 = supported, VFPv3 (single-precision constant load, single<->fixed conversion)
- FSQRTS only supported if SQRT field is 1
- FDIVS only supported if DIV field is 1
- double<->single conversion only supported if double precision field is nonzero
3..0 A_SIMD registers
0 = not supported
1 = 16x64bit regs
2 = 32x64bit regs
- if nonzero, all VFP LDC/STC/MCR/MRC supported
- if nonzero, VFP MCRR/MRRC supported (iff CPUID reg says MCRR/MRRC exist)
MVFR1:
- only contains details of stuff that's supported by hardware, not stuff which support code may implement instead
31..28 reserved
RAZ
27..24 VFP HPFH
0 = VFP half-precision not supported
1 = VFP half-precision supported
23..20 A_SIMD HPFP
0 = not supported
1 = supported (only permitted if A_SIMD SPFP == 1)
19..16 A_SIMD SPFP
0 = not supported
1 = supported (only permitted if A_SIMD int == 1)
15..12 A_SIMD int
0 = not supported
1 = supported
11..8 A_SIMD load/store
0 = not supported
1 = supported
7..4 D_NaN
0 = hardware only supports default NaN
1 = hardware supports NaN propagation
3..0 FtZ
0 = hardware only supports flush-to-zero
1 = hardware supportes full denormalized number arithmetic
--------------------------------------------------------------------------------
VFP feature/version determination:
1. Check CP10/CP11 presence
- if <ARMv5, not present
- if ARMv5, try reading FPSID and see if it aborts
- if ARMv6+, test with CPACR
2. Determine VFP version
- if bit 23 set, is software-only implementation, so abort and do whatever the hell we want
- if ARMv5/ARMv6 then version = FPSID[19..16]
- if ARMv7 then version = FPSID[22..16]
3. Determine trapped exception support
- if VFPv3+ use MVFR0[15..12]
- else trapped exceptions are always supported?
4. Determine register file size
- if VFPv3+ use MVFR0[3..0]
- else 16x64bit
5. Determine double support
- if VFPv3+ use MVFR0[11..8]
- else use FPSID[20]
6. Determine halfword support
- if VFPv3+ use MVFR1[27..24]
- else not supported?
7. Determine short vector support
- if VFPv3+ use MVFR0[27..24]
- else supported
8. Determine default NaN/NaN propagation
- if VFPv3+ use MVFR1[7..4]
- if VFPv1 only NaN propagation
- if VFPv2 both modes supported
9. Determine flush-to-zero support
- if VFPv3+ use MVFR1[3..0]
- else both modes supproted
10. Determine single precision support
- if VFPv3+ use MVFR0[7..4]
- else supported
11. Determine rounding mode support
- if VFPv3+ use MVFR0[31..28]
- else all supported
12. Determine SQRT hardware
- if VFPv3+ use MVFR0[23..20]
- else supported
13. Determine DIV hardware
- if VFPv3+ use MVFR0[19..16]
- else supported
NEON feature/version determination:
1. Check ARM architecture
- only supported in ARMv7+
2. Check CP10/CP11 presence
- using CPACR
3. Check MVFR1
- guaranteed to exist if CP10/11 are present, since must be VFPv3+ on ARMv7 (or just NEON)
4. if MVFR1 = xx001xxx, is integer-only NEON
5. if MVFR1 = xx011xxx, is integer + single NEON
6. if MVFR1 = xx111xxx, is integer + single + half NEON
VFP-D32/NEON disable ability:
1. Check ARM architecture
- D32/NEON can only be disabled in ARMv7+
2. Write CPACR[31..30] = 11 and read back to see if the bits stick
- if they stick, we can disable D32/NEON access?
- not that we really care - just need to make sure we only modify the bits if on ARMv7
#
# Copyright (c) 2010, RISC OS Open Ltd
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of RISC OS Open Ltd nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# Makefile for VFPSupport
#
COMPONENT = VFPSupport
HEADER1 = VFPSupport
ROM_SOURCE = GetAll.s
include StdTools
include AAsmModule
# Dynamic dependencies:
|
| Copyright (c) 2010, RISC OS Open Ltd
| All rights reserved.
|
| Redistribution and use in source and binary forms, with or without
| modification, are permitted provided that the following conditions are met:
| * Redistributions of source code must retain the above copyright
| notice, this list of conditions and the following disclaimer.
| * Redistributions in binary form must reproduce the above copyright
| notice, this list of conditions and the following disclaimer in the
| documentation and/or other materials provided with the distribution.
| * Neither the name of RISC OS Open Ltd nor the names of its contributors
| may be used to endorse or promote products derived from this software
| without specific prior written permission.
|
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
| ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
| LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
| CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
| CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
| POSSIBILITY OF SUCH DAMAGE.
|
Dir <Obey$Dir>
amu_machine clean
stripdepnd
|
| Copyright (c) 2010, RISC OS Open Ltd
| All rights reserved.
|
| Redistribution and use in source and binary forms, with or without
| modification, are permitted provided that the following conditions are met:
| * Redistributions of source code must retain the above copyright
| notice, this list of conditions and the following disclaimer.
| * Redistributions in binary form must reproduce the above copyright
| notice, this list of conditions and the following disclaimer in the
| documentation and/or other materials provided with the distribution.
| * Neither the name of RISC OS Open Ltd nor the names of its contributors
| may be used to endorse or promote products derived from this software
| without specific prior written permission.
|
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
| ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
| LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
| CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
| CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
| POSSIBILITY OF SUCH DAMAGE.
|
Dir <Obey$Dir>
amu_machine rom THROWBACK=-throwback
|
| Copyright (c) 2010, RISC OS Open Ltd
| All rights reserved.
|
| Redistribution and use in source and binary forms, with or without
| modification, are permitted provided that the following conditions are met:
| * Redistributions of source code must retain the above copyright
| notice, this list of conditions and the following disclaimer.
| * Redistributions in binary form must reproduce the above copyright
| notice, this list of conditions and the following disclaimer in the
| documentation and/or other materials provided with the distribution.
| * Neither the name of RISC OS Open Ltd nor the names of its contributors
| may be used to endorse or promote products derived from this software
| without specific prior written permission.
|
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
| ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
| LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
| CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
| CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
| POSSIBILITY OF SUCH DAMAGE.
|
dir <obey$dir>
amu_machine standalone THROWBACK=-throwback
#{DictTokens}
NoVFP:No VFP/NEON hardware present
BadVFP:Unsupported VFP/NEON version
FeatureUnavailable:A requested feature is unavailable
BadContext:Bad context
BadFeature:Bad VFPSupport_Features reason code
REM Copyright (c) 2010, RISC OS Open Ltd
REM All rights reserved.
REM
REM Redistribution and use in source and binary forms, with or without
REM modification, are permitted provided that the following conditions are met:
REM * Redistributions of source code must retain the above copyright
REM notice, this list of conditions and the following disclaimer.
REM * Redistributions in binary form must reproduce the above copyright
REM notice, this list of conditions and the following disclaimer in the
REM documentation and/or other materials provided with the distribution.
REM * Neither the name of RISC OS Open Ltd nor the names of its contributors
REM may be used to endorse or promote products derived from this software
REM without specific prior written permission.
REM
REM THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
REM AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
REM IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
REM ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
REM LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
REM CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
REM SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
REM INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
REM CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
REM ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
REM POSSIBILITY OF SUCH DAMAGE.
ON ERROR PRINT REPORT$;" at ";ERL : END
DIM code% 8
DIM temp% 128
REM VFPSupport_Version
SYS "VFPSupport_Version" TO A
PRINT "VFPSupport version ";(A/100)
REM VFPSupport_Features
SYS "VFPSupport_Features" TO A,B,C
PRINT "FPSID = &";FNhex8(A)
PRINT "MVFR0 = &";FNhex8(B)
PRINT "MVFR1 = &";FNhex8(C)
REM VFPSupport_CheckContext
FOR A=-1 TO 33
PRINT "Privileged context with ";A;" regs: ";
SYS "XVFPSupport_CheckContext",0,A TO B;flags%
IF flags% AND 1 THEN PRINT FNerr(B) ELSE PRINT ;B;" bytes"
PRINT "Usermode context with ";A;" regs: ";
SYS "XVFPSupport_CheckContext",1,A TO B;flags%
IF flags% AND 1 THEN PRINT FNerr(B) ELSE PRINT ;B;" bytes"
PRINT "Bad context with ";A;" regs: ";
SYS "XVFPSupport_CheckContext",NOT 1,A TO B;flags%
IF flags% AND 1 THEN PRINT FNerr(B) ELSE PRINT ;B;" bytes"
NEXT A
REM VFPSupport_FastAPI
SYS "VFPSupport_FastAPI" TO fast_wp%,fast_check%,fast_create%,fast_destroy%,fast_change%
PRINT "FastAPI:"
PRINT " Workspace = &";FNhex8(fast_wp%)
PRINT " CheckContext = &";FNhex8(fast_check%)
PRINT " CreateContext = &";FNhex8(fast_create%)
PRINT " DestroyContext = &";FNhex8(fast_destroy%)
PRINT " ChangeContext = &";FNhex8(fast_change%)
REM Test this bit multiple times, with different contexts active each time
FOR L=0 TO 2
CASE L OF
WHEN 0: PRINT '"Testing with current context active"'
WHEN 1: PRINT '"Testing with null context active"'
PROCChangeContext(0,0,really_orig_ctx%)
WHEN 2: PRINT '"Testing with non-null context active"'
nonnull%=FNCreateContext(&80000001,16,really_orig_ctx%)
ENDCASE
REM VFPSupport_ActiveContext
SYS "VFPSupport_ActiveContext" TO orig_ctx%
PRINT "Currently active context: &";FNhex8(orig_ctx%)
IF orig_ctx%<>0 THEN PROCExamine(orig_ctx%,0)
PRINT '"Checking context creation/deletion"'
new%=FNCreateContext(1,16,orig_ctx%)
PRINT "Destroying context"
PROCDestroyContext(new%,orig_ctx%,new%)
PRINT '"Checking context change & VFP operation"'
test1%=FNCreateContext(&80000001,16,orig_ctx%)
PRINT "Fill with some known value"
FOR A%=0 TO 31
temp%!(A%*4)=A%+&100
NEXT A%
PROCvldm(temp%,16)
PRINT "Serialise the context and examine the regs"
B%=FNGetRegs(test1%)
FOR A%=0 TO 31
IF temp%!(A%*4)<>B%!(A%*4) THEN PRINT "ERROR: Serialised context doesn't contain the right data at offset ";A%*4;" following nonlzay activation" : END
NEXT A%
test2%=FNCreateContext(1,16,test1%)
PRINT "Check lazy activation"
FOR A%=0 TO 31
temp%!(A%*4)=A%+&200
NEXT A%
PROCChangeContext(test2%,1,test1%)
SYS "VFPSupport_ExamineContext",test2%,0 TO flags%
IF (flags% AND (1<<29))=0 THEN PRINT "WARNING: Context was activated non-lazily"
PROCvldm(temp%,16)
PRINT "Serialise the context and examine the regs"
B%=FNGetRegs(test2%)
FOR A%=0 TO 31
IF temp%!(A%*4)<>B%!(A%*4) THEN PRINT "ERROR: Serialised context doesn't contain the right data at offset ";A%*4;" following lazy activation" : END
NEXT A%
PRINT "Check that writing to a context's register dump causes that data to be loaded on next activation"
B%=FNGetRegs(test1%)
FOR A%=0 TO 31
B%!(A%*4)=A%+&300
NEXT A%
PROCChangeContext(test1%,1,test2%)
PROCvstm(temp%,16)
FOR A%=0 TO 31
IF temp%!(A%*4)<>B%!(A%*4) THEN PRINT "ERROR: Reactivated context loaded wrong data at offset ";A%*4 : END
NEXT A%
PRINT "Activate test2% lazily ontop of test1%, then delete test1%"
PROCChangeContext(test2%,1,test1%)
PROCDestroyContext(test1%,0,test2%)
PRINT "Delete test2% and switch back to original"
PROCDestroyContext(test2%,0,test2%)
PROCChangeContext(orig_ctx%,0,0)
REM Restore previous state
CASE L OF
WHEN 0:
really_orig_ctx% = orig_ctx%
WHEN 1: PRINT '"Restoring original context &";FNhex8(really_orig_ctx%)
PROCChangeContext(really_orig_ctx%,0,prev%)
WHEN 2: PRINT '"Restoring original context &";FNhex8(really_orig_ctx%)
PROCDestroyContext(nonnull%,really_orig_ctx%,nonnull%)
ENDCASE
NEXT L
PRINT '"Lazily activate the null context and see what happens"'
PROCChangeContext(0,1,really_orig_ctx%)
errored%=FALSE
ON ERROR errored%=TRUE
IF errored%=FALSE THEN PROCvldm(temp%,16)
IF errored%=FALSE THEN PRINT "ERROR: VDLM with lazy null context didn't produce error" : END
ON ERROR PRINT REPORT$;" at ";ERL : END
PRINT '"Tests complete"'
END
REM VFPSupport_ExmaineContext
DEF PROCExamine(ctx%,serialise%)
LOCAL flags%,regs%,status%,format%,dump%,reg%,type%,offset%
IF ctx%=0 THEN ENDPROC
SYS "VFPSupport_ExamineContext",ctx%,serialise% TO flags%,regs%,status%,format%,dump%
PRINT "Context &";FNhex8(ctx%);" status:"
PRINT " Flags = &";FNhex8(flags%);":"
IF flags% AND 1 THEN PRINT " Supports usermode operation" ELSE PRINT " Privileged operation only"
IF flags% AND (1<<29) THEN PRINT " Awaiting lazy activation" ELSE PRINT " Not awaiting lazy activation"
IF flags% AND (1<<30) THEN PRINT " Status registers active" ELSE PRINT " Status registers inactive"
IF flags% AND (1<<31) THEN PRINT " Memory allocated by VFPSupport" ELSE PRINT " Memory allocated by user"
IF flags% AND &1FFFFFFE THEN PRINT " Unknown flag bits set!"
PRINT " Register count = ";regs%
PRINT " Register status = &";FNhex8(status%)
PRINT " Dump at &";FNhex8(dump%);" format &";FNhex8(format%);":"
WHILE format%!0<>-1
type%=format%?0 + ((format%?1)<<8)
offset%=format%?2 + ((format%?3)<<8)
format%+=4
PRINT " Type ";type%;" offset ";offset%;": ";
CASE type% OF
WHEN 0: PRINT "FPSCR=&";FNhex8(dump%!offset%)
WHEN 1: PRINT "FPEXC=&";FNhex8(dump%!offset%)
WHEN 2: PRINT "FPINST=&";FNhex8(dump%!offset%)
WHEN 3: PRINT "FPINST2=&";FNhex8(dump%!offset%)
WHEN 4: PRINT "FLDMX/FSTMX format word=&";FNhex8(dump%!offset%)
WHEN 5: PRINT "Register dump:"
FOR reg%=0 TO regs%-1
PRINT " D";reg%;" = &";FNhex8(dump%!(offset%+4));FNhex8(dump%!offset%)
offset%+=8
NEXT reg%
OTHERWISE
PRINT "Unknown!"
ENDCASE
ENDWHILE
ENDPROC
REM VFPSupport_CreateContext
DEF FNCreateContext(flags%,regs%,prev%)
LOCAL new%,prev2%
SYS "VFPSupport_CreateContext",flags%,regs%,0,0 TO new%,prev2%
PRINT "Created context &";FNhex8(new%);" with ";regs%;" regs and flags &";FNhex8(flags%)
PROCExamine(new%,0)
SYS "VFPSupport_ActiveContext" TO active%
IF flags% AND (1<<31) THEN
IF prev2%<>prev% THEN PRINT "ERROR: Context &";FNhex8(prev2%);" was previously active, expected &";FNhex8(prev%) : END
PROCExamine(prev2%,0)
IF active%<>new% THEN PRINT "ERROR: Context &";FNhex8(active%);" is now active, expected &";FNhex8(new%) : END
ELSE
IF active%<>prev% THEN PRINT "ERROR: Context &";FNhex8(active%);" is now active, expected &";FNhex8(prev%) : END