diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index 787bc908..14730d6e 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: core_dynrec.cpp,v 1.10 2008-08-20 14:13:21 c2woody Exp $ */ +/* $Id: core_dynrec.cpp,v 1.11 2008-09-19 16:48:02 c2woody Exp $ */ #include "dosbox.h" @@ -92,7 +92,7 @@ // access to a general register -#define DRCD_REG(reg) (&cpu_regs.regs[reg].dword) +#define DRCD_REG_VAL(reg) (&cpu_regs.regs[reg].dword) // access to a segment register #define DRCD_SEG_VAL(seg) (&Segs.val[seg]) // access to the physical value of a segment register/selector diff --git a/src/cpu/core_dynrec/Makefile.am b/src/cpu/core_dynrec/Makefile.am index ca58ca90..05edb3cf 100644 --- a/src/cpu/core_dynrec/Makefile.am +++ b/src/cpu/core_dynrec/Makefile.am @@ -1,4 +1,6 @@ noinst_HEADERS = cache.h decoder.h decoder_basic.h decoder_opcodes.h \ dyn_fpu.h operators.h risc_x64.h risc_x86.h risc_mipsel32.h \ risc_armv4le.h risc_armv4le-common.h \ - risc_armv4le-s3.h risc_armv4le-o3.h risc_armv4le-thumb.h + risc_armv4le-s3.h risc_armv4le-o3.h risc_armv4le-thumb.h \ + risc_armv4le-thumb-iw.h risc_armv4le-thumb-niw.h \ + decoder_macros.h diff --git a/src/cpu/core_dynrec/decoder.h b/src/cpu/core_dynrec/decoder.h index 76603912..1e32843a 100644 --- a/src/cpu/core_dynrec/decoder.h +++ b/src/cpu/core_dynrec/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * Copyright (C) 2002-2008 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: decoder.h,v 1.5 2008-09-19 16:48:02 c2woody Exp $ */ + #include "decoder_basic.h" #include "operators.h" @@ -324,11 +326,7 @@ restart_prefix: case 0x8c:dyn_mov_ev_seg();break; // load effective address - case 0x8d: - dyn_get_modrm(); - dyn_fill_ea(FC_ADDR,false); - gen_mov_word_from_reg(FC_ADDR,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); - break; + case 0x8d:dyn_lea();break; // move a value from memory or a 16bit register into a segment register case 0x8e:dyn_mov_seg_ev();break; diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index d568da4d..541cb70a 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: decoder_basic.h,v 1.12 2008-09-02 20:44:41 c2woody Exp $ */ +/* $Id: decoder_basic.h,v 1.13 2008-09-19 16:48:02 c2woody Exp $ */ /* @@ -352,6 +352,89 @@ static void INLINE dyn_get_modrm(void) { } +#ifdef DRC_USE_SEGS_ADDR + +#define MOV_SEG_VAL_TO_HOST_REG(host_reg, seg_index) gen_mov_seg16_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_SEG_VAL(seg_index)) - (DRC_PTR_SIZE_IM)(&Segs)) + +#define MOV_SEG_PHYS_TO_HOST_REG(host_reg, seg_index) gen_mov_seg32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_SEG_PHYS(seg_index)) - (DRC_PTR_SIZE_IM)(&Segs)) +#define ADD_SEG_PHYS_TO_HOST_REG(host_reg, seg_index) gen_add_seg32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_SEG_PHYS(seg_index)) - (DRC_PTR_SIZE_IM)(&Segs)) + +#else + +#define MOV_SEG_VAL_TO_HOST_REG(host_reg, seg_index) gen_mov_word_to_reg(host_reg,DRCD_SEG_VAL(seg_index),false) + +#define MOV_SEG_PHYS_TO_HOST_REG(host_reg, seg_index) gen_mov_word_to_reg(host_reg,DRCD_SEG_PHYS(seg_index),true) +#define ADD_SEG_PHYS_TO_HOST_REG(host_reg, seg_index) gen_add(host_reg,DRCD_SEG_PHYS(seg_index)) + +#endif + + +#ifdef DRC_USE_REGS_ADDR + +#define MOV_REG_VAL_TO_HOST_REG(host_reg, reg_index) gen_mov_regval32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_VAL(reg_index)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) +#define ADD_REG_VAL_TO_HOST_REG(host_reg, reg_index) gen_add_regval32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_VAL(reg_index)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) + +#define MOV_REG_WORD16_TO_HOST_REG(host_reg, reg_index) gen_mov_regval16_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,false)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) +#define MOV_REG_WORD32_TO_HOST_REG(host_reg, reg_index) gen_mov_regval32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,true)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) +#define MOV_REG_WORD_TO_HOST_REG(host_reg, reg_index, dword) gen_mov_regword_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,dword)) - (DRC_PTR_SIZE_IM)(&cpu_regs), dword) + +#define MOV_REG_WORD16_FROM_HOST_REG(host_reg, reg_index) gen_mov_regval16_from_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,false)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) +#define MOV_REG_WORD32_FROM_HOST_REG(host_reg, reg_index) gen_mov_regval32_from_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,true)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) +#define MOV_REG_WORD_FROM_HOST_REG(host_reg, reg_index, dword) gen_mov_regword_from_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,dword)) - (DRC_PTR_SIZE_IM)(&cpu_regs), dword) + +#define MOV_REG_BYTE_TO_HOST_REG_LOW(host_reg, reg_index, high_byte) gen_mov_regbyte_to_reg_low(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_BYTE(reg_index,high_byte)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) +#define MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(host_reg, reg_index, high_byte) gen_mov_regbyte_to_reg_low_canuseword(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_BYTE(reg_index,high_byte)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) +#define MOV_REG_BYTE_FROM_HOST_REG_LOW(host_reg, reg_index, high_byte) gen_mov_regbyte_from_reg_low(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_BYTE(reg_index,high_byte)) - (DRC_PTR_SIZE_IM)(&cpu_regs)) + +#else + +#define MOV_REG_VAL_TO_HOST_REG(host_reg, reg_index) gen_mov_word_to_reg(host_reg,DRCD_REG_VAL(reg_index),true) +#define ADD_REG_VAL_TO_HOST_REG(host_reg, reg_index) gen_add(host_reg,DRCD_REG_VAL(reg_index)) + +#define MOV_REG_WORD16_TO_HOST_REG(host_reg, reg_index) gen_mov_word_to_reg(host_reg,DRCD_REG_WORD(reg_index,false),false) +#define MOV_REG_WORD32_TO_HOST_REG(host_reg, reg_index) gen_mov_word_to_reg(host_reg,DRCD_REG_WORD(reg_index,true),true) +#define MOV_REG_WORD_TO_HOST_REG(host_reg, reg_index, dword) gen_mov_word_to_reg(host_reg,DRCD_REG_WORD(reg_index,dword),dword) + +#define MOV_REG_WORD16_FROM_HOST_REG(host_reg, reg_index) gen_mov_word_from_reg(host_reg,DRCD_REG_WORD(reg_index,false),false) +#define MOV_REG_WORD32_FROM_HOST_REG(host_reg, reg_index) gen_mov_word_from_reg(host_reg,DRCD_REG_WORD(reg_index,true),true) +#define MOV_REG_WORD_FROM_HOST_REG(host_reg, reg_index, dword) gen_mov_word_from_reg(host_reg,DRCD_REG_WORD(reg_index,dword),dword) + +#define MOV_REG_BYTE_TO_HOST_REG_LOW(host_reg, reg_index, high_byte) gen_mov_byte_to_reg_low(host_reg,DRCD_REG_BYTE(reg_index,high_byte)) +#define MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(host_reg, reg_index, high_byte) gen_mov_byte_to_reg_low_canuseword(host_reg,DRCD_REG_BYTE(reg_index,high_byte)) +#define MOV_REG_BYTE_FROM_HOST_REG_LOW(host_reg, reg_index, high_byte) gen_mov_byte_from_reg_low(host_reg,DRCD_REG_BYTE(reg_index,high_byte)) + +#endif + + +#define DYN_LEA_MEM_MEM(ea_reg, op1, op2, scale, imm) dyn_lea_mem_mem(ea_reg,op1,op2,scale,imm) + +#if defined(DRC_USE_REGS_ADDR) && defined(DRC_USE_SEGS_ADDR) + +#define DYN_LEA_SEG_PHYS_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_segphys_regval(ea_reg,op1_index,op2_index,scale,imm) +#define DYN_LEA_REG_VAL_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_regval_regval(ea_reg,op1_index,op2_index,scale,imm) +#define DYN_LEA_MEM_REG_VAL(ea_reg, op1, op2_index, scale, imm) dyn_lea_mem_regval(ea_reg,op1,op2_index,scale,imm) + +#elif defined(DRC_USE_REGS_ADDR) + +#define DYN_LEA_SEG_PHYS_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_mem_regval(ea_reg,DRCD_SEG_PHYS(op1_index),op2_index,scale,imm) +#define DYN_LEA_REG_VAL_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_regval_regval(ea_reg,op1_index,op2_index,scale,imm) +#define DYN_LEA_MEM_REG_VAL(ea_reg, op1, op2_index, scale, imm) dyn_lea_mem_regval(ea_reg,op1,op2_index,scale,imm) + +#elif defined(DRC_USE_SEGS_ADDR) + +#define DYN_LEA_SEG_PHYS_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_segphys_mem(ea_reg,op1_index,DRCD_REG_VAL(op2_index),scale,imm) +#define DYN_LEA_REG_VAL_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_mem_mem(ea_reg,DRCD_REG_VAL(op1_index),DRCD_REG_VAL(op2_index),scale,imm) +#define DYN_LEA_MEM_REG_VAL(ea_reg, op1, op2_index, scale, imm) dyn_lea_mem_mem(ea_reg,op1,DRCD_REG_VAL(op2_index),scale,imm) + +#else + +#define DYN_LEA_SEG_PHYS_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_mem_mem(ea_reg,DRCD_SEG_PHYS(op1_index),DRCD_REG_VAL(op2_index),scale,imm) +#define DYN_LEA_REG_VAL_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_mem_mem(ea_reg,DRCD_REG_VAL(op1_index),DRCD_REG_VAL(op2_index),scale,imm) +#define DYN_LEA_MEM_REG_VAL(ea_reg, op1, op2_index, scale, imm) dyn_lea_mem_mem(ea_reg,op1,DRCD_REG_VAL(op2_index),scale,imm) + +#endif + + // adjust CPU_Cycles value static void dyn_reduce_cycles(void) { @@ -689,7 +772,7 @@ static void dyn_write_word(HostReg reg_addr,HostReg reg_val,bool dword) { // effective address calculation helper, op2 has to be present! // loads op1 into ea_reg and adds the scaled op2 and the immediate to it -static void dyn_lea(HostReg ea_reg,void* op1,void* op2,Bitu scale,Bits imm) { +static void dyn_lea_mem_mem(HostReg ea_reg,void* op1,void* op2,Bitu scale,Bits imm) { if (scale || imm) { if (op1!=NULL) { gen_mov_word_to_reg(ea_reg,op1,true); @@ -706,6 +789,79 @@ static void dyn_lea(HostReg ea_reg,void* op1,void* op2,Bitu scale,Bits imm) { } } +#ifdef DRC_USE_REGS_ADDR +// effective address calculation helper +// loads op1 into ea_reg and adds the scaled op2 and the immediate to it +// op1 is cpu_regs[op1_index], op2 is cpu_regs[op2_index] +static void dyn_lea_regval_regval(HostReg ea_reg,Bitu op1_index,Bitu op2_index,Bitu scale,Bits imm) { + if (scale || imm) { + MOV_REG_VAL_TO_HOST_REG(ea_reg,op1_index); + MOV_REG_VAL_TO_HOST_REG(TEMP_REG_DRC,op2_index); + + gen_lea(ea_reg,TEMP_REG_DRC,scale,imm); + } else { + MOV_REG_VAL_TO_HOST_REG(ea_reg,op2_index); + ADD_REG_VAL_TO_HOST_REG(ea_reg,op1_index); + } +} + +// effective address calculation helper +// loads op1 into ea_reg and adds the scaled op2 and the immediate to it +// op2 is cpu_regs[op2_index] +static void dyn_lea_mem_regval(HostReg ea_reg,void* op1,Bitu op2_index,Bitu scale,Bits imm) { + if (scale || imm) { + if (op1!=NULL) { + gen_mov_word_to_reg(ea_reg,op1,true); + MOV_REG_VAL_TO_HOST_REG(TEMP_REG_DRC,op2_index); + + gen_lea(ea_reg,TEMP_REG_DRC,scale,imm); + } else { + MOV_REG_VAL_TO_HOST_REG(ea_reg,op2_index); + gen_lea(ea_reg,scale,imm); + } + } else { + MOV_REG_VAL_TO_HOST_REG(ea_reg,op2_index); + if (op1!=NULL) gen_add(ea_reg,op1); + } +} +#endif + +#ifdef DRC_USE_SEGS_ADDR +#ifdef DRC_USE_REGS_ADDR +// effective address calculation helper +// loads op1 into ea_reg and adds the scaled op2 and the immediate to it +// op1 is Segs[op1_index], op2 is cpu_regs[op2_index] +static void dyn_lea_segphys_regval(HostReg ea_reg,Bitu op1_index,Bitu op2_index,Bitu scale,Bits imm) { + if (scale || imm) { + MOV_SEG_PHYS_TO_HOST_REG(ea_reg,op1_index); + MOV_REG_VAL_TO_HOST_REG(TEMP_REG_DRC,op2_index); + + gen_lea(ea_reg,TEMP_REG_DRC,scale,imm); + } else { + MOV_REG_VAL_TO_HOST_REG(ea_reg,op2_index); + ADD_SEG_PHYS_TO_HOST_REG(ea_reg,op1_index); + } +} + +#else + +// effective address calculation helper, op2 has to be present! +// loads op1 into ea_reg and adds the scaled op2 and the immediate to it +// op1 is Segs[op1_index] +static void dyn_lea_segphys_mem(HostReg ea_reg,Bitu op1_index,void* op2,Bitu scale,Bits imm) { + if (scale || imm) { + MOV_SEG_PHYS_TO_HOST_REG(ea_reg,op1_index); + gen_mov_word_to_reg(TEMP_REG_DRC,op2,true); + + gen_lea(ea_reg,TEMP_REG_DRC,scale,imm); + } else { + gen_mov_word_to_reg(ea_reg,op2,true); + ADD_SEG_PHYS_TO_HOST_REG(ea_reg,op1_index); + } +} +#endif +#endif + // calculate the effective address and store it in ea_reg static void dyn_fill_ea(HostReg ea_reg,bool addseg=true) { Bit8u seg_base=DRC_SEG_DS; @@ -718,25 +874,25 @@ static void dyn_fill_ea(HostReg ea_reg,bool addseg=true) { } switch (decode.modrm.rm) { case 0:// BX+SI - dyn_lea(ea_reg,DRCD_REG(DRC_REG_EBX),DRCD_REG(DRC_REG_ESI),0,imm); + DYN_LEA_REG_VAL_REG_VAL(ea_reg,DRC_REG_EBX,DRC_REG_ESI,0,imm); break; case 1:// BX+DI - dyn_lea(ea_reg,DRCD_REG(DRC_REG_EBX),DRCD_REG(DRC_REG_EDI),0,imm); + DYN_LEA_REG_VAL_REG_VAL(ea_reg,DRC_REG_EBX,DRC_REG_EDI,0,imm); break; case 2:// BP+SI - dyn_lea(ea_reg,DRCD_REG(DRC_REG_EBP),DRCD_REG(DRC_REG_ESI),0,imm); + DYN_LEA_REG_VAL_REG_VAL(ea_reg,DRC_REG_EBP,DRC_REG_ESI,0,imm); seg_base=DRC_SEG_SS; break; case 3:// BP+DI - dyn_lea(ea_reg,DRCD_REG(DRC_REG_EBP),DRCD_REG(DRC_REG_EDI),0,imm); + DYN_LEA_REG_VAL_REG_VAL(ea_reg,DRC_REG_EBP,DRC_REG_EDI,0,imm); seg_base=DRC_SEG_SS; break; case 4:// SI - gen_mov_word_to_reg(ea_reg,DRCD_REG(DRC_REG_ESI),true); + MOV_REG_VAL_TO_HOST_REG(ea_reg,DRC_REG_ESI); if (imm) gen_add_imm(ea_reg,(Bit32u)imm); break; case 5:// DI - gen_mov_word_to_reg(ea_reg,DRCD_REG(DRC_REG_EDI),true); + MOV_REG_VAL_TO_HOST_REG(ea_reg,DRC_REG_EDI); if (imm) gen_add_imm(ea_reg,(Bit32u)imm); break; case 6:// imm/BP @@ -745,13 +901,13 @@ static void dyn_fill_ea(HostReg ea_reg,bool addseg=true) { gen_mov_dword_to_reg_imm(ea_reg,(Bit32u)imm); goto skip_extend_word; } else { - gen_mov_word_to_reg(ea_reg,DRCD_REG(DRC_REG_EBP),true); + MOV_REG_VAL_TO_HOST_REG(ea_reg,DRC_REG_EBP); gen_add_imm(ea_reg,(Bit32u)imm); seg_base=DRC_SEG_SS; } break; case 7: // BX - gen_mov_word_to_reg(ea_reg,DRCD_REG(DRC_REG_EBX),true); + MOV_REG_VAL_TO_HOST_REG(ea_reg,DRC_REG_EBX); if (imm) gen_add_imm(ea_reg,(Bit32u)imm); break; } @@ -760,7 +916,7 @@ static void dyn_fill_ea(HostReg ea_reg,bool addseg=true) { skip_extend_word: if (addseg) { // add the physical segment value if requested - gen_add(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); + ADD_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); } } else { Bits imm=0; @@ -804,14 +960,14 @@ skip_extend_word: if (!scaled_reg_used) { gen_mov_word_to_reg(ea_reg,(void*)val,true); } else { - dyn_lea(ea_reg,NULL,DRCD_REG(scaled_reg),scale,0); + DYN_LEA_MEM_REG_VAL(ea_reg,NULL,scaled_reg,scale,0); gen_add(ea_reg,(void*)val); } } else { if (!scaled_reg_used) { - gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); + MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); } else { - dyn_lea(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),DRCD_REG(scaled_reg),scale,0); + DYN_LEA_SEG_PHYS_REG_VAL(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base),scaled_reg,scale,0); } gen_add(ea_reg,(void*)val); } @@ -824,14 +980,14 @@ skip_extend_word: if (!scaled_reg_used) { gen_mov_dword_to_reg_imm(ea_reg,(Bit32u)imm); } else { - dyn_lea(ea_reg,NULL,DRCD_REG(scaled_reg),scale,imm); + DYN_LEA_MEM_REG_VAL(ea_reg,NULL,scaled_reg,scale,imm); } } else { if (!scaled_reg_used) { - gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); + MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); if (imm) gen_add_imm(ea_reg,(Bit32u)imm); } else { - dyn_lea(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),DRCD_REG(scaled_reg),scale,imm); + DYN_LEA_SEG_PHYS_REG_VAL(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base),scaled_reg,scale,imm); } } @@ -853,19 +1009,19 @@ skip_extend_word: // succeeded, use the pointer to avoid code invalidation if (!addseg) { if (!scaled_reg_used) { - gen_mov_word_to_reg(ea_reg,DRCD_REG(base_reg),true); + MOV_REG_VAL_TO_HOST_REG(ea_reg,base_reg); gen_add(ea_reg,(void*)val); } else { - dyn_lea(ea_reg,DRCD_REG(base_reg),DRCD_REG(scaled_reg),scale,0); + DYN_LEA_REG_VAL_REG_VAL(ea_reg,base_reg,scaled_reg,scale,0); gen_add(ea_reg,(void*)val); } } else { if (!scaled_reg_used) { - gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); + MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); } else { - dyn_lea(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),DRCD_REG(scaled_reg),scale,0); + DYN_LEA_SEG_PHYS_REG_VAL(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base),scaled_reg,scale,0); } - gen_add(ea_reg,DRCD_REG(base_reg)); + ADD_REG_VAL_TO_HOST_REG(ea_reg,base_reg); gen_add(ea_reg,(void*)val); } return; @@ -878,19 +1034,19 @@ skip_extend_word: if (!addseg) { if (!scaled_reg_used) { - gen_mov_word_to_reg(ea_reg,DRCD_REG(base_reg),true); + MOV_REG_VAL_TO_HOST_REG(ea_reg,base_reg); gen_add_imm(ea_reg,(Bit32u)imm); } else { - dyn_lea(ea_reg,DRCD_REG(base_reg),DRCD_REG(scaled_reg),scale,imm); + DYN_LEA_REG_VAL_REG_VAL(ea_reg,base_reg,scaled_reg,scale,imm); } } else { if (!scaled_reg_used) { - gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); - gen_add(ea_reg,DRCD_REG(base_reg)); + MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); + ADD_REG_VAL_TO_HOST_REG(ea_reg,base_reg); if (imm) gen_add_imm(ea_reg,(Bit32u)imm); } else { - dyn_lea(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),DRCD_REG(scaled_reg),scale,imm); - gen_add(ea_reg,DRCD_REG(base_reg)); + DYN_LEA_SEG_PHYS_REG_VAL(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base),scaled_reg,scale,imm); + ADD_REG_VAL_TO_HOST_REG(ea_reg,base_reg); } } @@ -907,7 +1063,7 @@ skip_extend_word: if (!addseg) { gen_mov_dword_to_reg_imm(ea_reg,(Bit32u)imm); } else { - gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); + MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); if (imm) gen_add_imm(ea_reg,(Bit32u)imm); } @@ -930,11 +1086,11 @@ skip_extend_word: if (decode_fetchd_imm(val)) { // succeeded, use the pointer to avoid code invalidation if (!addseg) { - gen_mov_word_to_reg(ea_reg,DRCD_REG(base_reg),true); + MOV_REG_VAL_TO_HOST_REG(ea_reg,base_reg); gen_add(ea_reg,(void*)val); } else { - gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); - gen_add(ea_reg,DRCD_REG(base_reg)); + MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); + ADD_REG_VAL_TO_HOST_REG(ea_reg,base_reg); gen_add(ea_reg,(void*)val); } return; @@ -946,11 +1102,11 @@ skip_extend_word: } if (!addseg) { - gen_mov_word_to_reg(ea_reg,DRCD_REG(base_reg),true); + MOV_REG_VAL_TO_HOST_REG(ea_reg,base_reg); if (imm) gen_add_imm(ea_reg,(Bit32u)imm); } else { - gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); - gen_add(ea_reg,DRCD_REG(base_reg)); + MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); + ADD_REG_VAL_TO_HOST_REG(ea_reg,base_reg); if (imm) gen_add_imm(ea_reg,(Bit32u)imm); } } diff --git a/src/cpu/core_dynrec/decoder_opcodes.h b/src/cpu/core_dynrec/decoder_opcodes.h index 9fbd88c8..030cf30e 100644 --- a/src/cpu/core_dynrec/decoder_opcodes.h +++ b/src/cpu/core_dynrec/decoder_opcodes.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2007 The DOSBox Team + * Copyright (C) 2002-2008 The DOSBox Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,7 +34,7 @@ static void dyn_dop_ebgb(DualOps op) { dyn_fill_ea(FC_ADDR); gen_protect_addr_reg(); dyn_read_byte_canuseword(FC_ADDR,FC_OP1); - gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP2,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); dyn_dop_byte_gencall(op); if ((op!=DOP_CMP) && (op!=DOP_TEST)) { @@ -42,10 +42,10 @@ static void dyn_dop_ebgb(DualOps op) { dyn_write_byte(FC_ADDR,FC_RETOP); } } else { - gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); - gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP2,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); dyn_dop_byte_gencall(op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); } } @@ -53,11 +53,11 @@ static void dyn_dop_ebgb_mov(void) { dyn_get_modrm(); if (decode.modrm.mod<3) { dyn_fill_ea(FC_ADDR); - gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); dyn_write_byte(FC_ADDR,FC_TMP_BA1); } else { - gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); - gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); } } @@ -69,7 +69,7 @@ static void dyn_dop_ebib_mov(void) { dyn_write_byte(FC_ADDR,FC_TMP_BA1); } else { gen_mov_byte_to_reg_low_imm(FC_TMP_BA1,decode_fetchb()); - gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); } } @@ -79,16 +79,16 @@ static void dyn_dop_ebgb_xchg(void) { dyn_fill_ea(FC_ADDR); gen_protect_addr_reg(); dyn_read_byte(FC_ADDR,FC_TMP_BA1); - gen_mov_byte_to_reg_low(FC_TMP_BA2,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA2,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); - gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); gen_restore_addr_reg(); dyn_write_byte(FC_ADDR,FC_TMP_BA2); } else { - gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); - gen_mov_byte_to_reg_low(FC_TMP_BA2,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); - gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); - gen_mov_byte_from_reg_low(FC_TMP_BA2,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); + MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA2,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA2,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); } } @@ -97,14 +97,14 @@ static void dyn_dop_gbeb(DualOps op) { if (decode.modrm.mod<3) { dyn_fill_ea(FC_ADDR); dyn_read_byte_canuseword(FC_ADDR,FC_OP2); - gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); dyn_dop_byte_gencall(op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); } else { - gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); - gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP2,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); dyn_dop_byte_gencall(op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); } } @@ -113,10 +113,10 @@ static void dyn_dop_gbeb_mov(void) { if (decode.modrm.mod<3) { dyn_fill_ea(FC_ADDR); dyn_read_byte(FC_ADDR,FC_TMP_BA1); - gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); } else { - gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); - gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1); } } @@ -126,17 +126,17 @@ static void dyn_dop_evgv(DualOps op) { dyn_fill_ea(FC_ADDR); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); gen_protect_addr_reg(); - gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); dyn_dop_word_gencall(op,decode.big_op); if ((op!=DOP_CMP) && (op!=DOP_TEST)) { gen_restore_addr_reg(); dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); } } else { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); - gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); dyn_dop_word_gencall(op,decode.big_op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op); } } @@ -144,11 +144,11 @@ static void dyn_dop_evgv_mov(void) { dyn_get_modrm(); if (decode.modrm.mod<3) { dyn_fill_ea(FC_ADDR); - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); dyn_write_word(FC_ADDR,FC_OP1,decode.big_op); } else { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); } } @@ -162,7 +162,7 @@ static void dyn_dop_eviv_mov(void) { } else { if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP1,decode_fetchd()); else gen_mov_word_to_reg_imm(FC_OP1,decode_fetchw()); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); } } @@ -172,26 +172,26 @@ static void dyn_dop_evgv_xchg(void) { dyn_fill_ea(FC_ADDR); gen_protect_addr_reg(); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); - gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); gen_protect_reg(FC_OP1); gen_restore_addr_reg(); dyn_write_word(FC_ADDR,FC_OP2,decode.big_op); gen_restore_reg(FC_OP1); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); } else { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); - gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); - gen_mov_word_from_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP2,decode.modrm.rm,decode.big_op); } } static void dyn_xchg_ax(Bit8u reg) { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); - gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); - gen_mov_word_from_reg(FC_OP2,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_EAX,decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP2,reg,decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,reg,decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP2,DRC_REG_EAX,decode.big_op); } static void dyn_dop_gvev(DualOps op) { @@ -200,17 +200,17 @@ static void dyn_dop_gvev(DualOps op) { dyn_fill_ea(FC_ADDR); gen_protect_addr_reg(); dyn_read_word(FC_ADDR,FC_OP2,decode.big_op); - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); dyn_dop_word_gencall(op,decode.big_op); if ((op!=DOP_CMP) && (op!=DOP_TEST)) { gen_restore_addr_reg(); - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.reg,decode.big_op); } } else { - gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.rm,decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); dyn_dop_word_gencall(op,decode.big_op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.reg,decode.big_op); } } @@ -219,22 +219,22 @@ static void dyn_dop_gvev_mov(void) { if (decode.modrm.mod<3) { dyn_fill_ea(FC_ADDR); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); } else { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); } } static void dyn_dop_byte_imm(DualOps op,Bit8u reg,Bit8u idx) { - gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(reg,idx)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,reg,idx); gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,decode_fetchb()); dyn_dop_byte_gencall(op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(reg,idx)); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,reg,idx); } static void dyn_dop_byte_imm_mem(DualOps op,Bit8u reg,Bit8u idx) { - gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(reg,idx)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,reg,idx); Bitu val; if (decode_fetchb_imm(val)) { gen_mov_byte_to_reg_low_canuseword(FC_OP2,(void*)val); @@ -242,7 +242,7 @@ static void dyn_dop_byte_imm_mem(DualOps op,Bit8u reg,Bit8u idx) { gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,(Bit8u)val); } dyn_dop_byte_gencall(op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(reg,idx)); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,reg,idx); } static void dyn_prep_word_imm(Bit8u reg) { @@ -263,23 +263,23 @@ static void dyn_prep_word_imm(Bit8u reg) { } static void dyn_dop_word_imm(DualOps op,Bit8u reg) { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,reg,decode.big_op); dyn_prep_word_imm(reg); dyn_dop_word_gencall(op,decode.big_op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,reg,decode.big_op); } static void dyn_dop_word_imm_old(DualOps op,Bit8u reg,Bitu imm) { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,reg,decode.big_op); if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit32u)imm); else gen_mov_word_to_reg_imm(FC_OP2,(Bit16u)imm); dyn_dop_word_gencall(op,decode.big_op); - if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,reg,decode.big_op); } static void dyn_mov_byte_imm(Bit8u reg,Bit8u idx,Bit8u imm) { gen_mov_byte_to_reg_low_imm(FC_TMP_BA1,imm); - gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(reg,idx)); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,reg,idx); } static void dyn_mov_word_imm(Bit8u reg) { @@ -287,45 +287,45 @@ static void dyn_mov_word_imm(Bit8u reg) { if (decode.big_op) { if (decode_fetchd_imm(val)) { gen_mov_word_to_reg(FC_OP1,(void*)val,true); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(reg,true),true); + MOV_REG_WORD32_FROM_HOST_REG(FC_OP1,reg); return; } } else { if (decode_fetchw_imm(val)) { gen_mov_word_to_reg(FC_OP1,(void*)val,false); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(reg,false),false); + MOV_REG_WORD16_FROM_HOST_REG(FC_OP1,reg); return; } } if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP1,(Bit32u)val); else gen_mov_word_to_reg_imm(FC_OP1,(Bit16u)val); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,reg,decode.big_op); } static void dyn_sop_word(SingleOps op,Bit8u reg) { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,reg,decode.big_op); dyn_sop_word_gencall(op,decode.big_op); - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,reg,decode.big_op); } static void dyn_mov_byte_al_direct(Bitu imm) { - gen_mov_word_to_reg(FC_ADDR,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS),true); + MOV_SEG_PHYS_TO_HOST_REG(FC_ADDR,(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS)); gen_add_imm(FC_ADDR,imm); dyn_read_byte(FC_ADDR,FC_TMP_BA1); - gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(DRC_REG_EAX,0)); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,DRC_REG_EAX,0); } static void dyn_mov_byte_ax_direct(Bitu imm) { - gen_mov_word_to_reg(FC_ADDR,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS),true); + MOV_SEG_PHYS_TO_HOST_REG(FC_ADDR,(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS)); gen_add_imm(FC_ADDR,imm); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,DRC_REG_EAX,decode.big_op); } static void dyn_mov_byte_direct_al() { - gen_mov_word_to_reg(FC_ADDR,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS),true); + MOV_SEG_PHYS_TO_HOST_REG(FC_ADDR,(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS)); if (decode.big_addr) { Bitu val; if (decode_fetchd_imm(val)) { @@ -336,14 +336,14 @@ static void dyn_mov_byte_direct_al() { } else { gen_add_imm(FC_ADDR,decode_fetchw()); } - gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(DRC_REG_EAX,0)); + MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,DRC_REG_EAX,0); dyn_write_byte(FC_ADDR,FC_TMP_BA1); } static void dyn_mov_byte_direct_ax(Bitu imm) { - gen_mov_word_to_reg(FC_ADDR,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS),true); + MOV_SEG_PHYS_TO_HOST_REG(FC_ADDR,(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS)); gen_add_imm(FC_ADDR,imm); - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_EAX,decode.big_op); dyn_write_word(FC_ADDR,FC_OP1,decode.big_op); } @@ -354,11 +354,11 @@ static void dyn_movx_ev_gb(bool sign) { dyn_fill_ea(FC_ADDR); dyn_read_byte(FC_ADDR,FC_TMP_BA1); gen_extend_byte(sign,FC_TMP_BA1); - gen_mov_word_from_reg(FC_TMP_BA1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_TMP_BA1,decode.modrm.reg,decode.big_op); } else { - gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); gen_extend_byte(sign,FC_TMP_BA1); - gen_mov_word_from_reg(FC_TMP_BA1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_TMP_BA1,decode.modrm.reg,decode.big_op); } } @@ -368,30 +368,37 @@ static void dyn_movx_ev_gw(bool sign) { dyn_fill_ea(FC_ADDR); dyn_read_word(FC_ADDR,FC_OP1,false); gen_extend_word(sign,FC_OP1); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); } else { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,false),false); + MOV_REG_WORD16_TO_HOST_REG(FC_OP1,decode.modrm.rm); gen_extend_word(sign,FC_OP1); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); } } static void dyn_mov_ev_seg(void) { dyn_get_modrm(); - gen_mov_word_to_reg(FC_OP1,DRCD_SEG_VAL(decode.modrm.reg),false); + MOV_SEG_VAL_TO_HOST_REG(FC_OP1,decode.modrm.reg); if (decode.modrm.mod<3) { dyn_fill_ea(FC_ADDR); dyn_write_word(FC_ADDR,FC_OP1,false); } else { if (decode.big_op) gen_extend_word(false,FC_OP1); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); } } +static void dyn_lea(void) { + dyn_get_modrm(); + dyn_fill_ea(FC_ADDR,false); + MOV_REG_WORD_FROM_HOST_REG(FC_ADDR,decode.modrm.reg,decode.big_op); +} + + static void dyn_push_seg(Bit8u seg) { - gen_mov_word_to_reg(FC_OP1,DRCD_SEG_VAL(seg),false); + MOV_SEG_VAL_TO_HOST_REG(FC_OP1,seg); if (decode.big_op) { gen_extend_word(false,FC_OP1); gen_call_function_raw((void*)&dynrec_push_dword); @@ -406,7 +413,7 @@ static void dyn_pop_seg(Bit8u seg) { } static void dyn_push_reg(Bit8u reg) { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,reg,decode.big_op); if (decode.big_op) gen_call_function_raw((void*)&dynrec_push_dword); else gen_call_function_raw((void*)&dynrec_push_word); } @@ -414,7 +421,7 @@ static void dyn_push_reg(Bit8u reg) { static void dyn_pop_reg(Bit8u reg) { if (decode.big_op) gen_call_function_raw((void*)&dynrec_pop_dword); else gen_call_function_raw((void*)&dynrec_pop_word); - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,reg,decode.big_op); } static void dyn_push_byte_imm(Bit8s imm) { @@ -447,7 +454,7 @@ static void dyn_pop_ev(void) { } else { if (decode.big_op) gen_call_function_raw((void*)&dynrec_pop_dword); else gen_call_function_raw((void*)&dynrec_pop_word); - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op); } } @@ -465,7 +472,7 @@ static void dyn_segprefix(Bit8u seg) { dyn_fill_ea(FC_ADDR); dyn_read_word(FC_ADDR,FC_RETOP,false); } else { - gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); + MOV_REG_WORD16_TO_HOST_REG(FC_RETOP,decode.modrm.rm); } gen_call_function_IR((void *)&CPU_SetSegGeneral,decode.modrm.reg,FC_RETOP); dyn_check_exception(FC_RETOP); @@ -486,7 +493,7 @@ static void dyn_load_seg_off_ea(Bit8u seg) { dyn_check_exception(FC_RETOP); gen_restore_reg(FC_OP1); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op); } else { IllegalOptionDynrec("dyn_load_seg_off_ea"); } @@ -500,12 +507,12 @@ static void dyn_imul_gvev(Bitu immsize) { dyn_fill_ea(FC_ADDR); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); } else { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); } switch (immsize) { case 0: - gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); break; case 1: if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit8s)decode_fetchb()); @@ -524,7 +531,7 @@ static void dyn_imul_gvev(Bitu immsize) { if (decode.big_op) gen_call_function_raw((void*)dynrec_dimul_dword); else gen_call_function_raw((void*)dynrec_dimul_word); - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.reg,decode.big_op); } static void dyn_dshift_ev_gv(bool left,bool immediate) { @@ -534,11 +541,11 @@ static void dyn_dshift_ev_gv(bool left,bool immediate) { gen_protect_addr_reg(); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); } else { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); } - gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); if (immediate) gen_mov_byte_to_reg_low_imm(FC_RETOP,decode_fetchb()); - else gen_mov_byte_to_reg_low(FC_RETOP,DRCD_REG_BYTE(DRC_REG_ECX,0)); + else MOV_REG_BYTE_TO_HOST_REG_LOW(FC_RETOP,DRC_REG_ECX,0); if (decode.big_op) dyn_dpshift_dword_gencall(left); else dyn_dpshift_word_gencall(left); @@ -546,7 +553,7 @@ static void dyn_dshift_ev_gv(bool left,bool immediate) { gen_restore_addr_reg(); dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); } else { - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op); } } @@ -610,7 +617,7 @@ static void dyn_grp2_eb(grp2_types type) { gen_protect_addr_reg(); dyn_read_byte_canuseword(FC_ADDR,FC_OP1); } else { - gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); } switch (type) { case grp2_1: @@ -626,7 +633,7 @@ static void dyn_grp2_eb(grp2_types type) { } break; case grp2_cl: - gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(DRC_REG_ECX,0)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP2,DRC_REG_ECX,0); gen_and_imm(FC_OP2,0x1f); dyn_shift_byte_gencall((ShiftOps)decode.modrm.reg); break; @@ -635,7 +642,7 @@ static void dyn_grp2_eb(grp2_types type) { gen_restore_addr_reg(); dyn_write_byte(FC_ADDR,FC_RETOP); } else { - gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); } } @@ -646,7 +653,7 @@ static void dyn_grp2_ev(grp2_types type) { gen_protect_addr_reg(); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); } else { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); } switch (type) { case grp2_1: @@ -669,7 +676,7 @@ static void dyn_grp2_ev(grp2_types type) { } break; case grp2_cl: - gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(DRC_REG_ECX,0)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP2,DRC_REG_ECX,0); gen_and_imm(FC_OP2,0x1f); dyn_shift_word_gencall((ShiftOps)decode.modrm.reg,decode.big_op); break; @@ -678,7 +685,7 @@ static void dyn_grp2_ev(grp2_types type) { gen_restore_addr_reg(); dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); } else { - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op); } } @@ -690,7 +697,7 @@ static void dyn_grp3_eb(void) { if ((decode.modrm.reg==2) || (decode.modrm.reg==3)) gen_protect_addr_reg(); dyn_read_byte_canuseword(FC_ADDR,FC_OP1); } else { - gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); } switch (decode.modrm.reg) { case 0x0: // test eb,ib @@ -723,7 +730,7 @@ static void dyn_grp3_eb(void) { gen_restore_addr_reg(); dyn_write_byte(FC_ADDR,FC_RETOP); } else { - gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); } } @@ -734,7 +741,7 @@ static void dyn_grp3_ev(void) { if ((decode.modrm.reg==2) || (decode.modrm.reg==3)) gen_protect_addr_reg(); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); } else { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); } switch (decode.modrm.reg) { case 0x0: // test ev,iv @@ -772,7 +779,7 @@ static void dyn_grp3_ev(void) { gen_restore_addr_reg(); dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); } else { - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op); } } @@ -790,9 +797,9 @@ static bool dyn_grp4_eb(void) { gen_restore_addr_reg(); dyn_write_byte(FC_ADDR,FC_RETOP); } else { - gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); dyn_sop_byte_gencall(decode.modrm.reg==0 ? SOP_INC : SOP_DEC); - gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); } break; case 0x7: //CALBACK Iw @@ -816,7 +823,7 @@ static bool dyn_grp4_ev(void) { if ((decode.modrm.reg<2) || (decode.modrm.reg==3) || (decode.modrm.reg==5)) gen_protect_addr_reg(); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); } else { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op); } switch (decode.modrm.reg) { case 0x0://INC Ev @@ -826,7 +833,7 @@ static bool dyn_grp4_ev(void) { gen_restore_addr_reg(); dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); } else { - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op); } break; case 0x2: // CALL Ev @@ -879,7 +886,7 @@ static bool dyn_grp6(void) { dyn_fill_ea(FC_ADDR); dyn_write_word(FC_ADDR,FC_RETOP,false); } else { - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); + MOV_REG_WORD16_FROM_HOST_REG(FC_RETOP,decode.modrm.rm); } break; case 0x02: // LLDT @@ -890,7 +897,7 @@ static bool dyn_grp6(void) { dyn_fill_ea(FC_ADDR); dyn_read_word(FC_ADDR,FC_RETOP,false); } else { - gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); + MOV_REG_WORD16_TO_HOST_REG(FC_RETOP,decode.modrm.rm); } gen_extend_word(false,FC_RETOP); switch (decode.modrm.reg) { @@ -988,10 +995,10 @@ static bool dyn_grp7(void) { switch (decode.modrm.reg) { case 0x04: // SMSW gen_call_function_raw((void*)CPU_SMSW); - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); + MOV_REG_WORD16_FROM_HOST_REG(FC_RETOP,decode.modrm.rm); break; case 0x06: // LMSW - gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); + MOV_REG_WORD16_TO_HOST_REG(FC_RETOP,decode.modrm.rm); gen_call_function_R((void*)CPU_LMSW,FC_RETOP); dyn_check_exception(FC_RETOP); dyn_set_eip_end(); @@ -1013,14 +1020,14 @@ static void dyn_larlsl(bool is_lar) { dyn_fill_ea(FC_ADDR); dyn_read_word(FC_ADDR,FC_RETOP,false); } else { - gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); + MOV_REG_WORD16_TO_HOST_REG(FC_RETOP,decode.modrm.rm); } gen_extend_word(false,FC_RETOP); if (is_lar) gen_call_function((void*)CPU_LAR,"%R%A",FC_RETOP,(DRC_PTR_SIZE_IM)&core_dynrec.readdata); else gen_call_function((void*)CPU_LSL,"%R%A",FC_RETOP,(DRC_PTR_SIZE_IM)&core_dynrec.readdata); DRC_PTR_SIZE_IM brnz=gen_create_branch_on_nonzero(FC_RETOP,true); gen_mov_word_to_reg(FC_OP2,&core_dynrec.readdata,true); - gen_mov_word_from_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); + MOV_REG_WORD_FROM_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op); gen_fill_branch(brnz); } */ @@ -1031,12 +1038,12 @@ static void dyn_mov_from_crx(void) { gen_call_function_IA((void*)CPU_READ_CRX,decode.modrm.reg,(DRC_PTR_SIZE_IM)&core_dynrec.readdata); dyn_check_exception(FC_RETOP); gen_mov_word_to_reg(FC_OP2,&core_dynrec.readdata,true); - gen_mov_word_from_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.rm,true),true); + MOV_REG_WORD32_FROM_HOST_REG(FC_OP2,decode.modrm.rm); } static void dyn_mov_to_crx(void) { dyn_get_modrm(); - gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,true),true); + MOV_REG_WORD32_TO_HOST_REG(FC_RETOP,decode.modrm.rm); gen_call_function_IR((void*)CPU_WRITE_CRX,decode.modrm.reg,FC_RETOP); dyn_check_exception(FC_RETOP); dyn_set_eip_end(); @@ -1048,29 +1055,29 @@ static void dyn_mov_to_crx(void) { static void dyn_cbw(void) { if (decode.big_op) { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,false),false); + MOV_REG_WORD16_TO_HOST_REG(FC_OP1,DRC_REG_EAX); gen_call_function_raw((void *)&dynrec_cwde); - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EAX,true),true); + MOV_REG_WORD32_FROM_HOST_REG(FC_RETOP,DRC_REG_EAX); } else { - gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(DRC_REG_EAX,0)); + MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,DRC_REG_EAX,0); gen_call_function_raw((void *)&dynrec_cbw); - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EAX,false),false); + MOV_REG_WORD16_FROM_HOST_REG(FC_RETOP,DRC_REG_EAX); } } static void dyn_cwd(void) { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_EAX,decode.big_op); if (decode.big_op) { gen_call_function_raw((void *)&dynrec_cdq); - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EDX,true),true); + MOV_REG_WORD32_FROM_HOST_REG(FC_RETOP,DRC_REG_EDX); } else { gen_call_function_raw((void *)&dynrec_cwd); - gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EDX,false),false); + MOV_REG_WORD16_FROM_HOST_REG(FC_RETOP,DRC_REG_EDX); } } static void dyn_sahf(void) { - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,false),false); + MOV_REG_WORD16_TO_HOST_REG(FC_OP1,DRC_REG_EAX); gen_call_function_raw((void *)&dynrec_sahf); InvalidateFlags(); } @@ -1111,7 +1118,7 @@ static void dyn_set_byte_on_condition(BranchTypes btype) { dyn_fill_ea(FC_ADDR); dyn_write_byte(FC_ADDR,FC_RETOP); } else { - gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); + MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.rm&3,(decode.modrm.rm>>2)&1); } } */ @@ -1136,13 +1143,13 @@ static void dyn_loop(LoopTypes type) { case LOOP_E: case LOOP_NE: case LOOP_NONE: - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr); gen_add_imm(FC_OP1,(Bit32u)(-1)); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr); branch2=gen_create_branch_on_zero(FC_OP1,decode.big_addr); break; case LOOP_JCXZ: - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr); branch2=gen_create_branch_on_nonzero(FC_OP1,decode.big_addr); break; } @@ -1150,9 +1157,9 @@ static void dyn_loop(LoopTypes type) { gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlockDynRec,cache.start)); if (branch1) { gen_fill_branch(branch1); - gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr); gen_add_imm(FC_OP1,(Bit32u)(-1)); - gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + MOV_REG_WORD_FROM_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr); } // Branch taken gen_fill_branch(branch2); @@ -1242,7 +1249,7 @@ static void dyn_interrupt(Bit8u num) { static void dyn_string(StringOps op) { - if (decode.rep) gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + if (decode.rep) MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr); else gen_mov_dword_to_reg_imm(FC_OP1,1); gen_mov_word_to_reg(FC_OP2,&cpu.direction,true); Bit8u di_base_addr=decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS; @@ -1287,7 +1294,7 @@ static void dyn_string(StringOps op) { break; default: IllegalOptionDynrec("dyn_string"); } - if (decode.rep) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); + if (decode.rep) MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,DRC_REG_ECX,decode.big_addr); if (op> 2)); // ldr r3, [pc, #(&Segs)] + // adr: 18 + cache_addw(0x4800 + (HOST_r2 << 8) + ((68 - (18 + 2)) >> 2)); // ldr r2, [pc, #(&cpu_regs)] + cache_addw(0x4680 + (FC_SEGS_ADDR - HOST_r8) + (HOST_r3 << 3)); // mov FC_SEGS_ADDR, r3 + cache_addw(0x4680 + (FC_REGS_ADDR - HOST_r8) + (HOST_r2 << 3)); // mov FC_REGS_ADDR, r2 + + // align 4 cache_addw(0xa302); // add r3, pc, #8 cache_addw(0x3001); // add r0, #1 @@ -760,10 +781,24 @@ static void gen_run_code(void) { cache_addw(0x4700); // bx r0 cache_addw(0x46c0); // nop - cache_addw(0xbcf0); // pop {v1-v4} + // align 4 + cache_addw(0xbcfc); // pop {r2,r3,v1-v4} + cache_addw(0x4680 + (FC_SEGS_ADDR - HOST_r8) + (HOST_r3 << 3)); // mov FC_SEGS_ADDR, r3 + cache_addw(0x4680 + (FC_REGS_ADDR - HOST_r8) + (HOST_r2 << 3)); // mov FC_REGS_ADDR, r2 cache_addw(0xbc08); // pop {r3} cache_addw(0x4718); // bx r3 + // fill up to 64 bytes + cache_addw(0x46c0); // nop + cache_addd(0x46c046c0); // nop, nop + cache_addd(0x46c046c0); // nop, nop + cache_addd(0x46c046c0); // nop, nop + cache_addd(0x46c046c0); // nop, nop + + // adr: 64 + cache_addd((Bit32u)&Segs); // address of "Segs" + // adr: 68 + cache_addd((Bit32u)&cpu_regs); // address of "cpu_regs" } // return from a function @@ -1133,3 +1168,122 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { #endif } #endif + +#ifdef DRC_USE_SEGS_ADDR + +// mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR + cache_addw(0x8800 + dest_reg + (templo1 << 3) + (index << 5)); // ldrh dest_reg, [templo1, #index] +} + +// mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) +static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR + cache_addw(0x6800 + dest_reg + (templo1 << 3) + (index << 4)); // ldr dest_reg, [templo1, #index] +} + +// add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) +static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { + cache_checkinstr(6); + cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR + cache_addw(0x6800 + templo2 + (templo1 << 3) + (index << 4)); // ldr templo2, [templo1, #index] + cache_addw(0x1800 + reg + (reg << 3) + (templo2 << 6)); // add reg, reg, templo2 +} + +#endif + +#ifdef DRC_USE_REGS_ADDR + +// mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x8800 + dest_reg + (templo2 << 3) + (index << 5)); // ldrh dest_reg, [templo2, #index] +} + +// mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x6800 + dest_reg + (templo2 << 3) + (index << 4)); // ldr dest_reg, [templo2, #index] +} + +// move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { + cache_checkinstr(4); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + if (dword) { + cache_addw(0x6800 + dest_reg + (templo2 << 3) + (index << 4)); // ldr dest_reg, [templo2, #index] + } else { + cache_addw(0x8800 + dest_reg + (templo2 << 3) + (index << 5)); // ldrh dest_reg, [templo2, #index] + } +} + +// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x7800 + dest_reg + (templo2 << 3) + (index << 6)); // ldrb dest_reg, [templo2, #index] +} + +// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x7800 + dest_reg + (templo2 << 3) + (index << 6)); // ldrb dest_reg, [templo2, #index] +} + + +// add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { + cache_checkinstr(6); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x6800 + templo1 + (templo2 << 3) + (index << 4)); // ldr templo1, [templo2, #index] + cache_addw(0x1800 + reg + (reg << 3) + (templo1 << 6)); // add reg, reg, templo1 +} + + +// move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) +static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw(0x8000 + src_reg + (templo1 << 3) + (index << 5)); // strh src_reg, [templo1, #index] +} + +// move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw(0x6000 + src_reg + (templo1 << 3) + (index << 4)); // str src_reg, [templo1, #index] +} + +// move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) +static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + if (dword) { + cache_addw(0x6000 + src_reg + (templo1 << 3) + (index << 4)); // str src_reg, [templo1, #index] + } else { + cache_addw(0x8000 + src_reg + (templo1 << 3) + (index << 5)); // strh src_reg, [templo1, #index] + } +} + +// move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR +static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw(0x7000 + src_reg + (templo1 << 3) + (index << 6)); // strb src_reg, [templo1, #index] +} +#endif diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h index 81a01bce..e994c731 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb-niw.h @@ -16,10 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-thumb-niw.h,v 1.1 2008-09-02 20:44:41 c2woody Exp $ */ +/* $Id: risc_armv4le-thumb-niw.h,v 1.2 2008-09-19 16:48:02 c2woody Exp $ */ -/* ARMv4 (little endian) backend by M-HT (thumb version) */ +/* ARMv4 (little endian) backend by M-HT (thumb version with data pool) */ // temporary "lo" registers @@ -53,6 +53,16 @@ // temporary register for LEA #define TEMP_REG_DRC HOST_a4 +#ifdef DRC_USE_REGS_ADDR +// used to hold the address of "cpu_regs" - preferably filled in function gen_run_code +#define FC_REGS_ADDR HOST_v7 +#endif + +#ifdef DRC_USE_SEGS_ADDR +// used to hold the address of "Segs" - preferably filled in function gen_run_code +#define FC_SEGS_ADDR HOST_v8 +#endif + // data pool defines #define CACHE_DATA_JUMP (2) @@ -65,7 +75,7 @@ static Bit8u * cache_datapos = NULL; // position of data pool in the cache block static Bit32u cache_datasize = 0; // total size of data pool static Bit32u cache_dataindex = 0; // used size of data pool = index of free data item (in bytes) in data pool - +// forwarded function static void INLINE gen_create_branch_short(void * func); // function to check distance to data pool @@ -753,7 +763,18 @@ static void gen_run_code(void) { // thumb state from now on cache_addw(0xb500); // push {lr} - cache_addw(0xb4f0); // push {v1-v4} + cache_addw(0x4640 + HOST_r3 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov r3, FC_SEGS_ADDR + cache_addw(0x4640 + HOST_r2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov r2, FC_REGS_ADDR + cache_addw(0xb4fc); // push {r2,r3,v1-v4} + + // adr: 16 + cache_addw(0x4800 + (HOST_r3 << 8) + ((64 - (16 + 4)) >> 2)); // ldr r3, [pc, #(&Segs)] + // adr: 18 + cache_addw(0x4800 + (HOST_r2 << 8) + ((68 - (18 + 2)) >> 2)); // ldr r2, [pc, #(&cpu_regs)] + cache_addw(0x4680 + (FC_SEGS_ADDR - HOST_r8) + (HOST_r3 << 3)); // mov FC_SEGS_ADDR, r3 + cache_addw(0x4680 + (FC_REGS_ADDR - HOST_r8) + (HOST_r2 << 3)); // mov FC_REGS_ADDR, r2 + + // align 4 cache_addw(0xa302); // add r3, pc, #8 cache_addw(0x3001); // add r0, #1 @@ -762,10 +783,24 @@ static void gen_run_code(void) { cache_addw(0x4700); // bx r0 cache_addw(0x46c0); // nop - cache_addw(0xbcf0); // pop {v1-v4} + // align 4 + cache_addw(0xbcfc); // pop {r2,r3,v1-v4} + cache_addw(0x4680 + (FC_SEGS_ADDR - HOST_r8) + (HOST_r3 << 3)); // mov FC_SEGS_ADDR, r3 + cache_addw(0x4680 + (FC_REGS_ADDR - HOST_r8) + (HOST_r2 << 3)); // mov FC_REGS_ADDR, r2 cache_addw(0xbc08); // pop {r3} cache_addw(0x4718); // bx r3 + // fill up to 64 bytes + cache_addw(0x46c0); // nop + cache_addd(0x46c046c0); // nop, nop + cache_addd(0x46c046c0); // nop, nop + cache_addd(0x46c046c0); // nop, nop + cache_addd(0x46c046c0); // nop, nop + + // adr: 64 + cache_addd((Bit32u)&Segs); // address of "Segs" + // adr: 68 + cache_addd((Bit32u)&cpu_regs); // address of "cpu_regs" } // return from a function @@ -1130,3 +1165,122 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { #endif } #endif + +#ifdef DRC_USE_SEGS_ADDR + +// mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR + cache_addw(0x8800 + dest_reg + (templo1 << 3) + (index << 5)); // ldrh dest_reg, [templo1, #index] +} + +// mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) +static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR + cache_addw(0x6800 + dest_reg + (templo1 << 3) + (index << 4)); // ldr dest_reg, [templo1, #index] +} + +// add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) +static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { + cache_checkinstr(6); + cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR + cache_addw(0x6800 + templo2 + (templo1 << 3) + (index << 4)); // ldr templo2, [templo1, #index] + cache_addw(0x1800 + reg + (reg << 3) + (templo2 << 6)); // add reg, reg, templo2 +} + +#endif + +#ifdef DRC_USE_REGS_ADDR + +// mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x8800 + dest_reg + (templo2 << 3) + (index << 5)); // ldrh dest_reg, [templo2, #index] +} + +// mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x6800 + dest_reg + (templo2 << 3) + (index << 4)); // ldr dest_reg, [templo2, #index] +} + +// move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { + cache_checkinstr(4); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + if (dword) { + cache_addw(0x6800 + dest_reg + (templo2 << 3) + (index << 4)); // ldr dest_reg, [templo2, #index] + } else { + cache_addw(0x8800 + dest_reg + (templo2 << 3) + (index << 5)); // ldrh dest_reg, [templo2, #index] + } +} + +// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x7800 + dest_reg + (templo2 << 3) + (index << 6)); // ldrb dest_reg, [templo2, #index] +} + +// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x7800 + dest_reg + (templo2 << 3) + (index << 6)); // ldrb dest_reg, [templo2, #index] +} + + +// add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { + cache_checkinstr(6); + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x6800 + templo1 + (templo2 << 3) + (index << 4)); // ldr templo1, [templo2, #index] + cache_addw(0x1800 + reg + (reg << 3) + (templo1 << 6)); // add reg, reg, templo1 +} + + +// move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) +static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw(0x8000 + src_reg + (templo1 << 3) + (index << 5)); // strh src_reg, [templo1, #index] +} + +// move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw(0x6000 + src_reg + (templo1 << 3) + (index << 4)); // str src_reg, [templo1, #index] +} + +// move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) +static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + if (dword) { + cache_addw(0x6000 + src_reg + (templo1 << 3) + (index << 4)); // str src_reg, [templo1, #index] + } else { + cache_addw(0x8000 + src_reg + (templo1 << 3) + (index << 5)); // strh src_reg, [templo1, #index] + } +} + +// move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR +static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { + cache_checkinstr(4); + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw(0x7000 + src_reg + (templo1 << 3) + (index << 6)); // strb src_reg, [templo1, #index] +} +#endif diff --git a/src/cpu/core_dynrec/risc_armv4le-thumb.h b/src/cpu/core_dynrec/risc_armv4le-thumb.h index 4d9222e2..5501bc0a 100644 --- a/src/cpu/core_dynrec/risc_armv4le-thumb.h +++ b/src/cpu/core_dynrec/risc_armv4le-thumb.h @@ -16,10 +16,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_armv4le-thumb.h,v 1.2 2008-09-02 20:44:41 c2woody Exp $ */ +/* $Id: risc_armv4le-thumb.h,v 1.3 2008-09-19 16:48:03 c2woody Exp $ */ -/* ARMv4 (little endian) backend by M-HT */ +/* ARMv4 (little endian) backend by M-HT (thumb version) */ // temporary "lo" registers @@ -53,6 +53,16 @@ // temporary register for LEA #define TEMP_REG_DRC HOST_a4 +#ifdef DRC_USE_REGS_ADDR +// used to hold the address of "cpu_regs" - preferably filled in function gen_run_code +#define FC_REGS_ADDR HOST_v7 +#endif + +#ifdef DRC_USE_SEGS_ADDR +// used to hold the address of "Segs" - preferably filled in function gen_run_code +#define FC_SEGS_ADDR HOST_v8 +#endif + // move a full register from reg_src to reg_dst static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) { if(reg_src == reg_dst) return; @@ -82,7 +92,6 @@ static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) { cache_addw(0xa000 + (dest_reg << 8) + (Bit8u)(diff >> 2)); // add dest_reg, pc, #(dist >> 2) } else { cache_addw(0x46c0); // nop - // is the result of (diff-2)>>2 correct for diff<2 ??? cache_addw(0xa000 + (dest_reg << 8) + (Bit8u)((diff - 2) >> 2)); // add dest_reg, pc, #((dist - 2) >> 2) } } else { @@ -488,7 +497,7 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) { // short conditional jump (+-127 bytes) if register is zero // the destination is set by gen_fill_branch() later -static Bit32u INLINE gen_create_branch_on_zero(HostReg reg,bool dword) { +static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) { if (dword) { cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 } else { @@ -500,7 +509,7 @@ static Bit32u INLINE gen_create_branch_on_zero(HostReg reg,bool dword) { // short conditional jump (+-127 bytes) if register is nonzero // the destination is set by gen_fill_branch() later -static Bit32u INLINE gen_create_branch_on_nonzero(HostReg reg,bool dword) { +static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) { if (dword) { cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 } else { @@ -545,7 +554,7 @@ static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) { } // compare 32bit-register against zero and jump if value less/equal than zero -static Bit32u INLINE gen_create_branch_long_leqzero(HostReg reg) { +static Bit32u gen_create_branch_long_leqzero(HostReg reg) { cache_addw(0x2800 + (reg << 8)); // cmp reg, #0 if (((Bit32u)cache.pos & 0x03) == 0) { cache_addw(0xdc00 + (8 >> 1)); // bgt nobranch (pc+8) @@ -575,7 +584,18 @@ static void gen_run_code(void) { // thumb state from now on cache_addw(0xb500); // push {lr} - cache_addw(0xb4f0); // push {v1-v4} + cache_addw(0x4640 + HOST_r3 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov r3, FC_SEGS_ADDR + cache_addw(0x4640 + HOST_r2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov r2, FC_REGS_ADDR + cache_addw(0xb4fc); // push {r2,r3,v1-v4} + + // adr: 16 + cache_addw(0x4800 + (HOST_r3 << 8) + ((64 - (16 + 4)) >> 2)); // ldr r3, [pc, #(&Segs)] + // adr: 18 + cache_addw(0x4800 + (HOST_r2 << 8) + ((68 - (18 + 2)) >> 2)); // ldr r2, [pc, #(&cpu_regs)] + cache_addw(0x4680 + (FC_SEGS_ADDR - HOST_r8) + (HOST_r3 << 3)); // mov FC_SEGS_ADDR, r3 + cache_addw(0x4680 + (FC_REGS_ADDR - HOST_r8) + (HOST_r2 << 3)); // mov FC_REGS_ADDR, r2 + + // align 4 cache_addw(0xa302); // add r3, pc, #8 cache_addw(0x3001); // add r0, #1 @@ -584,10 +604,24 @@ static void gen_run_code(void) { cache_addw(0x4700); // bx r0 cache_addw(0x46c0); // nop - cache_addw(0xbcf0); // pop {v1-v4} + // align 4 + cache_addw(0xbcfc); // pop {r2,r3,v1-v4} + cache_addw(0x4680 + (FC_SEGS_ADDR - HOST_r8) + (HOST_r3 << 3)); // mov FC_SEGS_ADDR, r3 + cache_addw(0x4680 + (FC_REGS_ADDR - HOST_r8) + (HOST_r2 << 3)); // mov FC_REGS_ADDR, r2 cache_addw(0xbc08); // pop {r3} cache_addw(0x4718); // bx r3 + // fill up to 64 bytes + cache_addw(0x46c0); // nop + cache_addd(0x46c046c0); // nop, nop + cache_addd(0x46c046c0); // nop, nop + cache_addd(0x46c046c0); // nop, nop + cache_addd(0x46c046c0); // nop, nop + + // adr: 64 + cache_addd((Bit32u)&Segs); // address of "Segs" + // adr: 68 + cache_addd((Bit32u)&cpu_regs); // address of "cpu_regs" } // return from a function @@ -934,3 +968,111 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) { #endif static void cache_block_before_close(void) { } + + +#ifdef DRC_USE_SEGS_ADDR + +// mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { + cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR + cache_addw(0x8800 + dest_reg + (templo1 << 3) + (index << 5)); // ldrh dest_reg, [templo1, #index] +} + +// mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) +static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { + cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR + cache_addw(0x6800 + dest_reg + (templo1 << 3) + (index << 4)); // ldr dest_reg, [templo1, #index] +} + +// add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) +static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { + cache_addw(0x4640 + templo1 + ((FC_SEGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_SEGS_ADDR + cache_addw(0x6800 + templo2 + (templo1 << 3) + (index << 4)); // ldr templo2, [templo1, #index] + cache_addw(0x1800 + reg + (reg << 3) + (templo2 << 6)); // add reg, reg, templo2 +} + +#endif + +#ifdef DRC_USE_REGS_ADDR + +// mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x8800 + dest_reg + (templo2 << 3) + (index << 5)); // ldrh dest_reg, [templo2, #index] +} + +// mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x6800 + dest_reg + (templo2 << 3) + (index << 4)); // ldr dest_reg, [templo2, #index] +} + +// move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + if (dword) { + cache_addw(0x6800 + dest_reg + (templo2 << 3) + (index << 4)); // ldr dest_reg, [templo2, #index] + } else { + cache_addw(0x8800 + dest_reg + (templo2 << 3) + (index << 5)); // ldrh dest_reg, [templo2, #index] + } +} + +// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x7800 + dest_reg + (templo2 << 3) + (index << 6)); // ldrb dest_reg, [templo2, #index] +} + +// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x7800 + dest_reg + (templo2 << 3) + (index << 6)); // ldrb dest_reg, [templo2, #index] +} + + +// add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { + cache_addw(0x4640 + templo2 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo2, FC_REGS_ADDR + cache_addw(0x6800 + templo1 + (templo2 << 3) + (index << 4)); // ldr templo1, [templo2, #index] + cache_addw(0x1800 + reg + (reg << 3) + (templo1 << 6)); // add reg, reg, templo1 +} + + +// move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) +static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw(0x8000 + src_reg + (templo1 << 3) + (index << 5)); // strh src_reg, [templo1, #index] +} + +// move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw(0x6000 + src_reg + (templo1 << 3) + (index << 4)); // str src_reg, [templo1, #index] +} + +// move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) +static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + if (dword) { + cache_addw(0x6000 + src_reg + (templo1 << 3) + (index << 4)); // str src_reg, [templo1, #index] + } else { + cache_addw(0x8000 + src_reg + (templo1 << 3) + (index << 5)); // strh src_reg, [templo1, #index] + } +} + +// move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR +static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { + cache_addw(0x4640 + templo1 + ((FC_REGS_ADDR - HOST_r8) << 3)); // mov templo1, FC_REGS_ADDR + cache_addw(0x7000 + src_reg + (templo1 << 3) + (index << 6)); // strb src_reg, [templo1, #index] +} + +#endif diff --git a/src/cpu/core_dynrec/risc_mipsel32.h b/src/cpu/core_dynrec/risc_mipsel32.h index eb0c124c..bcd92653 100644 --- a/src/cpu/core_dynrec/risc_mipsel32.h +++ b/src/cpu/core_dynrec/risc_mipsel32.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: risc_mipsel32.h,v 1.3 2008-09-02 20:44:41 c2woody Exp $ */ +/* $Id: risc_mipsel32.h,v 1.4 2008-09-19 16:48:03 c2woody Exp $ */ /* MIPS32 (little endian) backend by crazyc */ @@ -38,7 +38,12 @@ // calling convention modifier #define DRC_CALL_CONV /* nothing */ -#define DRC_FC /* nothing */ +#define DRC_FC /* nothing */ + +// use FC_REGS_ADDR to hold the address of "cpu_regs" and to access it using FC_REGS_ADDR +//#define DRC_USE_REGS_ADDR +// use FC_SEGS_ADDR to hold the address of "Segs" and to access it using FC_SEGS_ADDR +//#define DRC_USE_SEGS_ADDR // register mapping typedef Bit8u HostReg; @@ -78,6 +83,16 @@ typedef Bit8u HostReg; // temporary register for LEA #define TEMP_REG_DRC HOST_t7 +#ifdef DRC_USE_REGS_ADDR +// used to hold the address of "cpu_regs" - preferably filled in function gen_run_code +#define FC_REGS_ADDR HOST_??? +#endif + +#ifdef DRC_USE_SEGS_ADDR +// used to hold the address of "Segs" - preferably filled in function gen_run_code +#define FC_SEGS_ADDR HOST_??? +#endif + // save some state to improve code gen static bool temp1_valid = false; static Bit32u temp1_value; @@ -646,3 +661,88 @@ static void cache_block_closing(Bit8u* block_start,Bitu block_size) { } static void cache_block_before_close(void) { } + + +#ifdef DRC_USE_SEGS_ADDR + +// mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) { +// stub +} + +// mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero) +static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) { +// stub +} + +// add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero) +static void gen_add_seg32_to_reg(HostReg reg,Bitu index) { +// stub +} + +#endif + +#ifdef DRC_USE_REGS_ADDR + +// mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) { +// stub +} + +// mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) { +// stub +} + +// move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) +// 16bit moves may destroy the upper 16bit of the destination register +static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) { +// stub +} + +// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR +// the upper 24bit of the destination register can be destroyed +// this function does not use FC_OP1/FC_OP2 as dest_reg as these +// registers might not be directly byte-accessible on some architectures +static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) { +// stub +} + +// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR +// the upper 24bit of the destination register can be destroyed +// this function can use FC_OP1/FC_OP2 as dest_reg which are +// not directly byte-accessible on some architectures +static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) { +// stub +} + + +// add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_add_regval32_to_reg(HostReg reg,Bitu index) { +// stub +} + + +// move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero) +static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) { +// stub +} + +// move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero) +static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) { +// stub +} + +// move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero) +static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) { +// stub +} + +// move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR +static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) { +// stub +} + +#endif