@@ -70,6 +70,10 @@ typedef enum S390Opcode {
RIL_ALGFI = 0xc20a,
RIL_BRASL = 0xc005,
RIL_BRCL = 0xc004,
+ RIL_CFI = 0xc20d,
+ RIL_CGFI = 0xc20c,
+ RIL_CLFI = 0xc20f,
+ RIL_CLGFI = 0xc20e,
RIL_IIHF = 0xc008,
RIL_IILF = 0xc009,
RIL_LARL = 0xc000,
@@ -527,7 +531,29 @@ static int tcg_match_xori(int ct, tcg_target_long val)
static int tcg_match_cmpi(int ct, tcg_target_long val)
{
- return (val == 0);
+ if (facilities & FACILITY_EXT_IMM) {
+ /* The COMPARE IMMEDIATE instruction is available. */
+ if (ct & TCG_CT_CONST_32) {
+ /* We have a 32-bit immediate and can compare against anything. */
+ return 1;
+ } else {
+ /* ??? We have no insight here into whether the comparison is
+ signed or unsigned. The COMPARE IMMEDIATE insn uses a 32-bit
+ signed immediate, and the COMPARE LOGICAL IMMEDIATE insn uses
+ a 32-bit unsigned immediate. If we were to use the (semi)
+ obvious "val == (int32_t)val" we would be enabling unsigned
+ comparisons vs very large numbers. The only solution is to
+ take the intersection of the ranges. */
+ /* ??? Another possible solution is to simply lie and allow all
+ constants here and force the out-of-range values into a temp
+ register in tgen_cmp when we have knowledge of the actual
+ comparison code in use. */
+ return val >= 0 && val <= 0x7fffffff;
+ }
+ } else {
+ /* Only the LOAD AND TEST instruction is available. */
+ return val == 0;
+ }
}
/* Test if a constant matches the constraint. */
@@ -1083,7 +1109,21 @@ static int tgen_cmp(TCGContext *s, TCGType type, TCGCond c, TCGReg r1,
}
return tcg_cond_to_ltr_cond[c];
} else {
- tcg_abort();
+ if (c > TCG_COND_GT) {
+ /* unsigned */
+ if (type == TCG_TYPE_I32) {
+ tcg_out_insn(s, RIL, CLFI, r1, c2);
+ } else {
+ tcg_out_insn(s, RIL, CLGFI, r1, c2);
+ }
+ } else {
+ /* signed */
+ if (type == TCG_TYPE_I32) {
+ tcg_out_insn(s, RIL, CFI, r1, c2);
+ } else {
+ tcg_out_insn(s, RIL, CGFI, r1, c2);
+ }
+ }
}
} else {
if (c > TCG_COND_GT) {
These instructions are available with extended-immediate facility. Signed-off-by: Richard Henderson <rth@twiddle.net> --- tcg/s390/tcg-target.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 42 insertions(+), 2 deletions(-)