suppressed use of gen_multi - use intermediate FT0 register for floats - use T0 temporary for fpscr update - use PARAM1 for spr access - added untested single load/store support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@473 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									79aceca54a
								
							
						
					
					
						commit
						28b6751f30
					
				| 
						 | 
				
			
			@ -172,6 +172,7 @@ typedef struct CPUPPCState {
 | 
			
		|||
    uint32_t exception;
 | 
			
		||||
 | 
			
		||||
    /* qemu dedicated */
 | 
			
		||||
    uint64_t ft0; /* temporary float register */
 | 
			
		||||
    int interrupt_request;
 | 
			
		||||
    jmp_buf jmp_env;
 | 
			
		||||
    int exception_index;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										236
									
								
								target-ppc/op.c
								
								
								
								
							
							
						
						
									
										236
									
								
								target-ppc/op.c
								
								
								
								
							| 
						 | 
				
			
			@ -22,20 +22,110 @@
 | 
			
		|||
#include "exec.h"
 | 
			
		||||
 | 
			
		||||
#define regs (env)
 | 
			
		||||
extern uint32_t __a;
 | 
			
		||||
extern uint32_t __b;
 | 
			
		||||
extern uint32_t __c;
 | 
			
		||||
extern uint32_t __d;
 | 
			
		||||
extern uint32_t __e;
 | 
			
		||||
extern uint32_t __f;
 | 
			
		||||
#define Ts0 (int32_t)T0
 | 
			
		||||
#define Ts1 (int32_t)T1
 | 
			
		||||
#define Ts2 (int32_t)T2
 | 
			
		||||
 | 
			
		||||
#include "op-multi.c"
 | 
			
		||||
#define FT0 (env->ft0)
 | 
			
		||||
 | 
			
		||||
#define PPC_OP(name) void op_##name(void)
 | 
			
		||||
 | 
			
		||||
#define REG 0
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 1
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 2
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 3
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 4
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 5
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 6
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 7
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 8
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 9
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 10
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 11
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 12
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 13
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 14
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 15
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 16
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 17
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 18
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 19
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 20
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 21
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 22
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 23
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 24
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 25
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 26
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 27
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 28
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 29
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 30
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
#define REG 31
 | 
			
		||||
#include "op_template.h"
 | 
			
		||||
 | 
			
		||||
/* PPC state maintenance operations */
 | 
			
		||||
/* set_Rc0 */
 | 
			
		||||
PPC_OP(set_Rc0)
 | 
			
		||||
| 
						 | 
				
			
			@ -1114,3 +1204,135 @@ PPC_OP(stswx)
 | 
			
		|||
    do_stsw(PARAM(1), T0, T1 + T2);
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* SPR */
 | 
			
		||||
PPC_OP(load_spr)
 | 
			
		||||
{
 | 
			
		||||
    T0 = regs->spr[PARAM(1)];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PPC_OP(store_spr)
 | 
			
		||||
{
 | 
			
		||||
    regs->spr[PARAM(1)] = T0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* FPSCR */
 | 
			
		||||
PPC_OP(load_fpscr)
 | 
			
		||||
{
 | 
			
		||||
    T0 = do_load_fpscr();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PPC_OP(store_fpscr)
 | 
			
		||||
{
 | 
			
		||||
    do_store_fpscr(PARAM(1), T0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***                         Floating-point store                          ***/
 | 
			
		||||
 | 
			
		||||
static inline uint32_t dtos(uint64_t f)
 | 
			
		||||
{
 | 
			
		||||
    unsigned int e, m, s;
 | 
			
		||||
    e = (((f >> 52) & 0x7ff) - 1022) + 126;
 | 
			
		||||
    s = (f >> 63);
 | 
			
		||||
    m = (f >> 29);
 | 
			
		||||
    return (s << 31) | (e << 23) | m;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline uint64_t stod(uint32_t f)
 | 
			
		||||
{
 | 
			
		||||
    unsigned int e, m, s;
 | 
			
		||||
    e = ((f >> 23) & 0xff) - 126 + 1022;
 | 
			
		||||
    s = f >> 31;
 | 
			
		||||
    m = f & ((1 << 23) - 1);
 | 
			
		||||
    return ((uint64_t)s << 63) | ((uint64_t)e << 52) | ((uint64_t)m << 29);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PPC_OP(stfd_z_FT0)
 | 
			
		||||
{
 | 
			
		||||
    st64(SPARAM(1), FT0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PPC_OP(stfd_FT0)
 | 
			
		||||
{
 | 
			
		||||
    T0 += SPARAM(1);
 | 
			
		||||
    st64(T0, FT0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PPC_OP(stfdx_z_FT0)
 | 
			
		||||
{
 | 
			
		||||
    st64(T0, FT0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PPC_OP(stfdx_FT0)
 | 
			
		||||
{
 | 
			
		||||
    T0 += T1;
 | 
			
		||||
    st64(T0, FT0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
PPC_OP(stfs_z_FT0)
 | 
			
		||||
{
 | 
			
		||||
    st32(SPARAM(1), dtos(FT0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PPC_OP(stfs_FT0)
 | 
			
		||||
{
 | 
			
		||||
    T0 += SPARAM(1);
 | 
			
		||||
    st32(T0, dtos(FT0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PPC_OP(stfsx_z_FT0)
 | 
			
		||||
{
 | 
			
		||||
    st32(T0, dtos(FT0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PPC_OP(stfsx_FT0)
 | 
			
		||||
{
 | 
			
		||||
    T0 += T1;
 | 
			
		||||
    st32(T0, dtos(FT0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***                         Floating-point load                          ***/
 | 
			
		||||
PPC_OP(lfd_z_FT0)
 | 
			
		||||
{
 | 
			
		||||
    FT0 = ld64(SPARAM(1));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PPC_OP(lfd_FT0)
 | 
			
		||||
{
 | 
			
		||||
    T0 += SPARAM(1);
 | 
			
		||||
    FT0 = ld64(T0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PPC_OP(lfdx_z_FT0)
 | 
			
		||||
{
 | 
			
		||||
    FT0 = ld64(T0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PPC_OP(lfdx_FT0)
 | 
			
		||||
{
 | 
			
		||||
    T0 += T1;
 | 
			
		||||
    FT0 = ld64(T0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PPC_OP(lfs_z_FT0)
 | 
			
		||||
{
 | 
			
		||||
    FT0 = stod(ld32(SPARAM(1)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PPC_OP(lfs_FT0)
 | 
			
		||||
{
 | 
			
		||||
    T0 += SPARAM(1);
 | 
			
		||||
    FT0 = stod(ld32(T0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PPC_OP(lfsx_z_FT0)
 | 
			
		||||
{
 | 
			
		||||
    FT0 = stod(ld32(T0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PPC_OP(lfsx_FT0)
 | 
			
		||||
{
 | 
			
		||||
    T0 += T1;
 | 
			
		||||
    FT0 = stod(ld32(T0));
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,197 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 *  PPC emulation micro-operations for qemu.
 | 
			
		||||
 * 
 | 
			
		||||
 *  Copyright (c) 2003 Jocelyn Mayer
 | 
			
		||||
 *
 | 
			
		||||
 * 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
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Host registers definitions */
 | 
			
		||||
$DEFH T 3
 | 
			
		||||
/* PPC registers definitions */
 | 
			
		||||
$DEF gpr 32
 | 
			
		||||
$DEF fpr 32
 | 
			
		||||
$DEF crf 8
 | 
			
		||||
$DEF spr 1024
 | 
			
		||||
 | 
			
		||||
/* PPC registers <-> host registers move */
 | 
			
		||||
/* GPR */
 | 
			
		||||
$OP load_gpr_T0 gpr
 | 
			
		||||
{
 | 
			
		||||
    T0 = regs->gpra;
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
 | 
			
		||||
$OP load_gpr_T1 gpr
 | 
			
		||||
{
 | 
			
		||||
    T1 = regs->gpra;
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
 | 
			
		||||
$OP load_gpr_T2 gpr
 | 
			
		||||
{
 | 
			
		||||
    T2 = regs->gpra;
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
 | 
			
		||||
$OP store_T0_gpr gpr
 | 
			
		||||
{
 | 
			
		||||
    regs->gpra = T0;
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
 | 
			
		||||
$OP store_T1_gpr gpr
 | 
			
		||||
{
 | 
			
		||||
    regs->gpra = T1;
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
 | 
			
		||||
$OP store_gpr_P gpr PARAM
 | 
			
		||||
{
 | 
			
		||||
    regs->gpra = PARAM(1);
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
 | 
			
		||||
/* crf */
 | 
			
		||||
$OP load_crf_T0 crf
 | 
			
		||||
{
 | 
			
		||||
    T0 = regs->crfa;
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
 | 
			
		||||
$OP load_crf_T1 crf
 | 
			
		||||
{
 | 
			
		||||
    T1 = regs->crfa;
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
 | 
			
		||||
$OP store_T0_crf crf
 | 
			
		||||
{
 | 
			
		||||
    regs->crfa = T0;
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
 | 
			
		||||
$OP store_T1_crf crf
 | 
			
		||||
{
 | 
			
		||||
    regs->crfa = T1;
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
 | 
			
		||||
/* SPR */
 | 
			
		||||
$OP load_spr spr
 | 
			
		||||
{
 | 
			
		||||
    T0 = regs->spra;
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
 | 
			
		||||
$OP store_spr spr
 | 
			
		||||
{
 | 
			
		||||
    regs->spra = T0;
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
 | 
			
		||||
/* FPSCR */
 | 
			
		||||
$OP load_fpscr fpr
 | 
			
		||||
{
 | 
			
		||||
    regs->fpra = do_load_fpscr();
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
 | 
			
		||||
$OP store_fpscr fpr PARAM
 | 
			
		||||
{
 | 
			
		||||
    do_store_fpscr(PARAM(1), regs->fpra);
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
 | 
			
		||||
/***                         Floating-point store                          ***/
 | 
			
		||||
/* candidate for helper (too long on x86 host) */
 | 
			
		||||
$OP stfd_z fpr PARAM
 | 
			
		||||
{
 | 
			
		||||
    st64(SPARAM(1), regs->fpra);
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
 | 
			
		||||
/* candidate for helper (too long on x86 host) */
 | 
			
		||||
$OP stfd fpr PARAM
 | 
			
		||||
{
 | 
			
		||||
    T0 += SPARAM(1);
 | 
			
		||||
    st64(T0, regs->fpra);
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
 | 
			
		||||
/* candidate for helper (too long on x86 host) */
 | 
			
		||||
$OP stfdx_z fpr
 | 
			
		||||
{
 | 
			
		||||
    st64(T0, regs->fpra);
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
/* candidate for helper (too long on x86 host) */
 | 
			
		||||
$OP stfdx fpr
 | 
			
		||||
{
 | 
			
		||||
    T0 += T1;
 | 
			
		||||
    st64(T0, regs->fpra);
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
 | 
			
		||||
/* candidate for helper (too long on x86 host) */
 | 
			
		||||
$OP lfd_z fpr PARAM
 | 
			
		||||
{
 | 
			
		||||
    regs->fpra = ld64(SPARAM(1));
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
 | 
			
		||||
/* candidate for helper (too long) */
 | 
			
		||||
$OP lfd fpr PARAM
 | 
			
		||||
{
 | 
			
		||||
    T0 += SPARAM(1);
 | 
			
		||||
    regs->fpra = ld64(T0);
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
 | 
			
		||||
$OP lfdx_z fpr
 | 
			
		||||
{
 | 
			
		||||
    regs->fpra = ld64(T0);
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
 | 
			
		||||
$OP lfdx fpr
 | 
			
		||||
{
 | 
			
		||||
    T0 += T1;
 | 
			
		||||
    regs->fpra = ld64(T0);
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
$ENDOP
 | 
			
		||||
/*****************************************************************************/
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,87 @@
 | 
			
		|||
/*
 | 
			
		||||
 *  PPC emulation micro-operations for qemu.
 | 
			
		||||
 * 
 | 
			
		||||
 *  Copyright (c) 2003 Jocelyn Mayer
 | 
			
		||||
 *
 | 
			
		||||
 * 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_load_gpr_T0_gpr, REG)(void)
 | 
			
		||||
{
 | 
			
		||||
    T0 = regs->gpr[REG];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OPPROTO glue(op_load_gpr_T1_gpr, REG)(void)
 | 
			
		||||
{
 | 
			
		||||
    T1 = regs->gpr[REG];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OPPROTO glue(op_load_gpr_T2_gpr, REG)(void)
 | 
			
		||||
{
 | 
			
		||||
    T2 = regs->gpr[REG];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OPPROTO glue(op_store_T0_gpr_gpr, REG)(void)
 | 
			
		||||
{
 | 
			
		||||
    regs->gpr[REG] = T0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OPPROTO glue(op_store_T1_gpr_gpr, REG)(void)
 | 
			
		||||
{
 | 
			
		||||
    regs->gpr[REG] = T1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OPPROTO glue(op_store_T2_gpr_gpr, REG)(void)
 | 
			
		||||
{
 | 
			
		||||
    regs->gpr[REG] = T2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if REG <= 7
 | 
			
		||||
 | 
			
		||||
void OPPROTO glue(op_load_crf_T0_crf, REG)(void)
 | 
			
		||||
{
 | 
			
		||||
    T0 = regs->crf[REG];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OPPROTO glue(op_load_crf_T1_crf, REG)(void)
 | 
			
		||||
{
 | 
			
		||||
    T1 = regs->crf[REG];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OPPROTO glue(op_store_T0_crf_crf, REG)(void)
 | 
			
		||||
{
 | 
			
		||||
    regs->crf[REG] = T0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OPPROTO glue(op_store_T1_crf_crf, REG)(void)
 | 
			
		||||
{
 | 
			
		||||
    regs->crf[REG] = T1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* REG <= 7 */
 | 
			
		||||
 | 
			
		||||
/* float moves */
 | 
			
		||||
 | 
			
		||||
void OPPROTO glue(op_load_FT0_fpr, REG)(void)
 | 
			
		||||
{
 | 
			
		||||
    FT0 = env->fpr[REG];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OPPROTO glue(op_store_FT0_fpr, REG)(void)
 | 
			
		||||
{
 | 
			
		||||
    env->fpr[REG] = FT0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#undef REG
 | 
			
		||||
| 
						 | 
				
			
			@ -36,7 +36,50 @@ static uint16_t *gen_opc_ptr;
 | 
			
		|||
static uint32_t *gen_opparam_ptr;
 | 
			
		||||
 | 
			
		||||
#include "gen-op.h"
 | 
			
		||||
#include "select.h"
 | 
			
		||||
 | 
			
		||||
typedef void (GenOpFunc)(void);
 | 
			
		||||
 | 
			
		||||
#define GEN8(func, NAME) \
 | 
			
		||||
static GenOpFunc *NAME ## _table [8] = {\
 | 
			
		||||
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,\
 | 
			
		||||
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,\
 | 
			
		||||
};\
 | 
			
		||||
static inline void func(int n)\
 | 
			
		||||
{\
 | 
			
		||||
    NAME ## _table[n]();\
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define GEN32(func, NAME) \
 | 
			
		||||
static GenOpFunc *NAME ## _table [32] = {\
 | 
			
		||||
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,\
 | 
			
		||||
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,\
 | 
			
		||||
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,\
 | 
			
		||||
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,\
 | 
			
		||||
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,\
 | 
			
		||||
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,\
 | 
			
		||||
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,\
 | 
			
		||||
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,\
 | 
			
		||||
};\
 | 
			
		||||
static inline void func(int n)\
 | 
			
		||||
{\
 | 
			
		||||
    NAME ## _table[n]();\
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf)
 | 
			
		||||
GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf)
 | 
			
		||||
GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf)
 | 
			
		||||
GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf)
 | 
			
		||||
 | 
			
		||||
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr)
 | 
			
		||||
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr)
 | 
			
		||||
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr)
 | 
			
		||||
 | 
			
		||||
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr)
 | 
			
		||||
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr)
 | 
			
		||||
GEN32(gen_op_store_T2_gpr, gen_op_store_T2_gpr_gpr)
 | 
			
		||||
 | 
			
		||||
GEN32(gen_op_load_FT0_fpr, gen_op_load_FT0_fpr)
 | 
			
		||||
GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr)
 | 
			
		||||
 | 
			
		||||
static uint8_t  spr_access[1024 / 2];
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -810,7 +853,8 @@ GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
 | 
			
		|||
/* mffs */
 | 
			
		||||
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
 | 
			
		||||
{
 | 
			
		||||
    gen_op_load_fpscr(rD(ctx->opcode));
 | 
			
		||||
    gen_op_load_fpscr();
 | 
			
		||||
    gen_op_store_T0_gpr(rD(ctx->opcode));
 | 
			
		||||
    if (Rc(ctx->opcode)) {
 | 
			
		||||
        /* Update CR1 */
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -832,7 +876,8 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
 | 
			
		|||
/* mtfsf */
 | 
			
		||||
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
 | 
			
		||||
{
 | 
			
		||||
    gen_op_store_fpscr(FM(ctx->opcode), rB(ctx->opcode));
 | 
			
		||||
    gen_op_load_gpr_T0(rB(ctx->opcode));
 | 
			
		||||
    gen_op_store_fpscr(FM(ctx->opcode));
 | 
			
		||||
    if (Rc(ctx->opcode)) {
 | 
			
		||||
        /* Update CR1 */
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1182,11 +1227,12 @@ GEN_HANDLER(lf##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)                \
 | 
			
		|||
{                                                                             \
 | 
			
		||||
    uint32_t simm = SIMM(ctx->opcode);                                        \
 | 
			
		||||
    if (rA(ctx->opcode) == 0) {                                               \
 | 
			
		||||
        gen_op_lf##width##_z(simm, rD(ctx->opcode));                          \
 | 
			
		||||
        gen_op_lf##width##_z_FT0(simm);                          \
 | 
			
		||||
    } else {                                                                  \
 | 
			
		||||
        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
 | 
			
		||||
        gen_op_lf##width(simm, rD(ctx->opcode));                              \
 | 
			
		||||
        gen_op_lf##width##_FT0(simm);                              \
 | 
			
		||||
    }                                                                         \
 | 
			
		||||
    gen_op_store_FT0_fpr(rD(ctx->opcode));\
 | 
			
		||||
    SET_RETVAL(0);                                                            \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1197,7 +1243,8 @@ GEN_HANDLER(lf##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)             \
 | 
			
		|||
        rA(ctx->opcode) == rD(ctx->opcode))                                   \
 | 
			
		||||
        SET_RETVAL(EXCP_INVAL);                                               \
 | 
			
		||||
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
 | 
			
		||||
    gen_op_lf##width(SIMM(ctx->opcode), rD(ctx->opcode));                     \
 | 
			
		||||
    gen_op_lf##width##_FT0(SIMM(ctx->opcode));                     \
 | 
			
		||||
    gen_op_store_FT0_fpr(rD(ctx->opcode));\
 | 
			
		||||
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
 | 
			
		||||
    SET_RETVAL(0);                                                            \
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1210,7 +1257,8 @@ GEN_HANDLER(lf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)            \
 | 
			
		|||
        SET_RETVAL(EXCP_INVAL);                                               \
 | 
			
		||||
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
 | 
			
		||||
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
 | 
			
		||||
    gen_op_lf##width##x(rD(ctx->opcode));                                     \
 | 
			
		||||
    gen_op_lf##width##x_FT0();                                     \
 | 
			
		||||
    gen_op_store_FT0_fpr(rD(ctx->opcode));\
 | 
			
		||||
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
 | 
			
		||||
    SET_RETVAL(0);                                                            \
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1220,12 +1268,13 @@ GEN_HANDLER(lf##width##x, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)             \
 | 
			
		|||
{                                                                             \
 | 
			
		||||
    if (rA(ctx->opcode) == 0) {                                               \
 | 
			
		||||
        gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
 | 
			
		||||
        gen_op_lf##width##x_z(rD(ctx->opcode));                               \
 | 
			
		||||
        gen_op_lf##width##x_z_FT0();                               \
 | 
			
		||||
    } else {                                                                  \
 | 
			
		||||
        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
 | 
			
		||||
        gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
 | 
			
		||||
        gen_op_lf##width##x(rD(ctx->opcode));                                 \
 | 
			
		||||
        gen_op_lf##width##x_FT0();                                 \
 | 
			
		||||
    }                                                                         \
 | 
			
		||||
    gen_op_store_FT0_fpr(rD(ctx->opcode));\
 | 
			
		||||
    SET_RETVAL(0);                                                            \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1238,10 +1287,6 @@ GEN_LFX(width, opc | 0x00)
 | 
			
		|||
/* lfd lfdu lfdux lfdx */
 | 
			
		||||
GEN_LDF(d, 0x12);
 | 
			
		||||
/* lfs lfsu lfsux lfsx */
 | 
			
		||||
#define gen_op_lfs_z(a, b)
 | 
			
		||||
#define gen_op_lfs(a, b)
 | 
			
		||||
#define gen_op_lfsx_z(a)
 | 
			
		||||
#define gen_op_lfsx(a)
 | 
			
		||||
GEN_LDF(s, 0x10);
 | 
			
		||||
 | 
			
		||||
/***                         Floating-point store                          ***/
 | 
			
		||||
| 
						 | 
				
			
			@ -1249,11 +1294,12 @@ GEN_LDF(s, 0x10);
 | 
			
		|||
GEN_HANDLER(stf##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)               \
 | 
			
		||||
{                                                                             \
 | 
			
		||||
    uint32_t simm = SIMM(ctx->opcode);                                        \
 | 
			
		||||
    gen_op_load_FT0_fpr(rS(ctx->opcode));\
 | 
			
		||||
    if (rA(ctx->opcode) == 0) {                                               \
 | 
			
		||||
        gen_op_stf##width##_z(simm, rS(ctx->opcode));                         \
 | 
			
		||||
        gen_op_stf##width##_z_FT0(simm);                         \
 | 
			
		||||
    } else {                                                                  \
 | 
			
		||||
        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
 | 
			
		||||
        gen_op_stf##width(simm, rS(ctx->opcode));                             \
 | 
			
		||||
        gen_op_stf##width##_FT0(simm);                             \
 | 
			
		||||
    }                                                                         \
 | 
			
		||||
    SET_RETVAL(0);                                                            \
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1264,7 +1310,8 @@ GEN_HANDLER(stf##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT)            \
 | 
			
		|||
    if (rA(ctx->opcode) == 0)                                                 \
 | 
			
		||||
        SET_RETVAL(EXCP_INVAL);                                               \
 | 
			
		||||
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
 | 
			
		||||
    gen_op_stf##width(SIMM(ctx->opcode), rS(ctx->opcode));                    \
 | 
			
		||||
    gen_op_load_FT0_fpr(rS(ctx->opcode));\
 | 
			
		||||
    gen_op_stf##width##_FT0(SIMM(ctx->opcode));                    \
 | 
			
		||||
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
 | 
			
		||||
    SET_RETVAL(0);                                                            \
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1276,7 +1323,8 @@ GEN_HANDLER(stf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)           \
 | 
			
		|||
        SET_RETVAL(EXCP_INVAL);                                               \
 | 
			
		||||
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
 | 
			
		||||
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
 | 
			
		||||
    gen_op_stf##width##x(rS(ctx->opcode));                                    \
 | 
			
		||||
    gen_op_load_FT0_fpr(rS(ctx->opcode));\
 | 
			
		||||
    gen_op_stf##width##x_FT0();                                    \
 | 
			
		||||
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
 | 
			
		||||
    SET_RETVAL(0);                                                            \
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1284,13 +1332,14 @@ GEN_HANDLER(stf##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)           \
 | 
			
		|||
#define GEN_STFX(width, opc)                                                  \
 | 
			
		||||
GEN_HANDLER(stf##width##x, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT)            \
 | 
			
		||||
{                                                                             \
 | 
			
		||||
    gen_op_load_FT0_fpr(rS(ctx->opcode));\
 | 
			
		||||
    if (rA(ctx->opcode) == 0) {                                               \
 | 
			
		||||
        gen_op_load_gpr_T0(rB(ctx->opcode));                                  \
 | 
			
		||||
        gen_op_stf##width##x_z(rS(ctx->opcode));                              \
 | 
			
		||||
        gen_op_stf##width##x_z_FT0();                              \
 | 
			
		||||
    } else {                                                                  \
 | 
			
		||||
        gen_op_load_gpr_T0(rA(ctx->opcode));                                  \
 | 
			
		||||
        gen_op_load_gpr_T1(rB(ctx->opcode));                                  \
 | 
			
		||||
        gen_op_stf##width##x(rS(ctx->opcode));                                \
 | 
			
		||||
        gen_op_stf##width##x_FT0();                                \
 | 
			
		||||
    }                                                                         \
 | 
			
		||||
    SET_RETVAL(0);                                                            \
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1304,10 +1353,6 @@ GEN_STFX(width, opc | 0x00)
 | 
			
		|||
/* stfd stfdu stfdux stfdx */
 | 
			
		||||
GEN_STOF(d, 0x16);
 | 
			
		||||
/* stfs stfsu stfsux stfsx */
 | 
			
		||||
#define gen_op_stfs_z(a, b)
 | 
			
		||||
#define gen_op_stfs(a, b)
 | 
			
		||||
#define gen_op_stfsx_z(a)
 | 
			
		||||
#define gen_op_stfsx(a)
 | 
			
		||||
GEN_STOF(s, 0x14);
 | 
			
		||||
 | 
			
		||||
/* Optional: */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue