File indexing completed on 2025-05-11 08:23:48
0001 #include "fpsp-namespace.h"
0002 //
0003 //
0004 // kernel_ex.sa 3.3 12/19/90
0005 //
0006 // This file contains routines to force exception status in the
0007 // fpu for exceptional cases detected or reported within the
0008 // transcendental functions. Typically, the t_xx routine will
0009 // set the appropriate bits in the USER_FPSR word on the stack.
0010 // The bits are tested in gen_except.sa to determine if an exceptional
0011 // situation needs to be created on return from the FPSP.
0012 //
0013
0014 // Copyright (C) Motorola, Inc. 1990
0015 // All Rights Reserved
0016 //
0017 // THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MOTOROLA
0018 // The copyright notice above does not evidence any
0019 // actual or intended publication of such source code.
0020
0021 KERNEL_EX: //idnt 2,1 | Motorola 040 Floating Point Software Package
0022
0023 |section 8
0024
0025 #include "fpsp.defs"
0026
0027 mns_inf: .long 0xffff0000,0x00000000,0x00000000
0028 pls_inf: .long 0x7fff0000,0x00000000,0x00000000
0029 nan: .long 0x7fff0000,0xffffffff,0xffffffff
0030 huge: .long 0x7ffe0000,0xffffffff,0xffffffff
0031
0032 |xref ovf_r_k
0033 |xref unf_sub
0034 |xref nrm_set
0035
0036 .global t_dz
0037 .global t_dz2
0038 .global t_operr
0039 .global t_unfl
0040 .global t_ovfl
0041 .global t_ovfl2
0042 .global t_inx2
0043 .global t_frcinx
0044 .global t_extdnrm
0045 .global t_resdnrm
0046 .global dst_nan
0047 .global src_nan
0048 //
0049 // DZ exception
0050 //
0051 //
0052 // if dz trap disabled
0053 // store properly signed inf (use sign of etemp) into fp0
0054 // set FPSR exception status dz bit, condition code
0055 // inf bit, and accrued dz bit
0056 // return
0057 // frestore the frame into the machine (done by unimp_hd)
0058 //
0059 // else dz trap enabled
0060 // set exception status bit & accrued bits in FPSR
0061 // set flag to disable sto_res from corrupting fp register
0062 // return
0063 // frestore the frame into the machine (done by unimp_hd)
0064 //
0065 // t_dz2 is used by monadic functions such as flogn (from do_func).
0066 // t_dz is used by monadic functions such as satanh (from the
0067 // transcendental function).
0068 //
0069 t_dz2:
0070 bsetb #neg_bit,FPSR_CC(%a6) //set neg bit in FPSR
0071 fmovel #0,%FPSR //clr status bits (Z set)
0072 btstb #dz_bit,FPCR_ENABLE(%a6) //test FPCR for dz exc enabled
0073 bnes dz_ena_end
0074 bras m_inf //flogx always returns -inf
0075 t_dz:
0076 fmovel #0,%FPSR //clr status bits (Z set)
0077 btstb #dz_bit,FPCR_ENABLE(%a6) //test FPCR for dz exc enabled
0078 bnes dz_ena
0079 //
0080 // dz disabled
0081 //
0082 btstb #sign_bit,ETEMP_EX(%a6) //check sign for neg or pos
0083 beqs p_inf //branch if pos sign
0084
0085 m_inf:
0086 fmovemx mns_inf,%fp0-%fp0 //load -inf
0087 bsetb #neg_bit,FPSR_CC(%a6) //set neg bit in FPSR
0088 bras set_fpsr
0089 p_inf:
0090 fmovemx pls_inf,%fp0-%fp0 //load +inf
0091 set_fpsr:
0092 orl #dzinf_mask,USER_FPSR(%a6) //set I,DZ,ADZ
0093 rts
0094 //
0095 // dz enabled
0096 //
0097 dz_ena:
0098 btstb #sign_bit,ETEMP_EX(%a6) //check sign for neg or pos
0099 beqs dz_ena_end
0100 bsetb #neg_bit,FPSR_CC(%a6) //set neg bit in FPSR
0101 dz_ena_end:
0102 orl #dzinf_mask,USER_FPSR(%a6) //set I,DZ,ADZ
0103 st STORE_FLG(%a6)
0104 rts
0105 //
0106 // OPERR exception
0107 //
0108 // if (operr trap disabled)
0109 // set FPSR exception status operr bit, condition code
0110 // nan bit; Store default NAN into fp0
0111 // frestore the frame into the machine (done by unimp_hd)
0112 //
0113 // else (operr trap enabled)
0114 // set FPSR exception status operr bit, accrued operr bit
0115 // set flag to disable sto_res from corrupting fp register
0116 // frestore the frame into the machine (done by unimp_hd)
0117 //
0118 t_operr:
0119 orl #opnan_mask,USER_FPSR(%a6) //set NaN, OPERR, AIOP
0120
0121 btstb #operr_bit,FPCR_ENABLE(%a6) //test FPCR for operr enabled
0122 bnes op_ena
0123
0124 fmovemx nan,%fp0-%fp0 //load default nan
0125 rts
0126 op_ena:
0127 st STORE_FLG(%a6) //do not corrupt destination
0128 rts
0129
0130 //
0131 // t_unfl --- UNFL exception
0132 //
0133 // This entry point is used by all routines requiring unfl, inex2,
0134 // aunfl, and ainex to be set on exit.
0135 //
0136 // On entry, a0 points to the exceptional operand. The final exceptional
0137 // operand is built in FP_SCR1 and only the sign from the original operand
0138 // is used.
0139 //
0140 t_unfl:
0141 clrl FP_SCR1(%a6) //set exceptional operand to zero
0142 clrl FP_SCR1+4(%a6)
0143 clrl FP_SCR1+8(%a6)
0144 tstb (%a0) //extract sign from caller's exop
0145 bpls unfl_signok
0146 bset #sign_bit,FP_SCR1(%a6)
0147 unfl_signok:
0148 leal FP_SCR1(%a6),%a0
0149 orl #unfinx_mask,USER_FPSR(%a6)
0150 // ;set UNFL, INEX2, AUNFL, AINEX
0151 unfl_con:
0152 btstb #unfl_bit,FPCR_ENABLE(%a6)
0153 beqs unfl_dis
0154
0155 unfl_ena:
0156 bfclr STAG(%a6){#5:#3} //clear wbtm66,wbtm1,wbtm0
0157 bsetb #wbtemp15_bit,WB_BYTE(%a6) //set wbtemp15
0158 bsetb #sticky_bit,STICKY(%a6) //set sticky bit
0159
0160 bclrb #E1,E_BYTE(%a6)
0161
0162 unfl_dis:
0163 bfextu FPCR_MODE(%a6){#0:#2},%d0 //get round precision
0164
0165 bclrb #sign_bit,LOCAL_EX(%a0)
0166 sne LOCAL_SGN(%a0) //convert to internal ext format
0167
0168 bsr unf_sub //returns IEEE result at a0
0169 // ;and sets FPSR_CC accordingly
0170
0171 bfclr LOCAL_SGN(%a0){#0:#8} //convert back to IEEE ext format
0172 beqs unfl_fin
0173
0174 bsetb #sign_bit,LOCAL_EX(%a0)
0175 bsetb #sign_bit,FP_SCR1(%a6) //set sign bit of exc operand
0176
0177 unfl_fin:
0178 fmovemx (%a0),%fp0-%fp0 //store result in fp0
0179 rts
0180
0181
0182 //
0183 // t_ovfl2 --- OVFL exception (without inex2 returned)
0184 //
0185 // This entry is used by scale to force catastrophic overflow. The
0186 // ovfl, aovfl, and ainex bits are set, but not the inex2 bit.
0187 //
0188 t_ovfl2:
0189 orl #ovfl_inx_mask,USER_FPSR(%a6)
0190 movel ETEMP(%a6),FP_SCR1(%a6)
0191 movel ETEMP_HI(%a6),FP_SCR1+4(%a6)
0192 movel ETEMP_LO(%a6),FP_SCR1+8(%a6)
0193 //
0194 // Check for single or double round precision. If single, check if
0195 // the lower 40 bits of ETEMP are zero; if not, set inex2. If double,
0196 // check if the lower 21 bits are zero; if not, set inex2.
0197 //
0198 moveb FPCR_MODE(%a6),%d0
0199 andib #0xc0,%d0
0200 beq t_work //if extended, finish ovfl processing
0201 cmpib #0x40,%d0 //test for single
0202 bnes t_dbl
0203 t_sgl:
0204 tstb ETEMP_LO(%a6)
0205 bnes t_setinx2
0206 movel ETEMP_HI(%a6),%d0
0207 andil #0xff,%d0 //look at only lower 8 bits
0208 bnes t_setinx2
0209 bra t_work
0210 t_dbl:
0211 movel ETEMP_LO(%a6),%d0
0212 andil #0x7ff,%d0 //look at only lower 11 bits
0213 beq t_work
0214 t_setinx2:
0215 orl #inex2_mask,USER_FPSR(%a6)
0216 bras t_work
0217 //
0218 // t_ovfl --- OVFL exception
0219 //
0220 /
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496