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
|