Statistics
| Branch: | Revision:

root / target-ppc / translate.c @ 9a78eead

History | View | Annotate | Download (334.7 kB)

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

7489 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
7490 0487d6a8 j_mayer
GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
7491 0487d6a8 j_mayer
GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
7492 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
7493 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
7494 0487d6a8 j_mayer
GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
7495 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
7496 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
7497 0487d6a8 j_mayer
GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
7498 0487d6a8 j_mayer
GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
7499 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
7500 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
7501 0487d6a8 j_mayer
GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
7502 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
7503 0487d6a8 j_mayer

7504 0487d6a8 j_mayer
GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
7505 0487d6a8 j_mayer
GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
7506 0487d6a8 j_mayer
GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
7507 0487d6a8 j_mayer
GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
7508 0487d6a8 j_mayer
GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
7509 0487d6a8 j_mayer
GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
7510 0487d6a8 j_mayer

7511 0487d6a8 j_mayer
GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
7512 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
7513 0487d6a8 j_mayer
GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
7514 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
7515 0487d6a8 j_mayer
GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
7516 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
7517 0487d6a8 j_mayer
GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
7518 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
7519 0487d6a8 j_mayer
GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
7520 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
7521 0487d6a8 j_mayer
GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
7522 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
7523 0487d6a8 j_mayer

7524 0487d6a8 j_mayer
GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
7525 0487d6a8 j_mayer
GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
7526 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
7527 0487d6a8 j_mayer
GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
7528 0487d6a8 j_mayer
GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
7529 0487d6a8 j_mayer

7530 0487d6a8 j_mayer
GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
7531 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
7532 0487d6a8 j_mayer
GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
7533 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
7534 0487d6a8 j_mayer
GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
7535 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
7536 0487d6a8 j_mayer
GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
7537 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
7538 0487d6a8 j_mayer
GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
7539 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
7540 0487d6a8 j_mayer
GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
7541 0487d6a8 j_mayer
GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
7542 0487d6a8 j_mayer

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