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