]> Git Repo - qemu.git/blobdiff - tcg/tcg.c
tcg: optimize nor(X, Y, Y), used on PPC for not(X, Y)
[qemu.git] / tcg / tcg.c
index ad631e9f500430b2c0aa7d17ff0ed36dfd2edb09..e5508507e25c3533b02ec1c7f6a740daaf3e8911 100644 (file)
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -43,6 +43,7 @@
 
 #include "config.h"
 #include "qemu-common.h"
+#include "cache-utils.h"
 
 /* Note: the long term plan is to reduce the dependancies on the QEMU
    CPU definitions. Currently they are used for qemu_ld/st
@@ -58,7 +59,7 @@
 static void patch_reloc(uint8_t *code_ptr, int type, 
                         tcg_target_long value, tcg_target_long addend);
 
-TCGOpDef tcg_op_defs[] = {
+static TCGOpDef tcg_op_defs[] = {
 #define DEF(s, n, copy_size) { #s, 0, 0, n, n, 0, copy_size },
 #define DEF2(s, iargs, oargs, cargs, flags) { #s, iargs, oargs, cargs, iargs + oargs + cargs, flags, 0 },
 #include "tcg-opc.h"
@@ -312,43 +313,6 @@ TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
     return MAKE_TCGV_I64(idx);
 }
 
-#if TCG_TARGET_REG_BITS == 32
-/* temporary hack to avoid register shortage for tcg_qemu_st64() */
-TCGv_i64 tcg_global_reg2_new_hack(TCGType type, int reg1, int reg2,
-                                  const char *name)
-{
-    TCGContext *s = &tcg_ctx;
-    TCGTemp *ts;
-    int idx;
-    char buf[64];
-
-    if (type != TCG_TYPE_I64)
-        tcg_abort();
-    idx = s->nb_globals;
-    tcg_temp_alloc(s, s->nb_globals + 2);
-    ts = &s->temps[s->nb_globals];
-    ts->base_type = type;
-    ts->type = TCG_TYPE_I32;
-    ts->fixed_reg = 1;
-    ts->reg = reg1;
-    pstrcpy(buf, sizeof(buf), name);
-    pstrcat(buf, sizeof(buf), "_0");
-    ts->name = strdup(buf);
-
-    ts++;
-    ts->base_type = type;
-    ts->type = TCG_TYPE_I32;
-    ts->fixed_reg = 1;
-    ts->reg = reg2;
-    pstrcpy(buf, sizeof(buf), name);
-    pstrcat(buf, sizeof(buf), "_1");
-    ts->name = strdup(buf);
-
-    s->nb_globals += 2;
-    return MAKE_TCGV_I64(idx);
-}
-#endif
-
 static inline int tcg_global_mem_new_internal(TCGType type, int reg,
                                               tcg_target_long offset,
                                               const char *name)
@@ -621,8 +585,9 @@ void tcg_gen_callN(TCGContext *s, TCGv_ptr func, unsigned int flags,
 #endif
 #ifdef TCG_TARGET_CALL_ALIGN_ARGS
             /* some targets want aligned 64 bit args */
-            if (i & 1) {
+            if (real_args & 1) {
                 *gen_opparam_ptr++ = TCG_CALL_DUMMY_ARG;
+                real_args++;
             }
 #endif
 #ifdef TCG_TARGET_WORDS_BIGENDIAN
@@ -746,7 +711,7 @@ char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg)
 
 char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg)
 {
-    return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I32(arg));
+    return tcg_get_arg_str_idx(s, buf, buf_size, GET_TCGV_I64(arg));
 }
 
 static int helper_cmp(const void *p1, const void *p2)
@@ -884,7 +849,7 @@ void tcg_dump_ops(TCGContext *s, FILE *outfile)
             val = args[1];
             th = tcg_find_helper(s, val);
             if (th) {
-                fprintf(outfile, th->name);
+                fprintf(outfile, "%s", th->name);
             } else {
                 if (c == INDEX_op_movi_i32)
                     fprintf(outfile, "0x%x", (uint32_t)val);
@@ -1197,57 +1162,50 @@ static void tcg_liveness_analysis(TCGContext *s)
             break;
             /* XXX: optimize by hardcoding common cases (e.g. triadic ops) */
         default:
-            if (op > INDEX_op_end) {
-                args -= def->nb_args;
-                nb_iargs = def->nb_iargs;
-                nb_oargs = def->nb_oargs;
+            args -= def->nb_args;
+            nb_iargs = def->nb_iargs;
+            nb_oargs = def->nb_oargs;
 
-                /* Test if the operation can be removed because all
-                   its outputs are dead. We assume that nb_oargs == 0
-                   implies side effects */
-                if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
-                    for(i = 0; i < nb_oargs; i++) {
-                        arg = args[i];
-                        if (!dead_temps[arg])
-                            goto do_not_remove;
-                    }
-                    tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
+            /* Test if the operation can be removed because all
+               its outputs are dead. We assume that nb_oargs == 0
+               implies side effects */
+            if (!(def->flags & TCG_OPF_SIDE_EFFECTS) && nb_oargs != 0) {
+                for(i = 0; i < nb_oargs; i++) {
+                    arg = args[i];
+                    if (!dead_temps[arg])
+                        goto do_not_remove;
+                }
+                tcg_set_nop(s, gen_opc_buf + op_index, args, def->nb_args);
 #ifdef CONFIG_PROFILER
-                    s->del_op_count++;
+                s->del_op_count++;
 #endif
-                } else {
-                do_not_remove:
+            } else {
+            do_not_remove:
 
-                    /* output args are dead */
-                    for(i = 0; i < nb_oargs; i++) {
-                        arg = args[i];
-                        dead_temps[arg] = 1;
-                    }
-                    
-                    /* if end of basic block, update */
-                    if (def->flags & TCG_OPF_BB_END) {
-                        tcg_la_bb_end(s, dead_temps);
-                    } else if (def->flags & TCG_OPF_CALL_CLOBBER) {
-                        /* globals are live */
-                        memset(dead_temps, 0, s->nb_globals);
-                    }
-                    
-                    /* input args are live */
-                    dead_iargs = 0;
-                    for(i = 0; i < nb_iargs; i++) {
-                        arg = args[i + nb_oargs];
-                        if (dead_temps[arg]) {
-                            dead_iargs |= (1 << i);
-                        }
-                        dead_temps[arg] = 0;
+                /* output args are dead */
+                for(i = 0; i < nb_oargs; i++) {
+                    arg = args[i];
+                    dead_temps[arg] = 1;
+                }
+
+                /* if end of basic block, update */
+                if (def->flags & TCG_OPF_BB_END) {
+                    tcg_la_bb_end(s, dead_temps);
+                } else if (def->flags & TCG_OPF_CALL_CLOBBER) {
+                    /* globals are live */
+                    memset(dead_temps, 0, s->nb_globals);
+                }
+
+                /* input args are live */
+                dead_iargs = 0;
+                for(i = 0; i < nb_iargs; i++) {
+                    arg = args[i + nb_oargs];
+                    if (dead_temps[arg]) {
+                        dead_iargs |= (1 << i);
                     }
-                    s->op_dead_iargs[op_index] = dead_iargs;
+                    dead_temps[arg] = 0;
                 }
-            } else {
-                /* legacy dyngen operations */
-                args -= def->nb_args;
-                /* mark end of basic block */
-                tcg_la_bb_end(s, dead_temps);
+                s->op_dead_iargs[op_index] = dead_iargs;
             }
             break;
         }
@@ -1896,20 +1854,15 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
 
 #ifdef CONFIG_PROFILER
 
-static int64_t dyngen_table_op_count[NB_OPS];
+static int64_t tcg_table_op_count[NB_OPS];
 
 void dump_op_count(void)
 {
     int i;
     FILE *f;
-    f = fopen("/tmp/op1.log", "w");
-    for(i = 0; i < INDEX_op_end; i++) {
-        fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, dyngen_table_op_count[i]);
-    }
-    fclose(f);
-    f = fopen("/tmp/op2.log", "w");
+    f = fopen("/tmp/op.log", "w");
     for(i = INDEX_op_end; i < NB_OPS; i++) {
-        fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, dyngen_table_op_count[i]);
+        fprintf(f, "%s %" PRId64 "\n", tcg_op_defs[i].name, tcg_table_op_count[i]);
     }
     fclose(f);
 }
@@ -1925,10 +1878,10 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
     const TCGArg *args;
 
 #ifdef DEBUG_DISAS
-    if (unlikely(loglevel & CPU_LOG_TB_OP)) {
-        fprintf(logfile, "OP:\n");
+    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {
+        qemu_log("OP:\n");
         tcg_dump_ops(s, logfile);
-        fprintf(logfile, "\n");
+        qemu_log("\n");
     }
 #endif
 
@@ -1941,10 +1894,10 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
 #endif
 
 #ifdef DEBUG_DISAS
-    if (unlikely(loglevel & CPU_LOG_TB_OP_OPT)) {
-        fprintf(logfile, "OP after la:\n");
+    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {
+        qemu_log("OP after la:\n");
         tcg_dump_ops(s, logfile);
-        fprintf(logfile, "\n");
+        qemu_log("\n");
     }
 #endif
 
@@ -1959,7 +1912,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
     for(;;) {
         opc = gen_opc_buf[op_index];
 #ifdef CONFIG_PROFILER
-        dyngen_table_op_count[opc]++;
+        tcg_table_op_count[opc]++;
 #endif
         def = &tcg_op_defs[opc];
 #if 0
@@ -2014,22 +1967,6 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
             goto next;
         case INDEX_op_end:
             goto the_end;
-
-#ifdef CONFIG_DYNGEN_OP
-        case 0 ... INDEX_op_end - 1:
-            /* legacy dyngen ops */
-#ifdef CONFIG_PROFILER
-            s->old_op_count++;
-#endif
-            tcg_reg_alloc_bb_end(s, s->reserved_regs);
-            if (search_pc >= 0) {
-                s->code_ptr += def->copy_size;
-                args += def->nb_args;
-            } else {
-                args = dyngen_op(s, opc, args);
-            }
-            goto next;
-#endif
         default:
             /* Note: in order to speed up the code, it would be much
                faster to have specialized register allocator functions for
@@ -2052,7 +1989,7 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
     return -1;
 }
 
-int dyngen_code(TCGContext *s, uint8_t *gen_code_buf)
+int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
 {
 #ifdef CONFIG_PROFILER
     {
@@ -2080,7 +2017,7 @@ int dyngen_code(TCGContext *s, uint8_t *gen_code_buf)
    offset bytes from the start of the TB.  The contents of gen_code_buf must
    not be changed, though writing the same values is ok.
    Return -1 if not found. */
-int dyngen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
+int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
 {
     return tcg_gen_code_common(s, gen_code_buf, offset);
 }
@@ -2101,8 +2038,6 @@ void tcg_dump_info(FILE *f,
                 s->tb_count1 ? (double)(s->tb_count1 - s->tb_count) / s->tb_count1 * 100.0 : 0);
     cpu_fprintf(f, "avg ops/TB          %0.1f max=%d\n", 
                 s->tb_count ? (double)s->op_count / s->tb_count : 0, s->op_count_max);
-    cpu_fprintf(f, "old ops/total ops   %0.1f%%\n", 
-                s->op_count ? (double)s->old_op_count / s->op_count * 100.0 : 0);
     cpu_fprintf(f, "deleted ops/TB      %0.2f\n",
                 s->tb_count ? 
                 (double)s->del_op_count / s->tb_count : 0);
This page took 0.034044 seconds and 4 git commands to generate.