DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/cpu/core_dynrec/dyn_fpu.h
00001 /*
00002  *  Copyright (C) 2002-2020  The DOSBox Team
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License along
00015  *  with this program; if not, write to the Free Software Foundation, Inc.,
00016  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 
00019 
00020 
00021 #include "dosbox.h"
00022 #if C_FPU
00023 
00024 #include <math.h>
00025 #include <float.h>
00026 #include "cross.h"
00027 #include "mem.h"
00028 #include "fpu.h"
00029 #include "cpu.h"
00030 
00031 
00032 static void FPU_FDECSTP(){
00033         TOP = (TOP - 1) & 7;
00034 }
00035 
00036 static void FPU_FINCSTP(){
00037         TOP = (TOP + 1) & 7;
00038 }
00039 
00040 static void FPU_FNSTCW(PhysPt addr){
00041         mem_writew(addr,fpu.cw);
00042 }
00043 
00044 static void FPU_FFREE(Bitu st) {
00045         fpu.tags[st]=TAG_Empty;
00046 }
00047 
00048 
00049 #if C_FPU_X86
00050 #include "../../fpu/fpu_instructions_x86.h"
00051 #elif defined(HAS_LONG_DOUBLE)
00052 #include "../../fpu/fpu_instructions_longdouble.h"
00053 #else
00054 #include "../../fpu/fpu_instructions.h"
00055 #endif
00056 
00057 
00058 static INLINE void dyn_fpu_top() {
00059         gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
00060         gen_add_imm(FC_OP2,decode.modrm.rm);
00061         gen_and_imm(FC_OP2,7);
00062         gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
00063 }
00064 
00065 static INLINE void dyn_fpu_top_swapped() {
00066         gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
00067         gen_add_imm(FC_OP1,decode.modrm.rm);
00068         gen_and_imm(FC_OP1,7);
00069         gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
00070 }
00071 
00072 static void dyn_eatree() {
00073 //      Bitu group = (decode.modrm.val >> 3) & 7;
00074         Bitu group = decode.modrm.reg&7; //It is already that, but compilers.
00075         switch (group){
00076         case 0x00:              // FADD ST,STi
00077                 gen_call_function_R(FPU_FADD_EA,FC_OP1);
00078                 break;
00079         case 0x01:              // FMUL  ST,STi
00080                 gen_call_function_R(FPU_FMUL_EA,FC_OP1);
00081                 break;
00082         case 0x02:              // FCOM  STi
00083                 gen_call_function_R(FPU_FCOM_EA,FC_OP1);
00084                 break;
00085         case 0x03:              // FCOMP STi
00086                 gen_call_function_R(FPU_FCOM_EA,FC_OP1);
00087                 gen_call_function_raw(FPU_FPOP);
00088                 break;
00089         case 0x04:              // FSUB  ST,STi
00090                 gen_call_function_R(FPU_FSUB_EA,FC_OP1);
00091                 break;  
00092         case 0x05:              // FSUBR ST,STi
00093                 gen_call_function_R(FPU_FSUBR_EA,FC_OP1);
00094                 break;
00095         case 0x06:              // FDIV  ST,STi
00096                 gen_call_function_R(FPU_FDIV_EA,FC_OP1);
00097                 break;
00098         case 0x07:              // FDIVR ST,STi
00099                 gen_call_function_R(FPU_FDIVR_EA,FC_OP1);
00100                 break;
00101         default:
00102                 break;
00103         }
00104 }
00105 
00106 static void dyn_fpu_esc0(){
00107         dyn_get_modrm(); 
00108 //      if (decode.modrm.val >= 0xc0) {
00109         if (decode.modrm.mod == 3) { 
00110                 dyn_fpu_top();
00111                 switch (decode.modrm.reg){
00112                 case 0x00:              //FADD ST,STi
00113                         gen_call_function_RR(FPU_FADD,FC_OP1,FC_OP2);
00114                         break;
00115                 case 0x01:              // FMUL  ST,STi
00116                         gen_call_function_RR(FPU_FMUL,FC_OP1,FC_OP2);
00117                         break;
00118                 case 0x02:              // FCOM  STi
00119                         gen_call_function_RR(FPU_FCOM,FC_OP1,FC_OP2);
00120                         break;
00121                 case 0x03:              // FCOMP STi
00122                         gen_call_function_RR(FPU_FCOM,FC_OP1,FC_OP2);
00123                         gen_call_function_raw(FPU_FPOP);
00124                         break;
00125                 case 0x04:              // FSUB  ST,STi
00126                         gen_call_function_RR(FPU_FSUB,FC_OP1,FC_OP2);
00127                         break;  
00128                 case 0x05:              // FSUBR ST,STi
00129                         gen_call_function_RR(FPU_FSUBR,FC_OP1,FC_OP2);
00130                         break;
00131                 case 0x06:              // FDIV  ST,STi
00132                         gen_call_function_RR(FPU_FDIV,FC_OP1,FC_OP2);
00133                         break;
00134                 case 0x07:              // FDIVR ST,STi
00135                         gen_call_function_RR(FPU_FDIVR,FC_OP1,FC_OP2);
00136                         break;
00137                 default:
00138                         break;
00139                 }
00140         } else { 
00141                 dyn_fill_ea(FC_ADDR);
00142                 gen_call_function_R(FPU_FLD_F32_EA,FC_ADDR); 
00143                 gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
00144                 dyn_eatree();
00145         }
00146 }
00147 
00148 
00149 static void dyn_fpu_esc1(){
00150         dyn_get_modrm();  
00151 //      if (decode.modrm.val >= 0xc0) { 
00152         if (decode.modrm.mod == 3) {
00153                 switch (decode.modrm.reg){
00154                 case 0x00: /* FLD STi */
00155                         gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
00156                         gen_add_imm(FC_OP1,decode.modrm.rm);
00157                         gen_and_imm(FC_OP1,7);
00158                         gen_protect_reg(FC_OP1);
00159                         gen_call_function_raw(FPU_PREP_PUSH); 
00160                         gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
00161                         gen_restore_reg(FC_OP1);
00162                         gen_call_function_RR(FPU_FST,FC_OP1,FC_OP2);
00163                         break;
00164                 case 0x01: /* FXCH STi */
00165                         dyn_fpu_top();
00166                         gen_call_function_RR(FPU_FXCH,FC_OP1,FC_OP2);
00167                         break;
00168                 case 0x02: /* FNOP */
00169                         gen_call_function_raw(FPU_FNOP);
00170                         break;
00171                 case 0x03: /* FSTP STi */
00172                         dyn_fpu_top();
00173                         gen_call_function_RR(FPU_FST,FC_OP1,FC_OP2);
00174                         gen_call_function_raw(FPU_FPOP);
00175                         break;   
00176                 case 0x04:
00177                         switch(decode.modrm.rm){
00178                         case 0x00:       /* FCHS */
00179                                 gen_call_function_raw(FPU_FCHS);
00180                                 break;
00181                         case 0x01:       /* FABS */
00182                                 gen_call_function_raw(FPU_FABS);
00183                                 break;
00184                         case 0x02:       /* UNKNOWN */
00185                         case 0x03:       /* ILLEGAL */
00186                                 LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00187                                 break;
00188                         case 0x04:       /* FTST */
00189                                 gen_call_function_raw(FPU_FTST);
00190                                 break;
00191                         case 0x05:       /* FXAM */
00192                                 gen_call_function_raw(FPU_FXAM);
00193                                 break;
00194                         case 0x06:       /* FTSTP (cyrix)*/
00195                         case 0x07:       /* UNKNOWN */
00196                                 LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00197                                 break;
00198                         }
00199                         break;
00200                 case 0x05:
00201                         switch(decode.modrm.rm){        
00202                         case 0x00:       /* FLD1 */
00203                                 gen_call_function_raw(FPU_FLD1);
00204                                 break;
00205                         case 0x01:       /* FLDL2T */
00206                                 gen_call_function_raw(FPU_FLDL2T);
00207                                 break;
00208                         case 0x02:       /* FLDL2E */
00209                                 gen_call_function_raw(FPU_FLDL2E);
00210                                 break;
00211                         case 0x03:       /* FLDPI */
00212                                 gen_call_function_raw(FPU_FLDPI);
00213                                 break;
00214                         case 0x04:       /* FLDLG2 */
00215                                 gen_call_function_raw(FPU_FLDLG2);
00216                                 break;
00217                         case 0x05:       /* FLDLN2 */
00218                                 gen_call_function_raw(FPU_FLDLN2);
00219                                 break;
00220                         case 0x06:       /* FLDZ*/
00221                                 gen_call_function_raw(FPU_FLDZ);
00222                                 break;
00223                         case 0x07:       /* ILLEGAL */
00224                                 LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00225                                 break;
00226                         }
00227                         break;
00228                 case 0x06:
00229                         switch(decode.modrm.rm){
00230                         case 0x00:      /* F2XM1 */
00231                                 gen_call_function_raw(FPU_F2XM1);
00232                                 break;
00233                         case 0x01:      /* FYL2X */
00234                                 gen_call_function_raw(FPU_FYL2X);
00235                                 break;
00236                         case 0x02:      /* FPTAN  */
00237                                 gen_call_function_raw(FPU_FPTAN);
00238                                 break;
00239                         case 0x03:      /* FPATAN */
00240                                 gen_call_function_raw(FPU_FPATAN);
00241                                 break;
00242                         case 0x04:      /* FXTRACT */
00243                                 gen_call_function_raw(FPU_FXTRACT);
00244                                 break;
00245                         case 0x05:      /* FPREM1 */
00246                                 gen_call_function_raw(FPU_FPREM1);
00247                                 break;
00248                         case 0x06:      /* FDECSTP */
00249                                 gen_call_function_raw(FPU_FDECSTP);
00250                                 break;
00251                         case 0x07:      /* FINCSTP */
00252                                 gen_call_function_raw(FPU_FINCSTP);
00253                                 break;
00254                         default:
00255                                 LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00256                                 break;
00257                         }
00258                         break;
00259                 case 0x07:
00260                         switch(decode.modrm.rm){
00261                         case 0x00:              /* FPREM */
00262                                 gen_call_function_raw(FPU_FPREM);
00263                                 break;
00264                         case 0x01:              /* FYL2XP1 */
00265                                 gen_call_function_raw(FPU_FYL2XP1);
00266                                 break;
00267                         case 0x02:              /* FSQRT */
00268                                 gen_call_function_raw(FPU_FSQRT);
00269                                 break;
00270                         case 0x03:              /* FSINCOS */
00271                                 gen_call_function_raw(FPU_FSINCOS);
00272                                 break;
00273                         case 0x04:              /* FRNDINT */
00274                                 gen_call_function_raw(FPU_FRNDINT);
00275                                 break;
00276                         case 0x05:              /* FSCALE */
00277                                 gen_call_function_raw(FPU_FSCALE);
00278                                 break;
00279                         case 0x06:              /* FSIN */
00280                                 gen_call_function_raw(FPU_FSIN);
00281                                 break;
00282                         case 0x07:              /* FCOS */
00283                                 gen_call_function_raw(FPU_FCOS);
00284                                 break;
00285                         default:
00286                                 LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00287                                 break;
00288                         }
00289                         break;
00290                 default:
00291                         LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00292                         break;
00293                 }
00294         } else {
00295                 switch(decode.modrm.reg){
00296                 case 0x00: /* FLD float*/
00297                         gen_call_function_raw(FPU_PREP_PUSH);
00298                         dyn_fill_ea(FC_OP1);
00299                         gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
00300                         gen_call_function_RR(FPU_FLD_F32,FC_OP1,FC_OP2);
00301                         break;
00302                 case 0x01: /* UNKNOWN */
00303                         LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00304                         break;
00305                 case 0x02: /* FST float*/
00306                         dyn_fill_ea(FC_ADDR);
00307                         gen_call_function_R(FPU_FST_F32,FC_ADDR);
00308                         break;
00309                 case 0x03: /* FSTP float*/
00310                         dyn_fill_ea(FC_ADDR);
00311                         gen_call_function_R(FPU_FST_F32,FC_ADDR);
00312                         gen_call_function_raw(FPU_FPOP);
00313                         break;
00314                 case 0x04: /* FLDENV */
00315                         dyn_fill_ea(FC_ADDR);
00316                         gen_call_function_R(FPU_FLDENV,FC_ADDR);
00317                         break;
00318                 case 0x05: /* FLDCW */
00319                         dyn_fill_ea(FC_ADDR);
00320                         gen_call_function_R(FPU_FLDCW,FC_ADDR);
00321                         break;
00322                 case 0x06: /* FSTENV */
00323                         dyn_fill_ea(FC_ADDR);
00324                         gen_call_function_R(FPU_FSTENV,FC_ADDR);
00325                         break;
00326                 case 0x07:  /* FNSTCW*/
00327                         dyn_fill_ea(FC_ADDR);
00328                         gen_call_function_R(FPU_FNSTCW,FC_ADDR);
00329                         break;
00330                 default:
00331                         LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00332                         break;
00333                 }
00334         }
00335 }
00336 
00337 static void dyn_fpu_esc2(){
00338         dyn_get_modrm();  
00339 //      if (decode.modrm.val >= 0xc0) { 
00340         if (decode.modrm.mod == 3) {
00341                 switch(decode.modrm.reg){
00342                 case 0x05:
00343                         switch(decode.modrm.rm){
00344                         case 0x01:              /* FUCOMPP */
00345                                 gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
00346                                 gen_add_imm(FC_OP2,1);
00347                                 gen_and_imm(FC_OP2,7);
00348                                 gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
00349                                 gen_call_function_RR(FPU_FUCOM,FC_OP1,FC_OP2);
00350                                 gen_call_function_raw(FPU_FPOP);
00351                                 gen_call_function_raw(FPU_FPOP);
00352                                 break;
00353                         default:
00354                                 LOG(LOG_FPU,LOG_WARN)("ESC 2:Unhandled group %d subfunction %d",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm); 
00355                                 break;
00356                         }
00357                         break;
00358                 default:
00359                         LOG(LOG_FPU,LOG_WARN)("ESC 2:Unhandled group %d subfunction %d",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00360                         break;
00361                 }
00362         } else {
00363                 dyn_fill_ea(FC_ADDR);
00364                 gen_call_function_R(FPU_FLD_I32_EA,FC_ADDR); 
00365                 gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
00366                 dyn_eatree();
00367         }
00368 }
00369 
00370 static void dyn_fpu_esc3(){
00371         dyn_get_modrm();  
00372 //      if (decode.modrm.val >= 0xc0) { 
00373         if (decode.modrm.mod == 3) {
00374                 switch (decode.modrm.reg) {
00375                 case 0x04:
00376                         switch (decode.modrm.rm) {
00377                         case 0x00:                              //FNENI
00378                         case 0x01:                              //FNDIS
00379                                 LOG(LOG_FPU,LOG_ERROR)("8087 only fpu code used esc 3: group 4: subfuntion: %d",(int)decode.modrm.rm);
00380                                 break;
00381                         case 0x02:                              //FNCLEX FCLEX
00382                                 gen_call_function_raw(FPU_FCLEX);
00383                                 break;
00384                         case 0x03:                              //FNINIT FINIT
00385                                 gen_call_function_raw(FPU_FINIT);
00386                                 break;
00387                         case 0x04:                              //FNSETPM
00388                         case 0x05:                              //FRSTPM
00389 //                              LOG(LOG_FPU,LOG_ERROR)("80267 protected mode (un)set. Nothing done");
00390                                 break;
00391                         default:
00392                                 E_Exit("ESC 3:ILLEGAL OPCODE group %d subfunction %d",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00393                         }
00394                         break;
00395                 default:
00396                         LOG(LOG_FPU,LOG_WARN)("ESC 3:Unhandled group %d subfunction %d",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00397                         break;
00398                 }
00399         } else {
00400                 switch(decode.modrm.reg){
00401                 case 0x00:      /* FILD */
00402                         gen_call_function_raw(FPU_PREP_PUSH);
00403                         dyn_fill_ea(FC_OP1); 
00404                         gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
00405                         gen_call_function_RR(FPU_FLD_I32,FC_OP1,FC_OP2);
00406                         break;
00407                 case 0x01:      /* FISTTP */
00408                         LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00409                         break;
00410                 case 0x02:      /* FIST */
00411                         dyn_fill_ea(FC_ADDR); 
00412                         gen_call_function_R(FPU_FST_I32,FC_ADDR);
00413                         break;
00414                 case 0x03:      /* FISTP */
00415                         dyn_fill_ea(FC_ADDR); 
00416                         gen_call_function_R(FPU_FST_I32,FC_ADDR);
00417                         gen_call_function_raw(FPU_FPOP);
00418                         break;
00419                 case 0x05:      /* FLD 80 Bits Real */
00420                         gen_call_function_raw(FPU_PREP_PUSH);
00421                         dyn_fill_ea(FC_ADDR); 
00422                         gen_call_function_R(FPU_FLD_F80,FC_ADDR);
00423                         break;
00424                 case 0x07:      /* FSTP 80 Bits Real */
00425                         dyn_fill_ea(FC_ADDR); 
00426                         gen_call_function_R(FPU_FST_F80,FC_ADDR);
00427                         gen_call_function_raw(FPU_FPOP);
00428                         break;
00429                 default:
00430                         LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00431                 }
00432         }
00433 }
00434 
00435 static void dyn_fpu_esc4(){
00436         dyn_get_modrm();  
00437 //      if (decode.modrm.val >= 0xc0) { 
00438         if (decode.modrm.mod == 3) {
00439                 switch(decode.modrm.reg){
00440                 case 0x00:      /* FADD STi,ST*/
00441                         dyn_fpu_top_swapped();
00442                         gen_call_function_RR(FPU_FADD,FC_OP1,FC_OP2);
00443                         break;
00444                 case 0x01:      /* FMUL STi,ST*/
00445                         dyn_fpu_top_swapped();
00446                         gen_call_function_RR(FPU_FMUL,FC_OP1,FC_OP2);
00447                         break;
00448                 case 0x02:  /* FCOM*/
00449                         dyn_fpu_top();
00450                         gen_call_function_RR(FPU_FCOM,FC_OP1,FC_OP2);
00451                         break;
00452                 case 0x03:  /* FCOMP*/
00453                         dyn_fpu_top();
00454                         gen_call_function_RR(FPU_FCOM,FC_OP1,FC_OP2);
00455                         gen_call_function_raw(FPU_FPOP);
00456                         break;
00457                 case 0x04:  /* FSUBR STi,ST*/
00458                         dyn_fpu_top_swapped();
00459                         gen_call_function_RR(FPU_FSUBR,FC_OP1,FC_OP2);
00460                         break;
00461                 case 0x05:  /* FSUB  STi,ST*/
00462                         dyn_fpu_top_swapped();
00463                         gen_call_function_RR(FPU_FSUB,FC_OP1,FC_OP2);
00464                         break;
00465                 case 0x06:  /* FDIVR STi,ST*/
00466                         dyn_fpu_top_swapped();
00467                         gen_call_function_RR(FPU_FDIVR,FC_OP1,FC_OP2);
00468                         break;
00469                 case 0x07:  /* FDIV STi,ST*/
00470                         dyn_fpu_top_swapped();
00471                         gen_call_function_RR(FPU_FDIV,FC_OP1,FC_OP2);
00472                         break;
00473                 default:
00474                         break;
00475                 }
00476         } else { 
00477                 dyn_fill_ea(FC_ADDR);
00478                 gen_call_function_R(FPU_FLD_F64_EA,FC_ADDR); 
00479                 gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
00480                 dyn_eatree();
00481         }
00482 }
00483 
00484 static void dyn_fpu_esc5(){
00485         dyn_get_modrm();  
00486 //      if (decode.modrm.val >= 0xc0) { 
00487         if (decode.modrm.mod == 3) {
00488                 dyn_fpu_top();
00489                 switch(decode.modrm.reg){
00490                 case 0x00: /* FFREE STi */
00491                         gen_call_function_R(FPU_FFREE,FC_OP2);
00492                         break;
00493                 case 0x01: /* FXCH STi*/
00494                         gen_call_function_RR(FPU_FXCH,FC_OP1,FC_OP2);
00495                         break;
00496                 case 0x02: /* FST STi */
00497                         gen_call_function_RR(FPU_FST,FC_OP1,FC_OP2);
00498                         break;
00499                 case 0x03:  /* FSTP STi*/
00500                         gen_call_function_RR(FPU_FST,FC_OP1,FC_OP2);
00501                         gen_call_function_raw(FPU_FPOP);
00502                         break;
00503                 case 0x04:      /* FUCOM STi */
00504                         gen_call_function_RR(FPU_FUCOM,FC_OP1,FC_OP2);
00505                         break;
00506                 case 0x05:      /*FUCOMP STi */
00507                         gen_call_function_RR(FPU_FUCOM,FC_OP1,FC_OP2);
00508                         gen_call_function_raw(FPU_FPOP);
00509                         break;
00510                 default:
00511                         LOG(LOG_FPU,LOG_WARN)("ESC 5:Unhandled group %d subfunction %d",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00512                         break;
00513         }
00514         } else {
00515                 switch(decode.modrm.reg){
00516                 case 0x00:  /* FLD double real*/
00517                         gen_call_function_raw(FPU_PREP_PUSH);
00518                         dyn_fill_ea(FC_OP1); 
00519                         gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
00520                         gen_call_function_RR(FPU_FLD_F64,FC_OP1,FC_OP2);
00521                         break;
00522                 case 0x01:  /* FISTTP longint*/
00523                         LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00524                         break;
00525                 case 0x02:   /* FST double real*/
00526                         dyn_fill_ea(FC_ADDR); 
00527                         gen_call_function_R(FPU_FST_F64,FC_ADDR);
00528                         break;
00529                 case 0x03:      /* FSTP double real*/
00530                         dyn_fill_ea(FC_ADDR); 
00531                         gen_call_function_R(FPU_FST_F64,FC_ADDR);
00532                         gen_call_function_raw(FPU_FPOP);
00533                         break;
00534                 case 0x04:      /* FRSTOR */
00535                         dyn_fill_ea(FC_ADDR); 
00536                         gen_call_function_R(FPU_FRSTOR,FC_ADDR);
00537                         break;
00538                 case 0x06:      /* FSAVE */
00539                         dyn_fill_ea(FC_ADDR); 
00540                         gen_call_function_R(FPU_FSAVE,FC_ADDR);
00541                         break;
00542                 case 0x07:   /*FNSTSW */
00543                         gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
00544                         gen_call_function_R(FPU_SET_TOP,FC_OP1);
00545                         dyn_fill_ea(FC_OP1); 
00546                         gen_mov_word_to_reg(FC_OP2,(void*)(&fpu.sw),false);
00547                         gen_call_function_RR(mem_writew,FC_OP1,FC_OP2);
00548                         break;
00549                 default:
00550                         LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00551                 }
00552         }
00553 }
00554 
00555 static void dyn_fpu_esc6(){
00556         dyn_get_modrm();  
00557 //      if (decode.modrm.val >= 0xc0) { 
00558         if (decode.modrm.mod == 3) {
00559                 switch(decode.modrm.reg){
00560                 case 0x00:      /*FADDP STi,ST*/
00561                         dyn_fpu_top_swapped();
00562                         gen_call_function_RR(FPU_FADD,FC_OP1,FC_OP2);
00563                         break;
00564                 case 0x01:      /* FMULP STi,ST*/
00565                         dyn_fpu_top_swapped();
00566                         gen_call_function_RR(FPU_FMUL,FC_OP1,FC_OP2);
00567                         break;
00568                 case 0x02:  /* FCOMP5*/
00569                         dyn_fpu_top();
00570                         gen_call_function_RR(FPU_FCOM,FC_OP1,FC_OP2);
00571                         break;  /* TODO IS THIS ALLRIGHT ????????? */
00572                 case 0x03:  /*FCOMPP*/
00573                         if(decode.modrm.rm != 1) {
00574                                 LOG(LOG_FPU,LOG_WARN)("ESC 6:Unhandled group %d subfunction %d",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00575                                 return;
00576                         }
00577                         gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
00578                         gen_add_imm(FC_OP2,1);
00579                         gen_and_imm(FC_OP2,7);
00580                         gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
00581                         gen_call_function_RR(FPU_FCOM,FC_OP1,FC_OP2);
00582                         gen_call_function_raw(FPU_FPOP); /* extra pop at the bottom*/
00583                         break;
00584                 case 0x04:  /* FSUBRP STi,ST*/
00585                         dyn_fpu_top_swapped();
00586                         gen_call_function_RR(FPU_FSUBR,FC_OP1,FC_OP2);
00587                         break;
00588                 case 0x05:  /* FSUBP  STi,ST*/
00589                         dyn_fpu_top_swapped();
00590                         gen_call_function_RR(FPU_FSUB,FC_OP1,FC_OP2);
00591                         break;
00592                 case 0x06:      /* FDIVRP STi,ST*/
00593                         dyn_fpu_top_swapped();
00594                         gen_call_function_RR(FPU_FDIVR,FC_OP1,FC_OP2);
00595                         break;
00596                 case 0x07:  /* FDIVP STi,ST*/
00597                         dyn_fpu_top_swapped();
00598                         gen_call_function_RR(FPU_FDIV,FC_OP1,FC_OP2);
00599                         break;
00600                 default:
00601                         break;
00602                 }
00603                 gen_call_function_raw(FPU_FPOP);                
00604         } else {
00605                 dyn_fill_ea(FC_ADDR);
00606                 gen_call_function_R(FPU_FLD_I16_EA,FC_ADDR); 
00607                 gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
00608                 dyn_eatree();
00609         }
00610 }
00611 
00612 static void dyn_fpu_esc7(){
00613         dyn_get_modrm();  
00614 //      if (decode.modrm.val >= 0xc0) { 
00615         if (decode.modrm.mod == 3) {
00616                 switch (decode.modrm.reg){
00617                 case 0x00: /* FFREEP STi */
00618                         dyn_fpu_top();
00619                         gen_call_function_R(FPU_FFREE,FC_OP2);
00620                         gen_call_function_raw(FPU_FPOP);
00621                         break;
00622                 case 0x01: /* FXCH STi*/
00623                         dyn_fpu_top();
00624                         gen_call_function_RR(FPU_FXCH,FC_OP1,FC_OP2);
00625                         break;
00626                 case 0x02:  /* FSTP STi*/
00627                 case 0x03:  /* FSTP STi*/
00628                         dyn_fpu_top();
00629                         gen_call_function_RR(FPU_FST,FC_OP1,FC_OP2);
00630                         gen_call_function_raw(FPU_FPOP);
00631                         break;
00632                 case 0x04:
00633                         switch(decode.modrm.rm){
00634                                 case 0x00:     /* FNSTSW AX*/
00635                                         gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
00636                                         gen_call_function_R(FPU_SET_TOP,FC_OP1); 
00637                                         gen_mov_word_to_reg(FC_OP1,(void*)(&fpu.sw),false);
00638                                         MOV_REG_WORD16_FROM_HOST_REG(FC_OP1,DRC_REG_EAX);
00639                                         break;
00640                                 default:
00641                                         LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00642                                         break;
00643                         }
00644                         break;
00645                 default:
00646                         LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00647                         break;
00648                 }
00649         } else {
00650                 switch(decode.modrm.reg){
00651                 case 0x00:  /* FILD Bit16s */
00652                         gen_call_function_raw(FPU_PREP_PUSH);
00653                         dyn_fill_ea(FC_OP1); 
00654                         gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
00655                         gen_call_function_RR(FPU_FLD_I16,FC_OP1,FC_OP2);
00656                         break;
00657                 case 0x01:
00658                         LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00659                         break;
00660                 case 0x02:   /* FIST Bit16s */
00661                         dyn_fill_ea(FC_ADDR); 
00662                         gen_call_function_R(FPU_FST_I16,FC_ADDR);
00663                         break;
00664                 case 0x03:      /* FISTP Bit16s */
00665                         dyn_fill_ea(FC_ADDR); 
00666                         gen_call_function_R(FPU_FST_I16,FC_ADDR);
00667                         gen_call_function_raw(FPU_FPOP);
00668                         break;
00669                 case 0x04:   /* FBLD packed BCD */
00670                         gen_call_function_raw(FPU_PREP_PUSH);
00671                         dyn_fill_ea(FC_OP1);
00672                         gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
00673                         gen_call_function_RR(FPU_FBLD,FC_OP1,FC_OP2);
00674                         break;
00675                 case 0x05:  /* FILD Bit64s */
00676                         gen_call_function_raw(FPU_PREP_PUSH);
00677                         dyn_fill_ea(FC_OP1);
00678                         gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
00679                         gen_call_function_RR(FPU_FLD_I64,FC_OP1,FC_OP2);
00680                         break;
00681                 case 0x06:      /* FBSTP packed BCD */
00682                         dyn_fill_ea(FC_ADDR); 
00683                         gen_call_function_R(FPU_FBST,FC_ADDR);
00684                         gen_call_function_raw(FPU_FPOP);
00685                         break;
00686                 case 0x07:  /* FISTP Bit64s */
00687                         dyn_fill_ea(FC_ADDR); 
00688                         gen_call_function_R(FPU_FST_I64,FC_ADDR);
00689                         gen_call_function_raw(FPU_FPOP);
00690                         break;
00691                 default:
00692                         LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",(unsigned int)decode.modrm.reg,(unsigned int)decode.modrm.rm);
00693                         break;
00694                 }
00695         }
00696 }
00697 
00698 #endif