Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ daf4f96e

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

5769 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
5770 0487d6a8 j_mayer
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
5771 0487d6a8 j_mayer
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
5772 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
5773 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
5774 0487d6a8 j_mayer
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
5775 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
5776 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
5777 0487d6a8 j_mayer
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
5778 0487d6a8 j_mayer
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
5779 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
5780 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
5781 0487d6a8 j_mayer
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
5782 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
5783 0487d6a8 j_mayer

5784 0487d6a8 j_mayer
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
5785 0487d6a8 j_mayer
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
5786 0487d6a8 j_mayer
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
5787 0487d6a8 j_mayer
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
5788 0487d6a8 j_mayer
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
5789 0487d6a8 j_mayer
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
5790 0487d6a8 j_mayer

5791 0487d6a8 j_mayer
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
5792 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
5793 0487d6a8 j_mayer
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
5794 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
5795 0487d6a8 j_mayer
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
5796 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
5797 0487d6a8 j_mayer
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
5798 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
5799 0487d6a8 j_mayer
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
5800 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
5801 0487d6a8 j_mayer
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
5802 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
5803 0487d6a8 j_mayer

5804 0487d6a8 j_mayer
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
5805 0487d6a8 j_mayer
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
5806 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
5807 0487d6a8 j_mayer
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
5808 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
5809 0487d6a8 j_mayer

5810 0487d6a8 j_mayer
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
5811 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
5812 0487d6a8 j_mayer
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
5813 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
5814 0487d6a8 j_mayer
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
5815 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
5816 0487d6a8 j_mayer
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
5817 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
5818 0487d6a8 j_mayer
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
5819 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
5820 0487d6a8 j_mayer
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
5821 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
5822 0487d6a8 j_mayer

5823 0487d6a8 j_mayer
GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
5824 0487d6a8 j_mayer
GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
5825 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
5826 0487d6a8 j_mayer
GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
5827 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
5828 0487d6a8 j_mayer
#endif
5829 0487d6a8 j_mayer
5830 0487d6a8 j_mayer
/***                      SPE floating-point extension                     ***/
5831 0487d6a8 j_mayer
#define GEN_SPEFPUOP_CONV(name)                                               \
5832 0487d6a8 j_mayer
static inline void gen_##name (DisasContext *ctx)                             \
5833 0487d6a8 j_mayer
{                                                                             \
5834 0487d6a8 j_mayer
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
5835 0487d6a8 j_mayer
    gen_op_##name();                                                          \
5836 0487d6a8 j_mayer
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5837 0487d6a8 j_mayer
}
5838 0487d6a8 j_mayer
5839 0487d6a8 j_mayer
/* Single precision floating-point vectors operations */
5840 0487d6a8 j_mayer
/* Arithmetic */
5841 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evfsadd);
5842 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evfssub);
5843 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evfsmul);
5844 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evfsdiv);
5845 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evfsabs);
5846 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evfsnabs);
5847 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evfsneg);
5848 0487d6a8 j_mayer
/* Conversion */
5849 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfscfui);
5850 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfscfsi);
5851 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfscfuf);
5852 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfscfsf);
5853 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfsctui);
5854 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfsctsi);
5855 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfsctuf);
5856 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfsctsf);
5857 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfsctuiz);
5858 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfsctsiz);
5859 0487d6a8 j_mayer
/* Comparison */
5860 0487d6a8 j_mayer
GEN_SPEOP_COMP(evfscmpgt);
5861 0487d6a8 j_mayer
GEN_SPEOP_COMP(evfscmplt);
5862 0487d6a8 j_mayer
GEN_SPEOP_COMP(evfscmpeq);
5863 0487d6a8 j_mayer
GEN_SPEOP_COMP(evfststgt);
5864 0487d6a8 j_mayer
GEN_SPEOP_COMP(evfststlt);
5865 0487d6a8 j_mayer
GEN_SPEOP_COMP(evfststeq);
5866 0487d6a8 j_mayer
5867 0487d6a8 j_mayer
/* Opcodes definitions */
5868 0487d6a8 j_mayer
GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5869 0487d6a8 j_mayer
GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
5870 0487d6a8 j_mayer
GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
5871 0487d6a8 j_mayer
GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
5872 0487d6a8 j_mayer
GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
5873 0487d6a8 j_mayer
GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
5874 0487d6a8 j_mayer
GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
5875 0487d6a8 j_mayer
GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
5876 0487d6a8 j_mayer
GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
5877 0487d6a8 j_mayer
GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
5878 0487d6a8 j_mayer
GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
5879 0487d6a8 j_mayer
GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
5880 0487d6a8 j_mayer
GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
5881 0487d6a8 j_mayer
GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
5882 0487d6a8 j_mayer
5883 0487d6a8 j_mayer
/* Single precision floating-point operations */
5884 0487d6a8 j_mayer
/* Arithmetic */
5885 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efsadd);
5886 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efssub);
5887 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efsmul);
5888 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efsdiv);
5889 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(efsabs);
5890 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(efsnabs);
5891 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(efsneg);
5892 0487d6a8 j_mayer
/* Conversion */
5893 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efscfui);
5894 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efscfsi);
5895 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efscfuf);
5896 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efscfsf);
5897 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efsctui);
5898 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efsctsi);
5899 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efsctuf);
5900 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efsctsf);
5901 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efsctuiz);
5902 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efsctsiz);
5903 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efscfd);
5904 0487d6a8 j_mayer
/* Comparison */
5905 0487d6a8 j_mayer
GEN_SPEOP_COMP(efscmpgt);
5906 0487d6a8 j_mayer
GEN_SPEOP_COMP(efscmplt);
5907 0487d6a8 j_mayer
GEN_SPEOP_COMP(efscmpeq);
5908 0487d6a8 j_mayer
GEN_SPEOP_COMP(efststgt);
5909 0487d6a8 j_mayer
GEN_SPEOP_COMP(efststlt);
5910 0487d6a8 j_mayer
GEN_SPEOP_COMP(efststeq);
5911 0487d6a8 j_mayer
5912 0487d6a8 j_mayer
/* Opcodes definitions */
5913 0487d6a8 j_mayer
GEN_SPE(efsadd,         efssub,        0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
5914 0487d6a8 j_mayer
GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
5915 0487d6a8 j_mayer
GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
5916 0487d6a8 j_mayer
GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
5917 0487d6a8 j_mayer
GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
5918 0487d6a8 j_mayer
GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
5919 0487d6a8 j_mayer
GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
5920 0487d6a8 j_mayer
GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
5921 0487d6a8 j_mayer
GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
5922 0487d6a8 j_mayer
GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
5923 0487d6a8 j_mayer
GEN_SPE(efsctuiz,       efsctsiz,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
5924 0487d6a8 j_mayer
GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
5925 0487d6a8 j_mayer
GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
5926 0487d6a8 j_mayer
5927 0487d6a8 j_mayer
/* Double precision floating-point operations */
5928 0487d6a8 j_mayer
/* Arithmetic */
5929 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efdadd);
5930 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efdsub);
5931 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efdmul);
5932 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efddiv);
5933 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(efdabs);
5934 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(efdnabs);
5935 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(efdneg);
5936 0487d6a8 j_mayer
/* Conversion */
5937 0487d6a8 j_mayer
5938 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfui);
5939 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfsi);
5940 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfuf);
5941 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfsf);
5942 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctui);
5943 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctsi);
5944 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctuf);
5945 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctsf);
5946 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctuiz);
5947 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctsiz);
5948 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfs);
5949 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfuid);
5950 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfsid);
5951 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctuidz);
5952 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctsidz);
5953 0487d6a8 j_mayer
/* Comparison */
5954 0487d6a8 j_mayer
GEN_SPEOP_COMP(efdcmpgt);
5955 0487d6a8 j_mayer
GEN_SPEOP_COMP(efdcmplt);
5956 0487d6a8 j_mayer
GEN_SPEOP_COMP(efdcmpeq);
5957 0487d6a8 j_mayer
GEN_SPEOP_COMP(efdtstgt);
5958 0487d6a8 j_mayer
GEN_SPEOP_COMP(efdtstlt);
5959 0487d6a8 j_mayer
GEN_SPEOP_COMP(efdtsteq);
5960 0487d6a8 j_mayer
5961 0487d6a8 j_mayer
/* Opcodes definitions */
5962 0487d6a8 j_mayer
GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
5963 0487d6a8 j_mayer
GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
5964 0487d6a8 j_mayer
GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
5965 0487d6a8 j_mayer
GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
5966 0487d6a8 j_mayer
GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
5967 0487d6a8 j_mayer
GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
5968 0487d6a8 j_mayer
GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
5969 0487d6a8 j_mayer
GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
5970 0487d6a8 j_mayer
GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
5971 0487d6a8 j_mayer
GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
5972 0487d6a8 j_mayer
GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
5973 0487d6a8 j_mayer
GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
5974 0487d6a8 j_mayer
GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
5975 0487d6a8 j_mayer
GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
5976 0487d6a8 j_mayer
GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
5977 0487d6a8 j_mayer
GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
5978 0487d6a8 j_mayer
#endif
5979 0487d6a8 j_mayer
5980 79aceca5 bellard
/* End opcode list */
5981 79aceca5 bellard
GEN_OPCODE_MARK(end);
5982 79aceca5 bellard
5983 3fc6c082 bellard
#include "translate_init.c"
5984 79aceca5 bellard
5985 9a64fbe4 bellard
/*****************************************************************************/
5986 3fc6c082 bellard
/* Misc PowerPC helpers */
5987 76a66253 j_mayer
static inline uint32_t load_xer (CPUState *env)
5988 76a66253 j_mayer
{
5989 76a66253 j_mayer
    return (xer_so << XER_SO) |
5990 76a66253 j_mayer
        (xer_ov << XER_OV) |
5991 76a66253 j_mayer
        (xer_ca << XER_CA) |
5992 76a66253 j_mayer
        (xer_bc << XER_BC) |
5993 76a66253 j_mayer
        (xer_cmp << XER_CMP);
5994 76a66253 j_mayer
}
5995 76a66253 j_mayer
5996 36081602 j_mayer
void cpu_dump_state (CPUState *env, FILE *f,
5997 36081602 j_mayer
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5998 36081602 j_mayer
                     int flags)
5999 79aceca5 bellard
{
6000 3fc6c082 bellard
#if defined(TARGET_PPC64) || 1
6001 3fc6c082 bellard
#define FILL ""
6002 3fc6c082 bellard
#define RGPL  4
6003 3fc6c082 bellard
#define RFPL  4
6004 3fc6c082 bellard
#else
6005 3fc6c082 bellard
#define FILL "        "
6006 3fc6c082 bellard
#define RGPL  8
6007 3fc6c082 bellard
#define RFPL  4
6008 3fc6c082 bellard
#endif
6009 3fc6c082 bellard
6010 79aceca5 bellard
    int i;
6011 79aceca5 bellard
6012 1b9eb036 j_mayer
    cpu_fprintf(f, "NIP " ADDRX " LR " ADDRX " CTR " ADDRX "\n",
6013 3fc6c082 bellard
                env->nip, env->lr, env->ctr);
6014 d9bce9d9 j_mayer
    cpu_fprintf(f, "MSR " REGX FILL " XER %08x      "
6015 d9bce9d9 j_mayer
#if !defined(NO_TIMER_DUMP)
6016 d9bce9d9 j_mayer
                "TB %08x %08x "
6017 76a66253 j_mayer
#if !defined(CONFIG_USER_ONLY)
6018 76a66253 j_mayer
                "DECR %08x"
6019 76a66253 j_mayer
#endif
6020 d9bce9d9 j_mayer
#endif
6021 76a66253 j_mayer
                "\n",
6022 d9bce9d9 j_mayer
                do_load_msr(env), load_xer(env)
6023 d9bce9d9 j_mayer
#if !defined(NO_TIMER_DUMP)
6024 d9bce9d9 j_mayer
                , cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
6025 76a66253 j_mayer
#if !defined(CONFIG_USER_ONLY)
6026 76a66253 j_mayer
                , cpu_ppc_load_decr(env)
6027 76a66253 j_mayer
#endif
6028 d9bce9d9 j_mayer
#endif
6029 76a66253 j_mayer
                );
6030 76a66253 j_mayer
    for (i = 0; i < 32; i++) {
6031 3fc6c082 bellard
        if ((i & (RGPL - 1)) == 0)
6032 3fc6c082 bellard
            cpu_fprintf(f, "GPR%02d", i);
6033 a750fc0b j_mayer
        cpu_fprintf(f, " " REGX, (target_ulong)env->gpr[i]);
6034 3fc6c082 bellard
        if ((i & (RGPL - 1)) == (RGPL - 1))
6035 7fe48483 bellard
            cpu_fprintf(f, "\n");
6036 76a66253 j_mayer
    }
6037 3fc6c082 bellard
    cpu_fprintf(f, "CR ");
6038 76a66253 j_mayer
    for (i = 0; i < 8; i++)
6039 7fe48483 bellard
        cpu_fprintf(f, "%01x", env->crf[i]);
6040 7fe48483 bellard
    cpu_fprintf(f, "  [");
6041 76a66253 j_mayer
    for (i = 0; i < 8; i++) {
6042 76a66253 j_mayer
        char a = '-';
6043 76a66253 j_mayer
        if (env->crf[i] & 0x08)
6044 76a66253 j_mayer
            a = 'L';
6045 76a66253 j_mayer
        else if (env->crf[i] & 0x04)
6046 76a66253 j_mayer
            a = 'G';
6047 76a66253 j_mayer
        else if (env->crf[i] & 0x02)
6048 76a66253 j_mayer
            a = 'E';
6049 7fe48483 bellard
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
6050 76a66253 j_mayer
    }
6051 3fc6c082 bellard
    cpu_fprintf(f, " ]             " FILL "RES " REGX "\n", env->reserve);
6052 3fc6c082 bellard
    for (i = 0; i < 32; i++) {
6053 3fc6c082 bellard
        if ((i & (RFPL - 1)) == 0)
6054 3fc6c082 bellard
            cpu_fprintf(f, "FPR%02d", i);
6055 26a76461 bellard
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
6056 3fc6c082 bellard
        if ((i & (RFPL - 1)) == (RFPL - 1))
6057 7fe48483 bellard
            cpu_fprintf(f, "\n");
6058 79aceca5 bellard
    }
6059 3fc6c082 bellard
    cpu_fprintf(f, "SRR0 " REGX " SRR1 " REGX "         " FILL FILL FILL
6060 3fc6c082 bellard
                "SDR1 " REGX "\n",
6061 3fc6c082 bellard
                env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
6062 79aceca5 bellard
6063 3fc6c082 bellard
#undef RGPL
6064 3fc6c082 bellard
#undef RFPL
6065 3fc6c082 bellard
#undef FILL
6066 79aceca5 bellard
}
6067 79aceca5 bellard
6068 76a66253 j_mayer
void cpu_dump_statistics (CPUState *env, FILE*f,
6069 76a66253 j_mayer
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6070 76a66253 j_mayer
                          int flags)
6071 76a66253 j_mayer
{
6072 76a66253 j_mayer
#if defined(DO_PPC_STATISTICS)
6073 76a66253 j_mayer
    opc_handler_t **t1, **t2, **t3, *handler;
6074 76a66253 j_mayer
    int op1, op2, op3;
6075 76a66253 j_mayer
6076 76a66253 j_mayer
    t1 = env->opcodes;
6077 76a66253 j_mayer
    for (op1 = 0; op1 < 64; op1++) {
6078 76a66253 j_mayer
        handler = t1[op1];
6079 76a66253 j_mayer
        if (is_indirect_opcode(handler)) {
6080 76a66253 j_mayer
            t2 = ind_table(handler);
6081 76a66253 j_mayer
            for (op2 = 0; op2 < 32; op2++) {
6082 76a66253 j_mayer
                handler = t2[op2];
6083 76a66253 j_mayer
                if (is_indirect_opcode(handler)) {
6084 76a66253 j_mayer
                    t3 = ind_table(handler);
6085 76a66253 j_mayer
                    for (op3 = 0; op3 < 32; op3++) {
6086 76a66253 j_mayer
                        handler = t3[op3];
6087 76a66253 j_mayer
                        if (handler->count == 0)
6088 76a66253 j_mayer
                            continue;
6089 76a66253 j_mayer
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
6090 76a66253 j_mayer
                                    "%016llx %lld\n",
6091 76a66253 j_mayer
                                    op1, op2, op3, op1, (op3 << 5) | op2,
6092 76a66253 j_mayer
                                    handler->oname,
6093 76a66253 j_mayer
                                    handler->count, handler->count);
6094 76a66253 j_mayer
                    }
6095 76a66253 j_mayer
                } else {
6096 76a66253 j_mayer
                    if (handler->count == 0)
6097 76a66253 j_mayer
                        continue;
6098 76a66253 j_mayer
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
6099 76a66253 j_mayer
                                "%016llx %lld\n",
6100 76a66253 j_mayer
                                op1, op2, op1, op2, handler->oname,
6101 76a66253 j_mayer
                                handler->count, handler->count);
6102 76a66253 j_mayer
                }
6103 76a66253 j_mayer
            }
6104 76a66253 j_mayer
        } else {
6105 76a66253 j_mayer
            if (handler->count == 0)
6106 76a66253 j_mayer
                continue;
6107 76a66253 j_mayer
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
6108 76a66253 j_mayer
                        op1, op1, handler->oname,
6109 76a66253 j_mayer
                        handler->count, handler->count);
6110 76a66253 j_mayer
        }
6111 76a66253 j_mayer
    }
6112 76a66253 j_mayer
#endif
6113 76a66253 j_mayer
}
6114 76a66253 j_mayer
6115 9a64fbe4 bellard
/*****************************************************************************/
6116 0487d6a8 j_mayer
static inline int gen_intermediate_code_internal (CPUState *env,
6117 0487d6a8 j_mayer
                                                  TranslationBlock *tb,
6118 0487d6a8 j_mayer
                                                  int search_pc)
6119 79aceca5 bellard
{
6120 9fddaa0c bellard
    DisasContext ctx, *ctxp = &ctx;
6121 79aceca5 bellard
    opc_handler_t **table, *handler;
6122 0fa85d43 bellard
    target_ulong pc_start;
6123 79aceca5 bellard
    uint16_t *gen_opc_end;
6124 79aceca5 bellard
    int j, lj = -1;
6125 79aceca5 bellard
6126 79aceca5 bellard
    pc_start = tb->pc;
6127 79aceca5 bellard
    gen_opc_ptr = gen_opc_buf;
6128 79aceca5 bellard
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6129 79aceca5 bellard
    gen_opparam_ptr = gen_opparam_buf;
6130 c53be334 bellard
    nb_gen_labels = 0;
6131 046d6672 bellard
    ctx.nip = pc_start;
6132 79aceca5 bellard
    ctx.tb = tb;
6133 e1833e1f j_mayer
    ctx.exception = POWERPC_EXCP_NONE;
6134 3fc6c082 bellard
    ctx.spr_cb = env->spr_cb;
6135 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
6136 111bfab3 bellard
    ctx.mem_idx = msr_le;
6137 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
6138 d9bce9d9 j_mayer
    ctx.mem_idx |= msr_sf << 1;
6139 d9bce9d9 j_mayer
#endif
6140 9a64fbe4 bellard
#else
6141 be147d08 j_mayer
#if defined(TARGET_PPC64H)
6142 be147d08 j_mayer
    if (msr_pr == 0 && msr_hv == 1)
6143 be147d08 j_mayer
        ctx.supervisor = 2;
6144 be147d08 j_mayer
    else
6145 be147d08 j_mayer
#endif
6146 be147d08 j_mayer
        ctx.supervisor = 1 - msr_pr;
6147 111bfab3 bellard
    ctx.mem_idx = ((1 - msr_pr) << 1) | msr_le;
6148 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
6149 d9bce9d9 j_mayer
    ctx.mem_idx |= msr_sf << 2;
6150 d9bce9d9 j_mayer
#endif
6151 d9bce9d9 j_mayer
#endif
6152 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
6153 d9bce9d9 j_mayer
    ctx.sf_mode = msr_sf;
6154 9a64fbe4 bellard
#endif
6155 3cc62370 bellard
    ctx.fpu_enabled = msr_fp;
6156 35cdaad6 j_mayer
#if defined(TARGET_PPCEMB)
6157 0487d6a8 j_mayer
    ctx.spe_enabled = msr_spe;
6158 0487d6a8 j_mayer
#endif
6159 ea4e754f bellard
    ctx.singlestep_enabled = env->singlestep_enabled;
6160 3fc6c082 bellard
#if defined (DO_SINGLE_STEP) && 0
6161 9a64fbe4 bellard
    /* Single step trace mode */
6162 9a64fbe4 bellard
    msr_se = 1;
6163 9a64fbe4 bellard
#endif
6164 9a64fbe4 bellard
    /* Set env in case of segfault during code fetch */
6165 e1833e1f j_mayer
    while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
6166 76a66253 j_mayer
        if (unlikely(env->nb_breakpoints > 0)) {
6167 76a66253 j_mayer
            for (j = 0; j < env->nb_breakpoints; j++) {
6168 ea4e754f bellard
                if (env->breakpoints[j] == ctx.nip) {
6169 5fafdf24 ths
                    gen_update_nip(&ctx, ctx.nip);
6170 ea4e754f bellard
                    gen_op_debug();
6171 ea4e754f bellard
                    break;
6172 ea4e754f bellard
                }
6173 ea4e754f bellard
            }
6174 ea4e754f bellard
        }
6175 76a66253 j_mayer
        if (unlikely(search_pc)) {
6176 79aceca5 bellard
            j = gen_opc_ptr - gen_opc_buf;
6177 79aceca5 bellard
            if (lj < j) {
6178 79aceca5 bellard
                lj++;
6179 79aceca5 bellard
                while (lj < j)
6180 79aceca5 bellard
                    gen_opc_instr_start[lj++] = 0;
6181 046d6672 bellard
                gen_opc_pc[lj] = ctx.nip;
6182 79aceca5 bellard
                gen_opc_instr_start[lj] = 1;
6183 79aceca5 bellard
            }
6184 79aceca5 bellard
        }
6185 9fddaa0c bellard
#if defined PPC_DEBUG_DISAS
6186 9fddaa0c bellard
        if (loglevel & CPU_LOG_TB_IN_ASM) {
6187 79aceca5 bellard
            fprintf(logfile, "----------------\n");
6188 1b9eb036 j_mayer
            fprintf(logfile, "nip=" ADDRX " super=%d ir=%d\n",
6189 9a64fbe4 bellard
                    ctx.nip, 1 - msr_pr, msr_ir);
6190 9a64fbe4 bellard
        }
6191 9a64fbe4 bellard
#endif
6192 0fa85d43 bellard
        ctx.opcode = ldl_code(ctx.nip);
6193 111bfab3 bellard
        if (msr_le) {
6194 111bfab3 bellard
            ctx.opcode = ((ctx.opcode & 0xFF000000) >> 24) |
6195 111bfab3 bellard
                ((ctx.opcode & 0x00FF0000) >> 8) |
6196 111bfab3 bellard
                ((ctx.opcode & 0x0000FF00) << 8) |
6197 111bfab3 bellard
                ((ctx.opcode & 0x000000FF) << 24);
6198 111bfab3 bellard
        }
6199 9fddaa0c bellard
#if defined PPC_DEBUG_DISAS
6200 9fddaa0c bellard
        if (loglevel & CPU_LOG_TB_IN_ASM) {
6201 111bfab3 bellard
            fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
6202 9a64fbe4 bellard
                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
6203 111bfab3 bellard
                    opc3(ctx.opcode), msr_le ? "little" : "big");
6204 79aceca5 bellard
        }
6205 79aceca5 bellard
#endif
6206 046d6672 bellard
        ctx.nip += 4;
6207 3fc6c082 bellard
        table = env->opcodes;
6208 79aceca5 bellard
        handler = table[opc1(ctx.opcode)];
6209 79aceca5 bellard
        if (is_indirect_opcode(handler)) {
6210 79aceca5 bellard
            table = ind_table(handler);
6211 79aceca5 bellard
            handler = table[opc2(ctx.opcode)];
6212 79aceca5 bellard
            if (is_indirect_opcode(handler)) {
6213 79aceca5 bellard
                table = ind_table(handler);
6214 79aceca5 bellard
                handler = table[opc3(ctx.opcode)];
6215 79aceca5 bellard
            }
6216 79aceca5 bellard
        }
6217 79aceca5 bellard
        /* Is opcode *REALLY* valid ? */
6218 76a66253 j_mayer
        if (unlikely(handler->handler == &gen_invalid)) {
6219 4a057712 j_mayer
            if (loglevel != 0) {
6220 76a66253 j_mayer
                fprintf(logfile, "invalid/unsupported opcode: "
6221 1b9eb036 j_mayer
                        "%02x - %02x - %02x (%08x) 0x" ADDRX " %d\n",
6222 76a66253 j_mayer
                        opc1(ctx.opcode), opc2(ctx.opcode),
6223 4b3686fa bellard
                        opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
6224 4b3686fa bellard
            } else {
6225 4b3686fa bellard
                printf("invalid/unsupported opcode: "
6226 1b9eb036 j_mayer
                       "%02x - %02x - %02x (%08x) 0x" ADDRX " %d\n",
6227 4b3686fa bellard
                       opc1(ctx.opcode), opc2(ctx.opcode),
6228 4b3686fa bellard
                       opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir);
6229 4b3686fa bellard
            }
6230 76a66253 j_mayer
        } else {
6231 76a66253 j_mayer
            if (unlikely((ctx.opcode & handler->inval) != 0)) {
6232 4a057712 j_mayer
                if (loglevel != 0) {
6233 79aceca5 bellard
                    fprintf(logfile, "invalid bits: %08x for opcode: "
6234 e1833e1f j_mayer
                            "%02x - %02x - %02x (%08x) 0x" ADDRX "\n",
6235 79aceca5 bellard
                            ctx.opcode & handler->inval, opc1(ctx.opcode),
6236 79aceca5 bellard
                            opc2(ctx.opcode), opc3(ctx.opcode),
6237 046d6672 bellard
                            ctx.opcode, ctx.nip - 4);
6238 9a64fbe4 bellard
                } else {
6239 9a64fbe4 bellard
                    printf("invalid bits: %08x for opcode: "
6240 e1833e1f j_mayer
                           "%02x - %02x - %02x (%08x) 0x" ADDRX "\n",
6241 76a66253 j_mayer
                           ctx.opcode & handler->inval, opc1(ctx.opcode),
6242 76a66253 j_mayer
                           opc2(ctx.opcode), opc3(ctx.opcode),
6243 046d6672 bellard
                           ctx.opcode, ctx.nip - 4);
6244 76a66253 j_mayer
                }
6245 e1833e1f j_mayer
                GEN_EXCP_INVAL(ctxp);
6246 4b3686fa bellard
                break;
6247 79aceca5 bellard
            }
6248 79aceca5 bellard
        }
6249 4b3686fa bellard
        (*(handler->handler))(&ctx);
6250 76a66253 j_mayer
#if defined(DO_PPC_STATISTICS)
6251 76a66253 j_mayer
        handler->count++;
6252 76a66253 j_mayer
#endif
6253 9a64fbe4 bellard
        /* Check trace mode exceptions */
6254 08e46e54 j_mayer
#if 0 // XXX: buggy on embedded PowerPC
6255 e1833e1f j_mayer
        if (unlikely((msr_be && ctx.exception == POWERPC_EXCP_BRANCH) ||
6256 76a66253 j_mayer
                     /* Check in single step trace mode
6257 76a66253 j_mayer
                      * we need to stop except if:
6258 76a66253 j_mayer
                      * - rfi, trap or syscall
6259 76a66253 j_mayer
                      * - first instruction of an exception handler
6260 76a66253 j_mayer
                      */
6261 76a66253 j_mayer
                     (msr_se && (ctx.nip < 0x100 ||
6262 76a66253 j_mayer
                                 ctx.nip > 0xF00 ||
6263 76a66253 j_mayer
                                 (ctx.nip & 0xFC) != 0x04) &&
6264 e1833e1f j_mayer
#if defined(CONFIG_USER_ONLY)
6265 e1833e1f j_mayer
                      ctx.exception != POWERPC_EXCP_SYSCALL_USER &&
6266 e1833e1f j_mayer
#else
6267 e1833e1f j_mayer
                      ctx.exception != POWERPC_EXCP_SYSCALL &&
6268 e1833e1f j_mayer
#endif
6269 e1833e1f j_mayer
                      ctx.exception != POWERPC_EXCP_TRAP))) {
6270 e1833e1f j_mayer
            GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
6271 9a64fbe4 bellard
        }
6272 08e46e54 j_mayer
#endif
6273 ea4e754f bellard
        /* if we reach a page boundary or are single stepping, stop
6274 ea4e754f bellard
         * generation
6275 ea4e754f bellard
         */
6276 76a66253 j_mayer
        if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
6277 76a66253 j_mayer
                     (env->singlestep_enabled))) {
6278 8dd4983c bellard
            break;
6279 76a66253 j_mayer
        }
6280 3fc6c082 bellard
#if defined (DO_SINGLE_STEP)
6281 3fc6c082 bellard
        break;
6282 3fc6c082 bellard
#endif
6283 3fc6c082 bellard
    }
6284 e1833e1f j_mayer
    if (ctx.exception == POWERPC_EXCP_NONE) {
6285 c1942362 bellard
        gen_goto_tb(&ctx, 0, ctx.nip);
6286 e1833e1f j_mayer
    } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
6287 76a66253 j_mayer
        gen_op_reset_T0();
6288 76a66253 j_mayer
        /* Generate the return instruction */
6289 76a66253 j_mayer
        gen_op_exit_tb();
6290 9a64fbe4 bellard
    }
6291 79aceca5 bellard
    *gen_opc_ptr = INDEX_op_end;
6292 76a66253 j_mayer
    if (unlikely(search_pc)) {
6293 9a64fbe4 bellard
        j = gen_opc_ptr - gen_opc_buf;
6294 9a64fbe4 bellard
        lj++;
6295 9a64fbe4 bellard
        while (lj <= j)
6296 9a64fbe4 bellard
            gen_opc_instr_start[lj++] = 0;
6297 9a64fbe4 bellard
    } else {
6298 046d6672 bellard
        tb->size = ctx.nip - pc_start;
6299 9a64fbe4 bellard
    }
6300 d9bce9d9 j_mayer
#if defined(DEBUG_DISAS)
6301 9fddaa0c bellard
    if (loglevel & CPU_LOG_TB_CPU) {
6302 9a64fbe4 bellard
        fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
6303 7fe48483 bellard
        cpu_dump_state(env, logfile, fprintf, 0);
6304 9fddaa0c bellard
    }
6305 9fddaa0c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6306 76a66253 j_mayer
        int flags;
6307 237c0af0 j_mayer
        flags = env->bfd_mach;
6308 237c0af0 j_mayer
        flags |= msr_le << 16;
6309 0fa85d43 bellard
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6310 76a66253 j_mayer
        target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
6311 79aceca5 bellard
        fprintf(logfile, "\n");
6312 9fddaa0c bellard
    }
6313 9fddaa0c bellard
    if (loglevel & CPU_LOG_TB_OP) {
6314 79aceca5 bellard
        fprintf(logfile, "OP:\n");
6315 79aceca5 bellard
        dump_ops(gen_opc_buf, gen_opparam_buf);
6316 79aceca5 bellard
        fprintf(logfile, "\n");
6317 79aceca5 bellard
    }
6318 79aceca5 bellard
#endif
6319 79aceca5 bellard
    return 0;
6320 79aceca5 bellard
}
6321 79aceca5 bellard
6322 9a64fbe4 bellard
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6323 79aceca5 bellard
{
6324 79aceca5 bellard
    return gen_intermediate_code_internal(env, tb, 0);
6325 79aceca5 bellard
}
6326 79aceca5 bellard
6327 9a64fbe4 bellard
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6328 79aceca5 bellard
{
6329 79aceca5 bellard
    return gen_intermediate_code_internal(env, tb, 1);
6330 79aceca5 bellard
}