Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/m68k/fpsp040/x_store.S
10817 views
1
|
2
| x_store.sa 3.2 1/24/91
3
|
4
| store --- store operand to memory or register
5
|
6
| Used by underflow and overflow handlers.
7
|
8
| a6 = points to fp value to be stored.
9
|
10
11
| Copyright (C) Motorola, Inc. 1990
12
| All Rights Reserved
13
|
14
| For details on the license for this file, please see the
15
| file, README, in this same directory.
16
17
X_STORE: |idnt 2,1 | Motorola 040 Floating Point Software Package
18
19
|section 8
20
21
fpreg_mask:
22
.byte 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01
23
24
#include "fpsp.h"
25
26
|xref mem_write
27
|xref get_fline
28
|xref g_opcls
29
|xref g_dfmtou
30
|xref reg_dest
31
32
.global dest_ext
33
.global dest_dbl
34
.global dest_sgl
35
36
.global store
37
store:
38
btstb #E3,E_BYTE(%a6)
39
beqs E1_sto
40
E3_sto:
41
movel CMDREG3B(%a6),%d0
42
bfextu %d0{#6:#3},%d0 |isolate dest. reg from cmdreg3b
43
sto_fp:
44
lea fpreg_mask,%a1
45
moveb (%a1,%d0.w),%d0 |convert reg# to dynamic register mask
46
tstb LOCAL_SGN(%a0)
47
beqs is_pos
48
bsetb #sign_bit,LOCAL_EX(%a0)
49
is_pos:
50
fmovemx (%a0),%d0 |move to correct register
51
|
52
| if fp0-fp3 is being modified, we must put a copy
53
| in the USER_FPn variable on the stack because all exception
54
| handlers restore fp0-fp3 from there.
55
|
56
cmpb #0x80,%d0
57
bnes not_fp0
58
fmovemx %fp0-%fp0,USER_FP0(%a6)
59
rts
60
not_fp0:
61
cmpb #0x40,%d0
62
bnes not_fp1
63
fmovemx %fp1-%fp1,USER_FP1(%a6)
64
rts
65
not_fp1:
66
cmpb #0x20,%d0
67
bnes not_fp2
68
fmovemx %fp2-%fp2,USER_FP2(%a6)
69
rts
70
not_fp2:
71
cmpb #0x10,%d0
72
bnes not_fp3
73
fmovemx %fp3-%fp3,USER_FP3(%a6)
74
rts
75
not_fp3:
76
rts
77
78
E1_sto:
79
bsrl g_opcls |returns opclass in d0
80
cmpib #3,%d0
81
beq opc011 |branch if opclass 3
82
movel CMDREG1B(%a6),%d0
83
bfextu %d0{#6:#3},%d0 |extract destination register
84
bras sto_fp
85
86
opc011:
87
bsrl g_dfmtou |returns dest format in d0
88
| ;ext=00, sgl=01, dbl=10
89
movel %a0,%a1 |save source addr in a1
90
movel EXC_EA(%a6),%a0 |get the address
91
cmpil #0,%d0 |if dest format is extended
92
beq dest_ext |then branch
93
cmpil #1,%d0 |if dest format is single
94
beq dest_sgl |then branch
95
|
96
| fall through to dest_dbl
97
|
98
99
|
100
| dest_dbl --- write double precision value to user space
101
|
102
|Input
103
| a0 -> destination address
104
| a1 -> source in extended precision
105
|Output
106
| a0 -> destroyed
107
| a1 -> destroyed
108
| d0 -> 0
109
|
110
|Changes extended precision to double precision.
111
| Note: no attempt is made to round the extended value to double.
112
| dbl_sign = ext_sign
113
| dbl_exp = ext_exp - $3fff(ext bias) + $7ff(dbl bias)
114
| get rid of ext integer bit
115
| dbl_mant = ext_mant{62:12}
116
|
117
| --------------- --------------- ---------------
118
| extended -> |s| exp | |1| ms mant | | ls mant |
119
| --------------- --------------- ---------------
120
| 95 64 63 62 32 31 11 0
121
| | |
122
| | |
123
| | |
124
| v v
125
| --------------- ---------------
126
| double -> |s|exp| mant | | mant |
127
| --------------- ---------------
128
| 63 51 32 31 0
129
|
130
dest_dbl:
131
clrl %d0 |clear d0
132
movew LOCAL_EX(%a1),%d0 |get exponent
133
subw #0x3fff,%d0 |subtract extended precision bias
134
cmpw #0x4000,%d0 |check if inf
135
beqs inf |if so, special case
136
addw #0x3ff,%d0 |add double precision bias
137
swap %d0 |d0 now in upper word
138
lsll #4,%d0 |d0 now in proper place for dbl prec exp
139
tstb LOCAL_SGN(%a1)
140
beqs get_mant |if positive, go process mantissa
141
bsetl #31,%d0 |if negative, put in sign information
142
| ; before continuing
143
bras get_mant |go process mantissa
144
inf:
145
movel #0x7ff00000,%d0 |load dbl inf exponent
146
clrl LOCAL_HI(%a1) |clear msb
147
tstb LOCAL_SGN(%a1)
148
beqs dbl_inf |if positive, go ahead and write it
149
bsetl #31,%d0 |if negative put in sign information
150
dbl_inf:
151
movel %d0,LOCAL_EX(%a1) |put the new exp back on the stack
152
bras dbl_wrt
153
get_mant:
154
movel LOCAL_HI(%a1),%d1 |get ms mantissa
155
bfextu %d1{#1:#20},%d1 |get upper 20 bits of ms
156
orl %d1,%d0 |put these bits in ms word of double
157
movel %d0,LOCAL_EX(%a1) |put the new exp back on the stack
158
movel LOCAL_HI(%a1),%d1 |get ms mantissa
159
movel #21,%d0 |load shift count
160
lsll %d0,%d1 |put lower 11 bits in upper bits
161
movel %d1,LOCAL_HI(%a1) |build lower lword in memory
162
movel LOCAL_LO(%a1),%d1 |get ls mantissa
163
bfextu %d1{#0:#21},%d0 |get ls 21 bits of double
164
orl %d0,LOCAL_HI(%a1) |put them in double result
165
dbl_wrt:
166
movel #0x8,%d0 |byte count for double precision number
167
exg %a0,%a1 |a0=supervisor source, a1=user dest
168
bsrl mem_write |move the number to the user's memory
169
rts
170
|
171
| dest_sgl --- write single precision value to user space
172
|
173
|Input
174
| a0 -> destination address
175
| a1 -> source in extended precision
176
|
177
|Output
178
| a0 -> destroyed
179
| a1 -> destroyed
180
| d0 -> 0
181
|
182
|Changes extended precision to single precision.
183
| sgl_sign = ext_sign
184
| sgl_exp = ext_exp - $3fff(ext bias) + $7f(sgl bias)
185
| get rid of ext integer bit
186
| sgl_mant = ext_mant{62:12}
187
|
188
| --------------- --------------- ---------------
189
| extended -> |s| exp | |1| ms mant | | ls mant |
190
| --------------- --------------- ---------------
191
| 95 64 63 62 40 32 31 12 0
192
| | |
193
| | |
194
| | |
195
| v v
196
| ---------------
197
| single -> |s|exp| mant |
198
| ---------------
199
| 31 22 0
200
|
201
dest_sgl:
202
clrl %d0
203
movew LOCAL_EX(%a1),%d0 |get exponent
204
subw #0x3fff,%d0 |subtract extended precision bias
205
cmpw #0x4000,%d0 |check if inf
206
beqs sinf |if so, special case
207
addw #0x7f,%d0 |add single precision bias
208
swap %d0 |put exp in upper word of d0
209
lsll #7,%d0 |shift it into single exp bits
210
tstb LOCAL_SGN(%a1)
211
beqs get_sman |if positive, continue
212
bsetl #31,%d0 |if negative, put in sign first
213
bras get_sman |get mantissa
214
sinf:
215
movel #0x7f800000,%d0 |load single inf exp to d0
216
tstb LOCAL_SGN(%a1)
217
beqs sgl_wrt |if positive, continue
218
bsetl #31,%d0 |if negative, put in sign info
219
bras sgl_wrt
220
221
get_sman:
222
movel LOCAL_HI(%a1),%d1 |get ms mantissa
223
bfextu %d1{#1:#23},%d1 |get upper 23 bits of ms
224
orl %d1,%d0 |put these bits in ms word of single
225
226
sgl_wrt:
227
movel %d0,L_SCR1(%a6) |put the new exp back on the stack
228
movel #0x4,%d0 |byte count for single precision number
229
tstl %a0 |users destination address
230
beqs sgl_Dn |destination is a data register
231
exg %a0,%a1 |a0=supervisor source, a1=user dest
232
leal L_SCR1(%a6),%a0 |point a0 to data
233
bsrl mem_write |move the number to the user's memory
234
rts
235
sgl_Dn:
236
bsrl get_fline |returns fline word in d0
237
andw #0x7,%d0 |isolate register number
238
movel %d0,%d1 |d1 has size:reg formatted for reg_dest
239
orl #0x10,%d1 |reg_dest wants size added to reg#
240
bral reg_dest |size is X, rts in reg_dest will
241
| ;return to caller of dest_sgl
242
243
dest_ext:
244
tstb LOCAL_SGN(%a1) |put back sign into exponent word
245
beqs dstx_cont
246
bsetb #sign_bit,LOCAL_EX(%a1)
247
dstx_cont:
248
clrb LOCAL_SGN(%a1) |clear out the sign byte
249
250
movel #0x0c,%d0 |byte count for extended number
251
exg %a0,%a1 |a0=supervisor source, a1=user dest
252
bsrl mem_write |move the number to the user's memory
253
rts
254
255
|end
256
257