Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ f9fdea6b

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

6326 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
6327 0487d6a8 j_mayer
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
6328 0487d6a8 j_mayer
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
6329 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
6330 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
6331 0487d6a8 j_mayer
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
6332 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
6333 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
6334 0487d6a8 j_mayer
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
6335 0487d6a8 j_mayer
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
6336 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
6337 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
6338 0487d6a8 j_mayer
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
6339 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
6340 0487d6a8 j_mayer

6341 0487d6a8 j_mayer
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
6342 0487d6a8 j_mayer
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
6343 0487d6a8 j_mayer
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
6344 0487d6a8 j_mayer
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
6345 0487d6a8 j_mayer
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
6346 0487d6a8 j_mayer
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
6347 0487d6a8 j_mayer

6348 0487d6a8 j_mayer
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
6349 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
6350 0487d6a8 j_mayer
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
6351 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
6352 0487d6a8 j_mayer
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
6353 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
6354 0487d6a8 j_mayer
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
6355 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
6356 0487d6a8 j_mayer
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
6357 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
6358 0487d6a8 j_mayer
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
6359 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
6360 0487d6a8 j_mayer

6361 0487d6a8 j_mayer
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
6362 0487d6a8 j_mayer
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
6363 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
6364 0487d6a8 j_mayer
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
6365 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
6366 0487d6a8 j_mayer

6367 0487d6a8 j_mayer
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
6368 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
6369 0487d6a8 j_mayer
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
6370 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
6371 0487d6a8 j_mayer
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
6372 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
6373 0487d6a8 j_mayer
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
6374 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
6375 0487d6a8 j_mayer
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
6376 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
6377 0487d6a8 j_mayer
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
6378 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
6379 0487d6a8 j_mayer

6380 0487d6a8 j_mayer
GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
6381 0487d6a8 j_mayer
GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
6382 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
6383 0487d6a8 j_mayer
GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
6384 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
6385 0487d6a8 j_mayer
#endif
6386 0487d6a8 j_mayer
6387 0487d6a8 j_mayer
/***                      SPE floating-point extension                     ***/
6388 0487d6a8 j_mayer
#define GEN_SPEFPUOP_CONV(name)                                               \
6389 b068d6a7 j_mayer
static always_inline void gen_##name (DisasContext *ctx)                      \
6390 0487d6a8 j_mayer
{                                                                             \
6391 0487d6a8 j_mayer
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
6392 0487d6a8 j_mayer
    gen_op_##name();                                                          \
6393 0487d6a8 j_mayer
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
6394 0487d6a8 j_mayer
}
6395 0487d6a8 j_mayer
6396 0487d6a8 j_mayer
/* Single precision floating-point vectors operations */
6397 0487d6a8 j_mayer
/* Arithmetic */
6398 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evfsadd);
6399 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evfssub);
6400 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evfsmul);
6401 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evfsdiv);
6402 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evfsabs);
6403 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evfsnabs);
6404 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evfsneg);
6405 0487d6a8 j_mayer
/* Conversion */
6406 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfscfui);
6407 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfscfsi);
6408 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfscfuf);
6409 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfscfsf);
6410 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfsctui);
6411 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfsctsi);
6412 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfsctuf);
6413 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfsctsf);
6414 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfsctuiz);
6415 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(evfsctsiz);
6416 0487d6a8 j_mayer
/* Comparison */
6417 0487d6a8 j_mayer
GEN_SPEOP_COMP(evfscmpgt);
6418 0487d6a8 j_mayer
GEN_SPEOP_COMP(evfscmplt);
6419 0487d6a8 j_mayer
GEN_SPEOP_COMP(evfscmpeq);
6420 0487d6a8 j_mayer
GEN_SPEOP_COMP(evfststgt);
6421 0487d6a8 j_mayer
GEN_SPEOP_COMP(evfststlt);
6422 0487d6a8 j_mayer
GEN_SPEOP_COMP(evfststeq);
6423 0487d6a8 j_mayer
6424 0487d6a8 j_mayer
/* Opcodes definitions */
6425 0487d6a8 j_mayer
GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
6426 0487d6a8 j_mayer
GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
6427 0487d6a8 j_mayer
GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
6428 0487d6a8 j_mayer
GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
6429 0487d6a8 j_mayer
GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
6430 0487d6a8 j_mayer
GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
6431 0487d6a8 j_mayer
GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
6432 0487d6a8 j_mayer
GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
6433 0487d6a8 j_mayer
GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
6434 0487d6a8 j_mayer
GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
6435 0487d6a8 j_mayer
GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
6436 0487d6a8 j_mayer
GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
6437 0487d6a8 j_mayer
GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
6438 0487d6a8 j_mayer
GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
6439 0487d6a8 j_mayer
6440 0487d6a8 j_mayer
/* Single precision floating-point operations */
6441 0487d6a8 j_mayer
/* Arithmetic */
6442 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efsadd);
6443 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efssub);
6444 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efsmul);
6445 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efsdiv);
6446 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(efsabs);
6447 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(efsnabs);
6448 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(efsneg);
6449 0487d6a8 j_mayer
/* Conversion */
6450 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efscfui);
6451 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efscfsi);
6452 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efscfuf);
6453 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efscfsf);
6454 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efsctui);
6455 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efsctsi);
6456 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efsctuf);
6457 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efsctsf);
6458 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efsctuiz);
6459 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efsctsiz);
6460 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efscfd);
6461 0487d6a8 j_mayer
/* Comparison */
6462 0487d6a8 j_mayer
GEN_SPEOP_COMP(efscmpgt);
6463 0487d6a8 j_mayer
GEN_SPEOP_COMP(efscmplt);
6464 0487d6a8 j_mayer
GEN_SPEOP_COMP(efscmpeq);
6465 0487d6a8 j_mayer
GEN_SPEOP_COMP(efststgt);
6466 0487d6a8 j_mayer
GEN_SPEOP_COMP(efststlt);
6467 0487d6a8 j_mayer
GEN_SPEOP_COMP(efststeq);
6468 0487d6a8 j_mayer
6469 0487d6a8 j_mayer
/* Opcodes definitions */
6470 0487d6a8 j_mayer
GEN_SPE(efsadd,         efssub,        0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
6471 0487d6a8 j_mayer
GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
6472 0487d6a8 j_mayer
GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
6473 0487d6a8 j_mayer
GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
6474 0487d6a8 j_mayer
GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
6475 0487d6a8 j_mayer
GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
6476 0487d6a8 j_mayer
GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
6477 0487d6a8 j_mayer
GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
6478 0487d6a8 j_mayer
GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
6479 0487d6a8 j_mayer
GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
6480 0487d6a8 j_mayer
GEN_SPE(efsctuiz,       efsctsiz,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
6481 0487d6a8 j_mayer
GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
6482 0487d6a8 j_mayer
GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
6483 0487d6a8 j_mayer
6484 0487d6a8 j_mayer
/* Double precision floating-point operations */
6485 0487d6a8 j_mayer
/* Arithmetic */
6486 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efdadd);
6487 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efdsub);
6488 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efdmul);
6489 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(efddiv);
6490 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(efdabs);
6491 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(efdnabs);
6492 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(efdneg);
6493 0487d6a8 j_mayer
/* Conversion */
6494 0487d6a8 j_mayer
6495 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfui);
6496 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfsi);
6497 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfuf);
6498 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfsf);
6499 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctui);
6500 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctsi);
6501 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctuf);
6502 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctsf);
6503 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctuiz);
6504 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctsiz);
6505 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfs);
6506 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfuid);
6507 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdcfsid);
6508 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctuidz);
6509 0487d6a8 j_mayer
GEN_SPEFPUOP_CONV(efdctsidz);
6510 0487d6a8 j_mayer
/* Comparison */
6511 0487d6a8 j_mayer
GEN_SPEOP_COMP(efdcmpgt);
6512 0487d6a8 j_mayer
GEN_SPEOP_COMP(efdcmplt);
6513 0487d6a8 j_mayer
GEN_SPEOP_COMP(efdcmpeq);
6514 0487d6a8 j_mayer
GEN_SPEOP_COMP(efdtstgt);
6515 0487d6a8 j_mayer
GEN_SPEOP_COMP(efdtstlt);
6516 0487d6a8 j_mayer
GEN_SPEOP_COMP(efdtsteq);
6517 0487d6a8 j_mayer
6518 0487d6a8 j_mayer
/* Opcodes definitions */
6519 0487d6a8 j_mayer
GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
6520 0487d6a8 j_mayer
GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
6521 0487d6a8 j_mayer
GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
6522 0487d6a8 j_mayer
GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
6523 0487d6a8 j_mayer
GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
6524 0487d6a8 j_mayer
GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
6525 0487d6a8 j_mayer
GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
6526 0487d6a8 j_mayer
GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
6527 0487d6a8 j_mayer
GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
6528 0487d6a8 j_mayer
GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
6529 0487d6a8 j_mayer
GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
6530 0487d6a8 j_mayer
GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
6531 0487d6a8 j_mayer
GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
6532 0487d6a8 j_mayer
GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
6533 0487d6a8 j_mayer
GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
6534 0487d6a8 j_mayer
GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
6535 0487d6a8 j_mayer
#endif
6536 0487d6a8 j_mayer
6537 79aceca5 bellard
/* End opcode list */
6538 79aceca5 bellard
GEN_OPCODE_MARK(end);
6539 79aceca5 bellard
6540 3fc6c082 bellard
#include "translate_init.c"
6541 0411a972 j_mayer
#include "helper_regs.h"
6542 79aceca5 bellard
6543 9a64fbe4 bellard
/*****************************************************************************/
6544 3fc6c082 bellard
/* Misc PowerPC helpers */
6545 36081602 j_mayer
void cpu_dump_state (CPUState *env, FILE *f,
6546 36081602 j_mayer
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6547 36081602 j_mayer
                     int flags)
6548 79aceca5 bellard
{
6549 3fc6c082 bellard
#if defined(TARGET_PPC64) || 1
6550 3fc6c082 bellard
#define FILL ""
6551 3fc6c082 bellard
#define RGPL  4
6552 3fc6c082 bellard
#define RFPL  4
6553 3fc6c082 bellard
#else
6554 3fc6c082 bellard
#define FILL "        "
6555 3fc6c082 bellard
#define RGPL  8
6556 3fc6c082 bellard
#define RFPL  4
6557 3fc6c082 bellard
#endif
6558 3fc6c082 bellard
6559 79aceca5 bellard
    int i;
6560 79aceca5 bellard
6561 0411a972 j_mayer
    cpu_fprintf(f, "NIP " ADDRX " LR " ADDRX " CTR " ADDRX " idx %d\n",
6562 0411a972 j_mayer
                env->nip, env->lr, env->ctr, env->mmu_idx);
6563 d9bce9d9 j_mayer
    cpu_fprintf(f, "MSR " REGX FILL " XER %08x      "
6564 d9bce9d9 j_mayer
#if !defined(NO_TIMER_DUMP)
6565 d9bce9d9 j_mayer
                "TB %08x %08x "
6566 76a66253 j_mayer
#if !defined(CONFIG_USER_ONLY)
6567 76a66253 j_mayer
                "DECR %08x"
6568 76a66253 j_mayer
#endif
6569 d9bce9d9 j_mayer
#endif
6570 76a66253 j_mayer
                "\n",
6571 0411a972 j_mayer
                env->msr, hreg_load_xer(env)
6572 d9bce9d9 j_mayer
#if !defined(NO_TIMER_DUMP)
6573 d9bce9d9 j_mayer
                , cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
6574 76a66253 j_mayer
#if !defined(CONFIG_USER_ONLY)
6575 76a66253 j_mayer
                , cpu_ppc_load_decr(env)
6576 76a66253 j_mayer
#endif
6577 d9bce9d9 j_mayer
#endif
6578 76a66253 j_mayer
                );
6579 76a66253 j_mayer
    for (i = 0; i < 32; i++) {
6580 3fc6c082 bellard
        if ((i & (RGPL - 1)) == 0)
6581 3fc6c082 bellard
            cpu_fprintf(f, "GPR%02d", i);
6582 a750fc0b j_mayer
        cpu_fprintf(f, " " REGX, (target_ulong)env->gpr[i]);
6583 3fc6c082 bellard
        if ((i & (RGPL - 1)) == (RGPL - 1))
6584 7fe48483 bellard
            cpu_fprintf(f, "\n");
6585 76a66253 j_mayer
    }
6586 3fc6c082 bellard
    cpu_fprintf(f, "CR ");
6587 76a66253 j_mayer
    for (i = 0; i < 8; i++)
6588 7fe48483 bellard
        cpu_fprintf(f, "%01x", env->crf[i]);
6589 7fe48483 bellard
    cpu_fprintf(f, "  [");
6590 76a66253 j_mayer
    for (i = 0; i < 8; i++) {
6591 76a66253 j_mayer
        char a = '-';
6592 76a66253 j_mayer
        if (env->crf[i] & 0x08)
6593 76a66253 j_mayer
            a = 'L';
6594 76a66253 j_mayer
        else if (env->crf[i] & 0x04)
6595 76a66253 j_mayer
            a = 'G';
6596 76a66253 j_mayer
        else if (env->crf[i] & 0x02)
6597 76a66253 j_mayer
            a = 'E';
6598 7fe48483 bellard
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
6599 76a66253 j_mayer
    }
6600 3fc6c082 bellard
    cpu_fprintf(f, " ]             " FILL "RES " REGX "\n", env->reserve);
6601 3fc6c082 bellard
    for (i = 0; i < 32; i++) {
6602 3fc6c082 bellard
        if ((i & (RFPL - 1)) == 0)
6603 3fc6c082 bellard
            cpu_fprintf(f, "FPR%02d", i);
6604 26a76461 bellard
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
6605 3fc6c082 bellard
        if ((i & (RFPL - 1)) == (RFPL - 1))
6606 7fe48483 bellard
            cpu_fprintf(f, "\n");
6607 79aceca5 bellard
    }
6608 f2e63a42 j_mayer
#if !defined(CONFIG_USER_ONLY)
6609 3fc6c082 bellard
    cpu_fprintf(f, "SRR0 " REGX " SRR1 " REGX "         " FILL FILL FILL
6610 3fc6c082 bellard
                "SDR1 " REGX "\n",
6611 3fc6c082 bellard
                env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
6612 f2e63a42 j_mayer
#endif
6613 79aceca5 bellard
6614 3fc6c082 bellard
#undef RGPL
6615 3fc6c082 bellard
#undef RFPL
6616 3fc6c082 bellard
#undef FILL
6617 79aceca5 bellard
}
6618 79aceca5 bellard
6619 76a66253 j_mayer
void cpu_dump_statistics (CPUState *env, FILE*f,
6620 76a66253 j_mayer
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6621 76a66253 j_mayer
                          int flags)
6622 76a66253 j_mayer
{
6623 76a66253 j_mayer
#if defined(DO_PPC_STATISTICS)
6624 76a66253 j_mayer
    opc_handler_t **t1, **t2, **t3, *handler;
6625 76a66253 j_mayer
    int op1, op2, op3;
6626 76a66253 j_mayer
6627 76a66253 j_mayer
    t1 = env->opcodes;
6628 76a66253 j_mayer
    for (op1 = 0; op1 < 64; op1++) {
6629 76a66253 j_mayer
        handler = t1[op1];
6630 76a66253 j_mayer
        if (is_indirect_opcode(handler)) {
6631 76a66253 j_mayer
            t2 = ind_table(handler);
6632 76a66253 j_mayer
            for (op2 = 0; op2 < 32; op2++) {
6633 76a66253 j_mayer
                handler = t2[op2];
6634 76a66253 j_mayer
                if (is_indirect_opcode(handler)) {
6635 76a66253 j_mayer
                    t3 = ind_table(handler);
6636 76a66253 j_mayer
                    for (op3 = 0; op3 < 32; op3++) {
6637 76a66253 j_mayer
                        handler = t3[op3];
6638 76a66253 j_mayer
                        if (handler->count == 0)
6639 76a66253 j_mayer
                            continue;
6640 76a66253 j_mayer
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
6641 76a66253 j_mayer
                                    "%016llx %lld\n",
6642 76a66253 j_mayer
                                    op1, op2, op3, op1, (op3 << 5) | op2,
6643 76a66253 j_mayer
                                    handler->oname,
6644 76a66253 j_mayer
                                    handler->count, handler->count);
6645 76a66253 j_mayer
                    }
6646 76a66253 j_mayer
                } else {
6647 76a66253 j_mayer
                    if (handler->count == 0)
6648 76a66253 j_mayer
                        continue;
6649 76a66253 j_mayer
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
6650 76a66253 j_mayer
                                "%016llx %lld\n",
6651 76a66253 j_mayer
                                op1, op2, op1, op2, handler->oname,
6652 76a66253 j_mayer
                                handler->count, handler->count);
6653 76a66253 j_mayer
                }
6654 76a66253 j_mayer
            }
6655 76a66253 j_mayer
        } else {
6656 76a66253 j_mayer
            if (handler->count == 0)
6657 76a66253 j_mayer
                continue;
6658 76a66253 j_mayer
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
6659 76a66253 j_mayer
                        op1, op1, handler->oname,
6660 76a66253 j_mayer
                        handler->count, handler->count);
6661 76a66253 j_mayer
        }
6662 76a66253 j_mayer
    }
6663 76a66253 j_mayer
#endif
6664 76a66253 j_mayer
}
6665 76a66253 j_mayer
6666 9a64fbe4 bellard
/*****************************************************************************/
6667 b068d6a7 j_mayer
static always_inline int gen_intermediate_code_internal (CPUState *env,
6668 b068d6a7 j_mayer
                                                         TranslationBlock *tb,
6669 b068d6a7 j_mayer
                                                         int search_pc)
6670 79aceca5 bellard
{
6671 9fddaa0c bellard
    DisasContext ctx, *ctxp = &ctx;
6672 79aceca5 bellard
    opc_handler_t **table, *handler;
6673 0fa85d43 bellard
    target_ulong pc_start;
6674 79aceca5 bellard
    uint16_t *gen_opc_end;
6675 2857068e j_mayer
    int supervisor;
6676 d26bfc9a j_mayer
    int single_step, branch_step;
6677 79aceca5 bellard
    int j, lj = -1;
6678 79aceca5 bellard
6679 79aceca5 bellard
    pc_start = tb->pc;
6680 79aceca5 bellard
    gen_opc_ptr = gen_opc_buf;
6681 79aceca5 bellard
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6682 79aceca5 bellard
    gen_opparam_ptr = gen_opparam_buf;
6683 c53be334 bellard
    nb_gen_labels = 0;
6684 046d6672 bellard
    ctx.nip = pc_start;
6685 79aceca5 bellard
    ctx.tb = tb;
6686 e1833e1f j_mayer
    ctx.exception = POWERPC_EXCP_NONE;
6687 3fc6c082 bellard
    ctx.spr_cb = env->spr_cb;
6688 6ebbf390 j_mayer
    supervisor = env->mmu_idx;
6689 6ebbf390 j_mayer
#if !defined(CONFIG_USER_ONLY)
6690 2857068e j_mayer
    ctx.supervisor = supervisor;
6691 d9bce9d9 j_mayer
#endif
6692 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
6693 d9bce9d9 j_mayer
    ctx.sf_mode = msr_sf;
6694 2857068e j_mayer
    ctx.mem_idx = (supervisor << 2) | (msr_sf << 1) | msr_le;
6695 2857068e j_mayer
#else
6696 2857068e j_mayer
    ctx.mem_idx = (supervisor << 1) | msr_le;
6697 9a64fbe4 bellard
#endif
6698 d63001d1 j_mayer
    ctx.dcache_line_size = env->dcache_line_size;
6699 3cc62370 bellard
    ctx.fpu_enabled = msr_fp;
6700 35cdaad6 j_mayer
#if defined(TARGET_PPCEMB)
6701 a9d9eb8f j_mayer
    if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
6702 d26bfc9a j_mayer
        ctx.spe_enabled = msr_spe;
6703 d26bfc9a j_mayer
    else
6704 d26bfc9a j_mayer
        ctx.spe_enabled = 0;
6705 0487d6a8 j_mayer
#endif
6706 a9d9eb8f j_mayer
    if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
6707 a9d9eb8f j_mayer
        ctx.altivec_enabled = msr_vr;
6708 a9d9eb8f j_mayer
    else
6709 a9d9eb8f j_mayer
        ctx.altivec_enabled = 0;
6710 d26bfc9a j_mayer
    if ((env->flags & POWERPC_FLAG_SE) && msr_se)
6711 d26bfc9a j_mayer
        single_step = 1;
6712 d26bfc9a j_mayer
    else
6713 d26bfc9a j_mayer
        single_step = 0;
6714 d26bfc9a j_mayer
    if ((env->flags & POWERPC_FLAG_BE) && msr_be)
6715 d26bfc9a j_mayer
        branch_step = 1;
6716 d26bfc9a j_mayer
    else
6717 d26bfc9a j_mayer
        branch_step = 0;
6718 b33c17e1 j_mayer
    ctx.singlestep_enabled = env->singlestep_enabled || single_step == 1;
6719 3fc6c082 bellard
#if defined (DO_SINGLE_STEP) && 0
6720 9a64fbe4 bellard
    /* Single step trace mode */
6721 9a64fbe4 bellard
    msr_se = 1;
6722 9a64fbe4 bellard
#endif
6723 9a64fbe4 bellard
    /* Set env in case of segfault during code fetch */
6724 e1833e1f j_mayer
    while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
6725 76a66253 j_mayer
        if (unlikely(env->nb_breakpoints > 0)) {
6726 76a66253 j_mayer
            for (j = 0; j < env->nb_breakpoints; j++) {
6727 ea4e754f bellard
                if (env->breakpoints[j] == ctx.nip) {
6728 5fafdf24 ths
                    gen_update_nip(&ctx, ctx.nip);
6729 ea4e754f bellard
                    gen_op_debug();
6730 ea4e754f bellard
                    break;
6731 ea4e754f bellard
                }
6732 ea4e754f bellard
            }
6733 ea4e754f bellard
        }
6734 76a66253 j_mayer
        if (unlikely(search_pc)) {
6735 79aceca5 bellard
            j = gen_opc_ptr - gen_opc_buf;
6736 79aceca5 bellard
            if (lj < j) {
6737 79aceca5 bellard
                lj++;
6738 79aceca5 bellard
                while (lj < j)
6739 79aceca5 bellard
                    gen_opc_instr_start[lj++] = 0;
6740 046d6672 bellard
                gen_opc_pc[lj] = ctx.nip;
6741 79aceca5 bellard
                gen_opc_instr_start[lj] = 1;
6742 79aceca5 bellard
            }
6743 79aceca5 bellard
        }
6744 9fddaa0c bellard
#if defined PPC_DEBUG_DISAS
6745 9fddaa0c bellard
        if (loglevel & CPU_LOG_TB_IN_ASM) {
6746 79aceca5 bellard
            fprintf(logfile, "----------------\n");
6747 1b9eb036 j_mayer
            fprintf(logfile, "nip=" ADDRX " super=%d ir=%d\n",
6748 0411a972 j_mayer
                    ctx.nip, supervisor, (int)msr_ir);
6749 9a64fbe4 bellard
        }
6750 9a64fbe4 bellard
#endif
6751 0fa85d43 bellard
        ctx.opcode = ldl_code(ctx.nip);
6752 111bfab3 bellard
        if (msr_le) {
6753 111bfab3 bellard
            ctx.opcode = ((ctx.opcode & 0xFF000000) >> 24) |
6754 111bfab3 bellard
                ((ctx.opcode & 0x00FF0000) >> 8) |
6755 111bfab3 bellard
                ((ctx.opcode & 0x0000FF00) << 8) |
6756 111bfab3 bellard
                ((ctx.opcode & 0x000000FF) << 24);
6757 111bfab3 bellard
        }
6758 9fddaa0c bellard
#if defined PPC_DEBUG_DISAS
6759 9fddaa0c bellard
        if (loglevel & CPU_LOG_TB_IN_ASM) {
6760 111bfab3 bellard
            fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
6761 9a64fbe4 bellard
                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
6762 111bfab3 bellard
                    opc3(ctx.opcode), msr_le ? "little" : "big");
6763 79aceca5 bellard
        }
6764 79aceca5 bellard
#endif
6765 046d6672 bellard
        ctx.nip += 4;
6766 3fc6c082 bellard
        table = env->opcodes;
6767 79aceca5 bellard
        handler = table[opc1(ctx.opcode)];
6768 79aceca5 bellard
        if (is_indirect_opcode(handler)) {
6769 79aceca5 bellard
            table = ind_table(handler);
6770 79aceca5 bellard
            handler = table[opc2(ctx.opcode)];
6771 79aceca5 bellard
            if (is_indirect_opcode(handler)) {
6772 79aceca5 bellard
                table = ind_table(handler);
6773 79aceca5 bellard
                handler = table[opc3(ctx.opcode)];
6774 79aceca5 bellard
            }
6775 79aceca5 bellard
        }
6776 79aceca5 bellard
        /* Is opcode *REALLY* valid ? */
6777 76a66253 j_mayer
        if (unlikely(handler->handler == &gen_invalid)) {
6778 4a057712 j_mayer
            if (loglevel != 0) {
6779 76a66253 j_mayer
                fprintf(logfile, "invalid/unsupported opcode: "
6780 1b9eb036 j_mayer
                        "%02x - %02x - %02x (%08x) 0x" ADDRX " %d\n",
6781 76a66253 j_mayer
                        opc1(ctx.opcode), opc2(ctx.opcode),
6782 0411a972 j_mayer
                        opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
6783 4b3686fa bellard
            } else {
6784 4b3686fa bellard
                printf("invalid/unsupported opcode: "
6785 1b9eb036 j_mayer
                       "%02x - %02x - %02x (%08x) 0x" ADDRX " %d\n",
6786 4b3686fa bellard
                       opc1(ctx.opcode), opc2(ctx.opcode),
6787 0411a972 j_mayer
                       opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
6788 4b3686fa bellard
            }
6789 76a66253 j_mayer
        } else {
6790 76a66253 j_mayer
            if (unlikely((ctx.opcode & handler->inval) != 0)) {
6791 4a057712 j_mayer
                if (loglevel != 0) {
6792 79aceca5 bellard
                    fprintf(logfile, "invalid bits: %08x for opcode: "
6793 e1833e1f j_mayer
                            "%02x - %02x - %02x (%08x) 0x" ADDRX "\n",
6794 79aceca5 bellard
                            ctx.opcode & handler->inval, opc1(ctx.opcode),
6795 79aceca5 bellard
                            opc2(ctx.opcode), opc3(ctx.opcode),
6796 046d6672 bellard
                            ctx.opcode, ctx.nip - 4);
6797 9a64fbe4 bellard
                } else {
6798 9a64fbe4 bellard
                    printf("invalid bits: %08x for opcode: "
6799 e1833e1f j_mayer
                           "%02x - %02x - %02x (%08x) 0x" ADDRX "\n",
6800 76a66253 j_mayer
                           ctx.opcode & handler->inval, opc1(ctx.opcode),
6801 76a66253 j_mayer
                           opc2(ctx.opcode), opc3(ctx.opcode),
6802 046d6672 bellard
                           ctx.opcode, ctx.nip - 4);
6803 76a66253 j_mayer
                }
6804 e1833e1f j_mayer
                GEN_EXCP_INVAL(ctxp);
6805 4b3686fa bellard
                break;
6806 79aceca5 bellard
            }
6807 79aceca5 bellard
        }
6808 4b3686fa bellard
        (*(handler->handler))(&ctx);
6809 76a66253 j_mayer
#if defined(DO_PPC_STATISTICS)
6810 76a66253 j_mayer
        handler->count++;
6811 76a66253 j_mayer
#endif
6812 9a64fbe4 bellard
        /* Check trace mode exceptions */
6813 d26bfc9a j_mayer
        if (unlikely(branch_step != 0 &&
6814 d26bfc9a j_mayer
                     ctx.exception == POWERPC_EXCP_BRANCH)) {
6815 d26bfc9a j_mayer
            GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
6816 d26bfc9a j_mayer
        } else if (unlikely(single_step != 0 &&
6817 d26bfc9a j_mayer
                            (ctx.nip <= 0x100 || ctx.nip > 0xF00 ||
6818 d26bfc9a j_mayer
                             (ctx.nip & 0xFC) != 0x04) &&
6819 417bf010 j_mayer
                            ctx.exception != POWERPC_SYSCALL &&
6820 d26bfc9a j_mayer
                            ctx.exception != POWERPC_EXCP_TRAP)) {
6821 e1833e1f j_mayer
            GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
6822 d26bfc9a j_mayer
        } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
6823 d26bfc9a j_mayer
                            (env->singlestep_enabled))) {
6824 d26bfc9a j_mayer
            /* if we reach a page boundary or are single stepping, stop
6825 d26bfc9a j_mayer
             * generation
6826 d26bfc9a j_mayer
             */
6827 8dd4983c bellard
            break;
6828 76a66253 j_mayer
        }
6829 3fc6c082 bellard
#if defined (DO_SINGLE_STEP)
6830 3fc6c082 bellard
        break;
6831 3fc6c082 bellard
#endif
6832 3fc6c082 bellard
    }
6833 e1833e1f j_mayer
    if (ctx.exception == POWERPC_EXCP_NONE) {
6834 c1942362 bellard
        gen_goto_tb(&ctx, 0, ctx.nip);
6835 e1833e1f j_mayer
    } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
6836 76a66253 j_mayer
        gen_op_reset_T0();
6837 76a66253 j_mayer
        /* Generate the return instruction */
6838 76a66253 j_mayer
        gen_op_exit_tb();
6839 9a64fbe4 bellard
    }
6840 79aceca5 bellard
    *gen_opc_ptr = INDEX_op_end;
6841 76a66253 j_mayer
    if (unlikely(search_pc)) {
6842 9a64fbe4 bellard
        j = gen_opc_ptr - gen_opc_buf;
6843 9a64fbe4 bellard
        lj++;
6844 9a64fbe4 bellard
        while (lj <= j)
6845 9a64fbe4 bellard
            gen_opc_instr_start[lj++] = 0;
6846 9a64fbe4 bellard
    } else {
6847 046d6672 bellard
        tb->size = ctx.nip - pc_start;
6848 9a64fbe4 bellard
    }
6849 d9bce9d9 j_mayer
#if defined(DEBUG_DISAS)
6850 9fddaa0c bellard
    if (loglevel & CPU_LOG_TB_CPU) {
6851 9a64fbe4 bellard
        fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
6852 7fe48483 bellard
        cpu_dump_state(env, logfile, fprintf, 0);
6853 9fddaa0c bellard
    }
6854 9fddaa0c bellard
    if (loglevel & CPU_LOG_TB_IN_ASM) {
6855 76a66253 j_mayer
        int flags;
6856 237c0af0 j_mayer
        flags = env->bfd_mach;
6857 237c0af0 j_mayer
        flags |= msr_le << 16;
6858 0fa85d43 bellard
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
6859 76a66253 j_mayer
        target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
6860 79aceca5 bellard
        fprintf(logfile, "\n");
6861 9fddaa0c bellard
    }
6862 9fddaa0c bellard
    if (loglevel & CPU_LOG_TB_OP) {
6863 79aceca5 bellard
        fprintf(logfile, "OP:\n");
6864 79aceca5 bellard
        dump_ops(gen_opc_buf, gen_opparam_buf);
6865 79aceca5 bellard
        fprintf(logfile, "\n");
6866 79aceca5 bellard
    }
6867 79aceca5 bellard
#endif
6868 79aceca5 bellard
    return 0;
6869 79aceca5 bellard
}
6870 79aceca5 bellard
6871 9a64fbe4 bellard
int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
6872 79aceca5 bellard
{
6873 79aceca5 bellard
    return gen_intermediate_code_internal(env, tb, 0);
6874 79aceca5 bellard
}
6875 79aceca5 bellard
6876 9a64fbe4 bellard
int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
6877 79aceca5 bellard
{
6878 79aceca5 bellard
    return gen_intermediate_code_internal(env, tb, 1);
6879 79aceca5 bellard
}