mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Convert m68k target to TCG.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4565 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
@@ -1237,10 +1237,8 @@ case "$target_cpu" in
|
||||
;;
|
||||
m68k)
|
||||
echo "TARGET_ARCH=m68k" >> $config_mak
|
||||
echo "CONFIG_DYNGEN_OP=yes" >> $config_mak
|
||||
echo "#define TARGET_ARCH \"m68k\"" >> $config_h
|
||||
echo "#define TARGET_M68K 1" >> $config_h
|
||||
echo "#define CONFIG_DYNGEN_OP 1" >> $config_h
|
||||
bflt="yes"
|
||||
;;
|
||||
mips|mipsel)
|
||||
|
||||
+3
-4
@@ -108,7 +108,7 @@ typedef struct CPUM68KState {
|
||||
int exception_index;
|
||||
int interrupt_request;
|
||||
int user_mode_only;
|
||||
int halted;
|
||||
uint32_t halted;
|
||||
|
||||
int pending_vector;
|
||||
int pending_level;
|
||||
@@ -120,6 +120,7 @@ typedef struct CPUM68KState {
|
||||
uint32_t features;
|
||||
} CPUM68KState;
|
||||
|
||||
void m68k_tcg_init(void);
|
||||
CPUM68KState *cpu_m68k_init(const char *cpu_model);
|
||||
int cpu_m68k_exec(CPUM68KState *s);
|
||||
void cpu_m68k_close(CPUM68KState *s);
|
||||
@@ -141,9 +142,7 @@ enum {
|
||||
CC_OP_CMPW, /* CC_DEST = result, CC_SRC = source */
|
||||
CC_OP_ADDX, /* CC_DEST = result, CC_SRC = source */
|
||||
CC_OP_SUBX, /* CC_DEST = result, CC_SRC = source */
|
||||
CC_OP_SHL, /* CC_DEST = source, CC_SRC = shift */
|
||||
CC_OP_SHR, /* CC_DEST = source, CC_SRC = shift */
|
||||
CC_OP_SAR, /* CC_DEST = source, CC_SRC = shift */
|
||||
CC_OP_SHIFT, /* CC_DEST = result, CC_SRC = carry */
|
||||
};
|
||||
|
||||
#define CCF_C 0x01
|
||||
|
||||
@@ -45,8 +45,6 @@ int cpu_m68k_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
|
||||
#endif
|
||||
|
||||
void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op);
|
||||
float64 helper_sub_cmpf64(CPUM68KState *env, float64 src0, float64 src1);
|
||||
void helper_movec(CPUM68KState *env, int reg, uint32_t val);
|
||||
|
||||
void cpu_loop_exit(void);
|
||||
|
||||
|
||||
+552
-48
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,138 @@
|
||||
#ifndef DEF_HELPER
|
||||
#define DEF_HELPER(name, ret, args) ret glue(helper_,name) args;
|
||||
#endif
|
||||
|
||||
#ifdef GEN_HELPER
|
||||
#define DEF_HELPER_0_0(name, ret, args) \
|
||||
DEF_HELPER(name, ret, args) \
|
||||
static inline void gen_helper_##name(void) \
|
||||
{ \
|
||||
tcg_gen_helper_0_0(helper_##name); \
|
||||
}
|
||||
#define DEF_HELPER_0_1(name, ret, args) \
|
||||
DEF_HELPER(name, ret, args) \
|
||||
static inline void gen_helper_##name(TCGv arg1) \
|
||||
{ \
|
||||
tcg_gen_helper_0_1(helper_##name, arg1); \
|
||||
}
|
||||
#define DEF_HELPER_0_2(name, ret, args) \
|
||||
DEF_HELPER(name, ret, args) \
|
||||
static inline void gen_helper_##name(TCGv arg1, TCGv arg2) \
|
||||
{ \
|
||||
tcg_gen_helper_0_2(helper_##name, arg1, arg2); \
|
||||
}
|
||||
#define DEF_HELPER_0_3(name, ret, args) \
|
||||
DEF_HELPER(name, ret, args) \
|
||||
static inline void gen_helper_##name( \
|
||||
TCGv arg1, TCGv arg2, TCGv arg3) \
|
||||
{ \
|
||||
tcg_gen_helper_0_3(helper_##name, arg1, arg2, arg3); \
|
||||
}
|
||||
#define DEF_HELPER_1_0(name, ret, args) \
|
||||
DEF_HELPER(name, ret, args) \
|
||||
static inline void gen_helper_##name(TCGv ret) \
|
||||
{ \
|
||||
tcg_gen_helper_1_0(helper_##name, ret); \
|
||||
}
|
||||
#define DEF_HELPER_1_1(name, ret, args) \
|
||||
DEF_HELPER(name, ret, args) \
|
||||
static inline void gen_helper_##name(TCGv ret, TCGv arg1) \
|
||||
{ \
|
||||
tcg_gen_helper_1_1(helper_##name, ret, arg1); \
|
||||
}
|
||||
#define DEF_HELPER_1_2(name, ret, args) \
|
||||
DEF_HELPER(name, ret, args) \
|
||||
static inline void gen_helper_##name(TCGv ret, TCGv arg1, TCGv arg2) \
|
||||
{ \
|
||||
tcg_gen_helper_1_2(helper_##name, ret, arg1, arg2); \
|
||||
}
|
||||
#define DEF_HELPER_1_3(name, ret, args) \
|
||||
DEF_HELPER(name, ret, args) \
|
||||
static inline void gen_helper_##name(TCGv ret, \
|
||||
TCGv arg1, TCGv arg2, TCGv arg3) \
|
||||
{ \
|
||||
tcg_gen_helper_1_3(helper_##name, ret, arg1, arg2, arg3); \
|
||||
}
|
||||
#define DEF_HELPER_1_4(name, ret, args) \
|
||||
DEF_HELPER(name, ret, args) \
|
||||
static inline void gen_helper_##name(TCGv ret, \
|
||||
TCGv arg1, TCGv arg2, TCGv arg3, TCGv arg4) \
|
||||
{ \
|
||||
tcg_gen_helper_1_4(helper_##name, ret, arg1, arg2, arg3, arg4); \
|
||||
}
|
||||
#else /* !GEN_HELPER */
|
||||
#define DEF_HELPER_0_0 DEF_HELPER
|
||||
#define DEF_HELPER_0_1 DEF_HELPER
|
||||
#define DEF_HELPER_0_2 DEF_HELPER
|
||||
#define DEF_HELPER_0_3 DEF_HELPER
|
||||
#define DEF_HELPER_1_0 DEF_HELPER
|
||||
#define DEF_HELPER_1_1 DEF_HELPER
|
||||
#define DEF_HELPER_1_2 DEF_HELPER
|
||||
#define DEF_HELPER_1_3 DEF_HELPER
|
||||
#define DEF_HELPER_1_4 DEF_HELPER
|
||||
#define HELPER(x) glue(helper_,x)
|
||||
#endif
|
||||
|
||||
DEF_HELPER_1_1(bitrev, uint32_t, (uint32_t))
|
||||
DEF_HELPER_1_1(ff1, uint32_t, (uint32_t))
|
||||
DEF_HELPER_1_2(sats, uint32_t, (uint32_t, uint32_t))
|
||||
DEF_HELPER_0_2(divu, void, (CPUState *, uint32_t))
|
||||
DEF_HELPER_0_2(divs, void, (CPUState *, uint32_t))
|
||||
DEF_HELPER_1_3(addx_cc, uint32_t, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_1_3(subx_cc, uint32_t, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_1_3(shl_cc, uint32_t, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_1_3(shr_cc, uint32_t, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_1_3(sar_cc, uint32_t, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_1_2(xflag_lt, uint32_t, (uint32_t, uint32_t))
|
||||
DEF_HELPER_0_2(set_sr, void, (CPUState *, uint32_t))
|
||||
DEF_HELPER_0_3(movec, void, (CPUState *, uint32_t, uint32_t))
|
||||
|
||||
DEF_HELPER_1_2(f64_to_i32, float32, (CPUState *, float64))
|
||||
DEF_HELPER_1_2(f64_to_f32, float32, (CPUState *, float64))
|
||||
DEF_HELPER_1_2(i32_to_f64, float64, (CPUState *, uint32_t))
|
||||
DEF_HELPER_1_2(f32_to_f64, float64, (CPUState *, float32))
|
||||
DEF_HELPER_1_2(iround_f64, float64, (CPUState *, float64))
|
||||
DEF_HELPER_1_2(itrunc_f64, float64, (CPUState *, float64))
|
||||
DEF_HELPER_1_2(sqrt_f64, float64, (CPUState *, float64))
|
||||
DEF_HELPER_1_1(abs_f64, float64, (float64))
|
||||
DEF_HELPER_1_1(chs_f64, float64, (float64))
|
||||
DEF_HELPER_1_3(add_f64, float64, (CPUState *, float64, float64))
|
||||
DEF_HELPER_1_3(sub_f64, float64, (CPUState *, float64, float64))
|
||||
DEF_HELPER_1_3(mul_f64, float64, (CPUState *, float64, float64))
|
||||
DEF_HELPER_1_3(div_f64, float64, (CPUState *, float64, float64))
|
||||
DEF_HELPER_1_3(sub_cmp_f64, float64, (CPUState *, float64, float64))
|
||||
DEF_HELPER_1_2(compare_f64, uint32_t, (CPUState *, float64))
|
||||
|
||||
DEF_HELPER_0_3(mac_move, void, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_1_3(macmulf, uint64_t, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_1_3(macmuls, uint64_t, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_1_3(macmulu, uint64_t, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_0_2(macsats, void, (CPUState *, uint32_t))
|
||||
DEF_HELPER_0_2(macsatu, void, (CPUState *, uint32_t))
|
||||
DEF_HELPER_0_2(macsatf, void, (CPUState *, uint32_t))
|
||||
DEF_HELPER_0_2(mac_set_flags, void, (CPUState *, uint32_t))
|
||||
DEF_HELPER_0_2(set_macsr, void, (CPUState *, uint32_t))
|
||||
DEF_HELPER_1_2(get_macf, uint32_t, (CPUState *, uint64_t))
|
||||
DEF_HELPER_1_1(get_macs, uint32_t, (uint64_t))
|
||||
DEF_HELPER_1_1(get_macu, uint32_t, (uint64_t))
|
||||
DEF_HELPER_1_2(get_mac_extf, uint32_t, (CPUState *, uint32_t))
|
||||
DEF_HELPER_1_2(get_mac_exti, uint32_t, (CPUState *, uint32_t))
|
||||
DEF_HELPER_0_3(set_mac_extf, void, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_0_3(set_mac_exts, void, (CPUState *, uint32_t, uint32_t))
|
||||
DEF_HELPER_0_3(set_mac_extu, void, (CPUState *, uint32_t, uint32_t))
|
||||
|
||||
DEF_HELPER_0_2(flush_flags, void, (CPUState *, uint32_t))
|
||||
DEF_HELPER_0_1(raise_exception, void, (uint32_t))
|
||||
|
||||
#undef DEF_HELPER
|
||||
#undef DEF_HELPER_0_0
|
||||
#undef DEF_HELPER_0_1
|
||||
#undef DEF_HELPER_0_2
|
||||
#undef DEF_HELPER_0_3
|
||||
#undef DEF_HELPER_1_0
|
||||
#undef DEF_HELPER_1_1
|
||||
#undef DEF_HELPER_1_2
|
||||
#undef DEF_HELPER_1_3
|
||||
#undef DEF_HELPER_1_4
|
||||
#undef GEN_HELPER
|
||||
#undef DEF_HELPER
|
||||
@@ -1,130 +0,0 @@
|
||||
/* Various hacks to make code written for a dynamic code generator work
|
||||
with regular QEMU. */
|
||||
|
||||
static int free_qreg;
|
||||
|
||||
#define QMODE_I32 1
|
||||
#define QMODE_F32 1
|
||||
#define QMODE_F64 2
|
||||
|
||||
static inline int gen_new_qreg(int mode)
|
||||
{
|
||||
int qreg;
|
||||
|
||||
qreg = free_qreg;
|
||||
free_qreg += mode;
|
||||
if (free_qreg > MAX_QREGS) {
|
||||
fprintf(stderr, "qreg overflow\n");
|
||||
abort();
|
||||
}
|
||||
return qreg + TARGET_NUM_QREGS;
|
||||
}
|
||||
|
||||
static inline int gen_im32(uint32_t i)
|
||||
{
|
||||
int qreg = gen_new_qreg(QMODE_I32);
|
||||
gen_op_mov32_im(qreg, i);
|
||||
return qreg;
|
||||
}
|
||||
|
||||
static inline void gen_op_ldf32_raw(int dest, int addr)
|
||||
{
|
||||
gen_op_ld32_raw(dest, addr);
|
||||
}
|
||||
|
||||
static inline void gen_op_stf32_raw(int addr, int dest)
|
||||
{
|
||||
gen_op_st32_raw(addr, dest);
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
static inline void gen_op_ldf32_user(int dest, int addr)
|
||||
{
|
||||
gen_op_ld32_user(dest, addr);
|
||||
}
|
||||
|
||||
static inline void gen_op_stf32_user(int addr, int dest)
|
||||
{
|
||||
gen_op_st32_user(addr, dest);
|
||||
}
|
||||
|
||||
static inline void gen_op_ldf32_kernel(int dest, int addr)
|
||||
{
|
||||
gen_op_ld32_kernel(dest, addr);
|
||||
}
|
||||
|
||||
static inline void gen_op_stf32_kernel(int addr, int dest)
|
||||
{
|
||||
gen_op_st32_kernel(addr, dest);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void gen_op_pack_32_f32(int dest, int src)
|
||||
{
|
||||
gen_op_mov32(dest, src);
|
||||
}
|
||||
|
||||
static inline void gen_op_pack_f32_32(int dest, int src)
|
||||
{
|
||||
gen_op_mov32(dest, src);
|
||||
}
|
||||
|
||||
static inline void gen_op_flags_set(void)
|
||||
{
|
||||
/* Dummy op. */
|
||||
}
|
||||
|
||||
static inline void gen_op_shl_im_cc(int val, int shift)
|
||||
{
|
||||
gen_op_shl_cc(val, gen_im32(shift));
|
||||
}
|
||||
|
||||
static inline void gen_op_shr_im_cc(int val, int shift)
|
||||
{
|
||||
gen_op_shr_cc(val, gen_im32(shift));
|
||||
}
|
||||
|
||||
static inline void gen_op_sar_im_cc(int val, int shift)
|
||||
{
|
||||
gen_op_sar_cc(val, gen_im32(shift));
|
||||
}
|
||||
|
||||
#ifdef USE_DIRECT_JUMP
|
||||
#define TBPARAM(x)
|
||||
#else
|
||||
#define TBPARAM(x) (long)(x)
|
||||
#endif
|
||||
|
||||
static inline void gen_op_goto_tb(int dummy, int n, long tb)
|
||||
{
|
||||
if (n == 0) {
|
||||
gen_op_goto_tb0(TBPARAM(tb));
|
||||
} else {
|
||||
gen_op_goto_tb1(TBPARAM(tb));
|
||||
}
|
||||
}
|
||||
|
||||
static inline void gen_op_jmp_z32(int val, int label)
|
||||
{
|
||||
gen_op_set_T0_z32(val);
|
||||
gen_op_jmp_T0(label);
|
||||
}
|
||||
|
||||
static inline void gen_op_jmp_nz32(int val, int label)
|
||||
{
|
||||
gen_op_set_T0_nz32(val);
|
||||
gen_op_jmp_T0(label);
|
||||
}
|
||||
|
||||
static inline void gen_op_jmp_s32(int val, int label)
|
||||
{
|
||||
gen_op_set_T0_s32(val);
|
||||
gen_op_jmp_T0(label);
|
||||
}
|
||||
|
||||
static inline void gen_op_jmp_ns32(int val, int label)
|
||||
{
|
||||
gen_op_set_T0_ns32(val);
|
||||
gen_op_jmp_T0(label);
|
||||
}
|
||||
|
||||
-1059
File diff suppressed because it is too large
Load Diff
@@ -18,6 +18,7 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "exec.h"
|
||||
#include "helpers.h"
|
||||
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
|
||||
@@ -161,3 +162,71 @@ void do_interrupt(int is_hw)
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void raise_exception(int tt)
|
||||
{
|
||||
env->exception_index = tt;
|
||||
cpu_loop_exit();
|
||||
}
|
||||
|
||||
void HELPER(raise_exception)(uint32_t tt)
|
||||
{
|
||||
raise_exception(tt);
|
||||
}
|
||||
|
||||
void HELPER(divu)(CPUState *env, uint32_t word)
|
||||
{
|
||||
uint32_t num;
|
||||
uint32_t den;
|
||||
uint32_t quot;
|
||||
uint32_t rem;
|
||||
uint32_t flags;
|
||||
|
||||
num = env->div1;
|
||||
den = env->div2;
|
||||
/* ??? This needs to make sure the throwing location is accurate. */
|
||||
if (den == 0)
|
||||
raise_exception(EXCP_DIV0);
|
||||
quot = num / den;
|
||||
rem = num % den;
|
||||
flags = 0;
|
||||
/* Avoid using a PARAM1 of zero. This breaks dyngen because it uses
|
||||
the address of a symbol, and gcc knows symbols can't have address
|
||||
zero. */
|
||||
if (word && quot > 0xffff)
|
||||
flags |= CCF_V;
|
||||
if (quot == 0)
|
||||
flags |= CCF_Z;
|
||||
else if ((int32_t)quot < 0)
|
||||
flags |= CCF_N;
|
||||
env->div1 = quot;
|
||||
env->div2 = rem;
|
||||
env->cc_dest = flags;
|
||||
}
|
||||
|
||||
void HELPER(divs)(CPUState *env, uint32_t word)
|
||||
{
|
||||
int32_t num;
|
||||
int32_t den;
|
||||
int32_t quot;
|
||||
int32_t rem;
|
||||
int32_t flags;
|
||||
|
||||
num = env->div1;
|
||||
den = env->div2;
|
||||
if (den == 0)
|
||||
raise_exception(EXCP_DIV0);
|
||||
quot = num / den;
|
||||
rem = num % den;
|
||||
flags = 0;
|
||||
if (word && quot != (int16_t)quot)
|
||||
flags |= CCF_V;
|
||||
if (quot == 0)
|
||||
flags |= CCF_Z;
|
||||
else if (quot < 0)
|
||||
flags |= CCF_N;
|
||||
env->div1 = quot;
|
||||
env->div2 = rem;
|
||||
env->cc_dest = flags;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/* Load/store ops. */
|
||||
#define MEM_LD_OP(name,suffix) \
|
||||
OP(glue(glue(ld,name),MEMSUFFIX)) \
|
||||
{ \
|
||||
uint32_t addr = get_op(PARAM2); \
|
||||
set_op(PARAM1, glue(glue(ld,suffix),MEMSUFFIX)(addr)); \
|
||||
FORCE_RET(); \
|
||||
}
|
||||
|
||||
MEM_LD_OP(8u32,ub)
|
||||
MEM_LD_OP(8s32,sb)
|
||||
MEM_LD_OP(16u32,uw)
|
||||
MEM_LD_OP(16s32,sw)
|
||||
MEM_LD_OP(32,l)
|
||||
|
||||
#undef MEM_LD_OP
|
||||
|
||||
#define MEM_ST_OP(name,suffix) \
|
||||
OP(glue(glue(st,name),MEMSUFFIX)) \
|
||||
{ \
|
||||
uint32_t addr = get_op(PARAM1); \
|
||||
glue(glue(st,suffix),MEMSUFFIX)(addr, get_op(PARAM2)); \
|
||||
FORCE_RET(); \
|
||||
}
|
||||
|
||||
MEM_ST_OP(8,b)
|
||||
MEM_ST_OP(16,w)
|
||||
MEM_ST_OP(32,l)
|
||||
|
||||
#undef MEM_ST_OP
|
||||
|
||||
OP(glue(ldf64,MEMSUFFIX))
|
||||
{
|
||||
uint32_t addr = get_op(PARAM2);
|
||||
set_opf64(PARAM1, glue(ldfq,MEMSUFFIX)(addr));
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
OP(glue(stf64,MEMSUFFIX))
|
||||
{
|
||||
uint32_t addr = get_op(PARAM1);
|
||||
glue(stfq,MEMSUFFIX)(addr, get_opf64(PARAM2));
|
||||
FORCE_RET();
|
||||
}
|
||||
|
||||
#undef MEMSUFFIX
|
||||
+1
-25
@@ -1,37 +1,13 @@
|
||||
DEFO32(D0, dregs[0])
|
||||
DEFO32(D1, dregs[1])
|
||||
DEFO32(D2, dregs[2])
|
||||
DEFO32(D3, dregs[3])
|
||||
DEFO32(D4, dregs[4])
|
||||
DEFO32(D5, dregs[5])
|
||||
DEFO32(D6, dregs[6])
|
||||
DEFO32(D7, dregs[7])
|
||||
DEFO32(A0, aregs[0])
|
||||
DEFO32(A1, aregs[1])
|
||||
DEFO32(A2, aregs[2])
|
||||
DEFO32(A3, aregs[3])
|
||||
DEFO32(A4, aregs[4])
|
||||
DEFO32(A5, aregs[5])
|
||||
DEFO32(A6, aregs[6])
|
||||
DEFO32(SP, aregs[7]) /* A7 */
|
||||
DEFF64(F0, fregs[0])
|
||||
DEFF64(F1, fregs[1])
|
||||
DEFF64(F2, fregs[2])
|
||||
DEFF64(F3, fregs[3])
|
||||
DEFF64(F4, fregs[4])
|
||||
DEFF64(F5, fregs[5])
|
||||
DEFF64(F6, fregs[6])
|
||||
DEFF64(F7, fregs[7])
|
||||
DEFF64(FP_RESULT, fp_result)
|
||||
DEFO32(PC, pc)
|
||||
DEFO32(SR, sr)
|
||||
DEFO32(CC_OP, cc_op)
|
||||
DEFR(T0, AREG1, QMODE_I32)
|
||||
DEFO32(CC_DEST, cc_dest)
|
||||
DEFO32(CC_SRC, cc_src)
|
||||
DEFO32(CC_X, cc_x)
|
||||
DEFO32(DIV1, div1)
|
||||
DEFO32(DIV2, div2)
|
||||
DEFO32(EXCEPTION, exception_index)
|
||||
DEFO32(HALTED, halted)
|
||||
DEFO32(MACSR, macsr)
|
||||
DEFO32(MAC_MASK, mac_mask)
|
||||
|
||||
+810
-1035
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user