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