xref: /OK3568_Linux_fs/kernel/arch/m68k/fpsp040/smovecr.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun|
2*4882a593Smuzhiyun|	smovecr.sa 3.1 12/10/90
3*4882a593Smuzhiyun|
4*4882a593Smuzhiyun|	The entry point sMOVECR returns the constant at the
5*4882a593Smuzhiyun|	offset given in the instruction field.
6*4882a593Smuzhiyun|
7*4882a593Smuzhiyun|	Input: An offset in the instruction word.
8*4882a593Smuzhiyun|
9*4882a593Smuzhiyun|	Output:	The constant rounded to the user's rounding
10*4882a593Smuzhiyun|		mode unchecked for overflow.
11*4882a593Smuzhiyun|
12*4882a593Smuzhiyun|	Modified: fp0.
13*4882a593Smuzhiyun|
14*4882a593Smuzhiyun|
15*4882a593Smuzhiyun|		Copyright (C) Motorola, Inc. 1990
16*4882a593Smuzhiyun|			All Rights Reserved
17*4882a593Smuzhiyun|
18*4882a593Smuzhiyun|       For details on the license for this file, please see the
19*4882a593Smuzhiyun|       file, README, in this same directory.
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun|SMOVECR	idnt	2,1 | Motorola 040 Floating Point Software Package
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun	|section 8
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun#include "fpsp.h"
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun	|xref	nrm_set
28*4882a593Smuzhiyun	|xref	round
29*4882a593Smuzhiyun	|xref	PIRN
30*4882a593Smuzhiyun	|xref	PIRZRM
31*4882a593Smuzhiyun	|xref	PIRP
32*4882a593Smuzhiyun	|xref	SMALRN
33*4882a593Smuzhiyun	|xref	SMALRZRM
34*4882a593Smuzhiyun	|xref	SMALRP
35*4882a593Smuzhiyun	|xref	BIGRN
36*4882a593Smuzhiyun	|xref	BIGRZRM
37*4882a593Smuzhiyun	|xref	BIGRP
38*4882a593Smuzhiyun
39*4882a593SmuzhiyunFZERO:	.long	00000000
40*4882a593Smuzhiyun|
41*4882a593Smuzhiyun|	FMOVECR
42*4882a593Smuzhiyun|
43*4882a593Smuzhiyun	.global	smovcr
44*4882a593Smuzhiyunsmovcr:
45*4882a593Smuzhiyun	bfextu	CMDREG1B(%a6){#9:#7},%d0 |get offset
46*4882a593Smuzhiyun	bfextu	USER_FPCR(%a6){#26:#2},%d1 |get rmode
47*4882a593Smuzhiyun|
48*4882a593Smuzhiyun| check range of offset
49*4882a593Smuzhiyun|
50*4882a593Smuzhiyun	tstb	%d0		|if zero, offset is to pi
51*4882a593Smuzhiyun	beqs	PI_TBL		|it is pi
52*4882a593Smuzhiyun	cmpib	#0x0a,%d0		|check range $01 - $0a
53*4882a593Smuzhiyun	bles	Z_VAL		|if in this range, return zero
54*4882a593Smuzhiyun	cmpib	#0x0e,%d0		|check range $0b - $0e
55*4882a593Smuzhiyun	bles	SM_TBL		|valid constants in this range
56*4882a593Smuzhiyun	cmpib	#0x2f,%d0		|check range $10 - $2f
57*4882a593Smuzhiyun	bles	Z_VAL		|if in this range, return zero
58*4882a593Smuzhiyun	cmpib	#0x3f,%d0		|check range $30 - $3f
59*4882a593Smuzhiyun	ble	BG_TBL		|valid constants in this range
60*4882a593SmuzhiyunZ_VAL:
61*4882a593Smuzhiyun	fmoves	FZERO,%fp0
62*4882a593Smuzhiyun	rts
63*4882a593SmuzhiyunPI_TBL:
64*4882a593Smuzhiyun	tstb	%d1		|offset is zero, check for rmode
65*4882a593Smuzhiyun	beqs	PI_RN		|if zero, rn mode
66*4882a593Smuzhiyun	cmpib	#0x3,%d1		|check for rp
67*4882a593Smuzhiyun	beqs	PI_RP		|if 3, rp mode
68*4882a593SmuzhiyunPI_RZRM:
69*4882a593Smuzhiyun	leal	PIRZRM,%a0	|rmode is rz or rm, load PIRZRM in a0
70*4882a593Smuzhiyun	bra	set_finx
71*4882a593SmuzhiyunPI_RN:
72*4882a593Smuzhiyun	leal	PIRN,%a0		|rmode is rn, load PIRN in a0
73*4882a593Smuzhiyun	bra	set_finx
74*4882a593SmuzhiyunPI_RP:
75*4882a593Smuzhiyun	leal	PIRP,%a0		|rmode is rp, load PIRP in a0
76*4882a593Smuzhiyun	bra	set_finx
77*4882a593SmuzhiyunSM_TBL:
78*4882a593Smuzhiyun	subil	#0xb,%d0		|make offset in 0 - 4 range
79*4882a593Smuzhiyun	tstb	%d1		|check for rmode
80*4882a593Smuzhiyun	beqs	SM_RN		|if zero, rn mode
81*4882a593Smuzhiyun	cmpib	#0x3,%d1		|check for rp
82*4882a593Smuzhiyun	beqs	SM_RP		|if 3, rp mode
83*4882a593SmuzhiyunSM_RZRM:
84*4882a593Smuzhiyun	leal	SMALRZRM,%a0	|rmode is rz or rm, load SMRZRM in a0
85*4882a593Smuzhiyun	cmpib	#0x2,%d0		|check if result is inex
86*4882a593Smuzhiyun	ble	set_finx	|if 0 - 2, it is inexact
87*4882a593Smuzhiyun	bra	no_finx		|if 3, it is exact
88*4882a593SmuzhiyunSM_RN:
89*4882a593Smuzhiyun	leal	SMALRN,%a0	|rmode is rn, load SMRN in a0
90*4882a593Smuzhiyun	cmpib	#0x2,%d0		|check if result is inex
91*4882a593Smuzhiyun	ble	set_finx	|if 0 - 2, it is inexact
92*4882a593Smuzhiyun	bra	no_finx		|if 3, it is exact
93*4882a593SmuzhiyunSM_RP:
94*4882a593Smuzhiyun	leal	SMALRP,%a0	|rmode is rp, load SMRP in a0
95*4882a593Smuzhiyun	cmpib	#0x2,%d0		|check if result is inex
96*4882a593Smuzhiyun	ble	set_finx	|if 0 - 2, it is inexact
97*4882a593Smuzhiyun	bra	no_finx		|if 3, it is exact
98*4882a593SmuzhiyunBG_TBL:
99*4882a593Smuzhiyun	subil	#0x30,%d0		|make offset in 0 - f range
100*4882a593Smuzhiyun	tstb	%d1		|check for rmode
101*4882a593Smuzhiyun	beqs	BG_RN		|if zero, rn mode
102*4882a593Smuzhiyun	cmpib	#0x3,%d1		|check for rp
103*4882a593Smuzhiyun	beqs	BG_RP		|if 3, rp mode
104*4882a593SmuzhiyunBG_RZRM:
105*4882a593Smuzhiyun	leal	BIGRZRM,%a0	|rmode is rz or rm, load BGRZRM in a0
106*4882a593Smuzhiyun	cmpib	#0x1,%d0		|check if result is inex
107*4882a593Smuzhiyun	ble	set_finx	|if 0 - 1, it is inexact
108*4882a593Smuzhiyun	cmpib	#0x7,%d0		|second check
109*4882a593Smuzhiyun	ble	no_finx		|if 0 - 7, it is exact
110*4882a593Smuzhiyun	bra	set_finx	|if 8 - f, it is inexact
111*4882a593SmuzhiyunBG_RN:
112*4882a593Smuzhiyun	leal	BIGRN,%a0	|rmode is rn, load BGRN in a0
113*4882a593Smuzhiyun	cmpib	#0x1,%d0		|check if result is inex
114*4882a593Smuzhiyun	ble	set_finx	|if 0 - 1, it is inexact
115*4882a593Smuzhiyun	cmpib	#0x7,%d0		|second check
116*4882a593Smuzhiyun	ble	no_finx		|if 0 - 7, it is exact
117*4882a593Smuzhiyun	bra	set_finx	|if 8 - f, it is inexact
118*4882a593SmuzhiyunBG_RP:
119*4882a593Smuzhiyun	leal	BIGRP,%a0	|rmode is rp, load SMRP in a0
120*4882a593Smuzhiyun	cmpib	#0x1,%d0		|check if result is inex
121*4882a593Smuzhiyun	ble	set_finx	|if 0 - 1, it is inexact
122*4882a593Smuzhiyun	cmpib	#0x7,%d0		|second check
123*4882a593Smuzhiyun	ble	no_finx		|if 0 - 7, it is exact
124*4882a593Smuzhiyun|	bra	set_finx	;if 8 - f, it is inexact
125*4882a593Smuzhiyunset_finx:
126*4882a593Smuzhiyun	orl	#inx2a_mask,USER_FPSR(%a6) |set inex2/ainex
127*4882a593Smuzhiyunno_finx:
128*4882a593Smuzhiyun	mulul	#12,%d0			|use offset to point into tables
129*4882a593Smuzhiyun	movel	%d1,L_SCR1(%a6)		|load mode for round call
130*4882a593Smuzhiyun	bfextu	USER_FPCR(%a6){#24:#2},%d1	|get precision
131*4882a593Smuzhiyun	tstl	%d1			|check if extended precision
132*4882a593Smuzhiyun|
133*4882a593Smuzhiyun| Precision is extended
134*4882a593Smuzhiyun|
135*4882a593Smuzhiyun	bnes	not_ext			|if extended, do not call round
136*4882a593Smuzhiyun	fmovemx (%a0,%d0),%fp0-%fp0		|return result in fp0
137*4882a593Smuzhiyun	rts
138*4882a593Smuzhiyun|
139*4882a593Smuzhiyun| Precision is single or double
140*4882a593Smuzhiyun|
141*4882a593Smuzhiyunnot_ext:
142*4882a593Smuzhiyun	swap	%d1			|rnd prec in upper word of d1
143*4882a593Smuzhiyun	addl	L_SCR1(%a6),%d1		|merge rmode in low word of d1
144*4882a593Smuzhiyun	movel	(%a0,%d0),FP_SCR1(%a6)	|load first word to temp storage
145*4882a593Smuzhiyun	movel	4(%a0,%d0),FP_SCR1+4(%a6)	|load second word
146*4882a593Smuzhiyun	movel	8(%a0,%d0),FP_SCR1+8(%a6)	|load third word
147*4882a593Smuzhiyun	clrl	%d0			|clear g,r,s
148*4882a593Smuzhiyun	lea	FP_SCR1(%a6),%a0
149*4882a593Smuzhiyun	btstb	#sign_bit,LOCAL_EX(%a0)
150*4882a593Smuzhiyun	sne	LOCAL_SGN(%a0)		|convert to internal ext. format
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun	bsr	round			|go round the mantissa
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun	bfclr	LOCAL_SGN(%a0){#0:#8}	|convert back to IEEE ext format
155*4882a593Smuzhiyun	beqs	fin_fcr
156*4882a593Smuzhiyun	bsetb	#sign_bit,LOCAL_EX(%a0)
157*4882a593Smuzhiyunfin_fcr:
158*4882a593Smuzhiyun	fmovemx (%a0),%fp0-%fp0
159*4882a593Smuzhiyun	rts
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun	|end
162