From: Florian Krohm Date: Sat, 22 Dec 2012 02:28:25 +0000 (+0000) Subject: s390: Generalise S390_INSN_GADD which only worked on the guest X-Git-Tag: svn/VALGRIND_3_9_0^2~175 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7ec5a98d278cd09d1e4a7138801cac4df3373f5b;p=thirdparty%2Fvalgrind.git s390: Generalise S390_INSN_GADD which only worked on the guest state to S390_INSN_MADD which works for any memory location addressable with base reg + 20-bit displacement. git-svn-id: svn://svn.valgrind.org/vex/trunk@2611 --- diff --git a/VEX/priv/host_s390_defs.c b/VEX/priv/host_s390_defs.c index dcfef615e2..c3efa44cca 100644 --- a/VEX/priv/host_s390_defs.c +++ b/VEX/priv/host_s390_defs.c @@ -737,8 +737,11 @@ s390_insn_get_reg_usage(HRegUsage *u, const s390_insn *insn) s390_amode_get_reg_usage(u, insn->variant.mzero.dst); break; + case S390_INSN_MADD: + s390_amode_get_reg_usage(u, insn->variant.madd.dst); + break; + case S390_INSN_MFENCE: - case S390_INSN_GADD: break; case S390_INSN_SET_FPC_BFPRM: @@ -1017,8 +1020,11 @@ s390_insn_map_regs(HRegRemap *m, s390_insn *insn) s390_amode_map_regs(m, insn->variant.mzero.dst); break; + case S390_INSN_MADD: + s390_amode_map_regs(m, insn->variant.madd.dst); + break; + case S390_INSN_MFENCE: - case S390_INSN_GADD: break; case S390_INSN_SET_FPC_BFPRM: @@ -5444,15 +5450,21 @@ s390_insn_mzero(UChar size, s390_amode *dst) s390_insn * -s390_insn_gadd(UChar size, UInt offset, UChar delta, ULong value) +s390_insn_madd(UChar size, s390_amode *dst, UChar delta, ULong value) { s390_insn *insn = LibVEX_Alloc(sizeof(s390_insn)); - insn->tag = S390_INSN_GADD; + vassert(size == 4 || size == 8); + + /* This insn will be mapped to an ASI or AGSI so we can only allow base + register plus 12-bit / 20-bit displacement. */ + vassert(dst->tag == S390_AMODE_B12 || dst->tag == S390_AMODE_B20); + + insn->tag = S390_INSN_MADD; insn->size = size; - insn->variant.gadd.offset = offset; - insn->variant.gadd.delta = delta; - insn->variant.gadd.value = value; + insn->variant.madd.dst = dst; + insn->variant.madd.delta = delta; + insn->variant.madd.value = value; return insn; } @@ -6018,11 +6030,11 @@ s390_insn_as_string(const s390_insn *insn) s390_sprintf(buf, "%M %A", "v-mzero", insn->variant.mzero.dst); break; - case S390_INSN_GADD: - s390_sprintf(buf, "%M %G += %I (= %I)", "v-gadd", - insn->variant.gadd.offset, - (Long)(Char)insn->variant.gadd.delta, - insn->variant.gadd.value); + case S390_INSN_MADD: + s390_sprintf(buf, "%M %A += %I (= %I)", "v-madd", + insn->variant.madd.dst, + (Long)(Char)insn->variant.madd.delta, + insn->variant.madd.value); break; case S390_INSN_SET_FPC_BFPRM: @@ -8237,11 +8249,16 @@ s390_insn_mzero_emit(UChar *buf, const s390_insn *insn) static UChar * -s390_insn_gadd_emit(UChar *buf, const s390_insn *insn) +s390_insn_madd_emit(UChar *buf, const s390_insn *insn) { - return s390_emit_AGSI(buf, insn->variant.gadd.delta, - S390_REGNO_GUEST_STATE_POINTER, - DISP20(insn->variant.gadd.offset)); + s390_amode *am = insn->variant.madd.dst; + + if (insn->size == 4) { + return s390_emit_ASI(buf, insn->variant.madd.delta, am->b, + DISP20(am->d)); + } + + return s390_emit_AGSI(buf, insn->variant.madd.delta, am->b, DISP20(am->d)); } @@ -8829,8 +8846,8 @@ emit_S390Instr(Bool *is_profinc, UChar *buf, Int nbuf, s390_insn *insn, end = s390_insn_mzero_emit(buf, insn); break; - case S390_INSN_GADD: - end = s390_insn_gadd_emit(buf, insn); + case S390_INSN_MADD: + end = s390_insn_madd_emit(buf, insn); break; case S390_INSN_SET_FPC_BFPRM: diff --git a/VEX/priv/host_s390_defs.h b/VEX/priv/host_s390_defs.h index 5789baa23e..304e557536 100644 --- a/VEX/priv/host_s390_defs.h +++ b/VEX/priv/host_s390_defs.h @@ -142,7 +142,7 @@ typedef enum { S390_INSN_DFP_CONVERT, S390_INSN_MFENCE, S390_INSN_MZERO, /* Assign zero to a memory location */ - S390_INSN_GADD, /* Add a value to a guest register */ + S390_INSN_MADD, /* Add a value to a memory location */ S390_INSN_SET_FPC_BFPRM, /* Set the bfp rounding mode in the FPC */ S390_INSN_SET_FPC_DFPRM, /* Set the dfp rounding mode in the FPC */ /* The following 5 insns are mandated by translation chaining */ @@ -537,10 +537,10 @@ typedef struct { s390_amode *dst; } mzero; struct { - UInt offset; + s390_amode *dst; UChar delta; ULong value; /* for debugging only */ - } gadd; + } madd; struct { HReg mode; } set_fpc_bfprm; @@ -655,7 +655,8 @@ s390_insn *s390_insn_dfp128_convert_from(UChar size, s390_dfp_conv_t, s390_dfp_round_t); s390_insn *s390_insn_mfence(void); s390_insn *s390_insn_mzero(UChar size, s390_amode *dst); -s390_insn *s390_insn_gadd(UChar size, UInt offset, UChar delta, ULong value); +s390_insn *s390_insn_madd(UChar size, s390_amode *dst, UChar delta, + ULong value); s390_insn *s390_insn_set_fpc_bfprm(UChar size, HReg mode); s390_insn *s390_insn_set_fpc_dfprm(UChar size, HReg mode); diff --git a/VEX/priv/host_s390_isel.c b/VEX/priv/host_s390_isel.c index 9aca09f6c4..209bfb8dac 100644 --- a/VEX/priv/host_s390_isel.c +++ b/VEX/priv/host_s390_isel.c @@ -2912,6 +2912,7 @@ s390_isel_stmt(ISelEnv *env, IRStmt *stmt) case Ity_I16: case Ity_I32: case Ity_I64: + /* fixs390: We could check for INSN_MADD here. */ if (am->tag == S390_AMODE_B12 && s390_expr_is_const_zero(stmt->Ist.Store.data)) { addInstr(env, s390_insn_mzero(sizeofIRType(tyd), am)); @@ -3020,7 +3021,8 @@ s390_isel_stmt(ISelEnv *env, IRStmt *stmt) difference = new_value - old_value; if (s390_host_has_gie && ulong_fits_signed_8bit(difference)) { - addInstr(env, s390_insn_gadd(sizeofIRType(tyd), offset, + am = s390_amode_for_guest_state(offset); + addInstr(env, s390_insn_madd(sizeofIRType(tyd), am, (difference & 0xFF), new_value)); return; } @@ -3029,13 +3031,11 @@ s390_isel_stmt(ISelEnv *env, IRStmt *stmt) Use R0 as a scratch reg. */ if ((old_value >> 32) == (new_value >> 32)) { HReg r0 = make_gpr(0); - HReg gsp = make_gpr(S390_REGNO_GUEST_STATE_POINTER); - s390_amode *gam; - gam = s390_amode_b12(offset + 4, gsp); + am = s390_amode_for_guest_state(offset + 4); addInstr(env, s390_insn_load_immediate(4, r0, new_value & 0xFFFFFFFF)); - addInstr(env, s390_insn_store(4, gam, r0)); + addInstr(env, s390_insn_store(4, am, r0)); return; }