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