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