959c5da28e
The msa_wr_d[] registers are only initialized/used by MSA. They are declared static. We want to move them to the new 'msa_translate.c' unit in few commits, without having to declare them global (with extern). Extract first the logic initialization of the MSA registers from the generic initialization. We will later move this function along with the MSA registers to the new C unit. Reviewed-by: Jiaxun Yang <jiaxun.yang@flygoat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Tested-by: Jiaxun Yang <jiaxun.yang@flygoat.com> Message-Id: <20201208003702.4088927-8-f4bug@amsat.org>
179 lines
5.8 KiB
C
179 lines
5.8 KiB
C
/*
|
|
* MIPS translation routines.
|
|
*
|
|
* Copyright (c) 2004-2005 Jocelyn Mayer
|
|
*
|
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
*/
|
|
#ifndef TARGET_MIPS_TRANSLATE_H
|
|
#define TARGET_MIPS_TRANSLATE_H
|
|
|
|
#include "exec/translator.h"
|
|
|
|
#define MIPS_DEBUG_DISAS 0
|
|
|
|
typedef struct DisasContext {
|
|
DisasContextBase base;
|
|
target_ulong saved_pc;
|
|
target_ulong page_start;
|
|
uint32_t opcode;
|
|
uint64_t insn_flags;
|
|
int32_t CP0_Config1;
|
|
int32_t CP0_Config2;
|
|
int32_t CP0_Config3;
|
|
int32_t CP0_Config5;
|
|
/* Routine used to access memory */
|
|
int mem_idx;
|
|
MemOp default_tcg_memop_mask;
|
|
uint32_t hflags, saved_hflags;
|
|
target_ulong btarget;
|
|
bool ulri;
|
|
int kscrexist;
|
|
bool rxi;
|
|
int ie;
|
|
bool bi;
|
|
bool bp;
|
|
uint64_t PAMask;
|
|
bool mvh;
|
|
bool eva;
|
|
bool sc;
|
|
int CP0_LLAddr_shift;
|
|
bool ps;
|
|
bool vp;
|
|
bool cmgcr;
|
|
bool mrp;
|
|
bool nan2008;
|
|
bool abs2008;
|
|
bool saar;
|
|
bool mi;
|
|
int gi;
|
|
} DisasContext;
|
|
|
|
/* MIPS major opcodes */
|
|
#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
|
|
|
|
#define OPC_CP1 (0x11 << 26)
|
|
|
|
/* Coprocessor 1 (rs field) */
|
|
#define MASK_CP1(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
|
|
|
|
/* Values for the fmt field in FP instructions */
|
|
enum {
|
|
/* 0 - 15 are reserved */
|
|
FMT_S = 16, /* single fp */
|
|
FMT_D = 17, /* double fp */
|
|
FMT_E = 18, /* extended fp */
|
|
FMT_Q = 19, /* quad fp */
|
|
FMT_W = 20, /* 32-bit fixed */
|
|
FMT_L = 21, /* 64-bit fixed */
|
|
FMT_PS = 22, /* paired single fp */
|
|
/* 23 - 31 are reserved */
|
|
};
|
|
|
|
enum {
|
|
OPC_MFC1 = (0x00 << 21) | OPC_CP1,
|
|
OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
|
|
OPC_CFC1 = (0x02 << 21) | OPC_CP1,
|
|
OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
|
|
OPC_MTC1 = (0x04 << 21) | OPC_CP1,
|
|
OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
|
|
OPC_CTC1 = (0x06 << 21) | OPC_CP1,
|
|
OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
|
|
OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
|
|
OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
|
|
OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
|
|
OPC_BZ_V = (0x0B << 21) | OPC_CP1,
|
|
OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
|
|
OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
|
|
OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
|
|
OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
|
|
OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
|
|
OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
|
|
OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
|
|
OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
|
|
OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
|
|
OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
|
|
OPC_BZ_B = (0x18 << 21) | OPC_CP1,
|
|
OPC_BZ_H = (0x19 << 21) | OPC_CP1,
|
|
OPC_BZ_W = (0x1A << 21) | OPC_CP1,
|
|
OPC_BZ_D = (0x1B << 21) | OPC_CP1,
|
|
OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
|
|
OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
|
|
OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
|
|
OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
|
|
};
|
|
|
|
#define MASK_CP1_FUNC(op) (MASK_CP1(op) | (op & 0x3F))
|
|
#define MASK_BC1(op) (MASK_CP1(op) | (op & (0x3 << 16)))
|
|
|
|
enum {
|
|
OPC_BC1F = (0x00 << 16) | OPC_BC1,
|
|
OPC_BC1T = (0x01 << 16) | OPC_BC1,
|
|
OPC_BC1FL = (0x02 << 16) | OPC_BC1,
|
|
OPC_BC1TL = (0x03 << 16) | OPC_BC1,
|
|
};
|
|
|
|
enum {
|
|
OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
|
|
OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
|
|
};
|
|
|
|
enum {
|
|
OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
|
|
OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
|
|
};
|
|
|
|
void generate_exception(DisasContext *ctx, int excp);
|
|
void generate_exception_err(DisasContext *ctx, int excp, int err);
|
|
void generate_exception_end(DisasContext *ctx, int excp);
|
|
void gen_reserved_instruction(DisasContext *ctx);
|
|
|
|
void check_insn(DisasContext *ctx, uint64_t flags);
|
|
void check_mips_64(DisasContext *ctx);
|
|
void check_cp0_enabled(DisasContext *ctx);
|
|
void check_cp1_enabled(DisasContext *ctx);
|
|
void check_cp1_64bitmode(DisasContext *ctx);
|
|
void check_cp1_registers(DisasContext *ctx, int regs);
|
|
void check_cop1x(DisasContext *ctx);
|
|
|
|
void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset);
|
|
void gen_move_low32(TCGv ret, TCGv_i64 arg);
|
|
void gen_move_high32(TCGv ret, TCGv_i64 arg);
|
|
void gen_load_gpr(TCGv t, int reg);
|
|
void gen_store_gpr(TCGv t, int reg);
|
|
void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg);
|
|
void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg);
|
|
void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg);
|
|
void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg);
|
|
int get_fp_bit(int cc);
|
|
|
|
void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1);
|
|
|
|
extern TCGv cpu_gpr[32], cpu_PC;
|
|
extern TCGv_i32 fpu_fcr0, fpu_fcr31;
|
|
extern TCGv_i64 fpu_f64[32];
|
|
extern TCGv bcond;
|
|
|
|
#define LOG_DISAS(...) \
|
|
do { \
|
|
if (MIPS_DEBUG_DISAS) { \
|
|
qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define MIPS_INVAL(op) \
|
|
do { \
|
|
if (MIPS_DEBUG_DISAS) { \
|
|
qemu_log_mask(CPU_LOG_TB_IN_ASM, \
|
|
TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
|
|
ctx->base.pc_next, ctx->opcode, op, \
|
|
ctx->opcode >> 26, ctx->opcode & 0x3F, \
|
|
((ctx->opcode >> 16) & 0x1F)); \
|
|
} \
|
|
} while (0)
|
|
|
|
/* MSA */
|
|
void msa_translate_init(void);
|
|
|
|
#endif
|