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