]> Git Repo - qemu.git/blob - target/mips/translate.h
target/mips: Introduce decodetree helpers for Release6 LSA/DLSA opcodes
[qemu.git] / target / mips / translate.h
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
15 typedef 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 */
61 enum {
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
73 enum {
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
99 enum {
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
106 enum {
107     OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
108     OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
109 };
110
111 enum {
112     OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
113     OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
114 };
115
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);
120
121 void check_insn(DisasContext *ctx, uint64_t flags);
122 void check_mips_64(DisasContext *ctx);
123 void check_cp0_enabled(DisasContext *ctx);
124 void check_cp1_enabled(DisasContext *ctx);
125 void check_cp1_64bitmode(DisasContext *ctx);
126 void check_cp1_registers(DisasContext *ctx, int regs);
127 void check_cop1x(DisasContext *ctx);
128
129 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset);
130 void gen_move_low32(TCGv ret, TCGv_i64 arg);
131 void gen_move_high32(TCGv ret, TCGv_i64 arg);
132 void gen_load_gpr(TCGv t, int reg);
133 void gen_store_gpr(TCGv t, int reg);
134 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg);
135 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg);
136 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg);
137 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg);
138 int get_fp_bit(int cc);
139
140 /*
141  * Address Computation and Large Constant Instructions
142  */
143 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1);
144 bool gen_lsa(DisasContext *ctx, int rd, int rt, int rs, int sa);
145 bool gen_dlsa(DisasContext *ctx, int rd, int rt, int rs, int sa);
146
147 extern TCGv cpu_gpr[32], cpu_PC;
148 extern TCGv_i32 fpu_fcr0, fpu_fcr31;
149 extern TCGv_i64 fpu_f64[32];
150 extern TCGv bcond;
151
152 #define LOG_DISAS(...)                                                        \
153     do {                                                                      \
154         if (MIPS_DEBUG_DISAS) {                                               \
155             qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
156         }                                                                     \
157     } while (0)
158
159 #define MIPS_INVAL(op)                                                        \
160     do {                                                                      \
161         if (MIPS_DEBUG_DISAS) {                                               \
162             qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
163                           TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
164                           ctx->base.pc_next, ctx->opcode, op,                 \
165                           ctx->opcode >> 26, ctx->opcode & 0x3F,              \
166                           ((ctx->opcode >> 16) & 0x1F));                      \
167         }                                                                     \
168     } while (0)
169
170 /* MSA */
171 void msa_translate_init(void);
172
173 /* decodetree generated */
174 bool decode_isa_rel6(DisasContext *ctx, uint32_t insn);
175 bool decode_ase_msa(DisasContext *ctx, uint32_t insn);
176
177 #endif
This page took 0.034611 seconds and 4 git commands to generate.