Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 61c04807

History | View | Annotate | Download (223.1 kB)

1 79aceca5 bellard
/*
2 3fc6c082 bellard
 *  PowerPC emulation for qemu: main translation routines.
3 5fafdf24 ths
 *
4 76a66253 j_mayer
 *  Copyright (c) 2003-2007 Jocelyn Mayer
5 79aceca5 bellard
 *
6 79aceca5 bellard
 * This library is free software; you can redistribute it and/or
7 79aceca5 bellard
 * modify it under the terms of the GNU Lesser General Public
8 79aceca5 bellard
 * License as published by the Free Software Foundation; either
9 79aceca5 bellard
 * version 2 of the License, or (at your option) any later version.
10 79aceca5 bellard
 *
11 79aceca5 bellard
 * This library is distributed in the hope that it will be useful,
12 79aceca5 bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 79aceca5 bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 79aceca5 bellard
 * Lesser General Public License for more details.
15 79aceca5 bellard
 *
16 79aceca5 bellard
 * You should have received a copy of the GNU Lesser General Public
17 79aceca5 bellard
 * License along with this library; if not, write to the Free Software
18 79aceca5 bellard
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 79aceca5 bellard
 */
20 c6a1c22b bellard
#include <stdarg.h>
21 c6a1c22b bellard
#include <stdlib.h>
22 c6a1c22b bellard
#include <stdio.h>
23 c6a1c22b bellard
#include <string.h>
24 c6a1c22b bellard
#include <inttypes.h>
25 c6a1c22b bellard
26 79aceca5 bellard
#include "cpu.h"
27 c6a1c22b bellard
#include "exec-all.h"
28 79aceca5 bellard
#include "disas.h"
29 61c04807 aurel32
#include "helper.h"
30 57fec1fe bellard
#include "tcg-op.h"
31 ca10f867 aurel32
#include "qemu-common.h"
32 79aceca5 bellard
33 8cbcb4fa aurel32
#define CPU_SINGLE_STEP 0x1
34 8cbcb4fa aurel32
#define CPU_BRANCH_STEP 0x2
35 8cbcb4fa aurel32
#define GDBSTUB_SINGLE_STEP 0x4
36 8cbcb4fa aurel32
37 a750fc0b j_mayer
/* Include definitions for instructions classes and implementations flags */
38 79aceca5 bellard
//#define DO_SINGLE_STEP
39 9fddaa0c bellard
//#define PPC_DEBUG_DISAS
40 a496775f j_mayer
//#define DEBUG_MEMORY_ACCESSES
41 76a66253 j_mayer
//#define DO_PPC_STATISTICS
42 7c58044c j_mayer
//#define OPTIMIZE_FPRF_UPDATE
43 79aceca5 bellard
44 a750fc0b j_mayer
/*****************************************************************************/
45 a750fc0b j_mayer
/* Code translation helpers                                                  */
46 c53be334 bellard
47 c0692e3c aurel32
static TCGv cpu_env, cpu_T[3];
48 2e70f6ef pbrook
49 2e70f6ef pbrook
#include "gen-icount.h"
50 2e70f6ef pbrook
51 2e70f6ef pbrook
void ppc_translate_init(void)
52 2e70f6ef pbrook
{
53 b2437bf2 pbrook
    static int done_init = 0;
54 2e70f6ef pbrook
    if (done_init)
55 2e70f6ef pbrook
        return;
56 2e70f6ef pbrook
    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
57 c0692e3c aurel32
#if TARGET_LONG_BITS > HOST_LONG_BITS
58 c0692e3c aurel32
    cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
59 c0692e3c aurel32
                                  TCG_AREG0, offsetof(CPUState, t0), "T0");
60 c0692e3c aurel32
    cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
61 c0692e3c aurel32
                                  TCG_AREG0, offsetof(CPUState, t1), "T1");
62 c0692e3c aurel32
    cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
63 c0692e3c aurel32
                                  TCG_AREG0, offsetof(CPUState, t2), "T2");
64 c0692e3c aurel32
#else
65 c0692e3c aurel32
    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
66 c0692e3c aurel32
    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
67 c0692e3c aurel32
    cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2");
68 c0692e3c aurel32
#endif
69 61c04807 aurel32
70 61c04807 aurel32
    /* register helpers */
71 61c04807 aurel32
#undef DEF_HELPER
72 61c04807 aurel32
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
73 61c04807 aurel32
#include "helper.h"
74 61c04807 aurel32
75 2e70f6ef pbrook
    done_init = 1;
76 2e70f6ef pbrook
}
77 2e70f6ef pbrook
78 61c04807 aurel32
static inline void tcg_gen_helper_0_i(void *func, TCGv arg)
79 61c04807 aurel32
{
80 61c04807 aurel32
    TCGv tmp = tcg_const_i32(arg);
81 61c04807 aurel32
82 61c04807 aurel32
    tcg_gen_helper_0_1(func, tmp);
83 61c04807 aurel32
    tcg_temp_free(tmp);
84 61c04807 aurel32
}
85 61c04807 aurel32
86 61c04807 aurel32
87 7c58044c j_mayer
#if defined(OPTIMIZE_FPRF_UPDATE)
88 7c58044c j_mayer
static uint16_t *gen_fprf_buf[OPC_BUF_SIZE];
89 7c58044c j_mayer
static uint16_t **gen_fprf_ptr;
90 7c58044c j_mayer
#endif
91 79aceca5 bellard
92 b068d6a7 j_mayer
static always_inline void gen_set_T0 (target_ulong val)
93 d9bce9d9 j_mayer
{
94 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
95 d9bce9d9 j_mayer
    if (val >> 32)
96 d9bce9d9 j_mayer
        gen_op_set_T0_64(val >> 32, val);
97 d9bce9d9 j_mayer
    else
98 d9bce9d9 j_mayer
#endif
99 d9bce9d9 j_mayer
        gen_op_set_T0(val);
100 d9bce9d9 j_mayer
}
101 d9bce9d9 j_mayer
102 b068d6a7 j_mayer
static always_inline void gen_set_T1 (target_ulong val)
103 d9bce9d9 j_mayer
{
104 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
105 d9bce9d9 j_mayer
    if (val >> 32)
106 d9bce9d9 j_mayer
        gen_op_set_T1_64(val >> 32, val);
107 d9bce9d9 j_mayer
    else
108 d9bce9d9 j_mayer
#endif
109 d9bce9d9 j_mayer
        gen_op_set_T1(val);
110 d9bce9d9 j_mayer
}
111 d9bce9d9 j_mayer
112 d9bce9d9 j_mayer
#define GEN8(func, NAME)                                                      \
113 9a64fbe4 bellard
static GenOpFunc *NAME ## _table [8] = {                                      \
114 9a64fbe4 bellard
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
115 9a64fbe4 bellard
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
116 9a64fbe4 bellard
};                                                                            \
117 b068d6a7 j_mayer
static always_inline void func (int n)                                        \
118 9a64fbe4 bellard
{                                                                             \
119 9a64fbe4 bellard
    NAME ## _table[n]();                                                      \
120 9a64fbe4 bellard
}
121 9a64fbe4 bellard
122 9a64fbe4 bellard
#define GEN16(func, NAME)                                                     \
123 9a64fbe4 bellard
static GenOpFunc *NAME ## _table [16] = {                                     \
124 9a64fbe4 bellard
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
125 9a64fbe4 bellard
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
126 9a64fbe4 bellard
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
127 9a64fbe4 bellard
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
128 9a64fbe4 bellard
};                                                                            \
129 b068d6a7 j_mayer
static always_inline void func (int n)                                        \
130 9a64fbe4 bellard
{                                                                             \
131 9a64fbe4 bellard
    NAME ## _table[n]();                                                      \
132 28b6751f bellard
}
133 28b6751f bellard
134 d9bce9d9 j_mayer
#define GEN32(func, NAME)                                                     \
135 9a64fbe4 bellard
static GenOpFunc *NAME ## _table [32] = {                                     \
136 9a64fbe4 bellard
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
137 9a64fbe4 bellard
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
138 9a64fbe4 bellard
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
139 9a64fbe4 bellard
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
140 9a64fbe4 bellard
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
141 9a64fbe4 bellard
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
142 9a64fbe4 bellard
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
143 9a64fbe4 bellard
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
144 9a64fbe4 bellard
};                                                                            \
145 b068d6a7 j_mayer
static always_inline void func (int n)                                        \
146 9a64fbe4 bellard
{                                                                             \
147 9a64fbe4 bellard
    NAME ## _table[n]();                                                      \
148 9a64fbe4 bellard
}
149 9a64fbe4 bellard
150 9a64fbe4 bellard
/* Condition register moves */
151 9a64fbe4 bellard
GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf);
152 9a64fbe4 bellard
GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf);
153 9a64fbe4 bellard
GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf);
154 fc0d441e j_mayer
#if 0 // Unused
155 9a64fbe4 bellard
GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf);
156 fc0d441e j_mayer
#endif
157 28b6751f bellard
158 9a64fbe4 bellard
/* General purpose registers moves */
159 9a64fbe4 bellard
GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
160 9a64fbe4 bellard
GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
161 9a64fbe4 bellard
GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
162 9a64fbe4 bellard
163 9a64fbe4 bellard
GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
164 9a64fbe4 bellard
GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
165 76a66253 j_mayer
#if 0 // unused
166 9a64fbe4 bellard
GEN32(gen_op_store_T2_gpr, gen_op_store_T2_gpr_gpr);
167 76a66253 j_mayer
#endif
168 28b6751f bellard
169 fb0eaffc bellard
/* floating point registers moves */
170 fb0eaffc bellard
GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fpr);
171 fb0eaffc bellard
GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fpr);
172 fb0eaffc bellard
GEN32(gen_op_load_fpr_FT2, gen_op_load_fpr_FT2_fpr);
173 fb0eaffc bellard
GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fpr);
174 fb0eaffc bellard
GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fpr);
175 76a66253 j_mayer
#if 0 // unused
176 fb0eaffc bellard
GEN32(gen_op_store_FT2_fpr, gen_op_store_FT2_fpr_fpr);
177 76a66253 j_mayer
#endif
178 79aceca5 bellard
179 79aceca5 bellard
/* internal defines */
180 79aceca5 bellard
typedef struct DisasContext {
181 79aceca5 bellard
    struct TranslationBlock *tb;
182 0fa85d43 bellard
    target_ulong nip;
183 79aceca5 bellard
    uint32_t opcode;
184 9a64fbe4 bellard
    uint32_t exception;
185 3cc62370 bellard
    /* Routine used to access memory */
186 3cc62370 bellard
    int mem_idx;
187 3cc62370 bellard
    /* Translation flags */
188 9a64fbe4 bellard
#if !defined(CONFIG_USER_ONLY)
189 79aceca5 bellard
    int supervisor;
190 9a64fbe4 bellard
#endif
191 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
192 d9bce9d9 j_mayer
    int sf_mode;
193 d9bce9d9 j_mayer
#endif
194 3cc62370 bellard
    int fpu_enabled;
195 a9d9eb8f j_mayer
    int altivec_enabled;
196 0487d6a8 j_mayer
    int spe_enabled;
197 3fc6c082 bellard
    ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
198 ea4e754f bellard
    int singlestep_enabled;
199 d63001d1 j_mayer
    int dcache_line_size;
200 79aceca5 bellard
} DisasContext;
201 79aceca5 bellard
202 3fc6c082 bellard
struct opc_handler_t {
203 79aceca5 bellard
    /* invalid bits */
204 79aceca5 bellard
    uint32_t inval;
205 9a64fbe4 bellard
    /* instruction type */
206 0487d6a8 j_mayer
    uint64_t type;
207 79aceca5 bellard
    /* handler */
208 79aceca5 bellard
    void (*handler)(DisasContext *ctx);
209 a750fc0b j_mayer
#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
210 76a66253 j_mayer
    const unsigned char *oname;
211 a750fc0b j_mayer
#endif
212 a750fc0b j_mayer
#if defined(DO_PPC_STATISTICS)
213 76a66253 j_mayer
    uint64_t count;
214 76a66253 j_mayer
#endif
215 3fc6c082 bellard
};
216 79aceca5 bellard
217 b068d6a7 j_mayer
static always_inline void gen_set_Rc0 (DisasContext *ctx)
218 76a66253 j_mayer
{
219 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
220 d9bce9d9 j_mayer
    if (ctx->sf_mode)
221 d9bce9d9 j_mayer
        gen_op_cmpi_64(0);
222 d9bce9d9 j_mayer
    else
223 d9bce9d9 j_mayer
#endif
224 d9bce9d9 j_mayer
        gen_op_cmpi(0);
225 76a66253 j_mayer
    gen_op_set_Rc0();
226 76a66253 j_mayer
}
227 76a66253 j_mayer
228 7c58044c j_mayer
static always_inline void gen_reset_fpstatus (void)
229 7c58044c j_mayer
{
230 7c58044c j_mayer
#ifdef CONFIG_SOFTFLOAT
231 7c58044c j_mayer
    gen_op_reset_fpstatus();
232 7c58044c j_mayer
#endif
233 7c58044c j_mayer
}
234 7c58044c j_mayer
235 7c58044c j_mayer
static always_inline void gen_compute_fprf (int set_fprf, int set_rc)
236 7c58044c j_mayer
{
237 7c58044c j_mayer
    if (set_fprf != 0) {
238 7c58044c j_mayer
        /* This case might be optimized later */
239 7c58044c j_mayer
#if defined(OPTIMIZE_FPRF_UPDATE)
240 7c58044c j_mayer
        *gen_fprf_ptr++ = gen_opc_ptr;
241 7c58044c j_mayer
#endif
242 7c58044c j_mayer
        gen_op_compute_fprf(1);
243 7c58044c j_mayer
        if (unlikely(set_rc))
244 7c58044c j_mayer
            gen_op_store_T0_crf(1);
245 7c58044c j_mayer
        gen_op_float_check_status();
246 7c58044c j_mayer
    } else if (unlikely(set_rc)) {
247 7c58044c j_mayer
        /* We always need to compute fpcc */
248 7c58044c j_mayer
        gen_op_compute_fprf(0);
249 7c58044c j_mayer
        gen_op_store_T0_crf(1);
250 7c58044c j_mayer
        if (set_fprf)
251 7c58044c j_mayer
            gen_op_float_check_status();
252 7c58044c j_mayer
    }
253 7c58044c j_mayer
}
254 7c58044c j_mayer
255 7c58044c j_mayer
static always_inline void gen_optimize_fprf (void)
256 7c58044c j_mayer
{
257 7c58044c j_mayer
#if defined(OPTIMIZE_FPRF_UPDATE)
258 7c58044c j_mayer
    uint16_t **ptr;
259 7c58044c j_mayer
260 7c58044c j_mayer
    for (ptr = gen_fprf_buf; ptr != (gen_fprf_ptr - 1); ptr++)
261 7c58044c j_mayer
        *ptr = INDEX_op_nop1;
262 7c58044c j_mayer
    gen_fprf_ptr = gen_fprf_buf;
263 7c58044c j_mayer
#endif
264 7c58044c j_mayer
}
265 7c58044c j_mayer
266 b068d6a7 j_mayer
static always_inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
267 d9bce9d9 j_mayer
{
268 61c04807 aurel32
    TCGv tmp;
269 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
270 d9bce9d9 j_mayer
    if (ctx->sf_mode)
271 61c04807 aurel32
        tmp = tcg_const_i64(nip);
272 d9bce9d9 j_mayer
    else
273 d9bce9d9 j_mayer
#endif
274 61c04807 aurel32
        tmp = tcg_const_i32((uint32_t)nip);
275 61c04807 aurel32
276 61c04807 aurel32
    tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUState, nip));
277 61c04807 aurel32
    tcg_temp_free(tmp);
278 d9bce9d9 j_mayer
}
279 d9bce9d9 j_mayer
280 e1833e1f j_mayer
#define GEN_EXCP(ctx, excp, error)                                            \
281 79aceca5 bellard
do {                                                                          \
282 e1833e1f j_mayer
    if ((ctx)->exception == POWERPC_EXCP_NONE) {                              \
283 d9bce9d9 j_mayer
        gen_update_nip(ctx, (ctx)->nip);                                      \
284 9fddaa0c bellard
    }                                                                         \
285 9fddaa0c bellard
    gen_op_raise_exception_err((excp), (error));                              \
286 9fddaa0c bellard
    ctx->exception = (excp);                                                  \
287 79aceca5 bellard
} while (0)
288 79aceca5 bellard
289 e1833e1f j_mayer
#define GEN_EXCP_INVAL(ctx)                                                   \
290 e1833e1f j_mayer
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
291 e1833e1f j_mayer
         POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL)
292 9fddaa0c bellard
293 e1833e1f j_mayer
#define GEN_EXCP_PRIVOPC(ctx)                                                 \
294 e1833e1f j_mayer
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
295 e1833e1f j_mayer
         POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_OPC)
296 9a64fbe4 bellard
297 e1833e1f j_mayer
#define GEN_EXCP_PRIVREG(ctx)                                                 \
298 e1833e1f j_mayer
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
299 e1833e1f j_mayer
         POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG)
300 e1833e1f j_mayer
301 e1833e1f j_mayer
#define GEN_EXCP_NO_FP(ctx)                                                   \
302 e1833e1f j_mayer
GEN_EXCP(ctx, POWERPC_EXCP_FPU, 0)
303 e1833e1f j_mayer
304 e1833e1f j_mayer
#define GEN_EXCP_NO_AP(ctx)                                                   \
305 e1833e1f j_mayer
GEN_EXCP(ctx, POWERPC_EXCP_APU, 0)
306 9a64fbe4 bellard
307 a9d9eb8f j_mayer
#define GEN_EXCP_NO_VR(ctx)                                                   \
308 a9d9eb8f j_mayer
GEN_EXCP(ctx, POWERPC_EXCP_VPU, 0)
309 a9d9eb8f j_mayer
310 f24e5695 bellard
/* Stop translation */
311 b068d6a7 j_mayer
static always_inline void GEN_STOP (DisasContext *ctx)
312 3fc6c082 bellard
{
313 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip);
314 e1833e1f j_mayer
    ctx->exception = POWERPC_EXCP_STOP;
315 3fc6c082 bellard
}
316 3fc6c082 bellard
317 f24e5695 bellard
/* No need to update nip here, as execution flow will change */
318 b068d6a7 j_mayer
static always_inline void GEN_SYNC (DisasContext *ctx)
319 2be0071f bellard
{
320 e1833e1f j_mayer
    ctx->exception = POWERPC_EXCP_SYNC;
321 2be0071f bellard
}
322 2be0071f bellard
323 79aceca5 bellard
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
324 79aceca5 bellard
static void gen_##name (DisasContext *ctx);                                   \
325 79aceca5 bellard
GEN_OPCODE(name, opc1, opc2, opc3, inval, type);                              \
326 79aceca5 bellard
static void gen_##name (DisasContext *ctx)
327 79aceca5 bellard
328 c7697e1f j_mayer
#define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type)               \
329 c7697e1f j_mayer
static void gen_##name (DisasContext *ctx);                                   \
330 c7697e1f j_mayer
GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type);                       \
331 c7697e1f j_mayer
static void gen_##name (DisasContext *ctx)
332 c7697e1f j_mayer
333 79aceca5 bellard
typedef struct opcode_t {
334 79aceca5 bellard
    unsigned char opc1, opc2, opc3;
335 1235fc06 ths
#if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */
336 18fba28c bellard
    unsigned char pad[5];
337 18fba28c bellard
#else
338 18fba28c bellard
    unsigned char pad[1];
339 18fba28c bellard
#endif
340 79aceca5 bellard
    opc_handler_t handler;
341 3fc6c082 bellard
    const unsigned char *oname;
342 79aceca5 bellard
} opcode_t;
343 79aceca5 bellard
344 a750fc0b j_mayer
/*****************************************************************************/
345 79aceca5 bellard
/***                           Instruction decoding                        ***/
346 79aceca5 bellard
#define EXTRACT_HELPER(name, shift, nb)                                       \
347 b068d6a7 j_mayer
static always_inline uint32_t name (uint32_t opcode)                          \
348 79aceca5 bellard
{                                                                             \
349 79aceca5 bellard
    return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
350 79aceca5 bellard
}
351 79aceca5 bellard
352 79aceca5 bellard
#define EXTRACT_SHELPER(name, shift, nb)                                      \
353 b068d6a7 j_mayer
static always_inline int32_t name (uint32_t opcode)                           \
354 79aceca5 bellard
{                                                                             \
355 18fba28c bellard
    return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
356 79aceca5 bellard
}
357 79aceca5 bellard
358 79aceca5 bellard
/* Opcode part 1 */
359 79aceca5 bellard
EXTRACT_HELPER(opc1, 26, 6);
360 79aceca5 bellard
/* Opcode part 2 */
361 79aceca5 bellard
EXTRACT_HELPER(opc2, 1, 5);
362 79aceca5 bellard
/* Opcode part 3 */
363 79aceca5 bellard
EXTRACT_HELPER(opc3, 6, 5);
364 79aceca5 bellard
/* Update Cr0 flags */
365 79aceca5 bellard
EXTRACT_HELPER(Rc, 0, 1);
366 79aceca5 bellard
/* Destination */
367 79aceca5 bellard
EXTRACT_HELPER(rD, 21, 5);
368 79aceca5 bellard
/* Source */
369 79aceca5 bellard
EXTRACT_HELPER(rS, 21, 5);
370 79aceca5 bellard
/* First operand */
371 79aceca5 bellard
EXTRACT_HELPER(rA, 16, 5);
372 79aceca5 bellard
/* Second operand */
373 79aceca5 bellard
EXTRACT_HELPER(rB, 11, 5);
374 79aceca5 bellard
/* Third operand */
375 79aceca5 bellard
EXTRACT_HELPER(rC, 6, 5);
376 79aceca5 bellard
/***                               Get CRn                                 ***/
377 79aceca5 bellard
EXTRACT_HELPER(crfD, 23, 3);
378 79aceca5 bellard
EXTRACT_HELPER(crfS, 18, 3);
379 79aceca5 bellard
EXTRACT_HELPER(crbD, 21, 5);
380 79aceca5 bellard
EXTRACT_HELPER(crbA, 16, 5);
381 79aceca5 bellard
EXTRACT_HELPER(crbB, 11, 5);
382 79aceca5 bellard
/* SPR / TBL */
383 3fc6c082 bellard
EXTRACT_HELPER(_SPR, 11, 10);
384 b068d6a7 j_mayer
static always_inline uint32_t SPR (uint32_t opcode)
385 3fc6c082 bellard
{
386 3fc6c082 bellard
    uint32_t sprn = _SPR(opcode);
387 3fc6c082 bellard
388 3fc6c082 bellard
    return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
389 3fc6c082 bellard
}
390 79aceca5 bellard
/***                              Get constants                            ***/
391 79aceca5 bellard
EXTRACT_HELPER(IMM, 12, 8);
392 79aceca5 bellard
/* 16 bits signed immediate value */
393 79aceca5 bellard
EXTRACT_SHELPER(SIMM, 0, 16);
394 79aceca5 bellard
/* 16 bits unsigned immediate value */
395 79aceca5 bellard
EXTRACT_HELPER(UIMM, 0, 16);
396 79aceca5 bellard
/* Bit count */
397 79aceca5 bellard
EXTRACT_HELPER(NB, 11, 5);
398 79aceca5 bellard
/* Shift count */
399 79aceca5 bellard
EXTRACT_HELPER(SH, 11, 5);
400 79aceca5 bellard
/* Mask start */
401 79aceca5 bellard
EXTRACT_HELPER(MB, 6, 5);
402 79aceca5 bellard
/* Mask end */
403 79aceca5 bellard
EXTRACT_HELPER(ME, 1, 5);
404 fb0eaffc bellard
/* Trap operand */
405 fb0eaffc bellard
EXTRACT_HELPER(TO, 21, 5);
406 79aceca5 bellard
407 79aceca5 bellard
EXTRACT_HELPER(CRM, 12, 8);
408 79aceca5 bellard
EXTRACT_HELPER(FM, 17, 8);
409 79aceca5 bellard
EXTRACT_HELPER(SR, 16, 4);
410 e4bb997e aurel32
EXTRACT_HELPER(FPIMM, 12, 4);
411 fb0eaffc bellard
412 79aceca5 bellard
/***                            Jump target decoding                       ***/
413 79aceca5 bellard
/* Displacement */
414 79aceca5 bellard
EXTRACT_SHELPER(d, 0, 16);
415 79aceca5 bellard
/* Immediate address */
416 b068d6a7 j_mayer
static always_inline target_ulong LI (uint32_t opcode)
417 79aceca5 bellard
{
418 79aceca5 bellard
    return (opcode >> 0) & 0x03FFFFFC;
419 79aceca5 bellard
}
420 79aceca5 bellard
421 b068d6a7 j_mayer
static always_inline uint32_t BD (uint32_t opcode)
422 79aceca5 bellard
{
423 79aceca5 bellard
    return (opcode >> 0) & 0xFFFC;
424 79aceca5 bellard
}
425 79aceca5 bellard
426 79aceca5 bellard
EXTRACT_HELPER(BO, 21, 5);
427 79aceca5 bellard
EXTRACT_HELPER(BI, 16, 5);
428 79aceca5 bellard
/* Absolute/relative address */
429 79aceca5 bellard
EXTRACT_HELPER(AA, 1, 1);
430 79aceca5 bellard
/* Link */
431 79aceca5 bellard
EXTRACT_HELPER(LK, 0, 1);
432 79aceca5 bellard
433 79aceca5 bellard
/* Create a mask between <start> and <end> bits */
434 b068d6a7 j_mayer
static always_inline target_ulong MASK (uint32_t start, uint32_t end)
435 79aceca5 bellard
{
436 76a66253 j_mayer
    target_ulong ret;
437 79aceca5 bellard
438 76a66253 j_mayer
#if defined(TARGET_PPC64)
439 76a66253 j_mayer
    if (likely(start == 0)) {
440 6f2d8978 j_mayer
        ret = UINT64_MAX << (63 - end);
441 76a66253 j_mayer
    } else if (likely(end == 63)) {
442 6f2d8978 j_mayer
        ret = UINT64_MAX >> start;
443 76a66253 j_mayer
    }
444 76a66253 j_mayer
#else
445 76a66253 j_mayer
    if (likely(start == 0)) {
446 6f2d8978 j_mayer
        ret = UINT32_MAX << (31  - end);
447 76a66253 j_mayer
    } else if (likely(end == 31)) {
448 6f2d8978 j_mayer
        ret = UINT32_MAX >> start;
449 76a66253 j_mayer
    }
450 76a66253 j_mayer
#endif
451 76a66253 j_mayer
    else {
452 76a66253 j_mayer
        ret = (((target_ulong)(-1ULL)) >> (start)) ^
453 76a66253 j_mayer
            (((target_ulong)(-1ULL) >> (end)) >> 1);
454 76a66253 j_mayer
        if (unlikely(start > end))
455 76a66253 j_mayer
            return ~ret;
456 76a66253 j_mayer
    }
457 79aceca5 bellard
458 79aceca5 bellard
    return ret;
459 79aceca5 bellard
}
460 79aceca5 bellard
461 a750fc0b j_mayer
/*****************************************************************************/
462 a750fc0b j_mayer
/* PowerPC Instructions types definitions                                    */
463 a750fc0b j_mayer
enum {
464 1b413d55 j_mayer
    PPC_NONE           = 0x0000000000000000ULL,
465 12de9a39 j_mayer
    /* PowerPC base instructions set                                         */
466 1b413d55 j_mayer
    PPC_INSNS_BASE     = 0x0000000000000001ULL,
467 1b413d55 j_mayer
    /*   integer operations instructions                                     */
468 a750fc0b j_mayer
#define PPC_INTEGER PPC_INSNS_BASE
469 1b413d55 j_mayer
    /*   flow control instructions                                           */
470 a750fc0b j_mayer
#define PPC_FLOW    PPC_INSNS_BASE
471 1b413d55 j_mayer
    /*   virtual memory instructions                                         */
472 a750fc0b j_mayer
#define PPC_MEM     PPC_INSNS_BASE
473 1b413d55 j_mayer
    /*   ld/st with reservation instructions                                 */
474 a750fc0b j_mayer
#define PPC_RES     PPC_INSNS_BASE
475 1b413d55 j_mayer
    /*   spr/msr access instructions                                         */
476 a750fc0b j_mayer
#define PPC_MISC    PPC_INSNS_BASE
477 1b413d55 j_mayer
    /* Deprecated instruction sets                                           */
478 1b413d55 j_mayer
    /*   Original POWER instruction set                                      */
479 f610349f j_mayer
    PPC_POWER          = 0x0000000000000002ULL,
480 1b413d55 j_mayer
    /*   POWER2 instruction set extension                                    */
481 f610349f j_mayer
    PPC_POWER2         = 0x0000000000000004ULL,
482 1b413d55 j_mayer
    /*   Power RTC support                                                   */
483 f610349f j_mayer
    PPC_POWER_RTC      = 0x0000000000000008ULL,
484 1b413d55 j_mayer
    /*   Power-to-PowerPC bridge (601)                                       */
485 f610349f j_mayer
    PPC_POWER_BR       = 0x0000000000000010ULL,
486 1b413d55 j_mayer
    /* 64 bits PowerPC instruction set                                       */
487 f610349f j_mayer
    PPC_64B            = 0x0000000000000020ULL,
488 1b413d55 j_mayer
    /*   New 64 bits extensions (PowerPC 2.0x)                               */
489 f610349f j_mayer
    PPC_64BX           = 0x0000000000000040ULL,
490 1b413d55 j_mayer
    /*   64 bits hypervisor extensions                                       */
491 f610349f j_mayer
    PPC_64H            = 0x0000000000000080ULL,
492 1b413d55 j_mayer
    /*   New wait instruction (PowerPC 2.0x)                                 */
493 f610349f j_mayer
    PPC_WAIT           = 0x0000000000000100ULL,
494 1b413d55 j_mayer
    /*   Time base mftb instruction                                          */
495 f610349f j_mayer
    PPC_MFTB           = 0x0000000000000200ULL,
496 1b413d55 j_mayer
497 1b413d55 j_mayer
    /* Fixed-point unit extensions                                           */
498 1b413d55 j_mayer
    /*   PowerPC 602 specific                                                */
499 f610349f j_mayer
    PPC_602_SPEC       = 0x0000000000000400ULL,
500 05332d70 j_mayer
    /*   isel instruction                                                    */
501 05332d70 j_mayer
    PPC_ISEL           = 0x0000000000000800ULL,
502 05332d70 j_mayer
    /*   popcntb instruction                                                 */
503 05332d70 j_mayer
    PPC_POPCNTB        = 0x0000000000001000ULL,
504 05332d70 j_mayer
    /*   string load / store                                                 */
505 05332d70 j_mayer
    PPC_STRING         = 0x0000000000002000ULL,
506 1b413d55 j_mayer
507 1b413d55 j_mayer
    /* Floating-point unit extensions                                        */
508 1b413d55 j_mayer
    /*   Optional floating point instructions                                */
509 1b413d55 j_mayer
    PPC_FLOAT          = 0x0000000000010000ULL,
510 1b413d55 j_mayer
    /* New floating-point extensions (PowerPC 2.0x)                          */
511 1b413d55 j_mayer
    PPC_FLOAT_EXT      = 0x0000000000020000ULL,
512 1b413d55 j_mayer
    PPC_FLOAT_FSQRT    = 0x0000000000040000ULL,
513 1b413d55 j_mayer
    PPC_FLOAT_FRES     = 0x0000000000080000ULL,
514 1b413d55 j_mayer
    PPC_FLOAT_FRSQRTE  = 0x0000000000100000ULL,
515 1b413d55 j_mayer
    PPC_FLOAT_FRSQRTES = 0x0000000000200000ULL,
516 1b413d55 j_mayer
    PPC_FLOAT_FSEL     = 0x0000000000400000ULL,
517 1b413d55 j_mayer
    PPC_FLOAT_STFIWX   = 0x0000000000800000ULL,
518 1b413d55 j_mayer
519 1b413d55 j_mayer
    /* Vector/SIMD extensions                                                */
520 1b413d55 j_mayer
    /*   Altivec support                                                     */
521 1b413d55 j_mayer
    PPC_ALTIVEC        = 0x0000000001000000ULL,
522 1b413d55 j_mayer
    /*   PowerPC 2.03 SPE extension                                          */
523 05332d70 j_mayer
    PPC_SPE            = 0x0000000002000000ULL,
524 1b413d55 j_mayer
    /*   PowerPC 2.03 SPE floating-point extension                           */
525 05332d70 j_mayer
    PPC_SPEFPU         = 0x0000000004000000ULL,
526 1b413d55 j_mayer
527 12de9a39 j_mayer
    /* Optional memory control instructions                                  */
528 1b413d55 j_mayer
    PPC_MEM_TLBIA      = 0x0000000010000000ULL,
529 1b413d55 j_mayer
    PPC_MEM_TLBIE      = 0x0000000020000000ULL,
530 1b413d55 j_mayer
    PPC_MEM_TLBSYNC    = 0x0000000040000000ULL,
531 1b413d55 j_mayer
    /*   sync instruction                                                    */
532 1b413d55 j_mayer
    PPC_MEM_SYNC       = 0x0000000080000000ULL,
533 1b413d55 j_mayer
    /*   eieio instruction                                                   */
534 1b413d55 j_mayer
    PPC_MEM_EIEIO      = 0x0000000100000000ULL,
535 1b413d55 j_mayer
536 1b413d55 j_mayer
    /* Cache control instructions                                            */
537 c8623f2e j_mayer
    PPC_CACHE          = 0x0000000200000000ULL,
538 1b413d55 j_mayer
    /*   icbi instruction                                                    */
539 05332d70 j_mayer
    PPC_CACHE_ICBI     = 0x0000000400000000ULL,
540 1b413d55 j_mayer
    /*   dcbz instruction with fixed cache line size                         */
541 05332d70 j_mayer
    PPC_CACHE_DCBZ     = 0x0000000800000000ULL,
542 1b413d55 j_mayer
    /*   dcbz instruction with tunable cache line size                       */
543 05332d70 j_mayer
    PPC_CACHE_DCBZT    = 0x0000001000000000ULL,
544 1b413d55 j_mayer
    /*   dcba instruction                                                    */
545 05332d70 j_mayer
    PPC_CACHE_DCBA     = 0x0000002000000000ULL,
546 05332d70 j_mayer
    /*   Freescale cache locking instructions                                */
547 05332d70 j_mayer
    PPC_CACHE_LOCK     = 0x0000004000000000ULL,
548 1b413d55 j_mayer
549 1b413d55 j_mayer
    /* MMU related extensions                                                */
550 1b413d55 j_mayer
    /*   external control instructions                                       */
551 05332d70 j_mayer
    PPC_EXTERN         = 0x0000010000000000ULL,
552 1b413d55 j_mayer
    /*   segment register access instructions                                */
553 05332d70 j_mayer
    PPC_SEGMENT        = 0x0000020000000000ULL,
554 1b413d55 j_mayer
    /*   PowerPC 6xx TLB management instructions                             */
555 05332d70 j_mayer
    PPC_6xx_TLB        = 0x0000040000000000ULL,
556 1b413d55 j_mayer
    /* PowerPC 74xx TLB management instructions                              */
557 05332d70 j_mayer
    PPC_74xx_TLB       = 0x0000080000000000ULL,
558 1b413d55 j_mayer
    /*   PowerPC 40x TLB management instructions                             */
559 05332d70 j_mayer
    PPC_40x_TLB        = 0x0000100000000000ULL,
560 1b413d55 j_mayer
    /*   segment register access instructions for PowerPC 64 "bridge"        */
561 05332d70 j_mayer
    PPC_SEGMENT_64B    = 0x0000200000000000ULL,
562 1b413d55 j_mayer
    /*   SLB management                                                      */
563 05332d70 j_mayer
    PPC_SLBI           = 0x0000400000000000ULL,
564 1b413d55 j_mayer
565 12de9a39 j_mayer
    /* Embedded PowerPC dedicated instructions                               */
566 05332d70 j_mayer
    PPC_WRTEE          = 0x0001000000000000ULL,
567 12de9a39 j_mayer
    /* PowerPC 40x exception model                                           */
568 05332d70 j_mayer
    PPC_40x_EXCP       = 0x0002000000000000ULL,
569 12de9a39 j_mayer
    /* PowerPC 405 Mac instructions                                          */
570 05332d70 j_mayer
    PPC_405_MAC        = 0x0004000000000000ULL,
571 12de9a39 j_mayer
    /* PowerPC 440 specific instructions                                     */
572 05332d70 j_mayer
    PPC_440_SPEC       = 0x0008000000000000ULL,
573 12de9a39 j_mayer
    /* BookE (embedded) PowerPC specification                                */
574 05332d70 j_mayer
    PPC_BOOKE          = 0x0010000000000000ULL,
575 05332d70 j_mayer
    /* mfapidi instruction                                                   */
576 05332d70 j_mayer
    PPC_MFAPIDI        = 0x0020000000000000ULL,
577 05332d70 j_mayer
    /* tlbiva instruction                                                    */
578 05332d70 j_mayer
    PPC_TLBIVA         = 0x0040000000000000ULL,
579 05332d70 j_mayer
    /* tlbivax instruction                                                   */
580 05332d70 j_mayer
    PPC_TLBIVAX        = 0x0080000000000000ULL,
581 12de9a39 j_mayer
    /* PowerPC 4xx dedicated instructions                                    */
582 05332d70 j_mayer
    PPC_4xx_COMMON     = 0x0100000000000000ULL,
583 12de9a39 j_mayer
    /* PowerPC 40x ibct instructions                                         */
584 05332d70 j_mayer
    PPC_40x_ICBT       = 0x0200000000000000ULL,
585 12de9a39 j_mayer
    /* rfmci is not implemented in all BookE PowerPC                         */
586 05332d70 j_mayer
    PPC_RFMCI          = 0x0400000000000000ULL,
587 05332d70 j_mayer
    /* rfdi instruction                                                      */
588 05332d70 j_mayer
    PPC_RFDI           = 0x0800000000000000ULL,
589 05332d70 j_mayer
    /* DCR accesses                                                          */
590 05332d70 j_mayer
    PPC_DCR            = 0x1000000000000000ULL,
591 05332d70 j_mayer
    /* DCR extended accesse                                                  */
592 05332d70 j_mayer
    PPC_DCRX           = 0x2000000000000000ULL,
593 12de9a39 j_mayer
    /* user-mode DCR access, implemented in PowerPC 460                      */
594 05332d70 j_mayer
    PPC_DCRUX          = 0x4000000000000000ULL,
595 a750fc0b j_mayer
};
596 a750fc0b j_mayer
597 a750fc0b j_mayer
/*****************************************************************************/
598 a750fc0b j_mayer
/* PowerPC instructions table                                                */
599 3fc6c082 bellard
#if HOST_LONG_BITS == 64
600 3fc6c082 bellard
#define OPC_ALIGN 8
601 3fc6c082 bellard
#else
602 3fc6c082 bellard
#define OPC_ALIGN 4
603 3fc6c082 bellard
#endif
604 1b039c09 bellard
#if defined(__APPLE__)
605 d9bce9d9 j_mayer
#define OPCODES_SECTION                                                       \
606 3fc6c082 bellard
    __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
607 933dc6eb bellard
#else
608 d9bce9d9 j_mayer
#define OPCODES_SECTION                                                       \
609 3fc6c082 bellard
    __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
610 933dc6eb bellard
#endif
611 933dc6eb bellard
612 76a66253 j_mayer
#if defined(DO_PPC_STATISTICS)
613 79aceca5 bellard
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
614 18fba28c bellard
OPCODES_SECTION opcode_t opc_##name = {                                       \
615 79aceca5 bellard
    .opc1 = op1,                                                              \
616 79aceca5 bellard
    .opc2 = op2,                                                              \
617 79aceca5 bellard
    .opc3 = op3,                                                              \
618 18fba28c bellard
    .pad  = { 0, },                                                           \
619 79aceca5 bellard
    .handler = {                                                              \
620 79aceca5 bellard
        .inval   = invl,                                                      \
621 9a64fbe4 bellard
        .type = _typ,                                                         \
622 79aceca5 bellard
        .handler = &gen_##name,                                               \
623 76a66253 j_mayer
        .oname = stringify(name),                                             \
624 79aceca5 bellard
    },                                                                        \
625 3fc6c082 bellard
    .oname = stringify(name),                                                 \
626 79aceca5 bellard
}
627 c7697e1f j_mayer
#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ)                    \
628 c7697e1f j_mayer
OPCODES_SECTION opcode_t opc_##name = {                                       \
629 c7697e1f j_mayer
    .opc1 = op1,                                                              \
630 c7697e1f j_mayer
    .opc2 = op2,                                                              \
631 c7697e1f j_mayer
    .opc3 = op3,                                                              \
632 c7697e1f j_mayer
    .pad  = { 0, },                                                           \
633 c7697e1f j_mayer
    .handler = {                                                              \
634 c7697e1f j_mayer
        .inval   = invl,                                                      \
635 c7697e1f j_mayer
        .type = _typ,                                                         \
636 c7697e1f j_mayer
        .handler = &gen_##name,                                               \
637 c7697e1f j_mayer
        .oname = onam,                                                        \
638 c7697e1f j_mayer
    },                                                                        \
639 c7697e1f j_mayer
    .oname = onam,                                                            \
640 c7697e1f j_mayer
}
641 76a66253 j_mayer
#else
642 76a66253 j_mayer
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
643 76a66253 j_mayer
OPCODES_SECTION opcode_t opc_##name = {                                       \
644 76a66253 j_mayer
    .opc1 = op1,                                                              \
645 76a66253 j_mayer
    .opc2 = op2,                                                              \
646 76a66253 j_mayer
    .opc3 = op3,                                                              \
647 76a66253 j_mayer
    .pad  = { 0, },                                                           \
648 76a66253 j_mayer
    .handler = {                                                              \
649 76a66253 j_mayer
        .inval   = invl,                                                      \
650 76a66253 j_mayer
        .type = _typ,                                                         \
651 76a66253 j_mayer
        .handler = &gen_##name,                                               \
652 76a66253 j_mayer
    },                                                                        \
653 76a66253 j_mayer
    .oname = stringify(name),                                                 \
654 76a66253 j_mayer
}
655 c7697e1f j_mayer
#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ)                    \
656 c7697e1f j_mayer
OPCODES_SECTION opcode_t opc_##name = {                                       \
657 c7697e1f j_mayer
    .opc1 = op1,                                                              \
658 c7697e1f j_mayer
    .opc2 = op2,                                                              \
659 c7697e1f j_mayer
    .opc3 = op3,                                                              \
660 c7697e1f j_mayer
    .pad  = { 0, },                                                           \
661 c7697e1f j_mayer
    .handler = {                                                              \
662 c7697e1f j_mayer
        .inval   = invl,                                                      \
663 c7697e1f j_mayer
        .type = _typ,                                                         \
664 c7697e1f j_mayer
        .handler = &gen_##name,                                               \
665 c7697e1f j_mayer
    },                                                                        \
666 c7697e1f j_mayer
    .oname = onam,                                                            \
667 c7697e1f j_mayer
}
668 76a66253 j_mayer
#endif
669 79aceca5 bellard
670 79aceca5 bellard
#define GEN_OPCODE_MARK(name)                                                 \
671 18fba28c bellard
OPCODES_SECTION opcode_t opc_##name = {                                       \
672 79aceca5 bellard
    .opc1 = 0xFF,                                                             \
673 79aceca5 bellard
    .opc2 = 0xFF,                                                             \
674 79aceca5 bellard
    .opc3 = 0xFF,                                                             \
675 18fba28c bellard
    .pad  = { 0, },                                                           \
676 79aceca5 bellard
    .handler = {                                                              \
677 79aceca5 bellard
        .inval   = 0x00000000,                                                \
678 9a64fbe4 bellard
        .type = 0x00,                                                         \
679 79aceca5 bellard
        .handler = NULL,                                                      \
680 79aceca5 bellard
    },                                                                        \
681 3fc6c082 bellard
    .oname = stringify(name),                                                 \
682 79aceca5 bellard
}
683 79aceca5 bellard
684 79aceca5 bellard
/* Start opcode list */
685 79aceca5 bellard
GEN_OPCODE_MARK(start);
686 79aceca5 bellard
687 79aceca5 bellard
/* Invalid instruction */
688 9a64fbe4 bellard
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
689 9a64fbe4 bellard
{
690 e1833e1f j_mayer
    GEN_EXCP_INVAL(ctx);
691 9a64fbe4 bellard
}
692 9a64fbe4 bellard
693 79aceca5 bellard
static opc_handler_t invalid_handler = {
694 79aceca5 bellard
    .inval   = 0xFFFFFFFF,
695 9a64fbe4 bellard
    .type    = PPC_NONE,
696 79aceca5 bellard
    .handler = gen_invalid,
697 79aceca5 bellard
};
698 79aceca5 bellard
699 79aceca5 bellard
/***                           Integer arithmetic                          ***/
700 d9bce9d9 j_mayer
#define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval, type)                 \
701 d9bce9d9 j_mayer
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
702 79aceca5 bellard
{                                                                             \
703 79aceca5 bellard
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
704 79aceca5 bellard
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
705 79aceca5 bellard
    gen_op_##name();                                                          \
706 79aceca5 bellard
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
707 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
708 76a66253 j_mayer
        gen_set_Rc0(ctx);                                                     \
709 79aceca5 bellard
}
710 79aceca5 bellard
711 d9bce9d9 j_mayer
#define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval, type)               \
712 d9bce9d9 j_mayer
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
713 79aceca5 bellard
{                                                                             \
714 79aceca5 bellard
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
715 79aceca5 bellard
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
716 79aceca5 bellard
    gen_op_##name();                                                          \
717 79aceca5 bellard
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
718 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
719 76a66253 j_mayer
        gen_set_Rc0(ctx);                                                     \
720 79aceca5 bellard
}
721 79aceca5 bellard
722 d9bce9d9 j_mayer
#define __GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                        \
723 d9bce9d9 j_mayer
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
724 79aceca5 bellard
{                                                                             \
725 79aceca5 bellard
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
726 79aceca5 bellard
    gen_op_##name();                                                          \
727 79aceca5 bellard
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
728 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
729 76a66253 j_mayer
        gen_set_Rc0(ctx);                                                     \
730 79aceca5 bellard
}
731 d9bce9d9 j_mayer
#define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3, type)                      \
732 d9bce9d9 j_mayer
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
733 79aceca5 bellard
{                                                                             \
734 79aceca5 bellard
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
735 79aceca5 bellard
    gen_op_##name();                                                          \
736 79aceca5 bellard
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
737 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
738 76a66253 j_mayer
        gen_set_Rc0(ctx);                                                     \
739 79aceca5 bellard
}
740 79aceca5 bellard
741 79aceca5 bellard
/* Two operands arithmetic functions */
742 d9bce9d9 j_mayer
#define GEN_INT_ARITH2(name, opc1, opc2, opc3, type)                          \
743 d9bce9d9 j_mayer
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000, type)                    \
744 d9bce9d9 j_mayer
__GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
745 d9bce9d9 j_mayer
746 d9bce9d9 j_mayer
/* Two operands arithmetic functions with no overflow allowed */
747 d9bce9d9 j_mayer
#define GEN_INT_ARITHN(name, opc1, opc2, opc3, type)                          \
748 d9bce9d9 j_mayer
__GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400, type)
749 d9bce9d9 j_mayer
750 d9bce9d9 j_mayer
/* One operand arithmetic functions */
751 d9bce9d9 j_mayer
#define GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                          \
752 d9bce9d9 j_mayer
__GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                                \
753 d9bce9d9 j_mayer
__GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10, type)
754 d9bce9d9 j_mayer
755 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
756 d9bce9d9 j_mayer
#define __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, inval, type)              \
757 d9bce9d9 j_mayer
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
758 d9bce9d9 j_mayer
{                                                                             \
759 d9bce9d9 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
760 d9bce9d9 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
761 d9bce9d9 j_mayer
    if (ctx->sf_mode)                                                         \
762 d9bce9d9 j_mayer
        gen_op_##name##_64();                                                 \
763 d9bce9d9 j_mayer
    else                                                                      \
764 d9bce9d9 j_mayer
        gen_op_##name();                                                      \
765 d9bce9d9 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
766 d9bce9d9 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
767 d9bce9d9 j_mayer
        gen_set_Rc0(ctx);                                                     \
768 d9bce9d9 j_mayer
}
769 d9bce9d9 j_mayer
770 d9bce9d9 j_mayer
#define __GEN_INT_ARITH2_O_64(name, opc1, opc2, opc3, inval, type)            \
771 d9bce9d9 j_mayer
GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
772 d9bce9d9 j_mayer
{                                                                             \
773 d9bce9d9 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
774 d9bce9d9 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
775 d9bce9d9 j_mayer
    if (ctx->sf_mode)                                                         \
776 d9bce9d9 j_mayer
        gen_op_##name##_64();                                                 \
777 d9bce9d9 j_mayer
    else                                                                      \
778 d9bce9d9 j_mayer
        gen_op_##name();                                                      \
779 d9bce9d9 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
780 d9bce9d9 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
781 d9bce9d9 j_mayer
        gen_set_Rc0(ctx);                                                     \
782 d9bce9d9 j_mayer
}
783 d9bce9d9 j_mayer
784 d9bce9d9 j_mayer
#define __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                     \
785 d9bce9d9 j_mayer
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
786 d9bce9d9 j_mayer
{                                                                             \
787 d9bce9d9 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
788 d9bce9d9 j_mayer
    if (ctx->sf_mode)                                                         \
789 d9bce9d9 j_mayer
        gen_op_##name##_64();                                                 \
790 d9bce9d9 j_mayer
    else                                                                      \
791 d9bce9d9 j_mayer
        gen_op_##name();                                                      \
792 d9bce9d9 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
793 d9bce9d9 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
794 d9bce9d9 j_mayer
        gen_set_Rc0(ctx);                                                     \
795 d9bce9d9 j_mayer
}
796 d9bce9d9 j_mayer
#define __GEN_INT_ARITH1_O_64(name, opc1, opc2, opc3, type)                   \
797 d9bce9d9 j_mayer
GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
798 d9bce9d9 j_mayer
{                                                                             \
799 d9bce9d9 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
800 d9bce9d9 j_mayer
    if (ctx->sf_mode)                                                         \
801 d9bce9d9 j_mayer
        gen_op_##name##_64();                                                 \
802 d9bce9d9 j_mayer
    else                                                                      \
803 d9bce9d9 j_mayer
        gen_op_##name();                                                      \
804 d9bce9d9 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
805 d9bce9d9 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
806 d9bce9d9 j_mayer
        gen_set_Rc0(ctx);                                                     \
807 d9bce9d9 j_mayer
}
808 d9bce9d9 j_mayer
809 d9bce9d9 j_mayer
/* Two operands arithmetic functions */
810 d9bce9d9 j_mayer
#define GEN_INT_ARITH2_64(name, opc1, opc2, opc3, type)                       \
811 d9bce9d9 j_mayer
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000000, type)                 \
812 d9bce9d9 j_mayer
__GEN_INT_ARITH2_O_64(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
813 79aceca5 bellard
814 79aceca5 bellard
/* Two operands arithmetic functions with no overflow allowed */
815 d9bce9d9 j_mayer
#define GEN_INT_ARITHN_64(name, opc1, opc2, opc3, type)                       \
816 d9bce9d9 j_mayer
__GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000400, type)
817 79aceca5 bellard
818 79aceca5 bellard
/* One operand arithmetic functions */
819 d9bce9d9 j_mayer
#define GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                       \
820 d9bce9d9 j_mayer
__GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                             \
821 d9bce9d9 j_mayer
__GEN_INT_ARITH1_O_64(name##o, opc1, opc2, opc3 | 0x10, type)
822 d9bce9d9 j_mayer
#else
823 d9bce9d9 j_mayer
#define GEN_INT_ARITH2_64 GEN_INT_ARITH2
824 d9bce9d9 j_mayer
#define GEN_INT_ARITHN_64 GEN_INT_ARITHN
825 d9bce9d9 j_mayer
#define GEN_INT_ARITH1_64 GEN_INT_ARITH1
826 d9bce9d9 j_mayer
#endif
827 79aceca5 bellard
828 79aceca5 bellard
/* add    add.    addo    addo.    */
829 b068d6a7 j_mayer
static always_inline void gen_op_addo (void)
830 d9bce9d9 j_mayer
{
831 d9bce9d9 j_mayer
    gen_op_move_T2_T0();
832 d9bce9d9 j_mayer
    gen_op_add();
833 d9bce9d9 j_mayer
    gen_op_check_addo();
834 d9bce9d9 j_mayer
}
835 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
836 d9bce9d9 j_mayer
#define gen_op_add_64 gen_op_add
837 b068d6a7 j_mayer
static always_inline void gen_op_addo_64 (void)
838 d9bce9d9 j_mayer
{
839 d9bce9d9 j_mayer
    gen_op_move_T2_T0();
840 d9bce9d9 j_mayer
    gen_op_add();
841 d9bce9d9 j_mayer
    gen_op_check_addo_64();
842 d9bce9d9 j_mayer
}
843 d9bce9d9 j_mayer
#endif
844 d9bce9d9 j_mayer
GEN_INT_ARITH2_64 (add,    0x1F, 0x0A, 0x08, PPC_INTEGER);
845 79aceca5 bellard
/* addc   addc.   addco   addco.   */
846 b068d6a7 j_mayer
static always_inline void gen_op_addc (void)
847 d9bce9d9 j_mayer
{
848 d9bce9d9 j_mayer
    gen_op_move_T2_T0();
849 d9bce9d9 j_mayer
    gen_op_add();
850 d9bce9d9 j_mayer
    gen_op_check_addc();
851 d9bce9d9 j_mayer
}
852 b068d6a7 j_mayer
static always_inline void gen_op_addco (void)
853 d9bce9d9 j_mayer
{
854 d9bce9d9 j_mayer
    gen_op_move_T2_T0();
855 d9bce9d9 j_mayer
    gen_op_add();
856 d9bce9d9 j_mayer
    gen_op_check_addc();
857 d9bce9d9 j_mayer
    gen_op_check_addo();
858 d9bce9d9 j_mayer
}
859 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
860 b068d6a7 j_mayer
static always_inline void gen_op_addc_64 (void)
861 d9bce9d9 j_mayer
{
862 d9bce9d9 j_mayer
    gen_op_move_T2_T0();
863 d9bce9d9 j_mayer
    gen_op_add();
864 d9bce9d9 j_mayer
    gen_op_check_addc_64();
865 d9bce9d9 j_mayer
}
866 b068d6a7 j_mayer
static always_inline void gen_op_addco_64 (void)
867 d9bce9d9 j_mayer
{
868 d9bce9d9 j_mayer
    gen_op_move_T2_T0();
869 d9bce9d9 j_mayer
    gen_op_add();
870 d9bce9d9 j_mayer
    gen_op_check_addc_64();
871 d9bce9d9 j_mayer
    gen_op_check_addo_64();
872 d9bce9d9 j_mayer
}
873 d9bce9d9 j_mayer
#endif
874 d9bce9d9 j_mayer
GEN_INT_ARITH2_64 (addc,   0x1F, 0x0A, 0x00, PPC_INTEGER);
875 79aceca5 bellard
/* adde   adde.   addeo   addeo.   */
876 b068d6a7 j_mayer
static always_inline void gen_op_addeo (void)
877 d9bce9d9 j_mayer
{
878 d9bce9d9 j_mayer
    gen_op_move_T2_T0();
879 d9bce9d9 j_mayer
    gen_op_adde();
880 d9bce9d9 j_mayer
    gen_op_check_addo();
881 d9bce9d9 j_mayer
}
882 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
883 b068d6a7 j_mayer
static always_inline void gen_op_addeo_64 (void)
884 d9bce9d9 j_mayer
{
885 d9bce9d9 j_mayer
    gen_op_move_T2_T0();
886 d9bce9d9 j_mayer
    gen_op_adde_64();
887 d9bce9d9 j_mayer
    gen_op_check_addo_64();
888 d9bce9d9 j_mayer
}
889 d9bce9d9 j_mayer
#endif
890 d9bce9d9 j_mayer
GEN_INT_ARITH2_64 (adde,   0x1F, 0x0A, 0x04, PPC_INTEGER);
891 79aceca5 bellard
/* addme  addme.  addmeo  addmeo.  */
892 b068d6a7 j_mayer
static always_inline void gen_op_addme (void)
893 d9bce9d9 j_mayer
{
894 d9bce9d9 j_mayer
    gen_op_move_T1_T0();
895 d9bce9d9 j_mayer
    gen_op_add_me();
896 d9bce9d9 j_mayer
}
897 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
898 b068d6a7 j_mayer
static always_inline void gen_op_addme_64 (void)
899 d9bce9d9 j_mayer
{
900 d9bce9d9 j_mayer
    gen_op_move_T1_T0();
901 d9bce9d9 j_mayer
    gen_op_add_me_64();
902 d9bce9d9 j_mayer
}
903 d9bce9d9 j_mayer
#endif
904 d9bce9d9 j_mayer
GEN_INT_ARITH1_64 (addme,  0x1F, 0x0A, 0x07, PPC_INTEGER);
905 79aceca5 bellard
/* addze  addze.  addzeo  addzeo.  */
906 b068d6a7 j_mayer
static always_inline void gen_op_addze (void)
907 d9bce9d9 j_mayer
{
908 d9bce9d9 j_mayer
    gen_op_move_T2_T0();
909 d9bce9d9 j_mayer
    gen_op_add_ze();
910 d9bce9d9 j_mayer
    gen_op_check_addc();
911 d9bce9d9 j_mayer
}
912 b068d6a7 j_mayer
static always_inline void gen_op_addzeo (void)
913 d9bce9d9 j_mayer
{
914 d9bce9d9 j_mayer
    gen_op_move_T2_T0();
915 d9bce9d9 j_mayer
    gen_op_add_ze();
916 d9bce9d9 j_mayer
    gen_op_check_addc();
917 d9bce9d9 j_mayer
    gen_op_check_addo();
918 d9bce9d9 j_mayer
}
919 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
920 b068d6a7 j_mayer
static always_inline void gen_op_addze_64 (void)
921 d9bce9d9 j_mayer
{
922 d9bce9d9 j_mayer
    gen_op_move_T2_T0();
923 d9bce9d9 j_mayer
    gen_op_add_ze();
924 d9bce9d9 j_mayer
    gen_op_check_addc_64();
925 d9bce9d9 j_mayer
}
926 b068d6a7 j_mayer
static always_inline void gen_op_addzeo_64 (void)
927 d9bce9d9 j_mayer
{
928 d9bce9d9 j_mayer
    gen_op_move_T2_T0();
929 d9bce9d9 j_mayer
    gen_op_add_ze();
930 d9bce9d9 j_mayer
    gen_op_check_addc_64();
931 d9bce9d9 j_mayer
    gen_op_check_addo_64();
932 d9bce9d9 j_mayer
}
933 d9bce9d9 j_mayer
#endif
934 d9bce9d9 j_mayer
GEN_INT_ARITH1_64 (addze,  0x1F, 0x0A, 0x06, PPC_INTEGER);
935 79aceca5 bellard
/* divw   divw.   divwo   divwo.   */
936 d9bce9d9 j_mayer
GEN_INT_ARITH2 (divw,   0x1F, 0x0B, 0x0F, PPC_INTEGER);
937 79aceca5 bellard
/* divwu  divwu.  divwuo  divwuo.  */
938 d9bce9d9 j_mayer
GEN_INT_ARITH2 (divwu,  0x1F, 0x0B, 0x0E, PPC_INTEGER);
939 79aceca5 bellard
/* mulhw  mulhw.                   */
940 d9bce9d9 j_mayer
GEN_INT_ARITHN (mulhw,  0x1F, 0x0B, 0x02, PPC_INTEGER);
941 79aceca5 bellard
/* mulhwu mulhwu.                  */
942 d9bce9d9 j_mayer
GEN_INT_ARITHN (mulhwu, 0x1F, 0x0B, 0x00, PPC_INTEGER);
943 79aceca5 bellard
/* mullw  mullw.  mullwo  mullwo.  */
944 d9bce9d9 j_mayer
GEN_INT_ARITH2 (mullw,  0x1F, 0x0B, 0x07, PPC_INTEGER);
945 79aceca5 bellard
/* neg    neg.    nego    nego.    */
946 d9bce9d9 j_mayer
GEN_INT_ARITH1_64 (neg,    0x1F, 0x08, 0x03, PPC_INTEGER);
947 79aceca5 bellard
/* subf   subf.   subfo   subfo.   */
948 b068d6a7 j_mayer
static always_inline void gen_op_subfo (void)
949 d9bce9d9 j_mayer
{
950 c3e10c7b j_mayer
    gen_op_moven_T2_T0();
951 d9bce9d9 j_mayer
    gen_op_subf();
952 c3e10c7b j_mayer
    gen_op_check_addo();
953 d9bce9d9 j_mayer
}
954 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
955 d9bce9d9 j_mayer
#define gen_op_subf_64 gen_op_subf
956 b068d6a7 j_mayer
static always_inline void gen_op_subfo_64 (void)
957 d9bce9d9 j_mayer
{
958 c3e10c7b j_mayer
    gen_op_moven_T2_T0();
959 d9bce9d9 j_mayer
    gen_op_subf();
960 c3e10c7b j_mayer
    gen_op_check_addo_64();
961 d9bce9d9 j_mayer
}
962 d9bce9d9 j_mayer
#endif
963 d9bce9d9 j_mayer
GEN_INT_ARITH2_64 (subf,   0x1F, 0x08, 0x01, PPC_INTEGER);
964 79aceca5 bellard
/* subfc  subfc.  subfco  subfco.  */
965 b068d6a7 j_mayer
static always_inline void gen_op_subfc (void)
966 d9bce9d9 j_mayer
{
967 d9bce9d9 j_mayer
    gen_op_subf();
968 d9bce9d9 j_mayer
    gen_op_check_subfc();
969 d9bce9d9 j_mayer
}
970 b068d6a7 j_mayer
static always_inline void gen_op_subfco (void)
971 d9bce9d9 j_mayer
{
972 c3e10c7b j_mayer
    gen_op_moven_T2_T0();
973 d9bce9d9 j_mayer
    gen_op_subf();
974 d9bce9d9 j_mayer
    gen_op_check_subfc();
975 c3e10c7b j_mayer
    gen_op_check_addo();
976 d9bce9d9 j_mayer
}
977 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
978 b068d6a7 j_mayer
static always_inline void gen_op_subfc_64 (void)
979 d9bce9d9 j_mayer
{
980 d9bce9d9 j_mayer
    gen_op_subf();
981 d9bce9d9 j_mayer
    gen_op_check_subfc_64();
982 d9bce9d9 j_mayer
}
983 b068d6a7 j_mayer
static always_inline void gen_op_subfco_64 (void)
984 d9bce9d9 j_mayer
{
985 c3e10c7b j_mayer
    gen_op_moven_T2_T0();
986 d9bce9d9 j_mayer
    gen_op_subf();
987 d9bce9d9 j_mayer
    gen_op_check_subfc_64();
988 c3e10c7b j_mayer
    gen_op_check_addo_64();
989 d9bce9d9 j_mayer
}
990 d9bce9d9 j_mayer
#endif
991 d9bce9d9 j_mayer
GEN_INT_ARITH2_64 (subfc,  0x1F, 0x08, 0x00, PPC_INTEGER);
992 79aceca5 bellard
/* subfe  subfe.  subfeo  subfeo.  */
993 b068d6a7 j_mayer
static always_inline void gen_op_subfeo (void)
994 d9bce9d9 j_mayer
{
995 c3e10c7b j_mayer
    gen_op_moven_T2_T0();
996 d9bce9d9 j_mayer
    gen_op_subfe();
997 c3e10c7b j_mayer
    gen_op_check_addo();
998 d9bce9d9 j_mayer
}
999 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
1000 d9bce9d9 j_mayer
#define gen_op_subfe_64 gen_op_subfe
1001 b068d6a7 j_mayer
static always_inline void gen_op_subfeo_64 (void)
1002 d9bce9d9 j_mayer
{
1003 c3e10c7b j_mayer
    gen_op_moven_T2_T0();
1004 d9bce9d9 j_mayer
    gen_op_subfe_64();
1005 c3e10c7b j_mayer
    gen_op_check_addo_64();
1006 d9bce9d9 j_mayer
}
1007 d9bce9d9 j_mayer
#endif
1008 d9bce9d9 j_mayer
GEN_INT_ARITH2_64 (subfe,  0x1F, 0x08, 0x04, PPC_INTEGER);
1009 79aceca5 bellard
/* subfme subfme. subfmeo subfmeo. */
1010 d9bce9d9 j_mayer
GEN_INT_ARITH1_64 (subfme, 0x1F, 0x08, 0x07, PPC_INTEGER);
1011 79aceca5 bellard
/* subfze subfze. subfzeo subfzeo. */
1012 d9bce9d9 j_mayer
GEN_INT_ARITH1_64 (subfze, 0x1F, 0x08, 0x06, PPC_INTEGER);
1013 79aceca5 bellard
/* addi */
1014 79aceca5 bellard
GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1015 79aceca5 bellard
{
1016 76a66253 j_mayer
    target_long simm = SIMM(ctx->opcode);
1017 79aceca5 bellard
1018 79aceca5 bellard
    if (rA(ctx->opcode) == 0) {
1019 76a66253 j_mayer
        /* li case */
1020 d9bce9d9 j_mayer
        gen_set_T0(simm);
1021 79aceca5 bellard
    } else {
1022 79aceca5 bellard
        gen_op_load_gpr_T0(rA(ctx->opcode));
1023 76a66253 j_mayer
        if (likely(simm != 0))
1024 76a66253 j_mayer
            gen_op_addi(simm);
1025 79aceca5 bellard
    }
1026 79aceca5 bellard
    gen_op_store_T0_gpr(rD(ctx->opcode));
1027 79aceca5 bellard
}
1028 79aceca5 bellard
/* addic */
1029 79aceca5 bellard
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1030 79aceca5 bellard
{
1031 76a66253 j_mayer
    target_long simm = SIMM(ctx->opcode);
1032 76a66253 j_mayer
1033 79aceca5 bellard
    gen_op_load_gpr_T0(rA(ctx->opcode));
1034 d9bce9d9 j_mayer
    if (likely(simm != 0)) {
1035 d9bce9d9 j_mayer
        gen_op_move_T2_T0();
1036 d9bce9d9 j_mayer
        gen_op_addi(simm);
1037 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
1038 d9bce9d9 j_mayer
        if (ctx->sf_mode)
1039 d9bce9d9 j_mayer
            gen_op_check_addc_64();
1040 d9bce9d9 j_mayer
        else
1041 d9bce9d9 j_mayer
#endif
1042 d9bce9d9 j_mayer
            gen_op_check_addc();
1043 e864cabd j_mayer
    } else {
1044 e864cabd j_mayer
        gen_op_clear_xer_ca();
1045 d9bce9d9 j_mayer
    }
1046 79aceca5 bellard
    gen_op_store_T0_gpr(rD(ctx->opcode));
1047 79aceca5 bellard
}
1048 79aceca5 bellard
/* addic. */
1049 c7697e1f j_mayer
GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1050 79aceca5 bellard
{
1051 76a66253 j_mayer
    target_long simm = SIMM(ctx->opcode);
1052 76a66253 j_mayer
1053 79aceca5 bellard
    gen_op_load_gpr_T0(rA(ctx->opcode));
1054 d9bce9d9 j_mayer
    if (likely(simm != 0)) {
1055 d9bce9d9 j_mayer
        gen_op_move_T2_T0();
1056 d9bce9d9 j_mayer
        gen_op_addi(simm);
1057 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
1058 d9bce9d9 j_mayer
        if (ctx->sf_mode)
1059 d9bce9d9 j_mayer
            gen_op_check_addc_64();
1060 d9bce9d9 j_mayer
        else
1061 d9bce9d9 j_mayer
#endif
1062 d9bce9d9 j_mayer
            gen_op_check_addc();
1063 966439a6 j_mayer
    } else {
1064 966439a6 j_mayer
        gen_op_clear_xer_ca();
1065 d9bce9d9 j_mayer
    }
1066 79aceca5 bellard
    gen_op_store_T0_gpr(rD(ctx->opcode));
1067 76a66253 j_mayer
    gen_set_Rc0(ctx);
1068 79aceca5 bellard
}
1069 79aceca5 bellard
/* addis */
1070 79aceca5 bellard
GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1071 79aceca5 bellard
{
1072 76a66253 j_mayer
    target_long simm = SIMM(ctx->opcode);
1073 79aceca5 bellard
1074 79aceca5 bellard
    if (rA(ctx->opcode) == 0) {
1075 76a66253 j_mayer
        /* lis case */
1076 d9bce9d9 j_mayer
        gen_set_T0(simm << 16);
1077 79aceca5 bellard
    } else {
1078 79aceca5 bellard
        gen_op_load_gpr_T0(rA(ctx->opcode));
1079 76a66253 j_mayer
        if (likely(simm != 0))
1080 76a66253 j_mayer
            gen_op_addi(simm << 16);
1081 79aceca5 bellard
    }
1082 79aceca5 bellard
    gen_op_store_T0_gpr(rD(ctx->opcode));
1083 79aceca5 bellard
}
1084 79aceca5 bellard
/* mulli */
1085 79aceca5 bellard
GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1086 79aceca5 bellard
{
1087 79aceca5 bellard
    gen_op_load_gpr_T0(rA(ctx->opcode));
1088 79aceca5 bellard
    gen_op_mulli(SIMM(ctx->opcode));
1089 79aceca5 bellard
    gen_op_store_T0_gpr(rD(ctx->opcode));
1090 79aceca5 bellard
}
1091 79aceca5 bellard
/* subfic */
1092 79aceca5 bellard
GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1093 79aceca5 bellard
{
1094 79aceca5 bellard
    gen_op_load_gpr_T0(rA(ctx->opcode));
1095 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
1096 d9bce9d9 j_mayer
    if (ctx->sf_mode)
1097 d9bce9d9 j_mayer
        gen_op_subfic_64(SIMM(ctx->opcode));
1098 d9bce9d9 j_mayer
    else
1099 d9bce9d9 j_mayer
#endif
1100 d9bce9d9 j_mayer
        gen_op_subfic(SIMM(ctx->opcode));
1101 79aceca5 bellard
    gen_op_store_T0_gpr(rD(ctx->opcode));
1102 79aceca5 bellard
}
1103 79aceca5 bellard
1104 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
1105 d9bce9d9 j_mayer
/* mulhd  mulhd.                   */
1106 a750fc0b j_mayer
GEN_INT_ARITHN (mulhd,  0x1F, 0x09, 0x02, PPC_64B);
1107 d9bce9d9 j_mayer
/* mulhdu mulhdu.                  */
1108 a750fc0b j_mayer
GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_64B);
1109 d9bce9d9 j_mayer
/* mulld  mulld.  mulldo  mulldo.  */
1110 a750fc0b j_mayer
GEN_INT_ARITH2 (mulld,  0x1F, 0x09, 0x07, PPC_64B);
1111 d9bce9d9 j_mayer
/* divd   divd.   divdo   divdo.   */
1112 a750fc0b j_mayer
GEN_INT_ARITH2 (divd,   0x1F, 0x09, 0x0F, PPC_64B);
1113 d9bce9d9 j_mayer
/* divdu  divdu.  divduo  divduo.  */
1114 a750fc0b j_mayer
GEN_INT_ARITH2 (divdu,  0x1F, 0x09, 0x0E, PPC_64B);
1115 d9bce9d9 j_mayer
#endif
1116 d9bce9d9 j_mayer
1117 79aceca5 bellard
/***                           Integer comparison                          ***/
1118 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
1119 d9bce9d9 j_mayer
#define GEN_CMP(name, opc, type)                                              \
1120 d9bce9d9 j_mayer
GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type)                          \
1121 d9bce9d9 j_mayer
{                                                                             \
1122 d9bce9d9 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1123 d9bce9d9 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1124 e3878283 j_mayer
    if (ctx->sf_mode && (ctx->opcode & 0x00200000))                           \
1125 d9bce9d9 j_mayer
        gen_op_##name##_64();                                                 \
1126 d9bce9d9 j_mayer
    else                                                                      \
1127 d9bce9d9 j_mayer
        gen_op_##name();                                                      \
1128 d9bce9d9 j_mayer
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
1129 d9bce9d9 j_mayer
}
1130 d9bce9d9 j_mayer
#else
1131 d9bce9d9 j_mayer
#define GEN_CMP(name, opc, type)                                              \
1132 d9bce9d9 j_mayer
GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type)                          \
1133 79aceca5 bellard
{                                                                             \
1134 79aceca5 bellard
    gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
1135 79aceca5 bellard
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1136 79aceca5 bellard
    gen_op_##name();                                                          \
1137 79aceca5 bellard
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
1138 79aceca5 bellard
}
1139 d9bce9d9 j_mayer
#endif
1140 79aceca5 bellard
1141 79aceca5 bellard
/* cmp */
1142 d9bce9d9 j_mayer
GEN_CMP(cmp, 0x00, PPC_INTEGER);
1143 79aceca5 bellard
/* cmpi */
1144 79aceca5 bellard
GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
1145 79aceca5 bellard
{
1146 79aceca5 bellard
    gen_op_load_gpr_T0(rA(ctx->opcode));
1147 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
1148 e3878283 j_mayer
    if (ctx->sf_mode && (ctx->opcode & 0x00200000))
1149 d9bce9d9 j_mayer
        gen_op_cmpi_64(SIMM(ctx->opcode));
1150 d9bce9d9 j_mayer
    else
1151 d9bce9d9 j_mayer
#endif
1152 d9bce9d9 j_mayer
        gen_op_cmpi(SIMM(ctx->opcode));
1153 79aceca5 bellard
    gen_op_store_T0_crf(crfD(ctx->opcode));
1154 79aceca5 bellard
}
1155 79aceca5 bellard
/* cmpl */
1156 d9bce9d9 j_mayer
GEN_CMP(cmpl, 0x01, PPC_INTEGER);
1157 79aceca5 bellard
/* cmpli */
1158 79aceca5 bellard
GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
1159 79aceca5 bellard
{
1160 79aceca5 bellard
    gen_op_load_gpr_T0(rA(ctx->opcode));
1161 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
1162 e3878283 j_mayer
    if (ctx->sf_mode && (ctx->opcode & 0x00200000))
1163 d9bce9d9 j_mayer
        gen_op_cmpli_64(UIMM(ctx->opcode));
1164 d9bce9d9 j_mayer
    else
1165 d9bce9d9 j_mayer
#endif
1166 d9bce9d9 j_mayer
        gen_op_cmpli(UIMM(ctx->opcode));
1167 79aceca5 bellard
    gen_op_store_T0_crf(crfD(ctx->opcode));
1168 79aceca5 bellard
}
1169 79aceca5 bellard
1170 d9bce9d9 j_mayer
/* isel (PowerPC 2.03 specification) */
1171 fd501a05 aurel32
GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL)
1172 d9bce9d9 j_mayer
{
1173 d9bce9d9 j_mayer
    uint32_t bi = rC(ctx->opcode);
1174 d9bce9d9 j_mayer
    uint32_t mask;
1175 d9bce9d9 j_mayer
1176 d9bce9d9 j_mayer
    if (rA(ctx->opcode) == 0) {
1177 d9bce9d9 j_mayer
        gen_set_T0(0);
1178 d9bce9d9 j_mayer
    } else {
1179 d9bce9d9 j_mayer
        gen_op_load_gpr_T1(rA(ctx->opcode));
1180 d9bce9d9 j_mayer
    }
1181 d9bce9d9 j_mayer
    gen_op_load_gpr_T2(rB(ctx->opcode));
1182 d9bce9d9 j_mayer
    mask = 1 << (3 - (bi & 0x03));
1183 d9bce9d9 j_mayer
    gen_op_load_crf_T0(bi >> 2);
1184 d9bce9d9 j_mayer
    gen_op_test_true(mask);
1185 d9bce9d9 j_mayer
    gen_op_isel();
1186 d9bce9d9 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
1187 d9bce9d9 j_mayer
}
1188 d9bce9d9 j_mayer
1189 79aceca5 bellard
/***                            Integer logical                            ***/
1190 d9bce9d9 j_mayer
#define __GEN_LOGICAL2(name, opc2, opc3, type)                                \
1191 d9bce9d9 j_mayer
GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, type)                         \
1192 79aceca5 bellard
{                                                                             \
1193 79aceca5 bellard
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
1194 79aceca5 bellard
    gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
1195 79aceca5 bellard
    gen_op_##name();                                                          \
1196 79aceca5 bellard
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1197 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1198 76a66253 j_mayer
        gen_set_Rc0(ctx);                                                     \
1199 79aceca5 bellard
}
1200 d9bce9d9 j_mayer
#define GEN_LOGICAL2(name, opc, type)                                         \
1201 d9bce9d9 j_mayer
__GEN_LOGICAL2(name, 0x1C, opc, type)
1202 79aceca5 bellard
1203 d9bce9d9 j_mayer
#define GEN_LOGICAL1(name, opc, type)                                         \
1204 d9bce9d9 j_mayer
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)                          \
1205 79aceca5 bellard
{                                                                             \
1206 79aceca5 bellard
    gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
1207 79aceca5 bellard
    gen_op_##name();                                                          \
1208 79aceca5 bellard
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1209 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1210 76a66253 j_mayer
        gen_set_Rc0(ctx);                                                     \
1211 79aceca5 bellard
}
1212 79aceca5 bellard
1213 79aceca5 bellard
/* and & and. */
1214 d9bce9d9 j_mayer
GEN_LOGICAL2(and, 0x00, PPC_INTEGER);
1215 79aceca5 bellard
/* andc & andc. */
1216 d9bce9d9 j_mayer
GEN_LOGICAL2(andc, 0x01, PPC_INTEGER);
1217 79aceca5 bellard
/* andi. */
1218 c7697e1f j_mayer
GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1219 79aceca5 bellard
{
1220 79aceca5 bellard
    gen_op_load_gpr_T0(rS(ctx->opcode));
1221 76a66253 j_mayer
    gen_op_andi_T0(UIMM(ctx->opcode));
1222 79aceca5 bellard
    gen_op_store_T0_gpr(rA(ctx->opcode));
1223 76a66253 j_mayer
    gen_set_Rc0(ctx);
1224 79aceca5 bellard
}
1225 79aceca5 bellard
/* andis. */
1226 c7697e1f j_mayer
GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1227 79aceca5 bellard
{
1228 79aceca5 bellard
    gen_op_load_gpr_T0(rS(ctx->opcode));
1229 76a66253 j_mayer
    gen_op_andi_T0(UIMM(ctx->opcode) << 16);
1230 79aceca5 bellard
    gen_op_store_T0_gpr(rA(ctx->opcode));
1231 76a66253 j_mayer
    gen_set_Rc0(ctx);
1232 79aceca5 bellard
}
1233 79aceca5 bellard
1234 79aceca5 bellard
/* cntlzw */
1235 d9bce9d9 j_mayer
GEN_LOGICAL1(cntlzw, 0x00, PPC_INTEGER);
1236 79aceca5 bellard
/* eqv & eqv. */
1237 d9bce9d9 j_mayer
GEN_LOGICAL2(eqv, 0x08, PPC_INTEGER);
1238 79aceca5 bellard
/* extsb & extsb. */
1239 d9bce9d9 j_mayer
GEN_LOGICAL1(extsb, 0x1D, PPC_INTEGER);
1240 79aceca5 bellard
/* extsh & extsh. */
1241 d9bce9d9 j_mayer
GEN_LOGICAL1(extsh, 0x1C, PPC_INTEGER);
1242 79aceca5 bellard
/* nand & nand. */
1243 d9bce9d9 j_mayer
GEN_LOGICAL2(nand, 0x0E, PPC_INTEGER);
1244 79aceca5 bellard
/* nor & nor. */
1245 d9bce9d9 j_mayer
GEN_LOGICAL2(nor, 0x03, PPC_INTEGER);
1246 9a64fbe4 bellard
1247 79aceca5 bellard
/* or & or. */
1248 9a64fbe4 bellard
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
1249 9a64fbe4 bellard
{
1250 76a66253 j_mayer
    int rs, ra, rb;
1251 76a66253 j_mayer
1252 76a66253 j_mayer
    rs = rS(ctx->opcode);
1253 76a66253 j_mayer
    ra = rA(ctx->opcode);
1254 76a66253 j_mayer
    rb = rB(ctx->opcode);
1255 76a66253 j_mayer
    /* Optimisation for mr. ri case */
1256 76a66253 j_mayer
    if (rs != ra || rs != rb) {
1257 76a66253 j_mayer
        gen_op_load_gpr_T0(rs);
1258 76a66253 j_mayer
        if (rs != rb) {
1259 76a66253 j_mayer
            gen_op_load_gpr_T1(rb);
1260 76a66253 j_mayer
            gen_op_or();
1261 76a66253 j_mayer
        }
1262 76a66253 j_mayer
        gen_op_store_T0_gpr(ra);
1263 76a66253 j_mayer
        if (unlikely(Rc(ctx->opcode) != 0))
1264 76a66253 j_mayer
            gen_set_Rc0(ctx);
1265 76a66253 j_mayer
    } else if (unlikely(Rc(ctx->opcode) != 0)) {
1266 76a66253 j_mayer
        gen_op_load_gpr_T0(rs);
1267 76a66253 j_mayer
        gen_set_Rc0(ctx);
1268 c80f84e3 j_mayer
#if defined(TARGET_PPC64)
1269 c80f84e3 j_mayer
    } else {
1270 c80f84e3 j_mayer
        switch (rs) {
1271 c80f84e3 j_mayer
        case 1:
1272 c80f84e3 j_mayer
            /* Set process priority to low */
1273 c80f84e3 j_mayer
            gen_op_store_pri(2);
1274 c80f84e3 j_mayer
            break;
1275 c80f84e3 j_mayer
        case 6:
1276 c80f84e3 j_mayer
            /* Set process priority to medium-low */
1277 c80f84e3 j_mayer
            gen_op_store_pri(3);
1278 c80f84e3 j_mayer
            break;
1279 c80f84e3 j_mayer
        case 2:
1280 c80f84e3 j_mayer
            /* Set process priority to normal */
1281 c80f84e3 j_mayer
            gen_op_store_pri(4);
1282 c80f84e3 j_mayer
            break;
1283 be147d08 j_mayer
#if !defined(CONFIG_USER_ONLY)
1284 be147d08 j_mayer
        case 31:
1285 be147d08 j_mayer
            if (ctx->supervisor > 0) {
1286 be147d08 j_mayer
                /* Set process priority to very low */
1287 be147d08 j_mayer
                gen_op_store_pri(1);
1288 be147d08 j_mayer
            }
1289 be147d08 j_mayer
            break;
1290 be147d08 j_mayer
        case 5:
1291 be147d08 j_mayer
            if (ctx->supervisor > 0) {
1292 be147d08 j_mayer
                /* Set process priority to medium-hight */
1293 be147d08 j_mayer
                gen_op_store_pri(5);
1294 be147d08 j_mayer
            }
1295 be147d08 j_mayer
            break;
1296 be147d08 j_mayer
        case 3:
1297 be147d08 j_mayer
            if (ctx->supervisor > 0) {
1298 be147d08 j_mayer
                /* Set process priority to high */
1299 be147d08 j_mayer
                gen_op_store_pri(6);
1300 be147d08 j_mayer
            }
1301 be147d08 j_mayer
            break;
1302 be147d08 j_mayer
        case 7:
1303 be147d08 j_mayer
            if (ctx->supervisor > 1) {
1304 be147d08 j_mayer
                /* Set process priority to very high */
1305 be147d08 j_mayer
                gen_op_store_pri(7);
1306 be147d08 j_mayer
            }
1307 be147d08 j_mayer
            break;
1308 be147d08 j_mayer
#endif
1309 c80f84e3 j_mayer
        default:
1310 c80f84e3 j_mayer
            /* nop */
1311 c80f84e3 j_mayer
            break;
1312 c80f84e3 j_mayer
        }
1313 c80f84e3 j_mayer
#endif
1314 9a64fbe4 bellard
    }
1315 9a64fbe4 bellard
}
1316 9a64fbe4 bellard
1317 79aceca5 bellard
/* orc & orc. */
1318 d9bce9d9 j_mayer
GEN_LOGICAL2(orc, 0x0C, PPC_INTEGER);
1319 79aceca5 bellard
/* xor & xor. */
1320 9a64fbe4 bellard
GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
1321 9a64fbe4 bellard
{
1322 9a64fbe4 bellard
    gen_op_load_gpr_T0(rS(ctx->opcode));
1323 9a64fbe4 bellard
    /* Optimisation for "set to zero" case */
1324 9a64fbe4 bellard
    if (rS(ctx->opcode) != rB(ctx->opcode)) {
1325 9a64fbe4 bellard
        gen_op_load_gpr_T1(rB(ctx->opcode));
1326 9a64fbe4 bellard
        gen_op_xor();
1327 9a64fbe4 bellard
    } else {
1328 61c04807 aurel32
        tcg_gen_movi_tl(cpu_T[0], 0);
1329 9a64fbe4 bellard
    }
1330 9a64fbe4 bellard
    gen_op_store_T0_gpr(rA(ctx->opcode));
1331 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
1332 76a66253 j_mayer
        gen_set_Rc0(ctx);
1333 9a64fbe4 bellard
}
1334 79aceca5 bellard
/* ori */
1335 79aceca5 bellard
GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1336 79aceca5 bellard
{
1337 76a66253 j_mayer
    target_ulong uimm = UIMM(ctx->opcode);
1338 79aceca5 bellard
1339 9a64fbe4 bellard
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1340 9a64fbe4 bellard
        /* NOP */
1341 76a66253 j_mayer
        /* XXX: should handle special NOPs for POWER series */
1342 9a64fbe4 bellard
        return;
1343 76a66253 j_mayer
    }
1344 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
1345 76a66253 j_mayer
    if (likely(uimm != 0))
1346 79aceca5 bellard
        gen_op_ori(uimm);
1347 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
1348 79aceca5 bellard
}
1349 79aceca5 bellard
/* oris */
1350 79aceca5 bellard
GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1351 79aceca5 bellard
{
1352 76a66253 j_mayer
    target_ulong uimm = UIMM(ctx->opcode);
1353 79aceca5 bellard
1354 9a64fbe4 bellard
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1355 9a64fbe4 bellard
        /* NOP */
1356 9a64fbe4 bellard
        return;
1357 76a66253 j_mayer
    }
1358 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
1359 76a66253 j_mayer
    if (likely(uimm != 0))
1360 79aceca5 bellard
        gen_op_ori(uimm << 16);
1361 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
1362 79aceca5 bellard
}
1363 79aceca5 bellard
/* xori */
1364 79aceca5 bellard
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1365 79aceca5 bellard
{
1366 76a66253 j_mayer
    target_ulong uimm = UIMM(ctx->opcode);
1367 9a64fbe4 bellard
1368 9a64fbe4 bellard
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1369 9a64fbe4 bellard
        /* NOP */
1370 9a64fbe4 bellard
        return;
1371 9a64fbe4 bellard
    }
1372 79aceca5 bellard
    gen_op_load_gpr_T0(rS(ctx->opcode));
1373 76a66253 j_mayer
    if (likely(uimm != 0))
1374 76a66253 j_mayer
        gen_op_xori(uimm);
1375 79aceca5 bellard
    gen_op_store_T0_gpr(rA(ctx->opcode));
1376 79aceca5 bellard
}
1377 79aceca5 bellard
1378 79aceca5 bellard
/* xoris */
1379 79aceca5 bellard
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1380 79aceca5 bellard
{
1381 76a66253 j_mayer
    target_ulong uimm = UIMM(ctx->opcode);
1382 9a64fbe4 bellard
1383 9a64fbe4 bellard
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1384 9a64fbe4 bellard
        /* NOP */
1385 9a64fbe4 bellard
        return;
1386 9a64fbe4 bellard
    }
1387 79aceca5 bellard
    gen_op_load_gpr_T0(rS(ctx->opcode));
1388 76a66253 j_mayer
    if (likely(uimm != 0))
1389 76a66253 j_mayer
        gen_op_xori(uimm << 16);
1390 79aceca5 bellard
    gen_op_store_T0_gpr(rA(ctx->opcode));
1391 79aceca5 bellard
}
1392 79aceca5 bellard
1393 d9bce9d9 j_mayer
/* popcntb : PowerPC 2.03 specification */
1394 05332d70 j_mayer
GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB)
1395 d9bce9d9 j_mayer
{
1396 d9bce9d9 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
1397 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
1398 d9bce9d9 j_mayer
    if (ctx->sf_mode)
1399 61c04807 aurel32
        tcg_gen_helper_1_1(do_popcntb_64, cpu_T[0], cpu_T[0]);
1400 d9bce9d9 j_mayer
    else
1401 d9bce9d9 j_mayer
#endif
1402 61c04807 aurel32
        tcg_gen_helper_1_1(do_popcntb, cpu_T[0], cpu_T[0]);
1403 d9bce9d9 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
1404 d9bce9d9 j_mayer
}
1405 d9bce9d9 j_mayer
1406 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
1407 d9bce9d9 j_mayer
/* extsw & extsw. */
1408 d9bce9d9 j_mayer
GEN_LOGICAL1(extsw, 0x1E, PPC_64B);
1409 d9bce9d9 j_mayer
/* cntlzd */
1410 d9bce9d9 j_mayer
GEN_LOGICAL1(cntlzd, 0x01, PPC_64B);
1411 d9bce9d9 j_mayer
#endif
1412 d9bce9d9 j_mayer
1413 79aceca5 bellard
/***                             Integer rotate                            ***/
1414 79aceca5 bellard
/* rlwimi & rlwimi. */
1415 79aceca5 bellard
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1416 79aceca5 bellard
{
1417 76a66253 j_mayer
    target_ulong mask;
1418 76a66253 j_mayer
    uint32_t mb, me, sh;
1419 79aceca5 bellard
1420 79aceca5 bellard
    mb = MB(ctx->opcode);
1421 79aceca5 bellard
    me = ME(ctx->opcode);
1422 76a66253 j_mayer
    sh = SH(ctx->opcode);
1423 76a66253 j_mayer
    if (likely(sh == 0)) {
1424 76a66253 j_mayer
        if (likely(mb == 0 && me == 31)) {
1425 76a66253 j_mayer
            gen_op_load_gpr_T0(rS(ctx->opcode));
1426 76a66253 j_mayer
            goto do_store;
1427 76a66253 j_mayer
        } else if (likely(mb == 31 && me == 0)) {
1428 76a66253 j_mayer
            gen_op_load_gpr_T0(rA(ctx->opcode));
1429 76a66253 j_mayer
            goto do_store;
1430 76a66253 j_mayer
        }
1431 76a66253 j_mayer
        gen_op_load_gpr_T0(rS(ctx->opcode));
1432 76a66253 j_mayer
        gen_op_load_gpr_T1(rA(ctx->opcode));
1433 76a66253 j_mayer
        goto do_mask;
1434 76a66253 j_mayer
    }
1435 79aceca5 bellard
    gen_op_load_gpr_T0(rS(ctx->opcode));
1436 fb0eaffc bellard
    gen_op_load_gpr_T1(rA(ctx->opcode));
1437 76a66253 j_mayer
    gen_op_rotli32_T0(SH(ctx->opcode));
1438 76a66253 j_mayer
 do_mask:
1439 76a66253 j_mayer
#if defined(TARGET_PPC64)
1440 76a66253 j_mayer
    mb += 32;
1441 76a66253 j_mayer
    me += 32;
1442 76a66253 j_mayer
#endif
1443 76a66253 j_mayer
    mask = MASK(mb, me);
1444 76a66253 j_mayer
    gen_op_andi_T0(mask);
1445 76a66253 j_mayer
    gen_op_andi_T1(~mask);
1446 76a66253 j_mayer
    gen_op_or();
1447 76a66253 j_mayer
 do_store:
1448 79aceca5 bellard
    gen_op_store_T0_gpr(rA(ctx->opcode));
1449 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
1450 76a66253 j_mayer
        gen_set_Rc0(ctx);
1451 79aceca5 bellard
}
1452 79aceca5 bellard
/* rlwinm & rlwinm. */
1453 79aceca5 bellard
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1454 79aceca5 bellard
{
1455 79aceca5 bellard
    uint32_t mb, me, sh;
1456 3b46e624 ths
1457 79aceca5 bellard
    sh = SH(ctx->opcode);
1458 79aceca5 bellard
    mb = MB(ctx->opcode);
1459 79aceca5 bellard
    me = ME(ctx->opcode);
1460 79aceca5 bellard
    gen_op_load_gpr_T0(rS(ctx->opcode));
1461 76a66253 j_mayer
    if (likely(sh == 0)) {
1462 76a66253 j_mayer
        goto do_mask;
1463 76a66253 j_mayer
    }
1464 76a66253 j_mayer
    if (likely(mb == 0)) {
1465 76a66253 j_mayer
        if (likely(me == 31)) {
1466 76a66253 j_mayer
            gen_op_rotli32_T0(sh);
1467 76a66253 j_mayer
            goto do_store;
1468 76a66253 j_mayer
        } else if (likely(me == (31 - sh))) {
1469 76a66253 j_mayer
            gen_op_sli_T0(sh);
1470 76a66253 j_mayer
            goto do_store;
1471 79aceca5 bellard
        }
1472 76a66253 j_mayer
    } else if (likely(me == 31)) {
1473 76a66253 j_mayer
        if (likely(sh == (32 - mb))) {
1474 76a66253 j_mayer
            gen_op_srli_T0(mb);
1475 76a66253 j_mayer
            goto do_store;
1476 79aceca5 bellard
        }
1477 79aceca5 bellard
    }
1478 76a66253 j_mayer
    gen_op_rotli32_T0(sh);
1479 76a66253 j_mayer
 do_mask:
1480 76a66253 j_mayer
#if defined(TARGET_PPC64)
1481 76a66253 j_mayer
    mb += 32;
1482 76a66253 j_mayer
    me += 32;
1483 76a66253 j_mayer
#endif
1484 76a66253 j_mayer
    gen_op_andi_T0(MASK(mb, me));
1485 76a66253 j_mayer
 do_store:
1486 79aceca5 bellard
    gen_op_store_T0_gpr(rA(ctx->opcode));
1487 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
1488 76a66253 j_mayer
        gen_set_Rc0(ctx);
1489 79aceca5 bellard
}
1490 79aceca5 bellard
/* rlwnm & rlwnm. */
1491 79aceca5 bellard
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1492 79aceca5 bellard
{
1493 79aceca5 bellard
    uint32_t mb, me;
1494 79aceca5 bellard
1495 79aceca5 bellard
    mb = MB(ctx->opcode);
1496 79aceca5 bellard
    me = ME(ctx->opcode);
1497 79aceca5 bellard
    gen_op_load_gpr_T0(rS(ctx->opcode));
1498 79aceca5 bellard
    gen_op_load_gpr_T1(rB(ctx->opcode));
1499 76a66253 j_mayer
    gen_op_rotl32_T0_T1();
1500 76a66253 j_mayer
    if (unlikely(mb != 0 || me != 31)) {
1501 76a66253 j_mayer
#if defined(TARGET_PPC64)
1502 76a66253 j_mayer
        mb += 32;
1503 76a66253 j_mayer
        me += 32;
1504 76a66253 j_mayer
#endif
1505 76a66253 j_mayer
        gen_op_andi_T0(MASK(mb, me));
1506 79aceca5 bellard
    }
1507 79aceca5 bellard
    gen_op_store_T0_gpr(rA(ctx->opcode));
1508 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
1509 76a66253 j_mayer
        gen_set_Rc0(ctx);
1510 79aceca5 bellard
}
1511 79aceca5 bellard
1512 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
1513 d9bce9d9 j_mayer
#define GEN_PPC64_R2(name, opc1, opc2)                                        \
1514 c7697e1f j_mayer
GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1515 d9bce9d9 j_mayer
{                                                                             \
1516 d9bce9d9 j_mayer
    gen_##name(ctx, 0);                                                       \
1517 d9bce9d9 j_mayer
}                                                                             \
1518 c7697e1f j_mayer
GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
1519 c7697e1f j_mayer
             PPC_64B)                                                         \
1520 d9bce9d9 j_mayer
{                                                                             \
1521 d9bce9d9 j_mayer
    gen_##name(ctx, 1);                                                       \
1522 d9bce9d9 j_mayer
}
1523 d9bce9d9 j_mayer
#define GEN_PPC64_R4(name, opc1, opc2)                                        \
1524 c7697e1f j_mayer
GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
1525 d9bce9d9 j_mayer
{                                                                             \
1526 d9bce9d9 j_mayer
    gen_##name(ctx, 0, 0);                                                    \
1527 d9bce9d9 j_mayer
}                                                                             \
1528 c7697e1f j_mayer
GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
1529 c7697e1f j_mayer
             PPC_64B)                                                         \
1530 d9bce9d9 j_mayer
{                                                                             \
1531 d9bce9d9 j_mayer
    gen_##name(ctx, 0, 1);                                                    \
1532 d9bce9d9 j_mayer
}                                                                             \
1533 c7697e1f j_mayer
GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
1534 c7697e1f j_mayer
             PPC_64B)                                                         \
1535 d9bce9d9 j_mayer
{                                                                             \
1536 d9bce9d9 j_mayer
    gen_##name(ctx, 1, 0);                                                    \
1537 d9bce9d9 j_mayer
}                                                                             \
1538 c7697e1f j_mayer
GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
1539 c7697e1f j_mayer
             PPC_64B)                                                         \
1540 d9bce9d9 j_mayer
{                                                                             \
1541 d9bce9d9 j_mayer
    gen_##name(ctx, 1, 1);                                                    \
1542 d9bce9d9 j_mayer
}
1543 51789c41 j_mayer
1544 b068d6a7 j_mayer
static always_inline void gen_andi_T0_64 (DisasContext *ctx, uint64_t mask)
1545 40d0591e j_mayer
{
1546 40d0591e j_mayer
    if (mask >> 32)
1547 40d0591e j_mayer
        gen_op_andi_T0_64(mask >> 32, mask & 0xFFFFFFFF);
1548 40d0591e j_mayer
    else
1549 40d0591e j_mayer
        gen_op_andi_T0(mask);
1550 40d0591e j_mayer
}
1551 40d0591e j_mayer
1552 b068d6a7 j_mayer
static always_inline void gen_andi_T1_64 (DisasContext *ctx, uint64_t mask)
1553 40d0591e j_mayer
{
1554 40d0591e j_mayer
    if (mask >> 32)
1555 40d0591e j_mayer
        gen_op_andi_T1_64(mask >> 32, mask & 0xFFFFFFFF);
1556 40d0591e j_mayer
    else
1557 40d0591e j_mayer
        gen_op_andi_T1(mask);
1558 40d0591e j_mayer
}
1559 40d0591e j_mayer
1560 b068d6a7 j_mayer
static always_inline void gen_rldinm (DisasContext *ctx, uint32_t mb,
1561 b068d6a7 j_mayer
                                      uint32_t me, uint32_t sh)
1562 51789c41 j_mayer
{
1563 51789c41 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
1564 51789c41 j_mayer
    if (likely(sh == 0)) {
1565 51789c41 j_mayer
        goto do_mask;
1566 51789c41 j_mayer
    }
1567 51789c41 j_mayer
    if (likely(mb == 0)) {
1568 51789c41 j_mayer
        if (likely(me == 63)) {
1569 40d0591e j_mayer
            gen_op_rotli64_T0(sh);
1570 51789c41 j_mayer
            goto do_store;
1571 51789c41 j_mayer
        } else if (likely(me == (63 - sh))) {
1572 51789c41 j_mayer
            gen_op_sli_T0(sh);
1573 51789c41 j_mayer
            goto do_store;
1574 51789c41 j_mayer
        }
1575 51789c41 j_mayer
    } else if (likely(me == 63)) {
1576 51789c41 j_mayer
        if (likely(sh == (64 - mb))) {
1577 40d0591e j_mayer
            gen_op_srli_T0_64(mb);
1578 51789c41 j_mayer
            goto do_store;
1579 51789c41 j_mayer
        }
1580 51789c41 j_mayer
    }
1581 51789c41 j_mayer
    gen_op_rotli64_T0(sh);
1582 51789c41 j_mayer
 do_mask:
1583 40d0591e j_mayer
    gen_andi_T0_64(ctx, MASK(mb, me));
1584 51789c41 j_mayer
 do_store:
1585 51789c41 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
1586 51789c41 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
1587 51789c41 j_mayer
        gen_set_Rc0(ctx);
1588 51789c41 j_mayer
}
1589 d9bce9d9 j_mayer
/* rldicl - rldicl. */
1590 b068d6a7 j_mayer
static always_inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
1591 d9bce9d9 j_mayer
{
1592 51789c41 j_mayer
    uint32_t sh, mb;
1593 d9bce9d9 j_mayer
1594 9d53c753 j_mayer
    sh = SH(ctx->opcode) | (shn << 5);
1595 9d53c753 j_mayer
    mb = MB(ctx->opcode) | (mbn << 5);
1596 51789c41 j_mayer
    gen_rldinm(ctx, mb, 63, sh);
1597 d9bce9d9 j_mayer
}
1598 51789c41 j_mayer
GEN_PPC64_R4(rldicl, 0x1E, 0x00);
1599 d9bce9d9 j_mayer
/* rldicr - rldicr. */
1600 b068d6a7 j_mayer
static always_inline void gen_rldicr (DisasContext *ctx, int men, int shn)
1601 d9bce9d9 j_mayer
{
1602 51789c41 j_mayer
    uint32_t sh, me;
1603 d9bce9d9 j_mayer
1604 9d53c753 j_mayer
    sh = SH(ctx->opcode) | (shn << 5);
1605 9d53c753 j_mayer
    me = MB(ctx->opcode) | (men << 5);
1606 51789c41 j_mayer
    gen_rldinm(ctx, 0, me, sh);
1607 d9bce9d9 j_mayer
}
1608 51789c41 j_mayer
GEN_PPC64_R4(rldicr, 0x1E, 0x02);
1609 d9bce9d9 j_mayer
/* rldic - rldic. */
1610 b068d6a7 j_mayer
static always_inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
1611 d9bce9d9 j_mayer
{
1612 51789c41 j_mayer
    uint32_t sh, mb;
1613 d9bce9d9 j_mayer
1614 9d53c753 j_mayer
    sh = SH(ctx->opcode) | (shn << 5);
1615 9d53c753 j_mayer
    mb = MB(ctx->opcode) | (mbn << 5);
1616 51789c41 j_mayer
    gen_rldinm(ctx, mb, 63 - sh, sh);
1617 51789c41 j_mayer
}
1618 51789c41 j_mayer
GEN_PPC64_R4(rldic, 0x1E, 0x04);
1619 51789c41 j_mayer
1620 b068d6a7 j_mayer
static always_inline void gen_rldnm (DisasContext *ctx, uint32_t mb,
1621 b068d6a7 j_mayer
                                     uint32_t me)
1622 51789c41 j_mayer
{
1623 51789c41 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
1624 51789c41 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
1625 51789c41 j_mayer
    gen_op_rotl64_T0_T1();
1626 51789c41 j_mayer
    if (unlikely(mb != 0 || me != 63)) {
1627 40d0591e j_mayer
        gen_andi_T0_64(ctx, MASK(mb, me));
1628 51789c41 j_mayer
    }
1629 51789c41 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
1630 51789c41 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
1631 51789c41 j_mayer
        gen_set_Rc0(ctx);
1632 d9bce9d9 j_mayer
}
1633 51789c41 j_mayer
1634 d9bce9d9 j_mayer
/* rldcl - rldcl. */
1635 b068d6a7 j_mayer
static always_inline void gen_rldcl (DisasContext *ctx, int mbn)
1636 d9bce9d9 j_mayer
{
1637 51789c41 j_mayer
    uint32_t mb;
1638 d9bce9d9 j_mayer
1639 9d53c753 j_mayer
    mb = MB(ctx->opcode) | (mbn << 5);
1640 51789c41 j_mayer
    gen_rldnm(ctx, mb, 63);
1641 d9bce9d9 j_mayer
}
1642 36081602 j_mayer
GEN_PPC64_R2(rldcl, 0x1E, 0x08);
1643 d9bce9d9 j_mayer
/* rldcr - rldcr. */
1644 b068d6a7 j_mayer
static always_inline void gen_rldcr (DisasContext *ctx, int men)
1645 d9bce9d9 j_mayer
{
1646 51789c41 j_mayer
    uint32_t me;
1647 d9bce9d9 j_mayer
1648 9d53c753 j_mayer
    me = MB(ctx->opcode) | (men << 5);
1649 51789c41 j_mayer
    gen_rldnm(ctx, 0, me);
1650 d9bce9d9 j_mayer
}
1651 36081602 j_mayer
GEN_PPC64_R2(rldcr, 0x1E, 0x09);
1652 d9bce9d9 j_mayer
/* rldimi - rldimi. */
1653 b068d6a7 j_mayer
static always_inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
1654 d9bce9d9 j_mayer
{
1655 51789c41 j_mayer
    uint64_t mask;
1656 271a916e j_mayer
    uint32_t sh, mb, me;
1657 d9bce9d9 j_mayer
1658 9d53c753 j_mayer
    sh = SH(ctx->opcode) | (shn << 5);
1659 9d53c753 j_mayer
    mb = MB(ctx->opcode) | (mbn << 5);
1660 271a916e j_mayer
    me = 63 - sh;
1661 51789c41 j_mayer
    if (likely(sh == 0)) {
1662 51789c41 j_mayer
        if (likely(mb == 0)) {
1663 51789c41 j_mayer
            gen_op_load_gpr_T0(rS(ctx->opcode));
1664 51789c41 j_mayer
            goto do_store;
1665 51789c41 j_mayer
        }
1666 51789c41 j_mayer
        gen_op_load_gpr_T0(rS(ctx->opcode));
1667 51789c41 j_mayer
        gen_op_load_gpr_T1(rA(ctx->opcode));
1668 51789c41 j_mayer
        goto do_mask;
1669 51789c41 j_mayer
    }
1670 51789c41 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
1671 51789c41 j_mayer
    gen_op_load_gpr_T1(rA(ctx->opcode));
1672 40d0591e j_mayer
    gen_op_rotli64_T0(sh);
1673 51789c41 j_mayer
 do_mask:
1674 271a916e j_mayer
    mask = MASK(mb, me);
1675 40d0591e j_mayer
    gen_andi_T0_64(ctx, mask);
1676 40d0591e j_mayer
    gen_andi_T1_64(ctx, ~mask);
1677 51789c41 j_mayer
    gen_op_or();
1678 51789c41 j_mayer
 do_store:
1679 51789c41 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
1680 51789c41 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
1681 51789c41 j_mayer
        gen_set_Rc0(ctx);
1682 d9bce9d9 j_mayer
}
1683 36081602 j_mayer
GEN_PPC64_R4(rldimi, 0x1E, 0x06);
1684 d9bce9d9 j_mayer
#endif
1685 d9bce9d9 j_mayer
1686 79aceca5 bellard
/***                             Integer shift                             ***/
1687 79aceca5 bellard
/* slw & slw. */
1688 d9bce9d9 j_mayer
__GEN_LOGICAL2(slw, 0x18, 0x00, PPC_INTEGER);
1689 79aceca5 bellard
/* sraw & sraw. */
1690 d9bce9d9 j_mayer
__GEN_LOGICAL2(sraw, 0x18, 0x18, PPC_INTEGER);
1691 79aceca5 bellard
/* srawi & srawi. */
1692 79aceca5 bellard
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
1693 79aceca5 bellard
{
1694 d9bce9d9 j_mayer
    int mb, me;
1695 79aceca5 bellard
    gen_op_load_gpr_T0(rS(ctx->opcode));
1696 d9bce9d9 j_mayer
    if (SH(ctx->opcode) != 0) {
1697 d9bce9d9 j_mayer
        gen_op_move_T1_T0();
1698 d9bce9d9 j_mayer
        mb = 32 - SH(ctx->opcode);
1699 d9bce9d9 j_mayer
        me = 31;
1700 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
1701 d9bce9d9 j_mayer
        mb += 32;
1702 d9bce9d9 j_mayer
        me += 32;
1703 d9bce9d9 j_mayer
#endif
1704 d9bce9d9 j_mayer
        gen_op_srawi(SH(ctx->opcode), MASK(mb, me));
1705 d9bce9d9 j_mayer
    }
1706 79aceca5 bellard
    gen_op_store_T0_gpr(rA(ctx->opcode));
1707 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
1708 76a66253 j_mayer
        gen_set_Rc0(ctx);
1709 79aceca5 bellard
}
1710 79aceca5 bellard
/* srw & srw. */
1711 d9bce9d9 j_mayer
__GEN_LOGICAL2(srw, 0x18, 0x10, PPC_INTEGER);
1712 d9bce9d9 j_mayer
1713 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
1714 d9bce9d9 j_mayer
/* sld & sld. */
1715 d9bce9d9 j_mayer
__GEN_LOGICAL2(sld, 0x1B, 0x00, PPC_64B);
1716 d9bce9d9 j_mayer
/* srad & srad. */
1717 d9bce9d9 j_mayer
__GEN_LOGICAL2(srad, 0x1A, 0x18, PPC_64B);
1718 d9bce9d9 j_mayer
/* sradi & sradi. */
1719 b068d6a7 j_mayer
static always_inline void gen_sradi (DisasContext *ctx, int n)
1720 d9bce9d9 j_mayer
{
1721 d9bce9d9 j_mayer
    uint64_t mask;
1722 d9bce9d9 j_mayer
    int sh, mb, me;
1723 d9bce9d9 j_mayer
1724 d9bce9d9 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
1725 d9bce9d9 j_mayer
    sh = SH(ctx->opcode) + (n << 5);
1726 d9bce9d9 j_mayer
    if (sh != 0) {
1727 d9bce9d9 j_mayer
        gen_op_move_T1_T0();
1728 d9bce9d9 j_mayer
        mb = 64 - SH(ctx->opcode);
1729 d9bce9d9 j_mayer
        me = 63;
1730 d9bce9d9 j_mayer
        mask = MASK(mb, me);
1731 d9bce9d9 j_mayer
        gen_op_sradi(sh, mask >> 32, mask);
1732 d9bce9d9 j_mayer
    }
1733 d9bce9d9 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
1734 d9bce9d9 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
1735 d9bce9d9 j_mayer
        gen_set_Rc0(ctx);
1736 d9bce9d9 j_mayer
}
1737 c7697e1f j_mayer
GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B)
1738 d9bce9d9 j_mayer
{
1739 d9bce9d9 j_mayer
    gen_sradi(ctx, 0);
1740 d9bce9d9 j_mayer
}
1741 c7697e1f j_mayer
GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B)
1742 d9bce9d9 j_mayer
{
1743 d9bce9d9 j_mayer
    gen_sradi(ctx, 1);
1744 d9bce9d9 j_mayer
}
1745 d9bce9d9 j_mayer
/* srd & srd. */
1746 d9bce9d9 j_mayer
__GEN_LOGICAL2(srd, 0x1B, 0x10, PPC_64B);
1747 d9bce9d9 j_mayer
#endif
1748 79aceca5 bellard
1749 79aceca5 bellard
/***                       Floating-Point arithmetic                       ***/
1750 7c58044c j_mayer
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
1751 a750fc0b j_mayer
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)                        \
1752 9a64fbe4 bellard
{                                                                             \
1753 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1754 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);                                                  \
1755 3cc62370 bellard
        return;                                                               \
1756 3cc62370 bellard
    }                                                                         \
1757 9a64fbe4 bellard
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1758 9a64fbe4 bellard
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1759 9a64fbe4 bellard
    gen_op_load_fpr_FT2(rB(ctx->opcode));                                     \
1760 7c58044c j_mayer
    gen_reset_fpstatus();                                                     \
1761 4ecc3190 bellard
    gen_op_f##op();                                                           \
1762 4ecc3190 bellard
    if (isfloat) {                                                            \
1763 4ecc3190 bellard
        gen_op_frsp();                                                        \
1764 4ecc3190 bellard
    }                                                                         \
1765 9a64fbe4 bellard
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1766 7c58044c j_mayer
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1767 9a64fbe4 bellard
}
1768 9a64fbe4 bellard
1769 7c58044c j_mayer
#define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
1770 7c58044c j_mayer
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type);                     \
1771 7c58044c j_mayer
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
1772 9a64fbe4 bellard
1773 7c58044c j_mayer
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
1774 7c58044c j_mayer
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
1775 9a64fbe4 bellard
{                                                                             \
1776 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1777 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);                                                  \
1778 3cc62370 bellard
        return;                                                               \
1779 3cc62370 bellard
    }                                                                         \
1780 9a64fbe4 bellard
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1781 9a64fbe4 bellard
    gen_op_load_fpr_FT1(rB(ctx->opcode));                                     \
1782 7c58044c j_mayer
    gen_reset_fpstatus();                                                     \
1783 4ecc3190 bellard
    gen_op_f##op();                                                           \
1784 4ecc3190 bellard
    if (isfloat) {                                                            \
1785 4ecc3190 bellard
        gen_op_frsp();                                                        \
1786 4ecc3190 bellard
    }                                                                         \
1787 9a64fbe4 bellard
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1788 7c58044c j_mayer
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1789 9a64fbe4 bellard
}
1790 7c58044c j_mayer
#define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
1791 7c58044c j_mayer
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
1792 7c58044c j_mayer
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1793 9a64fbe4 bellard
1794 7c58044c j_mayer
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
1795 7c58044c j_mayer
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
1796 9a64fbe4 bellard
{                                                                             \
1797 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1798 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);                                                  \
1799 3cc62370 bellard
        return;                                                               \
1800 3cc62370 bellard
    }                                                                         \
1801 9a64fbe4 bellard
    gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
1802 9a64fbe4 bellard
    gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1803 7c58044c j_mayer
    gen_reset_fpstatus();                                                     \
1804 4ecc3190 bellard
    gen_op_f##op();                                                           \
1805 4ecc3190 bellard
    if (isfloat) {                                                            \
1806 4ecc3190 bellard
        gen_op_frsp();                                                        \
1807 4ecc3190 bellard
    }                                                                         \
1808 9a64fbe4 bellard
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1809 7c58044c j_mayer
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1810 9a64fbe4 bellard
}
1811 7c58044c j_mayer
#define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
1812 7c58044c j_mayer
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
1813 7c58044c j_mayer
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1814 9a64fbe4 bellard
1815 7c58044c j_mayer
#define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
1816 a750fc0b j_mayer
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)                        \
1817 9a64fbe4 bellard
{                                                                             \
1818 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1819 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);                                                  \
1820 3cc62370 bellard
        return;                                                               \
1821 3cc62370 bellard
    }                                                                         \
1822 9a64fbe4 bellard
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1823 7c58044c j_mayer
    gen_reset_fpstatus();                                                     \
1824 9a64fbe4 bellard
    gen_op_f##name();                                                         \
1825 9a64fbe4 bellard
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1826 7c58044c j_mayer
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1827 79aceca5 bellard
}
1828 79aceca5 bellard
1829 7c58044c j_mayer
#define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
1830 a750fc0b j_mayer
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)                        \
1831 9a64fbe4 bellard
{                                                                             \
1832 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1833 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);                                                  \
1834 3cc62370 bellard
        return;                                                               \
1835 3cc62370 bellard
    }                                                                         \
1836 9a64fbe4 bellard
    gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1837 7c58044c j_mayer
    gen_reset_fpstatus();                                                     \
1838 9a64fbe4 bellard
    gen_op_f##name();                                                         \
1839 9a64fbe4 bellard
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1840 7c58044c j_mayer
    gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1841 79aceca5 bellard
}
1842 79aceca5 bellard
1843 9a64fbe4 bellard
/* fadd - fadds */
1844 7c58044c j_mayer
GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
1845 4ecc3190 bellard
/* fdiv - fdivs */
1846 7c58044c j_mayer
GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
1847 4ecc3190 bellard
/* fmul - fmuls */
1848 7c58044c j_mayer
GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
1849 79aceca5 bellard
1850 d7e4b87e j_mayer
/* fre */
1851 7c58044c j_mayer
GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
1852 d7e4b87e j_mayer
1853 a750fc0b j_mayer
/* fres */
1854 7c58044c j_mayer
GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
1855 79aceca5 bellard
1856 a750fc0b j_mayer
/* frsqrte */
1857 7c58044c j_mayer
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
1858 7c58044c j_mayer
1859 7c58044c j_mayer
/* frsqrtes */
1860 7c58044c j_mayer
static always_inline void gen_op_frsqrtes (void)
1861 7c58044c j_mayer
{
1862 7c58044c j_mayer
    gen_op_frsqrte();
1863 7c58044c j_mayer
    gen_op_frsp();
1864 7c58044c j_mayer
}
1865 1b413d55 j_mayer
GEN_FLOAT_BS(rsqrtes, 0x3B, 0x1A, 1, PPC_FLOAT_FRSQRTES);
1866 79aceca5 bellard
1867 a750fc0b j_mayer
/* fsel */
1868 7c58044c j_mayer
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
1869 4ecc3190 bellard
/* fsub - fsubs */
1870 7c58044c j_mayer
GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
1871 79aceca5 bellard
/* Optional: */
1872 79aceca5 bellard
/* fsqrt */
1873 a750fc0b j_mayer
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1874 c7d344af bellard
{
1875 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
1876 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);
1877 c7d344af bellard
        return;
1878 c7d344af bellard
    }
1879 c7d344af bellard
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1880 7c58044c j_mayer
    gen_reset_fpstatus();
1881 c7d344af bellard
    gen_op_fsqrt();
1882 c7d344af bellard
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1883 7c58044c j_mayer
    gen_compute_fprf(1, Rc(ctx->opcode) != 0);
1884 c7d344af bellard
}
1885 79aceca5 bellard
1886 a750fc0b j_mayer
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1887 79aceca5 bellard
{
1888 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
1889 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);
1890 3cc62370 bellard
        return;
1891 3cc62370 bellard
    }
1892 9a64fbe4 bellard
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1893 7c58044c j_mayer
    gen_reset_fpstatus();
1894 4ecc3190 bellard
    gen_op_fsqrt();
1895 4ecc3190 bellard
    gen_op_frsp();
1896 9a64fbe4 bellard
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1897 7c58044c j_mayer
    gen_compute_fprf(1, Rc(ctx->opcode) != 0);
1898 79aceca5 bellard
}
1899 79aceca5 bellard
1900 79aceca5 bellard
/***                     Floating-Point multiply-and-add                   ***/
1901 4ecc3190 bellard
/* fmadd - fmadds */
1902 7c58044c j_mayer
GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
1903 4ecc3190 bellard
/* fmsub - fmsubs */
1904 7c58044c j_mayer
GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
1905 4ecc3190 bellard
/* fnmadd - fnmadds */
1906 7c58044c j_mayer
GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
1907 4ecc3190 bellard
/* fnmsub - fnmsubs */
1908 7c58044c j_mayer
GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
1909 79aceca5 bellard
1910 79aceca5 bellard
/***                     Floating-Point round & convert                    ***/
1911 79aceca5 bellard
/* fctiw */
1912 7c58044c j_mayer
GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
1913 79aceca5 bellard
/* fctiwz */
1914 7c58044c j_mayer
GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
1915 79aceca5 bellard
/* frsp */
1916 7c58044c j_mayer
GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
1917 426613db j_mayer
#if defined(TARGET_PPC64)
1918 426613db j_mayer
/* fcfid */
1919 7c58044c j_mayer
GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B);
1920 426613db j_mayer
/* fctid */
1921 7c58044c j_mayer
GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B);
1922 426613db j_mayer
/* fctidz */
1923 7c58044c j_mayer
GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B);
1924 426613db j_mayer
#endif
1925 79aceca5 bellard
1926 d7e4b87e j_mayer
/* frin */
1927 7c58044c j_mayer
GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
1928 d7e4b87e j_mayer
/* friz */
1929 7c58044c j_mayer
GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
1930 d7e4b87e j_mayer
/* frip */
1931 7c58044c j_mayer
GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
1932 d7e4b87e j_mayer
/* frim */
1933 7c58044c j_mayer
GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
1934 d7e4b87e j_mayer
1935 79aceca5 bellard
/***                         Floating-Point compare                        ***/
1936 79aceca5 bellard
/* fcmpo */
1937 76a66253 j_mayer
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
1938 79aceca5 bellard
{
1939 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
1940 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);
1941 3cc62370 bellard
        return;
1942 3cc62370 bellard
    }
1943 9a64fbe4 bellard
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1944 9a64fbe4 bellard
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1945 7c58044c j_mayer
    gen_reset_fpstatus();
1946 9a64fbe4 bellard
    gen_op_fcmpo();
1947 9a64fbe4 bellard
    gen_op_store_T0_crf(crfD(ctx->opcode));
1948 7c58044c j_mayer
    gen_op_float_check_status();
1949 79aceca5 bellard
}
1950 79aceca5 bellard
1951 79aceca5 bellard
/* fcmpu */
1952 76a66253 j_mayer
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
1953 79aceca5 bellard
{
1954 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
1955 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);
1956 3cc62370 bellard
        return;
1957 3cc62370 bellard
    }
1958 9a64fbe4 bellard
    gen_op_load_fpr_FT0(rA(ctx->opcode));
1959 9a64fbe4 bellard
    gen_op_load_fpr_FT1(rB(ctx->opcode));
1960 7c58044c j_mayer
    gen_reset_fpstatus();
1961 9a64fbe4 bellard
    gen_op_fcmpu();
1962 9a64fbe4 bellard
    gen_op_store_T0_crf(crfD(ctx->opcode));
1963 7c58044c j_mayer
    gen_op_float_check_status();
1964 79aceca5 bellard
}
1965 79aceca5 bellard
1966 9a64fbe4 bellard
/***                         Floating-point move                           ***/
1967 9a64fbe4 bellard
/* fabs */
1968 7c58044c j_mayer
/* XXX: beware that fabs never checks for NaNs nor update FPSCR */
1969 7c58044c j_mayer
GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT);
1970 9a64fbe4 bellard
1971 9a64fbe4 bellard
/* fmr  - fmr. */
1972 7c58044c j_mayer
/* XXX: beware that fmr never checks for NaNs nor update FPSCR */
1973 9a64fbe4 bellard
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
1974 9a64fbe4 bellard
{
1975 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
1976 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);
1977 3cc62370 bellard
        return;
1978 3cc62370 bellard
    }
1979 9a64fbe4 bellard
    gen_op_load_fpr_FT0(rB(ctx->opcode));
1980 9a64fbe4 bellard
    gen_op_store_FT0_fpr(rD(ctx->opcode));
1981 7c58044c j_mayer
    gen_compute_fprf(0, Rc(ctx->opcode) != 0);
1982 9a64fbe4 bellard
}
1983 9a64fbe4 bellard
1984 9a64fbe4 bellard
/* fnabs */
1985 7c58044c j_mayer
/* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
1986 7c58044c j_mayer
GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT);
1987 9a64fbe4 bellard
/* fneg */
1988 7c58044c j_mayer
/* XXX: beware that fneg never checks for NaNs nor update FPSCR */
1989 7c58044c j_mayer
GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT);
1990 9a64fbe4 bellard
1991 79aceca5 bellard
/***                  Floating-Point status & ctrl register                ***/
1992 79aceca5 bellard
/* mcrfs */
1993 79aceca5 bellard
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
1994 79aceca5 bellard
{
1995 7c58044c j_mayer
    int bfa;
1996 7c58044c j_mayer
1997 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
1998 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);
1999 3cc62370 bellard
        return;
2000 3cc62370 bellard
    }
2001 7c58044c j_mayer
    gen_optimize_fprf();
2002 7c58044c j_mayer
    bfa = 4 * (7 - crfS(ctx->opcode));
2003 7c58044c j_mayer
    gen_op_load_fpscr_T0(bfa);
2004 fb0eaffc bellard
    gen_op_store_T0_crf(crfD(ctx->opcode));
2005 7c58044c j_mayer
    gen_op_fpscr_resetbit(~(0xF << bfa));
2006 79aceca5 bellard
}
2007 79aceca5 bellard
2008 79aceca5 bellard
/* mffs */
2009 79aceca5 bellard
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
2010 79aceca5 bellard
{
2011 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
2012 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);
2013 3cc62370 bellard
        return;
2014 3cc62370 bellard
    }
2015 7c58044c j_mayer
    gen_optimize_fprf();
2016 7c58044c j_mayer
    gen_reset_fpstatus();
2017 7c58044c j_mayer
    gen_op_load_fpscr_FT0();
2018 fb0eaffc bellard
    gen_op_store_FT0_fpr(rD(ctx->opcode));
2019 7c58044c j_mayer
    gen_compute_fprf(0, Rc(ctx->opcode) != 0);
2020 79aceca5 bellard
}
2021 79aceca5 bellard
2022 79aceca5 bellard
/* mtfsb0 */
2023 79aceca5 bellard
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
2024 79aceca5 bellard
{
2025 fb0eaffc bellard
    uint8_t crb;
2026 3b46e624 ths
2027 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
2028 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);
2029 3cc62370 bellard
        return;
2030 3cc62370 bellard
    }
2031 7c58044c j_mayer
    crb = 32 - (crbD(ctx->opcode) >> 2);
2032 7c58044c j_mayer
    gen_optimize_fprf();
2033 7c58044c j_mayer
    gen_reset_fpstatus();
2034 7c58044c j_mayer
    if (likely(crb != 30 && crb != 29))
2035 7c58044c j_mayer
        gen_op_fpscr_resetbit(~(1 << crb));
2036 7c58044c j_mayer
    if (unlikely(Rc(ctx->opcode) != 0)) {
2037 7c58044c j_mayer
        gen_op_load_fpcc();
2038 7c58044c j_mayer
        gen_op_set_Rc0();
2039 7c58044c j_mayer
    }
2040 79aceca5 bellard
}
2041 79aceca5 bellard
2042 79aceca5 bellard
/* mtfsb1 */
2043 79aceca5 bellard
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
2044 79aceca5 bellard
{
2045 fb0eaffc bellard
    uint8_t crb;
2046 3b46e624 ths
2047 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
2048 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);
2049 3cc62370 bellard
        return;
2050 3cc62370 bellard
    }
2051 7c58044c j_mayer
    crb = 32 - (crbD(ctx->opcode) >> 2);
2052 7c58044c j_mayer
    gen_optimize_fprf();
2053 7c58044c j_mayer
    gen_reset_fpstatus();
2054 7c58044c j_mayer
    /* XXX: we pretend we can only do IEEE floating-point computations */
2055 7c58044c j_mayer
    if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI))
2056 7c58044c j_mayer
        gen_op_fpscr_setbit(crb);
2057 7c58044c j_mayer
    if (unlikely(Rc(ctx->opcode) != 0)) {
2058 7c58044c j_mayer
        gen_op_load_fpcc();
2059 7c58044c j_mayer
        gen_op_set_Rc0();
2060 7c58044c j_mayer
    }
2061 7c58044c j_mayer
    /* We can raise a differed exception */
2062 7c58044c j_mayer
    gen_op_float_check_status();
2063 79aceca5 bellard
}
2064 79aceca5 bellard
2065 79aceca5 bellard
/* mtfsf */
2066 79aceca5 bellard
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
2067 79aceca5 bellard
{
2068 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
2069 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);
2070 3cc62370 bellard
        return;
2071 3cc62370 bellard
    }
2072 7c58044c j_mayer
    gen_optimize_fprf();
2073 fb0eaffc bellard
    gen_op_load_fpr_FT0(rB(ctx->opcode));
2074 7c58044c j_mayer
    gen_reset_fpstatus();
2075 28b6751f bellard
    gen_op_store_fpscr(FM(ctx->opcode));
2076 7c58044c j_mayer
    if (unlikely(Rc(ctx->opcode) != 0)) {
2077 7c58044c j_mayer
        gen_op_load_fpcc();
2078 7c58044c j_mayer
        gen_op_set_Rc0();
2079 7c58044c j_mayer
    }
2080 7c58044c j_mayer
    /* We can raise a differed exception */
2081 7c58044c j_mayer
    gen_op_float_check_status();
2082 79aceca5 bellard
}
2083 79aceca5 bellard
2084 79aceca5 bellard
/* mtfsfi */
2085 79aceca5 bellard
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
2086 79aceca5 bellard
{
2087 7c58044c j_mayer
    int bf, sh;
2088 7c58044c j_mayer
2089 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
2090 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);
2091 3cc62370 bellard
        return;
2092 3cc62370 bellard
    }
2093 7c58044c j_mayer
    bf = crbD(ctx->opcode) >> 2;
2094 7c58044c j_mayer
    sh = 7 - bf;
2095 7c58044c j_mayer
    gen_optimize_fprf();
2096 7c58044c j_mayer
    gen_op_set_FT0(FPIMM(ctx->opcode) << (4 * sh));
2097 7c58044c j_mayer
    gen_reset_fpstatus();
2098 7c58044c j_mayer
    gen_op_store_fpscr(1 << sh);
2099 7c58044c j_mayer
    if (unlikely(Rc(ctx->opcode) != 0)) {
2100 7c58044c j_mayer
        gen_op_load_fpcc();
2101 7c58044c j_mayer
        gen_op_set_Rc0();
2102 7c58044c j_mayer
    }
2103 7c58044c j_mayer
    /* We can raise a differed exception */
2104 7c58044c j_mayer
    gen_op_float_check_status();
2105 79aceca5 bellard
}
2106 79aceca5 bellard
2107 76a66253 j_mayer
/***                           Addressing modes                            ***/
2108 76a66253 j_mayer
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
2109 b068d6a7 j_mayer
static always_inline void gen_addr_imm_index (DisasContext *ctx,
2110 b068d6a7 j_mayer
                                              target_long maskl)
2111 76a66253 j_mayer
{
2112 76a66253 j_mayer
    target_long simm = SIMM(ctx->opcode);
2113 76a66253 j_mayer
2114 be147d08 j_mayer
    simm &= ~maskl;
2115 76a66253 j_mayer
    if (rA(ctx->opcode) == 0) {
2116 d9bce9d9 j_mayer
        gen_set_T0(simm);
2117 76a66253 j_mayer
    } else {
2118 76a66253 j_mayer
        gen_op_load_gpr_T0(rA(ctx->opcode));
2119 76a66253 j_mayer
        if (likely(simm != 0))
2120 76a66253 j_mayer
            gen_op_addi(simm);
2121 76a66253 j_mayer
    }
2122 a496775f j_mayer
#ifdef DEBUG_MEMORY_ACCESSES
2123 61c04807 aurel32
    tcg_gen_helper_0_0(do_print_mem_EA);
2124 a496775f j_mayer
#endif
2125 76a66253 j_mayer
}
2126 76a66253 j_mayer
2127 b068d6a7 j_mayer
static always_inline void gen_addr_reg_index (DisasContext *ctx)
2128 76a66253 j_mayer
{
2129 76a66253 j_mayer
    if (rA(ctx->opcode) == 0) {
2130 76a66253 j_mayer
        gen_op_load_gpr_T0(rB(ctx->opcode));
2131 76a66253 j_mayer
    } else {
2132 76a66253 j_mayer
        gen_op_load_gpr_T0(rA(ctx->opcode));
2133 76a66253 j_mayer
        gen_op_load_gpr_T1(rB(ctx->opcode));
2134 76a66253 j_mayer
        gen_op_add();
2135 76a66253 j_mayer
    }
2136 a496775f j_mayer
#ifdef DEBUG_MEMORY_ACCESSES
2137 61c04807 aurel32
    tcg_gen_helper_0_0(do_print_mem_EA);
2138 a496775f j_mayer
#endif
2139 76a66253 j_mayer
}
2140 76a66253 j_mayer
2141 b068d6a7 j_mayer
static always_inline void gen_addr_register (DisasContext *ctx)
2142 76a66253 j_mayer
{
2143 76a66253 j_mayer
    if (rA(ctx->opcode) == 0) {
2144 61c04807 aurel32
        tcg_gen_movi_tl(cpu_T[0], 0);
2145 76a66253 j_mayer
    } else {
2146 76a66253 j_mayer
        gen_op_load_gpr_T0(rA(ctx->opcode));
2147 76a66253 j_mayer
    }
2148 a496775f j_mayer
#ifdef DEBUG_MEMORY_ACCESSES
2149 61c04807 aurel32
    tcg_gen_helper_0_0(do_print_mem_EA);
2150 a496775f j_mayer
#endif
2151 76a66253 j_mayer
}
2152 76a66253 j_mayer
2153 7863667f j_mayer
#if defined(TARGET_PPC64)
2154 7863667f j_mayer
#define _GEN_MEM_FUNCS(name, mode)                                            \
2155 7863667f j_mayer
    &gen_op_##name##_##mode,                                                  \
2156 7863667f j_mayer
    &gen_op_##name##_le_##mode,                                               \
2157 7863667f j_mayer
    &gen_op_##name##_64_##mode,                                               \
2158 7863667f j_mayer
    &gen_op_##name##_le_64_##mode
2159 7863667f j_mayer
#else
2160 7863667f j_mayer
#define _GEN_MEM_FUNCS(name, mode)                                            \
2161 7863667f j_mayer
    &gen_op_##name##_##mode,                                                  \
2162 7863667f j_mayer
    &gen_op_##name##_le_##mode
2163 7863667f j_mayer
#endif
2164 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
2165 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
2166 7863667f j_mayer
#define NB_MEM_FUNCS 4
2167 d9bce9d9 j_mayer
#else
2168 7863667f j_mayer
#define NB_MEM_FUNCS 2
2169 d9bce9d9 j_mayer
#endif
2170 7863667f j_mayer
#define GEN_MEM_FUNCS(name)                                                   \
2171 7863667f j_mayer
    _GEN_MEM_FUNCS(name, raw)
2172 9a64fbe4 bellard
#else
2173 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
2174 7863667f j_mayer
#define NB_MEM_FUNCS 12
2175 2857068e j_mayer
#else
2176 7863667f j_mayer
#define NB_MEM_FUNCS 6
2177 2857068e j_mayer
#endif
2178 7863667f j_mayer
#define GEN_MEM_FUNCS(name)                                                   \
2179 7863667f j_mayer
    _GEN_MEM_FUNCS(name, user),                                               \
2180 7863667f j_mayer
    _GEN_MEM_FUNCS(name, kernel),                                             \
2181 7863667f j_mayer
    _GEN_MEM_FUNCS(name, hypv)
2182 7863667f j_mayer
#endif
2183 7863667f j_mayer
2184 7863667f j_mayer
/***                             Integer load                              ***/
2185 7863667f j_mayer
#define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
2186 111bfab3 bellard
/* Byte access routine are endian safe */
2187 7863667f j_mayer
#define gen_op_lbz_le_raw       gen_op_lbz_raw
2188 7863667f j_mayer
#define gen_op_lbz_le_user      gen_op_lbz_user
2189 7863667f j_mayer
#define gen_op_lbz_le_kernel    gen_op_lbz_kernel
2190 7863667f j_mayer
#define gen_op_lbz_le_hypv      gen_op_lbz_hypv
2191 7863667f j_mayer
#define gen_op_lbz_le_64_raw    gen_op_lbz_64_raw
2192 2857068e j_mayer
#define gen_op_lbz_le_64_user   gen_op_lbz_64_user
2193 d9bce9d9 j_mayer
#define gen_op_lbz_le_64_kernel gen_op_lbz_64_kernel
2194 7863667f j_mayer
#define gen_op_lbz_le_64_hypv   gen_op_lbz_64_hypv
2195 7863667f j_mayer
#define gen_op_stb_le_raw       gen_op_stb_raw
2196 7863667f j_mayer
#define gen_op_stb_le_user      gen_op_stb_user
2197 7863667f j_mayer
#define gen_op_stb_le_kernel    gen_op_stb_kernel
2198 7863667f j_mayer
#define gen_op_stb_le_hypv      gen_op_stb_hypv
2199 7863667f j_mayer
#define gen_op_stb_le_64_raw    gen_op_stb_64_raw
2200 7863667f j_mayer
#define gen_op_stb_le_64_user   gen_op_stb_64_user
2201 7863667f j_mayer
#define gen_op_stb_le_64_kernel gen_op_stb_64_kernel
2202 7863667f j_mayer
#define gen_op_stb_le_64_hypv   gen_op_stb_64_hypv
2203 d9bce9d9 j_mayer
#define OP_LD_TABLE(width)                                                    \
2204 7863667f j_mayer
static GenOpFunc *gen_op_l##width[NB_MEM_FUNCS] = {                           \
2205 7863667f j_mayer
    GEN_MEM_FUNCS(l##width),                                                  \
2206 d9bce9d9 j_mayer
};
2207 d9bce9d9 j_mayer
#define OP_ST_TABLE(width)                                                    \
2208 7863667f j_mayer
static GenOpFunc *gen_op_st##width[NB_MEM_FUNCS] = {                          \
2209 7863667f j_mayer
    GEN_MEM_FUNCS(st##width),                                                 \
2210 d9bce9d9 j_mayer
};
2211 9a64fbe4 bellard
2212 d9bce9d9 j_mayer
#define GEN_LD(width, opc, type)                                              \
2213 d9bce9d9 j_mayer
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
2214 79aceca5 bellard
{                                                                             \
2215 9d53c753 j_mayer
    gen_addr_imm_index(ctx, 0);                                               \
2216 9a64fbe4 bellard
    op_ldst(l##width);                                                        \
2217 79aceca5 bellard
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2218 79aceca5 bellard
}
2219 79aceca5 bellard
2220 d9bce9d9 j_mayer
#define GEN_LDU(width, opc, type)                                             \
2221 d9bce9d9 j_mayer
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
2222 79aceca5 bellard
{                                                                             \
2223 76a66253 j_mayer
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2224 76a66253 j_mayer
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2225 e1833e1f j_mayer
        GEN_EXCP_INVAL(ctx);                                                  \
2226 9fddaa0c bellard
        return;                                                               \
2227 9a64fbe4 bellard
    }                                                                         \
2228 9d53c753 j_mayer
    if (type == PPC_64B)                                                      \
2229 be147d08 j_mayer
        gen_addr_imm_index(ctx, 0x03);                                        \
2230 9d53c753 j_mayer
    else                                                                      \
2231 9d53c753 j_mayer
        gen_addr_imm_index(ctx, 0);                                           \
2232 9a64fbe4 bellard
    op_ldst(l##width);                                                        \
2233 79aceca5 bellard
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2234 79aceca5 bellard
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2235 79aceca5 bellard
}
2236 79aceca5 bellard
2237 d9bce9d9 j_mayer
#define GEN_LDUX(width, opc2, opc3, type)                                     \
2238 d9bce9d9 j_mayer
GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                 \
2239 79aceca5 bellard
{                                                                             \
2240 76a66253 j_mayer
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2241 76a66253 j_mayer
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2242 e1833e1f j_mayer
        GEN_EXCP_INVAL(ctx);                                                  \
2243 9fddaa0c bellard
        return;                                                               \
2244 9a64fbe4 bellard
    }                                                                         \
2245 76a66253 j_mayer
    gen_addr_reg_index(ctx);                                                  \
2246 9a64fbe4 bellard
    op_ldst(l##width);                                                        \
2247 79aceca5 bellard
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2248 79aceca5 bellard
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2249 79aceca5 bellard
}
2250 79aceca5 bellard
2251 d9bce9d9 j_mayer
#define GEN_LDX(width, opc2, opc3, type)                                      \
2252 d9bce9d9 j_mayer
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2253 79aceca5 bellard
{                                                                             \
2254 76a66253 j_mayer
    gen_addr_reg_index(ctx);                                                  \
2255 9a64fbe4 bellard
    op_ldst(l##width);                                                        \
2256 79aceca5 bellard
    gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
2257 79aceca5 bellard
}
2258 79aceca5 bellard
2259 d9bce9d9 j_mayer
#define GEN_LDS(width, op, type)                                              \
2260 9a64fbe4 bellard
OP_LD_TABLE(width);                                                           \
2261 d9bce9d9 j_mayer
GEN_LD(width, op | 0x20, type);                                               \
2262 d9bce9d9 j_mayer
GEN_LDU(width, op | 0x21, type);                                              \
2263 d9bce9d9 j_mayer
GEN_LDUX(width, 0x17, op | 0x01, type);                                       \
2264 d9bce9d9 j_mayer
GEN_LDX(width, 0x17, op | 0x00, type)
2265 79aceca5 bellard
2266 79aceca5 bellard
/* lbz lbzu lbzux lbzx */
2267 d9bce9d9 j_mayer
GEN_LDS(bz, 0x02, PPC_INTEGER);
2268 79aceca5 bellard
/* lha lhau lhaux lhax */
2269 d9bce9d9 j_mayer
GEN_LDS(ha, 0x0A, PPC_INTEGER);
2270 79aceca5 bellard
/* lhz lhzu lhzux lhzx */
2271 d9bce9d9 j_mayer
GEN_LDS(hz, 0x08, PPC_INTEGER);
2272 79aceca5 bellard
/* lwz lwzu lwzux lwzx */
2273 d9bce9d9 j_mayer
GEN_LDS(wz, 0x00, PPC_INTEGER);
2274 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
2275 d9bce9d9 j_mayer
OP_LD_TABLE(wa);
2276 d9bce9d9 j_mayer
OP_LD_TABLE(d);
2277 d9bce9d9 j_mayer
/* lwaux */
2278 d9bce9d9 j_mayer
GEN_LDUX(wa, 0x15, 0x0B, PPC_64B);
2279 d9bce9d9 j_mayer
/* lwax */
2280 d9bce9d9 j_mayer
GEN_LDX(wa, 0x15, 0x0A, PPC_64B);
2281 d9bce9d9 j_mayer
/* ldux */
2282 d9bce9d9 j_mayer
GEN_LDUX(d, 0x15, 0x01, PPC_64B);
2283 d9bce9d9 j_mayer
/* ldx */
2284 d9bce9d9 j_mayer
GEN_LDX(d, 0x15, 0x00, PPC_64B);
2285 d9bce9d9 j_mayer
GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
2286 d9bce9d9 j_mayer
{
2287 d9bce9d9 j_mayer
    if (Rc(ctx->opcode)) {
2288 d9bce9d9 j_mayer
        if (unlikely(rA(ctx->opcode) == 0 ||
2289 d9bce9d9 j_mayer
                     rA(ctx->opcode) == rD(ctx->opcode))) {
2290 e1833e1f j_mayer
            GEN_EXCP_INVAL(ctx);
2291 d9bce9d9 j_mayer
            return;
2292 d9bce9d9 j_mayer
        }
2293 d9bce9d9 j_mayer
    }
2294 be147d08 j_mayer
    gen_addr_imm_index(ctx, 0x03);
2295 d9bce9d9 j_mayer
    if (ctx->opcode & 0x02) {
2296 d9bce9d9 j_mayer
        /* lwa (lwau is undefined) */
2297 d9bce9d9 j_mayer
        op_ldst(lwa);
2298 d9bce9d9 j_mayer
    } else {
2299 d9bce9d9 j_mayer
        /* ld - ldu */
2300 d9bce9d9 j_mayer
        op_ldst(ld);
2301 d9bce9d9 j_mayer
    }
2302 d9bce9d9 j_mayer
    gen_op_store_T1_gpr(rD(ctx->opcode));
2303 d9bce9d9 j_mayer
    if (Rc(ctx->opcode))
2304 d9bce9d9 j_mayer
        gen_op_store_T0_gpr(rA(ctx->opcode));
2305 d9bce9d9 j_mayer
}
2306 be147d08 j_mayer
/* lq */
2307 be147d08 j_mayer
GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX)
2308 be147d08 j_mayer
{
2309 be147d08 j_mayer
#if defined(CONFIG_USER_ONLY)
2310 be147d08 j_mayer
    GEN_EXCP_PRIVOPC(ctx);
2311 be147d08 j_mayer
#else
2312 be147d08 j_mayer
    int ra, rd;
2313 be147d08 j_mayer
2314 be147d08 j_mayer
    /* Restore CPU state */
2315 be147d08 j_mayer
    if (unlikely(ctx->supervisor == 0)) {
2316 be147d08 j_mayer
        GEN_EXCP_PRIVOPC(ctx);
2317 be147d08 j_mayer
        return;
2318 be147d08 j_mayer
    }
2319 be147d08 j_mayer
    ra = rA(ctx->opcode);
2320 be147d08 j_mayer
    rd = rD(ctx->opcode);
2321 be147d08 j_mayer
    if (unlikely((rd & 1) || rd == ra)) {
2322 be147d08 j_mayer
        GEN_EXCP_INVAL(ctx);
2323 be147d08 j_mayer
        return;
2324 be147d08 j_mayer
    }
2325 be147d08 j_mayer
    if (unlikely(ctx->mem_idx & 1)) {
2326 be147d08 j_mayer
        /* Little-endian mode is not handled */
2327 be147d08 j_mayer
        GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2328 be147d08 j_mayer
        return;
2329 be147d08 j_mayer
    }
2330 be147d08 j_mayer
    gen_addr_imm_index(ctx, 0x0F);
2331 be147d08 j_mayer
    op_ldst(ld);
2332 be147d08 j_mayer
    gen_op_store_T1_gpr(rd);
2333 be147d08 j_mayer
    gen_op_addi(8);
2334 be147d08 j_mayer
    op_ldst(ld);
2335 be147d08 j_mayer
    gen_op_store_T1_gpr(rd + 1);
2336 be147d08 j_mayer
#endif
2337 be147d08 j_mayer
}
2338 d9bce9d9 j_mayer
#endif
2339 79aceca5 bellard
2340 79aceca5 bellard
/***                              Integer store                            ***/
2341 d9bce9d9 j_mayer
#define GEN_ST(width, opc, type)                                              \
2342 d9bce9d9 j_mayer
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2343 79aceca5 bellard
{                                                                             \
2344 9d53c753 j_mayer
    gen_addr_imm_index(ctx, 0);                                               \
2345 9a64fbe4 bellard
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2346 9a64fbe4 bellard
    op_ldst(st##width);                                                       \
2347 79aceca5 bellard
}
2348 79aceca5 bellard
2349 d9bce9d9 j_mayer
#define GEN_STU(width, opc, type)                                             \
2350 d9bce9d9 j_mayer
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
2351 79aceca5 bellard
{                                                                             \
2352 76a66253 j_mayer
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2353 e1833e1f j_mayer
        GEN_EXCP_INVAL(ctx);                                                  \
2354 9fddaa0c bellard
        return;                                                               \
2355 9a64fbe4 bellard
    }                                                                         \
2356 9d53c753 j_mayer
    if (type == PPC_64B)                                                      \
2357 be147d08 j_mayer
        gen_addr_imm_index(ctx, 0x03);                                        \
2358 9d53c753 j_mayer
    else                                                                      \
2359 9d53c753 j_mayer
        gen_addr_imm_index(ctx, 0);                                           \
2360 79aceca5 bellard
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2361 9a64fbe4 bellard
    op_ldst(st##width);                                                       \
2362 79aceca5 bellard
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2363 79aceca5 bellard
}
2364 79aceca5 bellard
2365 d9bce9d9 j_mayer
#define GEN_STUX(width, opc2, opc3, type)                                     \
2366 d9bce9d9 j_mayer
GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                \
2367 79aceca5 bellard
{                                                                             \
2368 76a66253 j_mayer
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2369 e1833e1f j_mayer
        GEN_EXCP_INVAL(ctx);                                                  \
2370 9fddaa0c bellard
        return;                                                               \
2371 9a64fbe4 bellard
    }                                                                         \
2372 76a66253 j_mayer
    gen_addr_reg_index(ctx);                                                  \
2373 9a64fbe4 bellard
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2374 9a64fbe4 bellard
    op_ldst(st##width);                                                       \
2375 79aceca5 bellard
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2376 79aceca5 bellard
}
2377 79aceca5 bellard
2378 d9bce9d9 j_mayer
#define GEN_STX(width, opc2, opc3, type)                                      \
2379 d9bce9d9 j_mayer
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2380 79aceca5 bellard
{                                                                             \
2381 76a66253 j_mayer
    gen_addr_reg_index(ctx);                                                  \
2382 9a64fbe4 bellard
    gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
2383 9a64fbe4 bellard
    op_ldst(st##width);                                                       \
2384 79aceca5 bellard
}
2385 79aceca5 bellard
2386 d9bce9d9 j_mayer
#define GEN_STS(width, op, type)                                              \
2387 9a64fbe4 bellard
OP_ST_TABLE(width);                                                           \
2388 d9bce9d9 j_mayer
GEN_ST(width, op | 0x20, type);                                               \
2389 d9bce9d9 j_mayer
GEN_STU(width, op | 0x21, type);                                              \
2390 d9bce9d9 j_mayer
GEN_STUX(width, 0x17, op | 0x01, type);                                       \
2391 d9bce9d9 j_mayer
GEN_STX(width, 0x17, op | 0x00, type)
2392 79aceca5 bellard
2393 79aceca5 bellard
/* stb stbu stbux stbx */
2394 d9bce9d9 j_mayer
GEN_STS(b, 0x06, PPC_INTEGER);
2395 79aceca5 bellard
/* sth sthu sthux sthx */
2396 d9bce9d9 j_mayer
GEN_STS(h, 0x0C, PPC_INTEGER);
2397 79aceca5 bellard
/* stw stwu stwux stwx */
2398 d9bce9d9 j_mayer
GEN_STS(w, 0x04, PPC_INTEGER);
2399 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
2400 d9bce9d9 j_mayer
OP_ST_TABLE(d);
2401 426613db j_mayer
GEN_STUX(d, 0x15, 0x05, PPC_64B);
2402 426613db j_mayer
GEN_STX(d, 0x15, 0x04, PPC_64B);
2403 be147d08 j_mayer
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B)
2404 d9bce9d9 j_mayer
{
2405 be147d08 j_mayer
    int rs;
2406 be147d08 j_mayer
2407 be147d08 j_mayer
    rs = rS(ctx->opcode);
2408 be147d08 j_mayer
    if ((ctx->opcode & 0x3) == 0x2) {
2409 be147d08 j_mayer
#if defined(CONFIG_USER_ONLY)
2410 be147d08 j_mayer
        GEN_EXCP_PRIVOPC(ctx);
2411 be147d08 j_mayer
#else
2412 be147d08 j_mayer
        /* stq */
2413 be147d08 j_mayer
        if (unlikely(ctx->supervisor == 0)) {
2414 be147d08 j_mayer
            GEN_EXCP_PRIVOPC(ctx);
2415 be147d08 j_mayer
            return;
2416 be147d08 j_mayer
        }
2417 be147d08 j_mayer
        if (unlikely(rs & 1)) {
2418 e1833e1f j_mayer
            GEN_EXCP_INVAL(ctx);
2419 d9bce9d9 j_mayer
            return;
2420 d9bce9d9 j_mayer
        }
2421 be147d08 j_mayer
        if (unlikely(ctx->mem_idx & 1)) {
2422 be147d08 j_mayer
            /* Little-endian mode is not handled */
2423 be147d08 j_mayer
            GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2424 be147d08 j_mayer
            return;
2425 be147d08 j_mayer
        }
2426 be147d08 j_mayer
        gen_addr_imm_index(ctx, 0x03);
2427 be147d08 j_mayer
        gen_op_load_gpr_T1(rs);
2428 be147d08 j_mayer
        op_ldst(std);
2429 be147d08 j_mayer
        gen_op_addi(8);
2430 be147d08 j_mayer
        gen_op_load_gpr_T1(rs + 1);
2431 be147d08 j_mayer
        op_ldst(std);
2432 be147d08 j_mayer
#endif
2433 be147d08 j_mayer
    } else {
2434 be147d08 j_mayer
        /* std / stdu */
2435 be147d08 j_mayer
        if (Rc(ctx->opcode)) {
2436 be147d08 j_mayer
            if (unlikely(rA(ctx->opcode) == 0)) {
2437 be147d08 j_mayer
                GEN_EXCP_INVAL(ctx);
2438 be147d08 j_mayer
                return;
2439 be147d08 j_mayer
            }
2440 be147d08 j_mayer
        }
2441 be147d08 j_mayer
        gen_addr_imm_index(ctx, 0x03);
2442 be147d08 j_mayer
        gen_op_load_gpr_T1(rs);
2443 be147d08 j_mayer
        op_ldst(std);
2444 be147d08 j_mayer
        if (Rc(ctx->opcode))
2445 be147d08 j_mayer
            gen_op_store_T0_gpr(rA(ctx->opcode));
2446 d9bce9d9 j_mayer
    }
2447 d9bce9d9 j_mayer
}
2448 d9bce9d9 j_mayer
#endif
2449 79aceca5 bellard
/***                Integer load and store with byte reverse               ***/
2450 79aceca5 bellard
/* lhbrx */
2451 9a64fbe4 bellard
OP_LD_TABLE(hbr);
2452 d9bce9d9 j_mayer
GEN_LDX(hbr, 0x16, 0x18, PPC_INTEGER);
2453 79aceca5 bellard
/* lwbrx */
2454 9a64fbe4 bellard
OP_LD_TABLE(wbr);
2455 d9bce9d9 j_mayer
GEN_LDX(wbr, 0x16, 0x10, PPC_INTEGER);
2456 79aceca5 bellard
/* sthbrx */
2457 9a64fbe4 bellard
OP_ST_TABLE(hbr);
2458 d9bce9d9 j_mayer
GEN_STX(hbr, 0x16, 0x1C, PPC_INTEGER);
2459 79aceca5 bellard
/* stwbrx */
2460 9a64fbe4 bellard
OP_ST_TABLE(wbr);
2461 d9bce9d9 j_mayer
GEN_STX(wbr, 0x16, 0x14, PPC_INTEGER);
2462 79aceca5 bellard
2463 79aceca5 bellard
/***                    Integer load and store multiple                    ***/
2464 111bfab3 bellard
#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
2465 7863667f j_mayer
static GenOpFunc1 *gen_op_lmw[NB_MEM_FUNCS] = {
2466 7863667f j_mayer
    GEN_MEM_FUNCS(lmw),
2467 d9bce9d9 j_mayer
};
2468 7863667f j_mayer
static GenOpFunc1 *gen_op_stmw[NB_MEM_FUNCS] = {
2469 7863667f j_mayer
    GEN_MEM_FUNCS(stmw),
2470 d9bce9d9 j_mayer
};
2471 9a64fbe4 bellard
2472 79aceca5 bellard
/* lmw */
2473 79aceca5 bellard
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2474 79aceca5 bellard
{
2475 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
2476 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
2477 9d53c753 j_mayer
    gen_addr_imm_index(ctx, 0);
2478 9a64fbe4 bellard
    op_ldstm(lmw, rD(ctx->opcode));
2479 79aceca5 bellard
}
2480 79aceca5 bellard
2481 79aceca5 bellard
/* stmw */
2482 79aceca5 bellard
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2483 79aceca5 bellard
{
2484 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
2485 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
2486 9d53c753 j_mayer
    gen_addr_imm_index(ctx, 0);
2487 9a64fbe4 bellard
    op_ldstm(stmw, rS(ctx->opcode));
2488 79aceca5 bellard
}
2489 79aceca5 bellard
2490 79aceca5 bellard
/***                    Integer load and store strings                     ***/
2491 9a64fbe4 bellard
#define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
2492 9a64fbe4 bellard
#define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
2493 e7c24003 j_mayer
/* string load & stores are by definition endian-safe */
2494 e7c24003 j_mayer
#define gen_op_lswi_le_raw       gen_op_lswi_raw
2495 e7c24003 j_mayer
#define gen_op_lswi_le_user      gen_op_lswi_user
2496 e7c24003 j_mayer
#define gen_op_lswi_le_kernel    gen_op_lswi_kernel
2497 e7c24003 j_mayer
#define gen_op_lswi_le_hypv      gen_op_lswi_hypv
2498 e7c24003 j_mayer
#define gen_op_lswi_le_64_raw    gen_op_lswi_raw
2499 e7c24003 j_mayer
#define gen_op_lswi_le_64_user   gen_op_lswi_user
2500 e7c24003 j_mayer
#define gen_op_lswi_le_64_kernel gen_op_lswi_kernel
2501 e7c24003 j_mayer
#define gen_op_lswi_le_64_hypv   gen_op_lswi_hypv
2502 7863667f j_mayer
static GenOpFunc1 *gen_op_lswi[NB_MEM_FUNCS] = {
2503 7863667f j_mayer
    GEN_MEM_FUNCS(lswi),
2504 d9bce9d9 j_mayer
};
2505 e7c24003 j_mayer
#define gen_op_lswx_le_raw       gen_op_lswx_raw
2506 e7c24003 j_mayer
#define gen_op_lswx_le_user      gen_op_lswx_user
2507 e7c24003 j_mayer
#define gen_op_lswx_le_kernel    gen_op_lswx_kernel
2508 e7c24003 j_mayer
#define gen_op_lswx_le_hypv      gen_op_lswx_hypv
2509 e7c24003 j_mayer
#define gen_op_lswx_le_64_raw    gen_op_lswx_raw
2510 e7c24003 j_mayer
#define gen_op_lswx_le_64_user   gen_op_lswx_user
2511 e7c24003 j_mayer
#define gen_op_lswx_le_64_kernel gen_op_lswx_kernel
2512 e7c24003 j_mayer
#define gen_op_lswx_le_64_hypv   gen_op_lswx_hypv
2513 7863667f j_mayer
static GenOpFunc3 *gen_op_lswx[NB_MEM_FUNCS] = {
2514 7863667f j_mayer
    GEN_MEM_FUNCS(lswx),
2515 d9bce9d9 j_mayer
};
2516 e7c24003 j_mayer
#define gen_op_stsw_le_raw       gen_op_stsw_raw
2517 e7c24003 j_mayer
#define gen_op_stsw_le_user      gen_op_stsw_user
2518 e7c24003 j_mayer
#define gen_op_stsw_le_kernel    gen_op_stsw_kernel
2519 e7c24003 j_mayer
#define gen_op_stsw_le_hypv      gen_op_stsw_hypv
2520 e7c24003 j_mayer
#define gen_op_stsw_le_64_raw    gen_op_stsw_raw
2521 e7c24003 j_mayer
#define gen_op_stsw_le_64_user   gen_op_stsw_user
2522 e7c24003 j_mayer
#define gen_op_stsw_le_64_kernel gen_op_stsw_kernel
2523 e7c24003 j_mayer
#define gen_op_stsw_le_64_hypv   gen_op_stsw_hypv
2524 7863667f j_mayer
static GenOpFunc1 *gen_op_stsw[NB_MEM_FUNCS] = {
2525 7863667f j_mayer
    GEN_MEM_FUNCS(stsw),
2526 9a64fbe4 bellard
};
2527 9a64fbe4 bellard
2528 79aceca5 bellard
/* lswi */
2529 3fc6c082 bellard
/* PowerPC32 specification says we must generate an exception if
2530 9a64fbe4 bellard
 * rA is in the range of registers to be loaded.
2531 9a64fbe4 bellard
 * In an other hand, IBM says this is valid, but rA won't be loaded.
2532 9a64fbe4 bellard
 * For now, I'll follow the spec...
2533 9a64fbe4 bellard
 */
2534 05332d70 j_mayer
GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING)
2535 79aceca5 bellard
{
2536 79aceca5 bellard
    int nb = NB(ctx->opcode);
2537 79aceca5 bellard
    int start = rD(ctx->opcode);
2538 9a64fbe4 bellard
    int ra = rA(ctx->opcode);
2539 79aceca5 bellard
    int nr;
2540 79aceca5 bellard
2541 79aceca5 bellard
    if (nb == 0)
2542 79aceca5 bellard
        nb = 32;
2543 79aceca5 bellard
    nr = nb / 4;
2544 76a66253 j_mayer
    if (unlikely(((start + nr) > 32  &&
2545 76a66253 j_mayer
                  start <= ra && (start + nr - 32) > ra) ||
2546 76a66253 j_mayer
                 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
2547 e1833e1f j_mayer
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
2548 e1833e1f j_mayer
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX);
2549 9fddaa0c bellard
        return;
2550 297d8e62 bellard
    }
2551 8dd4983c bellard
    /* NIP cannot be restored if the memory exception comes from an helper */
2552 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
2553 76a66253 j_mayer
    gen_addr_register(ctx);
2554 76a66253 j_mayer
    gen_op_set_T1(nb);
2555 9a64fbe4 bellard
    op_ldsts(lswi, start);
2556 79aceca5 bellard
}
2557 79aceca5 bellard
2558 79aceca5 bellard
/* lswx */
2559 05332d70 j_mayer
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING)
2560 79aceca5 bellard
{
2561 9a64fbe4 bellard
    int ra = rA(ctx->opcode);
2562 9a64fbe4 bellard
    int rb = rB(ctx->opcode);
2563 9a64fbe4 bellard
2564 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
2565 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
2566 76a66253 j_mayer
    gen_addr_reg_index(ctx);
2567 9a64fbe4 bellard
    if (ra == 0) {
2568 9a64fbe4 bellard
        ra = rb;
2569 79aceca5 bellard
    }
2570 9a64fbe4 bellard
    gen_op_load_xer_bc();
2571 9a64fbe4 bellard
    op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
2572 79aceca5 bellard
}
2573 79aceca5 bellard
2574 79aceca5 bellard
/* stswi */
2575 05332d70 j_mayer
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING)
2576 79aceca5 bellard
{
2577 4b3686fa bellard
    int nb = NB(ctx->opcode);
2578 4b3686fa bellard
2579 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
2580 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
2581 76a66253 j_mayer
    gen_addr_register(ctx);
2582 4b3686fa bellard
    if (nb == 0)
2583 4b3686fa bellard
        nb = 32;
2584 4b3686fa bellard
    gen_op_set_T1(nb);
2585 9a64fbe4 bellard
    op_ldsts(stsw, rS(ctx->opcode));
2586 79aceca5 bellard
}
2587 79aceca5 bellard
2588 79aceca5 bellard
/* stswx */
2589 05332d70 j_mayer
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING)
2590 79aceca5 bellard
{
2591 8dd4983c bellard
    /* NIP cannot be restored if the memory exception comes from an helper */
2592 5fafdf24 ths
    gen_update_nip(ctx, ctx->nip - 4);
2593 76a66253 j_mayer
    gen_addr_reg_index(ctx);
2594 76a66253 j_mayer
    gen_op_load_xer_bc();
2595 9a64fbe4 bellard
    op_ldsts(stsw, rS(ctx->opcode));
2596 79aceca5 bellard
}
2597 79aceca5 bellard
2598 79aceca5 bellard
/***                        Memory synchronisation                         ***/
2599 79aceca5 bellard
/* eieio */
2600 0db1b20e j_mayer
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO)
2601 79aceca5 bellard
{
2602 79aceca5 bellard
}
2603 79aceca5 bellard
2604 79aceca5 bellard
/* isync */
2605 0db1b20e j_mayer
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM)
2606 79aceca5 bellard
{
2607 e1833e1f j_mayer
    GEN_STOP(ctx);
2608 79aceca5 bellard
}
2609 79aceca5 bellard
2610 111bfab3 bellard
#define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
2611 111bfab3 bellard
#define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
2612 7863667f j_mayer
static GenOpFunc *gen_op_lwarx[NB_MEM_FUNCS] = {
2613 7863667f j_mayer
    GEN_MEM_FUNCS(lwarx),
2614 111bfab3 bellard
};
2615 7863667f j_mayer
static GenOpFunc *gen_op_stwcx[NB_MEM_FUNCS] = {
2616 7863667f j_mayer
    GEN_MEM_FUNCS(stwcx),
2617 985a19d6 bellard
};
2618 9a64fbe4 bellard
2619 111bfab3 bellard
/* lwarx */
2620 76a66253 j_mayer
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
2621 79aceca5 bellard
{
2622 30032c94 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
2623 30032c94 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
2624 76a66253 j_mayer
    gen_addr_reg_index(ctx);
2625 985a19d6 bellard
    op_lwarx();
2626 79aceca5 bellard
    gen_op_store_T1_gpr(rD(ctx->opcode));
2627 79aceca5 bellard
}
2628 79aceca5 bellard
2629 79aceca5 bellard
/* stwcx. */
2630 c7697e1f j_mayer
GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
2631 79aceca5 bellard
{
2632 30032c94 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
2633 30032c94 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
2634 76a66253 j_mayer
    gen_addr_reg_index(ctx);
2635 9a64fbe4 bellard
    gen_op_load_gpr_T1(rS(ctx->opcode));
2636 9a64fbe4 bellard
    op_stwcx();
2637 79aceca5 bellard
}
2638 79aceca5 bellard
2639 426613db j_mayer
#if defined(TARGET_PPC64)
2640 426613db j_mayer
#define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])()
2641 426613db j_mayer
#define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])()
2642 7863667f j_mayer
static GenOpFunc *gen_op_ldarx[NB_MEM_FUNCS] = {
2643 7863667f j_mayer
    GEN_MEM_FUNCS(ldarx),
2644 426613db j_mayer
};
2645 7863667f j_mayer
static GenOpFunc *gen_op_stdcx[NB_MEM_FUNCS] = {
2646 7863667f j_mayer
    GEN_MEM_FUNCS(stdcx),
2647 426613db j_mayer
};
2648 426613db j_mayer
2649 426613db j_mayer
/* ldarx */
2650 a750fc0b j_mayer
GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
2651 426613db j_mayer
{
2652 30032c94 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
2653 30032c94 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
2654 426613db j_mayer
    gen_addr_reg_index(ctx);
2655 426613db j_mayer
    op_ldarx();
2656 426613db j_mayer
    gen_op_store_T1_gpr(rD(ctx->opcode));
2657 426613db j_mayer
}
2658 426613db j_mayer
2659 426613db j_mayer
/* stdcx. */
2660 c7697e1f j_mayer
GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
2661 426613db j_mayer
{
2662 30032c94 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
2663 30032c94 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
2664 426613db j_mayer
    gen_addr_reg_index(ctx);
2665 426613db j_mayer
    gen_op_load_gpr_T1(rS(ctx->opcode));
2666 426613db j_mayer
    op_stdcx();
2667 426613db j_mayer
}
2668 426613db j_mayer
#endif /* defined(TARGET_PPC64) */
2669 426613db j_mayer
2670 79aceca5 bellard
/* sync */
2671 a902d886 j_mayer
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC)
2672 79aceca5 bellard
{
2673 79aceca5 bellard
}
2674 79aceca5 bellard
2675 0db1b20e j_mayer
/* wait */
2676 0db1b20e j_mayer
GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT)
2677 0db1b20e j_mayer
{
2678 0db1b20e j_mayer
    /* Stop translation, as the CPU is supposed to sleep from now */
2679 be147d08 j_mayer
    gen_op_wait();
2680 be147d08 j_mayer
    GEN_EXCP(ctx, EXCP_HLT, 1);
2681 0db1b20e j_mayer
}
2682 0db1b20e j_mayer
2683 79aceca5 bellard
/***                         Floating-point load                           ***/
2684 477023a6 j_mayer
#define GEN_LDF(width, opc, type)                                             \
2685 477023a6 j_mayer
GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
2686 79aceca5 bellard
{                                                                             \
2687 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2688 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);                                                  \
2689 4ecc3190 bellard
        return;                                                               \
2690 4ecc3190 bellard
    }                                                                         \
2691 9d53c753 j_mayer
    gen_addr_imm_index(ctx, 0);                                               \
2692 9a64fbe4 bellard
    op_ldst(l##width);                                                        \
2693 76a66253 j_mayer
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2694 79aceca5 bellard
}
2695 79aceca5 bellard
2696 477023a6 j_mayer
#define GEN_LDUF(width, opc, type)                                            \
2697 477023a6 j_mayer
GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
2698 79aceca5 bellard
{                                                                             \
2699 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2700 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);                                                  \
2701 4ecc3190 bellard
        return;                                                               \
2702 4ecc3190 bellard
    }                                                                         \
2703 76a66253 j_mayer
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2704 e1833e1f j_mayer
        GEN_EXCP_INVAL(ctx);                                                  \
2705 9fddaa0c bellard
        return;                                                               \
2706 9a64fbe4 bellard
    }                                                                         \
2707 9d53c753 j_mayer
    gen_addr_imm_index(ctx, 0);                                               \
2708 9a64fbe4 bellard
    op_ldst(l##width);                                                        \
2709 76a66253 j_mayer
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2710 79aceca5 bellard
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2711 79aceca5 bellard
}
2712 79aceca5 bellard
2713 477023a6 j_mayer
#define GEN_LDUXF(width, opc, type)                                           \
2714 477023a6 j_mayer
GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                  \
2715 79aceca5 bellard
{                                                                             \
2716 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2717 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);                                                  \
2718 4ecc3190 bellard
        return;                                                               \
2719 4ecc3190 bellard
    }                                                                         \
2720 76a66253 j_mayer
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2721 e1833e1f j_mayer
        GEN_EXCP_INVAL(ctx);                                                  \
2722 9fddaa0c bellard
        return;                                                               \
2723 9a64fbe4 bellard
    }                                                                         \
2724 76a66253 j_mayer
    gen_addr_reg_index(ctx);                                                  \
2725 9a64fbe4 bellard
    op_ldst(l##width);                                                        \
2726 76a66253 j_mayer
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2727 79aceca5 bellard
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2728 79aceca5 bellard
}
2729 79aceca5 bellard
2730 477023a6 j_mayer
#define GEN_LDXF(width, opc2, opc3, type)                                     \
2731 477023a6 j_mayer
GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
2732 79aceca5 bellard
{                                                                             \
2733 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2734 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);                                                  \
2735 4ecc3190 bellard
        return;                                                               \
2736 4ecc3190 bellard
    }                                                                         \
2737 76a66253 j_mayer
    gen_addr_reg_index(ctx);                                                  \
2738 9a64fbe4 bellard
    op_ldst(l##width);                                                        \
2739 76a66253 j_mayer
    gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
2740 79aceca5 bellard
}
2741 79aceca5 bellard
2742 477023a6 j_mayer
#define GEN_LDFS(width, op, type)                                             \
2743 9a64fbe4 bellard
OP_LD_TABLE(width);                                                           \
2744 477023a6 j_mayer
GEN_LDF(width, op | 0x20, type);                                              \
2745 477023a6 j_mayer
GEN_LDUF(width, op | 0x21, type);                                             \
2746 477023a6 j_mayer
GEN_LDUXF(width, op | 0x01, type);                                            \
2747 477023a6 j_mayer
GEN_LDXF(width, 0x17, op | 0x00, type)
2748 79aceca5 bellard
2749 79aceca5 bellard
/* lfd lfdu lfdux lfdx */
2750 477023a6 j_mayer
GEN_LDFS(fd, 0x12, PPC_FLOAT);
2751 79aceca5 bellard
/* lfs lfsu lfsux lfsx */
2752 477023a6 j_mayer
GEN_LDFS(fs, 0x10, PPC_FLOAT);
2753 79aceca5 bellard
2754 79aceca5 bellard
/***                         Floating-point store                          ***/
2755 477023a6 j_mayer
#define GEN_STF(width, opc, type)                                             \
2756 477023a6 j_mayer
GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
2757 79aceca5 bellard
{                                                                             \
2758 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2759 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);                                                  \
2760 4ecc3190 bellard
        return;                                                               \
2761 4ecc3190 bellard
    }                                                                         \
2762 9d53c753 j_mayer
    gen_addr_imm_index(ctx, 0);                                               \
2763 76a66253 j_mayer
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2764 9a64fbe4 bellard
    op_ldst(st##width);                                                       \
2765 79aceca5 bellard
}
2766 79aceca5 bellard
2767 477023a6 j_mayer
#define GEN_STUF(width, opc, type)                                            \
2768 477023a6 j_mayer
GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
2769 79aceca5 bellard
{                                                                             \
2770 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2771 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);                                                  \
2772 4ecc3190 bellard
        return;                                                               \
2773 4ecc3190 bellard
    }                                                                         \
2774 76a66253 j_mayer
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2775 e1833e1f j_mayer
        GEN_EXCP_INVAL(ctx);                                                  \
2776 9fddaa0c bellard
        return;                                                               \
2777 9a64fbe4 bellard
    }                                                                         \
2778 9d53c753 j_mayer
    gen_addr_imm_index(ctx, 0);                                               \
2779 76a66253 j_mayer
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2780 9a64fbe4 bellard
    op_ldst(st##width);                                                       \
2781 79aceca5 bellard
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2782 79aceca5 bellard
}
2783 79aceca5 bellard
2784 477023a6 j_mayer
#define GEN_STUXF(width, opc, type)                                           \
2785 477023a6 j_mayer
GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                 \
2786 79aceca5 bellard
{                                                                             \
2787 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2788 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);                                                  \
2789 4ecc3190 bellard
        return;                                                               \
2790 4ecc3190 bellard
    }                                                                         \
2791 76a66253 j_mayer
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2792 e1833e1f j_mayer
        GEN_EXCP_INVAL(ctx);                                                  \
2793 9fddaa0c bellard
        return;                                                               \
2794 9a64fbe4 bellard
    }                                                                         \
2795 76a66253 j_mayer
    gen_addr_reg_index(ctx);                                                  \
2796 76a66253 j_mayer
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2797 9a64fbe4 bellard
    op_ldst(st##width);                                                       \
2798 79aceca5 bellard
    gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
2799 79aceca5 bellard
}
2800 79aceca5 bellard
2801 477023a6 j_mayer
#define GEN_STXF(width, opc2, opc3, type)                                     \
2802 477023a6 j_mayer
GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
2803 79aceca5 bellard
{                                                                             \
2804 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2805 e1833e1f j_mayer
        GEN_EXCP_NO_FP(ctx);                                                  \
2806 4ecc3190 bellard
        return;                                                               \
2807 4ecc3190 bellard
    }                                                                         \
2808 76a66253 j_mayer
    gen_addr_reg_index(ctx);                                                  \
2809 76a66253 j_mayer
    gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
2810 9a64fbe4 bellard
    op_ldst(st##width);                                                       \
2811 79aceca5 bellard
}
2812 79aceca5 bellard
2813 477023a6 j_mayer
#define GEN_STFS(width, op, type)                                             \
2814 9a64fbe4 bellard
OP_ST_TABLE(width);                                                           \
2815 477023a6 j_mayer
GEN_STF(width, op | 0x20, type);                                              \
2816 477023a6 j_mayer
GEN_STUF(width, op | 0x21, type);                                             \
2817 477023a6 j_mayer
GEN_STUXF(width, op | 0x01, type);                                            \
2818 477023a6 j_mayer
GEN_STXF(width, 0x17, op | 0x00, type)
2819 79aceca5 bellard
2820 79aceca5 bellard
/* stfd stfdu stfdux stfdx */
2821 477023a6 j_mayer
GEN_STFS(fd, 0x16, PPC_FLOAT);
2822 79aceca5 bellard
/* stfs stfsu stfsux stfsx */
2823 477023a6 j_mayer
GEN_STFS(fs, 0x14, PPC_FLOAT);
2824 79aceca5 bellard
2825 79aceca5 bellard
/* Optional: */
2826 79aceca5 bellard
/* stfiwx */
2827 5b8105fa j_mayer
OP_ST_TABLE(fiw);
2828 5b8105fa j_mayer
GEN_STXF(fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
2829 79aceca5 bellard
2830 79aceca5 bellard
/***                                Branch                                 ***/
2831 b068d6a7 j_mayer
static always_inline void gen_goto_tb (DisasContext *ctx, int n,
2832 b068d6a7 j_mayer
                                       target_ulong dest)
2833 c1942362 bellard
{
2834 c1942362 bellard
    TranslationBlock *tb;
2835 c1942362 bellard
    tb = ctx->tb;
2836 57fec1fe bellard
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2837 8cbcb4fa aurel32
        likely(!ctx->singlestep_enabled)) {
2838 57fec1fe bellard
        tcg_gen_goto_tb(n);
2839 d9bce9d9 j_mayer
        gen_set_T1(dest);
2840 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
2841 d9bce9d9 j_mayer
        if (ctx->sf_mode)
2842 d9bce9d9 j_mayer
            gen_op_b_T1_64();
2843 d9bce9d9 j_mayer
        else
2844 d9bce9d9 j_mayer
#endif
2845 d9bce9d9 j_mayer
            gen_op_b_T1();
2846 57fec1fe bellard
        tcg_gen_exit_tb((long)tb + n);
2847 c1942362 bellard
    } else {
2848 d9bce9d9 j_mayer
        gen_set_T1(dest);
2849 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
2850 d9bce9d9 j_mayer
        if (ctx->sf_mode)
2851 d9bce9d9 j_mayer
            gen_op_b_T1_64();
2852 d9bce9d9 j_mayer
        else
2853 d9bce9d9 j_mayer
#endif
2854 d9bce9d9 j_mayer
            gen_op_b_T1();
2855 8cbcb4fa aurel32
        if (unlikely(ctx->singlestep_enabled)) {
2856 8cbcb4fa aurel32
            if ((ctx->singlestep_enabled &
2857 8cbcb4fa aurel32
                 (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
2858 8cbcb4fa aurel32
                ctx->exception == POWERPC_EXCP_BRANCH) {
2859 8cbcb4fa aurel32
                target_ulong tmp = ctx->nip;
2860 8cbcb4fa aurel32
                ctx->nip = dest;
2861 8cbcb4fa aurel32
                GEN_EXCP(ctx, POWERPC_EXCP_TRACE, 0);
2862 8cbcb4fa aurel32
                ctx->nip = tmp;
2863 8cbcb4fa aurel32
            }
2864 8cbcb4fa aurel32
            if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
2865 8cbcb4fa aurel32
                gen_update_nip(ctx, dest);
2866 8cbcb4fa aurel32
                gen_op_debug();
2867 8cbcb4fa aurel32
            }
2868 8cbcb4fa aurel32
        }
2869 57fec1fe bellard
        tcg_gen_exit_tb(0);
2870 c1942362 bellard
    }
2871 c53be334 bellard
}
2872 c53be334 bellard
2873 b068d6a7 j_mayer
static always_inline void gen_setlr (DisasContext *ctx, target_ulong nip)
2874 e1833e1f j_mayer
{
2875 e1833e1f j_mayer
#if defined(TARGET_PPC64)
2876 e1833e1f j_mayer
    if (ctx->sf_mode != 0 && (nip >> 32))
2877 e1833e1f j_mayer
        gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
2878 e1833e1f j_mayer
    else
2879 e1833e1f j_mayer
#endif
2880 e1833e1f j_mayer
        gen_op_setlr(ctx->nip);
2881 e1833e1f j_mayer
}
2882 e1833e1f j_mayer
2883 79aceca5 bellard
/* b ba bl bla */
2884 79aceca5 bellard
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2885 79aceca5 bellard
{
2886 76a66253 j_mayer
    target_ulong li, target;
2887 38a64f9d bellard
2888 8cbcb4fa aurel32
    ctx->exception = POWERPC_EXCP_BRANCH;
2889 38a64f9d bellard
    /* sign extend LI */
2890 76a66253 j_mayer
#if defined(TARGET_PPC64)
2891 d9bce9d9 j_mayer
    if (ctx->sf_mode)
2892 d9bce9d9 j_mayer
        li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
2893 d9bce9d9 j_mayer
    else
2894 76a66253 j_mayer
#endif
2895 d9bce9d9 j_mayer
        li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
2896 76a66253 j_mayer
    if (likely(AA(ctx->opcode) == 0))
2897 046d6672 bellard
        target = ctx->nip + li - 4;
2898 79aceca5 bellard
    else
2899 9a64fbe4 bellard
        target = li;
2900 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
2901 e1833e1f j_mayer
    if (!ctx->sf_mode)
2902 e1833e1f j_mayer
        target = (uint32_t)target;
2903 d9bce9d9 j_mayer
#endif
2904 e1833e1f j_mayer
    if (LK(ctx->opcode))
2905 e1833e1f j_mayer
        gen_setlr(ctx, ctx->nip);
2906 c1942362 bellard
    gen_goto_tb(ctx, 0, target);
2907 79aceca5 bellard
}
2908 79aceca5 bellard
2909 e98a6e40 bellard
#define BCOND_IM  0
2910 e98a6e40 bellard
#define BCOND_LR  1
2911 e98a6e40 bellard
#define BCOND_CTR 2
2912 e98a6e40 bellard
2913 b068d6a7 j_mayer
static always_inline void gen_bcond (DisasContext *ctx, int type)
2914 d9bce9d9 j_mayer
{
2915 76a66253 j_mayer
    target_ulong target = 0;
2916 76a66253 j_mayer
    target_ulong li;
2917 d9bce9d9 j_mayer
    uint32_t bo = BO(ctx->opcode);
2918 d9bce9d9 j_mayer
    uint32_t bi = BI(ctx->opcode);
2919 d9bce9d9 j_mayer
    uint32_t mask;
2920 e98a6e40 bellard
2921 8cbcb4fa aurel32
    ctx->exception = POWERPC_EXCP_BRANCH;
2922 e98a6e40 bellard
    if ((bo & 0x4) == 0)
2923 d9bce9d9 j_mayer
        gen_op_dec_ctr();
2924 e98a6e40 bellard
    switch(type) {
2925 e98a6e40 bellard
    case BCOND_IM:
2926 76a66253 j_mayer
        li = (target_long)((int16_t)(BD(ctx->opcode)));
2927 76a66253 j_mayer
        if (likely(AA(ctx->opcode) == 0)) {
2928 046d6672 bellard
            target = ctx->nip + li - 4;
2929 e98a6e40 bellard
        } else {
2930 e98a6e40 bellard
            target = li;
2931 e98a6e40 bellard
        }
2932 e1833e1f j_mayer
#if defined(TARGET_PPC64)
2933 e1833e1f j_mayer
        if (!ctx->sf_mode)
2934 e1833e1f j_mayer
            target = (uint32_t)target;
2935 e1833e1f j_mayer
#endif
2936 e98a6e40 bellard
        break;
2937 e98a6e40 bellard
    case BCOND_CTR:
2938 e98a6e40 bellard
        gen_op_movl_T1_ctr();
2939 e98a6e40 bellard
        break;
2940 e98a6e40 bellard
    default:
2941 e98a6e40 bellard
    case BCOND_LR:
2942 e98a6e40 bellard
        gen_op_movl_T1_lr();
2943 e98a6e40 bellard
        break;
2944 e98a6e40 bellard
    }
2945 e1833e1f j_mayer
    if (LK(ctx->opcode))
2946 e1833e1f j_mayer
        gen_setlr(ctx, ctx->nip);
2947 e98a6e40 bellard
    if (bo & 0x10) {
2948 d9bce9d9 j_mayer
        /* No CR condition */
2949 d9bce9d9 j_mayer
        switch (bo & 0x6) {
2950 d9bce9d9 j_mayer
        case 0:
2951 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
2952 d9bce9d9 j_mayer
            if (ctx->sf_mode)
2953 d9bce9d9 j_mayer
                gen_op_test_ctr_64();
2954 d9bce9d9 j_mayer
            else
2955 d9bce9d9 j_mayer
#endif
2956 d9bce9d9 j_mayer
                gen_op_test_ctr();
2957 d9bce9d9 j_mayer
            break;
2958 d9bce9d9 j_mayer
        case 2:
2959 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
2960 d9bce9d9 j_mayer
            if (ctx->sf_mode)
2961 d9bce9d9 j_mayer
                gen_op_test_ctrz_64();
2962 d9bce9d9 j_mayer
            else
2963 d9bce9d9 j_mayer
#endif
2964 d9bce9d9 j_mayer
                gen_op_test_ctrz();
2965 e98a6e40 bellard
            break;
2966 e98a6e40 bellard
        default:
2967 d9bce9d9 j_mayer
        case 4:
2968 d9bce9d9 j_mayer
        case 6:
2969 e98a6e40 bellard
            if (type == BCOND_IM) {
2970 c1942362 bellard
                gen_goto_tb(ctx, 0, target);
2971 8cbcb4fa aurel32
                return;
2972 e98a6e40 bellard
            } else {
2973 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
2974 d9bce9d9 j_mayer
                if (ctx->sf_mode)
2975 d9bce9d9 j_mayer
                    gen_op_b_T1_64();
2976 d9bce9d9 j_mayer
                else
2977 d9bce9d9 j_mayer
#endif
2978 d9bce9d9 j_mayer
                    gen_op_b_T1();
2979 056b05f8 j_mayer
                goto no_test;
2980 e98a6e40 bellard
            }
2981 056b05f8 j_mayer
            break;
2982 e98a6e40 bellard
        }
2983 d9bce9d9 j_mayer
    } else {
2984 d9bce9d9 j_mayer
        mask = 1 << (3 - (bi & 0x03));
2985 d9bce9d9 j_mayer
        gen_op_load_crf_T0(bi >> 2);
2986 d9bce9d9 j_mayer
        if (bo & 0x8) {
2987 d9bce9d9 j_mayer
            switch (bo & 0x6) {
2988 d9bce9d9 j_mayer
            case 0:
2989 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
2990 d9bce9d9 j_mayer
                if (ctx->sf_mode)
2991 d9bce9d9 j_mayer
                    gen_op_test_ctr_true_64(mask);
2992 d9bce9d9 j_mayer
                else
2993 d9bce9d9 j_mayer
#endif
2994 d9bce9d9 j_mayer
                    gen_op_test_ctr_true(mask);
2995 d9bce9d9 j_mayer
                break;
2996 d9bce9d9 j_mayer
            case 2:
2997 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
2998 d9bce9d9 j_mayer
                if (ctx->sf_mode)
2999 d9bce9d9 j_mayer
                    gen_op_test_ctrz_true_64(mask);
3000 d9bce9d9 j_mayer
                else
3001 d9bce9d9 j_mayer
#endif
3002 d9bce9d9 j_mayer
                    gen_op_test_ctrz_true(mask);
3003 d9bce9d9 j_mayer
                break;
3004 d9bce9d9 j_mayer
            default:
3005 d9bce9d9 j_mayer
            case 4:
3006 d9bce9d9 j_mayer
            case 6:
3007 e98a6e40 bellard
                gen_op_test_true(mask);
3008 d9bce9d9 j_mayer
                break;
3009 d9bce9d9 j_mayer
            }
3010 d9bce9d9 j_mayer
        } else {
3011 d9bce9d9 j_mayer
            switch (bo & 0x6) {
3012 d9bce9d9 j_mayer
            case 0:
3013 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
3014 d9bce9d9 j_mayer
                if (ctx->sf_mode)
3015 d9bce9d9 j_mayer
                    gen_op_test_ctr_false_64(mask);
3016 d9bce9d9 j_mayer
                else
3017 d9bce9d9 j_mayer
#endif
3018 d9bce9d9 j_mayer
                    gen_op_test_ctr_false(mask);
3019 3b46e624 ths
                break;
3020 d9bce9d9 j_mayer
            case 2:
3021 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
3022 d9bce9d9 j_mayer
                if (ctx->sf_mode)
3023 d9bce9d9 j_mayer
                    gen_op_test_ctrz_false_64(mask);
3024 d9bce9d9 j_mayer
                else
3025 d9bce9d9 j_mayer
#endif
3026 d9bce9d9 j_mayer
                    gen_op_test_ctrz_false(mask);
3027 d9bce9d9 j_mayer
                break;
3028 e98a6e40 bellard
            default:
3029 d9bce9d9 j_mayer
            case 4:
3030 d9bce9d9 j_mayer
            case 6:
3031 e98a6e40 bellard
                gen_op_test_false(mask);
3032 d9bce9d9 j_mayer
                break;
3033 d9bce9d9 j_mayer
            }
3034 d9bce9d9 j_mayer
        }
3035 d9bce9d9 j_mayer
    }
3036 e98a6e40 bellard
    if (type == BCOND_IM) {
3037 c53be334 bellard
        int l1 = gen_new_label();
3038 c53be334 bellard
        gen_op_jz_T0(l1);
3039 c1942362 bellard
        gen_goto_tb(ctx, 0, target);
3040 c53be334 bellard
        gen_set_label(l1);
3041 c1942362 bellard
        gen_goto_tb(ctx, 1, ctx->nip);
3042 e98a6e40 bellard
    } else {
3043 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
3044 d9bce9d9 j_mayer
        if (ctx->sf_mode)
3045 d9bce9d9 j_mayer
            gen_op_btest_T1_64(ctx->nip >> 32, ctx->nip);
3046 d9bce9d9 j_mayer
        else
3047 d9bce9d9 j_mayer
#endif
3048 d9bce9d9 j_mayer
            gen_op_btest_T1(ctx->nip);
3049 36081602 j_mayer
    no_test:
3050 8cbcb4fa aurel32
        if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
3051 8cbcb4fa aurel32
            gen_update_nip(ctx, ctx->nip);
3052 08e46e54 j_mayer
            gen_op_debug();
3053 8cbcb4fa aurel32
        }
3054 57fec1fe bellard
        tcg_gen_exit_tb(0);
3055 08e46e54 j_mayer
    }
3056 e98a6e40 bellard
}
3057 e98a6e40 bellard
3058 e98a6e40 bellard
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3059 3b46e624 ths
{
3060 e98a6e40 bellard
    gen_bcond(ctx, BCOND_IM);
3061 e98a6e40 bellard
}
3062 e98a6e40 bellard
3063 e98a6e40 bellard
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
3064 3b46e624 ths
{
3065 e98a6e40 bellard
    gen_bcond(ctx, BCOND_CTR);
3066 e98a6e40 bellard
}
3067 e98a6e40 bellard
3068 e98a6e40 bellard
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
3069 3b46e624 ths
{
3070 e98a6e40 bellard
    gen_bcond(ctx, BCOND_LR);
3071 e98a6e40 bellard
}
3072 79aceca5 bellard
3073 79aceca5 bellard
/***                      Condition register logical                       ***/
3074 79aceca5 bellard
#define GEN_CRLOGIC(op, opc)                                                  \
3075 79aceca5 bellard
GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                 \
3076 79aceca5 bellard
{                                                                             \
3077 fc0d441e j_mayer
    uint8_t bitmask;                                                          \
3078 fc0d441e j_mayer
    int sh;                                                                   \
3079 79aceca5 bellard
    gen_op_load_crf_T0(crbA(ctx->opcode) >> 2);                               \
3080 fc0d441e j_mayer
    sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
3081 fc0d441e j_mayer
    if (sh > 0)                                                               \
3082 fc0d441e j_mayer
        gen_op_srli_T0(sh);                                                   \
3083 fc0d441e j_mayer
    else if (sh < 0)                                                          \
3084 fc0d441e j_mayer
        gen_op_sli_T0(-sh);                                                   \
3085 79aceca5 bellard
    gen_op_load_crf_T1(crbB(ctx->opcode) >> 2);                               \
3086 fc0d441e j_mayer
    sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
3087 fc0d441e j_mayer
    if (sh > 0)                                                               \
3088 fc0d441e j_mayer
        gen_op_srli_T1(sh);                                                   \
3089 fc0d441e j_mayer
    else if (sh < 0)                                                          \
3090 fc0d441e j_mayer
        gen_op_sli_T1(-sh);                                                   \
3091 79aceca5 bellard
    gen_op_##op();                                                            \
3092 fc0d441e j_mayer
    bitmask = 1 << (3 - (crbD(ctx->opcode) & 0x03));                          \
3093 fc0d441e j_mayer
    gen_op_andi_T0(bitmask);                                                  \
3094 79aceca5 bellard
    gen_op_load_crf_T1(crbD(ctx->opcode) >> 2);                               \
3095 fc0d441e j_mayer
    gen_op_andi_T1(~bitmask);                                                 \
3096 fc0d441e j_mayer
    gen_op_or();                                                              \
3097 fc0d441e j_mayer
    gen_op_store_T0_crf(crbD(ctx->opcode) >> 2);                              \
3098 79aceca5 bellard
}
3099 79aceca5 bellard
3100 79aceca5 bellard
/* crand */
3101 76a66253 j_mayer
GEN_CRLOGIC(and, 0x08);
3102 79aceca5 bellard
/* crandc */
3103 76a66253 j_mayer
GEN_CRLOGIC(andc, 0x04);
3104 79aceca5 bellard
/* creqv */
3105 76a66253 j_mayer
GEN_CRLOGIC(eqv, 0x09);
3106 79aceca5 bellard
/* crnand */
3107 76a66253 j_mayer
GEN_CRLOGIC(nand, 0x07);
3108 79aceca5 bellard
/* crnor */
3109 76a66253 j_mayer
GEN_CRLOGIC(nor, 0x01);
3110 79aceca5 bellard
/* cror */
3111 76a66253 j_mayer
GEN_CRLOGIC(or, 0x0E);
3112 79aceca5 bellard
/* crorc */
3113 76a66253 j_mayer
GEN_CRLOGIC(orc, 0x0D);
3114 79aceca5 bellard
/* crxor */
3115 76a66253 j_mayer
GEN_CRLOGIC(xor, 0x06);
3116 79aceca5 bellard
/* mcrf */
3117 79aceca5 bellard
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
3118 79aceca5 bellard
{
3119 79aceca5 bellard
    gen_op_load_crf_T0(crfS(ctx->opcode));
3120 79aceca5 bellard
    gen_op_store_T0_crf(crfD(ctx->opcode));
3121 79aceca5 bellard
}
3122 79aceca5 bellard
3123 79aceca5 bellard
/***                           System linkage                              ***/
3124 79aceca5 bellard
/* rfi (supervisor only) */
3125 76a66253 j_mayer
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
3126 79aceca5 bellard
{
3127 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
3128 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
3129 9a64fbe4 bellard
#else
3130 9a64fbe4 bellard
    /* Restore CPU state */
3131 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
3132 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
3133 9fddaa0c bellard
        return;
3134 9a64fbe4 bellard
    }
3135 a42bd6cc j_mayer
    gen_op_rfi();
3136 e1833e1f j_mayer
    GEN_SYNC(ctx);
3137 9a64fbe4 bellard
#endif
3138 79aceca5 bellard
}
3139 79aceca5 bellard
3140 426613db j_mayer
#if defined(TARGET_PPC64)
3141 a750fc0b j_mayer
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
3142 426613db j_mayer
{
3143 426613db j_mayer
#if defined(CONFIG_USER_ONLY)
3144 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
3145 426613db j_mayer
#else
3146 426613db j_mayer
    /* Restore CPU state */
3147 426613db j_mayer
    if (unlikely(!ctx->supervisor)) {
3148 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
3149 426613db j_mayer
        return;
3150 426613db j_mayer
    }
3151 a42bd6cc j_mayer
    gen_op_rfid();
3152 e1833e1f j_mayer
    GEN_SYNC(ctx);
3153 426613db j_mayer
#endif
3154 426613db j_mayer
}
3155 426613db j_mayer
3156 5b8105fa j_mayer
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H)
3157 be147d08 j_mayer
{
3158 be147d08 j_mayer
#if defined(CONFIG_USER_ONLY)
3159 be147d08 j_mayer
    GEN_EXCP_PRIVOPC(ctx);
3160 be147d08 j_mayer
#else
3161 be147d08 j_mayer
    /* Restore CPU state */
3162 be147d08 j_mayer
    if (unlikely(ctx->supervisor <= 1)) {
3163 be147d08 j_mayer
        GEN_EXCP_PRIVOPC(ctx);
3164 be147d08 j_mayer
        return;
3165 be147d08 j_mayer
    }
3166 be147d08 j_mayer
    gen_op_hrfid();
3167 be147d08 j_mayer
    GEN_SYNC(ctx);
3168 be147d08 j_mayer
#endif
3169 be147d08 j_mayer
}
3170 be147d08 j_mayer
#endif
3171 be147d08 j_mayer
3172 79aceca5 bellard
/* sc */
3173 417bf010 j_mayer
#if defined(CONFIG_USER_ONLY)
3174 417bf010 j_mayer
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
3175 417bf010 j_mayer
#else
3176 417bf010 j_mayer
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
3177 417bf010 j_mayer
#endif
3178 e1833e1f j_mayer
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
3179 79aceca5 bellard
{
3180 e1833e1f j_mayer
    uint32_t lev;
3181 e1833e1f j_mayer
3182 e1833e1f j_mayer
    lev = (ctx->opcode >> 5) & 0x7F;
3183 417bf010 j_mayer
    GEN_EXCP(ctx, POWERPC_SYSCALL, lev);
3184 79aceca5 bellard
}
3185 79aceca5 bellard
3186 79aceca5 bellard
/***                                Trap                                   ***/
3187 79aceca5 bellard
/* tw */
3188 76a66253 j_mayer
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
3189 79aceca5 bellard
{
3190 9a64fbe4 bellard
    gen_op_load_gpr_T0(rA(ctx->opcode));
3191 9a64fbe4 bellard
    gen_op_load_gpr_T1(rB(ctx->opcode));
3192 a0ae05aa ths
    /* Update the nip since this might generate a trap exception */
3193 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip);
3194 9a64fbe4 bellard
    gen_op_tw(TO(ctx->opcode));
3195 79aceca5 bellard
}
3196 79aceca5 bellard
3197 79aceca5 bellard
/* twi */
3198 79aceca5 bellard
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
3199 79aceca5 bellard
{
3200 9a64fbe4 bellard
    gen_op_load_gpr_T0(rA(ctx->opcode));
3201 d9bce9d9 j_mayer
    gen_set_T1(SIMM(ctx->opcode));
3202 d9bce9d9 j_mayer
    /* Update the nip since this might generate a trap exception */
3203 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip);
3204 76a66253 j_mayer
    gen_op_tw(TO(ctx->opcode));
3205 79aceca5 bellard
}
3206 79aceca5 bellard
3207 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
3208 d9bce9d9 j_mayer
/* td */
3209 d9bce9d9 j_mayer
GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
3210 d9bce9d9 j_mayer
{
3211 d9bce9d9 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
3212 d9bce9d9 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
3213 d9bce9d9 j_mayer
    /* Update the nip since this might generate a trap exception */
3214 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip);
3215 d9bce9d9 j_mayer
    gen_op_td(TO(ctx->opcode));
3216 d9bce9d9 j_mayer
}
3217 d9bce9d9 j_mayer
3218 d9bce9d9 j_mayer
/* tdi */
3219 d9bce9d9 j_mayer
GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
3220 d9bce9d9 j_mayer
{
3221 d9bce9d9 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
3222 d9bce9d9 j_mayer
    gen_set_T1(SIMM(ctx->opcode));
3223 d9bce9d9 j_mayer
    /* Update the nip since this might generate a trap exception */
3224 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip);
3225 d9bce9d9 j_mayer
    gen_op_td(TO(ctx->opcode));
3226 d9bce9d9 j_mayer
}
3227 d9bce9d9 j_mayer
#endif
3228 d9bce9d9 j_mayer
3229 79aceca5 bellard
/***                          Processor control                            ***/
3230 79aceca5 bellard
/* mcrxr */
3231 79aceca5 bellard
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
3232 79aceca5 bellard
{
3233 79aceca5 bellard
    gen_op_load_xer_cr();
3234 79aceca5 bellard
    gen_op_store_T0_crf(crfD(ctx->opcode));
3235 e864cabd j_mayer
    gen_op_clear_xer_ov();
3236 e864cabd j_mayer
    gen_op_clear_xer_ca();
3237 79aceca5 bellard
}
3238 79aceca5 bellard
3239 79aceca5 bellard
/* mfcr */
3240 76a66253 j_mayer
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
3241 79aceca5 bellard
{
3242 76a66253 j_mayer
    uint32_t crm, crn;
3243 3b46e624 ths
3244 76a66253 j_mayer
    if (likely(ctx->opcode & 0x00100000)) {
3245 76a66253 j_mayer
        crm = CRM(ctx->opcode);
3246 76a66253 j_mayer
        if (likely((crm ^ (crm - 1)) == 0)) {
3247 76a66253 j_mayer
            crn = ffs(crm);
3248 61c04807 aurel32
            tcg_gen_ld8u_tl(cpu_T[0], cpu_env, offsetof(CPUState, crf[7 - crn]));
3249 76a66253 j_mayer
        }
3250 d9bce9d9 j_mayer
    } else {
3251 61c04807 aurel32
        tcg_gen_helper_1_0(do_load_cr, cpu_T[0]);
3252 d9bce9d9 j_mayer
    }
3253 79aceca5 bellard
    gen_op_store_T0_gpr(rD(ctx->opcode));
3254 79aceca5 bellard
}
3255 79aceca5 bellard
3256 79aceca5 bellard
/* mfmsr */
3257 79aceca5 bellard
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
3258 79aceca5 bellard
{
3259 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
3260 e1833e1f j_mayer
    GEN_EXCP_PRIVREG(ctx);
3261 9a64fbe4 bellard
#else
3262 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
3263 e1833e1f j_mayer
        GEN_EXCP_PRIVREG(ctx);
3264 9fddaa0c bellard
        return;
3265 9a64fbe4 bellard
    }
3266 61c04807 aurel32
    tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, msr));
3267 79aceca5 bellard
    gen_op_store_T0_gpr(rD(ctx->opcode));
3268 9a64fbe4 bellard
#endif
3269 79aceca5 bellard
}
3270 79aceca5 bellard
3271 a11b8151 j_mayer
#if 1
3272 6f2d8978 j_mayer
#define SPR_NOACCESS ((void *)(-1UL))
3273 3fc6c082 bellard
#else
3274 3fc6c082 bellard
static void spr_noaccess (void *opaque, int sprn)
3275 3fc6c082 bellard
{
3276 3fc6c082 bellard
    sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3277 3fc6c082 bellard
    printf("ERROR: try to access SPR %d !\n", sprn);
3278 3fc6c082 bellard
}
3279 3fc6c082 bellard
#define SPR_NOACCESS (&spr_noaccess)
3280 3fc6c082 bellard
#endif
3281 3fc6c082 bellard
3282 79aceca5 bellard
/* mfspr */
3283 b068d6a7 j_mayer
static always_inline void gen_op_mfspr (DisasContext *ctx)
3284 79aceca5 bellard
{
3285 3fc6c082 bellard
    void (*read_cb)(void *opaque, int sprn);
3286 79aceca5 bellard
    uint32_t sprn = SPR(ctx->opcode);
3287 79aceca5 bellard
3288 3fc6c082 bellard
#if !defined(CONFIG_USER_ONLY)
3289 be147d08 j_mayer
    if (ctx->supervisor == 2)
3290 be147d08 j_mayer
        read_cb = ctx->spr_cb[sprn].hea_read;
3291 7863667f j_mayer
    else if (ctx->supervisor)
3292 3fc6c082 bellard
        read_cb = ctx->spr_cb[sprn].oea_read;
3293 3fc6c082 bellard
    else
3294 9a64fbe4 bellard
#endif
3295 3fc6c082 bellard
        read_cb = ctx->spr_cb[sprn].uea_read;
3296 76a66253 j_mayer
    if (likely(read_cb != NULL)) {
3297 76a66253 j_mayer
        if (likely(read_cb != SPR_NOACCESS)) {
3298 3fc6c082 bellard
            (*read_cb)(ctx, sprn);
3299 3fc6c082 bellard
            gen_op_store_T0_gpr(rD(ctx->opcode));
3300 3fc6c082 bellard
        } else {
3301 3fc6c082 bellard
            /* Privilege exception */
3302 9fceefa7 j_mayer
            /* This is a hack to avoid warnings when running Linux:
3303 9fceefa7 j_mayer
             * this OS breaks the PowerPC virtualisation model,
3304 9fceefa7 j_mayer
             * allowing userland application to read the PVR
3305 9fceefa7 j_mayer
             */
3306 9fceefa7 j_mayer
            if (sprn != SPR_PVR) {
3307 9fceefa7 j_mayer
                if (loglevel != 0) {
3308 6b542af7 j_mayer
                    fprintf(logfile, "Trying to read privileged spr %d %03x at "
3309 077fc206 j_mayer
                            ADDRX "\n", sprn, sprn, ctx->nip);
3310 9fceefa7 j_mayer
                }
3311 077fc206 j_mayer
                printf("Trying to read privileged spr %d %03x at " ADDRX "\n",
3312 077fc206 j_mayer
                       sprn, sprn, ctx->nip);
3313 f24e5695 bellard
            }
3314 e1833e1f j_mayer
            GEN_EXCP_PRIVREG(ctx);
3315 79aceca5 bellard
        }
3316 3fc6c082 bellard
    } else {
3317 3fc6c082 bellard
        /* Not defined */
3318 4a057712 j_mayer
        if (loglevel != 0) {
3319 077fc206 j_mayer
            fprintf(logfile, "Trying to read invalid spr %d %03x at "
3320 077fc206 j_mayer
                    ADDRX "\n", sprn, sprn, ctx->nip);
3321 f24e5695 bellard
        }
3322 077fc206 j_mayer
        printf("Trying to read invalid spr %d %03x at " ADDRX "\n",
3323 077fc206 j_mayer
               sprn, sprn, ctx->nip);
3324 e1833e1f j_mayer
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3325 e1833e1f j_mayer
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3326 79aceca5 bellard
    }
3327 79aceca5 bellard
}
3328 79aceca5 bellard
3329 3fc6c082 bellard
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
3330 79aceca5 bellard
{
3331 3fc6c082 bellard
    gen_op_mfspr(ctx);
3332 76a66253 j_mayer
}
3333 3fc6c082 bellard
3334 3fc6c082 bellard
/* mftb */
3335 a750fc0b j_mayer
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
3336 3fc6c082 bellard
{
3337 3fc6c082 bellard
    gen_op_mfspr(ctx);
3338 79aceca5 bellard
}
3339 79aceca5 bellard
3340 79aceca5 bellard
/* mtcrf */
3341 8dd4983c bellard
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
3342 79aceca5 bellard
{
3343 76a66253 j_mayer
    uint32_t crm, crn;
3344 3b46e624 ths
3345 79aceca5 bellard
    gen_op_load_gpr_T0(rS(ctx->opcode));
3346 76a66253 j_mayer
    crm = CRM(ctx->opcode);
3347 76a66253 j_mayer
    if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
3348 76a66253 j_mayer
        crn = ffs(crm);
3349 76a66253 j_mayer
        gen_op_srli_T0(crn * 4);
3350 61c04807 aurel32
        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xF);
3351 61c04807 aurel32
        tcg_gen_st8_tl(cpu_T[0], cpu_env, offsetof(CPUState, crf[7 - crn]));
3352 76a66253 j_mayer
    } else {
3353 61c04807 aurel32
        tcg_gen_helper_0_i(do_store_cr, crm);
3354 76a66253 j_mayer
    }
3355 79aceca5 bellard
}
3356 79aceca5 bellard
3357 79aceca5 bellard
/* mtmsr */
3358 426613db j_mayer
#if defined(TARGET_PPC64)
3359 be147d08 j_mayer
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B)
3360 426613db j_mayer
{
3361 426613db j_mayer
#if defined(CONFIG_USER_ONLY)
3362 e1833e1f j_mayer
    GEN_EXCP_PRIVREG(ctx);
3363 426613db j_mayer
#else
3364 426613db j_mayer
    if (unlikely(!ctx->supervisor)) {
3365 e1833e1f j_mayer
        GEN_EXCP_PRIVREG(ctx);
3366 426613db j_mayer
        return;
3367 426613db j_mayer
    }
3368 426613db j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
3369 be147d08 j_mayer
    if (ctx->opcode & 0x00010000) {
3370 be147d08 j_mayer
        /* Special form that does not need any synchronisation */
3371 be147d08 j_mayer
        gen_op_update_riee();
3372 be147d08 j_mayer
    } else {
3373 056b05f8 j_mayer
        /* XXX: we need to update nip before the store
3374 056b05f8 j_mayer
         *      if we enter power saving mode, we will exit the loop
3375 056b05f8 j_mayer
         *      directly from ppc_store_msr
3376 056b05f8 j_mayer
         */
3377 be147d08 j_mayer
        gen_update_nip(ctx, ctx->nip);
3378 61c04807 aurel32
        tcg_gen_helper_0_1(do_store_msr, cpu_T[0]);
3379 be147d08 j_mayer
        /* Must stop the translation as machine state (may have) changed */
3380 be147d08 j_mayer
        /* Note that mtmsr is not always defined as context-synchronizing */
3381 056b05f8 j_mayer
        ctx->exception = POWERPC_EXCP_STOP;
3382 be147d08 j_mayer
    }
3383 426613db j_mayer
#endif
3384 426613db j_mayer
}
3385 426613db j_mayer
#endif
3386 426613db j_mayer
3387 79aceca5 bellard
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
3388 79aceca5 bellard
{
3389 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
3390 e1833e1f j_mayer
    GEN_EXCP_PRIVREG(ctx);
3391 9a64fbe4 bellard
#else
3392 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
3393 e1833e1f j_mayer
        GEN_EXCP_PRIVREG(ctx);
3394 9fddaa0c bellard
        return;
3395 9a64fbe4 bellard
    }
3396 79aceca5 bellard
    gen_op_load_gpr_T0(rS(ctx->opcode));
3397 be147d08 j_mayer
    if (ctx->opcode & 0x00010000) {
3398 be147d08 j_mayer
        /* Special form that does not need any synchronisation */
3399 be147d08 j_mayer
        gen_op_update_riee();
3400 be147d08 j_mayer
    } else {
3401 056b05f8 j_mayer
        /* XXX: we need to update nip before the store
3402 056b05f8 j_mayer
         *      if we enter power saving mode, we will exit the loop
3403 056b05f8 j_mayer
         *      directly from ppc_store_msr
3404 056b05f8 j_mayer
         */
3405 be147d08 j_mayer
        gen_update_nip(ctx, ctx->nip);
3406 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
3407 be147d08 j_mayer
        if (!ctx->sf_mode)
3408 61c04807 aurel32
            tcg_gen_helper_0_1(do_store_msr_32, cpu_T[0]);
3409 be147d08 j_mayer
        else
3410 d9bce9d9 j_mayer
#endif
3411 61c04807 aurel32
            tcg_gen_helper_0_1(do_store_msr, cpu_T[0]);
3412 be147d08 j_mayer
        /* Must stop the translation as machine state (may have) changed */
3413 be147d08 j_mayer
        /* Note that mtmsrd is not always defined as context-synchronizing */
3414 056b05f8 j_mayer
        ctx->exception = POWERPC_EXCP_STOP;
3415 be147d08 j_mayer
    }
3416 9a64fbe4 bellard
#endif
3417 79aceca5 bellard
}
3418 79aceca5 bellard
3419 79aceca5 bellard
/* mtspr */
3420 79aceca5 bellard
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
3421 79aceca5 bellard
{
3422 3fc6c082 bellard
    void (*write_cb)(void *opaque, int sprn);
3423 79aceca5 bellard
    uint32_t sprn = SPR(ctx->opcode);
3424 79aceca5 bellard
3425 3fc6c082 bellard
#if !defined(CONFIG_USER_ONLY)
3426 be147d08 j_mayer
    if (ctx->supervisor == 2)
3427 be147d08 j_mayer
        write_cb = ctx->spr_cb[sprn].hea_write;
3428 7863667f j_mayer
    else if (ctx->supervisor)
3429 3fc6c082 bellard
        write_cb = ctx->spr_cb[sprn].oea_write;
3430 3fc6c082 bellard
    else
3431 9a64fbe4 bellard
#endif
3432 3fc6c082 bellard
        write_cb = ctx->spr_cb[sprn].uea_write;
3433 76a66253 j_mayer
    if (likely(write_cb != NULL)) {
3434 76a66253 j_mayer
        if (likely(write_cb != SPR_NOACCESS)) {
3435 3fc6c082 bellard
            gen_op_load_gpr_T0(rS(ctx->opcode));
3436 3fc6c082 bellard
            (*write_cb)(ctx, sprn);
3437 3fc6c082 bellard
        } else {
3438 3fc6c082 bellard
            /* Privilege exception */
3439 4a057712 j_mayer
            if (loglevel != 0) {
3440 077fc206 j_mayer
                fprintf(logfile, "Trying to write privileged spr %d %03x at "
3441 077fc206 j_mayer
                        ADDRX "\n", sprn, sprn, ctx->nip);
3442 f24e5695 bellard
            }
3443 077fc206 j_mayer
            printf("Trying to write privileged spr %d %03x at " ADDRX "\n",
3444 077fc206 j_mayer
                   sprn, sprn, ctx->nip);
3445 e1833e1f j_mayer
            GEN_EXCP_PRIVREG(ctx);
3446 76a66253 j_mayer
        }
3447 3fc6c082 bellard
    } else {
3448 3fc6c082 bellard
        /* Not defined */
3449 4a057712 j_mayer
        if (loglevel != 0) {
3450 077fc206 j_mayer
            fprintf(logfile, "Trying to write invalid spr %d %03x at "
3451 077fc206 j_mayer
                    ADDRX "\n", sprn, sprn, ctx->nip);
3452 f24e5695 bellard
        }
3453 077fc206 j_mayer
        printf("Trying to write invalid spr %d %03x at " ADDRX "\n",
3454 077fc206 j_mayer
               sprn, sprn, ctx->nip);
3455 e1833e1f j_mayer
        GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
3456 e1833e1f j_mayer
                 POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3457 79aceca5 bellard
    }
3458 79aceca5 bellard
}
3459 79aceca5 bellard
3460 79aceca5 bellard
/***                         Cache management                              ***/
3461 79aceca5 bellard
/* dcbf */
3462 0db1b20e j_mayer
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
3463 79aceca5 bellard
{
3464 dac454af j_mayer
    /* XXX: specification says this is treated as a load by the MMU */
3465 76a66253 j_mayer
    gen_addr_reg_index(ctx);
3466 a541f297 bellard
    op_ldst(lbz);
3467 79aceca5 bellard
}
3468 79aceca5 bellard
3469 79aceca5 bellard
/* dcbi (Supervisor only) */
3470 9a64fbe4 bellard
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
3471 79aceca5 bellard
{
3472 a541f297 bellard
#if defined(CONFIG_USER_ONLY)
3473 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
3474 a541f297 bellard
#else
3475 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
3476 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
3477 9fddaa0c bellard
        return;
3478 9a64fbe4 bellard
    }
3479 76a66253 j_mayer
    gen_addr_reg_index(ctx);
3480 76a66253 j_mayer
    /* XXX: specification says this should be treated as a store by the MMU */
3481 dac454af j_mayer
    op_ldst(lbz);
3482 a541f297 bellard
    op_ldst(stb);
3483 a541f297 bellard
#endif
3484 79aceca5 bellard
}
3485 79aceca5 bellard
3486 79aceca5 bellard
/* dcdst */
3487 9a64fbe4 bellard
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
3488 79aceca5 bellard
{
3489 76a66253 j_mayer
    /* XXX: specification say this is treated as a load by the MMU */
3490 76a66253 j_mayer
    gen_addr_reg_index(ctx);
3491 a541f297 bellard
    op_ldst(lbz);
3492 79aceca5 bellard
}
3493 79aceca5 bellard
3494 79aceca5 bellard
/* dcbt */
3495 0db1b20e j_mayer
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE)
3496 79aceca5 bellard
{
3497 0db1b20e j_mayer
    /* interpreted as no-op */
3498 76a66253 j_mayer
    /* XXX: specification say this is treated as a load by the MMU
3499 76a66253 j_mayer
     *      but does not generate any exception
3500 76a66253 j_mayer
     */
3501 79aceca5 bellard
}
3502 79aceca5 bellard
3503 79aceca5 bellard
/* dcbtst */
3504 0db1b20e j_mayer
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE)
3505 79aceca5 bellard
{
3506 0db1b20e j_mayer
    /* interpreted as no-op */
3507 76a66253 j_mayer
    /* XXX: specification say this is treated as a load by the MMU
3508 76a66253 j_mayer
     *      but does not generate any exception
3509 76a66253 j_mayer
     */
3510 79aceca5 bellard
}
3511 79aceca5 bellard
3512 79aceca5 bellard
/* dcbz */
3513 d63001d1 j_mayer
#define op_dcbz(n) (*gen_op_dcbz[n][ctx->mem_idx])()
3514 7863667f j_mayer
static GenOpFunc *gen_op_dcbz[4][NB_MEM_FUNCS] = {
3515 7863667f j_mayer
    /* 32 bytes cache line size */
3516 d63001d1 j_mayer
    {
3517 7863667f j_mayer
#define gen_op_dcbz_l32_le_raw        gen_op_dcbz_l32_raw
3518 7863667f j_mayer
#define gen_op_dcbz_l32_le_user       gen_op_dcbz_l32_user
3519 7863667f j_mayer
#define gen_op_dcbz_l32_le_kernel     gen_op_dcbz_l32_kernel
3520 7863667f j_mayer
#define gen_op_dcbz_l32_le_hypv       gen_op_dcbz_l32_hypv
3521 7863667f j_mayer
#define gen_op_dcbz_l32_le_64_raw     gen_op_dcbz_l32_64_raw
3522 7863667f j_mayer
#define gen_op_dcbz_l32_le_64_user    gen_op_dcbz_l32_64_user
3523 7863667f j_mayer
#define gen_op_dcbz_l32_le_64_kernel  gen_op_dcbz_l32_64_kernel
3524 7863667f j_mayer
#define gen_op_dcbz_l32_le_64_hypv    gen_op_dcbz_l32_64_hypv
3525 7863667f j_mayer
        GEN_MEM_FUNCS(dcbz_l32),
3526 d63001d1 j_mayer
    },
3527 7863667f j_mayer
    /* 64 bytes cache line size */
3528 d63001d1 j_mayer
    {
3529 7863667f j_mayer
#define gen_op_dcbz_l64_le_raw        gen_op_dcbz_l64_raw
3530 7863667f j_mayer
#define gen_op_dcbz_l64_le_user       gen_op_dcbz_l64_user
3531 7863667f j_mayer
#define gen_op_dcbz_l64_le_kernel     gen_op_dcbz_l64_kernel
3532 7863667f j_mayer
#define gen_op_dcbz_l64_le_hypv       gen_op_dcbz_l64_hypv
3533 7863667f j_mayer
#define gen_op_dcbz_l64_le_64_raw     gen_op_dcbz_l64_64_raw
3534 7863667f j_mayer
#define gen_op_dcbz_l64_le_64_user    gen_op_dcbz_l64_64_user
3535 7863667f j_mayer
#define gen_op_dcbz_l64_le_64_kernel  gen_op_dcbz_l64_64_kernel
3536 7863667f j_mayer
#define gen_op_dcbz_l64_le_64_hypv    gen_op_dcbz_l64_64_hypv
3537 7863667f j_mayer
        GEN_MEM_FUNCS(dcbz_l64),
3538 d63001d1 j_mayer
    },
3539 7863667f j_mayer
    /* 128 bytes cache line size */
3540 d63001d1 j_mayer
    {
3541 7863667f j_mayer
#define gen_op_dcbz_l128_le_raw       gen_op_dcbz_l128_raw
3542 7863667f j_mayer
#define gen_op_dcbz_l128_le_user      gen_op_dcbz_l128_user
3543 7863667f j_mayer
#define gen_op_dcbz_l128_le_kernel    gen_op_dcbz_l128_kernel
3544 7863667f j_mayer
#define gen_op_dcbz_l128_le_hypv      gen_op_dcbz_l128_hypv
3545 7863667f j_mayer
#define gen_op_dcbz_l128_le_64_raw    gen_op_dcbz_l128_64_raw
3546 7863667f j_mayer
#define gen_op_dcbz_l128_le_64_user   gen_op_dcbz_l128_64_user
3547 7863667f j_mayer
#define gen_op_dcbz_l128_le_64_kernel gen_op_dcbz_l128_64_kernel
3548 7863667f j_mayer
#define gen_op_dcbz_l128_le_64_hypv   gen_op_dcbz_l128_64_hypv
3549 7863667f j_mayer
        GEN_MEM_FUNCS(dcbz_l128),
3550 d63001d1 j_mayer
    },
3551 7863667f j_mayer
    /* tunable cache line size */
3552 d63001d1 j_mayer
    {
3553 7863667f j_mayer
#define gen_op_dcbz_le_raw            gen_op_dcbz_raw
3554 7863667f j_mayer
#define gen_op_dcbz_le_user           gen_op_dcbz_user
3555 7863667f j_mayer
#define gen_op_dcbz_le_kernel         gen_op_dcbz_kernel
3556 7863667f j_mayer
#define gen_op_dcbz_le_hypv           gen_op_dcbz_hypv
3557 7863667f j_mayer
#define gen_op_dcbz_le_64_raw         gen_op_dcbz_64_raw
3558 7863667f j_mayer
#define gen_op_dcbz_le_64_user        gen_op_dcbz_64_user
3559 7863667f j_mayer
#define gen_op_dcbz_le_64_kernel      gen_op_dcbz_64_kernel
3560 7863667f j_mayer
#define gen_op_dcbz_le_64_hypv        gen_op_dcbz_64_hypv
3561 7863667f j_mayer
        GEN_MEM_FUNCS(dcbz),
3562 d63001d1 j_mayer
    },
3563 76a66253 j_mayer
};
3564 9a64fbe4 bellard
3565 b068d6a7 j_mayer
static always_inline void handler_dcbz (DisasContext *ctx,
3566 b068d6a7 j_mayer
                                        int dcache_line_size)
3567 d63001d1 j_mayer
{
3568 d63001d1 j_mayer
    int n;
3569 d63001d1 j_mayer
3570 d63001d1 j_mayer
    switch (dcache_line_size) {
3571 d63001d1 j_mayer
    case 32:
3572 d63001d1 j_mayer
        n = 0;
3573 d63001d1 j_mayer
        break;
3574 d63001d1 j_mayer
    case 64:
3575 d63001d1 j_mayer
        n = 1;
3576 d63001d1 j_mayer
        break;
3577 d63001d1 j_mayer
    case 128:
3578 d63001d1 j_mayer
        n = 2;
3579 d63001d1 j_mayer
        break;
3580 d63001d1 j_mayer
    default:
3581 d63001d1 j_mayer
        n = 3;
3582 d63001d1 j_mayer
        break;
3583 d63001d1 j_mayer
    }
3584 d63001d1 j_mayer
    op_dcbz(n);
3585 d63001d1 j_mayer
}
3586 d63001d1 j_mayer
3587 d63001d1 j_mayer
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ)
3588 79aceca5 bellard
{
3589 76a66253 j_mayer
    gen_addr_reg_index(ctx);
3590 d63001d1 j_mayer
    handler_dcbz(ctx, ctx->dcache_line_size);
3591 d63001d1 j_mayer
    gen_op_check_reservation();
3592 d63001d1 j_mayer
}
3593 d63001d1 j_mayer
3594 c7697e1f j_mayer
GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT)
3595 d63001d1 j_mayer
{
3596 d63001d1 j_mayer
    gen_addr_reg_index(ctx);
3597 d63001d1 j_mayer
    if (ctx->opcode & 0x00200000)
3598 d63001d1 j_mayer
        handler_dcbz(ctx, ctx->dcache_line_size);
3599 d63001d1 j_mayer
    else
3600 d63001d1 j_mayer
        handler_dcbz(ctx, -1);
3601 4b3686fa bellard
    gen_op_check_reservation();
3602 79aceca5 bellard
}
3603 79aceca5 bellard
3604 79aceca5 bellard
/* icbi */
3605 36f69651 j_mayer
#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3606 7863667f j_mayer
#define gen_op_icbi_le_raw       gen_op_icbi_raw
3607 7863667f j_mayer
#define gen_op_icbi_le_user      gen_op_icbi_user
3608 7863667f j_mayer
#define gen_op_icbi_le_kernel    gen_op_icbi_kernel
3609 7863667f j_mayer
#define gen_op_icbi_le_hypv      gen_op_icbi_hypv
3610 7863667f j_mayer
#define gen_op_icbi_le_64_raw    gen_op_icbi_64_raw
3611 7863667f j_mayer
#define gen_op_icbi_le_64_user   gen_op_icbi_64_user
3612 7863667f j_mayer
#define gen_op_icbi_le_64_kernel gen_op_icbi_64_kernel
3613 7863667f j_mayer
#define gen_op_icbi_le_64_hypv   gen_op_icbi_64_hypv
3614 7863667f j_mayer
static GenOpFunc *gen_op_icbi[NB_MEM_FUNCS] = {
3615 7863667f j_mayer
    GEN_MEM_FUNCS(icbi),
3616 36f69651 j_mayer
};
3617 e1833e1f j_mayer
3618 1b413d55 j_mayer
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI)
3619 79aceca5 bellard
{
3620 30032c94 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
3621 30032c94 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
3622 76a66253 j_mayer
    gen_addr_reg_index(ctx);
3623 36f69651 j_mayer
    op_icbi();
3624 79aceca5 bellard
}
3625 79aceca5 bellard
3626 79aceca5 bellard
/* Optional: */
3627 79aceca5 bellard
/* dcba */
3628 a750fc0b j_mayer
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
3629 79aceca5 bellard
{
3630 0db1b20e j_mayer
    /* interpreted as no-op */
3631 0db1b20e j_mayer
    /* XXX: specification say this is treated as a store by the MMU
3632 0db1b20e j_mayer
     *      but does not generate any exception
3633 0db1b20e j_mayer
     */
3634 79aceca5 bellard
}
3635 79aceca5 bellard
3636 79aceca5 bellard
/***                    Segment register manipulation                      ***/
3637 79aceca5 bellard
/* Supervisor only: */
3638 79aceca5 bellard
/* mfsr */
3639 79aceca5 bellard
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
3640 79aceca5 bellard
{
3641 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
3642 e1833e1f j_mayer
    GEN_EXCP_PRIVREG(ctx);
3643 9a64fbe4 bellard
#else
3644 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
3645 e1833e1f j_mayer
        GEN_EXCP_PRIVREG(ctx);
3646 9fddaa0c bellard
        return;
3647 9a64fbe4 bellard
    }
3648 76a66253 j_mayer
    gen_op_set_T1(SR(ctx->opcode));
3649 76a66253 j_mayer
    gen_op_load_sr();
3650 9a64fbe4 bellard
    gen_op_store_T0_gpr(rD(ctx->opcode));
3651 9a64fbe4 bellard
#endif
3652 79aceca5 bellard
}
3653 79aceca5 bellard
3654 79aceca5 bellard
/* mfsrin */
3655 9a64fbe4 bellard
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3656 79aceca5 bellard
{
3657 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
3658 e1833e1f j_mayer
    GEN_EXCP_PRIVREG(ctx);
3659 9a64fbe4 bellard
#else
3660 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
3661 e1833e1f j_mayer
        GEN_EXCP_PRIVREG(ctx);
3662 9fddaa0c bellard
        return;
3663 9a64fbe4 bellard
    }
3664 9a64fbe4 bellard
    gen_op_load_gpr_T1(rB(ctx->opcode));
3665 76a66253 j_mayer
    gen_op_srli_T1(28);
3666 76a66253 j_mayer
    gen_op_load_sr();
3667 9a64fbe4 bellard
    gen_op_store_T0_gpr(rD(ctx->opcode));
3668 9a64fbe4 bellard
#endif
3669 79aceca5 bellard
}
3670 79aceca5 bellard
3671 79aceca5 bellard
/* mtsr */
3672 e63c59cb bellard
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3673 79aceca5 bellard
{
3674 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
3675 e1833e1f j_mayer
    GEN_EXCP_PRIVREG(ctx);
3676 9a64fbe4 bellard
#else
3677 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
3678 e1833e1f j_mayer
        GEN_EXCP_PRIVREG(ctx);
3679 9fddaa0c bellard
        return;
3680 9a64fbe4 bellard
    }
3681 9a64fbe4 bellard
    gen_op_load_gpr_T0(rS(ctx->opcode));
3682 76a66253 j_mayer
    gen_op_set_T1(SR(ctx->opcode));
3683 76a66253 j_mayer
    gen_op_store_sr();
3684 9a64fbe4 bellard
#endif
3685 79aceca5 bellard
}
3686 79aceca5 bellard
3687 79aceca5 bellard
/* mtsrin */
3688 9a64fbe4 bellard
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3689 79aceca5 bellard
{
3690 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
3691 e1833e1f j_mayer
    GEN_EXCP_PRIVREG(ctx);
3692 9a64fbe4 bellard
#else
3693 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
3694 e1833e1f j_mayer
        GEN_EXCP_PRIVREG(ctx);
3695 9fddaa0c bellard
        return;
3696 9a64fbe4 bellard
    }
3697 9a64fbe4 bellard
    gen_op_load_gpr_T0(rS(ctx->opcode));
3698 9a64fbe4 bellard
    gen_op_load_gpr_T1(rB(ctx->opcode));
3699 76a66253 j_mayer
    gen_op_srli_T1(28);
3700 76a66253 j_mayer
    gen_op_store_sr();
3701 9a64fbe4 bellard
#endif
3702 79aceca5 bellard
}
3703 79aceca5 bellard
3704 12de9a39 j_mayer
#if defined(TARGET_PPC64)
3705 12de9a39 j_mayer
/* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
3706 12de9a39 j_mayer
/* mfsr */
3707 c7697e1f j_mayer
GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B)
3708 12de9a39 j_mayer
{
3709 12de9a39 j_mayer
#if defined(CONFIG_USER_ONLY)
3710 12de9a39 j_mayer
    GEN_EXCP_PRIVREG(ctx);
3711 12de9a39 j_mayer
#else
3712 12de9a39 j_mayer
    if (unlikely(!ctx->supervisor)) {
3713 12de9a39 j_mayer
        GEN_EXCP_PRIVREG(ctx);
3714 12de9a39 j_mayer
        return;
3715 12de9a39 j_mayer
    }
3716 12de9a39 j_mayer
    gen_op_set_T1(SR(ctx->opcode));
3717 12de9a39 j_mayer
    gen_op_load_slb();
3718 12de9a39 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
3719 12de9a39 j_mayer
#endif
3720 12de9a39 j_mayer
}
3721 12de9a39 j_mayer
3722 12de9a39 j_mayer
/* mfsrin */
3723 c7697e1f j_mayer
GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
3724 c7697e1f j_mayer
             PPC_SEGMENT_64B)
3725 12de9a39 j_mayer
{
3726 12de9a39 j_mayer
#if defined(CONFIG_USER_ONLY)
3727 12de9a39 j_mayer
    GEN_EXCP_PRIVREG(ctx);
3728 12de9a39 j_mayer
#else
3729 12de9a39 j_mayer
    if (unlikely(!ctx->supervisor)) {
3730 12de9a39 j_mayer
        GEN_EXCP_PRIVREG(ctx);
3731 12de9a39 j_mayer
        return;
3732 12de9a39 j_mayer
    }
3733 12de9a39 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
3734 12de9a39 j_mayer
    gen_op_srli_T1(28);
3735 12de9a39 j_mayer
    gen_op_load_slb();
3736 12de9a39 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
3737 12de9a39 j_mayer
#endif
3738 12de9a39 j_mayer
}
3739 12de9a39 j_mayer
3740 12de9a39 j_mayer
/* mtsr */
3741 c7697e1f j_mayer
GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B)
3742 12de9a39 j_mayer
{
3743 12de9a39 j_mayer
#if defined(CONFIG_USER_ONLY)
3744 12de9a39 j_mayer
    GEN_EXCP_PRIVREG(ctx);
3745 12de9a39 j_mayer
#else
3746 12de9a39 j_mayer
    if (unlikely(!ctx->supervisor)) {
3747 12de9a39 j_mayer
        GEN_EXCP_PRIVREG(ctx);
3748 12de9a39 j_mayer
        return;
3749 12de9a39 j_mayer
    }
3750 12de9a39 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
3751 12de9a39 j_mayer
    gen_op_set_T1(SR(ctx->opcode));
3752 12de9a39 j_mayer
    gen_op_store_slb();
3753 12de9a39 j_mayer
#endif
3754 12de9a39 j_mayer
}
3755 12de9a39 j_mayer
3756 12de9a39 j_mayer
/* mtsrin */
3757 c7697e1f j_mayer
GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
3758 c7697e1f j_mayer
             PPC_SEGMENT_64B)
3759 12de9a39 j_mayer
{
3760 12de9a39 j_mayer
#if defined(CONFIG_USER_ONLY)
3761 12de9a39 j_mayer
    GEN_EXCP_PRIVREG(ctx);
3762 12de9a39 j_mayer
#else
3763 12de9a39 j_mayer
    if (unlikely(!ctx->supervisor)) {
3764 12de9a39 j_mayer
        GEN_EXCP_PRIVREG(ctx);
3765 12de9a39 j_mayer
        return;
3766 12de9a39 j_mayer
    }
3767 12de9a39 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
3768 12de9a39 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
3769 12de9a39 j_mayer
    gen_op_srli_T1(28);
3770 12de9a39 j_mayer
    gen_op_store_slb();
3771 12de9a39 j_mayer
#endif
3772 12de9a39 j_mayer
}
3773 12de9a39 j_mayer
#endif /* defined(TARGET_PPC64) */
3774 12de9a39 j_mayer
3775 79aceca5 bellard
/***                      Lookaside buffer management                      ***/
3776 79aceca5 bellard
/* Optional & supervisor only: */
3777 79aceca5 bellard
/* tlbia */
3778 3fc6c082 bellard
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
3779 79aceca5 bellard
{
3780 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
3781 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
3782 9a64fbe4 bellard
#else
3783 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
3784 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
3785 9fddaa0c bellard
        return;
3786 9a64fbe4 bellard
    }
3787 9a64fbe4 bellard
    gen_op_tlbia();
3788 9a64fbe4 bellard
#endif
3789 79aceca5 bellard
}
3790 79aceca5 bellard
3791 79aceca5 bellard
/* tlbie */
3792 76a66253 j_mayer
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
3793 79aceca5 bellard
{
3794 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
3795 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
3796 9a64fbe4 bellard
#else
3797 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
3798 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
3799 9fddaa0c bellard
        return;
3800 9a64fbe4 bellard
    }
3801 9a64fbe4 bellard
    gen_op_load_gpr_T0(rB(ctx->opcode));
3802 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
3803 d9bce9d9 j_mayer
    if (ctx->sf_mode)
3804 d9bce9d9 j_mayer
        gen_op_tlbie_64();
3805 d9bce9d9 j_mayer
    else
3806 d9bce9d9 j_mayer
#endif
3807 d9bce9d9 j_mayer
        gen_op_tlbie();
3808 9a64fbe4 bellard
#endif
3809 79aceca5 bellard
}
3810 79aceca5 bellard
3811 79aceca5 bellard
/* tlbsync */
3812 76a66253 j_mayer
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
3813 79aceca5 bellard
{
3814 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
3815 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
3816 9a64fbe4 bellard
#else
3817 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
3818 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
3819 9fddaa0c bellard
        return;
3820 9a64fbe4 bellard
    }
3821 9a64fbe4 bellard
    /* This has no effect: it should ensure that all previous
3822 9a64fbe4 bellard
     * tlbie have completed
3823 9a64fbe4 bellard
     */
3824 e1833e1f j_mayer
    GEN_STOP(ctx);
3825 9a64fbe4 bellard
#endif
3826 79aceca5 bellard
}
3827 79aceca5 bellard
3828 426613db j_mayer
#if defined(TARGET_PPC64)
3829 426613db j_mayer
/* slbia */
3830 426613db j_mayer
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
3831 426613db j_mayer
{
3832 426613db j_mayer
#if defined(CONFIG_USER_ONLY)
3833 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
3834 426613db j_mayer
#else
3835 426613db j_mayer
    if (unlikely(!ctx->supervisor)) {
3836 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
3837 426613db j_mayer
        return;
3838 426613db j_mayer
    }
3839 426613db j_mayer
    gen_op_slbia();
3840 426613db j_mayer
#endif
3841 426613db j_mayer
}
3842 426613db j_mayer
3843 426613db j_mayer
/* slbie */
3844 426613db j_mayer
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
3845 426613db j_mayer
{
3846 426613db j_mayer
#if defined(CONFIG_USER_ONLY)
3847 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
3848 426613db j_mayer
#else
3849 426613db j_mayer
    if (unlikely(!ctx->supervisor)) {
3850 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
3851 426613db j_mayer
        return;
3852 426613db j_mayer
    }
3853 426613db j_mayer
    gen_op_load_gpr_T0(rB(ctx->opcode));
3854 426613db j_mayer
    gen_op_slbie();
3855 426613db j_mayer
#endif
3856 426613db j_mayer
}
3857 426613db j_mayer
#endif
3858 426613db j_mayer
3859 79aceca5 bellard
/***                              External control                         ***/
3860 79aceca5 bellard
/* Optional: */
3861 9a64fbe4 bellard
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
3862 9a64fbe4 bellard
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
3863 7863667f j_mayer
static GenOpFunc *gen_op_eciwx[NB_MEM_FUNCS] = {
3864 7863667f j_mayer
    GEN_MEM_FUNCS(eciwx),
3865 111bfab3 bellard
};
3866 7863667f j_mayer
static GenOpFunc *gen_op_ecowx[NB_MEM_FUNCS] = {
3867 7863667f j_mayer
    GEN_MEM_FUNCS(ecowx),
3868 111bfab3 bellard
};
3869 9a64fbe4 bellard
3870 111bfab3 bellard
/* eciwx */
3871 79aceca5 bellard
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
3872 79aceca5 bellard
{
3873 9a64fbe4 bellard
    /* Should check EAR[E] & alignment ! */
3874 76a66253 j_mayer
    gen_addr_reg_index(ctx);
3875 76a66253 j_mayer
    op_eciwx();
3876 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
3877 76a66253 j_mayer
}
3878 76a66253 j_mayer
3879 76a66253 j_mayer
/* ecowx */
3880 76a66253 j_mayer
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
3881 76a66253 j_mayer
{
3882 76a66253 j_mayer
    /* Should check EAR[E] & alignment ! */
3883 76a66253 j_mayer
    gen_addr_reg_index(ctx);
3884 76a66253 j_mayer
    gen_op_load_gpr_T1(rS(ctx->opcode));
3885 76a66253 j_mayer
    op_ecowx();
3886 76a66253 j_mayer
}
3887 76a66253 j_mayer
3888 76a66253 j_mayer
/* PowerPC 601 specific instructions */
3889 76a66253 j_mayer
/* abs - abs. */
3890 76a66253 j_mayer
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
3891 76a66253 j_mayer
{
3892 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
3893 76a66253 j_mayer
    gen_op_POWER_abs();
3894 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
3895 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
3896 76a66253 j_mayer
        gen_set_Rc0(ctx);
3897 76a66253 j_mayer
}
3898 76a66253 j_mayer
3899 76a66253 j_mayer
/* abso - abso. */
3900 76a66253 j_mayer
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
3901 76a66253 j_mayer
{
3902 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
3903 76a66253 j_mayer
    gen_op_POWER_abso();
3904 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
3905 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
3906 76a66253 j_mayer
        gen_set_Rc0(ctx);
3907 76a66253 j_mayer
}
3908 76a66253 j_mayer
3909 76a66253 j_mayer
/* clcs */
3910 a750fc0b j_mayer
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
3911 76a66253 j_mayer
{
3912 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
3913 76a66253 j_mayer
    gen_op_POWER_clcs();
3914 c7697e1f j_mayer
    /* Rc=1 sets CR0 to an undefined state */
3915 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
3916 76a66253 j_mayer
}
3917 76a66253 j_mayer
3918 76a66253 j_mayer
/* div - div. */
3919 76a66253 j_mayer
GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
3920 76a66253 j_mayer
{
3921 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
3922 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
3923 76a66253 j_mayer
    gen_op_POWER_div();
3924 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
3925 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
3926 76a66253 j_mayer
        gen_set_Rc0(ctx);
3927 76a66253 j_mayer
}
3928 76a66253 j_mayer
3929 76a66253 j_mayer
/* divo - divo. */
3930 76a66253 j_mayer
GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
3931 76a66253 j_mayer
{
3932 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
3933 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
3934 76a66253 j_mayer
    gen_op_POWER_divo();
3935 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
3936 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
3937 76a66253 j_mayer
        gen_set_Rc0(ctx);
3938 76a66253 j_mayer
}
3939 76a66253 j_mayer
3940 76a66253 j_mayer
/* divs - divs. */
3941 76a66253 j_mayer
GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
3942 76a66253 j_mayer
{
3943 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
3944 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
3945 76a66253 j_mayer
    gen_op_POWER_divs();
3946 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
3947 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
3948 76a66253 j_mayer
        gen_set_Rc0(ctx);
3949 76a66253 j_mayer
}
3950 76a66253 j_mayer
3951 76a66253 j_mayer
/* divso - divso. */
3952 76a66253 j_mayer
GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
3953 76a66253 j_mayer
{
3954 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
3955 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
3956 76a66253 j_mayer
    gen_op_POWER_divso();
3957 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
3958 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
3959 76a66253 j_mayer
        gen_set_Rc0(ctx);
3960 76a66253 j_mayer
}
3961 76a66253 j_mayer
3962 76a66253 j_mayer
/* doz - doz. */
3963 76a66253 j_mayer
GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR)
3964 76a66253 j_mayer
{
3965 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
3966 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
3967 76a66253 j_mayer
    gen_op_POWER_doz();
3968 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
3969 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
3970 76a66253 j_mayer
        gen_set_Rc0(ctx);
3971 76a66253 j_mayer
}
3972 76a66253 j_mayer
3973 76a66253 j_mayer
/* dozo - dozo. */
3974 76a66253 j_mayer
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
3975 76a66253 j_mayer
{
3976 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
3977 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
3978 76a66253 j_mayer
    gen_op_POWER_dozo();
3979 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
3980 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
3981 76a66253 j_mayer
        gen_set_Rc0(ctx);
3982 76a66253 j_mayer
}
3983 76a66253 j_mayer
3984 76a66253 j_mayer
/* dozi */
3985 76a66253 j_mayer
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
3986 76a66253 j_mayer
{
3987 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
3988 76a66253 j_mayer
    gen_op_set_T1(SIMM(ctx->opcode));
3989 76a66253 j_mayer
    gen_op_POWER_doz();
3990 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
3991 76a66253 j_mayer
}
3992 76a66253 j_mayer
3993 7863667f j_mayer
/* As lscbx load from memory byte after byte, it's always endian safe.
3994 7863667f j_mayer
 * Original POWER is 32 bits only, define 64 bits ops as 32 bits ones
3995 7863667f j_mayer
 */
3996 2857068e j_mayer
#define op_POWER_lscbx(start, ra, rb)                                         \
3997 76a66253 j_mayer
(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
3998 7863667f j_mayer
#define gen_op_POWER_lscbx_64_raw       gen_op_POWER_lscbx_raw
3999 7863667f j_mayer
#define gen_op_POWER_lscbx_64_user      gen_op_POWER_lscbx_user
4000 7863667f j_mayer
#define gen_op_POWER_lscbx_64_kernel    gen_op_POWER_lscbx_kernel
4001 7863667f j_mayer
#define gen_op_POWER_lscbx_64_hypv      gen_op_POWER_lscbx_hypv
4002 7863667f j_mayer
#define gen_op_POWER_lscbx_le_raw       gen_op_POWER_lscbx_raw
4003 7863667f j_mayer
#define gen_op_POWER_lscbx_le_user      gen_op_POWER_lscbx_user
4004 7863667f j_mayer
#define gen_op_POWER_lscbx_le_kernel    gen_op_POWER_lscbx_kernel
4005 7863667f j_mayer
#define gen_op_POWER_lscbx_le_hypv      gen_op_POWER_lscbx_hypv
4006 7863667f j_mayer
#define gen_op_POWER_lscbx_le_64_raw    gen_op_POWER_lscbx_raw
4007 7863667f j_mayer
#define gen_op_POWER_lscbx_le_64_user   gen_op_POWER_lscbx_user
4008 7863667f j_mayer
#define gen_op_POWER_lscbx_le_64_kernel gen_op_POWER_lscbx_kernel
4009 7863667f j_mayer
#define gen_op_POWER_lscbx_le_64_hypv   gen_op_POWER_lscbx_hypv
4010 7863667f j_mayer
static GenOpFunc3 *gen_op_POWER_lscbx[NB_MEM_FUNCS] = {
4011 7863667f j_mayer
    GEN_MEM_FUNCS(POWER_lscbx),
4012 76a66253 j_mayer
};
4013 76a66253 j_mayer
4014 76a66253 j_mayer
/* lscbx - lscbx. */
4015 76a66253 j_mayer
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
4016 76a66253 j_mayer
{
4017 76a66253 j_mayer
    int ra = rA(ctx->opcode);
4018 76a66253 j_mayer
    int rb = rB(ctx->opcode);
4019 76a66253 j_mayer
4020 76a66253 j_mayer
    gen_addr_reg_index(ctx);
4021 76a66253 j_mayer
    if (ra == 0) {
4022 76a66253 j_mayer
        ra = rb;
4023 76a66253 j_mayer
    }
4024 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
4025 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
4026 76a66253 j_mayer
    gen_op_load_xer_bc();
4027 76a66253 j_mayer
    gen_op_load_xer_cmp();
4028 76a66253 j_mayer
    op_POWER_lscbx(rD(ctx->opcode), ra, rb);
4029 76a66253 j_mayer
    gen_op_store_xer_bc();
4030 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4031 76a66253 j_mayer
        gen_set_Rc0(ctx);
4032 76a66253 j_mayer
}
4033 76a66253 j_mayer
4034 76a66253 j_mayer
/* maskg - maskg. */
4035 76a66253 j_mayer
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
4036 76a66253 j_mayer
{
4037 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4038 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4039 76a66253 j_mayer
    gen_op_POWER_maskg();
4040 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4041 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4042 76a66253 j_mayer
        gen_set_Rc0(ctx);
4043 76a66253 j_mayer
}
4044 76a66253 j_mayer
4045 76a66253 j_mayer
/* maskir - maskir. */
4046 76a66253 j_mayer
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
4047 76a66253 j_mayer
{
4048 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4049 76a66253 j_mayer
    gen_op_load_gpr_T1(rS(ctx->opcode));
4050 76a66253 j_mayer
    gen_op_load_gpr_T2(rB(ctx->opcode));
4051 76a66253 j_mayer
    gen_op_POWER_maskir();
4052 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4053 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4054 76a66253 j_mayer
        gen_set_Rc0(ctx);
4055 76a66253 j_mayer
}
4056 76a66253 j_mayer
4057 76a66253 j_mayer
/* mul - mul. */
4058 76a66253 j_mayer
GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
4059 76a66253 j_mayer
{
4060 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4061 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4062 76a66253 j_mayer
    gen_op_POWER_mul();
4063 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4064 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4065 76a66253 j_mayer
        gen_set_Rc0(ctx);
4066 76a66253 j_mayer
}
4067 76a66253 j_mayer
4068 76a66253 j_mayer
/* mulo - mulo. */
4069 76a66253 j_mayer
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
4070 76a66253 j_mayer
{
4071 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4072 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4073 76a66253 j_mayer
    gen_op_POWER_mulo();
4074 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4075 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4076 76a66253 j_mayer
        gen_set_Rc0(ctx);
4077 76a66253 j_mayer
}
4078 76a66253 j_mayer
4079 76a66253 j_mayer
/* nabs - nabs. */
4080 76a66253 j_mayer
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
4081 76a66253 j_mayer
{
4082 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4083 76a66253 j_mayer
    gen_op_POWER_nabs();
4084 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4085 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4086 76a66253 j_mayer
        gen_set_Rc0(ctx);
4087 76a66253 j_mayer
}
4088 76a66253 j_mayer
4089 76a66253 j_mayer
/* nabso - nabso. */
4090 76a66253 j_mayer
GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
4091 76a66253 j_mayer
{
4092 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4093 76a66253 j_mayer
    gen_op_POWER_nabso();
4094 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4095 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4096 76a66253 j_mayer
        gen_set_Rc0(ctx);
4097 76a66253 j_mayer
}
4098 76a66253 j_mayer
4099 76a66253 j_mayer
/* rlmi - rlmi. */
4100 76a66253 j_mayer
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
4101 76a66253 j_mayer
{
4102 76a66253 j_mayer
    uint32_t mb, me;
4103 76a66253 j_mayer
4104 76a66253 j_mayer
    mb = MB(ctx->opcode);
4105 76a66253 j_mayer
    me = ME(ctx->opcode);
4106 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4107 76a66253 j_mayer
    gen_op_load_gpr_T1(rA(ctx->opcode));
4108 76a66253 j_mayer
    gen_op_load_gpr_T2(rB(ctx->opcode));
4109 76a66253 j_mayer
    gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
4110 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4111 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4112 76a66253 j_mayer
        gen_set_Rc0(ctx);
4113 76a66253 j_mayer
}
4114 76a66253 j_mayer
4115 76a66253 j_mayer
/* rrib - rrib. */
4116 76a66253 j_mayer
GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
4117 76a66253 j_mayer
{
4118 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4119 76a66253 j_mayer
    gen_op_load_gpr_T1(rA(ctx->opcode));
4120 76a66253 j_mayer
    gen_op_load_gpr_T2(rB(ctx->opcode));
4121 76a66253 j_mayer
    gen_op_POWER_rrib();
4122 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4123 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4124 76a66253 j_mayer
        gen_set_Rc0(ctx);
4125 76a66253 j_mayer
}
4126 76a66253 j_mayer
4127 76a66253 j_mayer
/* sle - sle. */
4128 76a66253 j_mayer
GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
4129 76a66253 j_mayer
{
4130 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4131 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4132 76a66253 j_mayer
    gen_op_POWER_sle();
4133 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4134 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4135 76a66253 j_mayer
        gen_set_Rc0(ctx);
4136 76a66253 j_mayer
}
4137 76a66253 j_mayer
4138 76a66253 j_mayer
/* sleq - sleq. */
4139 76a66253 j_mayer
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
4140 76a66253 j_mayer
{
4141 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4142 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4143 76a66253 j_mayer
    gen_op_POWER_sleq();
4144 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4145 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4146 76a66253 j_mayer
        gen_set_Rc0(ctx);
4147 76a66253 j_mayer
}
4148 76a66253 j_mayer
4149 76a66253 j_mayer
/* sliq - sliq. */
4150 76a66253 j_mayer
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
4151 76a66253 j_mayer
{
4152 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4153 76a66253 j_mayer
    gen_op_set_T1(SH(ctx->opcode));
4154 76a66253 j_mayer
    gen_op_POWER_sle();
4155 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4156 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4157 76a66253 j_mayer
        gen_set_Rc0(ctx);
4158 76a66253 j_mayer
}
4159 76a66253 j_mayer
4160 76a66253 j_mayer
/* slliq - slliq. */
4161 76a66253 j_mayer
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
4162 76a66253 j_mayer
{
4163 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4164 76a66253 j_mayer
    gen_op_set_T1(SH(ctx->opcode));
4165 76a66253 j_mayer
    gen_op_POWER_sleq();
4166 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4167 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4168 76a66253 j_mayer
        gen_set_Rc0(ctx);
4169 76a66253 j_mayer
}
4170 76a66253 j_mayer
4171 76a66253 j_mayer
/* sllq - sllq. */
4172 76a66253 j_mayer
GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR)
4173 76a66253 j_mayer
{
4174 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4175 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4176 76a66253 j_mayer
    gen_op_POWER_sllq();
4177 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4178 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4179 76a66253 j_mayer
        gen_set_Rc0(ctx);
4180 76a66253 j_mayer
}
4181 76a66253 j_mayer
4182 76a66253 j_mayer
/* slq - slq. */
4183 76a66253 j_mayer
GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR)
4184 76a66253 j_mayer
{
4185 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4186 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4187 76a66253 j_mayer
    gen_op_POWER_slq();
4188 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4189 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4190 76a66253 j_mayer
        gen_set_Rc0(ctx);
4191 76a66253 j_mayer
}
4192 76a66253 j_mayer
4193 d9bce9d9 j_mayer
/* sraiq - sraiq. */
4194 76a66253 j_mayer
GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
4195 76a66253 j_mayer
{
4196 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4197 76a66253 j_mayer
    gen_op_set_T1(SH(ctx->opcode));
4198 76a66253 j_mayer
    gen_op_POWER_sraq();
4199 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4200 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4201 76a66253 j_mayer
        gen_set_Rc0(ctx);
4202 76a66253 j_mayer
}
4203 76a66253 j_mayer
4204 76a66253 j_mayer
/* sraq - sraq. */
4205 76a66253 j_mayer
GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR)
4206 76a66253 j_mayer
{
4207 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4208 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4209 76a66253 j_mayer
    gen_op_POWER_sraq();
4210 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4211 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4212 76a66253 j_mayer
        gen_set_Rc0(ctx);
4213 76a66253 j_mayer
}
4214 76a66253 j_mayer
4215 76a66253 j_mayer
/* sre - sre. */
4216 76a66253 j_mayer
GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR)
4217 76a66253 j_mayer
{
4218 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4219 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4220 76a66253 j_mayer
    gen_op_POWER_sre();
4221 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4222 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4223 76a66253 j_mayer
        gen_set_Rc0(ctx);
4224 76a66253 j_mayer
}
4225 76a66253 j_mayer
4226 76a66253 j_mayer
/* srea - srea. */
4227 76a66253 j_mayer
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
4228 76a66253 j_mayer
{
4229 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4230 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4231 76a66253 j_mayer
    gen_op_POWER_srea();
4232 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4233 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4234 76a66253 j_mayer
        gen_set_Rc0(ctx);
4235 76a66253 j_mayer
}
4236 76a66253 j_mayer
4237 76a66253 j_mayer
/* sreq */
4238 76a66253 j_mayer
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
4239 76a66253 j_mayer
{
4240 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4241 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4242 76a66253 j_mayer
    gen_op_POWER_sreq();
4243 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4244 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4245 76a66253 j_mayer
        gen_set_Rc0(ctx);
4246 76a66253 j_mayer
}
4247 76a66253 j_mayer
4248 76a66253 j_mayer
/* sriq */
4249 76a66253 j_mayer
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
4250 76a66253 j_mayer
{
4251 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4252 76a66253 j_mayer
    gen_op_set_T1(SH(ctx->opcode));
4253 76a66253 j_mayer
    gen_op_POWER_srq();
4254 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4255 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4256 76a66253 j_mayer
        gen_set_Rc0(ctx);
4257 76a66253 j_mayer
}
4258 76a66253 j_mayer
4259 76a66253 j_mayer
/* srliq */
4260 76a66253 j_mayer
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
4261 76a66253 j_mayer
{
4262 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4263 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4264 76a66253 j_mayer
    gen_op_set_T1(SH(ctx->opcode));
4265 76a66253 j_mayer
    gen_op_POWER_srlq();
4266 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4267 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4268 76a66253 j_mayer
        gen_set_Rc0(ctx);
4269 76a66253 j_mayer
}
4270 76a66253 j_mayer
4271 76a66253 j_mayer
/* srlq */
4272 76a66253 j_mayer
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
4273 76a66253 j_mayer
{
4274 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4275 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4276 76a66253 j_mayer
    gen_op_POWER_srlq();
4277 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4278 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4279 76a66253 j_mayer
        gen_set_Rc0(ctx);
4280 76a66253 j_mayer
}
4281 76a66253 j_mayer
4282 76a66253 j_mayer
/* srq */
4283 76a66253 j_mayer
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
4284 76a66253 j_mayer
{
4285 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4286 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4287 76a66253 j_mayer
    gen_op_POWER_srq();
4288 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4289 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4290 76a66253 j_mayer
        gen_set_Rc0(ctx);
4291 76a66253 j_mayer
}
4292 76a66253 j_mayer
4293 76a66253 j_mayer
/* PowerPC 602 specific instructions */
4294 76a66253 j_mayer
/* dsa  */
4295 76a66253 j_mayer
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
4296 76a66253 j_mayer
{
4297 76a66253 j_mayer
    /* XXX: TODO */
4298 e1833e1f j_mayer
    GEN_EXCP_INVAL(ctx);
4299 76a66253 j_mayer
}
4300 76a66253 j_mayer
4301 76a66253 j_mayer
/* esa */
4302 76a66253 j_mayer
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
4303 76a66253 j_mayer
{
4304 76a66253 j_mayer
    /* XXX: TODO */
4305 e1833e1f j_mayer
    GEN_EXCP_INVAL(ctx);
4306 76a66253 j_mayer
}
4307 76a66253 j_mayer
4308 76a66253 j_mayer
/* mfrom */
4309 76a66253 j_mayer
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
4310 76a66253 j_mayer
{
4311 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4312 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4313 76a66253 j_mayer
#else
4314 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4315 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4316 76a66253 j_mayer
        return;
4317 76a66253 j_mayer
    }
4318 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4319 76a66253 j_mayer
    gen_op_602_mfrom();
4320 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4321 76a66253 j_mayer
#endif
4322 76a66253 j_mayer
}
4323 76a66253 j_mayer
4324 76a66253 j_mayer
/* 602 - 603 - G2 TLB management */
4325 76a66253 j_mayer
/* tlbld */
4326 c7697e1f j_mayer
GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
4327 76a66253 j_mayer
{
4328 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4329 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4330 76a66253 j_mayer
#else
4331 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4332 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4333 76a66253 j_mayer
        return;
4334 76a66253 j_mayer
    }
4335 76a66253 j_mayer
    gen_op_load_gpr_T0(rB(ctx->opcode));
4336 76a66253 j_mayer
    gen_op_6xx_tlbld();
4337 76a66253 j_mayer
#endif
4338 76a66253 j_mayer
}
4339 76a66253 j_mayer
4340 76a66253 j_mayer
/* tlbli */
4341 c7697e1f j_mayer
GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
4342 76a66253 j_mayer
{
4343 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4344 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4345 76a66253 j_mayer
#else
4346 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4347 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4348 76a66253 j_mayer
        return;
4349 76a66253 j_mayer
    }
4350 76a66253 j_mayer
    gen_op_load_gpr_T0(rB(ctx->opcode));
4351 76a66253 j_mayer
    gen_op_6xx_tlbli();
4352 76a66253 j_mayer
#endif
4353 76a66253 j_mayer
}
4354 76a66253 j_mayer
4355 7dbe11ac j_mayer
/* 74xx TLB management */
4356 7dbe11ac j_mayer
/* tlbld */
4357 c7697e1f j_mayer
GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB)
4358 7dbe11ac j_mayer
{
4359 7dbe11ac j_mayer
#if defined(CONFIG_USER_ONLY)
4360 7dbe11ac j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4361 7dbe11ac j_mayer
#else
4362 7dbe11ac j_mayer
    if (unlikely(!ctx->supervisor)) {
4363 7dbe11ac j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4364 7dbe11ac j_mayer
        return;
4365 7dbe11ac j_mayer
    }
4366 7dbe11ac j_mayer
    gen_op_load_gpr_T0(rB(ctx->opcode));
4367 7dbe11ac j_mayer
    gen_op_74xx_tlbld();
4368 7dbe11ac j_mayer
#endif
4369 7dbe11ac j_mayer
}
4370 7dbe11ac j_mayer
4371 7dbe11ac j_mayer
/* tlbli */
4372 c7697e1f j_mayer
GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB)
4373 7dbe11ac j_mayer
{
4374 7dbe11ac j_mayer
#if defined(CONFIG_USER_ONLY)
4375 7dbe11ac j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4376 7dbe11ac j_mayer
#else
4377 7dbe11ac j_mayer
    if (unlikely(!ctx->supervisor)) {
4378 7dbe11ac j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4379 7dbe11ac j_mayer
        return;
4380 7dbe11ac j_mayer
    }
4381 7dbe11ac j_mayer
    gen_op_load_gpr_T0(rB(ctx->opcode));
4382 7dbe11ac j_mayer
    gen_op_74xx_tlbli();
4383 7dbe11ac j_mayer
#endif
4384 7dbe11ac j_mayer
}
4385 7dbe11ac j_mayer
4386 76a66253 j_mayer
/* POWER instructions not in PowerPC 601 */
4387 76a66253 j_mayer
/* clf */
4388 76a66253 j_mayer
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
4389 76a66253 j_mayer
{
4390 76a66253 j_mayer
    /* Cache line flush: implemented as no-op */
4391 76a66253 j_mayer
}
4392 76a66253 j_mayer
4393 76a66253 j_mayer
/* cli */
4394 76a66253 j_mayer
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
4395 76a66253 j_mayer
{
4396 7f75ffd3 blueswir1
    /* Cache line invalidate: privileged and treated as no-op */
4397 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4398 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4399 76a66253 j_mayer
#else
4400 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4401 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4402 76a66253 j_mayer
        return;
4403 76a66253 j_mayer
    }
4404 76a66253 j_mayer
#endif
4405 76a66253 j_mayer
}
4406 76a66253 j_mayer
4407 76a66253 j_mayer
/* dclst */
4408 76a66253 j_mayer
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
4409 76a66253 j_mayer
{
4410 76a66253 j_mayer
    /* Data cache line store: treated as no-op */
4411 76a66253 j_mayer
}
4412 76a66253 j_mayer
4413 76a66253 j_mayer
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
4414 76a66253 j_mayer
{
4415 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4416 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4417 76a66253 j_mayer
#else
4418 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4419 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4420 76a66253 j_mayer
        return;
4421 76a66253 j_mayer
    }
4422 76a66253 j_mayer
    int ra = rA(ctx->opcode);
4423 76a66253 j_mayer
    int rd = rD(ctx->opcode);
4424 76a66253 j_mayer
4425 76a66253 j_mayer
    gen_addr_reg_index(ctx);
4426 76a66253 j_mayer
    gen_op_POWER_mfsri();
4427 76a66253 j_mayer
    gen_op_store_T0_gpr(rd);
4428 76a66253 j_mayer
    if (ra != 0 && ra != rd)
4429 76a66253 j_mayer
        gen_op_store_T1_gpr(ra);
4430 76a66253 j_mayer
#endif
4431 76a66253 j_mayer
}
4432 76a66253 j_mayer
4433 76a66253 j_mayer
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
4434 76a66253 j_mayer
{
4435 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4436 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4437 76a66253 j_mayer
#else
4438 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4439 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4440 76a66253 j_mayer
        return;
4441 76a66253 j_mayer
    }
4442 76a66253 j_mayer
    gen_addr_reg_index(ctx);
4443 76a66253 j_mayer
    gen_op_POWER_rac();
4444 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4445 76a66253 j_mayer
#endif
4446 76a66253 j_mayer
}
4447 76a66253 j_mayer
4448 76a66253 j_mayer
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
4449 76a66253 j_mayer
{
4450 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4451 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4452 76a66253 j_mayer
#else
4453 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4454 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4455 76a66253 j_mayer
        return;
4456 76a66253 j_mayer
    }
4457 76a66253 j_mayer
    gen_op_POWER_rfsvc();
4458 e1833e1f j_mayer
    GEN_SYNC(ctx);
4459 76a66253 j_mayer
#endif
4460 76a66253 j_mayer
}
4461 76a66253 j_mayer
4462 76a66253 j_mayer
/* svc is not implemented for now */
4463 76a66253 j_mayer
4464 76a66253 j_mayer
/* POWER2 specific instructions */
4465 76a66253 j_mayer
/* Quad manipulation (load/store two floats at a time) */
4466 7863667f j_mayer
/* Original POWER2 is 32 bits only, define 64 bits ops as 32 bits ones */
4467 76a66253 j_mayer
#define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
4468 76a66253 j_mayer
#define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
4469 7863667f j_mayer
#define gen_op_POWER2_lfq_64_raw        gen_op_POWER2_lfq_raw
4470 7863667f j_mayer
#define gen_op_POWER2_lfq_64_user       gen_op_POWER2_lfq_user
4471 7863667f j_mayer
#define gen_op_POWER2_lfq_64_kernel     gen_op_POWER2_lfq_kernel
4472 7863667f j_mayer
#define gen_op_POWER2_lfq_64_hypv       gen_op_POWER2_lfq_hypv
4473 7863667f j_mayer
#define gen_op_POWER2_lfq_le_64_raw     gen_op_POWER2_lfq_le_raw
4474 7863667f j_mayer
#define gen_op_POWER2_lfq_le_64_user    gen_op_POWER2_lfq_le_user
4475 7863667f j_mayer
#define gen_op_POWER2_lfq_le_64_kernel  gen_op_POWER2_lfq_le_kernel
4476 7863667f j_mayer
#define gen_op_POWER2_lfq_le_64_hypv    gen_op_POWER2_lfq_le_hypv
4477 7863667f j_mayer
#define gen_op_POWER2_stfq_64_raw       gen_op_POWER2_stfq_raw
4478 7863667f j_mayer
#define gen_op_POWER2_stfq_64_user      gen_op_POWER2_stfq_user
4479 7863667f j_mayer
#define gen_op_POWER2_stfq_64_kernel    gen_op_POWER2_stfq_kernel
4480 7863667f j_mayer
#define gen_op_POWER2_stfq_64_hypv      gen_op_POWER2_stfq_hypv
4481 7863667f j_mayer
#define gen_op_POWER2_stfq_le_64_raw    gen_op_POWER2_stfq_le_raw
4482 7863667f j_mayer
#define gen_op_POWER2_stfq_le_64_user   gen_op_POWER2_stfq_le_user
4483 7863667f j_mayer
#define gen_op_POWER2_stfq_le_64_kernel gen_op_POWER2_stfq_le_kernel
4484 7863667f j_mayer
#define gen_op_POWER2_stfq_le_64_hypv   gen_op_POWER2_stfq_le_hypv
4485 7863667f j_mayer
static GenOpFunc *gen_op_POWER2_lfq[NB_MEM_FUNCS] = {
4486 7863667f j_mayer
    GEN_MEM_FUNCS(POWER2_lfq),
4487 76a66253 j_mayer
};
4488 7863667f j_mayer
static GenOpFunc *gen_op_POWER2_stfq[NB_MEM_FUNCS] = {
4489 7863667f j_mayer
    GEN_MEM_FUNCS(POWER2_stfq),
4490 76a66253 j_mayer
};
4491 76a66253 j_mayer
4492 76a66253 j_mayer
/* lfq */
4493 76a66253 j_mayer
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4494 76a66253 j_mayer
{
4495 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
4496 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
4497 9d53c753 j_mayer
    gen_addr_imm_index(ctx, 0);
4498 76a66253 j_mayer
    op_POWER2_lfq();
4499 76a66253 j_mayer
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4500 76a66253 j_mayer
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4501 76a66253 j_mayer
}
4502 76a66253 j_mayer
4503 76a66253 j_mayer
/* lfqu */
4504 76a66253 j_mayer
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4505 76a66253 j_mayer
{
4506 76a66253 j_mayer
    int ra = rA(ctx->opcode);
4507 76a66253 j_mayer
4508 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
4509 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
4510 9d53c753 j_mayer
    gen_addr_imm_index(ctx, 0);
4511 76a66253 j_mayer
    op_POWER2_lfq();
4512 76a66253 j_mayer
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4513 76a66253 j_mayer
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4514 76a66253 j_mayer
    if (ra != 0)
4515 76a66253 j_mayer
        gen_op_store_T0_gpr(ra);
4516 76a66253 j_mayer
}
4517 76a66253 j_mayer
4518 76a66253 j_mayer
/* lfqux */
4519 76a66253 j_mayer
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
4520 76a66253 j_mayer
{
4521 76a66253 j_mayer
    int ra = rA(ctx->opcode);
4522 76a66253 j_mayer
4523 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
4524 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
4525 76a66253 j_mayer
    gen_addr_reg_index(ctx);
4526 76a66253 j_mayer
    op_POWER2_lfq();
4527 76a66253 j_mayer
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4528 76a66253 j_mayer
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4529 76a66253 j_mayer
    if (ra != 0)
4530 76a66253 j_mayer
        gen_op_store_T0_gpr(ra);
4531 76a66253 j_mayer
}
4532 76a66253 j_mayer
4533 76a66253 j_mayer
/* lfqx */
4534 76a66253 j_mayer
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
4535 76a66253 j_mayer
{
4536 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
4537 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
4538 76a66253 j_mayer
    gen_addr_reg_index(ctx);
4539 76a66253 j_mayer
    op_POWER2_lfq();
4540 76a66253 j_mayer
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4541 76a66253 j_mayer
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4542 76a66253 j_mayer
}
4543 76a66253 j_mayer
4544 76a66253 j_mayer
/* stfq */
4545 76a66253 j_mayer
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4546 76a66253 j_mayer
{
4547 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
4548 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
4549 9d53c753 j_mayer
    gen_addr_imm_index(ctx, 0);
4550 76a66253 j_mayer
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4551 76a66253 j_mayer
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4552 76a66253 j_mayer
    op_POWER2_stfq();
4553 76a66253 j_mayer
}
4554 76a66253 j_mayer
4555 76a66253 j_mayer
/* stfqu */
4556 76a66253 j_mayer
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4557 76a66253 j_mayer
{
4558 76a66253 j_mayer
    int ra = rA(ctx->opcode);
4559 76a66253 j_mayer
4560 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
4561 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
4562 9d53c753 j_mayer
    gen_addr_imm_index(ctx, 0);
4563 76a66253 j_mayer
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4564 76a66253 j_mayer
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4565 76a66253 j_mayer
    op_POWER2_stfq();
4566 76a66253 j_mayer
    if (ra != 0)
4567 76a66253 j_mayer
        gen_op_store_T0_gpr(ra);
4568 76a66253 j_mayer
}
4569 76a66253 j_mayer
4570 76a66253 j_mayer
/* stfqux */
4571 76a66253 j_mayer
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
4572 76a66253 j_mayer
{
4573 76a66253 j_mayer
    int ra = rA(ctx->opcode);
4574 76a66253 j_mayer
4575 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
4576 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
4577 76a66253 j_mayer
    gen_addr_reg_index(ctx);
4578 76a66253 j_mayer
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4579 76a66253 j_mayer
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4580 76a66253 j_mayer
    op_POWER2_stfq();
4581 76a66253 j_mayer
    if (ra != 0)
4582 76a66253 j_mayer
        gen_op_store_T0_gpr(ra);
4583 76a66253 j_mayer
}
4584 76a66253 j_mayer
4585 76a66253 j_mayer
/* stfqx */
4586 76a66253 j_mayer
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
4587 76a66253 j_mayer
{
4588 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
4589 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
4590 76a66253 j_mayer
    gen_addr_reg_index(ctx);
4591 76a66253 j_mayer
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4592 76a66253 j_mayer
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4593 76a66253 j_mayer
    op_POWER2_stfq();
4594 76a66253 j_mayer
}
4595 76a66253 j_mayer
4596 76a66253 j_mayer
/* BookE specific instructions */
4597 2662a059 j_mayer
/* XXX: not implemented on 440 ? */
4598 05332d70 j_mayer
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI)
4599 76a66253 j_mayer
{
4600 76a66253 j_mayer
    /* XXX: TODO */
4601 e1833e1f j_mayer
    GEN_EXCP_INVAL(ctx);
4602 76a66253 j_mayer
}
4603 76a66253 j_mayer
4604 2662a059 j_mayer
/* XXX: not implemented on 440 ? */
4605 05332d70 j_mayer
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA)
4606 76a66253 j_mayer
{
4607 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4608 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4609 76a66253 j_mayer
#else
4610 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4611 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4612 76a66253 j_mayer
        return;
4613 76a66253 j_mayer
    }
4614 76a66253 j_mayer
    gen_addr_reg_index(ctx);
4615 76a66253 j_mayer
    /* Use the same micro-ops as for tlbie */
4616 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
4617 d9bce9d9 j_mayer
    if (ctx->sf_mode)
4618 d9bce9d9 j_mayer
        gen_op_tlbie_64();
4619 d9bce9d9 j_mayer
    else
4620 d9bce9d9 j_mayer
#endif
4621 d9bce9d9 j_mayer
        gen_op_tlbie();
4622 76a66253 j_mayer
#endif
4623 76a66253 j_mayer
}
4624 76a66253 j_mayer
4625 76a66253 j_mayer
/* All 405 MAC instructions are translated here */
4626 b068d6a7 j_mayer
static always_inline void gen_405_mulladd_insn (DisasContext *ctx,
4627 b068d6a7 j_mayer
                                                int opc2, int opc3,
4628 b068d6a7 j_mayer
                                                int ra, int rb, int rt, int Rc)
4629 76a66253 j_mayer
{
4630 76a66253 j_mayer
    gen_op_load_gpr_T0(ra);
4631 76a66253 j_mayer
    gen_op_load_gpr_T1(rb);
4632 76a66253 j_mayer
    switch (opc3 & 0x0D) {
4633 76a66253 j_mayer
    case 0x05:
4634 76a66253 j_mayer
        /* macchw    - macchw.    - macchwo   - macchwo.   */
4635 76a66253 j_mayer
        /* macchws   - macchws.   - macchwso  - macchwso.  */
4636 76a66253 j_mayer
        /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
4637 76a66253 j_mayer
        /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
4638 76a66253 j_mayer
        /* mulchw - mulchw. */
4639 76a66253 j_mayer
        gen_op_405_mulchw();
4640 76a66253 j_mayer
        break;
4641 76a66253 j_mayer
    case 0x04:
4642 76a66253 j_mayer
        /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
4643 76a66253 j_mayer
        /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
4644 76a66253 j_mayer
        /* mulchwu - mulchwu. */
4645 76a66253 j_mayer
        gen_op_405_mulchwu();
4646 76a66253 j_mayer
        break;
4647 76a66253 j_mayer
    case 0x01:
4648 76a66253 j_mayer
        /* machhw    - machhw.    - machhwo   - machhwo.   */
4649 76a66253 j_mayer
        /* machhws   - machhws.   - machhwso  - machhwso.  */
4650 76a66253 j_mayer
        /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
4651 76a66253 j_mayer
        /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
4652 76a66253 j_mayer
        /* mulhhw - mulhhw. */
4653 76a66253 j_mayer
        gen_op_405_mulhhw();
4654 76a66253 j_mayer
        break;
4655 76a66253 j_mayer
    case 0x00:
4656 76a66253 j_mayer
        /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
4657 76a66253 j_mayer
        /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
4658 76a66253 j_mayer
        /* mulhhwu - mulhhwu. */
4659 76a66253 j_mayer
        gen_op_405_mulhhwu();
4660 76a66253 j_mayer
        break;
4661 76a66253 j_mayer
    case 0x0D:
4662 76a66253 j_mayer
        /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
4663 76a66253 j_mayer
        /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
4664 76a66253 j_mayer
        /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
4665 76a66253 j_mayer
        /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
4666 76a66253 j_mayer
        /* mullhw - mullhw. */
4667 76a66253 j_mayer
        gen_op_405_mullhw();
4668 76a66253 j_mayer
        break;
4669 76a66253 j_mayer
    case 0x0C:
4670 76a66253 j_mayer
        /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
4671 76a66253 j_mayer
        /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
4672 76a66253 j_mayer
        /* mullhwu - mullhwu. */
4673 76a66253 j_mayer
        gen_op_405_mullhwu();
4674 76a66253 j_mayer
        break;
4675 76a66253 j_mayer
    }
4676 76a66253 j_mayer
    if (opc2 & 0x02) {
4677 76a66253 j_mayer
        /* nmultiply-and-accumulate (0x0E) */
4678 76a66253 j_mayer
        gen_op_neg();
4679 76a66253 j_mayer
    }
4680 76a66253 j_mayer
    if (opc2 & 0x04) {
4681 76a66253 j_mayer
        /* (n)multiply-and-accumulate (0x0C - 0x0E) */
4682 76a66253 j_mayer
        gen_op_load_gpr_T2(rt);
4683 76a66253 j_mayer
        gen_op_move_T1_T0();
4684 76a66253 j_mayer
        gen_op_405_add_T0_T2();
4685 76a66253 j_mayer
    }
4686 76a66253 j_mayer
    if (opc3 & 0x10) {
4687 76a66253 j_mayer
        /* Check overflow */
4688 76a66253 j_mayer
        if (opc3 & 0x01)
4689 c3e10c7b j_mayer
            gen_op_check_addo();
4690 76a66253 j_mayer
        else
4691 76a66253 j_mayer
            gen_op_405_check_ovu();
4692 76a66253 j_mayer
    }
4693 76a66253 j_mayer
    if (opc3 & 0x02) {
4694 76a66253 j_mayer
        /* Saturate */
4695 76a66253 j_mayer
        if (opc3 & 0x01)
4696 76a66253 j_mayer
            gen_op_405_check_sat();
4697 76a66253 j_mayer
        else
4698 76a66253 j_mayer
            gen_op_405_check_satu();
4699 76a66253 j_mayer
    }
4700 76a66253 j_mayer
    gen_op_store_T0_gpr(rt);
4701 76a66253 j_mayer
    if (unlikely(Rc) != 0) {
4702 76a66253 j_mayer
        /* Update Rc0 */
4703 76a66253 j_mayer
        gen_set_Rc0(ctx);
4704 76a66253 j_mayer
    }
4705 76a66253 j_mayer
}
4706 76a66253 j_mayer
4707 a750fc0b j_mayer
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
4708 a750fc0b j_mayer
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
4709 76a66253 j_mayer
{                                                                             \
4710 76a66253 j_mayer
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
4711 76a66253 j_mayer
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
4712 76a66253 j_mayer
}
4713 76a66253 j_mayer
4714 76a66253 j_mayer
/* macchw    - macchw.    */
4715 a750fc0b j_mayer
GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
4716 76a66253 j_mayer
/* macchwo   - macchwo.   */
4717 a750fc0b j_mayer
GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
4718 76a66253 j_mayer
/* macchws   - macchws.   */
4719 a750fc0b j_mayer
GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
4720 76a66253 j_mayer
/* macchwso  - macchwso.  */
4721 a750fc0b j_mayer
GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
4722 76a66253 j_mayer
/* macchwsu  - macchwsu.  */
4723 a750fc0b j_mayer
GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
4724 76a66253 j_mayer
/* macchwsuo - macchwsuo. */
4725 a750fc0b j_mayer
GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
4726 76a66253 j_mayer
/* macchwu   - macchwu.   */
4727 a750fc0b j_mayer
GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
4728 76a66253 j_mayer
/* macchwuo  - macchwuo.  */
4729 a750fc0b j_mayer
GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
4730 76a66253 j_mayer
/* machhw    - machhw.    */
4731 a750fc0b j_mayer
GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
4732 76a66253 j_mayer
/* machhwo   - machhwo.   */
4733 a750fc0b j_mayer
GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
4734 76a66253 j_mayer
/* machhws   - machhws.   */
4735 a750fc0b j_mayer
GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
4736 76a66253 j_mayer
/* machhwso  - machhwso.  */
4737 a750fc0b j_mayer
GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
4738 76a66253 j_mayer
/* machhwsu  - machhwsu.  */
4739 a750fc0b j_mayer
GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
4740 76a66253 j_mayer
/* machhwsuo - machhwsuo. */
4741 a750fc0b j_mayer
GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
4742 76a66253 j_mayer
/* machhwu   - machhwu.   */
4743 a750fc0b j_mayer
GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
4744 76a66253 j_mayer
/* machhwuo  - machhwuo.  */
4745 a750fc0b j_mayer
GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
4746 76a66253 j_mayer
/* maclhw    - maclhw.    */
4747 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
4748 76a66253 j_mayer
/* maclhwo   - maclhwo.   */
4749 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
4750 76a66253 j_mayer
/* maclhws   - maclhws.   */
4751 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
4752 76a66253 j_mayer
/* maclhwso  - maclhwso.  */
4753 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
4754 76a66253 j_mayer
/* maclhwu   - maclhwu.   */
4755 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
4756 76a66253 j_mayer
/* maclhwuo  - maclhwuo.  */
4757 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
4758 76a66253 j_mayer
/* maclhwsu  - maclhwsu.  */
4759 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
4760 76a66253 j_mayer
/* maclhwsuo - maclhwsuo. */
4761 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
4762 76a66253 j_mayer
/* nmacchw   - nmacchw.   */
4763 a750fc0b j_mayer
GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
4764 76a66253 j_mayer
/* nmacchwo  - nmacchwo.  */
4765 a750fc0b j_mayer
GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
4766 76a66253 j_mayer
/* nmacchws  - nmacchws.  */
4767 a750fc0b j_mayer
GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
4768 76a66253 j_mayer
/* nmacchwso - nmacchwso. */
4769 a750fc0b j_mayer
GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
4770 76a66253 j_mayer
/* nmachhw   - nmachhw.   */
4771 a750fc0b j_mayer
GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
4772 76a66253 j_mayer
/* nmachhwo  - nmachhwo.  */
4773 a750fc0b j_mayer
GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
4774 76a66253 j_mayer
/* nmachhws  - nmachhws.  */
4775 a750fc0b j_mayer
GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
4776 76a66253 j_mayer
/* nmachhwso - nmachhwso. */
4777 a750fc0b j_mayer
GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
4778 76a66253 j_mayer
/* nmaclhw   - nmaclhw.   */
4779 a750fc0b j_mayer
GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
4780 76a66253 j_mayer
/* nmaclhwo  - nmaclhwo.  */
4781 a750fc0b j_mayer
GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
4782 76a66253 j_mayer
/* nmaclhws  - nmaclhws.  */
4783 a750fc0b j_mayer
GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
4784 76a66253 j_mayer
/* nmaclhwso - nmaclhwso. */
4785 a750fc0b j_mayer
GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
4786 76a66253 j_mayer
4787 76a66253 j_mayer
/* mulchw  - mulchw.  */
4788 a750fc0b j_mayer
GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
4789 76a66253 j_mayer
/* mulchwu - mulchwu. */
4790 a750fc0b j_mayer
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
4791 76a66253 j_mayer
/* mulhhw  - mulhhw.  */
4792 a750fc0b j_mayer
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
4793 76a66253 j_mayer
/* mulhhwu - mulhhwu. */
4794 a750fc0b j_mayer
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
4795 76a66253 j_mayer
/* mullhw  - mullhw.  */
4796 a750fc0b j_mayer
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
4797 76a66253 j_mayer
/* mullhwu - mullhwu. */
4798 a750fc0b j_mayer
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
4799 76a66253 j_mayer
4800 76a66253 j_mayer
/* mfdcr */
4801 05332d70 j_mayer
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR)
4802 76a66253 j_mayer
{
4803 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4804 e1833e1f j_mayer
    GEN_EXCP_PRIVREG(ctx);
4805 76a66253 j_mayer
#else
4806 76a66253 j_mayer
    uint32_t dcrn = SPR(ctx->opcode);
4807 76a66253 j_mayer
4808 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4809 e1833e1f j_mayer
        GEN_EXCP_PRIVREG(ctx);
4810 76a66253 j_mayer
        return;
4811 76a66253 j_mayer
    }
4812 a42bd6cc j_mayer
    gen_op_set_T0(dcrn);
4813 a42bd6cc j_mayer
    gen_op_load_dcr();
4814 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4815 76a66253 j_mayer
#endif
4816 76a66253 j_mayer
}
4817 76a66253 j_mayer
4818 76a66253 j_mayer
/* mtdcr */
4819 05332d70 j_mayer
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR)
4820 76a66253 j_mayer
{
4821 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4822 e1833e1f j_mayer
    GEN_EXCP_PRIVREG(ctx);
4823 76a66253 j_mayer
#else
4824 76a66253 j_mayer
    uint32_t dcrn = SPR(ctx->opcode);
4825 76a66253 j_mayer
4826 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4827 e1833e1f j_mayer
        GEN_EXCP_PRIVREG(ctx);
4828 76a66253 j_mayer
        return;
4829 76a66253 j_mayer
    }
4830 a42bd6cc j_mayer
    gen_op_set_T0(dcrn);
4831 a42bd6cc j_mayer
    gen_op_load_gpr_T1(rS(ctx->opcode));
4832 a42bd6cc j_mayer
    gen_op_store_dcr();
4833 a42bd6cc j_mayer
#endif
4834 a42bd6cc j_mayer
}
4835 a42bd6cc j_mayer
4836 a42bd6cc j_mayer
/* mfdcrx */
4837 2662a059 j_mayer
/* XXX: not implemented on 440 ? */
4838 05332d70 j_mayer
GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX)
4839 a42bd6cc j_mayer
{
4840 a42bd6cc j_mayer
#if defined(CONFIG_USER_ONLY)
4841 e1833e1f j_mayer
    GEN_EXCP_PRIVREG(ctx);
4842 a42bd6cc j_mayer
#else
4843 a42bd6cc j_mayer
    if (unlikely(!ctx->supervisor)) {
4844 e1833e1f j_mayer
        GEN_EXCP_PRIVREG(ctx);
4845 a42bd6cc j_mayer
        return;
4846 a42bd6cc j_mayer
    }
4847 a42bd6cc j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4848 a42bd6cc j_mayer
    gen_op_load_dcr();
4849 a42bd6cc j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4850 a750fc0b j_mayer
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4851 a42bd6cc j_mayer
#endif
4852 a42bd6cc j_mayer
}
4853 a42bd6cc j_mayer
4854 a42bd6cc j_mayer
/* mtdcrx */
4855 2662a059 j_mayer
/* XXX: not implemented on 440 ? */
4856 05332d70 j_mayer
GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX)
4857 a42bd6cc j_mayer
{
4858 a42bd6cc j_mayer
#if defined(CONFIG_USER_ONLY)
4859 e1833e1f j_mayer
    GEN_EXCP_PRIVREG(ctx);
4860 a42bd6cc j_mayer
#else
4861 a42bd6cc j_mayer
    if (unlikely(!ctx->supervisor)) {
4862 e1833e1f j_mayer
        GEN_EXCP_PRIVREG(ctx);
4863 a42bd6cc j_mayer
        return;
4864 a42bd6cc j_mayer
    }
4865 a42bd6cc j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4866 a42bd6cc j_mayer
    gen_op_load_gpr_T1(rS(ctx->opcode));
4867 a42bd6cc j_mayer
    gen_op_store_dcr();
4868 a750fc0b j_mayer
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4869 76a66253 j_mayer
#endif
4870 76a66253 j_mayer
}
4871 76a66253 j_mayer
4872 a750fc0b j_mayer
/* mfdcrux (PPC 460) : user-mode access to DCR */
4873 a750fc0b j_mayer
GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX)
4874 a750fc0b j_mayer
{
4875 a750fc0b j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4876 a750fc0b j_mayer
    gen_op_load_dcr();
4877 a750fc0b j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4878 a750fc0b j_mayer
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4879 a750fc0b j_mayer
}
4880 a750fc0b j_mayer
4881 a750fc0b j_mayer
/* mtdcrux (PPC 460) : user-mode access to DCR */
4882 a750fc0b j_mayer
GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
4883 a750fc0b j_mayer
{
4884 a750fc0b j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4885 a750fc0b j_mayer
    gen_op_load_gpr_T1(rS(ctx->opcode));
4886 a750fc0b j_mayer
    gen_op_store_dcr();
4887 a750fc0b j_mayer
    /* Note: Rc update flag set leads to undefined state of Rc0 */
4888 a750fc0b j_mayer
}
4889 a750fc0b j_mayer
4890 76a66253 j_mayer
/* dccci */
4891 76a66253 j_mayer
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
4892 76a66253 j_mayer
{
4893 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4894 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4895 76a66253 j_mayer
#else
4896 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4897 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4898 76a66253 j_mayer
        return;
4899 76a66253 j_mayer
    }
4900 76a66253 j_mayer
    /* interpreted as no-op */
4901 76a66253 j_mayer
#endif
4902 76a66253 j_mayer
}
4903 76a66253 j_mayer
4904 76a66253 j_mayer
/* dcread */
4905 76a66253 j_mayer
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
4906 76a66253 j_mayer
{
4907 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4908 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4909 76a66253 j_mayer
#else
4910 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4911 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4912 76a66253 j_mayer
        return;
4913 76a66253 j_mayer
    }
4914 76a66253 j_mayer
    gen_addr_reg_index(ctx);
4915 76a66253 j_mayer
    op_ldst(lwz);
4916 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4917 76a66253 j_mayer
#endif
4918 76a66253 j_mayer
}
4919 76a66253 j_mayer
4920 76a66253 j_mayer
/* icbt */
4921 c7697e1f j_mayer
GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
4922 76a66253 j_mayer
{
4923 76a66253 j_mayer
    /* interpreted as no-op */
4924 76a66253 j_mayer
    /* XXX: specification say this is treated as a load by the MMU
4925 76a66253 j_mayer
     *      but does not generate any exception
4926 76a66253 j_mayer
     */
4927 76a66253 j_mayer
}
4928 76a66253 j_mayer
4929 76a66253 j_mayer
/* iccci */
4930 76a66253 j_mayer
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
4931 76a66253 j_mayer
{
4932 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4933 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4934 76a66253 j_mayer
#else
4935 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4936 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4937 76a66253 j_mayer
        return;
4938 76a66253 j_mayer
    }
4939 76a66253 j_mayer
    /* interpreted as no-op */
4940 76a66253 j_mayer
#endif
4941 76a66253 j_mayer
}
4942 76a66253 j_mayer
4943 76a66253 j_mayer
/* icread */
4944 76a66253 j_mayer
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
4945 76a66253 j_mayer
{
4946 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4947 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4948 76a66253 j_mayer
#else
4949 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4950 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4951 76a66253 j_mayer
        return;
4952 76a66253 j_mayer
    }
4953 76a66253 j_mayer
    /* interpreted as no-op */
4954 76a66253 j_mayer
#endif
4955 76a66253 j_mayer
}
4956 76a66253 j_mayer
4957 76a66253 j_mayer
/* rfci (supervisor only) */
4958 c7697e1f j_mayer
GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP)
4959 a42bd6cc j_mayer
{
4960 a42bd6cc j_mayer
#if defined(CONFIG_USER_ONLY)
4961 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4962 a42bd6cc j_mayer
#else
4963 a42bd6cc j_mayer
    if (unlikely(!ctx->supervisor)) {
4964 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4965 a42bd6cc j_mayer
        return;
4966 a42bd6cc j_mayer
    }
4967 a42bd6cc j_mayer
    /* Restore CPU state */
4968 a42bd6cc j_mayer
    gen_op_40x_rfci();
4969 e1833e1f j_mayer
    GEN_SYNC(ctx);
4970 a42bd6cc j_mayer
#endif
4971 a42bd6cc j_mayer
}
4972 a42bd6cc j_mayer
4973 a42bd6cc j_mayer
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
4974 a42bd6cc j_mayer
{
4975 a42bd6cc j_mayer
#if defined(CONFIG_USER_ONLY)
4976 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4977 a42bd6cc j_mayer
#else
4978 a42bd6cc j_mayer
    if (unlikely(!ctx->supervisor)) {
4979 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4980 a42bd6cc j_mayer
        return;
4981 a42bd6cc j_mayer
    }
4982 a42bd6cc j_mayer
    /* Restore CPU state */
4983 a42bd6cc j_mayer
    gen_op_rfci();
4984 e1833e1f j_mayer
    GEN_SYNC(ctx);
4985 a42bd6cc j_mayer
#endif
4986 a42bd6cc j_mayer
}
4987 a42bd6cc j_mayer
4988 a42bd6cc j_mayer
/* BookE specific */
4989 2662a059 j_mayer
/* XXX: not implemented on 440 ? */
4990 05332d70 j_mayer
GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI)
4991 76a66253 j_mayer
{
4992 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4993 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4994 76a66253 j_mayer
#else
4995 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4996 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4997 76a66253 j_mayer
        return;
4998 76a66253 j_mayer
    }
4999 76a66253 j_mayer
    /* Restore CPU state */
5000 a42bd6cc j_mayer
    gen_op_rfdi();
5001 e1833e1f j_mayer
    GEN_SYNC(ctx);
5002 76a66253 j_mayer
#endif
5003 76a66253 j_mayer
}
5004 76a66253 j_mayer
5005 2662a059 j_mayer
/* XXX: not implemented on 440 ? */
5006 a750fc0b j_mayer
GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
5007 a42bd6cc j_mayer
{
5008 a42bd6cc j_mayer
#if defined(CONFIG_USER_ONLY)
5009 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5010 a42bd6cc j_mayer
#else
5011 a42bd6cc j_mayer
    if (unlikely(!ctx->supervisor)) {
5012 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5013 a42bd6cc j_mayer
        return;
5014 a42bd6cc j_mayer
    }
5015 a42bd6cc j_mayer
    /* Restore CPU state */
5016 a42bd6cc j_mayer
    gen_op_rfmci();
5017 e1833e1f j_mayer
    GEN_SYNC(ctx);
5018 a42bd6cc j_mayer
#endif
5019 a42bd6cc j_mayer
}
5020 5eb7995e j_mayer
5021 d9bce9d9 j_mayer
/* TLB management - PowerPC 405 implementation */
5022 76a66253 j_mayer
/* tlbre */
5023 c7697e1f j_mayer
GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
5024 76a66253 j_mayer
{
5025 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5026 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5027 76a66253 j_mayer
#else
5028 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
5029 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5030 76a66253 j_mayer
        return;
5031 76a66253 j_mayer
    }
5032 76a66253 j_mayer
    switch (rB(ctx->opcode)) {
5033 76a66253 j_mayer
    case 0:
5034 9a64fbe4 bellard
        gen_op_load_gpr_T0(rA(ctx->opcode));
5035 76a66253 j_mayer
        gen_op_4xx_tlbre_hi();
5036 76a66253 j_mayer
        gen_op_store_T0_gpr(rD(ctx->opcode));
5037 76a66253 j_mayer
        break;
5038 76a66253 j_mayer
    case 1:
5039 76a66253 j_mayer
        gen_op_load_gpr_T0(rA(ctx->opcode));
5040 76a66253 j_mayer
        gen_op_4xx_tlbre_lo();
5041 76a66253 j_mayer
        gen_op_store_T0_gpr(rD(ctx->opcode));
5042 76a66253 j_mayer
        break;
5043 76a66253 j_mayer
    default:
5044 e1833e1f j_mayer
        GEN_EXCP_INVAL(ctx);
5045 76a66253 j_mayer
        break;
5046 9a64fbe4 bellard
    }
5047 76a66253 j_mayer
#endif
5048 76a66253 j_mayer
}
5049 76a66253 j_mayer
5050 d9bce9d9 j_mayer
/* tlbsx - tlbsx. */
5051 c7697e1f j_mayer
GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
5052 76a66253 j_mayer
{
5053 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5054 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5055 76a66253 j_mayer
#else
5056 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
5057 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5058 76a66253 j_mayer
        return;
5059 76a66253 j_mayer
    }
5060 76a66253 j_mayer
    gen_addr_reg_index(ctx);
5061 daf4f96e j_mayer
    gen_op_4xx_tlbsx();
5062 76a66253 j_mayer
    if (Rc(ctx->opcode))
5063 daf4f96e j_mayer
        gen_op_4xx_tlbsx_check();
5064 9a64fbe4 bellard
    gen_op_store_T0_gpr(rD(ctx->opcode));
5065 76a66253 j_mayer
#endif
5066 79aceca5 bellard
}
5067 79aceca5 bellard
5068 76a66253 j_mayer
/* tlbwe */
5069 c7697e1f j_mayer
GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
5070 79aceca5 bellard
{
5071 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5072 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5073 76a66253 j_mayer
#else
5074 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
5075 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5076 76a66253 j_mayer
        return;
5077 76a66253 j_mayer
    }
5078 76a66253 j_mayer
    switch (rB(ctx->opcode)) {
5079 76a66253 j_mayer
    case 0:
5080 9a64fbe4 bellard
        gen_op_load_gpr_T0(rA(ctx->opcode));
5081 76a66253 j_mayer
        gen_op_load_gpr_T1(rS(ctx->opcode));
5082 76a66253 j_mayer
        gen_op_4xx_tlbwe_hi();
5083 76a66253 j_mayer
        break;
5084 76a66253 j_mayer
    case 1:
5085 76a66253 j_mayer
        gen_op_load_gpr_T0(rA(ctx->opcode));
5086 76a66253 j_mayer
        gen_op_load_gpr_T1(rS(ctx->opcode));
5087 76a66253 j_mayer
        gen_op_4xx_tlbwe_lo();
5088 76a66253 j_mayer
        break;
5089 76a66253 j_mayer
    default:
5090 e1833e1f j_mayer
        GEN_EXCP_INVAL(ctx);
5091 76a66253 j_mayer
        break;
5092 9a64fbe4 bellard
    }
5093 76a66253 j_mayer
#endif
5094 76a66253 j_mayer
}
5095 76a66253 j_mayer
5096 a4bb6c3e j_mayer
/* TLB management - PowerPC 440 implementation */
5097 5eb7995e j_mayer
/* tlbre */
5098 c7697e1f j_mayer
GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
5099 5eb7995e j_mayer
{
5100 5eb7995e j_mayer
#if defined(CONFIG_USER_ONLY)
5101 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5102 5eb7995e j_mayer
#else
5103 5eb7995e j_mayer
    if (unlikely(!ctx->supervisor)) {
5104 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5105 5eb7995e j_mayer
        return;
5106 5eb7995e j_mayer
    }
5107 5eb7995e j_mayer
    switch (rB(ctx->opcode)) {
5108 5eb7995e j_mayer
    case 0:
5109 5eb7995e j_mayer
    case 1:
5110 5eb7995e j_mayer
    case 2:
5111 5eb7995e j_mayer
        gen_op_load_gpr_T0(rA(ctx->opcode));
5112 a4bb6c3e j_mayer
        gen_op_440_tlbre(rB(ctx->opcode));
5113 5eb7995e j_mayer
        gen_op_store_T0_gpr(rD(ctx->opcode));
5114 5eb7995e j_mayer
        break;
5115 5eb7995e j_mayer
    default:
5116 e1833e1f j_mayer
        GEN_EXCP_INVAL(ctx);
5117 5eb7995e j_mayer
        break;
5118 5eb7995e j_mayer
    }
5119 5eb7995e j_mayer
#endif
5120 5eb7995e j_mayer
}
5121 5eb7995e j_mayer
5122 5eb7995e j_mayer
/* tlbsx - tlbsx. */
5123 c7697e1f j_mayer
GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
5124 5eb7995e j_mayer
{
5125 5eb7995e j_mayer
#if defined(CONFIG_USER_ONLY)
5126 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5127 5eb7995e j_mayer
#else
5128 5eb7995e j_mayer
    if (unlikely(!ctx->supervisor)) {
5129 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5130 5eb7995e j_mayer
        return;
5131 5eb7995e j_mayer
    }
5132 5eb7995e j_mayer
    gen_addr_reg_index(ctx);
5133 daf4f96e j_mayer
    gen_op_440_tlbsx();
5134 5eb7995e j_mayer
    if (Rc(ctx->opcode))
5135 daf4f96e j_mayer
        gen_op_4xx_tlbsx_check();
5136 5eb7995e j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
5137 5eb7995e j_mayer
#endif
5138 5eb7995e j_mayer
}
5139 5eb7995e j_mayer
5140 5eb7995e j_mayer
/* tlbwe */
5141 c7697e1f j_mayer
GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
5142 5eb7995e j_mayer
{
5143 5eb7995e j_mayer
#if defined(CONFIG_USER_ONLY)
5144 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5145 5eb7995e j_mayer
#else
5146 5eb7995e j_mayer
    if (unlikely(!ctx->supervisor)) {
5147 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5148 5eb7995e j_mayer
        return;
5149 5eb7995e j_mayer
    }
5150 5eb7995e j_mayer
    switch (rB(ctx->opcode)) {
5151 5eb7995e j_mayer
    case 0:
5152 5eb7995e j_mayer
    case 1:
5153 5eb7995e j_mayer
    case 2:
5154 5eb7995e j_mayer
        gen_op_load_gpr_T0(rA(ctx->opcode));
5155 5eb7995e j_mayer
        gen_op_load_gpr_T1(rS(ctx->opcode));
5156 a4bb6c3e j_mayer
        gen_op_440_tlbwe(rB(ctx->opcode));
5157 5eb7995e j_mayer
        break;
5158 5eb7995e j_mayer
    default:
5159 e1833e1f j_mayer
        GEN_EXCP_INVAL(ctx);
5160 5eb7995e j_mayer
        break;
5161 5eb7995e j_mayer
    }
5162 5eb7995e j_mayer
#endif
5163 5eb7995e j_mayer
}
5164 5eb7995e j_mayer
5165 76a66253 j_mayer
/* wrtee */
5166 05332d70 j_mayer
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE)
5167 76a66253 j_mayer
{
5168 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5169 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5170 76a66253 j_mayer
#else
5171 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
5172 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5173 76a66253 j_mayer
        return;
5174 76a66253 j_mayer
    }
5175 76a66253 j_mayer
    gen_op_load_gpr_T0(rD(ctx->opcode));
5176 a42bd6cc j_mayer
    gen_op_wrte();
5177 dee96f6c j_mayer
    /* Stop translation to have a chance to raise an exception
5178 dee96f6c j_mayer
     * if we just set msr_ee to 1
5179 dee96f6c j_mayer
     */
5180 e1833e1f j_mayer
    GEN_STOP(ctx);
5181 76a66253 j_mayer
#endif
5182 76a66253 j_mayer
}
5183 76a66253 j_mayer
5184 76a66253 j_mayer
/* wrteei */
5185 05332d70 j_mayer
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_WRTEE)
5186 76a66253 j_mayer
{
5187 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5188 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5189 76a66253 j_mayer
#else
5190 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
5191 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5192 76a66253 j_mayer
        return;
5193 76a66253 j_mayer
    }
5194 76a66253 j_mayer
    gen_op_set_T0(ctx->opcode & 0x00010000);
5195 a42bd6cc j_mayer
    gen_op_wrte();
5196 dee96f6c j_mayer
    /* Stop translation to have a chance to raise an exception
5197 dee96f6c j_mayer
     * if we just set msr_ee to 1
5198 dee96f6c j_mayer
     */
5199 e1833e1f j_mayer
    GEN_STOP(ctx);
5200 76a66253 j_mayer
#endif
5201 76a66253 j_mayer
}
5202 76a66253 j_mayer
5203 08e46e54 j_mayer
/* PowerPC 440 specific instructions */
5204 76a66253 j_mayer
/* dlmzb */
5205 76a66253 j_mayer
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
5206 76a66253 j_mayer
{
5207 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
5208 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
5209 76a66253 j_mayer
    gen_op_440_dlmzb();
5210 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
5211 76a66253 j_mayer
    gen_op_store_xer_bc();
5212 76a66253 j_mayer
    if (Rc(ctx->opcode)) {
5213 76a66253 j_mayer
        gen_op_440_dlmzb_update_Rc();
5214 76a66253 j_mayer
        gen_op_store_T0_crf(0);
5215 76a66253 j_mayer
    }
5216 76a66253 j_mayer
}
5217 76a66253 j_mayer
5218 76a66253 j_mayer
/* mbar replaces eieio on 440 */
5219 76a66253 j_mayer
GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
5220 76a66253 j_mayer
{
5221 76a66253 j_mayer
    /* interpreted as no-op */
5222 76a66253 j_mayer
}
5223 76a66253 j_mayer
5224 76a66253 j_mayer
/* msync replaces sync on 440 */
5225 0db1b20e j_mayer
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE)
5226 76a66253 j_mayer
{
5227 76a66253 j_mayer
    /* interpreted as no-op */
5228 76a66253 j_mayer
}
5229 76a66253 j_mayer
5230 76a66253 j_mayer
/* icbt */
5231 c7697e1f j_mayer
GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
5232 76a66253 j_mayer
{
5233 76a66253 j_mayer
    /* interpreted as no-op */
5234 76a66253 j_mayer
    /* XXX: specification say this is treated as a load by the MMU
5235 76a66253 j_mayer
     *      but does not generate any exception
5236 76a66253 j_mayer
     */
5237 79aceca5 bellard
}
5238 79aceca5 bellard
5239 a9d9eb8f j_mayer
/***                      Altivec vector extension                         ***/
5240 a9d9eb8f j_mayer
/* Altivec registers moves */
5241 a9d9eb8f j_mayer
GEN32(gen_op_load_avr_A0, gen_op_load_avr_A0_avr);
5242 a9d9eb8f j_mayer
GEN32(gen_op_load_avr_A1, gen_op_load_avr_A1_avr);
5243 a9d9eb8f j_mayer
GEN32(gen_op_load_avr_A2, gen_op_load_avr_A2_avr);
5244 a9d9eb8f j_mayer
5245 a9d9eb8f j_mayer
GEN32(gen_op_store_A0_avr, gen_op_store_A0_avr_avr);
5246 a9d9eb8f j_mayer
GEN32(gen_op_store_A1_avr, gen_op_store_A1_avr_avr);
5247 a9d9eb8f j_mayer
#if 0 // unused
5248 a9d9eb8f j_mayer
GEN32(gen_op_store_A2_avr, gen_op_store_A2_avr_avr);
5249 a9d9eb8f j_mayer
#endif
5250 a9d9eb8f j_mayer
5251 a9d9eb8f j_mayer
#define op_vr_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5252 a9d9eb8f j_mayer
#define OP_VR_LD_TABLE(name)                                                  \
5253 7863667f j_mayer
static GenOpFunc *gen_op_vr_l##name[NB_MEM_FUNCS] = {                         \
5254 7863667f j_mayer
    GEN_MEM_FUNCS(vr_l##name),                                                \
5255 a9d9eb8f j_mayer
};
5256 a9d9eb8f j_mayer
#define OP_VR_ST_TABLE(name)                                                  \
5257 7863667f j_mayer
static GenOpFunc *gen_op_vr_st##name[NB_MEM_FUNCS] = {                        \
5258 7863667f j_mayer
    GEN_MEM_FUNCS(vr_st##name),                                               \
5259 a9d9eb8f j_mayer
};
5260 a9d9eb8f j_mayer
5261 a9d9eb8f j_mayer
#define GEN_VR_LDX(name, opc2, opc3)                                          \
5262 a9d9eb8f j_mayer
GEN_HANDLER(l##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)               \
5263 a9d9eb8f j_mayer
{                                                                             \
5264 a9d9eb8f j_mayer
    if (unlikely(!ctx->altivec_enabled)) {                                    \
5265 a9d9eb8f j_mayer
        GEN_EXCP_NO_VR(ctx);                                                  \
5266 a9d9eb8f j_mayer
        return;                                                               \
5267 a9d9eb8f j_mayer
    }                                                                         \
5268 a9d9eb8f j_mayer
    gen_addr_reg_index(ctx);                                                  \
5269 a9d9eb8f j_mayer
    op_vr_ldst(vr_l##name);                                                   \
5270 a9d9eb8f j_mayer
    gen_op_store_A0_avr(rD(ctx->opcode));                                     \
5271 a9d9eb8f j_mayer
}
5272 a9d9eb8f j_mayer
5273 a9d9eb8f j_mayer
#define GEN_VR_STX(name, opc2, opc3)                                          \
5274 a9d9eb8f j_mayer
GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)              \
5275 a9d9eb8f j_mayer
{                                                                             \
5276 a9d9eb8f j_mayer
    if (unlikely(!ctx->altivec_enabled)) {                                    \
5277 a9d9eb8f j_mayer
        GEN_EXCP_NO_VR(ctx);                                                  \
5278 a9d9eb8f j_mayer
        return;                                                               \
5279 a9d9eb8f j_mayer
    }                                                                         \
5280 a9d9eb8f j_mayer
    gen_addr_reg_index(ctx);                                                  \
5281 a9d9eb8f j_mayer
    gen_op_load_avr_A0(rS(ctx->opcode));                                      \
5282 a9d9eb8f j_mayer
    op_vr_ldst(vr_st##name);                                                  \
5283 a9d9eb8f j_mayer
}
5284 a9d9eb8f j_mayer
5285 a9d9eb8f j_mayer
OP_VR_LD_TABLE(vx);
5286 a9d9eb8f j_mayer
GEN_VR_LDX(vx, 0x07, 0x03);
5287 a9d9eb8f j_mayer
/* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
5288 a9d9eb8f j_mayer
#define gen_op_vr_lvxl gen_op_vr_lvx
5289 a9d9eb8f j_mayer
GEN_VR_LDX(vxl, 0x07, 0x0B);
5290 a9d9eb8f j_mayer
5291 a9d9eb8f j_mayer
OP_VR_ST_TABLE(vx);
5292 a9d9eb8f j_mayer
GEN_VR_STX(vx, 0x07, 0x07);
5293 a9d9eb8f j_mayer
/* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
5294 a9d9eb8f j_mayer
#define gen_op_vr_stvxl gen_op_vr_stvx
5295 a9d9eb8f j_mayer
GEN_VR_STX(vxl, 0x07, 0x0F);
5296 a9d9eb8f j_mayer
5297 0487d6a8 j_mayer
/***                           SPE extension                               ***/
5298 0487d6a8 j_mayer
/* Register moves */
5299 65d6c0f3 j_mayer
#if !defined(TARGET_PPC64)
5300 3cd7d1dd j_mayer
5301 0487d6a8 j_mayer
GEN32(gen_op_load_gpr64_T0, gen_op_load_gpr64_T0_gpr);
5302 0487d6a8 j_mayer
GEN32(gen_op_load_gpr64_T1, gen_op_load_gpr64_T1_gpr);
5303 0487d6a8 j_mayer
#if 0 // unused
5304 0487d6a8 j_mayer
GEN32(gen_op_load_gpr64_T2, gen_op_load_gpr64_T2_gpr);
5305 0487d6a8 j_mayer
#endif
5306 0487d6a8 j_mayer
5307 0487d6a8 j_mayer
GEN32(gen_op_store_T0_gpr64, gen_op_store_T0_gpr64_gpr);
5308 0487d6a8 j_mayer
GEN32(gen_op_store_T1_gpr64, gen_op_store_T1_gpr64_gpr);
5309 0487d6a8 j_mayer
#if 0 // unused
5310 0487d6a8 j_mayer
GEN32(gen_op_store_T2_gpr64, gen_op_store_T2_gpr64_gpr);
5311 0487d6a8 j_mayer
#endif
5312 0487d6a8 j_mayer
5313 65d6c0f3 j_mayer
#else /* !defined(TARGET_PPC64) */
5314 3cd7d1dd j_mayer
5315 3cd7d1dd j_mayer
/* No specific load/store functions: GPRs are already 64 bits */
5316 3cd7d1dd j_mayer
#define gen_op_load_gpr64_T0 gen_op_load_gpr_T0
5317 3cd7d1dd j_mayer
#define gen_op_load_gpr64_T1 gen_op_load_gpr_T1
5318 3cd7d1dd j_mayer
#if 0 // unused
5319 3cd7d1dd j_mayer
#define gen_op_load_gpr64_T2 gen_op_load_gpr_T2
5320 3cd7d1dd j_mayer
#endif
5321 3cd7d1dd j_mayer
5322 3cd7d1dd j_mayer
#define gen_op_store_T0_gpr64 gen_op_store_T0_gpr
5323 3cd7d1dd j_mayer
#define gen_op_store_T1_gpr64 gen_op_store_T1_gpr
5324 3cd7d1dd j_mayer
#if 0 // unused
5325 3cd7d1dd j_mayer
#define gen_op_store_T2_gpr64 gen_op_store_T2_gpr
5326 3cd7d1dd j_mayer
#endif
5327 3cd7d1dd j_mayer
5328 65d6c0f3 j_mayer
#endif /* !defined(TARGET_PPC64) */
5329 3cd7d1dd j_mayer
5330 0487d6a8 j_mayer
#define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
5331 0487d6a8 j_mayer
GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
5332 0487d6a8 j_mayer
{                                                                             \
5333 0487d6a8 j_mayer
    if (Rc(ctx->opcode))                                                      \
5334 0487d6a8 j_mayer
        gen_##name1(ctx);                                                     \
5335 0487d6a8 j_mayer
    else                                                                      \
5336 0487d6a8 j_mayer
        gen_##name0(ctx);                                                     \
5337 0487d6a8 j_mayer
}
5338 0487d6a8 j_mayer
5339 0487d6a8 j_mayer
/* Handler for undefined SPE opcodes */
5340 b068d6a7 j_mayer
static always_inline void gen_speundef (DisasContext *ctx)
5341 0487d6a8 j_mayer
{
5342 e1833e1f j_mayer
    GEN_EXCP_INVAL(ctx);
5343 0487d6a8 j_mayer
}
5344 0487d6a8 j_mayer
5345 0487d6a8 j_mayer
/* SPE load and stores */
5346 b068d6a7 j_mayer
static always_inline void gen_addr_spe_imm_index (DisasContext *ctx, int sh)
5347 0487d6a8 j_mayer
{
5348 0487d6a8 j_mayer
    target_long simm = rB(ctx->opcode);
5349 0487d6a8 j_mayer
5350 0487d6a8 j_mayer
    if (rA(ctx->opcode) == 0) {
5351 0487d6a8 j_mayer
        gen_set_T0(simm << sh);
5352 0487d6a8 j_mayer
    } else {
5353 0487d6a8 j_mayer
        gen_op_load_gpr_T0(rA(ctx->opcode));
5354 0487d6a8 j_mayer
        if (likely(simm != 0))
5355 0487d6a8 j_mayer
            gen_op_addi(simm << sh);
5356 0487d6a8 j_mayer
    }
5357 0487d6a8 j_mayer
}
5358 0487d6a8 j_mayer
5359 0487d6a8 j_mayer
#define op_spe_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5360 0487d6a8 j_mayer
#define OP_SPE_LD_TABLE(name)                                                 \
5361 7863667f j_mayer
static GenOpFunc *gen_op_spe_l##name[NB_MEM_FUNCS] = {                        \
5362 7863667f j_mayer
    GEN_MEM_FUNCS(spe_l##name),                                               \
5363 0487d6a8 j_mayer
};
5364 0487d6a8 j_mayer
#define OP_SPE_ST_TABLE(name)                                                 \
5365 7863667f j_mayer
static GenOpFunc *gen_op_spe_st##name[NB_MEM_FUNCS] = {                       \
5366 7863667f j_mayer
    GEN_MEM_FUNCS(spe_st##name),                                              \
5367 2857068e j_mayer
};
5368 0487d6a8 j_mayer
5369 0487d6a8 j_mayer
#define GEN_SPE_LD(name, sh)                                                  \
5370 b068d6a7 j_mayer
static always_inline void gen_evl##name (DisasContext *ctx)                   \
5371 0487d6a8 j_mayer
{                                                                             \
5372 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
5373 e1833e1f j_mayer
        GEN_EXCP_NO_AP(ctx);                                                  \
5374 0487d6a8 j_mayer
        return;                                                               \
5375 0487d6a8 j_mayer
    }                                                                         \
5376 0487d6a8 j_mayer
    gen_addr_spe_imm_index(ctx, sh);                                          \
5377 0487d6a8 j_mayer
    op_spe_ldst(spe_l##name);                                                 \
5378 0487d6a8 j_mayer
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5379 0487d6a8 j_mayer
}
5380 0487d6a8 j_mayer
5381 0487d6a8 j_mayer
#define GEN_SPE_LDX(name)                                                     \
5382 b068d6a7 j_mayer
static always_inline void gen_evl##name##x (DisasContext *ctx)                \
5383 0487d6a8 j_mayer
{                                                                             \
5384 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
5385 e1833e1f j_mayer
        GEN_EXCP_NO_AP(ctx);                                                  \
5386 0487d6a8 j_mayer
        return;                                                               \
5387 0487d6a8 j_mayer
    }                                                                         \
5388 0487d6a8 j_mayer
    gen_addr_reg_index(ctx);                                                  \
5389 0487d6a8 j_mayer
    op_spe_ldst(spe_l##name);                                                 \
5390 0487d6a8 j_mayer
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5391 0487d6a8 j_mayer
}
5392 0487d6a8 j_mayer
5393 0487d6a8 j_mayer
#define GEN_SPEOP_LD(name, sh)                                                \
5394 0487d6a8 j_mayer
OP_SPE_LD_TABLE(name);                                                        \
5395 0487d6a8 j_mayer
GEN_SPE_LD(name, sh);                                                         \
5396 0487d6a8 j_mayer
GEN_SPE_LDX(name)
5397 0487d6a8 j_mayer
5398 0487d6a8 j_mayer
#define GEN_SPE_ST(name, sh)                                                  \
5399 b068d6a7 j_mayer
static always_inline void gen_evst##name (DisasContext *ctx)                  \
5400 0487d6a8 j_mayer
{                                                                             \
5401 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
5402 e1833e1f j_mayer
        GEN_EXCP_NO_AP(ctx);                                                  \
5403 0487d6a8 j_mayer
        return;                                                               \
5404 0487d6a8 j_mayer
    }                                                                         \
5405 0487d6a8 j_mayer
    gen_addr_spe_imm_index(ctx, sh);                                          \
5406 0487d6a8 j_mayer
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5407 0487d6a8 j_mayer
    op_spe_ldst(spe_st##name);                                                \
5408 0487d6a8 j_mayer
}
5409 0487d6a8 j_mayer
5410 0487d6a8 j_mayer
#define GEN_SPE_STX(name)                                                     \
5411 b068d6a7 j_mayer
static always_inline void gen_evst##name##x (DisasContext *ctx)               \
5412 0487d6a8 j_mayer
{                                                                             \
5413 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
5414 e1833e1f j_mayer
        GEN_EXCP_NO_AP(ctx);                                                  \
5415 0487d6a8 j_mayer
        return;                                                               \
5416 0487d6a8 j_mayer
    }                                                                         \
5417 0487d6a8 j_mayer
    gen_addr_reg_index(ctx);                                                  \
5418 0487d6a8 j_mayer
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5419 0487d6a8 j_mayer
    op_spe_ldst(spe_st##name);                                                \
5420 0487d6a8 j_mayer
}
5421 0487d6a8 j_mayer
5422 0487d6a8 j_mayer
#define GEN_SPEOP_ST(name, sh)                                                \
5423 0487d6a8 j_mayer
OP_SPE_ST_TABLE(name);                                                        \
5424 0487d6a8 j_mayer
GEN_SPE_ST(name, sh);                                                         \
5425 0487d6a8 j_mayer
GEN_SPE_STX(name)
5426 0487d6a8 j_mayer
5427 0487d6a8 j_mayer
#define GEN_SPEOP_LDST(name, sh)                                              \
5428 0487d6a8 j_mayer
GEN_SPEOP_LD(name, sh);                                                       \
5429 0487d6a8 j_mayer
GEN_SPEOP_ST(name, sh)
5430 0487d6a8 j_mayer
5431 0487d6a8 j_mayer
/* SPE arithmetic and logic */
5432 0487d6a8 j_mayer
#define GEN_SPEOP_ARITH2(name)                                                \
5433 b068d6a7 j_mayer
static always_inline void gen_##name (DisasContext *ctx)                      \
5434 0487d6a8 j_mayer
{                                                                             \
5435 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
5436 e1833e1f j_mayer
        GEN_EXCP_NO_AP(ctx);                                                  \
5437 0487d6a8 j_mayer
        return;                                                               \
5438 0487d6a8 j_mayer
    }                                                                         \
5439 0487d6a8 j_mayer
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5440 0487d6a8 j_mayer
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5441 0487d6a8 j_mayer
    gen_op_##name();                                                          \
5442 0487d6a8 j_mayer
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5443 0487d6a8 j_mayer
}
5444 0487d6a8 j_mayer
5445 0487d6a8 j_mayer
#define GEN_SPEOP_ARITH1(name)                                                \
5446 b068d6a7 j_mayer
static always_inline void gen_##name (DisasContext *ctx)                      \
5447 0487d6a8 j_mayer
{                                                                             \
5448 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
5449 e1833e1f j_mayer
        GEN_EXCP_NO_AP(ctx);                                                  \
5450 0487d6a8 j_mayer
        return;                                                               \
5451 0487d6a8 j_mayer
    }                                                                         \
5452 0487d6a8 j_mayer
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5453 0487d6a8 j_mayer
    gen_op_##name();                                                          \
5454 0487d6a8 j_mayer
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5455 0487d6a8 j_mayer
}
5456 0487d6a8 j_mayer
5457 0487d6a8 j_mayer
#define GEN_SPEOP_COMP(name)                                                  \
5458 b068d6a7 j_mayer
static always_inline void gen_##name (DisasContext *ctx)                      \
5459 0487d6a8 j_mayer
{                                                                             \
5460 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
5461 e1833e1f j_mayer
        GEN_EXCP_NO_AP(ctx);                                                  \
5462 0487d6a8 j_mayer
        return;                                                               \
5463 0487d6a8 j_mayer
    }                                                                         \
5464 0487d6a8 j_mayer
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5465 0487d6a8 j_mayer
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5466 0487d6a8 j_mayer
    gen_op_##name();                                                          \
5467 0487d6a8 j_mayer
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
5468 0487d6a8 j_mayer
}
5469 0487d6a8 j_mayer
5470 0487d6a8 j_mayer
/* Logical */
5471 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evand);
5472 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evandc);
5473 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evxor);
5474 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evor);
5475 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evnor);
5476 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(eveqv);
5477 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evorc);
5478 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evnand);
5479 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evsrwu);
5480 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evsrws);
5481 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evslw);
5482 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evrlw);
5483 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evmergehi);
5484 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evmergelo);
5485 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evmergehilo);
5486 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evmergelohi);
5487 0487d6a8 j_mayer
5488 0487d6a8 j_mayer
/* Arithmetic */
5489 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evaddw);
5490 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evsubfw);
5491 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evabs);
5492 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evneg);
5493 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evextsb);
5494 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evextsh);
5495 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evrndw);
5496 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evcntlzw);
5497 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evcntlsw);
5498 b068d6a7 j_mayer
static always_inline void gen_brinc (DisasContext *ctx)
5499 0487d6a8 j_mayer
{
5500 0487d6a8 j_mayer
    /* Note: brinc is usable even if SPE is disabled */
5501 3cd7d1dd j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
5502 3cd7d1dd j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
5503 0487d6a8 j_mayer
    gen_op_brinc();
5504 3cd7d1dd j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
5505 0487d6a8 j_mayer
}
5506 0487d6a8 j_mayer
5507 0487d6a8 j_mayer
#define GEN_SPEOP_ARITH_IMM2(name)                                            \
5508 b068d6a7 j_mayer
static always_inline void gen_##name##i (DisasContext *ctx)                   \
5509 0487d6a8 j_mayer
{                                                                             \
5510 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
5511 e1833e1f j_mayer
        GEN_EXCP_NO_AP(ctx);                                                  \
5512 0487d6a8 j_mayer
        return;                                                               \
5513 0487d6a8 j_mayer
    }                                                                         \
5514 0487d6a8 j_mayer
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5515 0487d6a8 j_mayer
    gen_op_splatwi_T1_64(rA(ctx->opcode));                                    \
5516 0487d6a8 j_mayer
    gen_op_##name();                                                          \
5517 0487d6a8 j_mayer
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5518 0487d6a8 j_mayer
}
5519 0487d6a8 j_mayer
5520 0487d6a8 j_mayer
#define GEN_SPEOP_LOGIC_IMM2(name)                                            \
5521 b068d6a7 j_mayer
static always_inline void gen_##name##i (DisasContext *ctx)                   \
5522 0487d6a8 j_mayer
{                                                                             \
5523 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
5524 e1833e1f j_mayer
        GEN_EXCP_NO_AP(ctx);                                                  \
5525 0487d6a8 j_mayer
        return;                                                               \
5526 0487d6a8 j_mayer
    }                                                                         \
5527 0487d6a8 j_mayer
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5528 0487d6a8 j_mayer
    gen_op_splatwi_T1_64(rB(ctx->opcode));                                    \
5529 0487d6a8 j_mayer
    gen_op_##name();                                                          \
5530 0487d6a8 j_mayer
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5531 0487d6a8 j_mayer
}
5532 0487d6a8 j_mayer
5533 0487d6a8 j_mayer
GEN_SPEOP_ARITH_IMM2(evaddw);
5534 0487d6a8 j_mayer
#define gen_evaddiw gen_evaddwi
5535 0487d6a8 j_mayer
GEN_SPEOP_ARITH_IMM2(evsubfw);
5536 0487d6a8 j_mayer
#define gen_evsubifw gen_evsubfwi
5537 0487d6a8 j_mayer
GEN_SPEOP_LOGIC_IMM2(evslw);
5538 0487d6a8 j_mayer
GEN_SPEOP_LOGIC_IMM2(evsrwu);
5539 0487d6a8 j_mayer
#define gen_evsrwis gen_evsrwsi
5540 0487d6a8 j_mayer
GEN_SPEOP_LOGIC_IMM2(evsrws);
5541 0487d6a8 j_mayer
#define gen_evsrwiu gen_evsrwui
5542 0487d6a8 j_mayer
GEN_SPEOP_LOGIC_IMM2(evrlw);
5543 0487d6a8 j_mayer
5544 b068d6a7 j_mayer
static always_inline void gen_evsplati (DisasContext *ctx)
5545 0487d6a8 j_mayer
{
5546 0487d6a8 j_mayer
    int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
5547 0487d6a8 j_mayer
5548 0487d6a8 j_mayer
    gen_op_splatwi_T0_64(imm);
5549 0487d6a8 j_mayer
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5550 0487d6a8 j_mayer
}
5551 0487d6a8 j_mayer
5552 b068d6a7 j_mayer
static always_inline void gen_evsplatfi (DisasContext *ctx)
5553 0487d6a8 j_mayer
{
5554 0487d6a8 j_mayer
    uint32_t imm = rA(ctx->opcode) << 27;
5555 0487d6a8 j_mayer
5556 0487d6a8 j_mayer
    gen_op_splatwi_T0_64(imm);
5557 0487d6a8 j_mayer
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5558 0487d6a8 j_mayer
}
5559 0487d6a8 j_mayer
5560 0487d6a8 j_mayer
/* Comparison */
5561 0487d6a8 j_mayer
GEN_SPEOP_COMP(evcmpgtu);
5562 0487d6a8 j_mayer
GEN_SPEOP_COMP(evcmpgts);
5563 0487d6a8 j_mayer
GEN_SPEOP_COMP(evcmpltu);
5564 0487d6a8 j_mayer
GEN_SPEOP_COMP(evcmplts);
5565 0487d6a8 j_mayer
GEN_SPEOP_COMP(evcmpeq);
5566 0487d6a8 j_mayer
5567 0487d6a8 j_mayer
GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
5568 0487d6a8 j_mayer
GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
5569 0487d6a8 j_mayer
GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
5570 0487d6a8 j_mayer
GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
5571 0487d6a8 j_mayer
GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
5572 0487d6a8 j_mayer
GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
5573 0487d6a8 j_mayer
GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
5574 0487d6a8 j_mayer
GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
5575 0487d6a8 j_mayer
GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
5576 0487d6a8 j_mayer
GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
5577 0487d6a8 j_mayer
GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
5578 0487d6a8 j_mayer
GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
5579 0487d6a8 j_mayer
GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
5580 0487d6a8 j_mayer
GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
5581 0487d6a8 j_mayer
GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
5582 0487d6a8 j_mayer
GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
5583 0487d6a8 j_mayer
GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
5584 0487d6a8 j_mayer
GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
5585 0487d6a8 j_mayer
GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
5586 0487d6a8 j_mayer
GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
5587 0487d6a8 j_mayer
GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
5588 0487d6a8 j_mayer
GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
5589 0487d6a8 j_mayer
GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
5590 0487d6a8 j_mayer
GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
5591 0487d6a8 j_mayer
GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
5592 0487d6a8 j_mayer
5593 b068d6a7 j_mayer
static always_inline void gen_evsel (DisasContext *ctx)
5594 0487d6a8 j_mayer
{
5595 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {
5596 e1833e1f j_mayer
        GEN_EXCP_NO_AP(ctx);
5597 0487d6a8 j_mayer
        return;
5598 0487d6a8 j_mayer
    }
5599 0487d6a8 j_mayer
    gen_op_load_crf_T0(ctx->opcode & 0x7);
5600 0487d6a8 j_mayer
    gen_op_load_gpr64_T0(rA(ctx->opcode));
5601 0487d6a8 j_mayer
    gen_op_load_gpr64_T1(rB(ctx->opcode));
5602 0487d6a8 j_mayer
    gen_op_evsel();
5603 0487d6a8 j_mayer
    gen_op_store_T0_gpr64(rD(ctx->opcode));
5604 0487d6a8 j_mayer
}
5605 0487d6a8 j_mayer
5606 c7697e1f j_mayer
GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
5607 0487d6a8 j_mayer
{
5608 0487d6a8 j_mayer
    gen_evsel(ctx);
5609 0487d6a8 j_mayer
}
5610 c7697e1f j_mayer
GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
5611 0487d6a8 j_mayer
{
5612 0487d6a8 j_mayer
    gen_evsel(ctx);
5613 0487d6a8 j_mayer
}
5614 c7697e1f j_mayer
GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
5615 0487d6a8 j_mayer
{
5616 0487d6a8 j_mayer
    gen_evsel(ctx);
5617 0487d6a8 j_mayer
}
5618 c7697e1f j_mayer
GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
5619 0487d6a8 j_mayer
{
5620 0487d6a8 j_mayer
    gen_evsel(ctx);
5621 0487d6a8 j_mayer
}
5622 0487d6a8 j_mayer
5623 0487d6a8 j_mayer
/* Load and stores */
5624 0487d6a8 j_mayer
#if defined(TARGET_PPC64)
5625 0487d6a8 j_mayer
/* In that case, we already have 64 bits load & stores
5626 0487d6a8 j_mayer
 * so, spe_ldd is equivalent to ld and spe_std is equivalent to std
5627 0487d6a8 j_mayer
 */
5628 7863667f j_mayer
#define gen_op_spe_ldd_raw           gen_op_ld_raw
5629 7863667f j_mayer
#define gen_op_spe_ldd_user          gen_op_ld_user
5630 7863667f j_mayer
#define gen_op_spe_ldd_kernel        gen_op_ld_kernel
5631 7863667f j_mayer
#define gen_op_spe_ldd_hypv          gen_op_ld_hypv
5632 7863667f j_mayer
#define gen_op_spe_ldd_64_raw        gen_op_ld_64_raw
5633 7863667f j_mayer
#define gen_op_spe_ldd_64_user       gen_op_ld_64_user
5634 7863667f j_mayer
#define gen_op_spe_ldd_64_kernel     gen_op_ld_64_kernel
5635 7863667f j_mayer
#define gen_op_spe_ldd_64_hypv       gen_op_ld_64_hypv
5636 7863667f j_mayer
#define gen_op_spe_ldd_le_raw        gen_op_ld_le_raw
5637 7863667f j_mayer
#define gen_op_spe_ldd_le_user       gen_op_ld_le_user
5638 7863667f j_mayer
#define gen_op_spe_ldd_le_kernel     gen_op_ld_le_kernel
5639 7863667f j_mayer
#define gen_op_spe_ldd_le_hypv       gen_op_ld_le_hypv
5640 7863667f j_mayer
#define gen_op_spe_ldd_le_64_raw     gen_op_ld_le_64_raw
5641 7863667f j_mayer
#define gen_op_spe_ldd_le_64_user    gen_op_ld_le_64_user
5642 7863667f j_mayer
#define gen_op_spe_ldd_le_64_kernel  gen_op_ld_le_64_kernel
5643 7863667f j_mayer
#define gen_op_spe_ldd_le_64_hypv    gen_op_ld_le_64_hypv
5644 7863667f j_mayer
#define gen_op_spe_stdd_raw          gen_op_std_raw
5645 7863667f j_mayer
#define gen_op_spe_stdd_user         gen_op_std_user
5646 7863667f j_mayer
#define gen_op_spe_stdd_kernel       gen_op_std_kernel
5647 7863667f j_mayer
#define gen_op_spe_stdd_hypv         gen_op_std_hypv
5648 7863667f j_mayer
#define gen_op_spe_stdd_64_raw       gen_op_std_64_raw
5649 7863667f j_mayer
#define gen_op_spe_stdd_64_user      gen_op_std_64_user
5650 7863667f j_mayer
#define gen_op_spe_stdd_64_kernel    gen_op_std_64_kernel
5651 7863667f j_mayer
#define gen_op_spe_stdd_64_hypv      gen_op_std_64_hypv
5652 7863667f j_mayer
#define gen_op_spe_stdd_le_raw       gen_op_std_le_raw
5653 7863667f j_mayer
#define gen_op_spe_stdd_le_user      gen_op_std_le_user
5654 7863667f j_mayer
#define gen_op_spe_stdd_le_kernel    gen_op_std_le_kernel
5655 7863667f j_mayer
#define gen_op_spe_stdd_le_hypv      gen_op_std_le_hypv
5656 7863667f j_mayer
#define gen_op_spe_stdd_le_64_raw    gen_op_std_le_64_raw
5657 7863667f j_mayer
#define gen_op_spe_stdd_le_64_user   gen_op_std_le_64_user
5658 7863667f j_mayer
#define gen_op_spe_stdd_le_64_kernel gen_op_std_le_64_kernel
5659 7863667f j_mayer
#define gen_op_spe_stdd_le_64_hypv   gen_op_std_le_64_hypv
5660 0487d6a8 j_mayer
#endif /* defined(TARGET_PPC64) */
5661 0487d6a8 j_mayer
GEN_SPEOP_LDST(dd, 3);
5662 0487d6a8 j_mayer
GEN_SPEOP_LDST(dw, 3);
5663 0487d6a8 j_mayer
GEN_SPEOP_LDST(dh, 3);
5664 0487d6a8 j_mayer
GEN_SPEOP_LDST(whe, 2);
5665 0487d6a8 j_mayer
GEN_SPEOP_LD(whou, 2);
5666 0487d6a8 j_mayer
GEN_SPEOP_LD(whos, 2);
5667 0487d6a8 j_mayer
GEN_SPEOP_ST(who, 2);
5668 0487d6a8 j_mayer
5669 0487d6a8 j_mayer
#if defined(TARGET_PPC64)
5670 0487d6a8 j_mayer
/* In that case, spe_stwwo is equivalent to stw */
5671 7863667f j_mayer
#define gen_op_spe_stwwo_raw          gen_op_stw_raw
5672 7863667f j_mayer
#define gen_op_spe_stwwo_user         gen_op_stw_user
5673 7863667f j_mayer
#define gen_op_spe_stwwo_kernel       gen_op_stw_kernel
5674 7863667f j_mayer
#define gen_op_spe_stwwo_hypv         gen_op_stw_hypv
5675 7863667f j_mayer
#define gen_op_spe_stwwo_le_raw       gen_op_stw_le_raw
5676 7863667f j_mayer
#define gen_op_spe_stwwo_le_user      gen_op_stw_le_user
5677 7863667f j_mayer
#define gen_op_spe_stwwo_le_kernel    gen_op_stw_le_kernel
5678 7863667f j_mayer
#define gen_op_spe_stwwo_le_hypv      gen_op_stw_le_hypv
5679 7863667f j_mayer
#define gen_op_spe_stwwo_64_raw       gen_op_stw_64_raw
5680 7863667f j_mayer
#define gen_op_spe_stwwo_64_user      gen_op_stw_64_user
5681 7863667f j_mayer
#define gen_op_spe_stwwo_64_kernel    gen_op_stw_64_kernel
5682 7863667f j_mayer
#define gen_op_spe_stwwo_64_hypv      gen_op_stw_64_hypv
5683 7863667f j_mayer
#define gen_op_spe_stwwo_le_64_raw    gen_op_stw_le_64_raw
5684 7863667f j_mayer
#define gen_op_spe_stwwo_le_64_user   gen_op_stw_le_64_user
5685 0487d6a8 j_mayer
#define gen_op_spe_stwwo_le_64_kernel gen_op_stw_le_64_kernel
5686 7863667f j_mayer
#define gen_op_spe_stwwo_le_64_hypv   gen_op_stw_le_64_hypv
5687 0487d6a8 j_mayer
#endif
5688 0487d6a8 j_mayer
#define _GEN_OP_SPE_STWWE(suffix)                                             \
5689 b068d6a7 j_mayer
static always_inline void gen_op_spe_stwwe_##suffix (void)                    \
5690 0487d6a8 j_mayer
{                                                                             \
5691 0487d6a8 j_mayer
    gen_op_srli32_T1_64();                                                    \
5692 0487d6a8 j_mayer
    gen_op_spe_stwwo_##suffix();                                              \
5693 0487d6a8 j_mayer
}
5694 0487d6a8 j_mayer
#define _GEN_OP_SPE_STWWE_LE(suffix)                                          \
5695 b068d6a7 j_mayer
static always_inline void gen_op_spe_stwwe_le_##suffix (void)                 \
5696 0487d6a8 j_mayer
{                                                                             \
5697 0487d6a8 j_mayer
    gen_op_srli32_T1_64();                                                    \
5698 0487d6a8 j_mayer
    gen_op_spe_stwwo_le_##suffix();                                           \
5699 0487d6a8 j_mayer
}
5700 0487d6a8 j_mayer
#if defined(TARGET_PPC64)
5701 0487d6a8 j_mayer
#define GEN_OP_SPE_STWWE(suffix)                                              \
5702 0487d6a8 j_mayer
_GEN_OP_SPE_STWWE(suffix);                                                    \
5703 0487d6a8 j_mayer
_GEN_OP_SPE_STWWE_LE(suffix);                                                 \
5704 b068d6a7 j_mayer
static always_inline void gen_op_spe_stwwe_64_##suffix (void)                 \
5705 0487d6a8 j_mayer
{                                                                             \
5706 0487d6a8 j_mayer
    gen_op_srli32_T1_64();                                                    \
5707 0487d6a8 j_mayer
    gen_op_spe_stwwo_64_##suffix();                                           \
5708 0487d6a8 j_mayer
}                                                                             \
5709 b068d6a7 j_mayer
static always_inline void gen_op_spe_stwwe_le_64_##suffix (void)              \
5710 0487d6a8 j_mayer
{                                                                             \
5711 0487d6a8 j_mayer
    gen_op_srli32_T1_64();                                                    \
5712 0487d6a8 j_mayer
    gen_op_spe_stwwo_le_64_##suffix();                                        \
5713 0487d6a8 j_mayer
}
5714 0487d6a8 j_mayer
#else
5715 0487d6a8 j_mayer
#define GEN_OP_SPE_STWWE(suffix)                                              \
5716 0487d6a8 j_mayer
_GEN_OP_SPE_STWWE(suffix);                                                    \
5717 0487d6a8 j_mayer
_GEN_OP_SPE_STWWE_LE(suffix)
5718 0487d6a8 j_mayer
#endif
5719 0487d6a8 j_mayer
#if defined(CONFIG_USER_ONLY)
5720 0487d6a8 j_mayer
GEN_OP_SPE_STWWE(raw);
5721 0487d6a8 j_mayer
#else /* defined(CONFIG_USER_ONLY) */
5722 0487d6a8 j_mayer
GEN_OP_SPE_STWWE(user);
5723 7863667f j_mayer
GEN_OP_SPE_STWWE(kernel);
5724 7863667f j_mayer
GEN_OP_SPE_STWWE(hypv);
5725 0487d6a8 j_mayer
#endif /* defined(CONFIG_USER_ONLY) */
5726 0487d6a8 j_mayer
GEN_SPEOP_ST(wwe, 2);
5727 0487d6a8 j_mayer
GEN_SPEOP_ST(wwo, 2);
5728 0487d6a8 j_mayer
5729 0487d6a8 j_mayer
#define GEN_SPE_LDSPLAT(name, op, suffix)                                     \
5730 b068d6a7 j_mayer
static always_inline void gen_op_spe_l##name##_##suffix (void)                \
5731 0487d6a8 j_mayer
{                                                                             \
5732 0487d6a8 j_mayer
    gen_op_##op##_##suffix();                                                 \
5733 0487d6a8 j_mayer
    gen_op_splatw_T1_64();                                                    \
5734 0487d6a8 j_mayer
}
5735 0487d6a8 j_mayer
5736 0487d6a8 j_mayer
#define GEN_OP_SPE_LHE(suffix)                                                \
5737 b068d6a7 j_mayer
static always_inline void gen_op_spe_lhe_##suffix (void)                      \
5738 0487d6a8 j_mayer
{                                                                             \
5739 0487d6a8 j_mayer
    gen_op_spe_lh_##suffix();                                                 \
5740 0487d6a8 j_mayer
    gen_op_sli16_T1_64();                                                     \
5741 0487d6a8 j_mayer
}
5742 0487d6a8 j_mayer
5743 0487d6a8 j_mayer
#define GEN_OP_SPE_LHX(suffix)                                                \
5744 b068d6a7 j_mayer
static always_inline void gen_op_spe_lhx_##suffix (void)                      \
5745 0487d6a8 j_mayer
{                                                                             \
5746 0487d6a8 j_mayer
    gen_op_spe_lh_##suffix();                                                 \
5747 0487d6a8 j_mayer
    gen_op_extsh_T1_64();                                                     \
5748 0487d6a8 j_mayer
}
5749 0487d6a8 j_mayer
5750 0487d6a8 j_mayer
#if defined(CONFIG_USER_ONLY)
5751 0487d6a8 j_mayer
GEN_OP_SPE_LHE(raw);
5752 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, raw);
5753 0487d6a8 j_mayer
GEN_OP_SPE_LHE(le_raw);
5754 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_raw);
5755 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, raw);
5756 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_raw);
5757 0487d6a8 j_mayer
GEN_OP_SPE_LHX(raw);
5758 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, raw);
5759 0487d6a8 j_mayer
GEN_OP_SPE_LHX(le_raw);
5760 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_raw);
5761 0487d6a8 j_mayer
#if defined(TARGET_PPC64)
5762 0487d6a8 j_mayer
GEN_OP_SPE_LHE(64_raw);
5763 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_raw);
5764 0487d6a8 j_mayer
GEN_OP_SPE_LHE(le_64_raw);
5765 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_raw);
5766 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_raw);
5767 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_raw);
5768 0487d6a8 j_mayer
GEN_OP_SPE_LHX(64_raw);
5769 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_raw);
5770 0487d6a8 j_mayer
GEN_OP_SPE_LHX(le_64_raw);
5771 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_raw);
5772 0487d6a8 j_mayer
#endif
5773 0487d6a8 j_mayer
#else
5774 0487d6a8 j_mayer
GEN_OP_SPE_LHE(user);
5775 7863667f j_mayer
GEN_OP_SPE_LHE(kernel);
5776 7863667f j_mayer
GEN_OP_SPE_LHE(hypv);
5777 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, user);
5778 7863667f j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, kernel);
5779 7863667f j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, hypv);
5780 0487d6a8 j_mayer
GEN_OP_SPE_LHE(le_user);
5781 7863667f j_mayer
GEN_OP_SPE_LHE(le_kernel);
5782 7863667f j_mayer
GEN_OP_SPE_LHE(le_hypv);
5783 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_user);
5784 7863667f j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_kernel);
5785 7863667f j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_hypv);
5786 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, user);
5787 7863667f j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, kernel);
5788 7863667f j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, hypv);
5789 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_user);
5790 7863667f j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_kernel);
5791 7863667f j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_hypv);
5792 0487d6a8 j_mayer
GEN_OP_SPE_LHX(user);
5793 7863667f j_mayer
GEN_OP_SPE_LHX(kernel);
5794 7863667f j_mayer
GEN_OP_SPE_LHX(hypv);
5795 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, user);
5796 7863667f j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, kernel);
5797 7863667f j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, hypv);
5798 0487d6a8 j_mayer
GEN_OP_SPE_LHX(le_user);
5799 7863667f j_mayer
GEN_OP_SPE_LHX(le_kernel);
5800 7863667f j_mayer
GEN_OP_SPE_LHX(le_hypv);
5801 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_user);
5802 7863667f j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_kernel);
5803 7863667f j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_hypv);
5804 0487d6a8 j_mayer
#if defined(TARGET_PPC64)
5805 0487d6a8 j_mayer
GEN_OP_SPE_LHE(64_user);
5806 7863667f j_mayer
GEN_OP_SPE_LHE(64_kernel);
5807 7863667f j_mayer
GEN_OP_SPE_LHE(64_hypv);
5808 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_user);
5809 7863667f j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_kernel);
5810 7863667f j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_hypv);
5811 0487d6a8 j_mayer
GEN_OP_SPE_LHE(le_64_user);
5812 7863667f j_mayer
GEN_OP_SPE_LHE(le_64_kernel);
5813 7863667f j_mayer
GEN_OP_SPE_LHE(le_64_hypv);
5814 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_user);
5815 7863667f j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_kernel);
5816 7863667f j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_hypv);
5817 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_user);
5818 7863667f j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_kernel);
5819 7863667f j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_hypv);
5820 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_user);
5821 7863667f j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_kernel);
5822 7863667f j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_hypv);
5823 0487d6a8 j_mayer
GEN_OP_SPE_LHX(64_user);
5824 7863667f j_mayer
GEN_OP_SPE_LHX(64_kernel);
5825 7863667f j_mayer
GEN_OP_SPE_LHX(64_hypv);
5826 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_user);
5827 7863667f j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_kernel);
5828 7863667f j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_hypv);
5829 0487d6a8 j_mayer
GEN_OP_SPE_LHX(le_64_user);
5830 7863667f j_mayer
GEN_OP_SPE_LHX(le_64_kernel);
5831 7863667f j_mayer
GEN_OP_SPE_LHX(le_64_hypv);
5832 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_user);
5833 7863667f j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_kernel);
5834 7863667f j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_hypv);
5835 0487d6a8 j_mayer
#endif
5836 0487d6a8 j_mayer
#endif
5837 0487d6a8 j_mayer
GEN_SPEOP_LD(hhesplat, 1);
5838 0487d6a8 j_mayer
GEN_SPEOP_LD(hhousplat, 1);
5839 0487d6a8 j_mayer
GEN_SPEOP_LD(hhossplat, 1);
5840 0487d6a8 j_mayer
GEN_SPEOP_LD(wwsplat, 2);
5841 0487d6a8 j_mayer
GEN_SPEOP_LD(whsplat, 2);
5842 0487d6a8 j_mayer
5843 0487d6a8 j_mayer
GEN_SPE(evlddx,         evldd,         0x00, 0x0C, 0x00000000, PPC_SPE); //
5844 0487d6a8 j_mayer
GEN_SPE(evldwx,         evldw,         0x01, 0x0C, 0x00000000, PPC_SPE); //
5845 0487d6a8 j_mayer
GEN_SPE(evldhx,         evldh,         0x02, 0x0C, 0x00000000, PPC_SPE); //
5846 0487d6a8 j_mayer
GEN_SPE(evlhhesplatx,   evlhhesplat,   0x04, 0x0C, 0x00000000, PPC_SPE); //
5847 0487d6a8 j_mayer
GEN_SPE(evlhhousplatx,  evlhhousplat,  0x06, 0x0C, 0x00000000, PPC_SPE); //
5848 0487d6a8 j_mayer
GEN_SPE(evlhhossplatx,  evlhhossplat,  0x07, 0x0C, 0x00000000, PPC_SPE); //
5849 0487d6a8 j_mayer
GEN_SPE(evlwhex,        evlwhe,        0x08, 0x0C, 0x00000000, PPC_SPE); //
5850 0487d6a8 j_mayer
GEN_SPE(evlwhoux,       evlwhou,       0x0A, 0x0C, 0x00000000, PPC_SPE); //
5851 0487d6a8 j_mayer
GEN_SPE(evlwhosx,       evlwhos,       0x0B, 0x0C, 0x00000000, PPC_SPE); //
5852 0487d6a8 j_mayer
GEN_SPE(evlwwsplatx,    evlwwsplat,    0x0C, 0x0C, 0x00000000, PPC_SPE); //
5853 0487d6a8 j_mayer
GEN_SPE(evlwhsplatx,    evlwhsplat,    0x0E, 0x0C, 0x00000000, PPC_SPE); //
5854 0487d6a8 j_mayer
GEN_SPE(evstddx,        evstdd,        0x10, 0x0C, 0x00000000, PPC_SPE); //
5855 0487d6a8 j_mayer
GEN_SPE(evstdwx,        evstdw,        0x11, 0x0C, 0x00000000, PPC_SPE); //
5856 0487d6a8 j_mayer
GEN_SPE(evstdhx,        evstdh,        0x12, 0x0C, 0x00000000, PPC_SPE); //
5857 0487d6a8 j_mayer
GEN_SPE(evstwhex,       evstwhe,       0x18, 0x0C, 0x00000000, PPC_SPE); //
5858 0487d6a8 j_mayer
GEN_SPE(evstwhox,       evstwho,       0x1A, 0x0C, 0x00000000, PPC_SPE); //
5859 0487d6a8 j_mayer
GEN_SPE(evstwwex,       evstwwe,       0x1C, 0x0C, 0x00000000, PPC_SPE); //
5860 0487d6a8 j_mayer
GEN_SPE(evstwwox,       evstwwo,       0x1E, 0x0C, 0x00000000, PPC_SPE); //
5861 0487d6a8 j_mayer
5862 0487d6a8 j_mayer
/* Multiply and add - TODO */
5863 0487d6a8 j_mayer
#if 0
5864 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
5865 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
5866 0487d6a8 j_mayer
GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
5867 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
5868 0487d6a8 j_mayer
GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
5869 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
5870 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
5871 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
5872 0487d6a8 j_mayer
GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
5873 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
5874 0487d6a8 j_mayer
GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
5875 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
5876 0487d6a8 j_mayer

5877 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
5878 0487d6a8 j_mayer
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
5879 0487d6a8 j_mayer
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
5880 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
5881 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
5882 0487d6a8 j_mayer
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
5883 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
5884 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
5885 0487d6a8 j_mayer
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
5886 0487d6a8 j_mayer
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
5887 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
5888 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
5889 0487d6a8 j_mayer
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
5890 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
5891 0487d6a8 j_mayer

5892 0487d6a8 j_mayer
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
5893 0487d6a8 j_mayer
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
5894 0487d6a8 j_mayer
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
5895 0487d6a8 j_mayer
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
5896 0487d6a8 j_mayer
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
5897 0487d6a8 j_mayer
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
5898 0487d6a8 j_mayer

5899 0487d6a8 j_mayer
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
5900 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
5901 0487d6a8 j_mayer
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
5902 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
5903 0487d6a8 j_mayer
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
5904 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
5905 0487d6a8 j_mayer
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
5906 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
5907 0487d6a8 j_mayer
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
5908 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
5909 0487d6a8 j_mayer
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
5910 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
5911 0487d6a8 j_mayer

5912 0487d6a8 j_mayer
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
5913 0487d6a8 j_mayer
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
5914 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
5915 0487d6a8 j_mayer
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
5916 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
5917 0487d6a8 j_mayer

5918 0487d6a8 j_mayer
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
5919 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
5920 0487d6a8 j_mayer
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
5921 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
5922 0487d6a8 j_mayer
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
5923 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
5924 0487d6a8 j_mayer
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
5925 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
5926 0487d6a8 j_mayer
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
5927 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
5928 0487d6a8 j_mayer
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
5929 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
5930 0487d6a8 j_mayer

5931 0487d6a8 j_mayer
GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
5932 0487d6a8 j_mayer
GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
5933 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
5934 0487d6a8 j_mayer
GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
5935 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
5936 0487d6a8 j_mayer
#endif
5937 0487d6a8 j_mayer
5938 0487d6a8 j_mayer
/***                      SPE floating-point extension                     ***/
5939 0487d6a8 j_mayer
#define GEN_SPEFPUOP_CONV(name)                                               \
5940 b068d6a7 j_mayer
static always_inline void gen_##name (DisasContext *ctx)                      \
5941 0487d6a8 j_mayer
{                                                                             \
5942 0487d6a8 j_mayer
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5943 0487d6a8 j_mayer
    gen_op_##name();                                                          \
5944 0487d6a8 j_mayer
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5945 0487d6a8 j_mayer
}
5946 0487d6a8 j_mayer
5947 0487d6a8 j_mayer
/* Single precision floating-point vectors operations */
5948 0487d6a8 j_mayer
/* Arithmetic */
5949 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evfsadd);
5950 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evfssub);
5951 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evfsmul);
5952 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evfsdiv);
5953 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evfsabs);
5954 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evfsnabs);
5955 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evfsneg);
5956 0487d6a8 j_mayer
/* Conversion */
5957 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfscfui);
5958 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfscfsi);
5959 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfscfuf);
5960 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfscfsf);
5961 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfsctui);
5962 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfsctsi);
5963 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfsctuf);
5964 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfsctsf);
5965 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfsctuiz);
5966 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfsctsiz);
5967 0487d6a8 j_mayer
/* Comparison */
5968 0487d6a8 j_mayer
GEN_SPEOP_COMP(evfscmpgt);
5969 0487d6a8 j_mayer
GEN_SPEOP_COMP(evfscmplt);
5970 0487d6a8 j_mayer
GEN_SPEOP_COMP(evfscmpeq);
5971 0487d6a8 j_mayer
GEN_SPEOP_COMP(evfststgt);
5972 0487d6a8 j_mayer
GEN_SPEOP_COMP(evfststlt);
5973 0487d6a8 j_mayer
GEN_SPEOP_COMP(evfststeq);
5974 0487d6a8 j_mayer
5975 0487d6a8 j_mayer
/* Opcodes definitions */
5976 0487d6a8 j_mayer
GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5977 0487d6a8 j_mayer
GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
5978 0487d6a8 j_mayer
GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
5979 0487d6a8 j_mayer
GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
5980 0487d6a8 j_mayer
GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
5981 0487d6a8 j_mayer
GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
5982 0487d6a8 j_mayer
GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
5983 0487d6a8 j_mayer
GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
5984 0487d6a8 j_mayer
GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
5985 0487d6a8 j_mayer
GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
5986 0487d6a8 j_mayer
GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
5987 0487d6a8 j_mayer
GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
5988 0487d6a8 j_mayer
GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
5989 0487d6a8 j_mayer
GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
5990 0487d6a8 j_mayer
5991 0487d6a8 j_mayer
/* Single precision floating-point operations */
5992 0487d6a8 j_mayer
/* Arithmetic */
5993 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efsadd);
5994 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efssub);
5995 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efsmul);
5996 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efsdiv);
5997 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(efsabs);
5998 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(efsnabs);
5999 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(efsneg);
6000 0487d6a8 j_mayer
/* Conversion */
6001 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efscfui);
6002 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efscfsi);
6003 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efscfuf);
6004 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efscfsf);
6005 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efsctui);
6006 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efsctsi);
6007 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efsctuf);
6008 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efsctsf);
6009 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efsctuiz);
6010 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efsctsiz);
6011 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efscfd);
6012 0487d6a8 j_mayer
/* Comparison */
6013 0487d6a8 j_mayer
GEN_SPEOP_COMP(efscmpgt);
6014 0487d6a8 j_mayer
GEN_SPEOP_COMP(efscmplt);
6015 0487d6a8 j_mayer
GEN_SPEOP_COMP(efscmpeq);
6016 0487d6a8 j_mayer
GEN_SPEOP_COMP(efststgt);
6017 0487d6a8 j_mayer
GEN_SPEOP_COMP(efststlt);
6018 0487d6a8 j_mayer
GEN_SPEOP_COMP(efststeq);
6019 0487d6a8 j_mayer
6020 0487d6a8 j_mayer
/* Opcodes definitions */
6021 05332d70 j_mayer
GEN_SPE(efsadd,         efssub,        0x00, 0x0B, 0x00000000, PPC_SPEFPU); //
6022 0487d6a8 j_mayer
GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
6023 0487d6a8 j_mayer
GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
6024 0487d6a8 j_mayer
GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
6025 0487d6a8 j_mayer
GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
6026 0487d6a8 j_mayer
GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
6027 0487d6a8 j_mayer
GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
6028 0487d6a8 j_mayer
GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
6029 0487d6a8 j_mayer
GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
6030 0487d6a8 j_mayer
GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
6031 9ceb2a77 ths
GEN_SPE(efsctuiz,       speundef,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
6032 9ceb2a77 ths
GEN_SPE(efsctsiz,       speundef,      0x0D, 0x0B, 0x00180000, PPC_SPEFPU); //
6033 0487d6a8 j_mayer
GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
6034 0487d6a8 j_mayer
GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
6035 0487d6a8 j_mayer
6036 0487d6a8 j_mayer
/* Double precision floating-point operations */
6037 0487d6a8 j_mayer
/* Arithmetic */
6038 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efdadd);
6039 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efdsub);
6040 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efdmul);
6041 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efddiv);
6042 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(efdabs);
6043 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(efdnabs);
6044 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(efdneg);
6045 0487d6a8 j_mayer
/* Conversion */
6046 0487d6a8 j_mayer
6047 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfui);
6048 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfsi);
6049 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfuf);
6050 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfsf);
6051 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctui);
6052 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctsi);
6053 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctuf);
6054 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctsf);
6055 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctuiz);
6056 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctsiz);
6057 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfs);
6058 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfuid);
6059 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfsid);
6060 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctuidz);
6061 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctsidz);
6062 0487d6a8 j_mayer
/* Comparison */
6063 0487d6a8 j_mayer
GEN_SPEOP_COMP(efdcmpgt);
6064 0487d6a8 j_mayer
GEN_SPEOP_COMP(efdcmplt);
6065 0487d6a8 j_mayer
GEN_SPEOP_COMP(efdcmpeq);
6066 0487d6a8 j_mayer
GEN_SPEOP_COMP(efdtstgt);
6067 0487d6a8 j_mayer
GEN_SPEOP_COMP(efdtstlt);
6068 0487d6a8 j_mayer
GEN_SPEOP_COMP(efdtsteq);
6069 0487d6a8 j_mayer
6070 0487d6a8 j_mayer
/* Opcodes definitions */
6071 0487d6a8 j_mayer
GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
6072 0487d6a8 j_mayer
GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
6073 0487d6a8 j_mayer
GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
6074 0487d6a8 j_mayer
GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
6075 0487d6a8 j_mayer
GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
6076 0487d6a8 j_mayer
GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
6077 0487d6a8 j_mayer
GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
6078 0487d6a8 j_mayer
GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
6079 0487d6a8 j_mayer
GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
6080 0487d6a8 j_mayer
GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
6081 0487d6a8 j_mayer
GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
6082 0487d6a8 j_mayer
GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
6083 0487d6a8 j_mayer
GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
6084 0487d6a8 j_mayer
GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
6085 0487d6a8 j_mayer
GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
6086 0487d6a8 j_mayer
GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
6087 0487d6a8 j_mayer
6088 79aceca5 bellard
/* End opcode list */
6089 79aceca5 bellard
GEN_OPCODE_MARK(end);
6090 79aceca5 bellard
6091 3fc6c082 bellard
#include "translate_init.c"
6092 0411a972 j_mayer
#include "helper_regs.h"
6093 79aceca5 bellard
6094 9a64fbe4 bellard
/*****************************************************************************/
6095 3fc6c082 bellard
/* Misc PowerPC helpers */
6096 36081602 j_mayer
void cpu_dump_state (CPUState *env, FILE *f,
6097 36081602 j_mayer
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6098 36081602 j_mayer
                     int flags)
6099 79aceca5 bellard
{
6100 3fc6c082 bellard
#define RGPL  4
6101 3fc6c082 bellard
#define RFPL  4
6102 3fc6c082 bellard
6103 79aceca5 bellard
    int i;
6104 79aceca5 bellard
6105 077fc206 j_mayer
    cpu_fprintf(f, "NIP " ADDRX "   LR " ADDRX " CTR " ADDRX " XER %08x\n",
6106 077fc206 j_mayer
                env->nip, env->lr, env->ctr, hreg_load_xer(env));
6107 6b542af7 j_mayer
    cpu_fprintf(f, "MSR " ADDRX " HID0 " ADDRX "  HF " ADDRX " idx %d\n",
6108 6b542af7 j_mayer
                env->msr, env->spr[SPR_HID0], env->hflags, env->mmu_idx);
6109 d9bce9d9 j_mayer
#if !defined(NO_TIMER_DUMP)
6110 077fc206 j_mayer
    cpu_fprintf(f, "TB %08x %08x "
6111 76a66253 j_mayer
#if !defined(CONFIG_USER_ONLY)
6112 76a66253 j_mayer
                "DECR %08x"
6113 76a66253 j_mayer
#endif
6114 76a66253 j_mayer
                "\n",
6115 077fc206 j_mayer
                cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
6116 76a66253 j_mayer
#if !defined(CONFIG_USER_ONLY)
6117 76a66253 j_mayer
                , cpu_ppc_load_decr(env)
6118 76a66253 j_mayer
#endif
6119 76a66253 j_mayer
                );
6120 077fc206 j_mayer
#endif
6121 76a66253 j_mayer
    for (i = 0; i < 32; i++) {
6122 3fc6c082 bellard
        if ((i & (RGPL - 1)) == 0)
6123 3fc6c082 bellard
            cpu_fprintf(f, "GPR%02d", i);
6124 6b542af7 j_mayer
        cpu_fprintf(f, " " REGX, ppc_dump_gpr(env, i));
6125 3fc6c082 bellard
        if ((i & (RGPL - 1)) == (RGPL - 1))
6126 7fe48483 bellard
            cpu_fprintf(f, "\n");
6127 76a66253 j_mayer
    }
6128 3fc6c082 bellard
    cpu_fprintf(f, "CR ");
6129 76a66253 j_mayer
    for (i = 0; i < 8; i++)
6130 7fe48483 bellard
        cpu_fprintf(f, "%01x", env->crf[i]);
6131 7fe48483 bellard
    cpu_fprintf(f, "  [");
6132 76a66253 j_mayer
    for (i = 0; i < 8; i++) {
6133 76a66253 j_mayer
        char a = '-';
6134 76a66253 j_mayer
        if (env->crf[i] & 0x08)
6135 76a66253 j_mayer
            a = 'L';
6136 76a66253 j_mayer
        else if (env->crf[i] & 0x04)
6137 76a66253 j_mayer
            a = 'G';
6138 76a66253 j_mayer
        else if (env->crf[i] & 0x02)
6139 76a66253 j_mayer
            a = 'E';
6140 7fe48483 bellard
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
6141 76a66253 j_mayer
    }
6142 6b542af7 j_mayer
    cpu_fprintf(f, " ]             RES " ADDRX "\n", env->reserve);
6143 3fc6c082 bellard
    for (i = 0; i < 32; i++) {
6144 3fc6c082 bellard
        if ((i & (RFPL - 1)) == 0)
6145 3fc6c082 bellard
            cpu_fprintf(f, "FPR%02d", i);
6146 26a76461 bellard
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
6147 3fc6c082 bellard
        if ((i & (RFPL - 1)) == (RFPL - 1))
6148 7fe48483 bellard
            cpu_fprintf(f, "\n");
6149 79aceca5 bellard
    }
6150 f2e63a42 j_mayer
#if !defined(CONFIG_USER_ONLY)
6151 6b542af7 j_mayer
    cpu_fprintf(f, "SRR0 " ADDRX " SRR1 " ADDRX " SDR1 " ADDRX "\n",
6152 3fc6c082 bellard
                env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
6153 f2e63a42 j_mayer
#endif
6154 79aceca5 bellard
6155 3fc6c082 bellard
#undef RGPL
6156 3fc6c082 bellard
#undef RFPL
6157 79aceca5 bellard
}
6158 79aceca5 bellard
6159 76a66253 j_mayer
void cpu_dump_statistics (CPUState *env, FILE*f,
6160 76a66253 j_mayer
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6161 76a66253 j_mayer
                          int flags)
6162 76a66253 j_mayer
{
6163 76a66253 j_mayer
#if defined(DO_PPC_STATISTICS)
6164 76a66253 j_mayer
    opc_handler_t **t1, **t2, **t3, *handler;
6165 76a66253 j_mayer
    int op1, op2, op3;
6166 76a66253 j_mayer
6167 76a66253 j_mayer
    t1 = env->opcodes;
6168 76a66253 j_mayer
    for (op1 = 0; op1 < 64; op1++) {
6169 76a66253 j_mayer
        handler = t1[op1];
6170 76a66253 j_mayer
        if (is_indirect_opcode(handler)) {
6171 76a66253 j_mayer
            t2 = ind_table(handler);
6172 76a66253 j_mayer
            for (op2 = 0; op2 < 32; op2++) {
6173 76a66253 j_mayer
                handler = t2[op2];
6174 76a66253 j_mayer
                if (is_indirect_opcode(handler)) {
6175 76a66253 j_mayer
                    t3 = ind_table(handler);
6176 76a66253 j_mayer
                    for (op3 = 0; op3 < 32; op3++) {
6177 76a66253 j_mayer
                        handler = t3[op3];
6178 76a66253 j_mayer
                        if (handler->count == 0)
6179 76a66253 j_mayer
                            continue;
6180 76a66253 j_mayer
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
6181 76a66253 j_mayer
                                    "%016llx %lld\n",
6182 76a66253 j_mayer
                                    op1, op2, op3, op1, (op3 << 5) | op2,
6183 76a66253 j_mayer
                                    handler->oname,
6184 76a66253 j_mayer
                                    handler->count, handler->count);
6185 76a66253 j_mayer
                    }
6186 76a66253 j_mayer
                } else {
6187 76a66253 j_mayer
                    if (handler->count == 0)
6188 76a66253 j_mayer
                        continue;
6189 76a66253 j_mayer
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
6190 76a66253 j_mayer
                                "%016llx %lld\n",
6191 76a66253 j_mayer
                                op1, op2, op1, op2, handler->oname,
6192 76a66253 j_mayer
                                handler->count, handler->count);
6193 76a66253 j_mayer
                }
6194 76a66253 j_mayer
            }
6195 76a66253 j_mayer
        } else {
6196 76a66253 j_mayer
            if (handler->count == 0)
6197 76a66253 j_mayer
                continue;
6198 76a66253 j_mayer
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
6199 76a66253 j_mayer
                        op1, op1, handler->oname,
6200 76a66253 j_mayer
                        handler->count, handler->count);
6201 76a66253 j_mayer
        }
6202 76a66253 j_mayer
    }
6203 76a66253 j_mayer
#endif
6204 76a66253 j_mayer
}
6205 76a66253 j_mayer
6206 9a64fbe4 bellard
/*****************************************************************************/
6207 2cfc5f17 ths
static always_inline void gen_intermediate_code_internal (CPUState *env,
6208 2cfc5f17 ths
                                                          TranslationBlock *tb,
6209 2cfc5f17 ths
                                                          int search_pc)
6210 79aceca5 bellard
{
6211 9fddaa0c bellard
    DisasContext ctx, *ctxp = &ctx;
6212 79aceca5 bellard
    opc_handler_t **table, *handler;
6213 0fa85d43 bellard
    target_ulong pc_start;
6214 79aceca5 bellard
    uint16_t *gen_opc_end;
6215 056401ea j_mayer
    int supervisor, little_endian;
6216 79aceca5 bellard
    int j, lj = -1;
6217 2e70f6ef pbrook
    int num_insns;
6218 2e70f6ef pbrook
    int max_insns;
6219 79aceca5 bellard
6220 79aceca5 bellard
    pc_start = tb->pc;
6221 79aceca5 bellard
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6222 7c58044c j_mayer
#if defined(OPTIMIZE_FPRF_UPDATE)
6223 7c58044c j_mayer
    gen_fprf_ptr = gen_fprf_buf;
6224 7c58044c j_mayer
#endif
6225 046d6672 bellard
    ctx.nip = pc_start;
6226 79aceca5 bellard
    ctx.tb = tb;
6227 e1833e1f j_mayer
    ctx.exception = POWERPC_EXCP_NONE;
6228 3fc6c082 bellard
    ctx.spr_cb = env->spr_cb;
6229 6ebbf390 j_mayer
    supervisor = env->mmu_idx;
6230 6ebbf390 j_mayer
#if !defined(CONFIG_USER_ONLY)
6231 2857068e j_mayer
    ctx.supervisor = supervisor;
6232 d9bce9d9 j_mayer
#endif
6233 056401ea j_mayer
    little_endian = env->hflags & (1 << MSR_LE) ? 1 : 0;
6234 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
6235 d9bce9d9 j_mayer
    ctx.sf_mode = msr_sf;
6236 056401ea j_mayer
    ctx.mem_idx = (supervisor << 2) | (msr_sf << 1) | little_endian;
6237 2857068e j_mayer
#else
6238 056401ea j_mayer
    ctx.mem_idx = (supervisor << 1) | little_endian;
6239 9a64fbe4 bellard
#endif
6240 d63001d1 j_mayer
    ctx.dcache_line_size = env->dcache_line_size;
6241 3cc62370 bellard
    ctx.fpu_enabled = msr_fp;
6242 a9d9eb8f j_mayer
    if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
6243 d26bfc9a j_mayer
        ctx.spe_enabled = msr_spe;
6244 d26bfc9a j_mayer
    else
6245 d26bfc9a j_mayer
        ctx.spe_enabled = 0;
6246 a9d9eb8f j_mayer
    if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
6247 a9d9eb8f j_mayer
        ctx.altivec_enabled = msr_vr;
6248 a9d9eb8f j_mayer
    else
6249 a9d9eb8f j_mayer
        ctx.altivec_enabled = 0;
6250 d26bfc9a j_mayer
    if ((env->flags & POWERPC_FLAG_SE) && msr_se)
6251 8cbcb4fa aurel32
        ctx.singlestep_enabled = CPU_SINGLE_STEP;
6252 d26bfc9a j_mayer
    else
6253 8cbcb4fa aurel32
        ctx.singlestep_enabled = 0;
6254 d26bfc9a j_mayer
    if ((env->flags & POWERPC_FLAG_BE) && msr_be)
6255 8cbcb4fa aurel32
        ctx.singlestep_enabled |= CPU_BRANCH_STEP;
6256 8cbcb4fa aurel32
    if (unlikely(env->singlestep_enabled))
6257 8cbcb4fa aurel32
        ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
6258 3fc6c082 bellard
#if defined (DO_SINGLE_STEP) && 0
6259 9a64fbe4 bellard
    /* Single step trace mode */
6260 9a64fbe4 bellard
    msr_se = 1;
6261 9a64fbe4 bellard
#endif
6262 2e70f6ef pbrook
    num_insns = 0;
6263 2e70f6ef pbrook
    max_insns = tb->cflags & CF_COUNT_MASK;
6264 2e70f6ef pbrook
    if (max_insns == 0)
6265 2e70f6ef pbrook
        max_insns = CF_COUNT_MASK;
6266 2e70f6ef pbrook
6267 2e70f6ef pbrook
    gen_icount_start();
6268 9a64fbe4 bellard
    /* Set env in case of segfault during code fetch */
6269 e1833e1f j_mayer
    while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
6270 76a66253 j_mayer
        if (unlikely(env->nb_breakpoints > 0)) {
6271 76a66253 j_mayer
            for (j = 0; j < env->nb_breakpoints; j++) {
6272 ea4e754f bellard
                if (env->breakpoints[j] == ctx.nip) {
6273 5fafdf24 ths
                    gen_update_nip(&ctx, ctx.nip);
6274 ea4e754f bellard
                    gen_op_debug();
6275 ea4e754f bellard
                    break;
6276 ea4e754f bellard
                }
6277 ea4e754f bellard
            }
6278 ea4e754f bellard
        }
6279 76a66253 j_mayer
        if (unlikely(search_pc)) {
6280 79aceca5 bellard
            j = gen_opc_ptr - gen_opc_buf;
6281 79aceca5 bellard
            if (lj < j) {
6282 79aceca5 bellard
                lj++;
6283 79aceca5 bellard
                while (lj < j)
6284 79aceca5 bellard
                    gen_opc_instr_start[lj++] = 0;
6285 046d6672 bellard
                gen_opc_pc[lj] = ctx.nip;
6286 79aceca5 bellard
                gen_opc_instr_start[lj] = 1;
6287 2e70f6ef pbrook
                gen_opc_icount[lj] = num_insns;
6288 79aceca5 bellard
            }
6289 79aceca5 bellard
        }
6290 9fddaa0c bellard
#if defined PPC_DEBUG_DISAS
6291 9fddaa0c bellard
        if (loglevel & CPU_LOG_TB_IN_ASM) {
6292 79aceca5 bellard
            fprintf(logfile, "----------------\n");
6293 1b9eb036 j_mayer
            fprintf(logfile, "nip=" ADDRX " super=%d ir=%d\n",
6294 0411a972 j_mayer
                    ctx.nip, supervisor, (int)msr_ir);
6295 9a64fbe4 bellard
        }
6296 9a64fbe4 bellard
#endif
6297 2e70f6ef pbrook
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
6298 2e70f6ef pbrook
            gen_io_start();
6299 056401ea j_mayer
        if (unlikely(little_endian)) {
6300 056401ea j_mayer
            ctx.opcode = bswap32(ldl_code(ctx.nip));
6301 056401ea j_mayer
        } else {
6302 056401ea j_mayer
            ctx.opcode = ldl_code(ctx.nip);
6303 111bfab3 bellard
        }
6304 9fddaa0c bellard
#if defined PPC_DEBUG_DISAS
6305 9fddaa0c bellard
        if (loglevel & CPU_LOG_TB_IN_ASM) {
6306 111bfab3 bellard
            fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
6307 9a64fbe4 bellard
                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
6308 056401ea j_mayer
                    opc3(ctx.opcode), little_endian ? "little" : "big");
6309 79aceca5 bellard
        }
6310 79aceca5 bellard
#endif
6311 046d6672 bellard
        ctx.nip += 4;
6312 3fc6c082 bellard
        table = env->opcodes;
6313 2e70f6ef pbrook
        num_insns++;
6314 79aceca5 bellard
        handler = table[opc1(ctx.opcode)];
6315 79aceca5 bellard
        if (is_indirect_opcode(handler)) {
6316 79aceca5 bellard
            table = ind_table(handler);
6317 79aceca5 bellard
            handler = table[opc2(ctx.opcode)];
6318 79aceca5 bellard
            if (is_indirect_opcode(handler)) {
6319 79aceca5 bellard
                table = ind_table(handler);
6320 79aceca5 bellard
                handler = table[opc3(ctx.opcode)];
6321 79aceca5 bellard
            }
6322 79aceca5 bellard
        }
6323 79aceca5 bellard
        /* Is opcode *REALLY* valid ? */
6324 76a66253 j_mayer
        if (unlikely(handler->handler == &gen_invalid)) {
6325 4a057712 j_mayer
            if (loglevel != 0) {
6326 76a66253 j_mayer
                fprintf(logfile, "invalid/unsupported opcode: "
6327 6b542af7 j_mayer
                        "%02x - %02x - %02x (%08x) " ADDRX " %d\n",
6328 76a66253 j_mayer
                        opc1(ctx.opcode), opc2(ctx.opcode),
6329 0411a972 j_mayer
                        opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
6330 4b3686fa bellard
            } else {
6331 4b3686fa bellard
                printf("invalid/unsupported opcode: "
6332 6b542af7 j_mayer
                       "%02x - %02x - %02x (%08x) " ADDRX " %d\n",
6333 4b3686fa bellard
                       opc1(ctx.opcode), opc2(ctx.opcode),
6334 0411a972 j_mayer
                       opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
6335 4b3686fa bellard
            }
6336 76a66253 j_mayer
        } else {
6337 76a66253 j_mayer
            if (unlikely((ctx.opcode & handler->inval) != 0)) {
6338 4a057712 j_mayer
                if (loglevel != 0) {
6339 79aceca5 bellard
                    fprintf(logfile, "invalid bits: %08x for opcode: "
6340 6b542af7 j_mayer
                            "%02x - %02x - %02x (%08x) " ADDRX "\n",
6341 79aceca5 bellard
                            ctx.opcode & handler->inval, opc1(ctx.opcode),
6342 79aceca5 bellard
                            opc2(ctx.opcode), opc3(ctx.opcode),
6343 046d6672 bellard
                            ctx.opcode, ctx.nip - 4);
6344 9a64fbe4 bellard
                } else {
6345 9a64fbe4 bellard
                    printf("invalid bits: %08x for opcode: "
6346 6b542af7 j_mayer
                           "%02x - %02x - %02x (%08x) " ADDRX "\n",
6347 76a66253 j_mayer
                           ctx.opcode & handler->inval, opc1(ctx.opcode),
6348 76a66253 j_mayer
                           opc2(ctx.opcode), opc3(ctx.opcode),
6349 046d6672 bellard
                           ctx.opcode, ctx.nip - 4);
6350 76a66253 j_mayer
                }
6351 e1833e1f j_mayer
                GEN_EXCP_INVAL(ctxp);
6352 4b3686fa bellard
                break;
6353 79aceca5 bellard
            }
6354 79aceca5 bellard
        }
6355 4b3686fa bellard
        (*(handler->handler))(&ctx);
6356 76a66253 j_mayer
#if defined(DO_PPC_STATISTICS)
6357 76a66253 j_mayer
        handler->count++;
6358 76a66253 j_mayer
#endif
6359 9a64fbe4 bellard
        /* Check trace mode exceptions */
6360 8cbcb4fa aurel32
        if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
6361 8cbcb4fa aurel32
                     (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
6362 8cbcb4fa aurel32
                     ctx.exception != POWERPC_SYSCALL &&
6363 8cbcb4fa aurel32
                     ctx.exception != POWERPC_EXCP_TRAP &&
6364 8cbcb4fa aurel32
                     ctx.exception != POWERPC_EXCP_BRANCH)) {
6365 e1833e1f j_mayer
            GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
6366 d26bfc9a j_mayer
        } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
6367 2e70f6ef pbrook
                            (env->singlestep_enabled) ||
6368 2e70f6ef pbrook
                            num_insns >= max_insns)) {
6369 d26bfc9a j_mayer
            /* if we reach a page boundary or are single stepping, stop
6370 d26bfc9a j_mayer
             * generation
6371 d26bfc9a j_mayer
             */
6372 8dd4983c bellard
            break;
6373 76a66253 j_mayer
        }
6374 3fc6c082 bellard
#if defined (DO_SINGLE_STEP)
6375 3fc6c082 bellard
        break;
6376 3fc6c082 bellard
#endif
6377 3fc6c082 bellard
    }
6378 2e70f6ef pbrook
    if (tb->cflags & CF_LAST_IO)
6379 2e70f6ef pbrook
        gen_io_end();
6380 e1833e1f j_mayer
    if (ctx.exception == POWERPC_EXCP_NONE) {
6381 c1942362 bellard
        gen_goto_tb(&ctx, 0, ctx.nip);
6382 e1833e1f j_mayer
    } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
6383 8cbcb4fa aurel32
        if (unlikely(env->singlestep_enabled)) {
6384 8cbcb4fa aurel32
            gen_update_nip(&ctx, ctx.nip);
6385 8cbcb4fa aurel32
            gen_op_debug();
6386 8cbcb4fa aurel32
        }
6387 76a66253 j_mayer
        /* Generate the return instruction */
6388 57fec1fe bellard
        tcg_gen_exit_tb(0);
6389 9a64fbe4 bellard
    }
6390 2e70f6ef pbrook
    gen_icount_end(tb, num_insns);
6391 79aceca5 bellard
    *gen_opc_ptr = INDEX_op_end;
6392 76a66253 j_mayer
    if (unlikely(search_pc)) {
6393 9a64fbe4 bellard
        j = gen_opc_ptr - gen_opc_buf;
6394 9a64fbe4 bellard
        lj++;
6395 9a64fbe4 bellard
        while (lj <= j)
6396 9a64fbe4 bellard
            gen_opc_instr_start[lj++] = 0;
6397 9a64fbe4 bellard
    } else {
6398 046d6672 bellard
        tb->size = ctx.nip - pc_start;
6399 2e70f6ef pbrook
        tb->icount = num_insns;
6400 9a64fbe4 bellard
    }
6401 d9bce9d9 j_mayer
#if defined(DEBUG_DISAS)
6402 9fddaa0c bellard
    if (loglevel & CPU_LOG_TB_CPU) {
6403 9a64fbe4 bellard
        fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
6404 7fe48483 bellard
        cpu_dump_state(env, logfile, fprintf, 0);
6405 9fddaa0c bellard
    }
6406 9fddaa0c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6407 76a66253 j_mayer
        int flags;
6408 237c0af0 j_mayer
        flags = env->bfd_mach;
6409 056401ea j_mayer
        flags |= little_endian << 16;
6410 0fa85d43 bellard
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6411 76a66253 j_mayer
        target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
6412 79aceca5 bellard
        fprintf(logfile, "\n");
6413 9fddaa0c bellard
    }
6414 79aceca5 bellard
#endif
6415 79aceca5 bellard
}
6416 79aceca5 bellard
6417 2cfc5f17 ths
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6418 79aceca5 bellard
{
6419 2cfc5f17 ths
    gen_intermediate_code_internal(env, tb, 0);
6420 79aceca5 bellard
}
6421 79aceca5 bellard
6422 2cfc5f17 ths
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6423 79aceca5 bellard
{
6424 2cfc5f17 ths
    gen_intermediate_code_internal(env, tb, 1);
6425 79aceca5 bellard
}
6426 d2856f1a aurel32
6427 d2856f1a aurel32
void gen_pc_load(CPUState *env, TranslationBlock *tb,
6428 d2856f1a aurel32
                unsigned long searched_pc, int pc_pos, void *puc)
6429 d2856f1a aurel32
{
6430 d2856f1a aurel32
    int type, c;
6431 d2856f1a aurel32
    /* for PPC, we need to look at the micro operation to get the
6432 d2856f1a aurel32
     * access type */
6433 d2856f1a aurel32
    env->nip = gen_opc_pc[pc_pos];
6434 d2856f1a aurel32
    c = gen_opc_buf[pc_pos];
6435 d2856f1a aurel32
    switch(c) {
6436 d2856f1a aurel32
#if defined(CONFIG_USER_ONLY)
6437 d2856f1a aurel32
#define CASE3(op)\
6438 d2856f1a aurel32
    case INDEX_op_ ## op ## _raw
6439 d2856f1a aurel32
#else
6440 d2856f1a aurel32
#define CASE3(op)\
6441 d2856f1a aurel32
    case INDEX_op_ ## op ## _user:\
6442 d2856f1a aurel32
    case INDEX_op_ ## op ## _kernel:\
6443 d2856f1a aurel32
    case INDEX_op_ ## op ## _hypv
6444 d2856f1a aurel32
#endif
6445 d2856f1a aurel32
6446 d2856f1a aurel32
    CASE3(stfd):
6447 d2856f1a aurel32
    CASE3(stfs):
6448 d2856f1a aurel32
    CASE3(lfd):
6449 d2856f1a aurel32
    CASE3(lfs):
6450 d2856f1a aurel32
        type = ACCESS_FLOAT;
6451 d2856f1a aurel32
        break;
6452 d2856f1a aurel32
    CASE3(lwarx):
6453 d2856f1a aurel32
        type = ACCESS_RES;
6454 d2856f1a aurel32
        break;
6455 d2856f1a aurel32
    CASE3(stwcx):
6456 d2856f1a aurel32
        type = ACCESS_RES;
6457 d2856f1a aurel32
        break;
6458 d2856f1a aurel32
    CASE3(eciwx):
6459 d2856f1a aurel32
    CASE3(ecowx):
6460 d2856f1a aurel32
        type = ACCESS_EXT;
6461 d2856f1a aurel32
        break;
6462 d2856f1a aurel32
    default:
6463 d2856f1a aurel32
        type = ACCESS_INT;
6464 d2856f1a aurel32
        break;
6465 d2856f1a aurel32
    }
6466 d2856f1a aurel32
    env->access_type = type;
6467 d2856f1a aurel32
}