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