Merge remote-tracking branch 'remotes/rth/tags/pull-s390-20170717' into staging

Queued s390x tcg patches, v2

# gpg: Signature made Mon 17 Jul 2017 22:22:23 BST
# gpg:                using RSA key 0xAD1270CC4DD0279B
# gpg: Good signature from "Richard Henderson <rth7680@gmail.com>"
# gpg:                 aka "Richard Henderson <rth@redhat.com>"
# gpg:                 aka "Richard Henderson <rth@twiddle.net>"
# Primary key fingerprint: 9CB1 8DDA F8E8 49AD 2AFC  16A4 AD12 70CC 4DD0 279B

* remotes/rth/tags/pull-s390-20170717:
  target/s390x: Fix risbg handling
  target/s390x: Allow to enable "idtes" feature for TCG
  target/s390x: Mark ETF3 and ETF3_ENH facilities as available
  target/s390x: Implement TRTR
  target/s390x: Implement SRSTU
  target/s390x: Tidy SRST
  target/s390x: Implement CONVERT UNICODE insns
  target/s390x: Implement CSST

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2017-07-18 17:54:51 +01:00
5 changed files with 696 additions and 25 deletions
+5
View File
@@ -779,14 +779,19 @@ static void add_qemu_cpu_model_features(S390FeatBitmap fbm)
{
static const int feats[] = {
S390_FEAT_DAT_ENH,
S390_FEAT_IDTE_SEGMENT,
S390_FEAT_STFLE,
S390_FEAT_EXTENDED_IMMEDIATE,
S390_FEAT_EXTENDED_TRANSLATION_2,
S390_FEAT_EXTENDED_TRANSLATION_3,
S390_FEAT_LONG_DISPLACEMENT,
S390_FEAT_LONG_DISPLACEMENT_FAST,
S390_FEAT_ETF2_ENH,
S390_FEAT_STORE_CLOCK_FAST,
S390_FEAT_MOVE_WITH_OPTIONAL_SPEC,
S390_FEAT_ETF3_ENH,
S390_FEAT_COMPARE_AND_SWAP_AND_STORE,
S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2,
S390_FEAT_GENERAL_INSTRUCTIONS_EXT,
S390_FEAT_EXECUTE_EXT,
S390_FEAT_FLOATING_POINT_SUPPPORT_ENH,
+10 -1
View File
@@ -12,7 +12,8 @@ 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_3(srstu, 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)
@@ -33,6 +34,7 @@ DEF_HELPER_3(celgb, i64, env, i64, i32)
DEF_HELPER_3(cdlgb, i64, env, i64, i32)
DEF_HELPER_3(cxlgb, i64, env, i64, i32)
DEF_HELPER_4(cdsg, void, env, i64, i32, i32)
DEF_HELPER_4(csst, i32, env, i32, i64, i64)
DEF_HELPER_FLAGS_3(aeb, TCG_CALL_NO_WG, i64, env, i64, i64)
DEF_HELPER_FLAGS_3(adb, TCG_CALL_NO_WG, i64, env, i64, i64)
DEF_HELPER_FLAGS_5(axb, TCG_CALL_NO_WG, i64, env, i64, i64, i64, i64)
@@ -95,6 +97,7 @@ DEF_HELPER_FLAGS_3(tp, TCG_CALL_NO_WG, i32, env, i64, i32)
DEF_HELPER_FLAGS_4(tr, TCG_CALL_NO_WG, void, env, i32, i64, i64)
DEF_HELPER_4(tre, i64, env, i64, i64, i64)
DEF_HELPER_4(trt, i32, env, i32, i64, i64)
DEF_HELPER_4(trtr, i32, env, i32, i64, i64)
DEF_HELPER_5(trXX, i32, env, i32, i32, i32, i32)
DEF_HELPER_4(cksm, i64, env, i64, i64, i64)
DEF_HELPER_FLAGS_5(calc_cc, TCG_CALL_NO_RWG_SE, i32, env, i32, i64, i64, i64)
@@ -106,6 +109,12 @@ DEF_HELPER_2(stfle, i32, env, i64)
DEF_HELPER_FLAGS_2(lpq, TCG_CALL_NO_WG, i64, env, i64)
DEF_HELPER_FLAGS_4(stpq, TCG_CALL_NO_WG, void, env, i64, i64, i64)
DEF_HELPER_4(mvcos, i32, env, i64, i64, i64)
DEF_HELPER_4(cu12, i32, env, i32, i32, i32)
DEF_HELPER_4(cu14, i32, env, i32, i32, i32)
DEF_HELPER_4(cu21, i32, env, i32, i32, i32)
DEF_HELPER_4(cu24, i32, env, i32, i32, i32)
DEF_HELPER_4(cu41, i32, env, i32, i32, i32)
DEF_HELPER_4(cu42, i32, env, i32, i32, i32)
#ifndef CONFIG_USER_ONLY
DEF_HELPER_3(servc, i32, env, i64, i64)
+20 -1
View File
@@ -265,6 +265,8 @@
D(0xbb00, CDS, RS_a, Z, r3_D32, r1_D32, new, r1_D32, cs, 0, MO_TEQ)
D(0xeb31, CDSY, RSY_a, LD, r3_D32, r1_D32, new, r1_D32, cs, 0, MO_TEQ)
C(0xeb3e, CDSG, RSY_a, Z, 0, 0, 0, 0, cdsg, 0)
/* COMPARE AND SWAP AND STORE */
C(0xc802, CSST, SSF, CASS, la1, a2, 0, 0, csst, 0)
/* COMPARE AND TRAP */
D(0xb972, CRT, RRF_c, GIE, r1_32s, r2_32s, 0, 0, ct, 0, 0)
@@ -311,6 +313,19 @@
C(0xb3a1, CDLGBR, RRF_e, FPE, 0, r2_o, f1, 0, cdlgb, 0)
C(0xb3a2, CXLGBR, RRF_e, FPE, 0, r2_o, x1, 0, cxlgb, 0)
/* CONVERT UTF-8 TO UTF-16 */
D(0xb2a7, CU12, RRF_c, Z, 0, 0, 0, 0, cuXX, 0, 12)
/* CONVERT UTF-8 TO UTF-32 */
D(0xb9b0, CU14, RRF_c, ETF3, 0, 0, 0, 0, cuXX, 0, 14)
/* CONVERT UTF-16 to UTF-8 */
D(0xb2a6, CU21, RRF_c, Z, 0, 0, 0, 0, cuXX, 0, 21)
/* CONVERT UTF-16 to UTF-32 */
D(0xb9b1, CU24, RRF_c, ETF3, 0, 0, 0, 0, cuXX, 0, 24)
/* CONVERT UTF-32 to UTF-8 */
D(0xb9b2, CU41, RRF_c, ETF3, 0, 0, 0, 0, cuXX, 0, 41)
/* CONVERT UTF-32 to UTF-16 */
D(0xb9b3, CU42, RRF_c, ETF3, 0, 0, 0, 0, cuXX, 0, 42)
/* DIVIDE */
C(0x1d00, DR, RR_a, Z, r1_D32, r2_32s, new_P, r1_P32, divs32, 0)
C(0x5d00, D, RX_a, Z, r1_D32, m2_32s, new_P, r1_P32, divs32, 0)
@@ -721,7 +736,9 @@
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)
/* SEARCH STRING UNICODE */
C(0xb9be, SRSTU, RRE, ETF3, 0, 0, 0, 0, srstu, 0)
/* SET ACCESS */
C(0xb24e, SAR, RRE, Z, 0, r2_o, 0, 0, sar, 0)
@@ -899,6 +916,8 @@
C(0xdc00, TR, SS_a, Z, la1, a2, 0, 0, tr, 0)
/* TRANSLATE AND TEST */
C(0xdd00, TRT, SS_a, Z, la1, a2, 0, 0, trt, 0)
/* TRANSLATE AND TEST REVERSE */
C(0xd000, TRTR, SS_a, ETF3, la1, a2, 0, 0, trtr, 0)
/* TRANSLATE EXTENDED */
C(0xb2a5, TRE, RRE, Z, 0, r2, r1_P, 0, tre, 0)
+567 -18
View File
File diff suppressed because it is too large Load Diff
+94 -5
View File
@@ -2033,6 +2033,18 @@ static ExitStatus op_cdsg(DisasContext *s, DisasOps *o)
return NO_EXIT;
}
static ExitStatus op_csst(DisasContext *s, DisasOps *o)
{
int r3 = get_field(s->fields, r3);
TCGv_i32 t_r3 = tcg_const_i32(r3);
gen_helper_csst(cc_op, cpu_env, t_r3, o->in1, o->in2);
tcg_temp_free_i32(t_r3);
set_cc_static(s);
return NO_EXIT;
}
#ifndef CONFIG_USER_ONLY
static ExitStatus op_csp(DisasContext *s, DisasOps *o)
{
@@ -2110,6 +2122,56 @@ static ExitStatus op_ct(DisasContext *s, DisasOps *o)
return NO_EXIT;
}
static ExitStatus op_cuXX(DisasContext *s, DisasOps *o)
{
int m3 = get_field(s->fields, m3);
int r1 = get_field(s->fields, r1);
int r2 = get_field(s->fields, r2);
TCGv_i32 tr1, tr2, chk;
/* R1 and R2 must both be even. */
if ((r1 | r2) & 1) {
gen_program_exception(s, PGM_SPECIFICATION);
return EXIT_NORETURN;
}
if (!s390_has_feat(S390_FEAT_ETF3_ENH)) {
m3 = 0;
}
tr1 = tcg_const_i32(r1);
tr2 = tcg_const_i32(r2);
chk = tcg_const_i32(m3);
switch (s->insn->data) {
case 12:
gen_helper_cu12(cc_op, cpu_env, tr1, tr2, chk);
break;
case 14:
gen_helper_cu14(cc_op, cpu_env, tr1, tr2, chk);
break;
case 21:
gen_helper_cu21(cc_op, cpu_env, tr1, tr2, chk);
break;
case 24:
gen_helper_cu24(cc_op, cpu_env, tr1, tr2, chk);
break;
case 41:
gen_helper_cu41(cc_op, cpu_env, tr1, tr2, chk);
break;
case 42:
gen_helper_cu42(cc_op, cpu_env, tr1, tr2, chk);
break;
default:
g_assert_not_reached();
}
tcg_temp_free_i32(tr1);
tcg_temp_free_i32(tr2);
tcg_temp_free_i32(chk);
set_cc_static(s);
return NO_EXIT;
}
#ifndef CONFIG_USER_ONLY
static ExitStatus op_diag(DisasContext *s, DisasOps *o)
{
@@ -3417,8 +3479,8 @@ static ExitStatus op_risbg(DisasContext *s, DisasOps *o)
}
/* In some cases we can implement this with extract. */
if (imask == 0 && pos == 0 && len > 0 && rot + len <= 64) {
tcg_gen_extract_i64(o->out, o->in2, rot, len);
if (imask == 0 && pos == 0 && len > 0 && len <= rot) {
tcg_gen_extract_i64(o->out, o->in2, 64 - rot, len);
return NO_EXIT;
}
@@ -4225,9 +4287,27 @@ 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 NO_EXIT;
}
static ExitStatus op_srstu(DisasContext *s, DisasOps *o)
{
TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));
gen_helper_srstu(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;
}
@@ -4367,6 +4447,15 @@ static ExitStatus op_trt(DisasContext *s, DisasOps *o)
return NO_EXIT;
}
static ExitStatus op_trtr(DisasContext *s, DisasOps *o)
{
TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
gen_helper_trtr(cc_op, cpu_env, l, o->addr1, o->in2);
tcg_temp_free_i32(l);
set_cc_static(s);
return NO_EXIT;
}
static ExitStatus op_trXX(DisasContext *s, DisasOps *o)
{
TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
@@ -5437,7 +5526,6 @@ enum DisasInsnEnum {
/* Give smaller names to the various facilities. */
#define FAC_Z S390_FEAT_ZARCH
#define FAC_CASS S390_FEAT_COMPARE_AND_SWAP_AND_STORE
#define FAC_CASS2 S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2
#define FAC_DFP S390_FEAT_DFP
#define FAC_DFPR S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* DFP-rounding */
#define FAC_DO S390_FEAT_STFLE_45 /* distinct-operands */
@@ -5466,6 +5554,7 @@ enum DisasInsnEnum {
#define FAC_EH S390_FEAT_STFLE_49 /* execution-hint */
#define FAC_PPA S390_FEAT_STFLE_49 /* processor-assist */
#define FAC_LZRB S390_FEAT_STFLE_53 /* load-and-zero-rightmost-byte */
#define FAC_ETF3 S390_FEAT_EXTENDED_TRANSLATION_3
static const DisasInsn insn_info[] = {
#include "insn-data.def"