1
2
3
4
5
6
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
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
54#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
55
56#define OPC_CP1 (0x11 << 26)
57
58
59#define MASK_CP1(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
60
61
62enum {
63
64 FMT_S = 16,
65 FMT_D = 17,
66 FMT_E = 18,
67 FMT_Q = 19,
68 FMT_W = 20,
69 FMT_L = 21,
70 FMT_PS = 22,
71
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,
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
138
139
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
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
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
204void msa_translate_init(void);
205
206
207void mxu_translate_init(void);
208bool decode_ase_mxu(DisasContext *ctx, uint32_t insn);
209
210
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
221
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