167 lines
5.1 KiB
ArmAsm
167 lines
5.1 KiB
ArmAsm
# @(#)58 1.3 src/bos/kernel/epost/POWER/fpu.s, sysepost, bos411, 9428A410j 3/25/94 16:16:54
|
|
#
|
|
# COMPONENT_NAME: (SYSEPOST) power-on self tests
|
|
#
|
|
# FUNCTIONS: fpu_epost
|
|
#
|
|
# ORIGINS: 27
|
|
#
|
|
# IBM CONFIDENTIAL -- (IBM Confidential Restricted when
|
|
# combined with the aggregated modules for this product)
|
|
# SOURCE MATERIALS
|
|
# (C) COPYRIGHT International Business Machines Corp. 1989, 1994
|
|
# All Rights Reserved
|
|
#
|
|
# US Government Users Restricted Rights - Use, duplication or
|
|
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
|
|
|
|
.file "fpu.s"
|
|
|
|
# Testing floating point unit. The return code, which is saved in
|
|
# general purpose register g3, is the error code.
|
|
#
|
|
# Defining symbols for general and floating point registers
|
|
# g0 - g31 : 32 general purpose registers
|
|
# f0 - f31 : 32 floating point registers
|
|
#
|
|
#
|
|
S_PROLOG(fpu_epost)
|
|
|
|
mfspr r7,lr # save link reg
|
|
# mfmsr r8 # get MSR
|
|
# oril r6,r8,0x2000 # set FP - allow access to fpu
|
|
# mtmsr r6
|
|
bl fpu_skip # get addr of data
|
|
# DATA START
|
|
C1: .long 0xFFFFFFFF # All one's
|
|
.long 0xFFFFFFFF
|
|
C2: .long 0x00000000 # All zero's
|
|
.long 0x00000000
|
|
C.6: .long 0x3FE33333 # 0.6
|
|
.long 0x33333333
|
|
C.2: .long 0x3FC99999 # 0.9
|
|
.long 0x99999999
|
|
C3S: .long 0x40400000 # 3.0 single precision
|
|
CM2S: .long 0xC0000000 # -2.0 single precision
|
|
SM: .long 0x00100000 # approx = 2^(1-1023), small number
|
|
.long 0xC0000000
|
|
JUNK: .long 0x98765432 # This will be written over
|
|
.long 0x10FEDCBA
|
|
FSC: .long 0xBA411000 # Should be the content of FPSCR
|
|
# DATA END
|
|
fpu_skip:
|
|
mfspr r4,lr # mv address of data to reg
|
|
.using C1,r4
|
|
# # Test data bus on/off
|
|
#
|
|
lfd f1,C1 # Get one's
|
|
lfd f2,C2 # Get zero's
|
|
stfd f1,C2 # Flip for store
|
|
stfd f2,C1
|
|
mtfsf 0xff,f2 # Zero to FPSCR
|
|
cal r3, 0(0) # r3 = 0
|
|
#
|
|
cal r3,1(r3) # Error code = 1
|
|
l r0,C1 # If DBUS bits stuck on
|
|
cmpi 0,r0,0 # Check value = 0
|
|
bne FINI # If not, exit
|
|
l r0,C1+4 # r0 = next 4 bytes of zero's
|
|
cmpi 0,r0,0 # r0 = 0 ?
|
|
bne FINI # If not, exit
|
|
#
|
|
cal r3,1(r3) # Error code = 2
|
|
l r0,C2 # r0 gets all one's, i.e. -1
|
|
cmpi 0,r0,-1 # r0 = -1 ?
|
|
bne FINI # If not, exit
|
|
l r0,C2+4 # r0 = next 4 bytes of one's, i.e. -1
|
|
cmpi 0,r0,-1 # r0 = -1 ?
|
|
bne FINI # If not, exit
|
|
#
|
|
# # Test each bit of CR bus; FI = 0
|
|
#
|
|
cal r3,1(r3) # Error code = 3
|
|
lfd f2,C.6 # f2 = 0.6
|
|
lfd f3,C.2 # f3 = 0.2
|
|
fcmpu 0,f3,f2 # f3 is compared with f2, "unordered"
|
|
bnl FINI # Exit if f3 is not less than f2
|
|
bgt FINI # Exit if f3 is greater than f2
|
|
beq FINI # Exit if f3 is equal to f2
|
|
bso FINI # Exit on summary overflow
|
|
#
|
|
cal r3,1(r3) # Error code = 4
|
|
fcmpu 0,f2,f3 # f2 is compared with f3, "unordered"
|
|
bng FINI # Exit if f2 is not greater than f3
|
|
blt FINI # Exit if f2 is less than f3
|
|
cal r3,1(r3) # Error code = 5
|
|
fcmpu 0,f2,f2 # f2 is compared with f2, "unordered"
|
|
bne FINI # Exit if f2 is not equal to f2
|
|
cal r3,1(r3) # Error code = 6
|
|
fcmpu 0,f1,f2 # f1 (-1) is compared with f2,
|
|
bns FINI # Exit on not summary overflow
|
|
#
|
|
# # Test each bit of FI bus
|
|
#
|
|
cal r3,1(r3) # Error code = 7
|
|
fcmpu 2,f2,f2 # f2 is compared with f2, set field 2
|
|
bne 2,FINI # Check field 2, exit if not equal
|
|
fcmpu 3,f3,f3 # f3 is compared with f3, set field 3
|
|
bne 3,FINI # Check field 3, exit if not equal
|
|
fcmpu 4,f2,f2 # f2 is compared with f2, set field 4
|
|
bne 4,FINI # Check field 4, exit if not equal
|
|
#
|
|
# # Arithmetic check
|
|
#
|
|
lfs f0,C3S # f0 = 3.0, single precision
|
|
cal r3,1(r3) # Error code = 8
|
|
fd f1,f2,f3 # f1=f2/f3 or f1 = 0.6 / 0.2 = 3.0
|
|
fcmpu 0,f0,f1 # f0 is compared with f1
|
|
bne FINI # Exit if not equal
|
|
#
|
|
# # Check single words
|
|
#
|
|
cal r3,1(r3) # Error code = 9
|
|
stfs f0,C2 # 3.0 is stored in 4 bytes @C2
|
|
l r0,C2 # r0 = 3.0
|
|
lil r5,0x0000 # r5 = 'xxxx0000'
|
|
liu r5,0x4040 # r5 = '40400000' = 3
|
|
cmp 0,r0,r5 # r0 is compared with r5
|
|
bne FINI # Exit if not equal
|
|
#
|
|
lfs f5,CM2S # f5 = -2.0 single precision
|
|
lil r5,0x0000 # r5 = 'xxxx0000'
|
|
liu r5,0x4000 # r5 = '40000000'
|
|
fneg f6,f5 # f6 = -f5 = 2
|
|
stfs f6,C2+4 # 2 is stored @(C2+4)
|
|
l r6,C2+4 # r6 = 2
|
|
cmp 0,r5,r6 # r5 is compared with r6
|
|
bne FINI # Exit if not equal
|
|
#
|
|
# # Set exception bits
|
|
#
|
|
cal r3,1(r3) # Error code = 10
|
|
lfd f5,SM # f5 = 2^(1-1023), i.e. small number
|
|
fm. f1,f5,f3 # f1 = f5 * f3 = very small number
|
|
# The "." sets Rc = 1
|
|
fma f0,f0,f0,f0 # f0 = f0*f0 + f0 = 3*3 + 3 = 12
|
|
fd. f4,f0,f5 # f4 = f0 / f5, create overflow
|
|
bc 4,7,FINI # Exit if not overflow. 4 means branch
|
|
# if false; 7 means overflow
|
|
fms. f0,f2,f3,f0 # f0=f2*f3-f0; set inexact flag
|
|
mffs f7 # f7 = (FPSCR)||X'FFFFFFFF'
|
|
fd. f8,f4,f4 # f8=f4/f4; invalid for f4 is overflow
|
|
bc 4,6,FINI # Exit if not invalid; 4 for false
|
|
# condition; 6 for invalid bit
|
|
cal r3,1(r3) # Error code = 11
|
|
l r6,FSC # r6 = X'BA411000'
|
|
mffs f9 # f9 = X'FFFFFFFF'||(FPSCR)
|
|
stfd f9,JUNK # f9 is stored @JUNK
|
|
l r5,JUNK+4 # r5 = (FPSCR)
|
|
cmp 0,r5,r6 # r5 is compared with r6
|
|
bne FINI # branch to FINI if not equal
|
|
#
|
|
cal r3, 0(0) # r3 = 0 ; OK, passes all tests
|
|
FINI: mtspr lr,r7
|
|
br # return
|
|
|
|
S_EPILOG
|