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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libcpu/] [m68k/] [m68040/] [fpsp/] [do_func.S] - Blame information for rev 594

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

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

powered by: WebSVN 2.1.0

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