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