]> git.proxmox.com Git - mirror_qemu.git/blame - target/s390x/translate.c
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
[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
9dc67537
DH
4019static DisasJumpType op_sck(DisasContext *s, DisasOps *o)
4020{
4021 check_privileged(s);
4022 tcg_gen_qemu_ld_i64(o->in1, o->addr1, get_mem_index(s), MO_TEQ | MO_ALIGN);
4023 gen_helper_sck(cc_op, cpu_env, o->in1);
4024 set_cc_static(s);
4025 return DISAS_NEXT;
4026}
4027
21a8eced 4028static DisasJumpType op_sckc(DisasContext *s, DisasOps *o)
dd3eb7b5
RH
4029{
4030 check_privileged(s);
4031 gen_helper_sckc(cpu_env, o->in2);
21a8eced 4032 return DISAS_NEXT;
dd3eb7b5
RH
4033}
4034
21a8eced 4035static DisasJumpType op_sckpf(DisasContext *s, DisasOps *o)
257a119e
DH
4036{
4037 check_privileged(s);
4038 gen_helper_sckpf(cpu_env, regs[0]);
21a8eced 4039 return DISAS_NEXT;
257a119e
DH
4040}
4041
21a8eced 4042static DisasJumpType op_stckc(DisasContext *s, DisasOps *o)
dd3eb7b5
RH
4043{
4044 check_privileged(s);
4045 gen_helper_stckc(o->out, cpu_env);
21a8eced 4046 return DISAS_NEXT;
dd3eb7b5
RH
4047}
4048
21a8eced 4049static DisasJumpType op_stctg(DisasContext *s, DisasOps *o)
3e398cf9
RH
4050{
4051 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4052 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
4053 check_privileged(s);
3e398cf9
RH
4054 gen_helper_stctg(cpu_env, r1, o->in2, r3);
4055 tcg_temp_free_i32(r1);
4056 tcg_temp_free_i32(r3);
21a8eced 4057 return DISAS_NEXT;
3e398cf9
RH
4058}
4059
21a8eced 4060static DisasJumpType op_stctl(DisasContext *s, DisasOps *o)
504488b8
RH
4061{
4062 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4063 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
4064 check_privileged(s);
504488b8
RH
4065 gen_helper_stctl(cpu_env, r1, o->in2, r3);
4066 tcg_temp_free_i32(r1);
4067 tcg_temp_free_i32(r3);
21a8eced 4068 return DISAS_NEXT;
504488b8
RH
4069}
4070
21a8eced 4071static DisasJumpType op_stidp(DisasContext *s, DisasOps *o)
71bd6669
RH
4072{
4073 check_privileged(s);
076d4d39 4074 tcg_gen_ld_i64(o->out, cpu_env, offsetof(CPUS390XState, cpuid));
21a8eced 4075 return DISAS_NEXT;
71bd6669
RH
4076}
4077
21a8eced 4078static DisasJumpType op_spt(DisasContext *s, DisasOps *o)
c4f0a863
RH
4079{
4080 check_privileged(s);
4081 gen_helper_spt(cpu_env, o->in2);
21a8eced 4082 return DISAS_NEXT;
c4f0a863
RH
4083}
4084
21a8eced 4085static DisasJumpType op_stfl(DisasContext *s, DisasOps *o)
fc778b55 4086{
fc778b55 4087 check_privileged(s);
5bf83628 4088 gen_helper_stfl(cpu_env);
21a8eced 4089 return DISAS_NEXT;
fc778b55
RH
4090}
4091
21a8eced 4092static DisasJumpType op_stpt(DisasContext *s, DisasOps *o)
c4f0a863
RH
4093{
4094 check_privileged(s);
4095 gen_helper_stpt(o->out, cpu_env);
21a8eced 4096 return DISAS_NEXT;
c4f0a863
RH
4097}
4098
21a8eced 4099static DisasJumpType op_stsi(DisasContext *s, DisasOps *o)
d14b3e09
RH
4100{
4101 check_privileged(s);
d14b3e09
RH
4102 gen_helper_stsi(cc_op, cpu_env, o->in2, regs[0], regs[1]);
4103 set_cc_static(s);
21a8eced 4104 return DISAS_NEXT;
d14b3e09
RH
4105}
4106
21a8eced 4107static DisasJumpType op_spx(DisasContext *s, DisasOps *o)
e805a0d3
RH
4108{
4109 check_privileged(s);
4110 gen_helper_spx(cpu_env, o->in2);
21a8eced 4111 return DISAS_NEXT;
e805a0d3
RH
4112}
4113
21a8eced 4114static DisasJumpType op_xsch(DisasContext *s, DisasOps *o)
2c423fc0
RH
4115{
4116 check_privileged(s);
ad8a4570
AG
4117 gen_helper_xsch(cpu_env, regs[1]);
4118 set_cc_static(s);
21a8eced 4119 return DISAS_NEXT;
ad8a4570
AG
4120}
4121
21a8eced 4122static DisasJumpType op_csch(DisasContext *s, DisasOps *o)
ad8a4570
AG
4123{
4124 check_privileged(s);
ad8a4570
AG
4125 gen_helper_csch(cpu_env, regs[1]);
4126 set_cc_static(s);
21a8eced 4127 return DISAS_NEXT;
ad8a4570
AG
4128}
4129
21a8eced 4130static DisasJumpType op_hsch(DisasContext *s, DisasOps *o)
ad8a4570
AG
4131{
4132 check_privileged(s);
ad8a4570
AG
4133 gen_helper_hsch(cpu_env, regs[1]);
4134 set_cc_static(s);
21a8eced 4135 return DISAS_NEXT;
ad8a4570
AG
4136}
4137
21a8eced 4138static DisasJumpType op_msch(DisasContext *s, DisasOps *o)
ad8a4570
AG
4139{
4140 check_privileged(s);
ad8a4570
AG
4141 gen_helper_msch(cpu_env, regs[1], o->in2);
4142 set_cc_static(s);
21a8eced 4143 return DISAS_NEXT;
ad8a4570
AG
4144}
4145
21a8eced 4146static DisasJumpType op_rchp(DisasContext *s, DisasOps *o)
ad8a4570
AG
4147{
4148 check_privileged(s);
ad8a4570
AG
4149 gen_helper_rchp(cpu_env, regs[1]);
4150 set_cc_static(s);
21a8eced 4151 return DISAS_NEXT;
ad8a4570
AG
4152}
4153
21a8eced 4154static DisasJumpType op_rsch(DisasContext *s, DisasOps *o)
ad8a4570
AG
4155{
4156 check_privileged(s);
ad8a4570
AG
4157 gen_helper_rsch(cpu_env, regs[1]);
4158 set_cc_static(s);
21a8eced 4159 return DISAS_NEXT;
ad8a4570
AG
4160}
4161
21a8eced 4162static DisasJumpType op_sal(DisasContext *s, DisasOps *o)
86c34633
DH
4163{
4164 check_privileged(s);
4165 gen_helper_sal(cpu_env, regs[1]);
21a8eced 4166 return DISAS_NEXT;
86c34633
DH
4167}
4168
21a8eced 4169static DisasJumpType op_schm(DisasContext *s, DisasOps *o)
a9de75a0
DH
4170{
4171 check_privileged(s);
4172 gen_helper_schm(cpu_env, regs[1], regs[2], o->in2);
21a8eced 4173 return DISAS_NEXT;
a9de75a0
DH
4174}
4175
21a8eced 4176static DisasJumpType op_siga(DisasContext *s, DisasOps *o)
ad0ccf1e
DH
4177{
4178 check_privileged(s);
4179 /* From KVM code: Not provided, set CC = 3 for subchannel not operational */
4180 gen_op_movi_cc(s, 3);
21a8eced 4181 return DISAS_NEXT;
ad0ccf1e
DH
4182}
4183
21a8eced 4184static DisasJumpType op_stcps(DisasContext *s, DisasOps *o)
b9b0a4dc
DH
4185{
4186 check_privileged(s);
4187 /* The instruction is suppressed if not provided. */
21a8eced 4188 return DISAS_NEXT;
b9b0a4dc
DH
4189}
4190
21a8eced 4191static DisasJumpType op_ssch(DisasContext *s, DisasOps *o)
ad8a4570
AG
4192{
4193 check_privileged(s);
ad8a4570
AG
4194 gen_helper_ssch(cpu_env, regs[1], o->in2);
4195 set_cc_static(s);
21a8eced 4196 return DISAS_NEXT;
ad8a4570
AG
4197}
4198
21a8eced 4199static DisasJumpType op_stsch(DisasContext *s, DisasOps *o)
ad8a4570
AG
4200{
4201 check_privileged(s);
ad8a4570
AG
4202 gen_helper_stsch(cpu_env, regs[1], o->in2);
4203 set_cc_static(s);
21a8eced 4204 return DISAS_NEXT;
ad8a4570
AG
4205}
4206
21a8eced 4207static DisasJumpType op_stcrw(DisasContext *s, DisasOps *o)
5a59bc1d
DH
4208{
4209 check_privileged(s);
4210 gen_helper_stcrw(cpu_env, o->in2);
4211 set_cc_static(s);
21a8eced 4212 return DISAS_NEXT;
5a59bc1d
DH
4213}
4214
21a8eced 4215static DisasJumpType op_tpi(DisasContext *s, DisasOps *o)
6a253de3
DH
4216{
4217 check_privileged(s);
4218 gen_helper_tpi(cc_op, cpu_env, o->addr1);
4219 set_cc_static(s);
21a8eced 4220 return DISAS_NEXT;
6a253de3
DH
4221}
4222
21a8eced 4223static DisasJumpType op_tsch(DisasContext *s, DisasOps *o)
ad8a4570
AG
4224{
4225 check_privileged(s);
ad8a4570
AG
4226 gen_helper_tsch(cpu_env, regs[1], o->in2);
4227 set_cc_static(s);
21a8eced 4228 return DISAS_NEXT;
ad8a4570
AG
4229}
4230
21a8eced 4231static DisasJumpType op_chsc(DisasContext *s, DisasOps *o)
ad8a4570
AG
4232{
4233 check_privileged(s);
ad8a4570
AG
4234 gen_helper_chsc(cpu_env, o->in2);
4235 set_cc_static(s);
21a8eced 4236 return DISAS_NEXT;
2c423fc0
RH
4237}
4238
21a8eced 4239static DisasJumpType op_stpx(DisasContext *s, DisasOps *o)
e805a0d3
RH
4240{
4241 check_privileged(s);
4242 tcg_gen_ld_i64(o->out, cpu_env, offsetof(CPUS390XState, psa));
4243 tcg_gen_andi_i64(o->out, o->out, 0x7fffe000);
21a8eced 4244 return DISAS_NEXT;
e805a0d3
RH
4245}
4246
21a8eced 4247static DisasJumpType op_stnosm(DisasContext *s, DisasOps *o)
145cdb40
RH
4248{
4249 uint64_t i2 = get_field(s->fields, i2);
4250 TCGv_i64 t;
4251
4252 check_privileged(s);
4253
4254 /* It is important to do what the instruction name says: STORE THEN.
4255 If we let the output hook perform the store then if we fault and
4256 restart, we'll have the wrong SYSTEM MASK in place. */
4257 t = tcg_temp_new_i64();
4258 tcg_gen_shri_i64(t, psw_mask, 56);
4259 tcg_gen_qemu_st8(t, o->addr1, get_mem_index(s));
4260 tcg_temp_free_i64(t);
4261
4262 if (s->fields->op == 0xac) {
4263 tcg_gen_andi_i64(psw_mask, psw_mask,
4264 (i2 << 56) | 0x00ffffffffffffffull);
4265 } else {
4266 tcg_gen_ori_i64(psw_mask, psw_mask, i2 << 56);
4267 }
542f70c2
RH
4268
4269 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
21a8eced 4270 return DISAS_PC_STALE_NOCHAIN;
145cdb40 4271}
204504e2 4272
21a8eced 4273static DisasJumpType op_stura(DisasContext *s, DisasOps *o)
204504e2
RH
4274{
4275 check_privileged(s);
204504e2 4276 gen_helper_stura(cpu_env, o->in2, o->in1);
21a8eced 4277 return DISAS_NEXT;
204504e2 4278}
9c3fd85b 4279
21a8eced 4280static DisasJumpType op_sturg(DisasContext *s, DisasOps *o)
9c3fd85b
RH
4281{
4282 check_privileged(s);
9c3fd85b 4283 gen_helper_sturg(cpu_env, o->in2, o->in1);
21a8eced 4284 return DISAS_NEXT;
9c3fd85b 4285}
7d30bb73
RH
4286#endif
4287
21a8eced 4288static DisasJumpType op_stfle(DisasContext *s, DisasOps *o)
5bf83628 4289{
5bf83628
RH
4290 gen_helper_stfle(cc_op, cpu_env, o->in2);
4291 set_cc_static(s);
21a8eced 4292 return DISAS_NEXT;
5bf83628
RH
4293}
4294
21a8eced 4295static DisasJumpType op_st8(DisasContext *s, DisasOps *o)
2b280b97
RH
4296{
4297 tcg_gen_qemu_st8(o->in1, o->in2, get_mem_index(s));
21a8eced 4298 return DISAS_NEXT;
2b280b97
RH
4299}
4300
21a8eced 4301static DisasJumpType op_st16(DisasContext *s, DisasOps *o)
2b280b97
RH
4302{
4303 tcg_gen_qemu_st16(o->in1, o->in2, get_mem_index(s));
21a8eced 4304 return DISAS_NEXT;
2b280b97
RH
4305}
4306
21a8eced 4307static DisasJumpType op_st32(DisasContext *s, DisasOps *o)
2b280b97
RH
4308{
4309 tcg_gen_qemu_st32(o->in1, o->in2, get_mem_index(s));
21a8eced 4310 return DISAS_NEXT;
2b280b97
RH
4311}
4312
21a8eced 4313static DisasJumpType op_st64(DisasContext *s, DisasOps *o)
2b280b97
RH
4314{
4315 tcg_gen_qemu_st64(o->in1, o->in2, get_mem_index(s));
21a8eced 4316 return DISAS_NEXT;
2b280b97
RH
4317}
4318
21a8eced 4319static DisasJumpType op_stam(DisasContext *s, DisasOps *o)
7df3e93a
RH
4320{
4321 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4322 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
7df3e93a
RH
4323 gen_helper_stam(cpu_env, r1, o->in2, r3);
4324 tcg_temp_free_i32(r1);
4325 tcg_temp_free_i32(r3);
21a8eced 4326 return DISAS_NEXT;
7df3e93a
RH
4327}
4328
21a8eced 4329static DisasJumpType op_stcm(DisasContext *s, DisasOps *o)
2ae68059
RH
4330{
4331 int m3 = get_field(s->fields, m3);
4332 int pos, base = s->insn->data;
4333 TCGv_i64 tmp = tcg_temp_new_i64();
4334
4335 pos = base + ctz32(m3) * 8;
4336 switch (m3) {
4337 case 0xf:
4338 /* Effectively a 32-bit store. */
4339 tcg_gen_shri_i64(tmp, o->in1, pos);
4340 tcg_gen_qemu_st32(tmp, o->in2, get_mem_index(s));
4341 break;
4342
4343 case 0xc:
4344 case 0x6:
4345 case 0x3:
4346 /* Effectively a 16-bit store. */
4347 tcg_gen_shri_i64(tmp, o->in1, pos);
4348 tcg_gen_qemu_st16(tmp, o->in2, get_mem_index(s));
4349 break;
4350
4351 case 0x8:
4352 case 0x4:
4353 case 0x2:
4354 case 0x1:
4355 /* Effectively an 8-bit store. */
4356 tcg_gen_shri_i64(tmp, o->in1, pos);
4357 tcg_gen_qemu_st8(tmp, o->in2, get_mem_index(s));
4358 break;
4359
4360 default:
4361 /* This is going to be a sequence of shifts and stores. */
4362 pos = base + 32 - 8;
4363 while (m3) {
4364 if (m3 & 0x8) {
4365 tcg_gen_shri_i64(tmp, o->in1, pos);
4366 tcg_gen_qemu_st8(tmp, o->in2, get_mem_index(s));
4367 tcg_gen_addi_i64(o->in2, o->in2, 1);
4368 }
4369 m3 = (m3 << 1) & 0xf;
4370 pos -= 8;
4371 }
4372 break;
4373 }
4374 tcg_temp_free_i64(tmp);
21a8eced 4375 return DISAS_NEXT;
2ae68059
RH
4376}
4377
21a8eced 4378static DisasJumpType op_stm(DisasContext *s, DisasOps *o)
77f8d6c3
RH
4379{
4380 int r1 = get_field(s->fields, r1);
4381 int r3 = get_field(s->fields, r3);
4382 int size = s->insn->data;
4383 TCGv_i64 tsize = tcg_const_i64(size);
4384
4385 while (1) {
4386 if (size == 8) {
4387 tcg_gen_qemu_st64(regs[r1], o->in2, get_mem_index(s));
4388 } else {
4389 tcg_gen_qemu_st32(regs[r1], o->in2, get_mem_index(s));
4390 }
4391 if (r1 == r3) {
4392 break;
4393 }
4394 tcg_gen_add_i64(o->in2, o->in2, tsize);
4395 r1 = (r1 + 1) & 15;
4396 }
4397
4398 tcg_temp_free_i64(tsize);
21a8eced 4399 return DISAS_NEXT;
77f8d6c3
RH
4400}
4401
21a8eced 4402static DisasJumpType op_stmh(DisasContext *s, DisasOps *o)
77f8d6c3
RH
4403{
4404 int r1 = get_field(s->fields, r1);
4405 int r3 = get_field(s->fields, r3);
4406 TCGv_i64 t = tcg_temp_new_i64();
4407 TCGv_i64 t4 = tcg_const_i64(4);
4408 TCGv_i64 t32 = tcg_const_i64(32);
4409
4410 while (1) {
4411 tcg_gen_shl_i64(t, regs[r1], t32);
4412 tcg_gen_qemu_st32(t, o->in2, get_mem_index(s));
4413 if (r1 == r3) {
4414 break;
4415 }
4416 tcg_gen_add_i64(o->in2, o->in2, t4);
4417 r1 = (r1 + 1) & 15;
4418 }
4419
4420 tcg_temp_free_i64(t);
4421 tcg_temp_free_i64(t4);
4422 tcg_temp_free_i64(t32);
21a8eced 4423 return DISAS_NEXT;
77f8d6c3
RH
4424}
4425
21a8eced 4426static DisasJumpType op_stpq(DisasContext *s, DisasOps *o)
c21b610f 4427{
eccf741a 4428 if (tb_cflags(s->base.tb) & CF_PARALLEL) {
6476615d
EC
4429 gen_helper_stpq_parallel(cpu_env, o->in2, o->out2, o->out);
4430 } else {
4431 gen_helper_stpq(cpu_env, o->in2, o->out2, o->out);
4432 }
21a8eced 4433 return DISAS_NEXT;
c21b610f
AJ
4434}
4435
21a8eced 4436static DisasJumpType op_srst(DisasContext *s, DisasOps *o)
4600c994 4437{
7591db78
RH
4438 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4439 TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));
4440
4441 gen_helper_srst(cpu_env, r1, r2);
4442
4443 tcg_temp_free_i32(r1);
4444 tcg_temp_free_i32(r2);
4600c994 4445 set_cc_static(s);
21a8eced 4446 return DISAS_NEXT;
4600c994
RH
4447}
4448
21a8eced 4449static DisasJumpType op_srstu(DisasContext *s, DisasOps *o)
be7acb58
RH
4450{
4451 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4452 TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));
4453
4454 gen_helper_srstu(cpu_env, r1, r2);
4455
4456 tcg_temp_free_i32(r1);
4457 tcg_temp_free_i32(r2);
4458 set_cc_static(s);
21a8eced 4459 return DISAS_NEXT;
be7acb58
RH
4460}
4461
21a8eced 4462static DisasJumpType op_sub(DisasContext *s, DisasOps *o)
ad044d09
RH
4463{
4464 tcg_gen_sub_i64(o->out, o->in1, o->in2);
21a8eced 4465 return DISAS_NEXT;
ad044d09
RH
4466}
4467
21a8eced 4468static DisasJumpType op_subb(DisasContext *s, DisasOps *o)
4e4bb438 4469{
c95ec459
RH
4470 DisasCompare cmp;
4471 TCGv_i64 borrow;
4e4bb438 4472
c95ec459 4473 tcg_gen_sub_i64(o->out, o->in1, o->in2);
4e4bb438 4474
c95ec459
RH
4475 /* The !borrow flag is the msb of CC. Since we want the inverse of
4476 that, we ask for a comparison of CC=0 | CC=1 -> mask of 8 | 4. */
4477 disas_jcc(s, &cmp, 8 | 4);
4478 borrow = tcg_temp_new_i64();
4479 if (cmp.is_64) {
4480 tcg_gen_setcond_i64(cmp.cond, borrow, cmp.u.s64.a, cmp.u.s64.b);
4481 } else {
4482 TCGv_i32 t = tcg_temp_new_i32();
4483 tcg_gen_setcond_i32(cmp.cond, t, cmp.u.s32.a, cmp.u.s32.b);
4484 tcg_gen_extu_i32_i64(borrow, t);
4485 tcg_temp_free_i32(t);
4486 }
4487 free_compare(&cmp);
4488
4489 tcg_gen_sub_i64(o->out, o->out, borrow);
4490 tcg_temp_free_i64(borrow);
21a8eced 4491 return DISAS_NEXT;
4e4bb438
RH
4492}
4493
21a8eced 4494static DisasJumpType op_svc(DisasContext *s, DisasOps *o)
b9836c1a
RH
4495{
4496 TCGv_i32 t;
4497
4498 update_psw_addr(s);
7a6c7067 4499 update_cc_op(s);
b9836c1a
RH
4500
4501 t = tcg_const_i32(get_field(s->fields, i1) & 0xff);
4502 tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, int_svc_code));
4503 tcg_temp_free_i32(t);
4504
99e57856 4505 t = tcg_const_i32(s->ilen);
b9836c1a
RH
4506 tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, int_svc_ilen));
4507 tcg_temp_free_i32(t);
4508
4509 gen_exception(EXCP_SVC);
21a8eced 4510 return DISAS_NORETURN;
b9836c1a
RH
4511}
4512
21a8eced 4513static DisasJumpType op_tam(DisasContext *s, DisasOps *o)
0c0974d7
AJ
4514{
4515 int cc = 0;
4516
eccf741a
EC
4517 cc |= (s->base.tb->flags & FLAG_MASK_64) ? 2 : 0;
4518 cc |= (s->base.tb->flags & FLAG_MASK_32) ? 1 : 0;
0c0974d7 4519 gen_op_movi_cc(s, cc);
21a8eced 4520 return DISAS_NEXT;
0c0974d7
AJ
4521}
4522
21a8eced 4523static DisasJumpType op_tceb(DisasContext *s, DisasOps *o)
31aa97d1 4524{
af39bc8c 4525 gen_helper_tceb(cc_op, cpu_env, o->in1, o->in2);
31aa97d1 4526 set_cc_static(s);
21a8eced 4527 return DISAS_NEXT;
31aa97d1
RH
4528}
4529
21a8eced 4530static DisasJumpType op_tcdb(DisasContext *s, DisasOps *o)
31aa97d1 4531{
af39bc8c 4532 gen_helper_tcdb(cc_op, cpu_env, o->in1, o->in2);
31aa97d1 4533 set_cc_static(s);
21a8eced 4534 return DISAS_NEXT;
31aa97d1
RH
4535}
4536
21a8eced 4537static DisasJumpType op_tcxb(DisasContext *s, DisasOps *o)
31aa97d1 4538{
af39bc8c 4539 gen_helper_tcxb(cc_op, cpu_env, o->out, o->out2, o->in2);
31aa97d1 4540 set_cc_static(s);
21a8eced 4541 return DISAS_NEXT;
31aa97d1
RH
4542}
4543
112bf079 4544#ifndef CONFIG_USER_ONLY
f79f1ca4 4545
21a8eced 4546static DisasJumpType op_testblock(DisasContext *s, DisasOps *o)
f79f1ca4
TH
4547{
4548 check_privileged(s);
f79f1ca4
TH
4549 gen_helper_testblock(cc_op, cpu_env, o->in2);
4550 set_cc_static(s);
21a8eced 4551 return DISAS_NEXT;
f79f1ca4
TH
4552}
4553
21a8eced 4554static DisasJumpType op_tprot(DisasContext *s, DisasOps *o)
112bf079 4555{
bb879430 4556 gen_helper_tprot(cc_op, cpu_env, o->addr1, o->in2);
112bf079 4557 set_cc_static(s);
21a8eced 4558 return DISAS_NEXT;
112bf079 4559}
f79f1ca4 4560
112bf079
RH
4561#endif
4562
21a8eced 4563static DisasJumpType op_tp(DisasContext *s, DisasOps *o)
5d4a655a
AJ
4564{
4565 TCGv_i32 l1 = tcg_const_i32(get_field(s->fields, l1) + 1);
4566 gen_helper_tp(cc_op, cpu_env, o->addr1, l1);
4567 tcg_temp_free_i32(l1);
4568 set_cc_static(s);
21a8eced 4569 return DISAS_NEXT;
5d4a655a
AJ
4570}
4571
21a8eced 4572static DisasJumpType op_tr(DisasContext *s, DisasOps *o)
0a949039
RH
4573{
4574 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
0a949039
RH
4575 gen_helper_tr(cpu_env, l, o->addr1, o->in2);
4576 tcg_temp_free_i32(l);
4577 set_cc_static(s);
21a8eced 4578 return DISAS_NEXT;
0a949039
RH
4579}
4580
21a8eced 4581static DisasJumpType op_tre(DisasContext *s, DisasOps *o)
3f4de675 4582{
3f4de675
AJ
4583 gen_helper_tre(o->out, cpu_env, o->out, o->out2, o->in2);
4584 return_low128(o->out2);
4585 set_cc_static(s);
21a8eced 4586 return DISAS_NEXT;
3f4de675
AJ
4587}
4588
21a8eced 4589static DisasJumpType op_trt(DisasContext *s, DisasOps *o)
54f00775
AJ
4590{
4591 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
54f00775
AJ
4592 gen_helper_trt(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;
54f00775
AJ
4596}
4597
21a8eced 4598static DisasJumpType op_trtr(DisasContext *s, DisasOps *o)
b213c9f5
RH
4599{
4600 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
4601 gen_helper_trtr(cc_op, cpu_env, l, o->addr1, o->in2);
4602 tcg_temp_free_i32(l);
4603 set_cc_static(s);
21a8eced 4604 return DISAS_NEXT;
b213c9f5
RH
4605}
4606
21a8eced 4607static DisasJumpType op_trXX(DisasContext *s, DisasOps *o)
4065ae76
AJ
4608{
4609 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4610 TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));
4611 TCGv_i32 sizes = tcg_const_i32(s->insn->opc & 3);
4612 TCGv_i32 tst = tcg_temp_new_i32();
4613 int m3 = get_field(s->fields, m3);
4614
3c39c800
RH
4615 if (!s390_has_feat(S390_FEAT_ETF2_ENH)) {
4616 m3 = 0;
4617 }
4065ae76
AJ
4618 if (m3 & 1) {
4619 tcg_gen_movi_i32(tst, -1);
4620 } else {
4621 tcg_gen_extrl_i64_i32(tst, regs[0]);
4622 if (s->insn->opc & 3) {
4623 tcg_gen_ext8u_i32(tst, tst);
4624 } else {
4625 tcg_gen_ext16u_i32(tst, tst);
4626 }
4627 }
4628 gen_helper_trXX(cc_op, cpu_env, r1, r2, tst, sizes);
4629
4630 tcg_temp_free_i32(r1);
4631 tcg_temp_free_i32(r2);
4632 tcg_temp_free_i32(sizes);
4633 tcg_temp_free_i32(tst);
4634 set_cc_static(s);
21a8eced 4635 return DISAS_NEXT;
4065ae76
AJ
4636}
4637
21a8eced 4638static DisasJumpType op_ts(DisasContext *s, DisasOps *o)
6699adfc
AJ
4639{
4640 TCGv_i32 t1 = tcg_const_i32(0xff);
4641 tcg_gen_atomic_xchg_i32(t1, o->in2, t1, get_mem_index(s), MO_UB);
4642 tcg_gen_extract_i32(cc_op, t1, 7, 1);
4643 tcg_temp_free_i32(t1);
4644 set_cc_static(s);
21a8eced 4645 return DISAS_NEXT;
6699adfc
AJ
4646}
4647
21a8eced 4648static DisasJumpType op_unpk(DisasContext *s, DisasOps *o)
0a949039
RH
4649{
4650 TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
0a949039
RH
4651 gen_helper_unpk(cpu_env, l, o->addr1, o->in2);
4652 tcg_temp_free_i32(l);
21a8eced 4653 return DISAS_NEXT;
0a949039
RH
4654}
4655
21a8eced 4656static DisasJumpType op_unpka(DisasContext *s, DisasOps *o)
1a35f08a
AJ
4657{
4658 int l1 = get_field(s->fields, l1) + 1;
4659 TCGv_i32 l;
4660
4661 /* The length must not exceed 32 bytes. */
4662 if (l1 > 32) {
4663 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 4664 return DISAS_NORETURN;
1a35f08a
AJ
4665 }
4666 l = tcg_const_i32(l1);
4667 gen_helper_unpka(cc_op, cpu_env, o->addr1, l, o->in2);
4668 tcg_temp_free_i32(l);
4669 set_cc_static(s);
21a8eced 4670 return DISAS_NEXT;
1a35f08a
AJ
4671}
4672
21a8eced 4673static DisasJumpType op_unpku(DisasContext *s, DisasOps *o)
15417787
AJ
4674{
4675 int l1 = get_field(s->fields, l1) + 1;
4676 TCGv_i32 l;
4677
4678 /* The length must be even and should not exceed 64 bytes. */
4679 if ((l1 & 1) || (l1 > 64)) {
4680 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 4681 return DISAS_NORETURN;
15417787
AJ
4682 }
4683 l = tcg_const_i32(l1);
4684 gen_helper_unpku(cc_op, cpu_env, o->addr1, l, o->in2);
4685 tcg_temp_free_i32(l);
4686 set_cc_static(s);
21a8eced 4687 return DISAS_NEXT;
15417787
AJ
4688}
4689
4690
21a8eced 4691static DisasJumpType op_xc(DisasContext *s, DisasOps *o)
0a949039 4692{
d074ac6d
RH
4693 int d1 = get_field(s->fields, d1);
4694 int d2 = get_field(s->fields, d2);
4695 int b1 = get_field(s->fields, b1);
4696 int b2 = get_field(s->fields, b2);
4697 int l = get_field(s->fields, l1);
4698 TCGv_i32 t32;
4699
4700 o->addr1 = get_address(s, 0, b1, d1);
4701
4702 /* If the addresses are identical, this is a store/memset of zero. */
4703 if (b1 == b2 && d1 == d2 && (l + 1) <= 32) {
4704 o->in2 = tcg_const_i64(0);
4705
4706 l++;
4707 while (l >= 8) {
4708 tcg_gen_qemu_st64(o->in2, o->addr1, get_mem_index(s));
4709 l -= 8;
4710 if (l > 0) {
4711 tcg_gen_addi_i64(o->addr1, o->addr1, 8);
4712 }
4713 }
4714 if (l >= 4) {
4715 tcg_gen_qemu_st32(o->in2, o->addr1, get_mem_index(s));
4716 l -= 4;
4717 if (l > 0) {
4718 tcg_gen_addi_i64(o->addr1, o->addr1, 4);
4719 }
4720 }
4721 if (l >= 2) {
4722 tcg_gen_qemu_st16(o->in2, o->addr1, get_mem_index(s));
4723 l -= 2;
4724 if (l > 0) {
4725 tcg_gen_addi_i64(o->addr1, o->addr1, 2);
4726 }
4727 }
4728 if (l) {
4729 tcg_gen_qemu_st8(o->in2, o->addr1, get_mem_index(s));
4730 }
4731 gen_op_movi_cc(s, 0);
21a8eced 4732 return DISAS_NEXT;
d074ac6d
RH
4733 }
4734
4735 /* But in general we'll defer to a helper. */
4736 o->in2 = get_address(s, 0, b2, d2);
4737 t32 = tcg_const_i32(l);
d074ac6d
RH
4738 gen_helper_xc(cc_op, cpu_env, t32, o->addr1, o->in2);
4739 tcg_temp_free_i32(t32);
0a949039 4740 set_cc_static(s);
21a8eced 4741 return DISAS_NEXT;
0a949039
RH
4742}
4743
21a8eced 4744static DisasJumpType op_xor(DisasContext *s, DisasOps *o)
3bbfbd1f
RH
4745{
4746 tcg_gen_xor_i64(o->out, o->in1, o->in2);
21a8eced 4747 return DISAS_NEXT;
3bbfbd1f
RH
4748}
4749
21a8eced 4750static DisasJumpType op_xori(DisasContext *s, DisasOps *o)
facfc864
RH
4751{
4752 int shift = s->insn->data & 0xff;
4753 int size = s->insn->data >> 8;
4754 uint64_t mask = ((1ull << size) - 1) << shift;
4755
4756 assert(!o->g_in2);
4757 tcg_gen_shli_i64(o->in2, o->in2, shift);
4758 tcg_gen_xor_i64(o->out, o->in1, o->in2);
4759
4760 /* Produce the CC from only the bits manipulated. */
4761 tcg_gen_andi_i64(cc_dst, o->out, mask);
4762 set_cc_nz_u64(s, cc_dst);
21a8eced 4763 return DISAS_NEXT;
facfc864
RH
4764}
4765
21a8eced 4766static DisasJumpType op_xi(DisasContext *s, DisasOps *o)
f400be18
DH
4767{
4768 o->in1 = tcg_temp_new_i64();
4769
4770 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
4771 tcg_gen_qemu_ld_tl(o->in1, o->addr1, get_mem_index(s), s->insn->data);
4772 } else {
4773 /* Perform the atomic operation in memory. */
4774 tcg_gen_atomic_fetch_xor_i64(o->in1, o->addr1, o->in2, get_mem_index(s),
4775 s->insn->data);
4776 }
4777
4778 /* Recompute also for atomic case: needed for setting CC. */
4779 tcg_gen_xor_i64(o->out, o->in1, o->in2);
4780
4781 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
4782 tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), s->insn->data);
4783 }
21a8eced 4784 return DISAS_NEXT;
f400be18
DH
4785}
4786
21a8eced 4787static DisasJumpType op_zero(DisasContext *s, DisasOps *o)
24db8412
RH
4788{
4789 o->out = tcg_const_i64(0);
21a8eced 4790 return DISAS_NEXT;
24db8412
RH
4791}
4792
21a8eced 4793static DisasJumpType op_zero2(DisasContext *s, DisasOps *o)
24db8412
RH
4794{
4795 o->out = tcg_const_i64(0);
4796 o->out2 = o->out;
4797 o->g_out2 = true;
21a8eced 4798 return DISAS_NEXT;
24db8412
RH
4799}
4800
f6c232ce 4801#ifndef CONFIG_USER_ONLY
21a8eced 4802static DisasJumpType op_clp(DisasContext *s, DisasOps *o)
f6c232ce
CH
4803{
4804 TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));
4805
4806 check_privileged(s);
4807 gen_helper_clp(cpu_env, r2);
4808 tcg_temp_free_i32(r2);
4809 set_cc_static(s);
21a8eced 4810 return DISAS_NEXT;
f6c232ce
CH
4811}
4812
21a8eced 4813static DisasJumpType op_pcilg(DisasContext *s, DisasOps *o)
f6c232ce
CH
4814{
4815 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4816 TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));
4817
4818 check_privileged(s);
4819 gen_helper_pcilg(cpu_env, r1, r2);
4820 tcg_temp_free_i32(r1);
4821 tcg_temp_free_i32(r2);
4822 set_cc_static(s);
21a8eced 4823 return DISAS_NEXT;
f6c232ce
CH
4824}
4825
21a8eced 4826static DisasJumpType op_pcistg(DisasContext *s, DisasOps *o)
f6c232ce
CH
4827{
4828 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4829 TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));
4830
4831 check_privileged(s);
4832 gen_helper_pcistg(cpu_env, r1, r2);
4833 tcg_temp_free_i32(r1);
4834 tcg_temp_free_i32(r2);
4835 set_cc_static(s);
21a8eced 4836 return DISAS_NEXT;
f6c232ce
CH
4837}
4838
21a8eced 4839static DisasJumpType op_stpcifc(DisasContext *s, DisasOps *o)
f6c232ce
CH
4840{
4841 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4842 TCGv_i32 ar = tcg_const_i32(get_field(s->fields, b2));
4843
4844 check_privileged(s);
4845 gen_helper_stpcifc(cpu_env, r1, o->addr1, ar);
4846 tcg_temp_free_i32(ar);
4847 tcg_temp_free_i32(r1);
4848 set_cc_static(s);
21a8eced 4849 return DISAS_NEXT;
f6c232ce
CH
4850}
4851
21a8eced 4852static DisasJumpType op_sic(DisasContext *s, DisasOps *o)
f6c232ce
CH
4853{
4854 check_privileged(s);
4855 gen_helper_sic(cpu_env, o->in1, o->in2);
21a8eced 4856 return DISAS_NEXT;
f6c232ce
CH
4857}
4858
21a8eced 4859static DisasJumpType op_rpcit(DisasContext *s, DisasOps *o)
f6c232ce
CH
4860{
4861 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4862 TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));
4863
4864 check_privileged(s);
4865 gen_helper_rpcit(cpu_env, r1, r2);
4866 tcg_temp_free_i32(r1);
4867 tcg_temp_free_i32(r2);
4868 set_cc_static(s);
21a8eced 4869 return DISAS_NEXT;
f6c232ce
CH
4870}
4871
21a8eced 4872static DisasJumpType op_pcistb(DisasContext *s, DisasOps *o)
f6c232ce
CH
4873{
4874 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4875 TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
4876 TCGv_i32 ar = tcg_const_i32(get_field(s->fields, b2));
4877
4878 check_privileged(s);
4879 gen_helper_pcistb(cpu_env, r1, r3, o->addr1, ar);
4880 tcg_temp_free_i32(ar);
4881 tcg_temp_free_i32(r1);
4882 tcg_temp_free_i32(r3);
4883 set_cc_static(s);
21a8eced 4884 return DISAS_NEXT;
f6c232ce
CH
4885}
4886
21a8eced 4887static DisasJumpType op_mpcifc(DisasContext *s, DisasOps *o)
f6c232ce
CH
4888{
4889 TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4890 TCGv_i32 ar = tcg_const_i32(get_field(s->fields, b2));
4891
4892 check_privileged(s);
4893 gen_helper_mpcifc(cpu_env, r1, o->addr1, ar);
4894 tcg_temp_free_i32(ar);
4895 tcg_temp_free_i32(r1);
4896 set_cc_static(s);
21a8eced 4897 return DISAS_NEXT;
f6c232ce
CH
4898}
4899#endif
4900
ad044d09
RH
4901/* ====================================================================== */
4902/* The "Cc OUTput" generators. Given the generated output (and in some cases
4903 the original inputs), update the various cc data structures in order to
4904 be able to compute the new condition code. */
4905
b9bca3e5
RH
4906static void cout_abs32(DisasContext *s, DisasOps *o)
4907{
4908 gen_op_update1_cc_i64(s, CC_OP_ABS_32, o->out);
4909}
4910
4911static void cout_abs64(DisasContext *s, DisasOps *o)
4912{
4913 gen_op_update1_cc_i64(s, CC_OP_ABS_64, o->out);
4914}
4915
ad044d09
RH
4916static void cout_adds32(DisasContext *s, DisasOps *o)
4917{
4918 gen_op_update3_cc_i64(s, CC_OP_ADD_32, o->in1, o->in2, o->out);
4919}
4920
4921static void cout_adds64(DisasContext *s, DisasOps *o)
4922{
4923 gen_op_update3_cc_i64(s, CC_OP_ADD_64, o->in1, o->in2, o->out);
4924}
4925
4926static void cout_addu32(DisasContext *s, DisasOps *o)
4927{
4928 gen_op_update3_cc_i64(s, CC_OP_ADDU_32, o->in1, o->in2, o->out);
4929}
4930
4931static void cout_addu64(DisasContext *s, DisasOps *o)
4932{
4933 gen_op_update3_cc_i64(s, CC_OP_ADDU_64, o->in1, o->in2, o->out);
4934}
4935
4e4bb438
RH
4936static void cout_addc32(DisasContext *s, DisasOps *o)
4937{
4938 gen_op_update3_cc_i64(s, CC_OP_ADDC_32, o->in1, o->in2, o->out);
4939}
4940
4941static void cout_addc64(DisasContext *s, DisasOps *o)
4942{
4943 gen_op_update3_cc_i64(s, CC_OP_ADDC_64, o->in1, o->in2, o->out);
4944}
4945
a7e836d5
RH
4946static void cout_cmps32(DisasContext *s, DisasOps *o)
4947{
4948 gen_op_update2_cc_i64(s, CC_OP_LTGT_32, o->in1, o->in2);
4949}
4950
4951static void cout_cmps64(DisasContext *s, DisasOps *o)
4952{
4953 gen_op_update2_cc_i64(s, CC_OP_LTGT_64, o->in1, o->in2);
4954}
4955
4956static void cout_cmpu32(DisasContext *s, DisasOps *o)
4957{
4958 gen_op_update2_cc_i64(s, CC_OP_LTUGTU_32, o->in1, o->in2);
4959}
4960
4961static void cout_cmpu64(DisasContext *s, DisasOps *o)
4962{
4963 gen_op_update2_cc_i64(s, CC_OP_LTUGTU_64, o->in1, o->in2);
4964}
4965
587626f8
RH
4966static void cout_f32(DisasContext *s, DisasOps *o)
4967{
4968 gen_op_update1_cc_i64(s, CC_OP_NZ_F32, o->out);
4969}
4970
4971static void cout_f64(DisasContext *s, DisasOps *o)
4972{
4973 gen_op_update1_cc_i64(s, CC_OP_NZ_F64, o->out);
4974}
4975
4976static void cout_f128(DisasContext *s, DisasOps *o)
4977{
4978 gen_op_update2_cc_i64(s, CC_OP_NZ_F128, o->out, o->out2);
4979}
4980
b9bca3e5
RH
4981static void cout_nabs32(DisasContext *s, DisasOps *o)
4982{
4983 gen_op_update1_cc_i64(s, CC_OP_NABS_32, o->out);
4984}
4985
4986static void cout_nabs64(DisasContext *s, DisasOps *o)
4987{
4988 gen_op_update1_cc_i64(s, CC_OP_NABS_64, o->out);
4989}
4990
4991static void cout_neg32(DisasContext *s, DisasOps *o)
4992{
4993 gen_op_update1_cc_i64(s, CC_OP_COMP_32, o->out);
4994}
4995
4996static void cout_neg64(DisasContext *s, DisasOps *o)
4997{
4998 gen_op_update1_cc_i64(s, CC_OP_COMP_64, o->out);
4999}
5000
3bbfbd1f
RH
5001static void cout_nz32(DisasContext *s, DisasOps *o)
5002{
5003 tcg_gen_ext32u_i64(cc_dst, o->out);
5004 gen_op_update1_cc_i64(s, CC_OP_NZ, cc_dst);
5005}
5006
5007static void cout_nz64(DisasContext *s, DisasOps *o)
5008{
5009 gen_op_update1_cc_i64(s, CC_OP_NZ, o->out);
5010}
5011
11bf2d73
RH
5012static void cout_s32(DisasContext *s, DisasOps *o)
5013{
5014 gen_op_update1_cc_i64(s, CC_OP_LTGT0_32, o->out);
5015}
5016
5017static void cout_s64(DisasContext *s, DisasOps *o)
5018{
5019 gen_op_update1_cc_i64(s, CC_OP_LTGT0_64, o->out);
5020}
5021
ad044d09
RH
5022static void cout_subs32(DisasContext *s, DisasOps *o)
5023{
5024 gen_op_update3_cc_i64(s, CC_OP_SUB_32, o->in1, o->in2, o->out);
5025}
5026
5027static void cout_subs64(DisasContext *s, DisasOps *o)
5028{
5029 gen_op_update3_cc_i64(s, CC_OP_SUB_64, o->in1, o->in2, o->out);
5030}
5031
5032static void cout_subu32(DisasContext *s, DisasOps *o)
5033{
5034 gen_op_update3_cc_i64(s, CC_OP_SUBU_32, o->in1, o->in2, o->out);
5035}
5036
5037static void cout_subu64(DisasContext *s, DisasOps *o)
5038{
5039 gen_op_update3_cc_i64(s, CC_OP_SUBU_64, o->in1, o->in2, o->out);
5040}
5041
4e4bb438
RH
5042static void cout_subb32(DisasContext *s, DisasOps *o)
5043{
5044 gen_op_update3_cc_i64(s, CC_OP_SUBB_32, o->in1, o->in2, o->out);
5045}
5046
5047static void cout_subb64(DisasContext *s, DisasOps *o)
5048{
5049 gen_op_update3_cc_i64(s, CC_OP_SUBB_64, o->in1, o->in2, o->out);
5050}
5051
00d2dc19
RH
5052static void cout_tm32(DisasContext *s, DisasOps *o)
5053{
5054 gen_op_update2_cc_i64(s, CC_OP_TM_32, o->in1, o->in2);
5055}
5056
5057static void cout_tm64(DisasContext *s, DisasOps *o)
5058{
5059 gen_op_update2_cc_i64(s, CC_OP_TM_64, o->in1, o->in2);
5060}
5061
ad044d09 5062/* ====================================================================== */
805a2505 5063/* The "PREParation" generators. These initialize the DisasOps.OUT fields
ad044d09
RH
5064 with the TCG register to which we will write. Used in combination with
5065 the "wout" generators, in some cases we need a new temporary, and in
5066 some cases we can write to a TCG global. */
5067
5068static void prep_new(DisasContext *s, DisasFields *f, DisasOps *o)
5069{
5070 o->out = tcg_temp_new_i64();
5071}
49f7ee80 5072#define SPEC_prep_new 0
ad044d09 5073
891452e5
RH
5074static void prep_new_P(DisasContext *s, DisasFields *f, DisasOps *o)
5075{
5076 o->out = tcg_temp_new_i64();
5077 o->out2 = tcg_temp_new_i64();
5078}
49f7ee80 5079#define SPEC_prep_new_P 0
891452e5 5080
ad044d09
RH
5081static void prep_r1(DisasContext *s, DisasFields *f, DisasOps *o)
5082{
5083 o->out = regs[get_field(f, r1)];
5084 o->g_out = true;
5085}
49f7ee80 5086#define SPEC_prep_r1 0
ad044d09 5087
1ac5889f
RH
5088static void prep_r1_P(DisasContext *s, DisasFields *f, DisasOps *o)
5089{
1ac5889f
RH
5090 int r1 = get_field(f, r1);
5091 o->out = regs[r1];
49f7ee80 5092 o->out2 = regs[r1 + 1];
1ac5889f
RH
5093 o->g_out = o->g_out2 = true;
5094}
49f7ee80 5095#define SPEC_prep_r1_P SPEC_r1_even
1ac5889f 5096
587626f8
RH
5097static void prep_f1(DisasContext *s, DisasFields *f, DisasOps *o)
5098{
5099 o->out = fregs[get_field(f, r1)];
5100 o->g_out = true;
5101}
49f7ee80 5102#define SPEC_prep_f1 0
587626f8
RH
5103
5104static void prep_x1(DisasContext *s, DisasFields *f, DisasOps *o)
5105{
587626f8
RH
5106 int r1 = get_field(f, r1);
5107 o->out = fregs[r1];
49f7ee80 5108 o->out2 = fregs[r1 + 2];
587626f8
RH
5109 o->g_out = o->g_out2 = true;
5110}
49f7ee80 5111#define SPEC_prep_x1 SPEC_r1_f128
587626f8 5112
ad044d09
RH
5113/* ====================================================================== */
5114/* The "Write OUTput" generators. These generally perform some non-trivial
5115 copy of data to TCG globals, or to main memory. The trivial cases are
5116 generally handled by having a "prep" generator install the TCG global
5117 as the destination of the operation. */
5118
22c37a08
RH
5119static void wout_r1(DisasContext *s, DisasFields *f, DisasOps *o)
5120{
5121 store_reg(get_field(f, r1), o->out);
5122}
49f7ee80 5123#define SPEC_wout_r1 0
22c37a08 5124
afdc70be
RH
5125static void wout_r1_8(DisasContext *s, DisasFields *f, DisasOps *o)
5126{
5127 int r1 = get_field(f, r1);
5128 tcg_gen_deposit_i64(regs[r1], regs[r1], o->out, 0, 8);
5129}
49f7ee80 5130#define SPEC_wout_r1_8 0
afdc70be 5131
d54f5865
RH
5132static void wout_r1_16(DisasContext *s, DisasFields *f, DisasOps *o)
5133{
5134 int r1 = get_field(f, r1);
5135 tcg_gen_deposit_i64(regs[r1], regs[r1], o->out, 0, 16);
5136}
49f7ee80 5137#define SPEC_wout_r1_16 0
d54f5865 5138
ad044d09
RH
5139static void wout_r1_32(DisasContext *s, DisasFields *f, DisasOps *o)
5140{
5141 store_reg32_i64(get_field(f, r1), o->out);
5142}
49f7ee80 5143#define SPEC_wout_r1_32 0
ad044d09 5144
a1f12d85
AJ
5145static void wout_r1_32h(DisasContext *s, DisasFields *f, DisasOps *o)
5146{
5147 store_reg32h_i64(get_field(f, r1), o->out);
5148}
5149#define SPEC_wout_r1_32h 0
5150
891452e5
RH
5151static void wout_r1_P32(DisasContext *s, DisasFields *f, DisasOps *o)
5152{
891452e5
RH
5153 int r1 = get_field(f, r1);
5154 store_reg32_i64(r1, o->out);
49f7ee80 5155 store_reg32_i64(r1 + 1, o->out2);
891452e5 5156}
49f7ee80 5157#define SPEC_wout_r1_P32 SPEC_r1_even
891452e5 5158
d87aaf93
RH
5159static void wout_r1_D32(DisasContext *s, DisasFields *f, DisasOps *o)
5160{
d87aaf93 5161 int r1 = get_field(f, r1);
49f7ee80 5162 store_reg32_i64(r1 + 1, o->out);
d87aaf93
RH
5163 tcg_gen_shri_i64(o->out, o->out, 32);
5164 store_reg32_i64(r1, o->out);
5165}
49f7ee80 5166#define SPEC_wout_r1_D32 SPEC_r1_even
22c37a08 5167
1807aaa5
EB
5168static void wout_r3_P32(DisasContext *s, DisasFields *f, DisasOps *o)
5169{
5170 int r3 = get_field(f, r3);
5171 store_reg32_i64(r3, o->out);
5172 store_reg32_i64(r3 + 1, o->out2);
5173}
5174#define SPEC_wout_r3_P32 SPEC_r3_even
5175
5176static void wout_r3_P64(DisasContext *s, DisasFields *f, DisasOps *o)
5177{
5178 int r3 = get_field(f, r3);
5179 store_reg(r3, o->out);
5180 store_reg(r3 + 1, o->out2);
5181}
5182#define SPEC_wout_r3_P64 SPEC_r3_even
5183
d764a8d1
RH
5184static void wout_e1(DisasContext *s, DisasFields *f, DisasOps *o)
5185{
5186 store_freg32_i64(get_field(f, r1), o->out);
5187}
49f7ee80 5188#define SPEC_wout_e1 0
d764a8d1
RH
5189
5190static void wout_f1(DisasContext *s, DisasFields *f, DisasOps *o)
5191{
5192 store_freg(get_field(f, r1), o->out);
5193}
49f7ee80 5194#define SPEC_wout_f1 0
d764a8d1
RH
5195
5196static void wout_x1(DisasContext *s, DisasFields *f, DisasOps *o)
5197{
5198 int f1 = get_field(s->fields, r1);
5199 store_freg(f1, o->out);
49f7ee80 5200 store_freg(f1 + 2, o->out2);
d764a8d1 5201}
49f7ee80 5202#define SPEC_wout_x1 SPEC_r1_f128
d764a8d1 5203
22c37a08
RH
5204static void wout_cond_r1r2_32(DisasContext *s, DisasFields *f, DisasOps *o)
5205{
5206 if (get_field(f, r1) != get_field(f, r2)) {
5207 store_reg32_i64(get_field(f, r1), o->out);
5208 }
5209}
49f7ee80 5210#define SPEC_wout_cond_r1r2_32 0
d87aaf93 5211
d764a8d1
RH
5212static void wout_cond_e1e2(DisasContext *s, DisasFields *f, DisasOps *o)
5213{
5214 if (get_field(f, r1) != get_field(f, r2)) {
5215 store_freg32_i64(get_field(f, r1), o->out);
5216 }
5217}
49f7ee80 5218#define SPEC_wout_cond_e1e2 0
d764a8d1 5219
6a04d76a
RH
5220static void wout_m1_8(DisasContext *s, DisasFields *f, DisasOps *o)
5221{
5222 tcg_gen_qemu_st8(o->out, o->addr1, get_mem_index(s));
5223}
49f7ee80 5224#define SPEC_wout_m1_8 0
6a04d76a
RH
5225
5226static void wout_m1_16(DisasContext *s, DisasFields *f, DisasOps *o)
5227{
5228 tcg_gen_qemu_st16(o->out, o->addr1, get_mem_index(s));
5229}
49f7ee80 5230#define SPEC_wout_m1_16 0
6a04d76a 5231
21fc97c5
DH
5232#ifndef CONFIG_USER_ONLY
5233static void wout_m1_16a(DisasContext *s, DisasFields *f, DisasOps *o)
5234{
5235 tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), MO_TEUW | MO_ALIGN);
5236}
5237#define SPEC_wout_m1_16a 0
5238#endif
5239
ad044d09
RH
5240static void wout_m1_32(DisasContext *s, DisasFields *f, DisasOps *o)
5241{
5242 tcg_gen_qemu_st32(o->out, o->addr1, get_mem_index(s));
5243}
49f7ee80 5244#define SPEC_wout_m1_32 0
ad044d09 5245
21fc97c5
DH
5246#ifndef CONFIG_USER_ONLY
5247static void wout_m1_32a(DisasContext *s, DisasFields *f, DisasOps *o)
5248{
5249 tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), MO_TEUL | MO_ALIGN);
5250}
5251#define SPEC_wout_m1_32a 0
5252#endif
5253
ad044d09
RH
5254static void wout_m1_64(DisasContext *s, DisasFields *f, DisasOps *o)
5255{
5256 tcg_gen_qemu_st64(o->out, o->addr1, get_mem_index(s));
5257}
49f7ee80 5258#define SPEC_wout_m1_64 0
ad044d09 5259
21fc97c5
DH
5260#ifndef CONFIG_USER_ONLY
5261static void wout_m1_64a(DisasContext *s, DisasFields *f, DisasOps *o)
5262{
5263 tcg_gen_qemu_st_i64(o->out, o->addr1, get_mem_index(s), MO_TEQ | MO_ALIGN);
5264}
5265#define SPEC_wout_m1_64a 0
5266#endif
5267
ea20490f
RH
5268static void wout_m2_32(DisasContext *s, DisasFields *f, DisasOps *o)
5269{
5270 tcg_gen_qemu_st32(o->out, o->in2, get_mem_index(s));
5271}
49f7ee80 5272#define SPEC_wout_m2_32 0
ea20490f 5273
4dba4d6f 5274static void wout_in2_r1(DisasContext *s, DisasFields *f, DisasOps *o)
57af7289 5275{
4dba4d6f 5276 store_reg(get_field(f, r1), o->in2);
57af7289 5277}
4dba4d6f 5278#define SPEC_wout_in2_r1 0
57af7289 5279
4dba4d6f 5280static void wout_in2_r1_32(DisasContext *s, DisasFields *f, DisasOps *o)
57af7289 5281{
4dba4d6f 5282 store_reg32_i64(get_field(f, r1), o->in2);
57af7289 5283}
4dba4d6f 5284#define SPEC_wout_in2_r1_32 0
57af7289 5285
ad044d09
RH
5286/* ====================================================================== */
5287/* The "INput 1" generators. These load the first operand to an insn. */
5288
5289static void in1_r1(DisasContext *s, DisasFields *f, DisasOps *o)
5290{
5291 o->in1 = load_reg(get_field(f, r1));
5292}
49f7ee80 5293#define SPEC_in1_r1 0
ad044d09 5294
d1c04a2b
RH
5295static void in1_r1_o(DisasContext *s, DisasFields *f, DisasOps *o)
5296{
5297 o->in1 = regs[get_field(f, r1)];
5298 o->g_in1 = true;
5299}
49f7ee80 5300#define SPEC_in1_r1_o 0
d1c04a2b 5301
cbe24bfa
RH
5302static void in1_r1_32s(DisasContext *s, DisasFields *f, DisasOps *o)
5303{
5304 o->in1 = tcg_temp_new_i64();
5305 tcg_gen_ext32s_i64(o->in1, regs[get_field(f, r1)]);
5306}
49f7ee80 5307#define SPEC_in1_r1_32s 0
cbe24bfa
RH
5308
5309static void in1_r1_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5310{
5311 o->in1 = tcg_temp_new_i64();
5312 tcg_gen_ext32u_i64(o->in1, regs[get_field(f, r1)]);
5313}
49f7ee80 5314#define SPEC_in1_r1_32u 0
cbe24bfa 5315
32a44d58
RH
5316static void in1_r1_sr32(DisasContext *s, DisasFields *f, DisasOps *o)
5317{
5318 o->in1 = tcg_temp_new_i64();
5319 tcg_gen_shri_i64(o->in1, regs[get_field(f, r1)], 32);
5320}
49f7ee80 5321#define SPEC_in1_r1_sr32 0
32a44d58 5322
1ac5889f
RH
5323static void in1_r1p1(DisasContext *s, DisasFields *f, DisasOps *o)
5324{
49f7ee80 5325 o->in1 = load_reg(get_field(f, r1) + 1);
1ac5889f 5326}
49f7ee80 5327#define SPEC_in1_r1p1 SPEC_r1_even
1ac5889f 5328
d87aaf93
RH
5329static void in1_r1p1_32s(DisasContext *s, DisasFields *f, DisasOps *o)
5330{
d87aaf93 5331 o->in1 = tcg_temp_new_i64();
49f7ee80 5332 tcg_gen_ext32s_i64(o->in1, regs[get_field(f, r1) + 1]);
d87aaf93 5333}
49f7ee80 5334#define SPEC_in1_r1p1_32s SPEC_r1_even
d87aaf93
RH
5335
5336static void in1_r1p1_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5337{
d87aaf93 5338 o->in1 = tcg_temp_new_i64();
49f7ee80 5339 tcg_gen_ext32u_i64(o->in1, regs[get_field(f, r1) + 1]);
d87aaf93 5340}
49f7ee80 5341#define SPEC_in1_r1p1_32u SPEC_r1_even
d87aaf93 5342
891452e5
RH
5343static void in1_r1_D32(DisasContext *s, DisasFields *f, DisasOps *o)
5344{
891452e5
RH
5345 int r1 = get_field(f, r1);
5346 o->in1 = tcg_temp_new_i64();
5347 tcg_gen_concat32_i64(o->in1, regs[r1 + 1], regs[r1]);
5348}
49f7ee80 5349#define SPEC_in1_r1_D32 SPEC_r1_even
891452e5 5350
ad044d09
RH
5351static void in1_r2(DisasContext *s, DisasFields *f, DisasOps *o)
5352{
5353 o->in1 = load_reg(get_field(f, r2));
5354}
49f7ee80 5355#define SPEC_in1_r2 0
ad044d09 5356
a1f12d85
AJ
5357static void in1_r2_sr32(DisasContext *s, DisasFields *f, DisasOps *o)
5358{
5359 o->in1 = tcg_temp_new_i64();
5360 tcg_gen_shri_i64(o->in1, regs[get_field(f, r2)], 32);
5361}
5362#define SPEC_in1_r2_sr32 0
5363
ad044d09
RH
5364static void in1_r3(DisasContext *s, DisasFields *f, DisasOps *o)
5365{
5366 o->in1 = load_reg(get_field(f, r3));
5367}
49f7ee80 5368#define SPEC_in1_r3 0
ad044d09 5369
cbe24bfa
RH
5370static void in1_r3_o(DisasContext *s, DisasFields *f, DisasOps *o)
5371{
5372 o->in1 = regs[get_field(f, r3)];
5373 o->g_in1 = true;
5374}
49f7ee80 5375#define SPEC_in1_r3_o 0
cbe24bfa
RH
5376
5377static void in1_r3_32s(DisasContext *s, DisasFields *f, DisasOps *o)
5378{
5379 o->in1 = tcg_temp_new_i64();
5380 tcg_gen_ext32s_i64(o->in1, regs[get_field(f, r3)]);
5381}
49f7ee80 5382#define SPEC_in1_r3_32s 0
cbe24bfa
RH
5383
5384static void in1_r3_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5385{
5386 o->in1 = tcg_temp_new_i64();
5387 tcg_gen_ext32u_i64(o->in1, regs[get_field(f, r3)]);
5388}
49f7ee80 5389#define SPEC_in1_r3_32u 0
cbe24bfa 5390
b7886de3
RH
5391static void in1_r3_D32(DisasContext *s, DisasFields *f, DisasOps *o)
5392{
5393 int r3 = get_field(f, r3);
5394 o->in1 = tcg_temp_new_i64();
5395 tcg_gen_concat32_i64(o->in1, regs[r3 + 1], regs[r3]);
5396}
5397#define SPEC_in1_r3_D32 SPEC_r3_even
5398
00574261
RH
5399static void in1_e1(DisasContext *s, DisasFields *f, DisasOps *o)
5400{
5401 o->in1 = load_freg32_i64(get_field(f, r1));
5402}
49f7ee80 5403#define SPEC_in1_e1 0
00574261
RH
5404
5405static void in1_f1_o(DisasContext *s, DisasFields *f, DisasOps *o)
5406{
5407 o->in1 = fregs[get_field(f, r1)];
5408 o->g_in1 = true;
5409}
49f7ee80 5410#define SPEC_in1_f1_o 0
00574261 5411
587626f8
RH
5412static void in1_x1_o(DisasContext *s, DisasFields *f, DisasOps *o)
5413{
587626f8
RH
5414 int r1 = get_field(f, r1);
5415 o->out = fregs[r1];
49f7ee80 5416 o->out2 = fregs[r1 + 2];
587626f8
RH
5417 o->g_out = o->g_out2 = true;
5418}
49f7ee80 5419#define SPEC_in1_x1_o SPEC_r1_f128
587626f8 5420
2db014b5
RH
5421static void in1_f3_o(DisasContext *s, DisasFields *f, DisasOps *o)
5422{
5423 o->in1 = fregs[get_field(f, r3)];
5424 o->g_in1 = true;
5425}
49f7ee80 5426#define SPEC_in1_f3_o 0
2db014b5 5427
ad044d09
RH
5428static void in1_la1(DisasContext *s, DisasFields *f, DisasOps *o)
5429{
5430 o->addr1 = get_address(s, 0, get_field(f, b1), get_field(f, d1));
5431}
49f7ee80 5432#define SPEC_in1_la1 0
ad044d09 5433
e025e52a
RH
5434static void in1_la2(DisasContext *s, DisasFields *f, DisasOps *o)
5435{
5436 int x2 = have_field(f, x2) ? get_field(f, x2) : 0;
5437 o->addr1 = get_address(s, x2, get_field(f, b2), get_field(f, d2));
5438}
49f7ee80 5439#define SPEC_in1_la2 0
e025e52a 5440
a7e836d5
RH
5441static void in1_m1_8u(DisasContext *s, DisasFields *f, DisasOps *o)
5442{
5443 in1_la1(s, f, o);
5444 o->in1 = tcg_temp_new_i64();
5445 tcg_gen_qemu_ld8u(o->in1, o->addr1, get_mem_index(s));
5446}
49f7ee80 5447#define SPEC_in1_m1_8u 0
a7e836d5
RH
5448
5449static void in1_m1_16s(DisasContext *s, DisasFields *f, DisasOps *o)
5450{
5451 in1_la1(s, f, o);
5452 o->in1 = tcg_temp_new_i64();
5453 tcg_gen_qemu_ld16s(o->in1, o->addr1, get_mem_index(s));
5454}
49f7ee80 5455#define SPEC_in1_m1_16s 0
a7e836d5
RH
5456
5457static void in1_m1_16u(DisasContext *s, DisasFields *f, DisasOps *o)
5458{
5459 in1_la1(s, f, o);
5460 o->in1 = tcg_temp_new_i64();
5461 tcg_gen_qemu_ld16u(o->in1, o->addr1, get_mem_index(s));
5462}
49f7ee80 5463#define SPEC_in1_m1_16u 0
a7e836d5 5464
ad044d09
RH
5465static void in1_m1_32s(DisasContext *s, DisasFields *f, DisasOps *o)
5466{
5467 in1_la1(s, f, o);
5468 o->in1 = tcg_temp_new_i64();
5469 tcg_gen_qemu_ld32s(o->in1, o->addr1, get_mem_index(s));
5470}
49f7ee80 5471#define SPEC_in1_m1_32s 0
ad044d09 5472
e272b3ac
RH
5473static void in1_m1_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5474{
5475 in1_la1(s, f, o);
5476 o->in1 = tcg_temp_new_i64();
5477 tcg_gen_qemu_ld32u(o->in1, o->addr1, get_mem_index(s));
5478}
49f7ee80 5479#define SPEC_in1_m1_32u 0
e272b3ac 5480
ad044d09
RH
5481static void in1_m1_64(DisasContext *s, DisasFields *f, DisasOps *o)
5482{
5483 in1_la1(s, f, o);
5484 o->in1 = tcg_temp_new_i64();
5485 tcg_gen_qemu_ld64(o->in1, o->addr1, get_mem_index(s));
5486}
49f7ee80 5487#define SPEC_in1_m1_64 0
ad044d09
RH
5488
5489/* ====================================================================== */
5490/* The "INput 2" generators. These load the second operand to an insn. */
5491
e025e52a
RH
5492static void in2_r1_o(DisasContext *s, DisasFields *f, DisasOps *o)
5493{
5494 o->in2 = regs[get_field(f, r1)];
5495 o->g_in2 = true;
5496}
49f7ee80 5497#define SPEC_in2_r1_o 0
e025e52a
RH
5498
5499static void in2_r1_16u(DisasContext *s, DisasFields *f, DisasOps *o)
5500{
5501 o->in2 = tcg_temp_new_i64();
5502 tcg_gen_ext16u_i64(o->in2, regs[get_field(f, r1)]);
5503}
49f7ee80 5504#define SPEC_in2_r1_16u 0
e025e52a
RH
5505
5506static void in2_r1_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5507{
5508 o->in2 = tcg_temp_new_i64();
5509 tcg_gen_ext32u_i64(o->in2, regs[get_field(f, r1)]);
5510}
49f7ee80 5511#define SPEC_in2_r1_32u 0
e025e52a 5512
b7886de3
RH
5513static void in2_r1_D32(DisasContext *s, DisasFields *f, DisasOps *o)
5514{
5515 int r1 = get_field(f, r1);
5516 o->in2 = tcg_temp_new_i64();
5517 tcg_gen_concat32_i64(o->in2, regs[r1 + 1], regs[r1]);
5518}
5519#define SPEC_in2_r1_D32 SPEC_r1_even
5520
ad044d09
RH
5521static void in2_r2(DisasContext *s, DisasFields *f, DisasOps *o)
5522{
5523 o->in2 = load_reg(get_field(f, r2));
5524}
49f7ee80 5525#define SPEC_in2_r2 0
ad044d09 5526
d1c04a2b
RH
5527static void in2_r2_o(DisasContext *s, DisasFields *f, DisasOps *o)
5528{
5529 o->in2 = regs[get_field(f, r2)];
5530 o->g_in2 = true;
5531}
49f7ee80 5532#define SPEC_in2_r2_o 0
d1c04a2b 5533
8ac33cdb
RH
5534static void in2_r2_nz(DisasContext *s, DisasFields *f, DisasOps *o)
5535{
5536 int r2 = get_field(f, r2);
5537 if (r2 != 0) {
5538 o->in2 = load_reg(r2);
5539 }
5540}
49f7ee80 5541#define SPEC_in2_r2_nz 0
8ac33cdb 5542
c698d876
RH
5543static void in2_r2_8s(DisasContext *s, DisasFields *f, DisasOps *o)
5544{
5545 o->in2 = tcg_temp_new_i64();
5546 tcg_gen_ext8s_i64(o->in2, regs[get_field(f, r2)]);
5547}
49f7ee80 5548#define SPEC_in2_r2_8s 0
c698d876
RH
5549
5550static void in2_r2_8u(DisasContext *s, DisasFields *f, DisasOps *o)
5551{
5552 o->in2 = tcg_temp_new_i64();
5553 tcg_gen_ext8u_i64(o->in2, regs[get_field(f, r2)]);
5554}
49f7ee80 5555#define SPEC_in2_r2_8u 0
c698d876
RH
5556
5557static void in2_r2_16s(DisasContext *s, DisasFields *f, DisasOps *o)
5558{
5559 o->in2 = tcg_temp_new_i64();
5560 tcg_gen_ext16s_i64(o->in2, regs[get_field(f, r2)]);
5561}
49f7ee80 5562#define SPEC_in2_r2_16s 0
c698d876
RH
5563
5564static void in2_r2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
5565{
5566 o->in2 = tcg_temp_new_i64();
5567 tcg_gen_ext16u_i64(o->in2, regs[get_field(f, r2)]);
5568}
49f7ee80 5569#define SPEC_in2_r2_16u 0
c698d876 5570
ad044d09
RH
5571static void in2_r3(DisasContext *s, DisasFields *f, DisasOps *o)
5572{
5573 o->in2 = load_reg(get_field(f, r3));
5574}
49f7ee80 5575#define SPEC_in2_r3 0
ad044d09 5576
a1f12d85
AJ
5577static void in2_r3_sr32(DisasContext *s, DisasFields *f, DisasOps *o)
5578{
5579 o->in2 = tcg_temp_new_i64();
5580 tcg_gen_shri_i64(o->in2, regs[get_field(f, r3)], 32);
5581}
5582#define SPEC_in2_r3_sr32 0
5583
ad044d09
RH
5584static void in2_r2_32s(DisasContext *s, DisasFields *f, DisasOps *o)
5585{
5586 o->in2 = tcg_temp_new_i64();
5587 tcg_gen_ext32s_i64(o->in2, regs[get_field(f, r2)]);
5588}
49f7ee80 5589#define SPEC_in2_r2_32s 0
ad044d09
RH
5590
5591static void in2_r2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5592{
5593 o->in2 = tcg_temp_new_i64();
5594 tcg_gen_ext32u_i64(o->in2, regs[get_field(f, r2)]);
5595}
49f7ee80 5596#define SPEC_in2_r2_32u 0
ad044d09 5597
a1f12d85
AJ
5598static void in2_r2_sr32(DisasContext *s, DisasFields *f, DisasOps *o)
5599{
5600 o->in2 = tcg_temp_new_i64();
5601 tcg_gen_shri_i64(o->in2, regs[get_field(f, r2)], 32);
5602}
5603#define SPEC_in2_r2_sr32 0
5604
d764a8d1
RH
5605static void in2_e2(DisasContext *s, DisasFields *f, DisasOps *o)
5606{
5607 o->in2 = load_freg32_i64(get_field(f, r2));
5608}
49f7ee80 5609#define SPEC_in2_e2 0
d764a8d1
RH
5610
5611static void in2_f2_o(DisasContext *s, DisasFields *f, DisasOps *o)
5612{
5613 o->in2 = fregs[get_field(f, r2)];
5614 o->g_in2 = true;
5615}
49f7ee80 5616#define SPEC_in2_f2_o 0
d764a8d1
RH
5617
5618static void in2_x2_o(DisasContext *s, DisasFields *f, DisasOps *o)
5619{
587626f8
RH
5620 int r2 = get_field(f, r2);
5621 o->in1 = fregs[r2];
49f7ee80 5622 o->in2 = fregs[r2 + 2];
d764a8d1
RH
5623 o->g_in1 = o->g_in2 = true;
5624}
49f7ee80 5625#define SPEC_in2_x2_o SPEC_r2_f128
d764a8d1 5626
374724f9
RH
5627static void in2_ra2(DisasContext *s, DisasFields *f, DisasOps *o)
5628{
5629 o->in2 = get_address(s, 0, get_field(f, r2), 0);
5630}
49f7ee80 5631#define SPEC_in2_ra2 0
374724f9 5632
ad044d09
RH
5633static void in2_a2(DisasContext *s, DisasFields *f, DisasOps *o)
5634{
5635 int x2 = have_field(f, x2) ? get_field(f, x2) : 0;
5636 o->in2 = get_address(s, x2, get_field(f, b2), get_field(f, d2));
5637}
49f7ee80 5638#define SPEC_in2_a2 0
ad044d09 5639
a7e836d5
RH
5640static void in2_ri2(DisasContext *s, DisasFields *f, DisasOps *o)
5641{
eccf741a 5642 o->in2 = tcg_const_i64(s->base.pc_next + (int64_t)get_field(f, i2) * 2);
a7e836d5 5643}
49f7ee80 5644#define SPEC_in2_ri2 0
a7e836d5 5645
cbe24bfa
RH
5646static void in2_sh32(DisasContext *s, DisasFields *f, DisasOps *o)
5647{
5648 help_l2_shift(s, f, o, 31);
5649}
49f7ee80 5650#define SPEC_in2_sh32 0
cbe24bfa
RH
5651
5652static void in2_sh64(DisasContext *s, DisasFields *f, DisasOps *o)
5653{
5654 help_l2_shift(s, f, o, 63);
5655}
49f7ee80 5656#define SPEC_in2_sh64 0
cbe24bfa 5657
afdc70be
RH
5658static void in2_m2_8u(DisasContext *s, DisasFields *f, DisasOps *o)
5659{
5660 in2_a2(s, f, o);
5661 tcg_gen_qemu_ld8u(o->in2, o->in2, get_mem_index(s));
5662}
49f7ee80 5663#define SPEC_in2_m2_8u 0
afdc70be 5664
d82287de
RH
5665static void in2_m2_16s(DisasContext *s, DisasFields *f, DisasOps *o)
5666{
5667 in2_a2(s, f, o);
5668 tcg_gen_qemu_ld16s(o->in2, o->in2, get_mem_index(s));
5669}
49f7ee80 5670#define SPEC_in2_m2_16s 0
d82287de 5671
d54f5865
RH
5672static void in2_m2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
5673{
5674 in2_a2(s, f, o);
5675 tcg_gen_qemu_ld16u(o->in2, o->in2, get_mem_index(s));
5676}
49f7ee80 5677#define SPEC_in2_m2_16u 0
d54f5865 5678
ad044d09
RH
5679static void in2_m2_32s(DisasContext *s, DisasFields *f, DisasOps *o)
5680{
5681 in2_a2(s, f, o);
5682 tcg_gen_qemu_ld32s(o->in2, o->in2, get_mem_index(s));
5683}
49f7ee80 5684#define SPEC_in2_m2_32s 0
ad044d09
RH
5685
5686static void in2_m2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5687{
5688 in2_a2(s, f, o);
5689 tcg_gen_qemu_ld32u(o->in2, o->in2, get_mem_index(s));
5690}
49f7ee80 5691#define SPEC_in2_m2_32u 0
ad044d09 5692
21fc97c5
DH
5693#ifndef CONFIG_USER_ONLY
5694static void in2_m2_32ua(DisasContext *s, DisasFields *f, DisasOps *o)
5695{
5696 in2_a2(s, f, o);
5697 tcg_gen_qemu_ld_tl(o->in2, o->in2, get_mem_index(s), MO_TEUL | MO_ALIGN);
5698}
5699#define SPEC_in2_m2_32ua 0
5700#endif
5701
ad044d09
RH
5702static void in2_m2_64(DisasContext *s, DisasFields *f, DisasOps *o)
5703{
5704 in2_a2(s, f, o);
5705 tcg_gen_qemu_ld64(o->in2, o->in2, get_mem_index(s));
5706}
49f7ee80 5707#define SPEC_in2_m2_64 0
ad044d09 5708
21fc97c5
DH
5709#ifndef CONFIG_USER_ONLY
5710static void in2_m2_64a(DisasContext *s, DisasFields *f, DisasOps *o)
5711{
5712 in2_a2(s, f, o);
5713 tcg_gen_qemu_ld_i64(o->in2, o->in2, get_mem_index(s), MO_TEQ | MO_ALIGN);
5714}
5715#define SPEC_in2_m2_64a 0
5716#endif
5717
a7e836d5
RH
5718static void in2_mri2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
5719{
5720 in2_ri2(s, f, o);
5721 tcg_gen_qemu_ld16u(o->in2, o->in2, get_mem_index(s));
5722}
49f7ee80 5723#define SPEC_in2_mri2_16u 0
a7e836d5
RH
5724
5725static void in2_mri2_32s(DisasContext *s, DisasFields *f, DisasOps *o)
5726{
5727 in2_ri2(s, f, o);
5728 tcg_gen_qemu_ld32s(o->in2, o->in2, get_mem_index(s));
5729}
49f7ee80 5730#define SPEC_in2_mri2_32s 0
a7e836d5
RH
5731
5732static void in2_mri2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5733{
5734 in2_ri2(s, f, o);
5735 tcg_gen_qemu_ld32u(o->in2, o->in2, get_mem_index(s));
5736}
49f7ee80 5737#define SPEC_in2_mri2_32u 0
a7e836d5
RH
5738
5739static void in2_mri2_64(DisasContext *s, DisasFields *f, DisasOps *o)
5740{
5741 in2_ri2(s, f, o);
5742 tcg_gen_qemu_ld64(o->in2, o->in2, get_mem_index(s));
5743}
49f7ee80 5744#define SPEC_in2_mri2_64 0
a7e836d5 5745
ad044d09
RH
5746static void in2_i2(DisasContext *s, DisasFields *f, DisasOps *o)
5747{
5748 o->in2 = tcg_const_i64(get_field(f, i2));
5749}
49f7ee80 5750#define SPEC_in2_i2 0
ad044d09 5751
a7e836d5
RH
5752static void in2_i2_8u(DisasContext *s, DisasFields *f, DisasOps *o)
5753{
5754 o->in2 = tcg_const_i64((uint8_t)get_field(f, i2));
5755}
49f7ee80 5756#define SPEC_in2_i2_8u 0
a7e836d5
RH
5757
5758static void in2_i2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
5759{
5760 o->in2 = tcg_const_i64((uint16_t)get_field(f, i2));
5761}
49f7ee80 5762#define SPEC_in2_i2_16u 0
a7e836d5 5763
ad044d09
RH
5764static void in2_i2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5765{
5766 o->in2 = tcg_const_i64((uint32_t)get_field(f, i2));
5767}
49f7ee80 5768#define SPEC_in2_i2_32u 0
ad044d09 5769
ade9dea4
RH
5770static void in2_i2_16u_shl(DisasContext *s, DisasFields *f, DisasOps *o)
5771{
5772 uint64_t i2 = (uint16_t)get_field(f, i2);
5773 o->in2 = tcg_const_i64(i2 << s->insn->data);
5774}
49f7ee80 5775#define SPEC_in2_i2_16u_shl 0
ade9dea4
RH
5776
5777static void in2_i2_32u_shl(DisasContext *s, DisasFields *f, DisasOps *o)
5778{
5779 uint64_t i2 = (uint32_t)get_field(f, i2);
5780 o->in2 = tcg_const_i64(i2 << s->insn->data);
5781}
49f7ee80 5782#define SPEC_in2_i2_32u_shl 0
ade9dea4 5783
ad8a4570
AG
5784#ifndef CONFIG_USER_ONLY
5785static void in2_insn(DisasContext *s, DisasFields *f, DisasOps *o)
5786{
5787 o->in2 = tcg_const_i64(s->fields->raw_insn);
5788}
5789#define SPEC_in2_insn 0
5790#endif
5791
ad044d09
RH
5792/* ====================================================================== */
5793
5794/* Find opc within the table of insns. This is formulated as a switch
5795 statement so that (1) we get compile-time notice of cut-paste errors
5796 for duplicated opcodes, and (2) the compiler generates the binary
5797 search tree, rather than us having to post-process the table. */
5798
5799#define C(OPC, NM, FT, FC, I1, I2, P, W, OP, CC) \
5800 D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, 0)
5801
5802#define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) insn_ ## NM,
5803
5804enum DisasInsnEnum {
5805#include "insn-data.def"
5806};
5807
5808#undef D
49f7ee80
RH
5809#define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) { \
5810 .opc = OPC, \
5811 .fmt = FMT_##FT, \
5812 .fac = FAC_##FC, \
5813 .spec = SPEC_in1_##I1 | SPEC_in2_##I2 | SPEC_prep_##P | SPEC_wout_##W, \
5814 .name = #NM, \
5815 .help_in1 = in1_##I1, \
5816 .help_in2 = in2_##I2, \
5817 .help_prep = prep_##P, \
5818 .help_wout = wout_##W, \
5819 .help_cout = cout_##CC, \
5820 .help_op = op_##OP, \
5821 .data = D \
ad044d09
RH
5822 },
5823
5824/* Allow 0 to be used for NULL in the table below. */
5825#define in1_0 NULL
5826#define in2_0 NULL
5827#define prep_0 NULL
5828#define wout_0 NULL
5829#define cout_0 NULL
5830#define op_0 NULL
5831
49f7ee80
RH
5832#define SPEC_in1_0 0
5833#define SPEC_in2_0 0
5834#define SPEC_prep_0 0
5835#define SPEC_wout_0 0
5836
d20bd43c
RH
5837/* Give smaller names to the various facilities. */
5838#define FAC_Z S390_FEAT_ZARCH
5839#define FAC_CASS S390_FEAT_COMPARE_AND_SWAP_AND_STORE
d20bd43c
RH
5840#define FAC_DFP S390_FEAT_DFP
5841#define FAC_DFPR S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* DFP-rounding */
5842#define FAC_DO S390_FEAT_STFLE_45 /* distinct-operands */
5843#define FAC_EE S390_FEAT_EXECUTE_EXT
5844#define FAC_EI S390_FEAT_EXTENDED_IMMEDIATE
5845#define FAC_FPE S390_FEAT_FLOATING_POINT_EXT
5846#define FAC_FPSSH S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* FPS-sign-handling */
5847#define FAC_FPRGR S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* FPR-GR-transfer */
5848#define FAC_GIE S390_FEAT_GENERAL_INSTRUCTIONS_EXT
5849#define FAC_HFP_MA S390_FEAT_HFP_MADDSUB
5850#define FAC_HW S390_FEAT_STFLE_45 /* high-word */
5851#define FAC_IEEEE_SIM S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* IEEE-exception-simulation */
5852#define FAC_MIE S390_FEAT_STFLE_49 /* misc-instruction-extensions */
5853#define FAC_LAT S390_FEAT_STFLE_49 /* load-and-trap */
5854#define FAC_LOC S390_FEAT_STFLE_45 /* load/store on condition 1 */
45aa9aa3 5855#define FAC_LOC2 S390_FEAT_STFLE_53 /* load/store on condition 2 */
d20bd43c
RH
5856#define FAC_LD S390_FEAT_LONG_DISPLACEMENT
5857#define FAC_PC S390_FEAT_STFLE_45 /* population count */
5858#define FAC_SCF S390_FEAT_STORE_CLOCK_FAST
5859#define FAC_SFLE S390_FEAT_STFLE
5860#define FAC_ILA S390_FEAT_STFLE_45 /* interlocked-access-facility 1 */
3e7e5e0b 5861#define FAC_MVCOS S390_FEAT_MOVE_WITH_OPTIONAL_SPEC
d20bd43c
RH
5862#define FAC_LPP S390_FEAT_SET_PROGRAM_PARAMETERS /* load-program-parameter */
5863#define FAC_DAT_ENH S390_FEAT_DAT_ENH
5864#define FAC_E2 S390_FEAT_EXTENDED_TRANSLATION_2
6a68acd5 5865#define FAC_EH S390_FEAT_STFLE_49 /* execution-hint */
632c61a9 5866#define FAC_PPA S390_FEAT_STFLE_49 /* processor-assist */
c2a5c1d7 5867#define FAC_LZRB S390_FEAT_STFLE_53 /* load-and-zero-rightmost-byte */
941ef3db 5868#define FAC_ETF3 S390_FEAT_EXTENDED_TRANSLATION_3
7705c750
DH
5869#define FAC_MSA S390_FEAT_MSA /* message-security-assist facility */
5870#define FAC_MSA3 S390_FEAT_MSA_EXT_3 /* msa-extension-3 facility */
5871#define FAC_MSA4 S390_FEAT_MSA_EXT_4 /* msa-extension-4 facility */
5872#define FAC_MSA5 S390_FEAT_MSA_EXT_5 /* msa-extension-5 facility */
4bac52f5 5873#define FAC_ECT S390_FEAT_EXTRACT_CPU_TIME
f6c232ce
CH
5874#define FAC_PCI S390_FEAT_ZPCI /* z/PCI facility */
5875#define FAC_AIS S390_FEAT_ADAPTER_INT_SUPPRESSION
d20bd43c 5876
ad044d09
RH
5877static const DisasInsn insn_info[] = {
5878#include "insn-data.def"
5879};
5880
5881#undef D
5882#define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) \
5883 case OPC: return &insn_info[insn_ ## NM];
5884
5885static const DisasInsn *lookup_opc(uint16_t opc)
5886{
5887 switch (opc) {
5888#include "insn-data.def"
5889 default:
5890 return NULL;
5891 }
5892}
5893
5894#undef D
5895#undef C
5896
5897/* Extract a field from the insn. The INSN should be left-aligned in
5898 the uint64_t so that we can more easily utilize the big-bit-endian
5899 definitions we extract from the Principals of Operation. */
5900
5901static void extract_field(DisasFields *o, const DisasField *f, uint64_t insn)
5902{
5903 uint32_t r, m;
5904
5905 if (f->size == 0) {
5906 return;
5907 }
5908
5909 /* Zero extract the field from the insn. */
5910 r = (insn << f->beg) >> (64 - f->size);
5911
5912 /* Sign-extend, or un-swap the field as necessary. */
5913 switch (f->type) {
5914 case 0: /* unsigned */
5915 break;
5916 case 1: /* signed */
5917 assert(f->size <= 32);
5918 m = 1u << (f->size - 1);
5919 r = (r ^ m) - m;
5920 break;
5921 case 2: /* dl+dh split, signed 20 bit. */
5922 r = ((int8_t)r << 12) | (r >> 8);
5923 break;
5924 default:
5925 abort();
5926 }
5927
5928 /* Validate that the "compressed" encoding we selected above is valid.
5929 I.e. we havn't make two different original fields overlap. */
5930 assert(((o->presentC >> f->indexC) & 1) == 0);
5931 o->presentC |= 1 << f->indexC;
5932 o->presentO |= 1 << f->indexO;
5933
5934 o->c[f->indexC] = r;
5935}
5936
5937/* Lookup the insn at the current PC, extracting the operands into O and
5938 returning the info struct for the insn. Returns NULL for invalid insn. */
5939
5940static const DisasInsn *extract_insn(CPUS390XState *env, DisasContext *s,
5941 DisasFields *f)
5942{
eccf741a 5943 uint64_t insn, pc = s->base.pc_next;
d5a103cd 5944 int op, op2, ilen;
ad044d09
RH
5945 const DisasInsn *info;
5946
303c681a
RH
5947 if (unlikely(s->ex_value)) {
5948 /* Drop the EX data now, so that it's clear on exception paths. */
5949 TCGv_i64 zero = tcg_const_i64(0);
5950 tcg_gen_st_i64(zero, cpu_env, offsetof(CPUS390XState, ex_value));
5951 tcg_temp_free_i64(zero);
d5a103cd 5952
303c681a
RH
5953 /* Extract the values saved by EXECUTE. */
5954 insn = s->ex_value & 0xffffffffffff0000ull;
5955 ilen = s->ex_value & 0xf;
5956 op = insn >> 56;
5957 } else {
5958 insn = ld_code2(env, pc);
5959 op = (insn >> 8) & 0xff;
5960 ilen = get_ilen(op);
5961 switch (ilen) {
5962 case 2:
5963 insn = insn << 48;
5964 break;
5965 case 4:
5966 insn = ld_code4(env, pc) << 32;
5967 break;
5968 case 6:
5969 insn = (insn << 48) | (ld_code4(env, pc + 2) << 16);
5970 break;
5971 default:
5972 g_assert_not_reached();
5973 }
ad044d09 5974 }
eccf741a 5975 s->pc_tmp = s->base.pc_next + ilen;
303c681a 5976 s->ilen = ilen;
ad044d09
RH
5977
5978 /* We can't actually determine the insn format until we've looked up
5979 the full insn opcode. Which we can't do without locating the
5980 secondary opcode. Assume by default that OP2 is at bit 40; for
5981 those smaller insns that don't actually have a secondary opcode
5982 this will correctly result in OP2 = 0. */
5983 switch (op) {
5984 case 0x01: /* E */
5985 case 0x80: /* S */
5986 case 0x82: /* S */
5987 case 0x93: /* S */
6a68acd5 5988 case 0xb2: /* S, RRF, RRE, IE */
ad044d09
RH
5989 case 0xb3: /* RRE, RRD, RRF */
5990 case 0xb9: /* RRE, RRF */
5991 case 0xe5: /* SSE, SIL */
5992 op2 = (insn << 8) >> 56;
5993 break;
5994 case 0xa5: /* RI */
5995 case 0xa7: /* RI */
5996 case 0xc0: /* RIL */
5997 case 0xc2: /* RIL */
5998 case 0xc4: /* RIL */
5999 case 0xc6: /* RIL */
6000 case 0xc8: /* SSF */
6001 case 0xcc: /* RIL */
6002 op2 = (insn << 12) >> 60;
6003 break;
6a68acd5
RH
6004 case 0xc5: /* MII */
6005 case 0xc7: /* SMI */
ad044d09
RH
6006 case 0xd0 ... 0xdf: /* SS */
6007 case 0xe1: /* SS */
6008 case 0xe2: /* SS */
6009 case 0xe8: /* SS */
6010 case 0xe9: /* SS */
6011 case 0xea: /* SS */
6012 case 0xee ... 0xf3: /* SS */
6013 case 0xf8 ... 0xfd: /* SS */
6014 op2 = 0;
6015 break;
6016 default:
6017 op2 = (insn << 40) >> 56;
6018 break;
6019 }
6020
6021 memset(f, 0, sizeof(*f));
ad8a4570 6022 f->raw_insn = insn;
ad044d09
RH
6023 f->op = op;
6024 f->op2 = op2;
6025
6026 /* Lookup the instruction. */
6027 info = lookup_opc(op << 8 | op2);
6028
6029 /* If we found it, extract the operands. */
6030 if (info != NULL) {
6031 DisasFormat fmt = info->fmt;
6032 int i;
6033
6034 for (i = 0; i < NUM_C_FIELD; ++i) {
6035 extract_field(f, &format_info[fmt].op[i], insn);
6036 }
6037 }
6038 return info;
6039}
6040
21a8eced 6041static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s)
ad044d09
RH
6042{
6043 const DisasInsn *insn;
21a8eced 6044 DisasJumpType ret = DISAS_NEXT;
ad044d09
RH
6045 DisasFields f;
6046 DisasOps o;
6047
4f3adfb2 6048 /* Search for the insn in the table. */
ad044d09 6049 insn = extract_insn(env, s, &f);
e023e832 6050
4f3adfb2 6051 /* Not found means unimplemented/illegal opcode. */
ad044d09 6052 if (insn == NULL) {
4f3adfb2
RH
6053 qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%02x%02x\n",
6054 f.op, f.op2);
6055 gen_illegal_opcode(s);
21a8eced 6056 return DISAS_NORETURN;
ad044d09
RH
6057 }
6058
f0e0d817 6059#ifndef CONFIG_USER_ONLY
eccf741a
EC
6060 if (s->base.tb->flags & FLAG_MASK_PER) {
6061 TCGv_i64 addr = tcg_const_i64(s->base.pc_next);
f0e0d817
AJ
6062 gen_helper_per_ifetch(cpu_env, addr);
6063 tcg_temp_free_i64(addr);
6064 }
6065#endif
6066
49f7ee80
RH
6067 /* Check for insn specification exceptions. */
6068 if (insn->spec) {
6069 int spec = insn->spec, excp = 0, r;
6070
6071 if (spec & SPEC_r1_even) {
6072 r = get_field(&f, r1);
6073 if (r & 1) {
6074 excp = PGM_SPECIFICATION;
6075 }
6076 }
6077 if (spec & SPEC_r2_even) {
6078 r = get_field(&f, r2);
6079 if (r & 1) {
b7886de3
RH
6080 excp = PGM_SPECIFICATION;
6081 }
6082 }
6083 if (spec & SPEC_r3_even) {
6084 r = get_field(&f, r3);
6085 if (r & 1) {
49f7ee80
RH
6086 excp = PGM_SPECIFICATION;
6087 }
6088 }
6089 if (spec & SPEC_r1_f128) {
6090 r = get_field(&f, r1);
6091 if (r > 13) {
6092 excp = PGM_SPECIFICATION;
6093 }
6094 }
6095 if (spec & SPEC_r2_f128) {
6096 r = get_field(&f, r2);
6097 if (r > 13) {
6098 excp = PGM_SPECIFICATION;
6099 }
6100 }
6101 if (excp) {
6102 gen_program_exception(s, excp);
21a8eced 6103 return DISAS_NORETURN;
49f7ee80
RH
6104 }
6105 }
6106
ad044d09
RH
6107 /* Set up the strutures we use to communicate with the helpers. */
6108 s->insn = insn;
6109 s->fields = &f;
6110 o.g_out = o.g_out2 = o.g_in1 = o.g_in2 = false;
f764718d
RH
6111 o.out = NULL;
6112 o.out2 = NULL;
6113 o.in1 = NULL;
6114 o.in2 = NULL;
6115 o.addr1 = NULL;
ad044d09
RH
6116
6117 /* Implement the instruction. */
6118 if (insn->help_in1) {
6119 insn->help_in1(s, &f, &o);
6120 }
6121 if (insn->help_in2) {
6122 insn->help_in2(s, &f, &o);
6123 }
6124 if (insn->help_prep) {
6125 insn->help_prep(s, &f, &o);
6126 }
6127 if (insn->help_op) {
6128 ret = insn->help_op(s, &o);
6129 }
6130 if (insn->help_wout) {
6131 insn->help_wout(s, &f, &o);
6132 }
6133 if (insn->help_cout) {
6134 insn->help_cout(s, &o);
6135 }
6136
6137 /* Free any temporaries created by the helpers. */
f764718d 6138 if (o.out && !o.g_out) {
ad044d09
RH
6139 tcg_temp_free_i64(o.out);
6140 }
f764718d 6141 if (o.out2 && !o.g_out2) {
ad044d09
RH
6142 tcg_temp_free_i64(o.out2);
6143 }
f764718d 6144 if (o.in1 && !o.g_in1) {
ad044d09
RH
6145 tcg_temp_free_i64(o.in1);
6146 }
f764718d 6147 if (o.in2 && !o.g_in2) {
ad044d09
RH
6148 tcg_temp_free_i64(o.in2);
6149 }
f764718d 6150 if (o.addr1) {
ad044d09
RH
6151 tcg_temp_free_i64(o.addr1);
6152 }
6153
777c98c3 6154#ifndef CONFIG_USER_ONLY
eccf741a 6155 if (s->base.tb->flags & FLAG_MASK_PER) {
777c98c3 6156 /* An exception might be triggered, save PSW if not already done. */
21a8eced 6157 if (ret == DISAS_NEXT || ret == DISAS_PC_STALE) {
eccf741a 6158 tcg_gen_movi_i64(psw_addr, s->pc_tmp);
777c98c3
AJ
6159 }
6160
777c98c3
AJ
6161 /* Call the helper to check for a possible PER exception. */
6162 gen_helper_per_check_exception(cpu_env);
6163 }
6164#endif
6165
ad044d09 6166 /* Advance to the next instruction. */
eccf741a 6167 s->base.pc_next = s->pc_tmp;
ad044d09 6168 return ret;
e023e832
AG
6169}
6170
c88691aa 6171static void s390x_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
e023e832 6172{
c88691aa 6173 DisasContext *dc = container_of(dcbase, DisasContext, base);
e023e832 6174
e023e832 6175 /* 31-bit mode */
c88691aa
EC
6176 if (!(dc->base.tb->flags & FLAG_MASK_64)) {
6177 dc->base.pc_first &= 0x7fffffff;
6178 dc->base.pc_next = dc->base.pc_first;
e023e832
AG
6179 }
6180
c88691aa
EC
6181 dc->cc_op = CC_OP_DYNAMIC;
6182 dc->ex_value = dc->base.tb->cs_base;
6183 dc->do_debug = dc->base.singlestep_enabled;
6184}
e023e832 6185
c88691aa
EC
6186static void s390x_tr_tb_start(DisasContextBase *db, CPUState *cs)
6187{
6188}
e023e832 6189
c88691aa
EC
6190static void s390x_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
6191{
6192 DisasContext *dc = container_of(dcbase, DisasContext, base);
e023e832 6193
c88691aa
EC
6194 tcg_gen_insn_start(dc->base.pc_next, dc->cc_op);
6195}
e023e832 6196
c88691aa
EC
6197static bool s390x_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
6198 const CPUBreakpoint *bp)
6199{
6200 DisasContext *dc = container_of(dcbase, DisasContext, base);
667b8e29 6201
c88691aa
EC
6202 dc->base.is_jmp = DISAS_PC_STALE;
6203 dc->do_debug = true;
6204 /* The address covered by the breakpoint must be included in
6205 [tb->pc, tb->pc + tb->size) in order to for it to be
6206 properly cleared -- thus we increment the PC here so that
6207 the logic setting tb->size does the right thing. */
6208 dc->base.pc_next += 2;
6209 return true;
6210}
7193b5f6 6211
c88691aa
EC
6212static void s390x_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
6213{
6214 CPUS390XState *env = cs->env_ptr;
6215 DisasContext *dc = container_of(dcbase, DisasContext, base);
7193b5f6 6216
c88691aa
EC
6217 dc->base.is_jmp = translate_one(env, dc);
6218 if (dc->base.is_jmp == DISAS_NEXT) {
6219 uint64_t page_start;
e023e832 6220
c88691aa
EC
6221 page_start = dc->base.pc_first & TARGET_PAGE_MASK;
6222 if (dc->base.pc_next - page_start >= TARGET_PAGE_SIZE || dc->ex_value) {
6223 dc->base.is_jmp = DISAS_TOO_MANY;
6224 }
e023e832 6225 }
c88691aa
EC
6226}
6227
6228static void s390x_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
6229{
6230 DisasContext *dc = container_of(dcbase, DisasContext, base);
ad044d09 6231
c88691aa 6232 switch (dc->base.is_jmp) {
21a8eced
EC
6233 case DISAS_GOTO_TB:
6234 case DISAS_NORETURN:
ad044d09 6235 break;
21a8eced
EC
6236 case DISAS_TOO_MANY:
6237 case DISAS_PC_STALE:
6238 case DISAS_PC_STALE_NOCHAIN:
c88691aa 6239 update_psw_addr(dc);
ad044d09 6240 /* FALLTHRU */
21a8eced 6241 case DISAS_PC_UPDATED:
7a6c7067
RH
6242 /* Next TB starts off with CC_OP_DYNAMIC, so make sure the
6243 cc op type is in env */
c88691aa 6244 update_cc_op(dc);
06fc0348 6245 /* FALLTHRU */
21a8eced 6246 case DISAS_PC_CC_UPDATED:
7a6c7067 6247 /* Exit the TB, either by raising a debug exception or by return. */
c88691aa 6248 if (dc->do_debug) {
d5a103cd 6249 gen_exception(EXCP_DEBUG);
c88691aa
EC
6250 } else if (use_exit_tb(dc) ||
6251 dc->base.is_jmp == DISAS_PC_STALE_NOCHAIN) {
07ea28b4 6252 tcg_gen_exit_tb(NULL, 0);
6350001e 6253 } else {
7f11636d 6254 tcg_gen_lookup_and_goto_ptr();
ad044d09
RH
6255 }
6256 break;
6257 default:
542f70c2 6258 g_assert_not_reached();
e023e832 6259 }
c88691aa 6260}
ad044d09 6261
c88691aa
EC
6262static void s390x_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
6263{
6264 DisasContext *dc = container_of(dcbase, DisasContext, base);
ad044d09 6265
c88691aa
EC
6266 if (unlikely(dc->ex_value)) {
6267 /* ??? Unfortunately log_target_disas can't use host memory. */
6268 qemu_log("IN: EXECUTE %016" PRIx64, dc->ex_value);
6269 } else {
6270 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
6271 log_target_disas(cs, dc->base.pc_first, dc->base.tb->size);
e023e832 6272 }
c88691aa
EC
6273}
6274
6275static const TranslatorOps s390x_tr_ops = {
6276 .init_disas_context = s390x_tr_init_disas_context,
6277 .tb_start = s390x_tr_tb_start,
6278 .insn_start = s390x_tr_insn_start,
6279 .breakpoint_check = s390x_tr_breakpoint_check,
6280 .translate_insn = s390x_tr_translate_insn,
6281 .tb_stop = s390x_tr_tb_stop,
6282 .disas_log = s390x_tr_disas_log,
6283};
6284
6285void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
6286{
6287 DisasContext dc;
6288
6289 translator_loop(&s390x_tr_ops, &dc.base, cs, tb);
e023e832
AG
6290}
6291
bad729e2
RH
6292void restore_state_to_opc(CPUS390XState *env, TranslationBlock *tb,
6293 target_ulong *data)
e023e832 6294{
bad729e2
RH
6295 int cc_op = data[1];
6296 env->psw.addr = data[0];
e023e832
AG
6297 if ((cc_op != CC_OP_DYNAMIC) && (cc_op != CC_OP_STATIC)) {
6298 env->cc_op = cc_op;
6299 }
10ec5117 6300}