Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 894efddb

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

5815 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
5816 0487d6a8 j_mayer
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
5817 0487d6a8 j_mayer
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
5818 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
5819 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
5820 0487d6a8 j_mayer
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
5821 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
5822 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
5823 0487d6a8 j_mayer
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
5824 0487d6a8 j_mayer
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
5825 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
5826 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
5827 0487d6a8 j_mayer
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
5828 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
5829 0487d6a8 j_mayer

5830 0487d6a8 j_mayer
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
5831 0487d6a8 j_mayer
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
5832 0487d6a8 j_mayer
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
5833 0487d6a8 j_mayer
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
5834 0487d6a8 j_mayer
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
5835 0487d6a8 j_mayer
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
5836 0487d6a8 j_mayer

5837 0487d6a8 j_mayer
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
5838 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
5839 0487d6a8 j_mayer
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
5840 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
5841 0487d6a8 j_mayer
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
5842 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
5843 0487d6a8 j_mayer
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
5844 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
5845 0487d6a8 j_mayer
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
5846 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
5847 0487d6a8 j_mayer
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
5848 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
5849 0487d6a8 j_mayer

5850 0487d6a8 j_mayer
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
5851 0487d6a8 j_mayer
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
5852 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
5853 0487d6a8 j_mayer
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
5854 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
5855 0487d6a8 j_mayer

5856 0487d6a8 j_mayer
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
5857 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
5858 0487d6a8 j_mayer
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
5859 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
5860 0487d6a8 j_mayer
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
5861 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
5862 0487d6a8 j_mayer
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
5863 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
5864 0487d6a8 j_mayer
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
5865 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
5866 0487d6a8 j_mayer
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
5867 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
5868 0487d6a8 j_mayer

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