xref: /openbmc/linux/arch/m68k/fpsp040/smovecr.S (revision e00d82d0)
11da177e4SLinus Torvalds|
21da177e4SLinus Torvalds|	smovecr.sa 3.1 12/10/90
31da177e4SLinus Torvalds|
41da177e4SLinus Torvalds|	The entry point sMOVECR returns the constant at the
51da177e4SLinus Torvalds|	offset given in the instruction field.
61da177e4SLinus Torvalds|
71da177e4SLinus Torvalds|	Input: An offset in the instruction word.
81da177e4SLinus Torvalds|
91da177e4SLinus Torvalds|	Output:	The constant rounded to the user's rounding
101da177e4SLinus Torvalds|		mode unchecked for overflow.
111da177e4SLinus Torvalds|
121da177e4SLinus Torvalds|	Modified: fp0.
131da177e4SLinus Torvalds|
141da177e4SLinus Torvalds|
151da177e4SLinus Torvalds|		Copyright (C) Motorola, Inc. 1990
161da177e4SLinus Torvalds|			All Rights Reserved
171da177e4SLinus Torvalds|
18e00d82d0SMatt Waddel|       For details on the license for this file, please see the
19e00d82d0SMatt Waddel|       file, README, in this same directory.
201da177e4SLinus Torvalds
211da177e4SLinus Torvalds|SMOVECR	idnt	2,1 | Motorola 040 Floating Point Software Package
221da177e4SLinus Torvalds
231da177e4SLinus Torvalds	|section 8
241da177e4SLinus Torvalds
251da177e4SLinus Torvalds#include "fpsp.h"
261da177e4SLinus Torvalds
271da177e4SLinus Torvalds	|xref	nrm_set
281da177e4SLinus Torvalds	|xref	round
291da177e4SLinus Torvalds	|xref	PIRN
301da177e4SLinus Torvalds	|xref	PIRZRM
311da177e4SLinus Torvalds	|xref	PIRP
321da177e4SLinus Torvalds	|xref	SMALRN
331da177e4SLinus Torvalds	|xref	SMALRZRM
341da177e4SLinus Torvalds	|xref	SMALRP
351da177e4SLinus Torvalds	|xref	BIGRN
361da177e4SLinus Torvalds	|xref	BIGRZRM
371da177e4SLinus Torvalds	|xref	BIGRP
381da177e4SLinus Torvalds
391da177e4SLinus TorvaldsFZERO:	.long	00000000
401da177e4SLinus Torvalds|
411da177e4SLinus Torvalds|	FMOVECR
421da177e4SLinus Torvalds|
431da177e4SLinus Torvalds	.global	smovcr
441da177e4SLinus Torvaldssmovcr:
451da177e4SLinus Torvalds	bfextu	CMDREG1B(%a6){#9:#7},%d0 |get offset
461da177e4SLinus Torvalds	bfextu	USER_FPCR(%a6){#26:#2},%d1 |get rmode
471da177e4SLinus Torvalds|
481da177e4SLinus Torvalds| check range of offset
491da177e4SLinus Torvalds|
501da177e4SLinus Torvalds	tstb	%d0		|if zero, offset is to pi
511da177e4SLinus Torvalds	beqs	PI_TBL		|it is pi
521da177e4SLinus Torvalds	cmpib	#0x0a,%d0		|check range $01 - $0a
531da177e4SLinus Torvalds	bles	Z_VAL		|if in this range, return zero
541da177e4SLinus Torvalds	cmpib	#0x0e,%d0		|check range $0b - $0e
551da177e4SLinus Torvalds	bles	SM_TBL		|valid constants in this range
561da177e4SLinus Torvalds	cmpib	#0x2f,%d0		|check range $10 - $2f
571da177e4SLinus Torvalds	bles	Z_VAL		|if in this range, return zero
581da177e4SLinus Torvalds	cmpib	#0x3f,%d0		|check range $30 - $3f
591da177e4SLinus Torvalds	ble	BG_TBL		|valid constants in this range
601da177e4SLinus TorvaldsZ_VAL:
611da177e4SLinus Torvalds	fmoves	FZERO,%fp0
621da177e4SLinus Torvalds	rts
631da177e4SLinus TorvaldsPI_TBL:
641da177e4SLinus Torvalds	tstb	%d1		|offset is zero, check for rmode
651da177e4SLinus Torvalds	beqs	PI_RN		|if zero, rn mode
661da177e4SLinus Torvalds	cmpib	#0x3,%d1		|check for rp
671da177e4SLinus Torvalds	beqs	PI_RP		|if 3, rp mode
681da177e4SLinus TorvaldsPI_RZRM:
691da177e4SLinus Torvalds	leal	PIRZRM,%a0	|rmode is rz or rm, load PIRZRM in a0
701da177e4SLinus Torvalds	bra	set_finx
711da177e4SLinus TorvaldsPI_RN:
721da177e4SLinus Torvalds	leal	PIRN,%a0		|rmode is rn, load PIRN in a0
731da177e4SLinus Torvalds	bra	set_finx
741da177e4SLinus TorvaldsPI_RP:
751da177e4SLinus Torvalds	leal	PIRP,%a0		|rmode is rp, load PIRP in a0
761da177e4SLinus Torvalds	bra	set_finx
771da177e4SLinus TorvaldsSM_TBL:
781da177e4SLinus Torvalds	subil	#0xb,%d0		|make offset in 0 - 4 range
791da177e4SLinus Torvalds	tstb	%d1		|check for rmode
801da177e4SLinus Torvalds	beqs	SM_RN		|if zero, rn mode
811da177e4SLinus Torvalds	cmpib	#0x3,%d1		|check for rp
821da177e4SLinus Torvalds	beqs	SM_RP		|if 3, rp mode
831da177e4SLinus TorvaldsSM_RZRM:
841da177e4SLinus Torvalds	leal	SMALRZRM,%a0	|rmode is rz or rm, load SMRZRM in a0
851da177e4SLinus Torvalds	cmpib	#0x2,%d0		|check if result is inex
861da177e4SLinus Torvalds	ble	set_finx	|if 0 - 2, it is inexact
871da177e4SLinus Torvalds	bra	no_finx		|if 3, it is exact
881da177e4SLinus TorvaldsSM_RN:
891da177e4SLinus Torvalds	leal	SMALRN,%a0	|rmode is rn, load SMRN in a0
901da177e4SLinus Torvalds	cmpib	#0x2,%d0		|check if result is inex
911da177e4SLinus Torvalds	ble	set_finx	|if 0 - 2, it is inexact
921da177e4SLinus Torvalds	bra	no_finx		|if 3, it is exact
931da177e4SLinus TorvaldsSM_RP:
941da177e4SLinus Torvalds	leal	SMALRP,%a0	|rmode is rp, load SMRP in a0
951da177e4SLinus Torvalds	cmpib	#0x2,%d0		|check if result is inex
961da177e4SLinus Torvalds	ble	set_finx	|if 0 - 2, it is inexact
971da177e4SLinus Torvalds	bra	no_finx		|if 3, it is exact
981da177e4SLinus TorvaldsBG_TBL:
991da177e4SLinus Torvalds	subil	#0x30,%d0		|make offset in 0 - f range
1001da177e4SLinus Torvalds	tstb	%d1		|check for rmode
1011da177e4SLinus Torvalds	beqs	BG_RN		|if zero, rn mode
1021da177e4SLinus Torvalds	cmpib	#0x3,%d1		|check for rp
1031da177e4SLinus Torvalds	beqs	BG_RP		|if 3, rp mode
1041da177e4SLinus TorvaldsBG_RZRM:
1051da177e4SLinus Torvalds	leal	BIGRZRM,%a0	|rmode is rz or rm, load BGRZRM in a0
1061da177e4SLinus Torvalds	cmpib	#0x1,%d0		|check if result is inex
1071da177e4SLinus Torvalds	ble	set_finx	|if 0 - 1, it is inexact
1081da177e4SLinus Torvalds	cmpib	#0x7,%d0		|second check
1091da177e4SLinus Torvalds	ble	no_finx		|if 0 - 7, it is exact
1101da177e4SLinus Torvalds	bra	set_finx	|if 8 - f, it is inexact
1111da177e4SLinus TorvaldsBG_RN:
1121da177e4SLinus Torvalds	leal	BIGRN,%a0	|rmode is rn, load BGRN in a0
1131da177e4SLinus Torvalds	cmpib	#0x1,%d0		|check if result is inex
1141da177e4SLinus Torvalds	ble	set_finx	|if 0 - 1, it is inexact
1151da177e4SLinus Torvalds	cmpib	#0x7,%d0		|second check
1161da177e4SLinus Torvalds	ble	no_finx		|if 0 - 7, it is exact
1171da177e4SLinus Torvalds	bra	set_finx	|if 8 - f, it is inexact
1181da177e4SLinus TorvaldsBG_RP:
1191da177e4SLinus Torvalds	leal	BIGRP,%a0	|rmode is rp, load SMRP in a0
1201da177e4SLinus Torvalds	cmpib	#0x1,%d0		|check if result is inex
1211da177e4SLinus Torvalds	ble	set_finx	|if 0 - 1, it is inexact
1221da177e4SLinus Torvalds	cmpib	#0x7,%d0		|second check
1231da177e4SLinus Torvalds	ble	no_finx		|if 0 - 7, it is exact
1241da177e4SLinus Torvalds|	bra	set_finx	;if 8 - f, it is inexact
1251da177e4SLinus Torvaldsset_finx:
1261da177e4SLinus Torvalds	orl	#inx2a_mask,USER_FPSR(%a6) |set inex2/ainex
1271da177e4SLinus Torvaldsno_finx:
1281da177e4SLinus Torvalds	mulul	#12,%d0			|use offset to point into tables
1291da177e4SLinus Torvalds	movel	%d1,L_SCR1(%a6)		|load mode for round call
1301da177e4SLinus Torvalds	bfextu	USER_FPCR(%a6){#24:#2},%d1	|get precision
1311da177e4SLinus Torvalds	tstl	%d1			|check if extended precision
1321da177e4SLinus Torvalds|
1331da177e4SLinus Torvalds| Precision is extended
1341da177e4SLinus Torvalds|
1351da177e4SLinus Torvalds	bnes	not_ext			|if extended, do not call round
1361da177e4SLinus Torvalds	fmovemx (%a0,%d0),%fp0-%fp0		|return result in fp0
1371da177e4SLinus Torvalds	rts
1381da177e4SLinus Torvalds|
1391da177e4SLinus Torvalds| Precision is single or double
1401da177e4SLinus Torvalds|
1411da177e4SLinus Torvaldsnot_ext:
1421da177e4SLinus Torvalds	swap	%d1			|rnd prec in upper word of d1
1431da177e4SLinus Torvalds	addl	L_SCR1(%a6),%d1		|merge rmode in low word of d1
1441da177e4SLinus Torvalds	movel	(%a0,%d0),FP_SCR1(%a6)	|load first word to temp storage
1451da177e4SLinus Torvalds	movel	4(%a0,%d0),FP_SCR1+4(%a6)	|load second word
1461da177e4SLinus Torvalds	movel	8(%a0,%d0),FP_SCR1+8(%a6)	|load third word
1471da177e4SLinus Torvalds	clrl	%d0			|clear g,r,s
1481da177e4SLinus Torvalds	lea	FP_SCR1(%a6),%a0
1491da177e4SLinus Torvalds	btstb	#sign_bit,LOCAL_EX(%a0)
1501da177e4SLinus Torvalds	sne	LOCAL_SGN(%a0)		|convert to internal ext. format
1511da177e4SLinus Torvalds
1521da177e4SLinus Torvalds	bsr	round			|go round the mantissa
1531da177e4SLinus Torvalds
1541da177e4SLinus Torvalds	bfclr	LOCAL_SGN(%a0){#0:#8}	|convert back to IEEE ext format
1551da177e4SLinus Torvalds	beqs	fin_fcr
1561da177e4SLinus Torvalds	bsetb	#sign_bit,LOCAL_EX(%a0)
1571da177e4SLinus Torvaldsfin_fcr:
1581da177e4SLinus Torvalds	fmovemx (%a0),%fp0-%fp0
1591da177e4SLinus Torvalds	rts
1601da177e4SLinus Torvalds
1611da177e4SLinus Torvalds	|end
162