|
From: <sv...@va...> - 2012-05-05 00:01:26
|
florian 2012-05-05 01:01:16 +0100 (Sat, 05 May 2012)
New Revision: 2320
Log:
Add NC and OC to the list of insns that get special treatment under EX.
Refactored code such that s390_irgen_xonc can be reused thereby avoiding
code duplication.
Modified files:
trunk/priv/guest_s390_toIR.c
Modified: trunk/priv/guest_s390_toIR.c (+36 -30)
===================================================================
--- trunk/priv/guest_s390_toIR.c 2012-05-03 02:30:48 +01:00 (rev 2319)
+++ trunk/priv/guest_s390_toIR.c 2012-05-05 01:01:16 +01:00 (rev 2320)
@@ -48,6 +48,7 @@
/*--- Forward declarations ---*/
/*------------------------------------------------------------*/
static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
+static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
/*------------------------------------------------------------*/
@@ -8784,38 +8785,25 @@
return "clcle";
}
+
static void
s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
{
- IRTemp old1 = newTemp(Ity_I8);
- IRTemp old2 = newTemp(Ity_I8);
- IRTemp new1 = newTemp(Ity_I8);
- IRTemp counter = newTemp(Ity_I32);
- IRTemp addr1 = newTemp(Ity_I64);
+ s390_irgen_xonc(Iop_Xor8, length, start1, start2);
+}
- assign(counter, get_counter_w0());
- assign(addr1, binop(Iop_Add64, mkexpr(start1),
- unop(Iop_32Uto64, mkexpr(counter))));
+static void
+s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
+{
+ s390_irgen_xonc(Iop_And8, length, start1, start2);
+}
- assign(old1, load(Ity_I8, mkexpr(addr1)));
- assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
- unop(Iop_32Uto64,mkexpr(counter)))));
- assign(new1, binop(Iop_Xor8, mkexpr(old1), mkexpr(old2)));
- store(mkexpr(addr1),
- mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
- mkU8(0), mkexpr(new1)));
- put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
- get_counter_w1()));
-
- /* Check for end of field */
- put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
- if_condition_goto(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)),
- guest_IA_curr_instr);
- s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
- False);
- put_counter_dw0(mkU64(0));
+static void
+s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
+{
+ s390_irgen_xonc(Iop_Or8, length, start1, start2);
}
@@ -8963,7 +8951,16 @@
s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
return "xc via ex";
+ case 0xd600000000000000ULL:
+ /* special case OC */
+ s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
+ return "oc via ex";
+ case 0xd400000000000000ULL:
+ /* special case NC */
+ s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
+ return "nc via ex";
+
default:
{
/* everything else will get a self checking prefix that also checks the
@@ -9308,7 +9305,7 @@
}
static void
-s390_irgen_xonc(IROp op, UChar length, IRTemp start1, IRTemp start2)
+s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
{
IRTemp old1 = newTemp(Ity_I8);
IRTemp old2 = newTemp(Ity_I8);
@@ -9338,7 +9335,7 @@
/* Check for end of field */
put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
- if_condition_goto(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)),
+ if_condition_goto(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)),
guest_IA_curr_instr);
s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
False);
@@ -9349,8 +9346,11 @@
static HChar *
s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
{
- s390_irgen_xonc(Iop_Xor8, length, start1, start2);
+ IRTemp len = newTemp(Ity_I32);
+ assign(len, mkU32(length));
+ s390_irgen_xonc(Iop_Xor8, len, start1, start2);
+
return "xc";
}
@@ -9397,16 +9397,22 @@
static HChar *
s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
{
- s390_irgen_xonc(Iop_And8, length, start1, start2);
+ IRTemp len = newTemp(Ity_I32);
+ assign(len, mkU32(length));
+ s390_irgen_xonc(Iop_And8, len, start1, start2);
+
return "nc";
}
static HChar *
s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
{
- s390_irgen_xonc(Iop_Or8, length, start1, start2);
+ IRTemp len = newTemp(Ity_I32);
+ assign(len, mkU32(length));
+ s390_irgen_xonc(Iop_Or8, len, start1, start2);
+
return "oc";
}
|