tcg/s390: Support deposit into zero

Since we can no longer use matching constraints, this does
mean we must handle that data movement by hand.

Backports commit 752b1be94757de906b9c24ebc8f5e6aa54b96b23 from qemu
This commit is contained in:
Richard Henderson 2018-03-01 13:46:49 -05:00 committed by Lioncash
parent a7462cc7bf
commit f0781470b4
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -43,6 +43,7 @@
#define TCG_CT_CONST_XORI 0x400
#define TCG_CT_CONST_CMPI 0x800
#define TCG_CT_CONST_ADLI 0x1000
#define TCG_CT_CONST_ZERO 0x2000
/* Several places within the instruction set 0 means "no register"
rather than TCG_REG_R0. */
@ -405,6 +406,9 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
case 'C':
ct->ct |= TCG_CT_CONST_CMPI;
break;
case 'Z':
ct->ct |= TCG_CT_CONST_ZERO;
break;
default:
return -1;
}
@ -544,6 +548,8 @@ static int tcg_target_const_match(tcg_target_long val, TCGType type,
return tcg_match_xori(type, val);
} else if (ct & TCG_CT_CONST_CMPI) {
return tcg_match_cmpi(type, val);
} else if (ct & TCG_CT_CONST_ZERO) {
return val == 0;
}
return 0;
@ -1251,11 +1257,11 @@ static void tgen_movcond(TCGContext *s, TCGType type, TCGCond c, TCGReg dest,
}
static void tgen_deposit(TCGContext *s, TCGReg dest, TCGReg src,
int ofs, int len)
int ofs, int len, int z)
{
int lsb = (63 - ofs);
int msb = lsb - (len - 1);
tcg_out_risbg(s, dest, src, msb, lsb, ofs, 0);
tcg_out_risbg(s, dest, src, msb, lsb, ofs, z);
}
static void tgen_extract(TCGContext *s, TCGReg dest, TCGReg src,
@ -2169,8 +2175,24 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
break;
OP_32_64(deposit):
tgen_deposit(s, args[0], args[2], args[3], args[4]);
a0 = args[0], a1 = args[1], a2 = args[2];
if (const_args[1]) {
tgen_deposit(s, a0, a2, args[3], args[4], 1);
} else {
/* Since we can't support "0Z" as a constraint, we allow a1 in
any register. Fix things up as if a matching constraint. */
if (a0 != a1) {
TCGType type = (opc == INDEX_op_deposit_i64);
if (a0 == a2) {
tcg_out_mov(s, type, TCG_TMP0, a2);
a2 = TCG_TMP0;
}
tcg_out_mov(s, type, a0, a1);
}
tgen_deposit(s, a0, a2, args[3], args[4], 0);
}
break;
OP_32_64(extract):
tgen_extract(s, args[0], args[1], args[2], args[3]);
break;
@ -2242,7 +2264,7 @@ static const TCGTargetOpDef s390_op_defs[] = {
{ INDEX_op_brcond_i32, { "r", "rC" } },
{ INDEX_op_setcond_i32, { "r", "r", "rC" } },
{ INDEX_op_movcond_i32, { "r", "r", "rC", "r", "0" } },
{ INDEX_op_deposit_i32, { "r", "0", "r" } },
{ INDEX_op_deposit_i32, { "r", "rZ", "r" } },
{ INDEX_op_extract_i32, { "r", "r" } },
{ INDEX_op_qemu_ld_i32, { "r", "L" } },