4 * Copyright (c) 2009 Ulrich Hecht
5 * Copyright (c) 2010 Alexander Graf
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.
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.
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/>.
21 /* #define DEBUG_INLINE_BRANCHES */
22 #define S390X_DEBUG_DISAS
23 /* #define S390X_DEBUG_DISAS_VERBOSE */
25 #ifdef S390X_DEBUG_DISAS_VERBOSE
26 # define LOG_DISAS(...) qemu_log(__VA_ARGS__)
28 # define LOG_DISAS(...) do { } while (0)
31 #include "qemu/osdep.h"
34 #include "disas/disas.h"
35 #include "exec/exec-all.h"
36 #include "tcg/tcg-op.h"
37 #include "tcg/tcg-op-gvec.h"
39 #include "qemu/host-utils.h"
40 #include "exec/cpu_ldst.h"
41 #include "exec/gen-icount.h"
42 #include "exec/helper-proto.h"
43 #include "exec/helper-gen.h"
45 #include "trace-tcg.h"
46 #include "exec/translator.h"
48 #include "qemu/atomic128.h"
51 /* Information that (most) every instruction needs to manipulate. */
52 typedef struct DisasContext DisasContext
;
53 typedef struct DisasInsn DisasInsn
;
54 typedef struct DisasFields DisasFields
;
57 * Define a structure to hold the decoded fields. We'll store each inside
58 * an array indexed by an enum. In order to conserve memory, we'll arrange
59 * for fields that do not exist at the same time to overlap, thus the "C"
60 * for compact. For checking purposes there is an "O" for original index
61 * as well that will be applied to availability bitmaps.
64 enum DisasFieldIndexO
{
93 enum DisasFieldIndexC
{
134 unsigned presentC
:16;
135 unsigned int presentO
;
139 struct DisasContext
{
140 DisasContextBase base
;
141 const DisasInsn
*insn
;
145 * During translate_one(), pc_tmp is used to determine the instruction
146 * to be executed after base.pc_next - e.g. next sequential instruction
147 * or a branch target.
155 /* Information carried about a condition to be evaluated. */
162 struct { TCGv_i64 a
, b
; } s64
;
163 struct { TCGv_i32 a
, b
; } s32
;
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
];
172 static void pc_to_link_info(TCGv_i64 out
, DisasContext
*s
, uint64_t pc
)
176 if (s
->base
.tb
->flags
& FLAG_MASK_32
) {
177 if (s
->base
.tb
->flags
& FLAG_MASK_64
) {
178 tcg_gen_movi_i64(out
, pc
);
183 assert(!(s
->base
.tb
->flags
& FLAG_MASK_64
));
184 tmp
= tcg_const_i64(pc
);
185 tcg_gen_deposit_i64(out
, out
, tmp
, 0, 32);
186 tcg_temp_free_i64(tmp
);
189 static TCGv_i64 psw_addr
;
190 static TCGv_i64 psw_mask
;
191 static TCGv_i64 gbea
;
193 static TCGv_i32 cc_op
;
194 static TCGv_i64 cc_src
;
195 static TCGv_i64 cc_dst
;
196 static TCGv_i64 cc_vr
;
198 static char cpu_reg_names
[16][4];
199 static TCGv_i64 regs
[16];
201 void s390x_translate_init(void)
205 psw_addr
= tcg_global_mem_new_i64(cpu_env
,
206 offsetof(CPUS390XState
, psw
.addr
),
208 psw_mask
= tcg_global_mem_new_i64(cpu_env
,
209 offsetof(CPUS390XState
, psw
.mask
),
211 gbea
= tcg_global_mem_new_i64(cpu_env
,
212 offsetof(CPUS390XState
, gbea
),
215 cc_op
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUS390XState
, cc_op
),
217 cc_src
= tcg_global_mem_new_i64(cpu_env
, offsetof(CPUS390XState
, cc_src
),
219 cc_dst
= tcg_global_mem_new_i64(cpu_env
, offsetof(CPUS390XState
, cc_dst
),
221 cc_vr
= tcg_global_mem_new_i64(cpu_env
, offsetof(CPUS390XState
, cc_vr
),
224 for (i
= 0; i
< 16; i
++) {
225 snprintf(cpu_reg_names
[i
], sizeof(cpu_reg_names
[0]), "r%d", i
);
226 regs
[i
] = tcg_global_mem_new(cpu_env
,
227 offsetof(CPUS390XState
, regs
[i
]),
232 static inline int vec_full_reg_offset(uint8_t reg
)
235 return offsetof(CPUS390XState
, vregs
[reg
][0]);
238 static inline int vec_reg_offset(uint8_t reg
, uint8_t enr
, MemOp es
)
240 /* Convert element size (es) - e.g. MO_8 - to bytes */
241 const uint8_t bytes
= 1 << es
;
242 int offs
= enr
* bytes
;
245 * vregs[n][0] is the lowest 8 byte and vregs[n][1] the highest 8 byte
246 * of the 16 byte vector, on both, little and big endian systems.
248 * Big Endian (target/possible host)
249 * B: [ 0][ 1][ 2][ 3][ 4][ 5][ 6][ 7] - [ 8][ 9][10][11][12][13][14][15]
250 * HW: [ 0][ 1][ 2][ 3] - [ 4][ 5][ 6][ 7]
251 * W: [ 0][ 1] - [ 2][ 3]
254 * Little Endian (possible host)
255 * B: [ 7][ 6][ 5][ 4][ 3][ 2][ 1][ 0] - [15][14][13][12][11][10][ 9][ 8]
256 * HW: [ 3][ 2][ 1][ 0] - [ 7][ 6][ 5][ 4]
257 * W: [ 1][ 0] - [ 3][ 2]
260 * For 16 byte elements, the two 8 byte halves will not form a host
261 * int128 if the host is little endian, since they're in the wrong order.
262 * Some operations (e.g. xor) do not care. For operations like addition,
263 * the two 8 byte elements have to be loaded separately. Let's force all
264 * 16 byte operations to handle it in a special way.
266 g_assert(es
<= MO_64
);
267 #ifndef HOST_WORDS_BIGENDIAN
270 return offs
+ vec_full_reg_offset(reg
);
273 static inline int freg64_offset(uint8_t reg
)
276 return vec_reg_offset(reg
, 0, MO_64
);
279 static inline int freg32_offset(uint8_t reg
)
282 return vec_reg_offset(reg
, 0, MO_32
);
285 static TCGv_i64
load_reg(int reg
)
287 TCGv_i64 r
= tcg_temp_new_i64();
288 tcg_gen_mov_i64(r
, regs
[reg
]);
292 static TCGv_i64
load_freg(int reg
)
294 TCGv_i64 r
= tcg_temp_new_i64();
296 tcg_gen_ld_i64(r
, cpu_env
, freg64_offset(reg
));
300 static TCGv_i64
load_freg32_i64(int reg
)
302 TCGv_i64 r
= tcg_temp_new_i64();
304 tcg_gen_ld32u_i64(r
, cpu_env
, freg32_offset(reg
));
308 static void store_reg(int reg
, TCGv_i64 v
)
310 tcg_gen_mov_i64(regs
[reg
], v
);
313 static void store_freg(int reg
, TCGv_i64 v
)
315 tcg_gen_st_i64(v
, cpu_env
, freg64_offset(reg
));
318 static void store_reg32_i64(int reg
, TCGv_i64 v
)
320 /* 32 bit register writes keep the upper half */
321 tcg_gen_deposit_i64(regs
[reg
], regs
[reg
], v
, 0, 32);
324 static void store_reg32h_i64(int reg
, TCGv_i64 v
)
326 tcg_gen_deposit_i64(regs
[reg
], regs
[reg
], v
, 32, 32);
329 static void store_freg32_i64(int reg
, TCGv_i64 v
)
331 tcg_gen_st32_i64(v
, cpu_env
, freg32_offset(reg
));
334 static void return_low128(TCGv_i64 dest
)
336 tcg_gen_ld_i64(dest
, cpu_env
, offsetof(CPUS390XState
, retxl
));
339 static void update_psw_addr(DisasContext
*s
)
342 tcg_gen_movi_i64(psw_addr
, s
->base
.pc_next
);
345 static void per_branch(DisasContext
*s
, bool to_next
)
347 #ifndef CONFIG_USER_ONLY
348 tcg_gen_movi_i64(gbea
, s
->base
.pc_next
);
350 if (s
->base
.tb
->flags
& FLAG_MASK_PER
) {
351 TCGv_i64 next_pc
= to_next
? tcg_const_i64(s
->pc_tmp
) : psw_addr
;
352 gen_helper_per_branch(cpu_env
, gbea
, next_pc
);
354 tcg_temp_free_i64(next_pc
);
360 static void per_branch_cond(DisasContext
*s
, TCGCond cond
,
361 TCGv_i64 arg1
, TCGv_i64 arg2
)
363 #ifndef CONFIG_USER_ONLY
364 if (s
->base
.tb
->flags
& FLAG_MASK_PER
) {
365 TCGLabel
*lab
= gen_new_label();
366 tcg_gen_brcond_i64(tcg_invert_cond(cond
), arg1
, arg2
, lab
);
368 tcg_gen_movi_i64(gbea
, s
->base
.pc_next
);
369 gen_helper_per_branch(cpu_env
, gbea
, psw_addr
);
373 TCGv_i64 pc
= tcg_const_i64(s
->base
.pc_next
);
374 tcg_gen_movcond_i64(cond
, gbea
, arg1
, arg2
, gbea
, pc
);
375 tcg_temp_free_i64(pc
);
380 static void per_breaking_event(DisasContext
*s
)
382 tcg_gen_movi_i64(gbea
, s
->base
.pc_next
);
385 static void update_cc_op(DisasContext
*s
)
387 if (s
->cc_op
!= CC_OP_DYNAMIC
&& s
->cc_op
!= CC_OP_STATIC
) {
388 tcg_gen_movi_i32(cc_op
, s
->cc_op
);
392 static inline uint64_t ld_code2(CPUS390XState
*env
, uint64_t pc
)
394 return (uint64_t)cpu_lduw_code(env
, pc
);
397 static inline uint64_t ld_code4(CPUS390XState
*env
, uint64_t pc
)
399 return (uint64_t)(uint32_t)cpu_ldl_code(env
, pc
);
402 static int get_mem_index(DisasContext
*s
)
404 #ifdef CONFIG_USER_ONLY
407 if (!(s
->base
.tb
->flags
& FLAG_MASK_DAT
)) {
411 switch (s
->base
.tb
->flags
& FLAG_MASK_ASC
) {
412 case PSW_ASC_PRIMARY
>> FLAG_MASK_PSW_SHIFT
:
413 return MMU_PRIMARY_IDX
;
414 case PSW_ASC_SECONDARY
>> FLAG_MASK_PSW_SHIFT
:
415 return MMU_SECONDARY_IDX
;
416 case PSW_ASC_HOME
>> FLAG_MASK_PSW_SHIFT
:
425 static void gen_exception(int excp
)
427 TCGv_i32 tmp
= tcg_const_i32(excp
);
428 gen_helper_exception(cpu_env
, tmp
);
429 tcg_temp_free_i32(tmp
);
432 static void gen_program_exception(DisasContext
*s
, int code
)
436 /* Remember what pgm exeption this was. */
437 tmp
= tcg_const_i32(code
);
438 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUS390XState
, int_pgm_code
));
439 tcg_temp_free_i32(tmp
);
441 tmp
= tcg_const_i32(s
->ilen
);
442 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUS390XState
, int_pgm_ilen
));
443 tcg_temp_free_i32(tmp
);
451 /* Trigger exception. */
452 gen_exception(EXCP_PGM
);
455 static inline void gen_illegal_opcode(DisasContext
*s
)
457 gen_program_exception(s
, PGM_OPERATION
);
460 static inline void gen_data_exception(uint8_t dxc
)
462 TCGv_i32 tmp
= tcg_const_i32(dxc
);
463 gen_helper_data_exception(cpu_env
, tmp
);
464 tcg_temp_free_i32(tmp
);
467 static inline void gen_trap(DisasContext
*s
)
469 /* Set DXC to 0xff */
470 gen_data_exception(0xff);
473 static void gen_addi_and_wrap_i64(DisasContext
*s
, TCGv_i64 dst
, TCGv_i64 src
,
476 tcg_gen_addi_i64(dst
, src
, imm
);
477 if (!(s
->base
.tb
->flags
& FLAG_MASK_64
)) {
478 if (s
->base
.tb
->flags
& FLAG_MASK_32
) {
479 tcg_gen_andi_i64(dst
, dst
, 0x7fffffff);
481 tcg_gen_andi_i64(dst
, dst
, 0x00ffffff);
486 static TCGv_i64
get_address(DisasContext
*s
, int x2
, int b2
, int d2
)
488 TCGv_i64 tmp
= tcg_temp_new_i64();
491 * Note that d2 is limited to 20 bits, signed. If we crop negative
492 * displacements early we create larger immedate addends.
495 tcg_gen_add_i64(tmp
, regs
[b2
], regs
[x2
]);
496 gen_addi_and_wrap_i64(s
, tmp
, tmp
, d2
);
498 gen_addi_and_wrap_i64(s
, tmp
, regs
[b2
], d2
);
500 gen_addi_and_wrap_i64(s
, tmp
, regs
[x2
], d2
);
501 } else if (!(s
->base
.tb
->flags
& FLAG_MASK_64
)) {
502 if (s
->base
.tb
->flags
& FLAG_MASK_32
) {
503 tcg_gen_movi_i64(tmp
, d2
& 0x7fffffff);
505 tcg_gen_movi_i64(tmp
, d2
& 0x00ffffff);
508 tcg_gen_movi_i64(tmp
, d2
);
514 static inline bool live_cc_data(DisasContext
*s
)
516 return (s
->cc_op
!= CC_OP_DYNAMIC
517 && s
->cc_op
!= CC_OP_STATIC
521 static inline void gen_op_movi_cc(DisasContext
*s
, uint32_t val
)
523 if (live_cc_data(s
)) {
524 tcg_gen_discard_i64(cc_src
);
525 tcg_gen_discard_i64(cc_dst
);
526 tcg_gen_discard_i64(cc_vr
);
528 s
->cc_op
= CC_OP_CONST0
+ val
;
531 static void gen_op_update1_cc_i64(DisasContext
*s
, enum cc_op op
, TCGv_i64 dst
)
533 if (live_cc_data(s
)) {
534 tcg_gen_discard_i64(cc_src
);
535 tcg_gen_discard_i64(cc_vr
);
537 tcg_gen_mov_i64(cc_dst
, dst
);
541 static void gen_op_update2_cc_i64(DisasContext
*s
, enum cc_op op
, TCGv_i64 src
,
544 if (live_cc_data(s
)) {
545 tcg_gen_discard_i64(cc_vr
);
547 tcg_gen_mov_i64(cc_src
, src
);
548 tcg_gen_mov_i64(cc_dst
, dst
);
552 static void gen_op_update3_cc_i64(DisasContext
*s
, enum cc_op op
, TCGv_i64 src
,
553 TCGv_i64 dst
, TCGv_i64 vr
)
555 tcg_gen_mov_i64(cc_src
, src
);
556 tcg_gen_mov_i64(cc_dst
, dst
);
557 tcg_gen_mov_i64(cc_vr
, vr
);
561 static void set_cc_nz_u64(DisasContext
*s
, TCGv_i64 val
)
563 gen_op_update1_cc_i64(s
, CC_OP_NZ
, val
);
566 static void gen_set_cc_nz_f32(DisasContext
*s
, TCGv_i64 val
)
568 gen_op_update1_cc_i64(s
, CC_OP_NZ_F32
, val
);
571 static void gen_set_cc_nz_f64(DisasContext
*s
, TCGv_i64 val
)
573 gen_op_update1_cc_i64(s
, CC_OP_NZ_F64
, val
);
576 static void gen_set_cc_nz_f128(DisasContext
*s
, TCGv_i64 vh
, TCGv_i64 vl
)
578 gen_op_update2_cc_i64(s
, CC_OP_NZ_F128
, vh
, vl
);
581 /* CC value is in env->cc_op */
582 static void set_cc_static(DisasContext
*s
)
584 if (live_cc_data(s
)) {
585 tcg_gen_discard_i64(cc_src
);
586 tcg_gen_discard_i64(cc_dst
);
587 tcg_gen_discard_i64(cc_vr
);
589 s
->cc_op
= CC_OP_STATIC
;
592 /* calculates cc into cc_op */
593 static void gen_op_calc_cc(DisasContext
*s
)
595 TCGv_i32 local_cc_op
= NULL
;
596 TCGv_i64 dummy
= NULL
;
600 dummy
= tcg_const_i64(0);
614 local_cc_op
= tcg_const_i32(s
->cc_op
);
630 /* s->cc_op is the cc value */
631 tcg_gen_movi_i32(cc_op
, s
->cc_op
- CC_OP_CONST0
);
634 /* env->cc_op already is the cc value */
650 gen_helper_calc_cc(cc_op
, cpu_env
, local_cc_op
, dummy
, cc_dst
, dummy
);
655 case CC_OP_LTUGTU_32
:
656 case CC_OP_LTUGTU_64
:
664 gen_helper_calc_cc(cc_op
, cpu_env
, local_cc_op
, cc_src
, cc_dst
, dummy
);
679 gen_helper_calc_cc(cc_op
, cpu_env
, local_cc_op
, cc_src
, cc_dst
, cc_vr
);
682 /* unknown operation - assume 3 arguments and cc_op in env */
683 gen_helper_calc_cc(cc_op
, cpu_env
, cc_op
, cc_src
, cc_dst
, cc_vr
);
690 tcg_temp_free_i32(local_cc_op
);
693 tcg_temp_free_i64(dummy
);
696 /* We now have cc in cc_op as constant */
700 static bool use_exit_tb(DisasContext
*s
)
702 return s
->base
.singlestep_enabled
||
703 (tb_cflags(s
->base
.tb
) & CF_LAST_IO
) ||
704 (s
->base
.tb
->flags
& FLAG_MASK_PER
);
707 static bool use_goto_tb(DisasContext
*s
, uint64_t dest
)
709 if (unlikely(use_exit_tb(s
))) {
712 #ifndef CONFIG_USER_ONLY
713 return (dest
& TARGET_PAGE_MASK
) == (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) ||
714 (dest
& TARGET_PAGE_MASK
) == (s
->base
.pc_next
& TARGET_PAGE_MASK
);
720 static void account_noninline_branch(DisasContext
*s
, int cc_op
)
722 #ifdef DEBUG_INLINE_BRANCHES
723 inline_branch_miss
[cc_op
]++;
727 static void account_inline_branch(DisasContext
*s
, int cc_op
)
729 #ifdef DEBUG_INLINE_BRANCHES
730 inline_branch_hit
[cc_op
]++;
734 /* Table of mask values to comparison codes, given a comparison as input.
735 For such, CC=3 should not be possible. */
736 static const TCGCond ltgt_cond
[16] = {
737 TCG_COND_NEVER
, TCG_COND_NEVER
, /* | | | x */
738 TCG_COND_GT
, TCG_COND_GT
, /* | | GT | x */
739 TCG_COND_LT
, TCG_COND_LT
, /* | LT | | x */
740 TCG_COND_NE
, TCG_COND_NE
, /* | LT | GT | x */
741 TCG_COND_EQ
, TCG_COND_EQ
, /* EQ | | | x */
742 TCG_COND_GE
, TCG_COND_GE
, /* EQ | | GT | x */
743 TCG_COND_LE
, TCG_COND_LE
, /* EQ | LT | | x */
744 TCG_COND_ALWAYS
, TCG_COND_ALWAYS
, /* EQ | LT | GT | x */
747 /* Table of mask values to comparison codes, given a logic op as input.
748 For such, only CC=0 and CC=1 should be possible. */
749 static const TCGCond nz_cond
[16] = {
750 TCG_COND_NEVER
, TCG_COND_NEVER
, /* | | x | x */
751 TCG_COND_NEVER
, TCG_COND_NEVER
,
752 TCG_COND_NE
, TCG_COND_NE
, /* | NE | x | x */
753 TCG_COND_NE
, TCG_COND_NE
,
754 TCG_COND_EQ
, TCG_COND_EQ
, /* EQ | | x | x */
755 TCG_COND_EQ
, TCG_COND_EQ
,
756 TCG_COND_ALWAYS
, TCG_COND_ALWAYS
, /* EQ | NE | x | x */
757 TCG_COND_ALWAYS
, TCG_COND_ALWAYS
,
760 /* Interpret MASK in terms of S->CC_OP, and fill in C with all the
761 details required to generate a TCG comparison. */
762 static void disas_jcc(DisasContext
*s
, DisasCompare
*c
, uint32_t mask
)
765 enum cc_op old_cc_op
= s
->cc_op
;
767 if (mask
== 15 || mask
== 0) {
768 c
->cond
= (mask
? TCG_COND_ALWAYS
: TCG_COND_NEVER
);
771 c
->g1
= c
->g2
= true;
776 /* Find the TCG condition for the mask + cc op. */
782 cond
= ltgt_cond
[mask
];
783 if (cond
== TCG_COND_NEVER
) {
786 account_inline_branch(s
, old_cc_op
);
789 case CC_OP_LTUGTU_32
:
790 case CC_OP_LTUGTU_64
:
791 cond
= tcg_unsigned_cond(ltgt_cond
[mask
]);
792 if (cond
== TCG_COND_NEVER
) {
795 account_inline_branch(s
, old_cc_op
);
799 cond
= nz_cond
[mask
];
800 if (cond
== TCG_COND_NEVER
) {
803 account_inline_branch(s
, old_cc_op
);
818 account_inline_branch(s
, old_cc_op
);
833 account_inline_branch(s
, old_cc_op
);
837 switch (mask
& 0xa) {
838 case 8: /* src == 0 -> no one bit found */
841 case 2: /* src != 0 -> one bit found */
847 account_inline_branch(s
, old_cc_op
);
853 case 8 | 2: /* vr == 0 */
856 case 4 | 1: /* vr != 0 */
859 case 8 | 4: /* no carry -> vr >= src */
862 case 2 | 1: /* carry -> vr < src */
868 account_inline_branch(s
, old_cc_op
);
873 /* Note that CC=0 is impossible; treat it as dont-care. */
875 case 2: /* zero -> op1 == op2 */
878 case 4 | 1: /* !zero -> op1 != op2 */
881 case 4: /* borrow (!carry) -> op1 < op2 */
884 case 2 | 1: /* !borrow (carry) -> op1 >= op2 */
890 account_inline_branch(s
, old_cc_op
);
895 /* Calculate cc value. */
900 /* Jump based on CC. We'll load up the real cond below;
901 the assignment here merely avoids a compiler warning. */
902 account_noninline_branch(s
, old_cc_op
);
903 old_cc_op
= CC_OP_STATIC
;
904 cond
= TCG_COND_NEVER
;
908 /* Load up the arguments of the comparison. */
910 c
->g1
= c
->g2
= false;
914 c
->u
.s32
.a
= tcg_temp_new_i32();
915 tcg_gen_extrl_i64_i32(c
->u
.s32
.a
, cc_dst
);
916 c
->u
.s32
.b
= tcg_const_i32(0);
919 case CC_OP_LTUGTU_32
:
922 c
->u
.s32
.a
= tcg_temp_new_i32();
923 tcg_gen_extrl_i64_i32(c
->u
.s32
.a
, cc_src
);
924 c
->u
.s32
.b
= tcg_temp_new_i32();
925 tcg_gen_extrl_i64_i32(c
->u
.s32
.b
, cc_dst
);
932 c
->u
.s64
.b
= tcg_const_i64(0);
936 case CC_OP_LTUGTU_64
:
940 c
->g1
= c
->g2
= true;
946 c
->u
.s64
.a
= tcg_temp_new_i64();
947 c
->u
.s64
.b
= tcg_const_i64(0);
948 tcg_gen_and_i64(c
->u
.s64
.a
, cc_src
, cc_dst
);
953 c
->u
.s32
.a
= tcg_temp_new_i32();
954 c
->u
.s32
.b
= tcg_temp_new_i32();
955 tcg_gen_extrl_i64_i32(c
->u
.s32
.a
, cc_vr
);
956 if (cond
== TCG_COND_EQ
|| cond
== TCG_COND_NE
) {
957 tcg_gen_movi_i32(c
->u
.s32
.b
, 0);
959 tcg_gen_extrl_i64_i32(c
->u
.s32
.b
, cc_src
);
966 if (cond
== TCG_COND_EQ
|| cond
== TCG_COND_NE
) {
967 c
->u
.s64
.b
= tcg_const_i64(0);
979 case 0x8 | 0x4 | 0x2: /* cc != 3 */
981 c
->u
.s32
.b
= tcg_const_i32(3);
983 case 0x8 | 0x4 | 0x1: /* cc != 2 */
985 c
->u
.s32
.b
= tcg_const_i32(2);
987 case 0x8 | 0x2 | 0x1: /* cc != 1 */
989 c
->u
.s32
.b
= tcg_const_i32(1);
991 case 0x8 | 0x2: /* cc == 0 || cc == 2 => (cc & 1) == 0 */
994 c
->u
.s32
.a
= tcg_temp_new_i32();
995 c
->u
.s32
.b
= tcg_const_i32(0);
996 tcg_gen_andi_i32(c
->u
.s32
.a
, cc_op
, 1);
998 case 0x8 | 0x4: /* cc < 2 */
1000 c
->u
.s32
.b
= tcg_const_i32(2);
1002 case 0x8: /* cc == 0 */
1004 c
->u
.s32
.b
= tcg_const_i32(0);
1006 case 0x4 | 0x2 | 0x1: /* cc != 0 */
1008 c
->u
.s32
.b
= tcg_const_i32(0);
1010 case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */
1013 c
->u
.s32
.a
= tcg_temp_new_i32();
1014 c
->u
.s32
.b
= tcg_const_i32(0);
1015 tcg_gen_andi_i32(c
->u
.s32
.a
, cc_op
, 1);
1017 case 0x4: /* cc == 1 */
1019 c
->u
.s32
.b
= tcg_const_i32(1);
1021 case 0x2 | 0x1: /* cc > 1 */
1022 cond
= TCG_COND_GTU
;
1023 c
->u
.s32
.b
= tcg_const_i32(1);
1025 case 0x2: /* cc == 2 */
1027 c
->u
.s32
.b
= tcg_const_i32(2);
1029 case 0x1: /* cc == 3 */
1031 c
->u
.s32
.b
= tcg_const_i32(3);
1034 /* CC is masked by something else: (8 >> cc) & mask. */
1037 c
->u
.s32
.a
= tcg_const_i32(8);
1038 c
->u
.s32
.b
= tcg_const_i32(0);
1039 tcg_gen_shr_i32(c
->u
.s32
.a
, c
->u
.s32
.a
, cc_op
);
1040 tcg_gen_andi_i32(c
->u
.s32
.a
, c
->u
.s32
.a
, mask
);
1051 static void free_compare(DisasCompare
*c
)
1055 tcg_temp_free_i64(c
->u
.s64
.a
);
1057 tcg_temp_free_i32(c
->u
.s32
.a
);
1062 tcg_temp_free_i64(c
->u
.s64
.b
);
1064 tcg_temp_free_i32(c
->u
.s32
.b
);
1069 /* ====================================================================== */
1070 /* Define the insn format enumeration. */
1071 #define F0(N) FMT_##N,
1072 #define F1(N, X1) F0(N)
1073 #define F2(N, X1, X2) F0(N)
1074 #define F3(N, X1, X2, X3) F0(N)
1075 #define F4(N, X1, X2, X3, X4) F0(N)
1076 #define F5(N, X1, X2, X3, X4, X5) F0(N)
1077 #define F6(N, X1, X2, X3, X4, X5, X6) F0(N)
1080 #include "insn-format.def"
1091 /* This is the way fields are to be accessed out of DisasFields. */
1092 #define have_field(S, F) have_field1((S), FLD_O_##F)
1093 #define get_field(S, F) get_field1((S), FLD_O_##F, FLD_C_##F)
1095 static bool have_field1(const DisasContext
*s
, enum DisasFieldIndexO c
)
1097 return (s
->fields
.presentO
>> c
) & 1;
1100 static int get_field1(const DisasContext
*s
, enum DisasFieldIndexO o
,
1101 enum DisasFieldIndexC c
)
1103 assert(have_field1(s
, o
));
1104 return s
->fields
.c
[c
];
1107 /* Describe the layout of each field in each format. */
1108 typedef struct DisasField
{
1110 unsigned int size
:8;
1111 unsigned int type
:2;
1112 unsigned int indexC
:6;
1113 enum DisasFieldIndexO indexO
:8;
1116 typedef struct DisasFormatInfo
{
1117 DisasField op
[NUM_C_FIELD
];
1120 #define R(N, B) { B, 4, 0, FLD_C_r##N, FLD_O_r##N }
1121 #define M(N, B) { B, 4, 0, FLD_C_m##N, FLD_O_m##N }
1122 #define V(N, B) { B, 4, 3, FLD_C_v##N, FLD_O_v##N }
1123 #define BD(N, BB, BD) { BB, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
1124 { BD, 12, 0, FLD_C_d##N, FLD_O_d##N }
1125 #define BXD(N) { 16, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
1126 { 12, 4, 0, FLD_C_x##N, FLD_O_x##N }, \
1127 { 20, 12, 0, FLD_C_d##N, FLD_O_d##N }
1128 #define BDL(N) { 16, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
1129 { 20, 20, 2, FLD_C_d##N, FLD_O_d##N }
1130 #define BXDL(N) { 16, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
1131 { 12, 4, 0, FLD_C_x##N, FLD_O_x##N }, \
1132 { 20, 20, 2, FLD_C_d##N, FLD_O_d##N }
1133 #define I(N, B, S) { B, S, 1, FLD_C_i##N, FLD_O_i##N }
1134 #define L(N, B, S) { B, S, 0, FLD_C_l##N, FLD_O_l##N }
1136 #define F0(N) { { } },
1137 #define F1(N, X1) { { X1 } },
1138 #define F2(N, X1, X2) { { X1, X2 } },
1139 #define F3(N, X1, X2, X3) { { X1, X2, X3 } },
1140 #define F4(N, X1, X2, X3, X4) { { X1, X2, X3, X4 } },
1141 #define F5(N, X1, X2, X3, X4, X5) { { X1, X2, X3, X4, X5 } },
1142 #define F6(N, X1, X2, X3, X4, X5, X6) { { X1, X2, X3, X4, X5, X6 } },
1144 static const DisasFormatInfo format_info
[] = {
1145 #include "insn-format.def"
1165 /* Generally, we'll extract operands into this structures, operate upon
1166 them, and store them back. See the "in1", "in2", "prep", "wout" sets
1167 of routines below for more details. */
1169 bool g_out
, g_out2
, g_in1
, g_in2
;
1170 TCGv_i64 out
, out2
, in1
, in2
;
1174 /* Instructions can place constraints on their operands, raising specification
1175 exceptions if they are violated. To make this easy to automate, each "in1",
1176 "in2", "prep", "wout" helper will have a SPEC_<name> define that equals one
1177 of the following, or 0. To make this easy to document, we'll put the
1178 SPEC_<name> defines next to <name>. */
1180 #define SPEC_r1_even 1
1181 #define SPEC_r2_even 2
1182 #define SPEC_r3_even 4
1183 #define SPEC_r1_f128 8
1184 #define SPEC_r2_f128 16
1186 /* Return values from translate_one, indicating the state of the TB. */
1188 /* We are not using a goto_tb (for whatever reason), but have updated
1189 the PC (for whatever reason), so there's no need to do it again on
1191 #define DISAS_PC_UPDATED DISAS_TARGET_0
1193 /* We have emitted one or more goto_tb. No fixup required. */
1194 #define DISAS_GOTO_TB DISAS_TARGET_1
1196 /* We have updated the PC and CC values. */
1197 #define DISAS_PC_CC_UPDATED DISAS_TARGET_2
1199 /* We are exiting the TB, but have neither emitted a goto_tb, nor
1200 updated the PC for the next instruction to be executed. */
1201 #define DISAS_PC_STALE DISAS_TARGET_3
1203 /* We are exiting the TB to the main loop. */
1204 #define DISAS_PC_STALE_NOCHAIN DISAS_TARGET_4
1207 /* Instruction flags */
1208 #define IF_AFP1 0x0001 /* r1 is a fp reg for HFP/FPS instructions */
1209 #define IF_AFP2 0x0002 /* r2 is a fp reg for HFP/FPS instructions */
1210 #define IF_AFP3 0x0004 /* r3 is a fp reg for HFP/FPS instructions */
1211 #define IF_BFP 0x0008 /* binary floating point instruction */
1212 #define IF_DFP 0x0010 /* decimal floating point instruction */
1213 #define IF_PRIV 0x0020 /* privileged instruction */
1214 #define IF_VEC 0x0040 /* vector instruction */
1225 /* Pre-process arguments before HELP_OP. */
1226 void (*help_in1
)(DisasContext
*, DisasOps
*);
1227 void (*help_in2
)(DisasContext
*, DisasOps
*);
1228 void (*help_prep
)(DisasContext
*, DisasOps
*);
1231 * Post-process output after HELP_OP.
1232 * Note that these are not called if HELP_OP returns DISAS_NORETURN.
1234 void (*help_wout
)(DisasContext
*, DisasOps
*);
1235 void (*help_cout
)(DisasContext
*, DisasOps
*);
1237 /* Implement the operation itself. */
1238 DisasJumpType (*help_op
)(DisasContext
*, DisasOps
*);
1243 /* ====================================================================== */
1244 /* Miscellaneous helpers, used by several operations. */
1246 static void help_l2_shift(DisasContext
*s
, DisasOps
*o
, int mask
)
1248 int b2
= get_field(s
, b2
);
1249 int d2
= get_field(s
, d2
);
1252 o
->in2
= tcg_const_i64(d2
& mask
);
1254 o
->in2
= get_address(s
, 0, b2
, d2
);
1255 tcg_gen_andi_i64(o
->in2
, o
->in2
, mask
);
1259 static DisasJumpType
help_goto_direct(DisasContext
*s
, uint64_t dest
)
1261 if (dest
== s
->pc_tmp
) {
1262 per_branch(s
, true);
1265 if (use_goto_tb(s
, dest
)) {
1267 per_breaking_event(s
);
1269 tcg_gen_movi_i64(psw_addr
, dest
);
1270 tcg_gen_exit_tb(s
->base
.tb
, 0);
1271 return DISAS_GOTO_TB
;
1273 tcg_gen_movi_i64(psw_addr
, dest
);
1274 per_branch(s
, false);
1275 return DISAS_PC_UPDATED
;
1279 static DisasJumpType
help_branch(DisasContext
*s
, DisasCompare
*c
,
1280 bool is_imm
, int imm
, TCGv_i64 cdest
)
1283 uint64_t dest
= s
->base
.pc_next
+ 2 * imm
;
1286 /* Take care of the special cases first. */
1287 if (c
->cond
== TCG_COND_NEVER
) {
1292 if (dest
== s
->pc_tmp
) {
1293 /* Branch to next. */
1294 per_branch(s
, true);
1298 if (c
->cond
== TCG_COND_ALWAYS
) {
1299 ret
= help_goto_direct(s
, dest
);
1304 /* E.g. bcr %r0 -> no branch. */
1308 if (c
->cond
== TCG_COND_ALWAYS
) {
1309 tcg_gen_mov_i64(psw_addr
, cdest
);
1310 per_branch(s
, false);
1311 ret
= DISAS_PC_UPDATED
;
1316 if (use_goto_tb(s
, s
->pc_tmp
)) {
1317 if (is_imm
&& use_goto_tb(s
, dest
)) {
1318 /* Both exits can use goto_tb. */
1321 lab
= gen_new_label();
1323 tcg_gen_brcond_i64(c
->cond
, c
->u
.s64
.a
, c
->u
.s64
.b
, lab
);
1325 tcg_gen_brcond_i32(c
->cond
, c
->u
.s32
.a
, c
->u
.s32
.b
, lab
);
1328 /* Branch not taken. */
1330 tcg_gen_movi_i64(psw_addr
, s
->pc_tmp
);
1331 tcg_gen_exit_tb(s
->base
.tb
, 0);
1335 per_breaking_event(s
);
1337 tcg_gen_movi_i64(psw_addr
, dest
);
1338 tcg_gen_exit_tb(s
->base
.tb
, 1);
1340 ret
= DISAS_GOTO_TB
;
1342 /* Fallthru can use goto_tb, but taken branch cannot. */
1343 /* Store taken branch destination before the brcond. This
1344 avoids having to allocate a new local temp to hold it.
1345 We'll overwrite this in the not taken case anyway. */
1347 tcg_gen_mov_i64(psw_addr
, cdest
);
1350 lab
= gen_new_label();
1352 tcg_gen_brcond_i64(c
->cond
, c
->u
.s64
.a
, c
->u
.s64
.b
, lab
);
1354 tcg_gen_brcond_i32(c
->cond
, c
->u
.s32
.a
, c
->u
.s32
.b
, lab
);
1357 /* Branch not taken. */
1360 tcg_gen_movi_i64(psw_addr
, s
->pc_tmp
);
1361 tcg_gen_exit_tb(s
->base
.tb
, 0);
1365 tcg_gen_movi_i64(psw_addr
, dest
);
1367 per_breaking_event(s
);
1368 ret
= DISAS_PC_UPDATED
;
1371 /* Fallthru cannot use goto_tb. This by itself is vanishingly rare.
1372 Most commonly we're single-stepping or some other condition that
1373 disables all use of goto_tb. Just update the PC and exit. */
1375 TCGv_i64 next
= tcg_const_i64(s
->pc_tmp
);
1377 cdest
= tcg_const_i64(dest
);
1381 tcg_gen_movcond_i64(c
->cond
, psw_addr
, c
->u
.s64
.a
, c
->u
.s64
.b
,
1383 per_branch_cond(s
, c
->cond
, c
->u
.s64
.a
, c
->u
.s64
.b
);
1385 TCGv_i32 t0
= tcg_temp_new_i32();
1386 TCGv_i64 t1
= tcg_temp_new_i64();
1387 TCGv_i64 z
= tcg_const_i64(0);
1388 tcg_gen_setcond_i32(c
->cond
, t0
, c
->u
.s32
.a
, c
->u
.s32
.b
);
1389 tcg_gen_extu_i32_i64(t1
, t0
);
1390 tcg_temp_free_i32(t0
);
1391 tcg_gen_movcond_i64(TCG_COND_NE
, psw_addr
, t1
, z
, cdest
, next
);
1392 per_branch_cond(s
, TCG_COND_NE
, t1
, z
);
1393 tcg_temp_free_i64(t1
);
1394 tcg_temp_free_i64(z
);
1398 tcg_temp_free_i64(cdest
);
1400 tcg_temp_free_i64(next
);
1402 ret
= DISAS_PC_UPDATED
;
1410 /* ====================================================================== */
1411 /* The operations. These perform the bulk of the work for any insn,
1412 usually after the operands have been loaded and output initialized. */
1414 static DisasJumpType
op_abs(DisasContext
*s
, DisasOps
*o
)
1416 tcg_gen_abs_i64(o
->out
, o
->in2
);
1420 static DisasJumpType
op_absf32(DisasContext
*s
, DisasOps
*o
)
1422 tcg_gen_andi_i64(o
->out
, o
->in2
, 0x7fffffffull
);
1426 static DisasJumpType
op_absf64(DisasContext
*s
, DisasOps
*o
)
1428 tcg_gen_andi_i64(o
->out
, o
->in2
, 0x7fffffffffffffffull
);
1432 static DisasJumpType
op_absf128(DisasContext
*s
, DisasOps
*o
)
1434 tcg_gen_andi_i64(o
->out
, o
->in1
, 0x7fffffffffffffffull
);
1435 tcg_gen_mov_i64(o
->out2
, o
->in2
);
1439 static DisasJumpType
op_add(DisasContext
*s
, DisasOps
*o
)
1441 tcg_gen_add_i64(o
->out
, o
->in1
, o
->in2
);
1445 static DisasJumpType
op_addc(DisasContext
*s
, DisasOps
*o
)
1450 tcg_gen_add_i64(o
->out
, o
->in1
, o
->in2
);
1452 /* The carry flag is the msb of CC, therefore the branch mask that would
1453 create that comparison is 3. Feeding the generated comparison to
1454 setcond produces the carry flag that we desire. */
1455 disas_jcc(s
, &cmp
, 3);
1456 carry
= tcg_temp_new_i64();
1458 tcg_gen_setcond_i64(cmp
.cond
, carry
, cmp
.u
.s64
.a
, cmp
.u
.s64
.b
);
1460 TCGv_i32 t
= tcg_temp_new_i32();
1461 tcg_gen_setcond_i32(cmp
.cond
, t
, cmp
.u
.s32
.a
, cmp
.u
.s32
.b
);
1462 tcg_gen_extu_i32_i64(carry
, t
);
1463 tcg_temp_free_i32(t
);
1467 tcg_gen_add_i64(o
->out
, o
->out
, carry
);
1468 tcg_temp_free_i64(carry
);
1472 static DisasJumpType
op_asi(DisasContext
*s
, DisasOps
*o
)
1474 o
->in1
= tcg_temp_new_i64();
1476 if (!s390_has_feat(S390_FEAT_STFLE_45
)) {
1477 tcg_gen_qemu_ld_tl(o
->in1
, o
->addr1
, get_mem_index(s
), s
->insn
->data
);
1479 /* Perform the atomic addition in memory. */
1480 tcg_gen_atomic_fetch_add_i64(o
->in1
, o
->addr1
, o
->in2
, get_mem_index(s
),
1484 /* Recompute also for atomic case: needed for setting CC. */
1485 tcg_gen_add_i64(o
->out
, o
->in1
, o
->in2
);
1487 if (!s390_has_feat(S390_FEAT_STFLE_45
)) {
1488 tcg_gen_qemu_st_tl(o
->out
, o
->addr1
, get_mem_index(s
), s
->insn
->data
);
1493 static DisasJumpType
op_aeb(DisasContext
*s
, DisasOps
*o
)
1495 gen_helper_aeb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
1499 static DisasJumpType
op_adb(DisasContext
*s
, DisasOps
*o
)
1501 gen_helper_adb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
1505 static DisasJumpType
op_axb(DisasContext
*s
, DisasOps
*o
)
1507 gen_helper_axb(o
->out
, cpu_env
, o
->out
, o
->out2
, o
->in1
, o
->in2
);
1508 return_low128(o
->out2
);
1512 static DisasJumpType
op_and(DisasContext
*s
, DisasOps
*o
)
1514 tcg_gen_and_i64(o
->out
, o
->in1
, o
->in2
);
1518 static DisasJumpType
op_andi(DisasContext
*s
, DisasOps
*o
)
1520 int shift
= s
->insn
->data
& 0xff;
1521 int size
= s
->insn
->data
>> 8;
1522 uint64_t mask
= ((1ull << size
) - 1) << shift
;
1525 tcg_gen_shli_i64(o
->in2
, o
->in2
, shift
);
1526 tcg_gen_ori_i64(o
->in2
, o
->in2
, ~mask
);
1527 tcg_gen_and_i64(o
->out
, o
->in1
, o
->in2
);
1529 /* Produce the CC from only the bits manipulated. */
1530 tcg_gen_andi_i64(cc_dst
, o
->out
, mask
);
1531 set_cc_nz_u64(s
, cc_dst
);
1535 static DisasJumpType
op_ni(DisasContext
*s
, DisasOps
*o
)
1537 o
->in1
= tcg_temp_new_i64();
1539 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2
)) {
1540 tcg_gen_qemu_ld_tl(o
->in1
, o
->addr1
, get_mem_index(s
), s
->insn
->data
);
1542 /* Perform the atomic operation in memory. */
1543 tcg_gen_atomic_fetch_and_i64(o
->in1
, o
->addr1
, o
->in2
, get_mem_index(s
),
1547 /* Recompute also for atomic case: needed for setting CC. */
1548 tcg_gen_and_i64(o
->out
, o
->in1
, o
->in2
);
1550 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2
)) {
1551 tcg_gen_qemu_st_tl(o
->out
, o
->addr1
, get_mem_index(s
), s
->insn
->data
);
1556 static DisasJumpType
op_bas(DisasContext
*s
, DisasOps
*o
)
1558 pc_to_link_info(o
->out
, s
, s
->pc_tmp
);
1560 tcg_gen_mov_i64(psw_addr
, o
->in2
);
1561 per_branch(s
, false);
1562 return DISAS_PC_UPDATED
;
1568 static void save_link_info(DisasContext
*s
, DisasOps
*o
)
1572 if (s
->base
.tb
->flags
& (FLAG_MASK_32
| FLAG_MASK_64
)) {
1573 pc_to_link_info(o
->out
, s
, s
->pc_tmp
);
1577 tcg_gen_andi_i64(o
->out
, o
->out
, 0xffffffff00000000ull
);
1578 tcg_gen_ori_i64(o
->out
, o
->out
, ((s
->ilen
/ 2) << 30) | s
->pc_tmp
);
1579 t
= tcg_temp_new_i64();
1580 tcg_gen_shri_i64(t
, psw_mask
, 16);
1581 tcg_gen_andi_i64(t
, t
, 0x0f000000);
1582 tcg_gen_or_i64(o
->out
, o
->out
, t
);
1583 tcg_gen_extu_i32_i64(t
, cc_op
);
1584 tcg_gen_shli_i64(t
, t
, 28);
1585 tcg_gen_or_i64(o
->out
, o
->out
, t
);
1586 tcg_temp_free_i64(t
);
1589 static DisasJumpType
op_bal(DisasContext
*s
, DisasOps
*o
)
1591 save_link_info(s
, o
);
1593 tcg_gen_mov_i64(psw_addr
, o
->in2
);
1594 per_branch(s
, false);
1595 return DISAS_PC_UPDATED
;
1601 static DisasJumpType
op_basi(DisasContext
*s
, DisasOps
*o
)
1603 pc_to_link_info(o
->out
, s
, s
->pc_tmp
);
1604 return help_goto_direct(s
, s
->base
.pc_next
+ 2 * get_field(s
, i2
));
1607 static DisasJumpType
op_bc(DisasContext
*s
, DisasOps
*o
)
1609 int m1
= get_field(s
, m1
);
1610 bool is_imm
= have_field(s
, i2
);
1611 int imm
= is_imm
? get_field(s
, i2
) : 0;
1614 /* BCR with R2 = 0 causes no branching */
1615 if (have_field(s
, r2
) && get_field(s
, r2
) == 0) {
1617 /* Perform serialization */
1618 /* FIXME: check for fast-BCR-serialization facility */
1619 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
1622 /* Perform serialization */
1623 /* FIXME: perform checkpoint-synchronisation */
1624 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
1629 disas_jcc(s
, &c
, m1
);
1630 return help_branch(s
, &c
, is_imm
, imm
, o
->in2
);
1633 static DisasJumpType
op_bct32(DisasContext
*s
, DisasOps
*o
)
1635 int r1
= get_field(s
, r1
);
1636 bool is_imm
= have_field(s
, i2
);
1637 int imm
= is_imm
? get_field(s
, i2
) : 0;
1641 c
.cond
= TCG_COND_NE
;
1646 t
= tcg_temp_new_i64();
1647 tcg_gen_subi_i64(t
, regs
[r1
], 1);
1648 store_reg32_i64(r1
, t
);
1649 c
.u
.s32
.a
= tcg_temp_new_i32();
1650 c
.u
.s32
.b
= tcg_const_i32(0);
1651 tcg_gen_extrl_i64_i32(c
.u
.s32
.a
, t
);
1652 tcg_temp_free_i64(t
);
1654 return help_branch(s
, &c
, is_imm
, imm
, o
->in2
);
1657 static DisasJumpType
op_bcth(DisasContext
*s
, DisasOps
*o
)
1659 int r1
= get_field(s
, r1
);
1660 int imm
= get_field(s
, i2
);
1664 c
.cond
= TCG_COND_NE
;
1669 t
= tcg_temp_new_i64();
1670 tcg_gen_shri_i64(t
, regs
[r1
], 32);
1671 tcg_gen_subi_i64(t
, t
, 1);
1672 store_reg32h_i64(r1
, t
);
1673 c
.u
.s32
.a
= tcg_temp_new_i32();
1674 c
.u
.s32
.b
= tcg_const_i32(0);
1675 tcg_gen_extrl_i64_i32(c
.u
.s32
.a
, t
);
1676 tcg_temp_free_i64(t
);
1678 return help_branch(s
, &c
, 1, imm
, o
->in2
);
1681 static DisasJumpType
op_bct64(DisasContext
*s
, DisasOps
*o
)
1683 int r1
= get_field(s
, r1
);
1684 bool is_imm
= have_field(s
, i2
);
1685 int imm
= is_imm
? get_field(s
, i2
) : 0;
1688 c
.cond
= TCG_COND_NE
;
1693 tcg_gen_subi_i64(regs
[r1
], regs
[r1
], 1);
1694 c
.u
.s64
.a
= regs
[r1
];
1695 c
.u
.s64
.b
= tcg_const_i64(0);
1697 return help_branch(s
, &c
, is_imm
, imm
, o
->in2
);
1700 static DisasJumpType
op_bx32(DisasContext
*s
, DisasOps
*o
)
1702 int r1
= get_field(s
, r1
);
1703 int r3
= get_field(s
, r3
);
1704 bool is_imm
= have_field(s
, i2
);
1705 int imm
= is_imm
? get_field(s
, i2
) : 0;
1709 c
.cond
= (s
->insn
->data
? TCG_COND_LE
: TCG_COND_GT
);
1714 t
= tcg_temp_new_i64();
1715 tcg_gen_add_i64(t
, regs
[r1
], regs
[r3
]);
1716 c
.u
.s32
.a
= tcg_temp_new_i32();
1717 c
.u
.s32
.b
= tcg_temp_new_i32();
1718 tcg_gen_extrl_i64_i32(c
.u
.s32
.a
, t
);
1719 tcg_gen_extrl_i64_i32(c
.u
.s32
.b
, regs
[r3
| 1]);
1720 store_reg32_i64(r1
, t
);
1721 tcg_temp_free_i64(t
);
1723 return help_branch(s
, &c
, is_imm
, imm
, o
->in2
);
1726 static DisasJumpType
op_bx64(DisasContext
*s
, DisasOps
*o
)
1728 int r1
= get_field(s
, r1
);
1729 int r3
= get_field(s
, r3
);
1730 bool is_imm
= have_field(s
, i2
);
1731 int imm
= is_imm
? get_field(s
, i2
) : 0;
1734 c
.cond
= (s
->insn
->data
? TCG_COND_LE
: TCG_COND_GT
);
1737 if (r1
== (r3
| 1)) {
1738 c
.u
.s64
.b
= load_reg(r3
| 1);
1741 c
.u
.s64
.b
= regs
[r3
| 1];
1745 tcg_gen_add_i64(regs
[r1
], regs
[r1
], regs
[r3
]);
1746 c
.u
.s64
.a
= regs
[r1
];
1749 return help_branch(s
, &c
, is_imm
, imm
, o
->in2
);
1752 static DisasJumpType
op_cj(DisasContext
*s
, DisasOps
*o
)
1754 int imm
, m3
= get_field(s
, m3
);
1758 c
.cond
= ltgt_cond
[m3
];
1759 if (s
->insn
->data
) {
1760 c
.cond
= tcg_unsigned_cond(c
.cond
);
1762 c
.is_64
= c
.g1
= c
.g2
= true;
1766 is_imm
= have_field(s
, i4
);
1768 imm
= get_field(s
, i4
);
1771 o
->out
= get_address(s
, 0, get_field(s
, b4
),
1775 return help_branch(s
, &c
, is_imm
, imm
, o
->out
);
1778 static DisasJumpType
op_ceb(DisasContext
*s
, DisasOps
*o
)
1780 gen_helper_ceb(cc_op
, cpu_env
, o
->in1
, o
->in2
);
1785 static DisasJumpType
op_cdb(DisasContext
*s
, DisasOps
*o
)
1787 gen_helper_cdb(cc_op
, cpu_env
, o
->in1
, o
->in2
);
1792 static DisasJumpType
op_cxb(DisasContext
*s
, DisasOps
*o
)
1794 gen_helper_cxb(cc_op
, cpu_env
, o
->out
, o
->out2
, o
->in1
, o
->in2
);
1799 static TCGv_i32
fpinst_extract_m34(DisasContext
*s
, bool m3_with_fpe
,
1802 const bool fpe
= s390_has_feat(S390_FEAT_FLOATING_POINT_EXT
);
1803 uint8_t m3
= get_field(s
, m3
);
1804 uint8_t m4
= get_field(s
, m4
);
1806 /* m3 field was introduced with FPE */
1807 if (!fpe
&& m3_with_fpe
) {
1810 /* m4 field was introduced with FPE */
1811 if (!fpe
&& m4_with_fpe
) {
1815 /* Check for valid rounding modes. Mode 3 was introduced later. */
1816 if (m3
== 2 || m3
> 7 || (!fpe
&& m3
== 3)) {
1817 gen_program_exception(s
, PGM_SPECIFICATION
);
1821 return tcg_const_i32(deposit32(m3
, 4, 4, m4
));
1824 static DisasJumpType
op_cfeb(DisasContext
*s
, DisasOps
*o
)
1826 TCGv_i32 m34
= fpinst_extract_m34(s
, false, true);
1829 return DISAS_NORETURN
;
1831 gen_helper_cfeb(o
->out
, cpu_env
, o
->in2
, m34
);
1832 tcg_temp_free_i32(m34
);
1833 gen_set_cc_nz_f32(s
, o
->in2
);
1837 static DisasJumpType
op_cfdb(DisasContext
*s
, DisasOps
*o
)
1839 TCGv_i32 m34
= fpinst_extract_m34(s
, false, true);
1842 return DISAS_NORETURN
;
1844 gen_helper_cfdb(o
->out
, cpu_env
, o
->in2
, m34
);
1845 tcg_temp_free_i32(m34
);
1846 gen_set_cc_nz_f64(s
, o
->in2
);
1850 static DisasJumpType
op_cfxb(DisasContext
*s
, DisasOps
*o
)
1852 TCGv_i32 m34
= fpinst_extract_m34(s
, false, true);
1855 return DISAS_NORETURN
;
1857 gen_helper_cfxb(o
->out
, cpu_env
, o
->in1
, o
->in2
, m34
);
1858 tcg_temp_free_i32(m34
);
1859 gen_set_cc_nz_f128(s
, o
->in1
, o
->in2
);
1863 static DisasJumpType
op_cgeb(DisasContext
*s
, DisasOps
*o
)
1865 TCGv_i32 m34
= fpinst_extract_m34(s
, false, true);
1868 return DISAS_NORETURN
;
1870 gen_helper_cgeb(o
->out
, cpu_env
, o
->in2
, m34
);
1871 tcg_temp_free_i32(m34
);
1872 gen_set_cc_nz_f32(s
, o
->in2
);
1876 static DisasJumpType
op_cgdb(DisasContext
*s
, DisasOps
*o
)
1878 TCGv_i32 m34
= fpinst_extract_m34(s
, false, true);
1881 return DISAS_NORETURN
;
1883 gen_helper_cgdb(o
->out
, cpu_env
, o
->in2
, m34
);
1884 tcg_temp_free_i32(m34
);
1885 gen_set_cc_nz_f64(s
, o
->in2
);
1889 static DisasJumpType
op_cgxb(DisasContext
*s
, DisasOps
*o
)
1891 TCGv_i32 m34
= fpinst_extract_m34(s
, false, true);
1894 return DISAS_NORETURN
;
1896 gen_helper_cgxb(o
->out
, cpu_env
, o
->in1
, o
->in2
, m34
);
1897 tcg_temp_free_i32(m34
);
1898 gen_set_cc_nz_f128(s
, o
->in1
, o
->in2
);
1902 static DisasJumpType
op_clfeb(DisasContext
*s
, DisasOps
*o
)
1904 TCGv_i32 m34
= fpinst_extract_m34(s
, false, false);
1907 return DISAS_NORETURN
;
1909 gen_helper_clfeb(o
->out
, cpu_env
, o
->in2
, m34
);
1910 tcg_temp_free_i32(m34
);
1911 gen_set_cc_nz_f32(s
, o
->in2
);
1915 static DisasJumpType
op_clfdb(DisasContext
*s
, DisasOps
*o
)
1917 TCGv_i32 m34
= fpinst_extract_m34(s
, false, false);
1920 return DISAS_NORETURN
;
1922 gen_helper_clfdb(o
->out
, cpu_env
, o
->in2
, m34
);
1923 tcg_temp_free_i32(m34
);
1924 gen_set_cc_nz_f64(s
, o
->in2
);
1928 static DisasJumpType
op_clfxb(DisasContext
*s
, DisasOps
*o
)
1930 TCGv_i32 m34
= fpinst_extract_m34(s
, false, false);
1933 return DISAS_NORETURN
;
1935 gen_helper_clfxb(o
->out
, cpu_env
, o
->in1
, o
->in2
, m34
);
1936 tcg_temp_free_i32(m34
);
1937 gen_set_cc_nz_f128(s
, o
->in1
, o
->in2
);
1941 static DisasJumpType
op_clgeb(DisasContext
*s
, DisasOps
*o
)
1943 TCGv_i32 m34
= fpinst_extract_m34(s
, false, false);
1946 return DISAS_NORETURN
;
1948 gen_helper_clgeb(o
->out
, cpu_env
, o
->in2
, m34
);
1949 tcg_temp_free_i32(m34
);
1950 gen_set_cc_nz_f32(s
, o
->in2
);
1954 static DisasJumpType
op_clgdb(DisasContext
*s
, DisasOps
*o
)
1956 TCGv_i32 m34
= fpinst_extract_m34(s
, false, false);
1959 return DISAS_NORETURN
;
1961 gen_helper_clgdb(o
->out
, cpu_env
, o
->in2
, m34
);
1962 tcg_temp_free_i32(m34
);
1963 gen_set_cc_nz_f64(s
, o
->in2
);
1967 static DisasJumpType
op_clgxb(DisasContext
*s
, DisasOps
*o
)
1969 TCGv_i32 m34
= fpinst_extract_m34(s
, false, false);
1972 return DISAS_NORETURN
;
1974 gen_helper_clgxb(o
->out
, cpu_env
, o
->in1
, o
->in2
, m34
);
1975 tcg_temp_free_i32(m34
);
1976 gen_set_cc_nz_f128(s
, o
->in1
, o
->in2
);
1980 static DisasJumpType
op_cegb(DisasContext
*s
, DisasOps
*o
)
1982 TCGv_i32 m34
= fpinst_extract_m34(s
, true, true);
1985 return DISAS_NORETURN
;
1987 gen_helper_cegb(o
->out
, cpu_env
, o
->in2
, m34
);
1988 tcg_temp_free_i32(m34
);
1992 static DisasJumpType
op_cdgb(DisasContext
*s
, DisasOps
*o
)
1994 TCGv_i32 m34
= fpinst_extract_m34(s
, true, true);
1997 return DISAS_NORETURN
;
1999 gen_helper_cdgb(o
->out
, cpu_env
, o
->in2
, m34
);
2000 tcg_temp_free_i32(m34
);
2004 static DisasJumpType
op_cxgb(DisasContext
*s
, DisasOps
*o
)
2006 TCGv_i32 m34
= fpinst_extract_m34(s
, true, true);
2009 return DISAS_NORETURN
;
2011 gen_helper_cxgb(o
->out
, cpu_env
, o
->in2
, m34
);
2012 tcg_temp_free_i32(m34
);
2013 return_low128(o
->out2
);
2017 static DisasJumpType
op_celgb(DisasContext
*s
, DisasOps
*o
)
2019 TCGv_i32 m34
= fpinst_extract_m34(s
, false, false);
2022 return DISAS_NORETURN
;
2024 gen_helper_celgb(o
->out
, cpu_env
, o
->in2
, m34
);
2025 tcg_temp_free_i32(m34
);
2029 static DisasJumpType
op_cdlgb(DisasContext
*s
, DisasOps
*o
)
2031 TCGv_i32 m34
= fpinst_extract_m34(s
, false, false);
2034 return DISAS_NORETURN
;
2036 gen_helper_cdlgb(o
->out
, cpu_env
, o
->in2
, m34
);
2037 tcg_temp_free_i32(m34
);
2041 static DisasJumpType
op_cxlgb(DisasContext
*s
, DisasOps
*o
)
2043 TCGv_i32 m34
= fpinst_extract_m34(s
, false, false);
2046 return DISAS_NORETURN
;
2048 gen_helper_cxlgb(o
->out
, cpu_env
, o
->in2
, m34
);
2049 tcg_temp_free_i32(m34
);
2050 return_low128(o
->out2
);
2054 static DisasJumpType
op_cksm(DisasContext
*s
, DisasOps
*o
)
2056 int r2
= get_field(s
, r2
);
2057 TCGv_i64 len
= tcg_temp_new_i64();
2059 gen_helper_cksm(len
, cpu_env
, o
->in1
, o
->in2
, regs
[r2
+ 1]);
2061 return_low128(o
->out
);
2063 tcg_gen_add_i64(regs
[r2
], regs
[r2
], len
);
2064 tcg_gen_sub_i64(regs
[r2
+ 1], regs
[r2
+ 1], len
);
2065 tcg_temp_free_i64(len
);
2070 static DisasJumpType
op_clc(DisasContext
*s
, DisasOps
*o
)
2072 int l
= get_field(s
, l1
);
2077 tcg_gen_qemu_ld8u(cc_src
, o
->addr1
, get_mem_index(s
));
2078 tcg_gen_qemu_ld8u(cc_dst
, o
->in2
, get_mem_index(s
));
2081 tcg_gen_qemu_ld16u(cc_src
, o
->addr1
, get_mem_index(s
));
2082 tcg_gen_qemu_ld16u(cc_dst
, o
->in2
, get_mem_index(s
));
2085 tcg_gen_qemu_ld32u(cc_src
, o
->addr1
, get_mem_index(s
));
2086 tcg_gen_qemu_ld32u(cc_dst
, o
->in2
, get_mem_index(s
));
2089 tcg_gen_qemu_ld64(cc_src
, o
->addr1
, get_mem_index(s
));
2090 tcg_gen_qemu_ld64(cc_dst
, o
->in2
, get_mem_index(s
));
2093 vl
= tcg_const_i32(l
);
2094 gen_helper_clc(cc_op
, cpu_env
, vl
, o
->addr1
, o
->in2
);
2095 tcg_temp_free_i32(vl
);
2099 gen_op_update2_cc_i64(s
, CC_OP_LTUGTU_64
, cc_src
, cc_dst
);
2103 static DisasJumpType
op_clcl(DisasContext
*s
, DisasOps
*o
)
2105 int r1
= get_field(s
, r1
);
2106 int r2
= get_field(s
, r2
);
2109 /* r1 and r2 must be even. */
2110 if (r1
& 1 || r2
& 1) {
2111 gen_program_exception(s
, PGM_SPECIFICATION
);
2112 return DISAS_NORETURN
;
2115 t1
= tcg_const_i32(r1
);
2116 t2
= tcg_const_i32(r2
);
2117 gen_helper_clcl(cc_op
, cpu_env
, t1
, t2
);
2118 tcg_temp_free_i32(t1
);
2119 tcg_temp_free_i32(t2
);
2124 static DisasJumpType
op_clcle(DisasContext
*s
, DisasOps
*o
)
2126 int r1
= get_field(s
, r1
);
2127 int r3
= get_field(s
, r3
);
2130 /* r1 and r3 must be even. */
2131 if (r1
& 1 || r3
& 1) {
2132 gen_program_exception(s
, PGM_SPECIFICATION
);
2133 return DISAS_NORETURN
;
2136 t1
= tcg_const_i32(r1
);
2137 t3
= tcg_const_i32(r3
);
2138 gen_helper_clcle(cc_op
, cpu_env
, t1
, o
->in2
, t3
);
2139 tcg_temp_free_i32(t1
);
2140 tcg_temp_free_i32(t3
);
2145 static DisasJumpType
op_clclu(DisasContext
*s
, DisasOps
*o
)
2147 int r1
= get_field(s
, r1
);
2148 int r3
= get_field(s
, r3
);
2151 /* r1 and r3 must be even. */
2152 if (r1
& 1 || r3
& 1) {
2153 gen_program_exception(s
, PGM_SPECIFICATION
);
2154 return DISAS_NORETURN
;
2157 t1
= tcg_const_i32(r1
);
2158 t3
= tcg_const_i32(r3
);
2159 gen_helper_clclu(cc_op
, cpu_env
, t1
, o
->in2
, t3
);
2160 tcg_temp_free_i32(t1
);
2161 tcg_temp_free_i32(t3
);
2166 static DisasJumpType
op_clm(DisasContext
*s
, DisasOps
*o
)
2168 TCGv_i32 m3
= tcg_const_i32(get_field(s
, m3
));
2169 TCGv_i32 t1
= tcg_temp_new_i32();
2170 tcg_gen_extrl_i64_i32(t1
, o
->in1
);
2171 gen_helper_clm(cc_op
, cpu_env
, t1
, m3
, o
->in2
);
2173 tcg_temp_free_i32(t1
);
2174 tcg_temp_free_i32(m3
);
2178 static DisasJumpType
op_clst(DisasContext
*s
, DisasOps
*o
)
2180 gen_helper_clst(o
->in1
, cpu_env
, regs
[0], o
->in1
, o
->in2
);
2182 return_low128(o
->in2
);
2186 static DisasJumpType
op_cps(DisasContext
*s
, DisasOps
*o
)
2188 TCGv_i64 t
= tcg_temp_new_i64();
2189 tcg_gen_andi_i64(t
, o
->in1
, 0x8000000000000000ull
);
2190 tcg_gen_andi_i64(o
->out
, o
->in2
, 0x7fffffffffffffffull
);
2191 tcg_gen_or_i64(o
->out
, o
->out
, t
);
2192 tcg_temp_free_i64(t
);
2196 static DisasJumpType
op_cs(DisasContext
*s
, DisasOps
*o
)
2198 int d2
= get_field(s
, d2
);
2199 int b2
= get_field(s
, b2
);
2202 /* Note that in1 = R3 (new value) and
2203 in2 = (zero-extended) R1 (expected value). */
2205 addr
= get_address(s
, 0, b2
, d2
);
2206 tcg_gen_atomic_cmpxchg_i64(o
->out
, addr
, o
->in2
, o
->in1
,
2207 get_mem_index(s
), s
->insn
->data
| MO_ALIGN
);
2208 tcg_temp_free_i64(addr
);
2210 /* Are the memory and expected values (un)equal? Note that this setcond
2211 produces the output CC value, thus the NE sense of the test. */
2212 cc
= tcg_temp_new_i64();
2213 tcg_gen_setcond_i64(TCG_COND_NE
, cc
, o
->in2
, o
->out
);
2214 tcg_gen_extrl_i64_i32(cc_op
, cc
);
2215 tcg_temp_free_i64(cc
);
2221 static DisasJumpType
op_cdsg(DisasContext
*s
, DisasOps
*o
)
2223 int r1
= get_field(s
, r1
);
2224 int r3
= get_field(s
, r3
);
2225 int d2
= get_field(s
, d2
);
2226 int b2
= get_field(s
, b2
);
2227 DisasJumpType ret
= DISAS_NEXT
;
2229 TCGv_i32 t_r1
, t_r3
;
2231 /* Note that R1:R1+1 = expected value and R3:R3+1 = new value. */
2232 addr
= get_address(s
, 0, b2
, d2
);
2233 t_r1
= tcg_const_i32(r1
);
2234 t_r3
= tcg_const_i32(r3
);
2235 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
2236 gen_helper_cdsg(cpu_env
, addr
, t_r1
, t_r3
);
2237 } else if (HAVE_CMPXCHG128
) {
2238 gen_helper_cdsg_parallel(cpu_env
, addr
, t_r1
, t_r3
);
2240 gen_helper_exit_atomic(cpu_env
);
2241 ret
= DISAS_NORETURN
;
2243 tcg_temp_free_i64(addr
);
2244 tcg_temp_free_i32(t_r1
);
2245 tcg_temp_free_i32(t_r3
);
2251 static DisasJumpType
op_csst(DisasContext
*s
, DisasOps
*o
)
2253 int r3
= get_field(s
, r3
);
2254 TCGv_i32 t_r3
= tcg_const_i32(r3
);
2256 if (tb_cflags(s
->base
.tb
) & CF_PARALLEL
) {
2257 gen_helper_csst_parallel(cc_op
, cpu_env
, t_r3
, o
->addr1
, o
->in2
);
2259 gen_helper_csst(cc_op
, cpu_env
, t_r3
, o
->addr1
, o
->in2
);
2261 tcg_temp_free_i32(t_r3
);
2267 #ifndef CONFIG_USER_ONLY
2268 static DisasJumpType
op_csp(DisasContext
*s
, DisasOps
*o
)
2270 MemOp mop
= s
->insn
->data
;
2271 TCGv_i64 addr
, old
, cc
;
2272 TCGLabel
*lab
= gen_new_label();
2274 /* Note that in1 = R1 (zero-extended expected value),
2275 out = R1 (original reg), out2 = R1+1 (new value). */
2277 addr
= tcg_temp_new_i64();
2278 old
= tcg_temp_new_i64();
2279 tcg_gen_andi_i64(addr
, o
->in2
, -1ULL << (mop
& MO_SIZE
));
2280 tcg_gen_atomic_cmpxchg_i64(old
, addr
, o
->in1
, o
->out2
,
2281 get_mem_index(s
), mop
| MO_ALIGN
);
2282 tcg_temp_free_i64(addr
);
2284 /* Are the memory and expected values (un)equal? */
2285 cc
= tcg_temp_new_i64();
2286 tcg_gen_setcond_i64(TCG_COND_NE
, cc
, o
->in1
, old
);
2287 tcg_gen_extrl_i64_i32(cc_op
, cc
);
2289 /* Write back the output now, so that it happens before the
2290 following branch, so that we don't need local temps. */
2291 if ((mop
& MO_SIZE
) == MO_32
) {
2292 tcg_gen_deposit_i64(o
->out
, o
->out
, old
, 0, 32);
2294 tcg_gen_mov_i64(o
->out
, old
);
2296 tcg_temp_free_i64(old
);
2298 /* If the comparison was equal, and the LSB of R2 was set,
2299 then we need to flush the TLB (for all cpus). */
2300 tcg_gen_xori_i64(cc
, cc
, 1);
2301 tcg_gen_and_i64(cc
, cc
, o
->in2
);
2302 tcg_gen_brcondi_i64(TCG_COND_EQ
, cc
, 0, lab
);
2303 tcg_temp_free_i64(cc
);
2305 gen_helper_purge(cpu_env
);
2312 static DisasJumpType
op_cvd(DisasContext
*s
, DisasOps
*o
)
2314 TCGv_i64 t1
= tcg_temp_new_i64();
2315 TCGv_i32 t2
= tcg_temp_new_i32();
2316 tcg_gen_extrl_i64_i32(t2
, o
->in1
);
2317 gen_helper_cvd(t1
, t2
);
2318 tcg_temp_free_i32(t2
);
2319 tcg_gen_qemu_st64(t1
, o
->in2
, get_mem_index(s
));
2320 tcg_temp_free_i64(t1
);
2324 static DisasJumpType
op_ct(DisasContext
*s
, DisasOps
*o
)
2326 int m3
= get_field(s
, m3
);
2327 TCGLabel
*lab
= gen_new_label();
2330 c
= tcg_invert_cond(ltgt_cond
[m3
]);
2331 if (s
->insn
->data
) {
2332 c
= tcg_unsigned_cond(c
);
2334 tcg_gen_brcond_i64(c
, o
->in1
, o
->in2
, lab
);
2343 static DisasJumpType
op_cuXX(DisasContext
*s
, DisasOps
*o
)
2345 int m3
= get_field(s
, m3
);
2346 int r1
= get_field(s
, r1
);
2347 int r2
= get_field(s
, r2
);
2348 TCGv_i32 tr1
, tr2
, chk
;
2350 /* R1 and R2 must both be even. */
2351 if ((r1
| r2
) & 1) {
2352 gen_program_exception(s
, PGM_SPECIFICATION
);
2353 return DISAS_NORETURN
;
2355 if (!s390_has_feat(S390_FEAT_ETF3_ENH
)) {
2359 tr1
= tcg_const_i32(r1
);
2360 tr2
= tcg_const_i32(r2
);
2361 chk
= tcg_const_i32(m3
);
2363 switch (s
->insn
->data
) {
2365 gen_helper_cu12(cc_op
, cpu_env
, tr1
, tr2
, chk
);
2368 gen_helper_cu14(cc_op
, cpu_env
, tr1
, tr2
, chk
);
2371 gen_helper_cu21(cc_op
, cpu_env
, tr1
, tr2
, chk
);
2374 gen_helper_cu24(cc_op
, cpu_env
, tr1
, tr2
, chk
);
2377 gen_helper_cu41(cc_op
, cpu_env
, tr1
, tr2
, chk
);
2380 gen_helper_cu42(cc_op
, cpu_env
, tr1
, tr2
, chk
);
2383 g_assert_not_reached();
2386 tcg_temp_free_i32(tr1
);
2387 tcg_temp_free_i32(tr2
);
2388 tcg_temp_free_i32(chk
);
2393 #ifndef CONFIG_USER_ONLY
2394 static DisasJumpType
op_diag(DisasContext
*s
, DisasOps
*o
)
2396 TCGv_i32 r1
= tcg_const_i32(get_field(s
, r1
));
2397 TCGv_i32 r3
= tcg_const_i32(get_field(s
, r3
));
2398 TCGv_i32 func_code
= tcg_const_i32(get_field(s
, i2
));
2400 gen_helper_diag(cpu_env
, r1
, r3
, func_code
);
2402 tcg_temp_free_i32(func_code
);
2403 tcg_temp_free_i32(r3
);
2404 tcg_temp_free_i32(r1
);
2409 static DisasJumpType
op_divs32(DisasContext
*s
, DisasOps
*o
)
2411 gen_helper_divs32(o
->out2
, cpu_env
, o
->in1
, o
->in2
);
2412 return_low128(o
->out
);
2416 static DisasJumpType
op_divu32(DisasContext
*s
, DisasOps
*o
)
2418 gen_helper_divu32(o
->out2
, cpu_env
, o
->in1
, o
->in2
);
2419 return_low128(o
->out
);
2423 static DisasJumpType
op_divs64(DisasContext
*s
, DisasOps
*o
)
2425 gen_helper_divs64(o
->out2
, cpu_env
, o
->in1
, o
->in2
);
2426 return_low128(o
->out
);
2430 static DisasJumpType
op_divu64(DisasContext
*s
, DisasOps
*o
)
2432 gen_helper_divu64(o
->out2
, cpu_env
, o
->out
, o
->out2
, o
->in2
);
2433 return_low128(o
->out
);
2437 static DisasJumpType
op_deb(DisasContext
*s
, DisasOps
*o
)
2439 gen_helper_deb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
2443 static DisasJumpType
op_ddb(DisasContext
*s
, DisasOps
*o
)
2445 gen_helper_ddb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
2449 static DisasJumpType
op_dxb(DisasContext
*s
, DisasOps
*o
)
2451 gen_helper_dxb(o
->out
, cpu_env
, o
->out
, o
->out2
, o
->in1
, o
->in2
);
2452 return_low128(o
->out2
);
2456 static DisasJumpType
op_ear(DisasContext
*s
, DisasOps
*o
)
2458 int r2
= get_field(s
, r2
);
2459 tcg_gen_ld32u_i64(o
->out
, cpu_env
, offsetof(CPUS390XState
, aregs
[r2
]));
2463 static DisasJumpType
op_ecag(DisasContext
*s
, DisasOps
*o
)
2465 /* No cache information provided. */
2466 tcg_gen_movi_i64(o
->out
, -1);
2470 static DisasJumpType
op_efpc(DisasContext
*s
, DisasOps
*o
)
2472 tcg_gen_ld32u_i64(o
->out
, cpu_env
, offsetof(CPUS390XState
, fpc
));
2476 static DisasJumpType
op_epsw(DisasContext
*s
, DisasOps
*o
)
2478 int r1
= get_field(s
, r1
);
2479 int r2
= get_field(s
, r2
);
2480 TCGv_i64 t
= tcg_temp_new_i64();
2482 /* Note the "subsequently" in the PoO, which implies a defined result
2483 if r1 == r2. Thus we cannot defer these writes to an output hook. */
2484 tcg_gen_shri_i64(t
, psw_mask
, 32);
2485 store_reg32_i64(r1
, t
);
2487 store_reg32_i64(r2
, psw_mask
);
2490 tcg_temp_free_i64(t
);
2494 static DisasJumpType
op_ex(DisasContext
*s
, DisasOps
*o
)
2496 int r1
= get_field(s
, r1
);
2500 /* Nested EXECUTE is not allowed. */
2501 if (unlikely(s
->ex_value
)) {
2502 gen_program_exception(s
, PGM_EXECUTE
);
2503 return DISAS_NORETURN
;
2510 v1
= tcg_const_i64(0);
2515 ilen
= tcg_const_i32(s
->ilen
);
2516 gen_helper_ex(cpu_env
, ilen
, v1
, o
->in2
);
2517 tcg_temp_free_i32(ilen
);
2520 tcg_temp_free_i64(v1
);
2523 return DISAS_PC_CC_UPDATED
;
2526 static DisasJumpType
op_fieb(DisasContext
*s
, DisasOps
*o
)
2528 TCGv_i32 m34
= fpinst_extract_m34(s
, false, true);
2531 return DISAS_NORETURN
;
2533 gen_helper_fieb(o
->out
, cpu_env
, o
->in2
, m34
);
2534 tcg_temp_free_i32(m34
);
2538 static DisasJumpType
op_fidb(DisasContext
*s
, DisasOps
*o
)
2540 TCGv_i32 m34
= fpinst_extract_m34(s
, false, true);
2543 return DISAS_NORETURN
;
2545 gen_helper_fidb(o
->out
, cpu_env
, o
->in2
, m34
);
2546 tcg_temp_free_i32(m34
);
2550 static DisasJumpType
op_fixb(DisasContext
*s
, DisasOps
*o
)
2552 TCGv_i32 m34
= fpinst_extract_m34(s
, false, true);
2555 return DISAS_NORETURN
;
2557 gen_helper_fixb(o
->out
, cpu_env
, o
->in1
, o
->in2
, m34
);
2558 return_low128(o
->out2
);
2559 tcg_temp_free_i32(m34
);
2563 static DisasJumpType
op_flogr(DisasContext
*s
, DisasOps
*o
)
2565 /* We'll use the original input for cc computation, since we get to
2566 compare that against 0, which ought to be better than comparing
2567 the real output against 64. It also lets cc_dst be a convenient
2568 temporary during our computation. */
2569 gen_op_update1_cc_i64(s
, CC_OP_FLOGR
, o
->in2
);
2571 /* R1 = IN ? CLZ(IN) : 64. */
2572 tcg_gen_clzi_i64(o
->out
, o
->in2
, 64);
2574 /* R1+1 = IN & ~(found bit). Note that we may attempt to shift this
2575 value by 64, which is undefined. But since the shift is 64 iff the
2576 input is zero, we still get the correct result after and'ing. */
2577 tcg_gen_movi_i64(o
->out2
, 0x8000000000000000ull
);
2578 tcg_gen_shr_i64(o
->out2
, o
->out2
, o
->out
);
2579 tcg_gen_andc_i64(o
->out2
, cc_dst
, o
->out2
);
2583 static DisasJumpType
op_icm(DisasContext
*s
, DisasOps
*o
)
2585 int m3
= get_field(s
, m3
);
2586 int pos
, len
, base
= s
->insn
->data
;
2587 TCGv_i64 tmp
= tcg_temp_new_i64();
2592 /* Effectively a 32-bit load. */
2593 tcg_gen_qemu_ld32u(tmp
, o
->in2
, get_mem_index(s
));
2600 /* Effectively a 16-bit load. */
2601 tcg_gen_qemu_ld16u(tmp
, o
->in2
, get_mem_index(s
));
2609 /* Effectively an 8-bit load. */
2610 tcg_gen_qemu_ld8u(tmp
, o
->in2
, get_mem_index(s
));
2615 pos
= base
+ ctz32(m3
) * 8;
2616 tcg_gen_deposit_i64(o
->out
, o
->out
, tmp
, pos
, len
);
2617 ccm
= ((1ull << len
) - 1) << pos
;
2621 /* This is going to be a sequence of loads and inserts. */
2622 pos
= base
+ 32 - 8;
2626 tcg_gen_qemu_ld8u(tmp
, o
->in2
, get_mem_index(s
));
2627 tcg_gen_addi_i64(o
->in2
, o
->in2
, 1);
2628 tcg_gen_deposit_i64(o
->out
, o
->out
, tmp
, pos
, 8);
2631 m3
= (m3
<< 1) & 0xf;
2637 tcg_gen_movi_i64(tmp
, ccm
);
2638 gen_op_update2_cc_i64(s
, CC_OP_ICM
, tmp
, o
->out
);
2639 tcg_temp_free_i64(tmp
);
2643 static DisasJumpType
op_insi(DisasContext
*s
, DisasOps
*o
)
2645 int shift
= s
->insn
->data
& 0xff;
2646 int size
= s
->insn
->data
>> 8;
2647 tcg_gen_deposit_i64(o
->out
, o
->in1
, o
->in2
, shift
, size
);
2651 static DisasJumpType
op_ipm(DisasContext
*s
, DisasOps
*o
)
2656 t1
= tcg_temp_new_i64();
2657 tcg_gen_extract_i64(t1
, psw_mask
, 40, 4);
2658 t2
= tcg_temp_new_i64();
2659 tcg_gen_extu_i32_i64(t2
, cc_op
);
2660 tcg_gen_deposit_i64(t1
, t1
, t2
, 4, 60);
2661 tcg_gen_deposit_i64(o
->out
, o
->out
, t1
, 24, 8);
2662 tcg_temp_free_i64(t1
);
2663 tcg_temp_free_i64(t2
);
2667 #ifndef CONFIG_USER_ONLY
2668 static DisasJumpType
op_idte(DisasContext
*s
, DisasOps
*o
)
2672 if (s390_has_feat(S390_FEAT_LOCAL_TLB_CLEARING
)) {
2673 m4
= tcg_const_i32(get_field(s
, m4
));
2675 m4
= tcg_const_i32(0);
2677 gen_helper_idte(cpu_env
, o
->in1
, o
->in2
, m4
);
2678 tcg_temp_free_i32(m4
);
2682 static DisasJumpType
op_ipte(DisasContext
*s
, DisasOps
*o
)
2686 if (s390_has_feat(S390_FEAT_LOCAL_TLB_CLEARING
)) {
2687 m4
= tcg_const_i32(get_field(s
, m4
));
2689 m4
= tcg_const_i32(0);
2691 gen_helper_ipte(cpu_env
, o
->in1
, o
->in2
, m4
);
2692 tcg_temp_free_i32(m4
);
2696 static DisasJumpType
op_iske(DisasContext
*s
, DisasOps
*o
)
2698 gen_helper_iske(o
->out
, cpu_env
, o
->in2
);
2703 static DisasJumpType
op_msa(DisasContext
*s
, DisasOps
*o
)
2705 int r1
= have_field(s
, r1
) ? get_field(s
, r1
) : 0;
2706 int r2
= have_field(s
, r2
) ? get_field(s
, r2
) : 0;
2707 int r3
= have_field(s
, r3
) ? get_field(s
, r3
) : 0;
2708 TCGv_i32 t_r1
, t_r2
, t_r3
, type
;
2710 switch (s
->insn
->data
) {
2711 case S390_FEAT_TYPE_KMCTR
:
2712 if (r3
& 1 || !r3
) {
2713 gen_program_exception(s
, PGM_SPECIFICATION
);
2714 return DISAS_NORETURN
;
2717 case S390_FEAT_TYPE_PPNO
:
2718 case S390_FEAT_TYPE_KMF
:
2719 case S390_FEAT_TYPE_KMC
:
2720 case S390_FEAT_TYPE_KMO
:
2721 case S390_FEAT_TYPE_KM
:
2722 if (r1
& 1 || !r1
) {
2723 gen_program_exception(s
, PGM_SPECIFICATION
);
2724 return DISAS_NORETURN
;
2727 case S390_FEAT_TYPE_KMAC
:
2728 case S390_FEAT_TYPE_KIMD
:
2729 case S390_FEAT_TYPE_KLMD
:
2730 if (r2
& 1 || !r2
) {
2731 gen_program_exception(s
, PGM_SPECIFICATION
);
2732 return DISAS_NORETURN
;
2735 case S390_FEAT_TYPE_PCKMO
:
2736 case S390_FEAT_TYPE_PCC
:
2739 g_assert_not_reached();
2742 t_r1
= tcg_const_i32(r1
);
2743 t_r2
= tcg_const_i32(r2
);
2744 t_r3
= tcg_const_i32(r3
);
2745 type
= tcg_const_i32(s
->insn
->data
);
2746 gen_helper_msa(cc_op
, cpu_env
, t_r1
, t_r2
, t_r3
, type
);
2748 tcg_temp_free_i32(t_r1
);
2749 tcg_temp_free_i32(t_r2
);
2750 tcg_temp_free_i32(t_r3
);
2751 tcg_temp_free_i32(type
);
2755 static DisasJumpType
op_keb(DisasContext
*s
, DisasOps
*o
)
2757 gen_helper_keb(cc_op
, cpu_env
, o
->in1
, o
->in2
);
2762 static DisasJumpType
op_kdb(DisasContext
*s
, DisasOps
*o
)
2764 gen_helper_kdb(cc_op
, cpu_env
, o
->in1
, o
->in2
);
2769 static DisasJumpType
op_kxb(DisasContext
*s
, DisasOps
*o
)
2771 gen_helper_kxb(cc_op
, cpu_env
, o
->out
, o
->out2
, o
->in1
, o
->in2
);
2776 static DisasJumpType
op_laa(DisasContext
*s
, DisasOps
*o
)
2778 /* The real output is indeed the original value in memory;
2779 recompute the addition for the computation of CC. */
2780 tcg_gen_atomic_fetch_add_i64(o
->in2
, o
->in2
, o
->in1
, get_mem_index(s
),
2781 s
->insn
->data
| MO_ALIGN
);
2782 /* However, we need to recompute the addition for setting CC. */
2783 tcg_gen_add_i64(o
->out
, o
->in1
, o
->in2
);
2787 static DisasJumpType
op_lan(DisasContext
*s
, DisasOps
*o
)
2789 /* The real output is indeed the original value in memory;
2790 recompute the addition for the computation of CC. */
2791 tcg_gen_atomic_fetch_and_i64(o
->in2
, o
->in2
, o
->in1
, get_mem_index(s
),
2792 s
->insn
->data
| MO_ALIGN
);
2793 /* However, we need to recompute the operation for setting CC. */
2794 tcg_gen_and_i64(o
->out
, o
->in1
, o
->in2
);
2798 static DisasJumpType
op_lao(DisasContext
*s
, DisasOps
*o
)
2800 /* The real output is indeed the original value in memory;
2801 recompute the addition for the computation of CC. */
2802 tcg_gen_atomic_fetch_or_i64(o
->in2
, o
->in2
, o
->in1
, get_mem_index(s
),
2803 s
->insn
->data
| MO_ALIGN
);
2804 /* However, we need to recompute the operation for setting CC. */
2805 tcg_gen_or_i64(o
->out
, o
->in1
, o
->in2
);
2809 static DisasJumpType
op_lax(DisasContext
*s
, DisasOps
*o
)
2811 /* The real output is indeed the original value in memory;
2812 recompute the addition for the computation of CC. */
2813 tcg_gen_atomic_fetch_xor_i64(o
->in2
, o
->in2
, o
->in1
, get_mem_index(s
),
2814 s
->insn
->data
| MO_ALIGN
);
2815 /* However, we need to recompute the operation for setting CC. */
2816 tcg_gen_xor_i64(o
->out
, o
->in1
, o
->in2
);
2820 static DisasJumpType
op_ldeb(DisasContext
*s
, DisasOps
*o
)
2822 gen_helper_ldeb(o
->out
, cpu_env
, o
->in2
);
2826 static DisasJumpType
op_ledb(DisasContext
*s
, DisasOps
*o
)
2828 TCGv_i32 m34
= fpinst_extract_m34(s
, true, true);
2831 return DISAS_NORETURN
;
2833 gen_helper_ledb(o
->out
, cpu_env
, o
->in2
, m34
);
2834 tcg_temp_free_i32(m34
);
2838 static DisasJumpType
op_ldxb(DisasContext
*s
, DisasOps
*o
)
2840 TCGv_i32 m34
= fpinst_extract_m34(s
, true, true);
2843 return DISAS_NORETURN
;
2845 gen_helper_ldxb(o
->out
, cpu_env
, o
->in1
, o
->in2
, m34
);
2846 tcg_temp_free_i32(m34
);
2850 static DisasJumpType
op_lexb(DisasContext
*s
, DisasOps
*o
)
2852 TCGv_i32 m34
= fpinst_extract_m34(s
, true, true);
2855 return DISAS_NORETURN
;
2857 gen_helper_lexb(o
->out
, cpu_env
, o
->in1
, o
->in2
, m34
);
2858 tcg_temp_free_i32(m34
);
2862 static DisasJumpType
op_lxdb(DisasContext
*s
, DisasOps
*o
)
2864 gen_helper_lxdb(o
->out
, cpu_env
, o
->in2
);
2865 return_low128(o
->out2
);
2869 static DisasJumpType
op_lxeb(DisasContext
*s
, DisasOps
*o
)
2871 gen_helper_lxeb(o
->out
, cpu_env
, o
->in2
);
2872 return_low128(o
->out2
);
2876 static DisasJumpType
op_lde(DisasContext
*s
, DisasOps
*o
)
2878 tcg_gen_shli_i64(o
->out
, o
->in2
, 32);
2882 static DisasJumpType
op_llgt(DisasContext
*s
, DisasOps
*o
)
2884 tcg_gen_andi_i64(o
->out
, o
->in2
, 0x7fffffff);
2888 static DisasJumpType
op_ld8s(DisasContext
*s
, DisasOps
*o
)
2890 tcg_gen_qemu_ld8s(o
->out
, o
->in2
, get_mem_index(s
));
2894 static DisasJumpType
op_ld8u(DisasContext
*s
, DisasOps
*o
)
2896 tcg_gen_qemu_ld8u(o
->out
, o
->in2
, get_mem_index(s
));
2900 static DisasJumpType
op_ld16s(DisasContext
*s
, DisasOps
*o
)
2902 tcg_gen_qemu_ld16s(o
->out
, o
->in2
, get_mem_index(s
));
2906 static DisasJumpType
op_ld16u(DisasContext
*s
, DisasOps
*o
)
2908 tcg_gen_qemu_ld16u(o
->out
, o
->in2
, get_mem_index(s
));
2912 static DisasJumpType
op_ld32s(DisasContext
*s
, DisasOps
*o
)
2914 tcg_gen_qemu_ld32s(o
->out
, o
->in2
, get_mem_index(s
));
2918 static DisasJumpType
op_ld32u(DisasContext
*s
, DisasOps
*o
)
2920 tcg_gen_qemu_ld32u(o
->out
, o
->in2
, get_mem_index(s
));
2924 static DisasJumpType
op_ld64(DisasContext
*s
, DisasOps
*o
)
2926 tcg_gen_qemu_ld64(o
->out
, o
->in2
, get_mem_index(s
));
2930 static DisasJumpType
op_lat(DisasContext
*s
, DisasOps
*o
)
2932 TCGLabel
*lab
= gen_new_label();
2933 store_reg32_i64(get_field(s
, r1
), o
->in2
);
2934 /* The value is stored even in case of trap. */
2935 tcg_gen_brcondi_i64(TCG_COND_NE
, o
->in2
, 0, lab
);
2941 static DisasJumpType
op_lgat(DisasContext
*s
, DisasOps
*o
)
2943 TCGLabel
*lab
= gen_new_label();
2944 tcg_gen_qemu_ld64(o
->out
, o
->in2
, get_mem_index(s
));
2945 /* The value is stored even in case of trap. */
2946 tcg_gen_brcondi_i64(TCG_COND_NE
, o
->out
, 0, lab
);
2952 static DisasJumpType
op_lfhat(DisasContext
*s
, DisasOps
*o
)
2954 TCGLabel
*lab
= gen_new_label();
2955 store_reg32h_i64(get_field(s
, r1
), o
->in2
);
2956 /* The value is stored even in case of trap. */
2957 tcg_gen_brcondi_i64(TCG_COND_NE
, o
->in2
, 0, lab
);
2963 static DisasJumpType
op_llgfat(DisasContext
*s
, DisasOps
*o
)
2965 TCGLabel
*lab
= gen_new_label();
2966 tcg_gen_qemu_ld32u(o
->out
, o
->in2
, get_mem_index(s
));
2967 /* The value is stored even in case of trap. */
2968 tcg_gen_brcondi_i64(TCG_COND_NE
, o
->out
, 0, lab
);
2974 static DisasJumpType
op_llgtat(DisasContext
*s
, DisasOps
*o
)
2976 TCGLabel
*lab
= gen_new_label();
2977 tcg_gen_andi_i64(o
->out
, o
->in2
, 0x7fffffff);
2978 /* The value is stored even in case of trap. */
2979 tcg_gen_brcondi_i64(TCG_COND_NE
, o
->out
, 0, lab
);
2985 static DisasJumpType
op_loc(DisasContext
*s
, DisasOps
*o
)
2989 disas_jcc(s
, &c
, get_field(s
, m3
));
2992 tcg_gen_movcond_i64(c
.cond
, o
->out
, c
.u
.s64
.a
, c
.u
.s64
.b
,
2996 TCGv_i32 t32
= tcg_temp_new_i32();
2999 tcg_gen_setcond_i32(c
.cond
, t32
, c
.u
.s32
.a
, c
.u
.s32
.b
);
3002 t
= tcg_temp_new_i64();
3003 tcg_gen_extu_i32_i64(t
, t32
);
3004 tcg_temp_free_i32(t32
);
3006 z
= tcg_const_i64(0);
3007 tcg_gen_movcond_i64(TCG_COND_NE
, o
->out
, t
, z
, o
->in2
, o
->in1
);
3008 tcg_temp_free_i64(t
);
3009 tcg_temp_free_i64(z
);
3015 #ifndef CONFIG_USER_ONLY
3016 static DisasJumpType
op_lctl(DisasContext
*s
, DisasOps
*o
)
3018 TCGv_i32 r1
= tcg_const_i32(get_field(s
, r1
));
3019 TCGv_i32 r3
= tcg_const_i32(get_field(s
, r3
));
3020 gen_helper_lctl(cpu_env
, r1
, o
->in2
, r3
);
3021 tcg_temp_free_i32(r1
);
3022 tcg_temp_free_i32(r3
);
3023 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
3024 return DISAS_PC_STALE_NOCHAIN
;
3027 static DisasJumpType
op_lctlg(DisasContext
*s
, DisasOps
*o
)
3029 TCGv_i32 r1
= tcg_const_i32(get_field(s
, r1
));
3030 TCGv_i32 r3
= tcg_const_i32(get_field(s
, r3
));
3031 gen_helper_lctlg(cpu_env
, r1
, o
->in2
, r3
);
3032 tcg_temp_free_i32(r1
);
3033 tcg_temp_free_i32(r3
);
3034 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
3035 return DISAS_PC_STALE_NOCHAIN
;
3038 static DisasJumpType
op_lra(DisasContext
*s
, DisasOps
*o
)
3040 gen_helper_lra(o
->out
, cpu_env
, o
->in2
);
3045 static DisasJumpType
op_lpp(DisasContext
*s
, DisasOps
*o
)
3047 tcg_gen_st_i64(o
->in2
, cpu_env
, offsetof(CPUS390XState
, pp
));
3051 static DisasJumpType
op_lpsw(DisasContext
*s
, DisasOps
*o
)
3055 per_breaking_event(s
);
3057 t1
= tcg_temp_new_i64();
3058 t2
= tcg_temp_new_i64();
3059 tcg_gen_qemu_ld_i64(t1
, o
->in2
, get_mem_index(s
),
3060 MO_TEUL
| MO_ALIGN_8
);
3061 tcg_gen_addi_i64(o
->in2
, o
->in2
, 4);
3062 tcg_gen_qemu_ld32u(t2
, o
->in2
, get_mem_index(s
));
3063 /* Convert the 32-bit PSW_MASK into the 64-bit PSW_MASK. */
3064 tcg_gen_shli_i64(t1
, t1
, 32);
3065 gen_helper_load_psw(cpu_env
, t1
, t2
);
3066 tcg_temp_free_i64(t1
);
3067 tcg_temp_free_i64(t2
);
3068 return DISAS_NORETURN
;
3071 static DisasJumpType
op_lpswe(DisasContext
*s
, DisasOps
*o
)
3075 per_breaking_event(s
);
3077 t1
= tcg_temp_new_i64();
3078 t2
= tcg_temp_new_i64();
3079 tcg_gen_qemu_ld_i64(t1
, o
->in2
, get_mem_index(s
),
3080 MO_TEQ
| MO_ALIGN_8
);
3081 tcg_gen_addi_i64(o
->in2
, o
->in2
, 8);
3082 tcg_gen_qemu_ld64(t2
, o
->in2
, get_mem_index(s
));
3083 gen_helper_load_psw(cpu_env
, t1
, t2
);
3084 tcg_temp_free_i64(t1
);
3085 tcg_temp_free_i64(t2
);
3086 return DISAS_NORETURN
;
3090 static DisasJumpType
op_lam(DisasContext
*s
, DisasOps
*o
)
3092 TCGv_i32 r1
= tcg_const_i32(get_field(s
, r1
));
3093 TCGv_i32 r3
= tcg_const_i32(get_field(s
, r3
));
3094 gen_helper_lam(cpu_env
, r1
, o
->in2
, r3
);
3095 tcg_temp_free_i32(r1
);
3096 tcg_temp_free_i32(r3
);
3100 static DisasJumpType
op_lm32(DisasContext
*s
, DisasOps
*o
)
3102 int r1
= get_field(s
, r1
);
3103 int r3
= get_field(s
, r3
);
3106 /* Only one register to read. */
3107 t1
= tcg_temp_new_i64();
3108 if (unlikely(r1
== r3
)) {
3109 tcg_gen_qemu_ld32u(t1
, o
->in2
, get_mem_index(s
));
3110 store_reg32_i64(r1
, t1
);
3115 /* First load the values of the first and last registers to trigger
3116 possible page faults. */
3117 t2
= tcg_temp_new_i64();
3118 tcg_gen_qemu_ld32u(t1
, o
->in2
, get_mem_index(s
));
3119 tcg_gen_addi_i64(t2
, o
->in2
, 4 * ((r3
- r1
) & 15));
3120 tcg_gen_qemu_ld32u(t2
, t2
, get_mem_index(s
));
3121 store_reg32_i64(r1
, t1
);
3122 store_reg32_i64(r3
, t2
);
3124 /* Only two registers to read. */
3125 if (((r1
+ 1) & 15) == r3
) {
3131 /* Then load the remaining registers. Page fault can't occur. */
3133 tcg_gen_movi_i64(t2
, 4);
3136 tcg_gen_add_i64(o
->in2
, o
->in2
, t2
);
3137 tcg_gen_qemu_ld32u(t1
, o
->in2
, get_mem_index(s
));
3138 store_reg32_i64(r1
, t1
);
3146 static DisasJumpType
op_lmh(DisasContext
*s
, DisasOps
*o
)
3148 int r1
= get_field(s
, r1
);
3149 int r3
= get_field(s
, r3
);
3152 /* Only one register to read. */
3153 t1
= tcg_temp_new_i64();
3154 if (unlikely(r1
== r3
)) {
3155 tcg_gen_qemu_ld32u(t1
, o
->in2
, get_mem_index(s
));
3156 store_reg32h_i64(r1
, t1
);
3161 /* First load the values of the first and last registers to trigger
3162 possible page faults. */
3163 t2
= tcg_temp_new_i64();
3164 tcg_gen_qemu_ld32u(t1
, o
->in2
, get_mem_index(s
));
3165 tcg_gen_addi_i64(t2
, o
->in2
, 4 * ((r3
- r1
) & 15));
3166 tcg_gen_qemu_ld32u(t2
, t2
, get_mem_index(s
));
3167 store_reg32h_i64(r1
, t1
);
3168 store_reg32h_i64(r3
, t2
);
3170 /* Only two registers to read. */
3171 if (((r1
+ 1) & 15) == r3
) {
3177 /* Then load the remaining registers. Page fault can't occur. */
3179 tcg_gen_movi_i64(t2
, 4);
3182 tcg_gen_add_i64(o
->in2
, o
->in2
, t2
);
3183 tcg_gen_qemu_ld32u(t1
, o
->in2
, get_mem_index(s
));
3184 store_reg32h_i64(r1
, t1
);
3192 static DisasJumpType
op_lm64(DisasContext
*s
, DisasOps
*o
)
3194 int r1
= get_field(s
, r1
);
3195 int r3
= get_field(s
, r3
);
3198 /* Only one register to read. */
3199 if (unlikely(r1
== r3
)) {
3200 tcg_gen_qemu_ld64(regs
[r1
], o
->in2
, get_mem_index(s
));
3204 /* First load the values of the first and last registers to trigger
3205 possible page faults. */
3206 t1
= tcg_temp_new_i64();
3207 t2
= tcg_temp_new_i64();
3208 tcg_gen_qemu_ld64(t1
, o
->in2
, get_mem_index(s
));
3209 tcg_gen_addi_i64(t2
, o
->in2
, 8 * ((r3
- r1
) & 15));
3210 tcg_gen_qemu_ld64(regs
[r3
], t2
, get_mem_index(s
));
3211 tcg_gen_mov_i64(regs
[r1
], t1
);
3214 /* Only two registers to read. */
3215 if (((r1
+ 1) & 15) == r3
) {
3220 /* Then load the remaining registers. Page fault can't occur. */
3222 tcg_gen_movi_i64(t1
, 8);
3225 tcg_gen_add_i64(o
->in2
, o
->in2
, t1
);
3226 tcg_gen_qemu_ld64(regs
[r1
], o
->in2
, get_mem_index(s
));
3233 static DisasJumpType
op_lpd(DisasContext
*s
, DisasOps
*o
)
3236 MemOp mop
= s
->insn
->data
;
3238 /* In a parallel context, stop the world and single step. */
3239 if (tb_cflags(s
->base
.tb
) & CF_PARALLEL
) {
3242 gen_exception(EXCP_ATOMIC
);
3243 return DISAS_NORETURN
;
3246 /* In a serial context, perform the two loads ... */
3247 a1
= get_address(s
, 0, get_field(s
, b1
), get_field(s
, d1
));
3248 a2
= get_address(s
, 0, get_field(s
, b2
), get_field(s
, d2
));
3249 tcg_gen_qemu_ld_i64(o
->out
, a1
, get_mem_index(s
), mop
| MO_ALIGN
);
3250 tcg_gen_qemu_ld_i64(o
->out2
, a2
, get_mem_index(s
), mop
| MO_ALIGN
);
3251 tcg_temp_free_i64(a1
);
3252 tcg_temp_free_i64(a2
);
3254 /* ... and indicate that we performed them while interlocked. */
3255 gen_op_movi_cc(s
, 0);
3259 static DisasJumpType
op_lpq(DisasContext
*s
, DisasOps
*o
)
3261 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
3262 gen_helper_lpq(o
->out
, cpu_env
, o
->in2
);
3263 } else if (HAVE_ATOMIC128
) {
3264 gen_helper_lpq_parallel(o
->out
, cpu_env
, o
->in2
);
3266 gen_helper_exit_atomic(cpu_env
);
3267 return DISAS_NORETURN
;
3269 return_low128(o
->out2
);
3273 #ifndef CONFIG_USER_ONLY
3274 static DisasJumpType
op_lura(DisasContext
*s
, DisasOps
*o
)
3276 o
->addr1
= get_address(s
, 0, get_field(s
, r2
), 0);
3277 tcg_gen_qemu_ld_tl(o
->out
, o
->addr1
, MMU_REAL_IDX
, s
->insn
->data
);
3282 static DisasJumpType
op_lzrb(DisasContext
*s
, DisasOps
*o
)
3284 tcg_gen_andi_i64(o
->out
, o
->in2
, -256);
3288 static DisasJumpType
op_lcbb(DisasContext
*s
, DisasOps
*o
)
3290 const int64_t block_size
= (1ull << (get_field(s
, m3
) + 6));
3292 if (get_field(s
, m3
) > 6) {
3293 gen_program_exception(s
, PGM_SPECIFICATION
);
3294 return DISAS_NORETURN
;
3297 tcg_gen_ori_i64(o
->addr1
, o
->addr1
, -block_size
);
3298 tcg_gen_neg_i64(o
->addr1
, o
->addr1
);
3299 tcg_gen_movi_i64(o
->out
, 16);
3300 tcg_gen_umin_i64(o
->out
, o
->out
, o
->addr1
);
3301 gen_op_update1_cc_i64(s
, CC_OP_LCBB
, o
->out
);
3305 static DisasJumpType
op_mov2(DisasContext
*s
, DisasOps
*o
)
3308 o
->g_out
= o
->g_in2
;
3314 static DisasJumpType
op_mov2e(DisasContext
*s
, DisasOps
*o
)
3316 int b2
= get_field(s
, b2
);
3317 TCGv ar1
= tcg_temp_new_i64();
3320 o
->g_out
= o
->g_in2
;
3324 switch (s
->base
.tb
->flags
& FLAG_MASK_ASC
) {
3325 case PSW_ASC_PRIMARY
>> FLAG_MASK_PSW_SHIFT
:
3326 tcg_gen_movi_i64(ar1
, 0);
3328 case PSW_ASC_ACCREG
>> FLAG_MASK_PSW_SHIFT
:
3329 tcg_gen_movi_i64(ar1
, 1);
3331 case PSW_ASC_SECONDARY
>> FLAG_MASK_PSW_SHIFT
:
3333 tcg_gen_ld32u_i64(ar1
, cpu_env
, offsetof(CPUS390XState
, aregs
[b2
]));
3335 tcg_gen_movi_i64(ar1
, 0);
3338 case PSW_ASC_HOME
>> FLAG_MASK_PSW_SHIFT
:
3339 tcg_gen_movi_i64(ar1
, 2);
3343 tcg_gen_st32_i64(ar1
, cpu_env
, offsetof(CPUS390XState
, aregs
[1]));
3344 tcg_temp_free_i64(ar1
);
3349 static DisasJumpType
op_movx(DisasContext
*s
, DisasOps
*o
)
3353 o
->g_out
= o
->g_in1
;
3354 o
->g_out2
= o
->g_in2
;
3357 o
->g_in1
= o
->g_in2
= false;
3361 static DisasJumpType
op_mvc(DisasContext
*s
, DisasOps
*o
)
3363 TCGv_i32 l
= tcg_const_i32(get_field(s
, l1
));
3364 gen_helper_mvc(cpu_env
, l
, o
->addr1
, o
->in2
);
3365 tcg_temp_free_i32(l
);
3369 static DisasJumpType
op_mvcin(DisasContext
*s
, DisasOps
*o
)
3371 TCGv_i32 l
= tcg_const_i32(get_field(s
, l1
));
3372 gen_helper_mvcin(cpu_env
, l
, o
->addr1
, o
->in2
);
3373 tcg_temp_free_i32(l
);
3377 static DisasJumpType
op_mvcl(DisasContext
*s
, DisasOps
*o
)
3379 int r1
= get_field(s
, r1
);
3380 int r2
= get_field(s
, r2
);
3383 /* r1 and r2 must be even. */
3384 if (r1
& 1 || r2
& 1) {
3385 gen_program_exception(s
, PGM_SPECIFICATION
);
3386 return DISAS_NORETURN
;
3389 t1
= tcg_const_i32(r1
);
3390 t2
= tcg_const_i32(r2
);
3391 gen_helper_mvcl(cc_op
, cpu_env
, t1
, t2
);
3392 tcg_temp_free_i32(t1
);
3393 tcg_temp_free_i32(t2
);
3398 static DisasJumpType
op_mvcle(DisasContext
*s
, DisasOps
*o
)
3400 int r1
= get_field(s
, r1
);
3401 int r3
= get_field(s
, r3
);
3404 /* r1 and r3 must be even. */
3405 if (r1
& 1 || r3
& 1) {
3406 gen_program_exception(s
, PGM_SPECIFICATION
);
3407 return DISAS_NORETURN
;
3410 t1
= tcg_const_i32(r1
);
3411 t3
= tcg_const_i32(r3
);
3412 gen_helper_mvcle(cc_op
, cpu_env
, t1
, o
->in2
, t3
);
3413 tcg_temp_free_i32(t1
);
3414 tcg_temp_free_i32(t3
);
3419 static DisasJumpType
op_mvclu(DisasContext
*s
, DisasOps
*o
)
3421 int r1
= get_field(s
, r1
);
3422 int r3
= get_field(s
, r3
);
3425 /* r1 and r3 must be even. */
3426 if (r1
& 1 || r3
& 1) {
3427 gen_program_exception(s
, PGM_SPECIFICATION
);
3428 return DISAS_NORETURN
;
3431 t1
= tcg_const_i32(r1
);
3432 t3
= tcg_const_i32(r3
);
3433 gen_helper_mvclu(cc_op
, cpu_env
, t1
, o
->in2
, t3
);
3434 tcg_temp_free_i32(t1
);
3435 tcg_temp_free_i32(t3
);
3440 static DisasJumpType
op_mvcos(DisasContext
*s
, DisasOps
*o
)
3442 int r3
= get_field(s
, r3
);
3443 gen_helper_mvcos(cc_op
, cpu_env
, o
->addr1
, o
->in2
, regs
[r3
]);
3448 #ifndef CONFIG_USER_ONLY
3449 static DisasJumpType
op_mvcp(DisasContext
*s
, DisasOps
*o
)
3451 int r1
= get_field(s
, l1
);
3452 gen_helper_mvcp(cc_op
, cpu_env
, regs
[r1
], o
->addr1
, o
->in2
);
3457 static DisasJumpType
op_mvcs(DisasContext
*s
, DisasOps
*o
)
3459 int r1
= get_field(s
, l1
);
3460 gen_helper_mvcs(cc_op
, cpu_env
, regs
[r1
], o
->addr1
, o
->in2
);
3466 static DisasJumpType
op_mvn(DisasContext
*s
, DisasOps
*o
)
3468 TCGv_i32 l
= tcg_const_i32(get_field(s
, l1
));
3469 gen_helper_mvn(cpu_env
, l
, o
->addr1
, o
->in2
);
3470 tcg_temp_free_i32(l
);
3474 static DisasJumpType
op_mvo(DisasContext
*s
, DisasOps
*o
)
3476 TCGv_i32 l
= tcg_const_i32(get_field(s
, l1
));
3477 gen_helper_mvo(cpu_env
, l
, o
->addr1
, o
->in2
);
3478 tcg_temp_free_i32(l
);
3482 static DisasJumpType
op_mvpg(DisasContext
*s
, DisasOps
*o
)
3484 gen_helper_mvpg(cc_op
, cpu_env
, regs
[0], o
->in1
, o
->in2
);
3489 static DisasJumpType
op_mvst(DisasContext
*s
, DisasOps
*o
)
3491 TCGv_i32 t1
= tcg_const_i32(get_field(s
, r1
));
3492 TCGv_i32 t2
= tcg_const_i32(get_field(s
, r2
));
3494 gen_helper_mvst(cc_op
, cpu_env
, t1
, t2
);
3495 tcg_temp_free_i32(t1
);
3496 tcg_temp_free_i32(t2
);
3501 static DisasJumpType
op_mvz(DisasContext
*s
, DisasOps
*o
)
3503 TCGv_i32 l
= tcg_const_i32(get_field(s
, l1
));
3504 gen_helper_mvz(cpu_env
, l
, o
->addr1
, o
->in2
);
3505 tcg_temp_free_i32(l
);
3509 static DisasJumpType
op_mul(DisasContext
*s
, DisasOps
*o
)
3511 tcg_gen_mul_i64(o
->out
, o
->in1
, o
->in2
);
3515 static DisasJumpType
op_mul128(DisasContext
*s
, DisasOps
*o
)
3517 tcg_gen_mulu2_i64(o
->out2
, o
->out
, o
->in1
, o
->in2
);
3521 static DisasJumpType
op_meeb(DisasContext
*s
, DisasOps
*o
)
3523 gen_helper_meeb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
3527 static DisasJumpType
op_mdeb(DisasContext
*s
, DisasOps
*o
)
3529 gen_helper_mdeb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
3533 static DisasJumpType
op_mdb(DisasContext
*s
, DisasOps
*o
)
3535 gen_helper_mdb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
3539 static DisasJumpType
op_mxb(DisasContext
*s
, DisasOps
*o
)
3541 gen_helper_mxb(o
->out
, cpu_env
, o
->out
, o
->out2
, o
->in1
, o
->in2
);
3542 return_low128(o
->out2
);
3546 static DisasJumpType
op_mxdb(DisasContext
*s
, DisasOps
*o
)
3548 gen_helper_mxdb(o
->out
, cpu_env
, o
->out
, o
->out2
, o
->in2
);
3549 return_low128(o
->out2
);
3553 static DisasJumpType
op_maeb(DisasContext
*s
, DisasOps
*o
)
3555 TCGv_i64 r3
= load_freg32_i64(get_field(s
, r3
));
3556 gen_helper_maeb(o
->out
, cpu_env
, o
->in1
, o
->in2
, r3
);
3557 tcg_temp_free_i64(r3
);
3561 static DisasJumpType
op_madb(DisasContext
*s
, DisasOps
*o
)
3563 TCGv_i64 r3
= load_freg(get_field(s
, r3
));
3564 gen_helper_madb(o
->out
, cpu_env
, o
->in1
, o
->in2
, r3
);
3565 tcg_temp_free_i64(r3
);
3569 static DisasJumpType
op_mseb(DisasContext
*s
, DisasOps
*o
)
3571 TCGv_i64 r3
= load_freg32_i64(get_field(s
, r3
));
3572 gen_helper_mseb(o
->out
, cpu_env
, o
->in1
, o
->in2
, r3
);
3573 tcg_temp_free_i64(r3
);
3577 static DisasJumpType
op_msdb(DisasContext
*s
, DisasOps
*o
)
3579 TCGv_i64 r3
= load_freg(get_field(s
, r3
));
3580 gen_helper_msdb(o
->out
, cpu_env
, o
->in1
, o
->in2
, r3
);
3581 tcg_temp_free_i64(r3
);
3585 static DisasJumpType
op_nabs(DisasContext
*s
, DisasOps
*o
)
3588 z
= tcg_const_i64(0);
3589 n
= tcg_temp_new_i64();
3590 tcg_gen_neg_i64(n
, o
->in2
);
3591 tcg_gen_movcond_i64(TCG_COND_GE
, o
->out
, o
->in2
, z
, n
, o
->in2
);
3592 tcg_temp_free_i64(n
);
3593 tcg_temp_free_i64(z
);
3597 static DisasJumpType
op_nabsf32(DisasContext
*s
, DisasOps
*o
)
3599 tcg_gen_ori_i64(o
->out
, o
->in2
, 0x80000000ull
);
3603 static DisasJumpType
op_nabsf64(DisasContext
*s
, DisasOps
*o
)
3605 tcg_gen_ori_i64(o
->out
, o
->in2
, 0x8000000000000000ull
);
3609 static DisasJumpType
op_nabsf128(DisasContext
*s
, DisasOps
*o
)
3611 tcg_gen_ori_i64(o
->out
, o
->in1
, 0x8000000000000000ull
);
3612 tcg_gen_mov_i64(o
->out2
, o
->in2
);
3616 static DisasJumpType
op_nc(DisasContext
*s
, DisasOps
*o
)
3618 TCGv_i32 l
= tcg_const_i32(get_field(s
, l1
));
3619 gen_helper_nc(cc_op
, cpu_env
, l
, o
->addr1
, o
->in2
);
3620 tcg_temp_free_i32(l
);
3625 static DisasJumpType
op_neg(DisasContext
*s
, DisasOps
*o
)
3627 tcg_gen_neg_i64(o
->out
, o
->in2
);
3631 static DisasJumpType
op_negf32(DisasContext
*s
, DisasOps
*o
)
3633 tcg_gen_xori_i64(o
->out
, o
->in2
, 0x80000000ull
);
3637 static DisasJumpType
op_negf64(DisasContext
*s
, DisasOps
*o
)
3639 tcg_gen_xori_i64(o
->out
, o
->in2
, 0x8000000000000000ull
);
3643 static DisasJumpType
op_negf128(DisasContext
*s
, DisasOps
*o
)
3645 tcg_gen_xori_i64(o
->out
, o
->in1
, 0x8000000000000000ull
);
3646 tcg_gen_mov_i64(o
->out2
, o
->in2
);
3650 static DisasJumpType
op_oc(DisasContext
*s
, DisasOps
*o
)
3652 TCGv_i32 l
= tcg_const_i32(get_field(s
, l1
));
3653 gen_helper_oc(cc_op
, cpu_env
, l
, o
->addr1
, o
->in2
);
3654 tcg_temp_free_i32(l
);
3659 static DisasJumpType
op_or(DisasContext
*s
, DisasOps
*o
)
3661 tcg_gen_or_i64(o
->out
, o
->in1
, o
->in2
);
3665 static DisasJumpType
op_ori(DisasContext
*s
, DisasOps
*o
)
3667 int shift
= s
->insn
->data
& 0xff;
3668 int size
= s
->insn
->data
>> 8;
3669 uint64_t mask
= ((1ull << size
) - 1) << shift
;
3672 tcg_gen_shli_i64(o
->in2
, o
->in2
, shift
);
3673 tcg_gen_or_i64(o
->out
, o
->in1
, o
->in2
);
3675 /* Produce the CC from only the bits manipulated. */
3676 tcg_gen_andi_i64(cc_dst
, o
->out
, mask
);
3677 set_cc_nz_u64(s
, cc_dst
);
3681 static DisasJumpType
op_oi(DisasContext
*s
, DisasOps
*o
)
3683 o
->in1
= tcg_temp_new_i64();
3685 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2
)) {
3686 tcg_gen_qemu_ld_tl(o
->in1
, o
->addr1
, get_mem_index(s
), s
->insn
->data
);
3688 /* Perform the atomic operation in memory. */
3689 tcg_gen_atomic_fetch_or_i64(o
->in1
, o
->addr1
, o
->in2
, get_mem_index(s
),
3693 /* Recompute also for atomic case: needed for setting CC. */
3694 tcg_gen_or_i64(o
->out
, o
->in1
, o
->in2
);
3696 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2
)) {
3697 tcg_gen_qemu_st_tl(o
->out
, o
->addr1
, get_mem_index(s
), s
->insn
->data
);
3702 static DisasJumpType
op_pack(DisasContext
*s
, DisasOps
*o
)
3704 TCGv_i32 l
= tcg_const_i32(get_field(s
, l1
));
3705 gen_helper_pack(cpu_env
, l
, o
->addr1
, o
->in2
);
3706 tcg_temp_free_i32(l
);
3710 static DisasJumpType
op_pka(DisasContext
*s
, DisasOps
*o
)
3712 int l2
= get_field(s
, l2
) + 1;
3715 /* The length must not exceed 32 bytes. */
3717 gen_program_exception(s
, PGM_SPECIFICATION
);
3718 return DISAS_NORETURN
;
3720 l
= tcg_const_i32(l2
);
3721 gen_helper_pka(cpu_env
, o
->addr1
, o
->in2
, l
);
3722 tcg_temp_free_i32(l
);
3726 static DisasJumpType
op_pku(DisasContext
*s
, DisasOps
*o
)
3728 int l2
= get_field(s
, l2
) + 1;
3731 /* The length must be even and should not exceed 64 bytes. */
3732 if ((l2
& 1) || (l2
> 64)) {
3733 gen_program_exception(s
, PGM_SPECIFICATION
);
3734 return DISAS_NORETURN
;
3736 l
= tcg_const_i32(l2
);
3737 gen_helper_pku(cpu_env
, o
->addr1
, o
->in2
, l
);
3738 tcg_temp_free_i32(l
);
3742 static DisasJumpType
op_popcnt(DisasContext
*s
, DisasOps
*o
)
3744 gen_helper_popcnt(o
->out
, o
->in2
);
3748 #ifndef CONFIG_USER_ONLY
3749 static DisasJumpType
op_ptlb(DisasContext
*s
, DisasOps
*o
)
3751 gen_helper_ptlb(cpu_env
);
3756 static DisasJumpType
op_risbg(DisasContext
*s
, DisasOps
*o
)
3758 int i3
= get_field(s
, i3
);
3759 int i4
= get_field(s
, i4
);
3760 int i5
= get_field(s
, i5
);
3761 int do_zero
= i4
& 0x80;
3762 uint64_t mask
, imask
, pmask
;
3765 /* Adjust the arguments for the specific insn. */
3766 switch (s
->fields
.op2
) {
3767 case 0x55: /* risbg */
3768 case 0x59: /* risbgn */
3773 case 0x5d: /* risbhg */
3776 pmask
= 0xffffffff00000000ull
;
3778 case 0x51: /* risblg */
3781 pmask
= 0x00000000ffffffffull
;
3784 g_assert_not_reached();
3787 /* MASK is the set of bits to be inserted from R2.
3788 Take care for I3/I4 wraparound. */
3791 mask
^= pmask
>> i4
>> 1;
3793 mask
|= ~(pmask
>> i4
>> 1);
3797 /* IMASK is the set of bits to be kept from R1. In the case of the high/low
3798 insns, we need to keep the other half of the register. */
3799 imask
= ~mask
| ~pmask
;
3807 if (s
->fields
.op2
== 0x5d) {
3811 /* In some cases we can implement this with extract. */
3812 if (imask
== 0 && pos
== 0 && len
> 0 && len
<= rot
) {
3813 tcg_gen_extract_i64(o
->out
, o
->in2
, 64 - rot
, len
);
3817 /* In some cases we can implement this with deposit. */
3818 if (len
> 0 && (imask
== 0 || ~mask
== imask
)) {
3819 /* Note that we rotate the bits to be inserted to the lsb, not to
3820 the position as described in the PoO. */
3821 rot
= (rot
- pos
) & 63;
3826 /* Rotate the input as necessary. */
3827 tcg_gen_rotli_i64(o
->in2
, o
->in2
, rot
);
3829 /* Insert the selected bits into the output. */
3832 tcg_gen_deposit_z_i64(o
->out
, o
->in2
, pos
, len
);
3834 tcg_gen_deposit_i64(o
->out
, o
->out
, o
->in2
, pos
, len
);
3836 } else if (imask
== 0) {
3837 tcg_gen_andi_i64(o
->out
, o
->in2
, mask
);
3839 tcg_gen_andi_i64(o
->in2
, o
->in2
, mask
);
3840 tcg_gen_andi_i64(o
->out
, o
->out
, imask
);
3841 tcg_gen_or_i64(o
->out
, o
->out
, o
->in2
);
3846 static DisasJumpType
op_rosbg(DisasContext
*s
, DisasOps
*o
)
3848 int i3
= get_field(s
, i3
);
3849 int i4
= get_field(s
, i4
);
3850 int i5
= get_field(s
, i5
);
3853 /* If this is a test-only form, arrange to discard the result. */
3855 o
->out
= tcg_temp_new_i64();
3863 /* MASK is the set of bits to be operated on from R2.
3864 Take care for I3/I4 wraparound. */
3867 mask
^= ~0ull >> i4
>> 1;
3869 mask
|= ~(~0ull >> i4
>> 1);
3872 /* Rotate the input as necessary. */
3873 tcg_gen_rotli_i64(o
->in2
, o
->in2
, i5
);
3876 switch (s
->fields
.op2
) {
3877 case 0x55: /* AND */
3878 tcg_gen_ori_i64(o
->in2
, o
->in2
, ~mask
);
3879 tcg_gen_and_i64(o
->out
, o
->out
, o
->in2
);
3882 tcg_gen_andi_i64(o
->in2
, o
->in2
, mask
);
3883 tcg_gen_or_i64(o
->out
, o
->out
, o
->in2
);
3885 case 0x57: /* XOR */
3886 tcg_gen_andi_i64(o
->in2
, o
->in2
, mask
);
3887 tcg_gen_xor_i64(o
->out
, o
->out
, o
->in2
);
3894 tcg_gen_andi_i64(cc_dst
, o
->out
, mask
);
3895 set_cc_nz_u64(s
, cc_dst
);
3899 static DisasJumpType
op_rev16(DisasContext
*s
, DisasOps
*o
)
3901 tcg_gen_bswap16_i64(o
->out
, o
->in2
);
3905 static DisasJumpType
op_rev32(DisasContext
*s
, DisasOps
*o
)
3907 tcg_gen_bswap32_i64(o
->out
, o
->in2
);
3911 static DisasJumpType
op_rev64(DisasContext
*s
, DisasOps
*o
)
3913 tcg_gen_bswap64_i64(o
->out
, o
->in2
);
3917 static DisasJumpType
op_rll32(DisasContext
*s
, DisasOps
*o
)
3919 TCGv_i32 t1
= tcg_temp_new_i32();
3920 TCGv_i32 t2
= tcg_temp_new_i32();
3921 TCGv_i32 to
= tcg_temp_new_i32();
3922 tcg_gen_extrl_i64_i32(t1
, o
->in1
);
3923 tcg_gen_extrl_i64_i32(t2
, o
->in2
);
3924 tcg_gen_rotl_i32(to
, t1
, t2
);
3925 tcg_gen_extu_i32_i64(o
->out
, to
);
3926 tcg_temp_free_i32(t1
);
3927 tcg_temp_free_i32(t2
);
3928 tcg_temp_free_i32(to
);
3932 static DisasJumpType
op_rll64(DisasContext
*s
, DisasOps
*o
)
3934 tcg_gen_rotl_i64(o
->out
, o
->in1
, o
->in2
);
3938 #ifndef CONFIG_USER_ONLY
3939 static DisasJumpType
op_rrbe(DisasContext
*s
, DisasOps
*o
)
3941 gen_helper_rrbe(cc_op
, cpu_env
, o
->in2
);
3946 static DisasJumpType
op_sacf(DisasContext
*s
, DisasOps
*o
)
3948 gen_helper_sacf(cpu_env
, o
->in2
);
3949 /* Addressing mode has changed, so end the block. */
3950 return DISAS_PC_STALE
;
3954 static DisasJumpType
op_sam(DisasContext
*s
, DisasOps
*o
)
3956 int sam
= s
->insn
->data
;
3972 /* Bizarre but true, we check the address of the current insn for the
3973 specification exception, not the next to be executed. Thus the PoO
3974 documents that Bad Things Happen two bytes before the end. */
3975 if (s
->base
.pc_next
& ~mask
) {
3976 gen_program_exception(s
, PGM_SPECIFICATION
);
3977 return DISAS_NORETURN
;
3981 tsam
= tcg_const_i64(sam
);
3982 tcg_gen_deposit_i64(psw_mask
, psw_mask
, tsam
, 31, 2);
3983 tcg_temp_free_i64(tsam
);
3985 /* Always exit the TB, since we (may have) changed execution mode. */
3986 return DISAS_PC_STALE
;
3989 static DisasJumpType
op_sar(DisasContext
*s
, DisasOps
*o
)
3991 int r1
= get_field(s
, r1
);
3992 tcg_gen_st32_i64(o
->in2
, cpu_env
, offsetof(CPUS390XState
, aregs
[r1
]));
3996 static DisasJumpType
op_seb(DisasContext
*s
, DisasOps
*o
)
3998 gen_helper_seb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
4002 static DisasJumpType
op_sdb(DisasContext
*s
, DisasOps
*o
)
4004 gen_helper_sdb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
4008 static DisasJumpType
op_sxb(DisasContext
*s
, DisasOps
*o
)
4010 gen_helper_sxb(o
->out
, cpu_env
, o
->out
, o
->out2
, o
->in1
, o
->in2
);
4011 return_low128(o
->out2
);
4015 static DisasJumpType
op_sqeb(DisasContext
*s
, DisasOps
*o
)
4017 gen_helper_sqeb(o
->out
, cpu_env
, o
->in2
);
4021 static DisasJumpType
op_sqdb(DisasContext
*s
, DisasOps
*o
)
4023 gen_helper_sqdb(o
->out
, cpu_env
, o
->in2
);
4027 static DisasJumpType
op_sqxb(DisasContext
*s
, DisasOps
*o
)
4029 gen_helper_sqxb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
4030 return_low128(o
->out2
);
4034 #ifndef CONFIG_USER_ONLY
4035 static DisasJumpType
op_servc(DisasContext
*s
, DisasOps
*o
)
4037 gen_helper_servc(cc_op
, cpu_env
, o
->in2
, o
->in1
);
4042 static DisasJumpType
op_sigp(DisasContext
*s
, DisasOps
*o
)
4044 TCGv_i32 r1
= tcg_const_i32(get_field(s
, r1
));
4045 TCGv_i32 r3
= tcg_const_i32(get_field(s
, r3
));
4046 gen_helper_sigp(cc_op
, cpu_env
, o
->in2
, r1
, r3
);
4048 tcg_temp_free_i32(r1
);
4049 tcg_temp_free_i32(r3
);
4054 static DisasJumpType
op_soc(DisasContext
*s
, DisasOps
*o
)
4061 disas_jcc(s
, &c
, get_field(s
, m3
));
4063 /* We want to store when the condition is fulfilled, so branch
4064 out when it's not */
4065 c
.cond
= tcg_invert_cond(c
.cond
);
4067 lab
= gen_new_label();
4069 tcg_gen_brcond_i64(c
.cond
, c
.u
.s64
.a
, c
.u
.s64
.b
, lab
);
4071 tcg_gen_brcond_i32(c
.cond
, c
.u
.s32
.a
, c
.u
.s32
.b
, lab
);
4075 r1
= get_field(s
, r1
);
4076 a
= get_address(s
, 0, get_field(s
, b2
), get_field(s
, d2
));
4077 switch (s
->insn
->data
) {
4079 tcg_gen_qemu_st64(regs
[r1
], a
, get_mem_index(s
));
4082 tcg_gen_qemu_st32(regs
[r1
], a
, get_mem_index(s
));
4084 case 2: /* STOCFH */
4085 h
= tcg_temp_new_i64();
4086 tcg_gen_shri_i64(h
, regs
[r1
], 32);
4087 tcg_gen_qemu_st32(h
, a
, get_mem_index(s
));
4088 tcg_temp_free_i64(h
);
4091 g_assert_not_reached();
4093 tcg_temp_free_i64(a
);
4099 static DisasJumpType
op_sla(DisasContext
*s
, DisasOps
*o
)
4101 uint64_t sign
= 1ull << s
->insn
->data
;
4102 enum cc_op cco
= s
->insn
->data
== 31 ? CC_OP_SLA_32
: CC_OP_SLA_64
;
4103 gen_op_update2_cc_i64(s
, cco
, o
->in1
, o
->in2
);
4104 tcg_gen_shl_i64(o
->out
, o
->in1
, o
->in2
);
4105 /* The arithmetic left shift is curious in that it does not affect
4106 the sign bit. Copy that over from the source unchanged. */
4107 tcg_gen_andi_i64(o
->out
, o
->out
, ~sign
);
4108 tcg_gen_andi_i64(o
->in1
, o
->in1
, sign
);
4109 tcg_gen_or_i64(o
->out
, o
->out
, o
->in1
);
4113 static DisasJumpType
op_sll(DisasContext
*s
, DisasOps
*o
)
4115 tcg_gen_shl_i64(o
->out
, o
->in1
, o
->in2
);
4119 static DisasJumpType
op_sra(DisasContext
*s
, DisasOps
*o
)
4121 tcg_gen_sar_i64(o
->out
, o
->in1
, o
->in2
);
4125 static DisasJumpType
op_srl(DisasContext
*s
, DisasOps
*o
)
4127 tcg_gen_shr_i64(o
->out
, o
->in1
, o
->in2
);
4131 static DisasJumpType
op_sfpc(DisasContext
*s
, DisasOps
*o
)
4133 gen_helper_sfpc(cpu_env
, o
->in2
);
4137 static DisasJumpType
op_sfas(DisasContext
*s
, DisasOps
*o
)
4139 gen_helper_sfas(cpu_env
, o
->in2
);
4143 static DisasJumpType
op_srnm(DisasContext
*s
, DisasOps
*o
)
4145 /* Bits other than 62 and 63 are ignored. Bit 29 is set to zero. */
4146 tcg_gen_andi_i64(o
->addr1
, o
->addr1
, 0x3ull
);
4147 gen_helper_srnm(cpu_env
, o
->addr1
);
4151 static DisasJumpType
op_srnmb(DisasContext
*s
, DisasOps
*o
)
4153 /* Bits 0-55 are are ignored. */
4154 tcg_gen_andi_i64(o
->addr1
, o
->addr1
, 0xffull
);
4155 gen_helper_srnm(cpu_env
, o
->addr1
);
4159 static DisasJumpType
op_srnmt(DisasContext
*s
, DisasOps
*o
)
4161 TCGv_i64 tmp
= tcg_temp_new_i64();
4163 /* Bits other than 61-63 are ignored. */
4164 tcg_gen_andi_i64(o
->addr1
, o
->addr1
, 0x7ull
);
4166 /* No need to call a helper, we don't implement dfp */
4167 tcg_gen_ld32u_i64(tmp
, cpu_env
, offsetof(CPUS390XState
, fpc
));
4168 tcg_gen_deposit_i64(tmp
, tmp
, o
->addr1
, 4, 3);
4169 tcg_gen_st32_i64(tmp
, cpu_env
, offsetof(CPUS390XState
, fpc
));
4171 tcg_temp_free_i64(tmp
);
4175 static DisasJumpType
op_spm(DisasContext
*s
, DisasOps
*o
)
4177 tcg_gen_extrl_i64_i32(cc_op
, o
->in1
);
4178 tcg_gen_extract_i32(cc_op
, cc_op
, 28, 2);
4181 tcg_gen_shri_i64(o
->in1
, o
->in1
, 24);
4182 tcg_gen_deposit_i64(psw_mask
, psw_mask
, o
->in1
, PSW_SHIFT_MASK_PM
, 4);
4186 static DisasJumpType
op_ectg(DisasContext
*s
, DisasOps
*o
)
4188 int b1
= get_field(s
, b1
);
4189 int d1
= get_field(s
, d1
);
4190 int b2
= get_field(s
, b2
);
4191 int d2
= get_field(s
, d2
);
4192 int r3
= get_field(s
, r3
);
4193 TCGv_i64 tmp
= tcg_temp_new_i64();
4195 /* fetch all operands first */
4196 o
->in1
= tcg_temp_new_i64();
4197 tcg_gen_addi_i64(o
->in1
, regs
[b1
], d1
);
4198 o
->in2
= tcg_temp_new_i64();
4199 tcg_gen_addi_i64(o
->in2
, regs
[b2
], d2
);
4200 o
->addr1
= get_address(s
, 0, r3
, 0);
4202 /* load the third operand into r3 before modifying anything */
4203 tcg_gen_qemu_ld64(regs
[r3
], o
->addr1
, get_mem_index(s
));
4205 /* subtract CPU timer from first operand and store in GR0 */
4206 gen_helper_stpt(tmp
, cpu_env
);
4207 tcg_gen_sub_i64(regs
[0], o
->in1
, tmp
);
4209 /* store second operand in GR1 */
4210 tcg_gen_mov_i64(regs
[1], o
->in2
);
4212 tcg_temp_free_i64(tmp
);
4216 #ifndef CONFIG_USER_ONLY
4217 static DisasJumpType
op_spka(DisasContext
*s
, DisasOps
*o
)
4219 tcg_gen_shri_i64(o
->in2
, o
->in2
, 4);
4220 tcg_gen_deposit_i64(psw_mask
, psw_mask
, o
->in2
, PSW_SHIFT_KEY
, 4);
4224 static DisasJumpType
op_sske(DisasContext
*s
, DisasOps
*o
)
4226 gen_helper_sske(cpu_env
, o
->in1
, o
->in2
);
4230 static DisasJumpType
op_ssm(DisasContext
*s
, DisasOps
*o
)
4232 tcg_gen_deposit_i64(psw_mask
, psw_mask
, o
->in2
, 56, 8);
4233 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
4234 return DISAS_PC_STALE_NOCHAIN
;
4237 static DisasJumpType
op_stap(DisasContext
*s
, DisasOps
*o
)
4239 tcg_gen_ld32u_i64(o
->out
, cpu_env
, offsetof(CPUS390XState
, core_id
));
4244 static DisasJumpType
op_stck(DisasContext
*s
, DisasOps
*o
)
4246 gen_helper_stck(o
->out
, cpu_env
);
4247 /* ??? We don't implement clock states. */
4248 gen_op_movi_cc(s
, 0);
4252 static DisasJumpType
op_stcke(DisasContext
*s
, DisasOps
*o
)
4254 TCGv_i64 c1
= tcg_temp_new_i64();
4255 TCGv_i64 c2
= tcg_temp_new_i64();
4256 TCGv_i64 todpr
= tcg_temp_new_i64();
4257 gen_helper_stck(c1
, cpu_env
);
4258 /* 16 bit value store in an uint32_t (only valid bits set) */
4259 tcg_gen_ld32u_i64(todpr
, cpu_env
, offsetof(CPUS390XState
, todpr
));
4260 /* Shift the 64-bit value into its place as a zero-extended
4261 104-bit value. Note that "bit positions 64-103 are always
4262 non-zero so that they compare differently to STCK"; we set
4263 the least significant bit to 1. */
4264 tcg_gen_shli_i64(c2
, c1
, 56);
4265 tcg_gen_shri_i64(c1
, c1
, 8);
4266 tcg_gen_ori_i64(c2
, c2
, 0x10000);
4267 tcg_gen_or_i64(c2
, c2
, todpr
);
4268 tcg_gen_qemu_st64(c1
, o
->in2
, get_mem_index(s
));
4269 tcg_gen_addi_i64(o
->in2
, o
->in2
, 8);
4270 tcg_gen_qemu_st64(c2
, o
->in2
, get_mem_index(s
));
4271 tcg_temp_free_i64(c1
);
4272 tcg_temp_free_i64(c2
);
4273 tcg_temp_free_i64(todpr
);
4274 /* ??? We don't implement clock states. */
4275 gen_op_movi_cc(s
, 0);
4279 #ifndef CONFIG_USER_ONLY
4280 static DisasJumpType
op_sck(DisasContext
*s
, DisasOps
*o
)
4282 tcg_gen_qemu_ld_i64(o
->in1
, o
->addr1
, get_mem_index(s
), MO_TEQ
| MO_ALIGN
);
4283 gen_helper_sck(cc_op
, cpu_env
, o
->in1
);
4288 static DisasJumpType
op_sckc(DisasContext
*s
, DisasOps
*o
)
4290 gen_helper_sckc(cpu_env
, o
->in2
);
4294 static DisasJumpType
op_sckpf(DisasContext
*s
, DisasOps
*o
)
4296 gen_helper_sckpf(cpu_env
, regs
[0]);
4300 static DisasJumpType
op_stckc(DisasContext
*s
, DisasOps
*o
)
4302 gen_helper_stckc(o
->out
, cpu_env
);
4306 static DisasJumpType
op_stctg(DisasContext
*s
, DisasOps
*o
)
4308 TCGv_i32 r1
= tcg_const_i32(get_field(s
, r1
));
4309 TCGv_i32 r3
= tcg_const_i32(get_field(s
, r3
));
4310 gen_helper_stctg(cpu_env
, r1
, o
->in2
, r3
);
4311 tcg_temp_free_i32(r1
);
4312 tcg_temp_free_i32(r3
);
4316 static DisasJumpType
op_stctl(DisasContext
*s
, DisasOps
*o
)
4318 TCGv_i32 r1
= tcg_const_i32(get_field(s
, r1
));
4319 TCGv_i32 r3
= tcg_const_i32(get_field(s
, r3
));
4320 gen_helper_stctl(cpu_env
, r1
, o
->in2
, r3
);
4321 tcg_temp_free_i32(r1
);
4322 tcg_temp_free_i32(r3
);
4326 static DisasJumpType
op_stidp(DisasContext
*s
, DisasOps
*o
)
4328 tcg_gen_ld_i64(o
->out
, cpu_env
, offsetof(CPUS390XState
, cpuid
));
4332 static DisasJumpType
op_spt(DisasContext
*s
, DisasOps
*o
)
4334 gen_helper_spt(cpu_env
, o
->in2
);
4338 static DisasJumpType
op_stfl(DisasContext
*s
, DisasOps
*o
)
4340 gen_helper_stfl(cpu_env
);
4344 static DisasJumpType
op_stpt(DisasContext
*s
, DisasOps
*o
)
4346 gen_helper_stpt(o
->out
, cpu_env
);
4350 static DisasJumpType
op_stsi(DisasContext
*s
, DisasOps
*o
)
4352 gen_helper_stsi(cc_op
, cpu_env
, o
->in2
, regs
[0], regs
[1]);
4357 static DisasJumpType
op_spx(DisasContext
*s
, DisasOps
*o
)
4359 gen_helper_spx(cpu_env
, o
->in2
);
4363 static DisasJumpType
op_xsch(DisasContext
*s
, DisasOps
*o
)
4365 gen_helper_xsch(cpu_env
, regs
[1]);
4370 static DisasJumpType
op_csch(DisasContext
*s
, DisasOps
*o
)
4372 gen_helper_csch(cpu_env
, regs
[1]);
4377 static DisasJumpType
op_hsch(DisasContext
*s
, DisasOps
*o
)
4379 gen_helper_hsch(cpu_env
, regs
[1]);
4384 static DisasJumpType
op_msch(DisasContext
*s
, DisasOps
*o
)
4386 gen_helper_msch(cpu_env
, regs
[1], o
->in2
);
4391 static DisasJumpType
op_rchp(DisasContext
*s
, DisasOps
*o
)
4393 gen_helper_rchp(cpu_env
, regs
[1]);
4398 static DisasJumpType
op_rsch(DisasContext
*s
, DisasOps
*o
)
4400 gen_helper_rsch(cpu_env
, regs
[1]);
4405 static DisasJumpType
op_sal(DisasContext
*s
, DisasOps
*o
)
4407 gen_helper_sal(cpu_env
, regs
[1]);
4411 static DisasJumpType
op_schm(DisasContext
*s
, DisasOps
*o
)
4413 gen_helper_schm(cpu_env
, regs
[1], regs
[2], o
->in2
);
4417 static DisasJumpType
op_siga(DisasContext
*s
, DisasOps
*o
)
4419 /* From KVM code: Not provided, set CC = 3 for subchannel not operational */
4420 gen_op_movi_cc(s
, 3);
4424 static DisasJumpType
op_stcps(DisasContext
*s
, DisasOps
*o
)
4426 /* The instruction is suppressed if not provided. */
4430 static DisasJumpType
op_ssch(DisasContext
*s
, DisasOps
*o
)
4432 gen_helper_ssch(cpu_env
, regs
[1], o
->in2
);
4437 static DisasJumpType
op_stsch(DisasContext
*s
, DisasOps
*o
)
4439 gen_helper_stsch(cpu_env
, regs
[1], o
->in2
);
4444 static DisasJumpType
op_stcrw(DisasContext
*s
, DisasOps
*o
)
4446 gen_helper_stcrw(cpu_env
, o
->in2
);
4451 static DisasJumpType
op_tpi(DisasContext
*s
, DisasOps
*o
)
4453 gen_helper_tpi(cc_op
, cpu_env
, o
->addr1
);
4458 static DisasJumpType
op_tsch(DisasContext
*s
, DisasOps
*o
)
4460 gen_helper_tsch(cpu_env
, regs
[1], o
->in2
);
4465 static DisasJumpType
op_chsc(DisasContext
*s
, DisasOps
*o
)
4467 gen_helper_chsc(cpu_env
, o
->in2
);
4472 static DisasJumpType
op_stpx(DisasContext
*s
, DisasOps
*o
)
4474 tcg_gen_ld_i64(o
->out
, cpu_env
, offsetof(CPUS390XState
, psa
));
4475 tcg_gen_andi_i64(o
->out
, o
->out
, 0x7fffe000);
4479 static DisasJumpType
op_stnosm(DisasContext
*s
, DisasOps
*o
)
4481 uint64_t i2
= get_field(s
, i2
);
4484 /* It is important to do what the instruction name says: STORE THEN.
4485 If we let the output hook perform the store then if we fault and
4486 restart, we'll have the wrong SYSTEM MASK in place. */
4487 t
= tcg_temp_new_i64();
4488 tcg_gen_shri_i64(t
, psw_mask
, 56);
4489 tcg_gen_qemu_st8(t
, o
->addr1
, get_mem_index(s
));
4490 tcg_temp_free_i64(t
);
4492 if (s
->fields
.op
== 0xac) {
4493 tcg_gen_andi_i64(psw_mask
, psw_mask
,
4494 (i2
<< 56) | 0x00ffffffffffffffull
);
4496 tcg_gen_ori_i64(psw_mask
, psw_mask
, i2
<< 56);
4499 /* Exit to main loop to reevaluate s390_cpu_exec_interrupt. */
4500 return DISAS_PC_STALE_NOCHAIN
;
4503 static DisasJumpType
op_stura(DisasContext
*s
, DisasOps
*o
)
4505 o
->addr1
= get_address(s
, 0, get_field(s
, r2
), 0);
4506 tcg_gen_qemu_st_tl(o
->in1
, o
->addr1
, MMU_REAL_IDX
, s
->insn
->data
);
4508 if (s
->base
.tb
->flags
& FLAG_MASK_PER
) {
4510 gen_helper_per_store_real(cpu_env
);
4516 static DisasJumpType
op_stfle(DisasContext
*s
, DisasOps
*o
)
4518 gen_helper_stfle(cc_op
, cpu_env
, o
->in2
);
4523 static DisasJumpType
op_st8(DisasContext
*s
, DisasOps
*o
)
4525 tcg_gen_qemu_st8(o
->in1
, o
->in2
, get_mem_index(s
));
4529 static DisasJumpType
op_st16(DisasContext
*s
, DisasOps
*o
)
4531 tcg_gen_qemu_st16(o
->in1
, o
->in2
, get_mem_index(s
));
4535 static DisasJumpType
op_st32(DisasContext
*s
, DisasOps
*o
)
4537 tcg_gen_qemu_st32(o
->in1
, o
->in2
, get_mem_index(s
));
4541 static DisasJumpType
op_st64(DisasContext
*s
, DisasOps
*o
)
4543 tcg_gen_qemu_st64(o
->in1
, o
->in2
, get_mem_index(s
));
4547 static DisasJumpType
op_stam(DisasContext
*s
, DisasOps
*o
)
4549 TCGv_i32 r1
= tcg_const_i32(get_field(s
, r1
));
4550 TCGv_i32 r3
= tcg_const_i32(get_field(s
, r3
));
4551 gen_helper_stam(cpu_env
, r1
, o
->in2
, r3
);
4552 tcg_temp_free_i32(r1
);
4553 tcg_temp_free_i32(r3
);
4557 static DisasJumpType
op_stcm(DisasContext
*s
, DisasOps
*o
)
4559 int m3
= get_field(s
, m3
);
4560 int pos
, base
= s
->insn
->data
;
4561 TCGv_i64 tmp
= tcg_temp_new_i64();
4563 pos
= base
+ ctz32(m3
) * 8;
4566 /* Effectively a 32-bit store. */
4567 tcg_gen_shri_i64(tmp
, o
->in1
, pos
);
4568 tcg_gen_qemu_st32(tmp
, o
->in2
, get_mem_index(s
));
4574 /* Effectively a 16-bit store. */
4575 tcg_gen_shri_i64(tmp
, o
->in1
, pos
);
4576 tcg_gen_qemu_st16(tmp
, o
->in2
, get_mem_index(s
));
4583 /* Effectively an 8-bit store. */
4584 tcg_gen_shri_i64(tmp
, o
->in1
, pos
);
4585 tcg_gen_qemu_st8(tmp
, o
->in2
, get_mem_index(s
));
4589 /* This is going to be a sequence of shifts and stores. */
4590 pos
= base
+ 32 - 8;
4593 tcg_gen_shri_i64(tmp
, o
->in1
, pos
);
4594 tcg_gen_qemu_st8(tmp
, o
->in2
, get_mem_index(s
));
4595 tcg_gen_addi_i64(o
->in2
, o
->in2
, 1);
4597 m3
= (m3
<< 1) & 0xf;
4602 tcg_temp_free_i64(tmp
);
4606 static DisasJumpType
op_stm(DisasContext
*s
, DisasOps
*o
)
4608 int r1
= get_field(s
, r1
);
4609 int r3
= get_field(s
, r3
);
4610 int size
= s
->insn
->data
;
4611 TCGv_i64 tsize
= tcg_const_i64(size
);
4615 tcg_gen_qemu_st64(regs
[r1
], o
->in2
, get_mem_index(s
));
4617 tcg_gen_qemu_st32(regs
[r1
], o
->in2
, get_mem_index(s
));
4622 tcg_gen_add_i64(o
->in2
, o
->in2
, tsize
);
4626 tcg_temp_free_i64(tsize
);
4630 static DisasJumpType
op_stmh(DisasContext
*s
, DisasOps
*o
)
4632 int r1
= get_field(s
, r1
);
4633 int r3
= get_field(s
, r3
);
4634 TCGv_i64 t
= tcg_temp_new_i64();
4635 TCGv_i64 t4
= tcg_const_i64(4);
4636 TCGv_i64 t32
= tcg_const_i64(32);
4639 tcg_gen_shl_i64(t
, regs
[r1
], t32
);
4640 tcg_gen_qemu_st32(t
, o
->in2
, get_mem_index(s
));
4644 tcg_gen_add_i64(o
->in2
, o
->in2
, t4
);
4648 tcg_temp_free_i64(t
);
4649 tcg_temp_free_i64(t4
);
4650 tcg_temp_free_i64(t32
);
4654 static DisasJumpType
op_stpq(DisasContext
*s
, DisasOps
*o
)
4656 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
4657 gen_helper_stpq(cpu_env
, o
->in2
, o
->out2
, o
->out
);
4658 } else if (HAVE_ATOMIC128
) {
4659 gen_helper_stpq_parallel(cpu_env
, o
->in2
, o
->out2
, o
->out
);
4661 gen_helper_exit_atomic(cpu_env
);
4662 return DISAS_NORETURN
;
4667 static DisasJumpType
op_srst(DisasContext
*s
, DisasOps
*o
)
4669 TCGv_i32 r1
= tcg_const_i32(get_field(s
, r1
));
4670 TCGv_i32 r2
= tcg_const_i32(get_field(s
, r2
));
4672 gen_helper_srst(cpu_env
, r1
, r2
);
4674 tcg_temp_free_i32(r1
);
4675 tcg_temp_free_i32(r2
);
4680 static DisasJumpType
op_srstu(DisasContext
*s
, DisasOps
*o
)
4682 TCGv_i32 r1
= tcg_const_i32(get_field(s
, r1
));
4683 TCGv_i32 r2
= tcg_const_i32(get_field(s
, r2
));
4685 gen_helper_srstu(cpu_env
, r1
, r2
);
4687 tcg_temp_free_i32(r1
);
4688 tcg_temp_free_i32(r2
);
4693 static DisasJumpType
op_sub(DisasContext
*s
, DisasOps
*o
)
4695 tcg_gen_sub_i64(o
->out
, o
->in1
, o
->in2
);
4699 static DisasJumpType
op_subb(DisasContext
*s
, DisasOps
*o
)
4704 tcg_gen_sub_i64(o
->out
, o
->in1
, o
->in2
);
4706 /* The !borrow flag is the msb of CC. Since we want the inverse of
4707 that, we ask for a comparison of CC=0 | CC=1 -> mask of 8 | 4. */
4708 disas_jcc(s
, &cmp
, 8 | 4);
4709 borrow
= tcg_temp_new_i64();
4711 tcg_gen_setcond_i64(cmp
.cond
, borrow
, cmp
.u
.s64
.a
, cmp
.u
.s64
.b
);
4713 TCGv_i32 t
= tcg_temp_new_i32();
4714 tcg_gen_setcond_i32(cmp
.cond
, t
, cmp
.u
.s32
.a
, cmp
.u
.s32
.b
);
4715 tcg_gen_extu_i32_i64(borrow
, t
);
4716 tcg_temp_free_i32(t
);
4720 tcg_gen_sub_i64(o
->out
, o
->out
, borrow
);
4721 tcg_temp_free_i64(borrow
);
4725 static DisasJumpType
op_svc(DisasContext
*s
, DisasOps
*o
)
4732 t
= tcg_const_i32(get_field(s
, i1
) & 0xff);
4733 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUS390XState
, int_svc_code
));
4734 tcg_temp_free_i32(t
);
4736 t
= tcg_const_i32(s
->ilen
);
4737 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUS390XState
, int_svc_ilen
));
4738 tcg_temp_free_i32(t
);
4740 gen_exception(EXCP_SVC
);
4741 return DISAS_NORETURN
;
4744 static DisasJumpType
op_tam(DisasContext
*s
, DisasOps
*o
)
4748 cc
|= (s
->base
.tb
->flags
& FLAG_MASK_64
) ? 2 : 0;
4749 cc
|= (s
->base
.tb
->flags
& FLAG_MASK_32
) ? 1 : 0;
4750 gen_op_movi_cc(s
, cc
);
4754 static DisasJumpType
op_tceb(DisasContext
*s
, DisasOps
*o
)
4756 gen_helper_tceb(cc_op
, cpu_env
, o
->in1
, o
->in2
);
4761 static DisasJumpType
op_tcdb(DisasContext
*s
, DisasOps
*o
)
4763 gen_helper_tcdb(cc_op
, cpu_env
, o
->in1
, o
->in2
);
4768 static DisasJumpType
op_tcxb(DisasContext
*s
, DisasOps
*o
)
4770 gen_helper_tcxb(cc_op
, cpu_env
, o
->out
, o
->out2
, o
->in2
);
4775 #ifndef CONFIG_USER_ONLY
4777 static DisasJumpType
op_testblock(DisasContext
*s
, DisasOps
*o
)
4779 gen_helper_testblock(cc_op
, cpu_env
, o
->in2
);
4784 static DisasJumpType
op_tprot(DisasContext
*s
, DisasOps
*o
)
4786 gen_helper_tprot(cc_op
, cpu_env
, o
->addr1
, o
->in2
);
4793 static DisasJumpType
op_tp(DisasContext
*s
, DisasOps
*o
)
4795 TCGv_i32 l1
= tcg_const_i32(get_field(s
, l1
) + 1);
4796 gen_helper_tp(cc_op
, cpu_env
, o
->addr1
, l1
);
4797 tcg_temp_free_i32(l1
);
4802 static DisasJumpType
op_tr(DisasContext
*s
, DisasOps
*o
)
4804 TCGv_i32 l
= tcg_const_i32(get_field(s
, l1
));
4805 gen_helper_tr(cpu_env
, l
, o
->addr1
, o
->in2
);
4806 tcg_temp_free_i32(l
);
4811 static DisasJumpType
op_tre(DisasContext
*s
, DisasOps
*o
)
4813 gen_helper_tre(o
->out
, cpu_env
, o
->out
, o
->out2
, o
->in2
);
4814 return_low128(o
->out2
);
4819 static DisasJumpType
op_trt(DisasContext
*s
, DisasOps
*o
)
4821 TCGv_i32 l
= tcg_const_i32(get_field(s
, l1
));
4822 gen_helper_trt(cc_op
, cpu_env
, l
, o
->addr1
, o
->in2
);
4823 tcg_temp_free_i32(l
);
4828 static DisasJumpType
op_trtr(DisasContext
*s
, DisasOps
*o
)
4830 TCGv_i32 l
= tcg_const_i32(get_field(s
, l1
));
4831 gen_helper_trtr(cc_op
, cpu_env
, l
, o
->addr1
, o
->in2
);
4832 tcg_temp_free_i32(l
);
4837 static DisasJumpType
op_trXX(DisasContext
*s
, DisasOps
*o
)
4839 TCGv_i32 r1
= tcg_const_i32(get_field(s
, r1
));
4840 TCGv_i32 r2
= tcg_const_i32(get_field(s
, r2
));
4841 TCGv_i32 sizes
= tcg_const_i32(s
->insn
->opc
& 3);
4842 TCGv_i32 tst
= tcg_temp_new_i32();
4843 int m3
= get_field(s
, m3
);
4845 if (!s390_has_feat(S390_FEAT_ETF2_ENH
)) {
4849 tcg_gen_movi_i32(tst
, -1);
4851 tcg_gen_extrl_i64_i32(tst
, regs
[0]);
4852 if (s
->insn
->opc
& 3) {
4853 tcg_gen_ext8u_i32(tst
, tst
);
4855 tcg_gen_ext16u_i32(tst
, tst
);
4858 gen_helper_trXX(cc_op
, cpu_env
, r1
, r2
, tst
, sizes
);
4860 tcg_temp_free_i32(r1
);
4861 tcg_temp_free_i32(r2
);
4862 tcg_temp_free_i32(sizes
);
4863 tcg_temp_free_i32(tst
);
4868 static DisasJumpType
op_ts(DisasContext
*s
, DisasOps
*o
)
4870 TCGv_i32 t1
= tcg_const_i32(0xff);
4871 tcg_gen_atomic_xchg_i32(t1
, o
->in2
, t1
, get_mem_index(s
), MO_UB
);
4872 tcg_gen_extract_i32(cc_op
, t1
, 7, 1);
4873 tcg_temp_free_i32(t1
);
4878 static DisasJumpType
op_unpk(DisasContext
*s
, DisasOps
*o
)
4880 TCGv_i32 l
= tcg_const_i32(get_field(s
, l1
));
4881 gen_helper_unpk(cpu_env
, l
, o
->addr1
, o
->in2
);
4882 tcg_temp_free_i32(l
);
4886 static DisasJumpType
op_unpka(DisasContext
*s
, DisasOps
*o
)
4888 int l1
= get_field(s
, l1
) + 1;
4891 /* The length must not exceed 32 bytes. */
4893 gen_program_exception(s
, PGM_SPECIFICATION
);
4894 return DISAS_NORETURN
;
4896 l
= tcg_const_i32(l1
);
4897 gen_helper_unpka(cc_op
, cpu_env
, o
->addr1
, l
, o
->in2
);
4898 tcg_temp_free_i32(l
);
4903 static DisasJumpType
op_unpku(DisasContext
*s
, DisasOps
*o
)
4905 int l1
= get_field(s
, l1
) + 1;
4908 /* The length must be even and should not exceed 64 bytes. */
4909 if ((l1
& 1) || (l1
> 64)) {
4910 gen_program_exception(s
, PGM_SPECIFICATION
);
4911 return DISAS_NORETURN
;
4913 l
= tcg_const_i32(l1
);
4914 gen_helper_unpku(cc_op
, cpu_env
, o
->addr1
, l
, o
->in2
);
4915 tcg_temp_free_i32(l
);
4921 static DisasJumpType
op_xc(DisasContext
*s
, DisasOps
*o
)
4923 int d1
= get_field(s
, d1
);
4924 int d2
= get_field(s
, d2
);
4925 int b1
= get_field(s
, b1
);
4926 int b2
= get_field(s
, b2
);
4927 int l
= get_field(s
, l1
);
4930 o
->addr1
= get_address(s
, 0, b1
, d1
);
4932 /* If the addresses are identical, this is a store/memset of zero. */
4933 if (b1
== b2
&& d1
== d2
&& (l
+ 1) <= 32) {
4934 o
->in2
= tcg_const_i64(0);
4938 tcg_gen_qemu_st64(o
->in2
, o
->addr1
, get_mem_index(s
));
4941 tcg_gen_addi_i64(o
->addr1
, o
->addr1
, 8);
4945 tcg_gen_qemu_st32(o
->in2
, o
->addr1
, get_mem_index(s
));
4948 tcg_gen_addi_i64(o
->addr1
, o
->addr1
, 4);
4952 tcg_gen_qemu_st16(o
->in2
, o
->addr1
, get_mem_index(s
));
4955 tcg_gen_addi_i64(o
->addr1
, o
->addr1
, 2);
4959 tcg_gen_qemu_st8(o
->in2
, o
->addr1
, get_mem_index(s
));
4961 gen_op_movi_cc(s
, 0);
4965 /* But in general we'll defer to a helper. */
4966 o
->in2
= get_address(s
, 0, b2
, d2
);
4967 t32
= tcg_const_i32(l
);
4968 gen_helper_xc(cc_op
, cpu_env
, t32
, o
->addr1
, o
->in2
);
4969 tcg_temp_free_i32(t32
);
4974 static DisasJumpType
op_xor(DisasContext
*s
, DisasOps
*o
)
4976 tcg_gen_xor_i64(o
->out
, o
->in1
, o
->in2
);
4980 static DisasJumpType
op_xori(DisasContext
*s
, DisasOps
*o
)
4982 int shift
= s
->insn
->data
& 0xff;
4983 int size
= s
->insn
->data
>> 8;
4984 uint64_t mask
= ((1ull << size
) - 1) << shift
;
4987 tcg_gen_shli_i64(o
->in2
, o
->in2
, shift
);
4988 tcg_gen_xor_i64(o
->out
, o
->in1
, o
->in2
);
4990 /* Produce the CC from only the bits manipulated. */
4991 tcg_gen_andi_i64(cc_dst
, o
->out
, mask
);
4992 set_cc_nz_u64(s
, cc_dst
);
4996 static DisasJumpType
op_xi(DisasContext
*s
, DisasOps
*o
)
4998 o
->in1
= tcg_temp_new_i64();
5000 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2
)) {
5001 tcg_gen_qemu_ld_tl(o
->in1
, o
->addr1
, get_mem_index(s
), s
->insn
->data
);
5003 /* Perform the atomic operation in memory. */
5004 tcg_gen_atomic_fetch_xor_i64(o
->in1
, o
->addr1
, o
->in2
, get_mem_index(s
),
5008 /* Recompute also for atomic case: needed for setting CC. */
5009 tcg_gen_xor_i64(o
->out
, o
->in1
, o
->in2
);
5011 if (!s390_has_feat(S390_FEAT_INTERLOCKED_ACCESS_2
)) {
5012 tcg_gen_qemu_st_tl(o
->out
, o
->addr1
, get_mem_index(s
), s
->insn
->data
);
5017 static DisasJumpType
op_zero(DisasContext
*s
, DisasOps
*o
)
5019 o
->out
= tcg_const_i64(0);
5023 static DisasJumpType
op_zero2(DisasContext
*s
, DisasOps
*o
)
5025 o
->out
= tcg_const_i64(0);
5031 #ifndef CONFIG_USER_ONLY
5032 static DisasJumpType
op_clp(DisasContext
*s
, DisasOps
*o
)
5034 TCGv_i32 r2
= tcg_const_i32(get_field(s
, r2
));
5036 gen_helper_clp(cpu_env
, r2
);
5037 tcg_temp_free_i32(r2
);
5042 static DisasJumpType
op_pcilg(DisasContext
*s
, DisasOps
*o
)
5044 TCGv_i32 r1
= tcg_const_i32(get_field(s
, r1
));
5045 TCGv_i32 r2
= tcg_const_i32(get_field(s
, r2
));
5047 gen_helper_pcilg(cpu_env
, r1
, r2
);
5048 tcg_temp_free_i32(r1
);
5049 tcg_temp_free_i32(r2
);
5054 static DisasJumpType
op_pcistg(DisasContext
*s
, DisasOps
*o
)
5056 TCGv_i32 r1
= tcg_const_i32(get_field(s
, r1
));
5057 TCGv_i32 r2
= tcg_const_i32(get_field(s
, r2
));
5059 gen_helper_pcistg(cpu_env
, r1
, r2
);
5060 tcg_temp_free_i32(r1
);
5061 tcg_temp_free_i32(r2
);
5066 static DisasJumpType
op_stpcifc(DisasContext
*s
, DisasOps
*o
)
5068 TCGv_i32 r1
= tcg_const_i32(get_field(s
, r1
));
5069 TCGv_i32 ar
= tcg_const_i32(get_field(s
, b2
));
5071 gen_helper_stpcifc(cpu_env
, r1
, o
->addr1
, ar
);
5072 tcg_temp_free_i32(ar
);
5073 tcg_temp_free_i32(r1
);
5078 static DisasJumpType
op_sic(DisasContext
*s
, DisasOps
*o
)
5080 gen_helper_sic(cpu_env
, o
->in1
, o
->in2
);
5084 static DisasJumpType
op_rpcit(DisasContext
*s
, DisasOps
*o
)
5086 TCGv_i32 r1
= tcg_const_i32(get_field(s
, r1
));
5087 TCGv_i32 r2
= tcg_const_i32(get_field(s
, r2
));
5089 gen_helper_rpcit(cpu_env
, r1
, r2
);
5090 tcg_temp_free_i32(r1
);
5091 tcg_temp_free_i32(r2
);
5096 static DisasJumpType
op_pcistb(DisasContext
*s
, DisasOps
*o
)
5098 TCGv_i32 r1
= tcg_const_i32(get_field(s
, r1
));
5099 TCGv_i32 r3
= tcg_const_i32(get_field(s
, r3
));
5100 TCGv_i32 ar
= tcg_const_i32(get_field(s
, b2
));
5102 gen_helper_pcistb(cpu_env
, r1
, r3
, o
->addr1
, ar
);
5103 tcg_temp_free_i32(ar
);
5104 tcg_temp_free_i32(r1
);
5105 tcg_temp_free_i32(r3
);
5110 static DisasJumpType
op_mpcifc(DisasContext
*s
, DisasOps
*o
)
5112 TCGv_i32 r1
= tcg_const_i32(get_field(s
, r1
));
5113 TCGv_i32 ar
= tcg_const_i32(get_field(s
, b2
));
5115 gen_helper_mpcifc(cpu_env
, r1
, o
->addr1
, ar
);
5116 tcg_temp_free_i32(ar
);
5117 tcg_temp_free_i32(r1
);
5123 #include "translate_vx.inc.c"
5125 /* ====================================================================== */
5126 /* The "Cc OUTput" generators. Given the generated output (and in some cases
5127 the original inputs), update the various cc data structures in order to
5128 be able to compute the new condition code. */
5130 static void cout_abs32(DisasContext
*s
, DisasOps
*o
)
5132 gen_op_update1_cc_i64(s
, CC_OP_ABS_32
, o
->out
);
5135 static void cout_abs64(DisasContext
*s
, DisasOps
*o
)
5137 gen_op_update1_cc_i64(s
, CC_OP_ABS_64
, o
->out
);
5140 static void cout_adds32(DisasContext
*s
, DisasOps
*o
)
5142 gen_op_update3_cc_i64(s
, CC_OP_ADD_32
, o
->in1
, o
->in2
, o
->out
);
5145 static void cout_adds64(DisasContext
*s
, DisasOps
*o
)
5147 gen_op_update3_cc_i64(s
, CC_OP_ADD_64
, o
->in1
, o
->in2
, o
->out
);
5150 static void cout_addu32(DisasContext
*s
, DisasOps
*o
)
5152 gen_op_update3_cc_i64(s
, CC_OP_ADDU_32
, o
->in1
, o
->in2
, o
->out
);
5155 static void cout_addu64(DisasContext
*s
, DisasOps
*o
)
5157 gen_op_update3_cc_i64(s
, CC_OP_ADDU_64
, o
->in1
, o
->in2
, o
->out
);
5160 static void cout_addc32(DisasContext
*s
, DisasOps
*o
)
5162 gen_op_update3_cc_i64(s
, CC_OP_ADDC_32
, o
->in1
, o
->in2
, o
->out
);
5165 static void cout_addc64(DisasContext
*s
, DisasOps
*o
)
5167 gen_op_update3_cc_i64(s
, CC_OP_ADDC_64
, o
->in1
, o
->in2
, o
->out
);
5170 static void cout_cmps32(DisasContext
*s
, DisasOps
*o
)
5172 gen_op_update2_cc_i64(s
, CC_OP_LTGT_32
, o
->in1
, o
->in2
);
5175 static void cout_cmps64(DisasContext
*s
, DisasOps
*o
)
5177 gen_op_update2_cc_i64(s
, CC_OP_LTGT_64
, o
->in1
, o
->in2
);
5180 static void cout_cmpu32(DisasContext
*s
, DisasOps
*o
)
5182 gen_op_update2_cc_i64(s
, CC_OP_LTUGTU_32
, o
->in1
, o
->in2
);
5185 static void cout_cmpu64(DisasContext
*s
, DisasOps
*o
)
5187 gen_op_update2_cc_i64(s
, CC_OP_LTUGTU_64
, o
->in1
, o
->in2
);
5190 static void cout_f32(DisasContext
*s
, DisasOps
*o
)
5192 gen_op_update1_cc_i64(s
, CC_OP_NZ_F32
, o
->out
);
5195 static void cout_f64(DisasContext
*s
, DisasOps
*o
)
5197 gen_op_update1_cc_i64(s
, CC_OP_NZ_F64
, o
->out
);
5200 static void cout_f128(DisasContext
*s
, DisasOps
*o
)
5202 gen_op_update2_cc_i64(s
, CC_OP_NZ_F128
, o
->out
, o
->out2
);
5205 static void cout_nabs32(DisasContext
*s
, DisasOps
*o
)
5207 gen_op_update1_cc_i64(s
, CC_OP_NABS_32
, o
->out
);
5210 static void cout_nabs64(DisasContext
*s
, DisasOps
*o
)
5212 gen_op_update1_cc_i64(s
, CC_OP_NABS_64
, o
->out
);
5215 static void cout_neg32(DisasContext
*s
, DisasOps
*o
)
5217 gen_op_update1_cc_i64(s
, CC_OP_COMP_32
, o
->out
);
5220 static void cout_neg64(DisasContext
*s
, DisasOps
*o
)
5222 gen_op_update1_cc_i64(s
, CC_OP_COMP_64
, o
->out
);
5225 static void cout_nz32(DisasContext
*s
, DisasOps
*o
)
5227 tcg_gen_ext32u_i64(cc_dst
, o
->out
);
5228 gen_op_update1_cc_i64(s
, CC_OP_NZ
, cc_dst
);
5231 static void cout_nz64(DisasContext
*s
, DisasOps
*o
)
5233 gen_op_update1_cc_i64(s
, CC_OP_NZ
, o
->out
);
5236 static void cout_s32(DisasContext
*s
, DisasOps
*o
)
5238 gen_op_update1_cc_i64(s
, CC_OP_LTGT0_32
, o
->out
);
5241 static void cout_s64(DisasContext
*s
, DisasOps
*o
)
5243 gen_op_update1_cc_i64(s
, CC_OP_LTGT0_64
, o
->out
);
5246 static void cout_subs32(DisasContext
*s
, DisasOps
*o
)
5248 gen_op_update3_cc_i64(s
, CC_OP_SUB_32
, o
->in1
, o
->in2
, o
->out
);
5251 static void cout_subs64(DisasContext
*s
, DisasOps
*o
)
5253 gen_op_update3_cc_i64(s
, CC_OP_SUB_64
, o
->in1
, o
->in2
, o
->out
);
5256 static void cout_subu32(DisasContext
*s
, DisasOps
*o
)
5258 gen_op_update3_cc_i64(s
, CC_OP_SUBU_32
, o
->in1
, o
->in2
, o
->out
);
5261 static void cout_subu64(DisasContext
*s
, DisasOps
*o
)
5263 gen_op_update3_cc_i64(s
, CC_OP_SUBU_64
, o
->in1
, o
->in2
, o
->out
);
5266 static void cout_subb32(DisasContext
*s
, DisasOps
*o
)
5268 gen_op_update3_cc_i64(s
, CC_OP_SUBB_32
, o
->in1
, o
->in2
, o
->out
);
5271 static void cout_subb64(DisasContext
*s
, DisasOps
*o
)
5273 gen_op_update3_cc_i64(s
, CC_OP_SUBB_64
, o
->in1
, o
->in2
, o
->out
);
5276 static void cout_tm32(DisasContext
*s
, DisasOps
*o
)
5278 gen_op_update2_cc_i64(s
, CC_OP_TM_32
, o
->in1
, o
->in2
);
5281 static void cout_tm64(DisasContext
*s
, DisasOps
*o
)
5283 gen_op_update2_cc_i64(s
, CC_OP_TM_64
, o
->in1
, o
->in2
);
5286 /* ====================================================================== */
5287 /* The "PREParation" generators. These initialize the DisasOps.OUT fields
5288 with the TCG register to which we will write. Used in combination with
5289 the "wout" generators, in some cases we need a new temporary, and in
5290 some cases we can write to a TCG global. */
5292 static void prep_new(DisasContext
*s
, DisasOps
*o
)
5294 o
->out
= tcg_temp_new_i64();
5296 #define SPEC_prep_new 0
5298 static void prep_new_P(DisasContext
*s
, DisasOps
*o
)
5300 o
->out
= tcg_temp_new_i64();
5301 o
->out2
= tcg_temp_new_i64();
5303 #define SPEC_prep_new_P 0
5305 static void prep_r1(DisasContext
*s
, DisasOps
*o
)
5307 o
->out
= regs
[get_field(s
, r1
)];
5310 #define SPEC_prep_r1 0
5312 static void prep_r1_P(DisasContext
*s
, DisasOps
*o
)
5314 int r1
= get_field(s
, r1
);
5316 o
->out2
= regs
[r1
+ 1];
5317 o
->g_out
= o
->g_out2
= true;
5319 #define SPEC_prep_r1_P SPEC_r1_even
5321 /* Whenever we need x1 in addition to other inputs, we'll load it to out/out2 */
5322 static void prep_x1(DisasContext
*s
, DisasOps
*o
)
5324 o
->out
= load_freg(get_field(s
, r1
));
5325 o
->out2
= load_freg(get_field(s
, r1
) + 2);
5327 #define SPEC_prep_x1 SPEC_r1_f128
5329 /* ====================================================================== */
5330 /* The "Write OUTput" generators. These generally perform some non-trivial
5331 copy of data to TCG globals, or to main memory. The trivial cases are
5332 generally handled by having a "prep" generator install the TCG global
5333 as the destination of the operation. */
5335 static void wout_r1(DisasContext
*s
, DisasOps
*o
)
5337 store_reg(get_field(s
, r1
), o
->out
);
5339 #define SPEC_wout_r1 0
5341 static void wout_r1_8(DisasContext
*s
, DisasOps
*o
)
5343 int r1
= get_field(s
, r1
);
5344 tcg_gen_deposit_i64(regs
[r1
], regs
[r1
], o
->out
, 0, 8);
5346 #define SPEC_wout_r1_8 0
5348 static void wout_r1_16(DisasContext
*s
, DisasOps
*o
)
5350 int r1
= get_field(s
, r1
);
5351 tcg_gen_deposit_i64(regs
[r1
], regs
[r1
], o
->out
, 0, 16);
5353 #define SPEC_wout_r1_16 0
5355 static void wout_r1_32(DisasContext
*s
, DisasOps
*o
)
5357 store_reg32_i64(get_field(s
, r1
), o
->out
);
5359 #define SPEC_wout_r1_32 0
5361 static void wout_r1_32h(DisasContext
*s
, DisasOps
*o
)
5363 store_reg32h_i64(get_field(s
, r1
), o
->out
);
5365 #define SPEC_wout_r1_32h 0
5367 static void wout_r1_P32(DisasContext
*s
, DisasOps
*o
)
5369 int r1
= get_field(s
, r1
);
5370 store_reg32_i64(r1
, o
->out
);
5371 store_reg32_i64(r1
+ 1, o
->out2
);
5373 #define SPEC_wout_r1_P32 SPEC_r1_even
5375 static void wout_r1_D32(DisasContext
*s
, DisasOps
*o
)
5377 int r1
= get_field(s
, r1
);
5378 store_reg32_i64(r1
+ 1, o
->out
);
5379 tcg_gen_shri_i64(o
->out
, o
->out
, 32);
5380 store_reg32_i64(r1
, o
->out
);
5382 #define SPEC_wout_r1_D32 SPEC_r1_even
5384 static void wout_r3_P32(DisasContext
*s
, DisasOps
*o
)
5386 int r3
= get_field(s
, r3
);
5387 store_reg32_i64(r3
, o
->out
);
5388 store_reg32_i64(r3
+ 1, o
->out2
);
5390 #define SPEC_wout_r3_P32 SPEC_r3_even
5392 static void wout_r3_P64(DisasContext
*s
, DisasOps
*o
)
5394 int r3
= get_field(s
, r3
);
5395 store_reg(r3
, o
->out
);
5396 store_reg(r3
+ 1, o
->out2
);
5398 #define SPEC_wout_r3_P64 SPEC_r3_even
5400 static void wout_e1(DisasContext
*s
, DisasOps
*o
)
5402 store_freg32_i64(get_field(s
, r1
), o
->out
);
5404 #define SPEC_wout_e1 0
5406 static void wout_f1(DisasContext
*s
, DisasOps
*o
)
5408 store_freg(get_field(s
, r1
), o
->out
);
5410 #define SPEC_wout_f1 0
5412 static void wout_x1(DisasContext
*s
, DisasOps
*o
)
5414 int f1
= get_field(s
, r1
);
5415 store_freg(f1
, o
->out
);
5416 store_freg(f1
+ 2, o
->out2
);
5418 #define SPEC_wout_x1 SPEC_r1_f128
5420 static void wout_cond_r1r2_32(DisasContext
*s
, DisasOps
*o
)
5422 if (get_field(s
, r1
) != get_field(s
, r2
)) {
5423 store_reg32_i64(get_field(s
, r1
), o
->out
);
5426 #define SPEC_wout_cond_r1r2_32 0
5428 static void wout_cond_e1e2(DisasContext
*s
, DisasOps
*o
)
5430 if (get_field(s
, r1
) != get_field(s
, r2
)) {
5431 store_freg32_i64(get_field(s
, r1
), o
->out
);
5434 #define SPEC_wout_cond_e1e2 0
5436 static void wout_m1_8(DisasContext
*s
, DisasOps
*o
)
5438 tcg_gen_qemu_st8(o
->out
, o
->addr1
, get_mem_index(s
));
5440 #define SPEC_wout_m1_8 0
5442 static void wout_m1_16(DisasContext
*s
, DisasOps
*o
)
5444 tcg_gen_qemu_st16(o
->out
, o
->addr1
, get_mem_index(s
));
5446 #define SPEC_wout_m1_16 0
5448 #ifndef CONFIG_USER_ONLY
5449 static void wout_m1_16a(DisasContext
*s
, DisasOps
*o
)
5451 tcg_gen_qemu_st_tl(o
->out
, o
->addr1
, get_mem_index(s
), MO_TEUW
| MO_ALIGN
);
5453 #define SPEC_wout_m1_16a 0
5456 static void wout_m1_32(DisasContext
*s
, DisasOps
*o
)
5458 tcg_gen_qemu_st32(o
->out
, o
->addr1
, get_mem_index(s
));
5460 #define SPEC_wout_m1_32 0
5462 #ifndef CONFIG_USER_ONLY
5463 static void wout_m1_32a(DisasContext
*s
, DisasOps
*o
)
5465 tcg_gen_qemu_st_tl(o
->out
, o
->addr1
, get_mem_index(s
), MO_TEUL
| MO_ALIGN
);
5467 #define SPEC_wout_m1_32a 0
5470 static void wout_m1_64(DisasContext
*s
, DisasOps
*o
)
5472 tcg_gen_qemu_st64(o
->out
, o
->addr1
, get_mem_index(s
));
5474 #define SPEC_wout_m1_64 0
5476 #ifndef CONFIG_USER_ONLY
5477 static void wout_m1_64a(DisasContext
*s
, DisasOps
*o
)
5479 tcg_gen_qemu_st_i64(o
->out
, o
->addr1
, get_mem_index(s
), MO_TEQ
| MO_ALIGN
);
5481 #define SPEC_wout_m1_64a 0
5484 static void wout_m2_32(DisasContext
*s
, DisasOps
*o
)
5486 tcg_gen_qemu_st32(o
->out
, o
->in2
, get_mem_index(s
));
5488 #define SPEC_wout_m2_32 0
5490 static void wout_in2_r1(DisasContext
*s
, DisasOps
*o
)
5492 store_reg(get_field(s
, r1
), o
->in2
);
5494 #define SPEC_wout_in2_r1 0
5496 static void wout_in2_r1_32(DisasContext
*s
, DisasOps
*o
)
5498 store_reg32_i64(get_field(s
, r1
), o
->in2
);
5500 #define SPEC_wout_in2_r1_32 0
5502 /* ====================================================================== */
5503 /* The "INput 1" generators. These load the first operand to an insn. */
5505 static void in1_r1(DisasContext
*s
, DisasOps
*o
)
5507 o
->in1
= load_reg(get_field(s
, r1
));
5509 #define SPEC_in1_r1 0
5511 static void in1_r1_o(DisasContext
*s
, DisasOps
*o
)
5513 o
->in1
= regs
[get_field(s
, r1
)];
5516 #define SPEC_in1_r1_o 0
5518 static void in1_r1_32s(DisasContext
*s
, DisasOps
*o
)
5520 o
->in1
= tcg_temp_new_i64();
5521 tcg_gen_ext32s_i64(o
->in1
, regs
[get_field(s
, r1
)]);
5523 #define SPEC_in1_r1_32s 0
5525 static void in1_r1_32u(DisasContext
*s
, DisasOps
*o
)
5527 o
->in1
= tcg_temp_new_i64();
5528 tcg_gen_ext32u_i64(o
->in1
, regs
[get_field(s
, r1
)]);
5530 #define SPEC_in1_r1_32u 0
5532 static void in1_r1_sr32(DisasContext
*s
, DisasOps
*o
)
5534 o
->in1
= tcg_temp_new_i64();
5535 tcg_gen_shri_i64(o
->in1
, regs
[get_field(s
, r1
)], 32);
5537 #define SPEC_in1_r1_sr32 0
5539 static void in1_r1p1(DisasContext
*s
, DisasOps
*o
)
5541 o
->in1
= load_reg(get_field(s
, r1
) + 1);
5543 #define SPEC_in1_r1p1 SPEC_r1_even
5545 static void in1_r1p1_32s(DisasContext
*s
, DisasOps
*o
)
5547 o
->in1
= tcg_temp_new_i64();
5548 tcg_gen_ext32s_i64(o
->in1
, regs
[get_field(s
, r1
) + 1]);
5550 #define SPEC_in1_r1p1_32s SPEC_r1_even
5552 static void in1_r1p1_32u(DisasContext
*s
, DisasOps
*o
)
5554 o
->in1
= tcg_temp_new_i64();
5555 tcg_gen_ext32u_i64(o
->in1
, regs
[get_field(s
, r1
) + 1]);
5557 #define SPEC_in1_r1p1_32u SPEC_r1_even
5559 static void in1_r1_D32(DisasContext
*s
, DisasOps
*o
)
5561 int r1
= get_field(s
, r1
);
5562 o
->in1
= tcg_temp_new_i64();
5563 tcg_gen_concat32_i64(o
->in1
, regs
[r1
+ 1], regs
[r1
]);
5565 #define SPEC_in1_r1_D32 SPEC_r1_even
5567 static void in1_r2(DisasContext
*s
, DisasOps
*o
)
5569 o
->in1
= load_reg(get_field(s
, r2
));
5571 #define SPEC_in1_r2 0
5573 static void in1_r2_sr32(DisasContext
*s
, DisasOps
*o
)
5575 o
->in1
= tcg_temp_new_i64();
5576 tcg_gen_shri_i64(o
->in1
, regs
[get_field(s
, r2
)], 32);
5578 #define SPEC_in1_r2_sr32 0
5580 static void in1_r3(DisasContext
*s
, DisasOps
*o
)
5582 o
->in1
= load_reg(get_field(s
, r3
));
5584 #define SPEC_in1_r3 0
5586 static void in1_r3_o(DisasContext
*s
, DisasOps
*o
)
5588 o
->in1
= regs
[get_field(s
, r3
)];
5591 #define SPEC_in1_r3_o 0
5593 static void in1_r3_32s(DisasContext
*s
, DisasOps
*o
)
5595 o
->in1
= tcg_temp_new_i64();
5596 tcg_gen_ext32s_i64(o
->in1
, regs
[get_field(s
, r3
)]);
5598 #define SPEC_in1_r3_32s 0
5600 static void in1_r3_32u(DisasContext
*s
, DisasOps
*o
)
5602 o
->in1
= tcg_temp_new_i64();
5603 tcg_gen_ext32u_i64(o
->in1
, regs
[get_field(s
, r3
)]);
5605 #define SPEC_in1_r3_32u 0
5607 static void in1_r3_D32(DisasContext
*s
, DisasOps
*o
)
5609 int r3
= get_field(s
, r3
);
5610 o
->in1
= tcg_temp_new_i64();
5611 tcg_gen_concat32_i64(o
->in1
, regs
[r3
+ 1], regs
[r3
]);
5613 #define SPEC_in1_r3_D32 SPEC_r3_even
5615 static void in1_e1(DisasContext
*s
, DisasOps
*o
)
5617 o
->in1
= load_freg32_i64(get_field(s
, r1
));
5619 #define SPEC_in1_e1 0
5621 static void in1_f1(DisasContext
*s
, DisasOps
*o
)
5623 o
->in1
= load_freg(get_field(s
, r1
));
5625 #define SPEC_in1_f1 0
5627 /* Load the high double word of an extended (128-bit) format FP number */
5628 static void in1_x2h(DisasContext
*s
, DisasOps
*o
)
5630 o
->in1
= load_freg(get_field(s
, r2
));
5632 #define SPEC_in1_x2h SPEC_r2_f128
5634 static void in1_f3(DisasContext
*s
, DisasOps
*o
)
5636 o
->in1
= load_freg(get_field(s
, r3
));
5638 #define SPEC_in1_f3 0
5640 static void in1_la1(DisasContext
*s
, DisasOps
*o
)
5642 o
->addr1
= get_address(s
, 0, get_field(s
, b1
), get_field(s
, d1
));
5644 #define SPEC_in1_la1 0
5646 static void in1_la2(DisasContext
*s
, DisasOps
*o
)
5648 int x2
= have_field(s
, x2
) ? get_field(s
, x2
) : 0;
5649 o
->addr1
= get_address(s
, x2
, get_field(s
, b2
), get_field(s
, d2
));
5651 #define SPEC_in1_la2 0
5653 static void in1_m1_8u(DisasContext
*s
, DisasOps
*o
)
5656 o
->in1
= tcg_temp_new_i64();
5657 tcg_gen_qemu_ld8u(o
->in1
, o
->addr1
, get_mem_index(s
));
5659 #define SPEC_in1_m1_8u 0
5661 static void in1_m1_16s(DisasContext
*s
, DisasOps
*o
)
5664 o
->in1
= tcg_temp_new_i64();
5665 tcg_gen_qemu_ld16s(o
->in1
, o
->addr1
, get_mem_index(s
));
5667 #define SPEC_in1_m1_16s 0
5669 static void in1_m1_16u(DisasContext
*s
, DisasOps
*o
)
5672 o
->in1
= tcg_temp_new_i64();
5673 tcg_gen_qemu_ld16u(o
->in1
, o
->addr1
, get_mem_index(s
));
5675 #define SPEC_in1_m1_16u 0
5677 static void in1_m1_32s(DisasContext
*s
, DisasOps
*o
)
5680 o
->in1
= tcg_temp_new_i64();
5681 tcg_gen_qemu_ld32s(o
->in1
, o
->addr1
, get_mem_index(s
));
5683 #define SPEC_in1_m1_32s 0
5685 static void in1_m1_32u(DisasContext
*s
, DisasOps
*o
)
5688 o
->in1
= tcg_temp_new_i64();
5689 tcg_gen_qemu_ld32u(o
->in1
, o
->addr1
, get_mem_index(s
));
5691 #define SPEC_in1_m1_32u 0
5693 static void in1_m1_64(DisasContext
*s
, DisasOps
*o
)
5696 o
->in1
= tcg_temp_new_i64();
5697 tcg_gen_qemu_ld64(o
->in1
, o
->addr1
, get_mem_index(s
));
5699 #define SPEC_in1_m1_64 0
5701 /* ====================================================================== */
5702 /* The "INput 2" generators. These load the second operand to an insn. */
5704 static void in2_r1_o(DisasContext
*s
, DisasOps
*o
)
5706 o
->in2
= regs
[get_field(s
, r1
)];
5709 #define SPEC_in2_r1_o 0
5711 static void in2_r1_16u(DisasContext
*s
, DisasOps
*o
)
5713 o
->in2
= tcg_temp_new_i64();
5714 tcg_gen_ext16u_i64(o
->in2
, regs
[get_field(s
, r1
)]);
5716 #define SPEC_in2_r1_16u 0
5718 static void in2_r1_32u(DisasContext
*s
, DisasOps
*o
)
5720 o
->in2
= tcg_temp_new_i64();
5721 tcg_gen_ext32u_i64(o
->in2
, regs
[get_field(s
, r1
)]);
5723 #define SPEC_in2_r1_32u 0
5725 static void in2_r1_D32(DisasContext
*s
, DisasOps
*o
)
5727 int r1
= get_field(s
, r1
);
5728 o
->in2
= tcg_temp_new_i64();
5729 tcg_gen_concat32_i64(o
->in2
, regs
[r1
+ 1], regs
[r1
]);
5731 #define SPEC_in2_r1_D32 SPEC_r1_even
5733 static void in2_r2(DisasContext
*s
, DisasOps
*o
)
5735 o
->in2
= load_reg(get_field(s
, r2
));
5737 #define SPEC_in2_r2 0
5739 static void in2_r2_o(DisasContext
*s
, DisasOps
*o
)
5741 o
->in2
= regs
[get_field(s
, r2
)];
5744 #define SPEC_in2_r2_o 0
5746 static void in2_r2_nz(DisasContext
*s
, DisasOps
*o
)
5748 int r2
= get_field(s
, r2
);
5750 o
->in2
= load_reg(r2
);
5753 #define SPEC_in2_r2_nz 0
5755 static void in2_r2_8s(DisasContext
*s
, DisasOps
*o
)
5757 o
->in2
= tcg_temp_new_i64();
5758 tcg_gen_ext8s_i64(o
->in2
, regs
[get_field(s
, r2
)]);
5760 #define SPEC_in2_r2_8s 0
5762 static void in2_r2_8u(DisasContext
*s
, DisasOps
*o
)
5764 o
->in2
= tcg_temp_new_i64();
5765 tcg_gen_ext8u_i64(o
->in2
, regs
[get_field(s
, r2
)]);
5767 #define SPEC_in2_r2_8u 0
5769 static void in2_r2_16s(DisasContext
*s
, DisasOps
*o
)
5771 o
->in2
= tcg_temp_new_i64();
5772 tcg_gen_ext16s_i64(o
->in2
, regs
[get_field(s
, r2
)]);
5774 #define SPEC_in2_r2_16s 0
5776 static void in2_r2_16u(DisasContext
*s
, DisasOps
*o
)
5778 o
->in2
= tcg_temp_new_i64();
5779 tcg_gen_ext16u_i64(o
->in2
, regs
[get_field(s
, r2
)]);
5781 #define SPEC_in2_r2_16u 0
5783 static void in2_r3(DisasContext
*s
, DisasOps
*o
)
5785 o
->in2
= load_reg(get_field(s
, r3
));
5787 #define SPEC_in2_r3 0
5789 static void in2_r3_sr32(DisasContext
*s
, DisasOps
*o
)
5791 o
->in2
= tcg_temp_new_i64();
5792 tcg_gen_shri_i64(o
->in2
, regs
[get_field(s
, r3
)], 32);
5794 #define SPEC_in2_r3_sr32 0
5796 static void in2_r3_32u(DisasContext
*s
, DisasOps
*o
)
5798 o
->in2
= tcg_temp_new_i64();
5799 tcg_gen_ext32u_i64(o
->in2
, regs
[get_field(s
, r3
)]);
5801 #define SPEC_in2_r3_32u 0
5803 static void in2_r2_32s(DisasContext
*s
, DisasOps
*o
)
5805 o
->in2
= tcg_temp_new_i64();
5806 tcg_gen_ext32s_i64(o
->in2
, regs
[get_field(s
, r2
)]);
5808 #define SPEC_in2_r2_32s 0
5810 static void in2_r2_32u(DisasContext
*s
, DisasOps
*o
)
5812 o
->in2
= tcg_temp_new_i64();
5813 tcg_gen_ext32u_i64(o
->in2
, regs
[get_field(s
, r2
)]);
5815 #define SPEC_in2_r2_32u 0
5817 static void in2_r2_sr32(DisasContext
*s
, DisasOps
*o
)
5819 o
->in2
= tcg_temp_new_i64();
5820 tcg_gen_shri_i64(o
->in2
, regs
[get_field(s
, r2
)], 32);
5822 #define SPEC_in2_r2_sr32 0
5824 static void in2_e2(DisasContext
*s
, DisasOps
*o
)
5826 o
->in2
= load_freg32_i64(get_field(s
, r2
));
5828 #define SPEC_in2_e2 0
5830 static void in2_f2(DisasContext
*s
, DisasOps
*o
)
5832 o
->in2
= load_freg(get_field(s
, r2
));
5834 #define SPEC_in2_f2 0
5836 /* Load the low double word of an extended (128-bit) format FP number */
5837 static void in2_x2l(DisasContext
*s
, DisasOps
*o
)
5839 o
->in2
= load_freg(get_field(s
, r2
) + 2);
5841 #define SPEC_in2_x2l SPEC_r2_f128
5843 static void in2_ra2(DisasContext
*s
, DisasOps
*o
)
5845 o
->in2
= get_address(s
, 0, get_field(s
, r2
), 0);
5847 #define SPEC_in2_ra2 0
5849 static void in2_a2(DisasContext
*s
, DisasOps
*o
)
5851 int x2
= have_field(s
, x2
) ? get_field(s
, x2
) : 0;
5852 o
->in2
= get_address(s
, x2
, get_field(s
, b2
), get_field(s
, d2
));
5854 #define SPEC_in2_a2 0
5856 static void in2_ri2(DisasContext
*s
, DisasOps
*o
)
5858 o
->in2
= tcg_const_i64(s
->base
.pc_next
+ (int64_t)get_field(s
, i2
) * 2);
5860 #define SPEC_in2_ri2 0
5862 static void in2_sh32(DisasContext
*s
, DisasOps
*o
)
5864 help_l2_shift(s
, o
, 31);
5866 #define SPEC_in2_sh32 0
5868 static void in2_sh64(DisasContext
*s
, DisasOps
*o
)
5870 help_l2_shift(s
, o
, 63);
5872 #define SPEC_in2_sh64 0
5874 static void in2_m2_8u(DisasContext
*s
, DisasOps
*o
)
5877 tcg_gen_qemu_ld8u(o
->in2
, o
->in2
, get_mem_index(s
));
5879 #define SPEC_in2_m2_8u 0
5881 static void in2_m2_16s(DisasContext
*s
, DisasOps
*o
)
5884 tcg_gen_qemu_ld16s(o
->in2
, o
->in2
, get_mem_index(s
));
5886 #define SPEC_in2_m2_16s 0
5888 static void in2_m2_16u(DisasContext
*s
, DisasOps
*o
)
5891 tcg_gen_qemu_ld16u(o
->in2
, o
->in2
, get_mem_index(s
));
5893 #define SPEC_in2_m2_16u 0
5895 static void in2_m2_32s(DisasContext
*s
, DisasOps
*o
)
5898 tcg_gen_qemu_ld32s(o
->in2
, o
->in2
, get_mem_index(s
));
5900 #define SPEC_in2_m2_32s 0
5902 static void in2_m2_32u(DisasContext
*s
, DisasOps
*o
)
5905 tcg_gen_qemu_ld32u(o
->in2
, o
->in2
, get_mem_index(s
));
5907 #define SPEC_in2_m2_32u 0
5909 #ifndef CONFIG_USER_ONLY
5910 static void in2_m2_32ua(DisasContext
*s
, DisasOps
*o
)
5913 tcg_gen_qemu_ld_tl(o
->in2
, o
->in2
, get_mem_index(s
), MO_TEUL
| MO_ALIGN
);
5915 #define SPEC_in2_m2_32ua 0
5918 static void in2_m2_64(DisasContext
*s
, DisasOps
*o
)
5921 tcg_gen_qemu_ld64(o
->in2
, o
->in2
, get_mem_index(s
));
5923 #define SPEC_in2_m2_64 0
5925 #ifndef CONFIG_USER_ONLY
5926 static void in2_m2_64a(DisasContext
*s
, DisasOps
*o
)
5929 tcg_gen_qemu_ld_i64(o
->in2
, o
->in2
, get_mem_index(s
), MO_TEQ
| MO_ALIGN
);
5931 #define SPEC_in2_m2_64a 0
5934 static void in2_mri2_16u(DisasContext
*s
, DisasOps
*o
)
5937 tcg_gen_qemu_ld16u(o
->in2
, o
->in2
, get_mem_index(s
));
5939 #define SPEC_in2_mri2_16u 0
5941 static void in2_mri2_32s(DisasContext
*s
, DisasOps
*o
)
5944 tcg_gen_qemu_ld32s(o
->in2
, o
->in2
, get_mem_index(s
));
5946 #define SPEC_in2_mri2_32s 0
5948 static void in2_mri2_32u(DisasContext
*s
, DisasOps
*o
)
5951 tcg_gen_qemu_ld32u(o
->in2
, o
->in2
, get_mem_index(s
));
5953 #define SPEC_in2_mri2_32u 0
5955 static void in2_mri2_64(DisasContext
*s
, DisasOps
*o
)
5958 tcg_gen_qemu_ld64(o
->in2
, o
->in2
, get_mem_index(s
));
5960 #define SPEC_in2_mri2_64 0
5962 static void in2_i2(DisasContext
*s
, DisasOps
*o
)
5964 o
->in2
= tcg_const_i64(get_field(s
, i2
));
5966 #define SPEC_in2_i2 0
5968 static void in2_i2_8u(DisasContext
*s
, DisasOps
*o
)
5970 o
->in2
= tcg_const_i64((uint8_t)get_field(s
, i2
));
5972 #define SPEC_in2_i2_8u 0
5974 static void in2_i2_16u(DisasContext
*s
, DisasOps
*o
)
5976 o
->in2
= tcg_const_i64((uint16_t)get_field(s
, i2
));
5978 #define SPEC_in2_i2_16u 0
5980 static void in2_i2_32u(DisasContext
*s
, DisasOps
*o
)
5982 o
->in2
= tcg_const_i64((uint32_t)get_field(s
, i2
));
5984 #define SPEC_in2_i2_32u 0
5986 static void in2_i2_16u_shl(DisasContext
*s
, DisasOps
*o
)
5988 uint64_t i2
= (uint16_t)get_field(s
, i2
);
5989 o
->in2
= tcg_const_i64(i2
<< s
->insn
->data
);
5991 #define SPEC_in2_i2_16u_shl 0
5993 static void in2_i2_32u_shl(DisasContext
*s
, DisasOps
*o
)
5995 uint64_t i2
= (uint32_t)get_field(s
, i2
);
5996 o
->in2
= tcg_const_i64(i2
<< s
->insn
->data
);
5998 #define SPEC_in2_i2_32u_shl 0
6000 #ifndef CONFIG_USER_ONLY
6001 static void in2_insn(DisasContext
*s
, DisasOps
*o
)
6003 o
->in2
= tcg_const_i64(s
->fields
.raw_insn
);
6005 #define SPEC_in2_insn 0
6008 /* ====================================================================== */
6010 /* Find opc within the table of insns. This is formulated as a switch
6011 statement so that (1) we get compile-time notice of cut-paste errors
6012 for duplicated opcodes, and (2) the compiler generates the binary
6013 search tree, rather than us having to post-process the table. */
6015 #define C(OPC, NM, FT, FC, I1, I2, P, W, OP, CC) \
6016 E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, 0, 0)
6018 #define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) \
6019 E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D, 0)
6021 #define F(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, FL) \
6022 E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, 0, FL)
6024 #define E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D, FL) insn_ ## NM,
6026 enum DisasInsnEnum
{
6027 #include "insn-data.def"
6031 #define E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D, FL) { \
6036 .spec = SPEC_in1_##I1 | SPEC_in2_##I2 | SPEC_prep_##P | SPEC_wout_##W, \
6038 .help_in1 = in1_##I1, \
6039 .help_in2 = in2_##I2, \
6040 .help_prep = prep_##P, \
6041 .help_wout = wout_##W, \
6042 .help_cout = cout_##CC, \
6043 .help_op = op_##OP, \
6047 /* Allow 0 to be used for NULL in the table below. */
6055 #define SPEC_in1_0 0
6056 #define SPEC_in2_0 0
6057 #define SPEC_prep_0 0
6058 #define SPEC_wout_0 0
6060 /* Give smaller names to the various facilities. */
6061 #define FAC_Z S390_FEAT_ZARCH
6062 #define FAC_CASS S390_FEAT_COMPARE_AND_SWAP_AND_STORE
6063 #define FAC_DFP S390_FEAT_DFP
6064 #define FAC_DFPR S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* DFP-rounding */
6065 #define FAC_DO S390_FEAT_STFLE_45 /* distinct-operands */
6066 #define FAC_EE S390_FEAT_EXECUTE_EXT
6067 #define FAC_EI S390_FEAT_EXTENDED_IMMEDIATE
6068 #define FAC_FPE S390_FEAT_FLOATING_POINT_EXT
6069 #define FAC_FPSSH S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* FPS-sign-handling */
6070 #define FAC_FPRGR S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* FPR-GR-transfer */
6071 #define FAC_GIE S390_FEAT_GENERAL_INSTRUCTIONS_EXT
6072 #define FAC_HFP_MA S390_FEAT_HFP_MADDSUB
6073 #define FAC_HW S390_FEAT_STFLE_45 /* high-word */
6074 #define FAC_IEEEE_SIM S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* IEEE-exception-simulation */
6075 #define FAC_MIE S390_FEAT_STFLE_49 /* misc-instruction-extensions */
6076 #define FAC_LAT S390_FEAT_STFLE_49 /* load-and-trap */
6077 #define FAC_LOC S390_FEAT_STFLE_45 /* load/store on condition 1 */
6078 #define FAC_LOC2 S390_FEAT_STFLE_53 /* load/store on condition 2 */
6079 #define FAC_LD S390_FEAT_LONG_DISPLACEMENT
6080 #define FAC_PC S390_FEAT_STFLE_45 /* population count */
6081 #define FAC_SCF S390_FEAT_STORE_CLOCK_FAST
6082 #define FAC_SFLE S390_FEAT_STFLE
6083 #define FAC_ILA S390_FEAT_STFLE_45 /* interlocked-access-facility 1 */
6084 #define FAC_MVCOS S390_FEAT_MOVE_WITH_OPTIONAL_SPEC
6085 #define FAC_LPP S390_FEAT_SET_PROGRAM_PARAMETERS /* load-program-parameter */
6086 #define FAC_DAT_ENH S390_FEAT_DAT_ENH
6087 #define FAC_E2 S390_FEAT_EXTENDED_TRANSLATION_2
6088 #define FAC_EH S390_FEAT_STFLE_49 /* execution-hint */
6089 #define FAC_PPA S390_FEAT_STFLE_49 /* processor-assist */
6090 #define FAC_LZRB S390_FEAT_STFLE_53 /* load-and-zero-rightmost-byte */
6091 #define FAC_ETF3 S390_FEAT_EXTENDED_TRANSLATION_3
6092 #define FAC_MSA S390_FEAT_MSA /* message-security-assist facility */
6093 #define FAC_MSA3 S390_FEAT_MSA_EXT_3 /* msa-extension-3 facility */
6094 #define FAC_MSA4 S390_FEAT_MSA_EXT_4 /* msa-extension-4 facility */
6095 #define FAC_MSA5 S390_FEAT_MSA_EXT_5 /* msa-extension-5 facility */
6096 #define FAC_ECT S390_FEAT_EXTRACT_CPU_TIME
6097 #define FAC_PCI S390_FEAT_ZPCI /* z/PCI facility */
6098 #define FAC_AIS S390_FEAT_ADAPTER_INT_SUPPRESSION
6099 #define FAC_V S390_FEAT_VECTOR /* vector facility */
6100 #define FAC_VE S390_FEAT_VECTOR_ENH /* vector enhancements facility 1 */
6102 static const DisasInsn insn_info
[] = {
6103 #include "insn-data.def"
6107 #define E(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D, FL) \
6108 case OPC: return &insn_info[insn_ ## NM];
6110 static const DisasInsn
*lookup_opc(uint16_t opc
)
6113 #include "insn-data.def"
6124 /* Extract a field from the insn. The INSN should be left-aligned in
6125 the uint64_t so that we can more easily utilize the big-bit-endian
6126 definitions we extract from the Principals of Operation. */
6128 static void extract_field(DisasFields
*o
, const DisasField
*f
, uint64_t insn
)
6136 /* Zero extract the field from the insn. */
6137 r
= (insn
<< f
->beg
) >> (64 - f
->size
);
6139 /* Sign-extend, or un-swap the field as necessary. */
6141 case 0: /* unsigned */
6143 case 1: /* signed */
6144 assert(f
->size
<= 32);
6145 m
= 1u << (f
->size
- 1);
6148 case 2: /* dl+dh split, signed 20 bit. */
6149 r
= ((int8_t)r
<< 12) | (r
>> 8);
6151 case 3: /* MSB stored in RXB */
6152 g_assert(f
->size
== 4);
6155 r
|= extract64(insn
, 63 - 36, 1) << 4;
6158 r
|= extract64(insn
, 63 - 37, 1) << 4;
6161 r
|= extract64(insn
, 63 - 38, 1) << 4;
6164 r
|= extract64(insn
, 63 - 39, 1) << 4;
6167 g_assert_not_reached();
6174 /* Validate that the "compressed" encoding we selected above is valid.
6175 I.e. we havn't make two different original fields overlap. */
6176 assert(((o
->presentC
>> f
->indexC
) & 1) == 0);
6177 o
->presentC
|= 1 << f
->indexC
;
6178 o
->presentO
|= 1 << f
->indexO
;
6180 o
->c
[f
->indexC
] = r
;
6183 /* Lookup the insn at the current PC, extracting the operands into O and
6184 returning the info struct for the insn. Returns NULL for invalid insn. */
6186 static const DisasInsn
*extract_insn(CPUS390XState
*env
, DisasContext
*s
)
6188 uint64_t insn
, pc
= s
->base
.pc_next
;
6190 const DisasInsn
*info
;
6192 if (unlikely(s
->ex_value
)) {
6193 /* Drop the EX data now, so that it's clear on exception paths. */
6194 TCGv_i64 zero
= tcg_const_i64(0);
6195 tcg_gen_st_i64(zero
, cpu_env
, offsetof(CPUS390XState
, ex_value
));
6196 tcg_temp_free_i64(zero
);
6198 /* Extract the values saved by EXECUTE. */
6199 insn
= s
->ex_value
& 0xffffffffffff0000ull
;
6200 ilen
= s
->ex_value
& 0xf;
6203 insn
= ld_code2(env
, pc
);
6204 op
= (insn
>> 8) & 0xff;
6205 ilen
= get_ilen(op
);
6211 insn
= ld_code4(env
, pc
) << 32;
6214 insn
= (insn
<< 48) | (ld_code4(env
, pc
+ 2) << 16);
6217 g_assert_not_reached();
6220 s
->pc_tmp
= s
->base
.pc_next
+ ilen
;
6223 /* We can't actually determine the insn format until we've looked up
6224 the full insn opcode. Which we can't do without locating the
6225 secondary opcode. Assume by default that OP2 is at bit 40; for
6226 those smaller insns that don't actually have a secondary opcode
6227 this will correctly result in OP2 = 0. */
6233 case 0xb2: /* S, RRF, RRE, IE */
6234 case 0xb3: /* RRE, RRD, RRF */
6235 case 0xb9: /* RRE, RRF */
6236 case 0xe5: /* SSE, SIL */
6237 op2
= (insn
<< 8) >> 56;
6241 case 0xc0: /* RIL */
6242 case 0xc2: /* RIL */
6243 case 0xc4: /* RIL */
6244 case 0xc6: /* RIL */
6245 case 0xc8: /* SSF */
6246 case 0xcc: /* RIL */
6247 op2
= (insn
<< 12) >> 60;
6249 case 0xc5: /* MII */
6250 case 0xc7: /* SMI */
6251 case 0xd0 ... 0xdf: /* SS */
6257 case 0xee ... 0xf3: /* SS */
6258 case 0xf8 ... 0xfd: /* SS */
6262 op2
= (insn
<< 40) >> 56;
6266 memset(&s
->fields
, 0, sizeof(s
->fields
));
6267 s
->fields
.raw_insn
= insn
;
6269 s
->fields
.op2
= op2
;
6271 /* Lookup the instruction. */
6272 info
= lookup_opc(op
<< 8 | op2
);
6275 /* If we found it, extract the operands. */
6277 DisasFormat fmt
= info
->fmt
;
6280 for (i
= 0; i
< NUM_C_FIELD
; ++i
) {
6281 extract_field(&s
->fields
, &format_info
[fmt
].op
[i
], insn
);
6287 static bool is_afp_reg(int reg
)
6289 return reg
% 2 || reg
> 6;
6292 static bool is_fp_pair(int reg
)
6294 /* 0,1,4,5,8,9,12,13: to exclude the others, check for single bit */
6295 return !(reg
& 0x2);
6298 static DisasJumpType
translate_one(CPUS390XState
*env
, DisasContext
*s
)
6300 const DisasInsn
*insn
;
6301 DisasJumpType ret
= DISAS_NEXT
;
6304 /* Search for the insn in the table. */
6305 insn
= extract_insn(env
, s
);
6307 /* Emit insn_start now that we know the ILEN. */
6308 tcg_gen_insn_start(s
->base
.pc_next
, s
->cc_op
, s
->ilen
);
6310 /* Not found means unimplemented/illegal opcode. */
6312 qemu_log_mask(LOG_UNIMP
, "unimplemented opcode 0x%02x%02x\n",
6313 s
->fields
.op
, s
->fields
.op2
);
6314 gen_illegal_opcode(s
);
6315 return DISAS_NORETURN
;
6318 #ifndef CONFIG_USER_ONLY
6319 if (s
->base
.tb
->flags
& FLAG_MASK_PER
) {
6320 TCGv_i64 addr
= tcg_const_i64(s
->base
.pc_next
);
6321 gen_helper_per_ifetch(cpu_env
, addr
);
6322 tcg_temp_free_i64(addr
);
6328 /* privileged instruction */
6329 if ((s
->base
.tb
->flags
& FLAG_MASK_PSTATE
) && (insn
->flags
& IF_PRIV
)) {
6330 gen_program_exception(s
, PGM_PRIVILEGED
);
6331 return DISAS_NORETURN
;
6334 /* if AFP is not enabled, instructions and registers are forbidden */
6335 if (!(s
->base
.tb
->flags
& FLAG_MASK_AFP
)) {
6338 if ((insn
->flags
& IF_AFP1
) && is_afp_reg(get_field(s
, r1
))) {
6341 if ((insn
->flags
& IF_AFP2
) && is_afp_reg(get_field(s
, r2
))) {
6344 if ((insn
->flags
& IF_AFP3
) && is_afp_reg(get_field(s
, r3
))) {
6347 if (insn
->flags
& IF_BFP
) {
6350 if (insn
->flags
& IF_DFP
) {
6353 if (insn
->flags
& IF_VEC
) {
6357 gen_data_exception(dxc
);
6358 return DISAS_NORETURN
;
6362 /* if vector instructions not enabled, executing them is forbidden */
6363 if (insn
->flags
& IF_VEC
) {
6364 if (!((s
->base
.tb
->flags
& FLAG_MASK_VECTOR
))) {
6365 gen_data_exception(0xfe);
6366 return DISAS_NORETURN
;
6371 /* Check for insn specification exceptions. */
6373 if ((insn
->spec
& SPEC_r1_even
&& get_field(s
, r1
) & 1) ||
6374 (insn
->spec
& SPEC_r2_even
&& get_field(s
, r2
) & 1) ||
6375 (insn
->spec
& SPEC_r3_even
&& get_field(s
, r3
) & 1) ||
6376 (insn
->spec
& SPEC_r1_f128
&& !is_fp_pair(get_field(s
, r1
))) ||
6377 (insn
->spec
& SPEC_r2_f128
&& !is_fp_pair(get_field(s
, r2
)))) {
6378 gen_program_exception(s
, PGM_SPECIFICATION
);
6379 return DISAS_NORETURN
;
6383 /* Implement the instruction. */
6384 if (insn
->help_in1
) {
6385 insn
->help_in1(s
, &o
);
6387 if (insn
->help_in2
) {
6388 insn
->help_in2(s
, &o
);
6390 if (insn
->help_prep
) {
6391 insn
->help_prep(s
, &o
);
6393 if (insn
->help_op
) {
6394 ret
= insn
->help_op(s
, &o
);
6396 if (ret
!= DISAS_NORETURN
) {
6397 if (insn
->help_wout
) {
6398 insn
->help_wout(s
, &o
);
6400 if (insn
->help_cout
) {
6401 insn
->help_cout(s
, &o
);
6405 /* Free any temporaries created by the helpers. */
6406 if (o
.out
&& !o
.g_out
) {
6407 tcg_temp_free_i64(o
.out
);
6409 if (o
.out2
&& !o
.g_out2
) {
6410 tcg_temp_free_i64(o
.out2
);
6412 if (o
.in1
&& !o
.g_in1
) {
6413 tcg_temp_free_i64(o
.in1
);
6415 if (o
.in2
&& !o
.g_in2
) {
6416 tcg_temp_free_i64(o
.in2
);
6419 tcg_temp_free_i64(o
.addr1
);
6422 #ifndef CONFIG_USER_ONLY
6423 if (s
->base
.tb
->flags
& FLAG_MASK_PER
) {
6424 /* An exception might be triggered, save PSW if not already done. */
6425 if (ret
== DISAS_NEXT
|| ret
== DISAS_PC_STALE
) {
6426 tcg_gen_movi_i64(psw_addr
, s
->pc_tmp
);
6429 /* Call the helper to check for a possible PER exception. */
6430 gen_helper_per_check_exception(cpu_env
);
6434 /* Advance to the next instruction. */
6435 s
->base
.pc_next
= s
->pc_tmp
;
6439 static void s390x_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
6441 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
6444 if (!(dc
->base
.tb
->flags
& FLAG_MASK_64
)) {
6445 dc
->base
.pc_first
&= 0x7fffffff;
6446 dc
->base
.pc_next
= dc
->base
.pc_first
;
6449 dc
->cc_op
= CC_OP_DYNAMIC
;
6450 dc
->ex_value
= dc
->base
.tb
->cs_base
;
6451 dc
->do_debug
= dc
->base
.singlestep_enabled
;
6454 static void s390x_tr_tb_start(DisasContextBase
*db
, CPUState
*cs
)
6458 static void s390x_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
6462 static bool s390x_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
6463 const CPUBreakpoint
*bp
)
6465 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
6468 * Emit an insn_start to accompany the breakpoint exception.
6469 * The ILEN value is a dummy, since this does not result in
6470 * an s390x exception, but an internal qemu exception which
6471 * brings us back to interact with the gdbstub.
6473 tcg_gen_insn_start(dc
->base
.pc_next
, dc
->cc_op
, 2);
6475 dc
->base
.is_jmp
= DISAS_PC_STALE
;
6476 dc
->do_debug
= true;
6477 /* The address covered by the breakpoint must be included in
6478 [tb->pc, tb->pc + tb->size) in order to for it to be
6479 properly cleared -- thus we increment the PC here so that
6480 the logic setting tb->size does the right thing. */
6481 dc
->base
.pc_next
+= 2;
6485 static void s390x_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
6487 CPUS390XState
*env
= cs
->env_ptr
;
6488 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
6490 dc
->base
.is_jmp
= translate_one(env
, dc
);
6491 if (dc
->base
.is_jmp
== DISAS_NEXT
) {
6492 uint64_t page_start
;
6494 page_start
= dc
->base
.pc_first
& TARGET_PAGE_MASK
;
6495 if (dc
->base
.pc_next
- page_start
>= TARGET_PAGE_SIZE
|| dc
->ex_value
) {
6496 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
6501 static void s390x_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
6503 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
6505 switch (dc
->base
.is_jmp
) {
6507 case DISAS_NORETURN
:
6509 case DISAS_TOO_MANY
:
6510 case DISAS_PC_STALE
:
6511 case DISAS_PC_STALE_NOCHAIN
:
6512 update_psw_addr(dc
);
6514 case DISAS_PC_UPDATED
:
6515 /* Next TB starts off with CC_OP_DYNAMIC, so make sure the
6516 cc op type is in env */
6519 case DISAS_PC_CC_UPDATED
:
6520 /* Exit the TB, either by raising a debug exception or by return. */
6522 gen_exception(EXCP_DEBUG
);
6523 } else if (use_exit_tb(dc
) ||
6524 dc
->base
.is_jmp
== DISAS_PC_STALE_NOCHAIN
) {
6525 tcg_gen_exit_tb(NULL
, 0);
6527 tcg_gen_lookup_and_goto_ptr();
6531 g_assert_not_reached();
6535 static void s390x_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
6537 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
6539 if (unlikely(dc
->ex_value
)) {
6540 /* ??? Unfortunately log_target_disas can't use host memory. */
6541 qemu_log("IN: EXECUTE %016" PRIx64
, dc
->ex_value
);
6543 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
6544 log_target_disas(cs
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
6548 static const TranslatorOps s390x_tr_ops
= {
6549 .init_disas_context
= s390x_tr_init_disas_context
,
6550 .tb_start
= s390x_tr_tb_start
,
6551 .insn_start
= s390x_tr_insn_start
,
6552 .breakpoint_check
= s390x_tr_breakpoint_check
,
6553 .translate_insn
= s390x_tr_translate_insn
,
6554 .tb_stop
= s390x_tr_tb_stop
,
6555 .disas_log
= s390x_tr_disas_log
,
6558 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
6562 translator_loop(&s390x_tr_ops
, &dc
.base
, cs
, tb
, max_insns
);
6565 void restore_state_to_opc(CPUS390XState
*env
, TranslationBlock
*tb
,
6568 int cc_op
= data
[1];
6570 env
->psw
.addr
= data
[0];
6572 /* Update the CC opcode if it is not already up-to-date. */
6573 if ((cc_op
!= CC_OP_DYNAMIC
) && (cc_op
!= CC_OP_STATIC
)) {
6578 env
->int_pgm_ilen
= data
[2];