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