Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ c7697e1f

History | View | Annotate | Download (238.1 kB)

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

6366 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
6367 0487d6a8 j_mayer
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
6368 0487d6a8 j_mayer
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
6369 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
6370 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
6371 0487d6a8 j_mayer
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
6372 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
6373 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
6374 0487d6a8 j_mayer
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
6375 0487d6a8 j_mayer
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
6376 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
6377 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
6378 0487d6a8 j_mayer
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
6379 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
6380 0487d6a8 j_mayer

6381 0487d6a8 j_mayer
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
6382 0487d6a8 j_mayer
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
6383 0487d6a8 j_mayer
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
6384 0487d6a8 j_mayer
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
6385 0487d6a8 j_mayer
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
6386 0487d6a8 j_mayer
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
6387 0487d6a8 j_mayer

6388 0487d6a8 j_mayer
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
6389 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
6390 0487d6a8 j_mayer
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
6391 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
6392 0487d6a8 j_mayer
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
6393 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
6394 0487d6a8 j_mayer
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
6395 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
6396 0487d6a8 j_mayer
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
6397 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
6398 0487d6a8 j_mayer
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
6399 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
6400 0487d6a8 j_mayer

6401 0487d6a8 j_mayer
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
6402 0487d6a8 j_mayer
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
6403 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
6404 0487d6a8 j_mayer
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
6405 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
6406 0487d6a8 j_mayer

6407 0487d6a8 j_mayer
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
6408 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
6409 0487d6a8 j_mayer
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
6410 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
6411 0487d6a8 j_mayer
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
6412 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
6413 0487d6a8 j_mayer
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
6414 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
6415 0487d6a8 j_mayer
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
6416 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
6417 0487d6a8 j_mayer
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
6418 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
6419 0487d6a8 j_mayer

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