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