]> git.proxmox.com Git - mirror_qemu.git/blame - target/s390x/tcg/translate.c
target/s390x: Handle CLRL and CLGFRL with non-aligned addresses
[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 2772{
e6d70c82
IL
2773 tcg_gen_qemu_ld_tl(o->out, o->in2, get_mem_index(s),
2774 MO_TESL | s->insn->data);
21a8eced 2775 return DISAS_NEXT;
22c37a08
RH
2776}
2777
21a8eced 2778static DisasJumpType op_ld32u(DisasContext *s, DisasOps *o)
22c37a08 2779{
4942e4cc
IL
2780 tcg_gen_qemu_ld_tl(o->out, o->in2, get_mem_index(s),
2781 MO_TEUL | s->insn->data);
21a8eced 2782 return DISAS_NEXT;
22c37a08
RH
2783}
2784
21a8eced 2785static DisasJumpType op_ld64(DisasContext *s, DisasOps *o)
22c37a08 2786{
2a00d55d
IL
2787 tcg_gen_qemu_ld_i64(o->out, o->in2, get_mem_index(s),
2788 MO_TEUQ | s->insn->data);
21a8eced 2789 return DISAS_NEXT;
22c37a08
RH
2790}
2791
21a8eced 2792static DisasJumpType op_lat(DisasContext *s, DisasOps *o)
782a8479
AJ
2793{
2794 TCGLabel *lab = gen_new_label();
c30988d1 2795 store_reg32_i64(get_field(s, r1), o->in2);
782a8479
AJ
2796 /* The value is stored even in case of trap. */
2797 tcg_gen_brcondi_i64(TCG_COND_NE, o->in2, 0, lab);
2798 gen_trap(s);
2799 gen_set_label(lab);
21a8eced 2800 return DISAS_NEXT;
782a8479
AJ
2801}
2802
21a8eced 2803static DisasJumpType op_lgat(DisasContext *s, DisasOps *o)
782a8479
AJ
2804{
2805 TCGLabel *lab = gen_new_label();
2806 tcg_gen_qemu_ld64(o->out, o->in2, get_mem_index(s));
2807 /* The value is stored even in case of trap. */
2808 tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab);
2809 gen_trap(s);
2810 gen_set_label(lab);
21a8eced 2811 return DISAS_NEXT;
782a8479
AJ
2812}
2813
21a8eced 2814static DisasJumpType op_lfhat(DisasContext *s, DisasOps *o)
782a8479
AJ
2815{
2816 TCGLabel *lab = gen_new_label();
c30988d1 2817 store_reg32h_i64(get_field(s, r1), o->in2);
782a8479
AJ
2818 /* The value is stored even in case of trap. */
2819 tcg_gen_brcondi_i64(TCG_COND_NE, o->in2, 0, lab);
2820 gen_trap(s);
2821 gen_set_label(lab);
21a8eced 2822 return DISAS_NEXT;
782a8479
AJ
2823}
2824
21a8eced 2825static DisasJumpType op_llgfat(DisasContext *s, DisasOps *o)
782a8479
AJ
2826{
2827 TCGLabel *lab = gen_new_label();
2828 tcg_gen_qemu_ld32u(o->out, o->in2, get_mem_index(s));
2829 /* The value is stored even in case of trap. */
2830 tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab);
2831 gen_trap(s);
2832 gen_set_label(lab);
21a8eced 2833 return DISAS_NEXT;
782a8479
AJ
2834}
2835
21a8eced 2836static DisasJumpType op_llgtat(DisasContext *s, DisasOps *o)
782a8479
AJ
2837{
2838 TCGLabel *lab = gen_new_label();
2839 tcg_gen_andi_i64(o->out, o->in2, 0x7fffffff);
2840 /* The value is stored even in case of trap. */
2841 tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab);
2842 gen_trap(s);
2843 gen_set_label(lab);
21a8eced 2844 return DISAS_NEXT;
782a8479
AJ
2845}
2846
21a8eced 2847static DisasJumpType op_loc(DisasContext *s, DisasOps *o)
632086da
RH
2848{
2849 DisasCompare c;
2850
ea0a1053
DM
2851 if (have_field(s, m3)) {
2852 /* LOAD * ON CONDITION */
2853 disas_jcc(s, &c, get_field(s, m3));
2854 } else {
2855 /* SELECT */
2856 disas_jcc(s, &c, get_field(s, m4));
2857 }
632086da
RH
2858
2859 if (c.is_64) {
2860 tcg_gen_movcond_i64(c.cond, o->out, c.u.s64.a, c.u.s64.b,
2861 o->in2, o->in1);
632086da
RH
2862 } else {
2863 TCGv_i32 t32 = tcg_temp_new_i32();
2864 TCGv_i64 t, z;
2865
2866 tcg_gen_setcond_i32(c.cond, t32, c.u.s32.a, c.u.s32.b);
632086da
RH
2867
2868 t = tcg_temp_new_i64();
2869 tcg_gen_extu_i32_i64(t, t32);
632086da 2870
f1ea739b 2871 z = tcg_constant_i64(0);
632086da 2872 tcg_gen_movcond_i64(TCG_COND_NE, o->out, t, z, o->in2, o->in1);
632086da
RH
2873 }
2874
21a8eced 2875 return DISAS_NEXT;
632086da
RH
2876}
2877
8b5ff571 2878#ifndef CONFIG_USER_ONLY
21a8eced 2879static DisasJumpType op_lctl(DisasContext *s, DisasOps *o)
504488b8 2880{
f1ea739b
RH
2881 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
2882 TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
2883
504488b8 2884 gen_helper_lctl(cpu_env, r1, o->in2, r3);
9dec2388 2885 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
872e1379
RH
2886 s->exit_to_mainloop = true;
2887 return DISAS_TOO_MANY;
504488b8
RH
2888}
2889
21a8eced 2890static DisasJumpType op_lctlg(DisasContext *s, DisasOps *o)
3e398cf9 2891{
f1ea739b
RH
2892 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
2893 TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
2894
3e398cf9 2895 gen_helper_lctlg(cpu_env, r1, o->in2, r3);
9dec2388 2896 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
872e1379
RH
2897 s->exit_to_mainloop = true;
2898 return DISAS_TOO_MANY;
3e398cf9 2899}
1807aaa5 2900
21a8eced 2901static DisasJumpType op_lra(DisasContext *s, DisasOps *o)
d8fe4a9c 2902{
d8fe4a9c
RH
2903 gen_helper_lra(o->out, cpu_env, o->in2);
2904 set_cc_static(s);
21a8eced 2905 return DISAS_NEXT;
d8fe4a9c
RH
2906}
2907
21a8eced 2908static DisasJumpType op_lpp(DisasContext *s, DisasOps *o)
190b2422 2909{
190b2422 2910 tcg_gen_st_i64(o->in2, cpu_env, offsetof(CPUS390XState, pp));
21a8eced 2911 return DISAS_NEXT;
190b2422
MB
2912}
2913
21a8eced 2914static DisasJumpType op_lpsw(DisasContext *s, DisasOps *o)
8b5ff571 2915{
377dc84e 2916 TCGv_i64 mask, addr;
8b5ff571 2917
3da0ab35 2918 per_breaking_event(s);
8b5ff571 2919
377dc84e
IL
2920 /*
2921 * Convert the short PSW into the normal PSW, similar to what
2922 * s390_cpu_load_normal() does.
2923 */
2924 mask = tcg_temp_new_i64();
2925 addr = tcg_temp_new_i64();
2926 tcg_gen_qemu_ld_i64(mask, o->in2, get_mem_index(s), MO_TEUQ | MO_ALIGN_8);
2927 tcg_gen_andi_i64(addr, mask, PSW_MASK_SHORT_ADDR);
2928 tcg_gen_andi_i64(mask, mask, PSW_MASK_SHORT_CTRL);
2929 tcg_gen_xori_i64(mask, mask, PSW_MASK_SHORTPSW);
2930 gen_helper_load_psw(cpu_env, mask, addr);
21a8eced 2931 return DISAS_NORETURN;
8b5ff571 2932}
7ab938d7 2933
21a8eced 2934static DisasJumpType op_lpswe(DisasContext *s, DisasOps *o)
7ab938d7
RH
2935{
2936 TCGv_i64 t1, t2;
2937
3da0ab35 2938 per_breaking_event(s);
7ab938d7
RH
2939
2940 t1 = tcg_temp_new_i64();
2941 t2 = tcg_temp_new_i64();
ae4b5a54 2942 tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s),
fc313c64 2943 MO_TEUQ | MO_ALIGN_8);
7ab938d7
RH
2944 tcg_gen_addi_i64(o->in2, o->in2, 8);
2945 tcg_gen_qemu_ld64(t2, o->in2, get_mem_index(s));
2946 gen_helper_load_psw(cpu_env, t1, t2);
21a8eced 2947 return DISAS_NORETURN;
7ab938d7 2948}
8b5ff571
RH
2949#endif
2950
21a8eced 2951static DisasJumpType op_lam(DisasContext *s, DisasOps *o)
7df3e93a 2952{
f1ea739b
RH
2953 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
2954 TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
2955
7df3e93a 2956 gen_helper_lam(cpu_env, r1, o->in2, r3);
21a8eced 2957 return DISAS_NEXT;
7df3e93a
RH
2958}
2959
21a8eced 2960static DisasJumpType op_lm32(DisasContext *s, DisasOps *o)
77f8d6c3 2961{
c30988d1
RH
2962 int r1 = get_field(s, r1);
2963 int r3 = get_field(s, r3);
aa752a4a 2964 TCGv_i64 t1, t2;
77f8d6c3 2965
aa752a4a
AJ
2966 /* Only one register to read. */
2967 t1 = tcg_temp_new_i64();
2968 if (unlikely(r1 == r3)) {
2969 tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
2970 store_reg32_i64(r1, t1);
21a8eced 2971 return DISAS_NEXT;
aa752a4a
AJ
2972 }
2973
2974 /* First load the values of the first and last registers to trigger
2975 possible page faults. */
2976 t2 = tcg_temp_new_i64();
2977 tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
2978 tcg_gen_addi_i64(t2, o->in2, 4 * ((r3 - r1) & 15));
2979 tcg_gen_qemu_ld32u(t2, t2, get_mem_index(s));
2980 store_reg32_i64(r1, t1);
2981 store_reg32_i64(r3, t2);
2982
2983 /* Only two registers to read. */
2984 if (((r1 + 1) & 15) == r3) {
21a8eced 2985 return DISAS_NEXT;
aa752a4a
AJ
2986 }
2987
2988 /* Then load the remaining registers. Page fault can't occur. */
2989 r3 = (r3 - 1) & 15;
2990 tcg_gen_movi_i64(t2, 4);
2991 while (r1 != r3) {
77f8d6c3 2992 r1 = (r1 + 1) & 15;
aa752a4a
AJ
2993 tcg_gen_add_i64(o->in2, o->in2, t2);
2994 tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
2995 store_reg32_i64(r1, t1);
77f8d6c3 2996 }
21a8eced 2997 return DISAS_NEXT;
77f8d6c3
RH
2998}
2999
21a8eced 3000static DisasJumpType op_lmh(DisasContext *s, DisasOps *o)
77f8d6c3 3001{
c30988d1
RH
3002 int r1 = get_field(s, r1);
3003 int r3 = get_field(s, r3);
aa752a4a 3004 TCGv_i64 t1, t2;
77f8d6c3 3005
aa752a4a
AJ
3006 /* Only one register to read. */
3007 t1 = tcg_temp_new_i64();
3008 if (unlikely(r1 == r3)) {
3009 tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
3010 store_reg32h_i64(r1, t1);
21a8eced 3011 return DISAS_NEXT;
aa752a4a
AJ
3012 }
3013
3014 /* First load the values of the first and last registers to trigger
3015 possible page faults. */
3016 t2 = tcg_temp_new_i64();
3017 tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
3018 tcg_gen_addi_i64(t2, o->in2, 4 * ((r3 - r1) & 15));
3019 tcg_gen_qemu_ld32u(t2, t2, get_mem_index(s));
3020 store_reg32h_i64(r1, t1);
3021 store_reg32h_i64(r3, t2);
3022
3023 /* Only two registers to read. */
3024 if (((r1 + 1) & 15) == r3) {
21a8eced 3025 return DISAS_NEXT;
aa752a4a
AJ
3026 }
3027
3028 /* Then load the remaining registers. Page fault can't occur. */
3029 r3 = (r3 - 1) & 15;
3030 tcg_gen_movi_i64(t2, 4);
3031 while (r1 != r3) {
77f8d6c3 3032 r1 = (r1 + 1) & 15;
aa752a4a
AJ
3033 tcg_gen_add_i64(o->in2, o->in2, t2);
3034 tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
3035 store_reg32h_i64(r1, t1);
77f8d6c3 3036 }
21a8eced 3037 return DISAS_NEXT;
77f8d6c3
RH
3038}
3039
21a8eced 3040static DisasJumpType op_lm64(DisasContext *s, DisasOps *o)
77f8d6c3 3041{
c30988d1
RH
3042 int r1 = get_field(s, r1);
3043 int r3 = get_field(s, r3);
aa752a4a 3044 TCGv_i64 t1, t2;
77f8d6c3 3045
aa752a4a
AJ
3046 /* Only one register to read. */
3047 if (unlikely(r1 == r3)) {
77f8d6c3 3048 tcg_gen_qemu_ld64(regs[r1], o->in2, get_mem_index(s));
21a8eced 3049 return DISAS_NEXT;
aa752a4a
AJ
3050 }
3051
3052 /* First load the values of the first and last registers to trigger
3053 possible page faults. */
3054 t1 = tcg_temp_new_i64();
3055 t2 = tcg_temp_new_i64();
3056 tcg_gen_qemu_ld64(t1, o->in2, get_mem_index(s));
3057 tcg_gen_addi_i64(t2, o->in2, 8 * ((r3 - r1) & 15));
3058 tcg_gen_qemu_ld64(regs[r3], t2, get_mem_index(s));
3059 tcg_gen_mov_i64(regs[r1], t1);
aa752a4a
AJ
3060
3061 /* Only two registers to read. */
3062 if (((r1 + 1) & 15) == r3) {
21a8eced 3063 return DISAS_NEXT;
aa752a4a
AJ
3064 }
3065
3066 /* Then load the remaining registers. Page fault can't occur. */
3067 r3 = (r3 - 1) & 15;
3068 tcg_gen_movi_i64(t1, 8);
3069 while (r1 != r3) {
77f8d6c3 3070 r1 = (r1 + 1) & 15;
aa752a4a
AJ
3071 tcg_gen_add_i64(o->in2, o->in2, t1);
3072 tcg_gen_qemu_ld64(regs[r1], o->in2, get_mem_index(s));
77f8d6c3 3073 }
21a8eced 3074 return DISAS_NEXT;
77f8d6c3
RH
3075}
3076
21a8eced 3077static DisasJumpType op_lpd(DisasContext *s, DisasOps *o)
1807aaa5
EB
3078{
3079 TCGv_i64 a1, a2;
14776ab5 3080 MemOp mop = s->insn->data;
1807aaa5
EB
3081
3082 /* In a parallel context, stop the world and single step. */
eccf741a 3083 if (tb_cflags(s->base.tb) & CF_PARALLEL) {
cb3129c3
DH
3084 update_psw_addr(s);
3085 update_cc_op(s);
1807aaa5 3086 gen_exception(EXCP_ATOMIC);
21a8eced 3087 return DISAS_NORETURN;
1807aaa5
EB
3088 }
3089
3090 /* In a serial context, perform the two loads ... */
c30988d1
RH
3091 a1 = get_address(s, 0, get_field(s, b1), get_field(s, d1));
3092 a2 = get_address(s, 0, get_field(s, b2), get_field(s, d2));
1807aaa5
EB
3093 tcg_gen_qemu_ld_i64(o->out, a1, get_mem_index(s), mop | MO_ALIGN);
3094 tcg_gen_qemu_ld_i64(o->out2, a2, get_mem_index(s), mop | MO_ALIGN);
1807aaa5
EB
3095
3096 /* ... and indicate that we performed them while interlocked. */
3097 gen_op_movi_cc(s, 0);
21a8eced 3098 return DISAS_NEXT;
1807aaa5
EB
3099}
3100
21a8eced 3101static DisasJumpType op_lpq(DisasContext *s, DisasOps *o)
e22dfdb2 3102{
830bf10c
RH
3103 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
3104 gen_helper_lpq(o->out, cpu_env, o->in2);
3105 } else if (HAVE_ATOMIC128) {
6476615d
EC
3106 gen_helper_lpq_parallel(o->out, cpu_env, o->in2);
3107 } else {
830bf10c
RH
3108 gen_helper_exit_atomic(cpu_env);
3109 return DISAS_NORETURN;
6476615d 3110 }
e22dfdb2 3111 return_low128(o->out2);
21a8eced 3112 return DISAS_NEXT;
e22dfdb2
AJ
3113}
3114
9c3fd85b 3115#ifndef CONFIG_USER_ONLY
21a8eced 3116static DisasJumpType op_lura(DisasContext *s, DisasOps *o)
9c3fd85b 3117{
401bf467 3118 tcg_gen_qemu_ld_tl(o->out, o->in2, MMU_REAL_IDX, s->insn->data);
21a8eced 3119 return DISAS_NEXT;
9c3fd85b
RH
3120}
3121#endif
3122
21a8eced 3123static DisasJumpType op_lzrb(DisasContext *s, DisasOps *o)
c2a5c1d7
RH
3124{
3125 tcg_gen_andi_i64(o->out, o->in2, -256);
21a8eced 3126 return DISAS_NEXT;
c2a5c1d7
RH
3127}
3128
6d930332
DH
3129static DisasJumpType op_lcbb(DisasContext *s, DisasOps *o)
3130{
c30988d1 3131 const int64_t block_size = (1ull << (get_field(s, m3) + 6));
6d930332 3132
c30988d1 3133 if (get_field(s, m3) > 6) {
6d930332
DH
3134 gen_program_exception(s, PGM_SPECIFICATION);
3135 return DISAS_NORETURN;
3136 }
3137
3138 tcg_gen_ori_i64(o->addr1, o->addr1, -block_size);
3139 tcg_gen_neg_i64(o->addr1, o->addr1);
3140 tcg_gen_movi_i64(o->out, 16);
3141 tcg_gen_umin_i64(o->out, o->out, o->addr1);
3142 gen_op_update1_cc_i64(s, CC_OP_LCBB, o->out);
3143 return DISAS_NEXT;
3144}
3145
20d143e2
DH
3146static DisasJumpType op_mc(DisasContext *s, DisasOps *o)
3147{
20d143e2
DH
3148 const uint16_t monitor_class = get_field(s, i2);
3149
3150 if (monitor_class & 0xff00) {
3151 gen_program_exception(s, PGM_SPECIFICATION);
3152 return DISAS_NORETURN;
3153 }
3154
3155#if !defined(CONFIG_USER_ONLY)
f1ea739b
RH
3156 gen_helper_monitor_call(cpu_env, o->addr1,
3157 tcg_constant_i32(monitor_class));
20d143e2
DH
3158#endif
3159 /* Defaults to a NOP. */
3160 return DISAS_NEXT;
3161}
3162
21a8eced 3163static DisasJumpType op_mov2(DisasContext *s, DisasOps *o)
22c37a08
RH
3164{
3165 o->out = o->in2;
f764718d 3166 o->in2 = NULL;
21a8eced 3167 return DISAS_NEXT;
22c37a08
RH
3168}
3169
21a8eced 3170static DisasJumpType op_mov2e(DisasContext *s, DisasOps *o)
a1c7610a 3171{
c30988d1 3172 int b2 = get_field(s, b2);
a1c7610a
AJ
3173 TCGv ar1 = tcg_temp_new_i64();
3174
3175 o->out = o->in2;
f764718d 3176 o->in2 = NULL;
a1c7610a 3177
eccf741a 3178 switch (s->base.tb->flags & FLAG_MASK_ASC) {
159fed45 3179 case PSW_ASC_PRIMARY >> FLAG_MASK_PSW_SHIFT:
a1c7610a
AJ
3180 tcg_gen_movi_i64(ar1, 0);
3181 break;
159fed45 3182 case PSW_ASC_ACCREG >> FLAG_MASK_PSW_SHIFT:
a1c7610a
AJ
3183 tcg_gen_movi_i64(ar1, 1);
3184 break;
159fed45 3185 case PSW_ASC_SECONDARY >> FLAG_MASK_PSW_SHIFT:
a1c7610a
AJ
3186 if (b2) {
3187 tcg_gen_ld32u_i64(ar1, cpu_env, offsetof(CPUS390XState, aregs[b2]));
3188 } else {
3189 tcg_gen_movi_i64(ar1, 0);
3190 }
3191 break;
159fed45 3192 case PSW_ASC_HOME >> FLAG_MASK_PSW_SHIFT:
a1c7610a
AJ
3193 tcg_gen_movi_i64(ar1, 2);
3194 break;
3195 }
3196
3197 tcg_gen_st32_i64(ar1, cpu_env, offsetof(CPUS390XState, aregs[1]));
21a8eced 3198 return DISAS_NEXT;
a1c7610a
AJ
3199}
3200
21a8eced 3201static DisasJumpType op_movx(DisasContext *s, DisasOps *o)
d764a8d1
RH
3202{
3203 o->out = o->in1;
3204 o->out2 = o->in2;
f764718d
RH
3205 o->in1 = NULL;
3206 o->in2 = NULL;
21a8eced 3207 return DISAS_NEXT;
d764a8d1
RH
3208}
3209
21a8eced 3210static DisasJumpType op_mvc(DisasContext *s, DisasOps *o)
af9e5a04 3211{
f1ea739b
RH
3212 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3213
af9e5a04 3214 gen_helper_mvc(cpu_env, l, o->addr1, o->in2);
21a8eced 3215 return DISAS_NEXT;
af9e5a04
RH
3216}
3217
ea0a1053
DM
3218static DisasJumpType op_mvcrl(DisasContext *s, DisasOps *o)
3219{
3220 gen_helper_mvcrl(cpu_env, regs[0], o->addr1, o->in2);
3221 return DISAS_NEXT;
3222}
3223
21a8eced 3224static DisasJumpType op_mvcin(DisasContext *s, DisasOps *o)
6c9deca8 3225{
f1ea739b
RH
3226 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3227
6c9deca8 3228 gen_helper_mvcin(cpu_env, l, o->addr1, o->in2);
21a8eced 3229 return DISAS_NEXT;
6c9deca8
AJ
3230}
3231
21a8eced 3232static DisasJumpType op_mvcl(DisasContext *s, DisasOps *o)
e1eaada9 3233{
c30988d1
RH
3234 int r1 = get_field(s, r1);
3235 int r2 = get_field(s, r2);
d3327121
AJ
3236 TCGv_i32 t1, t2;
3237
3238 /* r1 and r2 must be even. */
3239 if (r1 & 1 || r2 & 1) {
3240 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 3241 return DISAS_NORETURN;
d3327121
AJ
3242 }
3243
f1ea739b
RH
3244 t1 = tcg_constant_i32(r1);
3245 t2 = tcg_constant_i32(r2);
d3327121 3246 gen_helper_mvcl(cc_op, cpu_env, t1, t2);
e1eaada9 3247 set_cc_static(s);
21a8eced 3248 return DISAS_NEXT;
e1eaada9
RH
3249}
3250
21a8eced 3251static DisasJumpType op_mvcle(DisasContext *s, DisasOps *o)
eb66e6a9 3252{
c30988d1
RH
3253 int r1 = get_field(s, r1);
3254 int r3 = get_field(s, r3);
d3327121
AJ
3255 TCGv_i32 t1, t3;
3256
3257 /* r1 and r3 must be even. */
3258 if (r1 & 1 || r3 & 1) {
3259 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 3260 return DISAS_NORETURN;
d3327121
AJ
3261 }
3262
f1ea739b
RH
3263 t1 = tcg_constant_i32(r1);
3264 t3 = tcg_constant_i32(r3);
d3327121 3265 gen_helper_mvcle(cc_op, cpu_env, t1, o->in2, t3);
eb66e6a9 3266 set_cc_static(s);
21a8eced 3267 return DISAS_NEXT;
eb66e6a9
RH
3268}
3269
21a8eced 3270static DisasJumpType op_mvclu(DisasContext *s, DisasOps *o)
16f2e4b8 3271{
c30988d1
RH
3272 int r1 = get_field(s, r1);
3273 int r3 = get_field(s, r3);
16f2e4b8
AJ
3274 TCGv_i32 t1, t3;
3275
3276 /* r1 and r3 must be even. */
3277 if (r1 & 1 || r3 & 1) {
3278 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 3279 return DISAS_NORETURN;
16f2e4b8
AJ
3280 }
3281
f1ea739b
RH
3282 t1 = tcg_constant_i32(r1);
3283 t3 = tcg_constant_i32(r3);
16f2e4b8 3284 gen_helper_mvclu(cc_op, cpu_env, t1, o->in2, t3);
16f2e4b8 3285 set_cc_static(s);
21a8eced 3286 return DISAS_NEXT;
16f2e4b8
AJ
3287}
3288
21a8eced 3289static DisasJumpType op_mvcos(DisasContext *s, DisasOps *o)
3e7e5e0b 3290{
c30988d1 3291 int r3 = get_field(s, r3);
3e7e5e0b
DH
3292 gen_helper_mvcos(cc_op, cpu_env, o->addr1, o->in2, regs[r3]);
3293 set_cc_static(s);
21a8eced 3294 return DISAS_NEXT;
3e7e5e0b
DH
3295}
3296
97c3ab61 3297#ifndef CONFIG_USER_ONLY
21a8eced 3298static DisasJumpType op_mvcp(DisasContext *s, DisasOps *o)
97c3ab61 3299{
c30988d1 3300 int r1 = get_field(s, l1);
3ef473e5
TH
3301 int r3 = get_field(s, r3);
3302 gen_helper_mvcp(cc_op, cpu_env, regs[r1], o->addr1, o->in2, regs[r3]);
97c3ab61 3303 set_cc_static(s);
21a8eced 3304 return DISAS_NEXT;
97c3ab61
RH
3305}
3306
21a8eced 3307static DisasJumpType op_mvcs(DisasContext *s, DisasOps *o)
97c3ab61 3308{
c30988d1 3309 int r1 = get_field(s, l1);
3ef473e5
TH
3310 int r3 = get_field(s, r3);
3311 gen_helper_mvcs(cc_op, cpu_env, regs[r1], o->addr1, o->in2, regs[r3]);
97c3ab61 3312 set_cc_static(s);
21a8eced 3313 return DISAS_NEXT;
97c3ab61
RH
3314}
3315#endif
3316
21a8eced 3317static DisasJumpType op_mvn(DisasContext *s, DisasOps *o)
256dab6f 3318{
f1ea739b
RH
3319 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3320
256dab6f 3321 gen_helper_mvn(cpu_env, l, o->addr1, o->in2);
21a8eced 3322 return DISAS_NEXT;
256dab6f
AJ
3323}
3324
21a8eced 3325static DisasJumpType op_mvo(DisasContext *s, DisasOps *o)
fdc0a747 3326{
f1ea739b
RH
3327 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3328
fdc0a747 3329 gen_helper_mvo(cpu_env, l, o->addr1, o->in2);
21a8eced 3330 return DISAS_NEXT;
fdc0a747
AJ
3331}
3332
21a8eced 3333static DisasJumpType op_mvpg(DisasContext *s, DisasOps *o)
ee6c38d5 3334{
f1ea739b
RH
3335 TCGv_i32 t1 = tcg_constant_i32(get_field(s, r1));
3336 TCGv_i32 t2 = tcg_constant_i32(get_field(s, r2));
1a3c443c
DH
3337
3338 gen_helper_mvpg(cc_op, cpu_env, regs[0], t1, t2);
ee6c38d5 3339 set_cc_static(s);
21a8eced 3340 return DISAS_NEXT;
ee6c38d5
RH
3341}
3342
21a8eced 3343static DisasJumpType op_mvst(DisasContext *s, DisasOps *o)
aa31bf60 3344{
f1ea739b
RH
3345 TCGv_i32 t1 = tcg_constant_i32(get_field(s, r1));
3346 TCGv_i32 t2 = tcg_constant_i32(get_field(s, r2));
2bb525e2
DH
3347
3348 gen_helper_mvst(cc_op, cpu_env, t1, t2);
aa31bf60 3349 set_cc_static(s);
21a8eced 3350 return DISAS_NEXT;
aa31bf60
RH
3351}
3352
21a8eced 3353static DisasJumpType op_mvz(DisasContext *s, DisasOps *o)
01f8db88 3354{
f1ea739b
RH
3355 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3356
01f8db88 3357 gen_helper_mvz(cpu_env, l, o->addr1, o->in2);
21a8eced 3358 return DISAS_NEXT;
01f8db88
AJ
3359}
3360
21a8eced 3361static DisasJumpType op_mul(DisasContext *s, DisasOps *o)
d1c04a2b
RH
3362{
3363 tcg_gen_mul_i64(o->out, o->in1, o->in2);
21a8eced 3364 return DISAS_NEXT;
d1c04a2b
RH
3365}
3366
21a8eced 3367static DisasJumpType op_mul128(DisasContext *s, DisasOps *o)
1ac5889f 3368{
dc46d1c6 3369 tcg_gen_mulu2_i64(o->out2, o->out, o->in1, o->in2);
21a8eced 3370 return DISAS_NEXT;
1ac5889f
RH
3371}
3372
fa5e82cc
DH
3373static DisasJumpType op_muls128(DisasContext *s, DisasOps *o)
3374{
3375 tcg_gen_muls2_i64(o->out2, o->out, o->in1, o->in2);
3376 return DISAS_NEXT;
3377}
3378
21a8eced 3379static DisasJumpType op_meeb(DisasContext *s, DisasOps *o)
83b00736
RH
3380{
3381 gen_helper_meeb(o->out, cpu_env, o->in1, o->in2);
21a8eced 3382 return DISAS_NEXT;
83b00736
RH
3383}
3384
21a8eced 3385static DisasJumpType op_mdeb(DisasContext *s, DisasOps *o)
83b00736
RH
3386{
3387 gen_helper_mdeb(o->out, cpu_env, o->in1, o->in2);
21a8eced 3388 return DISAS_NEXT;
83b00736
RH
3389}
3390
21a8eced 3391static DisasJumpType op_mdb(DisasContext *s, DisasOps *o)
83b00736
RH
3392{
3393 gen_helper_mdb(o->out, cpu_env, o->in1, o->in2);
21a8eced 3394 return DISAS_NEXT;
83b00736
RH
3395}
3396
21a8eced 3397static DisasJumpType op_mxb(DisasContext *s, DisasOps *o)
83b00736 3398{
2b91240f 3399 gen_helper_mxb(o->out_128, cpu_env, o->in1_128, o->in2_128);
21a8eced 3400 return DISAS_NEXT;
83b00736
RH
3401}
3402
21a8eced 3403static DisasJumpType op_mxdb(DisasContext *s, DisasOps *o)
83b00736 3404{
2b91240f 3405 gen_helper_mxdb(o->out_128, cpu_env, o->in1_128, o->in2);
21a8eced 3406 return DISAS_NEXT;
83b00736
RH
3407}
3408
21a8eced 3409static DisasJumpType op_maeb(DisasContext *s, DisasOps *o)
722bfec3 3410{
c30988d1 3411 TCGv_i64 r3 = load_freg32_i64(get_field(s, r3));
722bfec3 3412 gen_helper_maeb(o->out, cpu_env, o->in1, o->in2, r3);
21a8eced 3413 return DISAS_NEXT;
722bfec3
RH
3414}
3415
21a8eced 3416static DisasJumpType op_madb(DisasContext *s, DisasOps *o)
722bfec3 3417{
c30988d1 3418 TCGv_i64 r3 = load_freg(get_field(s, r3));
80a7b759 3419 gen_helper_madb(o->out, cpu_env, o->in1, o->in2, r3);
21a8eced 3420 return DISAS_NEXT;
722bfec3
RH
3421}
3422
21a8eced 3423static DisasJumpType op_mseb(DisasContext *s, DisasOps *o)
722bfec3 3424{
c30988d1 3425 TCGv_i64 r3 = load_freg32_i64(get_field(s, r3));
722bfec3 3426 gen_helper_mseb(o->out, cpu_env, o->in1, o->in2, r3);
21a8eced 3427 return DISAS_NEXT;
722bfec3
RH
3428}
3429
21a8eced 3430static DisasJumpType op_msdb(DisasContext *s, DisasOps *o)
722bfec3 3431{
c30988d1 3432 TCGv_i64 r3 = load_freg(get_field(s, r3));
80a7b759 3433 gen_helper_msdb(o->out, cpu_env, o->in1, o->in2, r3);
21a8eced 3434 return DISAS_NEXT;
722bfec3
RH
3435}
3436
21a8eced 3437static DisasJumpType op_nabs(DisasContext *s, DisasOps *o)
b9bca3e5 3438{
f1ea739b
RH
3439 TCGv_i64 z = tcg_constant_i64(0);
3440 TCGv_i64 n = tcg_temp_new_i64();
3441
d3010781
AJ
3442 tcg_gen_neg_i64(n, o->in2);
3443 tcg_gen_movcond_i64(TCG_COND_GE, o->out, o->in2, z, n, o->in2);
21a8eced 3444 return DISAS_NEXT;
b9bca3e5
RH
3445}
3446
21a8eced 3447static DisasJumpType op_nabsf32(DisasContext *s, DisasOps *o)
5d7fd045
RH
3448{
3449 tcg_gen_ori_i64(o->out, o->in2, 0x80000000ull);
21a8eced 3450 return DISAS_NEXT;
5d7fd045
RH
3451}
3452
21a8eced 3453static DisasJumpType op_nabsf64(DisasContext *s, DisasOps *o)
5d7fd045
RH
3454{
3455 tcg_gen_ori_i64(o->out, o->in2, 0x8000000000000000ull);
21a8eced 3456 return DISAS_NEXT;
5d7fd045
RH
3457}
3458
21a8eced 3459static DisasJumpType op_nabsf128(DisasContext *s, DisasOps *o)
5d7fd045
RH
3460{
3461 tcg_gen_ori_i64(o->out, o->in1, 0x8000000000000000ull);
3462 tcg_gen_mov_i64(o->out2, o->in2);
21a8eced 3463 return DISAS_NEXT;
5d7fd045
RH
3464}
3465
21a8eced 3466static DisasJumpType op_nc(DisasContext *s, DisasOps *o)
0a949039 3467{
f1ea739b
RH
3468 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3469
0a949039 3470 gen_helper_nc(cc_op, cpu_env, l, o->addr1, o->in2);
0a949039 3471 set_cc_static(s);
21a8eced 3472 return DISAS_NEXT;
0a949039
RH
3473}
3474
21a8eced 3475static DisasJumpType op_neg(DisasContext *s, DisasOps *o)
b9bca3e5
RH
3476{
3477 tcg_gen_neg_i64(o->out, o->in2);
21a8eced 3478 return DISAS_NEXT;
b9bca3e5
RH
3479}
3480
21a8eced 3481static DisasJumpType op_negf32(DisasContext *s, DisasOps *o)
5d7fd045
RH
3482{
3483 tcg_gen_xori_i64(o->out, o->in2, 0x80000000ull);
21a8eced 3484 return DISAS_NEXT;
5d7fd045
RH
3485}
3486
21a8eced 3487static DisasJumpType op_negf64(DisasContext *s, DisasOps *o)
5d7fd045
RH
3488{
3489 tcg_gen_xori_i64(o->out, o->in2, 0x8000000000000000ull);
21a8eced 3490 return DISAS_NEXT;
5d7fd045
RH
3491}
3492
21a8eced 3493static DisasJumpType op_negf128(DisasContext *s, DisasOps *o)
5d7fd045
RH
3494{
3495 tcg_gen_xori_i64(o->out, o->in1, 0x8000000000000000ull);
3496 tcg_gen_mov_i64(o->out2, o->in2);
21a8eced 3497 return DISAS_NEXT;
5d7fd045
RH
3498}
3499
21a8eced 3500static DisasJumpType op_oc(DisasContext *s, DisasOps *o)
0a949039 3501{
f1ea739b
RH
3502 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3503
0a949039 3504 gen_helper_oc(cc_op, cpu_env, l, o->addr1, o->in2);
0a949039 3505 set_cc_static(s);
21a8eced 3506 return DISAS_NEXT;
0a949039
RH
3507}
3508
21a8eced 3509static DisasJumpType op_or(DisasContext *s, DisasOps *o)
3bbfbd1f
RH
3510{
3511 tcg_gen_or_i64(o->out, o->in1, o->in2);
21a8eced 3512 return DISAS_NEXT;
3bbfbd1f
RH
3513}
3514
21a8eced 3515static DisasJumpType op_ori(DisasContext *s, DisasOps *o)
facfc864
RH
3516{
3517 int shift = s->insn->data & 0xff;
3518 int size = s->insn->data >> 8;
3519 uint64_t mask = ((1ull << size) - 1) << shift;
ab9984bd 3520 TCGv_i64 t = tcg_temp_new_i64();
facfc864 3521
ab9984bd
RH
3522 tcg_gen_shli_i64(t, o->in2, shift);
3523 tcg_gen_or_i64(o->out, o->in1, t);
facfc864
RH
3524
3525 /* Produce the CC from only the bits manipulated. */
3526 tcg_gen_andi_i64(cc_dst, o->out, mask);
3527 set_cc_nz_u64(s, cc_dst);
21a8eced 3528 return DISAS_NEXT;
facfc864
RH
3529}
3530
21a8eced 3531static DisasJumpType op_oi(DisasContext *s, DisasOps *o)
f400be18
DH
3532{
3533 o->in1 = tcg_temp_new_i64();
3534
3535 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
3536 tcg_gen_qemu_ld_tl(o->in1, o->addr1, get_mem_index(s), s->insn->data);
3537 } else {
3538 /* Perform the atomic operation in memory. */
3539 tcg_gen_atomic_fetch_or_i64(o->in1, o->addr1, o->in2, get_mem_index(s),
3540 s->insn->data);
3541 }
3542
3543 /* Recompute also for atomic case: needed for setting CC. */
3544 tcg_gen_or_i64(o->out, o->in1, o->in2);
3545
3546 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
3547 tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), s->insn->data);
3548 }
21a8eced 3549 return DISAS_NEXT;
f400be18
DH
3550}
3551
21a8eced 3552static DisasJumpType op_pack(DisasContext *s, DisasOps *o)
76c57490 3553{
f1ea739b
RH
3554 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3555
76c57490 3556 gen_helper_pack(cpu_env, l, o->addr1, o->in2);
21a8eced 3557 return DISAS_NEXT;
76c57490
AJ
3558}
3559
21a8eced 3560static DisasJumpType op_pka(DisasContext *s, DisasOps *o)
3bd3d6d3 3561{
c30988d1 3562 int l2 = get_field(s, l2) + 1;
3bd3d6d3
AJ
3563 TCGv_i32 l;
3564
3565 /* The length must not exceed 32 bytes. */
3566 if (l2 > 32) {
3567 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 3568 return DISAS_NORETURN;
3bd3d6d3 3569 }
f1ea739b 3570 l = tcg_constant_i32(l2);
3bd3d6d3 3571 gen_helper_pka(cpu_env, o->addr1, o->in2, l);
21a8eced 3572 return DISAS_NEXT;
3bd3d6d3
AJ
3573}
3574
21a8eced 3575static DisasJumpType op_pku(DisasContext *s, DisasOps *o)
4e256bef 3576{
c30988d1 3577 int l2 = get_field(s, l2) + 1;
4e256bef
AJ
3578 TCGv_i32 l;
3579
3580 /* The length must be even and should not exceed 64 bytes. */
3581 if ((l2 & 1) || (l2 > 64)) {
3582 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 3583 return DISAS_NORETURN;
4e256bef 3584 }
f1ea739b 3585 l = tcg_constant_i32(l2);
4e256bef 3586 gen_helper_pku(cpu_env, o->addr1, o->in2, l);
21a8eced 3587 return DISAS_NEXT;
4e256bef
AJ
3588}
3589
21a8eced 3590static DisasJumpType op_popcnt(DisasContext *s, DisasOps *o)
99b4f24b 3591{
ea0a1053
DM
3592 const uint8_t m3 = get_field(s, m3);
3593
3594 if ((m3 & 8) && s390_has_feat(S390_FEAT_MISC_INSTRUCTION_EXT3)) {
3595 tcg_gen_ctpop_i64(o->out, o->in2);
3596 } else {
3597 gen_helper_popcnt(o->out, o->in2);
3598 }
21a8eced 3599 return DISAS_NEXT;
99b4f24b
RH
3600}
3601
0568d8aa 3602#ifndef CONFIG_USER_ONLY
21a8eced 3603static DisasJumpType op_ptlb(DisasContext *s, DisasOps *o)
0568d8aa 3604{
0568d8aa 3605 gen_helper_ptlb(cpu_env);
21a8eced 3606 return DISAS_NEXT;
0568d8aa
RH
3607}
3608#endif
3609
21a8eced 3610static DisasJumpType op_risbg(DisasContext *s, DisasOps *o)
2d6a8698 3611{
c30988d1
RH
3612 int i3 = get_field(s, i3);
3613 int i4 = get_field(s, i4);
3614 int i5 = get_field(s, i5);
2d6a8698
RH
3615 int do_zero = i4 & 0x80;
3616 uint64_t mask, imask, pmask;
3617 int pos, len, rot;
3618
3619 /* Adjust the arguments for the specific insn. */
344a7f65 3620 switch (s->fields.op2) {
2d6a8698 3621 case 0x55: /* risbg */
fdaae351 3622 case 0x59: /* risbgn */
2d6a8698
RH
3623 i3 &= 63;
3624 i4 &= 63;
3625 pmask = ~0;
3626 break;
3627 case 0x5d: /* risbhg */
3628 i3 &= 31;
3629 i4 &= 31;
3630 pmask = 0xffffffff00000000ull;
3631 break;
3632 case 0x51: /* risblg */
c2390830
DH
3633 i3 = (i3 & 31) + 32;
3634 i4 = (i4 & 31) + 32;
2d6a8698
RH
3635 pmask = 0x00000000ffffffffull;
3636 break;
3637 default:
fdaae351 3638 g_assert_not_reached();
2d6a8698
RH
3639 }
3640
c2390830 3641 /* MASK is the set of bits to be inserted from R2. */
2d6a8698 3642 if (i3 <= i4) {
c2390830
DH
3643 /* [0...i3---i4...63] */
3644 mask = (-1ull >> i3) & (-1ull << (63 - i4));
2d6a8698 3645 } else {
c2390830
DH
3646 /* [0---i4...i3---63] */
3647 mask = (-1ull >> i3) | (-1ull << (63 - i4));
2d6a8698 3648 }
c2390830 3649 /* For RISBLG/RISBHG, the wrapping is limited to the high/low doubleword. */
2d6a8698
RH
3650 mask &= pmask;
3651
3652 /* IMASK is the set of bits to be kept from R1. In the case of the high/low
3653 insns, we need to keep the other half of the register. */
3654 imask = ~mask | ~pmask;
3655 if (do_zero) {
fdaae351 3656 imask = ~pmask;
2d6a8698
RH
3657 }
3658
f6156b8f
RH
3659 len = i4 - i3 + 1;
3660 pos = 63 - i4;
3661 rot = i5 & 63;
f6156b8f
RH
3662
3663 /* In some cases we can implement this with extract. */
dbdaaff4
RH
3664 if (imask == 0 && pos == 0 && len > 0 && len <= rot) {
3665 tcg_gen_extract_i64(o->out, o->in2, 64 - rot, len);
21a8eced 3666 return DISAS_NEXT;
f6156b8f
RH
3667 }
3668
3669 /* In some cases we can implement this with deposit. */
3670 if (len > 0 && (imask == 0 || ~mask == imask)) {
2d6a8698
RH
3671 /* Note that we rotate the bits to be inserted to the lsb, not to
3672 the position as described in the PoO. */
f6156b8f 3673 rot = (rot - pos) & 63;
2d6a8698 3674 } else {
f6156b8f 3675 pos = -1;
2d6a8698
RH
3676 }
3677
3678 /* Rotate the input as necessary. */
3679 tcg_gen_rotli_i64(o->in2, o->in2, rot);
3680
3681 /* Insert the selected bits into the output. */
3682 if (pos >= 0) {
f6156b8f
RH
3683 if (imask == 0) {
3684 tcg_gen_deposit_z_i64(o->out, o->in2, pos, len);
3685 } else {
3686 tcg_gen_deposit_i64(o->out, o->out, o->in2, pos, len);
3687 }
2d6a8698
RH
3688 } else if (imask == 0) {
3689 tcg_gen_andi_i64(o->out, o->in2, mask);
3690 } else {
3691 tcg_gen_andi_i64(o->in2, o->in2, mask);
3692 tcg_gen_andi_i64(o->out, o->out, imask);
3693 tcg_gen_or_i64(o->out, o->out, o->in2);
3694 }
21a8eced 3695 return DISAS_NEXT;
d6c6372e
RH
3696}
3697
21a8eced 3698static DisasJumpType op_rosbg(DisasContext *s, DisasOps *o)
d6c6372e 3699{
c30988d1
RH
3700 int i3 = get_field(s, i3);
3701 int i4 = get_field(s, i4);
3702 int i5 = get_field(s, i5);
9701596d 3703 TCGv_i64 orig_out;
d6c6372e
RH
3704 uint64_t mask;
3705
3706 /* If this is a test-only form, arrange to discard the result. */
3707 if (i3 & 0x80) {
9701596d
IL
3708 tcg_debug_assert(o->out != NULL);
3709 orig_out = o->out;
d6c6372e 3710 o->out = tcg_temp_new_i64();
9701596d 3711 tcg_gen_mov_i64(o->out, orig_out);
d6c6372e
RH
3712 }
3713
3714 i3 &= 63;
3715 i4 &= 63;
3716 i5 &= 63;
3717
3718 /* MASK is the set of bits to be operated on from R2.
3719 Take care for I3/I4 wraparound. */
3720 mask = ~0ull >> i3;
3721 if (i3 <= i4) {
3722 mask ^= ~0ull >> i4 >> 1;
3723 } else {
3724 mask |= ~(~0ull >> i4 >> 1);
3725 }
3726
3727 /* Rotate the input as necessary. */
3728 tcg_gen_rotli_i64(o->in2, o->in2, i5);
3729
3730 /* Operate. */
344a7f65 3731 switch (s->fields.op2) {
0bab189c 3732 case 0x54: /* AND */
d6c6372e
RH
3733 tcg_gen_ori_i64(o->in2, o->in2, ~mask);
3734 tcg_gen_and_i64(o->out, o->out, o->in2);
3735 break;
3736 case 0x56: /* OR */
3737 tcg_gen_andi_i64(o->in2, o->in2, mask);
3738 tcg_gen_or_i64(o->out, o->out, o->in2);
3739 break;
3740 case 0x57: /* XOR */
3741 tcg_gen_andi_i64(o->in2, o->in2, mask);
3742 tcg_gen_xor_i64(o->out, o->out, o->in2);
3743 break;
3744 default:
3745 abort();
3746 }
3747
3748 /* Set the CC. */
3749 tcg_gen_andi_i64(cc_dst, o->out, mask);
3750 set_cc_nz_u64(s, cc_dst);
21a8eced 3751 return DISAS_NEXT;
2d6a8698
RH
3752}
3753
21a8eced 3754static DisasJumpType op_rev16(DisasContext *s, DisasOps *o)
d54f5865 3755{
2b836c2a 3756 tcg_gen_bswap16_i64(o->out, o->in2, TCG_BSWAP_IZ | TCG_BSWAP_OZ);
21a8eced 3757 return DISAS_NEXT;
d54f5865
RH
3758}
3759
21a8eced 3760static DisasJumpType op_rev32(DisasContext *s, DisasOps *o)
d54f5865 3761{
2b836c2a 3762 tcg_gen_bswap32_i64(o->out, o->in2, TCG_BSWAP_IZ | TCG_BSWAP_OZ);
21a8eced 3763 return DISAS_NEXT;
d54f5865
RH
3764}
3765
21a8eced 3766static DisasJumpType op_rev64(DisasContext *s, DisasOps *o)
d54f5865
RH
3767{
3768 tcg_gen_bswap64_i64(o->out, o->in2);
21a8eced 3769 return DISAS_NEXT;
d54f5865
RH
3770}
3771
21a8eced 3772static DisasJumpType op_rll32(DisasContext *s, DisasOps *o)
cbe24bfa
RH
3773{
3774 TCGv_i32 t1 = tcg_temp_new_i32();
3775 TCGv_i32 t2 = tcg_temp_new_i32();
3776 TCGv_i32 to = tcg_temp_new_i32();
ecc7b3aa
RH
3777 tcg_gen_extrl_i64_i32(t1, o->in1);
3778 tcg_gen_extrl_i64_i32(t2, o->in2);
cbe24bfa
RH
3779 tcg_gen_rotl_i32(to, t1, t2);
3780 tcg_gen_extu_i32_i64(o->out, to);
21a8eced 3781 return DISAS_NEXT;
cbe24bfa
RH
3782}
3783
21a8eced 3784static DisasJumpType op_rll64(DisasContext *s, DisasOps *o)
cbe24bfa
RH
3785{
3786 tcg_gen_rotl_i64(o->out, o->in1, o->in2);
21a8eced 3787 return DISAS_NEXT;
cbe24bfa
RH
3788}
3789
5cc69c54 3790#ifndef CONFIG_USER_ONLY
21a8eced 3791static DisasJumpType op_rrbe(DisasContext *s, DisasOps *o)
5cc69c54 3792{
5cc69c54
RH
3793 gen_helper_rrbe(cc_op, cpu_env, o->in2);
3794 set_cc_static(s);
21a8eced 3795 return DISAS_NEXT;
5cc69c54 3796}
14244b21 3797
21a8eced 3798static DisasJumpType op_sacf(DisasContext *s, DisasOps *o)
14244b21 3799{
14244b21
RH
3800 gen_helper_sacf(cpu_env, o->in2);
3801 /* Addressing mode has changed, so end the block. */
8ec2edac 3802 return DISAS_TOO_MANY;
14244b21 3803}
8612c935 3804#endif
44dd33ba 3805
21a8eced 3806static DisasJumpType op_sam(DisasContext *s, DisasOps *o)
44dd33ba
AG
3807{
3808 int sam = s->insn->data;
8612c935
RH
3809 TCGv_i64 tsam;
3810 uint64_t mask;
44dd33ba 3811
8612c935
RH
3812 switch (sam) {
3813 case 0:
3814 mask = 0xffffff;
3815 break;
3816 case 1:
3817 mask = 0x7fffffff;
3818 break;
3819 default:
3820 mask = -1;
3821 break;
3822 }
3823
631b22ea 3824 /* Bizarre but true, we check the address of the current insn for the
8612c935
RH
3825 specification exception, not the next to be executed. Thus the PoO
3826 documents that Bad Things Happen two bytes before the end. */
eccf741a 3827 if (s->base.pc_next & ~mask) {
8612c935 3828 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 3829 return DISAS_NORETURN;
8612c935 3830 }
eccf741a 3831 s->pc_tmp &= mask;
44dd33ba 3832
f1ea739b 3833 tsam = tcg_constant_i64(sam);
8612c935 3834 tcg_gen_deposit_i64(psw_mask, psw_mask, tsam, 31, 2);
8612c935
RH
3835
3836 /* Always exit the TB, since we (may have) changed execution mode. */
8ec2edac 3837 return DISAS_TOO_MANY;
44dd33ba 3838}
5cc69c54 3839
21a8eced 3840static DisasJumpType op_sar(DisasContext *s, DisasOps *o)
d62a4c97 3841{
c30988d1 3842 int r1 = get_field(s, r1);
d62a4c97 3843 tcg_gen_st32_i64(o->in2, cpu_env, offsetof(CPUS390XState, aregs[r1]));
21a8eced 3844 return DISAS_NEXT;
d62a4c97
RH
3845}
3846
21a8eced 3847static DisasJumpType op_seb(DisasContext *s, DisasOps *o)
1a800a2d
RH
3848{
3849 gen_helper_seb(o->out, cpu_env, o->in1, o->in2);
21a8eced 3850 return DISAS_NEXT;
1a800a2d
RH
3851}
3852
21a8eced 3853static DisasJumpType op_sdb(DisasContext *s, DisasOps *o)
1a800a2d
RH
3854{
3855 gen_helper_sdb(o->out, cpu_env, o->in1, o->in2);
21a8eced 3856 return DISAS_NEXT;
1a800a2d
RH
3857}
3858
21a8eced 3859static DisasJumpType op_sxb(DisasContext *s, DisasOps *o)
1a800a2d 3860{
2b91240f 3861 gen_helper_sxb(o->out_128, cpu_env, o->in1_128, o->in2_128);
21a8eced 3862 return DISAS_NEXT;
1a800a2d
RH
3863}
3864
21a8eced 3865static DisasJumpType op_sqeb(DisasContext *s, DisasOps *o)
16d7b2a4
RH
3866{
3867 gen_helper_sqeb(o->out, cpu_env, o->in2);
21a8eced 3868 return DISAS_NEXT;
16d7b2a4
RH
3869}
3870
21a8eced 3871static DisasJumpType op_sqdb(DisasContext *s, DisasOps *o)
16d7b2a4
RH
3872{
3873 gen_helper_sqdb(o->out, cpu_env, o->in2);
21a8eced 3874 return DISAS_NEXT;
16d7b2a4
RH
3875}
3876
21a8eced 3877static DisasJumpType op_sqxb(DisasContext *s, DisasOps *o)
16d7b2a4 3878{
2b91240f 3879 gen_helper_sqxb(o->out_128, cpu_env, o->in2_128);
21a8eced 3880 return DISAS_NEXT;
16d7b2a4
RH
3881}
3882
0c240015 3883#ifndef CONFIG_USER_ONLY
21a8eced 3884static DisasJumpType op_servc(DisasContext *s, DisasOps *o)
dc458df9 3885{
dc458df9
RH
3886 gen_helper_servc(cc_op, cpu_env, o->in2, o->in1);
3887 set_cc_static(s);
21a8eced 3888 return DISAS_NEXT;
dc458df9
RH
3889}
3890
21a8eced 3891static DisasJumpType op_sigp(DisasContext *s, DisasOps *o)
0c240015 3892{
f1ea739b
RH
3893 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
3894 TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
3895
11b0079c 3896 gen_helper_sigp(cc_op, cpu_env, o->in2, r1, r3);
1e8e69f0 3897 set_cc_static(s);
21a8eced 3898 return DISAS_NEXT;
0c240015
RH
3899}
3900#endif
3901
21a8eced 3902static DisasJumpType op_soc(DisasContext *s, DisasOps *o)
b92fa334
RH
3903{
3904 DisasCompare c;
45aa9aa3 3905 TCGv_i64 a, h;
42a268c2
RH
3906 TCGLabel *lab;
3907 int r1;
b92fa334 3908
c30988d1 3909 disas_jcc(s, &c, get_field(s, m3));
b92fa334 3910
c095ed73
AG
3911 /* We want to store when the condition is fulfilled, so branch
3912 out when it's not */
3913 c.cond = tcg_invert_cond(c.cond);
3914
b92fa334
RH
3915 lab = gen_new_label();
3916 if (c.is_64) {
3917 tcg_gen_brcond_i64(c.cond, c.u.s64.a, c.u.s64.b, lab);
3918 } else {
3919 tcg_gen_brcond_i32(c.cond, c.u.s32.a, c.u.s32.b, lab);
3920 }
b92fa334 3921
c30988d1
RH
3922 r1 = get_field(s, r1);
3923 a = get_address(s, 0, get_field(s, b2), get_field(s, d2));
45aa9aa3
RH
3924 switch (s->insn->data) {
3925 case 1: /* STOCG */
b92fa334 3926 tcg_gen_qemu_st64(regs[r1], a, get_mem_index(s));
45aa9aa3
RH
3927 break;
3928 case 0: /* STOC */
b92fa334 3929 tcg_gen_qemu_st32(regs[r1], a, get_mem_index(s));
45aa9aa3
RH
3930 break;
3931 case 2: /* STOCFH */
3932 h = tcg_temp_new_i64();
3933 tcg_gen_shri_i64(h, regs[r1], 32);
3934 tcg_gen_qemu_st32(h, a, get_mem_index(s));
45aa9aa3
RH
3935 break;
3936 default:
3937 g_assert_not_reached();
b92fa334 3938 }
b92fa334
RH
3939
3940 gen_set_label(lab);
21a8eced 3941 return DISAS_NEXT;
b92fa334
RH
3942}
3943
21a8eced 3944static DisasJumpType op_sla(DisasContext *s, DisasOps *o)
cbe24bfa 3945{
6da170be 3946 TCGv_i64 t;
cbe24bfa 3947 uint64_t sign = 1ull << s->insn->data;
6da170be
IL
3948 if (s->insn->data == 31) {
3949 t = tcg_temp_new_i64();
3950 tcg_gen_shli_i64(t, o->in1, 32);
3951 } else {
3952 t = o->in1;
3953 }
3954 gen_op_update2_cc_i64(s, CC_OP_SLA, t, o->in2);
cbe24bfa
RH
3955 tcg_gen_shl_i64(o->out, o->in1, o->in2);
3956 /* The arithmetic left shift is curious in that it does not affect
3957 the sign bit. Copy that over from the source unchanged. */
3958 tcg_gen_andi_i64(o->out, o->out, ~sign);
3959 tcg_gen_andi_i64(o->in1, o->in1, sign);
3960 tcg_gen_or_i64(o->out, o->out, o->in1);
21a8eced 3961 return DISAS_NEXT;
cbe24bfa
RH
3962}
3963
21a8eced 3964static DisasJumpType op_sll(DisasContext *s, DisasOps *o)
cbe24bfa
RH
3965{
3966 tcg_gen_shl_i64(o->out, o->in1, o->in2);
21a8eced 3967 return DISAS_NEXT;
cbe24bfa
RH
3968}
3969
21a8eced 3970static DisasJumpType op_sra(DisasContext *s, DisasOps *o)
cbe24bfa
RH
3971{
3972 tcg_gen_sar_i64(o->out, o->in1, o->in2);
21a8eced 3973 return DISAS_NEXT;
cbe24bfa
RH
3974}
3975
21a8eced 3976static DisasJumpType op_srl(DisasContext *s, DisasOps *o)
cbe24bfa
RH
3977{
3978 tcg_gen_shr_i64(o->out, o->in1, o->in2);
21a8eced 3979 return DISAS_NEXT;
cbe24bfa
RH
3980}
3981
21a8eced 3982static DisasJumpType op_sfpc(DisasContext *s, DisasOps *o)
8379bfdb
RH
3983{
3984 gen_helper_sfpc(cpu_env, o->in2);
21a8eced 3985 return DISAS_NEXT;
8379bfdb
RH
3986}
3987
21a8eced 3988static DisasJumpType op_sfas(DisasContext *s, DisasOps *o)
411edc22
RH
3989{
3990 gen_helper_sfas(cpu_env, o->in2);
21a8eced 3991 return DISAS_NEXT;
411edc22
RH
3992}
3993
21a8eced 3994static DisasJumpType op_srnm(DisasContext *s, DisasOps *o)
a12000b9 3995{
b9c737f5
DH
3996 /* Bits other than 62 and 63 are ignored. Bit 29 is set to zero. */
3997 tcg_gen_andi_i64(o->addr1, o->addr1, 0x3ull);
3998 gen_helper_srnm(cpu_env, o->addr1);
3999 return DISAS_NEXT;
4000}
a12000b9 4001
b9c737f5
DH
4002static DisasJumpType op_srnmb(DisasContext *s, DisasOps *o)
4003{
4004 /* Bits 0-55 are are ignored. */
4005 tcg_gen_andi_i64(o->addr1, o->addr1, 0xffull);
4006 gen_helper_srnm(cpu_env, o->addr1);
4007 return DISAS_NEXT;
4008}
a12000b9 4009
b9c737f5
DH
4010static DisasJumpType op_srnmt(DisasContext *s, DisasOps *o)
4011{
4012 TCGv_i64 tmp = tcg_temp_new_i64();
a12000b9 4013
b9c737f5
DH
4014 /* Bits other than 61-63 are ignored. */
4015 tcg_gen_andi_i64(o->addr1, o->addr1, 0x7ull);
4016
4017 /* No need to call a helper, we don't implement dfp */
4018 tcg_gen_ld32u_i64(tmp, cpu_env, offsetof(CPUS390XState, fpc));
4019 tcg_gen_deposit_i64(tmp, tmp, o->addr1, 4, 3);
4020 tcg_gen_st32_i64(tmp, cpu_env, offsetof(CPUS390XState, fpc));
21a8eced 4021 return DISAS_NEXT;
a12000b9
RH
4022}
4023
21a8eced 4024static DisasJumpType op_spm(DisasContext *s, DisasOps *o)
6b257354
DH
4025{
4026 tcg_gen_extrl_i64_i32(cc_op, o->in1);
4027 tcg_gen_extract_i32(cc_op, cc_op, 28, 2);
4028 set_cc_static(s);
4029
4030 tcg_gen_shri_i64(o->in1, o->in1, 24);
4031 tcg_gen_deposit_i64(psw_mask, psw_mask, o->in1, PSW_SHIFT_MASK_PM, 4);
21a8eced 4032 return DISAS_NEXT;
6b257354
DH
4033}
4034
21a8eced 4035static DisasJumpType op_ectg(DisasContext *s, DisasOps *o)
4bac52f5 4036{
c30988d1
RH
4037 int b1 = get_field(s, b1);
4038 int d1 = get_field(s, d1);
4039 int b2 = get_field(s, b2);
4040 int d2 = get_field(s, d2);
4041 int r3 = get_field(s, r3);
4bac52f5
DH
4042 TCGv_i64 tmp = tcg_temp_new_i64();
4043
4044 /* fetch all operands first */
4045 o->in1 = tcg_temp_new_i64();
4046 tcg_gen_addi_i64(o->in1, regs[b1], d1);
4047 o->in2 = tcg_temp_new_i64();
4048 tcg_gen_addi_i64(o->in2, regs[b2], d2);
401bf467
DH
4049 o->addr1 = tcg_temp_new_i64();
4050 gen_addi_and_wrap_i64(s, o->addr1, regs[r3], 0);
4bac52f5
DH
4051
4052 /* load the third operand into r3 before modifying anything */
4053 tcg_gen_qemu_ld64(regs[r3], o->addr1, get_mem_index(s));
4054
4055 /* subtract CPU timer from first operand and store in GR0 */
4056 gen_helper_stpt(tmp, cpu_env);
4057 tcg_gen_sub_i64(regs[0], o->in1, tmp);
4058
4059 /* store second operand in GR1 */
4060 tcg_gen_mov_i64(regs[1], o->in2);
21a8eced 4061 return DISAS_NEXT;
4bac52f5
DH
4062}
4063
7d30bb73 4064#ifndef CONFIG_USER_ONLY
21a8eced 4065static DisasJumpType op_spka(DisasContext *s, DisasOps *o)
28d55556 4066{
28d55556 4067 tcg_gen_shri_i64(o->in2, o->in2, 4);
c8bd9537 4068 tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, PSW_SHIFT_KEY, 4);
21a8eced 4069 return DISAS_NEXT;
28d55556
RH
4070}
4071
21a8eced 4072static DisasJumpType op_sske(DisasContext *s, DisasOps *o)
2bbde27f 4073{
2bbde27f 4074 gen_helper_sske(cpu_env, o->in1, o->in2);
21a8eced 4075 return DISAS_NEXT;
2bbde27f
RH
4076}
4077
199c42a6
IL
4078static void gen_check_psw_mask(DisasContext *s)
4079{
4080 TCGv_i64 reserved = tcg_temp_new_i64();
4081 TCGLabel *ok = gen_new_label();
4082
4083 tcg_gen_andi_i64(reserved, psw_mask, PSW_MASK_RESERVED);
4084 tcg_gen_brcondi_i64(TCG_COND_EQ, reserved, 0, ok);
4085 gen_program_exception(s, PGM_SPECIFICATION);
4086 gen_set_label(ok);
4087}
4088
21a8eced 4089static DisasJumpType op_ssm(DisasContext *s, DisasOps *o)
7d30bb73 4090{
7d30bb73 4091 tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, 56, 8);
199c42a6
IL
4092
4093 gen_check_psw_mask(s);
4094
542f70c2 4095 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
872e1379
RH
4096 s->exit_to_mainloop = true;
4097 return DISAS_TOO_MANY;
7d30bb73 4098}
145cdb40 4099
21a8eced 4100static DisasJumpType op_stap(DisasContext *s, DisasOps *o)
411fea3d 4101{
ca5c1457 4102 tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, core_id));
21a8eced 4103 return DISAS_NEXT;
411fea3d 4104}
965018be 4105#endif
411fea3d 4106
21a8eced 4107static DisasJumpType op_stck(DisasContext *s, DisasOps *o)
434c91a5
RH
4108{
4109 gen_helper_stck(o->out, cpu_env);
4110 /* ??? We don't implement clock states. */
4111 gen_op_movi_cc(s, 0);
21a8eced 4112 return DISAS_NEXT;
39a5003c
RH
4113}
4114
21a8eced 4115static DisasJumpType op_stcke(DisasContext *s, DisasOps *o)
39a5003c
RH
4116{
4117 TCGv_i64 c1 = tcg_temp_new_i64();
4118 TCGv_i64 c2 = tcg_temp_new_i64();
a63b7cbf 4119 TCGv_i64 todpr = tcg_temp_new_i64();
39a5003c 4120 gen_helper_stck(c1, cpu_env);
a63b7cbf
DH
4121 /* 16 bit value store in an uint32_t (only valid bits set) */
4122 tcg_gen_ld32u_i64(todpr, cpu_env, offsetof(CPUS390XState, todpr));
39a5003c
RH
4123 /* Shift the 64-bit value into its place as a zero-extended
4124 104-bit value. Note that "bit positions 64-103 are always
4125 non-zero so that they compare differently to STCK"; we set
4126 the least significant bit to 1. */
4127 tcg_gen_shli_i64(c2, c1, 56);
4128 tcg_gen_shri_i64(c1, c1, 8);
4129 tcg_gen_ori_i64(c2, c2, 0x10000);
a63b7cbf 4130 tcg_gen_or_i64(c2, c2, todpr);
39a5003c
RH
4131 tcg_gen_qemu_st64(c1, o->in2, get_mem_index(s));
4132 tcg_gen_addi_i64(o->in2, o->in2, 8);
4133 tcg_gen_qemu_st64(c2, o->in2, get_mem_index(s));
39a5003c
RH
4134 /* ??? We don't implement clock states. */
4135 gen_op_movi_cc(s, 0);
21a8eced 4136 return DISAS_NEXT;
434c91a5
RH
4137}
4138
965018be 4139#ifndef CONFIG_USER_ONLY
9dc67537
DH
4140static DisasJumpType op_sck(DisasContext *s, DisasOps *o)
4141{
2092fdd9 4142 gen_helper_sck(cc_op, cpu_env, o->in2);
9dc67537
DH
4143 set_cc_static(s);
4144 return DISAS_NEXT;
4145}
4146
21a8eced 4147static DisasJumpType op_sckc(DisasContext *s, DisasOps *o)
dd3eb7b5 4148{
dd3eb7b5 4149 gen_helper_sckc(cpu_env, o->in2);
21a8eced 4150 return DISAS_NEXT;
dd3eb7b5
RH
4151}
4152
21a8eced 4153static DisasJumpType op_sckpf(DisasContext *s, DisasOps *o)
257a119e 4154{
257a119e 4155 gen_helper_sckpf(cpu_env, regs[0]);
21a8eced 4156 return DISAS_NEXT;
257a119e
DH
4157}
4158
21a8eced 4159static DisasJumpType op_stckc(DisasContext *s, DisasOps *o)
dd3eb7b5 4160{
dd3eb7b5 4161 gen_helper_stckc(o->out, cpu_env);
21a8eced 4162 return DISAS_NEXT;
dd3eb7b5
RH
4163}
4164
21a8eced 4165static DisasJumpType op_stctg(DisasContext *s, DisasOps *o)
3e398cf9 4166{
f1ea739b
RH
4167 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4168 TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
4169
3e398cf9 4170 gen_helper_stctg(cpu_env, r1, o->in2, r3);
21a8eced 4171 return DISAS_NEXT;
3e398cf9
RH
4172}
4173
21a8eced 4174static DisasJumpType op_stctl(DisasContext *s, DisasOps *o)
504488b8 4175{
f1ea739b
RH
4176 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4177 TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
4178
504488b8 4179 gen_helper_stctl(cpu_env, r1, o->in2, r3);
21a8eced 4180 return DISAS_NEXT;
504488b8
RH
4181}
4182
21a8eced 4183static DisasJumpType op_stidp(DisasContext *s, DisasOps *o)
71bd6669 4184{
076d4d39 4185 tcg_gen_ld_i64(o->out, cpu_env, offsetof(CPUS390XState, cpuid));
21a8eced 4186 return DISAS_NEXT;
71bd6669
RH
4187}
4188
21a8eced 4189static DisasJumpType op_spt(DisasContext *s, DisasOps *o)
c4f0a863 4190{
c4f0a863 4191 gen_helper_spt(cpu_env, o->in2);
21a8eced 4192 return DISAS_NEXT;
c4f0a863
RH
4193}
4194
21a8eced 4195static DisasJumpType op_stfl(DisasContext *s, DisasOps *o)
fc778b55 4196{
5bf83628 4197 gen_helper_stfl(cpu_env);
21a8eced 4198 return DISAS_NEXT;
fc778b55
RH
4199}
4200
21a8eced 4201static DisasJumpType op_stpt(DisasContext *s, DisasOps *o)
c4f0a863 4202{
c4f0a863 4203 gen_helper_stpt(o->out, cpu_env);
21a8eced 4204 return DISAS_NEXT;
c4f0a863
RH
4205}
4206
21a8eced 4207static DisasJumpType op_stsi(DisasContext *s, DisasOps *o)
d14b3e09 4208{
d14b3e09
RH
4209 gen_helper_stsi(cc_op, cpu_env, o->in2, regs[0], regs[1]);
4210 set_cc_static(s);
21a8eced 4211 return DISAS_NEXT;
d14b3e09
RH
4212}
4213
21a8eced 4214static DisasJumpType op_spx(DisasContext *s, DisasOps *o)
e805a0d3 4215{
e805a0d3 4216 gen_helper_spx(cpu_env, o->in2);
21a8eced 4217 return DISAS_NEXT;
e805a0d3
RH
4218}
4219
21a8eced 4220static DisasJumpType op_xsch(DisasContext *s, DisasOps *o)
2c423fc0 4221{
ad8a4570
AG
4222 gen_helper_xsch(cpu_env, regs[1]);
4223 set_cc_static(s);
21a8eced 4224 return DISAS_NEXT;
ad8a4570
AG
4225}
4226
21a8eced 4227static DisasJumpType op_csch(DisasContext *s, DisasOps *o)
ad8a4570 4228{
ad8a4570
AG
4229 gen_helper_csch(cpu_env, regs[1]);
4230 set_cc_static(s);
21a8eced 4231 return DISAS_NEXT;
ad8a4570
AG
4232}
4233
21a8eced 4234static DisasJumpType op_hsch(DisasContext *s, DisasOps *o)
ad8a4570 4235{
ad8a4570
AG
4236 gen_helper_hsch(cpu_env, regs[1]);
4237 set_cc_static(s);
21a8eced 4238 return DISAS_NEXT;
ad8a4570
AG
4239}
4240
21a8eced 4241static DisasJumpType op_msch(DisasContext *s, DisasOps *o)
ad8a4570 4242{
ad8a4570
AG
4243 gen_helper_msch(cpu_env, regs[1], o->in2);
4244 set_cc_static(s);
21a8eced 4245 return DISAS_NEXT;
ad8a4570
AG
4246}
4247
21a8eced 4248static DisasJumpType op_rchp(DisasContext *s, DisasOps *o)
ad8a4570 4249{
ad8a4570
AG
4250 gen_helper_rchp(cpu_env, regs[1]);
4251 set_cc_static(s);
21a8eced 4252 return DISAS_NEXT;
ad8a4570
AG
4253}
4254
21a8eced 4255static DisasJumpType op_rsch(DisasContext *s, DisasOps *o)
ad8a4570 4256{
ad8a4570
AG
4257 gen_helper_rsch(cpu_env, regs[1]);
4258 set_cc_static(s);
21a8eced 4259 return DISAS_NEXT;
ad8a4570
AG
4260}
4261
21a8eced 4262static DisasJumpType op_sal(DisasContext *s, DisasOps *o)
86c34633 4263{
86c34633 4264 gen_helper_sal(cpu_env, regs[1]);
21a8eced 4265 return DISAS_NEXT;
86c34633
DH
4266}
4267
21a8eced 4268static DisasJumpType op_schm(DisasContext *s, DisasOps *o)
a9de75a0 4269{
a9de75a0 4270 gen_helper_schm(cpu_env, regs[1], regs[2], o->in2);
21a8eced 4271 return DISAS_NEXT;
a9de75a0
DH
4272}
4273
21a8eced 4274static DisasJumpType op_siga(DisasContext *s, DisasOps *o)
ad0ccf1e 4275{
ad0ccf1e
DH
4276 /* From KVM code: Not provided, set CC = 3 for subchannel not operational */
4277 gen_op_movi_cc(s, 3);
21a8eced 4278 return DISAS_NEXT;
ad0ccf1e
DH
4279}
4280
21a8eced 4281static DisasJumpType op_stcps(DisasContext *s, DisasOps *o)
b9b0a4dc 4282{
b9b0a4dc 4283 /* The instruction is suppressed if not provided. */
21a8eced 4284 return DISAS_NEXT;
b9b0a4dc
DH
4285}
4286
21a8eced 4287static DisasJumpType op_ssch(DisasContext *s, DisasOps *o)
ad8a4570 4288{
ad8a4570
AG
4289 gen_helper_ssch(cpu_env, regs[1], o->in2);
4290 set_cc_static(s);
21a8eced 4291 return DISAS_NEXT;
ad8a4570
AG
4292}
4293
21a8eced 4294static DisasJumpType op_stsch(DisasContext *s, DisasOps *o)
ad8a4570 4295{
ad8a4570
AG
4296 gen_helper_stsch(cpu_env, regs[1], o->in2);
4297 set_cc_static(s);
21a8eced 4298 return DISAS_NEXT;
ad8a4570
AG
4299}
4300
21a8eced 4301static DisasJumpType op_stcrw(DisasContext *s, DisasOps *o)
5a59bc1d 4302{
5a59bc1d
DH
4303 gen_helper_stcrw(cpu_env, o->in2);
4304 set_cc_static(s);
21a8eced 4305 return DISAS_NEXT;
5a59bc1d
DH
4306}
4307
21a8eced 4308static DisasJumpType op_tpi(DisasContext *s, DisasOps *o)
6a253de3 4309{
6a253de3
DH
4310 gen_helper_tpi(cc_op, cpu_env, o->addr1);
4311 set_cc_static(s);
21a8eced 4312 return DISAS_NEXT;
6a253de3
DH
4313}
4314
21a8eced 4315static DisasJumpType op_tsch(DisasContext *s, DisasOps *o)
ad8a4570 4316{
ad8a4570
AG
4317 gen_helper_tsch(cpu_env, regs[1], o->in2);
4318 set_cc_static(s);
21a8eced 4319 return DISAS_NEXT;
ad8a4570
AG
4320}
4321
21a8eced 4322static DisasJumpType op_chsc(DisasContext *s, DisasOps *o)
ad8a4570 4323{
ad8a4570
AG
4324 gen_helper_chsc(cpu_env, o->in2);
4325 set_cc_static(s);
21a8eced 4326 return DISAS_NEXT;
2c423fc0
RH
4327}
4328
21a8eced 4329static DisasJumpType op_stpx(DisasContext *s, DisasOps *o)
e805a0d3 4330{
e805a0d3
RH
4331 tcg_gen_ld_i64(o->out, cpu_env, offsetof(CPUS390XState, psa));
4332 tcg_gen_andi_i64(o->out, o->out, 0x7fffe000);
21a8eced 4333 return DISAS_NEXT;
e805a0d3
RH
4334}
4335
21a8eced 4336static DisasJumpType op_stnosm(DisasContext *s, DisasOps *o)
145cdb40 4337{
c30988d1 4338 uint64_t i2 = get_field(s, i2);
145cdb40
RH
4339 TCGv_i64 t;
4340
145cdb40
RH
4341 /* It is important to do what the instruction name says: STORE THEN.
4342 If we let the output hook perform the store then if we fault and
4343 restart, we'll have the wrong SYSTEM MASK in place. */
4344 t = tcg_temp_new_i64();
4345 tcg_gen_shri_i64(t, psw_mask, 56);
4346 tcg_gen_qemu_st8(t, o->addr1, get_mem_index(s));
145cdb40 4347
344a7f65 4348 if (s->fields.op == 0xac) {
145cdb40
RH
4349 tcg_gen_andi_i64(psw_mask, psw_mask,
4350 (i2 << 56) | 0x00ffffffffffffffull);
4351 } else {
4352 tcg_gen_ori_i64(psw_mask, psw_mask, i2 << 56);
4353 }
542f70c2 4354
199c42a6
IL
4355 gen_check_psw_mask(s);
4356
542f70c2 4357 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
872e1379
RH
4358 s->exit_to_mainloop = true;
4359 return DISAS_TOO_MANY;
145cdb40 4360}
204504e2 4361
21a8eced 4362static DisasJumpType op_stura(DisasContext *s, DisasOps *o)
204504e2 4363{
401bf467 4364 tcg_gen_qemu_st_tl(o->in1, o->in2, MMU_REAL_IDX, s->insn->data);
9c3fd85b 4365
ebed683c
RH
4366 if (s->base.tb->flags & FLAG_MASK_PER) {
4367 update_psw_addr(s);
4368 gen_helper_per_store_real(cpu_env);
4369 }
21a8eced 4370 return DISAS_NEXT;
9c3fd85b 4371}
7d30bb73
RH
4372#endif
4373
21a8eced 4374static DisasJumpType op_stfle(DisasContext *s, DisasOps *o)
5bf83628 4375{
5bf83628
RH
4376 gen_helper_stfle(cc_op, cpu_env, o->in2);
4377 set_cc_static(s);
21a8eced 4378 return DISAS_NEXT;
5bf83628
RH
4379}
4380
21a8eced 4381static DisasJumpType op_st8(DisasContext *s, DisasOps *o)
2b280b97
RH
4382{
4383 tcg_gen_qemu_st8(o->in1, o->in2, get_mem_index(s));
21a8eced 4384 return DISAS_NEXT;
2b280b97
RH
4385}
4386
21a8eced 4387static DisasJumpType op_st16(DisasContext *s, DisasOps *o)
2b280b97
RH
4388{
4389 tcg_gen_qemu_st16(o->in1, o->in2, get_mem_index(s));
21a8eced 4390 return DISAS_NEXT;
2b280b97
RH
4391}
4392
21a8eced 4393static DisasJumpType op_st32(DisasContext *s, DisasOps *o)
2b280b97
RH
4394{
4395 tcg_gen_qemu_st32(o->in1, o->in2, get_mem_index(s));
21a8eced 4396 return DISAS_NEXT;
2b280b97
RH
4397}
4398
21a8eced 4399static DisasJumpType op_st64(DisasContext *s, DisasOps *o)
2b280b97
RH
4400{
4401 tcg_gen_qemu_st64(o->in1, o->in2, get_mem_index(s));
21a8eced 4402 return DISAS_NEXT;
2b280b97
RH
4403}
4404
21a8eced 4405static DisasJumpType op_stam(DisasContext *s, DisasOps *o)
7df3e93a 4406{
f1ea739b
RH
4407 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4408 TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
4409
7df3e93a 4410 gen_helper_stam(cpu_env, r1, o->in2, r3);
21a8eced 4411 return DISAS_NEXT;
7df3e93a
RH
4412}
4413
21a8eced 4414static DisasJumpType op_stcm(DisasContext *s, DisasOps *o)
2ae68059 4415{
c30988d1 4416 int m3 = get_field(s, m3);
2ae68059
RH
4417 int pos, base = s->insn->data;
4418 TCGv_i64 tmp = tcg_temp_new_i64();
4419
4420 pos = base + ctz32(m3) * 8;
4421 switch (m3) {
4422 case 0xf:
4423 /* Effectively a 32-bit store. */
4424 tcg_gen_shri_i64(tmp, o->in1, pos);
4425 tcg_gen_qemu_st32(tmp, o->in2, get_mem_index(s));
4426 break;
4427
4428 case 0xc:
4429 case 0x6:
4430 case 0x3:
4431 /* Effectively a 16-bit store. */
4432 tcg_gen_shri_i64(tmp, o->in1, pos);
4433 tcg_gen_qemu_st16(tmp, o->in2, get_mem_index(s));
4434 break;
4435
4436 case 0x8:
4437 case 0x4:
4438 case 0x2:
4439 case 0x1:
4440 /* Effectively an 8-bit store. */
4441 tcg_gen_shri_i64(tmp, o->in1, pos);
4442 tcg_gen_qemu_st8(tmp, o->in2, get_mem_index(s));
4443 break;
4444
4445 default:
4446 /* This is going to be a sequence of shifts and stores. */
4447 pos = base + 32 - 8;
4448 while (m3) {
4449 if (m3 & 0x8) {
4450 tcg_gen_shri_i64(tmp, o->in1, pos);
4451 tcg_gen_qemu_st8(tmp, o->in2, get_mem_index(s));
4452 tcg_gen_addi_i64(o->in2, o->in2, 1);
4453 }
4454 m3 = (m3 << 1) & 0xf;
4455 pos -= 8;
4456 }
4457 break;
4458 }
21a8eced 4459 return DISAS_NEXT;
2ae68059
RH
4460}
4461
21a8eced 4462static DisasJumpType op_stm(DisasContext *s, DisasOps *o)
77f8d6c3 4463{
c30988d1
RH
4464 int r1 = get_field(s, r1);
4465 int r3 = get_field(s, r3);
77f8d6c3 4466 int size = s->insn->data;
f1ea739b 4467 TCGv_i64 tsize = tcg_constant_i64(size);
77f8d6c3
RH
4468
4469 while (1) {
4470 if (size == 8) {
4471 tcg_gen_qemu_st64(regs[r1], o->in2, get_mem_index(s));
4472 } else {
4473 tcg_gen_qemu_st32(regs[r1], o->in2, get_mem_index(s));
4474 }
4475 if (r1 == r3) {
4476 break;
4477 }
4478 tcg_gen_add_i64(o->in2, o->in2, tsize);
4479 r1 = (r1 + 1) & 15;
4480 }
4481
21a8eced 4482 return DISAS_NEXT;
77f8d6c3
RH
4483}
4484
21a8eced 4485static DisasJumpType op_stmh(DisasContext *s, DisasOps *o)
77f8d6c3 4486{
c30988d1
RH
4487 int r1 = get_field(s, r1);
4488 int r3 = get_field(s, r3);
77f8d6c3 4489 TCGv_i64 t = tcg_temp_new_i64();
f1ea739b
RH
4490 TCGv_i64 t4 = tcg_constant_i64(4);
4491 TCGv_i64 t32 = tcg_constant_i64(32);
77f8d6c3
RH
4492
4493 while (1) {
4494 tcg_gen_shl_i64(t, regs[r1], t32);
4495 tcg_gen_qemu_st32(t, o->in2, get_mem_index(s));
4496 if (r1 == r3) {
4497 break;
4498 }
4499 tcg_gen_add_i64(o->in2, o->in2, t4);
4500 r1 = (r1 + 1) & 15;
4501 }
21a8eced 4502 return DISAS_NEXT;
77f8d6c3
RH
4503}
4504
21a8eced 4505static DisasJumpType op_stpq(DisasContext *s, DisasOps *o)
c21b610f 4506{
830bf10c
RH
4507 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4508 gen_helper_stpq(cpu_env, o->in2, o->out2, o->out);
4509 } else if (HAVE_ATOMIC128) {
6476615d
EC
4510 gen_helper_stpq_parallel(cpu_env, o->in2, o->out2, o->out);
4511 } else {
830bf10c
RH
4512 gen_helper_exit_atomic(cpu_env);
4513 return DISAS_NORETURN;
6476615d 4514 }
21a8eced 4515 return DISAS_NEXT;
c21b610f
AJ
4516}
4517
21a8eced 4518static DisasJumpType op_srst(DisasContext *s, DisasOps *o)
4600c994 4519{
f1ea739b
RH
4520 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4521 TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
7591db78
RH
4522
4523 gen_helper_srst(cpu_env, r1, r2);
4600c994 4524 set_cc_static(s);
21a8eced 4525 return DISAS_NEXT;
4600c994
RH
4526}
4527
21a8eced 4528static DisasJumpType op_srstu(DisasContext *s, DisasOps *o)
be7acb58 4529{
f1ea739b
RH
4530 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4531 TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
be7acb58
RH
4532
4533 gen_helper_srstu(cpu_env, r1, r2);
be7acb58 4534 set_cc_static(s);
21a8eced 4535 return DISAS_NEXT;
be7acb58
RH
4536}
4537
21a8eced 4538static DisasJumpType op_sub(DisasContext *s, DisasOps *o)
ad044d09
RH
4539{
4540 tcg_gen_sub_i64(o->out, o->in1, o->in2);
21a8eced 4541 return DISAS_NEXT;
ad044d09
RH
4542}
4543
a2db06da
RH
4544static DisasJumpType op_subu64(DisasContext *s, DisasOps *o)
4545{
4546 tcg_gen_movi_i64(cc_src, 0);
4547 tcg_gen_sub2_i64(o->out, cc_src, o->in1, cc_src, o->in2, cc_src);
4548 return DISAS_NEXT;
4549}
4550
1a9aaa4b
RH
4551/* Compute borrow (0, -1) into cc_src. */
4552static void compute_borrow(DisasContext *s)
4e4bb438 4553{
1a9aaa4b
RH
4554 switch (s->cc_op) {
4555 case CC_OP_SUBU:
4556 /* The borrow value is already in cc_src (0,-1). */
4557 break;
4558 default:
4559 gen_op_calc_cc(s);
4560 /* fall through */
4561 case CC_OP_STATIC:
4562 /* The carry flag is the msb of CC; compute into cc_src. */
4563 tcg_gen_extu_i32_i64(cc_src, cc_op);
4564 tcg_gen_shri_i64(cc_src, cc_src, 1);
4565 /* fall through */
4566 case CC_OP_ADDU:
4567 /* Convert carry (1,0) to borrow (0,-1). */
4568 tcg_gen_subi_i64(cc_src, cc_src, 1);
4569 break;
4570 }
4571}
4e4bb438 4572
1a9aaa4b
RH
4573static DisasJumpType op_subb32(DisasContext *s, DisasOps *o)
4574{
4575 compute_borrow(s);
4e4bb438 4576
1a9aaa4b
RH
4577 /* Borrow is {0, -1}, so add to subtract. */
4578 tcg_gen_add_i64(o->out, o->in1, cc_src);
4579 tcg_gen_sub_i64(o->out, o->out, o->in2);
4580 return DISAS_NEXT;
4581}
4582
4583static DisasJumpType op_subb64(DisasContext *s, DisasOps *o)
4584{
4585 compute_borrow(s);
4586
4587 /*
4588 * Borrow is {0, -1}, so add to subtract; replicate the
4589 * borrow input to produce 128-bit -1 for the addition.
4590 */
f1ea739b 4591 TCGv_i64 zero = tcg_constant_i64(0);
1a9aaa4b
RH
4592 tcg_gen_add2_i64(o->out, cc_src, o->in1, zero, cc_src, cc_src);
4593 tcg_gen_sub2_i64(o->out, cc_src, o->out, cc_src, o->in2, zero);
c95ec459 4594
21a8eced 4595 return DISAS_NEXT;
4e4bb438
RH
4596}
4597
21a8eced 4598static DisasJumpType op_svc(DisasContext *s, DisasOps *o)
b9836c1a
RH
4599{
4600 TCGv_i32 t;
4601
4602 update_psw_addr(s);
7a6c7067 4603 update_cc_op(s);
b9836c1a 4604
f1ea739b 4605 t = tcg_constant_i32(get_field(s, i1) & 0xff);
b9836c1a 4606 tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, int_svc_code));
b9836c1a 4607
f1ea739b 4608 t = tcg_constant_i32(s->ilen);
b9836c1a 4609 tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, int_svc_ilen));
b9836c1a
RH
4610
4611 gen_exception(EXCP_SVC);
21a8eced 4612 return DISAS_NORETURN;
b9836c1a
RH
4613}
4614
21a8eced 4615static DisasJumpType op_tam(DisasContext *s, DisasOps *o)
0c0974d7
AJ
4616{
4617 int cc = 0;
4618
eccf741a
EC
4619 cc |= (s->base.tb->flags & FLAG_MASK_64) ? 2 : 0;
4620 cc |= (s->base.tb->flags & FLAG_MASK_32) ? 1 : 0;
0c0974d7 4621 gen_op_movi_cc(s, cc);
21a8eced 4622 return DISAS_NEXT;
0c0974d7
AJ
4623}
4624
21a8eced 4625static DisasJumpType op_tceb(DisasContext *s, DisasOps *o)
31aa97d1 4626{
af39bc8c 4627 gen_helper_tceb(cc_op, cpu_env, o->in1, o->in2);
31aa97d1 4628 set_cc_static(s);
21a8eced 4629 return DISAS_NEXT;
31aa97d1
RH
4630}
4631
21a8eced 4632static DisasJumpType op_tcdb(DisasContext *s, DisasOps *o)
31aa97d1 4633{
af39bc8c 4634 gen_helper_tcdb(cc_op, cpu_env, o->in1, o->in2);
31aa97d1 4635 set_cc_static(s);
21a8eced 4636 return DISAS_NEXT;
31aa97d1
RH
4637}
4638
21a8eced 4639static DisasJumpType op_tcxb(DisasContext *s, DisasOps *o)
31aa97d1 4640{
2b91240f 4641 gen_helper_tcxb(cc_op, cpu_env, o->in1_128, o->in2);
31aa97d1 4642 set_cc_static(s);
21a8eced 4643 return DISAS_NEXT;
31aa97d1
RH
4644}
4645
112bf079 4646#ifndef CONFIG_USER_ONLY
f79f1ca4 4647
21a8eced 4648static DisasJumpType op_testblock(DisasContext *s, DisasOps *o)
f79f1ca4 4649{
f79f1ca4
TH
4650 gen_helper_testblock(cc_op, cpu_env, o->in2);
4651 set_cc_static(s);
21a8eced 4652 return DISAS_NEXT;
f79f1ca4
TH
4653}
4654
21a8eced 4655static DisasJumpType op_tprot(DisasContext *s, DisasOps *o)
112bf079 4656{
bb879430 4657 gen_helper_tprot(cc_op, cpu_env, o->addr1, o->in2);
112bf079 4658 set_cc_static(s);
21a8eced 4659 return DISAS_NEXT;
112bf079 4660}
f79f1ca4 4661
112bf079
RH
4662#endif
4663
21a8eced 4664static DisasJumpType op_tp(DisasContext *s, DisasOps *o)
5d4a655a 4665{
f1ea739b
RH
4666 TCGv_i32 l1 = tcg_constant_i32(get_field(s, l1) + 1);
4667
5d4a655a 4668 gen_helper_tp(cc_op, cpu_env, o->addr1, l1);
5d4a655a 4669 set_cc_static(s);
21a8eced 4670 return DISAS_NEXT;
5d4a655a
AJ
4671}
4672
21a8eced 4673static DisasJumpType op_tr(DisasContext *s, DisasOps *o)
0a949039 4674{
f1ea739b
RH
4675 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
4676
0a949039 4677 gen_helper_tr(cpu_env, l, o->addr1, o->in2);
0a949039 4678 set_cc_static(s);
21a8eced 4679 return DISAS_NEXT;
0a949039
RH
4680}
4681
21a8eced 4682static DisasJumpType op_tre(DisasContext *s, DisasOps *o)
3f4de675 4683{
ef45f5b9
RH
4684 TCGv_i128 pair = tcg_temp_new_i128();
4685
4686 gen_helper_tre(pair, cpu_env, o->out, o->out2, o->in2);
4687 tcg_gen_extr_i128_i64(o->out2, o->out, pair);
3f4de675 4688 set_cc_static(s);
21a8eced 4689 return DISAS_NEXT;
3f4de675
AJ
4690}
4691
21a8eced 4692static DisasJumpType op_trt(DisasContext *s, DisasOps *o)
54f00775 4693{
f1ea739b
RH
4694 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
4695
54f00775 4696 gen_helper_trt(cc_op, cpu_env, l, o->addr1, o->in2);
54f00775 4697 set_cc_static(s);
21a8eced 4698 return DISAS_NEXT;
54f00775
AJ
4699}
4700
21a8eced 4701static DisasJumpType op_trtr(DisasContext *s, DisasOps *o)
b213c9f5 4702{
f1ea739b
RH
4703 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
4704
b213c9f5 4705 gen_helper_trtr(cc_op, cpu_env, l, o->addr1, o->in2);
b213c9f5 4706 set_cc_static(s);
21a8eced 4707 return DISAS_NEXT;
b213c9f5
RH
4708}
4709
21a8eced 4710static DisasJumpType op_trXX(DisasContext *s, DisasOps *o)
4065ae76 4711{
f1ea739b
RH
4712 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4713 TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
4714 TCGv_i32 sizes = tcg_constant_i32(s->insn->opc & 3);
4065ae76 4715 TCGv_i32 tst = tcg_temp_new_i32();
c30988d1 4716 int m3 = get_field(s, m3);
4065ae76 4717
3c39c800
RH
4718 if (!s390_has_feat(S390_FEAT_ETF2_ENH)) {
4719 m3 = 0;
4720 }
4065ae76
AJ
4721 if (m3 & 1) {
4722 tcg_gen_movi_i32(tst, -1);
4723 } else {
4724 tcg_gen_extrl_i64_i32(tst, regs[0]);
4725 if (s->insn->opc & 3) {
4726 tcg_gen_ext8u_i32(tst, tst);
4727 } else {
4728 tcg_gen_ext16u_i32(tst, tst);
4729 }
4730 }
4731 gen_helper_trXX(cc_op, cpu_env, r1, r2, tst, sizes);
4732
4065ae76 4733 set_cc_static(s);
21a8eced 4734 return DISAS_NEXT;
4065ae76
AJ
4735}
4736
21a8eced 4737static DisasJumpType op_ts(DisasContext *s, DisasOps *o)
6699adfc 4738{
f1ea739b
RH
4739 TCGv_i32 t1 = tcg_constant_i32(0xff);
4740
6699adfc
AJ
4741 tcg_gen_atomic_xchg_i32(t1, o->in2, t1, get_mem_index(s), MO_UB);
4742 tcg_gen_extract_i32(cc_op, t1, 7, 1);
6699adfc 4743 set_cc_static(s);
21a8eced 4744 return DISAS_NEXT;
6699adfc
AJ
4745}
4746
21a8eced 4747static DisasJumpType op_unpk(DisasContext *s, DisasOps *o)
0a949039 4748{
f1ea739b
RH
4749 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
4750
0a949039 4751 gen_helper_unpk(cpu_env, l, o->addr1, o->in2);
21a8eced 4752 return DISAS_NEXT;
0a949039
RH
4753}
4754
21a8eced 4755static DisasJumpType op_unpka(DisasContext *s, DisasOps *o)
1a35f08a 4756{
c30988d1 4757 int l1 = get_field(s, l1) + 1;
1a35f08a
AJ
4758 TCGv_i32 l;
4759
4760 /* The length must not exceed 32 bytes. */
4761 if (l1 > 32) {
4762 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 4763 return DISAS_NORETURN;
1a35f08a 4764 }
f1ea739b 4765 l = tcg_constant_i32(l1);
1a35f08a 4766 gen_helper_unpka(cc_op, cpu_env, o->addr1, l, o->in2);
1a35f08a 4767 set_cc_static(s);
21a8eced 4768 return DISAS_NEXT;
1a35f08a
AJ
4769}
4770
21a8eced 4771static DisasJumpType op_unpku(DisasContext *s, DisasOps *o)
15417787 4772{
c30988d1 4773 int l1 = get_field(s, l1) + 1;
15417787
AJ
4774 TCGv_i32 l;
4775
4776 /* The length must be even and should not exceed 64 bytes. */
4777 if ((l1 & 1) || (l1 > 64)) {
4778 gen_program_exception(s, PGM_SPECIFICATION);
21a8eced 4779 return DISAS_NORETURN;
15417787 4780 }
f1ea739b 4781 l = tcg_constant_i32(l1);
15417787 4782 gen_helper_unpku(cc_op, cpu_env, o->addr1, l, o->in2);
15417787 4783 set_cc_static(s);
21a8eced 4784 return DISAS_NEXT;
15417787
AJ
4785}
4786
4787
21a8eced 4788static DisasJumpType op_xc(DisasContext *s, DisasOps *o)
0a949039 4789{
c30988d1
RH
4790 int d1 = get_field(s, d1);
4791 int d2 = get_field(s, d2);
4792 int b1 = get_field(s, b1);
4793 int b2 = get_field(s, b2);
4794 int l = get_field(s, l1);
d074ac6d
RH
4795 TCGv_i32 t32;
4796
4797 o->addr1 = get_address(s, 0, b1, d1);
4798
4799 /* If the addresses are identical, this is a store/memset of zero. */
4800 if (b1 == b2 && d1 == d2 && (l + 1) <= 32) {
f1ea739b 4801 o->in2 = tcg_constant_i64(0);
d074ac6d
RH
4802
4803 l++;
4804 while (l >= 8) {
4805 tcg_gen_qemu_st64(o->in2, o->addr1, get_mem_index(s));
4806 l -= 8;
4807 if (l > 0) {
4808 tcg_gen_addi_i64(o->addr1, o->addr1, 8);
4809 }
4810 }
4811 if (l >= 4) {
4812 tcg_gen_qemu_st32(o->in2, o->addr1, get_mem_index(s));
4813 l -= 4;
4814 if (l > 0) {
4815 tcg_gen_addi_i64(o->addr1, o->addr1, 4);
4816 }
4817 }
4818 if (l >= 2) {
4819 tcg_gen_qemu_st16(o->in2, o->addr1, get_mem_index(s));
4820 l -= 2;
4821 if (l > 0) {
4822 tcg_gen_addi_i64(o->addr1, o->addr1, 2);
4823 }
4824 }
4825 if (l) {
4826 tcg_gen_qemu_st8(o->in2, o->addr1, get_mem_index(s));
4827 }
4828 gen_op_movi_cc(s, 0);
21a8eced 4829 return DISAS_NEXT;
d074ac6d
RH
4830 }
4831
4832 /* But in general we'll defer to a helper. */
4833 o->in2 = get_address(s, 0, b2, d2);
f1ea739b 4834 t32 = tcg_constant_i32(l);
d074ac6d 4835 gen_helper_xc(cc_op, cpu_env, t32, o->addr1, o->in2);
0a949039 4836 set_cc_static(s);
21a8eced 4837 return DISAS_NEXT;
0a949039
RH
4838}
4839
21a8eced 4840static DisasJumpType op_xor(DisasContext *s, DisasOps *o)
3bbfbd1f
RH
4841{
4842 tcg_gen_xor_i64(o->out, o->in1, o->in2);
21a8eced 4843 return DISAS_NEXT;
3bbfbd1f
RH
4844}
4845
21a8eced 4846static DisasJumpType op_xori(DisasContext *s, DisasOps *o)
facfc864
RH
4847{
4848 int shift = s->insn->data & 0xff;
4849 int size = s->insn->data >> 8;
4850 uint64_t mask = ((1ull << size) - 1) << shift;
ab9984bd 4851 TCGv_i64 t = tcg_temp_new_i64();
facfc864 4852
ab9984bd
RH
4853 tcg_gen_shli_i64(t, o->in2, shift);
4854 tcg_gen_xor_i64(o->out, o->in1, t);
facfc864
RH
4855
4856 /* Produce the CC from only the bits manipulated. */
4857 tcg_gen_andi_i64(cc_dst, o->out, mask);
4858 set_cc_nz_u64(s, cc_dst);
21a8eced 4859 return DISAS_NEXT;
facfc864
RH
4860}
4861
21a8eced 4862static DisasJumpType op_xi(DisasContext *s, DisasOps *o)
f400be18
DH
4863{
4864 o->in1 = tcg_temp_new_i64();
4865
4866 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
4867 tcg_gen_qemu_ld_tl(o->in1, o->addr1, get_mem_index(s), s->insn->data);
4868 } else {
4869 /* Perform the atomic operation in memory. */
4870 tcg_gen_atomic_fetch_xor_i64(o->in1, o->addr1, o->in2, get_mem_index(s),
4871 s->insn->data);
4872 }
4873
4874 /* Recompute also for atomic case: needed for setting CC. */
4875 tcg_gen_xor_i64(o->out, o->in1, o->in2);
4876
4877 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
4878 tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), s->insn->data);
4879 }
21a8eced 4880 return DISAS_NEXT;
f400be18
DH
4881}
4882
21a8eced 4883static DisasJumpType op_zero(DisasContext *s, DisasOps *o)
24db8412 4884{
5bd9790e 4885 o->out = tcg_constant_i64(0);
21a8eced 4886 return DISAS_NEXT;
24db8412
RH
4887}
4888
21a8eced 4889static DisasJumpType op_zero2(DisasContext *s, DisasOps *o)
24db8412 4890{
5bd9790e 4891 o->out = tcg_constant_i64(0);
24db8412 4892 o->out2 = o->out;
21a8eced 4893 return DISAS_NEXT;
24db8412
RH
4894}
4895
f6c232ce 4896#ifndef CONFIG_USER_ONLY
21a8eced 4897static DisasJumpType op_clp(DisasContext *s, DisasOps *o)
f6c232ce 4898{
f1ea739b 4899 TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
f6c232ce 4900
f6c232ce 4901 gen_helper_clp(cpu_env, r2);
f6c232ce 4902 set_cc_static(s);
21a8eced 4903 return DISAS_NEXT;
f6c232ce
CH
4904}
4905
21a8eced 4906static DisasJumpType op_pcilg(DisasContext *s, DisasOps *o)
f6c232ce 4907{
f1ea739b
RH
4908 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4909 TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
f6c232ce 4910
f6c232ce 4911 gen_helper_pcilg(cpu_env, r1, r2);
f6c232ce 4912 set_cc_static(s);
21a8eced 4913 return DISAS_NEXT;
f6c232ce
CH
4914}
4915
21a8eced 4916static DisasJumpType op_pcistg(DisasContext *s, DisasOps *o)
f6c232ce 4917{
f1ea739b
RH
4918 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4919 TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
f6c232ce 4920
f6c232ce 4921 gen_helper_pcistg(cpu_env, r1, r2);
f6c232ce 4922 set_cc_static(s);
21a8eced 4923 return DISAS_NEXT;
f6c232ce
CH
4924}
4925
21a8eced 4926static DisasJumpType op_stpcifc(DisasContext *s, DisasOps *o)
f6c232ce 4927{
f1ea739b
RH
4928 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4929 TCGv_i32 ar = tcg_constant_i32(get_field(s, b2));
f6c232ce 4930
f6c232ce 4931 gen_helper_stpcifc(cpu_env, r1, o->addr1, ar);
f6c232ce 4932 set_cc_static(s);
21a8eced 4933 return DISAS_NEXT;
f6c232ce
CH
4934}
4935
21a8eced 4936static DisasJumpType op_sic(DisasContext *s, DisasOps *o)
f6c232ce 4937{
f6c232ce 4938 gen_helper_sic(cpu_env, o->in1, o->in2);
21a8eced 4939 return DISAS_NEXT;
f6c232ce
CH
4940}
4941
21a8eced 4942static DisasJumpType op_rpcit(DisasContext *s, DisasOps *o)
f6c232ce 4943{
f1ea739b
RH
4944 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4945 TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
f6c232ce 4946
f6c232ce 4947 gen_helper_rpcit(cpu_env, r1, r2);
f6c232ce 4948 set_cc_static(s);
21a8eced 4949 return DISAS_NEXT;
f6c232ce
CH
4950}
4951
21a8eced 4952static DisasJumpType op_pcistb(DisasContext *s, DisasOps *o)
f6c232ce 4953{
f1ea739b
RH
4954 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4955 TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
4956 TCGv_i32 ar = tcg_constant_i32(get_field(s, b2));
f6c232ce 4957
f6c232ce 4958 gen_helper_pcistb(cpu_env, r1, r3, o->addr1, ar);
f6c232ce 4959 set_cc_static(s);
21a8eced 4960 return DISAS_NEXT;
f6c232ce
CH
4961}
4962
21a8eced 4963static DisasJumpType op_mpcifc(DisasContext *s, DisasOps *o)
f6c232ce 4964{
f1ea739b
RH
4965 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4966 TCGv_i32 ar = tcg_constant_i32(get_field(s, b2));
f6c232ce 4967
f6c232ce 4968 gen_helper_mpcifc(cpu_env, r1, o->addr1, ar);
f6c232ce 4969 set_cc_static(s);
21a8eced 4970 return DISAS_NEXT;
f6c232ce
CH
4971}
4972#endif
4973
139c1837 4974#include "translate_vx.c.inc"
6d841663 4975
ad044d09
RH
4976/* ====================================================================== */
4977/* The "Cc OUTput" generators. Given the generated output (and in some cases
4978 the original inputs), update the various cc data structures in order to
4979 be able to compute the new condition code. */
4980
b9bca3e5
RH
4981static void cout_abs32(DisasContext *s, DisasOps *o)
4982{
4983 gen_op_update1_cc_i64(s, CC_OP_ABS_32, o->out);
4984}
4985
4986static void cout_abs64(DisasContext *s, DisasOps *o)
4987{
4988 gen_op_update1_cc_i64(s, CC_OP_ABS_64, o->out);
4989}
4990
ad044d09
RH
4991static void cout_adds32(DisasContext *s, DisasOps *o)
4992{
4993 gen_op_update3_cc_i64(s, CC_OP_ADD_32, o->in1, o->in2, o->out);
4994}
4995
4996static void cout_adds64(DisasContext *s, DisasOps *o)
4997{
4998 gen_op_update3_cc_i64(s, CC_OP_ADD_64, o->in1, o->in2, o->out);
4999}
5000
5001static void cout_addu32(DisasContext *s, DisasOps *o)
5002{
ff26d287
RH
5003 tcg_gen_shri_i64(cc_src, o->out, 32);
5004 tcg_gen_ext32u_i64(cc_dst, o->out);
5005 gen_op_update2_cc_i64(s, CC_OP_ADDU, cc_src, cc_dst);
ad044d09
RH
5006}
5007
5008static void cout_addu64(DisasContext *s, DisasOps *o)
5009{
ff26d287 5010 gen_op_update2_cc_i64(s, CC_OP_ADDU, cc_src, o->out);
ad044d09
RH
5011}
5012
a7e836d5
RH
5013static void cout_cmps32(DisasContext *s, DisasOps *o)
5014{
5015 gen_op_update2_cc_i64(s, CC_OP_LTGT_32, o->in1, o->in2);
5016}
5017
5018static void cout_cmps64(DisasContext *s, DisasOps *o)
5019{
5020 gen_op_update2_cc_i64(s, CC_OP_LTGT_64, o->in1, o->in2);
5021}
5022
5023static void cout_cmpu32(DisasContext *s, DisasOps *o)
5024{
5025 gen_op_update2_cc_i64(s, CC_OP_LTUGTU_32, o->in1, o->in2);
5026}
5027
5028static void cout_cmpu64(DisasContext *s, DisasOps *o)
5029{
5030 gen_op_update2_cc_i64(s, CC_OP_LTUGTU_64, o->in1, o->in2);
5031}
5032
587626f8
RH
5033static void cout_f32(DisasContext *s, DisasOps *o)
5034{
5035 gen_op_update1_cc_i64(s, CC_OP_NZ_F32, o->out);
5036}
5037
5038static void cout_f64(DisasContext *s, DisasOps *o)
5039{
5040 gen_op_update1_cc_i64(s, CC_OP_NZ_F64, o->out);
5041}
5042
5043static void cout_f128(DisasContext *s, DisasOps *o)
5044{
5045 gen_op_update2_cc_i64(s, CC_OP_NZ_F128, o->out, o->out2);
5046}
5047
b9bca3e5
RH
5048static void cout_nabs32(DisasContext *s, DisasOps *o)
5049{
5050 gen_op_update1_cc_i64(s, CC_OP_NABS_32, o->out);
5051}
5052
5053static void cout_nabs64(DisasContext *s, DisasOps *o)
5054{
5055 gen_op_update1_cc_i64(s, CC_OP_NABS_64, o->out);
5056}
5057
5058static void cout_neg32(DisasContext *s, DisasOps *o)
5059{
5060 gen_op_update1_cc_i64(s, CC_OP_COMP_32, o->out);
5061}
5062
5063static void cout_neg64(DisasContext *s, DisasOps *o)
5064{
5065 gen_op_update1_cc_i64(s, CC_OP_COMP_64, o->out);
5066}
5067
3bbfbd1f
RH
5068static void cout_nz32(DisasContext *s, DisasOps *o)
5069{
5070 tcg_gen_ext32u_i64(cc_dst, o->out);
5071 gen_op_update1_cc_i64(s, CC_OP_NZ, cc_dst);
5072}
5073
5074static void cout_nz64(DisasContext *s, DisasOps *o)
5075{
5076 gen_op_update1_cc_i64(s, CC_OP_NZ, o->out);
5077}
5078
11bf2d73
RH
5079static void cout_s32(DisasContext *s, DisasOps *o)
5080{
5081 gen_op_update1_cc_i64(s, CC_OP_LTGT0_32, o->out);
5082}
5083
5084static void cout_s64(DisasContext *s, DisasOps *o)
5085{
5086 gen_op_update1_cc_i64(s, CC_OP_LTGT0_64, o->out);
5087}
5088
ad044d09
RH
5089static void cout_subs32(DisasContext *s, DisasOps *o)
5090{
5091 gen_op_update3_cc_i64(s, CC_OP_SUB_32, o->in1, o->in2, o->out);
5092}
5093
5094static void cout_subs64(DisasContext *s, DisasOps *o)
5095{
5096 gen_op_update3_cc_i64(s, CC_OP_SUB_64, o->in1, o->in2, o->out);
5097}
5098
5099static void cout_subu32(DisasContext *s, DisasOps *o)
5100{
a2db06da
RH
5101 tcg_gen_sari_i64(cc_src, o->out, 32);
5102 tcg_gen_ext32u_i64(cc_dst, o->out);
5103 gen_op_update2_cc_i64(s, CC_OP_SUBU, cc_src, cc_dst);
ad044d09
RH
5104}
5105
5106static void cout_subu64(DisasContext *s, DisasOps *o)
5107{
a2db06da 5108 gen_op_update2_cc_i64(s, CC_OP_SUBU, cc_src, o->out);
ad044d09
RH
5109}
5110
00d2dc19
RH
5111static void cout_tm32(DisasContext *s, DisasOps *o)
5112{
5113 gen_op_update2_cc_i64(s, CC_OP_TM_32, o->in1, o->in2);
5114}
5115
5116static void cout_tm64(DisasContext *s, DisasOps *o)
5117{
5118 gen_op_update2_cc_i64(s, CC_OP_TM_64, o->in1, o->in2);
5119}
5120
b1feeb87
DH
5121static void cout_muls32(DisasContext *s, DisasOps *o)
5122{
5123 gen_op_update1_cc_i64(s, CC_OP_MULS_32, o->out);
5124}
5125
5126static void cout_muls64(DisasContext *s, DisasOps *o)
5127{
5128 /* out contains "high" part, out2 contains "low" part of 128 bit result */
5129 gen_op_update2_cc_i64(s, CC_OP_MULS_64, o->out, o->out2);
5130}
5131
ad044d09 5132/* ====================================================================== */
805a2505 5133/* The "PREParation" generators. These initialize the DisasOps.OUT fields
ad044d09
RH
5134 with the TCG register to which we will write. Used in combination with
5135 the "wout" generators, in some cases we need a new temporary, and in
5136 some cases we can write to a TCG global. */
5137
3f68884b 5138static void prep_new(DisasContext *s, DisasOps *o)
ad044d09
RH
5139{
5140 o->out = tcg_temp_new_i64();
5141}
49f7ee80 5142#define SPEC_prep_new 0
ad044d09 5143
3f68884b 5144static void prep_new_P(DisasContext *s, DisasOps *o)
891452e5
RH
5145{
5146 o->out = tcg_temp_new_i64();
5147 o->out2 = tcg_temp_new_i64();
5148}
49f7ee80 5149#define SPEC_prep_new_P 0
891452e5 5150
ee5e866f
RH
5151static void prep_new_x(DisasContext *s, DisasOps *o)
5152{
ee5e866f
RH
5153 o->out_128 = tcg_temp_new_i128();
5154}
5155#define SPEC_prep_new_x 0
5156
3f68884b 5157static void prep_r1(DisasContext *s, DisasOps *o)
ad044d09 5158{
c30988d1 5159 o->out = regs[get_field(s, r1)];
ad044d09 5160}
49f7ee80 5161#define SPEC_prep_r1 0
ad044d09 5162
3f68884b 5163static void prep_r1_P(DisasContext *s, DisasOps *o)
1ac5889f 5164{
c30988d1 5165 int r1 = get_field(s, r1);
1ac5889f 5166 o->out = regs[r1];
49f7ee80 5167 o->out2 = regs[r1 + 1];
1ac5889f 5168}
49f7ee80 5169#define SPEC_prep_r1_P SPEC_r1_even
1ac5889f 5170
3f68884b 5171static void prep_x1(DisasContext *s, DisasOps *o)
587626f8 5172{
2b91240f 5173 o->out_128 = load_freg_128(get_field(s, r1));
587626f8 5174}
49f7ee80 5175#define SPEC_prep_x1 SPEC_r1_f128
587626f8 5176
ad044d09
RH
5177/* ====================================================================== */
5178/* The "Write OUTput" generators. These generally perform some non-trivial
5179 copy of data to TCG globals, or to main memory. The trivial cases are
5180 generally handled by having a "prep" generator install the TCG global
5181 as the destination of the operation. */
5182
3f68884b 5183static void wout_r1(DisasContext *s, DisasOps *o)
22c37a08 5184{
c30988d1 5185 store_reg(get_field(s, r1), o->out);
22c37a08 5186}
49f7ee80 5187#define SPEC_wout_r1 0
22c37a08 5188
b1feeb87
DH
5189static void wout_out2_r1(DisasContext *s, DisasOps *o)
5190{
5191 store_reg(get_field(s, r1), o->out2);
5192}
5193#define SPEC_wout_out2_r1 0
5194
3f68884b 5195static void wout_r1_8(DisasContext *s, DisasOps *o)
afdc70be 5196{
c30988d1 5197 int r1 = get_field(s, r1);
afdc70be
RH
5198 tcg_gen_deposit_i64(regs[r1], regs[r1], o->out, 0, 8);
5199}
49f7ee80 5200#define SPEC_wout_r1_8 0
afdc70be 5201
3f68884b 5202static void wout_r1_16(DisasContext *s, DisasOps *o)
d54f5865 5203{
c30988d1 5204 int r1 = get_field(s, r1);
d54f5865
RH
5205 tcg_gen_deposit_i64(regs[r1], regs[r1], o->out, 0, 16);
5206}
49f7ee80 5207#define SPEC_wout_r1_16 0
d54f5865 5208
3f68884b 5209static void wout_r1_32(DisasContext *s, DisasOps *o)
ad044d09 5210{
c30988d1 5211 store_reg32_i64(get_field(s, r1), o->out);
ad044d09 5212}
49f7ee80 5213#define SPEC_wout_r1_32 0
ad044d09 5214
3f68884b 5215static void wout_r1_32h(DisasContext *s, DisasOps *o)
a1f12d85 5216{
c30988d1 5217 store_reg32h_i64(get_field(s, r1), o->out);
a1f12d85
AJ
5218}
5219#define SPEC_wout_r1_32h 0
5220
3f68884b 5221static void wout_r1_P32(DisasContext *s, DisasOps *o)
891452e5 5222{
c30988d1 5223 int r1 = get_field(s, r1);
891452e5 5224 store_reg32_i64(r1, o->out);
49f7ee80 5225 store_reg32_i64(r1 + 1, o->out2);
891452e5 5226}
49f7ee80 5227#define SPEC_wout_r1_P32 SPEC_r1_even
891452e5 5228
3f68884b 5229static void wout_r1_D32(DisasContext *s, DisasOps *o)
d87aaf93 5230{
c30988d1 5231 int r1 = get_field(s, r1);
57556b28 5232 TCGv_i64 t = tcg_temp_new_i64();
49f7ee80 5233 store_reg32_i64(r1 + 1, o->out);
57556b28
IL
5234 tcg_gen_shri_i64(t, o->out, 32);
5235 store_reg32_i64(r1, t);
d87aaf93 5236}
49f7ee80 5237#define SPEC_wout_r1_D32 SPEC_r1_even
22c37a08 5238
1fcd84fa
RH
5239static void wout_r1_D64(DisasContext *s, DisasOps *o)
5240{
5241 int r1 = get_field(s, r1);
5242 tcg_gen_extr_i128_i64(regs[r1 + 1], regs[r1], o->out_128);
5243}
5244#define SPEC_wout_r1_D64 SPEC_r1_even
5245
3f68884b 5246static void wout_r3_P32(DisasContext *s, DisasOps *o)
1807aaa5 5247{
c30988d1 5248 int r3 = get_field(s, r3);
1807aaa5
EB
5249 store_reg32_i64(r3, o->out);
5250 store_reg32_i64(r3 + 1, o->out2);
5251}
5252#define SPEC_wout_r3_P32 SPEC_r3_even
5253
3f68884b 5254static void wout_r3_P64(DisasContext *s, DisasOps *o)
1807aaa5 5255{
c30988d1 5256 int r3 = get_field(s, r3);
1807aaa5
EB
5257 store_reg(r3, o->out);
5258 store_reg(r3 + 1, o->out2);
5259}
5260#define SPEC_wout_r3_P64 SPEC_r3_even
5261
3f68884b 5262static void wout_e1(DisasContext *s, DisasOps *o)
d764a8d1 5263{
c30988d1 5264 store_freg32_i64(get_field(s, r1), o->out);
d764a8d1 5265}
49f7ee80 5266#define SPEC_wout_e1 0
d764a8d1 5267
3f68884b 5268static void wout_f1(DisasContext *s, DisasOps *o)
d764a8d1 5269{
c30988d1 5270 store_freg(get_field(s, r1), o->out);
d764a8d1 5271}
49f7ee80 5272#define SPEC_wout_f1 0
d764a8d1 5273
3f68884b 5274static void wout_x1(DisasContext *s, DisasOps *o)
d764a8d1 5275{
c30988d1 5276 int f1 = get_field(s, r1);
ee5e866f 5277
2b91240f
RH
5278 /* Split out_128 into out+out2 for cout_f128. */
5279 tcg_debug_assert(o->out == NULL);
5280 o->out = tcg_temp_new_i64();
5281 o->out2 = tcg_temp_new_i64();
5282
ee5e866f 5283 tcg_gen_extr_i128_i64(o->out2, o->out, o->out_128);
d764a8d1 5284 store_freg(f1, o->out);
49f7ee80 5285 store_freg(f1 + 2, o->out2);
d764a8d1 5286}
49f7ee80 5287#define SPEC_wout_x1 SPEC_r1_f128
d764a8d1 5288
f4031d96
RH
5289static void wout_x1_P(DisasContext *s, DisasOps *o)
5290{
5291 int f1 = get_field(s, r1);
5292 store_freg(f1, o->out);
5293 store_freg(f1 + 2, o->out2);
5294}
5295#define SPEC_wout_x1_P SPEC_r1_f128
5296
3f68884b 5297static void wout_cond_r1r2_32(DisasContext *s, DisasOps *o)
22c37a08 5298{
c30988d1
RH
5299 if (get_field(s, r1) != get_field(s, r2)) {
5300 store_reg32_i64(get_field(s, r1), o->out);
22c37a08
RH
5301 }
5302}
49f7ee80 5303#define SPEC_wout_cond_r1r2_32 0
d87aaf93 5304
3f68884b 5305static void wout_cond_e1e2(DisasContext *s, DisasOps *o)
d764a8d1 5306{
c30988d1
RH
5307 if (get_field(s, r1) != get_field(s, r2)) {
5308 store_freg32_i64(get_field(s, r1), o->out);
d764a8d1
RH
5309 }
5310}
49f7ee80 5311#define SPEC_wout_cond_e1e2 0
d764a8d1 5312
3f68884b 5313static void wout_m1_8(DisasContext *s, DisasOps *o)
6a04d76a
RH
5314{
5315 tcg_gen_qemu_st8(o->out, o->addr1, get_mem_index(s));
5316}
49f7ee80 5317#define SPEC_wout_m1_8 0
6a04d76a 5318
3f68884b 5319static void wout_m1_16(DisasContext *s, DisasOps *o)
6a04d76a
RH
5320{
5321 tcg_gen_qemu_st16(o->out, o->addr1, get_mem_index(s));
5322}
49f7ee80 5323#define SPEC_wout_m1_16 0
6a04d76a 5324
21fc97c5 5325#ifndef CONFIG_USER_ONLY
3f68884b 5326static void wout_m1_16a(DisasContext *s, DisasOps *o)
21fc97c5
DH
5327{
5328 tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), MO_TEUW | MO_ALIGN);
5329}
5330#define SPEC_wout_m1_16a 0
5331#endif
5332
3f68884b 5333static void wout_m1_32(DisasContext *s, DisasOps *o)
ad044d09
RH
5334{
5335 tcg_gen_qemu_st32(o->out, o->addr1, get_mem_index(s));
5336}
49f7ee80 5337#define SPEC_wout_m1_32 0
ad044d09 5338
21fc97c5 5339#ifndef CONFIG_USER_ONLY
3f68884b 5340static void wout_m1_32a(DisasContext *s, DisasOps *o)
21fc97c5
DH
5341{
5342 tcg_gen_qemu_st_tl(o->out, o->addr1, get_mem_index(s), MO_TEUL | MO_ALIGN);
5343}
5344#define SPEC_wout_m1_32a 0
5345#endif
5346
3f68884b 5347static void wout_m1_64(DisasContext *s, DisasOps *o)
ad044d09
RH
5348{
5349 tcg_gen_qemu_st64(o->out, o->addr1, get_mem_index(s));
5350}
49f7ee80 5351#define SPEC_wout_m1_64 0
ad044d09 5352
21fc97c5 5353#ifndef CONFIG_USER_ONLY
3f68884b 5354static void wout_m1_64a(DisasContext *s, DisasOps *o)
21fc97c5 5355{
fc313c64 5356 tcg_gen_qemu_st_i64(o->out, o->addr1, get_mem_index(s), MO_TEUQ | MO_ALIGN);
21fc97c5
DH
5357}
5358#define SPEC_wout_m1_64a 0
5359#endif
5360
3f68884b 5361static void wout_m2_32(DisasContext *s, DisasOps *o)
ea20490f
RH
5362{
5363 tcg_gen_qemu_st32(o->out, o->in2, get_mem_index(s));
5364}
49f7ee80 5365#define SPEC_wout_m2_32 0
ea20490f 5366
3f68884b 5367static void wout_in2_r1(DisasContext *s, DisasOps *o)
57af7289 5368{
c30988d1 5369 store_reg(get_field(s, r1), o->in2);
57af7289 5370}
4dba4d6f 5371#define SPEC_wout_in2_r1 0
57af7289 5372
3f68884b 5373static void wout_in2_r1_32(DisasContext *s, DisasOps *o)
57af7289 5374{
c30988d1 5375 store_reg32_i64(get_field(s, r1), o->in2);
57af7289 5376}
4dba4d6f 5377#define SPEC_wout_in2_r1_32 0
57af7289 5378
ad044d09
RH
5379/* ====================================================================== */
5380/* The "INput 1" generators. These load the first operand to an insn. */
5381
3f68884b 5382static void in1_r1(DisasContext *s, DisasOps *o)
ad044d09 5383{
c30988d1 5384 o->in1 = load_reg(get_field(s, r1));
ad044d09 5385}
49f7ee80 5386#define SPEC_in1_r1 0
ad044d09 5387
3f68884b 5388static void in1_r1_o(DisasContext *s, DisasOps *o)
d1c04a2b 5389{
c30988d1 5390 o->in1 = regs[get_field(s, r1)];
d1c04a2b 5391}
49f7ee80 5392#define SPEC_in1_r1_o 0
d1c04a2b 5393
3f68884b 5394static void in1_r1_32s(DisasContext *s, DisasOps *o)
cbe24bfa
RH
5395{
5396 o->in1 = tcg_temp_new_i64();
c30988d1 5397 tcg_gen_ext32s_i64(o->in1, regs[get_field(s, r1)]);
cbe24bfa 5398}
49f7ee80 5399#define SPEC_in1_r1_32s 0
cbe24bfa 5400
3f68884b 5401static void in1_r1_32u(DisasContext *s, DisasOps *o)
cbe24bfa
RH
5402{
5403 o->in1 = tcg_temp_new_i64();
c30988d1 5404 tcg_gen_ext32u_i64(o->in1, regs[get_field(s, r1)]);
cbe24bfa 5405}
49f7ee80 5406#define SPEC_in1_r1_32u 0
cbe24bfa 5407
3f68884b 5408static void in1_r1_sr32(DisasContext *s, DisasOps *o)
32a44d58
RH
5409{
5410 o->in1 = tcg_temp_new_i64();
c30988d1 5411 tcg_gen_shri_i64(o->in1, regs[get_field(s, r1)], 32);
32a44d58 5412}
49f7ee80 5413#define SPEC_in1_r1_sr32 0
32a44d58 5414
3f68884b 5415static void in1_r1p1(DisasContext *s, DisasOps *o)
1ac5889f 5416{
c30988d1 5417 o->in1 = load_reg(get_field(s, r1) + 1);
1ac5889f 5418}
49f7ee80 5419#define SPEC_in1_r1p1 SPEC_r1_even
1ac5889f 5420
fa5e82cc
DH
5421static void in1_r1p1_o(DisasContext *s, DisasOps *o)
5422{
5423 o->in1 = regs[get_field(s, r1) + 1];
fa5e82cc
DH
5424}
5425#define SPEC_in1_r1p1_o SPEC_r1_even
5426
3f68884b 5427static void in1_r1p1_32s(DisasContext *s, DisasOps *o)
d87aaf93 5428{
d87aaf93 5429 o->in1 = tcg_temp_new_i64();
c30988d1 5430 tcg_gen_ext32s_i64(o->in1, regs[get_field(s, r1) + 1]);
d87aaf93 5431}
49f7ee80 5432#define SPEC_in1_r1p1_32s SPEC_r1_even
d87aaf93 5433
3f68884b 5434static void in1_r1p1_32u(DisasContext *s, DisasOps *o)
d87aaf93 5435{
d87aaf93 5436 o->in1 = tcg_temp_new_i64();
c30988d1 5437 tcg_gen_ext32u_i64(o->in1, regs[get_field(s, r1) + 1]);
d87aaf93 5438}
49f7ee80 5439#define SPEC_in1_r1p1_32u SPEC_r1_even
d87aaf93 5440
3f68884b 5441static void in1_r1_D32(DisasContext *s, DisasOps *o)
891452e5 5442{
c30988d1 5443 int r1 = get_field(s, r1);
891452e5
RH
5444 o->in1 = tcg_temp_new_i64();
5445 tcg_gen_concat32_i64(o->in1, regs[r1 + 1], regs[r1]);
5446}
49f7ee80 5447#define SPEC_in1_r1_D32 SPEC_r1_even
891452e5 5448
3f68884b 5449static void in1_r2(DisasContext *s, DisasOps *o)
ad044d09 5450{
c30988d1 5451 o->in1 = load_reg(get_field(s, r2));
ad044d09 5452}
49f7ee80 5453#define SPEC_in1_r2 0
ad044d09 5454
3f68884b 5455static void in1_r2_sr32(DisasContext *s, DisasOps *o)
a1f12d85
AJ
5456{
5457 o->in1 = tcg_temp_new_i64();
c30988d1 5458 tcg_gen_shri_i64(o->in1, regs[get_field(s, r2)], 32);
a1f12d85
AJ
5459}
5460#define SPEC_in1_r2_sr32 0
5461
ff26d287
RH
5462static void in1_r2_32u(DisasContext *s, DisasOps *o)
5463{
5464 o->in1 = tcg_temp_new_i64();
5465 tcg_gen_ext32u_i64(o->in1, regs[get_field(s, r2)]);
5466}
5467#define SPEC_in1_r2_32u 0
5468
3f68884b 5469static void in1_r3(DisasContext *s, DisasOps *o)
ad044d09 5470{
c30988d1 5471 o->in1 = load_reg(get_field(s, r3));
ad044d09 5472}
49f7ee80 5473#define SPEC_in1_r3 0
ad044d09 5474
3f68884b 5475static void in1_r3_o(DisasContext *s, DisasOps *o)
cbe24bfa 5476{
c30988d1 5477 o->in1 = regs[get_field(s, r3)];
cbe24bfa 5478}
49f7ee80 5479#define SPEC_in1_r3_o 0
cbe24bfa 5480
3f68884b 5481static void in1_r3_32s(DisasContext *s, DisasOps *o)
cbe24bfa
RH
5482{
5483 o->in1 = tcg_temp_new_i64();
c30988d1 5484 tcg_gen_ext32s_i64(o->in1, regs[get_field(s, r3)]);
cbe24bfa 5485}
49f7ee80 5486#define SPEC_in1_r3_32s 0
cbe24bfa 5487
3f68884b 5488static void in1_r3_32u(DisasContext *s, DisasOps *o)
cbe24bfa
RH
5489{
5490 o->in1 = tcg_temp_new_i64();
c30988d1 5491 tcg_gen_ext32u_i64(o->in1, regs[get_field(s, r3)]);
cbe24bfa 5492}
49f7ee80 5493#define SPEC_in1_r3_32u 0
cbe24bfa 5494
3f68884b 5495static void in1_r3_D32(DisasContext *s, DisasOps *o)
b7886de3 5496{
c30988d1 5497 int r3 = get_field(s, r3);
b7886de3
RH
5498 o->in1 = tcg_temp_new_i64();
5499 tcg_gen_concat32_i64(o->in1, regs[r3 + 1], regs[r3]);
5500}
5501#define SPEC_in1_r3_D32 SPEC_r3_even
5502
ea0a1053
DM
5503static void in1_r3_sr32(DisasContext *s, DisasOps *o)
5504{
5505 o->in1 = tcg_temp_new_i64();
5506 tcg_gen_shri_i64(o->in1, regs[get_field(s, r3)], 32);
5507}
5508#define SPEC_in1_r3_sr32 0
5509
3f68884b 5510static void in1_e1(DisasContext *s, DisasOps *o)
00574261 5511{
c30988d1 5512 o->in1 = load_freg32_i64(get_field(s, r1));
00574261 5513}
49f7ee80 5514#define SPEC_in1_e1 0
00574261 5515
3f68884b 5516static void in1_f1(DisasContext *s, DisasOps *o)
00574261 5517{
c30988d1 5518 o->in1 = load_freg(get_field(s, r1));
00574261 5519}
80a7b759 5520#define SPEC_in1_f1 0
00574261 5521
2b91240f
RH
5522static void in1_x1(DisasContext *s, DisasOps *o)
5523{
5524 o->in1_128 = load_freg_128(get_field(s, r1));
5525}
5526#define SPEC_in1_x1 SPEC_r1_f128
5527
80a7b759 5528/* Load the high double word of an extended (128-bit) format FP number */
3f68884b 5529static void in1_x2h(DisasContext *s, DisasOps *o)
587626f8 5530{
c30988d1 5531 o->in1 = load_freg(get_field(s, r2));
587626f8 5532}
80a7b759 5533#define SPEC_in1_x2h SPEC_r2_f128
587626f8 5534
3f68884b 5535static void in1_f3(DisasContext *s, DisasOps *o)
2db014b5 5536{
c30988d1 5537 o->in1 = load_freg(get_field(s, r3));
2db014b5 5538}
80a7b759 5539#define SPEC_in1_f3 0
2db014b5 5540
3f68884b 5541static void in1_la1(DisasContext *s, DisasOps *o)
ad044d09 5542{
c30988d1 5543 o->addr1 = get_address(s, 0, get_field(s, b1), get_field(s, d1));
ad044d09 5544}
49f7ee80 5545#define SPEC_in1_la1 0
ad044d09 5546
3f68884b 5547static void in1_la2(DisasContext *s, DisasOps *o)
e025e52a 5548{
c30988d1
RH
5549 int x2 = have_field(s, x2) ? get_field(s, x2) : 0;
5550 o->addr1 = get_address(s, x2, get_field(s, b2), get_field(s, d2));
e025e52a 5551}
49f7ee80 5552#define SPEC_in1_la2 0
e025e52a 5553
3f68884b 5554static void in1_m1_8u(DisasContext *s, DisasOps *o)
a7e836d5 5555{
3f68884b 5556 in1_la1(s, o);
a7e836d5
RH
5557 o->in1 = tcg_temp_new_i64();
5558 tcg_gen_qemu_ld8u(o->in1, o->addr1, get_mem_index(s));
5559}
49f7ee80 5560#define SPEC_in1_m1_8u 0
a7e836d5 5561
3f68884b 5562static void in1_m1_16s(DisasContext *s, DisasOps *o)
a7e836d5 5563{
3f68884b 5564 in1_la1(s, o);
a7e836d5
RH
5565 o->in1 = tcg_temp_new_i64();
5566 tcg_gen_qemu_ld16s(o->in1, o->addr1, get_mem_index(s));
5567}
49f7ee80 5568#define SPEC_in1_m1_16s 0
a7e836d5 5569
3f68884b 5570static void in1_m1_16u(DisasContext *s, DisasOps *o)
a7e836d5 5571{
3f68884b 5572 in1_la1(s, o);
a7e836d5
RH
5573 o->in1 = tcg_temp_new_i64();
5574 tcg_gen_qemu_ld16u(o->in1, o->addr1, get_mem_index(s));
5575}
49f7ee80 5576#define SPEC_in1_m1_16u 0
a7e836d5 5577
3f68884b 5578static void in1_m1_32s(DisasContext *s, DisasOps *o)
ad044d09 5579{
3f68884b 5580 in1_la1(s, o);
ad044d09
RH
5581 o->in1 = tcg_temp_new_i64();
5582 tcg_gen_qemu_ld32s(o->in1, o->addr1, get_mem_index(s));
5583}
49f7ee80 5584#define SPEC_in1_m1_32s 0
ad044d09 5585
3f68884b 5586static void in1_m1_32u(DisasContext *s, DisasOps *o)
e272b3ac 5587{
3f68884b 5588 in1_la1(s, o);
e272b3ac
RH
5589 o->in1 = tcg_temp_new_i64();
5590 tcg_gen_qemu_ld32u(o->in1, o->addr1, get_mem_index(s));
5591}
49f7ee80 5592#define SPEC_in1_m1_32u 0
e272b3ac 5593
3f68884b 5594static void in1_m1_64(DisasContext *s, DisasOps *o)
ad044d09 5595{
3f68884b 5596 in1_la1(s, o);
ad044d09
RH
5597 o->in1 = tcg_temp_new_i64();
5598 tcg_gen_qemu_ld64(o->in1, o->addr1, get_mem_index(s));
5599}
49f7ee80 5600#define SPEC_in1_m1_64 0
ad044d09
RH
5601
5602/* ====================================================================== */
5603/* The "INput 2" generators. These load the second operand to an insn. */
5604
3f68884b 5605static void in2_r1_o(DisasContext *s, DisasOps *o)
e025e52a 5606{
c30988d1 5607 o->in2 = regs[get_field(s, r1)];
e025e52a 5608}
49f7ee80 5609#define SPEC_in2_r1_o 0
e025e52a 5610
3f68884b 5611static void in2_r1_16u(DisasContext *s, DisasOps *o)
e025e52a
RH
5612{
5613 o->in2 = tcg_temp_new_i64();
c30988d1 5614 tcg_gen_ext16u_i64(o->in2, regs[get_field(s, r1)]);
e025e52a 5615}
49f7ee80 5616#define SPEC_in2_r1_16u 0
e025e52a 5617
3f68884b 5618static void in2_r1_32u(DisasContext *s, DisasOps *o)
e025e52a
RH
5619{
5620 o->in2 = tcg_temp_new_i64();
c30988d1 5621 tcg_gen_ext32u_i64(o->in2, regs[get_field(s, r1)]);
e025e52a 5622}
49f7ee80 5623#define SPEC_in2_r1_32u 0
e025e52a 5624
3f68884b 5625static void in2_r1_D32(DisasContext *s, DisasOps *o)
b7886de3 5626{
c30988d1 5627 int r1 = get_field(s, r1);
b7886de3
RH
5628 o->in2 = tcg_temp_new_i64();
5629 tcg_gen_concat32_i64(o->in2, regs[r1 + 1], regs[r1]);
5630}
5631#define SPEC_in2_r1_D32 SPEC_r1_even
5632
3f68884b 5633static void in2_r2(DisasContext *s, DisasOps *o)
ad044d09 5634{
c30988d1 5635 o->in2 = load_reg(get_field(s, r2));
ad044d09 5636}
49f7ee80 5637#define SPEC_in2_r2 0
ad044d09 5638
3f68884b 5639static void in2_r2_o(DisasContext *s, DisasOps *o)
d1c04a2b 5640{
c30988d1 5641 o->in2 = regs[get_field(s, r2)];
d1c04a2b 5642}
49f7ee80 5643#define SPEC_in2_r2_o 0
d1c04a2b 5644
3f68884b 5645static void in2_r2_nz(DisasContext *s, DisasOps *o)
8ac33cdb 5646{
c30988d1 5647 int r2 = get_field(s, r2);
8ac33cdb
RH
5648 if (r2 != 0) {
5649 o->in2 = load_reg(r2);
5650 }
5651}
49f7ee80 5652#define SPEC_in2_r2_nz 0
8ac33cdb 5653
3f68884b 5654static void in2_r2_8s(DisasContext *s, DisasOps *o)
c698d876
RH
5655{
5656 o->in2 = tcg_temp_new_i64();
c30988d1 5657 tcg_gen_ext8s_i64(o->in2, regs[get_field(s, r2)]);
c698d876 5658}
49f7ee80 5659#define SPEC_in2_r2_8s 0
c698d876 5660
3f68884b 5661static void in2_r2_8u(DisasContext *s, DisasOps *o)
c698d876
RH
5662{
5663 o->in2 = tcg_temp_new_i64();
c30988d1 5664 tcg_gen_ext8u_i64(o->in2, regs[get_field(s, r2)]);
c698d876 5665}
49f7ee80 5666#define SPEC_in2_r2_8u 0
c698d876 5667
3f68884b 5668static void in2_r2_16s(DisasContext *s, DisasOps *o)
c698d876
RH
5669{
5670 o->in2 = tcg_temp_new_i64();
c30988d1 5671 tcg_gen_ext16s_i64(o->in2, regs[get_field(s, r2)]);
c698d876 5672}
49f7ee80 5673#define SPEC_in2_r2_16s 0
c698d876 5674
3f68884b 5675static void in2_r2_16u(DisasContext *s, DisasOps *o)
c698d876
RH
5676{
5677 o->in2 = tcg_temp_new_i64();
c30988d1 5678 tcg_gen_ext16u_i64(o->in2, regs[get_field(s, r2)]);
c698d876 5679}
49f7ee80 5680#define SPEC_in2_r2_16u 0
c698d876 5681
3f68884b 5682static void in2_r3(DisasContext *s, DisasOps *o)
ad044d09 5683{
c30988d1 5684 o->in2 = load_reg(get_field(s, r3));
ad044d09 5685}
49f7ee80 5686#define SPEC_in2_r3 0
ad044d09 5687
1fcd84fa
RH
5688static void in2_r3_D64(DisasContext *s, DisasOps *o)
5689{
5690 int r3 = get_field(s, r3);
5691 o->in2_128 = tcg_temp_new_i128();
5692 tcg_gen_concat_i64_i128(o->in2_128, regs[r3 + 1], regs[r3]);
5693}
5694#define SPEC_in2_r3_D64 SPEC_r3_even
5695
3f68884b 5696static void in2_r3_sr32(DisasContext *s, DisasOps *o)
a1f12d85
AJ
5697{
5698 o->in2 = tcg_temp_new_i64();
c30988d1 5699 tcg_gen_shri_i64(o->in2, regs[get_field(s, r3)], 32);
a1f12d85
AJ
5700}
5701#define SPEC_in2_r3_sr32 0
5702
3f68884b 5703static void in2_r3_32u(DisasContext *s, DisasOps *o)
f6c7ff67
DH
5704{
5705 o->in2 = tcg_temp_new_i64();
c30988d1 5706 tcg_gen_ext32u_i64(o->in2, regs[get_field(s, r3)]);
f6c7ff67
DH
5707}
5708#define SPEC_in2_r3_32u 0
5709
3f68884b 5710static void in2_r2_32s(DisasContext *s, DisasOps *o)
ad044d09
RH
5711{
5712 o->in2 = tcg_temp_new_i64();
c30988d1 5713 tcg_gen_ext32s_i64(o->in2, regs[get_field(s, r2)]);
ad044d09 5714}
49f7ee80 5715#define SPEC_in2_r2_32s 0
ad044d09 5716
3f68884b 5717static void in2_r2_32u(DisasContext *s, DisasOps *o)
ad044d09
RH
5718{
5719 o->in2 = tcg_temp_new_i64();
c30988d1 5720 tcg_gen_ext32u_i64(o->in2, regs[get_field(s, r2)]);
ad044d09 5721}
49f7ee80 5722#define SPEC_in2_r2_32u 0
ad044d09 5723
3f68884b 5724static void in2_r2_sr32(DisasContext *s, DisasOps *o)
a1f12d85
AJ
5725{
5726 o->in2 = tcg_temp_new_i64();
c30988d1 5727 tcg_gen_shri_i64(o->in2, regs[get_field(s, r2)], 32);
a1f12d85
AJ
5728}
5729#define SPEC_in2_r2_sr32 0
5730
3f68884b 5731static void in2_e2(DisasContext *s, DisasOps *o)
d764a8d1 5732{
c30988d1 5733 o->in2 = load_freg32_i64(get_field(s, r2));
d764a8d1 5734}
49f7ee80 5735#define SPEC_in2_e2 0
d764a8d1 5736
3f68884b 5737static void in2_f2(DisasContext *s, DisasOps *o)
d764a8d1 5738{
c30988d1 5739 o->in2 = load_freg(get_field(s, r2));
d764a8d1 5740}
80a7b759 5741#define SPEC_in2_f2 0
d764a8d1 5742
2b91240f
RH
5743static void in2_x2(DisasContext *s, DisasOps *o)
5744{
5745 o->in2_128 = load_freg_128(get_field(s, r2));
5746}
5747#define SPEC_in2_x2 SPEC_r2_f128
5748
80a7b759 5749/* Load the low double word of an extended (128-bit) format FP number */
3f68884b 5750static void in2_x2l(DisasContext *s, DisasOps *o)
d764a8d1 5751{
c30988d1 5752 o->in2 = load_freg(get_field(s, r2) + 2);
d764a8d1 5753}
80a7b759 5754#define SPEC_in2_x2l SPEC_r2_f128
d764a8d1 5755
3f68884b 5756static void in2_ra2(DisasContext *s, DisasOps *o)
374724f9 5757{
401bf467
DH
5758 int r2 = get_field(s, r2);
5759
5760 /* Note: *don't* treat !r2 as 0, use the reg value. */
5761 o->in2 = tcg_temp_new_i64();
5762 gen_addi_and_wrap_i64(s, o->in2, regs[r2], 0);
374724f9 5763}
49f7ee80 5764#define SPEC_in2_ra2 0
374724f9 5765
3f68884b 5766static void in2_a2(DisasContext *s, DisasOps *o)
ad044d09 5767{
c30988d1
RH
5768 int x2 = have_field(s, x2) ? get_field(s, x2) : 0;
5769 o->in2 = get_address(s, x2, get_field(s, b2), get_field(s, d2));
ad044d09 5770}
49f7ee80 5771#define SPEC_in2_a2 0
ad044d09 5772
bdbc87e3
RH
5773static TCGv gen_ri2(DisasContext *s)
5774{
703d03a4
IL
5775 int64_t delta = (int64_t)get_field(s, i2) * 2;
5776 TCGv ri2;
5777
5778 if (unlikely(s->ex_value)) {
5779 ri2 = tcg_temp_new_i64();
5780 tcg_gen_ld_i64(ri2, cpu_env, offsetof(CPUS390XState, ex_target));
5781 tcg_gen_addi_i64(ri2, ri2, delta);
5782 } else {
5783 ri2 = tcg_constant_i64(s->base.pc_next + delta);
5784 }
5785
5786 return ri2;
bdbc87e3
RH
5787}
5788
3f68884b 5789static void in2_ri2(DisasContext *s, DisasOps *o)
a7e836d5 5790{
bdbc87e3 5791 o->in2 = gen_ri2(s);
a7e836d5 5792}
49f7ee80 5793#define SPEC_in2_ri2 0
a7e836d5 5794
6da170be 5795static void in2_sh(DisasContext *s, DisasOps *o)
cbe24bfa 5796{
6da170be
IL
5797 int b2 = get_field(s, b2);
5798 int d2 = get_field(s, d2);
cbe24bfa 5799
6da170be 5800 if (b2 == 0) {
5bd9790e 5801 o->in2 = tcg_constant_i64(d2 & 0x3f);
6da170be
IL
5802 } else {
5803 o->in2 = get_address(s, 0, b2, d2);
5804 tcg_gen_andi_i64(o->in2, o->in2, 0x3f);
5805 }
cbe24bfa 5806}
6da170be 5807#define SPEC_in2_sh 0
cbe24bfa 5808
3f68884b 5809static void in2_m2_8u(DisasContext *s, DisasOps *o)
afdc70be 5810{
3f68884b 5811 in2_a2(s, o);
afdc70be
RH
5812 tcg_gen_qemu_ld8u(o->in2, o->in2, get_mem_index(s));
5813}
49f7ee80 5814#define SPEC_in2_m2_8u 0
afdc70be 5815
3f68884b 5816static void in2_m2_16s(DisasContext *s, DisasOps *o)
d82287de 5817{
3f68884b 5818 in2_a2(s, o);
d82287de
RH
5819 tcg_gen_qemu_ld16s(o->in2, o->in2, get_mem_index(s));
5820}
49f7ee80 5821#define SPEC_in2_m2_16s 0
d82287de 5822
3f68884b 5823static void in2_m2_16u(DisasContext *s, DisasOps *o)
d54f5865 5824{
3f68884b 5825 in2_a2(s, o);
d54f5865
RH
5826 tcg_gen_qemu_ld16u(o->in2, o->in2, get_mem_index(s));
5827}
49f7ee80 5828#define SPEC_in2_m2_16u 0
d54f5865 5829
3f68884b 5830static void in2_m2_32s(DisasContext *s, DisasOps *o)
ad044d09 5831{
3f68884b 5832 in2_a2(s, o);
ad044d09
RH
5833 tcg_gen_qemu_ld32s(o->in2, o->in2, get_mem_index(s));
5834}
49f7ee80 5835#define SPEC_in2_m2_32s 0
ad044d09 5836
3f68884b 5837static void in2_m2_32u(DisasContext *s, DisasOps *o)
ad044d09 5838{
3f68884b 5839 in2_a2(s, o);
ad044d09
RH
5840 tcg_gen_qemu_ld32u(o->in2, o->in2, get_mem_index(s));
5841}
49f7ee80 5842#define SPEC_in2_m2_32u 0
ad044d09 5843
21fc97c5 5844#ifndef CONFIG_USER_ONLY
3f68884b 5845static void in2_m2_32ua(DisasContext *s, DisasOps *o)
21fc97c5 5846{
3f68884b 5847 in2_a2(s, o);
21fc97c5
DH
5848 tcg_gen_qemu_ld_tl(o->in2, o->in2, get_mem_index(s), MO_TEUL | MO_ALIGN);
5849}
5850#define SPEC_in2_m2_32ua 0
5851#endif
5852
3f68884b 5853static void in2_m2_64(DisasContext *s, DisasOps *o)
ad044d09 5854{
3f68884b 5855 in2_a2(s, o);
ad044d09
RH
5856 tcg_gen_qemu_ld64(o->in2, o->in2, get_mem_index(s));
5857}
49f7ee80 5858#define SPEC_in2_m2_64 0
ad044d09 5859
9131bd01
DH
5860static void in2_m2_64w(DisasContext *s, DisasOps *o)
5861{
5862 in2_a2(s, o);
5863 tcg_gen_qemu_ld64(o->in2, o->in2, get_mem_index(s));
5864 gen_addi_and_wrap_i64(s, o->in2, o->in2, 0);
5865}
5866#define SPEC_in2_m2_64w 0
5867
21fc97c5 5868#ifndef CONFIG_USER_ONLY
3f68884b 5869static void in2_m2_64a(DisasContext *s, DisasOps *o)
21fc97c5 5870{
3f68884b 5871 in2_a2(s, o);
fc313c64 5872 tcg_gen_qemu_ld_i64(o->in2, o->in2, get_mem_index(s), MO_TEUQ | MO_ALIGN);
21fc97c5
DH
5873}
5874#define SPEC_in2_m2_64a 0
5875#endif
5876
54fce97c
NSG
5877static void in2_mri2_16s(DisasContext *s, DisasOps *o)
5878{
5879 o->in2 = tcg_temp_new_i64();
5880 tcg_gen_qemu_ld16s(o->in2, gen_ri2(s), get_mem_index(s));
5881}
5882#define SPEC_in2_mri2_16s 0
5883
3f68884b 5884static void in2_mri2_16u(DisasContext *s, DisasOps *o)
a7e836d5 5885{
bdbc87e3
RH
5886 o->in2 = tcg_temp_new_i64();
5887 tcg_gen_qemu_ld16u(o->in2, gen_ri2(s), get_mem_index(s));
a7e836d5 5888}
49f7ee80 5889#define SPEC_in2_mri2_16u 0
a7e836d5 5890
3f68884b 5891static void in2_mri2_32s(DisasContext *s, DisasOps *o)
a7e836d5 5892{
bdbc87e3 5893 o->in2 = tcg_temp_new_i64();
227a9f79
IL
5894 tcg_gen_qemu_ld_tl(o->in2, gen_ri2(s), get_mem_index(s),
5895 MO_TESL | MO_ALIGN);
a7e836d5 5896}
49f7ee80 5897#define SPEC_in2_mri2_32s 0
a7e836d5 5898
3f68884b 5899static void in2_mri2_32u(DisasContext *s, DisasOps *o)
a7e836d5 5900{
bdbc87e3 5901 o->in2 = tcg_temp_new_i64();
0708220c
IL
5902 tcg_gen_qemu_ld_tl(o->in2, gen_ri2(s), get_mem_index(s),
5903 MO_TEUL | MO_ALIGN);
a7e836d5 5904}
49f7ee80 5905#define SPEC_in2_mri2_32u 0
a7e836d5 5906
3f68884b 5907static void in2_mri2_64(DisasContext *s, DisasOps *o)
a7e836d5 5908{
bdbc87e3 5909 o->in2 = tcg_temp_new_i64();
2b25c824
IL
5910 tcg_gen_qemu_ld_i64(o->in2, gen_ri2(s), get_mem_index(s),
5911 MO_TEUQ | MO_ALIGN);
a7e836d5 5912}
49f7ee80 5913#define SPEC_in2_mri2_64 0
a7e836d5 5914
3f68884b 5915static void in2_i2(DisasContext *s, DisasOps *o)
ad044d09 5916{
5bd9790e 5917 o->in2 = tcg_constant_i64(get_field(s, i2));
ad044d09 5918}
49f7ee80 5919#define SPEC_in2_i2 0
ad044d09 5920
3f68884b 5921static void in2_i2_8u(DisasContext *s, DisasOps *o)
a7e836d5 5922{
5bd9790e 5923 o->in2 = tcg_constant_i64((uint8_t)get_field(s, i2));
a7e836d5 5924}
49f7ee80 5925#define SPEC_in2_i2_8u 0
a7e836d5 5926
3f68884b 5927static void in2_i2_16u(DisasContext *s, DisasOps *o)
a7e836d5 5928{
5bd9790e 5929 o->in2 = tcg_constant_i64((uint16_t)get_field(s, i2));
a7e836d5 5930}
49f7ee80 5931#define SPEC_in2_i2_16u 0
a7e836d5 5932
3f68884b 5933static void in2_i2_32u(DisasContext *s, DisasOps *o)
ad044d09 5934{
5bd9790e 5935 o->in2 = tcg_constant_i64((uint32_t)get_field(s, i2));
ad044d09 5936}
49f7ee80 5937#define SPEC_in2_i2_32u 0
ad044d09 5938
3f68884b 5939static void in2_i2_16u_shl(DisasContext *s, DisasOps *o)
ade9dea4 5940{
c30988d1 5941 uint64_t i2 = (uint16_t)get_field(s, i2);
5bd9790e 5942 o->in2 = tcg_constant_i64(i2 << s->insn->data);
ade9dea4 5943}
49f7ee80 5944#define SPEC_in2_i2_16u_shl 0
ade9dea4 5945
3f68884b 5946static void in2_i2_32u_shl(DisasContext *s, DisasOps *o)
ade9dea4 5947{
c30988d1 5948 uint64_t i2 = (uint32_t)get_field(s, i2);
5bd9790e 5949 o->in2 = tcg_constant_i64(i2 << s->insn->data);
ade9dea4 5950}
49f7ee80 5951#define SPEC_in2_i2_32u_shl 0
ade9dea4 5952
ad8a4570 5953#ifndef CONFIG_USER_ONLY
3f68884b 5954static void in2_insn(DisasContext *s, DisasOps *o)
ad8a4570 5955{
5bd9790e 5956 o->in2 = tcg_constant_i64(s->fields.raw_insn);
ad8a4570
AG
5957}
5958#define SPEC_in2_insn 0
5959#endif
5960
ad044d09
RH
5961/* ====================================================================== */
5962
5963/* Find opc within the table of insns. This is formulated as a switch
5964 statement so that (1) we get compile-time notice of cut-paste errors
5965 for duplicated opcodes, and (2) the compiler generates the binary
5966 search tree, rather than us having to post-process the table. */
5967
5968#define C(OPC, NM, FT, FC, I1, I2, P, W, OP, CC) \
82d17933 5969 E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, 0, 0)
ad044d09 5970
82d17933
DH
5971#define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) \
5972 E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D, 0)
5973
5974#define F(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, FL) \
5975 E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, 0, FL)
5976
5977#define E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D, FL) insn_ ## NM,
ad044d09
RH
5978
5979enum DisasInsnEnum {
9cef8d99 5980#include "insn-data.h.inc"
ad044d09
RH
5981};
5982
82d17933
DH
5983#undef E
5984#define E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D, FL) { \
49f7ee80 5985 .opc = OPC, \
82d17933 5986 .flags = FL, \
49f7ee80
RH
5987 .fmt = FMT_##FT, \
5988 .fac = FAC_##FC, \
5989 .spec = SPEC_in1_##I1 | SPEC_in2_##I2 | SPEC_prep_##P | SPEC_wout_##W, \
5990 .name = #NM, \
5991 .help_in1 = in1_##I1, \
5992 .help_in2 = in2_##I2, \
5993 .help_prep = prep_##P, \
5994 .help_wout = wout_##W, \
5995 .help_cout = cout_##CC, \
5996 .help_op = op_##OP, \
5997 .data = D \
ad044d09
RH
5998 },
5999
6000/* Allow 0 to be used for NULL in the table below. */
6001#define in1_0 NULL
6002#define in2_0 NULL
6003#define prep_0 NULL
6004#define wout_0 NULL
6005#define cout_0 NULL
6006#define op_0 NULL
6007
49f7ee80
RH
6008#define SPEC_in1_0 0
6009#define SPEC_in2_0 0
6010#define SPEC_prep_0 0
6011#define SPEC_wout_0 0
6012
d20bd43c
RH
6013/* Give smaller names to the various facilities. */
6014#define FAC_Z S390_FEAT_ZARCH
6015#define FAC_CASS S390_FEAT_COMPARE_AND_SWAP_AND_STORE
d20bd43c 6016#define FAC_DFP S390_FEAT_DFP
00011706 6017#define FAC_DFPR S390_FEAT_FLOATING_POINT_SUPPORT_ENH /* DFP-rounding */
d20bd43c
RH
6018#define FAC_DO S390_FEAT_STFLE_45 /* distinct-operands */
6019#define FAC_EE S390_FEAT_EXECUTE_EXT
6020#define FAC_EI S390_FEAT_EXTENDED_IMMEDIATE
6021#define FAC_FPE S390_FEAT_FLOATING_POINT_EXT
00011706
DDAG
6022#define FAC_FPSSH S390_FEAT_FLOATING_POINT_SUPPORT_ENH /* FPS-sign-handling */
6023#define FAC_FPRGR S390_FEAT_FLOATING_POINT_SUPPORT_ENH /* FPR-GR-transfer */
d20bd43c
RH
6024#define FAC_GIE S390_FEAT_GENERAL_INSTRUCTIONS_EXT
6025#define FAC_HFP_MA S390_FEAT_HFP_MADDSUB
6026#define FAC_HW S390_FEAT_STFLE_45 /* high-word */
00011706 6027#define FAC_IEEEE_SIM S390_FEAT_FLOATING_POINT_SUPPORT_ENH /* IEEE-exception-simulation */
d20bd43c
RH
6028#define FAC_MIE S390_FEAT_STFLE_49 /* misc-instruction-extensions */
6029#define FAC_LAT S390_FEAT_STFLE_49 /* load-and-trap */
6030#define FAC_LOC S390_FEAT_STFLE_45 /* load/store on condition 1 */
45aa9aa3 6031#define FAC_LOC2 S390_FEAT_STFLE_53 /* load/store on condition 2 */
d20bd43c
RH
6032#define FAC_LD S390_FEAT_LONG_DISPLACEMENT
6033#define FAC_PC S390_FEAT_STFLE_45 /* population count */
6034#define FAC_SCF S390_FEAT_STORE_CLOCK_FAST
6035#define FAC_SFLE S390_FEAT_STFLE
6036#define FAC_ILA S390_FEAT_STFLE_45 /* interlocked-access-facility 1 */
3e7e5e0b 6037#define FAC_MVCOS S390_FEAT_MOVE_WITH_OPTIONAL_SPEC
d20bd43c
RH
6038#define FAC_LPP S390_FEAT_SET_PROGRAM_PARAMETERS /* load-program-parameter */
6039#define FAC_DAT_ENH S390_FEAT_DAT_ENH
6040#define FAC_E2 S390_FEAT_EXTENDED_TRANSLATION_2
6a68acd5 6041#define FAC_EH S390_FEAT_STFLE_49 /* execution-hint */
632c61a9 6042#define FAC_PPA S390_FEAT_STFLE_49 /* processor-assist */
c2a5c1d7 6043#define FAC_LZRB S390_FEAT_STFLE_53 /* load-and-zero-rightmost-byte */
941ef3db 6044#define FAC_ETF3 S390_FEAT_EXTENDED_TRANSLATION_3
7705c750
DH
6045#define FAC_MSA S390_FEAT_MSA /* message-security-assist facility */
6046#define FAC_MSA3 S390_FEAT_MSA_EXT_3 /* msa-extension-3 facility */
6047#define FAC_MSA4 S390_FEAT_MSA_EXT_4 /* msa-extension-4 facility */
6048#define FAC_MSA5 S390_FEAT_MSA_EXT_5 /* msa-extension-5 facility */
be2b5670 6049#define FAC_MSA8 S390_FEAT_MSA_EXT_8 /* msa-extension-8 facility */
4bac52f5 6050#define FAC_ECT S390_FEAT_EXTRACT_CPU_TIME
f6c232ce
CH
6051#define FAC_PCI S390_FEAT_ZPCI /* z/PCI facility */
6052#define FAC_AIS S390_FEAT_ADAPTER_INT_SUPPRESSION
6d930332 6053#define FAC_V S390_FEAT_VECTOR /* vector facility */
1d706f31
DM
6054#define FAC_VE S390_FEAT_VECTOR_ENH /* vector enhancements facility 1 */
6055#define FAC_VE2 S390_FEAT_VECTOR_ENH2 /* vector enhancements facility 2 */
87d7d931 6056#define FAC_MIE2 S390_FEAT_MISC_INSTRUCTION_EXT2 /* miscellaneous-instruction-extensions facility 2 */
ea0a1053 6057#define FAC_MIE3 S390_FEAT_MISC_INSTRUCTION_EXT3 /* miscellaneous-instruction-extensions facility 3 */
d20bd43c 6058
ad044d09 6059static const DisasInsn insn_info[] = {
9cef8d99 6060#include "insn-data.h.inc"
ad044d09
RH
6061};
6062
82d17933
DH
6063#undef E
6064#define E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D, FL) \
ad044d09
RH
6065 case OPC: return &insn_info[insn_ ## NM];
6066
6067static const DisasInsn *lookup_opc(uint16_t opc)
6068{
6069 switch (opc) {
9cef8d99 6070#include "insn-data.h.inc"
ad044d09
RH
6071 default:
6072 return NULL;
6073 }
6074}
6075
82d17933
DH
6076#undef F
6077#undef E
ad044d09
RH
6078#undef D
6079#undef C
6080
6081/* Extract a field from the insn. The INSN should be left-aligned in
6082 the uint64_t so that we can more easily utilize the big-bit-endian
6083 definitions we extract from the Principals of Operation. */
6084
6085static void extract_field(DisasFields *o, const DisasField *f, uint64_t insn)
6086{
6087 uint32_t r, m;
6088
6089 if (f->size == 0) {
6090 return;
6091 }
6092
6093 /* Zero extract the field from the insn. */
6094 r = (insn << f->beg) >> (64 - f->size);
6095
6096 /* Sign-extend, or un-swap the field as necessary. */
6097 switch (f->type) {
6098 case 0: /* unsigned */
6099 break;
6100 case 1: /* signed */
6101 assert(f->size <= 32);
6102 m = 1u << (f->size - 1);
6103 r = (r ^ m) - m;
6104 break;
6105 case 2: /* dl+dh split, signed 20 bit. */
6106 r = ((int8_t)r << 12) | (r >> 8);
6107 break;
481accd4
DH
6108 case 3: /* MSB stored in RXB */
6109 g_assert(f->size == 4);
6110 switch (f->beg) {
6111 case 8:
6112 r |= extract64(insn, 63 - 36, 1) << 4;
6113 break;
6114 case 12:
6115 r |= extract64(insn, 63 - 37, 1) << 4;
6116 break;
6117 case 16:
6118 r |= extract64(insn, 63 - 38, 1) << 4;
6119 break;
6120 case 32:
6121 r |= extract64(insn, 63 - 39, 1) << 4;
6122 break;
6123 default:
6124 g_assert_not_reached();
6125 }
6126 break;
ad044d09
RH
6127 default:
6128 abort();
6129 }
6130
a4761232
PMD
6131 /*
6132 * Validate that the "compressed" encoding we selected above is valid.
6133 * I.e. we haven't made two different original fields overlap.
6134 */
ad044d09
RH
6135 assert(((o->presentC >> f->indexC) & 1) == 0);
6136 o->presentC |= 1 << f->indexC;
6137 o->presentO |= 1 << f->indexO;
6138
6139 o->c[f->indexC] = r;
6140}
6141
6142/* Lookup the insn at the current PC, extracting the operands into O and
6143 returning the info struct for the insn. Returns NULL for invalid insn. */
6144
a2fb6b00 6145static const DisasInsn *extract_insn(CPUS390XState *env, DisasContext *s)
ad044d09 6146{
eccf741a 6147 uint64_t insn, pc = s->base.pc_next;
d5a103cd 6148 int op, op2, ilen;
ad044d09
RH
6149 const DisasInsn *info;
6150
303c681a
RH
6151 if (unlikely(s->ex_value)) {
6152 /* Drop the EX data now, so that it's clear on exception paths. */
f1ea739b
RH
6153 tcg_gen_st_i64(tcg_constant_i64(0), cpu_env,
6154 offsetof(CPUS390XState, ex_value));
d5a103cd 6155
303c681a
RH
6156 /* Extract the values saved by EXECUTE. */
6157 insn = s->ex_value & 0xffffffffffff0000ull;
6158 ilen = s->ex_value & 0xf;
f1ea739b
RH
6159
6160 /* Register insn bytes with translator so plugins work. */
6161 for (int i = 0; i < ilen; i++) {
9fa97e04
AB
6162 uint8_t byte = extract64(insn, 56 - (i * 8), 8);
6163 translator_fake_ldb(byte, pc + i);
6164 }
303c681a
RH
6165 op = insn >> 56;
6166 } else {
4e116893 6167 insn = ld_code2(env, s, pc);
303c681a
RH
6168 op = (insn >> 8) & 0xff;
6169 ilen = get_ilen(op);
6170 switch (ilen) {
6171 case 2:
6172 insn = insn << 48;
6173 break;
6174 case 4:
4e116893 6175 insn = ld_code4(env, s, pc) << 32;
303c681a
RH
6176 break;
6177 case 6:
4e116893 6178 insn = (insn << 48) | (ld_code4(env, s, pc + 2) << 16);
303c681a
RH
6179 break;
6180 default:
6181 g_assert_not_reached();
6182 }
ad044d09 6183 }
eccf741a 6184 s->pc_tmp = s->base.pc_next + ilen;
303c681a 6185 s->ilen = ilen;
ad044d09
RH
6186
6187 /* We can't actually determine the insn format until we've looked up
6188 the full insn opcode. Which we can't do without locating the
6189 secondary opcode. Assume by default that OP2 is at bit 40; for
6190 those smaller insns that don't actually have a secondary opcode
6191 this will correctly result in OP2 = 0. */
6192 switch (op) {
6193 case 0x01: /* E */
6194 case 0x80: /* S */
6195 case 0x82: /* S */
6196 case 0x93: /* S */
6a68acd5 6197 case 0xb2: /* S, RRF, RRE, IE */
ad044d09
RH
6198 case 0xb3: /* RRE, RRD, RRF */
6199 case 0xb9: /* RRE, RRF */
6200 case 0xe5: /* SSE, SIL */
6201 op2 = (insn << 8) >> 56;
6202 break;
6203 case 0xa5: /* RI */
6204 case 0xa7: /* RI */
6205 case 0xc0: /* RIL */
6206 case 0xc2: /* RIL */
6207 case 0xc4: /* RIL */
6208 case 0xc6: /* RIL */
6209 case 0xc8: /* SSF */
6210 case 0xcc: /* RIL */
6211 op2 = (insn << 12) >> 60;
6212 break;
6a68acd5
RH
6213 case 0xc5: /* MII */
6214 case 0xc7: /* SMI */
ad044d09
RH
6215 case 0xd0 ... 0xdf: /* SS */
6216 case 0xe1: /* SS */
6217 case 0xe2: /* SS */
6218 case 0xe8: /* SS */
6219 case 0xe9: /* SS */
6220 case 0xea: /* SS */
6221 case 0xee ... 0xf3: /* SS */
6222 case 0xf8 ... 0xfd: /* SS */
6223 op2 = 0;
6224 break;
6225 default:
6226 op2 = (insn << 40) >> 56;
6227 break;
6228 }
6229
a2fb6b00
RH
6230 memset(&s->fields, 0, sizeof(s->fields));
6231 s->fields.raw_insn = insn;
6232 s->fields.op = op;
6233 s->fields.op2 = op2;
ad044d09
RH
6234
6235 /* Lookup the instruction. */
6236 info = lookup_opc(op << 8 | op2);
a2fb6b00 6237 s->insn = info;
ad044d09
RH
6238
6239 /* If we found it, extract the operands. */
6240 if (info != NULL) {
6241 DisasFormat fmt = info->fmt;
6242 int i;
6243
6244 for (i = 0; i < NUM_C_FIELD; ++i) {
a2fb6b00 6245 extract_field(&s->fields, &format_info[fmt].op[i], insn);
ad044d09
RH
6246 }
6247 }
6248 return info;
6249}
6250
db050415
DH
6251static bool is_afp_reg(int reg)
6252{
6253 return reg % 2 || reg > 6;
6254}
6255
eba7170b
DH
6256static bool is_fp_pair(int reg)
6257{
6258 /* 0,1,4,5,8,9,12,13: to exclude the others, check for single bit */
6259 return !(reg & 0x2);
6260}
6261
21a8eced 6262static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s)
ad044d09
RH
6263{
6264 const DisasInsn *insn;
21a8eced 6265 DisasJumpType ret = DISAS_NEXT;
076081ec 6266 DisasOps o = {};
5e49e89c 6267 bool icount = false;
ad044d09 6268
4f3adfb2 6269 /* Search for the insn in the table. */
a2fb6b00 6270 insn = extract_insn(env, s);
c30988d1 6271
5d23d530
RH
6272 /* Update insn_start now that we know the ILEN. */
6273 tcg_set_insn_start_param(s->insn_start, 2, s->ilen);
c87ff4d1 6274
4f3adfb2 6275 /* Not found means unimplemented/illegal opcode. */
ad044d09 6276 if (insn == NULL) {
4f3adfb2 6277 qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%02x%02x\n",
344a7f65 6278 s->fields.op, s->fields.op2);
4f3adfb2 6279 gen_illegal_opcode(s);
86131c71
IL
6280 ret = DISAS_NORETURN;
6281 goto out;
ad044d09
RH
6282 }
6283
f0e0d817 6284#ifndef CONFIG_USER_ONLY
eccf741a 6285 if (s->base.tb->flags & FLAG_MASK_PER) {
f1ea739b 6286 TCGv_i64 addr = tcg_constant_i64(s->base.pc_next);
f0e0d817 6287 gen_helper_per_ifetch(cpu_env, addr);
f0e0d817
AJ
6288 }
6289#endif
6290
db050415
DH
6291 /* process flags */
6292 if (insn->flags) {
b51cc1d8
DH
6293 /* privileged instruction */
6294 if ((s->base.tb->flags & FLAG_MASK_PSTATE) && (insn->flags & IF_PRIV)) {
6295 gen_program_exception(s, PGM_PRIVILEGED);
86131c71
IL
6296 ret = DISAS_NORETURN;
6297 goto out;
b51cc1d8
DH
6298 }
6299
db050415
DH
6300 /* if AFP is not enabled, instructions and registers are forbidden */
6301 if (!(s->base.tb->flags & FLAG_MASK_AFP)) {
6302 uint8_t dxc = 0;
6303
c30988d1 6304 if ((insn->flags & IF_AFP1) && is_afp_reg(get_field(s, r1))) {
db050415
DH
6305 dxc = 1;
6306 }
c30988d1 6307 if ((insn->flags & IF_AFP2) && is_afp_reg(get_field(s, r2))) {
db050415
DH
6308 dxc = 1;
6309 }
c30988d1 6310 if ((insn->flags & IF_AFP3) && is_afp_reg(get_field(s, r3))) {
db050415
DH
6311 dxc = 1;
6312 }
6313 if (insn->flags & IF_BFP) {
6314 dxc = 2;
6315 }
6316 if (insn->flags & IF_DFP) {
6317 dxc = 3;
6318 }
b971a2fd
DH
6319 if (insn->flags & IF_VEC) {
6320 dxc = 0xfe;
6321 }
db050415
DH
6322 if (dxc) {
6323 gen_data_exception(dxc);
86131c71
IL
6324 ret = DISAS_NORETURN;
6325 goto out;
b971a2fd
DH
6326 }
6327 }
6328
6329 /* if vector instructions not enabled, executing them is forbidden */
6330 if (insn->flags & IF_VEC) {
6331 if (!((s->base.tb->flags & FLAG_MASK_VECTOR))) {
6332 gen_data_exception(0xfe);
86131c71
IL
6333 ret = DISAS_NORETURN;
6334 goto out;
db050415
DH
6335 }
6336 }
5e49e89c
PD
6337
6338 /* input/output is the special case for icount mode */
6339 if (unlikely(insn->flags & IF_IO)) {
6340 icount = tb_cflags(s->base.tb) & CF_USE_ICOUNT;
6341 if (icount) {
6342 gen_io_start();
6343 }
6344 }
db050415
DH
6345 }
6346
49f7ee80
RH
6347 /* Check for insn specification exceptions. */
6348 if (insn->spec) {
c30988d1
RH
6349 if ((insn->spec & SPEC_r1_even && get_field(s, r1) & 1) ||
6350 (insn->spec & SPEC_r2_even && get_field(s, r2) & 1) ||
6351 (insn->spec & SPEC_r3_even && get_field(s, r3) & 1) ||
6352 (insn->spec & SPEC_r1_f128 && !is_fp_pair(get_field(s, r1))) ||
6353 (insn->spec & SPEC_r2_f128 && !is_fp_pair(get_field(s, r2)))) {
74fbae31 6354 gen_program_exception(s, PGM_SPECIFICATION);
86131c71
IL
6355 ret = DISAS_NORETURN;
6356 goto out;
49f7ee80
RH
6357 }
6358 }
6359
ad044d09
RH
6360 /* Implement the instruction. */
6361 if (insn->help_in1) {
3f68884b 6362 insn->help_in1(s, &o);
ad044d09
RH
6363 }
6364 if (insn->help_in2) {
3f68884b 6365 insn->help_in2(s, &o);
ad044d09
RH
6366 }
6367 if (insn->help_prep) {
3f68884b 6368 insn->help_prep(s, &o);
ad044d09
RH
6369 }
6370 if (insn->help_op) {
6371 ret = insn->help_op(s, &o);
6372 }
72d8ad67
RH
6373 if (ret != DISAS_NORETURN) {
6374 if (insn->help_wout) {
3f68884b 6375 insn->help_wout(s, &o);
72d8ad67
RH
6376 }
6377 if (insn->help_cout) {
6378 insn->help_cout(s, &o);
6379 }
ad044d09
RH
6380 }
6381
5e49e89c
PD
6382 /* io should be the last instruction in tb when icount is enabled */
6383 if (unlikely(icount && ret == DISAS_NEXT)) {
8ec2edac 6384 ret = DISAS_TOO_MANY;
5e49e89c
PD
6385 }
6386
777c98c3 6387#ifndef CONFIG_USER_ONLY
eccf741a 6388 if (s->base.tb->flags & FLAG_MASK_PER) {
777c98c3 6389 /* An exception might be triggered, save PSW if not already done. */
8ec2edac 6390 if (ret == DISAS_NEXT || ret == DISAS_TOO_MANY) {
eccf741a 6391 tcg_gen_movi_i64(psw_addr, s->pc_tmp);
777c98c3
AJ
6392 }
6393
777c98c3
AJ
6394 /* Call the helper to check for a possible PER exception. */
6395 gen_helper_per_check_exception(cpu_env);
6396 }
6397#endif
6398
86131c71 6399out:
ad044d09 6400 /* Advance to the next instruction. */
eccf741a 6401 s->base.pc_next = s->pc_tmp;
ad044d09 6402 return ret;
e023e832
AG
6403}
6404
c88691aa 6405static void s390x_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
e023e832 6406{
c88691aa 6407 DisasContext *dc = container_of(dcbase, DisasContext, base);
e023e832 6408
e023e832 6409 /* 31-bit mode */
c88691aa
EC
6410 if (!(dc->base.tb->flags & FLAG_MASK_64)) {
6411 dc->base.pc_first &= 0x7fffffff;
6412 dc->base.pc_next = dc->base.pc_first;
e023e832
AG
6413 }
6414
c88691aa
EC
6415 dc->cc_op = CC_OP_DYNAMIC;
6416 dc->ex_value = dc->base.tb->cs_base;
3d8111fd 6417 dc->exit_to_mainloop = (dc->base.tb->flags & FLAG_MASK_PER) || dc->ex_value;
c88691aa 6418}
e023e832 6419
c88691aa
EC
6420static void s390x_tr_tb_start(DisasContextBase *db, CPUState *cs)
6421{
6422}
e023e832 6423
c88691aa
EC
6424static void s390x_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
6425{
5d23d530
RH
6426 DisasContext *dc = container_of(dcbase, DisasContext, base);
6427
6428 /* Delay the set of ilen until we've read the insn. */
6429 tcg_gen_insn_start(dc->base.pc_next, dc->cc_op, 0);
6430 dc->insn_start = tcg_last_op();
c88691aa 6431}
e023e832 6432
ab12c95d
IL
6433static target_ulong get_next_pc(CPUS390XState *env, DisasContext *s,
6434 uint64_t pc)
6435{
efe7c4f0 6436 uint64_t insn = cpu_lduw_code(env, pc);
ab12c95d
IL
6437
6438 return pc + get_ilen((insn >> 8) & 0xff);
6439}
6440
c88691aa
EC
6441static void s390x_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
6442{
6443 CPUS390XState *env = cs->env_ptr;
6444 DisasContext *dc = container_of(dcbase, DisasContext, base);
7193b5f6 6445
c88691aa
EC
6446 dc->base.is_jmp = translate_one(env, dc);
6447 if (dc->base.is_jmp == DISAS_NEXT) {
621aab6c
AB
6448 if (dc->ex_value ||
6449 !is_same_page(dcbase, dc->base.pc_next) ||
6450 !is_same_page(dcbase, get_next_pc(env, dc, dc->base.pc_next))) {
c88691aa
EC
6451 dc->base.is_jmp = DISAS_TOO_MANY;
6452 }
e023e832 6453 }
c88691aa
EC
6454}
6455
6456static void s390x_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
6457{
6458 DisasContext *dc = container_of(dcbase, DisasContext, base);
ad044d09 6459
c88691aa 6460 switch (dc->base.is_jmp) {
21a8eced 6461 case DISAS_NORETURN:
ad044d09 6462 break;
21a8eced 6463 case DISAS_TOO_MANY:
c88691aa 6464 update_psw_addr(dc);
ad044d09 6465 /* FALLTHRU */
21a8eced 6466 case DISAS_PC_UPDATED:
7a6c7067
RH
6467 /* Next TB starts off with CC_OP_DYNAMIC, so make sure the
6468 cc op type is in env */
c88691aa 6469 update_cc_op(dc);
06fc0348 6470 /* FALLTHRU */
21a8eced 6471 case DISAS_PC_CC_UPDATED:
7a6c7067 6472 /* Exit the TB, either by raising a debug exception or by return. */
872e1379 6473 if (dc->exit_to_mainloop) {
07ea28b4 6474 tcg_gen_exit_tb(NULL, 0);
6350001e 6475 } else {
7f11636d 6476 tcg_gen_lookup_and_goto_ptr();
ad044d09
RH
6477 }
6478 break;
6479 default:
542f70c2 6480 g_assert_not_reached();
e023e832 6481 }
c88691aa 6482}
ad044d09 6483
8eb806a7
RH
6484static void s390x_tr_disas_log(const DisasContextBase *dcbase,
6485 CPUState *cs, FILE *logfile)
c88691aa
EC
6486{
6487 DisasContext *dc = container_of(dcbase, DisasContext, base);
ad044d09 6488
c88691aa 6489 if (unlikely(dc->ex_value)) {
8eb806a7
RH
6490 /* ??? Unfortunately target_disas can't use host memory. */
6491 fprintf(logfile, "IN: EXECUTE %016" PRIx64, dc->ex_value);
c88691aa 6492 } else {
8eb806a7
RH
6493 fprintf(logfile, "IN: %s\n", lookup_symbol(dc->base.pc_first));
6494 target_disas(logfile, cs, dc->base.pc_first, dc->base.tb->size);
e023e832 6495 }
c88691aa
EC
6496}
6497
6498static const TranslatorOps s390x_tr_ops = {
6499 .init_disas_context = s390x_tr_init_disas_context,
6500 .tb_start = s390x_tr_tb_start,
6501 .insn_start = s390x_tr_insn_start,
c88691aa
EC
6502 .translate_insn = s390x_tr_translate_insn,
6503 .tb_stop = s390x_tr_tb_stop,
6504 .disas_log = s390x_tr_disas_log,
6505};
6506
597f9b2d 6507void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
306c8721 6508 target_ulong pc, void *host_pc)
c88691aa
EC
6509{
6510 DisasContext dc;
6511
306c8721 6512 translator_loop(cs, tb, max_insns, pc, host_pc, &s390x_tr_ops, &dc.base);
e023e832
AG
6513}
6514
3479783b
RH
6515void s390x_restore_state_to_opc(CPUState *cs,
6516 const TranslationBlock *tb,
6517 const uint64_t *data)
e023e832 6518{
3479783b
RH
6519 S390CPU *cpu = S390_CPU(cs);
6520 CPUS390XState *env = &cpu->env;
bad729e2 6521 int cc_op = data[1];
c87ff4d1 6522
bad729e2 6523 env->psw.addr = data[0];
c87ff4d1
RH
6524
6525 /* Update the CC opcode if it is not already up-to-date. */
e023e832
AG
6526 if ((cc_op != CC_OP_DYNAMIC) && (cc_op != CC_OP_STATIC)) {
6527 env->cc_op = cc_op;
6528 }
c87ff4d1
RH
6529
6530 /* Record ILEN. */
6531 env->int_pgm_ilen = data[2];
10ec5117 6532}