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