mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-09-09 00:07:57 -06:00
tcg/s390x: Check for general-instruction-extension facility at startup
The general-instruction-extension facility was introduced in z10, which itself was end-of-life in 2019. Reviewed-by: Ilya Leoshkevich <iii@linux.ibm.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
3e25f7da9a
commit
9c3bfb79f4
2 changed files with 49 additions and 61 deletions
|
@ -843,15 +843,8 @@ static void tcg_out_movi(TCGContext *s, TCGType type,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise, stuff it in the constant pool. */
|
/* Otherwise, stuff it in the constant pool. */
|
||||||
if (HAVE_FACILITY(GEN_INST_EXT)) {
|
tcg_out_insn(s, RIL, LGRL, ret, 0);
|
||||||
tcg_out_insn(s, RIL, LGRL, ret, 0);
|
new_pool_label(s, sval, R_390_PC32DBL, s->code_ptr - 2, 2);
|
||||||
new_pool_label(s, sval, R_390_PC32DBL, s->code_ptr - 2, 2);
|
|
||||||
} else {
|
|
||||||
TCGReg base = ret ? ret : TCG_TMP0;
|
|
||||||
tcg_out_insn(s, RIL, LARL, base, 0);
|
|
||||||
new_pool_label(s, sval, R_390_PC32DBL, s->code_ptr - 2, 2);
|
|
||||||
tcg_out_insn(s, RXY, LG, ret, base, TCG_REG_NONE, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Emit a load/store type instruction. Inputs are:
|
/* Emit a load/store type instruction. Inputs are:
|
||||||
|
@ -1105,7 +1098,7 @@ static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (HAVE_FACILITY(GEN_INST_EXT) && risbg_mask(val)) {
|
if (risbg_mask(val)) {
|
||||||
tgen_andi_risbg(s, dest, dest, val);
|
tgen_andi_risbg(s, dest, dest, val);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1460,48 +1453,47 @@ static void tgen_brcond(TCGContext *s, TCGType type, TCGCond c,
|
||||||
TCGReg r1, TCGArg c2, int c2const, TCGLabel *l)
|
TCGReg r1, TCGArg c2, int c2const, TCGLabel *l)
|
||||||
{
|
{
|
||||||
int cc;
|
int cc;
|
||||||
|
bool is_unsigned = is_unsigned_cond(c);
|
||||||
|
bool in_range;
|
||||||
|
S390Opcode opc;
|
||||||
|
|
||||||
if (HAVE_FACILITY(GEN_INST_EXT)) {
|
cc = tcg_cond_to_s390_cond[c];
|
||||||
bool is_unsigned = is_unsigned_cond(c);
|
|
||||||
bool in_range;
|
|
||||||
S390Opcode opc;
|
|
||||||
|
|
||||||
cc = tcg_cond_to_s390_cond[c];
|
if (!c2const) {
|
||||||
|
opc = (type == TCG_TYPE_I32
|
||||||
|
? (is_unsigned ? RIE_CLRJ : RIE_CRJ)
|
||||||
|
: (is_unsigned ? RIE_CLGRJ : RIE_CGRJ));
|
||||||
|
tgen_compare_branch(s, opc, cc, r1, c2, l);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!c2const) {
|
/*
|
||||||
opc = (type == TCG_TYPE_I32
|
* COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
|
||||||
? (is_unsigned ? RIE_CLRJ : RIE_CRJ)
|
* If the immediate we've been given does not fit that range, we'll
|
||||||
: (is_unsigned ? RIE_CLGRJ : RIE_CGRJ));
|
* fall back to separate compare and branch instructions using the
|
||||||
tgen_compare_branch(s, opc, cc, r1, c2, l);
|
* larger comparison range afforded by COMPARE IMMEDIATE.
|
||||||
return;
|
*/
|
||||||
}
|
if (type == TCG_TYPE_I32) {
|
||||||
|
if (is_unsigned) {
|
||||||
/* COMPARE IMMEDIATE AND BRANCH RELATIVE has an 8-bit immediate field.
|
opc = RIE_CLIJ;
|
||||||
If the immediate we've been given does not fit that range, we'll
|
in_range = (uint32_t)c2 == (uint8_t)c2;
|
||||||
fall back to separate compare and branch instructions using the
|
|
||||||
larger comparison range afforded by COMPARE IMMEDIATE. */
|
|
||||||
if (type == TCG_TYPE_I32) {
|
|
||||||
if (is_unsigned) {
|
|
||||||
opc = RIE_CLIJ;
|
|
||||||
in_range = (uint32_t)c2 == (uint8_t)c2;
|
|
||||||
} else {
|
|
||||||
opc = RIE_CIJ;
|
|
||||||
in_range = (int32_t)c2 == (int8_t)c2;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (is_unsigned) {
|
opc = RIE_CIJ;
|
||||||
opc = RIE_CLGIJ;
|
in_range = (int32_t)c2 == (int8_t)c2;
|
||||||
in_range = (uint64_t)c2 == (uint8_t)c2;
|
|
||||||
} else {
|
|
||||||
opc = RIE_CGIJ;
|
|
||||||
in_range = (int64_t)c2 == (int8_t)c2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (in_range) {
|
} else {
|
||||||
tgen_compare_imm_branch(s, opc, cc, r1, c2, l);
|
if (is_unsigned) {
|
||||||
return;
|
opc = RIE_CLGIJ;
|
||||||
|
in_range = (uint64_t)c2 == (uint8_t)c2;
|
||||||
|
} else {
|
||||||
|
opc = RIE_CGIJ;
|
||||||
|
in_range = (int64_t)c2 == (int8_t)c2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (in_range) {
|
||||||
|
tgen_compare_imm_branch(s, opc, cc, r1, c2, l);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
cc = tgen_cmp(s, type, c, r1, c2, c2const, false);
|
cc = tgen_cmp(s, type, c, r1, c2, c2const, false);
|
||||||
tgen_branch(s, cc, l);
|
tgen_branch(s, cc, l);
|
||||||
|
@ -1659,7 +1651,7 @@ static TCGReg tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg, MemOp opc,
|
||||||
cross pages using the address of the last byte of the access. */
|
cross pages using the address of the last byte of the access. */
|
||||||
a_off = (a_bits >= s_bits ? 0 : s_mask - a_mask);
|
a_off = (a_bits >= s_bits ? 0 : s_mask - a_mask);
|
||||||
tlb_mask = (uint64_t)TARGET_PAGE_MASK | a_mask;
|
tlb_mask = (uint64_t)TARGET_PAGE_MASK | a_mask;
|
||||||
if (HAVE_FACILITY(GEN_INST_EXT) && a_off == 0) {
|
if (a_off == 0) {
|
||||||
tgen_andi_risbg(s, TCG_REG_R3, addr_reg, tlb_mask);
|
tgen_andi_risbg(s, TCG_REG_R3, addr_reg, tlb_mask);
|
||||||
} else {
|
} else {
|
||||||
tcg_out_insn(s, RX, LA, TCG_REG_R3, addr_reg, TCG_REG_NONE, a_off);
|
tcg_out_insn(s, RX, LA, TCG_REG_R3, addr_reg, TCG_REG_NONE, a_off);
|
||||||
|
@ -2972,17 +2964,9 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
|
||||||
: C_O1_I2(r, 0, ri));
|
: C_O1_I2(r, 0, ri));
|
||||||
|
|
||||||
case INDEX_op_mul_i32:
|
case INDEX_op_mul_i32:
|
||||||
/* If we have the general-instruction-extensions, then we have
|
return C_O1_I2(r, 0, ri);
|
||||||
MULTIPLY SINGLE IMMEDIATE with a signed 32-bit, otherwise we
|
|
||||||
have only MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit. */
|
|
||||||
return (HAVE_FACILITY(GEN_INST_EXT)
|
|
||||||
? C_O1_I2(r, 0, ri)
|
|
||||||
: C_O1_I2(r, 0, rI));
|
|
||||||
|
|
||||||
case INDEX_op_mul_i64:
|
case INDEX_op_mul_i64:
|
||||||
return (HAVE_FACILITY(GEN_INST_EXT)
|
return C_O1_I2(r, 0, rJ);
|
||||||
? C_O1_I2(r, 0, rJ)
|
|
||||||
: C_O1_I2(r, 0, rI));
|
|
||||||
|
|
||||||
case INDEX_op_shl_i32:
|
case INDEX_op_shl_i32:
|
||||||
case INDEX_op_shr_i32:
|
case INDEX_op_shr_i32:
|
||||||
|
@ -3151,6 +3135,10 @@ static void query_s390_facilities(void)
|
||||||
which = "extended-immediate";
|
which = "extended-immediate";
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
if (!HAVE_FACILITY(GEN_INST_EXT)) {
|
||||||
|
which = "general-instructions-extension";
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
|
|
@ -57,10 +57,10 @@ typedef enum TCGReg {
|
||||||
#define FACILITY_ZARCH_ACTIVE 2
|
#define FACILITY_ZARCH_ACTIVE 2
|
||||||
#define FACILITY_LONG_DISP 18
|
#define FACILITY_LONG_DISP 18
|
||||||
#define FACILITY_EXT_IMM 21
|
#define FACILITY_EXT_IMM 21
|
||||||
|
#define FACILITY_GEN_INST_EXT 34
|
||||||
|
|
||||||
/* Facilities that are checked at runtime. */
|
/* Facilities that are checked at runtime. */
|
||||||
|
|
||||||
#define FACILITY_GEN_INST_EXT 34
|
|
||||||
#define FACILITY_LOAD_ON_COND 45
|
#define FACILITY_LOAD_ON_COND 45
|
||||||
#define FACILITY_FAST_BCR_SER FACILITY_LOAD_ON_COND
|
#define FACILITY_FAST_BCR_SER FACILITY_LOAD_ON_COND
|
||||||
#define FACILITY_DISTINCT_OPS FACILITY_LOAD_ON_COND
|
#define FACILITY_DISTINCT_OPS FACILITY_LOAD_ON_COND
|
||||||
|
@ -92,8 +92,8 @@ extern uint64_t s390_facilities[3];
|
||||||
#define TCG_TARGET_HAS_clz_i32 0
|
#define TCG_TARGET_HAS_clz_i32 0
|
||||||
#define TCG_TARGET_HAS_ctz_i32 0
|
#define TCG_TARGET_HAS_ctz_i32 0
|
||||||
#define TCG_TARGET_HAS_ctpop_i32 0
|
#define TCG_TARGET_HAS_ctpop_i32 0
|
||||||
#define TCG_TARGET_HAS_deposit_i32 HAVE_FACILITY(GEN_INST_EXT)
|
#define TCG_TARGET_HAS_deposit_i32 1
|
||||||
#define TCG_TARGET_HAS_extract_i32 HAVE_FACILITY(GEN_INST_EXT)
|
#define TCG_TARGET_HAS_extract_i32 1
|
||||||
#define TCG_TARGET_HAS_sextract_i32 0
|
#define TCG_TARGET_HAS_sextract_i32 0
|
||||||
#define TCG_TARGET_HAS_extract2_i32 0
|
#define TCG_TARGET_HAS_extract2_i32 0
|
||||||
#define TCG_TARGET_HAS_movcond_i32 1
|
#define TCG_TARGET_HAS_movcond_i32 1
|
||||||
|
@ -129,8 +129,8 @@ extern uint64_t s390_facilities[3];
|
||||||
#define TCG_TARGET_HAS_clz_i64 1
|
#define TCG_TARGET_HAS_clz_i64 1
|
||||||
#define TCG_TARGET_HAS_ctz_i64 0
|
#define TCG_TARGET_HAS_ctz_i64 0
|
||||||
#define TCG_TARGET_HAS_ctpop_i64 0
|
#define TCG_TARGET_HAS_ctpop_i64 0
|
||||||
#define TCG_TARGET_HAS_deposit_i64 HAVE_FACILITY(GEN_INST_EXT)
|
#define TCG_TARGET_HAS_deposit_i64 1
|
||||||
#define TCG_TARGET_HAS_extract_i64 HAVE_FACILITY(GEN_INST_EXT)
|
#define TCG_TARGET_HAS_extract_i64 1
|
||||||
#define TCG_TARGET_HAS_sextract_i64 0
|
#define TCG_TARGET_HAS_sextract_i64 0
|
||||||
#define TCG_TARGET_HAS_extract2_i64 0
|
#define TCG_TARGET_HAS_extract2_i64 0
|
||||||
#define TCG_TARGET_HAS_movcond_i64 1
|
#define TCG_TARGET_HAS_movcond_i64 1
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue