Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 57fec1fe

History | View | Annotate | Download (219.4 kB)

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

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

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

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

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

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

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