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 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"
33 #include "disas/disas.h"
36 #include "qemu/host-utils.h"
37 #include "exec/cpu_ldst.h"
39 /* global register indexes */
40 static TCGv_env cpu_env
;
42 #include "exec/gen-icount.h"
43 #include "exec/helper-proto.h"
44 #include "exec/helper-gen.h"
46 #include "trace-tcg.h"
50 /* Information that (most) every instruction needs to manipulate. */
51 typedef struct DisasContext DisasContext
;
52 typedef struct DisasInsn DisasInsn
;
53 typedef struct DisasFields DisasFields
;
56 struct TranslationBlock
*tb
;
57 const DisasInsn
*insn
;
61 bool singlestep_enabled
;
64 /* Information carried about a condition to be evaluated. */
71 struct { TCGv_i64 a
, b
; } s64
;
72 struct { TCGv_i32 a
, b
; } s32
;
78 #ifdef DEBUG_INLINE_BRANCHES
79 static uint64_t inline_branch_hit
[CC_OP_MAX
];
80 static uint64_t inline_branch_miss
[CC_OP_MAX
];
83 static uint64_t pc_to_link_info(DisasContext
*s
, uint64_t pc
)
85 if (!(s
->tb
->flags
& FLAG_MASK_64
)) {
86 if (s
->tb
->flags
& FLAG_MASK_32
) {
87 return pc
| 0x80000000;
93 void s390_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
96 S390CPU
*cpu
= S390_CPU(cs
);
97 CPUS390XState
*env
= &cpu
->env
;
100 if (env
->cc_op
> 3) {
101 cpu_fprintf(f
, "PSW=mask %016" PRIx64
" addr %016" PRIx64
" cc %15s\n",
102 env
->psw
.mask
, env
->psw
.addr
, cc_name(env
->cc_op
));
104 cpu_fprintf(f
, "PSW=mask %016" PRIx64
" addr %016" PRIx64
" cc %02x\n",
105 env
->psw
.mask
, env
->psw
.addr
, env
->cc_op
);
108 for (i
= 0; i
< 16; i
++) {
109 cpu_fprintf(f
, "R%02d=%016" PRIx64
, i
, env
->regs
[i
]);
111 cpu_fprintf(f
, "\n");
117 for (i
= 0; i
< 16; i
++) {
118 cpu_fprintf(f
, "F%02d=%016" PRIx64
, i
, get_freg(env
, i
)->ll
);
120 cpu_fprintf(f
, "\n");
126 for (i
= 0; i
< 32; i
++) {
127 cpu_fprintf(f
, "V%02d=%016" PRIx64
"%016" PRIx64
, i
,
128 env
->vregs
[i
][0].ll
, env
->vregs
[i
][1].ll
);
129 cpu_fprintf(f
, (i
% 2) ? "\n" : " ");
132 #ifndef CONFIG_USER_ONLY
133 for (i
= 0; i
< 16; i
++) {
134 cpu_fprintf(f
, "C%02d=%016" PRIx64
, i
, env
->cregs
[i
]);
136 cpu_fprintf(f
, "\n");
143 #ifdef DEBUG_INLINE_BRANCHES
144 for (i
= 0; i
< CC_OP_MAX
; i
++) {
145 cpu_fprintf(f
, " %15s = %10ld\t%10ld\n", cc_name(i
),
146 inline_branch_miss
[i
], inline_branch_hit
[i
]);
150 cpu_fprintf(f
, "\n");
153 static TCGv_i64 psw_addr
;
154 static TCGv_i64 psw_mask
;
155 static TCGv_i64 gbea
;
157 static TCGv_i32 cc_op
;
158 static TCGv_i64 cc_src
;
159 static TCGv_i64 cc_dst
;
160 static TCGv_i64 cc_vr
;
162 static char cpu_reg_names
[32][4];
163 static TCGv_i64 regs
[16];
164 static TCGv_i64 fregs
[16];
166 void s390x_translate_init(void)
170 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
171 psw_addr
= tcg_global_mem_new_i64(cpu_env
,
172 offsetof(CPUS390XState
, psw
.addr
),
174 psw_mask
= tcg_global_mem_new_i64(cpu_env
,
175 offsetof(CPUS390XState
, psw
.mask
),
177 gbea
= tcg_global_mem_new_i64(cpu_env
,
178 offsetof(CPUS390XState
, gbea
),
181 cc_op
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUS390XState
, cc_op
),
183 cc_src
= tcg_global_mem_new_i64(cpu_env
, offsetof(CPUS390XState
, cc_src
),
185 cc_dst
= tcg_global_mem_new_i64(cpu_env
, offsetof(CPUS390XState
, cc_dst
),
187 cc_vr
= tcg_global_mem_new_i64(cpu_env
, offsetof(CPUS390XState
, cc_vr
),
190 for (i
= 0; i
< 16; i
++) {
191 snprintf(cpu_reg_names
[i
], sizeof(cpu_reg_names
[0]), "r%d", i
);
192 regs
[i
] = tcg_global_mem_new(cpu_env
,
193 offsetof(CPUS390XState
, regs
[i
]),
197 for (i
= 0; i
< 16; i
++) {
198 snprintf(cpu_reg_names
[i
+ 16], sizeof(cpu_reg_names
[0]), "f%d", i
);
199 fregs
[i
] = tcg_global_mem_new(cpu_env
,
200 offsetof(CPUS390XState
, vregs
[i
][0].d
),
201 cpu_reg_names
[i
+ 16]);
205 static TCGv_i64
load_reg(int reg
)
207 TCGv_i64 r
= tcg_temp_new_i64();
208 tcg_gen_mov_i64(r
, regs
[reg
]);
212 static TCGv_i64
load_freg32_i64(int reg
)
214 TCGv_i64 r
= tcg_temp_new_i64();
215 tcg_gen_shri_i64(r
, fregs
[reg
], 32);
219 static void store_reg(int reg
, TCGv_i64 v
)
221 tcg_gen_mov_i64(regs
[reg
], v
);
224 static void store_freg(int reg
, TCGv_i64 v
)
226 tcg_gen_mov_i64(fregs
[reg
], v
);
229 static void store_reg32_i64(int reg
, TCGv_i64 v
)
231 /* 32 bit register writes keep the upper half */
232 tcg_gen_deposit_i64(regs
[reg
], regs
[reg
], v
, 0, 32);
235 static void store_reg32h_i64(int reg
, TCGv_i64 v
)
237 tcg_gen_deposit_i64(regs
[reg
], regs
[reg
], v
, 32, 32);
240 static void store_freg32_i64(int reg
, TCGv_i64 v
)
242 tcg_gen_deposit_i64(fregs
[reg
], fregs
[reg
], v
, 32, 32);
245 static void return_low128(TCGv_i64 dest
)
247 tcg_gen_ld_i64(dest
, cpu_env
, offsetof(CPUS390XState
, retxl
));
250 static void update_psw_addr(DisasContext
*s
)
253 tcg_gen_movi_i64(psw_addr
, s
->pc
);
256 static void per_branch(DisasContext
*s
, bool to_next
)
258 #ifndef CONFIG_USER_ONLY
259 tcg_gen_movi_i64(gbea
, s
->pc
);
261 if (s
->tb
->flags
& FLAG_MASK_PER
) {
262 TCGv_i64 next_pc
= to_next
? tcg_const_i64(s
->next_pc
) : psw_addr
;
263 gen_helper_per_branch(cpu_env
, gbea
, next_pc
);
265 tcg_temp_free_i64(next_pc
);
271 static void per_branch_cond(DisasContext
*s
, TCGCond cond
,
272 TCGv_i64 arg1
, TCGv_i64 arg2
)
274 #ifndef CONFIG_USER_ONLY
275 if (s
->tb
->flags
& FLAG_MASK_PER
) {
276 TCGLabel
*lab
= gen_new_label();
277 tcg_gen_brcond_i64(tcg_invert_cond(cond
), arg1
, arg2
, lab
);
279 tcg_gen_movi_i64(gbea
, s
->pc
);
280 gen_helper_per_branch(cpu_env
, gbea
, psw_addr
);
284 TCGv_i64 pc
= tcg_const_i64(s
->pc
);
285 tcg_gen_movcond_i64(cond
, gbea
, arg1
, arg2
, gbea
, pc
);
286 tcg_temp_free_i64(pc
);
291 static void per_breaking_event(DisasContext
*s
)
293 tcg_gen_movi_i64(gbea
, s
->pc
);
296 static void update_cc_op(DisasContext
*s
)
298 if (s
->cc_op
!= CC_OP_DYNAMIC
&& s
->cc_op
!= CC_OP_STATIC
) {
299 tcg_gen_movi_i32(cc_op
, s
->cc_op
);
303 static void potential_page_fault(DisasContext
*s
)
309 static inline uint64_t ld_code2(CPUS390XState
*env
, uint64_t pc
)
311 return (uint64_t)cpu_lduw_code(env
, pc
);
314 static inline uint64_t ld_code4(CPUS390XState
*env
, uint64_t pc
)
316 return (uint64_t)(uint32_t)cpu_ldl_code(env
, pc
);
319 static int get_mem_index(DisasContext
*s
)
321 switch (s
->tb
->flags
& FLAG_MASK_ASC
) {
322 case PSW_ASC_PRIMARY
>> 32:
324 case PSW_ASC_SECONDARY
>> 32:
326 case PSW_ASC_HOME
>> 32:
334 static void gen_exception(int excp
)
336 TCGv_i32 tmp
= tcg_const_i32(excp
);
337 gen_helper_exception(cpu_env
, tmp
);
338 tcg_temp_free_i32(tmp
);
341 static void gen_program_exception(DisasContext
*s
, int code
)
345 /* Remember what pgm exeption this was. */
346 tmp
= tcg_const_i32(code
);
347 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUS390XState
, int_pgm_code
));
348 tcg_temp_free_i32(tmp
);
350 tmp
= tcg_const_i32(s
->next_pc
- s
->pc
);
351 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUS390XState
, int_pgm_ilen
));
352 tcg_temp_free_i32(tmp
);
354 /* Advance past instruction. */
361 /* Trigger exception. */
362 gen_exception(EXCP_PGM
);
365 static inline void gen_illegal_opcode(DisasContext
*s
)
367 gen_program_exception(s
, PGM_OPERATION
);
370 static inline void gen_trap(DisasContext
*s
)
374 /* Set DXC to 0xff. */
375 t
= tcg_temp_new_i32();
376 tcg_gen_ld_i32(t
, cpu_env
, offsetof(CPUS390XState
, fpc
));
377 tcg_gen_ori_i32(t
, t
, 0xff00);
378 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUS390XState
, fpc
));
379 tcg_temp_free_i32(t
);
381 gen_program_exception(s
, PGM_DATA
);
384 #ifndef CONFIG_USER_ONLY
385 static void check_privileged(DisasContext
*s
)
387 if (s
->tb
->flags
& (PSW_MASK_PSTATE
>> 32)) {
388 gen_program_exception(s
, PGM_PRIVILEGED
);
393 static TCGv_i64
get_address(DisasContext
*s
, int x2
, int b2
, int d2
)
395 TCGv_i64 tmp
= tcg_temp_new_i64();
396 bool need_31
= !(s
->tb
->flags
& FLAG_MASK_64
);
398 /* Note that d2 is limited to 20 bits, signed. If we crop negative
399 displacements early we create larger immedate addends. */
401 /* Note that addi optimizes the imm==0 case. */
403 tcg_gen_add_i64(tmp
, regs
[b2
], regs
[x2
]);
404 tcg_gen_addi_i64(tmp
, tmp
, d2
);
406 tcg_gen_addi_i64(tmp
, regs
[b2
], d2
);
408 tcg_gen_addi_i64(tmp
, regs
[x2
], d2
);
414 tcg_gen_movi_i64(tmp
, d2
);
417 tcg_gen_andi_i64(tmp
, tmp
, 0x7fffffff);
423 static inline bool live_cc_data(DisasContext
*s
)
425 return (s
->cc_op
!= CC_OP_DYNAMIC
426 && s
->cc_op
!= CC_OP_STATIC
430 static inline void gen_op_movi_cc(DisasContext
*s
, uint32_t val
)
432 if (live_cc_data(s
)) {
433 tcg_gen_discard_i64(cc_src
);
434 tcg_gen_discard_i64(cc_dst
);
435 tcg_gen_discard_i64(cc_vr
);
437 s
->cc_op
= CC_OP_CONST0
+ val
;
440 static void gen_op_update1_cc_i64(DisasContext
*s
, enum cc_op op
, TCGv_i64 dst
)
442 if (live_cc_data(s
)) {
443 tcg_gen_discard_i64(cc_src
);
444 tcg_gen_discard_i64(cc_vr
);
446 tcg_gen_mov_i64(cc_dst
, dst
);
450 static void gen_op_update2_cc_i64(DisasContext
*s
, enum cc_op op
, TCGv_i64 src
,
453 if (live_cc_data(s
)) {
454 tcg_gen_discard_i64(cc_vr
);
456 tcg_gen_mov_i64(cc_src
, src
);
457 tcg_gen_mov_i64(cc_dst
, dst
);
461 static void gen_op_update3_cc_i64(DisasContext
*s
, enum cc_op op
, TCGv_i64 src
,
462 TCGv_i64 dst
, TCGv_i64 vr
)
464 tcg_gen_mov_i64(cc_src
, src
);
465 tcg_gen_mov_i64(cc_dst
, dst
);
466 tcg_gen_mov_i64(cc_vr
, vr
);
470 static void set_cc_nz_u64(DisasContext
*s
, TCGv_i64 val
)
472 gen_op_update1_cc_i64(s
, CC_OP_NZ
, val
);
475 static void gen_set_cc_nz_f32(DisasContext
*s
, TCGv_i64 val
)
477 gen_op_update1_cc_i64(s
, CC_OP_NZ_F32
, val
);
480 static void gen_set_cc_nz_f64(DisasContext
*s
, TCGv_i64 val
)
482 gen_op_update1_cc_i64(s
, CC_OP_NZ_F64
, val
);
485 static void gen_set_cc_nz_f128(DisasContext
*s
, TCGv_i64 vh
, TCGv_i64 vl
)
487 gen_op_update2_cc_i64(s
, CC_OP_NZ_F128
, vh
, vl
);
490 /* CC value is in env->cc_op */
491 static void set_cc_static(DisasContext
*s
)
493 if (live_cc_data(s
)) {
494 tcg_gen_discard_i64(cc_src
);
495 tcg_gen_discard_i64(cc_dst
);
496 tcg_gen_discard_i64(cc_vr
);
498 s
->cc_op
= CC_OP_STATIC
;
501 /* calculates cc into cc_op */
502 static void gen_op_calc_cc(DisasContext
*s
)
504 TCGv_i32 local_cc_op
;
507 TCGV_UNUSED_I32(local_cc_op
);
508 TCGV_UNUSED_I64(dummy
);
511 dummy
= tcg_const_i64(0);
525 local_cc_op
= tcg_const_i32(s
->cc_op
);
541 /* s->cc_op is the cc value */
542 tcg_gen_movi_i32(cc_op
, s
->cc_op
- CC_OP_CONST0
);
545 /* env->cc_op already is the cc value */
560 gen_helper_calc_cc(cc_op
, cpu_env
, local_cc_op
, dummy
, cc_dst
, dummy
);
565 case CC_OP_LTUGTU_32
:
566 case CC_OP_LTUGTU_64
:
573 gen_helper_calc_cc(cc_op
, cpu_env
, local_cc_op
, cc_src
, cc_dst
, dummy
);
588 gen_helper_calc_cc(cc_op
, cpu_env
, local_cc_op
, cc_src
, cc_dst
, cc_vr
);
591 /* unknown operation - assume 3 arguments and cc_op in env */
592 gen_helper_calc_cc(cc_op
, cpu_env
, cc_op
, cc_src
, cc_dst
, cc_vr
);
598 if (!TCGV_IS_UNUSED_I32(local_cc_op
)) {
599 tcg_temp_free_i32(local_cc_op
);
601 if (!TCGV_IS_UNUSED_I64(dummy
)) {
602 tcg_temp_free_i64(dummy
);
605 /* We now have cc in cc_op as constant */
609 static int use_goto_tb(DisasContext
*s
, uint64_t dest
)
611 if (unlikely(s
->singlestep_enabled
) ||
612 (s
->tb
->cflags
& CF_LAST_IO
) ||
613 (s
->tb
->flags
& FLAG_MASK_PER
)) {
616 #ifndef CONFIG_USER_ONLY
617 return (dest
& TARGET_PAGE_MASK
) == (s
->tb
->pc
& TARGET_PAGE_MASK
) ||
618 (dest
& TARGET_PAGE_MASK
) == (s
->pc
& TARGET_PAGE_MASK
);
624 static void account_noninline_branch(DisasContext
*s
, int cc_op
)
626 #ifdef DEBUG_INLINE_BRANCHES
627 inline_branch_miss
[cc_op
]++;
631 static void account_inline_branch(DisasContext
*s
, int cc_op
)
633 #ifdef DEBUG_INLINE_BRANCHES
634 inline_branch_hit
[cc_op
]++;
638 /* Table of mask values to comparison codes, given a comparison as input.
639 For such, CC=3 should not be possible. */
640 static const TCGCond ltgt_cond
[16] = {
641 TCG_COND_NEVER
, TCG_COND_NEVER
, /* | | | x */
642 TCG_COND_GT
, TCG_COND_GT
, /* | | GT | x */
643 TCG_COND_LT
, TCG_COND_LT
, /* | LT | | x */
644 TCG_COND_NE
, TCG_COND_NE
, /* | LT | GT | x */
645 TCG_COND_EQ
, TCG_COND_EQ
, /* EQ | | | x */
646 TCG_COND_GE
, TCG_COND_GE
, /* EQ | | GT | x */
647 TCG_COND_LE
, TCG_COND_LE
, /* EQ | LT | | x */
648 TCG_COND_ALWAYS
, TCG_COND_ALWAYS
, /* EQ | LT | GT | x */
651 /* Table of mask values to comparison codes, given a logic op as input.
652 For such, only CC=0 and CC=1 should be possible. */
653 static const TCGCond nz_cond
[16] = {
654 TCG_COND_NEVER
, TCG_COND_NEVER
, /* | | x | x */
655 TCG_COND_NEVER
, TCG_COND_NEVER
,
656 TCG_COND_NE
, TCG_COND_NE
, /* | NE | x | x */
657 TCG_COND_NE
, TCG_COND_NE
,
658 TCG_COND_EQ
, TCG_COND_EQ
, /* EQ | | x | x */
659 TCG_COND_EQ
, TCG_COND_EQ
,
660 TCG_COND_ALWAYS
, TCG_COND_ALWAYS
, /* EQ | NE | x | x */
661 TCG_COND_ALWAYS
, TCG_COND_ALWAYS
,
664 /* Interpret MASK in terms of S->CC_OP, and fill in C with all the
665 details required to generate a TCG comparison. */
666 static void disas_jcc(DisasContext
*s
, DisasCompare
*c
, uint32_t mask
)
669 enum cc_op old_cc_op
= s
->cc_op
;
671 if (mask
== 15 || mask
== 0) {
672 c
->cond
= (mask
? TCG_COND_ALWAYS
: TCG_COND_NEVER
);
675 c
->g1
= c
->g2
= true;
680 /* Find the TCG condition for the mask + cc op. */
686 cond
= ltgt_cond
[mask
];
687 if (cond
== TCG_COND_NEVER
) {
690 account_inline_branch(s
, old_cc_op
);
693 case CC_OP_LTUGTU_32
:
694 case CC_OP_LTUGTU_64
:
695 cond
= tcg_unsigned_cond(ltgt_cond
[mask
]);
696 if (cond
== TCG_COND_NEVER
) {
699 account_inline_branch(s
, old_cc_op
);
703 cond
= nz_cond
[mask
];
704 if (cond
== TCG_COND_NEVER
) {
707 account_inline_branch(s
, old_cc_op
);
722 account_inline_branch(s
, old_cc_op
);
737 account_inline_branch(s
, old_cc_op
);
741 switch (mask
& 0xa) {
742 case 8: /* src == 0 -> no one bit found */
745 case 2: /* src != 0 -> one bit found */
751 account_inline_branch(s
, old_cc_op
);
757 case 8 | 2: /* vr == 0 */
760 case 4 | 1: /* vr != 0 */
763 case 8 | 4: /* no carry -> vr >= src */
766 case 2 | 1: /* carry -> vr < src */
772 account_inline_branch(s
, old_cc_op
);
777 /* Note that CC=0 is impossible; treat it as dont-care. */
779 case 2: /* zero -> op1 == op2 */
782 case 4 | 1: /* !zero -> op1 != op2 */
785 case 4: /* borrow (!carry) -> op1 < op2 */
788 case 2 | 1: /* !borrow (carry) -> op1 >= op2 */
794 account_inline_branch(s
, old_cc_op
);
799 /* Calculate cc value. */
804 /* Jump based on CC. We'll load up the real cond below;
805 the assignment here merely avoids a compiler warning. */
806 account_noninline_branch(s
, old_cc_op
);
807 old_cc_op
= CC_OP_STATIC
;
808 cond
= TCG_COND_NEVER
;
812 /* Load up the arguments of the comparison. */
814 c
->g1
= c
->g2
= false;
818 c
->u
.s32
.a
= tcg_temp_new_i32();
819 tcg_gen_extrl_i64_i32(c
->u
.s32
.a
, cc_dst
);
820 c
->u
.s32
.b
= tcg_const_i32(0);
823 case CC_OP_LTUGTU_32
:
826 c
->u
.s32
.a
= tcg_temp_new_i32();
827 tcg_gen_extrl_i64_i32(c
->u
.s32
.a
, cc_src
);
828 c
->u
.s32
.b
= tcg_temp_new_i32();
829 tcg_gen_extrl_i64_i32(c
->u
.s32
.b
, cc_dst
);
836 c
->u
.s64
.b
= tcg_const_i64(0);
840 case CC_OP_LTUGTU_64
:
844 c
->g1
= c
->g2
= true;
850 c
->u
.s64
.a
= tcg_temp_new_i64();
851 c
->u
.s64
.b
= tcg_const_i64(0);
852 tcg_gen_and_i64(c
->u
.s64
.a
, cc_src
, cc_dst
);
857 c
->u
.s32
.a
= tcg_temp_new_i32();
858 c
->u
.s32
.b
= tcg_temp_new_i32();
859 tcg_gen_extrl_i64_i32(c
->u
.s32
.a
, cc_vr
);
860 if (cond
== TCG_COND_EQ
|| cond
== TCG_COND_NE
) {
861 tcg_gen_movi_i32(c
->u
.s32
.b
, 0);
863 tcg_gen_extrl_i64_i32(c
->u
.s32
.b
, cc_src
);
870 if (cond
== TCG_COND_EQ
|| cond
== TCG_COND_NE
) {
871 c
->u
.s64
.b
= tcg_const_i64(0);
883 case 0x8 | 0x4 | 0x2: /* cc != 3 */
885 c
->u
.s32
.b
= tcg_const_i32(3);
887 case 0x8 | 0x4 | 0x1: /* cc != 2 */
889 c
->u
.s32
.b
= tcg_const_i32(2);
891 case 0x8 | 0x2 | 0x1: /* cc != 1 */
893 c
->u
.s32
.b
= tcg_const_i32(1);
895 case 0x8 | 0x2: /* cc == 0 ||Â cc == 2 => (cc & 1) == 0 */
898 c
->u
.s32
.a
= tcg_temp_new_i32();
899 c
->u
.s32
.b
= tcg_const_i32(0);
900 tcg_gen_andi_i32(c
->u
.s32
.a
, cc_op
, 1);
902 case 0x8 | 0x4: /* cc < 2 */
904 c
->u
.s32
.b
= tcg_const_i32(2);
906 case 0x8: /* cc == 0 */
908 c
->u
.s32
.b
= tcg_const_i32(0);
910 case 0x4 | 0x2 | 0x1: /* cc != 0 */
912 c
->u
.s32
.b
= tcg_const_i32(0);
914 case 0x4 | 0x1: /* cc == 1 ||Â cc == 3 => (cc & 1) != 0 */
917 c
->u
.s32
.a
= tcg_temp_new_i32();
918 c
->u
.s32
.b
= tcg_const_i32(0);
919 tcg_gen_andi_i32(c
->u
.s32
.a
, cc_op
, 1);
921 case 0x4: /* cc == 1 */
923 c
->u
.s32
.b
= tcg_const_i32(1);
925 case 0x2 | 0x1: /* cc > 1 */
927 c
->u
.s32
.b
= tcg_const_i32(1);
929 case 0x2: /* cc == 2 */
931 c
->u
.s32
.b
= tcg_const_i32(2);
933 case 0x1: /* cc == 3 */
935 c
->u
.s32
.b
= tcg_const_i32(3);
938 /* CC is masked by something else: (8 >> cc) & mask. */
941 c
->u
.s32
.a
= tcg_const_i32(8);
942 c
->u
.s32
.b
= tcg_const_i32(0);
943 tcg_gen_shr_i32(c
->u
.s32
.a
, c
->u
.s32
.a
, cc_op
);
944 tcg_gen_andi_i32(c
->u
.s32
.a
, c
->u
.s32
.a
, mask
);
955 static void free_compare(DisasCompare
*c
)
959 tcg_temp_free_i64(c
->u
.s64
.a
);
961 tcg_temp_free_i32(c
->u
.s32
.a
);
966 tcg_temp_free_i64(c
->u
.s64
.b
);
968 tcg_temp_free_i32(c
->u
.s32
.b
);
973 /* ====================================================================== */
974 /* Define the insn format enumeration. */
975 #define F0(N) FMT_##N,
976 #define F1(N, X1) F0(N)
977 #define F2(N, X1, X2) F0(N)
978 #define F3(N, X1, X2, X3) F0(N)
979 #define F4(N, X1, X2, X3, X4) F0(N)
980 #define F5(N, X1, X2, X3, X4, X5) F0(N)
983 #include "insn-format.def"
993 /* Define a structure to hold the decoded fields. We'll store each inside
994 an array indexed by an enum. In order to conserve memory, we'll arrange
995 for fields that do not exist at the same time to overlap, thus the "C"
996 for compact. For checking purposes there is an "O" for original index
997 as well that will be applied to availability bitmaps. */
999 enum DisasFieldIndexO
{
1022 enum DisasFieldIndexC
{
1053 struct DisasFields
{
1057 unsigned presentC
:16;
1058 unsigned int presentO
;
1062 /* This is the way fields are to be accessed out of DisasFields. */
1063 #define have_field(S, F) have_field1((S), FLD_O_##F)
1064 #define get_field(S, F) get_field1((S), FLD_O_##F, FLD_C_##F)
1066 static bool have_field1(const DisasFields
*f
, enum DisasFieldIndexO c
)
1068 return (f
->presentO
>> c
) & 1;
1071 static int get_field1(const DisasFields
*f
, enum DisasFieldIndexO o
,
1072 enum DisasFieldIndexC c
)
1074 assert(have_field1(f
, o
));
1078 /* Describe the layout of each field in each format. */
1079 typedef struct DisasField
{
1081 unsigned int size
:8;
1082 unsigned int type
:2;
1083 unsigned int indexC
:6;
1084 enum DisasFieldIndexO indexO
:8;
1087 typedef struct DisasFormatInfo
{
1088 DisasField op
[NUM_C_FIELD
];
1091 #define R(N, B) { B, 4, 0, FLD_C_r##N, FLD_O_r##N }
1092 #define M(N, B) { B, 4, 0, FLD_C_m##N, FLD_O_m##N }
1093 #define BD(N, BB, BD) { BB, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
1094 { BD, 12, 0, FLD_C_d##N, FLD_O_d##N }
1095 #define BXD(N) { 16, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
1096 { 12, 4, 0, FLD_C_x##N, FLD_O_x##N }, \
1097 { 20, 12, 0, FLD_C_d##N, FLD_O_d##N }
1098 #define BDL(N) { 16, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
1099 { 20, 20, 2, FLD_C_d##N, FLD_O_d##N }
1100 #define BXDL(N) { 16, 4, 0, FLD_C_b##N, FLD_O_b##N }, \
1101 { 12, 4, 0, FLD_C_x##N, FLD_O_x##N }, \
1102 { 20, 20, 2, FLD_C_d##N, FLD_O_d##N }
1103 #define I(N, B, S) { B, S, 1, FLD_C_i##N, FLD_O_i##N }
1104 #define L(N, B, S) { B, S, 0, FLD_C_l##N, FLD_O_l##N }
1106 #define F0(N) { { } },
1107 #define F1(N, X1) { { X1 } },
1108 #define F2(N, X1, X2) { { X1, X2 } },
1109 #define F3(N, X1, X2, X3) { { X1, X2, X3 } },
1110 #define F4(N, X1, X2, X3, X4) { { X1, X2, X3, X4 } },
1111 #define F5(N, X1, X2, X3, X4, X5) { { X1, X2, X3, X4, X5 } },
1113 static const DisasFormatInfo format_info
[] = {
1114 #include "insn-format.def"
1132 /* Generally, we'll extract operands into this structures, operate upon
1133 them, and store them back. See the "in1", "in2", "prep", "wout" sets
1134 of routines below for more details. */
1136 bool g_out
, g_out2
, g_in1
, g_in2
;
1137 TCGv_i64 out
, out2
, in1
, in2
;
1141 /* Instructions can place constraints on their operands, raising specification
1142 exceptions if they are violated. To make this easy to automate, each "in1",
1143 "in2", "prep", "wout" helper will have a SPEC_<name> define that equals one
1144 of the following, or 0. To make this easy to document, we'll put the
1145 SPEC_<name> defines next to <name>. */
1147 #define SPEC_r1_even 1
1148 #define SPEC_r2_even 2
1149 #define SPEC_r3_even 4
1150 #define SPEC_r1_f128 8
1151 #define SPEC_r2_f128 16
1153 /* Return values from translate_one, indicating the state of the TB. */
1155 /* Continue the TB. */
1157 /* We have emitted one or more goto_tb. No fixup required. */
1159 /* We are not using a goto_tb (for whatever reason), but have updated
1160 the PC (for whatever reason), so there's no need to do it again on
1163 /* We are exiting the TB, but have neither emitted a goto_tb, nor
1164 updated the PC for the next instruction to be executed. */
1166 /* We are ending the TB with a noreturn function call, e.g. longjmp.
1167 No following code will be executed. */
1171 typedef enum DisasFacility
{
1172 FAC_Z
, /* zarch (default) */
1173 FAC_CASS
, /* compare and swap and store */
1174 FAC_CASS2
, /* compare and swap and store 2*/
1175 FAC_DFP
, /* decimal floating point */
1176 FAC_DFPR
, /* decimal floating point rounding */
1177 FAC_DO
, /* distinct operands */
1178 FAC_EE
, /* execute extensions */
1179 FAC_EI
, /* extended immediate */
1180 FAC_FPE
, /* floating point extension */
1181 FAC_FPSSH
, /* floating point support sign handling */
1182 FAC_FPRGR
, /* FPR-GR transfer */
1183 FAC_GIE
, /* general instructions extension */
1184 FAC_HFP_MA
, /* HFP multiply-and-add/subtract */
1185 FAC_HW
, /* high-word */
1186 FAC_IEEEE_SIM
, /* IEEE exception sumilation */
1187 FAC_MIE
, /* miscellaneous-instruction-extensions */
1188 FAC_LAT
, /* load-and-trap */
1189 FAC_LOC
, /* load/store on condition */
1190 FAC_LD
, /* long displacement */
1191 FAC_PC
, /* population count */
1192 FAC_SCF
, /* store clock fast */
1193 FAC_SFLE
, /* store facility list extended */
1194 FAC_ILA
, /* interlocked access facility 1 */
1200 DisasFacility fac
:8;
1205 void (*help_in1
)(DisasContext
*, DisasFields
*, DisasOps
*);
1206 void (*help_in2
)(DisasContext
*, DisasFields
*, DisasOps
*);
1207 void (*help_prep
)(DisasContext
*, DisasFields
*, DisasOps
*);
1208 void (*help_wout
)(DisasContext
*, DisasFields
*, DisasOps
*);
1209 void (*help_cout
)(DisasContext
*, DisasOps
*);
1210 ExitStatus (*help_op
)(DisasContext
*, DisasOps
*);
1215 /* ====================================================================== */
1216 /* Miscellaneous helpers, used by several operations. */
1218 static void help_l2_shift(DisasContext
*s
, DisasFields
*f
,
1219 DisasOps
*o
, int mask
)
1221 int b2
= get_field(f
, b2
);
1222 int d2
= get_field(f
, d2
);
1225 o
->in2
= tcg_const_i64(d2
& mask
);
1227 o
->in2
= get_address(s
, 0, b2
, d2
);
1228 tcg_gen_andi_i64(o
->in2
, o
->in2
, mask
);
1232 static ExitStatus
help_goto_direct(DisasContext
*s
, uint64_t dest
)
1234 if (dest
== s
->next_pc
) {
1235 per_branch(s
, true);
1238 if (use_goto_tb(s
, dest
)) {
1240 per_breaking_event(s
);
1242 tcg_gen_movi_i64(psw_addr
, dest
);
1243 tcg_gen_exit_tb((uintptr_t)s
->tb
);
1244 return EXIT_GOTO_TB
;
1246 tcg_gen_movi_i64(psw_addr
, dest
);
1247 per_branch(s
, false);
1248 return EXIT_PC_UPDATED
;
1252 static ExitStatus
help_branch(DisasContext
*s
, DisasCompare
*c
,
1253 bool is_imm
, int imm
, TCGv_i64 cdest
)
1256 uint64_t dest
= s
->pc
+ 2 * imm
;
1259 /* Take care of the special cases first. */
1260 if (c
->cond
== TCG_COND_NEVER
) {
1265 if (dest
== s
->next_pc
) {
1266 /* Branch to next. */
1267 per_branch(s
, true);
1271 if (c
->cond
== TCG_COND_ALWAYS
) {
1272 ret
= help_goto_direct(s
, dest
);
1276 if (TCGV_IS_UNUSED_I64(cdest
)) {
1277 /* E.g. bcr %r0 -> no branch. */
1281 if (c
->cond
== TCG_COND_ALWAYS
) {
1282 tcg_gen_mov_i64(psw_addr
, cdest
);
1283 per_branch(s
, false);
1284 ret
= EXIT_PC_UPDATED
;
1289 if (use_goto_tb(s
, s
->next_pc
)) {
1290 if (is_imm
&& use_goto_tb(s
, dest
)) {
1291 /* Both exits can use goto_tb. */
1294 lab
= gen_new_label();
1296 tcg_gen_brcond_i64(c
->cond
, c
->u
.s64
.a
, c
->u
.s64
.b
, lab
);
1298 tcg_gen_brcond_i32(c
->cond
, c
->u
.s32
.a
, c
->u
.s32
.b
, lab
);
1301 /* Branch not taken. */
1303 tcg_gen_movi_i64(psw_addr
, s
->next_pc
);
1304 tcg_gen_exit_tb((uintptr_t)s
->tb
+ 0);
1308 per_breaking_event(s
);
1310 tcg_gen_movi_i64(psw_addr
, dest
);
1311 tcg_gen_exit_tb((uintptr_t)s
->tb
+ 1);
1315 /* Fallthru can use goto_tb, but taken branch cannot. */
1316 /* Store taken branch destination before the brcond. This
1317 avoids having to allocate a new local temp to hold it.
1318 We'll overwrite this in the not taken case anyway. */
1320 tcg_gen_mov_i64(psw_addr
, cdest
);
1323 lab
= gen_new_label();
1325 tcg_gen_brcond_i64(c
->cond
, c
->u
.s64
.a
, c
->u
.s64
.b
, lab
);
1327 tcg_gen_brcond_i32(c
->cond
, c
->u
.s32
.a
, c
->u
.s32
.b
, lab
);
1330 /* Branch not taken. */
1333 tcg_gen_movi_i64(psw_addr
, s
->next_pc
);
1334 tcg_gen_exit_tb((uintptr_t)s
->tb
+ 0);
1338 tcg_gen_movi_i64(psw_addr
, dest
);
1340 per_breaking_event(s
);
1341 ret
= EXIT_PC_UPDATED
;
1344 /* Fallthru cannot use goto_tb. This by itself is vanishingly rare.
1345 Most commonly we're single-stepping or some other condition that
1346 disables all use of goto_tb. Just update the PC and exit. */
1348 TCGv_i64 next
= tcg_const_i64(s
->next_pc
);
1350 cdest
= tcg_const_i64(dest
);
1354 tcg_gen_movcond_i64(c
->cond
, psw_addr
, c
->u
.s64
.a
, c
->u
.s64
.b
,
1356 per_branch_cond(s
, c
->cond
, c
->u
.s64
.a
, c
->u
.s64
.b
);
1358 TCGv_i32 t0
= tcg_temp_new_i32();
1359 TCGv_i64 t1
= tcg_temp_new_i64();
1360 TCGv_i64 z
= tcg_const_i64(0);
1361 tcg_gen_setcond_i32(c
->cond
, t0
, c
->u
.s32
.a
, c
->u
.s32
.b
);
1362 tcg_gen_extu_i32_i64(t1
, t0
);
1363 tcg_temp_free_i32(t0
);
1364 tcg_gen_movcond_i64(TCG_COND_NE
, psw_addr
, t1
, z
, cdest
, next
);
1365 per_branch_cond(s
, TCG_COND_NE
, t1
, z
);
1366 tcg_temp_free_i64(t1
);
1367 tcg_temp_free_i64(z
);
1371 tcg_temp_free_i64(cdest
);
1373 tcg_temp_free_i64(next
);
1375 ret
= EXIT_PC_UPDATED
;
1383 /* ====================================================================== */
1384 /* The operations. These perform the bulk of the work for any insn,
1385 usually after the operands have been loaded and output initialized. */
1387 static ExitStatus
op_abs(DisasContext
*s
, DisasOps
*o
)
1390 z
= tcg_const_i64(0);
1391 n
= tcg_temp_new_i64();
1392 tcg_gen_neg_i64(n
, o
->in2
);
1393 tcg_gen_movcond_i64(TCG_COND_LT
, o
->out
, o
->in2
, z
, n
, o
->in2
);
1394 tcg_temp_free_i64(n
);
1395 tcg_temp_free_i64(z
);
1399 static ExitStatus
op_absf32(DisasContext
*s
, DisasOps
*o
)
1401 tcg_gen_andi_i64(o
->out
, o
->in2
, 0x7fffffffull
);
1405 static ExitStatus
op_absf64(DisasContext
*s
, DisasOps
*o
)
1407 tcg_gen_andi_i64(o
->out
, o
->in2
, 0x7fffffffffffffffull
);
1411 static ExitStatus
op_absf128(DisasContext
*s
, DisasOps
*o
)
1413 tcg_gen_andi_i64(o
->out
, o
->in1
, 0x7fffffffffffffffull
);
1414 tcg_gen_mov_i64(o
->out2
, o
->in2
);
1418 static ExitStatus
op_add(DisasContext
*s
, DisasOps
*o
)
1420 tcg_gen_add_i64(o
->out
, o
->in1
, o
->in2
);
1424 static ExitStatus
op_addc(DisasContext
*s
, DisasOps
*o
)
1429 tcg_gen_add_i64(o
->out
, o
->in1
, o
->in2
);
1431 /* The carry flag is the msb of CC, therefore the branch mask that would
1432 create that comparison is 3. Feeding the generated comparison to
1433 setcond produces the carry flag that we desire. */
1434 disas_jcc(s
, &cmp
, 3);
1435 carry
= tcg_temp_new_i64();
1437 tcg_gen_setcond_i64(cmp
.cond
, carry
, cmp
.u
.s64
.a
, cmp
.u
.s64
.b
);
1439 TCGv_i32 t
= tcg_temp_new_i32();
1440 tcg_gen_setcond_i32(cmp
.cond
, t
, cmp
.u
.s32
.a
, cmp
.u
.s32
.b
);
1441 tcg_gen_extu_i32_i64(carry
, t
);
1442 tcg_temp_free_i32(t
);
1446 tcg_gen_add_i64(o
->out
, o
->out
, carry
);
1447 tcg_temp_free_i64(carry
);
1451 static ExitStatus
op_aeb(DisasContext
*s
, DisasOps
*o
)
1453 gen_helper_aeb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
1457 static ExitStatus
op_adb(DisasContext
*s
, DisasOps
*o
)
1459 gen_helper_adb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
1463 static ExitStatus
op_axb(DisasContext
*s
, DisasOps
*o
)
1465 gen_helper_axb(o
->out
, cpu_env
, o
->out
, o
->out2
, o
->in1
, o
->in2
);
1466 return_low128(o
->out2
);
1470 static ExitStatus
op_and(DisasContext
*s
, DisasOps
*o
)
1472 tcg_gen_and_i64(o
->out
, o
->in1
, o
->in2
);
1476 static ExitStatus
op_andi(DisasContext
*s
, DisasOps
*o
)
1478 int shift
= s
->insn
->data
& 0xff;
1479 int size
= s
->insn
->data
>> 8;
1480 uint64_t mask
= ((1ull << size
) - 1) << shift
;
1483 tcg_gen_shli_i64(o
->in2
, o
->in2
, shift
);
1484 tcg_gen_ori_i64(o
->in2
, o
->in2
, ~mask
);
1485 tcg_gen_and_i64(o
->out
, o
->in1
, o
->in2
);
1487 /* Produce the CC from only the bits manipulated. */
1488 tcg_gen_andi_i64(cc_dst
, o
->out
, mask
);
1489 set_cc_nz_u64(s
, cc_dst
);
1493 static ExitStatus
op_bas(DisasContext
*s
, DisasOps
*o
)
1495 tcg_gen_movi_i64(o
->out
, pc_to_link_info(s
, s
->next_pc
));
1496 if (!TCGV_IS_UNUSED_I64(o
->in2
)) {
1497 tcg_gen_mov_i64(psw_addr
, o
->in2
);
1498 per_branch(s
, false);
1499 return EXIT_PC_UPDATED
;
1505 static ExitStatus
op_basi(DisasContext
*s
, DisasOps
*o
)
1507 tcg_gen_movi_i64(o
->out
, pc_to_link_info(s
, s
->next_pc
));
1508 return help_goto_direct(s
, s
->pc
+ 2 * get_field(s
->fields
, i2
));
1511 static ExitStatus
op_bc(DisasContext
*s
, DisasOps
*o
)
1513 int m1
= get_field(s
->fields
, m1
);
1514 bool is_imm
= have_field(s
->fields
, i2
);
1515 int imm
= is_imm
? get_field(s
->fields
, i2
) : 0;
1518 disas_jcc(s
, &c
, m1
);
1519 return help_branch(s
, &c
, is_imm
, imm
, o
->in2
);
1522 static ExitStatus
op_bct32(DisasContext
*s
, DisasOps
*o
)
1524 int r1
= get_field(s
->fields
, r1
);
1525 bool is_imm
= have_field(s
->fields
, i2
);
1526 int imm
= is_imm
? get_field(s
->fields
, i2
) : 0;
1530 c
.cond
= TCG_COND_NE
;
1535 t
= tcg_temp_new_i64();
1536 tcg_gen_subi_i64(t
, regs
[r1
], 1);
1537 store_reg32_i64(r1
, t
);
1538 c
.u
.s32
.a
= tcg_temp_new_i32();
1539 c
.u
.s32
.b
= tcg_const_i32(0);
1540 tcg_gen_extrl_i64_i32(c
.u
.s32
.a
, t
);
1541 tcg_temp_free_i64(t
);
1543 return help_branch(s
, &c
, is_imm
, imm
, o
->in2
);
1546 static ExitStatus
op_bcth(DisasContext
*s
, DisasOps
*o
)
1548 int r1
= get_field(s
->fields
, r1
);
1549 int imm
= get_field(s
->fields
, i2
);
1553 c
.cond
= TCG_COND_NE
;
1558 t
= tcg_temp_new_i64();
1559 tcg_gen_shri_i64(t
, regs
[r1
], 32);
1560 tcg_gen_subi_i64(t
, t
, 1);
1561 store_reg32h_i64(r1
, t
);
1562 c
.u
.s32
.a
= tcg_temp_new_i32();
1563 c
.u
.s32
.b
= tcg_const_i32(0);
1564 tcg_gen_extrl_i64_i32(c
.u
.s32
.a
, t
);
1565 tcg_temp_free_i64(t
);
1567 return help_branch(s
, &c
, 1, imm
, o
->in2
);
1570 static ExitStatus
op_bct64(DisasContext
*s
, DisasOps
*o
)
1572 int r1
= get_field(s
->fields
, r1
);
1573 bool is_imm
= have_field(s
->fields
, i2
);
1574 int imm
= is_imm
? get_field(s
->fields
, i2
) : 0;
1577 c
.cond
= TCG_COND_NE
;
1582 tcg_gen_subi_i64(regs
[r1
], regs
[r1
], 1);
1583 c
.u
.s64
.a
= regs
[r1
];
1584 c
.u
.s64
.b
= tcg_const_i64(0);
1586 return help_branch(s
, &c
, is_imm
, imm
, o
->in2
);
1589 static ExitStatus
op_bx32(DisasContext
*s
, DisasOps
*o
)
1591 int r1
= get_field(s
->fields
, r1
);
1592 int r3
= get_field(s
->fields
, r3
);
1593 bool is_imm
= have_field(s
->fields
, i2
);
1594 int imm
= is_imm
? get_field(s
->fields
, i2
) : 0;
1598 c
.cond
= (s
->insn
->data
? TCG_COND_LE
: TCG_COND_GT
);
1603 t
= tcg_temp_new_i64();
1604 tcg_gen_add_i64(t
, regs
[r1
], regs
[r3
]);
1605 c
.u
.s32
.a
= tcg_temp_new_i32();
1606 c
.u
.s32
.b
= tcg_temp_new_i32();
1607 tcg_gen_extrl_i64_i32(c
.u
.s32
.a
, t
);
1608 tcg_gen_extrl_i64_i32(c
.u
.s32
.b
, regs
[r3
| 1]);
1609 store_reg32_i64(r1
, t
);
1610 tcg_temp_free_i64(t
);
1612 return help_branch(s
, &c
, is_imm
, imm
, o
->in2
);
1615 static ExitStatus
op_bx64(DisasContext
*s
, DisasOps
*o
)
1617 int r1
= get_field(s
->fields
, r1
);
1618 int r3
= get_field(s
->fields
, r3
);
1619 bool is_imm
= have_field(s
->fields
, i2
);
1620 int imm
= is_imm
? get_field(s
->fields
, i2
) : 0;
1623 c
.cond
= (s
->insn
->data
? TCG_COND_LE
: TCG_COND_GT
);
1626 if (r1
== (r3
| 1)) {
1627 c
.u
.s64
.b
= load_reg(r3
| 1);
1630 c
.u
.s64
.b
= regs
[r3
| 1];
1634 tcg_gen_add_i64(regs
[r1
], regs
[r1
], regs
[r3
]);
1635 c
.u
.s64
.a
= regs
[r1
];
1638 return help_branch(s
, &c
, is_imm
, imm
, o
->in2
);
1641 static ExitStatus
op_cj(DisasContext
*s
, DisasOps
*o
)
1643 int imm
, m3
= get_field(s
->fields
, m3
);
1647 c
.cond
= ltgt_cond
[m3
];
1648 if (s
->insn
->data
) {
1649 c
.cond
= tcg_unsigned_cond(c
.cond
);
1651 c
.is_64
= c
.g1
= c
.g2
= true;
1655 is_imm
= have_field(s
->fields
, i4
);
1657 imm
= get_field(s
->fields
, i4
);
1660 o
->out
= get_address(s
, 0, get_field(s
->fields
, b4
),
1661 get_field(s
->fields
, d4
));
1664 return help_branch(s
, &c
, is_imm
, imm
, o
->out
);
1667 static ExitStatus
op_ceb(DisasContext
*s
, DisasOps
*o
)
1669 gen_helper_ceb(cc_op
, cpu_env
, o
->in1
, o
->in2
);
1674 static ExitStatus
op_cdb(DisasContext
*s
, DisasOps
*o
)
1676 gen_helper_cdb(cc_op
, cpu_env
, o
->in1
, o
->in2
);
1681 static ExitStatus
op_cxb(DisasContext
*s
, DisasOps
*o
)
1683 gen_helper_cxb(cc_op
, cpu_env
, o
->out
, o
->out2
, o
->in1
, o
->in2
);
1688 static ExitStatus
op_cfeb(DisasContext
*s
, DisasOps
*o
)
1690 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
1691 gen_helper_cfeb(o
->out
, cpu_env
, o
->in2
, m3
);
1692 tcg_temp_free_i32(m3
);
1693 gen_set_cc_nz_f32(s
, o
->in2
);
1697 static ExitStatus
op_cfdb(DisasContext
*s
, DisasOps
*o
)
1699 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
1700 gen_helper_cfdb(o
->out
, cpu_env
, o
->in2
, m3
);
1701 tcg_temp_free_i32(m3
);
1702 gen_set_cc_nz_f64(s
, o
->in2
);
1706 static ExitStatus
op_cfxb(DisasContext
*s
, DisasOps
*o
)
1708 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
1709 gen_helper_cfxb(o
->out
, cpu_env
, o
->in1
, o
->in2
, m3
);
1710 tcg_temp_free_i32(m3
);
1711 gen_set_cc_nz_f128(s
, o
->in1
, o
->in2
);
1715 static ExitStatus
op_cgeb(DisasContext
*s
, DisasOps
*o
)
1717 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
1718 gen_helper_cgeb(o
->out
, cpu_env
, o
->in2
, m3
);
1719 tcg_temp_free_i32(m3
);
1720 gen_set_cc_nz_f32(s
, o
->in2
);
1724 static ExitStatus
op_cgdb(DisasContext
*s
, DisasOps
*o
)
1726 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
1727 gen_helper_cgdb(o
->out
, cpu_env
, o
->in2
, m3
);
1728 tcg_temp_free_i32(m3
);
1729 gen_set_cc_nz_f64(s
, o
->in2
);
1733 static ExitStatus
op_cgxb(DisasContext
*s
, DisasOps
*o
)
1735 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
1736 gen_helper_cgxb(o
->out
, cpu_env
, o
->in1
, o
->in2
, m3
);
1737 tcg_temp_free_i32(m3
);
1738 gen_set_cc_nz_f128(s
, o
->in1
, o
->in2
);
1742 static ExitStatus
op_clfeb(DisasContext
*s
, DisasOps
*o
)
1744 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
1745 gen_helper_clfeb(o
->out
, cpu_env
, o
->in2
, m3
);
1746 tcg_temp_free_i32(m3
);
1747 gen_set_cc_nz_f32(s
, o
->in2
);
1751 static ExitStatus
op_clfdb(DisasContext
*s
, DisasOps
*o
)
1753 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
1754 gen_helper_clfdb(o
->out
, cpu_env
, o
->in2
, m3
);
1755 tcg_temp_free_i32(m3
);
1756 gen_set_cc_nz_f64(s
, o
->in2
);
1760 static ExitStatus
op_clfxb(DisasContext
*s
, DisasOps
*o
)
1762 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
1763 gen_helper_clfxb(o
->out
, cpu_env
, o
->in1
, o
->in2
, m3
);
1764 tcg_temp_free_i32(m3
);
1765 gen_set_cc_nz_f128(s
, o
->in1
, o
->in2
);
1769 static ExitStatus
op_clgeb(DisasContext
*s
, DisasOps
*o
)
1771 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
1772 gen_helper_clgeb(o
->out
, cpu_env
, o
->in2
, m3
);
1773 tcg_temp_free_i32(m3
);
1774 gen_set_cc_nz_f32(s
, o
->in2
);
1778 static ExitStatus
op_clgdb(DisasContext
*s
, DisasOps
*o
)
1780 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
1781 gen_helper_clgdb(o
->out
, cpu_env
, o
->in2
, m3
);
1782 tcg_temp_free_i32(m3
);
1783 gen_set_cc_nz_f64(s
, o
->in2
);
1787 static ExitStatus
op_clgxb(DisasContext
*s
, DisasOps
*o
)
1789 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
1790 gen_helper_clgxb(o
->out
, cpu_env
, o
->in1
, o
->in2
, m3
);
1791 tcg_temp_free_i32(m3
);
1792 gen_set_cc_nz_f128(s
, o
->in1
, o
->in2
);
1796 static ExitStatus
op_cegb(DisasContext
*s
, DisasOps
*o
)
1798 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
1799 gen_helper_cegb(o
->out
, cpu_env
, o
->in2
, m3
);
1800 tcg_temp_free_i32(m3
);
1804 static ExitStatus
op_cdgb(DisasContext
*s
, DisasOps
*o
)
1806 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
1807 gen_helper_cdgb(o
->out
, cpu_env
, o
->in2
, m3
);
1808 tcg_temp_free_i32(m3
);
1812 static ExitStatus
op_cxgb(DisasContext
*s
, DisasOps
*o
)
1814 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
1815 gen_helper_cxgb(o
->out
, cpu_env
, o
->in2
, m3
);
1816 tcg_temp_free_i32(m3
);
1817 return_low128(o
->out2
);
1821 static ExitStatus
op_celgb(DisasContext
*s
, DisasOps
*o
)
1823 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
1824 gen_helper_celgb(o
->out
, cpu_env
, o
->in2
, m3
);
1825 tcg_temp_free_i32(m3
);
1829 static ExitStatus
op_cdlgb(DisasContext
*s
, DisasOps
*o
)
1831 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
1832 gen_helper_cdlgb(o
->out
, cpu_env
, o
->in2
, m3
);
1833 tcg_temp_free_i32(m3
);
1837 static ExitStatus
op_cxlgb(DisasContext
*s
, DisasOps
*o
)
1839 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
1840 gen_helper_cxlgb(o
->out
, cpu_env
, o
->in2
, m3
);
1841 tcg_temp_free_i32(m3
);
1842 return_low128(o
->out2
);
1846 static ExitStatus
op_cksm(DisasContext
*s
, DisasOps
*o
)
1848 int r2
= get_field(s
->fields
, r2
);
1849 TCGv_i64 len
= tcg_temp_new_i64();
1851 potential_page_fault(s
);
1852 gen_helper_cksm(len
, cpu_env
, o
->in1
, o
->in2
, regs
[r2
+ 1]);
1854 return_low128(o
->out
);
1856 tcg_gen_add_i64(regs
[r2
], regs
[r2
], len
);
1857 tcg_gen_sub_i64(regs
[r2
+ 1], regs
[r2
+ 1], len
);
1858 tcg_temp_free_i64(len
);
1863 static ExitStatus
op_clc(DisasContext
*s
, DisasOps
*o
)
1865 int l
= get_field(s
->fields
, l1
);
1870 tcg_gen_qemu_ld8u(cc_src
, o
->addr1
, get_mem_index(s
));
1871 tcg_gen_qemu_ld8u(cc_dst
, o
->in2
, get_mem_index(s
));
1874 tcg_gen_qemu_ld16u(cc_src
, o
->addr1
, get_mem_index(s
));
1875 tcg_gen_qemu_ld16u(cc_dst
, o
->in2
, get_mem_index(s
));
1878 tcg_gen_qemu_ld32u(cc_src
, o
->addr1
, get_mem_index(s
));
1879 tcg_gen_qemu_ld32u(cc_dst
, o
->in2
, get_mem_index(s
));
1882 tcg_gen_qemu_ld64(cc_src
, o
->addr1
, get_mem_index(s
));
1883 tcg_gen_qemu_ld64(cc_dst
, o
->in2
, get_mem_index(s
));
1886 potential_page_fault(s
);
1887 vl
= tcg_const_i32(l
);
1888 gen_helper_clc(cc_op
, cpu_env
, vl
, o
->addr1
, o
->in2
);
1889 tcg_temp_free_i32(vl
);
1893 gen_op_update2_cc_i64(s
, CC_OP_LTUGTU_64
, cc_src
, cc_dst
);
1897 static ExitStatus
op_clcle(DisasContext
*s
, DisasOps
*o
)
1899 TCGv_i32 r1
= tcg_const_i32(get_field(s
->fields
, r1
));
1900 TCGv_i32 r3
= tcg_const_i32(get_field(s
->fields
, r3
));
1901 potential_page_fault(s
);
1902 gen_helper_clcle(cc_op
, cpu_env
, r1
, o
->in2
, r3
);
1903 tcg_temp_free_i32(r1
);
1904 tcg_temp_free_i32(r3
);
1909 static ExitStatus
op_clm(DisasContext
*s
, DisasOps
*o
)
1911 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
1912 TCGv_i32 t1
= tcg_temp_new_i32();
1913 tcg_gen_extrl_i64_i32(t1
, o
->in1
);
1914 potential_page_fault(s
);
1915 gen_helper_clm(cc_op
, cpu_env
, t1
, m3
, o
->in2
);
1917 tcg_temp_free_i32(t1
);
1918 tcg_temp_free_i32(m3
);
1922 static ExitStatus
op_clst(DisasContext
*s
, DisasOps
*o
)
1924 potential_page_fault(s
);
1925 gen_helper_clst(o
->in1
, cpu_env
, regs
[0], o
->in1
, o
->in2
);
1927 return_low128(o
->in2
);
1931 static ExitStatus
op_cps(DisasContext
*s
, DisasOps
*o
)
1933 TCGv_i64 t
= tcg_temp_new_i64();
1934 tcg_gen_andi_i64(t
, o
->in1
, 0x8000000000000000ull
);
1935 tcg_gen_andi_i64(o
->out
, o
->in2
, 0x7fffffffffffffffull
);
1936 tcg_gen_or_i64(o
->out
, o
->out
, t
);
1937 tcg_temp_free_i64(t
);
1941 static ExitStatus
op_cs(DisasContext
*s
, DisasOps
*o
)
1943 /* FIXME: needs an atomic solution for CONFIG_USER_ONLY. */
1944 int d2
= get_field(s
->fields
, d2
);
1945 int b2
= get_field(s
->fields
, b2
);
1946 int is_64
= s
->insn
->data
;
1947 TCGv_i64 addr
, mem
, cc
, z
;
1949 /* Note that in1 = R3 (new value) and
1950 in2 = (zero-extended) R1 (expected value). */
1952 /* Load the memory into the (temporary) output. While the PoO only talks
1953 about moving the memory to R1 on inequality, if we include equality it
1954 means that R1 is equal to the memory in all conditions. */
1955 addr
= get_address(s
, 0, b2
, d2
);
1957 tcg_gen_qemu_ld64(o
->out
, addr
, get_mem_index(s
));
1959 tcg_gen_qemu_ld32u(o
->out
, addr
, get_mem_index(s
));
1962 /* Are the memory and expected values (un)equal? Note that this setcond
1963 produces the output CC value, thus the NE sense of the test. */
1964 cc
= tcg_temp_new_i64();
1965 tcg_gen_setcond_i64(TCG_COND_NE
, cc
, o
->in2
, o
->out
);
1967 /* If the memory and expected values are equal (CC==0), copy R3 to MEM.
1968 Recall that we are allowed to unconditionally issue the store (and
1969 thus any possible write trap), so (re-)store the original contents
1970 of MEM in case of inequality. */
1971 z
= tcg_const_i64(0);
1972 mem
= tcg_temp_new_i64();
1973 tcg_gen_movcond_i64(TCG_COND_EQ
, mem
, cc
, z
, o
->in1
, o
->out
);
1975 tcg_gen_qemu_st64(mem
, addr
, get_mem_index(s
));
1977 tcg_gen_qemu_st32(mem
, addr
, get_mem_index(s
));
1979 tcg_temp_free_i64(z
);
1980 tcg_temp_free_i64(mem
);
1981 tcg_temp_free_i64(addr
);
1983 /* Store CC back to cc_op. Wait until after the store so that any
1984 exception gets the old cc_op value. */
1985 tcg_gen_extrl_i64_i32(cc_op
, cc
);
1986 tcg_temp_free_i64(cc
);
1991 static ExitStatus
op_cdsg(DisasContext
*s
, DisasOps
*o
)
1993 /* FIXME: needs an atomic solution for CONFIG_USER_ONLY. */
1994 int r1
= get_field(s
->fields
, r1
);
1995 int r3
= get_field(s
->fields
, r3
);
1996 int d2
= get_field(s
->fields
, d2
);
1997 int b2
= get_field(s
->fields
, b2
);
1998 TCGv_i64 addrh
, addrl
, memh
, meml
, outh
, outl
, cc
, z
;
2000 /* Note that R1:R1+1 = expected value and R3:R3+1 = new value. */
2002 addrh
= get_address(s
, 0, b2
, d2
);
2003 addrl
= get_address(s
, 0, b2
, d2
+ 8);
2004 outh
= tcg_temp_new_i64();
2005 outl
= tcg_temp_new_i64();
2007 tcg_gen_qemu_ld64(outh
, addrh
, get_mem_index(s
));
2008 tcg_gen_qemu_ld64(outl
, addrl
, get_mem_index(s
));
2010 /* Fold the double-word compare with arithmetic. */
2011 cc
= tcg_temp_new_i64();
2012 z
= tcg_temp_new_i64();
2013 tcg_gen_xor_i64(cc
, outh
, regs
[r1
]);
2014 tcg_gen_xor_i64(z
, outl
, regs
[r1
+ 1]);
2015 tcg_gen_or_i64(cc
, cc
, z
);
2016 tcg_gen_movi_i64(z
, 0);
2017 tcg_gen_setcond_i64(TCG_COND_NE
, cc
, cc
, z
);
2019 memh
= tcg_temp_new_i64();
2020 meml
= tcg_temp_new_i64();
2021 tcg_gen_movcond_i64(TCG_COND_EQ
, memh
, cc
, z
, regs
[r3
], outh
);
2022 tcg_gen_movcond_i64(TCG_COND_EQ
, meml
, cc
, z
, regs
[r3
+ 1], outl
);
2023 tcg_temp_free_i64(z
);
2025 tcg_gen_qemu_st64(memh
, addrh
, get_mem_index(s
));
2026 tcg_gen_qemu_st64(meml
, addrl
, get_mem_index(s
));
2027 tcg_temp_free_i64(memh
);
2028 tcg_temp_free_i64(meml
);
2029 tcg_temp_free_i64(addrh
);
2030 tcg_temp_free_i64(addrl
);
2032 /* Save back state now that we've passed all exceptions. */
2033 tcg_gen_mov_i64(regs
[r1
], outh
);
2034 tcg_gen_mov_i64(regs
[r1
+ 1], outl
);
2035 tcg_gen_extrl_i64_i32(cc_op
, cc
);
2036 tcg_temp_free_i64(outh
);
2037 tcg_temp_free_i64(outl
);
2038 tcg_temp_free_i64(cc
);
2043 #ifndef CONFIG_USER_ONLY
2044 static ExitStatus
op_csp(DisasContext
*s
, DisasOps
*o
)
2046 TCGv_i32 r1
= tcg_const_i32(get_field(s
->fields
, r1
));
2047 check_privileged(s
);
2048 gen_helper_csp(cc_op
, cpu_env
, r1
, o
->in2
);
2049 tcg_temp_free_i32(r1
);
2055 static ExitStatus
op_cvd(DisasContext
*s
, DisasOps
*o
)
2057 TCGv_i64 t1
= tcg_temp_new_i64();
2058 TCGv_i32 t2
= tcg_temp_new_i32();
2059 tcg_gen_extrl_i64_i32(t2
, o
->in1
);
2060 gen_helper_cvd(t1
, t2
);
2061 tcg_temp_free_i32(t2
);
2062 tcg_gen_qemu_st64(t1
, o
->in2
, get_mem_index(s
));
2063 tcg_temp_free_i64(t1
);
2067 static ExitStatus
op_ct(DisasContext
*s
, DisasOps
*o
)
2069 int m3
= get_field(s
->fields
, m3
);
2070 TCGLabel
*lab
= gen_new_label();
2073 c
= tcg_invert_cond(ltgt_cond
[m3
]);
2074 if (s
->insn
->data
) {
2075 c
= tcg_unsigned_cond(c
);
2077 tcg_gen_brcond_i64(c
, o
->in1
, o
->in2
, lab
);
2086 #ifndef CONFIG_USER_ONLY
2087 static ExitStatus
op_diag(DisasContext
*s
, DisasOps
*o
)
2089 TCGv_i32 r1
= tcg_const_i32(get_field(s
->fields
, r1
));
2090 TCGv_i32 r3
= tcg_const_i32(get_field(s
->fields
, r3
));
2091 TCGv_i32 func_code
= tcg_const_i32(get_field(s
->fields
, i2
));
2093 check_privileged(s
);
2097 gen_helper_diag(cpu_env
, r1
, r3
, func_code
);
2099 tcg_temp_free_i32(func_code
);
2100 tcg_temp_free_i32(r3
);
2101 tcg_temp_free_i32(r1
);
2106 static ExitStatus
op_divs32(DisasContext
*s
, DisasOps
*o
)
2108 gen_helper_divs32(o
->out2
, cpu_env
, o
->in1
, o
->in2
);
2109 return_low128(o
->out
);
2113 static ExitStatus
op_divu32(DisasContext
*s
, DisasOps
*o
)
2115 gen_helper_divu32(o
->out2
, cpu_env
, o
->in1
, o
->in2
);
2116 return_low128(o
->out
);
2120 static ExitStatus
op_divs64(DisasContext
*s
, DisasOps
*o
)
2122 gen_helper_divs64(o
->out2
, cpu_env
, o
->in1
, o
->in2
);
2123 return_low128(o
->out
);
2127 static ExitStatus
op_divu64(DisasContext
*s
, DisasOps
*o
)
2129 gen_helper_divu64(o
->out2
, cpu_env
, o
->out
, o
->out2
, o
->in2
);
2130 return_low128(o
->out
);
2134 static ExitStatus
op_deb(DisasContext
*s
, DisasOps
*o
)
2136 gen_helper_deb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
2140 static ExitStatus
op_ddb(DisasContext
*s
, DisasOps
*o
)
2142 gen_helper_ddb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
2146 static ExitStatus
op_dxb(DisasContext
*s
, DisasOps
*o
)
2148 gen_helper_dxb(o
->out
, cpu_env
, o
->out
, o
->out2
, o
->in1
, o
->in2
);
2149 return_low128(o
->out2
);
2153 static ExitStatus
op_ear(DisasContext
*s
, DisasOps
*o
)
2155 int r2
= get_field(s
->fields
, r2
);
2156 tcg_gen_ld32u_i64(o
->out
, cpu_env
, offsetof(CPUS390XState
, aregs
[r2
]));
2160 static ExitStatus
op_ecag(DisasContext
*s
, DisasOps
*o
)
2162 /* No cache information provided. */
2163 tcg_gen_movi_i64(o
->out
, -1);
2167 static ExitStatus
op_efpc(DisasContext
*s
, DisasOps
*o
)
2169 tcg_gen_ld32u_i64(o
->out
, cpu_env
, offsetof(CPUS390XState
, fpc
));
2173 static ExitStatus
op_epsw(DisasContext
*s
, DisasOps
*o
)
2175 int r1
= get_field(s
->fields
, r1
);
2176 int r2
= get_field(s
->fields
, r2
);
2177 TCGv_i64 t
= tcg_temp_new_i64();
2179 /* Note the "subsequently" in the PoO, which implies a defined result
2180 if r1 == r2. Thus we cannot defer these writes to an output hook. */
2181 tcg_gen_shri_i64(t
, psw_mask
, 32);
2182 store_reg32_i64(r1
, t
);
2184 store_reg32_i64(r2
, psw_mask
);
2187 tcg_temp_free_i64(t
);
2191 static ExitStatus
op_ex(DisasContext
*s
, DisasOps
*o
)
2193 /* ??? Perhaps a better way to implement EXECUTE is to set a bit in
2194 tb->flags, (ab)use the tb->cs_base field as the address of
2195 the template in memory, and grab 8 bits of tb->flags/cflags for
2196 the contents of the register. We would then recognize all this
2197 in gen_intermediate_code_internal, generating code for exactly
2198 one instruction. This new TB then gets executed normally.
2200 On the other hand, this seems to be mostly used for modifying
2201 MVC inside of memcpy, which needs a helper call anyway. So
2202 perhaps this doesn't bear thinking about any further. */
2209 tmp
= tcg_const_i64(s
->next_pc
);
2210 gen_helper_ex(cc_op
, cpu_env
, cc_op
, o
->in1
, o
->in2
, tmp
);
2211 tcg_temp_free_i64(tmp
);
2216 static ExitStatus
op_fieb(DisasContext
*s
, DisasOps
*o
)
2218 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
2219 gen_helper_fieb(o
->out
, cpu_env
, o
->in2
, m3
);
2220 tcg_temp_free_i32(m3
);
2224 static ExitStatus
op_fidb(DisasContext
*s
, DisasOps
*o
)
2226 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
2227 gen_helper_fidb(o
->out
, cpu_env
, o
->in2
, m3
);
2228 tcg_temp_free_i32(m3
);
2232 static ExitStatus
op_fixb(DisasContext
*s
, DisasOps
*o
)
2234 TCGv_i32 m3
= tcg_const_i32(get_field(s
->fields
, m3
));
2235 gen_helper_fixb(o
->out
, cpu_env
, o
->in1
, o
->in2
, m3
);
2236 return_low128(o
->out2
);
2237 tcg_temp_free_i32(m3
);
2241 static ExitStatus
op_flogr(DisasContext
*s
, DisasOps
*o
)
2243 /* We'll use the original input for cc computation, since we get to
2244 compare that against 0, which ought to be better than comparing
2245 the real output against 64. It also lets cc_dst be a convenient
2246 temporary during our computation. */
2247 gen_op_update1_cc_i64(s
, CC_OP_FLOGR
, o
->in2
);
2249 /* R1 = IN ? CLZ(IN) : 64. */
2250 gen_helper_clz(o
->out
, o
->in2
);
2252 /* R1+1 = IN & ~(found bit). Note that we may attempt to shift this
2253 value by 64, which is undefined. But since the shift is 64 iff the
2254 input is zero, we still get the correct result after and'ing. */
2255 tcg_gen_movi_i64(o
->out2
, 0x8000000000000000ull
);
2256 tcg_gen_shr_i64(o
->out2
, o
->out2
, o
->out
);
2257 tcg_gen_andc_i64(o
->out2
, cc_dst
, o
->out2
);
2261 static ExitStatus
op_icm(DisasContext
*s
, DisasOps
*o
)
2263 int m3
= get_field(s
->fields
, m3
);
2264 int pos
, len
, base
= s
->insn
->data
;
2265 TCGv_i64 tmp
= tcg_temp_new_i64();
2270 /* Effectively a 32-bit load. */
2271 tcg_gen_qemu_ld32u(tmp
, o
->in2
, get_mem_index(s
));
2278 /* Effectively a 16-bit load. */
2279 tcg_gen_qemu_ld16u(tmp
, o
->in2
, get_mem_index(s
));
2287 /* Effectively an 8-bit load. */
2288 tcg_gen_qemu_ld8u(tmp
, o
->in2
, get_mem_index(s
));
2293 pos
= base
+ ctz32(m3
) * 8;
2294 tcg_gen_deposit_i64(o
->out
, o
->out
, tmp
, pos
, len
);
2295 ccm
= ((1ull << len
) - 1) << pos
;
2299 /* This is going to be a sequence of loads and inserts. */
2300 pos
= base
+ 32 - 8;
2304 tcg_gen_qemu_ld8u(tmp
, o
->in2
, get_mem_index(s
));
2305 tcg_gen_addi_i64(o
->in2
, o
->in2
, 1);
2306 tcg_gen_deposit_i64(o
->out
, o
->out
, tmp
, pos
, 8);
2309 m3
= (m3
<< 1) & 0xf;
2315 tcg_gen_movi_i64(tmp
, ccm
);
2316 gen_op_update2_cc_i64(s
, CC_OP_ICM
, tmp
, o
->out
);
2317 tcg_temp_free_i64(tmp
);
2321 static ExitStatus
op_insi(DisasContext
*s
, DisasOps
*o
)
2323 int shift
= s
->insn
->data
& 0xff;
2324 int size
= s
->insn
->data
>> 8;
2325 tcg_gen_deposit_i64(o
->out
, o
->in1
, o
->in2
, shift
, size
);
2329 static ExitStatus
op_ipm(DisasContext
*s
, DisasOps
*o
)
2334 tcg_gen_andi_i64(o
->out
, o
->out
, ~0xff000000ull
);
2336 t1
= tcg_temp_new_i64();
2337 tcg_gen_shli_i64(t1
, psw_mask
, 20);
2338 tcg_gen_shri_i64(t1
, t1
, 36);
2339 tcg_gen_or_i64(o
->out
, o
->out
, t1
);
2341 tcg_gen_extu_i32_i64(t1
, cc_op
);
2342 tcg_gen_shli_i64(t1
, t1
, 28);
2343 tcg_gen_or_i64(o
->out
, o
->out
, t1
);
2344 tcg_temp_free_i64(t1
);
2348 #ifndef CONFIG_USER_ONLY
2349 static ExitStatus
op_ipte(DisasContext
*s
, DisasOps
*o
)
2351 check_privileged(s
);
2352 gen_helper_ipte(cpu_env
, o
->in1
, o
->in2
);
2356 static ExitStatus
op_iske(DisasContext
*s
, DisasOps
*o
)
2358 check_privileged(s
);
2359 gen_helper_iske(o
->out
, cpu_env
, o
->in2
);
2364 static ExitStatus
op_ldeb(DisasContext
*s
, DisasOps
*o
)
2366 gen_helper_ldeb(o
->out
, cpu_env
, o
->in2
);
2370 static ExitStatus
op_ledb(DisasContext
*s
, DisasOps
*o
)
2372 gen_helper_ledb(o
->out
, cpu_env
, o
->in2
);
2376 static ExitStatus
op_ldxb(DisasContext
*s
, DisasOps
*o
)
2378 gen_helper_ldxb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
2382 static ExitStatus
op_lexb(DisasContext
*s
, DisasOps
*o
)
2384 gen_helper_lexb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
2388 static ExitStatus
op_lxdb(DisasContext
*s
, DisasOps
*o
)
2390 gen_helper_lxdb(o
->out
, cpu_env
, o
->in2
);
2391 return_low128(o
->out2
);
2395 static ExitStatus
op_lxeb(DisasContext
*s
, DisasOps
*o
)
2397 gen_helper_lxeb(o
->out
, cpu_env
, o
->in2
);
2398 return_low128(o
->out2
);
2402 static ExitStatus
op_llgt(DisasContext
*s
, DisasOps
*o
)
2404 tcg_gen_andi_i64(o
->out
, o
->in2
, 0x7fffffff);
2408 static ExitStatus
op_ld8s(DisasContext
*s
, DisasOps
*o
)
2410 tcg_gen_qemu_ld8s(o
->out
, o
->in2
, get_mem_index(s
));
2414 static ExitStatus
op_ld8u(DisasContext
*s
, DisasOps
*o
)
2416 tcg_gen_qemu_ld8u(o
->out
, o
->in2
, get_mem_index(s
));
2420 static ExitStatus
op_ld16s(DisasContext
*s
, DisasOps
*o
)
2422 tcg_gen_qemu_ld16s(o
->out
, o
->in2
, get_mem_index(s
));
2426 static ExitStatus
op_ld16u(DisasContext
*s
, DisasOps
*o
)
2428 tcg_gen_qemu_ld16u(o
->out
, o
->in2
, get_mem_index(s
));
2432 static ExitStatus
op_ld32s(DisasContext
*s
, DisasOps
*o
)
2434 tcg_gen_qemu_ld32s(o
->out
, o
->in2
, get_mem_index(s
));
2438 static ExitStatus
op_ld32u(DisasContext
*s
, DisasOps
*o
)
2440 tcg_gen_qemu_ld32u(o
->out
, o
->in2
, get_mem_index(s
));
2444 static ExitStatus
op_ld64(DisasContext
*s
, DisasOps
*o
)
2446 tcg_gen_qemu_ld64(o
->out
, o
->in2
, get_mem_index(s
));
2450 static ExitStatus
op_lat(DisasContext
*s
, DisasOps
*o
)
2452 TCGLabel
*lab
= gen_new_label();
2453 store_reg32_i64(get_field(s
->fields
, r1
), o
->in2
);
2454 /* The value is stored even in case of trap. */
2455 tcg_gen_brcondi_i64(TCG_COND_NE
, o
->in2
, 0, lab
);
2461 static ExitStatus
op_lgat(DisasContext
*s
, DisasOps
*o
)
2463 TCGLabel
*lab
= gen_new_label();
2464 tcg_gen_qemu_ld64(o
->out
, o
->in2
, get_mem_index(s
));
2465 /* The value is stored even in case of trap. */
2466 tcg_gen_brcondi_i64(TCG_COND_NE
, o
->out
, 0, lab
);
2472 static ExitStatus
op_lfhat(DisasContext
*s
, DisasOps
*o
)
2474 TCGLabel
*lab
= gen_new_label();
2475 store_reg32h_i64(get_field(s
->fields
, r1
), o
->in2
);
2476 /* The value is stored even in case of trap. */
2477 tcg_gen_brcondi_i64(TCG_COND_NE
, o
->in2
, 0, lab
);
2483 static ExitStatus
op_llgfat(DisasContext
*s
, DisasOps
*o
)
2485 TCGLabel
*lab
= gen_new_label();
2486 tcg_gen_qemu_ld32u(o
->out
, o
->in2
, get_mem_index(s
));
2487 /* The value is stored even in case of trap. */
2488 tcg_gen_brcondi_i64(TCG_COND_NE
, o
->out
, 0, lab
);
2494 static ExitStatus
op_llgtat(DisasContext
*s
, DisasOps
*o
)
2496 TCGLabel
*lab
= gen_new_label();
2497 tcg_gen_andi_i64(o
->out
, o
->in2
, 0x7fffffff);
2498 /* The value is stored even in case of trap. */
2499 tcg_gen_brcondi_i64(TCG_COND_NE
, o
->out
, 0, lab
);
2505 static ExitStatus
op_loc(DisasContext
*s
, DisasOps
*o
)
2509 disas_jcc(s
, &c
, get_field(s
->fields
, m3
));
2512 tcg_gen_movcond_i64(c
.cond
, o
->out
, c
.u
.s64
.a
, c
.u
.s64
.b
,
2516 TCGv_i32 t32
= tcg_temp_new_i32();
2519 tcg_gen_setcond_i32(c
.cond
, t32
, c
.u
.s32
.a
, c
.u
.s32
.b
);
2522 t
= tcg_temp_new_i64();
2523 tcg_gen_extu_i32_i64(t
, t32
);
2524 tcg_temp_free_i32(t32
);
2526 z
= tcg_const_i64(0);
2527 tcg_gen_movcond_i64(TCG_COND_NE
, o
->out
, t
, z
, o
->in2
, o
->in1
);
2528 tcg_temp_free_i64(t
);
2529 tcg_temp_free_i64(z
);
2535 #ifndef CONFIG_USER_ONLY
2536 static ExitStatus
op_lctl(DisasContext
*s
, DisasOps
*o
)
2538 TCGv_i32 r1
= tcg_const_i32(get_field(s
->fields
, r1
));
2539 TCGv_i32 r3
= tcg_const_i32(get_field(s
->fields
, r3
));
2540 check_privileged(s
);
2541 potential_page_fault(s
);
2542 gen_helper_lctl(cpu_env
, r1
, o
->in2
, r3
);
2543 tcg_temp_free_i32(r1
);
2544 tcg_temp_free_i32(r3
);
2548 static ExitStatus
op_lctlg(DisasContext
*s
, DisasOps
*o
)
2550 TCGv_i32 r1
= tcg_const_i32(get_field(s
->fields
, r1
));
2551 TCGv_i32 r3
= tcg_const_i32(get_field(s
->fields
, r3
));
2552 check_privileged(s
);
2553 potential_page_fault(s
);
2554 gen_helper_lctlg(cpu_env
, r1
, o
->in2
, r3
);
2555 tcg_temp_free_i32(r1
);
2556 tcg_temp_free_i32(r3
);
2559 static ExitStatus
op_lra(DisasContext
*s
, DisasOps
*o
)
2561 check_privileged(s
);
2562 potential_page_fault(s
);
2563 gen_helper_lra(o
->out
, cpu_env
, o
->in2
);
2568 static ExitStatus
op_lpsw(DisasContext
*s
, DisasOps
*o
)
2572 check_privileged(s
);
2573 per_breaking_event(s
);
2575 t1
= tcg_temp_new_i64();
2576 t2
= tcg_temp_new_i64();
2577 tcg_gen_qemu_ld32u(t1
, o
->in2
, get_mem_index(s
));
2578 tcg_gen_addi_i64(o
->in2
, o
->in2
, 4);
2579 tcg_gen_qemu_ld32u(t2
, o
->in2
, get_mem_index(s
));
2580 /* Convert the 32-bit PSW_MASK into the 64-bit PSW_MASK. */
2581 tcg_gen_shli_i64(t1
, t1
, 32);
2582 gen_helper_load_psw(cpu_env
, t1
, t2
);
2583 tcg_temp_free_i64(t1
);
2584 tcg_temp_free_i64(t2
);
2585 return EXIT_NORETURN
;
2588 static ExitStatus
op_lpswe(DisasContext
*s
, DisasOps
*o
)
2592 check_privileged(s
);
2593 per_breaking_event(s
);
2595 t1
= tcg_temp_new_i64();
2596 t2
= tcg_temp_new_i64();
2597 tcg_gen_qemu_ld64(t1
, o
->in2
, get_mem_index(s
));
2598 tcg_gen_addi_i64(o
->in2
, o
->in2
, 8);
2599 tcg_gen_qemu_ld64(t2
, o
->in2
, get_mem_index(s
));
2600 gen_helper_load_psw(cpu_env
, t1
, t2
);
2601 tcg_temp_free_i64(t1
);
2602 tcg_temp_free_i64(t2
);
2603 return EXIT_NORETURN
;
2607 static ExitStatus
op_lam(DisasContext
*s
, DisasOps
*o
)
2609 TCGv_i32 r1
= tcg_const_i32(get_field(s
->fields
, r1
));
2610 TCGv_i32 r3
= tcg_const_i32(get_field(s
->fields
, r3
));
2611 potential_page_fault(s
);
2612 gen_helper_lam(cpu_env
, r1
, o
->in2
, r3
);
2613 tcg_temp_free_i32(r1
);
2614 tcg_temp_free_i32(r3
);
2618 static ExitStatus
op_lm32(DisasContext
*s
, DisasOps
*o
)
2620 int r1
= get_field(s
->fields
, r1
);
2621 int r3
= get_field(s
->fields
, r3
);
2624 /* Only one register to read. */
2625 t1
= tcg_temp_new_i64();
2626 if (unlikely(r1
== r3
)) {
2627 tcg_gen_qemu_ld32u(t1
, o
->in2
, get_mem_index(s
));
2628 store_reg32_i64(r1
, t1
);
2633 /* First load the values of the first and last registers to trigger
2634 possible page faults. */
2635 t2
= tcg_temp_new_i64();
2636 tcg_gen_qemu_ld32u(t1
, o
->in2
, get_mem_index(s
));
2637 tcg_gen_addi_i64(t2
, o
->in2
, 4 * ((r3
- r1
) & 15));
2638 tcg_gen_qemu_ld32u(t2
, t2
, get_mem_index(s
));
2639 store_reg32_i64(r1
, t1
);
2640 store_reg32_i64(r3
, t2
);
2642 /* Only two registers to read. */
2643 if (((r1
+ 1) & 15) == r3
) {
2649 /* Then load the remaining registers. Page fault can't occur. */
2651 tcg_gen_movi_i64(t2
, 4);
2654 tcg_gen_add_i64(o
->in2
, o
->in2
, t2
);
2655 tcg_gen_qemu_ld32u(t1
, o
->in2
, get_mem_index(s
));
2656 store_reg32_i64(r1
, t1
);
2664 static ExitStatus
op_lmh(DisasContext
*s
, DisasOps
*o
)
2666 int r1
= get_field(s
->fields
, r1
);
2667 int r3
= get_field(s
->fields
, r3
);
2670 /* Only one register to read. */
2671 t1
= tcg_temp_new_i64();
2672 if (unlikely(r1
== r3
)) {
2673 tcg_gen_qemu_ld32u(t1
, o
->in2
, get_mem_index(s
));
2674 store_reg32h_i64(r1
, t1
);
2679 /* First load the values of the first and last registers to trigger
2680 possible page faults. */
2681 t2
= tcg_temp_new_i64();
2682 tcg_gen_qemu_ld32u(t1
, o
->in2
, get_mem_index(s
));
2683 tcg_gen_addi_i64(t2
, o
->in2
, 4 * ((r3
- r1
) & 15));
2684 tcg_gen_qemu_ld32u(t2
, t2
, get_mem_index(s
));
2685 store_reg32h_i64(r1
, t1
);
2686 store_reg32h_i64(r3
, t2
);
2688 /* Only two registers to read. */
2689 if (((r1
+ 1) & 15) == r3
) {
2695 /* Then load the remaining registers. Page fault can't occur. */
2697 tcg_gen_movi_i64(t2
, 4);
2700 tcg_gen_add_i64(o
->in2
, o
->in2
, t2
);
2701 tcg_gen_qemu_ld32u(t1
, o
->in2
, get_mem_index(s
));
2702 store_reg32h_i64(r1
, t1
);
2710 static ExitStatus
op_lm64(DisasContext
*s
, DisasOps
*o
)
2712 int r1
= get_field(s
->fields
, r1
);
2713 int r3
= get_field(s
->fields
, r3
);
2716 /* Only one register to read. */
2717 if (unlikely(r1
== r3
)) {
2718 tcg_gen_qemu_ld64(regs
[r1
], o
->in2
, get_mem_index(s
));
2722 /* First load the values of the first and last registers to trigger
2723 possible page faults. */
2724 t1
= tcg_temp_new_i64();
2725 t2
= tcg_temp_new_i64();
2726 tcg_gen_qemu_ld64(t1
, o
->in2
, get_mem_index(s
));
2727 tcg_gen_addi_i64(t2
, o
->in2
, 8 * ((r3
- r1
) & 15));
2728 tcg_gen_qemu_ld64(regs
[r3
], t2
, get_mem_index(s
));
2729 tcg_gen_mov_i64(regs
[r1
], t1
);
2732 /* Only two registers to read. */
2733 if (((r1
+ 1) & 15) == r3
) {
2738 /* Then load the remaining registers. Page fault can't occur. */
2740 tcg_gen_movi_i64(t1
, 8);
2743 tcg_gen_add_i64(o
->in2
, o
->in2
, t1
);
2744 tcg_gen_qemu_ld64(regs
[r1
], o
->in2
, get_mem_index(s
));
2751 #ifndef CONFIG_USER_ONLY
2752 static ExitStatus
op_lura(DisasContext
*s
, DisasOps
*o
)
2754 check_privileged(s
);
2755 potential_page_fault(s
);
2756 gen_helper_lura(o
->out
, cpu_env
, o
->in2
);
2760 static ExitStatus
op_lurag(DisasContext
*s
, DisasOps
*o
)
2762 check_privileged(s
);
2763 potential_page_fault(s
);
2764 gen_helper_lurag(o
->out
, cpu_env
, o
->in2
);
2769 static ExitStatus
op_mov2(DisasContext
*s
, DisasOps
*o
)
2772 o
->g_out
= o
->g_in2
;
2773 TCGV_UNUSED_I64(o
->in2
);
2778 static ExitStatus
op_mov2e(DisasContext
*s
, DisasOps
*o
)
2780 int b2
= get_field(s
->fields
, b2
);
2781 TCGv ar1
= tcg_temp_new_i64();
2784 o
->g_out
= o
->g_in2
;
2785 TCGV_UNUSED_I64(o
->in2
);
2788 switch (s
->tb
->flags
& FLAG_MASK_ASC
) {
2789 case PSW_ASC_PRIMARY
>> 32:
2790 tcg_gen_movi_i64(ar1
, 0);
2792 case PSW_ASC_ACCREG
>> 32:
2793 tcg_gen_movi_i64(ar1
, 1);
2795 case PSW_ASC_SECONDARY
>> 32:
2797 tcg_gen_ld32u_i64(ar1
, cpu_env
, offsetof(CPUS390XState
, aregs
[b2
]));
2799 tcg_gen_movi_i64(ar1
, 0);
2802 case PSW_ASC_HOME
>> 32:
2803 tcg_gen_movi_i64(ar1
, 2);
2807 tcg_gen_st32_i64(ar1
, cpu_env
, offsetof(CPUS390XState
, aregs
[1]));
2808 tcg_temp_free_i64(ar1
);
2813 static ExitStatus
op_movx(DisasContext
*s
, DisasOps
*o
)
2817 o
->g_out
= o
->g_in1
;
2818 o
->g_out2
= o
->g_in2
;
2819 TCGV_UNUSED_I64(o
->in1
);
2820 TCGV_UNUSED_I64(o
->in2
);
2821 o
->g_in1
= o
->g_in2
= false;
2825 static ExitStatus
op_mvc(DisasContext
*s
, DisasOps
*o
)
2827 TCGv_i32 l
= tcg_const_i32(get_field(s
->fields
, l1
));
2828 potential_page_fault(s
);
2829 gen_helper_mvc(cpu_env
, l
, o
->addr1
, o
->in2
);
2830 tcg_temp_free_i32(l
);
2834 static ExitStatus
op_mvcl(DisasContext
*s
, DisasOps
*o
)
2836 TCGv_i32 r1
= tcg_const_i32(get_field(s
->fields
, r1
));
2837 TCGv_i32 r2
= tcg_const_i32(get_field(s
->fields
, r2
));
2838 potential_page_fault(s
);
2839 gen_helper_mvcl(cc_op
, cpu_env
, r1
, r2
);
2840 tcg_temp_free_i32(r1
);
2841 tcg_temp_free_i32(r2
);
2846 static ExitStatus
op_mvcle(DisasContext
*s
, DisasOps
*o
)
2848 TCGv_i32 r1
= tcg_const_i32(get_field(s
->fields
, r1
));
2849 TCGv_i32 r3
= tcg_const_i32(get_field(s
->fields
, r3
));
2850 potential_page_fault(s
);
2851 gen_helper_mvcle(cc_op
, cpu_env
, r1
, o
->in2
, r3
);
2852 tcg_temp_free_i32(r1
);
2853 tcg_temp_free_i32(r3
);
2858 #ifndef CONFIG_USER_ONLY
2859 static ExitStatus
op_mvcp(DisasContext
*s
, DisasOps
*o
)
2861 int r1
= get_field(s
->fields
, l1
);
2862 check_privileged(s
);
2863 potential_page_fault(s
);
2864 gen_helper_mvcp(cc_op
, cpu_env
, regs
[r1
], o
->addr1
, o
->in2
);
2869 static ExitStatus
op_mvcs(DisasContext
*s
, DisasOps
*o
)
2871 int r1
= get_field(s
->fields
, l1
);
2872 check_privileged(s
);
2873 potential_page_fault(s
);
2874 gen_helper_mvcs(cc_op
, cpu_env
, regs
[r1
], o
->addr1
, o
->in2
);
2880 static ExitStatus
op_mvpg(DisasContext
*s
, DisasOps
*o
)
2882 potential_page_fault(s
);
2883 gen_helper_mvpg(cpu_env
, regs
[0], o
->in1
, o
->in2
);
2888 static ExitStatus
op_mvst(DisasContext
*s
, DisasOps
*o
)
2890 potential_page_fault(s
);
2891 gen_helper_mvst(o
->in1
, cpu_env
, regs
[0], o
->in1
, o
->in2
);
2893 return_low128(o
->in2
);
2897 static ExitStatus
op_mul(DisasContext
*s
, DisasOps
*o
)
2899 tcg_gen_mul_i64(o
->out
, o
->in1
, o
->in2
);
2903 static ExitStatus
op_mul128(DisasContext
*s
, DisasOps
*o
)
2905 tcg_gen_mulu2_i64(o
->out2
, o
->out
, o
->in1
, o
->in2
);
2909 static ExitStatus
op_meeb(DisasContext
*s
, DisasOps
*o
)
2911 gen_helper_meeb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
2915 static ExitStatus
op_mdeb(DisasContext
*s
, DisasOps
*o
)
2917 gen_helper_mdeb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
2921 static ExitStatus
op_mdb(DisasContext
*s
, DisasOps
*o
)
2923 gen_helper_mdb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
2927 static ExitStatus
op_mxb(DisasContext
*s
, DisasOps
*o
)
2929 gen_helper_mxb(o
->out
, cpu_env
, o
->out
, o
->out2
, o
->in1
, o
->in2
);
2930 return_low128(o
->out2
);
2934 static ExitStatus
op_mxdb(DisasContext
*s
, DisasOps
*o
)
2936 gen_helper_mxdb(o
->out
, cpu_env
, o
->out
, o
->out2
, o
->in2
);
2937 return_low128(o
->out2
);
2941 static ExitStatus
op_maeb(DisasContext
*s
, DisasOps
*o
)
2943 TCGv_i64 r3
= load_freg32_i64(get_field(s
->fields
, r3
));
2944 gen_helper_maeb(o
->out
, cpu_env
, o
->in1
, o
->in2
, r3
);
2945 tcg_temp_free_i64(r3
);
2949 static ExitStatus
op_madb(DisasContext
*s
, DisasOps
*o
)
2951 int r3
= get_field(s
->fields
, r3
);
2952 gen_helper_madb(o
->out
, cpu_env
, o
->in1
, o
->in2
, fregs
[r3
]);
2956 static ExitStatus
op_mseb(DisasContext
*s
, DisasOps
*o
)
2958 TCGv_i64 r3
= load_freg32_i64(get_field(s
->fields
, r3
));
2959 gen_helper_mseb(o
->out
, cpu_env
, o
->in1
, o
->in2
, r3
);
2960 tcg_temp_free_i64(r3
);
2964 static ExitStatus
op_msdb(DisasContext
*s
, DisasOps
*o
)
2966 int r3
= get_field(s
->fields
, r3
);
2967 gen_helper_msdb(o
->out
, cpu_env
, o
->in1
, o
->in2
, fregs
[r3
]);
2971 static ExitStatus
op_nabs(DisasContext
*s
, DisasOps
*o
)
2974 z
= tcg_const_i64(0);
2975 n
= tcg_temp_new_i64();
2976 tcg_gen_neg_i64(n
, o
->in2
);
2977 tcg_gen_movcond_i64(TCG_COND_GE
, o
->out
, o
->in2
, z
, n
, o
->in2
);
2978 tcg_temp_free_i64(n
);
2979 tcg_temp_free_i64(z
);
2983 static ExitStatus
op_nabsf32(DisasContext
*s
, DisasOps
*o
)
2985 tcg_gen_ori_i64(o
->out
, o
->in2
, 0x80000000ull
);
2989 static ExitStatus
op_nabsf64(DisasContext
*s
, DisasOps
*o
)
2991 tcg_gen_ori_i64(o
->out
, o
->in2
, 0x8000000000000000ull
);
2995 static ExitStatus
op_nabsf128(DisasContext
*s
, DisasOps
*o
)
2997 tcg_gen_ori_i64(o
->out
, o
->in1
, 0x8000000000000000ull
);
2998 tcg_gen_mov_i64(o
->out2
, o
->in2
);
3002 static ExitStatus
op_nc(DisasContext
*s
, DisasOps
*o
)
3004 TCGv_i32 l
= tcg_const_i32(get_field(s
->fields
, l1
));
3005 potential_page_fault(s
);
3006 gen_helper_nc(cc_op
, cpu_env
, l
, o
->addr1
, o
->in2
);
3007 tcg_temp_free_i32(l
);
3012 static ExitStatus
op_neg(DisasContext
*s
, DisasOps
*o
)
3014 tcg_gen_neg_i64(o
->out
, o
->in2
);
3018 static ExitStatus
op_negf32(DisasContext
*s
, DisasOps
*o
)
3020 tcg_gen_xori_i64(o
->out
, o
->in2
, 0x80000000ull
);
3024 static ExitStatus
op_negf64(DisasContext
*s
, DisasOps
*o
)
3026 tcg_gen_xori_i64(o
->out
, o
->in2
, 0x8000000000000000ull
);
3030 static ExitStatus
op_negf128(DisasContext
*s
, DisasOps
*o
)
3032 tcg_gen_xori_i64(o
->out
, o
->in1
, 0x8000000000000000ull
);
3033 tcg_gen_mov_i64(o
->out2
, o
->in2
);
3037 static ExitStatus
op_oc(DisasContext
*s
, DisasOps
*o
)
3039 TCGv_i32 l
= tcg_const_i32(get_field(s
->fields
, l1
));
3040 potential_page_fault(s
);
3041 gen_helper_oc(cc_op
, cpu_env
, l
, o
->addr1
, o
->in2
);
3042 tcg_temp_free_i32(l
);
3047 static ExitStatus
op_or(DisasContext
*s
, DisasOps
*o
)
3049 tcg_gen_or_i64(o
->out
, o
->in1
, o
->in2
);
3053 static ExitStatus
op_ori(DisasContext
*s
, DisasOps
*o
)
3055 int shift
= s
->insn
->data
& 0xff;
3056 int size
= s
->insn
->data
>> 8;
3057 uint64_t mask
= ((1ull << size
) - 1) << shift
;
3060 tcg_gen_shli_i64(o
->in2
, o
->in2
, shift
);
3061 tcg_gen_or_i64(o
->out
, o
->in1
, o
->in2
);
3063 /* Produce the CC from only the bits manipulated. */
3064 tcg_gen_andi_i64(cc_dst
, o
->out
, mask
);
3065 set_cc_nz_u64(s
, cc_dst
);
3069 static ExitStatus
op_popcnt(DisasContext
*s
, DisasOps
*o
)
3071 gen_helper_popcnt(o
->out
, o
->in2
);
3075 #ifndef CONFIG_USER_ONLY
3076 static ExitStatus
op_ptlb(DisasContext
*s
, DisasOps
*o
)
3078 check_privileged(s
);
3079 gen_helper_ptlb(cpu_env
);
3084 static ExitStatus
op_risbg(DisasContext
*s
, DisasOps
*o
)
3086 int i3
= get_field(s
->fields
, i3
);
3087 int i4
= get_field(s
->fields
, i4
);
3088 int i5
= get_field(s
->fields
, i5
);
3089 int do_zero
= i4
& 0x80;
3090 uint64_t mask
, imask
, pmask
;
3093 /* Adjust the arguments for the specific insn. */
3094 switch (s
->fields
->op2
) {
3095 case 0x55: /* risbg */
3100 case 0x5d: /* risbhg */
3103 pmask
= 0xffffffff00000000ull
;
3105 case 0x51: /* risblg */
3108 pmask
= 0x00000000ffffffffull
;
3114 /* MASK is the set of bits to be inserted from R2.
3115 Take care for I3/I4 wraparound. */
3118 mask
^= pmask
>> i4
>> 1;
3120 mask
|= ~(pmask
>> i4
>> 1);
3124 /* IMASK is the set of bits to be kept from R1. In the case of the high/low
3125 insns, we need to keep the other half of the register. */
3126 imask
= ~mask
| ~pmask
;
3128 if (s
->fields
->op2
== 0x55) {
3135 /* In some cases we can implement this with deposit, which can be more
3136 efficient on some hosts. */
3137 if (~mask
== imask
&& i3
<= i4
) {
3138 if (s
->fields
->op2
== 0x5d) {
3141 /* Note that we rotate the bits to be inserted to the lsb, not to
3142 the position as described in the PoO. */
3145 rot
= (i5
- pos
) & 63;
3151 /* Rotate the input as necessary. */
3152 tcg_gen_rotli_i64(o
->in2
, o
->in2
, rot
);
3154 /* Insert the selected bits into the output. */
3156 tcg_gen_deposit_i64(o
->out
, o
->out
, o
->in2
, pos
, len
);
3157 } else if (imask
== 0) {
3158 tcg_gen_andi_i64(o
->out
, o
->in2
, mask
);
3160 tcg_gen_andi_i64(o
->in2
, o
->in2
, mask
);
3161 tcg_gen_andi_i64(o
->out
, o
->out
, imask
);
3162 tcg_gen_or_i64(o
->out
, o
->out
, o
->in2
);
3167 static ExitStatus
op_rosbg(DisasContext
*s
, DisasOps
*o
)
3169 int i3
= get_field(s
->fields
, i3
);
3170 int i4
= get_field(s
->fields
, i4
);
3171 int i5
= get_field(s
->fields
, i5
);
3174 /* If this is a test-only form, arrange to discard the result. */
3176 o
->out
= tcg_temp_new_i64();
3184 /* MASK is the set of bits to be operated on from R2.
3185 Take care for I3/I4 wraparound. */
3188 mask
^= ~0ull >> i4
>> 1;
3190 mask
|= ~(~0ull >> i4
>> 1);
3193 /* Rotate the input as necessary. */
3194 tcg_gen_rotli_i64(o
->in2
, o
->in2
, i5
);
3197 switch (s
->fields
->op2
) {
3198 case 0x55: /* AND */
3199 tcg_gen_ori_i64(o
->in2
, o
->in2
, ~mask
);
3200 tcg_gen_and_i64(o
->out
, o
->out
, o
->in2
);
3203 tcg_gen_andi_i64(o
->in2
, o
->in2
, mask
);
3204 tcg_gen_or_i64(o
->out
, o
->out
, o
->in2
);
3206 case 0x57: /* XOR */
3207 tcg_gen_andi_i64(o
->in2
, o
->in2
, mask
);
3208 tcg_gen_xor_i64(o
->out
, o
->out
, o
->in2
);
3215 tcg_gen_andi_i64(cc_dst
, o
->out
, mask
);
3216 set_cc_nz_u64(s
, cc_dst
);
3220 static ExitStatus
op_rev16(DisasContext
*s
, DisasOps
*o
)
3222 tcg_gen_bswap16_i64(o
->out
, o
->in2
);
3226 static ExitStatus
op_rev32(DisasContext
*s
, DisasOps
*o
)
3228 tcg_gen_bswap32_i64(o
->out
, o
->in2
);
3232 static ExitStatus
op_rev64(DisasContext
*s
, DisasOps
*o
)
3234 tcg_gen_bswap64_i64(o
->out
, o
->in2
);
3238 static ExitStatus
op_rll32(DisasContext
*s
, DisasOps
*o
)
3240 TCGv_i32 t1
= tcg_temp_new_i32();
3241 TCGv_i32 t2
= tcg_temp_new_i32();
3242 TCGv_i32 to
= tcg_temp_new_i32();
3243 tcg_gen_extrl_i64_i32(t1
, o
->in1
);
3244 tcg_gen_extrl_i64_i32(t2
, o
->in2
);
3245 tcg_gen_rotl_i32(to
, t1
, t2
);
3246 tcg_gen_extu_i32_i64(o
->out
, to
);
3247 tcg_temp_free_i32(t1
);
3248 tcg_temp_free_i32(t2
);
3249 tcg_temp_free_i32(to
);
3253 static ExitStatus
op_rll64(DisasContext
*s
, DisasOps
*o
)
3255 tcg_gen_rotl_i64(o
->out
, o
->in1
, o
->in2
);
3259 #ifndef CONFIG_USER_ONLY
3260 static ExitStatus
op_rrbe(DisasContext
*s
, DisasOps
*o
)
3262 check_privileged(s
);
3263 gen_helper_rrbe(cc_op
, cpu_env
, o
->in2
);
3268 static ExitStatus
op_sacf(DisasContext
*s
, DisasOps
*o
)
3270 check_privileged(s
);
3271 gen_helper_sacf(cpu_env
, o
->in2
);
3272 /* Addressing mode has changed, so end the block. */
3273 return EXIT_PC_STALE
;
3277 static ExitStatus
op_sam(DisasContext
*s
, DisasOps
*o
)
3279 int sam
= s
->insn
->data
;
3295 /* Bizarre but true, we check the address of the current insn for the
3296 specification exception, not the next to be executed. Thus the PoO
3297 documents that Bad Things Happen two bytes before the end. */
3298 if (s
->pc
& ~mask
) {
3299 gen_program_exception(s
, PGM_SPECIFICATION
);
3300 return EXIT_NORETURN
;
3304 tsam
= tcg_const_i64(sam
);
3305 tcg_gen_deposit_i64(psw_mask
, psw_mask
, tsam
, 31, 2);
3306 tcg_temp_free_i64(tsam
);
3308 /* Always exit the TB, since we (may have) changed execution mode. */
3309 return EXIT_PC_STALE
;
3312 static ExitStatus
op_sar(DisasContext
*s
, DisasOps
*o
)
3314 int r1
= get_field(s
->fields
, r1
);
3315 tcg_gen_st32_i64(o
->in2
, cpu_env
, offsetof(CPUS390XState
, aregs
[r1
]));
3319 static ExitStatus
op_seb(DisasContext
*s
, DisasOps
*o
)
3321 gen_helper_seb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
3325 static ExitStatus
op_sdb(DisasContext
*s
, DisasOps
*o
)
3327 gen_helper_sdb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
3331 static ExitStatus
op_sxb(DisasContext
*s
, DisasOps
*o
)
3333 gen_helper_sxb(o
->out
, cpu_env
, o
->out
, o
->out2
, o
->in1
, o
->in2
);
3334 return_low128(o
->out2
);
3338 static ExitStatus
op_sqeb(DisasContext
*s
, DisasOps
*o
)
3340 gen_helper_sqeb(o
->out
, cpu_env
, o
->in2
);
3344 static ExitStatus
op_sqdb(DisasContext
*s
, DisasOps
*o
)
3346 gen_helper_sqdb(o
->out
, cpu_env
, o
->in2
);
3350 static ExitStatus
op_sqxb(DisasContext
*s
, DisasOps
*o
)
3352 gen_helper_sqxb(o
->out
, cpu_env
, o
->in1
, o
->in2
);
3353 return_low128(o
->out2
);
3357 #ifndef CONFIG_USER_ONLY
3358 static ExitStatus
op_servc(DisasContext
*s
, DisasOps
*o
)
3360 check_privileged(s
);
3361 potential_page_fault(s
);
3362 gen_helper_servc(cc_op
, cpu_env
, o
->in2
, o
->in1
);
3367 static ExitStatus
op_sigp(DisasContext
*s
, DisasOps
*o
)
3369 TCGv_i32 r1
= tcg_const_i32(get_field(s
->fields
, r1
));
3370 check_privileged(s
);
3371 potential_page_fault(s
);
3372 gen_helper_sigp(cc_op
, cpu_env
, o
->in2
, r1
, o
->in1
);
3373 tcg_temp_free_i32(r1
);
3378 static ExitStatus
op_soc(DisasContext
*s
, DisasOps
*o
)
3385 disas_jcc(s
, &c
, get_field(s
->fields
, m3
));
3387 /* We want to store when the condition is fulfilled, so branch
3388 out when it's not */
3389 c
.cond
= tcg_invert_cond(c
.cond
);
3391 lab
= gen_new_label();
3393 tcg_gen_brcond_i64(c
.cond
, c
.u
.s64
.a
, c
.u
.s64
.b
, lab
);
3395 tcg_gen_brcond_i32(c
.cond
, c
.u
.s32
.a
, c
.u
.s32
.b
, lab
);
3399 r1
= get_field(s
->fields
, r1
);
3400 a
= get_address(s
, 0, get_field(s
->fields
, b2
), get_field(s
->fields
, d2
));
3401 if (s
->insn
->data
) {
3402 tcg_gen_qemu_st64(regs
[r1
], a
, get_mem_index(s
));
3404 tcg_gen_qemu_st32(regs
[r1
], a
, get_mem_index(s
));
3406 tcg_temp_free_i64(a
);
3412 static ExitStatus
op_sla(DisasContext
*s
, DisasOps
*o
)
3414 uint64_t sign
= 1ull << s
->insn
->data
;
3415 enum cc_op cco
= s
->insn
->data
== 31 ? CC_OP_SLA_32
: CC_OP_SLA_64
;
3416 gen_op_update2_cc_i64(s
, cco
, o
->in1
, o
->in2
);
3417 tcg_gen_shl_i64(o
->out
, o
->in1
, o
->in2
);
3418 /* The arithmetic left shift is curious in that it does not affect
3419 the sign bit. Copy that over from the source unchanged. */
3420 tcg_gen_andi_i64(o
->out
, o
->out
, ~sign
);
3421 tcg_gen_andi_i64(o
->in1
, o
->in1
, sign
);
3422 tcg_gen_or_i64(o
->out
, o
->out
, o
->in1
);
3426 static ExitStatus
op_sll(DisasContext
*s
, DisasOps
*o
)
3428 tcg_gen_shl_i64(o
->out
, o
->in1
, o
->in2
);
3432 static ExitStatus
op_sra(DisasContext
*s
, DisasOps
*o
)
3434 tcg_gen_sar_i64(o
->out
, o
->in1
, o
->in2
);
3438 static ExitStatus
op_srl(DisasContext
*s
, DisasOps
*o
)
3440 tcg_gen_shr_i64(o
->out
, o
->in1
, o
->in2
);
3444 static ExitStatus
op_sfpc(DisasContext
*s
, DisasOps
*o
)
3446 gen_helper_sfpc(cpu_env
, o
->in2
);
3450 static ExitStatus
op_sfas(DisasContext
*s
, DisasOps
*o
)
3452 gen_helper_sfas(cpu_env
, o
->in2
);
3456 static ExitStatus
op_srnm(DisasContext
*s
, DisasOps
*o
)
3458 int b2
= get_field(s
->fields
, b2
);
3459 int d2
= get_field(s
->fields
, d2
);
3460 TCGv_i64 t1
= tcg_temp_new_i64();
3461 TCGv_i64 t2
= tcg_temp_new_i64();
3464 switch (s
->fields
->op2
) {
3465 case 0x99: /* SRNM */
3468 case 0xb8: /* SRNMB */
3471 case 0xb9: /* SRNMT */
3477 mask
= (1 << len
) - 1;
3479 /* Insert the value into the appropriate field of the FPC. */
3481 tcg_gen_movi_i64(t1
, d2
& mask
);
3483 tcg_gen_addi_i64(t1
, regs
[b2
], d2
);
3484 tcg_gen_andi_i64(t1
, t1
, mask
);
3486 tcg_gen_ld32u_i64(t2
, cpu_env
, offsetof(CPUS390XState
, fpc
));
3487 tcg_gen_deposit_i64(t2
, t2
, t1
, pos
, len
);
3488 tcg_temp_free_i64(t1
);
3490 /* Then install the new FPC to set the rounding mode in fpu_status. */
3491 gen_helper_sfpc(cpu_env
, t2
);
3492 tcg_temp_free_i64(t2
);
3496 #ifndef CONFIG_USER_ONLY
3497 static ExitStatus
op_spka(DisasContext
*s
, DisasOps
*o
)
3499 check_privileged(s
);
3500 tcg_gen_shri_i64(o
->in2
, o
->in2
, 4);
3501 tcg_gen_deposit_i64(psw_mask
, psw_mask
, o
->in2
, PSW_SHIFT_KEY
- 4, 4);
3505 static ExitStatus
op_sske(DisasContext
*s
, DisasOps
*o
)
3507 check_privileged(s
);
3508 gen_helper_sske(cpu_env
, o
->in1
, o
->in2
);
3512 static ExitStatus
op_ssm(DisasContext
*s
, DisasOps
*o
)
3514 check_privileged(s
);
3515 tcg_gen_deposit_i64(psw_mask
, psw_mask
, o
->in2
, 56, 8);
3519 static ExitStatus
op_stap(DisasContext
*s
, DisasOps
*o
)
3521 check_privileged(s
);
3522 /* ??? Surely cpu address != cpu number. In any case the previous
3523 version of this stored more than the required half-word, so it
3524 is unlikely this has ever been tested. */
3525 tcg_gen_ld32u_i64(o
->out
, cpu_env
, offsetof(CPUS390XState
, cpu_num
));
3529 static ExitStatus
op_stck(DisasContext
*s
, DisasOps
*o
)
3531 gen_helper_stck(o
->out
, cpu_env
);
3532 /* ??? We don't implement clock states. */
3533 gen_op_movi_cc(s
, 0);
3537 static ExitStatus
op_stcke(DisasContext
*s
, DisasOps
*o
)
3539 TCGv_i64 c1
= tcg_temp_new_i64();
3540 TCGv_i64 c2
= tcg_temp_new_i64();
3541 gen_helper_stck(c1
, cpu_env
);
3542 /* Shift the 64-bit value into its place as a zero-extended
3543 104-bit value. Note that "bit positions 64-103 are always
3544 non-zero so that they compare differently to STCK"; we set
3545 the least significant bit to 1. */
3546 tcg_gen_shli_i64(c2
, c1
, 56);
3547 tcg_gen_shri_i64(c1
, c1
, 8);
3548 tcg_gen_ori_i64(c2
, c2
, 0x10000);
3549 tcg_gen_qemu_st64(c1
, o
->in2
, get_mem_index(s
));
3550 tcg_gen_addi_i64(o
->in2
, o
->in2
, 8);
3551 tcg_gen_qemu_st64(c2
, o
->in2
, get_mem_index(s
));
3552 tcg_temp_free_i64(c1
);
3553 tcg_temp_free_i64(c2
);
3554 /* ??? We don't implement clock states. */
3555 gen_op_movi_cc(s
, 0);
3559 static ExitStatus
op_sckc(DisasContext
*s
, DisasOps
*o
)
3561 check_privileged(s
);
3562 gen_helper_sckc(cpu_env
, o
->in2
);
3566 static ExitStatus
op_stckc(DisasContext
*s
, DisasOps
*o
)
3568 check_privileged(s
);
3569 gen_helper_stckc(o
->out
, cpu_env
);
3573 static ExitStatus
op_stctg(DisasContext
*s
, DisasOps
*o
)
3575 TCGv_i32 r1
= tcg_const_i32(get_field(s
->fields
, r1
));
3576 TCGv_i32 r3
= tcg_const_i32(get_field(s
->fields
, r3
));
3577 check_privileged(s
);
3578 potential_page_fault(s
);
3579 gen_helper_stctg(cpu_env
, r1
, o
->in2
, r3
);
3580 tcg_temp_free_i32(r1
);
3581 tcg_temp_free_i32(r3
);
3585 static ExitStatus
op_stctl(DisasContext
*s
, DisasOps
*o
)
3587 TCGv_i32 r1
= tcg_const_i32(get_field(s
->fields
, r1
));
3588 TCGv_i32 r3
= tcg_const_i32(get_field(s
->fields
, r3
));
3589 check_privileged(s
);
3590 potential_page_fault(s
);
3591 gen_helper_stctl(cpu_env
, r1
, o
->in2
, r3
);
3592 tcg_temp_free_i32(r1
);
3593 tcg_temp_free_i32(r3
);
3597 static ExitStatus
op_stidp(DisasContext
*s
, DisasOps
*o
)
3599 TCGv_i64 t1
= tcg_temp_new_i64();
3601 check_privileged(s
);
3602 tcg_gen_ld32u_i64(o
->out
, cpu_env
, offsetof(CPUS390XState
, cpu_num
));
3603 tcg_gen_ld32u_i64(t1
, cpu_env
, offsetof(CPUS390XState
, machine_type
));
3604 tcg_gen_deposit_i64(o
->out
, o
->out
, t1
, 32, 32);
3605 tcg_temp_free_i64(t1
);
3610 static ExitStatus
op_spt(DisasContext
*s
, DisasOps
*o
)
3612 check_privileged(s
);
3613 gen_helper_spt(cpu_env
, o
->in2
);
3617 static ExitStatus
op_stfl(DisasContext
*s
, DisasOps
*o
)
3620 /* We really ought to have more complete indication of facilities
3621 that we implement. Address this when STFLE is implemented. */
3622 check_privileged(s
);
3623 f
= tcg_const_i64(0xc0000000);
3624 a
= tcg_const_i64(200);
3625 tcg_gen_qemu_st32(f
, a
, get_mem_index(s
));
3626 tcg_temp_free_i64(f
);
3627 tcg_temp_free_i64(a
);
3631 static ExitStatus
op_stpt(DisasContext
*s
, DisasOps
*o
)
3633 check_privileged(s
);
3634 gen_helper_stpt(o
->out
, cpu_env
);
3638 static ExitStatus
op_stsi(DisasContext
*s
, DisasOps
*o
)
3640 check_privileged(s
);
3641 potential_page_fault(s
);
3642 gen_helper_stsi(cc_op
, cpu_env
, o
->in2
, regs
[0], regs
[1]);
3647 static ExitStatus
op_spx(DisasContext
*s
, DisasOps
*o
)
3649 check_privileged(s
);
3650 gen_helper_spx(cpu_env
, o
->in2
);
3654 static ExitStatus
op_xsch(DisasContext
*s
, DisasOps
*o
)
3656 check_privileged(s
);
3657 potential_page_fault(s
);
3658 gen_helper_xsch(cpu_env
, regs
[1]);
3663 static ExitStatus
op_csch(DisasContext
*s
, DisasOps
*o
)
3665 check_privileged(s
);
3666 potential_page_fault(s
);
3667 gen_helper_csch(cpu_env
, regs
[1]);
3672 static ExitStatus
op_hsch(DisasContext
*s
, DisasOps
*o
)
3674 check_privileged(s
);
3675 potential_page_fault(s
);
3676 gen_helper_hsch(cpu_env
, regs
[1]);
3681 static ExitStatus
op_msch(DisasContext
*s
, DisasOps
*o
)
3683 check_privileged(s
);
3684 potential_page_fault(s
);
3685 gen_helper_msch(cpu_env
, regs
[1], o
->in2
);
3690 static ExitStatus
op_rchp(DisasContext
*s
, DisasOps
*o
)
3692 check_privileged(s
);
3693 potential_page_fault(s
);
3694 gen_helper_rchp(cpu_env
, regs
[1]);
3699 static ExitStatus
op_rsch(DisasContext
*s
, DisasOps
*o
)
3701 check_privileged(s
);
3702 potential_page_fault(s
);
3703 gen_helper_rsch(cpu_env
, regs
[1]);
3708 static ExitStatus
op_ssch(DisasContext
*s
, DisasOps
*o
)
3710 check_privileged(s
);
3711 potential_page_fault(s
);
3712 gen_helper_ssch(cpu_env
, regs
[1], o
->in2
);
3717 static ExitStatus
op_stsch(DisasContext
*s
, DisasOps
*o
)
3719 check_privileged(s
);
3720 potential_page_fault(s
);
3721 gen_helper_stsch(cpu_env
, regs
[1], o
->in2
);
3726 static ExitStatus
op_tsch(DisasContext
*s
, DisasOps
*o
)
3728 check_privileged(s
);
3729 potential_page_fault(s
);
3730 gen_helper_tsch(cpu_env
, regs
[1], o
->in2
);
3735 static ExitStatus
op_chsc(DisasContext
*s
, DisasOps
*o
)
3737 check_privileged(s
);
3738 potential_page_fault(s
);
3739 gen_helper_chsc(cpu_env
, o
->in2
);
3744 static ExitStatus
op_stpx(DisasContext
*s
, DisasOps
*o
)
3746 check_privileged(s
);
3747 tcg_gen_ld_i64(o
->out
, cpu_env
, offsetof(CPUS390XState
, psa
));
3748 tcg_gen_andi_i64(o
->out
, o
->out
, 0x7fffe000);
3752 static ExitStatus
op_stnosm(DisasContext
*s
, DisasOps
*o
)
3754 uint64_t i2
= get_field(s
->fields
, i2
);
3757 check_privileged(s
);
3759 /* It is important to do what the instruction name says: STORE THEN.
3760 If we let the output hook perform the store then if we fault and
3761 restart, we'll have the wrong SYSTEM MASK in place. */
3762 t
= tcg_temp_new_i64();
3763 tcg_gen_shri_i64(t
, psw_mask
, 56);
3764 tcg_gen_qemu_st8(t
, o
->addr1
, get_mem_index(s
));
3765 tcg_temp_free_i64(t
);
3767 if (s
->fields
->op
== 0xac) {
3768 tcg_gen_andi_i64(psw_mask
, psw_mask
,
3769 (i2
<< 56) | 0x00ffffffffffffffull
);
3771 tcg_gen_ori_i64(psw_mask
, psw_mask
, i2
<< 56);
3776 static ExitStatus
op_stura(DisasContext
*s
, DisasOps
*o
)
3778 check_privileged(s
);
3779 potential_page_fault(s
);
3780 gen_helper_stura(cpu_env
, o
->in2
, o
->in1
);
3784 static ExitStatus
op_sturg(DisasContext
*s
, DisasOps
*o
)
3786 check_privileged(s
);
3787 potential_page_fault(s
);
3788 gen_helper_sturg(cpu_env
, o
->in2
, o
->in1
);
3793 static ExitStatus
op_st8(DisasContext
*s
, DisasOps
*o
)
3795 tcg_gen_qemu_st8(o
->in1
, o
->in2
, get_mem_index(s
));
3799 static ExitStatus
op_st16(DisasContext
*s
, DisasOps
*o
)
3801 tcg_gen_qemu_st16(o
->in1
, o
->in2
, get_mem_index(s
));
3805 static ExitStatus
op_st32(DisasContext
*s
, DisasOps
*o
)
3807 tcg_gen_qemu_st32(o
->in1
, o
->in2
, get_mem_index(s
));
3811 static ExitStatus
op_st64(DisasContext
*s
, DisasOps
*o
)
3813 tcg_gen_qemu_st64(o
->in1
, o
->in2
, get_mem_index(s
));
3817 static ExitStatus
op_stam(DisasContext
*s
, DisasOps
*o
)
3819 TCGv_i32 r1
= tcg_const_i32(get_field(s
->fields
, r1
));
3820 TCGv_i32 r3
= tcg_const_i32(get_field(s
->fields
, r3
));
3821 potential_page_fault(s
);
3822 gen_helper_stam(cpu_env
, r1
, o
->in2
, r3
);
3823 tcg_temp_free_i32(r1
);
3824 tcg_temp_free_i32(r3
);
3828 static ExitStatus
op_stcm(DisasContext
*s
, DisasOps
*o
)
3830 int m3
= get_field(s
->fields
, m3
);
3831 int pos
, base
= s
->insn
->data
;
3832 TCGv_i64 tmp
= tcg_temp_new_i64();
3834 pos
= base
+ ctz32(m3
) * 8;
3837 /* Effectively a 32-bit store. */
3838 tcg_gen_shri_i64(tmp
, o
->in1
, pos
);
3839 tcg_gen_qemu_st32(tmp
, o
->in2
, get_mem_index(s
));
3845 /* Effectively a 16-bit store. */
3846 tcg_gen_shri_i64(tmp
, o
->in1
, pos
);
3847 tcg_gen_qemu_st16(tmp
, o
->in2
, get_mem_index(s
));
3854 /* Effectively an 8-bit store. */
3855 tcg_gen_shri_i64(tmp
, o
->in1
, pos
);
3856 tcg_gen_qemu_st8(tmp
, o
->in2
, get_mem_index(s
));
3860 /* This is going to be a sequence of shifts and stores. */
3861 pos
= base
+ 32 - 8;
3864 tcg_gen_shri_i64(tmp
, o
->in1
, pos
);
3865 tcg_gen_qemu_st8(tmp
, o
->in2
, get_mem_index(s
));
3866 tcg_gen_addi_i64(o
->in2
, o
->in2
, 1);
3868 m3
= (m3
<< 1) & 0xf;
3873 tcg_temp_free_i64(tmp
);
3877 static ExitStatus
op_stm(DisasContext
*s
, DisasOps
*o
)
3879 int r1
= get_field(s
->fields
, r1
);
3880 int r3
= get_field(s
->fields
, r3
);
3881 int size
= s
->insn
->data
;
3882 TCGv_i64 tsize
= tcg_const_i64(size
);
3886 tcg_gen_qemu_st64(regs
[r1
], o
->in2
, get_mem_index(s
));
3888 tcg_gen_qemu_st32(regs
[r1
], o
->in2
, get_mem_index(s
));
3893 tcg_gen_add_i64(o
->in2
, o
->in2
, tsize
);
3897 tcg_temp_free_i64(tsize
);
3901 static ExitStatus
op_stmh(DisasContext
*s
, DisasOps
*o
)
3903 int r1
= get_field(s
->fields
, r1
);
3904 int r3
= get_field(s
->fields
, r3
);
3905 TCGv_i64 t
= tcg_temp_new_i64();
3906 TCGv_i64 t4
= tcg_const_i64(4);
3907 TCGv_i64 t32
= tcg_const_i64(32);
3910 tcg_gen_shl_i64(t
, regs
[r1
], t32
);
3911 tcg_gen_qemu_st32(t
, o
->in2
, get_mem_index(s
));
3915 tcg_gen_add_i64(o
->in2
, o
->in2
, t4
);
3919 tcg_temp_free_i64(t
);
3920 tcg_temp_free_i64(t4
);
3921 tcg_temp_free_i64(t32
);
3925 static ExitStatus
op_srst(DisasContext
*s
, DisasOps
*o
)
3927 potential_page_fault(s
);
3928 gen_helper_srst(o
->in1
, cpu_env
, regs
[0], o
->in1
, o
->in2
);
3930 return_low128(o
->in2
);
3934 static ExitStatus
op_sub(DisasContext
*s
, DisasOps
*o
)
3936 tcg_gen_sub_i64(o
->out
, o
->in1
, o
->in2
);
3940 static ExitStatus
op_subb(DisasContext
*s
, DisasOps
*o
)
3945 tcg_gen_sub_i64(o
->out
, o
->in1
, o
->in2
);
3947 /* The !borrow flag is the msb of CC. Since we want the inverse of
3948 that, we ask for a comparison of CC=0 | CC=1 -> mask of 8 | 4. */
3949 disas_jcc(s
, &cmp
, 8 | 4);
3950 borrow
= tcg_temp_new_i64();
3952 tcg_gen_setcond_i64(cmp
.cond
, borrow
, cmp
.u
.s64
.a
, cmp
.u
.s64
.b
);
3954 TCGv_i32 t
= tcg_temp_new_i32();
3955 tcg_gen_setcond_i32(cmp
.cond
, t
, cmp
.u
.s32
.a
, cmp
.u
.s32
.b
);
3956 tcg_gen_extu_i32_i64(borrow
, t
);
3957 tcg_temp_free_i32(t
);
3961 tcg_gen_sub_i64(o
->out
, o
->out
, borrow
);
3962 tcg_temp_free_i64(borrow
);
3966 static ExitStatus
op_svc(DisasContext
*s
, DisasOps
*o
)
3973 t
= tcg_const_i32(get_field(s
->fields
, i1
) & 0xff);
3974 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUS390XState
, int_svc_code
));
3975 tcg_temp_free_i32(t
);
3977 t
= tcg_const_i32(s
->next_pc
- s
->pc
);
3978 tcg_gen_st_i32(t
, cpu_env
, offsetof(CPUS390XState
, int_svc_ilen
));
3979 tcg_temp_free_i32(t
);
3981 gen_exception(EXCP_SVC
);
3982 return EXIT_NORETURN
;
3985 static ExitStatus
op_tceb(DisasContext
*s
, DisasOps
*o
)
3987 gen_helper_tceb(cc_op
, o
->in1
, o
->in2
);
3992 static ExitStatus
op_tcdb(DisasContext
*s
, DisasOps
*o
)
3994 gen_helper_tcdb(cc_op
, o
->in1
, o
->in2
);
3999 static ExitStatus
op_tcxb(DisasContext
*s
, DisasOps
*o
)
4001 gen_helper_tcxb(cc_op
, o
->out
, o
->out2
, o
->in2
);
4006 #ifndef CONFIG_USER_ONLY
4007 static ExitStatus
op_tprot(DisasContext
*s
, DisasOps
*o
)
4009 potential_page_fault(s
);
4010 gen_helper_tprot(cc_op
, o
->addr1
, o
->in2
);
4016 static ExitStatus
op_tr(DisasContext
*s
, DisasOps
*o
)
4018 TCGv_i32 l
= tcg_const_i32(get_field(s
->fields
, l1
));
4019 potential_page_fault(s
);
4020 gen_helper_tr(cpu_env
, l
, o
->addr1
, o
->in2
);
4021 tcg_temp_free_i32(l
);
4026 static ExitStatus
op_tre(DisasContext
*s
, DisasOps
*o
)
4028 potential_page_fault(s
);
4029 gen_helper_tre(o
->out
, cpu_env
, o
->out
, o
->out2
, o
->in2
);
4030 return_low128(o
->out2
);
4035 static ExitStatus
op_trt(DisasContext
*s
, DisasOps
*o
)
4037 TCGv_i32 l
= tcg_const_i32(get_field(s
->fields
, l1
));
4038 potential_page_fault(s
);
4039 gen_helper_trt(cc_op
, cpu_env
, l
, o
->addr1
, o
->in2
);
4040 tcg_temp_free_i32(l
);
4045 static ExitStatus
op_unpk(DisasContext
*s
, DisasOps
*o
)
4047 TCGv_i32 l
= tcg_const_i32(get_field(s
->fields
, l1
));
4048 potential_page_fault(s
);
4049 gen_helper_unpk(cpu_env
, l
, o
->addr1
, o
->in2
);
4050 tcg_temp_free_i32(l
);
4054 static ExitStatus
op_xc(DisasContext
*s
, DisasOps
*o
)
4056 int d1
= get_field(s
->fields
, d1
);
4057 int d2
= get_field(s
->fields
, d2
);
4058 int b1
= get_field(s
->fields
, b1
);
4059 int b2
= get_field(s
->fields
, b2
);
4060 int l
= get_field(s
->fields
, l1
);
4063 o
->addr1
= get_address(s
, 0, b1
, d1
);
4065 /* If the addresses are identical, this is a store/memset of zero. */
4066 if (b1
== b2
&& d1
== d2
&& (l
+ 1) <= 32) {
4067 o
->in2
= tcg_const_i64(0);
4071 tcg_gen_qemu_st64(o
->in2
, o
->addr1
, get_mem_index(s
));
4074 tcg_gen_addi_i64(o
->addr1
, o
->addr1
, 8);
4078 tcg_gen_qemu_st32(o
->in2
, o
->addr1
, get_mem_index(s
));
4081 tcg_gen_addi_i64(o
->addr1
, o
->addr1
, 4);
4085 tcg_gen_qemu_st16(o
->in2
, o
->addr1
, get_mem_index(s
));
4088 tcg_gen_addi_i64(o
->addr1
, o
->addr1
, 2);
4092 tcg_gen_qemu_st8(o
->in2
, o
->addr1
, get_mem_index(s
));
4094 gen_op_movi_cc(s
, 0);
4098 /* But in general we'll defer to a helper. */
4099 o
->in2
= get_address(s
, 0, b2
, d2
);
4100 t32
= tcg_const_i32(l
);
4101 potential_page_fault(s
);
4102 gen_helper_xc(cc_op
, cpu_env
, t32
, o
->addr1
, o
->in2
);
4103 tcg_temp_free_i32(t32
);
4108 static ExitStatus
op_xor(DisasContext
*s
, DisasOps
*o
)
4110 tcg_gen_xor_i64(o
->out
, o
->in1
, o
->in2
);
4114 static ExitStatus
op_xori(DisasContext
*s
, DisasOps
*o
)
4116 int shift
= s
->insn
->data
& 0xff;
4117 int size
= s
->insn
->data
>> 8;
4118 uint64_t mask
= ((1ull << size
) - 1) << shift
;
4121 tcg_gen_shli_i64(o
->in2
, o
->in2
, shift
);
4122 tcg_gen_xor_i64(o
->out
, o
->in1
, o
->in2
);
4124 /* Produce the CC from only the bits manipulated. */
4125 tcg_gen_andi_i64(cc_dst
, o
->out
, mask
);
4126 set_cc_nz_u64(s
, cc_dst
);
4130 static ExitStatus
op_zero(DisasContext
*s
, DisasOps
*o
)
4132 o
->out
= tcg_const_i64(0);
4136 static ExitStatus
op_zero2(DisasContext
*s
, DisasOps
*o
)
4138 o
->out
= tcg_const_i64(0);
4144 /* ====================================================================== */
4145 /* The "Cc OUTput" generators. Given the generated output (and in some cases
4146 the original inputs), update the various cc data structures in order to
4147 be able to compute the new condition code. */
4149 static void cout_abs32(DisasContext
*s
, DisasOps
*o
)
4151 gen_op_update1_cc_i64(s
, CC_OP_ABS_32
, o
->out
);
4154 static void cout_abs64(DisasContext
*s
, DisasOps
*o
)
4156 gen_op_update1_cc_i64(s
, CC_OP_ABS_64
, o
->out
);
4159 static void cout_adds32(DisasContext
*s
, DisasOps
*o
)
4161 gen_op_update3_cc_i64(s
, CC_OP_ADD_32
, o
->in1
, o
->in2
, o
->out
);
4164 static void cout_adds64(DisasContext
*s
, DisasOps
*o
)
4166 gen_op_update3_cc_i64(s
, CC_OP_ADD_64
, o
->in1
, o
->in2
, o
->out
);
4169 static void cout_addu32(DisasContext
*s
, DisasOps
*o
)
4171 gen_op_update3_cc_i64(s
, CC_OP_ADDU_32
, o
->in1
, o
->in2
, o
->out
);
4174 static void cout_addu64(DisasContext
*s
, DisasOps
*o
)
4176 gen_op_update3_cc_i64(s
, CC_OP_ADDU_64
, o
->in1
, o
->in2
, o
->out
);
4179 static void cout_addc32(DisasContext
*s
, DisasOps
*o
)
4181 gen_op_update3_cc_i64(s
, CC_OP_ADDC_32
, o
->in1
, o
->in2
, o
->out
);
4184 static void cout_addc64(DisasContext
*s
, DisasOps
*o
)
4186 gen_op_update3_cc_i64(s
, CC_OP_ADDC_64
, o
->in1
, o
->in2
, o
->out
);
4189 static void cout_cmps32(DisasContext
*s
, DisasOps
*o
)
4191 gen_op_update2_cc_i64(s
, CC_OP_LTGT_32
, o
->in1
, o
->in2
);
4194 static void cout_cmps64(DisasContext
*s
, DisasOps
*o
)
4196 gen_op_update2_cc_i64(s
, CC_OP_LTGT_64
, o
->in1
, o
->in2
);
4199 static void cout_cmpu32(DisasContext
*s
, DisasOps
*o
)
4201 gen_op_update2_cc_i64(s
, CC_OP_LTUGTU_32
, o
->in1
, o
->in2
);
4204 static void cout_cmpu64(DisasContext
*s
, DisasOps
*o
)
4206 gen_op_update2_cc_i64(s
, CC_OP_LTUGTU_64
, o
->in1
, o
->in2
);
4209 static void cout_f32(DisasContext
*s
, DisasOps
*o
)
4211 gen_op_update1_cc_i64(s
, CC_OP_NZ_F32
, o
->out
);
4214 static void cout_f64(DisasContext
*s
, DisasOps
*o
)
4216 gen_op_update1_cc_i64(s
, CC_OP_NZ_F64
, o
->out
);
4219 static void cout_f128(DisasContext
*s
, DisasOps
*o
)
4221 gen_op_update2_cc_i64(s
, CC_OP_NZ_F128
, o
->out
, o
->out2
);
4224 static void cout_nabs32(DisasContext
*s
, DisasOps
*o
)
4226 gen_op_update1_cc_i64(s
, CC_OP_NABS_32
, o
->out
);
4229 static void cout_nabs64(DisasContext
*s
, DisasOps
*o
)
4231 gen_op_update1_cc_i64(s
, CC_OP_NABS_64
, o
->out
);
4234 static void cout_neg32(DisasContext
*s
, DisasOps
*o
)
4236 gen_op_update1_cc_i64(s
, CC_OP_COMP_32
, o
->out
);
4239 static void cout_neg64(DisasContext
*s
, DisasOps
*o
)
4241 gen_op_update1_cc_i64(s
, CC_OP_COMP_64
, o
->out
);
4244 static void cout_nz32(DisasContext
*s
, DisasOps
*o
)
4246 tcg_gen_ext32u_i64(cc_dst
, o
->out
);
4247 gen_op_update1_cc_i64(s
, CC_OP_NZ
, cc_dst
);
4250 static void cout_nz64(DisasContext
*s
, DisasOps
*o
)
4252 gen_op_update1_cc_i64(s
, CC_OP_NZ
, o
->out
);
4255 static void cout_s32(DisasContext
*s
, DisasOps
*o
)
4257 gen_op_update1_cc_i64(s
, CC_OP_LTGT0_32
, o
->out
);
4260 static void cout_s64(DisasContext
*s
, DisasOps
*o
)
4262 gen_op_update1_cc_i64(s
, CC_OP_LTGT0_64
, o
->out
);
4265 static void cout_subs32(DisasContext
*s
, DisasOps
*o
)
4267 gen_op_update3_cc_i64(s
, CC_OP_SUB_32
, o
->in1
, o
->in2
, o
->out
);
4270 static void cout_subs64(DisasContext
*s
, DisasOps
*o
)
4272 gen_op_update3_cc_i64(s
, CC_OP_SUB_64
, o
->in1
, o
->in2
, o
->out
);
4275 static void cout_subu32(DisasContext
*s
, DisasOps
*o
)
4277 gen_op_update3_cc_i64(s
, CC_OP_SUBU_32
, o
->in1
, o
->in2
, o
->out
);
4280 static void cout_subu64(DisasContext
*s
, DisasOps
*o
)
4282 gen_op_update3_cc_i64(s
, CC_OP_SUBU_64
, o
->in1
, o
->in2
, o
->out
);
4285 static void cout_subb32(DisasContext
*s
, DisasOps
*o
)
4287 gen_op_update3_cc_i64(s
, CC_OP_SUBB_32
, o
->in1
, o
->in2
, o
->out
);
4290 static void cout_subb64(DisasContext
*s
, DisasOps
*o
)
4292 gen_op_update3_cc_i64(s
, CC_OP_SUBB_64
, o
->in1
, o
->in2
, o
->out
);
4295 static void cout_tm32(DisasContext
*s
, DisasOps
*o
)
4297 gen_op_update2_cc_i64(s
, CC_OP_TM_32
, o
->in1
, o
->in2
);
4300 static void cout_tm64(DisasContext
*s
, DisasOps
*o
)
4302 gen_op_update2_cc_i64(s
, CC_OP_TM_64
, o
->in1
, o
->in2
);
4305 /* ====================================================================== */
4306 /* The "PREParation" generators. These initialize the DisasOps.OUT fields
4307 with the TCG register to which we will write. Used in combination with
4308 the "wout" generators, in some cases we need a new temporary, and in
4309 some cases we can write to a TCG global. */
4311 static void prep_new(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4313 o
->out
= tcg_temp_new_i64();
4315 #define SPEC_prep_new 0
4317 static void prep_new_P(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4319 o
->out
= tcg_temp_new_i64();
4320 o
->out2
= tcg_temp_new_i64();
4322 #define SPEC_prep_new_P 0
4324 static void prep_r1(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4326 o
->out
= regs
[get_field(f
, r1
)];
4329 #define SPEC_prep_r1 0
4331 static void prep_r1_P(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4333 int r1
= get_field(f
, r1
);
4335 o
->out2
= regs
[r1
+ 1];
4336 o
->g_out
= o
->g_out2
= true;
4338 #define SPEC_prep_r1_P SPEC_r1_even
4340 static void prep_f1(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4342 o
->out
= fregs
[get_field(f
, r1
)];
4345 #define SPEC_prep_f1 0
4347 static void prep_x1(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4349 int r1
= get_field(f
, r1
);
4351 o
->out2
= fregs
[r1
+ 2];
4352 o
->g_out
= o
->g_out2
= true;
4354 #define SPEC_prep_x1 SPEC_r1_f128
4356 /* ====================================================================== */
4357 /* The "Write OUTput" generators. These generally perform some non-trivial
4358 copy of data to TCG globals, or to main memory. The trivial cases are
4359 generally handled by having a "prep" generator install the TCG global
4360 as the destination of the operation. */
4362 static void wout_r1(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4364 store_reg(get_field(f
, r1
), o
->out
);
4366 #define SPEC_wout_r1 0
4368 static void wout_r1_8(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4370 int r1
= get_field(f
, r1
);
4371 tcg_gen_deposit_i64(regs
[r1
], regs
[r1
], o
->out
, 0, 8);
4373 #define SPEC_wout_r1_8 0
4375 static void wout_r1_16(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4377 int r1
= get_field(f
, r1
);
4378 tcg_gen_deposit_i64(regs
[r1
], regs
[r1
], o
->out
, 0, 16);
4380 #define SPEC_wout_r1_16 0
4382 static void wout_r1_32(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4384 store_reg32_i64(get_field(f
, r1
), o
->out
);
4386 #define SPEC_wout_r1_32 0
4388 static void wout_r1_32h(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4390 store_reg32h_i64(get_field(f
, r1
), o
->out
);
4392 #define SPEC_wout_r1_32h 0
4394 static void wout_r1_P32(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4396 int r1
= get_field(f
, r1
);
4397 store_reg32_i64(r1
, o
->out
);
4398 store_reg32_i64(r1
+ 1, o
->out2
);
4400 #define SPEC_wout_r1_P32 SPEC_r1_even
4402 static void wout_r1_D32(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4404 int r1
= get_field(f
, r1
);
4405 store_reg32_i64(r1
+ 1, o
->out
);
4406 tcg_gen_shri_i64(o
->out
, o
->out
, 32);
4407 store_reg32_i64(r1
, o
->out
);
4409 #define SPEC_wout_r1_D32 SPEC_r1_even
4411 static void wout_e1(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4413 store_freg32_i64(get_field(f
, r1
), o
->out
);
4415 #define SPEC_wout_e1 0
4417 static void wout_f1(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4419 store_freg(get_field(f
, r1
), o
->out
);
4421 #define SPEC_wout_f1 0
4423 static void wout_x1(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4425 int f1
= get_field(s
->fields
, r1
);
4426 store_freg(f1
, o
->out
);
4427 store_freg(f1
+ 2, o
->out2
);
4429 #define SPEC_wout_x1 SPEC_r1_f128
4431 static void wout_cond_r1r2_32(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4433 if (get_field(f
, r1
) != get_field(f
, r2
)) {
4434 store_reg32_i64(get_field(f
, r1
), o
->out
);
4437 #define SPEC_wout_cond_r1r2_32 0
4439 static void wout_cond_e1e2(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4441 if (get_field(f
, r1
) != get_field(f
, r2
)) {
4442 store_freg32_i64(get_field(f
, r1
), o
->out
);
4445 #define SPEC_wout_cond_e1e2 0
4447 static void wout_m1_8(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4449 tcg_gen_qemu_st8(o
->out
, o
->addr1
, get_mem_index(s
));
4451 #define SPEC_wout_m1_8 0
4453 static void wout_m1_16(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4455 tcg_gen_qemu_st16(o
->out
, o
->addr1
, get_mem_index(s
));
4457 #define SPEC_wout_m1_16 0
4459 static void wout_m1_32(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4461 tcg_gen_qemu_st32(o
->out
, o
->addr1
, get_mem_index(s
));
4463 #define SPEC_wout_m1_32 0
4465 static void wout_m1_64(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4467 tcg_gen_qemu_st64(o
->out
, o
->addr1
, get_mem_index(s
));
4469 #define SPEC_wout_m1_64 0
4471 static void wout_m2_32(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4473 tcg_gen_qemu_st32(o
->out
, o
->in2
, get_mem_index(s
));
4475 #define SPEC_wout_m2_32 0
4477 static void wout_m2_32_r1_atomic(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4479 /* XXX release reservation */
4480 tcg_gen_qemu_st32(o
->out
, o
->addr1
, get_mem_index(s
));
4481 store_reg32_i64(get_field(f
, r1
), o
->in2
);
4483 #define SPEC_wout_m2_32_r1_atomic 0
4485 static void wout_m2_64_r1_atomic(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4487 /* XXX release reservation */
4488 tcg_gen_qemu_st64(o
->out
, o
->addr1
, get_mem_index(s
));
4489 store_reg(get_field(f
, r1
), o
->in2
);
4491 #define SPEC_wout_m2_64_r1_atomic 0
4493 /* ====================================================================== */
4494 /* The "INput 1" generators. These load the first operand to an insn. */
4496 static void in1_r1(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4498 o
->in1
= load_reg(get_field(f
, r1
));
4500 #define SPEC_in1_r1 0
4502 static void in1_r1_o(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4504 o
->in1
= regs
[get_field(f
, r1
)];
4507 #define SPEC_in1_r1_o 0
4509 static void in1_r1_32s(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4511 o
->in1
= tcg_temp_new_i64();
4512 tcg_gen_ext32s_i64(o
->in1
, regs
[get_field(f
, r1
)]);
4514 #define SPEC_in1_r1_32s 0
4516 static void in1_r1_32u(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4518 o
->in1
= tcg_temp_new_i64();
4519 tcg_gen_ext32u_i64(o
->in1
, regs
[get_field(f
, r1
)]);
4521 #define SPEC_in1_r1_32u 0
4523 static void in1_r1_sr32(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4525 o
->in1
= tcg_temp_new_i64();
4526 tcg_gen_shri_i64(o
->in1
, regs
[get_field(f
, r1
)], 32);
4528 #define SPEC_in1_r1_sr32 0
4530 static void in1_r1p1(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4532 o
->in1
= load_reg(get_field(f
, r1
) + 1);
4534 #define SPEC_in1_r1p1 SPEC_r1_even
4536 static void in1_r1p1_32s(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4538 o
->in1
= tcg_temp_new_i64();
4539 tcg_gen_ext32s_i64(o
->in1
, regs
[get_field(f
, r1
) + 1]);
4541 #define SPEC_in1_r1p1_32s SPEC_r1_even
4543 static void in1_r1p1_32u(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4545 o
->in1
= tcg_temp_new_i64();
4546 tcg_gen_ext32u_i64(o
->in1
, regs
[get_field(f
, r1
) + 1]);
4548 #define SPEC_in1_r1p1_32u SPEC_r1_even
4550 static void in1_r1_D32(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4552 int r1
= get_field(f
, r1
);
4553 o
->in1
= tcg_temp_new_i64();
4554 tcg_gen_concat32_i64(o
->in1
, regs
[r1
+ 1], regs
[r1
]);
4556 #define SPEC_in1_r1_D32 SPEC_r1_even
4558 static void in1_r2(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4560 o
->in1
= load_reg(get_field(f
, r2
));
4562 #define SPEC_in1_r2 0
4564 static void in1_r2_sr32(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4566 o
->in1
= tcg_temp_new_i64();
4567 tcg_gen_shri_i64(o
->in1
, regs
[get_field(f
, r2
)], 32);
4569 #define SPEC_in1_r2_sr32 0
4571 static void in1_r3(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4573 o
->in1
= load_reg(get_field(f
, r3
));
4575 #define SPEC_in1_r3 0
4577 static void in1_r3_o(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4579 o
->in1
= regs
[get_field(f
, r3
)];
4582 #define SPEC_in1_r3_o 0
4584 static void in1_r3_32s(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4586 o
->in1
= tcg_temp_new_i64();
4587 tcg_gen_ext32s_i64(o
->in1
, regs
[get_field(f
, r3
)]);
4589 #define SPEC_in1_r3_32s 0
4591 static void in1_r3_32u(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4593 o
->in1
= tcg_temp_new_i64();
4594 tcg_gen_ext32u_i64(o
->in1
, regs
[get_field(f
, r3
)]);
4596 #define SPEC_in1_r3_32u 0
4598 static void in1_r3_D32(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4600 int r3
= get_field(f
, r3
);
4601 o
->in1
= tcg_temp_new_i64();
4602 tcg_gen_concat32_i64(o
->in1
, regs
[r3
+ 1], regs
[r3
]);
4604 #define SPEC_in1_r3_D32 SPEC_r3_even
4606 static void in1_e1(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4608 o
->in1
= load_freg32_i64(get_field(f
, r1
));
4610 #define SPEC_in1_e1 0
4612 static void in1_f1_o(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4614 o
->in1
= fregs
[get_field(f
, r1
)];
4617 #define SPEC_in1_f1_o 0
4619 static void in1_x1_o(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4621 int r1
= get_field(f
, r1
);
4623 o
->out2
= fregs
[r1
+ 2];
4624 o
->g_out
= o
->g_out2
= true;
4626 #define SPEC_in1_x1_o SPEC_r1_f128
4628 static void in1_f3_o(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4630 o
->in1
= fregs
[get_field(f
, r3
)];
4633 #define SPEC_in1_f3_o 0
4635 static void in1_la1(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4637 o
->addr1
= get_address(s
, 0, get_field(f
, b1
), get_field(f
, d1
));
4639 #define SPEC_in1_la1 0
4641 static void in1_la2(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4643 int x2
= have_field(f
, x2
) ? get_field(f
, x2
) : 0;
4644 o
->addr1
= get_address(s
, x2
, get_field(f
, b2
), get_field(f
, d2
));
4646 #define SPEC_in1_la2 0
4648 static void in1_m1_8u(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4651 o
->in1
= tcg_temp_new_i64();
4652 tcg_gen_qemu_ld8u(o
->in1
, o
->addr1
, get_mem_index(s
));
4654 #define SPEC_in1_m1_8u 0
4656 static void in1_m1_16s(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4659 o
->in1
= tcg_temp_new_i64();
4660 tcg_gen_qemu_ld16s(o
->in1
, o
->addr1
, get_mem_index(s
));
4662 #define SPEC_in1_m1_16s 0
4664 static void in1_m1_16u(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4667 o
->in1
= tcg_temp_new_i64();
4668 tcg_gen_qemu_ld16u(o
->in1
, o
->addr1
, get_mem_index(s
));
4670 #define SPEC_in1_m1_16u 0
4672 static void in1_m1_32s(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4675 o
->in1
= tcg_temp_new_i64();
4676 tcg_gen_qemu_ld32s(o
->in1
, o
->addr1
, get_mem_index(s
));
4678 #define SPEC_in1_m1_32s 0
4680 static void in1_m1_32u(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4683 o
->in1
= tcg_temp_new_i64();
4684 tcg_gen_qemu_ld32u(o
->in1
, o
->addr1
, get_mem_index(s
));
4686 #define SPEC_in1_m1_32u 0
4688 static void in1_m1_64(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4691 o
->in1
= tcg_temp_new_i64();
4692 tcg_gen_qemu_ld64(o
->in1
, o
->addr1
, get_mem_index(s
));
4694 #define SPEC_in1_m1_64 0
4696 /* ====================================================================== */
4697 /* The "INput 2" generators. These load the second operand to an insn. */
4699 static void in2_r1_o(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4701 o
->in2
= regs
[get_field(f
, r1
)];
4704 #define SPEC_in2_r1_o 0
4706 static void in2_r1_16u(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4708 o
->in2
= tcg_temp_new_i64();
4709 tcg_gen_ext16u_i64(o
->in2
, regs
[get_field(f
, r1
)]);
4711 #define SPEC_in2_r1_16u 0
4713 static void in2_r1_32u(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4715 o
->in2
= tcg_temp_new_i64();
4716 tcg_gen_ext32u_i64(o
->in2
, regs
[get_field(f
, r1
)]);
4718 #define SPEC_in2_r1_32u 0
4720 static void in2_r1_D32(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4722 int r1
= get_field(f
, r1
);
4723 o
->in2
= tcg_temp_new_i64();
4724 tcg_gen_concat32_i64(o
->in2
, regs
[r1
+ 1], regs
[r1
]);
4726 #define SPEC_in2_r1_D32 SPEC_r1_even
4728 static void in2_r2(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4730 o
->in2
= load_reg(get_field(f
, r2
));
4732 #define SPEC_in2_r2 0
4734 static void in2_r2_o(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4736 o
->in2
= regs
[get_field(f
, r2
)];
4739 #define SPEC_in2_r2_o 0
4741 static void in2_r2_nz(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4743 int r2
= get_field(f
, r2
);
4745 o
->in2
= load_reg(r2
);
4748 #define SPEC_in2_r2_nz 0
4750 static void in2_r2_8s(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4752 o
->in2
= tcg_temp_new_i64();
4753 tcg_gen_ext8s_i64(o
->in2
, regs
[get_field(f
, r2
)]);
4755 #define SPEC_in2_r2_8s 0
4757 static void in2_r2_8u(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4759 o
->in2
= tcg_temp_new_i64();
4760 tcg_gen_ext8u_i64(o
->in2
, regs
[get_field(f
, r2
)]);
4762 #define SPEC_in2_r2_8u 0
4764 static void in2_r2_16s(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4766 o
->in2
= tcg_temp_new_i64();
4767 tcg_gen_ext16s_i64(o
->in2
, regs
[get_field(f
, r2
)]);
4769 #define SPEC_in2_r2_16s 0
4771 static void in2_r2_16u(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4773 o
->in2
= tcg_temp_new_i64();
4774 tcg_gen_ext16u_i64(o
->in2
, regs
[get_field(f
, r2
)]);
4776 #define SPEC_in2_r2_16u 0
4778 static void in2_r3(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4780 o
->in2
= load_reg(get_field(f
, r3
));
4782 #define SPEC_in2_r3 0
4784 static void in2_r3_sr32(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4786 o
->in2
= tcg_temp_new_i64();
4787 tcg_gen_shri_i64(o
->in2
, regs
[get_field(f
, r3
)], 32);
4789 #define SPEC_in2_r3_sr32 0
4791 static void in2_r2_32s(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4793 o
->in2
= tcg_temp_new_i64();
4794 tcg_gen_ext32s_i64(o
->in2
, regs
[get_field(f
, r2
)]);
4796 #define SPEC_in2_r2_32s 0
4798 static void in2_r2_32u(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4800 o
->in2
= tcg_temp_new_i64();
4801 tcg_gen_ext32u_i64(o
->in2
, regs
[get_field(f
, r2
)]);
4803 #define SPEC_in2_r2_32u 0
4805 static void in2_r2_sr32(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4807 o
->in2
= tcg_temp_new_i64();
4808 tcg_gen_shri_i64(o
->in2
, regs
[get_field(f
, r2
)], 32);
4810 #define SPEC_in2_r2_sr32 0
4812 static void in2_e2(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4814 o
->in2
= load_freg32_i64(get_field(f
, r2
));
4816 #define SPEC_in2_e2 0
4818 static void in2_f2_o(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4820 o
->in2
= fregs
[get_field(f
, r2
)];
4823 #define SPEC_in2_f2_o 0
4825 static void in2_x2_o(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4827 int r2
= get_field(f
, r2
);
4829 o
->in2
= fregs
[r2
+ 2];
4830 o
->g_in1
= o
->g_in2
= true;
4832 #define SPEC_in2_x2_o SPEC_r2_f128
4834 static void in2_ra2(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4836 o
->in2
= get_address(s
, 0, get_field(f
, r2
), 0);
4838 #define SPEC_in2_ra2 0
4840 static void in2_a2(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4842 int x2
= have_field(f
, x2
) ? get_field(f
, x2
) : 0;
4843 o
->in2
= get_address(s
, x2
, get_field(f
, b2
), get_field(f
, d2
));
4845 #define SPEC_in2_a2 0
4847 static void in2_ri2(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4849 o
->in2
= tcg_const_i64(s
->pc
+ (int64_t)get_field(f
, i2
) * 2);
4851 #define SPEC_in2_ri2 0
4853 static void in2_sh32(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4855 help_l2_shift(s
, f
, o
, 31);
4857 #define SPEC_in2_sh32 0
4859 static void in2_sh64(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4861 help_l2_shift(s
, f
, o
, 63);
4863 #define SPEC_in2_sh64 0
4865 static void in2_m2_8u(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4868 tcg_gen_qemu_ld8u(o
->in2
, o
->in2
, get_mem_index(s
));
4870 #define SPEC_in2_m2_8u 0
4872 static void in2_m2_16s(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4875 tcg_gen_qemu_ld16s(o
->in2
, o
->in2
, get_mem_index(s
));
4877 #define SPEC_in2_m2_16s 0
4879 static void in2_m2_16u(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4882 tcg_gen_qemu_ld16u(o
->in2
, o
->in2
, get_mem_index(s
));
4884 #define SPEC_in2_m2_16u 0
4886 static void in2_m2_32s(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4889 tcg_gen_qemu_ld32s(o
->in2
, o
->in2
, get_mem_index(s
));
4891 #define SPEC_in2_m2_32s 0
4893 static void in2_m2_32u(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4896 tcg_gen_qemu_ld32u(o
->in2
, o
->in2
, get_mem_index(s
));
4898 #define SPEC_in2_m2_32u 0
4900 static void in2_m2_64(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4903 tcg_gen_qemu_ld64(o
->in2
, o
->in2
, get_mem_index(s
));
4905 #define SPEC_in2_m2_64 0
4907 static void in2_mri2_16u(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4910 tcg_gen_qemu_ld16u(o
->in2
, o
->in2
, get_mem_index(s
));
4912 #define SPEC_in2_mri2_16u 0
4914 static void in2_mri2_32s(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4917 tcg_gen_qemu_ld32s(o
->in2
, o
->in2
, get_mem_index(s
));
4919 #define SPEC_in2_mri2_32s 0
4921 static void in2_mri2_32u(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4924 tcg_gen_qemu_ld32u(o
->in2
, o
->in2
, get_mem_index(s
));
4926 #define SPEC_in2_mri2_32u 0
4928 static void in2_mri2_64(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4931 tcg_gen_qemu_ld64(o
->in2
, o
->in2
, get_mem_index(s
));
4933 #define SPEC_in2_mri2_64 0
4935 static void in2_m2_32s_atomic(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4937 /* XXX should reserve the address */
4939 o
->in2
= tcg_temp_new_i64();
4940 tcg_gen_qemu_ld32s(o
->in2
, o
->addr1
, get_mem_index(s
));
4942 #define SPEC_in2_m2_32s_atomic 0
4944 static void in2_m2_64_atomic(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4946 /* XXX should reserve the address */
4948 o
->in2
= tcg_temp_new_i64();
4949 tcg_gen_qemu_ld64(o
->in2
, o
->addr1
, get_mem_index(s
));
4951 #define SPEC_in2_m2_64_atomic 0
4953 static void in2_i2(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4955 o
->in2
= tcg_const_i64(get_field(f
, i2
));
4957 #define SPEC_in2_i2 0
4959 static void in2_i2_8u(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4961 o
->in2
= tcg_const_i64((uint8_t)get_field(f
, i2
));
4963 #define SPEC_in2_i2_8u 0
4965 static void in2_i2_16u(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4967 o
->in2
= tcg_const_i64((uint16_t)get_field(f
, i2
));
4969 #define SPEC_in2_i2_16u 0
4971 static void in2_i2_32u(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4973 o
->in2
= tcg_const_i64((uint32_t)get_field(f
, i2
));
4975 #define SPEC_in2_i2_32u 0
4977 static void in2_i2_16u_shl(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4979 uint64_t i2
= (uint16_t)get_field(f
, i2
);
4980 o
->in2
= tcg_const_i64(i2
<< s
->insn
->data
);
4982 #define SPEC_in2_i2_16u_shl 0
4984 static void in2_i2_32u_shl(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4986 uint64_t i2
= (uint32_t)get_field(f
, i2
);
4987 o
->in2
= tcg_const_i64(i2
<< s
->insn
->data
);
4989 #define SPEC_in2_i2_32u_shl 0
4991 #ifndef CONFIG_USER_ONLY
4992 static void in2_insn(DisasContext
*s
, DisasFields
*f
, DisasOps
*o
)
4994 o
->in2
= tcg_const_i64(s
->fields
->raw_insn
);
4996 #define SPEC_in2_insn 0
4999 /* ====================================================================== */
5001 /* Find opc within the table of insns. This is formulated as a switch
5002 statement so that (1) we get compile-time notice of cut-paste errors
5003 for duplicated opcodes, and (2) the compiler generates the binary
5004 search tree, rather than us having to post-process the table. */
5006 #define C(OPC, NM, FT, FC, I1, I2, P, W, OP, CC) \
5007 D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, 0)
5009 #define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) insn_ ## NM,
5011 enum DisasInsnEnum
{
5012 #include "insn-data.def"
5016 #define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) { \
5020 .spec = SPEC_in1_##I1 | SPEC_in2_##I2 | SPEC_prep_##P | SPEC_wout_##W, \
5022 .help_in1 = in1_##I1, \
5023 .help_in2 = in2_##I2, \
5024 .help_prep = prep_##P, \
5025 .help_wout = wout_##W, \
5026 .help_cout = cout_##CC, \
5027 .help_op = op_##OP, \
5031 /* Allow 0 to be used for NULL in the table below. */
5039 #define SPEC_in1_0 0
5040 #define SPEC_in2_0 0
5041 #define SPEC_prep_0 0
5042 #define SPEC_wout_0 0
5044 static const DisasInsn insn_info
[] = {
5045 #include "insn-data.def"
5049 #define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) \
5050 case OPC: return &insn_info[insn_ ## NM];
5052 static const DisasInsn
*lookup_opc(uint16_t opc
)
5055 #include "insn-data.def"
5064 /* Extract a field from the insn. The INSN should be left-aligned in
5065 the uint64_t so that we can more easily utilize the big-bit-endian
5066 definitions we extract from the Principals of Operation. */
5068 static void extract_field(DisasFields
*o
, const DisasField
*f
, uint64_t insn
)
5076 /* Zero extract the field from the insn. */
5077 r
= (insn
<< f
->beg
) >> (64 - f
->size
);
5079 /* Sign-extend, or un-swap the field as necessary. */
5081 case 0: /* unsigned */
5083 case 1: /* signed */
5084 assert(f
->size
<= 32);
5085 m
= 1u << (f
->size
- 1);
5088 case 2: /* dl+dh split, signed 20 bit. */
5089 r
= ((int8_t)r
<< 12) | (r
>> 8);
5095 /* Validate that the "compressed" encoding we selected above is valid.
5096 I.e. we havn't make two different original fields overlap. */
5097 assert(((o
->presentC
>> f
->indexC
) & 1) == 0);
5098 o
->presentC
|= 1 << f
->indexC
;
5099 o
->presentO
|= 1 << f
->indexO
;
5101 o
->c
[f
->indexC
] = r
;
5104 /* Lookup the insn at the current PC, extracting the operands into O and
5105 returning the info struct for the insn. Returns NULL for invalid insn. */
5107 static const DisasInsn
*extract_insn(CPUS390XState
*env
, DisasContext
*s
,
5110 uint64_t insn
, pc
= s
->pc
;
5112 const DisasInsn
*info
;
5114 insn
= ld_code2(env
, pc
);
5115 op
= (insn
>> 8) & 0xff;
5116 ilen
= get_ilen(op
);
5117 s
->next_pc
= s
->pc
+ ilen
;
5124 insn
= ld_code4(env
, pc
) << 32;
5127 insn
= (insn
<< 48) | (ld_code4(env
, pc
+ 2) << 16);
5133 /* We can't actually determine the insn format until we've looked up
5134 the full insn opcode. Which we can't do without locating the
5135 secondary opcode. Assume by default that OP2 is at bit 40; for
5136 those smaller insns that don't actually have a secondary opcode
5137 this will correctly result in OP2 = 0. */
5143 case 0xb2: /* S, RRF, RRE */
5144 case 0xb3: /* RRE, RRD, RRF */
5145 case 0xb9: /* RRE, RRF */
5146 case 0xe5: /* SSE, SIL */
5147 op2
= (insn
<< 8) >> 56;
5151 case 0xc0: /* RIL */
5152 case 0xc2: /* RIL */
5153 case 0xc4: /* RIL */
5154 case 0xc6: /* RIL */
5155 case 0xc8: /* SSF */
5156 case 0xcc: /* RIL */
5157 op2
= (insn
<< 12) >> 60;
5159 case 0xd0 ... 0xdf: /* SS */
5165 case 0xee ... 0xf3: /* SS */
5166 case 0xf8 ... 0xfd: /* SS */
5170 op2
= (insn
<< 40) >> 56;
5174 memset(f
, 0, sizeof(*f
));
5179 /* Lookup the instruction. */
5180 info
= lookup_opc(op
<< 8 | op2
);
5182 /* If we found it, extract the operands. */
5184 DisasFormat fmt
= info
->fmt
;
5187 for (i
= 0; i
< NUM_C_FIELD
; ++i
) {
5188 extract_field(f
, &format_info
[fmt
].op
[i
], insn
);
5194 static ExitStatus
translate_one(CPUS390XState
*env
, DisasContext
*s
)
5196 const DisasInsn
*insn
;
5197 ExitStatus ret
= NO_EXIT
;
5201 /* Search for the insn in the table. */
5202 insn
= extract_insn(env
, s
, &f
);
5204 /* Not found means unimplemented/illegal opcode. */
5206 qemu_log_mask(LOG_UNIMP
, "unimplemented opcode 0x%02x%02x\n",
5208 gen_illegal_opcode(s
);
5209 return EXIT_NORETURN
;
5212 #ifndef CONFIG_USER_ONLY
5213 if (s
->tb
->flags
& FLAG_MASK_PER
) {
5214 TCGv_i64 addr
= tcg_const_i64(s
->pc
);
5215 gen_helper_per_ifetch(cpu_env
, addr
);
5216 tcg_temp_free_i64(addr
);
5220 /* Check for insn specification exceptions. */
5222 int spec
= insn
->spec
, excp
= 0, r
;
5224 if (spec
& SPEC_r1_even
) {
5225 r
= get_field(&f
, r1
);
5227 excp
= PGM_SPECIFICATION
;
5230 if (spec
& SPEC_r2_even
) {
5231 r
= get_field(&f
, r2
);
5233 excp
= PGM_SPECIFICATION
;
5236 if (spec
& SPEC_r3_even
) {
5237 r
= get_field(&f
, r3
);
5239 excp
= PGM_SPECIFICATION
;
5242 if (spec
& SPEC_r1_f128
) {
5243 r
= get_field(&f
, r1
);
5245 excp
= PGM_SPECIFICATION
;
5248 if (spec
& SPEC_r2_f128
) {
5249 r
= get_field(&f
, r2
);
5251 excp
= PGM_SPECIFICATION
;
5255 gen_program_exception(s
, excp
);
5256 return EXIT_NORETURN
;
5260 /* Set up the strutures we use to communicate with the helpers. */
5263 o
.g_out
= o
.g_out2
= o
.g_in1
= o
.g_in2
= false;
5264 TCGV_UNUSED_I64(o
.out
);
5265 TCGV_UNUSED_I64(o
.out2
);
5266 TCGV_UNUSED_I64(o
.in1
);
5267 TCGV_UNUSED_I64(o
.in2
);
5268 TCGV_UNUSED_I64(o
.addr1
);
5270 /* Implement the instruction. */
5271 if (insn
->help_in1
) {
5272 insn
->help_in1(s
, &f
, &o
);
5274 if (insn
->help_in2
) {
5275 insn
->help_in2(s
, &f
, &o
);
5277 if (insn
->help_prep
) {
5278 insn
->help_prep(s
, &f
, &o
);
5280 if (insn
->help_op
) {
5281 ret
= insn
->help_op(s
, &o
);
5283 if (insn
->help_wout
) {
5284 insn
->help_wout(s
, &f
, &o
);
5286 if (insn
->help_cout
) {
5287 insn
->help_cout(s
, &o
);
5290 /* Free any temporaries created by the helpers. */
5291 if (!TCGV_IS_UNUSED_I64(o
.out
) && !o
.g_out
) {
5292 tcg_temp_free_i64(o
.out
);
5294 if (!TCGV_IS_UNUSED_I64(o
.out2
) && !o
.g_out2
) {
5295 tcg_temp_free_i64(o
.out2
);
5297 if (!TCGV_IS_UNUSED_I64(o
.in1
) && !o
.g_in1
) {
5298 tcg_temp_free_i64(o
.in1
);
5300 if (!TCGV_IS_UNUSED_I64(o
.in2
) && !o
.g_in2
) {
5301 tcg_temp_free_i64(o
.in2
);
5303 if (!TCGV_IS_UNUSED_I64(o
.addr1
)) {
5304 tcg_temp_free_i64(o
.addr1
);
5307 #ifndef CONFIG_USER_ONLY
5308 if (s
->tb
->flags
& FLAG_MASK_PER
) {
5309 /* An exception might be triggered, save PSW if not already done. */
5310 if (ret
== NO_EXIT
|| ret
== EXIT_PC_STALE
) {
5311 tcg_gen_movi_i64(psw_addr
, s
->next_pc
);
5317 /* Call the helper to check for a possible PER exception. */
5318 gen_helper_per_check_exception(cpu_env
);
5322 /* Advance to the next instruction. */
5327 void gen_intermediate_code(CPUS390XState
*env
, struct TranslationBlock
*tb
)
5329 S390CPU
*cpu
= s390_env_get_cpu(env
);
5330 CPUState
*cs
= CPU(cpu
);
5332 target_ulong pc_start
;
5333 uint64_t next_page_start
;
5334 int num_insns
, max_insns
;
5341 if (!(tb
->flags
& FLAG_MASK_64
)) {
5342 pc_start
&= 0x7fffffff;
5347 dc
.cc_op
= CC_OP_DYNAMIC
;
5348 do_debug
= dc
.singlestep_enabled
= cs
->singlestep_enabled
;
5350 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
5353 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
5354 if (max_insns
== 0) {
5355 max_insns
= CF_COUNT_MASK
;
5357 if (max_insns
> TCG_MAX_INSNS
) {
5358 max_insns
= TCG_MAX_INSNS
;
5364 tcg_gen_insn_start(dc
.pc
, dc
.cc_op
);
5367 if (unlikely(cpu_breakpoint_test(cs
, dc
.pc
, BP_ANY
))) {
5368 status
= EXIT_PC_STALE
;
5370 /* The address covered by the breakpoint must be included in
5371 [tb->pc, tb->pc + tb->size) in order to for it to be
5372 properly cleared -- thus we increment the PC here so that
5373 the logic setting tb->size below does the right thing. */
5378 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
5383 if (status
== NO_EXIT
) {
5384 status
= translate_one(env
, &dc
);
5387 /* If we reach a page boundary, are single stepping,
5388 or exhaust instruction count, stop generation. */
5389 if (status
== NO_EXIT
5390 && (dc
.pc
>= next_page_start
5391 || tcg_op_buf_full()
5392 || num_insns
>= max_insns
5394 || cs
->singlestep_enabled
)) {
5395 status
= EXIT_PC_STALE
;
5397 } while (status
== NO_EXIT
);
5399 if (tb
->cflags
& CF_LAST_IO
) {
5408 update_psw_addr(&dc
);
5410 case EXIT_PC_UPDATED
:
5411 /* Next TB starts off with CC_OP_DYNAMIC, so make sure the
5412 cc op type is in env */
5414 /* Exit the TB, either by raising a debug exception or by return. */
5416 gen_exception(EXCP_DEBUG
);
5425 gen_tb_end(tb
, num_insns
);
5427 tb
->size
= dc
.pc
- pc_start
;
5428 tb
->icount
= num_insns
;
5430 #if defined(S390X_DEBUG_DISAS)
5431 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
5432 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
5433 log_target_disas(cs
, pc_start
, dc
.pc
- pc_start
, 1);
5439 void restore_state_to_opc(CPUS390XState
*env
, TranslationBlock
*tb
,
5442 int cc_op
= data
[1];
5443 env
->psw
.addr
= data
[0];
5444 if ((cc_op
!= CC_OP_DYNAMIC
) && (cc_op
!= CC_OP_STATIC
)) {