qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 23/62] tcg-s390: Add tgen_calli.


From: Richard Henderson
Subject: [Qemu-devel] [PATCH 23/62] tcg-s390: Add tgen_calli.
Date: Thu, 27 May 2010 13:46:05 -0700

Use it in the softmmu code paths, and INDEX_op_call.

Signed-off-by: Richard Henderson <address@hidden>
---
 tcg/s390/tcg-target.c |   45 ++++++++++++++++-----------------------------
 1 files changed, 16 insertions(+), 29 deletions(-)

diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
index f4dab1a..0bd4276 100644
--- a/tcg/s390/tcg-target.c
+++ b/tcg/s390/tcg-target.c
@@ -347,12 +347,6 @@ static void tcg_out_sh32(TCGContext* s, S390Opcode op, 
TCGReg dest,
     tcg_out_insn_RS(s, op, dest, sh_reg, 0, sh_imm);
 }
 
-/* branch to relative address (long) */
-static void tcg_out_brasl(TCGContext *s, TCGReg r, tcg_target_long raddr)
-{
-    tcg_out_insn(s, RIL, BRASL, r, raddr >> 1);
-}
-
 static inline void tcg_out_mov(TCGContext *s, int ret, int arg)
 {
     /* ??? With a TCGType argument, we could emit the smaller LR insn.  */
@@ -372,7 +366,7 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type,
         tcg_out_insn(s, RI, IILH, ret, arg >> 16);
     } else {
         /* branch over constant and store its address in R13 */
-        tcg_out_brasl(s, TCG_REG_R13, 14);
+        tcg_out_insn(s, RIL, BRASL, TCG_REG_R13, (6 + 8) >> 1);
         /* 64-bit constant */
         tcg_out32(s, arg >> 32);
         tcg_out32(s, arg);
@@ -491,6 +485,17 @@ static void tgen_branch(TCGContext *s, int cc, int labelno)
     }
 }
 
+static void tgen_calli(TCGContext *s, tcg_target_long dest)
+{
+    tcg_target_long off = (dest - (tcg_target_long)s->code_ptr) >> 1;
+    if (off == (int32_t)off) {
+        tcg_out_insn(s, RIL, BRASL, TCG_REG_R14, off);
+    } else {
+        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13, dest);
+        tcg_out_insn(s, RR, BASR, TCG_REG_R14, TCG_REG_R13);
+    }
+}
+
 #if defined(CONFIG_SOFTMMU)
 static void tcg_prepare_qemu_ldst(TCGContext* s, int data_reg, int addr_reg,
                                   int mem_index, int opc,
@@ -555,14 +560,10 @@ static void tcg_prepare_qemu_ldst(TCGContext* s, int 
data_reg, int addr_reg,
     if (is_store) {
         tcg_out_mov(s, arg1, data_reg);
         tcg_out_movi(s, TCG_TYPE_I32, arg2, mem_index);
-        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13,
-                     (tcg_target_ulong)qemu_st_helpers[s_bits]);
-        tcg_out_insn(s, RR, BASR, TCG_REG_R14, TCG_REG_R13);
+        tgen_calli(s, (tcg_target_ulong)qemu_st_helpers[s_bits]);
     } else {
         tcg_out_movi(s, TCG_TYPE_I32, arg1, mem_index);
-        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13,
-                     (tcg_target_ulong)qemu_ld_helpers[s_bits]);
-        tcg_out_insn(s, RR, BASR, TCG_REG_R14, TCG_REG_R13);
+        tgen_calli(s, (tcg_target_ulong)qemu_ld_helpers[s_bits]);
 
         /* sign extension */
         switch (opc) {
@@ -785,7 +786,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
         } else {
             tcg_target_long off = ((tcg_target_long)(s->tb_next + args[0]) -
                                    (tcg_target_long)s->code_ptr) >> 1;
-            if (off > -0x80000000L && off < 0x7fffffffL) {
+            if (off == (int32_t)off) {
                 /* load address relative to PC */
                 tcg_out_insn(s, RIL, LARL, TCG_REG_R13, off);
             } else {
@@ -803,22 +804,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
 
     case INDEX_op_call:
         if (const_args[0]) {
-            tcg_target_long off;
-
-            /* FIXME: + 4? Where did that come from? */
-            off = (args[0] - (tcg_target_long)s->code_ptr + 4) >> 1;
-            if (off > -0x80000000 && off < 0x7fffffff) {
-                /* relative call */
-                tcg_out_brasl(s, TCG_REG_R14, off << 1);
-                /* XXX untested */
-                tcg_abort();
-            } else {
-                /* too far for a relative call, load full address */
-                tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_R13, args[0]);
-                tcg_out_insn(s, RR, BASR, TCG_REG_R14, TCG_REG_R13);
-            }
+            tgen_calli(s, args[0]);
         } else {
-            /* call function in register args[0] */
             tcg_out_insn(s, RR, BASR, TCG_REG_R14, args[0]);
         }
         break;
-- 
1.7.0.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]