target/s390x: convert to DisasContextBase
Notes:
- Did not convert {num,max}_insns and is_jmp, since the corresponding
  code will go away in the next patch.
- Avoided a checkpatch error in use_exit_tb.
- As suggested by David, (1) Drop ctx.pc and use
  ctx.base.pc_next instead, and (2) Rename ctx.next_pc to
  ctx.pc_tmp and add a comment about it.
Acked-by: Cornelia Huck <cohuck@redhat.com>
Suggested-by: David Hildenbrand <david@redhat.com>
Reviewed-by:  David Hildenbrand <david@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Cc: David Hildenbrand <david@redhat.com>
Cc: Cornelia Huck <cohuck@redhat.com>
Cc: Alexander Graf <agraf@suse.de>
Cc: qemu-s390x@nongnu.org
Signed-off-by: Emilio G. Cota <cota@braap.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
			
			
This commit is contained in:
		
							parent
							
								
									21a8eced9b
								
							
						
					
					
						commit
						eccf741ab8
					
				@ -52,14 +52,18 @@ typedef struct DisasInsn DisasInsn;
 | 
				
			|||||||
typedef struct DisasFields DisasFields;
 | 
					typedef struct DisasFields DisasFields;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct DisasContext {
 | 
					struct DisasContext {
 | 
				
			||||||
    struct TranslationBlock *tb;
 | 
					    DisasContextBase base;
 | 
				
			||||||
    const DisasInsn *insn;
 | 
					    const DisasInsn *insn;
 | 
				
			||||||
    DisasFields *fields;
 | 
					    DisasFields *fields;
 | 
				
			||||||
    uint64_t ex_value;
 | 
					    uint64_t ex_value;
 | 
				
			||||||
    uint64_t pc, next_pc;
 | 
					    /*
 | 
				
			||||||
 | 
					     * During translate_one(), pc_tmp is used to determine the instruction
 | 
				
			||||||
 | 
					     * to be executed after base.pc_next - e.g. next sequential instruction
 | 
				
			||||||
 | 
					     * or a branch target.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    uint64_t pc_tmp;
 | 
				
			||||||
    uint32_t ilen;
 | 
					    uint32_t ilen;
 | 
				
			||||||
    enum cc_op cc_op;
 | 
					    enum cc_op cc_op;
 | 
				
			||||||
    bool singlestep_enabled;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Information carried about a condition to be evaluated.  */
 | 
					/* Information carried about a condition to be evaluated.  */
 | 
				
			||||||
@ -81,8 +85,8 @@ static uint64_t inline_branch_miss[CC_OP_MAX];
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static 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->base.tb->flags & FLAG_MASK_64)) {
 | 
				
			||||||
        if (s->tb->flags & FLAG_MASK_32) {
 | 
					        if (s->base.tb->flags & FLAG_MASK_32) {
 | 
				
			||||||
            return pc | 0x80000000;
 | 
					            return pc | 0x80000000;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -188,16 +192,16 @@ static void return_low128(TCGv_i64 dest)
 | 
				
			|||||||
static void update_psw_addr(DisasContext *s)
 | 
					static void update_psw_addr(DisasContext *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* psw.addr */
 | 
					    /* psw.addr */
 | 
				
			||||||
    tcg_gen_movi_i64(psw_addr, s->pc);
 | 
					    tcg_gen_movi_i64(psw_addr, s->base.pc_next);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void per_branch(DisasContext *s, bool to_next)
 | 
					static void per_branch(DisasContext *s, bool to_next)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#ifndef CONFIG_USER_ONLY
 | 
					#ifndef CONFIG_USER_ONLY
 | 
				
			||||||
    tcg_gen_movi_i64(gbea, s->pc);
 | 
					    tcg_gen_movi_i64(gbea, s->base.pc_next);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (s->tb->flags & FLAG_MASK_PER) {
 | 
					    if (s->base.tb->flags & FLAG_MASK_PER) {
 | 
				
			||||||
        TCGv_i64 next_pc = to_next ? tcg_const_i64(s->next_pc) : psw_addr;
 | 
					        TCGv_i64 next_pc = to_next ? tcg_const_i64(s->pc_tmp) : psw_addr;
 | 
				
			||||||
        gen_helper_per_branch(cpu_env, gbea, next_pc);
 | 
					        gen_helper_per_branch(cpu_env, gbea, next_pc);
 | 
				
			||||||
        if (to_next) {
 | 
					        if (to_next) {
 | 
				
			||||||
            tcg_temp_free_i64(next_pc);
 | 
					            tcg_temp_free_i64(next_pc);
 | 
				
			||||||
@ -210,16 +214,16 @@ static void per_branch_cond(DisasContext *s, TCGCond cond,
 | 
				
			|||||||
                            TCGv_i64 arg1, TCGv_i64 arg2)
 | 
					                            TCGv_i64 arg1, TCGv_i64 arg2)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#ifndef CONFIG_USER_ONLY
 | 
					#ifndef CONFIG_USER_ONLY
 | 
				
			||||||
    if (s->tb->flags & FLAG_MASK_PER) {
 | 
					    if (s->base.tb->flags & FLAG_MASK_PER) {
 | 
				
			||||||
        TCGLabel *lab = gen_new_label();
 | 
					        TCGLabel *lab = gen_new_label();
 | 
				
			||||||
        tcg_gen_brcond_i64(tcg_invert_cond(cond), arg1, arg2, lab);
 | 
					        tcg_gen_brcond_i64(tcg_invert_cond(cond), arg1, arg2, lab);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        tcg_gen_movi_i64(gbea, s->pc);
 | 
					        tcg_gen_movi_i64(gbea, s->base.pc_next);
 | 
				
			||||||
        gen_helper_per_branch(cpu_env, gbea, psw_addr);
 | 
					        gen_helper_per_branch(cpu_env, gbea, psw_addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        gen_set_label(lab);
 | 
					        gen_set_label(lab);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        TCGv_i64 pc = tcg_const_i64(s->pc);
 | 
					        TCGv_i64 pc = tcg_const_i64(s->base.pc_next);
 | 
				
			||||||
        tcg_gen_movcond_i64(cond, gbea, arg1, arg2, gbea, pc);
 | 
					        tcg_gen_movcond_i64(cond, gbea, arg1, arg2, gbea, pc);
 | 
				
			||||||
        tcg_temp_free_i64(pc);
 | 
					        tcg_temp_free_i64(pc);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -228,7 +232,7 @@ static void per_branch_cond(DisasContext *s, TCGCond cond,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static void per_breaking_event(DisasContext *s)
 | 
					static void per_breaking_event(DisasContext *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    tcg_gen_movi_i64(gbea, s->pc);
 | 
					    tcg_gen_movi_i64(gbea, s->base.pc_next);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void update_cc_op(DisasContext *s)
 | 
					static void update_cc_op(DisasContext *s)
 | 
				
			||||||
@ -250,11 +254,11 @@ static inline uint64_t ld_code4(CPUS390XState *env, uint64_t pc)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static int get_mem_index(DisasContext *s)
 | 
					static int get_mem_index(DisasContext *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (!(s->tb->flags & FLAG_MASK_DAT)) {
 | 
					    if (!(s->base.tb->flags & FLAG_MASK_DAT)) {
 | 
				
			||||||
        return MMU_REAL_IDX;
 | 
					        return MMU_REAL_IDX;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (s->tb->flags & FLAG_MASK_ASC) {
 | 
					    switch (s->base.tb->flags & FLAG_MASK_ASC) {
 | 
				
			||||||
    case PSW_ASC_PRIMARY >> FLAG_MASK_PSW_SHIFT:
 | 
					    case PSW_ASC_PRIMARY >> FLAG_MASK_PSW_SHIFT:
 | 
				
			||||||
        return MMU_PRIMARY_IDX;
 | 
					        return MMU_PRIMARY_IDX;
 | 
				
			||||||
    case PSW_ASC_SECONDARY >> FLAG_MASK_PSW_SHIFT:
 | 
					    case PSW_ASC_SECONDARY >> FLAG_MASK_PSW_SHIFT:
 | 
				
			||||||
@ -319,7 +323,7 @@ static inline void gen_trap(DisasContext *s)
 | 
				
			|||||||
#ifndef CONFIG_USER_ONLY
 | 
					#ifndef CONFIG_USER_ONLY
 | 
				
			||||||
static void check_privileged(DisasContext *s)
 | 
					static void check_privileged(DisasContext *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (s->tb->flags & FLAG_MASK_PSTATE) {
 | 
					    if (s->base.tb->flags & FLAG_MASK_PSTATE) {
 | 
				
			||||||
        gen_program_exception(s, PGM_PRIVILEGED);
 | 
					        gen_program_exception(s, PGM_PRIVILEGED);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -328,7 +332,7 @@ static void check_privileged(DisasContext *s)
 | 
				
			|||||||
static TCGv_i64 get_address(DisasContext *s, int x2, int b2, int d2)
 | 
					static TCGv_i64 get_address(DisasContext *s, int x2, int b2, int d2)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    TCGv_i64 tmp = tcg_temp_new_i64();
 | 
					    TCGv_i64 tmp = tcg_temp_new_i64();
 | 
				
			||||||
    bool need_31 = !(s->tb->flags & FLAG_MASK_64);
 | 
					    bool need_31 = !(s->base.tb->flags & FLAG_MASK_64);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Note that d2 is limited to 20 bits, signed.  If we crop negative
 | 
					    /* Note that d2 is limited to 20 bits, signed.  If we crop negative
 | 
				
			||||||
       displacements early we create larger immedate addends.  */
 | 
					       displacements early we create larger immedate addends.  */
 | 
				
			||||||
@ -541,9 +545,9 @@ static void gen_op_calc_cc(DisasContext *s)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static bool use_exit_tb(DisasContext *s)
 | 
					static bool use_exit_tb(DisasContext *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return (s->singlestep_enabled ||
 | 
					    return s->base.singlestep_enabled ||
 | 
				
			||||||
            (tb_cflags(s->tb) & CF_LAST_IO) ||
 | 
					            (tb_cflags(s->base.tb) & CF_LAST_IO) ||
 | 
				
			||||||
            (s->tb->flags & FLAG_MASK_PER));
 | 
					            (s->base.tb->flags & FLAG_MASK_PER);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool use_goto_tb(DisasContext *s, uint64_t dest)
 | 
					static bool use_goto_tb(DisasContext *s, uint64_t dest)
 | 
				
			||||||
@ -552,8 +556,8 @@ static bool use_goto_tb(DisasContext *s, uint64_t dest)
 | 
				
			|||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#ifndef CONFIG_USER_ONLY
 | 
					#ifndef CONFIG_USER_ONLY
 | 
				
			||||||
    return (dest & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK) ||
 | 
					    return (dest & TARGET_PAGE_MASK) == (s->base.tb->pc & TARGET_PAGE_MASK) ||
 | 
				
			||||||
           (dest & TARGET_PAGE_MASK) == (s->pc & TARGET_PAGE_MASK);
 | 
					           (dest & TARGET_PAGE_MASK) == (s->base.pc_next & TARGET_PAGE_MASK);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -1145,7 +1149,7 @@ static void help_l2_shift(DisasContext *s, DisasFields *f,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static DisasJumpType help_goto_direct(DisasContext *s, uint64_t dest)
 | 
					static DisasJumpType help_goto_direct(DisasContext *s, uint64_t dest)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (dest == s->next_pc) {
 | 
					    if (dest == s->pc_tmp) {
 | 
				
			||||||
        per_branch(s, true);
 | 
					        per_branch(s, true);
 | 
				
			||||||
        return DISAS_NEXT;
 | 
					        return DISAS_NEXT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -1154,7 +1158,7 @@ static DisasJumpType help_goto_direct(DisasContext *s, uint64_t dest)
 | 
				
			|||||||
        per_breaking_event(s);
 | 
					        per_breaking_event(s);
 | 
				
			||||||
        tcg_gen_goto_tb(0);
 | 
					        tcg_gen_goto_tb(0);
 | 
				
			||||||
        tcg_gen_movi_i64(psw_addr, dest);
 | 
					        tcg_gen_movi_i64(psw_addr, dest);
 | 
				
			||||||
        tcg_gen_exit_tb((uintptr_t)s->tb);
 | 
					        tcg_gen_exit_tb((uintptr_t)s->base.tb);
 | 
				
			||||||
        return DISAS_GOTO_TB;
 | 
					        return DISAS_GOTO_TB;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        tcg_gen_movi_i64(psw_addr, dest);
 | 
					        tcg_gen_movi_i64(psw_addr, dest);
 | 
				
			||||||
@ -1167,7 +1171,7 @@ static DisasJumpType help_branch(DisasContext *s, DisasCompare *c,
 | 
				
			|||||||
                                 bool is_imm, int imm, TCGv_i64 cdest)
 | 
					                                 bool is_imm, int imm, TCGv_i64 cdest)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    DisasJumpType ret;
 | 
					    DisasJumpType ret;
 | 
				
			||||||
    uint64_t dest = s->pc + 2 * imm;
 | 
					    uint64_t dest = s->base.pc_next + 2 * imm;
 | 
				
			||||||
    TCGLabel *lab;
 | 
					    TCGLabel *lab;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Take care of the special cases first.  */
 | 
					    /* Take care of the special cases first.  */
 | 
				
			||||||
@ -1176,7 +1180,7 @@ static DisasJumpType help_branch(DisasContext *s, DisasCompare *c,
 | 
				
			|||||||
        goto egress;
 | 
					        goto egress;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (is_imm) {
 | 
					    if (is_imm) {
 | 
				
			||||||
        if (dest == s->next_pc) {
 | 
					        if (dest == s->pc_tmp) {
 | 
				
			||||||
            /* Branch to next.  */
 | 
					            /* Branch to next.  */
 | 
				
			||||||
            per_branch(s, true);
 | 
					            per_branch(s, true);
 | 
				
			||||||
            ret = DISAS_NEXT;
 | 
					            ret = DISAS_NEXT;
 | 
				
			||||||
@ -1200,7 +1204,7 @@ static DisasJumpType help_branch(DisasContext *s, DisasCompare *c,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (use_goto_tb(s, s->next_pc)) {
 | 
					    if (use_goto_tb(s, s->pc_tmp)) {
 | 
				
			||||||
        if (is_imm && use_goto_tb(s, dest)) {
 | 
					        if (is_imm && use_goto_tb(s, dest)) {
 | 
				
			||||||
            /* Both exits can use goto_tb.  */
 | 
					            /* Both exits can use goto_tb.  */
 | 
				
			||||||
            update_cc_op(s);
 | 
					            update_cc_op(s);
 | 
				
			||||||
@ -1214,15 +1218,15 @@ static DisasJumpType help_branch(DisasContext *s, DisasCompare *c,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            /* Branch not taken.  */
 | 
					            /* Branch not taken.  */
 | 
				
			||||||
            tcg_gen_goto_tb(0);
 | 
					            tcg_gen_goto_tb(0);
 | 
				
			||||||
            tcg_gen_movi_i64(psw_addr, s->next_pc);
 | 
					            tcg_gen_movi_i64(psw_addr, s->pc_tmp);
 | 
				
			||||||
            tcg_gen_exit_tb((uintptr_t)s->tb + 0);
 | 
					            tcg_gen_exit_tb((uintptr_t)s->base.tb + 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* Branch taken.  */
 | 
					            /* Branch taken.  */
 | 
				
			||||||
            gen_set_label(lab);
 | 
					            gen_set_label(lab);
 | 
				
			||||||
            per_breaking_event(s);
 | 
					            per_breaking_event(s);
 | 
				
			||||||
            tcg_gen_goto_tb(1);
 | 
					            tcg_gen_goto_tb(1);
 | 
				
			||||||
            tcg_gen_movi_i64(psw_addr, dest);
 | 
					            tcg_gen_movi_i64(psw_addr, dest);
 | 
				
			||||||
            tcg_gen_exit_tb((uintptr_t)s->tb + 1);
 | 
					            tcg_gen_exit_tb((uintptr_t)s->base.tb + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ret = DISAS_GOTO_TB;
 | 
					            ret = DISAS_GOTO_TB;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
@ -1244,8 +1248,8 @@ static DisasJumpType help_branch(DisasContext *s, DisasCompare *c,
 | 
				
			|||||||
            /* Branch not taken.  */
 | 
					            /* Branch not taken.  */
 | 
				
			||||||
            update_cc_op(s);
 | 
					            update_cc_op(s);
 | 
				
			||||||
            tcg_gen_goto_tb(0);
 | 
					            tcg_gen_goto_tb(0);
 | 
				
			||||||
            tcg_gen_movi_i64(psw_addr, s->next_pc);
 | 
					            tcg_gen_movi_i64(psw_addr, s->pc_tmp);
 | 
				
			||||||
            tcg_gen_exit_tb((uintptr_t)s->tb + 0);
 | 
					            tcg_gen_exit_tb((uintptr_t)s->base.tb + 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            gen_set_label(lab);
 | 
					            gen_set_label(lab);
 | 
				
			||||||
            if (is_imm) {
 | 
					            if (is_imm) {
 | 
				
			||||||
@ -1259,7 +1263,7 @@ static DisasJumpType help_branch(DisasContext *s, DisasCompare *c,
 | 
				
			|||||||
           Most commonly we're single-stepping or some other condition that
 | 
					           Most commonly we're single-stepping or some other condition that
 | 
				
			||||||
           disables all use of goto_tb.  Just update the PC and exit.  */
 | 
					           disables all use of goto_tb.  Just update the PC and exit.  */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        TCGv_i64 next = tcg_const_i64(s->next_pc);
 | 
					        TCGv_i64 next = tcg_const_i64(s->pc_tmp);
 | 
				
			||||||
        if (is_imm) {
 | 
					        if (is_imm) {
 | 
				
			||||||
            cdest = tcg_const_i64(dest);
 | 
					            cdest = tcg_const_i64(dest);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -1448,7 +1452,7 @@ static DisasJumpType op_ni(DisasContext *s, DisasOps *o)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static DisasJumpType op_bas(DisasContext *s, DisasOps *o)
 | 
					static DisasJumpType op_bas(DisasContext *s, DisasOps *o)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    tcg_gen_movi_i64(o->out, pc_to_link_info(s, s->next_pc));
 | 
					    tcg_gen_movi_i64(o->out, pc_to_link_info(s, s->pc_tmp));
 | 
				
			||||||
    if (o->in2) {
 | 
					    if (o->in2) {
 | 
				
			||||||
        tcg_gen_mov_i64(psw_addr, o->in2);
 | 
					        tcg_gen_mov_i64(psw_addr, o->in2);
 | 
				
			||||||
        per_branch(s, false);
 | 
					        per_branch(s, false);
 | 
				
			||||||
@ -1460,8 +1464,8 @@ static DisasJumpType op_bas(DisasContext *s, DisasOps *o)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static DisasJumpType op_basi(DisasContext *s, DisasOps *o)
 | 
					static DisasJumpType op_basi(DisasContext *s, DisasOps *o)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    tcg_gen_movi_i64(o->out, pc_to_link_info(s, s->next_pc));
 | 
					    tcg_gen_movi_i64(o->out, pc_to_link_info(s, s->pc_tmp));
 | 
				
			||||||
    return help_goto_direct(s, s->pc + 2 * get_field(s->fields, i2));
 | 
					    return help_goto_direct(s, s->base.pc_next + 2 * get_field(s->fields, i2));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static DisasJumpType op_bc(DisasContext *s, DisasOps *o)
 | 
					static DisasJumpType op_bc(DisasContext *s, DisasOps *o)
 | 
				
			||||||
@ -1994,7 +1998,7 @@ static DisasJumpType op_cdsg(DisasContext *s, DisasOps *o)
 | 
				
			|||||||
    addr = get_address(s, 0, b2, d2);
 | 
					    addr = get_address(s, 0, b2, d2);
 | 
				
			||||||
    t_r1 = tcg_const_i32(r1);
 | 
					    t_r1 = tcg_const_i32(r1);
 | 
				
			||||||
    t_r3 = tcg_const_i32(r3);
 | 
					    t_r3 = tcg_const_i32(r3);
 | 
				
			||||||
    if (tb_cflags(s->tb) & CF_PARALLEL) {
 | 
					    if (tb_cflags(s->base.tb) & CF_PARALLEL) {
 | 
				
			||||||
        gen_helper_cdsg_parallel(cpu_env, addr, t_r1, t_r3);
 | 
					        gen_helper_cdsg_parallel(cpu_env, addr, t_r1, t_r3);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        gen_helper_cdsg(cpu_env, addr, t_r1, t_r3);
 | 
					        gen_helper_cdsg(cpu_env, addr, t_r1, t_r3);
 | 
				
			||||||
@ -2012,7 +2016,7 @@ static DisasJumpType op_csst(DisasContext *s, DisasOps *o)
 | 
				
			|||||||
    int r3 = get_field(s->fields, r3);
 | 
					    int r3 = get_field(s->fields, r3);
 | 
				
			||||||
    TCGv_i32 t_r3 = tcg_const_i32(r3);
 | 
					    TCGv_i32 t_r3 = tcg_const_i32(r3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (tb_cflags(s->tb) & CF_PARALLEL) {
 | 
					    if (tb_cflags(s->base.tb) & CF_PARALLEL) {
 | 
				
			||||||
        gen_helper_csst_parallel(cc_op, cpu_env, t_r3, o->in1, o->in2);
 | 
					        gen_helper_csst_parallel(cc_op, cpu_env, t_r3, o->in1, o->in2);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        gen_helper_csst(cc_op, cpu_env, t_r3, o->in1, o->in2);
 | 
					        gen_helper_csst(cc_op, cpu_env, t_r3, o->in1, o->in2);
 | 
				
			||||||
@ -2972,7 +2976,7 @@ static DisasJumpType op_lpd(DisasContext *s, DisasOps *o)
 | 
				
			|||||||
    TCGMemOp mop = s->insn->data;
 | 
					    TCGMemOp mop = s->insn->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* In a parallel context, stop the world and single step.  */
 | 
					    /* In a parallel context, stop the world and single step.  */
 | 
				
			||||||
    if (tb_cflags(s->tb) & CF_PARALLEL) {
 | 
					    if (tb_cflags(s->base.tb) & CF_PARALLEL) {
 | 
				
			||||||
        update_psw_addr(s);
 | 
					        update_psw_addr(s);
 | 
				
			||||||
        update_cc_op(s);
 | 
					        update_cc_op(s);
 | 
				
			||||||
        gen_exception(EXCP_ATOMIC);
 | 
					        gen_exception(EXCP_ATOMIC);
 | 
				
			||||||
@ -2994,7 +2998,7 @@ static DisasJumpType op_lpd(DisasContext *s, DisasOps *o)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static DisasJumpType op_lpq(DisasContext *s, DisasOps *o)
 | 
					static DisasJumpType op_lpq(DisasContext *s, DisasOps *o)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (tb_cflags(s->tb) & CF_PARALLEL) {
 | 
					    if (tb_cflags(s->base.tb) & CF_PARALLEL) {
 | 
				
			||||||
        gen_helper_lpq_parallel(o->out, cpu_env, o->in2);
 | 
					        gen_helper_lpq_parallel(o->out, cpu_env, o->in2);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        gen_helper_lpq(o->out, cpu_env, o->in2);
 | 
					        gen_helper_lpq(o->out, cpu_env, o->in2);
 | 
				
			||||||
@ -3044,7 +3048,7 @@ static DisasJumpType op_mov2e(DisasContext *s, DisasOps *o)
 | 
				
			|||||||
    o->in2 = NULL;
 | 
					    o->in2 = NULL;
 | 
				
			||||||
    o->g_in2 = false;
 | 
					    o->g_in2 = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (s->tb->flags & FLAG_MASK_ASC) {
 | 
					    switch (s->base.tb->flags & FLAG_MASK_ASC) {
 | 
				
			||||||
    case PSW_ASC_PRIMARY >> FLAG_MASK_PSW_SHIFT:
 | 
					    case PSW_ASC_PRIMARY >> FLAG_MASK_PSW_SHIFT:
 | 
				
			||||||
        tcg_gen_movi_i64(ar1, 0);
 | 
					        tcg_gen_movi_i64(ar1, 0);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
@ -3694,11 +3698,11 @@ static DisasJumpType op_sam(DisasContext *s, DisasOps *o)
 | 
				
			|||||||
    /* Bizarre but true, we check the address of the current insn for the
 | 
					    /* Bizarre but true, we check the address of the current insn for the
 | 
				
			||||||
       specification exception, not the next to be executed.  Thus the PoO
 | 
					       specification exception, not the next to be executed.  Thus the PoO
 | 
				
			||||||
       documents that Bad Things Happen two bytes before the end.  */
 | 
					       documents that Bad Things Happen two bytes before the end.  */
 | 
				
			||||||
    if (s->pc & ~mask) {
 | 
					    if (s->base.pc_next & ~mask) {
 | 
				
			||||||
        gen_program_exception(s, PGM_SPECIFICATION);
 | 
					        gen_program_exception(s, PGM_SPECIFICATION);
 | 
				
			||||||
        return DISAS_NORETURN;
 | 
					        return DISAS_NORETURN;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    s->next_pc &= mask;
 | 
					    s->pc_tmp &= mask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    tsam = tcg_const_i64(sam);
 | 
					    tsam = tcg_const_i64(sam);
 | 
				
			||||||
    tcg_gen_deposit_i64(psw_mask, psw_mask, tsam, 31, 2);
 | 
					    tcg_gen_deposit_i64(psw_mask, psw_mask, tsam, 31, 2);
 | 
				
			||||||
@ -4411,7 +4415,7 @@ static DisasJumpType op_stmh(DisasContext *s, DisasOps *o)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static DisasJumpType op_stpq(DisasContext *s, DisasOps *o)
 | 
					static DisasJumpType op_stpq(DisasContext *s, DisasOps *o)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (tb_cflags(s->tb) & CF_PARALLEL) {
 | 
					    if (tb_cflags(s->base.tb) & CF_PARALLEL) {
 | 
				
			||||||
        gen_helper_stpq_parallel(cpu_env, o->in2, o->out2, o->out);
 | 
					        gen_helper_stpq_parallel(cpu_env, o->in2, o->out2, o->out);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        gen_helper_stpq(cpu_env, o->in2, o->out2, o->out);
 | 
					        gen_helper_stpq(cpu_env, o->in2, o->out2, o->out);
 | 
				
			||||||
@ -4500,8 +4504,8 @@ static DisasJumpType op_tam(DisasContext *s, DisasOps *o)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    int cc = 0;
 | 
					    int cc = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cc |= (s->tb->flags & FLAG_MASK_64) ? 2 : 0;
 | 
					    cc |= (s->base.tb->flags & FLAG_MASK_64) ? 2 : 0;
 | 
				
			||||||
    cc |= (s->tb->flags & FLAG_MASK_32) ? 1 : 0;
 | 
					    cc |= (s->base.tb->flags & FLAG_MASK_32) ? 1 : 0;
 | 
				
			||||||
    gen_op_movi_cc(s, cc);
 | 
					    gen_op_movi_cc(s, cc);
 | 
				
			||||||
    return DISAS_NEXT;
 | 
					    return DISAS_NEXT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -5625,7 +5629,7 @@ static void in2_a2(DisasContext *s, DisasFields *f, DisasOps *o)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static void in2_ri2(DisasContext *s, DisasFields *f, DisasOps *o)
 | 
					static void in2_ri2(DisasContext *s, DisasFields *f, DisasOps *o)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    o->in2 = tcg_const_i64(s->pc + (int64_t)get_field(f, i2) * 2);
 | 
					    o->in2 = tcg_const_i64(s->base.pc_next + (int64_t)get_field(f, i2) * 2);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#define SPEC_in2_ri2 0
 | 
					#define SPEC_in2_ri2 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -5926,7 +5930,7 @@ static void extract_field(DisasFields *o, const DisasField *f, uint64_t insn)
 | 
				
			|||||||
static const DisasInsn *extract_insn(CPUS390XState *env, DisasContext *s,
 | 
					static const DisasInsn *extract_insn(CPUS390XState *env, DisasContext *s,
 | 
				
			||||||
                                     DisasFields *f)
 | 
					                                     DisasFields *f)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint64_t insn, pc = s->pc;
 | 
					    uint64_t insn, pc = s->base.pc_next;
 | 
				
			||||||
    int op, op2, ilen;
 | 
					    int op, op2, ilen;
 | 
				
			||||||
    const DisasInsn *info;
 | 
					    const DisasInsn *info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -5958,7 +5962,7 @@ static const DisasInsn *extract_insn(CPUS390XState *env, DisasContext *s,
 | 
				
			|||||||
            g_assert_not_reached();
 | 
					            g_assert_not_reached();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    s->next_pc = s->pc + ilen;
 | 
					    s->pc_tmp = s->base.pc_next + ilen;
 | 
				
			||||||
    s->ilen = ilen;
 | 
					    s->ilen = ilen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* We can't actually determine the insn format until we've looked up
 | 
					    /* We can't actually determine the insn format until we've looked up
 | 
				
			||||||
@ -6043,8 +6047,8 @@ static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef CONFIG_USER_ONLY
 | 
					#ifndef CONFIG_USER_ONLY
 | 
				
			||||||
    if (s->tb->flags & FLAG_MASK_PER) {
 | 
					    if (s->base.tb->flags & FLAG_MASK_PER) {
 | 
				
			||||||
        TCGv_i64 addr = tcg_const_i64(s->pc);
 | 
					        TCGv_i64 addr = tcg_const_i64(s->base.pc_next);
 | 
				
			||||||
        gen_helper_per_ifetch(cpu_env, addr);
 | 
					        gen_helper_per_ifetch(cpu_env, addr);
 | 
				
			||||||
        tcg_temp_free_i64(addr);
 | 
					        tcg_temp_free_i64(addr);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -6138,10 +6142,10 @@ static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef CONFIG_USER_ONLY
 | 
					#ifndef CONFIG_USER_ONLY
 | 
				
			||||||
    if (s->tb->flags & FLAG_MASK_PER) {
 | 
					    if (s->base.tb->flags & FLAG_MASK_PER) {
 | 
				
			||||||
        /* An exception might be triggered, save PSW if not already done.  */
 | 
					        /* An exception might be triggered, save PSW if not already done.  */
 | 
				
			||||||
        if (ret == DISAS_NEXT || ret == DISAS_PC_STALE) {
 | 
					        if (ret == DISAS_NEXT || ret == DISAS_PC_STALE) {
 | 
				
			||||||
            tcg_gen_movi_i64(psw_addr, s->next_pc);
 | 
					            tcg_gen_movi_i64(psw_addr, s->pc_tmp);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* Call the helper to check for a possible PER exception.  */
 | 
					        /* Call the helper to check for a possible PER exception.  */
 | 
				
			||||||
@ -6150,7 +6154,7 @@ static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s)
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Advance to the next instruction.  */
 | 
					    /* Advance to the next instruction.  */
 | 
				
			||||||
    s->pc = s->next_pc;
 | 
					    s->base.pc_next = s->pc_tmp;
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -6158,26 +6162,25 @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    CPUS390XState *env = cs->env_ptr;
 | 
					    CPUS390XState *env = cs->env_ptr;
 | 
				
			||||||
    DisasContext dc;
 | 
					    DisasContext dc;
 | 
				
			||||||
    target_ulong pc_start;
 | 
					 | 
				
			||||||
    uint64_t page_start;
 | 
					    uint64_t page_start;
 | 
				
			||||||
    int num_insns, max_insns;
 | 
					    int num_insns, max_insns;
 | 
				
			||||||
    DisasJumpType status;
 | 
					    DisasJumpType status;
 | 
				
			||||||
    bool do_debug;
 | 
					    bool do_debug;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pc_start = tb->pc;
 | 
					    dc.base.pc_first = tb->pc;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* 31-bit mode */
 | 
					    /* 31-bit mode */
 | 
				
			||||||
    if (!(tb->flags & FLAG_MASK_64)) {
 | 
					    if (!(tb->flags & FLAG_MASK_64)) {
 | 
				
			||||||
        pc_start &= 0x7fffffff;
 | 
					        dc.base.pc_first &= 0x7fffffff;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    dc.base.pc_next = dc.base.pc_first;
 | 
				
			||||||
 | 
					    dc.base.tb = tb;
 | 
				
			||||||
 | 
					    dc.base.singlestep_enabled = cs->singlestep_enabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dc.tb = tb;
 | 
					 | 
				
			||||||
    dc.pc = pc_start;
 | 
					 | 
				
			||||||
    dc.cc_op = CC_OP_DYNAMIC;
 | 
					    dc.cc_op = CC_OP_DYNAMIC;
 | 
				
			||||||
    dc.ex_value = tb->cs_base;
 | 
					    dc.ex_value = dc.base.tb->cs_base;
 | 
				
			||||||
    do_debug = dc.singlestep_enabled = cs->singlestep_enabled;
 | 
					    do_debug = cs->singlestep_enabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    page_start = pc_start & TARGET_PAGE_MASK;
 | 
					    page_start = dc.base.pc_first & TARGET_PAGE_MASK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    num_insns = 0;
 | 
					    num_insns = 0;
 | 
				
			||||||
    max_insns = tb_cflags(tb) & CF_COUNT_MASK;
 | 
					    max_insns = tb_cflags(tb) & CF_COUNT_MASK;
 | 
				
			||||||
@ -6191,17 +6194,17 @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
 | 
				
			|||||||
    gen_tb_start(tb);
 | 
					    gen_tb_start(tb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    do {
 | 
					    do {
 | 
				
			||||||
        tcg_gen_insn_start(dc.pc, dc.cc_op);
 | 
					        tcg_gen_insn_start(dc.base.pc_next, dc.cc_op);
 | 
				
			||||||
        num_insns++;
 | 
					        num_insns++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (unlikely(cpu_breakpoint_test(cs, dc.pc, BP_ANY))) {
 | 
					        if (unlikely(cpu_breakpoint_test(cs, dc.base.pc_next, BP_ANY))) {
 | 
				
			||||||
            status = DISAS_PC_STALE;
 | 
					            status = DISAS_PC_STALE;
 | 
				
			||||||
            do_debug = true;
 | 
					            do_debug = true;
 | 
				
			||||||
            /* The address covered by the breakpoint must be included in
 | 
					            /* The address covered by the breakpoint must be included in
 | 
				
			||||||
               [tb->pc, tb->pc + tb->size) in order to for it to be
 | 
					               [tb->pc, tb->pc + tb->size) in order to for it to be
 | 
				
			||||||
               properly cleared -- thus we increment the PC here so that
 | 
					               properly cleared -- thus we increment the PC here so that
 | 
				
			||||||
               the logic setting tb->size below does the right thing.  */
 | 
					               the logic setting tb->size below does the right thing.  */
 | 
				
			||||||
            dc.pc += 2;
 | 
					            dc.base.pc_next += 2;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -6214,11 +6217,11 @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
 | 
				
			|||||||
        /* If we reach a page boundary, are single stepping,
 | 
					        /* If we reach a page boundary, are single stepping,
 | 
				
			||||||
           or exhaust instruction count, stop generation.  */
 | 
					           or exhaust instruction count, stop generation.  */
 | 
				
			||||||
        if (status == DISAS_NEXT
 | 
					        if (status == DISAS_NEXT
 | 
				
			||||||
            && (dc.pc - page_start >= TARGET_PAGE_SIZE
 | 
					            && (dc.base.pc_next - page_start >= TARGET_PAGE_SIZE
 | 
				
			||||||
                || tcg_op_buf_full()
 | 
					                || tcg_op_buf_full()
 | 
				
			||||||
                || num_insns >= max_insns
 | 
					                || num_insns >= max_insns
 | 
				
			||||||
                || singlestep
 | 
					                || singlestep
 | 
				
			||||||
                || cs->singlestep_enabled
 | 
					                || dc.base.singlestep_enabled
 | 
				
			||||||
                || dc.ex_value)) {
 | 
					                || dc.ex_value)) {
 | 
				
			||||||
            status = DISAS_TOO_MANY;
 | 
					            status = DISAS_TOO_MANY;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -6258,19 +6261,20 @@ void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    gen_tb_end(tb, num_insns);
 | 
					    gen_tb_end(tb, num_insns);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    tb->size = dc.pc - pc_start;
 | 
					    tb->size = dc.base.pc_next - dc.base.pc_first;
 | 
				
			||||||
    tb->icount = num_insns;
 | 
					    tb->icount = num_insns;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(S390X_DEBUG_DISAS)
 | 
					#if defined(S390X_DEBUG_DISAS)
 | 
				
			||||||
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
 | 
					    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
 | 
				
			||||||
        && qemu_log_in_addr_range(pc_start)) {
 | 
					        && qemu_log_in_addr_range(dc.base.pc_first)) {
 | 
				
			||||||
        qemu_log_lock();
 | 
					        qemu_log_lock();
 | 
				
			||||||
        if (unlikely(dc.ex_value)) {
 | 
					        if (unlikely(dc.ex_value)) {
 | 
				
			||||||
            /* ??? Unfortunately log_target_disas can't use host memory.  */
 | 
					            /* ??? Unfortunately log_target_disas can't use host memory.  */
 | 
				
			||||||
            qemu_log("IN: EXECUTE %016" PRIx64 "\n", dc.ex_value);
 | 
					            qemu_log("IN: EXECUTE %016" PRIx64 "\n", dc.ex_value);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            qemu_log("IN: %s\n", lookup_symbol(pc_start));
 | 
					            qemu_log("IN: %s\n", lookup_symbol(dc.base.pc_first));
 | 
				
			||||||
            log_target_disas(cs, pc_start, dc.pc - pc_start);
 | 
					            log_target_disas(cs, dc.base.pc_first,
 | 
				
			||||||
 | 
					                             dc.base.pc_next - dc.base.pc_first);
 | 
				
			||||||
            qemu_log("\n");
 | 
					            qemu_log("\n");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        qemu_log_unlock();
 | 
					        qemu_log_unlock();
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user