summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2014-03-23 19:35:44 -0400
committerRichard Henderson <rth@twiddle.net>2014-05-15 00:10:42 -0400
commit547ec12141c3e5b5e5313a0634be369c6a199920 (patch)
tree975ac15cb527c0e9c4f53165c983a45d4dc7e74e
parentfb5964152d96bda7eee4e53c887f08824e91064f (diff)
downloadfocaccia-qemu-547ec12141c3e5b5e5313a0634be369c6a199920.tar.gz
focaccia-qemu-547ec12141c3e5b5e5313a0634be369c6a199920.zip
tcg-s390: Use more risbg in the tlb sequence
Elides two insns from the sequence.  The resulting tlb compare
sequence is satisfyingly minimal:

	risbg  %r2,%r8,51,186,56
	risbg  %r3,%r8,61,178,0
	cg     %r3,904(%r10,%r2)
	lg     %r2,920(%r10,%r2)
	jlh    tlb_miss

Signed-off-by: Richard Henderson <rth@twiddle.net>
-rw-r--r--tcg/s390/tcg-target.c49
1 files changed, 28 insertions, 21 deletions
diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
index 1c955dbe93..cd60c0162d 100644
--- a/tcg/s390/tcg-target.c
+++ b/tcg/s390/tcg-target.c
@@ -933,6 +933,20 @@ static inline bool risbg_mask(uint64_t c)
     return c == -lsb;
 }
 
+static void tgen_andi_risbg(TCGContext *s, TCGReg out, TCGReg in, uint64_t val)
+{
+    int msb, lsb;
+    if ((val & 0x8000000000000001ull) == 0x8000000000000001ull) {
+        /* Achieve wraparound by swapping msb and lsb.  */
+        msb = 64 - ctz64(~val);
+        lsb = clz64(~val) - 1;
+    } else {
+        msb = clz64(val);
+        lsb = 63 - ctz64(val);
+    }
+    tcg_out_risbg(s, out, in, msb, lsb, 0, 1);
+}
+
 static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
 {
     static const S390Opcode ni_insns[4] = {
@@ -980,16 +994,7 @@ static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val)
         }
     }
     if ((facilities & FACILITY_GEN_INST_EXT) && risbg_mask(val)) {
-        int msb, lsb;
-        if ((val & 0x8000000000000001ull) == 0x8000000000000001ull) {
-            /* Achieve wraparound by swapping msb and lsb.  */
-            msb = 64 - ctz64(~val);
-            lsb = clz64(~val) - 1;
-        } else {
-            msb = clz64(val);
-            lsb = 63 - ctz64(val);
-        }
-        tcg_out_risbg(s, dest, dest, msb, lsb, 0, 1);
+        tgen_andi_risbg(s, dest, dest, val);
         return;
     }
 
@@ -1398,22 +1403,24 @@ static TCGReg tcg_out_tlb_read(TCGContext* s, TCGReg addr_reg, TCGMemOp opc,
                                int mem_index, bool is_ld)
 {
     TCGMemOp s_bits = opc & MO_SIZE;
+    uint64_t tlb_mask = TARGET_PAGE_MASK | ((1 << s_bits) - 1);
     int ofs;
 
-    tcg_out_sh64(s, RSY_SRLG, TCG_REG_R2, addr_reg, TCG_REG_NONE,
-                 TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
-
-    if (TARGET_LONG_BITS == 32) {
-        tgen_ext32u(s, TCG_REG_R3, addr_reg);
+    if (facilities & FACILITY_GEN_INST_EXT) {
+        tcg_out_risbg(s, TCG_REG_R2, addr_reg,
+                      64 - CPU_TLB_BITS - CPU_TLB_ENTRY_BITS,
+                      63 - CPU_TLB_ENTRY_BITS,
+                      64 + CPU_TLB_ENTRY_BITS - TARGET_PAGE_BITS, 1);
+        tgen_andi_risbg(s, TCG_REG_R3, addr_reg, tlb_mask);
     } else {
-        tcg_out_mov(s, TCG_TYPE_I64, TCG_REG_R3, addr_reg);
+        tcg_out_sh64(s, RSY_SRLG, TCG_REG_R2, addr_reg, TCG_REG_NONE,
+                     TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
+        tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_R3, addr_reg);
+        tgen_andi(s, TCG_TYPE_I64, TCG_REG_R2,
+                  (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
+        tgen_andi(s, TCG_TYPE_TL, TCG_REG_R3, tlb_mask);
     }
 
-    tgen_andi(s, TCG_TYPE_I64, TCG_REG_R2,
-              (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS);
-    tgen_andi(s, TCG_TYPE_I64, TCG_REG_R3,
-              TARGET_PAGE_MASK | ((1 << s_bits) - 1));
-
     if (is_ld) {
         ofs = offsetof(CPUArchState, tlb_table[mem_index][0].addr_read);
     } else {