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