|
From: <sv...@va...> - 2012-05-05 02:55:31
|
florian 2012-05-05 03:55:24 +0100 (Sat, 05 May 2012)
New Revision: 2322
Log:
Special-case the TR insn for EX.
With this change all insns of the SS format with a length field
are special-cased for EX.
Modified files:
trunk/priv/guest_s390_toIR.c
Modified: trunk/priv/guest_s390_toIR.c (+30 -18)
===================================================================
--- trunk/priv/guest_s390_toIR.c 2012-05-05 03:20:30 +01:00 (rev 2321)
+++ trunk/priv/guest_s390_toIR.c 2012-05-05 03:55:24 +01:00 (rev 2322)
@@ -8834,8 +8834,30 @@
put_counter_dw0(mkU64(0));
}
+static void
+s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
+{
+ IRTemp op = newTemp(Ity_I8);
+ IRTemp op1 = newTemp(Ity_I8);
+ IRTemp result = newTemp(Ity_I64);
+ IRTemp counter = newTemp(Ity_I64);
+ assign(counter, get_counter_dw0());
+ assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
+
+ assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
+
+ assign(op1, load(Ity_I8, mkexpr(result)));
+ store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
+
+ put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
+ if_condition_goto(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)),
+ guest_IA_curr_instr);
+ put_counter_dw0(mkU64(0));
+}
+
+
static void
s390_irgen_EX_SS(UChar r, IRTemp addr2,
void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2), int lensize)
@@ -8943,6 +8965,11 @@
s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
return "nc via ex";
+ case 0xdc00000000000000ULL:
+ /* special case TR */
+ s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
+ return "tr via ex";
+
default:
{
/* everything else will get a self checking prefix that also checks the
@@ -11074,25 +11101,10 @@
static HChar *
s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
{
- IRTemp op = newTemp(Ity_I8);
- IRTemp op1 = newTemp(Ity_I8);
- IRTemp result = newTemp(Ity_I64);
- IRTemp counter = newTemp(Ity_I64);
+ IRTemp len = newTemp(Ity_I64);
- assign(counter, get_counter_dw0());
-
- assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
-
- assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
-
- assign(op1, load(Ity_I8, mkexpr(result)));
- store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
-
- put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
- if_condition_goto(binop(Iop_CmpNE64, mkexpr(counter), mkU64(length)),
- guest_IA_curr_instr);
-
- put_counter_dw0(mkU64(0));
+ assign(len, mkU64(length));
+ s390_irgen_TR_EX(len, start1, start2);
dummy_put_IA();
return "tr";
|