Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2     NetWinder Floating Point Emulator
  3     (c) Rebel.COM, 1998,1999
  4 
  5     Direct questions, comments to Scott Bambrough <scottb@netwinder.org>
  6 
  7     This program is free software; you can redistribute it and/or modify
  8     it under the terms of the GNU General Public License as published by
  9     the Free Software Foundation; either version 2 of the License, or
 10     (at your option) any later version.
 11 
 12     This program is distributed in the hope that it will be useful,
 13     but WITHOUT ANY WARRANTY; without even the implied warranty of
 14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15     GNU General Public License for more details.
 16 
 17     You should have received a copy of the GNU General Public License
 18     along with this program; if not, write to the Free Software
 19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 20 */
 21 
 22 #include "fpa11.h"
 23 #include "softfloat.h"
 24 #include "fpopcode.h"
 25 
 26 floatx80 floatx80_exp(floatx80 Fm);
 27 floatx80 floatx80_ln(floatx80 Fm);
 28 floatx80 floatx80_sin(floatx80 rFm);
 29 floatx80 floatx80_cos(floatx80 rFm);
 30 floatx80 floatx80_arcsin(floatx80 rFm);
 31 floatx80 floatx80_arctan(floatx80 rFm);
 32 floatx80 floatx80_log(floatx80 rFm);
 33 floatx80 floatx80_tan(floatx80 rFm);
 34 floatx80 floatx80_arccos(floatx80 rFm);
 35 floatx80 floatx80_pow(floatx80 rFn, floatx80 rFm);
 36 floatx80 floatx80_pol(floatx80 rFn, floatx80 rFm);
 37 
 38 static floatx80 floatx80_rsf(struct roundingData *roundData, floatx80 rFn, floatx80 rFm)
 39 {
 40         return floatx80_sub(roundData, rFm, rFn);
 41 }
 42 
 43 static floatx80 floatx80_rdv(struct roundingData *roundData, floatx80 rFn, floatx80 rFm)
 44 {
 45         return floatx80_div(roundData, rFm, rFn);
 46 }
 47 
 48 static floatx80 (*const dyadic_extended[16])(struct roundingData*, floatx80 rFn, floatx80 rFm) = {
 49         [ADF_CODE >> 20] = floatx80_add,
 50         [MUF_CODE >> 20] = floatx80_mul,
 51         [SUF_CODE >> 20] = floatx80_sub,
 52         [RSF_CODE >> 20] = floatx80_rsf,
 53         [DVF_CODE >> 20] = floatx80_div,
 54         [RDF_CODE >> 20] = floatx80_rdv,
 55         [RMF_CODE >> 20] = floatx80_rem,
 56 
 57         /* strictly, these opcodes should not be implemented */
 58         [FML_CODE >> 20] = floatx80_mul,
 59         [FDV_CODE >> 20] = floatx80_div,
 60         [FRD_CODE >> 20] = floatx80_rdv,
 61 };
 62 
 63 static floatx80 floatx80_mvf(struct roundingData *roundData, floatx80 rFm)
 64 {
 65         return rFm;
 66 }
 67 
 68 static floatx80 floatx80_mnf(struct roundingData *roundData, floatx80 rFm)
 69 {
 70         rFm.high ^= 0x8000;
 71         return rFm;
 72 }
 73 
 74 static floatx80 floatx80_abs(struct roundingData *roundData, floatx80 rFm)
 75 {
 76         rFm.high &= 0x7fff;
 77         return rFm;
 78 }
 79 
 80 static floatx80 (*const monadic_extended[16])(struct roundingData*, floatx80 rFm) = {
 81         [MVF_CODE >> 20] = floatx80_mvf,
 82         [MNF_CODE >> 20] = floatx80_mnf,
 83         [ABS_CODE >> 20] = floatx80_abs,
 84         [RND_CODE >> 20] = floatx80_round_to_int,
 85         [URD_CODE >> 20] = floatx80_round_to_int,
 86         [SQT_CODE >> 20] = floatx80_sqrt,
 87         [NRM_CODE >> 20] = floatx80_mvf,
 88 };
 89 
 90 unsigned int ExtendedCPDO(struct roundingData *roundData, const unsigned int opcode, FPREG * rFd)
 91 {
 92         FPA11 *fpa11 = GET_FPA11();
 93         floatx80 rFm;
 94         unsigned int Fm, opc_mask_shift;
 95 
 96         Fm = getFm(opcode);
 97         if (CONSTANT_FM(opcode)) {
 98                 rFm = getExtendedConstant(Fm);
 99         } else {
100                 switch (fpa11->fType[Fm]) {
101                 case typeSingle:
102                         rFm = float32_to_floatx80(fpa11->fpreg[Fm].fSingle);
103                         break;
104 
105                 case typeDouble:
106                         rFm = float64_to_floatx80(fpa11->fpreg[Fm].fDouble);
107                         break;
108 
109                 case typeExtended:
110                         rFm = fpa11->fpreg[Fm].fExtended;
111                         break;
112 
113                 default:
114                         return 0;
115                 }
116         }
117 
118         opc_mask_shift = (opcode & MASK_ARITHMETIC_OPCODE) >> 20;
119         if (!MONADIC_INSTRUCTION(opcode)) {
120                 unsigned int Fn = getFn(opcode);
121                 floatx80 rFn;
122 
123                 switch (fpa11->fType[Fn]) {
124                 case typeSingle:
125                         rFn = float32_to_floatx80(fpa11->fpreg[Fn].fSingle);
126                         break;
127 
128                 case typeDouble:
129                         rFn = float64_to_floatx80(fpa11->fpreg[Fn].fDouble);
130                         break;
131 
132                 case typeExtended:
133                         rFn = fpa11->fpreg[Fn].fExtended;
134                         break;
135 
136                 default:
137                         return 0;
138                 }
139 
140                 if (dyadic_extended[opc_mask_shift]) {
141                         rFd->fExtended = dyadic_extended[opc_mask_shift](roundData, rFn, rFm);
142                 } else {
143                         return 0;
144                 }
145         } else {
146                 if (monadic_extended[opc_mask_shift]) {
147                         rFd->fExtended = monadic_extended[opc_mask_shift](roundData, rFm);
148                 } else {
149                         return 0;
150                 }
151         }
152 
153         return 1;
154 }
155 
  This page was automatically generated by the LXR engine.