Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 16415335

History | View | Annotate | Download (334.6 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 8167ee88 Blue Swirl
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 79aceca5 bellard
 */
19 c6a1c22b bellard
#include <stdarg.h>
20 c6a1c22b bellard
#include <stdlib.h>
21 c6a1c22b bellard
#include <stdio.h>
22 c6a1c22b bellard
#include <string.h>
23 c6a1c22b bellard
#include <inttypes.h>
24 c6a1c22b bellard
25 79aceca5 bellard
#include "cpu.h"
26 c6a1c22b bellard
#include "exec-all.h"
27 79aceca5 bellard
#include "disas.h"
28 57fec1fe bellard
#include "tcg-op.h"
29 ca10f867 aurel32
#include "qemu-common.h"
30 0cfe11ea aurel32
#include "host-utils.h"
31 79aceca5 bellard
32 a7812ae4 pbrook
#include "helper.h"
33 a7812ae4 pbrook
#define GEN_HELPER 1
34 a7812ae4 pbrook
#include "helper.h"
35 a7812ae4 pbrook
36 8cbcb4fa aurel32
#define CPU_SINGLE_STEP 0x1
37 8cbcb4fa aurel32
#define CPU_BRANCH_STEP 0x2
38 8cbcb4fa aurel32
#define GDBSTUB_SINGLE_STEP 0x4
39 8cbcb4fa aurel32
40 a750fc0b j_mayer
/* Include definitions for instructions classes and implementations flags */
41 9fddaa0c bellard
//#define PPC_DEBUG_DISAS
42 76a66253 j_mayer
//#define DO_PPC_STATISTICS
43 79aceca5 bellard
44 d12d51d5 aliguori
#ifdef PPC_DEBUG_DISAS
45 93fcfe39 aliguori
#  define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
46 d12d51d5 aliguori
#else
47 d12d51d5 aliguori
#  define LOG_DISAS(...) do { } while (0)
48 d12d51d5 aliguori
#endif
49 a750fc0b j_mayer
/*****************************************************************************/
50 a750fc0b j_mayer
/* Code translation helpers                                                  */
51 c53be334 bellard
52 f78fb44e aurel32
/* global register indexes */
53 a7812ae4 pbrook
static TCGv_ptr cpu_env;
54 1d542695 aurel32
static char cpu_reg_names[10*3 + 22*4 /* GPR */
55 f78fb44e aurel32
#if !defined(TARGET_PPC64)
56 1d542695 aurel32
    + 10*4 + 22*5 /* SPE GPRh */
57 f78fb44e aurel32
#endif
58 a5e26afa aurel32
    + 10*4 + 22*5 /* FPR */
59 47e4661c aurel32
    + 2*(10*6 + 22*7) /* AVRh, AVRl */
60 47e4661c aurel32
    + 8*5 /* CRF */];
61 f78fb44e aurel32
static TCGv cpu_gpr[32];
62 f78fb44e aurel32
#if !defined(TARGET_PPC64)
63 f78fb44e aurel32
static TCGv cpu_gprh[32];
64 f78fb44e aurel32
#endif
65 a7812ae4 pbrook
static TCGv_i64 cpu_fpr[32];
66 a7812ae4 pbrook
static TCGv_i64 cpu_avrh[32], cpu_avrl[32];
67 a7812ae4 pbrook
static TCGv_i32 cpu_crf[8];
68 bd568f18 aurel32
static TCGv cpu_nip;
69 6527f6ea aurel32
static TCGv cpu_msr;
70 cfdcd37a aurel32
static TCGv cpu_ctr;
71 cfdcd37a aurel32
static TCGv cpu_lr;
72 3d7b417e aurel32
static TCGv cpu_xer;
73 cf360a32 aurel32
static TCGv cpu_reserve;
74 a7812ae4 pbrook
static TCGv_i32 cpu_fpscr;
75 a7859e89 aurel32
static TCGv_i32 cpu_access_type;
76 f78fb44e aurel32
77 2e70f6ef pbrook
#include "gen-icount.h"
78 2e70f6ef pbrook
79 2e70f6ef pbrook
void ppc_translate_init(void)
80 2e70f6ef pbrook
{
81 f78fb44e aurel32
    int i;
82 f78fb44e aurel32
    char* p;
83 2dc766da blueswir1
    size_t cpu_reg_names_size;
84 b2437bf2 pbrook
    static int done_init = 0;
85 f78fb44e aurel32
86 2e70f6ef pbrook
    if (done_init)
87 2e70f6ef pbrook
        return;
88 f78fb44e aurel32
89 a7812ae4 pbrook
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
90 a7812ae4 pbrook
91 f78fb44e aurel32
    p = cpu_reg_names;
92 2dc766da blueswir1
    cpu_reg_names_size = sizeof(cpu_reg_names);
93 47e4661c aurel32
94 47e4661c aurel32
    for (i = 0; i < 8; i++) {
95 2dc766da blueswir1
        snprintf(p, cpu_reg_names_size, "crf%d", i);
96 a7812ae4 pbrook
        cpu_crf[i] = tcg_global_mem_new_i32(TCG_AREG0,
97 a7812ae4 pbrook
                                            offsetof(CPUState, crf[i]), p);
98 47e4661c aurel32
        p += 5;
99 2dc766da blueswir1
        cpu_reg_names_size -= 5;
100 47e4661c aurel32
    }
101 47e4661c aurel32
102 f78fb44e aurel32
    for (i = 0; i < 32; i++) {
103 2dc766da blueswir1
        snprintf(p, cpu_reg_names_size, "r%d", i);
104 a7812ae4 pbrook
        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
105 f78fb44e aurel32
                                        offsetof(CPUState, gpr[i]), p);
106 f78fb44e aurel32
        p += (i < 10) ? 3 : 4;
107 2dc766da blueswir1
        cpu_reg_names_size -= (i < 10) ? 3 : 4;
108 f78fb44e aurel32
#if !defined(TARGET_PPC64)
109 2dc766da blueswir1
        snprintf(p, cpu_reg_names_size, "r%dH", i);
110 a7812ae4 pbrook
        cpu_gprh[i] = tcg_global_mem_new_i32(TCG_AREG0,
111 a7812ae4 pbrook
                                             offsetof(CPUState, gprh[i]), p);
112 f78fb44e aurel32
        p += (i < 10) ? 4 : 5;
113 2dc766da blueswir1
        cpu_reg_names_size -= (i < 10) ? 4 : 5;
114 f78fb44e aurel32
#endif
115 1d542695 aurel32
116 2dc766da blueswir1
        snprintf(p, cpu_reg_names_size, "fp%d", i);
117 a7812ae4 pbrook
        cpu_fpr[i] = tcg_global_mem_new_i64(TCG_AREG0,
118 a7812ae4 pbrook
                                            offsetof(CPUState, fpr[i]), p);
119 ec1ac72d aurel32
        p += (i < 10) ? 4 : 5;
120 2dc766da blueswir1
        cpu_reg_names_size -= (i < 10) ? 4 : 5;
121 a5e26afa aurel32
122 2dc766da blueswir1
        snprintf(p, cpu_reg_names_size, "avr%dH", i);
123 fe1e5c53 aurel32
#ifdef WORDS_BIGENDIAN
124 fe1e5c53 aurel32
        cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,
125 fe1e5c53 aurel32
                                             offsetof(CPUState, avr[i].u64[0]), p);
126 fe1e5c53 aurel32
#else
127 a7812ae4 pbrook
        cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,
128 fe1e5c53 aurel32
                                             offsetof(CPUState, avr[i].u64[1]), p);
129 fe1e5c53 aurel32
#endif
130 1d542695 aurel32
        p += (i < 10) ? 6 : 7;
131 2dc766da blueswir1
        cpu_reg_names_size -= (i < 10) ? 6 : 7;
132 ec1ac72d aurel32
133 2dc766da blueswir1
        snprintf(p, cpu_reg_names_size, "avr%dL", i);
134 fe1e5c53 aurel32
#ifdef WORDS_BIGENDIAN
135 fe1e5c53 aurel32
        cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,
136 fe1e5c53 aurel32
                                             offsetof(CPUState, avr[i].u64[1]), p);
137 fe1e5c53 aurel32
#else
138 a7812ae4 pbrook
        cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,
139 fe1e5c53 aurel32
                                             offsetof(CPUState, avr[i].u64[0]), p);
140 fe1e5c53 aurel32
#endif
141 1d542695 aurel32
        p += (i < 10) ? 6 : 7;
142 2dc766da blueswir1
        cpu_reg_names_size -= (i < 10) ? 6 : 7;
143 f78fb44e aurel32
    }
144 f10dc08e aurel32
145 a7812ae4 pbrook
    cpu_nip = tcg_global_mem_new(TCG_AREG0,
146 bd568f18 aurel32
                                 offsetof(CPUState, nip), "nip");
147 bd568f18 aurel32
148 6527f6ea aurel32
    cpu_msr = tcg_global_mem_new(TCG_AREG0,
149 6527f6ea aurel32
                                 offsetof(CPUState, msr), "msr");
150 6527f6ea aurel32
151 a7812ae4 pbrook
    cpu_ctr = tcg_global_mem_new(TCG_AREG0,
152 cfdcd37a aurel32
                                 offsetof(CPUState, ctr), "ctr");
153 cfdcd37a aurel32
154 a7812ae4 pbrook
    cpu_lr = tcg_global_mem_new(TCG_AREG0,
155 cfdcd37a aurel32
                                offsetof(CPUState, lr), "lr");
156 cfdcd37a aurel32
157 a7812ae4 pbrook
    cpu_xer = tcg_global_mem_new(TCG_AREG0,
158 3d7b417e aurel32
                                 offsetof(CPUState, xer), "xer");
159 3d7b417e aurel32
160 cf360a32 aurel32
    cpu_reserve = tcg_global_mem_new(TCG_AREG0,
161 cf360a32 aurel32
                                     offsetof(CPUState, reserve), "reserve");
162 cf360a32 aurel32
163 a7812ae4 pbrook
    cpu_fpscr = tcg_global_mem_new_i32(TCG_AREG0,
164 a7812ae4 pbrook
                                       offsetof(CPUState, fpscr), "fpscr");
165 e1571908 aurel32
166 a7859e89 aurel32
    cpu_access_type = tcg_global_mem_new_i32(TCG_AREG0,
167 a7859e89 aurel32
                                             offsetof(CPUState, access_type), "access_type");
168 a7859e89 aurel32
169 f10dc08e aurel32
    /* register helpers */
170 a7812ae4 pbrook
#define GEN_HELPER 2
171 f10dc08e aurel32
#include "helper.h"
172 f10dc08e aurel32
173 2e70f6ef pbrook
    done_init = 1;
174 2e70f6ef pbrook
}
175 2e70f6ef pbrook
176 79aceca5 bellard
/* internal defines */
177 79aceca5 bellard
typedef struct DisasContext {
178 79aceca5 bellard
    struct TranslationBlock *tb;
179 0fa85d43 bellard
    target_ulong nip;
180 79aceca5 bellard
    uint32_t opcode;
181 9a64fbe4 bellard
    uint32_t exception;
182 3cc62370 bellard
    /* Routine used to access memory */
183 3cc62370 bellard
    int mem_idx;
184 76db3ba4 aurel32
    int access_type;
185 3cc62370 bellard
    /* Translation flags */
186 76db3ba4 aurel32
    int le_mode;
187 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
188 d9bce9d9 j_mayer
    int sf_mode;
189 d9bce9d9 j_mayer
#endif
190 3cc62370 bellard
    int fpu_enabled;
191 a9d9eb8f j_mayer
    int altivec_enabled;
192 0487d6a8 j_mayer
    int spe_enabled;
193 3fc6c082 bellard
    ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
194 ea4e754f bellard
    int singlestep_enabled;
195 79aceca5 bellard
} DisasContext;
196 79aceca5 bellard
197 3fc6c082 bellard
struct opc_handler_t {
198 79aceca5 bellard
    /* invalid bits */
199 79aceca5 bellard
    uint32_t inval;
200 9a64fbe4 bellard
    /* instruction type */
201 0487d6a8 j_mayer
    uint64_t type;
202 79aceca5 bellard
    /* handler */
203 79aceca5 bellard
    void (*handler)(DisasContext *ctx);
204 a750fc0b j_mayer
#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
205 b55266b5 blueswir1
    const char *oname;
206 a750fc0b j_mayer
#endif
207 a750fc0b j_mayer
#if defined(DO_PPC_STATISTICS)
208 76a66253 j_mayer
    uint64_t count;
209 76a66253 j_mayer
#endif
210 3fc6c082 bellard
};
211 79aceca5 bellard
212 7c58044c j_mayer
static always_inline void gen_reset_fpstatus (void)
213 7c58044c j_mayer
{
214 7c58044c j_mayer
#ifdef CONFIG_SOFTFLOAT
215 a44d2ce1 aurel32
    gen_helper_reset_fpstatus();
216 7c58044c j_mayer
#endif
217 7c58044c j_mayer
}
218 7c58044c j_mayer
219 0f2f39c2 aurel32
static always_inline void gen_compute_fprf (TCGv_i64 arg, int set_fprf, int set_rc)
220 7c58044c j_mayer
{
221 0f2f39c2 aurel32
    TCGv_i32 t0 = tcg_temp_new_i32();
222 af12906f aurel32
223 7c58044c j_mayer
    if (set_fprf != 0) {
224 7c58044c j_mayer
        /* This case might be optimized later */
225 0f2f39c2 aurel32
        tcg_gen_movi_i32(t0, 1);
226 af12906f aurel32
        gen_helper_compute_fprf(t0, arg, t0);
227 a7812ae4 pbrook
        if (unlikely(set_rc)) {
228 0f2f39c2 aurel32
            tcg_gen_mov_i32(cpu_crf[1], t0);
229 a7812ae4 pbrook
        }
230 af12906f aurel32
        gen_helper_float_check_status();
231 7c58044c j_mayer
    } else if (unlikely(set_rc)) {
232 7c58044c j_mayer
        /* We always need to compute fpcc */
233 0f2f39c2 aurel32
        tcg_gen_movi_i32(t0, 0);
234 af12906f aurel32
        gen_helper_compute_fprf(t0, arg, t0);
235 0f2f39c2 aurel32
        tcg_gen_mov_i32(cpu_crf[1], t0);
236 7c58044c j_mayer
    }
237 af12906f aurel32
238 0f2f39c2 aurel32
    tcg_temp_free_i32(t0);
239 7c58044c j_mayer
}
240 7c58044c j_mayer
241 76db3ba4 aurel32
static always_inline void gen_set_access_type (DisasContext *ctx, int access_type)
242 a7859e89 aurel32
{
243 76db3ba4 aurel32
    if (ctx->access_type != access_type) {
244 76db3ba4 aurel32
        tcg_gen_movi_i32(cpu_access_type, access_type);
245 76db3ba4 aurel32
        ctx->access_type = access_type;
246 76db3ba4 aurel32
    }
247 a7859e89 aurel32
}
248 a7859e89 aurel32
249 b068d6a7 j_mayer
static always_inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
250 d9bce9d9 j_mayer
{
251 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
252 d9bce9d9 j_mayer
    if (ctx->sf_mode)
253 bd568f18 aurel32
        tcg_gen_movi_tl(cpu_nip, nip);
254 d9bce9d9 j_mayer
    else
255 d9bce9d9 j_mayer
#endif
256 bd568f18 aurel32
        tcg_gen_movi_tl(cpu_nip, (uint32_t)nip);
257 d9bce9d9 j_mayer
}
258 d9bce9d9 j_mayer
259 e06fcd75 aurel32
static always_inline void gen_exception_err (DisasContext *ctx, uint32_t excp, uint32_t error)
260 e06fcd75 aurel32
{
261 e06fcd75 aurel32
    TCGv_i32 t0, t1;
262 e06fcd75 aurel32
    if (ctx->exception == POWERPC_EXCP_NONE) {
263 e06fcd75 aurel32
        gen_update_nip(ctx, ctx->nip);
264 e06fcd75 aurel32
    }
265 e06fcd75 aurel32
    t0 = tcg_const_i32(excp);
266 e06fcd75 aurel32
    t1 = tcg_const_i32(error);
267 e06fcd75 aurel32
    gen_helper_raise_exception_err(t0, t1);
268 e06fcd75 aurel32
    tcg_temp_free_i32(t0);
269 e06fcd75 aurel32
    tcg_temp_free_i32(t1);
270 e06fcd75 aurel32
    ctx->exception = (excp);
271 e06fcd75 aurel32
}
272 e1833e1f j_mayer
273 e06fcd75 aurel32
static always_inline void gen_exception (DisasContext *ctx, uint32_t excp)
274 e06fcd75 aurel32
{
275 e06fcd75 aurel32
    TCGv_i32 t0;
276 e06fcd75 aurel32
    if (ctx->exception == POWERPC_EXCP_NONE) {
277 e06fcd75 aurel32
        gen_update_nip(ctx, ctx->nip);
278 e06fcd75 aurel32
    }
279 e06fcd75 aurel32
    t0 = tcg_const_i32(excp);
280 e06fcd75 aurel32
    gen_helper_raise_exception(t0);
281 e06fcd75 aurel32
    tcg_temp_free_i32(t0);
282 e06fcd75 aurel32
    ctx->exception = (excp);
283 e06fcd75 aurel32
}
284 e1833e1f j_mayer
285 e06fcd75 aurel32
static always_inline void gen_debug_exception (DisasContext *ctx)
286 e06fcd75 aurel32
{
287 e06fcd75 aurel32
    TCGv_i32 t0;
288 5518f3a6 blueswir1
289 5518f3a6 blueswir1
    if (ctx->exception != POWERPC_EXCP_BRANCH)
290 5518f3a6 blueswir1
        gen_update_nip(ctx, ctx->nip);
291 e06fcd75 aurel32
    t0 = tcg_const_i32(EXCP_DEBUG);
292 e06fcd75 aurel32
    gen_helper_raise_exception(t0);
293 e06fcd75 aurel32
    tcg_temp_free_i32(t0);
294 e06fcd75 aurel32
}
295 9a64fbe4 bellard
296 e06fcd75 aurel32
static always_inline void gen_inval_exception (DisasContext *ctx, uint32_t error)
297 e06fcd75 aurel32
{
298 e06fcd75 aurel32
    gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | error);
299 e06fcd75 aurel32
}
300 a9d9eb8f j_mayer
301 f24e5695 bellard
/* Stop translation */
302 e06fcd75 aurel32
static always_inline void gen_stop_exception (DisasContext *ctx)
303 3fc6c082 bellard
{
304 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip);
305 e1833e1f j_mayer
    ctx->exception = POWERPC_EXCP_STOP;
306 3fc6c082 bellard
}
307 3fc6c082 bellard
308 f24e5695 bellard
/* No need to update nip here, as execution flow will change */
309 e06fcd75 aurel32
static always_inline void gen_sync_exception (DisasContext *ctx)
310 2be0071f bellard
{
311 e1833e1f j_mayer
    ctx->exception = POWERPC_EXCP_SYNC;
312 2be0071f bellard
}
313 2be0071f bellard
314 79aceca5 bellard
#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
315 5c55ff99 Blue Swirl
GEN_OPCODE(name, opc1, opc2, opc3, inval, type)
316 79aceca5 bellard
317 c7697e1f j_mayer
#define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type)               \
318 5c55ff99 Blue Swirl
GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type)
319 c7697e1f j_mayer
320 79aceca5 bellard
typedef struct opcode_t {
321 79aceca5 bellard
    unsigned char opc1, opc2, opc3;
322 1235fc06 ths
#if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */
323 18fba28c bellard
    unsigned char pad[5];
324 18fba28c bellard
#else
325 18fba28c bellard
    unsigned char pad[1];
326 18fba28c bellard
#endif
327 79aceca5 bellard
    opc_handler_t handler;
328 b55266b5 blueswir1
    const char *oname;
329 79aceca5 bellard
} opcode_t;
330 79aceca5 bellard
331 a750fc0b j_mayer
/*****************************************************************************/
332 79aceca5 bellard
/***                           Instruction decoding                        ***/
333 79aceca5 bellard
#define EXTRACT_HELPER(name, shift, nb)                                       \
334 b068d6a7 j_mayer
static always_inline uint32_t name (uint32_t opcode)                          \
335 79aceca5 bellard
{                                                                             \
336 79aceca5 bellard
    return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
337 79aceca5 bellard
}
338 79aceca5 bellard
339 79aceca5 bellard
#define EXTRACT_SHELPER(name, shift, nb)                                      \
340 b068d6a7 j_mayer
static always_inline int32_t name (uint32_t opcode)                           \
341 79aceca5 bellard
{                                                                             \
342 18fba28c bellard
    return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
343 79aceca5 bellard
}
344 79aceca5 bellard
345 79aceca5 bellard
/* Opcode part 1 */
346 79aceca5 bellard
EXTRACT_HELPER(opc1, 26, 6);
347 79aceca5 bellard
/* Opcode part 2 */
348 79aceca5 bellard
EXTRACT_HELPER(opc2, 1, 5);
349 79aceca5 bellard
/* Opcode part 3 */
350 79aceca5 bellard
EXTRACT_HELPER(opc3, 6, 5);
351 79aceca5 bellard
/* Update Cr0 flags */
352 79aceca5 bellard
EXTRACT_HELPER(Rc, 0, 1);
353 79aceca5 bellard
/* Destination */
354 79aceca5 bellard
EXTRACT_HELPER(rD, 21, 5);
355 79aceca5 bellard
/* Source */
356 79aceca5 bellard
EXTRACT_HELPER(rS, 21, 5);
357 79aceca5 bellard
/* First operand */
358 79aceca5 bellard
EXTRACT_HELPER(rA, 16, 5);
359 79aceca5 bellard
/* Second operand */
360 79aceca5 bellard
EXTRACT_HELPER(rB, 11, 5);
361 79aceca5 bellard
/* Third operand */
362 79aceca5 bellard
EXTRACT_HELPER(rC, 6, 5);
363 79aceca5 bellard
/***                               Get CRn                                 ***/
364 79aceca5 bellard
EXTRACT_HELPER(crfD, 23, 3);
365 79aceca5 bellard
EXTRACT_HELPER(crfS, 18, 3);
366 79aceca5 bellard
EXTRACT_HELPER(crbD, 21, 5);
367 79aceca5 bellard
EXTRACT_HELPER(crbA, 16, 5);
368 79aceca5 bellard
EXTRACT_HELPER(crbB, 11, 5);
369 79aceca5 bellard
/* SPR / TBL */
370 3fc6c082 bellard
EXTRACT_HELPER(_SPR, 11, 10);
371 b068d6a7 j_mayer
static always_inline uint32_t SPR (uint32_t opcode)
372 3fc6c082 bellard
{
373 3fc6c082 bellard
    uint32_t sprn = _SPR(opcode);
374 3fc6c082 bellard
375 3fc6c082 bellard
    return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
376 3fc6c082 bellard
}
377 79aceca5 bellard
/***                              Get constants                            ***/
378 79aceca5 bellard
EXTRACT_HELPER(IMM, 12, 8);
379 79aceca5 bellard
/* 16 bits signed immediate value */
380 79aceca5 bellard
EXTRACT_SHELPER(SIMM, 0, 16);
381 79aceca5 bellard
/* 16 bits unsigned immediate value */
382 79aceca5 bellard
EXTRACT_HELPER(UIMM, 0, 16);
383 21d21583 aurel32
/* 5 bits signed immediate value */
384 21d21583 aurel32
EXTRACT_HELPER(SIMM5, 16, 5);
385 27a4edb3 aurel32
/* 5 bits signed immediate value */
386 27a4edb3 aurel32
EXTRACT_HELPER(UIMM5, 16, 5);
387 79aceca5 bellard
/* Bit count */
388 79aceca5 bellard
EXTRACT_HELPER(NB, 11, 5);
389 79aceca5 bellard
/* Shift count */
390 79aceca5 bellard
EXTRACT_HELPER(SH, 11, 5);
391 cd633b10 aurel32
/* Vector shift count */
392 cd633b10 aurel32
EXTRACT_HELPER(VSH, 6, 4);
393 79aceca5 bellard
/* Mask start */
394 79aceca5 bellard
EXTRACT_HELPER(MB, 6, 5);
395 79aceca5 bellard
/* Mask end */
396 79aceca5 bellard
EXTRACT_HELPER(ME, 1, 5);
397 fb0eaffc bellard
/* Trap operand */
398 fb0eaffc bellard
EXTRACT_HELPER(TO, 21, 5);
399 79aceca5 bellard
400 79aceca5 bellard
EXTRACT_HELPER(CRM, 12, 8);
401 79aceca5 bellard
EXTRACT_HELPER(FM, 17, 8);
402 79aceca5 bellard
EXTRACT_HELPER(SR, 16, 4);
403 e4bb997e aurel32
EXTRACT_HELPER(FPIMM, 12, 4);
404 fb0eaffc bellard
405 79aceca5 bellard
/***                            Jump target decoding                       ***/
406 79aceca5 bellard
/* Displacement */
407 79aceca5 bellard
EXTRACT_SHELPER(d, 0, 16);
408 79aceca5 bellard
/* Immediate address */
409 b068d6a7 j_mayer
static always_inline target_ulong LI (uint32_t opcode)
410 79aceca5 bellard
{
411 79aceca5 bellard
    return (opcode >> 0) & 0x03FFFFFC;
412 79aceca5 bellard
}
413 79aceca5 bellard
414 b068d6a7 j_mayer
static always_inline uint32_t BD (uint32_t opcode)
415 79aceca5 bellard
{
416 79aceca5 bellard
    return (opcode >> 0) & 0xFFFC;
417 79aceca5 bellard
}
418 79aceca5 bellard
419 79aceca5 bellard
EXTRACT_HELPER(BO, 21, 5);
420 79aceca5 bellard
EXTRACT_HELPER(BI, 16, 5);
421 79aceca5 bellard
/* Absolute/relative address */
422 79aceca5 bellard
EXTRACT_HELPER(AA, 1, 1);
423 79aceca5 bellard
/* Link */
424 79aceca5 bellard
EXTRACT_HELPER(LK, 0, 1);
425 79aceca5 bellard
426 79aceca5 bellard
/* Create a mask between <start> and <end> bits */
427 b068d6a7 j_mayer
static always_inline target_ulong MASK (uint32_t start, uint32_t end)
428 79aceca5 bellard
{
429 76a66253 j_mayer
    target_ulong ret;
430 79aceca5 bellard
431 76a66253 j_mayer
#if defined(TARGET_PPC64)
432 76a66253 j_mayer
    if (likely(start == 0)) {
433 6f2d8978 j_mayer
        ret = UINT64_MAX << (63 - end);
434 76a66253 j_mayer
    } else if (likely(end == 63)) {
435 6f2d8978 j_mayer
        ret = UINT64_MAX >> start;
436 76a66253 j_mayer
    }
437 76a66253 j_mayer
#else
438 76a66253 j_mayer
    if (likely(start == 0)) {
439 6f2d8978 j_mayer
        ret = UINT32_MAX << (31  - end);
440 76a66253 j_mayer
    } else if (likely(end == 31)) {
441 6f2d8978 j_mayer
        ret = UINT32_MAX >> start;
442 76a66253 j_mayer
    }
443 76a66253 j_mayer
#endif
444 76a66253 j_mayer
    else {
445 76a66253 j_mayer
        ret = (((target_ulong)(-1ULL)) >> (start)) ^
446 76a66253 j_mayer
            (((target_ulong)(-1ULL) >> (end)) >> 1);
447 76a66253 j_mayer
        if (unlikely(start > end))
448 76a66253 j_mayer
            return ~ret;
449 76a66253 j_mayer
    }
450 79aceca5 bellard
451 79aceca5 bellard
    return ret;
452 79aceca5 bellard
}
453 79aceca5 bellard
454 a750fc0b j_mayer
/*****************************************************************************/
455 a750fc0b j_mayer
/* PowerPC instructions table                                                */
456 933dc6eb bellard
457 76a66253 j_mayer
#if defined(DO_PPC_STATISTICS)
458 79aceca5 bellard
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
459 5c55ff99 Blue Swirl
{                                                                             \
460 79aceca5 bellard
    .opc1 = op1,                                                              \
461 79aceca5 bellard
    .opc2 = op2,                                                              \
462 79aceca5 bellard
    .opc3 = op3,                                                              \
463 18fba28c bellard
    .pad  = { 0, },                                                           \
464 79aceca5 bellard
    .handler = {                                                              \
465 79aceca5 bellard
        .inval   = invl,                                                      \
466 9a64fbe4 bellard
        .type = _typ,                                                         \
467 79aceca5 bellard
        .handler = &gen_##name,                                               \
468 76a66253 j_mayer
        .oname = stringify(name),                                             \
469 79aceca5 bellard
    },                                                                        \
470 3fc6c082 bellard
    .oname = stringify(name),                                                 \
471 79aceca5 bellard
}
472 c7697e1f j_mayer
#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ)                    \
473 5c55ff99 Blue Swirl
{                                                                             \
474 c7697e1f j_mayer
    .opc1 = op1,                                                              \
475 c7697e1f j_mayer
    .opc2 = op2,                                                              \
476 c7697e1f j_mayer
    .opc3 = op3,                                                              \
477 c7697e1f j_mayer
    .pad  = { 0, },                                                           \
478 c7697e1f j_mayer
    .handler = {                                                              \
479 c7697e1f j_mayer
        .inval   = invl,                                                      \
480 c7697e1f j_mayer
        .type = _typ,                                                         \
481 c7697e1f j_mayer
        .handler = &gen_##name,                                               \
482 c7697e1f j_mayer
        .oname = onam,                                                        \
483 c7697e1f j_mayer
    },                                                                        \
484 c7697e1f j_mayer
    .oname = onam,                                                            \
485 c7697e1f j_mayer
}
486 76a66253 j_mayer
#else
487 76a66253 j_mayer
#define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
488 5c55ff99 Blue Swirl
{                                                                             \
489 c7697e1f j_mayer
    .opc1 = op1,                                                              \
490 c7697e1f j_mayer
    .opc2 = op2,                                                              \
491 c7697e1f j_mayer
    .opc3 = op3,                                                              \
492 c7697e1f j_mayer
    .pad  = { 0, },                                                           \
493 c7697e1f j_mayer
    .handler = {                                                              \
494 c7697e1f j_mayer
        .inval   = invl,                                                      \
495 c7697e1f j_mayer
        .type = _typ,                                                         \
496 c7697e1f j_mayer
        .handler = &gen_##name,                                               \
497 5c55ff99 Blue Swirl
    },                                                                        \
498 5c55ff99 Blue Swirl
    .oname = stringify(name),                                                 \
499 5c55ff99 Blue Swirl
}
500 5c55ff99 Blue Swirl
#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ)                    \
501 5c55ff99 Blue Swirl
{                                                                             \
502 5c55ff99 Blue Swirl
    .opc1 = op1,                                                              \
503 5c55ff99 Blue Swirl
    .opc2 = op2,                                                              \
504 5c55ff99 Blue Swirl
    .opc3 = op3,                                                              \
505 5c55ff99 Blue Swirl
    .pad  = { 0, },                                                           \
506 5c55ff99 Blue Swirl
    .handler = {                                                              \
507 5c55ff99 Blue Swirl
        .inval   = invl,                                                      \
508 5c55ff99 Blue Swirl
        .type = _typ,                                                         \
509 5c55ff99 Blue Swirl
        .handler = &gen_##name,                                               \
510 5c55ff99 Blue Swirl
    },                                                                        \
511 5c55ff99 Blue Swirl
    .oname = onam,                                                            \
512 5c55ff99 Blue Swirl
}
513 5c55ff99 Blue Swirl
#endif
514 2e610050 Blue Swirl
515 5c55ff99 Blue Swirl
/* SPR load/store helpers */
516 5c55ff99 Blue Swirl
static always_inline void gen_load_spr(TCGv t, int reg)
517 5c55ff99 Blue Swirl
{
518 5c55ff99 Blue Swirl
    tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, spr[reg]));
519 5c55ff99 Blue Swirl
}
520 2e610050 Blue Swirl
521 5c55ff99 Blue Swirl
static always_inline void gen_store_spr(int reg, TCGv t)
522 5c55ff99 Blue Swirl
{
523 5c55ff99 Blue Swirl
    tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, spr[reg]));
524 5c55ff99 Blue Swirl
}
525 2e610050 Blue Swirl
526 54623277 Blue Swirl
/* Invalid instruction */
527 99e300ef Blue Swirl
static void gen_invalid(DisasContext *ctx)
528 9a64fbe4 bellard
{
529 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
530 9a64fbe4 bellard
}
531 9a64fbe4 bellard
532 79aceca5 bellard
static opc_handler_t invalid_handler = {
533 79aceca5 bellard
    .inval   = 0xFFFFFFFF,
534 9a64fbe4 bellard
    .type    = PPC_NONE,
535 79aceca5 bellard
    .handler = gen_invalid,
536 79aceca5 bellard
};
537 79aceca5 bellard
538 e1571908 aurel32
/***                           Integer comparison                          ***/
539 e1571908 aurel32
540 ea363694 aurel32
static always_inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf)
541 e1571908 aurel32
{
542 e1571908 aurel32
    int l1, l2, l3;
543 e1571908 aurel32
544 269f3e95 aurel32
    tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_xer);
545 269f3e95 aurel32
    tcg_gen_shri_i32(cpu_crf[crf], cpu_crf[crf], XER_SO);
546 e1571908 aurel32
    tcg_gen_andi_i32(cpu_crf[crf], cpu_crf[crf], 1);
547 e1571908 aurel32
548 e1571908 aurel32
    l1 = gen_new_label();
549 e1571908 aurel32
    l2 = gen_new_label();
550 e1571908 aurel32
    l3 = gen_new_label();
551 e1571908 aurel32
    if (s) {
552 ea363694 aurel32
        tcg_gen_brcond_tl(TCG_COND_LT, arg0, arg1, l1);
553 ea363694 aurel32
        tcg_gen_brcond_tl(TCG_COND_GT, arg0, arg1, l2);
554 e1571908 aurel32
    } else {
555 ea363694 aurel32
        tcg_gen_brcond_tl(TCG_COND_LTU, arg0, arg1, l1);
556 ea363694 aurel32
        tcg_gen_brcond_tl(TCG_COND_GTU, arg0, arg1, l2);
557 e1571908 aurel32
    }
558 e1571908 aurel32
    tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_EQ);
559 e1571908 aurel32
    tcg_gen_br(l3);
560 e1571908 aurel32
    gen_set_label(l1);
561 e1571908 aurel32
    tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_LT);
562 e1571908 aurel32
    tcg_gen_br(l3);
563 e1571908 aurel32
    gen_set_label(l2);
564 e1571908 aurel32
    tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_GT);
565 e1571908 aurel32
    gen_set_label(l3);
566 e1571908 aurel32
}
567 e1571908 aurel32
568 ea363694 aurel32
static always_inline void gen_op_cmpi(TCGv arg0, target_ulong arg1, int s, int crf)
569 e1571908 aurel32
{
570 ea363694 aurel32
    TCGv t0 = tcg_const_local_tl(arg1);
571 ea363694 aurel32
    gen_op_cmp(arg0, t0, s, crf);
572 ea363694 aurel32
    tcg_temp_free(t0);
573 e1571908 aurel32
}
574 e1571908 aurel32
575 e1571908 aurel32
#if defined(TARGET_PPC64)
576 ea363694 aurel32
static always_inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int s, int crf)
577 e1571908 aurel32
{
578 ea363694 aurel32
    TCGv t0, t1;
579 a7812ae4 pbrook
    t0 = tcg_temp_local_new();
580 a7812ae4 pbrook
    t1 = tcg_temp_local_new();
581 e1571908 aurel32
    if (s) {
582 ea363694 aurel32
        tcg_gen_ext32s_tl(t0, arg0);
583 ea363694 aurel32
        tcg_gen_ext32s_tl(t1, arg1);
584 e1571908 aurel32
    } else {
585 ea363694 aurel32
        tcg_gen_ext32u_tl(t0, arg0);
586 ea363694 aurel32
        tcg_gen_ext32u_tl(t1, arg1);
587 e1571908 aurel32
    }
588 ea363694 aurel32
    gen_op_cmp(t0, t1, s, crf);
589 ea363694 aurel32
    tcg_temp_free(t1);
590 ea363694 aurel32
    tcg_temp_free(t0);
591 e1571908 aurel32
}
592 e1571908 aurel32
593 ea363694 aurel32
static always_inline void gen_op_cmpi32(TCGv arg0, target_ulong arg1, int s, int crf)
594 e1571908 aurel32
{
595 ea363694 aurel32
    TCGv t0 = tcg_const_local_tl(arg1);
596 ea363694 aurel32
    gen_op_cmp32(arg0, t0, s, crf);
597 ea363694 aurel32
    tcg_temp_free(t0);
598 e1571908 aurel32
}
599 e1571908 aurel32
#endif
600 e1571908 aurel32
601 e1571908 aurel32
static always_inline void gen_set_Rc0 (DisasContext *ctx, TCGv reg)
602 e1571908 aurel32
{
603 e1571908 aurel32
#if defined(TARGET_PPC64)
604 e1571908 aurel32
    if (!(ctx->sf_mode))
605 e1571908 aurel32
        gen_op_cmpi32(reg, 0, 1, 0);
606 e1571908 aurel32
    else
607 e1571908 aurel32
#endif
608 e1571908 aurel32
        gen_op_cmpi(reg, 0, 1, 0);
609 e1571908 aurel32
}
610 e1571908 aurel32
611 e1571908 aurel32
/* cmp */
612 99e300ef Blue Swirl
static void gen_cmp(DisasContext *ctx)
613 e1571908 aurel32
{
614 e1571908 aurel32
#if defined(TARGET_PPC64)
615 e1571908 aurel32
    if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
616 e1571908 aurel32
        gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
617 e1571908 aurel32
                     1, crfD(ctx->opcode));
618 e1571908 aurel32
    else
619 e1571908 aurel32
#endif
620 e1571908 aurel32
        gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
621 e1571908 aurel32
                   1, crfD(ctx->opcode));
622 e1571908 aurel32
}
623 e1571908 aurel32
624 e1571908 aurel32
/* cmpi */
625 99e300ef Blue Swirl
static void gen_cmpi(DisasContext *ctx)
626 e1571908 aurel32
{
627 e1571908 aurel32
#if defined(TARGET_PPC64)
628 e1571908 aurel32
    if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
629 e1571908 aurel32
        gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
630 e1571908 aurel32
                      1, crfD(ctx->opcode));
631 e1571908 aurel32
    else
632 e1571908 aurel32
#endif
633 e1571908 aurel32
        gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
634 e1571908 aurel32
                    1, crfD(ctx->opcode));
635 e1571908 aurel32
}
636 e1571908 aurel32
637 e1571908 aurel32
/* cmpl */
638 99e300ef Blue Swirl
static void gen_cmpl(DisasContext *ctx)
639 e1571908 aurel32
{
640 e1571908 aurel32
#if defined(TARGET_PPC64)
641 e1571908 aurel32
    if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
642 e1571908 aurel32
        gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
643 e1571908 aurel32
                     0, crfD(ctx->opcode));
644 e1571908 aurel32
    else
645 e1571908 aurel32
#endif
646 e1571908 aurel32
        gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
647 e1571908 aurel32
                   0, crfD(ctx->opcode));
648 e1571908 aurel32
}
649 e1571908 aurel32
650 e1571908 aurel32
/* cmpli */
651 99e300ef Blue Swirl
static void gen_cmpli(DisasContext *ctx)
652 e1571908 aurel32
{
653 e1571908 aurel32
#if defined(TARGET_PPC64)
654 e1571908 aurel32
    if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
655 e1571908 aurel32
        gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
656 e1571908 aurel32
                      0, crfD(ctx->opcode));
657 e1571908 aurel32
    else
658 e1571908 aurel32
#endif
659 e1571908 aurel32
        gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
660 e1571908 aurel32
                    0, crfD(ctx->opcode));
661 e1571908 aurel32
}
662 e1571908 aurel32
663 e1571908 aurel32
/* isel (PowerPC 2.03 specification) */
664 99e300ef Blue Swirl
static void gen_isel(DisasContext *ctx)
665 e1571908 aurel32
{
666 e1571908 aurel32
    int l1, l2;
667 e1571908 aurel32
    uint32_t bi = rC(ctx->opcode);
668 e1571908 aurel32
    uint32_t mask;
669 a7812ae4 pbrook
    TCGv_i32 t0;
670 e1571908 aurel32
671 e1571908 aurel32
    l1 = gen_new_label();
672 e1571908 aurel32
    l2 = gen_new_label();
673 e1571908 aurel32
674 e1571908 aurel32
    mask = 1 << (3 - (bi & 0x03));
675 a7812ae4 pbrook
    t0 = tcg_temp_new_i32();
676 fea0c503 aurel32
    tcg_gen_andi_i32(t0, cpu_crf[bi >> 2], mask);
677 fea0c503 aurel32
    tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
678 e1571908 aurel32
    if (rA(ctx->opcode) == 0)
679 e1571908 aurel32
        tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
680 e1571908 aurel32
    else
681 e1571908 aurel32
        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
682 e1571908 aurel32
    tcg_gen_br(l2);
683 e1571908 aurel32
    gen_set_label(l1);
684 e1571908 aurel32
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
685 e1571908 aurel32
    gen_set_label(l2);
686 a7812ae4 pbrook
    tcg_temp_free_i32(t0);
687 e1571908 aurel32
}
688 e1571908 aurel32
689 79aceca5 bellard
/***                           Integer arithmetic                          ***/
690 79aceca5 bellard
691 74637406 aurel32
static always_inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0, TCGv arg1, TCGv arg2, int sub)
692 74637406 aurel32
{
693 74637406 aurel32
    int l1;
694 74637406 aurel32
    TCGv t0;
695 79aceca5 bellard
696 74637406 aurel32
    l1 = gen_new_label();
697 74637406 aurel32
    /* Start with XER OV disabled, the most likely case */
698 74637406 aurel32
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
699 a7812ae4 pbrook
    t0 = tcg_temp_local_new();
700 74637406 aurel32
    tcg_gen_xor_tl(t0, arg0, arg1);
701 74637406 aurel32
#if defined(TARGET_PPC64)
702 74637406 aurel32
    if (!ctx->sf_mode)
703 74637406 aurel32
        tcg_gen_ext32s_tl(t0, t0);
704 74637406 aurel32
#endif
705 74637406 aurel32
    if (sub)
706 74637406 aurel32
        tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l1);
707 74637406 aurel32
    else
708 74637406 aurel32
        tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
709 74637406 aurel32
    tcg_gen_xor_tl(t0, arg1, arg2);
710 74637406 aurel32
#if defined(TARGET_PPC64)
711 74637406 aurel32
    if (!ctx->sf_mode)
712 74637406 aurel32
        tcg_gen_ext32s_tl(t0, t0);
713 74637406 aurel32
#endif
714 74637406 aurel32
    if (sub)
715 74637406 aurel32
        tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
716 74637406 aurel32
    else
717 74637406 aurel32
        tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l1);
718 74637406 aurel32
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
719 74637406 aurel32
    gen_set_label(l1);
720 74637406 aurel32
    tcg_temp_free(t0);
721 79aceca5 bellard
}
722 79aceca5 bellard
723 74637406 aurel32
static always_inline void gen_op_arith_compute_ca(DisasContext *ctx, TCGv arg1, TCGv arg2, int sub)
724 74637406 aurel32
{
725 74637406 aurel32
    int l1 = gen_new_label();
726 d9bce9d9 j_mayer
727 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
728 74637406 aurel32
    if (!(ctx->sf_mode)) {
729 74637406 aurel32
        TCGv t0, t1;
730 a7812ae4 pbrook
        t0 = tcg_temp_new();
731 a7812ae4 pbrook
        t1 = tcg_temp_new();
732 d9bce9d9 j_mayer
733 74637406 aurel32
        tcg_gen_ext32u_tl(t0, arg1);
734 74637406 aurel32
        tcg_gen_ext32u_tl(t1, arg2);
735 74637406 aurel32
        if (sub) {
736 74637406 aurel32
            tcg_gen_brcond_tl(TCG_COND_GTU, t0, t1, l1);
737 bdc4e053 aurel32
        } else {
738 74637406 aurel32
            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
739 74637406 aurel32
        }
740 a9730017 aurel32
        tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
741 a9730017 aurel32
        gen_set_label(l1);
742 a9730017 aurel32
        tcg_temp_free(t0);
743 a9730017 aurel32
        tcg_temp_free(t1);
744 74637406 aurel32
    } else
745 74637406 aurel32
#endif
746 a9730017 aurel32
    {
747 a9730017 aurel32
        if (sub) {
748 a9730017 aurel32
            tcg_gen_brcond_tl(TCG_COND_GTU, arg1, arg2, l1);
749 a9730017 aurel32
        } else {
750 a9730017 aurel32
            tcg_gen_brcond_tl(TCG_COND_GEU, arg1, arg2, l1);
751 a9730017 aurel32
        }
752 a9730017 aurel32
        tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
753 a9730017 aurel32
        gen_set_label(l1);
754 74637406 aurel32
    }
755 d9bce9d9 j_mayer
}
756 d9bce9d9 j_mayer
757 74637406 aurel32
/* Common add function */
758 74637406 aurel32
static always_inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2,
759 74637406 aurel32
                                           int add_ca, int compute_ca, int compute_ov)
760 74637406 aurel32
{
761 74637406 aurel32
    TCGv t0, t1;
762 d9bce9d9 j_mayer
763 74637406 aurel32
    if ((!compute_ca && !compute_ov) ||
764 a7812ae4 pbrook
        (!TCGV_EQUAL(ret,arg1) && !TCGV_EQUAL(ret, arg2)))  {
765 74637406 aurel32
        t0 = ret;
766 74637406 aurel32
    } else {
767 a7812ae4 pbrook
        t0 = tcg_temp_local_new();
768 74637406 aurel32
    }
769 79aceca5 bellard
770 74637406 aurel32
    if (add_ca) {
771 a7812ae4 pbrook
        t1 = tcg_temp_local_new();
772 74637406 aurel32
        tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
773 74637406 aurel32
        tcg_gen_shri_tl(t1, t1, XER_CA);
774 d2e9fd8f malc
    } else {
775 d2e9fd8f malc
        TCGV_UNUSED(t1);
776 74637406 aurel32
    }
777 79aceca5 bellard
778 74637406 aurel32
    if (compute_ca && compute_ov) {
779 74637406 aurel32
        /* Start with XER CA and OV disabled, the most likely case */
780 74637406 aurel32
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~((1 << XER_CA) | (1 << XER_OV)));
781 74637406 aurel32
    } else if (compute_ca) {
782 74637406 aurel32
        /* Start with XER CA disabled, the most likely case */
783 74637406 aurel32
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
784 74637406 aurel32
    } else if (compute_ov) {
785 74637406 aurel32
        /* Start with XER OV disabled, the most likely case */
786 74637406 aurel32
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
787 74637406 aurel32
    }
788 79aceca5 bellard
789 74637406 aurel32
    tcg_gen_add_tl(t0, arg1, arg2);
790 74637406 aurel32
791 74637406 aurel32
    if (compute_ca) {
792 74637406 aurel32
        gen_op_arith_compute_ca(ctx, t0, arg1, 0);
793 74637406 aurel32
    }
794 74637406 aurel32
    if (add_ca) {
795 74637406 aurel32
        tcg_gen_add_tl(t0, t0, t1);
796 74637406 aurel32
        gen_op_arith_compute_ca(ctx, t0, t1, 0);
797 74637406 aurel32
        tcg_temp_free(t1);
798 74637406 aurel32
    }
799 74637406 aurel32
    if (compute_ov) {
800 74637406 aurel32
        gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 0);
801 74637406 aurel32
    }
802 74637406 aurel32
803 74637406 aurel32
    if (unlikely(Rc(ctx->opcode) != 0))
804 74637406 aurel32
        gen_set_Rc0(ctx, t0);
805 74637406 aurel32
806 a7812ae4 pbrook
    if (!TCGV_EQUAL(t0, ret)) {
807 74637406 aurel32
        tcg_gen_mov_tl(ret, t0);
808 74637406 aurel32
        tcg_temp_free(t0);
809 74637406 aurel32
    }
810 39dd32ee aurel32
}
811 74637406 aurel32
/* Add functions with two operands */
812 74637406 aurel32
#define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
813 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                       \
814 74637406 aurel32
{                                                                             \
815 74637406 aurel32
    gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                           \
816 74637406 aurel32
                     cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],      \
817 74637406 aurel32
                     add_ca, compute_ca, compute_ov);                         \
818 74637406 aurel32
}
819 74637406 aurel32
/* Add functions with one operand and one immediate */
820 74637406 aurel32
#define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
821 74637406 aurel32
                                add_ca, compute_ca, compute_ov)               \
822 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                       \
823 74637406 aurel32
{                                                                             \
824 74637406 aurel32
    TCGv t0 = tcg_const_local_tl(const_val);                                  \
825 74637406 aurel32
    gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                           \
826 74637406 aurel32
                     cpu_gpr[rA(ctx->opcode)], t0,                            \
827 74637406 aurel32
                     add_ca, compute_ca, compute_ov);                         \
828 74637406 aurel32
    tcg_temp_free(t0);                                                        \
829 74637406 aurel32
}
830 74637406 aurel32
831 74637406 aurel32
/* add  add.  addo  addo. */
832 74637406 aurel32
GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
833 74637406 aurel32
GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
834 74637406 aurel32
/* addc  addc.  addco  addco. */
835 74637406 aurel32
GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
836 74637406 aurel32
GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
837 74637406 aurel32
/* adde  adde.  addeo  addeo. */
838 74637406 aurel32
GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
839 74637406 aurel32
GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
840 74637406 aurel32
/* addme  addme.  addmeo  addmeo.  */
841 74637406 aurel32
GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
842 74637406 aurel32
GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
843 74637406 aurel32
/* addze  addze.  addzeo  addzeo.*/
844 74637406 aurel32
GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
845 74637406 aurel32
GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
846 74637406 aurel32
/* addi */
847 99e300ef Blue Swirl
static void gen_addi(DisasContext *ctx)
848 d9bce9d9 j_mayer
{
849 74637406 aurel32
    target_long simm = SIMM(ctx->opcode);
850 74637406 aurel32
851 74637406 aurel32
    if (rA(ctx->opcode) == 0) {
852 74637406 aurel32
        /* li case */
853 74637406 aurel32
        tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm);
854 74637406 aurel32
    } else {
855 74637406 aurel32
        tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], simm);
856 74637406 aurel32
    }
857 d9bce9d9 j_mayer
}
858 74637406 aurel32
/* addic  addic.*/
859 74637406 aurel32
static always_inline void gen_op_addic (DisasContext *ctx, TCGv ret, TCGv arg1,
860 74637406 aurel32
                                        int compute_Rc0)
861 d9bce9d9 j_mayer
{
862 74637406 aurel32
    target_long simm = SIMM(ctx->opcode);
863 74637406 aurel32
864 74637406 aurel32
    /* Start with XER CA and OV disabled, the most likely case */
865 74637406 aurel32
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
866 74637406 aurel32
867 74637406 aurel32
    if (likely(simm != 0)) {
868 a7812ae4 pbrook
        TCGv t0 = tcg_temp_local_new();
869 74637406 aurel32
        tcg_gen_addi_tl(t0, arg1, simm);
870 74637406 aurel32
        gen_op_arith_compute_ca(ctx, t0, arg1, 0);
871 74637406 aurel32
        tcg_gen_mov_tl(ret, t0);
872 74637406 aurel32
        tcg_temp_free(t0);
873 74637406 aurel32
    } else {
874 74637406 aurel32
        tcg_gen_mov_tl(ret, arg1);
875 74637406 aurel32
    }
876 74637406 aurel32
    if (compute_Rc0) {
877 74637406 aurel32
        gen_set_Rc0(ctx, ret);
878 74637406 aurel32
    }
879 d9bce9d9 j_mayer
}
880 99e300ef Blue Swirl
881 99e300ef Blue Swirl
static void gen_addic(DisasContext *ctx)
882 d9bce9d9 j_mayer
{
883 74637406 aurel32
    gen_op_addic(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0);
884 d9bce9d9 j_mayer
}
885 e8eaa2c0 Blue Swirl
886 e8eaa2c0 Blue Swirl
static void gen_addic_(DisasContext *ctx)
887 d9bce9d9 j_mayer
{
888 74637406 aurel32
    gen_op_addic(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1);
889 d9bce9d9 j_mayer
}
890 99e300ef Blue Swirl
891 54623277 Blue Swirl
/* addis */
892 99e300ef Blue Swirl
static void gen_addis(DisasContext *ctx)
893 d9bce9d9 j_mayer
{
894 74637406 aurel32
    target_long simm = SIMM(ctx->opcode);
895 74637406 aurel32
896 74637406 aurel32
    if (rA(ctx->opcode) == 0) {
897 74637406 aurel32
        /* lis case */
898 74637406 aurel32
        tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm << 16);
899 74637406 aurel32
    } else {
900 74637406 aurel32
        tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], simm << 16);
901 74637406 aurel32
    }
902 d9bce9d9 j_mayer
}
903 74637406 aurel32
904 74637406 aurel32
static always_inline void gen_op_arith_divw (DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2,
905 74637406 aurel32
                                             int sign, int compute_ov)
906 d9bce9d9 j_mayer
{
907 2ef1b120 aurel32
    int l1 = gen_new_label();
908 2ef1b120 aurel32
    int l2 = gen_new_label();
909 a7812ae4 pbrook
    TCGv_i32 t0 = tcg_temp_local_new_i32();
910 a7812ae4 pbrook
    TCGv_i32 t1 = tcg_temp_local_new_i32();
911 74637406 aurel32
912 2ef1b120 aurel32
    tcg_gen_trunc_tl_i32(t0, arg1);
913 2ef1b120 aurel32
    tcg_gen_trunc_tl_i32(t1, arg2);
914 2ef1b120 aurel32
    tcg_gen_brcondi_i32(TCG_COND_EQ, t1, 0, l1);
915 74637406 aurel32
    if (sign) {
916 2ef1b120 aurel32
        int l3 = gen_new_label();
917 2ef1b120 aurel32
        tcg_gen_brcondi_i32(TCG_COND_NE, t1, -1, l3);
918 2ef1b120 aurel32
        tcg_gen_brcondi_i32(TCG_COND_EQ, t0, INT32_MIN, l1);
919 74637406 aurel32
        gen_set_label(l3);
920 2ef1b120 aurel32
        tcg_gen_div_i32(t0, t0, t1);
921 74637406 aurel32
    } else {
922 2ef1b120 aurel32
        tcg_gen_divu_i32(t0, t0, t1);
923 74637406 aurel32
    }
924 74637406 aurel32
    if (compute_ov) {
925 74637406 aurel32
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
926 74637406 aurel32
    }
927 74637406 aurel32
    tcg_gen_br(l2);
928 74637406 aurel32
    gen_set_label(l1);
929 74637406 aurel32
    if (sign) {
930 2ef1b120 aurel32
        tcg_gen_sari_i32(t0, t0, 31);
931 74637406 aurel32
    } else {
932 74637406 aurel32
        tcg_gen_movi_i32(t0, 0);
933 74637406 aurel32
    }
934 74637406 aurel32
    if (compute_ov) {
935 74637406 aurel32
        tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
936 74637406 aurel32
    }
937 74637406 aurel32
    gen_set_label(l2);
938 2ef1b120 aurel32
    tcg_gen_extu_i32_tl(ret, t0);
939 a7812ae4 pbrook
    tcg_temp_free_i32(t0);
940 a7812ae4 pbrook
    tcg_temp_free_i32(t1);
941 74637406 aurel32
    if (unlikely(Rc(ctx->opcode) != 0))
942 74637406 aurel32
        gen_set_Rc0(ctx, ret);
943 d9bce9d9 j_mayer
}
944 74637406 aurel32
/* Div functions */
945 74637406 aurel32
#define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
946 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                       \
947 74637406 aurel32
{                                                                             \
948 74637406 aurel32
    gen_op_arith_divw(ctx, cpu_gpr[rD(ctx->opcode)],                          \
949 74637406 aurel32
                     cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],      \
950 74637406 aurel32
                     sign, compute_ov);                                       \
951 74637406 aurel32
}
952 74637406 aurel32
/* divwu  divwu.  divwuo  divwuo.   */
953 74637406 aurel32
GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0);
954 74637406 aurel32
GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1);
955 74637406 aurel32
/* divw  divw.  divwo  divwo.   */
956 74637406 aurel32
GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0);
957 74637406 aurel32
GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1);
958 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
959 2ef1b120 aurel32
static always_inline void gen_op_arith_divd (DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2,
960 2ef1b120 aurel32
                                             int sign, int compute_ov)
961 d9bce9d9 j_mayer
{
962 2ef1b120 aurel32
    int l1 = gen_new_label();
963 2ef1b120 aurel32
    int l2 = gen_new_label();
964 74637406 aurel32
965 74637406 aurel32
    tcg_gen_brcondi_i64(TCG_COND_EQ, arg2, 0, l1);
966 74637406 aurel32
    if (sign) {
967 2ef1b120 aurel32
        int l3 = gen_new_label();
968 74637406 aurel32
        tcg_gen_brcondi_i64(TCG_COND_NE, arg2, -1, l3);
969 74637406 aurel32
        tcg_gen_brcondi_i64(TCG_COND_EQ, arg1, INT64_MIN, l1);
970 74637406 aurel32
        gen_set_label(l3);
971 74637406 aurel32
        tcg_gen_div_i64(ret, arg1, arg2);
972 74637406 aurel32
    } else {
973 74637406 aurel32
        tcg_gen_divu_i64(ret, arg1, arg2);
974 74637406 aurel32
    }
975 74637406 aurel32
    if (compute_ov) {
976 74637406 aurel32
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
977 74637406 aurel32
    }
978 74637406 aurel32
    tcg_gen_br(l2);
979 74637406 aurel32
    gen_set_label(l1);
980 74637406 aurel32
    if (sign) {
981 74637406 aurel32
        tcg_gen_sari_i64(ret, arg1, 63);
982 74637406 aurel32
    } else {
983 74637406 aurel32
        tcg_gen_movi_i64(ret, 0);
984 74637406 aurel32
    }
985 74637406 aurel32
    if (compute_ov) {
986 74637406 aurel32
        tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
987 74637406 aurel32
    }
988 74637406 aurel32
    gen_set_label(l2);
989 74637406 aurel32
    if (unlikely(Rc(ctx->opcode) != 0))
990 74637406 aurel32
        gen_set_Rc0(ctx, ret);
991 d9bce9d9 j_mayer
}
992 74637406 aurel32
#define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
993 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                       \
994 74637406 aurel32
{                                                                             \
995 2ef1b120 aurel32
    gen_op_arith_divd(ctx, cpu_gpr[rD(ctx->opcode)],                          \
996 2ef1b120 aurel32
                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     \
997 2ef1b120 aurel32
                      sign, compute_ov);                                      \
998 74637406 aurel32
}
999 74637406 aurel32
/* divwu  divwu.  divwuo  divwuo.   */
1000 74637406 aurel32
GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0);
1001 74637406 aurel32
GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1);
1002 74637406 aurel32
/* divw  divw.  divwo  divwo.   */
1003 74637406 aurel32
GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0);
1004 74637406 aurel32
GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1);
1005 d9bce9d9 j_mayer
#endif
1006 74637406 aurel32
1007 74637406 aurel32
/* mulhw  mulhw. */
1008 99e300ef Blue Swirl
static void gen_mulhw(DisasContext *ctx)
1009 d9bce9d9 j_mayer
{
1010 a7812ae4 pbrook
    TCGv_i64 t0, t1;
1011 74637406 aurel32
1012 a7812ae4 pbrook
    t0 = tcg_temp_new_i64();
1013 a7812ae4 pbrook
    t1 = tcg_temp_new_i64();
1014 74637406 aurel32
#if defined(TARGET_PPC64)
1015 74637406 aurel32
    tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
1016 74637406 aurel32
    tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
1017 74637406 aurel32
    tcg_gen_mul_i64(t0, t0, t1);
1018 74637406 aurel32
    tcg_gen_shri_i64(cpu_gpr[rD(ctx->opcode)], t0, 32);
1019 74637406 aurel32
#else
1020 74637406 aurel32
    tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
1021 74637406 aurel32
    tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
1022 74637406 aurel32
    tcg_gen_mul_i64(t0, t0, t1);
1023 74637406 aurel32
    tcg_gen_shri_i64(t0, t0, 32);
1024 74637406 aurel32
    tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
1025 74637406 aurel32
#endif
1026 a7812ae4 pbrook
    tcg_temp_free_i64(t0);
1027 a7812ae4 pbrook
    tcg_temp_free_i64(t1);
1028 74637406 aurel32
    if (unlikely(Rc(ctx->opcode) != 0))
1029 74637406 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1030 d9bce9d9 j_mayer
}
1031 99e300ef Blue Swirl
1032 54623277 Blue Swirl
/* mulhwu  mulhwu.  */
1033 99e300ef Blue Swirl
static void gen_mulhwu(DisasContext *ctx)
1034 d9bce9d9 j_mayer
{
1035 a7812ae4 pbrook
    TCGv_i64 t0, t1;
1036 74637406 aurel32
1037 a7812ae4 pbrook
    t0 = tcg_temp_new_i64();
1038 a7812ae4 pbrook
    t1 = tcg_temp_new_i64();
1039 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
1040 74637406 aurel32
    tcg_gen_ext32u_i64(t0, cpu_gpr[rA(ctx->opcode)]);
1041 74637406 aurel32
    tcg_gen_ext32u_i64(t1, cpu_gpr[rB(ctx->opcode)]);
1042 74637406 aurel32
    tcg_gen_mul_i64(t0, t0, t1);
1043 74637406 aurel32
    tcg_gen_shri_i64(cpu_gpr[rD(ctx->opcode)], t0, 32);
1044 74637406 aurel32
#else
1045 74637406 aurel32
    tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
1046 74637406 aurel32
    tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
1047 74637406 aurel32
    tcg_gen_mul_i64(t0, t0, t1);
1048 74637406 aurel32
    tcg_gen_shri_i64(t0, t0, 32);
1049 74637406 aurel32
    tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
1050 74637406 aurel32
#endif
1051 a7812ae4 pbrook
    tcg_temp_free_i64(t0);
1052 a7812ae4 pbrook
    tcg_temp_free_i64(t1);
1053 74637406 aurel32
    if (unlikely(Rc(ctx->opcode) != 0))
1054 74637406 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1055 d9bce9d9 j_mayer
}
1056 99e300ef Blue Swirl
1057 54623277 Blue Swirl
/* mullw  mullw. */
1058 99e300ef Blue Swirl
static void gen_mullw(DisasContext *ctx)
1059 d9bce9d9 j_mayer
{
1060 74637406 aurel32
    tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1061 74637406 aurel32
                   cpu_gpr[rB(ctx->opcode)]);
1062 1e4c090f aurel32
    tcg_gen_ext32s_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)]);
1063 74637406 aurel32
    if (unlikely(Rc(ctx->opcode) != 0))
1064 74637406 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1065 d9bce9d9 j_mayer
}
1066 99e300ef Blue Swirl
1067 54623277 Blue Swirl
/* mullwo  mullwo. */
1068 99e300ef Blue Swirl
static void gen_mullwo(DisasContext *ctx)
1069 d9bce9d9 j_mayer
{
1070 74637406 aurel32
    int l1;
1071 a7812ae4 pbrook
    TCGv_i64 t0, t1;
1072 74637406 aurel32
1073 a7812ae4 pbrook
    t0 = tcg_temp_new_i64();
1074 a7812ae4 pbrook
    t1 = tcg_temp_new_i64();
1075 74637406 aurel32
    l1 = gen_new_label();
1076 74637406 aurel32
    /* Start with XER OV disabled, the most likely case */
1077 74637406 aurel32
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
1078 74637406 aurel32
#if defined(TARGET_PPC64)
1079 74637406 aurel32
    tcg_gen_ext32s_i64(t0, cpu_gpr[rA(ctx->opcode)]);
1080 74637406 aurel32
    tcg_gen_ext32s_i64(t1, cpu_gpr[rB(ctx->opcode)]);
1081 74637406 aurel32
#else
1082 74637406 aurel32
    tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
1083 74637406 aurel32
    tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
1084 d9bce9d9 j_mayer
#endif
1085 74637406 aurel32
    tcg_gen_mul_i64(t0, t0, t1);
1086 74637406 aurel32
#if defined(TARGET_PPC64)
1087 74637406 aurel32
    tcg_gen_ext32s_i64(cpu_gpr[rD(ctx->opcode)], t0);
1088 74637406 aurel32
    tcg_gen_brcond_i64(TCG_COND_EQ, t0, cpu_gpr[rD(ctx->opcode)], l1);
1089 74637406 aurel32
#else
1090 74637406 aurel32
    tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
1091 74637406 aurel32
    tcg_gen_ext32s_i64(t1, t0);
1092 74637406 aurel32
    tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
1093 74637406 aurel32
#endif
1094 74637406 aurel32
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
1095 74637406 aurel32
    gen_set_label(l1);
1096 a7812ae4 pbrook
    tcg_temp_free_i64(t0);
1097 a7812ae4 pbrook
    tcg_temp_free_i64(t1);
1098 74637406 aurel32
    if (unlikely(Rc(ctx->opcode) != 0))
1099 74637406 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1100 d9bce9d9 j_mayer
}
1101 99e300ef Blue Swirl
1102 54623277 Blue Swirl
/* mulli */
1103 99e300ef Blue Swirl
static void gen_mulli(DisasContext *ctx)
1104 d9bce9d9 j_mayer
{
1105 74637406 aurel32
    tcg_gen_muli_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1106 74637406 aurel32
                    SIMM(ctx->opcode));
1107 d9bce9d9 j_mayer
}
1108 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
1109 74637406 aurel32
#define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
1110 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                       \
1111 74637406 aurel32
{                                                                             \
1112 a7812ae4 pbrook
    gen_helper_##name (cpu_gpr[rD(ctx->opcode)],                              \
1113 74637406 aurel32
                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);   \
1114 74637406 aurel32
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1115 74637406 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);                           \
1116 d9bce9d9 j_mayer
}
1117 74637406 aurel32
/* mulhd  mulhd. */
1118 74637406 aurel32
GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00);
1119 74637406 aurel32
/* mulhdu  mulhdu. */
1120 74637406 aurel32
GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02);
1121 99e300ef Blue Swirl
1122 54623277 Blue Swirl
/* mulld  mulld. */
1123 99e300ef Blue Swirl
static void gen_mulld(DisasContext *ctx)
1124 d9bce9d9 j_mayer
{
1125 74637406 aurel32
    tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1126 74637406 aurel32
                   cpu_gpr[rB(ctx->opcode)]);
1127 74637406 aurel32
    if (unlikely(Rc(ctx->opcode) != 0))
1128 74637406 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1129 d9bce9d9 j_mayer
}
1130 74637406 aurel32
/* mulldo  mulldo. */
1131 74637406 aurel32
GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17);
1132 d9bce9d9 j_mayer
#endif
1133 74637406 aurel32
1134 74637406 aurel32
/* neg neg. nego nego. */
1135 ec6469a3 aurel32
static always_inline void gen_op_arith_neg (DisasContext *ctx, TCGv ret, TCGv arg1, int ov_check)
1136 d9bce9d9 j_mayer
{
1137 ec6469a3 aurel32
    int l1 = gen_new_label();
1138 ec6469a3 aurel32
    int l2 = gen_new_label();
1139 a7812ae4 pbrook
    TCGv t0 = tcg_temp_local_new();
1140 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
1141 74637406 aurel32
    if (ctx->sf_mode) {
1142 741a7444 aurel32
        tcg_gen_mov_tl(t0, arg1);
1143 ec6469a3 aurel32
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, INT64_MIN, l1);
1144 ec6469a3 aurel32
    } else
1145 ec6469a3 aurel32
#endif
1146 ec6469a3 aurel32
    {
1147 ec6469a3 aurel32
        tcg_gen_ext32s_tl(t0, arg1);
1148 74637406 aurel32
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, INT32_MIN, l1);
1149 74637406 aurel32
    }
1150 74637406 aurel32
    tcg_gen_neg_tl(ret, arg1);
1151 74637406 aurel32
    if (ov_check) {
1152 74637406 aurel32
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
1153 74637406 aurel32
    }
1154 74637406 aurel32
    tcg_gen_br(l2);
1155 74637406 aurel32
    gen_set_label(l1);
1156 ec6469a3 aurel32
    tcg_gen_mov_tl(ret, t0);
1157 74637406 aurel32
    if (ov_check) {
1158 74637406 aurel32
        tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
1159 74637406 aurel32
    }
1160 74637406 aurel32
    gen_set_label(l2);
1161 ec6469a3 aurel32
    tcg_temp_free(t0);
1162 74637406 aurel32
    if (unlikely(Rc(ctx->opcode) != 0))
1163 74637406 aurel32
        gen_set_Rc0(ctx, ret);
1164 74637406 aurel32
}
1165 99e300ef Blue Swirl
1166 99e300ef Blue Swirl
static void gen_neg(DisasContext *ctx)
1167 d9bce9d9 j_mayer
{
1168 ec6469a3 aurel32
    gen_op_arith_neg(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0);
1169 d9bce9d9 j_mayer
}
1170 99e300ef Blue Swirl
1171 99e300ef Blue Swirl
static void gen_nego(DisasContext *ctx)
1172 79aceca5 bellard
{
1173 ec6469a3 aurel32
    gen_op_arith_neg(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1);
1174 79aceca5 bellard
}
1175 74637406 aurel32
1176 74637406 aurel32
/* Common subf function */
1177 74637406 aurel32
static always_inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2,
1178 74637406 aurel32
                                            int add_ca, int compute_ca, int compute_ov)
1179 79aceca5 bellard
{
1180 74637406 aurel32
    TCGv t0, t1;
1181 76a66253 j_mayer
1182 74637406 aurel32
    if ((!compute_ca && !compute_ov) ||
1183 a7812ae4 pbrook
        (!TCGV_EQUAL(ret, arg1) && !TCGV_EQUAL(ret, arg2)))  {
1184 74637406 aurel32
        t0 = ret;
1185 e864cabd j_mayer
    } else {
1186 a7812ae4 pbrook
        t0 = tcg_temp_local_new();
1187 d9bce9d9 j_mayer
    }
1188 76a66253 j_mayer
1189 74637406 aurel32
    if (add_ca) {
1190 a7812ae4 pbrook
        t1 = tcg_temp_local_new();
1191 74637406 aurel32
        tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
1192 74637406 aurel32
        tcg_gen_shri_tl(t1, t1, XER_CA);
1193 d2e9fd8f malc
    } else {
1194 d2e9fd8f malc
        TCGV_UNUSED(t1);
1195 d9bce9d9 j_mayer
    }
1196 79aceca5 bellard
1197 74637406 aurel32
    if (compute_ca && compute_ov) {
1198 74637406 aurel32
        /* Start with XER CA and OV disabled, the most likely case */
1199 74637406 aurel32
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~((1 << XER_CA) | (1 << XER_OV)));
1200 74637406 aurel32
    } else if (compute_ca) {
1201 74637406 aurel32
        /* Start with XER CA disabled, the most likely case */
1202 74637406 aurel32
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1203 74637406 aurel32
    } else if (compute_ov) {
1204 74637406 aurel32
        /* Start with XER OV disabled, the most likely case */
1205 74637406 aurel32
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
1206 74637406 aurel32
    }
1207 74637406 aurel32
1208 74637406 aurel32
    if (add_ca) {
1209 74637406 aurel32
        tcg_gen_not_tl(t0, arg1);
1210 74637406 aurel32
        tcg_gen_add_tl(t0, t0, arg2);
1211 74637406 aurel32
        gen_op_arith_compute_ca(ctx, t0, arg2, 0);
1212 74637406 aurel32
        tcg_gen_add_tl(t0, t0, t1);
1213 74637406 aurel32
        gen_op_arith_compute_ca(ctx, t0, t1, 0);
1214 74637406 aurel32
        tcg_temp_free(t1);
1215 79aceca5 bellard
    } else {
1216 74637406 aurel32
        tcg_gen_sub_tl(t0, arg2, arg1);
1217 74637406 aurel32
        if (compute_ca) {
1218 74637406 aurel32
            gen_op_arith_compute_ca(ctx, t0, arg2, 1);
1219 74637406 aurel32
        }
1220 74637406 aurel32
    }
1221 74637406 aurel32
    if (compute_ov) {
1222 74637406 aurel32
        gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 1);
1223 74637406 aurel32
    }
1224 74637406 aurel32
1225 74637406 aurel32
    if (unlikely(Rc(ctx->opcode) != 0))
1226 74637406 aurel32
        gen_set_Rc0(ctx, t0);
1227 74637406 aurel32
1228 a7812ae4 pbrook
    if (!TCGV_EQUAL(t0, ret)) {
1229 74637406 aurel32
        tcg_gen_mov_tl(ret, t0);
1230 74637406 aurel32
        tcg_temp_free(t0);
1231 79aceca5 bellard
    }
1232 79aceca5 bellard
}
1233 74637406 aurel32
/* Sub functions with Two operands functions */
1234 74637406 aurel32
#define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
1235 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                       \
1236 74637406 aurel32
{                                                                             \
1237 74637406 aurel32
    gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1238 74637406 aurel32
                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     \
1239 74637406 aurel32
                      add_ca, compute_ca, compute_ov);                        \
1240 74637406 aurel32
}
1241 74637406 aurel32
/* Sub functions with one operand and one immediate */
1242 74637406 aurel32
#define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
1243 74637406 aurel32
                                add_ca, compute_ca, compute_ov)               \
1244 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                       \
1245 74637406 aurel32
{                                                                             \
1246 74637406 aurel32
    TCGv t0 = tcg_const_local_tl(const_val);                                  \
1247 74637406 aurel32
    gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1248 74637406 aurel32
                      cpu_gpr[rA(ctx->opcode)], t0,                           \
1249 74637406 aurel32
                      add_ca, compute_ca, compute_ov);                        \
1250 74637406 aurel32
    tcg_temp_free(t0);                                                        \
1251 74637406 aurel32
}
1252 74637406 aurel32
/* subf  subf.  subfo  subfo. */
1253 74637406 aurel32
GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
1254 74637406 aurel32
GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
1255 74637406 aurel32
/* subfc  subfc.  subfco  subfco. */
1256 74637406 aurel32
GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
1257 74637406 aurel32
GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
1258 74637406 aurel32
/* subfe  subfe.  subfeo  subfo. */
1259 74637406 aurel32
GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
1260 74637406 aurel32
GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
1261 74637406 aurel32
/* subfme  subfme.  subfmeo  subfmeo.  */
1262 74637406 aurel32
GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
1263 74637406 aurel32
GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
1264 74637406 aurel32
/* subfze  subfze.  subfzeo  subfzeo.*/
1265 74637406 aurel32
GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
1266 74637406 aurel32
GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
1267 99e300ef Blue Swirl
1268 54623277 Blue Swirl
/* subfic */
1269 99e300ef Blue Swirl
static void gen_subfic(DisasContext *ctx)
1270 79aceca5 bellard
{
1271 74637406 aurel32
    /* Start with XER CA and OV disabled, the most likely case */
1272 74637406 aurel32
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1273 a7812ae4 pbrook
    TCGv t0 = tcg_temp_local_new();
1274 74637406 aurel32
    TCGv t1 = tcg_const_local_tl(SIMM(ctx->opcode));
1275 74637406 aurel32
    tcg_gen_sub_tl(t0, t1, cpu_gpr[rA(ctx->opcode)]);
1276 74637406 aurel32
    gen_op_arith_compute_ca(ctx, t0, t1, 1);
1277 74637406 aurel32
    tcg_temp_free(t1);
1278 74637406 aurel32
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
1279 74637406 aurel32
    tcg_temp_free(t0);
1280 79aceca5 bellard
}
1281 79aceca5 bellard
1282 79aceca5 bellard
/***                            Integer logical                            ***/
1283 26d67362 aurel32
#define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
1284 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                       \
1285 79aceca5 bellard
{                                                                             \
1286 26d67362 aurel32
    tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],                \
1287 26d67362 aurel32
       cpu_gpr[rB(ctx->opcode)]);                                             \
1288 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1289 26d67362 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
1290 79aceca5 bellard
}
1291 79aceca5 bellard
1292 26d67362 aurel32
#define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
1293 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                       \
1294 79aceca5 bellard
{                                                                             \
1295 26d67362 aurel32
    tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);               \
1296 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1297 26d67362 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
1298 79aceca5 bellard
}
1299 79aceca5 bellard
1300 79aceca5 bellard
/* and & and. */
1301 26d67362 aurel32
GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER);
1302 79aceca5 bellard
/* andc & andc. */
1303 26d67362 aurel32
GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER);
1304 e8eaa2c0 Blue Swirl
1305 54623277 Blue Swirl
/* andi. */
1306 e8eaa2c0 Blue Swirl
static void gen_andi_(DisasContext *ctx)
1307 79aceca5 bellard
{
1308 26d67362 aurel32
    tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode));
1309 26d67362 aurel32
    gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1310 79aceca5 bellard
}
1311 e8eaa2c0 Blue Swirl
1312 54623277 Blue Swirl
/* andis. */
1313 e8eaa2c0 Blue Swirl
static void gen_andis_(DisasContext *ctx)
1314 79aceca5 bellard
{
1315 26d67362 aurel32
    tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode) << 16);
1316 26d67362 aurel32
    gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1317 79aceca5 bellard
}
1318 99e300ef Blue Swirl
1319 54623277 Blue Swirl
/* cntlzw */
1320 99e300ef Blue Swirl
static void gen_cntlzw(DisasContext *ctx)
1321 26d67362 aurel32
{
1322 a7812ae4 pbrook
    gen_helper_cntlzw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1323 26d67362 aurel32
    if (unlikely(Rc(ctx->opcode) != 0))
1324 2e31f5d3 pbrook
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1325 26d67362 aurel32
}
1326 79aceca5 bellard
/* eqv & eqv. */
1327 26d67362 aurel32
GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER);
1328 79aceca5 bellard
/* extsb & extsb. */
1329 26d67362 aurel32
GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER);
1330 79aceca5 bellard
/* extsh & extsh. */
1331 26d67362 aurel32
GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER);
1332 79aceca5 bellard
/* nand & nand. */
1333 26d67362 aurel32
GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER);
1334 79aceca5 bellard
/* nor & nor. */
1335 26d67362 aurel32
GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER);
1336 99e300ef Blue Swirl
1337 54623277 Blue Swirl
/* or & or. */
1338 99e300ef Blue Swirl
static void gen_or(DisasContext *ctx)
1339 9a64fbe4 bellard
{
1340 76a66253 j_mayer
    int rs, ra, rb;
1341 76a66253 j_mayer
1342 76a66253 j_mayer
    rs = rS(ctx->opcode);
1343 76a66253 j_mayer
    ra = rA(ctx->opcode);
1344 76a66253 j_mayer
    rb = rB(ctx->opcode);
1345 76a66253 j_mayer
    /* Optimisation for mr. ri case */
1346 76a66253 j_mayer
    if (rs != ra || rs != rb) {
1347 26d67362 aurel32
        if (rs != rb)
1348 26d67362 aurel32
            tcg_gen_or_tl(cpu_gpr[ra], cpu_gpr[rs], cpu_gpr[rb]);
1349 26d67362 aurel32
        else
1350 26d67362 aurel32
            tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rs]);
1351 76a66253 j_mayer
        if (unlikely(Rc(ctx->opcode) != 0))
1352 26d67362 aurel32
            gen_set_Rc0(ctx, cpu_gpr[ra]);
1353 76a66253 j_mayer
    } else if (unlikely(Rc(ctx->opcode) != 0)) {
1354 26d67362 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rs]);
1355 c80f84e3 j_mayer
#if defined(TARGET_PPC64)
1356 c80f84e3 j_mayer
    } else {
1357 26d67362 aurel32
        int prio = 0;
1358 26d67362 aurel32
1359 c80f84e3 j_mayer
        switch (rs) {
1360 c80f84e3 j_mayer
        case 1:
1361 c80f84e3 j_mayer
            /* Set process priority to low */
1362 26d67362 aurel32
            prio = 2;
1363 c80f84e3 j_mayer
            break;
1364 c80f84e3 j_mayer
        case 6:
1365 c80f84e3 j_mayer
            /* Set process priority to medium-low */
1366 26d67362 aurel32
            prio = 3;
1367 c80f84e3 j_mayer
            break;
1368 c80f84e3 j_mayer
        case 2:
1369 c80f84e3 j_mayer
            /* Set process priority to normal */
1370 26d67362 aurel32
            prio = 4;
1371 c80f84e3 j_mayer
            break;
1372 be147d08 j_mayer
#if !defined(CONFIG_USER_ONLY)
1373 be147d08 j_mayer
        case 31:
1374 76db3ba4 aurel32
            if (ctx->mem_idx > 0) {
1375 be147d08 j_mayer
                /* Set process priority to very low */
1376 26d67362 aurel32
                prio = 1;
1377 be147d08 j_mayer
            }
1378 be147d08 j_mayer
            break;
1379 be147d08 j_mayer
        case 5:
1380 76db3ba4 aurel32
            if (ctx->mem_idx > 0) {
1381 be147d08 j_mayer
                /* Set process priority to medium-hight */
1382 26d67362 aurel32
                prio = 5;
1383 be147d08 j_mayer
            }
1384 be147d08 j_mayer
            break;
1385 be147d08 j_mayer
        case 3:
1386 76db3ba4 aurel32
            if (ctx->mem_idx > 0) {
1387 be147d08 j_mayer
                /* Set process priority to high */
1388 26d67362 aurel32
                prio = 6;
1389 be147d08 j_mayer
            }
1390 be147d08 j_mayer
            break;
1391 be147d08 j_mayer
        case 7:
1392 76db3ba4 aurel32
            if (ctx->mem_idx > 1) {
1393 be147d08 j_mayer
                /* Set process priority to very high */
1394 26d67362 aurel32
                prio = 7;
1395 be147d08 j_mayer
            }
1396 be147d08 j_mayer
            break;
1397 be147d08 j_mayer
#endif
1398 c80f84e3 j_mayer
        default:
1399 c80f84e3 j_mayer
            /* nop */
1400 c80f84e3 j_mayer
            break;
1401 c80f84e3 j_mayer
        }
1402 26d67362 aurel32
        if (prio) {
1403 a7812ae4 pbrook
            TCGv t0 = tcg_temp_new();
1404 54cdcae6 aurel32
            gen_load_spr(t0, SPR_PPR);
1405 ea363694 aurel32
            tcg_gen_andi_tl(t0, t0, ~0x001C000000000000ULL);
1406 ea363694 aurel32
            tcg_gen_ori_tl(t0, t0, ((uint64_t)prio) << 50);
1407 54cdcae6 aurel32
            gen_store_spr(SPR_PPR, t0);
1408 ea363694 aurel32
            tcg_temp_free(t0);
1409 26d67362 aurel32
        }
1410 c80f84e3 j_mayer
#endif
1411 9a64fbe4 bellard
    }
1412 9a64fbe4 bellard
}
1413 79aceca5 bellard
/* orc & orc. */
1414 26d67362 aurel32
GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER);
1415 99e300ef Blue Swirl
1416 54623277 Blue Swirl
/* xor & xor. */
1417 99e300ef Blue Swirl
static void gen_xor(DisasContext *ctx)
1418 9a64fbe4 bellard
{
1419 9a64fbe4 bellard
    /* Optimisation for "set to zero" case */
1420 26d67362 aurel32
    if (rS(ctx->opcode) != rB(ctx->opcode))
1421 312179c4 aurel32
        tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1422 26d67362 aurel32
    else
1423 26d67362 aurel32
        tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
1424 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
1425 26d67362 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1426 9a64fbe4 bellard
}
1427 99e300ef Blue Swirl
1428 54623277 Blue Swirl
/* ori */
1429 99e300ef Blue Swirl
static void gen_ori(DisasContext *ctx)
1430 79aceca5 bellard
{
1431 76a66253 j_mayer
    target_ulong uimm = UIMM(ctx->opcode);
1432 79aceca5 bellard
1433 9a64fbe4 bellard
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1434 9a64fbe4 bellard
        /* NOP */
1435 76a66253 j_mayer
        /* XXX: should handle special NOPs for POWER series */
1436 9a64fbe4 bellard
        return;
1437 76a66253 j_mayer
    }
1438 26d67362 aurel32
    tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1439 79aceca5 bellard
}
1440 99e300ef Blue Swirl
1441 54623277 Blue Swirl
/* oris */
1442 99e300ef Blue Swirl
static void gen_oris(DisasContext *ctx)
1443 79aceca5 bellard
{
1444 76a66253 j_mayer
    target_ulong uimm = UIMM(ctx->opcode);
1445 79aceca5 bellard
1446 9a64fbe4 bellard
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1447 9a64fbe4 bellard
        /* NOP */
1448 9a64fbe4 bellard
        return;
1449 76a66253 j_mayer
    }
1450 26d67362 aurel32
    tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1451 79aceca5 bellard
}
1452 99e300ef Blue Swirl
1453 54623277 Blue Swirl
/* xori */
1454 99e300ef Blue Swirl
static void gen_xori(DisasContext *ctx)
1455 79aceca5 bellard
{
1456 76a66253 j_mayer
    target_ulong uimm = UIMM(ctx->opcode);
1457 9a64fbe4 bellard
1458 9a64fbe4 bellard
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1459 9a64fbe4 bellard
        /* NOP */
1460 9a64fbe4 bellard
        return;
1461 9a64fbe4 bellard
    }
1462 26d67362 aurel32
    tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1463 79aceca5 bellard
}
1464 99e300ef Blue Swirl
1465 54623277 Blue Swirl
/* xoris */
1466 99e300ef Blue Swirl
static void gen_xoris(DisasContext *ctx)
1467 79aceca5 bellard
{
1468 76a66253 j_mayer
    target_ulong uimm = UIMM(ctx->opcode);
1469 9a64fbe4 bellard
1470 9a64fbe4 bellard
    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1471 9a64fbe4 bellard
        /* NOP */
1472 9a64fbe4 bellard
        return;
1473 9a64fbe4 bellard
    }
1474 26d67362 aurel32
    tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1475 79aceca5 bellard
}
1476 99e300ef Blue Swirl
1477 54623277 Blue Swirl
/* popcntb : PowerPC 2.03 specification */
1478 99e300ef Blue Swirl
static void gen_popcntb(DisasContext *ctx)
1479 d9bce9d9 j_mayer
{
1480 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
1481 d9bce9d9 j_mayer
    if (ctx->sf_mode)
1482 a7812ae4 pbrook
        gen_helper_popcntb_64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1483 d9bce9d9 j_mayer
    else
1484 d9bce9d9 j_mayer
#endif
1485 a7812ae4 pbrook
        gen_helper_popcntb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1486 d9bce9d9 j_mayer
}
1487 d9bce9d9 j_mayer
1488 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
1489 d9bce9d9 j_mayer
/* extsw & extsw. */
1490 26d67362 aurel32
GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
1491 99e300ef Blue Swirl
1492 54623277 Blue Swirl
/* cntlzd */
1493 99e300ef Blue Swirl
static void gen_cntlzd(DisasContext *ctx)
1494 26d67362 aurel32
{
1495 a7812ae4 pbrook
    gen_helper_cntlzd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1496 26d67362 aurel32
    if (unlikely(Rc(ctx->opcode) != 0))
1497 26d67362 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1498 26d67362 aurel32
}
1499 d9bce9d9 j_mayer
#endif
1500 d9bce9d9 j_mayer
1501 79aceca5 bellard
/***                             Integer rotate                            ***/
1502 99e300ef Blue Swirl
1503 54623277 Blue Swirl
/* rlwimi & rlwimi. */
1504 99e300ef Blue Swirl
static void gen_rlwimi(DisasContext *ctx)
1505 79aceca5 bellard
{
1506 76a66253 j_mayer
    uint32_t mb, me, sh;
1507 79aceca5 bellard
1508 79aceca5 bellard
    mb = MB(ctx->opcode);
1509 79aceca5 bellard
    me = ME(ctx->opcode);
1510 76a66253 j_mayer
    sh = SH(ctx->opcode);
1511 d03ef511 aurel32
    if (likely(sh == 0 && mb == 0 && me == 31)) {
1512 d03ef511 aurel32
        tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1513 d03ef511 aurel32
    } else {
1514 d03ef511 aurel32
        target_ulong mask;
1515 a7812ae4 pbrook
        TCGv t1;
1516 a7812ae4 pbrook
        TCGv t0 = tcg_temp_new();
1517 54843a58 aurel32
#if defined(TARGET_PPC64)
1518 a7812ae4 pbrook
        TCGv_i32 t2 = tcg_temp_new_i32();
1519 a7812ae4 pbrook
        tcg_gen_trunc_i64_i32(t2, cpu_gpr[rS(ctx->opcode)]);
1520 a7812ae4 pbrook
        tcg_gen_rotli_i32(t2, t2, sh);
1521 a7812ae4 pbrook
        tcg_gen_extu_i32_i64(t0, t2);
1522 a7812ae4 pbrook
        tcg_temp_free_i32(t2);
1523 54843a58 aurel32
#else
1524 54843a58 aurel32
        tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
1525 54843a58 aurel32
#endif
1526 76a66253 j_mayer
#if defined(TARGET_PPC64)
1527 d03ef511 aurel32
        mb += 32;
1528 d03ef511 aurel32
        me += 32;
1529 76a66253 j_mayer
#endif
1530 d03ef511 aurel32
        mask = MASK(mb, me);
1531 a7812ae4 pbrook
        t1 = tcg_temp_new();
1532 d03ef511 aurel32
        tcg_gen_andi_tl(t0, t0, mask);
1533 d03ef511 aurel32
        tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
1534 d03ef511 aurel32
        tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1535 d03ef511 aurel32
        tcg_temp_free(t0);
1536 d03ef511 aurel32
        tcg_temp_free(t1);
1537 d03ef511 aurel32
    }
1538 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
1539 d03ef511 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1540 79aceca5 bellard
}
1541 99e300ef Blue Swirl
1542 54623277 Blue Swirl
/* rlwinm & rlwinm. */
1543 99e300ef Blue Swirl
static void gen_rlwinm(DisasContext *ctx)
1544 79aceca5 bellard
{
1545 79aceca5 bellard
    uint32_t mb, me, sh;
1546 3b46e624 ths
1547 79aceca5 bellard
    sh = SH(ctx->opcode);
1548 79aceca5 bellard
    mb = MB(ctx->opcode);
1549 79aceca5 bellard
    me = ME(ctx->opcode);
1550 d03ef511 aurel32
1551 d03ef511 aurel32
    if (likely(mb == 0 && me == (31 - sh))) {
1552 d03ef511 aurel32
        if (likely(sh == 0)) {
1553 d03ef511 aurel32
            tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1554 d03ef511 aurel32
        } else {
1555 a7812ae4 pbrook
            TCGv t0 = tcg_temp_new();
1556 d03ef511 aurel32
            tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
1557 d03ef511 aurel32
            tcg_gen_shli_tl(t0, t0, sh);
1558 d03ef511 aurel32
            tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
1559 d03ef511 aurel32
            tcg_temp_free(t0);
1560 79aceca5 bellard
        }
1561 d03ef511 aurel32
    } else if (likely(sh != 0 && me == 31 && sh == (32 - mb))) {
1562 a7812ae4 pbrook
        TCGv t0 = tcg_temp_new();
1563 d03ef511 aurel32
        tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
1564 d03ef511 aurel32
        tcg_gen_shri_tl(t0, t0, mb);
1565 d03ef511 aurel32
        tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
1566 d03ef511 aurel32
        tcg_temp_free(t0);
1567 d03ef511 aurel32
    } else {
1568 a7812ae4 pbrook
        TCGv t0 = tcg_temp_new();
1569 54843a58 aurel32
#if defined(TARGET_PPC64)
1570 a7812ae4 pbrook
        TCGv_i32 t1 = tcg_temp_new_i32();
1571 54843a58 aurel32
        tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
1572 54843a58 aurel32
        tcg_gen_rotli_i32(t1, t1, sh);
1573 54843a58 aurel32
        tcg_gen_extu_i32_i64(t0, t1);
1574 a7812ae4 pbrook
        tcg_temp_free_i32(t1);
1575 54843a58 aurel32
#else
1576 54843a58 aurel32
        tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
1577 54843a58 aurel32
#endif
1578 76a66253 j_mayer
#if defined(TARGET_PPC64)
1579 d03ef511 aurel32
        mb += 32;
1580 d03ef511 aurel32
        me += 32;
1581 76a66253 j_mayer
#endif
1582 d03ef511 aurel32
        tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1583 d03ef511 aurel32
        tcg_temp_free(t0);
1584 d03ef511 aurel32
    }
1585 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
1586 d03ef511 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1587 79aceca5 bellard
}
1588 99e300ef Blue Swirl
1589 54623277 Blue Swirl
/* rlwnm & rlwnm. */
1590 99e300ef Blue Swirl
static void gen_rlwnm(DisasContext *ctx)
1591 79aceca5 bellard
{
1592 79aceca5 bellard
    uint32_t mb, me;
1593 54843a58 aurel32
    TCGv t0;
1594 54843a58 aurel32
#if defined(TARGET_PPC64)
1595 a7812ae4 pbrook
    TCGv_i32 t1, t2;
1596 54843a58 aurel32
#endif
1597 79aceca5 bellard
1598 79aceca5 bellard
    mb = MB(ctx->opcode);
1599 79aceca5 bellard
    me = ME(ctx->opcode);
1600 a7812ae4 pbrook
    t0 = tcg_temp_new();
1601 d03ef511 aurel32
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1f);
1602 54843a58 aurel32
#if defined(TARGET_PPC64)
1603 a7812ae4 pbrook
    t1 = tcg_temp_new_i32();
1604 a7812ae4 pbrook
    t2 = tcg_temp_new_i32();
1605 54843a58 aurel32
    tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
1606 54843a58 aurel32
    tcg_gen_trunc_i64_i32(t2, t0);
1607 54843a58 aurel32
    tcg_gen_rotl_i32(t1, t1, t2);
1608 54843a58 aurel32
    tcg_gen_extu_i32_i64(t0, t1);
1609 a7812ae4 pbrook
    tcg_temp_free_i32(t1);
1610 a7812ae4 pbrook
    tcg_temp_free_i32(t2);
1611 54843a58 aurel32
#else
1612 54843a58 aurel32
    tcg_gen_rotl_i32(t0, cpu_gpr[rS(ctx->opcode)], t0);
1613 54843a58 aurel32
#endif
1614 76a66253 j_mayer
    if (unlikely(mb != 0 || me != 31)) {
1615 76a66253 j_mayer
#if defined(TARGET_PPC64)
1616 76a66253 j_mayer
        mb += 32;
1617 76a66253 j_mayer
        me += 32;
1618 76a66253 j_mayer
#endif
1619 54843a58 aurel32
        tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1620 d03ef511 aurel32
    } else {
1621 54843a58 aurel32
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1622 79aceca5 bellard
    }
1623 54843a58 aurel32
    tcg_temp_free(t0);
1624 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
1625 d03ef511 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1626 79aceca5 bellard
}
1627 79aceca5 bellard
1628 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
1629 d9bce9d9 j_mayer
#define GEN_PPC64_R2(name, opc1, opc2)                                        \
1630 e8eaa2c0 Blue Swirl
static void glue(gen_, name##0)(DisasContext *ctx)                            \
1631 d9bce9d9 j_mayer
{                                                                             \
1632 d9bce9d9 j_mayer
    gen_##name(ctx, 0);                                                       \
1633 d9bce9d9 j_mayer
}                                                                             \
1634 e8eaa2c0 Blue Swirl
                                                                              \
1635 e8eaa2c0 Blue Swirl
static void glue(gen_, name##1)(DisasContext *ctx)                            \
1636 d9bce9d9 j_mayer
{                                                                             \
1637 d9bce9d9 j_mayer
    gen_##name(ctx, 1);                                                       \
1638 d9bce9d9 j_mayer
}
1639 d9bce9d9 j_mayer
#define GEN_PPC64_R4(name, opc1, opc2)                                        \
1640 e8eaa2c0 Blue Swirl
static void glue(gen_, name##0)(DisasContext *ctx)                            \
1641 d9bce9d9 j_mayer
{                                                                             \
1642 d9bce9d9 j_mayer
    gen_##name(ctx, 0, 0);                                                    \
1643 d9bce9d9 j_mayer
}                                                                             \
1644 e8eaa2c0 Blue Swirl
                                                                              \
1645 e8eaa2c0 Blue Swirl
static void glue(gen_, name##1)(DisasContext *ctx)                            \
1646 d9bce9d9 j_mayer
{                                                                             \
1647 d9bce9d9 j_mayer
    gen_##name(ctx, 0, 1);                                                    \
1648 d9bce9d9 j_mayer
}                                                                             \
1649 e8eaa2c0 Blue Swirl
                                                                              \
1650 e8eaa2c0 Blue Swirl
static void glue(gen_, name##2)(DisasContext *ctx)                            \
1651 d9bce9d9 j_mayer
{                                                                             \
1652 d9bce9d9 j_mayer
    gen_##name(ctx, 1, 0);                                                    \
1653 d9bce9d9 j_mayer
}                                                                             \
1654 e8eaa2c0 Blue Swirl
                                                                              \
1655 e8eaa2c0 Blue Swirl
static void glue(gen_, name##3)(DisasContext *ctx)                            \
1656 d9bce9d9 j_mayer
{                                                                             \
1657 d9bce9d9 j_mayer
    gen_##name(ctx, 1, 1);                                                    \
1658 d9bce9d9 j_mayer
}
1659 51789c41 j_mayer
1660 b068d6a7 j_mayer
static always_inline void gen_rldinm (DisasContext *ctx, uint32_t mb,
1661 b068d6a7 j_mayer
                                      uint32_t me, uint32_t sh)
1662 51789c41 j_mayer
{
1663 d03ef511 aurel32
    if (likely(sh != 0 && mb == 0 && me == (63 - sh))) {
1664 d03ef511 aurel32
        tcg_gen_shli_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
1665 d03ef511 aurel32
    } else if (likely(sh != 0 && me == 63 && sh == (64 - mb))) {
1666 d03ef511 aurel32
        tcg_gen_shri_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], mb);
1667 d03ef511 aurel32
    } else {
1668 a7812ae4 pbrook
        TCGv t0 = tcg_temp_new();
1669 54843a58 aurel32
        tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
1670 d03ef511 aurel32
        if (likely(mb == 0 && me == 63)) {
1671 54843a58 aurel32
            tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1672 d03ef511 aurel32
        } else {
1673 d03ef511 aurel32
            tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1674 51789c41 j_mayer
        }
1675 d03ef511 aurel32
        tcg_temp_free(t0);
1676 51789c41 j_mayer
    }
1677 51789c41 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
1678 d03ef511 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1679 51789c41 j_mayer
}
1680 d9bce9d9 j_mayer
/* rldicl - rldicl. */
1681 b068d6a7 j_mayer
static always_inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
1682 d9bce9d9 j_mayer
{
1683 51789c41 j_mayer
    uint32_t sh, mb;
1684 d9bce9d9 j_mayer
1685 9d53c753 j_mayer
    sh = SH(ctx->opcode) | (shn << 5);
1686 9d53c753 j_mayer
    mb = MB(ctx->opcode) | (mbn << 5);
1687 51789c41 j_mayer
    gen_rldinm(ctx, mb, 63, sh);
1688 d9bce9d9 j_mayer
}
1689 51789c41 j_mayer
GEN_PPC64_R4(rldicl, 0x1E, 0x00);
1690 d9bce9d9 j_mayer
/* rldicr - rldicr. */
1691 b068d6a7 j_mayer
static always_inline void gen_rldicr (DisasContext *ctx, int men, int shn)
1692 d9bce9d9 j_mayer
{
1693 51789c41 j_mayer
    uint32_t sh, me;
1694 d9bce9d9 j_mayer
1695 9d53c753 j_mayer
    sh = SH(ctx->opcode) | (shn << 5);
1696 9d53c753 j_mayer
    me = MB(ctx->opcode) | (men << 5);
1697 51789c41 j_mayer
    gen_rldinm(ctx, 0, me, sh);
1698 d9bce9d9 j_mayer
}
1699 51789c41 j_mayer
GEN_PPC64_R4(rldicr, 0x1E, 0x02);
1700 d9bce9d9 j_mayer
/* rldic - rldic. */
1701 b068d6a7 j_mayer
static always_inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
1702 d9bce9d9 j_mayer
{
1703 51789c41 j_mayer
    uint32_t sh, mb;
1704 d9bce9d9 j_mayer
1705 9d53c753 j_mayer
    sh = SH(ctx->opcode) | (shn << 5);
1706 9d53c753 j_mayer
    mb = MB(ctx->opcode) | (mbn << 5);
1707 51789c41 j_mayer
    gen_rldinm(ctx, mb, 63 - sh, sh);
1708 51789c41 j_mayer
}
1709 51789c41 j_mayer
GEN_PPC64_R4(rldic, 0x1E, 0x04);
1710 51789c41 j_mayer
1711 b068d6a7 j_mayer
static always_inline void gen_rldnm (DisasContext *ctx, uint32_t mb,
1712 b068d6a7 j_mayer
                                     uint32_t me)
1713 51789c41 j_mayer
{
1714 54843a58 aurel32
    TCGv t0;
1715 d03ef511 aurel32
1716 d03ef511 aurel32
    mb = MB(ctx->opcode);
1717 d03ef511 aurel32
    me = ME(ctx->opcode);
1718 a7812ae4 pbrook
    t0 = tcg_temp_new();
1719 d03ef511 aurel32
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
1720 54843a58 aurel32
    tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1721 51789c41 j_mayer
    if (unlikely(mb != 0 || me != 63)) {
1722 54843a58 aurel32
        tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1723 54843a58 aurel32
    } else {
1724 54843a58 aurel32
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1725 54843a58 aurel32
    }
1726 54843a58 aurel32
    tcg_temp_free(t0);
1727 51789c41 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
1728 d03ef511 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1729 d9bce9d9 j_mayer
}
1730 51789c41 j_mayer
1731 d9bce9d9 j_mayer
/* rldcl - rldcl. */
1732 b068d6a7 j_mayer
static always_inline void gen_rldcl (DisasContext *ctx, int mbn)
1733 d9bce9d9 j_mayer
{
1734 51789c41 j_mayer
    uint32_t mb;
1735 d9bce9d9 j_mayer
1736 9d53c753 j_mayer
    mb = MB(ctx->opcode) | (mbn << 5);
1737 51789c41 j_mayer
    gen_rldnm(ctx, mb, 63);
1738 d9bce9d9 j_mayer
}
1739 36081602 j_mayer
GEN_PPC64_R2(rldcl, 0x1E, 0x08);
1740 d9bce9d9 j_mayer
/* rldcr - rldcr. */
1741 b068d6a7 j_mayer
static always_inline void gen_rldcr (DisasContext *ctx, int men)
1742 d9bce9d9 j_mayer
{
1743 51789c41 j_mayer
    uint32_t me;
1744 d9bce9d9 j_mayer
1745 9d53c753 j_mayer
    me = MB(ctx->opcode) | (men << 5);
1746 51789c41 j_mayer
    gen_rldnm(ctx, 0, me);
1747 d9bce9d9 j_mayer
}
1748 36081602 j_mayer
GEN_PPC64_R2(rldcr, 0x1E, 0x09);
1749 d9bce9d9 j_mayer
/* rldimi - rldimi. */
1750 b068d6a7 j_mayer
static always_inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
1751 d9bce9d9 j_mayer
{
1752 271a916e j_mayer
    uint32_t sh, mb, me;
1753 d9bce9d9 j_mayer
1754 9d53c753 j_mayer
    sh = SH(ctx->opcode) | (shn << 5);
1755 9d53c753 j_mayer
    mb = MB(ctx->opcode) | (mbn << 5);
1756 271a916e j_mayer
    me = 63 - sh;
1757 d03ef511 aurel32
    if (unlikely(sh == 0 && mb == 0)) {
1758 d03ef511 aurel32
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1759 d03ef511 aurel32
    } else {
1760 d03ef511 aurel32
        TCGv t0, t1;
1761 d03ef511 aurel32
        target_ulong mask;
1762 d03ef511 aurel32
1763 a7812ae4 pbrook
        t0 = tcg_temp_new();
1764 54843a58 aurel32
        tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
1765 a7812ae4 pbrook
        t1 = tcg_temp_new();
1766 d03ef511 aurel32
        mask = MASK(mb, me);
1767 d03ef511 aurel32
        tcg_gen_andi_tl(t0, t0, mask);
1768 d03ef511 aurel32
        tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
1769 d03ef511 aurel32
        tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1770 d03ef511 aurel32
        tcg_temp_free(t0);
1771 d03ef511 aurel32
        tcg_temp_free(t1);
1772 51789c41 j_mayer
    }
1773 51789c41 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
1774 d03ef511 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1775 d9bce9d9 j_mayer
}
1776 36081602 j_mayer
GEN_PPC64_R4(rldimi, 0x1E, 0x06);
1777 d9bce9d9 j_mayer
#endif
1778 d9bce9d9 j_mayer
1779 79aceca5 bellard
/***                             Integer shift                             ***/
1780 99e300ef Blue Swirl
1781 54623277 Blue Swirl
/* slw & slw. */
1782 99e300ef Blue Swirl
static void gen_slw(DisasContext *ctx)
1783 26d67362 aurel32
{
1784 fea0c503 aurel32
    TCGv t0;
1785 26d67362 aurel32
    int l1, l2;
1786 26d67362 aurel32
    l1 = gen_new_label();
1787 26d67362 aurel32
    l2 = gen_new_label();
1788 26d67362 aurel32
1789 a7812ae4 pbrook
    t0 = tcg_temp_local_new();
1790 0cfe58cd aurel32
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
1791 0cfe58cd aurel32
    tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0x20, l1);
1792 26d67362 aurel32
    tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
1793 26d67362 aurel32
    tcg_gen_br(l2);
1794 26d67362 aurel32
    gen_set_label(l1);
1795 fea0c503 aurel32
    tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t0);
1796 26d67362 aurel32
    tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1797 26d67362 aurel32
    gen_set_label(l2);
1798 fea0c503 aurel32
    tcg_temp_free(t0);
1799 26d67362 aurel32
    if (unlikely(Rc(ctx->opcode) != 0))
1800 26d67362 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1801 26d67362 aurel32
}
1802 99e300ef Blue Swirl
1803 54623277 Blue Swirl
/* sraw & sraw. */
1804 99e300ef Blue Swirl
static void gen_sraw(DisasContext *ctx)
1805 26d67362 aurel32
{
1806 a7812ae4 pbrook
    gen_helper_sraw(cpu_gpr[rA(ctx->opcode)],
1807 a7812ae4 pbrook
                    cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1808 26d67362 aurel32
    if (unlikely(Rc(ctx->opcode) != 0))
1809 26d67362 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1810 26d67362 aurel32
}
1811 99e300ef Blue Swirl
1812 54623277 Blue Swirl
/* srawi & srawi. */
1813 99e300ef Blue Swirl
static void gen_srawi(DisasContext *ctx)
1814 79aceca5 bellard
{
1815 26d67362 aurel32
    int sh = SH(ctx->opcode);
1816 26d67362 aurel32
    if (sh != 0) {
1817 26d67362 aurel32
        int l1, l2;
1818 fea0c503 aurel32
        TCGv t0;
1819 26d67362 aurel32
        l1 = gen_new_label();
1820 26d67362 aurel32
        l2 = gen_new_label();
1821 a7812ae4 pbrook
        t0 = tcg_temp_local_new();
1822 fea0c503 aurel32
        tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx->opcode)]);
1823 fea0c503 aurel32
        tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
1824 fea0c503 aurel32
        tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
1825 fea0c503 aurel32
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1826 269f3e95 aurel32
        tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
1827 26d67362 aurel32
        tcg_gen_br(l2);
1828 26d67362 aurel32
        gen_set_label(l1);
1829 269f3e95 aurel32
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1830 26d67362 aurel32
        gen_set_label(l2);
1831 fea0c503 aurel32
        tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx->opcode)]);
1832 fea0c503 aurel32
        tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], t0, sh);
1833 fea0c503 aurel32
        tcg_temp_free(t0);
1834 26d67362 aurel32
    } else {
1835 26d67362 aurel32
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1836 269f3e95 aurel32
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1837 d9bce9d9 j_mayer
    }
1838 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
1839 26d67362 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1840 79aceca5 bellard
}
1841 99e300ef Blue Swirl
1842 54623277 Blue Swirl
/* srw & srw. */
1843 99e300ef Blue Swirl
static void gen_srw(DisasContext *ctx)
1844 26d67362 aurel32
{
1845 fea0c503 aurel32
    TCGv t0, t1;
1846 26d67362 aurel32
    int l1, l2;
1847 26d67362 aurel32
    l1 = gen_new_label();
1848 26d67362 aurel32
    l2 = gen_new_label();
1849 d9bce9d9 j_mayer
1850 a7812ae4 pbrook
    t0 = tcg_temp_local_new();
1851 0cfe58cd aurel32
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
1852 0cfe58cd aurel32
    tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0x20, l1);
1853 26d67362 aurel32
    tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
1854 26d67362 aurel32
    tcg_gen_br(l2);
1855 26d67362 aurel32
    gen_set_label(l1);
1856 a7812ae4 pbrook
    t1 = tcg_temp_new();
1857 fea0c503 aurel32
    tcg_gen_ext32u_tl(t1, cpu_gpr[rS(ctx->opcode)]);
1858 fea0c503 aurel32
    tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t1, t0);
1859 fea0c503 aurel32
    tcg_temp_free(t1);
1860 26d67362 aurel32
    gen_set_label(l2);
1861 fea0c503 aurel32
    tcg_temp_free(t0);
1862 26d67362 aurel32
    if (unlikely(Rc(ctx->opcode) != 0))
1863 26d67362 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1864 26d67362 aurel32
}
1865 54623277 Blue Swirl
1866 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
1867 d9bce9d9 j_mayer
/* sld & sld. */
1868 99e300ef Blue Swirl
static void gen_sld(DisasContext *ctx)
1869 26d67362 aurel32
{
1870 fea0c503 aurel32
    TCGv t0;
1871 26d67362 aurel32
    int l1, l2;
1872 26d67362 aurel32
    l1 = gen_new_label();
1873 26d67362 aurel32
    l2 = gen_new_label();
1874 26d67362 aurel32
1875 a7812ae4 pbrook
    t0 = tcg_temp_local_new();
1876 0cfe58cd aurel32
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x7f);
1877 0cfe58cd aurel32
    tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0x40, l1);
1878 26d67362 aurel32
    tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
1879 26d67362 aurel32
    tcg_gen_br(l2);
1880 26d67362 aurel32
    gen_set_label(l1);
1881 fea0c503 aurel32
    tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t0);
1882 26d67362 aurel32
    gen_set_label(l2);
1883 fea0c503 aurel32
    tcg_temp_free(t0);
1884 26d67362 aurel32
    if (unlikely(Rc(ctx->opcode) != 0))
1885 26d67362 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1886 26d67362 aurel32
}
1887 99e300ef Blue Swirl
1888 54623277 Blue Swirl
/* srad & srad. */
1889 99e300ef Blue Swirl
static void gen_srad(DisasContext *ctx)
1890 26d67362 aurel32
{
1891 a7812ae4 pbrook
    gen_helper_srad(cpu_gpr[rA(ctx->opcode)],
1892 a7812ae4 pbrook
                    cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1893 26d67362 aurel32
    if (unlikely(Rc(ctx->opcode) != 0))
1894 26d67362 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1895 26d67362 aurel32
}
1896 d9bce9d9 j_mayer
/* sradi & sradi. */
1897 b068d6a7 j_mayer
static always_inline void gen_sradi (DisasContext *ctx, int n)
1898 d9bce9d9 j_mayer
{
1899 26d67362 aurel32
    int sh = SH(ctx->opcode) + (n << 5);
1900 d9bce9d9 j_mayer
    if (sh != 0) {
1901 26d67362 aurel32
        int l1, l2;
1902 fea0c503 aurel32
        TCGv t0;
1903 26d67362 aurel32
        l1 = gen_new_label();
1904 26d67362 aurel32
        l2 = gen_new_label();
1905 a7812ae4 pbrook
        t0 = tcg_temp_local_new();
1906 26d67362 aurel32
        tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
1907 fea0c503 aurel32
        tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
1908 fea0c503 aurel32
        tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1909 269f3e95 aurel32
        tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
1910 26d67362 aurel32
        tcg_gen_br(l2);
1911 26d67362 aurel32
        gen_set_label(l1);
1912 269f3e95 aurel32
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1913 26d67362 aurel32
        gen_set_label(l2);
1914 a9730017 aurel32
        tcg_temp_free(t0);
1915 26d67362 aurel32
        tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
1916 26d67362 aurel32
    } else {
1917 26d67362 aurel32
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1918 269f3e95 aurel32
        tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1919 d9bce9d9 j_mayer
    }
1920 d9bce9d9 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
1921 26d67362 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1922 d9bce9d9 j_mayer
}
1923 e8eaa2c0 Blue Swirl
1924 e8eaa2c0 Blue Swirl
static void gen_sradi0(DisasContext *ctx)
1925 d9bce9d9 j_mayer
{
1926 d9bce9d9 j_mayer
    gen_sradi(ctx, 0);
1927 d9bce9d9 j_mayer
}
1928 e8eaa2c0 Blue Swirl
1929 e8eaa2c0 Blue Swirl
static void gen_sradi1(DisasContext *ctx)
1930 d9bce9d9 j_mayer
{
1931 d9bce9d9 j_mayer
    gen_sradi(ctx, 1);
1932 d9bce9d9 j_mayer
}
1933 99e300ef Blue Swirl
1934 54623277 Blue Swirl
/* srd & srd. */
1935 99e300ef Blue Swirl
static void gen_srd(DisasContext *ctx)
1936 26d67362 aurel32
{
1937 fea0c503 aurel32
    TCGv t0;
1938 26d67362 aurel32
    int l1, l2;
1939 26d67362 aurel32
    l1 = gen_new_label();
1940 26d67362 aurel32
    l2 = gen_new_label();
1941 26d67362 aurel32
1942 a7812ae4 pbrook
    t0 = tcg_temp_local_new();
1943 0cfe58cd aurel32
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x7f);
1944 0cfe58cd aurel32
    tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0x40, l1);
1945 26d67362 aurel32
    tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
1946 26d67362 aurel32
    tcg_gen_br(l2);
1947 26d67362 aurel32
    gen_set_label(l1);
1948 fea0c503 aurel32
    tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t0);
1949 26d67362 aurel32
    gen_set_label(l2);
1950 fea0c503 aurel32
    tcg_temp_free(t0);
1951 26d67362 aurel32
    if (unlikely(Rc(ctx->opcode) != 0))
1952 26d67362 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1953 26d67362 aurel32
}
1954 d9bce9d9 j_mayer
#endif
1955 79aceca5 bellard
1956 79aceca5 bellard
/***                       Floating-Point arithmetic                       ***/
1957 7c58044c j_mayer
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
1958 99e300ef Blue Swirl
static void gen_f##name(DisasContext *ctx)                                    \
1959 9a64fbe4 bellard
{                                                                             \
1960 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1961 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1962 3cc62370 bellard
        return;                                                               \
1963 3cc62370 bellard
    }                                                                         \
1964 eb44b959 aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */ \
1965 eb44b959 aurel32
    gen_update_nip(ctx, ctx->nip - 4);                                        \
1966 7c58044c j_mayer
    gen_reset_fpstatus();                                                     \
1967 af12906f aurel32
    gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
1968 af12906f aurel32
                     cpu_fpr[rC(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);     \
1969 4ecc3190 bellard
    if (isfloat) {                                                            \
1970 af12906f aurel32
        gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
1971 4ecc3190 bellard
    }                                                                         \
1972 af12906f aurel32
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], set_fprf,                      \
1973 af12906f aurel32
                     Rc(ctx->opcode) != 0);                                   \
1974 9a64fbe4 bellard
}
1975 9a64fbe4 bellard
1976 7c58044c j_mayer
#define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
1977 7c58044c j_mayer
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type);                     \
1978 7c58044c j_mayer
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
1979 9a64fbe4 bellard
1980 7c58044c j_mayer
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
1981 99e300ef Blue Swirl
static void gen_f##name(DisasContext *ctx)                                    \
1982 9a64fbe4 bellard
{                                                                             \
1983 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
1984 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1985 3cc62370 bellard
        return;                                                               \
1986 3cc62370 bellard
    }                                                                         \
1987 eb44b959 aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */ \
1988 eb44b959 aurel32
    gen_update_nip(ctx, ctx->nip - 4);                                        \
1989 7c58044c j_mayer
    gen_reset_fpstatus();                                                     \
1990 af12906f aurel32
    gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
1991 af12906f aurel32
                     cpu_fpr[rB(ctx->opcode)]);                               \
1992 4ecc3190 bellard
    if (isfloat) {                                                            \
1993 af12906f aurel32
        gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
1994 4ecc3190 bellard
    }                                                                         \
1995 af12906f aurel32
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
1996 af12906f aurel32
                     set_fprf, Rc(ctx->opcode) != 0);                         \
1997 9a64fbe4 bellard
}
1998 7c58044c j_mayer
#define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
1999 7c58044c j_mayer
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
2000 7c58044c j_mayer
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
2001 9a64fbe4 bellard
2002 7c58044c j_mayer
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
2003 99e300ef Blue Swirl
static void gen_f##name(DisasContext *ctx)                                    \
2004 9a64fbe4 bellard
{                                                                             \
2005 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2006 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2007 3cc62370 bellard
        return;                                                               \
2008 3cc62370 bellard
    }                                                                         \
2009 eb44b959 aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */ \
2010 eb44b959 aurel32
    gen_update_nip(ctx, ctx->nip - 4);                                        \
2011 7c58044c j_mayer
    gen_reset_fpstatus();                                                     \
2012 af12906f aurel32
    gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
2013 af12906f aurel32
                       cpu_fpr[rC(ctx->opcode)]);                             \
2014 4ecc3190 bellard
    if (isfloat) {                                                            \
2015 af12906f aurel32
        gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
2016 4ecc3190 bellard
    }                                                                         \
2017 af12906f aurel32
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
2018 af12906f aurel32
                     set_fprf, Rc(ctx->opcode) != 0);                         \
2019 9a64fbe4 bellard
}
2020 7c58044c j_mayer
#define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
2021 7c58044c j_mayer
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
2022 7c58044c j_mayer
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
2023 9a64fbe4 bellard
2024 7c58044c j_mayer
#define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
2025 99e300ef Blue Swirl
static void gen_f##name(DisasContext *ctx)                                    \
2026 9a64fbe4 bellard
{                                                                             \
2027 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2028 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2029 3cc62370 bellard
        return;                                                               \
2030 3cc62370 bellard
    }                                                                         \
2031 eb44b959 aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */ \
2032 eb44b959 aurel32
    gen_update_nip(ctx, ctx->nip - 4);                                        \
2033 7c58044c j_mayer
    gen_reset_fpstatus();                                                     \
2034 af12906f aurel32
    gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);   \
2035 af12906f aurel32
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
2036 af12906f aurel32
                     set_fprf, Rc(ctx->opcode) != 0);                         \
2037 79aceca5 bellard
}
2038 79aceca5 bellard
2039 7c58044c j_mayer
#define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
2040 99e300ef Blue Swirl
static void gen_f##name(DisasContext *ctx)                                    \
2041 9a64fbe4 bellard
{                                                                             \
2042 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
2043 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
2044 3cc62370 bellard
        return;                                                               \
2045 3cc62370 bellard
    }                                                                         \
2046 eb44b959 aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */ \
2047 eb44b959 aurel32
    gen_update_nip(ctx, ctx->nip - 4);                                        \
2048 7c58044c j_mayer
    gen_reset_fpstatus();                                                     \
2049 af12906f aurel32
    gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);   \
2050 af12906f aurel32
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
2051 af12906f aurel32
                     set_fprf, Rc(ctx->opcode) != 0);                         \
2052 79aceca5 bellard
}
2053 79aceca5 bellard
2054 9a64fbe4 bellard
/* fadd - fadds */
2055 7c58044c j_mayer
GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
2056 4ecc3190 bellard
/* fdiv - fdivs */
2057 7c58044c j_mayer
GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
2058 4ecc3190 bellard
/* fmul - fmuls */
2059 7c58044c j_mayer
GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
2060 79aceca5 bellard
2061 d7e4b87e j_mayer
/* fre */
2062 7c58044c j_mayer
GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
2063 d7e4b87e j_mayer
2064 a750fc0b j_mayer
/* fres */
2065 7c58044c j_mayer
GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
2066 79aceca5 bellard
2067 a750fc0b j_mayer
/* frsqrte */
2068 7c58044c j_mayer
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
2069 7c58044c j_mayer
2070 7c58044c j_mayer
/* frsqrtes */
2071 99e300ef Blue Swirl
static void gen_frsqrtes(DisasContext *ctx)
2072 7c58044c j_mayer
{
2073 af12906f aurel32
    if (unlikely(!ctx->fpu_enabled)) {
2074 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);
2075 af12906f aurel32
        return;
2076 af12906f aurel32
    }
2077 eb44b959 aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */
2078 eb44b959 aurel32
    gen_update_nip(ctx, ctx->nip - 4);
2079 af12906f aurel32
    gen_reset_fpstatus();
2080 af12906f aurel32
    gen_helper_frsqrte(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
2081 af12906f aurel32
    gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);
2082 af12906f aurel32
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
2083 7c58044c j_mayer
}
2084 79aceca5 bellard
2085 a750fc0b j_mayer
/* fsel */
2086 7c58044c j_mayer
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
2087 4ecc3190 bellard
/* fsub - fsubs */
2088 7c58044c j_mayer
GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
2089 79aceca5 bellard
/* Optional: */
2090 99e300ef Blue Swirl
2091 54623277 Blue Swirl
/* fsqrt */
2092 99e300ef Blue Swirl
static void gen_fsqrt(DisasContext *ctx)
2093 c7d344af bellard
{
2094 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
2095 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);
2096 c7d344af bellard
        return;
2097 c7d344af bellard
    }
2098 eb44b959 aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */
2099 eb44b959 aurel32
    gen_update_nip(ctx, ctx->nip - 4);
2100 7c58044c j_mayer
    gen_reset_fpstatus();
2101 af12906f aurel32
    gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
2102 af12906f aurel32
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
2103 c7d344af bellard
}
2104 79aceca5 bellard
2105 99e300ef Blue Swirl
static void gen_fsqrts(DisasContext *ctx)
2106 79aceca5 bellard
{
2107 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
2108 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);
2109 3cc62370 bellard
        return;
2110 3cc62370 bellard
    }
2111 eb44b959 aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */
2112 eb44b959 aurel32
    gen_update_nip(ctx, ctx->nip - 4);
2113 7c58044c j_mayer
    gen_reset_fpstatus();
2114 af12906f aurel32
    gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
2115 af12906f aurel32
    gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);
2116 af12906f aurel32
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
2117 79aceca5 bellard
}
2118 79aceca5 bellard
2119 79aceca5 bellard
/***                     Floating-Point multiply-and-add                   ***/
2120 4ecc3190 bellard
/* fmadd - fmadds */
2121 7c58044c j_mayer
GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
2122 4ecc3190 bellard
/* fmsub - fmsubs */
2123 7c58044c j_mayer
GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
2124 4ecc3190 bellard
/* fnmadd - fnmadds */
2125 7c58044c j_mayer
GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
2126 4ecc3190 bellard
/* fnmsub - fnmsubs */
2127 7c58044c j_mayer
GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
2128 79aceca5 bellard
2129 79aceca5 bellard
/***                     Floating-Point round & convert                    ***/
2130 79aceca5 bellard
/* fctiw */
2131 7c58044c j_mayer
GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
2132 79aceca5 bellard
/* fctiwz */
2133 7c58044c j_mayer
GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
2134 79aceca5 bellard
/* frsp */
2135 7c58044c j_mayer
GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
2136 426613db j_mayer
#if defined(TARGET_PPC64)
2137 426613db j_mayer
/* fcfid */
2138 7c58044c j_mayer
GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B);
2139 426613db j_mayer
/* fctid */
2140 7c58044c j_mayer
GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B);
2141 426613db j_mayer
/* fctidz */
2142 7c58044c j_mayer
GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B);
2143 426613db j_mayer
#endif
2144 79aceca5 bellard
2145 d7e4b87e j_mayer
/* frin */
2146 7c58044c j_mayer
GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
2147 d7e4b87e j_mayer
/* friz */
2148 7c58044c j_mayer
GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
2149 d7e4b87e j_mayer
/* frip */
2150 7c58044c j_mayer
GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
2151 d7e4b87e j_mayer
/* frim */
2152 7c58044c j_mayer
GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
2153 d7e4b87e j_mayer
2154 79aceca5 bellard
/***                         Floating-Point compare                        ***/
2155 99e300ef Blue Swirl
2156 54623277 Blue Swirl
/* fcmpo */
2157 99e300ef Blue Swirl
static void gen_fcmpo(DisasContext *ctx)
2158 79aceca5 bellard
{
2159 330c483b aurel32
    TCGv_i32 crf;
2160 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
2161 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);
2162 3cc62370 bellard
        return;
2163 3cc62370 bellard
    }
2164 eb44b959 aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */
2165 eb44b959 aurel32
    gen_update_nip(ctx, ctx->nip - 4);
2166 7c58044c j_mayer
    gen_reset_fpstatus();
2167 9a819377 aurel32
    crf = tcg_const_i32(crfD(ctx->opcode));
2168 9a819377 aurel32
    gen_helper_fcmpo(cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)], crf);
2169 330c483b aurel32
    tcg_temp_free_i32(crf);
2170 af12906f aurel32
    gen_helper_float_check_status();
2171 79aceca5 bellard
}
2172 79aceca5 bellard
2173 79aceca5 bellard
/* fcmpu */
2174 99e300ef Blue Swirl
static void gen_fcmpu(DisasContext *ctx)
2175 79aceca5 bellard
{
2176 330c483b aurel32
    TCGv_i32 crf;
2177 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
2178 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);
2179 3cc62370 bellard
        return;
2180 3cc62370 bellard
    }
2181 eb44b959 aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */
2182 eb44b959 aurel32
    gen_update_nip(ctx, ctx->nip - 4);
2183 7c58044c j_mayer
    gen_reset_fpstatus();
2184 9a819377 aurel32
    crf = tcg_const_i32(crfD(ctx->opcode));
2185 9a819377 aurel32
    gen_helper_fcmpu(cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)], crf);
2186 330c483b aurel32
    tcg_temp_free_i32(crf);
2187 af12906f aurel32
    gen_helper_float_check_status();
2188 79aceca5 bellard
}
2189 79aceca5 bellard
2190 9a64fbe4 bellard
/***                         Floating-point move                           ***/
2191 9a64fbe4 bellard
/* fabs */
2192 7c58044c j_mayer
/* XXX: beware that fabs never checks for NaNs nor update FPSCR */
2193 7c58044c j_mayer
GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT);
2194 9a64fbe4 bellard
2195 9a64fbe4 bellard
/* fmr  - fmr. */
2196 7c58044c j_mayer
/* XXX: beware that fmr never checks for NaNs nor update FPSCR */
2197 99e300ef Blue Swirl
static void gen_fmr(DisasContext *ctx)
2198 9a64fbe4 bellard
{
2199 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
2200 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);
2201 3cc62370 bellard
        return;
2202 3cc62370 bellard
    }
2203 af12906f aurel32
    tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
2204 af12906f aurel32
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
2205 9a64fbe4 bellard
}
2206 9a64fbe4 bellard
2207 9a64fbe4 bellard
/* fnabs */
2208 7c58044c j_mayer
/* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
2209 7c58044c j_mayer
GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT);
2210 9a64fbe4 bellard
/* fneg */
2211 7c58044c j_mayer
/* XXX: beware that fneg never checks for NaNs nor update FPSCR */
2212 7c58044c j_mayer
GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT);
2213 9a64fbe4 bellard
2214 79aceca5 bellard
/***                  Floating-Point status & ctrl register                ***/
2215 99e300ef Blue Swirl
2216 54623277 Blue Swirl
/* mcrfs */
2217 99e300ef Blue Swirl
static void gen_mcrfs(DisasContext *ctx)
2218 79aceca5 bellard
{
2219 7c58044c j_mayer
    int bfa;
2220 7c58044c j_mayer
2221 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
2222 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);
2223 3cc62370 bellard
        return;
2224 3cc62370 bellard
    }
2225 7c58044c j_mayer
    bfa = 4 * (7 - crfS(ctx->opcode));
2226 e1571908 aurel32
    tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_fpscr, bfa);
2227 e1571908 aurel32
    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], 0xf);
2228 af12906f aurel32
    tcg_gen_andi_i32(cpu_fpscr, cpu_fpscr, ~(0xF << bfa));
2229 79aceca5 bellard
}
2230 79aceca5 bellard
2231 79aceca5 bellard
/* mffs */
2232 99e300ef Blue Swirl
static void gen_mffs(DisasContext *ctx)
2233 79aceca5 bellard
{
2234 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
2235 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);
2236 3cc62370 bellard
        return;
2237 3cc62370 bellard
    }
2238 7c58044c j_mayer
    gen_reset_fpstatus();
2239 af12906f aurel32
    tcg_gen_extu_i32_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpscr);
2240 af12906f aurel32
    gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
2241 79aceca5 bellard
}
2242 79aceca5 bellard
2243 79aceca5 bellard
/* mtfsb0 */
2244 99e300ef Blue Swirl
static void gen_mtfsb0(DisasContext *ctx)
2245 79aceca5 bellard
{
2246 fb0eaffc bellard
    uint8_t crb;
2247 3b46e624 ths
2248 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
2249 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);
2250 3cc62370 bellard
        return;
2251 3cc62370 bellard
    }
2252 6e35d524 aurel32
    crb = 31 - crbD(ctx->opcode);
2253 7c58044c j_mayer
    gen_reset_fpstatus();
2254 6e35d524 aurel32
    if (likely(crb != FPSCR_FEX && crb != FPSCR_VX)) {
2255 eb44b959 aurel32
        TCGv_i32 t0;
2256 eb44b959 aurel32
        /* NIP cannot be restored if the memory exception comes from an helper */
2257 eb44b959 aurel32
        gen_update_nip(ctx, ctx->nip - 4);
2258 eb44b959 aurel32
        t0 = tcg_const_i32(crb);
2259 6e35d524 aurel32
        gen_helper_fpscr_clrbit(t0);
2260 6e35d524 aurel32
        tcg_temp_free_i32(t0);
2261 6e35d524 aurel32
    }
2262 7c58044c j_mayer
    if (unlikely(Rc(ctx->opcode) != 0)) {
2263 e1571908 aurel32
        tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2264 7c58044c j_mayer
    }
2265 79aceca5 bellard
}
2266 79aceca5 bellard
2267 79aceca5 bellard
/* mtfsb1 */
2268 99e300ef Blue Swirl
static void gen_mtfsb1(DisasContext *ctx)
2269 79aceca5 bellard
{
2270 fb0eaffc bellard
    uint8_t crb;
2271 3b46e624 ths
2272 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
2273 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);
2274 3cc62370 bellard
        return;
2275 3cc62370 bellard
    }
2276 6e35d524 aurel32
    crb = 31 - crbD(ctx->opcode);
2277 7c58044c j_mayer
    gen_reset_fpstatus();
2278 7c58044c j_mayer
    /* XXX: we pretend we can only do IEEE floating-point computations */
2279 af12906f aurel32
    if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI)) {
2280 eb44b959 aurel32
        TCGv_i32 t0;
2281 eb44b959 aurel32
        /* NIP cannot be restored if the memory exception comes from an helper */
2282 eb44b959 aurel32
        gen_update_nip(ctx, ctx->nip - 4);
2283 eb44b959 aurel32
        t0 = tcg_const_i32(crb);
2284 af12906f aurel32
        gen_helper_fpscr_setbit(t0);
2285 0f2f39c2 aurel32
        tcg_temp_free_i32(t0);
2286 af12906f aurel32
    }
2287 7c58044c j_mayer
    if (unlikely(Rc(ctx->opcode) != 0)) {
2288 e1571908 aurel32
        tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2289 7c58044c j_mayer
    }
2290 7c58044c j_mayer
    /* We can raise a differed exception */
2291 af12906f aurel32
    gen_helper_float_check_status();
2292 79aceca5 bellard
}
2293 79aceca5 bellard
2294 79aceca5 bellard
/* mtfsf */
2295 99e300ef Blue Swirl
static void gen_mtfsf(DisasContext *ctx)
2296 79aceca5 bellard
{
2297 0f2f39c2 aurel32
    TCGv_i32 t0;
2298 4911012d blueswir1
    int L = ctx->opcode & 0x02000000;
2299 af12906f aurel32
2300 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
2301 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);
2302 3cc62370 bellard
        return;
2303 3cc62370 bellard
    }
2304 eb44b959 aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */
2305 eb44b959 aurel32
    gen_update_nip(ctx, ctx->nip - 4);
2306 7c58044c j_mayer
    gen_reset_fpstatus();
2307 4911012d blueswir1
    if (L)
2308 4911012d blueswir1
        t0 = tcg_const_i32(0xff);
2309 4911012d blueswir1
    else
2310 4911012d blueswir1
        t0 = tcg_const_i32(FM(ctx->opcode));
2311 af12906f aurel32
    gen_helper_store_fpscr(cpu_fpr[rB(ctx->opcode)], t0);
2312 0f2f39c2 aurel32
    tcg_temp_free_i32(t0);
2313 7c58044c j_mayer
    if (unlikely(Rc(ctx->opcode) != 0)) {
2314 e1571908 aurel32
        tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2315 7c58044c j_mayer
    }
2316 7c58044c j_mayer
    /* We can raise a differed exception */
2317 af12906f aurel32
    gen_helper_float_check_status();
2318 79aceca5 bellard
}
2319 79aceca5 bellard
2320 79aceca5 bellard
/* mtfsfi */
2321 99e300ef Blue Swirl
static void gen_mtfsfi(DisasContext *ctx)
2322 79aceca5 bellard
{
2323 7c58044c j_mayer
    int bf, sh;
2324 0f2f39c2 aurel32
    TCGv_i64 t0;
2325 0f2f39c2 aurel32
    TCGv_i32 t1;
2326 7c58044c j_mayer
2327 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {
2328 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);
2329 3cc62370 bellard
        return;
2330 3cc62370 bellard
    }
2331 7c58044c j_mayer
    bf = crbD(ctx->opcode) >> 2;
2332 7c58044c j_mayer
    sh = 7 - bf;
2333 eb44b959 aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */
2334 eb44b959 aurel32
    gen_update_nip(ctx, ctx->nip - 4);
2335 7c58044c j_mayer
    gen_reset_fpstatus();
2336 0f2f39c2 aurel32
    t0 = tcg_const_i64(FPIMM(ctx->opcode) << (4 * sh));
2337 af12906f aurel32
    t1 = tcg_const_i32(1 << sh);
2338 af12906f aurel32
    gen_helper_store_fpscr(t0, t1);
2339 0f2f39c2 aurel32
    tcg_temp_free_i64(t0);
2340 0f2f39c2 aurel32
    tcg_temp_free_i32(t1);
2341 7c58044c j_mayer
    if (unlikely(Rc(ctx->opcode) != 0)) {
2342 e1571908 aurel32
        tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
2343 7c58044c j_mayer
    }
2344 7c58044c j_mayer
    /* We can raise a differed exception */
2345 af12906f aurel32
    gen_helper_float_check_status();
2346 79aceca5 bellard
}
2347 79aceca5 bellard
2348 76a66253 j_mayer
/***                           Addressing modes                            ***/
2349 76a66253 j_mayer
/* Register indirect with immediate index : EA = (rA|0) + SIMM */
2350 76db3ba4 aurel32
static always_inline void gen_addr_imm_index (DisasContext *ctx, TCGv EA, target_long maskl)
2351 76a66253 j_mayer
{
2352 76a66253 j_mayer
    target_long simm = SIMM(ctx->opcode);
2353 76a66253 j_mayer
2354 be147d08 j_mayer
    simm &= ~maskl;
2355 76db3ba4 aurel32
    if (rA(ctx->opcode) == 0) {
2356 76db3ba4 aurel32
#if defined(TARGET_PPC64)
2357 76db3ba4 aurel32
        if (!ctx->sf_mode) {
2358 76db3ba4 aurel32
            tcg_gen_movi_tl(EA, (uint32_t)simm);
2359 76db3ba4 aurel32
        } else
2360 76db3ba4 aurel32
#endif
2361 e2be8d8d aurel32
        tcg_gen_movi_tl(EA, simm);
2362 76db3ba4 aurel32
    } else if (likely(simm != 0)) {
2363 e2be8d8d aurel32
        tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm);
2364 76db3ba4 aurel32
#if defined(TARGET_PPC64)
2365 76db3ba4 aurel32
        if (!ctx->sf_mode) {
2366 76db3ba4 aurel32
            tcg_gen_ext32u_tl(EA, EA);
2367 76db3ba4 aurel32
        }
2368 76db3ba4 aurel32
#endif
2369 76db3ba4 aurel32
    } else {
2370 76db3ba4 aurel32
#if defined(TARGET_PPC64)
2371 76db3ba4 aurel32
        if (!ctx->sf_mode) {
2372 76db3ba4 aurel32
            tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2373 76db3ba4 aurel32
        } else
2374 76db3ba4 aurel32
#endif
2375 e2be8d8d aurel32
        tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2376 76db3ba4 aurel32
    }
2377 76a66253 j_mayer
}
2378 76a66253 j_mayer
2379 76db3ba4 aurel32
static always_inline void gen_addr_reg_index (DisasContext *ctx, TCGv EA)
2380 76a66253 j_mayer
{
2381 76db3ba4 aurel32
    if (rA(ctx->opcode) == 0) {
2382 76db3ba4 aurel32
#if defined(TARGET_PPC64)
2383 76db3ba4 aurel32
        if (!ctx->sf_mode) {
2384 76db3ba4 aurel32
            tcg_gen_ext32u_tl(EA, cpu_gpr[rB(ctx->opcode)]);
2385 76db3ba4 aurel32
        } else
2386 76db3ba4 aurel32
#endif
2387 e2be8d8d aurel32
        tcg_gen_mov_tl(EA, cpu_gpr[rB(ctx->opcode)]);
2388 76db3ba4 aurel32
    } else {
2389 e2be8d8d aurel32
        tcg_gen_add_tl(EA, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
2390 76db3ba4 aurel32
#if defined(TARGET_PPC64)
2391 76db3ba4 aurel32
        if (!ctx->sf_mode) {
2392 76db3ba4 aurel32
            tcg_gen_ext32u_tl(EA, EA);
2393 76db3ba4 aurel32
        }
2394 76db3ba4 aurel32
#endif
2395 76db3ba4 aurel32
    }
2396 76a66253 j_mayer
}
2397 76a66253 j_mayer
2398 76db3ba4 aurel32
static always_inline void gen_addr_register (DisasContext *ctx, TCGv EA)
2399 76a66253 j_mayer
{
2400 76db3ba4 aurel32
    if (rA(ctx->opcode) == 0) {
2401 e2be8d8d aurel32
        tcg_gen_movi_tl(EA, 0);
2402 76db3ba4 aurel32
    } else {
2403 76db3ba4 aurel32
#if defined(TARGET_PPC64)
2404 76db3ba4 aurel32
        if (!ctx->sf_mode) {
2405 76db3ba4 aurel32
            tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2406 76db3ba4 aurel32
        } else
2407 76db3ba4 aurel32
#endif
2408 76db3ba4 aurel32
            tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2409 76db3ba4 aurel32
    }
2410 76db3ba4 aurel32
}
2411 76db3ba4 aurel32
2412 76db3ba4 aurel32
static always_inline void gen_addr_add (DisasContext *ctx, TCGv ret, TCGv arg1, target_long val)
2413 76db3ba4 aurel32
{
2414 76db3ba4 aurel32
    tcg_gen_addi_tl(ret, arg1, val);
2415 76db3ba4 aurel32
#if defined(TARGET_PPC64)
2416 76db3ba4 aurel32
    if (!ctx->sf_mode) {
2417 76db3ba4 aurel32
        tcg_gen_ext32u_tl(ret, ret);
2418 76db3ba4 aurel32
    }
2419 76db3ba4 aurel32
#endif
2420 76a66253 j_mayer
}
2421 76a66253 j_mayer
2422 cf360a32 aurel32
static always_inline void gen_check_align (DisasContext *ctx, TCGv EA, int mask)
2423 cf360a32 aurel32
{
2424 cf360a32 aurel32
    int l1 = gen_new_label();
2425 cf360a32 aurel32
    TCGv t0 = tcg_temp_new();
2426 cf360a32 aurel32
    TCGv_i32 t1, t2;
2427 cf360a32 aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */
2428 cf360a32 aurel32
    gen_update_nip(ctx, ctx->nip - 4);
2429 cf360a32 aurel32
    tcg_gen_andi_tl(t0, EA, mask);
2430 cf360a32 aurel32
    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2431 cf360a32 aurel32
    t1 = tcg_const_i32(POWERPC_EXCP_ALIGN);
2432 cf360a32 aurel32
    t2 = tcg_const_i32(0);
2433 cf360a32 aurel32
    gen_helper_raise_exception_err(t1, t2);
2434 cf360a32 aurel32
    tcg_temp_free_i32(t1);
2435 cf360a32 aurel32
    tcg_temp_free_i32(t2);
2436 cf360a32 aurel32
    gen_set_label(l1);
2437 cf360a32 aurel32
    tcg_temp_free(t0);
2438 cf360a32 aurel32
}
2439 cf360a32 aurel32
2440 7863667f j_mayer
/***                             Integer load                              ***/
2441 76db3ba4 aurel32
static always_inline void gen_qemu_ld8u(DisasContext *ctx, TCGv arg1, TCGv arg2)
2442 76db3ba4 aurel32
{
2443 76db3ba4 aurel32
    tcg_gen_qemu_ld8u(arg1, arg2, ctx->mem_idx);
2444 76db3ba4 aurel32
}
2445 76db3ba4 aurel32
2446 76db3ba4 aurel32
static always_inline void gen_qemu_ld8s(DisasContext *ctx, TCGv arg1, TCGv arg2)
2447 76db3ba4 aurel32
{
2448 76db3ba4 aurel32
    tcg_gen_qemu_ld8s(arg1, arg2, ctx->mem_idx);
2449 76db3ba4 aurel32
}
2450 76db3ba4 aurel32
2451 76db3ba4 aurel32
static always_inline void gen_qemu_ld16u(DisasContext *ctx, TCGv arg1, TCGv arg2)
2452 76db3ba4 aurel32
{
2453 76db3ba4 aurel32
    tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
2454 76db3ba4 aurel32
    if (unlikely(ctx->le_mode)) {
2455 fa3966a3 aurel32
        tcg_gen_bswap16_tl(arg1, arg1);
2456 76db3ba4 aurel32
    }
2457 b61f2753 aurel32
}
2458 b61f2753 aurel32
2459 76db3ba4 aurel32
static always_inline void gen_qemu_ld16s(DisasContext *ctx, TCGv arg1, TCGv arg2)
2460 b61f2753 aurel32
{
2461 76db3ba4 aurel32
    if (unlikely(ctx->le_mode)) {
2462 76db3ba4 aurel32
        tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
2463 fa3966a3 aurel32
        tcg_gen_bswap16_tl(arg1, arg1);
2464 76db3ba4 aurel32
        tcg_gen_ext16s_tl(arg1, arg1);
2465 76db3ba4 aurel32
    } else {
2466 76db3ba4 aurel32
        tcg_gen_qemu_ld16s(arg1, arg2, ctx->mem_idx);
2467 76db3ba4 aurel32
    }
2468 b61f2753 aurel32
}
2469 b61f2753 aurel32
2470 76db3ba4 aurel32
static always_inline void gen_qemu_ld32u(DisasContext *ctx, TCGv arg1, TCGv arg2)
2471 b61f2753 aurel32
{
2472 76db3ba4 aurel32
    tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
2473 76db3ba4 aurel32
    if (unlikely(ctx->le_mode)) {
2474 fa3966a3 aurel32
        tcg_gen_bswap32_tl(arg1, arg1);
2475 76db3ba4 aurel32
    }
2476 b61f2753 aurel32
}
2477 b61f2753 aurel32
2478 76db3ba4 aurel32
#if defined(TARGET_PPC64)
2479 76db3ba4 aurel32
static always_inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2)
2480 b61f2753 aurel32
{
2481 a457e7ee blueswir1
    if (unlikely(ctx->le_mode)) {
2482 76db3ba4 aurel32
        tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
2483 fa3966a3 aurel32
        tcg_gen_bswap32_tl(arg1, arg1);
2484 fa3966a3 aurel32
        tcg_gen_ext32s_tl(arg1, arg1);
2485 b61f2753 aurel32
    } else
2486 76db3ba4 aurel32
        tcg_gen_qemu_ld32s(arg1, arg2, ctx->mem_idx);
2487 b61f2753 aurel32
}
2488 76db3ba4 aurel32
#endif
2489 b61f2753 aurel32
2490 76db3ba4 aurel32
static always_inline void gen_qemu_ld64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
2491 b61f2753 aurel32
{
2492 76db3ba4 aurel32
    tcg_gen_qemu_ld64(arg1, arg2, ctx->mem_idx);
2493 76db3ba4 aurel32
    if (unlikely(ctx->le_mode)) {
2494 66896cb8 aurel32
        tcg_gen_bswap64_i64(arg1, arg1);
2495 76db3ba4 aurel32
    }
2496 b61f2753 aurel32
}
2497 b61f2753 aurel32
2498 76db3ba4 aurel32
static always_inline void gen_qemu_st8(DisasContext *ctx, TCGv arg1, TCGv arg2)
2499 b61f2753 aurel32
{
2500 76db3ba4 aurel32
    tcg_gen_qemu_st8(arg1, arg2, ctx->mem_idx);
2501 b61f2753 aurel32
}
2502 b61f2753 aurel32
2503 76db3ba4 aurel32
static always_inline void gen_qemu_st16(DisasContext *ctx, TCGv arg1, TCGv arg2)
2504 b61f2753 aurel32
{
2505 76db3ba4 aurel32
    if (unlikely(ctx->le_mode)) {
2506 76db3ba4 aurel32
        TCGv t0 = tcg_temp_new();
2507 76db3ba4 aurel32
        tcg_gen_ext16u_tl(t0, arg1);
2508 fa3966a3 aurel32
        tcg_gen_bswap16_tl(t0, t0);
2509 76db3ba4 aurel32
        tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
2510 76db3ba4 aurel32
        tcg_temp_free(t0);
2511 76db3ba4 aurel32
    } else {
2512 76db3ba4 aurel32
        tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
2513 76db3ba4 aurel32
    }
2514 b61f2753 aurel32
}
2515 b61f2753 aurel32
2516 76db3ba4 aurel32
static always_inline void gen_qemu_st32(DisasContext *ctx, TCGv arg1, TCGv arg2)
2517 b61f2753 aurel32
{
2518 76db3ba4 aurel32
    if (unlikely(ctx->le_mode)) {
2519 fa3966a3 aurel32
        TCGv t0 = tcg_temp_new();
2520 fa3966a3 aurel32
        tcg_gen_ext32u_tl(t0, arg1);
2521 fa3966a3 aurel32
        tcg_gen_bswap32_tl(t0, t0);
2522 76db3ba4 aurel32
        tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx);
2523 76db3ba4 aurel32
        tcg_temp_free(t0);
2524 76db3ba4 aurel32
    } else {
2525 76db3ba4 aurel32
        tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
2526 76db3ba4 aurel32
    }
2527 b61f2753 aurel32
}
2528 b61f2753 aurel32
2529 76db3ba4 aurel32
static always_inline void gen_qemu_st64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
2530 b61f2753 aurel32
{
2531 76db3ba4 aurel32
    if (unlikely(ctx->le_mode)) {
2532 a7812ae4 pbrook
        TCGv_i64 t0 = tcg_temp_new_i64();
2533 66896cb8 aurel32
        tcg_gen_bswap64_i64(t0, arg1);
2534 76db3ba4 aurel32
        tcg_gen_qemu_st64(t0, arg2, ctx->mem_idx);
2535 a7812ae4 pbrook
        tcg_temp_free_i64(t0);
2536 b61f2753 aurel32
    } else
2537 76db3ba4 aurel32
        tcg_gen_qemu_st64(arg1, arg2, ctx->mem_idx);
2538 b61f2753 aurel32
}
2539 b61f2753 aurel32
2540 0c8aacd4 aurel32
#define GEN_LD(name, ldop, opc, type)                                         \
2541 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                       \
2542 79aceca5 bellard
{                                                                             \
2543 76db3ba4 aurel32
    TCGv EA;                                                                  \
2544 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_INT);                                     \
2545 76db3ba4 aurel32
    EA = tcg_temp_new();                                                      \
2546 76db3ba4 aurel32
    gen_addr_imm_index(ctx, EA, 0);                                           \
2547 76db3ba4 aurel32
    gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2548 b61f2753 aurel32
    tcg_temp_free(EA);                                                        \
2549 79aceca5 bellard
}
2550 79aceca5 bellard
2551 0c8aacd4 aurel32
#define GEN_LDU(name, ldop, opc, type)                                        \
2552 99e300ef Blue Swirl
static void glue(gen_, name##u)(DisasContext *ctx)                                    \
2553 79aceca5 bellard
{                                                                             \
2554 b61f2753 aurel32
    TCGv EA;                                                                  \
2555 76a66253 j_mayer
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2556 76a66253 j_mayer
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2557 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2558 9fddaa0c bellard
        return;                                                               \
2559 9a64fbe4 bellard
    }                                                                         \
2560 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_INT);                                     \
2561 0c8aacd4 aurel32
    EA = tcg_temp_new();                                                      \
2562 9d53c753 j_mayer
    if (type == PPC_64B)                                                      \
2563 76db3ba4 aurel32
        gen_addr_imm_index(ctx, EA, 0x03);                                    \
2564 9d53c753 j_mayer
    else                                                                      \
2565 76db3ba4 aurel32
        gen_addr_imm_index(ctx, EA, 0);                                       \
2566 76db3ba4 aurel32
    gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2567 b61f2753 aurel32
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2568 b61f2753 aurel32
    tcg_temp_free(EA);                                                        \
2569 79aceca5 bellard
}
2570 79aceca5 bellard
2571 0c8aacd4 aurel32
#define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
2572 99e300ef Blue Swirl
static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
2573 79aceca5 bellard
{                                                                             \
2574 b61f2753 aurel32
    TCGv EA;                                                                  \
2575 76a66253 j_mayer
    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2576 76a66253 j_mayer
                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2577 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2578 9fddaa0c bellard
        return;                                                               \
2579 9a64fbe4 bellard
    }                                                                         \
2580 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_INT);                                     \
2581 0c8aacd4 aurel32
    EA = tcg_temp_new();                                                      \
2582 76db3ba4 aurel32
    gen_addr_reg_index(ctx, EA);                                              \
2583 76db3ba4 aurel32
    gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2584 b61f2753 aurel32
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2585 b61f2753 aurel32
    tcg_temp_free(EA);                                                        \
2586 79aceca5 bellard
}
2587 79aceca5 bellard
2588 0c8aacd4 aurel32
#define GEN_LDX(name, ldop, opc2, opc3, type)                                 \
2589 99e300ef Blue Swirl
static void glue(gen_, name##x)(DisasContext *ctx)                            \
2590 79aceca5 bellard
{                                                                             \
2591 76db3ba4 aurel32
    TCGv EA;                                                                  \
2592 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_INT);                                     \
2593 76db3ba4 aurel32
    EA = tcg_temp_new();                                                      \
2594 76db3ba4 aurel32
    gen_addr_reg_index(ctx, EA);                                              \
2595 76db3ba4 aurel32
    gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2596 b61f2753 aurel32
    tcg_temp_free(EA);                                                        \
2597 79aceca5 bellard
}
2598 79aceca5 bellard
2599 0c8aacd4 aurel32
#define GEN_LDS(name, ldop, op, type)                                         \
2600 0c8aacd4 aurel32
GEN_LD(name, ldop, op | 0x20, type);                                          \
2601 0c8aacd4 aurel32
GEN_LDU(name, ldop, op | 0x21, type);                                         \
2602 0c8aacd4 aurel32
GEN_LDUX(name, ldop, 0x17, op | 0x01, type);                                  \
2603 0c8aacd4 aurel32
GEN_LDX(name, ldop, 0x17, op | 0x00, type)
2604 79aceca5 bellard
2605 79aceca5 bellard
/* lbz lbzu lbzux lbzx */
2606 0c8aacd4 aurel32
GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER);
2607 79aceca5 bellard
/* lha lhau lhaux lhax */
2608 0c8aacd4 aurel32
GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER);
2609 79aceca5 bellard
/* lhz lhzu lhzux lhzx */
2610 0c8aacd4 aurel32
GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER);
2611 79aceca5 bellard
/* lwz lwzu lwzux lwzx */
2612 0c8aacd4 aurel32
GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER);
2613 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
2614 d9bce9d9 j_mayer
/* lwaux */
2615 0c8aacd4 aurel32
GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B);
2616 d9bce9d9 j_mayer
/* lwax */
2617 0c8aacd4 aurel32
GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B);
2618 d9bce9d9 j_mayer
/* ldux */
2619 0c8aacd4 aurel32
GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B);
2620 d9bce9d9 j_mayer
/* ldx */
2621 0c8aacd4 aurel32
GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B);
2622 99e300ef Blue Swirl
2623 99e300ef Blue Swirl
static void gen_ld(DisasContext *ctx)
2624 d9bce9d9 j_mayer
{
2625 b61f2753 aurel32
    TCGv EA;
2626 d9bce9d9 j_mayer
    if (Rc(ctx->opcode)) {
2627 d9bce9d9 j_mayer
        if (unlikely(rA(ctx->opcode) == 0 ||
2628 d9bce9d9 j_mayer
                     rA(ctx->opcode) == rD(ctx->opcode))) {
2629 e06fcd75 aurel32
            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2630 d9bce9d9 j_mayer
            return;
2631 d9bce9d9 j_mayer
        }
2632 d9bce9d9 j_mayer
    }
2633 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_INT);
2634 a7812ae4 pbrook
    EA = tcg_temp_new();
2635 76db3ba4 aurel32
    gen_addr_imm_index(ctx, EA, 0x03);
2636 d9bce9d9 j_mayer
    if (ctx->opcode & 0x02) {
2637 d9bce9d9 j_mayer
        /* lwa (lwau is undefined) */
2638 76db3ba4 aurel32
        gen_qemu_ld32s(ctx, cpu_gpr[rD(ctx->opcode)], EA);
2639 d9bce9d9 j_mayer
    } else {
2640 d9bce9d9 j_mayer
        /* ld - ldu */
2641 76db3ba4 aurel32
        gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], EA);
2642 d9bce9d9 j_mayer
    }
2643 d9bce9d9 j_mayer
    if (Rc(ctx->opcode))
2644 b61f2753 aurel32
        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
2645 b61f2753 aurel32
    tcg_temp_free(EA);
2646 d9bce9d9 j_mayer
}
2647 99e300ef Blue Swirl
2648 54623277 Blue Swirl
/* lq */
2649 99e300ef Blue Swirl
static void gen_lq(DisasContext *ctx)
2650 be147d08 j_mayer
{
2651 be147d08 j_mayer
#if defined(CONFIG_USER_ONLY)
2652 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2653 be147d08 j_mayer
#else
2654 be147d08 j_mayer
    int ra, rd;
2655 b61f2753 aurel32
    TCGv EA;
2656 be147d08 j_mayer
2657 be147d08 j_mayer
    /* Restore CPU state */
2658 76db3ba4 aurel32
    if (unlikely(ctx->mem_idx == 0)) {
2659 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2660 be147d08 j_mayer
        return;
2661 be147d08 j_mayer
    }
2662 be147d08 j_mayer
    ra = rA(ctx->opcode);
2663 be147d08 j_mayer
    rd = rD(ctx->opcode);
2664 be147d08 j_mayer
    if (unlikely((rd & 1) || rd == ra)) {
2665 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2666 be147d08 j_mayer
        return;
2667 be147d08 j_mayer
    }
2668 76db3ba4 aurel32
    if (unlikely(ctx->le_mode)) {
2669 be147d08 j_mayer
        /* Little-endian mode is not handled */
2670 e06fcd75 aurel32
        gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2671 be147d08 j_mayer
        return;
2672 be147d08 j_mayer
    }
2673 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_INT);
2674 a7812ae4 pbrook
    EA = tcg_temp_new();
2675 76db3ba4 aurel32
    gen_addr_imm_index(ctx, EA, 0x0F);
2676 76db3ba4 aurel32
    gen_qemu_ld64(ctx, cpu_gpr[rd], EA);
2677 76db3ba4 aurel32
    gen_addr_add(ctx, EA, EA, 8);
2678 76db3ba4 aurel32
    gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA);
2679 b61f2753 aurel32
    tcg_temp_free(EA);
2680 be147d08 j_mayer
#endif
2681 be147d08 j_mayer
}
2682 d9bce9d9 j_mayer
#endif
2683 79aceca5 bellard
2684 79aceca5 bellard
/***                              Integer store                            ***/
2685 0c8aacd4 aurel32
#define GEN_ST(name, stop, opc, type)                                         \
2686 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                       \
2687 79aceca5 bellard
{                                                                             \
2688 76db3ba4 aurel32
    TCGv EA;                                                                  \
2689 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_INT);                                     \
2690 76db3ba4 aurel32
    EA = tcg_temp_new();                                                      \
2691 76db3ba4 aurel32
    gen_addr_imm_index(ctx, EA, 0);                                           \
2692 76db3ba4 aurel32
    gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2693 b61f2753 aurel32
    tcg_temp_free(EA);                                                        \
2694 79aceca5 bellard
}
2695 79aceca5 bellard
2696 0c8aacd4 aurel32
#define GEN_STU(name, stop, opc, type)                                        \
2697 99e300ef Blue Swirl
static void glue(gen_, stop##u)(DisasContext *ctx)                                    \
2698 79aceca5 bellard
{                                                                             \
2699 b61f2753 aurel32
    TCGv EA;                                                                  \
2700 76a66253 j_mayer
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2701 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2702 9fddaa0c bellard
        return;                                                               \
2703 9a64fbe4 bellard
    }                                                                         \
2704 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_INT);                                     \
2705 0c8aacd4 aurel32
    EA = tcg_temp_new();                                                      \
2706 9d53c753 j_mayer
    if (type == PPC_64B)                                                      \
2707 76db3ba4 aurel32
        gen_addr_imm_index(ctx, EA, 0x03);                                    \
2708 9d53c753 j_mayer
    else                                                                      \
2709 76db3ba4 aurel32
        gen_addr_imm_index(ctx, EA, 0);                                       \
2710 76db3ba4 aurel32
    gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2711 b61f2753 aurel32
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2712 b61f2753 aurel32
    tcg_temp_free(EA);                                                        \
2713 79aceca5 bellard
}
2714 79aceca5 bellard
2715 0c8aacd4 aurel32
#define GEN_STUX(name, stop, opc2, opc3, type)                                \
2716 99e300ef Blue Swirl
static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
2717 79aceca5 bellard
{                                                                             \
2718 b61f2753 aurel32
    TCGv EA;                                                                  \
2719 76a66253 j_mayer
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2720 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2721 9fddaa0c bellard
        return;                                                               \
2722 9a64fbe4 bellard
    }                                                                         \
2723 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_INT);                                     \
2724 0c8aacd4 aurel32
    EA = tcg_temp_new();                                                      \
2725 76db3ba4 aurel32
    gen_addr_reg_index(ctx, EA);                                              \
2726 76db3ba4 aurel32
    gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2727 b61f2753 aurel32
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2728 b61f2753 aurel32
    tcg_temp_free(EA);                                                        \
2729 79aceca5 bellard
}
2730 79aceca5 bellard
2731 0c8aacd4 aurel32
#define GEN_STX(name, stop, opc2, opc3, type)                                 \
2732 99e300ef Blue Swirl
static void glue(gen_, name##x)(DisasContext *ctx)                                    \
2733 79aceca5 bellard
{                                                                             \
2734 76db3ba4 aurel32
    TCGv EA;                                                                  \
2735 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_INT);                                     \
2736 76db3ba4 aurel32
    EA = tcg_temp_new();                                                      \
2737 76db3ba4 aurel32
    gen_addr_reg_index(ctx, EA);                                              \
2738 76db3ba4 aurel32
    gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2739 b61f2753 aurel32
    tcg_temp_free(EA);                                                        \
2740 79aceca5 bellard
}
2741 79aceca5 bellard
2742 0c8aacd4 aurel32
#define GEN_STS(name, stop, op, type)                                         \
2743 0c8aacd4 aurel32
GEN_ST(name, stop, op | 0x20, type);                                          \
2744 0c8aacd4 aurel32
GEN_STU(name, stop, op | 0x21, type);                                         \
2745 0c8aacd4 aurel32
GEN_STUX(name, stop, 0x17, op | 0x01, type);                                  \
2746 0c8aacd4 aurel32
GEN_STX(name, stop, 0x17, op | 0x00, type)
2747 79aceca5 bellard
2748 79aceca5 bellard
/* stb stbu stbux stbx */
2749 0c8aacd4 aurel32
GEN_STS(stb, st8, 0x06, PPC_INTEGER);
2750 79aceca5 bellard
/* sth sthu sthux sthx */
2751 0c8aacd4 aurel32
GEN_STS(sth, st16, 0x0C, PPC_INTEGER);
2752 79aceca5 bellard
/* stw stwu stwux stwx */
2753 0c8aacd4 aurel32
GEN_STS(stw, st32, 0x04, PPC_INTEGER);
2754 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
2755 0c8aacd4 aurel32
GEN_STUX(std, st64, 0x15, 0x05, PPC_64B);
2756 0c8aacd4 aurel32
GEN_STX(std, st64, 0x15, 0x04, PPC_64B);
2757 99e300ef Blue Swirl
2758 99e300ef Blue Swirl
static void gen_std(DisasContext *ctx)
2759 d9bce9d9 j_mayer
{
2760 be147d08 j_mayer
    int rs;
2761 b61f2753 aurel32
    TCGv EA;
2762 be147d08 j_mayer
2763 be147d08 j_mayer
    rs = rS(ctx->opcode);
2764 be147d08 j_mayer
    if ((ctx->opcode & 0x3) == 0x2) {
2765 be147d08 j_mayer
#if defined(CONFIG_USER_ONLY)
2766 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2767 be147d08 j_mayer
#else
2768 be147d08 j_mayer
        /* stq */
2769 76db3ba4 aurel32
        if (unlikely(ctx->mem_idx == 0)) {
2770 e06fcd75 aurel32
            gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2771 be147d08 j_mayer
            return;
2772 be147d08 j_mayer
        }
2773 be147d08 j_mayer
        if (unlikely(rs & 1)) {
2774 e06fcd75 aurel32
            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2775 d9bce9d9 j_mayer
            return;
2776 d9bce9d9 j_mayer
        }
2777 76db3ba4 aurel32
        if (unlikely(ctx->le_mode)) {
2778 be147d08 j_mayer
            /* Little-endian mode is not handled */
2779 e06fcd75 aurel32
            gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
2780 be147d08 j_mayer
            return;
2781 be147d08 j_mayer
        }
2782 76db3ba4 aurel32
        gen_set_access_type(ctx, ACCESS_INT);
2783 a7812ae4 pbrook
        EA = tcg_temp_new();
2784 76db3ba4 aurel32
        gen_addr_imm_index(ctx, EA, 0x03);
2785 76db3ba4 aurel32
        gen_qemu_st64(ctx, cpu_gpr[rs], EA);
2786 76db3ba4 aurel32
        gen_addr_add(ctx, EA, EA, 8);
2787 76db3ba4 aurel32
        gen_qemu_st64(ctx, cpu_gpr[rs+1], EA);
2788 b61f2753 aurel32
        tcg_temp_free(EA);
2789 be147d08 j_mayer
#endif
2790 be147d08 j_mayer
    } else {
2791 be147d08 j_mayer
        /* std / stdu */
2792 be147d08 j_mayer
        if (Rc(ctx->opcode)) {
2793 be147d08 j_mayer
            if (unlikely(rA(ctx->opcode) == 0)) {
2794 e06fcd75 aurel32
                gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2795 be147d08 j_mayer
                return;
2796 be147d08 j_mayer
            }
2797 be147d08 j_mayer
        }
2798 76db3ba4 aurel32
        gen_set_access_type(ctx, ACCESS_INT);
2799 a7812ae4 pbrook
        EA = tcg_temp_new();
2800 76db3ba4 aurel32
        gen_addr_imm_index(ctx, EA, 0x03);
2801 76db3ba4 aurel32
        gen_qemu_st64(ctx, cpu_gpr[rs], EA);
2802 be147d08 j_mayer
        if (Rc(ctx->opcode))
2803 b61f2753 aurel32
            tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
2804 b61f2753 aurel32
        tcg_temp_free(EA);
2805 d9bce9d9 j_mayer
    }
2806 d9bce9d9 j_mayer
}
2807 d9bce9d9 j_mayer
#endif
2808 79aceca5 bellard
/***                Integer load and store with byte reverse               ***/
2809 79aceca5 bellard
/* lhbrx */
2810 76db3ba4 aurel32
static void always_inline gen_qemu_ld16ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
2811 b61f2753 aurel32
{
2812 76db3ba4 aurel32
    tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
2813 76db3ba4 aurel32
    if (likely(!ctx->le_mode)) {
2814 fa3966a3 aurel32
        tcg_gen_bswap16_tl(arg1, arg1);
2815 76db3ba4 aurel32
    }
2816 b61f2753 aurel32
}
2817 0c8aacd4 aurel32
GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER);
2818 b61f2753 aurel32
2819 79aceca5 bellard
/* lwbrx */
2820 76db3ba4 aurel32
static void always_inline gen_qemu_ld32ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
2821 b61f2753 aurel32
{
2822 76db3ba4 aurel32
    tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
2823 76db3ba4 aurel32
    if (likely(!ctx->le_mode)) {
2824 fa3966a3 aurel32
        tcg_gen_bswap32_tl(arg1, arg1);
2825 76db3ba4 aurel32
    }
2826 b61f2753 aurel32
}
2827 0c8aacd4 aurel32
GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
2828 b61f2753 aurel32
2829 79aceca5 bellard
/* sthbrx */
2830 76db3ba4 aurel32
static void always_inline gen_qemu_st16r(DisasContext *ctx, TCGv arg1, TCGv arg2)
2831 b61f2753 aurel32
{
2832 76db3ba4 aurel32
    if (likely(!ctx->le_mode)) {
2833 76db3ba4 aurel32
        TCGv t0 = tcg_temp_new();
2834 76db3ba4 aurel32
        tcg_gen_ext16u_tl(t0, arg1);
2835 fa3966a3 aurel32
        tcg_gen_bswap16_tl(t0, t0);
2836 76db3ba4 aurel32
        tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
2837 76db3ba4 aurel32
        tcg_temp_free(t0);
2838 76db3ba4 aurel32
    } else {
2839 76db3ba4 aurel32
        tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
2840 76db3ba4 aurel32
    }
2841 b61f2753 aurel32
}
2842 0c8aacd4 aurel32
GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER);
2843 b61f2753 aurel32
2844 79aceca5 bellard
/* stwbrx */
2845 76db3ba4 aurel32
static void always_inline gen_qemu_st32r(DisasContext *ctx, TCGv arg1, TCGv arg2)
2846 b61f2753 aurel32
{
2847 76db3ba4 aurel32
    if (likely(!ctx->le_mode)) {
2848 fa3966a3 aurel32
        TCGv t0 = tcg_temp_new();
2849 fa3966a3 aurel32
        tcg_gen_ext32u_tl(t0, arg1);
2850 fa3966a3 aurel32
        tcg_gen_bswap32_tl(t0, t0);
2851 76db3ba4 aurel32
        tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx);
2852 76db3ba4 aurel32
        tcg_temp_free(t0);
2853 76db3ba4 aurel32
    } else {
2854 76db3ba4 aurel32
        tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
2855 76db3ba4 aurel32
    }
2856 b61f2753 aurel32
}
2857 0c8aacd4 aurel32
GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
2858 79aceca5 bellard
2859 79aceca5 bellard
/***                    Integer load and store multiple                    ***/
2860 99e300ef Blue Swirl
2861 54623277 Blue Swirl
/* lmw */
2862 99e300ef Blue Swirl
static void gen_lmw(DisasContext *ctx)
2863 79aceca5 bellard
{
2864 76db3ba4 aurel32
    TCGv t0;
2865 76db3ba4 aurel32
    TCGv_i32 t1;
2866 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_INT);
2867 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
2868 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
2869 76db3ba4 aurel32
    t0 = tcg_temp_new();
2870 76db3ba4 aurel32
    t1 = tcg_const_i32(rD(ctx->opcode));
2871 76db3ba4 aurel32
    gen_addr_imm_index(ctx, t0, 0);
2872 ff4a62cd aurel32
    gen_helper_lmw(t0, t1);
2873 ff4a62cd aurel32
    tcg_temp_free(t0);
2874 ff4a62cd aurel32
    tcg_temp_free_i32(t1);
2875 79aceca5 bellard
}
2876 79aceca5 bellard
2877 79aceca5 bellard
/* stmw */
2878 99e300ef Blue Swirl
static void gen_stmw(DisasContext *ctx)
2879 79aceca5 bellard
{
2880 76db3ba4 aurel32
    TCGv t0;
2881 76db3ba4 aurel32
    TCGv_i32 t1;
2882 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_INT);
2883 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
2884 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
2885 76db3ba4 aurel32
    t0 = tcg_temp_new();
2886 76db3ba4 aurel32
    t1 = tcg_const_i32(rS(ctx->opcode));
2887 76db3ba4 aurel32
    gen_addr_imm_index(ctx, t0, 0);
2888 ff4a62cd aurel32
    gen_helper_stmw(t0, t1);
2889 ff4a62cd aurel32
    tcg_temp_free(t0);
2890 ff4a62cd aurel32
    tcg_temp_free_i32(t1);
2891 79aceca5 bellard
}
2892 79aceca5 bellard
2893 79aceca5 bellard
/***                    Integer load and store strings                     ***/
2894 54623277 Blue Swirl
2895 79aceca5 bellard
/* lswi */
2896 3fc6c082 bellard
/* PowerPC32 specification says we must generate an exception if
2897 9a64fbe4 bellard
 * rA is in the range of registers to be loaded.
2898 9a64fbe4 bellard
 * In an other hand, IBM says this is valid, but rA won't be loaded.
2899 9a64fbe4 bellard
 * For now, I'll follow the spec...
2900 9a64fbe4 bellard
 */
2901 99e300ef Blue Swirl
static void gen_lswi(DisasContext *ctx)
2902 79aceca5 bellard
{
2903 dfbc799d aurel32
    TCGv t0;
2904 dfbc799d aurel32
    TCGv_i32 t1, t2;
2905 79aceca5 bellard
    int nb = NB(ctx->opcode);
2906 79aceca5 bellard
    int start = rD(ctx->opcode);
2907 9a64fbe4 bellard
    int ra = rA(ctx->opcode);
2908 79aceca5 bellard
    int nr;
2909 79aceca5 bellard
2910 79aceca5 bellard
    if (nb == 0)
2911 79aceca5 bellard
        nb = 32;
2912 79aceca5 bellard
    nr = nb / 4;
2913 76a66253 j_mayer
    if (unlikely(((start + nr) > 32  &&
2914 76a66253 j_mayer
                  start <= ra && (start + nr - 32) > ra) ||
2915 76a66253 j_mayer
                 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
2916 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
2917 9fddaa0c bellard
        return;
2918 297d8e62 bellard
    }
2919 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_INT);
2920 8dd4983c bellard
    /* NIP cannot be restored if the memory exception comes from an helper */
2921 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
2922 dfbc799d aurel32
    t0 = tcg_temp_new();
2923 76db3ba4 aurel32
    gen_addr_register(ctx, t0);
2924 dfbc799d aurel32
    t1 = tcg_const_i32(nb);
2925 dfbc799d aurel32
    t2 = tcg_const_i32(start);
2926 dfbc799d aurel32
    gen_helper_lsw(t0, t1, t2);
2927 dfbc799d aurel32
    tcg_temp_free(t0);
2928 dfbc799d aurel32
    tcg_temp_free_i32(t1);
2929 dfbc799d aurel32
    tcg_temp_free_i32(t2);
2930 79aceca5 bellard
}
2931 79aceca5 bellard
2932 79aceca5 bellard
/* lswx */
2933 99e300ef Blue Swirl
static void gen_lswx(DisasContext *ctx)
2934 79aceca5 bellard
{
2935 76db3ba4 aurel32
    TCGv t0;
2936 76db3ba4 aurel32
    TCGv_i32 t1, t2, t3;
2937 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_INT);
2938 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
2939 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
2940 76db3ba4 aurel32
    t0 = tcg_temp_new();
2941 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
2942 76db3ba4 aurel32
    t1 = tcg_const_i32(rD(ctx->opcode));
2943 76db3ba4 aurel32
    t2 = tcg_const_i32(rA(ctx->opcode));
2944 76db3ba4 aurel32
    t3 = tcg_const_i32(rB(ctx->opcode));
2945 dfbc799d aurel32
    gen_helper_lswx(t0, t1, t2, t3);
2946 dfbc799d aurel32
    tcg_temp_free(t0);
2947 dfbc799d aurel32
    tcg_temp_free_i32(t1);
2948 dfbc799d aurel32
    tcg_temp_free_i32(t2);
2949 dfbc799d aurel32
    tcg_temp_free_i32(t3);
2950 79aceca5 bellard
}
2951 79aceca5 bellard
2952 79aceca5 bellard
/* stswi */
2953 99e300ef Blue Swirl
static void gen_stswi(DisasContext *ctx)
2954 79aceca5 bellard
{
2955 76db3ba4 aurel32
    TCGv t0;
2956 76db3ba4 aurel32
    TCGv_i32 t1, t2;
2957 4b3686fa bellard
    int nb = NB(ctx->opcode);
2958 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_INT);
2959 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
2960 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
2961 76db3ba4 aurel32
    t0 = tcg_temp_new();
2962 76db3ba4 aurel32
    gen_addr_register(ctx, t0);
2963 4b3686fa bellard
    if (nb == 0)
2964 4b3686fa bellard
        nb = 32;
2965 dfbc799d aurel32
    t1 = tcg_const_i32(nb);
2966 76db3ba4 aurel32
    t2 = tcg_const_i32(rS(ctx->opcode));
2967 dfbc799d aurel32
    gen_helper_stsw(t0, t1, t2);
2968 dfbc799d aurel32
    tcg_temp_free(t0);
2969 dfbc799d aurel32
    tcg_temp_free_i32(t1);
2970 dfbc799d aurel32
    tcg_temp_free_i32(t2);
2971 79aceca5 bellard
}
2972 79aceca5 bellard
2973 79aceca5 bellard
/* stswx */
2974 99e300ef Blue Swirl
static void gen_stswx(DisasContext *ctx)
2975 79aceca5 bellard
{
2976 76db3ba4 aurel32
    TCGv t0;
2977 76db3ba4 aurel32
    TCGv_i32 t1, t2;
2978 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_INT);
2979 8dd4983c bellard
    /* NIP cannot be restored if the memory exception comes from an helper */
2980 5fafdf24 ths
    gen_update_nip(ctx, ctx->nip - 4);
2981 76db3ba4 aurel32
    t0 = tcg_temp_new();
2982 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
2983 76db3ba4 aurel32
    t1 = tcg_temp_new_i32();
2984 dfbc799d aurel32
    tcg_gen_trunc_tl_i32(t1, cpu_xer);
2985 dfbc799d aurel32
    tcg_gen_andi_i32(t1, t1, 0x7F);
2986 76db3ba4 aurel32
    t2 = tcg_const_i32(rS(ctx->opcode));
2987 dfbc799d aurel32
    gen_helper_stsw(t0, t1, t2);
2988 dfbc799d aurel32
    tcg_temp_free(t0);
2989 dfbc799d aurel32
    tcg_temp_free_i32(t1);
2990 dfbc799d aurel32
    tcg_temp_free_i32(t2);
2991 79aceca5 bellard
}
2992 79aceca5 bellard
2993 79aceca5 bellard
/***                        Memory synchronisation                         ***/
2994 79aceca5 bellard
/* eieio */
2995 99e300ef Blue Swirl
static void gen_eieio(DisasContext *ctx)
2996 79aceca5 bellard
{
2997 79aceca5 bellard
}
2998 79aceca5 bellard
2999 79aceca5 bellard
/* isync */
3000 99e300ef Blue Swirl
static void gen_isync(DisasContext *ctx)
3001 79aceca5 bellard
{
3002 e06fcd75 aurel32
    gen_stop_exception(ctx);
3003 79aceca5 bellard
}
3004 79aceca5 bellard
3005 111bfab3 bellard
/* lwarx */
3006 99e300ef Blue Swirl
static void gen_lwarx(DisasContext *ctx)
3007 79aceca5 bellard
{
3008 76db3ba4 aurel32
    TCGv t0;
3009 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_RES);
3010 76db3ba4 aurel32
    t0 = tcg_temp_local_new();
3011 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
3012 cf360a32 aurel32
    gen_check_align(ctx, t0, 0x03);
3013 76db3ba4 aurel32
    gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], t0);
3014 cf360a32 aurel32
    tcg_gen_mov_tl(cpu_reserve, t0);
3015 cf360a32 aurel32
    tcg_temp_free(t0);
3016 79aceca5 bellard
}
3017 79aceca5 bellard
3018 79aceca5 bellard
/* stwcx. */
3019 e8eaa2c0 Blue Swirl
static void gen_stwcx_(DisasContext *ctx)
3020 79aceca5 bellard
{
3021 76db3ba4 aurel32
    int l1;
3022 76db3ba4 aurel32
    TCGv t0;
3023 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_RES);
3024 76db3ba4 aurel32
    t0 = tcg_temp_local_new();
3025 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
3026 cf360a32 aurel32
    gen_check_align(ctx, t0, 0x03);
3027 cf360a32 aurel32
    tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
3028 cf360a32 aurel32
    tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
3029 cf360a32 aurel32
    tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
3030 76db3ba4 aurel32
    l1 = gen_new_label();
3031 cf360a32 aurel32
    tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
3032 cf360a32 aurel32
    tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
3033 76db3ba4 aurel32
    gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], t0);
3034 cf360a32 aurel32
    gen_set_label(l1);
3035 cf360a32 aurel32
    tcg_gen_movi_tl(cpu_reserve, -1);
3036 cf360a32 aurel32
    tcg_temp_free(t0);
3037 79aceca5 bellard
}
3038 79aceca5 bellard
3039 426613db j_mayer
#if defined(TARGET_PPC64)
3040 426613db j_mayer
/* ldarx */
3041 99e300ef Blue Swirl
static void gen_ldarx(DisasContext *ctx)
3042 426613db j_mayer
{
3043 76db3ba4 aurel32
    TCGv t0;
3044 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_RES);
3045 76db3ba4 aurel32
    t0 = tcg_temp_local_new();
3046 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
3047 cf360a32 aurel32
    gen_check_align(ctx, t0, 0x07);
3048 76db3ba4 aurel32
    gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], t0);
3049 cf360a32 aurel32
    tcg_gen_mov_tl(cpu_reserve, t0);
3050 cf360a32 aurel32
    tcg_temp_free(t0);
3051 426613db j_mayer
}
3052 426613db j_mayer
3053 426613db j_mayer
/* stdcx. */
3054 e8eaa2c0 Blue Swirl
static void gen_stdcx_(DisasContext *ctx)
3055 426613db j_mayer
{
3056 76db3ba4 aurel32
    int l1;
3057 76db3ba4 aurel32
    TCGv t0;
3058 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_RES);
3059 76db3ba4 aurel32
    t0 = tcg_temp_local_new();
3060 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
3061 cf360a32 aurel32
    gen_check_align(ctx, t0, 0x07);
3062 cf360a32 aurel32
    tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
3063 cf360a32 aurel32
    tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
3064 cf360a32 aurel32
    tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
3065 76db3ba4 aurel32
    l1 = gen_new_label();
3066 cf360a32 aurel32
    tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
3067 cf360a32 aurel32
    tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
3068 76db3ba4 aurel32
    gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], t0);
3069 cf360a32 aurel32
    gen_set_label(l1);
3070 cf360a32 aurel32
    tcg_gen_movi_tl(cpu_reserve, -1);
3071 cf360a32 aurel32
    tcg_temp_free(t0);
3072 426613db j_mayer
}
3073 426613db j_mayer
#endif /* defined(TARGET_PPC64) */
3074 426613db j_mayer
3075 79aceca5 bellard
/* sync */
3076 99e300ef Blue Swirl
static void gen_sync(DisasContext *ctx)
3077 79aceca5 bellard
{
3078 79aceca5 bellard
}
3079 79aceca5 bellard
3080 0db1b20e j_mayer
/* wait */
3081 99e300ef Blue Swirl
static void gen_wait(DisasContext *ctx)
3082 0db1b20e j_mayer
{
3083 931ff272 aurel32
    TCGv_i32 t0 = tcg_temp_new_i32();
3084 931ff272 aurel32
    tcg_gen_st_i32(t0, cpu_env, offsetof(CPUState, halted));
3085 931ff272 aurel32
    tcg_temp_free_i32(t0);
3086 0db1b20e j_mayer
    /* Stop translation, as the CPU is supposed to sleep from now */
3087 e06fcd75 aurel32
    gen_exception_err(ctx, EXCP_HLT, 1);
3088 0db1b20e j_mayer
}
3089 0db1b20e j_mayer
3090 79aceca5 bellard
/***                         Floating-point load                           ***/
3091 a0d7d5a7 aurel32
#define GEN_LDF(name, ldop, opc, type)                                        \
3092 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                       \
3093 79aceca5 bellard
{                                                                             \
3094 a0d7d5a7 aurel32
    TCGv EA;                                                                  \
3095 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3096 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3097 4ecc3190 bellard
        return;                                                               \
3098 4ecc3190 bellard
    }                                                                         \
3099 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3100 a0d7d5a7 aurel32
    EA = tcg_temp_new();                                                      \
3101 76db3ba4 aurel32
    gen_addr_imm_index(ctx, EA, 0);                                           \
3102 76db3ba4 aurel32
    gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3103 a0d7d5a7 aurel32
    tcg_temp_free(EA);                                                        \
3104 79aceca5 bellard
}
3105 79aceca5 bellard
3106 a0d7d5a7 aurel32
#define GEN_LDUF(name, ldop, opc, type)                                       \
3107 99e300ef Blue Swirl
static void glue(gen_, name##u)(DisasContext *ctx)                                    \
3108 79aceca5 bellard
{                                                                             \
3109 a0d7d5a7 aurel32
    TCGv EA;                                                                  \
3110 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3111 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3112 4ecc3190 bellard
        return;                                                               \
3113 4ecc3190 bellard
    }                                                                         \
3114 76a66253 j_mayer
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3115 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3116 9fddaa0c bellard
        return;                                                               \
3117 9a64fbe4 bellard
    }                                                                         \
3118 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3119 a0d7d5a7 aurel32
    EA = tcg_temp_new();                                                      \
3120 76db3ba4 aurel32
    gen_addr_imm_index(ctx, EA, 0);                                           \
3121 76db3ba4 aurel32
    gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3122 a0d7d5a7 aurel32
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3123 a0d7d5a7 aurel32
    tcg_temp_free(EA);                                                        \
3124 79aceca5 bellard
}
3125 79aceca5 bellard
3126 a0d7d5a7 aurel32
#define GEN_LDUXF(name, ldop, opc, type)                                      \
3127 99e300ef Blue Swirl
static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
3128 79aceca5 bellard
{                                                                             \
3129 a0d7d5a7 aurel32
    TCGv EA;                                                                  \
3130 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3131 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3132 4ecc3190 bellard
        return;                                                               \
3133 4ecc3190 bellard
    }                                                                         \
3134 76a66253 j_mayer
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3135 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3136 9fddaa0c bellard
        return;                                                               \
3137 9a64fbe4 bellard
    }                                                                         \
3138 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3139 a0d7d5a7 aurel32
    EA = tcg_temp_new();                                                      \
3140 76db3ba4 aurel32
    gen_addr_reg_index(ctx, EA);                                              \
3141 76db3ba4 aurel32
    gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3142 a0d7d5a7 aurel32
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3143 a0d7d5a7 aurel32
    tcg_temp_free(EA);                                                        \
3144 79aceca5 bellard
}
3145 79aceca5 bellard
3146 a0d7d5a7 aurel32
#define GEN_LDXF(name, ldop, opc2, opc3, type)                                \
3147 99e300ef Blue Swirl
static void glue(gen_, name##x)(DisasContext *ctx)                                    \
3148 79aceca5 bellard
{                                                                             \
3149 a0d7d5a7 aurel32
    TCGv EA;                                                                  \
3150 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3151 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3152 4ecc3190 bellard
        return;                                                               \
3153 4ecc3190 bellard
    }                                                                         \
3154 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3155 a0d7d5a7 aurel32
    EA = tcg_temp_new();                                                      \
3156 76db3ba4 aurel32
    gen_addr_reg_index(ctx, EA);                                              \
3157 76db3ba4 aurel32
    gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
3158 a0d7d5a7 aurel32
    tcg_temp_free(EA);                                                        \
3159 79aceca5 bellard
}
3160 79aceca5 bellard
3161 a0d7d5a7 aurel32
#define GEN_LDFS(name, ldop, op, type)                                        \
3162 a0d7d5a7 aurel32
GEN_LDF(name, ldop, op | 0x20, type);                                         \
3163 a0d7d5a7 aurel32
GEN_LDUF(name, ldop, op | 0x21, type);                                        \
3164 a0d7d5a7 aurel32
GEN_LDUXF(name, ldop, op | 0x01, type);                                       \
3165 a0d7d5a7 aurel32
GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
3166 a0d7d5a7 aurel32
3167 76db3ba4 aurel32
static always_inline void gen_qemu_ld32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3168 a0d7d5a7 aurel32
{
3169 a0d7d5a7 aurel32
    TCGv t0 = tcg_temp_new();
3170 a0d7d5a7 aurel32
    TCGv_i32 t1 = tcg_temp_new_i32();
3171 76db3ba4 aurel32
    gen_qemu_ld32u(ctx, t0, arg2);
3172 a0d7d5a7 aurel32
    tcg_gen_trunc_tl_i32(t1, t0);
3173 a0d7d5a7 aurel32
    tcg_temp_free(t0);
3174 a0d7d5a7 aurel32
    gen_helper_float32_to_float64(arg1, t1);
3175 a0d7d5a7 aurel32
    tcg_temp_free_i32(t1);
3176 a0d7d5a7 aurel32
}
3177 79aceca5 bellard
3178 a0d7d5a7 aurel32
 /* lfd lfdu lfdux lfdx */
3179 a0d7d5a7 aurel32
GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT);
3180 a0d7d5a7 aurel32
 /* lfs lfsu lfsux lfsx */
3181 a0d7d5a7 aurel32
GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT);
3182 79aceca5 bellard
3183 79aceca5 bellard
/***                         Floating-point store                          ***/
3184 a0d7d5a7 aurel32
#define GEN_STF(name, stop, opc, type)                                        \
3185 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                       \
3186 79aceca5 bellard
{                                                                             \
3187 a0d7d5a7 aurel32
    TCGv EA;                                                                  \
3188 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3189 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3190 4ecc3190 bellard
        return;                                                               \
3191 4ecc3190 bellard
    }                                                                         \
3192 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3193 a0d7d5a7 aurel32
    EA = tcg_temp_new();                                                      \
3194 76db3ba4 aurel32
    gen_addr_imm_index(ctx, EA, 0);                                           \
3195 76db3ba4 aurel32
    gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3196 a0d7d5a7 aurel32
    tcg_temp_free(EA);                                                        \
3197 79aceca5 bellard
}
3198 79aceca5 bellard
3199 a0d7d5a7 aurel32
#define GEN_STUF(name, stop, opc, type)                                       \
3200 99e300ef Blue Swirl
static void glue(gen_, name##u)(DisasContext *ctx)                                    \
3201 79aceca5 bellard
{                                                                             \
3202 a0d7d5a7 aurel32
    TCGv EA;                                                                  \
3203 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3204 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3205 4ecc3190 bellard
        return;                                                               \
3206 4ecc3190 bellard
    }                                                                         \
3207 76a66253 j_mayer
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3208 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3209 9fddaa0c bellard
        return;                                                               \
3210 9a64fbe4 bellard
    }                                                                         \
3211 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3212 a0d7d5a7 aurel32
    EA = tcg_temp_new();                                                      \
3213 76db3ba4 aurel32
    gen_addr_imm_index(ctx, EA, 0);                                           \
3214 76db3ba4 aurel32
    gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3215 a0d7d5a7 aurel32
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3216 a0d7d5a7 aurel32
    tcg_temp_free(EA);                                                        \
3217 79aceca5 bellard
}
3218 79aceca5 bellard
3219 a0d7d5a7 aurel32
#define GEN_STUXF(name, stop, opc, type)                                      \
3220 99e300ef Blue Swirl
static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
3221 79aceca5 bellard
{                                                                             \
3222 a0d7d5a7 aurel32
    TCGv EA;                                                                  \
3223 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3224 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3225 4ecc3190 bellard
        return;                                                               \
3226 4ecc3190 bellard
    }                                                                         \
3227 76a66253 j_mayer
    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
3228 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
3229 9fddaa0c bellard
        return;                                                               \
3230 9a64fbe4 bellard
    }                                                                         \
3231 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3232 a0d7d5a7 aurel32
    EA = tcg_temp_new();                                                      \
3233 76db3ba4 aurel32
    gen_addr_reg_index(ctx, EA);                                              \
3234 76db3ba4 aurel32
    gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3235 a0d7d5a7 aurel32
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
3236 a0d7d5a7 aurel32
    tcg_temp_free(EA);                                                        \
3237 79aceca5 bellard
}
3238 79aceca5 bellard
3239 a0d7d5a7 aurel32
#define GEN_STXF(name, stop, opc2, opc3, type)                                \
3240 99e300ef Blue Swirl
static void glue(gen_, name##x)(DisasContext *ctx)                                    \
3241 79aceca5 bellard
{                                                                             \
3242 a0d7d5a7 aurel32
    TCGv EA;                                                                  \
3243 76a66253 j_mayer
    if (unlikely(!ctx->fpu_enabled)) {                                        \
3244 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
3245 4ecc3190 bellard
        return;                                                               \
3246 4ecc3190 bellard
    }                                                                         \
3247 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
3248 a0d7d5a7 aurel32
    EA = tcg_temp_new();                                                      \
3249 76db3ba4 aurel32
    gen_addr_reg_index(ctx, EA);                                              \
3250 76db3ba4 aurel32
    gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
3251 a0d7d5a7 aurel32
    tcg_temp_free(EA);                                                        \
3252 79aceca5 bellard
}
3253 79aceca5 bellard
3254 a0d7d5a7 aurel32
#define GEN_STFS(name, stop, op, type)                                        \
3255 a0d7d5a7 aurel32
GEN_STF(name, stop, op | 0x20, type);                                         \
3256 a0d7d5a7 aurel32
GEN_STUF(name, stop, op | 0x21, type);                                        \
3257 a0d7d5a7 aurel32
GEN_STUXF(name, stop, op | 0x01, type);                                       \
3258 a0d7d5a7 aurel32
GEN_STXF(name, stop, 0x17, op | 0x00, type)
3259 a0d7d5a7 aurel32
3260 76db3ba4 aurel32
static always_inline void gen_qemu_st32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3261 a0d7d5a7 aurel32
{
3262 a0d7d5a7 aurel32
    TCGv_i32 t0 = tcg_temp_new_i32();
3263 a0d7d5a7 aurel32
    TCGv t1 = tcg_temp_new();
3264 a0d7d5a7 aurel32
    gen_helper_float64_to_float32(t0, arg1);
3265 a0d7d5a7 aurel32
    tcg_gen_extu_i32_tl(t1, t0);
3266 a0d7d5a7 aurel32
    tcg_temp_free_i32(t0);
3267 76db3ba4 aurel32
    gen_qemu_st32(ctx, t1, arg2);
3268 a0d7d5a7 aurel32
    tcg_temp_free(t1);
3269 a0d7d5a7 aurel32
}
3270 79aceca5 bellard
3271 79aceca5 bellard
/* stfd stfdu stfdux stfdx */
3272 a0d7d5a7 aurel32
GEN_STFS(stfd, st64, 0x16, PPC_FLOAT);
3273 79aceca5 bellard
/* stfs stfsu stfsux stfsx */
3274 a0d7d5a7 aurel32
GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT);
3275 79aceca5 bellard
3276 79aceca5 bellard
/* Optional: */
3277 76db3ba4 aurel32
static always_inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
3278 a0d7d5a7 aurel32
{
3279 a0d7d5a7 aurel32
    TCGv t0 = tcg_temp_new();
3280 a0d7d5a7 aurel32
    tcg_gen_trunc_i64_tl(t0, arg1),
3281 76db3ba4 aurel32
    gen_qemu_st32(ctx, t0, arg2);
3282 a0d7d5a7 aurel32
    tcg_temp_free(t0);
3283 a0d7d5a7 aurel32
}
3284 79aceca5 bellard
/* stfiwx */
3285 a0d7d5a7 aurel32
GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
3286 79aceca5 bellard
3287 79aceca5 bellard
/***                                Branch                                 ***/
3288 b068d6a7 j_mayer
static always_inline void gen_goto_tb (DisasContext *ctx, int n,
3289 b068d6a7 j_mayer
                                       target_ulong dest)
3290 c1942362 bellard
{
3291 c1942362 bellard
    TranslationBlock *tb;
3292 c1942362 bellard
    tb = ctx->tb;
3293 a2ffb812 aurel32
#if defined(TARGET_PPC64)
3294 a2ffb812 aurel32
    if (!ctx->sf_mode)
3295 a2ffb812 aurel32
        dest = (uint32_t) dest;
3296 a2ffb812 aurel32
#endif
3297 57fec1fe bellard
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3298 8cbcb4fa aurel32
        likely(!ctx->singlestep_enabled)) {
3299 57fec1fe bellard
        tcg_gen_goto_tb(n);
3300 a2ffb812 aurel32
        tcg_gen_movi_tl(cpu_nip, dest & ~3);
3301 57fec1fe bellard
        tcg_gen_exit_tb((long)tb + n);
3302 c1942362 bellard
    } else {
3303 a2ffb812 aurel32
        tcg_gen_movi_tl(cpu_nip, dest & ~3);
3304 8cbcb4fa aurel32
        if (unlikely(ctx->singlestep_enabled)) {
3305 8cbcb4fa aurel32
            if ((ctx->singlestep_enabled &
3306 bdc4e053 aurel32
                (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
3307 8cbcb4fa aurel32
                ctx->exception == POWERPC_EXCP_BRANCH) {
3308 8cbcb4fa aurel32
                target_ulong tmp = ctx->nip;
3309 8cbcb4fa aurel32
                ctx->nip = dest;
3310 e06fcd75 aurel32
                gen_exception(ctx, POWERPC_EXCP_TRACE);
3311 8cbcb4fa aurel32
                ctx->nip = tmp;
3312 8cbcb4fa aurel32
            }
3313 8cbcb4fa aurel32
            if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
3314 e06fcd75 aurel32
                gen_debug_exception(ctx);
3315 8cbcb4fa aurel32
            }
3316 8cbcb4fa aurel32
        }
3317 57fec1fe bellard
        tcg_gen_exit_tb(0);
3318 c1942362 bellard
    }
3319 c53be334 bellard
}
3320 c53be334 bellard
3321 b068d6a7 j_mayer
static always_inline void gen_setlr (DisasContext *ctx, target_ulong nip)
3322 e1833e1f j_mayer
{
3323 e1833e1f j_mayer
#if defined(TARGET_PPC64)
3324 a2ffb812 aurel32
    if (ctx->sf_mode == 0)
3325 a2ffb812 aurel32
        tcg_gen_movi_tl(cpu_lr, (uint32_t)nip);
3326 e1833e1f j_mayer
    else
3327 e1833e1f j_mayer
#endif
3328 a2ffb812 aurel32
        tcg_gen_movi_tl(cpu_lr, nip);
3329 e1833e1f j_mayer
}
3330 e1833e1f j_mayer
3331 79aceca5 bellard
/* b ba bl bla */
3332 99e300ef Blue Swirl
static void gen_b(DisasContext *ctx)
3333 79aceca5 bellard
{
3334 76a66253 j_mayer
    target_ulong li, target;
3335 38a64f9d bellard
3336 8cbcb4fa aurel32
    ctx->exception = POWERPC_EXCP_BRANCH;
3337 38a64f9d bellard
    /* sign extend LI */
3338 76a66253 j_mayer
#if defined(TARGET_PPC64)
3339 d9bce9d9 j_mayer
    if (ctx->sf_mode)
3340 d9bce9d9 j_mayer
        li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
3341 d9bce9d9 j_mayer
    else
3342 76a66253 j_mayer
#endif
3343 d9bce9d9 j_mayer
        li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
3344 76a66253 j_mayer
    if (likely(AA(ctx->opcode) == 0))
3345 046d6672 bellard
        target = ctx->nip + li - 4;
3346 79aceca5 bellard
    else
3347 9a64fbe4 bellard
        target = li;
3348 e1833e1f j_mayer
    if (LK(ctx->opcode))
3349 e1833e1f j_mayer
        gen_setlr(ctx, ctx->nip);
3350 c1942362 bellard
    gen_goto_tb(ctx, 0, target);
3351 79aceca5 bellard
}
3352 79aceca5 bellard
3353 e98a6e40 bellard
#define BCOND_IM  0
3354 e98a6e40 bellard
#define BCOND_LR  1
3355 e98a6e40 bellard
#define BCOND_CTR 2
3356 e98a6e40 bellard
3357 b068d6a7 j_mayer
static always_inline void gen_bcond (DisasContext *ctx, int type)
3358 d9bce9d9 j_mayer
{
3359 d9bce9d9 j_mayer
    uint32_t bo = BO(ctx->opcode);
3360 a2ffb812 aurel32
    int l1 = gen_new_label();
3361 a2ffb812 aurel32
    TCGv target;
3362 e98a6e40 bellard
3363 8cbcb4fa aurel32
    ctx->exception = POWERPC_EXCP_BRANCH;
3364 a2ffb812 aurel32
    if (type == BCOND_LR || type == BCOND_CTR) {
3365 a7812ae4 pbrook
        target = tcg_temp_local_new();
3366 a2ffb812 aurel32
        if (type == BCOND_CTR)
3367 a2ffb812 aurel32
            tcg_gen_mov_tl(target, cpu_ctr);
3368 a2ffb812 aurel32
        else
3369 a2ffb812 aurel32
            tcg_gen_mov_tl(target, cpu_lr);
3370 d2e9fd8f malc
    } else {
3371 d2e9fd8f malc
        TCGV_UNUSED(target);
3372 e98a6e40 bellard
    }
3373 e1833e1f j_mayer
    if (LK(ctx->opcode))
3374 e1833e1f j_mayer
        gen_setlr(ctx, ctx->nip);
3375 a2ffb812 aurel32
    l1 = gen_new_label();
3376 a2ffb812 aurel32
    if ((bo & 0x4) == 0) {
3377 a2ffb812 aurel32
        /* Decrement and test CTR */
3378 a7812ae4 pbrook
        TCGv temp = tcg_temp_new();
3379 a2ffb812 aurel32
        if (unlikely(type == BCOND_CTR)) {
3380 e06fcd75 aurel32
            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3381 a2ffb812 aurel32
            return;
3382 a2ffb812 aurel32
        }
3383 a2ffb812 aurel32
        tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);
3384 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
3385 a2ffb812 aurel32
        if (!ctx->sf_mode)
3386 a2ffb812 aurel32
            tcg_gen_ext32u_tl(temp, cpu_ctr);
3387 a2ffb812 aurel32
        else
3388 d9bce9d9 j_mayer
#endif
3389 a2ffb812 aurel32
            tcg_gen_mov_tl(temp, cpu_ctr);
3390 a2ffb812 aurel32
        if (bo & 0x2) {
3391 a2ffb812 aurel32
            tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);
3392 a2ffb812 aurel32
        } else {
3393 a2ffb812 aurel32
            tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
3394 e98a6e40 bellard
        }
3395 a7812ae4 pbrook
        tcg_temp_free(temp);
3396 a2ffb812 aurel32
    }
3397 a2ffb812 aurel32
    if ((bo & 0x10) == 0) {
3398 a2ffb812 aurel32
        /* Test CR */
3399 a2ffb812 aurel32
        uint32_t bi = BI(ctx->opcode);
3400 a2ffb812 aurel32
        uint32_t mask = 1 << (3 - (bi & 0x03));
3401 a7812ae4 pbrook
        TCGv_i32 temp = tcg_temp_new_i32();
3402 a2ffb812 aurel32
3403 d9bce9d9 j_mayer
        if (bo & 0x8) {
3404 a2ffb812 aurel32
            tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
3405 a2ffb812 aurel32
            tcg_gen_brcondi_i32(TCG_COND_EQ, temp, 0, l1);
3406 d9bce9d9 j_mayer
        } else {
3407 a2ffb812 aurel32
            tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
3408 a2ffb812 aurel32
            tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1);
3409 d9bce9d9 j_mayer
        }
3410 a7812ae4 pbrook
        tcg_temp_free_i32(temp);
3411 d9bce9d9 j_mayer
    }
3412 e98a6e40 bellard
    if (type == BCOND_IM) {
3413 a2ffb812 aurel32
        target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
3414 a2ffb812 aurel32
        if (likely(AA(ctx->opcode) == 0)) {
3415 a2ffb812 aurel32
            gen_goto_tb(ctx, 0, ctx->nip + li - 4);
3416 a2ffb812 aurel32
        } else {
3417 a2ffb812 aurel32
            gen_goto_tb(ctx, 0, li);
3418 a2ffb812 aurel32
        }
3419 c53be334 bellard
        gen_set_label(l1);
3420 c1942362 bellard
        gen_goto_tb(ctx, 1, ctx->nip);
3421 e98a6e40 bellard
    } else {
3422 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
3423 a2ffb812 aurel32
        if (!(ctx->sf_mode))
3424 a2ffb812 aurel32
            tcg_gen_andi_tl(cpu_nip, target, (uint32_t)~3);
3425 a2ffb812 aurel32
        else
3426 a2ffb812 aurel32
#endif
3427 a2ffb812 aurel32
            tcg_gen_andi_tl(cpu_nip, target, ~3);
3428 a2ffb812 aurel32
        tcg_gen_exit_tb(0);
3429 a2ffb812 aurel32
        gen_set_label(l1);
3430 a2ffb812 aurel32
#if defined(TARGET_PPC64)
3431 a2ffb812 aurel32
        if (!(ctx->sf_mode))
3432 a2ffb812 aurel32
            tcg_gen_movi_tl(cpu_nip, (uint32_t)ctx->nip);
3433 d9bce9d9 j_mayer
        else
3434 d9bce9d9 j_mayer
#endif
3435 a2ffb812 aurel32
            tcg_gen_movi_tl(cpu_nip, ctx->nip);
3436 57fec1fe bellard
        tcg_gen_exit_tb(0);
3437 08e46e54 j_mayer
    }
3438 e98a6e40 bellard
}
3439 e98a6e40 bellard
3440 99e300ef Blue Swirl
static void gen_bc(DisasContext *ctx)
3441 3b46e624 ths
{
3442 e98a6e40 bellard
    gen_bcond(ctx, BCOND_IM);
3443 e98a6e40 bellard
}
3444 e98a6e40 bellard
3445 99e300ef Blue Swirl
static void gen_bcctr(DisasContext *ctx)
3446 3b46e624 ths
{
3447 e98a6e40 bellard
    gen_bcond(ctx, BCOND_CTR);
3448 e98a6e40 bellard
}
3449 e98a6e40 bellard
3450 99e300ef Blue Swirl
static void gen_bclr(DisasContext *ctx)
3451 3b46e624 ths
{
3452 e98a6e40 bellard
    gen_bcond(ctx, BCOND_LR);
3453 e98a6e40 bellard
}
3454 79aceca5 bellard
3455 79aceca5 bellard
/***                      Condition register logical                       ***/
3456 e1571908 aurel32
#define GEN_CRLOGIC(name, tcg_op, opc)                                        \
3457 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                       \
3458 79aceca5 bellard
{                                                                             \
3459 fc0d441e j_mayer
    uint8_t bitmask;                                                          \
3460 fc0d441e j_mayer
    int sh;                                                                   \
3461 a7812ae4 pbrook
    TCGv_i32 t0, t1;                                                          \
3462 fc0d441e j_mayer
    sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
3463 a7812ae4 pbrook
    t0 = tcg_temp_new_i32();                                                  \
3464 fc0d441e j_mayer
    if (sh > 0)                                                               \
3465 fea0c503 aurel32
        tcg_gen_shri_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], sh);            \
3466 fc0d441e j_mayer
    else if (sh < 0)                                                          \
3467 fea0c503 aurel32
        tcg_gen_shli_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], -sh);           \
3468 e1571908 aurel32
    else                                                                      \
3469 fea0c503 aurel32
        tcg_gen_mov_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2]);                 \
3470 a7812ae4 pbrook
    t1 = tcg_temp_new_i32();                                                  \
3471 fc0d441e j_mayer
    sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
3472 fc0d441e j_mayer
    if (sh > 0)                                                               \
3473 fea0c503 aurel32
        tcg_gen_shri_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], sh);            \
3474 fc0d441e j_mayer
    else if (sh < 0)                                                          \
3475 fea0c503 aurel32
        tcg_gen_shli_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], -sh);           \
3476 e1571908 aurel32
    else                                                                      \
3477 fea0c503 aurel32
        tcg_gen_mov_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2]);                 \
3478 fea0c503 aurel32
    tcg_op(t0, t0, t1);                                                       \
3479 fc0d441e j_mayer
    bitmask = 1 << (3 - (crbD(ctx->opcode) & 0x03));                          \
3480 fea0c503 aurel32
    tcg_gen_andi_i32(t0, t0, bitmask);                                        \
3481 fea0c503 aurel32
    tcg_gen_andi_i32(t1, cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask);          \
3482 fea0c503 aurel32
    tcg_gen_or_i32(cpu_crf[crbD(ctx->opcode) >> 2], t0, t1);                  \
3483 a7812ae4 pbrook
    tcg_temp_free_i32(t0);                                                    \
3484 a7812ae4 pbrook
    tcg_temp_free_i32(t1);                                                    \
3485 79aceca5 bellard
}
3486 79aceca5 bellard
3487 79aceca5 bellard
/* crand */
3488 e1571908 aurel32
GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08);
3489 79aceca5 bellard
/* crandc */
3490 e1571908 aurel32
GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04);
3491 79aceca5 bellard
/* creqv */
3492 e1571908 aurel32
GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09);
3493 79aceca5 bellard
/* crnand */
3494 e1571908 aurel32
GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07);
3495 79aceca5 bellard
/* crnor */
3496 e1571908 aurel32
GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01);
3497 79aceca5 bellard
/* cror */
3498 e1571908 aurel32
GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E);
3499 79aceca5 bellard
/* crorc */
3500 e1571908 aurel32
GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D);
3501 79aceca5 bellard
/* crxor */
3502 e1571908 aurel32
GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06);
3503 99e300ef Blue Swirl
3504 54623277 Blue Swirl
/* mcrf */
3505 99e300ef Blue Swirl
static void gen_mcrf(DisasContext *ctx)
3506 79aceca5 bellard
{
3507 47e4661c aurel32
    tcg_gen_mov_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfS(ctx->opcode)]);
3508 79aceca5 bellard
}
3509 79aceca5 bellard
3510 79aceca5 bellard
/***                           System linkage                              ***/
3511 99e300ef Blue Swirl
3512 54623277 Blue Swirl
/* rfi (mem_idx only) */
3513 99e300ef Blue Swirl
static void gen_rfi(DisasContext *ctx)
3514 79aceca5 bellard
{
3515 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
3516 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3517 9a64fbe4 bellard
#else
3518 9a64fbe4 bellard
    /* Restore CPU state */
3519 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
3520 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3521 9fddaa0c bellard
        return;
3522 9a64fbe4 bellard
    }
3523 d72a19f7 aurel32
    gen_helper_rfi();
3524 e06fcd75 aurel32
    gen_sync_exception(ctx);
3525 9a64fbe4 bellard
#endif
3526 79aceca5 bellard
}
3527 79aceca5 bellard
3528 426613db j_mayer
#if defined(TARGET_PPC64)
3529 99e300ef Blue Swirl
static void gen_rfid(DisasContext *ctx)
3530 426613db j_mayer
{
3531 426613db j_mayer
#if defined(CONFIG_USER_ONLY)
3532 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3533 426613db j_mayer
#else
3534 426613db j_mayer
    /* Restore CPU state */
3535 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
3536 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3537 426613db j_mayer
        return;
3538 426613db j_mayer
    }
3539 d72a19f7 aurel32
    gen_helper_rfid();
3540 e06fcd75 aurel32
    gen_sync_exception(ctx);
3541 426613db j_mayer
#endif
3542 426613db j_mayer
}
3543 426613db j_mayer
3544 99e300ef Blue Swirl
static void gen_hrfid(DisasContext *ctx)
3545 be147d08 j_mayer
{
3546 be147d08 j_mayer
#if defined(CONFIG_USER_ONLY)
3547 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3548 be147d08 j_mayer
#else
3549 be147d08 j_mayer
    /* Restore CPU state */
3550 76db3ba4 aurel32
    if (unlikely(ctx->mem_idx <= 1)) {
3551 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3552 be147d08 j_mayer
        return;
3553 be147d08 j_mayer
    }
3554 d72a19f7 aurel32
    gen_helper_hrfid();
3555 e06fcd75 aurel32
    gen_sync_exception(ctx);
3556 be147d08 j_mayer
#endif
3557 be147d08 j_mayer
}
3558 be147d08 j_mayer
#endif
3559 be147d08 j_mayer
3560 79aceca5 bellard
/* sc */
3561 417bf010 j_mayer
#if defined(CONFIG_USER_ONLY)
3562 417bf010 j_mayer
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
3563 417bf010 j_mayer
#else
3564 417bf010 j_mayer
#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
3565 417bf010 j_mayer
#endif
3566 99e300ef Blue Swirl
static void gen_sc(DisasContext *ctx)
3567 79aceca5 bellard
{
3568 e1833e1f j_mayer
    uint32_t lev;
3569 e1833e1f j_mayer
3570 e1833e1f j_mayer
    lev = (ctx->opcode >> 5) & 0x7F;
3571 e06fcd75 aurel32
    gen_exception_err(ctx, POWERPC_SYSCALL, lev);
3572 79aceca5 bellard
}
3573 79aceca5 bellard
3574 79aceca5 bellard
/***                                Trap                                   ***/
3575 99e300ef Blue Swirl
3576 54623277 Blue Swirl
/* tw */
3577 99e300ef Blue Swirl
static void gen_tw(DisasContext *ctx)
3578 79aceca5 bellard
{
3579 cab3bee2 aurel32
    TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
3580 a0ae05aa ths
    /* Update the nip since this might generate a trap exception */
3581 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip);
3582 cab3bee2 aurel32
    gen_helper_tw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0);
3583 cab3bee2 aurel32
    tcg_temp_free_i32(t0);
3584 79aceca5 bellard
}
3585 79aceca5 bellard
3586 79aceca5 bellard
/* twi */
3587 99e300ef Blue Swirl
static void gen_twi(DisasContext *ctx)
3588 79aceca5 bellard
{
3589 cab3bee2 aurel32
    TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
3590 cab3bee2 aurel32
    TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
3591 d9bce9d9 j_mayer
    /* Update the nip since this might generate a trap exception */
3592 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip);
3593 cab3bee2 aurel32
    gen_helper_tw(cpu_gpr[rA(ctx->opcode)], t0, t1);
3594 cab3bee2 aurel32
    tcg_temp_free(t0);
3595 cab3bee2 aurel32
    tcg_temp_free_i32(t1);
3596 79aceca5 bellard
}
3597 79aceca5 bellard
3598 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
3599 d9bce9d9 j_mayer
/* td */
3600 99e300ef Blue Swirl
static void gen_td(DisasContext *ctx)
3601 d9bce9d9 j_mayer
{
3602 cab3bee2 aurel32
    TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
3603 d9bce9d9 j_mayer
    /* Update the nip since this might generate a trap exception */
3604 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip);
3605 cab3bee2 aurel32
    gen_helper_td(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0);
3606 cab3bee2 aurel32
    tcg_temp_free_i32(t0);
3607 d9bce9d9 j_mayer
}
3608 d9bce9d9 j_mayer
3609 d9bce9d9 j_mayer
/* tdi */
3610 99e300ef Blue Swirl
static void gen_tdi(DisasContext *ctx)
3611 d9bce9d9 j_mayer
{
3612 cab3bee2 aurel32
    TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
3613 cab3bee2 aurel32
    TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
3614 d9bce9d9 j_mayer
    /* Update the nip since this might generate a trap exception */
3615 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip);
3616 cab3bee2 aurel32
    gen_helper_td(cpu_gpr[rA(ctx->opcode)], t0, t1);
3617 cab3bee2 aurel32
    tcg_temp_free(t0);
3618 cab3bee2 aurel32
    tcg_temp_free_i32(t1);
3619 d9bce9d9 j_mayer
}
3620 d9bce9d9 j_mayer
#endif
3621 d9bce9d9 j_mayer
3622 79aceca5 bellard
/***                          Processor control                            ***/
3623 99e300ef Blue Swirl
3624 54623277 Blue Swirl
/* mcrxr */
3625 99e300ef Blue Swirl
static void gen_mcrxr(DisasContext *ctx)
3626 79aceca5 bellard
{
3627 3d7b417e aurel32
    tcg_gen_trunc_tl_i32(cpu_crf[crfD(ctx->opcode)], cpu_xer);
3628 3d7b417e aurel32
    tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], XER_CA);
3629 269f3e95 aurel32
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_SO | 1 << XER_OV | 1 << XER_CA));
3630 79aceca5 bellard
}
3631 79aceca5 bellard
3632 0cfe11ea aurel32
/* mfcr mfocrf */
3633 99e300ef Blue Swirl
static void gen_mfcr(DisasContext *ctx)
3634 79aceca5 bellard
{
3635 76a66253 j_mayer
    uint32_t crm, crn;
3636 3b46e624 ths
3637 76a66253 j_mayer
    if (likely(ctx->opcode & 0x00100000)) {
3638 76a66253 j_mayer
        crm = CRM(ctx->opcode);
3639 8dd640e4 malc
        if (likely(crm && ((crm & (crm - 1)) == 0))) {
3640 0cfe11ea aurel32
            crn = ctz32 (crm);
3641 e1571908 aurel32
            tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], cpu_crf[7 - crn]);
3642 0497d2f4 aurel32
            tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)],
3643 0497d2f4 aurel32
                            cpu_gpr[rD(ctx->opcode)], crn * 4);
3644 76a66253 j_mayer
        }
3645 d9bce9d9 j_mayer
    } else {
3646 651721b2 aurel32
        TCGv_i32 t0 = tcg_temp_new_i32();
3647 651721b2 aurel32
        tcg_gen_mov_i32(t0, cpu_crf[0]);
3648 651721b2 aurel32
        tcg_gen_shli_i32(t0, t0, 4);
3649 651721b2 aurel32
        tcg_gen_or_i32(t0, t0, cpu_crf[1]);
3650 651721b2 aurel32
        tcg_gen_shli_i32(t0, t0, 4);
3651 651721b2 aurel32
        tcg_gen_or_i32(t0, t0, cpu_crf[2]);
3652 651721b2 aurel32
        tcg_gen_shli_i32(t0, t0, 4);
3653 651721b2 aurel32
        tcg_gen_or_i32(t0, t0, cpu_crf[3]);
3654 651721b2 aurel32
        tcg_gen_shli_i32(t0, t0, 4);
3655 651721b2 aurel32
        tcg_gen_or_i32(t0, t0, cpu_crf[4]);
3656 651721b2 aurel32
        tcg_gen_shli_i32(t0, t0, 4);
3657 651721b2 aurel32
        tcg_gen_or_i32(t0, t0, cpu_crf[5]);
3658 651721b2 aurel32
        tcg_gen_shli_i32(t0, t0, 4);
3659 651721b2 aurel32
        tcg_gen_or_i32(t0, t0, cpu_crf[6]);
3660 651721b2 aurel32
        tcg_gen_shli_i32(t0, t0, 4);
3661 651721b2 aurel32
        tcg_gen_or_i32(t0, t0, cpu_crf[7]);
3662 651721b2 aurel32
        tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);
3663 651721b2 aurel32
        tcg_temp_free_i32(t0);
3664 d9bce9d9 j_mayer
    }
3665 79aceca5 bellard
}
3666 79aceca5 bellard
3667 79aceca5 bellard
/* mfmsr */
3668 99e300ef Blue Swirl
static void gen_mfmsr(DisasContext *ctx)
3669 79aceca5 bellard
{
3670 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
3671 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3672 9a64fbe4 bellard
#else
3673 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
3674 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3675 9fddaa0c bellard
        return;
3676 9a64fbe4 bellard
    }
3677 6527f6ea aurel32
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
3678 9a64fbe4 bellard
#endif
3679 79aceca5 bellard
}
3680 79aceca5 bellard
3681 a11b8151 j_mayer
#if 1
3682 6f2d8978 j_mayer
#define SPR_NOACCESS ((void *)(-1UL))
3683 3fc6c082 bellard
#else
3684 3fc6c082 bellard
static void spr_noaccess (void *opaque, int sprn)
3685 3fc6c082 bellard
{
3686 3fc6c082 bellard
    sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3687 3fc6c082 bellard
    printf("ERROR: try to access SPR %d !\n", sprn);
3688 3fc6c082 bellard
}
3689 3fc6c082 bellard
#define SPR_NOACCESS (&spr_noaccess)
3690 3fc6c082 bellard
#endif
3691 3fc6c082 bellard
3692 79aceca5 bellard
/* mfspr */
3693 b068d6a7 j_mayer
static always_inline void gen_op_mfspr (DisasContext *ctx)
3694 79aceca5 bellard
{
3695 45d827d2 aurel32
    void (*read_cb)(void *opaque, int gprn, int sprn);
3696 79aceca5 bellard
    uint32_t sprn = SPR(ctx->opcode);
3697 79aceca5 bellard
3698 3fc6c082 bellard
#if !defined(CONFIG_USER_ONLY)
3699 76db3ba4 aurel32
    if (ctx->mem_idx == 2)
3700 be147d08 j_mayer
        read_cb = ctx->spr_cb[sprn].hea_read;
3701 76db3ba4 aurel32
    else if (ctx->mem_idx)
3702 3fc6c082 bellard
        read_cb = ctx->spr_cb[sprn].oea_read;
3703 3fc6c082 bellard
    else
3704 9a64fbe4 bellard
#endif
3705 3fc6c082 bellard
        read_cb = ctx->spr_cb[sprn].uea_read;
3706 76a66253 j_mayer
    if (likely(read_cb != NULL)) {
3707 76a66253 j_mayer
        if (likely(read_cb != SPR_NOACCESS)) {
3708 45d827d2 aurel32
            (*read_cb)(ctx, rD(ctx->opcode), sprn);
3709 3fc6c082 bellard
        } else {
3710 3fc6c082 bellard
            /* Privilege exception */
3711 9fceefa7 j_mayer
            /* This is a hack to avoid warnings when running Linux:
3712 9fceefa7 j_mayer
             * this OS breaks the PowerPC virtualisation model,
3713 9fceefa7 j_mayer
             * allowing userland application to read the PVR
3714 9fceefa7 j_mayer
             */
3715 9fceefa7 j_mayer
            if (sprn != SPR_PVR) {
3716 93fcfe39 aliguori
                qemu_log("Trying to read privileged spr %d %03x at "
3717 077fc206 j_mayer
                            ADDRX "\n", sprn, sprn, ctx->nip);
3718 077fc206 j_mayer
                printf("Trying to read privileged spr %d %03x at " ADDRX "\n",
3719 077fc206 j_mayer
                       sprn, sprn, ctx->nip);
3720 f24e5695 bellard
            }
3721 e06fcd75 aurel32
            gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3722 79aceca5 bellard
        }
3723 3fc6c082 bellard
    } else {
3724 3fc6c082 bellard
        /* Not defined */
3725 93fcfe39 aliguori
        qemu_log("Trying to read invalid spr %d %03x at "
3726 077fc206 j_mayer
                    ADDRX "\n", sprn, sprn, ctx->nip);
3727 077fc206 j_mayer
        printf("Trying to read invalid spr %d %03x at " ADDRX "\n",
3728 077fc206 j_mayer
               sprn, sprn, ctx->nip);
3729 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
3730 79aceca5 bellard
    }
3731 79aceca5 bellard
}
3732 79aceca5 bellard
3733 99e300ef Blue Swirl
static void gen_mfspr(DisasContext *ctx)
3734 79aceca5 bellard
{
3735 3fc6c082 bellard
    gen_op_mfspr(ctx);
3736 76a66253 j_mayer
}
3737 3fc6c082 bellard
3738 3fc6c082 bellard
/* mftb */
3739 99e300ef Blue Swirl
static void gen_mftb(DisasContext *ctx)
3740 3fc6c082 bellard
{
3741 3fc6c082 bellard
    gen_op_mfspr(ctx);
3742 79aceca5 bellard
}
3743 79aceca5 bellard
3744 0cfe11ea aurel32
/* mtcrf mtocrf*/
3745 99e300ef Blue Swirl
static void gen_mtcrf(DisasContext *ctx)
3746 79aceca5 bellard
{
3747 76a66253 j_mayer
    uint32_t crm, crn;
3748 3b46e624 ths
3749 76a66253 j_mayer
    crm = CRM(ctx->opcode);
3750 8dd640e4 malc
    if (likely((ctx->opcode & 0x00100000))) {
3751 8dd640e4 malc
        if (crm && ((crm & (crm - 1)) == 0)) {
3752 8dd640e4 malc
            TCGv_i32 temp = tcg_temp_new_i32();
3753 0cfe11ea aurel32
            crn = ctz32 (crm);
3754 8dd640e4 malc
            tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
3755 0cfe11ea aurel32
            tcg_gen_shri_i32(temp, temp, crn * 4);
3756 0cfe11ea aurel32
            tcg_gen_andi_i32(cpu_crf[7 - crn], temp, 0xf);
3757 8dd640e4 malc
            tcg_temp_free_i32(temp);
3758 8dd640e4 malc
        }
3759 76a66253 j_mayer
    } else {
3760 651721b2 aurel32
        TCGv_i32 temp = tcg_temp_new_i32();
3761 651721b2 aurel32
        tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
3762 651721b2 aurel32
        for (crn = 0 ; crn < 8 ; crn++) {
3763 651721b2 aurel32
            if (crm & (1 << crn)) {
3764 651721b2 aurel32
                    tcg_gen_shri_i32(cpu_crf[7 - crn], temp, crn * 4);
3765 651721b2 aurel32
                    tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf);
3766 651721b2 aurel32
            }
3767 651721b2 aurel32
        }
3768 a7812ae4 pbrook
        tcg_temp_free_i32(temp);
3769 76a66253 j_mayer
    }
3770 79aceca5 bellard
}
3771 79aceca5 bellard
3772 79aceca5 bellard
/* mtmsr */
3773 426613db j_mayer
#if defined(TARGET_PPC64)
3774 99e300ef Blue Swirl
static void gen_mtmsrd(DisasContext *ctx)
3775 426613db j_mayer
{
3776 426613db j_mayer
#if defined(CONFIG_USER_ONLY)
3777 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3778 426613db j_mayer
#else
3779 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
3780 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3781 426613db j_mayer
        return;
3782 426613db j_mayer
    }
3783 be147d08 j_mayer
    if (ctx->opcode & 0x00010000) {
3784 be147d08 j_mayer
        /* Special form that does not need any synchronisation */
3785 6527f6ea aurel32
        TCGv t0 = tcg_temp_new();
3786 6527f6ea aurel32
        tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
3787 6527f6ea aurel32
        tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
3788 6527f6ea aurel32
        tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
3789 6527f6ea aurel32
        tcg_temp_free(t0);
3790 be147d08 j_mayer
    } else {
3791 056b05f8 j_mayer
        /* XXX: we need to update nip before the store
3792 056b05f8 j_mayer
         *      if we enter power saving mode, we will exit the loop
3793 056b05f8 j_mayer
         *      directly from ppc_store_msr
3794 056b05f8 j_mayer
         */
3795 be147d08 j_mayer
        gen_update_nip(ctx, ctx->nip);
3796 6527f6ea aurel32
        gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]);
3797 be147d08 j_mayer
        /* Must stop the translation as machine state (may have) changed */
3798 be147d08 j_mayer
        /* Note that mtmsr is not always defined as context-synchronizing */
3799 e06fcd75 aurel32
        gen_stop_exception(ctx);
3800 be147d08 j_mayer
    }
3801 426613db j_mayer
#endif
3802 426613db j_mayer
}
3803 426613db j_mayer
#endif
3804 426613db j_mayer
3805 99e300ef Blue Swirl
static void gen_mtmsr(DisasContext *ctx)
3806 79aceca5 bellard
{
3807 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
3808 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3809 9a64fbe4 bellard
#else
3810 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
3811 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3812 9fddaa0c bellard
        return;
3813 9a64fbe4 bellard
    }
3814 be147d08 j_mayer
    if (ctx->opcode & 0x00010000) {
3815 be147d08 j_mayer
        /* Special form that does not need any synchronisation */
3816 6527f6ea aurel32
        TCGv t0 = tcg_temp_new();
3817 6527f6ea aurel32
        tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
3818 6527f6ea aurel32
        tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
3819 6527f6ea aurel32
        tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
3820 6527f6ea aurel32
        tcg_temp_free(t0);
3821 be147d08 j_mayer
    } else {
3822 056b05f8 j_mayer
        /* XXX: we need to update nip before the store
3823 056b05f8 j_mayer
         *      if we enter power saving mode, we will exit the loop
3824 056b05f8 j_mayer
         *      directly from ppc_store_msr
3825 056b05f8 j_mayer
         */
3826 be147d08 j_mayer
        gen_update_nip(ctx, ctx->nip);
3827 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
3828 6527f6ea aurel32
        if (!ctx->sf_mode) {
3829 6527f6ea aurel32
            TCGv t0 = tcg_temp_new();
3830 6527f6ea aurel32
            TCGv t1 = tcg_temp_new();
3831 6527f6ea aurel32
            tcg_gen_andi_tl(t0, cpu_msr, 0xFFFFFFFF00000000ULL);
3832 6527f6ea aurel32
            tcg_gen_ext32u_tl(t1, cpu_gpr[rS(ctx->opcode)]);
3833 6527f6ea aurel32
            tcg_gen_or_tl(t0, t0, t1);
3834 6527f6ea aurel32
            tcg_temp_free(t1);
3835 6527f6ea aurel32
            gen_helper_store_msr(t0);
3836 6527f6ea aurel32
            tcg_temp_free(t0);
3837 6527f6ea aurel32
        } else
3838 d9bce9d9 j_mayer
#endif
3839 6527f6ea aurel32
            gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]);
3840 be147d08 j_mayer
        /* Must stop the translation as machine state (may have) changed */
3841 6527f6ea aurel32
        /* Note that mtmsr is not always defined as context-synchronizing */
3842 e06fcd75 aurel32
        gen_stop_exception(ctx);
3843 be147d08 j_mayer
    }
3844 9a64fbe4 bellard
#endif
3845 79aceca5 bellard
}
3846 79aceca5 bellard
3847 79aceca5 bellard
/* mtspr */
3848 99e300ef Blue Swirl
static void gen_mtspr(DisasContext *ctx)
3849 79aceca5 bellard
{
3850 45d827d2 aurel32
    void (*write_cb)(void *opaque, int sprn, int gprn);
3851 79aceca5 bellard
    uint32_t sprn = SPR(ctx->opcode);
3852 79aceca5 bellard
3853 3fc6c082 bellard
#if !defined(CONFIG_USER_ONLY)
3854 76db3ba4 aurel32
    if (ctx->mem_idx == 2)
3855 be147d08 j_mayer
        write_cb = ctx->spr_cb[sprn].hea_write;
3856 76db3ba4 aurel32
    else if (ctx->mem_idx)
3857 3fc6c082 bellard
        write_cb = ctx->spr_cb[sprn].oea_write;
3858 3fc6c082 bellard
    else
3859 9a64fbe4 bellard
#endif
3860 3fc6c082 bellard
        write_cb = ctx->spr_cb[sprn].uea_write;
3861 76a66253 j_mayer
    if (likely(write_cb != NULL)) {
3862 76a66253 j_mayer
        if (likely(write_cb != SPR_NOACCESS)) {
3863 45d827d2 aurel32
            (*write_cb)(ctx, sprn, rS(ctx->opcode));
3864 3fc6c082 bellard
        } else {
3865 3fc6c082 bellard
            /* Privilege exception */
3866 93fcfe39 aliguori
            qemu_log("Trying to write privileged spr %d %03x at "
3867 077fc206 j_mayer
                        ADDRX "\n", sprn, sprn, ctx->nip);
3868 077fc206 j_mayer
            printf("Trying to write privileged spr %d %03x at " ADDRX "\n",
3869 077fc206 j_mayer
                   sprn, sprn, ctx->nip);
3870 e06fcd75 aurel32
            gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
3871 76a66253 j_mayer
        }
3872 3fc6c082 bellard
    } else {
3873 3fc6c082 bellard
        /* Not defined */
3874 93fcfe39 aliguori
        qemu_log("Trying to write invalid spr %d %03x at "
3875 077fc206 j_mayer
                    ADDRX "\n", sprn, sprn, ctx->nip);
3876 077fc206 j_mayer
        printf("Trying to write invalid spr %d %03x at " ADDRX "\n",
3877 077fc206 j_mayer
               sprn, sprn, ctx->nip);
3878 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
3879 79aceca5 bellard
    }
3880 79aceca5 bellard
}
3881 79aceca5 bellard
3882 79aceca5 bellard
/***                         Cache management                              ***/
3883 99e300ef Blue Swirl
3884 54623277 Blue Swirl
/* dcbf */
3885 99e300ef Blue Swirl
static void gen_dcbf(DisasContext *ctx)
3886 79aceca5 bellard
{
3887 dac454af j_mayer
    /* XXX: specification says this is treated as a load by the MMU */
3888 76db3ba4 aurel32
    TCGv t0;
3889 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_CACHE);
3890 76db3ba4 aurel32
    t0 = tcg_temp_new();
3891 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
3892 76db3ba4 aurel32
    gen_qemu_ld8u(ctx, t0, t0);
3893 fea0c503 aurel32
    tcg_temp_free(t0);
3894 79aceca5 bellard
}
3895 79aceca5 bellard
3896 79aceca5 bellard
/* dcbi (Supervisor only) */
3897 99e300ef Blue Swirl
static void gen_dcbi(DisasContext *ctx)
3898 79aceca5 bellard
{
3899 a541f297 bellard
#if defined(CONFIG_USER_ONLY)
3900 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3901 a541f297 bellard
#else
3902 b61f2753 aurel32
    TCGv EA, val;
3903 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
3904 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
3905 9fddaa0c bellard
        return;
3906 9a64fbe4 bellard
    }
3907 a7812ae4 pbrook
    EA = tcg_temp_new();
3908 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_CACHE);
3909 76db3ba4 aurel32
    gen_addr_reg_index(ctx, EA);
3910 a7812ae4 pbrook
    val = tcg_temp_new();
3911 76a66253 j_mayer
    /* XXX: specification says this should be treated as a store by the MMU */
3912 76db3ba4 aurel32
    gen_qemu_ld8u(ctx, val, EA);
3913 76db3ba4 aurel32
    gen_qemu_st8(ctx, val, EA);
3914 b61f2753 aurel32
    tcg_temp_free(val);
3915 b61f2753 aurel32
    tcg_temp_free(EA);
3916 a541f297 bellard
#endif
3917 79aceca5 bellard
}
3918 79aceca5 bellard
3919 79aceca5 bellard
/* dcdst */
3920 99e300ef Blue Swirl
static void gen_dcbst(DisasContext *ctx)
3921 79aceca5 bellard
{
3922 76a66253 j_mayer
    /* XXX: specification say this is treated as a load by the MMU */
3923 76db3ba4 aurel32
    TCGv t0;
3924 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_CACHE);
3925 76db3ba4 aurel32
    t0 = tcg_temp_new();
3926 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
3927 76db3ba4 aurel32
    gen_qemu_ld8u(ctx, t0, t0);
3928 fea0c503 aurel32
    tcg_temp_free(t0);
3929 79aceca5 bellard
}
3930 79aceca5 bellard
3931 79aceca5 bellard
/* dcbt */
3932 99e300ef Blue Swirl
static void gen_dcbt(DisasContext *ctx)
3933 79aceca5 bellard
{
3934 0db1b20e j_mayer
    /* interpreted as no-op */
3935 76a66253 j_mayer
    /* XXX: specification say this is treated as a load by the MMU
3936 76a66253 j_mayer
     *      but does not generate any exception
3937 76a66253 j_mayer
     */
3938 79aceca5 bellard
}
3939 79aceca5 bellard
3940 79aceca5 bellard
/* dcbtst */
3941 99e300ef Blue Swirl
static void gen_dcbtst(DisasContext *ctx)
3942 79aceca5 bellard
{
3943 0db1b20e j_mayer
    /* interpreted as no-op */
3944 76a66253 j_mayer
    /* XXX: specification say this is treated as a load by the MMU
3945 76a66253 j_mayer
     *      but does not generate any exception
3946 76a66253 j_mayer
     */
3947 79aceca5 bellard
}
3948 79aceca5 bellard
3949 79aceca5 bellard
/* dcbz */
3950 99e300ef Blue Swirl
static void gen_dcbz(DisasContext *ctx)
3951 79aceca5 bellard
{
3952 76db3ba4 aurel32
    TCGv t0;
3953 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_CACHE);
3954 799a8c8d aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */
3955 799a8c8d aurel32
    gen_update_nip(ctx, ctx->nip - 4);
3956 76db3ba4 aurel32
    t0 = tcg_temp_new();
3957 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
3958 799a8c8d aurel32
    gen_helper_dcbz(t0);
3959 799a8c8d aurel32
    tcg_temp_free(t0);
3960 d63001d1 j_mayer
}
3961 d63001d1 j_mayer
3962 e8eaa2c0 Blue Swirl
static void gen_dcbz_970(DisasContext *ctx)
3963 d63001d1 j_mayer
{
3964 76db3ba4 aurel32
    TCGv t0;
3965 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_CACHE);
3966 799a8c8d aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */
3967 799a8c8d aurel32
    gen_update_nip(ctx, ctx->nip - 4);
3968 76db3ba4 aurel32
    t0 = tcg_temp_new();
3969 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
3970 d63001d1 j_mayer
    if (ctx->opcode & 0x00200000)
3971 799a8c8d aurel32
        gen_helper_dcbz(t0);
3972 d63001d1 j_mayer
    else
3973 799a8c8d aurel32
        gen_helper_dcbz_970(t0);
3974 799a8c8d aurel32
    tcg_temp_free(t0);
3975 79aceca5 bellard
}
3976 79aceca5 bellard
3977 ae1c1a3d aurel32
/* dst / dstt */
3978 99e300ef Blue Swirl
static void gen_dst(DisasContext *ctx)
3979 ae1c1a3d aurel32
{
3980 ae1c1a3d aurel32
    if (rA(ctx->opcode) == 0) {
3981 ae1c1a3d aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
3982 ae1c1a3d aurel32
    } else {
3983 ae1c1a3d aurel32
        /* interpreted as no-op */
3984 ae1c1a3d aurel32
    }
3985 ae1c1a3d aurel32
}
3986 ae1c1a3d aurel32
3987 ae1c1a3d aurel32
/* dstst /dststt */
3988 99e300ef Blue Swirl
static void gen_dstst(DisasContext *ctx)
3989 ae1c1a3d aurel32
{
3990 ae1c1a3d aurel32
    if (rA(ctx->opcode) == 0) {
3991 ae1c1a3d aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
3992 ae1c1a3d aurel32
    } else {
3993 ae1c1a3d aurel32
        /* interpreted as no-op */
3994 ae1c1a3d aurel32
    }
3995 ae1c1a3d aurel32
3996 ae1c1a3d aurel32
}
3997 ae1c1a3d aurel32
3998 ae1c1a3d aurel32
/* dss / dssall */
3999 99e300ef Blue Swirl
static void gen_dss(DisasContext *ctx)
4000 ae1c1a3d aurel32
{
4001 ae1c1a3d aurel32
    /* interpreted as no-op */
4002 ae1c1a3d aurel32
}
4003 ae1c1a3d aurel32
4004 79aceca5 bellard
/* icbi */
4005 99e300ef Blue Swirl
static void gen_icbi(DisasContext *ctx)
4006 79aceca5 bellard
{
4007 76db3ba4 aurel32
    TCGv t0;
4008 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_CACHE);
4009 30032c94 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
4010 30032c94 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
4011 76db3ba4 aurel32
    t0 = tcg_temp_new();
4012 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
4013 37d269df aurel32
    gen_helper_icbi(t0);
4014 37d269df aurel32
    tcg_temp_free(t0);
4015 79aceca5 bellard
}
4016 79aceca5 bellard
4017 79aceca5 bellard
/* Optional: */
4018 79aceca5 bellard
/* dcba */
4019 99e300ef Blue Swirl
static void gen_dcba(DisasContext *ctx)
4020 79aceca5 bellard
{
4021 0db1b20e j_mayer
    /* interpreted as no-op */
4022 0db1b20e j_mayer
    /* XXX: specification say this is treated as a store by the MMU
4023 0db1b20e j_mayer
     *      but does not generate any exception
4024 0db1b20e j_mayer
     */
4025 79aceca5 bellard
}
4026 79aceca5 bellard
4027 79aceca5 bellard
/***                    Segment register manipulation                      ***/
4028 79aceca5 bellard
/* Supervisor only: */
4029 99e300ef Blue Swirl
4030 54623277 Blue Swirl
/* mfsr */
4031 99e300ef Blue Swirl
static void gen_mfsr(DisasContext *ctx)
4032 79aceca5 bellard
{
4033 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
4034 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4035 9a64fbe4 bellard
#else
4036 74d37793 aurel32
    TCGv t0;
4037 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
4038 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4039 9fddaa0c bellard
        return;
4040 9a64fbe4 bellard
    }
4041 74d37793 aurel32
    t0 = tcg_const_tl(SR(ctx->opcode));
4042 74d37793 aurel32
    gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
4043 74d37793 aurel32
    tcg_temp_free(t0);
4044 9a64fbe4 bellard
#endif
4045 79aceca5 bellard
}
4046 79aceca5 bellard
4047 79aceca5 bellard
/* mfsrin */
4048 99e300ef Blue Swirl
static void gen_mfsrin(DisasContext *ctx)
4049 79aceca5 bellard
{
4050 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
4051 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4052 9a64fbe4 bellard
#else
4053 74d37793 aurel32
    TCGv t0;
4054 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
4055 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4056 9fddaa0c bellard
        return;
4057 9a64fbe4 bellard
    }
4058 74d37793 aurel32
    t0 = tcg_temp_new();
4059 74d37793 aurel32
    tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4060 74d37793 aurel32
    tcg_gen_andi_tl(t0, t0, 0xF);
4061 74d37793 aurel32
    gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
4062 74d37793 aurel32
    tcg_temp_free(t0);
4063 9a64fbe4 bellard
#endif
4064 79aceca5 bellard
}
4065 79aceca5 bellard
4066 79aceca5 bellard
/* mtsr */
4067 99e300ef Blue Swirl
static void gen_mtsr(DisasContext *ctx)
4068 79aceca5 bellard
{
4069 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
4070 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4071 9a64fbe4 bellard
#else
4072 74d37793 aurel32
    TCGv t0;
4073 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
4074 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4075 9fddaa0c bellard
        return;
4076 9a64fbe4 bellard
    }
4077 74d37793 aurel32
    t0 = tcg_const_tl(SR(ctx->opcode));
4078 74d37793 aurel32
    gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
4079 74d37793 aurel32
    tcg_temp_free(t0);
4080 9a64fbe4 bellard
#endif
4081 79aceca5 bellard
}
4082 79aceca5 bellard
4083 79aceca5 bellard
/* mtsrin */
4084 99e300ef Blue Swirl
static void gen_mtsrin(DisasContext *ctx)
4085 79aceca5 bellard
{
4086 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
4087 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4088 9a64fbe4 bellard
#else
4089 74d37793 aurel32
    TCGv t0;
4090 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
4091 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4092 9fddaa0c bellard
        return;
4093 9a64fbe4 bellard
    }
4094 74d37793 aurel32
    t0 = tcg_temp_new();
4095 74d37793 aurel32
    tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4096 74d37793 aurel32
    tcg_gen_andi_tl(t0, t0, 0xF);
4097 74d37793 aurel32
    gen_helper_store_sr(t0, cpu_gpr[rD(ctx->opcode)]);
4098 74d37793 aurel32
    tcg_temp_free(t0);
4099 9a64fbe4 bellard
#endif
4100 79aceca5 bellard
}
4101 79aceca5 bellard
4102 12de9a39 j_mayer
#if defined(TARGET_PPC64)
4103 12de9a39 j_mayer
/* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
4104 e8eaa2c0 Blue Swirl
4105 54623277 Blue Swirl
/* mfsr */
4106 e8eaa2c0 Blue Swirl
static void gen_mfsr_64b(DisasContext *ctx)
4107 12de9a39 j_mayer
{
4108 12de9a39 j_mayer
#if defined(CONFIG_USER_ONLY)
4109 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4110 12de9a39 j_mayer
#else
4111 74d37793 aurel32
    TCGv t0;
4112 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
4113 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4114 12de9a39 j_mayer
        return;
4115 12de9a39 j_mayer
    }
4116 74d37793 aurel32
    t0 = tcg_const_tl(SR(ctx->opcode));
4117 f6b868fc blueswir1
    gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
4118 74d37793 aurel32
    tcg_temp_free(t0);
4119 12de9a39 j_mayer
#endif
4120 12de9a39 j_mayer
}
4121 12de9a39 j_mayer
4122 12de9a39 j_mayer
/* mfsrin */
4123 e8eaa2c0 Blue Swirl
static void gen_mfsrin_64b(DisasContext *ctx)
4124 12de9a39 j_mayer
{
4125 12de9a39 j_mayer
#if defined(CONFIG_USER_ONLY)
4126 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4127 12de9a39 j_mayer
#else
4128 74d37793 aurel32
    TCGv t0;
4129 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
4130 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4131 12de9a39 j_mayer
        return;
4132 12de9a39 j_mayer
    }
4133 74d37793 aurel32
    t0 = tcg_temp_new();
4134 74d37793 aurel32
    tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4135 74d37793 aurel32
    tcg_gen_andi_tl(t0, t0, 0xF);
4136 f6b868fc blueswir1
    gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
4137 74d37793 aurel32
    tcg_temp_free(t0);
4138 12de9a39 j_mayer
#endif
4139 12de9a39 j_mayer
}
4140 12de9a39 j_mayer
4141 12de9a39 j_mayer
/* mtsr */
4142 e8eaa2c0 Blue Swirl
static void gen_mtsr_64b(DisasContext *ctx)
4143 12de9a39 j_mayer
{
4144 12de9a39 j_mayer
#if defined(CONFIG_USER_ONLY)
4145 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4146 12de9a39 j_mayer
#else
4147 74d37793 aurel32
    TCGv t0;
4148 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
4149 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4150 12de9a39 j_mayer
        return;
4151 12de9a39 j_mayer
    }
4152 74d37793 aurel32
    t0 = tcg_const_tl(SR(ctx->opcode));
4153 f6b868fc blueswir1
    gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
4154 74d37793 aurel32
    tcg_temp_free(t0);
4155 12de9a39 j_mayer
#endif
4156 12de9a39 j_mayer
}
4157 12de9a39 j_mayer
4158 12de9a39 j_mayer
/* mtsrin */
4159 e8eaa2c0 Blue Swirl
static void gen_mtsrin_64b(DisasContext *ctx)
4160 12de9a39 j_mayer
{
4161 12de9a39 j_mayer
#if defined(CONFIG_USER_ONLY)
4162 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4163 12de9a39 j_mayer
#else
4164 74d37793 aurel32
    TCGv t0;
4165 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
4166 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4167 12de9a39 j_mayer
        return;
4168 12de9a39 j_mayer
    }
4169 74d37793 aurel32
    t0 = tcg_temp_new();
4170 74d37793 aurel32
    tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
4171 74d37793 aurel32
    tcg_gen_andi_tl(t0, t0, 0xF);
4172 f6b868fc blueswir1
    gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
4173 74d37793 aurel32
    tcg_temp_free(t0);
4174 12de9a39 j_mayer
#endif
4175 12de9a39 j_mayer
}
4176 f6b868fc blueswir1
4177 f6b868fc blueswir1
/* slbmte */
4178 e8eaa2c0 Blue Swirl
static void gen_slbmte(DisasContext *ctx)
4179 f6b868fc blueswir1
{
4180 f6b868fc blueswir1
#if defined(CONFIG_USER_ONLY)
4181 f6b868fc blueswir1
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4182 f6b868fc blueswir1
#else
4183 f6b868fc blueswir1
    if (unlikely(!ctx->mem_idx)) {
4184 f6b868fc blueswir1
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4185 f6b868fc blueswir1
        return;
4186 f6b868fc blueswir1
    }
4187 f6b868fc blueswir1
    gen_helper_store_slb(cpu_gpr[rB(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
4188 f6b868fc blueswir1
#endif
4189 f6b868fc blueswir1
}
4190 f6b868fc blueswir1
4191 12de9a39 j_mayer
#endif /* defined(TARGET_PPC64) */
4192 12de9a39 j_mayer
4193 79aceca5 bellard
/***                      Lookaside buffer management                      ***/
4194 76db3ba4 aurel32
/* Optional & mem_idx only: */
4195 99e300ef Blue Swirl
4196 54623277 Blue Swirl
/* tlbia */
4197 99e300ef Blue Swirl
static void gen_tlbia(DisasContext *ctx)
4198 79aceca5 bellard
{
4199 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
4200 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4201 9a64fbe4 bellard
#else
4202 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
4203 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4204 9fddaa0c bellard
        return;
4205 9a64fbe4 bellard
    }
4206 74d37793 aurel32
    gen_helper_tlbia();
4207 9a64fbe4 bellard
#endif
4208 79aceca5 bellard
}
4209 79aceca5 bellard
4210 bf14b1ce blueswir1
/* tlbiel */
4211 99e300ef Blue Swirl
static void gen_tlbiel(DisasContext *ctx)
4212 bf14b1ce blueswir1
{
4213 bf14b1ce blueswir1
#if defined(CONFIG_USER_ONLY)
4214 bf14b1ce blueswir1
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4215 bf14b1ce blueswir1
#else
4216 bf14b1ce blueswir1
    if (unlikely(!ctx->mem_idx)) {
4217 bf14b1ce blueswir1
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4218 bf14b1ce blueswir1
        return;
4219 bf14b1ce blueswir1
    }
4220 bf14b1ce blueswir1
    gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
4221 bf14b1ce blueswir1
#endif
4222 bf14b1ce blueswir1
}
4223 bf14b1ce blueswir1
4224 79aceca5 bellard
/* tlbie */
4225 99e300ef Blue Swirl
static void gen_tlbie(DisasContext *ctx)
4226 79aceca5 bellard
{
4227 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
4228 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4229 9a64fbe4 bellard
#else
4230 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
4231 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4232 9fddaa0c bellard
        return;
4233 9a64fbe4 bellard
    }
4234 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
4235 74d37793 aurel32
    if (!ctx->sf_mode) {
4236 74d37793 aurel32
        TCGv t0 = tcg_temp_new();
4237 74d37793 aurel32
        tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
4238 74d37793 aurel32
        gen_helper_tlbie(t0);
4239 74d37793 aurel32
        tcg_temp_free(t0);
4240 74d37793 aurel32
    } else
4241 d9bce9d9 j_mayer
#endif
4242 74d37793 aurel32
        gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
4243 9a64fbe4 bellard
#endif
4244 79aceca5 bellard
}
4245 79aceca5 bellard
4246 79aceca5 bellard
/* tlbsync */
4247 99e300ef Blue Swirl
static void gen_tlbsync(DisasContext *ctx)
4248 79aceca5 bellard
{
4249 9a64fbe4 bellard
#if defined(CONFIG_USER_ONLY)
4250 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4251 9a64fbe4 bellard
#else
4252 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
4253 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4254 9fddaa0c bellard
        return;
4255 9a64fbe4 bellard
    }
4256 9a64fbe4 bellard
    /* This has no effect: it should ensure that all previous
4257 9a64fbe4 bellard
     * tlbie have completed
4258 9a64fbe4 bellard
     */
4259 e06fcd75 aurel32
    gen_stop_exception(ctx);
4260 9a64fbe4 bellard
#endif
4261 79aceca5 bellard
}
4262 79aceca5 bellard
4263 426613db j_mayer
#if defined(TARGET_PPC64)
4264 426613db j_mayer
/* slbia */
4265 99e300ef Blue Swirl
static void gen_slbia(DisasContext *ctx)
4266 426613db j_mayer
{
4267 426613db j_mayer
#if defined(CONFIG_USER_ONLY)
4268 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4269 426613db j_mayer
#else
4270 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
4271 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4272 426613db j_mayer
        return;
4273 426613db j_mayer
    }
4274 74d37793 aurel32
    gen_helper_slbia();
4275 426613db j_mayer
#endif
4276 426613db j_mayer
}
4277 426613db j_mayer
4278 426613db j_mayer
/* slbie */
4279 99e300ef Blue Swirl
static void gen_slbie(DisasContext *ctx)
4280 426613db j_mayer
{
4281 426613db j_mayer
#if defined(CONFIG_USER_ONLY)
4282 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4283 426613db j_mayer
#else
4284 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
4285 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4286 426613db j_mayer
        return;
4287 426613db j_mayer
    }
4288 74d37793 aurel32
    gen_helper_slbie(cpu_gpr[rB(ctx->opcode)]);
4289 426613db j_mayer
#endif
4290 426613db j_mayer
}
4291 426613db j_mayer
#endif
4292 426613db j_mayer
4293 79aceca5 bellard
/***                              External control                         ***/
4294 79aceca5 bellard
/* Optional: */
4295 99e300ef Blue Swirl
4296 54623277 Blue Swirl
/* eciwx */
4297 99e300ef Blue Swirl
static void gen_eciwx(DisasContext *ctx)
4298 79aceca5 bellard
{
4299 76db3ba4 aurel32
    TCGv t0;
4300 fa407c03 aurel32
    /* Should check EAR[E] ! */
4301 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_EXT);
4302 76db3ba4 aurel32
    t0 = tcg_temp_new();
4303 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
4304 fa407c03 aurel32
    gen_check_align(ctx, t0, 0x03);
4305 76db3ba4 aurel32
    gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], t0);
4306 fa407c03 aurel32
    tcg_temp_free(t0);
4307 76a66253 j_mayer
}
4308 76a66253 j_mayer
4309 76a66253 j_mayer
/* ecowx */
4310 99e300ef Blue Swirl
static void gen_ecowx(DisasContext *ctx)
4311 76a66253 j_mayer
{
4312 76db3ba4 aurel32
    TCGv t0;
4313 fa407c03 aurel32
    /* Should check EAR[E] ! */
4314 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_EXT);
4315 76db3ba4 aurel32
    t0 = tcg_temp_new();
4316 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
4317 fa407c03 aurel32
    gen_check_align(ctx, t0, 0x03);
4318 76db3ba4 aurel32
    gen_qemu_st32(ctx, cpu_gpr[rD(ctx->opcode)], t0);
4319 fa407c03 aurel32
    tcg_temp_free(t0);
4320 76a66253 j_mayer
}
4321 76a66253 j_mayer
4322 76a66253 j_mayer
/* PowerPC 601 specific instructions */
4323 99e300ef Blue Swirl
4324 54623277 Blue Swirl
/* abs - abs. */
4325 99e300ef Blue Swirl
static void gen_abs(DisasContext *ctx)
4326 76a66253 j_mayer
{
4327 22e0e173 aurel32
    int l1 = gen_new_label();
4328 22e0e173 aurel32
    int l2 = gen_new_label();
4329 22e0e173 aurel32
    tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l1);
4330 22e0e173 aurel32
    tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4331 22e0e173 aurel32
    tcg_gen_br(l2);
4332 22e0e173 aurel32
    gen_set_label(l1);
4333 22e0e173 aurel32
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4334 22e0e173 aurel32
    gen_set_label(l2);
4335 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4336 22e0e173 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4337 76a66253 j_mayer
}
4338 76a66253 j_mayer
4339 76a66253 j_mayer
/* abso - abso. */
4340 99e300ef Blue Swirl
static void gen_abso(DisasContext *ctx)
4341 76a66253 j_mayer
{
4342 22e0e173 aurel32
    int l1 = gen_new_label();
4343 22e0e173 aurel32
    int l2 = gen_new_label();
4344 22e0e173 aurel32
    int l3 = gen_new_label();
4345 22e0e173 aurel32
    /* Start with XER OV disabled, the most likely case */
4346 22e0e173 aurel32
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
4347 22e0e173 aurel32
    tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l2);
4348 22e0e173 aurel32
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rA(ctx->opcode)], 0x80000000, l1);
4349 22e0e173 aurel32
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
4350 22e0e173 aurel32
    tcg_gen_br(l2);
4351 22e0e173 aurel32
    gen_set_label(l1);
4352 22e0e173 aurel32
    tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4353 22e0e173 aurel32
    tcg_gen_br(l3);
4354 22e0e173 aurel32
    gen_set_label(l2);
4355 22e0e173 aurel32
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4356 22e0e173 aurel32
    gen_set_label(l3);
4357 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4358 22e0e173 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4359 76a66253 j_mayer
}
4360 76a66253 j_mayer
4361 76a66253 j_mayer
/* clcs */
4362 99e300ef Blue Swirl
static void gen_clcs(DisasContext *ctx)
4363 76a66253 j_mayer
{
4364 22e0e173 aurel32
    TCGv_i32 t0 = tcg_const_i32(rA(ctx->opcode));
4365 22e0e173 aurel32
    gen_helper_clcs(cpu_gpr[rD(ctx->opcode)], t0);
4366 22e0e173 aurel32
    tcg_temp_free_i32(t0);
4367 c7697e1f j_mayer
    /* Rc=1 sets CR0 to an undefined state */
4368 76a66253 j_mayer
}
4369 76a66253 j_mayer
4370 76a66253 j_mayer
/* div - div. */
4371 99e300ef Blue Swirl
static void gen_div(DisasContext *ctx)
4372 76a66253 j_mayer
{
4373 22e0e173 aurel32
    gen_helper_div(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4374 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4375 22e0e173 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4376 76a66253 j_mayer
}
4377 76a66253 j_mayer
4378 76a66253 j_mayer
/* divo - divo. */
4379 99e300ef Blue Swirl
static void gen_divo(DisasContext *ctx)
4380 76a66253 j_mayer
{
4381 22e0e173 aurel32
    gen_helper_divo(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4382 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4383 22e0e173 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4384 76a66253 j_mayer
}
4385 76a66253 j_mayer
4386 76a66253 j_mayer
/* divs - divs. */
4387 99e300ef Blue Swirl
static void gen_divs(DisasContext *ctx)
4388 76a66253 j_mayer
{
4389 22e0e173 aurel32
    gen_helper_divs(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4390 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4391 22e0e173 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4392 76a66253 j_mayer
}
4393 76a66253 j_mayer
4394 76a66253 j_mayer
/* divso - divso. */
4395 99e300ef Blue Swirl
static void gen_divso(DisasContext *ctx)
4396 76a66253 j_mayer
{
4397 22e0e173 aurel32
    gen_helper_divso(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4398 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4399 22e0e173 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4400 76a66253 j_mayer
}
4401 76a66253 j_mayer
4402 76a66253 j_mayer
/* doz - doz. */
4403 99e300ef Blue Swirl
static void gen_doz(DisasContext *ctx)
4404 76a66253 j_mayer
{
4405 22e0e173 aurel32
    int l1 = gen_new_label();
4406 22e0e173 aurel32
    int l2 = gen_new_label();
4407 22e0e173 aurel32
    tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
4408 22e0e173 aurel32
    tcg_gen_sub_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4409 22e0e173 aurel32
    tcg_gen_br(l2);
4410 22e0e173 aurel32
    gen_set_label(l1);
4411 22e0e173 aurel32
    tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
4412 22e0e173 aurel32
    gen_set_label(l2);
4413 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4414 22e0e173 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4415 76a66253 j_mayer
}
4416 76a66253 j_mayer
4417 76a66253 j_mayer
/* dozo - dozo. */
4418 99e300ef Blue Swirl
static void gen_dozo(DisasContext *ctx)
4419 76a66253 j_mayer
{
4420 22e0e173 aurel32
    int l1 = gen_new_label();
4421 22e0e173 aurel32
    int l2 = gen_new_label();
4422 22e0e173 aurel32
    TCGv t0 = tcg_temp_new();
4423 22e0e173 aurel32
    TCGv t1 = tcg_temp_new();
4424 22e0e173 aurel32
    TCGv t2 = tcg_temp_new();
4425 22e0e173 aurel32
    /* Start with XER OV disabled, the most likely case */
4426 22e0e173 aurel32
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
4427 22e0e173 aurel32
    tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
4428 22e0e173 aurel32
    tcg_gen_sub_tl(t0, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4429 22e0e173 aurel32
    tcg_gen_xor_tl(t1, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4430 22e0e173 aurel32
    tcg_gen_xor_tl(t2, cpu_gpr[rA(ctx->opcode)], t0);
4431 22e0e173 aurel32
    tcg_gen_andc_tl(t1, t1, t2);
4432 22e0e173 aurel32
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
4433 22e0e173 aurel32
    tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
4434 22e0e173 aurel32
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
4435 22e0e173 aurel32
    tcg_gen_br(l2);
4436 22e0e173 aurel32
    gen_set_label(l1);
4437 22e0e173 aurel32
    tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
4438 22e0e173 aurel32
    gen_set_label(l2);
4439 22e0e173 aurel32
    tcg_temp_free(t0);
4440 22e0e173 aurel32
    tcg_temp_free(t1);
4441 22e0e173 aurel32
    tcg_temp_free(t2);
4442 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4443 22e0e173 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4444 76a66253 j_mayer
}
4445 76a66253 j_mayer
4446 76a66253 j_mayer
/* dozi */
4447 99e300ef Blue Swirl
static void gen_dozi(DisasContext *ctx)
4448 76a66253 j_mayer
{
4449 22e0e173 aurel32
    target_long simm = SIMM(ctx->opcode);
4450 22e0e173 aurel32
    int l1 = gen_new_label();
4451 22e0e173 aurel32
    int l2 = gen_new_label();
4452 22e0e173 aurel32
    tcg_gen_brcondi_tl(TCG_COND_LT, cpu_gpr[rA(ctx->opcode)], simm, l1);
4453 22e0e173 aurel32
    tcg_gen_subfi_tl(cpu_gpr[rD(ctx->opcode)], simm, cpu_gpr[rA(ctx->opcode)]);
4454 22e0e173 aurel32
    tcg_gen_br(l2);
4455 22e0e173 aurel32
    gen_set_label(l1);
4456 22e0e173 aurel32
    tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
4457 22e0e173 aurel32
    gen_set_label(l2);
4458 22e0e173 aurel32
    if (unlikely(Rc(ctx->opcode) != 0))
4459 22e0e173 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4460 76a66253 j_mayer
}
4461 76a66253 j_mayer
4462 76a66253 j_mayer
/* lscbx - lscbx. */
4463 99e300ef Blue Swirl
static void gen_lscbx(DisasContext *ctx)
4464 76a66253 j_mayer
{
4465 bdb4b689 aurel32
    TCGv t0 = tcg_temp_new();
4466 bdb4b689 aurel32
    TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode));
4467 bdb4b689 aurel32
    TCGv_i32 t2 = tcg_const_i32(rA(ctx->opcode));
4468 bdb4b689 aurel32
    TCGv_i32 t3 = tcg_const_i32(rB(ctx->opcode));
4469 76a66253 j_mayer
4470 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
4471 76a66253 j_mayer
    /* NIP cannot be restored if the memory exception comes from an helper */
4472 d9bce9d9 j_mayer
    gen_update_nip(ctx, ctx->nip - 4);
4473 bdb4b689 aurel32
    gen_helper_lscbx(t0, t0, t1, t2, t3);
4474 bdb4b689 aurel32
    tcg_temp_free_i32(t1);
4475 bdb4b689 aurel32
    tcg_temp_free_i32(t2);
4476 bdb4b689 aurel32
    tcg_temp_free_i32(t3);
4477 3d7b417e aurel32
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
4478 bdb4b689 aurel32
    tcg_gen_or_tl(cpu_xer, cpu_xer, t0);
4479 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4480 bdb4b689 aurel32
        gen_set_Rc0(ctx, t0);
4481 bdb4b689 aurel32
    tcg_temp_free(t0);
4482 76a66253 j_mayer
}
4483 76a66253 j_mayer
4484 76a66253 j_mayer
/* maskg - maskg. */
4485 99e300ef Blue Swirl
static void gen_maskg(DisasContext *ctx)
4486 76a66253 j_mayer
{
4487 22e0e173 aurel32
    int l1 = gen_new_label();
4488 22e0e173 aurel32
    TCGv t0 = tcg_temp_new();
4489 22e0e173 aurel32
    TCGv t1 = tcg_temp_new();
4490 22e0e173 aurel32
    TCGv t2 = tcg_temp_new();
4491 22e0e173 aurel32
    TCGv t3 = tcg_temp_new();
4492 22e0e173 aurel32
    tcg_gen_movi_tl(t3, 0xFFFFFFFF);
4493 22e0e173 aurel32
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4494 22e0e173 aurel32
    tcg_gen_andi_tl(t1, cpu_gpr[rS(ctx->opcode)], 0x1F);
4495 22e0e173 aurel32
    tcg_gen_addi_tl(t2, t0, 1);
4496 22e0e173 aurel32
    tcg_gen_shr_tl(t2, t3, t2);
4497 22e0e173 aurel32
    tcg_gen_shr_tl(t3, t3, t1);
4498 22e0e173 aurel32
    tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], t2, t3);
4499 22e0e173 aurel32
    tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4500 22e0e173 aurel32
    tcg_gen_neg_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4501 22e0e173 aurel32
    gen_set_label(l1);
4502 22e0e173 aurel32
    tcg_temp_free(t0);
4503 22e0e173 aurel32
    tcg_temp_free(t1);
4504 22e0e173 aurel32
    tcg_temp_free(t2);
4505 22e0e173 aurel32
    tcg_temp_free(t3);
4506 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4507 22e0e173 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4508 76a66253 j_mayer
}
4509 76a66253 j_mayer
4510 76a66253 j_mayer
/* maskir - maskir. */
4511 99e300ef Blue Swirl
static void gen_maskir(DisasContext *ctx)
4512 76a66253 j_mayer
{
4513 22e0e173 aurel32
    TCGv t0 = tcg_temp_new();
4514 22e0e173 aurel32
    TCGv t1 = tcg_temp_new();
4515 22e0e173 aurel32
    tcg_gen_and_tl(t0, cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4516 22e0e173 aurel32
    tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4517 22e0e173 aurel32
    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4518 22e0e173 aurel32
    tcg_temp_free(t0);
4519 22e0e173 aurel32
    tcg_temp_free(t1);
4520 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4521 22e0e173 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4522 76a66253 j_mayer
}
4523 76a66253 j_mayer
4524 76a66253 j_mayer
/* mul - mul. */
4525 99e300ef Blue Swirl
static void gen_mul(DisasContext *ctx)
4526 76a66253 j_mayer
{
4527 22e0e173 aurel32
    TCGv_i64 t0 = tcg_temp_new_i64();
4528 22e0e173 aurel32
    TCGv_i64 t1 = tcg_temp_new_i64();
4529 22e0e173 aurel32
    TCGv t2 = tcg_temp_new();
4530 22e0e173 aurel32
    tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
4531 22e0e173 aurel32
    tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
4532 22e0e173 aurel32
    tcg_gen_mul_i64(t0, t0, t1);
4533 22e0e173 aurel32
    tcg_gen_trunc_i64_tl(t2, t0);
4534 22e0e173 aurel32
    gen_store_spr(SPR_MQ, t2);
4535 22e0e173 aurel32
    tcg_gen_shri_i64(t1, t0, 32);
4536 22e0e173 aurel32
    tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
4537 22e0e173 aurel32
    tcg_temp_free_i64(t0);
4538 22e0e173 aurel32
    tcg_temp_free_i64(t1);
4539 22e0e173 aurel32
    tcg_temp_free(t2);
4540 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4541 22e0e173 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4542 76a66253 j_mayer
}
4543 76a66253 j_mayer
4544 76a66253 j_mayer
/* mulo - mulo. */
4545 99e300ef Blue Swirl
static void gen_mulo(DisasContext *ctx)
4546 76a66253 j_mayer
{
4547 22e0e173 aurel32
    int l1 = gen_new_label();
4548 22e0e173 aurel32
    TCGv_i64 t0 = tcg_temp_new_i64();
4549 22e0e173 aurel32
    TCGv_i64 t1 = tcg_temp_new_i64();
4550 22e0e173 aurel32
    TCGv t2 = tcg_temp_new();
4551 22e0e173 aurel32
    /* Start with XER OV disabled, the most likely case */
4552 22e0e173 aurel32
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
4553 22e0e173 aurel32
    tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
4554 22e0e173 aurel32
    tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
4555 22e0e173 aurel32
    tcg_gen_mul_i64(t0, t0, t1);
4556 22e0e173 aurel32
    tcg_gen_trunc_i64_tl(t2, t0);
4557 22e0e173 aurel32
    gen_store_spr(SPR_MQ, t2);
4558 22e0e173 aurel32
    tcg_gen_shri_i64(t1, t0, 32);
4559 22e0e173 aurel32
    tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
4560 22e0e173 aurel32
    tcg_gen_ext32s_i64(t1, t0);
4561 22e0e173 aurel32
    tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
4562 22e0e173 aurel32
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
4563 22e0e173 aurel32
    gen_set_label(l1);
4564 22e0e173 aurel32
    tcg_temp_free_i64(t0);
4565 22e0e173 aurel32
    tcg_temp_free_i64(t1);
4566 22e0e173 aurel32
    tcg_temp_free(t2);
4567 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4568 22e0e173 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4569 76a66253 j_mayer
}
4570 76a66253 j_mayer
4571 76a66253 j_mayer
/* nabs - nabs. */
4572 99e300ef Blue Swirl
static void gen_nabs(DisasContext *ctx)
4573 76a66253 j_mayer
{
4574 22e0e173 aurel32
    int l1 = gen_new_label();
4575 22e0e173 aurel32
    int l2 = gen_new_label();
4576 22e0e173 aurel32
    tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
4577 22e0e173 aurel32
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4578 22e0e173 aurel32
    tcg_gen_br(l2);
4579 22e0e173 aurel32
    gen_set_label(l1);
4580 22e0e173 aurel32
    tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4581 22e0e173 aurel32
    gen_set_label(l2);
4582 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4583 22e0e173 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4584 76a66253 j_mayer
}
4585 76a66253 j_mayer
4586 76a66253 j_mayer
/* nabso - nabso. */
4587 99e300ef Blue Swirl
static void gen_nabso(DisasContext *ctx)
4588 76a66253 j_mayer
{
4589 22e0e173 aurel32
    int l1 = gen_new_label();
4590 22e0e173 aurel32
    int l2 = gen_new_label();
4591 22e0e173 aurel32
    tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
4592 22e0e173 aurel32
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4593 22e0e173 aurel32
    tcg_gen_br(l2);
4594 22e0e173 aurel32
    gen_set_label(l1);
4595 22e0e173 aurel32
    tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4596 22e0e173 aurel32
    gen_set_label(l2);
4597 22e0e173 aurel32
    /* nabs never overflows */
4598 22e0e173 aurel32
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
4599 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4600 22e0e173 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4601 76a66253 j_mayer
}
4602 76a66253 j_mayer
4603 76a66253 j_mayer
/* rlmi - rlmi. */
4604 99e300ef Blue Swirl
static void gen_rlmi(DisasContext *ctx)
4605 76a66253 j_mayer
{
4606 7487953d aurel32
    uint32_t mb = MB(ctx->opcode);
4607 7487953d aurel32
    uint32_t me = ME(ctx->opcode);
4608 7487953d aurel32
    TCGv t0 = tcg_temp_new();
4609 7487953d aurel32
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4610 7487953d aurel32
    tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4611 7487953d aurel32
    tcg_gen_andi_tl(t0, t0, MASK(mb, me));
4612 7487953d aurel32
    tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~MASK(mb, me));
4613 7487953d aurel32
    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], t0);
4614 7487953d aurel32
    tcg_temp_free(t0);
4615 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4616 7487953d aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4617 76a66253 j_mayer
}
4618 76a66253 j_mayer
4619 76a66253 j_mayer
/* rrib - rrib. */
4620 99e300ef Blue Swirl
static void gen_rrib(DisasContext *ctx)
4621 76a66253 j_mayer
{
4622 7487953d aurel32
    TCGv t0 = tcg_temp_new();
4623 7487953d aurel32
    TCGv t1 = tcg_temp_new();
4624 7487953d aurel32
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4625 7487953d aurel32
    tcg_gen_movi_tl(t1, 0x80000000);
4626 7487953d aurel32
    tcg_gen_shr_tl(t1, t1, t0);
4627 7487953d aurel32
    tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4628 7487953d aurel32
    tcg_gen_and_tl(t0, t0, t1);
4629 7487953d aurel32
    tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], t1);
4630 7487953d aurel32
    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4631 7487953d aurel32
    tcg_temp_free(t0);
4632 7487953d aurel32
    tcg_temp_free(t1);
4633 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4634 7487953d aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4635 76a66253 j_mayer
}
4636 76a66253 j_mayer
4637 76a66253 j_mayer
/* sle - sle. */
4638 99e300ef Blue Swirl
static void gen_sle(DisasContext *ctx)
4639 76a66253 j_mayer
{
4640 7487953d aurel32
    TCGv t0 = tcg_temp_new();
4641 7487953d aurel32
    TCGv t1 = tcg_temp_new();
4642 7487953d aurel32
    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
4643 7487953d aurel32
    tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
4644 7487953d aurel32
    tcg_gen_subfi_tl(t1, 32, t1);
4645 7487953d aurel32
    tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
4646 7487953d aurel32
    tcg_gen_or_tl(t1, t0, t1);
4647 7487953d aurel32
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4648 7487953d aurel32
    gen_store_spr(SPR_MQ, t1);
4649 7487953d aurel32
    tcg_temp_free(t0);
4650 7487953d aurel32
    tcg_temp_free(t1);
4651 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4652 7487953d aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4653 76a66253 j_mayer
}
4654 76a66253 j_mayer
4655 76a66253 j_mayer
/* sleq - sleq. */
4656 99e300ef Blue Swirl
static void gen_sleq(DisasContext *ctx)
4657 76a66253 j_mayer
{
4658 7487953d aurel32
    TCGv t0 = tcg_temp_new();
4659 7487953d aurel32
    TCGv t1 = tcg_temp_new();
4660 7487953d aurel32
    TCGv t2 = tcg_temp_new();
4661 7487953d aurel32
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4662 7487953d aurel32
    tcg_gen_movi_tl(t2, 0xFFFFFFFF);
4663 7487953d aurel32
    tcg_gen_shl_tl(t2, t2, t0);
4664 7487953d aurel32
    tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4665 7487953d aurel32
    gen_load_spr(t1, SPR_MQ);
4666 7487953d aurel32
    gen_store_spr(SPR_MQ, t0);
4667 7487953d aurel32
    tcg_gen_and_tl(t0, t0, t2);
4668 7487953d aurel32
    tcg_gen_andc_tl(t1, t1, t2);
4669 7487953d aurel32
    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4670 7487953d aurel32
    tcg_temp_free(t0);
4671 7487953d aurel32
    tcg_temp_free(t1);
4672 7487953d aurel32
    tcg_temp_free(t2);
4673 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4674 7487953d aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4675 76a66253 j_mayer
}
4676 76a66253 j_mayer
4677 76a66253 j_mayer
/* sliq - sliq. */
4678 99e300ef Blue Swirl
static void gen_sliq(DisasContext *ctx)
4679 76a66253 j_mayer
{
4680 7487953d aurel32
    int sh = SH(ctx->opcode);
4681 7487953d aurel32
    TCGv t0 = tcg_temp_new();
4682 7487953d aurel32
    TCGv t1 = tcg_temp_new();
4683 7487953d aurel32
    tcg_gen_shli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
4684 7487953d aurel32
    tcg_gen_shri_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
4685 7487953d aurel32
    tcg_gen_or_tl(t1, t0, t1);
4686 7487953d aurel32
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4687 7487953d aurel32
    gen_store_spr(SPR_MQ, t1);
4688 7487953d aurel32
    tcg_temp_free(t0);
4689 7487953d aurel32
    tcg_temp_free(t1);
4690 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4691 7487953d aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4692 76a66253 j_mayer
}
4693 76a66253 j_mayer
4694 76a66253 j_mayer
/* slliq - slliq. */
4695 99e300ef Blue Swirl
static void gen_slliq(DisasContext *ctx)
4696 76a66253 j_mayer
{
4697 7487953d aurel32
    int sh = SH(ctx->opcode);
4698 7487953d aurel32
    TCGv t0 = tcg_temp_new();
4699 7487953d aurel32
    TCGv t1 = tcg_temp_new();
4700 7487953d aurel32
    tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
4701 7487953d aurel32
    gen_load_spr(t1, SPR_MQ);
4702 7487953d aurel32
    gen_store_spr(SPR_MQ, t0);
4703 7487953d aurel32
    tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU << sh));
4704 7487953d aurel32
    tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU << sh));
4705 7487953d aurel32
    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4706 7487953d aurel32
    tcg_temp_free(t0);
4707 7487953d aurel32
    tcg_temp_free(t1);
4708 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4709 7487953d aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4710 76a66253 j_mayer
}
4711 76a66253 j_mayer
4712 76a66253 j_mayer
/* sllq - sllq. */
4713 99e300ef Blue Swirl
static void gen_sllq(DisasContext *ctx)
4714 76a66253 j_mayer
{
4715 7487953d aurel32
    int l1 = gen_new_label();
4716 7487953d aurel32
    int l2 = gen_new_label();
4717 7487953d aurel32
    TCGv t0 = tcg_temp_local_new();
4718 7487953d aurel32
    TCGv t1 = tcg_temp_local_new();
4719 7487953d aurel32
    TCGv t2 = tcg_temp_local_new();
4720 7487953d aurel32
    tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
4721 7487953d aurel32
    tcg_gen_movi_tl(t1, 0xFFFFFFFF);
4722 7487953d aurel32
    tcg_gen_shl_tl(t1, t1, t2);
4723 7487953d aurel32
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
4724 7487953d aurel32
    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
4725 7487953d aurel32
    gen_load_spr(t0, SPR_MQ);
4726 7487953d aurel32
    tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4727 7487953d aurel32
    tcg_gen_br(l2);
4728 7487953d aurel32
    gen_set_label(l1);
4729 7487953d aurel32
    tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
4730 7487953d aurel32
    gen_load_spr(t2, SPR_MQ);
4731 7487953d aurel32
    tcg_gen_andc_tl(t1, t2, t1);
4732 7487953d aurel32
    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4733 7487953d aurel32
    gen_set_label(l2);
4734 7487953d aurel32
    tcg_temp_free(t0);
4735 7487953d aurel32
    tcg_temp_free(t1);
4736 7487953d aurel32
    tcg_temp_free(t2);
4737 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4738 7487953d aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4739 76a66253 j_mayer
}
4740 76a66253 j_mayer
4741 76a66253 j_mayer
/* slq - slq. */
4742 99e300ef Blue Swirl
static void gen_slq(DisasContext *ctx)
4743 76a66253 j_mayer
{
4744 7487953d aurel32
    int l1 = gen_new_label();
4745 7487953d aurel32
    TCGv t0 = tcg_temp_new();
4746 7487953d aurel32
    TCGv t1 = tcg_temp_new();
4747 7487953d aurel32
    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
4748 7487953d aurel32
    tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
4749 7487953d aurel32
    tcg_gen_subfi_tl(t1, 32, t1);
4750 7487953d aurel32
    tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
4751 7487953d aurel32
    tcg_gen_or_tl(t1, t0, t1);
4752 7487953d aurel32
    gen_store_spr(SPR_MQ, t1);
4753 7487953d aurel32
    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
4754 7487953d aurel32
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4755 7487953d aurel32
    tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4756 7487953d aurel32
    tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
4757 7487953d aurel32
    gen_set_label(l1);
4758 7487953d aurel32
    tcg_temp_free(t0);
4759 7487953d aurel32
    tcg_temp_free(t1);
4760 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4761 7487953d aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4762 76a66253 j_mayer
}
4763 76a66253 j_mayer
4764 d9bce9d9 j_mayer
/* sraiq - sraiq. */
4765 99e300ef Blue Swirl
static void gen_sraiq(DisasContext *ctx)
4766 76a66253 j_mayer
{
4767 7487953d aurel32
    int sh = SH(ctx->opcode);
4768 7487953d aurel32
    int l1 = gen_new_label();
4769 7487953d aurel32
    TCGv t0 = tcg_temp_new();
4770 7487953d aurel32
    TCGv t1 = tcg_temp_new();
4771 7487953d aurel32
    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
4772 7487953d aurel32
    tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
4773 7487953d aurel32
    tcg_gen_or_tl(t0, t0, t1);
4774 7487953d aurel32
    gen_store_spr(SPR_MQ, t0);
4775 7487953d aurel32
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
4776 7487953d aurel32
    tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4777 7487953d aurel32
    tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
4778 7487953d aurel32
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_CA));
4779 7487953d aurel32
    gen_set_label(l1);
4780 7487953d aurel32
    tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
4781 7487953d aurel32
    tcg_temp_free(t0);
4782 7487953d aurel32
    tcg_temp_free(t1);
4783 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4784 7487953d aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4785 76a66253 j_mayer
}
4786 76a66253 j_mayer
4787 76a66253 j_mayer
/* sraq - sraq. */
4788 99e300ef Blue Swirl
static void gen_sraq(DisasContext *ctx)
4789 76a66253 j_mayer
{
4790 7487953d aurel32
    int l1 = gen_new_label();
4791 7487953d aurel32
    int l2 = gen_new_label();
4792 7487953d aurel32
    TCGv t0 = tcg_temp_new();
4793 7487953d aurel32
    TCGv t1 = tcg_temp_local_new();
4794 7487953d aurel32
    TCGv t2 = tcg_temp_local_new();
4795 7487953d aurel32
    tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
4796 7487953d aurel32
    tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
4797 7487953d aurel32
    tcg_gen_sar_tl(t1, cpu_gpr[rS(ctx->opcode)], t2);
4798 7487953d aurel32
    tcg_gen_subfi_tl(t2, 32, t2);
4799 7487953d aurel32
    tcg_gen_shl_tl(t2, cpu_gpr[rS(ctx->opcode)], t2);
4800 7487953d aurel32
    tcg_gen_or_tl(t0, t0, t2);
4801 7487953d aurel32
    gen_store_spr(SPR_MQ, t0);
4802 7487953d aurel32
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
4803 7487953d aurel32
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l1);
4804 7487953d aurel32
    tcg_gen_mov_tl(t2, cpu_gpr[rS(ctx->opcode)]);
4805 7487953d aurel32
    tcg_gen_sari_tl(t1, cpu_gpr[rS(ctx->opcode)], 31);
4806 7487953d aurel32
    gen_set_label(l1);
4807 7487953d aurel32
    tcg_temp_free(t0);
4808 7487953d aurel32
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1);
4809 7487953d aurel32
    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
4810 7487953d aurel32
    tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
4811 7487953d aurel32
    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l2);
4812 7487953d aurel32
    tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_CA));
4813 7487953d aurel32
    gen_set_label(l2);
4814 7487953d aurel32
    tcg_temp_free(t1);
4815 7487953d aurel32
    tcg_temp_free(t2);
4816 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4817 7487953d aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4818 76a66253 j_mayer
}
4819 76a66253 j_mayer
4820 76a66253 j_mayer
/* sre - sre. */
4821 99e300ef Blue Swirl
static void gen_sre(DisasContext *ctx)
4822 76a66253 j_mayer
{
4823 7487953d aurel32
    TCGv t0 = tcg_temp_new();
4824 7487953d aurel32
    TCGv t1 = tcg_temp_new();
4825 7487953d aurel32
    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
4826 7487953d aurel32
    tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
4827 7487953d aurel32
    tcg_gen_subfi_tl(t1, 32, t1);
4828 7487953d aurel32
    tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
4829 7487953d aurel32
    tcg_gen_or_tl(t1, t0, t1);
4830 7487953d aurel32
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4831 7487953d aurel32
    gen_store_spr(SPR_MQ, t1);
4832 7487953d aurel32
    tcg_temp_free(t0);
4833 7487953d aurel32
    tcg_temp_free(t1);
4834 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4835 7487953d aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4836 76a66253 j_mayer
}
4837 76a66253 j_mayer
4838 76a66253 j_mayer
/* srea - srea. */
4839 99e300ef Blue Swirl
static void gen_srea(DisasContext *ctx)
4840 76a66253 j_mayer
{
4841 7487953d aurel32
    TCGv t0 = tcg_temp_new();
4842 7487953d aurel32
    TCGv t1 = tcg_temp_new();
4843 7487953d aurel32
    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
4844 7487953d aurel32
    tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
4845 7487953d aurel32
    gen_store_spr(SPR_MQ, t0);
4846 7487953d aurel32
    tcg_gen_sar_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t1);
4847 7487953d aurel32
    tcg_temp_free(t0);
4848 7487953d aurel32
    tcg_temp_free(t1);
4849 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4850 7487953d aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4851 76a66253 j_mayer
}
4852 76a66253 j_mayer
4853 76a66253 j_mayer
/* sreq */
4854 99e300ef Blue Swirl
static void gen_sreq(DisasContext *ctx)
4855 76a66253 j_mayer
{
4856 7487953d aurel32
    TCGv t0 = tcg_temp_new();
4857 7487953d aurel32
    TCGv t1 = tcg_temp_new();
4858 7487953d aurel32
    TCGv t2 = tcg_temp_new();
4859 7487953d aurel32
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4860 7487953d aurel32
    tcg_gen_movi_tl(t1, 0xFFFFFFFF);
4861 7487953d aurel32
    tcg_gen_shr_tl(t1, t1, t0);
4862 7487953d aurel32
    tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4863 7487953d aurel32
    gen_load_spr(t2, SPR_MQ);
4864 7487953d aurel32
    gen_store_spr(SPR_MQ, t0);
4865 7487953d aurel32
    tcg_gen_and_tl(t0, t0, t1);
4866 7487953d aurel32
    tcg_gen_andc_tl(t2, t2, t1);
4867 7487953d aurel32
    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
4868 7487953d aurel32
    tcg_temp_free(t0);
4869 7487953d aurel32
    tcg_temp_free(t1);
4870 7487953d aurel32
    tcg_temp_free(t2);
4871 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4872 7487953d aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4873 76a66253 j_mayer
}
4874 76a66253 j_mayer
4875 76a66253 j_mayer
/* sriq */
4876 99e300ef Blue Swirl
static void gen_sriq(DisasContext *ctx)
4877 76a66253 j_mayer
{
4878 7487953d aurel32
    int sh = SH(ctx->opcode);
4879 7487953d aurel32
    TCGv t0 = tcg_temp_new();
4880 7487953d aurel32
    TCGv t1 = tcg_temp_new();
4881 7487953d aurel32
    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
4882 7487953d aurel32
    tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
4883 7487953d aurel32
    tcg_gen_or_tl(t1, t0, t1);
4884 7487953d aurel32
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4885 7487953d aurel32
    gen_store_spr(SPR_MQ, t1);
4886 7487953d aurel32
    tcg_temp_free(t0);
4887 7487953d aurel32
    tcg_temp_free(t1);
4888 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4889 7487953d aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4890 76a66253 j_mayer
}
4891 76a66253 j_mayer
4892 76a66253 j_mayer
/* srliq */
4893 99e300ef Blue Swirl
static void gen_srliq(DisasContext *ctx)
4894 76a66253 j_mayer
{
4895 7487953d aurel32
    int sh = SH(ctx->opcode);
4896 7487953d aurel32
    TCGv t0 = tcg_temp_new();
4897 7487953d aurel32
    TCGv t1 = tcg_temp_new();
4898 7487953d aurel32
    tcg_gen_rotri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
4899 7487953d aurel32
    gen_load_spr(t1, SPR_MQ);
4900 7487953d aurel32
    gen_store_spr(SPR_MQ, t0);
4901 7487953d aurel32
    tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU >> sh));
4902 7487953d aurel32
    tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU >> sh));
4903 7487953d aurel32
    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4904 7487953d aurel32
    tcg_temp_free(t0);
4905 7487953d aurel32
    tcg_temp_free(t1);
4906 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4907 7487953d aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4908 76a66253 j_mayer
}
4909 76a66253 j_mayer
4910 76a66253 j_mayer
/* srlq */
4911 99e300ef Blue Swirl
static void gen_srlq(DisasContext *ctx)
4912 76a66253 j_mayer
{
4913 7487953d aurel32
    int l1 = gen_new_label();
4914 7487953d aurel32
    int l2 = gen_new_label();
4915 7487953d aurel32
    TCGv t0 = tcg_temp_local_new();
4916 7487953d aurel32
    TCGv t1 = tcg_temp_local_new();
4917 7487953d aurel32
    TCGv t2 = tcg_temp_local_new();
4918 7487953d aurel32
    tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
4919 7487953d aurel32
    tcg_gen_movi_tl(t1, 0xFFFFFFFF);
4920 7487953d aurel32
    tcg_gen_shr_tl(t2, t1, t2);
4921 7487953d aurel32
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
4922 7487953d aurel32
    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
4923 7487953d aurel32
    gen_load_spr(t0, SPR_MQ);
4924 7487953d aurel32
    tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
4925 7487953d aurel32
    tcg_gen_br(l2);
4926 7487953d aurel32
    gen_set_label(l1);
4927 7487953d aurel32
    tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
4928 7487953d aurel32
    tcg_gen_and_tl(t0, t0, t2);
4929 7487953d aurel32
    gen_load_spr(t1, SPR_MQ);
4930 7487953d aurel32
    tcg_gen_andc_tl(t1, t1, t2);
4931 7487953d aurel32
    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4932 7487953d aurel32
    gen_set_label(l2);
4933 7487953d aurel32
    tcg_temp_free(t0);
4934 7487953d aurel32
    tcg_temp_free(t1);
4935 7487953d aurel32
    tcg_temp_free(t2);
4936 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4937 7487953d aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4938 76a66253 j_mayer
}
4939 76a66253 j_mayer
4940 76a66253 j_mayer
/* srq */
4941 99e300ef Blue Swirl
static void gen_srq(DisasContext *ctx)
4942 76a66253 j_mayer
{
4943 7487953d aurel32
    int l1 = gen_new_label();
4944 7487953d aurel32
    TCGv t0 = tcg_temp_new();
4945 7487953d aurel32
    TCGv t1 = tcg_temp_new();
4946 7487953d aurel32
    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
4947 7487953d aurel32
    tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
4948 7487953d aurel32
    tcg_gen_subfi_tl(t1, 32, t1);
4949 7487953d aurel32
    tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
4950 7487953d aurel32
    tcg_gen_or_tl(t1, t0, t1);
4951 7487953d aurel32
    gen_store_spr(SPR_MQ, t1);
4952 7487953d aurel32
    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
4953 7487953d aurel32
    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4954 7487953d aurel32
    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
4955 7487953d aurel32
    tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
4956 7487953d aurel32
    gen_set_label(l1);
4957 7487953d aurel32
    tcg_temp_free(t0);
4958 7487953d aurel32
    tcg_temp_free(t1);
4959 76a66253 j_mayer
    if (unlikely(Rc(ctx->opcode) != 0))
4960 7487953d aurel32
        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4961 76a66253 j_mayer
}
4962 76a66253 j_mayer
4963 76a66253 j_mayer
/* PowerPC 602 specific instructions */
4964 99e300ef Blue Swirl
4965 54623277 Blue Swirl
/* dsa  */
4966 99e300ef Blue Swirl
static void gen_dsa(DisasContext *ctx)
4967 76a66253 j_mayer
{
4968 76a66253 j_mayer
    /* XXX: TODO */
4969 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
4970 76a66253 j_mayer
}
4971 76a66253 j_mayer
4972 76a66253 j_mayer
/* esa */
4973 99e300ef Blue Swirl
static void gen_esa(DisasContext *ctx)
4974 76a66253 j_mayer
{
4975 76a66253 j_mayer
    /* XXX: TODO */
4976 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
4977 76a66253 j_mayer
}
4978 76a66253 j_mayer
4979 76a66253 j_mayer
/* mfrom */
4980 99e300ef Blue Swirl
static void gen_mfrom(DisasContext *ctx)
4981 76a66253 j_mayer
{
4982 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4983 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4984 76a66253 j_mayer
#else
4985 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
4986 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
4987 76a66253 j_mayer
        return;
4988 76a66253 j_mayer
    }
4989 cf02a65c aurel32
    gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4990 76a66253 j_mayer
#endif
4991 76a66253 j_mayer
}
4992 76a66253 j_mayer
4993 76a66253 j_mayer
/* 602 - 603 - G2 TLB management */
4994 e8eaa2c0 Blue Swirl
4995 54623277 Blue Swirl
/* tlbld */
4996 e8eaa2c0 Blue Swirl
static void gen_tlbld_6xx(DisasContext *ctx)
4997 76a66253 j_mayer
{
4998 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
4999 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5000 76a66253 j_mayer
#else
5001 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5002 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5003 76a66253 j_mayer
        return;
5004 76a66253 j_mayer
    }
5005 74d37793 aurel32
    gen_helper_6xx_tlbd(cpu_gpr[rB(ctx->opcode)]);
5006 76a66253 j_mayer
#endif
5007 76a66253 j_mayer
}
5008 76a66253 j_mayer
5009 76a66253 j_mayer
/* tlbli */
5010 e8eaa2c0 Blue Swirl
static void gen_tlbli_6xx(DisasContext *ctx)
5011 76a66253 j_mayer
{
5012 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5013 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5014 76a66253 j_mayer
#else
5015 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5016 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5017 76a66253 j_mayer
        return;
5018 76a66253 j_mayer
    }
5019 74d37793 aurel32
    gen_helper_6xx_tlbi(cpu_gpr[rB(ctx->opcode)]);
5020 76a66253 j_mayer
#endif
5021 76a66253 j_mayer
}
5022 76a66253 j_mayer
5023 7dbe11ac j_mayer
/* 74xx TLB management */
5024 e8eaa2c0 Blue Swirl
5025 54623277 Blue Swirl
/* tlbld */
5026 e8eaa2c0 Blue Swirl
static void gen_tlbld_74xx(DisasContext *ctx)
5027 7dbe11ac j_mayer
{
5028 7dbe11ac j_mayer
#if defined(CONFIG_USER_ONLY)
5029 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5030 7dbe11ac j_mayer
#else
5031 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5032 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5033 7dbe11ac j_mayer
        return;
5034 7dbe11ac j_mayer
    }
5035 74d37793 aurel32
    gen_helper_74xx_tlbd(cpu_gpr[rB(ctx->opcode)]);
5036 7dbe11ac j_mayer
#endif
5037 7dbe11ac j_mayer
}
5038 7dbe11ac j_mayer
5039 7dbe11ac j_mayer
/* tlbli */
5040 e8eaa2c0 Blue Swirl
static void gen_tlbli_74xx(DisasContext *ctx)
5041 7dbe11ac j_mayer
{
5042 7dbe11ac j_mayer
#if defined(CONFIG_USER_ONLY)
5043 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5044 7dbe11ac j_mayer
#else
5045 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5046 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5047 7dbe11ac j_mayer
        return;
5048 7dbe11ac j_mayer
    }
5049 74d37793 aurel32
    gen_helper_74xx_tlbi(cpu_gpr[rB(ctx->opcode)]);
5050 7dbe11ac j_mayer
#endif
5051 7dbe11ac j_mayer
}
5052 7dbe11ac j_mayer
5053 76a66253 j_mayer
/* POWER instructions not in PowerPC 601 */
5054 99e300ef Blue Swirl
5055 54623277 Blue Swirl
/* clf */
5056 99e300ef Blue Swirl
static void gen_clf(DisasContext *ctx)
5057 76a66253 j_mayer
{
5058 76a66253 j_mayer
    /* Cache line flush: implemented as no-op */
5059 76a66253 j_mayer
}
5060 76a66253 j_mayer
5061 76a66253 j_mayer
/* cli */
5062 99e300ef Blue Swirl
static void gen_cli(DisasContext *ctx)
5063 76a66253 j_mayer
{
5064 7f75ffd3 blueswir1
    /* Cache line invalidate: privileged and treated as no-op */
5065 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5066 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5067 76a66253 j_mayer
#else
5068 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5069 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5070 76a66253 j_mayer
        return;
5071 76a66253 j_mayer
    }
5072 76a66253 j_mayer
#endif
5073 76a66253 j_mayer
}
5074 76a66253 j_mayer
5075 76a66253 j_mayer
/* dclst */
5076 99e300ef Blue Swirl
static void gen_dclst(DisasContext *ctx)
5077 76a66253 j_mayer
{
5078 76a66253 j_mayer
    /* Data cache line store: treated as no-op */
5079 76a66253 j_mayer
}
5080 76a66253 j_mayer
5081 99e300ef Blue Swirl
static void gen_mfsri(DisasContext *ctx)
5082 76a66253 j_mayer
{
5083 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5084 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5085 76a66253 j_mayer
#else
5086 74d37793 aurel32
    int ra = rA(ctx->opcode);
5087 74d37793 aurel32
    int rd = rD(ctx->opcode);
5088 74d37793 aurel32
    TCGv t0;
5089 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5090 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5091 76a66253 j_mayer
        return;
5092 76a66253 j_mayer
    }
5093 74d37793 aurel32
    t0 = tcg_temp_new();
5094 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
5095 74d37793 aurel32
    tcg_gen_shri_tl(t0, t0, 28);
5096 74d37793 aurel32
    tcg_gen_andi_tl(t0, t0, 0xF);
5097 74d37793 aurel32
    gen_helper_load_sr(cpu_gpr[rd], t0);
5098 74d37793 aurel32
    tcg_temp_free(t0);
5099 76a66253 j_mayer
    if (ra != 0 && ra != rd)
5100 74d37793 aurel32
        tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);
5101 76a66253 j_mayer
#endif
5102 76a66253 j_mayer
}
5103 76a66253 j_mayer
5104 99e300ef Blue Swirl
static void gen_rac(DisasContext *ctx)
5105 76a66253 j_mayer
{
5106 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5107 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5108 76a66253 j_mayer
#else
5109 22e0e173 aurel32
    TCGv t0;
5110 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5111 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5112 76a66253 j_mayer
        return;
5113 76a66253 j_mayer
    }
5114 22e0e173 aurel32
    t0 = tcg_temp_new();
5115 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
5116 22e0e173 aurel32
    gen_helper_rac(cpu_gpr[rD(ctx->opcode)], t0);
5117 22e0e173 aurel32
    tcg_temp_free(t0);
5118 76a66253 j_mayer
#endif
5119 76a66253 j_mayer
}
5120 76a66253 j_mayer
5121 99e300ef Blue Swirl
static void gen_rfsvc(DisasContext *ctx)
5122 76a66253 j_mayer
{
5123 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5124 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5125 76a66253 j_mayer
#else
5126 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5127 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5128 76a66253 j_mayer
        return;
5129 76a66253 j_mayer
    }
5130 d72a19f7 aurel32
    gen_helper_rfsvc();
5131 e06fcd75 aurel32
    gen_sync_exception(ctx);
5132 76a66253 j_mayer
#endif
5133 76a66253 j_mayer
}
5134 76a66253 j_mayer
5135 76a66253 j_mayer
/* svc is not implemented for now */
5136 76a66253 j_mayer
5137 76a66253 j_mayer
/* POWER2 specific instructions */
5138 76a66253 j_mayer
/* Quad manipulation (load/store two floats at a time) */
5139 76a66253 j_mayer
5140 76a66253 j_mayer
/* lfq */
5141 99e300ef Blue Swirl
static void gen_lfq(DisasContext *ctx)
5142 76a66253 j_mayer
{
5143 01a4afeb aurel32
    int rd = rD(ctx->opcode);
5144 76db3ba4 aurel32
    TCGv t0;
5145 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_FLOAT);
5146 76db3ba4 aurel32
    t0 = tcg_temp_new();
5147 76db3ba4 aurel32
    gen_addr_imm_index(ctx, t0, 0);
5148 76db3ba4 aurel32
    gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5149 76db3ba4 aurel32
    gen_addr_add(ctx, t0, t0, 8);
5150 76db3ba4 aurel32
    gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5151 01a4afeb aurel32
    tcg_temp_free(t0);
5152 76a66253 j_mayer
}
5153 76a66253 j_mayer
5154 76a66253 j_mayer
/* lfqu */
5155 99e300ef Blue Swirl
static void gen_lfqu(DisasContext *ctx)
5156 76a66253 j_mayer
{
5157 76a66253 j_mayer
    int ra = rA(ctx->opcode);
5158 01a4afeb aurel32
    int rd = rD(ctx->opcode);
5159 76db3ba4 aurel32
    TCGv t0, t1;
5160 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_FLOAT);
5161 76db3ba4 aurel32
    t0 = tcg_temp_new();
5162 76db3ba4 aurel32
    t1 = tcg_temp_new();
5163 76db3ba4 aurel32
    gen_addr_imm_index(ctx, t0, 0);
5164 76db3ba4 aurel32
    gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5165 76db3ba4 aurel32
    gen_addr_add(ctx, t1, t0, 8);
5166 76db3ba4 aurel32
    gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5167 76a66253 j_mayer
    if (ra != 0)
5168 01a4afeb aurel32
        tcg_gen_mov_tl(cpu_gpr[ra], t0);
5169 01a4afeb aurel32
    tcg_temp_free(t0);
5170 01a4afeb aurel32
    tcg_temp_free(t1);
5171 76a66253 j_mayer
}
5172 76a66253 j_mayer
5173 76a66253 j_mayer
/* lfqux */
5174 99e300ef Blue Swirl
static void gen_lfqux(DisasContext *ctx)
5175 76a66253 j_mayer
{
5176 76a66253 j_mayer
    int ra = rA(ctx->opcode);
5177 01a4afeb aurel32
    int rd = rD(ctx->opcode);
5178 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_FLOAT);
5179 76db3ba4 aurel32
    TCGv t0, t1;
5180 76db3ba4 aurel32
    t0 = tcg_temp_new();
5181 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
5182 76db3ba4 aurel32
    gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5183 76db3ba4 aurel32
    t1 = tcg_temp_new();
5184 76db3ba4 aurel32
    gen_addr_add(ctx, t1, t0, 8);
5185 76db3ba4 aurel32
    gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5186 76db3ba4 aurel32
    tcg_temp_free(t1);
5187 76a66253 j_mayer
    if (ra != 0)
5188 01a4afeb aurel32
        tcg_gen_mov_tl(cpu_gpr[ra], t0);
5189 01a4afeb aurel32
    tcg_temp_free(t0);
5190 76a66253 j_mayer
}
5191 76a66253 j_mayer
5192 76a66253 j_mayer
/* lfqx */
5193 99e300ef Blue Swirl
static void gen_lfqx(DisasContext *ctx)
5194 76a66253 j_mayer
{
5195 01a4afeb aurel32
    int rd = rD(ctx->opcode);
5196 76db3ba4 aurel32
    TCGv t0;
5197 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_FLOAT);
5198 76db3ba4 aurel32
    t0 = tcg_temp_new();
5199 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
5200 76db3ba4 aurel32
    gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
5201 76db3ba4 aurel32
    gen_addr_add(ctx, t0, t0, 8);
5202 76db3ba4 aurel32
    gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5203 01a4afeb aurel32
    tcg_temp_free(t0);
5204 76a66253 j_mayer
}
5205 76a66253 j_mayer
5206 76a66253 j_mayer
/* stfq */
5207 99e300ef Blue Swirl
static void gen_stfq(DisasContext *ctx)
5208 76a66253 j_mayer
{
5209 01a4afeb aurel32
    int rd = rD(ctx->opcode);
5210 76db3ba4 aurel32
    TCGv t0;
5211 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_FLOAT);
5212 76db3ba4 aurel32
    t0 = tcg_temp_new();
5213 76db3ba4 aurel32
    gen_addr_imm_index(ctx, t0, 0);
5214 76db3ba4 aurel32
    gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5215 76db3ba4 aurel32
    gen_addr_add(ctx, t0, t0, 8);
5216 76db3ba4 aurel32
    gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5217 01a4afeb aurel32
    tcg_temp_free(t0);
5218 76a66253 j_mayer
}
5219 76a66253 j_mayer
5220 76a66253 j_mayer
/* stfqu */
5221 99e300ef Blue Swirl
static void gen_stfqu(DisasContext *ctx)
5222 76a66253 j_mayer
{
5223 76a66253 j_mayer
    int ra = rA(ctx->opcode);
5224 01a4afeb aurel32
    int rd = rD(ctx->opcode);
5225 76db3ba4 aurel32
    TCGv t0, t1;
5226 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_FLOAT);
5227 76db3ba4 aurel32
    t0 = tcg_temp_new();
5228 76db3ba4 aurel32
    gen_addr_imm_index(ctx, t0, 0);
5229 76db3ba4 aurel32
    gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5230 76db3ba4 aurel32
    t1 = tcg_temp_new();
5231 76db3ba4 aurel32
    gen_addr_add(ctx, t1, t0, 8);
5232 76db3ba4 aurel32
    gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5233 76db3ba4 aurel32
    tcg_temp_free(t1);
5234 76a66253 j_mayer
    if (ra != 0)
5235 01a4afeb aurel32
        tcg_gen_mov_tl(cpu_gpr[ra], t0);
5236 01a4afeb aurel32
    tcg_temp_free(t0);
5237 76a66253 j_mayer
}
5238 76a66253 j_mayer
5239 76a66253 j_mayer
/* stfqux */
5240 99e300ef Blue Swirl
static void gen_stfqux(DisasContext *ctx)
5241 76a66253 j_mayer
{
5242 76a66253 j_mayer
    int ra = rA(ctx->opcode);
5243 01a4afeb aurel32
    int rd = rD(ctx->opcode);
5244 76db3ba4 aurel32
    TCGv t0, t1;
5245 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_FLOAT);
5246 76db3ba4 aurel32
    t0 = tcg_temp_new();
5247 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
5248 76db3ba4 aurel32
    gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5249 76db3ba4 aurel32
    t1 = tcg_temp_new();
5250 76db3ba4 aurel32
    gen_addr_add(ctx, t1, t0, 8);
5251 76db3ba4 aurel32
    gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
5252 76db3ba4 aurel32
    tcg_temp_free(t1);
5253 76a66253 j_mayer
    if (ra != 0)
5254 01a4afeb aurel32
        tcg_gen_mov_tl(cpu_gpr[ra], t0);
5255 01a4afeb aurel32
    tcg_temp_free(t0);
5256 76a66253 j_mayer
}
5257 76a66253 j_mayer
5258 76a66253 j_mayer
/* stfqx */
5259 99e300ef Blue Swirl
static void gen_stfqx(DisasContext *ctx)
5260 76a66253 j_mayer
{
5261 01a4afeb aurel32
    int rd = rD(ctx->opcode);
5262 76db3ba4 aurel32
    TCGv t0;
5263 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_FLOAT);
5264 76db3ba4 aurel32
    t0 = tcg_temp_new();
5265 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
5266 76db3ba4 aurel32
    gen_qemu_st64(ctx, cpu_fpr[rd], t0);
5267 76db3ba4 aurel32
    gen_addr_add(ctx, t0, t0, 8);
5268 76db3ba4 aurel32
    gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
5269 01a4afeb aurel32
    tcg_temp_free(t0);
5270 76a66253 j_mayer
}
5271 76a66253 j_mayer
5272 76a66253 j_mayer
/* BookE specific instructions */
5273 99e300ef Blue Swirl
5274 54623277 Blue Swirl
/* XXX: not implemented on 440 ? */
5275 99e300ef Blue Swirl
static void gen_mfapidi(DisasContext *ctx)
5276 76a66253 j_mayer
{
5277 76a66253 j_mayer
    /* XXX: TODO */
5278 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5279 76a66253 j_mayer
}
5280 76a66253 j_mayer
5281 2662a059 j_mayer
/* XXX: not implemented on 440 ? */
5282 99e300ef Blue Swirl
static void gen_tlbiva(DisasContext *ctx)
5283 76a66253 j_mayer
{
5284 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5285 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5286 76a66253 j_mayer
#else
5287 74d37793 aurel32
    TCGv t0;
5288 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5289 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5290 76a66253 j_mayer
        return;
5291 76a66253 j_mayer
    }
5292 ec72e276 aurel32
    t0 = tcg_temp_new();
5293 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
5294 74d37793 aurel32
    gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
5295 74d37793 aurel32
    tcg_temp_free(t0);
5296 76a66253 j_mayer
#endif
5297 76a66253 j_mayer
}
5298 76a66253 j_mayer
5299 76a66253 j_mayer
/* All 405 MAC instructions are translated here */
5300 b068d6a7 j_mayer
static always_inline void gen_405_mulladd_insn (DisasContext *ctx,
5301 b068d6a7 j_mayer
                                                int opc2, int opc3,
5302 b068d6a7 j_mayer
                                                int ra, int rb, int rt, int Rc)
5303 76a66253 j_mayer
{
5304 182608d4 aurel32
    TCGv t0, t1;
5305 182608d4 aurel32
5306 a7812ae4 pbrook
    t0 = tcg_temp_local_new();
5307 a7812ae4 pbrook
    t1 = tcg_temp_local_new();
5308 182608d4 aurel32
5309 76a66253 j_mayer
    switch (opc3 & 0x0D) {
5310 76a66253 j_mayer
    case 0x05:
5311 76a66253 j_mayer
        /* macchw    - macchw.    - macchwo   - macchwo.   */
5312 76a66253 j_mayer
        /* macchws   - macchws.   - macchwso  - macchwso.  */
5313 76a66253 j_mayer
        /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
5314 76a66253 j_mayer
        /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
5315 76a66253 j_mayer
        /* mulchw - mulchw. */
5316 182608d4 aurel32
        tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
5317 182608d4 aurel32
        tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
5318 182608d4 aurel32
        tcg_gen_ext16s_tl(t1, t1);
5319 76a66253 j_mayer
        break;
5320 76a66253 j_mayer
    case 0x04:
5321 76a66253 j_mayer
        /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
5322 76a66253 j_mayer
        /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
5323 76a66253 j_mayer
        /* mulchwu - mulchwu. */
5324 182608d4 aurel32
        tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
5325 182608d4 aurel32
        tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
5326 182608d4 aurel32
        tcg_gen_ext16u_tl(t1, t1);
5327 76a66253 j_mayer
        break;
5328 76a66253 j_mayer
    case 0x01:
5329 76a66253 j_mayer
        /* machhw    - machhw.    - machhwo   - machhwo.   */
5330 76a66253 j_mayer
        /* machhws   - machhws.   - machhwso  - machhwso.  */
5331 76a66253 j_mayer
        /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
5332 76a66253 j_mayer
        /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
5333 76a66253 j_mayer
        /* mulhhw - mulhhw. */
5334 182608d4 aurel32
        tcg_gen_sari_tl(t0, cpu_gpr[ra], 16);
5335 182608d4 aurel32
        tcg_gen_ext16s_tl(t0, t0);
5336 182608d4 aurel32
        tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
5337 182608d4 aurel32
        tcg_gen_ext16s_tl(t1, t1);
5338 76a66253 j_mayer
        break;
5339 76a66253 j_mayer
    case 0x00:
5340 76a66253 j_mayer
        /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
5341 76a66253 j_mayer
        /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
5342 76a66253 j_mayer
        /* mulhhwu - mulhhwu. */
5343 182608d4 aurel32
        tcg_gen_shri_tl(t0, cpu_gpr[ra], 16);
5344 182608d4 aurel32
        tcg_gen_ext16u_tl(t0, t0);
5345 182608d4 aurel32
        tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
5346 182608d4 aurel32
        tcg_gen_ext16u_tl(t1, t1);
5347 76a66253 j_mayer
        break;
5348 76a66253 j_mayer
    case 0x0D:
5349 76a66253 j_mayer
        /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
5350 76a66253 j_mayer
        /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
5351 76a66253 j_mayer
        /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
5352 76a66253 j_mayer
        /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
5353 76a66253 j_mayer
        /* mullhw - mullhw. */
5354 182608d4 aurel32
        tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
5355 182608d4 aurel32
        tcg_gen_ext16s_tl(t1, cpu_gpr[rb]);
5356 76a66253 j_mayer
        break;
5357 76a66253 j_mayer
    case 0x0C:
5358 76a66253 j_mayer
        /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
5359 76a66253 j_mayer
        /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
5360 76a66253 j_mayer
        /* mullhwu - mullhwu. */
5361 182608d4 aurel32
        tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
5362 182608d4 aurel32
        tcg_gen_ext16u_tl(t1, cpu_gpr[rb]);
5363 76a66253 j_mayer
        break;
5364 76a66253 j_mayer
    }
5365 76a66253 j_mayer
    if (opc2 & 0x04) {
5366 182608d4 aurel32
        /* (n)multiply-and-accumulate (0x0C / 0x0E) */
5367 182608d4 aurel32
        tcg_gen_mul_tl(t1, t0, t1);
5368 182608d4 aurel32
        if (opc2 & 0x02) {
5369 182608d4 aurel32
            /* nmultiply-and-accumulate (0x0E) */
5370 182608d4 aurel32
            tcg_gen_sub_tl(t0, cpu_gpr[rt], t1);
5371 182608d4 aurel32
        } else {
5372 182608d4 aurel32
            /* multiply-and-accumulate (0x0C) */
5373 182608d4 aurel32
            tcg_gen_add_tl(t0, cpu_gpr[rt], t1);
5374 182608d4 aurel32
        }
5375 182608d4 aurel32
5376 182608d4 aurel32
        if (opc3 & 0x12) {
5377 182608d4 aurel32
            /* Check overflow and/or saturate */
5378 182608d4 aurel32
            int l1 = gen_new_label();
5379 182608d4 aurel32
5380 182608d4 aurel32
            if (opc3 & 0x10) {
5381 182608d4 aurel32
                /* Start with XER OV disabled, the most likely case */
5382 182608d4 aurel32
                tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
5383 182608d4 aurel32
            }
5384 182608d4 aurel32
            if (opc3 & 0x01) {
5385 182608d4 aurel32
                /* Signed */
5386 182608d4 aurel32
                tcg_gen_xor_tl(t1, cpu_gpr[rt], t1);
5387 182608d4 aurel32
                tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
5388 182608d4 aurel32
                tcg_gen_xor_tl(t1, cpu_gpr[rt], t0);
5389 182608d4 aurel32
                tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
5390 bdc4e053 aurel32
                if (opc3 & 0x02) {
5391 182608d4 aurel32
                    /* Saturate */
5392 182608d4 aurel32
                    tcg_gen_sari_tl(t0, cpu_gpr[rt], 31);
5393 182608d4 aurel32
                    tcg_gen_xori_tl(t0, t0, 0x7fffffff);
5394 182608d4 aurel32
                }
5395 182608d4 aurel32
            } else {
5396 182608d4 aurel32
                /* Unsigned */
5397 182608d4 aurel32
                tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5398 bdc4e053 aurel32
                if (opc3 & 0x02) {
5399 182608d4 aurel32
                    /* Saturate */
5400 182608d4 aurel32
                    tcg_gen_movi_tl(t0, UINT32_MAX);
5401 182608d4 aurel32
                }
5402 182608d4 aurel32
            }
5403 182608d4 aurel32
            if (opc3 & 0x10) {
5404 182608d4 aurel32
                /* Check overflow */
5405 182608d4 aurel32
                tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
5406 182608d4 aurel32
            }
5407 182608d4 aurel32
            gen_set_label(l1);
5408 182608d4 aurel32
            tcg_gen_mov_tl(cpu_gpr[rt], t0);
5409 182608d4 aurel32
        }
5410 182608d4 aurel32
    } else {
5411 182608d4 aurel32
        tcg_gen_mul_tl(cpu_gpr[rt], t0, t1);
5412 76a66253 j_mayer
    }
5413 182608d4 aurel32
    tcg_temp_free(t0);
5414 182608d4 aurel32
    tcg_temp_free(t1);
5415 76a66253 j_mayer
    if (unlikely(Rc) != 0) {
5416 76a66253 j_mayer
        /* Update Rc0 */
5417 182608d4 aurel32
        gen_set_Rc0(ctx, cpu_gpr[rt]);
5418 76a66253 j_mayer
    }
5419 76a66253 j_mayer
}
5420 76a66253 j_mayer
5421 a750fc0b j_mayer
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
5422 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                               \
5423 76a66253 j_mayer
{                                                                             \
5424 76a66253 j_mayer
    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
5425 76a66253 j_mayer
                         rD(ctx->opcode), Rc(ctx->opcode));                   \
5426 76a66253 j_mayer
}
5427 76a66253 j_mayer
5428 76a66253 j_mayer
/* macchw    - macchw.    */
5429 a750fc0b j_mayer
GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
5430 76a66253 j_mayer
/* macchwo   - macchwo.   */
5431 a750fc0b j_mayer
GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
5432 76a66253 j_mayer
/* macchws   - macchws.   */
5433 a750fc0b j_mayer
GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
5434 76a66253 j_mayer
/* macchwso  - macchwso.  */
5435 a750fc0b j_mayer
GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
5436 76a66253 j_mayer
/* macchwsu  - macchwsu.  */
5437 a750fc0b j_mayer
GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
5438 76a66253 j_mayer
/* macchwsuo - macchwsuo. */
5439 a750fc0b j_mayer
GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
5440 76a66253 j_mayer
/* macchwu   - macchwu.   */
5441 a750fc0b j_mayer
GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
5442 76a66253 j_mayer
/* macchwuo  - macchwuo.  */
5443 a750fc0b j_mayer
GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
5444 76a66253 j_mayer
/* machhw    - machhw.    */
5445 a750fc0b j_mayer
GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
5446 76a66253 j_mayer
/* machhwo   - machhwo.   */
5447 a750fc0b j_mayer
GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
5448 76a66253 j_mayer
/* machhws   - machhws.   */
5449 a750fc0b j_mayer
GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
5450 76a66253 j_mayer
/* machhwso  - machhwso.  */
5451 a750fc0b j_mayer
GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
5452 76a66253 j_mayer
/* machhwsu  - machhwsu.  */
5453 a750fc0b j_mayer
GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
5454 76a66253 j_mayer
/* machhwsuo - machhwsuo. */
5455 a750fc0b j_mayer
GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
5456 76a66253 j_mayer
/* machhwu   - machhwu.   */
5457 a750fc0b j_mayer
GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
5458 76a66253 j_mayer
/* machhwuo  - machhwuo.  */
5459 a750fc0b j_mayer
GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
5460 76a66253 j_mayer
/* maclhw    - maclhw.    */
5461 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
5462 76a66253 j_mayer
/* maclhwo   - maclhwo.   */
5463 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
5464 76a66253 j_mayer
/* maclhws   - maclhws.   */
5465 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
5466 76a66253 j_mayer
/* maclhwso  - maclhwso.  */
5467 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
5468 76a66253 j_mayer
/* maclhwu   - maclhwu.   */
5469 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
5470 76a66253 j_mayer
/* maclhwuo  - maclhwuo.  */
5471 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
5472 76a66253 j_mayer
/* maclhwsu  - maclhwsu.  */
5473 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
5474 76a66253 j_mayer
/* maclhwsuo - maclhwsuo. */
5475 a750fc0b j_mayer
GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
5476 76a66253 j_mayer
/* nmacchw   - nmacchw.   */
5477 a750fc0b j_mayer
GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
5478 76a66253 j_mayer
/* nmacchwo  - nmacchwo.  */
5479 a750fc0b j_mayer
GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
5480 76a66253 j_mayer
/* nmacchws  - nmacchws.  */
5481 a750fc0b j_mayer
GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
5482 76a66253 j_mayer
/* nmacchwso - nmacchwso. */
5483 a750fc0b j_mayer
GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
5484 76a66253 j_mayer
/* nmachhw   - nmachhw.   */
5485 a750fc0b j_mayer
GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
5486 76a66253 j_mayer
/* nmachhwo  - nmachhwo.  */
5487 a750fc0b j_mayer
GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
5488 76a66253 j_mayer
/* nmachhws  - nmachhws.  */
5489 a750fc0b j_mayer
GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
5490 76a66253 j_mayer
/* nmachhwso - nmachhwso. */
5491 a750fc0b j_mayer
GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
5492 76a66253 j_mayer
/* nmaclhw   - nmaclhw.   */
5493 a750fc0b j_mayer
GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
5494 76a66253 j_mayer
/* nmaclhwo  - nmaclhwo.  */
5495 a750fc0b j_mayer
GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
5496 76a66253 j_mayer
/* nmaclhws  - nmaclhws.  */
5497 a750fc0b j_mayer
GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
5498 76a66253 j_mayer
/* nmaclhwso - nmaclhwso. */
5499 a750fc0b j_mayer
GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
5500 76a66253 j_mayer
5501 76a66253 j_mayer
/* mulchw  - mulchw.  */
5502 a750fc0b j_mayer
GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
5503 76a66253 j_mayer
/* mulchwu - mulchwu. */
5504 a750fc0b j_mayer
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
5505 76a66253 j_mayer
/* mulhhw  - mulhhw.  */
5506 a750fc0b j_mayer
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
5507 76a66253 j_mayer
/* mulhhwu - mulhhwu. */
5508 a750fc0b j_mayer
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
5509 76a66253 j_mayer
/* mullhw  - mullhw.  */
5510 a750fc0b j_mayer
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
5511 76a66253 j_mayer
/* mullhwu - mullhwu. */
5512 a750fc0b j_mayer
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
5513 76a66253 j_mayer
5514 76a66253 j_mayer
/* mfdcr */
5515 99e300ef Blue Swirl
static void gen_mfdcr(DisasContext *ctx)
5516 76a66253 j_mayer
{
5517 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5518 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5519 76a66253 j_mayer
#else
5520 06dca6a7 aurel32
    TCGv dcrn;
5521 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5522 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5523 76a66253 j_mayer
        return;
5524 76a66253 j_mayer
    }
5525 06dca6a7 aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */
5526 06dca6a7 aurel32
    gen_update_nip(ctx, ctx->nip - 4);
5527 06dca6a7 aurel32
    dcrn = tcg_const_tl(SPR(ctx->opcode));
5528 06dca6a7 aurel32
    gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], dcrn);
5529 06dca6a7 aurel32
    tcg_temp_free(dcrn);
5530 76a66253 j_mayer
#endif
5531 76a66253 j_mayer
}
5532 76a66253 j_mayer
5533 76a66253 j_mayer
/* mtdcr */
5534 99e300ef Blue Swirl
static void gen_mtdcr(DisasContext *ctx)
5535 76a66253 j_mayer
{
5536 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5537 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5538 76a66253 j_mayer
#else
5539 06dca6a7 aurel32
    TCGv dcrn;
5540 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5541 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5542 76a66253 j_mayer
        return;
5543 76a66253 j_mayer
    }
5544 06dca6a7 aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */
5545 06dca6a7 aurel32
    gen_update_nip(ctx, ctx->nip - 4);
5546 06dca6a7 aurel32
    dcrn = tcg_const_tl(SPR(ctx->opcode));
5547 06dca6a7 aurel32
    gen_helper_store_dcr(dcrn, cpu_gpr[rS(ctx->opcode)]);
5548 06dca6a7 aurel32
    tcg_temp_free(dcrn);
5549 a42bd6cc j_mayer
#endif
5550 a42bd6cc j_mayer
}
5551 a42bd6cc j_mayer
5552 a42bd6cc j_mayer
/* mfdcrx */
5553 2662a059 j_mayer
/* XXX: not implemented on 440 ? */
5554 99e300ef Blue Swirl
static void gen_mfdcrx(DisasContext *ctx)
5555 a42bd6cc j_mayer
{
5556 a42bd6cc j_mayer
#if defined(CONFIG_USER_ONLY)
5557 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5558 a42bd6cc j_mayer
#else
5559 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5560 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5561 a42bd6cc j_mayer
        return;
5562 a42bd6cc j_mayer
    }
5563 06dca6a7 aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */
5564 06dca6a7 aurel32
    gen_update_nip(ctx, ctx->nip - 4);
5565 06dca6a7 aurel32
    gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5566 a750fc0b j_mayer
    /* Note: Rc update flag set leads to undefined state of Rc0 */
5567 a42bd6cc j_mayer
#endif
5568 a42bd6cc j_mayer
}
5569 a42bd6cc j_mayer
5570 a42bd6cc j_mayer
/* mtdcrx */
5571 2662a059 j_mayer
/* XXX: not implemented on 440 ? */
5572 99e300ef Blue Swirl
static void gen_mtdcrx(DisasContext *ctx)
5573 a42bd6cc j_mayer
{
5574 a42bd6cc j_mayer
#if defined(CONFIG_USER_ONLY)
5575 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5576 a42bd6cc j_mayer
#else
5577 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5578 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
5579 a42bd6cc j_mayer
        return;
5580 a42bd6cc j_mayer
    }
5581 06dca6a7 aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */
5582 06dca6a7 aurel32
    gen_update_nip(ctx, ctx->nip - 4);
5583 06dca6a7 aurel32
    gen_helper_store_dcr(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5584 a750fc0b j_mayer
    /* Note: Rc update flag set leads to undefined state of Rc0 */
5585 76a66253 j_mayer
#endif
5586 76a66253 j_mayer
}
5587 76a66253 j_mayer
5588 a750fc0b j_mayer
/* mfdcrux (PPC 460) : user-mode access to DCR */
5589 99e300ef Blue Swirl
static void gen_mfdcrux(DisasContext *ctx)
5590 a750fc0b j_mayer
{
5591 06dca6a7 aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */
5592 06dca6a7 aurel32
    gen_update_nip(ctx, ctx->nip - 4);
5593 06dca6a7 aurel32
    gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5594 a750fc0b j_mayer
    /* Note: Rc update flag set leads to undefined state of Rc0 */
5595 a750fc0b j_mayer
}
5596 a750fc0b j_mayer
5597 a750fc0b j_mayer
/* mtdcrux (PPC 460) : user-mode access to DCR */
5598 99e300ef Blue Swirl
static void gen_mtdcrux(DisasContext *ctx)
5599 a750fc0b j_mayer
{
5600 06dca6a7 aurel32
    /* NIP cannot be restored if the memory exception comes from an helper */
5601 06dca6a7 aurel32
    gen_update_nip(ctx, ctx->nip - 4);
5602 06dca6a7 aurel32
    gen_helper_store_dcr(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5603 a750fc0b j_mayer
    /* Note: Rc update flag set leads to undefined state of Rc0 */
5604 a750fc0b j_mayer
}
5605 a750fc0b j_mayer
5606 76a66253 j_mayer
/* dccci */
5607 99e300ef Blue Swirl
static void gen_dccci(DisasContext *ctx)
5608 76a66253 j_mayer
{
5609 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5610 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5611 76a66253 j_mayer
#else
5612 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5613 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5614 76a66253 j_mayer
        return;
5615 76a66253 j_mayer
    }
5616 76a66253 j_mayer
    /* interpreted as no-op */
5617 76a66253 j_mayer
#endif
5618 76a66253 j_mayer
}
5619 76a66253 j_mayer
5620 76a66253 j_mayer
/* dcread */
5621 99e300ef Blue Swirl
static void gen_dcread(DisasContext *ctx)
5622 76a66253 j_mayer
{
5623 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5624 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5625 76a66253 j_mayer
#else
5626 b61f2753 aurel32
    TCGv EA, val;
5627 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5628 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5629 76a66253 j_mayer
        return;
5630 76a66253 j_mayer
    }
5631 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_CACHE);
5632 a7812ae4 pbrook
    EA = tcg_temp_new();
5633 76db3ba4 aurel32
    gen_addr_reg_index(ctx, EA);
5634 a7812ae4 pbrook
    val = tcg_temp_new();
5635 76db3ba4 aurel32
    gen_qemu_ld32u(ctx, val, EA);
5636 b61f2753 aurel32
    tcg_temp_free(val);
5637 b61f2753 aurel32
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
5638 b61f2753 aurel32
    tcg_temp_free(EA);
5639 76a66253 j_mayer
#endif
5640 76a66253 j_mayer
}
5641 76a66253 j_mayer
5642 76a66253 j_mayer
/* icbt */
5643 e8eaa2c0 Blue Swirl
static void gen_icbt_40x(DisasContext *ctx)
5644 76a66253 j_mayer
{
5645 76a66253 j_mayer
    /* interpreted as no-op */
5646 76a66253 j_mayer
    /* XXX: specification say this is treated as a load by the MMU
5647 76a66253 j_mayer
     *      but does not generate any exception
5648 76a66253 j_mayer
     */
5649 76a66253 j_mayer
}
5650 76a66253 j_mayer
5651 76a66253 j_mayer
/* iccci */
5652 99e300ef Blue Swirl
static void gen_iccci(DisasContext *ctx)
5653 76a66253 j_mayer
{
5654 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5655 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5656 76a66253 j_mayer
#else
5657 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5658 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5659 76a66253 j_mayer
        return;
5660 76a66253 j_mayer
    }
5661 76a66253 j_mayer
    /* interpreted as no-op */
5662 76a66253 j_mayer
#endif
5663 76a66253 j_mayer
}
5664 76a66253 j_mayer
5665 76a66253 j_mayer
/* icread */
5666 99e300ef Blue Swirl
static void gen_icread(DisasContext *ctx)
5667 76a66253 j_mayer
{
5668 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5669 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5670 76a66253 j_mayer
#else
5671 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5672 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5673 76a66253 j_mayer
        return;
5674 76a66253 j_mayer
    }
5675 76a66253 j_mayer
    /* interpreted as no-op */
5676 76a66253 j_mayer
#endif
5677 76a66253 j_mayer
}
5678 76a66253 j_mayer
5679 76db3ba4 aurel32
/* rfci (mem_idx only) */
5680 e8eaa2c0 Blue Swirl
static void gen_rfci_40x(DisasContext *ctx)
5681 a42bd6cc j_mayer
{
5682 a42bd6cc j_mayer
#if defined(CONFIG_USER_ONLY)
5683 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5684 a42bd6cc j_mayer
#else
5685 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5686 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5687 a42bd6cc j_mayer
        return;
5688 a42bd6cc j_mayer
    }
5689 a42bd6cc j_mayer
    /* Restore CPU state */
5690 d72a19f7 aurel32
    gen_helper_40x_rfci();
5691 e06fcd75 aurel32
    gen_sync_exception(ctx);
5692 a42bd6cc j_mayer
#endif
5693 a42bd6cc j_mayer
}
5694 a42bd6cc j_mayer
5695 99e300ef Blue Swirl
static void gen_rfci(DisasContext *ctx)
5696 a42bd6cc j_mayer
{
5697 a42bd6cc j_mayer
#if defined(CONFIG_USER_ONLY)
5698 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5699 a42bd6cc j_mayer
#else
5700 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5701 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5702 a42bd6cc j_mayer
        return;
5703 a42bd6cc j_mayer
    }
5704 a42bd6cc j_mayer
    /* Restore CPU state */
5705 d72a19f7 aurel32
    gen_helper_rfci();
5706 e06fcd75 aurel32
    gen_sync_exception(ctx);
5707 a42bd6cc j_mayer
#endif
5708 a42bd6cc j_mayer
}
5709 a42bd6cc j_mayer
5710 a42bd6cc j_mayer
/* BookE specific */
5711 99e300ef Blue Swirl
5712 54623277 Blue Swirl
/* XXX: not implemented on 440 ? */
5713 99e300ef Blue Swirl
static void gen_rfdi(DisasContext *ctx)
5714 76a66253 j_mayer
{
5715 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5716 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5717 76a66253 j_mayer
#else
5718 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5719 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5720 76a66253 j_mayer
        return;
5721 76a66253 j_mayer
    }
5722 76a66253 j_mayer
    /* Restore CPU state */
5723 d72a19f7 aurel32
    gen_helper_rfdi();
5724 e06fcd75 aurel32
    gen_sync_exception(ctx);
5725 76a66253 j_mayer
#endif
5726 76a66253 j_mayer
}
5727 76a66253 j_mayer
5728 2662a059 j_mayer
/* XXX: not implemented on 440 ? */
5729 99e300ef Blue Swirl
static void gen_rfmci(DisasContext *ctx)
5730 a42bd6cc j_mayer
{
5731 a42bd6cc j_mayer
#if defined(CONFIG_USER_ONLY)
5732 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5733 a42bd6cc j_mayer
#else
5734 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5735 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5736 a42bd6cc j_mayer
        return;
5737 a42bd6cc j_mayer
    }
5738 a42bd6cc j_mayer
    /* Restore CPU state */
5739 d72a19f7 aurel32
    gen_helper_rfmci();
5740 e06fcd75 aurel32
    gen_sync_exception(ctx);
5741 a42bd6cc j_mayer
#endif
5742 a42bd6cc j_mayer
}
5743 5eb7995e j_mayer
5744 d9bce9d9 j_mayer
/* TLB management - PowerPC 405 implementation */
5745 e8eaa2c0 Blue Swirl
5746 54623277 Blue Swirl
/* tlbre */
5747 e8eaa2c0 Blue Swirl
static void gen_tlbre_40x(DisasContext *ctx)
5748 76a66253 j_mayer
{
5749 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5750 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5751 76a66253 j_mayer
#else
5752 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5753 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5754 76a66253 j_mayer
        return;
5755 76a66253 j_mayer
    }
5756 76a66253 j_mayer
    switch (rB(ctx->opcode)) {
5757 76a66253 j_mayer
    case 0:
5758 74d37793 aurel32
        gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5759 76a66253 j_mayer
        break;
5760 76a66253 j_mayer
    case 1:
5761 74d37793 aurel32
        gen_helper_4xx_tlbre_lo(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5762 76a66253 j_mayer
        break;
5763 76a66253 j_mayer
    default:
5764 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5765 76a66253 j_mayer
        break;
5766 9a64fbe4 bellard
    }
5767 76a66253 j_mayer
#endif
5768 76a66253 j_mayer
}
5769 76a66253 j_mayer
5770 d9bce9d9 j_mayer
/* tlbsx - tlbsx. */
5771 e8eaa2c0 Blue Swirl
static void gen_tlbsx_40x(DisasContext *ctx)
5772 76a66253 j_mayer
{
5773 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5774 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5775 76a66253 j_mayer
#else
5776 74d37793 aurel32
    TCGv t0;
5777 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5778 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5779 76a66253 j_mayer
        return;
5780 76a66253 j_mayer
    }
5781 74d37793 aurel32
    t0 = tcg_temp_new();
5782 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
5783 74d37793 aurel32
    gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], t0);
5784 74d37793 aurel32
    tcg_temp_free(t0);
5785 74d37793 aurel32
    if (Rc(ctx->opcode)) {
5786 74d37793 aurel32
        int l1 = gen_new_label();
5787 74d37793 aurel32
        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
5788 74d37793 aurel32
        tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
5789 74d37793 aurel32
        tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
5790 74d37793 aurel32
        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
5791 74d37793 aurel32
        tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
5792 74d37793 aurel32
        gen_set_label(l1);
5793 74d37793 aurel32
    }
5794 76a66253 j_mayer
#endif
5795 79aceca5 bellard
}
5796 79aceca5 bellard
5797 76a66253 j_mayer
/* tlbwe */
5798 e8eaa2c0 Blue Swirl
static void gen_tlbwe_40x(DisasContext *ctx)
5799 79aceca5 bellard
{
5800 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5801 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5802 76a66253 j_mayer
#else
5803 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5804 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5805 76a66253 j_mayer
        return;
5806 76a66253 j_mayer
    }
5807 76a66253 j_mayer
    switch (rB(ctx->opcode)) {
5808 76a66253 j_mayer
    case 0:
5809 74d37793 aurel32
        gen_helper_4xx_tlbwe_hi(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5810 76a66253 j_mayer
        break;
5811 76a66253 j_mayer
    case 1:
5812 74d37793 aurel32
        gen_helper_4xx_tlbwe_lo(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5813 76a66253 j_mayer
        break;
5814 76a66253 j_mayer
    default:
5815 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5816 76a66253 j_mayer
        break;
5817 9a64fbe4 bellard
    }
5818 76a66253 j_mayer
#endif
5819 76a66253 j_mayer
}
5820 76a66253 j_mayer
5821 a4bb6c3e j_mayer
/* TLB management - PowerPC 440 implementation */
5822 e8eaa2c0 Blue Swirl
5823 54623277 Blue Swirl
/* tlbre */
5824 e8eaa2c0 Blue Swirl
static void gen_tlbre_440(DisasContext *ctx)
5825 5eb7995e j_mayer
{
5826 5eb7995e j_mayer
#if defined(CONFIG_USER_ONLY)
5827 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5828 5eb7995e j_mayer
#else
5829 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5830 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5831 5eb7995e j_mayer
        return;
5832 5eb7995e j_mayer
    }
5833 5eb7995e j_mayer
    switch (rB(ctx->opcode)) {
5834 5eb7995e j_mayer
    case 0:
5835 5eb7995e j_mayer
    case 1:
5836 5eb7995e j_mayer
    case 2:
5837 74d37793 aurel32
        {
5838 74d37793 aurel32
            TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
5839 74d37793 aurel32
            gen_helper_440_tlbwe(t0, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5840 74d37793 aurel32
            tcg_temp_free_i32(t0);
5841 74d37793 aurel32
        }
5842 5eb7995e j_mayer
        break;
5843 5eb7995e j_mayer
    default:
5844 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5845 5eb7995e j_mayer
        break;
5846 5eb7995e j_mayer
    }
5847 5eb7995e j_mayer
#endif
5848 5eb7995e j_mayer
}
5849 5eb7995e j_mayer
5850 5eb7995e j_mayer
/* tlbsx - tlbsx. */
5851 e8eaa2c0 Blue Swirl
static void gen_tlbsx_440(DisasContext *ctx)
5852 5eb7995e j_mayer
{
5853 5eb7995e j_mayer
#if defined(CONFIG_USER_ONLY)
5854 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5855 5eb7995e j_mayer
#else
5856 74d37793 aurel32
    TCGv t0;
5857 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5858 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5859 5eb7995e j_mayer
        return;
5860 5eb7995e j_mayer
    }
5861 74d37793 aurel32
    t0 = tcg_temp_new();
5862 76db3ba4 aurel32
    gen_addr_reg_index(ctx, t0);
5863 74d37793 aurel32
    gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], t0);
5864 74d37793 aurel32
    tcg_temp_free(t0);
5865 74d37793 aurel32
    if (Rc(ctx->opcode)) {
5866 74d37793 aurel32
        int l1 = gen_new_label();
5867 74d37793 aurel32
        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
5868 74d37793 aurel32
        tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
5869 74d37793 aurel32
        tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
5870 74d37793 aurel32
        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
5871 74d37793 aurel32
        tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
5872 74d37793 aurel32
        gen_set_label(l1);
5873 74d37793 aurel32
    }
5874 5eb7995e j_mayer
#endif
5875 5eb7995e j_mayer
}
5876 5eb7995e j_mayer
5877 5eb7995e j_mayer
/* tlbwe */
5878 e8eaa2c0 Blue Swirl
static void gen_tlbwe_440(DisasContext *ctx)
5879 5eb7995e j_mayer
{
5880 5eb7995e j_mayer
#if defined(CONFIG_USER_ONLY)
5881 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5882 5eb7995e j_mayer
#else
5883 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5884 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5885 5eb7995e j_mayer
        return;
5886 5eb7995e j_mayer
    }
5887 5eb7995e j_mayer
    switch (rB(ctx->opcode)) {
5888 5eb7995e j_mayer
    case 0:
5889 5eb7995e j_mayer
    case 1:
5890 5eb7995e j_mayer
    case 2:
5891 74d37793 aurel32
        {
5892 74d37793 aurel32
            TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
5893 74d37793 aurel32
            gen_helper_440_tlbwe(t0, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
5894 74d37793 aurel32
            tcg_temp_free_i32(t0);
5895 74d37793 aurel32
        }
5896 5eb7995e j_mayer
        break;
5897 5eb7995e j_mayer
    default:
5898 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5899 5eb7995e j_mayer
        break;
5900 5eb7995e j_mayer
    }
5901 5eb7995e j_mayer
#endif
5902 5eb7995e j_mayer
}
5903 5eb7995e j_mayer
5904 76a66253 j_mayer
/* wrtee */
5905 99e300ef Blue Swirl
static void gen_wrtee(DisasContext *ctx)
5906 76a66253 j_mayer
{
5907 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5908 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5909 76a66253 j_mayer
#else
5910 6527f6ea aurel32
    TCGv t0;
5911 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5912 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5913 76a66253 j_mayer
        return;
5914 76a66253 j_mayer
    }
5915 6527f6ea aurel32
    t0 = tcg_temp_new();
5916 6527f6ea aurel32
    tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));
5917 6527f6ea aurel32
    tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
5918 6527f6ea aurel32
    tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
5919 6527f6ea aurel32
    tcg_temp_free(t0);
5920 dee96f6c j_mayer
    /* Stop translation to have a chance to raise an exception
5921 dee96f6c j_mayer
     * if we just set msr_ee to 1
5922 dee96f6c j_mayer
     */
5923 e06fcd75 aurel32
    gen_stop_exception(ctx);
5924 76a66253 j_mayer
#endif
5925 76a66253 j_mayer
}
5926 76a66253 j_mayer
5927 76a66253 j_mayer
/* wrteei */
5928 99e300ef Blue Swirl
static void gen_wrteei(DisasContext *ctx)
5929 76a66253 j_mayer
{
5930 76a66253 j_mayer
#if defined(CONFIG_USER_ONLY)
5931 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5932 76a66253 j_mayer
#else
5933 76db3ba4 aurel32
    if (unlikely(!ctx->mem_idx)) {
5934 e06fcd75 aurel32
        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
5935 76a66253 j_mayer
        return;
5936 76a66253 j_mayer
    }
5937 fbe73008 Baojun Wang
    if (ctx->opcode & 0x00008000) {
5938 6527f6ea aurel32
        tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
5939 6527f6ea aurel32
        /* Stop translation to have a chance to raise an exception */
5940 e06fcd75 aurel32
        gen_stop_exception(ctx);
5941 6527f6ea aurel32
    } else {
5942 1b6e5f99 aurel32
        tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
5943 6527f6ea aurel32
    }
5944 76a66253 j_mayer
#endif
5945 76a66253 j_mayer
}
5946 76a66253 j_mayer
5947 08e46e54 j_mayer
/* PowerPC 440 specific instructions */
5948 99e300ef Blue Swirl
5949 54623277 Blue Swirl
/* dlmzb */
5950 99e300ef Blue Swirl
static void gen_dlmzb(DisasContext *ctx)
5951 76a66253 j_mayer
{
5952 ef0d51af aurel32
    TCGv_i32 t0 = tcg_const_i32(Rc(ctx->opcode));
5953 ef0d51af aurel32
    gen_helper_dlmzb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
5954 ef0d51af aurel32
                     cpu_gpr[rB(ctx->opcode)], t0);
5955 ef0d51af aurel32
    tcg_temp_free_i32(t0);
5956 76a66253 j_mayer
}
5957 76a66253 j_mayer
5958 76a66253 j_mayer
/* mbar replaces eieio on 440 */
5959 99e300ef Blue Swirl
static void gen_mbar(DisasContext *ctx)
5960 76a66253 j_mayer
{
5961 76a66253 j_mayer
    /* interpreted as no-op */
5962 76a66253 j_mayer
}
5963 76a66253 j_mayer
5964 76a66253 j_mayer
/* msync replaces sync on 440 */
5965 99e300ef Blue Swirl
static void gen_msync(DisasContext *ctx)
5966 76a66253 j_mayer
{
5967 76a66253 j_mayer
    /* interpreted as no-op */
5968 76a66253 j_mayer
}
5969 76a66253 j_mayer
5970 76a66253 j_mayer
/* icbt */
5971 e8eaa2c0 Blue Swirl
static void gen_icbt_440(DisasContext *ctx)
5972 76a66253 j_mayer
{
5973 76a66253 j_mayer
    /* interpreted as no-op */
5974 76a66253 j_mayer
    /* XXX: specification say this is treated as a load by the MMU
5975 76a66253 j_mayer
     *      but does not generate any exception
5976 76a66253 j_mayer
     */
5977 79aceca5 bellard
}
5978 79aceca5 bellard
5979 a9d9eb8f j_mayer
/***                      Altivec vector extension                         ***/
5980 a9d9eb8f j_mayer
/* Altivec registers moves */
5981 a9d9eb8f j_mayer
5982 564e571a aurel32
static always_inline TCGv_ptr gen_avr_ptr(int reg)
5983 564e571a aurel32
{
5984 e4704b3b aurel32
    TCGv_ptr r = tcg_temp_new_ptr();
5985 564e571a aurel32
    tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, avr[reg]));
5986 564e571a aurel32
    return r;
5987 564e571a aurel32
}
5988 564e571a aurel32
5989 a9d9eb8f j_mayer
#define GEN_VR_LDX(name, opc2, opc3)                                          \
5990 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                       \
5991 a9d9eb8f j_mayer
{                                                                             \
5992 fe1e5c53 aurel32
    TCGv EA;                                                                  \
5993 a9d9eb8f j_mayer
    if (unlikely(!ctx->altivec_enabled)) {                                    \
5994 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_VPU);                                 \
5995 a9d9eb8f j_mayer
        return;                                                               \
5996 a9d9eb8f j_mayer
    }                                                                         \
5997 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_INT);                                     \
5998 fe1e5c53 aurel32
    EA = tcg_temp_new();                                                      \
5999 76db3ba4 aurel32
    gen_addr_reg_index(ctx, EA);                                              \
6000 fe1e5c53 aurel32
    tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
6001 76db3ba4 aurel32
    if (ctx->le_mode) {                                                       \
6002 76db3ba4 aurel32
        gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6003 fe1e5c53 aurel32
        tcg_gen_addi_tl(EA, EA, 8);                                           \
6004 76db3ba4 aurel32
        gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6005 fe1e5c53 aurel32
    } else {                                                                  \
6006 76db3ba4 aurel32
        gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6007 fe1e5c53 aurel32
        tcg_gen_addi_tl(EA, EA, 8);                                           \
6008 76db3ba4 aurel32
        gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6009 fe1e5c53 aurel32
    }                                                                         \
6010 fe1e5c53 aurel32
    tcg_temp_free(EA);                                                        \
6011 a9d9eb8f j_mayer
}
6012 a9d9eb8f j_mayer
6013 a9d9eb8f j_mayer
#define GEN_VR_STX(name, opc2, opc3)                                          \
6014 99e300ef Blue Swirl
static void gen_st##name(DisasContext *ctx)                                   \
6015 a9d9eb8f j_mayer
{                                                                             \
6016 fe1e5c53 aurel32
    TCGv EA;                                                                  \
6017 a9d9eb8f j_mayer
    if (unlikely(!ctx->altivec_enabled)) {                                    \
6018 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_VPU);                                 \
6019 a9d9eb8f j_mayer
        return;                                                               \
6020 a9d9eb8f j_mayer
    }                                                                         \
6021 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_INT);                                     \
6022 fe1e5c53 aurel32
    EA = tcg_temp_new();                                                      \
6023 76db3ba4 aurel32
    gen_addr_reg_index(ctx, EA);                                              \
6024 fe1e5c53 aurel32
    tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
6025 76db3ba4 aurel32
    if (ctx->le_mode) {                                                       \
6026 76db3ba4 aurel32
        gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6027 fe1e5c53 aurel32
        tcg_gen_addi_tl(EA, EA, 8);                                           \
6028 76db3ba4 aurel32
        gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6029 fe1e5c53 aurel32
    } else {                                                                  \
6030 76db3ba4 aurel32
        gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
6031 fe1e5c53 aurel32
        tcg_gen_addi_tl(EA, EA, 8);                                           \
6032 76db3ba4 aurel32
        gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
6033 fe1e5c53 aurel32
    }                                                                         \
6034 fe1e5c53 aurel32
    tcg_temp_free(EA);                                                        \
6035 a9d9eb8f j_mayer
}
6036 a9d9eb8f j_mayer
6037 cbfb6ae9 aurel32
#define GEN_VR_LVE(name, opc2, opc3)                                    \
6038 99e300ef Blue Swirl
static void gen_lve##name(DisasContext *ctx)                            \
6039 cbfb6ae9 aurel32
    {                                                                   \
6040 cbfb6ae9 aurel32
        TCGv EA;                                                        \
6041 cbfb6ae9 aurel32
        TCGv_ptr rs;                                                    \
6042 cbfb6ae9 aurel32
        if (unlikely(!ctx->altivec_enabled)) {                          \
6043 cbfb6ae9 aurel32
            gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6044 cbfb6ae9 aurel32
            return;                                                     \
6045 cbfb6ae9 aurel32
        }                                                               \
6046 cbfb6ae9 aurel32
        gen_set_access_type(ctx, ACCESS_INT);                           \
6047 cbfb6ae9 aurel32
        EA = tcg_temp_new();                                            \
6048 cbfb6ae9 aurel32
        gen_addr_reg_index(ctx, EA);                                    \
6049 cbfb6ae9 aurel32
        rs = gen_avr_ptr(rS(ctx->opcode));                              \
6050 cbfb6ae9 aurel32
        gen_helper_lve##name (rs, EA);                                  \
6051 cbfb6ae9 aurel32
        tcg_temp_free(EA);                                              \
6052 cbfb6ae9 aurel32
        tcg_temp_free_ptr(rs);                                          \
6053 cbfb6ae9 aurel32
    }
6054 cbfb6ae9 aurel32
6055 cbfb6ae9 aurel32
#define GEN_VR_STVE(name, opc2, opc3)                                   \
6056 99e300ef Blue Swirl
static void gen_stve##name(DisasContext *ctx)                           \
6057 cbfb6ae9 aurel32
    {                                                                   \
6058 cbfb6ae9 aurel32
        TCGv EA;                                                        \
6059 cbfb6ae9 aurel32
        TCGv_ptr rs;                                                    \
6060 cbfb6ae9 aurel32
        if (unlikely(!ctx->altivec_enabled)) {                          \
6061 cbfb6ae9 aurel32
            gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6062 cbfb6ae9 aurel32
            return;                                                     \
6063 cbfb6ae9 aurel32
        }                                                               \
6064 cbfb6ae9 aurel32
        gen_set_access_type(ctx, ACCESS_INT);                           \
6065 cbfb6ae9 aurel32
        EA = tcg_temp_new();                                            \
6066 cbfb6ae9 aurel32
        gen_addr_reg_index(ctx, EA);                                    \
6067 cbfb6ae9 aurel32
        rs = gen_avr_ptr(rS(ctx->opcode));                              \
6068 cbfb6ae9 aurel32
        gen_helper_stve##name (rs, EA);                                 \
6069 cbfb6ae9 aurel32
        tcg_temp_free(EA);                                              \
6070 cbfb6ae9 aurel32
        tcg_temp_free_ptr(rs);                                          \
6071 cbfb6ae9 aurel32
    }
6072 cbfb6ae9 aurel32
6073 fe1e5c53 aurel32
GEN_VR_LDX(lvx, 0x07, 0x03);
6074 a9d9eb8f j_mayer
/* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
6075 fe1e5c53 aurel32
GEN_VR_LDX(lvxl, 0x07, 0x0B);
6076 a9d9eb8f j_mayer
6077 cbfb6ae9 aurel32
GEN_VR_LVE(bx, 0x07, 0x00);
6078 cbfb6ae9 aurel32
GEN_VR_LVE(hx, 0x07, 0x01);
6079 cbfb6ae9 aurel32
GEN_VR_LVE(wx, 0x07, 0x02);
6080 cbfb6ae9 aurel32
6081 fe1e5c53 aurel32
GEN_VR_STX(svx, 0x07, 0x07);
6082 a9d9eb8f j_mayer
/* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
6083 fe1e5c53 aurel32
GEN_VR_STX(svxl, 0x07, 0x0F);
6084 a9d9eb8f j_mayer
6085 cbfb6ae9 aurel32
GEN_VR_STVE(bx, 0x07, 0x04);
6086 cbfb6ae9 aurel32
GEN_VR_STVE(hx, 0x07, 0x05);
6087 cbfb6ae9 aurel32
GEN_VR_STVE(wx, 0x07, 0x06);
6088 cbfb6ae9 aurel32
6089 99e300ef Blue Swirl
static void gen_lvsl(DisasContext *ctx)
6090 bf8d8ded aurel32
{
6091 bf8d8ded aurel32
    TCGv_ptr rd;
6092 bf8d8ded aurel32
    TCGv EA;
6093 bf8d8ded aurel32
    if (unlikely(!ctx->altivec_enabled)) {
6094 bf8d8ded aurel32
        gen_exception(ctx, POWERPC_EXCP_VPU);
6095 bf8d8ded aurel32
        return;
6096 bf8d8ded aurel32
    }
6097 bf8d8ded aurel32
    EA = tcg_temp_new();
6098 bf8d8ded aurel32
    gen_addr_reg_index(ctx, EA);
6099 bf8d8ded aurel32
    rd = gen_avr_ptr(rD(ctx->opcode));
6100 bf8d8ded aurel32
    gen_helper_lvsl(rd, EA);
6101 bf8d8ded aurel32
    tcg_temp_free(EA);
6102 bf8d8ded aurel32
    tcg_temp_free_ptr(rd);
6103 bf8d8ded aurel32
}
6104 bf8d8ded aurel32
6105 99e300ef Blue Swirl
static void gen_lvsr(DisasContext *ctx)
6106 bf8d8ded aurel32
{
6107 bf8d8ded aurel32
    TCGv_ptr rd;
6108 bf8d8ded aurel32
    TCGv EA;
6109 bf8d8ded aurel32
    if (unlikely(!ctx->altivec_enabled)) {
6110 bf8d8ded aurel32
        gen_exception(ctx, POWERPC_EXCP_VPU);
6111 bf8d8ded aurel32
        return;
6112 bf8d8ded aurel32
    }
6113 bf8d8ded aurel32
    EA = tcg_temp_new();
6114 bf8d8ded aurel32
    gen_addr_reg_index(ctx, EA);
6115 bf8d8ded aurel32
    rd = gen_avr_ptr(rD(ctx->opcode));
6116 bf8d8ded aurel32
    gen_helper_lvsr(rd, EA);
6117 bf8d8ded aurel32
    tcg_temp_free(EA);
6118 bf8d8ded aurel32
    tcg_temp_free_ptr(rd);
6119 bf8d8ded aurel32
}
6120 bf8d8ded aurel32
6121 99e300ef Blue Swirl
static void gen_mfvscr(DisasContext *ctx)
6122 785f451b aurel32
{
6123 785f451b aurel32
    TCGv_i32 t;
6124 785f451b aurel32
    if (unlikely(!ctx->altivec_enabled)) {
6125 785f451b aurel32
        gen_exception(ctx, POWERPC_EXCP_VPU);
6126 785f451b aurel32
        return;
6127 785f451b aurel32
    }
6128 785f451b aurel32
    tcg_gen_movi_i64(cpu_avrh[rD(ctx->opcode)], 0);
6129 785f451b aurel32
    t = tcg_temp_new_i32();
6130 785f451b aurel32
    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, vscr));
6131 785f451b aurel32
    tcg_gen_extu_i32_i64(cpu_avrl[rD(ctx->opcode)], t);
6132 fce5ecb7 aurel32
    tcg_temp_free_i32(t);
6133 785f451b aurel32
}
6134 785f451b aurel32
6135 99e300ef Blue Swirl
static void gen_mtvscr(DisasContext *ctx)
6136 785f451b aurel32
{
6137 6e87b7c7 aurel32
    TCGv_ptr p;
6138 785f451b aurel32
    if (unlikely(!ctx->altivec_enabled)) {
6139 785f451b aurel32
        gen_exception(ctx, POWERPC_EXCP_VPU);
6140 785f451b aurel32
        return;
6141 785f451b aurel32
    }
6142 6e87b7c7 aurel32
    p = gen_avr_ptr(rD(ctx->opcode));
6143 6e87b7c7 aurel32
    gen_helper_mtvscr(p);
6144 6e87b7c7 aurel32
    tcg_temp_free_ptr(p);
6145 785f451b aurel32
}
6146 785f451b aurel32
6147 7a9b96cf aurel32
/* Logical operations */
6148 7a9b96cf aurel32
#define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)                        \
6149 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                 \
6150 7a9b96cf aurel32
{                                                                       \
6151 7a9b96cf aurel32
    if (unlikely(!ctx->altivec_enabled)) {                              \
6152 7a9b96cf aurel32
        gen_exception(ctx, POWERPC_EXCP_VPU);                           \
6153 7a9b96cf aurel32
        return;                                                         \
6154 7a9b96cf aurel32
    }                                                                   \
6155 7a9b96cf aurel32
    tcg_op(cpu_avrh[rD(ctx->opcode)], cpu_avrh[rA(ctx->opcode)], cpu_avrh[rB(ctx->opcode)]); \
6156 7a9b96cf aurel32
    tcg_op(cpu_avrl[rD(ctx->opcode)], cpu_avrl[rA(ctx->opcode)], cpu_avrl[rB(ctx->opcode)]); \
6157 7a9b96cf aurel32
}
6158 7a9b96cf aurel32
6159 7a9b96cf aurel32
GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16);
6160 7a9b96cf aurel32
GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17);
6161 7a9b96cf aurel32
GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18);
6162 7a9b96cf aurel32
GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19);
6163 7a9b96cf aurel32
GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20);
6164 7a9b96cf aurel32
6165 8e27dd6f aurel32
#define GEN_VXFORM(name, opc2, opc3)                                    \
6166 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                 \
6167 8e27dd6f aurel32
{                                                                       \
6168 8e27dd6f aurel32
    TCGv_ptr ra, rb, rd;                                                \
6169 8e27dd6f aurel32
    if (unlikely(!ctx->altivec_enabled)) {                              \
6170 8e27dd6f aurel32
        gen_exception(ctx, POWERPC_EXCP_VPU);                           \
6171 8e27dd6f aurel32
        return;                                                         \
6172 8e27dd6f aurel32
    }                                                                   \
6173 8e27dd6f aurel32
    ra = gen_avr_ptr(rA(ctx->opcode));                                  \
6174 8e27dd6f aurel32
    rb = gen_avr_ptr(rB(ctx->opcode));                                  \
6175 8e27dd6f aurel32
    rd = gen_avr_ptr(rD(ctx->opcode));                                  \
6176 8e27dd6f aurel32
    gen_helper_##name (rd, ra, rb);                                     \
6177 8e27dd6f aurel32
    tcg_temp_free_ptr(ra);                                              \
6178 8e27dd6f aurel32
    tcg_temp_free_ptr(rb);                                              \
6179 8e27dd6f aurel32
    tcg_temp_free_ptr(rd);                                              \
6180 8e27dd6f aurel32
}
6181 8e27dd6f aurel32
6182 7872c51c aurel32
GEN_VXFORM(vaddubm, 0, 0);
6183 7872c51c aurel32
GEN_VXFORM(vadduhm, 0, 1);
6184 7872c51c aurel32
GEN_VXFORM(vadduwm, 0, 2);
6185 7872c51c aurel32
GEN_VXFORM(vsububm, 0, 16);
6186 7872c51c aurel32
GEN_VXFORM(vsubuhm, 0, 17);
6187 7872c51c aurel32
GEN_VXFORM(vsubuwm, 0, 18);
6188 e4039339 aurel32
GEN_VXFORM(vmaxub, 1, 0);
6189 e4039339 aurel32
GEN_VXFORM(vmaxuh, 1, 1);
6190 e4039339 aurel32
GEN_VXFORM(vmaxuw, 1, 2);
6191 e4039339 aurel32
GEN_VXFORM(vmaxsb, 1, 4);
6192 e4039339 aurel32
GEN_VXFORM(vmaxsh, 1, 5);
6193 e4039339 aurel32
GEN_VXFORM(vmaxsw, 1, 6);
6194 e4039339 aurel32
GEN_VXFORM(vminub, 1, 8);
6195 e4039339 aurel32
GEN_VXFORM(vminuh, 1, 9);
6196 e4039339 aurel32
GEN_VXFORM(vminuw, 1, 10);
6197 e4039339 aurel32
GEN_VXFORM(vminsb, 1, 12);
6198 e4039339 aurel32
GEN_VXFORM(vminsh, 1, 13);
6199 e4039339 aurel32
GEN_VXFORM(vminsw, 1, 14);
6200 fab3cbe9 aurel32
GEN_VXFORM(vavgub, 1, 16);
6201 fab3cbe9 aurel32
GEN_VXFORM(vavguh, 1, 17);
6202 fab3cbe9 aurel32
GEN_VXFORM(vavguw, 1, 18);
6203 fab3cbe9 aurel32
GEN_VXFORM(vavgsb, 1, 20);
6204 fab3cbe9 aurel32
GEN_VXFORM(vavgsh, 1, 21);
6205 fab3cbe9 aurel32
GEN_VXFORM(vavgsw, 1, 22);
6206 3b430048 aurel32
GEN_VXFORM(vmrghb, 6, 0);
6207 3b430048 aurel32
GEN_VXFORM(vmrghh, 6, 1);
6208 3b430048 aurel32
GEN_VXFORM(vmrghw, 6, 2);
6209 3b430048 aurel32
GEN_VXFORM(vmrglb, 6, 4);
6210 3b430048 aurel32
GEN_VXFORM(vmrglh, 6, 5);
6211 3b430048 aurel32
GEN_VXFORM(vmrglw, 6, 6);
6212 2c277908 aurel32
GEN_VXFORM(vmuloub, 4, 0);
6213 2c277908 aurel32
GEN_VXFORM(vmulouh, 4, 1);
6214 2c277908 aurel32
GEN_VXFORM(vmulosb, 4, 4);
6215 2c277908 aurel32
GEN_VXFORM(vmulosh, 4, 5);
6216 2c277908 aurel32
GEN_VXFORM(vmuleub, 4, 8);
6217 2c277908 aurel32
GEN_VXFORM(vmuleuh, 4, 9);
6218 2c277908 aurel32
GEN_VXFORM(vmulesb, 4, 12);
6219 2c277908 aurel32
GEN_VXFORM(vmulesh, 4, 13);
6220 d79f0809 aurel32
GEN_VXFORM(vslb, 2, 4);
6221 d79f0809 aurel32
GEN_VXFORM(vslh, 2, 5);
6222 d79f0809 aurel32
GEN_VXFORM(vslw, 2, 6);
6223 07ef34c3 aurel32
GEN_VXFORM(vsrb, 2, 8);
6224 07ef34c3 aurel32
GEN_VXFORM(vsrh, 2, 9);
6225 07ef34c3 aurel32
GEN_VXFORM(vsrw, 2, 10);
6226 07ef34c3 aurel32
GEN_VXFORM(vsrab, 2, 12);
6227 07ef34c3 aurel32
GEN_VXFORM(vsrah, 2, 13);
6228 07ef34c3 aurel32
GEN_VXFORM(vsraw, 2, 14);
6229 7b239bec aurel32
GEN_VXFORM(vslo, 6, 16);
6230 7b239bec aurel32
GEN_VXFORM(vsro, 6, 17);
6231 e343da72 aurel32
GEN_VXFORM(vaddcuw, 0, 6);
6232 e343da72 aurel32
GEN_VXFORM(vsubcuw, 0, 22);
6233 5ab09f33 aurel32
GEN_VXFORM(vaddubs, 0, 8);
6234 5ab09f33 aurel32
GEN_VXFORM(vadduhs, 0, 9);
6235 5ab09f33 aurel32
GEN_VXFORM(vadduws, 0, 10);
6236 5ab09f33 aurel32
GEN_VXFORM(vaddsbs, 0, 12);
6237 5ab09f33 aurel32
GEN_VXFORM(vaddshs, 0, 13);
6238 5ab09f33 aurel32
GEN_VXFORM(vaddsws, 0, 14);
6239 5ab09f33 aurel32
GEN_VXFORM(vsububs, 0, 24);
6240 5ab09f33 aurel32
GEN_VXFORM(vsubuhs, 0, 25);
6241 5ab09f33 aurel32
GEN_VXFORM(vsubuws, 0, 26);
6242 5ab09f33 aurel32
GEN_VXFORM(vsubsbs, 0, 28);
6243 5ab09f33 aurel32
GEN_VXFORM(vsubshs, 0, 29);
6244 5ab09f33 aurel32
GEN_VXFORM(vsubsws, 0, 30);
6245 5e1d0985 aurel32
GEN_VXFORM(vrlb, 2, 0);
6246 5e1d0985 aurel32
GEN_VXFORM(vrlh, 2, 1);
6247 5e1d0985 aurel32
GEN_VXFORM(vrlw, 2, 2);
6248 d9430add aurel32
GEN_VXFORM(vsl, 2, 7);
6249 d9430add aurel32
GEN_VXFORM(vsr, 2, 11);
6250 5335a145 aurel32
GEN_VXFORM(vpkuhum, 7, 0);
6251 5335a145 aurel32
GEN_VXFORM(vpkuwum, 7, 1);
6252 5335a145 aurel32
GEN_VXFORM(vpkuhus, 7, 2);
6253 5335a145 aurel32
GEN_VXFORM(vpkuwus, 7, 3);
6254 5335a145 aurel32
GEN_VXFORM(vpkshus, 7, 4);
6255 5335a145 aurel32
GEN_VXFORM(vpkswus, 7, 5);
6256 5335a145 aurel32
GEN_VXFORM(vpkshss, 7, 6);
6257 5335a145 aurel32
GEN_VXFORM(vpkswss, 7, 7);
6258 1dd9ffb9 aurel32
GEN_VXFORM(vpkpx, 7, 12);
6259 8142cddd aurel32
GEN_VXFORM(vsum4ubs, 4, 24);
6260 8142cddd aurel32
GEN_VXFORM(vsum4sbs, 4, 28);
6261 8142cddd aurel32
GEN_VXFORM(vsum4shs, 4, 25);
6262 8142cddd aurel32
GEN_VXFORM(vsum2sws, 4, 26);
6263 8142cddd aurel32
GEN_VXFORM(vsumsws, 4, 30);
6264 56fdd213 aurel32
GEN_VXFORM(vaddfp, 5, 0);
6265 56fdd213 aurel32
GEN_VXFORM(vsubfp, 5, 1);
6266 1536ff64 aurel32
GEN_VXFORM(vmaxfp, 5, 16);
6267 1536ff64 aurel32
GEN_VXFORM(vminfp, 5, 17);
6268 fab3cbe9 aurel32
6269 0cbcd906 aurel32
#define GEN_VXRFORM1(opname, name, str, opc2, opc3)                     \
6270 e8eaa2c0 Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                         \
6271 0cbcd906 aurel32
    {                                                                   \
6272 0cbcd906 aurel32
        TCGv_ptr ra, rb, rd;                                            \
6273 0cbcd906 aurel32
        if (unlikely(!ctx->altivec_enabled)) {                          \
6274 0cbcd906 aurel32
            gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6275 0cbcd906 aurel32
            return;                                                     \
6276 0cbcd906 aurel32
        }                                                               \
6277 0cbcd906 aurel32
        ra = gen_avr_ptr(rA(ctx->opcode));                              \
6278 0cbcd906 aurel32
        rb = gen_avr_ptr(rB(ctx->opcode));                              \
6279 0cbcd906 aurel32
        rd = gen_avr_ptr(rD(ctx->opcode));                              \
6280 0cbcd906 aurel32
        gen_helper_##opname (rd, ra, rb);                               \
6281 0cbcd906 aurel32
        tcg_temp_free_ptr(ra);                                          \
6282 0cbcd906 aurel32
        tcg_temp_free_ptr(rb);                                          \
6283 0cbcd906 aurel32
        tcg_temp_free_ptr(rd);                                          \
6284 0cbcd906 aurel32
    }
6285 0cbcd906 aurel32
6286 0cbcd906 aurel32
#define GEN_VXRFORM(name, opc2, opc3)                                \
6287 0cbcd906 aurel32
    GEN_VXRFORM1(name, name, #name, opc2, opc3)                      \
6288 0cbcd906 aurel32
    GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
6289 0cbcd906 aurel32
6290 1add6e23 aurel32
GEN_VXRFORM(vcmpequb, 3, 0)
6291 1add6e23 aurel32
GEN_VXRFORM(vcmpequh, 3, 1)
6292 1add6e23 aurel32
GEN_VXRFORM(vcmpequw, 3, 2)
6293 1add6e23 aurel32
GEN_VXRFORM(vcmpgtsb, 3, 12)
6294 1add6e23 aurel32
GEN_VXRFORM(vcmpgtsh, 3, 13)
6295 1add6e23 aurel32
GEN_VXRFORM(vcmpgtsw, 3, 14)
6296 1add6e23 aurel32
GEN_VXRFORM(vcmpgtub, 3, 8)
6297 1add6e23 aurel32
GEN_VXRFORM(vcmpgtuh, 3, 9)
6298 1add6e23 aurel32
GEN_VXRFORM(vcmpgtuw, 3, 10)
6299 819ca121 aurel32
GEN_VXRFORM(vcmpeqfp, 3, 3)
6300 819ca121 aurel32
GEN_VXRFORM(vcmpgefp, 3, 7)
6301 819ca121 aurel32
GEN_VXRFORM(vcmpgtfp, 3, 11)
6302 819ca121 aurel32
GEN_VXRFORM(vcmpbfp, 3, 15)
6303 1add6e23 aurel32
6304 c026766b aurel32
#define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
6305 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                         \
6306 c026766b aurel32
    {                                                                   \
6307 c026766b aurel32
        TCGv_ptr rd;                                                    \
6308 c026766b aurel32
        TCGv_i32 simm;                                                  \
6309 c026766b aurel32
        if (unlikely(!ctx->altivec_enabled)) {                          \
6310 c026766b aurel32
            gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6311 c026766b aurel32
            return;                                                     \
6312 c026766b aurel32
        }                                                               \
6313 c026766b aurel32
        simm = tcg_const_i32(SIMM5(ctx->opcode));                       \
6314 c026766b aurel32
        rd = gen_avr_ptr(rD(ctx->opcode));                              \
6315 c026766b aurel32
        gen_helper_##name (rd, simm);                                   \
6316 c026766b aurel32
        tcg_temp_free_i32(simm);                                        \
6317 c026766b aurel32
        tcg_temp_free_ptr(rd);                                          \
6318 c026766b aurel32
    }
6319 c026766b aurel32
6320 c026766b aurel32
GEN_VXFORM_SIMM(vspltisb, 6, 12);
6321 c026766b aurel32
GEN_VXFORM_SIMM(vspltish, 6, 13);
6322 c026766b aurel32
GEN_VXFORM_SIMM(vspltisw, 6, 14);
6323 c026766b aurel32
6324 de5f2484 aurel32
#define GEN_VXFORM_NOA(name, opc2, opc3)                                \
6325 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                 \
6326 de5f2484 aurel32
    {                                                                   \
6327 de5f2484 aurel32
        TCGv_ptr rb, rd;                                                \
6328 de5f2484 aurel32
        if (unlikely(!ctx->altivec_enabled)) {                          \
6329 de5f2484 aurel32
            gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6330 de5f2484 aurel32
            return;                                                     \
6331 de5f2484 aurel32
        }                                                               \
6332 de5f2484 aurel32
        rb = gen_avr_ptr(rB(ctx->opcode));                              \
6333 de5f2484 aurel32
        rd = gen_avr_ptr(rD(ctx->opcode));                              \
6334 de5f2484 aurel32
        gen_helper_##name (rd, rb);                                     \
6335 de5f2484 aurel32
        tcg_temp_free_ptr(rb);                                          \
6336 de5f2484 aurel32
        tcg_temp_free_ptr(rd);                                         \
6337 de5f2484 aurel32
    }
6338 de5f2484 aurel32
6339 6cf1c6e5 aurel32
GEN_VXFORM_NOA(vupkhsb, 7, 8);
6340 6cf1c6e5 aurel32
GEN_VXFORM_NOA(vupkhsh, 7, 9);
6341 6cf1c6e5 aurel32
GEN_VXFORM_NOA(vupklsb, 7, 10);
6342 6cf1c6e5 aurel32
GEN_VXFORM_NOA(vupklsh, 7, 11);
6343 79f85c3a aurel32
GEN_VXFORM_NOA(vupkhpx, 7, 13);
6344 79f85c3a aurel32
GEN_VXFORM_NOA(vupklpx, 7, 15);
6345 bdfbac35 aurel32
GEN_VXFORM_NOA(vrefp, 5, 4);
6346 071fc3b1 aurel32
GEN_VXFORM_NOA(vrsqrtefp, 5, 5);
6347 b580763f aurel32
GEN_VXFORM_NOA(vlogefp, 5, 7);
6348 f6b19645 aurel32
GEN_VXFORM_NOA(vrfim, 5, 8);
6349 f6b19645 aurel32
GEN_VXFORM_NOA(vrfin, 5, 9);
6350 f6b19645 aurel32
GEN_VXFORM_NOA(vrfip, 5, 10);
6351 f6b19645 aurel32
GEN_VXFORM_NOA(vrfiz, 5, 11);
6352 79f85c3a aurel32
6353 21d21583 aurel32
#define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
6354 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                 \
6355 21d21583 aurel32
    {                                                                   \
6356 21d21583 aurel32
        TCGv_ptr rd;                                                    \
6357 21d21583 aurel32
        TCGv_i32 simm;                                                  \
6358 21d21583 aurel32
        if (unlikely(!ctx->altivec_enabled)) {                          \
6359 21d21583 aurel32
            gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6360 21d21583 aurel32
            return;                                                     \
6361 21d21583 aurel32
        }                                                               \
6362 21d21583 aurel32
        simm = tcg_const_i32(SIMM5(ctx->opcode));                       \
6363 21d21583 aurel32
        rd = gen_avr_ptr(rD(ctx->opcode));                              \
6364 21d21583 aurel32
        gen_helper_##name (rd, simm);                                   \
6365 21d21583 aurel32
        tcg_temp_free_i32(simm);                                        \
6366 21d21583 aurel32
        tcg_temp_free_ptr(rd);                                          \
6367 21d21583 aurel32
    }
6368 21d21583 aurel32
6369 27a4edb3 aurel32
#define GEN_VXFORM_UIMM(name, opc2, opc3)                               \
6370 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                 \
6371 27a4edb3 aurel32
    {                                                                   \
6372 27a4edb3 aurel32
        TCGv_ptr rb, rd;                                                \
6373 27a4edb3 aurel32
        TCGv_i32 uimm;                                                  \
6374 27a4edb3 aurel32
        if (unlikely(!ctx->altivec_enabled)) {                          \
6375 27a4edb3 aurel32
            gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6376 27a4edb3 aurel32
            return;                                                     \
6377 27a4edb3 aurel32
        }                                                               \
6378 27a4edb3 aurel32
        uimm = tcg_const_i32(UIMM5(ctx->opcode));                       \
6379 27a4edb3 aurel32
        rb = gen_avr_ptr(rB(ctx->opcode));                              \
6380 27a4edb3 aurel32
        rd = gen_avr_ptr(rD(ctx->opcode));                              \
6381 27a4edb3 aurel32
        gen_helper_##name (rd, rb, uimm);                               \
6382 27a4edb3 aurel32
        tcg_temp_free_i32(uimm);                                        \
6383 27a4edb3 aurel32
        tcg_temp_free_ptr(rb);                                          \
6384 27a4edb3 aurel32
        tcg_temp_free_ptr(rd);                                          \
6385 27a4edb3 aurel32
    }
6386 27a4edb3 aurel32
6387 e4e6bee7 aurel32
GEN_VXFORM_UIMM(vspltb, 6, 8);
6388 e4e6bee7 aurel32
GEN_VXFORM_UIMM(vsplth, 6, 9);
6389 e4e6bee7 aurel32
GEN_VXFORM_UIMM(vspltw, 6, 10);
6390 e140632e aurel32
GEN_VXFORM_UIMM(vcfux, 5, 12);
6391 e140632e aurel32
GEN_VXFORM_UIMM(vcfsx, 5, 13);
6392 875b31db aurel32
GEN_VXFORM_UIMM(vctuxs, 5, 14);
6393 875b31db aurel32
GEN_VXFORM_UIMM(vctsxs, 5, 15);
6394 e4e6bee7 aurel32
6395 99e300ef Blue Swirl
static void gen_vsldoi(DisasContext *ctx)
6396 cd633b10 aurel32
{
6397 cd633b10 aurel32
    TCGv_ptr ra, rb, rd;
6398 fce5ecb7 aurel32
    TCGv_i32 sh;
6399 cd633b10 aurel32
    if (unlikely(!ctx->altivec_enabled)) {
6400 cd633b10 aurel32
        gen_exception(ctx, POWERPC_EXCP_VPU);
6401 cd633b10 aurel32
        return;
6402 cd633b10 aurel32
    }
6403 cd633b10 aurel32
    ra = gen_avr_ptr(rA(ctx->opcode));
6404 cd633b10 aurel32
    rb = gen_avr_ptr(rB(ctx->opcode));
6405 cd633b10 aurel32
    rd = gen_avr_ptr(rD(ctx->opcode));
6406 cd633b10 aurel32
    sh = tcg_const_i32(VSH(ctx->opcode));
6407 cd633b10 aurel32
    gen_helper_vsldoi (rd, ra, rb, sh);
6408 cd633b10 aurel32
    tcg_temp_free_ptr(ra);
6409 cd633b10 aurel32
    tcg_temp_free_ptr(rb);
6410 cd633b10 aurel32
    tcg_temp_free_ptr(rd);
6411 fce5ecb7 aurel32
    tcg_temp_free_i32(sh);
6412 cd633b10 aurel32
}
6413 cd633b10 aurel32
6414 707cec33 aurel32
#define GEN_VAFORM_PAIRED(name0, name1, opc2)                           \
6415 99e300ef Blue Swirl
static void glue(gen_, name0##_##name1)(DisasContext *ctx)                      \
6416 707cec33 aurel32
    {                                                                   \
6417 707cec33 aurel32
        TCGv_ptr ra, rb, rc, rd;                                        \
6418 707cec33 aurel32
        if (unlikely(!ctx->altivec_enabled)) {                          \
6419 707cec33 aurel32
            gen_exception(ctx, POWERPC_EXCP_VPU);                       \
6420 707cec33 aurel32
            return;                                                     \
6421 707cec33 aurel32
        }                                                               \
6422 707cec33 aurel32
        ra = gen_avr_ptr(rA(ctx->opcode));                              \
6423 707cec33 aurel32
        rb = gen_avr_ptr(rB(ctx->opcode));                              \
6424 707cec33 aurel32
        rc = gen_avr_ptr(rC(ctx->opcode));                              \
6425 707cec33 aurel32
        rd = gen_avr_ptr(rD(ctx->opcode));                              \
6426 707cec33 aurel32
        if (Rc(ctx->opcode)) {                                          \
6427 707cec33 aurel32
            gen_helper_##name1 (rd, ra, rb, rc);                        \
6428 707cec33 aurel32
        } else {                                                        \
6429 707cec33 aurel32
            gen_helper_##name0 (rd, ra, rb, rc);                        \
6430 707cec33 aurel32
        }                                                               \
6431 707cec33 aurel32
        tcg_temp_free_ptr(ra);                                          \
6432 707cec33 aurel32
        tcg_temp_free_ptr(rb);                                          \
6433 707cec33 aurel32
        tcg_temp_free_ptr(rc);                                          \
6434 707cec33 aurel32
        tcg_temp_free_ptr(rd);                                          \
6435 707cec33 aurel32
    }
6436 707cec33 aurel32
6437 b161ae27 aurel32
GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16)
6438 b161ae27 aurel32
6439 99e300ef Blue Swirl
static void gen_vmladduhm(DisasContext *ctx)
6440 bcd2ee23 aurel32
{
6441 bcd2ee23 aurel32
    TCGv_ptr ra, rb, rc, rd;
6442 bcd2ee23 aurel32
    if (unlikely(!ctx->altivec_enabled)) {
6443 bcd2ee23 aurel32
        gen_exception(ctx, POWERPC_EXCP_VPU);
6444 bcd2ee23 aurel32
        return;
6445 bcd2ee23 aurel32
    }
6446 bcd2ee23 aurel32
    ra = gen_avr_ptr(rA(ctx->opcode));
6447 bcd2ee23 aurel32
    rb = gen_avr_ptr(rB(ctx->opcode));
6448 bcd2ee23 aurel32
    rc = gen_avr_ptr(rC(ctx->opcode));
6449 bcd2ee23 aurel32
    rd = gen_avr_ptr(rD(ctx->opcode));
6450 bcd2ee23 aurel32
    gen_helper_vmladduhm(rd, ra, rb, rc);
6451 bcd2ee23 aurel32
    tcg_temp_free_ptr(ra);
6452 bcd2ee23 aurel32
    tcg_temp_free_ptr(rb);
6453 bcd2ee23 aurel32
    tcg_temp_free_ptr(rc);
6454 bcd2ee23 aurel32
    tcg_temp_free_ptr(rd);
6455 bcd2ee23 aurel32
}
6456 bcd2ee23 aurel32
6457 b04ae981 aurel32
GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18)
6458 4d9903b6 aurel32
GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19)
6459 eae07261 aurel32
GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20)
6460 d1258698 aurel32
GEN_VAFORM_PAIRED(vsel, vperm, 21)
6461 35cf7c7e aurel32
GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23)
6462 b04ae981 aurel32
6463 0487d6a8 j_mayer
/***                           SPE extension                               ***/
6464 0487d6a8 j_mayer
/* Register moves */
6465 3cd7d1dd j_mayer
6466 a7812ae4 pbrook
static always_inline void gen_load_gpr64(TCGv_i64 t, int reg) {
6467 f78fb44e aurel32
#if defined(TARGET_PPC64)
6468 f78fb44e aurel32
    tcg_gen_mov_i64(t, cpu_gpr[reg]);
6469 f78fb44e aurel32
#else
6470 36aa55dc pbrook
    tcg_gen_concat_i32_i64(t, cpu_gpr[reg], cpu_gprh[reg]);
6471 3cd7d1dd j_mayer
#endif
6472 f78fb44e aurel32
}
6473 3cd7d1dd j_mayer
6474 a7812ae4 pbrook
static always_inline void gen_store_gpr64(int reg, TCGv_i64 t) {
6475 f78fb44e aurel32
#if defined(TARGET_PPC64)
6476 f78fb44e aurel32
    tcg_gen_mov_i64(cpu_gpr[reg], t);
6477 f78fb44e aurel32
#else
6478 a7812ae4 pbrook
    TCGv_i64 tmp = tcg_temp_new_i64();
6479 f78fb44e aurel32
    tcg_gen_trunc_i64_i32(cpu_gpr[reg], t);
6480 f78fb44e aurel32
    tcg_gen_shri_i64(tmp, t, 32);
6481 f78fb44e aurel32
    tcg_gen_trunc_i64_i32(cpu_gprh[reg], tmp);
6482 a7812ae4 pbrook
    tcg_temp_free_i64(tmp);
6483 3cd7d1dd j_mayer
#endif
6484 f78fb44e aurel32
}
6485 3cd7d1dd j_mayer
6486 0487d6a8 j_mayer
#define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
6487 99e300ef Blue Swirl
static void glue(gen_, name0##_##name1)(DisasContext *ctx)                    \
6488 0487d6a8 j_mayer
{                                                                             \
6489 0487d6a8 j_mayer
    if (Rc(ctx->opcode))                                                      \
6490 0487d6a8 j_mayer
        gen_##name1(ctx);                                                     \
6491 0487d6a8 j_mayer
    else                                                                      \
6492 0487d6a8 j_mayer
        gen_##name0(ctx);                                                     \
6493 0487d6a8 j_mayer
}
6494 0487d6a8 j_mayer
6495 0487d6a8 j_mayer
/* Handler for undefined SPE opcodes */
6496 b068d6a7 j_mayer
static always_inline void gen_speundef (DisasContext *ctx)
6497 0487d6a8 j_mayer
{
6498 e06fcd75 aurel32
    gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6499 0487d6a8 j_mayer
}
6500 0487d6a8 j_mayer
6501 57951c27 aurel32
/* SPE logic */
6502 57951c27 aurel32
#if defined(TARGET_PPC64)
6503 57951c27 aurel32
#define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
6504 b068d6a7 j_mayer
static always_inline void gen_##name (DisasContext *ctx)                      \
6505 0487d6a8 j_mayer
{                                                                             \
6506 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
6507 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6508 0487d6a8 j_mayer
        return;                                                               \
6509 0487d6a8 j_mayer
    }                                                                         \
6510 57951c27 aurel32
    tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
6511 57951c27 aurel32
           cpu_gpr[rB(ctx->opcode)]);                                         \
6512 57951c27 aurel32
}
6513 57951c27 aurel32
#else
6514 57951c27 aurel32
#define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
6515 57951c27 aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
6516 57951c27 aurel32
{                                                                             \
6517 57951c27 aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
6518 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6519 57951c27 aurel32
        return;                                                               \
6520 57951c27 aurel32
    }                                                                         \
6521 57951c27 aurel32
    tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
6522 57951c27 aurel32
           cpu_gpr[rB(ctx->opcode)]);                                         \
6523 57951c27 aurel32
    tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
6524 57951c27 aurel32
           cpu_gprh[rB(ctx->opcode)]);                                        \
6525 0487d6a8 j_mayer
}
6526 57951c27 aurel32
#endif
6527 57951c27 aurel32
6528 57951c27 aurel32
GEN_SPEOP_LOGIC2(evand, tcg_gen_and_tl);
6529 57951c27 aurel32
GEN_SPEOP_LOGIC2(evandc, tcg_gen_andc_tl);
6530 57951c27 aurel32
GEN_SPEOP_LOGIC2(evxor, tcg_gen_xor_tl);
6531 57951c27 aurel32
GEN_SPEOP_LOGIC2(evor, tcg_gen_or_tl);
6532 57951c27 aurel32
GEN_SPEOP_LOGIC2(evnor, tcg_gen_nor_tl);
6533 57951c27 aurel32
GEN_SPEOP_LOGIC2(eveqv, tcg_gen_eqv_tl);
6534 57951c27 aurel32
GEN_SPEOP_LOGIC2(evorc, tcg_gen_orc_tl);
6535 57951c27 aurel32
GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl);
6536 0487d6a8 j_mayer
6537 57951c27 aurel32
/* SPE logic immediate */
6538 57951c27 aurel32
#if defined(TARGET_PPC64)
6539 57951c27 aurel32
#define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
6540 3d3a6a0a aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
6541 3d3a6a0a aurel32
{                                                                             \
6542 3d3a6a0a aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
6543 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6544 3d3a6a0a aurel32
        return;                                                               \
6545 3d3a6a0a aurel32
    }                                                                         \
6546 a7812ae4 pbrook
    TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6547 a7812ae4 pbrook
    TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6548 a7812ae4 pbrook
    TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
6549 57951c27 aurel32
    tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
6550 57951c27 aurel32
    tcg_opi(t0, t0, rB(ctx->opcode));                                         \
6551 57951c27 aurel32
    tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
6552 57951c27 aurel32
    tcg_gen_trunc_i64_i32(t1, t2);                                            \
6553 a7812ae4 pbrook
    tcg_temp_free_i64(t2);                                                    \
6554 57951c27 aurel32
    tcg_opi(t1, t1, rB(ctx->opcode));                                         \
6555 57951c27 aurel32
    tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
6556 a7812ae4 pbrook
    tcg_temp_free_i32(t0);                                                    \
6557 a7812ae4 pbrook
    tcg_temp_free_i32(t1);                                                    \
6558 3d3a6a0a aurel32
}
6559 57951c27 aurel32
#else
6560 57951c27 aurel32
#define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
6561 b068d6a7 j_mayer
static always_inline void gen_##name (DisasContext *ctx)                      \
6562 0487d6a8 j_mayer
{                                                                             \
6563 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
6564 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6565 0487d6a8 j_mayer
        return;                                                               \
6566 0487d6a8 j_mayer
    }                                                                         \
6567 57951c27 aurel32
    tcg_opi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],               \
6568 57951c27 aurel32
            rB(ctx->opcode));                                                 \
6569 57951c27 aurel32
    tcg_opi(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],             \
6570 57951c27 aurel32
            rB(ctx->opcode));                                                 \
6571 0487d6a8 j_mayer
}
6572 57951c27 aurel32
#endif
6573 57951c27 aurel32
GEN_SPEOP_TCG_LOGIC_IMM2(evslwi, tcg_gen_shli_i32);
6574 57951c27 aurel32
GEN_SPEOP_TCG_LOGIC_IMM2(evsrwiu, tcg_gen_shri_i32);
6575 57951c27 aurel32
GEN_SPEOP_TCG_LOGIC_IMM2(evsrwis, tcg_gen_sari_i32);
6576 57951c27 aurel32
GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi, tcg_gen_rotli_i32);
6577 0487d6a8 j_mayer
6578 57951c27 aurel32
/* SPE arithmetic */
6579 57951c27 aurel32
#if defined(TARGET_PPC64)
6580 57951c27 aurel32
#define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
6581 b068d6a7 j_mayer
static always_inline void gen_##name (DisasContext *ctx)                      \
6582 0487d6a8 j_mayer
{                                                                             \
6583 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
6584 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6585 0487d6a8 j_mayer
        return;                                                               \
6586 0487d6a8 j_mayer
    }                                                                         \
6587 a7812ae4 pbrook
    TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6588 a7812ae4 pbrook
    TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6589 a7812ae4 pbrook
    TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
6590 57951c27 aurel32
    tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
6591 57951c27 aurel32
    tcg_op(t0, t0);                                                           \
6592 57951c27 aurel32
    tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
6593 57951c27 aurel32
    tcg_gen_trunc_i64_i32(t1, t2);                                            \
6594 a7812ae4 pbrook
    tcg_temp_free_i64(t2);                                                    \
6595 57951c27 aurel32
    tcg_op(t1, t1);                                                           \
6596 57951c27 aurel32
    tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
6597 a7812ae4 pbrook
    tcg_temp_free_i32(t0);                                                    \
6598 a7812ae4 pbrook
    tcg_temp_free_i32(t1);                                                    \
6599 0487d6a8 j_mayer
}
6600 57951c27 aurel32
#else
6601 a7812ae4 pbrook
#define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
6602 57951c27 aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
6603 57951c27 aurel32
{                                                                             \
6604 57951c27 aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
6605 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6606 57951c27 aurel32
        return;                                                               \
6607 57951c27 aurel32
    }                                                                         \
6608 57951c27 aurel32
    tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);               \
6609 57951c27 aurel32
    tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);             \
6610 57951c27 aurel32
}
6611 57951c27 aurel32
#endif
6612 0487d6a8 j_mayer
6613 a7812ae4 pbrook
static always_inline void gen_op_evabs (TCGv_i32 ret, TCGv_i32 arg1)
6614 57951c27 aurel32
{
6615 57951c27 aurel32
    int l1 = gen_new_label();
6616 57951c27 aurel32
    int l2 = gen_new_label();
6617 0487d6a8 j_mayer
6618 57951c27 aurel32
    tcg_gen_brcondi_i32(TCG_COND_GE, arg1, 0, l1);
6619 57951c27 aurel32
    tcg_gen_neg_i32(ret, arg1);
6620 57951c27 aurel32
    tcg_gen_br(l2);
6621 57951c27 aurel32
    gen_set_label(l1);
6622 a7812ae4 pbrook
    tcg_gen_mov_i32(ret, arg1);
6623 57951c27 aurel32
    gen_set_label(l2);
6624 57951c27 aurel32
}
6625 57951c27 aurel32
GEN_SPEOP_ARITH1(evabs, gen_op_evabs);
6626 57951c27 aurel32
GEN_SPEOP_ARITH1(evneg, tcg_gen_neg_i32);
6627 57951c27 aurel32
GEN_SPEOP_ARITH1(evextsb, tcg_gen_ext8s_i32);
6628 57951c27 aurel32
GEN_SPEOP_ARITH1(evextsh, tcg_gen_ext16s_i32);
6629 a7812ae4 pbrook
static always_inline void gen_op_evrndw (TCGv_i32 ret, TCGv_i32 arg1)
6630 0487d6a8 j_mayer
{
6631 57951c27 aurel32
    tcg_gen_addi_i32(ret, arg1, 0x8000);
6632 57951c27 aurel32
    tcg_gen_ext16u_i32(ret, ret);
6633 57951c27 aurel32
}
6634 57951c27 aurel32
GEN_SPEOP_ARITH1(evrndw, gen_op_evrndw);
6635 a7812ae4 pbrook
GEN_SPEOP_ARITH1(evcntlsw, gen_helper_cntlsw32);
6636 a7812ae4 pbrook
GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32);
6637 0487d6a8 j_mayer
6638 57951c27 aurel32
#if defined(TARGET_PPC64)
6639 57951c27 aurel32
#define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
6640 57951c27 aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
6641 0487d6a8 j_mayer
{                                                                             \
6642 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
6643 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6644 0487d6a8 j_mayer
        return;                                                               \
6645 0487d6a8 j_mayer
    }                                                                         \
6646 a7812ae4 pbrook
    TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6647 a7812ae4 pbrook
    TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6648 a7812ae4 pbrook
    TCGv_i32 t2 = tcg_temp_local_new_i32();                                   \
6649 501e23c4 aurel32
    TCGv_i64 t3 = tcg_temp_local_new_i64();                                   \
6650 57951c27 aurel32
    tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
6651 57951c27 aurel32
    tcg_gen_trunc_i64_i32(t2, cpu_gpr[rB(ctx->opcode)]);                      \
6652 57951c27 aurel32
    tcg_op(t0, t0, t2);                                                       \
6653 57951c27 aurel32
    tcg_gen_shri_i64(t3, cpu_gpr[rA(ctx->opcode)], 32);                       \
6654 57951c27 aurel32
    tcg_gen_trunc_i64_i32(t1, t3);                                            \
6655 57951c27 aurel32
    tcg_gen_shri_i64(t3, cpu_gpr[rB(ctx->opcode)], 32);                       \
6656 57951c27 aurel32
    tcg_gen_trunc_i64_i32(t2, t3);                                            \
6657 a7812ae4 pbrook
    tcg_temp_free_i64(t3);                                                    \
6658 57951c27 aurel32
    tcg_op(t1, t1, t2);                                                       \
6659 a7812ae4 pbrook
    tcg_temp_free_i32(t2);                                                    \
6660 57951c27 aurel32
    tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
6661 a7812ae4 pbrook
    tcg_temp_free_i32(t0);                                                    \
6662 a7812ae4 pbrook
    tcg_temp_free_i32(t1);                                                    \
6663 0487d6a8 j_mayer
}
6664 57951c27 aurel32
#else
6665 57951c27 aurel32
#define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
6666 57951c27 aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
6667 0487d6a8 j_mayer
{                                                                             \
6668 0487d6a8 j_mayer
    if (unlikely(!ctx->spe_enabled)) {                                        \
6669 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6670 0487d6a8 j_mayer
        return;                                                               \
6671 0487d6a8 j_mayer
    }                                                                         \
6672 57951c27 aurel32
    tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
6673 57951c27 aurel32
           cpu_gpr[rB(ctx->opcode)]);                                         \
6674 57951c27 aurel32
    tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
6675 57951c27 aurel32
           cpu_gprh[rB(ctx->opcode)]);                                        \
6676 0487d6a8 j_mayer
}
6677 57951c27 aurel32
#endif
6678 0487d6a8 j_mayer
6679 a7812ae4 pbrook
static always_inline void gen_op_evsrwu (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6680 57951c27 aurel32
{
6681 a7812ae4 pbrook
    TCGv_i32 t0;
6682 57951c27 aurel32
    int l1, l2;
6683 0487d6a8 j_mayer
6684 57951c27 aurel32
    l1 = gen_new_label();
6685 57951c27 aurel32
    l2 = gen_new_label();
6686 a7812ae4 pbrook
    t0 = tcg_temp_local_new_i32();
6687 57951c27 aurel32
    /* No error here: 6 bits are used */
6688 57951c27 aurel32
    tcg_gen_andi_i32(t0, arg2, 0x3F);
6689 57951c27 aurel32
    tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
6690 57951c27 aurel32
    tcg_gen_shr_i32(ret, arg1, t0);
6691 57951c27 aurel32
    tcg_gen_br(l2);
6692 57951c27 aurel32
    gen_set_label(l1);
6693 57951c27 aurel32
    tcg_gen_movi_i32(ret, 0);
6694 57951c27 aurel32
    tcg_gen_br(l2);
6695 a7812ae4 pbrook
    tcg_temp_free_i32(t0);
6696 57951c27 aurel32
}
6697 57951c27 aurel32
GEN_SPEOP_ARITH2(evsrwu, gen_op_evsrwu);
6698 a7812ae4 pbrook
static always_inline void gen_op_evsrws (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6699 57951c27 aurel32
{
6700 a7812ae4 pbrook
    TCGv_i32 t0;
6701 57951c27 aurel32
    int l1, l2;
6702 57951c27 aurel32
6703 57951c27 aurel32
    l1 = gen_new_label();
6704 57951c27 aurel32
    l2 = gen_new_label();
6705 a7812ae4 pbrook
    t0 = tcg_temp_local_new_i32();
6706 57951c27 aurel32
    /* No error here: 6 bits are used */
6707 57951c27 aurel32
    tcg_gen_andi_i32(t0, arg2, 0x3F);
6708 57951c27 aurel32
    tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
6709 57951c27 aurel32
    tcg_gen_sar_i32(ret, arg1, t0);
6710 57951c27 aurel32
    tcg_gen_br(l2);
6711 57951c27 aurel32
    gen_set_label(l1);
6712 57951c27 aurel32
    tcg_gen_movi_i32(ret, 0);
6713 57951c27 aurel32
    tcg_gen_br(l2);
6714 a7812ae4 pbrook
    tcg_temp_free_i32(t0);
6715 57951c27 aurel32
}
6716 57951c27 aurel32
GEN_SPEOP_ARITH2(evsrws, gen_op_evsrws);
6717 a7812ae4 pbrook
static always_inline void gen_op_evslw (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6718 57951c27 aurel32
{
6719 a7812ae4 pbrook
    TCGv_i32 t0;
6720 57951c27 aurel32
    int l1, l2;
6721 57951c27 aurel32
6722 57951c27 aurel32
    l1 = gen_new_label();
6723 57951c27 aurel32
    l2 = gen_new_label();
6724 a7812ae4 pbrook
    t0 = tcg_temp_local_new_i32();
6725 57951c27 aurel32
    /* No error here: 6 bits are used */
6726 57951c27 aurel32
    tcg_gen_andi_i32(t0, arg2, 0x3F);
6727 57951c27 aurel32
    tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
6728 57951c27 aurel32
    tcg_gen_shl_i32(ret, arg1, t0);
6729 57951c27 aurel32
    tcg_gen_br(l2);
6730 57951c27 aurel32
    gen_set_label(l1);
6731 57951c27 aurel32
    tcg_gen_movi_i32(ret, 0);
6732 57951c27 aurel32
    tcg_gen_br(l2);
6733 a7812ae4 pbrook
    tcg_temp_free_i32(t0);
6734 57951c27 aurel32
}
6735 57951c27 aurel32
GEN_SPEOP_ARITH2(evslw, gen_op_evslw);
6736 a7812ae4 pbrook
static always_inline void gen_op_evrlw (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6737 57951c27 aurel32
{
6738 a7812ae4 pbrook
    TCGv_i32 t0 = tcg_temp_new_i32();
6739 57951c27 aurel32
    tcg_gen_andi_i32(t0, arg2, 0x1F);
6740 57951c27 aurel32
    tcg_gen_rotl_i32(ret, arg1, t0);
6741 a7812ae4 pbrook
    tcg_temp_free_i32(t0);
6742 57951c27 aurel32
}
6743 57951c27 aurel32
GEN_SPEOP_ARITH2(evrlw, gen_op_evrlw);
6744 57951c27 aurel32
static always_inline void gen_evmergehi (DisasContext *ctx)
6745 57951c27 aurel32
{
6746 57951c27 aurel32
    if (unlikely(!ctx->spe_enabled)) {
6747 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);
6748 57951c27 aurel32
        return;
6749 57951c27 aurel32
    }
6750 57951c27 aurel32
#if defined(TARGET_PPC64)
6751 a7812ae4 pbrook
    TCGv t0 = tcg_temp_new();
6752 a7812ae4 pbrook
    TCGv t1 = tcg_temp_new();
6753 57951c27 aurel32
    tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);
6754 57951c27 aurel32
    tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
6755 57951c27 aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
6756 57951c27 aurel32
    tcg_temp_free(t0);
6757 57951c27 aurel32
    tcg_temp_free(t1);
6758 57951c27 aurel32
#else
6759 57951c27 aurel32
    tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
6760 57951c27 aurel32
    tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
6761 57951c27 aurel32
#endif
6762 57951c27 aurel32
}
6763 57951c27 aurel32
GEN_SPEOP_ARITH2(evaddw, tcg_gen_add_i32);
6764 a7812ae4 pbrook
static always_inline void gen_op_evsubf (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
6765 0487d6a8 j_mayer
{
6766 57951c27 aurel32
    tcg_gen_sub_i32(ret, arg2, arg1);
6767 57951c27 aurel32
}
6768 57951c27 aurel32
GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf);
6769 0487d6a8 j_mayer
6770 57951c27 aurel32
/* SPE arithmetic immediate */
6771 57951c27 aurel32
#if defined(TARGET_PPC64)
6772 57951c27 aurel32
#define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
6773 57951c27 aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
6774 57951c27 aurel32
{                                                                             \
6775 57951c27 aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
6776 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6777 57951c27 aurel32
        return;                                                               \
6778 57951c27 aurel32
    }                                                                         \
6779 a7812ae4 pbrook
    TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6780 a7812ae4 pbrook
    TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6781 a7812ae4 pbrook
    TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
6782 57951c27 aurel32
    tcg_gen_trunc_i64_i32(t0, cpu_gpr[rB(ctx->opcode)]);                      \
6783 57951c27 aurel32
    tcg_op(t0, t0, rA(ctx->opcode));                                          \
6784 57951c27 aurel32
    tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32);                       \
6785 57951c27 aurel32
    tcg_gen_trunc_i64_i32(t1, t2);                                            \
6786 e06fcd75 aurel32
    tcg_temp_free_i64(t2);                                                    \
6787 57951c27 aurel32
    tcg_op(t1, t1, rA(ctx->opcode));                                          \
6788 57951c27 aurel32
    tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
6789 a7812ae4 pbrook
    tcg_temp_free_i32(t0);                                                    \
6790 a7812ae4 pbrook
    tcg_temp_free_i32(t1);                                                    \
6791 57951c27 aurel32
}
6792 57951c27 aurel32
#else
6793 57951c27 aurel32
#define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
6794 57951c27 aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
6795 57951c27 aurel32
{                                                                             \
6796 57951c27 aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
6797 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6798 57951c27 aurel32
        return;                                                               \
6799 57951c27 aurel32
    }                                                                         \
6800 57951c27 aurel32
    tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],                \
6801 57951c27 aurel32
           rA(ctx->opcode));                                                  \
6802 57951c27 aurel32
    tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)],              \
6803 57951c27 aurel32
           rA(ctx->opcode));                                                  \
6804 57951c27 aurel32
}
6805 57951c27 aurel32
#endif
6806 57951c27 aurel32
GEN_SPEOP_ARITH_IMM2(evaddiw, tcg_gen_addi_i32);
6807 57951c27 aurel32
GEN_SPEOP_ARITH_IMM2(evsubifw, tcg_gen_subi_i32);
6808 57951c27 aurel32
6809 57951c27 aurel32
/* SPE comparison */
6810 57951c27 aurel32
#if defined(TARGET_PPC64)
6811 57951c27 aurel32
#define GEN_SPEOP_COMP(name, tcg_cond)                                        \
6812 57951c27 aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
6813 57951c27 aurel32
{                                                                             \
6814 57951c27 aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
6815 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6816 57951c27 aurel32
        return;                                                               \
6817 57951c27 aurel32
    }                                                                         \
6818 57951c27 aurel32
    int l1 = gen_new_label();                                                 \
6819 57951c27 aurel32
    int l2 = gen_new_label();                                                 \
6820 57951c27 aurel32
    int l3 = gen_new_label();                                                 \
6821 57951c27 aurel32
    int l4 = gen_new_label();                                                 \
6822 a7812ae4 pbrook
    TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
6823 a7812ae4 pbrook
    TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
6824 a7812ae4 pbrook
    TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
6825 57951c27 aurel32
    tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
6826 57951c27 aurel32
    tcg_gen_trunc_i64_i32(t1, cpu_gpr[rB(ctx->opcode)]);                      \
6827 57951c27 aurel32
    tcg_gen_brcond_i32(tcg_cond, t0, t1, l1);                                 \
6828 a7812ae4 pbrook
    tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0);                          \
6829 57951c27 aurel32
    tcg_gen_br(l2);                                                           \
6830 57951c27 aurel32
    gen_set_label(l1);                                                        \
6831 57951c27 aurel32
    tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
6832 57951c27 aurel32
                     CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
6833 57951c27 aurel32
    gen_set_label(l2);                                                        \
6834 57951c27 aurel32
    tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
6835 57951c27 aurel32
    tcg_gen_trunc_i64_i32(t0, t2);                                            \
6836 57951c27 aurel32
    tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32);                       \
6837 57951c27 aurel32
    tcg_gen_trunc_i64_i32(t1, t2);                                            \
6838 a7812ae4 pbrook
    tcg_temp_free_i64(t2);                                                    \
6839 57951c27 aurel32
    tcg_gen_brcond_i32(tcg_cond, t0, t1, l3);                                 \
6840 57951c27 aurel32
    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
6841 57951c27 aurel32
                     ~(CRF_CH | CRF_CH_AND_CL));                              \
6842 57951c27 aurel32
    tcg_gen_br(l4);                                                           \
6843 57951c27 aurel32
    gen_set_label(l3);                                                        \
6844 57951c27 aurel32
    tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
6845 57951c27 aurel32
                    CRF_CH | CRF_CH_OR_CL);                                   \
6846 57951c27 aurel32
    gen_set_label(l4);                                                        \
6847 a7812ae4 pbrook
    tcg_temp_free_i32(t0);                                                    \
6848 a7812ae4 pbrook
    tcg_temp_free_i32(t1);                                                    \
6849 57951c27 aurel32
}
6850 57951c27 aurel32
#else
6851 57951c27 aurel32
#define GEN_SPEOP_COMP(name, tcg_cond)                                        \
6852 57951c27 aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
6853 57951c27 aurel32
{                                                                             \
6854 57951c27 aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
6855 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
6856 57951c27 aurel32
        return;                                                               \
6857 57951c27 aurel32
    }                                                                         \
6858 57951c27 aurel32
    int l1 = gen_new_label();                                                 \
6859 57951c27 aurel32
    int l2 = gen_new_label();                                                 \
6860 57951c27 aurel32
    int l3 = gen_new_label();                                                 \
6861 57951c27 aurel32
    int l4 = gen_new_label();                                                 \
6862 57951c27 aurel32
                                                                              \
6863 57951c27 aurel32
    tcg_gen_brcond_i32(tcg_cond, cpu_gpr[rA(ctx->opcode)],                    \
6864 57951c27 aurel32
                       cpu_gpr[rB(ctx->opcode)], l1);                         \
6865 57951c27 aurel32
    tcg_gen_movi_tl(cpu_crf[crfD(ctx->opcode)], 0);                           \
6866 57951c27 aurel32
    tcg_gen_br(l2);                                                           \
6867 57951c27 aurel32
    gen_set_label(l1);                                                        \
6868 57951c27 aurel32
    tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
6869 57951c27 aurel32
                     CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
6870 57951c27 aurel32
    gen_set_label(l2);                                                        \
6871 57951c27 aurel32
    tcg_gen_brcond_i32(tcg_cond, cpu_gprh[rA(ctx->opcode)],                   \
6872 57951c27 aurel32
                       cpu_gprh[rB(ctx->opcode)], l3);                        \
6873 57951c27 aurel32
    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
6874 57951c27 aurel32
                     ~(CRF_CH | CRF_CH_AND_CL));                              \
6875 57951c27 aurel32
    tcg_gen_br(l4);                                                           \
6876 57951c27 aurel32
    gen_set_label(l3);                                                        \
6877 57951c27 aurel32
    tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
6878 57951c27 aurel32
                    CRF_CH | CRF_CH_OR_CL);                                   \
6879 57951c27 aurel32
    gen_set_label(l4);                                                        \
6880 57951c27 aurel32
}
6881 57951c27 aurel32
#endif
6882 57951c27 aurel32
GEN_SPEOP_COMP(evcmpgtu, TCG_COND_GTU);
6883 57951c27 aurel32
GEN_SPEOP_COMP(evcmpgts, TCG_COND_GT);
6884 57951c27 aurel32
GEN_SPEOP_COMP(evcmpltu, TCG_COND_LTU);
6885 57951c27 aurel32
GEN_SPEOP_COMP(evcmplts, TCG_COND_LT);
6886 57951c27 aurel32
GEN_SPEOP_COMP(evcmpeq, TCG_COND_EQ);
6887 57951c27 aurel32
6888 57951c27 aurel32
/* SPE misc */
6889 57951c27 aurel32
static always_inline void gen_brinc (DisasContext *ctx)
6890 57951c27 aurel32
{
6891 57951c27 aurel32
    /* Note: brinc is usable even if SPE is disabled */
6892 a7812ae4 pbrook
    gen_helper_brinc(cpu_gpr[rD(ctx->opcode)],
6893 a7812ae4 pbrook
                     cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
6894 0487d6a8 j_mayer
}
6895 57951c27 aurel32
static always_inline void gen_evmergelo (DisasContext *ctx)
6896 57951c27 aurel32
{
6897 57951c27 aurel32
    if (unlikely(!ctx->spe_enabled)) {
6898 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);
6899 57951c27 aurel32
        return;
6900 57951c27 aurel32
    }
6901 57951c27 aurel32
#if defined(TARGET_PPC64)
6902 a7812ae4 pbrook
    TCGv t0 = tcg_temp_new();
6903 a7812ae4 pbrook
    TCGv t1 = tcg_temp_new();
6904 57951c27 aurel32
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFLL);
6905 57951c27 aurel32
    tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
6906 57951c27 aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
6907 57951c27 aurel32
    tcg_temp_free(t0);
6908 57951c27 aurel32
    tcg_temp_free(t1);
6909 57951c27 aurel32
#else
6910 57951c27 aurel32
    tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
6911 33890b3e Nathan Froyd
    tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
6912 57951c27 aurel32
#endif
6913 57951c27 aurel32
}
6914 57951c27 aurel32
static always_inline void gen_evmergehilo (DisasContext *ctx)
6915 57951c27 aurel32
{
6916 57951c27 aurel32
    if (unlikely(!ctx->spe_enabled)) {
6917 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);
6918 57951c27 aurel32
        return;
6919 57951c27 aurel32
    }
6920 57951c27 aurel32
#if defined(TARGET_PPC64)
6921 a7812ae4 pbrook
    TCGv t0 = tcg_temp_new();
6922 a7812ae4 pbrook
    TCGv t1 = tcg_temp_new();
6923 57951c27 aurel32
    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFLL);
6924 57951c27 aurel32
    tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
6925 57951c27 aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
6926 57951c27 aurel32
    tcg_temp_free(t0);
6927 57951c27 aurel32
    tcg_temp_free(t1);
6928 57951c27 aurel32
#else
6929 57951c27 aurel32
    tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
6930 57951c27 aurel32
    tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
6931 57951c27 aurel32
#endif
6932 57951c27 aurel32
}
6933 57951c27 aurel32
static always_inline void gen_evmergelohi (DisasContext *ctx)
6934 57951c27 aurel32
{
6935 57951c27 aurel32
    if (unlikely(!ctx->spe_enabled)) {
6936 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);
6937 57951c27 aurel32
        return;
6938 57951c27 aurel32
    }
6939 57951c27 aurel32
#if defined(TARGET_PPC64)
6940 a7812ae4 pbrook
    TCGv t0 = tcg_temp_new();
6941 a7812ae4 pbrook
    TCGv t1 = tcg_temp_new();
6942 57951c27 aurel32
    tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);
6943 57951c27 aurel32
    tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
6944 57951c27 aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
6945 57951c27 aurel32
    tcg_temp_free(t0);
6946 57951c27 aurel32
    tcg_temp_free(t1);
6947 57951c27 aurel32
#else
6948 33890b3e Nathan Froyd
    if (rD(ctx->opcode) == rA(ctx->opcode)) {
6949 33890b3e Nathan Froyd
        TCGv_i32 tmp = tcg_temp_new_i32();
6950 33890b3e Nathan Froyd
        tcg_gen_mov_i32(tmp, cpu_gpr[rA(ctx->opcode)]);
6951 33890b3e Nathan Froyd
        tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
6952 33890b3e Nathan Froyd
        tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], tmp);
6953 33890b3e Nathan Froyd
        tcg_temp_free_i32(tmp);
6954 33890b3e Nathan Froyd
    } else {
6955 33890b3e Nathan Froyd
        tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
6956 33890b3e Nathan Froyd
        tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
6957 33890b3e Nathan Froyd
    }
6958 57951c27 aurel32
#endif
6959 57951c27 aurel32
}
6960 57951c27 aurel32
static always_inline void gen_evsplati (DisasContext *ctx)
6961 57951c27 aurel32
{
6962 38d14952 aurel32
    uint64_t imm = ((int32_t)(rA(ctx->opcode) << 11)) >> 27;
6963 0487d6a8 j_mayer
6964 57951c27 aurel32
#if defined(TARGET_PPC64)
6965 38d14952 aurel32
    tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm);
6966 57951c27 aurel32
#else
6967 57951c27 aurel32
    tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
6968 57951c27 aurel32
    tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
6969 57951c27 aurel32
#endif
6970 57951c27 aurel32
}
6971 b068d6a7 j_mayer
static always_inline void gen_evsplatfi (DisasContext *ctx)
6972 0487d6a8 j_mayer
{
6973 38d14952 aurel32
    uint64_t imm = rA(ctx->opcode) << 11;
6974 0487d6a8 j_mayer
6975 57951c27 aurel32
#if defined(TARGET_PPC64)
6976 38d14952 aurel32
    tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm);
6977 57951c27 aurel32
#else
6978 57951c27 aurel32
    tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
6979 57951c27 aurel32
    tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
6980 57951c27 aurel32
#endif
6981 0487d6a8 j_mayer
}
6982 0487d6a8 j_mayer
6983 57951c27 aurel32
static always_inline void gen_evsel (DisasContext *ctx)
6984 57951c27 aurel32
{
6985 57951c27 aurel32
    int l1 = gen_new_label();
6986 57951c27 aurel32
    int l2 = gen_new_label();
6987 57951c27 aurel32
    int l3 = gen_new_label();
6988 57951c27 aurel32
    int l4 = gen_new_label();
6989 a7812ae4 pbrook
    TCGv_i32 t0 = tcg_temp_local_new_i32();
6990 57951c27 aurel32
#if defined(TARGET_PPC64)
6991 a7812ae4 pbrook
    TCGv t1 = tcg_temp_local_new();
6992 a7812ae4 pbrook
    TCGv t2 = tcg_temp_local_new();
6993 57951c27 aurel32
#endif
6994 57951c27 aurel32
    tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 3);
6995 57951c27 aurel32
    tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
6996 57951c27 aurel32
#if defined(TARGET_PPC64)
6997 57951c27 aurel32
    tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF00000000ULL);
6998 57951c27 aurel32
#else
6999 57951c27 aurel32
    tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
7000 57951c27 aurel32
#endif
7001 57951c27 aurel32
    tcg_gen_br(l2);
7002 57951c27 aurel32
    gen_set_label(l1);
7003 57951c27 aurel32
#if defined(TARGET_PPC64)
7004 57951c27 aurel32
    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0xFFFFFFFF00000000ULL);
7005 57951c27 aurel32
#else
7006 57951c27 aurel32
    tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
7007 57951c27 aurel32
#endif
7008 57951c27 aurel32
    gen_set_label(l2);
7009 57951c27 aurel32
    tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 2);
7010 57951c27 aurel32
    tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l3);
7011 57951c27 aurel32
#if defined(TARGET_PPC64)
7012 57951c27 aurel32
    tcg_gen_andi_tl(t2, cpu_gpr[rA(ctx->opcode)], 0x00000000FFFFFFFFULL);
7013 57951c27 aurel32
#else
7014 57951c27 aurel32
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
7015 57951c27 aurel32
#endif
7016 57951c27 aurel32
    tcg_gen_br(l4);
7017 57951c27 aurel32
    gen_set_label(l3);
7018 57951c27 aurel32
#if defined(TARGET_PPC64)
7019 57951c27 aurel32
    tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFULL);
7020 57951c27 aurel32
#else
7021 57951c27 aurel32
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
7022 57951c27 aurel32
#endif
7023 57951c27 aurel32
    gen_set_label(l4);
7024 a7812ae4 pbrook
    tcg_temp_free_i32(t0);
7025 57951c27 aurel32
#if defined(TARGET_PPC64)
7026 57951c27 aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t1, t2);
7027 57951c27 aurel32
    tcg_temp_free(t1);
7028 57951c27 aurel32
    tcg_temp_free(t2);
7029 57951c27 aurel32
#endif
7030 57951c27 aurel32
}
7031 e8eaa2c0 Blue Swirl
7032 e8eaa2c0 Blue Swirl
static void gen_evsel0(DisasContext *ctx)
7033 57951c27 aurel32
{
7034 57951c27 aurel32
    gen_evsel(ctx);
7035 57951c27 aurel32
}
7036 e8eaa2c0 Blue Swirl
7037 e8eaa2c0 Blue Swirl
static void gen_evsel1(DisasContext *ctx)
7038 57951c27 aurel32
{
7039 57951c27 aurel32
    gen_evsel(ctx);
7040 57951c27 aurel32
}
7041 e8eaa2c0 Blue Swirl
7042 e8eaa2c0 Blue Swirl
static void gen_evsel2(DisasContext *ctx)
7043 57951c27 aurel32
{
7044 57951c27 aurel32
    gen_evsel(ctx);
7045 57951c27 aurel32
}
7046 e8eaa2c0 Blue Swirl
7047 e8eaa2c0 Blue Swirl
static void gen_evsel3(DisasContext *ctx)
7048 57951c27 aurel32
{
7049 57951c27 aurel32
    gen_evsel(ctx);
7050 57951c27 aurel32
}
7051 0487d6a8 j_mayer
7052 0487d6a8 j_mayer
GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
7053 0487d6a8 j_mayer
GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
7054 0487d6a8 j_mayer
GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
7055 0487d6a8 j_mayer
GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
7056 0487d6a8 j_mayer
GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
7057 0487d6a8 j_mayer
GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
7058 0487d6a8 j_mayer
GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
7059 0487d6a8 j_mayer
GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
7060 0487d6a8 j_mayer
GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
7061 0487d6a8 j_mayer
GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
7062 0487d6a8 j_mayer
GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
7063 0487d6a8 j_mayer
GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
7064 0487d6a8 j_mayer
GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
7065 0487d6a8 j_mayer
GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
7066 0487d6a8 j_mayer
GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
7067 0487d6a8 j_mayer
GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
7068 0487d6a8 j_mayer
GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
7069 0487d6a8 j_mayer
GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
7070 0487d6a8 j_mayer
GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
7071 0487d6a8 j_mayer
GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
7072 0487d6a8 j_mayer
GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
7073 0487d6a8 j_mayer
GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
7074 0487d6a8 j_mayer
GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
7075 0487d6a8 j_mayer
GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
7076 0487d6a8 j_mayer
GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
7077 0487d6a8 j_mayer
7078 6a6ae23f aurel32
/* SPE load and stores */
7079 76db3ba4 aurel32
static always_inline void gen_addr_spe_imm_index (DisasContext *ctx, TCGv EA, int sh)
7080 6a6ae23f aurel32
{
7081 6a6ae23f aurel32
    target_ulong uimm = rB(ctx->opcode);
7082 6a6ae23f aurel32
7083 76db3ba4 aurel32
    if (rA(ctx->opcode) == 0) {
7084 6a6ae23f aurel32
        tcg_gen_movi_tl(EA, uimm << sh);
7085 76db3ba4 aurel32
    } else {
7086 6a6ae23f aurel32
        tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], uimm << sh);
7087 76db3ba4 aurel32
#if defined(TARGET_PPC64)
7088 76db3ba4 aurel32
        if (!ctx->sf_mode) {
7089 76db3ba4 aurel32
            tcg_gen_ext32u_tl(EA, EA);
7090 76db3ba4 aurel32
        }
7091 76db3ba4 aurel32
#endif
7092 76db3ba4 aurel32
    }
7093 0487d6a8 j_mayer
}
7094 6a6ae23f aurel32
7095 6a6ae23f aurel32
static always_inline void gen_op_evldd(DisasContext *ctx, TCGv addr)
7096 6a6ae23f aurel32
{
7097 6a6ae23f aurel32
#if defined(TARGET_PPC64)
7098 76db3ba4 aurel32
    gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7099 6a6ae23f aurel32
#else
7100 6a6ae23f aurel32
    TCGv_i64 t0 = tcg_temp_new_i64();
7101 76db3ba4 aurel32
    gen_qemu_ld64(ctx, t0, addr);
7102 6a6ae23f aurel32
    tcg_gen_trunc_i64_i32(cpu_gpr[rD(ctx->opcode)], t0);
7103 6a6ae23f aurel32
    tcg_gen_shri_i64(t0, t0, 32);
7104 6a6ae23f aurel32
    tcg_gen_trunc_i64_i32(cpu_gprh[rD(ctx->opcode)], t0);
7105 6a6ae23f aurel32
    tcg_temp_free_i64(t0);
7106 6a6ae23f aurel32
#endif
7107 0487d6a8 j_mayer
}
7108 6a6ae23f aurel32
7109 6a6ae23f aurel32
static always_inline void gen_op_evldw(DisasContext *ctx, TCGv addr)
7110 6a6ae23f aurel32
{
7111 0487d6a8 j_mayer
#if defined(TARGET_PPC64)
7112 6a6ae23f aurel32
    TCGv t0 = tcg_temp_new();
7113 76db3ba4 aurel32
    gen_qemu_ld32u(ctx, t0, addr);
7114 6a6ae23f aurel32
    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
7115 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 4);
7116 76db3ba4 aurel32
    gen_qemu_ld32u(ctx, t0, addr);
7117 6a6ae23f aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7118 6a6ae23f aurel32
    tcg_temp_free(t0);
7119 6a6ae23f aurel32
#else
7120 76db3ba4 aurel32
    gen_qemu_ld32u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
7121 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 4);
7122 76db3ba4 aurel32
    gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7123 6a6ae23f aurel32
#endif
7124 0487d6a8 j_mayer
}
7125 6a6ae23f aurel32
7126 6a6ae23f aurel32
static always_inline void gen_op_evldh(DisasContext *ctx, TCGv addr)
7127 6a6ae23f aurel32
{
7128 6a6ae23f aurel32
    TCGv t0 = tcg_temp_new();
7129 6a6ae23f aurel32
#if defined(TARGET_PPC64)
7130 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, t0, addr);
7131 6a6ae23f aurel32
    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
7132 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 2);
7133 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, t0, addr);
7134 6a6ae23f aurel32
    tcg_gen_shli_tl(t0, t0, 32);
7135 6a6ae23f aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7136 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 2);
7137 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, t0, addr);
7138 6a6ae23f aurel32
    tcg_gen_shli_tl(t0, t0, 16);
7139 6a6ae23f aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7140 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 2);
7141 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, t0, addr);
7142 6a6ae23f aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7143 0487d6a8 j_mayer
#else
7144 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, t0, addr);
7145 6a6ae23f aurel32
    tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
7146 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 2);
7147 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, t0, addr);
7148 6a6ae23f aurel32
    tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
7149 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 2);
7150 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, t0, addr);
7151 6a6ae23f aurel32
    tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
7152 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 2);
7153 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, t0, addr);
7154 6a6ae23f aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7155 0487d6a8 j_mayer
#endif
7156 6a6ae23f aurel32
    tcg_temp_free(t0);
7157 0487d6a8 j_mayer
}
7158 0487d6a8 j_mayer
7159 6a6ae23f aurel32
static always_inline void gen_op_evlhhesplat(DisasContext *ctx, TCGv addr)
7160 6a6ae23f aurel32
{
7161 6a6ae23f aurel32
    TCGv t0 = tcg_temp_new();
7162 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, t0, addr);
7163 6a6ae23f aurel32
#if defined(TARGET_PPC64)
7164 6a6ae23f aurel32
    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
7165 6a6ae23f aurel32
    tcg_gen_shli_tl(t0, t0, 16);
7166 6a6ae23f aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7167 6a6ae23f aurel32
#else
7168 6a6ae23f aurel32
    tcg_gen_shli_tl(t0, t0, 16);
7169 6a6ae23f aurel32
    tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
7170 6a6ae23f aurel32
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
7171 6a6ae23f aurel32
#endif
7172 6a6ae23f aurel32
    tcg_temp_free(t0);
7173 0487d6a8 j_mayer
}
7174 0487d6a8 j_mayer
7175 6a6ae23f aurel32
static always_inline void gen_op_evlhhousplat(DisasContext *ctx, TCGv addr)
7176 6a6ae23f aurel32
{
7177 6a6ae23f aurel32
    TCGv t0 = tcg_temp_new();
7178 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, t0, addr);
7179 6a6ae23f aurel32
#if defined(TARGET_PPC64)
7180 6a6ae23f aurel32
    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
7181 6a6ae23f aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7182 6a6ae23f aurel32
#else
7183 6a6ae23f aurel32
    tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
7184 6a6ae23f aurel32
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
7185 6a6ae23f aurel32
#endif
7186 6a6ae23f aurel32
    tcg_temp_free(t0);
7187 0487d6a8 j_mayer
}
7188 0487d6a8 j_mayer
7189 6a6ae23f aurel32
static always_inline void gen_op_evlhhossplat(DisasContext *ctx, TCGv addr)
7190 6a6ae23f aurel32
{
7191 6a6ae23f aurel32
    TCGv t0 = tcg_temp_new();
7192 76db3ba4 aurel32
    gen_qemu_ld16s(ctx, t0, addr);
7193 6a6ae23f aurel32
#if defined(TARGET_PPC64)
7194 6a6ae23f aurel32
    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
7195 6a6ae23f aurel32
    tcg_gen_ext32u_tl(t0, t0);
7196 6a6ae23f aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7197 6a6ae23f aurel32
#else
7198 6a6ae23f aurel32
    tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
7199 6a6ae23f aurel32
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
7200 6a6ae23f aurel32
#endif
7201 6a6ae23f aurel32
    tcg_temp_free(t0);
7202 6a6ae23f aurel32
}
7203 6a6ae23f aurel32
7204 6a6ae23f aurel32
static always_inline void gen_op_evlwhe(DisasContext *ctx, TCGv addr)
7205 6a6ae23f aurel32
{
7206 6a6ae23f aurel32
    TCGv t0 = tcg_temp_new();
7207 6a6ae23f aurel32
#if defined(TARGET_PPC64)
7208 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, t0, addr);
7209 6a6ae23f aurel32
    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
7210 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 2);
7211 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, t0, addr);
7212 6a6ae23f aurel32
    tcg_gen_shli_tl(t0, t0, 16);
7213 6a6ae23f aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7214 6a6ae23f aurel32
#else
7215 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, t0, addr);
7216 6a6ae23f aurel32
    tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
7217 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 2);
7218 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, t0, addr);
7219 6a6ae23f aurel32
    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
7220 6a6ae23f aurel32
#endif
7221 6a6ae23f aurel32
    tcg_temp_free(t0);
7222 6a6ae23f aurel32
}
7223 6a6ae23f aurel32
7224 6a6ae23f aurel32
static always_inline void gen_op_evlwhou(DisasContext *ctx, TCGv addr)
7225 6a6ae23f aurel32
{
7226 6a6ae23f aurel32
#if defined(TARGET_PPC64)
7227 6a6ae23f aurel32
    TCGv t0 = tcg_temp_new();
7228 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7229 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 2);
7230 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, t0, addr);
7231 6a6ae23f aurel32
    tcg_gen_shli_tl(t0, t0, 32);
7232 6a6ae23f aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7233 6a6ae23f aurel32
    tcg_temp_free(t0);
7234 6a6ae23f aurel32
#else
7235 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
7236 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 2);
7237 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7238 6a6ae23f aurel32
#endif
7239 6a6ae23f aurel32
}
7240 6a6ae23f aurel32
7241 6a6ae23f aurel32
static always_inline void gen_op_evlwhos(DisasContext *ctx, TCGv addr)
7242 6a6ae23f aurel32
{
7243 6a6ae23f aurel32
#if defined(TARGET_PPC64)
7244 6a6ae23f aurel32
    TCGv t0 = tcg_temp_new();
7245 76db3ba4 aurel32
    gen_qemu_ld16s(ctx, t0, addr);
7246 6a6ae23f aurel32
    tcg_gen_ext32u_tl(cpu_gpr[rD(ctx->opcode)], t0);
7247 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 2);
7248 76db3ba4 aurel32
    gen_qemu_ld16s(ctx, t0, addr);
7249 6a6ae23f aurel32
    tcg_gen_shli_tl(t0, t0, 32);
7250 6a6ae23f aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7251 6a6ae23f aurel32
    tcg_temp_free(t0);
7252 6a6ae23f aurel32
#else
7253 76db3ba4 aurel32
    gen_qemu_ld16s(ctx, cpu_gprh[rD(ctx->opcode)], addr);
7254 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 2);
7255 76db3ba4 aurel32
    gen_qemu_ld16s(ctx, cpu_gpr[rD(ctx->opcode)], addr);
7256 6a6ae23f aurel32
#endif
7257 6a6ae23f aurel32
}
7258 6a6ae23f aurel32
7259 6a6ae23f aurel32
static always_inline void gen_op_evlwwsplat(DisasContext *ctx, TCGv addr)
7260 6a6ae23f aurel32
{
7261 6a6ae23f aurel32
    TCGv t0 = tcg_temp_new();
7262 76db3ba4 aurel32
    gen_qemu_ld32u(ctx, t0, addr);
7263 0487d6a8 j_mayer
#if defined(TARGET_PPC64)
7264 6a6ae23f aurel32
    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
7265 6a6ae23f aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7266 6a6ae23f aurel32
#else
7267 6a6ae23f aurel32
    tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
7268 6a6ae23f aurel32
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
7269 6a6ae23f aurel32
#endif
7270 6a6ae23f aurel32
    tcg_temp_free(t0);
7271 6a6ae23f aurel32
}
7272 6a6ae23f aurel32
7273 6a6ae23f aurel32
static always_inline void gen_op_evlwhsplat(DisasContext *ctx, TCGv addr)
7274 6a6ae23f aurel32
{
7275 6a6ae23f aurel32
    TCGv t0 = tcg_temp_new();
7276 6a6ae23f aurel32
#if defined(TARGET_PPC64)
7277 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, t0, addr);
7278 6a6ae23f aurel32
    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
7279 6a6ae23f aurel32
    tcg_gen_shli_tl(t0, t0, 32);
7280 6a6ae23f aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7281 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 2);
7282 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, t0, addr);
7283 6a6ae23f aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7284 6a6ae23f aurel32
    tcg_gen_shli_tl(t0, t0, 16);
7285 6a6ae23f aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
7286 6a6ae23f aurel32
#else
7287 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, t0, addr);
7288 6a6ae23f aurel32
    tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
7289 6a6ae23f aurel32
    tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
7290 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 2);
7291 76db3ba4 aurel32
    gen_qemu_ld16u(ctx, t0, addr);
7292 6a6ae23f aurel32
    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
7293 6a6ae23f aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
7294 0487d6a8 j_mayer
#endif
7295 6a6ae23f aurel32
    tcg_temp_free(t0);
7296 6a6ae23f aurel32
}
7297 6a6ae23f aurel32
7298 6a6ae23f aurel32
static always_inline void gen_op_evstdd(DisasContext *ctx, TCGv addr)
7299 6a6ae23f aurel32
{
7300 6a6ae23f aurel32
#if defined(TARGET_PPC64)
7301 76db3ba4 aurel32
    gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7302 0487d6a8 j_mayer
#else
7303 6a6ae23f aurel32
    TCGv_i64 t0 = tcg_temp_new_i64();
7304 6a6ae23f aurel32
    tcg_gen_concat_i32_i64(t0, cpu_gpr[rS(ctx->opcode)], cpu_gprh[rS(ctx->opcode)]);
7305 76db3ba4 aurel32
    gen_qemu_st64(ctx, t0, addr);
7306 6a6ae23f aurel32
    tcg_temp_free_i64(t0);
7307 6a6ae23f aurel32
#endif
7308 6a6ae23f aurel32
}
7309 6a6ae23f aurel32
7310 6a6ae23f aurel32
static always_inline void gen_op_evstdw(DisasContext *ctx, TCGv addr)
7311 6a6ae23f aurel32
{
7312 0487d6a8 j_mayer
#if defined(TARGET_PPC64)
7313 6a6ae23f aurel32
    TCGv t0 = tcg_temp_new();
7314 6a6ae23f aurel32
    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
7315 76db3ba4 aurel32
    gen_qemu_st32(ctx, t0, addr);
7316 6a6ae23f aurel32
    tcg_temp_free(t0);
7317 6a6ae23f aurel32
#else
7318 76db3ba4 aurel32
    gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
7319 6a6ae23f aurel32
#endif
7320 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 4);
7321 76db3ba4 aurel32
    gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7322 6a6ae23f aurel32
}
7323 6a6ae23f aurel32
7324 6a6ae23f aurel32
static always_inline void gen_op_evstdh(DisasContext *ctx, TCGv addr)
7325 6a6ae23f aurel32
{
7326 6a6ae23f aurel32
    TCGv t0 = tcg_temp_new();
7327 6a6ae23f aurel32
#if defined(TARGET_PPC64)
7328 6a6ae23f aurel32
    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48);
7329 6a6ae23f aurel32
#else
7330 6a6ae23f aurel32
    tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
7331 6a6ae23f aurel32
#endif
7332 76db3ba4 aurel32
    gen_qemu_st16(ctx, t0, addr);
7333 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 2);
7334 6a6ae23f aurel32
#if defined(TARGET_PPC64)
7335 6a6ae23f aurel32
    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
7336 76db3ba4 aurel32
    gen_qemu_st16(ctx, t0, addr);
7337 6a6ae23f aurel32
#else
7338 76db3ba4 aurel32
    gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
7339 6a6ae23f aurel32
#endif
7340 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 2);
7341 6a6ae23f aurel32
    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
7342 76db3ba4 aurel32
    gen_qemu_st16(ctx, t0, addr);
7343 6a6ae23f aurel32
    tcg_temp_free(t0);
7344 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 2);
7345 76db3ba4 aurel32
    gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7346 6a6ae23f aurel32
}
7347 6a6ae23f aurel32
7348 6a6ae23f aurel32
static always_inline void gen_op_evstwhe(DisasContext *ctx, TCGv addr)
7349 6a6ae23f aurel32
{
7350 6a6ae23f aurel32
    TCGv t0 = tcg_temp_new();
7351 6a6ae23f aurel32
#if defined(TARGET_PPC64)
7352 6a6ae23f aurel32
    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48);
7353 6a6ae23f aurel32
#else
7354 6a6ae23f aurel32
    tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
7355 6a6ae23f aurel32
#endif
7356 76db3ba4 aurel32
    gen_qemu_st16(ctx, t0, addr);
7357 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 2);
7358 6a6ae23f aurel32
    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
7359 76db3ba4 aurel32
    gen_qemu_st16(ctx, t0, addr);
7360 6a6ae23f aurel32
    tcg_temp_free(t0);
7361 6a6ae23f aurel32
}
7362 6a6ae23f aurel32
7363 6a6ae23f aurel32
static always_inline void gen_op_evstwho(DisasContext *ctx, TCGv addr)
7364 6a6ae23f aurel32
{
7365 6a6ae23f aurel32
#if defined(TARGET_PPC64)
7366 6a6ae23f aurel32
    TCGv t0 = tcg_temp_new();
7367 6a6ae23f aurel32
    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
7368 76db3ba4 aurel32
    gen_qemu_st16(ctx, t0, addr);
7369 6a6ae23f aurel32
    tcg_temp_free(t0);
7370 6a6ae23f aurel32
#else
7371 76db3ba4 aurel32
    gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
7372 6a6ae23f aurel32
#endif
7373 76db3ba4 aurel32
    gen_addr_add(ctx, addr, addr, 2);
7374 76db3ba4 aurel32
    gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7375 6a6ae23f aurel32
}
7376 6a6ae23f aurel32
7377 6a6ae23f aurel32
static always_inline void gen_op_evstwwe(DisasContext *ctx, TCGv addr)
7378 6a6ae23f aurel32
{
7379 6a6ae23f aurel32
#if defined(TARGET_PPC64)
7380 6a6ae23f aurel32
    TCGv t0 = tcg_temp_new();
7381 6a6ae23f aurel32
    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
7382 76db3ba4 aurel32
    gen_qemu_st32(ctx, t0, addr);
7383 6a6ae23f aurel32
    tcg_temp_free(t0);
7384 6a6ae23f aurel32
#else
7385 76db3ba4 aurel32
    gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
7386 6a6ae23f aurel32
#endif
7387 6a6ae23f aurel32
}
7388 6a6ae23f aurel32
7389 6a6ae23f aurel32
static always_inline void gen_op_evstwwo(DisasContext *ctx, TCGv addr)
7390 6a6ae23f aurel32
{
7391 76db3ba4 aurel32
    gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
7392 6a6ae23f aurel32
}
7393 6a6ae23f aurel32
7394 6a6ae23f aurel32
#define GEN_SPEOP_LDST(name, opc2, sh)                                        \
7395 99e300ef Blue Swirl
static void glue(gen_, name)(DisasContext *ctx)                                       \
7396 6a6ae23f aurel32
{                                                                             \
7397 6a6ae23f aurel32
    TCGv t0;                                                                  \
7398 6a6ae23f aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
7399 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7400 6a6ae23f aurel32
        return;                                                               \
7401 6a6ae23f aurel32
    }                                                                         \
7402 76db3ba4 aurel32
    gen_set_access_type(ctx, ACCESS_INT);                                     \
7403 6a6ae23f aurel32
    t0 = tcg_temp_new();                                                      \
7404 6a6ae23f aurel32
    if (Rc(ctx->opcode)) {                                                    \
7405 76db3ba4 aurel32
        gen_addr_spe_imm_index(ctx, t0, sh);                                  \
7406 6a6ae23f aurel32
    } else {                                                                  \
7407 76db3ba4 aurel32
        gen_addr_reg_index(ctx, t0);                                          \
7408 6a6ae23f aurel32
    }                                                                         \
7409 6a6ae23f aurel32
    gen_op_##name(ctx, t0);                                                   \
7410 6a6ae23f aurel32
    tcg_temp_free(t0);                                                        \
7411 6a6ae23f aurel32
}
7412 6a6ae23f aurel32
7413 6a6ae23f aurel32
GEN_SPEOP_LDST(evldd, 0x00, 3);
7414 6a6ae23f aurel32
GEN_SPEOP_LDST(evldw, 0x01, 3);
7415 6a6ae23f aurel32
GEN_SPEOP_LDST(evldh, 0x02, 3);
7416 6a6ae23f aurel32
GEN_SPEOP_LDST(evlhhesplat, 0x04, 1);
7417 6a6ae23f aurel32
GEN_SPEOP_LDST(evlhhousplat, 0x06, 1);
7418 6a6ae23f aurel32
GEN_SPEOP_LDST(evlhhossplat, 0x07, 1);
7419 6a6ae23f aurel32
GEN_SPEOP_LDST(evlwhe, 0x08, 2);
7420 6a6ae23f aurel32
GEN_SPEOP_LDST(evlwhou, 0x0A, 2);
7421 6a6ae23f aurel32
GEN_SPEOP_LDST(evlwhos, 0x0B, 2);
7422 6a6ae23f aurel32
GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2);
7423 6a6ae23f aurel32
GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2);
7424 6a6ae23f aurel32
7425 6a6ae23f aurel32
GEN_SPEOP_LDST(evstdd, 0x10, 3);
7426 6a6ae23f aurel32
GEN_SPEOP_LDST(evstdw, 0x11, 3);
7427 6a6ae23f aurel32
GEN_SPEOP_LDST(evstdh, 0x12, 3);
7428 6a6ae23f aurel32
GEN_SPEOP_LDST(evstwhe, 0x18, 2);
7429 6a6ae23f aurel32
GEN_SPEOP_LDST(evstwho, 0x1A, 2);
7430 6a6ae23f aurel32
GEN_SPEOP_LDST(evstwwe, 0x1C, 2);
7431 6a6ae23f aurel32
GEN_SPEOP_LDST(evstwwo, 0x1E, 2);
7432 0487d6a8 j_mayer
7433 0487d6a8 j_mayer
/* Multiply and add - TODO */
7434 0487d6a8 j_mayer
#if 0
7435 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
7436 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
7437 0487d6a8 j_mayer
GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
7438 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
7439 0487d6a8 j_mayer
GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
7440 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
7441 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
7442 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
7443 0487d6a8 j_mayer
GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
7444 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
7445 0487d6a8 j_mayer
GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
7446 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
7447 0487d6a8 j_mayer

7448 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
7449 0487d6a8 j_mayer
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
7450 0487d6a8 j_mayer
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
7451 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
7452 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
7453 0487d6a8 j_mayer
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
7454 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
7455 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
7456 0487d6a8 j_mayer
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
7457 0487d6a8 j_mayer
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
7458 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
7459 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
7460 0487d6a8 j_mayer
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
7461 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
7462 0487d6a8 j_mayer

7463 0487d6a8 j_mayer
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
7464 0487d6a8 j_mayer
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
7465 0487d6a8 j_mayer
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
7466 0487d6a8 j_mayer
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
7467 0487d6a8 j_mayer
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
7468 0487d6a8 j_mayer
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
7469 0487d6a8 j_mayer

7470 0487d6a8 j_mayer
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
7471 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
7472 0487d6a8 j_mayer
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
7473 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
7474 0487d6a8 j_mayer
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
7475 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
7476 0487d6a8 j_mayer
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
7477 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
7478 0487d6a8 j_mayer
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
7479 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
7480 0487d6a8 j_mayer
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
7481 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
7482 0487d6a8 j_mayer

7483 0487d6a8 j_mayer
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
7484 0487d6a8 j_mayer
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
7485 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
7486 0487d6a8 j_mayer
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
7487 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
7488 0487d6a8 j_mayer

7489 0487d6a8 j_mayer
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
7490 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
7491 0487d6a8 j_mayer
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
7492 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
7493 0487d6a8 j_mayer
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
7494 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
7495 0487d6a8 j_mayer
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
7496 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
7497 0487d6a8 j_mayer
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
7498 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
7499 0487d6a8 j_mayer
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
7500 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
7501 0487d6a8 j_mayer

7502 0487d6a8 j_mayer
GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
7503 0487d6a8 j_mayer
GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
7504 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
7505 0487d6a8 j_mayer
GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
7506 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
7507 0487d6a8 j_mayer
#endif
7508 0487d6a8 j_mayer
7509 0487d6a8 j_mayer
/***                      SPE floating-point extension                     ***/
7510 1c97856d aurel32
#if defined(TARGET_PPC64)
7511 1c97856d aurel32
#define GEN_SPEFPUOP_CONV_32_32(name)                                         \
7512 b068d6a7 j_mayer
static always_inline void gen_##name (DisasContext *ctx)                      \
7513 0487d6a8 j_mayer
{                                                                             \
7514 1c97856d aurel32
    TCGv_i32 t0;                                                              \
7515 1c97856d aurel32
    TCGv t1;                                                                  \
7516 1c97856d aurel32
    t0 = tcg_temp_new_i32();                                                  \
7517 1c97856d aurel32
    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
7518 1c97856d aurel32
    gen_helper_##name(t0, t0);                                                \
7519 1c97856d aurel32
    t1 = tcg_temp_new();                                                      \
7520 1c97856d aurel32
    tcg_gen_extu_i32_tl(t1, t0);                                              \
7521 1c97856d aurel32
    tcg_temp_free_i32(t0);                                                    \
7522 1c97856d aurel32
    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
7523 1c97856d aurel32
                    0xFFFFFFFF00000000ULL);                                   \
7524 1c97856d aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
7525 1c97856d aurel32
    tcg_temp_free(t1);                                                        \
7526 0487d6a8 j_mayer
}
7527 1c97856d aurel32
#define GEN_SPEFPUOP_CONV_32_64(name)                                         \
7528 1c97856d aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
7529 1c97856d aurel32
{                                                                             \
7530 1c97856d aurel32
    TCGv_i32 t0;                                                              \
7531 1c97856d aurel32
    TCGv t1;                                                                  \
7532 1c97856d aurel32
    t0 = tcg_temp_new_i32();                                                  \
7533 1c97856d aurel32
    gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]);                          \
7534 1c97856d aurel32
    t1 = tcg_temp_new();                                                      \
7535 1c97856d aurel32
    tcg_gen_extu_i32_tl(t1, t0);                                              \
7536 1c97856d aurel32
    tcg_temp_free_i32(t0);                                                    \
7537 1c97856d aurel32
    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
7538 1c97856d aurel32
                    0xFFFFFFFF00000000ULL);                                   \
7539 1c97856d aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
7540 1c97856d aurel32
    tcg_temp_free(t1);                                                        \
7541 1c97856d aurel32
}
7542 1c97856d aurel32
#define GEN_SPEFPUOP_CONV_64_32(name)                                         \
7543 1c97856d aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
7544 1c97856d aurel32
{                                                                             \
7545 1c97856d aurel32
    TCGv_i32 t0 = tcg_temp_new_i32();                                         \
7546 1c97856d aurel32
    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
7547 1c97856d aurel32
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0);                          \
7548 1c97856d aurel32
    tcg_temp_free_i32(t0);                                                    \
7549 1c97856d aurel32
}
7550 1c97856d aurel32
#define GEN_SPEFPUOP_CONV_64_64(name)                                         \
7551 1c97856d aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
7552 1c97856d aurel32
{                                                                             \
7553 1c97856d aurel32
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7554 1c97856d aurel32
}
7555 1c97856d aurel32
#define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
7556 57951c27 aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
7557 57951c27 aurel32
{                                                                             \
7558 1c97856d aurel32
    TCGv_i32 t0, t1;                                                          \
7559 1c97856d aurel32
    TCGv_i64 t2;                                                              \
7560 57951c27 aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
7561 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7562 57951c27 aurel32
        return;                                                               \
7563 57951c27 aurel32
    }                                                                         \
7564 1c97856d aurel32
    t0 = tcg_temp_new_i32();                                                  \
7565 1c97856d aurel32
    t1 = tcg_temp_new_i32();                                                  \
7566 1c97856d aurel32
    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
7567 1c97856d aurel32
    tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
7568 1c97856d aurel32
    gen_helper_##name(t0, t0, t1);                                            \
7569 1c97856d aurel32
    tcg_temp_free_i32(t1);                                                    \
7570 1c97856d aurel32
    t2 = tcg_temp_new();                                                      \
7571 1c97856d aurel32
    tcg_gen_extu_i32_tl(t2, t0);                                              \
7572 1c97856d aurel32
    tcg_temp_free_i32(t0);                                                    \
7573 1c97856d aurel32
    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
7574 1c97856d aurel32
                    0xFFFFFFFF00000000ULL);                                   \
7575 1c97856d aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t2);    \
7576 1c97856d aurel32
    tcg_temp_free(t2);                                                        \
7577 57951c27 aurel32
}
7578 1c97856d aurel32
#define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
7579 57951c27 aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
7580 57951c27 aurel32
{                                                                             \
7581 57951c27 aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
7582 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7583 57951c27 aurel32
        return;                                                               \
7584 57951c27 aurel32
    }                                                                         \
7585 1c97856d aurel32
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],     \
7586 1c97856d aurel32
                      cpu_gpr[rB(ctx->opcode)]);                              \
7587 57951c27 aurel32
}
7588 1c97856d aurel32
#define GEN_SPEFPUOP_COMP_32(name)                                            \
7589 57951c27 aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
7590 57951c27 aurel32
{                                                                             \
7591 1c97856d aurel32
    TCGv_i32 t0, t1;                                                          \
7592 57951c27 aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
7593 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7594 57951c27 aurel32
        return;                                                               \
7595 57951c27 aurel32
    }                                                                         \
7596 1c97856d aurel32
    t0 = tcg_temp_new_i32();                                                  \
7597 1c97856d aurel32
    t1 = tcg_temp_new_i32();                                                  \
7598 1c97856d aurel32
    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
7599 1c97856d aurel32
    tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
7600 1c97856d aurel32
    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1);                    \
7601 1c97856d aurel32
    tcg_temp_free_i32(t0);                                                    \
7602 1c97856d aurel32
    tcg_temp_free_i32(t1);                                                    \
7603 1c97856d aurel32
}
7604 1c97856d aurel32
#define GEN_SPEFPUOP_COMP_64(name)                                            \
7605 1c97856d aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
7606 1c97856d aurel32
{                                                                             \
7607 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
7608 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7609 1c97856d aurel32
        return;                                                               \
7610 1c97856d aurel32
    }                                                                         \
7611 1c97856d aurel32
    gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
7612 1c97856d aurel32
                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7613 1c97856d aurel32
}
7614 1c97856d aurel32
#else
7615 1c97856d aurel32
#define GEN_SPEFPUOP_CONV_32_32(name)                                         \
7616 1c97856d aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
7617 1c97856d aurel32
{                                                                             \
7618 1c97856d aurel32
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7619 57951c27 aurel32
}
7620 1c97856d aurel32
#define GEN_SPEFPUOP_CONV_32_64(name)                                         \
7621 1c97856d aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
7622 1c97856d aurel32
{                                                                             \
7623 1c97856d aurel32
    TCGv_i64 t0 = tcg_temp_new_i64();                                         \
7624 1c97856d aurel32
    gen_load_gpr64(t0, rB(ctx->opcode));                                      \
7625 1c97856d aurel32
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0);                          \
7626 1c97856d aurel32
    tcg_temp_free_i64(t0);                                                    \
7627 1c97856d aurel32
}
7628 1c97856d aurel32
#define GEN_SPEFPUOP_CONV_64_32(name)                                         \
7629 1c97856d aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
7630 1c97856d aurel32
{                                                                             \
7631 1c97856d aurel32
    TCGv_i64 t0 = tcg_temp_new_i64();                                         \
7632 1c97856d aurel32
    gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]);                          \
7633 1c97856d aurel32
    gen_store_gpr64(rD(ctx->opcode), t0);                                     \
7634 1c97856d aurel32
    tcg_temp_free_i64(t0);                                                    \
7635 1c97856d aurel32
}
7636 1c97856d aurel32
#define GEN_SPEFPUOP_CONV_64_64(name)                                         \
7637 1c97856d aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
7638 1c97856d aurel32
{                                                                             \
7639 1c97856d aurel32
    TCGv_i64 t0 = tcg_temp_new_i64();                                         \
7640 1c97856d aurel32
    gen_load_gpr64(t0, rB(ctx->opcode));                                      \
7641 1c97856d aurel32
    gen_helper_##name(t0, t0);                                                \
7642 1c97856d aurel32
    gen_store_gpr64(rD(ctx->opcode), t0);                                     \
7643 1c97856d aurel32
    tcg_temp_free_i64(t0);                                                    \
7644 1c97856d aurel32
}
7645 1c97856d aurel32
#define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
7646 1c97856d aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
7647 1c97856d aurel32
{                                                                             \
7648 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
7649 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7650 1c97856d aurel32
        return;                                                               \
7651 1c97856d aurel32
    }                                                                         \
7652 1c97856d aurel32
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)],                               \
7653 1c97856d aurel32
                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7654 1c97856d aurel32
}
7655 1c97856d aurel32
#define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
7656 1c97856d aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
7657 1c97856d aurel32
{                                                                             \
7658 1c97856d aurel32
    TCGv_i64 t0, t1;                                                          \
7659 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
7660 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7661 1c97856d aurel32
        return;                                                               \
7662 1c97856d aurel32
    }                                                                         \
7663 1c97856d aurel32
    t0 = tcg_temp_new_i64();                                                  \
7664 1c97856d aurel32
    t1 = tcg_temp_new_i64();                                                  \
7665 1c97856d aurel32
    gen_load_gpr64(t0, rA(ctx->opcode));                                      \
7666 1c97856d aurel32
    gen_load_gpr64(t1, rB(ctx->opcode));                                      \
7667 1c97856d aurel32
    gen_helper_##name(t0, t0, t1);                                            \
7668 1c97856d aurel32
    gen_store_gpr64(rD(ctx->opcode), t0);                                     \
7669 1c97856d aurel32
    tcg_temp_free_i64(t0);                                                    \
7670 1c97856d aurel32
    tcg_temp_free_i64(t1);                                                    \
7671 1c97856d aurel32
}
7672 1c97856d aurel32
#define GEN_SPEFPUOP_COMP_32(name)                                            \
7673 1c97856d aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
7674 1c97856d aurel32
{                                                                             \
7675 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
7676 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7677 1c97856d aurel32
        return;                                                               \
7678 1c97856d aurel32
    }                                                                         \
7679 1c97856d aurel32
    gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
7680 1c97856d aurel32
                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7681 1c97856d aurel32
}
7682 1c97856d aurel32
#define GEN_SPEFPUOP_COMP_64(name)                                            \
7683 1c97856d aurel32
static always_inline void gen_##name (DisasContext *ctx)                      \
7684 1c97856d aurel32
{                                                                             \
7685 1c97856d aurel32
    TCGv_i64 t0, t1;                                                          \
7686 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
7687 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
7688 1c97856d aurel32
        return;                                                               \
7689 1c97856d aurel32
    }                                                                         \
7690 1c97856d aurel32
    t0 = tcg_temp_new_i64();                                                  \
7691 1c97856d aurel32
    t1 = tcg_temp_new_i64();                                                  \
7692 1c97856d aurel32
    gen_load_gpr64(t0, rA(ctx->opcode));                                      \
7693 1c97856d aurel32
    gen_load_gpr64(t1, rB(ctx->opcode));                                      \
7694 1c97856d aurel32
    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1);                    \
7695 1c97856d aurel32
    tcg_temp_free_i64(t0);                                                    \
7696 1c97856d aurel32
    tcg_temp_free_i64(t1);                                                    \
7697 1c97856d aurel32
}
7698 1c97856d aurel32
#endif
7699 57951c27 aurel32
7700 0487d6a8 j_mayer
/* Single precision floating-point vectors operations */
7701 0487d6a8 j_mayer
/* Arithmetic */
7702 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_64_64(evfsadd);
7703 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_64_64(evfssub);
7704 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_64_64(evfsmul);
7705 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_64_64(evfsdiv);
7706 1c97856d aurel32
static always_inline void gen_evfsabs (DisasContext *ctx)
7707 1c97856d aurel32
{
7708 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {
7709 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);
7710 1c97856d aurel32
        return;
7711 1c97856d aurel32
    }
7712 1c97856d aurel32
#if defined(TARGET_PPC64)
7713 1c97856d aurel32
    tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000080000000LL);
7714 1c97856d aurel32
#else
7715 1c97856d aurel32
    tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x80000000);
7716 1c97856d aurel32
    tcg_gen_andi_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
7717 1c97856d aurel32
#endif
7718 1c97856d aurel32
}
7719 1c97856d aurel32
static always_inline void gen_evfsnabs (DisasContext *ctx)
7720 1c97856d aurel32
{
7721 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {
7722 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);
7723 1c97856d aurel32
        return;
7724 1c97856d aurel32
    }
7725 1c97856d aurel32
#if defined(TARGET_PPC64)
7726 1c97856d aurel32
    tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
7727 1c97856d aurel32
#else
7728 1c97856d aurel32
    tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
7729 1c97856d aurel32
    tcg_gen_ori_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
7730 1c97856d aurel32
#endif
7731 1c97856d aurel32
}
7732 1c97856d aurel32
static always_inline void gen_evfsneg (DisasContext *ctx)
7733 1c97856d aurel32
{
7734 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {
7735 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);
7736 1c97856d aurel32
        return;
7737 1c97856d aurel32
    }
7738 1c97856d aurel32
#if defined(TARGET_PPC64)
7739 1c97856d aurel32
    tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
7740 1c97856d aurel32
#else
7741 1c97856d aurel32
    tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
7742 1c97856d aurel32
    tcg_gen_xori_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
7743 1c97856d aurel32
#endif
7744 1c97856d aurel32
}
7745 1c97856d aurel32
7746 0487d6a8 j_mayer
/* Conversion */
7747 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(evfscfui);
7748 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(evfscfsi);
7749 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(evfscfuf);
7750 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(evfscfsf);
7751 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(evfsctui);
7752 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(evfsctsi);
7753 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(evfsctuf);
7754 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(evfsctsf);
7755 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(evfsctuiz);
7756 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(evfsctsiz);
7757 1c97856d aurel32
7758 0487d6a8 j_mayer
/* Comparison */
7759 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(evfscmpgt);
7760 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(evfscmplt);
7761 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(evfscmpeq);
7762 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(evfststgt);
7763 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(evfststlt);
7764 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(evfststeq);
7765 0487d6a8 j_mayer
7766 0487d6a8 j_mayer
/* Opcodes definitions */
7767 40569b7e aurel32
GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPE_SINGLE); //
7768 40569b7e aurel32
GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPE_SINGLE); //
7769 40569b7e aurel32
GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPE_SINGLE); //
7770 40569b7e aurel32
GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPE_SINGLE); //
7771 40569b7e aurel32
GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
7772 40569b7e aurel32
GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
7773 40569b7e aurel32
GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
7774 40569b7e aurel32
GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
7775 40569b7e aurel32
GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
7776 40569b7e aurel32
GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
7777 40569b7e aurel32
GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
7778 40569b7e aurel32
GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
7779 40569b7e aurel32
GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
7780 40569b7e aurel32
GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
7781 0487d6a8 j_mayer
7782 0487d6a8 j_mayer
/* Single precision floating-point operations */
7783 0487d6a8 j_mayer
/* Arithmetic */
7784 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_32_32(efsadd);
7785 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_32_32(efssub);
7786 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_32_32(efsmul);
7787 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_32_32(efsdiv);
7788 1c97856d aurel32
static always_inline void gen_efsabs (DisasContext *ctx)
7789 1c97856d aurel32
{
7790 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {
7791 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);
7792 1c97856d aurel32
        return;
7793 1c97856d aurel32
    }
7794 1c97856d aurel32
    tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], (target_long)~0x80000000LL);
7795 1c97856d aurel32
}
7796 1c97856d aurel32
static always_inline void gen_efsnabs (DisasContext *ctx)
7797 1c97856d aurel32
{
7798 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {
7799 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);
7800 1c97856d aurel32
        return;
7801 1c97856d aurel32
    }
7802 1c97856d aurel32
    tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
7803 1c97856d aurel32
}
7804 1c97856d aurel32
static always_inline void gen_efsneg (DisasContext *ctx)
7805 1c97856d aurel32
{
7806 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {
7807 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);
7808 1c97856d aurel32
        return;
7809 1c97856d aurel32
    }
7810 1c97856d aurel32
    tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
7811 1c97856d aurel32
}
7812 1c97856d aurel32
7813 0487d6a8 j_mayer
/* Conversion */
7814 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_32(efscfui);
7815 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_32(efscfsi);
7816 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_32(efscfuf);
7817 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_32(efscfsf);
7818 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_32(efsctui);
7819 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_32(efsctsi);
7820 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_32(efsctuf);
7821 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_32(efsctsf);
7822 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_32(efsctuiz);
7823 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_32(efsctsiz);
7824 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_64(efscfd);
7825 1c97856d aurel32
7826 0487d6a8 j_mayer
/* Comparison */
7827 1c97856d aurel32
GEN_SPEFPUOP_COMP_32(efscmpgt);
7828 1c97856d aurel32
GEN_SPEFPUOP_COMP_32(efscmplt);
7829 1c97856d aurel32
GEN_SPEFPUOP_COMP_32(efscmpeq);
7830 1c97856d aurel32
GEN_SPEFPUOP_COMP_32(efststgt);
7831 1c97856d aurel32
GEN_SPEFPUOP_COMP_32(efststlt);
7832 1c97856d aurel32
GEN_SPEFPUOP_COMP_32(efststeq);
7833 0487d6a8 j_mayer
7834 0487d6a8 j_mayer
/* Opcodes definitions */
7835 40569b7e aurel32
GEN_SPE(efsadd,         efssub,        0x00, 0x0B, 0x00000000, PPC_SPE_SINGLE); //
7836 40569b7e aurel32
GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPE_SINGLE); //
7837 40569b7e aurel32
GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPE_SINGLE); //
7838 40569b7e aurel32
GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPE_SINGLE); //
7839 40569b7e aurel32
GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
7840 40569b7e aurel32
GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
7841 40569b7e aurel32
GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
7842 40569b7e aurel32
GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
7843 40569b7e aurel32
GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
7844 40569b7e aurel32
GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
7845 40569b7e aurel32
GEN_SPE(efsctuiz,       speundef,      0x0C, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
7846 40569b7e aurel32
GEN_SPE(efsctsiz,       speundef,      0x0D, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
7847 40569b7e aurel32
GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
7848 40569b7e aurel32
GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
7849 0487d6a8 j_mayer
7850 0487d6a8 j_mayer
/* Double precision floating-point operations */
7851 0487d6a8 j_mayer
/* Arithmetic */
7852 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_64_64(efdadd);
7853 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_64_64(efdsub);
7854 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_64_64(efdmul);
7855 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_64_64(efddiv);
7856 1c97856d aurel32
static always_inline void gen_efdabs (DisasContext *ctx)
7857 1c97856d aurel32
{
7858 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {
7859 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);
7860 1c97856d aurel32
        return;
7861 1c97856d aurel32
    }
7862 1c97856d aurel32
#if defined(TARGET_PPC64)
7863 1c97856d aurel32
    tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000000000000LL);
7864 1c97856d aurel32
#else
7865 1c97856d aurel32
    tcg_gen_andi_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
7866 1c97856d aurel32
#endif
7867 1c97856d aurel32
}
7868 1c97856d aurel32
static always_inline void gen_efdnabs (DisasContext *ctx)
7869 1c97856d aurel32
{
7870 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {
7871 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);
7872 1c97856d aurel32
        return;
7873 1c97856d aurel32
    }
7874 1c97856d aurel32
#if defined(TARGET_PPC64)
7875 1c97856d aurel32
    tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
7876 1c97856d aurel32
#else
7877 1c97856d aurel32
    tcg_gen_ori_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
7878 1c97856d aurel32
#endif
7879 1c97856d aurel32
}
7880 1c97856d aurel32
static always_inline void gen_efdneg (DisasContext *ctx)
7881 1c97856d aurel32
{
7882 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {
7883 e06fcd75 aurel32
        gen_exception(ctx, POWERPC_EXCP_APU);
7884 1c97856d aurel32
        return;
7885 1c97856d aurel32
    }
7886 1c97856d aurel32
#if defined(TARGET_PPC64)
7887 1c97856d aurel32
    tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
7888 1c97856d aurel32
#else
7889 1c97856d aurel32
    tcg_gen_xori_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
7890 1c97856d aurel32
#endif
7891 1c97856d aurel32
}
7892 1c97856d aurel32
7893 0487d6a8 j_mayer
/* Conversion */
7894 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_32(efdcfui);
7895 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_32(efdcfsi);
7896 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_32(efdcfuf);
7897 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_32(efdcfsf);
7898 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_64(efdctui);
7899 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_64(efdctsi);
7900 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_64(efdctuf);
7901 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_64(efdctsf);
7902 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_64(efdctuiz);
7903 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_64(efdctsiz);
7904 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_32(efdcfs);
7905 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(efdcfuid);
7906 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(efdcfsid);
7907 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(efdctuidz);
7908 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(efdctsidz);
7909 0487d6a8 j_mayer
7910 0487d6a8 j_mayer
/* Comparison */
7911 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(efdcmpgt);
7912 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(efdcmplt);
7913 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(efdcmpeq);
7914 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(efdtstgt);
7915 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(efdtstlt);
7916 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(efdtsteq);
7917 0487d6a8 j_mayer
7918 0487d6a8 j_mayer
/* Opcodes definitions */
7919 40569b7e aurel32
GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPE_DOUBLE); //
7920 40569b7e aurel32
GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
7921 40569b7e aurel32
GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPE_DOUBLE); //
7922 40569b7e aurel32
GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPE_DOUBLE); //
7923 40569b7e aurel32
GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPE_DOUBLE); //
7924 40569b7e aurel32
GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
7925 40569b7e aurel32
GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
7926 40569b7e aurel32
GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
7927 40569b7e aurel32
GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
7928 40569b7e aurel32
GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
7929 40569b7e aurel32
GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
7930 40569b7e aurel32
GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
7931 40569b7e aurel32
GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
7932 40569b7e aurel32
GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
7933 40569b7e aurel32
GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
7934 40569b7e aurel32
GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
7935 0487d6a8 j_mayer
7936 5c55ff99 Blue Swirl
static opcode_t opcodes[] = {
7937 5c55ff99 Blue Swirl
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE),
7938 5c55ff99 Blue Swirl
GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER),
7939 5c55ff99 Blue Swirl
GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
7940 5c55ff99 Blue Swirl
GEN_HANDLER(cmpl, 0x1F, 0x00, 0x01, 0x00400000, PPC_INTEGER),
7941 5c55ff99 Blue Swirl
GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
7942 5c55ff99 Blue Swirl
GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL),
7943 5c55ff99 Blue Swirl
GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7944 5c55ff99 Blue Swirl
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7945 5c55ff99 Blue Swirl
GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7946 5c55ff99 Blue Swirl
GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7947 5c55ff99 Blue Swirl
GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER),
7948 5c55ff99 Blue Swirl
GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER),
7949 5c55ff99 Blue Swirl
GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER),
7950 5c55ff99 Blue Swirl
GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER),
7951 5c55ff99 Blue Swirl
GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7952 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
7953 5c55ff99 Blue Swirl
GEN_HANDLER(mulld, 0x1F, 0x09, 0x07, 0x00000000, PPC_64B),
7954 5c55ff99 Blue Swirl
#endif
7955 5c55ff99 Blue Swirl
GEN_HANDLER(neg, 0x1F, 0x08, 0x03, 0x0000F800, PPC_INTEGER),
7956 5c55ff99 Blue Swirl
GEN_HANDLER(nego, 0x1F, 0x08, 0x13, 0x0000F800, PPC_INTEGER),
7957 5c55ff99 Blue Swirl
GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7958 5c55ff99 Blue Swirl
GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7959 5c55ff99 Blue Swirl
GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7960 5c55ff99 Blue Swirl
GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER),
7961 5c55ff99 Blue Swirl
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER),
7962 5c55ff99 Blue Swirl
GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER),
7963 5c55ff99 Blue Swirl
GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7964 5c55ff99 Blue Swirl
GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7965 5c55ff99 Blue Swirl
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7966 5c55ff99 Blue Swirl
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7967 5c55ff99 Blue Swirl
GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB),
7968 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
7969 5c55ff99 Blue Swirl
GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B),
7970 5c55ff99 Blue Swirl
#endif
7971 5c55ff99 Blue Swirl
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7972 5c55ff99 Blue Swirl
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7973 5c55ff99 Blue Swirl
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
7974 5c55ff99 Blue Swirl
GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER),
7975 5c55ff99 Blue Swirl
GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER),
7976 5c55ff99 Blue Swirl
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER),
7977 5c55ff99 Blue Swirl
GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER),
7978 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
7979 5c55ff99 Blue Swirl
GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B),
7980 5c55ff99 Blue Swirl
GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B),
7981 5c55ff99 Blue Swirl
GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B),
7982 5c55ff99 Blue Swirl
GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B),
7983 5c55ff99 Blue Swirl
GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B),
7984 5c55ff99 Blue Swirl
#endif
7985 5c55ff99 Blue Swirl
GEN_HANDLER(frsqrtes, 0x3B, 0x1A, 0xFF, 0x001F07C0, PPC_FLOAT_FRSQRTES),
7986 5c55ff99 Blue Swirl
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
7987 5c55ff99 Blue Swirl
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
7988 5c55ff99 Blue Swirl
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT),
7989 5c55ff99 Blue Swirl
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT),
7990 5c55ff99 Blue Swirl
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT),
7991 5c55ff99 Blue Swirl
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT),
7992 5c55ff99 Blue Swirl
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT),
7993 5c55ff99 Blue Swirl
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT),
7994 5c55ff99 Blue Swirl
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT),
7995 5c55ff99 Blue Swirl
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00010000, PPC_FLOAT),
7996 5c55ff99 Blue Swirl
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT),
7997 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
7998 5c55ff99 Blue Swirl
GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B),
7999 5c55ff99 Blue Swirl
GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX),
8000 5c55ff99 Blue Swirl
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B),
8001 5c55ff99 Blue Swirl
#endif
8002 5c55ff99 Blue Swirl
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8003 5c55ff99 Blue Swirl
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8004 5c55ff99 Blue Swirl
GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING),
8005 5c55ff99 Blue Swirl
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING),
8006 5c55ff99 Blue Swirl
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING),
8007 5c55ff99 Blue Swirl
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING),
8008 5c55ff99 Blue Swirl
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO),
8009 5c55ff99 Blue Swirl
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
8010 5c55ff99 Blue Swirl
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES),
8011 5c55ff99 Blue Swirl
GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
8012 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8013 5c55ff99 Blue Swirl
GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B),
8014 5c55ff99 Blue Swirl
GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B),
8015 5c55ff99 Blue Swirl
#endif
8016 5c55ff99 Blue Swirl
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC),
8017 5c55ff99 Blue Swirl
GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT),
8018 5c55ff99 Blue Swirl
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
8019 5c55ff99 Blue Swirl
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
8020 5c55ff99 Blue Swirl
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW),
8021 5c55ff99 Blue Swirl
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW),
8022 5c55ff99 Blue Swirl
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
8023 5c55ff99 Blue Swirl
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
8024 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8025 5c55ff99 Blue Swirl
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
8026 5c55ff99 Blue Swirl
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
8027 5c55ff99 Blue Swirl
#endif
8028 5c55ff99 Blue Swirl
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW),
8029 5c55ff99 Blue Swirl
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW),
8030 5c55ff99 Blue Swirl
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
8031 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8032 5c55ff99 Blue Swirl
GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B),
8033 5c55ff99 Blue Swirl
GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B),
8034 5c55ff99 Blue Swirl
#endif
8035 5c55ff99 Blue Swirl
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC),
8036 5c55ff99 Blue Swirl
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC),
8037 5c55ff99 Blue Swirl
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC),
8038 5c55ff99 Blue Swirl
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC),
8039 5c55ff99 Blue Swirl
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB),
8040 5c55ff99 Blue Swirl
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC),
8041 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8042 5c55ff99 Blue Swirl
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B),
8043 5c55ff99 Blue Swirl
#endif
8044 5c55ff99 Blue Swirl
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC),
8045 5c55ff99 Blue Swirl
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC),
8046 5c55ff99 Blue Swirl
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE),
8047 5c55ff99 Blue Swirl
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
8048 5c55ff99 Blue Swirl
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
8049 5c55ff99 Blue Swirl
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE),
8050 5c55ff99 Blue Swirl
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE),
8051 5c55ff99 Blue Swirl
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ),
8052 5c55ff99 Blue Swirl
GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT),
8053 5c55ff99 Blue Swirl
GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC),
8054 5c55ff99 Blue Swirl
GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x02000001, PPC_ALTIVEC),
8055 5c55ff99 Blue Swirl
GEN_HANDLER(dss, 0x1F, 0x16, 0x19, 0x019FF801, PPC_ALTIVEC),
8056 5c55ff99 Blue Swirl
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI),
8057 5c55ff99 Blue Swirl
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA),
8058 5c55ff99 Blue Swirl
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT),
8059 5c55ff99 Blue Swirl
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT),
8060 5c55ff99 Blue Swirl
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT),
8061 5c55ff99 Blue Swirl
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT),
8062 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8063 5c55ff99 Blue Swirl
GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B),
8064 5c55ff99 Blue Swirl
GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
8065 5c55ff99 Blue Swirl
             PPC_SEGMENT_64B),
8066 5c55ff99 Blue Swirl
GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B),
8067 5c55ff99 Blue Swirl
GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
8068 5c55ff99 Blue Swirl
             PPC_SEGMENT_64B),
8069 5c55ff99 Blue Swirl
GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x00000000, PPC_SEGMENT_64B),
8070 5c55ff99 Blue Swirl
#endif
8071 5c55ff99 Blue Swirl
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
8072 5c55ff99 Blue Swirl
GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x03FF0001, PPC_MEM_TLBIE),
8073 5c55ff99 Blue Swirl
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE),
8074 5c55ff99 Blue Swirl
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC),
8075 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8076 5c55ff99 Blue Swirl
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI),
8077 5c55ff99 Blue Swirl
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI),
8078 5c55ff99 Blue Swirl
#endif
8079 5c55ff99 Blue Swirl
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN),
8080 5c55ff99 Blue Swirl
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN),
8081 5c55ff99 Blue Swirl
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR),
8082 5c55ff99 Blue Swirl
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR),
8083 5c55ff99 Blue Swirl
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR),
8084 5c55ff99 Blue Swirl
GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR),
8085 5c55ff99 Blue Swirl
GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR),
8086 5c55ff99 Blue Swirl
GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR),
8087 5c55ff99 Blue Swirl
GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR),
8088 5c55ff99 Blue Swirl
GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR),
8089 5c55ff99 Blue Swirl
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR),
8090 5c55ff99 Blue Swirl
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
8091 5c55ff99 Blue Swirl
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR),
8092 5c55ff99 Blue Swirl
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR),
8093 5c55ff99 Blue Swirl
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR),
8094 5c55ff99 Blue Swirl
GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR),
8095 5c55ff99 Blue Swirl
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR),
8096 5c55ff99 Blue Swirl
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR),
8097 5c55ff99 Blue Swirl
GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR),
8098 5c55ff99 Blue Swirl
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
8099 5c55ff99 Blue Swirl
GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR),
8100 5c55ff99 Blue Swirl
GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR),
8101 5c55ff99 Blue Swirl
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR),
8102 5c55ff99 Blue Swirl
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR),
8103 5c55ff99 Blue Swirl
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR),
8104 5c55ff99 Blue Swirl
GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR),
8105 5c55ff99 Blue Swirl
GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR),
8106 5c55ff99 Blue Swirl
GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR),
8107 5c55ff99 Blue Swirl
GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR),
8108 5c55ff99 Blue Swirl
GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR),
8109 5c55ff99 Blue Swirl
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR),
8110 5c55ff99 Blue Swirl
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR),
8111 5c55ff99 Blue Swirl
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR),
8112 5c55ff99 Blue Swirl
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR),
8113 5c55ff99 Blue Swirl
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR),
8114 5c55ff99 Blue Swirl
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR),
8115 5c55ff99 Blue Swirl
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC),
8116 5c55ff99 Blue Swirl
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC),
8117 5c55ff99 Blue Swirl
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC),
8118 5c55ff99 Blue Swirl
GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB),
8119 5c55ff99 Blue Swirl
GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB),
8120 5c55ff99 Blue Swirl
GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB),
8121 5c55ff99 Blue Swirl
GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB),
8122 5c55ff99 Blue Swirl
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER),
8123 5c55ff99 Blue Swirl
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER),
8124 5c55ff99 Blue Swirl
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER),
8125 5c55ff99 Blue Swirl
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER),
8126 5c55ff99 Blue Swirl
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER),
8127 5c55ff99 Blue Swirl
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER),
8128 5c55ff99 Blue Swirl
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8129 5c55ff99 Blue Swirl
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8130 5c55ff99 Blue Swirl
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2),
8131 5c55ff99 Blue Swirl
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2),
8132 5c55ff99 Blue Swirl
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8133 5c55ff99 Blue Swirl
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8134 5c55ff99 Blue Swirl
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2),
8135 5c55ff99 Blue Swirl
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2),
8136 5c55ff99 Blue Swirl
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI),
8137 5c55ff99 Blue Swirl
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA),
8138 5c55ff99 Blue Swirl
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR),
8139 5c55ff99 Blue Swirl
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR),
8140 5c55ff99 Blue Swirl
GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX),
8141 5c55ff99 Blue Swirl
GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX),
8142 5c55ff99 Blue Swirl
GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX),
8143 5c55ff99 Blue Swirl
GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX),
8144 5c55ff99 Blue Swirl
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON),
8145 5c55ff99 Blue Swirl
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON),
8146 5c55ff99 Blue Swirl
GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT),
8147 5c55ff99 Blue Swirl
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON),
8148 5c55ff99 Blue Swirl
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON),
8149 5c55ff99 Blue Swirl
GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP),
8150 5c55ff99 Blue Swirl
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE),
8151 5c55ff99 Blue Swirl
GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI),
8152 5c55ff99 Blue Swirl
GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI),
8153 5c55ff99 Blue Swirl
GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB),
8154 5c55ff99 Blue Swirl
GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB),
8155 5c55ff99 Blue Swirl
GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB),
8156 5c55ff99 Blue Swirl
GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE),
8157 5c55ff99 Blue Swirl
GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE),
8158 5c55ff99 Blue Swirl
GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE),
8159 5c55ff99 Blue Swirl
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE),
8160 fbe73008 Baojun Wang
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE),
8161 5c55ff99 Blue Swirl
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC),
8162 5c55ff99 Blue Swirl
GEN_HANDLER(mbar, 0x1F, 0x16, 0x1a, 0x001FF801, PPC_BOOKE),
8163 5c55ff99 Blue Swirl
GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE),
8164 5c55ff99 Blue Swirl
GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE),
8165 5c55ff99 Blue Swirl
GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC),
8166 5c55ff99 Blue Swirl
GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC),
8167 5c55ff99 Blue Swirl
GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC),
8168 5c55ff99 Blue Swirl
GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC),
8169 5c55ff99 Blue Swirl
GEN_HANDLER(vsldoi, 0x04, 0x16, 0xFF, 0x00000400, PPC_ALTIVEC),
8170 5c55ff99 Blue Swirl
GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC),
8171 5c55ff99 Blue Swirl
GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE),
8172 5c55ff99 Blue Swirl
GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE),
8173 5c55ff99 Blue Swirl
GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE),
8174 5c55ff99 Blue Swirl
GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE),
8175 5c55ff99 Blue Swirl
8176 5c55ff99 Blue Swirl
#undef GEN_INT_ARITH_ADD
8177 5c55ff99 Blue Swirl
#undef GEN_INT_ARITH_ADD_CONST
8178 5c55ff99 Blue Swirl
#define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
8179 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x00000000, PPC_INTEGER),
8180 5c55ff99 Blue Swirl
#define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
8181 5c55ff99 Blue Swirl
                                add_ca, compute_ca, compute_ov)               \
8182 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x0000F800, PPC_INTEGER),
8183 5c55ff99 Blue Swirl
GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
8184 5c55ff99 Blue Swirl
GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
8185 5c55ff99 Blue Swirl
GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
8186 5c55ff99 Blue Swirl
GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
8187 5c55ff99 Blue Swirl
GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
8188 5c55ff99 Blue Swirl
GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
8189 5c55ff99 Blue Swirl
GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
8190 5c55ff99 Blue Swirl
GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
8191 5c55ff99 Blue Swirl
GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
8192 5c55ff99 Blue Swirl
GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
8193 5c55ff99 Blue Swirl
8194 5c55ff99 Blue Swirl
#undef GEN_INT_ARITH_DIVW
8195 5c55ff99 Blue Swirl
#define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
8196 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x1F, 0x0B, opc3, 0x00000000, PPC_INTEGER)
8197 5c55ff99 Blue Swirl
GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0),
8198 5c55ff99 Blue Swirl
GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1),
8199 5c55ff99 Blue Swirl
GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0),
8200 5c55ff99 Blue Swirl
GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1),
8201 5c55ff99 Blue Swirl
8202 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8203 5c55ff99 Blue Swirl
#undef GEN_INT_ARITH_DIVD
8204 5c55ff99 Blue Swirl
#define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
8205 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
8206 5c55ff99 Blue Swirl
GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0),
8207 5c55ff99 Blue Swirl
GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1),
8208 5c55ff99 Blue Swirl
GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0),
8209 5c55ff99 Blue Swirl
GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1),
8210 5c55ff99 Blue Swirl
8211 5c55ff99 Blue Swirl
#undef GEN_INT_ARITH_MUL_HELPER
8212 5c55ff99 Blue Swirl
#define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
8213 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
8214 5c55ff99 Blue Swirl
GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00),
8215 5c55ff99 Blue Swirl
GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02),
8216 5c55ff99 Blue Swirl
GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17),
8217 5c55ff99 Blue Swirl
#endif
8218 5c55ff99 Blue Swirl
8219 5c55ff99 Blue Swirl
#undef GEN_INT_ARITH_SUBF
8220 5c55ff99 Blue Swirl
#undef GEN_INT_ARITH_SUBF_CONST
8221 5c55ff99 Blue Swirl
#define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
8222 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x00000000, PPC_INTEGER),
8223 5c55ff99 Blue Swirl
#define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
8224 5c55ff99 Blue Swirl
                                add_ca, compute_ca, compute_ov)               \
8225 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x0000F800, PPC_INTEGER),
8226 5c55ff99 Blue Swirl
GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
8227 5c55ff99 Blue Swirl
GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
8228 5c55ff99 Blue Swirl
GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
8229 5c55ff99 Blue Swirl
GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
8230 5c55ff99 Blue Swirl
GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
8231 5c55ff99 Blue Swirl
GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
8232 5c55ff99 Blue Swirl
GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
8233 5c55ff99 Blue Swirl
GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
8234 5c55ff99 Blue Swirl
GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
8235 5c55ff99 Blue Swirl
GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
8236 5c55ff99 Blue Swirl
8237 5c55ff99 Blue Swirl
#undef GEN_LOGICAL1
8238 5c55ff99 Blue Swirl
#undef GEN_LOGICAL2
8239 5c55ff99 Blue Swirl
#define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
8240 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type)
8241 5c55ff99 Blue Swirl
#define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
8242 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)
8243 5c55ff99 Blue Swirl
GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER),
8244 5c55ff99 Blue Swirl
GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER),
8245 5c55ff99 Blue Swirl
GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER),
8246 5c55ff99 Blue Swirl
GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER),
8247 5c55ff99 Blue Swirl
GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER),
8248 5c55ff99 Blue Swirl
GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER),
8249 5c55ff99 Blue Swirl
GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER),
8250 5c55ff99 Blue Swirl
GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER),
8251 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8252 5c55ff99 Blue Swirl
GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B),
8253 5c55ff99 Blue Swirl
#endif
8254 5c55ff99 Blue Swirl
8255 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8256 5c55ff99 Blue Swirl
#undef GEN_PPC64_R2
8257 5c55ff99 Blue Swirl
#undef GEN_PPC64_R4
8258 5c55ff99 Blue Swirl
#define GEN_PPC64_R2(name, opc1, opc2)                                        \
8259 5c55ff99 Blue Swirl
GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
8260 5c55ff99 Blue Swirl
GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
8261 5c55ff99 Blue Swirl
             PPC_64B)
8262 5c55ff99 Blue Swirl
#define GEN_PPC64_R4(name, opc1, opc2)                                        \
8263 5c55ff99 Blue Swirl
GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
8264 5c55ff99 Blue Swirl
GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
8265 5c55ff99 Blue Swirl
             PPC_64B),                                                        \
8266 5c55ff99 Blue Swirl
GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
8267 5c55ff99 Blue Swirl
             PPC_64B),                                                        \
8268 5c55ff99 Blue Swirl
GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
8269 5c55ff99 Blue Swirl
             PPC_64B)
8270 5c55ff99 Blue Swirl
GEN_PPC64_R4(rldicl, 0x1E, 0x00),
8271 5c55ff99 Blue Swirl
GEN_PPC64_R4(rldicr, 0x1E, 0x02),
8272 5c55ff99 Blue Swirl
GEN_PPC64_R4(rldic, 0x1E, 0x04),
8273 5c55ff99 Blue Swirl
GEN_PPC64_R2(rldcl, 0x1E, 0x08),
8274 5c55ff99 Blue Swirl
GEN_PPC64_R2(rldcr, 0x1E, 0x09),
8275 5c55ff99 Blue Swirl
GEN_PPC64_R4(rldimi, 0x1E, 0x06),
8276 5c55ff99 Blue Swirl
#endif
8277 5c55ff99 Blue Swirl
8278 5c55ff99 Blue Swirl
#undef _GEN_FLOAT_ACB
8279 5c55ff99 Blue Swirl
#undef GEN_FLOAT_ACB
8280 5c55ff99 Blue Swirl
#undef _GEN_FLOAT_AB
8281 5c55ff99 Blue Swirl
#undef GEN_FLOAT_AB
8282 5c55ff99 Blue Swirl
#undef _GEN_FLOAT_AC
8283 5c55ff99 Blue Swirl
#undef GEN_FLOAT_AC
8284 5c55ff99 Blue Swirl
#undef GEN_FLOAT_B
8285 5c55ff99 Blue Swirl
#undef GEN_FLOAT_BS
8286 5c55ff99 Blue Swirl
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
8287 5c55ff99 Blue Swirl
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)
8288 5c55ff99 Blue Swirl
#define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
8289 5c55ff99 Blue Swirl
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type),                     \
8290 5c55ff99 Blue Swirl
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type)
8291 5c55ff99 Blue Swirl
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
8292 5c55ff99 Blue Swirl
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
8293 5c55ff99 Blue Swirl
#define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
8294 5c55ff99 Blue Swirl
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type),               \
8295 5c55ff99 Blue Swirl
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
8296 5c55ff99 Blue Swirl
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
8297 5c55ff99 Blue Swirl
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
8298 5c55ff99 Blue Swirl
#define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
8299 5c55ff99 Blue Swirl
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type),               \
8300 5c55ff99 Blue Swirl
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
8301 5c55ff99 Blue Swirl
#define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
8302 5c55ff99 Blue Swirl
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)
8303 5c55ff99 Blue Swirl
#define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
8304 5c55ff99 Blue Swirl
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)
8305 5c55ff99 Blue Swirl
8306 5c55ff99 Blue Swirl
GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT),
8307 5c55ff99 Blue Swirl
GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT),
8308 5c55ff99 Blue Swirl
GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT),
8309 5c55ff99 Blue Swirl
GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT),
8310 5c55ff99 Blue Swirl
GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES),
8311 5c55ff99 Blue Swirl
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE),
8312 5c55ff99 Blue Swirl
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL),
8313 5c55ff99 Blue Swirl
GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT),
8314 5c55ff99 Blue Swirl
GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT),
8315 5c55ff99 Blue Swirl
GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT),
8316 5c55ff99 Blue Swirl
GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT),
8317 5c55ff99 Blue Swirl
GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT),
8318 5c55ff99 Blue Swirl
GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT),
8319 5c55ff99 Blue Swirl
GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT),
8320 5c55ff99 Blue Swirl
GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT),
8321 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8322 5c55ff99 Blue Swirl
GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B),
8323 5c55ff99 Blue Swirl
GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B),
8324 5c55ff99 Blue Swirl
GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B),
8325 5c55ff99 Blue Swirl
#endif
8326 5c55ff99 Blue Swirl
GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT),
8327 5c55ff99 Blue Swirl
GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT),
8328 5c55ff99 Blue Swirl
GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT),
8329 5c55ff99 Blue Swirl
GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT),
8330 5c55ff99 Blue Swirl
GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT),
8331 5c55ff99 Blue Swirl
GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT),
8332 5c55ff99 Blue Swirl
GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT),
8333 5c55ff99 Blue Swirl
8334 5c55ff99 Blue Swirl
#undef GEN_LD
8335 5c55ff99 Blue Swirl
#undef GEN_LDU
8336 5c55ff99 Blue Swirl
#undef GEN_LDUX
8337 5c55ff99 Blue Swirl
#undef GEN_LDX
8338 5c55ff99 Blue Swirl
#undef GEN_LDS
8339 5c55ff99 Blue Swirl
#define GEN_LD(name, ldop, opc, type)                                         \
8340 5c55ff99 Blue Swirl
GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
8341 5c55ff99 Blue Swirl
#define GEN_LDU(name, ldop, opc, type)                                        \
8342 5c55ff99 Blue Swirl
GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
8343 5c55ff99 Blue Swirl
#define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
8344 5c55ff99 Blue Swirl
GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
8345 5c55ff99 Blue Swirl
#define GEN_LDX(name, ldop, opc2, opc3, type)                                 \
8346 5c55ff99 Blue Swirl
GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
8347 5c55ff99 Blue Swirl
#define GEN_LDS(name, ldop, op, type)                                         \
8348 5c55ff99 Blue Swirl
GEN_LD(name, ldop, op | 0x20, type)                                           \
8349 5c55ff99 Blue Swirl
GEN_LDU(name, ldop, op | 0x21, type)                                          \
8350 5c55ff99 Blue Swirl
GEN_LDUX(name, ldop, 0x17, op | 0x01, type)                                   \
8351 5c55ff99 Blue Swirl
GEN_LDX(name, ldop, 0x17, op | 0x00, type)
8352 5c55ff99 Blue Swirl
8353 5c55ff99 Blue Swirl
GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER)
8354 5c55ff99 Blue Swirl
GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER)
8355 5c55ff99 Blue Swirl
GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER)
8356 5c55ff99 Blue Swirl
GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER)
8357 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8358 5c55ff99 Blue Swirl
GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B)
8359 5c55ff99 Blue Swirl
GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B)
8360 5c55ff99 Blue Swirl
GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B)
8361 5c55ff99 Blue Swirl
GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B)
8362 5c55ff99 Blue Swirl
#endif
8363 5c55ff99 Blue Swirl
GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
8364 5c55ff99 Blue Swirl
GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
8365 5c55ff99 Blue Swirl
8366 5c55ff99 Blue Swirl
#undef GEN_ST
8367 5c55ff99 Blue Swirl
#undef GEN_STU
8368 5c55ff99 Blue Swirl
#undef GEN_STUX
8369 5c55ff99 Blue Swirl
#undef GEN_STX
8370 5c55ff99 Blue Swirl
#undef GEN_STS
8371 5c55ff99 Blue Swirl
#define GEN_ST(name, stop, opc, type)                                         \
8372 5c55ff99 Blue Swirl
GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
8373 5c55ff99 Blue Swirl
#define GEN_STU(name, stop, opc, type)                                        \
8374 5c55ff99 Blue Swirl
GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type),
8375 5c55ff99 Blue Swirl
#define GEN_STUX(name, stop, opc2, opc3, type)                                \
8376 5c55ff99 Blue Swirl
GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
8377 5c55ff99 Blue Swirl
#define GEN_STX(name, stop, opc2, opc3, type)                                 \
8378 5c55ff99 Blue Swirl
GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
8379 5c55ff99 Blue Swirl
#define GEN_STS(name, stop, op, type)                                         \
8380 5c55ff99 Blue Swirl
GEN_ST(name, stop, op | 0x20, type)                                           \
8381 5c55ff99 Blue Swirl
GEN_STU(name, stop, op | 0x21, type)                                          \
8382 5c55ff99 Blue Swirl
GEN_STUX(name, stop, 0x17, op | 0x01, type)                                   \
8383 5c55ff99 Blue Swirl
GEN_STX(name, stop, 0x17, op | 0x00, type)
8384 5c55ff99 Blue Swirl
8385 5c55ff99 Blue Swirl
GEN_STS(stb, st8, 0x06, PPC_INTEGER)
8386 5c55ff99 Blue Swirl
GEN_STS(sth, st16, 0x0C, PPC_INTEGER)
8387 5c55ff99 Blue Swirl
GEN_STS(stw, st32, 0x04, PPC_INTEGER)
8388 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8389 5c55ff99 Blue Swirl
GEN_STUX(std, st64, 0x15, 0x05, PPC_64B)
8390 5c55ff99 Blue Swirl
GEN_STX(std, st64, 0x15, 0x04, PPC_64B)
8391 5c55ff99 Blue Swirl
#endif
8392 5c55ff99 Blue Swirl
GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
8393 5c55ff99 Blue Swirl
GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
8394 5c55ff99 Blue Swirl
8395 5c55ff99 Blue Swirl
#undef GEN_LDF
8396 5c55ff99 Blue Swirl
#undef GEN_LDUF
8397 5c55ff99 Blue Swirl
#undef GEN_LDUXF
8398 5c55ff99 Blue Swirl
#undef GEN_LDXF
8399 5c55ff99 Blue Swirl
#undef GEN_LDFS
8400 5c55ff99 Blue Swirl
#define GEN_LDF(name, ldop, opc, type)                                        \
8401 5c55ff99 Blue Swirl
GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
8402 5c55ff99 Blue Swirl
#define GEN_LDUF(name, ldop, opc, type)                                       \
8403 5c55ff99 Blue Swirl
GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
8404 5c55ff99 Blue Swirl
#define GEN_LDUXF(name, ldop, opc, type)                                      \
8405 5c55ff99 Blue Swirl
GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
8406 5c55ff99 Blue Swirl
#define GEN_LDXF(name, ldop, opc2, opc3, type)                                \
8407 5c55ff99 Blue Swirl
GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
8408 5c55ff99 Blue Swirl
#define GEN_LDFS(name, ldop, op, type)                                        \
8409 5c55ff99 Blue Swirl
GEN_LDF(name, ldop, op | 0x20, type)                                          \
8410 5c55ff99 Blue Swirl
GEN_LDUF(name, ldop, op | 0x21, type)                                         \
8411 5c55ff99 Blue Swirl
GEN_LDUXF(name, ldop, op | 0x01, type)                                        \
8412 5c55ff99 Blue Swirl
GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
8413 5c55ff99 Blue Swirl
8414 5c55ff99 Blue Swirl
GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT)
8415 5c55ff99 Blue Swirl
GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT)
8416 5c55ff99 Blue Swirl
8417 5c55ff99 Blue Swirl
#undef GEN_STF
8418 5c55ff99 Blue Swirl
#undef GEN_STUF
8419 5c55ff99 Blue Swirl
#undef GEN_STUXF
8420 5c55ff99 Blue Swirl
#undef GEN_STXF
8421 5c55ff99 Blue Swirl
#undef GEN_STFS
8422 5c55ff99 Blue Swirl
#define GEN_STF(name, stop, opc, type)                                        \
8423 5c55ff99 Blue Swirl
GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
8424 5c55ff99 Blue Swirl
#define GEN_STUF(name, stop, opc, type)                                       \
8425 5c55ff99 Blue Swirl
GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
8426 5c55ff99 Blue Swirl
#define GEN_STUXF(name, stop, opc, type)                                      \
8427 5c55ff99 Blue Swirl
GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
8428 5c55ff99 Blue Swirl
#define GEN_STXF(name, stop, opc2, opc3, type)                                \
8429 5c55ff99 Blue Swirl
GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
8430 5c55ff99 Blue Swirl
#define GEN_STFS(name, stop, op, type)                                        \
8431 5c55ff99 Blue Swirl
GEN_STF(name, stop, op | 0x20, type)                                          \
8432 5c55ff99 Blue Swirl
GEN_STUF(name, stop, op | 0x21, type)                                         \
8433 5c55ff99 Blue Swirl
GEN_STUXF(name, stop, op | 0x01, type)                                        \
8434 5c55ff99 Blue Swirl
GEN_STXF(name, stop, 0x17, op | 0x00, type)
8435 5c55ff99 Blue Swirl
8436 5c55ff99 Blue Swirl
GEN_STFS(stfd, st64, 0x16, PPC_FLOAT)
8437 5c55ff99 Blue Swirl
GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT)
8438 5c55ff99 Blue Swirl
GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX)
8439 5c55ff99 Blue Swirl
8440 5c55ff99 Blue Swirl
#undef GEN_CRLOGIC
8441 5c55ff99 Blue Swirl
#define GEN_CRLOGIC(name, tcg_op, opc)                                        \
8442 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)
8443 5c55ff99 Blue Swirl
GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08),
8444 5c55ff99 Blue Swirl
GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04),
8445 5c55ff99 Blue Swirl
GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09),
8446 5c55ff99 Blue Swirl
GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07),
8447 5c55ff99 Blue Swirl
GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01),
8448 5c55ff99 Blue Swirl
GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E),
8449 5c55ff99 Blue Swirl
GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D),
8450 5c55ff99 Blue Swirl
GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06),
8451 5c55ff99 Blue Swirl
8452 5c55ff99 Blue Swirl
#undef GEN_MAC_HANDLER
8453 5c55ff99 Blue Swirl
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
8454 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)
8455 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(macchw, 0x0C, 0x05),
8456 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(macchwo, 0x0C, 0x15),
8457 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(macchws, 0x0C, 0x07),
8458 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(macchwso, 0x0C, 0x17),
8459 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06),
8460 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16),
8461 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(macchwu, 0x0C, 0x04),
8462 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14),
8463 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(machhw, 0x0C, 0x01),
8464 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(machhwo, 0x0C, 0x11),
8465 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(machhws, 0x0C, 0x03),
8466 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(machhwso, 0x0C, 0x13),
8467 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02),
8468 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12),
8469 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(machhwu, 0x0C, 0x00),
8470 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10),
8471 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D),
8472 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D),
8473 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F),
8474 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F),
8475 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C),
8476 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C),
8477 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E),
8478 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E),
8479 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05),
8480 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15),
8481 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07),
8482 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17),
8483 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01),
8484 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11),
8485 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03),
8486 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13),
8487 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D),
8488 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D),
8489 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F),
8490 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F),
8491 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(mulchw, 0x08, 0x05),
8492 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04),
8493 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01),
8494 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00),
8495 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D),
8496 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C),
8497 5c55ff99 Blue Swirl
8498 5c55ff99 Blue Swirl
#undef GEN_VR_LDX
8499 5c55ff99 Blue Swirl
#undef GEN_VR_STX
8500 5c55ff99 Blue Swirl
#undef GEN_VR_LVE
8501 5c55ff99 Blue Swirl
#undef GEN_VR_STVE
8502 5c55ff99 Blue Swirl
#define GEN_VR_LDX(name, opc2, opc3)                                          \
8503 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
8504 5c55ff99 Blue Swirl
#define GEN_VR_STX(name, opc2, opc3)                                          \
8505 5c55ff99 Blue Swirl
GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
8506 5c55ff99 Blue Swirl
#define GEN_VR_LVE(name, opc2, opc3)                                    \
8507 5c55ff99 Blue Swirl
    GEN_HANDLER(lve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
8508 5c55ff99 Blue Swirl
#define GEN_VR_STVE(name, opc2, opc3)                                   \
8509 5c55ff99 Blue Swirl
    GEN_HANDLER(stve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
8510 5c55ff99 Blue Swirl
GEN_VR_LDX(lvx, 0x07, 0x03),
8511 5c55ff99 Blue Swirl
GEN_VR_LDX(lvxl, 0x07, 0x0B),
8512 5c55ff99 Blue Swirl
GEN_VR_LVE(bx, 0x07, 0x00),
8513 5c55ff99 Blue Swirl
GEN_VR_LVE(hx, 0x07, 0x01),
8514 5c55ff99 Blue Swirl
GEN_VR_LVE(wx, 0x07, 0x02),
8515 5c55ff99 Blue Swirl
GEN_VR_STX(svx, 0x07, 0x07),
8516 5c55ff99 Blue Swirl
GEN_VR_STX(svxl, 0x07, 0x0F),
8517 5c55ff99 Blue Swirl
GEN_VR_STVE(bx, 0x07, 0x04),
8518 5c55ff99 Blue Swirl
GEN_VR_STVE(hx, 0x07, 0x05),
8519 5c55ff99 Blue Swirl
GEN_VR_STVE(wx, 0x07, 0x06),
8520 5c55ff99 Blue Swirl
8521 5c55ff99 Blue Swirl
#undef GEN_VX_LOGICAL
8522 5c55ff99 Blue Swirl
#define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)                        \
8523 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
8524 5c55ff99 Blue Swirl
GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16),
8525 5c55ff99 Blue Swirl
GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17),
8526 5c55ff99 Blue Swirl
GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18),
8527 5c55ff99 Blue Swirl
GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19),
8528 5c55ff99 Blue Swirl
GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20),
8529 5c55ff99 Blue Swirl
8530 5c55ff99 Blue Swirl
#undef GEN_VXFORM
8531 5c55ff99 Blue Swirl
#define GEN_VXFORM(name, opc2, opc3)                                    \
8532 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
8533 5c55ff99 Blue Swirl
GEN_VXFORM(vaddubm, 0, 0),
8534 5c55ff99 Blue Swirl
GEN_VXFORM(vadduhm, 0, 1),
8535 5c55ff99 Blue Swirl
GEN_VXFORM(vadduwm, 0, 2),
8536 5c55ff99 Blue Swirl
GEN_VXFORM(vsububm, 0, 16),
8537 5c55ff99 Blue Swirl
GEN_VXFORM(vsubuhm, 0, 17),
8538 5c55ff99 Blue Swirl
GEN_VXFORM(vsubuwm, 0, 18),
8539 5c55ff99 Blue Swirl
GEN_VXFORM(vmaxub, 1, 0),
8540 5c55ff99 Blue Swirl
GEN_VXFORM(vmaxuh, 1, 1),
8541 5c55ff99 Blue Swirl
GEN_VXFORM(vmaxuw, 1, 2),
8542 5c55ff99 Blue Swirl
GEN_VXFORM(vmaxsb, 1, 4),
8543 5c55ff99 Blue Swirl
GEN_VXFORM(vmaxsh, 1, 5),
8544 5c55ff99 Blue Swirl
GEN_VXFORM(vmaxsw, 1, 6),
8545 5c55ff99 Blue Swirl
GEN_VXFORM(vminub, 1, 8),
8546 5c55ff99 Blue Swirl
GEN_VXFORM(vminuh, 1, 9),
8547 5c55ff99 Blue Swirl
GEN_VXFORM(vminuw, 1, 10),
8548 5c55ff99 Blue Swirl
GEN_VXFORM(vminsb, 1, 12),
8549 5c55ff99 Blue Swirl
GEN_VXFORM(vminsh, 1, 13),
8550 5c55ff99 Blue Swirl
GEN_VXFORM(vminsw, 1, 14),
8551 5c55ff99 Blue Swirl
GEN_VXFORM(vavgub, 1, 16),
8552 5c55ff99 Blue Swirl
GEN_VXFORM(vavguh, 1, 17),
8553 5c55ff99 Blue Swirl
GEN_VXFORM(vavguw, 1, 18),
8554 5c55ff99 Blue Swirl
GEN_VXFORM(vavgsb, 1, 20),
8555 5c55ff99 Blue Swirl
GEN_VXFORM(vavgsh, 1, 21),
8556 5c55ff99 Blue Swirl
GEN_VXFORM(vavgsw, 1, 22),
8557 5c55ff99 Blue Swirl
GEN_VXFORM(vmrghb, 6, 0),
8558 5c55ff99 Blue Swirl
GEN_VXFORM(vmrghh, 6, 1),
8559 5c55ff99 Blue Swirl
GEN_VXFORM(vmrghw, 6, 2),
8560 5c55ff99 Blue Swirl
GEN_VXFORM(vmrglb, 6, 4),
8561 5c55ff99 Blue Swirl
GEN_VXFORM(vmrglh, 6, 5),
8562 5c55ff99 Blue Swirl
GEN_VXFORM(vmrglw, 6, 6),
8563 5c55ff99 Blue Swirl
GEN_VXFORM(vmuloub, 4, 0),
8564 5c55ff99 Blue Swirl
GEN_VXFORM(vmulouh, 4, 1),
8565 5c55ff99 Blue Swirl
GEN_VXFORM(vmulosb, 4, 4),
8566 5c55ff99 Blue Swirl
GEN_VXFORM(vmulosh, 4, 5),
8567 5c55ff99 Blue Swirl
GEN_VXFORM(vmuleub, 4, 8),
8568 5c55ff99 Blue Swirl
GEN_VXFORM(vmuleuh, 4, 9),
8569 5c55ff99 Blue Swirl
GEN_VXFORM(vmulesb, 4, 12),
8570 5c55ff99 Blue Swirl
GEN_VXFORM(vmulesh, 4, 13),
8571 5c55ff99 Blue Swirl
GEN_VXFORM(vslb, 2, 4),
8572 5c55ff99 Blue Swirl
GEN_VXFORM(vslh, 2, 5),
8573 5c55ff99 Blue Swirl
GEN_VXFORM(vslw, 2, 6),
8574 5c55ff99 Blue Swirl
GEN_VXFORM(vsrb, 2, 8),
8575 5c55ff99 Blue Swirl
GEN_VXFORM(vsrh, 2, 9),
8576 5c55ff99 Blue Swirl
GEN_VXFORM(vsrw, 2, 10),
8577 5c55ff99 Blue Swirl
GEN_VXFORM(vsrab, 2, 12),
8578 5c55ff99 Blue Swirl
GEN_VXFORM(vsrah, 2, 13),
8579 5c55ff99 Blue Swirl
GEN_VXFORM(vsraw, 2, 14),
8580 5c55ff99 Blue Swirl
GEN_VXFORM(vslo, 6, 16),
8581 5c55ff99 Blue Swirl
GEN_VXFORM(vsro, 6, 17),
8582 5c55ff99 Blue Swirl
GEN_VXFORM(vaddcuw, 0, 6),
8583 5c55ff99 Blue Swirl
GEN_VXFORM(vsubcuw, 0, 22),
8584 5c55ff99 Blue Swirl
GEN_VXFORM(vaddubs, 0, 8),
8585 5c55ff99 Blue Swirl
GEN_VXFORM(vadduhs, 0, 9),
8586 5c55ff99 Blue Swirl
GEN_VXFORM(vadduws, 0, 10),
8587 5c55ff99 Blue Swirl
GEN_VXFORM(vaddsbs, 0, 12),
8588 5c55ff99 Blue Swirl
GEN_VXFORM(vaddshs, 0, 13),
8589 5c55ff99 Blue Swirl
GEN_VXFORM(vaddsws, 0, 14),
8590 5c55ff99 Blue Swirl
GEN_VXFORM(vsububs, 0, 24),
8591 5c55ff99 Blue Swirl
GEN_VXFORM(vsubuhs, 0, 25),
8592 5c55ff99 Blue Swirl
GEN_VXFORM(vsubuws, 0, 26),
8593 5c55ff99 Blue Swirl
GEN_VXFORM(vsubsbs, 0, 28),
8594 5c55ff99 Blue Swirl
GEN_VXFORM(vsubshs, 0, 29),
8595 5c55ff99 Blue Swirl
GEN_VXFORM(vsubsws, 0, 30),
8596 5c55ff99 Blue Swirl
GEN_VXFORM(vrlb, 2, 0),
8597 5c55ff99 Blue Swirl
GEN_VXFORM(vrlh, 2, 1),
8598 5c55ff99 Blue Swirl
GEN_VXFORM(vrlw, 2, 2),
8599 5c55ff99 Blue Swirl
GEN_VXFORM(vsl, 2, 7),
8600 5c55ff99 Blue Swirl
GEN_VXFORM(vsr, 2, 11),
8601 5c55ff99 Blue Swirl
GEN_VXFORM(vpkuhum, 7, 0),
8602 5c55ff99 Blue Swirl
GEN_VXFORM(vpkuwum, 7, 1),
8603 5c55ff99 Blue Swirl
GEN_VXFORM(vpkuhus, 7, 2),
8604 5c55ff99 Blue Swirl
GEN_VXFORM(vpkuwus, 7, 3),
8605 5c55ff99 Blue Swirl
GEN_VXFORM(vpkshus, 7, 4),
8606 5c55ff99 Blue Swirl
GEN_VXFORM(vpkswus, 7, 5),
8607 5c55ff99 Blue Swirl
GEN_VXFORM(vpkshss, 7, 6),
8608 5c55ff99 Blue Swirl
GEN_VXFORM(vpkswss, 7, 7),
8609 5c55ff99 Blue Swirl
GEN_VXFORM(vpkpx, 7, 12),
8610 5c55ff99 Blue Swirl
GEN_VXFORM(vsum4ubs, 4, 24),
8611 5c55ff99 Blue Swirl
GEN_VXFORM(vsum4sbs, 4, 28),
8612 5c55ff99 Blue Swirl
GEN_VXFORM(vsum4shs, 4, 25),
8613 5c55ff99 Blue Swirl
GEN_VXFORM(vsum2sws, 4, 26),
8614 5c55ff99 Blue Swirl
GEN_VXFORM(vsumsws, 4, 30),
8615 5c55ff99 Blue Swirl
GEN_VXFORM(vaddfp, 5, 0),
8616 5c55ff99 Blue Swirl
GEN_VXFORM(vsubfp, 5, 1),
8617 5c55ff99 Blue Swirl
GEN_VXFORM(vmaxfp, 5, 16),
8618 5c55ff99 Blue Swirl
GEN_VXFORM(vminfp, 5, 17),
8619 5c55ff99 Blue Swirl
8620 5c55ff99 Blue Swirl
#undef GEN_VXRFORM1
8621 5c55ff99 Blue Swirl
#undef GEN_VXRFORM
8622 5c55ff99 Blue Swirl
#define GEN_VXRFORM1(opname, name, str, opc2, opc3)                     \
8623 5c55ff99 Blue Swirl
    GEN_HANDLER2(name, str, 0x4, opc2, opc3, 0x00000000, PPC_ALTIVEC),
8624 5c55ff99 Blue Swirl
#define GEN_VXRFORM(name, opc2, opc3)                                \
8625 5c55ff99 Blue Swirl
    GEN_VXRFORM1(name, name, #name, opc2, opc3)                      \
8626 5c55ff99 Blue Swirl
    GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
8627 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpequb, 3, 0)
8628 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpequh, 3, 1)
8629 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpequw, 3, 2)
8630 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpgtsb, 3, 12)
8631 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpgtsh, 3, 13)
8632 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpgtsw, 3, 14)
8633 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpgtub, 3, 8)
8634 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpgtuh, 3, 9)
8635 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpgtuw, 3, 10)
8636 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpeqfp, 3, 3)
8637 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpgefp, 3, 7)
8638 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpgtfp, 3, 11)
8639 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpbfp, 3, 15)
8640 5c55ff99 Blue Swirl
8641 5c55ff99 Blue Swirl
#undef GEN_VXFORM_SIMM
8642 5c55ff99 Blue Swirl
#define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
8643 5c55ff99 Blue Swirl
    GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
8644 5c55ff99 Blue Swirl
GEN_VXFORM_SIMM(vspltisb, 6, 12),
8645 5c55ff99 Blue Swirl
GEN_VXFORM_SIMM(vspltish, 6, 13),
8646 5c55ff99 Blue Swirl
GEN_VXFORM_SIMM(vspltisw, 6, 14),
8647 5c55ff99 Blue Swirl
8648 5c55ff99 Blue Swirl
#undef GEN_VXFORM_NOA
8649 5c55ff99 Blue Swirl
#define GEN_VXFORM_NOA(name, opc2, opc3)                                \
8650 5c55ff99 Blue Swirl
    GEN_HANDLER(name, 0x04, opc2, opc3, 0x001f0000, PPC_ALTIVEC)
8651 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vupkhsb, 7, 8),
8652 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vupkhsh, 7, 9),
8653 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vupklsb, 7, 10),
8654 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vupklsh, 7, 11),
8655 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vupkhpx, 7, 13),
8656 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vupklpx, 7, 15),
8657 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vrefp, 5, 4),
8658 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vrsqrtefp, 5, 5),
8659 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vlogefp, 5, 7),
8660 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vrfim, 5, 8),
8661 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vrfin, 5, 9),
8662 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vrfip, 5, 10),
8663 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vrfiz, 5, 11),
8664 5c55ff99 Blue Swirl
8665 5c55ff99 Blue Swirl
#undef GEN_VXFORM_UIMM
8666 5c55ff99 Blue Swirl
#define GEN_VXFORM_UIMM(name, opc2, opc3)                               \
8667 5c55ff99 Blue Swirl
    GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
8668 5c55ff99 Blue Swirl
GEN_VXFORM_UIMM(vspltb, 6, 8),
8669 5c55ff99 Blue Swirl
GEN_VXFORM_UIMM(vsplth, 6, 9),
8670 5c55ff99 Blue Swirl
GEN_VXFORM_UIMM(vspltw, 6, 10),
8671 5c55ff99 Blue Swirl
GEN_VXFORM_UIMM(vcfux, 5, 12),
8672 5c55ff99 Blue Swirl
GEN_VXFORM_UIMM(vcfsx, 5, 13),
8673 5c55ff99 Blue Swirl
GEN_VXFORM_UIMM(vctuxs, 5, 14),
8674 5c55ff99 Blue Swirl
GEN_VXFORM_UIMM(vctsxs, 5, 15),
8675 5c55ff99 Blue Swirl
8676 5c55ff99 Blue Swirl
#undef GEN_VAFORM_PAIRED
8677 5c55ff99 Blue Swirl
#define GEN_VAFORM_PAIRED(name0, name1, opc2)                           \
8678 5c55ff99 Blue Swirl
    GEN_HANDLER(name0##_##name1, 0x04, opc2, 0xFF, 0x00000000, PPC_ALTIVEC)
8679 5c55ff99 Blue Swirl
GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16),
8680 5c55ff99 Blue Swirl
GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18),
8681 5c55ff99 Blue Swirl
GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19),
8682 5c55ff99 Blue Swirl
GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20),
8683 5c55ff99 Blue Swirl
GEN_VAFORM_PAIRED(vsel, vperm, 21),
8684 5c55ff99 Blue Swirl
GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23),
8685 5c55ff99 Blue Swirl
8686 5c55ff99 Blue Swirl
#undef GEN_SPE
8687 5c55ff99 Blue Swirl
#define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
8688 5c55ff99 Blue Swirl
GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)
8689 5c55ff99 Blue Swirl
GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE),
8690 5c55ff99 Blue Swirl
GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE),
8691 5c55ff99 Blue Swirl
GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE),
8692 5c55ff99 Blue Swirl
GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE),
8693 5c55ff99 Blue Swirl
GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE),
8694 5c55ff99 Blue Swirl
GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE),
8695 5c55ff99 Blue Swirl
GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE),
8696 5c55ff99 Blue Swirl
GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE),
8697 5c55ff99 Blue Swirl
GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE),
8698 5c55ff99 Blue Swirl
GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE),
8699 5c55ff99 Blue Swirl
GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE),
8700 5c55ff99 Blue Swirl
GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE),
8701 5c55ff99 Blue Swirl
GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE),
8702 5c55ff99 Blue Swirl
GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE),
8703 5c55ff99 Blue Swirl
GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE),
8704 5c55ff99 Blue Swirl
GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE),
8705 5c55ff99 Blue Swirl
GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE),
8706 5c55ff99 Blue Swirl
GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE),
8707 5c55ff99 Blue Swirl
GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE),
8708 5c55ff99 Blue Swirl
GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE),
8709 5c55ff99 Blue Swirl
GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE),
8710 5c55ff99 Blue Swirl
GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE),
8711 5c55ff99 Blue Swirl
GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE),
8712 5c55ff99 Blue Swirl
GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE),
8713 5c55ff99 Blue Swirl
GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE),
8714 5c55ff99 Blue Swirl
8715 5c55ff99 Blue Swirl
GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPE_SINGLE),
8716 5c55ff99 Blue Swirl
GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPE_SINGLE),
8717 5c55ff99 Blue Swirl
GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPE_SINGLE),
8718 5c55ff99 Blue Swirl
GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPE_SINGLE),
8719 5c55ff99 Blue Swirl
GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPE_SINGLE),
8720 5c55ff99 Blue Swirl
GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPE_SINGLE),
8721 5c55ff99 Blue Swirl
GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPE_SINGLE),
8722 5c55ff99 Blue Swirl
GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPE_SINGLE),
8723 5c55ff99 Blue Swirl
GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPE_SINGLE),
8724 5c55ff99 Blue Swirl
GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPE_SINGLE),
8725 5c55ff99 Blue Swirl
GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPE_SINGLE),
8726 5c55ff99 Blue Swirl
GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPE_SINGLE),
8727 5c55ff99 Blue Swirl
GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPE_SINGLE),
8728 5c55ff99 Blue Swirl
GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPE_SINGLE),
8729 5c55ff99 Blue Swirl
8730 5c55ff99 Blue Swirl
GEN_SPE(efsadd,         efssub,        0x00, 0x0B, 0x00000000, PPC_SPE_SINGLE),
8731 5c55ff99 Blue Swirl
GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPE_SINGLE),
8732 5c55ff99 Blue Swirl
GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPE_SINGLE),
8733 5c55ff99 Blue Swirl
GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPE_SINGLE),
8734 5c55ff99 Blue Swirl
GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPE_SINGLE),
8735 5c55ff99 Blue Swirl
GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPE_SINGLE),
8736 5c55ff99 Blue Swirl
GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPE_SINGLE),
8737 5c55ff99 Blue Swirl
GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPE_SINGLE),
8738 5c55ff99 Blue Swirl
GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPE_SINGLE),
8739 5c55ff99 Blue Swirl
GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPE_SINGLE),
8740 5c55ff99 Blue Swirl
GEN_SPE(efsctuiz,       speundef,      0x0C, 0x0B, 0x00180000, PPC_SPE_SINGLE),
8741 5c55ff99 Blue Swirl
GEN_SPE(efsctsiz,       speundef,      0x0D, 0x0B, 0x00180000, PPC_SPE_SINGLE),
8742 5c55ff99 Blue Swirl
GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPE_SINGLE),
8743 5c55ff99 Blue Swirl
GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPE_SINGLE),
8744 5c55ff99 Blue Swirl
8745 5c55ff99 Blue Swirl
GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPE_DOUBLE),
8746 5c55ff99 Blue Swirl
GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8747 5c55ff99 Blue Swirl
GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPE_DOUBLE),
8748 5c55ff99 Blue Swirl
GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPE_DOUBLE),
8749 5c55ff99 Blue Swirl
GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPE_DOUBLE),
8750 5c55ff99 Blue Swirl
GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8751 5c55ff99 Blue Swirl
GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPE_DOUBLE),
8752 5c55ff99 Blue Swirl
GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPE_DOUBLE),
8753 5c55ff99 Blue Swirl
GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8754 5c55ff99 Blue Swirl
GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8755 5c55ff99 Blue Swirl
GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8756 5c55ff99 Blue Swirl
GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8757 5c55ff99 Blue Swirl
GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8758 5c55ff99 Blue Swirl
GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPE_DOUBLE),
8759 5c55ff99 Blue Swirl
GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPE_DOUBLE),
8760 5c55ff99 Blue Swirl
GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPE_DOUBLE),
8761 5c55ff99 Blue Swirl
8762 5c55ff99 Blue Swirl
#undef GEN_SPEOP_LDST
8763 5c55ff99 Blue Swirl
#define GEN_SPEOP_LDST(name, opc2, sh)                                        \
8764 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x04, opc2, 0x0C, 0x00000000, PPC_SPE)
8765 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evldd, 0x00, 3),
8766 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evldw, 0x01, 3),
8767 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evldh, 0x02, 3),
8768 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evlhhesplat, 0x04, 1),
8769 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evlhhousplat, 0x06, 1),
8770 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evlhhossplat, 0x07, 1),
8771 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evlwhe, 0x08, 2),
8772 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evlwhou, 0x0A, 2),
8773 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evlwhos, 0x0B, 2),
8774 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2),
8775 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2),
8776 5c55ff99 Blue Swirl
8777 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evstdd, 0x10, 3),
8778 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evstdw, 0x11, 3),
8779 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evstdh, 0x12, 3),
8780 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evstwhe, 0x18, 2),
8781 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evstwho, 0x1A, 2),
8782 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evstwwe, 0x1C, 2),
8783 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evstwwo, 0x1E, 2),
8784 5c55ff99 Blue Swirl
};
8785 5c55ff99 Blue Swirl
8786 3fc6c082 bellard
#include "translate_init.c"
8787 0411a972 j_mayer
#include "helper_regs.h"
8788 79aceca5 bellard
8789 9a64fbe4 bellard
/*****************************************************************************/
8790 3fc6c082 bellard
/* Misc PowerPC helpers */
8791 36081602 j_mayer
void cpu_dump_state (CPUState *env, FILE *f,
8792 36081602 j_mayer
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8793 36081602 j_mayer
                     int flags)
8794 79aceca5 bellard
{
8795 3fc6c082 bellard
#define RGPL  4
8796 3fc6c082 bellard
#define RFPL  4
8797 3fc6c082 bellard
8798 79aceca5 bellard
    int i;
8799 79aceca5 bellard
8800 077fc206 j_mayer
    cpu_fprintf(f, "NIP " ADDRX "   LR " ADDRX " CTR " ADDRX " XER %08x\n",
8801 3d7b417e aurel32
                env->nip, env->lr, env->ctr, env->xer);
8802 6b542af7 j_mayer
    cpu_fprintf(f, "MSR " ADDRX " HID0 " ADDRX "  HF " ADDRX " idx %d\n",
8803 6b542af7 j_mayer
                env->msr, env->spr[SPR_HID0], env->hflags, env->mmu_idx);
8804 d9bce9d9 j_mayer
#if !defined(NO_TIMER_DUMP)
8805 077fc206 j_mayer
    cpu_fprintf(f, "TB %08x %08x "
8806 76a66253 j_mayer
#if !defined(CONFIG_USER_ONLY)
8807 76a66253 j_mayer
                "DECR %08x"
8808 76a66253 j_mayer
#endif
8809 76a66253 j_mayer
                "\n",
8810 077fc206 j_mayer
                cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
8811 76a66253 j_mayer
#if !defined(CONFIG_USER_ONLY)
8812 76a66253 j_mayer
                , cpu_ppc_load_decr(env)
8813 76a66253 j_mayer
#endif
8814 76a66253 j_mayer
                );
8815 077fc206 j_mayer
#endif
8816 76a66253 j_mayer
    for (i = 0; i < 32; i++) {
8817 3fc6c082 bellard
        if ((i & (RGPL - 1)) == 0)
8818 3fc6c082 bellard
            cpu_fprintf(f, "GPR%02d", i);
8819 6b542af7 j_mayer
        cpu_fprintf(f, " " REGX, ppc_dump_gpr(env, i));
8820 3fc6c082 bellard
        if ((i & (RGPL - 1)) == (RGPL - 1))
8821 7fe48483 bellard
            cpu_fprintf(f, "\n");
8822 76a66253 j_mayer
    }
8823 3fc6c082 bellard
    cpu_fprintf(f, "CR ");
8824 76a66253 j_mayer
    for (i = 0; i < 8; i++)
8825 7fe48483 bellard
        cpu_fprintf(f, "%01x", env->crf[i]);
8826 7fe48483 bellard
    cpu_fprintf(f, "  [");
8827 76a66253 j_mayer
    for (i = 0; i < 8; i++) {
8828 76a66253 j_mayer
        char a = '-';
8829 76a66253 j_mayer
        if (env->crf[i] & 0x08)
8830 76a66253 j_mayer
            a = 'L';
8831 76a66253 j_mayer
        else if (env->crf[i] & 0x04)
8832 76a66253 j_mayer
            a = 'G';
8833 76a66253 j_mayer
        else if (env->crf[i] & 0x02)
8834 76a66253 j_mayer
            a = 'E';
8835 7fe48483 bellard
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
8836 76a66253 j_mayer
    }
8837 6b542af7 j_mayer
    cpu_fprintf(f, " ]             RES " ADDRX "\n", env->reserve);
8838 3fc6c082 bellard
    for (i = 0; i < 32; i++) {
8839 3fc6c082 bellard
        if ((i & (RFPL - 1)) == 0)
8840 3fc6c082 bellard
            cpu_fprintf(f, "FPR%02d", i);
8841 26a76461 bellard
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
8842 3fc6c082 bellard
        if ((i & (RFPL - 1)) == (RFPL - 1))
8843 7fe48483 bellard
            cpu_fprintf(f, "\n");
8844 79aceca5 bellard
    }
8845 7889270a aurel32
    cpu_fprintf(f, "FPSCR %08x\n", env->fpscr);
8846 f2e63a42 j_mayer
#if !defined(CONFIG_USER_ONLY)
8847 6b542af7 j_mayer
    cpu_fprintf(f, "SRR0 " ADDRX " SRR1 " ADDRX " SDR1 " ADDRX "\n",
8848 3fc6c082 bellard
                env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
8849 f2e63a42 j_mayer
#endif
8850 79aceca5 bellard
8851 3fc6c082 bellard
#undef RGPL
8852 3fc6c082 bellard
#undef RFPL
8853 79aceca5 bellard
}
8854 79aceca5 bellard
8855 76a66253 j_mayer
void cpu_dump_statistics (CPUState *env, FILE*f,
8856 76a66253 j_mayer
                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8857 76a66253 j_mayer
                          int flags)
8858 76a66253 j_mayer
{
8859 76a66253 j_mayer
#if defined(DO_PPC_STATISTICS)
8860 76a66253 j_mayer
    opc_handler_t **t1, **t2, **t3, *handler;
8861 76a66253 j_mayer
    int op1, op2, op3;
8862 76a66253 j_mayer
8863 76a66253 j_mayer
    t1 = env->opcodes;
8864 76a66253 j_mayer
    for (op1 = 0; op1 < 64; op1++) {
8865 76a66253 j_mayer
        handler = t1[op1];
8866 76a66253 j_mayer
        if (is_indirect_opcode(handler)) {
8867 76a66253 j_mayer
            t2 = ind_table(handler);
8868 76a66253 j_mayer
            for (op2 = 0; op2 < 32; op2++) {
8869 76a66253 j_mayer
                handler = t2[op2];
8870 76a66253 j_mayer
                if (is_indirect_opcode(handler)) {
8871 76a66253 j_mayer
                    t3 = ind_table(handler);
8872 76a66253 j_mayer
                    for (op3 = 0; op3 < 32; op3++) {
8873 76a66253 j_mayer
                        handler = t3[op3];
8874 76a66253 j_mayer
                        if (handler->count == 0)
8875 76a66253 j_mayer
                            continue;
8876 76a66253 j_mayer
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
8877 76a66253 j_mayer
                                    "%016llx %lld\n",
8878 76a66253 j_mayer
                                    op1, op2, op3, op1, (op3 << 5) | op2,
8879 76a66253 j_mayer
                                    handler->oname,
8880 76a66253 j_mayer
                                    handler->count, handler->count);
8881 76a66253 j_mayer
                    }
8882 76a66253 j_mayer
                } else {
8883 76a66253 j_mayer
                    if (handler->count == 0)
8884 76a66253 j_mayer
                        continue;
8885 76a66253 j_mayer
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
8886 76a66253 j_mayer
                                "%016llx %lld\n",
8887 76a66253 j_mayer
                                op1, op2, op1, op2, handler->oname,
8888 76a66253 j_mayer
                                handler->count, handler->count);
8889 76a66253 j_mayer
                }
8890 76a66253 j_mayer
            }
8891 76a66253 j_mayer
        } else {
8892 76a66253 j_mayer
            if (handler->count == 0)
8893 76a66253 j_mayer
                continue;
8894 76a66253 j_mayer
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
8895 76a66253 j_mayer
                        op1, op1, handler->oname,
8896 76a66253 j_mayer
                        handler->count, handler->count);
8897 76a66253 j_mayer
        }
8898 76a66253 j_mayer
    }
8899 76a66253 j_mayer
#endif
8900 76a66253 j_mayer
}
8901 76a66253 j_mayer
8902 9a64fbe4 bellard
/*****************************************************************************/
8903 2cfc5f17 ths
static always_inline void gen_intermediate_code_internal (CPUState *env,
8904 2cfc5f17 ths
                                                          TranslationBlock *tb,
8905 2cfc5f17 ths
                                                          int search_pc)
8906 79aceca5 bellard
{
8907 9fddaa0c bellard
    DisasContext ctx, *ctxp = &ctx;
8908 79aceca5 bellard
    opc_handler_t **table, *handler;
8909 0fa85d43 bellard
    target_ulong pc_start;
8910 79aceca5 bellard
    uint16_t *gen_opc_end;
8911 a1d1bb31 aliguori
    CPUBreakpoint *bp;
8912 79aceca5 bellard
    int j, lj = -1;
8913 2e70f6ef pbrook
    int num_insns;
8914 2e70f6ef pbrook
    int max_insns;
8915 79aceca5 bellard
8916 79aceca5 bellard
    pc_start = tb->pc;
8917 79aceca5 bellard
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8918 046d6672 bellard
    ctx.nip = pc_start;
8919 79aceca5 bellard
    ctx.tb = tb;
8920 e1833e1f j_mayer
    ctx.exception = POWERPC_EXCP_NONE;
8921 3fc6c082 bellard
    ctx.spr_cb = env->spr_cb;
8922 76db3ba4 aurel32
    ctx.mem_idx = env->mmu_idx;
8923 76db3ba4 aurel32
    ctx.access_type = -1;
8924 76db3ba4 aurel32
    ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
8925 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
8926 d9bce9d9 j_mayer
    ctx.sf_mode = msr_sf;
8927 9a64fbe4 bellard
#endif
8928 3cc62370 bellard
    ctx.fpu_enabled = msr_fp;
8929 a9d9eb8f j_mayer
    if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
8930 d26bfc9a j_mayer
        ctx.spe_enabled = msr_spe;
8931 d26bfc9a j_mayer
    else
8932 d26bfc9a j_mayer
        ctx.spe_enabled = 0;
8933 a9d9eb8f j_mayer
    if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
8934 a9d9eb8f j_mayer
        ctx.altivec_enabled = msr_vr;
8935 a9d9eb8f j_mayer
    else
8936 a9d9eb8f j_mayer
        ctx.altivec_enabled = 0;
8937 d26bfc9a j_mayer
    if ((env->flags & POWERPC_FLAG_SE) && msr_se)
8938 8cbcb4fa aurel32
        ctx.singlestep_enabled = CPU_SINGLE_STEP;
8939 d26bfc9a j_mayer
    else
8940 8cbcb4fa aurel32
        ctx.singlestep_enabled = 0;
8941 d26bfc9a j_mayer
    if ((env->flags & POWERPC_FLAG_BE) && msr_be)
8942 8cbcb4fa aurel32
        ctx.singlestep_enabled |= CPU_BRANCH_STEP;
8943 8cbcb4fa aurel32
    if (unlikely(env->singlestep_enabled))
8944 8cbcb4fa aurel32
        ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
8945 3fc6c082 bellard
#if defined (DO_SINGLE_STEP) && 0
8946 9a64fbe4 bellard
    /* Single step trace mode */
8947 9a64fbe4 bellard
    msr_se = 1;
8948 9a64fbe4 bellard
#endif
8949 2e70f6ef pbrook
    num_insns = 0;
8950 2e70f6ef pbrook
    max_insns = tb->cflags & CF_COUNT_MASK;
8951 2e70f6ef pbrook
    if (max_insns == 0)
8952 2e70f6ef pbrook
        max_insns = CF_COUNT_MASK;
8953 2e70f6ef pbrook
8954 2e70f6ef pbrook
    gen_icount_start();
8955 9a64fbe4 bellard
    /* Set env in case of segfault during code fetch */
8956 e1833e1f j_mayer
    while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
8957 c0ce998e aliguori
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8958 c0ce998e aliguori
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8959 a1d1bb31 aliguori
                if (bp->pc == ctx.nip) {
8960 e06fcd75 aurel32
                    gen_debug_exception(ctxp);
8961 ea4e754f bellard
                    break;
8962 ea4e754f bellard
                }
8963 ea4e754f bellard
            }
8964 ea4e754f bellard
        }
8965 76a66253 j_mayer
        if (unlikely(search_pc)) {
8966 79aceca5 bellard
            j = gen_opc_ptr - gen_opc_buf;
8967 79aceca5 bellard
            if (lj < j) {
8968 79aceca5 bellard
                lj++;
8969 79aceca5 bellard
                while (lj < j)
8970 79aceca5 bellard
                    gen_opc_instr_start[lj++] = 0;
8971 79aceca5 bellard
            }
8972 af4b6c54 aurel32
            gen_opc_pc[lj] = ctx.nip;
8973 af4b6c54 aurel32
            gen_opc_instr_start[lj] = 1;
8974 af4b6c54 aurel32
            gen_opc_icount[lj] = num_insns;
8975 79aceca5 bellard
        }
8976 d12d51d5 aliguori
        LOG_DISAS("----------------\n");
8977 d12d51d5 aliguori
        LOG_DISAS("nip=" ADDRX " super=%d ir=%d\n",
8978 d12d51d5 aliguori
                  ctx.nip, ctx.mem_idx, (int)msr_ir);
8979 2e70f6ef pbrook
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8980 2e70f6ef pbrook
            gen_io_start();
8981 76db3ba4 aurel32
        if (unlikely(ctx.le_mode)) {
8982 056401ea j_mayer
            ctx.opcode = bswap32(ldl_code(ctx.nip));
8983 056401ea j_mayer
        } else {
8984 056401ea j_mayer
            ctx.opcode = ldl_code(ctx.nip);
8985 111bfab3 bellard
        }
8986 d12d51d5 aliguori
        LOG_DISAS("translate opcode %08x (%02x %02x %02x) (%s)\n",
8987 9a64fbe4 bellard
                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
8988 056401ea j_mayer
                    opc3(ctx.opcode), little_endian ? "little" : "big");
8989 046d6672 bellard
        ctx.nip += 4;
8990 3fc6c082 bellard
        table = env->opcodes;
8991 2e70f6ef pbrook
        num_insns++;
8992 79aceca5 bellard
        handler = table[opc1(ctx.opcode)];
8993 79aceca5 bellard
        if (is_indirect_opcode(handler)) {
8994 79aceca5 bellard
            table = ind_table(handler);
8995 79aceca5 bellard
            handler = table[opc2(ctx.opcode)];
8996 79aceca5 bellard
            if (is_indirect_opcode(handler)) {
8997 79aceca5 bellard
                table = ind_table(handler);
8998 79aceca5 bellard
                handler = table[opc3(ctx.opcode)];
8999 79aceca5 bellard
            }
9000 79aceca5 bellard
        }
9001 79aceca5 bellard
        /* Is opcode *REALLY* valid ? */
9002 76a66253 j_mayer
        if (unlikely(handler->handler == &gen_invalid)) {
9003 93fcfe39 aliguori
            if (qemu_log_enabled()) {
9004 93fcfe39 aliguori
                qemu_log("invalid/unsupported opcode: "
9005 93fcfe39 aliguori
                          "%02x - %02x - %02x (%08x) " ADDRX " %d\n",
9006 93fcfe39 aliguori
                          opc1(ctx.opcode), opc2(ctx.opcode),
9007 93fcfe39 aliguori
                          opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
9008 4b3686fa bellard
            } else {
9009 4b3686fa bellard
                printf("invalid/unsupported opcode: "
9010 6b542af7 j_mayer
                       "%02x - %02x - %02x (%08x) " ADDRX " %d\n",
9011 4b3686fa bellard
                       opc1(ctx.opcode), opc2(ctx.opcode),
9012 0411a972 j_mayer
                       opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
9013 4b3686fa bellard
            }
9014 76a66253 j_mayer
        } else {
9015 76a66253 j_mayer
            if (unlikely((ctx.opcode & handler->inval) != 0)) {
9016 93fcfe39 aliguori
                if (qemu_log_enabled()) {
9017 93fcfe39 aliguori
                    qemu_log("invalid bits: %08x for opcode: "
9018 93fcfe39 aliguori
                              "%02x - %02x - %02x (%08x) " ADDRX "\n",
9019 93fcfe39 aliguori
                              ctx.opcode & handler->inval, opc1(ctx.opcode),
9020 93fcfe39 aliguori
                              opc2(ctx.opcode), opc3(ctx.opcode),
9021 93fcfe39 aliguori
                              ctx.opcode, ctx.nip - 4);
9022 9a64fbe4 bellard
                } else {
9023 9a64fbe4 bellard
                    printf("invalid bits: %08x for opcode: "
9024 6b542af7 j_mayer
                           "%02x - %02x - %02x (%08x) " ADDRX "\n",
9025 76a66253 j_mayer
                           ctx.opcode & handler->inval, opc1(ctx.opcode),
9026 76a66253 j_mayer
                           opc2(ctx.opcode), opc3(ctx.opcode),
9027 046d6672 bellard
                           ctx.opcode, ctx.nip - 4);
9028 76a66253 j_mayer
                }
9029 e06fcd75 aurel32
                gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);
9030 4b3686fa bellard
                break;
9031 79aceca5 bellard
            }
9032 79aceca5 bellard
        }
9033 4b3686fa bellard
        (*(handler->handler))(&ctx);
9034 76a66253 j_mayer
#if defined(DO_PPC_STATISTICS)
9035 76a66253 j_mayer
        handler->count++;
9036 76a66253 j_mayer
#endif
9037 9a64fbe4 bellard
        /* Check trace mode exceptions */
9038 8cbcb4fa aurel32
        if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
9039 8cbcb4fa aurel32
                     (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
9040 8cbcb4fa aurel32
                     ctx.exception != POWERPC_SYSCALL &&
9041 8cbcb4fa aurel32
                     ctx.exception != POWERPC_EXCP_TRAP &&
9042 8cbcb4fa aurel32
                     ctx.exception != POWERPC_EXCP_BRANCH)) {
9043 e06fcd75 aurel32
            gen_exception(ctxp, POWERPC_EXCP_TRACE);
9044 d26bfc9a j_mayer
        } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
9045 2e70f6ef pbrook
                            (env->singlestep_enabled) ||
9046 1b530a6d aurel32
                            singlestep ||
9047 2e70f6ef pbrook
                            num_insns >= max_insns)) {
9048 d26bfc9a j_mayer
            /* if we reach a page boundary or are single stepping, stop
9049 d26bfc9a j_mayer
             * generation
9050 d26bfc9a j_mayer
             */
9051 8dd4983c bellard
            break;
9052 76a66253 j_mayer
        }
9053 3fc6c082 bellard
    }
9054 2e70f6ef pbrook
    if (tb->cflags & CF_LAST_IO)
9055 2e70f6ef pbrook
        gen_io_end();
9056 e1833e1f j_mayer
    if (ctx.exception == POWERPC_EXCP_NONE) {
9057 c1942362 bellard
        gen_goto_tb(&ctx, 0, ctx.nip);
9058 e1833e1f j_mayer
    } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
9059 8cbcb4fa aurel32
        if (unlikely(env->singlestep_enabled)) {
9060 e06fcd75 aurel32
            gen_debug_exception(ctxp);
9061 8cbcb4fa aurel32
        }
9062 76a66253 j_mayer
        /* Generate the return instruction */
9063 57fec1fe bellard
        tcg_gen_exit_tb(0);
9064 9a64fbe4 bellard
    }
9065 2e70f6ef pbrook
    gen_icount_end(tb, num_insns);
9066 79aceca5 bellard
    *gen_opc_ptr = INDEX_op_end;
9067 76a66253 j_mayer
    if (unlikely(search_pc)) {
9068 9a64fbe4 bellard
        j = gen_opc_ptr - gen_opc_buf;
9069 9a64fbe4 bellard
        lj++;
9070 9a64fbe4 bellard
        while (lj <= j)
9071 9a64fbe4 bellard
            gen_opc_instr_start[lj++] = 0;
9072 9a64fbe4 bellard
    } else {
9073 046d6672 bellard
        tb->size = ctx.nip - pc_start;
9074 2e70f6ef pbrook
        tb->icount = num_insns;
9075 9a64fbe4 bellard
    }
9076 d9bce9d9 j_mayer
#if defined(DEBUG_DISAS)
9077 93fcfe39 aliguori
    qemu_log_mask(CPU_LOG_TB_CPU, "---------------- excp: %04x\n", ctx.exception);
9078 93fcfe39 aliguori
    log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
9079 8fec2b8c aliguori
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9080 76a66253 j_mayer
        int flags;
9081 237c0af0 j_mayer
        flags = env->bfd_mach;
9082 76db3ba4 aurel32
        flags |= ctx.le_mode << 16;
9083 93fcfe39 aliguori
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
9084 93fcfe39 aliguori
        log_target_disas(pc_start, ctx.nip - pc_start, flags);
9085 93fcfe39 aliguori
        qemu_log("\n");
9086 9fddaa0c bellard
    }
9087 79aceca5 bellard
#endif
9088 79aceca5 bellard
}
9089 79aceca5 bellard
9090 2cfc5f17 ths
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
9091 79aceca5 bellard
{
9092 2cfc5f17 ths
    gen_intermediate_code_internal(env, tb, 0);
9093 79aceca5 bellard
}
9094 79aceca5 bellard
9095 2cfc5f17 ths
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
9096 79aceca5 bellard
{
9097 2cfc5f17 ths
    gen_intermediate_code_internal(env, tb, 1);
9098 79aceca5 bellard
}
9099 d2856f1a aurel32
9100 d2856f1a aurel32
void gen_pc_load(CPUState *env, TranslationBlock *tb,
9101 d2856f1a aurel32
                unsigned long searched_pc, int pc_pos, void *puc)
9102 d2856f1a aurel32
{
9103 d2856f1a aurel32
    env->nip = gen_opc_pc[pc_pos];
9104 d2856f1a aurel32
}