aboutsummaryrefslogtreecommitdiff
path: root/target-s390x
diff options
context:
space:
mode:
Diffstat (limited to 'target-s390x')
-rw-r--r--target-s390x/translate.c318
1 files changed, 27 insertions, 291 deletions
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index b4b197bb44..3d92a56a50 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -79,12 +79,7 @@ static uint64_t inline_branch_hit[CC_OP_MAX];
static uint64_t inline_branch_miss[CC_OP_MAX];
#endif
-static inline void debug_insn(uint64_t insn)
-{
- LOG_DISAS("insn: 0x%" PRIx64 "\n", insn);
-}
-
-static inline uint64_t pc_to_link_info(DisasContext *s, uint64_t pc)
+static uint64_t pc_to_link_info(DisasContext *s, uint64_t pc)
{
if (!(s->tb->flags & FLAG_MASK_64)) {
if (s->tb->flags & FLAG_MASK_32) {
@@ -200,112 +195,58 @@ void s390x_translate_init(void)
#include "helper.h"
}
-static inline TCGv_i64 load_reg(int reg)
+static TCGv_i64 load_reg(int reg)
{
TCGv_i64 r = tcg_temp_new_i64();
tcg_gen_mov_i64(r, regs[reg]);
return r;
}
-static inline TCGv_i64 load_freg(int reg)
-{
- TCGv_i64 r = tcg_temp_new_i64();
- tcg_gen_mov_i64(r, fregs[reg]);
- return r;
-}
-
-static inline TCGv_i32 load_freg32(int reg)
-{
- TCGv_i32 r = tcg_temp_new_i32();
-#if HOST_LONG_BITS == 32
- tcg_gen_mov_i32(r, TCGV_HIGH(fregs[reg]));
-#else
- tcg_gen_shri_i64(MAKE_TCGV_I64(GET_TCGV_I32(r)), fregs[reg], 32);
-#endif
- return r;
-}
-
-static inline TCGv_i64 load_freg32_i64(int reg)
+static TCGv_i64 load_freg32_i64(int reg)
{
TCGv_i64 r = tcg_temp_new_i64();
tcg_gen_shri_i64(r, fregs[reg], 32);
return r;
}
-static inline TCGv_i32 load_reg32(int reg)
-{
- TCGv_i32 r = tcg_temp_new_i32();
- tcg_gen_trunc_i64_i32(r, regs[reg]);
- return r;
-}
-
-static inline TCGv_i64 load_reg32_i64(int reg)
-{
- TCGv_i64 r = tcg_temp_new_i64();
- tcg_gen_ext32s_i64(r, regs[reg]);
- return r;
-}
-
-static inline void store_reg(int reg, TCGv_i64 v)
+static void store_reg(int reg, TCGv_i64 v)
{
tcg_gen_mov_i64(regs[reg], v);
}
-static inline void store_freg(int reg, TCGv_i64 v)
+static void store_freg(int reg, TCGv_i64 v)
{
tcg_gen_mov_i64(fregs[reg], v);
}
-static inline void store_reg32(int reg, TCGv_i32 v)
-{
- /* 32 bit register writes keep the upper half */
-#if HOST_LONG_BITS == 32
- tcg_gen_mov_i32(TCGV_LOW(regs[reg]), v);
-#else
- tcg_gen_deposit_i64(regs[reg], regs[reg],
- MAKE_TCGV_I64(GET_TCGV_I32(v)), 0, 32);
-#endif
-}
-
-static inline void store_reg32_i64(int reg, TCGv_i64 v)
+static void store_reg32_i64(int reg, TCGv_i64 v)
{
/* 32 bit register writes keep the upper half */
tcg_gen_deposit_i64(regs[reg], regs[reg], v, 0, 32);
}
-static inline void store_reg32h_i64(int reg, TCGv_i64 v)
+static void store_reg32h_i64(int reg, TCGv_i64 v)
{
tcg_gen_deposit_i64(regs[reg], regs[reg], v, 32, 32);
}
-static inline void store_freg32(int reg, TCGv_i32 v)
-{
- /* 32 bit register writes keep the lower half */
-#if HOST_LONG_BITS == 32
- tcg_gen_mov_i32(TCGV_HIGH(fregs[reg]), v);
-#else
- tcg_gen_deposit_i64(fregs[reg], fregs[reg],
- MAKE_TCGV_I64(GET_TCGV_I32(v)), 32, 32);
-#endif
-}
-
-static inline void store_freg32_i64(int reg, TCGv_i64 v)
+static void store_freg32_i64(int reg, TCGv_i64 v)
{
tcg_gen_deposit_i64(fregs[reg], fregs[reg], v, 32, 32);
}
-static inline void return_low128(TCGv_i64 dest)
+static void return_low128(TCGv_i64 dest)
{
tcg_gen_ld_i64(dest, cpu_env, offsetof(CPUS390XState, retxl));
}
-static inline void update_psw_addr(DisasContext *s)
+static void update_psw_addr(DisasContext *s)
{
/* psw.addr */
tcg_gen_movi_i64(psw_addr, s->pc);
}
-static inline void potential_page_fault(DisasContext *s)
+static void potential_page_fault(DisasContext *s)
{
#ifndef CONFIG_USER_ONLY
update_psw_addr(s);
@@ -328,7 +269,7 @@ static inline uint64_t ld_code6(CPUS390XState *env, uint64_t pc)
return (ld_code2(env, pc) << 32) | ld_code4(env, pc + 2);
}
-static inline int get_mem_index(DisasContext *s)
+static int get_mem_index(DisasContext *s)
{
switch (s->tb->flags & FLAG_MASK_ASC) {
case PSW_ASC_PRIMARY >> 32:
@@ -440,14 +381,6 @@ static void gen_op_update1_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 dst)
s->cc_op = op;
}
-static void gen_op_update1_cc_i32(DisasContext *s, enum cc_op op, TCGv_i32 dst)
-{
- tcg_gen_discard_i64(cc_src);
- tcg_gen_extu_i32_i64(cc_dst, dst);
- tcg_gen_discard_i64(cc_vr);
- s->cc_op = op;
-}
-
static void gen_op_update2_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src,
TCGv_i64 dst)
{
@@ -457,15 +390,6 @@ static void gen_op_update2_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src,
s->cc_op = op;
}
-static void gen_op_update2_cc_i32(DisasContext *s, enum cc_op op, TCGv_i32 src,
- TCGv_i32 dst)
-{
- tcg_gen_extu_i32_i64(cc_src, src);
- tcg_gen_extu_i32_i64(cc_dst, dst);
- tcg_gen_discard_i64(cc_vr);
- s->cc_op = op;
-}
-
static void gen_op_update3_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src,
TCGv_i64 dst, TCGv_i64 vr)
{
@@ -475,104 +399,28 @@ static void gen_op_update3_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src,
s->cc_op = op;
}
-static inline void set_cc_nz_u32(DisasContext *s, TCGv_i32 val)
-{
- gen_op_update1_cc_i32(s, CC_OP_NZ, val);
-}
-
-static inline void set_cc_nz_u64(DisasContext *s, TCGv_i64 val)
+static void set_cc_nz_u64(DisasContext *s, TCGv_i64 val)
{
gen_op_update1_cc_i64(s, CC_OP_NZ, val);
}
-static inline void gen_set_cc_nz_f32(DisasContext *s, TCGv_i64 val)
+static void gen_set_cc_nz_f32(DisasContext *s, TCGv_i64 val)
{
gen_op_update1_cc_i64(s, CC_OP_NZ_F32, val);
}
-static inline void gen_set_cc_nz_f64(DisasContext *s, TCGv_i64 val)
+static void gen_set_cc_nz_f64(DisasContext *s, TCGv_i64 val)
{
gen_op_update1_cc_i64(s, CC_OP_NZ_F64, val);
}
-static inline void gen_set_cc_nz_f128(DisasContext *s, TCGv_i64 vh, TCGv_i64 vl)
+static void gen_set_cc_nz_f128(DisasContext *s, TCGv_i64 vh, TCGv_i64 vl)
{
gen_op_update2_cc_i64(s, CC_OP_NZ_F128, vh, vl);
}
-static inline void cmp_32(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2,
- enum cc_op cond)
-{
- gen_op_update2_cc_i32(s, cond, v1, v2);
-}
-
-static inline void cmp_64(DisasContext *s, TCGv_i64 v1, TCGv_i64 v2,
- enum cc_op cond)
-{
- gen_op_update2_cc_i64(s, cond, v1, v2);
-}
-
-static inline void cmp_s32(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2)
-{
- cmp_32(s, v1, v2, CC_OP_LTGT_32);
-}
-
-static inline void cmp_u32(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2)
-{
- cmp_32(s, v1, v2, CC_OP_LTUGTU_32);
-}
-
-static inline void cmp_s32c(DisasContext *s, TCGv_i32 v1, int32_t v2)
-{
- /* XXX optimize for the constant? put it in s? */
- TCGv_i32 tmp = tcg_const_i32(v2);
- cmp_32(s, v1, tmp, CC_OP_LTGT_32);
- tcg_temp_free_i32(tmp);
-}
-
-static inline void cmp_u32c(DisasContext *s, TCGv_i32 v1, uint32_t v2)
-{
- TCGv_i32 tmp = tcg_const_i32(v2);
- cmp_32(s, v1, tmp, CC_OP_LTUGTU_32);
- tcg_temp_free_i32(tmp);
-}
-
-static inline void cmp_s64(DisasContext *s, TCGv_i64 v1, TCGv_i64 v2)
-{
- cmp_64(s, v1, v2, CC_OP_LTGT_64);
-}
-
-static inline void cmp_u64(DisasContext *s, TCGv_i64 v1, TCGv_i64 v2)
-{
- cmp_64(s, v1, v2, CC_OP_LTUGTU_64);
-}
-
-static inline void cmp_s64c(DisasContext *s, TCGv_i64 v1, int64_t v2)
-{
- TCGv_i64 tmp = tcg_const_i64(v2);
- cmp_s64(s, v1, tmp);
- tcg_temp_free_i64(tmp);
-}
-
-static inline void cmp_u64c(DisasContext *s, TCGv_i64 v1, uint64_t v2)
-{
- TCGv_i64 tmp = tcg_const_i64(v2);
- cmp_u64(s, v1, tmp);
- tcg_temp_free_i64(tmp);
-}
-
-static inline void set_cc_s32(DisasContext *s, TCGv_i32 val)
-{
- gen_op_update1_cc_i32(s, CC_OP_LTGT0_32, val);
-}
-
-static inline void set_cc_s64(DisasContext *s, TCGv_i64 val)
-{
- gen_op_update1_cc_i64(s, CC_OP_LTGT0_64, val);
-}
-
/* CC value is in env->cc_op */
-static inline void set_cc_static(DisasContext *s)
+static void set_cc_static(DisasContext *s)
{
tcg_gen_discard_i64(cc_src);
tcg_gen_discard_i64(cc_dst);
@@ -580,14 +428,14 @@ static inline void set_cc_static(DisasContext *s)
s->cc_op = CC_OP_STATIC;
}
-static inline void gen_op_set_cc_op(DisasContext *s)
+static void gen_op_set_cc_op(DisasContext *s)
{
if (s->cc_op != CC_OP_DYNAMIC && s->cc_op != CC_OP_STATIC) {
tcg_gen_movi_i32(cc_op, s->cc_op);
}
}
-static inline void gen_update_cc_op(DisasContext *s)
+static void gen_update_cc_op(DisasContext *s)
{
gen_op_set_cc_op(s);
}
@@ -667,51 +515,6 @@ static void gen_op_calc_cc(DisasContext *s)
set_cc_static(s);
}
-static inline void decode_rr(DisasContext *s, uint64_t insn, int *r1, int *r2)
-{
- debug_insn(insn);
-
- *r1 = (insn >> 4) & 0xf;
- *r2 = insn & 0xf;
-}
-
-static inline TCGv_i64 decode_rx(DisasContext *s, uint64_t insn, int *r1,
- int *x2, int *b2, int *d2)
-{
- debug_insn(insn);
-
- *r1 = (insn >> 20) & 0xf;
- *x2 = (insn >> 16) & 0xf;
- *b2 = (insn >> 12) & 0xf;
- *d2 = insn & 0xfff;
-
- return get_address(s, *x2, *b2, *d2);
-}
-
-static inline void decode_rs(DisasContext *s, uint64_t insn, int *r1, int *r3,
- int *b2, int *d2)
-{
- debug_insn(insn);
-
- *r1 = (insn >> 20) & 0xf;
- /* aka m3 */
- *r3 = (insn >> 16) & 0xf;
- *b2 = (insn >> 12) & 0xf;
- *d2 = insn & 0xfff;
-}
-
-static inline TCGv_i64 decode_si(DisasContext *s, uint64_t insn, int *i2,
- int *b1, int *d1)
-{
- debug_insn(insn);
-
- *i2 = (insn >> 16) & 0xff;
- *b1 = (insn >> 12) & 0xf;
- *d1 = insn & 0xfff;
-
- return get_address(s, 0, *b1, *d1);
-}
-
static int use_goto_tb(DisasContext *s, uint64_t dest)
{
/* NOTE: we handle the case where the TB spans two pages here */
@@ -721,29 +524,14 @@ static int use_goto_tb(DisasContext *s, uint64_t dest)
&& !(s->tb->cflags & CF_LAST_IO));
}
-static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong pc)
-{
- gen_update_cc_op(s);
-
- if (use_goto_tb(s, pc)) {
- tcg_gen_goto_tb(tb_num);
- tcg_gen_movi_i64(psw_addr, pc);
- tcg_gen_exit_tb((tcg_target_long)s->tb + tb_num);
- } else {
- /* jump to another page: currently not optimized */
- tcg_gen_movi_i64(psw_addr, pc);
- tcg_gen_exit_tb(0);
- }
-}
-
-static inline void account_noninline_branch(DisasContext *s, int cc_op)
+static void account_noninline_branch(DisasContext *s, int cc_op)
{
#ifdef DEBUG_INLINE_BRANCHES
inline_branch_miss[cc_op]++;
#endif
}
-static inline void account_inline_branch(DisasContext *s, int cc_op)
+static void account_inline_branch(DisasContext *s, int cc_op)
{
#ifdef DEBUG_INLINE_BRANCHES
inline_branch_hit[cc_op]++;
@@ -1018,43 +806,6 @@ static void free_compare(DisasCompare *c)
}
}
-static void disas_b2(CPUS390XState *env, DisasContext *s, int op,
- uint32_t insn)
-{
-#ifndef CONFIG_USER_ONLY
- switch (op) {
- default:
-#endif
- LOG_DISAS("illegal b2 operation 0x%x\n", op);
- gen_illegal_opcode(s);
-#ifndef CONFIG_USER_ONLY
- break;
- }
-#endif
-}
-
-static void disas_s390_insn(CPUS390XState *env, DisasContext *s)
-{
- unsigned char opc;
- uint64_t insn;
- int op;
-
- opc = cpu_ldub_code(env, s->pc);
- LOG_DISAS("opc 0x%x\n", opc);
-
- switch (opc) {
- case 0xb2:
- insn = ld_code4(env, s->pc);
- op = (insn >> 16) & 0xff;
- disas_b2(env, s, op, insn);
- break;
- default:
- qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%x\n", opc);
- gen_illegal_opcode(s);
- break;
- }
-}
-
/* ====================================================================== */
/* Define the insn format enumeration. */
#define F0(N) FMT_##N,
@@ -4108,30 +3859,15 @@ static ExitStatus translate_one(CPUS390XState *env, DisasContext *s)
DisasFields f;
DisasOps o;
+ /* Search for the insn in the table. */
insn = extract_insn(env, s, &f);
- /* If not found, try the old interpreter. This includes ILLOPC. */
+ /* Not found means unimplemented/illegal opcode. */
if (insn == NULL) {
- disas_s390_insn(env, s);
- switch (s->is_jmp) {
- case DISAS_NEXT:
- ret = NO_EXIT;
- break;
- case DISAS_TB_JUMP:
- ret = EXIT_GOTO_TB;
- break;
- case DISAS_JUMP:
- ret = EXIT_PC_UPDATED;
- break;
- case DISAS_EXCP:
- ret = EXIT_NORETURN;
- break;
- default:
- abort();
- }
-
- s->pc = s->next_pc;
- return ret;
+ qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%02x%02x\n",
+ f.op, f.op2);
+ gen_illegal_opcode(s);
+ return EXIT_NORETURN;
}
/* Set up the strutures we use to communicate with the helpers. */