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