]> git.proxmox.com Git - qemu.git/commitdiff
target-s390: Optimize XC
authorRichard Henderson <rth@twiddle.net>
Wed, 19 Sep 2012 20:48:46 +0000 (13:48 -0700)
committerRichard Henderson <rth@twiddle.net>
Sat, 5 Jan 2013 20:18:45 +0000 (12:18 -0800)
Notice XC with same address and convert that to store of zero.

Signed-off-by: Richard Henderson <rth@twiddle.net>
target-s390x/insn-data.def
target-s390x/translate.c

index e9159848281cd60536cccf0f2f63ecbc1caef4c1..480f1fdf510d824d9ca19b48403234d338fb6ee9 100644 (file)
     C(0xb982, XGR,     RRE,   Z,   r1, r2, r1, 0, xor, nz64)
     C(0xb9e7, XGRK,    RRF_a, DO,  r2, r3, r1, 0, xor, nz64)
     C(0xe382, XG,      RXY_a, Z,   r1, m2_64, r1, 0, xor, nz64)
-    C(0xd700, XC,      SS_a,  Z,   la1, a2, 0, 0, xc, 0)
+    C(0xd700, XC,      SS_a,  Z,   0, 0, 0, 0, xc, 0)
 /* EXCLUSIVE OR IMMEDIATE */
     D(0xc006, XIHF,    RIL_a, EI,  r1_o, i2_32u, r1, 0, xori, 0, 0x2020)
     D(0xc007, XILF,    RIL_a, EI,  r1_o, i2_32u, r1, 0, xori, 0, 0x2000)
index 34b9cdf127d8ef1f3d8439cd0ab33add6aef3b2b..7f8a5503d92ed1e4308fe2558ced97dc7dfb6629 100644 (file)
@@ -3403,10 +3403,54 @@ static ExitStatus op_unpk(DisasContext *s, DisasOps *o)
 
 static ExitStatus op_xc(DisasContext *s, DisasOps *o)
 {
-    TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
+    int d1 = get_field(s->fields, d1);
+    int d2 = get_field(s->fields, d2);
+    int b1 = get_field(s->fields, b1);
+    int b2 = get_field(s->fields, b2);
+    int l = get_field(s->fields, l1);
+    TCGv_i32 t32;
+
+    o->addr1 = get_address(s, 0, b1, d1);
+
+    /* If the addresses are identical, this is a store/memset of zero.  */
+    if (b1 == b2 && d1 == d2 && (l + 1) <= 32) {
+        o->in2 = tcg_const_i64(0);
+
+        l++;
+        while (l >= 8) {
+            tcg_gen_qemu_st64(o->in2, o->addr1, get_mem_index(s));
+            l -= 8;
+            if (l > 0) {
+                tcg_gen_addi_i64(o->addr1, o->addr1, 8);
+            }
+        }
+        if (l >= 4) {
+            tcg_gen_qemu_st32(o->in2, o->addr1, get_mem_index(s));
+            l -= 4;
+            if (l > 0) {
+                tcg_gen_addi_i64(o->addr1, o->addr1, 4);
+            }
+        }
+        if (l >= 2) {
+            tcg_gen_qemu_st16(o->in2, o->addr1, get_mem_index(s));
+            l -= 2;
+            if (l > 0) {
+                tcg_gen_addi_i64(o->addr1, o->addr1, 2);
+            }
+        }
+        if (l) {
+            tcg_gen_qemu_st8(o->in2, o->addr1, get_mem_index(s));
+        }
+        gen_op_movi_cc(s, 0);
+        return NO_EXIT;
+    }
+
+    /* But in general we'll defer to a helper.  */
+    o->in2 = get_address(s, 0, b2, d2);
+    t32 = tcg_const_i32(l);
     potential_page_fault(s);
-    gen_helper_xc(cc_op, cpu_env, l, o->addr1, o->in2);
-    tcg_temp_free_i32(l);
+    gen_helper_xc(cc_op, cpu_env, t32, o->addr1, o->in2);
+    tcg_temp_free_i32(t32);
     set_cc_static(s);
     return NO_EXIT;
 }