Skip to content

Commit

Permalink
target/s390x: Tidy SRST
Browse files Browse the repository at this point in the history
Since we require all registers saved on input, read R0 from ENV instead
of passing it manually.  Recognize the specification exception when R0
contains incorrect data.  Keep high bits of result registers unmodified
when in 31 or 24-bit mode.

Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
  • Loading branch information
rth7680 committed Jul 17, 2017
1 parent 941ef3d commit 7591db7
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 15 deletions.
2 changes: 1 addition & 1 deletion target/s390x/helper.h
Expand Up @@ -12,7 +12,7 @@ DEF_HELPER_FLAGS_3(divs32, TCG_CALL_NO_WG, s64, env, s64, s64)
DEF_HELPER_FLAGS_3(divu32, TCG_CALL_NO_WG, i64, env, i64, i64)
DEF_HELPER_FLAGS_3(divs64, TCG_CALL_NO_WG, s64, env, s64, s64)
DEF_HELPER_FLAGS_4(divu64, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
DEF_HELPER_4(srst, i64, env, i64, i64, i64)
DEF_HELPER_3(srst, void, env, i32, i32)
DEF_HELPER_4(clst, i64, env, i64, i64, i64)
DEF_HELPER_FLAGS_4(mvn, TCG_CALL_NO_WG, void, env, i32, i64, i64)
DEF_HELPER_FLAGS_4(mvo, TCG_CALL_NO_WG, void, env, i32, i64, i64)
Expand Down
2 changes: 1 addition & 1 deletion target/s390x/insn-data.def
Expand Up @@ -736,7 +736,7 @@
C(0xec57, RXSBG, RIE_f, GIE, 0, r2, r1, 0, rosbg, 0)

/* SEARCH STRING */
C(0xb25e, SRST, RRE, Z, r1_o, r2_o, 0, 0, srst, 0)
C(0xb25e, SRST, RRE, Z, 0, 0, 0, 0, srst, 0)

/* SET ACCESS */
C(0xb24e, SAR, RRE, Z, 0, r2_o, 0, 0, sar, 0)
Expand Down
25 changes: 14 additions & 11 deletions target/s390x/mem_helper.c
Expand Up @@ -538,39 +538,42 @@ static inline void set_length(CPUS390XState *env, int reg, uint64_t length)
}

/* search string (c is byte to search, r2 is string, r1 end of string) */
uint64_t HELPER(srst)(CPUS390XState *env, uint64_t r0, uint64_t end,
uint64_t str)
void HELPER(srst)(CPUS390XState *env, uint32_t r1, uint32_t r2)
{
uintptr_t ra = GETPC();
uint64_t end, str;
uint32_t len;
uint8_t v, c = r0;
uint8_t v, c = env->regs[0];

str = wrap_address(env, str);
end = wrap_address(env, end);
/* Bits 32-55 must contain all 0. */
if (env->regs[0] & 0xffffff00u) {
cpu_restore_state(ENV_GET_CPU(env), ra);
program_interrupt(env, PGM_SPECIFICATION, 6);
}

/* Assume for now that R2 is unmodified. */
env->retxl = str;
str = get_address(env, r2);
end = get_address(env, r1);

/* Lest we fail to service interrupts in a timely manner, limit the
amount of work we're willing to do. For now, let's cap at 8k. */
for (len = 0; len < 0x2000; ++len) {
if (str + len == end) {
/* Character not found. R1 & R2 are unmodified. */
env->cc_op = 2;
return end;
return;
}
v = cpu_ldub_data_ra(env, str + len, ra);
if (v == c) {
/* Character found. Set R1 to the location; R2 is unmodified. */
env->cc_op = 1;
return str + len;
set_address(env, r1, str + len);
return;
}
}

/* CPU-determined bytes processed. Advance R2 to next byte to process. */
env->retxl = str + len;
env->cc_op = 3;
return end;
set_address(env, r2, str + len);
}

/* unsigned string compare (c is string terminator) */
Expand Down
9 changes: 7 additions & 2 deletions target/s390x/translate.c
Expand Up @@ -4287,9 +4287,14 @@ static ExitStatus op_stpq(DisasContext *s, DisasOps *o)

static ExitStatus op_srst(DisasContext *s, DisasOps *o)
{
gen_helper_srst(o->in1, cpu_env, regs[0], o->in1, o->in2);
TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));

gen_helper_srst(cpu_env, r1, r2);

tcg_temp_free_i32(r1);
tcg_temp_free_i32(r2);
set_cc_static(s);
return_low128(o->in2);
return NO_EXIT;
}

Expand Down

0 comments on commit 7591db7

Please sign in to comment.