Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ f0685f6e

History | View | Annotate | Download (238 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
/* dcbf */
3622 0db1b20e j_mayer
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
3623 79aceca5 bellard
{
3624 dac454af j_mayer
    /* XXX: specification says this is treated as a load by the MMU */
3625 76a66253 j_mayer
    gen_addr_reg_index(ctx);
3626 a541f297 bellard
    op_ldst(lbz);
3627 79aceca5 bellard
}
3628 79aceca5 bellard
3629 79aceca5 bellard
/* dcbi (Supervisor only) */
3630 9a64fbe4 bellard
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
3631 79aceca5 bellard
{
3632 a541f297 bellard
#if defined(CONFIG_USER_ONLY)
3633 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
3634 a541f297 bellard
#else
3635 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
3636 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
3637 9fddaa0c bellard
        return;
3638 9a64fbe4 bellard
    }
3639 76a66253 j_mayer
    gen_addr_reg_index(ctx);
3640 76a66253 j_mayer
    /* XXX: specification says this should be treated as a store by the MMU */
3641 dac454af j_mayer
    op_ldst(lbz);
3642 a541f297 bellard
    op_ldst(stb);
3643 a541f297 bellard
#endif
3644 79aceca5 bellard
}
3645 79aceca5 bellard
3646 79aceca5 bellard
/* dcdst */
3647 9a64fbe4 bellard
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
3648 79aceca5 bellard
{
3649 76a66253 j_mayer
    /* XXX: specification say this is treated as a load by the MMU */
3650 76a66253 j_mayer
    gen_addr_reg_index(ctx);
3651 a541f297 bellard
    op_ldst(lbz);
3652 79aceca5 bellard
}
3653 79aceca5 bellard
3654 79aceca5 bellard
/* dcbt */
3655 0db1b20e j_mayer
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE)
3656 79aceca5 bellard
{
3657 0db1b20e j_mayer
    /* interpreted as no-op */
3658 76a66253 j_mayer
    /* XXX: specification say this is treated as a load by the MMU
3659 76a66253 j_mayer
     *      but does not generate any exception
3660 76a66253 j_mayer
     */
3661 79aceca5 bellard
}
3662 79aceca5 bellard
3663 79aceca5 bellard
/* dcbtst */
3664 0db1b20e j_mayer
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE)
3665 79aceca5 bellard
{
3666 0db1b20e j_mayer
    /* interpreted as no-op */
3667 76a66253 j_mayer
    /* XXX: specification say this is treated as a load by the MMU
3668 76a66253 j_mayer
     *      but does not generate any exception
3669 76a66253 j_mayer
     */
3670 79aceca5 bellard
}
3671 79aceca5 bellard
3672 79aceca5 bellard
/* dcbz */
3673 d63001d1 j_mayer
#define op_dcbz(n) (*gen_op_dcbz[n][ctx->mem_idx])()
3674 d9bce9d9 j_mayer
#if defined(CONFIG_USER_ONLY)
3675 2857068e j_mayer
/* User-mode only */
3676 d63001d1 j_mayer
static GenOpFunc *gen_op_dcbz[4][4] = {
3677 d63001d1 j_mayer
    {
3678 d63001d1 j_mayer
        &gen_op_dcbz_l32_raw,
3679 d63001d1 j_mayer
        &gen_op_dcbz_l32_raw,
3680 2857068e j_mayer
#if defined(TARGET_PPC64)
3681 d63001d1 j_mayer
        &gen_op_dcbz_l32_64_raw,
3682 d63001d1 j_mayer
        &gen_op_dcbz_l32_64_raw,
3683 2857068e j_mayer
#endif
3684 d63001d1 j_mayer
    },
3685 d63001d1 j_mayer
    {
3686 d63001d1 j_mayer
        &gen_op_dcbz_l64_raw,
3687 d63001d1 j_mayer
        &gen_op_dcbz_l64_raw,
3688 d63001d1 j_mayer
#if defined(TARGET_PPC64)
3689 d63001d1 j_mayer
        &gen_op_dcbz_l64_64_raw,
3690 d63001d1 j_mayer
        &gen_op_dcbz_l64_64_raw,
3691 d63001d1 j_mayer
#endif
3692 d63001d1 j_mayer
    },
3693 d63001d1 j_mayer
    {
3694 d63001d1 j_mayer
        &gen_op_dcbz_l128_raw,
3695 d63001d1 j_mayer
        &gen_op_dcbz_l128_raw,
3696 d63001d1 j_mayer
#if defined(TARGET_PPC64)
3697 d63001d1 j_mayer
        &gen_op_dcbz_l128_64_raw,
3698 d63001d1 j_mayer
        &gen_op_dcbz_l128_64_raw,
3699 d63001d1 j_mayer
#endif
3700 d63001d1 j_mayer
    },
3701 d63001d1 j_mayer
    {
3702 d63001d1 j_mayer
        &gen_op_dcbz_raw,
3703 d63001d1 j_mayer
        &gen_op_dcbz_raw,
3704 d63001d1 j_mayer
#if defined(TARGET_PPC64)
3705 d63001d1 j_mayer
        &gen_op_dcbz_64_raw,
3706 d63001d1 j_mayer
        &gen_op_dcbz_64_raw,
3707 d63001d1 j_mayer
#endif
3708 d63001d1 j_mayer
    },
3709 d9bce9d9 j_mayer
};
3710 d9bce9d9 j_mayer
#else
3711 2857068e j_mayer
#if defined(TARGET_PPC64)
3712 2857068e j_mayer
/* Full system - 64 bits mode */
3713 d63001d1 j_mayer
static GenOpFunc *gen_op_dcbz[4][12] = {
3714 d63001d1 j_mayer
    {
3715 d63001d1 j_mayer
        &gen_op_dcbz_l32_user,
3716 d63001d1 j_mayer
        &gen_op_dcbz_l32_user,
3717 d63001d1 j_mayer
        &gen_op_dcbz_l32_64_user,
3718 d63001d1 j_mayer
        &gen_op_dcbz_l32_64_user,
3719 d63001d1 j_mayer
        &gen_op_dcbz_l32_kernel,
3720 d63001d1 j_mayer
        &gen_op_dcbz_l32_kernel,
3721 d63001d1 j_mayer
        &gen_op_dcbz_l32_64_kernel,
3722 d63001d1 j_mayer
        &gen_op_dcbz_l32_64_kernel,
3723 d63001d1 j_mayer
#if defined(TARGET_PPC64H)
3724 d63001d1 j_mayer
        &gen_op_dcbz_l32_hypv,
3725 d63001d1 j_mayer
        &gen_op_dcbz_l32_hypv,
3726 d63001d1 j_mayer
        &gen_op_dcbz_l32_64_hypv,
3727 d63001d1 j_mayer
        &gen_op_dcbz_l32_64_hypv,
3728 d63001d1 j_mayer
#endif
3729 d63001d1 j_mayer
    },
3730 d63001d1 j_mayer
    {
3731 d63001d1 j_mayer
        &gen_op_dcbz_l64_user,
3732 d63001d1 j_mayer
        &gen_op_dcbz_l64_user,
3733 d63001d1 j_mayer
        &gen_op_dcbz_l64_64_user,
3734 d63001d1 j_mayer
        &gen_op_dcbz_l64_64_user,
3735 d63001d1 j_mayer
        &gen_op_dcbz_l64_kernel,
3736 d63001d1 j_mayer
        &gen_op_dcbz_l64_kernel,
3737 d63001d1 j_mayer
        &gen_op_dcbz_l64_64_kernel,
3738 d63001d1 j_mayer
        &gen_op_dcbz_l64_64_kernel,
3739 2857068e j_mayer
#if defined(TARGET_PPC64H)
3740 d63001d1 j_mayer
        &gen_op_dcbz_l64_hypv,
3741 d63001d1 j_mayer
        &gen_op_dcbz_l64_hypv,
3742 d63001d1 j_mayer
        &gen_op_dcbz_l64_64_hypv,
3743 d63001d1 j_mayer
        &gen_op_dcbz_l64_64_hypv,
3744 d63001d1 j_mayer
#endif
3745 d63001d1 j_mayer
    },
3746 d63001d1 j_mayer
    {
3747 d63001d1 j_mayer
        &gen_op_dcbz_l128_user,
3748 d63001d1 j_mayer
        &gen_op_dcbz_l128_user,
3749 d63001d1 j_mayer
        &gen_op_dcbz_l128_64_user,
3750 d63001d1 j_mayer
        &gen_op_dcbz_l128_64_user,
3751 d63001d1 j_mayer
        &gen_op_dcbz_l128_kernel,
3752 d63001d1 j_mayer
        &gen_op_dcbz_l128_kernel,
3753 d63001d1 j_mayer
        &gen_op_dcbz_l128_64_kernel,
3754 d63001d1 j_mayer
        &gen_op_dcbz_l128_64_kernel,
3755 d63001d1 j_mayer
#if defined(TARGET_PPC64H)
3756 d63001d1 j_mayer
        &gen_op_dcbz_l128_hypv,
3757 d63001d1 j_mayer
        &gen_op_dcbz_l128_hypv,
3758 d63001d1 j_mayer
        &gen_op_dcbz_l128_64_hypv,
3759 d63001d1 j_mayer
        &gen_op_dcbz_l128_64_hypv,
3760 d63001d1 j_mayer
#endif
3761 d63001d1 j_mayer
    },
3762 d63001d1 j_mayer
    {
3763 d63001d1 j_mayer
        &gen_op_dcbz_user,
3764 d63001d1 j_mayer
        &gen_op_dcbz_user,
3765 d63001d1 j_mayer
        &gen_op_dcbz_64_user,
3766 d63001d1 j_mayer
        &gen_op_dcbz_64_user,
3767 d63001d1 j_mayer
        &gen_op_dcbz_kernel,
3768 d63001d1 j_mayer
        &gen_op_dcbz_kernel,
3769 d63001d1 j_mayer
        &gen_op_dcbz_64_kernel,
3770 d63001d1 j_mayer
        &gen_op_dcbz_64_kernel,
3771 d63001d1 j_mayer
#if defined(TARGET_PPC64H)
3772 d63001d1 j_mayer
        &gen_op_dcbz_hypv,
3773 d63001d1 j_mayer
        &gen_op_dcbz_hypv,
3774 d63001d1 j_mayer
        &gen_op_dcbz_64_hypv,
3775 d63001d1 j_mayer
        &gen_op_dcbz_64_hypv,
3776 d9bce9d9 j_mayer
#endif
3777 d63001d1 j_mayer
    },
3778 76a66253 j_mayer
};
3779 9a64fbe4 bellard
#else
3780 2857068e j_mayer
/* Full system - 32 bits mode */
3781 d63001d1 j_mayer
static GenOpFunc *gen_op_dcbz[4][4] = {
3782 d63001d1 j_mayer
    {
3783 d63001d1 j_mayer
        &gen_op_dcbz_l32_user,
3784 d63001d1 j_mayer
        &gen_op_dcbz_l32_user,
3785 d63001d1 j_mayer
        &gen_op_dcbz_l32_kernel,
3786 d63001d1 j_mayer
        &gen_op_dcbz_l32_kernel,
3787 d63001d1 j_mayer
    },
3788 d63001d1 j_mayer
    {
3789 d63001d1 j_mayer
        &gen_op_dcbz_l64_user,
3790 d63001d1 j_mayer
        &gen_op_dcbz_l64_user,
3791 d63001d1 j_mayer
        &gen_op_dcbz_l64_kernel,
3792 d63001d1 j_mayer
        &gen_op_dcbz_l64_kernel,
3793 d63001d1 j_mayer
    },
3794 d63001d1 j_mayer
    {
3795 d63001d1 j_mayer
        &gen_op_dcbz_l128_user,
3796 d63001d1 j_mayer
        &gen_op_dcbz_l128_user,
3797 d63001d1 j_mayer
        &gen_op_dcbz_l128_kernel,
3798 d63001d1 j_mayer
        &gen_op_dcbz_l128_kernel,
3799 d63001d1 j_mayer
    },
3800 d63001d1 j_mayer
    {
3801 d63001d1 j_mayer
        &gen_op_dcbz_user,
3802 d63001d1 j_mayer
        &gen_op_dcbz_user,
3803 d63001d1 j_mayer
        &gen_op_dcbz_kernel,
3804 d63001d1 j_mayer
        &gen_op_dcbz_kernel,
3805 d63001d1 j_mayer
    },
3806 9a64fbe4 bellard
};
3807 9a64fbe4 bellard
#endif
3808 d9bce9d9 j_mayer
#endif
3809 9a64fbe4 bellard
3810 b068d6a7 j_mayer
static always_inline void handler_dcbz (DisasContext *ctx,
3811 b068d6a7 j_mayer
                                        int dcache_line_size)
3812 d63001d1 j_mayer
{
3813 d63001d1 j_mayer
    int n;
3814 d63001d1 j_mayer
3815 d63001d1 j_mayer
    switch (dcache_line_size) {
3816 d63001d1 j_mayer
    case 32:
3817 d63001d1 j_mayer
        n = 0;
3818 d63001d1 j_mayer
        break;
3819 d63001d1 j_mayer
    case 64:
3820 d63001d1 j_mayer
        n = 1;
3821 d63001d1 j_mayer
        break;
3822 d63001d1 j_mayer
    case 128:
3823 d63001d1 j_mayer
        n = 2;
3824 d63001d1 j_mayer
        break;
3825 d63001d1 j_mayer
    default:
3826 d63001d1 j_mayer
        n = 3;
3827 d63001d1 j_mayer
        break;
3828 d63001d1 j_mayer
    }
3829 d63001d1 j_mayer
    op_dcbz(n);
3830 d63001d1 j_mayer
}
3831 d63001d1 j_mayer
3832 d63001d1 j_mayer
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ)
3833 79aceca5 bellard
{
3834 76a66253 j_mayer
    gen_addr_reg_index(ctx);
3835 d63001d1 j_mayer
    handler_dcbz(ctx, ctx->dcache_line_size);
3836 d63001d1 j_mayer
    gen_op_check_reservation();
3837 d63001d1 j_mayer
}
3838 d63001d1 j_mayer
3839 c7697e1f j_mayer
GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT)
3840 d63001d1 j_mayer
{
3841 d63001d1 j_mayer
    gen_addr_reg_index(ctx);
3842 d63001d1 j_mayer
    if (ctx->opcode & 0x00200000)
3843 d63001d1 j_mayer
        handler_dcbz(ctx, ctx->dcache_line_size);
3844 d63001d1 j_mayer
    else
3845 d63001d1 j_mayer
        handler_dcbz(ctx, -1);
3846 4b3686fa bellard
    gen_op_check_reservation();
3847 79aceca5 bellard
}
3848 79aceca5 bellard
3849 79aceca5 bellard
/* icbi */
3850 36f69651 j_mayer
#define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
3851 36f69651 j_mayer
#if defined(CONFIG_USER_ONLY)
3852 2857068e j_mayer
/* User-mode only */
3853 36f69651 j_mayer
static GenOpFunc *gen_op_icbi[] = {
3854 36f69651 j_mayer
    &gen_op_icbi_raw,
3855 36f69651 j_mayer
    &gen_op_icbi_raw,
3856 2857068e j_mayer
#if defined(TARGET_PPC64)
3857 36f69651 j_mayer
    &gen_op_icbi_64_raw,
3858 36f69651 j_mayer
    &gen_op_icbi_64_raw,
3859 2857068e j_mayer
#endif
3860 36f69651 j_mayer
};
3861 36f69651 j_mayer
#else
3862 2857068e j_mayer
/* Full system - 64 bits mode */
3863 2857068e j_mayer
#if defined(TARGET_PPC64)
3864 36f69651 j_mayer
static GenOpFunc *gen_op_icbi[] = {
3865 36f69651 j_mayer
    &gen_op_icbi_user,
3866 36f69651 j_mayer
    &gen_op_icbi_user,
3867 36f69651 j_mayer
    &gen_op_icbi_64_user,
3868 36f69651 j_mayer
    &gen_op_icbi_64_user,
3869 2857068e j_mayer
    &gen_op_icbi_kernel,
3870 2857068e j_mayer
    &gen_op_icbi_kernel,
3871 36f69651 j_mayer
    &gen_op_icbi_64_kernel,
3872 36f69651 j_mayer
    &gen_op_icbi_64_kernel,
3873 2857068e j_mayer
#if defined(TARGET_PPC64H)
3874 2857068e j_mayer
    &gen_op_icbi_hypv,
3875 2857068e j_mayer
    &gen_op_icbi_hypv,
3876 2857068e j_mayer
    &gen_op_icbi_64_hypv,
3877 2857068e j_mayer
    &gen_op_icbi_64_hypv,
3878 36f69651 j_mayer
#endif
3879 36f69651 j_mayer
};
3880 36f69651 j_mayer
#else
3881 2857068e j_mayer
/* Full system - 32 bits mode */
3882 36f69651 j_mayer
static GenOpFunc *gen_op_icbi[] = {
3883 36f69651 j_mayer
    &gen_op_icbi_user,
3884 36f69651 j_mayer
    &gen_op_icbi_user,
3885 36f69651 j_mayer
    &gen_op_icbi_kernel,
3886 36f69651 j_mayer
    &gen_op_icbi_kernel,
3887 36f69651 j_mayer
};
3888 36f69651 j_mayer
#endif
3889 36f69651 j_mayer
#endif
3890 e1833e1f j_mayer
3891 9a64fbe4 bellard
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
3892 79aceca5 bellard
{
3893 30032c94 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
3894 30032c94 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
3895 76a66253 j_mayer
    gen_addr_reg_index(ctx);
3896 36f69651 j_mayer
    op_icbi();
3897 79aceca5 bellard
}
3898 79aceca5 bellard
3899 79aceca5 bellard
/* Optional: */
3900 79aceca5 bellard
/* dcba */
3901 a750fc0b j_mayer
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
3902 79aceca5 bellard
{
3903 0db1b20e j_mayer
    /* interpreted as no-op */
3904 0db1b20e j_mayer
    /* XXX: specification say this is treated as a store by the MMU
3905 0db1b20e j_mayer
     *      but does not generate any exception
3906 0db1b20e j_mayer
     */
3907 79aceca5 bellard
}
3908 79aceca5 bellard
3909 79aceca5 bellard
/***                    Segment register manipulation                      ***/
3910 79aceca5 bellard
/* Supervisor only: */
3911 79aceca5 bellard
/* mfsr */
3912 79aceca5 bellard
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
3913 79aceca5 bellard
{
3914 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
3915 e1833e1f j_mayer
    GEN_EXCP_PRIVREG(ctx);
3916 9a64fbe4 bellard
#else
3917 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
3918 e1833e1f j_mayer
        GEN_EXCP_PRIVREG(ctx);
3919 9fddaa0c bellard
        return;
3920 9a64fbe4 bellard
    }
3921 76a66253 j_mayer
    gen_op_set_T1(SR(ctx->opcode));
3922 76a66253 j_mayer
    gen_op_load_sr();
3923 9a64fbe4 bellard
    gen_op_store_T0_gpr(rD(ctx->opcode));
3924 9a64fbe4 bellard
#endif
3925 79aceca5 bellard
}
3926 79aceca5 bellard
3927 79aceca5 bellard
/* mfsrin */
3928 9a64fbe4 bellard
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3929 79aceca5 bellard
{
3930 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
3931 e1833e1f j_mayer
    GEN_EXCP_PRIVREG(ctx);
3932 9a64fbe4 bellard
#else
3933 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
3934 e1833e1f j_mayer
        GEN_EXCP_PRIVREG(ctx);
3935 9fddaa0c bellard
        return;
3936 9a64fbe4 bellard
    }
3937 9a64fbe4 bellard
    gen_op_load_gpr_T1(rB(ctx->opcode));
3938 76a66253 j_mayer
    gen_op_srli_T1(28);
3939 76a66253 j_mayer
    gen_op_load_sr();
3940 9a64fbe4 bellard
    gen_op_store_T0_gpr(rD(ctx->opcode));
3941 9a64fbe4 bellard
#endif
3942 79aceca5 bellard
}
3943 79aceca5 bellard
3944 79aceca5 bellard
/* mtsr */
3945 e63c59cb bellard
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3946 79aceca5 bellard
{
3947 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
3948 e1833e1f j_mayer
    GEN_EXCP_PRIVREG(ctx);
3949 9a64fbe4 bellard
#else
3950 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
3951 e1833e1f j_mayer
        GEN_EXCP_PRIVREG(ctx);
3952 9fddaa0c bellard
        return;
3953 9a64fbe4 bellard
    }
3954 9a64fbe4 bellard
    gen_op_load_gpr_T0(rS(ctx->opcode));
3955 76a66253 j_mayer
    gen_op_set_T1(SR(ctx->opcode));
3956 76a66253 j_mayer
    gen_op_store_sr();
3957 9a64fbe4 bellard
#endif
3958 79aceca5 bellard
}
3959 79aceca5 bellard
3960 79aceca5 bellard
/* mtsrin */
3961 9a64fbe4 bellard
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3962 79aceca5 bellard
{
3963 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
3964 e1833e1f j_mayer
    GEN_EXCP_PRIVREG(ctx);
3965 9a64fbe4 bellard
#else
3966 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
3967 e1833e1f j_mayer
        GEN_EXCP_PRIVREG(ctx);
3968 9fddaa0c bellard
        return;
3969 9a64fbe4 bellard
    }
3970 9a64fbe4 bellard
    gen_op_load_gpr_T0(rS(ctx->opcode));
3971 9a64fbe4 bellard
    gen_op_load_gpr_T1(rB(ctx->opcode));
3972 76a66253 j_mayer
    gen_op_srli_T1(28);
3973 76a66253 j_mayer
    gen_op_store_sr();
3974 9a64fbe4 bellard
#endif
3975 79aceca5 bellard
}
3976 79aceca5 bellard
3977 12de9a39 j_mayer
#if defined(TARGET_PPC64)
3978 12de9a39 j_mayer
/* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
3979 12de9a39 j_mayer
/* mfsr */
3980 c7697e1f j_mayer
GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B)
3981 12de9a39 j_mayer
{
3982 12de9a39 j_mayer
#if defined(CONFIG_USER_ONLY)
3983 12de9a39 j_mayer
    GEN_EXCP_PRIVREG(ctx);
3984 12de9a39 j_mayer
#else
3985 12de9a39 j_mayer
    if (unlikely(!ctx->supervisor)) {
3986 12de9a39 j_mayer
        GEN_EXCP_PRIVREG(ctx);
3987 12de9a39 j_mayer
        return;
3988 12de9a39 j_mayer
    }
3989 12de9a39 j_mayer
    gen_op_set_T1(SR(ctx->opcode));
3990 12de9a39 j_mayer
    gen_op_load_slb();
3991 12de9a39 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
3992 12de9a39 j_mayer
#endif
3993 12de9a39 j_mayer
}
3994 12de9a39 j_mayer
3995 12de9a39 j_mayer
/* mfsrin */
3996 c7697e1f j_mayer
GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
3997 c7697e1f j_mayer
             PPC_SEGMENT_64B)
3998 12de9a39 j_mayer
{
3999 12de9a39 j_mayer
#if defined(CONFIG_USER_ONLY)
4000 12de9a39 j_mayer
    GEN_EXCP_PRIVREG(ctx);
4001 12de9a39 j_mayer
#else
4002 12de9a39 j_mayer
    if (unlikely(!ctx->supervisor)) {
4003 12de9a39 j_mayer
        GEN_EXCP_PRIVREG(ctx);
4004 12de9a39 j_mayer
        return;
4005 12de9a39 j_mayer
    }
4006 12de9a39 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4007 12de9a39 j_mayer
    gen_op_srli_T1(28);
4008 12de9a39 j_mayer
    gen_op_load_slb();
4009 12de9a39 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4010 12de9a39 j_mayer
#endif
4011 12de9a39 j_mayer
}
4012 12de9a39 j_mayer
4013 12de9a39 j_mayer
/* mtsr */
4014 c7697e1f j_mayer
GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B)
4015 12de9a39 j_mayer
{
4016 12de9a39 j_mayer
#if defined(CONFIG_USER_ONLY)
4017 12de9a39 j_mayer
    GEN_EXCP_PRIVREG(ctx);
4018 12de9a39 j_mayer
#else
4019 12de9a39 j_mayer
    if (unlikely(!ctx->supervisor)) {
4020 12de9a39 j_mayer
        GEN_EXCP_PRIVREG(ctx);
4021 12de9a39 j_mayer
        return;
4022 12de9a39 j_mayer
    }
4023 12de9a39 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4024 12de9a39 j_mayer
    gen_op_set_T1(SR(ctx->opcode));
4025 12de9a39 j_mayer
    gen_op_store_slb();
4026 12de9a39 j_mayer
#endif
4027 12de9a39 j_mayer
}
4028 12de9a39 j_mayer
4029 12de9a39 j_mayer
/* mtsrin */
4030 c7697e1f j_mayer
GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
4031 c7697e1f j_mayer
             PPC_SEGMENT_64B)
4032 12de9a39 j_mayer
{
4033 12de9a39 j_mayer
#if defined(CONFIG_USER_ONLY)
4034 12de9a39 j_mayer
    GEN_EXCP_PRIVREG(ctx);
4035 12de9a39 j_mayer
#else
4036 12de9a39 j_mayer
    if (unlikely(!ctx->supervisor)) {
4037 12de9a39 j_mayer
        GEN_EXCP_PRIVREG(ctx);
4038 12de9a39 j_mayer
        return;
4039 12de9a39 j_mayer
    }
4040 12de9a39 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4041 12de9a39 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4042 12de9a39 j_mayer
    gen_op_srli_T1(28);
4043 12de9a39 j_mayer
    gen_op_store_slb();
4044 12de9a39 j_mayer
#endif
4045 12de9a39 j_mayer
}
4046 12de9a39 j_mayer
#endif /* defined(TARGET_PPC64) */
4047 12de9a39 j_mayer
4048 79aceca5 bellard
/***                      Lookaside buffer management                      ***/
4049 79aceca5 bellard
/* Optional & supervisor only: */
4050 79aceca5 bellard
/* tlbia */
4051 3fc6c082 bellard
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
4052 79aceca5 bellard
{
4053 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
4054 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4055 9a64fbe4 bellard
#else
4056 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4057 4a057712 j_mayer
        if (loglevel != 0)
4058 9fddaa0c bellard
            fprintf(logfile, "%s: ! supervisor\n", __func__);
4059 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4060 9fddaa0c bellard
        return;
4061 9a64fbe4 bellard
    }
4062 9a64fbe4 bellard
    gen_op_tlbia();
4063 9a64fbe4 bellard
#endif
4064 79aceca5 bellard
}
4065 79aceca5 bellard
4066 79aceca5 bellard
/* tlbie */
4067 76a66253 j_mayer
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
4068 79aceca5 bellard
{
4069 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
4070 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4071 9a64fbe4 bellard
#else
4072 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4073 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4074 9fddaa0c bellard
        return;
4075 9a64fbe4 bellard
    }
4076 9a64fbe4 bellard
    gen_op_load_gpr_T0(rB(ctx->opcode));
4077 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
4078 d9bce9d9 j_mayer
    if (ctx->sf_mode)
4079 d9bce9d9 j_mayer
        gen_op_tlbie_64();
4080 d9bce9d9 j_mayer
    else
4081 d9bce9d9 j_mayer
#endif
4082 d9bce9d9 j_mayer
        gen_op_tlbie();
4083 9a64fbe4 bellard
#endif
4084 79aceca5 bellard
}
4085 79aceca5 bellard
4086 79aceca5 bellard
/* tlbsync */
4087 76a66253 j_mayer
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
4088 79aceca5 bellard
{
4089 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
4090 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4091 9a64fbe4 bellard
#else
4092 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4093 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4094 9fddaa0c bellard
        return;
4095 9a64fbe4 bellard
    }
4096 9a64fbe4 bellard
    /* This has no effect: it should ensure that all previous
4097 9a64fbe4 bellard
     * tlbie have completed
4098 9a64fbe4 bellard
     */
4099 e1833e1f j_mayer
    GEN_STOP(ctx);
4100 9a64fbe4 bellard
#endif
4101 79aceca5 bellard
}
4102 79aceca5 bellard
4103 426613db j_mayer
#if defined(TARGET_PPC64)
4104 426613db j_mayer
/* slbia */
4105 426613db j_mayer
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
4106 426613db j_mayer
{
4107 426613db j_mayer
#if defined(CONFIG_USER_ONLY)
4108 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4109 426613db j_mayer
#else
4110 426613db j_mayer
    if (unlikely(!ctx->supervisor)) {
4111 4a057712 j_mayer
        if (loglevel != 0)
4112 426613db j_mayer
            fprintf(logfile, "%s: ! supervisor\n", __func__);
4113 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4114 426613db j_mayer
        return;
4115 426613db j_mayer
    }
4116 426613db j_mayer
    gen_op_slbia();
4117 426613db j_mayer
#endif
4118 426613db j_mayer
}
4119 426613db j_mayer
4120 426613db j_mayer
/* slbie */
4121 426613db j_mayer
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
4122 426613db j_mayer
{
4123 426613db j_mayer
#if defined(CONFIG_USER_ONLY)
4124 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4125 426613db j_mayer
#else
4126 426613db j_mayer
    if (unlikely(!ctx->supervisor)) {
4127 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4128 426613db j_mayer
        return;
4129 426613db j_mayer
    }
4130 426613db j_mayer
    gen_op_load_gpr_T0(rB(ctx->opcode));
4131 426613db j_mayer
    gen_op_slbie();
4132 426613db j_mayer
#endif
4133 426613db j_mayer
}
4134 426613db j_mayer
#endif
4135 426613db j_mayer
4136 79aceca5 bellard
/***                              External control                         ***/
4137 79aceca5 bellard
/* Optional: */
4138 9a64fbe4 bellard
#define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
4139 9a64fbe4 bellard
#define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
4140 111bfab3 bellard
#if defined(CONFIG_USER_ONLY)
4141 2857068e j_mayer
/* User-mode only */
4142 111bfab3 bellard
static GenOpFunc *gen_op_eciwx[] = {
4143 111bfab3 bellard
    &gen_op_eciwx_raw,
4144 111bfab3 bellard
    &gen_op_eciwx_le_raw,
4145 2857068e j_mayer
#if defined(TARGET_PPC64)
4146 d9bce9d9 j_mayer
    &gen_op_eciwx_64_raw,
4147 d9bce9d9 j_mayer
    &gen_op_eciwx_le_64_raw,
4148 2857068e j_mayer
#endif
4149 111bfab3 bellard
};
4150 111bfab3 bellard
static GenOpFunc *gen_op_ecowx[] = {
4151 111bfab3 bellard
    &gen_op_ecowx_raw,
4152 111bfab3 bellard
    &gen_op_ecowx_le_raw,
4153 2857068e j_mayer
#if defined(TARGET_PPC64)
4154 d9bce9d9 j_mayer
    &gen_op_ecowx_64_raw,
4155 d9bce9d9 j_mayer
    &gen_op_ecowx_le_64_raw,
4156 2857068e j_mayer
#endif
4157 111bfab3 bellard
};
4158 111bfab3 bellard
#else
4159 2857068e j_mayer
#if defined(TARGET_PPC64)
4160 2857068e j_mayer
/* Full system - 64 bits mode */
4161 9a64fbe4 bellard
static GenOpFunc *gen_op_eciwx[] = {
4162 9a64fbe4 bellard
    &gen_op_eciwx_user,
4163 111bfab3 bellard
    &gen_op_eciwx_le_user,
4164 d9bce9d9 j_mayer
    &gen_op_eciwx_64_user,
4165 d9bce9d9 j_mayer
    &gen_op_eciwx_le_64_user,
4166 2857068e j_mayer
    &gen_op_eciwx_kernel,
4167 2857068e j_mayer
    &gen_op_eciwx_le_kernel,
4168 d9bce9d9 j_mayer
    &gen_op_eciwx_64_kernel,
4169 d9bce9d9 j_mayer
    &gen_op_eciwx_le_64_kernel,
4170 2857068e j_mayer
#if defined(TARGET_PPC64H)
4171 2857068e j_mayer
    &gen_op_eciwx_hypv,
4172 2857068e j_mayer
    &gen_op_eciwx_le_hypv,
4173 2857068e j_mayer
    &gen_op_eciwx_64_hypv,
4174 2857068e j_mayer
    &gen_op_eciwx_le_64_hypv,
4175 2857068e j_mayer
#endif
4176 9a64fbe4 bellard
};
4177 9a64fbe4 bellard
static GenOpFunc *gen_op_ecowx[] = {
4178 9a64fbe4 bellard
    &gen_op_ecowx_user,
4179 111bfab3 bellard
    &gen_op_ecowx_le_user,
4180 d9bce9d9 j_mayer
    &gen_op_ecowx_64_user,
4181 d9bce9d9 j_mayer
    &gen_op_ecowx_le_64_user,
4182 2857068e j_mayer
    &gen_op_ecowx_kernel,
4183 2857068e j_mayer
    &gen_op_ecowx_le_kernel,
4184 d9bce9d9 j_mayer
    &gen_op_ecowx_64_kernel,
4185 d9bce9d9 j_mayer
    &gen_op_ecowx_le_64_kernel,
4186 2857068e j_mayer
#if defined(TARGET_PPC64H)
4187 2857068e j_mayer
    &gen_op_ecowx_hypv,
4188 2857068e j_mayer
    &gen_op_ecowx_le_hypv,
4189 2857068e j_mayer
    &gen_op_ecowx_64_hypv,
4190 2857068e j_mayer
    &gen_op_ecowx_le_64_hypv,
4191 9a64fbe4 bellard
#endif
4192 d9bce9d9 j_mayer
};
4193 d9bce9d9 j_mayer
#else
4194 2857068e j_mayer
/* Full system - 32 bits mode */
4195 d9bce9d9 j_mayer
static GenOpFunc *gen_op_eciwx[] = {
4196 d9bce9d9 j_mayer
    &gen_op_eciwx_user,
4197 d9bce9d9 j_mayer
    &gen_op_eciwx_le_user,
4198 d9bce9d9 j_mayer
    &gen_op_eciwx_kernel,
4199 d9bce9d9 j_mayer
    &gen_op_eciwx_le_kernel,
4200 d9bce9d9 j_mayer
};
4201 d9bce9d9 j_mayer
static GenOpFunc *gen_op_ecowx[] = {
4202 d9bce9d9 j_mayer
    &gen_op_ecowx_user,
4203 d9bce9d9 j_mayer
    &gen_op_ecowx_le_user,
4204 d9bce9d9 j_mayer
    &gen_op_ecowx_kernel,
4205 d9bce9d9 j_mayer
    &gen_op_ecowx_le_kernel,
4206 d9bce9d9 j_mayer
};
4207 d9bce9d9 j_mayer
#endif
4208 d9bce9d9 j_mayer
#endif
4209 9a64fbe4 bellard
4210 111bfab3 bellard
/* eciwx */
4211 79aceca5 bellard
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
4212 79aceca5 bellard
{
4213 9a64fbe4 bellard
    /* Should check EAR[E] & alignment ! */
4214 76a66253 j_mayer
    gen_addr_reg_index(ctx);
4215 76a66253 j_mayer
    op_eciwx();
4216 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4217 76a66253 j_mayer
}
4218 76a66253 j_mayer
4219 76a66253 j_mayer
/* ecowx */
4220 76a66253 j_mayer
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
4221 76a66253 j_mayer
{
4222 76a66253 j_mayer
    /* Should check EAR[E] & alignment ! */
4223 76a66253 j_mayer
    gen_addr_reg_index(ctx);
4224 76a66253 j_mayer
    gen_op_load_gpr_T1(rS(ctx->opcode));
4225 76a66253 j_mayer
    op_ecowx();
4226 76a66253 j_mayer
}
4227 76a66253 j_mayer
4228 76a66253 j_mayer
/* PowerPC 601 specific instructions */
4229 76a66253 j_mayer
/* abs - abs. */
4230 76a66253 j_mayer
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
4231 76a66253 j_mayer
{
4232 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4233 76a66253 j_mayer
    gen_op_POWER_abs();
4234 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4235 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4236 76a66253 j_mayer
        gen_set_Rc0(ctx);
4237 76a66253 j_mayer
}
4238 76a66253 j_mayer
4239 76a66253 j_mayer
/* abso - abso. */
4240 76a66253 j_mayer
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
4241 76a66253 j_mayer
{
4242 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4243 76a66253 j_mayer
    gen_op_POWER_abso();
4244 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4245 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4246 76a66253 j_mayer
        gen_set_Rc0(ctx);
4247 76a66253 j_mayer
}
4248 76a66253 j_mayer
4249 76a66253 j_mayer
/* clcs */
4250 a750fc0b j_mayer
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
4251 76a66253 j_mayer
{
4252 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4253 76a66253 j_mayer
    gen_op_POWER_clcs();
4254 c7697e1f j_mayer
    /* Rc=1 sets CR0 to an undefined state */
4255 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4256 76a66253 j_mayer
}
4257 76a66253 j_mayer
4258 76a66253 j_mayer
/* div - div. */
4259 76a66253 j_mayer
GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
4260 76a66253 j_mayer
{
4261 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4262 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4263 76a66253 j_mayer
    gen_op_POWER_div();
4264 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4265 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4266 76a66253 j_mayer
        gen_set_Rc0(ctx);
4267 76a66253 j_mayer
}
4268 76a66253 j_mayer
4269 76a66253 j_mayer
/* divo - divo. */
4270 76a66253 j_mayer
GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
4271 76a66253 j_mayer
{
4272 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4273 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4274 76a66253 j_mayer
    gen_op_POWER_divo();
4275 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4276 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4277 76a66253 j_mayer
        gen_set_Rc0(ctx);
4278 76a66253 j_mayer
}
4279 76a66253 j_mayer
4280 76a66253 j_mayer
/* divs - divs. */
4281 76a66253 j_mayer
GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
4282 76a66253 j_mayer
{
4283 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4284 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4285 76a66253 j_mayer
    gen_op_POWER_divs();
4286 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4287 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4288 76a66253 j_mayer
        gen_set_Rc0(ctx);
4289 76a66253 j_mayer
}
4290 76a66253 j_mayer
4291 76a66253 j_mayer
/* divso - divso. */
4292 76a66253 j_mayer
GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
4293 76a66253 j_mayer
{
4294 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4295 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4296 76a66253 j_mayer
    gen_op_POWER_divso();
4297 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4298 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4299 76a66253 j_mayer
        gen_set_Rc0(ctx);
4300 76a66253 j_mayer
}
4301 76a66253 j_mayer
4302 76a66253 j_mayer
/* doz - doz. */
4303 76a66253 j_mayer
GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR)
4304 76a66253 j_mayer
{
4305 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4306 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4307 76a66253 j_mayer
    gen_op_POWER_doz();
4308 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4309 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4310 76a66253 j_mayer
        gen_set_Rc0(ctx);
4311 76a66253 j_mayer
}
4312 76a66253 j_mayer
4313 76a66253 j_mayer
/* dozo - dozo. */
4314 76a66253 j_mayer
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
4315 76a66253 j_mayer
{
4316 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4317 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4318 76a66253 j_mayer
    gen_op_POWER_dozo();
4319 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4320 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4321 76a66253 j_mayer
        gen_set_Rc0(ctx);
4322 76a66253 j_mayer
}
4323 76a66253 j_mayer
4324 76a66253 j_mayer
/* dozi */
4325 76a66253 j_mayer
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
4326 76a66253 j_mayer
{
4327 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4328 76a66253 j_mayer
    gen_op_set_T1(SIMM(ctx->opcode));
4329 76a66253 j_mayer
    gen_op_POWER_doz();
4330 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4331 76a66253 j_mayer
}
4332 76a66253 j_mayer
4333 76a66253 j_mayer
/* As lscbx load from memory byte after byte, it's always endian safe */
4334 2857068e j_mayer
#define op_POWER_lscbx(start, ra, rb)                                         \
4335 76a66253 j_mayer
(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
4336 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4337 76a66253 j_mayer
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
4338 76a66253 j_mayer
    &gen_op_POWER_lscbx_raw,
4339 76a66253 j_mayer
    &gen_op_POWER_lscbx_raw,
4340 76a66253 j_mayer
};
4341 76a66253 j_mayer
#else
4342 76a66253 j_mayer
static GenOpFunc3 *gen_op_POWER_lscbx[] = {
4343 76a66253 j_mayer
    &gen_op_POWER_lscbx_user,
4344 76a66253 j_mayer
    &gen_op_POWER_lscbx_user,
4345 76a66253 j_mayer
    &gen_op_POWER_lscbx_kernel,
4346 76a66253 j_mayer
    &gen_op_POWER_lscbx_kernel,
4347 76a66253 j_mayer
};
4348 76a66253 j_mayer
#endif
4349 76a66253 j_mayer
4350 76a66253 j_mayer
/* lscbx - lscbx. */
4351 76a66253 j_mayer
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
4352 76a66253 j_mayer
{
4353 76a66253 j_mayer
    int ra = rA(ctx->opcode);
4354 76a66253 j_mayer
    int rb = rB(ctx->opcode);
4355 76a66253 j_mayer
4356 76a66253 j_mayer
    gen_addr_reg_index(ctx);
4357 76a66253 j_mayer
    if (ra == 0) {
4358 76a66253 j_mayer
        ra = rb;
4359 76a66253 j_mayer
    }
4360 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
4361 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
4362 76a66253 j_mayer
    gen_op_load_xer_bc();
4363 76a66253 j_mayer
    gen_op_load_xer_cmp();
4364 76a66253 j_mayer
    op_POWER_lscbx(rD(ctx->opcode), ra, rb);
4365 76a66253 j_mayer
    gen_op_store_xer_bc();
4366 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4367 76a66253 j_mayer
        gen_set_Rc0(ctx);
4368 76a66253 j_mayer
}
4369 76a66253 j_mayer
4370 76a66253 j_mayer
/* maskg - maskg. */
4371 76a66253 j_mayer
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
4372 76a66253 j_mayer
{
4373 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4374 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4375 76a66253 j_mayer
    gen_op_POWER_maskg();
4376 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4377 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4378 76a66253 j_mayer
        gen_set_Rc0(ctx);
4379 76a66253 j_mayer
}
4380 76a66253 j_mayer
4381 76a66253 j_mayer
/* maskir - maskir. */
4382 76a66253 j_mayer
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
4383 76a66253 j_mayer
{
4384 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4385 76a66253 j_mayer
    gen_op_load_gpr_T1(rS(ctx->opcode));
4386 76a66253 j_mayer
    gen_op_load_gpr_T2(rB(ctx->opcode));
4387 76a66253 j_mayer
    gen_op_POWER_maskir();
4388 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4389 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4390 76a66253 j_mayer
        gen_set_Rc0(ctx);
4391 76a66253 j_mayer
}
4392 76a66253 j_mayer
4393 76a66253 j_mayer
/* mul - mul. */
4394 76a66253 j_mayer
GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
4395 76a66253 j_mayer
{
4396 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4397 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4398 76a66253 j_mayer
    gen_op_POWER_mul();
4399 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4400 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4401 76a66253 j_mayer
        gen_set_Rc0(ctx);
4402 76a66253 j_mayer
}
4403 76a66253 j_mayer
4404 76a66253 j_mayer
/* mulo - mulo. */
4405 76a66253 j_mayer
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
4406 76a66253 j_mayer
{
4407 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4408 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4409 76a66253 j_mayer
    gen_op_POWER_mulo();
4410 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4411 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4412 76a66253 j_mayer
        gen_set_Rc0(ctx);
4413 76a66253 j_mayer
}
4414 76a66253 j_mayer
4415 76a66253 j_mayer
/* nabs - nabs. */
4416 76a66253 j_mayer
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
4417 76a66253 j_mayer
{
4418 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4419 76a66253 j_mayer
    gen_op_POWER_nabs();
4420 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4421 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4422 76a66253 j_mayer
        gen_set_Rc0(ctx);
4423 76a66253 j_mayer
}
4424 76a66253 j_mayer
4425 76a66253 j_mayer
/* nabso - nabso. */
4426 76a66253 j_mayer
GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
4427 76a66253 j_mayer
{
4428 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4429 76a66253 j_mayer
    gen_op_POWER_nabso();
4430 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4431 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4432 76a66253 j_mayer
        gen_set_Rc0(ctx);
4433 76a66253 j_mayer
}
4434 76a66253 j_mayer
4435 76a66253 j_mayer
/* rlmi - rlmi. */
4436 76a66253 j_mayer
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
4437 76a66253 j_mayer
{
4438 76a66253 j_mayer
    uint32_t mb, me;
4439 76a66253 j_mayer
4440 76a66253 j_mayer
    mb = MB(ctx->opcode);
4441 76a66253 j_mayer
    me = ME(ctx->opcode);
4442 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4443 76a66253 j_mayer
    gen_op_load_gpr_T1(rA(ctx->opcode));
4444 76a66253 j_mayer
    gen_op_load_gpr_T2(rB(ctx->opcode));
4445 76a66253 j_mayer
    gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
4446 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4447 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4448 76a66253 j_mayer
        gen_set_Rc0(ctx);
4449 76a66253 j_mayer
}
4450 76a66253 j_mayer
4451 76a66253 j_mayer
/* rrib - rrib. */
4452 76a66253 j_mayer
GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
4453 76a66253 j_mayer
{
4454 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4455 76a66253 j_mayer
    gen_op_load_gpr_T1(rA(ctx->opcode));
4456 76a66253 j_mayer
    gen_op_load_gpr_T2(rB(ctx->opcode));
4457 76a66253 j_mayer
    gen_op_POWER_rrib();
4458 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4459 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4460 76a66253 j_mayer
        gen_set_Rc0(ctx);
4461 76a66253 j_mayer
}
4462 76a66253 j_mayer
4463 76a66253 j_mayer
/* sle - sle. */
4464 76a66253 j_mayer
GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
4465 76a66253 j_mayer
{
4466 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4467 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4468 76a66253 j_mayer
    gen_op_POWER_sle();
4469 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4470 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4471 76a66253 j_mayer
        gen_set_Rc0(ctx);
4472 76a66253 j_mayer
}
4473 76a66253 j_mayer
4474 76a66253 j_mayer
/* sleq - sleq. */
4475 76a66253 j_mayer
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
4476 76a66253 j_mayer
{
4477 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4478 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4479 76a66253 j_mayer
    gen_op_POWER_sleq();
4480 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4481 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4482 76a66253 j_mayer
        gen_set_Rc0(ctx);
4483 76a66253 j_mayer
}
4484 76a66253 j_mayer
4485 76a66253 j_mayer
/* sliq - sliq. */
4486 76a66253 j_mayer
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
4487 76a66253 j_mayer
{
4488 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4489 76a66253 j_mayer
    gen_op_set_T1(SH(ctx->opcode));
4490 76a66253 j_mayer
    gen_op_POWER_sle();
4491 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4492 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4493 76a66253 j_mayer
        gen_set_Rc0(ctx);
4494 76a66253 j_mayer
}
4495 76a66253 j_mayer
4496 76a66253 j_mayer
/* slliq - slliq. */
4497 76a66253 j_mayer
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
4498 76a66253 j_mayer
{
4499 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4500 76a66253 j_mayer
    gen_op_set_T1(SH(ctx->opcode));
4501 76a66253 j_mayer
    gen_op_POWER_sleq();
4502 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4503 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4504 76a66253 j_mayer
        gen_set_Rc0(ctx);
4505 76a66253 j_mayer
}
4506 76a66253 j_mayer
4507 76a66253 j_mayer
/* sllq - sllq. */
4508 76a66253 j_mayer
GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR)
4509 76a66253 j_mayer
{
4510 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4511 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4512 76a66253 j_mayer
    gen_op_POWER_sllq();
4513 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4514 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4515 76a66253 j_mayer
        gen_set_Rc0(ctx);
4516 76a66253 j_mayer
}
4517 76a66253 j_mayer
4518 76a66253 j_mayer
/* slq - slq. */
4519 76a66253 j_mayer
GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR)
4520 76a66253 j_mayer
{
4521 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4522 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4523 76a66253 j_mayer
    gen_op_POWER_slq();
4524 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4525 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4526 76a66253 j_mayer
        gen_set_Rc0(ctx);
4527 76a66253 j_mayer
}
4528 76a66253 j_mayer
4529 d9bce9d9 j_mayer
/* sraiq - sraiq. */
4530 76a66253 j_mayer
GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
4531 76a66253 j_mayer
{
4532 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4533 76a66253 j_mayer
    gen_op_set_T1(SH(ctx->opcode));
4534 76a66253 j_mayer
    gen_op_POWER_sraq();
4535 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4536 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4537 76a66253 j_mayer
        gen_set_Rc0(ctx);
4538 76a66253 j_mayer
}
4539 76a66253 j_mayer
4540 76a66253 j_mayer
/* sraq - sraq. */
4541 76a66253 j_mayer
GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR)
4542 76a66253 j_mayer
{
4543 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4544 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4545 76a66253 j_mayer
    gen_op_POWER_sraq();
4546 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4547 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4548 76a66253 j_mayer
        gen_set_Rc0(ctx);
4549 76a66253 j_mayer
}
4550 76a66253 j_mayer
4551 76a66253 j_mayer
/* sre - sre. */
4552 76a66253 j_mayer
GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR)
4553 76a66253 j_mayer
{
4554 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4555 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4556 76a66253 j_mayer
    gen_op_POWER_sre();
4557 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4558 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4559 76a66253 j_mayer
        gen_set_Rc0(ctx);
4560 76a66253 j_mayer
}
4561 76a66253 j_mayer
4562 76a66253 j_mayer
/* srea - srea. */
4563 76a66253 j_mayer
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
4564 76a66253 j_mayer
{
4565 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4566 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4567 76a66253 j_mayer
    gen_op_POWER_srea();
4568 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4569 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4570 76a66253 j_mayer
        gen_set_Rc0(ctx);
4571 76a66253 j_mayer
}
4572 76a66253 j_mayer
4573 76a66253 j_mayer
/* sreq */
4574 76a66253 j_mayer
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
4575 76a66253 j_mayer
{
4576 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4577 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4578 76a66253 j_mayer
    gen_op_POWER_sreq();
4579 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4580 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4581 76a66253 j_mayer
        gen_set_Rc0(ctx);
4582 76a66253 j_mayer
}
4583 76a66253 j_mayer
4584 76a66253 j_mayer
/* sriq */
4585 76a66253 j_mayer
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
4586 76a66253 j_mayer
{
4587 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4588 76a66253 j_mayer
    gen_op_set_T1(SH(ctx->opcode));
4589 76a66253 j_mayer
    gen_op_POWER_srq();
4590 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4591 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4592 76a66253 j_mayer
        gen_set_Rc0(ctx);
4593 76a66253 j_mayer
}
4594 76a66253 j_mayer
4595 76a66253 j_mayer
/* srliq */
4596 76a66253 j_mayer
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
4597 76a66253 j_mayer
{
4598 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4599 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4600 76a66253 j_mayer
    gen_op_set_T1(SH(ctx->opcode));
4601 76a66253 j_mayer
    gen_op_POWER_srlq();
4602 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4603 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4604 76a66253 j_mayer
        gen_set_Rc0(ctx);
4605 76a66253 j_mayer
}
4606 76a66253 j_mayer
4607 76a66253 j_mayer
/* srlq */
4608 76a66253 j_mayer
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
4609 76a66253 j_mayer
{
4610 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4611 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4612 76a66253 j_mayer
    gen_op_POWER_srlq();
4613 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4614 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4615 76a66253 j_mayer
        gen_set_Rc0(ctx);
4616 76a66253 j_mayer
}
4617 76a66253 j_mayer
4618 76a66253 j_mayer
/* srq */
4619 76a66253 j_mayer
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
4620 76a66253 j_mayer
{
4621 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
4622 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
4623 76a66253 j_mayer
    gen_op_POWER_srq();
4624 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
4625 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4626 76a66253 j_mayer
        gen_set_Rc0(ctx);
4627 76a66253 j_mayer
}
4628 76a66253 j_mayer
4629 76a66253 j_mayer
/* PowerPC 602 specific instructions */
4630 76a66253 j_mayer
/* dsa  */
4631 76a66253 j_mayer
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
4632 76a66253 j_mayer
{
4633 76a66253 j_mayer
    /* XXX: TODO */
4634 e1833e1f j_mayer
    GEN_EXCP_INVAL(ctx);
4635 76a66253 j_mayer
}
4636 76a66253 j_mayer
4637 76a66253 j_mayer
/* esa */
4638 76a66253 j_mayer
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
4639 76a66253 j_mayer
{
4640 76a66253 j_mayer
    /* XXX: TODO */
4641 e1833e1f j_mayer
    GEN_EXCP_INVAL(ctx);
4642 76a66253 j_mayer
}
4643 76a66253 j_mayer
4644 76a66253 j_mayer
/* mfrom */
4645 76a66253 j_mayer
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
4646 76a66253 j_mayer
{
4647 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4648 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4649 76a66253 j_mayer
#else
4650 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4651 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4652 76a66253 j_mayer
        return;
4653 76a66253 j_mayer
    }
4654 76a66253 j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
4655 76a66253 j_mayer
    gen_op_602_mfrom();
4656 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4657 76a66253 j_mayer
#endif
4658 76a66253 j_mayer
}
4659 76a66253 j_mayer
4660 76a66253 j_mayer
/* 602 - 603 - G2 TLB management */
4661 76a66253 j_mayer
/* tlbld */
4662 c7697e1f j_mayer
GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
4663 76a66253 j_mayer
{
4664 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4665 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4666 76a66253 j_mayer
#else
4667 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4668 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4669 76a66253 j_mayer
        return;
4670 76a66253 j_mayer
    }
4671 76a66253 j_mayer
    gen_op_load_gpr_T0(rB(ctx->opcode));
4672 76a66253 j_mayer
    gen_op_6xx_tlbld();
4673 76a66253 j_mayer
#endif
4674 76a66253 j_mayer
}
4675 76a66253 j_mayer
4676 76a66253 j_mayer
/* tlbli */
4677 c7697e1f j_mayer
GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
4678 76a66253 j_mayer
{
4679 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4680 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4681 76a66253 j_mayer
#else
4682 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4683 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4684 76a66253 j_mayer
        return;
4685 76a66253 j_mayer
    }
4686 76a66253 j_mayer
    gen_op_load_gpr_T0(rB(ctx->opcode));
4687 76a66253 j_mayer
    gen_op_6xx_tlbli();
4688 76a66253 j_mayer
#endif
4689 76a66253 j_mayer
}
4690 76a66253 j_mayer
4691 7dbe11ac j_mayer
/* 74xx TLB management */
4692 7dbe11ac j_mayer
/* tlbld */
4693 c7697e1f j_mayer
GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB)
4694 7dbe11ac j_mayer
{
4695 7dbe11ac j_mayer
#if defined(CONFIG_USER_ONLY)
4696 7dbe11ac j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4697 7dbe11ac j_mayer
#else
4698 7dbe11ac j_mayer
    if (unlikely(!ctx->supervisor)) {
4699 7dbe11ac j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4700 7dbe11ac j_mayer
        return;
4701 7dbe11ac j_mayer
    }
4702 7dbe11ac j_mayer
    gen_op_load_gpr_T0(rB(ctx->opcode));
4703 7dbe11ac j_mayer
    gen_op_74xx_tlbld();
4704 7dbe11ac j_mayer
#endif
4705 7dbe11ac j_mayer
}
4706 7dbe11ac j_mayer
4707 7dbe11ac j_mayer
/* tlbli */
4708 c7697e1f j_mayer
GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB)
4709 7dbe11ac j_mayer
{
4710 7dbe11ac j_mayer
#if defined(CONFIG_USER_ONLY)
4711 7dbe11ac j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4712 7dbe11ac j_mayer
#else
4713 7dbe11ac j_mayer
    if (unlikely(!ctx->supervisor)) {
4714 7dbe11ac j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4715 7dbe11ac j_mayer
        return;
4716 7dbe11ac j_mayer
    }
4717 7dbe11ac j_mayer
    gen_op_load_gpr_T0(rB(ctx->opcode));
4718 7dbe11ac j_mayer
    gen_op_74xx_tlbli();
4719 7dbe11ac j_mayer
#endif
4720 7dbe11ac j_mayer
}
4721 7dbe11ac j_mayer
4722 76a66253 j_mayer
/* POWER instructions not in PowerPC 601 */
4723 76a66253 j_mayer
/* clf */
4724 76a66253 j_mayer
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
4725 76a66253 j_mayer
{
4726 76a66253 j_mayer
    /* Cache line flush: implemented as no-op */
4727 76a66253 j_mayer
}
4728 76a66253 j_mayer
4729 76a66253 j_mayer
/* cli */
4730 76a66253 j_mayer
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
4731 76a66253 j_mayer
{
4732 7f75ffd3 blueswir1
    /* Cache line invalidate: privileged and treated as no-op */
4733 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4734 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4735 76a66253 j_mayer
#else
4736 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4737 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4738 76a66253 j_mayer
        return;
4739 76a66253 j_mayer
    }
4740 76a66253 j_mayer
#endif
4741 76a66253 j_mayer
}
4742 76a66253 j_mayer
4743 76a66253 j_mayer
/* dclst */
4744 76a66253 j_mayer
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
4745 76a66253 j_mayer
{
4746 76a66253 j_mayer
    /* Data cache line store: treated as no-op */
4747 76a66253 j_mayer
}
4748 76a66253 j_mayer
4749 76a66253 j_mayer
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
4750 76a66253 j_mayer
{
4751 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4752 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4753 76a66253 j_mayer
#else
4754 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4755 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4756 76a66253 j_mayer
        return;
4757 76a66253 j_mayer
    }
4758 76a66253 j_mayer
    int ra = rA(ctx->opcode);
4759 76a66253 j_mayer
    int rd = rD(ctx->opcode);
4760 76a66253 j_mayer
4761 76a66253 j_mayer
    gen_addr_reg_index(ctx);
4762 76a66253 j_mayer
    gen_op_POWER_mfsri();
4763 76a66253 j_mayer
    gen_op_store_T0_gpr(rd);
4764 76a66253 j_mayer
    if (ra != 0 && ra != rd)
4765 76a66253 j_mayer
        gen_op_store_T1_gpr(ra);
4766 76a66253 j_mayer
#endif
4767 76a66253 j_mayer
}
4768 76a66253 j_mayer
4769 76a66253 j_mayer
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
4770 76a66253 j_mayer
{
4771 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4772 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4773 76a66253 j_mayer
#else
4774 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4775 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4776 76a66253 j_mayer
        return;
4777 76a66253 j_mayer
    }
4778 76a66253 j_mayer
    gen_addr_reg_index(ctx);
4779 76a66253 j_mayer
    gen_op_POWER_rac();
4780 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
4781 76a66253 j_mayer
#endif
4782 76a66253 j_mayer
}
4783 76a66253 j_mayer
4784 76a66253 j_mayer
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
4785 76a66253 j_mayer
{
4786 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4787 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4788 76a66253 j_mayer
#else
4789 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4790 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4791 76a66253 j_mayer
        return;
4792 76a66253 j_mayer
    }
4793 76a66253 j_mayer
    gen_op_POWER_rfsvc();
4794 e1833e1f j_mayer
    GEN_SYNC(ctx);
4795 76a66253 j_mayer
#endif
4796 76a66253 j_mayer
}
4797 76a66253 j_mayer
4798 76a66253 j_mayer
/* svc is not implemented for now */
4799 76a66253 j_mayer
4800 76a66253 j_mayer
/* POWER2 specific instructions */
4801 76a66253 j_mayer
/* Quad manipulation (load/store two floats at a time) */
4802 76a66253 j_mayer
#define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
4803 76a66253 j_mayer
#define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
4804 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4805 76a66253 j_mayer
static GenOpFunc *gen_op_POWER2_lfq[] = {
4806 76a66253 j_mayer
    &gen_op_POWER2_lfq_le_raw,
4807 76a66253 j_mayer
    &gen_op_POWER2_lfq_raw,
4808 76a66253 j_mayer
};
4809 76a66253 j_mayer
static GenOpFunc *gen_op_POWER2_stfq[] = {
4810 76a66253 j_mayer
    &gen_op_POWER2_stfq_le_raw,
4811 76a66253 j_mayer
    &gen_op_POWER2_stfq_raw,
4812 76a66253 j_mayer
};
4813 76a66253 j_mayer
#else
4814 76a66253 j_mayer
static GenOpFunc *gen_op_POWER2_lfq[] = {
4815 76a66253 j_mayer
    &gen_op_POWER2_lfq_le_user,
4816 76a66253 j_mayer
    &gen_op_POWER2_lfq_user,
4817 76a66253 j_mayer
    &gen_op_POWER2_lfq_le_kernel,
4818 76a66253 j_mayer
    &gen_op_POWER2_lfq_kernel,
4819 76a66253 j_mayer
};
4820 76a66253 j_mayer
static GenOpFunc *gen_op_POWER2_stfq[] = {
4821 76a66253 j_mayer
    &gen_op_POWER2_stfq_le_user,
4822 76a66253 j_mayer
    &gen_op_POWER2_stfq_user,
4823 76a66253 j_mayer
    &gen_op_POWER2_stfq_le_kernel,
4824 76a66253 j_mayer
    &gen_op_POWER2_stfq_kernel,
4825 76a66253 j_mayer
};
4826 76a66253 j_mayer
#endif
4827 76a66253 j_mayer
4828 76a66253 j_mayer
/* lfq */
4829 76a66253 j_mayer
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4830 76a66253 j_mayer
{
4831 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
4832 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
4833 9d53c753 j_mayer
    gen_addr_imm_index(ctx, 0);
4834 76a66253 j_mayer
    op_POWER2_lfq();
4835 76a66253 j_mayer
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4836 76a66253 j_mayer
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4837 76a66253 j_mayer
}
4838 76a66253 j_mayer
4839 76a66253 j_mayer
/* lfqu */
4840 76a66253 j_mayer
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4841 76a66253 j_mayer
{
4842 76a66253 j_mayer
    int ra = rA(ctx->opcode);
4843 76a66253 j_mayer
4844 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
4845 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
4846 9d53c753 j_mayer
    gen_addr_imm_index(ctx, 0);
4847 76a66253 j_mayer
    op_POWER2_lfq();
4848 76a66253 j_mayer
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4849 76a66253 j_mayer
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4850 76a66253 j_mayer
    if (ra != 0)
4851 76a66253 j_mayer
        gen_op_store_T0_gpr(ra);
4852 76a66253 j_mayer
}
4853 76a66253 j_mayer
4854 76a66253 j_mayer
/* lfqux */
4855 76a66253 j_mayer
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
4856 76a66253 j_mayer
{
4857 76a66253 j_mayer
    int ra = rA(ctx->opcode);
4858 76a66253 j_mayer
4859 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
4860 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
4861 76a66253 j_mayer
    gen_addr_reg_index(ctx);
4862 76a66253 j_mayer
    op_POWER2_lfq();
4863 76a66253 j_mayer
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4864 76a66253 j_mayer
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4865 76a66253 j_mayer
    if (ra != 0)
4866 76a66253 j_mayer
        gen_op_store_T0_gpr(ra);
4867 76a66253 j_mayer
}
4868 76a66253 j_mayer
4869 76a66253 j_mayer
/* lfqx */
4870 76a66253 j_mayer
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
4871 76a66253 j_mayer
{
4872 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
4873 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
4874 76a66253 j_mayer
    gen_addr_reg_index(ctx);
4875 76a66253 j_mayer
    op_POWER2_lfq();
4876 76a66253 j_mayer
    gen_op_store_FT0_fpr(rD(ctx->opcode));
4877 76a66253 j_mayer
    gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
4878 76a66253 j_mayer
}
4879 76a66253 j_mayer
4880 76a66253 j_mayer
/* stfq */
4881 76a66253 j_mayer
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4882 76a66253 j_mayer
{
4883 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
4884 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
4885 9d53c753 j_mayer
    gen_addr_imm_index(ctx, 0);
4886 76a66253 j_mayer
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4887 76a66253 j_mayer
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4888 76a66253 j_mayer
    op_POWER2_stfq();
4889 76a66253 j_mayer
}
4890 76a66253 j_mayer
4891 76a66253 j_mayer
/* stfqu */
4892 76a66253 j_mayer
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4893 76a66253 j_mayer
{
4894 76a66253 j_mayer
    int ra = rA(ctx->opcode);
4895 76a66253 j_mayer
4896 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
4897 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
4898 9d53c753 j_mayer
    gen_addr_imm_index(ctx, 0);
4899 76a66253 j_mayer
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4900 76a66253 j_mayer
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4901 76a66253 j_mayer
    op_POWER2_stfq();
4902 76a66253 j_mayer
    if (ra != 0)
4903 76a66253 j_mayer
        gen_op_store_T0_gpr(ra);
4904 76a66253 j_mayer
}
4905 76a66253 j_mayer
4906 76a66253 j_mayer
/* stfqux */
4907 76a66253 j_mayer
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
4908 76a66253 j_mayer
{
4909 76a66253 j_mayer
    int ra = rA(ctx->opcode);
4910 76a66253 j_mayer
4911 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
4912 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
4913 76a66253 j_mayer
    gen_addr_reg_index(ctx);
4914 76a66253 j_mayer
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4915 76a66253 j_mayer
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4916 76a66253 j_mayer
    op_POWER2_stfq();
4917 76a66253 j_mayer
    if (ra != 0)
4918 76a66253 j_mayer
        gen_op_store_T0_gpr(ra);
4919 76a66253 j_mayer
}
4920 76a66253 j_mayer
4921 76a66253 j_mayer
/* stfqx */
4922 76a66253 j_mayer
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
4923 76a66253 j_mayer
{
4924 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
4925 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
4926 76a66253 j_mayer
    gen_addr_reg_index(ctx);
4927 76a66253 j_mayer
    gen_op_load_fpr_FT0(rS(ctx->opcode));
4928 76a66253 j_mayer
    gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4929 76a66253 j_mayer
    op_POWER2_stfq();
4930 76a66253 j_mayer
}
4931 76a66253 j_mayer
4932 76a66253 j_mayer
/* BookE specific instructions */
4933 2662a059 j_mayer
/* XXX: not implemented on 440 ? */
4934 a750fc0b j_mayer
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE_EXT)
4935 76a66253 j_mayer
{
4936 76a66253 j_mayer
    /* XXX: TODO */
4937 e1833e1f j_mayer
    GEN_EXCP_INVAL(ctx);
4938 76a66253 j_mayer
}
4939 76a66253 j_mayer
4940 2662a059 j_mayer
/* XXX: not implemented on 440 ? */
4941 a750fc0b j_mayer
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE_EXT)
4942 76a66253 j_mayer
{
4943 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4944 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
4945 76a66253 j_mayer
#else
4946 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
4947 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
4948 76a66253 j_mayer
        return;
4949 76a66253 j_mayer
    }
4950 76a66253 j_mayer
    gen_addr_reg_index(ctx);
4951 76a66253 j_mayer
    /* Use the same micro-ops as for tlbie */
4952 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
4953 d9bce9d9 j_mayer
    if (ctx->sf_mode)
4954 d9bce9d9 j_mayer
        gen_op_tlbie_64();
4955 d9bce9d9 j_mayer
    else
4956 d9bce9d9 j_mayer
#endif
4957 d9bce9d9 j_mayer
        gen_op_tlbie();
4958 76a66253 j_mayer
#endif
4959 76a66253 j_mayer
}
4960 76a66253 j_mayer
4961 76a66253 j_mayer
/* All 405 MAC instructions are translated here */
4962 b068d6a7 j_mayer
static always_inline void gen_405_mulladd_insn (DisasContext *ctx,
4963 b068d6a7 j_mayer
                                                int opc2, int opc3,
4964 b068d6a7 j_mayer
                                                int ra, int rb, int rt, int Rc)
4965 76a66253 j_mayer
{
4966 76a66253 j_mayer
    gen_op_load_gpr_T0(ra);
4967 76a66253 j_mayer
    gen_op_load_gpr_T1(rb);
4968 76a66253 j_mayer
    switch (opc3 & 0x0D) {
4969 76a66253 j_mayer
    case 0x05:
4970 76a66253 j_mayer
        /* macchw    - macchw.    - macchwo   - macchwo.   */
4971 76a66253 j_mayer
        /* macchws   - macchws.   - macchwso  - macchwso.  */
4972 76a66253 j_mayer
        /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
4973 76a66253 j_mayer
        /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
4974 76a66253 j_mayer
        /* mulchw - mulchw. */
4975 76a66253 j_mayer
        gen_op_405_mulchw();
4976 76a66253 j_mayer
        break;
4977 76a66253 j_mayer
    case 0x04:
4978 76a66253 j_mayer
        /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
4979 76a66253 j_mayer
        /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
4980 76a66253 j_mayer
        /* mulchwu - mulchwu. */
4981 76a66253 j_mayer
        gen_op_405_mulchwu();
4982 76a66253 j_mayer
        break;
4983 76a66253 j_mayer
    case 0x01:
4984 76a66253 j_mayer
        /* machhw    - machhw.    - machhwo   - machhwo.   */
4985 76a66253 j_mayer
        /* machhws   - machhws.   - machhwso  - machhwso.  */
4986 76a66253 j_mayer
        /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
4987 76a66253 j_mayer
        /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
4988 76a66253 j_mayer
        /* mulhhw - mulhhw. */
4989 76a66253 j_mayer
        gen_op_405_mulhhw();
4990 76a66253 j_mayer
        break;
4991 76a66253 j_mayer
    case 0x00:
4992 76a66253 j_mayer
        /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
4993 76a66253 j_mayer
        /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
4994 76a66253 j_mayer
        /* mulhhwu - mulhhwu. */
4995 76a66253 j_mayer
        gen_op_405_mulhhwu();
4996 76a66253 j_mayer
        break;
4997 76a66253 j_mayer
    case 0x0D:
4998 76a66253 j_mayer
        /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
4999 76a66253 j_mayer
        /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
5000 76a66253 j_mayer
        /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
5001 76a66253 j_mayer
        /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
5002 76a66253 j_mayer
        /* mullhw - mullhw. */
5003 76a66253 j_mayer
        gen_op_405_mullhw();
5004 76a66253 j_mayer
        break;
5005 76a66253 j_mayer
    case 0x0C:
5006 76a66253 j_mayer
        /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
5007 76a66253 j_mayer
        /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
5008 76a66253 j_mayer
        /* mullhwu - mullhwu. */
5009 76a66253 j_mayer
        gen_op_405_mullhwu();
5010 76a66253 j_mayer
        break;
5011 76a66253 j_mayer
    }
5012 76a66253 j_mayer
    if (opc2 & 0x02) {
5013 76a66253 j_mayer
        /* nmultiply-and-accumulate (0x0E) */
5014 76a66253 j_mayer
        gen_op_neg();
5015 76a66253 j_mayer
    }
5016 76a66253 j_mayer
    if (opc2 & 0x04) {
5017 76a66253 j_mayer
        /* (n)multiply-and-accumulate (0x0C - 0x0E) */
5018 76a66253 j_mayer
        gen_op_load_gpr_T2(rt);
5019 76a66253 j_mayer
        gen_op_move_T1_T0();
5020 76a66253 j_mayer
        gen_op_405_add_T0_T2();
5021 76a66253 j_mayer
    }
5022 76a66253 j_mayer
    if (opc3 & 0x10) {
5023 76a66253 j_mayer
        /* Check overflow */
5024 76a66253 j_mayer
        if (opc3 & 0x01)
5025 76a66253 j_mayer
            gen_op_405_check_ov();
5026 76a66253 j_mayer
        else
5027 76a66253 j_mayer
            gen_op_405_check_ovu();
5028 76a66253 j_mayer
    }
5029 76a66253 j_mayer
    if (opc3 & 0x02) {
5030 76a66253 j_mayer
        /* Saturate */
5031 76a66253 j_mayer
        if (opc3 & 0x01)
5032 76a66253 j_mayer
            gen_op_405_check_sat();
5033 76a66253 j_mayer
        else
5034 76a66253 j_mayer
            gen_op_405_check_satu();
5035 76a66253 j_mayer
    }
5036 76a66253 j_mayer
    gen_op_store_T0_gpr(rt);
5037 76a66253 j_mayer
    if (unlikely(Rc) != 0) {
5038 76a66253 j_mayer
        /* Update Rc0 */
5039 76a66253 j_mayer
        gen_set_Rc0(ctx);
5040 76a66253 j_mayer
    }
5041 76a66253 j_mayer
}
5042 76a66253 j_mayer
5043 a750fc0b j_mayer
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
5044 a750fc0b j_mayer
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
5045 76a66253 j_mayer
{                                                                             \
5046 76a66253 j_mayer
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
5047 76a66253 j_mayer
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
5048 76a66253 j_mayer
}
5049 76a66253 j_mayer
5050 76a66253 j_mayer
/* macchw    - macchw.    */
5051 a750fc0b j_mayer
GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
5052 76a66253 j_mayer
/* macchwo   - macchwo.   */
5053 a750fc0b j_mayer
GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
5054 76a66253 j_mayer
/* macchws   - macchws.   */
5055 a750fc0b j_mayer
GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
5056 76a66253 j_mayer
/* macchwso  - macchwso.  */
5057 a750fc0b j_mayer
GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
5058 76a66253 j_mayer
/* macchwsu  - macchwsu.  */
5059 a750fc0b j_mayer
GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
5060 76a66253 j_mayer
/* macchwsuo - macchwsuo. */
5061 a750fc0b j_mayer
GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
5062 76a66253 j_mayer
/* macchwu   - macchwu.   */
5063 a750fc0b j_mayer
GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
5064 76a66253 j_mayer
/* macchwuo  - macchwuo.  */
5065 a750fc0b j_mayer
GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
5066 76a66253 j_mayer
/* machhw    - machhw.    */
5067 a750fc0b j_mayer
GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
5068 76a66253 j_mayer
/* machhwo   - machhwo.   */
5069 a750fc0b j_mayer
GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
5070 76a66253 j_mayer
/* machhws   - machhws.   */
5071 a750fc0b j_mayer
GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
5072 76a66253 j_mayer
/* machhwso  - machhwso.  */
5073 a750fc0b j_mayer
GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
5074 76a66253 j_mayer
/* machhwsu  - machhwsu.  */
5075 a750fc0b j_mayer
GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
5076 76a66253 j_mayer
/* machhwsuo - machhwsuo. */
5077 a750fc0b j_mayer
GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
5078 76a66253 j_mayer
/* machhwu   - machhwu.   */
5079 a750fc0b j_mayer
GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
5080 76a66253 j_mayer
/* machhwuo  - machhwuo.  */
5081 a750fc0b j_mayer
GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
5082 76a66253 j_mayer
/* maclhw    - maclhw.    */
5083 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
5084 76a66253 j_mayer
/* maclhwo   - maclhwo.   */
5085 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
5086 76a66253 j_mayer
/* maclhws   - maclhws.   */
5087 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
5088 76a66253 j_mayer
/* maclhwso  - maclhwso.  */
5089 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
5090 76a66253 j_mayer
/* maclhwu   - maclhwu.   */
5091 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
5092 76a66253 j_mayer
/* maclhwuo  - maclhwuo.  */
5093 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
5094 76a66253 j_mayer
/* maclhwsu  - maclhwsu.  */
5095 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
5096 76a66253 j_mayer
/* maclhwsuo - maclhwsuo. */
5097 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
5098 76a66253 j_mayer
/* nmacchw   - nmacchw.   */
5099 a750fc0b j_mayer
GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
5100 76a66253 j_mayer
/* nmacchwo  - nmacchwo.  */
5101 a750fc0b j_mayer
GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
5102 76a66253 j_mayer
/* nmacchws  - nmacchws.  */
5103 a750fc0b j_mayer
GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
5104 76a66253 j_mayer
/* nmacchwso - nmacchwso. */
5105 a750fc0b j_mayer
GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
5106 76a66253 j_mayer
/* nmachhw   - nmachhw.   */
5107 a750fc0b j_mayer
GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
5108 76a66253 j_mayer
/* nmachhwo  - nmachhwo.  */
5109 a750fc0b j_mayer
GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
5110 76a66253 j_mayer
/* nmachhws  - nmachhws.  */
5111 a750fc0b j_mayer
GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
5112 76a66253 j_mayer
/* nmachhwso - nmachhwso. */
5113 a750fc0b j_mayer
GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
5114 76a66253 j_mayer
/* nmaclhw   - nmaclhw.   */
5115 a750fc0b j_mayer
GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
5116 76a66253 j_mayer
/* nmaclhwo  - nmaclhwo.  */
5117 a750fc0b j_mayer
GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
5118 76a66253 j_mayer
/* nmaclhws  - nmaclhws.  */
5119 a750fc0b j_mayer
GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
5120 76a66253 j_mayer
/* nmaclhwso - nmaclhwso. */
5121 a750fc0b j_mayer
GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
5122 76a66253 j_mayer
5123 76a66253 j_mayer
/* mulchw  - mulchw.  */
5124 a750fc0b j_mayer
GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
5125 76a66253 j_mayer
/* mulchwu - mulchwu. */
5126 a750fc0b j_mayer
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
5127 76a66253 j_mayer
/* mulhhw  - mulhhw.  */
5128 a750fc0b j_mayer
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
5129 76a66253 j_mayer
/* mulhhwu - mulhhwu. */
5130 a750fc0b j_mayer
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
5131 76a66253 j_mayer
/* mullhw  - mullhw.  */
5132 a750fc0b j_mayer
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
5133 76a66253 j_mayer
/* mullhwu - mullhwu. */
5134 a750fc0b j_mayer
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
5135 76a66253 j_mayer
5136 76a66253 j_mayer
/* mfdcr */
5137 76a66253 j_mayer
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON)
5138 76a66253 j_mayer
{
5139 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5140 e1833e1f j_mayer
    GEN_EXCP_PRIVREG(ctx);
5141 76a66253 j_mayer
#else
5142 76a66253 j_mayer
    uint32_t dcrn = SPR(ctx->opcode);
5143 76a66253 j_mayer
5144 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
5145 e1833e1f j_mayer
        GEN_EXCP_PRIVREG(ctx);
5146 76a66253 j_mayer
        return;
5147 76a66253 j_mayer
    }
5148 a42bd6cc j_mayer
    gen_op_set_T0(dcrn);
5149 a42bd6cc j_mayer
    gen_op_load_dcr();
5150 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
5151 76a66253 j_mayer
#endif
5152 76a66253 j_mayer
}
5153 76a66253 j_mayer
5154 76a66253 j_mayer
/* mtdcr */
5155 76a66253 j_mayer
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON)
5156 76a66253 j_mayer
{
5157 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5158 e1833e1f j_mayer
    GEN_EXCP_PRIVREG(ctx);
5159 76a66253 j_mayer
#else
5160 76a66253 j_mayer
    uint32_t dcrn = SPR(ctx->opcode);
5161 76a66253 j_mayer
5162 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
5163 e1833e1f j_mayer
        GEN_EXCP_PRIVREG(ctx);
5164 76a66253 j_mayer
        return;
5165 76a66253 j_mayer
    }
5166 a42bd6cc j_mayer
    gen_op_set_T0(dcrn);
5167 a42bd6cc j_mayer
    gen_op_load_gpr_T1(rS(ctx->opcode));
5168 a42bd6cc j_mayer
    gen_op_store_dcr();
5169 a42bd6cc j_mayer
#endif
5170 a42bd6cc j_mayer
}
5171 a42bd6cc j_mayer
5172 a42bd6cc j_mayer
/* mfdcrx */
5173 2662a059 j_mayer
/* XXX: not implemented on 440 ? */
5174 a750fc0b j_mayer
GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_BOOKE_EXT)
5175 a42bd6cc j_mayer
{
5176 a42bd6cc j_mayer
#if defined(CONFIG_USER_ONLY)
5177 e1833e1f j_mayer
    GEN_EXCP_PRIVREG(ctx);
5178 a42bd6cc j_mayer
#else
5179 a42bd6cc j_mayer
    if (unlikely(!ctx->supervisor)) {
5180 e1833e1f j_mayer
        GEN_EXCP_PRIVREG(ctx);
5181 a42bd6cc j_mayer
        return;
5182 a42bd6cc j_mayer
    }
5183 a42bd6cc j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
5184 a42bd6cc j_mayer
    gen_op_load_dcr();
5185 a42bd6cc j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
5186 a750fc0b j_mayer
    /* Note: Rc update flag set leads to undefined state of Rc0 */
5187 a42bd6cc j_mayer
#endif
5188 a42bd6cc j_mayer
}
5189 a42bd6cc j_mayer
5190 a42bd6cc j_mayer
/* mtdcrx */
5191 2662a059 j_mayer
/* XXX: not implemented on 440 ? */
5192 a750fc0b j_mayer
GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_BOOKE_EXT)
5193 a42bd6cc j_mayer
{
5194 a42bd6cc j_mayer
#if defined(CONFIG_USER_ONLY)
5195 e1833e1f j_mayer
    GEN_EXCP_PRIVREG(ctx);
5196 a42bd6cc j_mayer
#else
5197 a42bd6cc j_mayer
    if (unlikely(!ctx->supervisor)) {
5198 e1833e1f j_mayer
        GEN_EXCP_PRIVREG(ctx);
5199 a42bd6cc j_mayer
        return;
5200 a42bd6cc j_mayer
    }
5201 a42bd6cc j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
5202 a42bd6cc j_mayer
    gen_op_load_gpr_T1(rS(ctx->opcode));
5203 a42bd6cc j_mayer
    gen_op_store_dcr();
5204 a750fc0b j_mayer
    /* Note: Rc update flag set leads to undefined state of Rc0 */
5205 76a66253 j_mayer
#endif
5206 76a66253 j_mayer
}
5207 76a66253 j_mayer
5208 a750fc0b j_mayer
/* mfdcrux (PPC 460) : user-mode access to DCR */
5209 a750fc0b j_mayer
GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX)
5210 a750fc0b j_mayer
{
5211 a750fc0b j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
5212 a750fc0b j_mayer
    gen_op_load_dcr();
5213 a750fc0b j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
5214 a750fc0b j_mayer
    /* Note: Rc update flag set leads to undefined state of Rc0 */
5215 a750fc0b j_mayer
}
5216 a750fc0b j_mayer
5217 a750fc0b j_mayer
/* mtdcrux (PPC 460) : user-mode access to DCR */
5218 a750fc0b j_mayer
GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
5219 a750fc0b j_mayer
{
5220 a750fc0b j_mayer
    gen_op_load_gpr_T0(rA(ctx->opcode));
5221 a750fc0b j_mayer
    gen_op_load_gpr_T1(rS(ctx->opcode));
5222 a750fc0b j_mayer
    gen_op_store_dcr();
5223 a750fc0b j_mayer
    /* Note: Rc update flag set leads to undefined state of Rc0 */
5224 a750fc0b j_mayer
}
5225 a750fc0b j_mayer
5226 76a66253 j_mayer
/* dccci */
5227 76a66253 j_mayer
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
5228 76a66253 j_mayer
{
5229 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5230 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5231 76a66253 j_mayer
#else
5232 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
5233 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5234 76a66253 j_mayer
        return;
5235 76a66253 j_mayer
    }
5236 76a66253 j_mayer
    /* interpreted as no-op */
5237 76a66253 j_mayer
#endif
5238 76a66253 j_mayer
}
5239 76a66253 j_mayer
5240 76a66253 j_mayer
/* dcread */
5241 76a66253 j_mayer
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
5242 76a66253 j_mayer
{
5243 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5244 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5245 76a66253 j_mayer
#else
5246 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
5247 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5248 76a66253 j_mayer
        return;
5249 76a66253 j_mayer
    }
5250 76a66253 j_mayer
    gen_addr_reg_index(ctx);
5251 76a66253 j_mayer
    op_ldst(lwz);
5252 76a66253 j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
5253 76a66253 j_mayer
#endif
5254 76a66253 j_mayer
}
5255 76a66253 j_mayer
5256 76a66253 j_mayer
/* icbt */
5257 c7697e1f j_mayer
GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
5258 76a66253 j_mayer
{
5259 76a66253 j_mayer
    /* interpreted as no-op */
5260 76a66253 j_mayer
    /* XXX: specification say this is treated as a load by the MMU
5261 76a66253 j_mayer
     *      but does not generate any exception
5262 76a66253 j_mayer
     */
5263 76a66253 j_mayer
}
5264 76a66253 j_mayer
5265 76a66253 j_mayer
/* iccci */
5266 76a66253 j_mayer
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
5267 76a66253 j_mayer
{
5268 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5269 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5270 76a66253 j_mayer
#else
5271 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
5272 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5273 76a66253 j_mayer
        return;
5274 76a66253 j_mayer
    }
5275 76a66253 j_mayer
    /* interpreted as no-op */
5276 76a66253 j_mayer
#endif
5277 76a66253 j_mayer
}
5278 76a66253 j_mayer
5279 76a66253 j_mayer
/* icread */
5280 76a66253 j_mayer
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
5281 76a66253 j_mayer
{
5282 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5283 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5284 76a66253 j_mayer
#else
5285 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
5286 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5287 76a66253 j_mayer
        return;
5288 76a66253 j_mayer
    }
5289 76a66253 j_mayer
    /* interpreted as no-op */
5290 76a66253 j_mayer
#endif
5291 76a66253 j_mayer
}
5292 76a66253 j_mayer
5293 76a66253 j_mayer
/* rfci (supervisor only) */
5294 c7697e1f j_mayer
GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP)
5295 a42bd6cc j_mayer
{
5296 a42bd6cc j_mayer
#if defined(CONFIG_USER_ONLY)
5297 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5298 a42bd6cc j_mayer
#else
5299 a42bd6cc j_mayer
    if (unlikely(!ctx->supervisor)) {
5300 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5301 a42bd6cc j_mayer
        return;
5302 a42bd6cc j_mayer
    }
5303 a42bd6cc j_mayer
    /* Restore CPU state */
5304 a42bd6cc j_mayer
    gen_op_40x_rfci();
5305 e1833e1f j_mayer
    GEN_SYNC(ctx);
5306 a42bd6cc j_mayer
#endif
5307 a42bd6cc j_mayer
}
5308 a42bd6cc j_mayer
5309 a42bd6cc j_mayer
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
5310 a42bd6cc j_mayer
{
5311 a42bd6cc j_mayer
#if defined(CONFIG_USER_ONLY)
5312 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5313 a42bd6cc j_mayer
#else
5314 a42bd6cc j_mayer
    if (unlikely(!ctx->supervisor)) {
5315 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5316 a42bd6cc j_mayer
        return;
5317 a42bd6cc j_mayer
    }
5318 a42bd6cc j_mayer
    /* Restore CPU state */
5319 a42bd6cc j_mayer
    gen_op_rfci();
5320 e1833e1f j_mayer
    GEN_SYNC(ctx);
5321 a42bd6cc j_mayer
#endif
5322 a42bd6cc j_mayer
}
5323 a42bd6cc j_mayer
5324 a42bd6cc j_mayer
/* BookE specific */
5325 2662a059 j_mayer
/* XXX: not implemented on 440 ? */
5326 a750fc0b j_mayer
GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_BOOKE_EXT)
5327 76a66253 j_mayer
{
5328 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5329 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5330 76a66253 j_mayer
#else
5331 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
5332 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5333 76a66253 j_mayer
        return;
5334 76a66253 j_mayer
    }
5335 76a66253 j_mayer
    /* Restore CPU state */
5336 a42bd6cc j_mayer
    gen_op_rfdi();
5337 e1833e1f j_mayer
    GEN_SYNC(ctx);
5338 76a66253 j_mayer
#endif
5339 76a66253 j_mayer
}
5340 76a66253 j_mayer
5341 2662a059 j_mayer
/* XXX: not implemented on 440 ? */
5342 a750fc0b j_mayer
GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
5343 a42bd6cc j_mayer
{
5344 a42bd6cc j_mayer
#if defined(CONFIG_USER_ONLY)
5345 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5346 a42bd6cc j_mayer
#else
5347 a42bd6cc j_mayer
    if (unlikely(!ctx->supervisor)) {
5348 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5349 a42bd6cc j_mayer
        return;
5350 a42bd6cc j_mayer
    }
5351 a42bd6cc j_mayer
    /* Restore CPU state */
5352 a42bd6cc j_mayer
    gen_op_rfmci();
5353 e1833e1f j_mayer
    GEN_SYNC(ctx);
5354 a42bd6cc j_mayer
#endif
5355 a42bd6cc j_mayer
}
5356 5eb7995e j_mayer
5357 d9bce9d9 j_mayer
/* TLB management - PowerPC 405 implementation */
5358 76a66253 j_mayer
/* tlbre */
5359 c7697e1f j_mayer
GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
5360 76a66253 j_mayer
{
5361 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5362 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5363 76a66253 j_mayer
#else
5364 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
5365 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5366 76a66253 j_mayer
        return;
5367 76a66253 j_mayer
    }
5368 76a66253 j_mayer
    switch (rB(ctx->opcode)) {
5369 76a66253 j_mayer
    case 0:
5370 9a64fbe4 bellard
        gen_op_load_gpr_T0(rA(ctx->opcode));
5371 76a66253 j_mayer
        gen_op_4xx_tlbre_hi();
5372 76a66253 j_mayer
        gen_op_store_T0_gpr(rD(ctx->opcode));
5373 76a66253 j_mayer
        break;
5374 76a66253 j_mayer
    case 1:
5375 76a66253 j_mayer
        gen_op_load_gpr_T0(rA(ctx->opcode));
5376 76a66253 j_mayer
        gen_op_4xx_tlbre_lo();
5377 76a66253 j_mayer
        gen_op_store_T0_gpr(rD(ctx->opcode));
5378 76a66253 j_mayer
        break;
5379 76a66253 j_mayer
    default:
5380 e1833e1f j_mayer
        GEN_EXCP_INVAL(ctx);
5381 76a66253 j_mayer
        break;
5382 9a64fbe4 bellard
    }
5383 76a66253 j_mayer
#endif
5384 76a66253 j_mayer
}
5385 76a66253 j_mayer
5386 d9bce9d9 j_mayer
/* tlbsx - tlbsx. */
5387 c7697e1f j_mayer
GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
5388 76a66253 j_mayer
{
5389 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5390 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5391 76a66253 j_mayer
#else
5392 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
5393 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5394 76a66253 j_mayer
        return;
5395 76a66253 j_mayer
    }
5396 76a66253 j_mayer
    gen_addr_reg_index(ctx);
5397 daf4f96e j_mayer
    gen_op_4xx_tlbsx();
5398 76a66253 j_mayer
    if (Rc(ctx->opcode))
5399 daf4f96e j_mayer
        gen_op_4xx_tlbsx_check();
5400 9a64fbe4 bellard
    gen_op_store_T0_gpr(rD(ctx->opcode));
5401 76a66253 j_mayer
#endif
5402 79aceca5 bellard
}
5403 79aceca5 bellard
5404 76a66253 j_mayer
/* tlbwe */
5405 c7697e1f j_mayer
GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
5406 79aceca5 bellard
{
5407 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5408 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5409 76a66253 j_mayer
#else
5410 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
5411 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5412 76a66253 j_mayer
        return;
5413 76a66253 j_mayer
    }
5414 76a66253 j_mayer
    switch (rB(ctx->opcode)) {
5415 76a66253 j_mayer
    case 0:
5416 9a64fbe4 bellard
        gen_op_load_gpr_T0(rA(ctx->opcode));
5417 76a66253 j_mayer
        gen_op_load_gpr_T1(rS(ctx->opcode));
5418 76a66253 j_mayer
        gen_op_4xx_tlbwe_hi();
5419 76a66253 j_mayer
        break;
5420 76a66253 j_mayer
    case 1:
5421 76a66253 j_mayer
        gen_op_load_gpr_T0(rA(ctx->opcode));
5422 76a66253 j_mayer
        gen_op_load_gpr_T1(rS(ctx->opcode));
5423 76a66253 j_mayer
        gen_op_4xx_tlbwe_lo();
5424 76a66253 j_mayer
        break;
5425 76a66253 j_mayer
    default:
5426 e1833e1f j_mayer
        GEN_EXCP_INVAL(ctx);
5427 76a66253 j_mayer
        break;
5428 9a64fbe4 bellard
    }
5429 76a66253 j_mayer
#endif
5430 76a66253 j_mayer
}
5431 76a66253 j_mayer
5432 a4bb6c3e j_mayer
/* TLB management - PowerPC 440 implementation */
5433 5eb7995e j_mayer
/* tlbre */
5434 c7697e1f j_mayer
GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
5435 5eb7995e j_mayer
{
5436 5eb7995e j_mayer
#if defined(CONFIG_USER_ONLY)
5437 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5438 5eb7995e j_mayer
#else
5439 5eb7995e j_mayer
    if (unlikely(!ctx->supervisor)) {
5440 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5441 5eb7995e j_mayer
        return;
5442 5eb7995e j_mayer
    }
5443 5eb7995e j_mayer
    switch (rB(ctx->opcode)) {
5444 5eb7995e j_mayer
    case 0:
5445 5eb7995e j_mayer
    case 1:
5446 5eb7995e j_mayer
    case 2:
5447 5eb7995e j_mayer
        gen_op_load_gpr_T0(rA(ctx->opcode));
5448 a4bb6c3e j_mayer
        gen_op_440_tlbre(rB(ctx->opcode));
5449 5eb7995e j_mayer
        gen_op_store_T0_gpr(rD(ctx->opcode));
5450 5eb7995e j_mayer
        break;
5451 5eb7995e j_mayer
    default:
5452 e1833e1f j_mayer
        GEN_EXCP_INVAL(ctx);
5453 5eb7995e j_mayer
        break;
5454 5eb7995e j_mayer
    }
5455 5eb7995e j_mayer
#endif
5456 5eb7995e j_mayer
}
5457 5eb7995e j_mayer
5458 5eb7995e j_mayer
/* tlbsx - tlbsx. */
5459 c7697e1f j_mayer
GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
5460 5eb7995e j_mayer
{
5461 5eb7995e j_mayer
#if defined(CONFIG_USER_ONLY)
5462 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5463 5eb7995e j_mayer
#else
5464 5eb7995e j_mayer
    if (unlikely(!ctx->supervisor)) {
5465 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5466 5eb7995e j_mayer
        return;
5467 5eb7995e j_mayer
    }
5468 5eb7995e j_mayer
    gen_addr_reg_index(ctx);
5469 daf4f96e j_mayer
    gen_op_440_tlbsx();
5470 5eb7995e j_mayer
    if (Rc(ctx->opcode))
5471 daf4f96e j_mayer
        gen_op_4xx_tlbsx_check();
5472 5eb7995e j_mayer
    gen_op_store_T0_gpr(rD(ctx->opcode));
5473 5eb7995e j_mayer
#endif
5474 5eb7995e j_mayer
}
5475 5eb7995e j_mayer
5476 5eb7995e j_mayer
/* tlbwe */
5477 c7697e1f j_mayer
GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
5478 5eb7995e j_mayer
{
5479 5eb7995e j_mayer
#if defined(CONFIG_USER_ONLY)
5480 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5481 5eb7995e j_mayer
#else
5482 5eb7995e j_mayer
    if (unlikely(!ctx->supervisor)) {
5483 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5484 5eb7995e j_mayer
        return;
5485 5eb7995e j_mayer
    }
5486 5eb7995e j_mayer
    switch (rB(ctx->opcode)) {
5487 5eb7995e j_mayer
    case 0:
5488 5eb7995e j_mayer
    case 1:
5489 5eb7995e j_mayer
    case 2:
5490 5eb7995e j_mayer
        gen_op_load_gpr_T0(rA(ctx->opcode));
5491 5eb7995e j_mayer
        gen_op_load_gpr_T1(rS(ctx->opcode));
5492 a4bb6c3e j_mayer
        gen_op_440_tlbwe(rB(ctx->opcode));
5493 5eb7995e j_mayer
        break;
5494 5eb7995e j_mayer
    default:
5495 e1833e1f j_mayer
        GEN_EXCP_INVAL(ctx);
5496 5eb7995e j_mayer
        break;
5497 5eb7995e j_mayer
    }
5498 5eb7995e j_mayer
#endif
5499 5eb7995e j_mayer
}
5500 5eb7995e j_mayer
5501 76a66253 j_mayer
/* wrtee */
5502 76a66253 j_mayer
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON)
5503 76a66253 j_mayer
{
5504 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5505 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5506 76a66253 j_mayer
#else
5507 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
5508 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5509 76a66253 j_mayer
        return;
5510 76a66253 j_mayer
    }
5511 76a66253 j_mayer
    gen_op_load_gpr_T0(rD(ctx->opcode));
5512 a42bd6cc j_mayer
    gen_op_wrte();
5513 dee96f6c j_mayer
    /* Stop translation to have a chance to raise an exception
5514 dee96f6c j_mayer
     * if we just set msr_ee to 1
5515 dee96f6c j_mayer
     */
5516 e1833e1f j_mayer
    GEN_STOP(ctx);
5517 76a66253 j_mayer
#endif
5518 76a66253 j_mayer
}
5519 76a66253 j_mayer
5520 76a66253 j_mayer
/* wrteei */
5521 76a66253 j_mayer
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_EMB_COMMON)
5522 76a66253 j_mayer
{
5523 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5524 e1833e1f j_mayer
    GEN_EXCP_PRIVOPC(ctx);
5525 76a66253 j_mayer
#else
5526 76a66253 j_mayer
    if (unlikely(!ctx->supervisor)) {
5527 e1833e1f j_mayer
        GEN_EXCP_PRIVOPC(ctx);
5528 76a66253 j_mayer
        return;
5529 76a66253 j_mayer
    }
5530 76a66253 j_mayer
    gen_op_set_T0(ctx->opcode & 0x00010000);
5531 a42bd6cc j_mayer
    gen_op_wrte();
5532 dee96f6c j_mayer
    /* Stop translation to have a chance to raise an exception
5533 dee96f6c j_mayer
     * if we just set msr_ee to 1
5534 dee96f6c j_mayer
     */
5535 e1833e1f j_mayer
    GEN_STOP(ctx);
5536 76a66253 j_mayer
#endif
5537 76a66253 j_mayer
}
5538 76a66253 j_mayer
5539 08e46e54 j_mayer
/* PowerPC 440 specific instructions */
5540 76a66253 j_mayer
/* dlmzb */
5541 76a66253 j_mayer
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
5542 76a66253 j_mayer
{
5543 76a66253 j_mayer
    gen_op_load_gpr_T0(rS(ctx->opcode));
5544 76a66253 j_mayer
    gen_op_load_gpr_T1(rB(ctx->opcode));
5545 76a66253 j_mayer
    gen_op_440_dlmzb();
5546 76a66253 j_mayer
    gen_op_store_T0_gpr(rA(ctx->opcode));
5547 76a66253 j_mayer
    gen_op_store_xer_bc();
5548 76a66253 j_mayer
    if (Rc(ctx->opcode)) {
5549 76a66253 j_mayer
        gen_op_440_dlmzb_update_Rc();
5550 76a66253 j_mayer
        gen_op_store_T0_crf(0);
5551 76a66253 j_mayer
    }
5552 76a66253 j_mayer
}
5553 76a66253 j_mayer
5554 76a66253 j_mayer
/* mbar replaces eieio on 440 */
5555 76a66253 j_mayer
GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
5556 76a66253 j_mayer
{
5557 76a66253 j_mayer
    /* interpreted as no-op */
5558 76a66253 j_mayer
}
5559 76a66253 j_mayer
5560 76a66253 j_mayer
/* msync replaces sync on 440 */
5561 0db1b20e j_mayer
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE)
5562 76a66253 j_mayer
{
5563 76a66253 j_mayer
    /* interpreted as no-op */
5564 76a66253 j_mayer
}
5565 76a66253 j_mayer
5566 76a66253 j_mayer
/* icbt */
5567 c7697e1f j_mayer
GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
5568 76a66253 j_mayer
{
5569 76a66253 j_mayer
    /* interpreted as no-op */
5570 76a66253 j_mayer
    /* XXX: specification say this is treated as a load by the MMU
5571 76a66253 j_mayer
     *      but does not generate any exception
5572 76a66253 j_mayer
     */
5573 79aceca5 bellard
}
5574 79aceca5 bellard
5575 a9d9eb8f j_mayer
/***                      Altivec vector extension                         ***/
5576 a9d9eb8f j_mayer
/* Altivec registers moves */
5577 a9d9eb8f j_mayer
GEN32(gen_op_load_avr_A0, gen_op_load_avr_A0_avr);
5578 a9d9eb8f j_mayer
GEN32(gen_op_load_avr_A1, gen_op_load_avr_A1_avr);
5579 a9d9eb8f j_mayer
GEN32(gen_op_load_avr_A2, gen_op_load_avr_A2_avr);
5580 a9d9eb8f j_mayer
5581 a9d9eb8f j_mayer
GEN32(gen_op_store_A0_avr, gen_op_store_A0_avr_avr);
5582 a9d9eb8f j_mayer
GEN32(gen_op_store_A1_avr, gen_op_store_A1_avr_avr);
5583 a9d9eb8f j_mayer
#if 0 // unused
5584 a9d9eb8f j_mayer
GEN32(gen_op_store_A2_avr, gen_op_store_A2_avr_avr);
5585 a9d9eb8f j_mayer
#endif
5586 a9d9eb8f j_mayer
5587 a9d9eb8f j_mayer
#define op_vr_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5588 a9d9eb8f j_mayer
#if defined(CONFIG_USER_ONLY)
5589 a9d9eb8f j_mayer
#if defined(TARGET_PPC64)
5590 a9d9eb8f j_mayer
/* User-mode only - 64 bits mode */
5591 a9d9eb8f j_mayer
#define OP_VR_LD_TABLE(name)                                                  \
5592 a9d9eb8f j_mayer
static GenOpFunc *gen_op_vr_l##name[] = {                                     \
5593 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_raw,                                                 \
5594 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_le_raw,                                              \
5595 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_64_raw,                                              \
5596 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_le_64_raw,                                           \
5597 a9d9eb8f j_mayer
};
5598 a9d9eb8f j_mayer
#define OP_VR_ST_TABLE(name)                                                  \
5599 a9d9eb8f j_mayer
static GenOpFunc *gen_op_vr_st##name[] = {                                    \
5600 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_raw,                                                \
5601 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_le_raw,                                             \
5602 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_64_raw,                                             \
5603 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_le_64_raw,                                          \
5604 a9d9eb8f j_mayer
};
5605 a9d9eb8f j_mayer
#else /* defined(TARGET_PPC64) */
5606 a9d9eb8f j_mayer
/* User-mode only - 32 bits mode */
5607 a9d9eb8f j_mayer
#define OP_VR_LD_TABLE(name)                                                  \
5608 a9d9eb8f j_mayer
static GenOpFunc *gen_op_vr_l##name[] = {                                     \
5609 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_raw,                                                 \
5610 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_le_raw,                                              \
5611 a9d9eb8f j_mayer
};
5612 a9d9eb8f j_mayer
#define OP_VR_ST_TABLE(name)                                                  \
5613 a9d9eb8f j_mayer
static GenOpFunc *gen_op_vr_st##name[] = {                                    \
5614 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_raw,                                                \
5615 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_le_raw,                                             \
5616 a9d9eb8f j_mayer
};
5617 a9d9eb8f j_mayer
#endif /* defined(TARGET_PPC64) */
5618 a9d9eb8f j_mayer
#else /* defined(CONFIG_USER_ONLY) */
5619 a9d9eb8f j_mayer
#if defined(TARGET_PPC64H)
5620 a9d9eb8f j_mayer
/* Full system with hypervisor mode */
5621 a9d9eb8f j_mayer
#define OP_VR_LD_TABLE(name)                                                  \
5622 a9d9eb8f j_mayer
static GenOpFunc *gen_op_vr_l##name[] = {                                     \
5623 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_user,                                                \
5624 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_le_user,                                             \
5625 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_64_user,                                             \
5626 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_le_64_user,                                          \
5627 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_kernel,                                              \
5628 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_le_kernel,                                           \
5629 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_64_kernel,                                           \
5630 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_le_64_kernel,                                        \
5631 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_hypv,                                                \
5632 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_le_hypv,                                             \
5633 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_64_hypv,                                             \
5634 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_le_64_hypv,                                          \
5635 a9d9eb8f j_mayer
};
5636 a9d9eb8f j_mayer
#define OP_VR_ST_TABLE(name)                                                  \
5637 a9d9eb8f j_mayer
static GenOpFunc *gen_op_vr_st##name[] = {                                    \
5638 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_user,                                               \
5639 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_le_user,                                            \
5640 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_64_user,                                            \
5641 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_le_64_user,                                         \
5642 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_kernel,                                             \
5643 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_le_kernel,                                          \
5644 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_64_kernel,                                          \
5645 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_le_64_kernel,                                       \
5646 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_hypv,                                               \
5647 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_le_hypv,                                            \
5648 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_64_hypv,                                            \
5649 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_le_64_hypv,                                         \
5650 a9d9eb8f j_mayer
};
5651 a9d9eb8f j_mayer
#elif defined(TARGET_PPC64)
5652 a9d9eb8f j_mayer
/* Full system - 64 bits mode */
5653 a9d9eb8f j_mayer
#define OP_VR_LD_TABLE(name)                                                  \
5654 a9d9eb8f j_mayer
static GenOpFunc *gen_op_vr_l##name[] = {                                     \
5655 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_user,                                                \
5656 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_le_user,                                             \
5657 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_64_user,                                             \
5658 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_le_64_user,                                          \
5659 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_kernel,                                              \
5660 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_le_kernel,                                           \
5661 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_64_kernel,                                           \
5662 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_le_64_kernel,                                        \
5663 a9d9eb8f j_mayer
};
5664 a9d9eb8f j_mayer
#define OP_VR_ST_TABLE(name)                                                  \
5665 a9d9eb8f j_mayer
static GenOpFunc *gen_op_vr_st##name[] = {                                    \
5666 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_user,                                               \
5667 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_le_user,                                            \
5668 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_64_user,                                            \
5669 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_le_64_user,                                         \
5670 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_kernel,                                             \
5671 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_le_kernel,                                          \
5672 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_64_kernel,                                          \
5673 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_le_64_kernel,                                       \
5674 a9d9eb8f j_mayer
};
5675 a9d9eb8f j_mayer
#else /* defined(TARGET_PPC64) */
5676 a9d9eb8f j_mayer
/* Full system - 32 bits mode */
5677 a9d9eb8f j_mayer
#define OP_VR_LD_TABLE(name)                                                  \
5678 a9d9eb8f j_mayer
static GenOpFunc *gen_op_vr_l##name[] = {                                     \
5679 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_user,                                                \
5680 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_le_user,                                             \
5681 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_kernel,                                              \
5682 a9d9eb8f j_mayer
    &gen_op_vr_l##name##_le_kernel,                                           \
5683 a9d9eb8f j_mayer
};
5684 a9d9eb8f j_mayer
#define OP_VR_ST_TABLE(name)                                                  \
5685 a9d9eb8f j_mayer
static GenOpFunc *gen_op_vr_st##name[] = {                                    \
5686 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_user,                                               \
5687 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_le_user,                                            \
5688 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_kernel,                                             \
5689 a9d9eb8f j_mayer
    &gen_op_vr_st##name##_le_kernel,                                          \
5690 a9d9eb8f j_mayer
};
5691 a9d9eb8f j_mayer
#endif /* defined(TARGET_PPC64) */
5692 a9d9eb8f j_mayer
#endif /* defined(CONFIG_USER_ONLY) */
5693 a9d9eb8f j_mayer
5694 a9d9eb8f j_mayer
#define GEN_VR_LDX(name, opc2, opc3)                                          \
5695 a9d9eb8f j_mayer
GEN_HANDLER(l##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)               \
5696 a9d9eb8f j_mayer
{                                                                             \
5697 a9d9eb8f j_mayer
    if (unlikely(!ctx->altivec_enabled)) {                                    \
5698 a9d9eb8f j_mayer
        GEN_EXCP_NO_VR(ctx);                                                  \
5699 a9d9eb8f j_mayer
        return;                                                               \
5700 a9d9eb8f j_mayer
    }                                                                         \
5701 a9d9eb8f j_mayer
    gen_addr_reg_index(ctx);                                                  \
5702 a9d9eb8f j_mayer
    op_vr_ldst(vr_l##name);                                                   \
5703 a9d9eb8f j_mayer
    gen_op_store_A0_avr(rD(ctx->opcode));                                     \
5704 a9d9eb8f j_mayer
}
5705 a9d9eb8f j_mayer
5706 a9d9eb8f j_mayer
#define GEN_VR_STX(name, opc2, opc3)                                          \
5707 a9d9eb8f j_mayer
GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)              \
5708 a9d9eb8f j_mayer
{                                                                             \
5709 a9d9eb8f j_mayer
    if (unlikely(!ctx->altivec_enabled)) {                                    \
5710 a9d9eb8f j_mayer
        GEN_EXCP_NO_VR(ctx);                                                  \
5711 a9d9eb8f j_mayer
        return;                                                               \
5712 a9d9eb8f j_mayer
    }                                                                         \
5713 a9d9eb8f j_mayer
    gen_addr_reg_index(ctx);                                                  \
5714 a9d9eb8f j_mayer
    gen_op_load_avr_A0(rS(ctx->opcode));                                      \
5715 a9d9eb8f j_mayer
    op_vr_ldst(vr_st##name);                                                  \
5716 a9d9eb8f j_mayer
}
5717 a9d9eb8f j_mayer
5718 a9d9eb8f j_mayer
OP_VR_LD_TABLE(vx);
5719 a9d9eb8f j_mayer
GEN_VR_LDX(vx, 0x07, 0x03);
5720 a9d9eb8f j_mayer
/* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
5721 a9d9eb8f j_mayer
#define gen_op_vr_lvxl gen_op_vr_lvx
5722 a9d9eb8f j_mayer
GEN_VR_LDX(vxl, 0x07, 0x0B);
5723 a9d9eb8f j_mayer
5724 a9d9eb8f j_mayer
OP_VR_ST_TABLE(vx);
5725 a9d9eb8f j_mayer
GEN_VR_STX(vx, 0x07, 0x07);
5726 a9d9eb8f j_mayer
/* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
5727 a9d9eb8f j_mayer
#define gen_op_vr_stvxl gen_op_vr_stvx
5728 a9d9eb8f j_mayer
GEN_VR_STX(vxl, 0x07, 0x0F);
5729 a9d9eb8f j_mayer
5730 35cdaad6 j_mayer
#if defined(TARGET_PPCEMB)
5731 0487d6a8 j_mayer
/***                           SPE extension                               ***/
5732 0487d6a8 j_mayer
5733 0487d6a8 j_mayer
/* Register moves */
5734 0487d6a8 j_mayer
GEN32(gen_op_load_gpr64_T0, gen_op_load_gpr64_T0_gpr);
5735 0487d6a8 j_mayer
GEN32(gen_op_load_gpr64_T1, gen_op_load_gpr64_T1_gpr);
5736 0487d6a8 j_mayer
#if 0 // unused
5737 0487d6a8 j_mayer
GEN32(gen_op_load_gpr64_T2, gen_op_load_gpr64_T2_gpr);
5738 0487d6a8 j_mayer
#endif
5739 0487d6a8 j_mayer
5740 0487d6a8 j_mayer
GEN32(gen_op_store_T0_gpr64, gen_op_store_T0_gpr64_gpr);
5741 0487d6a8 j_mayer
GEN32(gen_op_store_T1_gpr64, gen_op_store_T1_gpr64_gpr);
5742 0487d6a8 j_mayer
#if 0 // unused
5743 0487d6a8 j_mayer
GEN32(gen_op_store_T2_gpr64, gen_op_store_T2_gpr64_gpr);
5744 0487d6a8 j_mayer
#endif
5745 0487d6a8 j_mayer
5746 0487d6a8 j_mayer
#define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
5747 0487d6a8 j_mayer
GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
5748 0487d6a8 j_mayer
{                                                                             \
5749 0487d6a8 j_mayer
    if (Rc(ctx->opcode))                                                      \
5750 0487d6a8 j_mayer
        gen_##name1(ctx);                                                     \
5751 0487d6a8 j_mayer
    else                                                                      \
5752 0487d6a8 j_mayer
        gen_##name0(ctx);                                                     \
5753 0487d6a8 j_mayer
}
5754 0487d6a8 j_mayer
5755 0487d6a8 j_mayer
/* Handler for undefined SPE opcodes */
5756 b068d6a7 j_mayer
static always_inline void gen_speundef (DisasContext *ctx)
5757 0487d6a8 j_mayer
{
5758 e1833e1f j_mayer
    GEN_EXCP_INVAL(ctx);
5759 0487d6a8 j_mayer
}
5760 0487d6a8 j_mayer
5761 0487d6a8 j_mayer
/* SPE load and stores */
5762 b068d6a7 j_mayer
static always_inline void gen_addr_spe_imm_index (DisasContext *ctx, int sh)
5763 0487d6a8 j_mayer
{
5764 0487d6a8 j_mayer
    target_long simm = rB(ctx->opcode);
5765 0487d6a8 j_mayer
5766 0487d6a8 j_mayer
    if (rA(ctx->opcode) == 0) {
5767 0487d6a8 j_mayer
        gen_set_T0(simm << sh);
5768 0487d6a8 j_mayer
    } else {
5769 0487d6a8 j_mayer
        gen_op_load_gpr_T0(rA(ctx->opcode));
5770 0487d6a8 j_mayer
        if (likely(simm != 0))
5771 0487d6a8 j_mayer
            gen_op_addi(simm << sh);
5772 0487d6a8 j_mayer
    }
5773 0487d6a8 j_mayer
}
5774 0487d6a8 j_mayer
5775 0487d6a8 j_mayer
#define op_spe_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
5776 0487d6a8 j_mayer
#if defined(CONFIG_USER_ONLY)
5777 0487d6a8 j_mayer
#if defined(TARGET_PPC64)
5778 2857068e j_mayer
/* User-mode only - 64 bits mode */
5779 0487d6a8 j_mayer
#define OP_SPE_LD_TABLE(name)                                                 \
5780 0487d6a8 j_mayer
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5781 0487d6a8 j_mayer
    &gen_op_spe_l##name##_raw,                                                \
5782 0487d6a8 j_mayer
    &gen_op_spe_l##name##_le_raw,                                             \
5783 0487d6a8 j_mayer
    &gen_op_spe_l##name##_64_raw,                                             \
5784 0487d6a8 j_mayer
    &gen_op_spe_l##name##_le_64_raw,                                          \
5785 0487d6a8 j_mayer
};
5786 0487d6a8 j_mayer
#define OP_SPE_ST_TABLE(name)                                                 \
5787 0487d6a8 j_mayer
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5788 0487d6a8 j_mayer
    &gen_op_spe_st##name##_raw,                                               \
5789 0487d6a8 j_mayer
    &gen_op_spe_st##name##_le_raw,                                            \
5790 0487d6a8 j_mayer
    &gen_op_spe_st##name##_64_raw,                                            \
5791 0487d6a8 j_mayer
    &gen_op_spe_st##name##_le_64_raw,                                         \
5792 0487d6a8 j_mayer
};
5793 0487d6a8 j_mayer
#else /* defined(TARGET_PPC64) */
5794 2857068e j_mayer
/* User-mode only - 32 bits mode */
5795 0487d6a8 j_mayer
#define OP_SPE_LD_TABLE(name)                                                 \
5796 0487d6a8 j_mayer
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5797 0487d6a8 j_mayer
    &gen_op_spe_l##name##_raw,                                                \
5798 0487d6a8 j_mayer
    &gen_op_spe_l##name##_le_raw,                                             \
5799 0487d6a8 j_mayer
};
5800 0487d6a8 j_mayer
#define OP_SPE_ST_TABLE(name)                                                 \
5801 0487d6a8 j_mayer
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5802 0487d6a8 j_mayer
    &gen_op_spe_st##name##_raw,                                               \
5803 0487d6a8 j_mayer
    &gen_op_spe_st##name##_le_raw,                                            \
5804 0487d6a8 j_mayer
};
5805 0487d6a8 j_mayer
#endif /* defined(TARGET_PPC64) */
5806 0487d6a8 j_mayer
#else /* defined(CONFIG_USER_ONLY) */
5807 2857068e j_mayer
#if defined(TARGET_PPC64H)
5808 2857068e j_mayer
/* Full system with hypervisor mode */
5809 0487d6a8 j_mayer
#define OP_SPE_LD_TABLE(name)                                                 \
5810 0487d6a8 j_mayer
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5811 0487d6a8 j_mayer
    &gen_op_spe_l##name##_user,                                               \
5812 0487d6a8 j_mayer
    &gen_op_spe_l##name##_le_user,                                            \
5813 0487d6a8 j_mayer
    &gen_op_spe_l##name##_64_user,                                            \
5814 0487d6a8 j_mayer
    &gen_op_spe_l##name##_le_64_user,                                         \
5815 2857068e j_mayer
    &gen_op_spe_l##name##_kernel,                                             \
5816 2857068e j_mayer
    &gen_op_spe_l##name##_le_kernel,                                          \
5817 0487d6a8 j_mayer
    &gen_op_spe_l##name##_64_kernel,                                          \
5818 0487d6a8 j_mayer
    &gen_op_spe_l##name##_le_64_kernel,                                       \
5819 2857068e j_mayer
    &gen_op_spe_l##name##_hypv,                                               \
5820 2857068e j_mayer
    &gen_op_spe_l##name##_le_hypv,                                            \
5821 2857068e j_mayer
    &gen_op_spe_l##name##_64_hypv,                                            \
5822 2857068e j_mayer
    &gen_op_spe_l##name##_le_64_hypv,                                         \
5823 0487d6a8 j_mayer
};
5824 0487d6a8 j_mayer
#define OP_SPE_ST_TABLE(name)                                                 \
5825 0487d6a8 j_mayer
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5826 0487d6a8 j_mayer
    &gen_op_spe_st##name##_user,                                              \
5827 0487d6a8 j_mayer
    &gen_op_spe_st##name##_le_user,                                           \
5828 2857068e j_mayer
    &gen_op_spe_st##name##_64_user,                                           \
5829 2857068e j_mayer
    &gen_op_spe_st##name##_le_64_user,                                        \
5830 0487d6a8 j_mayer
    &gen_op_spe_st##name##_kernel,                                            \
5831 0487d6a8 j_mayer
    &gen_op_spe_st##name##_le_kernel,                                         \
5832 2857068e j_mayer
    &gen_op_spe_st##name##_64_kernel,                                         \
5833 2857068e j_mayer
    &gen_op_spe_st##name##_le_64_kernel,                                      \
5834 2857068e j_mayer
    &gen_op_spe_st##name##_hypv,                                              \
5835 2857068e j_mayer
    &gen_op_spe_st##name##_le_hypv,                                           \
5836 2857068e j_mayer
    &gen_op_spe_st##name##_64_hypv,                                           \
5837 2857068e j_mayer
    &gen_op_spe_st##name##_le_64_hypv,                                        \
5838 2857068e j_mayer
};
5839 2857068e j_mayer
#elif defined(TARGET_PPC64)
5840 2857068e j_mayer
/* Full system - 64 bits mode */
5841 2857068e j_mayer
#define OP_SPE_LD_TABLE(name)                                                 \
5842 2857068e j_mayer
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5843 2857068e j_mayer
    &gen_op_spe_l##name##_user,                                               \
5844 2857068e j_mayer
    &gen_op_spe_l##name##_le_user,                                            \
5845 2857068e j_mayer
    &gen_op_spe_l##name##_64_user,                                            \
5846 2857068e j_mayer
    &gen_op_spe_l##name##_le_64_user,                                         \
5847 2857068e j_mayer
    &gen_op_spe_l##name##_kernel,                                             \
5848 2857068e j_mayer
    &gen_op_spe_l##name##_le_kernel,                                          \
5849 2857068e j_mayer
    &gen_op_spe_l##name##_64_kernel,                                          \
5850 2857068e j_mayer
    &gen_op_spe_l##name##_le_64_kernel,                                       \
5851 2857068e j_mayer
};
5852 2857068e j_mayer
#define OP_SPE_ST_TABLE(name)                                                 \
5853 2857068e j_mayer
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5854 2857068e j_mayer
    &gen_op_spe_st##name##_user,                                              \
5855 2857068e j_mayer
    &gen_op_spe_st##name##_le_user,                                           \
5856 0487d6a8 j_mayer
    &gen_op_spe_st##name##_64_user,                                           \
5857 0487d6a8 j_mayer
    &gen_op_spe_st##name##_le_64_user,                                        \
5858 2857068e j_mayer
    &gen_op_spe_st##name##_kernel,                                            \
5859 2857068e j_mayer
    &gen_op_spe_st##name##_le_kernel,                                         \
5860 0487d6a8 j_mayer
    &gen_op_spe_st##name##_64_kernel,                                         \
5861 0487d6a8 j_mayer
    &gen_op_spe_st##name##_le_64_kernel,                                      \
5862 0487d6a8 j_mayer
};
5863 0487d6a8 j_mayer
#else /* defined(TARGET_PPC64) */
5864 2857068e j_mayer
/* Full system - 32 bits mode */
5865 0487d6a8 j_mayer
#define OP_SPE_LD_TABLE(name)                                                 \
5866 0487d6a8 j_mayer
static GenOpFunc *gen_op_spe_l##name[] = {                                    \
5867 0487d6a8 j_mayer
    &gen_op_spe_l##name##_user,                                               \
5868 0487d6a8 j_mayer
    &gen_op_spe_l##name##_le_user,                                            \
5869 0487d6a8 j_mayer
    &gen_op_spe_l##name##_kernel,                                             \
5870 0487d6a8 j_mayer
    &gen_op_spe_l##name##_le_kernel,                                          \
5871 0487d6a8 j_mayer
};
5872 0487d6a8 j_mayer
#define OP_SPE_ST_TABLE(name)                                                 \
5873 0487d6a8 j_mayer
static GenOpFunc *gen_op_spe_st##name[] = {                                   \
5874 0487d6a8 j_mayer
    &gen_op_spe_st##name##_user,                                              \
5875 0487d6a8 j_mayer
    &gen_op_spe_st##name##_le_user,                                           \
5876 0487d6a8 j_mayer
    &gen_op_spe_st##name##_kernel,                                            \
5877 0487d6a8 j_mayer
    &gen_op_spe_st##name##_le_kernel,                                         \
5878 0487d6a8 j_mayer
};
5879 0487d6a8 j_mayer
#endif /* defined(TARGET_PPC64) */
5880 0487d6a8 j_mayer
#endif /* defined(CONFIG_USER_ONLY) */
5881 0487d6a8 j_mayer
5882 0487d6a8 j_mayer
#define GEN_SPE_LD(name, sh)                                                  \
5883 b068d6a7 j_mayer
static always_inline void gen_evl##name (DisasContext *ctx)                   \
5884 0487d6a8 j_mayer
{                                                                             \
5885 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
5886 e1833e1f j_mayer
        GEN_EXCP_NO_AP(ctx);                                                  \
5887 0487d6a8 j_mayer
        return;                                                               \
5888 0487d6a8 j_mayer
    }                                                                         \
5889 0487d6a8 j_mayer
    gen_addr_spe_imm_index(ctx, sh);                                          \
5890 0487d6a8 j_mayer
    op_spe_ldst(spe_l##name);                                                 \
5891 0487d6a8 j_mayer
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5892 0487d6a8 j_mayer
}
5893 0487d6a8 j_mayer
5894 0487d6a8 j_mayer
#define GEN_SPE_LDX(name)                                                     \
5895 b068d6a7 j_mayer
static always_inline void gen_evl##name##x (DisasContext *ctx)                \
5896 0487d6a8 j_mayer
{                                                                             \
5897 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
5898 e1833e1f j_mayer
        GEN_EXCP_NO_AP(ctx);                                                  \
5899 0487d6a8 j_mayer
        return;                                                               \
5900 0487d6a8 j_mayer
    }                                                                         \
5901 0487d6a8 j_mayer
    gen_addr_reg_index(ctx);                                                  \
5902 0487d6a8 j_mayer
    op_spe_ldst(spe_l##name);                                                 \
5903 0487d6a8 j_mayer
    gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
5904 0487d6a8 j_mayer
}
5905 0487d6a8 j_mayer
5906 0487d6a8 j_mayer
#define GEN_SPEOP_LD(name, sh)                                                \
5907 0487d6a8 j_mayer
OP_SPE_LD_TABLE(name);                                                        \
5908 0487d6a8 j_mayer
GEN_SPE_LD(name, sh);                                                         \
5909 0487d6a8 j_mayer
GEN_SPE_LDX(name)
5910 0487d6a8 j_mayer
5911 0487d6a8 j_mayer
#define GEN_SPE_ST(name, sh)                                                  \
5912 b068d6a7 j_mayer
static always_inline void gen_evst##name (DisasContext *ctx)                  \
5913 0487d6a8 j_mayer
{                                                                             \
5914 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
5915 e1833e1f j_mayer
        GEN_EXCP_NO_AP(ctx);                                                  \
5916 0487d6a8 j_mayer
        return;                                                               \
5917 0487d6a8 j_mayer
    }                                                                         \
5918 0487d6a8 j_mayer
    gen_addr_spe_imm_index(ctx, sh);                                          \
5919 0487d6a8 j_mayer
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5920 0487d6a8 j_mayer
    op_spe_ldst(spe_st##name);                                                \
5921 0487d6a8 j_mayer
}
5922 0487d6a8 j_mayer
5923 0487d6a8 j_mayer
#define GEN_SPE_STX(name)                                                     \
5924 b068d6a7 j_mayer
static always_inline void gen_evst##name##x (DisasContext *ctx)               \
5925 0487d6a8 j_mayer
{                                                                             \
5926 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
5927 e1833e1f j_mayer
        GEN_EXCP_NO_AP(ctx);                                                  \
5928 0487d6a8 j_mayer
        return;                                                               \
5929 0487d6a8 j_mayer
    }                                                                         \
5930 0487d6a8 j_mayer
    gen_addr_reg_index(ctx);                                                  \
5931 0487d6a8 j_mayer
    gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
5932 0487d6a8 j_mayer
    op_spe_ldst(spe_st##name);                                                \
5933 0487d6a8 j_mayer
}
5934 0487d6a8 j_mayer
5935 0487d6a8 j_mayer
#define GEN_SPEOP_ST(name, sh)                                                \
5936 0487d6a8 j_mayer
OP_SPE_ST_TABLE(name);                                                        \
5937 0487d6a8 j_mayer
GEN_SPE_ST(name, sh);                                                         \
5938 0487d6a8 j_mayer
GEN_SPE_STX(name)
5939 0487d6a8 j_mayer
5940 0487d6a8 j_mayer
#define GEN_SPEOP_LDST(name, sh)                                              \
5941 0487d6a8 j_mayer
GEN_SPEOP_LD(name, sh);                                                       \
5942 0487d6a8 j_mayer
GEN_SPEOP_ST(name, sh)
5943 0487d6a8 j_mayer
5944 0487d6a8 j_mayer
/* SPE arithmetic and logic */
5945 0487d6a8 j_mayer
#define GEN_SPEOP_ARITH2(name)                                                \
5946 b068d6a7 j_mayer
static always_inline void gen_##name (DisasContext *ctx)                      \
5947 0487d6a8 j_mayer
{                                                                             \
5948 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
5949 e1833e1f j_mayer
        GEN_EXCP_NO_AP(ctx);                                                  \
5950 0487d6a8 j_mayer
        return;                                                               \
5951 0487d6a8 j_mayer
    }                                                                         \
5952 0487d6a8 j_mayer
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5953 0487d6a8 j_mayer
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5954 0487d6a8 j_mayer
    gen_op_##name();                                                          \
5955 0487d6a8 j_mayer
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5956 0487d6a8 j_mayer
}
5957 0487d6a8 j_mayer
5958 0487d6a8 j_mayer
#define GEN_SPEOP_ARITH1(name)                                                \
5959 b068d6a7 j_mayer
static always_inline void gen_##name (DisasContext *ctx)                      \
5960 0487d6a8 j_mayer
{                                                                             \
5961 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
5962 e1833e1f j_mayer
        GEN_EXCP_NO_AP(ctx);                                                  \
5963 0487d6a8 j_mayer
        return;                                                               \
5964 0487d6a8 j_mayer
    }                                                                         \
5965 0487d6a8 j_mayer
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5966 0487d6a8 j_mayer
    gen_op_##name();                                                          \
5967 0487d6a8 j_mayer
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
5968 0487d6a8 j_mayer
}
5969 0487d6a8 j_mayer
5970 0487d6a8 j_mayer
#define GEN_SPEOP_COMP(name)                                                  \
5971 b068d6a7 j_mayer
static always_inline void gen_##name (DisasContext *ctx)                      \
5972 0487d6a8 j_mayer
{                                                                             \
5973 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
5974 e1833e1f j_mayer
        GEN_EXCP_NO_AP(ctx);                                                  \
5975 0487d6a8 j_mayer
        return;                                                               \
5976 0487d6a8 j_mayer
    }                                                                         \
5977 0487d6a8 j_mayer
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
5978 0487d6a8 j_mayer
    gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
5979 0487d6a8 j_mayer
    gen_op_##name();                                                          \
5980 0487d6a8 j_mayer
    gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
5981 0487d6a8 j_mayer
}
5982 0487d6a8 j_mayer
5983 0487d6a8 j_mayer
/* Logical */
5984 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evand);
5985 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evandc);
5986 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evxor);
5987 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evor);
5988 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evnor);
5989 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(eveqv);
5990 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evorc);
5991 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evnand);
5992 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evsrwu);
5993 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evsrws);
5994 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evslw);
5995 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evrlw);
5996 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evmergehi);
5997 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evmergelo);
5998 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evmergehilo);
5999 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evmergelohi);
6000 0487d6a8 j_mayer
6001 0487d6a8 j_mayer
/* Arithmetic */
6002 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evaddw);
6003 0487d6a8 j_mayer
GEN_SPEOP_ARITH2(evsubfw);
6004 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evabs);
6005 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evneg);
6006 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evextsb);
6007 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evextsh);
6008 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evrndw);
6009 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evcntlzw);
6010 0487d6a8 j_mayer
GEN_SPEOP_ARITH1(evcntlsw);
6011 b068d6a7 j_mayer
static always_inline void gen_brinc (DisasContext *ctx)
6012 0487d6a8 j_mayer
{
6013 0487d6a8 j_mayer
    /* Note: brinc is usable even if SPE is disabled */
6014 0487d6a8 j_mayer
    gen_op_load_gpr64_T0(rA(ctx->opcode));
6015 0487d6a8 j_mayer
    gen_op_load_gpr64_T1(rB(ctx->opcode));
6016 0487d6a8 j_mayer
    gen_op_brinc();
6017 0487d6a8 j_mayer
    gen_op_store_T0_gpr64(rD(ctx->opcode));
6018 0487d6a8 j_mayer
}
6019 0487d6a8 j_mayer
6020 0487d6a8 j_mayer
#define GEN_SPEOP_ARITH_IMM2(name)                                            \
6021 b068d6a7 j_mayer
static always_inline void gen_##name##i (DisasContext *ctx)                   \
6022 0487d6a8 j_mayer
{                                                                             \
6023 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
6024 e1833e1f j_mayer
        GEN_EXCP_NO_AP(ctx);                                                  \
6025 0487d6a8 j_mayer
        return;                                                               \
6026 0487d6a8 j_mayer
    }                                                                         \
6027 0487d6a8 j_mayer
    gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
6028 0487d6a8 j_mayer
    gen_op_splatwi_T1_64(rA(ctx->opcode));                                    \
6029 0487d6a8 j_mayer
    gen_op_##name();                                                          \
6030 0487d6a8 j_mayer
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
6031 0487d6a8 j_mayer
}
6032 0487d6a8 j_mayer
6033 0487d6a8 j_mayer
#define GEN_SPEOP_LOGIC_IMM2(name)                                            \
6034 b068d6a7 j_mayer
static always_inline void gen_##name##i (DisasContext *ctx)                   \
6035 0487d6a8 j_mayer
{                                                                             \
6036 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
6037 e1833e1f j_mayer
        GEN_EXCP_NO_AP(ctx);                                                  \
6038 0487d6a8 j_mayer
        return;                                                               \
6039 0487d6a8 j_mayer
    }                                                                         \
6040 0487d6a8 j_mayer
    gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
6041 0487d6a8 j_mayer
    gen_op_splatwi_T1_64(rB(ctx->opcode));                                    \
6042 0487d6a8 j_mayer
    gen_op_##name();                                                          \
6043 0487d6a8 j_mayer
    gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
6044 0487d6a8 j_mayer
}
6045 0487d6a8 j_mayer
6046 0487d6a8 j_mayer
GEN_SPEOP_ARITH_IMM2(evaddw);
6047 0487d6a8 j_mayer
#define gen_evaddiw gen_evaddwi
6048 0487d6a8 j_mayer
GEN_SPEOP_ARITH_IMM2(evsubfw);
6049 0487d6a8 j_mayer
#define gen_evsubifw gen_evsubfwi
6050 0487d6a8 j_mayer
GEN_SPEOP_LOGIC_IMM2(evslw);
6051 0487d6a8 j_mayer
GEN_SPEOP_LOGIC_IMM2(evsrwu);
6052 0487d6a8 j_mayer
#define gen_evsrwis gen_evsrwsi
6053 0487d6a8 j_mayer
GEN_SPEOP_LOGIC_IMM2(evsrws);
6054 0487d6a8 j_mayer
#define gen_evsrwiu gen_evsrwui
6055 0487d6a8 j_mayer
GEN_SPEOP_LOGIC_IMM2(evrlw);
6056 0487d6a8 j_mayer
6057 b068d6a7 j_mayer
static always_inline void gen_evsplati (DisasContext *ctx)
6058 0487d6a8 j_mayer
{
6059 0487d6a8 j_mayer
    int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
6060 0487d6a8 j_mayer
6061 0487d6a8 j_mayer
    gen_op_splatwi_T0_64(imm);
6062 0487d6a8 j_mayer
    gen_op_store_T0_gpr64(rD(ctx->opcode));
6063 0487d6a8 j_mayer
}
6064 0487d6a8 j_mayer
6065 b068d6a7 j_mayer
static always_inline void gen_evsplatfi (DisasContext *ctx)
6066 0487d6a8 j_mayer
{
6067 0487d6a8 j_mayer
    uint32_t imm = rA(ctx->opcode) << 27;
6068 0487d6a8 j_mayer
6069 0487d6a8 j_mayer
    gen_op_splatwi_T0_64(imm);
6070 0487d6a8 j_mayer
    gen_op_store_T0_gpr64(rD(ctx->opcode));
6071 0487d6a8 j_mayer
}
6072 0487d6a8 j_mayer
6073 0487d6a8 j_mayer
/* Comparison */
6074 0487d6a8 j_mayer
GEN_SPEOP_COMP(evcmpgtu);
6075 0487d6a8 j_mayer
GEN_SPEOP_COMP(evcmpgts);
6076 0487d6a8 j_mayer
GEN_SPEOP_COMP(evcmpltu);
6077 0487d6a8 j_mayer
GEN_SPEOP_COMP(evcmplts);
6078 0487d6a8 j_mayer
GEN_SPEOP_COMP(evcmpeq);
6079 0487d6a8 j_mayer
6080 0487d6a8 j_mayer
GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
6081 0487d6a8 j_mayer
GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
6082 0487d6a8 j_mayer
GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
6083 0487d6a8 j_mayer
GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
6084 0487d6a8 j_mayer
GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
6085 0487d6a8 j_mayer
GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
6086 0487d6a8 j_mayer
GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
6087 0487d6a8 j_mayer
GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
6088 0487d6a8 j_mayer
GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
6089 0487d6a8 j_mayer
GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
6090 0487d6a8 j_mayer
GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
6091 0487d6a8 j_mayer
GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
6092 0487d6a8 j_mayer
GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
6093 0487d6a8 j_mayer
GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
6094 0487d6a8 j_mayer
GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
6095 0487d6a8 j_mayer
GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
6096 0487d6a8 j_mayer
GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
6097 0487d6a8 j_mayer
GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
6098 0487d6a8 j_mayer
GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
6099 0487d6a8 j_mayer
GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
6100 0487d6a8 j_mayer
GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
6101 0487d6a8 j_mayer
GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
6102 0487d6a8 j_mayer
GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
6103 0487d6a8 j_mayer
GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
6104 0487d6a8 j_mayer
GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
6105 0487d6a8 j_mayer
6106 b068d6a7 j_mayer
static always_inline void gen_evsel (DisasContext *ctx)
6107 0487d6a8 j_mayer
{
6108 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {
6109 e1833e1f j_mayer
        GEN_EXCP_NO_AP(ctx);
6110 0487d6a8 j_mayer
        return;
6111 0487d6a8 j_mayer
    }
6112 0487d6a8 j_mayer
    gen_op_load_crf_T0(ctx->opcode & 0x7);
6113 0487d6a8 j_mayer
    gen_op_load_gpr64_T0(rA(ctx->opcode));
6114 0487d6a8 j_mayer
    gen_op_load_gpr64_T1(rB(ctx->opcode));
6115 0487d6a8 j_mayer
    gen_op_evsel();
6116 0487d6a8 j_mayer
    gen_op_store_T0_gpr64(rD(ctx->opcode));
6117 0487d6a8 j_mayer
}
6118 0487d6a8 j_mayer
6119 c7697e1f j_mayer
GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
6120 0487d6a8 j_mayer
{
6121 0487d6a8 j_mayer
    gen_evsel(ctx);
6122 0487d6a8 j_mayer
}
6123 c7697e1f j_mayer
GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
6124 0487d6a8 j_mayer
{
6125 0487d6a8 j_mayer
    gen_evsel(ctx);
6126 0487d6a8 j_mayer
}
6127 c7697e1f j_mayer
GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
6128 0487d6a8 j_mayer
{
6129 0487d6a8 j_mayer
    gen_evsel(ctx);
6130 0487d6a8 j_mayer
}
6131 c7697e1f j_mayer
GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
6132 0487d6a8 j_mayer
{
6133 0487d6a8 j_mayer
    gen_evsel(ctx);
6134 0487d6a8 j_mayer
}
6135 0487d6a8 j_mayer
6136 0487d6a8 j_mayer
/* Load and stores */
6137 0487d6a8 j_mayer
#if defined(TARGET_PPC64)
6138 0487d6a8 j_mayer
/* In that case, we already have 64 bits load & stores
6139 0487d6a8 j_mayer
 * so, spe_ldd is equivalent to ld and spe_std is equivalent to std
6140 0487d6a8 j_mayer
 */
6141 0487d6a8 j_mayer
#if defined(CONFIG_USER_ONLY)
6142 0487d6a8 j_mayer
#define gen_op_spe_ldd_raw gen_op_ld_raw
6143 0487d6a8 j_mayer
#define gen_op_spe_ldd_64_raw gen_op_ld_64_raw
6144 0487d6a8 j_mayer
#define gen_op_spe_ldd_le_raw gen_op_ld_le_raw
6145 0487d6a8 j_mayer
#define gen_op_spe_ldd_le_64_raw gen_op_ld_le_64_raw
6146 0487d6a8 j_mayer
#define gen_op_spe_stdd_raw gen_op_ld_raw
6147 0487d6a8 j_mayer
#define gen_op_spe_stdd_64_raw gen_op_std_64_raw
6148 0487d6a8 j_mayer
#define gen_op_spe_stdd_le_raw gen_op_std_le_raw
6149 0487d6a8 j_mayer
#define gen_op_spe_stdd_le_64_raw gen_op_std_le_64_raw
6150 0487d6a8 j_mayer
#else /* defined(CONFIG_USER_ONLY) */
6151 0487d6a8 j_mayer
#define gen_op_spe_ldd_kernel gen_op_ld_kernel
6152 0487d6a8 j_mayer
#define gen_op_spe_ldd_64_kernel gen_op_ld_64_kernel
6153 0487d6a8 j_mayer
#define gen_op_spe_ldd_le_kernel gen_op_ld_kernel
6154 0487d6a8 j_mayer
#define gen_op_spe_ldd_le_64_kernel gen_op_ld_64_kernel
6155 0487d6a8 j_mayer
#define gen_op_spe_ldd_user gen_op_ld_user
6156 0487d6a8 j_mayer
#define gen_op_spe_ldd_64_user gen_op_ld_64_user
6157 0487d6a8 j_mayer
#define gen_op_spe_ldd_le_user gen_op_ld_le_user
6158 0487d6a8 j_mayer
#define gen_op_spe_ldd_le_64_user gen_op_ld_le_64_user
6159 0487d6a8 j_mayer
#define gen_op_spe_stdd_kernel gen_op_std_kernel
6160 0487d6a8 j_mayer
#define gen_op_spe_stdd_64_kernel gen_op_std_64_kernel
6161 0487d6a8 j_mayer
#define gen_op_spe_stdd_le_kernel gen_op_std_kernel
6162 0487d6a8 j_mayer
#define gen_op_spe_stdd_le_64_kernel gen_op_std_64_kernel
6163 0487d6a8 j_mayer
#define gen_op_spe_stdd_user gen_op_std_user
6164 0487d6a8 j_mayer
#define gen_op_spe_stdd_64_user gen_op_std_64_user
6165 0487d6a8 j_mayer
#define gen_op_spe_stdd_le_user gen_op_std_le_user
6166 0487d6a8 j_mayer
#define gen_op_spe_stdd_le_64_user gen_op_std_le_64_user
6167 0487d6a8 j_mayer
#endif /* defined(CONFIG_USER_ONLY) */
6168 0487d6a8 j_mayer
#endif /* defined(TARGET_PPC64) */
6169 0487d6a8 j_mayer
GEN_SPEOP_LDST(dd, 3);
6170 0487d6a8 j_mayer
GEN_SPEOP_LDST(dw, 3);
6171 0487d6a8 j_mayer
GEN_SPEOP_LDST(dh, 3);
6172 0487d6a8 j_mayer
GEN_SPEOP_LDST(whe, 2);
6173 0487d6a8 j_mayer
GEN_SPEOP_LD(whou, 2);
6174 0487d6a8 j_mayer
GEN_SPEOP_LD(whos, 2);
6175 0487d6a8 j_mayer
GEN_SPEOP_ST(who, 2);
6176 0487d6a8 j_mayer
6177 0487d6a8 j_mayer
#if defined(TARGET_PPC64)
6178 0487d6a8 j_mayer
/* In that case, spe_stwwo is equivalent to stw */
6179 0487d6a8 j_mayer
#if defined(CONFIG_USER_ONLY)
6180 0487d6a8 j_mayer
#define gen_op_spe_stwwo_raw gen_op_stw_raw
6181 0487d6a8 j_mayer
#define gen_op_spe_stwwo_le_raw gen_op_stw_le_raw
6182 0487d6a8 j_mayer
#define gen_op_spe_stwwo_64_raw gen_op_stw_64_raw
6183 0487d6a8 j_mayer
#define gen_op_spe_stwwo_le_64_raw gen_op_stw_le_64_raw
6184 0487d6a8 j_mayer
#else
6185 0487d6a8 j_mayer
#define gen_op_spe_stwwo_user gen_op_stw_user
6186 0487d6a8 j_mayer
#define gen_op_spe_stwwo_le_user gen_op_stw_le_user
6187 0487d6a8 j_mayer
#define gen_op_spe_stwwo_64_user gen_op_stw_64_user
6188 0487d6a8 j_mayer
#define gen_op_spe_stwwo_le_64_user gen_op_stw_le_64_user
6189 0487d6a8 j_mayer
#define gen_op_spe_stwwo_kernel gen_op_stw_kernel
6190 0487d6a8 j_mayer
#define gen_op_spe_stwwo_le_kernel gen_op_stw_le_kernel
6191 0487d6a8 j_mayer
#define gen_op_spe_stwwo_64_kernel gen_op_stw_64_kernel
6192 0487d6a8 j_mayer
#define gen_op_spe_stwwo_le_64_kernel gen_op_stw_le_64_kernel
6193 0487d6a8 j_mayer
#endif
6194 0487d6a8 j_mayer
#endif
6195 0487d6a8 j_mayer
#define _GEN_OP_SPE_STWWE(suffix)                                             \
6196 b068d6a7 j_mayer
static always_inline void gen_op_spe_stwwe_##suffix (void)                    \
6197 0487d6a8 j_mayer
{                                                                             \
6198 0487d6a8 j_mayer
    gen_op_srli32_T1_64();                                                    \
6199 0487d6a8 j_mayer
    gen_op_spe_stwwo_##suffix();                                              \
6200 0487d6a8 j_mayer
}
6201 0487d6a8 j_mayer
#define _GEN_OP_SPE_STWWE_LE(suffix)                                          \
6202 b068d6a7 j_mayer
static always_inline void gen_op_spe_stwwe_le_##suffix (void)                 \
6203 0487d6a8 j_mayer
{                                                                             \
6204 0487d6a8 j_mayer
    gen_op_srli32_T1_64();                                                    \
6205 0487d6a8 j_mayer
    gen_op_spe_stwwo_le_##suffix();                                           \
6206 0487d6a8 j_mayer
}
6207 0487d6a8 j_mayer
#if defined(TARGET_PPC64)
6208 0487d6a8 j_mayer
#define GEN_OP_SPE_STWWE(suffix)                                              \
6209 0487d6a8 j_mayer
_GEN_OP_SPE_STWWE(suffix);                                                    \
6210 0487d6a8 j_mayer
_GEN_OP_SPE_STWWE_LE(suffix);                                                 \
6211 b068d6a7 j_mayer
static always_inline void gen_op_spe_stwwe_64_##suffix (void)                 \
6212 0487d6a8 j_mayer
{                                                                             \
6213 0487d6a8 j_mayer
    gen_op_srli32_T1_64();                                                    \
6214 0487d6a8 j_mayer
    gen_op_spe_stwwo_64_##suffix();                                           \
6215 0487d6a8 j_mayer
}                                                                             \
6216 b068d6a7 j_mayer
static always_inline void gen_op_spe_stwwe_le_64_##suffix (void)              \
6217 0487d6a8 j_mayer
{                                                                             \
6218 0487d6a8 j_mayer
    gen_op_srli32_T1_64();                                                    \
6219 0487d6a8 j_mayer
    gen_op_spe_stwwo_le_64_##suffix();                                        \
6220 0487d6a8 j_mayer
}
6221 0487d6a8 j_mayer
#else
6222 0487d6a8 j_mayer
#define GEN_OP_SPE_STWWE(suffix)                                              \
6223 0487d6a8 j_mayer
_GEN_OP_SPE_STWWE(suffix);                                                    \
6224 0487d6a8 j_mayer
_GEN_OP_SPE_STWWE_LE(suffix)
6225 0487d6a8 j_mayer
#endif
6226 0487d6a8 j_mayer
#if defined(CONFIG_USER_ONLY)
6227 0487d6a8 j_mayer
GEN_OP_SPE_STWWE(raw);
6228 0487d6a8 j_mayer
#else /* defined(CONFIG_USER_ONLY) */
6229 0487d6a8 j_mayer
GEN_OP_SPE_STWWE(kernel);
6230 0487d6a8 j_mayer
GEN_OP_SPE_STWWE(user);
6231 0487d6a8 j_mayer
#endif /* defined(CONFIG_USER_ONLY) */
6232 0487d6a8 j_mayer
GEN_SPEOP_ST(wwe, 2);
6233 0487d6a8 j_mayer
GEN_SPEOP_ST(wwo, 2);
6234 0487d6a8 j_mayer
6235 0487d6a8 j_mayer
#define GEN_SPE_LDSPLAT(name, op, suffix)                                     \
6236 b068d6a7 j_mayer
static always_inline void gen_op_spe_l##name##_##suffix (void)                \
6237 0487d6a8 j_mayer
{                                                                             \
6238 0487d6a8 j_mayer
    gen_op_##op##_##suffix();                                                 \
6239 0487d6a8 j_mayer
    gen_op_splatw_T1_64();                                                    \
6240 0487d6a8 j_mayer
}
6241 0487d6a8 j_mayer
6242 0487d6a8 j_mayer
#define GEN_OP_SPE_LHE(suffix)                                                \
6243 b068d6a7 j_mayer
static always_inline void gen_op_spe_lhe_##suffix (void)                      \
6244 0487d6a8 j_mayer
{                                                                             \
6245 0487d6a8 j_mayer
    gen_op_spe_lh_##suffix();                                                 \
6246 0487d6a8 j_mayer
    gen_op_sli16_T1_64();                                                     \
6247 0487d6a8 j_mayer
}
6248 0487d6a8 j_mayer
6249 0487d6a8 j_mayer
#define GEN_OP_SPE_LHX(suffix)                                                \
6250 b068d6a7 j_mayer
static always_inline void gen_op_spe_lhx_##suffix (void)                      \
6251 0487d6a8 j_mayer
{                                                                             \
6252 0487d6a8 j_mayer
    gen_op_spe_lh_##suffix();                                                 \
6253 0487d6a8 j_mayer
    gen_op_extsh_T1_64();                                                     \
6254 0487d6a8 j_mayer
}
6255 0487d6a8 j_mayer
6256 0487d6a8 j_mayer
#if defined(CONFIG_USER_ONLY)
6257 0487d6a8 j_mayer
GEN_OP_SPE_LHE(raw);
6258 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, raw);
6259 0487d6a8 j_mayer
GEN_OP_SPE_LHE(le_raw);
6260 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_raw);
6261 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, raw);
6262 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_raw);
6263 0487d6a8 j_mayer
GEN_OP_SPE_LHX(raw);
6264 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, raw);
6265 0487d6a8 j_mayer
GEN_OP_SPE_LHX(le_raw);
6266 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_raw);
6267 0487d6a8 j_mayer
#if defined(TARGET_PPC64)
6268 0487d6a8 j_mayer
GEN_OP_SPE_LHE(64_raw);
6269 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_raw);
6270 0487d6a8 j_mayer
GEN_OP_SPE_LHE(le_64_raw);
6271 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_raw);
6272 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_raw);
6273 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_raw);
6274 0487d6a8 j_mayer
GEN_OP_SPE_LHX(64_raw);
6275 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_raw);
6276 0487d6a8 j_mayer
GEN_OP_SPE_LHX(le_64_raw);
6277 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_raw);
6278 0487d6a8 j_mayer
#endif
6279 0487d6a8 j_mayer
#else
6280 0487d6a8 j_mayer
GEN_OP_SPE_LHE(kernel);
6281 0487d6a8 j_mayer
GEN_OP_SPE_LHE(user);
6282 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, kernel);
6283 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, user);
6284 0487d6a8 j_mayer
GEN_OP_SPE_LHE(le_kernel);
6285 0487d6a8 j_mayer
GEN_OP_SPE_LHE(le_user);
6286 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_kernel);
6287 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_user);
6288 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, kernel);
6289 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, user);
6290 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_kernel);
6291 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_user);
6292 0487d6a8 j_mayer
GEN_OP_SPE_LHX(kernel);
6293 0487d6a8 j_mayer
GEN_OP_SPE_LHX(user);
6294 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, kernel);
6295 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, user);
6296 0487d6a8 j_mayer
GEN_OP_SPE_LHX(le_kernel);
6297 0487d6a8 j_mayer
GEN_OP_SPE_LHX(le_user);
6298 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_kernel);
6299 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_user);
6300 0487d6a8 j_mayer
#if defined(TARGET_PPC64)
6301 0487d6a8 j_mayer
GEN_OP_SPE_LHE(64_kernel);
6302 0487d6a8 j_mayer
GEN_OP_SPE_LHE(64_user);
6303 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_kernel);
6304 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_user);
6305 0487d6a8 j_mayer
GEN_OP_SPE_LHE(le_64_kernel);
6306 0487d6a8 j_mayer
GEN_OP_SPE_LHE(le_64_user);
6307 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_kernel);
6308 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_user);
6309 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_kernel);
6310 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_user);
6311 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_kernel);
6312 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_user);
6313 0487d6a8 j_mayer
GEN_OP_SPE_LHX(64_kernel);
6314 0487d6a8 j_mayer
GEN_OP_SPE_LHX(64_user);
6315 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_kernel);
6316 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_user);
6317 0487d6a8 j_mayer
GEN_OP_SPE_LHX(le_64_kernel);
6318 0487d6a8 j_mayer
GEN_OP_SPE_LHX(le_64_user);
6319 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_kernel);
6320 0487d6a8 j_mayer
GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_user);
6321 0487d6a8 j_mayer
#endif
6322 0487d6a8 j_mayer
#endif
6323 0487d6a8 j_mayer
GEN_SPEOP_LD(hhesplat, 1);
6324 0487d6a8 j_mayer
GEN_SPEOP_LD(hhousplat, 1);
6325 0487d6a8 j_mayer
GEN_SPEOP_LD(hhossplat, 1);
6326 0487d6a8 j_mayer
GEN_SPEOP_LD(wwsplat, 2);
6327 0487d6a8 j_mayer
GEN_SPEOP_LD(whsplat, 2);
6328 0487d6a8 j_mayer
6329 0487d6a8 j_mayer
GEN_SPE(evlddx,         evldd,         0x00, 0x0C, 0x00000000, PPC_SPE); //
6330 0487d6a8 j_mayer
GEN_SPE(evldwx,         evldw,         0x01, 0x0C, 0x00000000, PPC_SPE); //
6331 0487d6a8 j_mayer
GEN_SPE(evldhx,         evldh,         0x02, 0x0C, 0x00000000, PPC_SPE); //
6332 0487d6a8 j_mayer
GEN_SPE(evlhhesplatx,   evlhhesplat,   0x04, 0x0C, 0x00000000, PPC_SPE); //
6333 0487d6a8 j_mayer
GEN_SPE(evlhhousplatx,  evlhhousplat,  0x06, 0x0C, 0x00000000, PPC_SPE); //
6334 0487d6a8 j_mayer
GEN_SPE(evlhhossplatx,  evlhhossplat,  0x07, 0x0C, 0x00000000, PPC_SPE); //
6335 0487d6a8 j_mayer
GEN_SPE(evlwhex,        evlwhe,        0x08, 0x0C, 0x00000000, PPC_SPE); //
6336 0487d6a8 j_mayer
GEN_SPE(evlwhoux,       evlwhou,       0x0A, 0x0C, 0x00000000, PPC_SPE); //
6337 0487d6a8 j_mayer
GEN_SPE(evlwhosx,       evlwhos,       0x0B, 0x0C, 0x00000000, PPC_SPE); //
6338 0487d6a8 j_mayer
GEN_SPE(evlwwsplatx,    evlwwsplat,    0x0C, 0x0C, 0x00000000, PPC_SPE); //
6339 0487d6a8 j_mayer
GEN_SPE(evlwhsplatx,    evlwhsplat,    0x0E, 0x0C, 0x00000000, PPC_SPE); //
6340 0487d6a8 j_mayer
GEN_SPE(evstddx,        evstdd,        0x10, 0x0C, 0x00000000, PPC_SPE); //
6341 0487d6a8 j_mayer
GEN_SPE(evstdwx,        evstdw,        0x11, 0x0C, 0x00000000, PPC_SPE); //
6342 0487d6a8 j_mayer
GEN_SPE(evstdhx,        evstdh,        0x12, 0x0C, 0x00000000, PPC_SPE); //
6343 0487d6a8 j_mayer
GEN_SPE(evstwhex,       evstwhe,       0x18, 0x0C, 0x00000000, PPC_SPE); //
6344 0487d6a8 j_mayer
GEN_SPE(evstwhox,       evstwho,       0x1A, 0x0C, 0x00000000, PPC_SPE); //
6345 0487d6a8 j_mayer
GEN_SPE(evstwwex,       evstwwe,       0x1C, 0x0C, 0x00000000, PPC_SPE); //
6346 0487d6a8 j_mayer
GEN_SPE(evstwwox,       evstwwo,       0x1E, 0x0C, 0x00000000, PPC_SPE); //
6347 0487d6a8 j_mayer
6348 0487d6a8 j_mayer
/* Multiply and add - TODO */
6349 0487d6a8 j_mayer
#if 0
6350 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
6351 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
6352 0487d6a8 j_mayer
GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
6353 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
6354 0487d6a8 j_mayer
GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
6355 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
6356 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
6357 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
6358 0487d6a8 j_mayer
GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
6359 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
6360 0487d6a8 j_mayer
GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
6361 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
6362 0487d6a8 j_mayer

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

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

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

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

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

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