target-ppc: convert POWER2 load/store instructions to TCG
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5805 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									6a6ae23f3c
								
							
						
					
					
						commit
						01a4afeb99
					
				@ -561,9 +561,6 @@ struct CPUPPCState {
 | 
			
		||||
    target_ulong tgpr[4]; /* Used to speed-up TLB assist handlers */
 | 
			
		||||
 | 
			
		||||
    /* Floating point execution context */
 | 
			
		||||
    /* temporary float registers */
 | 
			
		||||
    float64 ft0;
 | 
			
		||||
    float64 ft1;
 | 
			
		||||
    float_status fp_status;
 | 
			
		||||
    /* floating point registers */
 | 
			
		||||
    float64 fpr[32];
 | 
			
		||||
 | 
			
		||||
@ -45,9 +45,6 @@ register target_ulong T2 asm(AREG3);
 | 
			
		||||
#define TDX "%016lx"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define FT0 (env->ft0)
 | 
			
		||||
#define FT1 (env->ft1)
 | 
			
		||||
 | 
			
		||||
#if defined (DEBUG_OP)
 | 
			
		||||
# define RETURN() __asm__ __volatile__("nop" : : : "memory");
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
@ -309,48 +309,4 @@ void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb)
 | 
			
		||||
    T0 = i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* XXX: TAGs are not managed */
 | 
			
		||||
void glue(do_POWER2_lfq, MEMSUFFIX) (void)
 | 
			
		||||
{
 | 
			
		||||
    FT0 = glue(ldfq, MEMSUFFIX)((uint32_t)T0);
 | 
			
		||||
    FT1 = glue(ldfq, MEMSUFFIX)((uint32_t)(T0 + 4));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static always_inline float64 glue(ldfqr, MEMSUFFIX) (target_ulong EA)
 | 
			
		||||
{
 | 
			
		||||
    CPU_DoubleU u;
 | 
			
		||||
 | 
			
		||||
    u.d = glue(ldfq, MEMSUFFIX)(EA);
 | 
			
		||||
    u.ll = bswap64(u.ll);
 | 
			
		||||
 | 
			
		||||
    return u.d;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void glue(do_POWER2_lfq_le, MEMSUFFIX) (void)
 | 
			
		||||
{
 | 
			
		||||
    FT0 = glue(ldfqr, MEMSUFFIX)((uint32_t)(T0 + 4));
 | 
			
		||||
    FT1 = glue(ldfqr, MEMSUFFIX)((uint32_t)T0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void glue(do_POWER2_stfq, MEMSUFFIX) (void)
 | 
			
		||||
{
 | 
			
		||||
    glue(stfq, MEMSUFFIX)((uint32_t)T0, FT0);
 | 
			
		||||
    glue(stfq, MEMSUFFIX)((uint32_t)(T0 + 4), FT1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static always_inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, float64 d)
 | 
			
		||||
{
 | 
			
		||||
    CPU_DoubleU u;
 | 
			
		||||
 | 
			
		||||
    u.d = d;
 | 
			
		||||
    u.ll = bswap64(u.ll);
 | 
			
		||||
    glue(stfq, MEMSUFFIX)(EA, u.d);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void glue(do_POWER2_stfq_le, MEMSUFFIX) (void)
 | 
			
		||||
{
 | 
			
		||||
    glue(stfqr, MEMSUFFIX)((uint32_t)(T0 + 4), FT0);
 | 
			
		||||
    glue(stfqr, MEMSUFFIX)((uint32_t)T0, FT1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#undef MEMSUFFIX
 | 
			
		||||
 | 
			
		||||
@ -616,30 +616,4 @@ void OPPROTO glue(op_POWER_lscbx, MEMSUFFIX) (void)
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* POWER2 quad load and store */
 | 
			
		||||
/* XXX: TAGs are not managed */
 | 
			
		||||
void OPPROTO glue(op_POWER2_lfq, MEMSUFFIX) (void)
 | 
			
		||||
{
 | 
			
		||||
    glue(do_POWER2_lfq, MEMSUFFIX)();
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void glue(op_POWER2_lfq_le, MEMSUFFIX) (void)
 | 
			
		||||
{
 | 
			
		||||
    glue(do_POWER2_lfq_le, MEMSUFFIX)();
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OPPROTO glue(op_POWER2_stfq, MEMSUFFIX) (void)
 | 
			
		||||
{
 | 
			
		||||
    glue(do_POWER2_stfq, MEMSUFFIX)();
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OPPROTO glue(op_POWER2_stfq_le, MEMSUFFIX) (void)
 | 
			
		||||
{
 | 
			
		||||
    glue(do_POWER2_stfq_le, MEMSUFFIX)();
 | 
			
		||||
    RETURN();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#undef MEMSUFFIX
 | 
			
		||||
 | 
			
		||||
@ -71,7 +71,6 @@ static TCGv_i32 cpu_access_type;
 | 
			
		||||
 | 
			
		||||
/* dyngen register indexes */
 | 
			
		||||
static TCGv cpu_T[3];
 | 
			
		||||
static TCGv_i64 cpu_FT[2];
 | 
			
		||||
 | 
			
		||||
#include "gen-icount.h"
 | 
			
		||||
 | 
			
		||||
@ -103,11 +102,6 @@ void ppc_translate_init(void)
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    cpu_FT[0] = tcg_global_mem_new_i64(TCG_AREG0,
 | 
			
		||||
                                       offsetof(CPUState, ft0), "FT0");
 | 
			
		||||
    cpu_FT[1] = tcg_global_mem_new_i64(TCG_AREG0,
 | 
			
		||||
                                       offsetof(CPUState, ft1), "FT1");
 | 
			
		||||
 | 
			
		||||
    p = cpu_reg_names;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < 8; i++) {
 | 
			
		||||
@ -5102,134 +5096,121 @@ GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
 | 
			
		||||
 | 
			
		||||
/* POWER2 specific instructions */
 | 
			
		||||
/* Quad manipulation (load/store two floats at a time) */
 | 
			
		||||
/* Original POWER2 is 32 bits only, define 64 bits ops as 32 bits ones */
 | 
			
		||||
#define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
 | 
			
		||||
#define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
 | 
			
		||||
#define gen_op_POWER2_lfq_64_raw        gen_op_POWER2_lfq_raw
 | 
			
		||||
#define gen_op_POWER2_lfq_64_user       gen_op_POWER2_lfq_user
 | 
			
		||||
#define gen_op_POWER2_lfq_64_kernel     gen_op_POWER2_lfq_kernel
 | 
			
		||||
#define gen_op_POWER2_lfq_64_hypv       gen_op_POWER2_lfq_hypv
 | 
			
		||||
#define gen_op_POWER2_lfq_le_64_raw     gen_op_POWER2_lfq_le_raw
 | 
			
		||||
#define gen_op_POWER2_lfq_le_64_user    gen_op_POWER2_lfq_le_user
 | 
			
		||||
#define gen_op_POWER2_lfq_le_64_kernel  gen_op_POWER2_lfq_le_kernel
 | 
			
		||||
#define gen_op_POWER2_lfq_le_64_hypv    gen_op_POWER2_lfq_le_hypv
 | 
			
		||||
#define gen_op_POWER2_stfq_64_raw       gen_op_POWER2_stfq_raw
 | 
			
		||||
#define gen_op_POWER2_stfq_64_user      gen_op_POWER2_stfq_user
 | 
			
		||||
#define gen_op_POWER2_stfq_64_kernel    gen_op_POWER2_stfq_kernel
 | 
			
		||||
#define gen_op_POWER2_stfq_64_hypv      gen_op_POWER2_stfq_hypv
 | 
			
		||||
#define gen_op_POWER2_stfq_le_64_raw    gen_op_POWER2_stfq_le_raw
 | 
			
		||||
#define gen_op_POWER2_stfq_le_64_user   gen_op_POWER2_stfq_le_user
 | 
			
		||||
#define gen_op_POWER2_stfq_le_64_kernel gen_op_POWER2_stfq_le_kernel
 | 
			
		||||
#define gen_op_POWER2_stfq_le_64_hypv   gen_op_POWER2_stfq_le_hypv
 | 
			
		||||
static GenOpFunc *gen_op_POWER2_lfq[NB_MEM_FUNCS] = {
 | 
			
		||||
    GEN_MEM_FUNCS(POWER2_lfq),
 | 
			
		||||
};
 | 
			
		||||
static GenOpFunc *gen_op_POWER2_stfq[NB_MEM_FUNCS] = {
 | 
			
		||||
    GEN_MEM_FUNCS(POWER2_stfq),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* lfq */
 | 
			
		||||
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
 | 
			
		||||
{
 | 
			
		||||
    /* NIP cannot be restored if the memory exception comes from an helper */
 | 
			
		||||
    gen_update_nip(ctx, ctx->nip - 4);
 | 
			
		||||
    gen_addr_imm_index(cpu_T[0], ctx, 0);
 | 
			
		||||
    op_POWER2_lfq();
 | 
			
		||||
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
 | 
			
		||||
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode) + 1], cpu_FT[1]);
 | 
			
		||||
    int rd = rD(ctx->opcode);
 | 
			
		||||
    TCGv t0 = tcg_temp_new();
 | 
			
		||||
    gen_addr_imm_index(t0, ctx, 0);
 | 
			
		||||
    gen_qemu_ld64(cpu_fpr[rd], t0, ctx->mem_idx);
 | 
			
		||||
    tcg_gen_addi_tl(t0, t0, 8);
 | 
			
		||||
    gen_qemu_ld64(cpu_fpr[(rd + 1) % 32], t0, ctx->mem_idx);
 | 
			
		||||
    tcg_temp_free(t0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* lfqu */
 | 
			
		||||
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
 | 
			
		||||
{
 | 
			
		||||
    int ra = rA(ctx->opcode);
 | 
			
		||||
 | 
			
		||||
    /* NIP cannot be restored if the memory exception comes from an helper */
 | 
			
		||||
    gen_update_nip(ctx, ctx->nip - 4);
 | 
			
		||||
    gen_addr_imm_index(cpu_T[0], ctx, 0);
 | 
			
		||||
    op_POWER2_lfq();
 | 
			
		||||
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
 | 
			
		||||
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode) + 1], cpu_FT[1]);
 | 
			
		||||
    int rd = rD(ctx->opcode);
 | 
			
		||||
    TCGv t0 = tcg_temp_new();
 | 
			
		||||
    TCGv t1 = tcg_temp_new();
 | 
			
		||||
    gen_addr_imm_index(t0, ctx, 0);
 | 
			
		||||
    gen_qemu_ld64(cpu_fpr[rd], t0, ctx->mem_idx);
 | 
			
		||||
    tcg_gen_addi_tl(t1, t0, 8);
 | 
			
		||||
    gen_qemu_ld64(cpu_fpr[(rd + 1) % 32], t1, ctx->mem_idx);
 | 
			
		||||
    if (ra != 0)
 | 
			
		||||
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
 | 
			
		||||
        tcg_gen_mov_tl(cpu_gpr[ra], t0);
 | 
			
		||||
    tcg_temp_free(t0);
 | 
			
		||||
    tcg_temp_free(t1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* lfqux */
 | 
			
		||||
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
 | 
			
		||||
{
 | 
			
		||||
    int ra = rA(ctx->opcode);
 | 
			
		||||
 | 
			
		||||
    /* NIP cannot be restored if the memory exception comes from an helper */
 | 
			
		||||
    gen_update_nip(ctx, ctx->nip - 4);
 | 
			
		||||
    gen_addr_reg_index(cpu_T[0], ctx);
 | 
			
		||||
    op_POWER2_lfq();
 | 
			
		||||
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
 | 
			
		||||
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode) + 1], cpu_FT[1]);
 | 
			
		||||
    int rd = rD(ctx->opcode);
 | 
			
		||||
    TCGv t0 = tcg_temp_new();
 | 
			
		||||
    TCGv t1 = tcg_temp_new();
 | 
			
		||||
    gen_addr_reg_index(t0, ctx);
 | 
			
		||||
    gen_qemu_ld64(cpu_fpr[rd], t0, ctx->mem_idx);
 | 
			
		||||
    tcg_gen_addi_tl(t1, t0, 8);
 | 
			
		||||
    gen_qemu_ld64(cpu_fpr[(rd + 1) % 32], t1, ctx->mem_idx);
 | 
			
		||||
    if (ra != 0)
 | 
			
		||||
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
 | 
			
		||||
        tcg_gen_mov_tl(cpu_gpr[ra], t0);
 | 
			
		||||
    tcg_temp_free(t0);
 | 
			
		||||
    tcg_temp_free(t1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* lfqx */
 | 
			
		||||
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
 | 
			
		||||
{
 | 
			
		||||
    /* NIP cannot be restored if the memory exception comes from an helper */
 | 
			
		||||
    gen_update_nip(ctx, ctx->nip - 4);
 | 
			
		||||
    gen_addr_reg_index(cpu_T[0], ctx);
 | 
			
		||||
    op_POWER2_lfq();
 | 
			
		||||
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_FT[0]);
 | 
			
		||||
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode) + 1], cpu_FT[1]);
 | 
			
		||||
    int rd = rD(ctx->opcode);
 | 
			
		||||
    TCGv t0 = tcg_temp_new();
 | 
			
		||||
    gen_addr_reg_index(t0, ctx);
 | 
			
		||||
    gen_qemu_ld64(cpu_fpr[rd], t0, ctx->mem_idx);
 | 
			
		||||
    tcg_gen_addi_tl(t0, t0, 8);
 | 
			
		||||
    gen_qemu_ld64(cpu_fpr[(rd + 1) % 32], t0, ctx->mem_idx);
 | 
			
		||||
    tcg_temp_free(t0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* stfq */
 | 
			
		||||
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
 | 
			
		||||
{
 | 
			
		||||
    /* NIP cannot be restored if the memory exception comes from an helper */
 | 
			
		||||
    gen_update_nip(ctx, ctx->nip - 4);
 | 
			
		||||
    gen_addr_imm_index(cpu_T[0], ctx, 0);
 | 
			
		||||
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);
 | 
			
		||||
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rS(ctx->opcode) + 1]);
 | 
			
		||||
    op_POWER2_stfq();
 | 
			
		||||
    int rd = rD(ctx->opcode);
 | 
			
		||||
    TCGv t0 = tcg_temp_new();
 | 
			
		||||
    gen_addr_imm_index(t0, ctx, 0);
 | 
			
		||||
    gen_qemu_st64(cpu_fpr[rd], t0, ctx->mem_idx);
 | 
			
		||||
    tcg_gen_addi_tl(t0, t0, 8);
 | 
			
		||||
    gen_qemu_st64(cpu_fpr[(rd + 1) % 32], t0, ctx->mem_idx);
 | 
			
		||||
    tcg_temp_free(t0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* stfqu */
 | 
			
		||||
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
 | 
			
		||||
{
 | 
			
		||||
    int ra = rA(ctx->opcode);
 | 
			
		||||
 | 
			
		||||
    /* NIP cannot be restored if the memory exception comes from an helper */
 | 
			
		||||
    gen_update_nip(ctx, ctx->nip - 4);
 | 
			
		||||
    gen_addr_imm_index(cpu_T[0], ctx, 0);
 | 
			
		||||
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);
 | 
			
		||||
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rS(ctx->opcode) + 1]);
 | 
			
		||||
    op_POWER2_stfq();
 | 
			
		||||
    int rd = rD(ctx->opcode);
 | 
			
		||||
    TCGv t0 = tcg_temp_new();
 | 
			
		||||
    TCGv t1 = tcg_temp_new();
 | 
			
		||||
    gen_addr_imm_index(t0, ctx, 0);
 | 
			
		||||
    gen_qemu_st64(cpu_fpr[rd], t0, ctx->mem_idx);
 | 
			
		||||
    tcg_gen_addi_tl(t1, t0, 8);
 | 
			
		||||
    gen_qemu_st64(cpu_fpr[(rd + 1) % 32], t1, ctx->mem_idx);
 | 
			
		||||
    if (ra != 0)
 | 
			
		||||
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
 | 
			
		||||
        tcg_gen_mov_tl(cpu_gpr[ra], t0);
 | 
			
		||||
    tcg_temp_free(t0);
 | 
			
		||||
    tcg_temp_free(t1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* stfqux */
 | 
			
		||||
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
 | 
			
		||||
{
 | 
			
		||||
    int ra = rA(ctx->opcode);
 | 
			
		||||
 | 
			
		||||
    /* NIP cannot be restored if the memory exception comes from an helper */
 | 
			
		||||
    gen_update_nip(ctx, ctx->nip - 4);
 | 
			
		||||
    gen_addr_reg_index(cpu_T[0], ctx);
 | 
			
		||||
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);
 | 
			
		||||
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rS(ctx->opcode) + 1]);
 | 
			
		||||
    op_POWER2_stfq();
 | 
			
		||||
    int rd = rD(ctx->opcode);
 | 
			
		||||
    TCGv t0 = tcg_temp_new();
 | 
			
		||||
    TCGv t1 = tcg_temp_new();
 | 
			
		||||
    gen_addr_reg_index(t0, ctx);
 | 
			
		||||
    gen_qemu_st64(cpu_fpr[rd], t0, ctx->mem_idx);
 | 
			
		||||
    tcg_gen_addi_tl(t1, t0, 8);
 | 
			
		||||
    gen_qemu_st64(cpu_fpr[(rd + 1) % 32], t1, ctx->mem_idx);
 | 
			
		||||
    if (ra != 0)
 | 
			
		||||
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
 | 
			
		||||
        tcg_gen_mov_tl(cpu_gpr[ra], t0);
 | 
			
		||||
    tcg_temp_free(t0);
 | 
			
		||||
    tcg_temp_free(t1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* stfqx */
 | 
			
		||||
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
 | 
			
		||||
{
 | 
			
		||||
    /* NIP cannot be restored if the memory exception comes from an helper */
 | 
			
		||||
    gen_update_nip(ctx, ctx->nip - 4);
 | 
			
		||||
    gen_addr_reg_index(cpu_T[0], ctx);
 | 
			
		||||
    tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rS(ctx->opcode)]);
 | 
			
		||||
    tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rS(ctx->opcode) + 1]);
 | 
			
		||||
    op_POWER2_stfq();
 | 
			
		||||
    int rd = rD(ctx->opcode);
 | 
			
		||||
    TCGv t0 = tcg_temp_new();
 | 
			
		||||
    gen_addr_reg_index(t0, ctx);
 | 
			
		||||
    gen_qemu_st64(cpu_fpr[rd], t0, ctx->mem_idx);
 | 
			
		||||
    tcg_gen_addi_tl(t0, t0, 8);
 | 
			
		||||
    gen_qemu_st64(cpu_fpr[(rd + 1) % 32], t0, ctx->mem_idx);
 | 
			
		||||
    tcg_temp_free(t0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* BookE specific instructions */
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user