DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/cpu/core_dyn_x86/mmx_gen.h
00001 
00002 #include "mmx.h"
00003 
00004 MMX_reg mmxtmp;
00005 
00006 static void MMX_LOAD_32(PhysPt addr) {
00007         mmxtmp.ud.d0 = mem_readd(addr);
00008 }
00009 
00010 static void MMX_STORE_32(PhysPt addr) {
00011         mem_writed(addr, mmxtmp.ud.d0);
00012 }
00013 
00014 static void MMX_LOAD_64(PhysPt addr) {
00015         mmxtmp.ud.d0 = mem_readd(addr);
00016         mmxtmp.ud.d1 = mem_readd(addr + 4);
00017 }
00018 
00019 static void MMX_STORE_64(PhysPt addr) {
00020         mem_writed(addr, mmxtmp.ud.d0);
00021         mem_writed(addr + 4, mmxtmp.ud.d1);
00022 }
00023 
00024 // add simple instruction (that operates only with mm regs)
00025 void dyn_mmx_simple(Bit8u op, Bit8u modrm) {
00026         cache_addw(0x0F | (op << 8)); cache_addb(modrm);
00027 }
00028 
00029 // same but with imm8 also
00030 void dyn_mmx_simple_imm8(Bit8u op, Bit8u modrm, Bit8u imm) {
00031         cache_addw(0x0F | (op << 8)); cache_addb(modrm); cache_addb(imm);
00032 }
00033 
00034 // mmx OP mm, mm/m64 template
00035 void dyn_mmx_op(Bit8u op) {
00036         dyn_get_modrm();
00037 
00038         if (decode.modrm.mod < 3) {
00039                 dyn_fill_ea();
00040                 gen_call_function((void*)&MMX_LOAD_64, "%Ddr", DREG(EA));
00041                 cache_addw(0x0F | (op << 8));
00042                 cache_addb(0x05 | (decode.modrm.val & 0x38));
00043                 cache_addd((uintptr_t)&mmxtmp);
00044         } else dyn_mmx_simple(op, decode.modrm.val);
00045 }
00046 
00047 // mmx SHIFT mm, imm8 template 
00048 void dyn_mmx_shift_imm8(Bit8u op) {
00049         dyn_get_modrm();
00050         Bitu imm; decode_fetchb_imm(imm);
00051         
00052         dyn_mmx_simple_imm8(op, decode.modrm.val, imm);
00053 }
00054 
00055 // 0x6E - MOVD mm, r/m32
00056 void dyn_mmx_movd_pqed() {
00057         dyn_get_modrm();
00058 
00059         if (decode.modrm.mod < 3) {
00060                 // movd mm, m32 - resolve EA and load data
00061                 dyn_fill_ea();
00062                 // generate call to mmxtmp load
00063                 gen_call_function((void*)&MMX_LOAD_32, "%Ddr", DREG(EA));
00064                 // mmxtmp contains loaded value - finish by loading it to mm
00065                 cache_addw(0x6E0F);     // movd  mm, m32
00066                 cache_addb(0x05 | (decode.modrm.val & 0x38));
00067                 cache_addd((uintptr_t)&mmxtmp);
00068         }
00069         else {
00070                 // movd mm, r32 - r32->mmxtmp->mm
00071                 // resolve dynreg
00072                 DynReg *reg = &DynRegs[decode.modrm.rm];
00073                 // resolve genreg
00074                 GenReg *gr = FindDynReg(reg);
00075                 // move from genreg to mmxtmp
00076                 cache_addb(0x89);       // mov m32, r32
00077                 cache_addb(0x05 | (gr->index << 3));
00078                 cache_addd((uintptr_t)&mmxtmp);
00079                 // mmxtmp contains loaded value - finish by loading it to mm
00080                 cache_addw(0x6E0F);     // movd  mm, m32
00081                 cache_addb(0x05 | (decode.modrm.val & 0x38));
00082                 cache_addd((uintptr_t)&mmxtmp);
00083         }
00084 }
00085 
00086 
00087 // 0x6F - MOVQ mm, mm/m64
00088 void dyn_mmx_movq_pqqq() {
00089         dyn_get_modrm(); 
00090 
00091         if (decode.modrm.mod < 3) {
00092                 // movq mm, m64 - resolve EA and load data
00093                 dyn_fill_ea();
00094                 // generate call to mmxtmp load
00095                 gen_call_function((void*)&MMX_LOAD_64, "%Ddr", DREG(EA));
00096                 // mmxtmp contains loaded value - finish by loading it to mm
00097                 cache_addw(0x6F0F);     // movq  mm, m64
00098                 cache_addb(0x05 | (decode.modrm.val & 0x38));
00099                 cache_addd((uintptr_t)&mmxtmp);
00100         }
00101         else {
00102                 // movq mm, mm
00103                 dyn_mmx_simple(0x6F, decode.modrm.val);
00104         }
00105 }
00106 
00107 // 0x7E - MOVD r/m32, mm 
00108 void dyn_mmx_movd_edpq() {
00109         dyn_get_modrm();
00110 
00111         if (decode.modrm.mod < 3) {
00112                 // movd m32, mm - resolve EA and load data
00113                 dyn_fill_ea();
00114                 // fill mmxtmp
00115                 cache_addw(0x7E0F);     // movd  mm, m32
00116                 cache_addb(0x05 | (decode.modrm.val & 0x38));
00117                 cache_addd((uintptr_t)&mmxtmp);
00118                 // generate call to mmxtmp store
00119                 gen_call_function((void*)&MMX_STORE_32, "%Ddr", DREG(EA));
00120         }
00121         else {
00122                 // movd r32, mm - mm->mmxtmp->r32
00123                 // resolve dynreg
00124                 DynReg *reg = &DynRegs[decode.modrm.rm];
00125                 // resolve genreg
00126                 GenReg *gr = FindDynReg(reg);
00127                 // fill mmxtmp
00128                 cache_addw(0x7E0F);     // movd  mm, m32
00129                 cache_addb(0x05 | (decode.modrm.val & 0x38));
00130                 cache_addd((uintptr_t)&mmxtmp);
00131                 // move from mmxtmp to genreg
00132                 cache_addb(0x8b);       // mov r32, m32
00133                 cache_addb(0x05 | (gr->index << 3));
00134                 cache_addd((uintptr_t)&mmxtmp);
00135                 // mark dynreg as changed
00136                 reg->flags |= DYNFLG_CHANGED;
00137         }
00138 }
00139 
00140 // 0x7F - MOVQ mm/m64, mm
00141 void dyn_mmx_movq_qqpq() {
00142         dyn_get_modrm();
00143 
00144         if (decode.modrm.mod < 3) {
00145                 // movq m64, mm - resolve EA and load data
00146                 dyn_fill_ea();
00147                 // fill mmxtmp
00148                 cache_addw(0x7F0F);     // movq  mm, m64
00149                 cache_addb(0x05 | (decode.modrm.val & 0x38));
00150                 cache_addd((uintptr_t)&mmxtmp);
00151                 // generate call to mmxtmp store
00152                 gen_call_function((void*)&MMX_STORE_64, "%Ddr", DREG(EA));
00153         }
00154         else {
00155                 // movq mm, mm
00156                 dyn_mmx_simple(0x7F, decode.modrm.val);
00157         }
00158 }
00159 
00160 // 0x77 - EMMS
00161 void dyn_mmx_emms() {
00162         cache_addw(0x770F);
00163 }