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