Files
seta75D 2e8a93c394 Init
2021-10-11 18:20:23 -03:00

1577 lines
35 KiB
ArmAsm

/*
*"@(#)assymbly.s 1.1 7/30/92 Copyright Sun Microsystems";
*/
/*
* the following is a temporary memory storage location used
* for transfering operands from the IU to the FPU and back
*/
.seg "data"
.align 8
temp:
.skip 4 /* storage location for a single precision */
temp1:
.skip 4 /* storage for double precision */
temp2:
.skip 4 /* storage for extended */
.seg "text"
.global _clear_regs
.global _register_test
.global _move_regs
/* .global _set_psr
*/
.global _branches
.global _trap_remove
.global _fpu_exc
! .global _sin_int_rnd
! .global _doub_int_rnd
_clear_regs:
save %sp, -88, %sp ! save the registers, stacck
set temp2, %l0
st %i0, [%l0]
ld [%l0], %f0
ld [%l0], %f1
ld [%l0], %f2
ld [%l0], %f3
ld [%l0], %f4
ld [%l0], %f5
ld [%l0], %f6
ld [%l0], %f7
ld [%l0], %f8
ld [%l0], %f9
ld [%l0], %f10
ld [%l0], %f11
ld [%l0], %f12
ld [%l0], %f13
ld [%l0], %f14
ld [%l0], %f15
ld [%l0], %f16
ld [%l0], %f17
ld [%l0], %f18
ld [%l0], %f19
ld [%l0], %f20
ld [%l0], %f21
ld [%l0], %f22
ld [%l0], %f23
ld [%l0], %f24
ld [%l0], %f25
ld [%l0], %f26
ld [%l0], %f27
ld [%l0], %f28
ld [%l0], %f29
ld [%l0], %f30
ld [%l0], %f31
ret
restore
/*
_set_psr:
save %sp, -88, %sp
mov %l0, %psr
bclr 0xEFFF, %l0
mov %psr, %l0
ret
restore
*/
_register_test:
save %sp, -88, %sp
set temp, %l0
set temp1, %l1
set temp2,%l2
set 0x0, %l3 !reg has register number
st %i0, [%l0] !save the register number
st %i1, [%l1] !save the pattern to be written
cmp %i0, %l3 ! == 0
be reg0
inc %l3
cmp %i0, %l3 ! == 1
be reg1
inc %l3
cmp %i0, %l3 ! == 2
be reg2
inc %l3
cmp %i0, %l3 ! == 3
be reg3
inc %l3
cmp %i0, %l3 ! == 4
be reg4
inc %l3
cmp %i0, %l3 ! == 5
be reg5
inc %l3
cmp %i0, %l3 ! == 5
be reg6
inc %l3
cmp %i0, %l3 ! == 7
be reg7
inc %l3
cmp %i0, %l3 ! == 8
be reg8
inc %l3
cmp %i0, %l3 ! == 9
be reg9
inc %l3
cmp %i0, %l3 ! == 10
be reg10
inc %l3
cmp %i0, %l3 ! == 11
be reg11
inc %l3
cmp %i0, %l3 ! == 12
be reg12
inc %l3
cmp %i0, %l3 ! == 13
be reg13
inc %l3
cmp %i0, %l3 ! == 14
be reg14
inc %l3
cmp %i0, %l3 ! == 15
be reg15
inc %l3
cmp %i0, %l3 ! == 16
be reg16
inc %l3
cmp %i0, %l3 ! == 17
be reg17
inc %l3
cmp %i0, %l3 ! == 18
be reg18
inc %l3
cmp %i0, %l3 ! == 19
be reg19
inc %l3
cmp %i0, %l3 ! == 20
be reg20
inc %l3
cmp %i0, %l3 ! == 21
be reg21
inc %l3
cmp %i0, %l3 ! == 22
be reg22
inc %l3
cmp %i0, %l3 ! == 23
be reg23
inc %l3
cmp %i0, %l3 ! == 24
be reg24
inc %l3
cmp %i0, %l3 ! == 25
be reg25
inc %l3
cmp %i0, %l3 ! == 26
be reg26
inc %l3
cmp %i0, %l3 ! == 27
be reg27
inc %l3
cmp %i0, %l3 ! == 28
be reg28
inc %l3
cmp %i0, %l3 ! == 29
be reg29
inc %l3
cmp %i0, %l3 ! == 30
be reg30
inc %l3
cmp %i0, %l3 ! == 31
nop
ld [%l1], %f31
st %f31, [%l2]
ba reg_done ! done
nop
reg0:
ld [%l1], %f0
st %f0, [%l2]
ba reg_done
nop
reg1:
ld [%l1], %f1
st %f1, [%l2]
ba reg_done
nop
reg2:
ld [%l1], %f2
st %f2, [%l2]
ba reg_done
nop
reg3:
ld [%l1], %f3
st %f3, [%l2]
ba reg_done
nop
reg4:
ld [%l1], %f4
st %f4, [%l2]
ba reg_done
nop
reg5:
ld [%l1], %f5
st %f5, [%l2]
ba reg_done
nop
reg6:
ld [%l1], %f6
st %f6, [%l2]
ba reg_done
nop
reg7:
ld [%l1], %f7
st %f7, [%l2]
ba reg_done
nop
reg8:
ld [%l1], %f8
st %f8, [%l2]
ba reg_done
nop
reg9:
ld [%l1], %f9
st %f9, [%l2]
ba reg_done
nop
reg10:
ld [%l1], %f10
st %f10, [%l2]
ba reg_done
nop
reg11:
ld [%l1], %f11
st %f11, [%l2]
ba reg_done
nop
reg12:
ld [%l1], %f12
st %f12, [%l2]
ba reg_done
nop
reg13:
ld [%l1], %f13
st %f13, [%l2]
ba reg_done
nop
reg14:
ld [%l1], %f14
st %f14, [%l2]
ba reg_done
nop
reg15:
ld [%l1], %f15
st %f15, [%l2]
ba reg_done
nop
reg16:
ld [%l1], %f16
st %f16, [%l2]
ba reg_done
nop
reg17:
ld [%l1], %f17
st %f17, [%l2]
ba reg_done
nop
reg18:
ld [%l1], %f18
st %f18, [%l2]
ba reg_done
nop
reg19:
ld [%l1], %f19
st %f19, [%l2]
ba reg_done
nop
reg20:
ld [%l1], %f20
st %f20, [%l2]
ba reg_done
nop
reg21:
ld [%l1], %f21
st %f21, [%l2]
ba reg_done
nop
reg22:
ld [%l1], %f22
st %f22, [%l2]
ba reg_done
nop
reg23:
ld [%l1], %f23
st %f23, [%l2]
ba reg_done
nop
reg24:
ld [%l1], %f24
st %f24, [%l2]
ba reg_done
nop
reg25:
ld [%l1], %f25
st %f25, [%l2]
ba reg_done
nop
reg26:
ld [%l1], %f26
st %f26, [%l2]
ba reg_done
nop
reg27:
ld [%l1], %f27
st %f27, [%l2]
ba reg_done
nop
reg28:
ld [%l1], %f28
st %f28, [%l2]
ba reg_done
nop
reg29:
ld [%l1], %f29
st %f29, [%l2]
ba reg_done
nop
reg30:
ld [%l1], %f30
st %f30, [%l2]
ba reg_done
nop
reg31:
ld [%l1], %f31
st %f31, [%l2]
reg_done:
ld [%l2], %i0
ret
restore
_move_regs:
save %sp, -88, %sp ! save the registers, stacck
set temp2, %l0
set temp, %l1
st %i0, [%l0]
ld [%l0], %f0
fmovs %f0, %f1 ! from 0 to 1
fmovs %f1, %f2
fmovs %f2, %f3
fmovs %f3, %f4
fmovs %f4, %f5
fmovs %f5, %f6
fmovs %f6, %f7
fmovs %f7, %f8
fmovs %f8, %f9
fmovs %f9, %f10
fmovs %f10, %f11
fmovs %f11, %f12
fmovs %f12, %f13
fmovs %f13, %f14
fmovs %f14, %f15
fmovs %f15, %f16
fmovs %f16, %f17
fmovs %f17, %f18
fmovs %f18, %f19
fmovs %f19, %f20
fmovs %f20, %f21
fmovs %f21, %f22
fmovs %f22, %f23
fmovs %f23, %f24
fmovs %f24, %f25
fmovs %f25, %f26
fmovs %f26, %f27
fmovs %f27, %f28
fmovs %f28, %f29
fmovs %f29, %f30
fmovs %f30, %f31
st %f31, [%l1]
ld [%l1], %i0
ret
restore
restore
/*
* The following routine checks the branching is done accordingly
* to the ficc bits.
* input %i0 = 0 = branch unordered
* 1 = branch greater
* 2 = branch unordered or greater
* 3 = branch less
* 4 = branch unordered or less
* 5 = branch less or greater
* 6 = branch not equal
* 7 = branch equal
* 8 = branch unordered or equal
* . 9 = branch greater or equal
* 10 = branch branch unordered or greater or equal
* 11 = branch less or equal
* 12 = branch unordered or or less or equal
* 13 = branch ordered
* 14 = branch always
* 15 = branch never
*
* ouput : %i0 = 0 = good
* = 1 = error
*/
_branches:
save %sp, -88, %sp ! save the registers, stacck
set temp2, %l0
set temp1, %l1
set temp, %l2
set 0x0, %l3
st %l3, [%l0] !set the result to be true
st %i1, [%l1]
st %i2, [%l2]
ld [%l1], %f0
ld [%l2], %f2
fcmps %f0, %f2 ! compare the values to get ficc
nop
cmp %i0, %l3
be brn_0
inc %l3
cmp %i0, %l3
be brn_1
inc %l3
cmp %i0, %l3
be brn_2
inc %l3
cmp %i0, %l3
be brn_3
inc %l3
cmp %i0, %l3
be brn_4
inc %l3
cmp %i0, %l3
be brn_5
inc %l3
cmp %i0, %l3
be brn_6
inc %l3
cmp %i0, %l3
be brn_7
inc %l3
cmp %i0, %l3
be brn_8
inc %l3
cmp %i0, %l3
be brn_9
inc %l3
cmp %i0, %l3
be brn_10
inc %l3
cmp %i0, %l3
be brn_11
inc %l3
cmp %i0, %l3
be brn_12
inc %l3
cmp %i0, %l3
be brn_13
inc %l3
cmp %i0, %l3
be brn_14
nop
fbn br_error
nop
br_good:
ld [%l0], %i0
ret
restore
br_error:
set 0xff, %l3 ! set the flag that it is error
st %l3, [%l0]
ld [%l0], %i0
ret
restore
!
! branch unordered
brn_0:
fbu br_good
nop
ba br_error
nop
! branch greater
brn_1:
fbg br_good
nop
ba br_error
nop
! branch unordered or greater
brn_2:
fbug br_good
nop
ba br_error
nop
! branch less
brn_3:
fbl br_good
nop
ba br_error
nop
! branch unorderd or less
brn_4:
fbul br_good
nop
ba br_error
nop
! branch less or greater
brn_5:
fblg br_good
nop
ba br_error
nop
! branch not equal
brn_6:
fbne br_good
nop
ba br_error
nop
! branch equal
brn_7:
fbe br_good
nop
ba br_error
nop
! branch unordered or equal
brn_8:
fbue br_good
nop
ba br_error
nop
! branch greater or equal
brn_9:
fbge br_good
nop
ba br_error
nop
! branch unordered or greater or equal
brn_10:
fbuge br_good
nop
ba br_error
nop
! branch less or equal
brn_11:
fble br_good
nop
ba br_error
nop
! branch unordered or less or equal
brn_12:
fbule br_good
nop
ba br_error
nop
! branch ordered
brn_13:
fbo br_good
nop
ba br_error
nop
! branch always
brn_14:
fba br_good
nop
ba br_error
nop
!
!
!
!
_trap_remove:
save %sp, -88, %sp
set temp, %l2
std %fq, [%l2]
std %fq, [%l2]
nop
ret
restore
!
!
_fpu_exc:
save %sp, -88, %sp ! save the registers, stacck
! set _exp_trap_signal, %l0
set temp, %l2
ld [%l0], %l1
st %i0, [%l0] ! put the expected interrupt level
fsqrtx %f0, %f4 ! send an unimplemented instruction
std %fq, [%l2]
std %fq, [%l2]
std %fq, [%l2]
std %fq, [%l2]
std %fq, [%l2]
std %fq, [%l2]
std %fq, [%l2]
std %fq, [%l2]
ld [%l0], %i0 ! return the interrupt level
st %l1, [%l0] ! put the original interrupt level
! save %sp, -88, %sp
! fsqrtx %f0, %f4
! nop
ret
restore
!
! for single to integer round
!
!_sin_int_rnd:
! save %sp, -88, %sp ! save the registers, stacck
! set temp2, %o5
! set temp, %o4
! st %i0, [%o4]
! ld [%o4], %f0
! fstoir %f0, %f2
! st %f2, [%o5]
! ld [%o5], %i0
! ret
! restore
!_doub_int_rnd:
! save %sp, -88, %sp ! save the registers, stacck
! set temp2, %o5
! set temp, %o4
! st %i0, [%o4]
! ld [%o4], %f0
! fdtoir %f0, %f2
! st %f2, [%o5]
! ld [%o5], %i0
! ret
! restore
/*
*static char frefsccsid[] = "@(#)assymbly.s 1.1 6/5/87 Copyright Sun Microsystems";
*/
.seg "text"
.global _datap_add
.global _datap_mult
.global _datap_add_dp
.global _datap_mult_dp
.global _timing_add_sp
.global _timing_mult_sp
.global _timing_add_dp
.global _timing_mult_dp
.global result_msw
.global result_lsw
.seg "data"
.align 8
wdp:
.skip 4 /* storage location for a single precision */
wdp1:
.skip 4 /* storage for double precision */
wdp2:
.skip 4 /* storage for extended */
dp_result:
.skip 4
result_msw:
.skip 4
result_lsw:
.skip 4
.seg "text"
/*
* This routine test the data path of weitek adder for singel precision
* f0 = value
* f1 = 0
* add = f2 = value
*/
_datap_add:
save %sp, -88, %sp
set wdp, %l0
set wdp1, %l1
set 0x0, %l3 ! put value zero
st %l3, [%l1]
st %i0, [%l0] !store the value passed into memory location
ld [%l0], %f0 ! put the passed value into f0
ld [%l1], %f1 ! put value 0 into reg f1
fadds %f0, %f1, %f2 ! add zero and value into f2
fcmps %f0, %f2 ! check the value passed and added value, it has to be
! same
nop
fbe datap_ok
nop
datap_no:
st %f2, [%l1]
datap_ok:
ld [%l1], %i0
ret
restore
/*
* This routine test the data path of weitek multiplier for single precision
* f0 = value
* f1 = 1
* mult = f2 = f0 * f1
*/
_datap_mult:
save %sp, -88, %sp
set wdp, %l0
set wdp1, %l1
set 0x3F800000, %l3 !put value 1 into memoruy
st %l3, [%l1]
st %i0, [%l0] !store the value passed into memory location
ld [%l0], %f0 ! put the passed value into f0
ld [%l1], %f1 ! put value 1 into reg f1
fmuls %f0, %f1, %f2 ! multiply value with 1 , it has to be same
fcmps %f0, %f2
nop
fbne datap_no
nop
set 0x0, %l3
st %l3, [%l1]
ba datap_ok
nop
/*
* This routine test the data path of weitek multiplier for double precision
* f0 = msw value
* f1 = lsw value
* f2 = 0
* f3 = 0
* add = f4 = f0 + f2
*/
_datap_add_dp:
save %sp, -88, %sp
set wdp, %l0
set wdp1, %l1
set wdp2, %l2
set result_msw, %l4
set result_lsw,%l5
set 0x0, %l3 !put value 0 into memoruy
st %l3, [%l1]
st %i0, [%l0] ! msw of value
st %i1, [%l2] ! lsw of value
ld [%l0], %f0 ! put the msw into f0
ld [%l2], %f1 ! put the lsw into f1
ld [%l1], %f2 ! put 0 into f2
ld [%l1], %f3 ! put 0 into f3
faddd %f0, %f2, %f4 ! add value + 0 into f4
fcmpd %f0, %f4 ! now compare the result
nop
fbe datap_ok ! good
nop
/*
stfd %f4, [%l4]
*/
st %f4, [%l4]
st %f5, [%l5]
nop
set 0x1, %l3
st %l3, [%l1]
ba datap_ok ! no good but code is already set
nop
/*
* This routine test the data path of weitek multiplier for double precision
* f0 = msw value
* f1 = lsw value
* f2 = 0
* f3 = 0
* mult = f4 = f0 * f2
*/
_datap_mult_dp:
save %sp, -88, %sp
set wdp, %l0
set wdp1, %l1
set wdp2, %l2
set result_msw, %l4
set result_lsw, %l5
set 0x3FF00000, %l3 !put value 1 into memoruy
st %l3, [%l1]
st %i0, [%l0] ! msw of value
st %i1, [%l2] ! lsw of value
ld [%l0], %f0 ! put the msw into f0
ld [%l2], %f1 ! put the lsw into f1
ld [%l1], %f2 ! put 1 into f2
set 0x0, %l3
st %l3, [%l1]
ld [%l1], %f3 ! put 0 into f3, i.e f2 = 0x3ff00000 dp of 1
fmuld %f0, %f2, %f4 ! mult value * 1 into f4
fcmpd %f0, %f4 ! now compare the result
nop
fbe datap_ok ! good
nop
/*
stfd %f4, [%l4]
*/
st %f4, [%l4]
st %f5, [%l5]
nop
set 0x1, %l3
st %l3, [%l1]
ba datap_ok ! no good but code is already set
nop
!
! for add routine all the f registers from 0 - 19 will be filled with numbers
! and the result should be 10.
!
_timing_add_sp:
save %sp, -88, %sp ! save the registers, stacck
set wdp, %l0
set wdp1, %l1
set wdp2, %l2
set 0x0, %l3
set 0x3f800000, %l4 ! put value 1
set 0x41200000, %l5 ! put value 10 into local 5
st %l5, [%l0]
st %l4, [%l1]
st %l3, [%l2]
ld [%l0], %f31 ! register 31 has 10
ld [%l1], %f30 ! register 30 has 1
ld [%l2], %f0 ! reg 0 has 0
fmovs %f31, %f1 ! reg1 has 10
fsubs %f31, %f30, %f18 ! reg 18 has 9
fmovs %f18, %f3 ! reg 3 has 9
fmovs %f30, %f2 ! reg 2 has 1
fmovs %f30, %f19 ! reg 19 has 1
fsubs %f18, %f19, %f16 ! reg 16 has 8
fmovs %f16, %f5 ! reg 5 has 8
fsubs %f31, %f16, %f17 ! reg 17 has 2
fmovs %f17, %f4 ! reg 4 has 2
fsubs %f16, %f30, %f14 ! reg 14 has 7
fmovs %f14, %f7 ! reg 7 has 7
fsubs %f31, %f14, %f15 ! reg 15 has 3
fmovs %f15, %f6 ! reg 6 has 3
fsubs %f14, %f30, %f12 ! reg 12 has 6
fmovs %f12, %f9 ! reg 9 has 6
fsubs %f31, %f12, %f13 ! reg 13 has 4
fmovs %f13, %f8 ! reg 8 has 4
fsubs %f12, %f30, %f10 ! reg 10 has 5
fmovs %f10, %f11 ! reg 11 has 5
fadds %f0, %f1, %f20 ! reg 0 + reg 1 = reg 20 = 10
fadds %f2, %f3, %f21 ! reg 2 + reg 3 = reg 21 = 10
fadds %f4, %f5, %f22 ! reg 4 + reg 5 = reg 22 = 10
fadds %f6, %f7, %f23 ! reg 6 + reg 7 = reg 23 = 10
fadds %f8, %f9, %f24 ! reg 8 + reg 9 = reg 24 = 10
fadds %f10, %f11, %f25 ! reg 10 + reg 11 = reg 25 = 10
fadds %f12, %f13, %f26 ! reg 12 + reg 13 = reg 26 = 10
fadds %f14, %f15, %f27 ! reg 14 + reg 15 = reg 27 = 10
fadds %f16, %f17, %f28 ! reg 16 + reg 17 = reg 28 = 10
fadds %f18, %f19, %f29 ! reg 18 + reg 19 = reg 29 = 10
!
treg20: ! Now additions are done check it out
fcmps %f31, %f20
nop
fbe treg21 ! go to check next one
nop
r20:
st %f20, [%l2]
ba done
nop
treg21:
fcmps %f31, %f21
nop
fbe treg22
nop
r21:
st %f21, [%l2]
ba done
nop
treg22:
fcmps %f31, %f22
nop
fbe treg23
nop
r22:
st %f22, [%l2]
ba done
nop
treg23:
fcmps %f31, %f23
nop
fbe treg24
nop
r23:
st %f23, [%l2]
ba done
nop
treg24:
fcmps %f31, %f24
nop
fbe treg25
nop
r24:
st %f24, [%l2]
ba done
nop
treg25:
fcmps %f31, %f25
nop
fbe treg26
nop
r25:
st %f25, [%l2]
ba done
nop
treg26:
fcmps %f31, %f26
nop
fbe treg27
nop
r26:
st %f26, [%l2]
ba done
nop
treg27:
fcmps %f31, %f27
nop
fbe treg28
nop
r27:
st %f27, [%l2]
ba done
nop
treg28:
fcmps %f31, %f28
nop
fbe treg29
nop
r28:
st %f28, [%l2]
ba done
nop
treg29:
fcmps %f31, %f28
nop
fbe reggood
nop
r29:
st %f29, [%l2]
nop
done:
reggood:
ld [%l2], %i0
ret
restore
!
! for mult routine all the f registers from 0 - 19 will be filled wiht numbers
! and the result should be the number.
!
_timing_mult_sp:
save %sp, -88, %sp ! save the registers, stacck
set wdp, %l0
set wdp1, %l1
set wdp2, %l2
set 0x0, %l3
set 0x3f800000, %l4 ! put value 1
set 0x41200000, %l5 ! put value 10 into local 5
st %l5, [%l0]
st %l4, [%l1]
st %l3, [%l2]
ld [%l0], %f31 ! register 31 has 10
ld [%l1], %f1 ! register 1 has 1
fmovs %f1, %f3
fmovs %f1, %f5
fmovs %f1, %f7
fmovs %f1, %f9
fmovs %f1, %f11 ! register 1, 3, 5, 7, 9, 11, 13, 15, 17, 19
fmovs %f1, %f13 ! has a value of 1
fmovs %f1, %f15
fmovs %f1, %f17
fmovs %f1, %f19 !
fmovs %f1, %f0
fmovs %f31, %f18 ! reg 18 has 10
fsubs %f31, %f0, %f16 ! reg 16 has 9
fsubs %f16, %f0, %f14 ! reg 14 has 8
fsubs %f14, %f0, %f12 ! reg 12 has 7
fsubs %f12, %f0, %f10 ! reg 10 has 6
fsubs %f10, %f0, %f8 ! reg 8 has 5
fsubs %f8, %f0, %f6 ! reg 6 has 4
fsubs %f6, %f0, %f4 ! reg 4 has 3
fsubs %f4, %f0, %f2 ! reg 2 has 2
fmuls %f0, %f1, %f20 ! reg 0 * reg 1 = reg 20 = 1
fmuls %f2, %f3, %f21 ! reg 2 * reg 3 = reg 21 = 2
fmuls %f4, %f5, %f22 ! reg 4 * reg 5 = reg 22 = 3
fmuls %f6, %f7, %f23 ! reg 6 * reg 7 = reg 23 = 4
fmuls %f8, %f9, %f24 ! reg 8 * reg 9 = reg 24 = 5
fmuls %f10, %f11, %f25 ! reg 10 * reg 11 = reg 25 = 6
fmuls %f12, %f13, %f26 ! reg 12 * reg 13 = reg 26 = 7
fmuls %f14, %f15, %f27 ! reg 14 * reg 15 = reg 27 = 8
fmuls %f16, %f17, %f28 ! reg 16 * reg 17 = reg 28 = 9
fmuls %f18, %f19, %f29 ! reg 18 * reg 19 = reg 29 = 10
fcmps %f0, %f20
nop
fbe m21
nop
ba r20
nop
m21:
fcmps %f2, %f21
nop
fbe m22
nop
ba r21
nop
m22:
fcmps %f4, %f22
nop
fbe m23
nop
ba r22
nop
m23:
fcmps %f6, %f23
nop
fbe m24
nop
ba r23
nop
m24:
fcmps %f8, %f24
nop
fbe m25
nop
ba r24
nop
m25:
fcmps %f10, %f25
nop
fbe m26
nop
ba r25
nop
m26:
fcmps %f12, %f26
nop
fbe m27
nop
ba r26
nop
m27:
fcmps %f14, %f27
nop
fbe m28
nop
ba r27
nop
m28:
fcmps %f16, %f28
nop
fbe m29
nop
ba r28
nop
m29:
fcmps %f18, %f29
nop
fbe reggood
nop
ba r29
nop
!
! same thing for double precision
!
_timing_add_dp:
save %sp, -88, %sp ! save the registers, stacck
set wdp, %l0
set wdp1, %l1
set wdp2, %l2
set 0x0, %l3
set 0x3ff00000, %l4 ! put value 1
set 0x40240000, %l5 ! put value 10 into local 5
st %l5, [%l0]
st %l4, [%l1]
st %l3, [%l2]
ld [%l0], %f30 ! register 30 has 10
fmovs %f30, %f2 ! reg 2 has 10
ld [%l2], %f0 ! reg 0 has 0
ld [%l1], %f4 ! reg 4 has 1
fsubd %f30, %f4, %f6 ! reg 6 has 9
fsubd %f6, %f4, %f10 ! reg 10 has 8
fsubd %f30, %f10, %f8 ! reg 8 has 2
fsubd %f10, %f4, %f14 ! reg 14 has 7
fsubd %f30, %f14, %f12 ! reg 12 has 3
fsubd %f14, %f4, %f18 ! reg 18 has 6
fsubd %f30, %f18, %f16 ! reg 16 has 4
!
faddd %f0, %f2, %f20 ! reg 20 has 10
faddd %f4, %f6, %f22 ! reg 22 has 10
faddd %f8, %f10, %f24 ! reg 24 has 10
faddd %f12, %f14, %f26 ! reg 26 has 10
faddd %f16, %f18, %f28 ! reg 28 has 10
!
fcmpd %f30, %f20
nop
fbe d22
nop
st %f20, [%l2]
ba nogood
nop
d22:
fcmpd %f30, %f22
nop
fbe d24
nop
st %f22, [%l2]
ba nogood
nop
d24:
fcmpd %f30, %f24
nop
fbe d26
nop
st %f24, [%l2]
ba nogood
nop
d26:
fcmpd %f30, %f26
nop
fbe d28
nop
st %f26, [%l2]
ba nogood
nop
d28:
fcmpd %f30, %f28
nop
fbe good
nop
st %f28, [%l2]
nop
good:
nogood:
ld [%l2], %i0
ret
restore
! Now for mult
!
_timing_mult_dp:
save %sp, -88, %sp ! save the registers, stacck
set wdp, %l0
set wdp1, %l1
set wdp2, %l2
set 0x0, %l3
set 0x3ff00000, %l4 ! put value 1
set 0x40340000, %l5 ! put value 20 into local 5
st %l5, [%l0]
st %l4, [%l1]
st %l3, [%l2]
ld [%l0], %f30 ! register 30 has 20
ld [%l1], %f2 ! register 2 has 1
fmovs %f30, %f0 ! register 0 has 20
faddd %f2, %f2, %f10 ! register 10 has 2
fmovs %f10, %f16 ! register 16 has 2
faddd %f10, %f16, %f4 ! register 4 has 4
faddd %f4, %f2, %f6 ! register 6 has 5
fmovs %f6, %f12 ! reg. 12 has 5
fmovs %f4, %f14 ! reg 14 has 4
faddd %f12, %f6, %f18 ! reg 18 has 10
fmovs %f18, %f8 ! reg 8 has 10
!
! now everything is set
!
fmuld %f0, %f2, %f20 ! reg 20 has 20
fmuld %f4, %f6, %f22 ! reg 22 has 20
fmuld %f8, %f10, %f24 ! reg 24 has 20
fmuld %f12, %f14, %f26 ! reg 26 has 20
fmuld %f16, %f18, %f28 ! reg 28 has 20
!
fcmpd %f30, %f20
nop
fbe dm22
nop
st %f20, [%l2]
ba nogood
nop
dm22:
fcmpd %f30, %f22
nop
fbe dm24
nop
st %f22, [%l2]
ba nogood
nop
dm24:
fcmpd %f30, %f24
nop
fbe dm26
nop
st %f24, [%l2]
ba nogood
nop
dm26:
fcmpd %f30, %f26
nop
fbe dm28
nop
st %f26, [%l2]
ba nogood
nop
dm28:
fcmpd %f30, %f28
nop
fbe good
nop
st %f28, [%l2]
nop
ba nogood
nop
!
!
.seg "text"
.global _wadd_sp
.global _wadd_dp
.global _wdiv_sp
.global _wdiv_dp
.global _wmult_sp
.global _wmult_dp
.global _wsadd_addr
.global _wdadd_addr
.global _wsdiv_addr
.global _wddiv_addr
.global _wsmult_addr
.global _wdmult_addr
.global _actual_addr
.global _chain_sp
.global _chain_dp
/*
* The following routines are for checking the weitek
* status tests.
* The input is : i0 = amsw
* i1 = bmsw or alsw (for double precision)
* i2 = bmsw (for dp)
* i3 = blsw (for dp)
*
* The output is i0 = value of FSR register
*/
_wadd_sp:
save %sp, -88, %sp
set xdp, %l0
set xdp1, %l1
set xdp2, %l2
set _wsadd_addr, %l3
set _actual_addr, %l4
st %l3, [%l4]
st %i0, [%l0] ! get the first value
st %i1, [%l1] ! get the second value
ld [%l0], %f0 ! f0 has the first value
ld [%l1], %f2 ! f2 has the second value
ld [%l1], %o3
_wsadd_addr:
fadds %f0, %f2, %f3 ! now do the instruction
nop
nop
st %fsr, [%l2] ! get the fsr value
go_back:
nop
ld [%l2], %i0
ret
restore
nop
!
! same thing for add double precision
!
_wadd_dp:
save %sp, -88, %sp
set xdp, %l0
set xdp1, %l1
set xdp2, %l2
set _wdadd_addr, %l3
set _actual_addr, %l4
st %l3, [%l4]
st %i0, [%l0] ! get the first value
st %i1, [%l1] ! get the lsw of first value
ld [%l0], %f0
ld [%l1], %f1
st %i2, [%l0] ! get the second value
st %i3, [%l1] ! get the lsw of second value
ld [%l0], %f2
ld [%l1], %f3
_wdadd_addr:
faddd %f0, %f2, %f4 ! now do the instruction
nop
nop
st %fsr, [%l2] ! get the fsr value
ba go_back
nop
!
!
! for divide single precision
!
_wdiv_sp:
save %sp, -88, %sp
set xdp, %l0
set xdp1, %l1
set xdp2, %l2
set _wsdiv_addr, %l3
set _actual_addr, %l4
st %l3, [%l4]
st %i0, [%l0] ! get the first value
st %i1, [%l1] ! get the second value
st %fsr, [%l2]
ld [%l0], %f0 ! f0 has the first value
ld [%l1], %f2 ! f2 has the second value
_wsdiv_addr:
fdivs %f0, %f2, %f3 ! now do the instruction
nop
nop
!-------
! if ( (fsr && 0x000c000) == 0) /* see if Weitek fpu */
! then fsr = 0; /* .. if so then clear the flags */
!-------
st %fsr, [%l0] ! .. copy the fsr into it
ld [%l0], %l4 ! .... then into a register
set 0x0c000, %l0 ! .. get the FPU Type mask
and %l4, %l0, %l4 ! .... isolate the fpu type
bne wsdiv_done ! ...... exit if not a weitek (ie.. 0)
fmovs %f3, %f3 ! .... code required by Weitek
wsdiv_done:
st %fsr, [%l2] ! get the fsr value
ba go_back
nop
!
!
! for divide double precision
!
_wdiv_dp:
save %sp, -88, %sp
set xdp, %l0
set xdp1, %l1
set xdp2, %l2
set _wddiv_addr, %l3
set _actual_addr, %l4
st %l3, [%l4]
st %i0, [%l0] ! get the first value
st %i1, [%l1] ! get the lsw of first value
ld [%l0], %f0
ld [%l1], %f1
st %i2, [%l0] ! get the second value
st %i3, [%l1] ! get the lsw of second value
ld [%l0], %f2
ld [%l1], %f3
_wddiv_addr:
fdivd %f0, %f2, %f4 ! now do the instruction
nop
nop
!-------
! if ( (fsr && 0x000c000) == 0) /* see if Weitek fpu */
! then fsr = 0; /* .. if so then clear the flags */
!-------
st %fsr, [%l0] ! .. copy the fsr into it
ld [%l0], %l4 ! .... then into a register
set 0x0c000, %l0 ! .. get the FPU Type mask
and %l4, %l0, %l4 ! .... isolate the fpu type
bne wsdiv_done ! ...... exit if not a weitek (ie.. 0)
fmovs %f3, %f3 ! .... code required by Weitek
wddiv_done:
st %fsr, [%l2] ! get the fsr value
ba go_back
nop
!
!
! for multiply single precision
!
_wmult_sp:
save %sp, -88, %sp
set xdp, %l0
set xdp1, %l1
set xdp2, %l2
set _wsmult_addr, %l3
set _actual_addr, %l4
st %l3, [%l4]
st %i0, [%l0] ! get the first value
st %i1, [%l1] ! get the second value
ld [%l0], %f0 ! f0 has the first value
ld [%l1], %f2 ! f2 has the second value
_wsmult_addr:
fmuls %f0, %f2, %f3 ! now do the instruction
nop
nop
st %fsr, [%l2] ! get the fsr value
ba go_back
nop
!
!
! for multiply double precision
!
_wmult_dp:
save %sp, -88, %sp
set xdp, %l0
set xdp1, %l1
set xdp2, %l2
set _wdmult_addr, %l3
set _actual_addr, %l4
st %l3, [%l4]
st %i0, [%l0] ! get the first value
st %i1, [%l1] ! get the lsw of first value
ld [%l0], %f0
ld [%l1], %f1
st %i2, [%l0] ! get the second value
st %i3, [%l1] ! get the lsw of second value
ld [%l0], %f2
ld [%l1], %f3
_wdmult_addr:
fmuld %f0, %f2, %f4 ! now do the instruction
nop
nop
st %fsr, [%l2] ! get the fsr value
ba go_back
nop
!
!
! Chaining test.
!
_chain_sp:
save %sp, -88, %sp
set xdp, %l0
set xdp1, %l1
st %i0, [%l0] ! store the value
ld [%l0], %f0
fitos %f0, %f2 ! convert integer into single
fmovs %f2, %f0 ! f0 has the same value x
fadds %f0, %f2, %f4 ! f4 will have 2x
fsubs %f4, %f0, %f6 ! f6 will have x
fmuls %f6, %f4, %f8 ! f8 will have (2x * x)
fdivs %f8, %f4, %f10 ! f10 will have (2x * x) / 2x = x
fstoi %f10, %f12
!-------
! if ( (fsr && 0x000c000) == 0) /* see if Weitek fpu */
! then fsr = 0; /* .. if so then clear the flags */
!-------
_ch_done:
st %fsr, [%l0] ! .. copy the fsr into it
ld [%l0], %l4 ! .... then into a register
set 0x0c000, %l0 ! .. get the FPU Type mask
and %l4, %l0, %l4 ! .... isolate the fpu type
bne chain_done ! ...... exit if not a weitek (ie.. 0)
fmovs %f3, %f3 ! .... code required by Weitek
chain_done:
st %f12, [%l1]
ld [%l1], %i0
ret
restore
!
!
_chain_dp:
save %sp, -88, %sp
set xdp, %l0
set xdp1, %l1
st %i0, [%l0] ! store the value
ld [%l0], %f0
fitod %f0, %f2 ! convert integer into double
fmovs %f2, %f0 ! f0 has the same value x
faddd %f0, %f2, %f4 ! f4 will have 2x
fsubd %f4, %f0, %f6 ! f6 will have x
fmuld %f6, %f4, %f8 ! f8 will have (2x * x)
fdivd %f8, %f4, %f10 ! f10 will have (2x * x) / 2x = x
fdtoi %f10, %f12
ba _ch_done
!
!
nop
!
.seg "data"
.align 4
xdp:
.word 1 /* storage location for a single precision */
xdp1:
.word 1 /* storage for double precision */
xdp2:
.word 1 /* storage for extended */
xp_result:
.word 2
_actual_addr:
.word 2
.seg "text"
.global _fpu_soft_trap
.global _fp_addr
.global _fsr_data
.global _donot_dq
.global _seqerr_trap
_fpu_soft_trap:
save %sp, -88, %sp
set _fwp, %l1
set _fp_addr, %l2
set _fsr_data, %l3
set 0x1, %l5 ! set the flag that trap occured
set _donot_dq, %l6
st %l5, [%l4] ! set the flag
st %fsr, [%l3] ! store the fsr data
ld [%l6], %i0
cmp %i0, %l5 ! check whether bit is set for
be no_que
nop
std %fq, [%l2]
std %fq, [%l1]
! std %fq, [%l1]
st %fsr, [%l1]
ld [%l1], %i0
!
no_que:
! st %fsr, [%l1]
! ld [%l1], %i0
ret
restore
!
! This routine is to create the seqerror trap only
! just uses an floating point operation and does not
! do anything.
!
_seqerr_trap:
save %sp, -88, %sp
set _fwp, %l1
ld [%l1], %f0 ! just do some fpu instruction
st %fsr, [%l1]
nop
nop
ld [%l1], %i0
ret
restore
.seg "data"
_fp_addr:
.word 2
_fsr_data:
.word 2
_donot_dq:
.word 2
_fwp:
.word 1
_fwp1:
.word 1