qemu/target/mips/tcg/translate.h
<<
>>
Prefs
   1/*
   2 *  MIPS translation routines.
   3 *
   4 *  Copyright (c) 2004-2005 Jocelyn Mayer
   5 *
   6 * SPDX-License-Identifier: LGPL-2.1-or-later
   7 */
   8#ifndef TARGET_MIPS_TRANSLATE_H
   9#define TARGET_MIPS_TRANSLATE_H
  10
  11#include "qemu/log.h"
  12#include "exec/translator.h"
  13
  14#define MIPS_DEBUG_DISAS 0
  15
  16typedef struct DisasContext {
  17    DisasContextBase base;
  18    target_ulong saved_pc;
  19    target_ulong page_start;
  20    uint32_t opcode;
  21    uint64_t insn_flags;
  22    int32_t CP0_Config0;
  23    int32_t CP0_Config1;
  24    int32_t CP0_Config2;
  25    int32_t CP0_Config3;
  26    int32_t CP0_Config5;
  27    /* Routine used to access memory */
  28    int mem_idx;
  29    MemOp default_tcg_memop_mask;
  30    uint32_t hflags, saved_hflags;
  31    target_ulong btarget;
  32    bool ulri;
  33    int kscrexist;
  34    bool rxi;
  35    int ie;
  36    bool bi;
  37    bool bp;
  38    uint64_t PAMask;
  39    bool mvh;
  40    bool eva;
  41    bool sc;
  42    int CP0_LLAddr_shift;
  43    bool ps;
  44    bool vp;
  45    bool cmgcr;
  46    bool mrp;
  47    bool nan2008;
  48    bool abs2008;
  49    bool saar;
  50    bool mi;
  51    int gi;
  52} DisasContext;
  53
  54#define DISAS_STOP       DISAS_TARGET_0
  55#define DISAS_EXIT       DISAS_TARGET_1
  56#define DISAS_SEMIHOST   DISAS_TARGET_2
  57
  58/* MIPS major opcodes */
  59#define MASK_OP_MAJOR(op)   (op & (0x3F << 26))
  60
  61#define OPC_CP1 (0x11 << 26)
  62
  63/* Coprocessor 1 (rs field) */
  64#define MASK_CP1(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
  65
  66/* Values for the fmt field in FP instructions */
  67enum {
  68    /* 0 - 15 are reserved */
  69    FMT_S = 16,          /* single fp */
  70    FMT_D = 17,          /* double fp */
  71    FMT_E = 18,          /* extended fp */
  72    FMT_Q = 19,          /* quad fp */
  73    FMT_W = 20,          /* 32-bit fixed */
  74    FMT_L = 21,          /* 64-bit fixed */
  75    FMT_PS = 22,         /* paired single fp */
  76    /* 23 - 31 are reserved */
  77};
  78
  79enum {
  80    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
  81    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
  82    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
  83    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
  84    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
  85    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
  86    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
  87    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
  88    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
  89    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
  90    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
  91    OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
  92    OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
  93    OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
  94    OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
  95    OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
  96    OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
  97    OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
  98    OPC_BC1EQZ   = (0x09 << 21) | OPC_CP1,
  99    OPC_BC1NEZ   = (0x0D << 21) | OPC_CP1,
 100};
 101
 102#define MASK_CP1_FUNC(op)           (MASK_CP1(op) | (op & 0x3F))
 103#define MASK_BC1(op)                (MASK_CP1(op) | (op & (0x3 << 16)))
 104
 105enum {
 106    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
 107    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
 108    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
 109    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
 110};
 111
 112enum {
 113    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
 114    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
 115};
 116
 117enum {
 118    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
 119    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
 120};
 121
 122#define gen_helper_0e1i(name, arg1, arg2) do { \
 123    gen_helper_##name(cpu_env, arg1, tcg_constant_i32(arg2)); \
 124    } while (0)
 125
 126#define gen_helper_1e0i(name, ret, arg1) do { \
 127    gen_helper_##name(ret, cpu_env, tcg_constant_i32(arg1)); \
 128    } while (0)
 129
 130#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
 131    gen_helper_##name(cpu_env, arg1, arg2, tcg_constant_i32(arg3));\
 132    } while (0)
 133
 134void generate_exception(DisasContext *ctx, int excp);
 135void generate_exception_err(DisasContext *ctx, int excp, int err);
 136void generate_exception_end(DisasContext *ctx, int excp);
 137void generate_exception_break(DisasContext *ctx, int code);
 138void gen_reserved_instruction(DisasContext *ctx);
 139
 140void check_insn(DisasContext *ctx, uint64_t flags);
 141void check_mips_64(DisasContext *ctx);
 142/**
 143 * check_cp0_enabled:
 144 * Return %true if CP0 is enabled, otherwise return %false
 145 * and emit a 'coprocessor unusable' exception.
 146 */
 147bool check_cp0_enabled(DisasContext *ctx);
 148void check_cp1_enabled(DisasContext *ctx);
 149void check_cp1_64bitmode(DisasContext *ctx);
 150void check_cp1_registers(DisasContext *ctx, int regs);
 151void check_cop1x(DisasContext *ctx);
 152
 153void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset);
 154void gen_move_low32(TCGv ret, TCGv_i64 arg);
 155void gen_move_high32(TCGv ret, TCGv_i64 arg);
 156void gen_load_gpr(TCGv t, int reg);
 157void gen_store_gpr(TCGv t, int reg);
 158#if defined(TARGET_MIPS64)
 159void gen_load_gpr_hi(TCGv_i64 t, int reg);
 160void gen_store_gpr_hi(TCGv_i64 t, int reg);
 161#endif /* TARGET_MIPS64 */
 162void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg);
 163void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg);
 164void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg);
 165void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg);
 166int get_fp_bit(int cc);
 167
 168void gen_ldxs(DisasContext *ctx, int base, int index, int rd);
 169void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp);
 170void gen_addiupc(DisasContext *ctx, int rx, int imm,
 171                 int is_64_bit, int extended);
 172
 173/*
 174 * Address Computation and Large Constant Instructions
 175 */
 176void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1);
 177bool gen_lsa(DisasContext *ctx, int rd, int rt, int rs, int sa);
 178bool gen_dlsa(DisasContext *ctx, int rd, int rt, int rs, int sa);
 179
 180void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel);
 181
 182extern TCGv cpu_gpr[32], cpu_PC;
 183#if defined(TARGET_MIPS64)
 184extern TCGv_i64 cpu_gpr_hi[32];
 185#endif
 186extern TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
 187extern TCGv_i32 fpu_fcr0, fpu_fcr31;
 188extern TCGv_i64 fpu_f64[32];
 189extern TCGv bcond;
 190
 191#define LOG_DISAS(...)                                                        \
 192    do {                                                                      \
 193        if (MIPS_DEBUG_DISAS) {                                               \
 194            qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
 195        }                                                                     \
 196    } while (0)
 197
 198#define MIPS_INVAL(op)                                                        \
 199    do {                                                                      \
 200        if (MIPS_DEBUG_DISAS) {                                               \
 201            qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
 202                          TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
 203                          ctx->base.pc_next, ctx->opcode, op,                 \
 204                          ctx->opcode >> 26, ctx->opcode & 0x3F,              \
 205                          ((ctx->opcode >> 16) & 0x1F));                      \
 206        }                                                                     \
 207    } while (0)
 208
 209/* MSA */
 210void msa_translate_init(void);
 211
 212/* MXU */
 213void mxu_translate_init(void);
 214bool decode_ase_mxu(DisasContext *ctx, uint32_t insn);
 215
 216/* decodetree generated */
 217bool decode_isa_rel6(DisasContext *ctx, uint32_t insn);
 218bool decode_ase_msa(DisasContext *ctx, uint32_t insn);
 219bool decode_ext_txx9(DisasContext *ctx, uint32_t insn);
 220#if defined(TARGET_MIPS64)
 221bool decode_ext_tx79(DisasContext *ctx, uint32_t insn);
 222bool decode_ext_octeon(DisasContext *ctx, uint32_t insn);
 223#endif
 224bool decode_ext_vr54xx(DisasContext *ctx, uint32_t insn);
 225
 226/*
 227 * Helpers for implementing sets of trans_* functions.
 228 * Defer the implementation of NAME to FUNC, with optional extra arguments.
 229 */
 230#define TRANS(NAME, FUNC, ...) \
 231    static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \
 232    { return FUNC(ctx, a, __VA_ARGS__); }
 233
 234static inline bool cpu_is_bigendian(DisasContext *ctx)
 235{
 236    return extract32(ctx->CP0_Config0, CP0C0_BE, 1);
 237}
 238
 239#endif
 240