Modify Sparc32/64 to use TCG

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3989 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
blueswir1 2008-02-24 14:10:06 +00:00
parent f8422f52fd
commit 1a2fb1c009
7 changed files with 895 additions and 1568 deletions

View File

@ -52,12 +52,6 @@ register uint32_t T2 asm(AREG3);
void cpu_lock(void);
void cpu_unlock(void);
void cpu_loop_exit(void);
void helper_flush(target_ulong addr);
void helper_ld_asi(int asi, int size, int sign);
void helper_st_asi(int asi, int size);
void helper_ldf_asi(int asi, int size, int rd);
void helper_stf_asi(int asi, int size, int rd);
void helper_rett(void);
void helper_ldfsr(void);
void set_cwp(int new_cwp);
void do_fitos(void);
@ -101,23 +95,13 @@ void do_fcmpeq_fcc1(void);
void do_fcmpeq_fcc2(void);
void do_fcmpeq_fcc3(void);
#endif
void do_popc();
void do_wrpstate();
void do_done();
void do_retry();
#endif
void do_ldd_kernel(target_ulong addr);
void do_ldd_user(target_ulong addr);
void do_ldd_raw(target_ulong addr);
void do_interrupt(int intno);
void raise_exception(int tt);
void check_ieee_exceptions();
void memcpy32(target_ulong *dst, const target_ulong *src);
target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev);
void dump_mmu(CPUState *env);
void helper_debug();
void do_wrpsr();
void do_rdpsr();
/* XXX: move that to a generic header */
#if !defined(CONFIG_USER_ONLY)

32
target-sparc/helper.h Normal file
View File

@ -0,0 +1,32 @@
#define TCG_HELPER_PROTO
#ifndef TARGET_SPARC64
void TCG_HELPER_PROTO helper_rett(void);
void TCG_HELPER_PROTO helper_wrpsr(target_ulong new_psr);
target_ulong TCG_HELPER_PROTO helper_rdpsr(void);
#else
void TCG_HELPER_PROTO helper_wrpstate(target_ulong new_state);
void TCG_HELPER_PROTO helper_done(void);
void TCG_HELPER_PROTO helper_retry(void);
target_ulong TCG_HELPER_PROTO helper_popc(target_ulong val);
void TCG_HELPER_PROTO helper_ldf_asi(target_ulong addr, int asi, int size,
int rd);
void TCG_HELPER_PROTO helper_stf_asi(target_ulong addr, int asi, int size,
int rd);
target_ulong TCG_HELPER_PROTO
helper_cas_asi(target_ulong addr, target_ulong val1,
target_ulong val2, uint32_t asi);
target_ulong TCG_HELPER_PROTO
helper_casx_asi(target_ulong addr, target_ulong val1,
target_ulong val2, uint32_t asi);
#endif
void TCG_HELPER_PROTO helper_trap(target_ulong nb_trap);
void TCG_HELPER_PROTO helper_trapcc(target_ulong nb_trap,
target_ulong do_trap);
void TCG_HELPER_PROTO helper_debug(void);
void TCG_HELPER_PROTO helper_flush(target_ulong addr);
uint64_t TCG_HELPER_PROTO helper_pack64(target_ulong high, target_ulong low);
uint64_t TCG_HELPER_PROTO helper_ld_asi(target_ulong addr, int asi,
int size, int sign);
void TCG_HELPER_PROTO helper_st_asi(target_ulong addr, uint64_t val, int asi,
int size);

View File

@ -19,104 +19,7 @@
*/
#include "exec.h"
/*XXX*/
#define REGNAME g0
#define REG (env->gregs[0])
#include "op_template.h"
#define REGNAME g1
#define REG (env->gregs[1])
#include "op_template.h"
#define REGNAME g2
#define REG (env->gregs[2])
#include "op_template.h"
#define REGNAME g3
#define REG (env->gregs[3])
#include "op_template.h"
#define REGNAME g4
#define REG (env->gregs[4])
#include "op_template.h"
#define REGNAME g5
#define REG (env->gregs[5])
#include "op_template.h"
#define REGNAME g6
#define REG (env->gregs[6])
#include "op_template.h"
#define REGNAME g7
#define REG (env->gregs[7])
#include "op_template.h"
#define REGNAME i0
#define REG (REGWPTR[16])
#include "op_template.h"
#define REGNAME i1
#define REG (REGWPTR[17])
#include "op_template.h"
#define REGNAME i2
#define REG (REGWPTR[18])
#include "op_template.h"
#define REGNAME i3
#define REG (REGWPTR[19])
#include "op_template.h"
#define REGNAME i4
#define REG (REGWPTR[20])
#include "op_template.h"
#define REGNAME i5
#define REG (REGWPTR[21])
#include "op_template.h"
#define REGNAME i6
#define REG (REGWPTR[22])
#include "op_template.h"
#define REGNAME i7
#define REG (REGWPTR[23])
#include "op_template.h"
#define REGNAME l0
#define REG (REGWPTR[8])
#include "op_template.h"
#define REGNAME l1
#define REG (REGWPTR[9])
#include "op_template.h"
#define REGNAME l2
#define REG (REGWPTR[10])
#include "op_template.h"
#define REGNAME l3
#define REG (REGWPTR[11])
#include "op_template.h"
#define REGNAME l4
#define REG (REGWPTR[12])
#include "op_template.h"
#define REGNAME l5
#define REG (REGWPTR[13])
#include "op_template.h"
#define REGNAME l6
#define REG (REGWPTR[14])
#include "op_template.h"
#define REGNAME l7
#define REG (REGWPTR[15])
#include "op_template.h"
#define REGNAME o0
#define REG (REGWPTR[0])
#include "op_template.h"
#define REGNAME o1
#define REG (REGWPTR[1])
#include "op_template.h"
#define REGNAME o2
#define REG (REGWPTR[2])
#include "op_template.h"
#define REGNAME o3
#define REG (REGWPTR[3])
#include "op_template.h"
#define REGNAME o4
#define REG (REGWPTR[4])
#include "op_template.h"
#define REGNAME o5
#define REG (REGWPTR[5])
#include "op_template.h"
#define REGNAME o6
#define REG (REGWPTR[6])
#include "op_template.h"
#define REGNAME o7
#define REG (REGWPTR[7])
#include "op_template.h"
#include "helper.h"
#define REGNAME f0
#define REG (env->fpr[0])
@ -267,106 +170,11 @@
#endif
#ifdef TARGET_SPARC64
#ifdef WORDS_BIGENDIAN
typedef union UREG64 {
struct { uint16_t v3, v2, v1, v0; } w;
struct { uint32_t v1, v0; } l;
uint64_t q;
} UREG64;
#else
typedef union UREG64 {
struct { uint16_t v0, v1, v2, v3; } w;
struct { uint32_t v0, v1; } l;
uint64_t q;
} UREG64;
#endif
#define PARAMQ1 \
({\
UREG64 __p;\
__p.l.v1 = PARAM1;\
__p.l.v0 = PARAM2;\
__p.q;\
})
void OPPROTO op_movq_T0_im64(void)
{
T0 = PARAMQ1;
}
void OPPROTO op_movq_T1_im64(void)
{
T1 = PARAMQ1;
}
#define XFLAG_SET(x) ((env->xcc&x)?1:0)
#else
#define EIP (env->pc)
#endif
#define FLAG_SET(x) ((env->psr&x)?1:0)
void OPPROTO op_movl_T0_0(void)
{
T0 = 0;
}
void OPPROTO op_movl_T0_im(void)
{
T0 = (uint32_t)PARAM1;
}
void OPPROTO op_movl_T1_im(void)
{
T1 = (uint32_t)PARAM1;
}
void OPPROTO op_movl_T2_im(void)
{
T2 = (uint32_t)PARAM1;
}
void OPPROTO op_movl_T0_sim(void)
{
T0 = (int32_t)PARAM1;
}
void OPPROTO op_movl_T1_sim(void)
{
T1 = (int32_t)PARAM1;
}
void OPPROTO op_movl_T2_sim(void)
{
T2 = (int32_t)PARAM1;
}
void OPPROTO op_movl_T0_env(void)
{
T0 = *(uint32_t *)((char *)env + PARAM1);
}
void OPPROTO op_movl_env_T0(void)
{
*(uint32_t *)((char *)env + PARAM1) = T0;
}
void OPPROTO op_movtl_T0_env(void)
{
T0 = *(target_ulong *)((char *)env + PARAM1);
}
void OPPROTO op_movtl_env_T0(void)
{
*(target_ulong *)((char *)env + PARAM1) = T0;
}
void OPPROTO op_add_T1_T0(void)
{
T0 += T1;
}
void OPPROTO op_add_T1_T0_cc(void)
{
target_ulong src1;
@ -565,11 +373,6 @@ void OPPROTO op_tadd_T1_T0_ccTV(void)
FORCE_RET();
}
void OPPROTO op_sub_T1_T0(void)
{
T0 -= T1;
}
void OPPROTO op_sub_T1_T0_cc(void)
{
target_ulong src1;
@ -765,21 +568,6 @@ void OPPROTO op_tsub_T1_T0_ccTV(void)
FORCE_RET();
}
void OPPROTO op_and_T1_T0(void)
{
T0 &= T1;
}
void OPPROTO op_or_T1_T0(void)
{
T0 |= T1;
}
void OPPROTO op_xor_T1_T0(void)
{
T0 ^= T1;
}
void OPPROTO op_andn_T1_T0(void)
{
T0 &= ~T1;
@ -921,12 +709,6 @@ void OPPROTO op_div_cc(void)
}
#ifdef TARGET_SPARC64
void OPPROTO op_mulx_T1_T0(void)
{
T0 *= T1;
FORCE_RET();
}
void OPPROTO op_udivx_T1_T0(void)
{
if (T1 == 0) {
@ -972,48 +754,6 @@ void OPPROTO op_logic_T0_cc(void)
FORCE_RET();
}
void OPPROTO op_sll(void)
{
T0 <<= (T1 & 0x1f);
}
#ifdef TARGET_SPARC64
void OPPROTO op_sllx(void)
{
T0 <<= (T1 & 0x3f);
}
void OPPROTO op_srl(void)
{
T0 = (T0 & 0xffffffff) >> (T1 & 0x1f);
}
void OPPROTO op_srlx(void)
{
T0 >>= (T1 & 0x3f);
}
void OPPROTO op_sra(void)
{
T0 = ((int32_t) (T0 & 0xffffffff)) >> (T1 & 0x1f);
}
void OPPROTO op_srax(void)
{
T0 = ((int64_t) T0) >> (T1 & 0x3f);
}
#else
void OPPROTO op_srl(void)
{
T0 >>= (T1 & 0x1f);
}
void OPPROTO op_sra(void)
{
T0 = ((int32_t) T0) >> (T1 & 0x1f);
}
#endif
/* Load and store */
#define MEMSUFFIX _raw
#include "op_mem.h"
@ -1042,32 +782,6 @@ void OPPROTO op_stfsr(void)
}
#ifndef TARGET_SPARC64
void OPPROTO op_rdpsr(void)
{
do_rdpsr();
}
void OPPROTO op_wrpsr(void)
{
do_wrpsr();
FORCE_RET();
}
void OPPROTO op_wrwim(void)
{
#if NWINDOWS == 32
env->wim = T0;
#else
env->wim = T0 & ((1 << NWINDOWS) - 1);
#endif
}
void OPPROTO op_rett(void)
{
helper_rett();
FORCE_RET();
}
/* XXX: use another pointer for %iN registers to avoid slow wrapping
handling ? */
void OPPROTO op_save(void)
@ -1178,16 +892,6 @@ void OPPROTO op_wrtt(void)
env->tt[env->tl] = T0;
}
void OPPROTO op_rdpstate(void)
{
T0 = env->pstate;
}
void OPPROTO op_wrpstate(void)
{
do_wrpstate();
}
// CWP handling is reversed in V9, but we still use the V8 register
// order.
void OPPROTO op_rdcwp(void)
@ -1247,22 +951,6 @@ void OPPROTO op_exception(void)
FORCE_RET();
}
void OPPROTO op_trap_T0(void)
{
env->exception_index = TT_TRAP + (T0 & 0x7f);
cpu_loop_exit();
FORCE_RET();
}
void OPPROTO op_trapcc_T0(void)
{
if (T2) {
env->exception_index = TT_TRAP + (T0 & 0x7f);
cpu_loop_exit();
}
FORCE_RET();
}
void OPPROTO op_fpexception_im(void)
{
env->exception_index = TT_FP_EXCP;
@ -1272,11 +960,6 @@ void OPPROTO op_fpexception_im(void)
FORCE_RET();
}
void OPPROTO op_debug(void)
{
helper_debug();
}
void OPPROTO op_eval_ba(void)
{
T2 = 1;
@ -1499,33 +1182,8 @@ void OPPROTO op_eval_brgez(void)
{
T2 = ((int64_t)T0 >= 0);
}
void OPPROTO op_jmp_im64(void)
{
env->pc = PARAMQ1;
}
void OPPROTO op_movq_npc_im64(void)
{
env->npc = PARAMQ1;
}
#endif
void OPPROTO op_jmp_im(void)
{
env->pc = (uint32_t)PARAM1;
}
void OPPROTO op_movl_npc_im(void)
{
env->npc = (uint32_t)PARAM1;
}
void OPPROTO op_movl_npc_T0(void)
{
env->npc = T0;
}
void OPPROTO op_mov_pc_npc(void)
{
env->pc = env->npc;
@ -1556,11 +1214,6 @@ void OPPROTO op_jz_T2_label(void)
FORCE_RET();
}
void OPPROTO op_flush_T0(void)
{
helper_flush(T0);
}
void OPPROTO op_clear_ieee_excp_and_FTT(void)
{
env->fsr &= ~(FSR_FTT_MASK | FSR_CEXC_MASK);;
@ -1993,210 +1646,6 @@ void OPPROTO op_restored(void)
env->otherwin--;
FORCE_RET();
}
void OPPROTO op_popc(void)
{
do_popc();
}
void OPPROTO op_done(void)
{
do_done();
}
void OPPROTO op_retry(void)
{
do_retry();
}
void OPPROTO op_sir(void)
{
T0 = 0; // XXX
}
void OPPROTO op_ld_asi_reg()
{
T0 += PARAM1;
helper_ld_asi(env->asi, PARAM2, PARAM3);
}
void OPPROTO op_st_asi_reg()
{
T0 += PARAM1;
helper_st_asi(env->asi, PARAM2);
}
void OPPROTO op_ldf_asi_reg()
{
T0 += PARAM1;
helper_ldf_asi(env->asi, PARAM2, PARAM3);
}
void OPPROTO op_stf_asi_reg()
{
T0 += PARAM1;
helper_stf_asi(env->asi, PARAM2, PARAM3);
}
void OPPROTO op_ldf_asi()
{
helper_ldf_asi(PARAM1, PARAM2, PARAM3);
}
void OPPROTO op_stf_asi()
{
helper_stf_asi(PARAM1, PARAM2, PARAM3);
}
void OPPROTO op_ldstub_asi_reg() /* XXX: should be atomically */
{
target_ulong tmp;
T0 += PARAM1;
helper_ld_asi(env->asi, 1, 0);
tmp = T1;
T1 = 0xff;
helper_st_asi(env->asi, 1);
T1 = tmp;
}
void OPPROTO op_swap_asi_reg() /* XXX: should be atomically */
{
target_ulong tmp1, tmp2;
T0 += PARAM1;
tmp1 = T1;
helper_ld_asi(env->asi, 4, 0);
tmp2 = T1;
T1 = tmp1;
helper_st_asi(env->asi, 4);
T1 = tmp2;
}
void OPPROTO op_ldda_asi()
{
helper_ld_asi(PARAM1, 8, 0);
T0 = T1 & 0xffffffffUL;
T1 >>= 32;
}
void OPPROTO op_ldda_asi_reg()
{
T0 += PARAM1;
helper_ld_asi(env->asi, 8, 0);
T0 = T1 & 0xffffffffUL;
T1 >>= 32;
}
void OPPROTO op_stda_asi()
{
T1 <<= 32;
T1 += T2 & 0xffffffffUL;
helper_st_asi(PARAM1, 8);
}
void OPPROTO op_stda_asi_reg()
{
T0 += PARAM1;
T1 <<= 32;
T1 += T2 & 0xffffffffUL;
helper_st_asi(env->asi, 8);
}
void OPPROTO op_cas_asi() /* XXX: should be atomically */
{
target_ulong tmp;
tmp = T1 & 0xffffffffUL;
helper_ld_asi(PARAM1, 4, 0);
if (tmp == T1) {
tmp = T1;
T1 = T2 & 0xffffffffUL;
helper_st_asi(PARAM1, 4);
T1 = tmp;
}
T1 &= 0xffffffffUL;
}
void OPPROTO op_cas_asi_reg() /* XXX: should be atomically */
{
target_ulong tmp;
T0 += PARAM1;
tmp = T1 & 0xffffffffUL;
helper_ld_asi(env->asi, 4, 0);
if (tmp == T1) {
tmp = T1;
T1 = T2 & 0xffffffffUL;
helper_st_asi(env->asi, 4);
T1 = tmp;
}
T1 &= 0xffffffffUL;
}
void OPPROTO op_casx_asi() /* XXX: should be atomically */
{
target_ulong tmp;
tmp = T1;
helper_ld_asi(PARAM1, 8, 0);
if (tmp == T1) {
tmp = T1;
T1 = T2;
helper_st_asi(PARAM1, 8);
T1 = tmp;
}
}
void OPPROTO op_casx_asi_reg() /* XXX: should be atomically */
{
target_ulong tmp;
T0 += PARAM1;
tmp = T1;
helper_ld_asi(env->asi, 8, 0);
if (tmp == T1) {
tmp = T1;
T1 = T2;
helper_st_asi(env->asi, 8);
T1 = tmp;
}
}
#endif
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
void OPPROTO op_ld_asi()
{
helper_ld_asi(PARAM1, PARAM2, PARAM3);
}
void OPPROTO op_st_asi()
{
helper_st_asi(PARAM1, PARAM2);
}
void OPPROTO op_ldstub_asi() /* XXX: should be atomically */
{
target_ulong tmp;
helper_ld_asi(PARAM1, 1, 0);
tmp = T1;
T1 = 0xff;
helper_st_asi(PARAM1, 1);
T1 = tmp;
}
void OPPROTO op_swap_asi() /* XXX: should be atomically */
{
target_ulong tmp1, tmp2;
tmp1 = T1;
helper_ld_asi(PARAM1, 4, 0);
tmp2 = T1;
T1 = tmp1;
helper_st_asi(PARAM1, 4);
T1 = tmp2;
}
#endif
#ifdef TARGET_SPARC64

File diff suppressed because it is too large Load Diff

View File

@ -4,65 +4,6 @@
#define ADDR(x) (x)
#endif
/*** Integer load ***/
#define SPARC_LD_OP(name, qp) \
void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
{ \
T1 = (target_ulong)glue(qp, MEMSUFFIX)(ADDR(T0)); \
}
#define SPARC_LD_OP_S(name, qp) \
void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
{ \
T1 = (target_long)glue(qp, MEMSUFFIX)(ADDR(T0)); \
}
#define SPARC_ST_OP(name, op) \
void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
{ \
glue(op, MEMSUFFIX)(ADDR(T0), T1); \
}
SPARC_LD_OP(ld, ldl);
SPARC_LD_OP(ldub, ldub);
SPARC_LD_OP(lduh, lduw);
SPARC_LD_OP_S(ldsb, ldsb);
SPARC_LD_OP_S(ldsh, ldsw);
/*** Integer store ***/
SPARC_ST_OP(st, stl);
SPARC_ST_OP(stb, stb);
SPARC_ST_OP(sth, stw);
void OPPROTO glue(op_std, MEMSUFFIX)(void)
{
uint64_t tmp = ((uint64_t)T1 << 32) | (uint64_t)(T2 & 0xffffffff);
glue(stq, MEMSUFFIX)(ADDR(T0), tmp);
}
void OPPROTO glue(op_ldstub, MEMSUFFIX)(void)
{
T1 = glue(ldub, MEMSUFFIX)(ADDR(T0));
glue(stb, MEMSUFFIX)(ADDR(T0), 0xff); /* XXX: Should be Atomically */
}
void OPPROTO glue(op_swap, MEMSUFFIX)(void)
{
target_ulong tmp = glue(ldl, MEMSUFFIX)(ADDR(T0));
glue(stl, MEMSUFFIX)(ADDR(T0), T1); /* XXX: Should be Atomically */
T1 = tmp;
}
void OPPROTO glue(op_ldd, MEMSUFFIX)(void)
{
uint64_t tmp;
tmp = glue(ldq, MEMSUFFIX)(ADDR(T0));
T1 = tmp >> 32;
T0 = tmp & 0xffffffff;
}
/*** Floating-point store ***/
void OPPROTO glue(op_stf, MEMSUFFIX) (void)
{
@ -107,18 +48,4 @@ void OPPROTO glue(op_stqf, MEMSUFFIX) (void)
}
#endif
#ifdef TARGET_SPARC64
void OPPROTO glue(op_lduw, MEMSUFFIX)(void)
{
T1 = (uint64_t)(glue(ldl, MEMSUFFIX)(ADDR(T0)) & 0xffffffff);
}
void OPPROTO glue(op_ldsw, MEMSUFFIX)(void)
{
T1 = (int64_t)(glue(ldl, MEMSUFFIX)(ADDR(T0)) & 0xffffffff);
}
SPARC_LD_OP(ldx, ldq);
SPARC_ST_OP(stx, stq);
#endif
#undef MEMSUFFIX

View File

@ -1,48 +0,0 @@
/*
* SPARC micro operations (templates for various register related
* operations)
*
* Copyright (c) 2003 Fabrice Bellard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
void OPPROTO glue(op_movl_T0_, REGNAME)(void)
{
T0 = REG;
}
void OPPROTO glue(op_movl_T1_, REGNAME)(void)
{
T1 = REG;
}
void OPPROTO glue(op_movl_T2_, REGNAME)(void)
{
T2 = REG;
}
void OPPROTO glue(glue(op_movl_, REGNAME), _T0)(void)
{
REG = T0;
}
void OPPROTO glue(glue(op_movl_, REGNAME), _T1)(void)
{
REG = T1;
}
#undef REG
#undef REGNAME

File diff suppressed because it is too large Load Diff