1577 lines
35 KiB
ArmAsm
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
|
|
|
|
|
|
|
|
|