]> git.proxmox.com Git - mirror_qemu.git/blame - target/s390x/translate.c
s390x/tcg: SET CLOCK COMPARATOR can clear CKC interrupts
[mirror_qemu.git] / target / s390x / translate.c
CommitLineData
10ec5117
AG
1/*
2 * S/390 translation
3 *
4 * Copyright (c) 2009 Ulrich Hecht
e023e832 5 * Copyright (c) 2010 Alexander Graf
10ec5117
AG
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
70539e18 18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
10ec5117 19 */
e023e832 20
e023e832
AG
21/* #define DEBUG_INLINE_BRANCHES */
22#define S390X_DEBUG_DISAS
23/* #define S390X_DEBUG_DISAS_VERBOSE */
24
25#ifdef S390X_DEBUG_DISAS_VERBOSE
26# define LOG_DISAS(...) qemu_log(__VA_ARGS__)
27#else
28# define LOG_DISAS(...) do { } while (0)
29#endif
10ec5117 30
9615495a 31#include "qemu/osdep.h"
10ec5117 32#include "cpu.h"
4e58b838 33#include "internal.h"
76cad711 34#include "disas/disas.h"
63c91552 35#include "exec/exec-all.h"
10ec5117 36#include "tcg-op.h"
1de7afc9 37#include "qemu/log.h"
58a9e35b 38#include "qemu/host-utils.h"
f08b6170 39#include "exec/cpu_ldst.h"
022c62cb 40#include "exec/gen-icount.h"
2ef6175a
RH
41#include "exec/helper-proto.h"
42#include "exec/helper-gen.h"
e023e832 43
a7e30d84 44#include "trace-tcg.h"
21a8eced 45#include "exec/translator.h"
508127e2 46#include "exec/log.h"
a7e30d84 47
ad044d09
RH
48
49/* Information that (most) every instruction needs to manipulate. */
e023e832 50typedef struct DisasContext DisasContext;
ad044d09
RH
51typedef struct DisasInsn DisasInsn;
52typedef struct DisasFields DisasFields;
53
e023e832 54struct DisasContext {
eccf741a 55 DisasContextBase base;
ad044d09
RH
56 const DisasInsn *insn;
57 DisasFields *fields;
303c681a 58 uint64_t ex_value;
eccf741a
EC
59 /*
60 * During translate_one(), pc_tmp is used to determine the instruction
61 * to be executed after base.pc_next - e.g. next sequential instruction
62 * or a branch target.
63 */
64 uint64_t pc_tmp;
99e57856 65 uint32_t ilen;
ad044d09 66 enum cc_op cc_op;
c88691aa 67 bool do_debug;
e023e832
AG
68};
69
3fde06f5
RH
70/* Information carried about a condition to be evaluated. */
71typedef struct {
72 TCGCond cond:8;
73 bool is_64;
74 bool g1;
75 bool g2;
76 union {
77 struct { TCGv_i64 a, b; } s64;
78 struct { TCGv_i32 a, b; } s32;
79 } u;
80} DisasCompare;
81
e023e832
AG
82#ifdef DEBUG_INLINE_BRANCHES
83static uint64_t inline_branch_hit[CC_OP_MAX];
84static uint64_t inline_branch_miss[CC_OP_MAX];
85#endif
86
4f3adfb2 87static uint64_t pc_to_link_info(DisasContext *s, uint64_t pc)
e023e832 88{
eccf741a
EC
89 if (!(s->base.tb->flags & FLAG_MASK_64)) {
90 if (s->base.tb->flags & FLAG_MASK_32) {
e023e832
AG
91 return pc | 0x80000000;
92 }
93 }
94 return pc;
95}
96
e023e832
AG
97static TCGv_i64 psw_addr;
98static TCGv_i64 psw_mask;
3da0ab35 99static TCGv_i64 gbea;
e023e832
AG
100
101static TCGv_i32 cc_op;
102static TCGv_i64 cc_src;
103static TCGv_i64 cc_dst;
104static TCGv_i64 cc_vr;
105
431253c2 106static char cpu_reg_names[32][4];
e023e832 107static TCGv_i64 regs[16];
431253c2 108static TCGv_i64 fregs[16];
e023e832 109
d5a43964
AG
110void s390x_translate_init(void)
111{
e023e832 112 int i;
e023e832 113
e1ccc054 114 psw_addr = tcg_global_mem_new_i64(cpu_env,
431253c2 115 offsetof(CPUS390XState, psw.addr),
e023e832 116 "psw_addr");
e1ccc054 117 psw_mask = tcg_global_mem_new_i64(cpu_env,
431253c2 118 offsetof(CPUS390XState, psw.mask),
e023e832 119 "psw_mask");
e1ccc054 120 gbea = tcg_global_mem_new_i64(cpu_env,
3da0ab35
AJ
121 offsetof(CPUS390XState, gbea),
122 "gbea");
e023e832 123
e1ccc054 124 cc_op = tcg_global_mem_new_i32(cpu_env, offsetof(CPUS390XState, cc_op),
e023e832 125 "cc_op");
e1ccc054 126 cc_src = tcg_global_mem_new_i64(cpu_env, offsetof(CPUS390XState, cc_src),
e023e832 127 "cc_src");
e1ccc054 128 cc_dst = tcg_global_mem_new_i64(cpu_env, offsetof(CPUS390XState, cc_dst),
e023e832 129 "cc_dst");
e1ccc054 130 cc_vr = tcg_global_mem_new_i64(cpu_env, offsetof(CPUS390XState, cc_vr),
e023e832
AG
131 "cc_vr");
132
e023e832 133 for (i = 0; i < 16; i++) {
431253c2 134 snprintf(cpu_reg_names[i], sizeof(cpu_reg_names[0]), "r%d", i);
e1ccc054 135 regs[i] = tcg_global_mem_new(cpu_env,
431253c2
RH
136 offsetof(CPUS390XState, regs[i]),
137 cpu_reg_names[i]);
138 }
139
140 for (i = 0; i < 16; i++) {
141 snprintf(cpu_reg_names[i + 16], sizeof(cpu_reg_names[0]), "f%d", i);
e1ccc054 142 fregs[i] = tcg_global_mem_new(cpu_env,
fcb79802 143 offsetof(CPUS390XState, vregs[i][0].d),
431253c2 144 cpu_reg_names[i + 16]);
e023e832 145 }
d5a43964
AG
146}
147
4f3adfb2 148static TCGv_i64 load_reg(int reg)
10ec5117 149{
e023e832
AG
150 TCGv_i64 r = tcg_temp_new_i64();
151 tcg_gen_mov_i64(r, regs[reg]);
152 return r;
10ec5117
AG
153}
154
4f3adfb2 155static TCGv_i64 load_freg32_i64(int reg)
d764a8d1
RH
156{
157 TCGv_i64 r = tcg_temp_new_i64();
158 tcg_gen_shri_i64(r, fregs[reg], 32);
159 return r;
160}
161
4f3adfb2 162static void store_reg(int reg, TCGv_i64 v)
e023e832
AG
163{
164 tcg_gen_mov_i64(regs[reg], v);
165}
166
4f3adfb2 167static void store_freg(int reg, TCGv_i64 v)
e023e832 168{
431253c2 169 tcg_gen_mov_i64(fregs[reg], v);
e023e832
AG
170}
171
4f3adfb2 172static void store_reg32_i64(int reg, TCGv_i64 v)
e023e832
AG
173{
174 /* 32 bit register writes keep the upper half */
e023e832 175 tcg_gen_deposit_i64(regs[reg], regs[reg], v, 0, 32);
e023e832
AG
176}
177
4f3adfb2 178static void store_reg32h_i64(int reg, TCGv_i64 v)
77f8d6c3
RH
179{
180 tcg_gen_deposit_i64(regs[reg], regs[reg], v, 32, 32);
181}
182
4f3adfb2 183static void store_freg32_i64(int reg, TCGv_i64 v)
d764a8d1
RH
184{
185 tcg_gen_deposit_i64(fregs[reg], fregs[reg], v, 32, 32);
186}
187
4f3adfb2 188static void return_low128(TCGv_i64 dest)
1ac5889f
RH
189{
190 tcg_gen_ld_i64(dest, cpu_env, offsetof(CPUS390XState, retxl));
191}
192
4f3adfb2 193static void update_psw_addr(DisasContext *s)
e023e832
AG
194{
195 /* psw.addr */
eccf741a 196 tcg_gen_movi_i64(psw_addr, s->base.pc_next);
e023e832
AG
197}
198
2c2275eb
AJ
199static void per_branch(DisasContext *s, bool to_next)
200{
201#ifndef CONFIG_USER_ONLY
eccf741a 202 tcg_gen_movi_i64(gbea, s->base.pc_next);
3da0ab35 203
eccf741a
EC
204 if (s->base.tb->flags & FLAG_MASK_PER) {
205 TCGv_i64 next_pc = to_next ? tcg_const_i64(s->pc_tmp) : psw_addr;
3da0ab35 206 gen_helper_per_branch(cpu_env, gbea, next_pc);
2c2275eb
AJ
207 if (to_next) {
208 tcg_temp_free_i64(next_pc);
209 }
2c2275eb
AJ
210 }
211#endif
212}
213
214static void per_branch_cond(DisasContext *s, TCGCond cond,
215 TCGv_i64 arg1, TCGv_i64 arg2)
216{
217#ifndef CONFIG_USER_ONLY
eccf741a 218 if (s->base.tb->flags & FLAG_MASK_PER) {
2c2275eb
AJ
219 TCGLabel *lab = gen_new_label();
220 tcg_gen_brcond_i64(tcg_invert_cond(cond), arg1, arg2, lab);
221
eccf741a 222 tcg_gen_movi_i64(gbea, s->base.pc_next);
3da0ab35 223 gen_helper_per_branch(cpu_env, gbea, psw_addr);
2c2275eb
AJ
224
225 gen_set_label(lab);
3da0ab35 226 } else {
eccf741a 227 TCGv_i64 pc = tcg_const_i64(s->base.pc_next);
3da0ab35
AJ
228 tcg_gen_movcond_i64(cond, gbea, arg1, arg2, gbea, pc);
229 tcg_temp_free_i64(pc);
2c2275eb
AJ
230 }
231#endif
232}
233
3da0ab35
AJ
234static void per_breaking_event(DisasContext *s)
235{
eccf741a 236 tcg_gen_movi_i64(gbea, s->base.pc_next);
3da0ab35
AJ
237}
238
7a6c7067
RH
239static void update_cc_op(DisasContext *s)
240{
241 if (s->cc_op != CC_OP_DYNAMIC && s->cc_op != CC_OP_STATIC) {
242 tcg_gen_movi_i32(cc_op, s->cc_op);
243 }
244}
245
46ee3d84 246static inline uint64_t ld_code2(CPUS390XState *env, uint64_t pc)
e023e832 247{
46ee3d84 248 return (uint64_t)cpu_lduw_code(env, pc);
e023e832
AG
249}
250
46ee3d84 251static inline uint64_t ld_code4(CPUS390XState *env, uint64_t pc)
e023e832 252{
ad044d09 253 return (uint64_t)(uint32_t)cpu_ldl_code(env, pc);
e023e832
AG
254}
255
4f3adfb2 256static int get_mem_index(DisasContext *s)
e023e832 257{
eccf741a 258 if (!(s->base.tb->flags & FLAG_MASK_DAT)) {
f26852aa
DH
259 return MMU_REAL_IDX;
260 }
261
eccf741a 262 switch (s->base.tb->flags & FLAG_MASK_ASC) {
159fed45 263 case PSW_ASC_PRIMARY >> FLAG_MASK_PSW_SHIFT:
f26852aa 264 return MMU_PRIMARY_IDX;
159fed45 265 case PSW_ASC_SECONDARY >> FLAG_MASK_PSW_SHIFT:
f26852aa 266 return MMU_SECONDARY_IDX;
159fed45 267 case PSW_ASC_HOME >> FLAG_MASK_PSW_SHIFT:
f26852aa 268 return MMU_HOME_IDX;
e023e832
AG
269 default:
270 tcg_abort();
271 break;
272 }
273}
274
d5a103cd 275static void gen_exception(int excp)
e023e832 276{
d5a103cd 277 TCGv_i32 tmp = tcg_const_i32(excp);
089f5c06 278 gen_helper_exception(cpu_env, tmp);
e023e832 279 tcg_temp_free_i32(tmp);
e023e832
AG
280}
281
d5a103cd 282static void gen_program_exception(DisasContext *s, int code)
e023e832
AG
283{
284 TCGv_i32 tmp;
285
d5a103cd 286 /* Remember what pgm exeption this was. */
e023e832 287 tmp = tcg_const_i32(code);
a4e3ad19 288 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUS390XState, int_pgm_code));
e023e832
AG
289 tcg_temp_free_i32(tmp);
290
99e57856 291 tmp = tcg_const_i32(s->ilen);
d5a103cd 292 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUS390XState, int_pgm_ilen));
e023e832
AG
293 tcg_temp_free_i32(tmp);
294
becf8217 295 /* update the psw */
e023e832
AG
296 update_psw_addr(s);
297
d5a103cd 298 /* Save off cc. */
7a6c7067 299 update_cc_op(s);
e023e832 300
d5a103cd
RH
301 /* Trigger exception. */
302 gen_exception(EXCP_PGM);
e023e832
AG
303}
304
d5a103cd 305static inline void gen_illegal_opcode(DisasContext *s)
e023e832 306{
111d7f4a 307 gen_program_exception(s, PGM_OPERATION);
e023e832
AG
308}
309
782a8479
AJ
310static inline void gen_trap(DisasContext *s)
311{
312 TCGv_i32 t;
313
314 /* Set DXC to 0xff. */
315 t = tcg_temp_new_i32();
316 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUS390XState, fpc));
317 tcg_gen_ori_i32(t, t, 0xff00);
318 tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, fpc));
319 tcg_temp_free_i32(t);
320
321 gen_program_exception(s, PGM_DATA);
322}
323
8841d9df
PM
324#ifndef CONFIG_USER_ONLY
325static void check_privileged(DisasContext *s)
e023e832 326{
eccf741a 327 if (s->base.tb->flags & FLAG_MASK_PSTATE) {
d5a103cd 328 gen_program_exception(s, PGM_PRIVILEGED);
e023e832
AG
329 }
330}
8841d9df 331#endif
e023e832 332
e023e832
AG
333static TCGv_i64 get_address(DisasContext *s, int x2, int b2, int d2)
334{
bacf43c6 335 TCGv_i64 tmp = tcg_temp_new_i64();
eccf741a 336 bool need_31 = !(s->base.tb->flags & FLAG_MASK_64);
e023e832 337
bacf43c6
RH
338 /* Note that d2 is limited to 20 bits, signed. If we crop negative
339 displacements early we create larger immedate addends. */
e023e832 340
bacf43c6
RH
341 /* Note that addi optimizes the imm==0 case. */
342 if (b2 && x2) {
343 tcg_gen_add_i64(tmp, regs[b2], regs[x2]);
344 tcg_gen_addi_i64(tmp, tmp, d2);
e023e832 345 } else if (b2) {
bacf43c6
RH
346 tcg_gen_addi_i64(tmp, regs[b2], d2);
347 } else if (x2) {
348 tcg_gen_addi_i64(tmp, regs[x2], d2);
e023e832 349 } else {
bacf43c6
RH
350 if (need_31) {
351 d2 &= 0x7fffffff;
352 need_31 = false;
353 }
354 tcg_gen_movi_i64(tmp, d2);
e023e832 355 }
bacf43c6
RH
356 if (need_31) {
357 tcg_gen_andi_i64(tmp, tmp, 0x7fffffff);
e023e832
AG
358 }
359
360 return tmp;
361}
362
f24c49c2
RH
363static inline bool live_cc_data(DisasContext *s)
364{
365 return (s->cc_op != CC_OP_DYNAMIC
366 && s->cc_op != CC_OP_STATIC
367 && s->cc_op > 3);
368}
369
aa31bf60 370static inline void gen_op_movi_cc(DisasContext *s, uint32_t val)
e023e832 371{
f24c49c2
RH
372 if (live_cc_data(s)) {
373 tcg_gen_discard_i64(cc_src);
374 tcg_gen_discard_i64(cc_dst);
375 tcg_gen_discard_i64(cc_vr);
376 }
e023e832
AG
377 s->cc_op = CC_OP_CONST0 + val;
378}
379
380static void gen_op_update1_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 dst)
381{
f24c49c2
RH
382 if (live_cc_data(s)) {
383 tcg_gen_discard_i64(cc_src);
384 tcg_gen_discard_i64(cc_vr);
385 }
e023e832 386 tcg_gen_mov_i64(cc_dst, dst);
e023e832
AG
387 s->cc_op = op;
388}
389
e023e832
AG
390static void gen_op_update2_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src,
391 TCGv_i64 dst)
392{
f24c49c2
RH
393 if (live_cc_data(s)) {
394 tcg_gen_discard_i64(cc_vr);
395 }
e023e832
AG
396 tcg_gen_mov_i64(cc_src, src);
397 tcg_gen_mov_i64(cc_dst, dst);
e023e832
AG
398 s->cc_op = op;
399}
400
e023e832
AG
401static void gen_op_update3_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src,
402 TCGv_i64 dst, TCGv_i64 vr)
403{
404 tcg_gen_mov_i64(cc_src, src);
405 tcg_gen_mov_i64(cc_dst, dst);
406 tcg_gen_mov_i64(cc_vr, vr);
407 s->cc_op = op;
408}
409
4f3adfb2 410static void set_cc_nz_u64(DisasContext *s, TCGv_i64 val)
e023e832
AG
411{
412 gen_op_update1_cc_i64(s, CC_OP_NZ, val);
413}
414
4f3adfb2 415static void gen_set_cc_nz_f32(DisasContext *s, TCGv_i64 val)
68c8bd93
RH
416{
417 gen_op_update1_cc_i64(s, CC_OP_NZ_F32, val);
418}
419
4f3adfb2 420static void gen_set_cc_nz_f64(DisasContext *s, TCGv_i64 val)
68c8bd93
RH
421{
422 gen_op_update1_cc_i64(s, CC_OP_NZ_F64, val);
423}
424
4f3adfb2 425static void gen_set_cc_nz_f128(DisasContext *s, TCGv_i64 vh, TCGv_i64 vl)
68c8bd93
RH
426{
427 gen_op_update2_cc_i64(s, CC_OP_NZ_F128, vh, vl);
428}
429
e023e832 430/* CC value is in env->cc_op */
4f3adfb2 431static void set_cc_static(DisasContext *s)
e023e832 432{
f24c49c2
RH
433 if (live_cc_data(s)) {
434 tcg_gen_discard_i64(cc_src);
435 tcg_gen_discard_i64(cc_dst);
436 tcg_gen_discard_i64(cc_vr);
437 }
e023e832
AG
438 s->cc_op = CC_OP_STATIC;
439}
440
e023e832
AG
441/* calculates cc into cc_op */
442static void gen_op_calc_cc(DisasContext *s)
443{
f764718d
RH
444 TCGv_i32 local_cc_op = NULL;
445 TCGv_i64 dummy = NULL;
7a6c7067 446
7a6c7067
RH
447 switch (s->cc_op) {
448 default:
449 dummy = tcg_const_i64(0);
450 /* FALLTHRU */
451 case CC_OP_ADD_64:
452 case CC_OP_ADDU_64:
453 case CC_OP_ADDC_64:
454 case CC_OP_SUB_64:
455 case CC_OP_SUBU_64:
456 case CC_OP_SUBB_64:
457 case CC_OP_ADD_32:
458 case CC_OP_ADDU_32:
459 case CC_OP_ADDC_32:
460 case CC_OP_SUB_32:
461 case CC_OP_SUBU_32:
462 case CC_OP_SUBB_32:
463 local_cc_op = tcg_const_i32(s->cc_op);
464 break;
465 case CC_OP_CONST0:
466 case CC_OP_CONST1:
467 case CC_OP_CONST2:
468 case CC_OP_CONST3:
469 case CC_OP_STATIC:
470 case CC_OP_DYNAMIC:
471 break;
472 }
e023e832
AG
473
474 switch (s->cc_op) {
475 case CC_OP_CONST0:
476 case CC_OP_CONST1:
477 case CC_OP_CONST2:
478 case CC_OP_CONST3:
479 /* s->cc_op is the cc value */
480 tcg_gen_movi_i32(cc_op, s->cc_op - CC_OP_CONST0);
481 break;
482 case CC_OP_STATIC:
483 /* env->cc_op already is the cc value */
484 break;
485 case CC_OP_NZ:
486 case CC_OP_ABS_64:
487 case CC_OP_NABS_64:
488 case CC_OP_ABS_32:
489 case CC_OP_NABS_32:
490 case CC_OP_LTGT0_32:
491 case CC_OP_LTGT0_64:
492 case CC_OP_COMP_32:
493 case CC_OP_COMP_64:
494 case CC_OP_NZ_F32:
495 case CC_OP_NZ_F64:
102bf2c6 496 case CC_OP_FLOGR:
e023e832 497 /* 1 argument */
932385a3 498 gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, dummy, cc_dst, dummy);
e023e832
AG
499 break;
500 case CC_OP_ICM:
501 case CC_OP_LTGT_32:
502 case CC_OP_LTGT_64:
503 case CC_OP_LTUGTU_32:
504 case CC_OP_LTUGTU_64:
505 case CC_OP_TM_32:
506 case CC_OP_TM_64:
cbe24bfa
RH
507 case CC_OP_SLA_32:
508 case CC_OP_SLA_64:
587626f8 509 case CC_OP_NZ_F128:
e023e832 510 /* 2 arguments */
932385a3 511 gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, cc_src, cc_dst, dummy);
e023e832
AG
512 break;
513 case CC_OP_ADD_64:
514 case CC_OP_ADDU_64:
4e4bb438 515 case CC_OP_ADDC_64:
e023e832
AG
516 case CC_OP_SUB_64:
517 case CC_OP_SUBU_64:
4e4bb438 518 case CC_OP_SUBB_64:
e023e832
AG
519 case CC_OP_ADD_32:
520 case CC_OP_ADDU_32:
4e4bb438 521 case CC_OP_ADDC_32:
e023e832
AG
522 case CC_OP_SUB_32:
523 case CC_OP_SUBU_32:
4e4bb438 524 case CC_OP_SUBB_32:
e023e832 525 /* 3 arguments */
932385a3 526 gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, cc_src, cc_dst, cc_vr);
e023e832
AG
527 break;
528 case CC_OP_DYNAMIC:
529 /* unknown operation - assume 3 arguments and cc_op in env */
932385a3 530 gen_helper_calc_cc(cc_op, cpu_env, cc_op, cc_src, cc_dst, cc_vr);
e023e832
AG
531 break;
532 default:
533 tcg_abort();
534 }
535
f764718d 536 if (local_cc_op) {
7a6c7067
RH
537 tcg_temp_free_i32(local_cc_op);
538 }
f764718d 539 if (dummy) {
7a6c7067
RH
540 tcg_temp_free_i64(dummy);
541 }
e023e832
AG
542
543 /* We now have cc in cc_op as constant */
544 set_cc_static(s);
545}
546
6350001e 547static bool use_exit_tb(DisasContext *s)
e023e832 548{
eccf741a
EC
549 return s->base.singlestep_enabled ||
550 (tb_cflags(s->base.tb) & CF_LAST_IO) ||
551 (s->base.tb->flags & FLAG_MASK_PER);
6350001e
RH
552}
553
554static bool use_goto_tb(DisasContext *s, uint64_t dest)
555{
556 if (unlikely(use_exit_tb(s))) {
90aa39a1
SF
557 return false;
558 }
559#ifndef CONFIG_USER_ONLY
eccf741a
EC
560 return (dest & TARGET_PAGE_MASK) == (s->base.tb->pc & TARGET_PAGE_MASK) ||
561 (dest & TARGET_PAGE_MASK) == (s->base.pc_next & TARGET_PAGE_MASK);
90aa39a1
SF
562#else
563 return true;
564#endif
8ac33cdb 565}
e023e832 566
4f3adfb2 567static void account_noninline_branch(DisasContext *s, int cc_op)
e023e832
AG
568{
569#ifdef DEBUG_INLINE_BRANCHES
570 inline_branch_miss[cc_op]++;
571#endif
572}
573
4f3adfb2 574static void account_inline_branch(DisasContext *s, int cc_op)
e023e832
AG
575{
576#ifdef DEBUG_INLINE_BRANCHES
3fde06f5 577 inline_branch_hit[cc_op]++;
e023e832
AG
578#endif
579}
580
3fde06f5 581/* Table of mask values to comparison codes, given a comparison as input.
de379661 582 For such, CC=3 should not be possible. */
3fde06f5
RH
583static const TCGCond ltgt_cond[16] = {
584 TCG_COND_NEVER, TCG_COND_NEVER, /* | | | x */
de379661
RH
585 TCG_COND_GT, TCG_COND_GT, /* | | GT | x */
586 TCG_COND_LT, TCG_COND_LT, /* | LT | | x */
587 TCG_COND_NE, TCG_COND_NE, /* | LT | GT | x */
588 TCG_COND_EQ, TCG_COND_EQ, /* EQ | | | x */
589 TCG_COND_GE, TCG_COND_GE, /* EQ | | GT | x */
590 TCG_COND_LE, TCG_COND_LE, /* EQ | LT | | x */
3fde06f5
RH
591 TCG_COND_ALWAYS, TCG_COND_ALWAYS, /* EQ | LT | GT | x */
592};
593
594/* Table of mask values to comparison codes, given a logic op as input.
595 For such, only CC=0 and CC=1 should be possible. */
596static const TCGCond nz_cond[16] = {
de379661
RH
597 TCG_COND_NEVER, TCG_COND_NEVER, /* | | x | x */
598 TCG_COND_NEVER, TCG_COND_NEVER,
599 TCG_COND_NE, TCG_COND_NE, /* | NE | x | x */
600 TCG_COND_NE, TCG_COND_NE,
601 TCG_COND_EQ, TCG_COND_EQ, /* EQ | | x | x */
602 TCG_COND_EQ, TCG_COND_EQ,
603 TCG_COND_ALWAYS, TCG_COND_ALWAYS, /* EQ | NE | x | x */
604 TCG_COND_ALWAYS, TCG_COND_ALWAYS,
3fde06f5
RH
605};
606
607/* Interpret MASK in terms of S->CC_OP, and fill in C with all the
608 details required to generate a TCG comparison. */
609static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
e023e832 610{
3fde06f5
RH
611 TCGCond cond;
612 enum cc_op old_cc_op = s->cc_op;
e023e832 613
3fde06f5
RH
614 if (mask == 15 || mask == 0) {
615 c->cond = (mask ? TCG_COND_ALWAYS : TCG_COND_NEVER);
616 c->u.s32.a = cc_op;
617 c->u.s32.b = cc_op;
618 c->g1 = c->g2 = true;
619 c->is_64 = false;
620 return;
621 }
622
623 /* Find the TCG condition for the mask + cc op. */
624 switch (old_cc_op) {
e023e832 625 case CC_OP_LTGT0_32:
e023e832 626 case CC_OP_LTGT0_64:
e023e832 627 case CC_OP_LTGT_32:
e023e832 628 case CC_OP_LTGT_64:
3fde06f5
RH
629 cond = ltgt_cond[mask];
630 if (cond == TCG_COND_NEVER) {
e023e832
AG
631 goto do_dynamic;
632 }
3fde06f5 633 account_inline_branch(s, old_cc_op);
e023e832 634 break;
3fde06f5 635
e023e832 636 case CC_OP_LTUGTU_32:
e023e832 637 case CC_OP_LTUGTU_64:
3fde06f5
RH
638 cond = tcg_unsigned_cond(ltgt_cond[mask]);
639 if (cond == TCG_COND_NEVER) {
e023e832
AG
640 goto do_dynamic;
641 }
3fde06f5 642 account_inline_branch(s, old_cc_op);
e023e832 643 break;
3fde06f5 644
e023e832 645 case CC_OP_NZ:
3fde06f5
RH
646 cond = nz_cond[mask];
647 if (cond == TCG_COND_NEVER) {
e023e832
AG
648 goto do_dynamic;
649 }
3fde06f5 650 account_inline_branch(s, old_cc_op);
e023e832 651 break;
e023e832 652
3fde06f5 653 case CC_OP_TM_32:
e023e832 654 case CC_OP_TM_64:
e023e832 655 switch (mask) {
3fde06f5
RH
656 case 8:
657 cond = TCG_COND_EQ;
e023e832 658 break;
3fde06f5
RH
659 case 4 | 2 | 1:
660 cond = TCG_COND_NE;
e023e832
AG
661 break;
662 default:
663 goto do_dynamic;
664 }
3fde06f5 665 account_inline_branch(s, old_cc_op);
e023e832 666 break;
3fde06f5 667
e023e832
AG
668 case CC_OP_ICM:
669 switch (mask) {
3fde06f5
RH
670 case 8:
671 cond = TCG_COND_EQ;
e023e832 672 break;
3fde06f5
RH
673 case 4 | 2 | 1:
674 case 4 | 2:
675 cond = TCG_COND_NE;
e023e832
AG
676 break;
677 default:
678 goto do_dynamic;
679 }
3fde06f5 680 account_inline_branch(s, old_cc_op);
e023e832 681 break;
3fde06f5 682
102bf2c6
RH
683 case CC_OP_FLOGR:
684 switch (mask & 0xa) {
685 case 8: /* src == 0 -> no one bit found */
686 cond = TCG_COND_EQ;
687 break;
688 case 2: /* src != 0 -> one bit found */
689 cond = TCG_COND_NE;
690 break;
691 default:
692 goto do_dynamic;
693 }
694 account_inline_branch(s, old_cc_op);
695 break;
696
a359b770
RH
697 case CC_OP_ADDU_32:
698 case CC_OP_ADDU_64:
699 switch (mask) {
700 case 8 | 2: /* vr == 0 */
701 cond = TCG_COND_EQ;
702 break;
703 case 4 | 1: /* vr != 0 */
704 cond = TCG_COND_NE;
705 break;
706 case 8 | 4: /* no carry -> vr >= src */
707 cond = TCG_COND_GEU;
708 break;
709 case 2 | 1: /* carry -> vr < src */
710 cond = TCG_COND_LTU;
711 break;
712 default:
713 goto do_dynamic;
714 }
715 account_inline_branch(s, old_cc_op);
716 break;
717
718 case CC_OP_SUBU_32:
719 case CC_OP_SUBU_64:
720 /* Note that CC=0 is impossible; treat it as dont-care. */
721 switch (mask & 7) {
722 case 2: /* zero -> op1 == op2 */
723 cond = TCG_COND_EQ;
724 break;
725 case 4 | 1: /* !zero -> op1 != op2 */
726 cond = TCG_COND_NE;
727 break;
728 case 4: /* borrow (!carry) -> op1 < op2 */
729 cond = TCG_COND_LTU;
730 break;
731 case 2 | 1: /* !borrow (carry) -> op1 >= op2 */
732 cond = TCG_COND_GEU;
733 break;
734 default:
735 goto do_dynamic;
736 }
737 account_inline_branch(s, old_cc_op);
738 break;
739
e023e832 740 default:
3fde06f5
RH
741 do_dynamic:
742 /* Calculate cc value. */
e023e832 743 gen_op_calc_cc(s);
3fde06f5 744 /* FALLTHRU */
e023e832 745
3fde06f5
RH
746 case CC_OP_STATIC:
747 /* Jump based on CC. We'll load up the real cond below;
748 the assignment here merely avoids a compiler warning. */
e023e832 749 account_noninline_branch(s, old_cc_op);
3fde06f5
RH
750 old_cc_op = CC_OP_STATIC;
751 cond = TCG_COND_NEVER;
752 break;
753 }
e023e832 754
3fde06f5
RH
755 /* Load up the arguments of the comparison. */
756 c->is_64 = true;
757 c->g1 = c->g2 = false;
758 switch (old_cc_op) {
759 case CC_OP_LTGT0_32:
760 c->is_64 = false;
761 c->u.s32.a = tcg_temp_new_i32();
ecc7b3aa 762 tcg_gen_extrl_i64_i32(c->u.s32.a, cc_dst);
3fde06f5
RH
763 c->u.s32.b = tcg_const_i32(0);
764 break;
765 case CC_OP_LTGT_32:
766 case CC_OP_LTUGTU_32:
a359b770 767 case CC_OP_SUBU_32:
3fde06f5
RH
768 c->is_64 = false;
769 c->u.s32.a = tcg_temp_new_i32();
ecc7b3aa 770 tcg_gen_extrl_i64_i32(c->u.s32.a, cc_src);
3fde06f5 771 c->u.s32.b = tcg_temp_new_i32();
ecc7b3aa 772 tcg_gen_extrl_i64_i32(c->u.s32.b, cc_dst);
3fde06f5
RH
773 break;
774
775 case CC_OP_LTGT0_64:
776 case CC_OP_NZ:
102bf2c6 777 case CC_OP_FLOGR:
3fde06f5
RH
778 c->u.s64.a = cc_dst;
779 c->u.s64.b = tcg_const_i64(0);
780 c->g1 = true;
781 break;
782 case CC_OP_LTGT_64:
783 case CC_OP_LTUGTU_64:
a359b770 784 case CC_OP_SUBU_64:
3fde06f5
RH
785 c->u.s64.a = cc_src;
786 c->u.s64.b = cc_dst;
787 c->g1 = c->g2 = true;
788 break;
789
790 case CC_OP_TM_32:
791 case CC_OP_TM_64:
58a9e35b 792 case CC_OP_ICM:
3fde06f5
RH
793 c->u.s64.a = tcg_temp_new_i64();
794 c->u.s64.b = tcg_const_i64(0);
795 tcg_gen_and_i64(c->u.s64.a, cc_src, cc_dst);
796 break;
a359b770
RH
797
798 case CC_OP_ADDU_32:
799 c->is_64 = false;
800 c->u.s32.a = tcg_temp_new_i32();
801 c->u.s32.b = tcg_temp_new_i32();
ecc7b3aa 802 tcg_gen_extrl_i64_i32(c->u.s32.a, cc_vr);
a359b770
RH
803 if (cond == TCG_COND_EQ || cond == TCG_COND_NE) {
804 tcg_gen_movi_i32(c->u.s32.b, 0);
805 } else {
ecc7b3aa 806 tcg_gen_extrl_i64_i32(c->u.s32.b, cc_src);
a359b770
RH
807 }
808 break;
809
810 case CC_OP_ADDU_64:
811 c->u.s64.a = cc_vr;
812 c->g1 = true;
813 if (cond == TCG_COND_EQ || cond == TCG_COND_NE) {
814 c->u.s64.b = tcg_const_i64(0);
815 } else {
816 c->u.s64.b = cc_src;
817 c->g2 = true;
818 }
819 break;
3fde06f5
RH
820
821 case CC_OP_STATIC:
822 c->is_64 = false;
823 c->u.s32.a = cc_op;
824 c->g1 = true;
e023e832 825 switch (mask) {
e023e832 826 case 0x8 | 0x4 | 0x2: /* cc != 3 */
3fde06f5
RH
827 cond = TCG_COND_NE;
828 c->u.s32.b = tcg_const_i32(3);
e023e832
AG
829 break;
830 case 0x8 | 0x4 | 0x1: /* cc != 2 */
3fde06f5
RH
831 cond = TCG_COND_NE;
832 c->u.s32.b = tcg_const_i32(2);
e023e832
AG
833 break;
834 case 0x8 | 0x2 | 0x1: /* cc != 1 */
3fde06f5
RH
835 cond = TCG_COND_NE;
836 c->u.s32.b = tcg_const_i32(1);
e023e832 837 break;
3fde06f5
RH
838 case 0x8 | 0x2: /* cc == 0 || cc == 2 => (cc & 1) == 0 */
839 cond = TCG_COND_EQ;
840 c->g1 = false;
841 c->u.s32.a = tcg_temp_new_i32();
842 c->u.s32.b = tcg_const_i32(0);
843 tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
e023e832
AG
844 break;
845 case 0x8 | 0x4: /* cc < 2 */
3fde06f5
RH
846 cond = TCG_COND_LTU;
847 c->u.s32.b = tcg_const_i32(2);
e023e832
AG
848 break;
849 case 0x8: /* cc == 0 */
3fde06f5
RH
850 cond = TCG_COND_EQ;
851 c->u.s32.b = tcg_const_i32(0);
e023e832
AG
852 break;
853 case 0x4 | 0x2 | 0x1: /* cc != 0 */
3fde06f5
RH
854 cond = TCG_COND_NE;
855 c->u.s32.b = tcg_const_i32(0);
e023e832 856 break;
3fde06f5
RH
857 case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */
858 cond = TCG_COND_NE;
859 c->g1 = false;
860 c->u.s32.a = tcg_temp_new_i32();
861 c->u.s32.b = tcg_const_i32(0);
862 tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
e023e832
AG
863 break;
864 case 0x4: /* cc == 1 */
3fde06f5
RH
865 cond = TCG_COND_EQ;
866 c->u.s32.b = tcg_const_i32(1);
e023e832
AG
867 break;
868 case 0x2 | 0x1: /* cc > 1 */
3fde06f5
RH
869 cond = TCG_COND_GTU;
870 c->u.s32.b = tcg_const_i32(1);
e023e832
AG
871 break;
872 case 0x2: /* cc == 2 */
3fde06f5
RH
873 cond = TCG_COND_EQ;
874 c->u.s32.b = tcg_const_i32(2);
e023e832
AG
875 break;
876 case 0x1: /* cc == 3 */
3fde06f5
RH
877 cond = TCG_COND_EQ;
878 c->u.s32.b = tcg_const_i32(3);
e023e832 879 break;
3fde06f5
RH
880 default:
881 /* CC is masked by something else: (8 >> cc) & mask. */
882 cond = TCG_COND_NE;
883 c->g1 = false;
884 c->u.s32.a = tcg_const_i32(8);
885 c->u.s32.b = tcg_const_i32(0);
886 tcg_gen_shr_i32(c->u.s32.a, c->u.s32.a, cc_op);
887 tcg_gen_andi_i32(c->u.s32.a, c->u.s32.a, mask);
e023e832
AG
888 break;
889 }
890 break;
3fde06f5
RH
891
892 default:
893 abort();
e023e832 894 }
3fde06f5
RH
895 c->cond = cond;
896}
897
898static void free_compare(DisasCompare *c)
899{
900 if (!c->g1) {
901 if (c->is_64) {
902 tcg_temp_free_i64(c->u.s64.a);
903 } else {
904 tcg_temp_free_i32(c->u.s32.a);
905 }
906 }
907 if (!c->g2) {
908 if (c->is_64) {
909 tcg_temp_free_i64(c->u.s64.b);
910 } else {
911 tcg_temp_free_i32(c->u.s32.b);
912 }
913 }
914}
915
ad044d09
RH
916/* ====================================================================== */
917/* Define the insn format enumeration. */
918#define F0(N) FMT_##N,
919#define F1(N, X1) F0(N)
920#define F2(N, X1, X2) F0(N)
921#define F3(N, X1, X2, X3) F0(N)
922#define F4(N, X1, X2, X3, X4) F0(N)
923#define F5(N, X1, X2, X3, X4, X5) F0(N)
924
925typedef enum {
926#include "insn-format.def"
927} DisasFormat;
928
929#undef F0
930#undef F1
931#undef F2
932#undef F3
933#undef F4
934#undef F5
935
936/* Define a structure to hold the decoded fields. We'll store each inside
937 an array indexed by an enum. In order to conserve memory, we'll arrange
938 for fields that do not exist at the same time to overlap, thus the "C"
939 for compact. For checking purposes there is an "O" for original index
940 as well that will be applied to availability bitmaps. */
941
942enum DisasFieldIndexO {
943 FLD_O_r1,
944 FLD_O_r2,
945 FLD_O_r3,
946 FLD_O_m1,
947 FLD_O_m3,
948 FLD_O_m4,
949 FLD_O_b1,
950 FLD_O_b2,
951 FLD_O_b4,
952 FLD_O_d1,
953 FLD_O_d2,
954 FLD_O_d4,
955 FLD_O_x2,
956 FLD_O_l1,
957 FLD_O_l2,
958 FLD_O_i1,
959 FLD_O_i2,
960 FLD_O_i3,
961 FLD_O_i4,
962 FLD_O_i5
963};
964
965enum DisasFieldIndexC {
966 FLD_C_r1 = 0,
967 FLD_C_m1 = 0,
968 FLD_C_b1 = 0,
969 FLD_C_i1 = 0,
970
971 FLD_C_r2 = 1,
972 FLD_C_b2 = 1,
973 FLD_C_i2 = 1,
974
975 FLD_C_r3 = 2,
976 FLD_C_m3 = 2,
977 FLD_C_i3 = 2,
978
979 FLD_C_m4 = 3,
980 FLD_C_b4 = 3,
981 FLD_C_i4 = 3,
982 FLD_C_l1 = 3,
983
984 FLD_C_i5 = 4,
985 FLD_C_d1 = 4,
986
987 FLD_C_d2 = 5,
988
989 FLD_C_d4 = 6,
990 FLD_C_x2 = 6,
991 FLD_C_l2 = 6,
992
993 NUM_C_FIELD = 7
994};
995
996struct DisasFields {
ad8a4570 997 uint64_t raw_insn;
ad044d09
RH
998 unsigned op:8;
999 unsigned op2:8;
1000 unsigned presentC:16;
1001 unsigned int presentO;
1002 int c[NUM_C_FIELD];
1003};
1004
1005/* This is the way fields are to be accessed out of DisasFields. */
1006#define have_field(S, F) have_field1((S), FLD_O_##F)
1007#define get_field(S, F) get_field1((S), FLD_O_##F, FLD_C_##F)
1008
1009static bool have_field1(const DisasFields *f, enum DisasFieldIndexO c)
1010{
1011 return (f->presentO >> c) & 1;
1012}
1013
1014static int get_field1(const DisasFields *f, enum DisasFieldIndexO o,
1015 enum DisasFieldIndexC c)
1016{
1017 assert(have_field1(f, o));
1018 return f->c[c];
1019}
1020
1021/* Describe the layout of each field in each format. */
1022typedef struct DisasField {
1023 unsigned int beg:8;
1024 unsigned int size:8;
1025 unsigned int type:2;
1026 unsigned int indexC:6;
1027 enum DisasFieldIndexO indexO:8;
1028} DisasField;
1029
1030typedef struct DisasFormatInfo {
1031 DisasField op[NUM_C_FIELD];
1032} DisasFormatInfo;
1033
1034#define R(N, B) { B, 4, 0, FLD_C_r##N, FLD_O_r##N }
1035#define M(N, B) { B, 4, 0, FLD_C_m##N, FLD_O_m##N }
1036#define BD(N, BB, BD) { BB, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
1037 { BD, 12, 0, FLD_C_d##N, FLD_O_d##N }
1038#define BXD(N) { 16, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
1039 { 12, 4, 0, FLD_C_x##N, FLD_O_x##N }, \
1040 { 20, 12, 0, FLD_C_d##N, FLD_O_d##N }
1041#define BDL(N) { 16, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
1042 { 20, 20, 2, FLD_C_d##N, FLD_O_d##N }
1043#define BXDL(N) { 16, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
1044 { 12, 4, 0, FLD_C_x##N, FLD_O_x##N }, \
1045 { 20, 20, 2, FLD_C_d##N, FLD_O_d##N }
1046#define I(N, B, S) { B, S, 1, FLD_C_i##N, FLD_O_i##N }
1047#define L(N, B, S) { B, S, 0, FLD_C_l##N, FLD_O_l##N }
1048
1049#define F0(N) { { } },
1050#define F1(N, X1) { { X1 } },
1051#define F2(N, X1, X2) { { X1, X2 } },
1052#define F3(N, X1, X2, X3) { { X1, X2, X3 } },
1053#define F4(N, X1, X2, X3, X4) { { X1, X2, X3, X4 } },
1054#define F5(N, X1, X2, X3, X4, X5) { { X1, X2, X3, X4, X5 } },
1055
1056static const DisasFormatInfo format_info[] = {
1057#include "insn-format.def"
1058};
1059
1060#undef F0
1061#undef F1
1062#undef F2
1063#undef F3
1064#undef F4
1065#undef F5
1066#undef R
1067#undef M
1068#undef BD
1069#undef BXD
1070#undef BDL
1071#undef BXDL
1072#undef I
1073#undef L
1074
1075/* Generally, we'll extract operands into this structures, operate upon
1076 them, and store them back. See the "in1", "in2", "prep", "wout" sets
1077 of routines below for more details. */
1078typedef struct {
1079 bool g_out, g_out2, g_in1, g_in2;
1080 TCGv_i64 out, out2, in1, in2;
1081 TCGv_i64 addr1;
1082} DisasOps;
1083
49f7ee80
RH
1084/* Instructions can place constraints on their operands, raising specification
1085 exceptions if they are violated. To make this easy to automate, each "in1",
1086 "in2", "prep", "wout" helper will have a SPEC_<name> define that equals one
1087 of the following, or 0. To make this easy to document, we'll put the
1088 SPEC_<name> defines next to <name>. */
1089
1090#define SPEC_r1_even 1
1091#define SPEC_r2_even 2
b7886de3
RH
1092#define SPEC_r3_even 4
1093#define SPEC_r1_f128 8
1094#define SPEC_r2_f128 16
49f7ee80 1095
ad044d09 1096/* Return values from translate_one, indicating the state of the TB. */
21a8eced
EC
1097
1098/* We are not using a goto_tb (for whatever reason), but have updated
1099 the PC (for whatever reason), so there's no need to do it again on
1100 exiting the TB. */
1101#define DISAS_PC_UPDATED DISAS_TARGET_0
1102
1103/* We have emitted one or more goto_tb. No fixup required. */
1104#define DISAS_GOTO_TB DISAS_TARGET_1
1105
1106/* We have updated the PC and CC values. */
1107#define DISAS_PC_CC_UPDATED DISAS_TARGET_2
1108
1109/* We are exiting the TB, but have neither emitted a goto_tb, nor
1110 updated the PC for the next instruction to be executed. */
1111#define DISAS_PC_STALE DISAS_TARGET_3
1112
1113/* We are exiting the TB to the main loop. */
1114#define DISAS_PC_STALE_NOCHAIN DISAS_TARGET_4
ad044d09 1115
ad044d09
RH
1116struct DisasInsn {
1117 unsigned opc:16;
b7886de3 1118 DisasFormat fmt:8;
d20bd43c 1119 unsigned fac:8;
b7886de3 1120 unsigned spec:8;
ad044d09
RH
1121
1122 const char *name;
1123
1124 void (*help_in1)(DisasContext *, DisasFields *, DisasOps *);
1125 void (*help_in2)(DisasContext *, DisasFields *, DisasOps *);
1126 void (*help_prep)(DisasContext *, DisasFields *, DisasOps *);
1127 void (*help_wout)(DisasContext *, DisasFields *, DisasOps *);
1128 void (*help_cout)(DisasContext *, DisasOps *);
21a8eced 1129 DisasJumpType (*help_op)(DisasContext *, DisasOps *);
ad044d09
RH
1130
1131 uint64_t data;
1132};
1133
8ac33cdb 1134/* ====================================================================== */
085d8134 1135/* Miscellaneous helpers, used by several operations. */
8ac33cdb 1136
cbe24bfa
RH
1137static void help_l2_shift(DisasContext *s, DisasFields *f,
1138 DisasOps *o, int mask)
1139{
1140 int b2 = get_field(f, b2);
1141 int d2 = get_field(f, d2);
1142
1143 if (b2 == 0) {
1144 o->in2 = tcg_const_i64(d2 & mask);
1145 } else {
1146 o->in2 = get_address(s, 0, b2, d2);
1147 tcg_gen_andi_i64(o->in2, o->in2, mask);
1148 }
1149}
1150
21a8eced 1151static DisasJumpType help_goto_direct(DisasContext *s, uint64_t dest)
8ac33cdb 1152{
eccf741a 1153 if (dest == s->pc_tmp) {
2c2275eb 1154 per_branch(s, true);
21a8eced 1155 return DISAS_NEXT;
8ac33cdb
RH
1156 }
1157 if (use_goto_tb(s, dest)) {
7a6c7067 1158 update_cc_op(s);
3da0ab35 1159 per_breaking_event(s);
8ac33cdb
RH
1160 tcg_gen_goto_tb(0);
1161 tcg_gen_movi_i64(psw_addr, dest);
07ea28b4 1162 tcg_gen_exit_tb(s->base.tb, 0);
21a8eced 1163 return DISAS_GOTO_TB;
8ac33cdb
RH
1164 } else {
1165 tcg_gen_movi_i64(psw_addr, dest);
2c2275eb 1166 per_branch(s, false);
21a8eced 1167 return DISAS_PC_UPDATED;
8ac33cdb
RH
1168 }
1169}
1170
21a8eced
EC
1171static DisasJumpType help_branch(DisasContext *s, DisasCompare *c,
1172 bool is_imm, int imm, TCGv_i64 cdest)
7233f2ed 1173{
21a8eced 1174 DisasJumpType ret;
eccf741a 1175 uint64_t dest = s->base.pc_next + 2 * imm;
42a268c2 1176 TCGLabel *lab;
7233f2ed
RH
1177
1178 /* Take care of the special cases first. */
1179 if (c->cond == TCG_COND_NEVER) {
21a8eced 1180 ret = DISAS_NEXT;
7233f2ed
RH
1181 goto egress;
1182 }
1183 if (is_imm) {
eccf741a 1184 if (dest == s->pc_tmp) {
7233f2ed 1185 /* Branch to next. */
2c2275eb 1186 per_branch(s, true);
21a8eced 1187 ret = DISAS_NEXT;
7233f2ed
RH
1188 goto egress;
1189 }
1190 if (c->cond == TCG_COND_ALWAYS) {
1191 ret = help_goto_direct(s, dest);
1192 goto egress;
1193 }
1194 } else {
f764718d 1195 if (!cdest) {
7233f2ed 1196 /* E.g. bcr %r0 -> no branch. */
21a8eced 1197 ret = DISAS_NEXT;
7233f2ed
RH
1198 goto egress;
1199 }
1200 if (c->cond == TCG_COND_ALWAYS) {
1201 tcg_gen_mov_i64(psw_addr, cdest);
2c2275eb 1202 per_branch(s, false);
21a8eced 1203 ret = DISAS_PC_UPDATED;
7233f2ed
RH
1204 goto egress;
1205 }
1206 }
1207
eccf741a 1208 if (use_goto_tb(s, s->pc_tmp)) {
7233f2ed
RH
1209 if (is_imm && use_goto_tb(s, dest)) {
1210 /* Both exits can use goto_tb. */
7a6c7067 1211 update_cc_op(s);
7233f2ed
RH
1212
1213 lab = gen_new_label();
1214 if (c->is_64) {
1215 tcg_gen_brcond_i64(c->cond, c->u.s64.a, c->u.s64.b, lab);
1216 } else {
1217 tcg_gen_brcond_i32(c->cond, c->u.s32.a, c->u.s32.b, lab);
1218 }
1219
1220 /* Branch not taken. */
1221 tcg_gen_goto_tb(0);
eccf741a 1222 tcg_gen_movi_i64(psw_addr, s->pc_tmp);
07ea28b4 1223 tcg_gen_exit_tb(s->base.tb, 0);
7233f2ed
RH
1224
1225 /* Branch taken. */
1226 gen_set_label(lab);
3da0ab35 1227 per_breaking_event(s);
7233f2ed
RH
1228 tcg_gen_goto_tb(1);
1229 tcg_gen_movi_i64(psw_addr, dest);
07ea28b4 1230 tcg_gen_exit_tb(s->base.tb, 1);
7233f2ed 1231
21a8eced 1232 ret = DISAS_GOTO_TB;
7233f2ed
RH
1233 } else {
1234 /* Fallthru can use goto_tb, but taken branch cannot. */
1235 /* Store taken branch destination before the brcond. This
1236 avoids having to allocate a new local temp to hold it.
1237 We'll overwrite this in the not taken case anyway. */
1238 if (!is_imm) {
1239 tcg_gen_mov_i64(psw_addr, cdest);
1240 }
1241
1242 lab = gen_new_label();
1243 if (c->is_64) {
1244 tcg_gen_brcond_i64(c->cond, c->u.s64.a, c->u.s64.b, lab);
1245 } else {
1246 tcg_gen_brcond_i32(c->cond, c->u.s32.a, c->u.s32.b, lab);
1247 }
1248
1249 /* Branch not taken. */
7a6c7067 1250 update_cc_op(s);
7233f2ed 1251 tcg_gen_goto_tb(0);
eccf741a 1252 tcg_gen_movi_i64(psw_addr, s->pc_tmp);
07ea28b4 1253 tcg_gen_exit_tb(s->base.tb, 0);
7233f2ed
RH
1254
1255 gen_set_label(lab);
1256 if (is_imm) {
1257 tcg_gen_movi_i64(psw_addr, dest);
1258 }
3da0ab35 1259 per_breaking_event(s);
21a8eced 1260 ret = DISAS_PC_UPDATED;
7233f2ed
RH
1261 }
1262 } else {
1263 /* Fallthru cannot use goto_tb. This by itself is vanishingly rare.
1264 Most commonly we're single-stepping or some other condition that
1265 disables all use of goto_tb. Just update the PC and exit. */
1266
eccf741a 1267 TCGv_i64 next = tcg_const_i64(s->pc_tmp);
7233f2ed
RH
1268 if (is_imm) {
1269 cdest = tcg_const_i64(dest);
1270 }
1271
1272 if (c->is_64) {
1273 tcg_gen_movcond_i64(c->cond, psw_addr, c->u.s64.a, c->u.s64.b,
1274 cdest, next);
2c2275eb 1275 per_branch_cond(s, c->cond, c->u.s64.a, c->u.s64.b);
7233f2ed
RH
1276 } else {
1277 TCGv_i32 t0 = tcg_temp_new_i32();
1278 TCGv_i64 t1 = tcg_temp_new_i64();
1279 TCGv_i64 z = tcg_const_i64(0);
1280 tcg_gen_setcond_i32(c->cond, t0, c->u.s32.a, c->u.s32.b);
1281 tcg_gen_extu_i32_i64(t1, t0);
1282 tcg_temp_free_i32(t0);
1283 tcg_gen_movcond_i64(TCG_COND_NE, psw_addr, t1, z, cdest, next);
2c2275eb 1284 per_branch_cond(s, TCG_COND_NE, t1, z);
7233f2ed
RH
1285 tcg_temp_free_i64(t1);
1286 tcg_temp_free_i64(z);
1287 }
1288
1289 if (is_imm) {
1290 tcg_temp_free_i64(cdest);
1291 }
1292 tcg_temp_free_i64(next);
1293
21a8eced 1294 ret = DISAS_PC_UPDATED;
7233f2ed
RH
1295 }
1296
1297 egress:
1298 free_compare(c);
1299 return ret;
1300}
1301
ad044d09
RH
1302/* ====================================================================== */
1303/* The operations. These perform the bulk of the work for any insn,
1304 usually after the operands have been loaded and output initialized. */
1305
21a8eced 1306static DisasJumpType op_abs(DisasContext *s, DisasOps *o)
b9bca3e5 1307{
d3010781
AJ
1308 TCGv_i64 z, n;
1309 z = tcg_const_i64(0);
1310 n = tcg_temp_new_i64();
1311 tcg_gen_neg_i64(n, o->in2);
1312 tcg_gen_movcond_i64(TCG_COND_LT, o->out, o->in2, z, n, o->in2);
1313 tcg_temp_free_i64(n);
1314 tcg_temp_free_i64(z);
21a8eced 1315 return DISAS_NEXT;
b9bca3e5
RH
1316}
1317
21a8eced 1318static DisasJumpType op_absf32(DisasContext *s, DisasOps *o)
5d7fd045
RH
1319{
1320 tcg_gen_andi_i64(o->out, o->in2, 0x7fffffffull);
21a8eced 1321 return DISAS_NEXT;
5d7fd045
RH
1322}
1323
21a8eced 1324static DisasJumpType op_absf64(DisasContext *s, DisasOps *o)
5d7fd045
RH
1325{
1326 tcg_gen_andi_i64(o->out, o->in2, 0x7fffffffffffffffull);
21a8eced 1327 return DISAS_NEXT;
5d7fd045
RH
1328}
1329
21a8eced 1330static DisasJumpType op_absf128(DisasContext *s, DisasOps *o)
5d7fd045
RH
1331{
1332 tcg_gen_andi_i64(o->out, o->in1, 0x7fffffffffffffffull);
1333 tcg_gen_mov_i64(o->out2, o->in2);
21a8eced 1334 return DISAS_NEXT;
5d7fd045
RH
1335}
1336
21a8eced 1337static DisasJumpType op_add(DisasContext *s, DisasOps *o)
ad044d09
RH
1338{
1339 tcg_gen_add_i64(o->out, o->in1, o->in2);
21a8eced 1340 return DISAS_NEXT;
ad044d09
RH
1341}
1342
21a8eced 1343static DisasJumpType op_addc(DisasContext *s, DisasOps *o)
4e4bb438 1344{
c95ec459
RH
1345 DisasCompare cmp;
1346 TCGv_i64 carry;
4e4bb438
RH
1347
1348 tcg_gen_add_i64(o->out, o->in1, o->in2);
1349
c95ec459
RH
1350 /* The carry flag is the msb of CC, therefore the branch mask that would
1351 create that comparison is 3. Feeding the generated comparison to
1352 setcond produces the carry flag that we desire. */
1353 disas_jcc(s, &cmp, 3);
1354 carry = tcg_temp_new_i64();
1355 if (cmp.is_64) {
1356 tcg_gen_setcond_i64(cmp.cond, carry, cmp.u.s64.a, cmp.u.s64.b);
1357 } else {
1358 TCGv_i32 t = tcg_temp_new_i32();
1359 tcg_gen_setcond_i32(cmp.cond, t, cmp.u.s32.a, cmp.u.s32.b);
1360 tcg_gen_extu_i32_i64(carry, t);
1361 tcg_temp_free_i32(t);
1362 }
1363 free_compare(&cmp);
4e4bb438 1364
c95ec459
RH
1365 tcg_gen_add_i64(o->out, o->out, carry);
1366 tcg_temp_free_i64(carry);
21a8eced 1367 return DISAS_NEXT;
4e4bb438
RH
1368}
1369
21a8eced 1370static DisasJumpType op_asi(DisasContext *s, DisasOps *o)
0e9383bc
DH
1371{
1372 o->in1 = tcg_temp_new_i64();
1373
1374 if (!s390_has_feat(S390_FEAT_STFLE_45)) {
1375 tcg_gen_qemu_ld_tl(o->in1, o->addr1, get_mem_index(s), s->insn->data);
1376 } else {
1377 /* Perform the atomic addition in memory. */
1378 tcg_gen_atomic_fetch_add_i64(o->in1, o->addr1, o->in2, get_mem_index(s),
1379 s->insn->data);
1380 }
1381
1382 /* Recompute also for atomic case: needed for setting CC. */
1383 tcg_gen_add_i64(o->out, o->in1, o->in2);
1384
1385 if (!s390_has_feat(S390_FEAT_STFLE_45)) {
1386 tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), s->insn->data);
1387 }
21a8eced 1388 return DISAS_NEXT;
0e9383bc
DH
1389}
1390
21a8eced 1391static DisasJumpType op_aeb(DisasContext *s, DisasOps *o)
587626f8
RH
1392{
1393 gen_helper_aeb(o->out, cpu_env, o->in1, o->in2);
21a8eced 1394 return DISAS_NEXT;
587626f8
RH
1395}
1396
21a8eced 1397static DisasJumpType op_adb(DisasContext *s, DisasOps *o)
587626f8
RH
1398{
1399 gen_helper_adb(o->out, cpu_env, o->in1, o->in2);
21a8eced 1400 return DISAS_NEXT;
587626f8
RH
1401}
1402
21a8eced 1403static DisasJumpType op_axb(DisasContext *s, DisasOps *o)
587626f8
RH
1404{
1405 gen_helper_axb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2);
1406 return_low128(o->out2);
21a8eced 1407 return DISAS_NEXT;
587626f8
RH
1408}
1409
21a8eced 1410static DisasJumpType op_and(DisasContext *s, DisasOps *o)
3bbfbd1f
RH
1411{
1412 tcg_gen_and_i64(o->out, o->in1, o->in2);
21a8eced 1413 return DISAS_NEXT;
3bbfbd1f
RH
1414}
1415
21a8eced 1416static DisasJumpType op_andi(DisasContext *s, DisasOps *o)
facfc864
RH
1417{
1418 int shift = s->insn->data & 0xff;
1419 int size = s->insn->data >> 8;
1420 uint64_t mask = ((1ull << size) - 1) << shift;
1421
1422 assert(!o->g_in2);
1423 tcg_gen_shli_i64(o->in2, o->in2, shift);
1424 tcg_gen_ori_i64(o->in2, o->in2, ~mask);
1425 tcg_gen_and_i64(o->out, o->in1, o->in2);
1426
1427 /* Produce the CC from only the bits manipulated. */
1428 tcg_gen_andi_i64(cc_dst, o->out, mask);
1429 set_cc_nz_u64(s, cc_dst);
21a8eced 1430 return DISAS_NEXT;
facfc864
RH
1431}
1432
21a8eced 1433static DisasJumpType op_ni(DisasContext *s, DisasOps *o)
f400be18
DH
1434{
1435 o->in1 = tcg_temp_new_i64();
1436
1437 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
1438 tcg_gen_qemu_ld_tl(o->in1, o->addr1, get_mem_index(s), s->insn->data);
1439 } else {
1440 /* Perform the atomic operation in memory. */
1441 tcg_gen_atomic_fetch_and_i64(o->in1, o->addr1, o->in2, get_mem_index(s),
1442 s->insn->data);
1443 }
1444
1445 /* Recompute also for atomic case: needed for setting CC. */
1446 tcg_gen_and_i64(o->out, o->in1, o->in2);
1447
1448 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
1449 tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), s->insn->data);
1450 }
21a8eced 1451 return DISAS_NEXT;
f400be18
DH
1452}
1453
21a8eced 1454static DisasJumpType op_bas(DisasContext *s, DisasOps *o)
8ac33cdb 1455{
eccf741a 1456 tcg_gen_movi_i64(o->out, pc_to_link_info(s, s->pc_tmp));
f764718d 1457 if (o->in2) {
8ac33cdb 1458 tcg_gen_mov_i64(psw_addr, o->in2);
2c2275eb 1459 per_branch(s, false);
21a8eced 1460 return DISAS_PC_UPDATED;
8ac33cdb 1461 } else {
21a8eced 1462 return DISAS_NEXT;
8ac33cdb
RH
1463 }
1464}
1465
21a8eced 1466static DisasJumpType op_basi(DisasContext *s, DisasOps *o)
8ac33cdb 1467{
eccf741a
EC
1468 tcg_gen_movi_i64(o->out, pc_to_link_info(s, s->pc_tmp));
1469 return help_goto_direct(s, s->base.pc_next + 2 * get_field(s->fields, i2));
8ac33cdb
RH
1470}
1471
21a8eced 1472static DisasJumpType op_bc(DisasContext *s, DisasOps *o)
7233f2ed
RH
1473{
1474 int m1 = get_field(s->fields, m1);
1475 bool is_imm = have_field(s->fields, i2);
1476 int imm = is_imm ? get_field(s->fields, i2) : 0;
1477 DisasCompare c;
1478
538fad59
AJ
1479 /* BCR with R2 = 0 causes no branching */
1480 if (have_field(s->fields, r2) && get_field(s->fields, r2) == 0) {
1481 if (m1 == 14) {
1482 /* Perform serialization */
1483 /* FIXME: check for fast-BCR-serialization facility */
1484 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
1485 }
1486 if (m1 == 15) {
1487 /* Perform serialization */
1488 /* FIXME: perform checkpoint-synchronisation */
1489 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
1490 }
21a8eced 1491 return DISAS_NEXT;
538fad59
AJ
1492 }
1493
7233f2ed
RH
1494 disas_jcc(s, &c, m1);
1495 return help_branch(s, &c, is_imm, imm, o->in2);
1496}
1497
21a8eced 1498static DisasJumpType op_bct32(DisasContext *s, DisasOps *o)
c61aad69
RH
1499{
1500 int r1 = get_field(s->fields, r1);
1501 bool is_imm = have_field(s->fields, i2);
1502 int imm = is_imm ? get_field(s->fields, i2) : 0;
1503 DisasCompare c;
1504 TCGv_i64 t;
1505
1506 c.cond = TCG_COND_NE;
1507 c.is_64 = false;
1508 c.g1 = false;
1509 c.g2 = false;
1510
1511 t = tcg_temp_new_i64();
1512 tcg_gen_subi_i64(t, regs[r1], 1);
1513 store_reg32_i64(r1, t);
1514 c.u.s32.a = tcg_temp_new_i32();
1515 c.u.s32.b = tcg_const_i32(0);
ecc7b3aa 1516 tcg_gen_extrl_i64_i32(c.u.s32.a, t);
c61aad69
RH
1517 tcg_temp_free_i64(t);
1518
1519 return help_branch(s, &c, is_imm, imm, o->in2);
1520}
1521
21a8eced 1522static DisasJumpType op_bcth(DisasContext *s, DisasOps *o)
a1f12d85
AJ
1523{
1524 int r1 = get_field(s->fields, r1);
1525 int imm = get_field(s->fields, i2);
1526 DisasCompare c;
1527 TCGv_i64 t;
1528
1529 c.cond = TCG_COND_NE;
1530 c.is_64 = false;
1531 c.g1 = false;
1532 c.g2 = false;
1533
1534 t = tcg_temp_new_i64();
1535 tcg_gen_shri_i64(t, regs[r1], 32);
1536 tcg_gen_subi_i64(t, t, 1);
1537 store_reg32h_i64(r1, t);
1538 c.u.s32.a = tcg_temp_new_i32();
1539 c.u.s32.b = tcg_const_i32(0);
ecc7b3aa 1540 tcg_gen_extrl_i64_i32(c.u.s32.a, t);
a1f12d85
AJ
1541 tcg_temp_free_i64(t);
1542
1543 return help_branch(s, &c, 1, imm, o->in2);
1544}
1545
21a8eced 1546static DisasJumpType op_bct64(DisasContext *s, DisasOps *o)
c61aad69
RH
1547{
1548 int r1 = get_field(s->fields, r1);
1549 bool is_imm = have_field(s->fields, i2);
1550 int imm = is_imm ? get_field(s->fields, i2) : 0;
1551 DisasCompare c;
1552
1553 c.cond = TCG_COND_NE;
1554 c.is_64 = true;
1555 c.g1 = true;
1556 c.g2 = false;
1557
1558 tcg_gen_subi_i64(regs[r1], regs[r1], 1);
1559 c.u.s64.a = regs[r1];
1560 c.u.s64.b = tcg_const_i64(0);
1561
2cf5e350
RH
1562 return help_branch(s, &c, is_imm, imm, o->in2);
1563}
1564
21a8eced 1565static DisasJumpType op_bx32(DisasContext *s, DisasOps *o)
2cf5e350
RH
1566{
1567 int r1 = get_field(s->fields, r1);
1568 int r3 = get_field(s->fields, r3);
1569 bool is_imm = have_field(s->fields, i2);
1570 int imm = is_imm ? get_field(s->fields, i2) : 0;
1571 DisasCompare c;
1572 TCGv_i64 t;
1573
1574 c.cond = (s->insn->data ? TCG_COND_LE : TCG_COND_GT);
1575 c.is_64 = false;
1576 c.g1 = false;
1577 c.g2 = false;
1578
1579 t = tcg_temp_new_i64();
1580 tcg_gen_add_i64(t, regs[r1], regs[r3]);
1581 c.u.s32.a = tcg_temp_new_i32();
1582 c.u.s32.b = tcg_temp_new_i32();
ecc7b3aa
RH
1583 tcg_gen_extrl_i64_i32(c.u.s32.a, t);
1584 tcg_gen_extrl_i64_i32(c.u.s32.b, regs[r3 | 1]);
2cf5e350
RH
1585 store_reg32_i64(r1, t);
1586 tcg_temp_free_i64(t);
1587
1588 return help_branch(s, &c, is_imm, imm, o->in2);
1589}
1590
21a8eced 1591static DisasJumpType op_bx64(DisasContext *s, DisasOps *o)
2cf5e350
RH
1592{
1593 int r1 = get_field(s->fields, r1);
1594 int r3 = get_field(s->fields, r3);
1595 bool is_imm = have_field(s->fields, i2);
1596 int imm = is_imm ? get_field(s->fields, i2) : 0;
1597 DisasCompare c;
1598
1599 c.cond = (s->insn->data ? TCG_COND_LE : TCG_COND_GT);
1600 c.is_64 = true;
1601
1602 if (r1 == (r3 | 1)) {
1603 c.u.s64.b = load_reg(r3 | 1);
1604 c.g2 = false;
1605 } else {
1606 c.u.s64.b = regs[r3 | 1];
1607 c.g2 = true;
1608 }
1609
1610 tcg_gen_add_i64(regs[r1], regs[r1], regs[r3]);
1611 c.u.s64.a = regs[r1];
1612 c.g1 = true;
1613
c61aad69
RH
1614 return help_branch(s, &c, is_imm, imm, o->in2);
1615}
1616
21a8eced 1617static DisasJumpType op_cj(DisasContext *s, DisasOps *o)
5550359f
RH
1618{
1619 int imm, m3 = get_field(s->fields, m3);
1620 bool is_imm;
1621 DisasCompare c;
1622
de379661 1623 c.cond = ltgt_cond[m3];
5550359f
RH
1624 if (s->insn->data) {
1625 c.cond = tcg_unsigned_cond(c.cond);
1626 }
1627 c.is_64 = c.g1 = c.g2 = true;
1628 c.u.s64.a = o->in1;
1629 c.u.s64.b = o->in2;
1630
1631 is_imm = have_field(s->fields, i4);
1632 if (is_imm) {
1633 imm = get_field(s->fields, i4);
1634 } else {
1635 imm = 0;
1636 o->out = get_address(s, 0, get_field(s->fields, b4),
1637 get_field(s->fields, d4));
1638 }
1639
1640 return help_branch(s, &c, is_imm, imm, o->out);
1641}
1642
21a8eced 1643static DisasJumpType op_ceb(DisasContext *s, DisasOps *o)
587626f8
RH
1644{
1645 gen_helper_ceb(cc_op, cpu_env, o->in1, o->in2);
1646 set_cc_static(s);
21a8eced 1647 return DISAS_NEXT;
587626f8
RH
1648}
1649
21a8eced 1650static DisasJumpType op_cdb(DisasContext *s, DisasOps *o)
587626f8
RH
1651{
1652 gen_helper_cdb(cc_op, cpu_env, o->in1, o->in2);
1653 set_cc_static(s);
21a8eced 1654 return DISAS_NEXT;
587626f8
RH
1655}
1656
21a8eced 1657static DisasJumpType op_cxb(DisasContext *s, DisasOps *o)
587626f8
RH
1658{
1659 gen_helper_cxb(cc_op, cpu_env, o->out, o->out2, o->in1, o->in2);
1660 set_cc_static(s);
21a8eced 1661 return DISAS_NEXT;
587626f8
RH
1662}
1663
21a8eced 1664static DisasJumpType op_cfeb(DisasContext *s, DisasOps *o)
68c8bd93
RH
1665{
1666 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1667 gen_helper_cfeb(o->out, cpu_env, o->in2, m3);
1668 tcg_temp_free_i32(m3);
1669 gen_set_cc_nz_f32(s, o->in2);
21a8eced 1670 return DISAS_NEXT;
68c8bd93
RH
1671}
1672
21a8eced 1673static DisasJumpType op_cfdb(DisasContext *s, DisasOps *o)
68c8bd93
RH
1674{
1675 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1676 gen_helper_cfdb(o->out, cpu_env, o->in2, m3);
1677 tcg_temp_free_i32(m3);
1678 gen_set_cc_nz_f64(s, o->in2);
21a8eced 1679 return DISAS_NEXT;
68c8bd93
RH
1680}
1681
21a8eced 1682static DisasJumpType op_cfxb(DisasContext *s, DisasOps *o)
68c8bd93
RH
1683{
1684 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1685 gen_helper_cfxb(o->out, cpu_env, o->in1, o->in2, m3);
1686 tcg_temp_free_i32(m3);
1687 gen_set_cc_nz_f128(s, o->in1, o->in2);
21a8eced 1688 return DISAS_NEXT;
68c8bd93
RH
1689}
1690
21a8eced 1691static DisasJumpType op_cgeb(DisasContext *s, DisasOps *o)
68c8bd93
RH
1692{
1693 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1694 gen_helper_cgeb(o->out, cpu_env, o->in2, m3);
1695 tcg_temp_free_i32(m3);
1696 gen_set_cc_nz_f32(s, o->in2);
21a8eced 1697 return DISAS_NEXT;
68c8bd93
RH
1698}
1699
21a8eced 1700static DisasJumpType op_cgdb(DisasContext *s, DisasOps *o)
68c8bd93
RH
1701{
1702 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1703 gen_helper_cgdb(o->out, cpu_env, o->in2, m3);
1704 tcg_temp_free_i32(m3);
1705 gen_set_cc_nz_f64(s, o->in2);
21a8eced 1706 return DISAS_NEXT;
68c8bd93
RH
1707}
1708
21a8eced 1709static DisasJumpType op_cgxb(DisasContext *s, DisasOps *o)
68c8bd93
RH
1710{
1711 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1712 gen_helper_cgxb(o->out, cpu_env, o->in1, o->in2, m3);
1713 tcg_temp_free_i32(m3);
1714 gen_set_cc_nz_f128(s, o->in1, o->in2);
21a8eced 1715 return DISAS_NEXT;
68c8bd93
RH
1716}
1717
21a8eced 1718static DisasJumpType op_clfeb(DisasContext *s, DisasOps *o)
6ac1b45f
RH
1719{
1720 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1721 gen_helper_clfeb(o->out, cpu_env, o->in2, m3);
1722 tcg_temp_free_i32(m3);
1723 gen_set_cc_nz_f32(s, o->in2);
21a8eced 1724 return DISAS_NEXT;
6ac1b45f
RH
1725}
1726
21a8eced 1727static DisasJumpType op_clfdb(DisasContext *s, DisasOps *o)
6ac1b45f
RH
1728{
1729 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1730 gen_helper_clfdb(o->out, cpu_env, o->in2, m3);
1731 tcg_temp_free_i32(m3);
1732 gen_set_cc_nz_f64(s, o->in2);
21a8eced 1733 return DISAS_NEXT;
6ac1b45f
RH
1734}
1735
21a8eced 1736static DisasJumpType op_clfxb(DisasContext *s, DisasOps *o)
6ac1b45f
RH
1737{
1738 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1739 gen_helper_clfxb(o->out, cpu_env, o->in1, o->in2, m3);
1740 tcg_temp_free_i32(m3);
1741 gen_set_cc_nz_f128(s, o->in1, o->in2);
21a8eced 1742 return DISAS_NEXT;
6ac1b45f
RH
1743}
1744
21a8eced 1745static DisasJumpType op_clgeb(DisasContext *s, DisasOps *o)
6ac1b45f
RH
1746{
1747 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1748 gen_helper_clgeb(o->out, cpu_env, o->in2, m3);
1749 tcg_temp_free_i32(m3);
1750 gen_set_cc_nz_f32(s, o->in2);
21a8eced 1751 return DISAS_NEXT;
6ac1b45f
RH
1752}
1753
21a8eced 1754static DisasJumpType op_clgdb(DisasContext *s, DisasOps *o)
6ac1b45f
RH
1755{
1756 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1757 gen_helper_clgdb(o->out, cpu_env, o->in2, m3);
1758 tcg_temp_free_i32(m3);
1759 gen_set_cc_nz_f64(s, o->in2);
21a8eced 1760 return DISAS_NEXT;
6ac1b45f
RH
1761}
1762
21a8eced 1763static DisasJumpType op_clgxb(DisasContext *s, DisasOps *o)
6ac1b45f
RH
1764{
1765 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1766 gen_helper_clgxb(o->out, cpu_env, o->in1, o->in2, m3);
1767 tcg_temp_free_i32(m3);
1768 gen_set_cc_nz_f128(s, o->in1, o->in2);
21a8eced 1769 return DISAS_NEXT;
6ac1b45f
RH
1770}
1771
21a8eced 1772static DisasJumpType op_cegb(DisasContext *s, DisasOps *o)
683bb9a8
RH
1773{
1774 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1775 gen_helper_cegb(o->out, cpu_env, o->in2, m3);
1776 tcg_temp_free_i32(m3);
21a8eced 1777 return DISAS_NEXT;
683bb9a8
RH
1778}
1779
21a8eced 1780static DisasJumpType op_cdgb(DisasContext *s, DisasOps *o)
683bb9a8
RH
1781{
1782 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1783 gen_helper_cdgb(o->out, cpu_env, o->in2, m3);
1784 tcg_temp_free_i32(m3);
21a8eced 1785 return DISAS_NEXT;
683bb9a8
RH
1786}
1787
21a8eced 1788static DisasJumpType op_cxgb(DisasContext *s, DisasOps *o)
683bb9a8
RH
1789{
1790 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1791 gen_helper_cxgb(o->out, cpu_env, o->in2, m3);
1792 tcg_temp_free_i32(m3);
2112bf1b 1793 return_low128(o->out2);
21a8eced 1794 return DISAS_NEXT;
2112bf1b
RH
1795}
1796
21a8eced 1797static DisasJumpType op_celgb(DisasContext *s, DisasOps *o)
2112bf1b
RH
1798{
1799 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1800 gen_helper_celgb(o->out, cpu_env, o->in2, m3);
1801 tcg_temp_free_i32(m3);
21a8eced 1802 return DISAS_NEXT;
2112bf1b
RH
1803}
1804
21a8eced 1805static DisasJumpType op_cdlgb(DisasContext *s, DisasOps *o)
2112bf1b
RH
1806{
1807 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1808 gen_helper_cdlgb(o->out, cpu_env, o->in2, m3);
1809 tcg_temp_free_i32(m3);
21a8eced 1810 return DISAS_NEXT;
2112bf1b
RH
1811}
1812
21a8eced 1813static DisasJumpType op_cxlgb(DisasContext *s, DisasOps *o)
2112bf1b
RH
1814{
1815 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1816 gen_helper_cxlgb(o->out, cpu_env, o->in2, m3);
1817 tcg_temp_free_i32(m3);
683bb9a8 1818 return_low128(o->out2);
21a8eced 1819 return DISAS_NEXT;
683bb9a8
RH
1820}
1821
21a8eced 1822static DisasJumpType op_cksm(DisasContext *s, DisasOps *o)
374724f9
RH
1823{
1824 int r2 = get_field(s->fields, r2);
1825 TCGv_i64 len = tcg_temp_new_i64();
1826
374724f9
RH
1827 gen_helper_cksm(len, cpu_env, o->in1, o->in2, regs[r2 + 1]);
1828 set_cc_static(s);
1829 return_low128(o->out);
1830
1831 tcg_gen_add_i64(regs[r2], regs[r2], len);
1832 tcg_gen_sub_i64(regs[r2 + 1], regs[r2 + 1], len);
1833 tcg_temp_free_i64(len);
1834
21a8eced 1835 return DISAS_NEXT;
374724f9
RH
1836}
1837
21a8eced 1838static DisasJumpType op_clc(DisasContext *s, DisasOps *o)
4f7403d5
RH
1839{
1840 int l = get_field(s->fields, l1);
1841 TCGv_i32 vl;
1842
1843 switch (l + 1) {
1844 case 1:
1845 tcg_gen_qemu_ld8u(cc_src, o->addr1, get_mem_index(s));
1846 tcg_gen_qemu_ld8u(cc_dst, o->in2, get_mem_index(s));
1847 break;
1848 case 2:
1849 tcg_gen_qemu_ld16u(cc_src, o->addr1, get_mem_index(s));
1850 tcg_gen_qemu_ld16u(cc_dst, o->in2, get_mem_index(s));
1851 break;
1852 case 4:
1853 tcg_gen_qemu_ld32u(cc_src, o->addr1, get_mem_index(s));
1854 tcg_gen_qemu_ld32u(cc_dst, o->in2, get_mem_index(s));
1855 break;
1856 case 8:
1857 tcg_gen_qemu_ld64(cc_src, o->addr1, get_mem_index(s));
1858 tcg_gen_qemu_ld64(cc_dst, o->in2, get_mem_index(s));
1859 break;
1860 default:
4f7403d5
RH
1861 vl = tcg_const_i32(l);
1862 gen_helper_clc(cc_op, cpu_env, vl, o->addr1, o->in2);
1863 tcg_temp_free_i32(vl);
1864 set_cc_static(s);
21a8eced 1865 return DISAS_NEXT;
4f7403d5
RH
1866 }
1867 gen_op_update2_cc_i64(s, CC_OP_LTUGTU_64, cc_src, cc_dst);
21a8eced 1868 return DISAS_NEXT;
4f7403d5
RH
1869}
1870
21a8eced 1871static DisasJumpType op_clcl(DisasContext *s, DisasOps *o)
5c2b48a8
AJ
1872{
1873 int r1 = get_field(s->fields, r1);
1874 int r2 = get_field(s->fields, r2);
1875 TCGv_i32 t1, t2;
1876
1877 /* r1 and r2 must be even. */
1878 if (r1 & 1 || r2 & 1) {
1879 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 1880 return DISAS_NORETURN;
5c2b48a8
AJ
1881 }
1882
1883 t1 = tcg_const_i32(r1);
1884 t2 = tcg_const_i32(r2);
1885 gen_helper_clcl(cc_op, cpu_env, t1, t2);
1886 tcg_temp_free_i32(t1);
1887 tcg_temp_free_i32(t2);
1888 set_cc_static(s);
21a8eced 1889 return DISAS_NEXT;
5c2b48a8
AJ
1890}
1891
21a8eced 1892static DisasJumpType op_clcle(DisasContext *s, DisasOps *o)
eb66e6a9 1893{
84aa07f1
AJ
1894 int r1 = get_field(s->fields, r1);
1895 int r3 = get_field(s->fields, r3);
1896 TCGv_i32 t1, t3;
1897
1898 /* r1 and r3 must be even. */
1899 if (r1 & 1 || r3 & 1) {
1900 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 1901 return DISAS_NORETURN;
84aa07f1
AJ
1902 }
1903
1904 t1 = tcg_const_i32(r1);
1905 t3 = tcg_const_i32(r3);
1906 gen_helper_clcle(cc_op, cpu_env, t1, o->in2, t3);
1907 tcg_temp_free_i32(t1);
1908 tcg_temp_free_i32(t3);
eb66e6a9 1909 set_cc_static(s);
21a8eced 1910 return DISAS_NEXT;
eb66e6a9
RH
1911}
1912
21a8eced 1913static DisasJumpType op_clclu(DisasContext *s, DisasOps *o)
31006af3
AJ
1914{
1915 int r1 = get_field(s->fields, r1);
1916 int r3 = get_field(s->fields, r3);
1917 TCGv_i32 t1, t3;
1918
1919 /* r1 and r3 must be even. */
1920 if (r1 & 1 || r3 & 1) {
1921 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 1922 return DISAS_NORETURN;
31006af3
AJ
1923 }
1924
1925 t1 = tcg_const_i32(r1);
1926 t3 = tcg_const_i32(r3);
1927 gen_helper_clclu(cc_op, cpu_env, t1, o->in2, t3);
1928 tcg_temp_free_i32(t1);
1929 tcg_temp_free_i32(t3);
1930 set_cc_static(s);
21a8eced 1931 return DISAS_NEXT;
31006af3
AJ
1932}
1933
21a8eced 1934static DisasJumpType op_clm(DisasContext *s, DisasOps *o)
32a44d58
RH
1935{
1936 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1937 TCGv_i32 t1 = tcg_temp_new_i32();
ecc7b3aa 1938 tcg_gen_extrl_i64_i32(t1, o->in1);
32a44d58
RH
1939 gen_helper_clm(cc_op, cpu_env, t1, m3, o->in2);
1940 set_cc_static(s);
1941 tcg_temp_free_i32(t1);
1942 tcg_temp_free_i32(m3);
21a8eced 1943 return DISAS_NEXT;
32a44d58
RH
1944}
1945
21a8eced 1946static DisasJumpType op_clst(DisasContext *s, DisasOps *o)
aa31bf60 1947{
aa31bf60
RH
1948 gen_helper_clst(o->in1, cpu_env, regs[0], o->in1, o->in2);
1949 set_cc_static(s);
1950 return_low128(o->in2);
21a8eced 1951 return DISAS_NEXT;
aa31bf60
RH
1952}
1953
21a8eced 1954static DisasJumpType op_cps(DisasContext *s, DisasOps *o)
2db014b5
RH
1955{
1956 TCGv_i64 t = tcg_temp_new_i64();
1957 tcg_gen_andi_i64(t, o->in1, 0x8000000000000000ull);
1958 tcg_gen_andi_i64(o->out, o->in2, 0x7fffffffffffffffull);
1959 tcg_gen_or_i64(o->out, o->out, t);
1960 tcg_temp_free_i64(t);
21a8eced 1961 return DISAS_NEXT;
2db014b5
RH
1962}
1963
21a8eced 1964static DisasJumpType op_cs(DisasContext *s, DisasOps *o)
f3de39c4 1965{
b7886de3
RH
1966 int d2 = get_field(s->fields, d2);
1967 int b2 = get_field(s->fields, b2);
303a9ab8 1968 TCGv_i64 addr, cc;
b7886de3
RH
1969
1970 /* Note that in1 = R3 (new value) and
1971 in2 = (zero-extended) R1 (expected value). */
1972
b7886de3 1973 addr = get_address(s, 0, b2, d2);
303a9ab8
RH
1974 tcg_gen_atomic_cmpxchg_i64(o->out, addr, o->in2, o->in1,
1975 get_mem_index(s), s->insn->data | MO_ALIGN);
1976 tcg_temp_free_i64(addr);
b7886de3
RH
1977
1978 /* Are the memory and expected values (un)equal? Note that this setcond
1979 produces the output CC value, thus the NE sense of the test. */
1980 cc = tcg_temp_new_i64();
1981 tcg_gen_setcond_i64(TCG_COND_NE, cc, o->in2, o->out);
ecc7b3aa 1982 tcg_gen_extrl_i64_i32(cc_op, cc);
b7886de3 1983 tcg_temp_free_i64(cc);
f3de39c4 1984 set_cc_static(s);
303a9ab8 1985
21a8eced 1986 return DISAS_NEXT;
f3de39c4
RH
1987}
1988
21a8eced 1989static DisasJumpType op_cdsg(DisasContext *s, DisasOps *o)
f3de39c4 1990{
b7886de3 1991 int r1 = get_field(s->fields, r1);
f3de39c4 1992 int r3 = get_field(s->fields, r3);
b7886de3
RH
1993 int d2 = get_field(s->fields, d2);
1994 int b2 = get_field(s->fields, b2);
303a9ab8
RH
1995 TCGv_i64 addr;
1996 TCGv_i32 t_r1, t_r3;
b7886de3
RH
1997
1998 /* Note that R1:R1+1 = expected value and R3:R3+1 = new value. */
303a9ab8
RH
1999 addr = get_address(s, 0, b2, d2);
2000 t_r1 = tcg_const_i32(r1);
2001 t_r3 = tcg_const_i32(r3);
eccf741a 2002 if (tb_cflags(s->base.tb) & CF_PARALLEL) {
6476615d
EC
2003 gen_helper_cdsg_parallel(cpu_env, addr, t_r1, t_r3);
2004 } else {
2005 gen_helper_cdsg(cpu_env, addr, t_r1, t_r3);
2006 }
303a9ab8
RH
2007 tcg_temp_free_i64(addr);
2008 tcg_temp_free_i32(t_r1);
2009 tcg_temp_free_i32(t_r3);
b7886de3 2010
f3de39c4 2011 set_cc_static(s);
21a8eced 2012 return DISAS_NEXT;
f3de39c4
RH
2013}
2014
21a8eced 2015static DisasJumpType op_csst(DisasContext *s, DisasOps *o)
c67ba303
RH
2016{
2017 int r3 = get_field(s->fields, r3);
2018 TCGv_i32 t_r3 = tcg_const_i32(r3);
2019
eccf741a 2020 if (tb_cflags(s->base.tb) & CF_PARALLEL) {
6476615d
EC
2021 gen_helper_csst_parallel(cc_op, cpu_env, t_r3, o->in1, o->in2);
2022 } else {
2023 gen_helper_csst(cc_op, cpu_env, t_r3, o->in1, o->in2);
2024 }
c67ba303
RH
2025 tcg_temp_free_i32(t_r3);
2026
2027 set_cc_static(s);
21a8eced 2028 return DISAS_NEXT;
c67ba303
RH
2029}
2030
3d596f49 2031#ifndef CONFIG_USER_ONLY
21a8eced 2032static DisasJumpType op_csp(DisasContext *s, DisasOps *o)
3d596f49 2033{
31a18b45
RH
2034 TCGMemOp mop = s->insn->data;
2035 TCGv_i64 addr, old, cc;
2036 TCGLabel *lab = gen_new_label();
2037
2038 /* Note that in1 = R1 (zero-extended expected value),
2039 out = R1 (original reg), out2 = R1+1 (new value). */
2040
3d596f49 2041 check_privileged(s);
31a18b45
RH
2042 addr = tcg_temp_new_i64();
2043 old = tcg_temp_new_i64();
2044 tcg_gen_andi_i64(addr, o->in2, -1ULL << (mop & MO_SIZE));
2045 tcg_gen_atomic_cmpxchg_i64(old, addr, o->in1, o->out2,
2046 get_mem_index(s), mop | MO_ALIGN);
2047 tcg_temp_free_i64(addr);
2048
2049 /* Are the memory and expected values (un)equal? */
2050 cc = tcg_temp_new_i64();
2051 tcg_gen_setcond_i64(TCG_COND_NE, cc, o->in1, old);
2052 tcg_gen_extrl_i64_i32(cc_op, cc);
2053
2054 /* Write back the output now, so that it happens before the
2055 following branch, so that we don't need local temps. */
2056 if ((mop & MO_SIZE) == MO_32) {
2057 tcg_gen_deposit_i64(o->out, o->out, old, 0, 32);
2058 } else {
2059 tcg_gen_mov_i64(o->out, old);
2060 }
2061 tcg_temp_free_i64(old);
2062
2063 /* If the comparison was equal, and the LSB of R2 was set,
2064 then we need to flush the TLB (for all cpus). */
2065 tcg_gen_xori_i64(cc, cc, 1);
2066 tcg_gen_and_i64(cc, cc, o->in2);
2067 tcg_gen_brcondi_i64(TCG_COND_EQ, cc, 0, lab);
2068 tcg_temp_free_i64(cc);
2069
2070 gen_helper_purge(cpu_env);
2071 gen_set_label(lab);
2072
21a8eced 2073 return DISAS_NEXT;
3d596f49
RH
2074}
2075#endif
2076
21a8eced 2077static DisasJumpType op_cvd(DisasContext *s, DisasOps *o)
c49daa51
RH
2078{
2079 TCGv_i64 t1 = tcg_temp_new_i64();
2080 TCGv_i32 t2 = tcg_temp_new_i32();
ecc7b3aa 2081 tcg_gen_extrl_i64_i32(t2, o->in1);
c49daa51
RH
2082 gen_helper_cvd(t1, t2);
2083 tcg_temp_free_i32(t2);
2084 tcg_gen_qemu_st64(t1, o->in2, get_mem_index(s));
2085 tcg_temp_free_i64(t1);
21a8eced 2086 return DISAS_NEXT;
c49daa51
RH
2087}
2088
21a8eced 2089static DisasJumpType op_ct(DisasContext *s, DisasOps *o)
1c268751
RH
2090{
2091 int m3 = get_field(s->fields, m3);
42a268c2 2092 TCGLabel *lab = gen_new_label();
1c268751
RH
2093 TCGCond c;
2094
de379661 2095 c = tcg_invert_cond(ltgt_cond[m3]);
1c268751
RH
2096 if (s->insn->data) {
2097 c = tcg_unsigned_cond(c);
2098 }
2099 tcg_gen_brcond_i64(c, o->in1, o->in2, lab);
2100
1c268751 2101 /* Trap. */
782a8479 2102 gen_trap(s);
1c268751
RH
2103
2104 gen_set_label(lab);
21a8eced 2105 return DISAS_NEXT;
1c268751
RH
2106}
2107
21a8eced 2108static DisasJumpType op_cuXX(DisasContext *s, DisasOps *o)
941ef3db
RH
2109{
2110 int m3 = get_field(s->fields, m3);
2111 int r1 = get_field(s->fields, r1);
2112 int r2 = get_field(s->fields, r2);
2113 TCGv_i32 tr1, tr2, chk;
2114
2115 /* R1 and R2 must both be even. */
2116 if ((r1 | r2) & 1) {
2117 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 2118 return DISAS_NORETURN;
941ef3db
RH
2119 }
2120 if (!s390_has_feat(S390_FEAT_ETF3_ENH)) {
2121 m3 = 0;
2122 }
2123
2124 tr1 = tcg_const_i32(r1);
2125 tr2 = tcg_const_i32(r2);
2126 chk = tcg_const_i32(m3);
2127
2128 switch (s->insn->data) {
2129 case 12:
2130 gen_helper_cu12(cc_op, cpu_env, tr1, tr2, chk);
2131 break;
2132 case 14:
2133 gen_helper_cu14(cc_op, cpu_env, tr1, tr2, chk);
2134 break;
2135 case 21:
2136 gen_helper_cu21(cc_op, cpu_env, tr1, tr2, chk);
2137 break;
2138 case 24:
2139 gen_helper_cu24(cc_op, cpu_env, tr1, tr2, chk);
2140 break;
2141 case 41:
2142 gen_helper_cu41(cc_op, cpu_env, tr1, tr2, chk);
2143 break;
2144 case 42:
2145 gen_helper_cu42(cc_op, cpu_env, tr1, tr2, chk);
2146 break;
2147 default:
2148 g_assert_not_reached();
2149 }
2150
2151 tcg_temp_free_i32(tr1);
2152 tcg_temp_free_i32(tr2);
2153 tcg_temp_free_i32(chk);
2154 set_cc_static(s);
21a8eced 2155 return DISAS_NEXT;
941ef3db
RH
2156}
2157
972e35b9 2158#ifndef CONFIG_USER_ONLY
21a8eced 2159static DisasJumpType op_diag(DisasContext *s, DisasOps *o)
972e35b9 2160{
8df7eef3
AJ
2161 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2162 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
2163 TCGv_i32 func_code = tcg_const_i32(get_field(s->fields, i2));
972e35b9
RH
2164
2165 check_privileged(s);
8df7eef3
AJ
2166 gen_helper_diag(cpu_env, r1, r3, func_code);
2167
2168 tcg_temp_free_i32(func_code);
2169 tcg_temp_free_i32(r3);
2170 tcg_temp_free_i32(r1);
21a8eced 2171 return DISAS_NEXT;
972e35b9
RH
2172}
2173#endif
2174
21a8eced 2175static DisasJumpType op_divs32(DisasContext *s, DisasOps *o)
891452e5
RH
2176{
2177 gen_helper_divs32(o->out2, cpu_env, o->in1, o->in2);
2178 return_low128(o->out);
21a8eced 2179 return DISAS_NEXT;
891452e5
RH
2180}
2181
21a8eced 2182static DisasJumpType op_divu32(DisasContext *s, DisasOps *o)
891452e5
RH
2183{
2184 gen_helper_divu32(o->out2, cpu_env, o->in1, o->in2);
2185 return_low128(o->out);
21a8eced 2186 return DISAS_NEXT;
891452e5
RH
2187}
2188
21a8eced 2189static DisasJumpType op_divs64(DisasContext *s, DisasOps *o)
891452e5
RH
2190{
2191 gen_helper_divs64(o->out2, cpu_env, o->in1, o->in2);
2192 return_low128(o->out);
21a8eced 2193 return DISAS_NEXT;
891452e5
RH
2194}
2195
21a8eced 2196static DisasJumpType op_divu64(DisasContext *s, DisasOps *o)
891452e5
RH
2197{
2198 gen_helper_divu64(o->out2, cpu_env, o->out, o->out2, o->in2);
2199 return_low128(o->out);
21a8eced 2200 return DISAS_NEXT;
891452e5
RH
2201}
2202
21a8eced 2203static DisasJumpType op_deb(DisasContext *s, DisasOps *o)
f08a5c31
RH
2204{
2205 gen_helper_deb(o->out, cpu_env, o->in1, o->in2);
21a8eced 2206 return DISAS_NEXT;
f08a5c31
RH
2207}
2208
21a8eced 2209static DisasJumpType op_ddb(DisasContext *s, DisasOps *o)
f08a5c31
RH
2210{
2211 gen_helper_ddb(o->out, cpu_env, o->in1, o->in2);
21a8eced 2212 return DISAS_NEXT;
f08a5c31
RH
2213}
2214
21a8eced 2215static DisasJumpType op_dxb(DisasContext *s, DisasOps *o)
f08a5c31
RH
2216{
2217 gen_helper_dxb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2);
2218 return_low128(o->out2);
21a8eced 2219 return DISAS_NEXT;
f08a5c31
RH
2220}
2221
21a8eced 2222static DisasJumpType op_ear(DisasContext *s, DisasOps *o)
d62a4c97
RH
2223{
2224 int r2 = get_field(s->fields, r2);
2225 tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, aregs[r2]));
21a8eced 2226 return DISAS_NEXT;
d62a4c97
RH
2227}
2228
21a8eced 2229static DisasJumpType op_ecag(DisasContext *s, DisasOps *o)
0774710f
RH
2230{
2231 /* No cache information provided. */
2232 tcg_gen_movi_i64(o->out, -1);
21a8eced 2233 return DISAS_NEXT;
0774710f
RH
2234}
2235
21a8eced 2236static DisasJumpType op_efpc(DisasContext *s, DisasOps *o)
ea20490f
RH
2237{
2238 tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, fpc));
21a8eced 2239 return DISAS_NEXT;
ea20490f
RH
2240}
2241
21a8eced 2242static DisasJumpType op_epsw(DisasContext *s, DisasOps *o)
e30a9d3f
RH
2243{
2244 int r1 = get_field(s->fields, r1);
2245 int r2 = get_field(s->fields, r2);
2246 TCGv_i64 t = tcg_temp_new_i64();
2247
2248 /* Note the "subsequently" in the PoO, which implies a defined result
2249 if r1 == r2. Thus we cannot defer these writes to an output hook. */
2250 tcg_gen_shri_i64(t, psw_mask, 32);
2251 store_reg32_i64(r1, t);
2252 if (r2 != 0) {
2253 store_reg32_i64(r2, psw_mask);
2254 }
2255
2256 tcg_temp_free_i64(t);
21a8eced 2257 return DISAS_NEXT;
e30a9d3f
RH
2258}
2259
21a8eced 2260static DisasJumpType op_ex(DisasContext *s, DisasOps *o)
6e764e97 2261{
a72da8b7 2262 int r1 = get_field(s->fields, r1);
83500793 2263 TCGv_i32 ilen;
a72da8b7 2264 TCGv_i64 v1;
6e764e97 2265
303c681a
RH
2266 /* Nested EXECUTE is not allowed. */
2267 if (unlikely(s->ex_value)) {
2268 gen_program_exception(s, PGM_EXECUTE);
21a8eced 2269 return DISAS_NORETURN;
303c681a
RH
2270 }
2271
6e764e97 2272 update_psw_addr(s);
303c681a 2273 update_cc_op(s);
6e764e97 2274
a72da8b7
RH
2275 if (r1 == 0) {
2276 v1 = tcg_const_i64(0);
2277 } else {
2278 v1 = regs[r1];
2279 }
2280
99e57856 2281 ilen = tcg_const_i32(s->ilen);
a72da8b7 2282 gen_helper_ex(cpu_env, ilen, v1, o->in2);
83500793 2283 tcg_temp_free_i32(ilen);
6e764e97 2284
a72da8b7
RH
2285 if (r1 == 0) {
2286 tcg_temp_free_i64(v1);
2287 }
2288
21a8eced 2289 return DISAS_PC_CC_UPDATED;
6e764e97
RH
2290}
2291
21a8eced 2292static DisasJumpType op_fieb(DisasContext *s, DisasOps *o)
ed0bcece
AJ
2293{
2294 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
2295 gen_helper_fieb(o->out, cpu_env, o->in2, m3);
2296 tcg_temp_free_i32(m3);
21a8eced 2297 return DISAS_NEXT;
ed0bcece
AJ
2298}
2299
21a8eced 2300static DisasJumpType op_fidb(DisasContext *s, DisasOps *o)
ed0bcece
AJ
2301{
2302 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
2303 gen_helper_fidb(o->out, cpu_env, o->in2, m3);
2304 tcg_temp_free_i32(m3);
21a8eced 2305 return DISAS_NEXT;
ed0bcece
AJ
2306}
2307
21a8eced 2308static DisasJumpType op_fixb(DisasContext *s, DisasOps *o)
ed0bcece
AJ
2309{
2310 TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
2311 gen_helper_fixb(o->out, cpu_env, o->in1, o->in2, m3);
2312 return_low128(o->out2);
2313 tcg_temp_free_i32(m3);
21a8eced 2314 return DISAS_NEXT;
ed0bcece
AJ
2315}
2316
21a8eced 2317static DisasJumpType op_flogr(DisasContext *s, DisasOps *o)
102bf2c6
RH
2318{
2319 /* We'll use the original input for cc computation, since we get to
2320 compare that against 0, which ought to be better than comparing
2321 the real output against 64. It also lets cc_dst be a convenient
2322 temporary during our computation. */
2323 gen_op_update1_cc_i64(s, CC_OP_FLOGR, o->in2);
2324
2325 /* R1 = IN ? CLZ(IN) : 64. */
0f9712b1 2326 tcg_gen_clzi_i64(o->out, o->in2, 64);
102bf2c6
RH
2327
2328 /* R1+1 = IN & ~(found bit). Note that we may attempt to shift this
2329 value by 64, which is undefined. But since the shift is 64 iff the
2330 input is zero, we still get the correct result after and'ing. */
2331 tcg_gen_movi_i64(o->out2, 0x8000000000000000ull);
2332 tcg_gen_shr_i64(o->out2, o->out2, o->out);
2333 tcg_gen_andc_i64(o->out2, cc_dst, o->out2);
21a8eced 2334 return DISAS_NEXT;
102bf2c6
RH
2335}
2336
21a8eced 2337static DisasJumpType op_icm(DisasContext *s, DisasOps *o)
58a9e35b
RH
2338{
2339 int m3 = get_field(s->fields, m3);
2340 int pos, len, base = s->insn->data;
2341 TCGv_i64 tmp = tcg_temp_new_i64();
2342 uint64_t ccm;
2343
2344 switch (m3) {
2345 case 0xf:
2346 /* Effectively a 32-bit load. */
2347 tcg_gen_qemu_ld32u(tmp, o->in2, get_mem_index(s));
2348 len = 32;
2349 goto one_insert;
2350
2351 case 0xc:
2352 case 0x6:
2353 case 0x3:
2354 /* Effectively a 16-bit load. */
2355 tcg_gen_qemu_ld16u(tmp, o->in2, get_mem_index(s));
2356 len = 16;
2357 goto one_insert;
2358
2359 case 0x8:
2360 case 0x4:
2361 case 0x2:
2362 case 0x1:
2363 /* Effectively an 8-bit load. */
2364 tcg_gen_qemu_ld8u(tmp, o->in2, get_mem_index(s));
2365 len = 8;
2366 goto one_insert;
2367
2368 one_insert:
2369 pos = base + ctz32(m3) * 8;
2370 tcg_gen_deposit_i64(o->out, o->out, tmp, pos, len);
2371 ccm = ((1ull << len) - 1) << pos;
2372 break;
2373
2374 default:
2375 /* This is going to be a sequence of loads and inserts. */
2376 pos = base + 32 - 8;
2377 ccm = 0;
2378 while (m3) {
2379 if (m3 & 0x8) {
2380 tcg_gen_qemu_ld8u(tmp, o->in2, get_mem_index(s));
2381 tcg_gen_addi_i64(o->in2, o->in2, 1);
2382 tcg_gen_deposit_i64(o->out, o->out, tmp, pos, 8);
2383 ccm |= 0xff << pos;
2384 }
2385 m3 = (m3 << 1) & 0xf;
2386 pos -= 8;
2387 }
2388 break;
2389 }
2390
2391 tcg_gen_movi_i64(tmp, ccm);
2392 gen_op_update2_cc_i64(s, CC_OP_ICM, tmp, o->out);
2393 tcg_temp_free_i64(tmp);
21a8eced 2394 return DISAS_NEXT;
58a9e35b
RH
2395}
2396
21a8eced 2397static DisasJumpType op_insi(DisasContext *s, DisasOps *o)
facfc864
RH
2398{
2399 int shift = s->insn->data & 0xff;
2400 int size = s->insn->data >> 8;
2401 tcg_gen_deposit_i64(o->out, o->in1, o->in2, shift, size);
21a8eced 2402 return DISAS_NEXT;
facfc864
RH
2403}
2404
21a8eced 2405static DisasJumpType op_ipm(DisasContext *s, DisasOps *o)
6e2704e7
RH
2406{
2407 TCGv_i64 t1;
2408
2409 gen_op_calc_cc(s);
2410 tcg_gen_andi_i64(o->out, o->out, ~0xff000000ull);
2411
2412 t1 = tcg_temp_new_i64();
2413 tcg_gen_shli_i64(t1, psw_mask, 20);
2414 tcg_gen_shri_i64(t1, t1, 36);
2415 tcg_gen_or_i64(o->out, o->out, t1);
2416
2417 tcg_gen_extu_i32_i64(t1, cc_op);
2418 tcg_gen_shli_i64(t1, t1, 28);
2419 tcg_gen_or_i64(o->out, o->out, t1);
2420 tcg_temp_free_i64(t1);
21a8eced 2421 return DISAS_NEXT;
6e2704e7
RH
2422}
2423
cfef53e3 2424#ifndef CONFIG_USER_ONLY
21a8eced 2425static DisasJumpType op_idte(DisasContext *s, DisasOps *o)
be7f28de
DH
2426{
2427 TCGv_i32 m4;
2428
2429 check_privileged(s);
2430 if (s390_has_feat(S390_FEAT_LOCAL_TLB_CLEARING)) {
2431 m4 = tcg_const_i32(get_field(s->fields, m4));
2432 } else {
2433 m4 = tcg_const_i32(0);
2434 }
2435 gen_helper_idte(cpu_env, o->in1, o->in2, m4);
2436 tcg_temp_free_i32(m4);
21a8eced 2437 return DISAS_NEXT;
be7f28de
DH
2438}
2439
21a8eced 2440static DisasJumpType op_ipte(DisasContext *s, DisasOps *o)
cfef53e3 2441{
1f58720c
AJ
2442 TCGv_i32 m4;
2443
cfef53e3 2444 check_privileged(s);
faf1c63d
DH
2445 if (s390_has_feat(S390_FEAT_LOCAL_TLB_CLEARING)) {
2446 m4 = tcg_const_i32(get_field(s->fields, m4));
2447 } else {
2448 m4 = tcg_const_i32(0);
2449 }
1f58720c
AJ
2450 gen_helper_ipte(cpu_env, o->in1, o->in2, m4);
2451 tcg_temp_free_i32(m4);
21a8eced 2452 return DISAS_NEXT;
cfef53e3 2453}
8026417c 2454
21a8eced 2455static DisasJumpType op_iske(DisasContext *s, DisasOps *o)
8026417c
RH
2456{
2457 check_privileged(s);
2458 gen_helper_iske(o->out, cpu_env, o->in2);
21a8eced 2459 return DISAS_NEXT;
8026417c 2460}
cfef53e3
RH
2461#endif
2462
21a8eced 2463static DisasJumpType op_msa(DisasContext *s, DisasOps *o)
7705c750
DH
2464{
2465 int r1 = have_field(s->fields, r1) ? get_field(s->fields, r1) : 0;
2466 int r2 = have_field(s->fields, r2) ? get_field(s->fields, r2) : 0;
2467 int r3 = have_field(s->fields, r3) ? get_field(s->fields, r3) : 0;
2468 TCGv_i32 t_r1, t_r2, t_r3, type;
2469
2470 switch (s->insn->data) {
2471 case S390_FEAT_TYPE_KMCTR:
2472 if (r3 & 1 || !r3) {
2473 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 2474 return DISAS_NORETURN;
7705c750
DH
2475 }
2476 /* FALL THROUGH */
2477 case S390_FEAT_TYPE_PPNO:
2478 case S390_FEAT_TYPE_KMF:
2479 case S390_FEAT_TYPE_KMC:
2480 case S390_FEAT_TYPE_KMO:
2481 case S390_FEAT_TYPE_KM:
2482 if (r1 & 1 || !r1) {
2483 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 2484 return DISAS_NORETURN;
7705c750
DH
2485 }
2486 /* FALL THROUGH */
2487 case S390_FEAT_TYPE_KMAC:
2488 case S390_FEAT_TYPE_KIMD:
2489 case S390_FEAT_TYPE_KLMD:
2490 if (r2 & 1 || !r2) {
2491 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 2492 return DISAS_NORETURN;
7705c750
DH
2493 }
2494 /* FALL THROUGH */
2495 case S390_FEAT_TYPE_PCKMO:
2496 case S390_FEAT_TYPE_PCC:
2497 break;
2498 default:
2499 g_assert_not_reached();
2500 };
2501
2502 t_r1 = tcg_const_i32(r1);
2503 t_r2 = tcg_const_i32(r2);
2504 t_r3 = tcg_const_i32(r3);
2505 type = tcg_const_i32(s->insn->data);
2506 gen_helper_msa(cc_op, cpu_env, t_r1, t_r2, t_r3, type);
2507 set_cc_static(s);
2508 tcg_temp_free_i32(t_r1);
2509 tcg_temp_free_i32(t_r2);
2510 tcg_temp_free_i32(t_r3);
2511 tcg_temp_free_i32(type);
21a8eced 2512 return DISAS_NEXT;
7705c750
DH
2513}
2514
21a8eced 2515static DisasJumpType op_keb(DisasContext *s, DisasOps *o)
9c8be598
AJ
2516{
2517 gen_helper_keb(cc_op, cpu_env, o->in1, o->in2);
2518 set_cc_static(s);
21a8eced 2519 return DISAS_NEXT;
9c8be598
AJ
2520}
2521
21a8eced 2522static DisasJumpType op_kdb(DisasContext *s, DisasOps *o)
9c8be598
AJ
2523{
2524 gen_helper_kdb(cc_op, cpu_env, o->in1, o->in2);
2525 set_cc_static(s);
21a8eced 2526 return DISAS_NEXT;
9c8be598
AJ
2527}
2528
21a8eced 2529static DisasJumpType op_kxb(DisasContext *s, DisasOps *o)
9c8be598
AJ
2530{
2531 gen_helper_kxb(cc_op, cpu_env, o->out, o->out2, o->in1, o->in2);
2532 set_cc_static(s);
21a8eced 2533 return DISAS_NEXT;
9c8be598
AJ
2534}
2535
21a8eced 2536static DisasJumpType op_laa(DisasContext *s, DisasOps *o)
4dba4d6f
RH
2537{
2538 /* The real output is indeed the original value in memory;
2539 recompute the addition for the computation of CC. */
2540 tcg_gen_atomic_fetch_add_i64(o->in2, o->in2, o->in1, get_mem_index(s),
2541 s->insn->data | MO_ALIGN);
2542 /* However, we need to recompute the addition for setting CC. */
2543 tcg_gen_add_i64(o->out, o->in1, o->in2);
21a8eced 2544 return DISAS_NEXT;
4dba4d6f
RH
2545}
2546
21a8eced 2547static DisasJumpType op_lan(DisasContext *s, DisasOps *o)
4dba4d6f
RH
2548{
2549 /* The real output is indeed the original value in memory;
2550 recompute the addition for the computation of CC. */
2551 tcg_gen_atomic_fetch_and_i64(o->in2, o->in2, o->in1, get_mem_index(s),
2552 s->insn->data | MO_ALIGN);
2553 /* However, we need to recompute the operation for setting CC. */
2554 tcg_gen_and_i64(o->out, o->in1, o->in2);
21a8eced 2555 return DISAS_NEXT;
4dba4d6f
RH
2556}
2557
21a8eced 2558static DisasJumpType op_lao(DisasContext *s, DisasOps *o)
4dba4d6f
RH
2559{
2560 /* The real output is indeed the original value in memory;
2561 recompute the addition for the computation of CC. */
2562 tcg_gen_atomic_fetch_or_i64(o->in2, o->in2, o->in1, get_mem_index(s),
2563 s->insn->data | MO_ALIGN);
2564 /* However, we need to recompute the operation for setting CC. */
2565 tcg_gen_or_i64(o->out, o->in1, o->in2);
21a8eced 2566 return DISAS_NEXT;
4dba4d6f
RH
2567}
2568
21a8eced 2569static DisasJumpType op_lax(DisasContext *s, DisasOps *o)
4dba4d6f
RH
2570{
2571 /* The real output is indeed the original value in memory;
2572 recompute the addition for the computation of CC. */
2573 tcg_gen_atomic_fetch_xor_i64(o->in2, o->in2, o->in1, get_mem_index(s),
2574 s->insn->data | MO_ALIGN);
2575 /* However, we need to recompute the operation for setting CC. */
2576 tcg_gen_xor_i64(o->out, o->in1, o->in2);
21a8eced 2577 return DISAS_NEXT;
4dba4d6f
RH
2578}
2579
21a8eced 2580static DisasJumpType op_ldeb(DisasContext *s, DisasOps *o)
587626f8
RH
2581{
2582 gen_helper_ldeb(o->out, cpu_env, o->in2);
21a8eced 2583 return DISAS_NEXT;
587626f8
RH
2584}
2585
21a8eced 2586static DisasJumpType op_ledb(DisasContext *s, DisasOps *o)
587626f8
RH
2587{
2588 gen_helper_ledb(o->out, cpu_env, o->in2);
21a8eced 2589 return DISAS_NEXT;
587626f8
RH
2590}
2591
21a8eced 2592static DisasJumpType op_ldxb(DisasContext *s, DisasOps *o)
587626f8
RH
2593{
2594 gen_helper_ldxb(o->out, cpu_env, o->in1, o->in2);
21a8eced 2595 return DISAS_NEXT;
587626f8
RH
2596}
2597
21a8eced 2598static DisasJumpType op_lexb(DisasContext *s, DisasOps *o)
587626f8
RH
2599{
2600 gen_helper_lexb(o->out, cpu_env, o->in1, o->in2);
21a8eced 2601 return DISAS_NEXT;
587626f8
RH
2602}
2603
21a8eced 2604static DisasJumpType op_lxdb(DisasContext *s, DisasOps *o)
587626f8
RH
2605{
2606 gen_helper_lxdb(o->out, cpu_env, o->in2);
2607 return_low128(o->out2);
21a8eced 2608 return DISAS_NEXT;
587626f8
RH
2609}
2610
21a8eced 2611static DisasJumpType op_lxeb(DisasContext *s, DisasOps *o)
587626f8
RH
2612{
2613 gen_helper_lxeb(o->out, cpu_env, o->in2);
2614 return_low128(o->out2);
21a8eced 2615 return DISAS_NEXT;
587626f8
RH
2616}
2617
21a8eced 2618static DisasJumpType op_llgt(DisasContext *s, DisasOps *o)
7691c23b
RH
2619{
2620 tcg_gen_andi_i64(o->out, o->in2, 0x7fffffff);
21a8eced 2621 return DISAS_NEXT;
7691c23b
RH
2622}
2623
21a8eced 2624static DisasJumpType op_ld8s(DisasContext *s, DisasOps *o)
c698d876
RH
2625{
2626 tcg_gen_qemu_ld8s(o->out, o->in2, get_mem_index(s));
21a8eced 2627 return DISAS_NEXT;
c698d876
RH
2628}
2629
21a8eced 2630static DisasJumpType op_ld8u(DisasContext *s, DisasOps *o)
c698d876
RH
2631{
2632 tcg_gen_qemu_ld8u(o->out, o->in2, get_mem_index(s));
21a8eced 2633 return DISAS_NEXT;
c698d876
RH
2634}
2635
21a8eced 2636static DisasJumpType op_ld16s(DisasContext *s, DisasOps *o)
c698d876
RH
2637{
2638 tcg_gen_qemu_ld16s(o->out, o->in2, get_mem_index(s));
21a8eced 2639 return DISAS_NEXT;
c698d876
RH
2640}
2641
21a8eced 2642static DisasJumpType op_ld16u(DisasContext *s, DisasOps *o)
c698d876
RH
2643{
2644 tcg_gen_qemu_ld16u(o->out, o->in2, get_mem_index(s));
21a8eced 2645 return DISAS_NEXT;
c698d876
RH
2646}
2647
21a8eced 2648static DisasJumpType op_ld32s(DisasContext *s, DisasOps *o)
22c37a08
RH
2649{
2650 tcg_gen_qemu_ld32s(o->out, o->in2, get_mem_index(s));
21a8eced 2651 return DISAS_NEXT;
22c37a08
RH
2652}
2653
21a8eced 2654static DisasJumpType op_ld32u(DisasContext *s, DisasOps *o)
22c37a08
RH
2655{
2656 tcg_gen_qemu_ld32u(o->out, o->in2, get_mem_index(s));
21a8eced 2657 return DISAS_NEXT;
22c37a08
RH
2658}
2659
21a8eced 2660static DisasJumpType op_ld64(DisasContext *s, DisasOps *o)
22c37a08
RH
2661{
2662 tcg_gen_qemu_ld64(o->out, o->in2, get_mem_index(s));
21a8eced 2663 return DISAS_NEXT;
22c37a08
RH
2664}
2665
21a8eced 2666static DisasJumpType op_lat(DisasContext *s, DisasOps *o)
782a8479
AJ
2667{
2668 TCGLabel *lab = gen_new_label();
2669 store_reg32_i64(get_field(s->fields, r1), o->in2);
2670 /* The value is stored even in case of trap. */
2671 tcg_gen_brcondi_i64(TCG_COND_NE, o->in2, 0, lab);
2672 gen_trap(s);
2673 gen_set_label(lab);
21a8eced 2674 return DISAS_NEXT;
782a8479
AJ
2675}
2676
21a8eced 2677static DisasJumpType op_lgat(DisasContext *s, DisasOps *o)
782a8479
AJ
2678{
2679 TCGLabel *lab = gen_new_label();
2680 tcg_gen_qemu_ld64(o->out, o->in2, get_mem_index(s));
2681 /* The value is stored even in case of trap. */
2682 tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab);
2683 gen_trap(s);
2684 gen_set_label(lab);
21a8eced 2685 return DISAS_NEXT;
782a8479
AJ
2686}
2687
21a8eced 2688static DisasJumpType op_lfhat(DisasContext *s, DisasOps *o)
782a8479
AJ
2689{
2690 TCGLabel *lab = gen_new_label();
2691 store_reg32h_i64(get_field(s->fields, r1), o->in2);
2692 /* The value is stored even in case of trap. */
2693 tcg_gen_brcondi_i64(TCG_COND_NE, o->in2, 0, lab);
2694 gen_trap(s);
2695 gen_set_label(lab);
21a8eced 2696 return DISAS_NEXT;
782a8479
AJ
2697}
2698
21a8eced 2699static DisasJumpType op_llgfat(DisasContext *s, DisasOps *o)
782a8479
AJ
2700{
2701 TCGLabel *lab = gen_new_label();
2702 tcg_gen_qemu_ld32u(o->out, o->in2, get_mem_index(s));
2703 /* The value is stored even in case of trap. */
2704 tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab);
2705 gen_trap(s);
2706 gen_set_label(lab);
21a8eced 2707 return DISAS_NEXT;
782a8479
AJ
2708}
2709
21a8eced 2710static DisasJumpType op_llgtat(DisasContext *s, DisasOps *o)
782a8479
AJ
2711{
2712 TCGLabel *lab = gen_new_label();
2713 tcg_gen_andi_i64(o->out, o->in2, 0x7fffffff);
2714 /* The value is stored even in case of trap. */
2715 tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab);
2716 gen_trap(s);
2717 gen_set_label(lab);
21a8eced 2718 return DISAS_NEXT;
782a8479
AJ
2719}
2720
21a8eced 2721static DisasJumpType op_loc(DisasContext *s, DisasOps *o)
632086da
RH
2722{
2723 DisasCompare c;
2724
2725 disas_jcc(s, &c, get_field(s->fields, m3));
2726
2727 if (c.is_64) {
2728 tcg_gen_movcond_i64(c.cond, o->out, c.u.s64.a, c.u.s64.b,
2729 o->in2, o->in1);
2730 free_compare(&c);
2731 } else {
2732 TCGv_i32 t32 = tcg_temp_new_i32();
2733 TCGv_i64 t, z;
2734
2735 tcg_gen_setcond_i32(c.cond, t32, c.u.s32.a, c.u.s32.b);
2736 free_compare(&c);
2737
2738 t = tcg_temp_new_i64();
2739 tcg_gen_extu_i32_i64(t, t32);
2740 tcg_temp_free_i32(t32);
2741
2742 z = tcg_const_i64(0);
2743 tcg_gen_movcond_i64(TCG_COND_NE, o->out, t, z, o->in2, o->in1);
2744 tcg_temp_free_i64(t);
2745 tcg_temp_free_i64(z);
2746 }
2747
21a8eced 2748 return DISAS_NEXT;
632086da
RH
2749}
2750
8b5ff571 2751#ifndef CONFIG_USER_ONLY
21a8eced 2752static DisasJumpType op_lctl(DisasContext *s, DisasOps *o)
504488b8
RH
2753{
2754 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2755 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
2756 check_privileged(s);
504488b8
RH
2757 gen_helper_lctl(cpu_env, r1, o->in2, r3);
2758 tcg_temp_free_i32(r1);
2759 tcg_temp_free_i32(r3);
9dec2388 2760 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
21a8eced 2761 return DISAS_PC_STALE_NOCHAIN;
504488b8
RH
2762}
2763
21a8eced 2764static DisasJumpType op_lctlg(DisasContext *s, DisasOps *o)
3e398cf9
RH
2765{
2766 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2767 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
2768 check_privileged(s);
3e398cf9
RH
2769 gen_helper_lctlg(cpu_env, r1, o->in2, r3);
2770 tcg_temp_free_i32(r1);
2771 tcg_temp_free_i32(r3);
9dec2388 2772 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
21a8eced 2773 return DISAS_PC_STALE_NOCHAIN;
3e398cf9 2774}
1807aaa5 2775
21a8eced 2776static DisasJumpType op_lra(DisasContext *s, DisasOps *o)
d8fe4a9c
RH
2777{
2778 check_privileged(s);
d8fe4a9c
RH
2779 gen_helper_lra(o->out, cpu_env, o->in2);
2780 set_cc_static(s);
21a8eced 2781 return DISAS_NEXT;
d8fe4a9c
RH
2782}
2783
21a8eced 2784static DisasJumpType op_lpp(DisasContext *s, DisasOps *o)
190b2422
MB
2785{
2786 check_privileged(s);
2787
2788 tcg_gen_st_i64(o->in2, cpu_env, offsetof(CPUS390XState, pp));
21a8eced 2789 return DISAS_NEXT;
190b2422
MB
2790}
2791
21a8eced 2792static DisasJumpType op_lpsw(DisasContext *s, DisasOps *o)
8b5ff571
RH
2793{
2794 TCGv_i64 t1, t2;
2795
2796 check_privileged(s);
3da0ab35 2797 per_breaking_event(s);
8b5ff571
RH
2798
2799 t1 = tcg_temp_new_i64();
2800 t2 = tcg_temp_new_i64();
2801 tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
2802 tcg_gen_addi_i64(o->in2, o->in2, 4);
2803 tcg_gen_qemu_ld32u(t2, o->in2, get_mem_index(s));
2804 /* Convert the 32-bit PSW_MASK into the 64-bit PSW_MASK. */
2805 tcg_gen_shli_i64(t1, t1, 32);
2806 gen_helper_load_psw(cpu_env, t1, t2);
2807 tcg_temp_free_i64(t1);
2808 tcg_temp_free_i64(t2);
21a8eced 2809 return DISAS_NORETURN;
8b5ff571 2810}
7ab938d7 2811
21a8eced 2812static DisasJumpType op_lpswe(DisasContext *s, DisasOps *o)
7ab938d7
RH
2813{
2814 TCGv_i64 t1, t2;
2815
2816 check_privileged(s);
3da0ab35 2817 per_breaking_event(s);
7ab938d7
RH
2818
2819 t1 = tcg_temp_new_i64();
2820 t2 = tcg_temp_new_i64();
2821 tcg_gen_qemu_ld64(t1, o->in2, get_mem_index(s));
2822 tcg_gen_addi_i64(o->in2, o->in2, 8);
2823 tcg_gen_qemu_ld64(t2, o->in2, get_mem_index(s));
2824 gen_helper_load_psw(cpu_env, t1, t2);
2825 tcg_temp_free_i64(t1);
2826 tcg_temp_free_i64(t2);
21a8eced 2827 return DISAS_NORETURN;
7ab938d7 2828}
8b5ff571
RH
2829#endif
2830
21a8eced 2831static DisasJumpType op_lam(DisasContext *s, DisasOps *o)
7df3e93a
RH
2832{
2833 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2834 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
7df3e93a
RH
2835 gen_helper_lam(cpu_env, r1, o->in2, r3);
2836 tcg_temp_free_i32(r1);
2837 tcg_temp_free_i32(r3);
21a8eced 2838 return DISAS_NEXT;
7df3e93a
RH
2839}
2840
21a8eced 2841static DisasJumpType op_lm32(DisasContext *s, DisasOps *o)
77f8d6c3
RH
2842{
2843 int r1 = get_field(s->fields, r1);
2844 int r3 = get_field(s->fields, r3);
aa752a4a 2845 TCGv_i64 t1, t2;
77f8d6c3 2846
aa752a4a
AJ
2847 /* Only one register to read. */
2848 t1 = tcg_temp_new_i64();
2849 if (unlikely(r1 == r3)) {
2850 tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
2851 store_reg32_i64(r1, t1);
2852 tcg_temp_free(t1);
21a8eced 2853 return DISAS_NEXT;
aa752a4a
AJ
2854 }
2855
2856 /* First load the values of the first and last registers to trigger
2857 possible page faults. */
2858 t2 = tcg_temp_new_i64();
2859 tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
2860 tcg_gen_addi_i64(t2, o->in2, 4 * ((r3 - r1) & 15));
2861 tcg_gen_qemu_ld32u(t2, t2, get_mem_index(s));
2862 store_reg32_i64(r1, t1);
2863 store_reg32_i64(r3, t2);
2864
2865 /* Only two registers to read. */
2866 if (((r1 + 1) & 15) == r3) {
2867 tcg_temp_free(t2);
2868 tcg_temp_free(t1);
21a8eced 2869 return DISAS_NEXT;
aa752a4a
AJ
2870 }
2871
2872 /* Then load the remaining registers. Page fault can't occur. */
2873 r3 = (r3 - 1) & 15;
2874 tcg_gen_movi_i64(t2, 4);
2875 while (r1 != r3) {
77f8d6c3 2876 r1 = (r1 + 1) & 15;
aa752a4a
AJ
2877 tcg_gen_add_i64(o->in2, o->in2, t2);
2878 tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
2879 store_reg32_i64(r1, t1);
77f8d6c3 2880 }
aa752a4a
AJ
2881 tcg_temp_free(t2);
2882 tcg_temp_free(t1);
77f8d6c3 2883
21a8eced 2884 return DISAS_NEXT;
77f8d6c3
RH
2885}
2886
21a8eced 2887static DisasJumpType op_lmh(DisasContext *s, DisasOps *o)
77f8d6c3
RH
2888{
2889 int r1 = get_field(s->fields, r1);
2890 int r3 = get_field(s->fields, r3);
aa752a4a 2891 TCGv_i64 t1, t2;
77f8d6c3 2892
aa752a4a
AJ
2893 /* Only one register to read. */
2894 t1 = tcg_temp_new_i64();
2895 if (unlikely(r1 == r3)) {
2896 tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
2897 store_reg32h_i64(r1, t1);
2898 tcg_temp_free(t1);
21a8eced 2899 return DISAS_NEXT;
aa752a4a
AJ
2900 }
2901
2902 /* First load the values of the first and last registers to trigger
2903 possible page faults. */
2904 t2 = tcg_temp_new_i64();
2905 tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
2906 tcg_gen_addi_i64(t2, o->in2, 4 * ((r3 - r1) & 15));
2907 tcg_gen_qemu_ld32u(t2, t2, get_mem_index(s));
2908 store_reg32h_i64(r1, t1);
2909 store_reg32h_i64(r3, t2);
2910
2911 /* Only two registers to read. */
2912 if (((r1 + 1) & 15) == r3) {
2913 tcg_temp_free(t2);
2914 tcg_temp_free(t1);
21a8eced 2915 return DISAS_NEXT;
aa752a4a
AJ
2916 }
2917
2918 /* Then load the remaining registers. Page fault can't occur. */
2919 r3 = (r3 - 1) & 15;
2920 tcg_gen_movi_i64(t2, 4);
2921 while (r1 != r3) {
77f8d6c3 2922 r1 = (r1 + 1) & 15;
aa752a4a
AJ
2923 tcg_gen_add_i64(o->in2, o->in2, t2);
2924 tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
2925 store_reg32h_i64(r1, t1);
77f8d6c3 2926 }
aa752a4a
AJ
2927 tcg_temp_free(t2);
2928 tcg_temp_free(t1);
77f8d6c3 2929
21a8eced 2930 return DISAS_NEXT;
77f8d6c3
RH
2931}
2932
21a8eced 2933static DisasJumpType op_lm64(DisasContext *s, DisasOps *o)
77f8d6c3
RH
2934{
2935 int r1 = get_field(s->fields, r1);
2936 int r3 = get_field(s->fields, r3);
aa752a4a 2937 TCGv_i64 t1, t2;
77f8d6c3 2938
aa752a4a
AJ
2939 /* Only one register to read. */
2940 if (unlikely(r1 == r3)) {
77f8d6c3 2941 tcg_gen_qemu_ld64(regs[r1], o->in2, get_mem_index(s));
21a8eced 2942 return DISAS_NEXT;
aa752a4a
AJ
2943 }
2944
2945 /* First load the values of the first and last registers to trigger
2946 possible page faults. */
2947 t1 = tcg_temp_new_i64();
2948 t2 = tcg_temp_new_i64();
2949 tcg_gen_qemu_ld64(t1, o->in2, get_mem_index(s));
2950 tcg_gen_addi_i64(t2, o->in2, 8 * ((r3 - r1) & 15));
2951 tcg_gen_qemu_ld64(regs[r3], t2, get_mem_index(s));
2952 tcg_gen_mov_i64(regs[r1], t1);
2953 tcg_temp_free(t2);
2954
2955 /* Only two registers to read. */
2956 if (((r1 + 1) & 15) == r3) {
2957 tcg_temp_free(t1);
21a8eced 2958 return DISAS_NEXT;
aa752a4a
AJ
2959 }
2960
2961 /* Then load the remaining registers. Page fault can't occur. */
2962 r3 = (r3 - 1) & 15;
2963 tcg_gen_movi_i64(t1, 8);
2964 while (r1 != r3) {
77f8d6c3 2965 r1 = (r1 + 1) & 15;
aa752a4a
AJ
2966 tcg_gen_add_i64(o->in2, o->in2, t1);
2967 tcg_gen_qemu_ld64(regs[r1], o->in2, get_mem_index(s));
77f8d6c3 2968 }
aa752a4a 2969 tcg_temp_free(t1);
77f8d6c3 2970
21a8eced 2971 return DISAS_NEXT;
77f8d6c3
RH
2972}
2973
21a8eced 2974static DisasJumpType op_lpd(DisasContext *s, DisasOps *o)
1807aaa5
EB
2975{
2976 TCGv_i64 a1, a2;
2977 TCGMemOp mop = s->insn->data;
2978
2979 /* In a parallel context, stop the world and single step. */
eccf741a 2980 if (tb_cflags(s->base.tb) & CF_PARALLEL) {
cb3129c3
DH
2981 update_psw_addr(s);
2982 update_cc_op(s);
1807aaa5 2983 gen_exception(EXCP_ATOMIC);
21a8eced 2984 return DISAS_NORETURN;
1807aaa5
EB
2985 }
2986
2987 /* In a serial context, perform the two loads ... */
2988 a1 = get_address(s, 0, get_field(s->fields, b1), get_field(s->fields, d1));
2989 a2 = get_address(s, 0, get_field(s->fields, b2), get_field(s->fields, d2));
2990 tcg_gen_qemu_ld_i64(o->out, a1, get_mem_index(s), mop | MO_ALIGN);
2991 tcg_gen_qemu_ld_i64(o->out2, a2, get_mem_index(s), mop | MO_ALIGN);
2992 tcg_temp_free_i64(a1);
2993 tcg_temp_free_i64(a2);
2994
2995 /* ... and indicate that we performed them while interlocked. */
2996 gen_op_movi_cc(s, 0);
21a8eced 2997 return DISAS_NEXT;
1807aaa5
EB
2998}
2999
21a8eced 3000static DisasJumpType op_lpq(DisasContext *s, DisasOps *o)
e22dfdb2 3001{
eccf741a 3002 if (tb_cflags(s->base.tb) & CF_PARALLEL) {
6476615d
EC
3003 gen_helper_lpq_parallel(o->out, cpu_env, o->in2);
3004 } else {
3005 gen_helper_lpq(o->out, cpu_env, o->in2);
3006 }
e22dfdb2 3007 return_low128(o->out2);
21a8eced 3008 return DISAS_NEXT;
e22dfdb2
AJ
3009}
3010
9c3fd85b 3011#ifndef CONFIG_USER_ONLY
21a8eced 3012static DisasJumpType op_lura(DisasContext *s, DisasOps *o)
9c3fd85b
RH
3013{
3014 check_privileged(s);
9c3fd85b 3015 gen_helper_lura(o->out, cpu_env, o->in2);
21a8eced 3016 return DISAS_NEXT;
9c3fd85b
RH
3017}
3018
21a8eced 3019static DisasJumpType op_lurag(DisasContext *s, DisasOps *o)
9c3fd85b
RH
3020{
3021 check_privileged(s);
9c3fd85b 3022 gen_helper_lurag(o->out, cpu_env, o->in2);
21a8eced 3023 return DISAS_NEXT;
9c3fd85b
RH
3024}
3025#endif
3026
21a8eced 3027static DisasJumpType op_lzrb(DisasContext *s, DisasOps *o)
c2a5c1d7
RH
3028{
3029 tcg_gen_andi_i64(o->out, o->in2, -256);
21a8eced 3030 return DISAS_NEXT;
c2a5c1d7
RH
3031}
3032
21a8eced 3033static DisasJumpType op_mov2(DisasContext *s, DisasOps *o)
22c37a08
RH
3034{
3035 o->out = o->in2;
3036 o->g_out = o->g_in2;
f764718d 3037 o->in2 = NULL;
22c37a08 3038 o->g_in2 = false;
21a8eced 3039 return DISAS_NEXT;
22c37a08
RH
3040}
3041
21a8eced 3042static DisasJumpType op_mov2e(DisasContext *s, DisasOps *o)
a1c7610a
AJ
3043{
3044 int b2 = get_field(s->fields, b2);
3045 TCGv ar1 = tcg_temp_new_i64();
3046
3047 o->out = o->in2;
3048 o->g_out = o->g_in2;
f764718d 3049 o->in2 = NULL;
a1c7610a
AJ
3050 o->g_in2 = false;
3051
eccf741a 3052 switch (s->base.tb->flags & FLAG_MASK_ASC) {
159fed45 3053 case PSW_ASC_PRIMARY >> FLAG_MASK_PSW_SHIFT:
a1c7610a
AJ
3054 tcg_gen_movi_i64(ar1, 0);
3055 break;
159fed45 3056 case PSW_ASC_ACCREG >> FLAG_MASK_PSW_SHIFT:
a1c7610a
AJ
3057 tcg_gen_movi_i64(ar1, 1);
3058 break;
159fed45 3059 case PSW_ASC_SECONDARY >> FLAG_MASK_PSW_SHIFT:
a1c7610a
AJ
3060 if (b2) {
3061 tcg_gen_ld32u_i64(ar1, cpu_env, offsetof(CPUS390XState, aregs[b2]));
3062 } else {
3063 tcg_gen_movi_i64(ar1, 0);
3064 }
3065 break;
159fed45 3066 case PSW_ASC_HOME >> FLAG_MASK_PSW_SHIFT:
a1c7610a
AJ
3067 tcg_gen_movi_i64(ar1, 2);
3068 break;
3069 }
3070
3071 tcg_gen_st32_i64(ar1, cpu_env, offsetof(CPUS390XState, aregs[1]));
3072 tcg_temp_free_i64(ar1);
3073
21a8eced 3074 return DISAS_NEXT;
a1c7610a
AJ
3075}
3076
21a8eced 3077static DisasJumpType op_movx(DisasContext *s, DisasOps *o)
d764a8d1
RH
3078{
3079 o->out = o->in1;
3080 o->out2 = o->in2;
3081 o->g_out = o->g_in1;
3082 o->g_out2 = o->g_in2;
f764718d
RH
3083 o->in1 = NULL;
3084 o->in2 = NULL;
d764a8d1 3085 o->g_in1 = o->g_in2 = false;
21a8eced 3086 return DISAS_NEXT;
d764a8d1
RH
3087}
3088
21a8eced 3089static DisasJumpType op_mvc(DisasContext *s, DisasOps *o)
af9e5a04
RH
3090{
3091 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
af9e5a04
RH
3092 gen_helper_mvc(cpu_env, l, o->addr1, o->in2);
3093 tcg_temp_free_i32(l);
21a8eced 3094 return DISAS_NEXT;
af9e5a04
RH
3095}
3096
21a8eced 3097static DisasJumpType op_mvcin(DisasContext *s, DisasOps *o)
6c9deca8
AJ
3098{
3099 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
3100 gen_helper_mvcin(cpu_env, l, o->addr1, o->in2);
3101 tcg_temp_free_i32(l);
21a8eced 3102 return DISAS_NEXT;
6c9deca8
AJ
3103}
3104
21a8eced 3105static DisasJumpType op_mvcl(DisasContext *s, DisasOps *o)
e1eaada9 3106{
d3327121
AJ
3107 int r1 = get_field(s->fields, r1);
3108 int r2 = get_field(s->fields, r2);
3109 TCGv_i32 t1, t2;
3110
3111 /* r1 and r2 must be even. */
3112 if (r1 & 1 || r2 & 1) {
3113 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 3114 return DISAS_NORETURN;
d3327121
AJ
3115 }
3116
3117 t1 = tcg_const_i32(r1);
3118 t2 = tcg_const_i32(r2);
3119 gen_helper_mvcl(cc_op, cpu_env, t1, t2);
3120 tcg_temp_free_i32(t1);
3121 tcg_temp_free_i32(t2);
e1eaada9 3122 set_cc_static(s);
21a8eced 3123 return DISAS_NEXT;
e1eaada9
RH
3124}
3125
21a8eced 3126static DisasJumpType op_mvcle(DisasContext *s, DisasOps *o)
eb66e6a9 3127{
d3327121
AJ
3128 int r1 = get_field(s->fields, r1);
3129 int r3 = get_field(s->fields, r3);
3130 TCGv_i32 t1, t3;
3131
3132 /* r1 and r3 must be even. */
3133 if (r1 & 1 || r3 & 1) {
3134 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 3135 return DISAS_NORETURN;
d3327121
AJ
3136 }
3137
3138 t1 = tcg_const_i32(r1);
3139 t3 = tcg_const_i32(r3);
3140 gen_helper_mvcle(cc_op, cpu_env, t1, o->in2, t3);
3141 tcg_temp_free_i32(t1);
3142 tcg_temp_free_i32(t3);
eb66e6a9 3143 set_cc_static(s);
21a8eced 3144 return DISAS_NEXT;
eb66e6a9
RH
3145}
3146
21a8eced 3147static DisasJumpType op_mvclu(DisasContext *s, DisasOps *o)
16f2e4b8
AJ
3148{
3149 int r1 = get_field(s->fields, r1);
3150 int r3 = get_field(s->fields, r3);
3151 TCGv_i32 t1, t3;
3152
3153 /* r1 and r3 must be even. */
3154 if (r1 & 1 || r3 & 1) {
3155 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 3156 return DISAS_NORETURN;
16f2e4b8
AJ
3157 }
3158
3159 t1 = tcg_const_i32(r1);
3160 t3 = tcg_const_i32(r3);
3161 gen_helper_mvclu(cc_op, cpu_env, t1, o->in2, t3);
3162 tcg_temp_free_i32(t1);
3163 tcg_temp_free_i32(t3);
3164 set_cc_static(s);
21a8eced 3165 return DISAS_NEXT;
16f2e4b8
AJ
3166}
3167
21a8eced 3168static DisasJumpType op_mvcos(DisasContext *s, DisasOps *o)
3e7e5e0b
DH
3169{
3170 int r3 = get_field(s->fields, r3);
3171 gen_helper_mvcos(cc_op, cpu_env, o->addr1, o->in2, regs[r3]);
3172 set_cc_static(s);
21a8eced 3173 return DISAS_NEXT;
3e7e5e0b
DH
3174}
3175
97c3ab61 3176#ifndef CONFIG_USER_ONLY
21a8eced 3177static DisasJumpType op_mvcp(DisasContext *s, DisasOps *o)
97c3ab61
RH
3178{
3179 int r1 = get_field(s->fields, l1);
3180 check_privileged(s);
97c3ab61
RH
3181 gen_helper_mvcp(cc_op, cpu_env, regs[r1], o->addr1, o->in2);
3182 set_cc_static(s);
21a8eced 3183 return DISAS_NEXT;
97c3ab61
RH
3184}
3185
21a8eced 3186static DisasJumpType op_mvcs(DisasContext *s, DisasOps *o)
97c3ab61
RH
3187{
3188 int r1 = get_field(s->fields, l1);
3189 check_privileged(s);
97c3ab61
RH
3190 gen_helper_mvcs(cc_op, cpu_env, regs[r1], o->addr1, o->in2);
3191 set_cc_static(s);
21a8eced 3192 return DISAS_NEXT;
97c3ab61
RH
3193}
3194#endif
3195
21a8eced 3196static DisasJumpType op_mvn(DisasContext *s, DisasOps *o)
256dab6f
AJ
3197{
3198 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
3199 gen_helper_mvn(cpu_env, l, o->addr1, o->in2);
3200 tcg_temp_free_i32(l);
21a8eced 3201 return DISAS_NEXT;
256dab6f
AJ
3202}
3203
21a8eced 3204static DisasJumpType op_mvo(DisasContext *s, DisasOps *o)
fdc0a747
AJ
3205{
3206 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
3207 gen_helper_mvo(cpu_env, l, o->addr1, o->in2);
3208 tcg_temp_free_i32(l);
21a8eced 3209 return DISAS_NEXT;
fdc0a747
AJ
3210}
3211
21a8eced 3212static DisasJumpType op_mvpg(DisasContext *s, DisasOps *o)
ee6c38d5 3213{
7cf96fca 3214 gen_helper_mvpg(cc_op, cpu_env, regs[0], o->in1, o->in2);
ee6c38d5 3215 set_cc_static(s);
21a8eced 3216 return DISAS_NEXT;
ee6c38d5
RH
3217}
3218
21a8eced 3219static DisasJumpType op_mvst(DisasContext *s, DisasOps *o)
aa31bf60 3220{
aa31bf60
RH
3221 gen_helper_mvst(o->in1, cpu_env, regs[0], o->in1, o->in2);
3222 set_cc_static(s);
3223 return_low128(o->in2);
21a8eced 3224 return DISAS_NEXT;
aa31bf60
RH
3225}
3226
21a8eced 3227static DisasJumpType op_mvz(DisasContext *s, DisasOps *o)
01f8db88
AJ
3228{
3229 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
3230 gen_helper_mvz(cpu_env, l, o->addr1, o->in2);
3231 tcg_temp_free_i32(l);
21a8eced 3232 return DISAS_NEXT;
01f8db88
AJ
3233}
3234
21a8eced 3235static DisasJumpType op_mul(DisasContext *s, DisasOps *o)
d1c04a2b
RH
3236{
3237 tcg_gen_mul_i64(o->out, o->in1, o->in2);
21a8eced 3238 return DISAS_NEXT;
d1c04a2b
RH
3239}
3240
21a8eced 3241static DisasJumpType op_mul128(DisasContext *s, DisasOps *o)
1ac5889f 3242{
dc46d1c6 3243 tcg_gen_mulu2_i64(o->out2, o->out, o->in1, o->in2);
21a8eced 3244 return DISAS_NEXT;
1ac5889f
RH
3245}
3246
21a8eced 3247static DisasJumpType op_meeb(DisasContext *s, DisasOps *o)
83b00736
RH
3248{
3249 gen_helper_meeb(o->out, cpu_env, o->in1, o->in2);
21a8eced 3250 return DISAS_NEXT;
83b00736
RH
3251}
3252
21a8eced 3253static DisasJumpType op_mdeb(DisasContext *s, DisasOps *o)
83b00736
RH
3254{
3255 gen_helper_mdeb(o->out, cpu_env, o->in1, o->in2);
21a8eced 3256 return DISAS_NEXT;
83b00736
RH
3257}
3258
21a8eced 3259static DisasJumpType op_mdb(DisasContext *s, DisasOps *o)
83b00736
RH
3260{
3261 gen_helper_mdb(o->out, cpu_env, o->in1, o->in2);
21a8eced 3262 return DISAS_NEXT;
83b00736
RH
3263}
3264
21a8eced 3265static DisasJumpType op_mxb(DisasContext *s, DisasOps *o)
83b00736
RH
3266{
3267 gen_helper_mxb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2);
3268 return_low128(o->out2);
21a8eced 3269 return DISAS_NEXT;
83b00736
RH
3270}
3271
21a8eced 3272static DisasJumpType op_mxdb(DisasContext *s, DisasOps *o)
83b00736
RH
3273{
3274 gen_helper_mxdb(o->out, cpu_env, o->out, o->out2, o->in2);
3275 return_low128(o->out2);
21a8eced 3276 return DISAS_NEXT;
83b00736
RH
3277}
3278
21a8eced 3279static DisasJumpType op_maeb(DisasContext *s, DisasOps *o)
722bfec3
RH
3280{
3281 TCGv_i64 r3 = load_freg32_i64(get_field(s->fields, r3));
3282 gen_helper_maeb(o->out, cpu_env, o->in1, o->in2, r3);
3283 tcg_temp_free_i64(r3);
21a8eced 3284 return DISAS_NEXT;
722bfec3
RH
3285}
3286
21a8eced 3287static DisasJumpType op_madb(DisasContext *s, DisasOps *o)
722bfec3
RH
3288{
3289 int r3 = get_field(s->fields, r3);
3290 gen_helper_madb(o->out, cpu_env, o->in1, o->in2, fregs[r3]);
21a8eced 3291 return DISAS_NEXT;
722bfec3
RH
3292}
3293
21a8eced 3294static DisasJumpType op_mseb(DisasContext *s, DisasOps *o)
722bfec3
RH
3295{
3296 TCGv_i64 r3 = load_freg32_i64(get_field(s->fields, r3));
3297 gen_helper_mseb(o->out, cpu_env, o->in1, o->in2, r3);
3298 tcg_temp_free_i64(r3);
21a8eced 3299 return DISAS_NEXT;
722bfec3
RH
3300}
3301
21a8eced 3302static DisasJumpType op_msdb(DisasContext *s, DisasOps *o)
722bfec3
RH
3303{
3304 int r3 = get_field(s->fields, r3);
3305 gen_helper_msdb(o->out, cpu_env, o->in1, o->in2, fregs[r3]);
21a8eced 3306 return DISAS_NEXT;
722bfec3
RH
3307}
3308
21a8eced 3309static DisasJumpType op_nabs(DisasContext *s, DisasOps *o)
b9bca3e5 3310{
d3010781
AJ
3311 TCGv_i64 z, n;
3312 z = tcg_const_i64(0);
3313 n = tcg_temp_new_i64();
3314 tcg_gen_neg_i64(n, o->in2);
3315 tcg_gen_movcond_i64(TCG_COND_GE, o->out, o->in2, z, n, o->in2);
3316 tcg_temp_free_i64(n);
3317 tcg_temp_free_i64(z);
21a8eced 3318 return DISAS_NEXT;
b9bca3e5
RH
3319}
3320
21a8eced 3321static DisasJumpType op_nabsf32(DisasContext *s, DisasOps *o)
5d7fd045
RH
3322{
3323 tcg_gen_ori_i64(o->out, o->in2, 0x80000000ull);
21a8eced 3324 return DISAS_NEXT;
5d7fd045
RH
3325}
3326
21a8eced 3327static DisasJumpType op_nabsf64(DisasContext *s, DisasOps *o)
5d7fd045
RH
3328{
3329 tcg_gen_ori_i64(o->out, o->in2, 0x8000000000000000ull);
21a8eced 3330 return DISAS_NEXT;
5d7fd045
RH
3331}
3332
21a8eced 3333static DisasJumpType op_nabsf128(DisasContext *s, DisasOps *o)
5d7fd045
RH
3334{
3335 tcg_gen_ori_i64(o->out, o->in1, 0x8000000000000000ull);
3336 tcg_gen_mov_i64(o->out2, o->in2);
21a8eced 3337 return DISAS_NEXT;
5d7fd045
RH
3338}
3339
21a8eced 3340static DisasJumpType op_nc(DisasContext *s, DisasOps *o)
0a949039
RH
3341{
3342 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
0a949039
RH
3343 gen_helper_nc(cc_op, cpu_env, l, o->addr1, o->in2);
3344 tcg_temp_free_i32(l);
3345 set_cc_static(s);
21a8eced 3346 return DISAS_NEXT;
0a949039
RH
3347}
3348
21a8eced 3349static DisasJumpType op_neg(DisasContext *s, DisasOps *o)
b9bca3e5
RH
3350{
3351 tcg_gen_neg_i64(o->out, o->in2);
21a8eced 3352 return DISAS_NEXT;
b9bca3e5
RH
3353}
3354
21a8eced 3355static DisasJumpType op_negf32(DisasContext *s, DisasOps *o)
5d7fd045
RH
3356{
3357 tcg_gen_xori_i64(o->out, o->in2, 0x80000000ull);
21a8eced 3358 return DISAS_NEXT;
5d7fd045
RH
3359}
3360
21a8eced 3361static DisasJumpType op_negf64(DisasContext *s, DisasOps *o)
5d7fd045
RH
3362{
3363 tcg_gen_xori_i64(o->out, o->in2, 0x8000000000000000ull);
21a8eced 3364 return DISAS_NEXT;
5d7fd045
RH
3365}
3366
21a8eced 3367static DisasJumpType op_negf128(DisasContext *s, DisasOps *o)
5d7fd045
RH
3368{
3369 tcg_gen_xori_i64(o->out, o->in1, 0x8000000000000000ull);
3370 tcg_gen_mov_i64(o->out2, o->in2);
21a8eced 3371 return DISAS_NEXT;
5d7fd045
RH
3372}
3373
21a8eced 3374static DisasJumpType op_oc(DisasContext *s, DisasOps *o)
0a949039
RH
3375{
3376 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
0a949039
RH
3377 gen_helper_oc(cc_op, cpu_env, l, o->addr1, o->in2);
3378 tcg_temp_free_i32(l);
3379 set_cc_static(s);
21a8eced 3380 return DISAS_NEXT;
0a949039
RH
3381}
3382
21a8eced 3383static DisasJumpType op_or(DisasContext *s, DisasOps *o)
3bbfbd1f
RH
3384{
3385 tcg_gen_or_i64(o->out, o->in1, o->in2);
21a8eced 3386 return DISAS_NEXT;
3bbfbd1f
RH
3387}
3388
21a8eced 3389static DisasJumpType op_ori(DisasContext *s, DisasOps *o)
facfc864
RH
3390{
3391 int shift = s->insn->data & 0xff;
3392 int size = s->insn->data >> 8;
3393 uint64_t mask = ((1ull << size) - 1) << shift;
3394
3395 assert(!o->g_in2);
3396 tcg_gen_shli_i64(o->in2, o->in2, shift);
3397 tcg_gen_or_i64(o->out, o->in1, o->in2);
3398
3399 /* Produce the CC from only the bits manipulated. */
3400 tcg_gen_andi_i64(cc_dst, o->out, mask);
3401 set_cc_nz_u64(s, cc_dst);
21a8eced 3402 return DISAS_NEXT;
facfc864
RH
3403}
3404
21a8eced 3405static DisasJumpType op_oi(DisasContext *s, DisasOps *o)
f400be18
DH
3406{
3407 o->in1 = tcg_temp_new_i64();
3408
3409 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
3410 tcg_gen_qemu_ld_tl(o->in1, o->addr1, get_mem_index(s), s->insn->data);
3411 } else {
3412 /* Perform the atomic operation in memory. */
3413 tcg_gen_atomic_fetch_or_i64(o->in1, o->addr1, o->in2, get_mem_index(s),
3414 s->insn->data);
3415 }
3416
3417 /* Recompute also for atomic case: needed for setting CC. */
3418 tcg_gen_or_i64(o->out, o->in1, o->in2);
3419
3420 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
3421 tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), s->insn->data);
3422 }
21a8eced 3423 return DISAS_NEXT;
f400be18
DH
3424}
3425
21a8eced 3426static DisasJumpType op_pack(DisasContext *s, DisasOps *o)
76c57490
AJ
3427{
3428 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
3429 gen_helper_pack(cpu_env, l, o->addr1, o->in2);
3430 tcg_temp_free_i32(l);
21a8eced 3431 return DISAS_NEXT;
76c57490
AJ
3432}
3433
21a8eced 3434static DisasJumpType op_pka(DisasContext *s, DisasOps *o)
3bd3d6d3
AJ
3435{
3436 int l2 = get_field(s->fields, l2) + 1;
3437 TCGv_i32 l;
3438
3439 /* The length must not exceed 32 bytes. */
3440 if (l2 > 32) {
3441 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 3442 return DISAS_NORETURN;
3bd3d6d3
AJ
3443 }
3444 l = tcg_const_i32(l2);
3445 gen_helper_pka(cpu_env, o->addr1, o->in2, l);
3446 tcg_temp_free_i32(l);
21a8eced 3447 return DISAS_NEXT;
3bd3d6d3
AJ
3448}
3449
21a8eced 3450static DisasJumpType op_pku(DisasContext *s, DisasOps *o)
4e256bef
AJ
3451{
3452 int l2 = get_field(s->fields, l2) + 1;
3453 TCGv_i32 l;
3454
3455 /* The length must be even and should not exceed 64 bytes. */
3456 if ((l2 & 1) || (l2 > 64)) {
3457 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 3458 return DISAS_NORETURN;
4e256bef
AJ
3459 }
3460 l = tcg_const_i32(l2);
3461 gen_helper_pku(cpu_env, o->addr1, o->in2, l);
3462 tcg_temp_free_i32(l);
21a8eced 3463 return DISAS_NEXT;
4e256bef
AJ
3464}
3465
21a8eced 3466static DisasJumpType op_popcnt(DisasContext *s, DisasOps *o)
99b4f24b
RH
3467{
3468 gen_helper_popcnt(o->out, o->in2);
21a8eced 3469 return DISAS_NEXT;
99b4f24b
RH
3470}
3471
0568d8aa 3472#ifndef CONFIG_USER_ONLY
21a8eced 3473static DisasJumpType op_ptlb(DisasContext *s, DisasOps *o)
0568d8aa
RH
3474{
3475 check_privileged(s);
3476 gen_helper_ptlb(cpu_env);
21a8eced 3477 return DISAS_NEXT;
0568d8aa
RH
3478}
3479#endif
3480
21a8eced 3481static DisasJumpType op_risbg(DisasContext *s, DisasOps *o)
2d6a8698
RH
3482{
3483 int i3 = get_field(s->fields, i3);
3484 int i4 = get_field(s->fields, i4);
3485 int i5 = get_field(s->fields, i5);
3486 int do_zero = i4 & 0x80;
3487 uint64_t mask, imask, pmask;
3488 int pos, len, rot;
3489
3490 /* Adjust the arguments for the specific insn. */
3491 switch (s->fields->op2) {
3492 case 0x55: /* risbg */
fdaae351 3493 case 0x59: /* risbgn */
2d6a8698
RH
3494 i3 &= 63;
3495 i4 &= 63;
3496 pmask = ~0;
3497 break;
3498 case 0x5d: /* risbhg */
3499 i3 &= 31;
3500 i4 &= 31;
3501 pmask = 0xffffffff00000000ull;
3502 break;
3503 case 0x51: /* risblg */
3504 i3 &= 31;
3505 i4 &= 31;
3506 pmask = 0x00000000ffffffffull;
3507 break;
3508 default:
fdaae351 3509 g_assert_not_reached();
2d6a8698
RH
3510 }
3511
3512 /* MASK is the set of bits to be inserted from R2.
3513 Take care for I3/I4 wraparound. */
3514 mask = pmask >> i3;
3515 if (i3 <= i4) {
3516 mask ^= pmask >> i4 >> 1;
3517 } else {
3518 mask |= ~(pmask >> i4 >> 1);
3519 }
3520 mask &= pmask;
3521
3522 /* IMASK is the set of bits to be kept from R1. In the case of the high/low
3523 insns, we need to keep the other half of the register. */
3524 imask = ~mask | ~pmask;
3525 if (do_zero) {
fdaae351 3526 imask = ~pmask;
2d6a8698
RH
3527 }
3528
f6156b8f
RH
3529 len = i4 - i3 + 1;
3530 pos = 63 - i4;
3531 rot = i5 & 63;
3532 if (s->fields->op2 == 0x5d) {
3533 pos += 32;
3534 }
3535
3536 /* In some cases we can implement this with extract. */
dbdaaff4
RH
3537 if (imask == 0 && pos == 0 && len > 0 && len <= rot) {
3538 tcg_gen_extract_i64(o->out, o->in2, 64 - rot, len);
21a8eced 3539 return DISAS_NEXT;
f6156b8f
RH
3540 }
3541
3542 /* In some cases we can implement this with deposit. */
3543 if (len > 0 && (imask == 0 || ~mask == imask)) {
2d6a8698
RH
3544 /* Note that we rotate the bits to be inserted to the lsb, not to
3545 the position as described in the PoO. */
f6156b8f 3546 rot = (rot - pos) & 63;
2d6a8698 3547 } else {
f6156b8f 3548 pos = -1;
2d6a8698
RH
3549 }
3550
3551 /* Rotate the input as necessary. */
3552 tcg_gen_rotli_i64(o->in2, o->in2, rot);
3553
3554 /* Insert the selected bits into the output. */
3555 if (pos >= 0) {
f6156b8f
RH
3556 if (imask == 0) {
3557 tcg_gen_deposit_z_i64(o->out, o->in2, pos, len);
3558 } else {
3559 tcg_gen_deposit_i64(o->out, o->out, o->in2, pos, len);
3560 }
2d6a8698
RH
3561 } else if (imask == 0) {
3562 tcg_gen_andi_i64(o->out, o->in2, mask);
3563 } else {
3564 tcg_gen_andi_i64(o->in2, o->in2, mask);
3565 tcg_gen_andi_i64(o->out, o->out, imask);
3566 tcg_gen_or_i64(o->out, o->out, o->in2);
3567 }
21a8eced 3568 return DISAS_NEXT;
d6c6372e
RH
3569}
3570
21a8eced 3571static DisasJumpType op_rosbg(DisasContext *s, DisasOps *o)
d6c6372e
RH
3572{
3573 int i3 = get_field(s->fields, i3);
3574 int i4 = get_field(s->fields, i4);
3575 int i5 = get_field(s->fields, i5);
3576 uint64_t mask;
3577
3578 /* If this is a test-only form, arrange to discard the result. */
3579 if (i3 & 0x80) {
3580 o->out = tcg_temp_new_i64();
3581 o->g_out = false;
3582 }
3583
3584 i3 &= 63;
3585 i4 &= 63;
3586 i5 &= 63;
3587
3588 /* MASK is the set of bits to be operated on from R2.
3589 Take care for I3/I4 wraparound. */
3590 mask = ~0ull >> i3;
3591 if (i3 <= i4) {
3592 mask ^= ~0ull >> i4 >> 1;
3593 } else {
3594 mask |= ~(~0ull >> i4 >> 1);
3595 }
3596
3597 /* Rotate the input as necessary. */
3598 tcg_gen_rotli_i64(o->in2, o->in2, i5);
3599
3600 /* Operate. */
3601 switch (s->fields->op2) {
3602 case 0x55: /* AND */
3603 tcg_gen_ori_i64(o->in2, o->in2, ~mask);
3604 tcg_gen_and_i64(o->out, o->out, o->in2);
3605 break;
3606 case 0x56: /* OR */
3607 tcg_gen_andi_i64(o->in2, o->in2, mask);
3608 tcg_gen_or_i64(o->out, o->out, o->in2);
3609 break;
3610 case 0x57: /* XOR */
3611 tcg_gen_andi_i64(o->in2, o->in2, mask);
3612 tcg_gen_xor_i64(o->out, o->out, o->in2);
3613 break;
3614 default:
3615 abort();
3616 }
3617
3618 /* Set the CC. */
3619 tcg_gen_andi_i64(cc_dst, o->out, mask);
3620 set_cc_nz_u64(s, cc_dst);
21a8eced 3621 return DISAS_NEXT;
2d6a8698
RH
3622}
3623
21a8eced 3624static DisasJumpType op_rev16(DisasContext *s, DisasOps *o)
d54f5865
RH
3625{
3626 tcg_gen_bswap16_i64(o->out, o->in2);
21a8eced 3627 return DISAS_NEXT;
d54f5865
RH
3628}
3629
21a8eced 3630static DisasJumpType op_rev32(DisasContext *s, DisasOps *o)
d54f5865
RH
3631{
3632 tcg_gen_bswap32_i64(o->out, o->in2);
21a8eced 3633 return DISAS_NEXT;
d54f5865
RH
3634}
3635
21a8eced 3636static DisasJumpType op_rev64(DisasContext *s, DisasOps *o)
d54f5865
RH
3637{
3638 tcg_gen_bswap64_i64(o->out, o->in2);
21a8eced 3639 return DISAS_NEXT;
d54f5865
RH
3640}
3641
21a8eced 3642static DisasJumpType op_rll32(DisasContext *s, DisasOps *o)
cbe24bfa
RH
3643{
3644 TCGv_i32 t1 = tcg_temp_new_i32();
3645 TCGv_i32 t2 = tcg_temp_new_i32();
3646 TCGv_i32 to = tcg_temp_new_i32();
ecc7b3aa
RH
3647 tcg_gen_extrl_i64_i32(t1, o->in1);
3648 tcg_gen_extrl_i64_i32(t2, o->in2);
cbe24bfa
RH
3649 tcg_gen_rotl_i32(to, t1, t2);
3650 tcg_gen_extu_i32_i64(o->out, to);
3651 tcg_temp_free_i32(t1);
3652 tcg_temp_free_i32(t2);
3653 tcg_temp_free_i32(to);
21a8eced 3654 return DISAS_NEXT;
cbe24bfa
RH
3655}
3656
21a8eced 3657static DisasJumpType op_rll64(DisasContext *s, DisasOps *o)
cbe24bfa
RH
3658{
3659 tcg_gen_rotl_i64(o->out, o->in1, o->in2);
21a8eced 3660 return DISAS_NEXT;
cbe24bfa
RH
3661}
3662
5cc69c54 3663#ifndef CONFIG_USER_ONLY
21a8eced 3664static DisasJumpType op_rrbe(DisasContext *s, DisasOps *o)
5cc69c54
RH
3665{
3666 check_privileged(s);
3667 gen_helper_rrbe(cc_op, cpu_env, o->in2);
3668 set_cc_static(s);
21a8eced 3669 return DISAS_NEXT;
5cc69c54 3670}
14244b21 3671
21a8eced 3672static DisasJumpType op_sacf(DisasContext *s, DisasOps *o)
14244b21
RH
3673{
3674 check_privileged(s);
3675 gen_helper_sacf(cpu_env, o->in2);
3676 /* Addressing mode has changed, so end the block. */
21a8eced 3677 return DISAS_PC_STALE;
14244b21 3678}
8612c935 3679#endif
44dd33ba 3680
21a8eced 3681static DisasJumpType op_sam(DisasContext *s, DisasOps *o)
44dd33ba
AG
3682{
3683 int sam = s->insn->data;
8612c935
RH
3684 TCGv_i64 tsam;
3685 uint64_t mask;
44dd33ba 3686
8612c935
RH
3687 switch (sam) {
3688 case 0:
3689 mask = 0xffffff;
3690 break;
3691 case 1:
3692 mask = 0x7fffffff;
3693 break;
3694 default:
3695 mask = -1;
3696 break;
3697 }
3698
631b22ea 3699 /* Bizarre but true, we check the address of the current insn for the
8612c935
RH
3700 specification exception, not the next to be executed. Thus the PoO
3701 documents that Bad Things Happen two bytes before the end. */
eccf741a 3702 if (s->base.pc_next & ~mask) {
8612c935 3703 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 3704 return DISAS_NORETURN;
8612c935 3705 }
eccf741a 3706 s->pc_tmp &= mask;
44dd33ba 3707
8612c935
RH
3708 tsam = tcg_const_i64(sam);
3709 tcg_gen_deposit_i64(psw_mask, psw_mask, tsam, 31, 2);
44dd33ba 3710 tcg_temp_free_i64(tsam);
8612c935
RH
3711
3712 /* Always exit the TB, since we (may have) changed execution mode. */
21a8eced 3713 return DISAS_PC_STALE;
44dd33ba 3714}
5cc69c54 3715
21a8eced 3716static DisasJumpType op_sar(DisasContext *s, DisasOps *o)
d62a4c97
RH
3717{
3718 int r1 = get_field(s->fields, r1);
3719 tcg_gen_st32_i64(o->in2, cpu_env, offsetof(CPUS390XState, aregs[r1]));
21a8eced 3720 return DISAS_NEXT;
d62a4c97
RH
3721}
3722
21a8eced 3723static DisasJumpType op_seb(DisasContext *s, DisasOps *o)
1a800a2d
RH
3724{
3725 gen_helper_seb(o->out, cpu_env, o->in1, o->in2);
21a8eced 3726 return DISAS_NEXT;
1a800a2d
RH
3727}
3728
21a8eced 3729static DisasJumpType op_sdb(DisasContext *s, DisasOps *o)
1a800a2d
RH
3730{
3731 gen_helper_sdb(o->out, cpu_env, o->in1, o->in2);
21a8eced 3732 return DISAS_NEXT;
1a800a2d
RH
3733}
3734
21a8eced 3735static DisasJumpType op_sxb(DisasContext *s, DisasOps *o)
1a800a2d
RH
3736{
3737 gen_helper_sxb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2);
3738 return_low128(o->out2);
21a8eced 3739 return DISAS_NEXT;
1a800a2d
RH
3740}
3741
21a8eced 3742static DisasJumpType op_sqeb(DisasContext *s, DisasOps *o)
16d7b2a4
RH
3743{
3744 gen_helper_sqeb(o->out, cpu_env, o->in2);
21a8eced 3745 return DISAS_NEXT;
16d7b2a4
RH
3746}
3747
21a8eced 3748static DisasJumpType op_sqdb(DisasContext *s, DisasOps *o)
16d7b2a4
RH
3749{
3750 gen_helper_sqdb(o->out, cpu_env, o->in2);
21a8eced 3751 return DISAS_NEXT;
16d7b2a4
RH
3752}
3753
21a8eced 3754static DisasJumpType op_sqxb(DisasContext *s, DisasOps *o)
16d7b2a4
RH
3755{
3756 gen_helper_sqxb(o->out, cpu_env, o->in1, o->in2);
3757 return_low128(o->out2);
21a8eced 3758 return DISAS_NEXT;
16d7b2a4
RH
3759}
3760
0c240015 3761#ifndef CONFIG_USER_ONLY
21a8eced 3762static DisasJumpType op_servc(DisasContext *s, DisasOps *o)
dc458df9
RH
3763{
3764 check_privileged(s);
dc458df9
RH
3765 gen_helper_servc(cc_op, cpu_env, o->in2, o->in1);
3766 set_cc_static(s);
21a8eced 3767 return DISAS_NEXT;
dc458df9
RH
3768}
3769
21a8eced 3770static DisasJumpType op_sigp(DisasContext *s, DisasOps *o)
0c240015
RH
3771{
3772 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
11b0079c 3773 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
0c240015 3774 check_privileged(s);
11b0079c 3775 gen_helper_sigp(cc_op, cpu_env, o->in2, r1, r3);
1e8e69f0 3776 set_cc_static(s);
0c240015 3777 tcg_temp_free_i32(r1);
11b0079c 3778 tcg_temp_free_i32(r3);
21a8eced 3779 return DISAS_NEXT;
0c240015
RH
3780}
3781#endif
3782
21a8eced 3783static DisasJumpType op_soc(DisasContext *s, DisasOps *o)
b92fa334
RH
3784{
3785 DisasCompare c;
45aa9aa3 3786 TCGv_i64 a, h;
42a268c2
RH
3787 TCGLabel *lab;
3788 int r1;
b92fa334
RH
3789
3790 disas_jcc(s, &c, get_field(s->fields, m3));
3791
c095ed73
AG
3792 /* We want to store when the condition is fulfilled, so branch
3793 out when it's not */
3794 c.cond = tcg_invert_cond(c.cond);
3795
b92fa334
RH
3796 lab = gen_new_label();
3797 if (c.is_64) {
3798 tcg_gen_brcond_i64(c.cond, c.u.s64.a, c.u.s64.b, lab);
3799 } else {
3800 tcg_gen_brcond_i32(c.cond, c.u.s32.a, c.u.s32.b, lab);
3801 }
3802 free_compare(&c);
3803
3804 r1 = get_field(s->fields, r1);
3805 a = get_address(s, 0, get_field(s->fields, b2), get_field(s->fields, d2));
45aa9aa3
RH
3806 switch (s->insn->data) {
3807 case 1: /* STOCG */
b92fa334 3808 tcg_gen_qemu_st64(regs[r1], a, get_mem_index(s));
45aa9aa3
RH
3809 break;
3810 case 0: /* STOC */
b92fa334 3811 tcg_gen_qemu_st32(regs[r1], a, get_mem_index(s));
45aa9aa3
RH
3812 break;
3813 case 2: /* STOCFH */
3814 h = tcg_temp_new_i64();
3815 tcg_gen_shri_i64(h, regs[r1], 32);
3816 tcg_gen_qemu_st32(h, a, get_mem_index(s));
3817 tcg_temp_free_i64(h);
3818 break;
3819 default:
3820 g_assert_not_reached();
b92fa334
RH
3821 }
3822 tcg_temp_free_i64(a);
3823
3824 gen_set_label(lab);
21a8eced 3825 return DISAS_NEXT;
b92fa334
RH
3826}
3827
21a8eced 3828static DisasJumpType op_sla(DisasContext *s, DisasOps *o)
cbe24bfa
RH
3829{
3830 uint64_t sign = 1ull << s->insn->data;
3831 enum cc_op cco = s->insn->data == 31 ? CC_OP_SLA_32 : CC_OP_SLA_64;
3832 gen_op_update2_cc_i64(s, cco, o->in1, o->in2);
3833 tcg_gen_shl_i64(o->out, o->in1, o->in2);
3834 /* The arithmetic left shift is curious in that it does not affect
3835 the sign bit. Copy that over from the source unchanged. */
3836 tcg_gen_andi_i64(o->out, o->out, ~sign);
3837 tcg_gen_andi_i64(o->in1, o->in1, sign);
3838 tcg_gen_or_i64(o->out, o->out, o->in1);
21a8eced 3839 return DISAS_NEXT;
cbe24bfa
RH
3840}
3841
21a8eced 3842static DisasJumpType op_sll(DisasContext *s, DisasOps *o)
cbe24bfa
RH
3843{
3844 tcg_gen_shl_i64(o->out, o->in1, o->in2);
21a8eced 3845 return DISAS_NEXT;
cbe24bfa
RH
3846}
3847
21a8eced 3848static DisasJumpType op_sra(DisasContext *s, DisasOps *o)
cbe24bfa
RH
3849{
3850 tcg_gen_sar_i64(o->out, o->in1, o->in2);
21a8eced 3851 return DISAS_NEXT;
cbe24bfa
RH
3852}
3853
21a8eced 3854static DisasJumpType op_srl(DisasContext *s, DisasOps *o)
cbe24bfa
RH
3855{
3856 tcg_gen_shr_i64(o->out, o->in1, o->in2);
21a8eced 3857 return DISAS_NEXT;
cbe24bfa
RH
3858}
3859
21a8eced 3860static DisasJumpType op_sfpc(DisasContext *s, DisasOps *o)
8379bfdb
RH
3861{
3862 gen_helper_sfpc(cpu_env, o->in2);
21a8eced 3863 return DISAS_NEXT;
8379bfdb
RH
3864}
3865
21a8eced 3866static DisasJumpType op_sfas(DisasContext *s, DisasOps *o)
411edc22
RH
3867{
3868 gen_helper_sfas(cpu_env, o->in2);
21a8eced 3869 return DISAS_NEXT;
411edc22
RH
3870}
3871
21a8eced 3872static DisasJumpType op_srnm(DisasContext *s, DisasOps *o)
a12000b9
RH
3873{
3874 int b2 = get_field(s->fields, b2);
3875 int d2 = get_field(s->fields, d2);
3876 TCGv_i64 t1 = tcg_temp_new_i64();
3877 TCGv_i64 t2 = tcg_temp_new_i64();
3878 int mask, pos, len;
3879
3880 switch (s->fields->op2) {
3881 case 0x99: /* SRNM */
3882 pos = 0, len = 2;
3883 break;
3884 case 0xb8: /* SRNMB */
3885 pos = 0, len = 3;
3886 break;
3887 case 0xb9: /* SRNMT */
3888 pos = 4, len = 3;
5b90a866 3889 break;
a12000b9
RH
3890 default:
3891 tcg_abort();
3892 }
3893 mask = (1 << len) - 1;
3894
3895 /* Insert the value into the appropriate field of the FPC. */
3896 if (b2 == 0) {
3897 tcg_gen_movi_i64(t1, d2 & mask);
3898 } else {
3899 tcg_gen_addi_i64(t1, regs[b2], d2);
3900 tcg_gen_andi_i64(t1, t1, mask);
3901 }
3902 tcg_gen_ld32u_i64(t2, cpu_env, offsetof(CPUS390XState, fpc));
3903 tcg_gen_deposit_i64(t2, t2, t1, pos, len);
3904 tcg_temp_free_i64(t1);
3905
3906 /* Then install the new FPC to set the rounding mode in fpu_status. */
3907 gen_helper_sfpc(cpu_env, t2);
3908 tcg_temp_free_i64(t2);
21a8eced 3909 return DISAS_NEXT;
a12000b9
RH
3910}
3911
21a8eced 3912static DisasJumpType op_spm(DisasContext *s, DisasOps *o)
6b257354
DH
3913{
3914 tcg_gen_extrl_i64_i32(cc_op, o->in1);
3915 tcg_gen_extract_i32(cc_op, cc_op, 28, 2);
3916 set_cc_static(s);
3917
3918 tcg_gen_shri_i64(o->in1, o->in1, 24);
3919 tcg_gen_deposit_i64(psw_mask, psw_mask, o->in1, PSW_SHIFT_MASK_PM, 4);
21a8eced 3920 return DISAS_NEXT;
6b257354
DH
3921}
3922
21a8eced 3923static DisasJumpType op_ectg(DisasContext *s, DisasOps *o)
4bac52f5
DH
3924{
3925 int b1 = get_field(s->fields, b1);
3926 int d1 = get_field(s->fields, d1);
3927 int b2 = get_field(s->fields, b2);
3928 int d2 = get_field(s->fields, d2);
3929 int r3 = get_field(s->fields, r3);
3930 TCGv_i64 tmp = tcg_temp_new_i64();
3931
3932 /* fetch all operands first */
3933 o->in1 = tcg_temp_new_i64();
3934 tcg_gen_addi_i64(o->in1, regs[b1], d1);
3935 o->in2 = tcg_temp_new_i64();
3936 tcg_gen_addi_i64(o->in2, regs[b2], d2);
3937 o->addr1 = get_address(s, 0, r3, 0);
3938
3939 /* load the third operand into r3 before modifying anything */
3940 tcg_gen_qemu_ld64(regs[r3], o->addr1, get_mem_index(s));
3941
3942 /* subtract CPU timer from first operand and store in GR0 */
3943 gen_helper_stpt(tmp, cpu_env);
3944 tcg_gen_sub_i64(regs[0], o->in1, tmp);
3945
3946 /* store second operand in GR1 */
3947 tcg_gen_mov_i64(regs[1], o->in2);
3948
3949 tcg_temp_free_i64(tmp);
21a8eced 3950 return DISAS_NEXT;
4bac52f5
DH
3951}
3952
7d30bb73 3953#ifndef CONFIG_USER_ONLY
21a8eced 3954static DisasJumpType op_spka(DisasContext *s, DisasOps *o)
28d55556
RH
3955{
3956 check_privileged(s);
3957 tcg_gen_shri_i64(o->in2, o->in2, 4);
c8bd9537 3958 tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, PSW_SHIFT_KEY, 4);
21a8eced 3959 return DISAS_NEXT;
28d55556
RH
3960}
3961
21a8eced 3962static DisasJumpType op_sske(DisasContext *s, DisasOps *o)
2bbde27f
RH
3963{
3964 check_privileged(s);
3965 gen_helper_sske(cpu_env, o->in1, o->in2);
21a8eced 3966 return DISAS_NEXT;
2bbde27f
RH
3967}
3968
21a8eced 3969static DisasJumpType op_ssm(DisasContext *s, DisasOps *o)
7d30bb73
RH
3970{
3971 check_privileged(s);
3972 tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, 56, 8);
542f70c2 3973 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
21a8eced 3974 return DISAS_PC_STALE_NOCHAIN;
7d30bb73 3975}
145cdb40 3976
21a8eced 3977static DisasJumpType op_stap(DisasContext *s, DisasOps *o)
411fea3d
RH
3978{
3979 check_privileged(s);
ca5c1457 3980 tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, core_id));
21a8eced 3981 return DISAS_NEXT;
411fea3d
RH
3982}
3983
21a8eced 3984static DisasJumpType op_stck(DisasContext *s, DisasOps *o)
434c91a5
RH
3985{
3986 gen_helper_stck(o->out, cpu_env);
3987 /* ??? We don't implement clock states. */
3988 gen_op_movi_cc(s, 0);
21a8eced 3989 return DISAS_NEXT;
39a5003c
RH
3990}
3991
21a8eced 3992static DisasJumpType op_stcke(DisasContext *s, DisasOps *o)
39a5003c
RH
3993{
3994 TCGv_i64 c1 = tcg_temp_new_i64();
3995 TCGv_i64 c2 = tcg_temp_new_i64();
a63b7cbf 3996 TCGv_i64 todpr = tcg_temp_new_i64();
39a5003c 3997 gen_helper_stck(c1, cpu_env);
a63b7cbf
DH
3998 /* 16 bit value store in an uint32_t (only valid bits set) */
3999 tcg_gen_ld32u_i64(todpr, cpu_env, offsetof(CPUS390XState, todpr));
39a5003c
RH
4000 /* Shift the 64-bit value into its place as a zero-extended
4001 104-bit value. Note that "bit positions 64-103 are always
4002 non-zero so that they compare differently to STCK"; we set
4003 the least significant bit to 1. */
4004 tcg_gen_shli_i64(c2, c1, 56);
4005 tcg_gen_shri_i64(c1, c1, 8);
4006 tcg_gen_ori_i64(c2, c2, 0x10000);
a63b7cbf 4007 tcg_gen_or_i64(c2, c2, todpr);
39a5003c
RH
4008 tcg_gen_qemu_st64(c1, o->in2, get_mem_index(s));
4009 tcg_gen_addi_i64(o->in2, o->in2, 8);
4010 tcg_gen_qemu_st64(c2, o->in2, get_mem_index(s));
4011 tcg_temp_free_i64(c1);
4012 tcg_temp_free_i64(c2);
a63b7cbf 4013 tcg_temp_free_i64(todpr);
39a5003c
RH
4014 /* ??? We don't implement clock states. */
4015 gen_op_movi_cc(s, 0);
21a8eced 4016 return DISAS_NEXT;
434c91a5
RH
4017}
4018
21a8eced 4019static DisasJumpType op_sckc(DisasContext *s, DisasOps *o)
dd3eb7b5
RH
4020{
4021 check_privileged(s);
4022 gen_helper_sckc(cpu_env, o->in2);
21a8eced 4023 return DISAS_NEXT;
dd3eb7b5
RH
4024}
4025
21a8eced 4026static DisasJumpType op_sckpf(DisasContext *s, DisasOps *o)
257a119e
DH
4027{
4028 check_privileged(s);
4029 gen_helper_sckpf(cpu_env, regs[0]);
21a8eced 4030 return DISAS_NEXT;
257a119e
DH
4031}
4032
21a8eced 4033static DisasJumpType op_stckc(DisasContext *s, DisasOps *o)
dd3eb7b5
RH
4034{
4035 check_privileged(s);
4036 gen_helper_stckc(o->out, cpu_env);
21a8eced 4037 return DISAS_NEXT;
dd3eb7b5
RH
4038}
4039
21a8eced 4040static DisasJumpType op_stctg(DisasContext *s, DisasOps *o)
3e398cf9
RH
4041{
4042 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4043 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
4044 check_privileged(s);
3e398cf9
RH
4045 gen_helper_stctg(cpu_env, r1, o->in2, r3);
4046 tcg_temp_free_i32(r1);
4047 tcg_temp_free_i32(r3);
21a8eced 4048 return DISAS_NEXT;
3e398cf9
RH
4049}
4050
21a8eced 4051static DisasJumpType op_stctl(DisasContext *s, DisasOps *o)
504488b8
RH
4052{
4053 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4054 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
4055 check_privileged(s);
504488b8
RH
4056 gen_helper_stctl(cpu_env, r1, o->in2, r3);
4057 tcg_temp_free_i32(r1);
4058 tcg_temp_free_i32(r3);
21a8eced 4059 return DISAS_NEXT;
504488b8
RH
4060}
4061
21a8eced 4062static DisasJumpType op_stidp(DisasContext *s, DisasOps *o)
71bd6669
RH
4063{
4064 check_privileged(s);
076d4d39 4065 tcg_gen_ld_i64(o->out, cpu_env, offsetof(CPUS390XState, cpuid));
21a8eced 4066 return DISAS_NEXT;
71bd6669
RH
4067}
4068
21a8eced 4069static DisasJumpType op_spt(DisasContext *s, DisasOps *o)
c4f0a863
RH
4070{
4071 check_privileged(s);
4072 gen_helper_spt(cpu_env, o->in2);
21a8eced 4073 return DISAS_NEXT;
c4f0a863
RH
4074}
4075
21a8eced 4076static DisasJumpType op_stfl(DisasContext *s, DisasOps *o)
fc778b55 4077{
fc778b55 4078 check_privileged(s);
5bf83628 4079 gen_helper_stfl(cpu_env);
21a8eced 4080 return DISAS_NEXT;
fc778b55
RH
4081}
4082
21a8eced 4083static DisasJumpType op_stpt(DisasContext *s, DisasOps *o)
c4f0a863
RH
4084{
4085 check_privileged(s);
4086 gen_helper_stpt(o->out, cpu_env);
21a8eced 4087 return DISAS_NEXT;
c4f0a863
RH
4088}
4089
21a8eced 4090static DisasJumpType op_stsi(DisasContext *s, DisasOps *o)
d14b3e09
RH
4091{
4092 check_privileged(s);
d14b3e09
RH
4093 gen_helper_stsi(cc_op, cpu_env, o->in2, regs[0], regs[1]);
4094 set_cc_static(s);
21a8eced 4095 return DISAS_NEXT;
d14b3e09
RH
4096}
4097
21a8eced 4098static DisasJumpType op_spx(DisasContext *s, DisasOps *o)
e805a0d3
RH
4099{
4100 check_privileged(s);
4101 gen_helper_spx(cpu_env, o->in2);
21a8eced 4102 return DISAS_NEXT;
e805a0d3
RH
4103}
4104
21a8eced 4105static DisasJumpType op_xsch(DisasContext *s, DisasOps *o)
2c423fc0
RH
4106{
4107 check_privileged(s);
ad8a4570
AG
4108 gen_helper_xsch(cpu_env, regs[1]);
4109 set_cc_static(s);
21a8eced 4110 return DISAS_NEXT;
ad8a4570
AG
4111}
4112
21a8eced 4113static DisasJumpType op_csch(DisasContext *s, DisasOps *o)
ad8a4570
AG
4114{
4115 check_privileged(s);
ad8a4570
AG
4116 gen_helper_csch(cpu_env, regs[1]);
4117 set_cc_static(s);
21a8eced 4118 return DISAS_NEXT;
ad8a4570
AG
4119}
4120
21a8eced 4121static DisasJumpType op_hsch(DisasContext *s, DisasOps *o)
ad8a4570
AG
4122{
4123 check_privileged(s);
ad8a4570
AG
4124 gen_helper_hsch(cpu_env, regs[1]);
4125 set_cc_static(s);
21a8eced 4126 return DISAS_NEXT;
ad8a4570
AG
4127}
4128
21a8eced 4129static DisasJumpType op_msch(DisasContext *s, DisasOps *o)
ad8a4570
AG
4130{
4131 check_privileged(s);
ad8a4570
AG
4132 gen_helper_msch(cpu_env, regs[1], o->in2);
4133 set_cc_static(s);
21a8eced 4134 return DISAS_NEXT;
ad8a4570
AG
4135}
4136
21a8eced 4137static DisasJumpType op_rchp(DisasContext *s, DisasOps *o)
ad8a4570
AG
4138{
4139 check_privileged(s);
ad8a4570
AG
4140 gen_helper_rchp(cpu_env, regs[1]);
4141 set_cc_static(s);
21a8eced 4142 return DISAS_NEXT;
ad8a4570
AG
4143}
4144
21a8eced 4145static DisasJumpType op_rsch(DisasContext *s, DisasOps *o)
ad8a4570
AG
4146{
4147 check_privileged(s);
ad8a4570
AG
4148 gen_helper_rsch(cpu_env, regs[1]);
4149 set_cc_static(s);
21a8eced 4150 return DISAS_NEXT;
ad8a4570
AG
4151}
4152
21a8eced 4153static DisasJumpType op_sal(DisasContext *s, DisasOps *o)
86c34633
DH
4154{
4155 check_privileged(s);
4156 gen_helper_sal(cpu_env, regs[1]);
21a8eced 4157 return DISAS_NEXT;
86c34633
DH
4158}
4159
21a8eced 4160static DisasJumpType op_schm(DisasContext *s, DisasOps *o)
a9de75a0
DH
4161{
4162 check_privileged(s);
4163 gen_helper_schm(cpu_env, regs[1], regs[2], o->in2);
21a8eced 4164 return DISAS_NEXT;
a9de75a0
DH
4165}
4166
21a8eced 4167static DisasJumpType op_siga(DisasContext *s, DisasOps *o)
ad0ccf1e
DH
4168{
4169 check_privileged(s);
4170 /* From KVM code: Not provided, set CC = 3 for subchannel not operational */
4171 gen_op_movi_cc(s, 3);
21a8eced 4172 return DISAS_NEXT;
ad0ccf1e
DH
4173}
4174
21a8eced 4175static DisasJumpType op_stcps(DisasContext *s, DisasOps *o)
b9b0a4dc
DH
4176{
4177 check_privileged(s);
4178 /* The instruction is suppressed if not provided. */
21a8eced 4179 return DISAS_NEXT;
b9b0a4dc
DH
4180}
4181
21a8eced 4182static DisasJumpType op_ssch(DisasContext *s, DisasOps *o)
ad8a4570
AG
4183{
4184 check_privileged(s);
ad8a4570
AG
4185 gen_helper_ssch(cpu_env, regs[1], o->in2);
4186 set_cc_static(s);
21a8eced 4187 return DISAS_NEXT;
ad8a4570
AG
4188}
4189
21a8eced 4190static DisasJumpType op_stsch(DisasContext *s, DisasOps *o)
ad8a4570
AG
4191{
4192 check_privileged(s);
ad8a4570
AG
4193 gen_helper_stsch(cpu_env, regs[1], o->in2);
4194 set_cc_static(s);
21a8eced 4195 return DISAS_NEXT;
ad8a4570
AG
4196}
4197
21a8eced 4198static DisasJumpType op_stcrw(DisasContext *s, DisasOps *o)
5a59bc1d
DH
4199{
4200 check_privileged(s);
4201 gen_helper_stcrw(cpu_env, o->in2);
4202 set_cc_static(s);
21a8eced 4203 return DISAS_NEXT;
5a59bc1d
DH
4204}
4205
21a8eced 4206static DisasJumpType op_tpi(DisasContext *s, DisasOps *o)
6a253de3
DH
4207{
4208 check_privileged(s);
4209 gen_helper_tpi(cc_op, cpu_env, o->addr1);
4210 set_cc_static(s);
21a8eced 4211 return DISAS_NEXT;
6a253de3
DH
4212}
4213
21a8eced 4214static DisasJumpType op_tsch(DisasContext *s, DisasOps *o)
ad8a4570
AG
4215{
4216 check_privileged(s);
ad8a4570
AG
4217 gen_helper_tsch(cpu_env, regs[1], o->in2);
4218 set_cc_static(s);
21a8eced 4219 return DISAS_NEXT;
ad8a4570
AG
4220}
4221
21a8eced 4222static DisasJumpType op_chsc(DisasContext *s, DisasOps *o)
ad8a4570
AG
4223{
4224 check_privileged(s);
ad8a4570
AG
4225 gen_helper_chsc(cpu_env, o->in2);
4226 set_cc_static(s);
21a8eced 4227 return DISAS_NEXT;
2c423fc0
RH
4228}
4229
21a8eced 4230static DisasJumpType op_stpx(DisasContext *s, DisasOps *o)
e805a0d3
RH
4231{
4232 check_privileged(s);
4233 tcg_gen_ld_i64(o->out, cpu_env, offsetof(CPUS390XState, psa));
4234 tcg_gen_andi_i64(o->out, o->out, 0x7fffe000);
21a8eced 4235 return DISAS_NEXT;
e805a0d3
RH
4236}
4237
21a8eced 4238static DisasJumpType op_stnosm(DisasContext *s, DisasOps *o)
145cdb40
RH
4239{
4240 uint64_t i2 = get_field(s->fields, i2);
4241 TCGv_i64 t;
4242
4243 check_privileged(s);
4244
4245 /* It is important to do what the instruction name says: STORE THEN.
4246 If we let the output hook perform the store then if we fault and
4247 restart, we'll have the wrong SYSTEM MASK in place. */
4248 t = tcg_temp_new_i64();
4249 tcg_gen_shri_i64(t, psw_mask, 56);
4250 tcg_gen_qemu_st8(t, o->addr1, get_mem_index(s));
4251 tcg_temp_free_i64(t);
4252
4253 if (s->fields->op == 0xac) {
4254 tcg_gen_andi_i64(psw_mask, psw_mask,
4255 (i2 << 56) | 0x00ffffffffffffffull);
4256 } else {
4257 tcg_gen_ori_i64(psw_mask, psw_mask, i2 << 56);
4258 }
542f70c2
RH
4259
4260 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
21a8eced 4261 return DISAS_PC_STALE_NOCHAIN;
145cdb40 4262}
204504e2 4263
21a8eced 4264static DisasJumpType op_stura(DisasContext *s, DisasOps *o)
204504e2
RH
4265{
4266 check_privileged(s);
204504e2 4267 gen_helper_stura(cpu_env, o->in2, o->in1);
21a8eced 4268 return DISAS_NEXT;
204504e2 4269}
9c3fd85b 4270
21a8eced 4271static DisasJumpType op_sturg(DisasContext *s, DisasOps *o)
9c3fd85b
RH
4272{
4273 check_privileged(s);
9c3fd85b 4274 gen_helper_sturg(cpu_env, o->in2, o->in1);
21a8eced 4275 return DISAS_NEXT;
9c3fd85b 4276}
7d30bb73
RH
4277#endif
4278
21a8eced 4279static DisasJumpType op_stfle(DisasContext *s, DisasOps *o)
5bf83628 4280{
5bf83628
RH
4281 gen_helper_stfle(cc_op, cpu_env, o->in2);
4282 set_cc_static(s);
21a8eced 4283 return DISAS_NEXT;
5bf83628
RH
4284}
4285
21a8eced 4286static DisasJumpType op_st8(DisasContext *s, DisasOps *o)
2b280b97
RH
4287{
4288 tcg_gen_qemu_st8(o->in1, o->in2, get_mem_index(s));
21a8eced 4289 return DISAS_NEXT;
2b280b97
RH
4290}
4291
21a8eced 4292static DisasJumpType op_st16(DisasContext *s, DisasOps *o)
2b280b97
RH
4293{
4294 tcg_gen_qemu_st16(o->in1, o->in2, get_mem_index(s));
21a8eced 4295 return DISAS_NEXT;
2b280b97
RH
4296}
4297
21a8eced 4298static DisasJumpType op_st32(DisasContext *s, DisasOps *o)
2b280b97
RH
4299{
4300 tcg_gen_qemu_st32(o->in1, o->in2, get_mem_index(s));
21a8eced 4301 return DISAS_NEXT;
2b280b97
RH
4302}
4303
21a8eced 4304static DisasJumpType op_st64(DisasContext *s, DisasOps *o)
2b280b97
RH
4305{
4306 tcg_gen_qemu_st64(o->in1, o->in2, get_mem_index(s));
21a8eced 4307 return DISAS_NEXT;
2b280b97
RH
4308}
4309
21a8eced 4310static DisasJumpType op_stam(DisasContext *s, DisasOps *o)
7df3e93a
RH
4311{
4312 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4313 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
7df3e93a
RH
4314 gen_helper_stam(cpu_env, r1, o->in2, r3);
4315 tcg_temp_free_i32(r1);
4316 tcg_temp_free_i32(r3);
21a8eced 4317 return DISAS_NEXT;
7df3e93a
RH
4318}
4319
21a8eced 4320static DisasJumpType op_stcm(DisasContext *s, DisasOps *o)
2ae68059
RH
4321{
4322 int m3 = get_field(s->fields, m3);
4323 int pos, base = s->insn->data;
4324 TCGv_i64 tmp = tcg_temp_new_i64();
4325
4326 pos = base + ctz32(m3) * 8;
4327 switch (m3) {
4328 case 0xf:
4329 /* Effectively a 32-bit store. */
4330 tcg_gen_shri_i64(tmp, o->in1, pos);
4331 tcg_gen_qemu_st32(tmp, o->in2, get_mem_index(s));
4332 break;
4333
4334 case 0xc:
4335 case 0x6:
4336 case 0x3:
4337 /* Effectively a 16-bit store. */
4338 tcg_gen_shri_i64(tmp, o->in1, pos);
4339 tcg_gen_qemu_st16(tmp, o->in2, get_mem_index(s));
4340 break;
4341
4342 case 0x8:
4343 case 0x4:
4344 case 0x2:
4345 case 0x1:
4346 /* Effectively an 8-bit store. */
4347 tcg_gen_shri_i64(tmp, o->in1, pos);
4348 tcg_gen_qemu_st8(tmp, o->in2, get_mem_index(s));
4349 break;
4350
4351 default:
4352 /* This is going to be a sequence of shifts and stores. */
4353 pos = base + 32 - 8;
4354 while (m3) {
4355 if (m3 & 0x8) {
4356 tcg_gen_shri_i64(tmp, o->in1, pos);
4357 tcg_gen_qemu_st8(tmp, o->in2, get_mem_index(s));
4358 tcg_gen_addi_i64(o->in2, o->in2, 1);
4359 }
4360 m3 = (m3 << 1) & 0xf;
4361 pos -= 8;
4362 }
4363 break;
4364 }
4365 tcg_temp_free_i64(tmp);
21a8eced 4366 return DISAS_NEXT;
2ae68059
RH
4367}
4368
21a8eced 4369static DisasJumpType op_stm(DisasContext *s, DisasOps *o)
77f8d6c3
RH
4370{
4371 int r1 = get_field(s->fields, r1);
4372 int r3 = get_field(s->fields, r3);
4373 int size = s->insn->data;
4374 TCGv_i64 tsize = tcg_const_i64(size);
4375
4376 while (1) {
4377 if (size == 8) {
4378 tcg_gen_qemu_st64(regs[r1], o->in2, get_mem_index(s));
4379 } else {
4380 tcg_gen_qemu_st32(regs[r1], o->in2, get_mem_index(s));
4381 }
4382 if (r1 == r3) {
4383 break;
4384 }
4385 tcg_gen_add_i64(o->in2, o->in2, tsize);
4386 r1 = (r1 + 1) & 15;
4387 }
4388
4389 tcg_temp_free_i64(tsize);
21a8eced 4390 return DISAS_NEXT;
77f8d6c3
RH
4391}
4392
21a8eced 4393static DisasJumpType op_stmh(DisasContext *s, DisasOps *o)
77f8d6c3
RH
4394{
4395 int r1 = get_field(s->fields, r1);
4396 int r3 = get_field(s->fields, r3);
4397 TCGv_i64 t = tcg_temp_new_i64();
4398 TCGv_i64 t4 = tcg_const_i64(4);
4399 TCGv_i64 t32 = tcg_const_i64(32);
4400
4401 while (1) {
4402 tcg_gen_shl_i64(t, regs[r1], t32);
4403 tcg_gen_qemu_st32(t, o->in2, get_mem_index(s));
4404 if (r1 == r3) {
4405 break;
4406 }
4407 tcg_gen_add_i64(o->in2, o->in2, t4);
4408 r1 = (r1 + 1) & 15;
4409 }
4410
4411 tcg_temp_free_i64(t);
4412 tcg_temp_free_i64(t4);
4413 tcg_temp_free_i64(t32);
21a8eced 4414 return DISAS_NEXT;
77f8d6c3
RH
4415}
4416
21a8eced 4417static DisasJumpType op_stpq(DisasContext *s, DisasOps *o)
c21b610f 4418{
eccf741a 4419 if (tb_cflags(s->base.tb) & CF_PARALLEL) {
6476615d
EC
4420 gen_helper_stpq_parallel(cpu_env, o->in2, o->out2, o->out);
4421 } else {
4422 gen_helper_stpq(cpu_env, o->in2, o->out2, o->out);
4423 }
21a8eced 4424 return DISAS_NEXT;
c21b610f
AJ
4425}
4426
21a8eced 4427static DisasJumpType op_srst(DisasContext *s, DisasOps *o)
4600c994 4428{
7591db78
RH
4429 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4430 TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));
4431
4432 gen_helper_srst(cpu_env, r1, r2);
4433
4434 tcg_temp_free_i32(r1);
4435 tcg_temp_free_i32(r2);
4600c994 4436 set_cc_static(s);
21a8eced 4437 return DISAS_NEXT;
4600c994
RH
4438}
4439
21a8eced 4440static DisasJumpType op_srstu(DisasContext *s, DisasOps *o)
be7acb58
RH
4441{
4442 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4443 TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));
4444
4445 gen_helper_srstu(cpu_env, r1, r2);
4446
4447 tcg_temp_free_i32(r1);
4448 tcg_temp_free_i32(r2);
4449 set_cc_static(s);
21a8eced 4450 return DISAS_NEXT;
be7acb58
RH
4451}
4452
21a8eced 4453static DisasJumpType op_sub(DisasContext *s, DisasOps *o)
ad044d09
RH
4454{
4455 tcg_gen_sub_i64(o->out, o->in1, o->in2);
21a8eced 4456 return DISAS_NEXT;
ad044d09
RH
4457}
4458
21a8eced 4459static DisasJumpType op_subb(DisasContext *s, DisasOps *o)
4e4bb438 4460{
c95ec459
RH
4461 DisasCompare cmp;
4462 TCGv_i64 borrow;
4e4bb438 4463
c95ec459 4464 tcg_gen_sub_i64(o->out, o->in1, o->in2);
4e4bb438 4465
c95ec459
RH
4466 /* The !borrow flag is the msb of CC. Since we want the inverse of
4467 that, we ask for a comparison of CC=0 | CC=1 -> mask of 8 | 4. */
4468 disas_jcc(s, &cmp, 8 | 4);
4469 borrow = tcg_temp_new_i64();
4470 if (cmp.is_64) {
4471 tcg_gen_setcond_i64(cmp.cond, borrow, cmp.u.s64.a, cmp.u.s64.b);
4472 } else {
4473 TCGv_i32 t = tcg_temp_new_i32();
4474 tcg_gen_setcond_i32(cmp.cond, t, cmp.u.s32.a, cmp.u.s32.b);
4475 tcg_gen_extu_i32_i64(borrow, t);
4476 tcg_temp_free_i32(t);
4477 }
4478 free_compare(&cmp);
4479
4480 tcg_gen_sub_i64(o->out, o->out, borrow);
4481 tcg_temp_free_i64(borrow);
21a8eced 4482 return DISAS_NEXT;
4e4bb438
RH
4483}
4484
21a8eced 4485static DisasJumpType op_svc(DisasContext *s, DisasOps *o)
b9836c1a
RH
4486{
4487 TCGv_i32 t;
4488
4489 update_psw_addr(s);
7a6c7067 4490 update_cc_op(s);
b9836c1a
RH
4491
4492 t = tcg_const_i32(get_field(s->fields, i1) & 0xff);
4493 tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, int_svc_code));
4494 tcg_temp_free_i32(t);
4495
99e57856 4496 t = tcg_const_i32(s->ilen);
b9836c1a
RH
4497 tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, int_svc_ilen));
4498 tcg_temp_free_i32(t);
4499
4500 gen_exception(EXCP_SVC);
21a8eced 4501 return DISAS_NORETURN;
b9836c1a
RH
4502}
4503
21a8eced 4504static DisasJumpType op_tam(DisasContext *s, DisasOps *o)
0c0974d7
AJ
4505{
4506 int cc = 0;
4507
eccf741a
EC
4508 cc |= (s->base.tb->flags & FLAG_MASK_64) ? 2 : 0;
4509 cc |= (s->base.tb->flags & FLAG_MASK_32) ? 1 : 0;
0c0974d7 4510 gen_op_movi_cc(s, cc);
21a8eced 4511 return DISAS_NEXT;
0c0974d7
AJ
4512}
4513
21a8eced 4514static DisasJumpType op_tceb(DisasContext *s, DisasOps *o)
31aa97d1 4515{
af39bc8c 4516 gen_helper_tceb(cc_op, cpu_env, o->in1, o->in2);
31aa97d1 4517 set_cc_static(s);
21a8eced 4518 return DISAS_NEXT;
31aa97d1
RH
4519}
4520
21a8eced 4521static DisasJumpType op_tcdb(DisasContext *s, DisasOps *o)
31aa97d1 4522{
af39bc8c 4523 gen_helper_tcdb(cc_op, cpu_env, o->in1, o->in2);
31aa97d1 4524 set_cc_static(s);
21a8eced 4525 return DISAS_NEXT;
31aa97d1
RH
4526}
4527
21a8eced 4528static DisasJumpType op_tcxb(DisasContext *s, DisasOps *o)
31aa97d1 4529{
af39bc8c 4530 gen_helper_tcxb(cc_op, cpu_env, o->out, o->out2, o->in2);
31aa97d1 4531 set_cc_static(s);
21a8eced 4532 return DISAS_NEXT;
31aa97d1
RH
4533}
4534
112bf079 4535#ifndef CONFIG_USER_ONLY
f79f1ca4 4536
21a8eced 4537static DisasJumpType op_testblock(DisasContext *s, DisasOps *o)
f79f1ca4
TH
4538{
4539 check_privileged(s);
f79f1ca4
TH
4540 gen_helper_testblock(cc_op, cpu_env, o->in2);
4541 set_cc_static(s);
21a8eced 4542 return DISAS_NEXT;
f79f1ca4
TH
4543}
4544
21a8eced 4545static DisasJumpType op_tprot(DisasContext *s, DisasOps *o)
112bf079 4546{
bb879430 4547 gen_helper_tprot(cc_op, cpu_env, o->addr1, o->in2);
112bf079 4548 set_cc_static(s);
21a8eced 4549 return DISAS_NEXT;
112bf079 4550}
f79f1ca4 4551
112bf079
RH
4552#endif
4553
21a8eced 4554static DisasJumpType op_tp(DisasContext *s, DisasOps *o)
5d4a655a
AJ
4555{
4556 TCGv_i32 l1 = tcg_const_i32(get_field(s->fields, l1) + 1);
4557 gen_helper_tp(cc_op, cpu_env, o->addr1, l1);
4558 tcg_temp_free_i32(l1);
4559 set_cc_static(s);
21a8eced 4560 return DISAS_NEXT;
5d4a655a
AJ
4561}
4562
21a8eced 4563static DisasJumpType op_tr(DisasContext *s, DisasOps *o)
0a949039
RH
4564{
4565 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
0a949039
RH
4566 gen_helper_tr(cpu_env, l, o->addr1, o->in2);
4567 tcg_temp_free_i32(l);
4568 set_cc_static(s);
21a8eced 4569 return DISAS_NEXT;
0a949039
RH
4570}
4571
21a8eced 4572static DisasJumpType op_tre(DisasContext *s, DisasOps *o)
3f4de675 4573{
3f4de675
AJ
4574 gen_helper_tre(o->out, cpu_env, o->out, o->out2, o->in2);
4575 return_low128(o->out2);
4576 set_cc_static(s);
21a8eced 4577 return DISAS_NEXT;
3f4de675
AJ
4578}
4579
21a8eced 4580static DisasJumpType op_trt(DisasContext *s, DisasOps *o)
54f00775
AJ
4581{
4582 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
54f00775
AJ
4583 gen_helper_trt(cc_op, cpu_env, l, o->addr1, o->in2);
4584 tcg_temp_free_i32(l);
4585 set_cc_static(s);
21a8eced 4586 return DISAS_NEXT;
54f00775
AJ
4587}
4588
21a8eced 4589static DisasJumpType op_trtr(DisasContext *s, DisasOps *o)
b213c9f5
RH
4590{
4591 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
4592 gen_helper_trtr(cc_op, cpu_env, l, o->addr1, o->in2);
4593 tcg_temp_free_i32(l);
4594 set_cc_static(s);
21a8eced 4595 return DISAS_NEXT;
b213c9f5
RH
4596}
4597
21a8eced 4598static DisasJumpType op_trXX(DisasContext *s, DisasOps *o)
4065ae76
AJ
4599{
4600 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4601 TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));
4602 TCGv_i32 sizes = tcg_const_i32(s->insn->opc & 3);
4603 TCGv_i32 tst = tcg_temp_new_i32();
4604 int m3 = get_field(s->fields, m3);
4605
3c39c800
RH
4606 if (!s390_has_feat(S390_FEAT_ETF2_ENH)) {
4607 m3 = 0;
4608 }
4065ae76
AJ
4609 if (m3 & 1) {
4610 tcg_gen_movi_i32(tst, -1);
4611 } else {
4612 tcg_gen_extrl_i64_i32(tst, regs[0]);
4613 if (s->insn->opc & 3) {
4614 tcg_gen_ext8u_i32(tst, tst);
4615 } else {
4616 tcg_gen_ext16u_i32(tst, tst);
4617 }
4618 }
4619 gen_helper_trXX(cc_op, cpu_env, r1, r2, tst, sizes);
4620
4621 tcg_temp_free_i32(r1);
4622 tcg_temp_free_i32(r2);
4623 tcg_temp_free_i32(sizes);
4624 tcg_temp_free_i32(tst);
4625 set_cc_static(s);
21a8eced 4626 return DISAS_NEXT;
4065ae76
AJ
4627}
4628
21a8eced 4629static DisasJumpType op_ts(DisasContext *s, DisasOps *o)
6699adfc
AJ
4630{
4631 TCGv_i32 t1 = tcg_const_i32(0xff);
4632 tcg_gen_atomic_xchg_i32(t1, o->in2, t1, get_mem_index(s), MO_UB);
4633 tcg_gen_extract_i32(cc_op, t1, 7, 1);
4634 tcg_temp_free_i32(t1);
4635 set_cc_static(s);
21a8eced 4636 return DISAS_NEXT;
6699adfc
AJ
4637}
4638
21a8eced 4639static DisasJumpType op_unpk(DisasContext *s, DisasOps *o)
0a949039
RH
4640{
4641 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
0a949039
RH
4642 gen_helper_unpk(cpu_env, l, o->addr1, o->in2);
4643 tcg_temp_free_i32(l);
21a8eced 4644 return DISAS_NEXT;
0a949039
RH
4645}
4646
21a8eced 4647static DisasJumpType op_unpka(DisasContext *s, DisasOps *o)
1a35f08a
AJ
4648{
4649 int l1 = get_field(s->fields, l1) + 1;
4650 TCGv_i32 l;
4651
4652 /* The length must not exceed 32 bytes. */
4653 if (l1 > 32) {
4654 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 4655 return DISAS_NORETURN;
1a35f08a
AJ
4656 }
4657 l = tcg_const_i32(l1);
4658 gen_helper_unpka(cc_op, cpu_env, o->addr1, l, o->in2);
4659 tcg_temp_free_i32(l);
4660 set_cc_static(s);
21a8eced 4661 return DISAS_NEXT;
1a35f08a
AJ
4662}
4663
21a8eced 4664static DisasJumpType op_unpku(DisasContext *s, DisasOps *o)
15417787
AJ
4665{
4666 int l1 = get_field(s->fields, l1) + 1;
4667 TCGv_i32 l;
4668
4669 /* The length must be even and should not exceed 64 bytes. */
4670 if ((l1 & 1) || (l1 > 64)) {
4671 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 4672 return DISAS_NORETURN;
15417787
AJ
4673 }
4674 l = tcg_const_i32(l1);
4675 gen_helper_unpku(cc_op, cpu_env, o->addr1, l, o->in2);
4676 tcg_temp_free_i32(l);
4677 set_cc_static(s);
21a8eced 4678 return DISAS_NEXT;
15417787
AJ
4679}
4680
4681
21a8eced 4682static DisasJumpType op_xc(DisasContext *s, DisasOps *o)
0a949039 4683{
d074ac6d
RH
4684 int d1 = get_field(s->fields, d1);
4685 int d2 = get_field(s->fields, d2);
4686 int b1 = get_field(s->fields, b1);
4687 int b2 = get_field(s->fields, b2);
4688 int l = get_field(s->fields, l1);
4689 TCGv_i32 t32;
4690
4691 o->addr1 = get_address(s, 0, b1, d1);
4692
4693 /* If the addresses are identical, this is a store/memset of zero. */
4694 if (b1 == b2 && d1 == d2 && (l + 1) <= 32) {
4695 o->in2 = tcg_const_i64(0);
4696
4697 l++;
4698 while (l >= 8) {
4699 tcg_gen_qemu_st64(o->in2, o->addr1, get_mem_index(s));
4700 l -= 8;
4701 if (l > 0) {
4702 tcg_gen_addi_i64(o->addr1, o->addr1, 8);
4703 }
4704 }
4705 if (l >= 4) {
4706 tcg_gen_qemu_st32(o->in2, o->addr1, get_mem_index(s));
4707 l -= 4;
4708 if (l > 0) {
4709 tcg_gen_addi_i64(o->addr1, o->addr1, 4);
4710 }
4711 }
4712 if (l >= 2) {
4713 tcg_gen_qemu_st16(o->in2, o->addr1, get_mem_index(s));
4714 l -= 2;
4715 if (l > 0) {
4716 tcg_gen_addi_i64(o->addr1, o->addr1, 2);
4717 }
4718 }
4719 if (l) {
4720 tcg_gen_qemu_st8(o->in2, o->addr1, get_mem_index(s));
4721 }
4722 gen_op_movi_cc(s, 0);
21a8eced 4723 return DISAS_NEXT;
d074ac6d
RH
4724 }
4725
4726 /* But in general we'll defer to a helper. */
4727 o->in2 = get_address(s, 0, b2, d2);
4728 t32 = tcg_const_i32(l);
d074ac6d
RH
4729 gen_helper_xc(cc_op, cpu_env, t32, o->addr1, o->in2);
4730 tcg_temp_free_i32(t32);
0a949039 4731 set_cc_static(s);
21a8eced 4732 return DISAS_NEXT;
0a949039
RH
4733}
4734
21a8eced 4735static DisasJumpType op_xor(DisasContext *s, DisasOps *o)
3bbfbd1f
RH
4736{
4737 tcg_gen_xor_i64(o->out, o->in1, o->in2);
21a8eced 4738 return DISAS_NEXT;
3bbfbd1f
RH
4739}
4740
21a8eced 4741static DisasJumpType op_xori(DisasContext *s, DisasOps *o)
facfc864
RH
4742{
4743 int shift = s->insn->data & 0xff;
4744 int size = s->insn->data >> 8;
4745 uint64_t mask = ((1ull << size) - 1) << shift;
4746
4747 assert(!o->g_in2);
4748 tcg_gen_shli_i64(o->in2, o->in2, shift);
4749 tcg_gen_xor_i64(o->out, o->in1, o->in2);
4750
4751 /* Produce the CC from only the bits manipulated. */
4752 tcg_gen_andi_i64(cc_dst, o->out, mask);
4753 set_cc_nz_u64(s, cc_dst);
21a8eced 4754 return DISAS_NEXT;
facfc864
RH
4755}
4756
21a8eced 4757static DisasJumpType op_xi(DisasContext *s, DisasOps *o)
f400be18
DH
4758{
4759 o->in1 = tcg_temp_new_i64();
4760
4761 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
4762 tcg_gen_qemu_ld_tl(o->in1, o->addr1, get_mem_index(s), s->insn->data);
4763 } else {
4764 /* Perform the atomic operation in memory. */
4765 tcg_gen_atomic_fetch_xor_i64(o->in1, o->addr1, o->in2, get_mem_index(s),
4766 s->insn->data);
4767 }
4768
4769 /* Recompute also for atomic case: needed for setting CC. */
4770 tcg_gen_xor_i64(o->out, o->in1, o->in2);
4771
4772 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
4773 tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), s->insn->data);
4774 }
21a8eced 4775 return DISAS_NEXT;
f400be18
DH
4776}
4777
21a8eced 4778static DisasJumpType op_zero(DisasContext *s, DisasOps *o)
24db8412
RH
4779{
4780 o->out = tcg_const_i64(0);
21a8eced 4781 return DISAS_NEXT;
24db8412
RH
4782}
4783
21a8eced 4784static DisasJumpType op_zero2(DisasContext *s, DisasOps *o)
24db8412
RH
4785{
4786 o->out = tcg_const_i64(0);
4787 o->out2 = o->out;
4788 o->g_out2 = true;
21a8eced 4789 return DISAS_NEXT;
24db8412
RH
4790}
4791
f6c232ce 4792#ifndef CONFIG_USER_ONLY
21a8eced 4793static DisasJumpType op_clp(DisasContext *s, DisasOps *o)
f6c232ce
CH
4794{
4795 TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));
4796
4797 check_privileged(s);
4798 gen_helper_clp(cpu_env, r2);
4799 tcg_temp_free_i32(r2);
4800 set_cc_static(s);
21a8eced 4801 return DISAS_NEXT;
f6c232ce
CH
4802}
4803
21a8eced 4804static DisasJumpType op_pcilg(DisasContext *s, DisasOps *o)
f6c232ce
CH
4805{
4806 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4807 TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));
4808
4809 check_privileged(s);
4810 gen_helper_pcilg(cpu_env, r1, r2);
4811 tcg_temp_free_i32(r1);
4812 tcg_temp_free_i32(r2);
4813 set_cc_static(s);
21a8eced 4814 return DISAS_NEXT;
f6c232ce
CH
4815}
4816
21a8eced 4817static DisasJumpType op_pcistg(DisasContext *s, DisasOps *o)
f6c232ce
CH
4818{
4819 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4820 TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));
4821
4822 check_privileged(s);
4823 gen_helper_pcistg(cpu_env, r1, r2);
4824 tcg_temp_free_i32(r1);
4825 tcg_temp_free_i32(r2);
4826 set_cc_static(s);
21a8eced 4827 return DISAS_NEXT;
f6c232ce
CH
4828}
4829
21a8eced 4830static DisasJumpType op_stpcifc(DisasContext *s, DisasOps *o)
f6c232ce
CH
4831{
4832 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4833 TCGv_i32 ar = tcg_const_i32(get_field(s->fields, b2));
4834
4835 check_privileged(s);
4836 gen_helper_stpcifc(cpu_env, r1, o->addr1, ar);
4837 tcg_temp_free_i32(ar);
4838 tcg_temp_free_i32(r1);
4839 set_cc_static(s);
21a8eced 4840 return DISAS_NEXT;
f6c232ce
CH
4841}
4842
21a8eced 4843static DisasJumpType op_sic(DisasContext *s, DisasOps *o)
f6c232ce
CH
4844{
4845 check_privileged(s);
4846 gen_helper_sic(cpu_env, o->in1, o->in2);
21a8eced 4847 return DISAS_NEXT;
f6c232ce
CH
4848}
4849
21a8eced 4850static DisasJumpType op_rpcit(DisasContext *s, DisasOps *o)
f6c232ce
CH
4851{
4852 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4853 TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));
4854
4855 check_privileged(s);
4856 gen_helper_rpcit(cpu_env, r1, r2);
4857 tcg_temp_free_i32(r1);
4858 tcg_temp_free_i32(r2);
4859 set_cc_static(s);
21a8eced 4860 return DISAS_NEXT;
f6c232ce
CH
4861}
4862
21a8eced 4863static DisasJumpType op_pcistb(DisasContext *s, DisasOps *o)
f6c232ce
CH
4864{
4865 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4866 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
4867 TCGv_i32 ar = tcg_const_i32(get_field(s->fields, b2));
4868
4869 check_privileged(s);
4870 gen_helper_pcistb(cpu_env, r1, r3, o->addr1, ar);
4871 tcg_temp_free_i32(ar);
4872 tcg_temp_free_i32(r1);
4873 tcg_temp_free_i32(r3);
4874 set_cc_static(s);
21a8eced 4875 return DISAS_NEXT;
f6c232ce
CH
4876}
4877
21a8eced 4878static DisasJumpType op_mpcifc(DisasContext *s, DisasOps *o)
f6c232ce
CH
4879{
4880 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4881 TCGv_i32 ar = tcg_const_i32(get_field(s->fields, b2));
4882
4883 check_privileged(s);
4884 gen_helper_mpcifc(cpu_env, r1, o->addr1, ar);
4885 tcg_temp_free_i32(ar);
4886 tcg_temp_free_i32(r1);
4887 set_cc_static(s);
21a8eced 4888 return DISAS_NEXT;
f6c232ce
CH
4889}
4890#endif
4891
ad044d09
RH
4892/* ====================================================================== */
4893/* The "Cc OUTput" generators. Given the generated output (and in some cases
4894 the original inputs), update the various cc data structures in order to
4895 be able to compute the new condition code. */
4896
b9bca3e5
RH
4897static void cout_abs32(DisasContext *s, DisasOps *o)
4898{
4899 gen_op_update1_cc_i64(s, CC_OP_ABS_32, o->out);
4900}
4901
4902static void cout_abs64(DisasContext *s, DisasOps *o)
4903{
4904 gen_op_update1_cc_i64(s, CC_OP_ABS_64, o->out);
4905}
4906
ad044d09
RH
4907static void cout_adds32(DisasContext *s, DisasOps *o)
4908{
4909 gen_op_update3_cc_i64(s, CC_OP_ADD_32, o->in1, o->in2, o->out);
4910}
4911
4912static void cout_adds64(DisasContext *s, DisasOps *o)
4913{
4914 gen_op_update3_cc_i64(s, CC_OP_ADD_64, o->in1, o->in2, o->out);
4915}
4916
4917static void cout_addu32(DisasContext *s, DisasOps *o)
4918{
4919 gen_op_update3_cc_i64(s, CC_OP_ADDU_32, o->in1, o->in2, o->out);
4920}
4921
4922static void cout_addu64(DisasContext *s, DisasOps *o)
4923{
4924 gen_op_update3_cc_i64(s, CC_OP_ADDU_64, o->in1, o->in2, o->out);
4925}
4926
4e4bb438
RH
4927static void cout_addc32(DisasContext *s, DisasOps *o)
4928{
4929 gen_op_update3_cc_i64(s, CC_OP_ADDC_32, o->in1, o->in2, o->out);
4930}
4931
4932static void cout_addc64(DisasContext *s, DisasOps *o)
4933{
4934 gen_op_update3_cc_i64(s, CC_OP_ADDC_64, o->in1, o->in2, o->out);
4935}
4936
a7e836d5
RH
4937static void cout_cmps32(DisasContext *s, DisasOps *o)
4938{
4939 gen_op_update2_cc_i64(s, CC_OP_LTGT_32, o->in1, o->in2);
4940}
4941
4942static void cout_cmps64(DisasContext *s, DisasOps *o)
4943{
4944 gen_op_update2_cc_i64(s, CC_OP_LTGT_64, o->in1, o->in2);
4945}
4946
4947static void cout_cmpu32(DisasContext *s, DisasOps *o)
4948{
4949 gen_op_update2_cc_i64(s, CC_OP_LTUGTU_32, o->in1, o->in2);
4950}
4951
4952static void cout_cmpu64(DisasContext *s, DisasOps *o)
4953{
4954 gen_op_update2_cc_i64(s, CC_OP_LTUGTU_64, o->in1, o->in2);
4955}
4956
587626f8
RH
4957static void cout_f32(DisasContext *s, DisasOps *o)
4958{
4959 gen_op_update1_cc_i64(s, CC_OP_NZ_F32, o->out);
4960}
4961
4962static void cout_f64(DisasContext *s, DisasOps *o)
4963{
4964 gen_op_update1_cc_i64(s, CC_OP_NZ_F64, o->out);
4965}
4966
4967static void cout_f128(DisasContext *s, DisasOps *o)
4968{
4969 gen_op_update2_cc_i64(s, CC_OP_NZ_F128, o->out, o->out2);
4970}
4971
b9bca3e5
RH
4972static void cout_nabs32(DisasContext *s, DisasOps *o)
4973{
4974 gen_op_update1_cc_i64(s, CC_OP_NABS_32, o->out);
4975}
4976
4977static void cout_nabs64(DisasContext *s, DisasOps *o)
4978{
4979 gen_op_update1_cc_i64(s, CC_OP_NABS_64, o->out);
4980}
4981
4982static void cout_neg32(DisasContext *s, DisasOps *o)
4983{
4984 gen_op_update1_cc_i64(s, CC_OP_COMP_32, o->out);
4985}
4986
4987static void cout_neg64(DisasContext *s, DisasOps *o)
4988{
4989 gen_op_update1_cc_i64(s, CC_OP_COMP_64, o->out);
4990}
4991
3bbfbd1f
RH
4992static void cout_nz32(DisasContext *s, DisasOps *o)
4993{
4994 tcg_gen_ext32u_i64(cc_dst, o->out);
4995 gen_op_update1_cc_i64(s, CC_OP_NZ, cc_dst);
4996}
4997
4998static void cout_nz64(DisasContext *s, DisasOps *o)
4999{
5000 gen_op_update1_cc_i64(s, CC_OP_NZ, o->out);
5001}
5002
11bf2d73
RH
5003static void cout_s32(DisasContext *s, DisasOps *o)
5004{
5005 gen_op_update1_cc_i64(s, CC_OP_LTGT0_32, o->out);
5006}
5007
5008static void cout_s64(DisasContext *s, DisasOps *o)
5009{
5010 gen_op_update1_cc_i64(s, CC_OP_LTGT0_64, o->out);
5011}
5012
ad044d09
RH
5013static void cout_subs32(DisasContext *s, DisasOps *o)
5014{
5015 gen_op_update3_cc_i64(s, CC_OP_SUB_32, o->in1, o->in2, o->out);
5016}
5017
5018static void cout_subs64(DisasContext *s, DisasOps *o)
5019{
5020 gen_op_update3_cc_i64(s, CC_OP_SUB_64, o->in1, o->in2, o->out);
5021}
5022
5023static void cout_subu32(DisasContext *s, DisasOps *o)
5024{
5025 gen_op_update3_cc_i64(s, CC_OP_SUBU_32, o->in1, o->in2, o->out);
5026}
5027
5028static void cout_subu64(DisasContext *s, DisasOps *o)
5029{
5030 gen_op_update3_cc_i64(s, CC_OP_SUBU_64, o->in1, o->in2, o->out);
5031}
5032
4e4bb438
RH
5033static void cout_subb32(DisasContext *s, DisasOps *o)
5034{
5035 gen_op_update3_cc_i64(s, CC_OP_SUBB_32, o->in1, o->in2, o->out);
5036}
5037
5038static void cout_subb64(DisasContext *s, DisasOps *o)
5039{
5040 gen_op_update3_cc_i64(s, CC_OP_SUBB_64, o->in1, o->in2, o->out);
5041}
5042
00d2dc19
RH
5043static void cout_tm32(DisasContext *s, DisasOps *o)
5044{
5045 gen_op_update2_cc_i64(s, CC_OP_TM_32, o->in1, o->in2);
5046}
5047
5048static void cout_tm64(DisasContext *s, DisasOps *o)
5049{
5050 gen_op_update2_cc_i64(s, CC_OP_TM_64, o->in1, o->in2);
5051}
5052
ad044d09 5053/* ====================================================================== */
805a2505 5054/* The "PREParation" generators. These initialize the DisasOps.OUT fields
ad044d09
RH
5055 with the TCG register to which we will write. Used in combination with
5056 the "wout" generators, in some cases we need a new temporary, and in
5057 some cases we can write to a TCG global. */
5058
5059static void prep_new(DisasContext *s, DisasFields *f, DisasOps *o)
5060{
5061 o->out = tcg_temp_new_i64();
5062}
49f7ee80 5063#define SPEC_prep_new 0
ad044d09 5064
891452e5
RH
5065static void prep_new_P(DisasContext *s, DisasFields *f, DisasOps *o)
5066{
5067 o->out = tcg_temp_new_i64();
5068 o->out2 = tcg_temp_new_i64();
5069}
49f7ee80 5070#define SPEC_prep_new_P 0
891452e5 5071
ad044d09
RH
5072static void prep_r1(DisasContext *s, DisasFields *f, DisasOps *o)
5073{
5074 o->out = regs[get_field(f, r1)];
5075 o->g_out = true;
5076}
49f7ee80 5077#define SPEC_prep_r1 0
ad044d09 5078
1ac5889f
RH
5079static void prep_r1_P(DisasContext *s, DisasFields *f, DisasOps *o)
5080{
1ac5889f
RH
5081 int r1 = get_field(f, r1);
5082 o->out = regs[r1];
49f7ee80 5083 o->out2 = regs[r1 + 1];
1ac5889f
RH
5084 o->g_out = o->g_out2 = true;
5085}
49f7ee80 5086#define SPEC_prep_r1_P SPEC_r1_even
1ac5889f 5087
587626f8
RH
5088static void prep_f1(DisasContext *s, DisasFields *f, DisasOps *o)
5089{
5090 o->out = fregs[get_field(f, r1)];
5091 o->g_out = true;
5092}
49f7ee80 5093#define SPEC_prep_f1 0
587626f8
RH
5094
5095static void prep_x1(DisasContext *s, DisasFields *f, DisasOps *o)
5096{
587626f8
RH
5097 int r1 = get_field(f, r1);
5098 o->out = fregs[r1];
49f7ee80 5099 o->out2 = fregs[r1 + 2];
587626f8
RH
5100 o->g_out = o->g_out2 = true;
5101}
49f7ee80 5102#define SPEC_prep_x1 SPEC_r1_f128
587626f8 5103
ad044d09
RH
5104/* ====================================================================== */
5105/* The "Write OUTput" generators. These generally perform some non-trivial
5106 copy of data to TCG globals, or to main memory. The trivial cases are
5107 generally handled by having a "prep" generator install the TCG global
5108 as the destination of the operation. */
5109
22c37a08
RH
5110static void wout_r1(DisasContext *s, DisasFields *f, DisasOps *o)
5111{
5112 store_reg(get_field(f, r1), o->out);
5113}
49f7ee80 5114#define SPEC_wout_r1 0
22c37a08 5115
afdc70be
RH
5116static void wout_r1_8(DisasContext *s, DisasFields *f, DisasOps *o)
5117{
5118 int r1 = get_field(f, r1);
5119 tcg_gen_deposit_i64(regs[r1], regs[r1], o->out, 0, 8);
5120}
49f7ee80 5121#define SPEC_wout_r1_8 0
afdc70be 5122
d54f5865
RH
5123static void wout_r1_16(DisasContext *s, DisasFields *f, DisasOps *o)
5124{
5125 int r1 = get_field(f, r1);
5126 tcg_gen_deposit_i64(regs[r1], regs[r1], o->out, 0, 16);
5127}
49f7ee80 5128#define SPEC_wout_r1_16 0
d54f5865 5129
ad044d09
RH
5130static void wout_r1_32(DisasContext *s, DisasFields *f, DisasOps *o)
5131{
5132 store_reg32_i64(get_field(f, r1), o->out);
5133}
49f7ee80 5134#define SPEC_wout_r1_32 0
ad044d09 5135
a1f12d85
AJ
5136static void wout_r1_32h(DisasContext *s, DisasFields *f, DisasOps *o)
5137{
5138 store_reg32h_i64(get_field(f, r1), o->out);
5139}
5140#define SPEC_wout_r1_32h 0
5141
891452e5
RH
5142static void wout_r1_P32(DisasContext *s, DisasFields *f, DisasOps *o)
5143{
891452e5
RH
5144 int r1 = get_field(f, r1);
5145 store_reg32_i64(r1, o->out);
49f7ee80 5146 store_reg32_i64(r1 + 1, o->out2);
891452e5 5147}
49f7ee80 5148#define SPEC_wout_r1_P32 SPEC_r1_even
891452e5 5149
d87aaf93
RH
5150static void wout_r1_D32(DisasContext *s, DisasFields *f, DisasOps *o)
5151{
d87aaf93 5152 int r1 = get_field(f, r1);
49f7ee80 5153 store_reg32_i64(r1 + 1, o->out);
d87aaf93
RH
5154 tcg_gen_shri_i64(o->out, o->out, 32);
5155 store_reg32_i64(r1, o->out);
5156}
49f7ee80 5157#define SPEC_wout_r1_D32 SPEC_r1_even
22c37a08 5158
1807aaa5
EB
5159static void wout_r3_P32(DisasContext *s, DisasFields *f, DisasOps *o)
5160{
5161 int r3 = get_field(f, r3);
5162 store_reg32_i64(r3, o->out);
5163 store_reg32_i64(r3 + 1, o->out2);
5164}
5165#define SPEC_wout_r3_P32 SPEC_r3_even
5166
5167static void wout_r3_P64(DisasContext *s, DisasFields *f, DisasOps *o)
5168{
5169 int r3 = get_field(f, r3);
5170 store_reg(r3, o->out);
5171 store_reg(r3 + 1, o->out2);
5172}
5173#define SPEC_wout_r3_P64 SPEC_r3_even
5174
d764a8d1
RH
5175static void wout_e1(DisasContext *s, DisasFields *f, DisasOps *o)
5176{
5177 store_freg32_i64(get_field(f, r1), o->out);
5178}
49f7ee80 5179#define SPEC_wout_e1 0
d764a8d1
RH
5180
5181static void wout_f1(DisasContext *s, DisasFields *f, DisasOps *o)
5182{
5183 store_freg(get_field(f, r1), o->out);
5184}
49f7ee80 5185#define SPEC_wout_f1 0
d764a8d1
RH
5186
5187static void wout_x1(DisasContext *s, DisasFields *f, DisasOps *o)
5188{
5189 int f1 = get_field(s->fields, r1);
5190 store_freg(f1, o->out);
49f7ee80 5191 store_freg(f1 + 2, o->out2);
d764a8d1 5192}
49f7ee80 5193#define SPEC_wout_x1 SPEC_r1_f128
d764a8d1 5194
22c37a08
RH
5195static void wout_cond_r1r2_32(DisasContext *s, DisasFields *f, DisasOps *o)
5196{
5197 if (get_field(f, r1) != get_field(f, r2)) {
5198 store_reg32_i64(get_field(f, r1), o->out);
5199 }
5200}
49f7ee80 5201#define SPEC_wout_cond_r1r2_32 0
d87aaf93 5202
d764a8d1
RH
5203static void wout_cond_e1e2(DisasContext *s, DisasFields *f, DisasOps *o)
5204{
5205 if (get_field(f, r1) != get_field(f, r2)) {
5206 store_freg32_i64(get_field(f, r1), o->out);
5207 }
5208}
49f7ee80 5209#define SPEC_wout_cond_e1e2 0
d764a8d1 5210
6a04d76a
RH
5211static void wout_m1_8(DisasContext *s, DisasFields *f, DisasOps *o)
5212{
5213 tcg_gen_qemu_st8(o->out, o->addr1, get_mem_index(s));
5214}
49f7ee80 5215#define SPEC_wout_m1_8 0
6a04d76a
RH
5216
5217static void wout_m1_16(DisasContext *s, DisasFields *f, DisasOps *o)
5218{
5219 tcg_gen_qemu_st16(o->out, o->addr1, get_mem_index(s));
5220}
49f7ee80 5221#define SPEC_wout_m1_16 0
6a04d76a 5222
21fc97c5
DH
5223#ifndef CONFIG_USER_ONLY
5224static void wout_m1_16a(DisasContext *s, DisasFields *f, DisasOps *o)
5225{
5226 tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), MO_TEUW | MO_ALIGN);
5227}
5228#define SPEC_wout_m1_16a 0
5229#endif
5230
ad044d09
RH
5231static void wout_m1_32(DisasContext *s, DisasFields *f, DisasOps *o)
5232{
5233 tcg_gen_qemu_st32(o->out, o->addr1, get_mem_index(s));
5234}
49f7ee80 5235#define SPEC_wout_m1_32 0
ad044d09 5236
21fc97c5
DH
5237#ifndef CONFIG_USER_ONLY
5238static void wout_m1_32a(DisasContext *s, DisasFields *f, DisasOps *o)
5239{
5240 tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), MO_TEUL | MO_ALIGN);
5241}
5242#define SPEC_wout_m1_32a 0
5243#endif
5244
ad044d09
RH
5245static void wout_m1_64(DisasContext *s, DisasFields *f, DisasOps *o)
5246{
5247 tcg_gen_qemu_st64(o->out, o->addr1, get_mem_index(s));
5248}
49f7ee80 5249#define SPEC_wout_m1_64 0
ad044d09 5250
21fc97c5
DH
5251#ifndef CONFIG_USER_ONLY
5252static void wout_m1_64a(DisasContext *s, DisasFields *f, DisasOps *o)
5253{
5254 tcg_gen_qemu_st_i64(o->out, o->addr1, get_mem_index(s), MO_TEQ | MO_ALIGN);
5255}
5256#define SPEC_wout_m1_64a 0
5257#endif
5258
ea20490f
RH
5259static void wout_m2_32(DisasContext *s, DisasFields *f, DisasOps *o)
5260{
5261 tcg_gen_qemu_st32(o->out, o->in2, get_mem_index(s));
5262}
49f7ee80 5263#define SPEC_wout_m2_32 0
ea20490f 5264
4dba4d6f 5265static void wout_in2_r1(DisasContext *s, DisasFields *f, DisasOps *o)
57af7289 5266{
4dba4d6f 5267 store_reg(get_field(f, r1), o->in2);
57af7289 5268}
4dba4d6f 5269#define SPEC_wout_in2_r1 0
57af7289 5270
4dba4d6f 5271static void wout_in2_r1_32(DisasContext *s, DisasFields *f, DisasOps *o)
57af7289 5272{
4dba4d6f 5273 store_reg32_i64(get_field(f, r1), o->in2);
57af7289 5274}
4dba4d6f 5275#define SPEC_wout_in2_r1_32 0
57af7289 5276
ad044d09
RH
5277/* ====================================================================== */
5278/* The "INput 1" generators. These load the first operand to an insn. */
5279
5280static void in1_r1(DisasContext *s, DisasFields *f, DisasOps *o)
5281{
5282 o->in1 = load_reg(get_field(f, r1));
5283}
49f7ee80 5284#define SPEC_in1_r1 0
ad044d09 5285
d1c04a2b
RH
5286static void in1_r1_o(DisasContext *s, DisasFields *f, DisasOps *o)
5287{
5288 o->in1 = regs[get_field(f, r1)];
5289 o->g_in1 = true;
5290}
49f7ee80 5291#define SPEC_in1_r1_o 0
d1c04a2b 5292
cbe24bfa
RH
5293static void in1_r1_32s(DisasContext *s, DisasFields *f, DisasOps *o)
5294{
5295 o->in1 = tcg_temp_new_i64();
5296 tcg_gen_ext32s_i64(o->in1, regs[get_field(f, r1)]);
5297}
49f7ee80 5298#define SPEC_in1_r1_32s 0
cbe24bfa
RH
5299
5300static void in1_r1_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5301{
5302 o->in1 = tcg_temp_new_i64();
5303 tcg_gen_ext32u_i64(o->in1, regs[get_field(f, r1)]);
5304}
49f7ee80 5305#define SPEC_in1_r1_32u 0
cbe24bfa 5306
32a44d58
RH
5307static void in1_r1_sr32(DisasContext *s, DisasFields *f, DisasOps *o)
5308{
5309 o->in1 = tcg_temp_new_i64();
5310 tcg_gen_shri_i64(o->in1, regs[get_field(f, r1)], 32);
5311}
49f7ee80 5312#define SPEC_in1_r1_sr32 0
32a44d58 5313
1ac5889f
RH
5314static void in1_r1p1(DisasContext *s, DisasFields *f, DisasOps *o)
5315{
49f7ee80 5316 o->in1 = load_reg(get_field(f, r1) + 1);
1ac5889f 5317}
49f7ee80 5318#define SPEC_in1_r1p1 SPEC_r1_even
1ac5889f 5319
d87aaf93
RH
5320static void in1_r1p1_32s(DisasContext *s, DisasFields *f, DisasOps *o)
5321{
d87aaf93 5322 o->in1 = tcg_temp_new_i64();
49f7ee80 5323 tcg_gen_ext32s_i64(o->in1, regs[get_field(f, r1) + 1]);
d87aaf93 5324}
49f7ee80 5325#define SPEC_in1_r1p1_32s SPEC_r1_even
d87aaf93
RH
5326
5327static void in1_r1p1_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5328{
d87aaf93 5329 o->in1 = tcg_temp_new_i64();
49f7ee80 5330 tcg_gen_ext32u_i64(o->in1, regs[get_field(f, r1) + 1]);
d87aaf93 5331}
49f7ee80 5332#define SPEC_in1_r1p1_32u SPEC_r1_even
d87aaf93 5333
891452e5
RH
5334static void in1_r1_D32(DisasContext *s, DisasFields *f, DisasOps *o)
5335{
891452e5
RH
5336 int r1 = get_field(f, r1);
5337 o->in1 = tcg_temp_new_i64();
5338 tcg_gen_concat32_i64(o->in1, regs[r1 + 1], regs[r1]);
5339}
49f7ee80 5340#define SPEC_in1_r1_D32 SPEC_r1_even
891452e5 5341
ad044d09
RH
5342static void in1_r2(DisasContext *s, DisasFields *f, DisasOps *o)
5343{
5344 o->in1 = load_reg(get_field(f, r2));
5345}
49f7ee80 5346#define SPEC_in1_r2 0
ad044d09 5347
a1f12d85
AJ
5348static void in1_r2_sr32(DisasContext *s, DisasFields *f, DisasOps *o)
5349{
5350 o->in1 = tcg_temp_new_i64();
5351 tcg_gen_shri_i64(o->in1, regs[get_field(f, r2)], 32);
5352}
5353#define SPEC_in1_r2_sr32 0
5354
ad044d09
RH
5355static void in1_r3(DisasContext *s, DisasFields *f, DisasOps *o)
5356{
5357 o->in1 = load_reg(get_field(f, r3));
5358}
49f7ee80 5359#define SPEC_in1_r3 0
ad044d09 5360
cbe24bfa
RH
5361static void in1_r3_o(DisasContext *s, DisasFields *f, DisasOps *o)
5362{
5363 o->in1 = regs[get_field(f, r3)];
5364 o->g_in1 = true;
5365}
49f7ee80 5366#define SPEC_in1_r3_o 0
cbe24bfa
RH
5367
5368static void in1_r3_32s(DisasContext *s, DisasFields *f, DisasOps *o)
5369{
5370 o->in1 = tcg_temp_new_i64();
5371 tcg_gen_ext32s_i64(o->in1, regs[get_field(f, r3)]);
5372}
49f7ee80 5373#define SPEC_in1_r3_32s 0
cbe24bfa
RH
5374
5375static void in1_r3_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5376{
5377 o->in1 = tcg_temp_new_i64();
5378 tcg_gen_ext32u_i64(o->in1, regs[get_field(f, r3)]);
5379}
49f7ee80 5380#define SPEC_in1_r3_32u 0
cbe24bfa 5381
b7886de3
RH
5382static void in1_r3_D32(DisasContext *s, DisasFields *f, DisasOps *o)
5383{
5384 int r3 = get_field(f, r3);
5385 o->in1 = tcg_temp_new_i64();
5386 tcg_gen_concat32_i64(o->in1, regs[r3 + 1], regs[r3]);
5387}
5388#define SPEC_in1_r3_D32 SPEC_r3_even
5389
00574261
RH
5390static void in1_e1(DisasContext *s, DisasFields *f, DisasOps *o)
5391{
5392 o->in1 = load_freg32_i64(get_field(f, r1));
5393}
49f7ee80 5394#define SPEC_in1_e1 0
00574261
RH
5395
5396static void in1_f1_o(DisasContext *s, DisasFields *f, DisasOps *o)
5397{
5398 o->in1 = fregs[get_field(f, r1)];
5399 o->g_in1 = true;
5400}
49f7ee80 5401#define SPEC_in1_f1_o 0
00574261 5402
587626f8
RH
5403static void in1_x1_o(DisasContext *s, DisasFields *f, DisasOps *o)
5404{
587626f8
RH
5405 int r1 = get_field(f, r1);
5406 o->out = fregs[r1];
49f7ee80 5407 o->out2 = fregs[r1 + 2];
587626f8
RH
5408 o->g_out = o->g_out2 = true;
5409}
49f7ee80 5410#define SPEC_in1_x1_o SPEC_r1_f128
587626f8 5411
2db014b5
RH
5412static void in1_f3_o(DisasContext *s, DisasFields *f, DisasOps *o)
5413{
5414 o->in1 = fregs[get_field(f, r3)];
5415 o->g_in1 = true;
5416}
49f7ee80 5417#define SPEC_in1_f3_o 0
2db014b5 5418
ad044d09
RH
5419static void in1_la1(DisasContext *s, DisasFields *f, DisasOps *o)
5420{
5421 o->addr1 = get_address(s, 0, get_field(f, b1), get_field(f, d1));
5422}
49f7ee80 5423#define SPEC_in1_la1 0
ad044d09 5424
e025e52a
RH
5425static void in1_la2(DisasContext *s, DisasFields *f, DisasOps *o)
5426{
5427 int x2 = have_field(f, x2) ? get_field(f, x2) : 0;
5428 o->addr1 = get_address(s, x2, get_field(f, b2), get_field(f, d2));
5429}
49f7ee80 5430#define SPEC_in1_la2 0
e025e52a 5431
a7e836d5
RH
5432static void in1_m1_8u(DisasContext *s, DisasFields *f, DisasOps *o)
5433{
5434 in1_la1(s, f, o);
5435 o->in1 = tcg_temp_new_i64();
5436 tcg_gen_qemu_ld8u(o->in1, o->addr1, get_mem_index(s));
5437}
49f7ee80 5438#define SPEC_in1_m1_8u 0
a7e836d5
RH
5439
5440static void in1_m1_16s(DisasContext *s, DisasFields *f, DisasOps *o)
5441{
5442 in1_la1(s, f, o);
5443 o->in1 = tcg_temp_new_i64();
5444 tcg_gen_qemu_ld16s(o->in1, o->addr1, get_mem_index(s));
5445}
49f7ee80 5446#define SPEC_in1_m1_16s 0
a7e836d5
RH
5447
5448static void in1_m1_16u(DisasContext *s, DisasFields *f, DisasOps *o)
5449{
5450 in1_la1(s, f, o);
5451 o->in1 = tcg_temp_new_i64();
5452 tcg_gen_qemu_ld16u(o->in1, o->addr1, get_mem_index(s));
5453}
49f7ee80 5454#define SPEC_in1_m1_16u 0
a7e836d5 5455
ad044d09
RH
5456static void in1_m1_32s(DisasContext *s, DisasFields *f, DisasOps *o)
5457{
5458 in1_la1(s, f, o);
5459 o->in1 = tcg_temp_new_i64();
5460 tcg_gen_qemu_ld32s(o->in1, o->addr1, get_mem_index(s));
5461}
49f7ee80 5462#define SPEC_in1_m1_32s 0
ad044d09 5463
e272b3ac
RH
5464static void in1_m1_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5465{
5466 in1_la1(s, f, o);
5467 o->in1 = tcg_temp_new_i64();
5468 tcg_gen_qemu_ld32u(o->in1, o->addr1, get_mem_index(s));
5469}
49f7ee80 5470#define SPEC_in1_m1_32u 0
e272b3ac 5471
ad044d09
RH
5472static void in1_m1_64(DisasContext *s, DisasFields *f, DisasOps *o)
5473{
5474 in1_la1(s, f, o);
5475 o->in1 = tcg_temp_new_i64();
5476 tcg_gen_qemu_ld64(o->in1, o->addr1, get_mem_index(s));
5477}
49f7ee80 5478#define SPEC_in1_m1_64 0
ad044d09
RH
5479
5480/* ====================================================================== */
5481/* The "INput 2" generators. These load the second operand to an insn. */
5482
e025e52a
RH
5483static void in2_r1_o(DisasContext *s, DisasFields *f, DisasOps *o)
5484{
5485 o->in2 = regs[get_field(f, r1)];
5486 o->g_in2 = true;
5487}
49f7ee80 5488#define SPEC_in2_r1_o 0
e025e52a
RH
5489
5490static void in2_r1_16u(DisasContext *s, DisasFields *f, DisasOps *o)
5491{
5492 o->in2 = tcg_temp_new_i64();
5493 tcg_gen_ext16u_i64(o->in2, regs[get_field(f, r1)]);
5494}
49f7ee80 5495#define SPEC_in2_r1_16u 0
e025e52a
RH
5496
5497static void in2_r1_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5498{
5499 o->in2 = tcg_temp_new_i64();
5500 tcg_gen_ext32u_i64(o->in2, regs[get_field(f, r1)]);
5501}
49f7ee80 5502#define SPEC_in2_r1_32u 0
e025e52a 5503
b7886de3
RH
5504static void in2_r1_D32(DisasContext *s, DisasFields *f, DisasOps *o)
5505{
5506 int r1 = get_field(f, r1);
5507 o->in2 = tcg_temp_new_i64();
5508 tcg_gen_concat32_i64(o->in2, regs[r1 + 1], regs[r1]);
5509}
5510#define SPEC_in2_r1_D32 SPEC_r1_even
5511
ad044d09
RH
5512static void in2_r2(DisasContext *s, DisasFields *f, DisasOps *o)
5513{
5514 o->in2 = load_reg(get_field(f, r2));
5515}
49f7ee80 5516#define SPEC_in2_r2 0
ad044d09 5517
d1c04a2b
RH
5518static void in2_r2_o(DisasContext *s, DisasFields *f, DisasOps *o)
5519{
5520 o->in2 = regs[get_field(f, r2)];
5521 o->g_in2 = true;
5522}
49f7ee80 5523#define SPEC_in2_r2_o 0
d1c04a2b 5524
8ac33cdb
RH
5525static void in2_r2_nz(DisasContext *s, DisasFields *f, DisasOps *o)
5526{
5527 int r2 = get_field(f, r2);
5528 if (r2 != 0) {
5529 o->in2 = load_reg(r2);
5530 }
5531}
49f7ee80 5532#define SPEC_in2_r2_nz 0
8ac33cdb 5533
c698d876
RH
5534static void in2_r2_8s(DisasContext *s, DisasFields *f, DisasOps *o)
5535{
5536 o->in2 = tcg_temp_new_i64();
5537 tcg_gen_ext8s_i64(o->in2, regs[get_field(f, r2)]);
5538}
49f7ee80 5539#define SPEC_in2_r2_8s 0
c698d876
RH
5540
5541static void in2_r2_8u(DisasContext *s, DisasFields *f, DisasOps *o)
5542{
5543 o->in2 = tcg_temp_new_i64();
5544 tcg_gen_ext8u_i64(o->in2, regs[get_field(f, r2)]);
5545}
49f7ee80 5546#define SPEC_in2_r2_8u 0
c698d876
RH
5547
5548static void in2_r2_16s(DisasContext *s, DisasFields *f, DisasOps *o)
5549{
5550 o->in2 = tcg_temp_new_i64();
5551 tcg_gen_ext16s_i64(o->in2, regs[get_field(f, r2)]);
5552}
49f7ee80 5553#define SPEC_in2_r2_16s 0
c698d876
RH
5554
5555static void in2_r2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
5556{
5557 o->in2 = tcg_temp_new_i64();
5558 tcg_gen_ext16u_i64(o->in2, regs[get_field(f, r2)]);
5559}
49f7ee80 5560#define SPEC_in2_r2_16u 0
c698d876 5561
ad044d09
RH
5562static void in2_r3(DisasContext *s, DisasFields *f, DisasOps *o)
5563{
5564 o->in2 = load_reg(get_field(f, r3));
5565}
49f7ee80 5566#define SPEC_in2_r3 0
ad044d09 5567
a1f12d85
AJ
5568static void in2_r3_sr32(DisasContext *s, DisasFields *f, DisasOps *o)
5569{
5570 o->in2 = tcg_temp_new_i64();
5571 tcg_gen_shri_i64(o->in2, regs[get_field(f, r3)], 32);
5572}
5573#define SPEC_in2_r3_sr32 0
5574
ad044d09
RH
5575static void in2_r2_32s(DisasContext *s, DisasFields *f, DisasOps *o)
5576{
5577 o->in2 = tcg_temp_new_i64();
5578 tcg_gen_ext32s_i64(o->in2, regs[get_field(f, r2)]);
5579}
49f7ee80 5580#define SPEC_in2_r2_32s 0
ad044d09
RH
5581
5582static void in2_r2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5583{
5584 o->in2 = tcg_temp_new_i64();
5585 tcg_gen_ext32u_i64(o->in2, regs[get_field(f, r2)]);
5586}
49f7ee80 5587#define SPEC_in2_r2_32u 0
ad044d09 5588
a1f12d85
AJ
5589static void in2_r2_sr32(DisasContext *s, DisasFields *f, DisasOps *o)
5590{
5591 o->in2 = tcg_temp_new_i64();
5592 tcg_gen_shri_i64(o->in2, regs[get_field(f, r2)], 32);
5593}
5594#define SPEC_in2_r2_sr32 0
5595
d764a8d1
RH
5596static void in2_e2(DisasContext *s, DisasFields *f, DisasOps *o)
5597{
5598 o->in2 = load_freg32_i64(get_field(f, r2));
5599}
49f7ee80 5600#define SPEC_in2_e2 0
d764a8d1
RH
5601
5602static void in2_f2_o(DisasContext *s, DisasFields *f, DisasOps *o)
5603{
5604 o->in2 = fregs[get_field(f, r2)];
5605 o->g_in2 = true;
5606}
49f7ee80 5607#define SPEC_in2_f2_o 0
d764a8d1
RH
5608
5609static void in2_x2_o(DisasContext *s, DisasFields *f, DisasOps *o)
5610{
587626f8
RH
5611 int r2 = get_field(f, r2);
5612 o->in1 = fregs[r2];
49f7ee80 5613 o->in2 = fregs[r2 + 2];
d764a8d1
RH
5614 o->g_in1 = o->g_in2 = true;
5615}
49f7ee80 5616#define SPEC_in2_x2_o SPEC_r2_f128
d764a8d1 5617
374724f9
RH
5618static void in2_ra2(DisasContext *s, DisasFields *f, DisasOps *o)
5619{
5620 o->in2 = get_address(s, 0, get_field(f, r2), 0);
5621}
49f7ee80 5622#define SPEC_in2_ra2 0
374724f9 5623
ad044d09
RH
5624static void in2_a2(DisasContext *s, DisasFields *f, DisasOps *o)
5625{
5626 int x2 = have_field(f, x2) ? get_field(f, x2) : 0;
5627 o->in2 = get_address(s, x2, get_field(f, b2), get_field(f, d2));
5628}
49f7ee80 5629#define SPEC_in2_a2 0
ad044d09 5630
a7e836d5
RH
5631static void in2_ri2(DisasContext *s, DisasFields *f, DisasOps *o)
5632{
eccf741a 5633 o->in2 = tcg_const_i64(s->base.pc_next + (int64_t)get_field(f, i2) * 2);
a7e836d5 5634}
49f7ee80 5635#define SPEC_in2_ri2 0
a7e836d5 5636
cbe24bfa
RH
5637static void in2_sh32(DisasContext *s, DisasFields *f, DisasOps *o)
5638{
5639 help_l2_shift(s, f, o, 31);
5640}
49f7ee80 5641#define SPEC_in2_sh32 0
cbe24bfa
RH
5642
5643static void in2_sh64(DisasContext *s, DisasFields *f, DisasOps *o)
5644{
5645 help_l2_shift(s, f, o, 63);
5646}
49f7ee80 5647#define SPEC_in2_sh64 0
cbe24bfa 5648
afdc70be
RH
5649static void in2_m2_8u(DisasContext *s, DisasFields *f, DisasOps *o)
5650{
5651 in2_a2(s, f, o);
5652 tcg_gen_qemu_ld8u(o->in2, o->in2, get_mem_index(s));
5653}
49f7ee80 5654#define SPEC_in2_m2_8u 0
afdc70be 5655
d82287de
RH
5656static void in2_m2_16s(DisasContext *s, DisasFields *f, DisasOps *o)
5657{
5658 in2_a2(s, f, o);
5659 tcg_gen_qemu_ld16s(o->in2, o->in2, get_mem_index(s));
5660}
49f7ee80 5661#define SPEC_in2_m2_16s 0
d82287de 5662
d54f5865
RH
5663static void in2_m2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
5664{
5665 in2_a2(s, f, o);
5666 tcg_gen_qemu_ld16u(o->in2, o->in2, get_mem_index(s));
5667}
49f7ee80 5668#define SPEC_in2_m2_16u 0
d54f5865 5669
ad044d09
RH
5670static void in2_m2_32s(DisasContext *s, DisasFields *f, DisasOps *o)
5671{
5672 in2_a2(s, f, o);
5673 tcg_gen_qemu_ld32s(o->in2, o->in2, get_mem_index(s));
5674}
49f7ee80 5675#define SPEC_in2_m2_32s 0
ad044d09
RH
5676
5677static void in2_m2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5678{
5679 in2_a2(s, f, o);
5680 tcg_gen_qemu_ld32u(o->in2, o->in2, get_mem_index(s));
5681}
49f7ee80 5682#define SPEC_in2_m2_32u 0
ad044d09 5683
21fc97c5
DH
5684#ifndef CONFIG_USER_ONLY
5685static void in2_m2_32ua(DisasContext *s, DisasFields *f, DisasOps *o)
5686{
5687 in2_a2(s, f, o);
5688 tcg_gen_qemu_ld_tl(o->in2, o->in2, get_mem_index(s), MO_TEUL | MO_ALIGN);
5689}
5690#define SPEC_in2_m2_32ua 0
5691#endif
5692
ad044d09
RH
5693static void in2_m2_64(DisasContext *s, DisasFields *f, DisasOps *o)
5694{
5695 in2_a2(s, f, o);
5696 tcg_gen_qemu_ld64(o->in2, o->in2, get_mem_index(s));
5697}
49f7ee80 5698#define SPEC_in2_m2_64 0
ad044d09 5699
21fc97c5
DH
5700#ifndef CONFIG_USER_ONLY
5701static void in2_m2_64a(DisasContext *s, DisasFields *f, DisasOps *o)
5702{
5703 in2_a2(s, f, o);
5704 tcg_gen_qemu_ld_i64(o->in2, o->in2, get_mem_index(s), MO_TEQ | MO_ALIGN);
5705}
5706#define SPEC_in2_m2_64a 0
5707#endif
5708
a7e836d5
RH
5709static void in2_mri2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
5710{
5711 in2_ri2(s, f, o);
5712 tcg_gen_qemu_ld16u(o->in2, o->in2, get_mem_index(s));
5713}
49f7ee80 5714#define SPEC_in2_mri2_16u 0
a7e836d5
RH
5715
5716static void in2_mri2_32s(DisasContext *s, DisasFields *f, DisasOps *o)
5717{
5718 in2_ri2(s, f, o);
5719 tcg_gen_qemu_ld32s(o->in2, o->in2, get_mem_index(s));
5720}
49f7ee80 5721#define SPEC_in2_mri2_32s 0
a7e836d5
RH
5722
5723static void in2_mri2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5724{
5725 in2_ri2(s, f, o);
5726 tcg_gen_qemu_ld32u(o->in2, o->in2, get_mem_index(s));
5727}
49f7ee80 5728#define SPEC_in2_mri2_32u 0
a7e836d5
RH
5729
5730static void in2_mri2_64(DisasContext *s, DisasFields *f, DisasOps *o)
5731{
5732 in2_ri2(s, f, o);
5733 tcg_gen_qemu_ld64(o->in2, o->in2, get_mem_index(s));
5734}
49f7ee80 5735#define SPEC_in2_mri2_64 0
a7e836d5 5736
ad044d09
RH
5737static void in2_i2(DisasContext *s, DisasFields *f, DisasOps *o)
5738{
5739 o->in2 = tcg_const_i64(get_field(f, i2));
5740}
49f7ee80 5741#define SPEC_in2_i2 0
ad044d09 5742
a7e836d5
RH
5743static void in2_i2_8u(DisasContext *s, DisasFields *f, DisasOps *o)
5744{
5745 o->in2 = tcg_const_i64((uint8_t)get_field(f, i2));
5746}
49f7ee80 5747#define SPEC_in2_i2_8u 0
a7e836d5
RH
5748
5749static void in2_i2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
5750{
5751 o->in2 = tcg_const_i64((uint16_t)get_field(f, i2));
5752}
49f7ee80 5753#define SPEC_in2_i2_16u 0
a7e836d5 5754
ad044d09
RH
5755static void in2_i2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5756{
5757 o->in2 = tcg_const_i64((uint32_t)get_field(f, i2));
5758}
49f7ee80 5759#define SPEC_in2_i2_32u 0
ad044d09 5760
ade9dea4
RH
5761static void in2_i2_16u_shl(DisasContext *s, DisasFields *f, DisasOps *o)
5762{
5763 uint64_t i2 = (uint16_t)get_field(f, i2);
5764 o->in2 = tcg_const_i64(i2 << s->insn->data);
5765}
49f7ee80 5766#define SPEC_in2_i2_16u_shl 0
ade9dea4
RH
5767
5768static void in2_i2_32u_shl(DisasContext *s, DisasFields *f, DisasOps *o)
5769{
5770 uint64_t i2 = (uint32_t)get_field(f, i2);
5771 o->in2 = tcg_const_i64(i2 << s->insn->data);
5772}
49f7ee80 5773#define SPEC_in2_i2_32u_shl 0
ade9dea4 5774
ad8a4570
AG
5775#ifndef CONFIG_USER_ONLY
5776static void in2_insn(DisasContext *s, DisasFields *f, DisasOps *o)
5777{
5778 o->in2 = tcg_const_i64(s->fields->raw_insn);
5779}
5780#define SPEC_in2_insn 0
5781#endif
5782
ad044d09
RH
5783/* ====================================================================== */
5784
5785/* Find opc within the table of insns. This is formulated as a switch
5786 statement so that (1) we get compile-time notice of cut-paste errors
5787 for duplicated opcodes, and (2) the compiler generates the binary
5788 search tree, rather than us having to post-process the table. */
5789
5790#define C(OPC, NM, FT, FC, I1, I2, P, W, OP, CC) \
5791 D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, 0)
5792
5793#define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) insn_ ## NM,
5794
5795enum DisasInsnEnum {
5796#include "insn-data.def"
5797};
5798
5799#undef D
49f7ee80
RH
5800#define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) { \
5801 .opc = OPC, \
5802 .fmt = FMT_##FT, \
5803 .fac = FAC_##FC, \
5804 .spec = SPEC_in1_##I1 | SPEC_in2_##I2 | SPEC_prep_##P | SPEC_wout_##W, \
5805 .name = #NM, \
5806 .help_in1 = in1_##I1, \
5807 .help_in2 = in2_##I2, \
5808 .help_prep = prep_##P, \
5809 .help_wout = wout_##W, \
5810 .help_cout = cout_##CC, \
5811 .help_op = op_##OP, \
5812 .data = D \
ad044d09
RH
5813 },
5814
5815/* Allow 0 to be used for NULL in the table below. */
5816#define in1_0 NULL
5817#define in2_0 NULL
5818#define prep_0 NULL
5819#define wout_0 NULL
5820#define cout_0 NULL
5821#define op_0 NULL
5822
49f7ee80
RH
5823#define SPEC_in1_0 0
5824#define SPEC_in2_0 0
5825#define SPEC_prep_0 0
5826#define SPEC_wout_0 0
5827
d20bd43c
RH
5828/* Give smaller names to the various facilities. */
5829#define FAC_Z S390_FEAT_ZARCH
5830#define FAC_CASS S390_FEAT_COMPARE_AND_SWAP_AND_STORE
d20bd43c
RH
5831#define FAC_DFP S390_FEAT_DFP
5832#define FAC_DFPR S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* DFP-rounding */
5833#define FAC_DO S390_FEAT_STFLE_45 /* distinct-operands */
5834#define FAC_EE S390_FEAT_EXECUTE_EXT
5835#define FAC_EI S390_FEAT_EXTENDED_IMMEDIATE
5836#define FAC_FPE S390_FEAT_FLOATING_POINT_EXT
5837#define FAC_FPSSH S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* FPS-sign-handling */
5838#define FAC_FPRGR S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* FPR-GR-transfer */
5839#define FAC_GIE S390_FEAT_GENERAL_INSTRUCTIONS_EXT
5840#define FAC_HFP_MA S390_FEAT_HFP_MADDSUB
5841#define FAC_HW S390_FEAT_STFLE_45 /* high-word */
5842#define FAC_IEEEE_SIM S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* IEEE-exception-simulation */
5843#define FAC_MIE S390_FEAT_STFLE_49 /* misc-instruction-extensions */
5844#define FAC_LAT S390_FEAT_STFLE_49 /* load-and-trap */
5845#define FAC_LOC S390_FEAT_STFLE_45 /* load/store on condition 1 */
45aa9aa3 5846#define FAC_LOC2 S390_FEAT_STFLE_53 /* load/store on condition 2 */
d20bd43c
RH
5847#define FAC_LD S390_FEAT_LONG_DISPLACEMENT
5848#define FAC_PC S390_FEAT_STFLE_45 /* population count */
5849#define FAC_SCF S390_FEAT_STORE_CLOCK_FAST
5850#define FAC_SFLE S390_FEAT_STFLE
5851#define FAC_ILA S390_FEAT_STFLE_45 /* interlocked-access-facility 1 */
3e7e5e0b 5852#define FAC_MVCOS S390_FEAT_MOVE_WITH_OPTIONAL_SPEC
d20bd43c
RH
5853#define FAC_LPP S390_FEAT_SET_PROGRAM_PARAMETERS /* load-program-parameter */
5854#define FAC_DAT_ENH S390_FEAT_DAT_ENH
5855#define FAC_E2 S390_FEAT_EXTENDED_TRANSLATION_2
6a68acd5 5856#define FAC_EH S390_FEAT_STFLE_49 /* execution-hint */
632c61a9 5857#define FAC_PPA S390_FEAT_STFLE_49 /* processor-assist */
c2a5c1d7 5858#define FAC_LZRB S390_FEAT_STFLE_53 /* load-and-zero-rightmost-byte */
941ef3db 5859#define FAC_ETF3 S390_FEAT_EXTENDED_TRANSLATION_3
7705c750
DH
5860#define FAC_MSA S390_FEAT_MSA /* message-security-assist facility */
5861#define FAC_MSA3 S390_FEAT_MSA_EXT_3 /* msa-extension-3 facility */
5862#define FAC_MSA4 S390_FEAT_MSA_EXT_4 /* msa-extension-4 facility */
5863#define FAC_MSA5 S390_FEAT_MSA_EXT_5 /* msa-extension-5 facility */
4bac52f5 5864#define FAC_ECT S390_FEAT_EXTRACT_CPU_TIME
f6c232ce
CH
5865#define FAC_PCI S390_FEAT_ZPCI /* z/PCI facility */
5866#define FAC_AIS S390_FEAT_ADAPTER_INT_SUPPRESSION
d20bd43c 5867
ad044d09
RH
5868static const DisasInsn insn_info[] = {
5869#include "insn-data.def"
5870};
5871
5872#undef D
5873#define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) \
5874 case OPC: return &insn_info[insn_ ## NM];
5875
5876static const DisasInsn *lookup_opc(uint16_t opc)
5877{
5878 switch (opc) {
5879#include "insn-data.def"
5880 default:
5881 return NULL;
5882 }
5883}
5884
5885#undef D
5886#undef C
5887
5888/* Extract a field from the insn. The INSN should be left-aligned in
5889 the uint64_t so that we can more easily utilize the big-bit-endian
5890 definitions we extract from the Principals of Operation. */
5891
5892static void extract_field(DisasFields *o, const DisasField *f, uint64_t insn)
5893{
5894 uint32_t r, m;
5895
5896 if (f->size == 0) {
5897 return;
5898 }
5899
5900 /* Zero extract the field from the insn. */
5901 r = (insn << f->beg) >> (64 - f->size);
5902
5903 /* Sign-extend, or un-swap the field as necessary. */
5904 switch (f->type) {
5905 case 0: /* unsigned */
5906 break;
5907 case 1: /* signed */
5908 assert(f->size <= 32);
5909 m = 1u << (f->size - 1);
5910 r = (r ^ m) - m;
5911 break;
5912 case 2: /* dl+dh split, signed 20 bit. */
5913 r = ((int8_t)r << 12) | (r >> 8);
5914 break;
5915 default:
5916 abort();
5917 }
5918
5919 /* Validate that the "compressed" encoding we selected above is valid.
5920 I.e. we havn't make two different original fields overlap. */
5921 assert(((o->presentC >> f->indexC) & 1) == 0);
5922 o->presentC |= 1 << f->indexC;
5923 o->presentO |= 1 << f->indexO;
5924
5925 o->c[f->indexC] = r;
5926}
5927
5928/* Lookup the insn at the current PC, extracting the operands into O and
5929 returning the info struct for the insn. Returns NULL for invalid insn. */
5930
5931static const DisasInsn *extract_insn(CPUS390XState *env, DisasContext *s,
5932 DisasFields *f)
5933{
eccf741a 5934 uint64_t insn, pc = s->base.pc_next;
d5a103cd 5935 int op, op2, ilen;
ad044d09
RH
5936 const DisasInsn *info;
5937
303c681a
RH
5938 if (unlikely(s->ex_value)) {
5939 /* Drop the EX data now, so that it's clear on exception paths. */
5940 TCGv_i64 zero = tcg_const_i64(0);
5941 tcg_gen_st_i64(zero, cpu_env, offsetof(CPUS390XState, ex_value));
5942 tcg_temp_free_i64(zero);
d5a103cd 5943
303c681a
RH
5944 /* Extract the values saved by EXECUTE. */
5945 insn = s->ex_value & 0xffffffffffff0000ull;
5946 ilen = s->ex_value & 0xf;
5947 op = insn >> 56;
5948 } else {
5949 insn = ld_code2(env, pc);
5950 op = (insn >> 8) & 0xff;
5951 ilen = get_ilen(op);
5952 switch (ilen) {
5953 case 2:
5954 insn = insn << 48;
5955 break;
5956 case 4:
5957 insn = ld_code4(env, pc) << 32;
5958 break;
5959 case 6:
5960 insn = (insn << 48) | (ld_code4(env, pc + 2) << 16);
5961 break;
5962 default:
5963 g_assert_not_reached();
5964 }
ad044d09 5965 }
eccf741a 5966 s->pc_tmp = s->base.pc_next + ilen;
303c681a 5967 s->ilen = ilen;
ad044d09
RH
5968
5969 /* We can't actually determine the insn format until we've looked up
5970 the full insn opcode. Which we can't do without locating the
5971 secondary opcode. Assume by default that OP2 is at bit 40; for
5972 those smaller insns that don't actually have a secondary opcode
5973 this will correctly result in OP2 = 0. */
5974 switch (op) {
5975 case 0x01: /* E */
5976 case 0x80: /* S */
5977 case 0x82: /* S */
5978 case 0x93: /* S */
6a68acd5 5979 case 0xb2: /* S, RRF, RRE, IE */
ad044d09
RH
5980 case 0xb3: /* RRE, RRD, RRF */
5981 case 0xb9: /* RRE, RRF */
5982 case 0xe5: /* SSE, SIL */
5983 op2 = (insn << 8) >> 56;
5984 break;
5985 case 0xa5: /* RI */
5986 case 0xa7: /* RI */
5987 case 0xc0: /* RIL */
5988 case 0xc2: /* RIL */
5989 case 0xc4: /* RIL */
5990 case 0xc6: /* RIL */
5991 case 0xc8: /* SSF */
5992 case 0xcc: /* RIL */
5993 op2 = (insn << 12) >> 60;
5994 break;
6a68acd5
RH
5995 case 0xc5: /* MII */
5996 case 0xc7: /* SMI */
ad044d09
RH
5997 case 0xd0 ... 0xdf: /* SS */
5998 case 0xe1: /* SS */
5999 case 0xe2: /* SS */
6000 case 0xe8: /* SS */
6001 case 0xe9: /* SS */
6002 case 0xea: /* SS */
6003 case 0xee ... 0xf3: /* SS */
6004 case 0xf8 ... 0xfd: /* SS */
6005 op2 = 0;
6006 break;
6007 default:
6008 op2 = (insn << 40) >> 56;
6009 break;
6010 }
6011
6012 memset(f, 0, sizeof(*f));
ad8a4570 6013 f->raw_insn = insn;
ad044d09
RH
6014 f->op = op;
6015 f->op2 = op2;
6016
6017 /* Lookup the instruction. */
6018 info = lookup_opc(op << 8 | op2);
6019
6020 /* If we found it, extract the operands. */
6021 if (info != NULL) {
6022 DisasFormat fmt = info->fmt;
6023 int i;
6024
6025 for (i = 0; i < NUM_C_FIELD; ++i) {
6026 extract_field(f, &format_info[fmt].op[i], insn);
6027 }
6028 }
6029 return info;
6030}
6031
21a8eced 6032static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s)
ad044d09
RH
6033{
6034 const DisasInsn *insn;
21a8eced 6035 DisasJumpType ret = DISAS_NEXT;
ad044d09
RH
6036 DisasFields f;
6037 DisasOps o;
6038
4f3adfb2 6039 /* Search for the insn in the table. */
ad044d09 6040 insn = extract_insn(env, s, &f);
e023e832 6041
4f3adfb2 6042 /* Not found means unimplemented/illegal opcode. */
ad044d09 6043 if (insn == NULL) {
4f3adfb2
RH
6044 qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%02x%02x\n",
6045 f.op, f.op2);
6046 gen_illegal_opcode(s);
21a8eced 6047 return DISAS_NORETURN;
ad044d09
RH
6048 }
6049
f0e0d817 6050#ifndef CONFIG_USER_ONLY
eccf741a
EC
6051 if (s->base.tb->flags & FLAG_MASK_PER) {
6052 TCGv_i64 addr = tcg_const_i64(s->base.pc_next);
f0e0d817
AJ
6053 gen_helper_per_ifetch(cpu_env, addr);
6054 tcg_temp_free_i64(addr);
6055 }
6056#endif
6057
49f7ee80
RH
6058 /* Check for insn specification exceptions. */
6059 if (insn->spec) {
6060 int spec = insn->spec, excp = 0, r;
6061
6062 if (spec & SPEC_r1_even) {
6063 r = get_field(&f, r1);
6064 if (r & 1) {
6065 excp = PGM_SPECIFICATION;
6066 }
6067 }
6068 if (spec & SPEC_r2_even) {
6069 r = get_field(&f, r2);
6070 if (r & 1) {
b7886de3
RH
6071 excp = PGM_SPECIFICATION;
6072 }
6073 }
6074 if (spec & SPEC_r3_even) {
6075 r = get_field(&f, r3);
6076 if (r & 1) {
49f7ee80
RH
6077 excp = PGM_SPECIFICATION;
6078 }
6079 }
6080 if (spec & SPEC_r1_f128) {
6081 r = get_field(&f, r1);
6082 if (r > 13) {
6083 excp = PGM_SPECIFICATION;
6084 }
6085 }
6086 if (spec & SPEC_r2_f128) {
6087 r = get_field(&f, r2);
6088 if (r > 13) {
6089 excp = PGM_SPECIFICATION;
6090 }
6091 }
6092 if (excp) {
6093 gen_program_exception(s, excp);
21a8eced 6094 return DISAS_NORETURN;
49f7ee80
RH
6095 }
6096 }
6097
ad044d09
RH
6098 /* Set up the strutures we use to communicate with the helpers. */
6099 s->insn = insn;
6100 s->fields = &f;
6101 o.g_out = o.g_out2 = o.g_in1 = o.g_in2 = false;
f764718d
RH
6102 o.out = NULL;
6103 o.out2 = NULL;
6104 o.in1 = NULL;
6105 o.in2 = NULL;
6106 o.addr1 = NULL;
ad044d09
RH
6107
6108 /* Implement the instruction. */
6109 if (insn->help_in1) {
6110 insn->help_in1(s, &f, &o);
6111 }
6112 if (insn->help_in2) {
6113 insn->help_in2(s, &f, &o);
6114 }
6115 if (insn->help_prep) {
6116 insn->help_prep(s, &f, &o);
6117 }
6118 if (insn->help_op) {
6119 ret = insn->help_op(s, &o);
6120 }
6121 if (insn->help_wout) {
6122 insn->help_wout(s, &f, &o);
6123 }
6124 if (insn->help_cout) {
6125 insn->help_cout(s, &o);
6126 }
6127
6128 /* Free any temporaries created by the helpers. */
f764718d 6129 if (o.out && !o.g_out) {
ad044d09
RH
6130 tcg_temp_free_i64(o.out);
6131 }
f764718d 6132 if (o.out2 && !o.g_out2) {
ad044d09
RH
6133 tcg_temp_free_i64(o.out2);
6134 }
f764718d 6135 if (o.in1 && !o.g_in1) {
ad044d09
RH
6136 tcg_temp_free_i64(o.in1);
6137 }
f764718d 6138 if (o.in2 && !o.g_in2) {
ad044d09
RH
6139 tcg_temp_free_i64(o.in2);
6140 }
f764718d 6141 if (o.addr1) {
ad044d09
RH
6142 tcg_temp_free_i64(o.addr1);
6143 }
6144
777c98c3 6145#ifndef CONFIG_USER_ONLY
eccf741a 6146 if (s->base.tb->flags & FLAG_MASK_PER) {
777c98c3 6147 /* An exception might be triggered, save PSW if not already done. */
21a8eced 6148 if (ret == DISAS_NEXT || ret == DISAS_PC_STALE) {
eccf741a 6149 tcg_gen_movi_i64(psw_addr, s->pc_tmp);
777c98c3
AJ
6150 }
6151
777c98c3
AJ
6152 /* Call the helper to check for a possible PER exception. */
6153 gen_helper_per_check_exception(cpu_env);
6154 }
6155#endif
6156
ad044d09 6157 /* Advance to the next instruction. */
eccf741a 6158 s->base.pc_next = s->pc_tmp;
ad044d09 6159 return ret;
e023e832
AG
6160}
6161
c88691aa 6162static void s390x_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
e023e832 6163{
c88691aa 6164 DisasContext *dc = container_of(dcbase, DisasContext, base);
e023e832 6165
e023e832 6166 /* 31-bit mode */
c88691aa
EC
6167 if (!(dc->base.tb->flags & FLAG_MASK_64)) {
6168 dc->base.pc_first &= 0x7fffffff;
6169 dc->base.pc_next = dc->base.pc_first;
e023e832
AG
6170 }
6171
c88691aa
EC
6172 dc->cc_op = CC_OP_DYNAMIC;
6173 dc->ex_value = dc->base.tb->cs_base;
6174 dc->do_debug = dc->base.singlestep_enabled;
6175}
e023e832 6176
c88691aa
EC
6177static void s390x_tr_tb_start(DisasContextBase *db, CPUState *cs)
6178{
6179}
e023e832 6180
c88691aa
EC
6181static void s390x_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
6182{
6183 DisasContext *dc = container_of(dcbase, DisasContext, base);
e023e832 6184
c88691aa
EC
6185 tcg_gen_insn_start(dc->base.pc_next, dc->cc_op);
6186}
e023e832 6187
c88691aa
EC
6188static bool s390x_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
6189 const CPUBreakpoint *bp)
6190{
6191 DisasContext *dc = container_of(dcbase, DisasContext, base);
667b8e29 6192
c88691aa
EC
6193 dc->base.is_jmp = DISAS_PC_STALE;
6194 dc->do_debug = true;
6195 /* The address covered by the breakpoint must be included in
6196 [tb->pc, tb->pc + tb->size) in order to for it to be
6197 properly cleared -- thus we increment the PC here so that
6198 the logic setting tb->size does the right thing. */
6199 dc->base.pc_next += 2;
6200 return true;
6201}
7193b5f6 6202
c88691aa
EC
6203static void s390x_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
6204{
6205 CPUS390XState *env = cs->env_ptr;
6206 DisasContext *dc = container_of(dcbase, DisasContext, base);
7193b5f6 6207
c88691aa
EC
6208 dc->base.is_jmp = translate_one(env, dc);
6209 if (dc->base.is_jmp == DISAS_NEXT) {
6210 uint64_t page_start;
e023e832 6211
c88691aa
EC
6212 page_start = dc->base.pc_first & TARGET_PAGE_MASK;
6213 if (dc->base.pc_next - page_start >= TARGET_PAGE_SIZE || dc->ex_value) {
6214 dc->base.is_jmp = DISAS_TOO_MANY;
6215 }
e023e832 6216 }
c88691aa
EC
6217}
6218
6219static void s390x_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
6220{
6221 DisasContext *dc = container_of(dcbase, DisasContext, base);
ad044d09 6222
c88691aa 6223 switch (dc->base.is_jmp) {
21a8eced
EC
6224 case DISAS_GOTO_TB:
6225 case DISAS_NORETURN:
ad044d09 6226 break;
21a8eced
EC
6227 case DISAS_TOO_MANY:
6228 case DISAS_PC_STALE:
6229 case DISAS_PC_STALE_NOCHAIN:
c88691aa 6230 update_psw_addr(dc);
ad044d09 6231 /* FALLTHRU */
21a8eced 6232 case DISAS_PC_UPDATED:
7a6c7067
RH
6233 /* Next TB starts off with CC_OP_DYNAMIC, so make sure the
6234 cc op type is in env */
c88691aa 6235 update_cc_op(dc);
06fc0348 6236 /* FALLTHRU */
21a8eced 6237 case DISAS_PC_CC_UPDATED:
7a6c7067 6238 /* Exit the TB, either by raising a debug exception or by return. */
c88691aa 6239 if (dc->do_debug) {
d5a103cd 6240 gen_exception(EXCP_DEBUG);
c88691aa
EC
6241 } else if (use_exit_tb(dc) ||
6242 dc->base.is_jmp == DISAS_PC_STALE_NOCHAIN) {
07ea28b4 6243 tcg_gen_exit_tb(NULL, 0);
6350001e 6244 } else {
7f11636d 6245 tcg_gen_lookup_and_goto_ptr();
ad044d09
RH
6246 }
6247 break;
6248 default:
542f70c2 6249 g_assert_not_reached();
e023e832 6250 }
c88691aa 6251}
ad044d09 6252
c88691aa
EC
6253static void s390x_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
6254{
6255 DisasContext *dc = container_of(dcbase, DisasContext, base);
ad044d09 6256
c88691aa
EC
6257 if (unlikely(dc->ex_value)) {
6258 /* ??? Unfortunately log_target_disas can't use host memory. */
6259 qemu_log("IN: EXECUTE %016" PRIx64, dc->ex_value);
6260 } else {
6261 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
6262 log_target_disas(cs, dc->base.pc_first, dc->base.tb->size);
e023e832 6263 }
c88691aa
EC
6264}
6265
6266static const TranslatorOps s390x_tr_ops = {
6267 .init_disas_context = s390x_tr_init_disas_context,
6268 .tb_start = s390x_tr_tb_start,
6269 .insn_start = s390x_tr_insn_start,
6270 .breakpoint_check = s390x_tr_breakpoint_check,
6271 .translate_insn = s390x_tr_translate_insn,
6272 .tb_stop = s390x_tr_tb_stop,
6273 .disas_log = s390x_tr_disas_log,
6274};
6275
6276void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
6277{
6278 DisasContext dc;
6279
6280 translator_loop(&s390x_tr_ops, &dc.base, cs, tb);
e023e832
AG
6281}
6282
bad729e2
RH
6283void restore_state_to_opc(CPUS390XState *env, TranslationBlock *tb,
6284 target_ulong *data)
e023e832 6285{
bad729e2
RH
6286 int cc_op = data[1];
6287 env->psw.addr = data[0];
e023e832
AG
6288 if ((cc_op != CC_OP_DYNAMIC) && (cc_op != CC_OP_STATIC)) {
6289 env->cc_op = cc_op;
6290 }
10ec5117 6291}