OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [m68k/] [fpsp040/] [do_func.S] - Blame information for rev 199

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
|
2
|       do_func.sa 3.4 2/18/91
3
|
4
| Do_func performs the unimplemented operation.  The operation
5
| to be performed is determined from the lower 7 bits of the
6
| extension word (except in the case of fmovecr and fsincos).
7
| The opcode and tag bits form an index into a jump table in
8
| tbldo.sa.  Cases of zero, infinity and NaN are handled in
9
| do_func by forcing the default result.  Normalized and
10
| denormalized (there are no unnormalized numbers at this
11
| point) are passed onto the emulation code.
12
|
13
| CMDREG1B and STAG are extracted from the fsave frame
14
| and combined to form the table index.  The function called
15
| will start with a0 pointing to the ETEMP operand.  Dyadic
16
| functions can find FPTEMP at -12(a0).
17
|
18
| Called functions return their result in fp0.  Sincos returns
19
| sin(x) in fp0 and cos(x) in fp1.
20
|
21
 
22
|               Copyright (C) Motorola, Inc. 1990
23
|                       All Rights Reserved
24
|
25
|       THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
26
|       The copyright notice above does not evidence any
27
|       actual or intended publication of such source code.
28
 
29
DO_FUNC:        |idnt    2,1 | Motorola 040 Floating Point Software Package
30
 
31
        |section        8
32
 
33
        .include "fpsp.h"
34
 
35
        |xref   t_dz2
36
        |xref   t_operr
37
        |xref   t_inx2
38
        |xref   t_resdnrm
39
        |xref   dst_nan
40
        |xref   src_nan
41
        |xref   nrm_set
42
        |xref   sto_cos
43
 
44
        |xref   tblpre
45
        |xref   slognp1,slogn,slog10,slog2
46
        |xref   slognd,slog10d,slog2d
47
        |xref   smod,srem
48
        |xref   sscale
49
        |xref   smovcr
50
 
51
PONE:   .long   0x3fff0000,0x80000000,0x00000000        |+1
52
MONE:   .long   0xbfff0000,0x80000000,0x00000000        |-1
53
PZERO:  .long   0x00000000,0x00000000,0x00000000        |+0
54
MZERO:  .long   0x80000000,0x00000000,0x00000000        |-0
55
PINF:   .long   0x7fff0000,0x00000000,0x00000000        |+inf
56
MINF:   .long   0xffff0000,0x00000000,0x00000000        |-inf
57
QNAN:   .long   0x7fff0000,0xffffffff,0xffffffff        |non-signaling nan
58
PPIBY2:  .long  0x3FFF0000,0xC90FDAA2,0x2168C235        |+PI/2
59
MPIBY2:  .long  0xbFFF0000,0xC90FDAA2,0x2168C235        |-PI/2
60
 
61
        .global do_func
62
do_func:
63
        clrb    CU_ONLY(%a6)
64
|
65
| Check for fmovecr.  It does not follow the format of fp gen
66
| unimplemented instructions.  The test is on the upper 6 bits;
67
| if they are $17, the inst is fmovecr.  Call entry smovcr
68
| directly.
69
|
70
        bfextu  CMDREG1B(%a6){#0:#6},%d0 |get opclass and src fields
71
        cmpil   #0x17,%d0               |if op class and size fields are $17,
72
|                               ;it is FMOVECR; if not, continue
73
        bnes    not_fmovecr
74
        jmp     smovcr          |fmovecr; jmp directly to emulation
75
 
76
not_fmovecr:
77
        movew   CMDREG1B(%a6),%d0
78
        andl    #0x7F,%d0
79
        cmpil   #0x38,%d0               |if the extension is >= $38,
80
        bges    serror          |it is illegal
81
        bfextu  STAG(%a6){#0:#3},%d1
82
        lsll    #3,%d0          |make room for STAG
83
        addl    %d1,%d0         |combine for final index into table
84
        leal    tblpre,%a1      |start of monster jump table
85
        movel   (%a1,%d0.w*4),%a1       |real target address
86
        leal    ETEMP(%a6),%a0  |a0 is pointer to src op
87
        movel   USER_FPCR(%a6),%d1
88
        andl    #0xFF,%d1               | discard all but rounding mode/prec
89
        fmovel  #0,%fpcr
90
        jmp     (%a1)
91
|
92
|       ERROR
93
|
94
        .global serror
95
serror:
96
        st      STORE_FLG(%a6)
97
        rts
98
|
99
| These routines load forced values into fp0.  They are called
100
| by index into tbldo.
101
|
102
| Load a signed zero to fp0 and set inex2/ainex
103
|
104
        .global snzrinx
105
snzrinx:
106
        btstb   #sign_bit,LOCAL_EX(%a0) |get sign of source operand
107
        bnes    ld_mzinx        |if negative, branch
108
        bsr     ld_pzero        |bsr so we can return and set inx
109
        bra     t_inx2          |now, set the inx for the next inst
110
ld_mzinx:
111
        bsr     ld_mzero        |if neg, load neg zero, return here
112
        bra     t_inx2          |now, set the inx for the next inst
113
|
114
| Load a signed zero to fp0; do not set inex2/ainex
115
|
116
        .global szero
117
szero:
118
        btstb   #sign_bit,LOCAL_EX(%a0) |get sign of source operand
119
        bne     ld_mzero        |if neg, load neg zero
120
        bra     ld_pzero        |load positive zero
121
|
122
| Load a signed infinity to fp0; do not set inex2/ainex
123
|
124
        .global sinf
125
sinf:
126
        btstb   #sign_bit,LOCAL_EX(%a0) |get sign of source operand
127
        bne     ld_minf                 |if negative branch
128
        bra     ld_pinf
129
|
130
| Load a signed one to fp0; do not set inex2/ainex
131
|
132
        .global sone
133
sone:
134
        btstb   #sign_bit,LOCAL_EX(%a0) |check sign of source
135
        bne     ld_mone
136
        bra     ld_pone
137
|
138
| Load a signed pi/2 to fp0; do not set inex2/ainex
139
|
140
        .global spi_2
141
spi_2:
142
        btstb   #sign_bit,LOCAL_EX(%a0) |check sign of source
143
        bne     ld_mpi2
144
        bra     ld_ppi2
145
|
146
| Load either a +0 or +inf for plus/minus operand
147
|
148
        .global szr_inf
149
szr_inf:
150
        btstb   #sign_bit,LOCAL_EX(%a0) |check sign of source
151
        bne     ld_pzero
152
        bra     ld_pinf
153
|
154
| Result is either an operr or +inf for plus/minus operand
155
| [Used by slogn, slognp1, slog10, and slog2]
156
|
157
        .global sopr_inf
158
sopr_inf:
159
        btstb   #sign_bit,LOCAL_EX(%a0) |check sign of source
160
        bne     t_operr
161
        bra     ld_pinf
162
|
163
|       FLOGNP1
164
|
165
        .global sslognp1
166
sslognp1:
167
        fmovemx (%a0),%fp0-%fp0
168
        fcmpb   #-1,%fp0
169
        fbgt    slognp1
170
        fbeq    t_dz2           |if = -1, divide by zero exception
171
        fmovel  #0,%FPSR                |clr N flag
172
        bra     t_operr         |take care of operands < -1
173
|
174
|       FETOXM1
175
|
176
        .global setoxm1i
177
setoxm1i:
178
        btstb   #sign_bit,LOCAL_EX(%a0) |check sign of source
179
        bne     ld_mone
180
        bra     ld_pinf
181
|
182
|       FLOGN
183
|
184
| Test for 1.0 as an input argument, returning +zero.  Also check
185
| the sign and return operr if negative.
186
|
187
        .global sslogn
188
sslogn:
189
        btstb   #sign_bit,LOCAL_EX(%a0)
190
        bne     t_operr         |take care of operands < 0
191
        cmpiw   #0x3fff,LOCAL_EX(%a0) |test for 1.0 input
192
        bne     slogn
193
        cmpil   #0x80000000,LOCAL_HI(%a0)
194
        bne     slogn
195
        tstl    LOCAL_LO(%a0)
196
        bne     slogn
197
        fmovex  PZERO,%fp0
198
        rts
199
 
200
        .global sslognd
201
sslognd:
202
        btstb   #sign_bit,LOCAL_EX(%a0)
203
        beq     slognd
204
        bra     t_operr         |take care of operands < 0
205
 
206
|
207
|       FLOG10
208
|
209
        .global sslog10
210
sslog10:
211
        btstb   #sign_bit,LOCAL_EX(%a0)
212
        bne     t_operr         |take care of operands < 0
213
        cmpiw   #0x3fff,LOCAL_EX(%a0) |test for 1.0 input
214
        bne     slog10
215
        cmpil   #0x80000000,LOCAL_HI(%a0)
216
        bne     slog10
217
        tstl    LOCAL_LO(%a0)
218
        bne     slog10
219
        fmovex  PZERO,%fp0
220
        rts
221
 
222
        .global sslog10d
223
sslog10d:
224
        btstb   #sign_bit,LOCAL_EX(%a0)
225
        beq     slog10d
226
        bra     t_operr         |take care of operands < 0
227
 
228
|
229
|       FLOG2
230
|
231
        .global sslog2
232
sslog2:
233
        btstb   #sign_bit,LOCAL_EX(%a0)
234
        bne     t_operr         |take care of operands < 0
235
        cmpiw   #0x3fff,LOCAL_EX(%a0) |test for 1.0 input
236
        bne     slog2
237
        cmpil   #0x80000000,LOCAL_HI(%a0)
238
        bne     slog2
239
        tstl    LOCAL_LO(%a0)
240
        bne     slog2
241
        fmovex  PZERO,%fp0
242
        rts
243
 
244
        .global sslog2d
245
sslog2d:
246
        btstb   #sign_bit,LOCAL_EX(%a0)
247
        beq     slog2d
248
        bra     t_operr         |take care of operands < 0
249
 
250
|
251
|       FMOD
252
|
253
pmodt:
254
|                               ;$21 fmod
255
|                               ;dtag,stag
256
        .long   smod            |  00,00  norm,norm = normal
257
        .long   smod_oper       |  00,01  norm,zero = nan with operr
258
        .long   smod_fpn        |  00,10  norm,inf  = fpn
259
        .long   smod_snan       |  00,11  norm,nan  = nan
260
        .long   smod_zro        |  01,00  zero,norm = +-zero
261
        .long   smod_oper       |  01,01  zero,zero = nan with operr
262
        .long   smod_zro        |  01,10  zero,inf  = +-zero
263
        .long   smod_snan       |  01,11  zero,nan  = nan
264
        .long   smod_oper       |  10,00  inf,norm  = nan with operr
265
        .long   smod_oper       |  10,01  inf,zero  = nan with operr
266
        .long   smod_oper       |  10,10  inf,inf   = nan with operr
267
        .long   smod_snan       |  10,11  inf,nan   = nan
268
        .long   smod_dnan       |  11,00  nan,norm  = nan
269
        .long   smod_dnan       |  11,01  nan,zero  = nan
270
        .long   smod_dnan       |  11,10  nan,inf   = nan
271
        .long   smod_dnan       |  11,11  nan,nan   = nan
272
 
273
        .global pmod
274
pmod:
275
        clrb    FPSR_QBYTE(%a6) | clear quotient field
276
        bfextu  STAG(%a6){#0:#3},%d0 |stag = d0
277
        bfextu  DTAG(%a6){#0:#3},%d1 |dtag = d1
278
 
279
|
280
| Alias extended denorms to norms for the jump table.
281
|
282
        bclrl   #2,%d0
283
        bclrl   #2,%d1
284
 
285
        lslb    #2,%d1
286
        orb     %d0,%d1         |d1{3:2} = dtag, d1{1:0} = stag
287
|                               ;Tag values:
288
|                               ;00 = norm or denorm
289
|                               ;01 = zero
290
|                               ;10 = inf
291
|                               ;11 = nan
292
        lea     pmodt,%a1
293
        movel   (%a1,%d1.w*4),%a1
294
        jmp     (%a1)
295
 
296
smod_snan:
297
        bra     src_nan
298
smod_dnan:
299
        bra     dst_nan
300
smod_oper:
301
        bra     t_operr
302
smod_zro:
303
        moveb   ETEMP(%a6),%d1  |get sign of src op
304
        moveb   FPTEMP(%a6),%d0 |get sign of dst op
305
        eorb    %d0,%d1         |get exor of sign bits
306
        btstl   #7,%d1          |test for sign
307
        beqs    smod_zsn        |if clr, do not set sign big
308
        bsetb   #q_sn_bit,FPSR_QBYTE(%a6) |set q-byte sign bit
309
smod_zsn:
310
        btstl   #7,%d0          |test if + or -
311
        beq     ld_pzero        |if pos then load +0
312
        bra     ld_mzero        |else neg load -0
313
 
314
smod_fpn:
315
        moveb   ETEMP(%a6),%d1  |get sign of src op
316
        moveb   FPTEMP(%a6),%d0 |get sign of dst op
317
        eorb    %d0,%d1         |get exor of sign bits
318
        btstl   #7,%d1          |test for sign
319
        beqs    smod_fsn        |if clr, do not set sign big
320
        bsetb   #q_sn_bit,FPSR_QBYTE(%a6) |set q-byte sign bit
321
smod_fsn:
322
        tstb    DTAG(%a6)       |filter out denormal destination case
323
        bpls    smod_nrm        |
324
        leal    FPTEMP(%a6),%a0 |a0<- addr(FPTEMP)
325
        bra     t_resdnrm       |force UNFL(but exact) result
326
smod_nrm:
327
        fmovel USER_FPCR(%a6),%fpcr |use user's rmode and precision
328
        fmovex FPTEMP(%a6),%fp0 |return dest to fp0
329
        rts
330
 
331
|
332
|       FREM
333
|
334
premt:
335
|                               ;$25 frem
336
|                               ;dtag,stag
337
        .long   srem            |  00,00  norm,norm = normal
338
        .long   srem_oper       |  00,01  norm,zero = nan with operr
339
        .long   srem_fpn        |  00,10  norm,inf  = fpn
340
        .long   srem_snan       |  00,11  norm,nan  = nan
341
        .long   srem_zro        |  01,00  zero,norm = +-zero
342
        .long   srem_oper       |  01,01  zero,zero = nan with operr
343
        .long   srem_zro        |  01,10  zero,inf  = +-zero
344
        .long   srem_snan       |  01,11  zero,nan  = nan
345
        .long   srem_oper       |  10,00  inf,norm  = nan with operr
346
        .long   srem_oper       |  10,01  inf,zero  = nan with operr
347
        .long   srem_oper       |  10,10  inf,inf   = nan with operr
348
        .long   srem_snan       |  10,11  inf,nan   = nan
349
        .long   srem_dnan       |  11,00  nan,norm  = nan
350
        .long   srem_dnan       |  11,01  nan,zero  = nan
351
        .long   srem_dnan       |  11,10  nan,inf   = nan
352
        .long   srem_dnan       |  11,11  nan,nan   = nan
353
 
354
        .global prem
355
prem:
356
        clrb    FPSR_QBYTE(%a6)   |clear quotient field
357
        bfextu  STAG(%a6){#0:#3},%d0 |stag = d0
358
        bfextu  DTAG(%a6){#0:#3},%d1 |dtag = d1
359
|
360
| Alias extended denorms to norms for the jump table.
361
|
362
        bclr    #2,%d0
363
        bclr    #2,%d1
364
 
365
        lslb    #2,%d1
366
        orb     %d0,%d1         |d1{3:2} = dtag, d1{1:0} = stag
367
|                               ;Tag values:
368
|                               ;00 = norm or denorm
369
|                               ;01 = zero
370
|                               ;10 = inf
371
|                               ;11 = nan
372
        lea     premt,%a1
373
        movel   (%a1,%d1.w*4),%a1
374
        jmp     (%a1)
375
 
376
srem_snan:
377
        bra     src_nan
378
srem_dnan:
379
        bra     dst_nan
380
srem_oper:
381
        bra     t_operr
382
srem_zro:
383
        moveb   ETEMP(%a6),%d1  |get sign of src op
384
        moveb   FPTEMP(%a6),%d0 |get sign of dst op
385
        eorb    %d0,%d1         |get exor of sign bits
386
        btstl   #7,%d1          |test for sign
387
        beqs    srem_zsn        |if clr, do not set sign big
388
        bsetb   #q_sn_bit,FPSR_QBYTE(%a6) |set q-byte sign bit
389
srem_zsn:
390
        btstl   #7,%d0          |test if + or -
391
        beq     ld_pzero        |if pos then load +0
392
        bra     ld_mzero        |else neg load -0
393
 
394
srem_fpn:
395
        moveb   ETEMP(%a6),%d1  |get sign of src op
396
        moveb   FPTEMP(%a6),%d0 |get sign of dst op
397
        eorb    %d0,%d1         |get exor of sign bits
398
        btstl   #7,%d1          |test for sign
399
        beqs    srem_fsn        |if clr, do not set sign big
400
        bsetb   #q_sn_bit,FPSR_QBYTE(%a6) |set q-byte sign bit
401
srem_fsn:
402
        tstb    DTAG(%a6)       |filter out denormal destination case
403
        bpls    srem_nrm        |
404
        leal    FPTEMP(%a6),%a0 |a0<- addr(FPTEMP)
405
        bra     t_resdnrm       |force UNFL(but exact) result
406
srem_nrm:
407
        fmovel USER_FPCR(%a6),%fpcr |use user's rmode and precision
408
        fmovex FPTEMP(%a6),%fp0 |return dest to fp0
409
        rts
410
|
411
|       FSCALE
412
|
413
pscalet:
414
|                               ;$26 fscale
415
|                               ;dtag,stag
416
        .long   sscale          |  00,00  norm,norm = result
417
        .long   sscale          |  00,01  norm,zero = fpn
418
        .long   scl_opr         |  00,10  norm,inf  = nan with operr
419
        .long   scl_snan        |  00,11  norm,nan  = nan
420
        .long   scl_zro         |  01,00  zero,norm = +-zero
421
        .long   scl_zro         |  01,01  zero,zero = +-zero
422
        .long   scl_opr         |  01,10  zero,inf  = nan with operr
423
        .long   scl_snan        |  01,11  zero,nan  = nan
424
        .long   scl_inf         |  10,00  inf,norm  = +-inf
425
        .long   scl_inf         |  10,01  inf,zero  = +-inf
426
        .long   scl_opr         |  10,10  inf,inf   = nan with operr
427
        .long   scl_snan        |  10,11  inf,nan   = nan
428
        .long   scl_dnan        |  11,00  nan,norm  = nan
429
        .long   scl_dnan        |  11,01  nan,zero  = nan
430
        .long   scl_dnan        |  11,10  nan,inf   = nan
431
        .long   scl_dnan        |  11,11  nan,nan   = nan
432
 
433
        .global pscale
434
pscale:
435
        bfextu  STAG(%a6){#0:#3},%d0 |stag in d0
436
        bfextu  DTAG(%a6){#0:#3},%d1 |dtag in d1
437
        bclrl   #2,%d0          |alias  denorm into norm
438
        bclrl   #2,%d1          |alias  denorm into norm
439
        lslb    #2,%d1
440
        orb     %d0,%d1         |d1{4:2} = dtag, d1{1:0} = stag
441
|                               ;dtag values     stag values:
442
|                               ;000 = norm      00 = norm
443
|                               ;001 = zero      01 = zero
444
|                               ;010 = inf       10 = inf
445
|                               ;011 = nan       11 = nan
446
|                               ;100 = dnrm
447
|
448
|
449
        leal    pscalet,%a1     |load start of jump table
450
        movel   (%a1,%d1.w*4),%a1       |load a1 with label depending on tag
451
        jmp     (%a1)           |go to the routine
452
 
453
scl_opr:
454
        bra     t_operr
455
 
456
scl_dnan:
457
        bra     dst_nan
458
 
459
scl_zro:
460
        btstb   #sign_bit,FPTEMP_EX(%a6)        |test if + or -
461
        beq     ld_pzero                |if pos then load +0
462
        bra     ld_mzero                |if neg then load -0
463
scl_inf:
464
        btstb   #sign_bit,FPTEMP_EX(%a6)        |test if + or -
465
        beq     ld_pinf                 |if pos then load +inf
466
        bra     ld_minf                 |else neg load -inf
467
scl_snan:
468
        bra     src_nan
469
|
470
|       FSINCOS
471
|
472
        .global ssincosz
473
ssincosz:
474
        btstb   #sign_bit,ETEMP(%a6)    |get sign
475
        beqs    sincosp
476
        fmovex  MZERO,%fp0
477
        bras    sincoscom
478
sincosp:
479
        fmovex PZERO,%fp0
480
sincoscom:
481
        fmovemx PONE,%fp1-%fp1  |do not allow FPSR to be affected
482
        bra     sto_cos         |store cosine result
483
 
484
        .global ssincosi
485
ssincosi:
486
        fmovex QNAN,%fp1        |load NAN
487
        bsr     sto_cos         |store cosine result
488
        fmovex QNAN,%fp0        |load NAN
489
        bra     t_operr
490
 
491
        .global ssincosnan
492
ssincosnan:
493
        movel   ETEMP_EX(%a6),FP_SCR1(%a6)
494
        movel   ETEMP_HI(%a6),FP_SCR1+4(%a6)
495
        movel   ETEMP_LO(%a6),FP_SCR1+8(%a6)
496
        bsetb   #signan_bit,FP_SCR1+4(%a6)
497
        fmovemx FP_SCR1(%a6),%fp1-%fp1
498
        bsr     sto_cos
499
        bra     src_nan
500
|
501
| This code forces default values for the zero, inf, and nan cases
502
| in the transcendentals code.  The CC bits must be set in the
503
| stacked FPSR to be correctly reported.
504
|
505
|**Returns +PI/2
506
        .global ld_ppi2
507
ld_ppi2:
508
        fmovex PPIBY2,%fp0              |load +pi/2
509
        bra     t_inx2                  |set inex2 exc
510
 
511
|**Returns -PI/2
512
        .global ld_mpi2
513
ld_mpi2:
514
        fmovex MPIBY2,%fp0              |load -pi/2
515
        orl     #neg_mask,USER_FPSR(%a6)        |set N bit
516
        bra     t_inx2                  |set inex2 exc
517
 
518
|**Returns +inf
519
        .global ld_pinf
520
ld_pinf:
521
        fmovex PINF,%fp0                |load +inf
522
        orl     #inf_mask,USER_FPSR(%a6)        |set I bit
523
        rts
524
 
525
|**Returns -inf
526
        .global ld_minf
527
ld_minf:
528
        fmovex MINF,%fp0                |load -inf
529
        orl     #neg_mask+inf_mask,USER_FPSR(%a6)       |set N and I bits
530
        rts
531
 
532
|**Returns +1
533
        .global ld_pone
534
ld_pone:
535
        fmovex PONE,%fp0                |load +1
536
        rts
537
 
538
|**Returns -1
539
        .global ld_mone
540
ld_mone:
541
        fmovex MONE,%fp0                |load -1
542
        orl     #neg_mask,USER_FPSR(%a6)        |set N bit
543
        rts
544
 
545
|**Returns +0
546
        .global ld_pzero
547
ld_pzero:
548
        fmovex PZERO,%fp0               |load +0
549
        orl     #z_mask,USER_FPSR(%a6)  |set Z bit
550
        rts
551
 
552
|**Returns -0
553
        .global ld_mzero
554
ld_mzero:
555
        fmovex MZERO,%fp0               |load -0
556
        orl     #neg_mask+z_mask,USER_FPSR(%a6) |set N and Z bits
557
        rts
558
 
559
        |end

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.