1 |
30 |
unneback |
//
|
2 |
|
|
// $Id: get_op.S,v 1.2 2001-09-27 12:01:22 chris Exp $
|
3 |
|
|
//
|
4 |
|
|
// get_op.sa 3.6 5/19/92
|
5 |
|
|
//
|
6 |
|
|
// get_op.sa 3.5 4/26/91
|
7 |
|
|
//
|
8 |
|
|
// Description: This routine is called by the unsupported format/data
|
9 |
|
|
// type exception handler ('unsupp' - vector 55) and the unimplemented
|
10 |
|
|
// instruction exception handler ('unimp' - vector 11). 'get_op'
|
11 |
|
|
// determines the opclass (0, 2, or 3) and branches to the
|
12 |
|
|
// opclass handler routine. See 68881/2 User's Manual table 4-11
|
13 |
|
|
// for a description of the opclasses.
|
14 |
|
|
//
|
15 |
|
|
// For UNSUPPORTED data/format (exception vector 55) and for
|
16 |
|
|
// UNIMPLEMENTED instructions (exception vector 11) the following
|
17 |
|
|
// applies:
|
18 |
|
|
//
|
19 |
|
|
// - For unnormalized numbers (opclass 0, 2, or 3) the
|
20 |
|
|
// number(s) is normalized and the operand type tag is updated.
|
21 |
|
|
//
|
22 |
|
|
// - For a packed number (opclass 2) the number is unpacked and the
|
23 |
|
|
// operand type tag is updated.
|
24 |
|
|
//
|
25 |
|
|
// - For denormalized numbers (opclass 0 or 2) the number(s) is not
|
26 |
|
|
// changed but passed to the next module. The next module for
|
27 |
|
|
// unimp is do_func, the next module for unsupp is res_func.
|
28 |
|
|
//
|
29 |
|
|
// For UNSUPPORTED data/format (exception vector 55) only the
|
30 |
|
|
// following applies:
|
31 |
|
|
//
|
32 |
|
|
// - If there is a move out with a packed number (opclass 3) the
|
33 |
|
|
// number is packed and written to user memory. For the other
|
34 |
|
|
// opclasses the number(s) are written back to the fsave stack
|
35 |
|
|
// and the instruction is then restored back into the '040. The
|
36 |
|
|
// '040 is then able to complete the instruction.
|
37 |
|
|
//
|
38 |
|
|
// For example:
|
39 |
|
|
// fadd.x fpm,fpn where the fpm contains an unnormalized number.
|
40 |
|
|
// The '040 takes an unsupported data trap and gets to this
|
41 |
|
|
// routine. The number is normalized, put back on the stack and
|
42 |
|
|
// then an frestore is done to restore the instruction back into
|
43 |
|
|
// the '040. The '040 then re-executes the fadd.x fpm,fpn with
|
44 |
|
|
// a normalized number in the source and the instruction is
|
45 |
|
|
// successful.
|
46 |
|
|
//
|
47 |
|
|
// Next consider if in the process of normalizing the un-
|
48 |
|
|
// normalized number it becomes a denormalized number. The
|
49 |
|
|
// routine which converts the unnorm to a norm (called mk_norm)
|
50 |
|
|
// detects this and tags the number as a denorm. The routine
|
51 |
|
|
// res_func sees the denorm tag and converts the denorm to a
|
52 |
|
|
// norm. The instruction is then restored back into the '040
|
53 |
|
|
// which re_executes the instruction.
|
54 |
|
|
//
|
55 |
|
|
//
|
56 |
|
|
// Copyright (C) Motorola, Inc. 1990
|
57 |
|
|
// All Rights Reserved
|
58 |
|
|
//
|
59 |
|
|
// THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
|
60 |
|
|
// The copyright notice above does not evidence any
|
61 |
|
|
// actual or intended publication of such source code.
|
62 |
|
|
|
63 |
|
|
GET_OP: //idnt 2,1 | Motorola 040 Floating Point Software Package
|
64 |
|
|
|
65 |
|
|
|section 8
|
66 |
|
|
|
67 |
|
|
#include "fpsp.defs"
|
68 |
|
|
|
69 |
|
|
.global PIRN,PIRZRM,PIRP
|
70 |
|
|
.global SMALRN,SMALRZRM,SMALRP
|
71 |
|
|
.global BIGRN,BIGRZRM,BIGRP
|
72 |
|
|
|
73 |
|
|
PIRN:
|
74 |
|
|
.long 0x40000000,0xc90fdaa2,0x2168c235 //pi
|
75 |
|
|
PIRZRM:
|
76 |
|
|
.long 0x40000000,0xc90fdaa2,0x2168c234 //pi
|
77 |
|
|
PIRP:
|
78 |
|
|
.long 0x40000000,0xc90fdaa2,0x2168c235 //pi
|
79 |
|
|
|
80 |
|
|
//round to nearest
|
81 |
|
|
SMALRN:
|
82 |
|
|
.long 0x3ffd0000,0x9a209a84,0xfbcff798 //log10(2)
|
83 |
|
|
.long 0x40000000,0xadf85458,0xa2bb4a9a //e
|
84 |
|
|
.long 0x3fff0000,0xb8aa3b29,0x5c17f0bc //log2(e)
|
85 |
|
|
.long 0x3ffd0000,0xde5bd8a9,0x37287195 //log10(e)
|
86 |
|
|
.long 0x00000000,0x00000000,0x00000000 //0.0
|
87 |
|
|
// round to zero;round to negative infinity
|
88 |
|
|
SMALRZRM:
|
89 |
|
|
.long 0x3ffd0000,0x9a209a84,0xfbcff798 //log10(2)
|
90 |
|
|
.long 0x40000000,0xadf85458,0xa2bb4a9a //e
|
91 |
|
|
.long 0x3fff0000,0xb8aa3b29,0x5c17f0bb //log2(e)
|
92 |
|
|
.long 0x3ffd0000,0xde5bd8a9,0x37287195 //log10(e)
|
93 |
|
|
.long 0x00000000,0x00000000,0x00000000 //0.0
|
94 |
|
|
// round to positive infinity
|
95 |
|
|
SMALRP:
|
96 |
|
|
.long 0x3ffd0000,0x9a209a84,0xfbcff799 //log10(2)
|
97 |
|
|
.long 0x40000000,0xadf85458,0xa2bb4a9b //e
|
98 |
|
|
.long 0x3fff0000,0xb8aa3b29,0x5c17f0bc //log2(e)
|
99 |
|
|
.long 0x3ffd0000,0xde5bd8a9,0x37287195 //log10(e)
|
100 |
|
|
.long 0x00000000,0x00000000,0x00000000 //0.0
|
101 |
|
|
|
102 |
|
|
//round to nearest
|
103 |
|
|
BIGRN:
|
104 |
|
|
.long 0x3ffe0000,0xb17217f7,0xd1cf79ac //ln(2)
|
105 |
|
|
.long 0x40000000,0x935d8ddd,0xaaa8ac17 //ln(10)
|
106 |
|
|
.long 0x3fff0000,0x80000000,0x00000000 //10 ^ 0
|
107 |
|
|
|
108 |
|
|
.global PTENRN
|
109 |
|
|
PTENRN:
|
110 |
|
|
.long 0x40020000,0xA0000000,0x00000000 //10 ^ 1
|
111 |
|
|
.long 0x40050000,0xC8000000,0x00000000 //10 ^ 2
|
112 |
|
|
.long 0x400C0000,0x9C400000,0x00000000 //10 ^ 4
|
113 |
|
|
.long 0x40190000,0xBEBC2000,0x00000000 //10 ^ 8
|
114 |
|
|
.long 0x40340000,0x8E1BC9BF,0x04000000 //10 ^ 16
|
115 |
|
|
.long 0x40690000,0x9DC5ADA8,0x2B70B59E //10 ^ 32
|
116 |
|
|
.long 0x40D30000,0xC2781F49,0xFFCFA6D5 //10 ^ 64
|
117 |
|
|
.long 0x41A80000,0x93BA47C9,0x80E98CE0 //10 ^ 128
|
118 |
|
|
.long 0x43510000,0xAA7EEBFB,0x9DF9DE8E //10 ^ 256
|
119 |
|
|
.long 0x46A30000,0xE319A0AE,0xA60E91C7 //10 ^ 512
|
120 |
|
|
.long 0x4D480000,0xC9767586,0x81750C17 //10 ^ 1024
|
121 |
|
|
.long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 //10 ^ 2048
|
122 |
|
|
.long 0x75250000,0xC4605202,0x8A20979B //10 ^ 4096
|
123 |
|
|
//round to minus infinity
|
124 |
|
|
BIGRZRM:
|
125 |
|
|
.long 0x3ffe0000,0xb17217f7,0xd1cf79ab //ln(2)
|
126 |
|
|
.long 0x40000000,0x935d8ddd,0xaaa8ac16 //ln(10)
|
127 |
|
|
.long 0x3fff0000,0x80000000,0x00000000 //10 ^ 0
|
128 |
|
|
|
129 |
|
|
.global PTENRM
|
130 |
|
|
PTENRM:
|
131 |
|
|
.long 0x40020000,0xA0000000,0x00000000 //10 ^ 1
|
132 |
|
|
.long 0x40050000,0xC8000000,0x00000000 //10 ^ 2
|
133 |
|
|
.long 0x400C0000,0x9C400000,0x00000000 //10 ^ 4
|
134 |
|
|
.long 0x40190000,0xBEBC2000,0x00000000 //10 ^ 8
|
135 |
|
|
.long 0x40340000,0x8E1BC9BF,0x04000000 //10 ^ 16
|
136 |
|
|
.long 0x40690000,0x9DC5ADA8,0x2B70B59D //10 ^ 32
|
137 |
|
|
.long 0x40D30000,0xC2781F49,0xFFCFA6D5 //10 ^ 64
|
138 |
|
|
.long 0x41A80000,0x93BA47C9,0x80E98CDF //10 ^ 128
|
139 |
|
|
.long 0x43510000,0xAA7EEBFB,0x9DF9DE8D //10 ^ 256
|
140 |
|
|
.long 0x46A30000,0xE319A0AE,0xA60E91C6 //10 ^ 512
|
141 |
|
|
.long 0x4D480000,0xC9767586,0x81750C17 //10 ^ 1024
|
142 |
|
|
.long 0x5A920000,0x9E8B3B5D,0xC53D5DE5 //10 ^ 2048
|
143 |
|
|
.long 0x75250000,0xC4605202,0x8A20979A //10 ^ 4096
|
144 |
|
|
//round to positive infinity
|
145 |
|
|
BIGRP:
|
146 |
|
|
.long 0x3ffe0000,0xb17217f7,0xd1cf79ac //ln(2)
|
147 |
|
|
.long 0x40000000,0x935d8ddd,0xaaa8ac17 //ln(10)
|
148 |
|
|
.long 0x3fff0000,0x80000000,0x00000000 //10 ^ 0
|
149 |
|
|
|
150 |
|
|
.global PTENRP
|
151 |
|
|
PTENRP:
|
152 |
|
|
.long 0x40020000,0xA0000000,0x00000000 //10 ^ 1
|
153 |
|
|
.long 0x40050000,0xC8000000,0x00000000 //10 ^ 2
|
154 |
|
|
.long 0x400C0000,0x9C400000,0x00000000 //10 ^ 4
|
155 |
|
|
.long 0x40190000,0xBEBC2000,0x00000000 //10 ^ 8
|
156 |
|
|
.long 0x40340000,0x8E1BC9BF,0x04000000 //10 ^ 16
|
157 |
|
|
.long 0x40690000,0x9DC5ADA8,0x2B70B59E //10 ^ 32
|
158 |
|
|
.long 0x40D30000,0xC2781F49,0xFFCFA6D6 //10 ^ 64
|
159 |
|
|
.long 0x41A80000,0x93BA47C9,0x80E98CE0 //10 ^ 128
|
160 |
|
|
.long 0x43510000,0xAA7EEBFB,0x9DF9DE8E //10 ^ 256
|
161 |
|
|
.long 0x46A30000,0xE319A0AE,0xA60E91C7 //10 ^ 512
|
162 |
|
|
.long 0x4D480000,0xC9767586,0x81750C18 //10 ^ 1024
|
163 |
|
|
.long 0x5A920000,0x9E8B3B5D,0xC53D5DE6 //10 ^ 2048
|
164 |
|
|
.long 0x75250000,0xC4605202,0x8A20979B //10 ^ 4096
|
165 |
|
|
|
166 |
|
|
|xref nrm_zero
|
167 |
|
|
|xref decbin
|
168 |
|
|
|xref round
|
169 |
|
|
|
170 |
|
|
.global get_op
|
171 |
|
|
.global uns_getop
|
172 |
|
|
.global uni_getop
|
173 |
|
|
get_op:
|
174 |
|
|
clrb DY_MO_FLG(%a6)
|
175 |
|
|
tstb UFLG_TMP(%a6) //test flag for unsupp/unimp state
|
176 |
|
|
beq uni_getop
|
177 |
|
|
|
178 |
|
|
uns_getop:
|
179 |
|
|
btstb #direction_bit,CMDREG1B(%a6)
|
180 |
|
|
bne opclass3 //branch if a fmove out (any kind)
|
181 |
|
|
btstb #6,CMDREG1B(%a6)
|
182 |
|
|
beqs uns_notpacked
|
183 |
|
|
|
184 |
|
|
bfextu CMDREG1B(%a6){#3:#3},%d0
|
185 |
|
|
cmpb #3,%d0
|
186 |
|
|
beq pack_source //check for a packed src op, branch if so
|
187 |
|
|
uns_notpacked:
|
188 |
|
|
bsr chk_dy_mo //set the dyadic/monadic flag
|
189 |
|
|
tstb DY_MO_FLG(%a6)
|
190 |
|
|
beqs src_op_ck //if monadic, go check src op
|
191 |
|
|
// ;else, check dst op (fall through)
|
192 |
|
|
|
193 |
|
|
btstb #7,DTAG(%a6)
|
194 |
|
|
beqs src_op_ck //if dst op is norm, check src op
|
195 |
|
|
bras dst_ex_dnrm //else, handle destination unnorm/dnrm
|
196 |
|
|
|
197 |
|
|
uni_getop:
|
198 |
|
|
bfextu CMDREG1B(%a6){#0:#6},%d0 //get opclass and src fields
|
199 |
|
|
cmpil #0x17,%d0 //if op class and size fields are $17,
|
200 |
|
|
// ;it is FMOVECR; if not, continue
|
201 |
|
|
//
|
202 |
|
|
// If the instruction is fmovecr, exit get_op. It is handled
|
203 |
|
|
// in do_func and smovecr.sa.
|
204 |
|
|
//
|
205 |
|
|
bne not_fmovecr //handle fmovecr as an unimplemented inst
|
206 |
|
|
rts
|
207 |
|
|
|
208 |
|
|
not_fmovecr:
|
209 |
|
|
btstb #E1,E_BYTE(%a6) //if set, there is a packed operand
|
210 |
|
|
bne pack_source //check for packed src op, branch if so
|
211 |
|
|
|
212 |
|
|
// The following lines of are coded to optimize on normalized operands
|
213 |
|
|
moveb STAG(%a6),%d0
|
214 |
|
|
orb DTAG(%a6),%d0 //check if either of STAG/DTAG msb set
|
215 |
|
|
bmis dest_op_ck //if so, some op needs to be fixed
|
216 |
|
|
rts
|
217 |
|
|
|
218 |
|
|
dest_op_ck:
|
219 |
|
|
btstb #7,DTAG(%a6) //check for unsupported data types in
|
220 |
|
|
beqs src_op_ck //the destination, if not, check src op
|
221 |
|
|
bsr chk_dy_mo //set dyadic/monadic flag
|
222 |
|
|
tstb DY_MO_FLG(%a6) //
|
223 |
|
|
beqs src_op_ck //if monadic, check src op
|
224 |
|
|
//
|
225 |
|
|
// At this point, destination has an extended denorm or unnorm.
|
226 |
|
|
//
|
227 |
|
|
dst_ex_dnrm:
|
228 |
|
|
movew FPTEMP_EX(%a6),%d0 //get destination exponent
|
229 |
|
|
andiw #0x7fff,%d0 //mask sign, check if exp = 0000
|
230 |
|
|
beqs src_op_ck //if denorm then check source op.
|
231 |
|
|
// ;denorms are taken care of in res_func
|
232 |
|
|
// ;(unsupp) or do_func (unimp)
|
233 |
|
|
// ;else unnorm fall through
|
234 |
|
|
leal FPTEMP(%a6),%a0 //point a0 to dop - used in mk_norm
|
235 |
|
|
bsr mk_norm //go normalize - mk_norm returns:
|
236 |
|
|
// ;L_SCR1{7:5} = operand tag
|
237 |
|
|
// ; (000 = norm, 100 = denorm)
|
238 |
|
|
// ;L_SCR1{4} = fpte15 or ete15
|
239 |
|
|
// ; 0 = exp > $3fff
|
240 |
|
|
// ; 1 = exp <= $3fff
|
241 |
|
|
// ;and puts the normalized num back
|
242 |
|
|
// ;on the fsave stack
|
243 |
|
|
//
|
244 |
|
|
moveb L_SCR1(%a6),DTAG(%a6) //write the new tag & fpte15
|
245 |
|
|
// ;to the fsave stack and fall
|
246 |
|
|
// ;through to check source operand
|
247 |
|
|
//
|
248 |
|
|
src_op_ck:
|
249 |
|
|
btstb #7,STAG(%a6)
|
250 |
|
|
beq end_getop //check for unsupported data types on the
|
251 |
|
|
// ;source operand
|
252 |
|
|
btstb #5,STAG(%a6)
|
253 |
|
|
bnes src_sd_dnrm //if bit 5 set, handle sgl/dbl denorms
|
254 |
|
|
//
|
255 |
|
|
// At this point only unnorms or extended denorms are possible.
|
256 |
|
|
//
|
257 |
|
|
src_ex_dnrm:
|
258 |
|
|
movew ETEMP_EX(%a6),%d0 //get source exponent
|
259 |
|
|
andiw #0x7fff,%d0 //mask sign, check if exp = 0000
|
260 |
|
|
beq end_getop //if denorm then exit, denorms are
|
261 |
|
|
// ;handled in do_func
|
262 |
|
|
leal ETEMP(%a6),%a0 //point a0 to sop - used in mk_norm
|
263 |
|
|
bsr mk_norm //go normalize - mk_norm returns:
|
264 |
|
|
// ;L_SCR1{7:5} = operand tag
|
265 |
|
|
// ; (000 = norm, 100 = denorm)
|
266 |
|
|
// ;L_SCR1{4} = fpte15 or ete15
|
267 |
|
|
// ; 0 = exp > $3fff
|
268 |
|
|
// ; 1 = exp <= $3fff
|
269 |
|
|
// ;and puts the normalized num back
|
270 |
|
|
// ;on the fsave stack
|
271 |
|
|
//
|
272 |
|
|
moveb L_SCR1(%a6),STAG(%a6) //write the new tag & ete15
|
273 |
|
|
rts //end_getop
|
274 |
|
|
|
275 |
|
|
//
|
276 |
|
|
// At this point, only single or double denorms are possible.
|
277 |
|
|
// If the inst is not fmove, normalize the source. If it is,
|
278 |
|
|
// do nothing to the input.
|
279 |
|
|
//
|
280 |
|
|
src_sd_dnrm:
|
281 |
|
|
btstb #4,CMDREG1B(%a6) //differentiate between sgl/dbl denorm
|
282 |
|
|
bnes is_double
|
283 |
|
|
is_single:
|
284 |
|
|
movew #0x3f81,%d1 //write bias for sgl denorm
|
285 |
|
|
bras common //goto the common code
|
286 |
|
|
is_double:
|
287 |
|
|
movew #0x3c01,%d1 //write the bias for a dbl denorm
|
288 |
|
|
common:
|
289 |
|
|
btstb #sign_bit,ETEMP_EX(%a6) //grab sign bit of mantissa
|
290 |
|
|
beqs pos
|
291 |
|
|
bset #15,%d1 //set sign bit because it is negative
|
292 |
|
|
pos:
|
293 |
|
|
movew %d1,ETEMP_EX(%a6)
|
294 |
|
|
// ;put exponent on stack
|
295 |
|
|
|
296 |
|
|
movew CMDREG1B(%a6),%d1
|
297 |
|
|
andw #0xe3ff,%d1 //clear out source specifier
|
298 |
|
|
orw #0x0800,%d1 //set source specifier to extended prec
|
299 |
|
|
movew %d1,CMDREG1B(%a6) //write back to the command word in stack
|
300 |
|
|
// ;this is needed to fix unsupp data stack
|
301 |
|
|
leal ETEMP(%a6),%a0 //point a0 to sop
|
302 |
|
|
|
303 |
|
|
bsr mk_norm //convert sgl/dbl denorm to norm
|
304 |
|
|
moveb L_SCR1(%a6),STAG(%a6) //put tag into source tag reg - d0
|
305 |
|
|
rts //end_getop
|
306 |
|
|
//
|
307 |
|
|
// At this point, the source is definitely packed, whether
|
308 |
|
|
// instruction is dyadic or monadic is still unknown
|
309 |
|
|
//
|
310 |
|
|
pack_source:
|
311 |
|
|
movel FPTEMP_LO(%a6),ETEMP(%a6) //write ms part of packed
|
312 |
|
|
// ;number to etemp slot
|
313 |
|
|
bsr chk_dy_mo //set dyadic/monadic flag
|
314 |
|
|
bsr unpack
|
315 |
|
|
|
316 |
|
|
tstb DY_MO_FLG(%a6)
|
317 |
|
|
beqs end_getop //if monadic, exit
|
318 |
|
|
// ;else, fix FPTEMP
|
319 |
|
|
pack_dya:
|
320 |
|
|
bfextu CMDREG1B(%a6){#6:#3},%d0 //extract dest fp reg
|
321 |
|
|
movel #7,%d1
|
322 |
|
|
subl %d0,%d1
|
323 |
|
|
clrl %d0
|
324 |
|
|
bsetl %d1,%d0 //set up d0 as a dynamic register mask
|
325 |
|
|
fmovemx %d0,FPTEMP(%a6) //write to FPTEMP
|
326 |
|
|
|
327 |
|
|
btstb #7,DTAG(%a6) //check dest tag for unnorm or denorm
|
328 |
|
|
bne dst_ex_dnrm //else, handle the unnorm or ext denorm
|
329 |
|
|
//
|
330 |
|
|
// Dest is not denormalized. Check for norm, and set fpte15
|
331 |
|
|
// accordingly.
|
332 |
|
|
//
|
333 |
|
|
moveb DTAG(%a6),%d0
|
334 |
|
|
andib #0xf0,%d0 //strip to only dtag:fpte15
|
335 |
|
|
tstb %d0 //check for normalized value
|
336 |
|
|
bnes end_getop //if inf/nan/zero leave get_op
|
337 |
|
|
movew FPTEMP_EX(%a6),%d0
|
338 |
|
|
andiw #0x7fff,%d0
|
339 |
|
|
cmpiw #0x3fff,%d0 //check if fpte15 needs setting
|
340 |
|
|
bges end_getop //if >= $3fff, leave fpte15=0
|
341 |
|
|
orb #0x10,DTAG(%a6)
|
342 |
|
|
bras end_getop
|
343 |
|
|
|
344 |
|
|
//
|
345 |
|
|
// At this point, it is either an fmoveout packed, unnorm or denorm
|
346 |
|
|
//
|
347 |
|
|
opclass3:
|
348 |
|
|
clrb DY_MO_FLG(%a6) //set dyadic/monadic flag to monadic
|
349 |
|
|
bfextu CMDREG1B(%a6){#4:#2},%d0
|
350 |
|
|
cmpib #3,%d0
|
351 |
|
|
bne src_ex_dnrm //if not equal, must be unnorm or denorm
|
352 |
|
|
// ;else it is a packed move out
|
353 |
|
|
// ;exit
|
354 |
|
|
end_getop:
|
355 |
|
|
rts
|
356 |
|
|
|
357 |
|
|
//
|
358 |
|
|
// Sets the DY_MO_FLG correctly. This is used only on if it is an
|
359 |
|
|
// unsupported data type exception. Set if dyadic.
|
360 |
|
|
//
|
361 |
|
|
chk_dy_mo:
|
362 |
|
|
movew CMDREG1B(%a6),%d0
|
363 |
|
|
btstl #5,%d0 //testing extension command word
|
364 |
|
|
beqs set_mon //if bit 5 = 0 then monadic
|
365 |
|
|
btstl #4,%d0 //know that bit 5 = 1
|
366 |
|
|
beqs set_dya //if bit 4 = 0 then dyadic
|
367 |
|
|
andiw #0x007f,%d0 //get rid of all but extension bits {6:0}
|
368 |
|
|
cmpiw #0x0038,%d0 //if extension = $38 then fcmp (dyadic)
|
369 |
|
|
bnes set_mon
|
370 |
|
|
set_dya:
|
371 |
|
|
st DY_MO_FLG(%a6) //set the inst flag type to dyadic
|
372 |
|
|
rts
|
373 |
|
|
set_mon:
|
374 |
|
|
clrb DY_MO_FLG(%a6) //set the inst flag type to monadic
|
375 |
|
|
rts
|
376 |
|
|
//
|
377 |
|
|
// MK_NORM
|
378 |
|
|
//
|
379 |
|
|
// Normalizes unnormalized numbers, sets tag to norm or denorm, sets unfl
|
380 |
|
|
// exception if denorm.
|
381 |
|
|
//
|
382 |
|
|
// CASE opclass 0x0 unsupp
|
383 |
|
|
// mk_norm till msb set
|
384 |
|
|
// set tag = norm
|
385 |
|
|
//
|
386 |
|
|
// CASE opclass 0x0 unimp
|
387 |
|
|
// mk_norm till msb set or exp = 0
|
388 |
|
|
// if integer bit = 0
|
389 |
|
|
// tag = denorm
|
390 |
|
|
// else
|
391 |
|
|
// tag = norm
|
392 |
|
|
//
|
393 |
|
|
// CASE opclass 011 unsupp
|
394 |
|
|
// mk_norm till msb set or exp = 0
|
395 |
|
|
// if integer bit = 0
|
396 |
|
|
// tag = denorm
|
397 |
|
|
// set unfl_nmcexe = 1
|
398 |
|
|
// else
|
399 |
|
|
// tag = norm
|
400 |
|
|
//
|
401 |
|
|
// if exp <= $3fff
|
402 |
|
|
// set ete15 or fpte15 = 1
|
403 |
|
|
// else set ete15 or fpte15 = 0
|
404 |
|
|
|
405 |
|
|
// input:
|
406 |
|
|
// a0 = points to operand to be normalized
|
407 |
|
|
// output:
|
408 |
|
|
// L_SCR1{7:5} = operand tag (000 = norm, 100 = denorm)
|
409 |
|
|
// L_SCR1{4} = fpte15 or ete15 (0 = exp > $3fff, 1 = exp <=$3fff)
|
410 |
|
|
// the normalized operand is placed back on the fsave stack
|
411 |
|
|
mk_norm:
|
412 |
|
|
clrl L_SCR1(%a6)
|
413 |
|
|
bclrb #sign_bit,LOCAL_EX(%a0)
|
414 |
|
|
sne LOCAL_SGN(%a0) //transform into internal extended format
|
415 |
|
|
|
416 |
|
|
cmpib #0x2c,1+EXC_VEC(%a6) //check if unimp
|
417 |
|
|
bnes uns_data //branch if unsupp
|
418 |
|
|
bsr uni_inst //call if unimp (opclass 0x0)
|
419 |
|
|
bras reload
|
420 |
|
|
uns_data:
|
421 |
|
|
btstb #direction_bit,CMDREG1B(%a6) //check transfer direction
|
422 |
|
|
bnes bit_set //branch if set (opclass 011)
|
423 |
|
|
bsr uns_opx //call if opclass 0x0
|
424 |
|
|
bras reload
|
425 |
|
|
bit_set:
|
426 |
|
|
bsr uns_op3 //opclass 011
|
427 |
|
|
reload:
|
428 |
|
|
cmpw #0x3fff,LOCAL_EX(%a0) //if exp > $3fff
|
429 |
|
|
bgts end_mk // fpte15/ete15 already set to 0
|
430 |
|
|
bsetb #4,L_SCR1(%a6) //else set fpte15/ete15 to 1
|
431 |
|
|
// ;calling routine actually sets the
|
432 |
|
|
// ;value on the stack (along with the
|
433 |
|
|
// ;tag), since this routine doesn't
|
434 |
|
|
// ;know if it should set ete15 or fpte15
|
435 |
|
|
// ;ie, it doesn't know if this is the
|
436 |
|
|
// ;src op or dest op.
|
437 |
|
|
end_mk:
|
438 |
|
|
bfclr LOCAL_SGN(%a0){#0:#8}
|
439 |
|
|
beqs end_mk_pos
|
440 |
|
|
bsetb #sign_bit,LOCAL_EX(%a0) //convert back to IEEE format
|
441 |
|
|
end_mk_pos:
|
442 |
|
|
rts
|
443 |
|
|
//
|
444 |
|
|
// CASE opclass 011 unsupp
|
445 |
|
|
//
|
446 |
|
|
uns_op3:
|
447 |
|
|
bsr nrm_zero //normalize till msb = 1 or exp = zero
|
448 |
|
|
btstb #7,LOCAL_HI(%a0) //if msb = 1
|
449 |
|
|
bnes no_unfl //then branch
|
450 |
|
|
set_unfl:
|
451 |
|
|
orw #dnrm_tag,L_SCR1(%a6) //set denorm tag
|
452 |
|
|
bsetb #unfl_bit,FPSR_EXCEPT(%a6) //set unfl exception bit
|
453 |
|
|
no_unfl:
|
454 |
|
|
rts
|
455 |
|
|
//
|
456 |
|
|
// CASE opclass 0x0 unsupp
|
457 |
|
|
//
|
458 |
|
|
uns_opx:
|
459 |
|
|
bsr nrm_zero //normalize the number
|
460 |
|
|
btstb #7,LOCAL_HI(%a0) //check if integer bit (j-bit) is set
|
461 |
|
|
beqs uns_den //if clear then now have a denorm
|
462 |
|
|
uns_nrm:
|
463 |
|
|
orb #norm_tag,L_SCR1(%a6) //set tag to norm
|
464 |
|
|
rts
|
465 |
|
|
uns_den:
|
466 |
|
|
orb #dnrm_tag,L_SCR1(%a6) //set tag to denorm
|
467 |
|
|
rts
|
468 |
|
|
//
|
469 |
|
|
// CASE opclass 0x0 unimp
|
470 |
|
|
//
|
471 |
|
|
uni_inst:
|
472 |
|
|
bsr nrm_zero
|
473 |
|
|
btstb #7,LOCAL_HI(%a0) //check if integer bit (j-bit) is set
|
474 |
|
|
beqs uni_den //if clear then now have a denorm
|
475 |
|
|
uni_nrm:
|
476 |
|
|
orb #norm_tag,L_SCR1(%a6) //set tag to norm
|
477 |
|
|
rts
|
478 |
|
|
uni_den:
|
479 |
|
|
orb #dnrm_tag,L_SCR1(%a6) //set tag to denorm
|
480 |
|
|
rts
|
481 |
|
|
|
482 |
|
|
//
|
483 |
|
|
// Decimal to binary conversion
|
484 |
|
|
//
|
485 |
|
|
// Special cases of inf and NaNs are completed outside of decbin.
|
486 |
|
|
// If the input is an snan, the snan bit is not set.
|
487 |
|
|
//
|
488 |
|
|
// input:
|
489 |
|
|
// ETEMP(a6) - points to packed decimal string in memory
|
490 |
|
|
// output:
|
491 |
|
|
// fp0 - contains packed string converted to extended precision
|
492 |
|
|
// ETEMP - same as fp0
|
493 |
|
|
unpack:
|
494 |
|
|
movew CMDREG1B(%a6),%d0 //examine command word, looking for fmove's
|
495 |
|
|
andw #0x3b,%d0
|
496 |
|
|
beq move_unpack //special handling for fmove: must set FPSR_CC
|
497 |
|
|
|
498 |
|
|
movew ETEMP(%a6),%d0 //get word with inf information
|
499 |
|
|
bfextu %d0{#20:#12},%d1 //get exponent into d1
|
500 |
|
|
cmpiw #0x0fff,%d1 //test for inf or NaN
|
501 |
|
|
bnes try_zero //if not equal, it is not special
|
502 |
|
|
bfextu %d0{#17:#3},%d1 //get SE and y bits into d1
|
503 |
|
|
cmpiw #7,%d1 //SE and y bits must be on for special
|
504 |
|
|
bnes try_zero //if not on, it is not special
|
505 |
|
|
//input is of the special cases of inf and NaN
|
506 |
|
|
tstl ETEMP_HI(%a6) //check ms mantissa
|
507 |
|
|
bnes fix_nan //if non-zero, it is a NaN
|
508 |
|
|
tstl ETEMP_LO(%a6) //check ls mantissa
|
509 |
|
|
bnes fix_nan //if non-zero, it is a NaN
|
510 |
|
|
bra finish //special already on stack
|
511 |
|
|
fix_nan:
|
512 |
|
|
btstb #signan_bit,ETEMP_HI(%a6) //test for snan
|
513 |
|
|
bne finish
|
514 |
|
|
orl #snaniop_mask,USER_FPSR(%a6) //always set snan if it is so
|
515 |
|
|
bra finish
|
516 |
|
|
try_zero:
|
517 |
|
|
movew ETEMP_EX+2(%a6),%d0 //get word 4
|
518 |
|
|
andiw #0x000f,%d0 //clear all but last ni(y)bble
|
519 |
|
|
tstw %d0 //check for zero.
|
520 |
|
|
bne not_spec
|
521 |
|
|
tstl ETEMP_HI(%a6) //check words 3 and 2
|
522 |
|
|
bne not_spec
|
523 |
|
|
tstl ETEMP_LO(%a6) //check words 1 and 0
|
524 |
|
|
bne not_spec
|
525 |
|
|
tstl ETEMP(%a6) //test sign of the zero
|
526 |
|
|
bges pos_zero
|
527 |
|
|
movel #0x80000000,ETEMP(%a6) //write neg zero to etemp
|
528 |
|
|
clrl ETEMP_HI(%a6)
|
529 |
|
|
clrl ETEMP_LO(%a6)
|
530 |
|
|
bra finish
|
531 |
|
|
pos_zero:
|
532 |
|
|
clrl ETEMP(%a6)
|
533 |
|
|
clrl ETEMP_HI(%a6)
|
534 |
|
|
clrl ETEMP_LO(%a6)
|
535 |
|
|
bra finish
|
536 |
|
|
|
537 |
|
|
not_spec:
|
538 |
|
|
fmovemx %fp0-%fp1,-(%a7) //save fp0 - decbin returns in it
|
539 |
|
|
bsr decbin
|
540 |
|
|
fmovex %fp0,ETEMP(%a6) //put the unpacked sop in the fsave stack
|
541 |
|
|
fmovemx (%a7)+,%fp0-%fp1
|
542 |
|
|
fmovel #0,%FPSR //clr fpsr from decbin
|
543 |
|
|
bra finish
|
544 |
|
|
|
545 |
|
|
//
|
546 |
|
|
// Special handling for packed move in: Same results as all other
|
547 |
|
|
// packed cases, but we must set the FPSR condition codes properly.
|
548 |
|
|
//
|
549 |
|
|
move_unpack:
|
550 |
|
|
movew ETEMP(%a6),%d0 //get word with inf information
|
551 |
|
|
bfextu %d0{#20:#12},%d1 //get exponent into d1
|
552 |
|
|
cmpiw #0x0fff,%d1 //test for inf or NaN
|
553 |
|
|
bnes mtry_zero //if not equal, it is not special
|
554 |
|
|
bfextu %d0{#17:#3},%d1 //get SE and y bits into d1
|
555 |
|
|
cmpiw #7,%d1 //SE and y bits must be on for special
|
556 |
|
|
bnes mtry_zero //if not on, it is not special
|
557 |
|
|
//input is of the special cases of inf and NaN
|
558 |
|
|
tstl ETEMP_HI(%a6) //check ms mantissa
|
559 |
|
|
bnes mfix_nan //if non-zero, it is a NaN
|
560 |
|
|
tstl ETEMP_LO(%a6) //check ls mantissa
|
561 |
|
|
bnes mfix_nan //if non-zero, it is a NaN
|
562 |
|
|
//input is inf
|
563 |
|
|
orl #inf_mask,USER_FPSR(%a6) //set I bit
|
564 |
|
|
tstl ETEMP(%a6) //check sign
|
565 |
|
|
bge finish
|
566 |
|
|
orl #neg_mask,USER_FPSR(%a6) //set N bit
|
567 |
|
|
bra finish //special already on stack
|
568 |
|
|
mfix_nan:
|
569 |
|
|
orl #nan_mask,USER_FPSR(%a6) //set NaN bit
|
570 |
|
|
moveb #nan_tag,STAG(%a6) //set stag to NaN
|
571 |
|
|
btstb #signan_bit,ETEMP_HI(%a6) //test for snan
|
572 |
|
|
bnes mn_snan
|
573 |
|
|
orl #snaniop_mask,USER_FPSR(%a6) //set snan bit
|
574 |
|
|
btstb #snan_bit,FPCR_ENABLE(%a6) //test for snan enabled
|
575 |
|
|
bnes mn_snan
|
576 |
|
|
bsetb #signan_bit,ETEMP_HI(%a6) //force snans to qnans
|
577 |
|
|
mn_snan:
|
578 |
|
|
tstl ETEMP(%a6) //check for sign
|
579 |
|
|
bge finish //if clr, go on
|
580 |
|
|
orl #neg_mask,USER_FPSR(%a6) //set N bit
|
581 |
|
|
bra finish
|
582 |
|
|
|
583 |
|
|
mtry_zero:
|
584 |
|
|
movew ETEMP_EX+2(%a6),%d0 //get word 4
|
585 |
|
|
andiw #0x000f,%d0 //clear all but last ni(y)bble
|
586 |
|
|
tstw %d0 //check for zero.
|
587 |
|
|
bnes mnot_spec
|
588 |
|
|
tstl ETEMP_HI(%a6) //check words 3 and 2
|
589 |
|
|
bnes mnot_spec
|
590 |
|
|
tstl ETEMP_LO(%a6) //check words 1 and 0
|
591 |
|
|
bnes mnot_spec
|
592 |
|
|
tstl ETEMP(%a6) //test sign of the zero
|
593 |
|
|
bges mpos_zero
|
594 |
|
|
orl #neg_mask+z_mask,USER_FPSR(%a6) //set N and Z
|
595 |
|
|
movel #0x80000000,ETEMP(%a6) //write neg zero to etemp
|
596 |
|
|
clrl ETEMP_HI(%a6)
|
597 |
|
|
clrl ETEMP_LO(%a6)
|
598 |
|
|
bras finish
|
599 |
|
|
mpos_zero:
|
600 |
|
|
orl #z_mask,USER_FPSR(%a6) //set Z
|
601 |
|
|
clrl ETEMP(%a6)
|
602 |
|
|
clrl ETEMP_HI(%a6)
|
603 |
|
|
clrl ETEMP_LO(%a6)
|
604 |
|
|
bras finish
|
605 |
|
|
|
606 |
|
|
mnot_spec:
|
607 |
|
|
fmovemx %fp0-%fp1,-(%a7) //save fp0 ,fp1 - decbin returns in fp0
|
608 |
|
|
bsr decbin
|
609 |
|
|
fmovex %fp0,ETEMP(%a6)
|
610 |
|
|
// ;put the unpacked sop in the fsave stack
|
611 |
|
|
fmovemx (%a7)+,%fp0-%fp1
|
612 |
|
|
|
613 |
|
|
finish:
|
614 |
|
|
movew CMDREG1B(%a6),%d0 //get the command word
|
615 |
|
|
andw #0xfbff,%d0 //change the source specifier field to
|
616 |
|
|
// ;extended (was packed).
|
617 |
|
|
movew %d0,CMDREG1B(%a6) //write command word back to fsave stack
|
618 |
|
|
// ;we need to do this so the 040 will
|
619 |
|
|
// ;re-execute the inst. without taking
|
620 |
|
|
// ;another packed trap.
|
621 |
|
|
|
622 |
|
|
fix_stag:
|
623 |
|
|
//Converted result is now in etemp on fsave stack, now set the source
|
624 |
|
|
//tag (stag)
|
625 |
|
|
// if (ete =$7fff) then INF or NAN
|
626 |
|
|
// if (etemp = $x.0----0) then
|
627 |
|
|
// stag = INF
|
628 |
|
|
// else
|
629 |
|
|
// stag = NAN
|
630 |
|
|
// else
|
631 |
|
|
// if (ete = $0000) then
|
632 |
|
|
// stag = ZERO
|
633 |
|
|
// else
|
634 |
|
|
// stag = NORM
|
635 |
|
|
//
|
636 |
|
|
// Note also that the etemp_15 bit (just right of the stag) must
|
637 |
|
|
// be set accordingly.
|
638 |
|
|
//
|
639 |
|
|
movew ETEMP_EX(%a6),%d1
|
640 |
|
|
andiw #0x7fff,%d1 //strip sign
|
641 |
|
|
cmpw #0x7fff,%d1
|
642 |
|
|
bnes z_or_nrm
|
643 |
|
|
movel ETEMP_HI(%a6),%d1
|
644 |
|
|
bnes is_nan
|
645 |
|
|
movel ETEMP_LO(%a6),%d1
|
646 |
|
|
bnes is_nan
|
647 |
|
|
is_inf:
|
648 |
|
|
moveb #0x40,STAG(%a6)
|
649 |
|
|
movel #0x40,%d0
|
650 |
|
|
rts
|
651 |
|
|
is_nan:
|
652 |
|
|
moveb #0x60,STAG(%a6)
|
653 |
|
|
movel #0x60,%d0
|
654 |
|
|
rts
|
655 |
|
|
z_or_nrm:
|
656 |
|
|
tstw %d1
|
657 |
|
|
bnes is_nrm
|
658 |
|
|
is_zro:
|
659 |
|
|
// For a zero, set etemp_15
|
660 |
|
|
moveb #0x30,STAG(%a6)
|
661 |
|
|
movel #0x20,%d0
|
662 |
|
|
rts
|
663 |
|
|
is_nrm:
|
664 |
|
|
// For a norm, check if the exp <= $3fff; if so, set etemp_15
|
665 |
|
|
cmpiw #0x3fff,%d1
|
666 |
|
|
bles set_bit15
|
667 |
|
|
moveb #0,STAG(%a6)
|
668 |
|
|
bras end_is_nrm
|
669 |
|
|
set_bit15:
|
670 |
|
|
moveb #0x10,STAG(%a6)
|
671 |
|
|
end_is_nrm:
|
672 |
|
|
movel #0,%d0
|
673 |
|
|
end_fix:
|
674 |
|
|
rts
|
675 |
|
|
|
676 |
|
|
end_get:
|
677 |
|
|
rts
|
678 |
|
|
|end
|