2 * MIPS translation routines.
4 * Copyright (c) 2004-2005 Jocelyn Mayer
6 * SPDX-License-Identifier: LGPL-2.1-or-later
8 #ifndef TARGET_MIPS_TRANSLATE_H
9 #define TARGET_MIPS_TRANSLATE_H
11 #include "exec/translator.h"
13 #define MIPS_DEBUG_DISAS 0
15 typedef struct DisasContext
{
16 DisasContextBase base
;
17 target_ulong saved_pc
;
18 target_ulong page_start
;
25 /* Routine used to access memory */
27 MemOp default_tcg_memop_mask
;
28 uint32_t hflags
, saved_hflags
;
52 /* MIPS major opcodes */
53 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
55 #define OPC_CP1 (0x11 << 26)
57 /* Coprocessor 1 (rs field) */
58 #define MASK_CP1(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
60 /* Values for the fmt field in FP instructions */
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 */
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
,
96 #define MASK_CP1_FUNC(op) (MASK_CP1(op) | (op & 0x3F))
97 #define MASK_BC1(op) (MASK_CP1(op) | (op & (0x3 << 16)))
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
,
107 OPC_BC1FANY2
= (0x00 << 16) | OPC_BC1ANY2
,
108 OPC_BC1TANY2
= (0x01 << 16) | OPC_BC1ANY2
,
112 OPC_BC1FANY4
= (0x00 << 16) | OPC_BC1ANY4
,
113 OPC_BC1TANY4
= (0x01 << 16) | OPC_BC1ANY4
,
116 void generate_exception(DisasContext
*ctx
, int excp
);
117 void generate_exception_err(DisasContext
*ctx
, int excp
, int err
);
118 void generate_exception_end(DisasContext
*ctx
, int excp
);
119 void gen_reserved_instruction(DisasContext
*ctx
);
121 void check_insn(DisasContext
*ctx
, uint64_t flags
);
122 void check_mips_64(DisasContext
*ctx
);
125 * Return %true if CP0 is enabled, otherwise return %false
126 * and emit a 'coprocessor unusable' exception.
128 bool check_cp0_enabled(DisasContext
*ctx
);
129 void check_cp1_enabled(DisasContext
*ctx
);
130 void check_cp1_64bitmode(DisasContext
*ctx
);
131 void check_cp1_registers(DisasContext
*ctx
, int regs
);
132 void check_cop1x(DisasContext
*ctx
);
134 void gen_base_offset_addr(DisasContext
*ctx
, TCGv addr
, int base
, int offset
);
135 void gen_move_low32(TCGv ret
, TCGv_i64 arg
);
136 void gen_move_high32(TCGv ret
, TCGv_i64 arg
);
137 void gen_load_gpr(TCGv t
, int reg
);
138 void gen_store_gpr(TCGv t
, int reg
);
139 #if defined(TARGET_MIPS64)
140 void gen_load_gpr_hi(TCGv_i64 t
, int reg
);
141 void gen_store_gpr_hi(TCGv_i64 t
, int reg
);
142 #endif /* TARGET_MIPS64 */
143 void gen_load_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
);
144 void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
);
145 void gen_store_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
);
146 void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
);
147 int get_fp_bit(int cc
);
150 * Address Computation and Large Constant Instructions
152 void gen_op_addr_add(DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
);
153 bool gen_lsa(DisasContext
*ctx
, int rd
, int rt
, int rs
, int sa
);
154 bool gen_dlsa(DisasContext
*ctx
, int rd
, int rt
, int rs
, int sa
);
156 void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
);
158 extern TCGv cpu_gpr
[32], cpu_PC
;
159 #if defined(TARGET_MIPS64)
160 extern TCGv_i64 cpu_gpr_hi
[32];
162 extern TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
];
163 extern TCGv_i32 fpu_fcr0
, fpu_fcr31
;
164 extern TCGv_i64 fpu_f64
[32];
167 #define LOG_DISAS(...) \
169 if (MIPS_DEBUG_DISAS) { \
170 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
174 #define MIPS_INVAL(op) \
176 if (MIPS_DEBUG_DISAS) { \
177 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
178 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
179 ctx->base.pc_next, ctx->opcode, op, \
180 ctx->opcode >> 26, ctx->opcode & 0x3F, \
181 ((ctx->opcode >> 16) & 0x1F)); \
186 void msa_translate_init(void);
189 void mxu_translate_init(void);
190 bool decode_ase_mxu(DisasContext
*ctx
, uint32_t insn
);
192 /* decodetree generated */
193 bool decode_isa_rel6(DisasContext
*ctx
, uint32_t insn
);
194 bool decode_ase_msa(DisasContext
*ctx
, uint32_t insn
);
195 bool decode_ext_txx9(DisasContext
*ctx
, uint32_t insn
);
196 #if defined(TARGET_MIPS64)
197 bool decode_ext_tx79(DisasContext
*ctx
, uint32_t insn
);