Patchwork [55/62] tcg-s390: Use 16-bit branches for forward jumps.

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

Comments

Richard Henderson - May 27, 2010, 8:46 p.m.
Translation blocks are never big enough to require 32-bit branches.

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

Patch

diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
index 0dc71e2..697c5e4 100644
--- a/tcg/s390/tcg-target.c
+++ b/tcg/s390/tcg-target.c
@@ -33,6 +33,11 @@ 
     do { } while (0)
 #endif
 
+/* ??? The translation blocks produced by TCG are generally small enough to
+   be entirely reachable with a 16-bit displacement.  Leaving the option for
+   a 32-bit displacement here Just In Case.  */
+#define USE_LONG_BRANCHES 0
+
 #define TCG_CT_CONST_32    0x0100
 #define TCG_CT_CONST_NEG   0x0200
 #define TCG_CT_CONST_ADDI  0x0400
@@ -295,14 +300,22 @@  static uint8_t *tb_ret_addr;
 static uint64_t facilities;
 
 static void patch_reloc(uint8_t *code_ptr, int type,
-                tcg_target_long value, tcg_target_long addend)
+                        tcg_target_long value, tcg_target_long addend)
 {
-    uint32_t *code_ptr_32 = (uint32_t*)code_ptr;
-    tcg_target_long code_ptr_tlong = (tcg_target_long)code_ptr;
+    tcg_target_long code_ptr_tl = (tcg_target_long)code_ptr;
+    tcg_target_long pcrel2;
 
+    /* ??? Not the usual definition of "addend".  */
+    pcrel2 = (value - (code_ptr_tl + addend)) >> 1;
+    
     switch (type) {
+    case R_390_PC16DBL:
+        assert(pcrel2 == (int16_t)pcrel2);
+        *(int16_t *)code_ptr = pcrel2;
+        break;
     case R_390_PC32DBL:
-        *code_ptr_32 = (value - (code_ptr_tlong + addend)) >> 1;
+        assert(pcrel2 == (int32_t)pcrel2);
+        *(int32_t *)code_ptr = pcrel2;
         break;
     default:
         tcg_abort();
@@ -1081,10 +1094,14 @@  static void tgen_branch(TCGContext *s, int cc, int labelno)
     TCGLabel* l = &s->labels[labelno];
     if (l->has_value) {
         tgen_gotoi(s, cc, l->u.value);
-    } else {
+    } else if (USE_LONG_BRANCHES) {
         tcg_out16(s, RIL_BRCL | (cc << 4));
         tcg_out_reloc(s, s->code_ptr, R_390_PC32DBL, labelno, -2);
         s->code_ptr += 4;
+    } else {
+        tcg_out16(s, RI_BRC | (cc << 4));
+        tcg_out_reloc(s, s->code_ptr, R_390_PC16DBL, labelno, -2);
+        s->code_ptr += 2;
     }
 }