master
c 5,198 lines 155 KB
Raw
1 /*
2 * PowerPC emulation for qemu: main translation routines.
3 *
4 * Copyright (c) 2003-2007 Jocelyn Mayer
5 * Copyright (C) 2011 Freescale Semiconductor, Inc.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "qemu/osdep.h"
22 #include "cpu.h"
23 #include "internal.h"
24 #include "exec/target_page.h"
25 #include "tcg/tcg-op.h"
26 #include "tcg/tcg-op-gvec.h"
27 #include "qemu/host-utils.h"
28
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
31
32 #include "exec/translator.h"
33 #include "exec/translation-block.h"
34 #include "exec/log.h"
35 #include "qemu/atomic128.h"
36 #include "spr_common.h"
37 #include "power8-pmu.h"
38
39 #include "qemu/qemu-print.h"
40 #include "qapi/error.h"
41
42 #define HELPER_H "helper.h"
43 #include "exec/helper-info.c.inc"
44 #undef HELPER_H
45
46 #define CPU_SINGLE_STEP 0x1
47 #define CPU_BRANCH_STEP 0x2
48
49 /* Include definitions for instructions classes and implementations flags */
50 /* #define PPC_DEBUG_DISAS */
51
52 #ifdef PPC_DEBUG_DISAS
53 # define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
54 #else
55 # define LOG_DISAS(...) do { } while (0)
56 #endif
57 /*****************************************************************************/
58 /* Code translation helpers */
59
60 /* global register indexes */
61 static char cpu_reg_names[10 * 3 + 22 * 4 /* GPR */
62 + 10 * 4 + 22 * 5 /* SPE GPRh */
63 + 8 * 5 /* CRF */];
64 static TCGv cpu_gpr[32];
65 static TCGv cpu_gprh[32];
66 static TCGv_i32 cpu_crf[8];
67 static TCGv cpu_nip;
68 static TCGv cpu_msr;
69 static TCGv cpu_ctr;
70 static TCGv cpu_lr;
71 #if defined(TARGET_PPC64)
72 static TCGv cpu_cfar;
73 #endif
74 static TCGv cpu_xer, cpu_so, cpu_ov, cpu_ca, cpu_ov32, cpu_ca32;
75 static TCGv cpu_reserve;
76 static TCGv cpu_reserve_length;
77 static TCGv cpu_reserve_val;
78 #if defined(TARGET_PPC64)
79 static TCGv cpu_reserve_val2;
80 #endif
81 static TCGv cpu_fpscr;
82 static TCGv_i32 cpu_access_type;
83
84 void ppc_translate_init(void)
85 {
86 int i;
87 char *p;
88 size_t cpu_reg_names_size;
89
90 p = cpu_reg_names;
91 cpu_reg_names_size = sizeof(cpu_reg_names);
92
93 for (i = 0; i < 8; i++) {
94 snprintf(p, cpu_reg_names_size, "crf%d", i);
95 cpu_crf[i] = tcg_global_mem_new_i32(tcg_env,
96 offsetof(CPUPPCState, crf[i]), p);
97 p += 5;
98 cpu_reg_names_size -= 5;
99 }
100
101 for (i = 0; i < 32; i++) {
102 snprintf(p, cpu_reg_names_size, "r%d", i);
103 cpu_gpr[i] = tcg_global_mem_new(tcg_env,
104 offsetof(CPUPPCState, gpr[i]), p);
105 p += (i < 10) ? 3 : 4;
106 cpu_reg_names_size -= (i < 10) ? 3 : 4;
107 snprintf(p, cpu_reg_names_size, "r%dH", i);
108 cpu_gprh[i] = tcg_global_mem_new(tcg_env,
109 offsetof(CPUPPCState, gprh[i]), p);
110 p += (i < 10) ? 4 : 5;
111 cpu_reg_names_size -= (i < 10) ? 4 : 5;
112 }
113
114 cpu_nip = tcg_global_mem_new(tcg_env,
115 offsetof(CPUPPCState, nip), "nip");
116
117 cpu_msr = tcg_global_mem_new(tcg_env,
118 offsetof(CPUPPCState, msr), "msr");
119
120 cpu_ctr = tcg_global_mem_new(tcg_env,
121 offsetof(CPUPPCState, ctr), "ctr");
122
123 cpu_lr = tcg_global_mem_new(tcg_env,
124 offsetof(CPUPPCState, lr), "lr");
125
126 #if defined(TARGET_PPC64)
127 cpu_cfar = tcg_global_mem_new(tcg_env,
128 offsetof(CPUPPCState, cfar), "cfar");
129 #endif
130
131 cpu_xer = tcg_global_mem_new(tcg_env,
132 offsetof(CPUPPCState, xer), "xer");
133 cpu_so = tcg_global_mem_new(tcg_env,
134 offsetof(CPUPPCState, so), "SO");
135 cpu_ov = tcg_global_mem_new(tcg_env,
136 offsetof(CPUPPCState, ov), "OV");
137 cpu_ca = tcg_global_mem_new(tcg_env,
138 offsetof(CPUPPCState, ca), "CA");
139 cpu_ov32 = tcg_global_mem_new(tcg_env,
140 offsetof(CPUPPCState, ov32), "OV32");
141 cpu_ca32 = tcg_global_mem_new(tcg_env,
142 offsetof(CPUPPCState, ca32), "CA32");
143
144 cpu_reserve = tcg_global_mem_new(tcg_env,
145 offsetof(CPUPPCState, reserve_addr),
146 "reserve_addr");
147 cpu_reserve_length = tcg_global_mem_new(tcg_env,
148 offsetof(CPUPPCState,
149 reserve_length),
150 "reserve_length");
151 cpu_reserve_val = tcg_global_mem_new(tcg_env,
152 offsetof(CPUPPCState, reserve_val),
153 "reserve_val");
154 #if defined(TARGET_PPC64)
155 cpu_reserve_val2 = tcg_global_mem_new(tcg_env,
156 offsetof(CPUPPCState, reserve_val2),
157 "reserve_val2");
158 #endif
159
160 cpu_fpscr = tcg_global_mem_new(tcg_env,
161 offsetof(CPUPPCState, fpscr), "fpscr");
162
163 cpu_access_type = tcg_global_mem_new_i32(tcg_env,
164 offsetof(CPUPPCState, access_type),
165 "access_type");
166 }
167
168 /* internal defines */
169 struct DisasContext {
170 DisasContextBase base;
171 target_ulong cia; /* current instruction address */
172 uint32_t opcode;
173 /* Routine used to access memory */
174 bool pr, hv, dr, le_mode;
175 bool lazy_tlb_flush;
176 bool need_access_type;
177 int mem_idx;
178 int access_type;
179 /* Translation flags */
180 MemOp default_tcg_memop_mask;
181 #if defined(TARGET_PPC64)
182 powerpc_excp_t excp_model;
183 bool sf_mode;
184 bool has_cfar;
185 bool has_bhrb;
186 #endif
187 bool fpu_enabled;
188 bool altivec_enabled;
189 bool vsx_enabled;
190 bool spe_enabled;
191 bool tm_enabled;
192 bool gtse;
193 bool hr;
194 bool mmcr0_pmcc0;
195 bool mmcr0_pmcc1;
196 bool mmcr0_pmcjce;
197 bool pmc_other;
198 bool pmu_insn_cnt;
199 bool bhrb_enable;
200 ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
201 int singlestep_flags;
202 uint32_t flags;
203 uint64_t insns_flags;
204 uint64_t insns_flags2;
205 };
206
207 #define DISAS_EXIT DISAS_TARGET_0 /* exit to main loop, pc updated */
208 #define DISAS_EXIT_UPDATE DISAS_TARGET_1 /* exit to main loop, pc stale */
209 #define DISAS_CHAIN DISAS_TARGET_2 /* lookup next tb, pc updated */
210 #define DISAS_CHAIN_UPDATE DISAS_TARGET_3 /* lookup next tb, pc stale */
211
212 static inline bool is_ppe(const DisasContext *ctx)
213 {
214 return !!(ctx->flags & POWERPC_FLAG_PPE42);
215 }
216
217 /**
218 * ppc_code_endian_dc:
219 * @dc: the disassembly context
220 *
221 * Return the MemOp endianness of the CODE path.
222 */
223 static inline MemOp ppc_code_endian_dc(const DisasContext *ctx)
224 {
225 return MO_BE ^ (ctx->le_mode * MO_BSWAP);
226 }
227
228 /* True when active word size < size of target_long. */
229 #ifdef TARGET_PPC64
230 # define NARROW_MODE(C) (!(C)->sf_mode)
231 #else
232 # define NARROW_MODE(C) 0
233 #endif
234
235 struct opc_handler_t {
236 /* invalid bits for instruction 1 (Rc(opcode) == 0) */
237 uint32_t inval1;
238 /* invalid bits for instruction 2 (Rc(opcode) == 1) */
239 uint32_t inval2;
240 /* instruction type */
241 uint64_t type;
242 /* extended instruction type */
243 uint64_t type2;
244 /* handler */
245 void (*handler)(DisasContext *ctx);
246 };
247
248 static inline bool gen_serialize(DisasContext *ctx)
249 {
250 if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
251 /* Restart with exclusive lock. */
252 gen_helper_exit_atomic(tcg_env);
253 ctx->base.is_jmp = DISAS_NORETURN;
254 return false;
255 }
256 return true;
257 }
258
259 #if !defined(CONFIG_USER_ONLY)
260 #if defined(TARGET_PPC64)
261 static inline bool gen_serialize_core(DisasContext *ctx)
262 {
263 if (ctx->flags & POWERPC_FLAG_SMT) {
264 return gen_serialize(ctx);
265 }
266 return true;
267 }
268 #endif
269
270 static inline bool gen_serialize_core_lpar(DisasContext *ctx)
271 {
272 #if defined(TARGET_PPC64)
273 if (ctx->flags & POWERPC_FLAG_SMT_1LPAR) {
274 return gen_serialize(ctx);
275 }
276 #endif
277 return true;
278 }
279 #endif
280
281 /* SPR load/store helpers */
282 static inline void gen_load_spr(TCGv t, int reg)
283 {
284 tcg_gen_ld_tl(t, tcg_env, offsetof(CPUPPCState, spr[reg]));
285 }
286
287 static inline void gen_store_spr(int reg, TCGv t)
288 {
289 tcg_gen_st_tl(t, tcg_env, offsetof(CPUPPCState, spr[reg]));
290 }
291
292 static inline void gen_set_access_type(DisasContext *ctx, int access_type)
293 {
294 if (ctx->need_access_type && ctx->access_type != access_type) {
295 tcg_gen_movi_i32(cpu_access_type, access_type);
296 ctx->access_type = access_type;
297 }
298 }
299
300 static inline void gen_update_nip(DisasContext *ctx, target_ulong nip)
301 {
302 if (NARROW_MODE(ctx)) {
303 nip = (uint32_t)nip;
304 }
305 tcg_gen_movi_tl(cpu_nip, nip);
306 }
307
308 static void gen_exception_err_nip(DisasContext *ctx, uint32_t excp,
309 uint32_t error, target_ulong nip)
310 {
311 TCGv_i32 t0, t1;
312
313 gen_update_nip(ctx, nip);
314 t0 = tcg_constant_i32(excp);
315 t1 = tcg_constant_i32(error);
316 gen_helper_raise_exception_err(tcg_env, t0, t1);
317 ctx->base.is_jmp = DISAS_NORETURN;
318 }
319
320 static inline void gen_exception_err(DisasContext *ctx, uint32_t excp,
321 uint32_t error)
322 {
323 /*
324 * These are all synchronous exceptions, we set the PC back to the
325 * faulting instruction
326 */
327 gen_exception_err_nip(ctx, excp, error, ctx->cia);
328 }
329
330 static void gen_exception_nip(DisasContext *ctx, uint32_t excp,
331 target_ulong nip)
332 {
333 TCGv_i32 t0;
334
335 gen_update_nip(ctx, nip);
336 t0 = tcg_constant_i32(excp);
337 gen_helper_raise_exception(tcg_env, t0);
338 ctx->base.is_jmp = DISAS_NORETURN;
339 }
340
341 static inline void gen_exception(DisasContext *ctx, uint32_t excp)
342 {
343 /*
344 * These are all synchronous exceptions, we set the PC back to the
345 * faulting instruction
346 */
347 gen_exception_nip(ctx, excp, ctx->cia);
348 }
349
350 #if !defined(CONFIG_USER_ONLY)
351 static void gen_ppc_maybe_interrupt(DisasContext *ctx)
352 {
353 translator_io_start(&ctx->base);
354 gen_helper_ppc_maybe_interrupt(tcg_env);
355 }
356 #endif
357
358 /*
359 * Tells the caller what is the appropriate exception to generate and prepares
360 * SPR registers for this exception.
361 *
362 * The exception can be either POWERPC_EXCP_TRACE (on most PowerPCs) or
363 * POWERPC_EXCP_DEBUG (on BookE).
364 */
365 static void gen_debug_exception(DisasContext *ctx, bool rfi_type)
366 {
367 #if !defined(CONFIG_USER_ONLY)
368 if (ctx->flags & POWERPC_FLAG_DE) {
369 target_ulong dbsr = 0;
370 if (ctx->singlestep_flags & CPU_SINGLE_STEP) {
371 dbsr = DBCR0_ICMP;
372 } else {
373 /* Must have been branch */
374 dbsr = DBCR0_BRT;
375 }
376 TCGv t0 = tcg_temp_new();
377 gen_load_spr(t0, SPR_BOOKE_DBSR);
378 tcg_gen_ori_tl(t0, t0, dbsr);
379 gen_store_spr(SPR_BOOKE_DBSR, t0);
380 gen_helper_raise_exception(tcg_env,
381 tcg_constant_i32(POWERPC_EXCP_DEBUG));
382 ctx->base.is_jmp = DISAS_NORETURN;
383 } else {
384 if (!rfi_type) { /* BookS does not single step rfi type instructions */
385 TCGv t0 = tcg_temp_new();
386 tcg_gen_movi_tl(t0, ctx->cia);
387 gen_helper_book3s_trace(tcg_env, t0);
388 ctx->base.is_jmp = DISAS_NORETURN;
389 }
390 }
391 #endif
392 }
393
394 static inline void gen_inval_exception(DisasContext *ctx, uint32_t error)
395 {
396 /* Will be converted to program check if needed */
397 gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_INVAL | error);
398 }
399
400 static inline void gen_priv_exception(DisasContext *ctx, uint32_t error)
401 {
402 gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_PRIV | error);
403 }
404
405 static inline void gen_hvpriv_exception(DisasContext *ctx, uint32_t error)
406 {
407 /* Will be converted to program check if needed */
408 gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_PRIV | error);
409 }
410
411 /*****************************************************************************/
412 /* SPR READ/WRITE CALLBACKS */
413
414 void spr_noaccess(DisasContext *ctx, int gprn, int sprn)
415 {
416 #if 0
417 sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
418 printf("ERROR: try to access SPR %d !\n", sprn);
419 #endif
420 }
421
422 /* #define PPC_DUMP_SPR_ACCESSES */
423
424 /*
425 * Generic callbacks:
426 * do nothing but store/retrieve spr value
427 */
428 static void spr_load_dump_spr(int sprn)
429 {
430 #ifdef PPC_DUMP_SPR_ACCESSES
431 TCGv_i32 t0 = tcg_constant_i32(sprn);
432 gen_helper_load_dump_spr(tcg_env, t0);
433 #endif
434 }
435
436 void spr_read_generic(DisasContext *ctx, int gprn, int sprn)
437 {
438 gen_load_spr(cpu_gpr[gprn], sprn);
439 spr_load_dump_spr(sprn);
440 }
441
442 static void spr_store_dump_spr(int sprn)
443 {
444 #ifdef PPC_DUMP_SPR_ACCESSES
445 TCGv_i32 t0 = tcg_constant_i32(sprn);
446 gen_helper_store_dump_spr(tcg_env, t0);
447 #endif
448 }
449
450 void spr_write_generic(DisasContext *ctx, int sprn, int gprn)
451 {
452 gen_store_spr(sprn, cpu_gpr[gprn]);
453 spr_store_dump_spr(sprn);
454 }
455
456 void spr_write_generic32(DisasContext *ctx, int sprn, int gprn)
457 {
458 #ifdef TARGET_PPC64
459 TCGv t0 = tcg_temp_new();
460 tcg_gen_ext32u_tl(t0, cpu_gpr[gprn]);
461 gen_store_spr(sprn, t0);
462 spr_store_dump_spr(sprn);
463 #else
464 spr_write_generic(ctx, sprn, gprn);
465 #endif
466 }
467
468 void spr_core_write_generic(DisasContext *ctx, int sprn, int gprn)
469 {
470 if (!(ctx->flags & POWERPC_FLAG_SMT)) {
471 spr_write_generic(ctx, sprn, gprn);
472 return;
473 }
474
475 if (!gen_serialize(ctx)) {
476 return;
477 }
478
479 gen_helper_spr_core_write_generic(tcg_env, tcg_constant_i32(sprn),
480 cpu_gpr[gprn]);
481 spr_store_dump_spr(sprn);
482 }
483
484 void spr_core_write_generic32(DisasContext *ctx, int sprn, int gprn)
485 {
486 TCGv t0;
487
488 if (!(ctx->flags & POWERPC_FLAG_SMT)) {
489 spr_write_generic32(ctx, sprn, gprn);
490 return;
491 }
492
493 if (!gen_serialize(ctx)) {
494 return;
495 }
496
497 t0 = tcg_temp_new();
498 tcg_gen_ext32u_tl(t0, cpu_gpr[gprn]);
499 gen_helper_spr_core_write_generic(tcg_env, tcg_constant_i32(sprn), t0);
500 spr_store_dump_spr(sprn);
501 }
502
503 void spr_core_lpar_write_generic(DisasContext *ctx, int sprn, int gprn)
504 {
505 if (ctx->flags & POWERPC_FLAG_SMT_1LPAR) {
506 spr_core_write_generic(ctx, sprn, gprn);
507 } else {
508 spr_write_generic(ctx, sprn, gprn);
509 }
510 }
511
512 static void spr_write_CTRL_ST(DisasContext *ctx, int sprn, int gprn)
513 {
514 /* This does not implement >1 thread */
515 TCGv t0 = tcg_temp_new();
516 TCGv t1 = tcg_temp_new();
517 tcg_gen_extract_tl(t0, cpu_gpr[gprn], 0, 1); /* Extract RUN field */
518 tcg_gen_shli_tl(t1, t0, 8); /* Duplicate the bit in TS */
519 tcg_gen_or_tl(t1, t1, t0);
520 gen_store_spr(sprn, t1);
521 }
522
523 void spr_write_CTRL(DisasContext *ctx, int sprn, int gprn)
524 {
525 if (!(ctx->flags & POWERPC_FLAG_SMT_1LPAR)) {
526 /* CTRL behaves as 1-thread in LPAR-per-thread mode */
527 spr_write_CTRL_ST(ctx, sprn, gprn);
528 goto out;
529 }
530
531 if (!gen_serialize(ctx)) {
532 return;
533 }
534
535 gen_helper_spr_write_CTRL(tcg_env, tcg_constant_i32(sprn),
536 cpu_gpr[gprn]);
537 out:
538 spr_store_dump_spr(sprn);
539
540 /*
541 * SPR_CTRL writes must force a new translation block,
542 * allowing the PMU to calculate the run latch events with
543 * more accuracy.
544 */
545 ctx->base.is_jmp = DISAS_EXIT_UPDATE;
546 }
547
548 #if !defined(CONFIG_USER_ONLY)
549 void spr_write_clear(DisasContext *ctx, int sprn, int gprn)
550 {
551 TCGv t0 = tcg_temp_new();
552 TCGv t1 = tcg_temp_new();
553 gen_load_spr(t0, sprn);
554 tcg_gen_neg_tl(t1, cpu_gpr[gprn]);
555 tcg_gen_and_tl(t0, t0, t1);
556 gen_store_spr(sprn, t0);
557 }
558
559 void spr_access_nop(DisasContext *ctx, int sprn, int gprn)
560 {
561 }
562
563 #endif
564
565 static void gen_get_xer(DisasContext *ctx, TCGv dst)
566 {
567 TCGv t0 = tcg_temp_new();
568 TCGv t1 = tcg_temp_new();
569 TCGv t2 = tcg_temp_new();
570 tcg_gen_mov_tl(dst, cpu_xer);
571 tcg_gen_shli_tl(t0, cpu_so, XER_SO);
572 tcg_gen_shli_tl(t1, cpu_ov, XER_OV);
573 tcg_gen_shli_tl(t2, cpu_ca, XER_CA);
574 tcg_gen_or_tl(t0, t0, t1);
575 tcg_gen_or_tl(dst, dst, t2);
576 tcg_gen_or_tl(dst, dst, t0);
577 if (is_isa300(ctx)) {
578 tcg_gen_shli_tl(t0, cpu_ov32, XER_OV32);
579 tcg_gen_or_tl(dst, dst, t0);
580 tcg_gen_shli_tl(t0, cpu_ca32, XER_CA32);
581 tcg_gen_or_tl(dst, dst, t0);
582 }
583 }
584
585 /* SPR common to all PowerPC */
586 /* XER */
587 void spr_read_xer(DisasContext *ctx, int gprn, int sprn)
588 {
589 TCGv dst = cpu_gpr[gprn];
590 gen_get_xer(ctx, dst);
591 }
592
593 static void gen_set_xer(DisasContext *ctx, TCGv src)
594 {
595 /* Write all flags, while reading back check for isa300 */
596 tcg_gen_andi_tl(cpu_xer, src,
597 ~((1u << XER_SO) |
598 (1u << XER_OV) | (1u << XER_OV32) |
599 (1u << XER_CA) | (1u << XER_CA32)));
600 tcg_gen_extract_tl(cpu_ov32, src, XER_OV32, 1);
601 tcg_gen_extract_tl(cpu_ca32, src, XER_CA32, 1);
602 tcg_gen_extract_tl(cpu_so, src, XER_SO, 1);
603 tcg_gen_extract_tl(cpu_ov, src, XER_OV, 1);
604 tcg_gen_extract_tl(cpu_ca, src, XER_CA, 1);
605 }
606
607 void spr_write_xer(DisasContext *ctx, int sprn, int gprn)
608 {
609 TCGv src = cpu_gpr[gprn];
610 gen_set_xer(ctx, src);
611 }
612
613 /* LR */
614 void spr_read_lr(DisasContext *ctx, int gprn, int sprn)
615 {
616 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_lr);
617 }
618
619 void spr_write_lr(DisasContext *ctx, int sprn, int gprn)
620 {
621 tcg_gen_mov_tl(cpu_lr, cpu_gpr[gprn]);
622 }
623
624 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
625 /* Debug facilities */
626 /* CFAR */
627 void spr_read_cfar(DisasContext *ctx, int gprn, int sprn)
628 {
629 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_cfar);
630 }
631
632 void spr_write_cfar(DisasContext *ctx, int sprn, int gprn)
633 {
634 tcg_gen_mov_tl(cpu_cfar, cpu_gpr[gprn]);
635 }
636
637 /* Breakpoint */
638 void spr_write_ciabr(DisasContext *ctx, int sprn, int gprn)
639 {
640 translator_io_start(&ctx->base);
641 gen_helper_store_ciabr(tcg_env, cpu_gpr[gprn]);
642 }
643
644 /* Watchpoint */
645 void spr_write_dawr0(DisasContext *ctx, int sprn, int gprn)
646 {
647 translator_io_start(&ctx->base);
648 gen_helper_store_dawr0(tcg_env, cpu_gpr[gprn]);
649 }
650
651 void spr_write_dawrx0(DisasContext *ctx, int sprn, int gprn)
652 {
653 translator_io_start(&ctx->base);
654 gen_helper_store_dawrx0(tcg_env, cpu_gpr[gprn]);
655 }
656
657 void spr_write_dawr1(DisasContext *ctx, int sprn, int gprn)
658 {
659 translator_io_start(&ctx->base);
660 gen_helper_store_dawr1(tcg_env, cpu_gpr[gprn]);
661 }
662
663 void spr_write_dawrx1(DisasContext *ctx, int sprn, int gprn)
664 {
665 translator_io_start(&ctx->base);
666 gen_helper_store_dawrx1(tcg_env, cpu_gpr[gprn]);
667 }
668 #endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
669
670 /* CTR */
671 void spr_read_ctr(DisasContext *ctx, int gprn, int sprn)
672 {
673 tcg_gen_mov_tl(cpu_gpr[gprn], cpu_ctr);
674 }
675
676 void spr_write_ctr(DisasContext *ctx, int sprn, int gprn)
677 {
678 tcg_gen_mov_tl(cpu_ctr, cpu_gpr[gprn]);
679 }
680
681 /* User read access to SPR */
682 /* USPRx */
683 /* UMMCRx */
684 /* UPMCx */
685 /* USIA */
686 /* UDECR */
687 void spr_read_ureg(DisasContext *ctx, int gprn, int sprn)
688 {
689 gen_load_spr(cpu_gpr[gprn], sprn + 0x10);
690 }
691
692 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
693 void spr_write_ureg(DisasContext *ctx, int sprn, int gprn)
694 {
695 gen_store_spr(sprn + 0x10, cpu_gpr[gprn]);
696 }
697 #endif
698
699 /* SPR common to all non-embedded PowerPC */
700 /* DECR */
701 #if !defined(CONFIG_USER_ONLY)
702 void spr_read_decr(DisasContext *ctx, int gprn, int sprn)
703 {
704 translator_io_start(&ctx->base);
705 gen_helper_load_decr(cpu_gpr[gprn], tcg_env);
706 }
707
708 void spr_write_decr(DisasContext *ctx, int sprn, int gprn)
709 {
710 translator_io_start(&ctx->base);
711 gen_helper_store_decr(tcg_env, cpu_gpr[gprn]);
712 }
713 #endif
714
715 /* SPR common to all non-embedded PowerPC, except 601 */
716 /* Time base */
717 void spr_read_tbl(DisasContext *ctx, int gprn, int sprn)
718 {
719 translator_io_start(&ctx->base);
720 gen_helper_load_tbl(cpu_gpr[gprn], tcg_env);
721 }
722
723 void spr_read_tbu(DisasContext *ctx, int gprn, int sprn)
724 {
725 translator_io_start(&ctx->base);
726 gen_helper_load_tbu(cpu_gpr[gprn], tcg_env);
727 }
728
729 void spr_read_atbl(DisasContext *ctx, int gprn, int sprn)
730 {
731 gen_helper_load_atbl(cpu_gpr[gprn], tcg_env);
732 }
733
734 void spr_read_atbu(DisasContext *ctx, int gprn, int sprn)
735 {
736 gen_helper_load_atbu(cpu_gpr[gprn], tcg_env);
737 }
738
739 #if !defined(CONFIG_USER_ONLY)
740 void spr_write_tbl(DisasContext *ctx, int sprn, int gprn)
741 {
742 if (!gen_serialize_core_lpar(ctx)) {
743 return;
744 }
745
746 translator_io_start(&ctx->base);
747 gen_helper_store_tbl(tcg_env, cpu_gpr[gprn]);
748 }
749
750 void spr_write_tbu(DisasContext *ctx, int sprn, int gprn)
751 {
752 if (!gen_serialize_core_lpar(ctx)) {
753 return;
754 }
755
756 translator_io_start(&ctx->base);
757 gen_helper_store_tbu(tcg_env, cpu_gpr[gprn]);
758 }
759
760 void spr_write_atbl(DisasContext *ctx, int sprn, int gprn)
761 {
762 gen_helper_store_atbl(tcg_env, cpu_gpr[gprn]);
763 }
764
765 void spr_write_atbu(DisasContext *ctx, int sprn, int gprn)
766 {
767 gen_helper_store_atbu(tcg_env, cpu_gpr[gprn]);
768 }
769
770 #if defined(TARGET_PPC64)
771 void spr_read_purr(DisasContext *ctx, int gprn, int sprn)
772 {
773 translator_io_start(&ctx->base);
774 gen_helper_load_purr(cpu_gpr[gprn], tcg_env);
775 }
776
777 void spr_write_purr(DisasContext *ctx, int sprn, int gprn)
778 {
779 if (!gen_serialize_core_lpar(ctx)) {
780 return;
781 }
782 translator_io_start(&ctx->base);
783 gen_helper_store_purr(tcg_env, cpu_gpr[gprn]);
784 }
785
786 /* HDECR */
787 void spr_read_hdecr(DisasContext *ctx, int gprn, int sprn)
788 {
789 translator_io_start(&ctx->base);
790 gen_helper_load_hdecr(cpu_gpr[gprn], tcg_env);
791 }
792
793 void spr_write_hdecr(DisasContext *ctx, int sprn, int gprn)
794 {
795 if (!gen_serialize_core_lpar(ctx)) {
796 return;
797 }
798 translator_io_start(&ctx->base);
799 gen_helper_store_hdecr(tcg_env, cpu_gpr[gprn]);
800 }
801
802 void spr_read_vtb(DisasContext *ctx, int gprn, int sprn)
803 {
804 translator_io_start(&ctx->base);
805 gen_helper_load_vtb(cpu_gpr[gprn], tcg_env);
806 }
807
808 void spr_write_vtb(DisasContext *ctx, int sprn, int gprn)
809 {
810 if (!gen_serialize_core_lpar(ctx)) {
811 return;
812 }
813 translator_io_start(&ctx->base);
814 gen_helper_store_vtb(tcg_env, cpu_gpr[gprn]);
815 }
816
817 void spr_write_tbu40(DisasContext *ctx, int sprn, int gprn)
818 {
819 if (!gen_serialize_core_lpar(ctx)) {
820 return;
821 }
822 translator_io_start(&ctx->base);
823 gen_helper_store_tbu40(tcg_env, cpu_gpr[gprn]);
824 }
825
826 #endif
827 #endif
828
829 #if !defined(CONFIG_USER_ONLY)
830 /* IBAT0U...IBAT0U */
831 /* IBAT0L...IBAT7L */
832 void spr_read_ibat(DisasContext *ctx, int gprn, int sprn)
833 {
834 tcg_gen_ld_tl(cpu_gpr[gprn], tcg_env,
835 offsetof(CPUPPCState,
836 IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2]));
837 }
838
839 void spr_read_ibat_h(DisasContext *ctx, int gprn, int sprn)
840 {
841 tcg_gen_ld_tl(cpu_gpr[gprn], tcg_env,
842 offsetof(CPUPPCState,
843 IBAT[sprn & 1][((sprn - SPR_IBAT4U) / 2) + 4]));
844 }
845
846 void spr_write_ibatu(DisasContext *ctx, int sprn, int gprn)
847 {
848 TCGv_i32 t0 = tcg_constant_i32((sprn - SPR_IBAT0U) / 2);
849 gen_helper_store_ibatu(tcg_env, t0, cpu_gpr[gprn]);
850 }
851
852 void spr_write_ibatu_h(DisasContext *ctx, int sprn, int gprn)
853 {
854 TCGv_i32 t0 = tcg_constant_i32(((sprn - SPR_IBAT4U) / 2) + 4);
855 gen_helper_store_ibatu(tcg_env, t0, cpu_gpr[gprn]);
856 }
857
858 void spr_write_ibatl(DisasContext *ctx, int sprn, int gprn)
859 {
860 TCGv_i32 t0 = tcg_constant_i32((sprn - SPR_IBAT0L) / 2);
861 gen_helper_store_ibatl(tcg_env, t0, cpu_gpr[gprn]);
862 }
863
864 void spr_write_ibatl_h(DisasContext *ctx, int sprn, int gprn)
865 {
866 TCGv_i32 t0 = tcg_constant_i32(((sprn - SPR_IBAT4L) / 2) + 4);
867 gen_helper_store_ibatl(tcg_env, t0, cpu_gpr[gprn]);
868 }
869
870 /* DBAT0U...DBAT7U */
871 /* DBAT0L...DBAT7L */
872 void spr_read_dbat(DisasContext *ctx, int gprn, int sprn)
873 {
874 tcg_gen_ld_tl(cpu_gpr[gprn], tcg_env,
875 offsetof(CPUPPCState,
876 DBAT[sprn & 1][(sprn - SPR_DBAT0U) / 2]));
877 }
878
879 void spr_read_dbat_h(DisasContext *ctx, int gprn, int sprn)
880 {
881 tcg_gen_ld_tl(cpu_gpr[gprn], tcg_env,
882 offsetof(CPUPPCState,
883 DBAT[sprn & 1][((sprn - SPR_DBAT4U) / 2) + 4]));
884 }
885
886 void spr_write_dbatu(DisasContext *ctx, int sprn, int gprn)
887 {
888 TCGv_i32 t0 = tcg_constant_i32((sprn - SPR_DBAT0U) / 2);
889 gen_helper_store_dbatu(tcg_env, t0, cpu_gpr[gprn]);
890 }
891
892 void spr_write_dbatu_h(DisasContext *ctx, int sprn, int gprn)
893 {
894 TCGv_i32 t0 = tcg_constant_i32(((sprn - SPR_DBAT4U) / 2) + 4);
895 gen_helper_store_dbatu(tcg_env, t0, cpu_gpr[gprn]);
896 }
897
898 void spr_write_dbatl(DisasContext *ctx, int sprn, int gprn)
899 {
900 TCGv_i32 t0 = tcg_constant_i32((sprn - SPR_DBAT0L) / 2);
901 gen_helper_store_dbatl(tcg_env, t0, cpu_gpr[gprn]);
902 }
903
904 void spr_write_dbatl_h(DisasContext *ctx, int sprn, int gprn)
905 {
906 TCGv_i32 t0 = tcg_constant_i32(((sprn - SPR_DBAT4L) / 2) + 4);
907 gen_helper_store_dbatl(tcg_env, t0, cpu_gpr[gprn]);
908 }
909
910 /* SDR1 */
911 void spr_write_sdr1(DisasContext *ctx, int sprn, int gprn)
912 {
913 gen_helper_store_sdr1(tcg_env, cpu_gpr[gprn]);
914 }
915
916 #if defined(TARGET_PPC64)
917 /* 64 bits PowerPC specific SPRs */
918 /* PIDR */
919 void spr_write_pidr(DisasContext *ctx, int sprn, int gprn)
920 {
921 gen_helper_store_pidr(tcg_env, cpu_gpr[gprn]);
922 }
923
924 void spr_write_lpidr(DisasContext *ctx, int sprn, int gprn)
925 {
926 gen_helper_store_lpidr(tcg_env, cpu_gpr[gprn]);
927 }
928
929 void spr_read_hior(DisasContext *ctx, int gprn, int sprn)
930 {
931 tcg_gen_ld_tl(cpu_gpr[gprn], tcg_env, offsetof(CPUPPCState, excp_prefix));
932 }
933
934 void spr_write_hior(DisasContext *ctx, int sprn, int gprn)
935 {
936 TCGv t0 = tcg_temp_new();
937 tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0x3FFFFF00000ULL);
938 tcg_gen_st_tl(t0, tcg_env, offsetof(CPUPPCState, excp_prefix));
939 }
940 void spr_write_ptcr(DisasContext *ctx, int sprn, int gprn)
941 {
942 if (!gen_serialize_core(ctx)) {
943 return;
944 }
945
946 gen_helper_store_ptcr(tcg_env, cpu_gpr[gprn]);
947 }
948
949 void spr_write_pcr(DisasContext *ctx, int sprn, int gprn)
950 {
951 gen_helper_store_pcr(tcg_env, cpu_gpr[gprn]);
952 }
953
954 /* DPDES */
955 void spr_read_dpdes(DisasContext *ctx, int gprn, int sprn)
956 {
957 if (!gen_serialize_core_lpar(ctx)) {
958 return;
959 }
960
961 gen_helper_load_dpdes(cpu_gpr[gprn], tcg_env);
962 }
963
964 void spr_write_dpdes(DisasContext *ctx, int sprn, int gprn)
965 {
966 if (!gen_serialize_core_lpar(ctx)) {
967 return;
968 }
969
970 gen_helper_store_dpdes(tcg_env, cpu_gpr[gprn]);
971 }
972 #endif
973 #endif
974
975 /* PowerPC 40x specific registers */
976 #if !defined(CONFIG_USER_ONLY)
977 void spr_read_40x_pit(DisasContext *ctx, int gprn, int sprn)
978 {
979 translator_io_start(&ctx->base);
980 gen_helper_load_40x_pit(cpu_gpr[gprn], tcg_env);
981 }
982
983 void spr_write_40x_pit(DisasContext *ctx, int sprn, int gprn)
984 {
985 translator_io_start(&ctx->base);
986 gen_helper_store_40x_pit(tcg_env, cpu_gpr[gprn]);
987 }
988
989 void spr_write_40x_dbcr0(DisasContext *ctx, int sprn, int gprn)
990 {
991 translator_io_start(&ctx->base);
992 gen_store_spr(sprn, cpu_gpr[gprn]);
993 gen_helper_store_40x_dbcr0(tcg_env, cpu_gpr[gprn]);
994 /* We must stop translation as we may have rebooted */
995 ctx->base.is_jmp = DISAS_EXIT_UPDATE;
996 }
997
998 void spr_write_40x_sler(DisasContext *ctx, int sprn, int gprn)
999 {
1000 translator_io_start(&ctx->base);
1001 gen_helper_store_40x_sler(tcg_env, cpu_gpr[gprn]);
1002 }
1003
1004 void spr_write_40x_tcr(DisasContext *ctx, int sprn, int gprn)
1005 {
1006 translator_io_start(&ctx->base);
1007 gen_helper_store_40x_tcr(tcg_env, cpu_gpr[gprn]);
1008 }
1009
1010 void spr_write_40x_tsr(DisasContext *ctx, int sprn, int gprn)
1011 {
1012 translator_io_start(&ctx->base);
1013 gen_helper_store_40x_tsr(tcg_env, cpu_gpr[gprn]);
1014 }
1015
1016 void spr_write_40x_pid(DisasContext *ctx, int sprn, int gprn)
1017 {
1018 TCGv t0 = tcg_temp_new();
1019 tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0xFF);
1020 gen_helper_store_40x_pid(tcg_env, t0);
1021 }
1022
1023 void spr_write_booke_tcr(DisasContext *ctx, int sprn, int gprn)
1024 {
1025 translator_io_start(&ctx->base);
1026 gen_helper_store_booke_tcr(tcg_env, cpu_gpr[gprn]);
1027 }
1028
1029 void spr_write_booke_tsr(DisasContext *ctx, int sprn, int gprn)
1030 {
1031 translator_io_start(&ctx->base);
1032 gen_helper_store_booke_tsr(tcg_env, cpu_gpr[gprn]);
1033 }
1034 #endif
1035
1036 /* PIR */
1037 #if !defined(CONFIG_USER_ONLY)
1038 void spr_write_pir(DisasContext *ctx, int sprn, int gprn)
1039 {
1040 TCGv t0 = tcg_temp_new();
1041 tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0xF);
1042 gen_store_spr(SPR_PIR, t0);
1043 }
1044 #endif
1045
1046 /* SPE specific registers */
1047 void spr_read_spefscr(DisasContext *ctx, int gprn, int sprn)
1048 {
1049 TCGv_i32 t0 = tcg_temp_new_i32();
1050 tcg_gen_ld_i32(t0, tcg_env, offsetof(CPUPPCState, spe_fscr));
1051 tcg_gen_extu_i32_tl(cpu_gpr[gprn], t0);
1052 }
1053
1054 void spr_write_spefscr(DisasContext *ctx, int sprn, int gprn)
1055 {
1056 TCGv_i32 t0 = tcg_temp_new_i32();
1057 tcg_gen_trunc_tl_i32(t0, cpu_gpr[gprn]);
1058 tcg_gen_st_i32(t0, tcg_env, offsetof(CPUPPCState, spe_fscr));
1059 }
1060
1061 #if !defined(CONFIG_USER_ONLY)
1062 /* Callback used to write the exception vector base */
1063 void spr_write_excp_prefix(DisasContext *ctx, int sprn, int gprn)
1064 {
1065 TCGv t0 = tcg_temp_new();
1066 tcg_gen_ld_tl(t0, tcg_env, offsetof(CPUPPCState, ivpr_mask));
1067 tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]);
1068 tcg_gen_st_tl(t0, tcg_env, offsetof(CPUPPCState, excp_prefix));
1069 gen_store_spr(sprn, t0);
1070 }
1071
1072 void spr_write_excp_vector(DisasContext *ctx, int sprn, int gprn)
1073 {
1074 int sprn_offs;
1075
1076 if (sprn >= SPR_BOOKE_IVOR0 && sprn <= SPR_BOOKE_IVOR15) {
1077 sprn_offs = sprn - SPR_BOOKE_IVOR0;
1078 } else if (sprn >= SPR_BOOKE_IVOR32 && sprn <= SPR_BOOKE_IVOR37) {
1079 sprn_offs = sprn - SPR_BOOKE_IVOR32 + 32;
1080 } else if (sprn >= SPR_BOOKE_IVOR38 && sprn <= SPR_BOOKE_IVOR42) {
1081 sprn_offs = sprn - SPR_BOOKE_IVOR38 + 38;
1082 } else {
1083 qemu_log_mask(LOG_GUEST_ERROR, "Trying to write an unknown exception"
1084 " vector 0x%03x\n", sprn);
1085 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1086 return;
1087 }
1088
1089 TCGv t0 = tcg_temp_new();
1090 tcg_gen_ld_tl(t0, tcg_env, offsetof(CPUPPCState, ivor_mask));
1091 tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]);
1092 tcg_gen_st_tl(t0, tcg_env, offsetof(CPUPPCState, excp_vectors[sprn_offs]));
1093 gen_store_spr(sprn, t0);
1094 }
1095 #endif
1096
1097 #ifdef TARGET_PPC64
1098 #ifndef CONFIG_USER_ONLY
1099 void spr_write_amr(DisasContext *ctx, int sprn, int gprn)
1100 {
1101 TCGv t0 = tcg_temp_new();
1102 TCGv t1 = tcg_temp_new();
1103 TCGv t2 = tcg_temp_new();
1104
1105 /*
1106 * Note, the HV=1 PR=0 case is handled earlier by simply using
1107 * spr_write_generic for HV mode in the SPR table
1108 */
1109
1110 /* Build insertion mask into t1 based on context */
1111 if (ctx->pr) {
1112 gen_load_spr(t1, SPR_UAMOR);
1113 } else {
1114 gen_load_spr(t1, SPR_AMOR);
1115 }
1116
1117 /* Mask new bits into t2 */
1118 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
1119
1120 /* Load AMR and clear new bits in t0 */
1121 gen_load_spr(t0, SPR_AMR);
1122 tcg_gen_andc_tl(t0, t0, t1);
1123
1124 /* Or'in new bits and write it out */
1125 tcg_gen_or_tl(t0, t0, t2);
1126 gen_store_spr(SPR_AMR, t0);
1127 spr_store_dump_spr(SPR_AMR);
1128 }
1129
1130 void spr_write_uamor(DisasContext *ctx, int sprn, int gprn)
1131 {
1132 TCGv t0 = tcg_temp_new();
1133 TCGv t1 = tcg_temp_new();
1134 TCGv t2 = tcg_temp_new();
1135
1136 /*
1137 * Note, the HV=1 case is handled earlier by simply using
1138 * spr_write_generic for HV mode in the SPR table
1139 */
1140
1141 /* Build insertion mask into t1 based on context */
1142 gen_load_spr(t1, SPR_AMOR);
1143
1144 /* Mask new bits into t2 */
1145 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
1146
1147 /* Load AMR and clear new bits in t0 */
1148 gen_load_spr(t0, SPR_UAMOR);
1149 tcg_gen_andc_tl(t0, t0, t1);
1150
1151 /* Or'in new bits and write it out */
1152 tcg_gen_or_tl(t0, t0, t2);
1153 gen_store_spr(SPR_UAMOR, t0);
1154 spr_store_dump_spr(SPR_UAMOR);
1155 }
1156
1157 void spr_write_iamr(DisasContext *ctx, int sprn, int gprn)
1158 {
1159 TCGv t0 = tcg_temp_new();
1160 TCGv t1 = tcg_temp_new();
1161 TCGv t2 = tcg_temp_new();
1162
1163 /*
1164 * Note, the HV=1 case is handled earlier by simply using
1165 * spr_write_generic for HV mode in the SPR table
1166 */
1167
1168 /* Build insertion mask into t1 based on context */
1169 gen_load_spr(t1, SPR_AMOR);
1170
1171 /* Mask new bits into t2 */
1172 tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
1173
1174 /* Load AMR and clear new bits in t0 */
1175 gen_load_spr(t0, SPR_IAMR);
1176 tcg_gen_andc_tl(t0, t0, t1);
1177
1178 /* Or'in new bits and write it out */
1179 tcg_gen_or_tl(t0, t0, t2);
1180 gen_store_spr(SPR_IAMR, t0);
1181 spr_store_dump_spr(SPR_IAMR);
1182 }
1183 #endif
1184 #endif
1185
1186 #ifndef CONFIG_USER_ONLY
1187 void spr_read_thrm(DisasContext *ctx, int gprn, int sprn)
1188 {
1189 gen_helper_fixup_thrm(tcg_env);
1190 gen_load_spr(cpu_gpr[gprn], sprn);
1191 spr_load_dump_spr(sprn);
1192 }
1193 #endif /* !CONFIG_USER_ONLY */
1194
1195 #if !defined(CONFIG_USER_ONLY)
1196 void spr_write_e500_l1csr0(DisasContext *ctx, int sprn, int gprn)
1197 {
1198 TCGv t0 = tcg_temp_new();
1199
1200 tcg_gen_andi_tl(t0, cpu_gpr[gprn], L1CSR0_DCE | L1CSR0_CPE);
1201 gen_store_spr(sprn, t0);
1202 }
1203
1204 void spr_write_e500_l1csr1(DisasContext *ctx, int sprn, int gprn)
1205 {
1206 TCGv t0 = tcg_temp_new();
1207
1208 tcg_gen_andi_tl(t0, cpu_gpr[gprn], L1CSR1_ICE | L1CSR1_CPE);
1209 gen_store_spr(sprn, t0);
1210 }
1211
1212 void spr_write_e500_l2csr0(DisasContext *ctx, int sprn, int gprn)
1213 {
1214 TCGv t0 = tcg_temp_new();
1215
1216 tcg_gen_andi_tl(t0, cpu_gpr[gprn],
1217 ~(E500_L2CSR0_L2FI | E500_L2CSR0_L2FL | E500_L2CSR0_L2LFC));
1218 gen_store_spr(sprn, t0);
1219 }
1220
1221 void spr_write_booke206_mmucsr0(DisasContext *ctx, int sprn, int gprn)
1222 {
1223 gen_helper_booke206_tlbflush(tcg_env, cpu_gpr[gprn]);
1224 }
1225
1226 void spr_write_booke_pid(DisasContext *ctx, int sprn, int gprn)
1227 {
1228 TCGv_i32 t0 = tcg_constant_i32(sprn);
1229 gen_helper_booke_setpid(tcg_env, t0, cpu_gpr[gprn]);
1230 }
1231
1232 void spr_write_eplc(DisasContext *ctx, int sprn, int gprn)
1233 {
1234 gen_helper_booke_set_eplc(tcg_env, cpu_gpr[gprn]);
1235 }
1236
1237 void spr_write_epsc(DisasContext *ctx, int sprn, int gprn)
1238 {
1239 gen_helper_booke_set_epsc(tcg_env, cpu_gpr[gprn]);
1240 }
1241
1242 #endif
1243
1244 #if !defined(CONFIG_USER_ONLY)
1245 void spr_write_mas73(DisasContext *ctx, int sprn, int gprn)
1246 {
1247 TCGv val = tcg_temp_new();
1248 tcg_gen_ext32u_tl(val, cpu_gpr[gprn]);
1249 gen_store_spr(SPR_BOOKE_MAS3, val);
1250 tcg_gen_shri_tl(val, cpu_gpr[gprn], 32);
1251 gen_store_spr(SPR_BOOKE_MAS7, val);
1252 }
1253
1254 void spr_read_mas73(DisasContext *ctx, int gprn, int sprn)
1255 {
1256 TCGv mas7 = tcg_temp_new();
1257 TCGv mas3 = tcg_temp_new();
1258 gen_load_spr(mas7, SPR_BOOKE_MAS7);
1259 tcg_gen_shli_tl(mas7, mas7, 32);
1260 gen_load_spr(mas3, SPR_BOOKE_MAS3);
1261 tcg_gen_or_tl(cpu_gpr[gprn], mas3, mas7);
1262 }
1263
1264 #endif
1265
1266 #ifdef TARGET_PPC64
1267 static void gen_fscr_facility_check(DisasContext *ctx, int facility_sprn,
1268 int bit, int sprn, int cause)
1269 {
1270 TCGv_i32 t1 = tcg_constant_i32(bit);
1271 TCGv_i32 t2 = tcg_constant_i32(sprn);
1272 TCGv_i32 t3 = tcg_constant_i32(cause);
1273
1274 gen_helper_fscr_facility_check(tcg_env, t1, t2, t3);
1275 }
1276
1277 static void gen_msr_facility_check(DisasContext *ctx, int facility_sprn,
1278 int bit, int sprn, int cause)
1279 {
1280 TCGv_i32 t1 = tcg_constant_i32(bit);
1281 TCGv_i32 t2 = tcg_constant_i32(sprn);
1282 TCGv_i32 t3 = tcg_constant_i32(cause);
1283
1284 gen_helper_msr_facility_check(tcg_env, t1, t2, t3);
1285 }
1286
1287 void spr_read_prev_upper32(DisasContext *ctx, int gprn, int sprn)
1288 {
1289 TCGv spr_up = tcg_temp_new();
1290 TCGv spr = tcg_temp_new();
1291
1292 gen_load_spr(spr, sprn - 1);
1293 tcg_gen_shri_tl(spr_up, spr, 32);
1294 tcg_gen_ext32u_tl(cpu_gpr[gprn], spr_up);
1295 }
1296
1297 void spr_write_prev_upper32(DisasContext *ctx, int sprn, int gprn)
1298 {
1299 TCGv spr = tcg_temp_new();
1300
1301 gen_load_spr(spr, sprn - 1);
1302 tcg_gen_deposit_tl(spr, spr, cpu_gpr[gprn], 32, 32);
1303 gen_store_spr(sprn - 1, spr);
1304 }
1305
1306 #if !defined(CONFIG_USER_ONLY)
1307 void spr_write_hmer(DisasContext *ctx, int sprn, int gprn)
1308 {
1309 TCGv hmer = tcg_temp_new();
1310
1311 gen_load_spr(hmer, sprn);
1312 tcg_gen_and_tl(hmer, cpu_gpr[gprn], hmer);
1313 gen_store_spr(sprn, hmer);
1314 spr_store_dump_spr(sprn);
1315 }
1316
1317 void spr_read_tfmr(DisasContext *ctx, int gprn, int sprn)
1318 {
1319 /* Reading TFMR can cause it to be updated, so serialize threads here too */
1320 if (!gen_serialize_core(ctx)) {
1321 return;
1322 }
1323 gen_helper_load_tfmr(cpu_gpr[gprn], tcg_env);
1324 }
1325
1326 void spr_write_tfmr(DisasContext *ctx, int sprn, int gprn)
1327 {
1328 if (!gen_serialize_core(ctx)) {
1329 return;
1330 }
1331 gen_helper_store_tfmr(tcg_env, cpu_gpr[gprn]);
1332 }
1333
1334 void spr_write_sprc(DisasContext *ctx, int sprn, int gprn)
1335 {
1336 gen_helper_store_sprc(tcg_env, cpu_gpr[gprn]);
1337 }
1338
1339 void spr_read_sprd(DisasContext *ctx, int gprn, int sprn)
1340 {
1341 gen_helper_load_sprd(cpu_gpr[gprn], tcg_env);
1342 }
1343
1344 void spr_write_sprd(DisasContext *ctx, int sprn, int gprn)
1345 {
1346 if (!gen_serialize_core(ctx)) {
1347 return;
1348 }
1349 gen_helper_store_sprd(tcg_env, cpu_gpr[gprn]);
1350 }
1351
1352 void spr_write_lpcr(DisasContext *ctx, int sprn, int gprn)
1353 {
1354 translator_io_start(&ctx->base);
1355 gen_helper_store_lpcr(tcg_env, cpu_gpr[gprn]);
1356 }
1357
1358 void spr_read_pmsr(DisasContext *ctx, int gprn, int sprn)
1359 {
1360 translator_io_start(&ctx->base);
1361 gen_helper_load_pmsr(cpu_gpr[gprn], tcg_env);
1362 }
1363
1364 void spr_write_pmcr(DisasContext *ctx, int sprn, int gprn)
1365 {
1366 if (!gen_serialize_core_lpar(ctx)) {
1367 return;
1368 }
1369 translator_io_start(&ctx->base);
1370 gen_helper_store_pmcr(tcg_env, cpu_gpr[gprn]);
1371 }
1372
1373 #endif /* !defined(CONFIG_USER_ONLY) */
1374
1375 void spr_read_tar(DisasContext *ctx, int gprn, int sprn)
1376 {
1377 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR);
1378 spr_read_generic(ctx, gprn, sprn);
1379 }
1380
1381 void spr_write_tar(DisasContext *ctx, int sprn, int gprn)
1382 {
1383 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR);
1384 spr_write_generic(ctx, sprn, gprn);
1385 }
1386
1387 void spr_read_tm(DisasContext *ctx, int gprn, int sprn)
1388 {
1389 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
1390 spr_read_generic(ctx, gprn, sprn);
1391 }
1392
1393 void spr_write_tm(DisasContext *ctx, int sprn, int gprn)
1394 {
1395 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
1396 spr_write_generic(ctx, sprn, gprn);
1397 }
1398
1399 void spr_read_tm_upper32(DisasContext *ctx, int gprn, int sprn)
1400 {
1401 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
1402 spr_read_prev_upper32(ctx, gprn, sprn);
1403 }
1404
1405 void spr_write_tm_upper32(DisasContext *ctx, int sprn, int gprn)
1406 {
1407 gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
1408 spr_write_prev_upper32(ctx, sprn, gprn);
1409 }
1410
1411 void spr_read_ebb(DisasContext *ctx, int gprn, int sprn)
1412 {
1413 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
1414 spr_read_generic(ctx, gprn, sprn);
1415 }
1416
1417 void spr_write_ebb(DisasContext *ctx, int sprn, int gprn)
1418 {
1419 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
1420 spr_write_generic(ctx, sprn, gprn);
1421 }
1422
1423 void spr_read_ebb_upper32(DisasContext *ctx, int gprn, int sprn)
1424 {
1425 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
1426 spr_read_prev_upper32(ctx, gprn, sprn);
1427 }
1428
1429 void spr_write_ebb_upper32(DisasContext *ctx, int sprn, int gprn)
1430 {
1431 gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
1432 spr_write_prev_upper32(ctx, sprn, gprn);
1433 }
1434
1435 void spr_read_dexcr_ureg(DisasContext *ctx, int gprn, int sprn)
1436 {
1437 TCGv t0 = tcg_temp_new();
1438
1439 /*
1440 * Access to the (H)DEXCR in problem state is done using separated
1441 * SPR indexes which are 16 below the SPR indexes which have full
1442 * access to the (H)DEXCR in privileged state. Problem state can
1443 * only read bits 32:63, bits 0:31 return 0.
1444 *
1445 * See section 9.3.1-9.3.2 of PowerISA v3.1B
1446 */
1447
1448 gen_load_spr(t0, sprn + 16);
1449 tcg_gen_ext32u_tl(cpu_gpr[gprn], t0);
1450 }
1451
1452 /* The PPR32 SPR accesses the upper 32-bits of PPR */
1453 void spr_read_ppr32(DisasContext *ctx, int gprn, int sprn)
1454 {
1455 gen_load_spr(cpu_gpr[gprn], SPR_PPR);
1456 tcg_gen_shri_tl(cpu_gpr[gprn], cpu_gpr[gprn], 32);
1457 spr_load_dump_spr(SPR_PPR);
1458 }
1459
1460 void spr_write_ppr32(DisasContext *ctx, int sprn, int gprn)
1461 {
1462 TCGv t0 = tcg_temp_new();
1463
1464 /*
1465 * Don't clobber the low 32-bits of the PPR. These are all reserved bits
1466 * but TCG does implement them, so it would be surprising to zero them
1467 * here. "Priority nops" are similarly careful not to clobber reserved
1468 * bits.
1469 */
1470 gen_load_spr(t0, SPR_PPR);
1471 tcg_gen_deposit_tl(t0, t0, cpu_gpr[gprn], 32, 32);
1472 gen_store_spr(SPR_PPR, t0);
1473 spr_store_dump_spr(SPR_PPR);
1474 }
1475 #endif
1476
1477 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
1478 GEN_OPCODE(name, opc1, opc2, opc3, inval, type, PPC_NONE)
1479
1480 #define GEN_HANDLER_E(name, opc1, opc2, opc3, inval, type, type2) \
1481 GEN_OPCODE(name, opc1, opc2, opc3, inval, type, type2)
1482
1483 #define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type) \
1484 GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, PPC_NONE)
1485
1486 #define GEN_HANDLER2_E(name, onam, opc1, opc2, opc3, inval, type, type2) \
1487 GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, type2)
1488
1489 #define GEN_HANDLER_E_2(name, opc1, opc2, opc3, opc4, inval, type, type2) \
1490 GEN_OPCODE3(name, opc1, opc2, opc3, opc4, inval, type, type2)
1491
1492 #define GEN_HANDLER2_E_2(name, onam, opc1, opc2, opc3, opc4, inval, typ, typ2) \
1493 GEN_OPCODE4(name, onam, opc1, opc2, opc3, opc4, inval, typ, typ2)
1494
1495 typedef struct opcode_t {
1496 unsigned char opc1, opc2, opc3, opc4;
1497 #if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */
1498 unsigned char pad[4];
1499 #endif
1500 opc_handler_t handler;
1501 const char *oname;
1502 } opcode_t;
1503
1504 static void gen_priv_opc(DisasContext *ctx)
1505 {
1506 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1507 }
1508
1509 /* Helpers for priv. check */
1510 #define GEN_PRIV(CTX) \
1511 do { \
1512 gen_priv_opc(CTX); return; \
1513 } while (0)
1514
1515 #if defined(CONFIG_USER_ONLY)
1516 #define CHK_HV(CTX) GEN_PRIV(CTX)
1517 #define CHK_SV(CTX) GEN_PRIV(CTX)
1518 #define CHK_HVRM(CTX) GEN_PRIV(CTX)
1519 #else
1520 #define CHK_HV(CTX) \
1521 do { \
1522 if (unlikely(ctx->pr || !ctx->hv)) {\
1523 GEN_PRIV(CTX); \
1524 } \
1525 } while (0)
1526 #define CHK_SV(CTX) \
1527 do { \
1528 if (unlikely(ctx->pr)) { \
1529 GEN_PRIV(CTX); \
1530 } \
1531 } while (0)
1532 #define CHK_HVRM(CTX) \
1533 do { \
1534 if (unlikely(ctx->pr || !ctx->hv || ctx->dr)) { \
1535 GEN_PRIV(CTX); \
1536 } \
1537 } while (0)
1538 #endif
1539
1540 #define CHK_NONE(CTX)
1541
1542 /*****************************************************************************/
1543 /* PowerPC instructions table */
1544
1545 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2) \
1546 { \
1547 .opc1 = op1, \
1548 .opc2 = op2, \
1549 .opc3 = op3, \
1550 .opc4 = 0xff, \
1551 .handler = { \
1552 .inval1 = invl, \
1553 .type = _typ, \
1554 .type2 = _typ2, \
1555 .handler = &gen_##name, \
1556 }, \
1557 .oname = stringify(name), \
1558 }
1559 #define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2) \
1560 { \
1561 .opc1 = op1, \
1562 .opc2 = op2, \
1563 .opc3 = op3, \
1564 .opc4 = 0xff, \
1565 .handler = { \
1566 .inval1 = invl1, \
1567 .inval2 = invl2, \
1568 .type = _typ, \
1569 .type2 = _typ2, \
1570 .handler = &gen_##name, \
1571 }, \
1572 .oname = stringify(name), \
1573 }
1574 #define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2) \
1575 { \
1576 .opc1 = op1, \
1577 .opc2 = op2, \
1578 .opc3 = op3, \
1579 .opc4 = 0xff, \
1580 .handler = { \
1581 .inval1 = invl, \
1582 .type = _typ, \
1583 .type2 = _typ2, \
1584 .handler = &gen_##name, \
1585 }, \
1586 .oname = onam, \
1587 }
1588 #define GEN_OPCODE3(name, op1, op2, op3, op4, invl, _typ, _typ2) \
1589 { \
1590 .opc1 = op1, \
1591 .opc2 = op2, \
1592 .opc3 = op3, \
1593 .opc4 = op4, \
1594 .handler = { \
1595 .inval1 = invl, \
1596 .type = _typ, \
1597 .type2 = _typ2, \
1598 .handler = &gen_##name, \
1599 }, \
1600 .oname = stringify(name), \
1601 }
1602 #define GEN_OPCODE4(name, onam, op1, op2, op3, op4, invl, _typ, _typ2) \
1603 { \
1604 .opc1 = op1, \
1605 .opc2 = op2, \
1606 .opc3 = op3, \
1607 .opc4 = op4, \
1608 .handler = { \
1609 .inval1 = invl, \
1610 .type = _typ, \
1611 .type2 = _typ2, \
1612 .handler = &gen_##name, \
1613 }, \
1614 .oname = onam, \
1615 }
1616
1617 /* Invalid instruction */
1618 static void gen_invalid(DisasContext *ctx)
1619 {
1620 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1621 }
1622
1623 static opc_handler_t invalid_handler = {
1624 .inval1 = 0xFFFFFFFF,
1625 .inval2 = 0xFFFFFFFF,
1626 .type = PPC_NONE,
1627 .type2 = PPC_NONE,
1628 .handler = gen_invalid,
1629 };
1630
1631 /*** Integer comparison ***/
1632
1633 static inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf)
1634 {
1635 TCGv t0 = tcg_temp_new();
1636 TCGv_i32 t = tcg_temp_new_i32();
1637
1638 tcg_gen_movcond_tl((s ? TCG_COND_LT : TCG_COND_LTU),
1639 t0, arg0, arg1,
1640 tcg_constant_tl(CRF_LT), tcg_constant_tl(CRF_EQ));
1641 tcg_gen_movcond_tl((s ? TCG_COND_GT : TCG_COND_GTU),
1642 t0, arg0, arg1, tcg_constant_tl(CRF_GT), t0);
1643
1644 tcg_gen_trunc_tl_i32(t, t0);
1645 tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_so);
1646 tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t);
1647 }
1648
1649 static inline void gen_op_cmpi(TCGv arg0, target_ulong arg1, int s, int crf)
1650 {
1651 TCGv t0 = tcg_constant_tl(arg1);
1652 gen_op_cmp(arg0, t0, s, crf);
1653 }
1654
1655 static inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int s, int crf)
1656 {
1657 TCGv t0, t1;
1658 t0 = tcg_temp_new();
1659 t1 = tcg_temp_new();
1660 if (s) {
1661 tcg_gen_ext32s_tl(t0, arg0);
1662 tcg_gen_ext32s_tl(t1, arg1);
1663 } else {
1664 tcg_gen_ext32u_tl(t0, arg0);
1665 tcg_gen_ext32u_tl(t1, arg1);
1666 }
1667 gen_op_cmp(t0, t1, s, crf);
1668 }
1669
1670 static inline void gen_op_cmpi32(TCGv arg0, target_ulong arg1, int s, int crf)
1671 {
1672 TCGv t0 = tcg_constant_tl(arg1);
1673 gen_op_cmp32(arg0, t0, s, crf);
1674 }
1675
1676 static inline void gen_set_Rc0(DisasContext *ctx, TCGv reg)
1677 {
1678 if (NARROW_MODE(ctx)) {
1679 gen_op_cmpi32(reg, 0, 1, 0);
1680 } else {
1681 gen_op_cmpi(reg, 0, 1, 0);
1682 }
1683 }
1684
1685 /*** Integer arithmetic ***/
1686
1687 static inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0,
1688 TCGv arg1, TCGv arg2, int sub)
1689 {
1690 TCGv t0 = tcg_temp_new();
1691
1692 tcg_gen_xor_tl(cpu_ov, arg0, arg2);
1693 tcg_gen_xor_tl(t0, arg1, arg2);
1694 if (sub) {
1695 tcg_gen_and_tl(cpu_ov, cpu_ov, t0);
1696 } else {
1697 tcg_gen_andc_tl(cpu_ov, cpu_ov, t0);
1698 }
1699 if (NARROW_MODE(ctx)) {
1700 tcg_gen_extract_tl(cpu_ov, cpu_ov, 31, 1);
1701 if (is_isa300(ctx)) {
1702 tcg_gen_mov_tl(cpu_ov32, cpu_ov);
1703 }
1704 } else {
1705 if (is_isa300(ctx)) {
1706 tcg_gen_extract_tl(cpu_ov32, cpu_ov, 31, 1);
1707 }
1708 tcg_gen_extract_tl(cpu_ov, cpu_ov, TARGET_LONG_BITS - 1, 1);
1709 }
1710 tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
1711 }
1712
1713 static inline void gen_op_arith_compute_ca32(DisasContext *ctx,
1714 TCGv res, TCGv arg0, TCGv arg1,
1715 TCGv ca32, int sub)
1716 {
1717 TCGv t0;
1718
1719 if (!is_isa300(ctx)) {
1720 return;
1721 }
1722
1723 t0 = tcg_temp_new();
1724 if (sub) {
1725 tcg_gen_eqv_tl(t0, arg0, arg1);
1726 } else {
1727 tcg_gen_xor_tl(t0, arg0, arg1);
1728 }
1729 tcg_gen_xor_tl(t0, t0, res);
1730 tcg_gen_extract_tl(ca32, t0, 32, 1);
1731 }
1732
1733 /* Common add function */
1734 static inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1,
1735 TCGv arg2, TCGv ca, TCGv ca32,
1736 bool add_ca, bool compute_ca,
1737 bool compute_ov, bool compute_rc0)
1738 {
1739 TCGv t0 = ret;
1740
1741 if (compute_ca || compute_ov) {
1742 t0 = tcg_temp_new();
1743 }
1744
1745 if (compute_ca) {
1746 if (NARROW_MODE(ctx)) {
1747 /*
1748 * Caution: a non-obvious corner case of the spec is that
1749 * we must produce the *entire* 64-bit addition, but
1750 * produce the carry into bit 32.
1751 */
1752 TCGv t1 = tcg_temp_new();
1753 tcg_gen_xor_tl(t1, arg1, arg2); /* add without carry */
1754 tcg_gen_add_tl(t0, arg1, arg2);
1755 if (add_ca) {
1756 tcg_gen_add_tl(t0, t0, ca);
1757 }
1758 tcg_gen_xor_tl(ca, t0, t1); /* bits changed w/ carry */
1759 tcg_gen_extract_tl(ca, ca, 32, 1);
1760 if (is_isa300(ctx)) {
1761 tcg_gen_mov_tl(ca32, ca);
1762 }
1763 } else {
1764 if (add_ca) {
1765 tcg_gen_addcio_tl(t0, ca, arg1, arg2, ca);
1766 } else {
1767 TCGv zero = tcg_constant_tl(0);
1768 tcg_gen_add2_tl(t0, ca, arg1, zero, arg2, zero);
1769 }
1770 gen_op_arith_compute_ca32(ctx, t0, arg1, arg2, ca32, 0);
1771 }
1772 } else {
1773 tcg_gen_add_tl(t0, arg1, arg2);
1774 if (add_ca) {
1775 tcg_gen_add_tl(t0, t0, ca);
1776 }
1777 }
1778
1779 if (compute_ov) {
1780 gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 0);
1781 }
1782 if (unlikely(compute_rc0)) {
1783 gen_set_Rc0(ctx, t0);
1784 }
1785
1786 if (t0 != ret) {
1787 tcg_gen_mov_tl(ret, t0);
1788 }
1789 }
1790
1791 static inline void gen_op_arith_divw(DisasContext *ctx, TCGv ret,
1792 TCGv arg1, TCGv arg2, bool sign,
1793 bool compute_ov, bool compute_rc0)
1794 {
1795 TCGv_i32 t0 = tcg_temp_new_i32();
1796 TCGv_i32 t1 = tcg_temp_new_i32();
1797 TCGv_i32 t2 = tcg_temp_new_i32();
1798 TCGv_i32 t3 = tcg_temp_new_i32();
1799
1800 tcg_gen_trunc_tl_i32(t0, arg1);
1801 tcg_gen_trunc_tl_i32(t1, arg2);
1802 if (sign) {
1803 tcg_gen_setcondi_i32(TCG_COND_EQ, t2, t0, INT_MIN);
1804 tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, -1);
1805 tcg_gen_and_i32(t2, t2, t3);
1806 tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, 0);
1807 tcg_gen_or_i32(t2, t2, t3);
1808 tcg_gen_movi_i32(t3, 0);
1809 tcg_gen_movcond_i32(TCG_COND_NE, t1, t2, t3, t2, t1);
1810 tcg_gen_div_i32(t3, t0, t1);
1811 tcg_gen_extu_i32_tl(ret, t3);
1812 } else {
1813 tcg_gen_setcondi_i32(TCG_COND_EQ, t2, t1, 0);
1814 tcg_gen_movi_i32(t3, 0);
1815 tcg_gen_movcond_i32(TCG_COND_NE, t1, t2, t3, t2, t1);
1816 tcg_gen_divu_i32(t3, t0, t1);
1817 tcg_gen_extu_i32_tl(ret, t3);
1818 }
1819 if (compute_ov) {
1820 tcg_gen_extu_i32_tl(cpu_ov, t2);
1821 if (is_isa300(ctx)) {
1822 tcg_gen_extu_i32_tl(cpu_ov32, t2);
1823 }
1824 tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
1825 }
1826
1827 if (unlikely(compute_rc0)) {
1828 gen_set_Rc0(ctx, ret);
1829 }
1830 }
1831
1832 #if defined(TARGET_PPC64)
1833 static inline void gen_op_arith_divd(DisasContext *ctx, TCGv ret,
1834 TCGv arg1, TCGv arg2, bool sign,
1835 bool compute_ov, bool compute_rc0)
1836 {
1837 TCGv_i64 t0 = tcg_temp_new_i64();
1838 TCGv_i64 t1 = tcg_temp_new_i64();
1839 TCGv_i64 t2 = tcg_temp_new_i64();
1840 TCGv_i64 t3 = tcg_temp_new_i64();
1841
1842 tcg_gen_mov_i64(t0, arg1);
1843 tcg_gen_mov_i64(t1, arg2);
1844 if (sign) {
1845 tcg_gen_setcondi_i64(TCG_COND_EQ, t2, t0, INT64_MIN);
1846 tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, -1);
1847 tcg_gen_and_i64(t2, t2, t3);
1848 tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, 0);
1849 tcg_gen_or_i64(t2, t2, t3);
1850 tcg_gen_movi_i64(t3, 0);
1851 tcg_gen_movcond_i64(TCG_COND_NE, t1, t2, t3, t2, t1);
1852 tcg_gen_div_i64(ret, t0, t1);
1853 } else {
1854 tcg_gen_setcondi_i64(TCG_COND_EQ, t2, t1, 0);
1855 tcg_gen_movi_i64(t3, 0);
1856 tcg_gen_movcond_i64(TCG_COND_NE, t1, t2, t3, t2, t1);
1857 tcg_gen_divu_i64(ret, t0, t1);
1858 }
1859 if (compute_ov) {
1860 tcg_gen_mov_tl(cpu_ov, t2);
1861 if (is_isa300(ctx)) {
1862 tcg_gen_mov_tl(cpu_ov32, t2);
1863 }
1864 tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
1865 }
1866
1867 if (unlikely(compute_rc0)) {
1868 gen_set_Rc0(ctx, ret);
1869 }
1870 }
1871 #endif
1872
1873 static inline void gen_op_arith_modw(DisasContext *ctx, TCGv ret, TCGv arg1,
1874 TCGv arg2, int sign)
1875 {
1876 TCGv_i32 t0 = tcg_temp_new_i32();
1877 TCGv_i32 t1 = tcg_temp_new_i32();
1878
1879 tcg_gen_trunc_tl_i32(t0, arg1);
1880 tcg_gen_trunc_tl_i32(t1, arg2);
1881 if (sign) {
1882 TCGv_i32 t2 = tcg_temp_new_i32();
1883 TCGv_i32 t3 = tcg_temp_new_i32();
1884 tcg_gen_setcondi_i32(TCG_COND_EQ, t2, t0, INT_MIN);
1885 tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, -1);
1886 tcg_gen_and_i32(t2, t2, t3);
1887 tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, 0);
1888 tcg_gen_or_i32(t2, t2, t3);
1889 tcg_gen_movi_i32(t3, 0);
1890 tcg_gen_movcond_i32(TCG_COND_NE, t1, t2, t3, t2, t1);
1891 tcg_gen_rem_i32(t3, t0, t1);
1892 tcg_gen_ext_i32_tl(ret, t3);
1893 } else {
1894 TCGv_i32 t2 = tcg_constant_i32(1);
1895 TCGv_i32 t3 = tcg_constant_i32(0);
1896 tcg_gen_movcond_i32(TCG_COND_EQ, t1, t1, t3, t2, t1);
1897 tcg_gen_remu_i32(t0, t0, t1);
1898 tcg_gen_extu_i32_tl(ret, t0);
1899 }
1900 }
1901
1902 #if defined(TARGET_PPC64)
1903 static inline void gen_op_arith_modd(DisasContext *ctx, TCGv ret, TCGv arg1,
1904 TCGv arg2, int sign)
1905 {
1906 TCGv_i64 t0 = tcg_temp_new_i64();
1907 TCGv_i64 t1 = tcg_temp_new_i64();
1908
1909 tcg_gen_mov_i64(t0, arg1);
1910 tcg_gen_mov_i64(t1, arg2);
1911 if (sign) {
1912 TCGv_i64 t2 = tcg_temp_new_i64();
1913 TCGv_i64 t3 = tcg_temp_new_i64();
1914 tcg_gen_setcondi_i64(TCG_COND_EQ, t2, t0, INT64_MIN);
1915 tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, -1);
1916 tcg_gen_and_i64(t2, t2, t3);
1917 tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, 0);
1918 tcg_gen_or_i64(t2, t2, t3);
1919 tcg_gen_movi_i64(t3, 0);
1920 tcg_gen_movcond_i64(TCG_COND_NE, t1, t2, t3, t2, t1);
1921 tcg_gen_rem_i64(ret, t0, t1);
1922 } else {
1923 TCGv_i64 t2 = tcg_constant_i64(1);
1924 TCGv_i64 t3 = tcg_constant_i64(0);
1925 tcg_gen_movcond_i64(TCG_COND_EQ, t1, t1, t3, t2, t1);
1926 tcg_gen_remu_i64(ret, t0, t1);
1927 }
1928 }
1929 #endif
1930
1931 /* Common subf function */
1932 static inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1,
1933 TCGv arg2, bool add_ca, bool compute_ca,
1934 bool compute_ov, bool compute_rc0)
1935 {
1936 TCGv t0 = ret;
1937
1938 if (compute_ca || compute_ov) {
1939 t0 = tcg_temp_new();
1940 }
1941
1942 if (compute_ca) {
1943 /* dest = ~arg1 + arg2 [+ ca]. */
1944 if (NARROW_MODE(ctx)) {
1945 /*
1946 * Caution: a non-obvious corner case of the spec is that
1947 * we must produce the *entire* 64-bit addition, but
1948 * produce the carry into bit 32.
1949 */
1950 TCGv inv1 = tcg_temp_new();
1951 TCGv t1 = tcg_temp_new();
1952 tcg_gen_not_tl(inv1, arg1);
1953 if (add_ca) {
1954 tcg_gen_add_tl(t0, arg2, cpu_ca);
1955 } else {
1956 tcg_gen_addi_tl(t0, arg2, 1);
1957 }
1958 tcg_gen_xor_tl(t1, arg2, inv1); /* add without carry */
1959 tcg_gen_add_tl(t0, t0, inv1);
1960 tcg_gen_xor_tl(cpu_ca, t0, t1); /* bits changes w/ carry */
1961 tcg_gen_extract_tl(cpu_ca, cpu_ca, 32, 1);
1962 if (is_isa300(ctx)) {
1963 tcg_gen_mov_tl(cpu_ca32, cpu_ca);
1964 }
1965 } else if (add_ca) {
1966 TCGv inv1 = tcg_temp_new();
1967 tcg_gen_not_tl(inv1, arg1);
1968 tcg_gen_addcio_tl(t0, cpu_ca, arg2, inv1, cpu_ca);
1969 gen_op_arith_compute_ca32(ctx, t0, inv1, arg2, cpu_ca32, 0);
1970 } else {
1971 tcg_gen_setcond_tl(TCG_COND_GEU, cpu_ca, arg2, arg1);
1972 tcg_gen_sub_tl(t0, arg2, arg1);
1973 gen_op_arith_compute_ca32(ctx, t0, arg1, arg2, cpu_ca32, 1);
1974 }
1975 } else if (add_ca) {
1976 /*
1977 * Since we're ignoring carry-out, we can simplify the
1978 * standard ~arg1 + arg2 + ca to arg2 - arg1 + ca - 1.
1979 */
1980 tcg_gen_sub_tl(t0, arg2, arg1);
1981 tcg_gen_add_tl(t0, t0, cpu_ca);
1982 tcg_gen_subi_tl(t0, t0, 1);
1983 } else {
1984 tcg_gen_sub_tl(t0, arg2, arg1);
1985 }
1986
1987 if (compute_ov) {
1988 gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 1);
1989 }
1990 if (unlikely(compute_rc0)) {
1991 gen_set_Rc0(ctx, t0);
1992 }
1993
1994 if (t0 != ret) {
1995 tcg_gen_mov_tl(ret, t0);
1996 }
1997 }
1998
1999 /*** Integer logical ***/
2000
2001 #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
2002 static void gen_pause(DisasContext *ctx)
2003 {
2004 TCGv_i32 t0 = tcg_constant_i32(0);
2005 tcg_gen_st_i32(t0, tcg_env,
2006 -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted));
2007
2008 /* Stop translation, this gives other CPUs a chance to run */
2009 gen_exception_nip(ctx, EXCP_HLT, ctx->base.pc_next);
2010 }
2011 #endif /* defined(TARGET_PPC64) */
2012
2013 /*** Integer rotate ***/
2014
2015 /* rlwnm & rlwnm. */
2016 static void gen_rlwnm(DisasContext *ctx)
2017 {
2018 TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
2019 TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
2020 TCGv t_rb = cpu_gpr[rB(ctx->opcode)];
2021 uint32_t mb = MB(ctx->opcode);
2022 uint32_t me = ME(ctx->opcode);
2023 target_ulong mask;
2024 bool mask_in_32b = true;
2025
2026 #if defined(TARGET_PPC64)
2027 mb += 32;
2028 me += 32;
2029 #endif
2030 mask = MASK(mb, me);
2031
2032 #if defined(TARGET_PPC64)
2033 if (mask > 0xffffffffu) {
2034 mask_in_32b = false;
2035 }
2036 #endif
2037 if (mask_in_32b) {
2038 TCGv_i32 t0 = tcg_temp_new_i32();
2039 TCGv_i32 t1 = tcg_temp_new_i32();
2040 tcg_gen_trunc_tl_i32(t0, t_rb);
2041 tcg_gen_trunc_tl_i32(t1, t_rs);
2042 tcg_gen_andi_i32(t0, t0, 0x1f);
2043 tcg_gen_rotl_i32(t1, t1, t0);
2044 tcg_gen_extu_i32_tl(t_ra, t1);
2045 } else {
2046 #if defined(TARGET_PPC64)
2047 TCGv_i64 t0 = tcg_temp_new_i64();
2048 tcg_gen_andi_i64(t0, t_rb, 0x1f);
2049 tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32);
2050 tcg_gen_rotl_i64(t_ra, t_ra, t0);
2051 #else
2052 g_assert_not_reached();
2053 #endif
2054 }
2055
2056 tcg_gen_andi_tl(t_ra, t_ra, mask);
2057
2058 if (unlikely(Rc(ctx->opcode) != 0)) {
2059 gen_set_Rc0(ctx, t_ra);
2060 }
2061 }
2062
2063 #if defined(TARGET_PPC64)
2064 #define GEN_PPC64_R2(name, opc1, opc2) \
2065 static void glue(gen_, name##0)(DisasContext *ctx) \
2066 { \
2067 gen_##name(ctx, 0); \
2068 } \
2069 \
2070 static void glue(gen_, name##1)(DisasContext *ctx) \
2071 { \
2072 gen_##name(ctx, 1); \
2073 }
2074 #define GEN_PPC64_R4(name, opc1, opc2) \
2075 static void glue(gen_, name##0)(DisasContext *ctx) \
2076 { \
2077 gen_##name(ctx, 0, 0); \
2078 } \
2079 \
2080 static void glue(gen_, name##1)(DisasContext *ctx) \
2081 { \
2082 gen_##name(ctx, 0, 1); \
2083 } \
2084 \
2085 static void glue(gen_, name##2)(DisasContext *ctx) \
2086 { \
2087 gen_##name(ctx, 1, 0); \
2088 } \
2089 \
2090 static void glue(gen_, name##3)(DisasContext *ctx) \
2091 { \
2092 gen_##name(ctx, 1, 1); \
2093 }
2094
2095 static void gen_rldinm(DisasContext *ctx, int mb, int me, int sh)
2096 {
2097 TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
2098 TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
2099 int len = me - mb + 1;
2100 int rsh = (64 - sh) & 63;
2101
2102 if (sh != 0 && len > 0 && me == (63 - sh)) {
2103 tcg_gen_deposit_z_tl(t_ra, t_rs, sh, len);
2104 } else if (me == 63 && rsh + len <= 64) {
2105 tcg_gen_extract_tl(t_ra, t_rs, rsh, len);
2106 } else {
2107 tcg_gen_rotli_tl(t_ra, t_rs, sh);
2108 tcg_gen_andi_tl(t_ra, t_ra, MASK(mb, me));
2109 }
2110 if (unlikely(Rc(ctx->opcode) != 0)) {
2111 gen_set_Rc0(ctx, t_ra);
2112 }
2113 }
2114
2115 /* rldicl - rldicl. */
2116 static inline void gen_rldicl(DisasContext *ctx, int mbn, int shn)
2117 {
2118 uint32_t sh, mb;
2119
2120 sh = SH(ctx->opcode) | (shn << 5);
2121 mb = MB(ctx->opcode) | (mbn << 5);
2122 gen_rldinm(ctx, mb, 63, sh);
2123 }
2124 GEN_PPC64_R4(rldicl, 0x1E, 0x00);
2125
2126 /* rldicr - rldicr. */
2127 static inline void gen_rldicr(DisasContext *ctx, int men, int shn)
2128 {
2129 uint32_t sh, me;
2130
2131 sh = SH(ctx->opcode) | (shn << 5);
2132 me = MB(ctx->opcode) | (men << 5);
2133 gen_rldinm(ctx, 0, me, sh);
2134 }
2135 GEN_PPC64_R4(rldicr, 0x1E, 0x02);
2136
2137 /* rldic - rldic. */
2138 static inline void gen_rldic(DisasContext *ctx, int mbn, int shn)
2139 {
2140 uint32_t sh, mb;
2141
2142 sh = SH(ctx->opcode) | (shn << 5);
2143 mb = MB(ctx->opcode) | (mbn << 5);
2144 gen_rldinm(ctx, mb, 63 - sh, sh);
2145 }
2146 GEN_PPC64_R4(rldic, 0x1E, 0x04);
2147
2148 static void gen_rldnm(DisasContext *ctx, int mb, int me)
2149 {
2150 TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
2151 TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
2152 TCGv t_rb = cpu_gpr[rB(ctx->opcode)];
2153 TCGv t0;
2154
2155 t0 = tcg_temp_new();
2156 tcg_gen_andi_tl(t0, t_rb, 0x3f);
2157 tcg_gen_rotl_tl(t_ra, t_rs, t0);
2158
2159 tcg_gen_andi_tl(t_ra, t_ra, MASK(mb, me));
2160 if (unlikely(Rc(ctx->opcode) != 0)) {
2161 gen_set_Rc0(ctx, t_ra);
2162 }
2163 }
2164
2165 /* rldcl - rldcl. */
2166 static inline void gen_rldcl(DisasContext *ctx, int mbn)
2167 {
2168 uint32_t mb;
2169
2170 mb = MB(ctx->opcode) | (mbn << 5);
2171 gen_rldnm(ctx, mb, 63);
2172 }
2173 GEN_PPC64_R2(rldcl, 0x1E, 0x08);
2174
2175 /* rldcr - rldcr. */
2176 static inline void gen_rldcr(DisasContext *ctx, int men)
2177 {
2178 uint32_t me;
2179
2180 me = MB(ctx->opcode) | (men << 5);
2181 gen_rldnm(ctx, 0, me);
2182 }
2183 GEN_PPC64_R2(rldcr, 0x1E, 0x09);
2184
2185 /* rldimi - rldimi. */
2186 static void gen_rldimi(DisasContext *ctx, int mbn, int shn)
2187 {
2188 TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
2189 TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
2190 uint32_t sh = SH(ctx->opcode) | (shn << 5);
2191 uint32_t mb = MB(ctx->opcode) | (mbn << 5);
2192 uint32_t me = 63 - sh;
2193
2194 if (mb <= me) {
2195 tcg_gen_deposit_tl(t_ra, t_ra, t_rs, sh, me - mb + 1);
2196 } else {
2197 target_ulong mask = MASK(mb, me);
2198 TCGv t1 = tcg_temp_new();
2199
2200 tcg_gen_rotli_tl(t1, t_rs, sh);
2201 tcg_gen_andi_tl(t1, t1, mask);
2202 tcg_gen_andi_tl(t_ra, t_ra, ~mask);
2203 tcg_gen_or_tl(t_ra, t_ra, t1);
2204 }
2205 if (unlikely(Rc(ctx->opcode) != 0)) {
2206 gen_set_Rc0(ctx, t_ra);
2207 }
2208 }
2209 GEN_PPC64_R4(rldimi, 0x1E, 0x06);
2210 #endif
2211
2212 /*** Addressing modes ***/
2213 /* Register indirect with immediate index : EA = (rA|0) + SIMM */
2214 static inline void gen_addr_imm_index(DisasContext *ctx, TCGv EA,
2215 target_long maskl)
2216 {
2217 target_long simm = SIMM(ctx->opcode);
2218
2219 simm &= ~maskl;
2220 if (rA(ctx->opcode) == 0) {
2221 if (NARROW_MODE(ctx)) {
2222 simm = (uint32_t)simm;
2223 }
2224 tcg_gen_movi_tl(EA, simm);
2225 } else if (likely(simm != 0)) {
2226 tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm);
2227 if (NARROW_MODE(ctx)) {
2228 tcg_gen_ext32u_tl(EA, EA);
2229 }
2230 } else {
2231 if (NARROW_MODE(ctx)) {
2232 tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2233 } else {
2234 tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2235 }
2236 }
2237 }
2238
2239 static inline void gen_addr_reg_index(DisasContext *ctx, TCGv EA)
2240 {
2241 if (rA(ctx->opcode) == 0) {
2242 if (NARROW_MODE(ctx)) {
2243 tcg_gen_ext32u_tl(EA, cpu_gpr[rB(ctx->opcode)]);
2244 } else {
2245 tcg_gen_mov_tl(EA, cpu_gpr[rB(ctx->opcode)]);
2246 }
2247 } else {
2248 tcg_gen_add_tl(EA, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
2249 if (NARROW_MODE(ctx)) {
2250 tcg_gen_ext32u_tl(EA, EA);
2251 }
2252 }
2253 }
2254
2255 static inline void gen_addr_register(DisasContext *ctx, TCGv EA)
2256 {
2257 if (rA(ctx->opcode) == 0) {
2258 tcg_gen_movi_tl(EA, 0);
2259 } else if (NARROW_MODE(ctx)) {
2260 tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2261 } else {
2262 tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2263 }
2264 }
2265
2266 static inline void gen_addr_add(DisasContext *ctx, TCGv ret, TCGv arg1,
2267 target_long val)
2268 {
2269 tcg_gen_addi_tl(ret, arg1, val);
2270 if (NARROW_MODE(ctx)) {
2271 tcg_gen_ext32u_tl(ret, ret);
2272 }
2273 }
2274
2275 static inline void gen_align_no_le(DisasContext *ctx)
2276 {
2277 gen_exception_err(ctx, POWERPC_EXCP_ALIGN,
2278 (ctx->opcode & 0x03FF0000) | POWERPC_EXCP_ALIGN_LE);
2279 }
2280
2281 /* EA <- {(ra == 0) ? 0 : GPR[ra]} + displ */
2282 static TCGv do_ea_calc(DisasContext *ctx, int ra, TCGv displ)
2283 {
2284 TCGv ea = tcg_temp_new();
2285 if (ra) {
2286 tcg_gen_add_tl(ea, cpu_gpr[ra], displ);
2287 } else {
2288 tcg_gen_mov_tl(ea, displ);
2289 }
2290 if (NARROW_MODE(ctx)) {
2291 tcg_gen_ext32u_tl(ea, ea);
2292 }
2293 return ea;
2294 }
2295
2296 /* EA <- (ra == 0) ? 0 : GPR[ra] */
2297 static TCGv do_ea_calc_ra(DisasContext *ctx, int ra)
2298 {
2299 TCGv EA = tcg_temp_new();
2300 if (!ra) {
2301 tcg_gen_movi_tl(EA, 0);
2302 } else if (NARROW_MODE(ctx)) {
2303 tcg_gen_ext32u_tl(EA, cpu_gpr[ra]);
2304 } else {
2305 tcg_gen_mov_tl(EA, cpu_gpr[ra]);
2306 }
2307 return EA;
2308 }
2309
2310 /*** Integer load ***/
2311 #define DEF_MEMOP(op) ((op) | ctx->default_tcg_memop_mask)
2312 #define BSWAP_MEMOP(op) ((op) | (ctx->default_tcg_memop_mask ^ MO_BSWAP))
2313
2314 #define GEN_QEMU_LOAD_TL(ldop, op) \
2315 static void glue(gen_qemu_, ldop)(DisasContext *ctx, \
2316 TCGv val, \
2317 TCGv addr) \
2318 { \
2319 tcg_gen_qemu_ld_tl(val, addr, ctx->mem_idx, op); \
2320 }
2321
2322 GEN_QEMU_LOAD_TL(ld8u, DEF_MEMOP(MO_UB))
2323 GEN_QEMU_LOAD_TL(ld16u, DEF_MEMOP(MO_UW))
2324 GEN_QEMU_LOAD_TL(ld16s, DEF_MEMOP(MO_SW))
2325 GEN_QEMU_LOAD_TL(ld32u, DEF_MEMOP(MO_UL))
2326 GEN_QEMU_LOAD_TL(ld32s, DEF_MEMOP(MO_SL))
2327
2328 GEN_QEMU_LOAD_TL(ld16ur, BSWAP_MEMOP(MO_UW))
2329 GEN_QEMU_LOAD_TL(ld32ur, BSWAP_MEMOP(MO_UL))
2330
2331 #define GEN_QEMU_LOAD_64(ldop, op) \
2332 static void glue(gen_qemu_, glue(ldop, _i64))(DisasContext *ctx, \
2333 TCGv_i64 val, \
2334 TCGv addr) \
2335 { \
2336 tcg_gen_qemu_ld_i64(val, addr, ctx->mem_idx, op); \
2337 }
2338
2339 GEN_QEMU_LOAD_64(ld8u, DEF_MEMOP(MO_UB))
2340 GEN_QEMU_LOAD_64(ld16u, DEF_MEMOP(MO_UW))
2341 GEN_QEMU_LOAD_64(ld32u, DEF_MEMOP(MO_UL))
2342 GEN_QEMU_LOAD_64(ld32s, DEF_MEMOP(MO_SL))
2343 GEN_QEMU_LOAD_64(ld64, DEF_MEMOP(MO_UQ))
2344
2345 #if defined(TARGET_PPC64)
2346 GEN_QEMU_LOAD_64(ld64ur, BSWAP_MEMOP(MO_UQ))
2347 #endif
2348
2349 #define GEN_QEMU_STORE_TL(stop, op) \
2350 static void glue(gen_qemu_, stop)(DisasContext *ctx, \
2351 TCGv val, \
2352 TCGv addr) \
2353 { \
2354 tcg_gen_qemu_st_tl(val, addr, ctx->mem_idx, op); \
2355 }
2356
2357 #if defined(TARGET_PPC64) || !defined(CONFIG_USER_ONLY)
2358 GEN_QEMU_STORE_TL(st8, DEF_MEMOP(MO_UB))
2359 #endif
2360 GEN_QEMU_STORE_TL(st16, DEF_MEMOP(MO_UW))
2361 GEN_QEMU_STORE_TL(st32, DEF_MEMOP(MO_UL))
2362
2363 GEN_QEMU_STORE_TL(st16r, BSWAP_MEMOP(MO_UW))
2364 GEN_QEMU_STORE_TL(st32r, BSWAP_MEMOP(MO_UL))
2365
2366 #define GEN_QEMU_STORE_64(stop, op) \
2367 static void glue(gen_qemu_, glue(stop, _i64))(DisasContext *ctx, \
2368 TCGv_i64 val, \
2369 TCGv addr) \
2370 { \
2371 tcg_gen_qemu_st_i64(val, addr, ctx->mem_idx, op); \
2372 }
2373
2374 GEN_QEMU_STORE_64(st8, DEF_MEMOP(MO_UB))
2375 GEN_QEMU_STORE_64(st16, DEF_MEMOP(MO_UW))
2376 GEN_QEMU_STORE_64(st32, DEF_MEMOP(MO_UL))
2377 GEN_QEMU_STORE_64(st64, DEF_MEMOP(MO_UQ))
2378
2379 #if defined(TARGET_PPC64)
2380 GEN_QEMU_STORE_64(st64r, BSWAP_MEMOP(MO_UQ))
2381 #endif
2382
2383 #define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk) \
2384 static void glue(gen_, name##x)(DisasContext *ctx) \
2385 { \
2386 TCGv EA; \
2387 chk(ctx); \
2388 gen_set_access_type(ctx, ACCESS_INT); \
2389 EA = tcg_temp_new(); \
2390 gen_addr_reg_index(ctx, EA); \
2391 gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \
2392 }
2393
2394 #define GEN_LDX(name, ldop, opc2, opc3, type) \
2395 GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_NONE)
2396
2397 #define GEN_LDX_HVRM(name, ldop, opc2, opc3, type) \
2398 GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_HVRM)
2399
2400 #define GEN_LDEPX(name, ldop, opc2, opc3) \
2401 static void glue(gen_, name##epx)(DisasContext *ctx) \
2402 { \
2403 TCGv EA; \
2404 CHK_SV(ctx); \
2405 gen_set_access_type(ctx, ACCESS_INT); \
2406 EA = tcg_temp_new(); \
2407 gen_addr_reg_index(ctx, EA); \
2408 tcg_gen_qemu_ld_tl(cpu_gpr[rD(ctx->opcode)], EA, PPC_TLB_EPID_LOAD, ldop);\
2409 }
2410
2411 GEN_LDEPX(lb, DEF_MEMOP(MO_UB), 0x1F, 0x02)
2412 GEN_LDEPX(lh, DEF_MEMOP(MO_UW), 0x1F, 0x08)
2413 GEN_LDEPX(lw, DEF_MEMOP(MO_UL), 0x1F, 0x00)
2414 #if defined(TARGET_PPC64)
2415 GEN_LDEPX(ld, DEF_MEMOP(MO_UQ), 0x1D, 0x00)
2416 #endif
2417
2418 #if defined(TARGET_PPC64)
2419 /* CI load/store variants */
2420 GEN_LDX_HVRM(ldcix, ld64_i64, 0x15, 0x1b, PPC_CILDST)
2421 GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x15, PPC_CILDST)
2422 GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
2423 GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
2424 #endif
2425
2426 #define GEN_STEPX(name, stop, opc2, opc3) \
2427 static void glue(gen_, name##epx)(DisasContext *ctx) \
2428 { \
2429 TCGv EA; \
2430 CHK_SV(ctx); \
2431 gen_set_access_type(ctx, ACCESS_INT); \
2432 EA = tcg_temp_new(); \
2433 gen_addr_reg_index(ctx, EA); \
2434 tcg_gen_qemu_st_tl( \
2435 cpu_gpr[rD(ctx->opcode)], EA, PPC_TLB_EPID_STORE, stop); \
2436 }
2437
2438 GEN_STEPX(stb, DEF_MEMOP(MO_UB), 0x1F, 0x06)
2439 GEN_STEPX(sth, DEF_MEMOP(MO_UW), 0x1F, 0x0C)
2440 GEN_STEPX(stw, DEF_MEMOP(MO_UL), 0x1F, 0x04)
2441 #if defined(TARGET_PPC64)
2442 GEN_STEPX(std, DEF_MEMOP(MO_UQ), 0x1d, 0x04)
2443 #endif
2444
2445 /*** Integer load and store with byte reverse ***/
2446
2447 /* lhbrx */
2448 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER);
2449
2450 /* lwbrx */
2451 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
2452
2453 #if defined(TARGET_PPC64)
2454 /* ldbrx */
2455 GEN_LDX_E(ldbr, ld64ur_i64, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE);
2456 #endif /* TARGET_PPC64 */
2457
2458 #if !defined(CONFIG_USER_ONLY)
2459 static inline void gen_check_tlb_flush(DisasContext *ctx, bool global)
2460 {
2461 TCGv_i32 t;
2462 TCGLabel *l;
2463
2464 if (!ctx->lazy_tlb_flush) {
2465 return;
2466 }
2467 l = gen_new_label();
2468 t = tcg_temp_new_i32();
2469 tcg_gen_ld_i32(t, tcg_env, offsetof(CPUPPCState, tlb_need_flush));
2470 tcg_gen_brcondi_i32(TCG_COND_EQ, t, 0, l);
2471 if (global) {
2472 gen_helper_check_tlb_flush_global(tcg_env);
2473 } else {
2474 gen_helper_check_tlb_flush_local(tcg_env);
2475 }
2476 gen_set_label(l);
2477 if (global) {
2478 /*
2479 * Global TLB flush uses async-work which must run before the
2480 * next instruction, so this must be the last in the TB.
2481 */
2482 ctx->base.is_jmp = DISAS_EXIT_UPDATE;
2483 }
2484 }
2485 #else
2486 static inline void gen_check_tlb_flush(DisasContext *ctx, bool global) { }
2487 #endif
2488
2489 #if defined(TARGET_PPC64)
2490 static inline TCGv gen_write_bhrb(TCGv_ptr base, TCGv offset, TCGv mask, TCGv value)
2491 {
2492 TCGv_ptr tmp = tcg_temp_new_ptr();
2493
2494 /* add base and offset to get address of bhrb entry */
2495 tcg_gen_add_ptr(tmp, base, (TCGv_ptr)offset);
2496
2497 /* store value into bhrb at bhrb_offset */
2498 tcg_gen_st_i64(value, tmp, 0);
2499
2500 /* add 8 to current bhrb_offset */
2501 tcg_gen_addi_tl(offset, offset, 8);
2502
2503 /* apply offset mask */
2504 tcg_gen_and_tl(offset, offset, mask);
2505
2506 return offset;
2507 }
2508 #endif /* #if defined(TARGET_PPC64) */
2509
2510 static inline void gen_update_branch_history(DisasContext *ctx,
2511 target_ulong nip,
2512 TCGv target,
2513 target_long inst_type)
2514 {
2515 #if defined(TARGET_PPC64)
2516 TCGv_ptr base;
2517 TCGv tmp;
2518 TCGv offset;
2519 TCGv mask;
2520 TCGLabel *no_update;
2521
2522 if (ctx->has_cfar) {
2523 tcg_gen_movi_tl(cpu_cfar, nip);
2524 }
2525
2526 if (!ctx->has_bhrb ||
2527 !ctx->bhrb_enable ||
2528 inst_type == BHRB_TYPE_NORECORD) {
2529 return;
2530 }
2531
2532 tmp = tcg_temp_new();
2533 no_update = gen_new_label();
2534
2535 /* check for bhrb filtering */
2536 tcg_gen_ld_tl(tmp, tcg_env, offsetof(CPUPPCState, bhrb_filter));
2537 tcg_gen_andi_tl(tmp, tmp, inst_type);
2538 tcg_gen_brcondi_tl(TCG_COND_EQ, tmp, 0, no_update);
2539
2540 base = tcg_temp_new_ptr();
2541 offset = tcg_temp_new();
2542 mask = tcg_temp_new();
2543
2544 /* load bhrb base address */
2545 tcg_gen_ld_ptr(base, tcg_env, offsetof(CPUPPCState, bhrb_base));
2546
2547 /* load current bhrb_offset */
2548 tcg_gen_ld_tl(offset, tcg_env, offsetof(CPUPPCState, bhrb_offset));
2549
2550 /* load a BHRB offset mask */
2551 tcg_gen_ld_tl(mask, tcg_env, offsetof(CPUPPCState, bhrb_offset_mask));
2552
2553 offset = gen_write_bhrb(base, offset, mask, tcg_constant_i64(nip));
2554
2555 /* Also record the target address for XL-Form branches */
2556 if (inst_type & BHRB_TYPE_XL_FORM) {
2557
2558 /* Set the 'T' bit for target entries */
2559 tcg_gen_ori_tl(tmp, target, 0x2);
2560
2561 offset = gen_write_bhrb(base, offset, mask, tmp);
2562 }
2563
2564 /* save updated bhrb_offset for next time */
2565 tcg_gen_st_tl(offset, tcg_env, offsetof(CPUPPCState, bhrb_offset));
2566
2567 gen_set_label(no_update);
2568 #endif
2569 }
2570
2571 #if defined(TARGET_PPC64)
2572 static void pmu_count_insns(DisasContext *ctx)
2573 {
2574 /*
2575 * Do not bother calling the helper if the PMU isn't counting
2576 * instructions.
2577 */
2578 if (!ctx->pmu_insn_cnt) {
2579 return;
2580 }
2581
2582 #if !defined(CONFIG_USER_ONLY)
2583 TCGLabel *l;
2584 TCGv t0;
2585
2586 /*
2587 * The PMU insns_inc() helper stops the internal PMU timer if a
2588 * counter overflows happens. In that case, if the guest is
2589 * running with icount and we do not handle it beforehand,
2590 * the helper can trigger a 'bad icount read'.
2591 */
2592 translator_io_start(&ctx->base);
2593
2594 /* Avoid helper calls when only PMC5-6 are enabled. */
2595 if (!ctx->pmc_other) {
2596 l = gen_new_label();
2597 t0 = tcg_temp_new();
2598
2599 gen_load_spr(t0, SPR_POWER_PMC5);
2600 tcg_gen_addi_tl(t0, t0, ctx->base.num_insns);
2601 gen_store_spr(SPR_POWER_PMC5, t0);
2602 /* Check for overflow, if it's enabled */
2603 if (ctx->mmcr0_pmcjce) {
2604 tcg_gen_brcondi_tl(TCG_COND_LT, t0, PMC_COUNTER_NEGATIVE_VAL, l);
2605 gen_helper_handle_pmc5_overflow(tcg_env);
2606 }
2607
2608 gen_set_label(l);
2609 } else {
2610 gen_helper_insns_inc(tcg_env, tcg_constant_i32(ctx->base.num_insns));
2611 }
2612 #else
2613 /*
2614 * User mode can read (but not write) PMC5 and start/stop
2615 * the PMU via MMCR0_FC. In this case just increment
2616 * PMC5 with base.num_insns.
2617 */
2618 TCGv t0 = tcg_temp_new();
2619
2620 gen_load_spr(t0, SPR_POWER_PMC5);
2621 tcg_gen_addi_tl(t0, t0, ctx->base.num_insns);
2622 gen_store_spr(SPR_POWER_PMC5, t0);
2623 #endif /* #if !defined(CONFIG_USER_ONLY) */
2624 }
2625 #else
2626 static void pmu_count_insns(DisasContext *ctx)
2627 {
2628 }
2629 #endif /* #if defined(TARGET_PPC64) */
2630
2631 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
2632 {
2633 if (unlikely(ctx->singlestep_flags)) {
2634 return false;
2635 }
2636 return translator_use_goto_tb(&ctx->base, dest);
2637 }
2638
2639 static void gen_lookup_and_goto_ptr(DisasContext *ctx)
2640 {
2641 if (unlikely(ctx->singlestep_flags)) {
2642 gen_debug_exception(ctx, false);
2643 } else {
2644 /*
2645 * tcg_gen_lookup_and_goto_ptr will exit the TB if
2646 * CF_NO_GOTO_PTR is set. Count insns now.
2647 */
2648 if (ctx->base.tb->flags & CF_NO_GOTO_PTR) {
2649 pmu_count_insns(ctx);
2650 }
2651
2652 tcg_gen_lookup_and_goto_ptr();
2653 }
2654 }
2655
2656 /*** Branch ***/
2657 static void gen_goto_tb(DisasContext *ctx, unsigned tb_slot_idx,
2658 target_ulong dest)
2659 {
2660 if (NARROW_MODE(ctx)) {
2661 dest = (uint32_t) dest;
2662 }
2663 if (use_goto_tb(ctx, dest)) {
2664 pmu_count_insns(ctx);
2665 tcg_gen_goto_tb(tb_slot_idx);
2666 tcg_gen_movi_tl(cpu_nip, dest & ~3);
2667 tcg_gen_exit_tb(ctx->base.tb, tb_slot_idx);
2668 } else {
2669 tcg_gen_movi_tl(cpu_nip, dest & ~3);
2670 gen_lookup_and_goto_ptr(ctx);
2671 }
2672 }
2673
2674 static inline void gen_setlr(DisasContext *ctx, target_ulong nip)
2675 {
2676 if (NARROW_MODE(ctx)) {
2677 nip = (uint32_t)nip;
2678 }
2679 tcg_gen_movi_tl(cpu_lr, nip);
2680 }
2681
2682 /*** Trap ***/
2683
2684 /* Check for unconditional traps (always or never) */
2685 static bool check_unconditional_trap(DisasContext *ctx, int to)
2686 {
2687 /* Trap never */
2688 if (to == 0) {
2689 return true;
2690 }
2691 /* Trap always */
2692 if (to == 31) {
2693 gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
2694 return true;
2695 }
2696 return false;
2697 }
2698
2699 /*** Processor control ***/
2700
2701 /* mcrxr */
2702 static void gen_mcrxr(DisasContext *ctx)
2703 {
2704 TCGv_i32 t0 = tcg_temp_new_i32();
2705 TCGv_i32 t1 = tcg_temp_new_i32();
2706 TCGv_i32 dst = cpu_crf[crfD(ctx->opcode)];
2707
2708 tcg_gen_trunc_tl_i32(t0, cpu_so);
2709 tcg_gen_trunc_tl_i32(t1, cpu_ov);
2710 tcg_gen_trunc_tl_i32(dst, cpu_ca);
2711 tcg_gen_shli_i32(t0, t0, 3);
2712 tcg_gen_shli_i32(t1, t1, 2);
2713 tcg_gen_shli_i32(dst, dst, 1);
2714 tcg_gen_or_i32(dst, dst, t0);
2715 tcg_gen_or_i32(dst, dst, t1);
2716
2717 tcg_gen_movi_tl(cpu_so, 0);
2718 tcg_gen_movi_tl(cpu_ov, 0);
2719 tcg_gen_movi_tl(cpu_ca, 0);
2720 }
2721
2722 #ifdef TARGET_PPC64
2723 /* mcrxrx */
2724 static void gen_mcrxrx(DisasContext *ctx)
2725 {
2726 TCGv t0 = tcg_temp_new();
2727 TCGv t1 = tcg_temp_new();
2728 TCGv_i32 dst = cpu_crf[crfD(ctx->opcode)];
2729
2730 /* copy OV and OV32 */
2731 tcg_gen_shli_tl(t0, cpu_ov, 1);
2732 tcg_gen_or_tl(t0, t0, cpu_ov32);
2733 tcg_gen_shli_tl(t0, t0, 2);
2734 /* copy CA and CA32 */
2735 tcg_gen_shli_tl(t1, cpu_ca, 1);
2736 tcg_gen_or_tl(t1, t1, cpu_ca32);
2737 tcg_gen_or_tl(t0, t0, t1);
2738 tcg_gen_trunc_tl_i32(dst, t0);
2739 }
2740 #endif
2741
2742 /* mfspr */
2743 static inline void gen_op_mfspr(DisasContext *ctx)
2744 {
2745 void (*read_cb)(DisasContext *ctx, int gprn, int sprn);
2746 uint32_t sprn = SPR(ctx->opcode);
2747
2748 #if defined(CONFIG_USER_ONLY)
2749 read_cb = ctx->spr_cb[sprn].uea_read;
2750 #else
2751 if (ctx->pr) {
2752 read_cb = ctx->spr_cb[sprn].uea_read;
2753 } else if (ctx->hv) {
2754 read_cb = ctx->spr_cb[sprn].hea_read;
2755 } else {
2756 read_cb = ctx->spr_cb[sprn].oea_read;
2757 }
2758 #endif
2759 if (likely(read_cb != NULL)) {
2760 if (likely(read_cb != SPR_NOACCESS)) {
2761 (*read_cb)(ctx, rD(ctx->opcode), sprn);
2762 } else {
2763 /* Privilege exception */
2764 /*
2765 * This is a hack to avoid warnings when running Linux:
2766 * this OS breaks the PowerPC virtualisation model,
2767 * allowing userland application to read the PVR
2768 */
2769 if (sprn != SPR_PVR) {
2770 qemu_log_mask(LOG_GUEST_ERROR, "Trying to read privileged spr "
2771 "%d (0x%03x) at " TARGET_FMT_lx "\n", sprn, sprn,
2772 ctx->cia);
2773 }
2774 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
2775 }
2776 } else {
2777 /* ISA 2.07 defines these as no-ops */
2778 if ((ctx->insns_flags2 & PPC2_ISA207) &&
2779 (sprn >= 808 && sprn <= 811)) {
2780 /* This is a nop */
2781 return;
2782 }
2783 /* Not defined */
2784 qemu_log_mask(LOG_GUEST_ERROR,
2785 "Trying to read invalid spr %d (0x%03x) at "
2786 TARGET_FMT_lx "\n", sprn, sprn, ctx->cia);
2787
2788 /*
2789 * The behaviour depends on MSR:PR and SPR# bit 0x10, it can
2790 * generate a priv, a hv emu or a no-op
2791 */
2792 if (sprn & 0x10) {
2793 if (ctx->pr) {
2794 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
2795 }
2796 } else {
2797 if (ctx->pr || sprn == 0 || sprn == 4 || sprn == 5 || sprn == 6) {
2798 gen_hvpriv_exception(ctx, POWERPC_EXCP_PRIV_REG);
2799 }
2800 }
2801 }
2802 }
2803
2804 static void gen_mfspr(DisasContext *ctx)
2805 {
2806 gen_op_mfspr(ctx);
2807 }
2808
2809 /* mftb */
2810 static void gen_mftb(DisasContext *ctx)
2811 {
2812 gen_op_mfspr(ctx);
2813 }
2814
2815 /* mtspr */
2816 static void gen_mtspr(DisasContext *ctx)
2817 {
2818 void (*write_cb)(DisasContext *ctx, int sprn, int gprn);
2819 uint32_t sprn = SPR(ctx->opcode);
2820
2821 #if defined(CONFIG_USER_ONLY)
2822 write_cb = ctx->spr_cb[sprn].uea_write;
2823 #else
2824 if (ctx->pr) {
2825 write_cb = ctx->spr_cb[sprn].uea_write;
2826 } else if (ctx->hv) {
2827 write_cb = ctx->spr_cb[sprn].hea_write;
2828 } else {
2829 write_cb = ctx->spr_cb[sprn].oea_write;
2830 }
2831 #endif
2832 if (likely(write_cb != NULL)) {
2833 if (likely(write_cb != SPR_NOACCESS)) {
2834 (*write_cb)(ctx, sprn, rS(ctx->opcode));
2835 } else {
2836 /* Privilege exception */
2837 qemu_log_mask(LOG_GUEST_ERROR, "Trying to write privileged spr "
2838 "%d (0x%03x) at " TARGET_FMT_lx "\n", sprn, sprn,
2839 ctx->cia);
2840 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
2841 }
2842 } else {
2843 /* ISA 2.07 defines these as no-ops */
2844 if ((ctx->insns_flags2 & PPC2_ISA207) &&
2845 (sprn >= 808 && sprn <= 811)) {
2846 /* This is a nop */
2847 return;
2848 }
2849
2850 /* Not defined */
2851 qemu_log_mask(LOG_GUEST_ERROR,
2852 "Trying to write invalid spr %d (0x%03x) at "
2853 TARGET_FMT_lx "\n", sprn, sprn, ctx->cia);
2854
2855
2856 /*
2857 * The behaviour depends on MSR:PR and SPR# bit 0x10, it can
2858 * generate a priv, a hv emu or a no-op
2859 */
2860 if (sprn & 0x10) {
2861 if (ctx->pr) {
2862 gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
2863 }
2864 } else {
2865 if (ctx->pr || sprn == 0) {
2866 gen_hvpriv_exception(ctx, POWERPC_EXCP_PRIV_REG);
2867 }
2868 }
2869 }
2870 }
2871
2872 #if defined(TARGET_PPC64)
2873 /* setb */
2874 static void gen_setb(DisasContext *ctx)
2875 {
2876 TCGv_i32 t0 = tcg_temp_new_i32();
2877 TCGv_i32 t8 = tcg_constant_i32(8);
2878 TCGv_i32 tm1 = tcg_constant_i32(-1);
2879 int crf = crfS(ctx->opcode);
2880
2881 tcg_gen_setcondi_i32(TCG_COND_GEU, t0, cpu_crf[crf], 4);
2882 tcg_gen_movcond_i32(TCG_COND_GEU, t0, cpu_crf[crf], t8, tm1, t0);
2883 tcg_gen_ext_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);
2884 }
2885 #endif
2886
2887 /*** Cache management ***/
2888
2889 /* dcbz */
2890 static void gen_dcbz(DisasContext *ctx)
2891 {
2892 TCGv tcgv_addr = tcg_temp_new();
2893
2894 gen_set_access_type(ctx, ACCESS_CACHE);
2895 gen_addr_reg_index(ctx, tcgv_addr);
2896
2897 #ifdef TARGET_PPC64
2898 if (ctx->excp_model == POWERPC_EXCP_970 && !(ctx->opcode & 0x00200000)) {
2899 gen_helper_dcbzl(tcg_env, tcgv_addr);
2900 return;
2901 }
2902 #endif
2903
2904 gen_helper_dcbz(tcg_env, tcgv_addr, tcg_constant_i32(ctx->mem_idx));
2905 }
2906
2907 /* dcbzep */
2908 static void gen_dcbzep(DisasContext *ctx)
2909 {
2910 TCGv tcgv_addr = tcg_temp_new();
2911
2912 gen_set_access_type(ctx, ACCESS_CACHE);
2913 gen_addr_reg_index(ctx, tcgv_addr);
2914 gen_helper_dcbz(tcg_env, tcgv_addr, tcg_constant_i32(PPC_TLB_EPID_STORE));
2915 }
2916
2917 /*** Segment register manipulation ***/
2918 /* Supervisor only: */
2919
2920 /* mfsr */
2921 static void gen_mfsr(DisasContext *ctx)
2922 {
2923 #if defined(CONFIG_USER_ONLY)
2924 GEN_PRIV(ctx);
2925 #else
2926 TCGv t0;
2927
2928 CHK_SV(ctx);
2929 t0 = tcg_constant_tl(SR(ctx->opcode));
2930 gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], tcg_env, t0);
2931 #endif /* defined(CONFIG_USER_ONLY) */
2932 }
2933
2934 /* mfsrin */
2935 static void gen_mfsrin(DisasContext *ctx)
2936 {
2937 #if defined(CONFIG_USER_ONLY)
2938 GEN_PRIV(ctx);
2939 #else
2940 TCGv t0;
2941
2942 CHK_SV(ctx);
2943 t0 = tcg_temp_new();
2944 tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4);
2945 gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], tcg_env, t0);
2946 #endif /* defined(CONFIG_USER_ONLY) */
2947 }
2948
2949 /* mtsr */
2950 static void gen_mtsr(DisasContext *ctx)
2951 {
2952 #if defined(CONFIG_USER_ONLY)
2953 GEN_PRIV(ctx);
2954 #else
2955 TCGv t0;
2956
2957 CHK_SV(ctx);
2958 t0 = tcg_constant_tl(SR(ctx->opcode));
2959 gen_helper_store_sr(tcg_env, t0, cpu_gpr[rS(ctx->opcode)]);
2960 #endif /* defined(CONFIG_USER_ONLY) */
2961 }
2962
2963 /* mtsrin */
2964 static void gen_mtsrin(DisasContext *ctx)
2965 {
2966 #if defined(CONFIG_USER_ONLY)
2967 GEN_PRIV(ctx);
2968 #else
2969 TCGv t0;
2970 CHK_SV(ctx);
2971
2972 t0 = tcg_temp_new();
2973 tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4);
2974 gen_helper_store_sr(tcg_env, t0, cpu_gpr[rD(ctx->opcode)]);
2975 #endif /* defined(CONFIG_USER_ONLY) */
2976 }
2977
2978 #if defined(TARGET_PPC64)
2979 /* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
2980
2981 /* mfsr */
2982 static void gen_mfsr_64b(DisasContext *ctx)
2983 {
2984 #if defined(CONFIG_USER_ONLY)
2985 GEN_PRIV(ctx);
2986 #else
2987 TCGv t0;
2988
2989 CHK_SV(ctx);
2990 t0 = tcg_constant_tl(SR(ctx->opcode));
2991 gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], tcg_env, t0);
2992 #endif /* defined(CONFIG_USER_ONLY) */
2993 }
2994
2995 /* mfsrin */
2996 static void gen_mfsrin_64b(DisasContext *ctx)
2997 {
2998 #if defined(CONFIG_USER_ONLY)
2999 GEN_PRIV(ctx);
3000 #else
3001 TCGv t0;
3002
3003 CHK_SV(ctx);
3004 t0 = tcg_temp_new();
3005 tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4);
3006 gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], tcg_env, t0);
3007 #endif /* defined(CONFIG_USER_ONLY) */
3008 }
3009
3010 /* mtsr */
3011 static void gen_mtsr_64b(DisasContext *ctx)
3012 {
3013 #if defined(CONFIG_USER_ONLY)
3014 GEN_PRIV(ctx);
3015 #else
3016 TCGv t0;
3017
3018 CHK_SV(ctx);
3019 t0 = tcg_constant_tl(SR(ctx->opcode));
3020 gen_helper_store_sr(tcg_env, t0, cpu_gpr[rS(ctx->opcode)]);
3021 #endif /* defined(CONFIG_USER_ONLY) */
3022 }
3023
3024 /* mtsrin */
3025 static void gen_mtsrin_64b(DisasContext *ctx)
3026 {
3027 #if defined(CONFIG_USER_ONLY)
3028 GEN_PRIV(ctx);
3029 #else
3030 TCGv t0;
3031
3032 CHK_SV(ctx);
3033 t0 = tcg_temp_new();
3034 tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4);
3035 gen_helper_store_sr(tcg_env, t0, cpu_gpr[rS(ctx->opcode)]);
3036 #endif /* defined(CONFIG_USER_ONLY) */
3037 }
3038
3039 #endif /* defined(TARGET_PPC64) */
3040
3041 /*** Lookaside buffer management ***/
3042 /* Optional & supervisor only: */
3043
3044 /* tlbia */
3045 static void gen_tlbia(DisasContext *ctx)
3046 {
3047 #if defined(CONFIG_USER_ONLY)
3048 GEN_PRIV(ctx);
3049 #else
3050 CHK_HV(ctx);
3051
3052 gen_helper_tlbia(tcg_env);
3053 #endif /* defined(CONFIG_USER_ONLY) */
3054 }
3055
3056 /* tlbsync */
3057 static void gen_tlbsync(DisasContext *ctx)
3058 {
3059 #if defined(CONFIG_USER_ONLY)
3060 GEN_PRIV(ctx);
3061 #else
3062
3063 if (ctx->gtse) {
3064 CHK_SV(ctx); /* If gtse is set then tlbsync is supervisor privileged */
3065 } else {
3066 CHK_HV(ctx); /* Else hypervisor privileged */
3067 }
3068
3069 /* BookS does both ptesync and tlbsync make tlbsync a nop for server */
3070 if (ctx->insns_flags & PPC_BOOKE) {
3071 gen_check_tlb_flush(ctx, true);
3072 }
3073 #endif /* defined(CONFIG_USER_ONLY) */
3074 }
3075
3076 /*** External control ***/
3077 /* Optional: */
3078
3079 /* eciwx */
3080 static void gen_eciwx(DisasContext *ctx)
3081 {
3082 TCGv t0;
3083 /* Should check EAR[E] ! */
3084 gen_set_access_type(ctx, ACCESS_EXT);
3085 t0 = tcg_temp_new();
3086 gen_addr_reg_index(ctx, t0);
3087 tcg_gen_qemu_ld_tl(cpu_gpr[rD(ctx->opcode)], t0, ctx->mem_idx,
3088 DEF_MEMOP(MO_UL | MO_ALIGN));
3089 }
3090
3091 /* ecowx */
3092 static void gen_ecowx(DisasContext *ctx)
3093 {
3094 TCGv t0;
3095 /* Should check EAR[E] ! */
3096 gen_set_access_type(ctx, ACCESS_EXT);
3097 t0 = tcg_temp_new();
3098 gen_addr_reg_index(ctx, t0);
3099 tcg_gen_qemu_st_tl(cpu_gpr[rD(ctx->opcode)], t0, ctx->mem_idx,
3100 DEF_MEMOP(MO_UL | MO_ALIGN));
3101 }
3102
3103 /* 602 - 603 - G2 TLB management */
3104
3105 /* tlbld */
3106 static void gen_tlbld_6xx(DisasContext *ctx)
3107 {
3108 #if defined(CONFIG_USER_ONLY)
3109 GEN_PRIV(ctx);
3110 #else
3111 CHK_SV(ctx);
3112 gen_helper_6xx_tlbd(tcg_env, cpu_gpr[rB(ctx->opcode)]);
3113 #endif /* defined(CONFIG_USER_ONLY) */
3114 }
3115
3116 /* tlbli */
3117 static void gen_tlbli_6xx(DisasContext *ctx)
3118 {
3119 #if defined(CONFIG_USER_ONLY)
3120 GEN_PRIV(ctx);
3121 #else
3122 CHK_SV(ctx);
3123 gen_helper_6xx_tlbi(tcg_env, cpu_gpr[rB(ctx->opcode)]);
3124 #endif /* defined(CONFIG_USER_ONLY) */
3125 }
3126
3127 /* BookE specific instructions */
3128
3129 /* XXX: not implemented on 440 ? */
3130 static void gen_mfapidi(DisasContext *ctx)
3131 {
3132 /* XXX: TODO */
3133 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3134 }
3135
3136 /* XXX: not implemented on 440 ? */
3137 static void gen_tlbiva(DisasContext *ctx)
3138 {
3139 #if defined(CONFIG_USER_ONLY)
3140 GEN_PRIV(ctx);
3141 #else
3142 TCGv t0;
3143
3144 CHK_SV(ctx);
3145 t0 = tcg_temp_new();
3146 gen_addr_reg_index(ctx, t0);
3147 gen_helper_tlbiva(tcg_env, cpu_gpr[rB(ctx->opcode)]);
3148 #endif /* defined(CONFIG_USER_ONLY) */
3149 }
3150
3151 /* All 405 MAC instructions are translated here */
3152 static inline void gen_405_mulladd_insn(DisasContext *ctx, int opc2, int opc3,
3153 int ra, int rb, int rt, int Rc)
3154 {
3155 TCGv t0, t1;
3156
3157 t0 = tcg_temp_new();
3158 t1 = tcg_temp_new();
3159
3160 switch (opc3 & 0x0D) {
3161 case 0x05:
3162 /* macchw - macchw. - macchwo - macchwo. */
3163 /* macchws - macchws. - macchwso - macchwso. */
3164 /* nmacchw - nmacchw. - nmacchwo - nmacchwo. */
3165 /* nmacchws - nmacchws. - nmacchwso - nmacchwso. */
3166 /* mulchw - mulchw. */
3167 tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
3168 tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
3169 tcg_gen_ext16s_tl(t1, t1);
3170 break;
3171 case 0x04:
3172 /* macchwu - macchwu. - macchwuo - macchwuo. */
3173 /* macchwsu - macchwsu. - macchwsuo - macchwsuo. */
3174 /* mulchwu - mulchwu. */
3175 tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
3176 tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
3177 tcg_gen_ext16u_tl(t1, t1);
3178 break;
3179 case 0x01:
3180 /* machhw - machhw. - machhwo - machhwo. */
3181 /* machhws - machhws. - machhwso - machhwso. */
3182 /* nmachhw - nmachhw. - nmachhwo - nmachhwo. */
3183 /* nmachhws - nmachhws. - nmachhwso - nmachhwso. */
3184 /* mulhhw - mulhhw. */
3185 tcg_gen_sari_tl(t0, cpu_gpr[ra], 16);
3186 tcg_gen_ext16s_tl(t0, t0);
3187 tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
3188 tcg_gen_ext16s_tl(t1, t1);
3189 break;
3190 case 0x00:
3191 /* machhwu - machhwu. - machhwuo - machhwuo. */
3192 /* machhwsu - machhwsu. - machhwsuo - machhwsuo. */
3193 /* mulhhwu - mulhhwu. */
3194 tcg_gen_shri_tl(t0, cpu_gpr[ra], 16);
3195 tcg_gen_ext16u_tl(t0, t0);
3196 tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
3197 tcg_gen_ext16u_tl(t1, t1);
3198 break;
3199 case 0x0D:
3200 /* maclhw - maclhw. - maclhwo - maclhwo. */
3201 /* maclhws - maclhws. - maclhwso - maclhwso. */
3202 /* nmaclhw - nmaclhw. - nmaclhwo - nmaclhwo. */
3203 /* nmaclhws - nmaclhws. - nmaclhwso - nmaclhwso. */
3204 /* mullhw - mullhw. */
3205 tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
3206 tcg_gen_ext16s_tl(t1, cpu_gpr[rb]);
3207 break;
3208 case 0x0C:
3209 /* maclhwu - maclhwu. - maclhwuo - maclhwuo. */
3210 /* maclhwsu - maclhwsu. - maclhwsuo - maclhwsuo. */
3211 /* mullhwu - mullhwu. */
3212 tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
3213 tcg_gen_ext16u_tl(t1, cpu_gpr[rb]);
3214 break;
3215 }
3216 if (opc2 & 0x04) {
3217 /* (n)multiply-and-accumulate (0x0C / 0x0E) */
3218 tcg_gen_mul_tl(t1, t0, t1);
3219 if (opc2 & 0x02) {
3220 /* nmultiply-and-accumulate (0x0E) */
3221 tcg_gen_sub_tl(t0, cpu_gpr[rt], t1);
3222 } else {
3223 /* multiply-and-accumulate (0x0C) */
3224 tcg_gen_add_tl(t0, cpu_gpr[rt], t1);
3225 }
3226
3227 if (opc3 & 0x12) {
3228 /* Check overflow and/or saturate */
3229 TCGLabel *l1 = gen_new_label();
3230
3231 if (opc3 & 0x10) {
3232 /* Start with XER OV disabled, the most likely case */
3233 tcg_gen_movi_tl(cpu_ov, 0);
3234 }
3235 if (opc3 & 0x01) {
3236 /* Signed */
3237 tcg_gen_xor_tl(t1, cpu_gpr[rt], t1);
3238 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3239 tcg_gen_xor_tl(t1, cpu_gpr[rt], t0);
3240 tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
3241 if (opc3 & 0x02) {
3242 /* Saturate */
3243 tcg_gen_sari_tl(t0, cpu_gpr[rt], 31);
3244 tcg_gen_xori_tl(t0, t0, 0x7fffffff);
3245 }
3246 } else {
3247 /* Unsigned */
3248 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3249 if (opc3 & 0x02) {
3250 /* Saturate */
3251 tcg_gen_movi_tl(t0, UINT32_MAX);
3252 }
3253 }
3254 if (opc3 & 0x10) {
3255 /* Check overflow */
3256 tcg_gen_movi_tl(cpu_ov, 1);
3257 tcg_gen_movi_tl(cpu_so, 1);
3258 }
3259 gen_set_label(l1);
3260 tcg_gen_mov_tl(cpu_gpr[rt], t0);
3261 }
3262 } else {
3263 tcg_gen_mul_tl(cpu_gpr[rt], t0, t1);
3264 }
3265 if (unlikely(Rc) != 0) {
3266 /* Update Rc0 */
3267 gen_set_Rc0(ctx, cpu_gpr[rt]);
3268 }
3269 }
3270
3271 #define GEN_MAC_HANDLER(name, opc2, opc3) \
3272 static void glue(gen_, name)(DisasContext *ctx) \
3273 { \
3274 gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode), \
3275 rD(ctx->opcode), Rc(ctx->opcode)); \
3276 }
3277
3278 /* macchw - macchw. */
3279 GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
3280 /* macchwo - macchwo. */
3281 GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
3282 /* macchws - macchws. */
3283 GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
3284 /* macchwso - macchwso. */
3285 GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
3286 /* macchwsu - macchwsu. */
3287 GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
3288 /* macchwsuo - macchwsuo. */
3289 GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
3290 /* macchwu - macchwu. */
3291 GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
3292 /* macchwuo - macchwuo. */
3293 GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
3294 /* machhw - machhw. */
3295 GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
3296 /* machhwo - machhwo. */
3297 GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
3298 /* machhws - machhws. */
3299 GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
3300 /* machhwso - machhwso. */
3301 GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
3302 /* machhwsu - machhwsu. */
3303 GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
3304 /* machhwsuo - machhwsuo. */
3305 GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
3306 /* machhwu - machhwu. */
3307 GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
3308 /* machhwuo - machhwuo. */
3309 GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
3310 /* maclhw - maclhw. */
3311 GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
3312 /* maclhwo - maclhwo. */
3313 GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
3314 /* maclhws - maclhws. */
3315 GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
3316 /* maclhwso - maclhwso. */
3317 GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
3318 /* maclhwu - maclhwu. */
3319 GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
3320 /* maclhwuo - maclhwuo. */
3321 GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
3322 /* maclhwsu - maclhwsu. */
3323 GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
3324 /* maclhwsuo - maclhwsuo. */
3325 GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
3326 /* nmacchw - nmacchw. */
3327 GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
3328 /* nmacchwo - nmacchwo. */
3329 GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
3330 /* nmacchws - nmacchws. */
3331 GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
3332 /* nmacchwso - nmacchwso. */
3333 GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
3334 /* nmachhw - nmachhw. */
3335 GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
3336 /* nmachhwo - nmachhwo. */
3337 GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
3338 /* nmachhws - nmachhws. */
3339 GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
3340 /* nmachhwso - nmachhwso. */
3341 GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
3342 /* nmaclhw - nmaclhw. */
3343 GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
3344 /* nmaclhwo - nmaclhwo. */
3345 GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
3346 /* nmaclhws - nmaclhws. */
3347 GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
3348 /* nmaclhwso - nmaclhwso. */
3349 GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
3350
3351 /* mulchw - mulchw. */
3352 GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
3353 /* mulchwu - mulchwu. */
3354 GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
3355 /* mulhhw - mulhhw. */
3356 GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
3357 /* mulhhwu - mulhhwu. */
3358 GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
3359 /* mullhw - mullhw. */
3360 GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
3361 /* mullhwu - mullhwu. */
3362 GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
3363
3364 /* mfdcr */
3365 static void gen_mfdcr(DisasContext *ctx)
3366 {
3367 #if defined(CONFIG_USER_ONLY)
3368 GEN_PRIV(ctx);
3369 #else
3370 TCGv dcrn;
3371
3372 CHK_SV(ctx);
3373 dcrn = tcg_constant_tl(SPR(ctx->opcode));
3374 gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], tcg_env, dcrn);
3375 #endif /* defined(CONFIG_USER_ONLY) */
3376 }
3377
3378 /* mtdcr */
3379 static void gen_mtdcr(DisasContext *ctx)
3380 {
3381 #if defined(CONFIG_USER_ONLY)
3382 GEN_PRIV(ctx);
3383 #else
3384 TCGv dcrn;
3385
3386 CHK_SV(ctx);
3387 dcrn = tcg_constant_tl(SPR(ctx->opcode));
3388 gen_helper_store_dcr(tcg_env, dcrn, cpu_gpr[rS(ctx->opcode)]);
3389 #endif /* defined(CONFIG_USER_ONLY) */
3390 }
3391
3392 /* mfdcrx */
3393 /* XXX: not implemented on 440 ? */
3394 static void gen_mfdcrx(DisasContext *ctx)
3395 {
3396 #if defined(CONFIG_USER_ONLY)
3397 GEN_PRIV(ctx);
3398 #else
3399 CHK_SV(ctx);
3400 gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], tcg_env,
3401 cpu_gpr[rA(ctx->opcode)]);
3402 /* Note: Rc update flag set leads to undefined state of Rc0 */
3403 #endif /* defined(CONFIG_USER_ONLY) */
3404 }
3405
3406 /* mtdcrx */
3407 /* XXX: not implemented on 440 ? */
3408 static void gen_mtdcrx(DisasContext *ctx)
3409 {
3410 #if defined(CONFIG_USER_ONLY)
3411 GEN_PRIV(ctx);
3412 #else
3413 CHK_SV(ctx);
3414 gen_helper_store_dcr(tcg_env, cpu_gpr[rA(ctx->opcode)],
3415 cpu_gpr[rS(ctx->opcode)]);
3416 /* Note: Rc update flag set leads to undefined state of Rc0 */
3417 #endif /* defined(CONFIG_USER_ONLY) */
3418 }
3419
3420 /* dccci */
3421 static void gen_dccci(DisasContext *ctx)
3422 {
3423 CHK_SV(ctx);
3424 /* interpreted as no-op */
3425 }
3426
3427 /* dcread */
3428 static void gen_dcread(DisasContext *ctx)
3429 {
3430 #if defined(CONFIG_USER_ONLY)
3431 GEN_PRIV(ctx);
3432 #else
3433 TCGv EA, val;
3434
3435 CHK_SV(ctx);
3436 gen_set_access_type(ctx, ACCESS_CACHE);
3437 EA = tcg_temp_new();
3438 gen_addr_reg_index(ctx, EA);
3439 val = tcg_temp_new();
3440 gen_qemu_ld32u(ctx, val, EA);
3441 tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
3442 #endif /* defined(CONFIG_USER_ONLY) */
3443 }
3444
3445 /* icbt */
3446 static void gen_icbt_40x(DisasContext *ctx)
3447 {
3448 /*
3449 * interpreted as no-op
3450 * XXX: specification say this is treated as a load by the MMU but
3451 * does not generate any exception
3452 */
3453 }
3454
3455 /* iccci */
3456 static void gen_iccci(DisasContext *ctx)
3457 {
3458 CHK_SV(ctx);
3459 /* interpreted as no-op */
3460 }
3461
3462 /* icread */
3463 static void gen_icread(DisasContext *ctx)
3464 {
3465 CHK_SV(ctx);
3466 /* interpreted as no-op */
3467 }
3468
3469 /* rfci (supervisor only) */
3470 static void gen_rfci_40x(DisasContext *ctx)
3471 {
3472 #if defined(CONFIG_USER_ONLY)
3473 GEN_PRIV(ctx);
3474 #else
3475 CHK_SV(ctx);
3476 /* Restore CPU state */
3477 gen_helper_40x_rfci(tcg_env);
3478 ctx->base.is_jmp = DISAS_EXIT;
3479 #endif /* defined(CONFIG_USER_ONLY) */
3480 }
3481
3482 static void gen_rfci(DisasContext *ctx)
3483 {
3484 #if defined(CONFIG_USER_ONLY)
3485 GEN_PRIV(ctx);
3486 #else
3487 CHK_SV(ctx);
3488 /* Restore CPU state */
3489 gen_helper_rfci(tcg_env);
3490 ctx->base.is_jmp = DISAS_EXIT;
3491 #endif /* defined(CONFIG_USER_ONLY) */
3492 }
3493
3494 /* BookE specific */
3495
3496 /* XXX: not implemented on 440 ? */
3497 static void gen_rfdi(DisasContext *ctx)
3498 {
3499 #if defined(CONFIG_USER_ONLY)
3500 GEN_PRIV(ctx);
3501 #else
3502 CHK_SV(ctx);
3503 /* Restore CPU state */
3504 gen_helper_rfdi(tcg_env);
3505 ctx->base.is_jmp = DISAS_EXIT;
3506 #endif /* defined(CONFIG_USER_ONLY) */
3507 }
3508
3509 /* XXX: not implemented on 440 ? */
3510 static void gen_rfmci(DisasContext *ctx)
3511 {
3512 #if defined(CONFIG_USER_ONLY)
3513 GEN_PRIV(ctx);
3514 #else
3515 CHK_SV(ctx);
3516 /* Restore CPU state */
3517 gen_helper_rfmci(tcg_env);
3518 ctx->base.is_jmp = DISAS_EXIT;
3519 #endif /* defined(CONFIG_USER_ONLY) */
3520 }
3521
3522 /* TLB management - PowerPC 405 implementation */
3523
3524 /* tlbre */
3525 static void gen_tlbre_40x(DisasContext *ctx)
3526 {
3527 #if defined(CONFIG_USER_ONLY)
3528 GEN_PRIV(ctx);
3529 #else
3530 CHK_SV(ctx);
3531 switch (rB(ctx->opcode)) {
3532 case 0:
3533 gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], tcg_env,
3534 cpu_gpr[rA(ctx->opcode)]);
3535 break;
3536 case 1:
3537 gen_helper_4xx_tlbre_lo(cpu_gpr[rD(ctx->opcode)], tcg_env,
3538 cpu_gpr[rA(ctx->opcode)]);
3539 break;
3540 default:
3541 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3542 break;
3543 }
3544 #endif /* defined(CONFIG_USER_ONLY) */
3545 }
3546
3547 /* tlbsx - tlbsx. */
3548 static void gen_tlbsx_40x(DisasContext *ctx)
3549 {
3550 #if defined(CONFIG_USER_ONLY)
3551 GEN_PRIV(ctx);
3552 #else
3553 TCGv t0;
3554
3555 CHK_SV(ctx);
3556 t0 = tcg_temp_new();
3557 gen_addr_reg_index(ctx, t0);
3558 gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], tcg_env, t0);
3559 if (Rc(ctx->opcode)) {
3560 TCGLabel *l1 = gen_new_label();
3561 tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
3562 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
3563 tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
3564 gen_set_label(l1);
3565 }
3566 #endif /* defined(CONFIG_USER_ONLY) */
3567 }
3568
3569 /* tlbwe */
3570 static void gen_tlbwe_40x(DisasContext *ctx)
3571 {
3572 #if defined(CONFIG_USER_ONLY)
3573 GEN_PRIV(ctx);
3574 #else
3575 CHK_SV(ctx);
3576
3577 switch (rB(ctx->opcode)) {
3578 case 0:
3579 gen_helper_4xx_tlbwe_hi(tcg_env, cpu_gpr[rA(ctx->opcode)],
3580 cpu_gpr[rS(ctx->opcode)]);
3581 break;
3582 case 1:
3583 gen_helper_4xx_tlbwe_lo(tcg_env, cpu_gpr[rA(ctx->opcode)],
3584 cpu_gpr[rS(ctx->opcode)]);
3585 break;
3586 default:
3587 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3588 break;
3589 }
3590 #endif /* defined(CONFIG_USER_ONLY) */
3591 }
3592
3593 /* TLB management - PowerPC 440 implementation */
3594
3595 /* tlbre */
3596 static void gen_tlbre_440(DisasContext *ctx)
3597 {
3598 #if defined(CONFIG_USER_ONLY)
3599 GEN_PRIV(ctx);
3600 #else
3601 CHK_SV(ctx);
3602
3603 switch (rB(ctx->opcode)) {
3604 case 0:
3605 case 1:
3606 case 2:
3607 {
3608 TCGv_i32 t0 = tcg_constant_i32(rB(ctx->opcode));
3609 gen_helper_440_tlbre(cpu_gpr[rD(ctx->opcode)], tcg_env,
3610 t0, cpu_gpr[rA(ctx->opcode)]);
3611 }
3612 break;
3613 default:
3614 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3615 break;
3616 }
3617 #endif /* defined(CONFIG_USER_ONLY) */
3618 }
3619
3620 /* tlbsx - tlbsx. */
3621 static void gen_tlbsx_440(DisasContext *ctx)
3622 {
3623 #if defined(CONFIG_USER_ONLY)
3624 GEN_PRIV(ctx);
3625 #else
3626 TCGv t0;
3627
3628 CHK_SV(ctx);
3629 t0 = tcg_temp_new();
3630 gen_addr_reg_index(ctx, t0);
3631 gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], tcg_env, t0);
3632 if (Rc(ctx->opcode)) {
3633 TCGLabel *l1 = gen_new_label();
3634 tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
3635 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
3636 tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
3637 gen_set_label(l1);
3638 }
3639 #endif /* defined(CONFIG_USER_ONLY) */
3640 }
3641
3642 /* tlbwe */
3643 static void gen_tlbwe_440(DisasContext *ctx)
3644 {
3645 #if defined(CONFIG_USER_ONLY)
3646 GEN_PRIV(ctx);
3647 #else
3648 CHK_SV(ctx);
3649 switch (rB(ctx->opcode)) {
3650 case 0:
3651 case 1:
3652 case 2:
3653 {
3654 TCGv_i32 t0 = tcg_constant_i32(rB(ctx->opcode));
3655 gen_helper_440_tlbwe(tcg_env, t0, cpu_gpr[rA(ctx->opcode)],
3656 cpu_gpr[rS(ctx->opcode)]);
3657 }
3658 break;
3659 default:
3660 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3661 break;
3662 }
3663 #endif /* defined(CONFIG_USER_ONLY) */
3664 }
3665
3666 /* TLB management - PowerPC BookE 2.06 implementation */
3667
3668 /* tlbre */
3669 static void gen_tlbre_booke206(DisasContext *ctx)
3670 {
3671 #if defined(CONFIG_USER_ONLY)
3672 GEN_PRIV(ctx);
3673 #else
3674 CHK_SV(ctx);
3675 gen_helper_booke206_tlbre(tcg_env);
3676 #endif /* defined(CONFIG_USER_ONLY) */
3677 }
3678
3679 /* tlbsx - tlbsx. */
3680 static void gen_tlbsx_booke206(DisasContext *ctx)
3681 {
3682 #if defined(CONFIG_USER_ONLY)
3683 GEN_PRIV(ctx);
3684 #else
3685 TCGv t0;
3686
3687 CHK_SV(ctx);
3688 if (rA(ctx->opcode)) {
3689 t0 = tcg_temp_new();
3690 tcg_gen_add_tl(t0, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
3691 } else {
3692 t0 = cpu_gpr[rB(ctx->opcode)];
3693 }
3694 gen_helper_booke206_tlbsx(tcg_env, t0);
3695 #endif /* defined(CONFIG_USER_ONLY) */
3696 }
3697
3698 /* tlbwe */
3699 static void gen_tlbwe_booke206(DisasContext *ctx)
3700 {
3701 #if defined(CONFIG_USER_ONLY)
3702 GEN_PRIV(ctx);
3703 #else
3704 CHK_SV(ctx);
3705 gen_helper_booke206_tlbwe(tcg_env);
3706 #endif /* defined(CONFIG_USER_ONLY) */
3707 }
3708
3709 static void gen_tlbivax_booke206(DisasContext *ctx)
3710 {
3711 #if defined(CONFIG_USER_ONLY)
3712 GEN_PRIV(ctx);
3713 #else
3714 TCGv t0;
3715
3716 CHK_SV(ctx);
3717 t0 = tcg_temp_new();
3718 gen_addr_reg_index(ctx, t0);
3719 gen_helper_booke206_tlbivax(tcg_env, t0);
3720 #endif /* defined(CONFIG_USER_ONLY) */
3721 }
3722
3723 static void gen_tlbilx_booke206(DisasContext *ctx)
3724 {
3725 #if defined(CONFIG_USER_ONLY)
3726 GEN_PRIV(ctx);
3727 #else
3728 TCGv t0;
3729
3730 CHK_SV(ctx);
3731 t0 = tcg_temp_new();
3732 gen_addr_reg_index(ctx, t0);
3733
3734 switch ((ctx->opcode >> 21) & 0x3) {
3735 case 0:
3736 gen_helper_booke206_tlbilx0(tcg_env, t0);
3737 break;
3738 case 1:
3739 gen_helper_booke206_tlbilx1(tcg_env, t0);
3740 break;
3741 case 3:
3742 gen_helper_booke206_tlbilx3(tcg_env, t0);
3743 break;
3744 default:
3745 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3746 break;
3747 }
3748 #endif /* defined(CONFIG_USER_ONLY) */
3749 }
3750
3751 /* wrtee */
3752 static void gen_wrtee(DisasContext *ctx)
3753 {
3754 #if defined(CONFIG_USER_ONLY)
3755 GEN_PRIV(ctx);
3756 #else
3757 TCGv t0;
3758
3759 CHK_SV(ctx);
3760 t0 = tcg_temp_new();
3761 tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));
3762 tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
3763 tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
3764 gen_ppc_maybe_interrupt(ctx);
3765 /*
3766 * Stop translation to have a chance to raise an exception if we
3767 * just set msr_ee to 1
3768 */
3769 ctx->base.is_jmp = DISAS_EXIT_UPDATE;
3770 #endif /* defined(CONFIG_USER_ONLY) */
3771 }
3772
3773 /* wrteei */
3774 static void gen_wrteei(DisasContext *ctx)
3775 {
3776 #if defined(CONFIG_USER_ONLY)
3777 GEN_PRIV(ctx);
3778 #else
3779 CHK_SV(ctx);
3780 if (ctx->opcode & 0x00008000) {
3781 tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
3782 gen_ppc_maybe_interrupt(ctx);
3783 /* Stop translation to have a chance to raise an exception */
3784 ctx->base.is_jmp = DISAS_EXIT_UPDATE;
3785 } else {
3786 tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
3787 }
3788 #endif /* defined(CONFIG_USER_ONLY) */
3789 }
3790
3791 /* PowerPC 440 specific instructions */
3792
3793 /* dlmzb */
3794 static void gen_dlmzb(DisasContext *ctx)
3795 {
3796 TCGv_i32 t0 = tcg_constant_i32(Rc(ctx->opcode));
3797 gen_helper_dlmzb(cpu_gpr[rA(ctx->opcode)], tcg_env,
3798 cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0);
3799 }
3800
3801 /* icbt */
3802 static void gen_icbt_440(DisasContext *ctx)
3803 {
3804 /*
3805 * interpreted as no-op
3806 * XXX: specification say this is treated as a load by the MMU but
3807 * does not generate any exception
3808 */
3809 }
3810
3811 static void gen_tbegin(DisasContext *ctx)
3812 {
3813 if (unlikely(!ctx->tm_enabled)) {
3814 gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);
3815 return;
3816 }
3817 gen_helper_tbegin(tcg_env);
3818 }
3819
3820 #define GEN_TM_NOOP(name) \
3821 static inline void gen_##name(DisasContext *ctx) \
3822 { \
3823 if (unlikely(!ctx->tm_enabled)) { \
3824 gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM); \
3825 return; \
3826 } \
3827 /* \
3828 * Because tbegin always fails in QEMU, these user \
3829 * space instructions all have a simple implementation: \
3830 * \
3831 * CR[0] = 0b0 || MSR[TS] || 0b0 \
3832 * = 0b0 || 0b00 || 0b0 \
3833 */ \
3834 tcg_gen_movi_i32(cpu_crf[0], 0); \
3835 }
3836
3837 GEN_TM_NOOP(tend);
3838 GEN_TM_NOOP(tabort);
3839 GEN_TM_NOOP(tabortwc);
3840 GEN_TM_NOOP(tabortwci);
3841 GEN_TM_NOOP(tabortdc);
3842 GEN_TM_NOOP(tabortdci);
3843 GEN_TM_NOOP(tsr);
3844
3845 static inline void gen_cp_abort(DisasContext *ctx)
3846 {
3847 /* Do Nothing */
3848 }
3849
3850 #define GEN_CP_PASTE_NOOP(name) \
3851 static inline void gen_##name(DisasContext *ctx) \
3852 { \
3853 /* \
3854 * Generate invalid exception until we have an \
3855 * implementation of the copy paste facility \
3856 */ \
3857 gen_invalid(ctx); \
3858 }
3859
3860 GEN_CP_PASTE_NOOP(copy)
3861 GEN_CP_PASTE_NOOP(paste)
3862
3863 static void gen_tcheck(DisasContext *ctx)
3864 {
3865 if (unlikely(!ctx->tm_enabled)) {
3866 gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);
3867 return;
3868 }
3869 /*
3870 * Because tbegin always fails, the tcheck implementation is
3871 * simple:
3872 *
3873 * CR[CRF] = TDOOMED || MSR[TS] || 0b0
3874 * = 0b1 || 0b00 || 0b0
3875 */
3876 tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0x8);
3877 }
3878
3879 #if defined(CONFIG_USER_ONLY)
3880 #define GEN_TM_PRIV_NOOP(name) \
3881 static inline void gen_##name(DisasContext *ctx) \
3882 { \
3883 gen_priv_opc(ctx); \
3884 }
3885
3886 #else
3887
3888 #define GEN_TM_PRIV_NOOP(name) \
3889 static inline void gen_##name(DisasContext *ctx) \
3890 { \
3891 CHK_SV(ctx); \
3892 if (unlikely(!ctx->tm_enabled)) { \
3893 gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM); \
3894 return; \
3895 } \
3896 /* \
3897 * Because tbegin always fails, the implementation is \
3898 * simple: \
3899 * \
3900 * CR[0] = 0b0 || MSR[TS] || 0b0 \
3901 * = 0b0 || 0b00 | 0b0 \
3902 */ \
3903 tcg_gen_movi_i32(cpu_crf[0], 0); \
3904 }
3905
3906 #endif
3907
3908 GEN_TM_PRIV_NOOP(treclaim);
3909 GEN_TM_PRIV_NOOP(trechkpt);
3910
3911 static inline void get_fpr(TCGv_i64 dst, int regno)
3912 {
3913 tcg_gen_ld_i64(dst, tcg_env, fpr_offset(regno));
3914 }
3915
3916 static inline void set_fpr(int regno, TCGv_i64 src)
3917 {
3918 tcg_gen_st_i64(src, tcg_env, fpr_offset(regno));
3919 /*
3920 * Before PowerISA v3.1 the result of doubleword 1 of the VSR
3921 * corresponding to the target FPR was undefined. However,
3922 * most (if not all) real hardware were setting the result to 0.
3923 * Starting at ISA v3.1, the result for doubleword 1 is now defined
3924 * to be 0.
3925 */
3926 tcg_gen_st_i64(tcg_constant_i64(0), tcg_env, vsr64_offset(regno, false));
3927 }
3928
3929 /*
3930 * Helpers for decodetree used by !function for decoding arguments.
3931 */
3932 static int times_2(DisasContext *ctx, int x)
3933 {
3934 return x * 2;
3935 }
3936
3937 static int times_4(DisasContext *ctx, int x)
3938 {
3939 return x * 4;
3940 }
3941
3942 static int times_16(DisasContext *ctx, int x)
3943 {
3944 return x * 16;
3945 }
3946
3947 static int64_t dw_compose_ea(DisasContext *ctx, int x)
3948 {
3949 return deposit64(0xfffffffffffffe00, 3, 6, x);
3950 }
3951
3952 /*
3953 * Helpers for trans_* functions to check for specific insns flags.
3954 * Use token pasting to ensure that we use the proper flag with the
3955 * proper variable.
3956 */
3957 #define REQUIRE_INSNS_FLAGS(CTX, NAME) \
3958 do { \
3959 if (((CTX)->insns_flags & PPC_##NAME) == 0) { \
3960 return false; \
3961 } \
3962 } while (0)
3963
3964 #define REQUIRE_INSNS_FLAGS2(CTX, NAME) \
3965 do { \
3966 if (((CTX)->insns_flags2 & PPC2_##NAME) == 0) { \
3967 return false; \
3968 } \
3969 } while (0)
3970
3971 /* Then special-case the check for 64-bit so that we elide code for ppc32. */
3972 #if TARGET_LONG_BITS == 32
3973 # define REQUIRE_64BIT(CTX) return false
3974 #else
3975 # define REQUIRE_64BIT(CTX) REQUIRE_INSNS_FLAGS(CTX, 64B)
3976 #endif
3977
3978 #define REQUIRE_VECTOR(CTX) \
3979 do { \
3980 if (unlikely(!(CTX)->altivec_enabled)) { \
3981 gen_exception((CTX), POWERPC_EXCP_VPU); \
3982 return true; \
3983 } \
3984 } while (0)
3985
3986 #define REQUIRE_VSX(CTX) \
3987 do { \
3988 if (unlikely(!(CTX)->vsx_enabled)) { \
3989 gen_exception((CTX), POWERPC_EXCP_VSXU); \
3990 return true; \
3991 } \
3992 } while (0)
3993
3994 #define REQUIRE_FPU(ctx) \
3995 do { \
3996 if (unlikely(!(ctx)->fpu_enabled)) { \
3997 gen_exception((ctx), POWERPC_EXCP_FPU); \
3998 return true; \
3999 } \
4000 } while (0)
4001
4002 #if !defined(CONFIG_USER_ONLY)
4003 #define REQUIRE_SV(CTX) \
4004 do { \
4005 if (unlikely((CTX)->pr)) { \
4006 gen_priv_opc(CTX); \
4007 return true; \
4008 } \
4009 } while (0)
4010
4011 #define REQUIRE_HV(CTX) \
4012 do { \
4013 if (unlikely((CTX)->pr || !(CTX)->hv)) { \
4014 gen_priv_opc(CTX); \
4015 return true; \
4016 } \
4017 } while (0)
4018 #define REQUIRE_HVRM(CTX) \
4019 do { \
4020 if (unlikely(ctx->pr || !ctx->hv || ctx->dr)) { \
4021 gen_priv_opc(CTX); \
4022 return true; \
4023 } \
4024 } while (0)
4025 #else
4026 #define REQUIRE_SV(CTX) do { gen_priv_opc(CTX); return true; } while (0)
4027 #define REQUIRE_HV(CTX) do { gen_priv_opc(CTX); return true; } while (0)
4028 #define REQUIRE_HVRM(CTX) do { gen_priv_opc(CTX); return true; } while (0)
4029 #endif
4030
4031 /*
4032 * Helpers for implementing sets of trans_* functions.
4033 * Defer the implementation of NAME to FUNC, with optional extra arguments.
4034 */
4035 #define TRANS(NAME, FUNC, ...) \
4036 static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \
4037 { return FUNC(ctx, a, ##__VA_ARGS__); }
4038 #define TRANS_FLAGS(FLAGS, NAME, FUNC, ...) \
4039 static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \
4040 { \
4041 REQUIRE_INSNS_FLAGS(ctx, FLAGS); \
4042 return FUNC(ctx, a, ##__VA_ARGS__); \
4043 }
4044 #define TRANS_FLAGS2(FLAGS2, NAME, FUNC, ...) \
4045 static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \
4046 { \
4047 REQUIRE_INSNS_FLAGS2(ctx, FLAGS2); \
4048 return FUNC(ctx, a, ##__VA_ARGS__); \
4049 }
4050
4051 #define TRANS64(NAME, FUNC, ...) \
4052 static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \
4053 { REQUIRE_64BIT(ctx); return FUNC(ctx, a, ##__VA_ARGS__); }
4054 #define TRANS64_FLAGS(FLAGS, NAME, FUNC, ...) \
4055 static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \
4056 { \
4057 REQUIRE_64BIT(ctx); \
4058 REQUIRE_INSNS_FLAGS(ctx, FLAGS); \
4059 return FUNC(ctx, a, ##__VA_ARGS__); \
4060 }
4061 #define TRANS64_FLAGS2(FLAGS2, NAME, FUNC, ...) \
4062 static bool trans_##NAME(DisasContext *ctx, arg_##NAME *a) \
4063 { \
4064 REQUIRE_64BIT(ctx); \
4065 REQUIRE_INSNS_FLAGS2(ctx, FLAGS2); \
4066 return FUNC(ctx, a, ##__VA_ARGS__); \
4067 }
4068
4069 /* TODO: More TRANS* helpers for extra insn_flags checks. */
4070
4071
4072 #include "decode-insn32.c.inc"
4073 #include "decode-insn64.c.inc"
4074 #include "power8-pmu-regs.c.inc"
4075
4076 /*
4077 * Incorporate CIA into the constant when R=1.
4078 * Validate that when R=1, RA=0.
4079 */
4080 static bool resolve_PLS_D(DisasContext *ctx, arg_D *d, arg_PLS_D *a)
4081 {
4082 d->rt = a->rt;
4083 d->ra = a->ra;
4084 d->si = a->si;
4085 if (a->r) {
4086 if (unlikely(a->ra != 0)) {
4087 gen_invalid(ctx);
4088 return false;
4089 }
4090 d->si += ctx->cia;
4091 }
4092 return true;
4093 }
4094
4095 static bool trans_EXTSWSLI(DisasContext *ctx, arg_XS *a)
4096 {
4097 REQUIRE_64BIT(ctx);
4098 REQUIRE_INSNS_FLAGS2(ctx, ISA300);
4099
4100 /* Mimic legacy behavior: operate directly on dst */
4101 tcg_gen_ext32s_tl(cpu_gpr[a->ra], cpu_gpr[a->rs]);
4102 tcg_gen_shli_tl(cpu_gpr[a->ra], cpu_gpr[a->ra], a->sh);
4103
4104 if (unlikely(a->rc)) {
4105 gen_set_Rc0(ctx, cpu_gpr[a->ra]);
4106 }
4107 return true;
4108 }
4109
4110 /*
4111 * Load-and-reserve core
4112 */
4113 static bool do_load_locked(DisasContext *ctx, arg_X_rc *a, MemOp memop)
4114 {
4115 TCGv EA = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
4116 TCGv gpr = cpu_gpr[a->rt];
4117
4118 gen_set_access_type(ctx, ACCESS_RES);
4119
4120 tcg_gen_qemu_ld_tl(gpr, EA, ctx->mem_idx, memop | MO_ALIGN);
4121
4122 tcg_gen_mov_tl(cpu_reserve, EA);
4123 tcg_gen_movi_tl(cpu_reserve_length, memop_size(memop));
4124
4125 tcg_gen_mov_tl(cpu_reserve_val, gpr);
4126
4127 return true;
4128 }
4129
4130 TRANS_FLAGS2(ATOMIC_ISA206, LBARX, do_load_locked, DEF_MEMOP(MO_UB))
4131 TRANS_FLAGS2(ATOMIC_ISA206, LHARX, do_load_locked, DEF_MEMOP(MO_UW))
4132 TRANS(LWARX, do_load_locked, DEF_MEMOP(MO_UL))
4133 TRANS64(LDARX, do_load_locked, DEF_MEMOP(MO_UQ))
4134
4135 static bool trans_LQARX(DisasContext *ctx, arg_LQARX *a)
4136 {
4137 REQUIRE_64BIT(ctx);
4138 REQUIRE_INSNS_FLAGS2(ctx, ISA207);
4139 #if defined(TARGET_PPC64)
4140 TCGv EA;
4141 TCGv_i128 t16;
4142 /* Must use even register and avoid overlap */
4143 if (unlikely((a->rt & 1) || (a->rt == a->ra) || (a->rt == a->rb))) {
4144 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
4145 return true;
4146 }
4147
4148 gen_set_access_type(ctx, ACCESS_RES);
4149 EA = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
4150 t16 = tcg_temp_new_i128();
4151
4152 tcg_gen_qemu_ld_i128(t16, EA, ctx->mem_idx, DEF_MEMOP(MO_128 | MO_ALIGN));
4153 tcg_gen_extr_i128_i64(cpu_gpr[a->rt + 1], cpu_gpr[a->rt], t16);
4154 tcg_gen_mov_tl(cpu_reserve, EA);
4155 tcg_gen_movi_tl(cpu_reserve_length, 16);
4156 tcg_gen_st_i64(cpu_gpr[a->rt], tcg_env,
4157 offsetof(CPUPPCState, reserve_val));
4158 tcg_gen_st_i64(cpu_gpr[a->rt + 1], tcg_env,
4159 offsetof(CPUPPCState, reserve_val2));
4160 #else
4161 qemu_build_not_reached();
4162 #endif
4163 return true;
4164 }
4165
4166 /*
4167 * Cache Management Instructions (decodetree)
4168 */
4169
4170 static bool trans_DCBA(DisasContext *ctx, arg_X_ea *a)
4171 {
4172 REQUIRE_INSNS_FLAGS(ctx, CACHE_DCBA);
4173 return true;
4174 }
4175
4176 static bool trans_DCBT(DisasContext *ctx, arg_X_th *a)
4177 {
4178 REQUIRE_INSNS_FLAGS(ctx, CACHE);
4179 return true;
4180 }
4181
4182 static bool trans_DCBTEP(DisasContext *ctx, arg_X_ea *a)
4183 {
4184 REQUIRE_INSNS_FLAGS2(ctx, BOOKE206);
4185 return true;
4186 }
4187
4188 static bool trans_DCBTST(DisasContext *ctx, arg_X_th *a)
4189 {
4190 REQUIRE_INSNS_FLAGS(ctx, CACHE);
4191 return true;
4192 }
4193
4194 static bool trans_DCBTSTEP(DisasContext *ctx, arg_X_ea *a)
4195 {
4196 REQUIRE_INSNS_FLAGS2(ctx, BOOKE206);
4197 return true;
4198 }
4199
4200 static bool trans_DCBLC(DisasContext *ctx, arg_X_th *a)
4201 {
4202 /* Requires either PPC_BOOKE or PPC2_BOOKE206 */
4203 if (!(ctx->insns_flags & PPC_BOOKE) &&
4204 !(ctx->insns_flags2 & PPC2_BOOKE206)) {
4205 return false;
4206 }
4207 return true;
4208 }
4209
4210 static bool trans_DSS(DisasContext *ctx, arg_X_ea *a)
4211 {
4212 REQUIRE_INSNS_FLAGS(ctx, ALTIVEC);
4213 return true;
4214 }
4215
4216 static bool trans_DCBTLS(DisasContext *ctx, arg_X_th *a)
4217 {
4218 TCGv t0 = tcg_temp_new();
4219
4220 /* Requires either PPC_BOOKE or PPC2_BOOKE206 */
4221 if (!(ctx->insns_flags & PPC_BOOKE) &&
4222 !(ctx->insns_flags2 & PPC2_BOOKE206)) {
4223 return false;
4224 }
4225
4226 gen_load_spr(t0, SPR_Exxx_L1CSR0);
4227 tcg_gen_ori_tl(t0, t0, L1CSR0_CUL);
4228 gen_store_spr(SPR_Exxx_L1CSR0, t0);
4229
4230 return true;
4231 }
4232
4233 static bool trans_DST(DisasContext *ctx, arg_X_ea *a)
4234 {
4235 REQUIRE_INSNS_FLAGS(ctx, ALTIVEC);
4236
4237 if (a->ra == 0) {
4238 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
4239 }
4240
4241 return true;
4242 }
4243
4244 static bool trans_DSTST(DisasContext *ctx, arg_X_ea *a)
4245 {
4246 REQUIRE_INSNS_FLAGS(ctx, ALTIVEC);
4247
4248 if (a->ra == 0) {
4249 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
4250 }
4251
4252 return true;
4253 }
4254
4255 static bool trans_DCBF(DisasContext *ctx, arg_X_l *a)
4256 {
4257 TCGv EA;
4258
4259 REQUIRE_INSNS_FLAGS(ctx, CACHE);
4260
4261 /*
4262 * As per PowerISA v3.1, the L field can have values 0, 1, 3, 4, or 6.
4263 * Other values are Undefined Behavior (UB).
4264 */
4265 switch (a->l) {
4266 case 0: /* dcbf */
4267 case 1: /* dcbfl */
4268 case 3: /* dcbflp */
4269 case 4: /* dcbfps */
4270 case 6: /* dcbstps */
4271 break;
4272 default:
4273 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
4274 return true;
4275 }
4276
4277 gen_set_access_type(ctx, ACCESS_CACHE);
4278 EA = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
4279 gen_qemu_ld8u(ctx, EA, EA);
4280
4281 return true;
4282 }
4283
4284 static bool trans_DCBST(DisasContext *ctx, arg_X_ea *a)
4285 {
4286 TCGv EA;
4287
4288 REQUIRE_INSNS_FLAGS(ctx, CACHE);
4289
4290 gen_set_access_type(ctx, ACCESS_CACHE);
4291 EA = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
4292 gen_qemu_ld8u(ctx, EA, EA);
4293
4294 return true;
4295 }
4296
4297 static bool trans_DCBFEP(DisasContext *ctx, arg_X_ea *a)
4298 {
4299 TCGv EA;
4300
4301 REQUIRE_INSNS_FLAGS2(ctx, BOOKE206);
4302
4303 REQUIRE_SV(ctx);
4304
4305 gen_set_access_type(ctx, ACCESS_CACHE);
4306 EA = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
4307
4308 tcg_gen_qemu_ld_tl(EA, EA, PPC_TLB_EPID_LOAD, DEF_MEMOP(MO_UB));
4309
4310 return true;
4311 }
4312
4313 static bool trans_DCBSTEP(DisasContext *ctx, arg_X_ea *a)
4314 {
4315 TCGv EA;
4316
4317 REQUIRE_INSNS_FLAGS2(ctx, BOOKE206);
4318
4319 gen_set_access_type(ctx, ACCESS_CACHE);
4320 EA = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
4321
4322 tcg_gen_qemu_ld_tl(EA, EA, PPC_TLB_EPID_LOAD, DEF_MEMOP(MO_UB));
4323
4324 return true;
4325 }
4326
4327 static bool trans_DCBI(DisasContext *ctx, arg_X_ea *a)
4328 {
4329 REQUIRE_INSNS_FLAGS(ctx, CACHE);
4330
4331 #if defined(CONFIG_USER_ONLY)
4332 gen_priv_opc(ctx);
4333 return true;
4334 #else
4335 TCGv EA, val;
4336
4337 REQUIRE_SV(ctx);
4338
4339 gen_set_access_type(ctx, ACCESS_CACHE);
4340 EA = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
4341 val = tcg_temp_new();
4342
4343 gen_qemu_ld8u(ctx, val, EA);
4344 gen_qemu_st8(ctx, val, EA);
4345
4346 return true;
4347 #endif
4348 }
4349
4350 static bool trans_ICBI(DisasContext *ctx, arg_X_ea *a)
4351 {
4352 TCGv EA;
4353
4354 REQUIRE_INSNS_FLAGS(ctx, CACHE_ICBI);
4355
4356 gen_set_access_type(ctx, ACCESS_CACHE);
4357
4358 EA = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
4359 gen_helper_ICBI(tcg_env, EA);
4360
4361 return true;
4362 }
4363
4364 static bool trans_ICBIEP(DisasContext *ctx, arg_X_ea *a)
4365 {
4366 TCGv EA;
4367
4368 REQUIRE_INSNS_FLAGS2(ctx, BOOKE206);
4369 REQUIRE_SV(ctx);
4370
4371 gen_set_access_type(ctx, ACCESS_CACHE);
4372 EA = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
4373
4374 gen_helper_ICBIEP(tcg_env, EA);
4375 return true;
4376 }
4377
4378 #include "translate/fixedpoint-impl.c.inc"
4379
4380 #include "translate/fp-impl.c.inc"
4381
4382 #include "translate/vmx-impl.c.inc"
4383
4384 #include "translate/vsx-impl.c.inc"
4385
4386 #include "translate/dfp-impl.c.inc"
4387
4388 #include "translate/spe-impl.c.inc"
4389
4390 #include "translate/branch-impl.c.inc"
4391
4392 #include "translate/processor-ctrl-impl.c.inc"
4393
4394 #include "translate/storage-ctrl-impl.c.inc"
4395
4396 #include "translate/misc-impl.c.inc"
4397
4398 #include "translate/bhrb-impl.c.inc"
4399
4400 #include "translate/ppe-impl.c.inc"
4401
4402 /* Handles lfdp */
4403 static void gen_dform39(DisasContext *ctx)
4404 {
4405 if ((ctx->opcode & 0x3) == 0) {
4406 if (ctx->insns_flags2 & PPC2_ISA205) {
4407 return gen_lfdp(ctx);
4408 }
4409 }
4410 return gen_invalid(ctx);
4411 }
4412
4413 /* Handles stfdp */
4414 static void gen_dform3D(DisasContext *ctx)
4415 {
4416 if ((ctx->opcode & 3) == 0) { /* DS-FORM */
4417 /* stfdp */
4418 if (ctx->insns_flags2 & PPC2_ISA205) {
4419 return gen_stfdp(ctx);
4420 }
4421 }
4422 return gen_invalid(ctx);
4423 }
4424
4425 static opcode_t opcodes[] = {
4426 GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE),
4427 GEN_HANDLER_E(copy, 0x1F, 0x06, 0x18, 0x03C00001, PPC_NONE, PPC2_ISA300),
4428 GEN_HANDLER_E(cp_abort, 0x1F, 0x06, 0x1A, 0x03FFF801, PPC_NONE, PPC2_ISA300),
4429 GEN_HANDLER_E(paste, 0x1F, 0x06, 0x1C, 0x03C00000, PPC_NONE, PPC2_ISA300),
4430 GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
4431 /* handles lfdp, lxsd, lxssp */
4432 GEN_HANDLER_E(dform39, 0x39, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205),
4433 /* handles stfdp, stxsd, stxssp */
4434 GEN_HANDLER_E(dform3D, 0x3D, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205),
4435 GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC),
4436 GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC),
4437 GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB),
4438 #if defined(TARGET_PPC64)
4439 GEN_HANDLER_E(setb, 0x1F, 0x00, 0x04, 0x0003F801, PPC_NONE, PPC2_ISA300),
4440 GEN_HANDLER_E(mcrxrx, 0x1F, 0x00, 0x12, 0x007FF801, PPC_NONE, PPC2_ISA300),
4441 #endif
4442 GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000000, PPC_MISC),
4443 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZ),
4444 GEN_HANDLER_E(dcbzep, 0x1F, 0x1F, 0x1F, 0x03C00001, PPC_NONE, PPC2_BOOKE206),
4445 GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT),
4446 GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT),
4447 GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT),
4448 GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT),
4449 #if defined(TARGET_PPC64)
4450 GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B),
4451 GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
4452 PPC_SEGMENT_64B),
4453 GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B),
4454 GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
4455 PPC_SEGMENT_64B),
4456 #endif
4457 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
4458 /*
4459 * XXX Those instructions will need to be handled differently for
4460 * different ISA versions
4461 */
4462 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC),
4463 GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN),
4464 GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN),
4465 GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB),
4466 GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB),
4467 GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI),
4468 GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA),
4469 GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR),
4470 GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR),
4471 GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX),
4472 GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX),
4473 GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON),
4474 GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON),
4475 GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT),
4476 GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON),
4477 GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON),
4478 GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP),
4479 GEN_HANDLER_E(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE, PPC2_BOOKE206),
4480 GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI),
4481 GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI),
4482 GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB),
4483 GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB),
4484 GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB),
4485 GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE),
4486 GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE),
4487 GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE),
4488 GEN_HANDLER2_E(tlbre_booke206, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001,
4489 PPC_NONE, PPC2_BOOKE206),
4490 GEN_HANDLER2_E(tlbsx_booke206, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000,
4491 PPC_NONE, PPC2_BOOKE206),
4492 GEN_HANDLER2_E(tlbwe_booke206, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001,
4493 PPC_NONE, PPC2_BOOKE206),
4494 GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001,
4495 PPC_NONE, PPC2_BOOKE206),
4496 GEN_HANDLER2_E(tlbilx_booke206, "tlbilx", 0x1F, 0x12, 0x00, 0x03800001,
4497 PPC_NONE, PPC2_BOOKE206),
4498 GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE),
4499 GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE),
4500 GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC),
4501 GEN_HANDLER2_E(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x02000001,
4502 PPC_BOOKE, (PPC2_BOOKE206 | PPC2_ISA207)),
4503 GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x06, 0x08, 0x03E00001,
4504 PPC_440_SPEC),
4505 GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC),
4506 GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC),
4507
4508 #if defined(TARGET_PPC64)
4509 #undef GEN_PPC64_R2
4510 #undef GEN_PPC64_R4
4511 #define GEN_PPC64_R2(name, opc1, opc2) \
4512 GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
4513 GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000, \
4514 PPC_64B)
4515 #define GEN_PPC64_R4(name, opc1, opc2) \
4516 GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
4517 GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000, \
4518 PPC_64B), \
4519 GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000, \
4520 PPC_64B), \
4521 GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000, \
4522 PPC_64B)
4523 GEN_PPC64_R4(rldicl, 0x1E, 0x00),
4524 GEN_PPC64_R4(rldicr, 0x1E, 0x02),
4525 GEN_PPC64_R4(rldic, 0x1E, 0x04),
4526 GEN_PPC64_R2(rldcl, 0x1E, 0x08),
4527 GEN_PPC64_R2(rldcr, 0x1E, 0x09),
4528 GEN_PPC64_R4(rldimi, 0x1E, 0x06),
4529 #endif
4530
4531 #undef GEN_LDX_E
4532 #define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk) \
4533 GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
4534
4535 #if defined(TARGET_PPC64)
4536 GEN_LDX_E(ldbr, ld64ur_i64, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE)
4537
4538 /* HV/P7 and later only */
4539 GEN_LDX_HVRM(ldcix, ld64_i64, 0x15, 0x1b, PPC_CILDST)
4540 GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x18, PPC_CILDST)
4541 GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
4542 GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
4543 #endif
4544 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
4545 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
4546
4547 /* External PID based load */
4548 #undef GEN_LDEPX
4549 #define GEN_LDEPX(name, ldop, opc2, opc3) \
4550 GEN_HANDLER_E(name##epx, 0x1F, opc2, opc3, \
4551 0x00000001, PPC_NONE, PPC2_BOOKE206),
4552
4553 GEN_LDEPX(lb, DEF_MEMOP(MO_UB), 0x1F, 0x02)
4554 GEN_LDEPX(lh, DEF_MEMOP(MO_UW), 0x1F, 0x08)
4555 GEN_LDEPX(lw, DEF_MEMOP(MO_UL), 0x1F, 0x00)
4556 #if defined(TARGET_PPC64)
4557 GEN_LDEPX(ld, DEF_MEMOP(MO_UQ), 0x1D, 0x00)
4558 #endif
4559
4560 #undef GEN_STEPX
4561 #define GEN_STEPX(name, ldop, opc2, opc3) \
4562 GEN_HANDLER_E(name##epx, 0x1F, opc2, opc3, \
4563 0x00000001, PPC_NONE, PPC2_BOOKE206),
4564
4565 GEN_STEPX(stb, DEF_MEMOP(MO_UB), 0x1F, 0x06)
4566 GEN_STEPX(sth, DEF_MEMOP(MO_UW), 0x1F, 0x0C)
4567 GEN_STEPX(stw, DEF_MEMOP(MO_UL), 0x1F, 0x04)
4568 #if defined(TARGET_PPC64)
4569 GEN_STEPX(std, DEF_MEMOP(MO_UQ), 0x1D, 0x04)
4570 #endif
4571
4572 #undef GEN_MAC_HANDLER
4573 #define GEN_MAC_HANDLER(name, opc2, opc3) \
4574 GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)
4575 GEN_MAC_HANDLER(macchw, 0x0C, 0x05),
4576 GEN_MAC_HANDLER(macchwo, 0x0C, 0x15),
4577 GEN_MAC_HANDLER(macchws, 0x0C, 0x07),
4578 GEN_MAC_HANDLER(macchwso, 0x0C, 0x17),
4579 GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06),
4580 GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16),
4581 GEN_MAC_HANDLER(macchwu, 0x0C, 0x04),
4582 GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14),
4583 GEN_MAC_HANDLER(machhw, 0x0C, 0x01),
4584 GEN_MAC_HANDLER(machhwo, 0x0C, 0x11),
4585 GEN_MAC_HANDLER(machhws, 0x0C, 0x03),
4586 GEN_MAC_HANDLER(machhwso, 0x0C, 0x13),
4587 GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02),
4588 GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12),
4589 GEN_MAC_HANDLER(machhwu, 0x0C, 0x00),
4590 GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10),
4591 GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D),
4592 GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D),
4593 GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F),
4594 GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F),
4595 GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C),
4596 GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C),
4597 GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E),
4598 GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E),
4599 GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05),
4600 GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15),
4601 GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07),
4602 GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17),
4603 GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01),
4604 GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11),
4605 GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03),
4606 GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13),
4607 GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D),
4608 GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D),
4609 GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F),
4610 GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F),
4611 GEN_MAC_HANDLER(mulchw, 0x08, 0x05),
4612 GEN_MAC_HANDLER(mulchwu, 0x08, 0x04),
4613 GEN_MAC_HANDLER(mulhhw, 0x08, 0x01),
4614 GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00),
4615 GEN_MAC_HANDLER(mullhw, 0x08, 0x0D),
4616 GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C),
4617
4618 GEN_HANDLER2_E(tbegin, "tbegin", 0x1F, 0x0E, 0x14, 0x01DFF800, \
4619 PPC_NONE, PPC2_TM),
4620 GEN_HANDLER2_E(tend, "tend", 0x1F, 0x0E, 0x15, 0x01FFF800, \
4621 PPC_NONE, PPC2_TM),
4622 GEN_HANDLER2_E(tabort, "tabort", 0x1F, 0x0E, 0x1C, 0x03E0F800, \
4623 PPC_NONE, PPC2_TM),
4624 GEN_HANDLER2_E(tabortwc, "tabortwc", 0x1F, 0x0E, 0x18, 0x00000000, \
4625 PPC_NONE, PPC2_TM),
4626 GEN_HANDLER2_E(tabortwci, "tabortwci", 0x1F, 0x0E, 0x1A, 0x00000000, \
4627 PPC_NONE, PPC2_TM),
4628 GEN_HANDLER2_E(tabortdc, "tabortdc", 0x1F, 0x0E, 0x19, 0x00000000, \
4629 PPC_NONE, PPC2_TM),
4630 GEN_HANDLER2_E(tabortdci, "tabortdci", 0x1F, 0x0E, 0x1B, 0x00000000, \
4631 PPC_NONE, PPC2_TM),
4632 GEN_HANDLER2_E(tsr, "tsr", 0x1F, 0x0E, 0x17, 0x03DFF800, \
4633 PPC_NONE, PPC2_TM),
4634 GEN_HANDLER2_E(tcheck, "tcheck", 0x1F, 0x0E, 0x16, 0x007FF800, \
4635 PPC_NONE, PPC2_TM),
4636 GEN_HANDLER2_E(treclaim, "treclaim", 0x1F, 0x0E, 0x1D, 0x03E0F800, \
4637 PPC_NONE, PPC2_TM),
4638 GEN_HANDLER2_E(trechkpt, "trechkpt", 0x1F, 0x0E, 0x1F, 0x03FFF800, \
4639 PPC_NONE, PPC2_TM),
4640
4641 #include "translate/fp-ops.c.inc"
4642
4643 #include "translate/vmx-ops.c.inc"
4644
4645 #include "translate/vsx-ops.c.inc"
4646
4647 #include "translate/spe-ops.c.inc"
4648 };
4649
4650 /*****************************************************************************/
4651 /* Opcode types */
4652 enum {
4653 PPC_DIRECT = 0, /* Opcode routine */
4654 PPC_INDIRECT = 1, /* Indirect opcode table */
4655 };
4656
4657 #define PPC_OPCODE_MASK 0x3
4658
4659 static inline int is_indirect_opcode(void *handler)
4660 {
4661 return ((uintptr_t)handler & PPC_OPCODE_MASK) == PPC_INDIRECT;
4662 }
4663
4664 static inline opc_handler_t **ind_table(void *handler)
4665 {
4666 return (opc_handler_t **)((uintptr_t)handler & ~PPC_OPCODE_MASK);
4667 }
4668
4669 /* Instruction table creation */
4670 /* Opcodes tables creation */
4671 static void fill_new_table(opc_handler_t **table, int len)
4672 {
4673 int i;
4674
4675 for (i = 0; i < len; i++) {
4676 table[i] = &invalid_handler;
4677 }
4678 }
4679
4680 static int create_new_table(opc_handler_t **table, unsigned char idx)
4681 {
4682 opc_handler_t **tmp;
4683
4684 tmp = g_new(opc_handler_t *, PPC_CPU_INDIRECT_OPCODES_LEN);
4685 fill_new_table(tmp, PPC_CPU_INDIRECT_OPCODES_LEN);
4686 table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT);
4687
4688 return 0;
4689 }
4690
4691 static int insert_in_table(opc_handler_t **table, unsigned char idx,
4692 opc_handler_t *handler)
4693 {
4694 if (table[idx] != &invalid_handler) {
4695 return -1;
4696 }
4697 table[idx] = handler;
4698
4699 return 0;
4700 }
4701
4702 static int register_direct_insn(opc_handler_t **ppc_opcodes,
4703 unsigned char idx, opc_handler_t *handler)
4704 {
4705 if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
4706 printf("*** ERROR: opcode %02x already assigned in main "
4707 "opcode table\n", idx);
4708 return -1;
4709 }
4710
4711 return 0;
4712 }
4713
4714 static int register_ind_in_table(opc_handler_t **table,
4715 unsigned char idx1, unsigned char idx2,
4716 opc_handler_t *handler)
4717 {
4718 if (table[idx1] == &invalid_handler) {
4719 if (create_new_table(table, idx1) < 0) {
4720 printf("*** ERROR: unable to create indirect table "
4721 "idx=%02x\n", idx1);
4722 return -1;
4723 }
4724 } else {
4725 if (!is_indirect_opcode(table[idx1])) {
4726 printf("*** ERROR: idx %02x already assigned to a direct "
4727 "opcode\n", idx1);
4728 return -1;
4729 }
4730 }
4731 if (handler != NULL &&
4732 insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {
4733 printf("*** ERROR: opcode %02x already assigned in "
4734 "opcode table %02x\n", idx2, idx1);
4735 return -1;
4736 }
4737
4738 return 0;
4739 }
4740
4741 static int register_ind_insn(opc_handler_t **ppc_opcodes,
4742 unsigned char idx1, unsigned char idx2,
4743 opc_handler_t *handler)
4744 {
4745 return register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
4746 }
4747
4748 static int register_dblind_insn(opc_handler_t **ppc_opcodes,
4749 unsigned char idx1, unsigned char idx2,
4750 unsigned char idx3, opc_handler_t *handler)
4751 {
4752 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
4753 printf("*** ERROR: unable to join indirect table idx "
4754 "[%02x-%02x]\n", idx1, idx2);
4755 return -1;
4756 }
4757 if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,
4758 handler) < 0) {
4759 printf("*** ERROR: unable to insert opcode "
4760 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
4761 return -1;
4762 }
4763
4764 return 0;
4765 }
4766
4767 static int register_trplind_insn(opc_handler_t **ppc_opcodes,
4768 unsigned char idx1, unsigned char idx2,
4769 unsigned char idx3, unsigned char idx4,
4770 opc_handler_t *handler)
4771 {
4772 opc_handler_t **table;
4773
4774 if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
4775 printf("*** ERROR: unable to join indirect table idx "
4776 "[%02x-%02x]\n", idx1, idx2);
4777 return -1;
4778 }
4779 table = ind_table(ppc_opcodes[idx1]);
4780 if (register_ind_in_table(table, idx2, idx3, NULL) < 0) {
4781 printf("*** ERROR: unable to join 2nd-level indirect table idx "
4782 "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
4783 return -1;
4784 }
4785 table = ind_table(table[idx2]);
4786 if (register_ind_in_table(table, idx3, idx4, handler) < 0) {
4787 printf("*** ERROR: unable to insert opcode "
4788 "[%02x-%02x-%02x-%02x]\n", idx1, idx2, idx3, idx4);
4789 return -1;
4790 }
4791 return 0;
4792 }
4793 static int register_insn(opc_handler_t **ppc_opcodes, opcode_t *insn)
4794 {
4795 if (insn->opc2 != 0xFF) {
4796 if (insn->opc3 != 0xFF) {
4797 if (insn->opc4 != 0xFF) {
4798 if (register_trplind_insn(ppc_opcodes, insn->opc1, insn->opc2,
4799 insn->opc3, insn->opc4,
4800 &insn->handler) < 0) {
4801 return -1;
4802 }
4803 } else {
4804 if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2,
4805 insn->opc3, &insn->handler) < 0) {
4806 return -1;
4807 }
4808 }
4809 } else {
4810 if (register_ind_insn(ppc_opcodes, insn->opc1,
4811 insn->opc2, &insn->handler) < 0) {
4812 return -1;
4813 }
4814 }
4815 } else {
4816 if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0) {
4817 return -1;
4818 }
4819 }
4820
4821 return 0;
4822 }
4823
4824 static int test_opcode_table(opc_handler_t **table, int len)
4825 {
4826 int i, count, tmp;
4827
4828 for (i = 0, count = 0; i < len; i++) {
4829 /* Consistency fixup */
4830 if (table[i] == NULL) {
4831 table[i] = &invalid_handler;
4832 }
4833 if (table[i] != &invalid_handler) {
4834 if (is_indirect_opcode(table[i])) {
4835 tmp = test_opcode_table(ind_table(table[i]),
4836 PPC_CPU_INDIRECT_OPCODES_LEN);
4837 if (tmp == 0) {
4838 g_free(table[i]);
4839 table[i] = &invalid_handler;
4840 } else {
4841 count++;
4842 }
4843 } else {
4844 count++;
4845 }
4846 }
4847 }
4848
4849 return count;
4850 }
4851
4852 static void fix_opcode_tables(opc_handler_t **ppc_opcodes)
4853 {
4854 if (test_opcode_table(ppc_opcodes, PPC_CPU_OPCODES_LEN) == 0) {
4855 printf("*** WARNING: no opcode defined !\n");
4856 }
4857 }
4858
4859 /*****************************************************************************/
4860 void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp)
4861 {
4862 PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
4863 opcode_t *opc;
4864
4865 fill_new_table(cpu->opcodes, PPC_CPU_OPCODES_LEN);
4866 for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) {
4867 if (((opc->handler.type & pcc->insns_flags) != 0) ||
4868 ((opc->handler.type2 & pcc->insns_flags2) != 0)) {
4869 if (register_insn(cpu->opcodes, opc) < 0) {
4870 error_setg(errp, "ERROR initializing PowerPC instruction "
4871 "0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2,
4872 opc->opc3);
4873 return;
4874 }
4875 }
4876 }
4877 fix_opcode_tables(cpu->opcodes);
4878 fflush(stdout);
4879 fflush(stderr);
4880 }
4881
4882 void destroy_ppc_opcodes(PowerPCCPU *cpu)
4883 {
4884 opc_handler_t **table, **table_2;
4885 int i, j, k;
4886
4887 for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) {
4888 if (cpu->opcodes[i] == &invalid_handler) {
4889 continue;
4890 }
4891 if (is_indirect_opcode(cpu->opcodes[i])) {
4892 table = ind_table(cpu->opcodes[i]);
4893 for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) {
4894 if (table[j] == &invalid_handler) {
4895 continue;
4896 }
4897 if (is_indirect_opcode(table[j])) {
4898 table_2 = ind_table(table[j]);
4899 for (k = 0; k < PPC_CPU_INDIRECT_OPCODES_LEN; k++) {
4900 if (table_2[k] != &invalid_handler &&
4901 is_indirect_opcode(table_2[k])) {
4902 g_free((opc_handler_t *)((uintptr_t)table_2[k] &
4903 ~PPC_INDIRECT));
4904 }
4905 }
4906 g_free((opc_handler_t *)((uintptr_t)table[j] &
4907 ~PPC_INDIRECT));
4908 }
4909 }
4910 g_free((opc_handler_t *)((uintptr_t)cpu->opcodes[i] &
4911 ~PPC_INDIRECT));
4912 }
4913 }
4914 }
4915
4916 int ppc_fixup_cpu(PowerPCCPU *cpu)
4917 {
4918 CPUPPCState *env = &cpu->env;
4919
4920 /*
4921 * TCG doesn't (yet) emulate some groups of instructions that are
4922 * implemented on some otherwise supported CPUs (e.g. VSX and
4923 * decimal floating point instructions on POWER7). We remove
4924 * unsupported instruction groups from the cpu state's instruction
4925 * masks and hope the guest can cope. For at least the pseries
4926 * machine, the unavailability of these instructions can be
4927 * advertised to the guest via the device tree.
4928 */
4929 if ((env->insns_flags & ~PPC_TCG_INSNS)
4930 || (env->insns_flags2 & ~PPC_TCG_INSNS2)) {
4931 warn_report("Disabling some instructions which are not "
4932 "emulated by TCG (0x%" PRIx64 ", 0x%" PRIx64 ")",
4933 env->insns_flags & ~PPC_TCG_INSNS,
4934 env->insns_flags2 & ~PPC_TCG_INSNS2);
4935 }
4936 env->insns_flags &= PPC_TCG_INSNS;
4937 env->insns_flags2 &= PPC_TCG_INSNS2;
4938 return 0;
4939 }
4940
4941 static bool decode_legacy(PowerPCCPU *cpu, DisasContext *ctx, uint32_t insn)
4942 {
4943 opc_handler_t **table, *handler;
4944 uint32_t inval;
4945
4946 LOG_DISAS("translate opcode %08x (%02x %02x %02x %02x) (%s)\n",
4947 insn, opc1(insn), opc2(insn), opc3(insn), opc4(insn),
4948 ctx->le_mode ? "little" : "big");
4949
4950 table = cpu->opcodes;
4951 handler = table[opc1(insn)];
4952 if (is_indirect_opcode(handler)) {
4953 table = ind_table(handler);
4954 handler = table[opc2(insn)];
4955 if (is_indirect_opcode(handler)) {
4956 table = ind_table(handler);
4957 handler = table[opc3(insn)];
4958 if (is_indirect_opcode(handler)) {
4959 table = ind_table(handler);
4960 handler = table[opc4(insn)];
4961 }
4962 }
4963 }
4964
4965 /* Is opcode *REALLY* valid ? */
4966 if (unlikely(handler->handler == &gen_invalid)) {
4967 qemu_log_mask(LOG_GUEST_ERROR, "invalid/unsupported opcode: "
4968 "%02x - %02x - %02x - %02x (%08x) "
4969 TARGET_FMT_lx "\n",
4970 opc1(insn), opc2(insn), opc3(insn), opc4(insn),
4971 insn, ctx->cia);
4972 return false;
4973 }
4974
4975 if (unlikely(handler->type & (PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE)
4976 && Rc(insn))) {
4977 inval = handler->inval2;
4978 } else {
4979 inval = handler->inval1;
4980 }
4981
4982 if (unlikely((insn & inval) != 0)) {
4983 qemu_log_mask(LOG_GUEST_ERROR, "invalid bits: %08x for opcode: "
4984 "%02x - %02x - %02x - %02x (%08x) "
4985 TARGET_FMT_lx "\n", insn & inval,
4986 opc1(insn), opc2(insn), opc3(insn), opc4(insn),
4987 insn, ctx->cia);
4988 return false;
4989 }
4990
4991 handler->handler(ctx);
4992 return true;
4993 }
4994
4995 static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
4996 {
4997 DisasContext *ctx = container_of(dcbase, DisasContext, base);
4998 CPUPPCState *env = cpu_env(cs);
4999 uint32_t hflags = ctx->base.tb->flags;
5000
Showing first 5,000 of 5,198 lines. View raw