]> git.proxmox.com Git - qemu.git/blob - target-s390x/translate.c
cba7b8752709f12f105268c16d159207ead9bdb0
[qemu.git] / target-s390x / translate.c
1 /*
2 * S/390 translation
3 *
4 * Copyright (c) 2009 Ulrich Hecht
5 * Copyright (c) 2010 Alexander Graf
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 */
20
21 /* #define DEBUG_INLINE_BRANCHES */
22 #define S390X_DEBUG_DISAS
23 /* #define S390X_DEBUG_DISAS_VERBOSE */
24
25 #ifdef S390X_DEBUG_DISAS_VERBOSE
26 # define LOG_DISAS(...) qemu_log(__VA_ARGS__)
27 #else
28 # define LOG_DISAS(...) do { } while (0)
29 #endif
30
31 #include "cpu.h"
32 #include "disas/disas.h"
33 #include "tcg-op.h"
34 #include "qemu/log.h"
35 #include "qemu/host-utils.h"
36
37 /* global register indexes */
38 static TCGv_ptr cpu_env;
39
40 #include "exec/gen-icount.h"
41 #include "helper.h"
42 #define GEN_HELPER 1
43 #include "helper.h"
44
45
46 /* Information that (most) every instruction needs to manipulate. */
47 typedef struct DisasContext DisasContext;
48 typedef struct DisasInsn DisasInsn;
49 typedef struct DisasFields DisasFields;
50
51 struct DisasContext {
52 struct TranslationBlock *tb;
53 const DisasInsn *insn;
54 DisasFields *fields;
55 uint64_t pc, next_pc;
56 enum cc_op cc_op;
57 bool singlestep_enabled;
58 };
59
60 /* Information carried about a condition to be evaluated. */
61 typedef struct {
62 TCGCond cond:8;
63 bool is_64;
64 bool g1;
65 bool g2;
66 union {
67 struct { TCGv_i64 a, b; } s64;
68 struct { TCGv_i32 a, b; } s32;
69 } u;
70 } DisasCompare;
71
72 #define DISAS_EXCP 4
73
74 #ifdef DEBUG_INLINE_BRANCHES
75 static uint64_t inline_branch_hit[CC_OP_MAX];
76 static uint64_t inline_branch_miss[CC_OP_MAX];
77 #endif
78
79 static uint64_t pc_to_link_info(DisasContext *s, uint64_t pc)
80 {
81 if (!(s->tb->flags & FLAG_MASK_64)) {
82 if (s->tb->flags & FLAG_MASK_32) {
83 return pc | 0x80000000;
84 }
85 }
86 return pc;
87 }
88
89 void s390_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
90 int flags)
91 {
92 S390CPU *cpu = S390_CPU(cs);
93 CPUS390XState *env = &cpu->env;
94 int i;
95
96 if (env->cc_op > 3) {
97 cpu_fprintf(f, "PSW=mask %016" PRIx64 " addr %016" PRIx64 " cc %15s\n",
98 env->psw.mask, env->psw.addr, cc_name(env->cc_op));
99 } else {
100 cpu_fprintf(f, "PSW=mask %016" PRIx64 " addr %016" PRIx64 " cc %02x\n",
101 env->psw.mask, env->psw.addr, env->cc_op);
102 }
103
104 for (i = 0; i < 16; i++) {
105 cpu_fprintf(f, "R%02d=%016" PRIx64, i, env->regs[i]);
106 if ((i % 4) == 3) {
107 cpu_fprintf(f, "\n");
108 } else {
109 cpu_fprintf(f, " ");
110 }
111 }
112
113 for (i = 0; i < 16; i++) {
114 cpu_fprintf(f, "F%02d=%016" PRIx64, i, env->fregs[i].ll);
115 if ((i % 4) == 3) {
116 cpu_fprintf(f, "\n");
117 } else {
118 cpu_fprintf(f, " ");
119 }
120 }
121
122 #ifndef CONFIG_USER_ONLY
123 for (i = 0; i < 16; i++) {
124 cpu_fprintf(f, "C%02d=%016" PRIx64, i, env->cregs[i]);
125 if ((i % 4) == 3) {
126 cpu_fprintf(f, "\n");
127 } else {
128 cpu_fprintf(f, " ");
129 }
130 }
131 #endif
132
133 #ifdef DEBUG_INLINE_BRANCHES
134 for (i = 0; i < CC_OP_MAX; i++) {
135 cpu_fprintf(f, " %15s = %10ld\t%10ld\n", cc_name(i),
136 inline_branch_miss[i], inline_branch_hit[i]);
137 }
138 #endif
139
140 cpu_fprintf(f, "\n");
141 }
142
143 static TCGv_i64 psw_addr;
144 static TCGv_i64 psw_mask;
145
146 static TCGv_i32 cc_op;
147 static TCGv_i64 cc_src;
148 static TCGv_i64 cc_dst;
149 static TCGv_i64 cc_vr;
150
151 static char cpu_reg_names[32][4];
152 static TCGv_i64 regs[16];
153 static TCGv_i64 fregs[16];
154
155 static uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
156
157 void s390x_translate_init(void)
158 {
159 int i;
160
161 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
162 psw_addr = tcg_global_mem_new_i64(TCG_AREG0,
163 offsetof(CPUS390XState, psw.addr),
164 "psw_addr");
165 psw_mask = tcg_global_mem_new_i64(TCG_AREG0,
166 offsetof(CPUS390XState, psw.mask),
167 "psw_mask");
168
169 cc_op = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUS390XState, cc_op),
170 "cc_op");
171 cc_src = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUS390XState, cc_src),
172 "cc_src");
173 cc_dst = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUS390XState, cc_dst),
174 "cc_dst");
175 cc_vr = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUS390XState, cc_vr),
176 "cc_vr");
177
178 for (i = 0; i < 16; i++) {
179 snprintf(cpu_reg_names[i], sizeof(cpu_reg_names[0]), "r%d", i);
180 regs[i] = tcg_global_mem_new(TCG_AREG0,
181 offsetof(CPUS390XState, regs[i]),
182 cpu_reg_names[i]);
183 }
184
185 for (i = 0; i < 16; i++) {
186 snprintf(cpu_reg_names[i + 16], sizeof(cpu_reg_names[0]), "f%d", i);
187 fregs[i] = tcg_global_mem_new(TCG_AREG0,
188 offsetof(CPUS390XState, fregs[i].d),
189 cpu_reg_names[i + 16]);
190 }
191
192 /* register helpers */
193 #define GEN_HELPER 2
194 #include "helper.h"
195 }
196
197 static TCGv_i64 load_reg(int reg)
198 {
199 TCGv_i64 r = tcg_temp_new_i64();
200 tcg_gen_mov_i64(r, regs[reg]);
201 return r;
202 }
203
204 static TCGv_i64 load_freg32_i64(int reg)
205 {
206 TCGv_i64 r = tcg_temp_new_i64();
207 tcg_gen_shri_i64(r, fregs[reg], 32);
208 return r;
209 }
210
211 static void store_reg(int reg, TCGv_i64 v)
212 {
213 tcg_gen_mov_i64(regs[reg], v);
214 }
215
216 static void store_freg(int reg, TCGv_i64 v)
217 {
218 tcg_gen_mov_i64(fregs[reg], v);
219 }
220
221 static void store_reg32_i64(int reg, TCGv_i64 v)
222 {
223 /* 32 bit register writes keep the upper half */
224 tcg_gen_deposit_i64(regs[reg], regs[reg], v, 0, 32);
225 }
226
227 static void store_reg32h_i64(int reg, TCGv_i64 v)
228 {
229 tcg_gen_deposit_i64(regs[reg], regs[reg], v, 32, 32);
230 }
231
232 static void store_freg32_i64(int reg, TCGv_i64 v)
233 {
234 tcg_gen_deposit_i64(fregs[reg], fregs[reg], v, 32, 32);
235 }
236
237 static void return_low128(TCGv_i64 dest)
238 {
239 tcg_gen_ld_i64(dest, cpu_env, offsetof(CPUS390XState, retxl));
240 }
241
242 static void update_psw_addr(DisasContext *s)
243 {
244 /* psw.addr */
245 tcg_gen_movi_i64(psw_addr, s->pc);
246 }
247
248 static void update_cc_op(DisasContext *s)
249 {
250 if (s->cc_op != CC_OP_DYNAMIC && s->cc_op != CC_OP_STATIC) {
251 tcg_gen_movi_i32(cc_op, s->cc_op);
252 }
253 }
254
255 static void potential_page_fault(DisasContext *s)
256 {
257 update_psw_addr(s);
258 update_cc_op(s);
259 }
260
261 static inline uint64_t ld_code2(CPUS390XState *env, uint64_t pc)
262 {
263 return (uint64_t)cpu_lduw_code(env, pc);
264 }
265
266 static inline uint64_t ld_code4(CPUS390XState *env, uint64_t pc)
267 {
268 return (uint64_t)(uint32_t)cpu_ldl_code(env, pc);
269 }
270
271 static inline uint64_t ld_code6(CPUS390XState *env, uint64_t pc)
272 {
273 return (ld_code2(env, pc) << 32) | ld_code4(env, pc + 2);
274 }
275
276 static int get_mem_index(DisasContext *s)
277 {
278 switch (s->tb->flags & FLAG_MASK_ASC) {
279 case PSW_ASC_PRIMARY >> 32:
280 return 0;
281 case PSW_ASC_SECONDARY >> 32:
282 return 1;
283 case PSW_ASC_HOME >> 32:
284 return 2;
285 default:
286 tcg_abort();
287 break;
288 }
289 }
290
291 static void gen_exception(int excp)
292 {
293 TCGv_i32 tmp = tcg_const_i32(excp);
294 gen_helper_exception(cpu_env, tmp);
295 tcg_temp_free_i32(tmp);
296 }
297
298 static void gen_program_exception(DisasContext *s, int code)
299 {
300 TCGv_i32 tmp;
301
302 /* Remember what pgm exeption this was. */
303 tmp = tcg_const_i32(code);
304 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUS390XState, int_pgm_code));
305 tcg_temp_free_i32(tmp);
306
307 tmp = tcg_const_i32(s->next_pc - s->pc);
308 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUS390XState, int_pgm_ilen));
309 tcg_temp_free_i32(tmp);
310
311 /* Advance past instruction. */
312 s->pc = s->next_pc;
313 update_psw_addr(s);
314
315 /* Save off cc. */
316 update_cc_op(s);
317
318 /* Trigger exception. */
319 gen_exception(EXCP_PGM);
320 }
321
322 static inline void gen_illegal_opcode(DisasContext *s)
323 {
324 gen_program_exception(s, PGM_SPECIFICATION);
325 }
326
327 static inline void check_privileged(DisasContext *s)
328 {
329 if (s->tb->flags & (PSW_MASK_PSTATE >> 32)) {
330 gen_program_exception(s, PGM_PRIVILEGED);
331 }
332 }
333
334 static TCGv_i64 get_address(DisasContext *s, int x2, int b2, int d2)
335 {
336 TCGv_i64 tmp = tcg_temp_new_i64();
337 bool need_31 = !(s->tb->flags & FLAG_MASK_64);
338
339 /* Note that d2 is limited to 20 bits, signed. If we crop negative
340 displacements early we create larger immedate addends. */
341
342 /* Note that addi optimizes the imm==0 case. */
343 if (b2 && x2) {
344 tcg_gen_add_i64(tmp, regs[b2], regs[x2]);
345 tcg_gen_addi_i64(tmp, tmp, d2);
346 } else if (b2) {
347 tcg_gen_addi_i64(tmp, regs[b2], d2);
348 } else if (x2) {
349 tcg_gen_addi_i64(tmp, regs[x2], d2);
350 } else {
351 if (need_31) {
352 d2 &= 0x7fffffff;
353 need_31 = false;
354 }
355 tcg_gen_movi_i64(tmp, d2);
356 }
357 if (need_31) {
358 tcg_gen_andi_i64(tmp, tmp, 0x7fffffff);
359 }
360
361 return tmp;
362 }
363
364 static inline bool live_cc_data(DisasContext *s)
365 {
366 return (s->cc_op != CC_OP_DYNAMIC
367 && s->cc_op != CC_OP_STATIC
368 && s->cc_op > 3);
369 }
370
371 static inline void gen_op_movi_cc(DisasContext *s, uint32_t val)
372 {
373 if (live_cc_data(s)) {
374 tcg_gen_discard_i64(cc_src);
375 tcg_gen_discard_i64(cc_dst);
376 tcg_gen_discard_i64(cc_vr);
377 }
378 s->cc_op = CC_OP_CONST0 + val;
379 }
380
381 static void gen_op_update1_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 dst)
382 {
383 if (live_cc_data(s)) {
384 tcg_gen_discard_i64(cc_src);
385 tcg_gen_discard_i64(cc_vr);
386 }
387 tcg_gen_mov_i64(cc_dst, dst);
388 s->cc_op = op;
389 }
390
391 static void gen_op_update2_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src,
392 TCGv_i64 dst)
393 {
394 if (live_cc_data(s)) {
395 tcg_gen_discard_i64(cc_vr);
396 }
397 tcg_gen_mov_i64(cc_src, src);
398 tcg_gen_mov_i64(cc_dst, dst);
399 s->cc_op = op;
400 }
401
402 static void gen_op_update3_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src,
403 TCGv_i64 dst, TCGv_i64 vr)
404 {
405 tcg_gen_mov_i64(cc_src, src);
406 tcg_gen_mov_i64(cc_dst, dst);
407 tcg_gen_mov_i64(cc_vr, vr);
408 s->cc_op = op;
409 }
410
411 static void set_cc_nz_u64(DisasContext *s, TCGv_i64 val)
412 {
413 gen_op_update1_cc_i64(s, CC_OP_NZ, val);
414 }
415
416 static void gen_set_cc_nz_f32(DisasContext *s, TCGv_i64 val)
417 {
418 gen_op_update1_cc_i64(s, CC_OP_NZ_F32, val);
419 }
420
421 static void gen_set_cc_nz_f64(DisasContext *s, TCGv_i64 val)
422 {
423 gen_op_update1_cc_i64(s, CC_OP_NZ_F64, val);
424 }
425
426 static void gen_set_cc_nz_f128(DisasContext *s, TCGv_i64 vh, TCGv_i64 vl)
427 {
428 gen_op_update2_cc_i64(s, CC_OP_NZ_F128, vh, vl);
429 }
430
431 /* CC value is in env->cc_op */
432 static void set_cc_static(DisasContext *s)
433 {
434 if (live_cc_data(s)) {
435 tcg_gen_discard_i64(cc_src);
436 tcg_gen_discard_i64(cc_dst);
437 tcg_gen_discard_i64(cc_vr);
438 }
439 s->cc_op = CC_OP_STATIC;
440 }
441
442 /* calculates cc into cc_op */
443 static void gen_op_calc_cc(DisasContext *s)
444 {
445 TCGv_i32 local_cc_op;
446 TCGv_i64 dummy;
447
448 TCGV_UNUSED_I32(local_cc_op);
449 TCGV_UNUSED_I64(dummy);
450 switch (s->cc_op) {
451 default:
452 dummy = tcg_const_i64(0);
453 /* FALLTHRU */
454 case CC_OP_ADD_64:
455 case CC_OP_ADDU_64:
456 case CC_OP_ADDC_64:
457 case CC_OP_SUB_64:
458 case CC_OP_SUBU_64:
459 case CC_OP_SUBB_64:
460 case CC_OP_ADD_32:
461 case CC_OP_ADDU_32:
462 case CC_OP_ADDC_32:
463 case CC_OP_SUB_32:
464 case CC_OP_SUBU_32:
465 case CC_OP_SUBB_32:
466 local_cc_op = tcg_const_i32(s->cc_op);
467 break;
468 case CC_OP_CONST0:
469 case CC_OP_CONST1:
470 case CC_OP_CONST2:
471 case CC_OP_CONST3:
472 case CC_OP_STATIC:
473 case CC_OP_DYNAMIC:
474 break;
475 }
476
477 switch (s->cc_op) {
478 case CC_OP_CONST0:
479 case CC_OP_CONST1:
480 case CC_OP_CONST2:
481 case CC_OP_CONST3:
482 /* s->cc_op is the cc value */
483 tcg_gen_movi_i32(cc_op, s->cc_op - CC_OP_CONST0);
484 break;
485 case CC_OP_STATIC:
486 /* env->cc_op already is the cc value */
487 break;
488 case CC_OP_NZ:
489 case CC_OP_ABS_64:
490 case CC_OP_NABS_64:
491 case CC_OP_ABS_32:
492 case CC_OP_NABS_32:
493 case CC_OP_LTGT0_32:
494 case CC_OP_LTGT0_64:
495 case CC_OP_COMP_32:
496 case CC_OP_COMP_64:
497 case CC_OP_NZ_F32:
498 case CC_OP_NZ_F64:
499 case CC_OP_FLOGR:
500 /* 1 argument */
501 gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, dummy, cc_dst, dummy);
502 break;
503 case CC_OP_ICM:
504 case CC_OP_LTGT_32:
505 case CC_OP_LTGT_64:
506 case CC_OP_LTUGTU_32:
507 case CC_OP_LTUGTU_64:
508 case CC_OP_TM_32:
509 case CC_OP_TM_64:
510 case CC_OP_SLA_32:
511 case CC_OP_SLA_64:
512 case CC_OP_NZ_F128:
513 /* 2 arguments */
514 gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, cc_src, cc_dst, dummy);
515 break;
516 case CC_OP_ADD_64:
517 case CC_OP_ADDU_64:
518 case CC_OP_ADDC_64:
519 case CC_OP_SUB_64:
520 case CC_OP_SUBU_64:
521 case CC_OP_SUBB_64:
522 case CC_OP_ADD_32:
523 case CC_OP_ADDU_32:
524 case CC_OP_ADDC_32:
525 case CC_OP_SUB_32:
526 case CC_OP_SUBU_32:
527 case CC_OP_SUBB_32:
528 /* 3 arguments */
529 gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, cc_src, cc_dst, cc_vr);
530 break;
531 case CC_OP_DYNAMIC:
532 /* unknown operation - assume 3 arguments and cc_op in env */
533 gen_helper_calc_cc(cc_op, cpu_env, cc_op, cc_src, cc_dst, cc_vr);
534 break;
535 default:
536 tcg_abort();
537 }
538
539 if (!TCGV_IS_UNUSED_I32(local_cc_op)) {
540 tcg_temp_free_i32(local_cc_op);
541 }
542 if (!TCGV_IS_UNUSED_I64(dummy)) {
543 tcg_temp_free_i64(dummy);
544 }
545
546 /* We now have cc in cc_op as constant */
547 set_cc_static(s);
548 }
549
550 static int use_goto_tb(DisasContext *s, uint64_t dest)
551 {
552 /* NOTE: we handle the case where the TB spans two pages here */
553 return (((dest & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK)
554 || (dest & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))
555 && !s->singlestep_enabled
556 && !(s->tb->cflags & CF_LAST_IO));
557 }
558
559 static void account_noninline_branch(DisasContext *s, int cc_op)
560 {
561 #ifdef DEBUG_INLINE_BRANCHES
562 inline_branch_miss[cc_op]++;
563 #endif
564 }
565
566 static void account_inline_branch(DisasContext *s, int cc_op)
567 {
568 #ifdef DEBUG_INLINE_BRANCHES
569 inline_branch_hit[cc_op]++;
570 #endif
571 }
572
573 /* Table of mask values to comparison codes, given a comparison as input.
574 For such, CC=3 should not be possible. */
575 static const TCGCond ltgt_cond[16] = {
576 TCG_COND_NEVER, TCG_COND_NEVER, /* | | | x */
577 TCG_COND_GT, TCG_COND_GT, /* | | GT | x */
578 TCG_COND_LT, TCG_COND_LT, /* | LT | | x */
579 TCG_COND_NE, TCG_COND_NE, /* | LT | GT | x */
580 TCG_COND_EQ, TCG_COND_EQ, /* EQ | | | x */
581 TCG_COND_GE, TCG_COND_GE, /* EQ | | GT | x */
582 TCG_COND_LE, TCG_COND_LE, /* EQ | LT | | x */
583 TCG_COND_ALWAYS, TCG_COND_ALWAYS, /* EQ | LT | GT | x */
584 };
585
586 /* Table of mask values to comparison codes, given a logic op as input.
587 For such, only CC=0 and CC=1 should be possible. */
588 static const TCGCond nz_cond[16] = {
589 TCG_COND_NEVER, TCG_COND_NEVER, /* | | x | x */
590 TCG_COND_NEVER, TCG_COND_NEVER,
591 TCG_COND_NE, TCG_COND_NE, /* | NE | x | x */
592 TCG_COND_NE, TCG_COND_NE,
593 TCG_COND_EQ, TCG_COND_EQ, /* EQ | | x | x */
594 TCG_COND_EQ, TCG_COND_EQ,
595 TCG_COND_ALWAYS, TCG_COND_ALWAYS, /* EQ | NE | x | x */
596 TCG_COND_ALWAYS, TCG_COND_ALWAYS,
597 };
598
599 /* Interpret MASK in terms of S->CC_OP, and fill in C with all the
600 details required to generate a TCG comparison. */
601 static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
602 {
603 TCGCond cond;
604 enum cc_op old_cc_op = s->cc_op;
605
606 if (mask == 15 || mask == 0) {
607 c->cond = (mask ? TCG_COND_ALWAYS : TCG_COND_NEVER);
608 c->u.s32.a = cc_op;
609 c->u.s32.b = cc_op;
610 c->g1 = c->g2 = true;
611 c->is_64 = false;
612 return;
613 }
614
615 /* Find the TCG condition for the mask + cc op. */
616 switch (old_cc_op) {
617 case CC_OP_LTGT0_32:
618 case CC_OP_LTGT0_64:
619 case CC_OP_LTGT_32:
620 case CC_OP_LTGT_64:
621 cond = ltgt_cond[mask];
622 if (cond == TCG_COND_NEVER) {
623 goto do_dynamic;
624 }
625 account_inline_branch(s, old_cc_op);
626 break;
627
628 case CC_OP_LTUGTU_32:
629 case CC_OP_LTUGTU_64:
630 cond = tcg_unsigned_cond(ltgt_cond[mask]);
631 if (cond == TCG_COND_NEVER) {
632 goto do_dynamic;
633 }
634 account_inline_branch(s, old_cc_op);
635 break;
636
637 case CC_OP_NZ:
638 cond = nz_cond[mask];
639 if (cond == TCG_COND_NEVER) {
640 goto do_dynamic;
641 }
642 account_inline_branch(s, old_cc_op);
643 break;
644
645 case CC_OP_TM_32:
646 case CC_OP_TM_64:
647 switch (mask) {
648 case 8:
649 cond = TCG_COND_EQ;
650 break;
651 case 4 | 2 | 1:
652 cond = TCG_COND_NE;
653 break;
654 default:
655 goto do_dynamic;
656 }
657 account_inline_branch(s, old_cc_op);
658 break;
659
660 case CC_OP_ICM:
661 switch (mask) {
662 case 8:
663 cond = TCG_COND_EQ;
664 break;
665 case 4 | 2 | 1:
666 case 4 | 2:
667 cond = TCG_COND_NE;
668 break;
669 default:
670 goto do_dynamic;
671 }
672 account_inline_branch(s, old_cc_op);
673 break;
674
675 case CC_OP_FLOGR:
676 switch (mask & 0xa) {
677 case 8: /* src == 0 -> no one bit found */
678 cond = TCG_COND_EQ;
679 break;
680 case 2: /* src != 0 -> one bit found */
681 cond = TCG_COND_NE;
682 break;
683 default:
684 goto do_dynamic;
685 }
686 account_inline_branch(s, old_cc_op);
687 break;
688
689 case CC_OP_ADDU_32:
690 case CC_OP_ADDU_64:
691 switch (mask) {
692 case 8 | 2: /* vr == 0 */
693 cond = TCG_COND_EQ;
694 break;
695 case 4 | 1: /* vr != 0 */
696 cond = TCG_COND_NE;
697 break;
698 case 8 | 4: /* no carry -> vr >= src */
699 cond = TCG_COND_GEU;
700 break;
701 case 2 | 1: /* carry -> vr < src */
702 cond = TCG_COND_LTU;
703 break;
704 default:
705 goto do_dynamic;
706 }
707 account_inline_branch(s, old_cc_op);
708 break;
709
710 case CC_OP_SUBU_32:
711 case CC_OP_SUBU_64:
712 /* Note that CC=0 is impossible; treat it as dont-care. */
713 switch (mask & 7) {
714 case 2: /* zero -> op1 == op2 */
715 cond = TCG_COND_EQ;
716 break;
717 case 4 | 1: /* !zero -> op1 != op2 */
718 cond = TCG_COND_NE;
719 break;
720 case 4: /* borrow (!carry) -> op1 < op2 */
721 cond = TCG_COND_LTU;
722 break;
723 case 2 | 1: /* !borrow (carry) -> op1 >= op2 */
724 cond = TCG_COND_GEU;
725 break;
726 default:
727 goto do_dynamic;
728 }
729 account_inline_branch(s, old_cc_op);
730 break;
731
732 default:
733 do_dynamic:
734 /* Calculate cc value. */
735 gen_op_calc_cc(s);
736 /* FALLTHRU */
737
738 case CC_OP_STATIC:
739 /* Jump based on CC. We'll load up the real cond below;
740 the assignment here merely avoids a compiler warning. */
741 account_noninline_branch(s, old_cc_op);
742 old_cc_op = CC_OP_STATIC;
743 cond = TCG_COND_NEVER;
744 break;
745 }
746
747 /* Load up the arguments of the comparison. */
748 c->is_64 = true;
749 c->g1 = c->g2 = false;
750 switch (old_cc_op) {
751 case CC_OP_LTGT0_32:
752 c->is_64 = false;
753 c->u.s32.a = tcg_temp_new_i32();
754 tcg_gen_trunc_i64_i32(c->u.s32.a, cc_dst);
755 c->u.s32.b = tcg_const_i32(0);
756 break;
757 case CC_OP_LTGT_32:
758 case CC_OP_LTUGTU_32:
759 case CC_OP_SUBU_32:
760 c->is_64 = false;
761 c->u.s32.a = tcg_temp_new_i32();
762 tcg_gen_trunc_i64_i32(c->u.s32.a, cc_src);
763 c->u.s32.b = tcg_temp_new_i32();
764 tcg_gen_trunc_i64_i32(c->u.s32.b, cc_dst);
765 break;
766
767 case CC_OP_LTGT0_64:
768 case CC_OP_NZ:
769 case CC_OP_FLOGR:
770 c->u.s64.a = cc_dst;
771 c->u.s64.b = tcg_const_i64(0);
772 c->g1 = true;
773 break;
774 case CC_OP_LTGT_64:
775 case CC_OP_LTUGTU_64:
776 case CC_OP_SUBU_64:
777 c->u.s64.a = cc_src;
778 c->u.s64.b = cc_dst;
779 c->g1 = c->g2 = true;
780 break;
781
782 case CC_OP_TM_32:
783 case CC_OP_TM_64:
784 case CC_OP_ICM:
785 c->u.s64.a = tcg_temp_new_i64();
786 c->u.s64.b = tcg_const_i64(0);
787 tcg_gen_and_i64(c->u.s64.a, cc_src, cc_dst);
788 break;
789
790 case CC_OP_ADDU_32:
791 c->is_64 = false;
792 c->u.s32.a = tcg_temp_new_i32();
793 c->u.s32.b = tcg_temp_new_i32();
794 tcg_gen_trunc_i64_i32(c->u.s32.a, cc_vr);
795 if (cond == TCG_COND_EQ || cond == TCG_COND_NE) {
796 tcg_gen_movi_i32(c->u.s32.b, 0);
797 } else {
798 tcg_gen_trunc_i64_i32(c->u.s32.b, cc_src);
799 }
800 break;
801
802 case CC_OP_ADDU_64:
803 c->u.s64.a = cc_vr;
804 c->g1 = true;
805 if (cond == TCG_COND_EQ || cond == TCG_COND_NE) {
806 c->u.s64.b = tcg_const_i64(0);
807 } else {
808 c->u.s64.b = cc_src;
809 c->g2 = true;
810 }
811 break;
812
813 case CC_OP_STATIC:
814 c->is_64 = false;
815 c->u.s32.a = cc_op;
816 c->g1 = true;
817 switch (mask) {
818 case 0x8 | 0x4 | 0x2: /* cc != 3 */
819 cond = TCG_COND_NE;
820 c->u.s32.b = tcg_const_i32(3);
821 break;
822 case 0x8 | 0x4 | 0x1: /* cc != 2 */
823 cond = TCG_COND_NE;
824 c->u.s32.b = tcg_const_i32(2);
825 break;
826 case 0x8 | 0x2 | 0x1: /* cc != 1 */
827 cond = TCG_COND_NE;
828 c->u.s32.b = tcg_const_i32(1);
829 break;
830 case 0x8 | 0x2: /* cc == 0 || cc == 2 => (cc & 1) == 0 */
831 cond = TCG_COND_EQ;
832 c->g1 = false;
833 c->u.s32.a = tcg_temp_new_i32();
834 c->u.s32.b = tcg_const_i32(0);
835 tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
836 break;
837 case 0x8 | 0x4: /* cc < 2 */
838 cond = TCG_COND_LTU;
839 c->u.s32.b = tcg_const_i32(2);
840 break;
841 case 0x8: /* cc == 0 */
842 cond = TCG_COND_EQ;
843 c->u.s32.b = tcg_const_i32(0);
844 break;
845 case 0x4 | 0x2 | 0x1: /* cc != 0 */
846 cond = TCG_COND_NE;
847 c->u.s32.b = tcg_const_i32(0);
848 break;
849 case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */
850 cond = TCG_COND_NE;
851 c->g1 = false;
852 c->u.s32.a = tcg_temp_new_i32();
853 c->u.s32.b = tcg_const_i32(0);
854 tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
855 break;
856 case 0x4: /* cc == 1 */
857 cond = TCG_COND_EQ;
858 c->u.s32.b = tcg_const_i32(1);
859 break;
860 case 0x2 | 0x1: /* cc > 1 */
861 cond = TCG_COND_GTU;
862 c->u.s32.b = tcg_const_i32(1);
863 break;
864 case 0x2: /* cc == 2 */
865 cond = TCG_COND_EQ;
866 c->u.s32.b = tcg_const_i32(2);
867 break;
868 case 0x1: /* cc == 3 */
869 cond = TCG_COND_EQ;
870 c->u.s32.b = tcg_const_i32(3);
871 break;
872 default:
873 /* CC is masked by something else: (8 >> cc) & mask. */
874 cond = TCG_COND_NE;
875 c->g1 = false;
876 c->u.s32.a = tcg_const_i32(8);
877 c->u.s32.b = tcg_const_i32(0);
878 tcg_gen_shr_i32(c->u.s32.a, c->u.s32.a, cc_op);
879 tcg_gen_andi_i32(c->u.s32.a, c->u.s32.a, mask);
880 break;
881 }
882 break;
883
884 default:
885 abort();
886 }
887 c->cond = cond;
888 }
889
890 static void free_compare(DisasCompare *c)
891 {
892 if (!c->g1) {
893 if (c->is_64) {
894 tcg_temp_free_i64(c->u.s64.a);
895 } else {
896 tcg_temp_free_i32(c->u.s32.a);
897 }
898 }
899 if (!c->g2) {
900 if (c->is_64) {
901 tcg_temp_free_i64(c->u.s64.b);
902 } else {
903 tcg_temp_free_i32(c->u.s32.b);
904 }
905 }
906 }
907
908 /* ====================================================================== */
909 /* Define the insn format enumeration. */
910 #define F0(N) FMT_##N,
911 #define F1(N, X1) F0(N)
912 #define F2(N, X1, X2) F0(N)
913 #define F3(N, X1, X2, X3) F0(N)
914 #define F4(N, X1, X2, X3, X4) F0(N)
915 #define F5(N, X1, X2, X3, X4, X5) F0(N)
916
917 typedef enum {
918 #include "insn-format.def"
919 } DisasFormat;
920
921 #undef F0
922 #undef F1
923 #undef F2
924 #undef F3
925 #undef F4
926 #undef F5
927
928 /* Define a structure to hold the decoded fields. We'll store each inside
929 an array indexed by an enum. In order to conserve memory, we'll arrange
930 for fields that do not exist at the same time to overlap, thus the "C"
931 for compact. For checking purposes there is an "O" for original index
932 as well that will be applied to availability bitmaps. */
933
934 enum DisasFieldIndexO {
935 FLD_O_r1,
936 FLD_O_r2,
937 FLD_O_r3,
938 FLD_O_m1,
939 FLD_O_m3,
940 FLD_O_m4,
941 FLD_O_b1,
942 FLD_O_b2,
943 FLD_O_b4,
944 FLD_O_d1,
945 FLD_O_d2,
946 FLD_O_d4,
947 FLD_O_x2,
948 FLD_O_l1,
949 FLD_O_l2,
950 FLD_O_i1,
951 FLD_O_i2,
952 FLD_O_i3,
953 FLD_O_i4,
954 FLD_O_i5
955 };
956
957 enum DisasFieldIndexC {
958 FLD_C_r1 = 0,
959 FLD_C_m1 = 0,
960 FLD_C_b1 = 0,
961 FLD_C_i1 = 0,
962
963 FLD_C_r2 = 1,
964 FLD_C_b2 = 1,
965 FLD_C_i2 = 1,
966
967 FLD_C_r3 = 2,
968 FLD_C_m3 = 2,
969 FLD_C_i3 = 2,
970
971 FLD_C_m4 = 3,
972 FLD_C_b4 = 3,
973 FLD_C_i4 = 3,
974 FLD_C_l1 = 3,
975
976 FLD_C_i5 = 4,
977 FLD_C_d1 = 4,
978
979 FLD_C_d2 = 5,
980
981 FLD_C_d4 = 6,
982 FLD_C_x2 = 6,
983 FLD_C_l2 = 6,
984
985 NUM_C_FIELD = 7
986 };
987
988 struct DisasFields {
989 unsigned op:8;
990 unsigned op2:8;
991 unsigned presentC:16;
992 unsigned int presentO;
993 int c[NUM_C_FIELD];
994 };
995
996 /* This is the way fields are to be accessed out of DisasFields. */
997 #define have_field(S, F) have_field1((S), FLD_O_##F)
998 #define get_field(S, F) get_field1((S), FLD_O_##F, FLD_C_##F)
999
1000 static bool have_field1(const DisasFields *f, enum DisasFieldIndexO c)
1001 {
1002 return (f->presentO >> c) & 1;
1003 }
1004
1005 static int get_field1(const DisasFields *f, enum DisasFieldIndexO o,
1006 enum DisasFieldIndexC c)
1007 {
1008 assert(have_field1(f, o));
1009 return f->c[c];
1010 }
1011
1012 /* Describe the layout of each field in each format. */
1013 typedef struct DisasField {
1014 unsigned int beg:8;
1015 unsigned int size:8;
1016 unsigned int type:2;
1017 unsigned int indexC:6;
1018 enum DisasFieldIndexO indexO:8;
1019 } DisasField;
1020
1021 typedef struct DisasFormatInfo {
1022 DisasField op[NUM_C_FIELD];
1023 } DisasFormatInfo;
1024
1025 #define R(N, B) { B, 4, 0, FLD_C_r##N, FLD_O_r##N }
1026 #define M(N, B) { B, 4, 0, FLD_C_m##N, FLD_O_m##N }
1027 #define BD(N, BB, BD) { BB, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
1028 { BD, 12, 0, FLD_C_d##N, FLD_O_d##N }
1029 #define BXD(N) { 16, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
1030 { 12, 4, 0, FLD_C_x##N, FLD_O_x##N }, \
1031 { 20, 12, 0, FLD_C_d##N, FLD_O_d##N }
1032 #define BDL(N) { 16, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
1033 { 20, 20, 2, FLD_C_d##N, FLD_O_d##N }
1034 #define BXDL(N) { 16, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
1035 { 12, 4, 0, FLD_C_x##N, FLD_O_x##N }, \
1036 { 20, 20, 2, FLD_C_d##N, FLD_O_d##N }
1037 #define I(N, B, S) { B, S, 1, FLD_C_i##N, FLD_O_i##N }
1038 #define L(N, B, S) { B, S, 0, FLD_C_l##N, FLD_O_l##N }
1039
1040 #define F0(N) { { } },
1041 #define F1(N, X1) { { X1 } },
1042 #define F2(N, X1, X2) { { X1, X2 } },
1043 #define F3(N, X1, X2, X3) { { X1, X2, X3 } },
1044 #define F4(N, X1, X2, X3, X4) { { X1, X2, X3, X4 } },
1045 #define F5(N, X1, X2, X3, X4, X5) { { X1, X2, X3, X4, X5 } },
1046
1047 static const DisasFormatInfo format_info[] = {
1048 #include "insn-format.def"
1049 };
1050
1051 #undef F0
1052 #undef F1
1053 #undef F2
1054 #undef F3
1055 #undef F4
1056 #undef F5
1057 #undef R
1058 #undef M
1059 #undef BD
1060 #undef BXD
1061 #undef BDL
1062 #undef BXDL
1063 #undef I
1064 #undef L
1065
1066 /* Generally, we'll extract operands into this structures, operate upon
1067 them, and store them back. See the "in1", "in2", "prep", "wout" sets
1068 of routines below for more details. */
1069 typedef struct {
1070 bool g_out, g_out2, g_in1, g_in2;
1071 TCGv_i64 out, out2, in1, in2;
1072 TCGv_i64 addr1;
1073 } DisasOps;
1074
1075 /* Instructions can place constraints on their operands, raising specification
1076 exceptions if they are violated. To make this easy to automate, each "in1",
1077 "in2", "prep", "wout" helper will have a SPEC_<name> define that equals one
1078 of the following, or 0. To make this easy to document, we'll put the
1079 SPEC_<name> defines next to <name>. */
1080
1081 #define SPEC_r1_even 1
1082 #define SPEC_r2_even 2
1083 #define SPEC_r3_even 4
1084 #define SPEC_r1_f128 8
1085 #define SPEC_r2_f128 16
1086
1087 /* Return values from translate_one, indicating the state of the TB. */
1088 typedef enum {
1089 /* Continue the TB. */
1090 NO_EXIT,
1091 /* We have emitted one or more goto_tb. No fixup required. */
1092 EXIT_GOTO_TB,
1093 /* We are not using a goto_tb (for whatever reason), but have updated
1094 the PC (for whatever reason), so there's no need to do it again on
1095 exiting the TB. */
1096 EXIT_PC_UPDATED,
1097 /* We are exiting the TB, but have neither emitted a goto_tb, nor
1098 updated the PC for the next instruction to be executed. */
1099 EXIT_PC_STALE,
1100 /* We are ending the TB with a noreturn function call, e.g. longjmp.
1101 No following code will be executed. */
1102 EXIT_NORETURN,
1103 } ExitStatus;
1104
1105 typedef enum DisasFacility {
1106 FAC_Z, /* zarch (default) */
1107 FAC_CASS, /* compare and swap and store */
1108 FAC_CASS2, /* compare and swap and store 2*/
1109 FAC_DFP, /* decimal floating point */
1110 FAC_DFPR, /* decimal floating point rounding */
1111 FAC_DO, /* distinct operands */
1112 FAC_EE, /* execute extensions */
1113 FAC_EI, /* extended immediate */
1114 FAC_FPE, /* floating point extension */
1115 FAC_FPSSH, /* floating point support sign handling */
1116 FAC_FPRGR, /* FPR-GR transfer */
1117 FAC_GIE, /* general instructions extension */
1118 FAC_HFP_MA, /* HFP multiply-and-add/subtract */
1119 FAC_HW, /* high-word */
1120 FAC_IEEEE_SIM, /* IEEE exception sumilation */
1121 FAC_LOC, /* load/store on condition */
1122 FAC_LD, /* long displacement */
1123 FAC_PC, /* population count */
1124 FAC_SCF, /* store clock fast */
1125 FAC_SFLE, /* store facility list extended */
1126 } DisasFacility;
1127
1128 struct DisasInsn {
1129 unsigned opc:16;
1130 DisasFormat fmt:8;
1131 DisasFacility fac:8;
1132 unsigned spec:8;
1133
1134 const char *name;
1135
1136 void (*help_in1)(DisasContext *, DisasFields *, DisasOps *);
1137 void (*help_in2)(DisasContext *, DisasFields *, DisasOps *);
1138 void (*help_prep)(DisasContext *, DisasFields *, DisasOps *);
1139 void (*help_wout)(DisasContext *, DisasFields *, DisasOps *);
1140 void (*help_cout)(DisasContext *, DisasOps *);
1141 ExitStatus (*help_op)(DisasContext *, DisasOps *);
1142
1143 uint64_t data;
1144 };
1145
1146 /* ====================================================================== */
1147 /* Miscellaneous helpers, used by several operations. */
1148
1149 static void help_l2_shift(DisasContext *s, DisasFields *f,
1150 DisasOps *o, int mask)
1151 {
1152 int b2 = get_field(f, b2);
1153 int d2 = get_field(f, d2);
1154
1155 if (b2 == 0) {
1156 o->in2 = tcg_const_i64(d2 & mask);
1157 } else {
1158 o->in2 = get_address(s, 0, b2, d2);
1159 tcg_gen_andi_i64(o->in2, o->in2, mask);
1160 }
1161 }
1162
1163 static ExitStatus help_goto_direct(DisasContext *s, uint64_t dest)
1164 {
1165 if (dest == s->next_pc) {
1166 return NO_EXIT;
1167 }
1168 if (use_goto_tb(s, dest)) {
1169 update_cc_op(s);
1170 tcg_gen_goto_tb(0);
1171 tcg_gen_movi_i64(psw_addr, dest);
1172 tcg_gen_exit_tb((tcg_target_long)s->tb);
1173 return EXIT_GOTO_TB;
1174 } else {
1175 tcg_gen_movi_i64(psw_addr, dest);
1176 return EXIT_PC_UPDATED;
1177 }
1178 }
1179
1180 static ExitStatus help_branch(DisasContext *s, DisasCompare *c,
1181 bool is_imm, int imm, TCGv_i64 cdest)
1182 {
1183 ExitStatus ret;
1184 uint64_t dest = s->pc + 2 * imm;
1185 int lab;
1186
1187 /* Take care of the special cases first. */
1188 if (c->cond == TCG_COND_NEVER) {
1189 ret = NO_EXIT;
1190 goto egress;
1191 }
1192 if (is_imm) {
1193 if (dest == s->next_pc) {
1194 /* Branch to next. */
1195 ret = NO_EXIT;
1196 goto egress;
1197 }
1198 if (c->cond == TCG_COND_ALWAYS) {
1199 ret = help_goto_direct(s, dest);
1200 goto egress;
1201 }
1202 } else {
1203 if (TCGV_IS_UNUSED_I64(cdest)) {
1204 /* E.g. bcr %r0 -> no branch. */
1205 ret = NO_EXIT;
1206 goto egress;
1207 }
1208 if (c->cond == TCG_COND_ALWAYS) {
1209 tcg_gen_mov_i64(psw_addr, cdest);
1210 ret = EXIT_PC_UPDATED;
1211 goto egress;
1212 }
1213 }
1214
1215 if (use_goto_tb(s, s->next_pc)) {
1216 if (is_imm && use_goto_tb(s, dest)) {
1217 /* Both exits can use goto_tb. */
1218 update_cc_op(s);
1219
1220 lab = gen_new_label();
1221 if (c->is_64) {
1222 tcg_gen_brcond_i64(c->cond, c->u.s64.a, c->u.s64.b, lab);
1223 } else {
1224 tcg_gen_brcond_i32(c->cond, c->u.s32.a, c->u.s32.b, lab);
1225 }
1226
1227 /* Branch not taken. */
1228 tcg_gen_goto_tb(0);
1229 tcg_gen_movi_i64(psw_addr, s->next_pc);
1230 tcg_gen_exit_tb((tcg_target_long)s->tb + 0);
1231
1232 /* Branch taken. */
1233 gen_set_label(lab);
1234 tcg_gen_goto_tb(1);
1235 tcg_gen_movi_i64(psw_addr, dest);
1236 tcg_gen_exit_tb((tcg_target_long)s->tb + 1);
1237
1238 ret = EXIT_GOTO_TB;
1239 } else {
1240 /* Fallthru can use goto_tb, but taken branch cannot. */
1241 /* Store taken branch destination before the brcond. This
1242 avoids having to allocate a new local temp to hold it.
1243 We'll overwrite this in the not taken case anyway. */
1244 if (!is_imm) {
1245 tcg_gen_mov_i64(psw_addr, cdest);
1246 }
1247
1248 lab = gen_new_label();
1249 if (c->is_64) {
1250 tcg_gen_brcond_i64(c->cond, c->u.s64.a, c->u.s64.b, lab);
1251 } else {
1252 tcg_gen_brcond_i32(c->cond, c->u.s32.a, c->u.s32.b, lab);
1253 }
1254
1255 /* Branch not taken. */
1256 update_cc_op(s);
1257 tcg_gen_goto_tb(0);
1258 tcg_gen_movi_i64(psw_addr, s->next_pc);
1259 tcg_gen_exit_tb((tcg_target_long)s->tb + 0);
1260
1261 gen_set_label(lab);
1262 if (is_imm) {
1263 tcg_gen_movi_i64(psw_addr, dest);
1264 }
1265 ret = EXIT_PC_UPDATED;
1266 }
1267 } else {
1268 /* Fallthru cannot use goto_tb. This by itself is vanishingly rare.
1269 Most commonly we're single-stepping or some other condition that
1270 disables all use of goto_tb. Just update the PC and exit. */
1271
1272 TCGv_i64 next = tcg_const_i64(s->next_pc);
1273 if (is_imm) {
1274 cdest = tcg_const_i64(dest);
1275 }
1276
1277 if (c->is_64) {
1278 tcg_gen_movcond_i64(c->cond, psw_addr, c->u.s64.a, c->u.s64.b,
1279 cdest, next);
1280 } else {
1281 TCGv_i32 t0 = tcg_temp_new_i32();
1282 TCGv_i64 t1 = tcg_temp_new_i64();
1283 TCGv_i64 z = tcg_const_i64(0);
1284 tcg_gen_setcond_i32(c->cond, t0, c->u.s32.a, c->u.s32.b);
1285 tcg_gen_extu_i32_i64(t1, t0);
1286 tcg_temp_free_i32(t0);
1287 tcg_gen_movcond_i64(TCG_COND_NE, psw_addr, t1, z, cdest, next);
1288 tcg_temp_free_i64(t1);
1289 tcg_temp_free_i64(z);
1290 }
1291
1292 if (is_imm) {
1293 tcg_temp_free_i64(cdest);
1294 }
1295 tcg_temp_free_i64(next);
1296
1297 ret = EXIT_PC_UPDATED;
1298 }
1299
1300 egress:
1301 free_compare(c);
1302 return ret;
1303 }
1304
1305 /* ====================================================================== */
1306 /* The operations. These perform the bulk of the work for any insn,
1307 usually after the operands have been loaded and output initialized. */
1308
1309 static ExitStatus op_abs(DisasContext *s, DisasOps *o)
1310 {
1311 gen_helper_abs_i64(o->out, o->in2);
1312 return NO_EXIT;
1313 }
1314
1315 static ExitStatus op_absf32(DisasContext *s, DisasOps *o)
1316 {
1317 tcg_gen_andi_i64(o->out, o->in2, 0x7fffffffull);
1318 return NO_EXIT;
1319 }
1320
1321 static ExitStatus op_absf64(DisasContext *s, DisasOps *o)
1322 {
1323 tcg_gen_andi_i64(o->out, o->in2, 0x7fffffffffffffffull);
1324 return NO_EXIT;
1325 }
1326
1327 static ExitStatus op_absf128(DisasContext *s, DisasOps *o)
1328 {
1329 tcg_gen_andi_i64(o->out, o->in1, 0x7fffffffffffffffull);
1330 tcg_gen_mov_i64(o->out2, o->in2);
1331 return NO_EXIT;
1332 }
1333
1334 static ExitStatus op_add(DisasContext *s, DisasOps *o)
1335 {
1336 tcg_gen_add_i64(o->out, o->in1, o->in2);
1337 return NO_EXIT;
1338 }
1339
1340 static ExitStatus op_addc(DisasContext *s, DisasOps *o)
1341 {
1342 DisasCompare cmp;
1343 TCGv_i64 carry;
1344
1345 tcg_gen_add_i64(o->out, o->in1, o->in2);
1346
1347 /* The carry flag is the msb of CC, therefore the branch mask that would
1348 create that comparison is 3. Feeding the generated comparison to
1349 setcond produces the carry flag that we desire. */
1350 disas_jcc(s, &cmp, 3);
1351 carry = tcg_temp_new_i64();
1352 if (cmp.is_64) {
1353 tcg_gen_setcond_i64(cmp.cond, carry, cmp.u.s64.a, cmp.u.s64.b);
1354 } else {
1355 TCGv_i32 t = tcg_temp_new_i32();
1356 tcg_gen_setcond_i32(cmp.cond, t, cmp.u.s32.a, cmp.u.s32.b);
1357 tcg_gen_extu_i32_i64(carry, t);
1358 tcg_temp_free_i32(t);
1359 }
1360 free_compare(&cmp);
1361
1362 tcg_gen_add_i64(o->out, o->out, carry);
1363 tcg_temp_free_i64(carry);
1364 return NO_EXIT;
1365 }
1366
1367 static ExitStatus op_aeb(DisasContext *s, DisasOps *o)
1368 {
1369 gen_helper_aeb(o->out, cpu_env, o->in1, o->in2);
1370 return NO_EXIT;
1371 }
1372
1373 static ExitStatus op_adb(DisasContext *s, DisasOps *o)
1374 {
1375 gen_helper_adb(o->out, cpu_env, o->in1, o->in2);
1376 return NO_EXIT;
1377 }
1378
1379 static ExitStatus op_axb(DisasContext *s, DisasOps *o)
1380 {
1381 gen_helper_axb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2);
1382 return_low128(o->out2);
1383 return NO_EXIT;
1384 }
1385
1386 static ExitStatus op_and(DisasContext *s, DisasOps *o)
1387 {
1388 tcg_gen_and_i64(o->out, o->in1, o->in2);
1389 return NO_EXIT;
1390 }
1391
1392 static ExitStatus op_andi(DisasContext *s, DisasOps *o)
1393 {
1394 int shift = s->insn->data & 0xff;
1395 int size = s->insn->data >> 8;
1396 uint64_t mask = ((1ull << size) - 1) << shift;
1397
1398 assert(!o->g_in2);
1399 tcg_gen_shli_i64(o->in2, o->in2, shift);
1400 tcg_gen_ori_i64(o->in2, o->in2, ~mask);
1401 tcg_gen_and_i64(o->out, o->in1, o->in2);
1402
1403 /* Produce the CC from only the bits manipulated. */
1404 tcg_gen_andi_i64(cc_dst, o->out, mask);
1405 set_cc_nz_u64(s, cc_dst);
1406 return NO_EXIT;
1407 }
1408
1409 static ExitStatus op_bas(DisasContext *s, DisasOps *o)
1410 {
1411 tcg_gen_movi_i64(o->out, pc_to_link_info(s, s->next_pc));
1412 if (!TCGV_IS_UNUSED_I64(o->in2)) {
1413 tcg_gen_mov_i64(psw_addr, o->in2);
1414 return EXIT_PC_UPDATED;
1415 } else {
1416 return NO_EXIT;
1417 }
1418 }
1419
1420 static ExitStatus op_basi(DisasContext *s, DisasOps *o)
1421 {
1422 tcg_gen_movi_i64(o->out, pc_to_link_info(s, s->next_pc));
1423 return help_goto_direct(s, s->pc + 2 * get_field(s->fields, i2));
1424 }
1425
1426 static ExitStatus op_bc(DisasContext *s, DisasOps *o)
1427 {
1428 int m1 = get_field(s->fields, m1);
1429 bool is_imm = have_field(s->fields, i2);
1430 int imm = is_imm ? get_field(s->fields, i2) : 0;
1431 DisasCompare c;
1432
1433 disas_jcc(s, &c, m1);
1434 return help_branch(s, &c, is_imm, imm, o->in2);
1435 }
1436
1437 static ExitStatus op_bct32(DisasContext *s, DisasOps *o)
1438 {
1439 int r1 = get_field(s->fields, r1);
1440 bool is_imm = have_field(s->fields, i2);
1441 int imm = is_imm ? get_field(s->fields, i2) : 0;
1442 DisasCompare c;
1443 TCGv_i64 t;
1444
1445 c.cond = TCG_COND_NE;
1446 c.is_64 = false;
1447 c.g1 = false;
1448 c.g2 = false;
1449
1450 t = tcg_temp_new_i64();
1451 tcg_gen_subi_i64(t, regs[r1], 1);
1452 store_reg32_i64(r1, t);
1453 c.u.s32.a = tcg_temp_new_i32();
1454 c.u.s32.b = tcg_const_i32(0);
1455 tcg_gen_trunc_i64_i32(c.u.s32.a, t);
1456 tcg_temp_free_i64(t);
1457
1458 return help_branch(s, &c, is_imm, imm, o->in2);
1459 }
1460
1461 static ExitStatus op_bct64(DisasContext *s, DisasOps *o)
1462 {
1463 int r1 = get_field(s->fields, r1);
1464 bool is_imm = have_field(s->fields, i2);
1465 int imm = is_imm ? get_field(s->fields, i2) : 0;
1466 DisasCompare c;
1467
1468 c.cond = TCG_COND_NE;
1469 c.is_64 = true;
1470 c.g1 = true;
1471 c.g2 = false;
1472
1473 tcg_gen_subi_i64(regs[r1], regs[r1], 1);
1474 c.u.s64.a = regs[r1];
1475 c.u.s64.b = tcg_const_i64(0);
1476
1477 return help_branch(s, &c, is_imm, imm, o->in2);
1478 }
1479
1480 static ExitStatus op_bx32(DisasContext *s, DisasOps *o)
1481 {
1482 int r1 = get_field(s->fields, r1);
1483 int r3 = get_field(s->fields, r3);
1484 bool is_imm = have_field(s->fields, i2);
1485 int imm = is_imm ? get_field(s->fields, i2) : 0;
1486 DisasCompare c;
1487 TCGv_i64 t;
1488
1489 c.cond = (s->insn->data ? TCG_COND_LE : TCG_COND_GT);
1490 c.is_64 = false;
1491 c.g1 = false;
1492 c.g2 = false;
1493
1494 t = tcg_temp_new_i64();
1495 tcg_gen_add_i64(t, regs[r1], regs[r3]);
1496 c.u.s32.a = tcg_temp_new_i32();
1497 c.u.s32.b = tcg_temp_new_i32();
1498 tcg_gen_trunc_i64_i32(c.u.s32.a, t);
1499 tcg_gen_trunc_i64_i32(c.u.s32.b, regs[r3 | 1]);
1500 store_reg32_i64(r1, t);
1501 tcg_temp_free_i64(t);
1502
1503 return help_branch(s, &c, is_imm, imm, o->in2);
1504 }
1505
1506 static ExitStatus op_bx64(DisasContext *s, DisasOps *o)
1507 {
1508 int r1 = get_field(s->fields, r1);
1509 int r3 = get_field(s->fields, r3);
1510 bool is_imm = have_field(s->fields, i2);
1511 int imm = is_imm ? get_field(s->fields, i2) : 0;
1512 DisasCompare c;
1513
1514 c.cond = (s->insn->data ? TCG_COND_LE : TCG_COND_GT);
1515 c.is_64 = true;
1516
1517 if (r1 == (r3 | 1)) {
1518 c.u.s64.b = load_reg(r3 | 1);
1519 c.g2 = false;
1520 } else {
1521 c.u.s64.b = regs[r3 | 1];
1522 c.g2 = true;
1523 }
1524
1525 tcg_gen_add_i64(regs[r1], regs[r1], regs[r3]);
1526 c.u.s64.a = regs[r1];
1527 c.g1 = true;
1528
1529 return help_branch(s, &c, is_imm, imm, o->in2);
1530 }
1531
1532 static ExitStatus op_cj(DisasContext *s, DisasOps *o)
1533 {
1534 int imm, m3 = get_field(s->fields, m3);
1535 bool is_imm;
1536 DisasCompare c;
1537
1538 c.cond = ltgt_cond[m3];
1539 if (s->insn->data) {
1540 c.cond = tcg_unsigned_cond(c.cond);
1541 }
1542 c.is_64 = c.g1 = c.g2 = true;
1543 c.u.s64.a = o->in1;
1544 c.u.s64.b = o->in2;
1545
1546 is_imm = have_field(s->fields, i4);
1547 if (is_imm) {
1548 imm = get_field(s->fields, i4);
1549 } else {
1550 imm = 0;
1551 o->out = get_address(s, 0, get_field(s->fields, b4),
1552 get_field(s->fields, d4));
1553 }
1554
1555 return help_branch(s, &c, is_imm, imm, o->out);
1556 }
1557
1558 static ExitStatus op_ceb(DisasContext *s, DisasOps *o)
1559 {
1560 gen_helper_ceb(cc_op, cpu_env, o->in1, o->in2);
1561 set_cc_static(s);
1562 return NO_EXIT;
1563 }
1564
1565 static ExitStatus op_cdb(DisasContext *s, DisasOps *o)
1566 {
1567 gen_helper_cdb(cc_op, cpu_env, o->in1, o->in2);
1568 set_cc_static(s);
1569 return NO_EXIT;
1570 }
1571
1572 static ExitStatus op_cxb(DisasContext *s, DisasOps *o)
1573 {
1574 gen_helper_cxb(cc_op, cpu_env, o->out, o->out2, o->in1, o->in2);
1575 set_cc_static(s);
1576 return NO_EXIT;
1577 }
1578
1579 static ExitStatus op_cfeb(DisasContext *s, DisasOps *o)
1580 {
1581 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1582 gen_helper_cfeb(o->out, cpu_env, o->in2, m3);
1583 tcg_temp_free_i32(m3);
1584 gen_set_cc_nz_f32(s, o->in2);
1585 return NO_EXIT;
1586 }
1587
1588 static ExitStatus op_cfdb(DisasContext *s, DisasOps *o)
1589 {
1590 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1591 gen_helper_cfdb(o->out, cpu_env, o->in2, m3);
1592 tcg_temp_free_i32(m3);
1593 gen_set_cc_nz_f64(s, o->in2);
1594 return NO_EXIT;
1595 }
1596
1597 static ExitStatus op_cfxb(DisasContext *s, DisasOps *o)
1598 {
1599 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1600 gen_helper_cfxb(o->out, cpu_env, o->in1, o->in2, m3);
1601 tcg_temp_free_i32(m3);
1602 gen_set_cc_nz_f128(s, o->in1, o->in2);
1603 return NO_EXIT;
1604 }
1605
1606 static ExitStatus op_cgeb(DisasContext *s, DisasOps *o)
1607 {
1608 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1609 gen_helper_cgeb(o->out, cpu_env, o->in2, m3);
1610 tcg_temp_free_i32(m3);
1611 gen_set_cc_nz_f32(s, o->in2);
1612 return NO_EXIT;
1613 }
1614
1615 static ExitStatus op_cgdb(DisasContext *s, DisasOps *o)
1616 {
1617 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1618 gen_helper_cgdb(o->out, cpu_env, o->in2, m3);
1619 tcg_temp_free_i32(m3);
1620 gen_set_cc_nz_f64(s, o->in2);
1621 return NO_EXIT;
1622 }
1623
1624 static ExitStatus op_cgxb(DisasContext *s, DisasOps *o)
1625 {
1626 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1627 gen_helper_cgxb(o->out, cpu_env, o->in1, o->in2, m3);
1628 tcg_temp_free_i32(m3);
1629 gen_set_cc_nz_f128(s, o->in1, o->in2);
1630 return NO_EXIT;
1631 }
1632
1633 static ExitStatus op_clfeb(DisasContext *s, DisasOps *o)
1634 {
1635 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1636 gen_helper_clfeb(o->out, cpu_env, o->in2, m3);
1637 tcg_temp_free_i32(m3);
1638 gen_set_cc_nz_f32(s, o->in2);
1639 return NO_EXIT;
1640 }
1641
1642 static ExitStatus op_clfdb(DisasContext *s, DisasOps *o)
1643 {
1644 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1645 gen_helper_clfdb(o->out, cpu_env, o->in2, m3);
1646 tcg_temp_free_i32(m3);
1647 gen_set_cc_nz_f64(s, o->in2);
1648 return NO_EXIT;
1649 }
1650
1651 static ExitStatus op_clfxb(DisasContext *s, DisasOps *o)
1652 {
1653 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1654 gen_helper_clfxb(o->out, cpu_env, o->in1, o->in2, m3);
1655 tcg_temp_free_i32(m3);
1656 gen_set_cc_nz_f128(s, o->in1, o->in2);
1657 return NO_EXIT;
1658 }
1659
1660 static ExitStatus op_clgeb(DisasContext *s, DisasOps *o)
1661 {
1662 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1663 gen_helper_clgeb(o->out, cpu_env, o->in2, m3);
1664 tcg_temp_free_i32(m3);
1665 gen_set_cc_nz_f32(s, o->in2);
1666 return NO_EXIT;
1667 }
1668
1669 static ExitStatus op_clgdb(DisasContext *s, DisasOps *o)
1670 {
1671 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1672 gen_helper_clgdb(o->out, cpu_env, o->in2, m3);
1673 tcg_temp_free_i32(m3);
1674 gen_set_cc_nz_f64(s, o->in2);
1675 return NO_EXIT;
1676 }
1677
1678 static ExitStatus op_clgxb(DisasContext *s, DisasOps *o)
1679 {
1680 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1681 gen_helper_clgxb(o->out, cpu_env, o->in1, o->in2, m3);
1682 tcg_temp_free_i32(m3);
1683 gen_set_cc_nz_f128(s, o->in1, o->in2);
1684 return NO_EXIT;
1685 }
1686
1687 static ExitStatus op_cegb(DisasContext *s, DisasOps *o)
1688 {
1689 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1690 gen_helper_cegb(o->out, cpu_env, o->in2, m3);
1691 tcg_temp_free_i32(m3);
1692 return NO_EXIT;
1693 }
1694
1695 static ExitStatus op_cdgb(DisasContext *s, DisasOps *o)
1696 {
1697 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1698 gen_helper_cdgb(o->out, cpu_env, o->in2, m3);
1699 tcg_temp_free_i32(m3);
1700 return NO_EXIT;
1701 }
1702
1703 static ExitStatus op_cxgb(DisasContext *s, DisasOps *o)
1704 {
1705 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1706 gen_helper_cxgb(o->out, cpu_env, o->in2, m3);
1707 tcg_temp_free_i32(m3);
1708 return_low128(o->out2);
1709 return NO_EXIT;
1710 }
1711
1712 static ExitStatus op_celgb(DisasContext *s, DisasOps *o)
1713 {
1714 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1715 gen_helper_celgb(o->out, cpu_env, o->in2, m3);
1716 tcg_temp_free_i32(m3);
1717 return NO_EXIT;
1718 }
1719
1720 static ExitStatus op_cdlgb(DisasContext *s, DisasOps *o)
1721 {
1722 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1723 gen_helper_cdlgb(o->out, cpu_env, o->in2, m3);
1724 tcg_temp_free_i32(m3);
1725 return NO_EXIT;
1726 }
1727
1728 static ExitStatus op_cxlgb(DisasContext *s, DisasOps *o)
1729 {
1730 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1731 gen_helper_cxlgb(o->out, cpu_env, o->in2, m3);
1732 tcg_temp_free_i32(m3);
1733 return_low128(o->out2);
1734 return NO_EXIT;
1735 }
1736
1737 static ExitStatus op_cksm(DisasContext *s, DisasOps *o)
1738 {
1739 int r2 = get_field(s->fields, r2);
1740 TCGv_i64 len = tcg_temp_new_i64();
1741
1742 potential_page_fault(s);
1743 gen_helper_cksm(len, cpu_env, o->in1, o->in2, regs[r2 + 1]);
1744 set_cc_static(s);
1745 return_low128(o->out);
1746
1747 tcg_gen_add_i64(regs[r2], regs[r2], len);
1748 tcg_gen_sub_i64(regs[r2 + 1], regs[r2 + 1], len);
1749 tcg_temp_free_i64(len);
1750
1751 return NO_EXIT;
1752 }
1753
1754 static ExitStatus op_clc(DisasContext *s, DisasOps *o)
1755 {
1756 int l = get_field(s->fields, l1);
1757 TCGv_i32 vl;
1758
1759 switch (l + 1) {
1760 case 1:
1761 tcg_gen_qemu_ld8u(cc_src, o->addr1, get_mem_index(s));
1762 tcg_gen_qemu_ld8u(cc_dst, o->in2, get_mem_index(s));
1763 break;
1764 case 2:
1765 tcg_gen_qemu_ld16u(cc_src, o->addr1, get_mem_index(s));
1766 tcg_gen_qemu_ld16u(cc_dst, o->in2, get_mem_index(s));
1767 break;
1768 case 4:
1769 tcg_gen_qemu_ld32u(cc_src, o->addr1, get_mem_index(s));
1770 tcg_gen_qemu_ld32u(cc_dst, o->in2, get_mem_index(s));
1771 break;
1772 case 8:
1773 tcg_gen_qemu_ld64(cc_src, o->addr1, get_mem_index(s));
1774 tcg_gen_qemu_ld64(cc_dst, o->in2, get_mem_index(s));
1775 break;
1776 default:
1777 potential_page_fault(s);
1778 vl = tcg_const_i32(l);
1779 gen_helper_clc(cc_op, cpu_env, vl, o->addr1, o->in2);
1780 tcg_temp_free_i32(vl);
1781 set_cc_static(s);
1782 return NO_EXIT;
1783 }
1784 gen_op_update2_cc_i64(s, CC_OP_LTUGTU_64, cc_src, cc_dst);
1785 return NO_EXIT;
1786 }
1787
1788 static ExitStatus op_clcle(DisasContext *s, DisasOps *o)
1789 {
1790 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
1791 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
1792 potential_page_fault(s);
1793 gen_helper_clcle(cc_op, cpu_env, r1, o->in2, r3);
1794 tcg_temp_free_i32(r1);
1795 tcg_temp_free_i32(r3);
1796 set_cc_static(s);
1797 return NO_EXIT;
1798 }
1799
1800 static ExitStatus op_clm(DisasContext *s, DisasOps *o)
1801 {
1802 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1803 TCGv_i32 t1 = tcg_temp_new_i32();
1804 tcg_gen_trunc_i64_i32(t1, o->in1);
1805 potential_page_fault(s);
1806 gen_helper_clm(cc_op, cpu_env, t1, m3, o->in2);
1807 set_cc_static(s);
1808 tcg_temp_free_i32(t1);
1809 tcg_temp_free_i32(m3);
1810 return NO_EXIT;
1811 }
1812
1813 static ExitStatus op_clst(DisasContext *s, DisasOps *o)
1814 {
1815 potential_page_fault(s);
1816 gen_helper_clst(o->in1, cpu_env, regs[0], o->in1, o->in2);
1817 set_cc_static(s);
1818 return_low128(o->in2);
1819 return NO_EXIT;
1820 }
1821
1822 static ExitStatus op_cps(DisasContext *s, DisasOps *o)
1823 {
1824 TCGv_i64 t = tcg_temp_new_i64();
1825 tcg_gen_andi_i64(t, o->in1, 0x8000000000000000ull);
1826 tcg_gen_andi_i64(o->out, o->in2, 0x7fffffffffffffffull);
1827 tcg_gen_or_i64(o->out, o->out, t);
1828 tcg_temp_free_i64(t);
1829 return NO_EXIT;
1830 }
1831
1832 static ExitStatus op_cs(DisasContext *s, DisasOps *o)
1833 {
1834 /* FIXME: needs an atomic solution for CONFIG_USER_ONLY. */
1835 int d2 = get_field(s->fields, d2);
1836 int b2 = get_field(s->fields, b2);
1837 int is_64 = s->insn->data;
1838 TCGv_i64 addr, mem, cc, z;
1839
1840 /* Note that in1 = R3 (new value) and
1841 in2 = (zero-extended) R1 (expected value). */
1842
1843 /* Load the memory into the (temporary) output. While the PoO only talks
1844 about moving the memory to R1 on inequality, if we include equality it
1845 means that R1 is equal to the memory in all conditions. */
1846 addr = get_address(s, 0, b2, d2);
1847 if (is_64) {
1848 tcg_gen_qemu_ld64(o->out, addr, get_mem_index(s));
1849 } else {
1850 tcg_gen_qemu_ld32u(o->out, addr, get_mem_index(s));
1851 }
1852
1853 /* Are the memory and expected values (un)equal? Note that this setcond
1854 produces the output CC value, thus the NE sense of the test. */
1855 cc = tcg_temp_new_i64();
1856 tcg_gen_setcond_i64(TCG_COND_NE, cc, o->in2, o->out);
1857
1858 /* If the memory and expected values are equal (CC==0), copy R3 to MEM.
1859 Recall that we are allowed to unconditionally issue the store (and
1860 thus any possible write trap), so (re-)store the original contents
1861 of MEM in case of inequality. */
1862 z = tcg_const_i64(0);
1863 mem = tcg_temp_new_i64();
1864 tcg_gen_movcond_i64(TCG_COND_EQ, mem, cc, z, o->in1, o->out);
1865 if (is_64) {
1866 tcg_gen_qemu_st64(mem, addr, get_mem_index(s));
1867 } else {
1868 tcg_gen_qemu_st32(mem, addr, get_mem_index(s));
1869 }
1870 tcg_temp_free_i64(z);
1871 tcg_temp_free_i64(mem);
1872 tcg_temp_free_i64(addr);
1873
1874 /* Store CC back to cc_op. Wait until after the store so that any
1875 exception gets the old cc_op value. */
1876 tcg_gen_trunc_i64_i32(cc_op, cc);
1877 tcg_temp_free_i64(cc);
1878 set_cc_static(s);
1879 return NO_EXIT;
1880 }
1881
1882 static ExitStatus op_cdsg(DisasContext *s, DisasOps *o)
1883 {
1884 /* FIXME: needs an atomic solution for CONFIG_USER_ONLY. */
1885 int r1 = get_field(s->fields, r1);
1886 int r3 = get_field(s->fields, r3);
1887 int d2 = get_field(s->fields, d2);
1888 int b2 = get_field(s->fields, b2);
1889 TCGv_i64 addrh, addrl, memh, meml, outh, outl, cc, z;
1890
1891 /* Note that R1:R1+1 = expected value and R3:R3+1 = new value. */
1892
1893 addrh = get_address(s, 0, b2, d2);
1894 addrl = get_address(s, 0, b2, d2 + 8);
1895 outh = tcg_temp_new_i64();
1896 outl = tcg_temp_new_i64();
1897
1898 tcg_gen_qemu_ld64(outh, addrh, get_mem_index(s));
1899 tcg_gen_qemu_ld64(outl, addrl, get_mem_index(s));
1900
1901 /* Fold the double-word compare with arithmetic. */
1902 cc = tcg_temp_new_i64();
1903 z = tcg_temp_new_i64();
1904 tcg_gen_xor_i64(cc, outh, regs[r1]);
1905 tcg_gen_xor_i64(z, outl, regs[r1 + 1]);
1906 tcg_gen_or_i64(cc, cc, z);
1907 tcg_gen_movi_i64(z, 0);
1908 tcg_gen_setcond_i64(TCG_COND_NE, cc, cc, z);
1909
1910 memh = tcg_temp_new_i64();
1911 meml = tcg_temp_new_i64();
1912 tcg_gen_movcond_i64(TCG_COND_EQ, memh, cc, z, regs[r3], outh);
1913 tcg_gen_movcond_i64(TCG_COND_EQ, meml, cc, z, regs[r3 + 1], outl);
1914 tcg_temp_free_i64(z);
1915
1916 tcg_gen_qemu_st64(memh, addrh, get_mem_index(s));
1917 tcg_gen_qemu_st64(meml, addrl, get_mem_index(s));
1918 tcg_temp_free_i64(memh);
1919 tcg_temp_free_i64(meml);
1920 tcg_temp_free_i64(addrh);
1921 tcg_temp_free_i64(addrl);
1922
1923 /* Save back state now that we've passed all exceptions. */
1924 tcg_gen_mov_i64(regs[r1], outh);
1925 tcg_gen_mov_i64(regs[r1 + 1], outl);
1926 tcg_gen_trunc_i64_i32(cc_op, cc);
1927 tcg_temp_free_i64(outh);
1928 tcg_temp_free_i64(outl);
1929 tcg_temp_free_i64(cc);
1930 set_cc_static(s);
1931 return NO_EXIT;
1932 }
1933
1934 #ifndef CONFIG_USER_ONLY
1935 static ExitStatus op_csp(DisasContext *s, DisasOps *o)
1936 {
1937 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
1938 check_privileged(s);
1939 gen_helper_csp(cc_op, cpu_env, r1, o->in2);
1940 tcg_temp_free_i32(r1);
1941 set_cc_static(s);
1942 return NO_EXIT;
1943 }
1944 #endif
1945
1946 static ExitStatus op_cvd(DisasContext *s, DisasOps *o)
1947 {
1948 TCGv_i64 t1 = tcg_temp_new_i64();
1949 TCGv_i32 t2 = tcg_temp_new_i32();
1950 tcg_gen_trunc_i64_i32(t2, o->in1);
1951 gen_helper_cvd(t1, t2);
1952 tcg_temp_free_i32(t2);
1953 tcg_gen_qemu_st64(t1, o->in2, get_mem_index(s));
1954 tcg_temp_free_i64(t1);
1955 return NO_EXIT;
1956 }
1957
1958 static ExitStatus op_ct(DisasContext *s, DisasOps *o)
1959 {
1960 int m3 = get_field(s->fields, m3);
1961 int lab = gen_new_label();
1962 TCGv_i32 t;
1963 TCGCond c;
1964
1965 c = tcg_invert_cond(ltgt_cond[m3]);
1966 if (s->insn->data) {
1967 c = tcg_unsigned_cond(c);
1968 }
1969 tcg_gen_brcond_i64(c, o->in1, o->in2, lab);
1970
1971 /* Set DXC to 0xff. */
1972 t = tcg_temp_new_i32();
1973 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUS390XState, fpc));
1974 tcg_gen_ori_i32(t, t, 0xff00);
1975 tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, fpc));
1976 tcg_temp_free_i32(t);
1977
1978 /* Trap. */
1979 gen_program_exception(s, PGM_DATA);
1980
1981 gen_set_label(lab);
1982 return NO_EXIT;
1983 }
1984
1985 #ifndef CONFIG_USER_ONLY
1986 static ExitStatus op_diag(DisasContext *s, DisasOps *o)
1987 {
1988 TCGv_i32 tmp;
1989
1990 check_privileged(s);
1991 potential_page_fault(s);
1992
1993 /* We pretend the format is RX_a so that D2 is the field we want. */
1994 tmp = tcg_const_i32(get_field(s->fields, d2) & 0xfff);
1995 gen_helper_diag(regs[2], cpu_env, tmp, regs[2], regs[1]);
1996 tcg_temp_free_i32(tmp);
1997 return NO_EXIT;
1998 }
1999 #endif
2000
2001 static ExitStatus op_divs32(DisasContext *s, DisasOps *o)
2002 {
2003 gen_helper_divs32(o->out2, cpu_env, o->in1, o->in2);
2004 return_low128(o->out);
2005 return NO_EXIT;
2006 }
2007
2008 static ExitStatus op_divu32(DisasContext *s, DisasOps *o)
2009 {
2010 gen_helper_divu32(o->out2, cpu_env, o->in1, o->in2);
2011 return_low128(o->out);
2012 return NO_EXIT;
2013 }
2014
2015 static ExitStatus op_divs64(DisasContext *s, DisasOps *o)
2016 {
2017 gen_helper_divs64(o->out2, cpu_env, o->in1, o->in2);
2018 return_low128(o->out);
2019 return NO_EXIT;
2020 }
2021
2022 static ExitStatus op_divu64(DisasContext *s, DisasOps *o)
2023 {
2024 gen_helper_divu64(o->out2, cpu_env, o->out, o->out2, o->in2);
2025 return_low128(o->out);
2026 return NO_EXIT;
2027 }
2028
2029 static ExitStatus op_deb(DisasContext *s, DisasOps *o)
2030 {
2031 gen_helper_deb(o->out, cpu_env, o->in1, o->in2);
2032 return NO_EXIT;
2033 }
2034
2035 static ExitStatus op_ddb(DisasContext *s, DisasOps *o)
2036 {
2037 gen_helper_ddb(o->out, cpu_env, o->in1, o->in2);
2038 return NO_EXIT;
2039 }
2040
2041 static ExitStatus op_dxb(DisasContext *s, DisasOps *o)
2042 {
2043 gen_helper_dxb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2);
2044 return_low128(o->out2);
2045 return NO_EXIT;
2046 }
2047
2048 static ExitStatus op_ear(DisasContext *s, DisasOps *o)
2049 {
2050 int r2 = get_field(s->fields, r2);
2051 tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, aregs[r2]));
2052 return NO_EXIT;
2053 }
2054
2055 static ExitStatus op_efpc(DisasContext *s, DisasOps *o)
2056 {
2057 tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, fpc));
2058 return NO_EXIT;
2059 }
2060
2061 static ExitStatus op_ex(DisasContext *s, DisasOps *o)
2062 {
2063 /* ??? Perhaps a better way to implement EXECUTE is to set a bit in
2064 tb->flags, (ab)use the tb->cs_base field as the address of
2065 the template in memory, and grab 8 bits of tb->flags/cflags for
2066 the contents of the register. We would then recognize all this
2067 in gen_intermediate_code_internal, generating code for exactly
2068 one instruction. This new TB then gets executed normally.
2069
2070 On the other hand, this seems to be mostly used for modifying
2071 MVC inside of memcpy, which needs a helper call anyway. So
2072 perhaps this doesn't bear thinking about any further. */
2073
2074 TCGv_i64 tmp;
2075
2076 update_psw_addr(s);
2077 update_cc_op(s);
2078
2079 tmp = tcg_const_i64(s->next_pc);
2080 gen_helper_ex(cc_op, cpu_env, cc_op, o->in1, o->in2, tmp);
2081 tcg_temp_free_i64(tmp);
2082
2083 set_cc_static(s);
2084 return NO_EXIT;
2085 }
2086
2087 static ExitStatus op_flogr(DisasContext *s, DisasOps *o)
2088 {
2089 /* We'll use the original input for cc computation, since we get to
2090 compare that against 0, which ought to be better than comparing
2091 the real output against 64. It also lets cc_dst be a convenient
2092 temporary during our computation. */
2093 gen_op_update1_cc_i64(s, CC_OP_FLOGR, o->in2);
2094
2095 /* R1 = IN ? CLZ(IN) : 64. */
2096 gen_helper_clz(o->out, o->in2);
2097
2098 /* R1+1 = IN & ~(found bit). Note that we may attempt to shift this
2099 value by 64, which is undefined. But since the shift is 64 iff the
2100 input is zero, we still get the correct result after and'ing. */
2101 tcg_gen_movi_i64(o->out2, 0x8000000000000000ull);
2102 tcg_gen_shr_i64(o->out2, o->out2, o->out);
2103 tcg_gen_andc_i64(o->out2, cc_dst, o->out2);
2104 return NO_EXIT;
2105 }
2106
2107 static ExitStatus op_icm(DisasContext *s, DisasOps *o)
2108 {
2109 int m3 = get_field(s->fields, m3);
2110 int pos, len, base = s->insn->data;
2111 TCGv_i64 tmp = tcg_temp_new_i64();
2112 uint64_t ccm;
2113
2114 switch (m3) {
2115 case 0xf:
2116 /* Effectively a 32-bit load. */
2117 tcg_gen_qemu_ld32u(tmp, o->in2, get_mem_index(s));
2118 len = 32;
2119 goto one_insert;
2120
2121 case 0xc:
2122 case 0x6:
2123 case 0x3:
2124 /* Effectively a 16-bit load. */
2125 tcg_gen_qemu_ld16u(tmp, o->in2, get_mem_index(s));
2126 len = 16;
2127 goto one_insert;
2128
2129 case 0x8:
2130 case 0x4:
2131 case 0x2:
2132 case 0x1:
2133 /* Effectively an 8-bit load. */
2134 tcg_gen_qemu_ld8u(tmp, o->in2, get_mem_index(s));
2135 len = 8;
2136 goto one_insert;
2137
2138 one_insert:
2139 pos = base + ctz32(m3) * 8;
2140 tcg_gen_deposit_i64(o->out, o->out, tmp, pos, len);
2141 ccm = ((1ull << len) - 1) << pos;
2142 break;
2143
2144 default:
2145 /* This is going to be a sequence of loads and inserts. */
2146 pos = base + 32 - 8;
2147 ccm = 0;
2148 while (m3) {
2149 if (m3 & 0x8) {
2150 tcg_gen_qemu_ld8u(tmp, o->in2, get_mem_index(s));
2151 tcg_gen_addi_i64(o->in2, o->in2, 1);
2152 tcg_gen_deposit_i64(o->out, o->out, tmp, pos, 8);
2153 ccm |= 0xff << pos;
2154 }
2155 m3 = (m3 << 1) & 0xf;
2156 pos -= 8;
2157 }
2158 break;
2159 }
2160
2161 tcg_gen_movi_i64(tmp, ccm);
2162 gen_op_update2_cc_i64(s, CC_OP_ICM, tmp, o->out);
2163 tcg_temp_free_i64(tmp);
2164 return NO_EXIT;
2165 }
2166
2167 static ExitStatus op_insi(DisasContext *s, DisasOps *o)
2168 {
2169 int shift = s->insn->data & 0xff;
2170 int size = s->insn->data >> 8;
2171 tcg_gen_deposit_i64(o->out, o->in1, o->in2, shift, size);
2172 return NO_EXIT;
2173 }
2174
2175 static ExitStatus op_ipm(DisasContext *s, DisasOps *o)
2176 {
2177 TCGv_i64 t1;
2178
2179 gen_op_calc_cc(s);
2180 tcg_gen_andi_i64(o->out, o->out, ~0xff000000ull);
2181
2182 t1 = tcg_temp_new_i64();
2183 tcg_gen_shli_i64(t1, psw_mask, 20);
2184 tcg_gen_shri_i64(t1, t1, 36);
2185 tcg_gen_or_i64(o->out, o->out, t1);
2186
2187 tcg_gen_extu_i32_i64(t1, cc_op);
2188 tcg_gen_shli_i64(t1, t1, 28);
2189 tcg_gen_or_i64(o->out, o->out, t1);
2190 tcg_temp_free_i64(t1);
2191 return NO_EXIT;
2192 }
2193
2194 #ifndef CONFIG_USER_ONLY
2195 static ExitStatus op_ipte(DisasContext *s, DisasOps *o)
2196 {
2197 check_privileged(s);
2198 gen_helper_ipte(cpu_env, o->in1, o->in2);
2199 return NO_EXIT;
2200 }
2201
2202 static ExitStatus op_iske(DisasContext *s, DisasOps *o)
2203 {
2204 check_privileged(s);
2205 gen_helper_iske(o->out, cpu_env, o->in2);
2206 return NO_EXIT;
2207 }
2208 #endif
2209
2210 static ExitStatus op_ldeb(DisasContext *s, DisasOps *o)
2211 {
2212 gen_helper_ldeb(o->out, cpu_env, o->in2);
2213 return NO_EXIT;
2214 }
2215
2216 static ExitStatus op_ledb(DisasContext *s, DisasOps *o)
2217 {
2218 gen_helper_ledb(o->out, cpu_env, o->in2);
2219 return NO_EXIT;
2220 }
2221
2222 static ExitStatus op_ldxb(DisasContext *s, DisasOps *o)
2223 {
2224 gen_helper_ldxb(o->out, cpu_env, o->in1, o->in2);
2225 return NO_EXIT;
2226 }
2227
2228 static ExitStatus op_lexb(DisasContext *s, DisasOps *o)
2229 {
2230 gen_helper_lexb(o->out, cpu_env, o->in1, o->in2);
2231 return NO_EXIT;
2232 }
2233
2234 static ExitStatus op_lxdb(DisasContext *s, DisasOps *o)
2235 {
2236 gen_helper_lxdb(o->out, cpu_env, o->in2);
2237 return_low128(o->out2);
2238 return NO_EXIT;
2239 }
2240
2241 static ExitStatus op_lxeb(DisasContext *s, DisasOps *o)
2242 {
2243 gen_helper_lxeb(o->out, cpu_env, o->in2);
2244 return_low128(o->out2);
2245 return NO_EXIT;
2246 }
2247
2248 static ExitStatus op_llgt(DisasContext *s, DisasOps *o)
2249 {
2250 tcg_gen_andi_i64(o->out, o->in2, 0x7fffffff);
2251 return NO_EXIT;
2252 }
2253
2254 static ExitStatus op_ld8s(DisasContext *s, DisasOps *o)
2255 {
2256 tcg_gen_qemu_ld8s(o->out, o->in2, get_mem_index(s));
2257 return NO_EXIT;
2258 }
2259
2260 static ExitStatus op_ld8u(DisasContext *s, DisasOps *o)
2261 {
2262 tcg_gen_qemu_ld8u(o->out, o->in2, get_mem_index(s));
2263 return NO_EXIT;
2264 }
2265
2266 static ExitStatus op_ld16s(DisasContext *s, DisasOps *o)
2267 {
2268 tcg_gen_qemu_ld16s(o->out, o->in2, get_mem_index(s));
2269 return NO_EXIT;
2270 }
2271
2272 static ExitStatus op_ld16u(DisasContext *s, DisasOps *o)
2273 {
2274 tcg_gen_qemu_ld16u(o->out, o->in2, get_mem_index(s));
2275 return NO_EXIT;
2276 }
2277
2278 static ExitStatus op_ld32s(DisasContext *s, DisasOps *o)
2279 {
2280 tcg_gen_qemu_ld32s(o->out, o->in2, get_mem_index(s));
2281 return NO_EXIT;
2282 }
2283
2284 static ExitStatus op_ld32u(DisasContext *s, DisasOps *o)
2285 {
2286 tcg_gen_qemu_ld32u(o->out, o->in2, get_mem_index(s));
2287 return NO_EXIT;
2288 }
2289
2290 static ExitStatus op_ld64(DisasContext *s, DisasOps *o)
2291 {
2292 tcg_gen_qemu_ld64(o->out, o->in2, get_mem_index(s));
2293 return NO_EXIT;
2294 }
2295
2296 static ExitStatus op_loc(DisasContext *s, DisasOps *o)
2297 {
2298 DisasCompare c;
2299
2300 disas_jcc(s, &c, get_field(s->fields, m3));
2301
2302 if (c.is_64) {
2303 tcg_gen_movcond_i64(c.cond, o->out, c.u.s64.a, c.u.s64.b,
2304 o->in2, o->in1);
2305 free_compare(&c);
2306 } else {
2307 TCGv_i32 t32 = tcg_temp_new_i32();
2308 TCGv_i64 t, z;
2309
2310 tcg_gen_setcond_i32(c.cond, t32, c.u.s32.a, c.u.s32.b);
2311 free_compare(&c);
2312
2313 t = tcg_temp_new_i64();
2314 tcg_gen_extu_i32_i64(t, t32);
2315 tcg_temp_free_i32(t32);
2316
2317 z = tcg_const_i64(0);
2318 tcg_gen_movcond_i64(TCG_COND_NE, o->out, t, z, o->in2, o->in1);
2319 tcg_temp_free_i64(t);
2320 tcg_temp_free_i64(z);
2321 }
2322
2323 return NO_EXIT;
2324 }
2325
2326 #ifndef CONFIG_USER_ONLY
2327 static ExitStatus op_lctl(DisasContext *s, DisasOps *o)
2328 {
2329 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2330 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
2331 check_privileged(s);
2332 potential_page_fault(s);
2333 gen_helper_lctl(cpu_env, r1, o->in2, r3);
2334 tcg_temp_free_i32(r1);
2335 tcg_temp_free_i32(r3);
2336 return NO_EXIT;
2337 }
2338
2339 static ExitStatus op_lctlg(DisasContext *s, DisasOps *o)
2340 {
2341 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2342 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
2343 check_privileged(s);
2344 potential_page_fault(s);
2345 gen_helper_lctlg(cpu_env, r1, o->in2, r3);
2346 tcg_temp_free_i32(r1);
2347 tcg_temp_free_i32(r3);
2348 return NO_EXIT;
2349 }
2350 static ExitStatus op_lra(DisasContext *s, DisasOps *o)
2351 {
2352 check_privileged(s);
2353 potential_page_fault(s);
2354 gen_helper_lra(o->out, cpu_env, o->in2);
2355 set_cc_static(s);
2356 return NO_EXIT;
2357 }
2358
2359 static ExitStatus op_lpsw(DisasContext *s, DisasOps *o)
2360 {
2361 TCGv_i64 t1, t2;
2362
2363 check_privileged(s);
2364
2365 t1 = tcg_temp_new_i64();
2366 t2 = tcg_temp_new_i64();
2367 tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
2368 tcg_gen_addi_i64(o->in2, o->in2, 4);
2369 tcg_gen_qemu_ld32u(t2, o->in2, get_mem_index(s));
2370 /* Convert the 32-bit PSW_MASK into the 64-bit PSW_MASK. */
2371 tcg_gen_shli_i64(t1, t1, 32);
2372 gen_helper_load_psw(cpu_env, t1, t2);
2373 tcg_temp_free_i64(t1);
2374 tcg_temp_free_i64(t2);
2375 return EXIT_NORETURN;
2376 }
2377
2378 static ExitStatus op_lpswe(DisasContext *s, DisasOps *o)
2379 {
2380 TCGv_i64 t1, t2;
2381
2382 check_privileged(s);
2383
2384 t1 = tcg_temp_new_i64();
2385 t2 = tcg_temp_new_i64();
2386 tcg_gen_qemu_ld64(t1, o->in2, get_mem_index(s));
2387 tcg_gen_addi_i64(o->in2, o->in2, 8);
2388 tcg_gen_qemu_ld64(t2, o->in2, get_mem_index(s));
2389 gen_helper_load_psw(cpu_env, t1, t2);
2390 tcg_temp_free_i64(t1);
2391 tcg_temp_free_i64(t2);
2392 return EXIT_NORETURN;
2393 }
2394 #endif
2395
2396 static ExitStatus op_lam(DisasContext *s, DisasOps *o)
2397 {
2398 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2399 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
2400 potential_page_fault(s);
2401 gen_helper_lam(cpu_env, r1, o->in2, r3);
2402 tcg_temp_free_i32(r1);
2403 tcg_temp_free_i32(r3);
2404 return NO_EXIT;
2405 }
2406
2407 static ExitStatus op_lm32(DisasContext *s, DisasOps *o)
2408 {
2409 int r1 = get_field(s->fields, r1);
2410 int r3 = get_field(s->fields, r3);
2411 TCGv_i64 t = tcg_temp_new_i64();
2412 TCGv_i64 t4 = tcg_const_i64(4);
2413
2414 while (1) {
2415 tcg_gen_qemu_ld32u(t, o->in2, get_mem_index(s));
2416 store_reg32_i64(r1, t);
2417 if (r1 == r3) {
2418 break;
2419 }
2420 tcg_gen_add_i64(o->in2, o->in2, t4);
2421 r1 = (r1 + 1) & 15;
2422 }
2423
2424 tcg_temp_free_i64(t);
2425 tcg_temp_free_i64(t4);
2426 return NO_EXIT;
2427 }
2428
2429 static ExitStatus op_lmh(DisasContext *s, DisasOps *o)
2430 {
2431 int r1 = get_field(s->fields, r1);
2432 int r3 = get_field(s->fields, r3);
2433 TCGv_i64 t = tcg_temp_new_i64();
2434 TCGv_i64 t4 = tcg_const_i64(4);
2435
2436 while (1) {
2437 tcg_gen_qemu_ld32u(t, o->in2, get_mem_index(s));
2438 store_reg32h_i64(r1, t);
2439 if (r1 == r3) {
2440 break;
2441 }
2442 tcg_gen_add_i64(o->in2, o->in2, t4);
2443 r1 = (r1 + 1) & 15;
2444 }
2445
2446 tcg_temp_free_i64(t);
2447 tcg_temp_free_i64(t4);
2448 return NO_EXIT;
2449 }
2450
2451 static ExitStatus op_lm64(DisasContext *s, DisasOps *o)
2452 {
2453 int r1 = get_field(s->fields, r1);
2454 int r3 = get_field(s->fields, r3);
2455 TCGv_i64 t8 = tcg_const_i64(8);
2456
2457 while (1) {
2458 tcg_gen_qemu_ld64(regs[r1], o->in2, get_mem_index(s));
2459 if (r1 == r3) {
2460 break;
2461 }
2462 tcg_gen_add_i64(o->in2, o->in2, t8);
2463 r1 = (r1 + 1) & 15;
2464 }
2465
2466 tcg_temp_free_i64(t8);
2467 return NO_EXIT;
2468 }
2469
2470 static ExitStatus op_mov2(DisasContext *s, DisasOps *o)
2471 {
2472 o->out = o->in2;
2473 o->g_out = o->g_in2;
2474 TCGV_UNUSED_I64(o->in2);
2475 o->g_in2 = false;
2476 return NO_EXIT;
2477 }
2478
2479 static ExitStatus op_movx(DisasContext *s, DisasOps *o)
2480 {
2481 o->out = o->in1;
2482 o->out2 = o->in2;
2483 o->g_out = o->g_in1;
2484 o->g_out2 = o->g_in2;
2485 TCGV_UNUSED_I64(o->in1);
2486 TCGV_UNUSED_I64(o->in2);
2487 o->g_in1 = o->g_in2 = false;
2488 return NO_EXIT;
2489 }
2490
2491 static ExitStatus op_mvc(DisasContext *s, DisasOps *o)
2492 {
2493 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
2494 potential_page_fault(s);
2495 gen_helper_mvc(cpu_env, l, o->addr1, o->in2);
2496 tcg_temp_free_i32(l);
2497 return NO_EXIT;
2498 }
2499
2500 static ExitStatus op_mvcl(DisasContext *s, DisasOps *o)
2501 {
2502 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2503 TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));
2504 potential_page_fault(s);
2505 gen_helper_mvcl(cc_op, cpu_env, r1, r2);
2506 tcg_temp_free_i32(r1);
2507 tcg_temp_free_i32(r2);
2508 set_cc_static(s);
2509 return NO_EXIT;
2510 }
2511
2512 static ExitStatus op_mvcle(DisasContext *s, DisasOps *o)
2513 {
2514 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2515 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
2516 potential_page_fault(s);
2517 gen_helper_mvcle(cc_op, cpu_env, r1, o->in2, r3);
2518 tcg_temp_free_i32(r1);
2519 tcg_temp_free_i32(r3);
2520 set_cc_static(s);
2521 return NO_EXIT;
2522 }
2523
2524 #ifndef CONFIG_USER_ONLY
2525 static ExitStatus op_mvcp(DisasContext *s, DisasOps *o)
2526 {
2527 int r1 = get_field(s->fields, l1);
2528 check_privileged(s);
2529 potential_page_fault(s);
2530 gen_helper_mvcp(cc_op, cpu_env, regs[r1], o->addr1, o->in2);
2531 set_cc_static(s);
2532 return NO_EXIT;
2533 }
2534
2535 static ExitStatus op_mvcs(DisasContext *s, DisasOps *o)
2536 {
2537 int r1 = get_field(s->fields, l1);
2538 check_privileged(s);
2539 potential_page_fault(s);
2540 gen_helper_mvcs(cc_op, cpu_env, regs[r1], o->addr1, o->in2);
2541 set_cc_static(s);
2542 return NO_EXIT;
2543 }
2544 #endif
2545
2546 static ExitStatus op_mvpg(DisasContext *s, DisasOps *o)
2547 {
2548 potential_page_fault(s);
2549 gen_helper_mvpg(cpu_env, regs[0], o->in1, o->in2);
2550 set_cc_static(s);
2551 return NO_EXIT;
2552 }
2553
2554 static ExitStatus op_mvst(DisasContext *s, DisasOps *o)
2555 {
2556 potential_page_fault(s);
2557 gen_helper_mvst(o->in1, cpu_env, regs[0], o->in1, o->in2);
2558 set_cc_static(s);
2559 return_low128(o->in2);
2560 return NO_EXIT;
2561 }
2562
2563 static ExitStatus op_mul(DisasContext *s, DisasOps *o)
2564 {
2565 tcg_gen_mul_i64(o->out, o->in1, o->in2);
2566 return NO_EXIT;
2567 }
2568
2569 static ExitStatus op_mul128(DisasContext *s, DisasOps *o)
2570 {
2571 tcg_gen_mulu2_i64(o->out2, o->out, o->in1, o->in2);
2572 return NO_EXIT;
2573 }
2574
2575 static ExitStatus op_meeb(DisasContext *s, DisasOps *o)
2576 {
2577 gen_helper_meeb(o->out, cpu_env, o->in1, o->in2);
2578 return NO_EXIT;
2579 }
2580
2581 static ExitStatus op_mdeb(DisasContext *s, DisasOps *o)
2582 {
2583 gen_helper_mdeb(o->out, cpu_env, o->in1, o->in2);
2584 return NO_EXIT;
2585 }
2586
2587 static ExitStatus op_mdb(DisasContext *s, DisasOps *o)
2588 {
2589 gen_helper_mdb(o->out, cpu_env, o->in1, o->in2);
2590 return NO_EXIT;
2591 }
2592
2593 static ExitStatus op_mxb(DisasContext *s, DisasOps *o)
2594 {
2595 gen_helper_mxb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2);
2596 return_low128(o->out2);
2597 return NO_EXIT;
2598 }
2599
2600 static ExitStatus op_mxdb(DisasContext *s, DisasOps *o)
2601 {
2602 gen_helper_mxdb(o->out, cpu_env, o->out, o->out2, o->in2);
2603 return_low128(o->out2);
2604 return NO_EXIT;
2605 }
2606
2607 static ExitStatus op_maeb(DisasContext *s, DisasOps *o)
2608 {
2609 TCGv_i64 r3 = load_freg32_i64(get_field(s->fields, r3));
2610 gen_helper_maeb(o->out, cpu_env, o->in1, o->in2, r3);
2611 tcg_temp_free_i64(r3);
2612 return NO_EXIT;
2613 }
2614
2615 static ExitStatus op_madb(DisasContext *s, DisasOps *o)
2616 {
2617 int r3 = get_field(s->fields, r3);
2618 gen_helper_madb(o->out, cpu_env, o->in1, o->in2, fregs[r3]);
2619 return NO_EXIT;
2620 }
2621
2622 static ExitStatus op_mseb(DisasContext *s, DisasOps *o)
2623 {
2624 TCGv_i64 r3 = load_freg32_i64(get_field(s->fields, r3));
2625 gen_helper_mseb(o->out, cpu_env, o->in1, o->in2, r3);
2626 tcg_temp_free_i64(r3);
2627 return NO_EXIT;
2628 }
2629
2630 static ExitStatus op_msdb(DisasContext *s, DisasOps *o)
2631 {
2632 int r3 = get_field(s->fields, r3);
2633 gen_helper_msdb(o->out, cpu_env, o->in1, o->in2, fregs[r3]);
2634 return NO_EXIT;
2635 }
2636
2637 static ExitStatus op_nabs(DisasContext *s, DisasOps *o)
2638 {
2639 gen_helper_nabs_i64(o->out, o->in2);
2640 return NO_EXIT;
2641 }
2642
2643 static ExitStatus op_nabsf32(DisasContext *s, DisasOps *o)
2644 {
2645 tcg_gen_ori_i64(o->out, o->in2, 0x80000000ull);
2646 return NO_EXIT;
2647 }
2648
2649 static ExitStatus op_nabsf64(DisasContext *s, DisasOps *o)
2650 {
2651 tcg_gen_ori_i64(o->out, o->in2, 0x8000000000000000ull);
2652 return NO_EXIT;
2653 }
2654
2655 static ExitStatus op_nabsf128(DisasContext *s, DisasOps *o)
2656 {
2657 tcg_gen_ori_i64(o->out, o->in1, 0x8000000000000000ull);
2658 tcg_gen_mov_i64(o->out2, o->in2);
2659 return NO_EXIT;
2660 }
2661
2662 static ExitStatus op_nc(DisasContext *s, DisasOps *o)
2663 {
2664 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
2665 potential_page_fault(s);
2666 gen_helper_nc(cc_op, cpu_env, l, o->addr1, o->in2);
2667 tcg_temp_free_i32(l);
2668 set_cc_static(s);
2669 return NO_EXIT;
2670 }
2671
2672 static ExitStatus op_neg(DisasContext *s, DisasOps *o)
2673 {
2674 tcg_gen_neg_i64(o->out, o->in2);
2675 return NO_EXIT;
2676 }
2677
2678 static ExitStatus op_negf32(DisasContext *s, DisasOps *o)
2679 {
2680 tcg_gen_xori_i64(o->out, o->in2, 0x80000000ull);
2681 return NO_EXIT;
2682 }
2683
2684 static ExitStatus op_negf64(DisasContext *s, DisasOps *o)
2685 {
2686 tcg_gen_xori_i64(o->out, o->in2, 0x8000000000000000ull);
2687 return NO_EXIT;
2688 }
2689
2690 static ExitStatus op_negf128(DisasContext *s, DisasOps *o)
2691 {
2692 tcg_gen_xori_i64(o->out, o->in1, 0x8000000000000000ull);
2693 tcg_gen_mov_i64(o->out2, o->in2);
2694 return NO_EXIT;
2695 }
2696
2697 static ExitStatus op_oc(DisasContext *s, DisasOps *o)
2698 {
2699 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
2700 potential_page_fault(s);
2701 gen_helper_oc(cc_op, cpu_env, l, o->addr1, o->in2);
2702 tcg_temp_free_i32(l);
2703 set_cc_static(s);
2704 return NO_EXIT;
2705 }
2706
2707 static ExitStatus op_or(DisasContext *s, DisasOps *o)
2708 {
2709 tcg_gen_or_i64(o->out, o->in1, o->in2);
2710 return NO_EXIT;
2711 }
2712
2713 static ExitStatus op_ori(DisasContext *s, DisasOps *o)
2714 {
2715 int shift = s->insn->data & 0xff;
2716 int size = s->insn->data >> 8;
2717 uint64_t mask = ((1ull << size) - 1) << shift;
2718
2719 assert(!o->g_in2);
2720 tcg_gen_shli_i64(o->in2, o->in2, shift);
2721 tcg_gen_or_i64(o->out, o->in1, o->in2);
2722
2723 /* Produce the CC from only the bits manipulated. */
2724 tcg_gen_andi_i64(cc_dst, o->out, mask);
2725 set_cc_nz_u64(s, cc_dst);
2726 return NO_EXIT;
2727 }
2728
2729 static ExitStatus op_popcnt(DisasContext *s, DisasOps *o)
2730 {
2731 gen_helper_popcnt(o->out, o->in2);
2732 return NO_EXIT;
2733 }
2734
2735 #ifndef CONFIG_USER_ONLY
2736 static ExitStatus op_ptlb(DisasContext *s, DisasOps *o)
2737 {
2738 check_privileged(s);
2739 gen_helper_ptlb(cpu_env);
2740 return NO_EXIT;
2741 }
2742 #endif
2743
2744 static ExitStatus op_risbg(DisasContext *s, DisasOps *o)
2745 {
2746 int i3 = get_field(s->fields, i3);
2747 int i4 = get_field(s->fields, i4);
2748 int i5 = get_field(s->fields, i5);
2749 int do_zero = i4 & 0x80;
2750 uint64_t mask, imask, pmask;
2751 int pos, len, rot;
2752
2753 /* Adjust the arguments for the specific insn. */
2754 switch (s->fields->op2) {
2755 case 0x55: /* risbg */
2756 i3 &= 63;
2757 i4 &= 63;
2758 pmask = ~0;
2759 break;
2760 case 0x5d: /* risbhg */
2761 i3 &= 31;
2762 i4 &= 31;
2763 pmask = 0xffffffff00000000ull;
2764 break;
2765 case 0x51: /* risblg */
2766 i3 &= 31;
2767 i4 &= 31;
2768 pmask = 0x00000000ffffffffull;
2769 break;
2770 default:
2771 abort();
2772 }
2773
2774 /* MASK is the set of bits to be inserted from R2.
2775 Take care for I3/I4 wraparound. */
2776 mask = pmask >> i3;
2777 if (i3 <= i4) {
2778 mask ^= pmask >> i4 >> 1;
2779 } else {
2780 mask |= ~(pmask >> i4 >> 1);
2781 }
2782 mask &= pmask;
2783
2784 /* IMASK is the set of bits to be kept from R1. In the case of the high/low
2785 insns, we need to keep the other half of the register. */
2786 imask = ~mask | ~pmask;
2787 if (do_zero) {
2788 if (s->fields->op2 == 0x55) {
2789 imask = 0;
2790 } else {
2791 imask = ~pmask;
2792 }
2793 }
2794
2795 /* In some cases we can implement this with deposit, which can be more
2796 efficient on some hosts. */
2797 if (~mask == imask && i3 <= i4) {
2798 if (s->fields->op2 == 0x5d) {
2799 i3 += 32, i4 += 32;
2800 }
2801 /* Note that we rotate the bits to be inserted to the lsb, not to
2802 the position as described in the PoO. */
2803 len = i4 - i3 + 1;
2804 pos = 63 - i4;
2805 rot = (i5 - pos) & 63;
2806 } else {
2807 pos = len = -1;
2808 rot = i5 & 63;
2809 }
2810
2811 /* Rotate the input as necessary. */
2812 tcg_gen_rotli_i64(o->in2, o->in2, rot);
2813
2814 /* Insert the selected bits into the output. */
2815 if (pos >= 0) {
2816 tcg_gen_deposit_i64(o->out, o->out, o->in2, pos, len);
2817 } else if (imask == 0) {
2818 tcg_gen_andi_i64(o->out, o->in2, mask);
2819 } else {
2820 tcg_gen_andi_i64(o->in2, o->in2, mask);
2821 tcg_gen_andi_i64(o->out, o->out, imask);
2822 tcg_gen_or_i64(o->out, o->out, o->in2);
2823 }
2824 return NO_EXIT;
2825 }
2826
2827 static ExitStatus op_rosbg(DisasContext *s, DisasOps *o)
2828 {
2829 int i3 = get_field(s->fields, i3);
2830 int i4 = get_field(s->fields, i4);
2831 int i5 = get_field(s->fields, i5);
2832 uint64_t mask;
2833
2834 /* If this is a test-only form, arrange to discard the result. */
2835 if (i3 & 0x80) {
2836 o->out = tcg_temp_new_i64();
2837 o->g_out = false;
2838 }
2839
2840 i3 &= 63;
2841 i4 &= 63;
2842 i5 &= 63;
2843
2844 /* MASK is the set of bits to be operated on from R2.
2845 Take care for I3/I4 wraparound. */
2846 mask = ~0ull >> i3;
2847 if (i3 <= i4) {
2848 mask ^= ~0ull >> i4 >> 1;
2849 } else {
2850 mask |= ~(~0ull >> i4 >> 1);
2851 }
2852
2853 /* Rotate the input as necessary. */
2854 tcg_gen_rotli_i64(o->in2, o->in2, i5);
2855
2856 /* Operate. */
2857 switch (s->fields->op2) {
2858 case 0x55: /* AND */
2859 tcg_gen_ori_i64(o->in2, o->in2, ~mask);
2860 tcg_gen_and_i64(o->out, o->out, o->in2);
2861 break;
2862 case 0x56: /* OR */
2863 tcg_gen_andi_i64(o->in2, o->in2, mask);
2864 tcg_gen_or_i64(o->out, o->out, o->in2);
2865 break;
2866 case 0x57: /* XOR */
2867 tcg_gen_andi_i64(o->in2, o->in2, mask);
2868 tcg_gen_xor_i64(o->out, o->out, o->in2);
2869 break;
2870 default:
2871 abort();
2872 }
2873
2874 /* Set the CC. */
2875 tcg_gen_andi_i64(cc_dst, o->out, mask);
2876 set_cc_nz_u64(s, cc_dst);
2877 return NO_EXIT;
2878 }
2879
2880 static ExitStatus op_rev16(DisasContext *s, DisasOps *o)
2881 {
2882 tcg_gen_bswap16_i64(o->out, o->in2);
2883 return NO_EXIT;
2884 }
2885
2886 static ExitStatus op_rev32(DisasContext *s, DisasOps *o)
2887 {
2888 tcg_gen_bswap32_i64(o->out, o->in2);
2889 return NO_EXIT;
2890 }
2891
2892 static ExitStatus op_rev64(DisasContext *s, DisasOps *o)
2893 {
2894 tcg_gen_bswap64_i64(o->out, o->in2);
2895 return NO_EXIT;
2896 }
2897
2898 static ExitStatus op_rll32(DisasContext *s, DisasOps *o)
2899 {
2900 TCGv_i32 t1 = tcg_temp_new_i32();
2901 TCGv_i32 t2 = tcg_temp_new_i32();
2902 TCGv_i32 to = tcg_temp_new_i32();
2903 tcg_gen_trunc_i64_i32(t1, o->in1);
2904 tcg_gen_trunc_i64_i32(t2, o->in2);
2905 tcg_gen_rotl_i32(to, t1, t2);
2906 tcg_gen_extu_i32_i64(o->out, to);
2907 tcg_temp_free_i32(t1);
2908 tcg_temp_free_i32(t2);
2909 tcg_temp_free_i32(to);
2910 return NO_EXIT;
2911 }
2912
2913 static ExitStatus op_rll64(DisasContext *s, DisasOps *o)
2914 {
2915 tcg_gen_rotl_i64(o->out, o->in1, o->in2);
2916 return NO_EXIT;
2917 }
2918
2919 #ifndef CONFIG_USER_ONLY
2920 static ExitStatus op_rrbe(DisasContext *s, DisasOps *o)
2921 {
2922 check_privileged(s);
2923 gen_helper_rrbe(cc_op, cpu_env, o->in2);
2924 set_cc_static(s);
2925 return NO_EXIT;
2926 }
2927
2928 static ExitStatus op_sacf(DisasContext *s, DisasOps *o)
2929 {
2930 check_privileged(s);
2931 gen_helper_sacf(cpu_env, o->in2);
2932 /* Addressing mode has changed, so end the block. */
2933 return EXIT_PC_STALE;
2934 }
2935 #endif
2936
2937 static ExitStatus op_sar(DisasContext *s, DisasOps *o)
2938 {
2939 int r1 = get_field(s->fields, r1);
2940 tcg_gen_st32_i64(o->in2, cpu_env, offsetof(CPUS390XState, aregs[r1]));
2941 return NO_EXIT;
2942 }
2943
2944 static ExitStatus op_seb(DisasContext *s, DisasOps *o)
2945 {
2946 gen_helper_seb(o->out, cpu_env, o->in1, o->in2);
2947 return NO_EXIT;
2948 }
2949
2950 static ExitStatus op_sdb(DisasContext *s, DisasOps *o)
2951 {
2952 gen_helper_sdb(o->out, cpu_env, o->in1, o->in2);
2953 return NO_EXIT;
2954 }
2955
2956 static ExitStatus op_sxb(DisasContext *s, DisasOps *o)
2957 {
2958 gen_helper_sxb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2);
2959 return_low128(o->out2);
2960 return NO_EXIT;
2961 }
2962
2963 static ExitStatus op_sqeb(DisasContext *s, DisasOps *o)
2964 {
2965 gen_helper_sqeb(o->out, cpu_env, o->in2);
2966 return NO_EXIT;
2967 }
2968
2969 static ExitStatus op_sqdb(DisasContext *s, DisasOps *o)
2970 {
2971 gen_helper_sqdb(o->out, cpu_env, o->in2);
2972 return NO_EXIT;
2973 }
2974
2975 static ExitStatus op_sqxb(DisasContext *s, DisasOps *o)
2976 {
2977 gen_helper_sqxb(o->out, cpu_env, o->in1, o->in2);
2978 return_low128(o->out2);
2979 return NO_EXIT;
2980 }
2981
2982 #ifndef CONFIG_USER_ONLY
2983 static ExitStatus op_servc(DisasContext *s, DisasOps *o)
2984 {
2985 check_privileged(s);
2986 potential_page_fault(s);
2987 gen_helper_servc(cc_op, cpu_env, o->in2, o->in1);
2988 set_cc_static(s);
2989 return NO_EXIT;
2990 }
2991
2992 static ExitStatus op_sigp(DisasContext *s, DisasOps *o)
2993 {
2994 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2995 check_privileged(s);
2996 potential_page_fault(s);
2997 gen_helper_sigp(cc_op, cpu_env, o->in2, r1, o->in1);
2998 tcg_temp_free_i32(r1);
2999 return NO_EXIT;
3000 }
3001 #endif
3002
3003 static ExitStatus op_soc(DisasContext *s, DisasOps *o)
3004 {
3005 DisasCompare c;
3006 TCGv_i64 a;
3007 int lab, r1;
3008
3009 disas_jcc(s, &c, get_field(s->fields, m3));
3010
3011 lab = gen_new_label();
3012 if (c.is_64) {
3013 tcg_gen_brcond_i64(c.cond, c.u.s64.a, c.u.s64.b, lab);
3014 } else {
3015 tcg_gen_brcond_i32(c.cond, c.u.s32.a, c.u.s32.b, lab);
3016 }
3017 free_compare(&c);
3018
3019 r1 = get_field(s->fields, r1);
3020 a = get_address(s, 0, get_field(s->fields, b2), get_field(s->fields, d2));
3021 if (s->insn->data) {
3022 tcg_gen_qemu_st64(regs[r1], a, get_mem_index(s));
3023 } else {
3024 tcg_gen_qemu_st32(regs[r1], a, get_mem_index(s));
3025 }
3026 tcg_temp_free_i64(a);
3027
3028 gen_set_label(lab);
3029 return NO_EXIT;
3030 }
3031
3032 static ExitStatus op_sla(DisasContext *s, DisasOps *o)
3033 {
3034 uint64_t sign = 1ull << s->insn->data;
3035 enum cc_op cco = s->insn->data == 31 ? CC_OP_SLA_32 : CC_OP_SLA_64;
3036 gen_op_update2_cc_i64(s, cco, o->in1, o->in2);
3037 tcg_gen_shl_i64(o->out, o->in1, o->in2);
3038 /* The arithmetic left shift is curious in that it does not affect
3039 the sign bit. Copy that over from the source unchanged. */
3040 tcg_gen_andi_i64(o->out, o->out, ~sign);
3041 tcg_gen_andi_i64(o->in1, o->in1, sign);
3042 tcg_gen_or_i64(o->out, o->out, o->in1);
3043 return NO_EXIT;
3044 }
3045
3046 static ExitStatus op_sll(DisasContext *s, DisasOps *o)
3047 {
3048 tcg_gen_shl_i64(o->out, o->in1, o->in2);
3049 return NO_EXIT;
3050 }
3051
3052 static ExitStatus op_sra(DisasContext *s, DisasOps *o)
3053 {
3054 tcg_gen_sar_i64(o->out, o->in1, o->in2);
3055 return NO_EXIT;
3056 }
3057
3058 static ExitStatus op_srl(DisasContext *s, DisasOps *o)
3059 {
3060 tcg_gen_shr_i64(o->out, o->in1, o->in2);
3061 return NO_EXIT;
3062 }
3063
3064 static ExitStatus op_sfpc(DisasContext *s, DisasOps *o)
3065 {
3066 gen_helper_sfpc(cpu_env, o->in2);
3067 return NO_EXIT;
3068 }
3069
3070 static ExitStatus op_sfas(DisasContext *s, DisasOps *o)
3071 {
3072 gen_helper_sfas(cpu_env, o->in2);
3073 return NO_EXIT;
3074 }
3075
3076 static ExitStatus op_srnm(DisasContext *s, DisasOps *o)
3077 {
3078 int b2 = get_field(s->fields, b2);
3079 int d2 = get_field(s->fields, d2);
3080 TCGv_i64 t1 = tcg_temp_new_i64();
3081 TCGv_i64 t2 = tcg_temp_new_i64();
3082 int mask, pos, len;
3083
3084 switch (s->fields->op2) {
3085 case 0x99: /* SRNM */
3086 pos = 0, len = 2;
3087 break;
3088 case 0xb8: /* SRNMB */
3089 pos = 0, len = 3;
3090 break;
3091 case 0xb9: /* SRNMT */
3092 pos = 4, len = 3;
3093 break;
3094 default:
3095 tcg_abort();
3096 }
3097 mask = (1 << len) - 1;
3098
3099 /* Insert the value into the appropriate field of the FPC. */
3100 if (b2 == 0) {
3101 tcg_gen_movi_i64(t1, d2 & mask);
3102 } else {
3103 tcg_gen_addi_i64(t1, regs[b2], d2);
3104 tcg_gen_andi_i64(t1, t1, mask);
3105 }
3106 tcg_gen_ld32u_i64(t2, cpu_env, offsetof(CPUS390XState, fpc));
3107 tcg_gen_deposit_i64(t2, t2, t1, pos, len);
3108 tcg_temp_free_i64(t1);
3109
3110 /* Then install the new FPC to set the rounding mode in fpu_status. */
3111 gen_helper_sfpc(cpu_env, t2);
3112 tcg_temp_free_i64(t2);
3113 return NO_EXIT;
3114 }
3115
3116 #ifndef CONFIG_USER_ONLY
3117 static ExitStatus op_spka(DisasContext *s, DisasOps *o)
3118 {
3119 check_privileged(s);
3120 tcg_gen_shri_i64(o->in2, o->in2, 4);
3121 tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, PSW_SHIFT_KEY - 4, 4);
3122 return NO_EXIT;
3123 }
3124
3125 static ExitStatus op_sske(DisasContext *s, DisasOps *o)
3126 {
3127 check_privileged(s);
3128 gen_helper_sske(cpu_env, o->in1, o->in2);
3129 return NO_EXIT;
3130 }
3131
3132 static ExitStatus op_ssm(DisasContext *s, DisasOps *o)
3133 {
3134 check_privileged(s);
3135 tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, 56, 8);
3136 return NO_EXIT;
3137 }
3138
3139 static ExitStatus op_stap(DisasContext *s, DisasOps *o)
3140 {
3141 check_privileged(s);
3142 /* ??? Surely cpu address != cpu number. In any case the previous
3143 version of this stored more than the required half-word, so it
3144 is unlikely this has ever been tested. */
3145 tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, cpu_num));
3146 return NO_EXIT;
3147 }
3148
3149 static ExitStatus op_stck(DisasContext *s, DisasOps *o)
3150 {
3151 gen_helper_stck(o->out, cpu_env);
3152 /* ??? We don't implement clock states. */
3153 gen_op_movi_cc(s, 0);
3154 return NO_EXIT;
3155 }
3156
3157 static ExitStatus op_stcke(DisasContext *s, DisasOps *o)
3158 {
3159 TCGv_i64 c1 = tcg_temp_new_i64();
3160 TCGv_i64 c2 = tcg_temp_new_i64();
3161 gen_helper_stck(c1, cpu_env);
3162 /* Shift the 64-bit value into its place as a zero-extended
3163 104-bit value. Note that "bit positions 64-103 are always
3164 non-zero so that they compare differently to STCK"; we set
3165 the least significant bit to 1. */
3166 tcg_gen_shli_i64(c2, c1, 56);
3167 tcg_gen_shri_i64(c1, c1, 8);
3168 tcg_gen_ori_i64(c2, c2, 0x10000);
3169 tcg_gen_qemu_st64(c1, o->in2, get_mem_index(s));
3170 tcg_gen_addi_i64(o->in2, o->in2, 8);
3171 tcg_gen_qemu_st64(c2, o->in2, get_mem_index(s));
3172 tcg_temp_free_i64(c1);
3173 tcg_temp_free_i64(c2);
3174 /* ??? We don't implement clock states. */
3175 gen_op_movi_cc(s, 0);
3176 return NO_EXIT;
3177 }
3178
3179 static ExitStatus op_sckc(DisasContext *s, DisasOps *o)
3180 {
3181 check_privileged(s);
3182 gen_helper_sckc(cpu_env, o->in2);
3183 return NO_EXIT;
3184 }
3185
3186 static ExitStatus op_stckc(DisasContext *s, DisasOps *o)
3187 {
3188 check_privileged(s);
3189 gen_helper_stckc(o->out, cpu_env);
3190 return NO_EXIT;
3191 }
3192
3193 static ExitStatus op_stctg(DisasContext *s, DisasOps *o)
3194 {
3195 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
3196 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
3197 check_privileged(s);
3198 potential_page_fault(s);
3199 gen_helper_stctg(cpu_env, r1, o->in2, r3);
3200 tcg_temp_free_i32(r1);
3201 tcg_temp_free_i32(r3);
3202 return NO_EXIT;
3203 }
3204
3205 static ExitStatus op_stctl(DisasContext *s, DisasOps *o)
3206 {
3207 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
3208 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
3209 check_privileged(s);
3210 potential_page_fault(s);
3211 gen_helper_stctl(cpu_env, r1, o->in2, r3);
3212 tcg_temp_free_i32(r1);
3213 tcg_temp_free_i32(r3);
3214 return NO_EXIT;
3215 }
3216
3217 static ExitStatus op_stidp(DisasContext *s, DisasOps *o)
3218 {
3219 check_privileged(s);
3220 tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, cpu_num));
3221 return NO_EXIT;
3222 }
3223
3224 static ExitStatus op_spt(DisasContext *s, DisasOps *o)
3225 {
3226 check_privileged(s);
3227 gen_helper_spt(cpu_env, o->in2);
3228 return NO_EXIT;
3229 }
3230
3231 static ExitStatus op_stfl(DisasContext *s, DisasOps *o)
3232 {
3233 TCGv_i64 f, a;
3234 /* We really ought to have more complete indication of facilities
3235 that we implement. Address this when STFLE is implemented. */
3236 check_privileged(s);
3237 f = tcg_const_i64(0xc0000000);
3238 a = tcg_const_i64(200);
3239 tcg_gen_qemu_st32(f, a, get_mem_index(s));
3240 tcg_temp_free_i64(f);
3241 tcg_temp_free_i64(a);
3242 return NO_EXIT;
3243 }
3244
3245 static ExitStatus op_stpt(DisasContext *s, DisasOps *o)
3246 {
3247 check_privileged(s);
3248 gen_helper_stpt(o->out, cpu_env);
3249 return NO_EXIT;
3250 }
3251
3252 static ExitStatus op_stsi(DisasContext *s, DisasOps *o)
3253 {
3254 check_privileged(s);
3255 potential_page_fault(s);
3256 gen_helper_stsi(cc_op, cpu_env, o->in2, regs[0], regs[1]);
3257 set_cc_static(s);
3258 return NO_EXIT;
3259 }
3260
3261 static ExitStatus op_spx(DisasContext *s, DisasOps *o)
3262 {
3263 check_privileged(s);
3264 gen_helper_spx(cpu_env, o->in2);
3265 return NO_EXIT;
3266 }
3267
3268 static ExitStatus op_subchannel(DisasContext *s, DisasOps *o)
3269 {
3270 check_privileged(s);
3271 /* Not operational. */
3272 gen_op_movi_cc(s, 3);
3273 return NO_EXIT;
3274 }
3275
3276 static ExitStatus op_stpx(DisasContext *s, DisasOps *o)
3277 {
3278 check_privileged(s);
3279 tcg_gen_ld_i64(o->out, cpu_env, offsetof(CPUS390XState, psa));
3280 tcg_gen_andi_i64(o->out, o->out, 0x7fffe000);
3281 return NO_EXIT;
3282 }
3283
3284 static ExitStatus op_stnosm(DisasContext *s, DisasOps *o)
3285 {
3286 uint64_t i2 = get_field(s->fields, i2);
3287 TCGv_i64 t;
3288
3289 check_privileged(s);
3290
3291 /* It is important to do what the instruction name says: STORE THEN.
3292 If we let the output hook perform the store then if we fault and
3293 restart, we'll have the wrong SYSTEM MASK in place. */
3294 t = tcg_temp_new_i64();
3295 tcg_gen_shri_i64(t, psw_mask, 56);
3296 tcg_gen_qemu_st8(t, o->addr1, get_mem_index(s));
3297 tcg_temp_free_i64(t);
3298
3299 if (s->fields->op == 0xac) {
3300 tcg_gen_andi_i64(psw_mask, psw_mask,
3301 (i2 << 56) | 0x00ffffffffffffffull);
3302 } else {
3303 tcg_gen_ori_i64(psw_mask, psw_mask, i2 << 56);
3304 }
3305 return NO_EXIT;
3306 }
3307
3308 static ExitStatus op_stura(DisasContext *s, DisasOps *o)
3309 {
3310 check_privileged(s);
3311 potential_page_fault(s);
3312 gen_helper_stura(cpu_env, o->in2, o->in1);
3313 return NO_EXIT;
3314 }
3315 #endif
3316
3317 static ExitStatus op_st8(DisasContext *s, DisasOps *o)
3318 {
3319 tcg_gen_qemu_st8(o->in1, o->in2, get_mem_index(s));
3320 return NO_EXIT;
3321 }
3322
3323 static ExitStatus op_st16(DisasContext *s, DisasOps *o)
3324 {
3325 tcg_gen_qemu_st16(o->in1, o->in2, get_mem_index(s));
3326 return NO_EXIT;
3327 }
3328
3329 static ExitStatus op_st32(DisasContext *s, DisasOps *o)
3330 {
3331 tcg_gen_qemu_st32(o->in1, o->in2, get_mem_index(s));
3332 return NO_EXIT;
3333 }
3334
3335 static ExitStatus op_st64(DisasContext *s, DisasOps *o)
3336 {
3337 tcg_gen_qemu_st64(o->in1, o->in2, get_mem_index(s));
3338 return NO_EXIT;
3339 }
3340
3341 static ExitStatus op_stam(DisasContext *s, DisasOps *o)
3342 {
3343 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
3344 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
3345 potential_page_fault(s);
3346 gen_helper_stam(cpu_env, r1, o->in2, r3);
3347 tcg_temp_free_i32(r1);
3348 tcg_temp_free_i32(r3);
3349 return NO_EXIT;
3350 }
3351
3352 static ExitStatus op_stcm(DisasContext *s, DisasOps *o)
3353 {
3354 int m3 = get_field(s->fields, m3);
3355 int pos, base = s->insn->data;
3356 TCGv_i64 tmp = tcg_temp_new_i64();
3357
3358 pos = base + ctz32(m3) * 8;
3359 switch (m3) {
3360 case 0xf:
3361 /* Effectively a 32-bit store. */
3362 tcg_gen_shri_i64(tmp, o->in1, pos);
3363 tcg_gen_qemu_st32(tmp, o->in2, get_mem_index(s));
3364 break;
3365
3366 case 0xc:
3367 case 0x6:
3368 case 0x3:
3369 /* Effectively a 16-bit store. */
3370 tcg_gen_shri_i64(tmp, o->in1, pos);
3371 tcg_gen_qemu_st16(tmp, o->in2, get_mem_index(s));
3372 break;
3373
3374 case 0x8:
3375 case 0x4:
3376 case 0x2:
3377 case 0x1:
3378 /* Effectively an 8-bit store. */
3379 tcg_gen_shri_i64(tmp, o->in1, pos);
3380 tcg_gen_qemu_st8(tmp, o->in2, get_mem_index(s));
3381 break;
3382
3383 default:
3384 /* This is going to be a sequence of shifts and stores. */
3385 pos = base + 32 - 8;
3386 while (m3) {
3387 if (m3 & 0x8) {
3388 tcg_gen_shri_i64(tmp, o->in1, pos);
3389 tcg_gen_qemu_st8(tmp, o->in2, get_mem_index(s));
3390 tcg_gen_addi_i64(o->in2, o->in2, 1);
3391 }
3392 m3 = (m3 << 1) & 0xf;
3393 pos -= 8;
3394 }
3395 break;
3396 }
3397 tcg_temp_free_i64(tmp);
3398 return NO_EXIT;
3399 }
3400
3401 static ExitStatus op_stm(DisasContext *s, DisasOps *o)
3402 {
3403 int r1 = get_field(s->fields, r1);
3404 int r3 = get_field(s->fields, r3);
3405 int size = s->insn->data;
3406 TCGv_i64 tsize = tcg_const_i64(size);
3407
3408 while (1) {
3409 if (size == 8) {
3410 tcg_gen_qemu_st64(regs[r1], o->in2, get_mem_index(s));
3411 } else {
3412 tcg_gen_qemu_st32(regs[r1], o->in2, get_mem_index(s));
3413 }
3414 if (r1 == r3) {
3415 break;
3416 }
3417 tcg_gen_add_i64(o->in2, o->in2, tsize);
3418 r1 = (r1 + 1) & 15;
3419 }
3420
3421 tcg_temp_free_i64(tsize);
3422 return NO_EXIT;
3423 }
3424
3425 static ExitStatus op_stmh(DisasContext *s, DisasOps *o)
3426 {
3427 int r1 = get_field(s->fields, r1);
3428 int r3 = get_field(s->fields, r3);
3429 TCGv_i64 t = tcg_temp_new_i64();
3430 TCGv_i64 t4 = tcg_const_i64(4);
3431 TCGv_i64 t32 = tcg_const_i64(32);
3432
3433 while (1) {
3434 tcg_gen_shl_i64(t, regs[r1], t32);
3435 tcg_gen_qemu_st32(t, o->in2, get_mem_index(s));
3436 if (r1 == r3) {
3437 break;
3438 }
3439 tcg_gen_add_i64(o->in2, o->in2, t4);
3440 r1 = (r1 + 1) & 15;
3441 }
3442
3443 tcg_temp_free_i64(t);
3444 tcg_temp_free_i64(t4);
3445 tcg_temp_free_i64(t32);
3446 return NO_EXIT;
3447 }
3448
3449 static ExitStatus op_srst(DisasContext *s, DisasOps *o)
3450 {
3451 potential_page_fault(s);
3452 gen_helper_srst(o->in1, cpu_env, regs[0], o->in1, o->in2);
3453 set_cc_static(s);
3454 return_low128(o->in2);
3455 return NO_EXIT;
3456 }
3457
3458 static ExitStatus op_sub(DisasContext *s, DisasOps *o)
3459 {
3460 tcg_gen_sub_i64(o->out, o->in1, o->in2);
3461 return NO_EXIT;
3462 }
3463
3464 static ExitStatus op_subb(DisasContext *s, DisasOps *o)
3465 {
3466 DisasCompare cmp;
3467 TCGv_i64 borrow;
3468
3469 tcg_gen_sub_i64(o->out, o->in1, o->in2);
3470
3471 /* The !borrow flag is the msb of CC. Since we want the inverse of
3472 that, we ask for a comparison of CC=0 | CC=1 -> mask of 8 | 4. */
3473 disas_jcc(s, &cmp, 8 | 4);
3474 borrow = tcg_temp_new_i64();
3475 if (cmp.is_64) {
3476 tcg_gen_setcond_i64(cmp.cond, borrow, cmp.u.s64.a, cmp.u.s64.b);
3477 } else {
3478 TCGv_i32 t = tcg_temp_new_i32();
3479 tcg_gen_setcond_i32(cmp.cond, t, cmp.u.s32.a, cmp.u.s32.b);
3480 tcg_gen_extu_i32_i64(borrow, t);
3481 tcg_temp_free_i32(t);
3482 }
3483 free_compare(&cmp);
3484
3485 tcg_gen_sub_i64(o->out, o->out, borrow);
3486 tcg_temp_free_i64(borrow);
3487 return NO_EXIT;
3488 }
3489
3490 static ExitStatus op_svc(DisasContext *s, DisasOps *o)
3491 {
3492 TCGv_i32 t;
3493
3494 update_psw_addr(s);
3495 update_cc_op(s);
3496
3497 t = tcg_const_i32(get_field(s->fields, i1) & 0xff);
3498 tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, int_svc_code));
3499 tcg_temp_free_i32(t);
3500
3501 t = tcg_const_i32(s->next_pc - s->pc);
3502 tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, int_svc_ilen));
3503 tcg_temp_free_i32(t);
3504
3505 gen_exception(EXCP_SVC);
3506 return EXIT_NORETURN;
3507 }
3508
3509 static ExitStatus op_tceb(DisasContext *s, DisasOps *o)
3510 {
3511 gen_helper_tceb(cc_op, o->in1, o->in2);
3512 set_cc_static(s);
3513 return NO_EXIT;
3514 }
3515
3516 static ExitStatus op_tcdb(DisasContext *s, DisasOps *o)
3517 {
3518 gen_helper_tcdb(cc_op, o->in1, o->in2);
3519 set_cc_static(s);
3520 return NO_EXIT;
3521 }
3522
3523 static ExitStatus op_tcxb(DisasContext *s, DisasOps *o)
3524 {
3525 gen_helper_tcxb(cc_op, o->out, o->out2, o->in2);
3526 set_cc_static(s);
3527 return NO_EXIT;
3528 }
3529
3530 #ifndef CONFIG_USER_ONLY
3531 static ExitStatus op_tprot(DisasContext *s, DisasOps *o)
3532 {
3533 potential_page_fault(s);
3534 gen_helper_tprot(cc_op, o->addr1, o->in2);
3535 set_cc_static(s);
3536 return NO_EXIT;
3537 }
3538 #endif
3539
3540 static ExitStatus op_tr(DisasContext *s, DisasOps *o)
3541 {
3542 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
3543 potential_page_fault(s);
3544 gen_helper_tr(cpu_env, l, o->addr1, o->in2);
3545 tcg_temp_free_i32(l);
3546 set_cc_static(s);
3547 return NO_EXIT;
3548 }
3549
3550 static ExitStatus op_unpk(DisasContext *s, DisasOps *o)
3551 {
3552 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
3553 potential_page_fault(s);
3554 gen_helper_unpk(cpu_env, l, o->addr1, o->in2);
3555 tcg_temp_free_i32(l);
3556 return NO_EXIT;
3557 }
3558
3559 static ExitStatus op_xc(DisasContext *s, DisasOps *o)
3560 {
3561 int d1 = get_field(s->fields, d1);
3562 int d2 = get_field(s->fields, d2);
3563 int b1 = get_field(s->fields, b1);
3564 int b2 = get_field(s->fields, b2);
3565 int l = get_field(s->fields, l1);
3566 TCGv_i32 t32;
3567
3568 o->addr1 = get_address(s, 0, b1, d1);
3569
3570 /* If the addresses are identical, this is a store/memset of zero. */
3571 if (b1 == b2 && d1 == d2 && (l + 1) <= 32) {
3572 o->in2 = tcg_const_i64(0);
3573
3574 l++;
3575 while (l >= 8) {
3576 tcg_gen_qemu_st64(o->in2, o->addr1, get_mem_index(s));
3577 l -= 8;
3578 if (l > 0) {
3579 tcg_gen_addi_i64(o->addr1, o->addr1, 8);
3580 }
3581 }
3582 if (l >= 4) {
3583 tcg_gen_qemu_st32(o->in2, o->addr1, get_mem_index(s));
3584 l -= 4;
3585 if (l > 0) {
3586 tcg_gen_addi_i64(o->addr1, o->addr1, 4);
3587 }
3588 }
3589 if (l >= 2) {
3590 tcg_gen_qemu_st16(o->in2, o->addr1, get_mem_index(s));
3591 l -= 2;
3592 if (l > 0) {
3593 tcg_gen_addi_i64(o->addr1, o->addr1, 2);
3594 }
3595 }
3596 if (l) {
3597 tcg_gen_qemu_st8(o->in2, o->addr1, get_mem_index(s));
3598 }
3599 gen_op_movi_cc(s, 0);
3600 return NO_EXIT;
3601 }
3602
3603 /* But in general we'll defer to a helper. */
3604 o->in2 = get_address(s, 0, b2, d2);
3605 t32 = tcg_const_i32(l);
3606 potential_page_fault(s);
3607 gen_helper_xc(cc_op, cpu_env, t32, o->addr1, o->in2);
3608 tcg_temp_free_i32(t32);
3609 set_cc_static(s);
3610 return NO_EXIT;
3611 }
3612
3613 static ExitStatus op_xor(DisasContext *s, DisasOps *o)
3614 {
3615 tcg_gen_xor_i64(o->out, o->in1, o->in2);
3616 return NO_EXIT;
3617 }
3618
3619 static ExitStatus op_xori(DisasContext *s, DisasOps *o)
3620 {
3621 int shift = s->insn->data & 0xff;
3622 int size = s->insn->data >> 8;
3623 uint64_t mask = ((1ull << size) - 1) << shift;
3624
3625 assert(!o->g_in2);
3626 tcg_gen_shli_i64(o->in2, o->in2, shift);
3627 tcg_gen_xor_i64(o->out, o->in1, o->in2);
3628
3629 /* Produce the CC from only the bits manipulated. */
3630 tcg_gen_andi_i64(cc_dst, o->out, mask);
3631 set_cc_nz_u64(s, cc_dst);
3632 return NO_EXIT;
3633 }
3634
3635 static ExitStatus op_zero(DisasContext *s, DisasOps *o)
3636 {
3637 o->out = tcg_const_i64(0);
3638 return NO_EXIT;
3639 }
3640
3641 static ExitStatus op_zero2(DisasContext *s, DisasOps *o)
3642 {
3643 o->out = tcg_const_i64(0);
3644 o->out2 = o->out;
3645 o->g_out2 = true;
3646 return NO_EXIT;
3647 }
3648
3649 /* ====================================================================== */
3650 /* The "Cc OUTput" generators. Given the generated output (and in some cases
3651 the original inputs), update the various cc data structures in order to
3652 be able to compute the new condition code. */
3653
3654 static void cout_abs32(DisasContext *s, DisasOps *o)
3655 {
3656 gen_op_update1_cc_i64(s, CC_OP_ABS_32, o->out);
3657 }
3658
3659 static void cout_abs64(DisasContext *s, DisasOps *o)
3660 {
3661 gen_op_update1_cc_i64(s, CC_OP_ABS_64, o->out);
3662 }
3663
3664 static void cout_adds32(DisasContext *s, DisasOps *o)
3665 {
3666 gen_op_update3_cc_i64(s, CC_OP_ADD_32, o->in1, o->in2, o->out);
3667 }
3668
3669 static void cout_adds64(DisasContext *s, DisasOps *o)
3670 {
3671 gen_op_update3_cc_i64(s, CC_OP_ADD_64, o->in1, o->in2, o->out);
3672 }
3673
3674 static void cout_addu32(DisasContext *s, DisasOps *o)
3675 {
3676 gen_op_update3_cc_i64(s, CC_OP_ADDU_32, o->in1, o->in2, o->out);
3677 }
3678
3679 static void cout_addu64(DisasContext *s, DisasOps *o)
3680 {
3681 gen_op_update3_cc_i64(s, CC_OP_ADDU_64, o->in1, o->in2, o->out);
3682 }
3683
3684 static void cout_addc32(DisasContext *s, DisasOps *o)
3685 {
3686 gen_op_update3_cc_i64(s, CC_OP_ADDC_32, o->in1, o->in2, o->out);
3687 }
3688
3689 static void cout_addc64(DisasContext *s, DisasOps *o)
3690 {
3691 gen_op_update3_cc_i64(s, CC_OP_ADDC_64, o->in1, o->in2, o->out);
3692 }
3693
3694 static void cout_cmps32(DisasContext *s, DisasOps *o)
3695 {
3696 gen_op_update2_cc_i64(s, CC_OP_LTGT_32, o->in1, o->in2);
3697 }
3698
3699 static void cout_cmps64(DisasContext *s, DisasOps *o)
3700 {
3701 gen_op_update2_cc_i64(s, CC_OP_LTGT_64, o->in1, o->in2);
3702 }
3703
3704 static void cout_cmpu32(DisasContext *s, DisasOps *o)
3705 {
3706 gen_op_update2_cc_i64(s, CC_OP_LTUGTU_32, o->in1, o->in2);
3707 }
3708
3709 static void cout_cmpu64(DisasContext *s, DisasOps *o)
3710 {
3711 gen_op_update2_cc_i64(s, CC_OP_LTUGTU_64, o->in1, o->in2);
3712 }
3713
3714 static void cout_f32(DisasContext *s, DisasOps *o)
3715 {
3716 gen_op_update1_cc_i64(s, CC_OP_NZ_F32, o->out);
3717 }
3718
3719 static void cout_f64(DisasContext *s, DisasOps *o)
3720 {
3721 gen_op_update1_cc_i64(s, CC_OP_NZ_F64, o->out);
3722 }
3723
3724 static void cout_f128(DisasContext *s, DisasOps *o)
3725 {
3726 gen_op_update2_cc_i64(s, CC_OP_NZ_F128, o->out, o->out2);
3727 }
3728
3729 static void cout_nabs32(DisasContext *s, DisasOps *o)
3730 {
3731 gen_op_update1_cc_i64(s, CC_OP_NABS_32, o->out);
3732 }
3733
3734 static void cout_nabs64(DisasContext *s, DisasOps *o)
3735 {
3736 gen_op_update1_cc_i64(s, CC_OP_NABS_64, o->out);
3737 }
3738
3739 static void cout_neg32(DisasContext *s, DisasOps *o)
3740 {
3741 gen_op_update1_cc_i64(s, CC_OP_COMP_32, o->out);
3742 }
3743
3744 static void cout_neg64(DisasContext *s, DisasOps *o)
3745 {
3746 gen_op_update1_cc_i64(s, CC_OP_COMP_64, o->out);
3747 }
3748
3749 static void cout_nz32(DisasContext *s, DisasOps *o)
3750 {
3751 tcg_gen_ext32u_i64(cc_dst, o->out);
3752 gen_op_update1_cc_i64(s, CC_OP_NZ, cc_dst);
3753 }
3754
3755 static void cout_nz64(DisasContext *s, DisasOps *o)
3756 {
3757 gen_op_update1_cc_i64(s, CC_OP_NZ, o->out);
3758 }
3759
3760 static void cout_s32(DisasContext *s, DisasOps *o)
3761 {
3762 gen_op_update1_cc_i64(s, CC_OP_LTGT0_32, o->out);
3763 }
3764
3765 static void cout_s64(DisasContext *s, DisasOps *o)
3766 {
3767 gen_op_update1_cc_i64(s, CC_OP_LTGT0_64, o->out);
3768 }
3769
3770 static void cout_subs32(DisasContext *s, DisasOps *o)
3771 {
3772 gen_op_update3_cc_i64(s, CC_OP_SUB_32, o->in1, o->in2, o->out);
3773 }
3774
3775 static void cout_subs64(DisasContext *s, DisasOps *o)
3776 {
3777 gen_op_update3_cc_i64(s, CC_OP_SUB_64, o->in1, o->in2, o->out);
3778 }
3779
3780 static void cout_subu32(DisasContext *s, DisasOps *o)
3781 {
3782 gen_op_update3_cc_i64(s, CC_OP_SUBU_32, o->in1, o->in2, o->out);
3783 }
3784
3785 static void cout_subu64(DisasContext *s, DisasOps *o)
3786 {
3787 gen_op_update3_cc_i64(s, CC_OP_SUBU_64, o->in1, o->in2, o->out);
3788 }
3789
3790 static void cout_subb32(DisasContext *s, DisasOps *o)
3791 {
3792 gen_op_update3_cc_i64(s, CC_OP_SUBB_32, o->in1, o->in2, o->out);
3793 }
3794
3795 static void cout_subb64(DisasContext *s, DisasOps *o)
3796 {
3797 gen_op_update3_cc_i64(s, CC_OP_SUBB_64, o->in1, o->in2, o->out);
3798 }
3799
3800 static void cout_tm32(DisasContext *s, DisasOps *o)
3801 {
3802 gen_op_update2_cc_i64(s, CC_OP_TM_32, o->in1, o->in2);
3803 }
3804
3805 static void cout_tm64(DisasContext *s, DisasOps *o)
3806 {
3807 gen_op_update2_cc_i64(s, CC_OP_TM_64, o->in1, o->in2);
3808 }
3809
3810 /* ====================================================================== */
3811 /* The "PREParation" generators. These initialize the DisasOps.OUT fields
3812 with the TCG register to which we will write. Used in combination with
3813 the "wout" generators, in some cases we need a new temporary, and in
3814 some cases we can write to a TCG global. */
3815
3816 static void prep_new(DisasContext *s, DisasFields *f, DisasOps *o)
3817 {
3818 o->out = tcg_temp_new_i64();
3819 }
3820 #define SPEC_prep_new 0
3821
3822 static void prep_new_P(DisasContext *s, DisasFields *f, DisasOps *o)
3823 {
3824 o->out = tcg_temp_new_i64();
3825 o->out2 = tcg_temp_new_i64();
3826 }
3827 #define SPEC_prep_new_P 0
3828
3829 static void prep_r1(DisasContext *s, DisasFields *f, DisasOps *o)
3830 {
3831 o->out = regs[get_field(f, r1)];
3832 o->g_out = true;
3833 }
3834 #define SPEC_prep_r1 0
3835
3836 static void prep_r1_P(DisasContext *s, DisasFields *f, DisasOps *o)
3837 {
3838 int r1 = get_field(f, r1);
3839 o->out = regs[r1];
3840 o->out2 = regs[r1 + 1];
3841 o->g_out = o->g_out2 = true;
3842 }
3843 #define SPEC_prep_r1_P SPEC_r1_even
3844
3845 static void prep_f1(DisasContext *s, DisasFields *f, DisasOps *o)
3846 {
3847 o->out = fregs[get_field(f, r1)];
3848 o->g_out = true;
3849 }
3850 #define SPEC_prep_f1 0
3851
3852 static void prep_x1(DisasContext *s, DisasFields *f, DisasOps *o)
3853 {
3854 int r1 = get_field(f, r1);
3855 o->out = fregs[r1];
3856 o->out2 = fregs[r1 + 2];
3857 o->g_out = o->g_out2 = true;
3858 }
3859 #define SPEC_prep_x1 SPEC_r1_f128
3860
3861 /* ====================================================================== */
3862 /* The "Write OUTput" generators. These generally perform some non-trivial
3863 copy of data to TCG globals, or to main memory. The trivial cases are
3864 generally handled by having a "prep" generator install the TCG global
3865 as the destination of the operation. */
3866
3867 static void wout_r1(DisasContext *s, DisasFields *f, DisasOps *o)
3868 {
3869 store_reg(get_field(f, r1), o->out);
3870 }
3871 #define SPEC_wout_r1 0
3872
3873 static void wout_r1_8(DisasContext *s, DisasFields *f, DisasOps *o)
3874 {
3875 int r1 = get_field(f, r1);
3876 tcg_gen_deposit_i64(regs[r1], regs[r1], o->out, 0, 8);
3877 }
3878 #define SPEC_wout_r1_8 0
3879
3880 static void wout_r1_16(DisasContext *s, DisasFields *f, DisasOps *o)
3881 {
3882 int r1 = get_field(f, r1);
3883 tcg_gen_deposit_i64(regs[r1], regs[r1], o->out, 0, 16);
3884 }
3885 #define SPEC_wout_r1_16 0
3886
3887 static void wout_r1_32(DisasContext *s, DisasFields *f, DisasOps *o)
3888 {
3889 store_reg32_i64(get_field(f, r1), o->out);
3890 }
3891 #define SPEC_wout_r1_32 0
3892
3893 static void wout_r1_P32(DisasContext *s, DisasFields *f, DisasOps *o)
3894 {
3895 int r1 = get_field(f, r1);
3896 store_reg32_i64(r1, o->out);
3897 store_reg32_i64(r1 + 1, o->out2);
3898 }
3899 #define SPEC_wout_r1_P32 SPEC_r1_even
3900
3901 static void wout_r1_D32(DisasContext *s, DisasFields *f, DisasOps *o)
3902 {
3903 int r1 = get_field(f, r1);
3904 store_reg32_i64(r1 + 1, o->out);
3905 tcg_gen_shri_i64(o->out, o->out, 32);
3906 store_reg32_i64(r1, o->out);
3907 }
3908 #define SPEC_wout_r1_D32 SPEC_r1_even
3909
3910 static void wout_e1(DisasContext *s, DisasFields *f, DisasOps *o)
3911 {
3912 store_freg32_i64(get_field(f, r1), o->out);
3913 }
3914 #define SPEC_wout_e1 0
3915
3916 static void wout_f1(DisasContext *s, DisasFields *f, DisasOps *o)
3917 {
3918 store_freg(get_field(f, r1), o->out);
3919 }
3920 #define SPEC_wout_f1 0
3921
3922 static void wout_x1(DisasContext *s, DisasFields *f, DisasOps *o)
3923 {
3924 int f1 = get_field(s->fields, r1);
3925 store_freg(f1, o->out);
3926 store_freg(f1 + 2, o->out2);
3927 }
3928 #define SPEC_wout_x1 SPEC_r1_f128
3929
3930 static void wout_cond_r1r2_32(DisasContext *s, DisasFields *f, DisasOps *o)
3931 {
3932 if (get_field(f, r1) != get_field(f, r2)) {
3933 store_reg32_i64(get_field(f, r1), o->out);
3934 }
3935 }
3936 #define SPEC_wout_cond_r1r2_32 0
3937
3938 static void wout_cond_e1e2(DisasContext *s, DisasFields *f, DisasOps *o)
3939 {
3940 if (get_field(f, r1) != get_field(f, r2)) {
3941 store_freg32_i64(get_field(f, r1), o->out);
3942 }
3943 }
3944 #define SPEC_wout_cond_e1e2 0
3945
3946 static void wout_m1_8(DisasContext *s, DisasFields *f, DisasOps *o)
3947 {
3948 tcg_gen_qemu_st8(o->out, o->addr1, get_mem_index(s));
3949 }
3950 #define SPEC_wout_m1_8 0
3951
3952 static void wout_m1_16(DisasContext *s, DisasFields *f, DisasOps *o)
3953 {
3954 tcg_gen_qemu_st16(o->out, o->addr1, get_mem_index(s));
3955 }
3956 #define SPEC_wout_m1_16 0
3957
3958 static void wout_m1_32(DisasContext *s, DisasFields *f, DisasOps *o)
3959 {
3960 tcg_gen_qemu_st32(o->out, o->addr1, get_mem_index(s));
3961 }
3962 #define SPEC_wout_m1_32 0
3963
3964 static void wout_m1_64(DisasContext *s, DisasFields *f, DisasOps *o)
3965 {
3966 tcg_gen_qemu_st64(o->out, o->addr1, get_mem_index(s));
3967 }
3968 #define SPEC_wout_m1_64 0
3969
3970 static void wout_m2_32(DisasContext *s, DisasFields *f, DisasOps *o)
3971 {
3972 tcg_gen_qemu_st32(o->out, o->in2, get_mem_index(s));
3973 }
3974 #define SPEC_wout_m2_32 0
3975
3976 /* ====================================================================== */
3977 /* The "INput 1" generators. These load the first operand to an insn. */
3978
3979 static void in1_r1(DisasContext *s, DisasFields *f, DisasOps *o)
3980 {
3981 o->in1 = load_reg(get_field(f, r1));
3982 }
3983 #define SPEC_in1_r1 0
3984
3985 static void in1_r1_o(DisasContext *s, DisasFields *f, DisasOps *o)
3986 {
3987 o->in1 = regs[get_field(f, r1)];
3988 o->g_in1 = true;
3989 }
3990 #define SPEC_in1_r1_o 0
3991
3992 static void in1_r1_32s(DisasContext *s, DisasFields *f, DisasOps *o)
3993 {
3994 o->in1 = tcg_temp_new_i64();
3995 tcg_gen_ext32s_i64(o->in1, regs[get_field(f, r1)]);
3996 }
3997 #define SPEC_in1_r1_32s 0
3998
3999 static void in1_r1_32u(DisasContext *s, DisasFields *f, DisasOps *o)
4000 {
4001 o->in1 = tcg_temp_new_i64();
4002 tcg_gen_ext32u_i64(o->in1, regs[get_field(f, r1)]);
4003 }
4004 #define SPEC_in1_r1_32u 0
4005
4006 static void in1_r1_sr32(DisasContext *s, DisasFields *f, DisasOps *o)
4007 {
4008 o->in1 = tcg_temp_new_i64();
4009 tcg_gen_shri_i64(o->in1, regs[get_field(f, r1)], 32);
4010 }
4011 #define SPEC_in1_r1_sr32 0
4012
4013 static void in1_r1p1(DisasContext *s, DisasFields *f, DisasOps *o)
4014 {
4015 o->in1 = load_reg(get_field(f, r1) + 1);
4016 }
4017 #define SPEC_in1_r1p1 SPEC_r1_even
4018
4019 static void in1_r1p1_32s(DisasContext *s, DisasFields *f, DisasOps *o)
4020 {
4021 o->in1 = tcg_temp_new_i64();
4022 tcg_gen_ext32s_i64(o->in1, regs[get_field(f, r1) + 1]);
4023 }
4024 #define SPEC_in1_r1p1_32s SPEC_r1_even
4025
4026 static void in1_r1p1_32u(DisasContext *s, DisasFields *f, DisasOps *o)
4027 {
4028 o->in1 = tcg_temp_new_i64();
4029 tcg_gen_ext32u_i64(o->in1, regs[get_field(f, r1) + 1]);
4030 }
4031 #define SPEC_in1_r1p1_32u SPEC_r1_even
4032
4033 static void in1_r1_D32(DisasContext *s, DisasFields *f, DisasOps *o)
4034 {
4035 int r1 = get_field(f, r1);
4036 o->in1 = tcg_temp_new_i64();
4037 tcg_gen_concat32_i64(o->in1, regs[r1 + 1], regs[r1]);
4038 }
4039 #define SPEC_in1_r1_D32 SPEC_r1_even
4040
4041 static void in1_r2(DisasContext *s, DisasFields *f, DisasOps *o)
4042 {
4043 o->in1 = load_reg(get_field(f, r2));
4044 }
4045 #define SPEC_in1_r2 0
4046
4047 static void in1_r3(DisasContext *s, DisasFields *f, DisasOps *o)
4048 {
4049 o->in1 = load_reg(get_field(f, r3));
4050 }
4051 #define SPEC_in1_r3 0
4052
4053 static void in1_r3_o(DisasContext *s, DisasFields *f, DisasOps *o)
4054 {
4055 o->in1 = regs[get_field(f, r3)];
4056 o->g_in1 = true;
4057 }
4058 #define SPEC_in1_r3_o 0
4059
4060 static void in1_r3_32s(DisasContext *s, DisasFields *f, DisasOps *o)
4061 {
4062 o->in1 = tcg_temp_new_i64();
4063 tcg_gen_ext32s_i64(o->in1, regs[get_field(f, r3)]);
4064 }
4065 #define SPEC_in1_r3_32s 0
4066
4067 static void in1_r3_32u(DisasContext *s, DisasFields *f, DisasOps *o)
4068 {
4069 o->in1 = tcg_temp_new_i64();
4070 tcg_gen_ext32u_i64(o->in1, regs[get_field(f, r3)]);
4071 }
4072 #define SPEC_in1_r3_32u 0
4073
4074 static void in1_r3_D32(DisasContext *s, DisasFields *f, DisasOps *o)
4075 {
4076 int r3 = get_field(f, r3);
4077 o->in1 = tcg_temp_new_i64();
4078 tcg_gen_concat32_i64(o->in1, regs[r3 + 1], regs[r3]);
4079 }
4080 #define SPEC_in1_r3_D32 SPEC_r3_even
4081
4082 static void in1_e1(DisasContext *s, DisasFields *f, DisasOps *o)
4083 {
4084 o->in1 = load_freg32_i64(get_field(f, r1));
4085 }
4086 #define SPEC_in1_e1 0
4087
4088 static void in1_f1_o(DisasContext *s, DisasFields *f, DisasOps *o)
4089 {
4090 o->in1 = fregs[get_field(f, r1)];
4091 o->g_in1 = true;
4092 }
4093 #define SPEC_in1_f1_o 0
4094
4095 static void in1_x1_o(DisasContext *s, DisasFields *f, DisasOps *o)
4096 {
4097 int r1 = get_field(f, r1);
4098 o->out = fregs[r1];
4099 o->out2 = fregs[r1 + 2];
4100 o->g_out = o->g_out2 = true;
4101 }
4102 #define SPEC_in1_x1_o SPEC_r1_f128
4103
4104 static void in1_f3_o(DisasContext *s, DisasFields *f, DisasOps *o)
4105 {
4106 o->in1 = fregs[get_field(f, r3)];
4107 o->g_in1 = true;
4108 }
4109 #define SPEC_in1_f3_o 0
4110
4111 static void in1_la1(DisasContext *s, DisasFields *f, DisasOps *o)
4112 {
4113 o->addr1 = get_address(s, 0, get_field(f, b1), get_field(f, d1));
4114 }
4115 #define SPEC_in1_la1 0
4116
4117 static void in1_la2(DisasContext *s, DisasFields *f, DisasOps *o)
4118 {
4119 int x2 = have_field(f, x2) ? get_field(f, x2) : 0;
4120 o->addr1 = get_address(s, x2, get_field(f, b2), get_field(f, d2));
4121 }
4122 #define SPEC_in1_la2 0
4123
4124 static void in1_m1_8u(DisasContext *s, DisasFields *f, DisasOps *o)
4125 {
4126 in1_la1(s, f, o);
4127 o->in1 = tcg_temp_new_i64();
4128 tcg_gen_qemu_ld8u(o->in1, o->addr1, get_mem_index(s));
4129 }
4130 #define SPEC_in1_m1_8u 0
4131
4132 static void in1_m1_16s(DisasContext *s, DisasFields *f, DisasOps *o)
4133 {
4134 in1_la1(s, f, o);
4135 o->in1 = tcg_temp_new_i64();
4136 tcg_gen_qemu_ld16s(o->in1, o->addr1, get_mem_index(s));
4137 }
4138 #define SPEC_in1_m1_16s 0
4139
4140 static void in1_m1_16u(DisasContext *s, DisasFields *f, DisasOps *o)
4141 {
4142 in1_la1(s, f, o);
4143 o->in1 = tcg_temp_new_i64();
4144 tcg_gen_qemu_ld16u(o->in1, o->addr1, get_mem_index(s));
4145 }
4146 #define SPEC_in1_m1_16u 0
4147
4148 static void in1_m1_32s(DisasContext *s, DisasFields *f, DisasOps *o)
4149 {
4150 in1_la1(s, f, o);
4151 o->in1 = tcg_temp_new_i64();
4152 tcg_gen_qemu_ld32s(o->in1, o->addr1, get_mem_index(s));
4153 }
4154 #define SPEC_in1_m1_32s 0
4155
4156 static void in1_m1_32u(DisasContext *s, DisasFields *f, DisasOps *o)
4157 {
4158 in1_la1(s, f, o);
4159 o->in1 = tcg_temp_new_i64();
4160 tcg_gen_qemu_ld32u(o->in1, o->addr1, get_mem_index(s));
4161 }
4162 #define SPEC_in1_m1_32u 0
4163
4164 static void in1_m1_64(DisasContext *s, DisasFields *f, DisasOps *o)
4165 {
4166 in1_la1(s, f, o);
4167 o->in1 = tcg_temp_new_i64();
4168 tcg_gen_qemu_ld64(o->in1, o->addr1, get_mem_index(s));
4169 }
4170 #define SPEC_in1_m1_64 0
4171
4172 /* ====================================================================== */
4173 /* The "INput 2" generators. These load the second operand to an insn. */
4174
4175 static void in2_r1_o(DisasContext *s, DisasFields *f, DisasOps *o)
4176 {
4177 o->in2 = regs[get_field(f, r1)];
4178 o->g_in2 = true;
4179 }
4180 #define SPEC_in2_r1_o 0
4181
4182 static void in2_r1_16u(DisasContext *s, DisasFields *f, DisasOps *o)
4183 {
4184 o->in2 = tcg_temp_new_i64();
4185 tcg_gen_ext16u_i64(o->in2, regs[get_field(f, r1)]);
4186 }
4187 #define SPEC_in2_r1_16u 0
4188
4189 static void in2_r1_32u(DisasContext *s, DisasFields *f, DisasOps *o)
4190 {
4191 o->in2 = tcg_temp_new_i64();
4192 tcg_gen_ext32u_i64(o->in2, regs[get_field(f, r1)]);
4193 }
4194 #define SPEC_in2_r1_32u 0
4195
4196 static void in2_r1_D32(DisasContext *s, DisasFields *f, DisasOps *o)
4197 {
4198 int r1 = get_field(f, r1);
4199 o->in2 = tcg_temp_new_i64();
4200 tcg_gen_concat32_i64(o->in2, regs[r1 + 1], regs[r1]);
4201 }
4202 #define SPEC_in2_r1_D32 SPEC_r1_even
4203
4204 static void in2_r2(DisasContext *s, DisasFields *f, DisasOps *o)
4205 {
4206 o->in2 = load_reg(get_field(f, r2));
4207 }
4208 #define SPEC_in2_r2 0
4209
4210 static void in2_r2_o(DisasContext *s, DisasFields *f, DisasOps *o)
4211 {
4212 o->in2 = regs[get_field(f, r2)];
4213 o->g_in2 = true;
4214 }
4215 #define SPEC_in2_r2_o 0
4216
4217 static void in2_r2_nz(DisasContext *s, DisasFields *f, DisasOps *o)
4218 {
4219 int r2 = get_field(f, r2);
4220 if (r2 != 0) {
4221 o->in2 = load_reg(r2);
4222 }
4223 }
4224 #define SPEC_in2_r2_nz 0
4225
4226 static void in2_r2_8s(DisasContext *s, DisasFields *f, DisasOps *o)
4227 {
4228 o->in2 = tcg_temp_new_i64();
4229 tcg_gen_ext8s_i64(o->in2, regs[get_field(f, r2)]);
4230 }
4231 #define SPEC_in2_r2_8s 0
4232
4233 static void in2_r2_8u(DisasContext *s, DisasFields *f, DisasOps *o)
4234 {
4235 o->in2 = tcg_temp_new_i64();
4236 tcg_gen_ext8u_i64(o->in2, regs[get_field(f, r2)]);
4237 }
4238 #define SPEC_in2_r2_8u 0
4239
4240 static void in2_r2_16s(DisasContext *s, DisasFields *f, DisasOps *o)
4241 {
4242 o->in2 = tcg_temp_new_i64();
4243 tcg_gen_ext16s_i64(o->in2, regs[get_field(f, r2)]);
4244 }
4245 #define SPEC_in2_r2_16s 0
4246
4247 static void in2_r2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
4248 {
4249 o->in2 = tcg_temp_new_i64();
4250 tcg_gen_ext16u_i64(o->in2, regs[get_field(f, r2)]);
4251 }
4252 #define SPEC_in2_r2_16u 0
4253
4254 static void in2_r3(DisasContext *s, DisasFields *f, DisasOps *o)
4255 {
4256 o->in2 = load_reg(get_field(f, r3));
4257 }
4258 #define SPEC_in2_r3 0
4259
4260 static void in2_r2_32s(DisasContext *s, DisasFields *f, DisasOps *o)
4261 {
4262 o->in2 = tcg_temp_new_i64();
4263 tcg_gen_ext32s_i64(o->in2, regs[get_field(f, r2)]);
4264 }
4265 #define SPEC_in2_r2_32s 0
4266
4267 static void in2_r2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
4268 {
4269 o->in2 = tcg_temp_new_i64();
4270 tcg_gen_ext32u_i64(o->in2, regs[get_field(f, r2)]);
4271 }
4272 #define SPEC_in2_r2_32u 0
4273
4274 static void in2_e2(DisasContext *s, DisasFields *f, DisasOps *o)
4275 {
4276 o->in2 = load_freg32_i64(get_field(f, r2));
4277 }
4278 #define SPEC_in2_e2 0
4279
4280 static void in2_f2_o(DisasContext *s, DisasFields *f, DisasOps *o)
4281 {
4282 o->in2 = fregs[get_field(f, r2)];
4283 o->g_in2 = true;
4284 }
4285 #define SPEC_in2_f2_o 0
4286
4287 static void in2_x2_o(DisasContext *s, DisasFields *f, DisasOps *o)
4288 {
4289 int r2 = get_field(f, r2);
4290 o->in1 = fregs[r2];
4291 o->in2 = fregs[r2 + 2];
4292 o->g_in1 = o->g_in2 = true;
4293 }
4294 #define SPEC_in2_x2_o SPEC_r2_f128
4295
4296 static void in2_ra2(DisasContext *s, DisasFields *f, DisasOps *o)
4297 {
4298 o->in2 = get_address(s, 0, get_field(f, r2), 0);
4299 }
4300 #define SPEC_in2_ra2 0
4301
4302 static void in2_a2(DisasContext *s, DisasFields *f, DisasOps *o)
4303 {
4304 int x2 = have_field(f, x2) ? get_field(f, x2) : 0;
4305 o->in2 = get_address(s, x2, get_field(f, b2), get_field(f, d2));
4306 }
4307 #define SPEC_in2_a2 0
4308
4309 static void in2_ri2(DisasContext *s, DisasFields *f, DisasOps *o)
4310 {
4311 o->in2 = tcg_const_i64(s->pc + (int64_t)get_field(f, i2) * 2);
4312 }
4313 #define SPEC_in2_ri2 0
4314
4315 static void in2_sh32(DisasContext *s, DisasFields *f, DisasOps *o)
4316 {
4317 help_l2_shift(s, f, o, 31);
4318 }
4319 #define SPEC_in2_sh32 0
4320
4321 static void in2_sh64(DisasContext *s, DisasFields *f, DisasOps *o)
4322 {
4323 help_l2_shift(s, f, o, 63);
4324 }
4325 #define SPEC_in2_sh64 0
4326
4327 static void in2_m2_8u(DisasContext *s, DisasFields *f, DisasOps *o)
4328 {
4329 in2_a2(s, f, o);
4330 tcg_gen_qemu_ld8u(o->in2, o->in2, get_mem_index(s));
4331 }
4332 #define SPEC_in2_m2_8u 0
4333
4334 static void in2_m2_16s(DisasContext *s, DisasFields *f, DisasOps *o)
4335 {
4336 in2_a2(s, f, o);
4337 tcg_gen_qemu_ld16s(o->in2, o->in2, get_mem_index(s));
4338 }
4339 #define SPEC_in2_m2_16s 0
4340
4341 static void in2_m2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
4342 {
4343 in2_a2(s, f, o);
4344 tcg_gen_qemu_ld16u(o->in2, o->in2, get_mem_index(s));
4345 }
4346 #define SPEC_in2_m2_16u 0
4347
4348 static void in2_m2_32s(DisasContext *s, DisasFields *f, DisasOps *o)
4349 {
4350 in2_a2(s, f, o);
4351 tcg_gen_qemu_ld32s(o->in2, o->in2, get_mem_index(s));
4352 }
4353 #define SPEC_in2_m2_32s 0
4354
4355 static void in2_m2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
4356 {
4357 in2_a2(s, f, o);
4358 tcg_gen_qemu_ld32u(o->in2, o->in2, get_mem_index(s));
4359 }
4360 #define SPEC_in2_m2_32u 0
4361
4362 static void in2_m2_64(DisasContext *s, DisasFields *f, DisasOps *o)
4363 {
4364 in2_a2(s, f, o);
4365 tcg_gen_qemu_ld64(o->in2, o->in2, get_mem_index(s));
4366 }
4367 #define SPEC_in2_m2_64 0
4368
4369 static void in2_mri2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
4370 {
4371 in2_ri2(s, f, o);
4372 tcg_gen_qemu_ld16u(o->in2, o->in2, get_mem_index(s));
4373 }
4374 #define SPEC_in2_mri2_16u 0
4375
4376 static void in2_mri2_32s(DisasContext *s, DisasFields *f, DisasOps *o)
4377 {
4378 in2_ri2(s, f, o);
4379 tcg_gen_qemu_ld32s(o->in2, o->in2, get_mem_index(s));
4380 }
4381 #define SPEC_in2_mri2_32s 0
4382
4383 static void in2_mri2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
4384 {
4385 in2_ri2(s, f, o);
4386 tcg_gen_qemu_ld32u(o->in2, o->in2, get_mem_index(s));
4387 }
4388 #define SPEC_in2_mri2_32u 0
4389
4390 static void in2_mri2_64(DisasContext *s, DisasFields *f, DisasOps *o)
4391 {
4392 in2_ri2(s, f, o);
4393 tcg_gen_qemu_ld64(o->in2, o->in2, get_mem_index(s));
4394 }
4395 #define SPEC_in2_mri2_64 0
4396
4397 static void in2_i2(DisasContext *s, DisasFields *f, DisasOps *o)
4398 {
4399 o->in2 = tcg_const_i64(get_field(f, i2));
4400 }
4401 #define SPEC_in2_i2 0
4402
4403 static void in2_i2_8u(DisasContext *s, DisasFields *f, DisasOps *o)
4404 {
4405 o->in2 = tcg_const_i64((uint8_t)get_field(f, i2));
4406 }
4407 #define SPEC_in2_i2_8u 0
4408
4409 static void in2_i2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
4410 {
4411 o->in2 = tcg_const_i64((uint16_t)get_field(f, i2));
4412 }
4413 #define SPEC_in2_i2_16u 0
4414
4415 static void in2_i2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
4416 {
4417 o->in2 = tcg_const_i64((uint32_t)get_field(f, i2));
4418 }
4419 #define SPEC_in2_i2_32u 0
4420
4421 static void in2_i2_16u_shl(DisasContext *s, DisasFields *f, DisasOps *o)
4422 {
4423 uint64_t i2 = (uint16_t)get_field(f, i2);
4424 o->in2 = tcg_const_i64(i2 << s->insn->data);
4425 }
4426 #define SPEC_in2_i2_16u_shl 0
4427
4428 static void in2_i2_32u_shl(DisasContext *s, DisasFields *f, DisasOps *o)
4429 {
4430 uint64_t i2 = (uint32_t)get_field(f, i2);
4431 o->in2 = tcg_const_i64(i2 << s->insn->data);
4432 }
4433 #define SPEC_in2_i2_32u_shl 0
4434
4435 /* ====================================================================== */
4436
4437 /* Find opc within the table of insns. This is formulated as a switch
4438 statement so that (1) we get compile-time notice of cut-paste errors
4439 for duplicated opcodes, and (2) the compiler generates the binary
4440 search tree, rather than us having to post-process the table. */
4441
4442 #define C(OPC, NM, FT, FC, I1, I2, P, W, OP, CC) \
4443 D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, 0)
4444
4445 #define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) insn_ ## NM,
4446
4447 enum DisasInsnEnum {
4448 #include "insn-data.def"
4449 };
4450
4451 #undef D
4452 #define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) { \
4453 .opc = OPC, \
4454 .fmt = FMT_##FT, \
4455 .fac = FAC_##FC, \
4456 .spec = SPEC_in1_##I1 | SPEC_in2_##I2 | SPEC_prep_##P | SPEC_wout_##W, \
4457 .name = #NM, \
4458 .help_in1 = in1_##I1, \
4459 .help_in2 = in2_##I2, \
4460 .help_prep = prep_##P, \
4461 .help_wout = wout_##W, \
4462 .help_cout = cout_##CC, \
4463 .help_op = op_##OP, \
4464 .data = D \
4465 },
4466
4467 /* Allow 0 to be used for NULL in the table below. */
4468 #define in1_0 NULL
4469 #define in2_0 NULL
4470 #define prep_0 NULL
4471 #define wout_0 NULL
4472 #define cout_0 NULL
4473 #define op_0 NULL
4474
4475 #define SPEC_in1_0 0
4476 #define SPEC_in2_0 0
4477 #define SPEC_prep_0 0
4478 #define SPEC_wout_0 0
4479
4480 static const DisasInsn insn_info[] = {
4481 #include "insn-data.def"
4482 };
4483
4484 #undef D
4485 #define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) \
4486 case OPC: return &insn_info[insn_ ## NM];
4487
4488 static const DisasInsn *lookup_opc(uint16_t opc)
4489 {
4490 switch (opc) {
4491 #include "insn-data.def"
4492 default:
4493 return NULL;
4494 }
4495 }
4496
4497 #undef D
4498 #undef C
4499
4500 /* Extract a field from the insn. The INSN should be left-aligned in
4501 the uint64_t so that we can more easily utilize the big-bit-endian
4502 definitions we extract from the Principals of Operation. */
4503
4504 static void extract_field(DisasFields *o, const DisasField *f, uint64_t insn)
4505 {
4506 uint32_t r, m;
4507
4508 if (f->size == 0) {
4509 return;
4510 }
4511
4512 /* Zero extract the field from the insn. */
4513 r = (insn << f->beg) >> (64 - f->size);
4514
4515 /* Sign-extend, or un-swap the field as necessary. */
4516 switch (f->type) {
4517 case 0: /* unsigned */
4518 break;
4519 case 1: /* signed */
4520 assert(f->size <= 32);
4521 m = 1u << (f->size - 1);
4522 r = (r ^ m) - m;
4523 break;
4524 case 2: /* dl+dh split, signed 20 bit. */
4525 r = ((int8_t)r << 12) | (r >> 8);
4526 break;
4527 default:
4528 abort();
4529 }
4530
4531 /* Validate that the "compressed" encoding we selected above is valid.
4532 I.e. we havn't make two different original fields overlap. */
4533 assert(((o->presentC >> f->indexC) & 1) == 0);
4534 o->presentC |= 1 << f->indexC;
4535 o->presentO |= 1 << f->indexO;
4536
4537 o->c[f->indexC] = r;
4538 }
4539
4540 /* Lookup the insn at the current PC, extracting the operands into O and
4541 returning the info struct for the insn. Returns NULL for invalid insn. */
4542
4543 static const DisasInsn *extract_insn(CPUS390XState *env, DisasContext *s,
4544 DisasFields *f)
4545 {
4546 uint64_t insn, pc = s->pc;
4547 int op, op2, ilen;
4548 const DisasInsn *info;
4549
4550 insn = ld_code2(env, pc);
4551 op = (insn >> 8) & 0xff;
4552 ilen = get_ilen(op);
4553 s->next_pc = s->pc + ilen;
4554
4555 switch (ilen) {
4556 case 2:
4557 insn = insn << 48;
4558 break;
4559 case 4:
4560 insn = ld_code4(env, pc) << 32;
4561 break;
4562 case 6:
4563 insn = (insn << 48) | (ld_code4(env, pc + 2) << 16);
4564 break;
4565 default:
4566 abort();
4567 }
4568
4569 /* We can't actually determine the insn format until we've looked up
4570 the full insn opcode. Which we can't do without locating the
4571 secondary opcode. Assume by default that OP2 is at bit 40; for
4572 those smaller insns that don't actually have a secondary opcode
4573 this will correctly result in OP2 = 0. */
4574 switch (op) {
4575 case 0x01: /* E */
4576 case 0x80: /* S */
4577 case 0x82: /* S */
4578 case 0x93: /* S */
4579 case 0xb2: /* S, RRF, RRE */
4580 case 0xb3: /* RRE, RRD, RRF */
4581 case 0xb9: /* RRE, RRF */
4582 case 0xe5: /* SSE, SIL */
4583 op2 = (insn << 8) >> 56;
4584 break;
4585 case 0xa5: /* RI */
4586 case 0xa7: /* RI */
4587 case 0xc0: /* RIL */
4588 case 0xc2: /* RIL */
4589 case 0xc4: /* RIL */
4590 case 0xc6: /* RIL */
4591 case 0xc8: /* SSF */
4592 case 0xcc: /* RIL */
4593 op2 = (insn << 12) >> 60;
4594 break;
4595 case 0xd0 ... 0xdf: /* SS */
4596 case 0xe1: /* SS */
4597 case 0xe2: /* SS */
4598 case 0xe8: /* SS */
4599 case 0xe9: /* SS */
4600 case 0xea: /* SS */
4601 case 0xee ... 0xf3: /* SS */
4602 case 0xf8 ... 0xfd: /* SS */
4603 op2 = 0;
4604 break;
4605 default:
4606 op2 = (insn << 40) >> 56;
4607 break;
4608 }
4609
4610 memset(f, 0, sizeof(*f));
4611 f->op = op;
4612 f->op2 = op2;
4613
4614 /* Lookup the instruction. */
4615 info = lookup_opc(op << 8 | op2);
4616
4617 /* If we found it, extract the operands. */
4618 if (info != NULL) {
4619 DisasFormat fmt = info->fmt;
4620 int i;
4621
4622 for (i = 0; i < NUM_C_FIELD; ++i) {
4623 extract_field(f, &format_info[fmt].op[i], insn);
4624 }
4625 }
4626 return info;
4627 }
4628
4629 static ExitStatus translate_one(CPUS390XState *env, DisasContext *s)
4630 {
4631 const DisasInsn *insn;
4632 ExitStatus ret = NO_EXIT;
4633 DisasFields f;
4634 DisasOps o;
4635
4636 /* Search for the insn in the table. */
4637 insn = extract_insn(env, s, &f);
4638
4639 /* Not found means unimplemented/illegal opcode. */
4640 if (insn == NULL) {
4641 qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%02x%02x\n",
4642 f.op, f.op2);
4643 gen_illegal_opcode(s);
4644 return EXIT_NORETURN;
4645 }
4646
4647 /* Check for insn specification exceptions. */
4648 if (insn->spec) {
4649 int spec = insn->spec, excp = 0, r;
4650
4651 if (spec & SPEC_r1_even) {
4652 r = get_field(&f, r1);
4653 if (r & 1) {
4654 excp = PGM_SPECIFICATION;
4655 }
4656 }
4657 if (spec & SPEC_r2_even) {
4658 r = get_field(&f, r2);
4659 if (r & 1) {
4660 excp = PGM_SPECIFICATION;
4661 }
4662 }
4663 if (spec & SPEC_r3_even) {
4664 r = get_field(&f, r3);
4665 if (r & 1) {
4666 excp = PGM_SPECIFICATION;
4667 }
4668 }
4669 if (spec & SPEC_r1_f128) {
4670 r = get_field(&f, r1);
4671 if (r > 13) {
4672 excp = PGM_SPECIFICATION;
4673 }
4674 }
4675 if (spec & SPEC_r2_f128) {
4676 r = get_field(&f, r2);
4677 if (r > 13) {
4678 excp = PGM_SPECIFICATION;
4679 }
4680 }
4681 if (excp) {
4682 gen_program_exception(s, excp);
4683 return EXIT_NORETURN;
4684 }
4685 }
4686
4687 /* Set up the strutures we use to communicate with the helpers. */
4688 s->insn = insn;
4689 s->fields = &f;
4690 o.g_out = o.g_out2 = o.g_in1 = o.g_in2 = false;
4691 TCGV_UNUSED_I64(o.out);
4692 TCGV_UNUSED_I64(o.out2);
4693 TCGV_UNUSED_I64(o.in1);
4694 TCGV_UNUSED_I64(o.in2);
4695 TCGV_UNUSED_I64(o.addr1);
4696
4697 /* Implement the instruction. */
4698 if (insn->help_in1) {
4699 insn->help_in1(s, &f, &o);
4700 }
4701 if (insn->help_in2) {
4702 insn->help_in2(s, &f, &o);
4703 }
4704 if (insn->help_prep) {
4705 insn->help_prep(s, &f, &o);
4706 }
4707 if (insn->help_op) {
4708 ret = insn->help_op(s, &o);
4709 }
4710 if (insn->help_wout) {
4711 insn->help_wout(s, &f, &o);
4712 }
4713 if (insn->help_cout) {
4714 insn->help_cout(s, &o);
4715 }
4716
4717 /* Free any temporaries created by the helpers. */
4718 if (!TCGV_IS_UNUSED_I64(o.out) && !o.g_out) {
4719 tcg_temp_free_i64(o.out);
4720 }
4721 if (!TCGV_IS_UNUSED_I64(o.out2) && !o.g_out2) {
4722 tcg_temp_free_i64(o.out2);
4723 }
4724 if (!TCGV_IS_UNUSED_I64(o.in1) && !o.g_in1) {
4725 tcg_temp_free_i64(o.in1);
4726 }
4727 if (!TCGV_IS_UNUSED_I64(o.in2) && !o.g_in2) {
4728 tcg_temp_free_i64(o.in2);
4729 }
4730 if (!TCGV_IS_UNUSED_I64(o.addr1)) {
4731 tcg_temp_free_i64(o.addr1);
4732 }
4733
4734 /* Advance to the next instruction. */
4735 s->pc = s->next_pc;
4736 return ret;
4737 }
4738
4739 static inline void gen_intermediate_code_internal(S390CPU *cpu,
4740 TranslationBlock *tb,
4741 bool search_pc)
4742 {
4743 CPUS390XState *env = &cpu->env;
4744 DisasContext dc;
4745 target_ulong pc_start;
4746 uint64_t next_page_start;
4747 uint16_t *gen_opc_end;
4748 int j, lj = -1;
4749 int num_insns, max_insns;
4750 CPUBreakpoint *bp;
4751 ExitStatus status;
4752 bool do_debug;
4753
4754 pc_start = tb->pc;
4755
4756 /* 31-bit mode */
4757 if (!(tb->flags & FLAG_MASK_64)) {
4758 pc_start &= 0x7fffffff;
4759 }
4760
4761 dc.tb = tb;
4762 dc.pc = pc_start;
4763 dc.cc_op = CC_OP_DYNAMIC;
4764 do_debug = dc.singlestep_enabled = env->singlestep_enabled;
4765
4766 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
4767
4768 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
4769
4770 num_insns = 0;
4771 max_insns = tb->cflags & CF_COUNT_MASK;
4772 if (max_insns == 0) {
4773 max_insns = CF_COUNT_MASK;
4774 }
4775
4776 gen_tb_start();
4777
4778 do {
4779 if (search_pc) {
4780 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
4781 if (lj < j) {
4782 lj++;
4783 while (lj < j) {
4784 tcg_ctx.gen_opc_instr_start[lj++] = 0;
4785 }
4786 }
4787 tcg_ctx.gen_opc_pc[lj] = dc.pc;
4788 gen_opc_cc_op[lj] = dc.cc_op;
4789 tcg_ctx.gen_opc_instr_start[lj] = 1;
4790 tcg_ctx.gen_opc_icount[lj] = num_insns;
4791 }
4792 if (++num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
4793 gen_io_start();
4794 }
4795
4796 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
4797 tcg_gen_debug_insn_start(dc.pc);
4798 }
4799
4800 status = NO_EXIT;
4801 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
4802 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
4803 if (bp->pc == dc.pc) {
4804 status = EXIT_PC_STALE;
4805 do_debug = true;
4806 break;
4807 }
4808 }
4809 }
4810 if (status == NO_EXIT) {
4811 status = translate_one(env, &dc);
4812 }
4813
4814 /* If we reach a page boundary, are single stepping,
4815 or exhaust instruction count, stop generation. */
4816 if (status == NO_EXIT
4817 && (dc.pc >= next_page_start
4818 || tcg_ctx.gen_opc_ptr >= gen_opc_end
4819 || num_insns >= max_insns
4820 || singlestep
4821 || env->singlestep_enabled)) {
4822 status = EXIT_PC_STALE;
4823 }
4824 } while (status == NO_EXIT);
4825
4826 if (tb->cflags & CF_LAST_IO) {
4827 gen_io_end();
4828 }
4829
4830 switch (status) {
4831 case EXIT_GOTO_TB:
4832 case EXIT_NORETURN:
4833 break;
4834 case EXIT_PC_STALE:
4835 update_psw_addr(&dc);
4836 /* FALLTHRU */
4837 case EXIT_PC_UPDATED:
4838 /* Next TB starts off with CC_OP_DYNAMIC, so make sure the
4839 cc op type is in env */
4840 update_cc_op(&dc);
4841 /* Exit the TB, either by raising a debug exception or by return. */
4842 if (do_debug) {
4843 gen_exception(EXCP_DEBUG);
4844 } else {
4845 tcg_gen_exit_tb(0);
4846 }
4847 break;
4848 default:
4849 abort();
4850 }
4851
4852 gen_tb_end(tb, num_insns);
4853 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
4854 if (search_pc) {
4855 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
4856 lj++;
4857 while (lj <= j) {
4858 tcg_ctx.gen_opc_instr_start[lj++] = 0;
4859 }
4860 } else {
4861 tb->size = dc.pc - pc_start;
4862 tb->icount = num_insns;
4863 }
4864
4865 #if defined(S390X_DEBUG_DISAS)
4866 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
4867 qemu_log("IN: %s\n", lookup_symbol(pc_start));
4868 log_target_disas(env, pc_start, dc.pc - pc_start, 1);
4869 qemu_log("\n");
4870 }
4871 #endif
4872 }
4873
4874 void gen_intermediate_code (CPUS390XState *env, struct TranslationBlock *tb)
4875 {
4876 gen_intermediate_code_internal(s390_env_get_cpu(env), tb, false);
4877 }
4878
4879 void gen_intermediate_code_pc (CPUS390XState *env, struct TranslationBlock *tb)
4880 {
4881 gen_intermediate_code_internal(s390_env_get_cpu(env), tb, true);
4882 }
4883
4884 void restore_state_to_opc(CPUS390XState *env, TranslationBlock *tb, int pc_pos)
4885 {
4886 int cc_op;
4887 env->psw.addr = tcg_ctx.gen_opc_pc[pc_pos];
4888 cc_op = gen_opc_cc_op[pc_pos];
4889 if ((cc_op != CC_OP_DYNAMIC) && (cc_op != CC_OP_STATIC)) {
4890 env->cc_op = cc_op;
4891 }
4892 }