cpu_fp_operate.h

Go to the documentation of this file.
00001 /* ES40 emulator.
00002  * Copyright (C) 2007-2008 by the ES40 Emulator Project
00003  *
00004  * WWW    : http://sourceforge.net/projects/es40
00005  * E-mail : camiel@camicom.com
00006  * 
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  * 
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00020  * 
00021  * Although this is not required, the author would appreciate being notified of, 
00022  * and receiving any modifications you may make to the source code that might serve
00023  * the general public.
00024  */
00025 
00098 #if defined(HAVE_NEW_FP)
00099 
00100 /* copy sign */
00101 #define DO_CPYS   FPSTART; \
00102   state.f[FREG_3] = (state.f[FREG_1] & FPR_SIGN) | (state.f[FREG_2] &~FPR_SIGN);
00103 
00104 #define DO_CPYSN  FPSTART; \
00105   state.f[FREG_3] = ((state.f[FREG_1] & FPR_SIGN) ^ FPR_SIGN) | (state.f[FREG_2] &~FPR_SIGN);
00106 
00107 #define DO_CPYSE  FPSTART; \
00108   state.f[FREG_3] = (state.f[FREG_1] & (FPR_SIGN | FPR_EXP)) | (state.f[FREG_2] &~(FPR_SIGN | FPR_EXP));
00109 
00110 /* conditional move */
00111 #define DO_FCMOVEQ  FPSTART;            \
00112   if((state.f[FREG_1] &~FPR_SIGN) == 0) \
00113     state.f[FREG_3] = state.f[FREG_2];
00114 
00115 #define DO_FCMOVGE  FPSTART;      \
00116   if(state.f[FREG_1] <= FPR_SIGN) \
00117     state.f[FREG_3] = state.f[FREG_2];
00118 
00119 #define DO_FCMOVGT  FPSTART;                                  \
00120   if(!FPR_GETSIGN(state.f[FREG_1]) && (state.f[FREG_1] != 0)) \
00121     state.f[FREG_3] = state.f[FREG_2];
00122 
00123 #define DO_FCMOVLE  FPSTART;                                 \
00124   if(FPR_GETSIGN(state.f[FREG_1]) || (state.f[FREG_1] == 0)) \
00125     state.f[FREG_3] = state.f[FREG_2];
00126 
00127 #define DO_FCMOVLT  FPSTART;     \
00128   if(state.f[FREG_1] > FPR_SIGN) \
00129     state.f[FREG_3] = state.f[FREG_2];
00130 
00131 #define DO_FCMOVNE  FPSTART;            \
00132   if((state.f[FREG_1] &~FPR_SIGN) != 0) \
00133     state.f[FREG_3] = state.f[FREG_2];
00134 
00135 /* floating-point control register */
00136 #define DO_MF_FPCR  FPSTART; \
00137   state.f[FREG_1] = state.fpcr;
00138 
00139 #define DO_MT_FPCR  FPSTART;                              \
00140   state.fpcr = state.f[FREG_1] & U64(0x7fff800000000000); \
00141   if(state.fpcr & U64(0x03f0000000000000))                \
00142     state.fpcr |= U64(0x8000000000000000);  /* SUM */
00143 
00144 /* add */
00145 #define DO_ADDG FPSTART; \
00146   state.f[FREG_3] = vax_fadd(state.f[FREG_1], state.f[FREG_2], ins, DT_G, 0);
00147 
00148 #define DO_ADDF FPSTART; \
00149   state.f[FREG_3] = vax_fadd(state.f[FREG_1], state.f[FREG_2], ins, DT_F, 0);
00150 
00151 #define DO_ADDT FPSTART; \
00152   state.f[FREG_3] = ieee_fadd(state.f[FREG_1], state.f[FREG_2], ins, DT_T, 0);
00153 
00154 #define DO_ADDS FPSTART; \
00155   state.f[FREG_3] = ieee_fadd(state.f[FREG_1], state.f[FREG_2], ins, DT_S, 0);
00156 
00157 /* subtract */
00158 #define DO_SUBG FPSTART; \
00159   state.f[FREG_3] = vax_fadd(state.f[FREG_1], state.f[FREG_2], ins, DT_G, 1);
00160 
00161 #define DO_SUBF FPSTART; \
00162   state.f[FREG_3] = vax_fadd(state.f[FREG_1], state.f[FREG_2], ins, DT_F, 1);
00163 
00164 #define DO_SUBT FPSTART; \
00165   state.f[FREG_3] = ieee_fadd(state.f[FREG_1], state.f[FREG_2], ins, DT_T, 1);
00166 
00167 #define DO_SUBS FPSTART; \
00168   state.f[FREG_3] = ieee_fadd(state.f[FREG_1], state.f[FREG_2], ins, DT_S, 1);
00169 
00170 /* comparison */
00171 #define DO_CMPGEQ FPSTART; \
00172   state.f[FREG_3] = (vax_fcmp(state.f[FREG_1], state.f[FREG_2], ins) == 0) ? FP_TRUE : 0;
00173 
00174 #define DO_CMPGLE FPSTART; \
00175   state.f[FREG_3] = (vax_fcmp(state.f[FREG_1], state.f[FREG_2], ins) <= 0) ? FP_TRUE : 0;
00176 
00177 #define DO_CMPGLT FPSTART; \
00178   state.f[FREG_3] = (vax_fcmp(state.f[FREG_1], state.f[FREG_2], ins) < 0) ? FP_TRUE : 0;
00179 
00180 #define DO_CMPTEQ FPSTART; \
00181   state.f[FREG_3] = (ieee_fcmp(state.f[FREG_1], state.f[FREG_2], ins, 0) == 0) ? FP_TRUE : 0;
00182 
00183 #define DO_CMPTLE FPSTART; \
00184   state.f[FREG_3] = (ieee_fcmp(state.f[FREG_1], state.f[FREG_2], ins, 1) <= 0) ? FP_TRUE : 0;
00185 
00186 #define DO_CMPTLT FPSTART; \
00187   state.f[FREG_3] = (ieee_fcmp(state.f[FREG_1], state.f[FREG_2], ins, 1) < 0) ? FP_TRUE : 0;
00188 
00189 #define DO_CMPTUN FPSTART;                                   \
00190   state.f[FREG_3] =                                          \
00191     (                                                        \
00192       (ieee_unpack(state.f[FREG_1], &ufp1, ins) == UFT_NAN)  \
00193     || (ieee_unpack(state.f[FREG_2], &ufp2, ins) == UFT_NAN) \
00194     ) ? FP_TRUE : 0;
00195 
00196 /* format conversions */
00197 #define DO_CVTQL  FPSTART;                                                                           \
00198   state.f[FREG_3] = ((state.f[FREG_2] & 0xC0000000) << 32) | ((state.f[FREG_2] & 0x3FFFFFFF) << 29); \
00199   if(FPR_GETSIGN(state.f[FREG_2]) ? (state.f[FREG_2] < U64(0xFFFFFFFF80000000)) :                    \
00200        (state.f[FREG_2] > U64(0x000000007FFFFFFF)))                                                  \
00201   {                                                                                                  \
00202     if(ins & I_FTRP_V)                                                                               \
00203       vax_trap(TRAP_IOV, ins);                                                                       \
00204   }
00205 
00206 #define DO_CVTLQ  FPSTART;                                               \
00207   state.f[FREG_3] = sext_u64_32(((state.f[FREG_2] >> 32) & 0xC0000000) | \
00208                                   ((state.f[FREG_2] >> 29) & 0x3FFFFFFF));
00209 
00210 #define DO_CVTGQ  FPSTART; \
00211   state.f[FREG_3] = vax_cvtfi(state.f[FREG_2], ins);
00212 
00213 #define DO_CVTQG  FPSTART; \
00214   state.f[FREG_3] = vax_cvtif(state.f[FREG_2], ins, DT_G);
00215 
00216 #define DO_CVTQF  FPSTART; \
00217   state.f[FREG_3] = vax_cvtif(state.f[FREG_2], ins, DT_F);
00218 
00219 #define DO_CVTTQ  FPSTART; \
00220   state.f[FREG_3] = ieee_cvtfi(state.f[FREG_2], ins);
00221 
00222 #define DO_CVTQT  FPSTART; \
00223   state.f[FREG_3] = ieee_cvtif(state.f[FREG_2], ins, DT_T);
00224 
00225 #define DO_CVTQS  FPSTART; \
00226   state.f[FREG_3] = ieee_cvtif(state.f[FREG_2], ins, DT_S);
00227 
00228 #define DO_CVTGD  FPSTART;                 \
00229   vax_unpack(state.f[FREG_2], &ufp2, ins); \
00230   state.f[FREG_3] = vax_rpack_d(&ufp2, ins);
00231 
00232 #define DO_CVTDG  FPSTART;                   \
00233   vax_unpack_d(state.f[FREG_2], &ufp2, ins); \
00234   state.f[FREG_3] = vax_rpack(&ufp2, ins, DT_G);
00235 
00236 #define DO_CVTGF  FPSTART;                 \
00237   vax_unpack(state.f[FREG_2], &ufp2, ins); \
00238   state.f[FREG_3] = vax_rpack(&ufp2, ins, DT_F);
00239 
00240 #define DO_CVTST  FPSTART; \
00241   state.f[FREG_3] = ieee_cvtst(state.f[FREG_2], ins);
00242 
00243 #define DO_CVTTS  FPSTART; \
00244   state.f[FREG_3] = ieee_cvtts(state.f[FREG_2], ins);
00245 
00246 /* float <-> integer register moves */
00247 #define DO_FTOIS  FPSTART; \
00248   state.r[REG_3] = ieee_sts(state.f[FREG_1]);
00249 
00250 #define DO_FTOIT  FPSTART; \
00251   state.r[REG_3] = state.f[FREG_1];
00252 
00253 #define DO_ITOFT  FPSTART; \
00254   state.f[FREG_3] = state.r[REG_1];
00255 
00256 #define DO_ITOFS  FPSTART; \
00257   state.f[FREG_3] = ieee_lds((u32) state.r[REG_1]);
00258 
00259 #define DO_ITOFF  FPSTART; \
00260   state.f[FREG_3] = vax_ldf(SWAP_VAXF((u32) state.r[REG_1]));
00261 
00262 /* Multiply */
00263 #define DO_MULG FPSTART; \
00264   state.f[FREG_3] = vax_fmul(state.f[FREG_1], state.f[FREG_2], ins, DT_G);
00265 
00266 #define DO_MULF FPSTART; \
00267   state.f[FREG_3] = vax_fmul(state.f[FREG_1], state.f[FREG_2], ins, DT_F);
00268 
00269 #define DO_MULT FPSTART; \
00270   state.f[FREG_3] = ieee_fmul(state.f[FREG_1], state.f[FREG_2], ins, DT_T);
00271 
00272 #define DO_MULS FPSTART; \
00273   state.f[FREG_3] = ieee_fmul(state.f[FREG_1], state.f[FREG_2], ins, DT_S);
00274 
00275 /* Divide */
00276 #define DO_DIVG FPSTART; \
00277   state.f[FREG_3] = vax_fdiv(state.f[FREG_1], state.f[FREG_2], ins, DT_G);
00278 
00279 #define DO_DIVF FPSTART; \
00280   state.f[FREG_3] = vax_fdiv(state.f[FREG_1], state.f[FREG_2], ins, DT_F);
00281 
00282 #define DO_DIVT FPSTART; \
00283   state.f[FREG_3] = ieee_fdiv(state.f[FREG_1], state.f[FREG_2], ins, DT_T);
00284 
00285 #define DO_DIVS FPSTART; \
00286   state.f[FREG_3] = ieee_fdiv(state.f[FREG_1], state.f[FREG_2], ins, DT_S);
00287 
00288 /* Square-root */
00289 #define DO_SQRTG  FPSTART; \
00290   state.f[FREG_3] = vax_sqrt(state.f[FREG_2], ins, DT_G);
00291 
00292 #define DO_SQRTF  FPSTART; \
00293   state.f[FREG_3] = vax_sqrt(state.f[FREG_2], ins, DT_F);
00294 
00295 #define DO_SQRTT  FPSTART; \
00296   state.f[FREG_3] = ieee_sqrt(state.f[FREG_2], ins, DT_T);
00297 
00298 #define DO_SQRTS  FPSTART; \
00299   state.f[FREG_3] = ieee_sqrt(state.f[FREG_2], ins, DT_S);
00300 
00301 #else
00302 #define DO_CPYS     FPSTART; \
00303   state.f[FREG_3] = (state.f[FREG_1] & U64(0x8000000000000000)) | (state.f[FREG_2] & U64(0x7fffffffffffffff));
00304 
00305 #define DO_CPYSN    FPSTART;                      \
00306   state.f[FREG_3] =                               \
00307     (                                             \
00308       state.f[FREG_1] & U64(0x8000000000000000) ^ \
00309       U64(0x8000000000000000)                     \
00310     ) |                                           \
00311     (state.f[FREG_2] & U64(0x7fffffffffffffff));
00312 
00313 #define DO_CPYSE    FPSTART; \
00314   state.f[FREG_3] = (state.f[FREG_1] & U64(0xfff0000000000000)) | (state.f[FREG_2] & U64(0x000fffffffffffff));
00315 
00316 #define DO_CVTQL    FPSTART; \
00317   state.f[FREG_3] = ((state.f[FREG_2] & U64(0x00000000c0000000)) << 32) | ((state.f[FREG_2] & U64(0x000000003fffffff)) << 29);
00318 
00319 #define DO_CVTLQ    FPSTART;                                                          \
00320   state.f[FREG_3] = sext_u64_32(((state.f[FREG_2] >> 32) & U64(0x00000000c0000000)) | \
00321                                         ((state.f[FREG_2] >> 29) & U64(0x000000003fffffff)));
00322 
00323 #define DO_FCMOVEQ  FPSTART;                    \
00324   if(state.f[FREG_1] == U64(0x0000000000000000) \
00325    || state.f[FREG_1] == U64(0x8000000000000000)) state.f[FREG_3] = state.f[FREG_2];
00326 #define DO_FCMOVGE  FPSTART;                      \
00327   if(!(state.f[FREG_1] & U64(0x8000000000000000)) \
00328    || state.f[FREG_1] == U64(0x8000000000000000)) state.f[FREG_3] = state.f[FREG_2];
00329 #define DO_FCMOVGT  FPSTART;                      \
00330   if(!(state.f[FREG_1] & U64(0x8000000000000000)) \
00331    && state.f[FREG_1] != U64(0x0000000000000000)) state.f[FREG_3] = state.f[FREG_2];
00332 #define DO_FCMOVLE  FPSTART;                     \
00333   if((state.f[FREG_1] & U64(0x8000000000000000)) \
00334    || state.f[FREG_1] == U64(0x0000000000000000)) state.f[FREG_3] = state.f[FREG_2];
00335 #define DO_FCMOVLT  FPSTART;                     \
00336   if((state.f[FREG_1] & U64(0x8000000000000000)) \
00337    && state.f[FREG_1] != U64(0x8000000000000000)) state.f[FREG_3] = state.f[FREG_2];
00338 #define DO_FCMOVNE  FPSTART;                    \
00339   if(state.f[FREG_1] != U64(0x0000000000000000) \
00340    && state.f[FREG_1] != U64(0x8000000000000000)) state.f[FREG_3] = state.f[FREG_2];
00341 
00342 #define DO_MF_FPCR  FPSTART; \
00343   state.f[FREG_1] = state.fpcr;
00344 #define DO_MT_FPCR  FPSTART; \
00345   state.fpcr = state.f[FREG_1];
00346 
00347 #define DO_ADDG     FPSTART; \
00348   state.f[FREG_3] = host2g(g2host(state.f[FREG_1]) + g2host(state.f[FREG_2]));
00349 #define DO_ADDF     FPSTART; \
00350   state.f[FREG_3] = host2f(f2host(state.f[FREG_1]) + f2host(state.f[FREG_2]));
00351 #define DO_ADDT     FPSTART; \
00352   state.f[FREG_3] = host2t(t2host(state.f[FREG_1]) + t2host(state.f[FREG_2]));
00353 #define DO_ADDS     FPSTART; \
00354   state.f[FREG_3] = host2s(s2host(state.f[FREG_1]) + s2host(state.f[FREG_2]));
00355 
00356 #define DO_SUBG     FPSTART; \
00357   state.f[FREG_3] = host2g(g2host(state.f[FREG_1]) - g2host(state.f[FREG_2]));
00358 #define DO_SUBF     FPSTART; \
00359   state.f[FREG_3] = host2f(f2host(state.f[FREG_1]) - f2host(state.f[FREG_2]));
00360 #define DO_SUBT     FPSTART; \
00361   state.f[FREG_3] = host2t(t2host(state.f[FREG_1]) - t2host(state.f[FREG_2]));
00362 #define DO_SUBS     FPSTART; \
00363   state.f[FREG_3] = host2s(s2host(state.f[FREG_1]) - s2host(state.f[FREG_2]));
00364 
00365 #define DO_CMPGEQ   FPSTART; \
00366   state.f[FREG_3] = (g2host(state.f[FREG_1]) == g2host(state.f[FREG_2])) ? U64(0x4000000000000000) : 0;
00367 #define DO_CMPGLE   FPSTART; \
00368   state.f[FREG_3] = (g2host(state.f[FREG_1]) <= g2host(state.f[FREG_2])) ? U64(0x4000000000000000) : 0;
00369 #define DO_CMPGLT   FPSTART; \
00370   state.f[FREG_3] = (g2host(state.f[FREG_1]) < g2host(state.f[FREG_2])) ? U64(0x4000000000000000) : 0;
00371 
00372 #define DO_CMPTEQ   FPSTART; \
00373   state.f[FREG_3] = (t2host(state.f[FREG_1]) == t2host(state.f[FREG_2])) ? U64(0x4000000000000000) : 0;
00374 #define DO_CMPTLE   FPSTART; \
00375   state.f[FREG_3] = (t2host(state.f[FREG_1]) <= t2host(state.f[FREG_2])) ? U64(0x4000000000000000) : 0;
00376 #define DO_CMPTLT   FPSTART; \
00377   state.f[FREG_3] = (t2host(state.f[FREG_1]) < t2host(state.f[FREG_2])) ? U64(0x4000000000000000) : 0;
00378 #define DO_CMPTUN   FPSTART; \
00379   state.f[FREG_3] = (i_isnan(state.f[FREG_1]) || i_isnan(state.f[FREG_2])) ? U64(0x4000000000000000) : 0;
00380 
00381 #define DO_CVTGQ    FPSTART; \
00382   state.f[FREG_3] = (u64) ((s64) g2host(state.f[FREG_2]));
00383 #define DO_CVTQG    FPSTART; \
00384   state.f[FREG_3] = host2g((double) ((s64) state.f[FREG_2]));
00385 #define DO_CVTQF    FPSTART; \
00386   state.f[FREG_3] = host2f((double) ((s64) state.f[FREG_2]));
00387 
00388 #define DO_CVTTQ    FPSTART; \
00389   state.f[FREG_3] = (u64) ((s64) t2host(state.f[FREG_2]));
00390 #define DO_CVTQT    FPSTART; \
00391   state.f[FREG_3] = host2t((double) ((s64) state.f[FREG_2]));
00392 #define DO_CVTQS    FPSTART; \
00393   state.f[FREG_3] = host2s((double) ((s64) state.f[FREG_2]));
00394 #define DO_CVTGD    FPSTART; \
00395   state.f[FREG_3] = host2d(g2host(state.f[FREG_2]));
00396 #define DO_CVTDG    FPSTART; \
00397   state.f[FREG_3] = host2g(d2host(state.f[FREG_2]));
00398 #define DO_CVTGF    FPSTART; \
00399   state.f[FREG_3] = host2f(g2host(state.f[FREG_2]));
00400 
00401 #define DO_FTOIS    FPSTART;                             \
00402   temp_64 = state.f[FREG_1];                             \
00403   state.r[REG_3] = (temp_64 & U64(0x000000003fffffff)) | \
00404     ((temp_64 & U64(0xc000000000000000)) >> 32) |        \
00405       (((temp_64 & U64(0x8000000000000000)) >> 31) * U64(0xffffffff));
00406 
00407 #define DO_FTOIT    FPSTART; \
00408   state.r[REG_3] = state.f[FREG_1];
00409 #define DO_ITOFT    FPSTART; \
00410   state.f[FREG_3] = state.r[REG_1];
00411 #define DO_ITOFS    FPSTART; \
00412   state.f[FREG_3] = load_s((u32) state.r[REG_1]);
00413 #define DO_ITOFF    FPSTART; \
00414   state.f[FREG_3] = itof_f(state.r[REG_1]);
00415 
00416 #define DO_MULG     FPSTART; \
00417   state.f[FREG_3] = host2g(g2host(state.f[FREG_1]) * g2host(state.f[FREG_2]));
00418 #define DO_MULF     FPSTART; \
00419   state.f[FREG_3] = host2f(f2host(state.f[FREG_1]) * f2host(state.f[FREG_2]));
00420 #define DO_MULT     FPSTART; \
00421   state.f[FREG_3] = host2t(t2host(state.f[FREG_1]) * t2host(state.f[FREG_2]));
00422 #define DO_MULS     FPSTART; \
00423   state.f[FREG_3] = host2s(s2host(state.f[FREG_1]) * s2host(state.f[FREG_2]));
00424 
00425 #define DO_DIVG     FPSTART; \
00426   state.f[FREG_3] = host2g(g2host(state.f[FREG_1]) / g2host(state.f[FREG_2]));
00427 #define DO_DIVF     FPSTART; \
00428   state.f[FREG_3] = host2f(f2host(state.f[FREG_1]) / f2host(state.f[FREG_2]));
00429 #define DO_DIVT     FPSTART; \
00430   state.f[FREG_3] = host2t(t2host(state.f[FREG_1]) / t2host(state.f[FREG_2]));
00431 #define DO_DIVS     FPSTART; \
00432   state.f[FREG_3] = host2s(s2host(state.f[FREG_1]) / s2host(state.f[FREG_2]));
00433 
00434 #define DO_SQRTG    FPSTART; \
00435   state.f[FREG_3] = host2g(sqrt(g2host(state.f[FREG_2])));
00436 #define DO_SQRTF    FPSTART; \
00437   state.f[FREG_3] = host2f(sqrt(f2host(state.f[FREG_2])));
00438 #define DO_SQRTT    FPSTART; \
00439   state.f[FREG_3] = host2t(sqrt(t2host(state.f[FREG_2])));
00440 #define DO_SQRTS    FPSTART; \
00441   state.f[FREG_3] = host2s(sqrt(s2host(state.f[FREG_2])));
00442 
00443 #define DO_CVTST    FPSTART; \
00444   state.f[FREG_3] = host2t(s2host(state.f[FREG_2]));
00445 #define DO_CVTTS    FPSTART; \
00446   state.f[FREG_3] = host2s(t2host(state.f[FREG_2]));
00447 #endif

SourceForge.net Logo
Project space on SourceForge.net