1
0
Fork 0

ability to cache register/segment register pointer in host register for the recompiler (M-HT, implemented for arm backends)

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3220
This commit is contained in:
Sebastian Strohhäcker 2008-09-19 16:48:03 +00:00
parent 5f12dea767
commit 298034bec7
13 changed files with 1179 additions and 218 deletions

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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);
}
}

View file

@ -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<STR_SCASB) {
// those string operations are allowed for premature termination
@ -1304,67 +1311,67 @@ static void dyn_string(StringOps op) {
static void dyn_read_port_byte_direct(Bit8u port) {
dyn_add_iocheck_var(port,1);
gen_call_function_I((void*)&IO_ReadB,port);
gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(DRC_REG_EAX,0));
MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,DRC_REG_EAX,0);
}
static void dyn_read_port_word_direct(Bit8u port) {
dyn_add_iocheck_var(port,decode.big_op?4:2);
gen_call_function_I(decode.big_op?((void*)&IO_ReadD):((void*)&IO_ReadW),port);
gen_mov_word_from_reg(FC_RETOP,DRCD_REG_BYTE(DRC_REG_EAX,decode.big_op),decode.big_op);
MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,DRC_REG_EAX,decode.big_op);
}
static void dyn_write_port_byte_direct(Bit8u port) {
dyn_add_iocheck_var(port,1);
gen_mov_byte_to_reg_low(FC_RETOP,DRCD_REG_BYTE(DRC_REG_EAX,0));
MOV_REG_BYTE_TO_HOST_REG_LOW(FC_RETOP,DRC_REG_EAX,0);
gen_extend_byte(false,FC_RETOP);
gen_call_function_IR((void*)&IO_WriteB,port,FC_RETOP);
}
static void dyn_write_port_word_direct(Bit8u port) {
dyn_add_iocheck_var(port,decode.big_op?4:2);
gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op);
MOV_REG_WORD_TO_HOST_REG(FC_RETOP,DRC_REG_EAX,decode.big_op);
if (!decode.big_op) gen_extend_word(false,FC_RETOP);
gen_call_function_IR(decode.big_op?((void*)&IO_WriteD):((void*)&IO_WriteW),port,FC_RETOP);
}
static void dyn_read_port_byte(void) {
gen_mov_word_to_reg(FC_ADDR,DRCD_REG_WORD(DRC_REG_EDX,false),false);
MOV_REG_WORD16_TO_HOST_REG(FC_ADDR,DRC_REG_EDX);
gen_extend_word(false,FC_ADDR);
gen_protect_addr_reg();
dyn_add_iocheck(FC_ADDR,1);
gen_restore_addr_reg();
gen_call_function_R((void*)&IO_ReadB,FC_ADDR);
gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(DRC_REG_EAX,0));
MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,DRC_REG_EAX,0);
}
static void dyn_read_port_word(void) {
gen_mov_word_to_reg(FC_ADDR,DRCD_REG_WORD(DRC_REG_EDX,false),false);
MOV_REG_WORD16_TO_HOST_REG(FC_ADDR,DRC_REG_EDX);
gen_extend_word(false,FC_ADDR);
gen_protect_addr_reg();
dyn_add_iocheck(FC_ADDR,decode.big_op?4:2);
gen_restore_addr_reg();
gen_call_function_R(decode.big_op?((void*)&IO_ReadD):((void*)&IO_ReadW),FC_ADDR);
gen_mov_word_from_reg(FC_RETOP,DRCD_REG_BYTE(DRC_REG_EAX,decode.big_op),decode.big_op);
MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,DRC_REG_EAX,decode.big_op);
}
static void dyn_write_port_byte(void) {
gen_mov_word_to_reg(FC_ADDR,DRCD_REG_WORD(DRC_REG_EDX,false),false);
MOV_REG_WORD16_TO_HOST_REG(FC_ADDR,DRC_REG_EDX);
gen_extend_word(false,FC_ADDR);
gen_protect_addr_reg();
dyn_add_iocheck(FC_ADDR,1);
gen_mov_byte_to_reg_low(FC_RETOP,DRCD_REG_BYTE(DRC_REG_EAX,0));
MOV_REG_BYTE_TO_HOST_REG_LOW(FC_RETOP,DRC_REG_EAX,0);
gen_extend_byte(false,FC_RETOP);
gen_restore_addr_reg();
gen_call_function_RR((void*)&IO_WriteB,FC_ADDR,FC_RETOP);
}
static void dyn_write_port_word(void) {
gen_mov_word_to_reg(FC_ADDR,DRCD_REG_WORD(DRC_REG_EDX,false),false);
MOV_REG_WORD16_TO_HOST_REG(FC_ADDR,DRC_REG_EDX);
gen_extend_word(false,FC_ADDR);
gen_protect_addr_reg();
dyn_add_iocheck(FC_ADDR,decode.big_op?4:2);
gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op);
MOV_REG_WORD_TO_HOST_REG(FC_RETOP,DRC_REG_EAX,decode.big_op);
if (!decode.big_op) gen_extend_word(false,FC_RETOP);
gen_restore_addr_reg();
gen_call_function_RR(decode.big_op?((void*)&IO_WriteD):((void*)&IO_WriteW),FC_ADDR,FC_RETOP);

View file

@ -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
@ -618,7 +618,7 @@ static void dyn_fpu_esc7(){
gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
gen_call_function_R((void*)&FPU_SET_TOP,FC_OP1);
gen_mov_word_to_reg(FC_OP1,(void*)(&fpu.sw),false);
gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,false),false);
MOV_REG_WORD16_FROM_HOST_REG(FC_OP1,DRC_REG_EAX);
break;
default:
LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm);

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: risc_armv4le-common.h,v 1.1 2008-08-20 14:13:21 c2woody Exp $ */
/* $Id: risc_armv4le-common.h,v 1.2 2008-09-19 16:48:02 c2woody Exp $ */
/* ARMv4 (little endian) backend by M-HT (common data/functions) */
@ -40,6 +40,11 @@
#define DRC_CALL_CONV /* 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;
@ -91,7 +96,7 @@ static void cache_block_closing(Bit8u* block_start,Bitu block_size) {
register unsigned long _flg __asm ("a3") = 0;
__asm __volatile ("swi 0x9f0002 @ sys_cacheflush"
: // no outputs
: // no inputs
: "a1");
: "r" (_beg), "r" (_end), "r" (_flg)
);
// GP2X END
}

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: risc_armv4le-o3.h,v 1.2 2008-09-02 20:44:41 c2woody Exp $ */
/* $Id: risc_armv4le-o3.h,v 1.3 2008-09-19 16:48:02 c2woody Exp $ */
/* ARMv4 (little endian) backend by M-HT (size-tweaked arm version) */
@ -48,6 +48,16 @@
// temporary register for LEA
#define TEMP_REG_DRC HOST_v2
#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
// helper macro
#define ROTATE_SCALE(x) ( (x)?(32 - x):(0) )
@ -684,14 +694,31 @@ static void INLINE gen_fill_branch_long(Bit32u data) {
static void gen_run_code(void) {
cache_addd(0xe92d4000); // stmfd sp!, {lr}
cache_addd(0xe92d01f0); // stmfd sp!, {v1-v5}
cache_addd(0xe92d0df0); // stmfd sp!, {v1-v5,v7,v8}
// adr: 8
cache_addd(0xe5900000 + (FC_SEGS_ADDR << 12) + (HOST_pc << 16) + (64 - (8 + 8))); // ldr FC_SEGS_ADDR, [pc, #(&Segs)]
// adr: 12
cache_addd(0xe5900000 + (FC_REGS_ADDR << 12) + (HOST_pc << 16) + (68 - (12 + 8))); // ldr FC_REGS_ADDR, [pc, #(&cpu_regs)]
cache_addd(0xe28fe004); // add lr, pc, #4
cache_addd(0xe92d4000); // stmfd sp!, {lr}
cache_addd(0xe12fff10); // bx r0
cache_addd(0xe8bd01f0); // ldmfd sp!, {v1-v5}
cache_addd(0xe8bd0df0); // ldmfd sp!, {v1-v5,v7,v8}
cache_addd(0xe8bd4000); // ldmfd sp!, {lr}
cache_addd(0xe12fff1e); // bx lr
// fill up to 64 bytes
cache_addd(0xe1a00000); // nop
cache_addd(0xe1a00000); // nop
cache_addd(0xe1a00000); // nop
cache_addd(0xe1a00000); // nop
cache_addd(0xe1a00000); // nop
cache_addd(0xe1a00000); // 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
@ -858,3 +885,98 @@ 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_addd(0xe1d000b0 + (dest_reg << 12) + (FC_SEGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // ldrh dest_reg, [FC_SEGS_ADDR, #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_addd(0xe5900000 + (dest_reg << 12) + (FC_SEGS_ADDR << 16) + (index)); // ldr dest_reg, [FC_SEGS_ADDR, #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_addd(0xe5900000 + (temp1 << 12) + (FC_SEGS_ADDR << 16) + (index)); // ldr temp1, [FC_SEGS_ADDR, #index]
cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp1)); // add reg, reg, temp1
}
#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_addd(0xe1d000b0 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // ldrh dest_reg, [FC_REGS_ADDR, #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_addd(0xe5900000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldr dest_reg, [FC_REGS_ADDR, #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) {
if (dword) {
cache_addd(0xe5900000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldr dest_reg, [FC_REGS_ADDR, #index]
} else {
cache_addd(0xe1d000b0 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // ldrh dest_reg, [FC_REGS_ADDR, #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_addd(0xe5d00000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldrb dest_reg, [FC_REGS_ADDR, #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_addd(0xe5d00000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldrb dest_reg, [FC_REGS_ADDR, #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_addd(0xe5900000 + (temp2 << 12) + (FC_REGS_ADDR << 16) + (index)); // ldr temp2, [FC_REGS_ADDR, #index]
cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp2)); // add reg, reg, temp2
}
// 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_addd(0xe1c000b0 + (src_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // strh src_reg, [FC_REGS_ADDR, #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_addd(0xe5800000 + (src_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // str src_reg, [FC_REGS_ADDR, #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) {
if (dword) {
cache_addd(0xe5800000 + (src_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // str src_reg, [FC_REGS_ADDR, #index]
} else {
cache_addd(0xe1c000b0 + (src_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // strh src_reg, [FC_REGS_ADDR, #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_addd(0xe5c00000 + (src_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // strb src_reg, [FC_REGS_ADDR, #index]
}
#endif

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: risc_armv4le-s3.h,v 1.2 2008-09-02 20:44:41 c2woody Exp $ */
/* $Id: risc_armv4le-s3.h,v 1.3 2008-09-19 16:48:02 c2woody Exp $ */
/* ARMv4 (little endian) backend by M-HT (speed-tweaked arm version) */
@ -48,6 +48,16 @@
// temporary register for LEA
#define TEMP_REG_DRC HOST_v2
#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
// helper macro
#define ROTATE_SCALE(x) ( (x)?(32 - x):(0) )
@ -520,14 +530,30 @@ static void INLINE gen_fill_branch_long(Bit32u data) {
static void gen_run_code(void) {
cache_addd(0xe92d4000); // stmfd sp!, {lr}
cache_addd(0xe92d01f0); // stmfd sp!, {v1-v5}
cache_addd(0xe92d0df0); // stmfd sp!, {v1-v5,v7,v8}
// adr: 8
cache_addd(0xe5900000 + (FC_SEGS_ADDR << 12) + (HOST_pc << 16) + (64 - (8 + 8))); // ldr FC_SEGS_ADDR, [pc, #(&Segs)]
// adr: 12
cache_addd(0xe5900000 + (FC_REGS_ADDR << 12) + (HOST_pc << 16) + (68 - (12 + 8))); // ldr FC_REGS_ADDR, [pc, #(&cpu_regs)]
cache_addd(0xe28fe004); // add lr, pc, #4
cache_addd(0xe92d4000); // stmfd sp!, {lr}
cache_addd(0xe12fff10); // bx r0
cache_addd(0xe8bd01f0); // ldmfd sp!, {v1-v5}
cache_addd(0xe8bd0df0); // ldmfd sp!, {v1-v5,v7,v8}
cache_addd(0xe8bd4000); // ldmfd sp!, {lr}
cache_addd(0xe12fff1e); // bx lr
// fill up to 64 bytes
cache_addd(0xe1a00000); // nop
cache_addd(0xe1a00000); // nop
cache_addd(0xe1a00000); // nop
cache_addd(0xe1a00000); // nop
cache_addd(0xe1a00000); // nop
cache_addd(0xe1a00000); // 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
@ -694,3 +720,98 @@ 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_addd(0xe1d000b0 + (dest_reg << 12) + (FC_SEGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // ldrh dest_reg, [FC_SEGS_ADDR, #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_addd(0xe5900000 + (dest_reg << 12) + (FC_SEGS_ADDR << 16) + (index)); // ldr dest_reg, [FC_SEGS_ADDR, #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_addd(0xe5900000 + (temp1 << 12) + (FC_SEGS_ADDR << 16) + (index)); // ldr temp1, [FC_SEGS_ADDR, #index]
cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp1)); // add reg, reg, temp1
}
#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_addd(0xe1d000b0 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // ldrh dest_reg, [FC_REGS_ADDR, #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_addd(0xe5900000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldr dest_reg, [FC_REGS_ADDR, #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) {
if (dword) {
cache_addd(0xe5900000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldr dest_reg, [FC_REGS_ADDR, #index]
} else {
cache_addd(0xe1d000b0 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // ldrh dest_reg, [FC_REGS_ADDR, #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_addd(0xe5d00000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldrb dest_reg, [FC_REGS_ADDR, #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_addd(0xe5d00000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldrb dest_reg, [FC_REGS_ADDR, #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_addd(0xe5900000 + (temp2 << 12) + (FC_REGS_ADDR << 16) + (index)); // ldr temp2, [FC_REGS_ADDR, #index]
cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp2)); // add reg, reg, temp2
}
// 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_addd(0xe1c000b0 + (src_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // strh src_reg, [FC_REGS_ADDR, #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_addd(0xe5800000 + (src_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // str src_reg, [FC_REGS_ADDR, #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) {
if (dword) {
cache_addd(0xe5800000 + (src_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // str src_reg, [FC_REGS_ADDR, #index]
} else {
cache_addd(0xe1c000b0 + (src_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // strh src_reg, [FC_REGS_ADDR, #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_addd(0xe5c00000 + (src_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // strb src_reg, [FC_REGS_ADDR, #index]
}
#endif

View file

@ -16,10 +16,10 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: risc_armv4le-thumb-iw.h,v 1.1 2008-09-02 20:44:41 c2woody Exp $ */
/* $Id: risc_armv4le-thumb-iw.h,v 1.2 2008-09-19 16:48:02 c2woody Exp $ */
/* ARMv4 (little endian) backend by M-HT (thumb version, requires -mthumb-interwork switch when compiling dosbox) */
/* ARMv4 (little endian) backend by M-HT (thumb version with data pool, requires -mthumb-interwork switch when compiling dosbox) */
// 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
@ -751,7 +761,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
@ -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

View file

@ -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

View file

@ -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

View file

@ -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