master
c 6,536 lines 174 KB
Raw
1 /*
2 * S/390 translation
3 *
4 * Copyright (c) 2009 Ulrich Hecht
5 * Copyright (c) 2010 Alexander Graf
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 */
20
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
30
31 #include "qemu/osdep.h"
32 #include "cpu.h"
33 #include "s390x-internal.h"
34 #define TCG_ADDRESS_BITS 64
35 #include "tcg/tcg-op-common.h"
36 #include "tcg/tcg-op-mem.h"
37 #include "tcg/tcg-op-gvec-common.h"
38 #include "qemu/log.h"
39 #include "qemu/host-utils.h"
40 #include "exec/helper-proto.h"
41 #include "exec/helper-gen.h"
42
43 #include "exec/translator.h"
44 #include "exec/translation-block.h"
45 #include "exec/log.h"
46 #include "qemu/atomic128.h"
47
48 #define HELPER_H "helper.h"
49 #include "exec/helper-info.c.inc"
50 #undef HELPER_H
51
52
53 /* Information that (most) every instruction needs to manipulate. */
54 typedef struct DisasContext DisasContext;
55 typedef struct DisasInsn DisasInsn;
56 typedef struct DisasFields DisasFields;
57
58 /*
59 * Define a structure to hold the decoded fields. We'll store each inside
60 * an array indexed by an enum. In order to conserve memory, we'll arrange
61 * for fields that do not exist at the same time to overlap, thus the "C"
62 * for compact. For checking purposes there is an "O" for original index
63 * as well that will be applied to availability bitmaps.
64 */
65
66 enum DisasFieldIndexO {
67 FLD_O_r1,
68 FLD_O_r2,
69 FLD_O_r3,
70 FLD_O_m1,
71 FLD_O_m3,
72 FLD_O_m4,
73 FLD_O_m5,
74 FLD_O_m6,
75 FLD_O_b1,
76 FLD_O_b2,
77 FLD_O_b4,
78 FLD_O_d1,
79 FLD_O_d2,
80 FLD_O_d4,
81 FLD_O_x2,
82 FLD_O_l1,
83 FLD_O_l2,
84 FLD_O_i1,
85 FLD_O_i2,
86 FLD_O_i3,
87 FLD_O_i4,
88 FLD_O_i5,
89 FLD_O_v1,
90 FLD_O_v2,
91 FLD_O_v3,
92 FLD_O_v4,
93 };
94
95 enum DisasFieldIndexC {
96 FLD_C_r1 = 0,
97 FLD_C_m1 = 0,
98 FLD_C_b1 = 0,
99 FLD_C_i1 = 0,
100 FLD_C_v1 = 0,
101
102 FLD_C_r2 = 1,
103 FLD_C_b2 = 1,
104 FLD_C_i2 = 1,
105
106 FLD_C_r3 = 2,
107 FLD_C_m3 = 2,
108 FLD_C_i3 = 2,
109 FLD_C_v3 = 2,
110
111 FLD_C_m4 = 3,
112 FLD_C_b4 = 3,
113 FLD_C_i4 = 3,
114 FLD_C_l1 = 3,
115 FLD_C_v4 = 3,
116
117 FLD_C_i5 = 4,
118 FLD_C_d1 = 4,
119 FLD_C_m5 = 4,
120
121 FLD_C_d2 = 5,
122 FLD_C_m6 = 5,
123
124 FLD_C_d4 = 6,
125 FLD_C_x2 = 6,
126 FLD_C_l2 = 6,
127 FLD_C_v2 = 6,
128
129 NUM_C_FIELD = 7
130 };
131
132 struct DisasFields {
133 uint64_t raw_insn;
134 unsigned op:8;
135 unsigned op2:8;
136 unsigned presentC:16;
137 unsigned int presentO;
138 int c[NUM_C_FIELD];
139 };
140
141 struct DisasContext {
142 DisasContextBase base;
143 const DisasInsn *insn;
144 DisasFields fields;
145 uint64_t ex_value;
146 /*
147 * During translate_one(), pc_tmp is used to determine the instruction
148 * to be executed after base.pc_next - e.g. next sequential instruction
149 * or a branch target.
150 */
151 uint64_t pc_tmp;
152 uint32_t ilen;
153 enum cc_op cc_op;
154 bool exit_to_mainloop;
155 };
156
157 /* Information carried about a condition to be evaluated. */
158 typedef struct {
159 TCGCond cond:8;
160 bool is_64;
161 union {
162 struct { TCGv_i64 a, b; } s64;
163 struct { TCGv_i32 a, b; } s32;
164 } u;
165 } DisasCompare;
166
167 #ifdef DEBUG_INLINE_BRANCHES
168 static uint64_t inline_branch_hit[CC_OP_MAX];
169 static uint64_t inline_branch_miss[CC_OP_MAX];
170 #endif
171
172 static void pc_to_link_info(TCGv_i64 out, DisasContext *s, uint64_t pc)
173 {
174 if (s->base.tb->flags & FLAG_MASK_32) {
175 if (s->base.tb->flags & FLAG_MASK_64) {
176 tcg_gen_movi_i64(out, pc);
177 return;
178 }
179 pc |= 0x80000000;
180 }
181 assert(!(s->base.tb->flags & FLAG_MASK_64));
182 tcg_gen_deposit_i64(out, out, tcg_constant_i64(pc), 0, 32);
183 }
184
185 static TCGv_i64 psw_addr;
186 static TCGv_i64 psw_mask;
187 static TCGv_i64 gbea;
188
189 static TCGv_i32 cc_op;
190 static TCGv_i64 cc_src;
191 static TCGv_i64 cc_dst;
192 static TCGv_i64 cc_vr;
193
194 static char cpu_reg_names[16][4];
195 static TCGv_i64 regs[16];
196
197 void s390x_translate_init(void)
198 {
199 int i;
200
201 psw_addr = tcg_global_mem_new_i64(tcg_env,
202 offsetof(CPUS390XState, psw.addr),
203 "psw_addr");
204 psw_mask = tcg_global_mem_new_i64(tcg_env,
205 offsetof(CPUS390XState, psw.mask),
206 "psw_mask");
207 gbea = tcg_global_mem_new_i64(tcg_env,
208 offsetof(CPUS390XState, gbea),
209 "gbea");
210
211 cc_op = tcg_global_mem_new_i32(tcg_env, offsetof(CPUS390XState, cc_op),
212 "cc_op");
213 cc_src = tcg_global_mem_new_i64(tcg_env, offsetof(CPUS390XState, cc_src),
214 "cc_src");
215 cc_dst = tcg_global_mem_new_i64(tcg_env, offsetof(CPUS390XState, cc_dst),
216 "cc_dst");
217 cc_vr = tcg_global_mem_new_i64(tcg_env, offsetof(CPUS390XState, cc_vr),
218 "cc_vr");
219
220 for (i = 0; i < 16; i++) {
221 snprintf(cpu_reg_names[i], sizeof(cpu_reg_names[0]), "r%d", i);
222 regs[i] = tcg_global_mem_new_i64(tcg_env,
223 offsetof(CPUS390XState, regs[i]),
224 cpu_reg_names[i]);
225 }
226 }
227
228 static inline int vec_full_reg_offset(uint8_t reg)
229 {
230 g_assert(reg < 32);
231 return offsetof(CPUS390XState, vregs[reg][0]);
232 }
233
234 static inline int vec_reg_offset(uint8_t reg, uint8_t enr, MemOp es)
235 {
236 /* Convert element size (es) - e.g. MO_8 - to bytes */
237 const uint8_t bytes = 1 << es;
238 int offs = enr * bytes;
239
240 /*
241 * vregs[n][0] is the lowest 8 byte and vregs[n][1] the highest 8 byte
242 * of the 16 byte vector, on both, little and big endian systems.
243 *
244 * Big Endian (target/possible host)
245 * B: [ 0][ 1][ 2][ 3][ 4][ 5][ 6][ 7] - [ 8][ 9][10][11][12][13][14][15]
246 * HW: [ 0][ 1][ 2][ 3] - [ 4][ 5][ 6][ 7]
247 * W: [ 0][ 1] - [ 2][ 3]
248 * DW: [ 0] - [ 1]
249 *
250 * Little Endian (possible host)
251 * B: [ 7][ 6][ 5][ 4][ 3][ 2][ 1][ 0] - [15][14][13][12][11][10][ 9][ 8]
252 * HW: [ 3][ 2][ 1][ 0] - [ 7][ 6][ 5][ 4]
253 * W: [ 1][ 0] - [ 3][ 2]
254 * DW: [ 0] - [ 1]
255 *
256 * For 16 byte elements, the two 8 byte halves will not form a host
257 * int128 if the host is little endian, since they're in the wrong order.
258 * Some operations (e.g. xor) do not care. For operations like addition,
259 * the two 8 byte elements have to be loaded separately. Let's force all
260 * 16 byte operations to handle it in a special way.
261 */
262 g_assert(es <= MO_64);
263 if (!HOST_BIG_ENDIAN) {
264 offs ^= (8 - bytes);
265 }
266 return offs + vec_full_reg_offset(reg);
267 }
268
269 static inline int freg64_offset(uint8_t reg)
270 {
271 g_assert(reg < 16);
272 return vec_reg_offset(reg, 0, MO_64);
273 }
274
275 static inline int freg32_offset(uint8_t reg)
276 {
277 g_assert(reg < 16);
278 return vec_reg_offset(reg, 0, MO_32);
279 }
280
281 static TCGv_i64 load_reg(int reg)
282 {
283 TCGv_i64 r = tcg_temp_new_i64();
284 tcg_gen_mov_i64(r, regs[reg]);
285 return r;
286 }
287
288 static TCGv_i64 load_freg(int reg)
289 {
290 TCGv_i64 r = tcg_temp_new_i64();
291
292 tcg_gen_ld_i64(r, tcg_env, freg64_offset(reg));
293 return r;
294 }
295
296 static TCGv_i64 load_freg32_i64(int reg)
297 {
298 TCGv_i64 r = tcg_temp_new_i64();
299
300 tcg_gen_ld32u_i64(r, tcg_env, freg32_offset(reg));
301 return r;
302 }
303
304 static TCGv_i128 load_freg_128(int reg)
305 {
306 TCGv_i64 h = load_freg(reg);
307 TCGv_i64 l = load_freg(reg + 2);
308 TCGv_i128 r = tcg_temp_new_i128();
309
310 tcg_gen_concat_i64_i128(r, l, h);
311 return r;
312 }
313
314 static void store_reg(int reg, TCGv_i64 v)
315 {
316 tcg_gen_mov_i64(regs[reg], v);
317 }
318
319 static void store_freg(int reg, TCGv_i64 v)
320 {
321 tcg_gen_st_i64(v, tcg_env, freg64_offset(reg));
322 }
323
324 static void store_reg32_i64(int reg, TCGv_i64 v)
325 {
326 /* 32 bit register writes keep the upper half */
327 tcg_gen_deposit_i64(regs[reg], regs[reg], v, 0, 32);
328 }
329
330 static void store_reg32h_i64(int reg, TCGv_i64 v)
331 {
332 tcg_gen_deposit_i64(regs[reg], regs[reg], v, 32, 32);
333 }
334
335 static void store_freg32_i64(int reg, TCGv_i64 v)
336 {
337 tcg_gen_st32_i64(v, tcg_env, freg32_offset(reg));
338 }
339
340 static void update_psw_addr(DisasContext *s)
341 {
342 /* psw.addr */
343 tcg_gen_movi_i64(psw_addr, s->base.pc_next);
344 }
345
346 static void per_branch(DisasContext *s, TCGv_i64 dest)
347 {
348 #ifndef CONFIG_USER_ONLY
349 if (s->base.tb->flags & FLAG_MASK_PER_BRANCH) {
350 gen_helper_per_branch(tcg_env, dest, tcg_constant_i32(s->ilen));
351 }
352 #endif
353 }
354
355 static void per_breaking_event(DisasContext *s)
356 {
357 tcg_gen_movi_i64(gbea, s->base.pc_next);
358 }
359
360 static void update_cc_op(DisasContext *s)
361 {
362 if (s->cc_op != CC_OP_DYNAMIC && s->cc_op != CC_OP_STATIC) {
363 tcg_gen_movi_i32(cc_op, s->cc_op);
364 }
365 }
366
367 static inline uint64_t ld_code2(CPUS390XState *env, DisasContext *s,
368 uint64_t pc)
369 {
370 return (uint64_t) translator_lduw_end(env, &s->base, pc, MO_BE);
371 }
372
373 static inline uint64_t ld_code4(CPUS390XState *env, DisasContext *s,
374 uint64_t pc)
375 {
376 return (uint64_t)(uint32_t) translator_ldl_end(env, &s->base, pc, MO_BE);
377 }
378
379 static int get_mem_index(DisasContext *s)
380 {
381 #ifdef CONFIG_USER_ONLY
382 return MMU_USER_IDX;
383 #else
384 if (!(s->base.tb->flags & FLAG_MASK_DAT)) {
385 return MMU_REAL_IDX;
386 }
387
388 switch (s->base.tb->flags & FLAG_MASK_ASC) {
389 case PSW_ASC_PRIMARY >> FLAG_MASK_PSW_SHIFT:
390 return MMU_PRIMARY_IDX;
391 case PSW_ASC_SECONDARY >> FLAG_MASK_PSW_SHIFT:
392 return MMU_SECONDARY_IDX;
393 case PSW_ASC_HOME >> FLAG_MASK_PSW_SHIFT:
394 return MMU_HOME_IDX;
395 default:
396 g_assert_not_reached();
397 }
398 #endif
399 }
400
401 static void gen_exception(int excp)
402 {
403 gen_helper_exception(tcg_env, tcg_constant_i32(excp));
404 }
405
406 static void gen_program_exception(DisasContext *s, int code)
407 {
408 /* Remember what pgm exception this was. */
409 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env,
410 offsetof(CPUS390XState, int_pgm_code));
411
412 tcg_gen_st_i32(tcg_constant_i32(s->ilen), tcg_env,
413 offsetof(CPUS390XState, int_pgm_ilen));
414
415 /* update the psw */
416 update_psw_addr(s);
417
418 /* Save off cc. */
419 update_cc_op(s);
420
421 /* Trigger exception. */
422 gen_exception(EXCP_PGM);
423 }
424
425 static inline void gen_illegal_opcode(DisasContext *s)
426 {
427 gen_program_exception(s, PGM_OPERATION);
428 }
429
430 static inline void gen_data_exception(uint8_t dxc)
431 {
432 gen_helper_data_exception(tcg_env, tcg_constant_i32(dxc));
433 }
434
435 static inline void gen_trap(DisasContext *s)
436 {
437 /* Set DXC to 0xff */
438 gen_data_exception(0xff);
439 }
440
441 static void gen_addi_and_wrap_i64(DisasContext *s, TCGv_i64 dst, TCGv_i64 src,
442 int64_t imm)
443 {
444 tcg_gen_addi_i64(dst, src, imm);
445 if (!(s->base.tb->flags & FLAG_MASK_64)) {
446 if (s->base.tb->flags & FLAG_MASK_32) {
447 tcg_gen_andi_i64(dst, dst, 0x7fffffff);
448 } else {
449 tcg_gen_andi_i64(dst, dst, 0x00ffffff);
450 }
451 }
452 }
453
454 static TCGv_i64 get_address(DisasContext *s, int x2, int b2, int d2)
455 {
456 TCGv_i64 tmp = tcg_temp_new_i64();
457
458 /*
459 * Note that d2 is limited to 20 bits, signed. If we crop negative
460 * displacements early we create larger immediate addends.
461 */
462 if (b2 && x2) {
463 tcg_gen_add_i64(tmp, regs[b2], regs[x2]);
464 gen_addi_and_wrap_i64(s, tmp, tmp, d2);
465 } else if (b2) {
466 gen_addi_and_wrap_i64(s, tmp, regs[b2], d2);
467 } else if (x2) {
468 gen_addi_and_wrap_i64(s, tmp, regs[x2], d2);
469 } else if (!(s->base.tb->flags & FLAG_MASK_64)) {
470 if (s->base.tb->flags & FLAG_MASK_32) {
471 tcg_gen_movi_i64(tmp, d2 & 0x7fffffff);
472 } else {
473 tcg_gen_movi_i64(tmp, d2 & 0x00ffffff);
474 }
475 } else {
476 tcg_gen_movi_i64(tmp, d2);
477 }
478
479 return tmp;
480 }
481
482 static inline bool live_cc_data(DisasContext *s)
483 {
484 return (s->cc_op != CC_OP_DYNAMIC
485 && s->cc_op != CC_OP_STATIC
486 && s->cc_op > 3);
487 }
488
489 static inline void gen_op_movi_cc(DisasContext *s, uint32_t val)
490 {
491 if (live_cc_data(s)) {
492 tcg_gen_discard_i64(cc_src);
493 tcg_gen_discard_i64(cc_dst);
494 tcg_gen_discard_i64(cc_vr);
495 }
496 s->cc_op = CC_OP_CONST0 + val;
497 }
498
499 static void gen_op_update1_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 dst)
500 {
501 if (live_cc_data(s)) {
502 tcg_gen_discard_i64(cc_src);
503 tcg_gen_discard_i64(cc_vr);
504 }
505 tcg_gen_mov_i64(cc_dst, dst);
506 s->cc_op = op;
507 }
508
509 static void gen_op_update2_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src,
510 TCGv_i64 dst)
511 {
512 if (live_cc_data(s)) {
513 tcg_gen_discard_i64(cc_vr);
514 }
515 tcg_gen_mov_i64(cc_src, src);
516 tcg_gen_mov_i64(cc_dst, dst);
517 s->cc_op = op;
518 }
519
520 static void gen_op_update3_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src,
521 TCGv_i64 dst, TCGv_i64 vr)
522 {
523 tcg_gen_mov_i64(cc_src, src);
524 tcg_gen_mov_i64(cc_dst, dst);
525 tcg_gen_mov_i64(cc_vr, vr);
526 s->cc_op = op;
527 }
528
529 static void set_cc_nz_u64(DisasContext *s, TCGv_i64 val)
530 {
531 gen_op_update1_cc_i64(s, CC_OP_NZ, val);
532 }
533
534 /* CC value is in env->cc_op */
535 static void set_cc_static(DisasContext *s)
536 {
537 if (live_cc_data(s)) {
538 tcg_gen_discard_i64(cc_src);
539 tcg_gen_discard_i64(cc_dst);
540 tcg_gen_discard_i64(cc_vr);
541 }
542 s->cc_op = CC_OP_STATIC;
543 }
544
545 /* calculates cc into cc_op */
546 static void gen_op_calc_cc(DisasContext *s)
547 {
548 TCGv_i32 local_cc_op = NULL;
549 TCGv_i64 dummy = NULL;
550
551 switch (s->cc_op) {
552 default:
553 dummy = tcg_constant_i64(0);
554 /* FALLTHRU */
555 case CC_OP_ADD_64:
556 case CC_OP_SUB_64:
557 case CC_OP_ADD_32:
558 case CC_OP_SUB_32:
559 local_cc_op = tcg_constant_i32(s->cc_op);
560 break;
561 case CC_OP_CONST0:
562 case CC_OP_CONST1:
563 case CC_OP_CONST2:
564 case CC_OP_CONST3:
565 case CC_OP_STATIC:
566 case CC_OP_DYNAMIC:
567 break;
568 }
569
570 switch (s->cc_op) {
571 case CC_OP_CONST0:
572 case CC_OP_CONST1:
573 case CC_OP_CONST2:
574 case CC_OP_CONST3:
575 /* s->cc_op is the cc value */
576 tcg_gen_movi_i32(cc_op, s->cc_op - CC_OP_CONST0);
577 break;
578 case CC_OP_STATIC:
579 /* env->cc_op already is the cc value */
580 break;
581 case CC_OP_NZ:
582 tcg_gen_setcondi_i64(TCG_COND_NE, cc_dst, cc_dst, 0);
583 tcg_gen_extrl_i64_i32(cc_op, cc_dst);
584 break;
585 case CC_OP_ABS_64:
586 case CC_OP_NABS_64:
587 case CC_OP_ABS_32:
588 case CC_OP_NABS_32:
589 case CC_OP_LTGT0_32:
590 case CC_OP_LTGT0_64:
591 case CC_OP_COMP_32:
592 case CC_OP_COMP_64:
593 case CC_OP_NZ_F32:
594 case CC_OP_NZ_F64:
595 case CC_OP_FLOGR:
596 case CC_OP_LCBB:
597 case CC_OP_MULS_32:
598 /* 1 argument */
599 gen_helper_calc_cc(cc_op, tcg_env, local_cc_op, dummy, cc_dst, dummy);
600 break;
601 case CC_OP_ADDU:
602 case CC_OP_ICM:
603 case CC_OP_LTGT_32:
604 case CC_OP_LTGT_64:
605 case CC_OP_LTUGTU_32:
606 case CC_OP_LTUGTU_64:
607 case CC_OP_TM_32:
608 case CC_OP_TM_64:
609 case CC_OP_SLA:
610 case CC_OP_SUBU:
611 case CC_OP_NZ_F128:
612 case CC_OP_VC:
613 case CC_OP_MULS_64:
614 /* 2 arguments */
615 gen_helper_calc_cc(cc_op, tcg_env, local_cc_op, cc_src, cc_dst, dummy);
616 break;
617 case CC_OP_ADD_64:
618 case CC_OP_SUB_64:
619 case CC_OP_ADD_32:
620 case CC_OP_SUB_32:
621 /* 3 arguments */
622 gen_helper_calc_cc(cc_op, tcg_env, local_cc_op, cc_src, cc_dst, cc_vr);
623 break;
624 case CC_OP_DYNAMIC:
625 /* unknown operation - assume 3 arguments and cc_op in env */
626 gen_helper_calc_cc(cc_op, tcg_env, cc_op, cc_src, cc_dst, cc_vr);
627 break;
628 default:
629 g_assert_not_reached();
630 }
631
632 /* We now have cc in cc_op as constant */
633 set_cc_static(s);
634 }
635
636 static bool use_goto_tb(DisasContext *s, uint64_t dest)
637 {
638 return translator_use_goto_tb(&s->base, dest);
639 }
640
641 static void account_noninline_branch(DisasContext *s, int cc_op)
642 {
643 #ifdef DEBUG_INLINE_BRANCHES
644 inline_branch_miss[cc_op]++;
645 #endif
646 }
647
648 static void account_inline_branch(DisasContext *s, int cc_op)
649 {
650 #ifdef DEBUG_INLINE_BRANCHES
651 inline_branch_hit[cc_op]++;
652 #endif
653 }
654
655 /* Table of mask values to comparison codes, given a comparison as input.
656 For such, CC=3 should not be possible. */
657 static const TCGCond ltgt_cond[16] = {
658 TCG_COND_NEVER, TCG_COND_NEVER, /* | | | x */
659 TCG_COND_GT, TCG_COND_GT, /* | | GT | x */
660 TCG_COND_LT, TCG_COND_LT, /* | LT | | x */
661 TCG_COND_NE, TCG_COND_NE, /* | LT | GT | x */
662 TCG_COND_EQ, TCG_COND_EQ, /* EQ | | | x */
663 TCG_COND_GE, TCG_COND_GE, /* EQ | | GT | x */
664 TCG_COND_LE, TCG_COND_LE, /* EQ | LT | | x */
665 TCG_COND_ALWAYS, TCG_COND_ALWAYS, /* EQ | LT | GT | x */
666 };
667
668 /* Table of mask values to comparison codes, given a logic op as input.
669 For such, only CC=0 and CC=1 should be possible. */
670 static const TCGCond nz_cond[16] = {
671 TCG_COND_NEVER, TCG_COND_NEVER, /* | | x | x */
672 TCG_COND_NEVER, TCG_COND_NEVER,
673 TCG_COND_NE, TCG_COND_NE, /* | NE | x | x */
674 TCG_COND_NE, TCG_COND_NE,
675 TCG_COND_EQ, TCG_COND_EQ, /* EQ | | x | x */
676 TCG_COND_EQ, TCG_COND_EQ,
677 TCG_COND_ALWAYS, TCG_COND_ALWAYS, /* EQ | NE | x | x */
678 TCG_COND_ALWAYS, TCG_COND_ALWAYS,
679 };
680
681 /* Interpret MASK in terms of S->CC_OP, and fill in C with all the
682 details required to generate a TCG comparison. */
683 static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
684 {
685 TCGCond cond;
686 enum cc_op old_cc_op = s->cc_op;
687
688 if (mask == 15 || mask == 0) {
689 c->cond = (mask ? TCG_COND_ALWAYS : TCG_COND_NEVER);
690 c->u.s32.a = cc_op;
691 c->u.s32.b = cc_op;
692 c->is_64 = false;
693 return;
694 }
695
696 /* Find the TCG condition for the mask + cc op. */
697 switch (old_cc_op) {
698 case CC_OP_LTGT0_32:
699 case CC_OP_LTGT0_64:
700 case CC_OP_LTGT_32:
701 case CC_OP_LTGT_64:
702 cond = ltgt_cond[mask];
703 if (cond == TCG_COND_NEVER) {
704 goto do_dynamic;
705 }
706 account_inline_branch(s, old_cc_op);
707 break;
708
709 case CC_OP_LTUGTU_32:
710 case CC_OP_LTUGTU_64:
711 cond = tcg_unsigned_cond(ltgt_cond[mask]);
712 if (cond == TCG_COND_NEVER) {
713 goto do_dynamic;
714 }
715 account_inline_branch(s, old_cc_op);
716 break;
717
718 case CC_OP_NZ:
719 cond = nz_cond[mask];
720 if (cond == TCG_COND_NEVER) {
721 goto do_dynamic;
722 }
723 account_inline_branch(s, old_cc_op);
724 break;
725
726 case CC_OP_TM_32:
727 case CC_OP_TM_64:
728 switch (mask) {
729 case 8:
730 cond = TCG_COND_TSTEQ;
731 break;
732 case 4 | 2 | 1:
733 cond = TCG_COND_TSTNE;
734 break;
735 default:
736 goto do_dynamic;
737 }
738 account_inline_branch(s, old_cc_op);
739 break;
740
741 case CC_OP_ICM:
742 switch (mask) {
743 case 8:
744 cond = TCG_COND_TSTEQ;
745 break;
746 case 4 | 2 | 1:
747 case 4 | 2:
748 cond = TCG_COND_TSTNE;
749 break;
750 default:
751 goto do_dynamic;
752 }
753 account_inline_branch(s, old_cc_op);
754 break;
755
756 case CC_OP_FLOGR:
757 switch (mask & 0xa) {
758 case 8: /* src == 0 -> no one bit found */
759 cond = TCG_COND_EQ;
760 break;
761 case 2: /* src != 0 -> one bit found */
762 cond = TCG_COND_NE;
763 break;
764 default:
765 goto do_dynamic;
766 }
767 account_inline_branch(s, old_cc_op);
768 break;
769
770 case CC_OP_ADDU:
771 case CC_OP_SUBU:
772 switch (mask) {
773 case 8 | 2: /* result == 0 */
774 cond = TCG_COND_EQ;
775 break;
776 case 4 | 1: /* result != 0 */
777 cond = TCG_COND_NE;
778 break;
779 case 8 | 4: /* !carry (borrow) */
780 cond = old_cc_op == CC_OP_ADDU ? TCG_COND_EQ : TCG_COND_NE;
781 break;
782 case 2 | 1: /* carry (!borrow) */
783 cond = old_cc_op == CC_OP_ADDU ? TCG_COND_NE : TCG_COND_EQ;
784 break;
785 default:
786 goto do_dynamic;
787 }
788 account_inline_branch(s, old_cc_op);
789 break;
790
791 default:
792 do_dynamic:
793 /* Calculate cc value. */
794 gen_op_calc_cc(s);
795 /* FALLTHRU */
796
797 case CC_OP_STATIC:
798 /* Jump based on CC. We'll load up the real cond below;
799 the assignment here merely avoids a compiler warning. */
800 account_noninline_branch(s, old_cc_op);
801 old_cc_op = CC_OP_STATIC;
802 cond = TCG_COND_NEVER;
803 break;
804 }
805
806 /* Load up the arguments of the comparison. */
807 c->is_64 = true;
808 switch (old_cc_op) {
809 case CC_OP_LTGT0_32:
810 c->is_64 = false;
811 c->u.s32.a = tcg_temp_new_i32();
812 tcg_gen_extrl_i64_i32(c->u.s32.a, cc_dst);
813 c->u.s32.b = tcg_constant_i32(0);
814 break;
815 case CC_OP_LTGT_32:
816 case CC_OP_LTUGTU_32:
817 c->is_64 = false;
818 c->u.s32.a = tcg_temp_new_i32();
819 tcg_gen_extrl_i64_i32(c->u.s32.a, cc_src);
820 c->u.s32.b = tcg_temp_new_i32();
821 tcg_gen_extrl_i64_i32(c->u.s32.b, cc_dst);
822 break;
823
824 case CC_OP_LTGT0_64:
825 case CC_OP_NZ:
826 case CC_OP_FLOGR:
827 c->u.s64.a = cc_dst;
828 c->u.s64.b = tcg_constant_i64(0);
829 break;
830
831 case CC_OP_LTGT_64:
832 case CC_OP_LTUGTU_64:
833 case CC_OP_TM_32:
834 case CC_OP_TM_64:
835 case CC_OP_ICM:
836 c->u.s64.a = cc_src;
837 c->u.s64.b = cc_dst;
838 break;
839
840 case CC_OP_ADDU:
841 case CC_OP_SUBU:
842 c->is_64 = true;
843 c->u.s64.b = tcg_constant_i64(0);
844 switch (mask) {
845 case 8 | 2:
846 case 4 | 1: /* result */
847 c->u.s64.a = cc_dst;
848 break;
849 case 8 | 4:
850 case 2 | 1: /* carry */
851 c->u.s64.a = cc_src;
852 break;
853 default:
854 g_assert_not_reached();
855 }
856 break;
857
858 case CC_OP_STATIC:
859 c->is_64 = false;
860 c->u.s32.a = cc_op;
861
862 /* Fold half of the cases using bit 3 to invert. */
863 switch (mask & 8 ? mask ^ 0xf : mask) {
864 case 0x1: /* cc == 3 */
865 cond = TCG_COND_EQ;
866 c->u.s32.b = tcg_constant_i32(3);
867 break;
868 case 0x2: /* cc == 2 */
869 cond = TCG_COND_EQ;
870 c->u.s32.b = tcg_constant_i32(2);
871 break;
872 case 0x4: /* cc == 1 */
873 cond = TCG_COND_EQ;
874 c->u.s32.b = tcg_constant_i32(1);
875 break;
876 case 0x2 | 0x1: /* cc == 2 || cc == 3 => cc > 1 */
877 cond = TCG_COND_GTU;
878 c->u.s32.b = tcg_constant_i32(1);
879 break;
880 case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */
881 cond = TCG_COND_TSTNE;
882 c->u.s32.b = tcg_constant_i32(1);
883 break;
884 case 0x4 | 0x2: /* cc == 1 || cc == 2 => (cc - 1) <= 1 */
885 cond = TCG_COND_LEU;
886 c->u.s32.a = tcg_temp_new_i32();
887 c->u.s32.b = tcg_constant_i32(1);
888 tcg_gen_addi_i32(c->u.s32.a, cc_op, -1);
889 break;
890 case 0x4 | 0x2 | 0x1: /* cc != 0 */
891 cond = TCG_COND_NE;
892 c->u.s32.b = tcg_constant_i32(0);
893 break;
894 default:
895 /* case 0: never, handled above. */
896 g_assert_not_reached();
897 }
898 if (mask & 8) {
899 cond = tcg_invert_cond(cond);
900 }
901 break;
902
903 default:
904 abort();
905 }
906 c->cond = cond;
907 }
908
909 /* ====================================================================== */
910 /* Define the insn format enumeration. */
911 #define F0(N) FMT_##N,
912 #define F1(N, X1) F0(N)
913 #define F2(N, X1, X2) F0(N)
914 #define F3(N, X1, X2, X3) F0(N)
915 #define F4(N, X1, X2, X3, X4) F0(N)
916 #define F5(N, X1, X2, X3, X4, X5) F0(N)
917 #define F6(N, X1, X2, X3, X4, X5, X6) F0(N)
918
919 typedef enum {
920 #include "insn-format.h.inc"
921 } DisasFormat;
922
923 #undef F0
924 #undef F1
925 #undef F2
926 #undef F3
927 #undef F4
928 #undef F5
929 #undef F6
930
931 /* This is the way fields are to be accessed out of DisasFields. */
932 #define have_field(S, F) have_field1((S), FLD_O_##F)
933 #define get_field(S, F) get_field1((S), FLD_O_##F, FLD_C_##F)
934
935 static bool have_field1(const DisasContext *s, enum DisasFieldIndexO c)
936 {
937 return (s->fields.presentO >> c) & 1;
938 }
939
940 static int get_field1(const DisasContext *s, enum DisasFieldIndexO o,
941 enum DisasFieldIndexC c)
942 {
943 assert(have_field1(s, o));
944 return s->fields.c[c];
945 }
946
947 /* Describe the layout of each field in each format. */
948 typedef struct DisasField {
949 unsigned int beg:8;
950 unsigned int size:8;
951 unsigned int type:2;
952 unsigned int indexC:6;
953 enum DisasFieldIndexO indexO:8;
954 } DisasField;
955
956 typedef struct DisasFormatInfo {
957 DisasField op[NUM_C_FIELD];
958 } DisasFormatInfo;
959
960 #define R(N, B) { B, 4, 0, FLD_C_r##N, FLD_O_r##N }
961 #define M(N, B) { B, 4, 0, FLD_C_m##N, FLD_O_m##N }
962 #define V(N, B) { B, 4, 3, FLD_C_v##N, FLD_O_v##N }
963 #define BD(N, BB, BD) { BB, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
964 { BD, 12, 0, FLD_C_d##N, FLD_O_d##N }
965 #define BXD(N) { 16, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
966 { 12, 4, 0, FLD_C_x##N, FLD_O_x##N }, \
967 { 20, 12, 0, FLD_C_d##N, FLD_O_d##N }
968 #define BDL(N) { 16, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
969 { 20, 20, 2, FLD_C_d##N, FLD_O_d##N }
970 #define BXDL(N) { 16, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
971 { 12, 4, 0, FLD_C_x##N, FLD_O_x##N }, \
972 { 20, 20, 2, FLD_C_d##N, FLD_O_d##N }
973 #define I(N, B, S) { B, S, 1, FLD_C_i##N, FLD_O_i##N }
974 #define L(N, B, S) { B, S, 0, FLD_C_l##N, FLD_O_l##N }
975
976 #define F0(N) { { } },
977 #define F1(N, X1) { { X1 } },
978 #define F2(N, X1, X2) { { X1, X2 } },
979 #define F3(N, X1, X2, X3) { { X1, X2, X3 } },
980 #define F4(N, X1, X2, X3, X4) { { X1, X2, X3, X4 } },
981 #define F5(N, X1, X2, X3, X4, X5) { { X1, X2, X3, X4, X5 } },
982 #define F6(N, X1, X2, X3, X4, X5, X6) { { X1, X2, X3, X4, X5, X6 } },
983
984 static const DisasFormatInfo format_info[] = {
985 #include "insn-format.h.inc"
986 };
987
988 #undef F0
989 #undef F1
990 #undef F2
991 #undef F3
992 #undef F4
993 #undef F5
994 #undef F6
995 #undef R
996 #undef M
997 #undef V
998 #undef BD
999 #undef BXD
1000 #undef BDL
1001 #undef BXDL
1002 #undef I
1003 #undef L
1004
1005 /* Generally, we'll extract operands into this structures, operate upon
1006 them, and store them back. See the "in1", "in2", "prep", "wout" sets
1007 of routines below for more details. */
1008 typedef struct {
1009 TCGv_i64 out, out2, in1, in2;
1010 TCGv_i64 addr1;
1011 TCGv_i128 out_128, in1_128, in2_128;
1012 } DisasOps;
1013
1014 /* Instructions can place constraints on their operands, raising specification
1015 exceptions if they are violated. To make this easy to automate, each "in1",
1016 "in2", "prep", "wout" helper will have a SPEC_<name> define that equals one
1017 of the following, or 0. To make this easy to document, we'll put the
1018 SPEC_<name> defines next to <name>. */
1019
1020 #define SPEC_r1_even 1
1021 #define SPEC_r2_even 2
1022 #define SPEC_r3_even 4
1023 #define SPEC_r1_f128 8
1024 #define SPEC_r2_f128 16
1025
1026 /* Return values from translate_one, indicating the state of the TB. */
1027
1028 /* We are not using a goto_tb (for whatever reason), but have updated
1029 the PC (for whatever reason), so there's no need to do it again on
1030 exiting the TB. */
1031 #define DISAS_PC_UPDATED DISAS_TARGET_0
1032
1033 /* We have updated the PC and CC values. */
1034 #define DISAS_PC_CC_UPDATED DISAS_TARGET_2
1035
1036
1037 /* Instruction flags */
1038 #define IF_AFP1 0x0001 /* r1 is a fp reg for HFP/FPS instructions */
1039 #define IF_AFP2 0x0002 /* r2 is a fp reg for HFP/FPS instructions */
1040 #define IF_AFP3 0x0004 /* r3 is a fp reg for HFP/FPS instructions */
1041 #define IF_BFP 0x0008 /* binary floating point instruction */
1042 #define IF_DFP 0x0010 /* decimal floating point instruction */
1043 #define IF_PRIV 0x0020 /* privileged instruction */
1044 #define IF_VEC 0x0040 /* vector instruction */
1045 #define IF_IO 0x0080 /* input/output instruction */
1046
1047 struct DisasInsn {
1048 unsigned opc:16;
1049 unsigned flags:16;
1050 DisasFormat fmt:8;
1051 unsigned fac:8;
1052 unsigned spec:8;
1053
1054 const char *name;
1055
1056 /* Pre-process arguments before HELP_OP. */
1057 void (*help_in1)(DisasContext *, DisasOps *);
1058 void (*help_in2)(DisasContext *, DisasOps *);
1059 void (*help_prep)(DisasContext *, DisasOps *);
1060
1061 /*
1062 * Post-process output after HELP_OP.
1063 * Note that these are not called if HELP_OP returns DISAS_NORETURN.
1064 */
1065 void (*help_wout)(DisasContext *, DisasOps *);
1066 void (*help_cout)(DisasContext *, DisasOps *);
1067
1068 /* Implement the operation itself. */
1069 DisasJumpType (*help_op)(DisasContext *, DisasOps *);
1070
1071 uint64_t data;
1072 };
1073
1074 /* ====================================================================== */
1075 /* Miscellaneous helpers, used by several operations. */
1076
1077 static DisasJumpType help_goto_direct(DisasContext *s, uint64_t dest)
1078 {
1079 update_cc_op(s);
1080 per_breaking_event(s);
1081 per_branch(s, tcg_constant_i64(dest));
1082
1083 if (dest == s->pc_tmp) {
1084 return DISAS_NEXT;
1085 }
1086 if (use_goto_tb(s, dest)) {
1087 tcg_gen_goto_tb(0);
1088 tcg_gen_movi_i64(psw_addr, dest);
1089 tcg_gen_exit_tb(s->base.tb, 0);
1090 return DISAS_NORETURN;
1091 } else {
1092 tcg_gen_movi_i64(psw_addr, dest);
1093 return DISAS_PC_CC_UPDATED;
1094 }
1095 }
1096
1097 static DisasJumpType help_goto_indirect(DisasContext *s, TCGv_i64 dest)
1098 {
1099 update_cc_op(s);
1100 per_breaking_event(s);
1101 tcg_gen_mov_i64(psw_addr, dest);
1102 per_branch(s, psw_addr);
1103 return DISAS_PC_CC_UPDATED;
1104 }
1105
1106 static DisasJumpType help_branch(DisasContext *s, DisasCompare *c,
1107 bool is_imm, int imm, TCGv_i64 cdest)
1108 {
1109 uint64_t dest = s->base.pc_next + (int64_t)imm * 2;
1110 TCGLabel *lab;
1111
1112 /* Take care of the special cases first. */
1113 if (c->cond == TCG_COND_NEVER) {
1114 return DISAS_NEXT;
1115 }
1116 if (is_imm) {
1117 /*
1118 * Do not optimize a conditional branch if PER enabled, because we
1119 * still need a conditional call to helper_per_branch.
1120 */
1121 if (c->cond == TCG_COND_ALWAYS
1122 || (dest == s->pc_tmp &&
1123 !(s->base.tb->flags & FLAG_MASK_PER_BRANCH))) {
1124 return help_goto_direct(s, dest);
1125 }
1126 } else {
1127 if (!cdest) {
1128 /* E.g. bcr %r0 -> no branch. */
1129 return DISAS_NEXT;
1130 }
1131 if (c->cond == TCG_COND_ALWAYS) {
1132 return help_goto_indirect(s, cdest);
1133 }
1134 }
1135
1136 update_cc_op(s);
1137
1138 /*
1139 * Ensure the taken branch is fall-through of the tcg branch.
1140 * This keeps @cdest usage within the extended basic block,
1141 * which avoids an otherwise unnecessary spill to the stack.
1142 */
1143 lab = gen_new_label();
1144 if (c->is_64) {
1145 tcg_gen_brcond_i64(tcg_invert_cond(c->cond),
1146 c->u.s64.a, c->u.s64.b, lab);
1147 } else {
1148 tcg_gen_brcond_i32(tcg_invert_cond(c->cond),
1149 c->u.s32.a, c->u.s32.b, lab);
1150 }
1151
1152 /* Branch taken. */
1153 per_breaking_event(s);
1154 if (is_imm) {
1155 tcg_gen_movi_i64(psw_addr, dest);
1156 } else {
1157 tcg_gen_mov_i64(psw_addr, cdest);
1158 }
1159 per_branch(s, psw_addr);
1160
1161 if (is_imm && use_goto_tb(s, dest)) {
1162 tcg_gen_goto_tb(0);
1163 tcg_gen_exit_tb(s->base.tb, 0);
1164 } else {
1165 tcg_gen_lookup_and_goto_ptr();
1166 }
1167
1168 gen_set_label(lab);
1169
1170 /* Branch not taken. */
1171 tcg_gen_movi_i64(psw_addr, s->pc_tmp);
1172 if (use_goto_tb(s, s->pc_tmp)) {
1173 tcg_gen_goto_tb(1);
1174 tcg_gen_exit_tb(s->base.tb, 1);
1175 return DISAS_NORETURN;
1176 }
1177 return DISAS_PC_CC_UPDATED;
1178 }
1179
1180 /* ====================================================================== */
1181 /* The operations. These perform the bulk of the work for any insn,
1182 usually after the operands have been loaded and output initialized. */
1183
1184 static DisasJumpType op_abs(DisasContext *s, DisasOps *o)
1185 {
1186 tcg_gen_abs_i64(o->out, o->in2);
1187 return DISAS_NEXT;
1188 }
1189
1190 static DisasJumpType op_absf32(DisasContext *s, DisasOps *o)
1191 {
1192 tcg_gen_andi_i64(o->out, o->in2, 0x7fffffffull);
1193 return DISAS_NEXT;
1194 }
1195
1196 static DisasJumpType op_absf64(DisasContext *s, DisasOps *o)
1197 {
1198 tcg_gen_andi_i64(o->out, o->in2, 0x7fffffffffffffffull);
1199 return DISAS_NEXT;
1200 }
1201
1202 static DisasJumpType op_absf128(DisasContext *s, DisasOps *o)
1203 {
1204 tcg_gen_andi_i64(o->out, o->in1, 0x7fffffffffffffffull);
1205 tcg_gen_mov_i64(o->out2, o->in2);
1206 return DISAS_NEXT;
1207 }
1208
1209 static DisasJumpType op_add(DisasContext *s, DisasOps *o)
1210 {
1211 tcg_gen_add_i64(o->out, o->in1, o->in2);
1212 return DISAS_NEXT;
1213 }
1214
1215 static DisasJumpType op_addu64(DisasContext *s, DisasOps *o)
1216 {
1217 tcg_gen_movi_i64(cc_src, 0);
1218 tcg_gen_add2_i64(o->out, cc_src, o->in1, cc_src, o->in2, cc_src);
1219 return DISAS_NEXT;
1220 }
1221
1222 /* Compute carry into cc_src. */
1223 static void compute_carry(DisasContext *s)
1224 {
1225 switch (s->cc_op) {
1226 case CC_OP_ADDU:
1227 /* The carry value is already in cc_src (1,0). */
1228 break;
1229 case CC_OP_SUBU:
1230 tcg_gen_addi_i64(cc_src, cc_src, 1);
1231 break;
1232 default:
1233 gen_op_calc_cc(s);
1234 /* fall through */
1235 case CC_OP_STATIC:
1236 /* The carry flag is the msb of CC; compute into cc_src. */
1237 tcg_gen_extu_i32_i64(cc_src, cc_op);
1238 tcg_gen_shri_i64(cc_src, cc_src, 1);
1239 break;
1240 }
1241 }
1242
1243 static DisasJumpType op_addc32(DisasContext *s, DisasOps *o)
1244 {
1245 compute_carry(s);
1246 tcg_gen_add_i64(o->out, o->in1, o->in2);
1247 tcg_gen_add_i64(o->out, o->out, cc_src);
1248 return DISAS_NEXT;
1249 }
1250
1251 static DisasJumpType op_addc64(DisasContext *s, DisasOps *o)
1252 {
1253 compute_carry(s);
1254 tcg_gen_addcio_i64(o->out, cc_src, o->in1, o->in2, cc_src);
1255 return DISAS_NEXT;
1256 }
1257
1258 static DisasJumpType op_asi(DisasContext *s, DisasOps *o)
1259 {
1260 bool non_atomic = !s390_has_feat(S390_FEAT_STFLE_45);
1261
1262 o->in1 = tcg_temp_new_i64();
1263 if (non_atomic) {
1264 tcg_gen_qemu_ld_i64(o->in1, o->addr1, get_mem_index(s), s->insn->data);
1265 } else {
1266 /* Perform the atomic addition in memory. */
1267 tcg_gen_atomic_fetch_add_i64(o->in1, o->addr1, o->in2, get_mem_index(s),
1268 s->insn->data);
1269 }
1270
1271 /* Recompute also for atomic case: needed for setting CC. */
1272 tcg_gen_add_i64(o->out, o->in1, o->in2);
1273
1274 if (non_atomic) {
1275 tcg_gen_qemu_st_i64(o->out, o->addr1, get_mem_index(s), s->insn->data);
1276 }
1277 return DISAS_NEXT;
1278 }
1279
1280 static DisasJumpType op_asiu64(DisasContext *s, DisasOps *o)
1281 {
1282 bool non_atomic = !s390_has_feat(S390_FEAT_STFLE_45);
1283
1284 o->in1 = tcg_temp_new_i64();
1285 if (non_atomic) {
1286 tcg_gen_qemu_ld_i64(o->in1, o->addr1, get_mem_index(s), s->insn->data);
1287 } else {
1288 /* Perform the atomic addition in memory. */
1289 tcg_gen_atomic_fetch_add_i64(o->in1, o->addr1, o->in2, get_mem_index(s),
1290 s->insn->data);
1291 }
1292
1293 /* Recompute also for atomic case: needed for setting CC. */
1294 tcg_gen_movi_i64(cc_src, 0);
1295 tcg_gen_add2_i64(o->out, cc_src, o->in1, cc_src, o->in2, cc_src);
1296
1297 if (non_atomic) {
1298 tcg_gen_qemu_st_i64(o->out, o->addr1, get_mem_index(s), s->insn->data);
1299 }
1300 return DISAS_NEXT;
1301 }
1302
1303 static DisasJumpType op_aeb(DisasContext *s, DisasOps *o)
1304 {
1305 gen_helper_aeb(o->out, tcg_env, o->in1, o->in2);
1306 return DISAS_NEXT;
1307 }
1308
1309 static DisasJumpType op_adb(DisasContext *s, DisasOps *o)
1310 {
1311 gen_helper_adb(o->out, tcg_env, o->in1, o->in2);
1312 return DISAS_NEXT;
1313 }
1314
1315 static DisasJumpType op_axb(DisasContext *s, DisasOps *o)
1316 {
1317 gen_helper_axb(o->out_128, tcg_env, o->in1_128, o->in2_128);
1318 return DISAS_NEXT;
1319 }
1320
1321 static DisasJumpType op_and(DisasContext *s, DisasOps *o)
1322 {
1323 tcg_gen_and_i64(o->out, o->in1, o->in2);
1324 return DISAS_NEXT;
1325 }
1326
1327 static DisasJumpType op_andi(DisasContext *s, DisasOps *o)
1328 {
1329 int shift = s->insn->data & 0xff;
1330 int size = s->insn->data >> 8;
1331 uint64_t mask = ((1ull << size) - 1) << shift;
1332 TCGv_i64 t = tcg_temp_new_i64();
1333
1334 tcg_gen_shli_i64(t, o->in2, shift);
1335 tcg_gen_ori_i64(t, t, ~mask);
1336 tcg_gen_and_i64(o->out, o->in1, t);
1337
1338 /* Produce the CC from only the bits manipulated. */
1339 tcg_gen_andi_i64(cc_dst, o->out, mask);
1340 set_cc_nz_u64(s, cc_dst);
1341 return DISAS_NEXT;
1342 }
1343
1344 static DisasJumpType op_andc(DisasContext *s, DisasOps *o)
1345 {
1346 tcg_gen_andc_i64(o->out, o->in1, o->in2);
1347 return DISAS_NEXT;
1348 }
1349
1350 static DisasJumpType op_orc(DisasContext *s, DisasOps *o)
1351 {
1352 tcg_gen_orc_i64(o->out, o->in1, o->in2);
1353 return DISAS_NEXT;
1354 }
1355
1356 static DisasJumpType op_nand(DisasContext *s, DisasOps *o)
1357 {
1358 tcg_gen_nand_i64(o->out, o->in1, o->in2);
1359 return DISAS_NEXT;
1360 }
1361
1362 static DisasJumpType op_nor(DisasContext *s, DisasOps *o)
1363 {
1364 tcg_gen_nor_i64(o->out, o->in1, o->in2);
1365 return DISAS_NEXT;
1366 }
1367
1368 static DisasJumpType op_nxor(DisasContext *s, DisasOps *o)
1369 {
1370 tcg_gen_eqv_i64(o->out, o->in1, o->in2);
1371 return DISAS_NEXT;
1372 }
1373
1374 static DisasJumpType op_ni(DisasContext *s, DisasOps *o)
1375 {
1376 o->in1 = tcg_temp_new_i64();
1377
1378 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
1379 tcg_gen_qemu_ld_i64(o->in1, o->addr1, get_mem_index(s), s->insn->data);
1380 } else {
1381 /* Perform the atomic operation in memory. */
1382 tcg_gen_atomic_fetch_and_i64(o->in1, o->addr1, o->in2, get_mem_index(s),
1383 s->insn->data);
1384 }
1385
1386 /* Recompute also for atomic case: needed for setting CC. */
1387 tcg_gen_and_i64(o->out, o->in1, o->in2);
1388
1389 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
1390 tcg_gen_qemu_st_i64(o->out, o->addr1, get_mem_index(s), s->insn->data);
1391 }
1392 return DISAS_NEXT;
1393 }
1394
1395 static DisasJumpType op_bas(DisasContext *s, DisasOps *o)
1396 {
1397 pc_to_link_info(o->out, s, s->pc_tmp);
1398 if (o->in2) {
1399 return help_goto_indirect(s, o->in2);
1400 } else {
1401 return DISAS_NEXT;
1402 }
1403 }
1404
1405 static void save_link_info(DisasContext *s, DisasOps *o)
1406 {
1407 TCGv_i64 t;
1408
1409 if (s->base.tb->flags & (FLAG_MASK_32 | FLAG_MASK_64)) {
1410 pc_to_link_info(o->out, s, s->pc_tmp);
1411 return;
1412 }
1413 gen_op_calc_cc(s);
1414 tcg_gen_andi_i64(o->out, o->out, 0xffffffff00000000ull);
1415 tcg_gen_ori_i64(o->out, o->out, ((s->ilen / 2) << 30) | s->pc_tmp);
1416 t = tcg_temp_new_i64();
1417 tcg_gen_shri_i64(t, psw_mask, 16);
1418 tcg_gen_andi_i64(t, t, 0x0f000000);
1419 tcg_gen_or_i64(o->out, o->out, t);
1420 tcg_gen_extu_i32_i64(t, cc_op);
1421 tcg_gen_shli_i64(t, t, 28);
1422 tcg_gen_or_i64(o->out, o->out, t);
1423 }
1424
1425 static DisasJumpType op_bal(DisasContext *s, DisasOps *o)
1426 {
1427 save_link_info(s, o);
1428 if (o->in2) {
1429 return help_goto_indirect(s, o->in2);
1430 } else {
1431 return DISAS_NEXT;
1432 }
1433 }
1434
1435 /*
1436 * Disassemble the target of a branch. The results are returned in a form
1437 * suitable for passing into help_branch():
1438 *
1439 * - bool IS_IMM reflects whether the target is fixed or computed. Non-EXECUTEd
1440 * branches, whose DisasContext *S contains the relative immediate field RI,
1441 * are considered fixed. All the other branches are considered computed.
1442 * - int IMM is the value of RI.
1443 * - TCGv_i64 CDEST is the address of the computed target.
1444 */
1445 #define disas_jdest(s, ri, is_imm, imm, cdest) do { \
1446 if (have_field(s, ri)) { \
1447 if (unlikely(s->ex_value)) { \
1448 cdest = tcg_temp_new_i64(); \
1449 tcg_gen_ld_i64(cdest, tcg_env, offsetof(CPUS390XState, ex_target));\
1450 tcg_gen_addi_i64(cdest, cdest, (int64_t)get_field(s, ri) * 2); \
1451 is_imm = false; \
1452 } else { \
1453 is_imm = true; \
1454 } \
1455 } else { \
1456 is_imm = false; \
1457 } \
1458 imm = is_imm ? get_field(s, ri) : 0; \
1459 } while (false)
1460
1461 static DisasJumpType op_basi(DisasContext *s, DisasOps *o)
1462 {
1463 DisasCompare c;
1464 bool is_imm;
1465 int imm;
1466
1467 pc_to_link_info(o->out, s, s->pc_tmp);
1468
1469 disas_jdest(s, i2, is_imm, imm, o->in2);
1470 disas_jcc(s, &c, 0xf);
1471 return help_branch(s, &c, is_imm, imm, o->in2);
1472 }
1473
1474 static DisasJumpType op_bc(DisasContext *s, DisasOps *o)
1475 {
1476 int m1 = get_field(s, m1);
1477 DisasCompare c;
1478 bool is_imm;
1479 int imm;
1480
1481 /* BCR with R2 = 0 causes no branching */
1482 if (have_field(s, r2) && get_field(s, r2) == 0) {
1483 if (m1 == 14) {
1484 /* Perform serialization */
1485 /* FIXME: check for fast-BCR-serialization facility */
1486 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
1487 }
1488 if (m1 == 15) {
1489 /* Perform serialization */
1490 /* FIXME: perform checkpoint-synchronisation */
1491 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
1492 }
1493 return DISAS_NEXT;
1494 }
1495
1496 disas_jdest(s, i2, is_imm, imm, o->in2);
1497 disas_jcc(s, &c, m1);
1498 return help_branch(s, &c, is_imm, imm, o->in2);
1499 }
1500
1501 static DisasJumpType op_bct32(DisasContext *s, DisasOps *o)
1502 {
1503 int r1 = get_field(s, r1);
1504 DisasCompare c;
1505 bool is_imm;
1506 TCGv_i64 t;
1507 int imm;
1508
1509 c.cond = TCG_COND_NE;
1510 c.is_64 = false;
1511
1512 t = tcg_temp_new_i64();
1513 tcg_gen_subi_i64(t, regs[r1], 1);
1514 store_reg32_i64(r1, t);
1515 c.u.s32.a = tcg_temp_new_i32();
1516 c.u.s32.b = tcg_constant_i32(0);
1517 tcg_gen_extrl_i64_i32(c.u.s32.a, t);
1518
1519 disas_jdest(s, i2, is_imm, imm, o->in2);
1520 return help_branch(s, &c, is_imm, imm, o->in2);
1521 }
1522
1523 static DisasJumpType op_bcth(DisasContext *s, DisasOps *o)
1524 {
1525 int r1 = get_field(s, r1);
1526 int imm = get_field(s, i2);
1527 DisasCompare c;
1528 TCGv_i64 t;
1529
1530 c.cond = TCG_COND_NE;
1531 c.is_64 = false;
1532
1533 t = tcg_temp_new_i64();
1534 tcg_gen_shri_i64(t, regs[r1], 32);
1535 tcg_gen_subi_i64(t, t, 1);
1536 store_reg32h_i64(r1, t);
1537 c.u.s32.a = tcg_temp_new_i32();
1538 c.u.s32.b = tcg_constant_i32(0);
1539 tcg_gen_extrl_i64_i32(c.u.s32.a, t);
1540
1541 return help_branch(s, &c, 1, imm, o->in2);
1542 }
1543
1544 static DisasJumpType op_bct64(DisasContext *s, DisasOps *o)
1545 {
1546 int r1 = get_field(s, r1);
1547 DisasCompare c;
1548 bool is_imm;
1549 int imm;
1550
1551 c.cond = TCG_COND_NE;
1552 c.is_64 = true;
1553
1554 tcg_gen_subi_i64(regs[r1], regs[r1], 1);
1555 c.u.s64.a = regs[r1];
1556 c.u.s64.b = tcg_constant_i64(0);
1557
1558 disas_jdest(s, i2, is_imm, imm, o->in2);
1559 return help_branch(s, &c, is_imm, imm, o->in2);
1560 }
1561
1562 static DisasJumpType op_bx32(DisasContext *s, DisasOps *o)
1563 {
1564 int r1 = get_field(s, r1);
1565 int r3 = get_field(s, r3);
1566 DisasCompare c;
1567 bool is_imm;
1568 TCGv_i64 t;
1569 int imm;
1570
1571 c.cond = (s->insn->data ? TCG_COND_LE : TCG_COND_GT);
1572 c.is_64 = false;
1573
1574 t = tcg_temp_new_i64();
1575 tcg_gen_add_i64(t, regs[r1], regs[r3]);
1576 c.u.s32.a = tcg_temp_new_i32();
1577 c.u.s32.b = tcg_temp_new_i32();
1578 tcg_gen_extrl_i64_i32(c.u.s32.a, t);
1579 tcg_gen_extrl_i64_i32(c.u.s32.b, regs[r3 | 1]);
1580 store_reg32_i64(r1, t);
1581
1582 disas_jdest(s, i2, is_imm, imm, o->in2);
1583 return help_branch(s, &c, is_imm, imm, o->in2);
1584 }
1585
1586 static DisasJumpType op_bx64(DisasContext *s, DisasOps *o)
1587 {
1588 int r1 = get_field(s, r1);
1589 int r3 = get_field(s, r3);
1590 DisasCompare c;
1591 bool is_imm;
1592 int imm;
1593
1594 c.cond = (s->insn->data ? TCG_COND_LE : TCG_COND_GT);
1595 c.is_64 = true;
1596
1597 if (r1 == (r3 | 1)) {
1598 c.u.s64.b = load_reg(r3 | 1);
1599 } else {
1600 c.u.s64.b = regs[r3 | 1];
1601 }
1602
1603 tcg_gen_add_i64(regs[r1], regs[r1], regs[r3]);
1604 c.u.s64.a = regs[r1];
1605
1606 disas_jdest(s, i2, is_imm, imm, o->in2);
1607 return help_branch(s, &c, is_imm, imm, o->in2);
1608 }
1609
1610 static DisasJumpType op_cj(DisasContext *s, DisasOps *o)
1611 {
1612 int imm, m3 = get_field(s, m3);
1613 bool is_imm;
1614 DisasCompare c;
1615
1616 c.cond = ltgt_cond[m3];
1617 if (s->insn->data) {
1618 c.cond = tcg_unsigned_cond(c.cond);
1619 }
1620 c.is_64 = true;
1621 c.u.s64.a = o->in1;
1622 c.u.s64.b = o->in2;
1623
1624 o->out = NULL;
1625 disas_jdest(s, i4, is_imm, imm, o->out);
1626 if (!is_imm && !o->out) {
1627 imm = 0;
1628 o->out = get_address(s, 0, get_field(s, b4),
1629 get_field(s, d4));
1630 }
1631
1632 return help_branch(s, &c, is_imm, imm, o->out);
1633 }
1634
1635 static DisasJumpType op_ceb(DisasContext *s, DisasOps *o)
1636 {
1637 gen_helper_ceb(cc_op, tcg_env, o->in1, o->in2);
1638 set_cc_static(s);
1639 return DISAS_NEXT;
1640 }
1641
1642 static DisasJumpType op_cdb(DisasContext *s, DisasOps *o)
1643 {
1644 gen_helper_cdb(cc_op, tcg_env, o->in1, o->in2);
1645 set_cc_static(s);
1646 return DISAS_NEXT;
1647 }
1648
1649 static DisasJumpType op_cxb(DisasContext *s, DisasOps *o)
1650 {
1651 gen_helper_cxb(cc_op, tcg_env, o->in1_128, o->in2_128);
1652 set_cc_static(s);
1653 return DISAS_NEXT;
1654 }
1655
1656 static TCGv_i32 fpinst_extract_m34(DisasContext *s, bool m3_with_fpe,
1657 bool m4_with_fpe)
1658 {
1659 const bool fpe = s390_has_feat(S390_FEAT_FLOATING_POINT_EXT);
1660 uint8_t m3 = get_field(s, m3);
1661 uint8_t m4 = get_field(s, m4);
1662
1663 /* m3 field was introduced with FPE */
1664 if (!fpe && m3_with_fpe) {
1665 m3 = 0;
1666 }
1667 /* m4 field was introduced with FPE */
1668 if (!fpe && m4_with_fpe) {
1669 m4 = 0;
1670 }
1671
1672 /* Check for valid rounding modes. Mode 3 was introduced later. */
1673 if (m3 == 2 || m3 > 7 || (!fpe && m3 == 3)) {
1674 gen_program_exception(s, PGM_SPECIFICATION);
1675 return NULL;
1676 }
1677
1678 return tcg_constant_i32(deposit32(m3, 4, 4, m4));
1679 }
1680
1681 static DisasJumpType op_cfeb(DisasContext *s, DisasOps *o)
1682 {
1683 TCGv_i32 m34 = fpinst_extract_m34(s, false, true);
1684
1685 if (!m34) {
1686 return DISAS_NORETURN;
1687 }
1688 gen_helper_cfeb(o->out, tcg_env, o->in2, m34);
1689 set_cc_static(s);
1690 return DISAS_NEXT;
1691 }
1692
1693 static DisasJumpType op_cfdb(DisasContext *s, DisasOps *o)
1694 {
1695 TCGv_i32 m34 = fpinst_extract_m34(s, false, true);
1696
1697 if (!m34) {
1698 return DISAS_NORETURN;
1699 }
1700 gen_helper_cfdb(o->out, tcg_env, o->in2, m34);
1701 set_cc_static(s);
1702 return DISAS_NEXT;
1703 }
1704
1705 static DisasJumpType op_cfxb(DisasContext *s, DisasOps *o)
1706 {
1707 TCGv_i32 m34 = fpinst_extract_m34(s, false, true);
1708
1709 if (!m34) {
1710 return DISAS_NORETURN;
1711 }
1712 gen_helper_cfxb(o->out, tcg_env, o->in2_128, m34);
1713 set_cc_static(s);
1714 return DISAS_NEXT;
1715 }
1716
1717 static DisasJumpType op_cgeb(DisasContext *s, DisasOps *o)
1718 {
1719 TCGv_i32 m34 = fpinst_extract_m34(s, false, true);
1720
1721 if (!m34) {
1722 return DISAS_NORETURN;
1723 }
1724 gen_helper_cgeb(o->out, tcg_env, o->in2, m34);
1725 set_cc_static(s);
1726 return DISAS_NEXT;
1727 }
1728
1729 static DisasJumpType op_cgdb(DisasContext *s, DisasOps *o)
1730 {
1731 TCGv_i32 m34 = fpinst_extract_m34(s, false, true);
1732
1733 if (!m34) {
1734 return DISAS_NORETURN;
1735 }
1736 gen_helper_cgdb(o->out, tcg_env, o->in2, m34);
1737 set_cc_static(s);
1738 return DISAS_NEXT;
1739 }
1740
1741 static DisasJumpType op_cgxb(DisasContext *s, DisasOps *o)
1742 {
1743 TCGv_i32 m34 = fpinst_extract_m34(s, false, true);
1744
1745 if (!m34) {
1746 return DISAS_NORETURN;
1747 }
1748 gen_helper_cgxb(o->out, tcg_env, o->in2_128, m34);
1749 set_cc_static(s);
1750 return DISAS_NEXT;
1751 }
1752
1753 static DisasJumpType op_clfeb(DisasContext *s, DisasOps *o)
1754 {
1755 TCGv_i32 m34 = fpinst_extract_m34(s, false, false);
1756
1757 if (!m34) {
1758 return DISAS_NORETURN;
1759 }
1760 gen_helper_clfeb(o->out, tcg_env, o->in2, m34);
1761 set_cc_static(s);
1762 return DISAS_NEXT;
1763 }
1764
1765 static DisasJumpType op_clfdb(DisasContext *s, DisasOps *o)
1766 {
1767 TCGv_i32 m34 = fpinst_extract_m34(s, false, false);
1768
1769 if (!m34) {
1770 return DISAS_NORETURN;
1771 }
1772 gen_helper_clfdb(o->out, tcg_env, o->in2, m34);
1773 set_cc_static(s);
1774 return DISAS_NEXT;
1775 }
1776
1777 static DisasJumpType op_clfxb(DisasContext *s, DisasOps *o)
1778 {
1779 TCGv_i32 m34 = fpinst_extract_m34(s, false, false);
1780
1781 if (!m34) {
1782 return DISAS_NORETURN;
1783 }
1784 gen_helper_clfxb(o->out, tcg_env, o->in2_128, m34);
1785 set_cc_static(s);
1786 return DISAS_NEXT;
1787 }
1788
1789 static DisasJumpType op_clgeb(DisasContext *s, DisasOps *o)
1790 {
1791 TCGv_i32 m34 = fpinst_extract_m34(s, false, false);
1792
1793 if (!m34) {
1794 return DISAS_NORETURN;
1795 }
1796 gen_helper_clgeb(o->out, tcg_env, o->in2, m34);
1797 set_cc_static(s);
1798 return DISAS_NEXT;
1799 }
1800
1801 static DisasJumpType op_clgdb(DisasContext *s, DisasOps *o)
1802 {
1803 TCGv_i32 m34 = fpinst_extract_m34(s, false, false);
1804
1805 if (!m34) {
1806 return DISAS_NORETURN;
1807 }
1808 gen_helper_clgdb(o->out, tcg_env, o->in2, m34);
1809 set_cc_static(s);
1810 return DISAS_NEXT;
1811 }
1812
1813 static DisasJumpType op_clgxb(DisasContext *s, DisasOps *o)
1814 {
1815 TCGv_i32 m34 = fpinst_extract_m34(s, false, false);
1816
1817 if (!m34) {
1818 return DISAS_NORETURN;
1819 }
1820 gen_helper_clgxb(o->out, tcg_env, o->in2_128, m34);
1821 set_cc_static(s);
1822 return DISAS_NEXT;
1823 }
1824
1825 static DisasJumpType op_cegb(DisasContext *s, DisasOps *o)
1826 {
1827 TCGv_i32 m34 = fpinst_extract_m34(s, true, true);
1828
1829 if (!m34) {
1830 return DISAS_NORETURN;
1831 }
1832 gen_helper_cegb(o->out, tcg_env, o->in2, m34);
1833 return DISAS_NEXT;
1834 }
1835
1836 static DisasJumpType op_cdgb(DisasContext *s, DisasOps *o)
1837 {
1838 TCGv_i32 m34 = fpinst_extract_m34(s, true, true);
1839
1840 if (!m34) {
1841 return DISAS_NORETURN;
1842 }
1843 gen_helper_cdgb(o->out, tcg_env, o->in2, m34);
1844 return DISAS_NEXT;
1845 }
1846
1847 static DisasJumpType op_cxgb(DisasContext *s, DisasOps *o)
1848 {
1849 TCGv_i32 m34 = fpinst_extract_m34(s, true, true);
1850
1851 if (!m34) {
1852 return DISAS_NORETURN;
1853 }
1854 gen_helper_cxgb(o->out_128, tcg_env, o->in2, m34);
1855 return DISAS_NEXT;
1856 }
1857
1858 static DisasJumpType op_celgb(DisasContext *s, DisasOps *o)
1859 {
1860 TCGv_i32 m34 = fpinst_extract_m34(s, false, false);
1861
1862 if (!m34) {
1863 return DISAS_NORETURN;
1864 }
1865 gen_helper_celgb(o->out, tcg_env, o->in2, m34);
1866 return DISAS_NEXT;
1867 }
1868
1869 static DisasJumpType op_cdlgb(DisasContext *s, DisasOps *o)
1870 {
1871 TCGv_i32 m34 = fpinst_extract_m34(s, false, false);
1872
1873 if (!m34) {
1874 return DISAS_NORETURN;
1875 }
1876 gen_helper_cdlgb(o->out, tcg_env, o->in2, m34);
1877 return DISAS_NEXT;
1878 }
1879
1880 static DisasJumpType op_cxlgb(DisasContext *s, DisasOps *o)
1881 {
1882 TCGv_i32 m34 = fpinst_extract_m34(s, false, false);
1883
1884 if (!m34) {
1885 return DISAS_NORETURN;
1886 }
1887 gen_helper_cxlgb(o->out_128, tcg_env, o->in2, m34);
1888 return DISAS_NEXT;
1889 }
1890
1891 static DisasJumpType op_cksm(DisasContext *s, DisasOps *o)
1892 {
1893 int r2 = get_field(s, r2);
1894 TCGv_i128 pair = tcg_temp_new_i128();
1895 TCGv_i64 len = tcg_temp_new_i64();
1896
1897 gen_helper_cksm(pair, tcg_env, o->in1, o->in2, regs[r2 + 1]);
1898 set_cc_static(s);
1899 tcg_gen_extr_i128_i64(o->out, len, pair);
1900
1901 tcg_gen_add_i64(regs[r2], regs[r2], len);
1902 tcg_gen_sub_i64(regs[r2 + 1], regs[r2 + 1], len);
1903
1904 return DISAS_NEXT;
1905 }
1906
1907 static DisasJumpType op_clc(DisasContext *s, DisasOps *o)
1908 {
1909 int l = get_field(s, l1);
1910 TCGv_i64 src;
1911 TCGv_i32 vl;
1912 MemOp mop;
1913
1914 switch (l + 1) {
1915 case 1:
1916 case 2:
1917 case 4:
1918 case 8:
1919 mop = ctz32(l + 1) | MO_BE;
1920 /* Do not update cc_src yet: loading cc_dst may cause an exception. */
1921 src = tcg_temp_new_i64();
1922 tcg_gen_qemu_ld_i64(src, o->addr1, get_mem_index(s), mop);
1923 tcg_gen_qemu_ld_i64(cc_dst, o->in2, get_mem_index(s), mop);
1924 gen_op_update2_cc_i64(s, CC_OP_LTUGTU_64, src, cc_dst);
1925 return DISAS_NEXT;
1926 default:
1927 vl = tcg_constant_i32(l);
1928 gen_helper_clc(cc_op, tcg_env, vl, o->addr1, o->in2);
1929 set_cc_static(s);
1930 return DISAS_NEXT;
1931 }
1932 }
1933
1934 static DisasJumpType op_clcl(DisasContext *s, DisasOps *o)
1935 {
1936 int r1 = get_field(s, r1);
1937 int r2 = get_field(s, r2);
1938 TCGv_i32 t1, t2;
1939
1940 /* r1 and r2 must be even. */
1941 if (r1 & 1 || r2 & 1) {
1942 gen_program_exception(s, PGM_SPECIFICATION);
1943 return DISAS_NORETURN;
1944 }
1945
1946 t1 = tcg_constant_i32(r1);
1947 t2 = tcg_constant_i32(r2);
1948 gen_helper_clcl(cc_op, tcg_env, t1, t2);
1949 set_cc_static(s);
1950 return DISAS_NEXT;
1951 }
1952
1953 static DisasJumpType op_clcle(DisasContext *s, DisasOps *o)
1954 {
1955 int r1 = get_field(s, r1);
1956 int r3 = get_field(s, r3);
1957 TCGv_i32 t1, t3;
1958
1959 /* r1 and r3 must be even. */
1960 if (r1 & 1 || r3 & 1) {
1961 gen_program_exception(s, PGM_SPECIFICATION);
1962 return DISAS_NORETURN;
1963 }
1964
1965 t1 = tcg_constant_i32(r1);
1966 t3 = tcg_constant_i32(r3);
1967 gen_helper_clcle(cc_op, tcg_env, t1, o->in2, t3);
1968 set_cc_static(s);
1969 return DISAS_NEXT;
1970 }
1971
1972 static DisasJumpType op_clclu(DisasContext *s, DisasOps *o)
1973 {
1974 int r1 = get_field(s, r1);
1975 int r3 = get_field(s, r3);
1976 TCGv_i32 t1, t3;
1977
1978 /* r1 and r3 must be even. */
1979 if (r1 & 1 || r3 & 1) {
1980 gen_program_exception(s, PGM_SPECIFICATION);
1981 return DISAS_NORETURN;
1982 }
1983
1984 t1 = tcg_constant_i32(r1);
1985 t3 = tcg_constant_i32(r3);
1986 gen_helper_clclu(cc_op, tcg_env, t1, o->in2, t3);
1987 set_cc_static(s);
1988 return DISAS_NEXT;
1989 }
1990
1991 static DisasJumpType op_clm(DisasContext *s, DisasOps *o)
1992 {
1993 TCGv_i32 m3 = tcg_constant_i32(get_field(s, m3));
1994 TCGv_i32 t1 = tcg_temp_new_i32();
1995
1996 tcg_gen_extrl_i64_i32(t1, o->in1);
1997 gen_helper_clm(cc_op, tcg_env, t1, m3, o->in2);
1998 set_cc_static(s);
1999 return DISAS_NEXT;
2000 }
2001
2002 static DisasJumpType op_clst(DisasContext *s, DisasOps *o)
2003 {
2004 TCGv_i128 pair = tcg_temp_new_i128();
2005
2006 gen_helper_clst(pair, tcg_env, regs[0], o->in1, o->in2);
2007 tcg_gen_extr_i128_i64(o->in2, o->in1, pair);
2008
2009 set_cc_static(s);
2010 return DISAS_NEXT;
2011 }
2012
2013 static DisasJumpType op_cps(DisasContext *s, DisasOps *o)
2014 {
2015 TCGv_i64 t = tcg_temp_new_i64();
2016 tcg_gen_andi_i64(t, o->in1, 0x8000000000000000ull);
2017 tcg_gen_andi_i64(o->out, o->in2, 0x7fffffffffffffffull);
2018 tcg_gen_or_i64(o->out, o->out, t);
2019 return DISAS_NEXT;
2020 }
2021
2022 static DisasJumpType op_cs(DisasContext *s, DisasOps *o)
2023 {
2024 int d2 = get_field(s, d2);
2025 int b2 = get_field(s, b2);
2026 TCGv_i64 addr, cc;
2027
2028 /* Note that in1 = R3 (new value) and
2029 in2 = (zero-extended) R1 (expected value). */
2030
2031 addr = get_address(s, 0, b2, d2);
2032 tcg_gen_atomic_cmpxchg_i64(o->out, addr, o->in2, o->in1,
2033 get_mem_index(s), s->insn->data | MO_ALIGN);
2034
2035 /* Are the memory and expected values (un)equal? Note that this setcond
2036 produces the output CC value, thus the NE sense of the test. */
2037 cc = tcg_temp_new_i64();
2038 tcg_gen_setcond_i64(TCG_COND_NE, cc, o->in2, o->out);
2039 tcg_gen_extrl_i64_i32(cc_op, cc);
2040 set_cc_static(s);
2041
2042 return DISAS_NEXT;
2043 }
2044
2045 static DisasJumpType op_cdsg(DisasContext *s, DisasOps *o)
2046 {
2047 int r1 = get_field(s, r1);
2048
2049 o->out_128 = tcg_temp_new_i128();
2050 tcg_gen_concat_i64_i128(o->out_128, regs[r1 + 1], regs[r1]);
2051
2052 /* Note out (R1:R1+1) = expected value and in2 (R3:R3+1) = new value. */
2053 tcg_gen_atomic_cmpxchg_i128(o->out_128, o->addr1, o->out_128, o->in2_128,
2054 get_mem_index(s), MO_BE | MO_128 | MO_ALIGN);
2055
2056 /*
2057 * Extract result into cc_dst:cc_src, compare vs the expected value
2058 * in the as yet unmodified input registers, then update CC_OP.
2059 */
2060 tcg_gen_extr_i128_i64(cc_src, cc_dst, o->out_128);
2061 tcg_gen_xor_i64(cc_dst, cc_dst, regs[r1]);
2062 tcg_gen_xor_i64(cc_src, cc_src, regs[r1 + 1]);
2063 tcg_gen_or_i64(cc_dst, cc_dst, cc_src);
2064 set_cc_nz_u64(s, cc_dst);
2065
2066 return DISAS_NEXT;
2067 }
2068
2069 static DisasJumpType op_csst(DisasContext *s, DisasOps *o)
2070 {
2071 int r3 = get_field(s, r3);
2072 TCGv_i32 t_r3 = tcg_constant_i32(r3);
2073
2074 if (tb_cflags(s->base.tb) & CF_PARALLEL) {
2075 gen_helper_csst_parallel(cc_op, tcg_env, t_r3, o->addr1, o->in2);
2076 } else {
2077 gen_helper_csst(cc_op, tcg_env, t_r3, o->addr1, o->in2);
2078 }
2079
2080 set_cc_static(s);
2081 return DISAS_NEXT;
2082 }
2083
2084 #ifndef CONFIG_USER_ONLY
2085 static DisasJumpType op_csp(DisasContext *s, DisasOps *o)
2086 {
2087 MemOp mop = s->insn->data;
2088 TCGv_i64 addr, old, cc;
2089 TCGLabel *lab = gen_new_label();
2090
2091 /* Note that in1 = R1 (zero-extended expected value),
2092 out = R1 (original reg), out2 = R1+1 (new value). */
2093
2094 addr = tcg_temp_new_i64();
2095 old = tcg_temp_new_i64();
2096 tcg_gen_andi_i64(addr, o->in2, -1ULL << (mop & MO_SIZE));
2097 tcg_gen_atomic_cmpxchg_i64(old, addr, o->in1, o->out2,
2098 get_mem_index(s), mop | MO_ALIGN);
2099
2100 /* Are the memory and expected values (un)equal? */
2101 cc = tcg_temp_new_i64();
2102 tcg_gen_setcond_i64(TCG_COND_NE, cc, o->in1, old);
2103 tcg_gen_extrl_i64_i32(cc_op, cc);
2104
2105 /* Write back the output now, so that it happens before the
2106 following branch, so that we don't need local temps. */
2107 if ((mop & MO_SIZE) == MO_32) {
2108 tcg_gen_deposit_i64(o->out, o->out, old, 0, 32);
2109 } else {
2110 tcg_gen_mov_i64(o->out, old);
2111 }
2112
2113 /* If the comparison was equal, and the LSB of R2 was set,
2114 then we need to flush the TLB (for all cpus). */
2115 tcg_gen_xori_i64(cc, cc, 1);
2116 tcg_gen_and_i64(cc, cc, o->in2);
2117 tcg_gen_brcondi_i64(TCG_COND_EQ, cc, 0, lab);
2118
2119 gen_helper_purge(tcg_env);
2120 gen_set_label(lab);
2121
2122 return DISAS_NEXT;
2123 }
2124 #endif
2125
2126 static DisasJumpType op_cvb(DisasContext *s, DisasOps *o)
2127 {
2128 TCGv_i64 t = tcg_temp_new_i64();
2129 tcg_gen_qemu_ld_i64(t, o->addr1, get_mem_index(s), MO_BEUQ);
2130 gen_helper_cvb(tcg_env, tcg_constant_i32(get_field(s, r1)), t);
2131 return DISAS_NEXT;
2132 }
2133
2134 static DisasJumpType op_cvbg(DisasContext *s, DisasOps *o)
2135 {
2136 TCGv_i128 t = tcg_temp_new_i128();
2137 tcg_gen_qemu_ld_i128(t, o->addr1, get_mem_index(s), MO_BE | MO_128);
2138 gen_helper_cvbg(o->out, tcg_env, t);
2139 return DISAS_NEXT;
2140 }
2141
2142 static DisasJumpType op_cvd(DisasContext *s, DisasOps *o)
2143 {
2144 TCGv_i64 t1 = tcg_temp_new_i64();
2145 TCGv_i32 t2 = tcg_temp_new_i32();
2146 tcg_gen_extrl_i64_i32(t2, o->in1);
2147 gen_helper_cvd(t1, t2);
2148 tcg_gen_qemu_st_i64(t1, o->in2, get_mem_index(s), MO_BEUQ);
2149 return DISAS_NEXT;
2150 }
2151
2152 static DisasJumpType op_cvdg(DisasContext *s, DisasOps *o)
2153 {
2154 TCGv_i128 t = tcg_temp_new_i128();
2155 gen_helper_cvdg(t, o->in1);
2156 tcg_gen_qemu_st_i128(t, o->in2, get_mem_index(s), MO_BE | MO_128);
2157 return DISAS_NEXT;
2158 }
2159
2160 static DisasJumpType op_ct(DisasContext *s, DisasOps *o)
2161 {
2162 int m3 = get_field(s, m3);
2163 TCGLabel *lab = gen_new_label();
2164 TCGCond c;
2165
2166 c = tcg_invert_cond(ltgt_cond[m3]);
2167 if (s->insn->data) {
2168 c = tcg_unsigned_cond(c);
2169 }
2170 tcg_gen_brcond_i64(c, o->in1, o->in2, lab);
2171
2172 /* Trap. */
2173 gen_trap(s);
2174
2175 gen_set_label(lab);
2176 return DISAS_NEXT;
2177 }
2178
2179 static DisasJumpType op_cuXX(DisasContext *s, DisasOps *o)
2180 {
2181 int m3 = get_field(s, m3);
2182 int r1 = get_field(s, r1);
2183 int r2 = get_field(s, r2);
2184 TCGv_i32 tr1, tr2, chk;
2185
2186 /* R1 and R2 must both be even. */
2187 if ((r1 | r2) & 1) {
2188 gen_program_exception(s, PGM_SPECIFICATION);
2189 return DISAS_NORETURN;
2190 }
2191 if (!s390_has_feat(S390_FEAT_ETF3_ENH)) {
2192 m3 = 0;
2193 }
2194
2195 tr1 = tcg_constant_i32(r1);
2196 tr2 = tcg_constant_i32(r2);
2197 chk = tcg_constant_i32(m3);
2198
2199 switch (s->insn->data) {
2200 case 12:
2201 gen_helper_cu12(cc_op, tcg_env, tr1, tr2, chk);
2202 break;
2203 case 14:
2204 gen_helper_cu14(cc_op, tcg_env, tr1, tr2, chk);
2205 break;
2206 case 21:
2207 gen_helper_cu21(cc_op, tcg_env, tr1, tr2, chk);
2208 break;
2209 case 24:
2210 gen_helper_cu24(cc_op, tcg_env, tr1, tr2, chk);
2211 break;
2212 case 41:
2213 gen_helper_cu41(cc_op, tcg_env, tr1, tr2, chk);
2214 break;
2215 case 42:
2216 gen_helper_cu42(cc_op, tcg_env, tr1, tr2, chk);
2217 break;
2218 default:
2219 g_assert_not_reached();
2220 }
2221
2222 set_cc_static(s);
2223 return DISAS_NEXT;
2224 }
2225
2226 #ifndef CONFIG_USER_ONLY
2227 static DisasJumpType op_diag(DisasContext *s, DisasOps *o)
2228 {
2229 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
2230 TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
2231 TCGv_i32 func_code = tcg_constant_i32(get_field(s, i2));
2232
2233 gen_helper_diag(tcg_env, r1, r3, func_code);
2234 return DISAS_NEXT;
2235 }
2236 #endif
2237
2238 static DisasJumpType op_divs32(DisasContext *s, DisasOps *o)
2239 {
2240 gen_helper_divs32(o->out, tcg_env, o->in1, o->in2);
2241 tcg_gen_extr32_i64(o->out2, o->out, o->out);
2242 return DISAS_NEXT;
2243 }
2244
2245 static DisasJumpType op_divu32(DisasContext *s, DisasOps *o)
2246 {
2247 gen_helper_divu32(o->out, tcg_env, o->in1, o->in2);
2248 tcg_gen_extr32_i64(o->out2, o->out, o->out);
2249 return DISAS_NEXT;
2250 }
2251
2252 static DisasJumpType op_divs64(DisasContext *s, DisasOps *o)
2253 {
2254 TCGv_i128 t = tcg_temp_new_i128();
2255
2256 gen_helper_divs64(t, tcg_env, o->in1, o->in2);
2257 tcg_gen_extr_i128_i64(o->out2, o->out, t);
2258 return DISAS_NEXT;
2259 }
2260
2261 static DisasJumpType op_divu64(DisasContext *s, DisasOps *o)
2262 {
2263 TCGv_i128 t = tcg_temp_new_i128();
2264
2265 gen_helper_divu64(t, tcg_env, o->out, o->out2, o->in2);
2266 tcg_gen_extr_i128_i64(o->out2, o->out, t);
2267 return DISAS_NEXT;
2268 }
2269
2270 static DisasJumpType op_deb(DisasContext *s, DisasOps *o)
2271 {
2272 gen_helper_deb(o->out, tcg_env, o->in1, o->in2);
2273 return DISAS_NEXT;
2274 }
2275
2276 static DisasJumpType op_ddb(DisasContext *s, DisasOps *o)
2277 {
2278 gen_helper_ddb(o->out, tcg_env, o->in1, o->in2);
2279 return DISAS_NEXT;
2280 }
2281
2282 static DisasJumpType op_dxb(DisasContext *s, DisasOps *o)
2283 {
2284 gen_helper_dxb(o->out_128, tcg_env, o->in1_128, o->in2_128);
2285 return DISAS_NEXT;
2286 }
2287
2288 static DisasJumpType op_dib(DisasContext *s, DisasOps *o)
2289 {
2290 const bool fpe = s390_has_feat(S390_FEAT_FLOATING_POINT_EXT);
2291 uint8_t m4 = get_field(s, m4);
2292
2293 if (get_field(s, r1) == get_field(s, r2) ||
2294 get_field(s, r1) == get_field(s, r3) ||
2295 get_field(s, r2) == get_field(s, r3)) {
2296 gen_program_exception(s, PGM_SPECIFICATION);
2297 return DISAS_NORETURN;
2298 }
2299
2300 if (m4 == 2 || (!fpe && m4 == 3) || m4 > 7) {
2301 gen_program_exception(s, PGM_SPECIFICATION);
2302 return DISAS_NORETURN;
2303 }
2304
2305 gen_helper_dib(tcg_env, tcg_constant_i32(get_field(s, r1)),
2306 tcg_constant_i32(get_field(s, r2)),
2307 tcg_constant_i32(get_field(s, r3)), tcg_constant_i32(m4),
2308 tcg_constant_i32(s->insn->data));
2309 set_cc_static(s);
2310
2311 return DISAS_NEXT;
2312 }
2313
2314 static DisasJumpType op_ear(DisasContext *s, DisasOps *o)
2315 {
2316 int r2 = get_field(s, r2);
2317 tcg_gen_ld32u_i64(o->out, tcg_env, offsetof(CPUS390XState, aregs[r2]));
2318 return DISAS_NEXT;
2319 }
2320
2321 static DisasJumpType op_ecag(DisasContext *s, DisasOps *o)
2322 {
2323 /* No cache information provided. */
2324 tcg_gen_movi_i64(o->out, -1);
2325 return DISAS_NEXT;
2326 }
2327
2328 static DisasJumpType op_efpc(DisasContext *s, DisasOps *o)
2329 {
2330 tcg_gen_ld32u_i64(o->out, tcg_env, offsetof(CPUS390XState, fpc));
2331 return DISAS_NEXT;
2332 }
2333
2334 static DisasJumpType op_epsw(DisasContext *s, DisasOps *o)
2335 {
2336 int r1 = get_field(s, r1);
2337 int r2 = get_field(s, r2);
2338 TCGv_i64 t = tcg_temp_new_i64();
2339 TCGv_i64 t_cc = tcg_temp_new_i64();
2340
2341 /* Note the "subsequently" in the PoO, which implies a defined result
2342 if r1 == r2. Thus we cannot defer these writes to an output hook. */
2343 gen_op_calc_cc(s);
2344 tcg_gen_extu_i32_i64(t_cc, cc_op);
2345 tcg_gen_shri_i64(t, psw_mask, 32);
2346 tcg_gen_deposit_i64(t, t, t_cc, 12, 2);
2347 store_reg32_i64(r1, t);
2348 if (r2 != 0) {
2349 store_reg32_i64(r2, psw_mask);
2350 }
2351 return DISAS_NEXT;
2352 }
2353
2354 static DisasJumpType op_ex(DisasContext *s, DisasOps *o)
2355 {
2356 int r1 = get_field(s, r1);
2357 TCGv_i32 ilen;
2358 TCGv_i64 v1;
2359
2360 /* Nested EXECUTE is not allowed. */
2361 if (unlikely(s->ex_value)) {
2362 gen_program_exception(s, PGM_EXECUTE);
2363 return DISAS_NORETURN;
2364 }
2365
2366 update_psw_addr(s);
2367 update_cc_op(s);
2368
2369 if (r1 == 0) {
2370 v1 = tcg_constant_i64(0);
2371 } else {
2372 v1 = regs[r1];
2373 }
2374
2375 ilen = tcg_constant_i32(s->ilen);
2376 gen_helper_ex(tcg_env, ilen, v1, o->in2);
2377
2378 return DISAS_PC_CC_UPDATED;
2379 }
2380
2381 static DisasJumpType op_fieb(DisasContext *s, DisasOps *o)
2382 {
2383 TCGv_i32 m34 = fpinst_extract_m34(s, false, true);
2384
2385 if (!m34) {
2386 return DISAS_NORETURN;
2387 }
2388 gen_helper_fieb(o->out, tcg_env, o->in2, m34);
2389 return DISAS_NEXT;
2390 }
2391
2392 static DisasJumpType op_fidb(DisasContext *s, DisasOps *o)
2393 {
2394 TCGv_i32 m34 = fpinst_extract_m34(s, false, true);
2395
2396 if (!m34) {
2397 return DISAS_NORETURN;
2398 }
2399 gen_helper_fidb(o->out, tcg_env, o->in2, m34);
2400 return DISAS_NEXT;
2401 }
2402
2403 static DisasJumpType op_fixb(DisasContext *s, DisasOps *o)
2404 {
2405 TCGv_i32 m34 = fpinst_extract_m34(s, false, true);
2406
2407 if (!m34) {
2408 return DISAS_NORETURN;
2409 }
2410 gen_helper_fixb(o->out_128, tcg_env, o->in2_128, m34);
2411 return DISAS_NEXT;
2412 }
2413
2414 static DisasJumpType op_flogr(DisasContext *s, DisasOps *o)
2415 {
2416 /* We'll use the original input for cc computation, since we get to
2417 compare that against 0, which ought to be better than comparing
2418 the real output against 64. It also lets cc_dst be a convenient
2419 temporary during our computation. */
2420 gen_op_update1_cc_i64(s, CC_OP_FLOGR, o->in2);
2421
2422 /* R1 = IN ? CLZ(IN) : 64. */
2423 tcg_gen_clzi_i64(o->out, o->in2, 64);
2424
2425 /* R1+1 = IN & ~(found bit). Note that we may attempt to shift this
2426 value by 64, which is undefined. But since the shift is 64 iff the
2427 input is zero, we still get the correct result after and'ing. */
2428 tcg_gen_movi_i64(o->out2, 0x8000000000000000ull);
2429 tcg_gen_shr_i64(o->out2, o->out2, o->out);
2430 tcg_gen_andc_i64(o->out2, cc_dst, o->out2);
2431 return DISAS_NEXT;
2432 }
2433
2434 static DisasJumpType op_icm(DisasContext *s, DisasOps *o)
2435 {
2436 int m3 = get_field(s, m3);
2437 int pos, len, base = s->insn->data;
2438 TCGv_i64 tmp = tcg_temp_new_i64();
2439 uint64_t ccm;
2440
2441 switch (m3) {
2442 case 0xf:
2443 /* Effectively a 32-bit load. */
2444 tcg_gen_qemu_ld_i64(tmp, o->in2, get_mem_index(s), MO_BEUL);
2445 len = 32;
2446 goto one_insert;
2447
2448 case 0xc:
2449 case 0x6:
2450 case 0x3:
2451 /* Effectively a 16-bit load. */
2452 tcg_gen_qemu_ld_i64(tmp, o->in2, get_mem_index(s), MO_BEUW);
2453 len = 16;
2454 goto one_insert;
2455
2456 case 0x8:
2457 case 0x4:
2458 case 0x2:
2459 case 0x1:
2460 /* Effectively an 8-bit load. */
2461 tcg_gen_qemu_ld_i64(tmp, o->in2, get_mem_index(s), MO_UB);
2462 len = 8;
2463 goto one_insert;
2464
2465 one_insert:
2466 pos = base + ctz32(m3) * 8;
2467 tcg_gen_deposit_i64(o->out, o->out, tmp, pos, len);
2468 ccm = ((1ull << len) - 1) << pos;
2469 break;
2470
2471 case 0:
2472 /* Recognize access exceptions for the first byte. */
2473 tcg_gen_qemu_ld_i64(tmp, o->in2, get_mem_index(s), MO_UB);
2474 gen_op_movi_cc(s, 0);
2475 return DISAS_NEXT;
2476
2477 default:
2478 /* This is going to be a sequence of loads and inserts. */
2479 pos = base + 32 - 8;
2480 ccm = 0;
2481 while (m3) {
2482 if (m3 & 0x8) {
2483 tcg_gen_qemu_ld_i64(tmp, o->in2, get_mem_index(s), MO_UB);
2484 tcg_gen_addi_i64(o->in2, o->in2, 1);
2485 tcg_gen_deposit_i64(o->out, o->out, tmp, pos, 8);
2486 ccm |= 0xffull << pos;
2487 }
2488 m3 = (m3 << 1) & 0xf;
2489 pos -= 8;
2490 }
2491 break;
2492 }
2493
2494 tcg_gen_movi_i64(tmp, ccm);
2495 gen_op_update2_cc_i64(s, CC_OP_ICM, tmp, o->out);
2496 return DISAS_NEXT;
2497 }
2498
2499 static DisasJumpType op_insi(DisasContext *s, DisasOps *o)
2500 {
2501 int shift = s->insn->data & 0xff;
2502 int size = s->insn->data >> 8;
2503 tcg_gen_deposit_i64(o->out, o->in1, o->in2, shift, size);
2504 return DISAS_NEXT;
2505 }
2506
2507 static DisasJumpType op_ipm(DisasContext *s, DisasOps *o)
2508 {
2509 TCGv_i64 t1, t2;
2510
2511 gen_op_calc_cc(s);
2512 t1 = tcg_temp_new_i64();
2513 tcg_gen_extract_i64(t1, psw_mask, 40, 4);
2514 t2 = tcg_temp_new_i64();
2515 tcg_gen_extu_i32_i64(t2, cc_op);
2516 tcg_gen_deposit_i64(t1, t1, t2, 4, 60);
2517 tcg_gen_deposit_i64(o->out, o->out, t1, 24, 8);
2518 return DISAS_NEXT;
2519 }
2520
2521 #ifndef CONFIG_USER_ONLY
2522 static DisasJumpType op_idte(DisasContext *s, DisasOps *o)
2523 {
2524 TCGv_i32 m4;
2525
2526 if (s390_has_feat(S390_FEAT_LOCAL_TLB_CLEARING)) {
2527 m4 = tcg_constant_i32(get_field(s, m4));
2528 } else {
2529 m4 = tcg_constant_i32(0);
2530 }
2531 gen_helper_idte(tcg_env, o->in1, o->in2, m4);
2532 return DISAS_NEXT;
2533 }
2534
2535 static DisasJumpType op_ipte(DisasContext *s, DisasOps *o)
2536 {
2537 TCGv_i32 m4;
2538
2539 if (s390_has_feat(S390_FEAT_LOCAL_TLB_CLEARING)) {
2540 m4 = tcg_constant_i32(get_field(s, m4));
2541 } else {
2542 m4 = tcg_constant_i32(0);
2543 }
2544 gen_helper_ipte(tcg_env, o->in1, o->in2, m4);
2545 return DISAS_NEXT;
2546 }
2547
2548 static DisasJumpType op_iske(DisasContext *s, DisasOps *o)
2549 {
2550 gen_helper_iske(o->out, tcg_env, o->in2);
2551 return DISAS_NEXT;
2552 }
2553 #endif
2554
2555 static DisasJumpType op_msa(DisasContext *s, DisasOps *o)
2556 {
2557 int r1 = have_field(s, r1) ? get_field(s, r1) : 0;
2558 int r2 = have_field(s, r2) ? get_field(s, r2) : 0;
2559 int r3 = have_field(s, r3) ? get_field(s, r3) : 0;
2560 TCGv_i32 t_r1, t_r2, t_r3, type;
2561
2562 switch (s->insn->data) {
2563 case S390_FEAT_TYPE_KMA:
2564 if (r3 == r1 || r3 == r2) {
2565 gen_program_exception(s, PGM_SPECIFICATION);
2566 return DISAS_NORETURN;
2567 }
2568 /* FALL THROUGH */
2569 case S390_FEAT_TYPE_KMCTR:
2570 if (r3 & 1 || !r3) {
2571 gen_program_exception(s, PGM_SPECIFICATION);
2572 return DISAS_NORETURN;
2573 }
2574 /* FALL THROUGH */
2575 case S390_FEAT_TYPE_PPNO:
2576 case S390_FEAT_TYPE_KMF:
2577 case S390_FEAT_TYPE_KMC:
2578 case S390_FEAT_TYPE_KMO:
2579 case S390_FEAT_TYPE_KM:
2580 if (r1 & 1 || !r1) {
2581 gen_program_exception(s, PGM_SPECIFICATION);
2582 return DISAS_NORETURN;
2583 }
2584 /* FALL THROUGH */
2585 case S390_FEAT_TYPE_KMAC:
2586 case S390_FEAT_TYPE_KIMD:
2587 case S390_FEAT_TYPE_KLMD:
2588 if (r2 & 1 || !r2) {
2589 gen_program_exception(s, PGM_SPECIFICATION);
2590 return DISAS_NORETURN;
2591 }
2592 /* FALL THROUGH */
2593 case S390_FEAT_TYPE_PCKMO:
2594 case S390_FEAT_TYPE_PCC:
2595 break;
2596 default:
2597 g_assert_not_reached();
2598 };
2599
2600 t_r1 = tcg_constant_i32(r1);
2601 t_r2 = tcg_constant_i32(r2);
2602 t_r3 = tcg_constant_i32(r3);
2603 type = tcg_constant_i32(s->insn->data);
2604 gen_helper_msa(cc_op, tcg_env, t_r1, t_r2, t_r3, type);
2605 set_cc_static(s);
2606 return DISAS_NEXT;
2607 }
2608
2609 static DisasJumpType op_keb(DisasContext *s, DisasOps *o)
2610 {
2611 gen_helper_keb(cc_op, tcg_env, o->in1, o->in2);
2612 set_cc_static(s);
2613 return DISAS_NEXT;
2614 }
2615
2616 static DisasJumpType op_kdb(DisasContext *s, DisasOps *o)
2617 {
2618 gen_helper_kdb(cc_op, tcg_env, o->in1, o->in2);
2619 set_cc_static(s);
2620 return DISAS_NEXT;
2621 }
2622
2623 static DisasJumpType op_kxb(DisasContext *s, DisasOps *o)
2624 {
2625 gen_helper_kxb(cc_op, tcg_env, o->in1_128, o->in2_128);
2626 set_cc_static(s);
2627 return DISAS_NEXT;
2628 }
2629
2630 static DisasJumpType help_laa(DisasContext *s, DisasOps *o, bool addu64)
2631 {
2632 /* The real output is indeed the original value in memory;
2633 recompute the addition for the computation of CC. */
2634 tcg_gen_atomic_fetch_add_i64(o->in2, o->in2, o->in1, get_mem_index(s),
2635 s->insn->data | MO_ALIGN);
2636 /* However, we need to recompute the addition for setting CC. */
2637 if (addu64) {
2638 tcg_gen_movi_i64(cc_src, 0);
2639 tcg_gen_add2_i64(o->out, cc_src, o->in1, cc_src, o->in2, cc_src);
2640 } else {
2641 tcg_gen_add_i64(o->out, o->in1, o->in2);
2642 }
2643 return DISAS_NEXT;
2644 }
2645
2646 static DisasJumpType op_laa(DisasContext *s, DisasOps *o)
2647 {
2648 return help_laa(s, o, false);
2649 }
2650
2651 static DisasJumpType op_laa_addu64(DisasContext *s, DisasOps *o)
2652 {
2653 return help_laa(s, o, true);
2654 }
2655
2656 static DisasJumpType op_lan(DisasContext *s, DisasOps *o)
2657 {
2658 /* The real output is indeed the original value in memory;
2659 recompute the addition for the computation of CC. */
2660 tcg_gen_atomic_fetch_and_i64(o->in2, o->in2, o->in1, get_mem_index(s),
2661 s->insn->data | MO_ALIGN);
2662 /* However, we need to recompute the operation for setting CC. */
2663 tcg_gen_and_i64(o->out, o->in1, o->in2);
2664 return DISAS_NEXT;
2665 }
2666
2667 static DisasJumpType op_lao(DisasContext *s, DisasOps *o)
2668 {
2669 /* The real output is indeed the original value in memory;
2670 recompute the addition for the computation of CC. */
2671 tcg_gen_atomic_fetch_or_i64(o->in2, o->in2, o->in1, get_mem_index(s),
2672 s->insn->data | MO_ALIGN);
2673 /* However, we need to recompute the operation for setting CC. */
2674 tcg_gen_or_i64(o->out, o->in1, o->in2);
2675 return DISAS_NEXT;
2676 }
2677
2678 static DisasJumpType op_lax(DisasContext *s, DisasOps *o)
2679 {
2680 /* The real output is indeed the original value in memory;
2681 recompute the addition for the computation of CC. */
2682 tcg_gen_atomic_fetch_xor_i64(o->in2, o->in2, o->in1, get_mem_index(s),
2683 s->insn->data | MO_ALIGN);
2684 /* However, we need to recompute the operation for setting CC. */
2685 tcg_gen_xor_i64(o->out, o->in1, o->in2);
2686 return DISAS_NEXT;
2687 }
2688
2689 static DisasJumpType op_ldeb(DisasContext *s, DisasOps *o)
2690 {
2691 gen_helper_ldeb(o->out, tcg_env, o->in2);
2692 return DISAS_NEXT;
2693 }
2694
2695 static DisasJumpType op_ledb(DisasContext *s, DisasOps *o)
2696 {
2697 TCGv_i32 m34 = fpinst_extract_m34(s, true, true);
2698
2699 if (!m34) {
2700 return DISAS_NORETURN;
2701 }
2702 gen_helper_ledb(o->out, tcg_env, o->in2, m34);
2703 return DISAS_NEXT;
2704 }
2705
2706 static DisasJumpType op_ldxb(DisasContext *s, DisasOps *o)
2707 {
2708 TCGv_i32 m34 = fpinst_extract_m34(s, true, true);
2709
2710 if (!m34) {
2711 return DISAS_NORETURN;
2712 }
2713 gen_helper_ldxb(o->out, tcg_env, o->in2_128, m34);
2714 return DISAS_NEXT;
2715 }
2716
2717 static DisasJumpType op_lexb(DisasContext *s, DisasOps *o)
2718 {
2719 TCGv_i32 m34 = fpinst_extract_m34(s, true, true);
2720
2721 if (!m34) {
2722 return DISAS_NORETURN;
2723 }
2724 gen_helper_lexb(o->out, tcg_env, o->in2_128, m34);
2725 return DISAS_NEXT;
2726 }
2727
2728 static DisasJumpType op_lxdb(DisasContext *s, DisasOps *o)
2729 {
2730 gen_helper_lxdb(o->out_128, tcg_env, o->in2);
2731 return DISAS_NEXT;
2732 }
2733
2734 static DisasJumpType op_lxeb(DisasContext *s, DisasOps *o)
2735 {
2736 gen_helper_lxeb(o->out_128, tcg_env, o->in2);
2737 return DISAS_NEXT;
2738 }
2739
2740 static DisasJumpType op_lde(DisasContext *s, DisasOps *o)
2741 {
2742 tcg_gen_shli_i64(o->out, o->in2, 32);
2743 return DISAS_NEXT;
2744 }
2745
2746 static DisasJumpType op_llgt(DisasContext *s, DisasOps *o)
2747 {
2748 tcg_gen_andi_i64(o->out, o->in2, 0x7fffffff);
2749 return DISAS_NEXT;
2750 }
2751
2752 static DisasJumpType op_ld8s(DisasContext *s, DisasOps *o)
2753 {
2754 tcg_gen_qemu_ld_i64(o->out, o->in2, get_mem_index(s), MO_SB);
2755 return DISAS_NEXT;
2756 }
2757
2758 static DisasJumpType op_ld8u(DisasContext *s, DisasOps *o)
2759 {
2760 tcg_gen_qemu_ld_i64(o->out, o->in2, get_mem_index(s), MO_UB);
2761 return DISAS_NEXT;
2762 }
2763
2764 static DisasJumpType op_ld16s(DisasContext *s, DisasOps *o)
2765 {
2766 tcg_gen_qemu_ld_i64(o->out, o->in2, get_mem_index(s), MO_BESW);
2767 return DISAS_NEXT;
2768 }
2769
2770 static DisasJumpType op_ld16u(DisasContext *s, DisasOps *o)
2771 {
2772 tcg_gen_qemu_ld_i64(o->out, o->in2, get_mem_index(s), MO_BEUW);
2773 return DISAS_NEXT;
2774 }
2775
2776 static DisasJumpType op_ld32s(DisasContext *s, DisasOps *o)
2777 {
2778 tcg_gen_qemu_ld_i64(o->out, o->in2, get_mem_index(s),
2779 MO_BESL | s->insn->data);
2780 return DISAS_NEXT;
2781 }
2782
2783 static DisasJumpType op_ld32u(DisasContext *s, DisasOps *o)
2784 {
2785 tcg_gen_qemu_ld_i64(o->out, o->in2, get_mem_index(s),
2786 MO_BEUL | s->insn->data);
2787 return DISAS_NEXT;
2788 }
2789
2790 static DisasJumpType op_ld64(DisasContext *s, DisasOps *o)
2791 {
2792 tcg_gen_qemu_ld_i64(o->out, o->in2, get_mem_index(s),
2793 MO_BEUQ | s->insn->data);
2794 return DISAS_NEXT;
2795 }
2796
2797 static DisasJumpType op_lat(DisasContext *s, DisasOps *o)
2798 {
2799 TCGLabel *lab = gen_new_label();
2800 store_reg32_i64(get_field(s, r1), o->in2);
2801 /* The value is stored even in case of trap. */
2802 tcg_gen_brcondi_i64(TCG_COND_NE, o->in2, 0, lab);
2803 gen_trap(s);
2804 gen_set_label(lab);
2805 return DISAS_NEXT;
2806 }
2807
2808 static DisasJumpType op_lgat(DisasContext *s, DisasOps *o)
2809 {
2810 TCGLabel *lab = gen_new_label();
2811 tcg_gen_qemu_ld_i64(o->out, o->in2, get_mem_index(s), MO_BEUQ);
2812 /* The value is stored even in case of trap. */
2813 tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab);
2814 gen_trap(s);
2815 gen_set_label(lab);
2816 return DISAS_NEXT;
2817 }
2818
2819 static DisasJumpType op_lfhat(DisasContext *s, DisasOps *o)
2820 {
2821 TCGLabel *lab = gen_new_label();
2822 store_reg32h_i64(get_field(s, r1), o->in2);
2823 /* The value is stored even in case of trap. */
2824 tcg_gen_brcondi_i64(TCG_COND_NE, o->in2, 0, lab);
2825 gen_trap(s);
2826 gen_set_label(lab);
2827 return DISAS_NEXT;
2828 }
2829
2830 static DisasJumpType op_llgfat(DisasContext *s, DisasOps *o)
2831 {
2832 TCGLabel *lab = gen_new_label();
2833
2834 tcg_gen_qemu_ld_i64(o->out, o->in2, get_mem_index(s), MO_BEUL);
2835 /* The value is stored even in case of trap. */
2836 tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab);
2837 gen_trap(s);
2838 gen_set_label(lab);
2839 return DISAS_NEXT;
2840 }
2841
2842 static DisasJumpType op_llgtat(DisasContext *s, DisasOps *o)
2843 {
2844 TCGLabel *lab = gen_new_label();
2845 tcg_gen_andi_i64(o->out, o->in2, 0x7fffffff);
2846 /* The value is stored even in case of trap. */
2847 tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab);
2848 gen_trap(s);
2849 gen_set_label(lab);
2850 return DISAS_NEXT;
2851 }
2852
2853 static DisasJumpType op_loc(DisasContext *s, DisasOps *o)
2854 {
2855 DisasCompare c;
2856
2857 if (have_field(s, m3)) {
2858 /* LOAD * ON CONDITION */
2859 disas_jcc(s, &c, get_field(s, m3));
2860 } else {
2861 /* SELECT */
2862 disas_jcc(s, &c, get_field(s, m4));
2863 }
2864
2865 if (c.is_64) {
2866 tcg_gen_movcond_i64(c.cond, o->out, c.u.s64.a, c.u.s64.b,
2867 o->in2, o->in1);
2868 } else {
2869 TCGv_i32 t32 = tcg_temp_new_i32();
2870 TCGv_i64 t, z;
2871
2872 tcg_gen_setcond_i32(c.cond, t32, c.u.s32.a, c.u.s32.b);
2873
2874 t = tcg_temp_new_i64();
2875 tcg_gen_extu_i32_i64(t, t32);
2876
2877 z = tcg_constant_i64(0);
2878 tcg_gen_movcond_i64(TCG_COND_NE, o->out, t, z, o->in2, o->in1);
2879 }
2880
2881 return DISAS_NEXT;
2882 }
2883
2884 #ifndef CONFIG_USER_ONLY
2885 static DisasJumpType op_lctl(DisasContext *s, DisasOps *o)
2886 {
2887 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
2888 TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
2889
2890 gen_helper_lctl(tcg_env, r1, o->in2, r3);
2891 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
2892 s->exit_to_mainloop = true;
2893 return DISAS_TOO_MANY;
2894 }
2895
2896 static DisasJumpType op_lctlg(DisasContext *s, DisasOps *o)
2897 {
2898 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
2899 TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
2900
2901 gen_helper_lctlg(tcg_env, r1, o->in2, r3);
2902 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
2903 s->exit_to_mainloop = true;
2904 return DISAS_TOO_MANY;
2905 }
2906
2907 static DisasJumpType op_lra(DisasContext *s, DisasOps *o)
2908 {
2909 gen_helper_lra(o->out, tcg_env, o->out, o->in2);
2910 set_cc_static(s);
2911 return DISAS_NEXT;
2912 }
2913
2914 static DisasJumpType op_lpp(DisasContext *s, DisasOps *o)
2915 {
2916 tcg_gen_st_i64(o->in2, tcg_env, offsetof(CPUS390XState, pp));
2917 return DISAS_NEXT;
2918 }
2919
2920 static DisasJumpType op_lpsw(DisasContext *s, DisasOps *o)
2921 {
2922 TCGv_i64 mask, addr;
2923
2924 per_breaking_event(s);
2925
2926 /*
2927 * Convert the short PSW into the normal PSW, similar to what
2928 * s390_cpu_load_normal() does.
2929 */
2930 mask = tcg_temp_new_i64();
2931 addr = tcg_temp_new_i64();
2932 tcg_gen_qemu_ld_i64(mask, o->in2, get_mem_index(s), MO_BEUQ | MO_ALIGN_8);
2933 tcg_gen_andi_i64(addr, mask, PSW_MASK_SHORT_ADDR);
2934 tcg_gen_andi_i64(mask, mask, PSW_MASK_SHORT_CTRL);
2935 tcg_gen_xori_i64(mask, mask, PSW_MASK_SHORTPSW);
2936 gen_helper_load_psw(tcg_env, mask, addr);
2937 return DISAS_NORETURN;
2938 }
2939
2940 static DisasJumpType op_lpswe(DisasContext *s, DisasOps *o)
2941 {
2942 TCGv_i64 t1, t2;
2943
2944 per_breaking_event(s);
2945
2946 t1 = tcg_temp_new_i64();
2947 t2 = tcg_temp_new_i64();
2948 tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s),
2949 MO_BEUQ | MO_ALIGN_8);
2950 tcg_gen_addi_i64(o->in2, o->in2, 8);
2951 tcg_gen_qemu_ld_i64(t2, o->in2, get_mem_index(s), MO_BEUQ);
2952 gen_helper_load_psw(tcg_env, t1, t2);
2953 return DISAS_NORETURN;
2954 }
2955 #endif
2956
2957 static DisasJumpType op_lam(DisasContext *s, DisasOps *o)
2958 {
2959 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
2960 TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
2961
2962 gen_helper_lam(tcg_env, r1, o->in2, r3);
2963 return DISAS_NEXT;
2964 }
2965
2966 static DisasJumpType op_lm32(DisasContext *s, DisasOps *o)
2967 {
2968 int r1 = get_field(s, r1);
2969 int r3 = get_field(s, r3);
2970 TCGv_i64 t1, t2;
2971
2972 /* Only one register to read. */
2973 t1 = tcg_temp_new_i64();
2974 if (unlikely(r1 == r3)) {
2975 tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s), MO_BEUL);
2976 store_reg32_i64(r1, t1);
2977 return DISAS_NEXT;
2978 }
2979
2980 /* First load the values of the first and last registers to trigger
2981 possible page faults. */
2982 t2 = tcg_temp_new_i64();
2983 tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s), MO_BEUL);
2984 tcg_gen_addi_i64(t2, o->in2, 4 * ((r3 - r1) & 15));
2985 tcg_gen_qemu_ld_i64(t2, t2, get_mem_index(s), MO_BEUL);
2986 store_reg32_i64(r1, t1);
2987 store_reg32_i64(r3, t2);
2988
2989 /* Only two registers to read. */
2990 if (((r1 + 1) & 15) == r3) {
2991 return DISAS_NEXT;
2992 }
2993
2994 /* Then load the remaining registers. Page fault can't occur. */
2995 r3 = (r3 - 1) & 15;
2996 tcg_gen_movi_i64(t2, 4);
2997 while (r1 != r3) {
2998 r1 = (r1 + 1) & 15;
2999 tcg_gen_add_i64(o->in2, o->in2, t2);
3000 tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s), MO_BEUL);
3001 store_reg32_i64(r1, t1);
3002 }
3003 return DISAS_NEXT;
3004 }
3005
3006 static DisasJumpType op_lmh(DisasContext *s, DisasOps *o)
3007 {
3008 int r1 = get_field(s, r1);
3009 int r3 = get_field(s, r3);
3010 TCGv_i64 t1, t2;
3011
3012 /* Only one register to read. */
3013 t1 = tcg_temp_new_i64();
3014 if (unlikely(r1 == r3)) {
3015 tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s), MO_BEUL);
3016 store_reg32h_i64(r1, t1);
3017 return DISAS_NEXT;
3018 }
3019
3020 /* First load the values of the first and last registers to trigger
3021 possible page faults. */
3022 t2 = tcg_temp_new_i64();
3023 tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s), MO_BEUL);
3024 tcg_gen_addi_i64(t2, o->in2, 4 * ((r3 - r1) & 15));
3025 tcg_gen_qemu_ld_i64(t2, t2, get_mem_index(s), MO_BEUL);
3026 store_reg32h_i64(r1, t1);
3027 store_reg32h_i64(r3, t2);
3028
3029 /* Only two registers to read. */
3030 if (((r1 + 1) & 15) == r3) {
3031 return DISAS_NEXT;
3032 }
3033
3034 /* Then load the remaining registers. Page fault can't occur. */
3035 r3 = (r3 - 1) & 15;
3036 tcg_gen_movi_i64(t2, 4);
3037 while (r1 != r3) {
3038 r1 = (r1 + 1) & 15;
3039 tcg_gen_add_i64(o->in2, o->in2, t2);
3040 tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s), MO_BEUL);
3041 store_reg32h_i64(r1, t1);
3042 }
3043 return DISAS_NEXT;
3044 }
3045
3046 static DisasJumpType op_lm64(DisasContext *s, DisasOps *o)
3047 {
3048 int r1 = get_field(s, r1);
3049 int r3 = get_field(s, r3);
3050 TCGv_i64 t1, t2;
3051
3052 /* Only one register to read. */
3053 if (unlikely(r1 == r3)) {
3054 tcg_gen_qemu_ld_i64(regs[r1], o->in2, get_mem_index(s), MO_BEUQ);
3055 return DISAS_NEXT;
3056 }
3057
3058 /* First load the values of the first and last registers to trigger
3059 possible page faults. */
3060 t1 = tcg_temp_new_i64();
3061 t2 = tcg_temp_new_i64();
3062 tcg_gen_qemu_ld_i64(t1, o->in2, get_mem_index(s), MO_BEUQ);
3063 tcg_gen_addi_i64(t2, o->in2, 8 * ((r3 - r1) & 15));
3064 tcg_gen_qemu_ld_i64(regs[r3], t2, get_mem_index(s), MO_BEUQ);
3065 tcg_gen_mov_i64(regs[r1], t1);
3066
3067 /* Only two registers to read. */
3068 if (((r1 + 1) & 15) == r3) {
3069 return DISAS_NEXT;
3070 }
3071
3072 /* Then load the remaining registers. Page fault can't occur. */
3073 r3 = (r3 - 1) & 15;
3074 tcg_gen_movi_i64(t1, 8);
3075 while (r1 != r3) {
3076 r1 = (r1 + 1) & 15;
3077 tcg_gen_add_i64(o->in2, o->in2, t1);
3078 tcg_gen_qemu_ld_i64(regs[r1], o->in2, get_mem_index(s), MO_BEUQ);
3079 }
3080 return DISAS_NEXT;
3081 }
3082
3083 static DisasJumpType op_lpd(DisasContext *s, DisasOps *o)
3084 {
3085 TCGv_i64 a1, a2;
3086 MemOp mop = s->insn->data;
3087
3088 /* In a parallel context, stop the world and single step. */
3089 if (tb_cflags(s->base.tb) & CF_PARALLEL) {
3090 update_psw_addr(s);
3091 update_cc_op(s);
3092 gen_exception(EXCP_ATOMIC);
3093 return DISAS_NORETURN;
3094 }
3095
3096 /* In a serial context, perform the two loads ... */
3097 a1 = get_address(s, 0, get_field(s, b1), get_field(s, d1));
3098 a2 = get_address(s, 0, get_field(s, b2), get_field(s, d2));
3099 tcg_gen_qemu_ld_i64(o->out, a1, get_mem_index(s), mop | MO_ALIGN);
3100 tcg_gen_qemu_ld_i64(o->out2, a2, get_mem_index(s), mop | MO_ALIGN);
3101
3102 /* ... and indicate that we performed them while interlocked. */
3103 gen_op_movi_cc(s, 0);
3104 return DISAS_NEXT;
3105 }
3106
3107 static DisasJumpType op_lpq(DisasContext *s, DisasOps *o)
3108 {
3109 o->out_128 = tcg_temp_new_i128();
3110 tcg_gen_qemu_ld_i128(o->out_128, o->in2, get_mem_index(s),
3111 MO_BE | MO_128 | MO_ALIGN);
3112 return DISAS_NEXT;
3113 }
3114
3115 #ifndef CONFIG_USER_ONLY
3116 static DisasJumpType op_lura(DisasContext *s, DisasOps *o)
3117 {
3118 tcg_gen_qemu_ld_i64(o->out, o->in2, MMU_REAL_IDX, s->insn->data);
3119 return DISAS_NEXT;
3120 }
3121 #endif
3122
3123 static DisasJumpType op_lzrb(DisasContext *s, DisasOps *o)
3124 {
3125 tcg_gen_andi_i64(o->out, o->in2, -256);
3126 return DISAS_NEXT;
3127 }
3128
3129 static DisasJumpType op_lcbb(DisasContext *s, DisasOps *o)
3130 {
3131 const int64_t block_size = (1ull << (get_field(s, m3) + 6));
3132
3133 if (get_field(s, m3) > 6) {
3134 gen_program_exception(s, PGM_SPECIFICATION);
3135 return DISAS_NORETURN;
3136 }
3137
3138 tcg_gen_ori_i64(o->addr1, o->addr1, -block_size);
3139 tcg_gen_neg_i64(o->addr1, o->addr1);
3140 tcg_gen_movi_i64(o->out, 16);
3141 tcg_gen_umin_i64(o->out, o->out, o->addr1);
3142 gen_op_update1_cc_i64(s, CC_OP_LCBB, o->out);
3143 return DISAS_NEXT;
3144 }
3145
3146 static DisasJumpType op_mc(DisasContext *s, DisasOps *o)
3147 {
3148 const uint8_t monitor_class = get_field(s, i2);
3149
3150 if (monitor_class & 0xf0) {
3151 gen_program_exception(s, PGM_SPECIFICATION);
3152 return DISAS_NORETURN;
3153 }
3154
3155 #if !defined(CONFIG_USER_ONLY)
3156 gen_helper_monitor_call(tcg_env, o->addr1,
3157 tcg_constant_i32(monitor_class));
3158 #endif
3159 /* Defaults to a NOP. */
3160 return DISAS_NEXT;
3161 }
3162
3163 static DisasJumpType op_mov2(DisasContext *s, DisasOps *o)
3164 {
3165 o->out = o->in2;
3166 o->in2 = NULL;
3167 return DISAS_NEXT;
3168 }
3169
3170 static DisasJumpType op_mov2e(DisasContext *s, DisasOps *o)
3171 {
3172 int b2 = get_field(s, b2);
3173 TCGv_i64 ar1 = tcg_temp_new_i64();
3174 int r1 = get_field(s, r1);
3175
3176 o->out = o->in2;
3177 o->in2 = NULL;
3178
3179 switch (s->base.tb->flags & FLAG_MASK_ASC) {
3180 case PSW_ASC_PRIMARY >> FLAG_MASK_PSW_SHIFT:
3181 tcg_gen_movi_i64(ar1, 0);
3182 break;
3183 case PSW_ASC_ACCREG >> FLAG_MASK_PSW_SHIFT:
3184 tcg_gen_movi_i64(ar1, 1);
3185 break;
3186 case PSW_ASC_SECONDARY >> FLAG_MASK_PSW_SHIFT:
3187 if (b2) {
3188 tcg_gen_ld32u_i64(ar1, tcg_env, offsetof(CPUS390XState, aregs[b2]));
3189 } else {
3190 tcg_gen_movi_i64(ar1, 0);
3191 }
3192 break;
3193 case PSW_ASC_HOME >> FLAG_MASK_PSW_SHIFT:
3194 tcg_gen_movi_i64(ar1, 2);
3195 break;
3196 }
3197
3198 tcg_gen_st32_i64(ar1, tcg_env, offsetof(CPUS390XState, aregs[r1]));
3199 return DISAS_NEXT;
3200 }
3201
3202 static DisasJumpType op_movx(DisasContext *s, DisasOps *o)
3203 {
3204 o->out = o->in1;
3205 o->out2 = o->in2;
3206 o->in1 = NULL;
3207 o->in2 = NULL;
3208 return DISAS_NEXT;
3209 }
3210
3211 static DisasJumpType op_mvc(DisasContext *s, DisasOps *o)
3212 {
3213 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3214
3215 gen_helper_mvc(tcg_env, l, o->addr1, o->in2);
3216 return DISAS_NEXT;
3217 }
3218
3219 static DisasJumpType op_mvcrl(DisasContext *s, DisasOps *o)
3220 {
3221 gen_helper_mvcrl(tcg_env, regs[0], o->addr1, o->in2);
3222 return DISAS_NEXT;
3223 }
3224
3225 static DisasJumpType op_mvcin(DisasContext *s, DisasOps *o)
3226 {
3227 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3228
3229 gen_helper_mvcin(tcg_env, l, o->addr1, o->in2);
3230 return DISAS_NEXT;
3231 }
3232
3233 static DisasJumpType op_mvcl(DisasContext *s, DisasOps *o)
3234 {
3235 int r1 = get_field(s, r1);
3236 int r2 = get_field(s, r2);
3237 TCGv_i32 t1, t2;
3238
3239 /* r1 and r2 must be even. */
3240 if (r1 & 1 || r2 & 1) {
3241 gen_program_exception(s, PGM_SPECIFICATION);
3242 return DISAS_NORETURN;
3243 }
3244
3245 t1 = tcg_constant_i32(r1);
3246 t2 = tcg_constant_i32(r2);
3247 gen_helper_mvcl(cc_op, tcg_env, t1, t2);
3248 set_cc_static(s);
3249 return DISAS_NEXT;
3250 }
3251
3252 static DisasJumpType op_mvcle(DisasContext *s, DisasOps *o)
3253 {
3254 int r1 = get_field(s, r1);
3255 int r3 = get_field(s, r3);
3256 TCGv_i32 t1, t3;
3257
3258 /* r1 and r3 must be even. */
3259 if (r1 & 1 || r3 & 1) {
3260 gen_program_exception(s, PGM_SPECIFICATION);
3261 return DISAS_NORETURN;
3262 }
3263
3264 t1 = tcg_constant_i32(r1);
3265 t3 = tcg_constant_i32(r3);
3266 gen_helper_mvcle(cc_op, tcg_env, t1, o->in2, t3);
3267 set_cc_static(s);
3268 return DISAS_NEXT;
3269 }
3270
3271 static DisasJumpType op_mvclu(DisasContext *s, DisasOps *o)
3272 {
3273 int r1 = get_field(s, r1);
3274 int r3 = get_field(s, r3);
3275 TCGv_i32 t1, t3;
3276
3277 /* r1 and r3 must be even. */
3278 if (r1 & 1 || r3 & 1) {
3279 gen_program_exception(s, PGM_SPECIFICATION);
3280 return DISAS_NORETURN;
3281 }
3282
3283 t1 = tcg_constant_i32(r1);
3284 t3 = tcg_constant_i32(r3);
3285 gen_helper_mvclu(cc_op, tcg_env, t1, o->in2, t3);
3286 set_cc_static(s);
3287 return DISAS_NEXT;
3288 }
3289
3290 static DisasJumpType op_mvcos(DisasContext *s, DisasOps *o)
3291 {
3292 int r3 = get_field(s, r3);
3293 gen_helper_mvcos(cc_op, tcg_env, o->addr1, o->in2, regs[r3]);
3294 set_cc_static(s);
3295 return DISAS_NEXT;
3296 }
3297
3298 #ifndef CONFIG_USER_ONLY
3299 static DisasJumpType op_mvcp(DisasContext *s, DisasOps *o)
3300 {
3301 int r1 = get_field(s, l1);
3302 int r3 = get_field(s, r3);
3303 gen_helper_mvcp(cc_op, tcg_env, regs[r1], o->addr1, o->in2, regs[r3]);
3304 set_cc_static(s);
3305 return DISAS_NEXT;
3306 }
3307
3308 static DisasJumpType op_mvcs(DisasContext *s, DisasOps *o)
3309 {
3310 int r1 = get_field(s, l1);
3311 int r3 = get_field(s, r3);
3312 gen_helper_mvcs(cc_op, tcg_env, regs[r1], o->addr1, o->in2, regs[r3]);
3313 set_cc_static(s);
3314 return DISAS_NEXT;
3315 }
3316 #endif
3317
3318 static DisasJumpType op_mvn(DisasContext *s, DisasOps *o)
3319 {
3320 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3321
3322 gen_helper_mvn(tcg_env, l, o->addr1, o->in2);
3323 return DISAS_NEXT;
3324 }
3325
3326 static DisasJumpType op_mvo(DisasContext *s, DisasOps *o)
3327 {
3328 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3329
3330 gen_helper_mvo(tcg_env, l, o->addr1, o->in2);
3331 return DISAS_NEXT;
3332 }
3333
3334 static DisasJumpType op_mvpg(DisasContext *s, DisasOps *o)
3335 {
3336 TCGv_i32 t1 = tcg_constant_i32(get_field(s, r1));
3337 TCGv_i32 t2 = tcg_constant_i32(get_field(s, r2));
3338
3339 gen_helper_mvpg(cc_op, tcg_env, regs[0], t1, t2);
3340 set_cc_static(s);
3341 return DISAS_NEXT;
3342 }
3343
3344 static DisasJumpType op_mvst(DisasContext *s, DisasOps *o)
3345 {
3346 TCGv_i32 t1 = tcg_constant_i32(get_field(s, r1));
3347 TCGv_i32 t2 = tcg_constant_i32(get_field(s, r2));
3348
3349 gen_helper_mvst(cc_op, tcg_env, t1, t2);
3350 set_cc_static(s);
3351 return DISAS_NEXT;
3352 }
3353
3354 static DisasJumpType op_mvz(DisasContext *s, DisasOps *o)
3355 {
3356 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3357
3358 gen_helper_mvz(tcg_env, l, o->addr1, o->in2);
3359 return DISAS_NEXT;
3360 }
3361
3362 static DisasJumpType op_mul(DisasContext *s, DisasOps *o)
3363 {
3364 tcg_gen_mul_i64(o->out, o->in1, o->in2);
3365 return DISAS_NEXT;
3366 }
3367
3368 static DisasJumpType op_mul128(DisasContext *s, DisasOps *o)
3369 {
3370 tcg_gen_mulu2_i64(o->out2, o->out, o->in1, o->in2);
3371 return DISAS_NEXT;
3372 }
3373
3374 static DisasJumpType op_muls128(DisasContext *s, DisasOps *o)
3375 {
3376 tcg_gen_muls2_i64(o->out2, o->out, o->in1, o->in2);
3377 return DISAS_NEXT;
3378 }
3379
3380 static DisasJumpType op_meeb(DisasContext *s, DisasOps *o)
3381 {
3382 gen_helper_meeb(o->out, tcg_env, o->in1, o->in2);
3383 return DISAS_NEXT;
3384 }
3385
3386 static DisasJumpType op_mdeb(DisasContext *s, DisasOps *o)
3387 {
3388 gen_helper_mdeb(o->out, tcg_env, o->in1, o->in2);
3389 return DISAS_NEXT;
3390 }
3391
3392 static DisasJumpType op_mdb(DisasContext *s, DisasOps *o)
3393 {
3394 gen_helper_mdb(o->out, tcg_env, o->in1, o->in2);
3395 return DISAS_NEXT;
3396 }
3397
3398 static DisasJumpType op_mxb(DisasContext *s, DisasOps *o)
3399 {
3400 gen_helper_mxb(o->out_128, tcg_env, o->in1_128, o->in2_128);
3401 return DISAS_NEXT;
3402 }
3403
3404 static DisasJumpType op_mxdb(DisasContext *s, DisasOps *o)
3405 {
3406 gen_helper_mxdb(o->out_128, tcg_env, o->in1, o->in2);
3407 return DISAS_NEXT;
3408 }
3409
3410 static DisasJumpType op_maeb(DisasContext *s, DisasOps *o)
3411 {
3412 TCGv_i64 r3 = load_freg32_i64(get_field(s, r3));
3413 gen_helper_maeb(o->out, tcg_env, o->in1, o->in2, r3);
3414 return DISAS_NEXT;
3415 }
3416
3417 static DisasJumpType op_madb(DisasContext *s, DisasOps *o)
3418 {
3419 TCGv_i64 r3 = load_freg(get_field(s, r3));
3420 gen_helper_madb(o->out, tcg_env, o->in1, o->in2, r3);
3421 return DISAS_NEXT;
3422 }
3423
3424 static DisasJumpType op_mseb(DisasContext *s, DisasOps *o)
3425 {
3426 TCGv_i64 r3 = load_freg32_i64(get_field(s, r3));
3427 gen_helper_mseb(o->out, tcg_env, o->in1, o->in2, r3);
3428 return DISAS_NEXT;
3429 }
3430
3431 static DisasJumpType op_msdb(DisasContext *s, DisasOps *o)
3432 {
3433 TCGv_i64 r3 = load_freg(get_field(s, r3));
3434 gen_helper_msdb(o->out, tcg_env, o->in1, o->in2, r3);
3435 return DISAS_NEXT;
3436 }
3437
3438 static DisasJumpType op_nabs(DisasContext *s, DisasOps *o)
3439 {
3440 TCGv_i64 z = tcg_constant_i64(0);
3441 TCGv_i64 n = tcg_temp_new_i64();
3442
3443 tcg_gen_neg_i64(n, o->in2);
3444 tcg_gen_movcond_i64(TCG_COND_GE, o->out, o->in2, z, n, o->in2);
3445 return DISAS_NEXT;
3446 }
3447
3448 static DisasJumpType op_nabsf32(DisasContext *s, DisasOps *o)
3449 {
3450 tcg_gen_ori_i64(o->out, o->in2, 0x80000000ull);
3451 return DISAS_NEXT;
3452 }
3453
3454 static DisasJumpType op_nabsf64(DisasContext *s, DisasOps *o)
3455 {
3456 tcg_gen_ori_i64(o->out, o->in2, 0x8000000000000000ull);
3457 return DISAS_NEXT;
3458 }
3459
3460 static DisasJumpType op_nabsf128(DisasContext *s, DisasOps *o)
3461 {
3462 tcg_gen_ori_i64(o->out, o->in1, 0x8000000000000000ull);
3463 tcg_gen_mov_i64(o->out2, o->in2);
3464 return DISAS_NEXT;
3465 }
3466
3467 static DisasJumpType op_nc(DisasContext *s, DisasOps *o)
3468 {
3469 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3470
3471 gen_helper_nc(cc_op, tcg_env, l, o->addr1, o->in2);
3472 set_cc_static(s);
3473 return DISAS_NEXT;
3474 }
3475
3476 static DisasJumpType op_neg(DisasContext *s, DisasOps *o)
3477 {
3478 tcg_gen_neg_i64(o->out, o->in2);
3479 return DISAS_NEXT;
3480 }
3481
3482 static DisasJumpType op_negf32(DisasContext *s, DisasOps *o)
3483 {
3484 tcg_gen_xori_i64(o->out, o->in2, 0x80000000ull);
3485 return DISAS_NEXT;
3486 }
3487
3488 static DisasJumpType op_negf64(DisasContext *s, DisasOps *o)
3489 {
3490 tcg_gen_xori_i64(o->out, o->in2, 0x8000000000000000ull);
3491 return DISAS_NEXT;
3492 }
3493
3494 static DisasJumpType op_negf128(DisasContext *s, DisasOps *o)
3495 {
3496 tcg_gen_xori_i64(o->out, o->in1, 0x8000000000000000ull);
3497 tcg_gen_mov_i64(o->out2, o->in2);
3498 return DISAS_NEXT;
3499 }
3500
3501 static DisasJumpType op_oc(DisasContext *s, DisasOps *o)
3502 {
3503 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3504
3505 gen_helper_oc(cc_op, tcg_env, l, o->addr1, o->in2);
3506 set_cc_static(s);
3507 return DISAS_NEXT;
3508 }
3509
3510 static DisasJumpType op_or(DisasContext *s, DisasOps *o)
3511 {
3512 tcg_gen_or_i64(o->out, o->in1, o->in2);
3513 return DISAS_NEXT;
3514 }
3515
3516 static DisasJumpType op_ori(DisasContext *s, DisasOps *o)
3517 {
3518 int shift = s->insn->data & 0xff;
3519 int size = s->insn->data >> 8;
3520 uint64_t mask = ((1ull << size) - 1) << shift;
3521 TCGv_i64 t = tcg_temp_new_i64();
3522
3523 tcg_gen_shli_i64(t, o->in2, shift);
3524 tcg_gen_or_i64(o->out, o->in1, t);
3525
3526 /* Produce the CC from only the bits manipulated. */
3527 tcg_gen_andi_i64(cc_dst, o->out, mask);
3528 set_cc_nz_u64(s, cc_dst);
3529 return DISAS_NEXT;
3530 }
3531
3532 static DisasJumpType op_oi(DisasContext *s, DisasOps *o)
3533 {
3534 o->in1 = tcg_temp_new_i64();
3535
3536 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
3537 tcg_gen_qemu_ld_i64(o->in1, o->addr1, get_mem_index(s), s->insn->data);
3538 } else {
3539 /* Perform the atomic operation in memory. */
3540 tcg_gen_atomic_fetch_or_i64(o->in1, o->addr1, o->in2, get_mem_index(s),
3541 s->insn->data);
3542 }
3543
3544 /* Recompute also for atomic case: needed for setting CC. */
3545 tcg_gen_or_i64(o->out, o->in1, o->in2);
3546
3547 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
3548 tcg_gen_qemu_st_i64(o->out, o->addr1, get_mem_index(s), s->insn->data);
3549 }
3550 return DISAS_NEXT;
3551 }
3552
3553 static DisasJumpType op_pack(DisasContext *s, DisasOps *o)
3554 {
3555 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
3556
3557 gen_helper_pack(tcg_env, l, o->addr1, o->in2);
3558 return DISAS_NEXT;
3559 }
3560
3561 static DisasJumpType op_pka(DisasContext *s, DisasOps *o)
3562 {
3563 int l2 = get_field(s, l2) + 1;
3564 TCGv_i32 l;
3565
3566 /* The length must not exceed 32 bytes. */
3567 if (l2 > 32) {
3568 gen_program_exception(s, PGM_SPECIFICATION);
3569 return DISAS_NORETURN;
3570 }
3571 l = tcg_constant_i32(l2);
3572 gen_helper_pka(tcg_env, o->addr1, o->in2, l);
3573 return DISAS_NEXT;
3574 }
3575
3576 static DisasJumpType op_pku(DisasContext *s, DisasOps *o)
3577 {
3578 int l2 = get_field(s, l2) + 1;
3579 TCGv_i32 l;
3580
3581 /* The length must be even and should not exceed 64 bytes. */
3582 if ((l2 & 1) || (l2 > 64)) {
3583 gen_program_exception(s, PGM_SPECIFICATION);
3584 return DISAS_NORETURN;
3585 }
3586 l = tcg_constant_i32(l2);
3587 gen_helper_pku(tcg_env, o->addr1, o->in2, l);
3588 return DISAS_NEXT;
3589 }
3590
3591 static DisasJumpType op_popcnt(DisasContext *s, DisasOps *o)
3592 {
3593 const uint8_t m3 = get_field(s, m3);
3594
3595 if ((m3 & 8) && s390_has_feat(S390_FEAT_MISC_INSTRUCTION_EXT3)) {
3596 tcg_gen_ctpop_i64(o->out, o->in2);
3597 } else {
3598 gen_helper_popcnt(o->out, o->in2);
3599 }
3600 return DISAS_NEXT;
3601 }
3602
3603 #ifndef CONFIG_USER_ONLY
3604 static DisasJumpType op_ptlb(DisasContext *s, DisasOps *o)
3605 {
3606 gen_helper_ptlb(tcg_env);
3607 return DISAS_NEXT;
3608 }
3609 #endif
3610
3611 static DisasJumpType op_risbg(DisasContext *s, DisasOps *o)
3612 {
3613 int i3 = get_field(s, i3);
3614 int i4 = get_field(s, i4);
3615 int i5 = get_field(s, i5);
3616 int do_zero = i4 & 0x80;
3617 uint64_t mask, imask, pmask;
3618 int pos, len, rot;
3619
3620 /* Adjust the arguments for the specific insn. */
3621 switch (s->fields.op2) {
3622 case 0x55: /* risbg */
3623 case 0x59: /* risbgn */
3624 i3 &= 63;
3625 i4 &= 63;
3626 pmask = ~0;
3627 break;
3628 case 0x5d: /* risbhg */
3629 i3 &= 31;
3630 i4 &= 31;
3631 pmask = 0xffffffff00000000ull;
3632 break;
3633 case 0x51: /* risblg */
3634 i3 = (i3 & 31) + 32;
3635 i4 = (i4 & 31) + 32;
3636 pmask = 0x00000000ffffffffull;
3637 break;
3638 default:
3639 g_assert_not_reached();
3640 }
3641
3642 /* MASK is the set of bits to be inserted from R2. */
3643 if (i3 <= i4) {
3644 /* [0...i3---i4...63] */
3645 mask = (-1ull >> i3) & (-1ull << (63 - i4));
3646 } else {
3647 /* [0---i4...i3---63] */
3648 mask = (-1ull >> i3) | (-1ull << (63 - i4));
3649 }
3650 /* For RISBLG/RISBHG, the wrapping is limited to the high/low doubleword. */
3651 mask &= pmask;
3652
3653 /* IMASK is the set of bits to be kept from R1. In the case of the high/low
3654 insns, we need to keep the other half of the register. */
3655 imask = ~mask | ~pmask;
3656 if (do_zero) {
3657 imask = ~pmask;
3658 }
3659
3660 len = i4 - i3 + 1;
3661 pos = 63 - i4;
3662 rot = i5 & 63;
3663
3664 /* In some cases we can implement this with extract. */
3665 if (imask == 0 && pos == 0 && len > 0 && len <= rot) {
3666 tcg_gen_extract_i64(o->out, o->in2, 64 - rot, len);
3667 return DISAS_NEXT;
3668 }
3669
3670 /* In some cases we can implement this with deposit. */
3671 if (len > 0 && (imask == 0 || ~mask == imask)) {
3672 /* Note that we rotate the bits to be inserted to the lsb, not to
3673 the position as described in the PoO. */
3674 rot = (rot - pos) & 63;
3675 } else {
3676 pos = -1;
3677 }
3678
3679 /* Rotate the input as necessary. */
3680 tcg_gen_rotli_i64(o->in2, o->in2, rot);
3681
3682 /* Insert the selected bits into the output. */
3683 if (pos >= 0) {
3684 if (imask == 0) {
3685 tcg_gen_deposit_z_i64(o->out, o->in2, pos, len);
3686 } else {
3687 tcg_gen_deposit_i64(o->out, o->out, o->in2, pos, len);
3688 }
3689 } else if (imask == 0) {
3690 tcg_gen_andi_i64(o->out, o->in2, mask);
3691 } else {
3692 tcg_gen_andi_i64(o->in2, o->in2, mask);
3693 tcg_gen_andi_i64(o->out, o->out, imask);
3694 tcg_gen_or_i64(o->out, o->out, o->in2);
3695 }
3696 return DISAS_NEXT;
3697 }
3698
3699 static DisasJumpType op_rosbg(DisasContext *s, DisasOps *o)
3700 {
3701 int i3 = get_field(s, i3);
3702 int i4 = get_field(s, i4);
3703 int i5 = get_field(s, i5);
3704 TCGv_i64 orig_out;
3705 uint64_t mask;
3706
3707 /* If this is a test-only form, arrange to discard the result. */
3708 if (i3 & 0x80) {
3709 tcg_debug_assert(o->out != NULL);
3710 orig_out = o->out;
3711 o->out = tcg_temp_new_i64();
3712 tcg_gen_mov_i64(o->out, orig_out);
3713 }
3714
3715 i3 &= 63;
3716 i4 &= 63;
3717 i5 &= 63;
3718
3719 /* MASK is the set of bits to be operated on from R2.
3720 Take care for I3/I4 wraparound. */
3721 mask = ~0ull >> i3;
3722 if (i3 <= i4) {
3723 mask ^= ~0ull >> i4 >> 1;
3724 } else {
3725 mask |= ~(~0ull >> i4 >> 1);
3726 }
3727
3728 /* Rotate the input as necessary. */
3729 tcg_gen_rotli_i64(o->in2, o->in2, i5);
3730
3731 /* Operate. */
3732 switch (s->fields.op2) {
3733 case 0x54: /* AND */
3734 tcg_gen_ori_i64(o->in2, o->in2, ~mask);
3735 tcg_gen_and_i64(o->out, o->out, o->in2);
3736 break;
3737 case 0x56: /* OR */
3738 tcg_gen_andi_i64(o->in2, o->in2, mask);
3739 tcg_gen_or_i64(o->out, o->out, o->in2);
3740 break;
3741 case 0x57: /* XOR */
3742 tcg_gen_andi_i64(o->in2, o->in2, mask);
3743 tcg_gen_xor_i64(o->out, o->out, o->in2);
3744 break;
3745 default:
3746 abort();
3747 }
3748
3749 /* Set the CC. */
3750 tcg_gen_andi_i64(cc_dst, o->out, mask);
3751 set_cc_nz_u64(s, cc_dst);
3752 return DISAS_NEXT;
3753 }
3754
3755 static DisasJumpType op_rev16(DisasContext *s, DisasOps *o)
3756 {
3757 tcg_gen_bswap16_i64(o->out, o->in2, TCG_BSWAP_IZ | TCG_BSWAP_OZ);
3758 return DISAS_NEXT;
3759 }
3760
3761 static DisasJumpType op_rev32(DisasContext *s, DisasOps *o)
3762 {
3763 tcg_gen_bswap32_i64(o->out, o->in2, TCG_BSWAP_IZ | TCG_BSWAP_OZ);
3764 return DISAS_NEXT;
3765 }
3766
3767 static DisasJumpType op_rev64(DisasContext *s, DisasOps *o)
3768 {
3769 tcg_gen_bswap64_i64(o->out, o->in2);
3770 return DISAS_NEXT;
3771 }
3772
3773 static DisasJumpType op_rll32(DisasContext *s, DisasOps *o)
3774 {
3775 TCGv_i32 t1 = tcg_temp_new_i32();
3776 TCGv_i32 t2 = tcg_temp_new_i32();
3777 TCGv_i32 to = tcg_temp_new_i32();
3778 tcg_gen_extrl_i64_i32(t1, o->in1);
3779 tcg_gen_extrl_i64_i32(t2, o->in2);
3780 tcg_gen_rotl_i32(to, t1, t2);
3781 tcg_gen_extu_i32_i64(o->out, to);
3782 return DISAS_NEXT;
3783 }
3784
3785 static DisasJumpType op_rll64(DisasContext *s, DisasOps *o)
3786 {
3787 tcg_gen_rotl_i64(o->out, o->in1, o->in2);
3788 return DISAS_NEXT;
3789 }
3790
3791 #ifndef CONFIG_USER_ONLY
3792 static DisasJumpType op_rrbe(DisasContext *s, DisasOps *o)
3793 {
3794 gen_helper_rrbe(cc_op, tcg_env, o->in2);
3795 set_cc_static(s);
3796 return DISAS_NEXT;
3797 }
3798
3799 static DisasJumpType op_sacf(DisasContext *s, DisasOps *o)
3800 {
3801 gen_helper_sacf(tcg_env, o->in2);
3802 /* Addressing mode has changed, so end the block. */
3803 return DISAS_TOO_MANY;
3804 }
3805 #endif
3806
3807 static DisasJumpType op_sam(DisasContext *s, DisasOps *o)
3808 {
3809 int sam = s->insn->data;
3810 TCGv_i64 tsam;
3811 uint64_t mask;
3812
3813 switch (sam) {
3814 case 0:
3815 mask = 0xffffff;
3816 break;
3817 case 1:
3818 mask = 0x7fffffff;
3819 break;
3820 default:
3821 mask = -1;
3822 break;
3823 }
3824
3825 /* Bizarre but true, we check the address of the current insn for the
3826 specification exception, not the next to be executed. Thus the PoO
3827 documents that Bad Things Happen two bytes before the end. */
3828 if (s->base.pc_next & ~mask) {
3829 gen_program_exception(s, PGM_SPECIFICATION);
3830 return DISAS_NORETURN;
3831 }
3832 s->pc_tmp &= mask;
3833
3834 tsam = tcg_constant_i64(sam);
3835 tcg_gen_deposit_i64(psw_mask, psw_mask, tsam, 31, 2);
3836
3837 /* Always exit the TB, since we (may have) changed execution mode. */
3838 return DISAS_TOO_MANY;
3839 }
3840
3841 static DisasJumpType op_sar(DisasContext *s, DisasOps *o)
3842 {
3843 int r1 = get_field(s, r1);
3844 tcg_gen_st32_i64(o->in2, tcg_env, offsetof(CPUS390XState, aregs[r1]));
3845 return DISAS_NEXT;
3846 }
3847
3848 static DisasJumpType op_seb(DisasContext *s, DisasOps *o)
3849 {
3850 gen_helper_seb(o->out, tcg_env, o->in1, o->in2);
3851 return DISAS_NEXT;
3852 }
3853
3854 static DisasJumpType op_sdb(DisasContext *s, DisasOps *o)
3855 {
3856 gen_helper_sdb(o->out, tcg_env, o->in1, o->in2);
3857 return DISAS_NEXT;
3858 }
3859
3860 static DisasJumpType op_sxb(DisasContext *s, DisasOps *o)
3861 {
3862 gen_helper_sxb(o->out_128, tcg_env, o->in1_128, o->in2_128);
3863 return DISAS_NEXT;
3864 }
3865
3866 static DisasJumpType op_sqeb(DisasContext *s, DisasOps *o)
3867 {
3868 gen_helper_sqeb(o->out, tcg_env, o->in2);
3869 return DISAS_NEXT;
3870 }
3871
3872 static DisasJumpType op_sqdb(DisasContext *s, DisasOps *o)
3873 {
3874 gen_helper_sqdb(o->out, tcg_env, o->in2);
3875 return DISAS_NEXT;
3876 }
3877
3878 static DisasJumpType op_sqxb(DisasContext *s, DisasOps *o)
3879 {
3880 gen_helper_sqxb(o->out_128, tcg_env, o->in2_128);
3881 return DISAS_NEXT;
3882 }
3883
3884 #ifndef CONFIG_USER_ONLY
3885 static DisasJumpType op_servc(DisasContext *s, DisasOps *o)
3886 {
3887 gen_helper_servc(cc_op, tcg_env, o->in2, o->in1);
3888 set_cc_static(s);
3889 return DISAS_NEXT;
3890 }
3891
3892 static DisasJumpType op_sigp(DisasContext *s, DisasOps *o)
3893 {
3894 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
3895 TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
3896
3897 gen_helper_sigp(cc_op, tcg_env, o->in2, r1, r3);
3898 set_cc_static(s);
3899 return DISAS_NEXT;
3900 }
3901 #endif
3902
3903 static DisasJumpType op_soc(DisasContext *s, DisasOps *o)
3904 {
3905 DisasCompare c;
3906 TCGv_i64 a, h;
3907 TCGLabel *lab;
3908 int r1;
3909
3910 disas_jcc(s, &c, get_field(s, m3));
3911
3912 /* We want to store when the condition is fulfilled, so branch
3913 out when it's not */
3914 c.cond = tcg_invert_cond(c.cond);
3915
3916 lab = gen_new_label();
3917 if (c.is_64) {
3918 tcg_gen_brcond_i64(c.cond, c.u.s64.a, c.u.s64.b, lab);
3919 } else {
3920 tcg_gen_brcond_i32(c.cond, c.u.s32.a, c.u.s32.b, lab);
3921 }
3922
3923 r1 = get_field(s, r1);
3924 a = get_address(s, 0, get_field(s, b2), get_field(s, d2));
3925 switch (s->insn->data) {
3926 case 1: /* STOCG */
3927 tcg_gen_qemu_st_i64(regs[r1], a, get_mem_index(s), MO_BEUQ);
3928 break;
3929 case 0: /* STOC */
3930 tcg_gen_qemu_st_i64(regs[r1], a, get_mem_index(s), MO_BEUL);
3931 break;
3932 case 2: /* STOCFH */
3933 h = tcg_temp_new_i64();
3934 tcg_gen_shri_i64(h, regs[r1], 32);
3935 tcg_gen_qemu_st_i64(h, a, get_mem_index(s), MO_BEUL);
3936 break;
3937 default:
3938 g_assert_not_reached();
3939 }
3940
3941 gen_set_label(lab);
3942 return DISAS_NEXT;
3943 }
3944
3945 static DisasJumpType op_sla(DisasContext *s, DisasOps *o)
3946 {
3947 TCGv_i64 t;
3948 uint64_t sign = 1ull << s->insn->data;
3949 if (s->insn->data == 31) {
3950 t = tcg_temp_new_i64();
3951 tcg_gen_shli_i64(t, o->in1, 32);
3952 } else {
3953 t = o->in1;
3954 }
3955 gen_op_update2_cc_i64(s, CC_OP_SLA, t, o->in2);
3956 tcg_gen_shl_i64(o->out, o->in1, o->in2);
3957 /* The arithmetic left shift is curious in that it does not affect
3958 the sign bit. Copy that over from the source unchanged. */
3959 tcg_gen_andi_i64(o->out, o->out, ~sign);
3960 tcg_gen_andi_i64(o->in1, o->in1, sign);
3961 tcg_gen_or_i64(o->out, o->out, o->in1);
3962 return DISAS_NEXT;
3963 }
3964
3965 static DisasJumpType op_sll(DisasContext *s, DisasOps *o)
3966 {
3967 tcg_gen_shl_i64(o->out, o->in1, o->in2);
3968 return DISAS_NEXT;
3969 }
3970
3971 static DisasJumpType op_sra(DisasContext *s, DisasOps *o)
3972 {
3973 tcg_gen_sar_i64(o->out, o->in1, o->in2);
3974 return DISAS_NEXT;
3975 }
3976
3977 static DisasJumpType op_srl(DisasContext *s, DisasOps *o)
3978 {
3979 tcg_gen_shr_i64(o->out, o->in1, o->in2);
3980 return DISAS_NEXT;
3981 }
3982
3983 static DisasJumpType op_sfpc(DisasContext *s, DisasOps *o)
3984 {
3985 gen_helper_sfpc(tcg_env, o->in2);
3986 return DISAS_NEXT;
3987 }
3988
3989 static DisasJumpType op_sfas(DisasContext *s, DisasOps *o)
3990 {
3991 gen_helper_sfas(tcg_env, o->in2);
3992 return DISAS_NEXT;
3993 }
3994
3995 static DisasJumpType op_srnm(DisasContext *s, DisasOps *o)
3996 {
3997 /* Bits other than 62 and 63 are ignored. Bit 29 is set to zero. */
3998 tcg_gen_andi_i64(o->addr1, o->addr1, 0x3ull);
3999 gen_helper_srnm(tcg_env, o->addr1);
4000 return DISAS_NEXT;
4001 }
4002
4003 static DisasJumpType op_srnmb(DisasContext *s, DisasOps *o)
4004 {
4005 /* Bits 0-55 are are ignored. */
4006 tcg_gen_andi_i64(o->addr1, o->addr1, 0xffull);
4007 gen_helper_srnm(tcg_env, o->addr1);
4008 return DISAS_NEXT;
4009 }
4010
4011 static DisasJumpType op_srnmt(DisasContext *s, DisasOps *o)
4012 {
4013 TCGv_i64 tmp = tcg_temp_new_i64();
4014
4015 /* Bits other than 61-63 are ignored. */
4016 tcg_gen_andi_i64(o->addr1, o->addr1, 0x7ull);
4017
4018 /* No need to call a helper, we don't implement dfp */
4019 tcg_gen_ld32u_i64(tmp, tcg_env, offsetof(CPUS390XState, fpc));
4020 tcg_gen_deposit_i64(tmp, tmp, o->addr1, 4, 3);
4021 tcg_gen_st32_i64(tmp, tcg_env, offsetof(CPUS390XState, fpc));
4022 return DISAS_NEXT;
4023 }
4024
4025 static DisasJumpType op_spm(DisasContext *s, DisasOps *o)
4026 {
4027 tcg_gen_extrl_i64_i32(cc_op, o->in1);
4028 tcg_gen_extract_i32(cc_op, cc_op, 28, 2);
4029 set_cc_static(s);
4030
4031 tcg_gen_shri_i64(o->in1, o->in1, 24);
4032 tcg_gen_deposit_i64(psw_mask, psw_mask, o->in1, PSW_SHIFT_MASK_PM, 4);
4033 return DISAS_NEXT;
4034 }
4035
4036 static DisasJumpType op_ectg(DisasContext *s, DisasOps *o)
4037 {
4038 int b1 = get_field(s, b1);
4039 int d1 = get_field(s, d1);
4040 int b2 = get_field(s, b2);
4041 int d2 = get_field(s, d2);
4042 int r3 = get_field(s, r3);
4043 TCGv_i64 tmp = tcg_temp_new_i64();
4044
4045 /* fetch all operands first */
4046 o->in1 = tcg_temp_new_i64();
4047 tcg_gen_addi_i64(o->in1, regs[b1], d1);
4048 o->in2 = tcg_temp_new_i64();
4049 tcg_gen_addi_i64(o->in2, regs[b2], d2);
4050 o->addr1 = tcg_temp_new_i64();
4051 gen_addi_and_wrap_i64(s, o->addr1, regs[r3], 0);
4052
4053 /* load the third operand into r3 before modifying anything */
4054 tcg_gen_qemu_ld_i64(regs[r3], o->addr1, get_mem_index(s), MO_BEUQ);
4055
4056 /* subtract CPU timer from first operand and store in GR0 */
4057 gen_helper_stpt(tmp, tcg_env);
4058 tcg_gen_sub_i64(regs[0], o->in1, tmp);
4059
4060 /* store second operand in GR1 */
4061 tcg_gen_mov_i64(regs[1], o->in2);
4062 return DISAS_NEXT;
4063 }
4064
4065 #ifndef CONFIG_USER_ONLY
4066 static DisasJumpType op_spka(DisasContext *s, DisasOps *o)
4067 {
4068 tcg_gen_shri_i64(o->in2, o->in2, 4);
4069 tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, PSW_SHIFT_KEY, 4);
4070 return DISAS_NEXT;
4071 }
4072
4073 static DisasJumpType op_sske(DisasContext *s, DisasOps *o)
4074 {
4075 gen_helper_sske(tcg_env, o->in1, o->in2);
4076 return DISAS_NEXT;
4077 }
4078
4079 static void gen_check_psw_mask(DisasContext *s)
4080 {
4081 TCGv_i64 reserved = tcg_temp_new_i64();
4082 TCGLabel *ok = gen_new_label();
4083
4084 tcg_gen_andi_i64(reserved, psw_mask, PSW_MASK_RESERVED);
4085 tcg_gen_brcondi_i64(TCG_COND_EQ, reserved, 0, ok);
4086 gen_program_exception(s, PGM_SPECIFICATION);
4087 gen_set_label(ok);
4088 }
4089
4090 static DisasJumpType op_ssm(DisasContext *s, DisasOps *o)
4091 {
4092 tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, 56, 8);
4093
4094 gen_check_psw_mask(s);
4095
4096 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
4097 s->exit_to_mainloop = true;
4098 return DISAS_TOO_MANY;
4099 }
4100
4101 static DisasJumpType op_stap(DisasContext *s, DisasOps *o)
4102 {
4103 tcg_gen_ld32u_i64(o->out, tcg_env, offsetof(CPUS390XState, core_id));
4104 return DISAS_NEXT;
4105 }
4106 #endif
4107
4108 static DisasJumpType op_stck(DisasContext *s, DisasOps *o)
4109 {
4110 gen_helper_stck(o->out, tcg_env);
4111 tcg_gen_qemu_st_i64(o->out, o->addr1, get_mem_index(s), MO_BEUQ);
4112 /* ??? We don't implement clock states. */
4113 /* Set the CC after the store; a suppressed store must preserve it. */
4114 gen_op_movi_cc(s, 0);
4115 return DISAS_NEXT;
4116 }
4117
4118 static DisasJumpType op_stcke(DisasContext *s, DisasOps *o)
4119 {
4120 TCGv_i64 c1 = tcg_temp_new_i64();
4121 TCGv_i64 c2 = tcg_temp_new_i64();
4122 TCGv_i64 todpr = tcg_temp_new_i64();
4123 gen_helper_stck(c1, tcg_env);
4124 /* 16 bit value store in an uint32_t (only valid bits set) */
4125 tcg_gen_ld32u_i64(todpr, tcg_env, offsetof(CPUS390XState, todpr));
4126 /* Shift the 64-bit value into its place as a zero-extended
4127 104-bit value. Note that "bit positions 64-103 are always
4128 non-zero so that they compare differently to STCK"; we set
4129 the least significant bit to 1. */
4130 tcg_gen_shli_i64(c2, c1, 56);
4131 tcg_gen_shri_i64(c1, c1, 8);
4132 tcg_gen_ori_i64(c2, c2, 0x10000);
4133 tcg_gen_or_i64(c2, c2, todpr);
4134 tcg_gen_qemu_st_i64(c1, o->in2, get_mem_index(s), MO_BEUQ);
4135 tcg_gen_addi_i64(o->in2, o->in2, 8);
4136 tcg_gen_qemu_st_i64(c2, o->in2, get_mem_index(s), MO_BEUQ);
4137 /* ??? We don't implement clock states. */
4138 gen_op_movi_cc(s, 0);
4139 return DISAS_NEXT;
4140 }
4141
4142 #ifndef CONFIG_USER_ONLY
4143 static DisasJumpType op_sck(DisasContext *s, DisasOps *o)
4144 {
4145 gen_helper_sck(cc_op, tcg_env, o->in2);
4146 set_cc_static(s);
4147 return DISAS_NEXT;
4148 }
4149
4150 static DisasJumpType op_sckc(DisasContext *s, DisasOps *o)
4151 {
4152 gen_helper_sckc(tcg_env, o->in2);
4153 return DISAS_NEXT;
4154 }
4155
4156 static DisasJumpType op_sckpf(DisasContext *s, DisasOps *o)
4157 {
4158 gen_helper_sckpf(tcg_env, regs[0]);
4159 return DISAS_NEXT;
4160 }
4161
4162 static DisasJumpType op_stckc(DisasContext *s, DisasOps *o)
4163 {
4164 gen_helper_stckc(o->out, tcg_env);
4165 return DISAS_NEXT;
4166 }
4167
4168 static DisasJumpType op_stctg(DisasContext *s, DisasOps *o)
4169 {
4170 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4171 TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
4172
4173 gen_helper_stctg(tcg_env, r1, o->in2, r3);
4174 return DISAS_NEXT;
4175 }
4176
4177 static DisasJumpType op_stctl(DisasContext *s, DisasOps *o)
4178 {
4179 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4180 TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
4181
4182 gen_helper_stctl(tcg_env, r1, o->in2, r3);
4183 return DISAS_NEXT;
4184 }
4185
4186 static DisasJumpType op_stidp(DisasContext *s, DisasOps *o)
4187 {
4188 tcg_gen_ld_i64(o->out, tcg_env, offsetof(CPUS390XState, cpuid));
4189 return DISAS_NEXT;
4190 }
4191
4192 static DisasJumpType op_spt(DisasContext *s, DisasOps *o)
4193 {
4194 gen_helper_spt(tcg_env, o->in2);
4195 return DISAS_NEXT;
4196 }
4197
4198 static DisasJumpType op_stfl(DisasContext *s, DisasOps *o)
4199 {
4200 gen_helper_stfl(tcg_env);
4201 return DISAS_NEXT;
4202 }
4203
4204 static DisasJumpType op_stpt(DisasContext *s, DisasOps *o)
4205 {
4206 gen_helper_stpt(o->out, tcg_env);
4207 return DISAS_NEXT;
4208 }
4209
4210 static DisasJumpType op_stsi(DisasContext *s, DisasOps *o)
4211 {
4212 gen_helper_stsi(cc_op, tcg_env, o->in2, regs[0], regs[1]);
4213 set_cc_static(s);
4214 return DISAS_NEXT;
4215 }
4216
4217 static DisasJumpType op_spx(DisasContext *s, DisasOps *o)
4218 {
4219 gen_helper_spx(tcg_env, o->in2);
4220 return DISAS_NEXT;
4221 }
4222
4223 static DisasJumpType op_xsch(DisasContext *s, DisasOps *o)
4224 {
4225 gen_helper_xsch(tcg_env, regs[1]);
4226 set_cc_static(s);
4227 return DISAS_NEXT;
4228 }
4229
4230 static DisasJumpType op_csch(DisasContext *s, DisasOps *o)
4231 {
4232 gen_helper_csch(tcg_env, regs[1]);
4233 set_cc_static(s);
4234 return DISAS_NEXT;
4235 }
4236
4237 static DisasJumpType op_hsch(DisasContext *s, DisasOps *o)
4238 {
4239 gen_helper_hsch(tcg_env, regs[1]);
4240 set_cc_static(s);
4241 return DISAS_NEXT;
4242 }
4243
4244 static DisasJumpType op_msch(DisasContext *s, DisasOps *o)
4245 {
4246 gen_helper_msch(tcg_env, regs[1], o->in2);
4247 set_cc_static(s);
4248 return DISAS_NEXT;
4249 }
4250
4251 static DisasJumpType op_rchp(DisasContext *s, DisasOps *o)
4252 {
4253 gen_helper_rchp(tcg_env, regs[1]);
4254 set_cc_static(s);
4255 return DISAS_NEXT;
4256 }
4257
4258 static DisasJumpType op_rsch(DisasContext *s, DisasOps *o)
4259 {
4260 gen_helper_rsch(tcg_env, regs[1]);
4261 set_cc_static(s);
4262 return DISAS_NEXT;
4263 }
4264
4265 static DisasJumpType op_sal(DisasContext *s, DisasOps *o)
4266 {
4267 gen_helper_sal(tcg_env, regs[1]);
4268 return DISAS_NEXT;
4269 }
4270
4271 static DisasJumpType op_schm(DisasContext *s, DisasOps *o)
4272 {
4273 gen_helper_schm(tcg_env, regs[1], regs[2], o->in2);
4274 return DISAS_NEXT;
4275 }
4276
4277 static DisasJumpType op_siga(DisasContext *s, DisasOps *o)
4278 {
4279 /* From KVM code: Not provided, set CC = 3 for subchannel not operational */
4280 gen_op_movi_cc(s, 3);
4281 return DISAS_NEXT;
4282 }
4283
4284 static DisasJumpType op_stcps(DisasContext *s, DisasOps *o)
4285 {
4286 /* The instruction is suppressed if not provided. */
4287 return DISAS_NEXT;
4288 }
4289
4290 static DisasJumpType op_ssch(DisasContext *s, DisasOps *o)
4291 {
4292 gen_helper_ssch(tcg_env, regs[1], o->in2);
4293 set_cc_static(s);
4294 return DISAS_NEXT;
4295 }
4296
4297 static DisasJumpType op_stsch(DisasContext *s, DisasOps *o)
4298 {
4299 gen_helper_stsch(tcg_env, regs[1], o->in2);
4300 set_cc_static(s);
4301 return DISAS_NEXT;
4302 }
4303
4304 static DisasJumpType op_stcrw(DisasContext *s, DisasOps *o)
4305 {
4306 gen_helper_stcrw(tcg_env, o->in2);
4307 set_cc_static(s);
4308 return DISAS_NEXT;
4309 }
4310
4311 static DisasJumpType op_tpi(DisasContext *s, DisasOps *o)
4312 {
4313 gen_helper_tpi(cc_op, tcg_env, o->addr1);
4314 set_cc_static(s);
4315 return DISAS_NEXT;
4316 }
4317
4318 static DisasJumpType op_tsch(DisasContext *s, DisasOps *o)
4319 {
4320 gen_helper_tsch(tcg_env, regs[1], o->in2);
4321 set_cc_static(s);
4322 return DISAS_NEXT;
4323 }
4324
4325 static DisasJumpType op_chsc(DisasContext *s, DisasOps *o)
4326 {
4327 gen_helper_chsc(tcg_env, o->in2);
4328 set_cc_static(s);
4329 return DISAS_NEXT;
4330 }
4331
4332 static DisasJumpType op_stpx(DisasContext *s, DisasOps *o)
4333 {
4334 tcg_gen_ld_i64(o->out, tcg_env, offsetof(CPUS390XState, psa));
4335 tcg_gen_andi_i64(o->out, o->out, 0x7fffe000);
4336 return DISAS_NEXT;
4337 }
4338
4339 static DisasJumpType op_stnosm(DisasContext *s, DisasOps *o)
4340 {
4341 uint64_t i2 = get_field(s, i2);
4342 TCGv_i64 t;
4343
4344 /* It is important to do what the instruction name says: STORE THEN.
4345 If we let the output hook perform the store then if we fault and
4346 restart, we'll have the wrong SYSTEM MASK in place. */
4347 t = tcg_temp_new_i64();
4348 tcg_gen_shri_i64(t, psw_mask, 56);
4349 tcg_gen_qemu_st_i64(t, o->addr1, get_mem_index(s), MO_UB);
4350
4351 if (s->fields.op == 0xac) {
4352 tcg_gen_andi_i64(psw_mask, psw_mask,
4353 (i2 << 56) | 0x00ffffffffffffffull);
4354 } else {
4355 tcg_gen_ori_i64(psw_mask, psw_mask, i2 << 56);
4356 }
4357
4358 gen_check_psw_mask(s);
4359
4360 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
4361 s->exit_to_mainloop = true;
4362 return DISAS_TOO_MANY;
4363 }
4364
4365 static DisasJumpType op_stura(DisasContext *s, DisasOps *o)
4366 {
4367 tcg_gen_qemu_st_i64(o->in1, o->in2, MMU_REAL_IDX, s->insn->data);
4368
4369 if (s->base.tb->flags & FLAG_MASK_PER_STORE_REAL) {
4370 update_cc_op(s);
4371 update_psw_addr(s);
4372 gen_helper_per_store_real(tcg_env, tcg_constant_i32(s->ilen));
4373 return DISAS_NORETURN;
4374 }
4375 return DISAS_NEXT;
4376 }
4377 #endif
4378
4379 static DisasJumpType op_stfle(DisasContext *s, DisasOps *o)
4380 {
4381 gen_helper_stfle(cc_op, tcg_env, o->in2);
4382 set_cc_static(s);
4383 return DISAS_NEXT;
4384 }
4385
4386 static DisasJumpType op_st8(DisasContext *s, DisasOps *o)
4387 {
4388 tcg_gen_qemu_st_i64(o->in1, o->in2, get_mem_index(s), MO_UB);
4389 return DISAS_NEXT;
4390 }
4391
4392 static DisasJumpType op_st16(DisasContext *s, DisasOps *o)
4393 {
4394 tcg_gen_qemu_st_i64(o->in1, o->in2, get_mem_index(s), MO_BEUW);
4395 return DISAS_NEXT;
4396 }
4397
4398 static DisasJumpType op_st32(DisasContext *s, DisasOps *o)
4399 {
4400 tcg_gen_qemu_st_i64(o->in1, o->in2, get_mem_index(s),
4401 MO_BEUL | s->insn->data);
4402 return DISAS_NEXT;
4403 }
4404
4405 static DisasJumpType op_st64(DisasContext *s, DisasOps *o)
4406 {
4407 tcg_gen_qemu_st_i64(o->in1, o->in2, get_mem_index(s),
4408 MO_BEUQ | s->insn->data);
4409 return DISAS_NEXT;
4410 }
4411
4412 static DisasJumpType op_stam(DisasContext *s, DisasOps *o)
4413 {
4414 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4415 TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
4416
4417 gen_helper_stam(tcg_env, r1, o->in2, r3);
4418 return DISAS_NEXT;
4419 }
4420
4421 static DisasJumpType op_stcm(DisasContext *s, DisasOps *o)
4422 {
4423 int m3 = get_field(s, m3);
4424 int pos, base = s->insn->data;
4425 TCGv_i64 tmp = tcg_temp_new_i64();
4426
4427 pos = base + ctz32(m3) * 8;
4428 switch (m3) {
4429 case 0xf:
4430 /* Effectively a 32-bit store. */
4431 tcg_gen_shri_i64(tmp, o->in1, pos);
4432 tcg_gen_qemu_st_i64(tmp, o->in2, get_mem_index(s), MO_BEUL);
4433 break;
4434
4435 case 0xc:
4436 case 0x6:
4437 case 0x3:
4438 /* Effectively a 16-bit store. */
4439 tcg_gen_shri_i64(tmp, o->in1, pos);
4440 tcg_gen_qemu_st_i64(tmp, o->in2, get_mem_index(s), MO_BEUW);
4441 break;
4442
4443 case 0x8:
4444 case 0x4:
4445 case 0x2:
4446 case 0x1:
4447 /* Effectively an 8-bit store. */
4448 tcg_gen_shri_i64(tmp, o->in1, pos);
4449 tcg_gen_qemu_st_i64(tmp, o->in2, get_mem_index(s), MO_UB);
4450 break;
4451
4452 default:
4453 /* This is going to be a sequence of shifts and stores. */
4454 pos = base + 32 - 8;
4455 while (m3) {
4456 if (m3 & 0x8) {
4457 tcg_gen_shri_i64(tmp, o->in1, pos);
4458 tcg_gen_qemu_st_i64(tmp, o->in2, get_mem_index(s), MO_UB);
4459 tcg_gen_addi_i64(o->in2, o->in2, 1);
4460 }
4461 m3 = (m3 << 1) & 0xf;
4462 pos -= 8;
4463 }
4464 break;
4465 }
4466 return DISAS_NEXT;
4467 }
4468
4469 static DisasJumpType op_stm(DisasContext *s, DisasOps *o)
4470 {
4471 int r1 = get_field(s, r1);
4472 int r3 = get_field(s, r3);
4473 int size = s->insn->data;
4474 TCGv_i64 tsize = tcg_constant_i64(size);
4475
4476 while (1) {
4477 tcg_gen_qemu_st_i64(regs[r1], o->in2, get_mem_index(s),
4478 size == 8 ? MO_BEUQ : MO_BEUL);
4479 if (r1 == r3) {
4480 break;
4481 }
4482 tcg_gen_add_i64(o->in2, o->in2, tsize);
4483 r1 = (r1 + 1) & 15;
4484 }
4485
4486 return DISAS_NEXT;
4487 }
4488
4489 static DisasJumpType op_stmh(DisasContext *s, DisasOps *o)
4490 {
4491 int r1 = get_field(s, r1);
4492 int r3 = get_field(s, r3);
4493 TCGv_i64 t = tcg_temp_new_i64();
4494 TCGv_i64 t4 = tcg_constant_i64(4);
4495 TCGv_i64 t32 = tcg_constant_i64(32);
4496
4497 while (1) {
4498 tcg_gen_shl_i64(t, regs[r1], t32);
4499 tcg_gen_qemu_st_i64(t, o->in2, get_mem_index(s), MO_BEUL);
4500 if (r1 == r3) {
4501 break;
4502 }
4503 tcg_gen_add_i64(o->in2, o->in2, t4);
4504 r1 = (r1 + 1) & 15;
4505 }
4506 return DISAS_NEXT;
4507 }
4508
4509 static DisasJumpType op_stpq(DisasContext *s, DisasOps *o)
4510 {
4511 TCGv_i128 t16 = tcg_temp_new_i128();
4512
4513 tcg_gen_concat_i64_i128(t16, o->out2, o->out);
4514 tcg_gen_qemu_st_i128(t16, o->in2, get_mem_index(s),
4515 MO_BE | MO_128 | MO_ALIGN);
4516 return DISAS_NEXT;
4517 }
4518
4519 static DisasJumpType op_srst(DisasContext *s, DisasOps *o)
4520 {
4521 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4522 TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
4523
4524 gen_helper_srst(tcg_env, r1, r2);
4525 set_cc_static(s);
4526 return DISAS_NEXT;
4527 }
4528
4529 static DisasJumpType op_srstu(DisasContext *s, DisasOps *o)
4530 {
4531 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4532 TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
4533
4534 gen_helper_srstu(tcg_env, r1, r2);
4535 set_cc_static(s);
4536 return DISAS_NEXT;
4537 }
4538
4539 static DisasJumpType op_sub(DisasContext *s, DisasOps *o)
4540 {
4541 tcg_gen_sub_i64(o->out, o->in1, o->in2);
4542 return DISAS_NEXT;
4543 }
4544
4545 static DisasJumpType op_subu64(DisasContext *s, DisasOps *o)
4546 {
4547 tcg_gen_movi_i64(cc_src, 0);
4548 tcg_gen_sub2_i64(o->out, cc_src, o->in1, cc_src, o->in2, cc_src);
4549 return DISAS_NEXT;
4550 }
4551
4552 /* Compute borrow (0, -1) into cc_src. */
4553 static void compute_borrow(DisasContext *s)
4554 {
4555 switch (s->cc_op) {
4556 case CC_OP_SUBU:
4557 /* The borrow value is already in cc_src (0,-1). */
4558 break;
4559 default:
4560 gen_op_calc_cc(s);
4561 /* fall through */
4562 case CC_OP_STATIC:
4563 /* The carry flag is the msb of CC; compute into cc_src. */
4564 tcg_gen_extu_i32_i64(cc_src, cc_op);
4565 tcg_gen_shri_i64(cc_src, cc_src, 1);
4566 /* fall through */
4567 case CC_OP_ADDU:
4568 /* Convert carry (1,0) to borrow (0,-1). */
4569 tcg_gen_subi_i64(cc_src, cc_src, 1);
4570 break;
4571 }
4572 }
4573
4574 static DisasJumpType op_subb32(DisasContext *s, DisasOps *o)
4575 {
4576 compute_borrow(s);
4577
4578 /* Borrow is {0, -1}, so add to subtract. */
4579 tcg_gen_add_i64(o->out, o->in1, cc_src);
4580 tcg_gen_sub_i64(o->out, o->out, o->in2);
4581 return DISAS_NEXT;
4582 }
4583
4584 static DisasJumpType op_subb64(DisasContext *s, DisasOps *o)
4585 {
4586 compute_borrow(s);
4587
4588 /*
4589 * Borrow is {0, -1}, so add to subtract; replicate the
4590 * borrow input to produce 128-bit -1 for the addition.
4591 */
4592 TCGv_i64 zero = tcg_constant_i64(0);
4593 tcg_gen_add2_i64(o->out, cc_src, o->in1, zero, cc_src, cc_src);
4594 tcg_gen_sub2_i64(o->out, cc_src, o->out, cc_src, o->in2, zero);
4595
4596 return DISAS_NEXT;
4597 }
4598
4599 static DisasJumpType op_svc(DisasContext *s, DisasOps *o)
4600 {
4601 TCGv_i32 t;
4602
4603 update_psw_addr(s);
4604 update_cc_op(s);
4605
4606 t = tcg_constant_i32(get_field(s, i1) & 0xff);
4607 tcg_gen_st_i32(t, tcg_env, offsetof(CPUS390XState, int_svc_code));
4608
4609 t = tcg_constant_i32(s->ilen);
4610 tcg_gen_st_i32(t, tcg_env, offsetof(CPUS390XState, int_svc_ilen));
4611
4612 gen_exception(EXCP_SVC);
4613 return DISAS_NORETURN;
4614 }
4615
4616 static DisasJumpType op_tam(DisasContext *s, DisasOps *o)
4617 {
4618 int cc = 0;
4619
4620 cc |= (s->base.tb->flags & FLAG_MASK_64) ? 2 : 0;
4621 cc |= (s->base.tb->flags & FLAG_MASK_32) ? 1 : 0;
4622 gen_op_movi_cc(s, cc);
4623 return DISAS_NEXT;
4624 }
4625
4626 static DisasJumpType op_tceb(DisasContext *s, DisasOps *o)
4627 {
4628 gen_helper_tceb(cc_op, tcg_env, o->in1, o->in2);
4629 set_cc_static(s);
4630 return DISAS_NEXT;
4631 }
4632
4633 static DisasJumpType op_tcdb(DisasContext *s, DisasOps *o)
4634 {
4635 gen_helper_tcdb(cc_op, tcg_env, o->in1, o->in2);
4636 set_cc_static(s);
4637 return DISAS_NEXT;
4638 }
4639
4640 static DisasJumpType op_tcxb(DisasContext *s, DisasOps *o)
4641 {
4642 gen_helper_tcxb(cc_op, tcg_env, o->in1_128, o->in2);
4643 set_cc_static(s);
4644 return DISAS_NEXT;
4645 }
4646
4647 #ifndef CONFIG_USER_ONLY
4648
4649 static DisasJumpType op_testblock(DisasContext *s, DisasOps *o)
4650 {
4651 gen_helper_testblock(cc_op, tcg_env, o->in2);
4652 set_cc_static(s);
4653 return DISAS_NEXT;
4654 }
4655
4656 static DisasJumpType op_tprot(DisasContext *s, DisasOps *o)
4657 {
4658 gen_helper_tprot(cc_op, tcg_env, o->addr1, o->in2);
4659 set_cc_static(s);
4660 return DISAS_NEXT;
4661 }
4662
4663 #endif
4664
4665 static DisasJumpType op_tp(DisasContext *s, DisasOps *o)
4666 {
4667 TCGv_i32 l1 = tcg_constant_i32(get_field(s, l1) + 1);
4668
4669 gen_helper_tp(cc_op, tcg_env, o->addr1, l1);
4670 set_cc_static(s);
4671 return DISAS_NEXT;
4672 }
4673
4674 static DisasJumpType op_tr(DisasContext *s, DisasOps *o)
4675 {
4676 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
4677
4678 gen_helper_tr(tcg_env, l, o->addr1, o->in2);
4679 set_cc_static(s);
4680 return DISAS_NEXT;
4681 }
4682
4683 static DisasJumpType op_tre(DisasContext *s, DisasOps *o)
4684 {
4685 TCGv_i128 pair = tcg_temp_new_i128();
4686
4687 gen_helper_tre(pair, tcg_env, o->out, o->out2, o->in2);
4688 tcg_gen_extr_i128_i64(o->out2, o->out, pair);
4689 set_cc_static(s);
4690 return DISAS_NEXT;
4691 }
4692
4693 static DisasJumpType op_trt(DisasContext *s, DisasOps *o)
4694 {
4695 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
4696
4697 gen_helper_trt(cc_op, tcg_env, l, o->addr1, o->in2);
4698 set_cc_static(s);
4699 return DISAS_NEXT;
4700 }
4701
4702 static DisasJumpType op_trtr(DisasContext *s, DisasOps *o)
4703 {
4704 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
4705
4706 gen_helper_trtr(cc_op, tcg_env, l, o->addr1, o->in2);
4707 set_cc_static(s);
4708 return DISAS_NEXT;
4709 }
4710
4711 static DisasJumpType op_trXX(DisasContext *s, DisasOps *o)
4712 {
4713 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4714 TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
4715 TCGv_i32 sizes = tcg_constant_i32(s->insn->opc & 3);
4716 TCGv_i32 tst = tcg_temp_new_i32();
4717 int m3 = get_field(s, m3);
4718
4719 if (!s390_has_feat(S390_FEAT_ETF2_ENH)) {
4720 m3 = 0;
4721 }
4722 if (m3 & 1) {
4723 tcg_gen_movi_i32(tst, -1);
4724 } else {
4725 tcg_gen_extrl_i64_i32(tst, regs[0]);
4726 if (s->insn->opc & 3) {
4727 tcg_gen_ext8u_i32(tst, tst);
4728 } else {
4729 tcg_gen_ext16u_i32(tst, tst);
4730 }
4731 }
4732 gen_helper_trXX(cc_op, tcg_env, r1, r2, tst, sizes);
4733
4734 set_cc_static(s);
4735 return DISAS_NEXT;
4736 }
4737
4738 static DisasJumpType op_ts(DisasContext *s, DisasOps *o)
4739 {
4740 TCGv_i32 ff = tcg_constant_i32(0xff);
4741 TCGv_i32 t1 = tcg_temp_new_i32();
4742
4743 tcg_gen_atomic_xchg_i32(t1, o->in2, ff, get_mem_index(s), MO_UB);
4744 tcg_gen_extract_i32(cc_op, t1, 7, 1);
4745 set_cc_static(s);
4746 return DISAS_NEXT;
4747 }
4748
4749 static DisasJumpType op_unpk(DisasContext *s, DisasOps *o)
4750 {
4751 TCGv_i32 l = tcg_constant_i32(get_field(s, l1));
4752
4753 gen_helper_unpk(tcg_env, l, o->addr1, o->in2);
4754 return DISAS_NEXT;
4755 }
4756
4757 static DisasJumpType op_unpka(DisasContext *s, DisasOps *o)
4758 {
4759 int l1 = get_field(s, l1) + 1;
4760 TCGv_i32 l;
4761
4762 /* The length must not exceed 32 bytes. */
4763 if (l1 > 32) {
4764 gen_program_exception(s, PGM_SPECIFICATION);
4765 return DISAS_NORETURN;
4766 }
4767 l = tcg_constant_i32(l1);
4768 gen_helper_unpka(cc_op, tcg_env, o->addr1, l, o->in2);
4769 set_cc_static(s);
4770 return DISAS_NEXT;
4771 }
4772
4773 static DisasJumpType op_unpku(DisasContext *s, DisasOps *o)
4774 {
4775 int l1 = get_field(s, l1) + 1;
4776 TCGv_i32 l;
4777
4778 /* The length must be even and should not exceed 64 bytes. */
4779 if ((l1 & 1) || (l1 > 64)) {
4780 gen_program_exception(s, PGM_SPECIFICATION);
4781 return DISAS_NORETURN;
4782 }
4783 l = tcg_constant_i32(l1);
4784 gen_helper_unpku(cc_op, tcg_env, o->addr1, l, o->in2);
4785 set_cc_static(s);
4786 return DISAS_NEXT;
4787 }
4788
4789
4790 static DisasJumpType op_xc(DisasContext *s, DisasOps *o)
4791 {
4792 int d1 = get_field(s, d1);
4793 int d2 = get_field(s, d2);
4794 int b1 = get_field(s, b1);
4795 int b2 = get_field(s, b2);
4796 int l = get_field(s, l1);
4797 TCGv_i32 t32;
4798
4799 o->addr1 = get_address(s, 0, b1, d1);
4800
4801 /* If the addresses are identical, this is a store/memset of zero. */
4802 if (b1 == b2 && d1 == d2 && (l + 1) <= 32) {
4803 o->in2 = tcg_constant_i64(0);
4804
4805 l++;
4806 while (l >= 8) {
4807 tcg_gen_qemu_st_i64(o->in2, o->addr1, get_mem_index(s), MO_UQ);
4808 l -= 8;
4809 if (l > 0) {
4810 tcg_gen_addi_i64(o->addr1, o->addr1, 8);
4811 }
4812 }
4813 if (l >= 4) {
4814 tcg_gen_qemu_st_i64(o->in2, o->addr1, get_mem_index(s), MO_UL);
4815 l -= 4;
4816 if (l > 0) {
4817 tcg_gen_addi_i64(o->addr1, o->addr1, 4);
4818 }
4819 }
4820 if (l >= 2) {
4821 tcg_gen_qemu_st_i64(o->in2, o->addr1, get_mem_index(s), MO_UW);
4822 l -= 2;
4823 if (l > 0) {
4824 tcg_gen_addi_i64(o->addr1, o->addr1, 2);
4825 }
4826 }
4827 if (l) {
4828 tcg_gen_qemu_st_i64(o->in2, o->addr1, get_mem_index(s), MO_UB);
4829 }
4830 gen_op_movi_cc(s, 0);
4831 return DISAS_NEXT;
4832 }
4833
4834 /* But in general we'll defer to a helper. */
4835 o->in2 = get_address(s, 0, b2, d2);
4836 t32 = tcg_constant_i32(l);
4837 gen_helper_xc(cc_op, tcg_env, t32, o->addr1, o->in2);
4838 set_cc_static(s);
4839 return DISAS_NEXT;
4840 }
4841
4842 static DisasJumpType op_xor(DisasContext *s, DisasOps *o)
4843 {
4844 tcg_gen_xor_i64(o->out, o->in1, o->in2);
4845 return DISAS_NEXT;
4846 }
4847
4848 static DisasJumpType op_xori(DisasContext *s, DisasOps *o)
4849 {
4850 int shift = s->insn->data & 0xff;
4851 int size = s->insn->data >> 8;
4852 uint64_t mask = ((1ull << size) - 1) << shift;
4853 TCGv_i64 t = tcg_temp_new_i64();
4854
4855 tcg_gen_shli_i64(t, o->in2, shift);
4856 tcg_gen_xor_i64(o->out, o->in1, t);
4857
4858 /* Produce the CC from only the bits manipulated. */
4859 tcg_gen_andi_i64(cc_dst, o->out, mask);
4860 set_cc_nz_u64(s, cc_dst);
4861 return DISAS_NEXT;
4862 }
4863
4864 static DisasJumpType op_xi(DisasContext *s, DisasOps *o)
4865 {
4866 o->in1 = tcg_temp_new_i64();
4867
4868 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
4869 tcg_gen_qemu_ld_i64(o->in1, o->addr1, get_mem_index(s), s->insn->data);
4870 } else {
4871 /* Perform the atomic operation in memory. */
4872 tcg_gen_atomic_fetch_xor_i64(o->in1, o->addr1, o->in2, get_mem_index(s),
4873 s->insn->data);
4874 }
4875
4876 /* Recompute also for atomic case: needed for setting CC. */
4877 tcg_gen_xor_i64(o->out, o->in1, o->in2);
4878
4879 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2)) {
4880 tcg_gen_qemu_st_i64(o->out, o->addr1, get_mem_index(s), s->insn->data);
4881 }
4882 return DISAS_NEXT;
4883 }
4884
4885 static DisasJumpType op_zero(DisasContext *s, DisasOps *o)
4886 {
4887 o->out = tcg_constant_i64(0);
4888 return DISAS_NEXT;
4889 }
4890
4891 static DisasJumpType op_zero2(DisasContext *s, DisasOps *o)
4892 {
4893 o->out = tcg_constant_i64(0);
4894 o->out2 = o->out;
4895 return DISAS_NEXT;
4896 }
4897
4898 #ifndef CONFIG_USER_ONLY
4899 static DisasJumpType op_clp(DisasContext *s, DisasOps *o)
4900 {
4901 TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
4902
4903 gen_helper_clp(tcg_env, r2);
4904 set_cc_static(s);
4905 return DISAS_NEXT;
4906 }
4907
4908 static DisasJumpType op_pcilg(DisasContext *s, DisasOps *o)
4909 {
4910 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4911 TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
4912
4913 gen_helper_pcilg(tcg_env, r1, r2);
4914 set_cc_static(s);
4915 return DISAS_NEXT;
4916 }
4917
4918 static DisasJumpType op_pcistg(DisasContext *s, DisasOps *o)
4919 {
4920 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4921 TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
4922
4923 gen_helper_pcistg(tcg_env, r1, r2);
4924 set_cc_static(s);
4925 return DISAS_NEXT;
4926 }
4927
4928 static DisasJumpType op_stpcifc(DisasContext *s, DisasOps *o)
4929 {
4930 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4931 TCGv_i32 ar = tcg_constant_i32(get_field(s, b2));
4932
4933 gen_helper_stpcifc(tcg_env, r1, o->addr1, ar);
4934 set_cc_static(s);
4935 return DISAS_NEXT;
4936 }
4937
4938 static DisasJumpType op_sic(DisasContext *s, DisasOps *o)
4939 {
4940 gen_helper_sic(tcg_env, o->in1, o->in2);
4941 return DISAS_NEXT;
4942 }
4943
4944 static DisasJumpType op_rpcit(DisasContext *s, DisasOps *o)
4945 {
4946 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4947 TCGv_i32 r2 = tcg_constant_i32(get_field(s, r2));
4948
4949 gen_helper_rpcit(tcg_env, r1, r2);
4950 set_cc_static(s);
4951 return DISAS_NEXT;
4952 }
4953
4954 static DisasJumpType op_pcistb(DisasContext *s, DisasOps *o)
4955 {
4956 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4957 TCGv_i32 r3 = tcg_constant_i32(get_field(s, r3));
4958 TCGv_i32 ar = tcg_constant_i32(get_field(s, b2));
4959
4960 gen_helper_pcistb(tcg_env, r1, r3, o->addr1, ar);
4961 set_cc_static(s);
4962 return DISAS_NEXT;
4963 }
4964
4965 static DisasJumpType op_mpcifc(DisasContext *s, DisasOps *o)
4966 {
4967 TCGv_i32 r1 = tcg_constant_i32(get_field(s, r1));
4968 TCGv_i32 ar = tcg_constant_i32(get_field(s, b2));
4969
4970 gen_helper_mpcifc(tcg_env, r1, o->addr1, ar);
4971 set_cc_static(s);
4972 return DISAS_NEXT;
4973 }
4974 #endif
4975
4976 #include "translate_vx.c.inc"
4977
4978 /* ====================================================================== */
4979 /* The "Cc OUTput" generators. Given the generated output (and in some cases
4980 the original inputs), update the various cc data structures in order to
4981 be able to compute the new condition code. */
4982
4983 static void cout_abs32(DisasContext *s, DisasOps *o)
4984 {
4985 gen_op_update1_cc_i64(s, CC_OP_ABS_32, o->out);
4986 }
4987
4988 static void cout_abs64(DisasContext *s, DisasOps *o)
4989 {
4990 gen_op_update1_cc_i64(s, CC_OP_ABS_64, o->out);
4991 }
4992
4993 static void cout_adds32(DisasContext *s, DisasOps *o)
4994 {
4995 gen_op_update3_cc_i64(s, CC_OP_ADD_32, o->in1, o->in2, o->out);
4996 }
4997
4998 static void cout_adds64(DisasContext *s, DisasOps *o)
4999 {
5000 gen_op_update3_cc_i64(s, CC_OP_ADD_64, o->in1, o->in2, o->out);
Showing first 5,000 of 6,536 lines. View raw