Patchwork [47/62] tcg-s390: Conditionalize general-instruction-extension insns.

login
register
mail settings
Submitter Richard Henderson
Date May 27, 2010, 8:46 p.m.
Message ID <1274993204-30766-48-git-send-email-rth@twiddle.net>
Download mbox | patch
Permalink /patch/53824/
State New
Headers show

Comments

Richard Henderson - May 27, 2010, 8:46 p.m.
The LOAD RELATIVE and MULTIPLY SINGLE IMMEDIATE instructions
are currently the only insns from that extension.  It's easy
enough to test for that facility and avoid emitting them.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/s390/tcg-target.c |   51 +++++++++++++++++++++++++++++-------------------
 1 files changed, 31 insertions(+), 20 deletions(-)

Patch

diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
index 4807bca..aecabf9 100644
--- a/tcg/s390/tcg-target.c
+++ b/tcg/s390/tcg-target.c
@@ -35,6 +35,7 @@ 
 
 #define TCG_CT_CONST_S32   0x100
 #define TCG_CT_CONST_N32   0x200
+#define TCG_CT_CONST_MULI  0x400
 
 #define TCG_TMP0           TCG_REG_R14
 
@@ -344,6 +345,10 @@  static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
         ct->ct &= ~TCG_CT_REG;
         ct->ct |= TCG_CT_CONST_N32;
         break;
+    case 'K':
+        ct->ct &= ~TCG_CT_REG;
+        ct->ct |= TCG_CT_CONST_MULI;
+        break;
     default:
         break;
     }
@@ -365,6 +370,16 @@  static inline int tcg_target_const_match(tcg_target_long val,
         return val == (int32_t)val;
     } else if (ct & TCG_CT_CONST_N32) {
         return -val == (int32_t)-val;
+    } else if (ct & TCG_CT_CONST_MULI) {
+        /* Immediates that may be used with multiply.  If we have the
+           general-instruction-extensions, then we have MULTIPLY SINGLE
+           IMMEDIATE with a signed 32-bit, otherwise we have only 
+           MULTIPLY HALFWORD IMMEDIATE, with a signed 16-bit.  */
+        if (facilities & FACILITY_GEN_INST_EXT) {
+            return val == (int32_t)val;
+        } else {
+            return val == (int16_t)val;
+        }
     }
 
     return 0;
@@ -559,18 +574,21 @@  static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg data,
 static void tcg_out_ld_abs(TCGContext *s, TCGType type, TCGReg dest, void *abs)
 {
     tcg_target_long addr = (tcg_target_long)abs;
-    tcg_target_long disp = (addr - (tcg_target_long)s->code_ptr) >> 1;
 
-    if (disp == (int32_t)disp) {
-        if (type == TCG_TYPE_I32) {
-            tcg_out_insn(s, RIL, LRL, dest, disp);
-        } else {
-            tcg_out_insn(s, RIL, LGRL, dest, disp);
+    if (facilities & FACILITY_GEN_INST_EXT) {
+        tcg_target_long disp = (addr - (tcg_target_long)s->code_ptr) >> 1;
+        if (disp == (int32_t)disp) {
+            if (type == TCG_TYPE_I32) {
+                tcg_out_insn(s, RIL, LRL, dest, disp);
+            } else {
+                tcg_out_insn(s, RIL, LGRL, dest, disp);
+            }
+            return;
         }
-    } else {
-        tcg_out_movi(s, TCG_TYPE_PTR, dest, addr & ~0xffff);
-        tcg_out_ld(s, type, dest, dest, addr & 0xffff);
     }
+
+    tcg_out_movi(s, TCG_TYPE_PTR, dest, addr & ~0xffff);
+    tcg_out_ld(s, type, dest, dest, addr & 0xffff);
 }
 
 static inline void tgen_ext8s(TCGContext *s, TCGReg dest, TCGReg src)
@@ -1322,7 +1340,7 @@  static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
     case INDEX_op_mul_i32:
         if (const_args[2]) {
-            if (args[2] == (int16_t)args[2]) {
+            if ((int32_t)args[2] == (int16_t)args[2]) {
                 tcg_out_insn(s, RI, MHI, args[0], args[2]);
             } else {
                 tcg_out_insn(s, RIL, MSFI, args[0], args[2]);
@@ -1573,7 +1591,7 @@  static const TCGTargetOpDef s390_op_defs[] = {
 
     { INDEX_op_add_i32, { "r", "0", "ri" } },
     { INDEX_op_sub_i32, { "r", "0", "ri" } },
-    { INDEX_op_mul_i32, { "r", "0", "ri" } },
+    { INDEX_op_mul_i32, { "r", "0", "rK" } },
 
     { INDEX_op_div2_i32, { "b", "a", "0", "1", "r" } },
     { INDEX_op_divu2_i32, { "b", "a", "0", "1", "r" } },
@@ -1634,7 +1652,7 @@  static const TCGTargetOpDef s390_op_defs[] = {
 
     { INDEX_op_add_i64, { "r", "0", "rI" } },
     { INDEX_op_sub_i64, { "r", "0", "rJ" } },
-    { INDEX_op_mul_i64, { "r", "0", "rI" } },
+    { INDEX_op_mul_i64, { "r", "0", "rK" } },
 
     { INDEX_op_div2_i64, { "b", "a", "0", "1", "r" } },
     { INDEX_op_divu2_i64, { "b", "a", "0", "1", "r" } },
@@ -1752,9 +1770,7 @@  static void query_facilities(void)
 
     sigaction(SIGILL, &sa_old, NULL);
 
-    /* ??? The translator currently uses all of these extensions
-       unconditionally.  This list could be pruned back to just
-       z/Arch and long displacement with some work.  */
+    /* The translator currently uses these extensions unconditionally.  */
     fail = 0;
     if ((facilities & FACILITY_ZARCH_ACTIVE) == 0) {
         fprintf(stderr, "TCG: z/Arch facility is required\n");
@@ -1768,11 +1784,6 @@  static void query_facilities(void)
         fprintf(stderr, "TCG: extended-immediate facility is required\n");
         fail = 1;
     }
-    if ((facilities & FACILITY_GEN_INST_EXT) == 0) {
-        fprintf(stderr, "TCG: general-instructions-extension "
-                "facility is required\n");
-        fail = 1;
-    }
     if (fail) {
         exit(-1);
     }