aboutsummaryrefslogtreecommitdiff
path: root/unix/as.vax/ieeer.s
blob: 789712aaa9aaa35915d959d278b6bcad7049886d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
#
# IEEER.S -- IEEE real to VAX single precision floating conversions.
#
#	 ieepakr (x)				# scalar, vax->ieee
#	 ieeupkr (x)				# scalar, ieee->vax
#	ieevpakr (native, ieee, nelem)		# vector, vax->ieee
#	ieevupkr (ieee, native, nelem)		# vector, ieee->vax
#	ieesnanr (NaN)				# set VAX NaN value
#	ieegnanr (NaN)				# get VAX NaN value
#	 ieemapr (mapin, mapout)		# enable NaN mapping
#	ieestatr (nin, nout)			# get num NaN values mapped
#      ieezstatr ()				# zero NaN counters
#
# These routines convert between the VAX and IEEE real floating formats,
# operating upon a single value or an array of values.  +/- zero is converted
# to zero.  When converting IEEE to VAX, underflow maps to zero, and exponent
# overflow and NaN input values map to the value set by IEESNANR (default 0).
# These routines are functionally equivalent to the semi-portable versions of
# the IRAF ieee/native floating conversion routines in osb$ieeer.x.
# TODO - Add a function callback option for processing NaN values.

	.data
vaxnan:	.long	0
nanin:	.long	0
nanout:	.long	0
mapin:	.long	1	# enable input NaN mapping by default for VAX
mapout:	.long	0

	.text
	.align	1
	.globl	_ieepar_
	.globl	_ieevpr_
	.globl	_ieeupr_
	.globl	_ieevur_
	.globl	_ieesnr_
	.globl	_ieegnr_
	.globl	_ieemar_
	.globl	_ieestr_
	.globl	_ieezsr_

_ieepar_:	# IEEPAKR (X)
	.word	0x0c
	movl	4(ap), r2			# data addr -> r2
	movl	r2, r3				# output clobbers input
	jsb	cvt_vax_ieee			# convert value
	ret
_ieevpr_:	# IEEVPAKR (VAX, IEEE, NELEM)
	.word	0x1c
	movl	4(ap), r2			# input vector -> r2
	movl	8(ap), r3			# output vector -> r3
	movl	*12(ap), r4			# loop counter
L1:	jsb	cvt_vax_ieee			# convert one value
	sobgtr	r4, L1				# loop
	ret
_ieeupr_:	# IEEUPKR (X)
	.word	0x0c
	movl	4(ap), r2			# data addr -> r2
	movl	r2, r3				# output clobbers input
	jsb	cvt_ieee_vax			# convert value
	ret
_ieevur_:	# IEEVUPKR (IEEE, VAX, NELEM)
	.word	0x1c
	movl	4(ap), r2			# input vector -> r2
	movl	8(ap), r3			# output vector -> r3
	movl	*12(ap), r4			# loop counter
L2:	jsb	cvt_ieee_vax			# convert one value
	sobgtr	r4, L2				# loop
	ret
_ieesnr_:	# IEESNANR (VAXNAN)
	.word	0x0
	movl	*4(ap), vaxnan
	clrl	nanin
	clrl	nanout
	ret
_ieegnr_:	# IEEGNANR (VAXNAN)
	.word	0x0
	movl	vaxnan, *4(ap)
	ret
_ieemar_:	# IEEMAPR (MAPIN, MAPOUT)
	.word	0x0
	movl	*4(ap), mapin
	movl	*8(ap), mapout
	ret
_ieestr_:	# IEESTATR (NIN, NOUT)
	.word	0x0
	movl	nanin, *4(ap)
	movl	nanout, *8(ap)
	ret
_ieezsr_:	# IEEZSTATR ()
	.word	0x0
	clrl	nanin
	clrl	nanout
	ret

cvt_vax_ieee:					# R2=in, R3=out
	movl	(r2)+, r0			# vax value -> r0

	tstl	mapout				# map NaNs on output?
	beql	L4				# no, just output value
	cmpl	r0, vaxnan			# yes, check if reserved value
	bneq	L4				# no, just output value
	clrl	r0				# generate IEEE NaN value
	insv	$255, $23, $8, r0		# insert NaN exponent (255)
	incl	nanout				# increment counter
	jbr	L5
L4:
	rotl	$16, r0, r0			# swap words -> r0
	extzv	$23, $8, r0, r1			# 8 bit exponent -> r1
	beql	L6				# branch if zero exponent 
	subw2	$2, r1				# adjust exponent bias
	bleq	L6				# return zero if underflow
	insv	r1, $23, $8, r0			# insert new exponent
L5:
	movl	sp, r1				# r3 points to input byte
	pushl	r0				# push r0 on stack
	movb	-(r1), (r3)+			# output longword, swapped
	movb	-(r1), (r3)+
	movb	-(r1), (r3)+
	movb	-(r1), (r3)+
	tstl	(sp)+				# pop stack
	rsb					# all done
L6:
	clrl	r0				# return all 32 bits zero
	jbr	L5

cvt_ieee_vax:					# R2=in, R3=out
	movb	(r2)+, -(sp)			# byte swap longword onto stack
	movb	(r2)+, -(sp)
	movb	(r2)+, -(sp)
	movb	(r2)+, -(sp)
	movl	(sp)+, r0			# pop swapped value -> r0
	extzv	$23, $8, r0, r1			# exponent -> r1
	beql	L10				# zero exponent
	tstl	mapin				# map NaNs on input?
	beql	L9				# no, don't check value
	cmpl	r1, $255			# NaN has exponent 255
	beql	L11				# yes, output vaxnan
L9:
	addw2	$2, r1				# adjust exponent bias
	cmpw	r1, $256			# compare with max VAX exponent
	bgeq	L11				# return VAX-NaN if overflow
	insv	r1, $23, $8, r0			# insert VAX-D exponent
	rotl	$16, r0, (r3)+			# output VAX value
	rsb
L10:
	clrl	(r3)+				# return all 32 bits zero
	rsb
L11:
	moval	vaxnan, r1			# return VAX equiv. of NaN
	movl	(r1)+, (r3)+
	incl	nanin
	rsb