Skip to content

Commit

Permalink
Support for VR5432, and some of its special instructions. Original patch
Browse files Browse the repository at this point in the history
by Dirk Behme.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3859 c046a42c-6fe2-441c-8c8c-71466251a162
  • Loading branch information
ths committed Dec 25, 2007
1 parent 29fe0e3 commit e9c71dd
Show file tree
Hide file tree
Showing 6 changed files with 405 additions and 7 deletions.
14 changes: 14 additions & 0 deletions target-mips/exec.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,20 @@ void do_madd (void);
void do_maddu (void);
void do_msub (void);
void do_msubu (void);
void do_muls (void);
void do_mulsu (void);
void do_macc (void);
void do_macchi (void);
void do_maccu (void);
void do_macchiu (void);
void do_msac (void);
void do_msachi (void);
void do_msacu (void);
void do_msachiu (void);
void do_mulhi (void);
void do_mulhiu (void);
void do_mulshi (void);
void do_mulshiu (void);
#endif
#if defined(TARGET_MIPS64)
void do_ddiv (void);
Expand Down
14 changes: 9 additions & 5 deletions target-mips/mips-defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
/* If we want to use host float regs... */
//#define USE_HOST_FLOAT_REGS

/* real pages are variable size... */
/* Real pages are variable size... */
#define TARGET_PAGE_BITS 12
#define MIPS_TLB_MAX 128

Expand All @@ -29,7 +29,7 @@
#define ISA_MIPS64 0x00000080
#define ISA_MIPS64R2 0x00000100

/* MIPS ASE */
/* MIPS ASEs. */
#define ASE_MIPS16 0x00001000
#define ASE_MIPS3D 0x00002000
#define ASE_MDMX 0x00004000
Expand All @@ -38,19 +38,23 @@
#define ASE_MT 0x00020000
#define ASE_SMARTMIPS 0x00040000

/* Chip specific instructions. */
/* Currently void */
/* Chip specific instructions. */
#define INSN_VR54XX 0x80000000

/* MIPS CPU defines. */
/* MIPS CPU defines. */
#define CPU_MIPS1 (ISA_MIPS1)
#define CPU_MIPS2 (CPU_MIPS1 | ISA_MIPS2)
#define CPU_MIPS3 (CPU_MIPS2 | ISA_MIPS3)
#define CPU_MIPS4 (CPU_MIPS3 | ISA_MIPS4)
#define CPU_VR54XX (CPU_MIPS4 | INSN_VR54XX)

#define CPU_MIPS5 (CPU_MIPS4 | ISA_MIPS5)

/* MIPS Technologies "Release 1" */
#define CPU_MIPS32 (CPU_MIPS2 | ISA_MIPS32)
#define CPU_MIPS64 (CPU_MIPS5 | CPU_MIPS32 | ISA_MIPS64)

/* MIPS Technologies "Release 2" */
#define CPU_MIPS32R2 (CPU_MIPS32 | ISA_MIPS32R2)
#define CPU_MIPS64R2 (CPU_MIPS64 | CPU_MIPS32R2 | ISA_MIPS64R2)

Expand Down
182 changes: 182 additions & 0 deletions target-mips/op.c
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,90 @@ void op_msubu (void)
FORCE_RET();
}

/* Multiplication variants of the vr54xx. */
void op_muls (void)
{
CALL_FROM_TB0(do_muls);
FORCE_RET();
}

void op_mulsu (void)
{
CALL_FROM_TB0(do_mulsu);
FORCE_RET();
}

void op_macc (void)
{
CALL_FROM_TB0(do_macc);
FORCE_RET();
}

void op_macchi (void)
{
CALL_FROM_TB0(do_macchi);
FORCE_RET();
}

void op_maccu (void)
{
CALL_FROM_TB0(do_maccu);
FORCE_RET();
}
void op_macchiu (void)
{
CALL_FROM_TB0(do_macchiu);
FORCE_RET();
}

void op_msac (void)
{
CALL_FROM_TB0(do_msac);
FORCE_RET();
}

void op_msachi (void)
{
CALL_FROM_TB0(do_msachi);
FORCE_RET();
}

void op_msacu (void)
{
CALL_FROM_TB0(do_msacu);
FORCE_RET();
}

void op_msachiu (void)
{
CALL_FROM_TB0(do_msachiu);
FORCE_RET();
}

void op_mulhi (void)
{
CALL_FROM_TB0(do_mulhi);
FORCE_RET();
}

void op_mulhiu (void)
{
CALL_FROM_TB0(do_mulhiu);
FORCE_RET();
}

void op_mulshi (void)
{
CALL_FROM_TB0(do_mulshi);
FORCE_RET();
}

void op_mulshiu (void)
{
CALL_FROM_TB0(do_mulshiu);
FORCE_RET();
}

#else /* TARGET_LONG_BITS > HOST_LONG_BITS */

static always_inline uint64_t get_HILO (void)
Expand All @@ -795,6 +879,18 @@ static always_inline void set_HILO (uint64_t HILO)
env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
}

static always_inline void set_HIT0_LO (uint64_t HILO)
{
env->LO[0][env->current_tc] = (int32_t)(HILO & 0xFFFFFFFF);
T0 = env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
}

static always_inline void set_HI_LOT0 (uint64_t HILO)
{
T0 = env->LO[0][env->current_tc] = (int32_t)(HILO & 0xFFFFFFFF);
env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
}

void op_mult (void)
{
set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
Expand Down Expand Up @@ -842,6 +938,92 @@ void op_msubu (void)
set_HILO(get_HILO() - tmp);
FORCE_RET();
}

/* Multiplication variants of the vr54xx. */
void op_muls (void)
{
set_HI_LOT0(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
FORCE_RET();
}

void op_mulsu (void)
{
set_HI_LOT0(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
FORCE_RET();
}

void op_macc (void)
{
set_HI_LOT0(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
FORCE_RET();
}

void op_macchi (void)
{
set_HIT0_LO(get_HILO() + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
FORCE_RET();
}

void op_maccu (void)
{
set_HI_LOT0(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
FORCE_RET();
}

void op_macchiu (void)
{
set_HIT0_LO(get_HILO() + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
FORCE_RET();
}

void op_msac (void)
{
set_HI_LOT0(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
FORCE_RET();
}

void op_msachi (void)
{
set_HIT0_LO(get_HILO() - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
FORCE_RET();
}

void op_msacu (void)
{
set_HI_LOT0(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
FORCE_RET();
}

void op_msachiu (void)
{
set_HIT0_LO(get_HILO() - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
FORCE_RET();
}

void op_mulhi (void)
{
set_HIT0_LO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
FORCE_RET();
}

void op_mulhiu (void)
{
set_HIT0_LO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
FORCE_RET();
}

void op_mulshi (void)
{
set_HIT0_LO(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
FORCE_RET();
}

void op_mulshiu (void)
{
set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
FORCE_RET();
}

#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */

#if defined(TARGET_MIPS64)
Expand Down
85 changes: 84 additions & 1 deletion target-mips/op_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,18 @@ static always_inline void set_HILO (uint64_t HILO)
env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
}

static always_inline void set_HIT0_LO (uint64_t HILO)
{
env->LO[0][env->current_tc] = (int32_t)(HILO & 0xFFFFFFFF);
T0 = env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
}

static always_inline void set_HI_LOT0 (uint64_t HILO)
{
T0 = env->LO[0][env->current_tc] = (int32_t)(HILO & 0xFFFFFFFF);
env->HI[0][env->current_tc] = (int32_t)(HILO >> 32);
}

void do_mult (void)
{
set_HILO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
Expand Down Expand Up @@ -213,7 +225,78 @@ void do_msubu (void)
tmp = ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
set_HILO(get_HILO() - tmp);
}
#endif

/* Multiplication variants of the vr54xx. */
void do_muls (void)
{
set_HI_LOT0(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
}

void do_mulsu (void)
{
set_HI_LOT0(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
}

void do_macc (void)
{
set_HI_LOT0(((int64_t)get_HILO()) + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
}

void do_macchi (void)
{
set_HIT0_LO(((int64_t)get_HILO()) + ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
}

void do_maccu (void)
{
set_HI_LOT0(((uint64_t)get_HILO()) + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
}

void do_macchiu (void)
{
set_HIT0_LO(((uint64_t)get_HILO()) + ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
}

void do_msac (void)
{
set_HI_LOT0(((int64_t)get_HILO()) - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
}

void do_msachi (void)
{
set_HIT0_LO(((int64_t)get_HILO()) - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
}

void do_msacu (void)
{
set_HI_LOT0(((uint64_t)get_HILO()) - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
}

void do_msachiu (void)
{
set_HIT0_LO(((uint64_t)get_HILO()) - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
}

void do_mulhi (void)
{
set_HIT0_LO((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1);
}

void do_mulhiu (void)
{
set_HIT0_LO((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1);
}

void do_mulshi (void)
{
set_HIT0_LO(0 - ((int64_t)(int32_t)T0 * (int64_t)(int32_t)T1));
}

void do_mulshiu (void)
{
set_HIT0_LO(0 - ((uint64_t)(uint32_t)T0 * (uint64_t)(uint32_t)T1));
}
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */

#if HOST_LONG_BITS < 64
void do_div (void)
Expand Down
Loading

0 comments on commit e9c71dd

Please sign in to comment.