00001
00027 #ifndef _FENV_H
00028 #define _FENV_H
00029
00030 #include <nlibc.h>
00031
00032
00033
00034 #define FE_AU_BAD_OP_H 0x00001
00035 #define FE_AU_BAD_OP_L 0x00002
00036 #define FE_AU_DEN_IN_H 0x00004
00037 #define FE_AU_DEN_IN_L 0x00008
00038 #define FE_AU_DEN_OUT_H 0x00010
00039 #define FE_AU_DEN_OUT_L 0x00020
00040 #define FE_AU_OVERFLOW_H 0x00040
00041 #define FE_AU_OVERFLOW_L 0x00080
00042 #define FE_LUT_BAD_OP_H 0x00100
00043 #define FE_LUT_BAD_OP_L 0x00200
00044 #define FE_LUT_DEN_IN_H 0x00400
00045 #define FE_LUT_DEN_IN_L 0x00800
00046 #define FE_LUT_DEN_OUT_H 0x01000
00047 #define FE_LUT_DEN_OUT_L 0x02000
00048 #define FE_LUT_OVFLW_H 0x04000
00049 #define FE_LUT_OVFLW_L 0x08000
00050 #define FE_AGU_MULT_OVF 0x10000
00051 #define FE_AGU_ADD_OVF 0x20000
00052 #define FE_AGU_ILLEGAL_INSTRUCTION 0x40000
00053
00054 #define FE_ALL_EXCEPT ( FE_AU_BAD_OP_H \
00055 | FE_AU_BAD_OP_L \
00056 | FE_AU_DEN_IN_H \
00057 | FE_AU_DEN_IN_L \
00058 | FE_AU_DEN_OUT_H \
00059 | FE_AU_DEN_OUT_L \
00060 | FE_AU_OVERFLOW_H \
00061 | FE_AU_OVERFLOW_L \
00062 | FE_LUT_BAD_OP_H \
00063 | FE_LUT_BAD_OP_L \
00064 | FE_LUT_DEN_IN_H \
00065 | FE_LUT_DEN_IN_L \
00066 | FE_LUT_DEN_OUT_H \
00067 | FE_LUT_DEN_OUT_L \
00068 | FE_LUT_OVFLW_H \
00069 | FE_LUT_OVFLW_L \
00070 | FE_AGU_MULT_OVF \
00071 | FE_AGU_ADD_OVF \
00072 | FE_AGU_ILLEGAL_INSTRUCTION )
00073
00074 #undef FE_DOWNWARD
00075 #undef FE_TONEAREST
00076 #undef FE_TOWARDZERO
00077 #undef FE_UPWARD
00078
00079
00080
00081 typedef int fexcept_t;
00082 typedef int fmask_t;
00083
00084 typedef struct
00085 {
00086 fexcept_t __exc_reg;
00087 fmask_t __msk_reg;
00088 }
00089 fenv_t;
00090
00091
00092
00093 int feclearexcept(int excepts);
00094 int fegetexceptflag(fexcept_t *flagp, int excepts);
00095 int feraiseexcept(int excepts);
00096 int fesetexceptflag(const fexcept_t *flagp, int excepts);
00097 int fetestexcept(int excepts);
00098 int fegetenv(fenv_t *envp);
00099 int feholdexcept(fenv_t *envp);
00100 int fesetenv(const fenv_t *envp);
00101 int feupdateenv(const fenv_t *envp);
00102 int feclearmask(int mask);
00103 int fegetmaskflag(fmask_t *flagp, int mask);
00104 int feraisemask(int mask);
00105 int fesetmaskflag(const fmask_t *flagp, int mask);
00106 int fetestmask(int mask);
00107
00108
00130
00131 int feclearexcept(int excepts)
00132 {
00133 int tmp_exc;
00134
00135 asm("\tctr %0 0x30" : "=r" (tmp_exc));
00136 tmp_exc &= ~excepts;
00137 asm("\trtc 0x30 %0" : : "r" (tmp_exc) );
00138
00139 return(0);
00140 }
00141
00142
00143
00164
00165 int fegetexceptflag(fexcept_t *flagp, int excepts)
00166 {
00167 int tmp_exc;
00168
00169 asm("\tctr %0 0x30" : "=r" (tmp_exc));
00170 *flagp=tmp_exc&excepts;
00171
00172 return(0);
00173 }
00174
00175
00198
00199 int feraiseexcept(int excepts)
00200 {
00201 int tmp_exc;
00202
00203 asm("\tctr %0 0x30" : "=r" (tmp_exc));
00204 tmp_exc |= excepts;
00205 asm("\trtc 0x30 %0" : : "r" (tmp_exc) );
00206
00207 return(0);
00208 }
00209
00210
00211
00239
00240 int fesetexceptflag(const fexcept_t *flagp, int excepts)
00241 {
00242 int tmp_exc,tmp_exc2;
00243
00244 asm("\tctr %0 0x30" : "=r" (tmp_exc));
00245 tmp_exc2 = (tmp_exc & (~(*flagp)));
00246 tmp_exc = tmp_exc2 | (excepts&(*flagp));
00247 asm("\trtc 0x30 %0" : : "r" (tmp_exc) );
00248
00249 return(0);
00250 }
00251
00252
00253
00277
00278 int fetestexcept(int excepts)
00279 {
00280 int tmp_exc;
00281
00282 asm("\tctr %0 0x30" : "=r" (tmp_exc));
00283 tmp_exc &= excepts;
00284
00285 return(tmp_exc);
00286 }
00287
00288
00289
00312
00313 int fegetenv(fenv_t *envp)
00314 {
00315
00316 envp->__exc_reg=fetestexcept(FE_ALL_EXCEPT);
00317 envp->__msk_reg=fetestmask(FE_ALL_EXCEPT);
00318
00319 return(0);
00320 }
00321
00322
00349
00350 int feholdexcept(fenv_t *envp)
00351 {
00352 fenv_t tmp_exc;
00353
00354 fegetenv(&tmp_exc);
00355 *envp = tmp_exc;
00356 tmp_exc.__exc_reg=0;
00357 tmp_exc.__msk_reg=FE_ALL_EXCEPT;
00358 fesetenv(&tmp_exc);
00359
00360 return(0);
00361 }
00362
00363
00364
00390
00391 int fesetenv(const fenv_t *envp)
00392 {
00393
00394 asm("\trtc 0x31 %0" : : "r" (envp->__msk_reg) );
00395 asm("\trtc 0x30 %0" : : "r" (envp->__exc_reg) );
00396
00397 return(0);
00398 }
00399
00400
00401
00426
00427 int feupdateenv(const fenv_t *envp)
00428 {
00429 feraisemask(envp->__msk_reg);
00430 feraiseexcept(envp->__exc_reg);
00431
00432 return(0);
00433 }
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00470
00471 int feclearmask(int mask)
00472 {
00473 int tmp_msk;
00474
00475 asm("\tctr %0 0x31" : "=r" (tmp_msk));
00476 tmp_msk &= ~mask;
00477 asm("\trtc 0x31 %0" : : "r" (tmp_msk) );
00478
00479 return(0);
00480 }
00481
00482
00483
00504
00505 int fegetmaskflag(fmask_t *flagp, int mask)
00506 {
00507 int tmp_msk;
00508
00509 asm("\tctr %0 0x31" : "=r" (tmp_msk));
00510 *flagp=tmp_msk&mask;
00511
00512 return(0);
00513 }
00514
00515
00537
00538 int feraisemask(int mask)
00539 {
00540 int tmp_msk;
00541
00542 asm("\tctr %0 0x31" : "=r" (tmp_msk));
00543 tmp_msk |= mask;
00544 asm("\trtc 0x31 %0" : : "r" (tmp_msk) );
00545
00546 return(0);
00547 }
00548
00549
00550
00577
00578 int fesetmaskflag(const fmask_t *flagp, int mask)
00579 {
00580 int tmp_msk,tmp_msk2;
00581
00582 asm("\tctr %0 0x31" : "=r" (tmp_msk));
00583 tmp_msk2 = (tmp_msk & (~(*flagp)));
00584 tmp_msk = tmp_msk2 | (mask&(*flagp));
00585 asm("\trtc 0x31 %0" : : "r" (tmp_msk) );
00586
00587 return(0);
00588 }
00589
00590
00591
00614
00615 int fetestmask(int mask)
00616 {
00617 int tmp_msk;
00618
00619 asm("\tctr %0 0x31" : "=r" (tmp_msk));
00620 tmp_msk &= mask;
00621
00622 return(tmp_msk);
00623 }
00624
00625 #endif
00626
00627
00628