Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 6659394f

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

7853 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7854 70560da7 Fabien Chouteau
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE);
7855 70560da7 Fabien Chouteau
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, 0x00000000, PPC_SPE);
7856 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7857 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7858 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7859 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7860 70560da7 Fabien Chouteau
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE);
7861 70560da7 Fabien Chouteau
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, 0x00000000, PPC_SPE);
7862 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7863 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7864 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7865 70560da7 Fabien Chouteau

7866 70560da7 Fabien Chouteau
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
7867 70560da7 Fabien Chouteau
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
7868 70560da7 Fabien Chouteau
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
7869 70560da7 Fabien Chouteau
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
7870 70560da7 Fabien Chouteau
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, 0x00000000, PPC_SPE);
7871 70560da7 Fabien Chouteau

7872 70560da7 Fabien Chouteau
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, 0x00000000, PPC_SPE);
7873 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7874 70560da7 Fabien Chouteau
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, 0x00000000, PPC_SPE);
7875 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7876 70560da7 Fabien Chouteau
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, 0x00000000, PPC_SPE);
7877 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7878 70560da7 Fabien Chouteau
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, 0x00000000, PPC_SPE);
7879 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7880 70560da7 Fabien Chouteau
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, 0x00000000, PPC_SPE);
7881 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7882 70560da7 Fabien Chouteau
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, 0x00000000, PPC_SPE);
7883 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7884 70560da7 Fabien Chouteau

7885 70560da7 Fabien Chouteau
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, 0x00000000, PPC_SPE);
7886 70560da7 Fabien Chouteau
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, 0x00000000, PPC_SPE);
7887 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7888 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7889 70560da7 Fabien Chouteau

7890 70560da7 Fabien Chouteau
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, 0x00000000, PPC_SPE);
7891 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7892 70560da7 Fabien Chouteau
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, 0x00000000, PPC_SPE);
7893 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7894 70560da7 Fabien Chouteau
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, 0x00000000, PPC_SPE);
7895 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7896 70560da7 Fabien Chouteau
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, 0x00000000, PPC_SPE);
7897 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7898 70560da7 Fabien Chouteau
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, 0x00000000, PPC_SPE);
7899 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7900 70560da7 Fabien Chouteau
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, 0x00000000, PPC_SPE);
7901 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7902 70560da7 Fabien Chouteau

7903 70560da7 Fabien Chouteau
GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, 0x00000000, PPC_SPE);
7904 70560da7 Fabien Chouteau
GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, 0x00000000, PPC_SPE);
7905 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7906 70560da7 Fabien Chouteau
GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, 0x00000000, PPC_SPE);
7907 70560da7 Fabien Chouteau
GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE);
7908 0487d6a8 j_mayer
#endif
7909 0487d6a8 j_mayer
7910 0487d6a8 j_mayer
/***                      SPE floating-point extension                     ***/
7911 1c97856d aurel32
#if defined(TARGET_PPC64)
7912 1c97856d aurel32
#define GEN_SPEFPUOP_CONV_32_32(name)                                         \
7913 636aa200 Blue Swirl
static inline void gen_##name(DisasContext *ctx)                              \
7914 0487d6a8 j_mayer
{                                                                             \
7915 1c97856d aurel32
    TCGv_i32 t0;                                                              \
7916 1c97856d aurel32
    TCGv t1;                                                                  \
7917 1c97856d aurel32
    t0 = tcg_temp_new_i32();                                                  \
7918 1c97856d aurel32
    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
7919 1c97856d aurel32
    gen_helper_##name(t0, t0);                                                \
7920 1c97856d aurel32
    t1 = tcg_temp_new();                                                      \
7921 1c97856d aurel32
    tcg_gen_extu_i32_tl(t1, t0);                                              \
7922 1c97856d aurel32
    tcg_temp_free_i32(t0);                                                    \
7923 1c97856d aurel32
    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
7924 1c97856d aurel32
                    0xFFFFFFFF00000000ULL);                                   \
7925 1c97856d aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
7926 1c97856d aurel32
    tcg_temp_free(t1);                                                        \
7927 0487d6a8 j_mayer
}
7928 1c97856d aurel32
#define GEN_SPEFPUOP_CONV_32_64(name)                                         \
7929 636aa200 Blue Swirl
static inline void gen_##name(DisasContext *ctx)                              \
7930 1c97856d aurel32
{                                                                             \
7931 1c97856d aurel32
    TCGv_i32 t0;                                                              \
7932 1c97856d aurel32
    TCGv t1;                                                                  \
7933 1c97856d aurel32
    t0 = tcg_temp_new_i32();                                                  \
7934 1c97856d aurel32
    gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]);                          \
7935 1c97856d aurel32
    t1 = tcg_temp_new();                                                      \
7936 1c97856d aurel32
    tcg_gen_extu_i32_tl(t1, t0);                                              \
7937 1c97856d aurel32
    tcg_temp_free_i32(t0);                                                    \
7938 1c97856d aurel32
    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
7939 1c97856d aurel32
                    0xFFFFFFFF00000000ULL);                                   \
7940 1c97856d aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
7941 1c97856d aurel32
    tcg_temp_free(t1);                                                        \
7942 1c97856d aurel32
}
7943 1c97856d aurel32
#define GEN_SPEFPUOP_CONV_64_32(name)                                         \
7944 636aa200 Blue Swirl
static inline void gen_##name(DisasContext *ctx)                              \
7945 1c97856d aurel32
{                                                                             \
7946 1c97856d aurel32
    TCGv_i32 t0 = tcg_temp_new_i32();                                         \
7947 1c97856d aurel32
    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
7948 1c97856d aurel32
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0);                          \
7949 1c97856d aurel32
    tcg_temp_free_i32(t0);                                                    \
7950 1c97856d aurel32
}
7951 1c97856d aurel32
#define GEN_SPEFPUOP_CONV_64_64(name)                                         \
7952 636aa200 Blue Swirl
static inline void gen_##name(DisasContext *ctx)                              \
7953 1c97856d aurel32
{                                                                             \
7954 1c97856d aurel32
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
7955 1c97856d aurel32
}
7956 1c97856d aurel32
#define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
7957 636aa200 Blue Swirl
static inline void gen_##name(DisasContext *ctx)                              \
7958 57951c27 aurel32
{                                                                             \
7959 1c97856d aurel32
    TCGv_i32 t0, t1;                                                          \
7960 1c97856d aurel32
    TCGv_i64 t2;                                                              \
7961 57951c27 aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
7962 27a69bb0 Alexander Graf
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7963 57951c27 aurel32
        return;                                                               \
7964 57951c27 aurel32
    }                                                                         \
7965 1c97856d aurel32
    t0 = tcg_temp_new_i32();                                                  \
7966 1c97856d aurel32
    t1 = tcg_temp_new_i32();                                                  \
7967 1c97856d aurel32
    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
7968 1c97856d aurel32
    tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
7969 1c97856d aurel32
    gen_helper_##name(t0, t0, t1);                                            \
7970 1c97856d aurel32
    tcg_temp_free_i32(t1);                                                    \
7971 1c97856d aurel32
    t2 = tcg_temp_new();                                                      \
7972 1c97856d aurel32
    tcg_gen_extu_i32_tl(t2, t0);                                              \
7973 1c97856d aurel32
    tcg_temp_free_i32(t0);                                                    \
7974 1c97856d aurel32
    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
7975 1c97856d aurel32
                    0xFFFFFFFF00000000ULL);                                   \
7976 1c97856d aurel32
    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t2);    \
7977 1c97856d aurel32
    tcg_temp_free(t2);                                                        \
7978 57951c27 aurel32
}
7979 1c97856d aurel32
#define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
7980 636aa200 Blue Swirl
static inline void gen_##name(DisasContext *ctx)                              \
7981 57951c27 aurel32
{                                                                             \
7982 57951c27 aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
7983 27a69bb0 Alexander Graf
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7984 57951c27 aurel32
        return;                                                               \
7985 57951c27 aurel32
    }                                                                         \
7986 1c97856d aurel32
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],     \
7987 1c97856d aurel32
                      cpu_gpr[rB(ctx->opcode)]);                              \
7988 57951c27 aurel32
}
7989 1c97856d aurel32
#define GEN_SPEFPUOP_COMP_32(name)                                            \
7990 636aa200 Blue Swirl
static inline void gen_##name(DisasContext *ctx)                              \
7991 57951c27 aurel32
{                                                                             \
7992 1c97856d aurel32
    TCGv_i32 t0, t1;                                                          \
7993 57951c27 aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
7994 27a69bb0 Alexander Graf
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
7995 57951c27 aurel32
        return;                                                               \
7996 57951c27 aurel32
    }                                                                         \
7997 1c97856d aurel32
    t0 = tcg_temp_new_i32();                                                  \
7998 1c97856d aurel32
    t1 = tcg_temp_new_i32();                                                  \
7999 1c97856d aurel32
    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
8000 1c97856d aurel32
    tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
8001 1c97856d aurel32
    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1);                    \
8002 1c97856d aurel32
    tcg_temp_free_i32(t0);                                                    \
8003 1c97856d aurel32
    tcg_temp_free_i32(t1);                                                    \
8004 1c97856d aurel32
}
8005 1c97856d aurel32
#define GEN_SPEFPUOP_COMP_64(name)                                            \
8006 636aa200 Blue Swirl
static inline void gen_##name(DisasContext *ctx)                              \
8007 1c97856d aurel32
{                                                                             \
8008 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
8009 27a69bb0 Alexander Graf
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8010 1c97856d aurel32
        return;                                                               \
8011 1c97856d aurel32
    }                                                                         \
8012 1c97856d aurel32
    gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
8013 1c97856d aurel32
                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
8014 1c97856d aurel32
}
8015 1c97856d aurel32
#else
8016 1c97856d aurel32
#define GEN_SPEFPUOP_CONV_32_32(name)                                         \
8017 636aa200 Blue Swirl
static inline void gen_##name(DisasContext *ctx)                              \
8018 1c97856d aurel32
{                                                                             \
8019 1c97856d aurel32
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
8020 57951c27 aurel32
}
8021 1c97856d aurel32
#define GEN_SPEFPUOP_CONV_32_64(name)                                         \
8022 636aa200 Blue Swirl
static inline void gen_##name(DisasContext *ctx)                              \
8023 1c97856d aurel32
{                                                                             \
8024 1c97856d aurel32
    TCGv_i64 t0 = tcg_temp_new_i64();                                         \
8025 1c97856d aurel32
    gen_load_gpr64(t0, rB(ctx->opcode));                                      \
8026 1c97856d aurel32
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0);                          \
8027 1c97856d aurel32
    tcg_temp_free_i64(t0);                                                    \
8028 1c97856d aurel32
}
8029 1c97856d aurel32
#define GEN_SPEFPUOP_CONV_64_32(name)                                         \
8030 636aa200 Blue Swirl
static inline void gen_##name(DisasContext *ctx)                              \
8031 1c97856d aurel32
{                                                                             \
8032 1c97856d aurel32
    TCGv_i64 t0 = tcg_temp_new_i64();                                         \
8033 1c97856d aurel32
    gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]);                          \
8034 1c97856d aurel32
    gen_store_gpr64(rD(ctx->opcode), t0);                                     \
8035 1c97856d aurel32
    tcg_temp_free_i64(t0);                                                    \
8036 1c97856d aurel32
}
8037 1c97856d aurel32
#define GEN_SPEFPUOP_CONV_64_64(name)                                         \
8038 636aa200 Blue Swirl
static inline void gen_##name(DisasContext *ctx)                              \
8039 1c97856d aurel32
{                                                                             \
8040 1c97856d aurel32
    TCGv_i64 t0 = tcg_temp_new_i64();                                         \
8041 1c97856d aurel32
    gen_load_gpr64(t0, rB(ctx->opcode));                                      \
8042 1c97856d aurel32
    gen_helper_##name(t0, t0);                                                \
8043 1c97856d aurel32
    gen_store_gpr64(rD(ctx->opcode), t0);                                     \
8044 1c97856d aurel32
    tcg_temp_free_i64(t0);                                                    \
8045 1c97856d aurel32
}
8046 1c97856d aurel32
#define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
8047 636aa200 Blue Swirl
static inline void gen_##name(DisasContext *ctx)                              \
8048 1c97856d aurel32
{                                                                             \
8049 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
8050 27a69bb0 Alexander Graf
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8051 1c97856d aurel32
        return;                                                               \
8052 1c97856d aurel32
    }                                                                         \
8053 1c97856d aurel32
    gen_helper_##name(cpu_gpr[rD(ctx->opcode)],                               \
8054 1c97856d aurel32
                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
8055 1c97856d aurel32
}
8056 1c97856d aurel32
#define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
8057 636aa200 Blue Swirl
static inline void gen_##name(DisasContext *ctx)                              \
8058 1c97856d aurel32
{                                                                             \
8059 1c97856d aurel32
    TCGv_i64 t0, t1;                                                          \
8060 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
8061 27a69bb0 Alexander Graf
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8062 1c97856d aurel32
        return;                                                               \
8063 1c97856d aurel32
    }                                                                         \
8064 1c97856d aurel32
    t0 = tcg_temp_new_i64();                                                  \
8065 1c97856d aurel32
    t1 = tcg_temp_new_i64();                                                  \
8066 1c97856d aurel32
    gen_load_gpr64(t0, rA(ctx->opcode));                                      \
8067 1c97856d aurel32
    gen_load_gpr64(t1, rB(ctx->opcode));                                      \
8068 1c97856d aurel32
    gen_helper_##name(t0, t0, t1);                                            \
8069 1c97856d aurel32
    gen_store_gpr64(rD(ctx->opcode), t0);                                     \
8070 1c97856d aurel32
    tcg_temp_free_i64(t0);                                                    \
8071 1c97856d aurel32
    tcg_temp_free_i64(t1);                                                    \
8072 1c97856d aurel32
}
8073 1c97856d aurel32
#define GEN_SPEFPUOP_COMP_32(name)                                            \
8074 636aa200 Blue Swirl
static inline void gen_##name(DisasContext *ctx)                              \
8075 1c97856d aurel32
{                                                                             \
8076 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
8077 27a69bb0 Alexander Graf
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8078 1c97856d aurel32
        return;                                                               \
8079 1c97856d aurel32
    }                                                                         \
8080 1c97856d aurel32
    gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
8081 1c97856d aurel32
                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
8082 1c97856d aurel32
}
8083 1c97856d aurel32
#define GEN_SPEFPUOP_COMP_64(name)                                            \
8084 636aa200 Blue Swirl
static inline void gen_##name(DisasContext *ctx)                              \
8085 1c97856d aurel32
{                                                                             \
8086 1c97856d aurel32
    TCGv_i64 t0, t1;                                                          \
8087 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {                                        \
8088 27a69bb0 Alexander Graf
        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
8089 1c97856d aurel32
        return;                                                               \
8090 1c97856d aurel32
    }                                                                         \
8091 1c97856d aurel32
    t0 = tcg_temp_new_i64();                                                  \
8092 1c97856d aurel32
    t1 = tcg_temp_new_i64();                                                  \
8093 1c97856d aurel32
    gen_load_gpr64(t0, rA(ctx->opcode));                                      \
8094 1c97856d aurel32
    gen_load_gpr64(t1, rB(ctx->opcode));                                      \
8095 1c97856d aurel32
    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1);                    \
8096 1c97856d aurel32
    tcg_temp_free_i64(t0);                                                    \
8097 1c97856d aurel32
    tcg_temp_free_i64(t1);                                                    \
8098 1c97856d aurel32
}
8099 1c97856d aurel32
#endif
8100 57951c27 aurel32
8101 0487d6a8 j_mayer
/* Single precision floating-point vectors operations */
8102 0487d6a8 j_mayer
/* Arithmetic */
8103 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_64_64(evfsadd);
8104 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_64_64(evfssub);
8105 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_64_64(evfsmul);
8106 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_64_64(evfsdiv);
8107 636aa200 Blue Swirl
static inline void gen_evfsabs(DisasContext *ctx)
8108 1c97856d aurel32
{
8109 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {
8110 27a69bb0 Alexander Graf
        gen_exception(ctx, POWERPC_EXCP_SPEU);
8111 1c97856d aurel32
        return;
8112 1c97856d aurel32
    }
8113 1c97856d aurel32
#if defined(TARGET_PPC64)
8114 6d5c34fa Mike Pall
    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000080000000LL);
8115 1c97856d aurel32
#else
8116 6d5c34fa Mike Pall
    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x80000000);
8117 6d5c34fa Mike Pall
    tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
8118 1c97856d aurel32
#endif
8119 1c97856d aurel32
}
8120 636aa200 Blue Swirl
static inline void gen_evfsnabs(DisasContext *ctx)
8121 1c97856d aurel32
{
8122 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {
8123 27a69bb0 Alexander Graf
        gen_exception(ctx, POWERPC_EXCP_SPEU);
8124 1c97856d aurel32
        return;
8125 1c97856d aurel32
    }
8126 1c97856d aurel32
#if defined(TARGET_PPC64)
8127 6d5c34fa Mike Pall
    tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
8128 1c97856d aurel32
#else
8129 6d5c34fa Mike Pall
    tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
8130 6d5c34fa Mike Pall
    tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
8131 1c97856d aurel32
#endif
8132 1c97856d aurel32
}
8133 636aa200 Blue Swirl
static inline void gen_evfsneg(DisasContext *ctx)
8134 1c97856d aurel32
{
8135 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {
8136 27a69bb0 Alexander Graf
        gen_exception(ctx, POWERPC_EXCP_SPEU);
8137 1c97856d aurel32
        return;
8138 1c97856d aurel32
    }
8139 1c97856d aurel32
#if defined(TARGET_PPC64)
8140 6d5c34fa Mike Pall
    tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
8141 1c97856d aurel32
#else
8142 6d5c34fa Mike Pall
    tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
8143 6d5c34fa Mike Pall
    tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
8144 1c97856d aurel32
#endif
8145 1c97856d aurel32
}
8146 1c97856d aurel32
8147 0487d6a8 j_mayer
/* Conversion */
8148 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(evfscfui);
8149 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(evfscfsi);
8150 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(evfscfuf);
8151 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(evfscfsf);
8152 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(evfsctui);
8153 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(evfsctsi);
8154 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(evfsctuf);
8155 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(evfsctsf);
8156 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(evfsctuiz);
8157 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(evfsctsiz);
8158 1c97856d aurel32
8159 0487d6a8 j_mayer
/* Comparison */
8160 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(evfscmpgt);
8161 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(evfscmplt);
8162 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(evfscmpeq);
8163 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(evfststgt);
8164 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(evfststlt);
8165 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(evfststeq);
8166 0487d6a8 j_mayer
8167 0487d6a8 j_mayer
/* Opcodes definitions */
8168 70560da7 Fabien Chouteau
GEN_SPE(evfsadd,   evfssub,   0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
8169 70560da7 Fabien Chouteau
GEN_SPE(evfsabs,   evfsnabs,  0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE); //
8170 70560da7 Fabien Chouteau
GEN_SPE(evfsneg,   speundef,  0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8171 70560da7 Fabien Chouteau
GEN_SPE(evfsmul,   evfsdiv,   0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
8172 70560da7 Fabien Chouteau
GEN_SPE(evfscmpgt, evfscmplt, 0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
8173 70560da7 Fabien Chouteau
GEN_SPE(evfscmpeq, speundef,  0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8174 70560da7 Fabien Chouteau
GEN_SPE(evfscfui,  evfscfsi,  0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8175 70560da7 Fabien Chouteau
GEN_SPE(evfscfuf,  evfscfsf,  0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8176 70560da7 Fabien Chouteau
GEN_SPE(evfsctui,  evfsctsi,  0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8177 70560da7 Fabien Chouteau
GEN_SPE(evfsctuf,  evfsctsf,  0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8178 70560da7 Fabien Chouteau
GEN_SPE(evfsctuiz, speundef,  0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8179 70560da7 Fabien Chouteau
GEN_SPE(evfsctsiz, speundef,  0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8180 70560da7 Fabien Chouteau
GEN_SPE(evfststgt, evfststlt, 0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
8181 70560da7 Fabien Chouteau
GEN_SPE(evfststeq, speundef,  0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8182 0487d6a8 j_mayer
8183 0487d6a8 j_mayer
/* Single precision floating-point operations */
8184 0487d6a8 j_mayer
/* Arithmetic */
8185 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_32_32(efsadd);
8186 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_32_32(efssub);
8187 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_32_32(efsmul);
8188 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_32_32(efsdiv);
8189 636aa200 Blue Swirl
static inline void gen_efsabs(DisasContext *ctx)
8190 1c97856d aurel32
{
8191 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {
8192 27a69bb0 Alexander Graf
        gen_exception(ctx, POWERPC_EXCP_SPEU);
8193 1c97856d aurel32
        return;
8194 1c97856d aurel32
    }
8195 6d5c34fa Mike Pall
    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], (target_long)~0x80000000LL);
8196 1c97856d aurel32
}
8197 636aa200 Blue Swirl
static inline void gen_efsnabs(DisasContext *ctx)
8198 1c97856d aurel32
{
8199 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {
8200 27a69bb0 Alexander Graf
        gen_exception(ctx, POWERPC_EXCP_SPEU);
8201 1c97856d aurel32
        return;
8202 1c97856d aurel32
    }
8203 6d5c34fa Mike Pall
    tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
8204 1c97856d aurel32
}
8205 636aa200 Blue Swirl
static inline void gen_efsneg(DisasContext *ctx)
8206 1c97856d aurel32
{
8207 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {
8208 27a69bb0 Alexander Graf
        gen_exception(ctx, POWERPC_EXCP_SPEU);
8209 1c97856d aurel32
        return;
8210 1c97856d aurel32
    }
8211 6d5c34fa Mike Pall
    tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
8212 1c97856d aurel32
}
8213 1c97856d aurel32
8214 0487d6a8 j_mayer
/* Conversion */
8215 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_32(efscfui);
8216 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_32(efscfsi);
8217 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_32(efscfuf);
8218 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_32(efscfsf);
8219 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_32(efsctui);
8220 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_32(efsctsi);
8221 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_32(efsctuf);
8222 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_32(efsctsf);
8223 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_32(efsctuiz);
8224 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_32(efsctsiz);
8225 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_64(efscfd);
8226 1c97856d aurel32
8227 0487d6a8 j_mayer
/* Comparison */
8228 1c97856d aurel32
GEN_SPEFPUOP_COMP_32(efscmpgt);
8229 1c97856d aurel32
GEN_SPEFPUOP_COMP_32(efscmplt);
8230 1c97856d aurel32
GEN_SPEFPUOP_COMP_32(efscmpeq);
8231 1c97856d aurel32
GEN_SPEFPUOP_COMP_32(efststgt);
8232 1c97856d aurel32
GEN_SPEFPUOP_COMP_32(efststlt);
8233 1c97856d aurel32
GEN_SPEFPUOP_COMP_32(efststeq);
8234 0487d6a8 j_mayer
8235 0487d6a8 j_mayer
/* Opcodes definitions */
8236 70560da7 Fabien Chouteau
GEN_SPE(efsadd,   efssub,   0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
8237 70560da7 Fabien Chouteau
GEN_SPE(efsabs,   efsnabs,  0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE); //
8238 70560da7 Fabien Chouteau
GEN_SPE(efsneg,   speundef, 0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8239 70560da7 Fabien Chouteau
GEN_SPE(efsmul,   efsdiv,   0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
8240 70560da7 Fabien Chouteau
GEN_SPE(efscmpgt, efscmplt, 0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
8241 70560da7 Fabien Chouteau
GEN_SPE(efscmpeq, efscfd,   0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE); //
8242 70560da7 Fabien Chouteau
GEN_SPE(efscfui,  efscfsi,  0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8243 70560da7 Fabien Chouteau
GEN_SPE(efscfuf,  efscfsf,  0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8244 70560da7 Fabien Chouteau
GEN_SPE(efsctui,  efsctsi,  0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8245 70560da7 Fabien Chouteau
GEN_SPE(efsctuf,  efsctsf,  0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
8246 70560da7 Fabien Chouteau
GEN_SPE(efsctuiz, speundef, 0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8247 70560da7 Fabien Chouteau
GEN_SPE(efsctsiz, speundef, 0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8248 70560da7 Fabien Chouteau
GEN_SPE(efststgt, efststlt, 0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
8249 70560da7 Fabien Chouteau
GEN_SPE(efststeq, speundef, 0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
8250 0487d6a8 j_mayer
8251 0487d6a8 j_mayer
/* Double precision floating-point operations */
8252 0487d6a8 j_mayer
/* Arithmetic */
8253 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_64_64(efdadd);
8254 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_64_64(efdsub);
8255 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_64_64(efdmul);
8256 1c97856d aurel32
GEN_SPEFPUOP_ARITH2_64_64(efddiv);
8257 636aa200 Blue Swirl
static inline void gen_efdabs(DisasContext *ctx)
8258 1c97856d aurel32
{
8259 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {
8260 27a69bb0 Alexander Graf
        gen_exception(ctx, POWERPC_EXCP_SPEU);
8261 1c97856d aurel32
        return;
8262 1c97856d aurel32
    }
8263 1c97856d aurel32
#if defined(TARGET_PPC64)
8264 6d5c34fa Mike Pall
    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000000000000LL);
8265 1c97856d aurel32
#else
8266 6d5c34fa Mike Pall
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8267 6d5c34fa Mike Pall
    tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
8268 1c97856d aurel32
#endif
8269 1c97856d aurel32
}
8270 636aa200 Blue Swirl
static inline void gen_efdnabs(DisasContext *ctx)
8271 1c97856d aurel32
{
8272 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {
8273 27a69bb0 Alexander Graf
        gen_exception(ctx, POWERPC_EXCP_SPEU);
8274 1c97856d aurel32
        return;
8275 1c97856d aurel32
    }
8276 1c97856d aurel32
#if defined(TARGET_PPC64)
8277 6d5c34fa Mike Pall
    tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
8278 1c97856d aurel32
#else
8279 6d5c34fa Mike Pall
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8280 6d5c34fa Mike Pall
    tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
8281 1c97856d aurel32
#endif
8282 1c97856d aurel32
}
8283 636aa200 Blue Swirl
static inline void gen_efdneg(DisasContext *ctx)
8284 1c97856d aurel32
{
8285 1c97856d aurel32
    if (unlikely(!ctx->spe_enabled)) {
8286 27a69bb0 Alexander Graf
        gen_exception(ctx, POWERPC_EXCP_SPEU);
8287 1c97856d aurel32
        return;
8288 1c97856d aurel32
    }
8289 1c97856d aurel32
#if defined(TARGET_PPC64)
8290 6d5c34fa Mike Pall
    tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
8291 1c97856d aurel32
#else
8292 6d5c34fa Mike Pall
    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
8293 6d5c34fa Mike Pall
    tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
8294 1c97856d aurel32
#endif
8295 1c97856d aurel32
}
8296 1c97856d aurel32
8297 0487d6a8 j_mayer
/* Conversion */
8298 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_32(efdcfui);
8299 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_32(efdcfsi);
8300 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_32(efdcfuf);
8301 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_32(efdcfsf);
8302 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_64(efdctui);
8303 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_64(efdctsi);
8304 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_64(efdctuf);
8305 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_64(efdctsf);
8306 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_64(efdctuiz);
8307 1c97856d aurel32
GEN_SPEFPUOP_CONV_32_64(efdctsiz);
8308 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_32(efdcfs);
8309 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(efdcfuid);
8310 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(efdcfsid);
8311 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(efdctuidz);
8312 1c97856d aurel32
GEN_SPEFPUOP_CONV_64_64(efdctsidz);
8313 0487d6a8 j_mayer
8314 0487d6a8 j_mayer
/* Comparison */
8315 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(efdcmpgt);
8316 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(efdcmplt);
8317 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(efdcmpeq);
8318 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(efdtstgt);
8319 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(efdtstlt);
8320 1c97856d aurel32
GEN_SPEFPUOP_COMP_64(efdtsteq);
8321 0487d6a8 j_mayer
8322 0487d6a8 j_mayer
/* Opcodes definitions */
8323 70560da7 Fabien Chouteau
GEN_SPE(efdadd,    efdsub,    0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE); //
8324 70560da7 Fabien Chouteau
GEN_SPE(efdcfuid,  efdcfsid,  0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
8325 70560da7 Fabien Chouteau
GEN_SPE(efdabs,    efdnabs,   0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE); //
8326 70560da7 Fabien Chouteau
GEN_SPE(efdneg,    speundef,  0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
8327 70560da7 Fabien Chouteau
GEN_SPE(efdmul,    efddiv,    0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE); //
8328 70560da7 Fabien Chouteau
GEN_SPE(efdctuidz, efdctsidz, 0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
8329 70560da7 Fabien Chouteau
GEN_SPE(efdcmpgt,  efdcmplt,  0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE); //
8330 70560da7 Fabien Chouteau
GEN_SPE(efdcmpeq,  efdcfs,    0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE); //
8331 70560da7 Fabien Chouteau
GEN_SPE(efdcfui,   efdcfsi,   0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
8332 70560da7 Fabien Chouteau
GEN_SPE(efdcfuf,   efdcfsf,   0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
8333 70560da7 Fabien Chouteau
GEN_SPE(efdctui,   efdctsi,   0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
8334 70560da7 Fabien Chouteau
GEN_SPE(efdctuf,   efdctsf,   0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
8335 70560da7 Fabien Chouteau
GEN_SPE(efdctuiz,  speundef,  0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
8336 70560da7 Fabien Chouteau
GEN_SPE(efdctsiz,  speundef,  0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
8337 70560da7 Fabien Chouteau
GEN_SPE(efdtstgt,  efdtstlt,  0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE); //
8338 70560da7 Fabien Chouteau
GEN_SPE(efdtsteq,  speundef,  0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
8339 0487d6a8 j_mayer
8340 c227f099 Anthony Liguori
static opcode_t opcodes[] = {
8341 5c55ff99 Blue Swirl
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE),
8342 5c55ff99 Blue Swirl
GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER),
8343 5c55ff99 Blue Swirl
GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
8344 5c55ff99 Blue Swirl
GEN_HANDLER(cmpl, 0x1F, 0x00, 0x01, 0x00400000, PPC_INTEGER),
8345 5c55ff99 Blue Swirl
GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
8346 5c55ff99 Blue Swirl
GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL),
8347 5c55ff99 Blue Swirl
GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8348 5c55ff99 Blue Swirl
GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8349 5c55ff99 Blue Swirl
GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8350 5c55ff99 Blue Swirl
GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8351 5c55ff99 Blue Swirl
GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER),
8352 5c55ff99 Blue Swirl
GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER),
8353 5c55ff99 Blue Swirl
GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER),
8354 5c55ff99 Blue Swirl
GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER),
8355 5c55ff99 Blue Swirl
GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8356 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8357 5c55ff99 Blue Swirl
GEN_HANDLER(mulld, 0x1F, 0x09, 0x07, 0x00000000, PPC_64B),
8358 5c55ff99 Blue Swirl
#endif
8359 5c55ff99 Blue Swirl
GEN_HANDLER(neg, 0x1F, 0x08, 0x03, 0x0000F800, PPC_INTEGER),
8360 5c55ff99 Blue Swirl
GEN_HANDLER(nego, 0x1F, 0x08, 0x13, 0x0000F800, PPC_INTEGER),
8361 5c55ff99 Blue Swirl
GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8362 5c55ff99 Blue Swirl
GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8363 5c55ff99 Blue Swirl
GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8364 5c55ff99 Blue Swirl
GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER),
8365 5c55ff99 Blue Swirl
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER),
8366 5c55ff99 Blue Swirl
GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER),
8367 5c55ff99 Blue Swirl
GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8368 5c55ff99 Blue Swirl
GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8369 5c55ff99 Blue Swirl
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8370 5c55ff99 Blue Swirl
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8371 5c55ff99 Blue Swirl
GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB),
8372 eaabeef2 David Gibson
GEN_HANDLER(popcntw, 0x1F, 0x1A, 0x0b, 0x0000F801, PPC_POPCNTWD),
8373 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8374 eaabeef2 David Gibson
GEN_HANDLER(popcntd, 0x1F, 0x1A, 0x0F, 0x0000F801, PPC_POPCNTWD),
8375 5c55ff99 Blue Swirl
GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B),
8376 5c55ff99 Blue Swirl
#endif
8377 5c55ff99 Blue Swirl
GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8378 5c55ff99 Blue Swirl
GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8379 5c55ff99 Blue Swirl
GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8380 5c55ff99 Blue Swirl
GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER),
8381 5c55ff99 Blue Swirl
GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER),
8382 5c55ff99 Blue Swirl
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER),
8383 5c55ff99 Blue Swirl
GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER),
8384 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8385 5c55ff99 Blue Swirl
GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B),
8386 5c55ff99 Blue Swirl
GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B),
8387 5c55ff99 Blue Swirl
GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B),
8388 5c55ff99 Blue Swirl
GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B),
8389 5c55ff99 Blue Swirl
GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B),
8390 5c55ff99 Blue Swirl
#endif
8391 5c55ff99 Blue Swirl
GEN_HANDLER(frsqrtes, 0x3B, 0x1A, 0xFF, 0x001F07C0, PPC_FLOAT_FRSQRTES),
8392 5c55ff99 Blue Swirl
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
8393 5c55ff99 Blue Swirl
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
8394 5c55ff99 Blue Swirl
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT),
8395 5c55ff99 Blue Swirl
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT),
8396 5c55ff99 Blue Swirl
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT),
8397 5c55ff99 Blue Swirl
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT),
8398 5c55ff99 Blue Swirl
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT),
8399 5c55ff99 Blue Swirl
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT),
8400 5c55ff99 Blue Swirl
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT),
8401 5c55ff99 Blue Swirl
GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00010000, PPC_FLOAT),
8402 5c55ff99 Blue Swirl
GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT),
8403 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8404 5c55ff99 Blue Swirl
GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B),
8405 5c55ff99 Blue Swirl
GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX),
8406 5c55ff99 Blue Swirl
GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B),
8407 5c55ff99 Blue Swirl
#endif
8408 5c55ff99 Blue Swirl
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8409 5c55ff99 Blue Swirl
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
8410 5c55ff99 Blue Swirl
GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING),
8411 5c55ff99 Blue Swirl
GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING),
8412 5c55ff99 Blue Swirl
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING),
8413 5c55ff99 Blue Swirl
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING),
8414 5c55ff99 Blue Swirl
GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO),
8415 5c55ff99 Blue Swirl
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
8416 f844c817 Alexander Graf
GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000000, PPC_RES),
8417 5c55ff99 Blue Swirl
GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
8418 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8419 f844c817 Alexander Graf
GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000000, PPC_64B),
8420 5c55ff99 Blue Swirl
GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B),
8421 5c55ff99 Blue Swirl
#endif
8422 5c55ff99 Blue Swirl
GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC),
8423 5c55ff99 Blue Swirl
GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT),
8424 5c55ff99 Blue Swirl
GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
8425 5c55ff99 Blue Swirl
GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
8426 5c55ff99 Blue Swirl
GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW),
8427 5c55ff99 Blue Swirl
GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW),
8428 5c55ff99 Blue Swirl
GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
8429 5c55ff99 Blue Swirl
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
8430 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8431 5c55ff99 Blue Swirl
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
8432 5c55ff99 Blue Swirl
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
8433 5c55ff99 Blue Swirl
#endif
8434 5c55ff99 Blue Swirl
GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW),
8435 5c55ff99 Blue Swirl
GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW),
8436 5c55ff99 Blue Swirl
GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
8437 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8438 5c55ff99 Blue Swirl
GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B),
8439 5c55ff99 Blue Swirl
GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B),
8440 5c55ff99 Blue Swirl
#endif
8441 5c55ff99 Blue Swirl
GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC),
8442 5c55ff99 Blue Swirl
GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC),
8443 5c55ff99 Blue Swirl
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC),
8444 5c55ff99 Blue Swirl
GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC),
8445 5c55ff99 Blue Swirl
GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB),
8446 5c55ff99 Blue Swirl
GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC),
8447 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8448 5c55ff99 Blue Swirl
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B),
8449 5c55ff99 Blue Swirl
#endif
8450 5c55ff99 Blue Swirl
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC),
8451 5c55ff99 Blue Swirl
GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC),
8452 5c55ff99 Blue Swirl
GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE),
8453 5c55ff99 Blue Swirl
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
8454 5c55ff99 Blue Swirl
GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
8455 5c55ff99 Blue Swirl
GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE),
8456 5c55ff99 Blue Swirl
GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE),
8457 5c55ff99 Blue Swirl
GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ),
8458 5c55ff99 Blue Swirl
GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT),
8459 5c55ff99 Blue Swirl
GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC),
8460 5c55ff99 Blue Swirl
GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x02000001, PPC_ALTIVEC),
8461 5c55ff99 Blue Swirl
GEN_HANDLER(dss, 0x1F, 0x16, 0x19, 0x019FF801, PPC_ALTIVEC),
8462 5c55ff99 Blue Swirl
GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI),
8463 5c55ff99 Blue Swirl
GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA),
8464 5c55ff99 Blue Swirl
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT),
8465 5c55ff99 Blue Swirl
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT),
8466 5c55ff99 Blue Swirl
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT),
8467 5c55ff99 Blue Swirl
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT),
8468 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8469 5c55ff99 Blue Swirl
GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B),
8470 5c55ff99 Blue Swirl
GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
8471 5c55ff99 Blue Swirl
             PPC_SEGMENT_64B),
8472 5c55ff99 Blue Swirl
GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B),
8473 5c55ff99 Blue Swirl
GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
8474 5c55ff99 Blue Swirl
             PPC_SEGMENT_64B),
8475 efdef95f David Gibson
GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x001F0001, PPC_SEGMENT_64B),
8476 efdef95f David Gibson
GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B),
8477 efdef95f David Gibson
GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001, PPC_SEGMENT_64B),
8478 5c55ff99 Blue Swirl
#endif
8479 5c55ff99 Blue Swirl
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
8480 5c55ff99 Blue Swirl
GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x03FF0001, PPC_MEM_TLBIE),
8481 5c55ff99 Blue Swirl
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE),
8482 5c55ff99 Blue Swirl
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC),
8483 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8484 5c55ff99 Blue Swirl
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI),
8485 5c55ff99 Blue Swirl
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI),
8486 5c55ff99 Blue Swirl
#endif
8487 5c55ff99 Blue Swirl
GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN),
8488 5c55ff99 Blue Swirl
GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN),
8489 5c55ff99 Blue Swirl
GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR),
8490 5c55ff99 Blue Swirl
GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR),
8491 5c55ff99 Blue Swirl
GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR),
8492 5c55ff99 Blue Swirl
GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR),
8493 5c55ff99 Blue Swirl
GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR),
8494 5c55ff99 Blue Swirl
GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR),
8495 5c55ff99 Blue Swirl
GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR),
8496 5c55ff99 Blue Swirl
GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR),
8497 5c55ff99 Blue Swirl
GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR),
8498 5c55ff99 Blue Swirl
GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
8499 5c55ff99 Blue Swirl
GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR),
8500 5c55ff99 Blue Swirl
GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR),
8501 5c55ff99 Blue Swirl
GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR),
8502 5c55ff99 Blue Swirl
GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR),
8503 5c55ff99 Blue Swirl
GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR),
8504 5c55ff99 Blue Swirl
GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR),
8505 5c55ff99 Blue Swirl
GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR),
8506 5c55ff99 Blue Swirl
GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
8507 5c55ff99 Blue Swirl
GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR),
8508 5c55ff99 Blue Swirl
GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR),
8509 5c55ff99 Blue Swirl
GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR),
8510 5c55ff99 Blue Swirl
GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR),
8511 5c55ff99 Blue Swirl
GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR),
8512 5c55ff99 Blue Swirl
GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR),
8513 5c55ff99 Blue Swirl
GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR),
8514 5c55ff99 Blue Swirl
GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR),
8515 5c55ff99 Blue Swirl
GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR),
8516 5c55ff99 Blue Swirl
GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR),
8517 5c55ff99 Blue Swirl
GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR),
8518 5c55ff99 Blue Swirl
GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR),
8519 5c55ff99 Blue Swirl
GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR),
8520 5c55ff99 Blue Swirl
GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR),
8521 5c55ff99 Blue Swirl
GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR),
8522 5c55ff99 Blue Swirl
GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR),
8523 5c55ff99 Blue Swirl
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC),
8524 5c55ff99 Blue Swirl
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC),
8525 5c55ff99 Blue Swirl
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC),
8526 5c55ff99 Blue Swirl
GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB),
8527 5c55ff99 Blue Swirl
GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB),
8528 5c55ff99 Blue Swirl
GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB),
8529 5c55ff99 Blue Swirl
GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB),
8530 5c55ff99 Blue Swirl
GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER),
8531 5c55ff99 Blue Swirl
GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER),
8532 5c55ff99 Blue Swirl
GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER),
8533 5c55ff99 Blue Swirl
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER),
8534 5c55ff99 Blue Swirl
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER),
8535 5c55ff99 Blue Swirl
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER),
8536 5c55ff99 Blue Swirl
GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8537 5c55ff99 Blue Swirl
GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8538 5c55ff99 Blue Swirl
GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2),
8539 5c55ff99 Blue Swirl
GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2),
8540 5c55ff99 Blue Swirl
GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8541 5c55ff99 Blue Swirl
GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
8542 5c55ff99 Blue Swirl
GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2),
8543 5c55ff99 Blue Swirl
GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2),
8544 5c55ff99 Blue Swirl
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI),
8545 5c55ff99 Blue Swirl
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA),
8546 5c55ff99 Blue Swirl
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR),
8547 5c55ff99 Blue Swirl
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR),
8548 5c55ff99 Blue Swirl
GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX),
8549 5c55ff99 Blue Swirl
GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX),
8550 5c55ff99 Blue Swirl
GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX),
8551 5c55ff99 Blue Swirl
GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX),
8552 5c55ff99 Blue Swirl
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON),
8553 5c55ff99 Blue Swirl
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON),
8554 5c55ff99 Blue Swirl
GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT),
8555 5c55ff99 Blue Swirl
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON),
8556 5c55ff99 Blue Swirl
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON),
8557 5c55ff99 Blue Swirl
GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP),
8558 01662f3e Alexander Graf
GEN_HANDLER_E(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE, PPC2_BOOKE206),
8559 5c55ff99 Blue Swirl
GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI),
8560 5c55ff99 Blue Swirl
GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI),
8561 5c55ff99 Blue Swirl
GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB),
8562 5c55ff99 Blue Swirl
GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB),
8563 5c55ff99 Blue Swirl
GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB),
8564 5c55ff99 Blue Swirl
GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE),
8565 5c55ff99 Blue Swirl
GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE),
8566 5c55ff99 Blue Swirl
GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE),
8567 01662f3e Alexander Graf
GEN_HANDLER2_E(tlbre_booke206, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001,
8568 01662f3e Alexander Graf
               PPC_NONE, PPC2_BOOKE206),
8569 01662f3e Alexander Graf
GEN_HANDLER2_E(tlbsx_booke206, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000,
8570 01662f3e Alexander Graf
               PPC_NONE, PPC2_BOOKE206),
8571 01662f3e Alexander Graf
GEN_HANDLER2_E(tlbwe_booke206, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001,
8572 01662f3e Alexander Graf
               PPC_NONE, PPC2_BOOKE206),
8573 01662f3e Alexander Graf
GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001,
8574 01662f3e Alexander Graf
               PPC_NONE, PPC2_BOOKE206),
8575 5c55ff99 Blue Swirl
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE),
8576 fbe73008 Baojun Wang
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE),
8577 5c55ff99 Blue Swirl
GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC),
8578 01662f3e Alexander Graf
GEN_HANDLER_E(mbar, 0x1F, 0x16, 0x1a, 0x001FF801,
8579 01662f3e Alexander Graf
              PPC_BOOKE, PPC2_BOOKE206),
8580 01662f3e Alexander Graf
GEN_HANDLER_E(msync, 0x1F, 0x16, 0x12, 0x03FFF801,
8581 01662f3e Alexander Graf
              PPC_BOOKE, PPC2_BOOKE206),
8582 01662f3e Alexander Graf
GEN_HANDLER2_E(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001,
8583 01662f3e Alexander Graf
               PPC_BOOKE, PPC2_BOOKE206),
8584 5c55ff99 Blue Swirl
GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC),
8585 5c55ff99 Blue Swirl
GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC),
8586 5c55ff99 Blue Swirl
GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC),
8587 5c55ff99 Blue Swirl
GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC),
8588 5c55ff99 Blue Swirl
GEN_HANDLER(vsldoi, 0x04, 0x16, 0xFF, 0x00000400, PPC_ALTIVEC),
8589 5c55ff99 Blue Swirl
GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC),
8590 5c55ff99 Blue Swirl
GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE),
8591 5c55ff99 Blue Swirl
GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE),
8592 5c55ff99 Blue Swirl
GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE),
8593 5c55ff99 Blue Swirl
GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE),
8594 5c55ff99 Blue Swirl
8595 5c55ff99 Blue Swirl
#undef GEN_INT_ARITH_ADD
8596 5c55ff99 Blue Swirl
#undef GEN_INT_ARITH_ADD_CONST
8597 5c55ff99 Blue Swirl
#define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
8598 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x00000000, PPC_INTEGER),
8599 5c55ff99 Blue Swirl
#define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
8600 5c55ff99 Blue Swirl
                                add_ca, compute_ca, compute_ov)               \
8601 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x0000F800, PPC_INTEGER),
8602 5c55ff99 Blue Swirl
GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
8603 5c55ff99 Blue Swirl
GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
8604 5c55ff99 Blue Swirl
GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
8605 5c55ff99 Blue Swirl
GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
8606 5c55ff99 Blue Swirl
GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
8607 5c55ff99 Blue Swirl
GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
8608 5c55ff99 Blue Swirl
GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
8609 5c55ff99 Blue Swirl
GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
8610 5c55ff99 Blue Swirl
GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
8611 5c55ff99 Blue Swirl
GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
8612 5c55ff99 Blue Swirl
8613 5c55ff99 Blue Swirl
#undef GEN_INT_ARITH_DIVW
8614 5c55ff99 Blue Swirl
#define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
8615 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x1F, 0x0B, opc3, 0x00000000, PPC_INTEGER)
8616 5c55ff99 Blue Swirl
GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0),
8617 5c55ff99 Blue Swirl
GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1),
8618 5c55ff99 Blue Swirl
GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0),
8619 5c55ff99 Blue Swirl
GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1),
8620 5c55ff99 Blue Swirl
8621 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8622 5c55ff99 Blue Swirl
#undef GEN_INT_ARITH_DIVD
8623 5c55ff99 Blue Swirl
#define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
8624 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
8625 5c55ff99 Blue Swirl
GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0),
8626 5c55ff99 Blue Swirl
GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1),
8627 5c55ff99 Blue Swirl
GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0),
8628 5c55ff99 Blue Swirl
GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1),
8629 5c55ff99 Blue Swirl
8630 5c55ff99 Blue Swirl
#undef GEN_INT_ARITH_MUL_HELPER
8631 5c55ff99 Blue Swirl
#define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
8632 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
8633 5c55ff99 Blue Swirl
GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00),
8634 5c55ff99 Blue Swirl
GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02),
8635 5c55ff99 Blue Swirl
GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17),
8636 5c55ff99 Blue Swirl
#endif
8637 5c55ff99 Blue Swirl
8638 5c55ff99 Blue Swirl
#undef GEN_INT_ARITH_SUBF
8639 5c55ff99 Blue Swirl
#undef GEN_INT_ARITH_SUBF_CONST
8640 5c55ff99 Blue Swirl
#define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
8641 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x00000000, PPC_INTEGER),
8642 5c55ff99 Blue Swirl
#define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
8643 5c55ff99 Blue Swirl
                                add_ca, compute_ca, compute_ov)               \
8644 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x0000F800, PPC_INTEGER),
8645 5c55ff99 Blue Swirl
GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
8646 5c55ff99 Blue Swirl
GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
8647 5c55ff99 Blue Swirl
GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
8648 5c55ff99 Blue Swirl
GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
8649 5c55ff99 Blue Swirl
GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
8650 5c55ff99 Blue Swirl
GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
8651 5c55ff99 Blue Swirl
GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
8652 5c55ff99 Blue Swirl
GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
8653 5c55ff99 Blue Swirl
GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
8654 5c55ff99 Blue Swirl
GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
8655 5c55ff99 Blue Swirl
8656 5c55ff99 Blue Swirl
#undef GEN_LOGICAL1
8657 5c55ff99 Blue Swirl
#undef GEN_LOGICAL2
8658 5c55ff99 Blue Swirl
#define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
8659 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type)
8660 5c55ff99 Blue Swirl
#define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
8661 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)
8662 5c55ff99 Blue Swirl
GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER),
8663 5c55ff99 Blue Swirl
GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER),
8664 5c55ff99 Blue Swirl
GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER),
8665 5c55ff99 Blue Swirl
GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER),
8666 5c55ff99 Blue Swirl
GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER),
8667 5c55ff99 Blue Swirl
GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER),
8668 5c55ff99 Blue Swirl
GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER),
8669 5c55ff99 Blue Swirl
GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER),
8670 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8671 5c55ff99 Blue Swirl
GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B),
8672 5c55ff99 Blue Swirl
#endif
8673 5c55ff99 Blue Swirl
8674 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8675 5c55ff99 Blue Swirl
#undef GEN_PPC64_R2
8676 5c55ff99 Blue Swirl
#undef GEN_PPC64_R4
8677 5c55ff99 Blue Swirl
#define GEN_PPC64_R2(name, opc1, opc2)                                        \
8678 5c55ff99 Blue Swirl
GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
8679 5c55ff99 Blue Swirl
GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
8680 5c55ff99 Blue Swirl
             PPC_64B)
8681 5c55ff99 Blue Swirl
#define GEN_PPC64_R4(name, opc1, opc2)                                        \
8682 5c55ff99 Blue Swirl
GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
8683 5c55ff99 Blue Swirl
GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
8684 5c55ff99 Blue Swirl
             PPC_64B),                                                        \
8685 5c55ff99 Blue Swirl
GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
8686 5c55ff99 Blue Swirl
             PPC_64B),                                                        \
8687 5c55ff99 Blue Swirl
GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
8688 5c55ff99 Blue Swirl
             PPC_64B)
8689 5c55ff99 Blue Swirl
GEN_PPC64_R4(rldicl, 0x1E, 0x00),
8690 5c55ff99 Blue Swirl
GEN_PPC64_R4(rldicr, 0x1E, 0x02),
8691 5c55ff99 Blue Swirl
GEN_PPC64_R4(rldic, 0x1E, 0x04),
8692 5c55ff99 Blue Swirl
GEN_PPC64_R2(rldcl, 0x1E, 0x08),
8693 5c55ff99 Blue Swirl
GEN_PPC64_R2(rldcr, 0x1E, 0x09),
8694 5c55ff99 Blue Swirl
GEN_PPC64_R4(rldimi, 0x1E, 0x06),
8695 5c55ff99 Blue Swirl
#endif
8696 5c55ff99 Blue Swirl
8697 5c55ff99 Blue Swirl
#undef _GEN_FLOAT_ACB
8698 5c55ff99 Blue Swirl
#undef GEN_FLOAT_ACB
8699 5c55ff99 Blue Swirl
#undef _GEN_FLOAT_AB
8700 5c55ff99 Blue Swirl
#undef GEN_FLOAT_AB
8701 5c55ff99 Blue Swirl
#undef _GEN_FLOAT_AC
8702 5c55ff99 Blue Swirl
#undef GEN_FLOAT_AC
8703 5c55ff99 Blue Swirl
#undef GEN_FLOAT_B
8704 5c55ff99 Blue Swirl
#undef GEN_FLOAT_BS
8705 5c55ff99 Blue Swirl
#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
8706 5c55ff99 Blue Swirl
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)
8707 5c55ff99 Blue Swirl
#define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
8708 5c55ff99 Blue Swirl
_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type),                     \
8709 5c55ff99 Blue Swirl
_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type)
8710 5c55ff99 Blue Swirl
#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
8711 5c55ff99 Blue Swirl
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
8712 5c55ff99 Blue Swirl
#define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
8713 5c55ff99 Blue Swirl
_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type),               \
8714 5c55ff99 Blue Swirl
_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
8715 5c55ff99 Blue Swirl
#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
8716 5c55ff99 Blue Swirl
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
8717 5c55ff99 Blue Swirl
#define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
8718 5c55ff99 Blue Swirl
_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type),               \
8719 5c55ff99 Blue Swirl
_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
8720 5c55ff99 Blue Swirl
#define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
8721 5c55ff99 Blue Swirl
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)
8722 5c55ff99 Blue Swirl
#define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
8723 5c55ff99 Blue Swirl
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)
8724 5c55ff99 Blue Swirl
8725 5c55ff99 Blue Swirl
GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT),
8726 5c55ff99 Blue Swirl
GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT),
8727 5c55ff99 Blue Swirl
GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT),
8728 5c55ff99 Blue Swirl
GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT),
8729 5c55ff99 Blue Swirl
GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES),
8730 5c55ff99 Blue Swirl
GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE),
8731 5c55ff99 Blue Swirl
_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL),
8732 5c55ff99 Blue Swirl
GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT),
8733 5c55ff99 Blue Swirl
GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT),
8734 5c55ff99 Blue Swirl
GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT),
8735 5c55ff99 Blue Swirl
GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT),
8736 5c55ff99 Blue Swirl
GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT),
8737 5c55ff99 Blue Swirl
GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT),
8738 5c55ff99 Blue Swirl
GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT),
8739 5c55ff99 Blue Swirl
GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT),
8740 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8741 5c55ff99 Blue Swirl
GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B),
8742 5c55ff99 Blue Swirl
GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B),
8743 5c55ff99 Blue Swirl
GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B),
8744 5c55ff99 Blue Swirl
#endif
8745 5c55ff99 Blue Swirl
GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT),
8746 5c55ff99 Blue Swirl
GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT),
8747 5c55ff99 Blue Swirl
GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT),
8748 5c55ff99 Blue Swirl
GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT),
8749 5c55ff99 Blue Swirl
GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT),
8750 5c55ff99 Blue Swirl
GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT),
8751 5c55ff99 Blue Swirl
GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT),
8752 5c55ff99 Blue Swirl
8753 5c55ff99 Blue Swirl
#undef GEN_LD
8754 5c55ff99 Blue Swirl
#undef GEN_LDU
8755 5c55ff99 Blue Swirl
#undef GEN_LDUX
8756 5c55ff99 Blue Swirl
#undef GEN_LDX
8757 5c55ff99 Blue Swirl
#undef GEN_LDS
8758 5c55ff99 Blue Swirl
#define GEN_LD(name, ldop, opc, type)                                         \
8759 5c55ff99 Blue Swirl
GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
8760 5c55ff99 Blue Swirl
#define GEN_LDU(name, ldop, opc, type)                                        \
8761 5c55ff99 Blue Swirl
GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
8762 5c55ff99 Blue Swirl
#define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
8763 5c55ff99 Blue Swirl
GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
8764 5c55ff99 Blue Swirl
#define GEN_LDX(name, ldop, opc2, opc3, type)                                 \
8765 5c55ff99 Blue Swirl
GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
8766 5c55ff99 Blue Swirl
#define GEN_LDS(name, ldop, op, type)                                         \
8767 5c55ff99 Blue Swirl
GEN_LD(name, ldop, op | 0x20, type)                                           \
8768 5c55ff99 Blue Swirl
GEN_LDU(name, ldop, op | 0x21, type)                                          \
8769 5c55ff99 Blue Swirl
GEN_LDUX(name, ldop, 0x17, op | 0x01, type)                                   \
8770 5c55ff99 Blue Swirl
GEN_LDX(name, ldop, 0x17, op | 0x00, type)
8771 5c55ff99 Blue Swirl
8772 5c55ff99 Blue Swirl
GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER)
8773 5c55ff99 Blue Swirl
GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER)
8774 5c55ff99 Blue Swirl
GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER)
8775 5c55ff99 Blue Swirl
GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER)
8776 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8777 5c55ff99 Blue Swirl
GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B)
8778 5c55ff99 Blue Swirl
GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B)
8779 5c55ff99 Blue Swirl
GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B)
8780 5c55ff99 Blue Swirl
GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B)
8781 5c55ff99 Blue Swirl
#endif
8782 5c55ff99 Blue Swirl
GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
8783 5c55ff99 Blue Swirl
GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
8784 5c55ff99 Blue Swirl
8785 5c55ff99 Blue Swirl
#undef GEN_ST
8786 5c55ff99 Blue Swirl
#undef GEN_STU
8787 5c55ff99 Blue Swirl
#undef GEN_STUX
8788 5c55ff99 Blue Swirl
#undef GEN_STX
8789 5c55ff99 Blue Swirl
#undef GEN_STS
8790 5c55ff99 Blue Swirl
#define GEN_ST(name, stop, opc, type)                                         \
8791 5c55ff99 Blue Swirl
GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
8792 5c55ff99 Blue Swirl
#define GEN_STU(name, stop, opc, type)                                        \
8793 5c55ff99 Blue Swirl
GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type),
8794 5c55ff99 Blue Swirl
#define GEN_STUX(name, stop, opc2, opc3, type)                                \
8795 5c55ff99 Blue Swirl
GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
8796 5c55ff99 Blue Swirl
#define GEN_STX(name, stop, opc2, opc3, type)                                 \
8797 5c55ff99 Blue Swirl
GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
8798 5c55ff99 Blue Swirl
#define GEN_STS(name, stop, op, type)                                         \
8799 5c55ff99 Blue Swirl
GEN_ST(name, stop, op | 0x20, type)                                           \
8800 5c55ff99 Blue Swirl
GEN_STU(name, stop, op | 0x21, type)                                          \
8801 5c55ff99 Blue Swirl
GEN_STUX(name, stop, 0x17, op | 0x01, type)                                   \
8802 5c55ff99 Blue Swirl
GEN_STX(name, stop, 0x17, op | 0x00, type)
8803 5c55ff99 Blue Swirl
8804 5c55ff99 Blue Swirl
GEN_STS(stb, st8, 0x06, PPC_INTEGER)
8805 5c55ff99 Blue Swirl
GEN_STS(sth, st16, 0x0C, PPC_INTEGER)
8806 5c55ff99 Blue Swirl
GEN_STS(stw, st32, 0x04, PPC_INTEGER)
8807 5c55ff99 Blue Swirl
#if defined(TARGET_PPC64)
8808 5c55ff99 Blue Swirl
GEN_STUX(std, st64, 0x15, 0x05, PPC_64B)
8809 5c55ff99 Blue Swirl
GEN_STX(std, st64, 0x15, 0x04, PPC_64B)
8810 5c55ff99 Blue Swirl
#endif
8811 5c55ff99 Blue Swirl
GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
8812 5c55ff99 Blue Swirl
GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
8813 5c55ff99 Blue Swirl
8814 5c55ff99 Blue Swirl
#undef GEN_LDF
8815 5c55ff99 Blue Swirl
#undef GEN_LDUF
8816 5c55ff99 Blue Swirl
#undef GEN_LDUXF
8817 5c55ff99 Blue Swirl
#undef GEN_LDXF
8818 5c55ff99 Blue Swirl
#undef GEN_LDFS
8819 5c55ff99 Blue Swirl
#define GEN_LDF(name, ldop, opc, type)                                        \
8820 5c55ff99 Blue Swirl
GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
8821 5c55ff99 Blue Swirl
#define GEN_LDUF(name, ldop, opc, type)                                       \
8822 5c55ff99 Blue Swirl
GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
8823 5c55ff99 Blue Swirl
#define GEN_LDUXF(name, ldop, opc, type)                                      \
8824 5c55ff99 Blue Swirl
GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
8825 5c55ff99 Blue Swirl
#define GEN_LDXF(name, ldop, opc2, opc3, type)                                \
8826 5c55ff99 Blue Swirl
GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
8827 5c55ff99 Blue Swirl
#define GEN_LDFS(name, ldop, op, type)                                        \
8828 5c55ff99 Blue Swirl
GEN_LDF(name, ldop, op | 0x20, type)                                          \
8829 5c55ff99 Blue Swirl
GEN_LDUF(name, ldop, op | 0x21, type)                                         \
8830 5c55ff99 Blue Swirl
GEN_LDUXF(name, ldop, op | 0x01, type)                                        \
8831 5c55ff99 Blue Swirl
GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
8832 5c55ff99 Blue Swirl
8833 5c55ff99 Blue Swirl
GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT)
8834 5c55ff99 Blue Swirl
GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT)
8835 5c55ff99 Blue Swirl
8836 5c55ff99 Blue Swirl
#undef GEN_STF
8837 5c55ff99 Blue Swirl
#undef GEN_STUF
8838 5c55ff99 Blue Swirl
#undef GEN_STUXF
8839 5c55ff99 Blue Swirl
#undef GEN_STXF
8840 5c55ff99 Blue Swirl
#undef GEN_STFS
8841 5c55ff99 Blue Swirl
#define GEN_STF(name, stop, opc, type)                                        \
8842 5c55ff99 Blue Swirl
GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
8843 5c55ff99 Blue Swirl
#define GEN_STUF(name, stop, opc, type)                                       \
8844 5c55ff99 Blue Swirl
GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
8845 5c55ff99 Blue Swirl
#define GEN_STUXF(name, stop, opc, type)                                      \
8846 5c55ff99 Blue Swirl
GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
8847 5c55ff99 Blue Swirl
#define GEN_STXF(name, stop, opc2, opc3, type)                                \
8848 5c55ff99 Blue Swirl
GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
8849 5c55ff99 Blue Swirl
#define GEN_STFS(name, stop, op, type)                                        \
8850 5c55ff99 Blue Swirl
GEN_STF(name, stop, op | 0x20, type)                                          \
8851 5c55ff99 Blue Swirl
GEN_STUF(name, stop, op | 0x21, type)                                         \
8852 5c55ff99 Blue Swirl
GEN_STUXF(name, stop, op | 0x01, type)                                        \
8853 5c55ff99 Blue Swirl
GEN_STXF(name, stop, 0x17, op | 0x00, type)
8854 5c55ff99 Blue Swirl
8855 5c55ff99 Blue Swirl
GEN_STFS(stfd, st64, 0x16, PPC_FLOAT)
8856 5c55ff99 Blue Swirl
GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT)
8857 5c55ff99 Blue Swirl
GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX)
8858 5c55ff99 Blue Swirl
8859 5c55ff99 Blue Swirl
#undef GEN_CRLOGIC
8860 5c55ff99 Blue Swirl
#define GEN_CRLOGIC(name, tcg_op, opc)                                        \
8861 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)
8862 5c55ff99 Blue Swirl
GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08),
8863 5c55ff99 Blue Swirl
GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04),
8864 5c55ff99 Blue Swirl
GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09),
8865 5c55ff99 Blue Swirl
GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07),
8866 5c55ff99 Blue Swirl
GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01),
8867 5c55ff99 Blue Swirl
GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E),
8868 5c55ff99 Blue Swirl
GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D),
8869 5c55ff99 Blue Swirl
GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06),
8870 5c55ff99 Blue Swirl
8871 5c55ff99 Blue Swirl
#undef GEN_MAC_HANDLER
8872 5c55ff99 Blue Swirl
#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
8873 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)
8874 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(macchw, 0x0C, 0x05),
8875 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(macchwo, 0x0C, 0x15),
8876 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(macchws, 0x0C, 0x07),
8877 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(macchwso, 0x0C, 0x17),
8878 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06),
8879 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16),
8880 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(macchwu, 0x0C, 0x04),
8881 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14),
8882 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(machhw, 0x0C, 0x01),
8883 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(machhwo, 0x0C, 0x11),
8884 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(machhws, 0x0C, 0x03),
8885 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(machhwso, 0x0C, 0x13),
8886 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02),
8887 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12),
8888 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(machhwu, 0x0C, 0x00),
8889 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10),
8890 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D),
8891 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D),
8892 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F),
8893 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F),
8894 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C),
8895 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C),
8896 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E),
8897 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E),
8898 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05),
8899 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15),
8900 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07),
8901 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17),
8902 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01),
8903 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11),
8904 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03),
8905 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13),
8906 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D),
8907 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D),
8908 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F),
8909 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F),
8910 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(mulchw, 0x08, 0x05),
8911 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(mulchwu, 0x08, 0x04),
8912 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(mulhhw, 0x08, 0x01),
8913 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00),
8914 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(mullhw, 0x08, 0x0D),
8915 5c55ff99 Blue Swirl
GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C),
8916 5c55ff99 Blue Swirl
8917 5c55ff99 Blue Swirl
#undef GEN_VR_LDX
8918 5c55ff99 Blue Swirl
#undef GEN_VR_STX
8919 5c55ff99 Blue Swirl
#undef GEN_VR_LVE
8920 5c55ff99 Blue Swirl
#undef GEN_VR_STVE
8921 5c55ff99 Blue Swirl
#define GEN_VR_LDX(name, opc2, opc3)                                          \
8922 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
8923 5c55ff99 Blue Swirl
#define GEN_VR_STX(name, opc2, opc3)                                          \
8924 5c55ff99 Blue Swirl
GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
8925 5c55ff99 Blue Swirl
#define GEN_VR_LVE(name, opc2, opc3)                                    \
8926 5c55ff99 Blue Swirl
    GEN_HANDLER(lve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
8927 5c55ff99 Blue Swirl
#define GEN_VR_STVE(name, opc2, opc3)                                   \
8928 5c55ff99 Blue Swirl
    GEN_HANDLER(stve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
8929 5c55ff99 Blue Swirl
GEN_VR_LDX(lvx, 0x07, 0x03),
8930 5c55ff99 Blue Swirl
GEN_VR_LDX(lvxl, 0x07, 0x0B),
8931 5c55ff99 Blue Swirl
GEN_VR_LVE(bx, 0x07, 0x00),
8932 5c55ff99 Blue Swirl
GEN_VR_LVE(hx, 0x07, 0x01),
8933 5c55ff99 Blue Swirl
GEN_VR_LVE(wx, 0x07, 0x02),
8934 5c55ff99 Blue Swirl
GEN_VR_STX(svx, 0x07, 0x07),
8935 5c55ff99 Blue Swirl
GEN_VR_STX(svxl, 0x07, 0x0F),
8936 5c55ff99 Blue Swirl
GEN_VR_STVE(bx, 0x07, 0x04),
8937 5c55ff99 Blue Swirl
GEN_VR_STVE(hx, 0x07, 0x05),
8938 5c55ff99 Blue Swirl
GEN_VR_STVE(wx, 0x07, 0x06),
8939 5c55ff99 Blue Swirl
8940 5c55ff99 Blue Swirl
#undef GEN_VX_LOGICAL
8941 5c55ff99 Blue Swirl
#define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)                        \
8942 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
8943 5c55ff99 Blue Swirl
GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16),
8944 5c55ff99 Blue Swirl
GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17),
8945 5c55ff99 Blue Swirl
GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18),
8946 5c55ff99 Blue Swirl
GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19),
8947 5c55ff99 Blue Swirl
GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20),
8948 5c55ff99 Blue Swirl
8949 5c55ff99 Blue Swirl
#undef GEN_VXFORM
8950 5c55ff99 Blue Swirl
#define GEN_VXFORM(name, opc2, opc3)                                    \
8951 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
8952 5c55ff99 Blue Swirl
GEN_VXFORM(vaddubm, 0, 0),
8953 5c55ff99 Blue Swirl
GEN_VXFORM(vadduhm, 0, 1),
8954 5c55ff99 Blue Swirl
GEN_VXFORM(vadduwm, 0, 2),
8955 5c55ff99 Blue Swirl
GEN_VXFORM(vsububm, 0, 16),
8956 5c55ff99 Blue Swirl
GEN_VXFORM(vsubuhm, 0, 17),
8957 5c55ff99 Blue Swirl
GEN_VXFORM(vsubuwm, 0, 18),
8958 5c55ff99 Blue Swirl
GEN_VXFORM(vmaxub, 1, 0),
8959 5c55ff99 Blue Swirl
GEN_VXFORM(vmaxuh, 1, 1),
8960 5c55ff99 Blue Swirl
GEN_VXFORM(vmaxuw, 1, 2),
8961 5c55ff99 Blue Swirl
GEN_VXFORM(vmaxsb, 1, 4),
8962 5c55ff99 Blue Swirl
GEN_VXFORM(vmaxsh, 1, 5),
8963 5c55ff99 Blue Swirl
GEN_VXFORM(vmaxsw, 1, 6),
8964 5c55ff99 Blue Swirl
GEN_VXFORM(vminub, 1, 8),
8965 5c55ff99 Blue Swirl
GEN_VXFORM(vminuh, 1, 9),
8966 5c55ff99 Blue Swirl
GEN_VXFORM(vminuw, 1, 10),
8967 5c55ff99 Blue Swirl
GEN_VXFORM(vminsb, 1, 12),
8968 5c55ff99 Blue Swirl
GEN_VXFORM(vminsh, 1, 13),
8969 5c55ff99 Blue Swirl
GEN_VXFORM(vminsw, 1, 14),
8970 5c55ff99 Blue Swirl
GEN_VXFORM(vavgub, 1, 16),
8971 5c55ff99 Blue Swirl
GEN_VXFORM(vavguh, 1, 17),
8972 5c55ff99 Blue Swirl
GEN_VXFORM(vavguw, 1, 18),
8973 5c55ff99 Blue Swirl
GEN_VXFORM(vavgsb, 1, 20),
8974 5c55ff99 Blue Swirl
GEN_VXFORM(vavgsh, 1, 21),
8975 5c55ff99 Blue Swirl
GEN_VXFORM(vavgsw, 1, 22),
8976 5c55ff99 Blue Swirl
GEN_VXFORM(vmrghb, 6, 0),
8977 5c55ff99 Blue Swirl
GEN_VXFORM(vmrghh, 6, 1),
8978 5c55ff99 Blue Swirl
GEN_VXFORM(vmrghw, 6, 2),
8979 5c55ff99 Blue Swirl
GEN_VXFORM(vmrglb, 6, 4),
8980 5c55ff99 Blue Swirl
GEN_VXFORM(vmrglh, 6, 5),
8981 5c55ff99 Blue Swirl
GEN_VXFORM(vmrglw, 6, 6),
8982 5c55ff99 Blue Swirl
GEN_VXFORM(vmuloub, 4, 0),
8983 5c55ff99 Blue Swirl
GEN_VXFORM(vmulouh, 4, 1),
8984 5c55ff99 Blue Swirl
GEN_VXFORM(vmulosb, 4, 4),
8985 5c55ff99 Blue Swirl
GEN_VXFORM(vmulosh, 4, 5),
8986 5c55ff99 Blue Swirl
GEN_VXFORM(vmuleub, 4, 8),
8987 5c55ff99 Blue Swirl
GEN_VXFORM(vmuleuh, 4, 9),
8988 5c55ff99 Blue Swirl
GEN_VXFORM(vmulesb, 4, 12),
8989 5c55ff99 Blue Swirl
GEN_VXFORM(vmulesh, 4, 13),
8990 5c55ff99 Blue Swirl
GEN_VXFORM(vslb, 2, 4),
8991 5c55ff99 Blue Swirl
GEN_VXFORM(vslh, 2, 5),
8992 5c55ff99 Blue Swirl
GEN_VXFORM(vslw, 2, 6),
8993 5c55ff99 Blue Swirl
GEN_VXFORM(vsrb, 2, 8),
8994 5c55ff99 Blue Swirl
GEN_VXFORM(vsrh, 2, 9),
8995 5c55ff99 Blue Swirl
GEN_VXFORM(vsrw, 2, 10),
8996 5c55ff99 Blue Swirl
GEN_VXFORM(vsrab, 2, 12),
8997 5c55ff99 Blue Swirl
GEN_VXFORM(vsrah, 2, 13),
8998 5c55ff99 Blue Swirl
GEN_VXFORM(vsraw, 2, 14),
8999 5c55ff99 Blue Swirl
GEN_VXFORM(vslo, 6, 16),
9000 5c55ff99 Blue Swirl
GEN_VXFORM(vsro, 6, 17),
9001 5c55ff99 Blue Swirl
GEN_VXFORM(vaddcuw, 0, 6),
9002 5c55ff99 Blue Swirl
GEN_VXFORM(vsubcuw, 0, 22),
9003 5c55ff99 Blue Swirl
GEN_VXFORM(vaddubs, 0, 8),
9004 5c55ff99 Blue Swirl
GEN_VXFORM(vadduhs, 0, 9),
9005 5c55ff99 Blue Swirl
GEN_VXFORM(vadduws, 0, 10),
9006 5c55ff99 Blue Swirl
GEN_VXFORM(vaddsbs, 0, 12),
9007 5c55ff99 Blue Swirl
GEN_VXFORM(vaddshs, 0, 13),
9008 5c55ff99 Blue Swirl
GEN_VXFORM(vaddsws, 0, 14),
9009 5c55ff99 Blue Swirl
GEN_VXFORM(vsububs, 0, 24),
9010 5c55ff99 Blue Swirl
GEN_VXFORM(vsubuhs, 0, 25),
9011 5c55ff99 Blue Swirl
GEN_VXFORM(vsubuws, 0, 26),
9012 5c55ff99 Blue Swirl
GEN_VXFORM(vsubsbs, 0, 28),
9013 5c55ff99 Blue Swirl
GEN_VXFORM(vsubshs, 0, 29),
9014 5c55ff99 Blue Swirl
GEN_VXFORM(vsubsws, 0, 30),
9015 5c55ff99 Blue Swirl
GEN_VXFORM(vrlb, 2, 0),
9016 5c55ff99 Blue Swirl
GEN_VXFORM(vrlh, 2, 1),
9017 5c55ff99 Blue Swirl
GEN_VXFORM(vrlw, 2, 2),
9018 5c55ff99 Blue Swirl
GEN_VXFORM(vsl, 2, 7),
9019 5c55ff99 Blue Swirl
GEN_VXFORM(vsr, 2, 11),
9020 5c55ff99 Blue Swirl
GEN_VXFORM(vpkuhum, 7, 0),
9021 5c55ff99 Blue Swirl
GEN_VXFORM(vpkuwum, 7, 1),
9022 5c55ff99 Blue Swirl
GEN_VXFORM(vpkuhus, 7, 2),
9023 5c55ff99 Blue Swirl
GEN_VXFORM(vpkuwus, 7, 3),
9024 5c55ff99 Blue Swirl
GEN_VXFORM(vpkshus, 7, 4),
9025 5c55ff99 Blue Swirl
GEN_VXFORM(vpkswus, 7, 5),
9026 5c55ff99 Blue Swirl
GEN_VXFORM(vpkshss, 7, 6),
9027 5c55ff99 Blue Swirl
GEN_VXFORM(vpkswss, 7, 7),
9028 5c55ff99 Blue Swirl
GEN_VXFORM(vpkpx, 7, 12),
9029 5c55ff99 Blue Swirl
GEN_VXFORM(vsum4ubs, 4, 24),
9030 5c55ff99 Blue Swirl
GEN_VXFORM(vsum4sbs, 4, 28),
9031 5c55ff99 Blue Swirl
GEN_VXFORM(vsum4shs, 4, 25),
9032 5c55ff99 Blue Swirl
GEN_VXFORM(vsum2sws, 4, 26),
9033 5c55ff99 Blue Swirl
GEN_VXFORM(vsumsws, 4, 30),
9034 5c55ff99 Blue Swirl
GEN_VXFORM(vaddfp, 5, 0),
9035 5c55ff99 Blue Swirl
GEN_VXFORM(vsubfp, 5, 1),
9036 5c55ff99 Blue Swirl
GEN_VXFORM(vmaxfp, 5, 16),
9037 5c55ff99 Blue Swirl
GEN_VXFORM(vminfp, 5, 17),
9038 5c55ff99 Blue Swirl
9039 5c55ff99 Blue Swirl
#undef GEN_VXRFORM1
9040 5c55ff99 Blue Swirl
#undef GEN_VXRFORM
9041 5c55ff99 Blue Swirl
#define GEN_VXRFORM1(opname, name, str, opc2, opc3)                     \
9042 5c55ff99 Blue Swirl
    GEN_HANDLER2(name, str, 0x4, opc2, opc3, 0x00000000, PPC_ALTIVEC),
9043 5c55ff99 Blue Swirl
#define GEN_VXRFORM(name, opc2, opc3)                                \
9044 5c55ff99 Blue Swirl
    GEN_VXRFORM1(name, name, #name, opc2, opc3)                      \
9045 5c55ff99 Blue Swirl
    GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
9046 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpequb, 3, 0)
9047 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpequh, 3, 1)
9048 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpequw, 3, 2)
9049 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpgtsb, 3, 12)
9050 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpgtsh, 3, 13)
9051 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpgtsw, 3, 14)
9052 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpgtub, 3, 8)
9053 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpgtuh, 3, 9)
9054 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpgtuw, 3, 10)
9055 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpeqfp, 3, 3)
9056 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpgefp, 3, 7)
9057 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpgtfp, 3, 11)
9058 5c55ff99 Blue Swirl
GEN_VXRFORM(vcmpbfp, 3, 15)
9059 5c55ff99 Blue Swirl
9060 5c55ff99 Blue Swirl
#undef GEN_VXFORM_SIMM
9061 5c55ff99 Blue Swirl
#define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
9062 5c55ff99 Blue Swirl
    GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
9063 5c55ff99 Blue Swirl
GEN_VXFORM_SIMM(vspltisb, 6, 12),
9064 5c55ff99 Blue Swirl
GEN_VXFORM_SIMM(vspltish, 6, 13),
9065 5c55ff99 Blue Swirl
GEN_VXFORM_SIMM(vspltisw, 6, 14),
9066 5c55ff99 Blue Swirl
9067 5c55ff99 Blue Swirl
#undef GEN_VXFORM_NOA
9068 5c55ff99 Blue Swirl
#define GEN_VXFORM_NOA(name, opc2, opc3)                                \
9069 5c55ff99 Blue Swirl
    GEN_HANDLER(name, 0x04, opc2, opc3, 0x001f0000, PPC_ALTIVEC)
9070 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vupkhsb, 7, 8),
9071 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vupkhsh, 7, 9),
9072 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vupklsb, 7, 10),
9073 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vupklsh, 7, 11),
9074 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vupkhpx, 7, 13),
9075 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vupklpx, 7, 15),
9076 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vrefp, 5, 4),
9077 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vrsqrtefp, 5, 5),
9078 0bffbc6c Aurelien Jarno
GEN_VXFORM_NOA(vexptefp, 5, 6),
9079 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vlogefp, 5, 7),
9080 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vrfim, 5, 8),
9081 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vrfin, 5, 9),
9082 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vrfip, 5, 10),
9083 5c55ff99 Blue Swirl
GEN_VXFORM_NOA(vrfiz, 5, 11),
9084 5c55ff99 Blue Swirl
9085 5c55ff99 Blue Swirl
#undef GEN_VXFORM_UIMM
9086 5c55ff99 Blue Swirl
#define GEN_VXFORM_UIMM(name, opc2, opc3)                               \
9087 5c55ff99 Blue Swirl
    GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
9088 5c55ff99 Blue Swirl
GEN_VXFORM_UIMM(vspltb, 6, 8),
9089 5c55ff99 Blue Swirl
GEN_VXFORM_UIMM(vsplth, 6, 9),
9090 5c55ff99 Blue Swirl
GEN_VXFORM_UIMM(vspltw, 6, 10),
9091 5c55ff99 Blue Swirl
GEN_VXFORM_UIMM(vcfux, 5, 12),
9092 5c55ff99 Blue Swirl
GEN_VXFORM_UIMM(vcfsx, 5, 13),
9093 5c55ff99 Blue Swirl
GEN_VXFORM_UIMM(vctuxs, 5, 14),
9094 5c55ff99 Blue Swirl
GEN_VXFORM_UIMM(vctsxs, 5, 15),
9095 5c55ff99 Blue Swirl
9096 5c55ff99 Blue Swirl
#undef GEN_VAFORM_PAIRED
9097 5c55ff99 Blue Swirl
#define GEN_VAFORM_PAIRED(name0, name1, opc2)                           \
9098 5c55ff99 Blue Swirl
    GEN_HANDLER(name0##_##name1, 0x04, opc2, 0xFF, 0x00000000, PPC_ALTIVEC)
9099 5c55ff99 Blue Swirl
GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16),
9100 5c55ff99 Blue Swirl
GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18),
9101 5c55ff99 Blue Swirl
GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19),
9102 5c55ff99 Blue Swirl
GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20),
9103 5c55ff99 Blue Swirl
GEN_VAFORM_PAIRED(vsel, vperm, 21),
9104 5c55ff99 Blue Swirl
GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23),
9105 5c55ff99 Blue Swirl
9106 5c55ff99 Blue Swirl
#undef GEN_SPE
9107 70560da7 Fabien Chouteau
#define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \
9108 70560da7 Fabien Chouteau
    GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE)
9109 70560da7 Fabien Chouteau
GEN_SPE(evaddw,      speundef,    0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9110 70560da7 Fabien Chouteau
GEN_SPE(evaddiw,     speundef,    0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9111 70560da7 Fabien Chouteau
GEN_SPE(evsubfw,     speundef,    0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9112 70560da7 Fabien Chouteau
GEN_SPE(evsubifw,    speundef,    0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9113 70560da7 Fabien Chouteau
GEN_SPE(evabs,       evneg,       0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
9114 70560da7 Fabien Chouteau
GEN_SPE(evextsb,     evextsh,     0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
9115 70560da7 Fabien Chouteau
GEN_SPE(evrndw,      evcntlzw,    0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
9116 70560da7 Fabien Chouteau
GEN_SPE(evcntlsw,    brinc,       0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE),
9117 70560da7 Fabien Chouteau
GEN_SPE(evmra,       speundef,    0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE),
9118 70560da7 Fabien Chouteau
GEN_SPE(speundef,    evand,       0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE),
9119 70560da7 Fabien Chouteau
GEN_SPE(evandc,      speundef,    0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9120 70560da7 Fabien Chouteau
GEN_SPE(evxor,       evor,        0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE),
9121 70560da7 Fabien Chouteau
GEN_SPE(evnor,       eveqv,       0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE),
9122 70560da7 Fabien Chouteau
GEN_SPE(evmwumi,     evmwsmi,     0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE),
9123 70560da7 Fabien Chouteau
GEN_SPE(evmwumia,    evmwsmia,    0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE),
9124 70560da7 Fabien Chouteau
GEN_SPE(evmwumiaa,   evmwsmiaa,   0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE),
9125 70560da7 Fabien Chouteau
GEN_SPE(speundef,    evorc,       0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE),
9126 70560da7 Fabien Chouteau
GEN_SPE(evnand,      speundef,    0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9127 70560da7 Fabien Chouteau
GEN_SPE(evsrwu,      evsrws,      0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE),
9128 70560da7 Fabien Chouteau
GEN_SPE(evsrwiu,     evsrwis,     0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE),
9129 70560da7 Fabien Chouteau
GEN_SPE(evslw,       speundef,    0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9130 70560da7 Fabien Chouteau
GEN_SPE(evslwi,      speundef,    0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
9131 70560da7 Fabien Chouteau
GEN_SPE(evrlw,       evsplati,    0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE),
9132 70560da7 Fabien Chouteau
GEN_SPE(evrlwi,      evsplatfi,   0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE),
9133 70560da7 Fabien Chouteau
GEN_SPE(evmergehi,   evmergelo,   0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE),
9134 70560da7 Fabien Chouteau
GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE),
9135 70560da7 Fabien Chouteau
GEN_SPE(evcmpgtu,    evcmpgts,    0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE),
9136 70560da7 Fabien Chouteau
GEN_SPE(evcmpltu,    evcmplts,    0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE),
9137 70560da7 Fabien Chouteau
GEN_SPE(evcmpeq,     speundef,    0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE),
9138 70560da7 Fabien Chouteau
9139 70560da7 Fabien Chouteau
GEN_SPE(evfsadd,     evfssub,     0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
9140 70560da7 Fabien Chouteau
GEN_SPE(evfsabs,     evfsnabs,    0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE),
9141 70560da7 Fabien Chouteau
GEN_SPE(evfsneg,     speundef,    0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE),
9142 70560da7 Fabien Chouteau
GEN_SPE(evfsmul,     evfsdiv,     0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
9143 70560da7 Fabien Chouteau
GEN_SPE(evfscmpgt,   evfscmplt,   0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
9144 70560da7 Fabien Chouteau
GEN_SPE(evfscmpeq,   speundef,    0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9145 70560da7 Fabien Chouteau
GEN_SPE(evfscfui,    evfscfsi,    0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9146 70560da7 Fabien Chouteau
GEN_SPE(evfscfuf,    evfscfsf,    0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9147 70560da7 Fabien Chouteau
GEN_SPE(evfsctui,    evfsctsi,    0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9148 70560da7 Fabien Chouteau
GEN_SPE(evfsctuf,    evfsctsf,    0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9149 70560da7 Fabien Chouteau
GEN_SPE(evfsctuiz,   speundef,    0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9150 70560da7 Fabien Chouteau
GEN_SPE(evfsctsiz,   speundef,    0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9151 70560da7 Fabien Chouteau
GEN_SPE(evfststgt,   evfststlt,   0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
9152 70560da7 Fabien Chouteau
GEN_SPE(evfststeq,   speundef,    0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9153 70560da7 Fabien Chouteau
9154 70560da7 Fabien Chouteau
GEN_SPE(efsadd,      efssub,      0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
9155 70560da7 Fabien Chouteau
GEN_SPE(efsabs,      efsnabs,     0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE),
9156 70560da7 Fabien Chouteau
GEN_SPE(efsneg,      speundef,    0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE),
9157 70560da7 Fabien Chouteau
GEN_SPE(efsmul,      efsdiv,      0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
9158 70560da7 Fabien Chouteau
GEN_SPE(efscmpgt,    efscmplt,    0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
9159 70560da7 Fabien Chouteau
GEN_SPE(efscmpeq,    efscfd,      0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE),
9160 70560da7 Fabien Chouteau
GEN_SPE(efscfui,     efscfsi,     0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9161 70560da7 Fabien Chouteau
GEN_SPE(efscfuf,     efscfsf,     0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9162 70560da7 Fabien Chouteau
GEN_SPE(efsctui,     efsctsi,     0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9163 70560da7 Fabien Chouteau
GEN_SPE(efsctuf,     efsctsf,     0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
9164 70560da7 Fabien Chouteau
GEN_SPE(efsctuiz,    speundef,    0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9165 70560da7 Fabien Chouteau
GEN_SPE(efsctsiz,    speundef,    0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9166 70560da7 Fabien Chouteau
GEN_SPE(efststgt,    efststlt,    0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
9167 70560da7 Fabien Chouteau
GEN_SPE(efststeq,    speundef,    0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
9168 70560da7 Fabien Chouteau
9169 70560da7 Fabien Chouteau
GEN_SPE(efdadd,      efdsub,      0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE),
9170 70560da7 Fabien Chouteau
GEN_SPE(efdcfuid,    efdcfsid,    0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
9171 70560da7 Fabien Chouteau
GEN_SPE(efdabs,      efdnabs,     0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE),
9172 70560da7 Fabien Chouteau
GEN_SPE(efdneg,      speundef,    0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE),
9173 70560da7 Fabien Chouteau
GEN_SPE(efdmul,      efddiv,      0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE),
9174 70560da7 Fabien Chouteau
GEN_SPE(efdctuidz,   efdctsidz,   0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
9175 70560da7 Fabien Chouteau
GEN_SPE(efdcmpgt,    efdcmplt,    0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE),
9176 70560da7 Fabien Chouteau
GEN_SPE(efdcmpeq,    efdcfs,      0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE),
9177 70560da7 Fabien Chouteau
GEN_SPE(efdcfui,     efdcfsi,     0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
9178 70560da7 Fabien Chouteau
GEN_SPE(efdcfuf,     efdcfsf,     0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
9179 70560da7 Fabien Chouteau
GEN_SPE(efdctui,     efdctsi,     0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
9180 70560da7 Fabien Chouteau
GEN_SPE(efdctuf,     efdctsf,     0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
9181 70560da7 Fabien Chouteau
GEN_SPE(efdctuiz,    speundef,    0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
9182 70560da7 Fabien Chouteau
GEN_SPE(efdctsiz,    speundef,    0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
9183 70560da7 Fabien Chouteau
GEN_SPE(efdtstgt,    efdtstlt,    0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE),
9184 70560da7 Fabien Chouteau
GEN_SPE(efdtsteq,    speundef,    0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
9185 5c55ff99 Blue Swirl
9186 5c55ff99 Blue Swirl
#undef GEN_SPEOP_LDST
9187 5c55ff99 Blue Swirl
#define GEN_SPEOP_LDST(name, opc2, sh)                                        \
9188 5c55ff99 Blue Swirl
GEN_HANDLER(name, 0x04, opc2, 0x0C, 0x00000000, PPC_SPE)
9189 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evldd, 0x00, 3),
9190 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evldw, 0x01, 3),
9191 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evldh, 0x02, 3),
9192 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evlhhesplat, 0x04, 1),
9193 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evlhhousplat, 0x06, 1),
9194 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evlhhossplat, 0x07, 1),
9195 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evlwhe, 0x08, 2),
9196 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evlwhou, 0x0A, 2),
9197 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evlwhos, 0x0B, 2),
9198 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2),
9199 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2),
9200 5c55ff99 Blue Swirl
9201 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evstdd, 0x10, 3),
9202 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evstdw, 0x11, 3),
9203 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evstdh, 0x12, 3),
9204 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evstwhe, 0x18, 2),
9205 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evstwho, 0x1A, 2),
9206 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evstwwe, 0x1C, 2),
9207 5c55ff99 Blue Swirl
GEN_SPEOP_LDST(evstwwo, 0x1E, 2),
9208 5c55ff99 Blue Swirl
};
9209 5c55ff99 Blue Swirl
9210 3fc6c082 bellard
#include "translate_init.c"
9211 0411a972 j_mayer
#include "helper_regs.h"
9212 79aceca5 bellard
9213 9a64fbe4 bellard
/*****************************************************************************/
9214 3fc6c082 bellard
/* Misc PowerPC helpers */
9215 9a78eead Stefan Weil
void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
9216 36081602 j_mayer
                     int flags)
9217 79aceca5 bellard
{
9218 3fc6c082 bellard
#define RGPL  4
9219 3fc6c082 bellard
#define RFPL  4
9220 3fc6c082 bellard
9221 79aceca5 bellard
    int i;
9222 79aceca5 bellard
9223 90e189ec Blue Swirl
    cpu_fprintf(f, "NIP " TARGET_FMT_lx "   LR " TARGET_FMT_lx " CTR "
9224 9a78eead Stefan Weil
                TARGET_FMT_lx " XER " TARGET_FMT_lx "\n",
9225 9a78eead Stefan Weil
                env->nip, env->lr, env->ctr, env->xer);
9226 90e189ec Blue Swirl
    cpu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx "  HF "
9227 90e189ec Blue Swirl
                TARGET_FMT_lx " idx %d\n", env->msr, env->spr[SPR_HID0],
9228 90e189ec Blue Swirl
                env->hflags, env->mmu_idx);
9229 d9bce9d9 j_mayer
#if !defined(NO_TIMER_DUMP)
9230 9a78eead Stefan Weil
    cpu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
9231 76a66253 j_mayer
#if !defined(CONFIG_USER_ONLY)
9232 9a78eead Stefan Weil
                " DECR %08" PRIu32
9233 76a66253 j_mayer
#endif
9234 76a66253 j_mayer
                "\n",
9235 077fc206 j_mayer
                cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
9236 76a66253 j_mayer
#if !defined(CONFIG_USER_ONLY)
9237 76a66253 j_mayer
                , cpu_ppc_load_decr(env)
9238 76a66253 j_mayer
#endif
9239 76a66253 j_mayer
                );
9240 077fc206 j_mayer
#endif
9241 76a66253 j_mayer
    for (i = 0; i < 32; i++) {
9242 3fc6c082 bellard
        if ((i & (RGPL - 1)) == 0)
9243 3fc6c082 bellard
            cpu_fprintf(f, "GPR%02d", i);
9244 b11ebf64 Blue Swirl
        cpu_fprintf(f, " %016" PRIx64, ppc_dump_gpr(env, i));
9245 3fc6c082 bellard
        if ((i & (RGPL - 1)) == (RGPL - 1))
9246 7fe48483 bellard
            cpu_fprintf(f, "\n");
9247 76a66253 j_mayer
    }
9248 3fc6c082 bellard
    cpu_fprintf(f, "CR ");
9249 76a66253 j_mayer
    for (i = 0; i < 8; i++)
9250 7fe48483 bellard
        cpu_fprintf(f, "%01x", env->crf[i]);
9251 7fe48483 bellard
    cpu_fprintf(f, "  [");
9252 76a66253 j_mayer
    for (i = 0; i < 8; i++) {
9253 76a66253 j_mayer
        char a = '-';
9254 76a66253 j_mayer
        if (env->crf[i] & 0x08)
9255 76a66253 j_mayer
            a = 'L';
9256 76a66253 j_mayer
        else if (env->crf[i] & 0x04)
9257 76a66253 j_mayer
            a = 'G';
9258 76a66253 j_mayer
        else if (env->crf[i] & 0x02)
9259 76a66253 j_mayer
            a = 'E';
9260 7fe48483 bellard
        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
9261 76a66253 j_mayer
    }
9262 90e189ec Blue Swirl
    cpu_fprintf(f, " ]             RES " TARGET_FMT_lx "\n",
9263 90e189ec Blue Swirl
                env->reserve_addr);
9264 3fc6c082 bellard
    for (i = 0; i < 32; i++) {
9265 3fc6c082 bellard
        if ((i & (RFPL - 1)) == 0)
9266 3fc6c082 bellard
            cpu_fprintf(f, "FPR%02d", i);
9267 26a76461 bellard
        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
9268 3fc6c082 bellard
        if ((i & (RFPL - 1)) == (RFPL - 1))
9269 7fe48483 bellard
            cpu_fprintf(f, "\n");
9270 79aceca5 bellard
    }
9271 7889270a aurel32
    cpu_fprintf(f, "FPSCR %08x\n", env->fpscr);
9272 f2e63a42 j_mayer
#if !defined(CONFIG_USER_ONLY)
9273 90dc8812 Scott Wood
    cpu_fprintf(f, " SRR0 " TARGET_FMT_lx "  SRR1 " TARGET_FMT_lx
9274 90dc8812 Scott Wood
                   "    PVR " TARGET_FMT_lx " VRSAVE " TARGET_FMT_lx "\n",
9275 90dc8812 Scott Wood
                env->spr[SPR_SRR0], env->spr[SPR_SRR1],
9276 90dc8812 Scott Wood
                env->spr[SPR_PVR], env->spr[SPR_VRSAVE]);
9277 90dc8812 Scott Wood
9278 90dc8812 Scott Wood
    cpu_fprintf(f, "SPRG0 " TARGET_FMT_lx " SPRG1 " TARGET_FMT_lx
9279 90dc8812 Scott Wood
                   "  SPRG2 " TARGET_FMT_lx "  SPRG3 " TARGET_FMT_lx "\n",
9280 90dc8812 Scott Wood
                env->spr[SPR_SPRG0], env->spr[SPR_SPRG1],
9281 90dc8812 Scott Wood
                env->spr[SPR_SPRG2], env->spr[SPR_SPRG3]);
9282 90dc8812 Scott Wood
9283 90dc8812 Scott Wood
    cpu_fprintf(f, "SPRG4 " TARGET_FMT_lx " SPRG5 " TARGET_FMT_lx
9284 90dc8812 Scott Wood
                   "  SPRG6 " TARGET_FMT_lx "  SPRG7 " TARGET_FMT_lx "\n",
9285 90dc8812 Scott Wood
                env->spr[SPR_SPRG4], env->spr[SPR_SPRG5],
9286 90dc8812 Scott Wood
                env->spr[SPR_SPRG6], env->spr[SPR_SPRG7]);
9287 90dc8812 Scott Wood
9288 90dc8812 Scott Wood
    if (env->excp_model == POWERPC_EXCP_BOOKE) {
9289 90dc8812 Scott Wood
        cpu_fprintf(f, "CSRR0 " TARGET_FMT_lx " CSRR1 " TARGET_FMT_lx
9290 90dc8812 Scott Wood
                       " MCSRR0 " TARGET_FMT_lx " MCSRR1 " TARGET_FMT_lx "\n",
9291 90dc8812 Scott Wood
                    env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
9292 90dc8812 Scott Wood
                    env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
9293 90dc8812 Scott Wood
9294 90dc8812 Scott Wood
        cpu_fprintf(f, "  TCR " TARGET_FMT_lx "   TSR " TARGET_FMT_lx
9295 90dc8812 Scott Wood
                       "    ESR " TARGET_FMT_lx "   DEAR " TARGET_FMT_lx "\n",
9296 90dc8812 Scott Wood
                    env->spr[SPR_BOOKE_TCR], env->spr[SPR_BOOKE_TSR],
9297 90dc8812 Scott Wood
                    env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]);
9298 90dc8812 Scott Wood
9299 90dc8812 Scott Wood
        cpu_fprintf(f, "  PIR " TARGET_FMT_lx " DECAR " TARGET_FMT_lx
9300 90dc8812 Scott Wood
                       "   IVPR " TARGET_FMT_lx "   EPCR " TARGET_FMT_lx "\n",
9301 90dc8812 Scott Wood
                    env->spr[SPR_BOOKE_PIR], env->spr[SPR_BOOKE_DECAR],
9302 90dc8812 Scott Wood
                    env->spr[SPR_BOOKE_IVPR], env->spr[SPR_BOOKE_EPCR]);
9303 90dc8812 Scott Wood
9304 90dc8812 Scott Wood
        cpu_fprintf(f, " MCSR " TARGET_FMT_lx " SPRG8 " TARGET_FMT_lx
9305 90dc8812 Scott Wood
                       "    EPR " TARGET_FMT_lx "\n",
9306 90dc8812 Scott Wood
                    env->spr[SPR_BOOKE_MCSR], env->spr[SPR_BOOKE_SPRG8],
9307 90dc8812 Scott Wood
                    env->spr[SPR_BOOKE_EPR]);
9308 90dc8812 Scott Wood
9309 90dc8812 Scott Wood
        /* FSL-specific */
9310 90dc8812 Scott Wood
        cpu_fprintf(f, " MCAR " TARGET_FMT_lx "  PID1 " TARGET_FMT_lx
9311 90dc8812 Scott Wood
                       "   PID2 " TARGET_FMT_lx "    SVR " TARGET_FMT_lx "\n",
9312 90dc8812 Scott Wood
                    env->spr[SPR_Exxx_MCAR], env->spr[SPR_BOOKE_PID1],
9313 90dc8812 Scott Wood
                    env->spr[SPR_BOOKE_PID2], env->spr[SPR_E500_SVR]);
9314 90dc8812 Scott Wood
9315 90dc8812 Scott Wood
        /*
9316 90dc8812 Scott Wood
         * IVORs are left out as they are large and do not change often --
9317 90dc8812 Scott Wood
         * they can be read with "p $ivor0", "p $ivor1", etc.
9318 90dc8812 Scott Wood
         */
9319 90dc8812 Scott Wood
    }
9320 90dc8812 Scott Wood
9321 697ab892 David Gibson
#if defined(TARGET_PPC64)
9322 697ab892 David Gibson
    if (env->flags & POWERPC_FLAG_CFAR) {
9323 697ab892 David Gibson
        cpu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar);
9324 697ab892 David Gibson
    }
9325 697ab892 David Gibson
#endif
9326 697ab892 David Gibson
9327 90dc8812 Scott Wood
    switch (env->mmu_model) {
9328 90dc8812 Scott Wood
    case POWERPC_MMU_32B:
9329 90dc8812 Scott Wood
    case POWERPC_MMU_601:
9330 90dc8812 Scott Wood
    case POWERPC_MMU_SOFT_6xx:
9331 90dc8812 Scott Wood
    case POWERPC_MMU_SOFT_74xx:
9332 90dc8812 Scott Wood
#if defined(TARGET_PPC64)
9333 90dc8812 Scott Wood
    case POWERPC_MMU_620:
9334 90dc8812 Scott Wood
    case POWERPC_MMU_64B:
9335 90dc8812 Scott Wood
#endif
9336 90dc8812 Scott Wood
        cpu_fprintf(f, " SDR1 " TARGET_FMT_lx "\n", env->spr[SPR_SDR1]);
9337 90dc8812 Scott Wood
        break;
9338 01662f3e Alexander Graf
    case POWERPC_MMU_BOOKE206:
9339 90dc8812 Scott Wood
        cpu_fprintf(f, " MAS0 " TARGET_FMT_lx "  MAS1 " TARGET_FMT_lx
9340 90dc8812 Scott Wood
                       "   MAS2 " TARGET_FMT_lx "   MAS3 " TARGET_FMT_lx "\n",
9341 90dc8812 Scott Wood
                    env->spr[SPR_BOOKE_MAS0], env->spr[SPR_BOOKE_MAS1],
9342 90dc8812 Scott Wood
                    env->spr[SPR_BOOKE_MAS2], env->spr[SPR_BOOKE_MAS3]);
9343 90dc8812 Scott Wood
9344 90dc8812 Scott Wood
        cpu_fprintf(f, " MAS4 " TARGET_FMT_lx "  MAS6 " TARGET_FMT_lx
9345 90dc8812 Scott Wood
                       "   MAS7 " TARGET_FMT_lx "    PID " TARGET_FMT_lx "\n",
9346 90dc8812 Scott Wood
                    env->spr[SPR_BOOKE_MAS4], env->spr[SPR_BOOKE_MAS6],
9347 90dc8812 Scott Wood
                    env->spr[SPR_BOOKE_MAS7], env->spr[SPR_BOOKE_PID]);
9348 90dc8812 Scott Wood
9349 90dc8812 Scott Wood
        cpu_fprintf(f, "MMUCFG " TARGET_FMT_lx " TLB0CFG " TARGET_FMT_lx
9350 90dc8812 Scott Wood
                       " TLB1CFG " TARGET_FMT_lx "\n",
9351 90dc8812 Scott Wood
                    env->spr[SPR_MMUCFG], env->spr[SPR_BOOKE_TLB0CFG],
9352 90dc8812 Scott Wood
                    env->spr[SPR_BOOKE_TLB1CFG]);
9353 90dc8812 Scott Wood
        break;
9354 90dc8812 Scott Wood
    default:
9355 90dc8812 Scott Wood
        break;
9356 90dc8812 Scott Wood
    }
9357 f2e63a42 j_mayer
#endif
9358 79aceca5 bellard
9359 3fc6c082 bellard
#undef RGPL
9360 3fc6c082 bellard
#undef RFPL
9361 79aceca5 bellard
}
9362 79aceca5 bellard
9363 9a78eead Stefan Weil
void cpu_dump_statistics (CPUState *env, FILE*f, fprintf_function cpu_fprintf,
9364 76a66253 j_mayer
                          int flags)
9365 76a66253 j_mayer
{
9366 76a66253 j_mayer
#if defined(DO_PPC_STATISTICS)
9367 c227f099 Anthony Liguori
    opc_handler_t **t1, **t2, **t3, *handler;
9368 76a66253 j_mayer
    int op1, op2, op3;
9369 76a66253 j_mayer
9370 76a66253 j_mayer
    t1 = env->opcodes;
9371 76a66253 j_mayer
    for (op1 = 0; op1 < 64; op1++) {
9372 76a66253 j_mayer
        handler = t1[op1];
9373 76a66253 j_mayer
        if (is_indirect_opcode(handler)) {
9374 76a66253 j_mayer
            t2 = ind_table(handler);
9375 76a66253 j_mayer
            for (op2 = 0; op2 < 32; op2++) {
9376 76a66253 j_mayer
                handler = t2[op2];
9377 76a66253 j_mayer
                if (is_indirect_opcode(handler)) {
9378 76a66253 j_mayer
                    t3 = ind_table(handler);
9379 76a66253 j_mayer
                    for (op3 = 0; op3 < 32; op3++) {
9380 76a66253 j_mayer
                        handler = t3[op3];
9381 76a66253 j_mayer
                        if (handler->count == 0)
9382 76a66253 j_mayer
                            continue;
9383 76a66253 j_mayer
                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
9384 0bfcd599 Blue Swirl
                                    "%016" PRIx64 " %" PRId64 "\n",
9385 76a66253 j_mayer
                                    op1, op2, op3, op1, (op3 << 5) | op2,
9386 76a66253 j_mayer
                                    handler->oname,
9387 76a66253 j_mayer
                                    handler->count, handler->count);
9388 76a66253 j_mayer
                    }
9389 76a66253 j_mayer
                } else {
9390 76a66253 j_mayer
                    if (handler->count == 0)
9391 76a66253 j_mayer
                        continue;
9392 76a66253 j_mayer
                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
9393 0bfcd599 Blue Swirl
                                "%016" PRIx64 " %" PRId64 "\n",
9394 76a66253 j_mayer
                                op1, op2, op1, op2, handler->oname,
9395 76a66253 j_mayer
                                handler->count, handler->count);
9396 76a66253 j_mayer
                }
9397 76a66253 j_mayer
            }
9398 76a66253 j_mayer
        } else {
9399 76a66253 j_mayer
            if (handler->count == 0)
9400 76a66253 j_mayer
                continue;
9401 0bfcd599 Blue Swirl
            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016" PRIx64
9402 0bfcd599 Blue Swirl
                        " %" PRId64 "\n",
9403 76a66253 j_mayer
                        op1, op1, handler->oname,
9404 76a66253 j_mayer
                        handler->count, handler->count);
9405 76a66253 j_mayer
        }
9406 76a66253 j_mayer
    }
9407 76a66253 j_mayer
#endif
9408 76a66253 j_mayer
}
9409 76a66253 j_mayer
9410 9a64fbe4 bellard
/*****************************************************************************/
9411 636aa200 Blue Swirl
static inline void gen_intermediate_code_internal(CPUState *env,
9412 636aa200 Blue Swirl
                                                  TranslationBlock *tb,
9413 636aa200 Blue Swirl
                                                  int search_pc)
9414 79aceca5 bellard
{
9415 9fddaa0c bellard
    DisasContext ctx, *ctxp = &ctx;
9416 c227f099 Anthony Liguori
    opc_handler_t **table, *handler;
9417 0fa85d43 bellard
    target_ulong pc_start;
9418 79aceca5 bellard
    uint16_t *gen_opc_end;
9419 a1d1bb31 aliguori
    CPUBreakpoint *bp;
9420 79aceca5 bellard
    int j, lj = -1;
9421 2e70f6ef pbrook
    int num_insns;
9422 2e70f6ef pbrook
    int max_insns;
9423 79aceca5 bellard
9424 79aceca5 bellard
    pc_start = tb->pc;
9425 79aceca5 bellard
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
9426 046d6672 bellard
    ctx.nip = pc_start;
9427 79aceca5 bellard
    ctx.tb = tb;
9428 e1833e1f j_mayer
    ctx.exception = POWERPC_EXCP_NONE;
9429 3fc6c082 bellard
    ctx.spr_cb = env->spr_cb;
9430 76db3ba4 aurel32
    ctx.mem_idx = env->mmu_idx;
9431 76db3ba4 aurel32
    ctx.access_type = -1;
9432 76db3ba4 aurel32
    ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
9433 d9bce9d9 j_mayer
#if defined(TARGET_PPC64)
9434 d9bce9d9 j_mayer
    ctx.sf_mode = msr_sf;
9435 697ab892 David Gibson
    ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR);
9436 9a64fbe4 bellard
#endif
9437 3cc62370 bellard
    ctx.fpu_enabled = msr_fp;
9438 a9d9eb8f j_mayer
    if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
9439 d26bfc9a j_mayer
        ctx.spe_enabled = msr_spe;
9440 d26bfc9a j_mayer
    else
9441 d26bfc9a j_mayer
        ctx.spe_enabled = 0;
9442 a9d9eb8f j_mayer
    if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
9443 a9d9eb8f j_mayer
        ctx.altivec_enabled = msr_vr;
9444 a9d9eb8f j_mayer
    else
9445 a9d9eb8f j_mayer
        ctx.altivec_enabled = 0;
9446 d26bfc9a j_mayer
    if ((env->flags & POWERPC_FLAG_SE) && msr_se)
9447 8cbcb4fa aurel32
        ctx.singlestep_enabled = CPU_SINGLE_STEP;
9448 d26bfc9a j_mayer
    else
9449 8cbcb4fa aurel32
        ctx.singlestep_enabled = 0;
9450 d26bfc9a j_mayer
    if ((env->flags & POWERPC_FLAG_BE) && msr_be)
9451 8cbcb4fa aurel32
        ctx.singlestep_enabled |= CPU_BRANCH_STEP;
9452 8cbcb4fa aurel32
    if (unlikely(env->singlestep_enabled))
9453 8cbcb4fa aurel32
        ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
9454 3fc6c082 bellard
#if defined (DO_SINGLE_STEP) && 0
9455 9a64fbe4 bellard
    /* Single step trace mode */
9456 9a64fbe4 bellard
    msr_se = 1;
9457 9a64fbe4 bellard
#endif
9458 2e70f6ef pbrook
    num_insns = 0;
9459 2e70f6ef pbrook
    max_insns = tb->cflags & CF_COUNT_MASK;
9460 2e70f6ef pbrook
    if (max_insns == 0)
9461 2e70f6ef pbrook
        max_insns = CF_COUNT_MASK;
9462 2e70f6ef pbrook
9463 2e70f6ef pbrook
    gen_icount_start();
9464 9a64fbe4 bellard
    /* Set env in case of segfault during code fetch */
9465 e1833e1f j_mayer
    while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
9466 72cf2d4f Blue Swirl
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
9467 72cf2d4f Blue Swirl
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
9468 a1d1bb31 aliguori
                if (bp->pc == ctx.nip) {
9469 e06fcd75 aurel32
                    gen_debug_exception(ctxp);
9470 ea4e754f bellard
                    break;
9471 ea4e754f bellard
                }
9472 ea4e754f bellard
            }
9473 ea4e754f bellard
        }
9474 76a66253 j_mayer
        if (unlikely(search_pc)) {
9475 79aceca5 bellard
            j = gen_opc_ptr - gen_opc_buf;
9476 79aceca5 bellard
            if (lj < j) {
9477 79aceca5 bellard
                lj++;
9478 79aceca5 bellard
                while (lj < j)
9479 79aceca5 bellard
                    gen_opc_instr_start[lj++] = 0;
9480 79aceca5 bellard
            }
9481 af4b6c54 aurel32
            gen_opc_pc[lj] = ctx.nip;
9482 af4b6c54 aurel32
            gen_opc_instr_start[lj] = 1;
9483 af4b6c54 aurel32
            gen_opc_icount[lj] = num_insns;
9484 79aceca5 bellard
        }
9485 d12d51d5 aliguori
        LOG_DISAS("----------------\n");
9486 90e189ec Blue Swirl
        LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n",
9487 d12d51d5 aliguori
                  ctx.nip, ctx.mem_idx, (int)msr_ir);
9488 2e70f6ef pbrook
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
9489 2e70f6ef pbrook
            gen_io_start();
9490 76db3ba4 aurel32
        if (unlikely(ctx.le_mode)) {
9491 056401ea j_mayer
            ctx.opcode = bswap32(ldl_code(ctx.nip));
9492 056401ea j_mayer
        } else {
9493 056401ea j_mayer
            ctx.opcode = ldl_code(ctx.nip);
9494 111bfab3 bellard
        }
9495 d12d51d5 aliguori
        LOG_DISAS("translate opcode %08x (%02x %02x %02x) (%s)\n",
9496 9a64fbe4 bellard
                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
9497 056401ea j_mayer
                    opc3(ctx.opcode), little_endian ? "little" : "big");
9498 731c54f8 Aurelien Jarno
        if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
9499 731c54f8 Aurelien Jarno
            tcg_gen_debug_insn_start(ctx.nip);
9500 046d6672 bellard
        ctx.nip += 4;
9501 3fc6c082 bellard
        table = env->opcodes;
9502 2e70f6ef pbrook
        num_insns++;
9503 79aceca5 bellard
        handler = table[opc1(ctx.opcode)];
9504 79aceca5 bellard
        if (is_indirect_opcode(handler)) {
9505 79aceca5 bellard
            table = ind_table(handler);
9506 79aceca5 bellard
            handler = table[opc2(ctx.opcode)];
9507 79aceca5 bellard
            if (is_indirect_opcode(handler)) {
9508 79aceca5 bellard
                table = ind_table(handler);
9509 79aceca5 bellard
                handler = table[opc3(ctx.opcode)];
9510 79aceca5 bellard
            }
9511 79aceca5 bellard
        }
9512 79aceca5 bellard
        /* Is opcode *REALLY* valid ? */
9513 76a66253 j_mayer
        if (unlikely(handler->handler == &gen_invalid)) {
9514 93fcfe39 aliguori
            if (qemu_log_enabled()) {
9515 93fcfe39 aliguori
                qemu_log("invalid/unsupported opcode: "
9516 90e189ec Blue Swirl
                         "%02x - %02x - %02x (%08x) " TARGET_FMT_lx " %d\n",
9517 90e189ec Blue Swirl
                         opc1(ctx.opcode), opc2(ctx.opcode),
9518 90e189ec Blue Swirl
                         opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
9519 4b3686fa bellard
            }
9520 76a66253 j_mayer
        } else {
9521 70560da7 Fabien Chouteau
            uint32_t inval;
9522 70560da7 Fabien Chouteau
9523 70560da7 Fabien Chouteau
            if (unlikely(handler->type & (PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE) && Rc(ctx.opcode))) {
9524 70560da7 Fabien Chouteau
                inval = handler->inval2;
9525 70560da7 Fabien Chouteau
            } else {
9526 70560da7 Fabien Chouteau
                inval = handler->inval1;
9527 70560da7 Fabien Chouteau
            }
9528 70560da7 Fabien Chouteau
9529 70560da7 Fabien Chouteau
            if (unlikely((ctx.opcode & inval) != 0)) {
9530 93fcfe39 aliguori
                if (qemu_log_enabled()) {
9531 93fcfe39 aliguori
                    qemu_log("invalid bits: %08x for opcode: "
9532 90e189ec Blue Swirl
                             "%02x - %02x - %02x (%08x) " TARGET_FMT_lx "\n",
9533 70560da7 Fabien Chouteau
                             ctx.opcode & inval, opc1(ctx.opcode),
9534 90e189ec Blue Swirl
                             opc2(ctx.opcode), opc3(ctx.opcode),
9535 90e189ec Blue Swirl
                             ctx.opcode, ctx.nip - 4);
9536 76a66253 j_mayer
                }
9537 e06fcd75 aurel32
                gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);
9538 4b3686fa bellard
                break;
9539 79aceca5 bellard
            }
9540 79aceca5 bellard
        }
9541 4b3686fa bellard
        (*(handler->handler))(&ctx);
9542 76a66253 j_mayer
#if defined(DO_PPC_STATISTICS)
9543 76a66253 j_mayer
        handler->count++;
9544 76a66253 j_mayer
#endif
9545 9a64fbe4 bellard
        /* Check trace mode exceptions */
9546 8cbcb4fa aurel32
        if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
9547 8cbcb4fa aurel32
                     (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
9548 8cbcb4fa aurel32
                     ctx.exception != POWERPC_SYSCALL &&
9549 8cbcb4fa aurel32
                     ctx.exception != POWERPC_EXCP_TRAP &&
9550 8cbcb4fa aurel32
                     ctx.exception != POWERPC_EXCP_BRANCH)) {
9551 e06fcd75 aurel32
            gen_exception(ctxp, POWERPC_EXCP_TRACE);
9552 d26bfc9a j_mayer
        } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
9553 2e70f6ef pbrook
                            (env->singlestep_enabled) ||
9554 1b530a6d aurel32
                            singlestep ||
9555 2e70f6ef pbrook
                            num_insns >= max_insns)) {
9556 d26bfc9a j_mayer
            /* if we reach a page boundary or are single stepping, stop
9557 d26bfc9a j_mayer
             * generation
9558 d26bfc9a j_mayer
             */
9559 8dd4983c bellard
            break;
9560 76a66253 j_mayer
        }
9561 3fc6c082 bellard
    }
9562 2e70f6ef pbrook
    if (tb->cflags & CF_LAST_IO)
9563 2e70f6ef pbrook
        gen_io_end();
9564 e1833e1f j_mayer
    if (ctx.exception == POWERPC_EXCP_NONE) {
9565 c1942362 bellard
        gen_goto_tb(&ctx, 0, ctx.nip);
9566 e1833e1f j_mayer
    } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
9567 8cbcb4fa aurel32
        if (unlikely(env->singlestep_enabled)) {
9568 e06fcd75 aurel32
            gen_debug_exception(ctxp);
9569 8cbcb4fa aurel32
        }
9570 76a66253 j_mayer
        /* Generate the return instruction */
9571 57fec1fe bellard
        tcg_gen_exit_tb(0);
9572 9a64fbe4 bellard
    }
9573 2e70f6ef pbrook
    gen_icount_end(tb, num_insns);
9574 79aceca5 bellard
    *gen_opc_ptr = INDEX_op_end;
9575 76a66253 j_mayer
    if (unlikely(search_pc)) {
9576 9a64fbe4 bellard
        j = gen_opc_ptr - gen_opc_buf;
9577 9a64fbe4 bellard
        lj++;
9578 9a64fbe4 bellard
        while (lj <= j)
9579 9a64fbe4 bellard
            gen_opc_instr_start[lj++] = 0;
9580 9a64fbe4 bellard
    } else {
9581 046d6672 bellard
        tb->size = ctx.nip - pc_start;
9582 2e70f6ef pbrook
        tb->icount = num_insns;
9583 9a64fbe4 bellard
    }
9584 d9bce9d9 j_mayer
#if defined(DEBUG_DISAS)
9585 8fec2b8c aliguori
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9586 76a66253 j_mayer
        int flags;
9587 237c0af0 j_mayer
        flags = env->bfd_mach;
9588 76db3ba4 aurel32
        flags |= ctx.le_mode << 16;
9589 93fcfe39 aliguori
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
9590 93fcfe39 aliguori
        log_target_disas(pc_start, ctx.nip - pc_start, flags);
9591 93fcfe39 aliguori
        qemu_log("\n");
9592 9fddaa0c bellard
    }
9593 79aceca5 bellard
#endif
9594 79aceca5 bellard
}
9595 79aceca5 bellard
9596 2cfc5f17 ths
void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
9597 79aceca5 bellard
{
9598 2cfc5f17 ths
    gen_intermediate_code_internal(env, tb, 0);
9599 79aceca5 bellard
}
9600 79aceca5 bellard
9601 2cfc5f17 ths
void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
9602 79aceca5 bellard
{
9603 2cfc5f17 ths
    gen_intermediate_code_internal(env, tb, 1);
9604 79aceca5 bellard
}
9605 d2856f1a aurel32
9606 e87b7cb0 Stefan Weil
void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
9607 d2856f1a aurel32
{
9608 d2856f1a aurel32
    env->nip = gen_opc_pc[pc_pos];
9609 d2856f1a aurel32
}